BASS.NET API for the Un4seen BASS Audio LibraryRECORDPROC DelegateBASS.NET API for the Un4seen BASS Audio Library
User defined callback function to process recorded sample data.

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

public delegate bool RECORDPROC(
	int handle,
	IntPtr buffer,
	int length,
	IntPtr user
)

Parameters

handle
Type: SystemInt32
The recording handle that the data is from.
buffer
Type: SystemIntPtr
The pointer to the buffer containing the recorded sample data. The sample data is in standard Windows PCM format, that is 8-bit samples are unsigned, 16-bit samples are signed, 32-bit floating-point samples range from -1 to +1.
length
Type: SystemInt32
The number of bytes in the buffer.
user
Type: SystemIntPtr
The user instance data given when BASS_RecordStart(Int32, Int32, BASSFlag, RECORDPROC, IntPtr) was called.

Return Value

Type: Boolean
Return to stop recording, and anything else to continue recording.
Remarks

BASS_RecordFree should not be used to free the recording device within a recording callback function. Nor should BASS_ChannelStop(Int32) be used to stop the recording; return to do that instead.

It is clever to NOT alloc any buffer data (e.g. a byte[]) everytime within the callback method, since ALL callbacks should be really fast! And if you would do a 'byte[] data = new byte[]' every time here...the GarbageCollector would never really clean up that memory. Sideeffects might occure, due to the fact, that BASS will call this callback too fast and too often...

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

VB
Private _myRecProc As RECORDPROC ' make it global, so that the GC can not remove it
Private _byteswritten As Integer = 0
Private _recbuffer() As Byte ' local recording buffer
...
If Bass.BASS_RecordInit(-1) Then
  _myRecProc = New RECORDPROC(AddressOf MyRecording)
  Dim recHandle As Integer = Bass.BASS_RecordStart(44100, 2, BASSFlag.BASS_RECORD_PAUSE, _myRecProc, IntPtr.Zero)
  ...
  ' start recording
  Bass.BASS_ChannelPlay(recHandle, False)
End If
...
Private Function MyRecording(handle As Integer, buffer As IntPtr, length As Integer, user As IntPtr) As Boolean
  Dim cont As Boolean = True
  If length > 0 AndAlso buffer <> IntPtr.Zero Then
    ' increase the rec buffer as needed
    If _recbuffer Is Nothing OrElse _recbuffer.Length < length Then
      _recbuffer = New Byte(length) {}
    End If
    ' copy from managed to unmanaged memory
    Marshal.Copy(buffer, _recbuffer, 0, length)
    _byteswritten += length
    ' write to file
    ...
    ' stop recording after a certain amout (just to demo)
    If _byteswritten > 800000 Then
      cont = False ' stop recording
    End If
  End If
  Return cont
End Function
private RECORDPROC _myRecProc; // make it global, so that the GC can not remove it
private int _byteswritten = 0;
private byte[] _recbuffer; // local recording buffer
...
if ( Bass.BASS_RecordInit(-1) )
{
  _myRecProc = new RECORDPROC(MyRecording);
  int recHandle = Bass.BASS_RecordStart(44100, 2, BASSFlag.BASS_RECORD_PAUSE, _myRecProc, IntPtr.Zero);
  ...
  // start recording
  Bass.BASS_ChannelPlay(recHandle, false);
}
...
private bool MyRecording(int handle, IntPtr buffer, int length, IntPtr user)
{
  bool cont = true;
  if (length > 0 && buffer != IntPtr.Zero)
  {
    // increase the rec buffer as needed
    if (_recbuffer == null || _recbuffer.Length < length)
      _recbuffer = new byte[length];
    // copy from managed to unmanaged memory
    Marshal.Copy(buffer, _recbuffer, 0, length);
    _byteswritten += length;
    // write to file
    ...
    // stop recording after a certain amout (just to demo)
    if (_byteswritten > 800000)
      cont = false; // stop recording
  }
  return cont;
}
If you are into C# you might also use an unsafe codeblock with native pointer access (which might be must faster than the above - depending on what you are doing with the data):
private unsafe bool MyRecording(int handle, IntPtr buffer, int length, IntPtr user)
{
  bool cont = true;
  if (length > 0 && buffer != IntPtr.Zero)
  {
    // assuming 16-bit sample data here
    short *data = (short*)buffer;
    ...

    // stop recording after a certain amout (just to demo)
    if (_byteswritten > 800000)
      cont = false; // stop recording
  }
  return cont;
}
See Also

Reference