summaryrefslogtreecommitdiff
path: root/src/audio
diff options
context:
space:
mode:
authorjacqueline <me@jacqueline.id.au>2023-08-07 18:22:15 +1000
committerjacqueline <me@jacqueline.id.au>2023-08-07 18:22:15 +1000
commitc38754401b95642b5e61fd273c2adf7d76a829fe (patch)
tree2dc23008f6b2b471ce54fbc61d96b7b8c508b0dd /src/audio
parenta66c3428063017f2233b6b15d5ce6c920d5c9095 (diff)
downloadtangara-fw-c38754401b95642b5e61fd273c2adf7d76a829fe.tar.gz
Downscaling working!
Diffstat (limited to 'src/audio')
-rw-r--r--src/audio/audio_task.cpp3
-rw-r--r--src/audio/i2s_audio_output.cpp16
-rw-r--r--src/audio/include/resample.hpp2
-rw-r--r--src/audio/include/sink_mixer.hpp5
-rw-r--r--src/audio/sink_mixer.cpp14
-rw-r--r--src/audio/stream_info.cpp3
6 files changed, 24 insertions, 19 deletions
diff --git a/src/audio/audio_task.cpp b/src/audio/audio_task.cpp
index d7c0c209..7c038730 100644
--- a/src/audio/audio_task.cpp
+++ b/src/audio/audio_task.cpp
@@ -297,7 +297,8 @@ auto AudioTask::FinishDecoding(InputStream& stream) -> void {
InputStream padded_stream{mad_buffer.get()};
OutputStream writer{codec_buffer_.get()};
- auto res = codec_->ContinueStream(stream.data(), writer.data_as<sample::Sample>());
+ auto res =
+ codec_->ContinueStream(stream.data(), writer.data_as<sample::Sample>());
if (res.second.has_error()) {
return;
}
diff --git a/src/audio/i2s_audio_output.cpp b/src/audio/i2s_audio_output.cpp
index 09dc1ce8..e8aa8975 100644
--- a/src/audio/i2s_audio_output.cpp
+++ b/src/audio/i2s_audio_output.cpp
@@ -117,19 +117,19 @@ auto I2SAudioOutput::AdjustVolumeDown() -> bool {
auto I2SAudioOutput::PrepareFormat(const StreamInfo::Pcm& orig)
-> StreamInfo::Pcm {
- return StreamInfo::Pcm{
- .channels = std::min<uint8_t>(orig.channels, 2),
- .bits_per_sample = std::clamp<uint8_t>(orig.bits_per_sample, 16, 32),
- .sample_rate = std::clamp<uint32_t>(orig.sample_rate, 8000, 96000),
- };
- /*
+ /*
+return StreamInfo::Pcm{
+ .channels = std::min<uint8_t>(orig.channels, 2),
+ .bits_per_sample = std::clamp<uint8_t>(orig.bits_per_sample, 16, 32),
+ .sample_rate = std::clamp<uint32_t>(orig.sample_rate, 8000, 96000),
+};
+ */
return StreamInfo::Pcm{
.channels = std::min<uint8_t>(orig.channels, 2),
.bits_per_sample = 16,
//.sample_rate = std::clamp<uint32_t>(orig.sample_rate, 8000, 96000),
- .sample_rate = 32000,
+ .sample_rate = 44100,
};
- */
}
auto I2SAudioOutput::Configure(const StreamInfo::Pcm& pcm) -> void {
diff --git a/src/audio/include/resample.hpp b/src/audio/include/resample.hpp
index 32b6fde8..3855415a 100644
--- a/src/audio/include/resample.hpp
+++ b/src/audio/include/resample.hpp
@@ -23,7 +23,7 @@ class Resampler {
auto Process(cpp::span<const sample::Sample> input,
cpp::span<sample::Sample> output,
- bool end_of_data) -> std::pair<size_t,size_t>;
+ bool end_of_data) -> std::pair<size_t, size_t>;
private:
auto Subsample(int channel) -> float;
diff --git a/src/audio/include/sink_mixer.hpp b/src/audio/include/sink_mixer.hpp
index e8a2d8cc..d1e9aa8a 100644
--- a/src/audio/include/sink_mixer.hpp
+++ b/src/audio/include/sink_mixer.hpp
@@ -40,9 +40,10 @@ class SinkMixer {
auto HandleBytes() -> void;
auto Resample(InputStream&, OutputStream&) -> bool;
- auto ApplyDither(cpp::span<sample::Sample> samples, uint_fast8_t bits) -> void;
+ auto ApplyDither(cpp::span<sample::Sample> samples, uint_fast8_t bits)
+ -> void;
auto Downscale(cpp::span<sample::Sample>, cpp::span<int16_t>) -> void;
-
+
enum class Command {
kReadBytes,
kSetSourceFormat,
diff --git a/src/audio/sink_mixer.cpp b/src/audio/sink_mixer.cpp
index 176fb4a3..a2bf229b 100644
--- a/src/audio/sink_mixer.cpp
+++ b/src/audio/sink_mixer.cpp
@@ -137,7 +137,7 @@ auto SinkMixer::HandleBytes() -> void {
return;
}
- while (!input_stream_->empty()) {
+ while (input_stream_->info().bytes_in_stream() >= sizeof(sample::Sample)) {
RawStream* output_source;
if (pcm->sample_rate != target_format_.sample_rate) {
OutputStream resampled_writer{resampled_stream_.get()};
@@ -150,6 +150,9 @@ auto SinkMixer::HandleBytes() -> void {
output_source = input_stream_.get();
}
+ size_t bytes_consumed = output_source->info().bytes_in_stream();
+ size_t bytes_to_send = output_source->info().bytes_in_stream();
+
if (target_format_.bits_per_sample == 16) {
// This is slightly scary; we're basically reaching into the internals of
// the stream buffer to do in-place conversion of samples. Saving an
@@ -163,19 +166,20 @@ auto SinkMixer::HandleBytes() -> void {
ApplyDither(src, 16);
Downscale(src, dest);
- output_source->info().bytes_in_stream() = dest.size_bytes();
+ bytes_consumed = src.size_bytes();
+ bytes_to_send = src.size_bytes() / 2;
}
InputStream output{output_source};
cpp::span<const std::byte> buf = output.data();
size_t bytes_sent = 0;
- while (bytes_sent < buf.size_bytes()) {
- auto cropped = buf.subspan(bytes_sent);
+ while (bytes_sent < bytes_to_send) {
+ auto cropped = buf.subspan(bytes_sent, bytes_to_send - bytes_sent);
bytes_sent += xStreamBufferSend(sink_, cropped.data(),
cropped.size_bytes(), portMAX_DELAY);
}
- output.consume(bytes_sent);
+ output.consume(bytes_consumed);
}
}
diff --git a/src/audio/stream_info.cpp b/src/audio/stream_info.cpp
index 749e880e..73dbf91b 100644
--- a/src/audio/stream_info.cpp
+++ b/src/audio/stream_info.cpp
@@ -33,8 +33,7 @@ RawStream::RawStream(std::size_t size)
RawStream::RawStream(std::size_t size, uint32_t caps)
: info_(),
buffer_size_(size),
- buffer_(reinterpret_cast<std::byte*>(
- heap_caps_malloc(size, caps))) {
+ buffer_(reinterpret_cast<std::byte*>(heap_caps_malloc(size, caps))) {
assert(buffer_ != NULL);
}