BASS_Encode_Start

Sets up an encoder on a channel.

HENCODE BASS_Encode_Start(
    DWORD handle,
    char *cmdline,
    DWORD flags,
    ENCODEPROC *proc,
    void *user
);

Parameters

handleThe channel handle... a HSTREAM, HMUSIC, or HRECORD.
cmdlineThe encoder command-line, including the executable filename and any options. Or the output filename if the BASS_ENCODE_PCM flag is used.
flagsA combination of these flags.
BASS_ENCODE_AIFFSend an AIFF header to the encoder instead of a WAVE header.
BASS_ENCODE_PCMWrite plain PCM sample data, without an encoder. The output filename is given in the cmdline parameter, or it can be NULL to not write a file.
BASS_ENCODE_NOHEADDon't send a WAVE (or AIFF) header to the encoder. If this flag is used then the sample format must be passed to the encoder some other way, eg. via the command-line.
BASS_ENCODE_RF64Send an RF64 header to the encoder instead of a standard RIFF header, allowing more than 4GB of sample data. This flag is ignored if the BASS_ENCODE_NOHEAD or BASS_ENCODE_AIFF flags are used.
BASS_ENCODE_WFEXTSend the sample format information to the encoder in WAVEFORMATEXTENSIBLE form instead of WAVEFORMATEX form. This flag is ignored if the BASS_ENCODE_NOHEAD or BASS_ENCODE_AIFF flags are used.
BASS_ENCODE_BIGENDSend big-endian sample data to the encoder, else little-endian. This flag is ignored unless the BASS_ENCODE_NOHEAD flag is used.
BASS_ENCODE_FP_8BIT,
BASS_ENCODE_FP_16BIT,
BASS_ENCODE_FP_24BIT,
BASS_ENCODE_FP_32BIT
Convert floating-point sample data to 8/16/24/32 bit integer. If the encoder does not support 32-bit floating-point sample data, one of these flags can be used to have the sample data converted to integer before it is fed to the encoder. These flags are ignored if the channel is not floating-point and the BASS_CONFIG_FLOATDSP option is not enabled.
BASS_ENCODE_FP_AUTOConvert floating-point sample data back to the channel's format (8/16 bit integer) if the data is only floating-point due to the BASS_CONFIG_FLOATDSP option being enabled.
BASS_ENCODE_DITHERApply dither (TPDF) when converting floating-point sample data to integer
BASS_ENCODE_QUEUEQueue data to feed the encoder asynchronously. This prevents the data source (DSP system or BASS_Encode_Write call) getting blocked by the encoder, but if data is queued more quickly than the encoder can process it then that could result in lost data.
BASS_ENCODE_LIMITLimit the encoding 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 and BASS_ChannelUpdate 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.
BASS_ENCODE_CAST_NOLIMITDon't limit the encoding rate to real-time speed when feeding a Shoutcast or Icecast server. This flag overrides the BASS_ENCODE_LIMIT flag.
BASS_ENCODE_PAUSEStart the encoder in a paused state.
BASS_ENCODE_AUTOFREEAutomatically free the encoder when the source channel is freed. If queuing is enabled, any remaining queued data will be sent to the encoder before it is freed.
BASS_UNICODEcmdline is in UTF-16 form. Otherwise it is ANSI on Windows or Windows CE, and UTF-8 on other platforms.
procOptional callback function to receive the encoded data... NULL = no callback. To have the encoded data received by a callback function, the encoder needs to be told to output to STDOUT.
userUser instance data to pass to the callback function.

Return value

The encoder handle is returned if the encoder is successfully started, else 0 is returned. Use BASS_ErrorGetCode to get the error code.

Error codes

BASS_ERROR_HANDLEhandle is not valid.
BASS_ERROR_FILEOPENThe encoder could not be started. Check that the executable exists.
BASS_ERROR_CREATEThe PCM file could not be created.
BASS_ERROR_NOTAVAILExternal encoders are not supported.
BASS_ERROR_MEMThere is insufficient memory.
BASS_ERROR_UNKNOWNSome other mystery problem!

Remarks

If the encoder's path is not specified in the command-line, then the executable's directory will be tried first, before the OS's normal search path. The encoder must be told (via the command-line) to expect input from STDIN, rather than a file. The command-line should also tell the encoder what filename to write its output to, unless a callback function is used, in which case the encoder should be told to write its output to STDOUT. No user interaction with the encoder is possible, so anything that would cause the encoder to require the user to press any keys should be avoided. For example, if the encoder asks whether to overwrite files, it should be instructed to always overwrite (via the command-line) or the existing file should be deleted before starting it.

