#pragma once #include "AudioTools/AudioCodecs/AudioCodecsBase.h" #ifndef HELIX_PRINT #define HELIX_PRINT #endif #include "AACDecoderHelix.h" namespace audio_tools { /** * @brief AAC Decoder using libhelix: * https://github.com/pschatzmann/arduino-libhelix This is basically just a * simple wrapper to provide AudioInfo and AudioInfoSupport * @ingroup codecs * @ingroup decoder * @author Phil Schatzmann * @copyright GPLv3 */ class AACDecoderHelix : public AudioDecoder { public: AACDecoderHelix() { TRACED(); aac = new libhelix::AACDecoderHelix(); if (aac != nullptr) { aac->setReference(this); } else { LOGE("Not enough memory for libhelix"); } } /** * @brief Construct a new AACDecoderMini object * * @param out_stream */ AACDecoderHelix(Print &out_stream) { TRACED(); aac = new libhelix::AACDecoderHelix(out_stream); if (aac != nullptr) { aac->setReference(this); } else { LOGE("Not enough memory for libhelix"); } } /** * @brief Construct a new AACDecoderMini object. The decoded output will go to * the print object. * * @param out_stream * @param bi */ AACDecoderHelix(Print &out_stream, AudioInfoSupport &bi) { TRACED(); aac = new libhelix::AACDecoderHelix(out_stream); if (aac != nullptr) { aac->setReference(this); } else { LOGE("Not enough memory for libhelix"); } addNotifyAudioChange(bi); } /** * @brief Destroy the AACDecoderMini object * */ ~AACDecoderHelix() { TRACED(); if (aac != nullptr) delete aac; } // void setRaw(bool flag){ // if (aac!=nullptr) aac->setRaw(flag); // } /// Defines the output Stream virtual void setOutput(Print &out_stream) override { TRACED(); AudioDecoder::setOutput(out_stream); if (aac != nullptr) aac->setOutput(out_stream); } /// Starts the processing bool begin() override { TRACED(); if (aac != nullptr) { // aac->setDelay(CODEC_DELAY_MS); aac->setInfoCallback(infoCallback, this); aac->begin(); } return true; } /// Releases the reserved memory virtual void end() override { TRACED(); if (aac != nullptr) aac->end(); } virtual _AACFrameInfo audioInfoEx() { return aac->audioInfo(); } AudioInfo audioInfo() override { AudioInfo result; auto i = audioInfoEx(); if (i.nChans != 0 && i.bitsPerSample != 0 && i.sampRateOut != 0) { result.channels = i.nChans; result.sample_rate = i.sampRateOut; result.bits_per_sample = i.bitsPerSample; } return result; } void setAudioInfo(AudioInfo info) override { this->info = info; if (info_notifications_active) { notifyAudioChange(info); } } /// Write AAC data to decoder size_t write(const uint8_t *data, size_t len) override { LOGD("AACDecoderHelix::write: %d", (int)len); if (aac == nullptr) return 0; int open = len; int processed = 0; uint8_t *data8 = (uint8_t *)data; while (open > 0) { int act_write = aac->write(data8 + processed, min(open, DEFAULT_BUFFER_SIZE)); open -= act_write; processed += act_write; } return processed; } /// checks if the class is active virtual operator bool() override { return aac != nullptr && (bool)*aac; } void flush() { // aac->flush(); } /// notifies the subscriber about a change static void infoCallback(_AACFrameInfo &i, void *ref) { AACDecoderHelix *p_helix = (AACDecoderHelix *)ref; if (p_helix != nullptr) { TRACED(); AudioInfo baseInfo; baseInfo.channels = i.nChans; baseInfo.sample_rate = i.sampRateOut; baseInfo.bits_per_sample = i.bitsPerSample; // p_helix->audioChangeAACHelix->setAudioInfo(baseInfo); LOGW("sample_rate: %d", i.sampRateOut); p_helix->setAudioInfo(baseInfo); } } /// Provides the maximum frame size - this is allocated on the heap and you /// can reduce the heap size my minimizing this value size_t maxFrameSize() { return aac->maxFrameSize(); } /// Define your optimized maximum frame size void setMaxFrameSize(size_t len) { aac->setMaxFrameSize(len); } void setAudioInfoNotifications(bool active) { info_notifications_active = active; } /// Provides the maximum pwm buffer size - this is allocated on the heap and /// you can reduce the heap size my minimizing this value size_t maxPCMSize() { return aac->maxPCMSize(); } /// Define your optimized maximum pwm buffer size void setMaxPCMSize(size_t len) { aac->setMaxPCMSize(len); } protected: libhelix::AACDecoderHelix *aac = nullptr; bool info_notifications_active = true; }; } // namespace audio_tools