BASS.NET API for the Un4seen BASS Audio LibraryDSP_StreamCopy ClassBASS.NET API for the Un4seen BASS Audio Library
Stream Copy DSP (to clone any BASS stream).
Inheritance Hierarchy

SystemObject
  Un4seen.Bass.MiscBaseDSP
    Un4seen.Bass.MiscDSP_StreamCopy

Namespace: Un4seen.Bass.Misc
Assembly: Bass.Net (in Bass.Net.dll) Version: 2.4.12.0
Syntax

[SerializableAttribute]
public sealed class DSP_StreamCopy : BaseDSP

The DSP_StreamCopy type exposes the following members.

Constructors

  NameDescription
Public methodDSP_StreamCopy
Creates a new instance of the Stream Copy DSP, not assigning the DSP yet.
Public methodDSP_StreamCopy(Int32, Int32)
Creates a new instance of the Stream Copy DSP, which already assigns the DSP (Start will be called automatically).
Top
Properties

  NameDescription
Public propertyChannelBitwidth
This property returns the actual bitwidth of the sample data of the channel (e.g. 8, 16, 32).
(Inherited from BaseDSP.)
Public propertyChannelHandle
Gets or Sets the channel that the DSP is being applied to.
(Inherited from BaseDSP.)
Public propertyChannelInfo
Gets the BASS_CHANNELINFO of the assigned ChannelHandle.
(Inherited from BaseDSP.)
Public propertyChannelNumChans
This property returns the actual number of channles of the sample data BASS is using with the channel (e.g. 1=mono, 2=stereo, etc.).
(Inherited from BaseDSP.)
Public propertyChannelSampleRate
This property returns the actual sample rate in Hz of the sample data BASS is using with the channel (e.g. 44100).
(Inherited from BaseDSP.)
Public propertyDSPHandle
Returns the actual DSP handle (or 0, if the DSP has not been assigned to the channel).
(Inherited from BaseDSP.)
Public propertyDSPPriority
Sets or reassigns the priority of the DSP, which determines it's position in the DSP chain - DSPs with higher priority are called before those with lower.
(Inherited from BaseDSP.)
Public propertyDSPProc
Returns the actual DSPPROC (callback delegate) which is used by the DSP.
(Inherited from BaseDSP.)
Public propertyIsAssigned
Is the DSP assigned to an active channel? (=assigned, =not assigned).
(Inherited from BaseDSP.)
Public propertyIsBypassed
Returns if the DSP is currently bypassed (=bypass).
(Inherited from BaseDSP.)
Public propertyIsOutputBuffered
Gets or Sets, if the StreamCopy should be buffered or not (default is ).
Public propertyOutputLatency
Gets or Sets the output latency in milliseconds (default = 0).
Public propertySourceMixerStream
Gets or Sets the mixer handle of the mixer from which you are cloning (see BASSmix addon).
Public propertyStreamCopy
Gets the copied BASS stream (the created custom push stream).
Public propertyStreamCopyDevice
Gets or Sets the BASS device, which should be used for the stream copy.
Public propertyStreamCopyFlags
Gets or Sets the BASSFlag flags which should be used to create the StreamCopy.
Public propertyTargetMixerStream
Gets or Sets the mixer handle of the mixer to which the StreamCopy handle should be added (see BASSmix addon).
Public propertyUser
Gets or Sets the value of the user instance data to pass to the callback function (see DSPCallback(Int32, Int32, IntPtr, Int32, IntPtr)).
(Inherited from BaseDSP.)
Top
Methods

  NameDescription
Public methodDispose
Implement IDisposable.
(Inherited from BaseDSP.)
Public methodDSPCallback
User defined DSP callback function which does the stream copy operation. Not for direct use in your application!
(Overrides BaseDSPDSPCallback(Int32, Int32, IntPtr, Int32, IntPtr).)
Protected methodFinalize
Finalization code.
(Inherited from BaseDSP.)
Public methodOnBypassChanged
Occures when the SetBypass(Boolean) method was called.
(Overrides BaseDSPOnBypassChanged.)
Public methodOnChannelChanged
Occures when the ChannelHandle has been changed.
(Overrides BaseDSPOnChannelChanged.)
Public methodOnStarted
Occures when the Start method was called. Actually creates the StreamCopy custom push stream here.
(Overrides BaseDSPOnStarted.)
Public methodOnStopped
Occures when the Stop method was called. Actually frees the StreamCopy custom stream here.
(Overrides BaseDSPOnStopped.)
Public methodRaiseNotification
Fires the Notification event.
(Inherited from BaseDSP.)
Public methodReSync
Re-Synchronizes the StreamCopy with the ChannelHandle when using BASSmix mixer channels.
Public methodSetBypass
Sets the Bypass mode.
(Inherited from BaseDSP.)
Public methodStart
Assigns the DSP to the channel (actually starts using the DSP).
(Inherited from BaseDSP.)
Public methodStop
Stops (removes) the DSP from the channel.
(Inherited from BaseDSP.)
Public methodToString
Returns the name of the DSP.
(Overrides BaseDSPToString.)
Top
Events

  NameDescription
