initial commit
[goodguy/history.git] / cinelerra-5.0 / quicktime / vbraudio.c
1 // Utility functions for vbr audio
2
3 #include "funcprotos.h"
4 #include "quicktime.h"
5
6
7
8 // Maximum samples to store in output buffer
9 #define MAX_VBR_BUFFER 0x200000
10
11
12
13 void quicktime_init_vbr(quicktime_vbr_t *vbr, int channels)
14 {
15         int i;
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));
20 }
21
22 void quicktime_clear_vbr(quicktime_vbr_t *vbr)
23 {
24         if( vbr->output_buffer ) {
25                 int i;
26                 for( i=0; i<vbr->channels; ++i )
27                         free(vbr->output_buffer[i]);
28                 free(vbr->output_buffer);
29         }
30
31         if( vbr->input_buffer )
32                 free(vbr->input_buffer);
33 }
34
35 int64_t quicktime_vbr_input_end(quicktime_vbr_t *vbr)
36 {
37         return vbr->input_end;
38 }
39
40 int64_t quicktime_vbr_output_end(quicktime_vbr_t *vbr)
41 {
42         return vbr->output_end;
43 }
44
45 unsigned char* quicktime_vbr_input(quicktime_vbr_t *vbr)
46 {
47         return vbr->input_buffer + vbr->inp_ptr;
48 }
49
50 int quicktime_vbr_input_size(quicktime_vbr_t *vbr)
51 {
52         return vbr->input_size;
53 }
54
55 int quicktime_limit_samples(int samples)
56 {
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",
60                         MAX_VBR_BUFFER);
61                 return 1;
62         }
63         return 0;
64 }
65
66 int quicktime_seek_vbr(quicktime_audio_map_t *atrack, int64_t start_time, int offset)
67 {
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;
76         vbr->sample = sample;
77         return 0;
78 }
79
80 int quicktime_align_vbr(quicktime_audio_map_t *atrack, int64_t start_position)
81 {
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;
85
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++;
91                 vbr->inp_ptr = 0;
92         }
93         return 0;
94 }
95
96 int quicktime_read_vbr(quicktime_t *file, quicktime_audio_map_t *atrack)
97 {
98         char *input_ptr;
99         int result = 0;
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;
106
107         if( vbr->input_allocation < new_allocation ) {
108                 vbr->input_buffer = realloc(vbr->input_buffer, new_allocation);
109                 vbr->input_allocation = new_allocation;
110         }
111
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);
117         return result;
118 }
119
120 void quicktime_shift_vbr(quicktime_audio_map_t *atrack, int bytes)
121 {
122         quicktime_vbr_t *vbr = &atrack->vbr;
123         if( bytes >= vbr->input_size ) {
124                 vbr->inp_ptr = 0;
125                 vbr->input_size = 0;
126         }
127         else {
128                 vbr->inp_ptr += bytes;
129                 vbr->input_size -= bytes;
130         }
131 }
132
133 void quicktime_store_vbr_float(quicktime_audio_map_t *atrack,
134         float *samples, int sample_count)
135 {
136         int i, j, k;
137         quicktime_vbr_t *vbr = &atrack->vbr;
138         int channels = vbr->channels;
139         i = vbr->out_ptr;
140
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;
145         }
146
147         vbr->out_ptr = i;
148         vbr->output_end += sample_count;
149         if( (vbr->output_size += sample_count) > MAX_VBR_BUFFER )
150                 vbr->output_size = MAX_VBR_BUFFER;
151 }
152
153 void quicktime_store_vbr_floatp(quicktime_audio_map_t *atrack,
154         float **samples, int sample_count)
155 {
156         int i, j, k;
157         quicktime_vbr_t *vbr = &atrack->vbr;
158         int channels = vbr->channels;
159         i = vbr->out_ptr;
160
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;
165         }
166
167         vbr->out_ptr = i;
168         vbr->output_end += sample_count;
169         if( (vbr->output_size += sample_count) > MAX_VBR_BUFFER )
170                 vbr->output_size = MAX_VBR_BUFFER;
171 }
172
173 void quicktime_store_vbr_int16(quicktime_audio_map_t *atrack,
174         int16_t *samples, int sample_count)
175 {
176         int i, j, k;
177         quicktime_vbr_t *vbr = &atrack->vbr;
178         int channels = vbr->channels;
179         i = vbr->out_ptr;
180
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;
185         }
186
187         vbr->out_ptr = i;
188         vbr->output_end += sample_count;
189         if( (vbr->output_size += sample_count) > MAX_VBR_BUFFER )
190                 vbr->output_size = MAX_VBR_BUFFER;
191 }
192
193 void quicktime_copy_vbr_float(quicktime_vbr_t *vbr,
194         int64_t start_position, int sample_count, float *output, int channel)
195 {
196         int i, k;
197         double *sp = vbr->output_buffer[channel];
198
199         i = vbr->out_ptr - (vbr->output_end - start_position);
200         while( i < 0 ) i += MAX_VBR_BUFFER;
201
202         for( k=0; k<sample_count; ++k ) {
203                 *output++ = sp[i++];
204                 if( i >= MAX_VBR_BUFFER ) i = 0;
205         }
206 }
207
208
209 void quicktime_copy_vbr_int16(quicktime_vbr_t *vbr,
210         int64_t start_position, int sample_count, int16_t *output, int channel)
211 {
212         int i, k;
213         double *sp = vbr->output_buffer[channel];
214
215         i = vbr->out_ptr - (vbr->output_end - start_position);
216         while( i < 0 ) i += MAX_VBR_BUFFER;
217
218         for( k=0; k<sample_count; ++k ) {
219                 *output++ = sp[i++] * 32767;
220                 if( i >= MAX_VBR_BUFFER ) i = 0;
221         }
222 }
223