summaryrefslogtreecommitdiff
path: root/src/codecs/include
diff options
context:
space:
mode:
Diffstat (limited to 'src/codecs/include')
-rw-r--r--src/codecs/include/codec.hpp6
-rw-r--r--src/codecs/include/foxenflac.hpp3
-rw-r--r--src/codecs/include/mad.hpp3
-rw-r--r--src/codecs/include/sample.hpp59
4 files changed, 66 insertions, 5 deletions
diff --git a/src/codecs/include/codec.hpp b/src/codecs/include/codec.hpp
index e8be8f0a..f260aca4 100644
--- a/src/codecs/include/codec.hpp
+++ b/src/codecs/include/codec.hpp
@@ -16,6 +16,7 @@
#include <string>
#include <utility>
+#include "sample.hpp"
#include "result.hpp"
#include "span.hpp"
#include "types.hpp"
@@ -61,7 +62,6 @@ class ICodec {
struct OutputFormat {
uint8_t num_channels;
- uint8_t bits_per_sample;
uint32_t sample_rate_hz;
std::optional<uint32_t> duration_seconds;
@@ -76,7 +76,7 @@ class ICodec {
-> Result<OutputFormat> = 0;
struct OutputInfo {
- std::size_t bytes_written;
+ std::size_t samples_written;
bool is_finished_writing;
};
@@ -84,7 +84,7 @@ class ICodec {
* Writes PCM samples to the given output buffer.
*/
virtual auto ContinueStream(cpp::span<const std::byte> input,
- cpp::span<std::byte> output)
+ cpp::span<sample::Sample> output)
-> Result<OutputInfo> = 0;
virtual auto SeekStream(cpp::span<const std::byte> input,
diff --git a/src/codecs/include/foxenflac.hpp b/src/codecs/include/foxenflac.hpp
index cce1b762..abfa6d80 100644
--- a/src/codecs/include/foxenflac.hpp
+++ b/src/codecs/include/foxenflac.hpp
@@ -14,6 +14,7 @@
#include <utility>
#include "foxen/flac.h"
+#include "sample.hpp"
#include "span.hpp"
#include "codec.hpp"
@@ -26,7 +27,7 @@ class FoxenFlacDecoder : public ICodec {
~FoxenFlacDecoder();
auto BeginStream(cpp::span<const std::byte>) -> Result<OutputFormat> override;
- auto ContinueStream(cpp::span<const std::byte>, cpp::span<std::byte>)
+ auto ContinueStream(cpp::span<const std::byte>, cpp::span<sample::Sample>)
-> Result<OutputInfo> override;
auto SeekStream(cpp::span<const std::byte> input, std::size_t target_sample)
-> Result<void> override;
diff --git a/src/codecs/include/mad.hpp b/src/codecs/include/mad.hpp
index fbae560c..b81e4acb 100644
--- a/src/codecs/include/mad.hpp
+++ b/src/codecs/include/mad.hpp
@@ -13,6 +13,7 @@
#include <utility>
#include "mad.h"
+#include "sample.hpp"
#include "span.hpp"
#include "codec.hpp"
@@ -35,7 +36,7 @@ class MadMp3Decoder : public ICodec {
* Writes samples for the current frame.
*/
auto ContinueStream(cpp::span<const std::byte> input,
- cpp::span<std::byte> output)
+ cpp::span<sample::Sample> output)
-> Result<OutputInfo> override;
auto SeekStream(cpp::span<const std::byte> input, std::size_t target_sample)
diff --git a/src/codecs/include/sample.hpp b/src/codecs/include/sample.hpp
new file mode 100644
index 00000000..7209673b
--- /dev/null
+++ b/src/codecs/include/sample.hpp
@@ -0,0 +1,59 @@
+#pragma once
+
+#include <stdint.h>
+
+#include <algorithm>
+
+#include <mad.h>
+
+namespace sample {
+
+// A signed, 32-bit PCM sample.
+typedef int32_t Sample;
+
+constexpr auto Clip(int64_t v) -> Sample {
+ if (v > INT32_MAX)
+ return INT32_MAX;
+ if (v < INT32_MIN)
+ return INT32_MIN;
+ return v;
+}
+
+constexpr auto FromSigned(int32_t src, uint_fast8_t bits) -> Sample {
+ // Left-align samples, effectively scaling them up to 32 bits.
+ return src << (sizeof(Sample) * 8 - bits);
+}
+
+constexpr auto FromUnsigned(uint32_t src, uint_fast8_t bits) -> Sample {
+ // Left-align, then substract the max value / 2 to make the sample centred
+ // around zero.
+ return (src << (sizeof(uint32_t) * 8 - bits)) - (~0UL >> 1);
+}
+
+constexpr auto FromFloat(float src) -> Sample {
+ return std::clamp<float>(src, -1.0f, 1.0f) * static_cast<float>(INT32_MAX);
+}
+
+constexpr auto FromDouble(double src) -> Sample {
+ return std::clamp<double>(src, -1.0, 1.0) * static_cast<double>(INT32_MAX);
+}
+
+constexpr auto FromMad(mad_fixed_t src) -> Sample {
+ // Round the bottom bits.
+ src += (1L << (MAD_F_FRACBITS - 24));
+
+ // Clip the leftover bits to within range.
+ if (src >= MAD_F_ONE)
+ src = MAD_F_ONE - 1;
+ else if (src < -MAD_F_ONE)
+ src = -MAD_F_ONE;
+
+ // Quantize.
+ return FromSigned(src >> (MAD_F_FRACBITS + 1 - 24), 24);
+}
+
+constexpr auto ToSigned16Bit(Sample src) -> uint16_t {
+ return src >> 16;
+}
+
+} // namespace sample