Public eventNotification
Event handler used to notify that the DSP has processed some data.
(Inherited from BaseDSP.)
Top
Remarks

A Stream Copy DSP actually provides a synchronized clone of the ChannelHandle which can for example be used to playout the StreamCopy to another device or spreakers. Use the StreamCopyDevice property to specify the BASS device which should be used for the stream copy. Use the StreamCopyFlags property to specify additional flags which should be used create the stream copy.

The ChannelHandle and the StreamCopy handles will be linked. So the StreamCopy channel will be started/stopped/paused/resumed together with the original ChannelHandle.

When using with a mixer stream (see Un4seen.Bass.AddOn.Mix) you need to set the SourceMixerStream and TargetMixerStream properties accordingly. It is possible to copy either a mixer source stream or the mixer stream itself (in both cases the SourceMixerStream handle must be set - so the ChannelHandle might be equal to the ChannelHandle). If you specify a TargetMixerStream the StreamCopy handle will automatically be add as a new source channel to that mixer (in such case make sure to use BASS_STREAM_DECODE as a StreamCopyFlags). The IsOutputBuffered property will define, if the final output is a buffered stream or not (so if using with a TargetMixerStream you might still need to set this to ).

The DSP automatically handles 8-, 16- or 32-bit sample data accordingly. 8- and 16-bit sample data will be clipped if needed, 32-bit floating-point values will not be clipped.

Use Start to assign the DSP to the channel. Use Stop to remove the DSP (you can (re)assign the DSP at any time again by calling Start). Changing the DSPPriority when the DSP is already assigned will automatically reassign the DSP.

Use the ChannelHandle property to change the original channel assignment at any time. If the DSP has already been assigned, the DSP will immediately be reassigned to the new channel.

NOTE: This DSP does NOT support the Notification event!

Internally the DSP_StreamCopy implementation uses BASS_StreamPutData(Int32, IntPtr, Int32) to keep the sample data of the original stream in sync with the custom created push stream (the 'StreamCopy' is created via BASS_StreamCreatePush(Int32, Int32, BASSFlag, IntPtr) and linked to the source stream via BASS_ChannelSetLink(Int32, Int32)). It is not recommended to use this DSP with ASIO sources (use the DSP_BufferStream DSP instead).

So when you now call the Stop method on the DSP_StreamCopy instance the copied-stream will be freed (but not the source stream). The same is true, if the GarbageCollector disposes your DSP_StreamCopy instance, since within the dispose implementation the Stop method will be called.

However, stopping the source stream will not reset the copied-stream! Also the copied-stream will not be freed automatically, if you simply free the original stream (only the DSP will be removed from it).

So when you free your source stream (or the playback ends) it is advised to call the Stop method on your DSP_StreamCopy method as well. So that the DSP is removed and the copied-stream will be removed/freed! When you need to start the original stream again, simply call Start again.

Here is a full overview of all possible scenarios:

A) Stopping/Releasing the source stream: -> call Stop to also free the StreamCopy (and internal DSP).

A.1) Restarting the same source stream: -> call Start if you need to start the source stream again.

A.2) Assigning a new source stream: -> set the ChannelHandle to the new source stream (see B).

B) Changing the ChannelHandle of the DSP_StreamCopy instance: -> the current StreamCopy (if existing) will be freed automatically (and internal DSP). A new StreamCopy is created automatically for the new source stream.

C) Changing the StreamCopyDevice of the DSP_StreamCopy instance: -> the current StreamCopy (if existing) will be freed automatically. A new StreamCopy is created automatically on the new device.

D) Disposing of the DSP_StreamCopy instance (e.g. via GC): -> the current StreamCopy (if existing) will be freed automatically (and internal DSP).

Examples

Create a copy of a regular BASS stream and play it on another BASS device:
VB
Private _streamCopy As DSP_StreamCopy
...
Bass.BASS_Init(2, 44100, BASSInit.BASS_DEVICE_DEFAULT, IntPtr.Zero)
Bass.BASS_Init(1, 44100, BASSInit.BASS_DEVICE_DEFAULT, IntPtr.Zero)
...
' create the original stream (on device 1)
Dim stream As Integer = Bass.BASS_StreamCreateFile("test.mp3", 0, 0, BASSFlag.BASS_SAMPLE_FLOAT)
' start playing it...
Bass.BASS_ChannelPlay(stream, False)
...
_streamCopy = New DSP_StreamCopy()
BASS_INFO info = Bass.BASS_GetInfo()
_streamCopy.OutputLatency = info.latency
' the stream to copy
_streamCopy.ChannelHandle = stream
_streamCopy.DSPPriority = -1000
' use device 2 to create the copy on
_streamCopy.StreamCopyDevice = 2
' use the exact same stream flags for the stream copy
_streamCopy.StreamCopyFlags = _streamCopy.ChannelInfo.flags
_streamCopy.Start()
private DSP_StreamCopy _streamCopy;
...
Bass.BASS_Init(2, 44100, BASSInit.BASS_DEVICE_DEFAULT, IntPtr.Zero);
Bass.BASS_Init(1, 44100, BASSInit.BASS_DEVICE_DEFAULT, IntPtr.Zero);
...
// create the original stream (on device 1)
int stream = Bass.BASS_StreamCreateFile("test.mp3", 0, 0, BASSFlag.BASS_SAMPLE_FLOAT);
// start playing it...
Bass.BASS_ChannelPlay(stream, false);
...
_streamCopy = new DSP_StreamCopy();
BASS_INFO info = Bass.BASS_GetInfo();
_streamCopy.OutputLatency = info.latency;
// the stream to copy
_streamCopy.ChannelHandle = stream;
_streamCopy.DSPPriority = -1000;
// use device 2 to create the copy on
_streamCopy.StreamCopyDevice = 2;
// use the exact same stream flags for the stream copy
_streamCopy.StreamCopyFlags = _streamCopy.ChannelInfo.flags;
_streamCopy.Start();
Create a copy of a regular BASS stream and play it on other speakers:
VB
Private _streamCopy As DSP_StreamCopy
...
Bass.BASS_Init(-1, 44100, BASSInit.BASS_DEVICE_SPEAKERS, IntPtr.Zero)
...
' create the original stream (using front speakers)
Dim stream As Integer = Bass.BASS_StreamCreateFile("test.mp3", 0, 0, 
                             BASSFlag.BASS_SAMPLE_FLOAT Or BASSFlag.BASS_SPEAKER_FRONT)
