LICENSE: CC0 1.0 Universal
[spdif-tools.git] / ac32spdif.c
1 \r
2 #include <stdio.h>\r
3 //#include <stdlib.h>\r
4 //#include <string.h>\r
5 #include <memory.h>\r
6 \r
7 //#include "fs_codes.h"\r
8 \r
9 \r
10 short bitrates[] = { 32,  40,  48,  56,  64,  80,  96, 112, 128, 160,\r
11 192, 224, 256, 320, 384, 448, 512, 576, 640 };\r
12 \r
13 short fsize44[] = {  70,   88,  105,  122,  140,  175,  209,  244,  279,  349,\r
14 418,  488,  558,  697,  836,  976, 1115, 1254, 1394 };\r
15 \r
16 unsigned long DecFS(char sratecode, unsigned long fsizecode)\r
17 {\r
18         switch (sratecode)\r
19         {\r
20                 case 0:\r
21                         return (bitrates[fsizecode / 2] * 2);\r
22                 case 1:\r
23                         return ((fsizecode % 2) ? fsize44[fsizecode / 2] : fsize44[fsizecode / 2] - 1);\r
24                 case 2:\r
25                         return (bitrates[fsizecode / 2] * 3);\r
26                 default:\r
27                         return 0;\r
28         }\r
29 \r
30         return 0;\r
31 }\r
32 \r
33 \r
34 \r
35 \r
36 struct WAVEHEADER {\r
37     unsigned long  ChunkID;\r
38     unsigned long  ChunkSize;\r
39     unsigned long  Format;\r
40     unsigned long  SubChunk1ID;\r
41     unsigned long  SubChunk1Size;\r
42     unsigned short AudioFormat;\r
43     unsigned short NumChannels;\r
44     unsigned long  SampleRate;\r
45     unsigned long  ByteRate;\r
46     unsigned short BlockAlign;\r
47     unsigned short BitsPerSample;\r
48     unsigned long  SubChunk2ID;\r
49     unsigned long  SubChunk2Size;\r
50 };\r
51 \r
52 \r
53 struct AC3PREAMBLE {\r
54         unsigned short sync1;\r
55         unsigned short sync2;\r
56         unsigned char burst_infoLSB;\r
57         unsigned char burst_infoMSB;\r
58         unsigned short lengthcode;\r
59 };\r
60 \r
61 char burst[6144];\r
62 \r
63 FILE *infile, *outfile;\r
64 \r
65 unsigned long bytesread;\r
66 unsigned long payloadbytes;\r
67 char sampleratecode;\r
68 unsigned long framesizecode;\r
69 \r
70 struct AC3PREAMBLE ac3p = { 0xF872, 0x4E1F, 1, 0, 0x3800 };\r
71 struct WAVEHEADER wavhdr = { 0x46464952,\r
72                                                         0,\r
73                                                         0x45564157,\r
74                                                         0x20746D66,\r
75                                                         16,\r
76                                                         1,\r
77                                                         2,\r
78                                                         0,\r
79                                                         0,\r
80                                                         4,\r
81                                                         16,\r
82                                                         0x61746164,\r
83                                                         0 };\r
84 \r
85 unsigned long i;\r
86 char temp;\r
87 \r
88 int main( int argc, char *argv[ ], char *envp[ ] )\r
89 {\r
90         if (argc < 3)\r
91         {\r
92                 printf("Wrong syntax. AC3PACK <In.ac3> <Out.wav>.\n");\r
93                 return 0;\r
94         }\r
95 \r
96         infile = fopen(argv[1], "rb");\r
97         outfile = fopen(argv[2], "wb");\r
98         //fseek(outfile, SEEK_SET, 44);\r
99         fwrite (&wavhdr, sizeof(struct WAVEHEADER), 1, outfile);\r
100 \r
101 \r
102 \r
103         for(;;)\r
104         {\r
105                 memset (burst, 0, 6144);\r
106                 bytesread = fread(&burst[8], 1, 6, infile);\r
107                 if (bytesread < 6)\r
108                 {\r
109                         printf ("EOF reached (Frame Header reading)!\nCurrent position in INFILE: %i\n", ftell(infile));\r
110                         break;\r
111                 }\r
112                 if ((burst[8] != 0x0B) || (burst[9] != 0x77))\r
113                 {\r
114                         printf("ERROR: INVALID SYNCWORD !\nCurrent position in INFILE: %i\n", ftell(infile));\r
115                         break;\r
116                 }\r
117                 framesizecode = (burst[12] & 63);\r
118                 sampleratecode = ((burst[12] & 192) / 64);\r
119 \r
120                 if (wavhdr.SampleRate == 0)\r
121                 {\r
122                                 printf ("First Sampleratecode: %i\n", sampleratecode);\r
123 \r
124                                 switch (sampleratecode)\r
125                                 {\r
126                                 case 0:\r
127                                         wavhdr.SampleRate = 48000;\r
128                                         wavhdr.ByteRate = 192000;\r
129                                         break;\r
130                                 case 1:\r
131                                         wavhdr.SampleRate = 44100;\r
132                                         wavhdr.ByteRate = 176000;\r
133                                         break;\r
134                                 case 2:\r
135                                         wavhdr.SampleRate = 32000;\r
136                                         wavhdr.ByteRate = 128000;\r
137                                         break;\r
138                                 default:\r
139                                         wavhdr.SampleRate = 48000;\r
140                                         wavhdr.ByteRate = 192000;\r
141                                 }\r
142                 }\r
143 \r
144                 payloadbytes = DecFS (sampleratecode, framesizecode);\r
145                 payloadbytes *= 2;\r
146 \r
147                 bytesread = fread (&burst[14], 1, payloadbytes - 6, infile);\r
148                 if ((bytesread + 6) < payloadbytes)\r
149                 {\r
150                         printf ("EOF reached (Burst Reading)!\nCurrent position in INFILE: %i\n", ftell(infile));\r
151                         printf ("Frame size: %i  .. Bytes read: %i\n", payloadbytes, bytesread);\r
152                         break;\r
153                 }\r
154                 ac3p.burst_infoMSB = (burst[13] & 7);\r
155                 ac3p.lengthcode = (short)(payloadbytes * 8);\r
156 \r
157                 for (i = 8; i < (payloadbytes + 8); i += 2)\r
158                 {\r
159                         temp = burst[i];\r
160                         burst[i] = burst[i + 1];\r
161                         burst[i + 1] = temp;\r
162                 }\r
163 \r
164                 memcpy (burst, &ac3p, sizeof(struct AC3PREAMBLE));\r
165 \r
166                 fwrite (burst, 1, 6144, outfile);\r
167 \r
168         }\r
169 \r
170         printf ("Last Sampleratecode: %i\n", sampleratecode);\r
171 \r
172         wavhdr.SubChunk2Size = (ftell(outfile) - 44);\r
173         wavhdr.ChunkSize = wavhdr.SubChunk2Size + 36;\r
174 \r
175         fseek (outfile, SEEK_SET, 0);\r
176         fwrite (&wavhdr, sizeof(struct WAVEHEADER), 1, outfile);\r
177 \r
178         fclose (infile);\r
179         fclose (outfile);\r
180 \r
181         return 0;\r
182 }\r