1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
/*
Copyright (C) 2014 Matthias P. Braendli (http://www.opendigitalradio.org)
This program 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 3 of the License, or
(at your option) any later version.
This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
dabplussnoop.cpp
Parse DAB+ frames from a ETI file
Authors:
Matthias P. Braendli <matthias@mpb.li>
*/
/* From the spec:
subchannel_index = MSC sub-channel size (kbps) / 8
audio_super_frame_size (bytes) = subchannel_index * 110
// Derived from
// au_start[n] = au_start[n - 1] + au_size[n - 1] + 2;
// 2 bytes for CRC
au_size[n] = au_start[n+1] - au_start[n] - 2;
he_aac_super_frame(subchannel_index)
{
he_aac_super_frame_header()
{
header_firecode 16
rfa 1
dac_rate 1
sbr_flag 1
aac_channel_mode 1
ps_flag 1
mpeg_surround_config 3
// end of audio parameters
if ((dac_rate == 0) && (sbr_flag == 1)) num_aus = 2;
// AAC core sampling rate 16 kHz
if ((dac_rate == 1) && (sbr_flag == 1)) num_aus = 3;
// AAC core sampling rate 24 kHz
if ((dac_rate == 0) && (sbr_flag == 0)) num_aus = 4;
// AAC core sampling rate 32 kHz
if ((dac_rate == 1) && (sbr_flag == 0)) num_aus = 6;
// AAC core sampling rate 48 kHz
for (n = 1; n < num_aus; n++) {
au_start[n]; 12
}
if !((dac_rate == 1) && (sbr_flag == 1))
alignment 4
}
for (n = 0; n < num_aus; n++) {
au[n] 8 * au_size[n]
au_crc[n] 16
}
}
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <sstream>
#include <vector>
#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:
DabPlusSnoop() :
m_subchannel_index(0),
m_data(0) {}
void set_subchannel_index(unsigned subchannel_index)
{
m_subchannel_index = subchannel_index;
}
void push(uint8_t* streamdata, size_t streamsize);
private:
bool seek_valid_firecode(void);
bool decode(void);
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;
};
#endif
|