1 #include "audiodevice.h"
6 #include "playbackconfig.h"
11 int AudioDevice::write_buffer(double **output, int samples)
13 // find free buffer to fill
14 if(interrupt) return 0;
15 arm_buffer(arm_buffer_num, output, samples);
17 if(arm_buffer_num >= TOTAL_BUFFERS) arm_buffer_num = 0;
21 int AudioDevice::set_last_buffer()
23 arm_lock[arm_buffer_num]->lock("AudioDevice::set_last_buffer");
24 last_buffer[arm_buffer_num] = 1;
25 play_lock[arm_buffer_num]->unlock();
29 if(arm_buffer_num >= TOTAL_BUFFERS) arm_buffer_num = 0;
34 // must run before threading once to allocate buffers
35 // must send maximum size buffer the first time or risk reallocation while threaded
36 int AudioDevice::arm_buffer(int buffer_num,
47 int channel, last_input_channel;
49 int int_sample, int_sample2;
52 int device_channels = get_ochannels();
53 char *buffer_num_buffer;
54 double *buffer_in_channel;
58 frame = device_channels * (bits / 8);
60 new_size = frame * samples;
62 if(interrupt) return 1;
64 // wait for buffer to become available for writing
65 arm_lock[buffer_num]->lock("AudioDevice::arm_buffer");
66 if(interrupt) return 1;
68 if(new_size > buffer_size[buffer_num])
70 delete [] output_buffer[buffer_num];
71 output_buffer[buffer_num] = new char[new_size];
72 buffer_size[buffer_num] = new_size;
75 buffer_size[buffer_num] = new_size;
77 buffer_num_buffer = output_buffer[buffer_num];
78 bzero(buffer_num_buffer, new_size);
80 last_input_channel = device_channels - 1;
82 // intel byte order only to correspond with bits_to_fmt
84 for(channel = 0; channel < device_channels; channel++)
86 buffer_in_channel = output[channel];
90 output_advance = device_channels;
93 for(output_offset = channel, input_offset = 0; input_offset < samples; output_offset += output_advance, input_offset++)
95 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];
110 CLAMP(sample, -1, 1);
112 int_sample = (int)sample;
113 buffer_num_buffer[output_offset] = int_sample;
119 output_advance = device_channels * 2 - 1;
122 for(output_offset = channel * 2, input_offset = 0;
123 input_offset < samples;
124 output_offset += output_advance, input_offset++)
126 sample = buffer_in_channel[input_offset];
127 CLAMP(sample, -1, 1);
129 int_sample = (int)sample;
130 dither_value = rand() % 255;
131 int_sample -= dither_value;
133 buffer_num_buffer[output_offset] = int_sample;
138 for(output_offset = channel * 2, input_offset = 0;
139 input_offset < samples;
140 output_offset += output_advance, input_offset++)
142 sample = buffer_in_channel[input_offset];
143 CLAMP(sample, -1, 1);
145 int_sample = (int)sample;
146 buffer_num_buffer[output_offset++] = (int_sample & 0xff);
147 buffer_num_buffer[output_offset] = (int_sample & 0xff00) >> 8;
153 output_advance = (device_channels - 1) * 3;
154 for(output_offset = channel * 3, input_offset = 0;
155 input_offset < samples;
156 output_offset += output_advance, input_offset++)
158 sample = buffer_in_channel[input_offset];
159 CLAMP(sample, -1, 1);
161 int_sample = (int)sample;
162 buffer_num_buffer[output_offset++] = (int_sample & 0xff);
163 buffer_num_buffer[output_offset++] = (int_sample & 0xff00) >> 8;
164 buffer_num_buffer[output_offset++] = (int_sample & 0xff0000) >> 16;
169 output_advance = (device_channels - 1) * 4;
170 for(output_offset = channel * 4, input_offset = 0;
171 input_offset < samples;
172 output_offset += output_advance, input_offset++)
174 sample = buffer_in_channel[input_offset];
175 CLAMP(sample, -1, 1);
176 sample *= 0x7fffffff;
177 int_sample = (int)sample;
178 buffer_num_buffer[output_offset++] = (int_sample & 0xff);
179 buffer_num_buffer[output_offset++] = (int_sample & 0xff00) >> 8;
180 buffer_num_buffer[output_offset++] = (int_sample & 0xff0000) >> 16;
181 buffer_num_buffer[output_offset++] = (int_sample & 0xff000000) >> 24;
187 // make buffer available for playback
188 play_lock[buffer_num]->unlock();
192 int AudioDevice::reset_output()
194 for(int i = 0; i < TOTAL_BUFFERS; i++)
196 delete [] output_buffer[i];
197 output_buffer[i] = 0;
199 arm_lock[i]->reset();
200 play_lock[i]->reset();
205 software_position_info = 0;
206 position_correction = 0;
207 last_buffer_size = 0;
217 int AudioDevice::set_play_dither(int status)
219 play_dither = status;
223 int AudioDevice::set_software_positioning(int status)
225 software_position_info = status;
229 int AudioDevice::start_playback()
231 // arm buffer before doing this
235 playback_timer->update();
238 Thread::set_realtime(get_orealtime());
239 Thread::start(); // synchronize threads by starting playback here and blocking
242 int AudioDevice::interrupt_playback()
250 get_lowlevel_out()->interrupt_playback();
251 // Completion is waited for in arender
255 for(int i = 0; i < TOTAL_BUFFERS; i++)
257 // When TRACE_LOCKS is enabled, this
258 // locks up when run() is waiting on it at just the right time.
259 // Seems there may be a cancel after the trace lock is locked.
260 play_lock[i]->unlock();
261 arm_lock[i]->unlock();
267 int AudioDevice::wait_for_startup()
269 startup_lock->lock("AudioDevice::wait_for_startup");
273 int AudioDevice::wait_for_completion()
281 int64_t AudioDevice::current_position()
283 // try to get OSS position
284 int64_t hardware_result = 0, software_result = 0, frame;
288 frame = get_obits() / 8;
290 // get hardware position
291 if(!software_position_info)
293 hardware_result = get_lowlevel_out()->device_position();
296 // get software position
297 if(hardware_result < 0 || software_position_info)
299 timer_lock->lock("AudioDevice::current_position");
300 software_result = total_samples - last_buffer_size -
301 device_buffer / frame / get_ochannels();
302 software_result += playback_timer->get_scaled_difference(get_orate());
303 timer_lock->unlock();
305 if(software_result < last_position)
306 software_result = last_position;
308 last_position = software_result;
311 int64_t offset_samples = -(int64_t)(get_orate() *
312 out_config->audio_offset);
314 if(hardware_result < 0 || software_position_info)
315 return software_result + offset_samples;
317 return hardware_result + offset_samples;
322 int64_t result = total_samples_read +
323 record_timer->get_scaled_difference(get_irate());
330 void AudioDevice::run_output()
332 thread_buffer_num = 0;
334 startup_lock->unlock();
335 playback_timer->update();
338 //printf("AudioDevice::run 1 %d\n", Thread::calculate_realtime());
339 while(is_playing_back && !interrupt && !last_buffer[thread_buffer_num])
341 // wait for buffer to become available
342 play_lock[thread_buffer_num]->lock("AudioDevice::run 1");
344 if(is_playing_back && !last_buffer[thread_buffer_num])
348 if(record_before_play)
350 // block until recording starts
351 duplex_lock->lock("AudioDevice::run 2");
355 // allow recording to start
356 duplex_lock->unlock();
361 // get size for position information
362 timer_lock->lock("AudioDevice::run 3");
363 last_buffer_size = buffer_size[thread_buffer_num] / (get_obits() / 8) / get_ochannels();
364 total_samples += last_buffer_size;
365 playback_timer->update();
366 timer_lock->unlock();
369 // write converted buffer synchronously
370 thread_result = get_lowlevel_out()->write_buffer(
371 output_buffer[thread_buffer_num],
372 buffer_size[thread_buffer_num]);
374 // allow writing to the buffer
375 arm_lock[thread_buffer_num]->unlock();
377 // inform user if the buffer write failed
378 if(thread_result < 0)
380 perror("AudioDevice::write_buffer");
385 if(thread_buffer_num >= TOTAL_BUFFERS) thread_buffer_num = 0;
389 //printf("AudioDevice::run 1 %d %d\n", interrupt, last_buffer[thread_buffer_num]);
390 // test for last buffer
391 if(!interrupt && last_buffer[thread_buffer_num])
395 // flush the audio device
396 get_lowlevel_out()->flush_device();