Mercurial > mplayer.hg
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 |