From 578c3737f8c07e543b90f964da0e89db1c18bb9a Mon Sep 17 00:00:00 2001 From: jacqueline Date: Wed, 9 Aug 2023 11:22:08 +1000 Subject: Add vorbis support whilst we're here --- src/codecs/stbvorbis.cpp | 128 ----------------------------------------------- 1 file changed, 128 deletions(-) delete mode 100644 src/codecs/stbvorbis.cpp (limited to 'src/codecs/stbvorbis.cpp') diff --git a/src/codecs/stbvorbis.cpp b/src/codecs/stbvorbis.cpp deleted file mode 100644 index de315416..00000000 --- a/src/codecs/stbvorbis.cpp +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright 2023 jacqueline - * - * SPDX-License-Identifier: GPL-3.0-only - */ - -#include "stbvorbis.hpp" -#include - -#include -#include - -#include "stb_vorbis.h" - -namespace codecs { - -StbVorbisDecoder::StbVorbisDecoder() - : vorbis_(nullptr), - current_sample_(-1), - num_channels_(0), - num_samples_(0), - samples_array_(NULL) {} - -StbVorbisDecoder::~StbVorbisDecoder() { - if (vorbis_ != nullptr) { - stb_vorbis_close(vorbis_); - } -} - -static uint32_t scaleToBits(float sample, uint8_t bits) { - // Scale to range. - int32_t max_val = (1 << (bits - 1)); - int32_t fixed_point = sample * max_val; - - // Clamp within bounds. - fixed_point = std::clamp(fixed_point, -max_val, max_val); - - // Remove sign. - return *reinterpret_cast(&fixed_point); -} - -auto StbVorbisDecoder::BeginStream(const cpp::span input) - -> Result { - if (vorbis_ != nullptr) { - stb_vorbis_close(vorbis_); - vorbis_ = nullptr; - } - current_sample_ = -1; - int bytes_read = 0; - int error = 0; - vorbis_ = - stb_vorbis_open_pushdata(reinterpret_cast(input.data()), - input.size_bytes(), &bytes_read, &error, NULL); - if (error != 0) { - return {0, cpp::fail(Error::kMalformedData)}; - } - stb_vorbis_info info = stb_vorbis_get_info(vorbis_); - return {bytes_read, - OutputFormat{.num_channels = static_cast(info.channels), - .bits_per_sample = 24, - .sample_rate_hz = info.sample_rate}}; -} - -auto StbVorbisDecoder::ContinueStream(cpp::span input, - cpp::span output) - -> Result { - std::size_t bytes_used = 0; - if (current_sample_ < 0) { - num_channels_ = 0; - num_samples_ = 0; - samples_array_ = NULL; - - while (true) { - auto cropped = input.subspan(bytes_used); - std::size_t b = stb_vorbis_decode_frame_pushdata( - vorbis_, reinterpret_cast(cropped.data()), - cropped.size_bytes(), &num_channels_, &samples_array_, &num_samples_); - if (b == 0) { - return {bytes_used, cpp::fail(Error::kOutOfInput)}; - } - bytes_used += b; - - if (num_samples_ == 0) { - // Decoder is synchronising. Decode more bytes. - continue; - } - if (num_channels_ == 0 || samples_array_ == NULL) { - // The decoder isn't satisfying its contract. - return {bytes_used, cpp::fail(Error::kInternalError)}; - } - current_sample_ = 0; - break; - } - } - - // We successfully decoded a frame. Time to write out the samples. - std::size_t output_byte = 0; - while (current_sample_ < num_samples_) { - if (output_byte + (2 * num_channels_) >= output.size()) { - return {0, OutputInfo{.bytes_written = output_byte, - .is_finished_writing = false}}; - } - - for (int channel = 0; channel < num_channels_; channel++) { - float raw_sample = samples_array_[channel][current_sample_]; - - uint16_t sample_24 = scaleToBits(raw_sample, 24); - output[output_byte++] = static_cast((sample_24 >> 16) & 0xFF); - output[output_byte++] = static_cast((sample_24 >> 8) & 0xFF); - output[output_byte++] = static_cast((sample_24)&0xFF); - // Pad to 32 bits for alignment. - output[output_byte++] = static_cast(0); - } - current_sample_++; - } - - current_sample_ = -1; - return {bytes_used, OutputInfo{.bytes_written = output_byte, - .is_finished_writing = true}}; -} - -auto StbVorbisDecoder::SeekStream(cpp::span input, - std::size_t target_sample) -> Result { - // TODO(jacqueline): Implement me. - return {0, {}}; -} - -} // namespace codecs -- cgit v1.2.3