1 // Utility functions for vbr audio
3 #include "funcprotos.h"
8 // Maximum samples to store in output buffer
9 #define MAX_VBR_BUFFER 0x200000
13 void quicktime_init_vbr(quicktime_vbr_t *vbr, int channels)
16 vbr->channels = channels;
17 vbr->output_buffer = calloc(channels, sizeof(double*));
18 for(i = 0; i < channels; i++)
19 vbr->output_buffer[i] = calloc(MAX_VBR_BUFFER, sizeof(double));
22 void quicktime_clear_vbr(quicktime_vbr_t *vbr)
24 if( vbr->output_buffer ) {
26 for( i=0; i<vbr->channels; ++i )
27 free(vbr->output_buffer[i]);
28 free(vbr->output_buffer);
31 if( vbr->input_buffer )
32 free(vbr->input_buffer);
35 int64_t quicktime_vbr_input_end(quicktime_vbr_t *vbr)
37 return vbr->input_end;
40 int64_t quicktime_vbr_output_end(quicktime_vbr_t *vbr)
42 return vbr->output_end;
45 unsigned char* quicktime_vbr_input(quicktime_vbr_t *vbr)
47 return vbr->input_buffer + vbr->inp_ptr;
50 int quicktime_vbr_input_size(quicktime_vbr_t *vbr)
52 return vbr->input_size;
55 int quicktime_limit_samples(int samples)
57 if( samples > MAX_VBR_BUFFER ) {
58 fprintf(stderr, "quicktime_limit_samples: "
59 "can't decode more than 0x%x samples at a time.\n",
66 int quicktime_seek_vbr(quicktime_audio_map_t *atrack, int64_t start_time, int offset)
68 quicktime_vbr_t *vbr = &atrack->vbr;
69 quicktime_stts_t *stts = &atrack->track->mdia.minf.stbl.stts;
70 int sample = quicktime_time_to_sample(stts, &start_time);
71 if( (sample-=offset) < 0 ) sample = 0;
72 start_time = quicktime_chunk_to_samples(stts, sample);
73 vbr->output_end = vbr->input_end = start_time;
74 vbr->output_size = vbr->input_size = 0;
75 vbr->out_ptr = vbr->inp_ptr = 0;
80 int quicktime_align_vbr(quicktime_audio_map_t *atrack, int64_t start_position)
82 quicktime_vbr_t *vbr = &atrack->vbr;
83 if( start_position < vbr->output_end - vbr->output_size ||
84 start_position > vbr->output_end ) return 1;
86 if( vbr->inp_ptr > 0 ) {
87 unsigned char *dp = vbr->input_buffer;
88 unsigned char *sp = dp + vbr->inp_ptr;
89 int i = vbr->input_size;
90 while( --i >= 0 ) *dp++ = *sp++;
96 int quicktime_read_vbr(quicktime_t *file, quicktime_audio_map_t *atrack)
100 quicktime_vbr_t *vbr = &atrack->vbr;
101 quicktime_trak_t *trak = atrack->track;
102 quicktime_stts_t *stts = &trak->mdia.minf.stbl.stts;
103 int64_t offset = quicktime_sample_to_offset(file, trak, vbr->sample);
104 int size = quicktime_sample_size(trak, vbr->sample);
105 int new_allocation = vbr->input_size + size;
107 if( vbr->input_allocation < new_allocation ) {
108 vbr->input_buffer = realloc(vbr->input_buffer, new_allocation);
109 vbr->input_allocation = new_allocation;
112 quicktime_set_position(file, offset);
113 input_ptr = (char *)vbr->input_buffer + vbr->inp_ptr + vbr->input_size;
114 result = !quicktime_read_data(file, input_ptr, size);
115 vbr->input_size += size;
116 vbr->input_end = quicktime_chunk_to_samples(stts, ++vbr->sample);
120 void quicktime_shift_vbr(quicktime_audio_map_t *atrack, int bytes)
122 quicktime_vbr_t *vbr = &atrack->vbr;
123 if( bytes >= vbr->input_size ) {
128 vbr->inp_ptr += bytes;
129 vbr->input_size -= bytes;
133 void quicktime_store_vbr_float(quicktime_audio_map_t *atrack,
134 float *samples, int sample_count)
137 quicktime_vbr_t *vbr = &atrack->vbr;
138 int channels = vbr->channels;
141 for( k=0; k<sample_count; ++k ) {
142 for( j=0; j<channels; ++j )
143 vbr->output_buffer[j][i] = *samples++;
144 if( ++i >= MAX_VBR_BUFFER ) i = 0;
148 vbr->output_end += sample_count;
149 if( (vbr->output_size += sample_count) > MAX_VBR_BUFFER )
150 vbr->output_size = MAX_VBR_BUFFER;
153 void quicktime_store_vbr_floatp(quicktime_audio_map_t *atrack,
154 float **samples, int sample_count)
157 quicktime_vbr_t *vbr = &atrack->vbr;
158 int channels = vbr->channels;
161 for( k=0; k<sample_count; ++k ) {
162 for( j=0; j<channels; ++j )
163 vbr->output_buffer[j][i] = samples[j][k];
164 if( ++i >= MAX_VBR_BUFFER ) i = 0;
168 vbr->output_end += sample_count;
169 if( (vbr->output_size += sample_count) > MAX_VBR_BUFFER )
170 vbr->output_size = MAX_VBR_BUFFER;
173 void quicktime_store_vbr_int16(quicktime_audio_map_t *atrack,
174 int16_t *samples, int sample_count)
177 quicktime_vbr_t *vbr = &atrack->vbr;
178 int channels = vbr->channels;
181 for( k=0; k<sample_count; ++k ) {
182 for( j=0; j<channels; ++j )
183 vbr->output_buffer[j][i] = *samples++ / 32768.0;
184 if( ++i >= MAX_VBR_BUFFER ) i = 0;
188 vbr->output_end += sample_count;
189 if( (vbr->output_size += sample_count) > MAX_VBR_BUFFER )
190 vbr->output_size = MAX_VBR_BUFFER;
193 void quicktime_copy_vbr_float(quicktime_vbr_t *vbr,
194 int64_t start_position, int sample_count, float *output, int channel)
197 double *sp = vbr->output_buffer[channel];
199 i = vbr->out_ptr - (vbr->output_end - start_position);
200 while( i < 0 ) i += MAX_VBR_BUFFER;
202 for( k=0; k<sample_count; ++k ) {
204 if( i >= MAX_VBR_BUFFER ) i = 0;
209 void quicktime_copy_vbr_int16(quicktime_vbr_t *vbr,
210 int64_t start_position, int sample_count, int16_t *output, int channel)
213 double *sp = vbr->output_buffer[channel];
215 i = vbr->out_ptr - (vbr->output_end - start_position);
216 while( i < 0 ) i += MAX_VBR_BUFFER;
218 for( k=0; k<sample_count; ++k ) {
219 *output++ = sp[i++] * 32767;
220 if( i >= MAX_VBR_BUFFER ) i = 0;