Namespace: Un4seen.Bass.AddOn.Enc
Assembly: Bass.Net (in Bass.Net.dll) Version: 2.4.17.5
[DllImportAttribute("bassenc")] public static int BASS_Encode_StartACM( int handle, ACMFORMAT form, BASSEncode flags, ENCODEPROC proc, IntPtr user )
Parameters
- handle
- Type: SystemInt32
The channel handle... a HSTREAM, HMUSIC, or HRECORD. - form
- Type: Un4seen.Bass.AddOn.EncACMFORMAT
ACM codec output format (an ACMFORMAT instance as returned by BASS_Encode_GetACMFormat(Int32, IntPtr, Int32, String, BASSACMFormat)). - flags
- Type: Un4seen.Bass.AddOn.EncBASSEncode
A combination of these flags BASSEncode:BASS_ENCODE_PAUSE Start the encoder paused. BASS_ENCODE_AUTOFREE Automatically free the encoder when the source channel is freed. BASS_ENCODE_QUEUE Queue data to feed the encoder asynchronously. This prevents the data source (DSP system or BASS_Encode_Write(Int32, IntPtr, Int32) call) getting blocked by the encoder, but if data is queud more quickly than the encoder can process it, that could result in lost data. BASS_ENCODE_CAST_NOLIMIT Don't limit the data rate (to real-time speed) when sending to a Shoutcast or Icecast server. BASS_ENCODE_LIMIT Limit the data rate to real-time speed, by introducing a delay when the rate is too high. With BASS 2.4.6 or above, this flag is ignored when the encoder is fed in a playback buffer update cycle (including BASS_Update(Int32) and BASS_ChannelUpdate(Int32, Int32) calls), to avoid possibly causing playback buffer underruns. Except for in those instances, this flag is applied automatically when the encoder is feeding a Shoutcast or Icecast server. - proc
- Type: Un4seen.Bass.AddOn.EncENCODEPROC
Callback function to receive the encoded data. - user
- Type: SystemIntPtr
User instance data to pass to the callback function.
Return Value
Type: Int32The encoder handle is returned if the encoder is successfully started, else 0 is returned. Use BASS_ErrorGetCode to get the error code.
Internally, the sending of sample data to the encoder is implemented via a DSP callback on the channel. That means when you play the channel (or call BASS_ChannelGetData(Int32, IntPtr, Int32) if it's a decoding channel), the sample data will be sent to the encoder at the same time. The encoding is performed in the DSP callback. There isn't a separate process doing the encoding, as when using an external encoder via BASS_Encode_Start(Int32, String, BASSEncode, ENCODEPROC, IntPtr).
By default, the encoder DSP has a priority setting of -1000, which determines where in the DSP chain the encoding is performed. That can be changed using the BASS_CONFIG_ENCODE_PRIORITY config option (see BASS_SetConfig(BASSConfig, Int32)).
Besides the automatic DSP system, data can also be manually fed to the encoder via the BASS_Encode_Write(Int32, IntPtr, Int32) function. Both methods can be used together, but in general, the "automatic" system ought be paused when using the "manual" system, by use of the BASS_ENCODE_PAUSE flag or the BASS_Encode_SetPaused(Int32, Boolean) function.
When queued encoding is enabled via the BASS_ENCODE_QUEUE flag, the DSP system or BASS_Encode_Write(Int32, IntPtr, Int32) call will just buffer the data, and the data will then be fed to the encoder by another thread. The buffer will grow as needed to hold the queued data, up to a limit specified by the BASS_CONFIG_ENCODE_QUEUE config option. If the limit is exceeded (or there is no free memory), data will be lost; BASS_Encode_SetNotify(Int32, ENCODENOTIFYPROC, IntPtr) can be used to be notified of that occurrence. The amount of data that is currently queued, as well as the queue limit and how much data has been lost, is available from BASS_Encode_GetCount(Int32, BASSEncodeCount).
When done encoding, use BASS_Encode_Stop(Int32) to close the encoder.
Multiple encoders can be set on a channel. For simplicity, the encoder functions will accept either an encoder handle or a channel handle. When using a channel handle, the function is applied to all encoders that are set on that channel.
ERROR CODE | Description |
---|---|
BASS_ERROR_HANDLE | handle is not valid. |
BASS_ERROR_NOTAVAIL | The codec specified in form couldn't be initialized. |
BASS_ERROR_UNKNOWN | Some other mystery problem! |
// the encoding callback private ENCODEPROC _myEncProc; private byte[] _encbuffer = null; ... ACMFORMAT codec = BassEnc.BASS_Encode_GetACMFormat(channel, "Select your encoder", BASSACMFormat.BASS_ACM_DEFAULT, WAVEFormatTag.UNKNOWN); if ( codec != null ) { // create the delegate _myEncProc = new ENCODEPROC(MyEncoderProc); // begin encoding using the codec with the delegate callback int encHandle = BassEnc.BASS_Encode_StartACM( channel, codec, BASSEncode.BASS_ENCODE_DEFAULT, _myEncProc, IntPtr.Zero); } ... private bool MyEncodingWriter(int handle, int channel, IntPtr buffer, int length, IntPtr user) { // dynamic buffer allocation if ( _encbuffer == null || _encbuffer.Length < length ) _encbuffer = new byte[length]; // copy from managed to unmanaged memory Marshal.Copy(buffer, _encbuffer, 0, length); // process the data in _encbuffer, e.g. write to disk or whatever ... }
private unsafe void MyEncoding(int handle, int channel, IntPtr buffer, int length, IntPtr user) { // here we receive the encoded data back. // the encoded data is a kind of raw byte buffer... byte *data = (byte*)buffer; for (int a=0; a<length; a++) { // do whatever you want with the encoded data _stream.WriteByte( data[a] ); } }