9 } quicktime_rawaudio_codec_t;
11 /* =================================== private for rawaudio */
13 static int is_little_endian(void)
15 int16_t test = 0x0001;
16 return *((unsigned char *)&test);
19 static int get_work_buffer(quicktime_t *file, int track, long bytes)
21 quicktime_rawaudio_codec_t *codec = ((quicktime_codec_t*)file->atracks[track].codec)->priv;
23 if(codec->work_buffer && codec->buffer_size != bytes) {
24 free(codec->work_buffer);
25 codec->work_buffer = 0;
28 if(!codec->work_buffer) {
29 codec->buffer_size = bytes;
30 if(!(codec->work_buffer = malloc(bytes))) return 1;
35 /* =================================== public for rawaudio */
37 static void quicktime_delete_codec_rawaudio(quicktime_audio_map_t *atrack)
39 quicktime_rawaudio_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;
41 if(codec->work_buffer) free(codec->work_buffer);
42 codec->work_buffer = 0;
43 codec->buffer_size = 0;
47 static int fclip(float f, int mx)
49 f *= mx; f += f >= 0 ? 0.5f : -0.5f;
50 return f >= mx ? mx+mx-1 : f < -mx ? 0 : (int)f + mx;
52 static int fclip8 (float f) { return fclip(f,0x80); }
53 static int fclip16(float f) { return fclip(f,0x8000); }
54 static int fclip24(float f) { return fclip(f,0x800000); }
56 static int rd8be_s16 (uint8_t *bp) { return (bp[0]<<8) - 0x8000; }
57 static int rd8le_s16 (uint8_t *bp) { return (bp[0]<<8) - 0x8000; }
58 static int rd16be_s16(uint8_t *bp) { return ((bp[0]<<8) | bp[1]) - 0x8000; }
59 static int rd16le_s16(uint8_t *bp) { return (bp[0] | (bp[1]<<8)) - 0x8000; }
60 static int rd24be_s16(uint8_t *bp) { return ((bp[0]<<8) | bp[1]) - 0x8000; }
61 static int rd24le_s16(uint8_t *bp) { return (bp[1] | (bp[2]<<8)) - 0x8000; }
62 static float rd8be_flt (uint8_t *bp) { return (float)(bp[0]-0x80)/0x80; }
63 static float rd8le_flt (uint8_t *bp) { return (float)(bp[0]-0x80)/0x80; }
64 static float rd16be_flt(uint8_t *bp) { return (float)(((bp[0]<<8) | bp[1])-0x8000)/0x8000; }
65 static float rd16le_flt(uint8_t *bp) { return (float)((bp[0] | (bp[1]<<8))-0x8000)/0x8000; }
66 static float rd24be_flt(uint8_t *bp) { return (float)(((bp[0]<<16) | (bp[1]<<8) | bp[2])-0x800000)/0x800000; }
67 static float rd24le_flt(uint8_t *bp) { return (float)((bp[0] | (bp[1]<<8) | (bp[2]<<16))-0x800000)/0x800000; }
69 static void wr8be_s16 (uint8_t *bp, int v) { v+=0x8000; bp[0] = v>>8; }
70 static void wr8le_s16 (uint8_t *bp, int v) { v+=0x8000; bp[0] = v>>8; }
71 static void wr16be_s16(uint8_t *bp, int v) { v+=0x8000; bp[0] = v>>8; bp[1] = v; }
72 static void wr16le_s16(uint8_t *bp, int v) { v+=0x8000; bp[0] = v; bp[1] = v>>8; }
73 static void wr24be_s16(uint8_t *bp, int v) { v+=0x8000; bp[0] = v>>8; bp[1] = v; bp[2] = 0; }
74 static void wr24le_s16(uint8_t *bp, int v) { v+=0x8000; bp[0] = 0; bp[1] = v; bp[2] = v>>8; }
75 static void wr8be_flt (uint8_t *bp, float f) { int v = fclip8(f); bp[0] = v; }
76 static void wr8le_flt (uint8_t *bp, float f) { int v = fclip8(f); bp[0] = v; }
77 static void wr16be_flt(uint8_t *bp, float f) { int v = fclip16(f); bp[0] = v>>8; bp[1] = v; }
78 static void wr16le_flt(uint8_t *bp, float f) { int v = fclip16(f); bp[0] = v; bp[1] = v>>8; }
79 static void wr24be_flt(uint8_t *bp, float f) { int v = fclip24(f); bp[0] = v>>16; bp[1] = v>>8; bp[2] = v; }
80 static void wr24le_flt(uint8_t *bp, float f) { int v = fclip24(f); bp[0] = v; bp[1] = v>>8; bp[2] = v>>16; }
82 #define rd_samples(typ, fn, out, step) { \
83 uint8_t *bp = (uint8_t *)codec->work_buffer + channel*byts; \
84 for( i=0; i<samples; ++i ) { *out++ = fn(bp); bp += step; } \
87 #define wr_samples(typ, fn, in, step) { \
88 for( j=0; j<channels; ++j ) { typ *inp = in[j]; \
89 uint8_t *bp = (uint8_t *)codec->work_buffer + j*byts; \
90 for( i=0; i<samples; ++i ) { fn(bp,*inp++); bp += step; } \
94 static int quicktime_decode_rawaudio(quicktime_t *file,
95 int16_t *output_i, float *output_f, long samples,
96 int track, int channel)
99 int little_endian = is_little_endian();
100 quicktime_audio_map_t *track_map = &(file->atracks[track]);
101 quicktime_rawaudio_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;
102 int bits = quicktime_audio_bits(file, track);
103 int byts = bits/8, channels = file->atracks[track].channels;
104 int size = channels * byts;
105 get_work_buffer(file, track, samples * size);
106 result = !quicktime_read_audio(file, codec->work_buffer, samples, track);
107 if( result ) return result;
108 // Undo increment since this is done in codecs.c
109 track_map->current_position -= samples;
110 if( !little_endian ) {
113 case 1: rd_samples(int16_t,rd8be_s16,output_i,size); break;
114 case 2: rd_samples(int16_t,rd16be_s16,output_i,size); break;
115 case 3: rd_samples(int16_t,rd24be_s16,output_i,size); break;
118 else if( output_f ) {
120 case 1: rd_samples(float,rd8be_flt,output_f,size); break;
121 case 2: rd_samples(float,rd16be_flt,output_f,size); break;
122 case 3: rd_samples(float,rd24be_flt,output_f,size); break;
127 // Undo increment since this is done in codecs.c
128 track_map->current_position -= samples;
131 case 1: rd_samples(int16_t,rd8le_s16,output_i,size); break;
132 case 2: rd_samples(int16_t,rd16le_s16,output_i,size); break;
133 case 3: rd_samples(int16_t,rd24le_s16,output_i,size); break;
136 else if( output_f ) {
138 case 1: rd_samples(float,rd8le_flt,output_f,size); break;
139 case 2: rd_samples(float,rd16le_flt,output_f,size); break;
140 case 3: rd_samples(float,rd24le_flt,output_f,size); break;
144 /*printf("quicktime_decode_rawaudio 2\n"); */
148 static int quicktime_encode_rawaudio(quicktime_t *file,
149 int16_t **input_i, float **input_f, int track, long samples)
152 int little_endian = is_little_endian();
153 quicktime_audio_map_t *track_map = &(file->atracks[track]);
154 quicktime_rawaudio_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;
155 int bits = quicktime_audio_bits(file, track);
156 int byts = bits/8, channels = file->atracks[track].channels;
157 int size = channels * byts;
158 get_work_buffer(file, track, samples * size);
160 if( !little_endian ) {
163 case 1: wr_samples(int16_t,wr8be_s16,input_i,size); break;
164 case 2: wr_samples(int16_t,wr16be_s16,input_i,size); break;
165 case 3: wr_samples(int16_t,wr24be_s16,input_i,size); break;
170 case 1: wr_samples(float,wr8be_flt,input_f,size); break;
171 case 2: wr_samples(float,wr16be_flt,input_f,size); break;
172 case 3: wr_samples(float,wr24be_flt,input_f,size); break;
179 case 1: wr_samples(int16_t,wr8le_s16,input_i,size); break;
180 case 2: wr_samples(int16_t,wr16le_s16,input_i,size); break;
181 case 3: wr_samples(int16_t,wr24le_s16,input_i,size); break;
186 case 1: wr_samples(float,wr8le_flt,input_f,size); break;
187 case 2: wr_samples(float,wr16le_flt,input_f,size); break;
188 case 3: wr_samples(float,wr24le_flt,input_f,size); break;
193 result = quicktime_write_audio(file, (char *)codec->work_buffer, samples, track);
198 void quicktime_init_codec_rawaudio(quicktime_audio_map_t *atrack)
200 quicktime_codec_t *codec_base = (quicktime_codec_t*)atrack->codec;
201 // quicktime_rawaudio_codec_t *codec = codec_base->priv;
203 /* Init public items */
204 codec_base->priv = calloc(1, sizeof(quicktime_rawaudio_codec_t));
205 codec_base->delete_acodec = quicktime_delete_codec_rawaudio;
206 codec_base->decode_video = 0;
207 codec_base->encode_video = 0;
208 codec_base->decode_audio = quicktime_decode_rawaudio;
209 codec_base->encode_audio = quicktime_encode_rawaudio;
210 codec_base->fourcc = QUICKTIME_RAW;
211 codec_base->title = "8 bit unsigned";
212 codec_base->desc = "8 bit unsigned for audio";
213 codec_base->wav_id = 0x01;
214 /* Init private items */