1 #include "audiodevice.h"
5 int AudioDevice::write_buffer(double **output, int samples, int channels)
7 // find free buffer to fill
8 if(interrupt) return 0;
9 arm_buffer(arm_buffer_num, output, samples, channels);
11 if(arm_buffer_num >= TOTAL_BUFFERS) arm_buffer_num = 0;
15 int AudioDevice::set_last_buffer()
17 arm_mutex[arm_buffer_num].lock();
18 last_buffer[arm_buffer_num] = 1;
19 play_mutex[arm_buffer_num].unlock();
21 if(arm_buffer_num >= TOTAL_BUFFERS) arm_buffer_num = 0;
26 // must run before threading once to allocate buffers
27 // must send maximum size buffer the first time or risk reallocation while threaded
28 int AudioDevice::arm_buffer(int buffer_num,
40 int channel, last_input_channel;
42 int int_sample, int_sample2;
45 int device_channels = get_ochannels();
46 char *buffer_num_buffer;
47 double *buffer_in_channel;
49 // for(i = 0; i < 100; i++)
50 // printf("%.2f ", output[0][i]);
53 //printf("AudioDevice::arm_buffer 1\n");
54 if(channels == -1) channels = get_ochannels();
57 //printf("AudioDevice::arm_buffer 1\n");
58 frame = device_channels * (bits / 8);
59 // if(bits == 24) frame = 4;
61 //printf("AudioDevice::arm_buffer 1\n");
62 new_size = frame * samples;
64 //printf("AudioDevice::arm_buffer 1\n");
65 if(interrupt) return 1;
67 //printf("AudioDevice::arm_buffer 1 %d\n", buffer_num);
68 // wait for buffer to become available for writing
69 arm_mutex[buffer_num].lock();
70 //printf("AudioDevice::arm_buffer 2\n");
71 if(interrupt) return 1;
73 if(new_size > buffer_size[buffer_num])
75 // do both buffers before threading to prevent kill during allocation
76 // for(i = 0; i < 2; i++)
78 // if(buffer_size[i] != 0)
80 // delete [] buffer[i];
82 // buffer[i] = new char[new_size];
83 // buffer_size[i] = new_size;
85 if(buffer_size[buffer_num] != 0)
87 delete [] buffer[buffer_num];
89 buffer[buffer_num] = new char[new_size];
90 buffer_size[buffer_num] = new_size;
93 buffer_size[buffer_num] = new_size;
95 //printf("AudioDevice::arm_buffer 1\n");
96 buffer_num_buffer = buffer[buffer_num];
97 bzero(buffer_num_buffer, new_size);
99 last_input_channel = channels - 1;
101 // intel byte order only to correspond with bits_to_fmt
103 //printf("AudioDevice::arm_buffer 1\n");
104 for(channel = 0; channel < device_channels && channel < channels; channel++)
106 // if(channel >= channels) buffer_in_channel = output[last_input_channel];
107 // else buffer_in_channel = output[channel];
109 buffer_in_channel = output[channel];
113 output_advance = device_channels;
116 for(output_offset = channel, input_offset = 0; input_offset < samples; output_offset += output_advance, input_offset++)
118 sample = buffer_in_channel[input_offset];
120 int_sample = (int)sample;
121 dither_value = rand() % 255;
122 int_sample -= dither_value;
124 buffer_num_buffer[output_offset] = int_sample;
129 for(output_offset = channel, input_offset = 0; input_offset < samples; output_offset += output_advance, input_offset++)
131 sample = buffer_in_channel[input_offset];
133 int_sample = (int)sample;
134 buffer_num_buffer[output_offset] = int_sample;
140 output_advance = device_channels * 2 - 1;
143 for(output_offset = channel * 2, input_offset = 0;
144 input_offset < samples;
145 output_offset += output_advance, input_offset++)
147 sample = buffer_in_channel[input_offset];
149 int_sample = (int)sample;
150 dither_value = rand() % 255;
151 int_sample -= dither_value;
153 buffer_num_buffer[output_offset] = int_sample;
158 for(output_offset = channel * 2, input_offset = 0;
159 input_offset < samples;
160 output_offset += output_advance, input_offset++)
162 sample = buffer_in_channel[input_offset];
164 int_sample = (int)sample;
165 buffer_num_buffer[output_offset++] = (int_sample & 0xff);
166 buffer_num_buffer[output_offset] = (int_sample & 0xff00) >> 8;
172 output_advance = (device_channels - 1) * 3;
173 for(output_offset = channel * 3, input_offset = 0;
174 input_offset < samples;
175 output_offset += output_advance, input_offset++)
177 sample = buffer_in_channel[input_offset];
179 int_sample = (int)sample;
180 buffer_num_buffer[output_offset++] = (int_sample & 0xff);
181 buffer_num_buffer[output_offset++] = (int_sample & 0xff00) >> 8;
182 buffer_num_buffer[output_offset++] = (int_sample & 0xff0000) >> 16;
187 output_advance = (device_channels - 1) * 4;
188 for(output_offset = channel * 4, input_offset = 0;
189 input_offset < samples;
190 output_offset += output_advance, input_offset++)
192 sample = buffer_in_channel[input_offset];
193 sample *= 0x7fffffff;
194 int_sample = (int)sample;
195 buffer_num_buffer[output_offset++] = (int_sample & 0xff);
196 buffer_num_buffer[output_offset++] = (int_sample & 0xff00) >> 8;
197 buffer_num_buffer[output_offset++] = (int_sample & 0xff0000) >> 16;
198 buffer_num_buffer[output_offset++] = (int_sample & 0xff000000) >> 24;
204 //printf("AudioDevice::arm_buffer 2\n");
205 // make buffer available for playback
206 play_mutex[buffer_num].unlock();
210 int AudioDevice::reset_output()
212 for(int i = 0; i < TOTAL_BUFFERS; i++)
214 if(buffer_size[i]) { delete [] buffer[i]; }
217 arm_mutex[i].unlock();
218 play_mutex[i].reset();
219 play_mutex[i].lock();
226 software_position_info = position_correction = last_buffer_size = 0;
236 int AudioDevice::set_play_dither(int status)
238 play_dither = status;
242 int AudioDevice::set_software_positioning(int status)
244 software_position_info = status;
248 int AudioDevice::start_playback()
250 // arm buffer before doing this
254 playback_timer.update();
258 Thread::set_realtime(get_orealtime());
259 Thread::start(); // synchronize threads by starting playback here and blocking
262 int AudioDevice::interrupt_playback()
270 get_lowlevel_out()->interrupt_playback();
272 // Completion is waited for in arender
276 for(int i = 0; i < TOTAL_BUFFERS; i++)
278 // play_mutex[i].reset();
279 // Caused a crash when run() was waiting on it in original versions.
280 // This is required now since thread cancelation is only possible during
282 play_mutex[i].unlock();
283 arm_mutex[i].unlock();
289 int AudioDevice::wait_for_startup()
292 startup_lock.unlock();
296 int AudioDevice::wait_for_completion()
304 int64_t AudioDevice::current_position()
306 // try to get OSS position
307 int64_t hardware_result = 0, software_result = 0, frame;
311 frame = get_obits() / 8;
312 // if(get_obits() == 24) frame = 4;
314 // get hardware position
315 if(!software_position_info)
317 hardware_result = get_lowlevel_out()->device_position();
320 // get software position
321 if(hardware_result < 0 || software_position_info)
324 software_result = total_samples - last_buffer_size -
325 device_buffer / frame / get_ochannels();
326 software_result += playback_timer.get_scaled_difference(get_orate());
329 if(software_result < last_position)
330 software_result = last_position;
332 last_position = software_result;
338 //printf("AudioDevice 1\n");
339 return total_samples_read + record_timer.get_scaled_difference(get_irate());
340 //printf("AudioDevice 2\n");
343 if(hardware_result < 0 || software_position_info)
344 return software_result;
346 return hardware_result;
350 void AudioDevice::run()
352 thread_buffer_num = 0;
354 startup_lock.unlock();
355 playback_timer.update();
357 while(is_playing_back && !interrupt && !last_buffer[thread_buffer_num])
359 // wait for buffer to become available
360 play_mutex[thread_buffer_num].lock();
362 if(is_playing_back && !last_buffer[thread_buffer_num])
366 if(record_before_play)
368 // block until recording starts
373 // allow recording to start
374 duplex_lock.unlock();
379 // get size for position information
381 last_buffer_size = buffer_size[thread_buffer_num] / (get_obits() / 8) / get_ochannels();
382 total_samples += last_buffer_size;
383 playback_timer.update();
387 thread_result = get_lowlevel_out()->write_buffer(buffer[thread_buffer_num], buffer_size[thread_buffer_num]);
389 // allow writing to the buffer
390 arm_mutex[thread_buffer_num].unlock();
392 // inform user if the buffer write failed
393 if(thread_result < 0)
395 perror("AudioDevice::write_buffer");
400 if(thread_buffer_num >= TOTAL_BUFFERS) thread_buffer_num = 0;
403 // test for last buffer
404 if(!interrupt && last_buffer[thread_buffer_num])
408 // flush the audio device
409 get_lowlevel_out()->flush_device();