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