BASS.NET API for the Un4seen BASS Audio LibrarySYNCPROC DelegateBASS.NET API for the Un4seen BASS Audio Library
User defined synchronizer callback function (see BASS_ChannelSetSync(Int32, BASSSync, Int64, SYNCPROC, IntPtr) for details).

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

public delegate void SYNCPROC(
	int handle,
	int channel,
	int data,
	IntPtr user
)

Parameters

handle
Type: SystemInt32
The sync handle that has occured (as returned by BASS_ChannelSetSync(Int32, BASSSync, Int64, SYNCPROC, IntPtr)).
channel
Type: SystemInt32
The channel that the sync occured on.
data
Type: SystemInt32
Additional data associated with the sync's occurance.
user
Type: SystemIntPtr
The user instance data given when BASS_ChannelSetSync(Int32, BASSSync, Int64, SYNCPROC, IntPtr) was called.
Remarks

BASS creates a single thread dedicated to executing sync callback functions, so a callback function should be quick as other syncs cannot be processed until it has finished. Attribute slides (BASS_ChannelSlideAttribute(Int32, BASSAttribute, Single, Int32)) are also performed by the sync thread, so are also affected if a sync callback takes a long time.

"Mixtime" syncs (BASS_SYNC_MIXTIME) are not executed in the sync thread, but immediately in whichever thread triggers them. In most cases that will be an update thread, and so the same restrictions that apply to stream callbacks (STREAMPROC) also apply here.

BASS_ChannelSetPosition(Int32, Int64, BASSMode) can be used in a mixtime sync to implement custom looping, eg. set a BASS_SYNC_POS sync at the loop end position and seek to the loop start position in the callback.

NOTE: When you pass an instance of a callback delegate to one of the BASS functions, this delegate object will not be reference counted. This means .NET would not know, that it might still being used by BASS. The Garbage Collector might (re)move the delegate instance, if the variable holding the delegate is not declared as global. So make sure to always keep your delegate instance in a variable which lives as long as BASS needs it, e.g. use a global variable or member.

Examples

Do some processing until a MOD music reaches the 10th order
VB
Private _order10 As Boolean = False ' the order 10 flag
Private _mySyncProc As SYNCPROC
...
' set the one-time order 10 sync
_mySyncProc = New SYNCPROC(AddressOf MySync)
Bass.BASS_ChannelSetSync(music, BASSSync.BASS_SYNC_MUSICPOS Or BASSSync.BASS_SYNC_ONETIME, 
     Utils.MakeLong64(10, 0), _mySyncProc, IntPtr.Zero)
While Not _order10
  ' order 10 has not arrived, so do some processing
  Thread.Sleep(0)
End While
' order 10 has arrived!
...
' the sync callback
Private Sub MySync(syncHandle As Integer, channel As Integer, data As Integer, user As IntPtr)
  _order10 = True ' set the order 10 flag
End Sub
private volatile bool _order10 = false; // the order 10 flag
private SYNCPROC _mySyncProc;
...
// set the one-time order 10 sync
_mySyncProc = new SYNCPROC(MySync);
Bass.BASS_ChannelSetSync(music, BASSSync.BASS_SYNC_MUSICPOS | BASSSync.BASS_SYNC_ONETIME, 
     Utils.MakeLong64(10,0), _mySyncProc, IntPtr.Zero);
while (!_order10) 
{
  // order 10 has not arrived, so do some processing
  Thread.Sleep(0);
}
// order 10 has arrived!
...
// the sync callback
private void MySync(int syncHandle, int channel, int data, IntPtr user) 
{
    _order10 = true; // set the order 10 flag
}
Process metadata received from an internet stream:
VB
Private _mySync As SYNCPROC
...
Dim stream As Integer =  Bass.BASS_StreamCreateURL(url, 0, BASSFlag.BASS_DEFAULT, Nothing, 0) 
' set a sync to get notified on stream title updates
_mySync = New SYNCPROC(AddressOf MetaSync)
Bass.BASS_ChannelSetSync(stream, BASSSync.BASS_SYNC_META, 0, _mySync, IntPtr.Zero)
Bass.BASS_ChannelPlay(stream, False)
...
Private Sub MetaSync(ByVal handle As Integer, ByVal channel As Integer, 
                     ByVal data As Integer, ByVal user As IntPtr)
  ' BASS_SYNC_META is triggered
  Dim tags() As String = Bass.BASS_ChannelGetTagsMETA(channel) 
  Dim tag As String
  For Each tag In tags
    Console.WriteLine(tag)
End Sub
private SYNCPROC _mySync;
...
int stream = Bass.BASS_StreamCreateURL(url, 0, BASSFlag.BASS_DEFAULT, null, 0);
// set a sync to get notified on stream title updates
_mySync = new SYNCPROC(MetaSync);
Bass.BASS_ChannelSetSync(stream, BASSSync.BASS_SYNC_META, 0, _mySync, IntPtr.Zero);
Bass.BASS_ChannelPlay(stream, false);
...
private void MetaSync(int handle, int channel, int data, IntPtr user)
{
  // BASS_SYNC_META is triggered
  string[] tags = Bass.BASS_ChannelGetTagsMETA(channel);
  foreach (string tag in tags)
    Console.WriteLine(tag);
}
Perform a loop between a start and end position:
VB
Private _loopSync As Integer = 0 
Private _loopSyncCallback As SYNCPROC 
...
Dim loopStartPos As Long = 1024  ' set to whatever you need
Dim loopEndPos As Long   = 20480 ' set to whatever you need
_loopSyncCallback = New SYNCPROC(AddressOf LoopSync);
_loopSync = Bass.BASS_ChannelSetSync(stream, BASSSync.BASS_SYNC_POS Or BASSSync.BASS_SYNC_MIXTIME, 
                                     loopEndPos, _loopSyncCallback, New IntPtr(loopStartPos)) 
...
' to remove the loop call this
Bass.Bass.BASS_ChannelRemoveSync(stream, _loopSync)
...
' the sync callback
Private Sub LoopSync(ByVal handle As Integer, ByVal channel As Integer, 
                     ByVal data As Integer, ByVal user As IntPtr)
    ' move the position to the start (which is given in the user data)
    Bass.BASS_ChannelSetPosition(channel, user.ToInt64())
End Sub
private int _loopSync = 0;
private SYNCPROC _loopSyncCallback;
...
long loopStartPos = 1024;  // set to whatever you need
long loopEndPos   = 20480; // set to whatever you need
_loopSyncCallback = new SYNCPROC(LoopSync);
_loopSync = Bass.BASS_ChannelSetSync(stream, BASSSync.BASS_SYNC_POS | BASSSync.BASS_SYNC_MIXTIME, 
                                     loopEndPos, _loopSyncCallback, new IntPtr(loopStartPos));
...
// to remove the loop call this
Bass.Bass.BASS_ChannelRemoveSync(stream, _loopSync);
...
// the sync callback
private void LoopSync(int syncHandle, int channel, int data, IntPtr user) 
{
    // move the position to the start (which is given in the user data)
    Bass.BASS_ChannelSetPosition(channel, user.ToInt64());
}
See Also

Reference