1 #include "audiodevice.h"
7 int AudioDevice::write_buffer(double **output, int samples, int channels)
9 // find free buffer to fill
10 if(interrupt) return 0;
11 arm_buffer(arm_buffer_num, output, samples, channels);
13 if(arm_buffer_num >= TOTAL_BUFFERS) arm_buffer_num = 0;
17 int AudioDevice::set_last_buffer()
19 arm_lock[arm_buffer_num]->lock("AudioDevice::set_last_buffer");
20 last_buffer[arm_buffer_num] = 1;
21 play_lock[arm_buffer_num]->unlock();
25 if(arm_buffer_num >= TOTAL_BUFFERS) arm_buffer_num = 0;
30 // must run before threading once to allocate buffers
31 // must send maximum size buffer the first time or risk reallocation while threaded
32 int AudioDevice::arm_buffer(int buffer_num,
44 int channel, last_input_channel;
46 int int_sample, int_sample2;
49 int device_channels = get_ochannels();
50 char *buffer_num_buffer;
51 double *buffer_in_channel;
53 if(channels == -1) channels = get_ochannels();
56 frame = device_channels * (bits / 8);
58 new_size = frame * samples;
60 if(interrupt) return 1;
62 // wait for buffer to become available for writing
63 arm_lock[buffer_num]->lock("AudioDevice::arm_buffer");
64 if(interrupt) return 1;
66 if(new_size > buffer_size[buffer_num])
68 if(buffer_size[buffer_num] != 0)
70 delete [] buffer[buffer_num];
72 buffer[buffer_num] = new char[new_size];
73 buffer_size[buffer_num] = new_size;
76 buffer_size[buffer_num] = new_size;
78 buffer_num_buffer = buffer[buffer_num];
79 bzero(buffer_num_buffer, new_size);
81 last_input_channel = channels - 1;
83 // intel byte order only to correspond with bits_to_fmt
85 for(channel = 0; channel < device_channels && channel < channels; channel++)
87 buffer_in_channel = output[channel];
91 output_advance = device_channels;
94 for(output_offset = channel, input_offset = 0; input_offset < samples; output_offset += output_advance, input_offset++)
96 sample = buffer_in_channel[input_offset];
98 int_sample = (int)sample;
99 dither_value = rand() % 255;
100 int_sample -= dither_value;
102 buffer_num_buffer[output_offset] = int_sample;
107 for(output_offset = channel, input_offset = 0; input_offset < samples; output_offset += output_advance, input_offset++)
109 sample = buffer_in_channel[input_offset];
111 int_sample = (int)sample;
112 buffer_num_buffer[output_offset] = int_sample;
118 output_advance = device_channels * 2 - 1;
121 for(output_offset = channel * 2, input_offset = 0;
122 input_offset < samples;
123 output_offset += output_advance, input_offset++)
125 sample = buffer_in_channel[input_offset];
127 int_sample = (int)sample;
128 dither_value = rand() % 255;
129 int_sample -= dither_value;
131 buffer_num_buffer[output_offset] = int_sample;
136 for(output_offset = channel * 2, input_offset = 0;
137 input_offset < samples;
138 output_offset += output_advance, input_offset++)
140 sample = buffer_in_channel[input_offset];
142 int_sample = (int)sample;
143 buffer_num_buffer[output_offset++] = (int_sample & 0xff);
144 buffer_num_buffer[output_offset] = (int_sample & 0xff00) >> 8;
150 output_advance = (device_channels - 1) * 3;
151 for(output_offset = channel * 3, input_offset = 0;
152 input_offset < samples;
153 output_offset += output_advance, input_offset++)
155 sample = buffer_in_channel[input_offset];
157 int_sample = (int)sample;
158 buffer_num_buffer[output_offset++] = (int_sample & 0xff);
159 buffer_num_buffer[output_offset++] = (int_sample & 0xff00) >> 8;
160 buffer_num_buffer[output_offset++] = (int_sample & 0xff0000) >> 16;
165 output_advance = (device_channels - 1) * 4;
166 for(output_offset = channel * 4, input_offset = 0;
167 input_offset < samples;
168 output_offset += output_advance, input_offset++)
170 sample = buffer_in_channel[input_offset];
171 sample *= 0x7fffffff;
172 int_sample = (int)sample;
173 buffer_num_buffer[output_offset++] = (int_sample & 0xff);
174 buffer_num_buffer[output_offset++] = (int_sample & 0xff00) >> 8;
175 buffer_num_buffer[output_offset++] = (int_sample & 0xff0000) >> 16;
176 buffer_num_buffer[output_offset++] = (int_sample & 0xff000000) >> 24;
182 // make buffer available for playback
183 play_lock[buffer_num]->unlock();
187 int AudioDevice::reset_output()
189 for(int i = 0; i < TOTAL_BUFFERS; i++)
191 if(buffer_size[i]) { delete [] buffer[i]; }
194 arm_lock[i]->reset();
195 play_lock[i]->reset();
200 software_position_info = position_correction = last_buffer_size = 0;
210 int AudioDevice::set_play_dither(int status)
212 play_dither = status;
216 int AudioDevice::set_software_positioning(int status)
218 software_position_info = status;
222 int AudioDevice::start_playback()
224 // arm buffer before doing this
228 playback_timer.update();
231 Thread::set_realtime(get_orealtime());
232 Thread::start(); // synchronize threads by starting playback here and blocking
235 int AudioDevice::interrupt_playback()
243 get_lowlevel_out()->interrupt_playback();
245 // Completion is waited for in arender
249 for(int i = 0; i < TOTAL_BUFFERS; i++)
251 // play_lock[i].reset();
252 // Caused a crash when run() was waiting on it in original versions.
253 // This is required now since thread cancelation is only possible during
255 play_lock[i]->unlock();
256 arm_lock[i]->unlock();
262 int AudioDevice::wait_for_startup()
264 startup_lock->lock("AudioDevice::wait_for_startup");
268 int AudioDevice::wait_for_completion()
276 int64_t AudioDevice::current_position()
278 // try to get OSS position
279 int64_t hardware_result = 0, software_result = 0, frame;
283 frame = get_obits() / 8;
284 // if(get_obits() == 24) frame = 4;
286 // get hardware position
287 if(!software_position_info)
289 hardware_result = get_lowlevel_out()->device_position();
292 // get software position
293 if(hardware_result < 0 || software_position_info)
295 timer_lock->lock("AudioDevice::current_position");
296 software_result = total_samples - last_buffer_size -
297 device_buffer / frame / get_ochannels();
298 software_result += playback_timer.get_scaled_difference(get_orate());
299 timer_lock->unlock();
301 if(software_result < last_position)
302 software_result = last_position;
304 last_position = software_result;
310 //printf("AudioDevice 1\n");
311 return total_samples_read + record_timer.get_scaled_difference(get_irate());
312 //printf("AudioDevice 2\n");
315 if(hardware_result < 0 || software_position_info)
316 return software_result;
318 return hardware_result;
322 void AudioDevice::run()
324 thread_buffer_num = 0;
326 startup_lock->unlock();
327 playback_timer.update();
329 while(is_playing_back && !interrupt && !last_buffer[thread_buffer_num])
331 // wait for buffer to become available
332 play_lock[thread_buffer_num]->lock("AudioDevice::run 1");
334 if(is_playing_back && !last_buffer[thread_buffer_num])
338 if(record_before_play)
340 // block until recording starts
341 duplex_lock->lock("AudioDevice::run 2");
345 // allow recording to start
346 duplex_lock->unlock();
351 // get size for position information
352 timer_lock->lock("AudioDevice::run 3");
353 last_buffer_size = buffer_size[thread_buffer_num] / (get_obits() / 8) / get_ochannels();
354 total_samples += last_buffer_size;
355 playback_timer.update();
356 timer_lock->unlock();
360 thread_result = get_lowlevel_out()->write_buffer(buffer[thread_buffer_num], buffer_size[thread_buffer_num]);
362 // allow writing to the buffer
363 arm_lock[thread_buffer_num]->unlock();
365 // inform user if the buffer write failed
366 if(thread_result < 0)
368 perror("AudioDevice::write_buffer");
373 if(thread_buffer_num >= TOTAL_BUFFERS) thread_buffer_num = 0;
377 //printf("AudioDevice::run 1 %d %d\n", interrupt, last_buffer[thread_buffer_num]);
378 // test for last buffer
379 if(!interrupt && last_buffer[thread_buffer_num])
383 // flush the audio device
384 get_lowlevel_out()->flush_device();