Author Topic: DSP Procs Buffer Length  (Read 4705 times)

georgebou

  • Posts: 189
DSP Procs Buffer Length
« on: 29 Sep '02 - 12:22 »
Ian,
as we all know the Syntax of a DSP Proc is the following:
procedure DSPProc(handle: HSYNC; channel: DWORD; buffer: Pointer; length, user: DWORD); stdcall;

I'm writing a DSP that it's proccessing produces more bytes than the length of the DSP Proc Buffer.Is there a way to send these bytes to the DSP Buffer or the only solution is just ignore them. What about if i want to write less bytes than the DSP Buffer length?

Ian @ un4seen

  • Administrator
  • Posts: 21363
Re: DSP Procs Buffer Length
« Reply #1 on: 30 Sep '02 - 11:22 »
The DSPs are performed "in place", that is the DSP input buffer is also the DSP output buffer. This gives optimal performance because there is no extra buffer allocation or data copying, but it means you can not return more/less data (or you can, but it won't sound good ;D).

What sort of DSP are you trying to perform? If it's time stretching, for example, you can use pitch scaling DSP and change the playback rate.

georgebou

  • Posts: 189
Re: DSP Procs Buffer Length
« Reply #2 on: 30 Sep '02 - 15:28 »
I'm writing a winamp DSP plugin reader.
The code i use for my DSP Proc is the following:
Code: [Select]

procedure WinAmpDSPProc(handle: HSYNC; channel: DWORD; buffer: Pointer; length, user: DWORD); stdcall;
Var
  SamplesReturned:Integer;
  BytesToWriteToDSP:Integer;
begin
    d := buffer;
    Move(d^,WinampSamplesForDSP^,Length);
    If Assigned(WINAMP_DSP_PLUGIN_CurrentPluginModule) Then Begin
       // NumSamples for 16 bit = Length Div 2
       SamplesReturned:=WINAMP_DSP_PLUGIN_CurrentPluginModule.ModifySamples(WINAMP_DSP_PLUGIN_CurrentPluginModule,WinampSamplesForDSP,Length Div 2,16,2,44100);
    End
    Else Begin
       // NumSamples for 16 bit = Length Div 2
         SamplesReturned:=Length Div 2;
    End;
    If SamplesReturned*2<=Length Then Begin
       BytesToWriteToDSP:=SamplesReturned*2;
    End
    Else Begin
              BytesToWriteToDSP:=Length;
    End;
    Move(WinampSamplesForDSP^,d^,BytesToWriteToDSP);
end;

It's the simplest way i could do it.
This code works fine for most plugins but the problem is that some plugins that do pitch scaling return different number of bytes than the length you give as input.
In any case, i should have to do something when the number of bytes returned from the ModifySamples procedure differ from the input length given, if i want to say that i my program supports these plugins.
So do you have any idea?

Ian @ un4seen

  • Administrator
  • Posts: 21363
Re: DSP Procs Buffer Length
« Reply #3 on: 30 Sep '02 - 23:48 »
What you could do is use a decoding channel and custom stream combo. In the stream function you'd get data from the decoding channel, pass it onto the DSP plugin(s), and then feed the result into the stream.

If the plugin(s) produce more data than BASS requested from the stream, you'll have to buffer the extra data, and feed it into the stream on the next call.

georgebou

  • Posts: 189
Re: DSP Procs Buffer Length
« Reply #4 on: 1 Oct '02 - 15:31 »
Thanks man, i'll try it.

georgebou

  • Posts: 189
Re: DSP Procs Buffer Length
« Reply #5 on: 29 Oct '02 - 17:20 »
Ian, i have a new question about buffer lengths:
If i use a buffer of 5 secs with the BASS_SetBufferLength function, which is the possible maximum number of bytes that a DSP Proc could return to me?
I 'm asking because i want to allocate a Buffer that i want to use in a DSP Proc. For now the number of bytes i allocate is :SamplingRate*2 Channels *5 Secs, but the DSP proc never returns such a large length and i think that i waste my memory for no reason.

Ian @ un4seen

  • Administrator
  • Posts: 21363
Re: DSP Procs Buffer Length
« Reply #6 on: 29 Oct '02 - 21:31 »
BASS will give at most 200ms worth of data in a single update, no matter what the buffer length is.

bigjim

  • Posts: 232
Re: DSP Procs Buffer Length
« Reply #7 on: 30 Oct '02 - 10:56 »
Is there any chance of sharing your code to allow bass to use winamp plugins, or could you point me in the direction of some info on the subject.
Thanx

georgebou

  • Posts: 189
Re: DSP Procs Buffer Length
« Reply #8 on: 30 Oct '02 - 15:48 »
First of all i must thank Ian for his answer.
About bigjim's question the answer is in this thread: The WinAmpDSPProc is the whole idea. The only thing that has left to you is to manage to load the winamp dsp plugins using it's headers, something that is not very difficult. There are on this forum translations for the winamp visuals plugins and the only thing you have to do is to do it for the winamp dsp plugins too.

bigjim

  • Posts: 232
Re: DSP Procs Buffer Length
« Reply #9 on: 2 Nov '02 - 01:29 »
Am I being daft? but where are the headers for each/the plugin(s)... also exceptionally tidy delphi coding 8)

georgebou

  • Posts: 189
Re: DSP Procs Buffer Length
« Reply #10 on: 2 Nov '02 - 11:52 »
Check this thread
http://www.un4seen.com/music/YaBB.cgi?board=bass&action=display&num=1029418720&start=0#0
It contains a good example on how to translate winamp headers  for c to Delphi.
The original headers are in C and you should download the winamp DSK from http://www.winamp.com


little_jay

  • Posts: 15
Re: DSP Procs Buffer Length
« Reply #12 on: 17 Feb '03 - 20:32 »
Quote

Posted by: Ian @ un4seen Posted on: 30.09.02 at 23:48:12:

What you could do is use a decoding channel and custom stream combo. In the stream function you'd get data from the decoding channel, pass it onto the DSP plugin(s), and then feed the result into the stream.

If the plugin(s) produce more data than BASS requested from the stream, you'll have to buffer the extra data, and feed it into the stream on the next call.


Ian, what would a good approach be for a FIFO DSP that generates fewer samples that the input?  As far as I can tell, using the decoding channel and streamproc technique, the stream will abort the first time there are too few samples returned.

Ian @ un4seen

  • Administrator
  • Posts: 21363
Re: DSP Procs Buffer Length
« Reply #13 on: 18 Feb '03 - 17:35 »
Quote
Ian, what would a good approach be for a FIFO DSP that generates fewer samples that the input?  As far as I can tell, using the decoding channel and streamproc technique, the stream will abort the first time there are too few samples returned.

I would just decode/process some more sample data until there is enough to fill the buffer. Something like this...

Code: [Select]
if (excess buffered from last time) {
     copy excess to buffer
     advance buffer pointer
}
while (buffer not full) {
     decode some data
     feed data to DSP plugin
     put result in buffer
     advance buffer pointer
}
if (excess) {
     buffer excess for next time
}