r689: Fixed that changes made by dragging a control would often store each
[cinelerra_cv.git] / cinelerra / filebaseaudio.C
blob1bd1152937a52f65631c04ee9881c90b23c251c8
1 #include "asset.h"
2 #include "byteorder.h"
3 #include "file.h"
4 #include "filebase.h"
7 int64_t FileBase::samples_to_raw(char *out_buffer, 
8                                                         float **in_buffer,
9                                                         int64_t input_len, 
10                                                         int bits, 
11                                                         int channels,
12                                                         int byte_order,
13                                                         int signed_)
15         int output_advance;       // number of bytes in a sample
16         float *buffer_channel;    // channel in input buffer
17         float *buffer_channel_end;
18         int channel;
19         int64_t int_sample, int_sample2;
20         float float_sample;
21         int64_t dither_value, dither_scale = 255;
22         int64_t bytes = input_len * channels * (file->bytes_per_sample(bits));
23         int machine_byte_order = get_byte_order();
25         switch(bits)
26         {
27                 case BITSLINEAR8:
28                         {
29                                 char *output_ptr, *output_end;
30                                 output_advance = channels;
31                                 for(channel = 0; channel < channels; channel++)
32                                 {
33                                         output_ptr = out_buffer + channel;
34                                         buffer_channel = in_buffer[channel];
35                                         buffer_channel_end = buffer_channel + input_len;
37                                         if(dither)
38                                         {
39                                                 for( ; buffer_channel < buffer_channel_end; buffer_channel++)
40                                                 {
41                                                         float_sample = *buffer_channel * 0x7fff;
42                                                         int_sample = (int64_t)float_sample;
43                                                         if(int_sample > -0x7f00) { dither_value = rand() % dither_scale; int_sample -= dither_value; }
44                                                         int_sample /= 0x100;  // rotating bits screws up the signs
45                                                         *output_ptr = int_sample;
46                                                         output_ptr += output_advance;
47                                                 }
48                                         }
49                                         else
50                                         {
51                                                 for( ; buffer_channel < buffer_channel_end; buffer_channel++)
52                                                 {
53                                                         float_sample = *buffer_channel * 0x7f;
54                                                         *output_ptr = (char)float_sample;
55                                                         output_ptr += output_advance;
56                                                 }
57                                         }
58                                 }
60 // fix signed
61                                 if(!signed_)
62                                 {
63                                         output_ptr = out_buffer;
64                                         output_end = out_buffer + bytes;
66                                         for( ; output_ptr < output_end; output_ptr++)
67                                                 *output_ptr ^= 0x80;
68                                 }
69                         }
70                         break;
72                 case BITSLINEAR16:
73                         {
74                                 int16_t *output_ptr, *output_end;
75                                 output_advance = channels;
76                                 for(channel = 0; channel < channels; channel++)
77                                 {
78                                         output_ptr = (int16_t*)out_buffer + channel;
79                                         buffer_channel = in_buffer[channel];
80                                         buffer_channel_end = buffer_channel + input_len;
82                                         if(dither)
83                                         {
84                                                 for( ; buffer_channel < buffer_channel_end; buffer_channel++)
85                                                 {
86                                                         float_sample = *buffer_channel * 0x7fffff;
87                                                         int_sample = (int64_t)float_sample;
88                                                         if(int_sample > -0x7fff00) { dither_value = rand() % dither_scale; int_sample -= dither_value; }
89                                                         int_sample /= 0x100;
90                                                         *output_ptr = int_sample;
91                                                         output_ptr += output_advance;
92                                                 }
93                                         }
94                                         else
95                                         {
96                                                 for( ; buffer_channel < buffer_channel_end; buffer_channel++)
97                                                 {
98                                                         float_sample = *buffer_channel * 0x7fff;
99                                                         *output_ptr = (int16_t)float_sample;
100                                                         output_ptr += output_advance;
101                                                 }
102                                         }
103                                 }
104                         }
105                         break;
107                 case BITSLINEAR24:
108                         {
109                                 char *output_ptr, *output_end;
110                                 output_advance = asset->channels * 3 - 2;
111                                 for(channel = 0; channel < channels; channel++)
112                                 {
113                                         output_ptr = out_buffer + channel * 3;
114                                         buffer_channel = in_buffer[channel];
115                                         buffer_channel_end = buffer_channel + input_len;
117 // don't bother dithering 24 bits
118                                         for( ; buffer_channel < buffer_channel_end; buffer_channel++)
119                                         {
120                                                 float_sample = *buffer_channel * 0x7fffff;
121                                                 int_sample = (int64_t)float_sample;
122                                                 int_sample2 = int_sample & 0xff0000;
123                                                 *output_ptr++ = (int_sample & 0xff);
124                                                 int_sample &= 0xff00;
125                                                 *output_ptr++ = (int_sample >> 8);
126                                                 *output_ptr = (int_sample2 >> 16);
127                                                 output_ptr += output_advance;
128                                         }
129                                 }
130                         }
131                         break;
132                 
133                 case BITSULAW:
134                         {
135                                 char *output_ptr;
136                                 output_advance = asset->channels;
137 //printf("FileBase::samples_to_raw 1\n");
138                                 generate_ulaw_tables();
139 //printf("FileBase::samples_to_raw 2\n");
141                                 for(channel = 0; channel < channels; channel++)
142                                 {
143                                         output_ptr = out_buffer + channel;
144                                         buffer_channel = in_buffer[channel];
145                                         buffer_channel_end = buffer_channel + input_len;
146                                         for( ; buffer_channel < buffer_channel_end; buffer_channel++)
147                                         {
148                                                 *output_ptr = floattoulaw(*buffer_channel);
149                                                 output_ptr += output_advance;
150                                         }
151                                 }
152 //printf("FileBase::samples_to_raw 3\n");
153                         }
154                         break;
155         }
157 // swap bytes
158         if((bits == BITSLINEAR16 && byte_order != machine_byte_order) ||
159                 (bits == BITSLINEAR24 && !byte_order))
160         {
161                 swap_bytes(file->bytes_per_sample(bits), (unsigned char*)out_buffer, bytes);
162         }
164         return bytes;
168 #define READ_8_MACRO \
169                                 sample = *inbuffer_8;                   \
170                                 sample /= 0x7f; \
171                                 inbuffer_8 += input_frame;
173 #define READ_16_MACRO \
174                                 sample = *inbuffer_16;                   \
175                                 sample /= 0x7fff; \
176                                 inbuffer_16 += input_frame;
178 #define READ_24_MACRO \
179                                 sample = (unsigned char)*inbuffer_24++;  \
180                                 sample_24 = (unsigned char)*inbuffer_24++; \
181                                 sample_24 <<= 8;                           \
182                                 sample += sample_24;                       \
183                                 sample_24 = *inbuffer_24;                  \
184                                 sample_24 <<= 16;                          \
185                                 sample += sample_24;                       \
186                                 sample /= 0x7fffff; \
187                                 inbuffer_24 += input_frame; \
189 #define READ_ULAW_MACRO \
190                                 sample = ulawtofloat(*inbuffer_8);                   \
191                                 inbuffer_8 += input_frame;
193 #define LFEATHER_MACRO1 \
194                                 for(feather_current = 0; feather_current < lfeather_len; \
195                                         output_current++, feather_current++) \
196                                 {
198 #define LFEATHER_MACRO2 \
199                                         current_gain = lfeather_gain + lfeather_slope * feather_current; \
200                                         out_buffer[output_current] = out_buffer[output_current] * (1 - current_gain) + sample * current_gain; \
201                                 }
203 #define CENTER_MACRO1 \
204                                 for(; output_current < samples; \
205                                         output_current++) \
206                                 {
208 #define CENTER_MACRO2 \
209                                         out_buffer[output_current] += sample; \
210                                 }
212 int FileBase::raw_to_samples(float *out_buffer, char *in_buffer, 
213                 int64_t samples, int bits, int channels, int channel, int feather, 
214                 float lfeather_len, float lfeather_gain, float lfeather_slope)
216         int64_t output_current = 0;  // position in output buffer
217         int64_t input_len = samples;     // length of input buffer
218 // The following are floats because they are multiplied by the slope to get the gain.
219         float feather_current;     // input position for feather
221         float sample; 
222         char *inbuffer_8;               // point to actual byte being read
223         int16_t *inbuffer_16;
224         char *inbuffer_24;
225         int sample_24;                                         
226         float current_gain;
227         int input_frame;                   // amount to advance the input buffer pointer
229 // set up the parameters
230         switch(bits)
231         {
232                 case BITSLINEAR8:  
233                         inbuffer_8 = in_buffer + channel;
234                         input_frame = channels;
235                         break;
236                         
237                 case BITSLINEAR16: 
238                         inbuffer_16 = (int16_t *)in_buffer + channel;          
239                         input_frame = channels;
240                         break;
241                          
242                 case BITSLINEAR24: 
243                         inbuffer_24 = in_buffer + channel * 3;
244                         input_frame = channels * file->bytes_per_sample(bits) - 2; 
245                         break;
246                 
247                 case BITSULAW:
248                         generate_ulaw_tables();
249                         inbuffer_8 = in_buffer + channel;
250                         input_frame = channels;
251                         break;
252         }
254 // read the data
255 // ================== calculate feathering and add to buffer ================
256         if(feather)
257         {
258 // left feather
259                 switch(bits)
260                 {
261                         case BITSLINEAR8:
262                                 LFEATHER_MACRO1;                                             
263                                 READ_8_MACRO; 
264                                 LFEATHER_MACRO2;
265                                 break;
267                         case BITSLINEAR16:
268                                 LFEATHER_MACRO1;                                             
269                                 READ_16_MACRO; 
270                                 LFEATHER_MACRO2;
271                                 break;
273                         case BITSLINEAR24:                                               
274                                 LFEATHER_MACRO1;                                             
275                                 READ_24_MACRO; 
276                                 LFEATHER_MACRO2;
277                                 break;
278                         
279                         case BITSULAW:
280                                 LFEATHER_MACRO1;
281                                 READ_ULAW_MACRO;
282                                 LFEATHER_MACRO2;
283                                 break;
284                 }
285         
287 // central region
288                 switch(bits)
289                 {
290                         case BITSLINEAR8:                                                  
291                                 CENTER_MACRO1;
292                                 READ_8_MACRO; 
293                                 CENTER_MACRO2;
294                                 break;
296                         case BITSLINEAR16:
297                                 CENTER_MACRO1;
298                                 READ_16_MACRO;
299                                 CENTER_MACRO2;
300                                 break;
302                         case BITSLINEAR24:
303                                 CENTER_MACRO1;
304                                 READ_24_MACRO;
305                                 CENTER_MACRO2;
306                                 break;
307                         
308                         case BITSULAW:
309                                 CENTER_MACRO1;
310                                 READ_ULAW_MACRO;
311                                 CENTER_MACRO2;
312                                 break;
313                 }
314         }
315         else
316 // ====================== don't feather and overwrite buffer =================
317         {
318                 switch(bits)
319                 {
320                         case BITSLINEAR8:
321                                 for(; output_current < input_len; 
322                                         output_current++) 
323                                 { READ_8_MACRO; out_buffer[output_current] = sample; }
324                                 break;
326                         case BITSLINEAR16:
327                                 for(; output_current < input_len; 
328                                         output_current++) 
329                                 { READ_16_MACRO; out_buffer[output_current] = sample; }
330                                 break;
332                         case BITSLINEAR24:
333                                 for(; output_current < input_len; 
334                                         output_current++) 
335                                 { READ_24_MACRO; out_buffer[output_current] = sample; }
336                                 break;
337                         
338                         case BITSULAW:
339                                 for(; output_current < input_len; 
340                                         output_current++) 
341                                 { READ_ULAW_MACRO; out_buffer[output_current] = sample; }
342                                 break;
343                 }
344         }
346         return 0;
349 int FileBase::overlay_float_buffer(float *out_buffer, float *in_buffer, 
350                 int64_t samples, 
351                 float lfeather_len, float lfeather_gain, float lfeather_slope)
353         int64_t output_current = 0;
354         float sample, current_gain;
355         float feather_current;     // input position for feather
357         LFEATHER_MACRO1
358                 sample = in_buffer[output_current];
359         LFEATHER_MACRO2
361         CENTER_MACRO1
362                 sample = in_buffer[output_current];
363         CENTER_MACRO2
365         return 0;
369 int FileBase::get_audio_buffer(char **buffer, int64_t len, int64_t bits, int64_t channels)
371         int64_t bytes = len * channels * (file->bytes_per_sample(bits));
372         if(*buffer && bytes > prev_bytes) 
373         { 
374                 delete [] *buffer; 
375                 *buffer = 0; 
376         }
377         prev_bytes = bytes;
379         if(!*buffer) *buffer = new char[bytes];
382 int FileBase::get_float_buffer(float **buffer, int64_t len)
384         if(*buffer && len > prev_len) 
385         { 
386                 delete [] *buffer; 
387                 *buffer = 0; 
388         }
389         prev_len = len;
391         if(!*buffer) *buffer = new float[len];