' start playing it...
Bass.BASS_ChannelPlay(stream, False)
...
_streamCopy = New DSP_StreamCopy()
BASS_INFO info = Bass.BASS_GetInfo();
_streamCopy.OutputLatency = info.latency;
' the stream to copy
_streamCopy.ChannelHandle = stream
_streamCopy.DSPPriority = -1000
' use different speaker flags for the stream copy
_streamCopy.StreamCopyFlags = BASSFlag.BASS_SAMPLE_FLOAT Or BASSFlag.BASS_SPEAKER_REAR
_streamCopy.Start()
private DSP_StreamCopy _streamCopy;
...
Bass.BASS_Init(-1, 44100, BASSInit.BASS_DEVICE_SPEAKERS, IntPtr.Zero);
...
// create the original stream (using front speakers)
int stream = Bass.BASS_StreamCreateFile("test.mp3", 0, 0, 
                  BASSFlag.BASS_SAMPLE_FLOAT | BASSFlag.BASS_SPEAKER_FRONT);
// start playing it...
Bass.BASS_ChannelPlay(stream, false);
...
_streamCopy = new DSP_StreamCopy();
BASS_INFO info = Bass.BASS_GetInfo();
_streamCopy.OutputLatency = info.latency;
// the stream to copy
_streamCopy.ChannelHandle = stream;
_streamCopy.DSPPriority = -1000;
// use different speaker flags for the stream copy
_streamCopy.StreamCopyFlags = BASSFlag.BASS_SAMPLE_FLOAT | BASSFlag.BASS_SPEAKER_REAR;
_streamCopy.Start();
Create a copy of a BASSmix source mixer stream and copy it to another BASSmix mixer as a source:
VB
Private _streamCopy As DSP_StreamCopy
...
_streamCopy = New DSP_StreamCopy()
BASS_INFO info = Bass.BASS_GetInfo();
_streamCopy.OutputLatency = info.latency;
_streamCopy.DSPPriority = -9000
...
' assign the copy
_streamCopy.ChannelHandle = _mixerSourceStream ' the stream to copy
_streamCopy.StreamCopyDevice = 0
_streamCopy.StreamCopyFlags = BASSFlag.BASS_STREAM_DECODE
_streamCopy.SourceMixerStream = MixerStreamA
_streamCopy.TargetMixerStream = MixerStreamB
_streamCopy.IsOutputBuffered = true
_streamCopy.Start()
...
' start playing the original source
BassMix.BASS_Mixer_ChannelPlay(_mixerSourceStream)
If _streamCopy.IsAssigned Then
  _streamCopy.ReSync();
End If
...
' pausing the original source
BassMix.BASS_Mixer_ChannelPause(_mixerSourceStream)
...
private DSP_StreamCopy _streamCopy;
...
_streamCopy = new DSP_StreamCopy();
BASS_INFO info = Bass.BASS_GetInfo();
_streamCopy.OutputLatency = info.latency;
_streamCopy.DSPPriority = -9000;
...
// assign the copy
_streamCopy.ChannelHandle = _mixerSourceStream; // the stream to copy
_streamCopy.StreamCopyDevice = 0;
_streamCopy.StreamCopyFlags = BASSFlag.BASS_STREAM_DECODE;
_streamCopy.SourceMixerStream = MixerStreamA;
_streamCopy.TargetMixerStream = MixerStreamB;
_streamCopy.IsOutputBuffered = true;
_streamCopy.Start();
...
// start playing the original source
BassMix.BASS_Mixer_ChannelPlay(_mixerSourceStream);
if (_streamCopy.IsAssigned)
  _streamCopy.ReSync();
...
// pausing the original source
BassMix.BASS_Mixer_ChannelPause(_mixerSourceStream);
...
See Also

Reference