summaryrefslogtreecommitdiff
path: root/src/audio/audio_decoder.cpp
blob: ff9f0d62846e13525d58b3b4435b451f41bb5d59 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
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