r553: Modern gccs require __attribute__((used)) for variables used only in assembly.
[cinelerra_cv/mob.git] / cinelerra / audioidevice.C
bloba0fbba2b67e4e09f7e97397d5567a0c1959e7d3f
1 #include "audiodevice.h"
2 #include "condition.h"
3 #include "dcoffset.h"
4 #include "bcprogressbox.h"
7 int AudioDevice::set_record_dither(int bits)
9         rec_dither = bits;
10         return 0;
14 int AudioDevice::get_dc_offset(int *output, RecordGUIDCOffsetText **dc_offset_text)
16         dc_offset_thread->calibrate_dc_offset(output, dc_offset_text, get_ichannels());
17         return 0;
20 int AudioDevice::set_dc_offset(int dc_offset, int channel)
22         dc_offset_thread->dc_offset[channel] = dc_offset;
23         return 0;
26 #define GET_PEAK_MACRO \
27                                         input_channel[j] = sample;                          \
28                                         if(sample > max[i]) max[i] = sample;           \
29                                         else if(-sample > max[i]) max[i] = -sample;
31 // ============================ use 2 macros to allow for getting dc_offset
32 // ============= must check for overload after dc_offset because of byte wrapping on save
34 #define GET_8BIT_SAMPLE_MACRO1 \
35 sample = input_buffer[k];      \
36 sample -= dc_offset_value;        \
37 k += input_channels;           \
38 if(sample >= max_sample[i]) { sample = max_sample[i]; if(over_count < 3) over_count++; } \
39 else                           \
40 if(sample <= min_sample[i]) { sample = min_sample[i]; if(over_count < 3) over_count++; } \
41 else                           \
42 if(over_count < 3) over_count = 0; 
44 #define GET_8BIT_SAMPLE_MACRO2 \
45 sample /= 0x7f;                  
49 #define GET_16BIT_SAMPLE_MACRO1                            \
50 sample = input_buffer_16[k];                               \
51 if(dither_scale) { dither_value = rand() % dither_scale; sample -= dither_value; } \
52 sample -= dc_offset_value;                                    \
53 k += input_channels;                                       \
54 if(sample >= max_sample[i]) { sample = max_sample[i]; if(over_count < 3) over_count++; } \
55 else                                                       \
56 if(sample <= min_sample[i]) { sample = min_sample[i]; if(over_count < 3) over_count++; } \
57 else                                                       \
58 if(over_count < 3) over_count = 0;                         \
60 #define GET_16BIT_SAMPLE_MACRO2                            \
61 sample /= 0x7fff;                  
65 #define GET_24BIT_SAMPLE_MACRO1 \
66 sample = (unsigned char)input_buffer[k] | \
67                         (((unsigned char)input_buffer[k + 1]) << 8) | \
68                         (((int)input_buffer[k + 2]) << 16); \
69 sample -= dc_offset_value; \
70 k += input_channels * 3; \
71 if(sample >= max_sample[i]) { sample = max_sample[i]; if(over_count < 3) over_count++; } \
72 else                                                 \
73 if(sample <= min_sample[i]) { sample = min_sample[i]; if(over_count < 3) over_count++; } \
74 else                                                 \
75 if(over_count < 3) over_count = 0; 
77 #define GET_24BIT_SAMPLE_MACRO2       \
78 sample /= 0x7fffff;
82 #define GET_32BIT_SAMPLE_MACRO1 \
83 sample = (unsigned char)input_buffer[k] | \
84                         (((unsigned char)input_buffer[k + 1]) << 8) | \
85                         (((unsigned char)input_buffer[k + 2]) << 16) | \
86                         (((int)input_buffer[k + 3]) << 24); \
87 sample -= dc_offset_value; \
88 k += input_channels * 4; \
89 if(sample >= max_sample[i]) { sample = max_sample[i]; if(over_count < 3) over_count++; } \
90 else \
91 if(sample <= min_sample[i]) { sample = min_sample[i]; if(over_count < 3) over_count++; } \
92 else \
93 if(over_count < 3) over_count = 0; 
95 #define GET_32BIT_SAMPLE_MACRO2       \
96 sample /= 0x7fffffff;
98 int AudioDevice::read_buffer(double **input, 
99         int samples, 
100         int channels, 
101         int *over, 
102         double *max, 
103         int input_offset)
105         int i, j, k, frame, bits;
106         double sample, denominator;
107         double min_sample[MAXCHANNELS], max_sample[MAXCHANNELS];
108         int sample_int;
109         int over_count;
110         int dither_value, dither_scale;
111         int input_channels;
112         int result = 0;
113         double *input_channel;
114         int *dc_offset_total;
115         int dc_offset_value;
117         is_recording = 1;
118         record_timer.update();
120         bits = get_ibits();
121         input_channels = get_ichannels();
122         frame = input_channels * bits / 8;
124         //if(bits == 24) frame = 4;
125         dither_scale = 0;
126         total_samples_read += samples;
128         switch(bits)
129         {
130                 case 8:       
131                         denominator = 0x7f;          
132                         break;
133                 case 16:      
134                         denominator = 0x7fff;        
135                         if(rec_dither == 8)
136                         {
137                                 dither_scale = 255;
138                         }
139                         break;
140                 case 24:      
141                         denominator = 0x7fffff;      
142                         if(rec_dither == 8)
143                         {
144                                 dither_scale = 65535;
145                         }
146                         else 
147                         if (rec_dither == 16)
148                         {
149                                 dither_scale = 255;
150                         }
151                         break;
152                 case 32:      
153                         denominator = 0x7fffffff;      
154                         dither_scale = 0;
155                         break;
156         }
158         if(input_buffer == 0) input_buffer = new char[samples * frame];
160         if(duplex_init && !record_before_play)
161         {
162 // block until playback starts
163                 duplex_lock->lock("AudioDevice::read_buffer");
164                 duplex_init = 0;
165         }
167         result = get_lowlevel_in()->read_buffer(input_buffer, samples * frame);
169 // allow playback to start
170         if(duplex_init && record_before_play)
171         {
172                 duplex_lock->unlock();
173                 duplex_init = 0;
174         }
177         if(result < 0)
178         {
179                 perror("AudioDevice::read_buffer");
180                 sleep(1);
181         }
183         for(i = 0; i < channels && i < get_ichannels(); i++)
184         {
185                 input_channel = &input[i][input_offset];
186                 dc_offset_value = dc_offset_thread->dc_offset[i];
188 // calculate minimum and maximum samples
189                 if(dc_offset_thread->dc_offset[i] <= 0) 
190                 { 
191                         min_sample[i] = -denominator - dc_offset_thread->dc_offset[i]; 
192                         max_sample[i] = denominator; 
193                 }
194                 else 
195                 { 
196                         min_sample[i] = -denominator; 
197                         max_sample[i] = denominator - dc_offset_thread->dc_offset[i]; 
198                 }
199                 max[i] = 0; 
200                 over_count = 0;
202 // device is set to little endian
203                 switch(bits)
204                 {
205                         case 8:
206                                 if(dc_offset_thread->getting_dc_offset)
207                                 {
208                                         dc_offset_total = &(dc_offset_thread->dc_offset_total[i]);
209                                         for(j = 0, k = i; j < samples; j++)
210                                         {
211                                                 GET_8BIT_SAMPLE_MACRO1
212                                                 (*dc_offset_total) += (int)sample;
213                                                 GET_8BIT_SAMPLE_MACRO2
214                                                 GET_PEAK_MACRO
215                                         }
216                                 }
217                                 else
218                                 {
219                                         for(j = 0, k = i; j < samples; j++)
220                                         {
221                                                 GET_8BIT_SAMPLE_MACRO1
222                                                 GET_8BIT_SAMPLE_MACRO2
223                                                 GET_PEAK_MACRO
224                                         }
225                                 }
226                                 break;
227                                 
228                         case 16:
229                                 {
230                                         int16_t *input_buffer_16;
231                                         input_buffer_16 = (int16_t *)input_buffer;
232                                         dc_offset_total = &(dc_offset_thread->dc_offset_total[i]);
233                                         
234                                         if(dc_offset_thread->getting_dc_offset)
235                                         {
236                                                 for(j = 0, k = i; j < samples; j++)
237                                                 {
238                                                         GET_16BIT_SAMPLE_MACRO1
239                                                         (*dc_offset_total) += (int)sample;
240                                                         GET_16BIT_SAMPLE_MACRO2
241                                                         GET_PEAK_MACRO
242                                                 }
243                                         }
244                                         else
245                                         {
246                                                 for(j = 0, k = i; j < samples; j++)
247                                                 {
248                                                         GET_16BIT_SAMPLE_MACRO1
249                                                         GET_16BIT_SAMPLE_MACRO2
250                                                         GET_PEAK_MACRO
251                                                 }
252                                         }
253                                 }
254                                 break;
255                                 
256                         case 24:
257                                 {
258                                         dc_offset_total = &(dc_offset_thread->dc_offset_total[i]);
259                                         
260                                         if(dc_offset_thread->getting_dc_offset)
261                                         {
262                                                 for(j = 0, k = i * 3; j < samples; j++)
263                                                 {
264                                                         GET_24BIT_SAMPLE_MACRO1
265                                                         (*dc_offset_total) += (int)sample;
266                                                         GET_24BIT_SAMPLE_MACRO2
267                                                         GET_PEAK_MACRO
268                                                 }
269                                         }
270                                         else
271                                         {
272                                                 for(j = 0, k = i * 3; j < samples; j++)
273                                                 {
274                                                         GET_24BIT_SAMPLE_MACRO1
275                                                         GET_24BIT_SAMPLE_MACRO2
276                                                         GET_PEAK_MACRO
277                                                 }
278                                         }
279                                 }
280                                 
281                         case 32:
282                                 {
283                                         dc_offset_total = &(dc_offset_thread->dc_offset_total[i]);
284                                         
285                                         if(dc_offset_thread->getting_dc_offset)
286                                         {
287                                                 for(j = 0, k = i * 4; j < samples; j++)
288                                                 {
289                                                         GET_32BIT_SAMPLE_MACRO1
290                                                         (*dc_offset_total) += (int)sample;
291                                                         GET_32BIT_SAMPLE_MACRO2
292                                                         GET_PEAK_MACRO
293                                                 }
294                                         }
295                                         else
296                                         {
297                                                 for(j = 0, k = i * 4; j < samples; j++)
298                                                 {
299                                                         GET_32BIT_SAMPLE_MACRO1
300                                                         GET_32BIT_SAMPLE_MACRO2
301                                                         GET_PEAK_MACRO
302                                                 }
303                                         }
304                                 }
305                                 break;
306                 }
307                 if(over_count >= 3) over[i] = 1; else over[i] = 0;
308         }
310         if(dc_offset_thread->getting_dc_offset) 
311         {
312                 dc_offset_thread->dc_offset_count += samples * channels;
313                 if(dc_offset_thread->progress->update(dc_offset_thread->dc_offset_count))
314                 {
315                         dc_offset_thread->getting_dc_offset = 0;
316                         dc_offset_thread->dc_offset_lock->unlock();
317                 }
318                 else
319                 if(dc_offset_thread->dc_offset_count > 256000)
320                 {
321                         for(i = 0; i < get_ichannels(); i++)
322                         {
323                                 dc_offset_thread->dc_offset[i] = dc_offset_thread->dc_offset_total[i] / dc_offset_thread->dc_offset_count * 2; // don't know why * 2
324                         }
325                         dc_offset_thread->getting_dc_offset = 0;
326                         dc_offset_thread->dc_offset_lock->unlock();
327                 }
328         }
329         return result < 0;