Entwickler-Ecke

Multimedia / Grafik - FMOD - Streams


K.S.M. - Mo 08.03.10 16:26
Titel: FMOD - Streams
Hallo Delphi-Forum :)

Ich sitze gerade an einem Physik-Projekt über die Fourieranaylse und möchte das gerne mit Ton realisieren. Als Sound-Engine habe ich mir FMOD ausgesucht.

Mit dem initialisieren und beenden gibts so weit keine Probleme - allerdings erzeugt die "StreamCallback"-Funktion beim 2455. Aufruf einer AccessViolation gemedlet von FMOD.

Hier mein Stream-Callback:

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:
function StreamCallback(Stream: PFSoundStream; Buff: Pointer; Len, Param: Integer): ByteBool; stdcall;
var
  Count: Integer;
  Buffer: PSmallInt;
  Calc: SmallInt;
  //CPUUsage : Single;
begin
  NewFreq := MainForm.FreqBar.Position;
  Buffer := PSmallInt( Buff );
  Count := 0;

  while Count < (Len shr 2do    { >>2 = 16bit stereo (4 bytes per sample) }
  begin
    //LastFreq := NewFreq;
    if Pos >= SamplingRate/LastFreq then //2*Pi/SR*f*p >= 2*Pi
    begin
      Pos := Pos - SamplingRate/(LastFreq);
      if (LastFreq <> NewFreq) then
      begin
        LastFreq := NewFreq;
        Pos := 0.0;
      end;
    end;

    Calc := Trunc( Sin(2*Pi/SamplingRate*LastFreq*Pos) * (32767.0/2.0) );

    Buffer^ := Calc; // <-- Access Violation!!

    Inc(Buffer, 2);
    Buffer^ := Calc;
    Inc(Buffer, 2);

    Inc( Count );
    Pos := Pos + 1;
  end;

  { Ich nutze die CPU in meinem Programm zunächst nicht. }
  Inc(CPUUpdate);
  if CPUUpdate > 10 then
  begin
    //CPUUsage := FSOUND_GetCPUUsage;
    CPUUpdate := 0;
  end;

  Result := True;
end;


Ich nutze die neueste FMOD-Version, und diese Funktion ist schon rfecht alt. Ist sie vlt fehlerbehaftet aufgrund von flaschen Paramtern o.Ä.?

Liebe Grüße und vielen Dank für eure Hilfe :),
K.S.M.

Edit1 ich benutze Delphi-Version 2010. Vielleicht liegt daran das Problem.
Edit2 ich habe eben das FMOD-Stream 2-Beispiel ausprobiert. Es erzeugt auch eine AccessViolation...


Oliver Marx - Mo 08.03.10 17:16

Hi,

ich vermute, du möchtest mit
Zitat:
Inc(Buffer, 2);
den Buffer auf das nächste Element setzen. Allerdings erhöhst du mit inc immer um die Bitbreite der Variablen und SmallInt sind 2 Byte. Daher erhöhst du Buffer immer um 4 Byte und es kommt zu einem Zugriff außerhalb des reservierten Speichers.
Versuch es mal nur mit Inc(Buffer);

Oliver


K.S.M. - Mo 08.03.10 17:30

Hey super, es funktioniert tatsächlich!!

Vielen Dank!
:)