Namespace: Un4seen.Bass
Assembly: Bass.Net (in Bass.Net.dll) Version: 2.4.17.5
[DllImportAttribute("bass")] public static int BASS_ChannelSetDSP( int handle, DSPPROC proc, IntPtr user, int priority )
Parameters
- handle
- Type: SystemInt32
The channel handle... a HSTREAM, HMUSIC, or HRECORD. - proc
- Type: Un4seen.BassDSPPROC
The callback function (see DSPPROC). - user
- Type: SystemIntPtr
User instance data to pass to the callback function. - priority
- Type: SystemInt32
The priority of the new DSP, which determines it's position in the DSP chain - DSPs with higher priority are called before those with lower.
Return Value
Type: Int32If succesful, then the new DSP's handle is returned, else 0 is returned. Use BASS_ErrorGetCode to get the error code.
The channel does not have to be playing to set a DSP function, they can be set before and while playing.
Equally, you can also remove them at any time. Use BASS_ChannelRemoveDSP(Int32, Int32) to remove a DSP function.
Multiple DSP functions may be used per channel, in which case the order that the functions are called is determined by their priorities. Any DSPs that have the same priority are called in the order that they were added.
DSP functions can be applied to MOD musics and streams, but not samples. If you want to apply a DSP function to a sample, then you should stream the sample.
ERROR CODE | Description |
---|---|
BASS_ERROR_HANDLE | handle is not a valid channel. |
private float _gainDB = 0f; private int _stream = 0; private DSPPROC _myDSPProc; // make it global, so that the GC can not remove it ... _gainDB = 6f; // amplify by +6dB _stream = Bass.BASS_StreamCreateFile("test.mp3", 0, 0, BASSFlag.BASS_STREAM_AUTOFREE | BASSFlag.BASS_SAMPLE_FLOAT); // set a DSP user callback method _myDSPProc = new DSPPROC(MyDSPGain); // set the user DSP callback Bass.BASS_ChannelSetDSP(_stream, _myDSPProc, IntPtr.Zero, 0); ... // this is the actual processing method private void MyDSPGain(int handle, int channel, IntPtr buffer, int length, IntPtr user) { // the global variable _gainDB contains the amplification value in dB! if (_gainDB == 0f || length == 0 || buffer == IntPtr.Zero) return; // convert the _gainDB value to a float float _gainAmplification = (float)Math.Pow(10d, _gainDB / 20d); // number of bytes in 32-bit floats, since length is in bytes int l4 = length/4; float[] data = new float[l4]; // copy from managed to unmanaged memory Marshal.Copy(buffer, data, 0, l4); // apply gain, assumeing using 32-bit floats (no clipping here ;-) for (int a=0; a<l4; a++) data[a] = data[a] * _gainAmplification; // copy back from unmanaged to managed memory Marshal.Copy(data, 0, buffer, l4); }
C# user can be a little more lucky, since C# supports unsafe code blocks and native pointer access - which will be shown in the following example:
private unsafe void MyDSPGain(int handle, int channel, IntPtr buffer, int length, IntPtr user) { if (_gainDB == 1f || length == 0 || buffer == IntPtr.Zero) return; // convert the _gainDB value to a float float _gainAmplification = (float)Math.Pow(10d, _gainDB / 20d); // length is in bytes, so the number of floats to process is length/4 int l4 = length / 4; // cast the given buffer IntPtr to a native pointer to float values float *data = (float*)buffer; for (int a=0; a<l4; a++) { data[a] = data[a] * _gainAmplification; // alternatively you can also use: // *data = *data * _gainAmplification; // data++; } }