Fix docs nits, avoid recalculating frame length

custom
jacqueline 2 years ago
parent 06283e0714
commit a4ba7350a7
  1. 41
      src/audio/audio_task.cpp
  2. 7
      src/audio/include/audio_task.hpp
  3. 16
      src/codecs/include/sample.hpp

@ -7,6 +7,7 @@
#include "audio_task.hpp" #include "audio_task.hpp"
#include <stdlib.h> #include <stdlib.h>
#include <sys/_stdint.h>
#include <algorithm> #include <algorithm>
#include <cmath> #include <cmath>
@ -17,34 +18,28 @@
#include <memory> #include <memory>
#include <variant> #include <variant>
#include "audio_decoder.hpp"
#include "audio_events.hpp"
#include "audio_fsm.hpp"
#include "audio_sink.hpp"
#include "audio_source.hpp"
#include "cbor.h" #include "cbor.h"
#include "codec.hpp"
#include "esp_err.h" #include "esp_err.h"
#include "esp_heap_caps.h" #include "esp_heap_caps.h"
#include "esp_log.h" #include "esp_log.h"
#include "event_queue.hpp"
#include "fatfs_audio_input.hpp"
#include "freertos/portmacro.h" #include "freertos/portmacro.h"
#include "freertos/projdefs.h" #include "freertos/projdefs.h"
#include "freertos/queue.h" #include "freertos/queue.h"
#include "freertos/ringbuf.h" #include "freertos/ringbuf.h"
#include "pipeline.hpp"
#include "sample.hpp"
#include "sink_mixer.hpp"
#include "span.hpp" #include "span.hpp"
#include "arena.hpp" #include "audio_decoder.hpp"
#include "audio_element.hpp" #include "audio_element.hpp"
#include "audio_events.hpp"
#include "audio_fsm.hpp"
#include "audio_sink.hpp"
#include "audio_source.hpp"
#include "chunk.hpp" #include "chunk.hpp"
#include "stream_event.hpp" #include "codec.hpp"
#include "stream_info.hpp" #include "event_queue.hpp"
#include "stream_message.hpp" #include "fatfs_audio_input.hpp"
#include "sys/_stdint.h" #include "sample.hpp"
#include "sink_mixer.hpp"
#include "tasks.hpp" #include "tasks.hpp"
#include "track.hpp" #include "track.hpp"
#include "types.hpp" #include "types.hpp"
@ -57,19 +52,18 @@ static const char* kTag = "audio_dec";
static constexpr std::size_t kCodecBufferLength = 240 * 4; static constexpr std::size_t kCodecBufferLength = 240 * 4;
Timer::Timer(const codecs::ICodec::OutputFormat& format) Timer::Timer(const codecs::ICodec::OutputFormat& format)
: format_(format), : current_seconds_(0),
current_seconds_(0),
current_sample_in_second_(0), current_sample_in_second_(0),
samples_per_second_(format.sample_rate_hz * format.num_channels),
total_duration_seconds_(format.total_samples.value_or(0) / total_duration_seconds_(format.total_samples.value_or(0) /
format.num_channels / format.sample_rate_hz) {} format.num_channels / format.sample_rate_hz) {}
auto Timer::AddSamples(std::size_t samples) -> void { auto Timer::AddSamples(std::size_t samples) -> void {
bool incremented = false; bool incremented = false;
current_sample_in_second_ += samples; current_sample_in_second_ += samples;
while (current_sample_in_second_ >= while (current_sample_in_second_ >= samples_per_second_) {
format_.sample_rate_hz * format_.num_channels) {
current_seconds_++; current_seconds_++;
current_sample_in_second_ -= format_.sample_rate_hz * format_.num_channels; current_sample_in_second_ -= samples_per_second_;
incremented = true; incremented = true;
} }
@ -87,10 +81,7 @@ auto Timer::AddSamples(std::size_t samples) -> void {
auto AudioTask::Start(IAudioSource* source, IAudioSink* sink) -> AudioTask* { auto AudioTask::Start(IAudioSource* source, IAudioSink* sink) -> AudioTask* {
AudioTask* task = new AudioTask(source, sink); AudioTask* task = new AudioTask(source, sink);
// Pin to CORE1 because codecs should be fixed point anyway, and being on tasks::StartPersistent<tasks::Type::kAudio>([=]() { task->Main(); });
// the opposite core to the mixer maximises throughput in the worst case
// (some heavy codec like opus + resampling for bluetooth).
tasks::StartPersistent<tasks::Type::kAudio>(1, [=]() { task->Main(); });
return task; return task;
} }

@ -7,15 +7,15 @@
#pragma once #pragma once
#include <sys/_stdint.h> #include <sys/_stdint.h>
#include <cstdint> #include <cstdint>
#include <memory> #include <memory>
#include "audio_decoder.hpp" #include "audio_decoder.hpp"
#include "audio_sink.hpp" #include "audio_sink.hpp"
#include "audio_source.hpp" #include "audio_source.hpp"
#include "codec.hpp" #include "codec.hpp"
#include "pipeline.hpp"
#include "sink_mixer.hpp" #include "sink_mixer.hpp"
#include "stream_info.hpp"
#include "track.hpp" #include "track.hpp"
#include "types.hpp" #include "types.hpp"
@ -28,10 +28,9 @@ class Timer {
auto AddSamples(std::size_t) -> void; auto AddSamples(std::size_t) -> void;
private: private:
codecs::ICodec::OutputFormat format_;
uint32_t current_seconds_; uint32_t current_seconds_;
uint32_t current_sample_in_second_; uint32_t current_sample_in_second_;
uint32_t samples_per_second_;
uint32_t total_duration_seconds_; uint32_t total_duration_seconds_;
}; };

@ -1,3 +1,9 @@
/*
* Copyright 2023 jacqueline <me@jacqueline.id.au>
*
* SPDX-License-Identifier: GPL-3.0-only
*/
#pragma once #pragma once
#include <stdint.h> #include <stdint.h>
@ -8,7 +14,14 @@
namespace sample { namespace sample {
// A signed, 32-bit PCM sample. // A signed, 16-bit PCM sample. All decoder output should be normalised to this
// format, in order to simplify resampling and/or re-encoding for bluetooth.
// Why 'only' 16 bits?
// 1. It's the lowest common bits per sample amongst our codecs. A higher bits
// per sample would require us to uselessly scale up those outputs.
// 2. With appropriate dithering, you're not going to hear a difference
// between 16 bit samples and higher bits anyway.
// 3. Monty from Xiph.org reckons it's all you need.
typedef int16_t Sample; typedef int16_t Sample;
constexpr auto Clip(int64_t v) -> Sample { constexpr auto Clip(int64_t v) -> Sample {
@ -21,7 +34,6 @@ constexpr auto Clip(int64_t v) -> Sample {
constexpr auto FromSigned(int32_t src, uint_fast8_t bits) -> Sample { constexpr auto FromSigned(int32_t src, uint_fast8_t bits) -> Sample {
if (bits > 16) { if (bits > 16) {
// Left-align samples, effectively scaling them up to 32 bits.
return src << (sizeof(Sample) * 8 - bits); return src << (sizeof(Sample) * 8 - bits);
} else if (bits < 16) { } else if (bits < 16) {
return src << (bits - (sizeof(Sample) * 8)); return src << (bits - (sizeof(Sample) * 8));

Loading…
Cancel
Save