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