annotate TOOLS/302m_convert.c @ 18809:9634870ebe4c

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