r954: Improve icons of the liveaudio and livevideo effects.
[cinelerra_cv.git] / cinelerra / audioidevice.C
blob2bf4a10b6b0787c21a27e3f62bb830cdaf2199ca
1 #include "audiodevice.h"
2 #include "bcprogressbox.h"
3 #include "bcsignals.h"
4 #include "bctimer.h"
5 #include "condition.h"
6 #include "dcoffset.h"
7 #include "mutex.h"
9 #include <string.h>
12 #define GET_PEAK_MACRO \
13                                         input_channel[j] = sample;                          \
14                                         if(sample > max[i]) max[i] = sample;           \
15                                         else if(-sample > max[i]) max[i] = -sample;
18 #define GET_8BIT_SAMPLE_MACRO1 \
19 sample = input_buffer[k];      \
20 k += input_channels;           \
21 if(sample >= max_sample[i]) { sample = max_sample[i]; if(over_count < 3) over_count++; } \
22 else                           \
23 if(sample <= min_sample[i]) { sample = min_sample[i]; if(over_count < 3) over_count++; } \
24 else                           \
25 if(over_count < 3) over_count = 0; 
27 #define GET_8BIT_SAMPLE_MACRO2 \
28 sample /= 0x7f;                  
32 #define GET_16BIT_SAMPLE_MACRO1                            \
33 sample = input_buffer_16[k];                               \
34 k += input_channels;                                       \
35 if(sample >= max_sample[i]) { sample = max_sample[i]; if(over_count < 3) over_count++; } \
36 else                                                       \
37 if(sample <= min_sample[i]) { sample = min_sample[i]; if(over_count < 3) over_count++; } \
38 else                                                       \
39 if(over_count < 3) over_count = 0;                         \
41 #define GET_16BIT_SAMPLE_MACRO2                            \
42 sample /= 0x7fff;                  
46 #define GET_24BIT_SAMPLE_MACRO1 \
47 sample = (unsigned char)input_buffer[k] | \
48                         (((unsigned char)input_buffer[k + 1]) << 8) | \
49                         (((int)input_buffer[k + 2]) << 16); \
50 k += input_channels * 3; \
51 if(sample >= max_sample[i]) { sample = max_sample[i]; if(over_count < 3) over_count++; } \
52 else                                                 \
53 if(sample <= min_sample[i]) { sample = min_sample[i]; if(over_count < 3) over_count++; } \
54 else                                                 \
55 if(over_count < 3) over_count = 0; 
57 #define GET_24BIT_SAMPLE_MACRO2       \
58 sample /= 0x7fffff;
62 #define GET_32BIT_SAMPLE_MACRO1 \
63 sample = (unsigned char)input_buffer[k] | \
64                         (((unsigned char)input_buffer[k + 1]) << 8) | \
65                         (((unsigned char)input_buffer[k + 2]) << 16) | \
66                         (((int)input_buffer[k + 3]) << 24); \
67 k += input_channels * 4; \
68 if(sample >= max_sample[i]) { sample = max_sample[i]; if(over_count < 3) over_count++; } \
69 else \
70 if(sample <= min_sample[i]) { sample = min_sample[i]; if(over_count < 3) over_count++; } \
71 else \
72 if(over_count < 3) over_count = 0; 
74 #define GET_32BIT_SAMPLE_MACRO2       \
75 sample /= 0x7fffffff;
77 int AudioDevice::read_buffer(double **input, 
78         int samples, 
79         int *over, 
80         double *max, 
81         int input_offset)
83         int i, j, k, frame, bits;
84         double sample, denominator;
85         double min_sample[MAXCHANNELS], max_sample[MAXCHANNELS];
86         int sample_int;
87         int over_count;
88         int input_channels;
89         int result = 0;
90         double *input_channel;
94         record_timer->update();
96         bits = get_ibits();
97         input_channels = get_ichannels();
98         frame = input_channels * bits / 8;
100         total_samples_read += samples;
102         switch(bits)
103         {
104                 case 8:       
105                         denominator = 0x7f;          
106                         break;
107                 case 16:      
108                         denominator = 0x7fff;        
109                         break;
110                 case 24:      
111                         denominator = 0x7fffff;      
112                         break;
113                 case 32:      
114                         denominator = 0x7fffffff;      
115                         break;
116         }
119         for(i = 0; i < get_ichannels(); i++)
120         {
121                 min_sample[i] = -denominator; 
122                 max_sample[i] = denominator; 
123                 max[i] = 0; 
124                 over_count = 0;
125         }
129         int got_it = 0;
130         int fragment_size = samples * frame;
131         while(fragment_size > 0 && is_recording)
132         {
134 // Get next buffer
135                 polling_lock->lock("AudioDevice::read_buffer");
138                 int output_buffer_num = thread_buffer_num - 1;
139                 if(output_buffer_num < 0) output_buffer_num = TOTAL_BUFFERS - 1;
142 // Test previously written buffer for data
143                 char *input_buffer = this->input_buffer[output_buffer_num];
145                 int *input_buffer_size = &this->buffer_size[output_buffer_num];
148 // No data.  Test current buffer for data
149                 if(!*input_buffer_size)
150                 {
151                         read_waiting = 1;
152                         buffer_lock->lock("AudioDevice::read_buffer 1");
153                         read_waiting = 0;
154                         input_buffer = this->input_buffer[thread_buffer_num];
156                         input_buffer_size = &this->buffer_size[thread_buffer_num];
159 // Data in current buffer.  Advance thread buffer.
160                         if(*input_buffer_size >= fragment_size)
161                         {
162                                 thread_buffer_num++;
163                                 if(thread_buffer_num >= TOTAL_BUFFERS)
164                                         thread_buffer_num = 0;
165                         }
166                         else
167 // Not enough data.
168                         {
169                                 input_buffer = 0;
170                                 input_buffer_size = 0;
171                         }
173                         buffer_lock->unlock();
175                 }
178 // Transfer data
179                 if(input_buffer_size && *input_buffer_size)
180                 {
181                         int subfragment_size = fragment_size;
182                         if(subfragment_size > *input_buffer_size)
183                                 subfragment_size = *input_buffer_size;
184                         int subfragment_samples = subfragment_size / frame;
187                         for(i = 0; i < get_ichannels(); i++)
188                         {
189                                 input_channel = &input[i][input_offset];
191 // device is set to little endian
192                                 switch(bits)
193                                 {
194                                         case 8:
195                                                 for(j = 0, k = i; j < subfragment_samples; j++)
196                                                 {
197                                                         GET_8BIT_SAMPLE_MACRO1
198                                                         GET_8BIT_SAMPLE_MACRO2
199                                                         GET_PEAK_MACRO
200                                                 }
201                                                 break;
203                                         case 16:
204                                                 {
205                                                         int16_t *input_buffer_16;
206                                                         input_buffer_16 = (int16_t *)input_buffer;
208                                                         {
209                                                                 for(j = 0, k = i; j < subfragment_samples; j++)
210                                                                 {
211                                                                         GET_16BIT_SAMPLE_MACRO1
212                                                                         GET_16BIT_SAMPLE_MACRO2
213                                                                         GET_PEAK_MACRO
214                                                                 }
215                                                         }
216                                                 }
217                                                 break;
219                                         case 24:
220                                                 for(j = 0, k = i * 3; j < subfragment_samples; j++)
221                                                 {
222                                                         GET_24BIT_SAMPLE_MACRO1
223                                                         GET_24BIT_SAMPLE_MACRO2
224                                                         GET_PEAK_MACRO
225                                                 }
227                                         case 32:
228                                                 for(j = 0, k = i * 4; j < subfragment_samples; j++)
229                                                 {
230                                                         GET_32BIT_SAMPLE_MACRO1
231                                                         GET_32BIT_SAMPLE_MACRO2
232                                                         GET_PEAK_MACRO
233                                                 }
234                                                 break;
235                                 }
237                                 if(over_count >= 3) 
238                                         over[i] = 1; 
239                                 else 
240                                         over[i] = 0;
241                         }
246                         input_offset += subfragment_size / frame;
248 // Shift input buffer
249                         if(*input_buffer_size > subfragment_size)
250                         {
251                                 memcpy(input_buffer, 
252                                         input_buffer + subfragment_size, 
253                                         *input_buffer_size - subfragment_size);
254                         }
256                         fragment_size -= subfragment_size;
257                         *input_buffer_size -= subfragment_size;
258                 }
259         }
267         return result < 0;
271 void AudioDevice::run_input()
273         int frame = get_ichannels() * get_ibits() / 8;
274         int fragment_size = in_samples * frame;
276         while(is_recording)
277         {
278                 if(read_waiting) usleep(1);
279                 buffer_lock->lock("AudioDevice::run_input 1");
281 // Get available input buffer
282                 char *input_buffer = this->input_buffer[thread_buffer_num];
283                 int *input_buffer_size = &this->buffer_size[thread_buffer_num];
285                 if(*input_buffer_size + fragment_size > INPUT_BUFFER_BYTES)
286                 {
287                         *input_buffer_size = INPUT_BUFFER_BYTES - fragment_size;
288                         *input_buffer_size -= *input_buffer_size % fragment_size;
289                         printf("AudioDevice::run_input: buffer overflow\n");
290                 }
292                 int result = get_lowlevel_in()->read_buffer(
293                         input_buffer + *input_buffer_size, 
294                         fragment_size);
296                 if(result < 0)
297                 {
298                         perror("AudioDevice::run_input");
299                         sleep(1);
300                 }
301                 else
302                 {
303                         *input_buffer_size += fragment_size;
305                 }
306                 buffer_lock->unlock();
307                 polling_lock->unlock();
308         }
311 void AudioDevice::start_recording()
313         is_recording = 1;
314         interrupt = 0;
315         thread_buffer_num = 0;
317         for(int i = 0; i < TOTAL_BUFFERS; i++)
318         {
319                 input_buffer[i] = new char[INPUT_BUFFER_BYTES];
320         }
321         record_timer->update();
323         Thread::set_realtime(get_irealtime());
324         Thread::start();