mirror of
https://github.com/JvanKatwijk/qt-dab.git
synced 2025-10-06 00:02:40 +02:00
128 lines
3.7 KiB
C++
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;
|
|
}
|
|
|