virtual void Flush() { while (const int res = LameApi->lame_encode_flush(Context.get(), &Encoded[0], Encoded.size())) { if (res > 0) { Stream->ApplyData(Binary::DataAdapter(&Encoded[0], res)); break; } else if (-1 == res)//buffer too small { ResizeBuffer(); } else { CheckLameCall(res, THIS_LINE); } } Dbg("Stream flushed"); }
virtual void ApplyData(const Chunk::Ptr& data) { //work with 16-bit BOOST_STATIC_ASSERT(Sample::BITS == 16); BOOST_STATIC_ASSERT(Sample::CHANNELS == 2); data->ToS16(); while (const int res = LameApi->lame_encode_buffer_interleaved(Context.get(), safe_ptr_cast<short int*>(&data->front()), data->size(), &Encoded[0], Encoded.size())) { if (res > 0) //encoded { Stream->ApplyData(Binary::DataAdapter(&Encoded[0], res)); break; } else if (-1 == res)//buffer too small { ResizeBuffer(); } else { CheckLameCall(res, THIS_LINE); } } }
void ApplyData(Chunk::Ptr data) override { //work with 16-bit static_assert(Sample::BITS == 16, "Incompatible sound sample bits count"); static_assert(Sample::CHANNELS == 2, "Incompatible sound channels count"); data->ToS16(); while (const int res = LameApi->lame_encode_buffer_interleaved(Context.get(), safe_ptr_cast<short int*>(&data->front()), data->size(), &Encoded[0], Encoded.size())) { if (res > 0) //encoded { Stream->ApplyData(Binary::DataAdapter(&Encoded[0], res)); break; } else if (-1 == res)//buffer too small { ResizeBuffer(); } else { CheckLameCall(res, THIS_LINE); } } }
void SetupContext(lame_global_flags& ctx) const { const StreamParameters stream(Params); const RenderParameters::Ptr sound = RenderParameters::Create(Params); const uint_t samplerate = sound->SoundFreq(); Dbg("Setting samplerate to %1%Hz", samplerate); CheckLameCall(LameApi->lame_set_in_samplerate(&ctx, samplerate), THIS_LINE); CheckLameCall(LameApi->lame_set_out_samplerate(&ctx, samplerate), THIS_LINE); CheckLameCall(LameApi->lame_set_num_channels(&ctx, Sample::CHANNELS), THIS_LINE); CheckLameCall(LameApi->lame_set_bWriteVbrTag(&ctx, true), THIS_LINE); switch (stream.GetBitrateMode()) { case MODE_CBR: { const uint_t bitrate = stream.GetBitrate(); Dbg("Setting bitrate to %1%kbps", bitrate); CheckLameCall(LameApi->lame_set_VBR(&ctx, vbr_off), THIS_LINE); CheckLameCall(LameApi->lame_set_brate(&ctx, bitrate), THIS_LINE); } break; case MODE_ABR: { const uint_t bitrate = stream.GetBitrate(); Dbg("Setting average bitrate to %1%kbps", bitrate); CheckLameCall(LameApi->lame_set_VBR(&ctx, vbr_abr), THIS_LINE); CheckLameCall(LameApi->lame_set_VBR_mean_bitrate_kbps(&ctx, bitrate), THIS_LINE); } break; case MODE_VBR: { const uint_t quality = stream.GetQuality(); Dbg("Setting VBR quality to %1%", quality); CheckLameCall(LameApi->lame_set_VBR(&ctx, vbr_default), THIS_LINE); CheckLameCall(LameApi->lame_set_VBR_q(&ctx, quality), THIS_LINE); } break; default: assert(!"Invalid mode"); } switch (stream.GetChannelsMode()) { case MODE_DEFAULT: Dbg("Using default channels mode"); break; case MODE_STEREO: Dbg("Using stereo mode"); CheckLameCall(LameApi->lame_set_mode(&ctx, STEREO), THIS_LINE); break; case MODE_JOINTSTEREO: Dbg("Using joint stereo mode"); CheckLameCall(LameApi->lame_set_mode(&ctx, JOINT_STEREO), THIS_LINE); break; case MODE_MONO: Dbg("Using mono mode"); CheckLameCall(LameApi->lame_set_mode(&ctx, MONO), THIS_LINE); break; default: assert(!"Invalid mode"); } CheckLameCall(LameApi->lame_init_params(&ctx), THIS_LINE); LameApi->id3tag_init(&ctx); }