summaryrefslogtreecommitdiff
path: root/src/audio/audio_task.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/audio/audio_task.cpp')
-rw-r--r--src/audio/audio_task.cpp36
1 files changed, 36 insertions, 0 deletions
diff --git a/src/audio/audio_task.cpp b/src/audio/audio_task.cpp
index 10bed656..d4c1d27a 100644
--- a/src/audio/audio_task.cpp
+++ b/src/audio/audio_task.cpp
@@ -62,6 +62,10 @@ void AudioTaskMain(std::unique_ptr<Pipeline> pipeline, IAudioSink* sink) {
std::vector<Pipeline*> all_elements = pipeline->GetIterationOrder();
+ float current_sample_in_second = 0;
+ uint32_t previous_second = 0;
+ uint32_t current_second = 0;
+
bool previously_had_work = false;
events::EventQueue& event_queue = events::EventQueue::GetInstance();
while (1) {
@@ -78,6 +82,10 @@ void AudioTaskMain(std::unique_ptr<Pipeline> pipeline, IAudioSink* sink) {
}
}
+ if (!has_work) {
+ has_work = !xStreamBufferIsEmpty(sink->buffer());
+ }
+
if (previously_had_work && !has_work) {
events::Dispatch<AudioPipelineIdle, AudioState>({});
}
@@ -127,6 +135,10 @@ void AudioTaskMain(std::unique_ptr<Pipeline> pipeline, IAudioSink* sink) {
if (sink_stream.info().bytes_in_stream == 0) {
if (sink_stream.is_producer_finished()) {
sink_stream.mark_consumer_finished();
+
+ current_second = 0;
+ previous_second = 0;
+ current_sample_in_second = 0;
} else {
// The user is probably about to hear a skip :(
ESP_LOGW(kTag, "!! audio sink is underbuffered !!");
@@ -155,6 +167,30 @@ void AudioTaskMain(std::unique_ptr<Pipeline> pipeline, IAudioSink* sink) {
xStreamBufferSend(sink->buffer(), sink_stream.data().data(),
sink_stream.data().size_bytes(), 0);
+ if (std::holds_alternative<StreamInfo::Pcm>(*output_format)) {
+ StreamInfo::Pcm pcm = std::get<StreamInfo::Pcm>(*output_format);
+
+ float samples_sunk = bytes_sunk;
+ samples_sunk /= pcm.channels;
+
+ int8_t bps = pcm.bits_per_sample;
+ if (bps == 24) {
+ bps = 32;
+ }
+ samples_sunk /= (bps / 8);
+
+ current_sample_in_second += samples_sunk;
+ while (current_sample_in_second >= pcm.sample_rate) {
+ current_second++;
+ current_sample_in_second -= pcm.sample_rate;
+ }
+ if (previous_second != current_second) {
+ events::Dispatch<PlaybackUpdate, AudioState>(
+ {.seconds_elapsed = current_second});
+ }
+ previous_second = current_second;
+ }
+
// Adjust how long we wait for the next iteration if we're getting too far
// ahead or behind.
float sunk_percent = static_cast<float>(bytes_sunk) /