summaryrefslogtreecommitdiff
path: root/src/drivers/audio_playback.cpp
diff options
context:
space:
mode:
authorjacqueline <me@jacqueline.id.au>2022-11-16 11:13:21 +1100
committerjacqueline <me@jacqueline.id.au>2022-11-16 11:13:21 +1100
commit8c51280bc68e51b76243e83b84762e33c52510ca (patch)
tree7871ce5bca24c9b9f42a437763d7f1411ddbcd94 /src/drivers/audio_playback.cpp
parente802b8583f58a2be366f24b72afeb050550dbc7e (diff)
downloadtangara-fw-8c51280bc68e51b76243e83b84762e33c52510ca.tar.gz
Fix playback and console issues
Diffstat (limited to 'src/drivers/audio_playback.cpp')
-rw-r--r--src/drivers/audio_playback.cpp72
1 files changed, 43 insertions, 29 deletions
diff --git a/src/drivers/audio_playback.cpp b/src/drivers/audio_playback.cpp
index 1bc5cb3b..29f7a7a4 100644
--- a/src/drivers/audio_playback.cpp
+++ b/src/drivers/audio_playback.cpp
@@ -25,9 +25,7 @@ static const char* kSource = "src";
static const char* kDecoder = "dec";
static const char* kSink = "sink";
-namespace drivers {
-
-static audio_element_status_t status_from_the_void(void* status) {
+static audio_element_status_t toStatus(void* status) {
uintptr_t as_pointer_int = reinterpret_cast<uintptr_t>(status);
return static_cast<audio_element_status_t>(as_pointer_int);
}
@@ -42,6 +40,8 @@ static void toLower(std::string& str) {
[](unsigned char c) { return std::tolower(c); });
}
+namespace drivers {
+
auto AudioPlayback::create(std::unique_ptr<IAudioOutput> output)
-> cpp::result<std::unique_ptr<AudioPlayback>, Error> {
audio_pipeline_handle_t pipeline;
@@ -108,58 +108,67 @@ AudioPlayback::~AudioPlayback() {
}
void AudioPlayback::Play(const std::string& filename) {
- if (GetPlaybackState() != STOPPED) {
+ output_->SetSoftMute(true);
+
+ if (playback_state_ != STOPPED) {
audio_pipeline_stop(pipeline_);
audio_pipeline_wait_for_stop(pipeline_);
audio_pipeline_terminate(pipeline_);
}
- current_state_ = PLAYING;
+ playback_state_ = PLAYING;
Decoder decoder = GetDecoderForFilename(filename);
ReconfigurePipeline(decoder);
audio_element_set_uri(source_element_, filename.c_str());
audio_pipeline_reset_ringbuffer(pipeline_);
audio_pipeline_reset_elements(pipeline_);
audio_pipeline_run(pipeline_);
- output_->SetVolume(volume_);
+
+ output_->SetSoftMute(false);
}
void AudioPlayback::Toggle() {
- if (GetPlaybackState() == PLAYING) {
+ if (playback_state_ == PLAYING) {
Pause();
- } else if (GetPlaybackState() == PAUSED) {
+ } else if (playback_state_ == PAUSED) {
Resume();
}
}
void AudioPlayback::Resume() {
- if (GetPlaybackState() == PAUSED) {
- current_state_ = PLAYING;
+ if (playback_state_ == PAUSED) {
+ ESP_LOGI(kTag, "resuming");
+ playback_state_ = PLAYING;
audio_pipeline_resume(pipeline_);
+ output_->SetSoftMute(false);
}
}
void AudioPlayback::Pause() {
if (GetPlaybackState() == PLAYING) {
- current_state_ = PAUSED;
+ ESP_LOGI(kTag, "pausing");
+ output_->SetSoftMute(true);
+ playback_state_ = PAUSED;
audio_pipeline_pause(pipeline_);
}
}
-auto AudioPlayback::GetPlaybackState() -> PlaybackState {
- return current_state_;
+auto AudioPlayback::GetPlaybackState() const -> PlaybackState {
+ return playback_state_;
}
void AudioPlayback::ProcessEvents(uint16_t max_time_ms) {
- if (current_state_ == STOPPED) {
+ if (playback_state_ == STOPPED) {
return;
}
+
while (1) {
audio_event_iface_msg_t event;
esp_err_t err = audio_event_iface_listen(event_interface_, &event,
pdMS_TO_TICKS(max_time_ms));
if (err != ESP_OK) {
- ESP_LOGE(kTag, "error listening for event:%x", err);
- continue;
+ // Error should only be timeouts, so use a 'failure' as an indication that
+ // we're out of events to process.
+ break;
}
if (event.source_type == AUDIO_ELEMENT_TYPE_ELEMENT &&
@@ -174,61 +183,65 @@ void AudioPlayback::ProcessEvents(uint16_t max_time_ms) {
if (event.source_type == AUDIO_ELEMENT_TYPE_ELEMENT &&
event.source == (void*)source_element_ &&
event.cmd == AEL_MSG_CMD_REPORT_STATUS) {
- audio_element_status_t status = status_from_the_void(event.data);
+ audio_element_status_t status = toStatus(event.data);
if (status == AEL_STATUS_STATE_FINISHED) {
// TODO: Could we change the uri here? hmm.
+ ESP_LOGI(kTag, "finished reading input.");
}
}
if (event.source_type == AUDIO_ELEMENT_TYPE_ELEMENT &&
event.source == (void*)output_->GetAudioElement() &&
event.cmd == AEL_MSG_CMD_REPORT_STATUS) {
- audio_element_status_t status = status_from_the_void(event.data);
+ audio_element_status_t status = toStatus(event.data);
if (status == AEL_STATUS_STATE_FINISHED) {
if (next_filename_ != "") {
+ ESP_LOGI(kTag, "finished writing output. enqueing next.");
Decoder decoder = GetDecoderForFilename(next_filename_);
if (decoder == decoder_type_) {
+ output_->SetSoftMute(true);
audio_element_set_uri(source_element_, next_filename_.c_str());
audio_pipeline_reset_ringbuffer(pipeline_);
audio_pipeline_reset_elements(pipeline_);
audio_pipeline_change_state(pipeline_, AEL_STATE_INIT);
audio_pipeline_run(pipeline_);
+ output_->SetSoftMute(true);
} else {
Play(next_filename_);
}
next_filename_ = "";
} else {
- audio_pipeline_stop(pipeline_);
+ ESP_LOGI(kTag, "finished writing output. stopping.");
audio_pipeline_wait_for_stop(pipeline_);
audio_pipeline_terminate(pipeline_);
- current_state_ = STOPPED;
+ playback_state_ = STOPPED;
}
return;
}
}
if (event.need_free_data) {
- ESP_LOGI(kTag, "freeing event data");
+ // AFAICT this never happens in practice, but it doesn't hurt to follow
+ // the api here anyway.
free(event.data);
}
}
}
-void AudioPlayback::set_next_file(const std::string& filename) {
+void AudioPlayback::SetNextFile(const std::string& filename) {
next_filename_ = filename;
}
-void AudioPlayback::set_volume(uint8_t volume) {
- volume_ = volume;
- // TODO: don't write immediately if we're muted to change track or similar.
+void AudioPlayback::SetVolume(uint8_t volume) {
output_->SetVolume(volume);
}
-auto AudioPlayback::volume() -> uint8_t {
- return volume_;
+auto AudioPlayback::GetVolume() const -> uint8_t {
+ return output_->GetVolume();
}
-auto AudioPlayback::GetDecoderForFilename(std::string filename) -> Decoder {
+auto AudioPlayback::GetDecoderForFilename(std::string filename) const
+ -> Decoder {
toLower(filename);
if (endsWith(filename, "mp3")) {
return MP3;
@@ -255,7 +268,8 @@ auto AudioPlayback::GetDecoderForFilename(std::string filename) -> Decoder {
return NONE;
}
-auto AudioPlayback::CreateDecoder(Decoder decoder) -> audio_element_handle_t {
+auto AudioPlayback::CreateDecoder(Decoder decoder) const
+ -> audio_element_handle_t {
if (decoder == MP3) {
mp3_decoder_cfg_t config = DEFAULT_MP3_DECODER_CONFIG();
return mp3_decoder_init(&config);