aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dabplussnoop.cpp149
-rw-r--r--dabplussnoop.h20
-rw-r--r--etisnoop.cpp60
3 files changed, 175 insertions, 54 deletions
diff --git a/dabplussnoop.cpp b/dabplussnoop.cpp
index 40cb124..c0fbcca 100644
--- a/dabplussnoop.cpp
+++ b/dabplussnoop.cpp
@@ -26,6 +26,7 @@
#include <stdlib.h>
#include <string.h>
#include <string>
+#include <cassert>
#include <sstream>
#include <algorithm>
#include <vector>
@@ -34,7 +35,9 @@
#include "lib_crc.h"
#define DPS_INDENT "\t\t"
-#define DPS_PREFIX "DABPLUS:"
+#define DPS_PREFIX "DAB+ decode:"
+
+#define DPS_DEBUG 0
using namespace std;
@@ -82,13 +85,17 @@ bool DabPlusSnoop::seek_valid_firecode()
}
if (crc_ok) {
- fprintf(stderr, DPS_PREFIX " Found valid FireCode at %zu\n", i);
+#if DPS_DEBUG
+ printf(DPS_PREFIX " Found valid FireCode at %zu\n", i);
+#endif
m_data.erase(m_data.begin(), m_data.begin() + i);
return true;
}
else {
- fprintf(stderr, DPS_PREFIX " No valid FireCode found\n");
+#if DPS_DEBUG
+ printf(DPS_PREFIX " No valid FireCode found\n");
+#endif
m_data.clear();
return false;
@@ -97,9 +104,11 @@ bool DabPlusSnoop::seek_valid_firecode()
bool DabPlusSnoop::decode()
{
- fprintf(stderr, DPS_PREFIX " We have %zu bytes of data\n", m_data.size());
+#if DPS_DEBUG
+ printf(DPS_PREFIX " We have %zu bytes of data\n", m_data.size());
+#endif
- if (m_subchannel_index && m_data.size() >= m_subchannel_index * 110) {
+ if (m_subchannel_index && m_data.size() >= m_subchannel_index * 120) {
uint8_t* b = &m_data[0];
@@ -125,8 +134,7 @@ bool DabPlusSnoop::decode()
else if ((dac_rate == 1) && (sbr_flag == 0)) num_aus = 6;
// AAC core sampling rate 48 kHz
- fprintf(stderr,
- DPS_INDENT DPS_PREFIX "\n"
+ printf( DPS_INDENT DPS_PREFIX "\n"
DPS_INDENT "\tfirecode 0x%x\n"
DPS_INDENT "\trfa %d\n"
DPS_INDENT "\tdac_rate %d\n"
@@ -151,20 +159,15 @@ bool DabPlusSnoop::decode()
char nibble = b[i/2] >> 4;
au_start_nibbles.push_back( nibble );
-
- fprintf(stderr, "0x%1x", nibble);
}
else {
char nibble = b[i/2] & 0x0F;
au_start_nibbles.push_back( nibble );
-
- fprintf(stderr, "0x%1x", nibble);
}
}
- fprintf(stderr, "\n");
vector<int> au_start(num_aus);
@@ -179,7 +182,6 @@ bool DabPlusSnoop::decode()
int nib = 0;
- fprintf(stderr, DPS_INDENT DPS_PREFIX " AU start\n");
for (int au = 1; au < num_aus; au++) {
au_start[au] = au_start_nibbles[nib] << 8 | \
au_start_nibbles[nib+1] << 4 | \
@@ -188,41 +190,41 @@ bool DabPlusSnoop::decode()
nib += 3;
}
+#if DPS_DEBUG
+ printf(DPS_INDENT DPS_PREFIX " AU start\n");
for (int au = 0; au < num_aus; au++) {
- fprintf(stderr, DPS_INDENT "\tAU[%d] %d 0x%x\n", au,
+ printf(DPS_INDENT "\tAU[%d] %d 0x%x\n", au,
au_start[au],
au_start[au]);
}
+#endif
- return analyse_au(au_start);
+ return extract_au(au_start);
}
else {
return false;
}
}
-bool DabPlusSnoop::analyse_au(vector<int> au_start)
+bool DabPlusSnoop::extract_au(vector<int> au_start)
{
-
- /*
- for (int i = 0; i < au_start.length - 1; i++) {
- byte[] new_frame = Arrays.copyOfRange(frame, au_start[i], au_start[i+1] - 2);
-
- int current_crc = MiscTools.getUInt16(frame, au_start[i+1] - 2);
- int crc = MiscTools.calcCRC(new_frame, MiscTools.crc_mode.CRC_16_CCITT);
- }
-*/
-
vector<vector<uint8_t> > aus(au_start.size());
+ // The last entry of au_start must the end of valid
+ // AU data. We stop at m_subchannel_index * 110 because
+ // what comes after is RS parity
au_start.push_back(m_subchannel_index * 110);
+ bool all_crc_ok = true;
+
for (size_t au = 0; au < aus.size(); au++)
{
- fprintf(stderr, DPS_PREFIX DPS_INDENT
+#if DPS_DEBUG
+ printf(DPS_PREFIX DPS_INDENT
"Copy au %zu of size %zu\n",
au,
au_start[au+1] - au_start[au]-2 );
+#endif
aus[au].resize(au_start[au+1] - au_start[au]-2);
std::copy(
@@ -242,11 +244,94 @@ bool DabPlusSnoop::analyse_au(vector<int> au_start)
}
calc_crc =~ calc_crc;
- fprintf(stderr, DPS_PREFIX DPS_INDENT
- " AU H: %04x C: %04x\n"
- " DAU H: %u C: %u\n",
- au_crc, calc_crc,
- au_crc, calc_crc);
+ if (calc_crc != au_crc) {
+ printf(DPS_INDENT DPS_PREFIX
+ "Erroneous CRC for au %zu\n", au);
+
+ all_crc_ok = false;
+ }
+ }
+
+ if (all_crc_ok) {
+ return analyse_au(aus);
+ }
+ else {
+ return false;
+ }
+}
+
+bool DabPlusSnoop::analyse_au(vector<vector<uint8_t> >& aus)
+{
+ for (size_t i_au = 0; i_au < aus.size(); i_au++) {
+ size_t i = 0;
+
+ vector<uint8_t>& au = aus[i_au];
+
+ bool continue_au = true;
+ while (continue_au && i < au.size()) {
+ printf("R at %zu\n", i);
+ int id_syn_ele = (au[i] & 0xE0) >> 5;
+
+ /* Debugging print */
+ stringstream ss;
+ ss << DPS_INDENT << "\tID_SYN_ELE: ";
+
+ switch (id_syn_ele) {
+ case ID_SCE: ss << "Single Channel Element"; break;
+ case ID_CPE: ss << "Channel Pair Element"; break;
+ case ID_CCE: ss << "Coupling Channel Element"; break;
+ case ID_LFE: ss << "LFE Channel Element"; break;
+ case ID_DSE: ss << "Data Stream Element"; break;
+ case ID_PCE: ss << "Program Config Element"; break;
+ case ID_FIL: ss << "Fill Element"; break;
+ case ID_END: ss << "Terminator"; break;
+ case ID_EXT: ss << "Extension Payload"; break;
+ case ID_SCAL: ss << "AAC scalable element"; break;
+ default: ss << "Unknown (" << id_syn_ele << ")"; break;
+ }
+
+ int element_instance_tag = (au[i] & 0x78) >> 1;
+ ss << " [" << element_instance_tag << "]";
+
+
+ // Keep track of index increment in bits
+ size_t inc = 7; // eat id_syn_ele, element_instance_tag
+
+ if (id_syn_ele == ID_DSE) {
+ bool data_byte_align_flag = (au[i] & 0x01);
+ inc++;
+
+ ss << "\n" DPS_INDENT "\t\t";
+ if (data_byte_align_flag) {
+ ss << " <byte align flag>";
+ }
+
+
+ uint8_t count = au[1];
+ int cnt = count;
+ inc += 8;
+
+ if (count == 255) {
+ uint8_t esc_count = au[2];
+ inc += 8;
+
+ cnt += esc_count;
+ }
+
+ ss << " cnt:" << cnt;
+ inc += 8*cnt;
+
+ }
+ else
+ {
+ continue_au = false;
+ }
+
+ printf("%s\n", ss.str().c_str());
+
+ assert (inc % 8 == 0);
+ i += inc / 8;
+ }
}
return true;
diff --git a/dabplussnoop.h b/dabplussnoop.h
index ef0807b..28f94ba 100644
--- a/dabplussnoop.h
+++ b/dabplussnoop.h
@@ -80,6 +80,23 @@ he_aac_super_frame(subchannel_index)
#ifndef __DABPLUSSNOOP_H_
#define __DABPLUSSNOOP_H_
+/** MP4 Element IDs. */
+typedef enum
+{
+ ID_NONE = -1, /**< Invalid Element helper ID. */
+ ID_SCE = 0, /**< Single Channel Element. */
+ ID_CPE = 1, /**< Channel Pair Element. */
+ ID_CCE = 2, /**< Coupling Channel Element. */
+ ID_LFE = 3, /**< LFE Channel Element. */
+ ID_DSE = 4, /**< Currently one Data Stream Element for ancillary data is supported. */
+ ID_PCE = 5, /**< Program Config Element. */
+ ID_FIL = 6, /**< Fill Element. */
+ ID_END = 7, /**< Arnie (End Element = Terminator). */
+ ID_EXT = 8, /**< Extension Payload (ER only). */
+ ID_SCAL = 9, /**< AAC scalable element (ER only). */
+ ID_LAST
+} MP4_ELEMENT_ID;
+
class DabPlusSnoop
{
public:
@@ -97,7 +114,8 @@ class DabPlusSnoop
private:
bool seek_valid_firecode(void);
bool decode(void);
- bool analyse_au(std::vector<int> au_start);
+ bool extract_au(std::vector<int> au_start);
+ bool analyse_au(std::vector<std::vector<uint8_t> >& aus);
unsigned m_subchannel_index;
std::vector<uint8_t> m_data;
diff --git a/etisnoop.cpp b/etisnoop.cpp
index 9786fc3..e81741e 100644
--- a/etisnoop.cpp
+++ b/etisnoop.cpp
@@ -46,6 +46,8 @@
using namespace std;
+static int verbosity;
+
void printbuf(string header,
int indent_level,
unsigned char* buffer,
@@ -59,7 +61,6 @@ void decodeFIG(unsigned char* figdata,
struct eti_analyse_config_t {
int etifd;
- int verbosity;
bool ignore_error;
std::map<int, DabPlusSnoop> streams_to_decode;
};
@@ -94,7 +95,7 @@ int main(int argc, char *argv[])
string file_name("-");
map<int, DabPlusSnoop> streams_to_decode;
- int verbosity = 0;
+ verbosity = 0;
bool ignore_error = false;
while(ch != -1) {
@@ -139,7 +140,6 @@ int main(int argc, char *argv[])
eti_analyse_config_t config = {
.etifd = etifd,
- .verbosity = verbosity,
.ignore_error = ignore_error,
.streams_to_decode = streams_to_decode
};
@@ -431,8 +431,18 @@ int eti_analyse(eti_analyse_config_t& config)
unsigned char streamdata[684*8];
memcpy(streamdata, p + 12 + 4*nst + ficf*ficl*4 + offset, stl[i]*8);
offset += stl[i] * 8;
- sprintf(sdesc, "id %d, len %d", i, stl[i]*8);
- printbuf("Stream Data", 1, streamdata, stl[i]*8, sdesc);
+ if (config.streams_to_decode.count(i) > 0) {
+ sprintf(sdesc, "id %d, len %d, selected for decoding", i, stl[i]*8);
+ }
+ else {
+ sprintf(sdesc, "id %d, len %d, not selected for decoding", i, stl[i]*8);
+ }
+ if (verbosity > 1) {
+ printbuf("Stream Data", 1, streamdata, stl[i]*8, sdesc);
+ }
+ else {
+ printbuf("Stream Data", 1, streamdata, 0, sdesc);
+ }
if (config.streams_to_decode.count(i) > 0) {
config.streams_to_decode[i].push(streamdata, stl[i]*8);
@@ -466,7 +476,9 @@ int eti_analyse(eti_analyse_config_t& config)
printbuf("TIST - Time Stamp", 1, p+12+4*nst+ficf*ficl*4+offset+4, 4, sdesc);
- printf("-------------------------------------------------------------------------------------------------------------\n");
+ if (verbosity) {
+ printf("-------------------------------------------------------------------------------------------------------------\n");
+ }
}
return 0;
}
@@ -477,28 +489,34 @@ void printbuf(string header,
size_t size,
string desc)
{
- for (int i = 0; i < indent_level; i++) {
- printf("\t");
- }
+ if (verbosity > 0) {
+ for (int i = 0; i < indent_level; i++) {
+ printf("\t");
+ }
- printf("%s", header.c_str());
- if (size != 0) {
- printf(": ");
- }
+ printf("%s", header.c_str());
+ if (size != 0) {
+ printf(": ");
+ }
- for (size_t i = 0; i < size; i++) {
- printf("%02x ", buffer[i]);
- }
+ for (size_t i = 0; i < size; i++) {
+ printf("%02x ", buffer[i]);
+ }
- if (desc != "") {
- printf(" [%s] ", desc.c_str());
- }
+ if (desc != "") {
+ printf(" [%s] ", desc.c_str());
+ }
- printf("\n");
+ printf("\n");
+ }
}
-void decodeFIG(unsigned char* f, unsigned char figlen,unsigned short int figtype, unsigned short int indent) {
+void decodeFIG(unsigned char* f,
+ unsigned char figlen,
+ unsigned short int figtype,
+ unsigned short int indent)
+{
char desc[256];