diff --git a/src/internal_modules/roc_audio/target_libvorbis/roc_audio/vorbis_encoder.cpp b/src/internal_modules/roc_audio/target_libvorbis/roc_audio/vorbis_encoder.cpp index 5c083df3b..b9eb200ef 100644 --- a/src/internal_modules/roc_audio/target_libvorbis/roc_audio/vorbis_encoder.cpp +++ b/src/internal_modules/roc_audio/target_libvorbis/roc_audio/vorbis_encoder.cpp @@ -13,19 +13,18 @@ namespace roc { namespace audio { VorbisEncoder::VorbisEncoder(const SampleSpec& sample_spec) - : sample_spec_(sample_spec) - , initialized_(false) + : initialized_(false) , frame_data_(NULL) , frame_size_(0) { vorbis_info_init(&vorbis_info_); - const int num_channels = static_cast(sample_spec_.num_channels()); - const int sample_rate = static_cast(sample_spec_.sample_rate()); + + const int num_channels = static_cast(sample_spec.num_channels()); + const int sample_rate = static_cast(sample_spec.sample_rate()); int ret = vorbis_encode_init_vbr(&vorbis_info_, num_channels, sample_rate, 0.0f); if (ret != 0) { roc_panic("vorbis encoder: failed to initialize vorbis encoder"); } vorbis_comment_init(&vorbis_comment_); - vorbis_comment_add_tag(&vorbis_comment_, "ENCODER", "roc_audio VorbisEncoder"); ret = vorbis_analysis_init(&vorbis_dsp_, &vorbis_info_); if (ret != 0) { @@ -52,12 +51,27 @@ VorbisEncoder::~VorbisEncoder() { } status::StatusCode VorbisEncoder::init_status() const { - return initialized_ ? status::StatusOK : status::StatusNoMem; + return initialized_ ? status::StatusOK : status::StatusAbort; } -size_t VorbisEncoder::encoded_byte_count(size_t n_samples) const { - roc_panic("TODO"); - return 0; +size_t VorbisEncoder::encoded_byte_count(size_t num_samples) const { + if (!initialized_) { + return 0; + } + + if (vorbis_info_.rate <= 0 || vorbis_info_.channels <= 0 + || vorbis_info_.bitrate_nominal <= 0) { + roc_panic("vorbis encoder: vorbis_info structure has invalid values"); + return 0; + } + + // Average number of bits used per sample, per channel. + const size_t bit_width = static_cast( + (vorbis_info_.bitrate_nominal / vorbis_info_.rate) / vorbis_info_.channels); + + const size_t encoded_bytes = (num_samples * bit_width + 7) / 8; + + return encoded_bytes; } void VorbisEncoder::begin_frame(void* frame_data, size_t frame_size) { diff --git a/src/internal_modules/roc_audio/target_libvorbis/roc_audio/vorbis_encoder.h b/src/internal_modules/roc_audio/target_libvorbis/roc_audio/vorbis_encoder.h index 921467520..33043d3d8 100644 --- a/src/internal_modules/roc_audio/target_libvorbis/roc_audio/vorbis_encoder.h +++ b/src/internal_modules/roc_audio/target_libvorbis/roc_audio/vorbis_encoder.h @@ -44,7 +44,6 @@ class VorbisEncoder : public IFrameEncoder { virtual void end_frame(); private: - SampleSpec sample_spec_; bool initialized_; void* frame_data_; size_t frame_size_;