add bluray dv, misc fixes
[goodguy/history.git] / cinelerra-5.1 / cinelerra / filebaseaudio.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  */
21
22 #include "asset.h"
23 #include "byteorder.h"
24 #include "file.h"
25 #include "filebase.h"
26
27
28 int64_t FileBase::samples_to_raw(char *out_buffer,
29                                                         float **in_buffer,
30                                                         int64_t input_len,
31                                                         int bits,
32                                                         int channels,
33                                                         int byte_order,
34                                                         int signed_)
35 {
36         int output_advance;       // number of bytes in a sample
37         float *buffer_channel;    // channel in input buffer
38         float *buffer_channel_end;
39         int channel;
40         int64_t int_sample, int_sample2;
41         float float_sample;
42         int64_t dither_value, dither_scale = 255;
43         int64_t bytes = input_len * channels * (file->bytes_per_sample(bits));
44         int machine_byte_order = get_byte_order();
45
46         switch(bits)
47         {
48                 case BITSLINEAR8:
49                         {
50                                 char *output_ptr, *output_end;
51                                 output_advance = channels;
52                                 for(channel = 0; channel < channels; channel++)
53                                 {
54                                         output_ptr = out_buffer + channel;
55                                         buffer_channel = in_buffer[channel];
56                                         buffer_channel_end = buffer_channel + input_len;
57
58                                         if(dither)
59                                         {
60                                                 for( ; buffer_channel < buffer_channel_end; buffer_channel++)
61                                                 {
62                                                         float_sample = *buffer_channel * 0x7fff;
63                                                         int_sample = (int64_t)float_sample;
64                                                         if(int_sample > -0x7f00) { dither_value = rand() % dither_scale; int_sample -= dither_value; }
65                                                         int_sample /= 0x100;  // rotating bits screws up the signs
66                                                         *output_ptr = int_sample;
67                                                         output_ptr += output_advance;
68                                                 }
69                                         }
70                                         else
71                                         {
72                                                 for( ; buffer_channel < buffer_channel_end; buffer_channel++)
73                                                 {
74                                                         float_sample = *buffer_channel * 0x7f;
75                                                         *output_ptr = (char)float_sample;
76                                                         output_ptr += output_advance;
77                                                 }
78                                         }
79                                 }
80
81 // fix signed
82                                 if(!signed_)
83                                 {
84                                         output_ptr = out_buffer;
85                                         output_end = out_buffer + bytes;
86
87                                         for( ; output_ptr < output_end; output_ptr++)
88                                                 *output_ptr ^= 0x80;
89                                 }
90                         }
91                         break;
92
93                 case BITSLINEAR16:
94                         {
95                                 int16_t *output_ptr;
96                                 output_advance = channels;
97                                 for(channel = 0; channel < channels; channel++)
98                                 {
99                                         output_ptr = (int16_t*)out_buffer + channel;
100                                         buffer_channel = in_buffer[channel];
101                                         buffer_channel_end = buffer_channel + input_len;
102
103                                         if(dither)
104                                         {
105                                                 for( ; buffer_channel < buffer_channel_end; buffer_channel++)
106                                                 {
107                                                         float_sample = *buffer_channel * 0x7fffff;
108                                                         int_sample = (int64_t)float_sample;
109                                                         if(int_sample > -0x7fff00) { dither_value = rand() % dither_scale; int_sample -= dither_value; }
110                                                         int_sample /= 0x100;
111                                                         *output_ptr = int_sample;
112                                                         output_ptr += output_advance;
113                                                 }
114                                         }
115                                         else
116                                         {
117                                                 for( ; buffer_channel < buffer_channel_end; buffer_channel++)
118                                                 {
119                                                         float_sample = *buffer_channel * 0x7fff;
120                                                         *output_ptr = (int16_t)float_sample;
121                                                         output_ptr += output_advance;
122                                                 }
123                                         }
124                                 }
125                         }
126                         break;
127
128                 case BITSLINEAR24:
129                         {
130                                 char *output_ptr;
131                                 output_advance = asset->channels * 3 - 2;
132                                 for(channel = 0; channel < channels; channel++)
133                                 {
134                                         output_ptr = out_buffer + channel * 3;
135                                         buffer_channel = in_buffer[channel];
136                                         buffer_channel_end = buffer_channel + input_len;
137
138 // don't bother dithering 24 bits
139                                         for( ; buffer_channel < buffer_channel_end; buffer_channel++)
140                                         {
141                                                 float_sample = *buffer_channel * 0x7fffff;
142                                                 int_sample = (int64_t)float_sample;
143                                                 int_sample2 = int_sample & 0xff0000;
144                                                 *output_ptr++ = (int_sample & 0xff);
145                                                 int_sample &= 0xff00;
146                                                 *output_ptr++ = (int_sample >> 8);
147                                                 *output_ptr = (int_sample2 >> 16);
148                                                 output_ptr += output_advance;
149                                         }
150                                 }
151                         }
152                         break;
153
154                 case BITSULAW:
155                         {
156                                 char *output_ptr;
157                                 output_advance = asset->channels;
158 //printf("FileBase::samples_to_raw 1\n");
159                                 generate_ulaw_tables();
160 //printf("FileBase::samples_to_raw 2\n");
161
162                                 for(channel = 0; channel < channels; channel++)
163                                 {
164                                         output_ptr = out_buffer + channel;
165                                         buffer_channel = in_buffer[channel];
166                                         buffer_channel_end = buffer_channel + input_len;
167                                         for( ; buffer_channel < buffer_channel_end; buffer_channel++)
168                                         {
169                                                 *output_ptr = floattoulaw(*buffer_channel);
170                                                 output_ptr += output_advance;
171                                         }
172                                 }
173 //printf("FileBase::samples_to_raw 3\n");
174                         }
175                         break;
176         }
177
178 // swap bytes
179         if((bits == BITSLINEAR16 && byte_order != machine_byte_order) ||
180                 (bits == BITSLINEAR24 && !byte_order))
181         {
182                 swap_bytes(file->bytes_per_sample(bits), (unsigned char*)out_buffer, bytes);
183         }
184
185         return bytes;
186 }
187
188
189 #define READ_8_MACRO \
190                                 sample = *inbuffer_8;                   \
191                                 sample /= 0x7f; \
192                                 inbuffer_8 += input_frame;
193
194 #define READ_16_MACRO \
195                                 sample = *inbuffer_16;                   \
196                                 sample /= 0x7fff; \
197                                 inbuffer_16 += input_frame;
198
199 #define READ_24_MACRO \
200                                 sample = (unsigned char)*inbuffer_24++;  \
201                                 sample_24 = (unsigned char)*inbuffer_24++; \
202                                 sample_24 <<= 8;                           \
203                                 sample += sample_24;                       \
204                                 sample_24 = *inbuffer_24;                  \
205                                 sample_24 <<= 16;                          \
206                                 sample += sample_24;                       \
207                                 sample /= 0x7fffff; \
208                                 inbuffer_24 += input_frame; \
209
210 #define READ_ULAW_MACRO \
211                                 sample = ulawtofloat(*inbuffer_8);                   \
212                                 inbuffer_8 += input_frame;
213
214 #define LFEATHER_MACRO1 \
215                                 for(feather_current = 0; feather_current < lfeather_len; \
216                                         output_current++, feather_current++) \
217                                 {
218
219 #define LFEATHER_MACRO2 \
220                                         current_gain = lfeather_gain + lfeather_slope * feather_current; \
221                                         out_buffer[output_current] = out_buffer[output_current] * (1 - current_gain) + sample * current_gain; \
222                                 }
223
224 #define CENTER_MACRO1 \
225                                 for(; output_current < samples; \
226                                         output_current++) \
227                                 {
228
229 #define CENTER_MACRO2 \
230                                         out_buffer[output_current] += sample; \
231                                 }
232
233 int FileBase::raw_to_samples(float *out_buffer, char *in_buffer,
234                 int64_t samples, int bits, int channels, int channel, int feather,
235                 float lfeather_len, float lfeather_gain, float lfeather_slope)
236 {
237         int64_t output_current = 0;    // position in output buffer
238         int64_t input_len = samples;   // length of input buffer
239 // The following are floats because they are multiplied by the slope to get the gain.
240         float feather_current;         // input position for feather
241
242         float sample;
243         char *inbuffer_8 = 0;          // point to actual byte being read
244         int16_t *inbuffer_16 = 0;
245         char *inbuffer_24 = 0;
246         int sample_24;
247         float current_gain;
248         int input_frame = 0;           // amount to advance the input buffer pointer
249
250 // set up the parameters
251         switch(bits)
252         {
253                 case BITSLINEAR8:
254                         inbuffer_8 = in_buffer + channel;
255                         input_frame = channels;
256                         break;
257
258                 case BITSLINEAR16:
259                         inbuffer_16 = (int16_t *)in_buffer + channel;
260                         input_frame = channels;
261                         break;
262
263                 case BITSLINEAR24:
264                         inbuffer_24 = in_buffer + channel * 3;
265                         input_frame = channels * file->bytes_per_sample(bits) - 2;
266                         break;
267
268                 case BITSULAW:
269                         generate_ulaw_tables();
270                         inbuffer_8 = in_buffer + channel;
271                         input_frame = channels;
272                         break;
273         }
274
275 // read the data
276 // ================== calculate feathering and add to buffer ================
277         if(feather)
278         {
279 // left feather
280                 switch(bits)
281                 {
282                         case BITSLINEAR8:
283                                 LFEATHER_MACRO1;
284                                 READ_8_MACRO;
285                                 LFEATHER_MACRO2;
286                                 break;
287
288                         case BITSLINEAR16:
289                                 LFEATHER_MACRO1;
290                                 READ_16_MACRO;
291                                 LFEATHER_MACRO2;
292                                 break;
293
294                         case BITSLINEAR24:
295                                 LFEATHER_MACRO1;
296                                 READ_24_MACRO;
297                                 LFEATHER_MACRO2;
298                                 break;
299
300                         case BITSULAW:
301                                 LFEATHER_MACRO1;
302                                 READ_ULAW_MACRO;
303                                 LFEATHER_MACRO2;
304                                 break;
305                 }
306
307
308 // central region
309                 switch(bits)
310                 {
311                         case BITSLINEAR8:
312                                 CENTER_MACRO1;
313                                 READ_8_MACRO;
314                                 CENTER_MACRO2;
315                                 break;
316
317                         case BITSLINEAR16:
318                                 CENTER_MACRO1;
319                                 READ_16_MACRO;
320                                 CENTER_MACRO2;
321                                 break;
322
323                         case BITSLINEAR24:
324                                 CENTER_MACRO1;
325                                 READ_24_MACRO;
326                                 CENTER_MACRO2;
327                                 break;
328
329                         case BITSULAW:
330                                 CENTER_MACRO1;
331                                 READ_ULAW_MACRO;
332                                 CENTER_MACRO2;
333                                 break;
334                 }
335         }
336         else
337 // ====================== don't feather and overwrite buffer =================
338         {
339                 switch(bits)
340                 {
341                         case BITSLINEAR8:
342                                 for(; output_current < input_len;
343                                         output_current++)
344                                 { READ_8_MACRO; out_buffer[output_current] = sample; }
345                                 break;
346
347                         case BITSLINEAR16:
348                                 for(; output_current < input_len;
349                                         output_current++)
350                                 { READ_16_MACRO; out_buffer[output_current] = sample; }
351                                 break;
352
353                         case BITSLINEAR24:
354                                 for(; output_current < input_len;
355                                         output_current++)
356                                 { READ_24_MACRO; out_buffer[output_current] = sample; }
357                                 break;
358
359                         case BITSULAW:
360                                 for(; output_current < input_len;
361                                         output_current++)
362                                 { READ_ULAW_MACRO; out_buffer[output_current] = sample; }
363                                 break;
364                 }
365         }
366
367         return 0;
368 }
369
370 int FileBase::overlay_float_buffer(float *out_buffer, float *in_buffer,
371                 int64_t samples,
372                 float lfeather_len, float lfeather_gain, float lfeather_slope)
373 {
374         int64_t output_current = 0;
375         float sample, current_gain;
376         float feather_current;     // input position for feather
377
378         LFEATHER_MACRO1
379                 sample = in_buffer[output_current];
380         LFEATHER_MACRO2
381
382         CENTER_MACRO1
383                 sample = in_buffer[output_current];
384         CENTER_MACRO2
385
386         return 0;
387 }
388
389
390 int FileBase::get_audio_buffer(char **buffer, int64_t len, int64_t bits, int64_t channels)
391 {
392         int64_t bytes = len * channels * (file->bytes_per_sample(bits));
393         if(*buffer && bytes > prev_bytes)
394         {
395                 delete [] *buffer;
396                 *buffer = 0;
397         }
398         prev_bytes = bytes;
399
400         if(!*buffer) *buffer = new char[bytes];
401         return 0;
402 }
403
404 int FileBase::get_float_buffer(float **buffer, int64_t len)
405 {
406         if(*buffer && len > prev_len)
407         {
408                 delete [] *buffer;
409                 *buffer = 0;
410         }
411         prev_len = len;
412
413         if(!*buffer) *buffer = new float[len];
414         return 0;
415 }