Delphi And Winamp Dsp Plugin

Started by Shin,

Shin

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


QuoteProcedure 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

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


QuoteProcedure 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.