Sources
Delphi Russian Knowledge Base
DRKB - это самая большая и удобная в использовании база знаний по Дельфи в рунете, составленная Виталием Невзоровым

Снятие звука с микрофона, отображение звуковые данных в виде графика

01.01.2007
unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Classes, Graphics, Forms,
  Dialogs, MMSystem;
 
type
  TWavArrayBuf = array[0..1023]of byte;
  PWavArrayBuf = ^TWavArrayBuf;
 
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    WaveFormat: TWaveFormatEx;
    WaveIn: PHWaveIn;
    procedure WndProc(var Msg: TMessage); override;
    function InitWaveIn: Boolean;
    procedure CloseWaveIn;
  end;
 
var
  Form1: TForm1;
 
implementation
 
uses Math;
 
{$R *.dfm}
 
function TForm1.InitWaveIn: Boolean;
var
  I, Err: Integer;
  WaveHdr: PWaveHdr;
  WavBuff: PWavArrayBuf;
 
  procedure FreeData;
  begin
    if WavBuff <> nil then Dispose(WavBuff);
    if WaveHdr <> nil then Dispose(WaveHdr);
    if WaveIn <> nil then Dispose(WaveIn);
  end;
 
begin
  Result := False;
  WaveFormat.wFormatTag := WAVE_FORMAT_PCM;
  WaveFormat.nChannels := 1; 
  WaveFormat.nSamplesPerSec := 44100;
  WaveFormat.nAvgBytesPerSec := 44100;
  WaveFormat.nBlockAlign := 4;
  WaveFormat.wBitsPerSample := 8;
  WaveIn := New(PHWaveIn);
  Err := WaveInOpen(WaveIn, 0, @WaveFormat, Handle, 0, CALLBACK_WINDOW);
  if Err <> 0 then Exit;
  for i:=1 to 8 do
  begin
    WavBuff := New(PWavArrayBuf);
    WaveHdr := New(PWaveHdr);
    with WaveHdr^ do
    begin
      lpData := Pointer(WavBuff);
      dwBufferLength := SizeOf(WavBuff);
      dwBytesRecorded := 0;
      dwUser := 0;
      dwFlags := 0;
      dwLoops := 0;
    end;
    Err := WaveInPrepareHeader(WaveIn^, WaveHdr, SizeOf(TWaveHdr));
    if Err <> 0 then
    begin
      FreeData;
      Exit;
    end;
    Err := WaveInAddBuffer(WaveIn^, WaveHdr, Sizeof(TWaveHdr));
    if Err <> 0 then
    begin
      FreeData;
      Exit;
    end;
  end;
  Err := WaveInStart(WaveIn^);
  if Err <> 0 then
  begin
    FreeData;
    Exit;
  end;
  Result := True;
end;
 
Procedure Tform1.WndProc(var Msg: TMessage);
var
  Hdr: PWaveHdr;
  I: Integer;
  R: Real;
begin
  inherited;
  case Msg.Msg of
    MM_WIM_DATA:
    begin
      Hdr := PWaveHdr(Msg.LParam);
      if Hdr^.dwBytesRecorded = 0 then Exit;
      R := IfThen(Hdr^.dwBytesRecorded > 0,
        ClientWidth / Hdr^.dwBytesRecorded, 0);
      PatBlt(Canvas.Handle, 0, 0, ClientWidth,  ClientHeight, PATCOPY);
      Canvas.Pen.Color:=clRed;
      Canvas.MoveTo(0, 127);
      Canvas.LineTo(ClientWidth, 127);
      Canvas.Pen.Color := clMaroon;
      for I := 1 to 12 do
      begin
        Canvas.MoveTo(Round(R * (I * 100)), 0);
        Canvas.LineTo(Round(R * (I * 100)), 255);
      end;
      Canvas.Pen.Color:=clLime;
      Canvas.MoveTo(0, PWavArrayBuf(Hdr.lpData)^[0]);
      for I := 0 to Hdr^.dwBytesRecorded - 1 do
        Canvas.LineTo(Round(R * I), PWavArrayBuf(Hdr.lpData)^[I]);
 
      WaveInUnprepareHeader(WaveIn^, Hdr, Sizeof(TWaveHdr));
      Dispose(hdr.lpData);
      DisPose(hdr);
 
      Hdr := New(PWaveHdr);
      Hdr^.lpData := Pointer(New(PWavArrayBuf));
      Hdr^.dwBufferLength := 1024;
      Hdr^.dwBytesRecorded := 0;
      Hdr^.dwUser := 0;
      Hdr^.dwFlags := 0;
      Hdr^.dwLoops := 0;
 
      WaveInPrepareHeader(WaveIn^, Hdr, Sizeof(TWaveHdr));
      WaveInAddBuffer(WaveIn^, Hdr, Sizeof(TWaveHdr));
    end;
  end;
end;
 
procedure TForm1.CloseWaveIn;
begin
  WaveInStop(WaveIn^);
  if WaveIn <> nil then
  begin
    WaveInReset(WaveIn^);
    WaveInClose(WaveIn^);
  end;
  Dispose(WaveIn);
end;
 
procedure TForm1.FormCreate(Sender: TObject);
begin
  DoubleBuffered := True;
  Height := 282;
  Width := 1000;
  Color := clBlack;
  if not InitWaveIn then ShowMessage(SysErrorMessage(GetLastError));
end;
 
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  CloseWaveIn;
end;
 
end.

 
 

Автор: Rouse_

Взято из https://forum.sources.ru