Downscaling working!

custom
jacqueline 2 years ago
parent a66c342806
commit c38754401b
  1. 3
      src/audio/audio_task.cpp
  2. 16
      src/audio/i2s_audio_output.cpp
  3. 2
      src/audio/include/resample.hpp
  4. 3
      src/audio/include/sink_mixer.hpp
  5. 14
      src/audio/sink_mixer.cpp
  6. 3
      src/audio/stream_info.cpp
  7. 2
      src/codecs/include/codec.hpp
  8. 5
      src/codecs/sample.cpp
  9. 9
      src/tasks/tasks.hpp

@ -297,7 +297,8 @@ auto AudioTask::FinishDecoding(InputStream& stream) -> void {
InputStream padded_stream{mad_buffer.get()}; InputStream padded_stream{mad_buffer.get()};
OutputStream writer{codec_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()) { if (res.second.has_error()) {
return; return;
} }

@ -117,19 +117,19 @@ auto I2SAudioOutput::AdjustVolumeDown() -> bool {
auto I2SAudioOutput::PrepareFormat(const StreamInfo::Pcm& orig) auto I2SAudioOutput::PrepareFormat(const StreamInfo::Pcm& orig)
-> StreamInfo::Pcm { -> StreamInfo::Pcm {
return StreamInfo::Pcm{ /*
.channels = std::min<uint8_t>(orig.channels, 2), return StreamInfo::Pcm{
.bits_per_sample = std::clamp<uint8_t>(orig.bits_per_sample, 16, 32), .channels = std::min<uint8_t>(orig.channels, 2),
.sample_rate = std::clamp<uint32_t>(orig.sample_rate, 8000, 96000), .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{ return StreamInfo::Pcm{
.channels = std::min<uint8_t>(orig.channels, 2), .channels = std::min<uint8_t>(orig.channels, 2),
.bits_per_sample = 16, .bits_per_sample = 16,
//.sample_rate = std::clamp<uint32_t>(orig.sample_rate, 8000, 96000), //.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 { auto I2SAudioOutput::Configure(const StreamInfo::Pcm& pcm) -> void {

@ -23,7 +23,7 @@ class Resampler {
auto Process(cpp::span<const sample::Sample> input, auto Process(cpp::span<const sample::Sample> input,
cpp::span<sample::Sample> output, 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: private:
auto Subsample(int channel) -> float; auto Subsample(int channel) -> float;

@ -40,7 +40,8 @@ class SinkMixer {
auto HandleBytes() -> void; auto HandleBytes() -> void;
auto Resample(InputStream&, OutputStream&) -> bool; 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; auto Downscale(cpp::span<sample::Sample>, cpp::span<int16_t>) -> void;
enum class Command { enum class Command {

@ -137,7 +137,7 @@ auto SinkMixer::HandleBytes() -> void {
return; return;
} }
while (!input_stream_->empty()) { while (input_stream_->info().bytes_in_stream() >= sizeof(sample::Sample)) {
RawStream* output_source; RawStream* output_source;
if (pcm->sample_rate != target_format_.sample_rate) { if (pcm->sample_rate != target_format_.sample_rate) {
OutputStream resampled_writer{resampled_stream_.get()}; OutputStream resampled_writer{resampled_stream_.get()};
@ -150,6 +150,9 @@ auto SinkMixer::HandleBytes() -> void {
output_source = input_stream_.get(); 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) { if (target_format_.bits_per_sample == 16) {
// This is slightly scary; we're basically reaching into the internals of // This is slightly scary; we're basically reaching into the internals of
// the stream buffer to do in-place conversion of samples. Saving an // the stream buffer to do in-place conversion of samples. Saving an
@ -163,19 +166,20 @@ auto SinkMixer::HandleBytes() -> void {
ApplyDither(src, 16); ApplyDither(src, 16);
Downscale(src, dest); 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}; InputStream output{output_source};
cpp::span<const std::byte> buf = output.data(); cpp::span<const std::byte> buf = output.data();
size_t bytes_sent = 0; size_t bytes_sent = 0;
while (bytes_sent < buf.size_bytes()) { while (bytes_sent < bytes_to_send) {
auto cropped = buf.subspan(bytes_sent); auto cropped = buf.subspan(bytes_sent, bytes_to_send - bytes_sent);
bytes_sent += xStreamBufferSend(sink_, cropped.data(), bytes_sent += xStreamBufferSend(sink_, cropped.data(),
cropped.size_bytes(), portMAX_DELAY); cropped.size_bytes(), portMAX_DELAY);
} }
output.consume(bytes_sent); output.consume(bytes_consumed);
} }
} }

@ -33,8 +33,7 @@ RawStream::RawStream(std::size_t size)
RawStream::RawStream(std::size_t size, uint32_t caps) RawStream::RawStream(std::size_t size, uint32_t caps)
: info_(), : info_(),
buffer_size_(size), buffer_size_(size),
buffer_(reinterpret_cast<std::byte*>( buffer_(reinterpret_cast<std::byte*>(heap_caps_malloc(size, caps))) {
heap_caps_malloc(size, caps))) {
assert(buffer_ != NULL); assert(buffer_ != NULL);
} }

@ -16,8 +16,8 @@
#include <string> #include <string>
#include <utility> #include <utility>
#include "sample.hpp"
#include "result.hpp" #include "result.hpp"
#include "sample.hpp"
#include "span.hpp" #include "span.hpp"
#include "types.hpp" #include "types.hpp"

@ -269,7 +269,6 @@ void foconv(int* src, uint8_t* dst, int bits, int skip, int count) {
} }
} }
} // namespace sample
} } // namespace audio
}

@ -59,13 +59,14 @@ template <Type t>
auto StartPersistent(const std::function<void(void)>& fn) -> void { auto StartPersistent(const std::function<void(void)>& fn) -> void {
StaticTask_t* task_buffer = new StaticTask_t; StaticTask_t* task_buffer = new StaticTask_t;
cpp::span<StackType_t> stack = AllocateStack<t>(); cpp::span<StackType_t> stack = AllocateStack<t>();
xTaskCreateStatic(&PersistentMain, Name<t>().c_str(), xTaskCreateStatic(&PersistentMain, Name<t>().c_str(), stack.size(),
stack.size(), new std::function<void(void)>(fn), new std::function<void(void)>(fn), Priority<t>(),
Priority<t>(), stack.data(), task_buffer); stack.data(), task_buffer);
} }
template <Type t> template <Type t>
auto StartPersistent(BaseType_t core, const std::function<void(void)>& fn) -> void { auto StartPersistent(BaseType_t core, const std::function<void(void)>& fn)
-> void {
StaticTask_t* task_buffer = new StaticTask_t; StaticTask_t* task_buffer = new StaticTask_t;
cpp::span<StackType_t> stack = AllocateStack<t>(); cpp::span<StackType_t> stack = AllocateStack<t>();
xTaskCreateStaticPinnedToCore(&PersistentMain, Name<t>().c_str(), xTaskCreateStaticPinnedToCore(&PersistentMain, Name<t>().c_str(),

Loading…
Cancel
Save