aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Pöschel <github@basicmaster.de>2015-05-07 20:59:21 +0200
committerStefan Pöschel <github@basicmaster.de>2015-05-07 20:59:21 +0200
commit6e82930326b9f30fe786b5ed3dd3b74a6e751f6c (patch)
tree60ac6c5e59dafde88a8d5b151f9bfbababd3f705
parent76a07373d964433f4a9e22761a380fc297d726d4 (diff)
downloadetisnoop-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.cpp136
-rw-r--r--faad_decoder.h23
-rw-r--r--utils.h32
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
-