comparison TOOLS/302m_convert.c @ 16298:78f69659c797

Add D-Cinema Audio and Video conversion programs
author reimar
date Tue, 23 Aug 2005 18:03:23 +0000
parents
children
comparison
equal deleted inserted replaced
16297:c6e8ef454266 16298:78f69659c797
1 /**
2 * convert D-Cinema Audio (probably SMPTE 302M) to a
3 * wav file that MPlayer can play.
4 * Usage: 302m_convert <infile> <outfile>
5 */
6 #include <stdlib.h>
7 #include <stdio.h>
8 #include <inttypes.h>
9 #include <byteswap.h>
10 #define le2me_32(x) (x)
11 #define le2me_16(x) (x)
12 #define be2me_16(x) bswap_16(x)
13
14 // From MPlayer libao/ao_pcm.c
15 #define WAV_ID_RIFF 0x46464952 /* "RIFF" */
16 #define WAV_ID_WAVE 0x45564157 /* "WAVE" */
17 #define WAV_ID_FMT 0x20746d66 /* "fmt " */
18 #define WAV_ID_DATA 0x61746164 /* "data" */
19 #define WAV_ID_PCM 0x0001
20
21 struct WaveHeader {
22 uint32_t riff;
23 uint32_t file_length;
24 uint32_t wave;
25 uint32_t fmt;
26 uint32_t fmt_length;
27 uint16_t fmt_tag;
28 uint16_t channels;
29 uint32_t sample_rate;
30 uint32_t bytes_per_second;
31 uint16_t block_align;
32 uint16_t bits;
33 uint32_t data;
34 uint32_t data_length;
35 };
36
37 static struct WaveHeader wavhdr = {
38 le2me_32(WAV_ID_RIFF),
39 le2me_32(0x7fffffff),
40 le2me_32(WAV_ID_WAVE),
41 le2me_32(WAV_ID_FMT),
42 le2me_32(16),
43 le2me_16(WAV_ID_PCM),
44 le2me_16(6),
45 le2me_32(96000),
46 le2me_32(1728000),
47 le2me_16(18),
48 le2me_16(24),
49 le2me_32(WAV_ID_DATA),
50 le2me_32(0x7fffffff),
51 };
52
53 // this format is completely braindead, and this bitorder
54 // is the result of pure guesswork (counting how often
55 // the bits flip), so it might be wrong.
56 void fixup(unsigned char *in_, unsigned char *out) {
57 int i;
58 unsigned char in[3] = {in_[0], in_[1], in_[2]};
59 unsigned char sync = in[2] & 0x0f; // sync flags
60 in[2] >>= 4;
61 out[2] = 0;
62 for (i = 0; i < 4; i++) {
63 out[2] <<= 1;
64 out[2] |= in[2] & 1;
65 in[2] >>= 1;
66 }
67 for (i = 0; i < 4; i++) {
68 out[2] <<= 1;
69 out[2] |= in[1] & 1;
70 in[1] >>= 1;
71 }
72 out[1] = 0;
73 for (i = 0; i < 4; i++) {
74 out[1] <<= 1;
75 out[1] |= in[1] & 1;
76 in[1] >>= 1;
77 }
78 for (i = 0; i < 4; i++) {
79 out[1] <<= 1;
80 out[1] |= in[0] & 1;
81 in[0] >>= 1;
82 }
83 out[0] = 0;
84 for (i = 0; i < 4; i++) {
85 out[0] <<= 1;
86 out[0] |= in[0] & 1;
87 in[0] >>= 1;
88 }
89 out[0] <<= 4;
90 out[0] |= sync; // sync flags go into lowest bits
91 // it seems those might also contain audio data,
92 // don't know if this is the right order then
93 // these might be also useful to detect the number
94 // of channels in case there are files with != 6 channels
95 }
96
97 int main(int argc, char *argv[]) {
98 FILE *in = fopen(argv[1], "r");
99 FILE *out = fopen(argv[2], "w");
100 int i;
101 uint16_t blocklen, unknown;
102 unsigned char *block;
103 if (!in) {
104 printf("Could not open %s for reading\n", argv[1]);
105 return EXIT_FAILURE;
106 }
107 if (!out) {
108 printf("Could not open %s for writing\n", argv[2]);
109 return EXIT_FAILURE;
110 }
111 fwrite(&wavhdr, 1, sizeof(wavhdr), out);
112 do {
113 fread(&blocklen, 2, 1, in);
114 blocklen = be2me_16(blocklen);
115 fread(&unknown, 2, 1, in);
116 block = malloc(blocklen);
117 blocklen = fread(block, 1, blocklen, in);
118 for (i = 0; i < blocklen; i += 3)
119 fixup(&block[i], &block[i]);
120 fwrite(block, 1, blocklen, out);
121 free(block);
122 } while (!feof(in));
123 return EXIT_SUCCESS;
124 }
125