Author Topic: Delphi And Winamp Dsp Plugin  (Read 4669 times)

Shin

  • Guest
Delphi And Winamp Dsp Plugin
« on: 3 Jul '03 - 17:07 »
i am in problem...:(
I want my mp3player to use winamp dsp plugin.
so i added dspactivex ocx. i'm noobs..

this is my source...(stream procedure)

Procedure WinampDSPProc(handle: HSYNC; channel: DWORD; buffer: Pointer; length, user: DWORD); stdcall;
Var
 d : ^Byte;
 DecBuf  : ^Byte;
 c       : DWord;
 a       : Integer;
 excess2 : ^Byte;
begin
 d:=Buffer;
 c:=Length;
 if (exlen>0) Then Begin // excess left from last time
   If c>ExLen Then a:=ExLen Else a:=c;
 End Else Begin
   a:=exlen;
   Move(d^,excess,a);
   Dec(exlen,a);
   Excess2:=@Excess;
   Inc(Excess2,a);
   if (exlen>0) Then Move(excess^,Excess2^,exlen); // some excess remaining
   Inc(d,a); // advance buffer
   c:=c-a;
 End;
 while (c>0) Do Begin
   a:=BASS_ChannelGetData(Channel, decbuf, decblock);
   if (a<0) Then break; // end of data (you may want to continue processing for effect tail)
   a:=4*DspOcx.ModifySamples(Integer(@decbuf),a div 4,16,2,44100);
   Beep;
   if (a>c) Then Begin // some excess data, keep it for next time
     Move(d^,decbuf^,c);
     exlen:=a-c;
     Inc(Decbuf,c);
     Move(excess^,decbuf^,exlen);
     c:=0; // all done
   End else Begin
     Move(d^,decbuf^,a);
     Inc(d,a); // advance buffer
     c:=c-a;
   End;
 End;
 Buffer:=@DecBuf;
End;

i translated c++ source code..
it does not work.
but only access violation..

please help me !!!!!!!!!!

sorry for my bad English... i'm not native speaker.

DanaPaul

  • Posts: 335
Re: Delphi And Winamp Dsp Plugin
« Reply #1 on: 3 Jul '03 - 21:07 »

Quote
Procedure WinampDSPProc(handle: HSYNC; channel: DWORD; buffer: Pointer; length, user: DWORD); stdcall;
Var
 d : ^Byte;
 DecBuf  : ^Byte;
 c       : DWord;
 a       : Integer;
 excess2 : ^Byte;
begin 


Well, your Delphi syntax isn't the "best practice" for memory pointers. Without knowing your Delphi version, let's use standard 4 byte pointers (32 bit values) as a working example...

Use these variable types...

Var
 d : Pointer;
 DecBuf  : Pointer;
 c       : DWord;
 a       : Integer;
 excess2 : Pointer;


Change from...

Inc(d,a); // advance buffer
 
To...

DWord(d) := PChar(d) + a; // advance buffer

The reasoning behind typecasting pointers as a PChar is because Delphi's compiler understands that a PChar is 4 bytes and it references memory, ie... ^Char.  Additionally, if you use "Inc" to increment pointers then you would need to trap negative values and add one...

Due to the use of the negative flag (32nd Bit of a 4 byte integer) these 4 byte integers can access 2 GB memory. On the other hand, a PChar can access 4 GB memory.



Or...



Use these variable types...

Var
 d : PChar;
 DecBuf  : PChar;
 c       : DWord;
 a       : Integer;
 excess2 : PChar;


Change from...

Move(d^,decbuf^,c);
       
To...

Move(d[0],decbuf[0],c);
   





 


Shin

  • Guest
Thanks A lot
« Reply #2 on: 5 Jul '03 - 17:35 »
so i tried next procedure instead of mine.

Procedure WinampDSPProc(handle: HSYNC; channel: DWORD; buffer: Pointer; length, user: DWORD); stdcall;
Type PointerByte=^Byte;
Var
 Tempbuf : PointerByte;
 Linker  : Integer;
begin
 TempBuf:=Buffer;
 Linker:=Integer(TempBuf);
 DspPlugin^.ModifySamples(DspPlugin,Linker,Length Div 4,16,2,44100);
 Buffer:=TempBuf;
 TempBuf:=Buffer;
End;

it works... with some plugins(ex. DFX).
but it crashes with shoutcast dsp plugin.

what's wrong ?

DanaPaul

  • Posts: 335
Re: Thanks A lot
« Reply #3 on: 5 Jul '03 - 19:46 »

Quote
Procedure WinampDSPProc(handle: HSYNC; channel: DWORD; buffer: Pointer; length, user: DWORD); stdcall;
Type PointerByte=^Byte;
Var
 Tempbuf : PointerByte;
 Linker  : Integer;
begin
 TempBuf:=Buffer;
 Linker:=Integer(TempBuf);
 DspPlugin^.ModifySamples(DspPlugin,Linker,Length Div 4,16,2,44100);
 Buffer:=TempBuf;
 TempBuf:=Buffer;

End;


You are mixing Pointer references, Class references, and memory indexing references.  

Without seeing the rest of your code, nor the remaining type definitions, consider this...

Procedure WinampDSPProc(handle: HSYNC; channel: DWORD; var buffer: Pointer; var length: DWORD; user: DWORD); stdcall;
Var
Linker  : Integer;
begin

 ... Either ...
 Linker := Integer(PByte(buffer)^);
 ... Or ...
 System.Move(Buffer^, Linker, SizeOf(integer));
 
 DspPlugin^.ModifySamples(DspPlugin,Linker,Length Div SizeOf(Integer),16,2,44100);
 DWord(Buffer) := PChar(Buffer) + SizeOf(Integer);
 Dec(length, SizeOf(Integer));
End;

How is "DspPlugin" defined? If DspPlugin is derived from a Class then your pointer reference for the DspPlugin (DspPlugin^) is incorrect. On the other hand, if DspPlugin is derived from the old Pascal Object type (not to be confused with TObject class) then your pointer reference (DspPlugin^) for the DspPlugin is correct.