BASS_Encode_MP3_Start -s option

Started by jpf,

jpf

It seems that the -s option supported by Lame isn't supported by BASS_Encode_MP3_Start. Or is it not documented?

I'm encoding a mixer which is now set to play at low speed by setting its BASS_ATTRIB_FREQ to a value different than that of its source channel (and changing at real time). I thought I could let bassenc compensate for that by letting it know that the input samplerate is source's/mixer's freq, so the output mp3 file will sound like I hear the mixer on the speakers.

I guess the same result could be obtained by adding other components to the audio chain but I thought I could go the easy way.

I thought of setting the encoder on the final mix but I see a few drawbacks (the encoder will be fed all of the streams playing, the volume of the playing channels will affect the volume of the output mp3).

I also wanted to avoid callbacks because the VB6 IDE isn't thread-safe.

Is the -s option supported somehow? If not, is there any easy workaround not involving adding components to the audio chain?

Thanks!

Ian @ un4seen

LAME's raw input options (including "-s") aren't supported by BASSenc_MP3, as it always uses the source's sample format (as told by BASS_ChannelGetInfo). If you would like the encoder to assume a different rate then you could achieve that by creating a "dummy" stream with the new rate, setting the encoder on that, and sending the data to it via BASS_Encode_Write in a DSP callback (DSPPROC) on the source. It could look something like this:

encstream = BASS_StreamCreate(newfreq, chans, BASS_STREAM_DECODE, STREAMPROC_DUMMY, 0); // create dummy stream with wanted rate (add BASS_SAMPLE_FLOAT if needed)
encoder = BASS_Endode_MP3_Start(encstream, options, BASS_ENCODE_QUEUE, EncodeProc, 0); // set MP3 encoder on it
encdsp = BASS_ChannelSetDSP(source, EncoderDSP, 0, 0); // set DSP function on source stream

...

void CALLBACK EncoderDSP(HDSP handle, DWORD channel, void *buffer, DWORD length, void *user)
{
BASS_Encode_Write(encoder, buffer, length); // feed the data to the encoder
}

I know you wanted to avoid callbacks in VB6, but I think they're usually safe if you avoid VB6 calls in them, eg. just call BASS_Encode_Write?

jpf

Thanks, Ian!

Not as fool-proof as I'd like, but at least it doesn't add too much code. I'll explore other options before yours. Maybe using a standalone command Lame encoder fed by your bassenc I'd be able to use the -s option? The first workaround I thought of was using a resample stream (bass_fx) but that's a stream and not a DSP; I'd need to completely change de signal flow in my app --too messy! I wish all those stream functions like mixers/splitters/tempo/etc. would be available as DSPs as well. I don't mean to request anything, just thinking aloud.

Ian @ un4seen

Yes, you could instead use LAME.EXE with BASS_Encode_Start for the raw input options. Note you should include the BASS_ENCODE_NOHEAD flag then to prevent it sending the source's format to the encoder.