00001 #include "audiodevice.h"
00002 #include "bctimer.h"
00003 #include "clip.h"
00004 #include "condition.h"
00005 #include "mutex.h"
00006 #include "playbackconfig.h"
00007 #include "sema.h"
00008
00009 #include <string.h>
00010
00011 int AudioDevice::write_buffer(double **output, int samples)
00012 {
00013
00014 if(interrupt) return 0;
00015 arm_buffer(arm_buffer_num, output, samples);
00016 arm_buffer_num++;
00017 if(arm_buffer_num >= TOTAL_BUFFERS) arm_buffer_num = 0;
00018 return 0;
00019 }
00020
00021 int AudioDevice::set_last_buffer()
00022 {
00023 arm_lock[arm_buffer_num]->lock("AudioDevice::set_last_buffer");
00024 last_buffer[arm_buffer_num] = 1;
00025 play_lock[arm_buffer_num]->unlock();
00026
00027
00028 arm_buffer_num++;
00029 if(arm_buffer_num >= TOTAL_BUFFERS) arm_buffer_num = 0;
00030 return 0;
00031 }
00032
00033
00034
00035
00036 int AudioDevice::arm_buffer(int buffer_num,
00037 double **output,
00038 int samples)
00039 {
00040 int bits;
00041 int new_size;
00042
00043 int i, j;
00044 int input_offset;
00045 int output_offset;
00046 int output_advance;
00047 int channel, last_input_channel;
00048 double sample;
00049 int int_sample, int_sample2;
00050 int dither_value;
00051 int frame;
00052 int device_channels = get_ochannels();
00053 char *buffer_num_buffer;
00054 double *buffer_in_channel;
00055
00056 bits = get_obits();
00057
00058 frame = device_channels * (bits / 8);
00059
00060 new_size = frame * samples;
00061
00062 if(interrupt) return 1;
00063
00064
00065 arm_lock[buffer_num]->lock("AudioDevice::arm_buffer");
00066 if(interrupt) return 1;
00067
00068 if(new_size > buffer_size[buffer_num])
00069 {
00070 delete [] output_buffer[buffer_num];
00071 output_buffer[buffer_num] = new char[new_size];
00072 buffer_size[buffer_num] = new_size;
00073 }
00074
00075 buffer_size[buffer_num] = new_size;
00076
00077 buffer_num_buffer = output_buffer[buffer_num];
00078 bzero(buffer_num_buffer, new_size);
00079
00080 last_input_channel = device_channels - 1;
00081
00082
00083
00084 for(channel = 0; channel < device_channels; channel++)
00085 {
00086 buffer_in_channel = output[channel];
00087 switch(bits)
00088 {
00089 case 8:
00090 output_advance = device_channels;
00091 if(play_dither)
00092 {
00093 for(output_offset = channel, input_offset = 0; input_offset < samples; output_offset += output_advance, input_offset++)
00094 {
00095 sample = buffer_in_channel[input_offset];
00096 CLAMP(sample, -1, 1);
00097 sample *= 0x7fff;
00098 int_sample = (int)sample;
00099 dither_value = rand() % 255;
00100 int_sample -= dither_value;
00101 int_sample /= 0x100;
00102 buffer_num_buffer[output_offset] = int_sample;
00103 }
00104 }
00105 else
00106 {
00107 for(output_offset = channel, input_offset = 0; input_offset < samples; output_offset += output_advance, input_offset++)
00108 {
00109 sample = buffer_in_channel[input_offset];
00110 CLAMP(sample, -1, 1);
00111 sample *= 0x7f;
00112 int_sample = (int)sample;
00113 buffer_num_buffer[output_offset] = int_sample;
00114 }
00115 }
00116 break;
00117
00118 case 16:
00119 output_advance = device_channels * 2 - 1;
00120 if(play_dither)
00121 {
00122 for(output_offset = channel * 2, input_offset = 0;
00123 input_offset < samples;
00124 output_offset += output_advance, input_offset++)
00125 {
00126 sample = buffer_in_channel[input_offset];
00127 CLAMP(sample, -1, 1);
00128 sample *= 0x7fffff;
00129 int_sample = (int)sample;
00130 dither_value = rand() % 255;
00131 int_sample -= dither_value;
00132 int_sample /= 0x100;
00133 buffer_num_buffer[output_offset] = int_sample;
00134 }
00135 }
00136 else
00137 {
00138 for(output_offset = channel * 2, input_offset = 0;
00139 input_offset < samples;
00140 output_offset += output_advance, input_offset++)
00141 {
00142 sample = buffer_in_channel[input_offset];
00143 CLAMP(sample, -1, 1);
00144 sample *= 0x7fff;
00145 int_sample = (int)sample;
00146 buffer_num_buffer[output_offset++] = (int_sample & 0xff);
00147 buffer_num_buffer[output_offset] = (int_sample & 0xff00) >> 8;
00148 }
00149 }
00150 break;
00151
00152 case 24:
00153 output_advance = (device_channels - 1) * 3;
00154 for(output_offset = channel * 3, input_offset = 0;
00155 input_offset < samples;
00156 output_offset += output_advance, input_offset++)
00157 {
00158 sample = buffer_in_channel[input_offset];
00159 CLAMP(sample, -1, 1);
00160 sample *= 0x7fffff;
00161 int_sample = (int)sample;
00162 buffer_num_buffer[output_offset++] = (int_sample & 0xff);
00163 buffer_num_buffer[output_offset++] = (int_sample & 0xff00) >> 8;
00164 buffer_num_buffer[output_offset++] = (int_sample & 0xff0000) >> 16;
00165 }
00166 break;
00167
00168 case 32:
00169 output_advance = (device_channels - 1) * 4;
00170 for(output_offset = channel * 4, input_offset = 0;
00171 input_offset < samples;
00172 output_offset += output_advance, input_offset++)
00173 {
00174 sample = buffer_in_channel[input_offset];
00175 CLAMP(sample, -1, 1);
00176 sample *= 0x7fffffff;
00177 int_sample = (int)sample;
00178 buffer_num_buffer[output_offset++] = (int_sample & 0xff);
00179 buffer_num_buffer[output_offset++] = (int_sample & 0xff00) >> 8;
00180 buffer_num_buffer[output_offset++] = (int_sample & 0xff0000) >> 16;
00181 buffer_num_buffer[output_offset++] = (int_sample & 0xff000000) >> 24;
00182 }
00183 break;
00184 }
00185 }
00186
00187
00188 play_lock[buffer_num]->unlock();
00189 return 0;
00190 }
00191
00192 int AudioDevice::reset_output()
00193 {
00194 for(int i = 0; i < TOTAL_BUFFERS; i++)
00195 {
00196 delete [] output_buffer[i];
00197 output_buffer[i] = 0;
00198 buffer_size[i] = 0;
00199 arm_lock[i]->reset();
00200 play_lock[i]->reset();
00201 last_buffer[i] = 0;
00202 }
00203
00204 is_playing_back = 0;
00205 software_position_info = 0;
00206 position_correction = 0;
00207 last_buffer_size = 0;
00208 total_samples = 0;
00209 play_dither == 0;
00210 arm_buffer_num = 0;
00211 last_position = 0;
00212 interrupt = 0;
00213 return 0;
00214 }
00215
00216
00217 int AudioDevice::set_play_dither(int status)
00218 {
00219 play_dither = status;
00220 return 0;
00221 }
00222
00223 int AudioDevice::set_software_positioning(int status)
00224 {
00225 software_position_info = status;
00226 return 0;
00227 }
00228
00229 int AudioDevice::start_playback()
00230 {
00231
00232 is_playing_back = 1;
00233 interrupt = 0;
00234
00235 playback_timer->update();
00236 last_position = 0;
00237
00238 Thread::set_realtime(get_orealtime());
00239 Thread::start();
00240 }
00241
00242 int AudioDevice::interrupt_playback()
00243 {
00244 interrupt = 1;
00245
00246 if(is_playing_back)
00247 {
00248
00249 is_playing_back = 0;
00250 get_lowlevel_out()->interrupt_playback();
00251
00252 }
00253
00254
00255 for(int i = 0; i < TOTAL_BUFFERS; i++)
00256 {
00257
00258
00259
00260 play_lock[i]->unlock();
00261 arm_lock[i]->unlock();
00262 }
00263
00264 return 0;
00265 }
00266
00267 int AudioDevice::wait_for_startup()
00268 {
00269 startup_lock->lock("AudioDevice::wait_for_startup");
00270 return 0;
00271 }
00272
00273 int AudioDevice::wait_for_completion()
00274 {
00275 Thread::join();
00276 return 0;
00277 }
00278
00279
00280
00281 int64_t AudioDevice::current_position()
00282 {
00283
00284 int64_t hardware_result = 0, software_result = 0, frame;
00285
00286 if(w)
00287 {
00288 frame = get_obits() / 8;
00289
00290
00291 if(!software_position_info)
00292 {
00293 hardware_result = get_lowlevel_out()->device_position();
00294 }
00295
00296
00297 if(hardware_result < 0 || software_position_info)
00298 {
00299 timer_lock->lock("AudioDevice::current_position");
00300 software_result = total_samples - last_buffer_size -
00301 device_buffer / frame / get_ochannels();
00302 software_result += playback_timer->get_scaled_difference(get_orate());
00303 timer_lock->unlock();
00304
00305 if(software_result < last_position)
00306 software_result = last_position;
00307 else
00308 last_position = software_result;
00309 }
00310
00311 int64_t offset_samples = -(int64_t)(get_orate() *
00312 out_config->audio_offset);
00313
00314 if(hardware_result < 0 || software_position_info)
00315 return software_result + offset_samples;
00316 else
00317 return hardware_result + offset_samples;
00318 }
00319 else
00320 if(r)
00321 {
00322 int64_t result = total_samples_read +
00323 record_timer->get_scaled_difference(get_irate());
00324 return result;
00325 }
00326
00327 return 0;
00328 }
00329
00330 void AudioDevice::run_output()
00331 {
00332 thread_buffer_num = 0;
00333
00334 startup_lock->unlock();
00335 playback_timer->update();
00336
00337
00338
00339 while(is_playing_back && !interrupt && !last_buffer[thread_buffer_num])
00340 {
00341
00342 play_lock[thread_buffer_num]->lock("AudioDevice::run 1");
00343
00344 if(is_playing_back && !last_buffer[thread_buffer_num])
00345 {
00346 if(duplex_init)
00347 {
00348 if(record_before_play)
00349 {
00350
00351 duplex_lock->lock("AudioDevice::run 2");
00352 }
00353 else
00354 {
00355
00356 duplex_lock->unlock();
00357 }
00358 duplex_init = 0;
00359 }
00360
00361
00362 timer_lock->lock("AudioDevice::run 3");
00363 last_buffer_size = buffer_size[thread_buffer_num] / (get_obits() / 8) / get_ochannels();
00364 total_samples += last_buffer_size;
00365 playback_timer->update();
00366 timer_lock->unlock();
00367
00368
00369
00370 thread_result = get_lowlevel_out()->write_buffer(
00371 output_buffer[thread_buffer_num],
00372 buffer_size[thread_buffer_num]);
00373
00374
00375 arm_lock[thread_buffer_num]->unlock();
00376
00377
00378 if(thread_result < 0)
00379 {
00380 perror("AudioDevice::write_buffer");
00381 sleep(1);
00382 }
00383
00384 thread_buffer_num++;
00385 if(thread_buffer_num >= TOTAL_BUFFERS) thread_buffer_num = 0;
00386 }
00387
00388
00389
00390
00391 if(!interrupt && last_buffer[thread_buffer_num])
00392 {
00393
00394 is_playing_back = 0;
00395
00396 get_lowlevel_out()->flush_device();
00397 }
00398 }
00399 }
00400
00401
00402
00403
00404
00405
00406
00407