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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
|
#include "OFL.h"
#include "foundation/error.h"
static void crcofl(unsigned short crcPoly, unsigned short crcMask, unsigned long *crc, unsigned char byte)
{
int i;
for (i=0; i<8; i++)
{
unsigned short flag = (*crc) & crcMask ? 1:0;
flag ^= (byte & 0x80 ? 1 : 0);
(*crc)<<=1;
byte <<= 1;
if(flag)
(*crc) ^= crcPoly;
}
}
int OFL::GetGaps(size_t *pregap, size_t *postgap)
{
/* TODO: verify the postgap calculation */
if (codec_delay >= 529)
{
*pregap = codec_delay;
size_t endcut;
endcut = samples_per_frame - ((total_length + codec_delay) % samples_per_frame); // how many 0 samples had to be added?
*postgap = endcut;
return NErr_Success;
}
return NErr_Empty;
}
double OFL::GetLengthSeconds() const
{
return (double)GetSamples() / (double)sample_rate;
}
uint64_t OFL::GetSamples() const
{
return total_length;
}
uint32_t OFL::GetFrames() const
{
uint64_t real_samples = (total_length+codec_delay)*samples_per_frame;
return (uint32_t) (real_samples/samples_per_frame);
}
int OFL::Read(const MPEGFrame &header, const uint8_t *buffer, size_t buffer_len)
{
if (header.layer != MPEGFrame::Layer3)
return NErr_False;
sample_rate = header.GetSampleRate();
samples_per_frame = header.GetSamplesPerFrame();
if (header.channelMode == MPEGFrame::Mono)
{
if (header.mpegVersion == MPEGFrame::MPEG1)
{
// 0-9 : main_data_end
int16_t main_data_end = (buffer[0] << 1) | (buffer[1] >> 7);
// read the 2 part2_3_lengths out so we know how big the main data section is
uint16_t part2_3_length = ((buffer[2] & 0x3F) << 6) | (buffer[3]>>2); // bits 18-30
part2_3_length += ((buffer[9] & 0x7) << 9) | (buffer[10] << 1) | (buffer[11] >> 7) ; // bits 77-89
size_t offset = 17 + (part2_3_length+7)/8;
if (offset+9 < buffer_len && buffer[offset] == 0xb4)
{
unsigned long crc=255;
for (int i=0;i<9;i++)
crcofl(0x0045, 0x0080, &crc, buffer[offset+i]);
if ((crc & 0xFF) == buffer[offset+9])
{
total_length = (buffer[offset+3] << 24) | (buffer[offset+4] << 16) | (buffer[offset+5] << 8) | (buffer[offset+6]);
codec_delay = (buffer[offset+1] << 8) | (buffer[offset+2]);
additional_delay= (buffer[offset+7] << 8) | (buffer[offset+8]);
return NErr_Success;
}
}
}
else
{ // MPEG2 and 2.5
// 0-8 : main_data_end
uint16_t main_data_end = buffer[0];
// read the 2 part2_3_lengths out so we know how big the main data section is
uint16_t part2_3_length = ((buffer[1] & 0x7F) << 5) | (buffer[2]>>3); // bits 9-21
size_t offset = 9 + (part2_3_length+7)/8;
if (offset+9 < buffer_len && buffer[offset] == 0xb4)
{
unsigned long crc=255;
for (int i=0;i<9;i++)
crcofl(0x0045, 0x0080, &crc, buffer[offset+i]);
if ((crc & 0xFF) == buffer[offset+9])
{
total_length = (buffer[offset+3] << 24) | (buffer[offset+4] << 16) | (buffer[offset+5] << 8) | (buffer[offset+6]);
codec_delay = (buffer[offset+1] << 8) | (buffer[offset+2]);
additional_delay= (buffer[offset+7] << 8) | (buffer[offset+8]);
return NErr_Success;
}
}
}
}
else
{
if (header.mpegVersion == MPEGFrame::MPEG1)
{
// 0-9 : main_data_end
uint16_t main_data_end = (buffer[0] << 1) | (buffer[1] >> 7);
// read the 4 part2_3_lengths out so we know how big the main data section is
uint16_t part2_3_length = ((buffer[2] & 0xF) << 8) | buffer[3]; // bits 20-32
part2_3_length += ((buffer[9] & 0x1) << 11) | (buffer[10] << 3) | (buffer[11] >> 5) ; // bits 79-91
part2_3_length += ((buffer[17] & 0x3F) << 6) | (buffer[18] >> 2); // bits 138-150
part2_3_length += ((buffer[24] & 0x7) << 9) | (buffer[25] << 1) | (buffer[26] >> 7); // bits 197-209
size_t offset = 32 + (part2_3_length+7)/8;
if (offset+9 < buffer_len && buffer[offset] == 0xb4)
{
unsigned long crc=255;
for (int i=0;i<9;i++)
crcofl(0x0045, 0x0080, &crc, buffer[offset+i]);
if ((crc & 0xFF) == buffer[offset+9])
{
total_length = (buffer[offset+3] << 24) | (buffer[offset+4] << 16) | (buffer[offset+5] << 8) | (buffer[offset+6]);
codec_delay = (buffer[offset+1] << 8) | (buffer[offset+2]);
additional_delay= (buffer[offset+7] << 8) | (buffer[offset+8]);
return NErr_Success;
}
}
}
else
{ // MPEG2 and 2.5
// 0-8 : main_data_end
uint16_t main_data_end = buffer[0];
// read the 4 part2_3_lengths out so we know how big the main data section is
uint16_t part2_3_length = ((buffer[1] & 0x3F) << 6) | (buffer[2] >> 2); // bits 10-22
part2_3_length += ((buffer[8] & 0x7) << 9) | (buffer[9] << 1) | (buffer[10] >> 7) ; // bits 69-81
size_t offset = 17 + (part2_3_length+7)/8;
if (offset+9 < buffer_len && buffer[offset] == 0xb4)
{
unsigned long crc=255;
for (int i=0;i<9;i++)
crcofl(0x0045, 0x0080, &crc, buffer[offset+i]);
if ((crc & 0xFF) == buffer[offset+9])
{
total_length = (buffer[offset+3] << 24) | (buffer[offset+4] << 16) | (buffer[offset+5] << 8) | (buffer[offset+6]);
codec_delay = (buffer[offset+1] << 8) | (buffer[offset+2]);
additional_delay= (buffer[offset+7] << 8) | (buffer[offset+8]);
return NErr_Success;
}
}
}
}
return NErr_False;
}
|