diff options
author | Stefan Pöschel <github@basicmaster.de> | 2015-05-07 20:59:21 +0200 |
---|---|---|
committer | Stefan Pöschel <github@basicmaster.de> | 2015-05-07 20:59:21 +0200 |
commit | 6e82930326b9f30fe786b5ed3dd3b74a6e751f6c (patch) | |
tree | 60ac6c5e59dafde88a8d5b151f9bfbababd3f705 | |
parent | 76a07373d964433f4a9e22761a380fc297d726d4 (diff) | |
download | etisnoop-6e82930326b9f30fe786b5ed3dd3b74a6e751f6c.tar.gz etisnoop-6e82930326b9f30fe786b5ed3dd3b74a6e751f6c.tar.bz2 etisnoop-6e82930326b9f30fe786b5ed3dd3b74a6e751f6c.zip |
Use 960-transformation in libfaad2
Previously the (default) 1024-transformation was used for PCM output, although
DAB+ uses the 960-transformation. This lead to audio being slower and lower
than the original source.
In libfaad2 the 960-transformation can be enabled by using a carefully crafted
AudioSpecificConfig for initialization, which is carried out by this commit.
-rw-r--r-- | faad_decoder.cpp | 136 | ||||
-rw-r--r-- | faad_decoder.h | 23 | ||||
-rw-r--r-- | utils.h | 32 |
3 files changed, 45 insertions, 146 deletions
diff --git a/faad_decoder.cpp b/faad_decoder.cpp index 5ca45fb..5489e53 100644 --- a/faad_decoder.cpp +++ b/faad_decoder.cpp @@ -23,7 +23,6 @@ #include "faad_decoder.h" #include "wavfile.h" -#include "utils.h" #include <stdio.h> #include <stdint.h> #include <stdlib.h> @@ -55,116 +54,55 @@ void FaadDecoder::open(string filename, bool ps_flag, bool aac_channel_mode, bool FaadDecoder::decode(vector<vector<uint8_t> > aus) { - /* ADTS header creation taken from SDR-J */ - adts_fixed_header fh; - adts_variable_header vh; - - fh.syncword = 0xfff; - fh.id = 0; - fh.layer = 0; - fh.protection_absent = 1; - fh.profile_objecttype = 0; // aac main - 1 - fh.private_bit = 0; // ignored when decoding - fh.original_copy = 0; - fh.home = 0; - vh.copyright_id_bit = 0; - vh.copyright_id_start = 0; - vh.adts_buffer_fullness = 1999; // ? according to OpenDab - vh.no_raw_data_blocks = 0; - - uint8_t d_header[10]; - d_header[0] = fh.syncword >> 4; - d_header[1] = (fh.syncword & 0xf) << 4; - d_header[1] |= fh.id << 3; - d_header[1] |= fh.layer << 1; - d_header[1] |= fh.protection_absent; - d_header[2] = fh.profile_objecttype << 6; - // sampling frequency index filled in dynamically - d_header[2] |= fh.private_bit << 1; - // channel configuration filled in dynamically - d_header[3] = fh.original_copy << 5; - d_header[3] |= fh.home << 4; - d_header[3] |= vh.copyright_id_bit << 3; - d_header[3] |= vh.copyright_id_start << 2; - // framelength filled in dynamically - d_header[4] = 0; - d_header[5] = vh.adts_buffer_fullness >> 6; - d_header[6] = (vh.adts_buffer_fullness & 0x3f) << 2; - d_header[6] |= vh.no_raw_data_blocks; - - if (!m_dac_rate && m_sbr_flag) fh.sampling_freq_idx = 8; - // AAC core sampling rate 16 kHz - else if (m_dac_rate && m_sbr_flag) fh.sampling_freq_idx = 6; - // AAC core sampling rate 24 kHz - else if (!m_dac_rate && !m_sbr_flag) fh.sampling_freq_idx = 5; - // AAC core sampling rate 32 kHz - else if (m_dac_rate && !m_sbr_flag) fh.sampling_freq_idx = 3; - // AAC core sampling rate 48 kHz - - setBits (&d_header[2], fh.sampling_freq_idx, 2, 4); - - if (m_mpeg_surround_config == 0) { - if (m_sbr_flag && !m_aac_channel_mode && m_ps_flag) - fh.channel_conf = 2; - else - fh.channel_conf = 1 << (m_aac_channel_mode ? 1 : 0); - } - else if (m_mpeg_surround_config == 1) { - fh.channel_conf = 6; - } - else { - printf("Unrecognized mpeg surround config (ignored)\n"); - return false; - } - - setBits (&d_header[2], fh.channel_conf, 7, 3); - for (size_t au_ix = 0; au_ix < aus.size(); au_ix++) { vector<uint8_t>& au = aus[au_ix]; - uint8_t helpBuffer[960]; - memset(helpBuffer, 0, sizeof(helpBuffer)); - - // Set length in header (header + au) - vh.aac_frame_length = 7 + au.size(); - setBits(&d_header[3], vh.aac_frame_length, 6, 13); - - memcpy(helpBuffer, d_header, 7 * sizeof(uint8_t)); - memcpy(&helpBuffer[7], - &au[0], au.size() * sizeof (uint8_t)); - NeAACDecFrameInfo hInfo; int16_t* outBuffer; if (!m_initialised) { + /* AudioSpecificConfig structure (the only way to select 960 transform here!) + * + * 00010 = AudioObjectType 2 (AAC LC) + * xxxx = (core) sample rate index + * xxxx = (core) channel config + * 100 = GASpecificConfig with 960 transform + * + * SBR: implicit signaling sufficient - libfaad2 automatically assumes SBR on sample rates <= 24 kHz + * => explicit signaling works, too, but is not necessary here + * + * PS: implicit signaling sufficient - libfaad2 therefore always uses stereo output (if PS support was enabled) + * => explicit signaling not possible, as libfaad2 does not support AudioObjectType 29 (PS) + */ + + int core_sr_index = m_dac_rate ? (m_sbr_flag ? 6 : 3) : (m_sbr_flag ? 8 : 5); // 24/48/16/32 kHz + int core_ch_config = get_aac_channel_configuration(); + if(core_ch_config == -1) { + printf("Unrecognized mpeg surround config (ignored): %d\n", m_mpeg_surround_config); + return false; + } + + uint8_t asc[2]; + asc[0] = 0b00010 << 3 | core_sr_index >> 1; + asc[1] = (core_sr_index & 0x01) << 7 | core_ch_config << 3 | 0b100; + + long unsigned samplerate; unsigned char channels; - int len; - - if ((len = NeAACDecInit(m_faad_handle.decoder, helpBuffer, - vh.aac_frame_length, &samplerate, &channels)) < 0) - { + long int init_result = NeAACDecInit2(m_faad_handle.decoder, asc, sizeof(asc), &samplerate, &channels); + if(init_result != 0) { /* If some error initializing occured, skip the file */ - printf("Error initializing decoder library (%d).\n", - len); + printf("Error initializing decoder library: %s\n", NeAACDecGetErrorMessage(-init_result)); NeAACDecClose(m_faad_handle.decoder); return false; } m_initialised = true; - - outBuffer = (int16_t *)NeAACDecDecode( - m_faad_handle.decoder, &hInfo, - helpBuffer + len, vh.aac_frame_length - len ); - } - else { - outBuffer = (int16_t *)NeAACDecDecode( - m_faad_handle.decoder, &hInfo, - helpBuffer, vh.aac_frame_length ); } + outBuffer = (int16_t *)NeAACDecDecode(m_faad_handle.decoder, &hInfo, &au[0], au.size()); assert(outBuffer != NULL); m_sample_rate = hInfo.samplerate; @@ -220,4 +158,18 @@ void FaadDecoder::close() } } +int FaadDecoder::get_aac_channel_configuration() +{ + switch(m_mpeg_surround_config) { + case 0: // no surround + return m_aac_channel_mode ? 2 : 1; + case 1: // 5.1 + return 6; + case 2: // 7.1 + return 7; + default: + return -1; + } +} + diff --git a/faad_decoder.h b/faad_decoder.h index 1a14efb..b84913c 100644 --- a/faad_decoder.h +++ b/faad_decoder.h @@ -33,27 +33,6 @@ #ifndef __FAAD_DECODER_H_ #define __FAAD_DECODER_H_ -struct adts_fixed_header { - unsigned int syncword :12; - unsigned int id :1; - unsigned int layer :2; - unsigned int protection_absent :1; - unsigned int profile_objecttype :2; - unsigned int sampling_freq_idx :4; - unsigned int private_bit :1; - unsigned int channel_conf :3; - unsigned int original_copy :1; - unsigned int home :1; -}; - -struct adts_variable_header { - unsigned int copyright_id_bit :1; - unsigned int copyright_id_start :1; - unsigned int aac_frame_length :13; - unsigned int adts_buffer_fullness :11; - unsigned int no_raw_data_blocks :2; -}; - class FaadHandle { public: @@ -97,7 +76,7 @@ class FaadDecoder bool is_initialised(void) { return m_initialised; } private: - void update_header(void); + int get_aac_channel_configuration(); size_t m_data_len; std::string m_filename; diff --git a/utils.h b/utils.h deleted file mode 100644 index 9c43c88..0000000 --- a/utils.h +++ /dev/null @@ -1,32 +0,0 @@ -#include <stdlib.h> -#include <stdint.h> - -#ifndef __UTILS_H_ -#define __UTILS_H_ -static inline -void setBit(uint8_t x [], uint8_t bit, int32_t pos) -{ - int16_t iByte; - int16_t iBit; - - iByte = pos / 8; - iBit = pos % 8; - x[iByte] = (x[iByte] & (~(1 << (7 - iBit)))) | - (bit << (7 - iBit)); -} - -static inline -void setBits(uint8_t x[], uint32_t bits, - int32_t startPosition, int32_t numBits) -{ - int32_t i; - uint8_t bit; - - for (i = 0; i < numBits; i ++) { - bit = bits & (1 << (numBits - i - 1)) ? 1 : 0; - setBit(x, bit, startPosition + i); - } -} - -#endif - |