parent
ddcbcad6d4
commit
acd6d78900
@ -0,0 +1,103 @@ |
|||||||
|
#include "audio_decoder.hpp" |
||||||
|
#include <cstddef> |
||||||
|
#include "esp_heap_caps.h" |
||||||
|
#include "include/audio_element.hpp" |
||||||
|
#include "include/fatfs_audio_input.hpp" |
||||||
|
|
||||||
|
namespace audio { |
||||||
|
|
||||||
|
static const TickType_t kMaxWaitTicks = portMAX_DELAY; |
||||||
|
// TODO: could this be larger? depends on the codecs i guess
|
||||||
|
static const std::size_t kWorkingBufferSize = kMaxFrameSize; |
||||||
|
|
||||||
|
AudioDecoder::AudioDecoder() { |
||||||
|
working_buffer_ = heap_caps_malloc(kWorkingBufferSize, MALLOC_CAP_SPIRAM); |
||||||
|
} |
||||||
|
|
||||||
|
AudioDecoder::~AudioDecoder() { |
||||||
|
free(working_buffer_); |
||||||
|
} |
||||||
|
|
||||||
|
auto AudioDecoder::InputCommandQueue() -> QueueHandle_t { |
||||||
|
return input_queue_; |
||||||
|
} |
||||||
|
|
||||||
|
auto AudioDecoder::SetInputCommandQueue(QueueHandle_t queue) -> void { |
||||||
|
input_queue_ = queue; |
||||||
|
} |
||||||
|
|
||||||
|
auto AudioDecoder::SetOutputCommandQueue(QueueHandle_t queue) -> void { |
||||||
|
output_queue_ = queue; |
||||||
|
} |
||||||
|
|
||||||
|
auto AudioDecoder::InputBuffer() -> StreamBufferHandle_t { |
||||||
|
return input_buffer_; |
||||||
|
} |
||||||
|
|
||||||
|
auto AudioDecoder::SetInputBuffer(StreamBufferHandle_t buffer) -> void { |
||||||
|
input_buffer_ = buffer; |
||||||
|
} |
||||||
|
|
||||||
|
auto AudioDecoder::SetOutputBuffer(StreamBufferHandle_t buffer) -> void { |
||||||
|
output_buffer_ = buffer; |
||||||
|
} |
||||||
|
|
||||||
|
auto AudioDecoder::ProcessElementCommand(void* command) -> ProcessResult { |
||||||
|
FatfsAudioInput::OutputCommand *real = std::reinterpret_cast<FatfsAudioInput::OutputCommand*>(command); |
||||||
|
|
||||||
|
if (current_codec_->CanHandleExtension(real->extension)) { |
||||||
|
// TODO: Do we need to reset the codec?
|
||||||
|
delete real; |
||||||
|
return OK; |
||||||
|
} |
||||||
|
|
||||||
|
auto result = codecs::CreateCodecForExtension(real->extension); |
||||||
|
// TODO: handle error case
|
||||||
|
if (result.has_value()) { |
||||||
|
current_codec_ = result.value(); |
||||||
|
} |
||||||
|
|
||||||
|
delete real; |
||||||
|
return OK; |
||||||
|
} |
||||||
|
|
||||||
|
auto AudioDecoder::SkipElementCommand(void* command) -> void { |
||||||
|
FatfsAudioInput::OutputCommand *real = std::reinterpret_cast<FatfsAudioInput::OutputCommand*>(command); |
||||||
|
delete real; |
||||||
|
} |
||||||
|
|
||||||
|
auto AudioDecoder::ProcessData(uint8_t* data, uint16_t length) -> ProcessResult { |
||||||
|
if (current_codec_ == nullptr) { |
||||||
|
// TODO: signal this
|
||||||
|
return OK; |
||||||
|
} |
||||||
|
|
||||||
|
auto result = current_codec_->Process(data, length, working_buffer_, kWorkingBufferSize); |
||||||
|
if (result.has_value()) { |
||||||
|
xStreamBufferSend(&output_buffer_, working_buffer_, result.value(), kMaxWaitTicks); |
||||||
|
} else { |
||||||
|
// TODO: handle i guess
|
||||||
|
return ERROR; |
||||||
|
} |
||||||
|
|
||||||
|
return OK; |
||||||
|
} |
||||||
|
|
||||||
|
auto AudioDecoder::ProcessIdle() -> ProcessResult { |
||||||
|
// Not used.
|
||||||
|
return OK; |
||||||
|
} |
||||||
|
|
||||||
|
auto AudioDecoder::Pause() -> void { |
||||||
|
// TODO.
|
||||||
|
} |
||||||
|
auto AudioDecoder::IsPaused() -> bool { |
||||||
|
// TODO.
|
||||||
|
} |
||||||
|
|
||||||
|
auto AudioDecoder::Resume() -> void { |
||||||
|
// TODO.
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} // namespace audio
|
@ -1,34 +1,36 @@ |
|||||||
#pragma once |
#pragma once |
||||||
|
|
||||||
#include <cstddef> |
#include <cstddef> |
||||||
|
#include "audio_element.hpp" |
||||||
#include "ff.h" |
#include "ff.h" |
||||||
|
#include "codec.hpp" |
||||||
|
|
||||||
namespace audio { |
namespace audio { |
||||||
|
|
||||||
enum SampleRate {}; |
class AudioDecoder : public IAudioElement { |
||||||
enum BitDepth {}; |
|
||||||
|
|
||||||
struct PcmStreamHeader { |
|
||||||
SampleRate sample_rate; |
|
||||||
BitDepth bit_depth; |
|
||||||
bool configure_now; |
|
||||||
}; |
|
||||||
|
|
||||||
class AudioDecoder { |
|
||||||
public: |
public: |
||||||
AudioDecoder(); |
AudioDecoder(); |
||||||
~AudioDecoder(); |
~AudioDecoder(); |
||||||
|
|
||||||
auto SetSource(RingbufHandle_t& source) -> void; |
auto Pause() -> void; |
||||||
|
auto IsPaused() -> bool; |
||||||
|
|
||||||
enum Status {}; |
auto Resume() -> void; |
||||||
auto ProcessChunk() -> Status; |
|
||||||
|
|
||||||
auto GetOutputStream() const -> RingbufHandle_t; |
auto SetInputCommandQueue(QueueHandle_t) -> void; |
||||||
|
auto SetOutputCommandQueue(QueueHandle_t) -> void; |
||||||
|
auto SetInputBuffer(StreamBufferHandle_t) -> void; |
||||||
|
auto SetOutputBuffer(StreamBufferHandle_t) -> void; |
||||||
|
|
||||||
private: |
private: |
||||||
RingbufHandle_t input_; |
std::unique_ptr<codecs::ICodec> current_codec_; |
||||||
RingbufHandle_t output_; |
|
||||||
|
uint8_t *working_buffer_; |
||||||
|
|
||||||
|
QueueHandle_t input_queue_; |
||||||
|
QueueHandle_t output_queue_; |
||||||
|
StreamBufferHandle_t input_buffer_; |
||||||
|
StreamBufferHandle_t output_buffer_; |
||||||
}; |
}; |
||||||
|
|
||||||
} // namespace audio
|
} // namespace audio
|
||||||
|
Loading…
Reference in new issue