mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-19 08:46:32 +00:00
I2S: AAC support for web radio (#22787)
* I2S: AAC decoding support for web radio * optimize AAC-lib for size
This commit is contained in:
parent
1fc6f5c707
commit
b73f50be6b
@ -18,7 +18,7 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma GCC optimize ("O3")
|
||||
#pragma GCC optimize ("Os")
|
||||
|
||||
#include "AudioGeneratorAAC.h"
|
||||
|
||||
|
@ -54,7 +54,7 @@
|
||||
#define AAC_ENABLE_SBR 1
|
||||
#endif
|
||||
|
||||
#pragma GCC optimize ("O3")
|
||||
#pragma GCC optimize ("Os")
|
||||
|
||||
#include "aacdec.h"
|
||||
#include "statname.h"
|
||||
|
@ -1409,6 +1409,7 @@
|
||||
#define USE_SHINE
|
||||
#define MP3_MIC_STREAM
|
||||
#define USE_I2S_AUDIO_BERRY
|
||||
#define USE_I2S_AAC
|
||||
#endif // USE_I2S_ALL
|
||||
|
||||
#endif // _MY_USER_CONFIG_H_
|
||||
|
@ -52,6 +52,12 @@ enum : int8_t {
|
||||
I2S_SLOT_PHILIPS = 2, // Philips
|
||||
};
|
||||
|
||||
// I2S decoder type
|
||||
enum : uint32_t {
|
||||
AAC_DECODER = 0,
|
||||
MP3_DECODER = 1,
|
||||
};
|
||||
|
||||
#define I2S_SLOTS 2
|
||||
#define AUDIO_SETTINGS_VERSION 2
|
||||
|
||||
|
@ -30,7 +30,9 @@
|
||||
#include "AudioGeneratorTalkie.h"
|
||||
#include "AudioFileSourceICYStream.h"
|
||||
#include "AudioFileSourceBuffer.h"
|
||||
#ifdef USE_I2S_AAC
|
||||
#include "AudioGeneratorAAC.h"
|
||||
#endif // USE_I2S_AAC
|
||||
|
||||
#include <layer3.h>
|
||||
|
||||
@ -54,9 +56,9 @@
|
||||
extern FS *ufsp;
|
||||
extern FS *ffsp;
|
||||
|
||||
const int preallocateBufferSize = 16*1024;
|
||||
const int preallocateCodecSize = 29192; // MP3 codec max mem needed
|
||||
//const int preallocateCodecSize = 85332; // AAC+SBR codec max mem needed
|
||||
constexpr int preallocateBufferSize = 16*1024;
|
||||
constexpr int preallocateCodecSize = 29192; // MP3 codec max mem needed
|
||||
constexpr int preallocateCodecSizeAAC = 85332; // AAC+SBR codec max mem needed
|
||||
|
||||
void sayTime(int hour, int minutes);
|
||||
void Cmndwav2mp3(void);
|
||||
@ -81,7 +83,7 @@ struct AUDIO_I2S_MP3_t {
|
||||
#endif // USE_I2S_MP3
|
||||
|
||||
#if defined(USE_I2S_MP3) || defined(USE_I2S_WEBRADIO) || defined(USE_SHINE) || defined(MP3_MIC_STREAM)
|
||||
AudioGeneratorMP3 *decoder = NULL;
|
||||
AudioGenerator *decoder = nullptr;
|
||||
TaskHandle_t mp3_task_handle;
|
||||
TaskHandle_t mic_task_handle;
|
||||
#endif // defined(USE_I2S_MP3) || defined(USE_I2S_WEBRADIO)
|
||||
|
@ -46,7 +46,29 @@ void I2SWrStatusCB(void *cbData, int code, const char *str){
|
||||
AddLog(LOG_LEVEL_INFO, "I2S: status: %s",str);
|
||||
}
|
||||
|
||||
void Webradio(const char *url) {
|
||||
bool I2SinitDecoder(uint32_t decoder_type){
|
||||
switch(decoder_type){
|
||||
case MP3_DECODER:
|
||||
audio_i2s_mp3.decoder = dynamic_cast<AudioGenerator *>(new AudioGeneratorMP3(Audio_webradio.preallocateCodec, preallocateCodecSize));
|
||||
break;
|
||||
#ifdef USE_I2S_AAC
|
||||
case AAC_DECODER:
|
||||
Audio_webradio.preallocateCodec = special_realloc(Audio_webradio.preallocateCodec, preallocateCodecSizeAAC);
|
||||
if(Audio_webradio.preallocateCodec == nullptr){
|
||||
AddLog(LOG_LEVEL_ERROR, "I2S: could not alloc heap for AAC");
|
||||
return false;
|
||||
}
|
||||
audio_i2s_mp3.decoder = dynamic_cast<AudioGenerator *>(new AudioGeneratorAAC(Audio_webradio.preallocateCodec, preallocateCodecSizeAAC));
|
||||
break;
|
||||
#endif //USE_I2S_AAC
|
||||
}
|
||||
if(audio_i2s_mp3.decoder == nullptr){
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool I2SWebradio(const char *url, uint32_t decoder_type) {
|
||||
// allocate buffers if not already done
|
||||
if (Audio_webradio.preallocateBuffer == NULL) {
|
||||
Audio_webradio.preallocateBuffer = special_malloc(preallocateBufferSize);
|
||||
@ -65,41 +87,49 @@ void Webradio(const char *url) {
|
||||
free(Audio_webradio.preallocateCodec);
|
||||
Audio_webradio.preallocateCodec = NULL;
|
||||
}
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
Audio_webradio.ifile = new AudioFileSourceICYStream();
|
||||
Audio_webradio.ifile->RegisterMetadataCB(I2sMDCallback, NULL);
|
||||
Audio_webradio.ifile->RegisterStatusCB(I2SWrStatusCB, NULL);
|
||||
if(!Audio_webradio.ifile->open(url)){
|
||||
I2sWebRadioStopPlaying();
|
||||
return;
|
||||
goto i2swr_fail;
|
||||
}
|
||||
AddLog(LOG_LEVEL_INFO, "I2S: did connect to %s",url);
|
||||
|
||||
I2SAudioPower(true);
|
||||
Audio_webradio.buff = new AudioFileSourceBuffer(Audio_webradio.ifile, Audio_webradio.preallocateBuffer, preallocateBufferSize);
|
||||
if(Audio_webradio.buff == nullptr){
|
||||
return;
|
||||
goto i2swr_fail;
|
||||
}
|
||||
Audio_webradio.buff->RegisterStatusCB(I2sStatusCallback, NULL);
|
||||
audio_i2s_mp3.decoder = new AudioGeneratorMP3(Audio_webradio.preallocateCodec, preallocateCodecSize);
|
||||
if(audio_i2s_mp3.decoder == nullptr){
|
||||
return;
|
||||
}
|
||||
audio_i2s_mp3.decoder->RegisterStatusCB(I2sStatusCallback, NULL);
|
||||
audio_i2s_mp3.decoder->begin(Audio_webradio.buff, audio_i2s.out);
|
||||
if (!audio_i2s_mp3.decoder->isRunning()) {
|
||||
I2sStopPlaying();
|
||||
|
||||
if(I2SinitDecoder(decoder_type) == false){
|
||||
AddLog(LOG_LEVEL_DEBUG, "I2S: decoder init failed");
|
||||
goto i2swr_fail;
|
||||
}
|
||||
|
||||
AddLog(LOG_LEVEL_DEBUG,PSTR("I2S: will launch webradio task"));
|
||||
audio_i2s_mp3.decoder->RegisterStatusCB(I2sStatusCallback, NULL);
|
||||
if(audio_i2s_mp3.decoder->begin(Audio_webradio.buff, audio_i2s.out)){
|
||||
AddLog(LOG_LEVEL_DEBUG, "I2S: decoder started");
|
||||
} else {
|
||||
goto i2swr_fail;
|
||||
}
|
||||
|
||||
AddLog(LOG_LEVEL_DEBUG,PSTR("I2S: will launch webradio task with decoder type %u"), decoder_type);
|
||||
xTaskCreatePinnedToCore(I2sMp3WrTask, "MP3-WR", 8192, NULL, 3, &audio_i2s_mp3.mp3_task_handle, 1);
|
||||
return true;
|
||||
|
||||
i2swr_fail:
|
||||
I2sStopPlaying();
|
||||
I2sWebRadioStopPlaying();
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef USE_WEBSERVER
|
||||
const char HTTP_WEBRADIO[] PROGMEM =
|
||||
"{s}" "I2S_WR-Title" "{m}%s{e}";
|
||||
"{s}" "Webradio:" "{m}%s{e}";
|
||||
|
||||
void I2sWrShow(bool json) {
|
||||
if (audio_i2s_mp3.decoder) {
|
||||
@ -116,8 +146,11 @@ void CmndI2SWebRadio(void) {
|
||||
if (I2SPrepareTx() != I2S_OK) return;
|
||||
|
||||
if (XdrvMailbox.data_len > 0) {
|
||||
Webradio(XdrvMailbox.data);
|
||||
if(I2SWebradio(XdrvMailbox.data, XdrvMailbox.index)){
|
||||
ResponseCmndChar(XdrvMailbox.data);
|
||||
} else {
|
||||
ResponseCmndFailed();
|
||||
}
|
||||
} else {
|
||||
ResponseCmndChar_P(PSTR("Stopped"));
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user