Class BassMix
BassMix is a BASS addon providing the ability to mix together multiple BASS channels, with resampling and matrix mixing features.
Namespace: System.Dynamic.ExpandoObject
Assembly: ManagedBass.Mix.dll
Syntax
public static class BassMix : object
Properties
MixerBufferLength
The source channel Buffer size multiplier... 1 (min) to 5 (max).
Declaration
public static int MixerBufferLength { get; set; }
Property Value
Int32
|
Remarks
If the value specified is outside this range, it is automatically capped. When a source channel has buffering enabled, the mixer will Buffer the decoded data, so that it is available to the ChannelGetData(Int32, IntPtr, Int32) and ChannelGetLevel(Int32) functions. To reach the source channel's Buffer size, the multiplier (multiple) is applied to the PlaybackBufferLength setting at the time of the mixer's creation. If the source is played at it's default rate, then the Buffer only need to be as big as the mixer's Buffer. But if it's played at a faster rate, then the Buffer needs to be bigger for it to contain the data that is currently being heard from the mixer. For example, playing a channel at 2x its normal speed would require the Buffer to be 2x the normal size (multiple = 2). Larger buffers obviously require more memory, so the multiplier should not be set higher than necessary. The default multiplier is 2x. Changes only affect subsequently setup channel buffers. An existing channel can have its Buffer reinitilized by disabling and then re-enabling the MixerBuffer flag using ChannelFlags(Int32, BassFlags, BassFlags).
MixerPositionEx
BASSmix add-on: How far back to keep record of source positions to make available for ChannelGetPosition(Int32, PositionFlags, Int32), in milliseconds.
Declaration
public static int MixerPositionEx { get; set; }
Property Value
Int32
|
Remarks
If a mixer is not a decoding channel (not using the BassFlag.Decode flag), this config setting will just be a minimum and the mixer will always have a position record at least equal to its playback Buffer Length, as determined by the PlaybackBufferLength config option. The default setting is 2000ms. Changes only affect newly created mixers, not any that already exist.
SplitBufferLength
The splitter Buffer Length in milliseconds... 100 (min) to 5000 (max).
Declaration
public static int SplitBufferLength { get; set; }
Property Value
Int32
|
Remarks
If the value specified is outside this range, it is automatically capped. When a source has its first splitter stream created, a Buffer is allocated for its sample data, which all of its subsequently created splitter streams will share. This config option determines how big that Buffer is. The default is 2000ms. The Buffer will always be kept as empty as possible, so its size does not necessarily affect latency; it just determines how far splitter streams can drift apart before there are Buffer overflow issues for those left behind. Changes do not affect buffers that have already been allocated; any sources that have already had splitter streams created will continue to use their existing buffers.
Methods
ChannelAddFlag(Int32, BassFlags)
Adds a flag to Mixer.
Declaration
public static bool ChannelAddFlag(int handle, BassFlags flag)
Parameters
Int32
handle
|
BassFlags
flag
|
Returns
Boolean
|
ChannelFlags(Int32, BassFlags, BassFlags)
Modifies and/or retrieves a channel's mixer flags.
Declaration
public static BassFlags ChannelFlags(int Handle, BassFlags Flags, BassFlags Mask)
Parameters
Int32
Handle
The handle of the mixer source channel to modify (which was add via MixerAddChannel(Int32, Int32, BassFlags) or MixerAddChannel(Int32, Int32, BassFlags, Int64, Int64)) beforehand). |
||||||||||||||
BassFlags
Flags
A combination of these flags.
|
||||||||||||||
BassFlags
Mask
The flags (as above) to modify. Flags that are not included in this are left as they are, so it can be set to 0 (Default) in order to just retrieve the current flags. To modify the speaker flags, any of the Speaker flags can be used in the mask (no need to include all of them). |
Returns
BassFlags
If successful, the channel's updated flags are returned, else -1 is returned. Use LastError to get the error code. |
Remarks
This function only deals with the channel's mixer related flags. The channel's standard flags, for example looping (Loop), are unaffected - use ChannelFlags(Int32, BassFlags, BassFlags) to modify them.
ChannelGetData(Int32, IntPtr, Int32)
Retrieves the immediate sample data (or an FFT representation of it) of a mixer source channel.
Declaration
public static int ChannelGetData(int Handle, IntPtr Buffer, int Length)
Parameters
Int32
Handle
The handle of the mixer source channel (which was addded via MixerAddChannel(Int32, Int32, BassFlags) or MixerAddChannel(Int32, Int32, BassFlags, Int64, Int64) beforehand). |
IntPtr
Buffer
Location to write the data as an |
Int32
Length
Number of bytes wanted, and/or DataFlags. |
Returns
Int32
If an error occurs, -1 is returned, use LastError to get the error code. When requesting FFT data, the number of bytes read from the channel (to perform the FFT) is returned. When requesting sample data, the number of bytes written to buffer will be returned (not necessarily the same as the number of bytes read when using the Float flag). When using the Available flag, the number of bytes in the channel's buffer is returned. |
Remarks
This function is like the standard
If the mixer is a decoding channel, then the channel's most recent data will be returned. Otherwise, the data will be in sync with what is currently being heard from the mixer, unless the buffer is too small so that the currently heard data isn't in it. The MixerBufferLength config option can be used to set the buffer size.
ChannelGetData(Int32, Byte[], Int32)
Retrieves the immediate sample data (or an FFT representation of it) of a mixer source channel.
Declaration
public static int ChannelGetData(int Handle, byte[] Buffer, int Length)
Parameters
Int32
Handle
The handle of the mixer source channel (which was addded via MixerAddChannel(Int32, Int32, BassFlags) or MixerAddChannel(Int32, Int32, BassFlags, Int64, Int64) beforehand). |
Byte[]
Buffer
byte[] to write the data to. |
Int32
Length
Number of bytes wanted, and/or DataFlags. |
Returns
Int32
If an error occurs, -1 is returned, use LastError to get the error code. When requesting FFT data, the number of bytes read from the channel (to perform the FFT) is returned. When requesting sample data, the number of bytes written to buffer will be returned (not necessarily the same as the number of bytes read when using the Float flag). When using the Available flag, the number of bytes in the channel's buffer is returned. |
Remarks
This function is like the standard
If the mixer is a decoding channel, then the channel's most recent data will be returned. Otherwise, the data will be in sync with what is currently being heard from the mixer, unless the buffer is too small so that the currently heard data isn't in it. The MixerBufferLength config option can be used to set the buffer size.
ChannelGetData(Int32, Int16[], Int32)
Retrieves the immediate sample data (or an FFT representation of it) of a mixer source channel.
Declaration
public static int ChannelGetData(int Handle, short[] Buffer, int Length)
Parameters
Int32
Handle
The handle of the mixer source channel (which was addded via MixerAddChannel(Int32, Int32, BassFlags) or MixerAddChannel(Int32, Int32, BassFlags, Int64, Int64) beforehand). |
Int16[]
Buffer
short[] to write the data to. |
Int32
Length
Number of bytes wanted, and/or DataFlags. |
Returns
Int32
If an error occurs, -1 is returned, use LastError to get the error code. When requesting FFT data, the number of bytes read from the channel (to perform the FFT) is returned. When requesting sample data, the number of bytes written to buffer will be returned (not necessarily the same as the number of bytes read when using the Float flag). When using the Available flag, the number of bytes in the channel's buffer is returned. |
Remarks
This function is like the standard
If the mixer is a decoding channel, then the channel's most recent data will be returned. Otherwise, the data will be in sync with what is currently being heard from the mixer, unless the buffer is too small so that the currently heard data isn't in it. The MixerBufferLength config option can be used to set the buffer size.
ChannelGetData(Int32, Int32[], Int32)
Retrieves the immediate sample data (or an FFT representation of it) of a mixer source channel.
Declaration
public static int ChannelGetData(int Handle, int[] Buffer, int Length)
Parameters
Int32
Handle
The handle of the mixer source channel (which was addded via MixerAddChannel(Int32, Int32, BassFlags) or MixerAddChannel(Int32, Int32, BassFlags, Int64, Int64) beforehand). |
Int32[]
Buffer
int[] to write the data to. |
Int32
Length
Number of bytes wanted, and/or DataFlags. |
Returns
Int32
If an error occurs, -1 is returned, use LastError to get the error code. When requesting FFT data, the number of bytes read from the channel (to perform the FFT) is returned. When requesting sample data, the number of bytes written to buffer will be returned (not necessarily the same as the number of bytes read when using the Float flag). When using the Available flag, the number of bytes in the channel's buffer is returned. |
Remarks
This function is like the standard
If the mixer is a decoding channel, then the channel's most recent data will be returned. Otherwise, the data will be in sync with what is currently being heard from the mixer, unless the buffer is too small so that the currently heard data isn't in it. The MixerBufferLength config option can be used to set the buffer size.
ChannelGetData(Int32, Single[], Int32)
Retrieves the immediate sample data (or an FFT representation of it) of a mixer source channel.
Declaration
public static int ChannelGetData(int Handle, float[] Buffer, int Length)
Parameters
Int32
Handle
The handle of the mixer source channel (which was addded via MixerAddChannel(Int32, Int32, BassFlags) or MixerAddChannel(Int32, Int32, BassFlags, Int64, Int64) beforehand). |
Single[]
Buffer
float[] to write the data to. |
Int32
Length
Number of bytes wanted, and/or DataFlags. |
Returns
Int32
If an error occurs, -1 is returned, use LastError to get the error code. When requesting FFT data, the number of bytes read from the channel (to perform the FFT) is returned. When requesting sample data, the number of bytes written to buffer will be returned (not necessarily the same as the number of bytes read when using the Float flag). When using the Available flag, the number of bytes in the channel's buffer is returned. |
Remarks
This function is like the standard
If the mixer is a decoding channel, then the channel's most recent data will be returned. Otherwise, the data will be in sync with what is currently being heard from the mixer, unless the buffer is too small so that the currently heard data isn't in it. The MixerBufferLength config option can be used to set the buffer size.
ChannelGetEnvelopePosition(Int32, MixEnvelope, ref Single)
Retrieves the current position and value of an envelope on a channel.
Declaration
public static long ChannelGetEnvelopePosition(int Handle, MixEnvelope Type, ref float Value)
Parameters
Int32
Handle
The mixer source channel handle (which was add via MixerAddChannel(Int32, Int32, BassFlags) or MixerAddChannel(Int32, Int32, BassFlags, Int64, Int64)) beforehand). |
MixEnvelope
Type
The envelope to get the position/value of. |
Single
Value
A reference to a variable to receive the envelope value at the current position. |
Returns
Int64
If successful, the current position of the envelope is returned, else -1 is returned. Use LastError to get the error code. |
Remarks
The envelope's current position is not necessarily what is currently being heard, due to buffering.
ChannelGetLevel(Int32)
Retrieves the level (peak amplitude) of a mixer source channel.
Declaration
public static int ChannelGetLevel(int Handle)
Parameters
Int32
Handle
The handle of the mixer source channel (which was add via MixerAddChannel(Int32, Int32, BassFlags) or MixerAddChannel(Int32, Int32, BassFlags, Int64, Int64)) beforehand). |
Returns
Int32
If an error occurs, -1 is returned, use LastError to get the error code. If successful, the level of the left channel is returned in the low word (low 16-bits), and the level of the right channel is returned in the high word (high 16-bits). If the channel is mono, then the low word is duplicated in the high word. The level ranges linearly from 0 (silent) to 32768 (max). 0 will be returned when a channel is stalled. |
Remarks
This function is like the standard
If the mixer is a decoding channel, then the channel's most recent data will be used to get the level. Otherwise, the level will be in sync with what is currently being heard from the mixer, unless the buffer is too small so that the currently heard data isn't in it. The MixerBufferLength config option can be used to set the buffer size.
ChannelGetLevel(Int32, Single[], Single, LevelRetrievalFlags)
Retrieves the level of a mixer source channel.
Declaration
public static int ChannelGetLevel(int Handle, float[] Levels, float Length, LevelRetrievalFlags Flags)
Parameters
Int32
Handle
The handle of the mixer source channel (which was add via MixerAddChannel(Int32, Int32, BassFlags) or MixerAddChannel(Int32, Int32, BassFlags, Int64, Int64)) beforehand). |
Single[]
Levels
An array to receive the levels. |
Single
Length
The amount of data to inspect to calculate the level, in seconds. The maximum is 1 second. Less data than requested may be used if the full amount is not available, eg. if the source's buffer (determined by the MixerBufferLength config option) is shorter. |
LevelRetrievalFlags
Flags
A combination of LevelRetrievalFlags. |
Returns
Int32
If an error occurs, -1 is returned, use LastError to get the error code. If successful, the level of the left channel is returned in the low word (low 16-bits), and the level of the right channel is returned in the high word (high 16-bits). If the channel is mono, then the low word is duplicated in the high word. The level ranges linearly from 0 (silent) to 32768 (max). 0 will be returned when a channel is stalled. |
Remarks
This function is like the standard
ChannelGetMatrix(Int32, Single[,])
Retrieves a channel's mixing matrix, if it has one.
Declaration
public static bool ChannelGetMatrix(int Handle, float[, ] Matrix)
Parameters
Int32
Handle
The mixer source channel handle (which was add via MixerAddChannel(Int32, Int32, BassFlags) or MixerAddChannel(Int32, Int32, BassFlags, Int64, Int64)) beforehand). |
Single[,]
Matrix
The 2-dimentional array (float[,]) where to write the matrix. |
Returns
Boolean
If successful, a true is returned, else false is returned. Use LastError to get the error code. |
Remarks
For more details see ChannelSetMatrix(Int32, Single[,]). The array must be big enough to get the matrix.
ChannelGetMixer(Int32)
Retrieves the mixer that a channel is plugged into.
Declaration
public static int ChannelGetMixer(int Handle)
Parameters
Int32
Handle
The mixer source channel handle (which was add via MixerAddChannel(Int32, Int32, BassFlags) or MixerAddChannel(Int32, Int32, BassFlags, Int64, Int64) beforehand). |
Returns
Int32
If successful, the mixer stream's handle is returned, else 0 is returned. Use LastError to get the error code. |
ChannelGetPosition(Int32, PositionFlags)
Retrieves the playback position of a mixer source channel.
Declaration
public static long ChannelGetPosition(int Handle, PositionFlags Mode = PositionFlags.Bytes)
Parameters
Int32
Handle
The mixer source channel handle (which was addded via MixerAddChannel(Int32, Int32, BassFlags) or MixerAddChannel(Int32, Int32, BassFlags, Int64, Int64) beforehand). |
PositionFlags
Mode
Position mode... default = Bytes. |
Returns
Int64
If an error occurs, -1 is returned, use LastError to get the error code. If successful, the position is returned. |
Remarks
This function is like the standard ChannelGetPosition(Int32, PositionFlags), but it compensates for the mixer's buffering to return the source channel position that is currently being heard. So when used with a decoding channel (eg. a mixer source channel), this method will return the current decoding position. But if the mixer output is being played, then there is a playback buffer involved. This function compensates for that, to return the position that is currently being heard. If the mixer itself is a decoding channel, then this function is identical to using ChannelGetPosition(Int32, PositionFlags).
ChannelGetPosition(Int32, PositionFlags, Int32)
Retrieves the playback position of a mixer source channel, optionally accounting for some latency.
Declaration
public static long ChannelGetPosition(int Handle, PositionFlags Mode, int Delay)
Parameters
Int32
Handle
The mixer source channel handle (which was addded via MixerAddChannel(Int32, Int32, BassFlags) or MixerAddChannel(Int32, Int32, BassFlags, Int64, Int64) beforehand). |
PositionFlags
Mode
Position mode. |
Int32
Delay
How far back (in bytes) in the mixer output to get the source channel's position from. |
Returns
Int64
If an error occurs, -1 is returned, use LastError to get the error code. If successful, the channel's position is returned. |
Remarks
ChannelGetPosition(Int32, PositionFlags) compensates for the mixer's playback buffering to give the position that is currently being heard, but if the mixer is feeding some other output system, it will not know how to compensate for that. This function fills that gap by allowing the latency to be specified in the call. This functionality requires the mixer to keep a record of its sources' position going back some time, and that is enabled via the MixerPositionEx flag when a mixer is created, with the MixerPositionEx config option determining how far back the position record goes. If the mixer is not a decoding channel (not using the Decode flag), then it will automatically have a position record at least equal to its playback buffer length.
ChannelHasFlag(Int32, BassFlags)
Gets whether a flag is present.
Declaration
public static bool ChannelHasFlag(int handle, BassFlags flag)
Parameters
Int32
handle
|
BassFlags
flag
|
Returns
Boolean
|
ChannelRemoveFlag(Int32, BassFlags)
Removes a flag from Mixer.
Declaration
public static bool ChannelRemoveFlag(int handle, BassFlags flag)
Parameters
Int32
handle
|
BassFlags
flag
|
Returns
Boolean
|
ChannelRemoveSync(Int32, Int32)
Removes a synchronizer from a mixer source channel.
Declaration
public static bool ChannelRemoveSync(int Handle, int Sync)
Parameters
Int32
Handle
The mixer source channel handle (as returned by MixerAddChannel(Int32, Int32, BassFlags) or MixerAddChannel(Int32, Int32, BassFlags, Int64, Int64)). |
Int32
Sync
Handle of the synchronizer to remove (return value of a previous ChannelSetSync(Int32, SyncFlags, Int64, SyncProcedure, IntPtr) call). |
Returns
Boolean
If succesful, true is returned, else false is returned. Use LastError to get the error code. |
Remarks
This function can only remove syncs that were set via ChannelSetSync(Int32, SyncFlags, Int64, SyncProcedure, IntPtr), not those that were set via
ChannelSetEnvelope(Int32, MixEnvelope, MixerNode[], Int32)
Sets an envelope to modify the sample rate, volume or pan of a channel over a period of time.
Example
Set an envelope to bounce the pan position between left and right every 4 seconds.
var nodes = new MixerNode[4];
nodes[0].Position = 0;
nodes[0].Value = 0; // start at centre
nodes[1].Position = Bass.ChannelSeconds2Bytes(mixer, 1);
nodes[1].Value = -1; // full left after 1 second
nodes[2].Position = Bass.ChannelSeconds2Bytes(mixer, 3);
nodes[2].Value = 1; // full right after 3 seconds
nodes[3].Position = Bass.ChannelSeconds2Bytes(mixer, 4);
nodes[3].Value = 0; // back at centre after 4 seconds
// apply the envelope, looped
BassMix.ChannelSetEnvelope(channel, MixerEnvelope.Pan | MixerEnvelope.Loop, nodes, 4);
Declaration
public static bool ChannelSetEnvelope(int Handle, MixEnvelope Type, MixerNode[] Nodes, int Length = 0)
Parameters
Int32
Handle
The mixer source channel handle. |
MixEnvelope
Type
The envelope to get the position/value of. |
MixerNode[]
Nodes
The array of envelope nodes, which should have sequential positions. |
Int32
Length
The number of elements in the nodes array... 0 = no envelope. |
Returns
Boolean
If successful, true is returned, else false is returned. Use LastError to get the error code. |
Remarks
Envelopes are applied on top of the channel's attributes, as set via
ChannelGetEnvelopePosition(Int32, MixEnvelope, ref Single) can be used to get the current envelope position, and a MixerEnvelope sync can be set via ChannelSetSync(Int32, SyncFlags, Int64, SyncProcedure, IntPtr) to be informed of when an envelope ends. The function can be called again from such a sync, in order to set a new envelope to follow the old one.
Any previous envelope of the same type is replaced by the new envelope. A copy is made of the nodes array, so it does not need to persist beyond this function call.
Note: Envelopes deal in mixer positions, not sources! You might use ChannelSetEnvelopePosition(Int32, MixEnvelope, Int64) to adjust the envelope to a source channel position.
ChannelSetEnvelopePosition(Int32, MixEnvelope, Int64)
Sets the current position of an envelope on a channel.
Declaration
public static bool ChannelSetEnvelopePosition(int Handle, MixEnvelope Type, long Position)
Parameters
Int32
Handle
The mixer source channel handle. |
MixEnvelope
Type
The envelope to set the position/value of. |
Int64
Position
The new envelope position, in bytes. If this is beyond the end of the envelope it will be capped or looped, depending on whether the envelope has looping enabled. |
Returns
Boolean
If successful, the current position of the envelope is returned, else -1 is returned. Use LastError to get the error code. |
Remarks
During playback, the effect of changes are not heard instantaneously, due to buffering. To reduce the delay, use the PlaybackBufferLength config option config option to reduce the buffer length.
Note: Envelopes deal in mixer positions, not sources! So when you are changing the source position (e.g. via ChannelSetPosition(Int32, Int64, PositionFlags) the envelope's positions doesn't change with it. You might use this method to align the envelope position accorting to the new source position .
ChannelSetMatrix(Int32, Single[,])
Sets a channel's mixing matrix, if it has one.
Declaration
public static bool ChannelSetMatrix(int Handle, float[, ] Matrix)
Parameters
Int32
Handle
The mixer source channel handle (which was addded via MixerAddChannel(Int32, Int32, BassFlags) or MixerAddChannel(Int32, Int32, BassFlags, Int64, Int64) beforehand) |
Single[,]
Matrix
The 2-dimensional array (float[,]) of the mixing matrix. |
Returns
Boolean
If successful, a true is returned, else false is returned. Use LastError to get the error code. |
Remarks
Normally when mixing channels, the source channels are sent to the output in the same order - the left input is sent to the left output, and so on. Sometimes something a bit more complex than that is required. For example, if the source has more channels than the output, you may want to "downmix" the source so that all channels are present in the output. Equally, if the source has fewer channels than the output, you may want to "upmix" it so that all output channels have sound. Or you may just want to rearrange the channels. Matrix mixing allows all of these.
A matrix mixer is created on a per-source basis (you can mix'n'match normal and matrix mixing), by using the MixerMatrix and/or MixerDownMix flag when calling MixerAddChannel(Int32, Int32, BassFlags) or MixerAddChannel(Int32, Int32, BassFlags, Int64, Int64). The matrix itself is a 2-dimensional array of floating-point mixing levels, with the source channels on one axis, and the output channels on the other.
ChannelSetMatrix(Int32, Single[,], Single)
Sets a channel's mixing matrix, transitioning from the current matrix.
Declaration
public static bool ChannelSetMatrix(int Handle, float[, ] Matrix, float Time)
Parameters
Int32
Handle
The mixer source channel handle (which was add via MixerAddChannel(Int32, Int32, BassFlags) or MixerAddChannel(Int32, Int32, BassFlags, Int64, Int64) beforehand). |
Single[,]
Matrix
The 2-dimensional array (float[,]) of the new mixing matrix. |
Single
Time
The time to take (in seconds) to transition from the current matrix to the specified matrix. |
Returns
Boolean
If successful, a true is returned, else false is returned. Use LastError to get the error code. |
Remarks
This method is identical to ChannelSetMatrix(Int32, Single[,]) but with the option of transitioning over time to the specified matrix. If this function or ChannelSetMatrix(Int32, Single[,]) is called while a previous matrix transition is still in progress, then that transition will be stopped. If ChannelGetMatrix(Int32, Single[,]) is called mid-transition, it will give the mid-transition matrix values.
ChannelSetPosition(Int32, Int64, PositionFlags)
Sets the playback position of a mixer source channel.
Declaration
public static bool ChannelSetPosition(int Handle, long Position, PositionFlags Mode = PositionFlags.Bytes)
Parameters
Int32
Handle
The mixer source channel handle (which was addded via MixerAddChannel(Int32, Int32, BassFlags) or MixerAddChannel(Int32, Int32, BassFlags, Int64, Int64) beforehand). |
Int64
Position
The position, in bytes. With MOD musics, the position can also be set in orders and rows instead of bytes. |
PositionFlags
Mode
Position Mode... default = Bytes. |
Returns
Boolean
If successful, then true is returned, else false is returned. Use LastError to get the error code. |
Remarks
This function works exactly like the standard ChannelSetPosition(Int32, Int64, PositionFlags), except that it also resets things for the channel in the mixer, well as supporting the MixerNoRampin flag. See ChannelGetPosition(Int32, PositionFlags) for details.
For custom looping purposes (eg. in a mixtime SyncProcedure), the standard
The playback buffer of the mixer can be flushed by using pos = 0.
ChannelSetSync(Int32, SyncFlags, Int64, SyncProcedureEx, IntPtr)
Sets up an extended synchronizer on a mixer source channel.
Declaration
public static int ChannelSetSync(int Handle, SyncFlags Type, long Parameter, SyncProcedureEx Procedure, IntPtr User = null)
Parameters
Int32
Handle
The mixer source channel handle. |
SyncFlags
Type
The type of sync. |
Int64
Parameter
The sync parameters, depends on the sync type. |
SyncProcedureEx
Procedure
The callback function which should be invoked with the sync. |
IntPtr
User
User instance data to pass to the callback function. |
Returns
Int32
If succesful, then the new synchronizer's handle is returned, else 0 is returned. Use LastError to get the error code. |
Remarks
The main difference between this method and ChannelSetSync(Int32, SyncFlags, Int64, SyncProcedure, IntPtr) is, that this method invokes the SyncProcedureEx callback. This callback contains an extra 'Offset' parameter, which defines the position of the sync occurrence within the current update cycle of the source converted to the mixer stream position. This offset might be used to calculate more accurate non-mixtime sync triggers (as with non-mixtime sync's a variable delay is to be expected, as the accuracy depends on the sync thread waking in time, and there is no guarantee when that will happen) - as well as mixtime syncs are only accurate to the current update period, as they are triggered within such. So a mixtime sync is being triggered ahead of the actual mixer position being heard. The 'Offset' parameter might be used to compensate for that.
When used on a decoding channel (eg. a mixer source channel), syncs set with ChannelSetSync(Int32, SyncFlags, Int64, SyncProcedure, IntPtr) are automatically Mixtime, which means that they will be triggered as soon as the sync event is encountered during decoding. But if the mixer output is being played, then there is a playback buffer involved, which will delay the hearing of the sync event. This function compensates for that, delaying the triggering of the sync until the event is actually heard. If the mixer itself is a decoding channel, or the Mixtime flag is used, then there is effectively no real difference between this function and ChannelSetSync(Int32, SyncFlags, Int64, SyncProcedure, IntPtr). One sync type that is slightly different is the Stalled sync, which can be either mixtime or not.
Sync types that would automatically be mixtime when using ChannelSetSync(Int32, SyncFlags, Int64, SyncProcedure, IntPtr) are not so when using this function. The Mixtime flag should be specified in those cases, or ChannelSetSync(Int32, SyncFlags, Int64, SyncProcedure, IntPtr) used instead.
When a source is removed from a mixer, any syncs that have been set on it via this function are automatically removed. If the channel is subsequently plugged back into a mixer, the previous syncs will not still be set on it. Syncs set via ChannelSetSync(Int32, SyncFlags, Int64, SyncProcedure, IntPtr) are unaffected.
ChannelSetSync(Int32, SyncFlags, Int64, SyncProcedure, IntPtr)
Sets up a synchronizer on a mixer source channel.
Declaration
public static int ChannelSetSync(int Handle, SyncFlags Type, long Parameter, SyncProcedure Procedure, IntPtr User = null)
Parameters
Int32
Handle
The mixer source channel handle. |
SyncFlags
Type
The type of sync. |
Int64
Parameter
The sync parameters, depends on the sync type. |
SyncProcedure
Procedure
The callback function which should be invoked with the sync. |
IntPtr
User
User instance data to pass to the callback function. |
Returns
Int32
If succesful, then the new synchronizer's handle is returned, else 0 is returned. Use LastError to get the error code. |
Remarks
When used on a decoding channel (eg. a mixer source channel), syncs set with ChannelSetSync(Int32, SyncFlags, Int64, SyncProcedure, IntPtr) are automatically Mixtime, which means that they will be triggered as soon as the sync event is encountered during decoding. But if the mixer output is being played, then there is a playback buffer involved, which will delay the hearing of the sync event. This function compensates for that, delaying the triggering of the sync until the event is actually heard. If the mixer itself is a decoding channel, or the Mixtime flag is used, then there is effectively no real difference between this function and ChannelSetSync(Int32, SyncFlags, Int64, SyncProcedure, IntPtr). One sync type that is slightly different is the Stalled sync, which can be either mixtime or not.
Sync types that would automatically be mixtime when using ChannelSetSync(Int32, SyncFlags, Int64, SyncProcedure, IntPtr) are not so when using this function. The Mixtime flag should be specified in those cases, or ChannelSetSync(Int32, SyncFlags, Int64, SyncProcedure, IntPtr) used instead.
When a source is removed from a mixer, any syncs that have been set on it via this function are automatically removed. If the channel is subsequently plugged back into a mixer, the previous syncs will not still be set on it. Syncs set via ChannelSetSync(Int32, SyncFlags, Int64, SyncProcedure, IntPtr) are unaffected.
CreateMixerStream(Int32, Int32, BassFlags)
Creates a mixer stream.
Declaration
public static int CreateMixerStream(int Frequency, int Channels, BassFlags Flags)
Parameters
Int32
Frequency
The sample rate of the mixer output (e.g. 44100). |
||||||||||||||||||||||||||
Int32
Channels
The number of channels... 1 = mono, 2 = stereo, 4 = quadraphonic, 6 = 5.1, 8 = 7.1. More than stereo requires WDM drivers (or the Decode flag) in Windows, and the Speaker flags are ignored. |
||||||||||||||||||||||||||
BassFlags
Flags
Any combination of these flags.
|
Returns
Int32
If successful, the new stream's handle is returned, else 0 is returned. Use LastError to get the error code. |
Remarks
Source channels are "plugged" into a mixer using the MixerAddChannel(Int32, Int32, BassFlags) or MixerAddChannel(Int32, Int32, BassFlags, Int64, Int64) functions, and "unplugged" using the MixerRemoveChannel(Int32) function. Sources can be added and removed at any time, so a mixer does not have a predetermined length and ChannelGetLength(Int32, PositionFlags) is not applicable. Likewise, seeking is not possible, except to position 0, as described below.
If the mixer output is being played (it is not a decoding channel), then there will be some delay in the effect of adding/removing source channels or changing their attributes being heard. This latency can be reduced by making use of the PlaybackBufferLength and UpdatePeriod config options. The playback buffer can be flushed by calling ChannelPlay(Int32, Boolean) (Restart = true) or ChannelSetPosition(Int32, Int64, PositionFlags) (Position = 0). That can also be done to restart a mixer that has ended.
Unless the MixerEnd flag is specified, a mixer stream will never end. When there are no sources (or the sources have ended/stalled), it'll produce no output until there's an active source. That's unless the MixerNonStop flag is used, in which case it will produce silent output while there are no active sources. The MixerEnd and MixerNonStop flags can be toggled at any time, using ChannelFlags(Int32, BassFlags, BassFlags).
Besides mixing channels, a mixer stream can be used as a resampler. In that case the freq parameter would be set the new sample rate, and the source channel's attributes would be left at their defaults. A mixer stream can also be used to downmix, upmix and generally rearrange channels, set using the ChannelSetMatrix(Int32, Single[,]).
CreateSplitStream(Int32, BassFlags, Int32[])
Creates a splitter stream (adds a reader channel to a decoding source channel).
Example
Create a splitter stream from a stereo source with the channels reversed.
// channel mapping: left = source right, right = source left
var chanmap = { 1, 0, -1 };
// create the splitter stream
var split = Bass.CreateSplitStream(source, 0, chanmap);
Declaration
public static int CreateSplitStream(int Channel, BassFlags Flags, int[] ChannelMap)
Parameters
Int32
Channel
The handle of the decoding source channel to split... a HMUSIC, HSTREAM or HRECORD. |
||||||||||||||||
BassFlags
Flags
Any combination of these flags.
|
||||||||||||||||
Int32[]
ChannelMap
The target (readers) channel mapping definition, which is an array of source channel index values (0=1st channel, 1=2nd channel, 2=3rd channel, 3=4th channel etc.) ending with a final -1 element (use null to create a 1:1 reader). |
Returns
Int32
If successful, the new reader stream's handle is returned, else 0 is returned. Use LastError to get the error code. |
Remarks
A "splitter" basically does the opposite of a mixer: it splits a single source into multiple streams rather then mixing multiple sources into a single stream. Like mixer sources, splitter sources must be decoding channels.
The splitter stream will have the same sample rate and resolution as its source, but it can have a different number of channels, as dictated by the mapping parameter. Even when the number of channels is different (and so the amount of data produced is different), ChannelGetLength(Int32, PositionFlags) will give the source length, and ChannelGetPosition(Int32, PositionFlags) will give the source position that is currently being output by the splitter stream.
All splitter streams with the same source share a buffer to access its sample data. The length of the buffer is determined by the SplitBufferLength config option; the splitter streams should not be allowed to drift apart beyond that, otherwise those left behind will suffer buffer overflows. A splitter stream's buffer state can be reset via SplitStreamReset(Int32); that can also be used to reset a splitter stream that has ended, so that it can be played again.
If the SplitSlave flag is used, the splitter stream will only receive data from the buffer and will not request more data from the source, so it can only receive data that has already been received by another splitter stream with the same source. The SplitSlave flag can be toggled at any time via ChannelFlags(Int32, BassFlags, BassFlags).
When ChannelSetPosition(Int32, Int64, PositionFlags) is used on a splitter stream, its source will be set to the requested position and the splitter stream's buffer state will be reset so that it immediately receives data from the new position. The position change will affect all of the source's splitter streams, but the others will not have their buffer state reset; they will continue to receive any buffered data before reaching the data from the new position. SplitStreamReset(Int32) can be used to reset the buffer state.
Use StreamFree(Int32) with a splitter channel to remove it from the source. When a source is freed, all of its splitter streams are automatically freed.
The ChannelMap
array defines the channel number to be created for the reader as well as which source channels should be used for each.
This enables you to create a reader stream which extract certain source channels (e.g. create a mono reader based on a stereo source), remaps the channel order (e.g. swap left and right in the reader) or even contains more channels than the source (e.g. create a 5.1 reader based on a stereo source).
MixerAddChannel(Int32, Int32, BassFlags)
Plugs a channel into a mixer.
Declaration
public static bool MixerAddChannel(int Handle, int Channel, BassFlags Flags)
Parameters
Int32
Handle
The mixer handle (created with CreateMixerStream(Int32, Int32, BassFlags)). |
||||||||||||||||||
Int32
Channel
The handle of the channel to plug into the mixer... a HMUSIC, HSTREAM or HRECORD. |
||||||||||||||||||
BassFlags
Flags
Any combination of these flags.
|
Returns
Boolean
If successful, then true is returned, else false is returned. Use LastError to get the error code. |
Remarks
Internally, a mixer will use the
Channels are 'unplugged' using the MixerRemoveChannel(Int32) function. Channels are also automatically unplugged when they are freed.
When mixing a channel, the mixer makes use of the channel's attributes (freq/volume/pan), as set with
If a multi-channel stream has more channels than the mixer output, the extra channels will be discarded. For example, if a 5.1 stream is plugged into a stereo mixer, only the front-left/right channels will be retained. That is unless matrix mixing is used.
The mixer processing is performed in floating-point, so it makes sense (for both quality and efficiency reasons) for the source channels to be floating-point too, though they do not have to be. It is also more efficient if the source channels have the same sample rate as the mixer output because no sample rate conversion is required then. When sample rate conversion is required, windowed sinc interpolation is used and the source's SampleRateConversion attribute determines how many points/samples are used in that, as follows: 0 (or below) = 4 points, 1 = 8 points, 2 = 16 points, 3 = 32 points, 4 = 64 points, 5 = 128 points, 6 (or above) = 256 points. 8 points are used if the SampleRateConversion attribute is unavailable (old BASS version). A higher number of points results in better sound quality (less aliasing and smaller transition band in the low-pass filter), but also higher CPU usage.
Platform-specific:
The sample rate conversion processing is limited to 128 points on iOS and Android. The mixer processing is also performed in fixed-point rather than floating-point on Android.
MixerAddChannel(Int32, Int32, BassFlags, Int64, Int64)
Plugs a channel into a mixer, optionally delaying the start and limiting the length.
Example
Add a channel to a mixer, delaying the start by 1 second and limiting the duration to 2 seconds.
var start = Bass.ChannelSeconds2Bytes(mixer, 1); // delay
var length = BASS_ChannelSeconds2Bytes(mixer, 2); // duration
// add the channel
BassMix.MixerAddChannel(mixer, channel, 0, start, length);
Declaration
public static bool MixerAddChannel(int Handle, int Channel, BassFlags Flags, long Start, long Length)
Parameters
Int32
Handle
The mixer handle (created with CreateMixerStream(Int32, Int32, BassFlags)). |
||||||||||||||||||
Int32
Channel
The handle of the channel to plug into the mixer... a HMUSIC, HSTREAM or HRECORD. |
||||||||||||||||||
BassFlags
Flags
Any combination of these flags.
|
||||||||||||||||||
Int64
Start
Delay (in bytes) before the channel is mixed in. |
||||||||||||||||||
Int64
Length
The maximum amount of data (in bytes) to mix... 0 = no limit. Once this end point is reached, the channel will be removed from the mixer. |
Returns
Boolean
If successful, then true is returned, else false is returned. Use LastError to get the error code. |
Remarks
This function is identical to MixerAddChannel(Int32, Int32, BassFlags), but with the additional ability to specify a delay and duration for the channel.
The Start
and Length
parameters relate to the mixer output.
So when calculating these values, use the mixer stream's sample format rather than the source channel's.
The start parameter is automatically rounded-down to the nearest sample boundary, while the length parameter is rounded-up to the nearest sample boundary.
MixerRemoveChannel(Int32)
Unplugs a channel from a mixer.
Declaration
public static bool MixerRemoveChannel(int Handle)
Parameters
Int32
Handle
The handle of the mixer source channel to unplug (which was addded via MixerAddChannel(Int32, Int32, BassFlags) or MixerAddChannel(Int32, Int32, BassFlags, Int64, Int64)) beforehand). |
Returns
Boolean
If successful, then true is returned, else false is returned. Use LastError to get the error code. |
SplitStreamGetAvailable(Int32)
Retrieves the amount of buffered data available to a splitter stream, or the amount of data in a splitter source buffer.
Declaration
public static int SplitStreamGetAvailable(int Handle)
Parameters
Int32
Handle
The splitter (as obtained by CreateSplitStream(Int32, BassFlags, Int32[])) or the source channel handle. |
Returns
Int32
If successful, then the amount of buffered data (in bytes) is returned, else -1 is returned. Use LastError to get the error code. |
Remarks
With a splitter source, this function reports how much data is in the buffer that is shared by all of its splitter streams. With a splitter stream, this function reports how much data is ahead of it in the buffer, before it will receive any new data from the source. A splitter stream can be repositioned within the buffer via the SplitStreamReset(Int32, Int32) function.
The amount of data that can be buffered is limited by the buffer size, which is determined by the SplitBufferLength config option.
The returned buffered byte count is always based on the source's sample format, even with splitter streams that were created with a different channel count.
SplitStreamGetSource(Int32)
Retrieves the source of a splitter stream.
Declaration
public static int SplitStreamGetSource(int Handle)
Parameters
Int32
Handle
The splitter stream handle (which was add via CreateSplitStream(Int32, BassFlags, Int32[]) beforehand). |
Returns
Int32
If successful, the source stream's handle is returned, else 0 is returned. Use LastError to get the error code. |
SplitStreamGetSplits(Int32)
Retrieves the channel's splitters.
Declaration
public static int[] SplitStreamGetSplits(int Handle)
Parameters
Int32
Handle
The handle to check. |
Returns
Int32[]
The array of splitter handles (null on error, use LastError to get the error code). |
SplitStreamReset(Int32)
Resets a splitter stream or all splitter streams of a source.
Declaration
public static bool SplitStreamReset(int Handle)
Parameters
Int32
Handle
The splitter (as obtained by CreateSplitStream(Int32, BassFlags, Int32[])) or the source channel handle. |
Returns
Boolean
If successful, true is returned, else false is returned. Use LastError to get the error code. |
Remarks
This function resets the splitter stream's buffer state, so that the next sample data it receives will be from the source's current position. If the stream has ended, that is reset too, so that it can be played again. Unless called from within a mixtime sync callback, the stream's output buffer (if it has one) is also flushed.
SplitStreamReset(Int32, Int32)
Resets a splitter stream and sets its position in the source buffer.
Example
Create a new splitter stream that will first play 0.5s of already buffered data (if available).
// create a splitter stream
var split = Bass.CreateSplitStream(source, 0, null);
// set it 0.5s back in the buffer
Bass.SplitStreamReset(split, Bass.ChannelSeconds2Bytes(source, 0.5));
// start playing
Bass.ChannelPlay(split, false);
Declaration
public static bool SplitStreamReset(int Handle, int Offset)
Parameters
Int32
Handle
The splitter (as obtained by CreateSplitStream(Int32, BassFlags, Int32[])) or the source channel handle. |
Int32
Offset
How far back (in bytes) to position the splitter in the source buffer. This is based on the source's sample format, which may have a different channel count to the splitter. |
Returns
Boolean
If successful, true is returned, else false is returned. Use LastError to get the error code. |
Remarks
This function is the same as SplitStreamReset(Int32) except that it also provides the ability to position the splitter stream within the buffer that is shared by all of the splitter streams of the same source.
A splitter stream's buffer position determines what data it will next receive.
For example, if its position is half a second back, it will receive half a second of buffered data before receiving new data from the source.
Calling this function with Offset
= 0 will result in the next data that the splitter stream receives being new data from the source, and is identical to using SplitStreamReset(Int32).
Offset
is automatically limited to the amount of data that the source buffer contains, which is in turn limited to the buffer size, determined by the SplitBufferLength config option.
The amount of source data buffered, as well as a splitter stream's position within it, is available from SplitStreamGetAvailable(Int32).