This commit is contained in:
'mr software' 2023-10-08 20:38:50 -07:00
parent d764ce7e9c
commit 3989ed9779
1 changed files with 148 additions and 8 deletions

156
main.c
View File

@ -1,19 +1,33 @@
#include <stdint.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <arpa/inet.h>
// TODO autodetect endianness here
#define fromle(x) (x)
// get bit big endian
#define bitb(x, y) ((((uint8_t*)(x))[y >> 3] >> (7 - (y & 7))) & 1)
//#define bitb(x, y) ((((uint8_t*)(x))[(y) >> 3] >> (7 - ((y) & 7))) & 1)
uint8_t bitb(uint8_t* s, uint32_t b) {
return (s[b >> 3] >> (7 - (b & 7))) & 1;
}
#define bitrb(x, y, z) ibitrb((uint8_t*)x, y, z)
#define cast(x, y) (*((x*)&(y)))
uint32_t bitrb(uint8_t* s, uint32_t b, char e) { // bit range big endian
#define cblimit 21
#define cblimit_short 12
uint32_t ibitrb(uint8_t* s, uint32_t* b, char e) { // bit range big endian
uint32_t a = 0;
for(int i = 0; i < e; i++) a = (a << 1) | bitb(s, b+i);
printf("bitrb %X\n", a);
for(int i = 0; i < e; i++) a = (a << 1) | bitb(s, (*b)+i);
//printf("bitrb %i at %i: 0x%X, 0d%u\n", e, *b, a, a);
*b += e;
return a;
}
@ -5127,6 +5141,32 @@ uint32_t verify_l3(uint32_t d) { // returns 0 if header is valid
return (d & 0xFFFE0000) ^ 0xFFFA0000;
}
typedef struct {
uint8_t x;
uint8_t y;
} coord;
// TODO possiblility block_type is undefined if blocksplit not set. read spec for blocksplit_flag and block_type
// table to get length of scalefactor bands
uint8_t sfcom[16][2] = {
{0,0},
{0,1},
{0,2},
{0,3},
{3,0},
{1,1},
{1,2},
{1,3},
{2,1},
{2,2},
{2,3},
{3,1},
{3,2},
{3,3},
{4,2},
{4,3},
};
void rdl3(uint32_t* s, mp3_frame* m) {
uint32_t d = ntohl(*(s++));
m->hdr = d;
@ -5143,9 +5183,98 @@ void rdl3(uint32_t* s, mp3_frame* m) {
m->crc = htons(*((uint16_t*)s)); // only valid if m->crc
int bp = m->prot << 4; // bitpointer
if(m->mode) { // mono
uint32_t bp = m->prot << 4; // bitpointer
uint16_t main_data_end = bitrb(s, &bp, 9);
char private_bits = bitrb(s, &bp, 5 - ((m->mode != 3) << 1));
char num_ch = 1 + (m->mode != 3);
char scfsi[4][num_ch];
uint16_t part2_3_length[2][num_ch];
uint16_t big_values[2][num_ch];
uint8_t global_gain[2][num_ch];
uint8_t scalefac_compress[2][num_ch];
uint8_t blocksplit_flag[2][num_ch];
// used if blocksplit flag is set
uint8_t block_type[2][num_ch];
uint8_t switch_point[2][num_ch];
uint8_t table_select[2][2][num_ch];
uint8_t subblock_gain[3][2][num_ch];
// used if NOT set
uint8_t region_address1[2][num_ch];
uint8_t region_address2[2][num_ch];
uint8_t preflag[2][num_ch];
uint8_t scalefac_scale[2][num_ch];
uint8_t count1table_select[2][num_ch];
for(int band = 0; band < 4; band++) for(int ch = 0; ch < num_ch; ch++) scfsi[band][ch] = bitrb(s, &bp, 1);
for(int gr = 0; gr < 2; gr++) for(int ch = 0; ch < num_ch; ch++) {
part2_3_length[gr][ch] = bitrb(s, &bp, 12);
big_values[gr][ch] = bitrb(s, &bp, 9);
global_gain[gr][ch] = bitrb(s, &bp, 8);
scalefac_compress[gr][ch] = bitrb(s, &bp, 4);
blocksplit_flag[gr][ch] = bitrb(s, &bp, 1);
if(blocksplit_flag[gr][ch]) {
block_type[gr][ch] = bitrb(s, &bp, 2);
switch_point[gr][ch] = bitrb(s, &bp, 1);
for(int reg = 0; reg < 2; reg++) table_select[reg][gr][ch] = bitrb(s, &bp, 5);
for(int window = 0; window < 3; window++) subblock_gain[window][gr][ch] = bitrb(s, &bp, 3);
} else {
for(int reg = 0; reg < 3; reg++) table_select[reg][gr][ch] = bitrb(s, &bp, 5);
region_address1[gr][ch] = bitrb(s, &bp, 4);
region_address2[gr][ch] = bitrb(s, &bp, 3);
}
preflag[gr][ch] = bitrb(s, &bp, 1);
scalefac_scale[gr][ch] = bitrb(s, &bp, 1);
count1table_select[gr][ch] = bitrb(s, &bp, 1);
}
// begin to parse main_data
// TODO completely unclear where it is supposed to start - comment from specification reproduced below
/***
The main_data follows. It does not follow the above side information in the
bitstream. The main_data ends at a location in the main_data bitstream
preceding the frame header of the following frame at an offset given by the
value of main_data_end (see definition of main_data_end and 3-Annex Fig.3-
A.7.1
***/
int bpsave = bp;
for(int gr = 0; gr < 2; gr++) for(int ch = 0; ch < num_ch; ch++) {
if(blocksplit_flag[gr][ch] && block_type[gr][ch] == 2) {
// long window(?)
for(int cb = 0; cb < (switch_point[gr][ch] ? 8 : 0); cb++) if(!scfsi[cb] | !gr) {
// TODO scalefac[cb][gr][ch]
// use scalefac_compress[gr][ch]
int sfcd;
if(block_type[gr][ch] != 2) sfcd = cb > 10;
else if(switch_point[gr][ch]) {
// TODO if block_type is 2 and switch_point is 1
} else sfcd = cb > 5;
//scalefac[cb][0/*window*/][gr][ch] = bitrb(s, &bp, sfcom[scalefac_compress[gr][ch]][sfcd]);
}
// short window(?)
for(int cb = (switch_point[gr][ch] ? 3 : 0); cb < cblimit_short; cb++) for(int window = 0; window < 3; window++) if(!scfsi[cb] | !gr) {
// TODO scalefac[cb][gr][ch]
// use scalefac_compress[gr][ch]
}
} else {
for(int cb = 0; cb < cblimit; cb++) if(!scfsi[cb] | !gr) {
// TODO scalefac[cb][gr][ch]
// use scalefac_compress[gr][ch]
}
// TODO huffman bits
unsigned short csz = 16, ci = 0;
coord* c = malloc(csz * sizeof(coord));
while(bp < bpsave + part2_3_length[gr][ch]) {
//bp += huffman(table_select[]);
}
}
}
}
@ -5164,11 +5293,20 @@ int main(int argc, char** argv) {
uint8_t* stream = malloc(s.st_size);
read(fd, stream, s.st_size);
static char* yn[2] = {"no", "yes"};
static char* chtyp[4] = {"stereo", "joint stereo", "dual mono (stereo)", "mono"};
static char* emph[4] = {"none", "50/15 ms", "reserved", "CCIT J.17"};
printf("begin reading %s (%u bytes at %p)\n", argv[f], s.st_size, stream);
printf("begin reading %s (%lu bytes at %p)\n", argv[f], s.st_size, stream);
if(!memcmp(stream, "ID3", 3)) {
int d = htonl(*((uint32_t*)(stream + 6)));
sp += d + 10 + ((stream[5] & 0x10) ? 10 : 0);
printf("ID3v2 detected, skipping %08X bytes so as not to deal with it\n", sp);
}
if(!memcmp(stream + s.st_size - 128, "TAG", 3)) printf("TAG detected :)\n");
while(!verify_l3(*(uint32_t*)(stream + sp))) {
printf("frame %u sync at %u (%X)!\n", fc, sp, sp);
@ -5196,5 +5334,7 @@ int main(int argc, char** argv) {
sp += m.len;
fc++;
}
free(stream);
}
}