Standard RIFF files are limited to a little over 4GB in size. When writing a WAV file, BASSenc will automatically stop at that point, so that the file is valid. That does not apply when sending data to an encoder though, as the encoder may (possibly via a command-line option) ignore the size restriction, but if it does not, it could mean that the encoder stops after a few hours (depending on the sample format). If longer encodings are needed, the BASS_ENCODE_NOHEAD flag can be used to omit the WAVE header, and the encoder informed of the sample format via the command-line instead. The 4GB size limit can also be overcome with the BASS_ENCODE_RF64 flag, but most encoders are unlikely to support RF64.

When writing an RF64 WAV file, a standard RIFF header will still be written initially, which will only be replaced by an RF64 header at the end if the file size has exceeded the standard limit. When an encoder is used, it is not possible to go back and change the header at the end, so the RF64 header is sent at the beginning in that case.

Internally, the sending of sample data to the encoder is implemented via a DSP callback on the channel. That means when the channel is played (or BASS_ChannelGetData is called if it is a decoding channel), the sample data will be sent to the encoder at the same time. It also means that if the BASS_CONFIG_FLOATDSP option is enabled, the sample data will be 32-bit floating-point, and one of the BASS_ENCODE_FP flags will be required if the encoder does not support floating-point sample data. The BASS_CONFIG_FLOATDSP setting should not be changed while encoding is in progress.

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 via the BASS_CONFIG_ENCODE_PRIORITY config option.

Besides the automatic DSP system, data can also be manually fed to the encoder via the BASS_Encode_Write function. Both methods can be used together, but in general, the "automatic" system ought to be paused when using the "manual" system, via the BASS_ENCODE_PAUSE flag or the BASS_Encode_SetPaused function. Data fed to the encoder manually does not go through the source channel's DSP chain, so any DSP/FX set on the channel will not be applied to the data.

When queued encoding is enabled via the BASS_ENCODE_QUEUE flag, the DSP system or BASS_Encode_Write call will just buffer the data, and the data will then be fed to the encoder by another thread. The maximum amount of queued data is determined by the BASS_CONFIG_ENCODE_QUEUE config option. If the limit is exceeded then data will be lost; BASS_Encode_SetNotify 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.

BASS_Encode_IsActive can be used to check that the encoder is still running. When done encoding, use BASS_Encode_Stop or BASS_Encode_StopEx to close the encoder.

When an encoder is used (not writing plain PCM), the returned handle is the encoder's process handle, which can be used to do things like change the encoder's priority (SetPriorityClass) and get its exit code (GetExitCodeProcess).

Multiple encoders can be set on a channel. For convenience, most of the encoder functions will accept either an encoder handle or a channel handle. When a channel handle is used, the function is applied to all encoders that are set on that channel.

Several add-ons for encoding to popular file formats, without needing external encoders, are available from the BASS website: www.un4seen.com

Platform-specific

External encoders are not supported on Android or iOS or Windows CE, so only plain PCM file writing with the BASS_ENCODE_PCM flag is possible on those platforms. User-provided encoders can be used via BASS_Encode_StartUser.

Example

Start encoding a channel to an MP3 file (output.mp3) using LAME with the standard preset settings.
BASS_Encode_Start(channel, "lame --preset standard - output.mp3", BASS_ENCODE_FP_24BIT, NULL, NULL);
BASS_ChannelPlay(channel, 0); // start the channel playing & encoding

Start writing a channel to a WAV file (output.wav).

BASS_Encode_Start(channel, "output.wav", BASS_ENCODE_PCM, NULL, NULL);
BASS_ChannelPlay(channel, 0); // start the channel playing & encoding

See also

BASS_Encode_AddChunk, BASS_Encode_CastInit, BASS_Encode_IsActive, BASS_Encode_ServerInit, BASS_Encode_SetNotify, BASS_Encode_SetPaused, BASS_Encode_StartACM, BASS_Encode_StartCA, BASS_Encode_StartLimit, BASS_Encode_StartUser, BASS_Encode_Stop, BASS_Encode_Write, ENCODEPROC callback, BASS_CONFIG_ENCODE_PRIORITY