00001 #include "audiodevice.h"
00002 #include "condition.h"
00003 #include "dcoffset.h"
00004 #include "bcprogressbox.h"
00005
00006
00007 int AudioDevice::set_record_dither(int bits)
00008 {
00009 rec_dither = bits;
00010 return 0;
00011 }
00012
00013
00014 int AudioDevice::get_dc_offset(int *output, RecordGUIDCOffsetText **dc_offset_text)
00015 {
00016 dc_offset_thread->calibrate_dc_offset(output, dc_offset_text, get_ichannels());
00017 return 0;
00018 }
00019
00020 int AudioDevice::set_dc_offset(int dc_offset, int channel)
00021 {
00022 dc_offset_thread->dc_offset[channel] = dc_offset;
00023 return 0;
00024 }
00025
00026 #define GET_PEAK_MACRO \
00027 input_channel[j] = sample; \
00028 if(sample > max[i]) max[i] = sample; \
00029 else if(-sample > max[i]) max[i] = -sample;
00030
00031
00032
00033
00034 #define GET_8BIT_SAMPLE_MACRO1 \
00035 sample = input_buffer[k]; \
00036 sample -= dc_offset_value; \
00037 k += input_channels; \
00038 if(sample >= max_sample[i]) { sample = max_sample[i]; if(over_count < 3) over_count++; } \
00039 else \
00040 if(sample <= min_sample[i]) { sample = min_sample[i]; if(over_count < 3) over_count++; } \
00041 else \
00042 if(over_count < 3) over_count = 0;
00043
00044 #define GET_8BIT_SAMPLE_MACRO2 \
00045 sample /= 0x7f;
00046
00047
00048
00049 #define GET_16BIT_SAMPLE_MACRO1 \
00050 sample = input_buffer_16[k]; \
00051 if(dither_scale) { dither_value = rand() % dither_scale; sample -= dither_value; } \
00052 sample -= dc_offset_value; \
00053 k += input_channels; \
00054 if(sample >= max_sample[i]) { sample = max_sample[i]; if(over_count < 3) over_count++; } \
00055 else \
00056 if(sample <= min_sample[i]) { sample = min_sample[i]; if(over_count < 3) over_count++; } \
00057 else \
00058 if(over_count < 3) over_count = 0; \
00059
00060 #define GET_16BIT_SAMPLE_MACRO2 \
00061 sample /= 0x7fff;
00062
00063
00064
00065 #define GET_24BIT_SAMPLE_MACRO1 \
00066 sample = (unsigned char)input_buffer[k] | \
00067 (((unsigned char)input_buffer[k + 1]) << 8) | \
00068 (((int)input_buffer[k + 2]) << 16); \
00069 sample -= dc_offset_value; \
00070 k += input_channels * 3; \
00071 if(sample >= max_sample[i]) { sample = max_sample[i]; if(over_count < 3) over_count++; } \
00072 else \
00073 if(sample <= min_sample[i]) { sample = min_sample[i]; if(over_count < 3) over_count++; } \
00074 else \
00075 if(over_count < 3) over_count = 0;
00076
00077 #define GET_24BIT_SAMPLE_MACRO2 \
00078 sample /= 0x7fffff;
00079
00080
00081
00082 #define GET_32BIT_SAMPLE_MACRO1 \
00083 sample = (unsigned char)input_buffer[k] | \
00084 (((unsigned char)input_buffer[k + 1]) << 8) | \
00085 (((unsigned char)input_buffer[k + 2]) << 16) | \
00086 (((int)input_buffer[k + 3]) << 24); \
00087 sample -= dc_offset_value; \
00088 k += input_channels * 4; \
00089 if(sample >= max_sample[i]) { sample = max_sample[i]; if(over_count < 3) over_count++; } \
00090 else \
00091 if(sample <= min_sample[i]) { sample = min_sample[i]; if(over_count < 3) over_count++; } \
00092 else \
00093 if(over_count < 3) over_count = 0;
00094
00095 #define GET_32BIT_SAMPLE_MACRO2 \
00096 sample /= 0x7fffffff;
00097
00098 int AudioDevice::read_buffer(double **input,
00099 int samples,
00100 int channels,
00101 int *over,
00102 double *max,
00103 int input_offset)
00104 {
00105 int i, j, k, frame, bits;
00106 double sample, denominator;
00107 double min_sample[MAXCHANNELS], max_sample[MAXCHANNELS];
00108 int sample_int;
00109 int over_count;
00110 int dither_value, dither_scale;
00111 int input_channels;
00112 int result = 0;
00113 double *input_channel;
00114 int *dc_offset_total;
00115 int dc_offset_value;
00116
00117 is_recording = 1;
00118 record_timer.update();
00119
00120 bits = get_ibits();
00121 input_channels = get_ichannels();
00122 frame = input_channels * bits / 8;
00123
00124 dither_scale = 0;
00125 total_samples_read += samples;
00126
00127 switch(bits)
00128 {
00129 case 8:
00130 denominator = 0x7f;
00131 break;
00132 case 16:
00133 denominator = 0x7fff;
00134 if(rec_dither == 8)
00135 {
00136 dither_scale = 255;
00137 }
00138 break;
00139 case 24:
00140 denominator = 0x7fffff;
00141 if(rec_dither == 8)
00142 {
00143 dither_scale = 65535;
00144 }
00145 else
00146 if (rec_dither == 16)
00147 {
00148 dither_scale = 255;
00149 }
00150 break;
00151 case 32:
00152 denominator = 0x7fffffff;
00153 dither_scale = 0;
00154 break;
00155 }
00156
00157 if(input_buffer == 0) input_buffer = new char[samples * frame];
00158
00159 if(duplex_init && !record_before_play)
00160 {
00161
00162 duplex_lock->lock("AudioDevice::read_buffer");
00163 duplex_init = 0;
00164 }
00165
00166 result = get_lowlevel_in()->read_buffer(input_buffer, samples * frame);
00167
00168
00169 if(duplex_init && record_before_play)
00170 {
00171 duplex_lock->unlock();
00172 duplex_init = 0;
00173 }
00174
00175
00176 if(result < 0)
00177 {
00178 perror("AudioDevice::read_buffer");
00179 sleep(1);
00180 }
00181
00182 for(i = 0; i < channels && i < get_ichannels(); i++)
00183 {
00184 input_channel = &input[i][input_offset];
00185 dc_offset_value = dc_offset_thread->dc_offset[i];
00186
00187
00188 if(dc_offset_thread->dc_offset[i] <= 0)
00189 {
00190 min_sample[i] = -denominator - dc_offset_thread->dc_offset[i];
00191 max_sample[i] = denominator;
00192 }
00193 else
00194 {
00195 min_sample[i] = -denominator;
00196 max_sample[i] = denominator - dc_offset_thread->dc_offset[i];
00197 }
00198 max[i] = 0;
00199 over_count = 0;
00200
00201
00202 switch(bits)
00203 {
00204 case 8:
00205 if(dc_offset_thread->getting_dc_offset)
00206 {
00207 dc_offset_total = &(dc_offset_thread->dc_offset_total[i]);
00208 for(j = 0, k = i; j < samples; j++)
00209 {
00210 GET_8BIT_SAMPLE_MACRO1
00211 (*dc_offset_total) += (int)sample;
00212 GET_8BIT_SAMPLE_MACRO2
00213 GET_PEAK_MACRO
00214 }
00215 }
00216 else
00217 {
00218 for(j = 0, k = i; j < samples; j++)
00219 {
00220 GET_8BIT_SAMPLE_MACRO1
00221 GET_8BIT_SAMPLE_MACRO2
00222 GET_PEAK_MACRO
00223 }
00224 }
00225 break;
00226
00227 case 16:
00228 {
00229 int16_t *input_buffer_16;
00230 input_buffer_16 = (int16_t *)input_buffer;
00231 dc_offset_total = &(dc_offset_thread->dc_offset_total[i]);
00232
00233 if(dc_offset_thread->getting_dc_offset)
00234 {
00235 for(j = 0, k = i; j < samples; j++)
00236 {
00237 GET_16BIT_SAMPLE_MACRO1
00238 (*dc_offset_total) += (int)sample;
00239 GET_16BIT_SAMPLE_MACRO2
00240 GET_PEAK_MACRO
00241 }
00242 }
00243 else
00244 {
00245 for(j = 0, k = i; j < samples; j++)
00246 {
00247 GET_16BIT_SAMPLE_MACRO1
00248 GET_16BIT_SAMPLE_MACRO2
00249 GET_PEAK_MACRO
00250 }
00251 }
00252 }
00253 break;
00254
00255 case 24:
00256 {
00257 dc_offset_total = &(dc_offset_thread->dc_offset_total[i]);
00258
00259 if(dc_offset_thread->getting_dc_offset)
00260 {
00261 for(j = 0, k = i * 3; j < samples; j++)
00262 {
00263 GET_24BIT_SAMPLE_MACRO1
00264 (*dc_offset_total) += (int)sample;
00265 GET_24BIT_SAMPLE_MACRO2
00266 GET_PEAK_MACRO
00267 }
00268 }
00269 else
00270 {
00271 for(j = 0, k = i * 3; j < samples; j++)
00272 {
00273 GET_24BIT_SAMPLE_MACRO1
00274 GET_24BIT_SAMPLE_MACRO2
00275 GET_PEAK_MACRO
00276 }
00277 }
00278 }
00279
00280 case 32:
00281 {
00282 dc_offset_total = &(dc_offset_thread->dc_offset_total[i]);
00283
00284 if(dc_offset_thread->getting_dc_offset)
00285 {
00286 for(j = 0, k = i * 4; j < samples; j++)
00287 {
00288 GET_32BIT_SAMPLE_MACRO1
00289 (*dc_offset_total) += (int)sample;
00290 GET_32BIT_SAMPLE_MACRO2
00291 GET_PEAK_MACRO
00292 }
00293 }
00294 else
00295 {
00296 for(j = 0, k = i * 4; j < samples; j++)
00297 {
00298 GET_32BIT_SAMPLE_MACRO1
00299 GET_32BIT_SAMPLE_MACRO2
00300 GET_PEAK_MACRO
00301 }
00302 }
00303 }
00304 break;
00305 }
00306 if(over_count >= 3) over[i] = 1; else over[i] = 0;
00307 }
00308
00309 if(dc_offset_thread->getting_dc_offset)
00310 {
00311 dc_offset_thread->dc_offset_count += samples * channels;
00312 if(dc_offset_thread->progress->update(dc_offset_thread->dc_offset_count, 1))
00313 {
00314 dc_offset_thread->getting_dc_offset = 0;
00315 dc_offset_thread->dc_offset_lock->unlock();
00316 }
00317 else
00318 if(dc_offset_thread->dc_offset_count > 256000)
00319 {
00320 for(i = 0; i < get_ichannels(); i++)
00321 {
00322 dc_offset_thread->dc_offset[i] = dc_offset_thread->dc_offset_total[i] / dc_offset_thread->dc_offset_count * 2;
00323 }
00324 dc_offset_thread->getting_dc_offset = 0;
00325 dc_offset_thread->dc_offset_lock->unlock();
00326 }
00327 }
00328 return result < 0;
00329 }