Reported by Fedora team for gcc-13 and Andrew created patch here
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / audioidevice.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 "audiodevice.h"
23 #include "clip.h"
24 #include "playbackconfig.h"
25 #include "recordconfig.h"
26 #include "bcprogressbox.h"
27 #include "bcsignals.h"
28 #include "bctimer.h"
29 #include "condition.h"
30 #include "dcoffset.h"
31 #include "samples.h"
32 #include "mutex.h"
33
34 #include <string.h>
35
36
37 #define STORE(k) \
38   double v = fabs(sample); \
39   if(v > 1) { ++over_count; sample = sample>0 ? 1 : -1; } \
40   if(v > max[ich]) max[ich] = v; \
41   input_channel[k] = sample
42
43 #define GET_8BIT(i) ((double)(buffer[(i)]))
44 #define GET_16BIT(i) ((double)(*(int16_t*)&buffer[(i)]))
45 #define GET_24BIT(i) ((i&1) ? \
46     ((double)((*(uint8_t*)&buffer[i]) | (*(int16_t*)&buffer[i+1] << 8))) : \
47     ((double)((*(uint16_t*)&buffer[i]) | (*(int8_t*)&buffer[i+2] << 16))))
48 #define GET_32BIT(i) ((double)(*(int32_t *)&buffer[(i)]))
49
50 #define GET_8BITS(j,k)  { double sample = gain*GET_8BIT(k);  STORE(j); }
51 #define GET_16BITS(j,k) { double sample = gain*GET_16BIT(k); STORE(j); }
52 #define GET_24BITS(j,k) { double sample = gain*GET_24BIT(k); STORE(j); }
53 #define GET_32BITS(j,k) { double sample = gain*GET_32BIT(k); STORE(j); }
54
55 #define GET_NBIT(sz,n,k,ich) \
56   (GET_##n##BIT(k) + \
57  2*GET_##n##BIT((k)+sz*(1+(ich))) + \
58  2*GET_##n##BIT((k)+sz*(3+(ich))) + \
59    GET_##n##BIT((k)+sz*5))
60
61 #define GET_8BITZ(j,k,ich)  { double sample = gain*GET_NBIT(1,8,k,ich);  STORE(j); }
62 #define GET_16BITZ(j,k,ich) { double sample = gain*GET_NBIT(2,16,k,ich); STORE(j); }
63 #define GET_24BITZ(j,k,ich) { double sample = gain*GET_NBIT(3,24,k,ich); STORE(j); }
64 #define GET_32BITZ(j,k,ich) { double sample = gain*GET_NBIT(4,32,k,ich); STORE(j); }
65
66 int AudioDevice::read_buffer(Samples **data, int channels,
67         int samples, int *over, double *max, int input_offset)
68 {
69         for( int i=0; i<channels; ++i ) {
70                 over[i] = 0;  max[i] = 0.;
71         }
72         int input_channels = get_ichannels();
73         int map51_2 = in51_2 && channels == 2 && input_channels == 6;
74         int bits = get_ibits();
75         int frame_size = input_channels * bits / 8;
76         int fragment_size = samples * frame_size;
77         int result = !fragment_size ? 1 : 0;
78         double gain = bits ? rec_gain / ((1<<(bits-1))-1) : 0.;
79         if( map51_2 ) gain *= 0.2;
80
81         while( !result && fragment_size > 0 ) {
82                 if( (result=read_inactive()) ) break;
83                 polling_lock->lock("AudioDevice::read_buffer");
84                 if( (result=read_inactive()) ) break;
85                 if( !input_buffer_count ) continue;
86
87                 input_buffer_t *ibfr = &input[input_buffer_out];
88                 if( input_buffer_offset >= ibfr->size ) {
89                         // guarentee the buffer has finished loading
90                         if( input_buffer_in == input_buffer_out ) continue;
91                         buffer_lock->lock("AudioDevice::read_buffer 1");
92                         --input_buffer_count;
93                         buffer_lock->unlock();
94                         if( ++input_buffer_out >= TOTAL_AUDIO_BUFFERS )
95                                 input_buffer_out = 0;
96                         ibfr = &input[input_buffer_out];
97                         input_buffer_offset = 0;
98                 }
99                 char *buffer = ibfr->buffer + input_buffer_offset;
100                 int ibfr_remaining = ibfr->size - input_buffer_offset;
101
102                 int xfr_size = MIN(fragment_size, ibfr_remaining);
103                 int xfr_samples = xfr_size / frame_size;
104
105                 for( int ich=0; ich<channels; ++ich ) {
106                         int over_count = 0;
107                         double *input_channel = data[ich]->get_data() + input_offset;
108                         if( map51_2 ) {
109                                 int k = 0;
110                                 switch( bits ) {
111                                 case 8: for(int j=0; j<xfr_samples; ++j,k+=frame_size)
112                                                 GET_8BITZ(j,k,ich)
113                                         break;
114                                 case 16: for(int j=0; j<xfr_samples; ++j,k+=frame_size)
115                                                 GET_16BITZ(j,k,ich)
116                                         break;
117                                 case 24: for(int j=0; j<xfr_samples; ++j,k+=frame_size)
118                                                 GET_24BITZ(j,k,ich)
119                                         break;
120                                 case 32: for(int j=0; j<xfr_samples; ++j,k+=frame_size)
121                                                 GET_32BITZ(j,k,ich)
122                                         break;
123                                 }
124                         }
125                         else {
126                                 int k = (ich % input_channels) * bits / 8;
127                                 switch( bits) {
128                                 case 8: for(int j=0; j<xfr_samples; ++j,k+=frame_size)
129                                                 GET_8BITS(j,k)
130                                         break;
131                                 case 16: for(int j=0; j<xfr_samples; ++j,k+=frame_size)
132                                                 GET_16BITS(j,k)
133                                         break;
134                                 case 24: for(int j=0; j<xfr_samples; ++j,k+=frame_size)
135                                                 GET_24BITS(j,k)
136                                         break;
137                                 case 32: for(int j=0; j<xfr_samples; ++j,k+=frame_size)
138                                                 GET_32BITS(j,k)
139                                         break;
140                                 }
141                         }
142                         over[ich] = over_count >= 3 ? 1 : 0;
143                 }
144
145                 if( monitoring ) {
146                         int sample_offset = input_buffer_offset / frame_size;
147                         double buffer_time = ibfr->timestamp +
148                                 (double) sample_offset / in_samplerate;
149                         monitor_buffer(data, channels,
150                                 xfr_samples, input_offset, buffer_time);
151                 }
152
153                 input_offset += xfr_samples;
154                 input_buffer_offset += xfr_size;
155                 fragment_size -= xfr_size;
156         }
157
158         if( !result ) {
159                 total_samples_read += samples;
160                 record_timer->update();
161         }
162
163         return result;
164 }
165
166
167 void AudioDevice::run_input()
168 {
169         while( is_recording ) {
170 // Get available input buffer
171                 input_buffer_t *ibfr = &input[input_buffer_in];
172                 char *data = &ibfr->buffer[ibfr->size];
173                 if( !ibfr->size || ibfr->timestamp < 0. )
174                         ibfr->timestamp = lowlevel_in->device_timestamp();
175                 int frame_size = get_ichannels() * get_ibits() / 8;
176                 int fragment_size = in_samples * frame_size;
177                 int result = lowlevel_in->read_buffer(data, fragment_size);
178                 if( !result ) {
179                         total_samples_input += in_samples;
180                         buffer_lock->lock("AudioDevice::run_input 2");
181                         if( !ibfr->size )
182                                 ++input_buffer_count;
183                         ibfr->size += fragment_size;
184
185                         if( ibfr->size > INPUT_BUFFER_BYTES-fragment_size ) {
186 #if 0
187 // jam job dvb file testing, enable code
188 while( is_recording ) {
189         if( input_buffer_count < TOTAL_AUDIO_BUFFERS ) break;
190         buffer_lock->unlock();
191         Timer::delay(250);
192         buffer_lock->lock("AudioDevice::run_input 3");
193 }
194 #endif
195                                 if( input_buffer_count < TOTAL_AUDIO_BUFFERS ) {
196                                         if( ++input_buffer_in >= TOTAL_AUDIO_BUFFERS )
197                                                 input_buffer_in = 0;
198                                 }
199                                 else {
200                                         --input_buffer_count;
201                                         printf("AudioDevice::run_input: buffer overflow\n");
202                                         result = 1;
203                                 }
204                                 ibfr = &input[input_buffer_in];
205                                 ibfr->size = 0;
206                                 ibfr->timestamp = -1.;
207                         }
208                         buffer_lock->unlock();
209                         polling_lock->unlock();
210                 }
211                 if( result ) {
212                         perror("AudioDevice::run_input");
213                         usleep(250000);
214                 }
215         }
216 }
217
218 void AudioDevice::end_input()
219 {
220         is_recording = 0;
221         polling_lock->unlock();
222         buffer_lock->reset();
223 }
224
225 int AudioDevice::reset_input()
226 {
227         for( int i=0; i<TOTAL_AUDIO_BUFFERS; ++i ) {
228                 input_buffer_t *ibfr = &input[i];
229                 if( ibfr->buffer ) {
230                         delete [] ibfr->buffer;
231                         ibfr->buffer = 0;
232                 }
233                 ibfr->size = 0;
234                 ibfr->timestamp = -1.;
235         }
236         input_buffer_count = 0;
237         input_buffer_in = 0;
238         input_buffer_out = 0;
239         input_buffer_offset = 0;
240         is_recording = 0;
241         recording_interrupted = 0;
242         buffer_lock->reset();
243         polling_lock->reset();
244         monitoring = 0;
245         monitor_open = 0;
246         return 0;
247 }
248
249 void AudioDevice::start_recording()
250 {
251         reset_input();
252         is_recording = 1;
253         for( int i=0; i<TOTAL_AUDIO_BUFFERS; ++i ) {
254                 input[i].buffer = new char[INPUT_BUFFER_BYTES];
255                 input[i].size = 0;
256         }
257         record_timer->update();
258         audio_in = new AudioThread(this,
259                 &AudioDevice::run_input,&AudioDevice::end_input);
260         audio_in->set_realtime(get_irealtime());
261         audio_in->startup();
262 }
263
264 void AudioDevice::interrupt_recording()
265 {
266         recording_interrupted = 1;
267         polling_lock->unlock();
268 }
269
270 void AudioDevice::resume_recording()
271 {
272         recording_interrupted = 0;
273 }
274
275 void AudioDevice::set_rec_gain(double gain)
276 {
277         rec_gain = gain * in_config->rec_gain;
278 }
279
280 void AudioDevice::set_monitoring(int mode)
281 {
282         interrupt_playback();
283         monitoring = mode;
284         if( mode )
285                 start_playback();
286 }
287
288 void AudioDevice::monitor_buffer(Samples **data, int channels,
289          int samples, int ioffset, double bfr_time)
290 {
291         if( !monitoring || !out_config ) return;
292         if( !in_samplerate || !in_samples || !in_bits || !in_channels ) return;
293         int ochannels = out_config->map51_2 && channels == 6 ? 2 : channels;
294         if( !monitor_open
295                 /* follow input config, except for channels */
296                  || in_samplerate != out_samplerate ||
297                  in_bits != out_bits || ochannels != out_channels ||
298                  in_samples != out_samples || in_realtime != out_realtime ) {
299                 interrupt_playback();
300                 if( lowlevel_out ) {
301                         lowlevel_out->close_all();
302                         delete lowlevel_out;
303                         lowlevel_out = 0;
304                 }
305                 int ret = open_output(out_config,
306                         in_samplerate, in_samples, channels, in_realtime );
307                 monitor_open = !ret ? 1 : 0;
308                 if( monitor_open ) {
309                         start_playback();
310                         monitoring = 1;
311                 }
312         }
313         if( is_monitoring() ) {
314                 double *offset_data[channels];
315                 for( int i=0; i<channels; ++i )
316                         offset_data[i] = data[i]->get_data() + ioffset;
317                 write_buffer(offset_data, channels, samples, bfr_time);
318         }
319 }
320
321