Entwickler-Ecke

Multimedia / Grafik - Zugriffsverletzung bei Verwendung von waveOutWrite


Flamefire - Di 22.12.09 23:58
Titel: Zugriffsverletzung bei Verwendung von waveOutWrite
Ich versuche gerade, aufgenommene Daten (vom Mikrofon) wieder abzuspielen.
Nach viel Google und noch mehr probieren, habe ich mir dann was zusammenkopiert und gebastelt, so dass die Aufnahme geht.
Der wichtige Teil sieht so aus:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
procedure TForm2.FormCreate(Sender: TObject);
var
  Format: tWAVEFORMATEX;
begin
  with Format do
  begin
    wFormatTag := WAVE_FORMAT_PCM;
    nChannels := 1;
    wBitsPerSample := 8;
    nSamplesPerSec := 44100;
     nBlockAlign := nChannels * (wBitsPerSample div 8);
    nAvgBytesPerSec := nSamplesPerSec * nBlockAlign;
    cbSize := 0;
  end;
 wave := TWaveIn.Create;
 wave.OnData := OnData;
 wave.open(0);
 waveOutOpen(@fHandle, 0, @format, 00, CALLBACK_NULL);
 fStream:=TMemoryStream.Create;
end;

procedure TForm2.OnData(const aStream: TMemoryStream);
begin
  fStream.CopyFrom(aStream,aStream.Size);
end;

//...
procedure waveInProc(hwi: HWAVEIN; uMsg: UINT; dwInstance, dwParam1, dwParam2 : DWord); stdcall;
var
  classinstance: TWaveIn absolute dwInstance;
  tmpBuff:PWaveHdr;
begin
 if umsg = WIM_DATA then
 begin
   with classinstance do
   begin
     tmpBuff:=PWaveHdr(dwParam1);
     //if(fCurBuff=fBuff1) then fCurBuff:=fBuff2
     //else fCurBuff:=fBuff1;
     if (tmpBuff.dwBytesRecorded = 0or (tmpBuff.dwFlags and MHDR_DONE<>MHDR_DONE) then exit;
     fSyncStream.Clear;
     fSyncStream.Write(tmpBuff.lpData^, tmpBuff.dwBytesRecorded);
     fSyncStream.Position := 0;
     if Assigned(fOnData) then
      fOnData(fSyncStream);
     WaveInAddBuffer(fHandle, tmpBuff, SizeOf(TWaveHdr));
   end;
 end;
end;

Ist noch nicht optimal, da ich viel probiert habe, aber egal erstmal.
Das Problem tritt beim Abspielen auf:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
procedure TForm2.Button1Click(Sender: TObject);
var header: TWaveHdr;
begin
  wave.close;
  fStream.Position:=0;
  header.lpData := fStream.Memory;
  header.dwBufferLength := fStream.Size;
  header.dwFlags := 0;
  waveOutPrepareHeader(fhandle, @header, sizeof(TWaveHdr));
  waveOutWrite(fhandle, @header, sizeof(TWaveHdr));
end;


Er spielt mir alles ab, aber am Ende der Sequenz stürzt das programm mit einer Zugriffsverletzung ab.
Warum? Buffergrößen stimmen doch.

Außerdem habe ich ein ziemlich starkes Rauschen und leichtes Knacksen drin. Wie kriege ich das weg?


BenBE - Mo 04.01.10 17:48

Stimmen auch alle Ziele, wo er liest? Nicht, dass du aus Versehen in den Stack geschrieben hast ...


Knulli - Do 11.11.10 19:21

HiHiHi...

hatte das selbe Problem...

Dein Header ist LOKAL und Du schubst die Funktion Write an, die 'ne Weile braucht aber sofort zurückkommt (Asynchron!!) und verläßt dann auch gleich die Funktion
und der header ist --- schwupps --- weg von Stack!

:-)

Knulli