1
0
mirror of https://github.com/JvanKatwijk/qt-dab.git synced 2025-10-06 00:02:40 +02:00
Files
SDR-DAB_Qt-DAB/sources/backend/audio/fdk-aac.cpp
2025-07-16 20:32:47 +02:00

128 lines
3.7 KiB
C++

#
/*
* Copyright (C) 2020 .. 2024
* Jan van Katwijk (J.vanKatwijk@gmail.com)
* Lazy Chair Computing
*
* This file is part of the Qt-DAB program
*
* Qt-DAB is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Qt-DAB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Qt-DAB; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Use the fdk-aac library.
*/
#include "mp4processor.h"
#include "radio.h"
//
#include <cstring>
#include "charsets.h"
#include "fdk-aac.h"
//
/**
* For interpreting the HeAAC frames we have the faad decoder
* and the fdk-aac decoder`
*/
fdkAAC::fdkAAC (RadioInterface *mr,
RingBuffer<complex16> *buffer) {
this -> audioBuffer = buffer;
working = false;
handle = aacDecoder_Open (TT_MP4_LOAS, 1);
if (handle == nullptr)
return;
connect (this, &fdkAAC::newAudio,
mr, &RadioInterface::newAudio);
working = true;
}
fdkAAC::~fdkAAC () {
if (working)
aacDecoder_Close (handle);
}
int16_t fdkAAC::MP42PCM (stream_parms *sp,
uint8_t packet [],
int16_t packetLength) {
uint32_t packet_size;
uint32_t valid;
AAC_DECODER_ERROR err;
uint8_t *ptr = packet;
INT_PCM decode_buf [8 * sizeof (INT_PCM) * 2048];
INT_PCM *bufp = &decode_buf [0];
int output_size = 8 * 2048;
if (!working)
return -1;
if ((packet [0] != 0x56) || ((packet [1] >> 5) != 7))
return -1;
packet_size = (((packet [1] & 0x1F) << 8) | packet [2]) + 3;
if (packet_size != (uint32_t)packetLength)
return -1;
valid = packet_size;
err = aacDecoder_Fill (handle, &ptr, &packet_size, &valid);
if (err != AAC_DEC_OK)
return -1;
err = aacDecoder_DecodeFrame (handle,
bufp,
output_size, 0);
if (err == AAC_DEC_NOT_ENOUGH_BITS)
return -1;
if (err != AAC_DEC_OK)
return -1;
CStreamInfo *info = aacDecoder_GetStreamInfo (handle);
if (!info || info -> sampleRate <= 0)
return -1;
if (info -> numChannels == 2) {
for (int i = 0; i < info -> frameSize; i ++) {
complex16 s = complex16 (bufp [2 * i], bufp [2 * i + 1]);
audioBuffer -> putDataIntoBuffer (&s, 1);
}
if (audioBuffer -> GetRingBufferReadAvailable() >
(int)info -> sampleRate / 8)
newAudio (info -> frameSize, info -> sampleRate,
sp -> psFlag, sp -> sbrFlag);
}
else
if (info -> numChannels == 1) {
int16_t buffer [2 * info -> frameSize];
for (uint16_t i = 0; i < info -> frameSize; i ++) {
buffer [2 * i] = ((int16_t *)bufp) [i];
buffer [2 * i + 1] = buffer [2 * i];
// buffer [2 * i + 1] = 0;
}
audioBuffer -> putDataIntoBuffer ((complex16 *)buffer,
info -> frameSize);
// audioBuffer -> putDataIntoBuffer (buffer, info -> frameSize * 2);
if (audioBuffer -> GetRingBufferReadAvailable() >
(int)info -> sampleRate / 8)
newAudio (info -> frameSize, info -> sampleRate,
sp -> psFlag, sp -> sbrFlag);
}
else
fprintf (stderr, "Cannot handle these channels\n");
return info -> numChannels;
}