summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgnieboer <gnieboer@corpcomm.net>2019-01-22 20:20:26 -0500
committerAndrej Rode <mail@andrejro.de>2019-02-14 11:23:43 +0100
commitec752effae559255b3aa5d2468f57a8139feb45f (patch)
tree91b274e11b8ff5394904d5a54bb01881a4f0fe5d
parentaddf04b9c51779a423a4795f02c941eaff5a33a1 (diff)
gr-audio: fix windows when receiving > 1 output_multiple per work() call
-rw-r--r--gr-audio/lib/windows/windows_sink.cc156
1 files changed, 81 insertions, 75 deletions
diff --git a/gr-audio/lib/windows/windows_sink.cc b/gr-audio/lib/windows/windows_sink.cc
index 04aaba0470..6c17084c08 100644
--- a/gr-audio/lib/windows/windows_sink.cc
+++ b/gr-audio/lib/windows/windows_sink.cc
@@ -134,81 +134,87 @@ namespace gr {
{
const float *f0, *f1;
- // Pick the first available wave header (buffer)
- // If none available, then wait until the processing event if fired and check again
- // Not all events free up a buffer, so it could take more than one loop to get one
- // however, to avoid a lock, only wait 1 second for a freed up buffer then abort.
- LPWAVEHDR chosen_header = NULL;
- int c = 0;
- while (!chosen_header)
- {
- ResetEvent(d_wave_write_event);
- for (int i = 0; i < nPeriods; i++)
+ int samples_sent = 0;
+ int samples_tosend = 0;
+ switch (input_items.size()) {
+ case 1: // mono input
+ f0 = (const float*)input_items[0];
+ break;
+ case 2: // stereo input
+ f0 = (const float*)input_items[0];
+ f1 = (const float*)input_items[1];
+ break;
+ }
+
+ while (samples_sent < noutput_items) {
+ // Pick the first available wave header (buffer)
+ // If none available, then wait until the processing event if fired and check again
+ // Not all events free up a buffer, so it could take more than one loop to get one
+ // however, to avoid a lock, only wait 1 second for a freed up buffer then abort.
+ LPWAVEHDR chosen_header = NULL;
+ int c = 0;
+ while (!chosen_header)
{
- if (d_buffers[i]->dwFlags & WHDR_DONE) {
- // uncomment the below to see which buffers are being consumed
- // printf("%d ", i);
- chosen_header = d_buffers[i];
- break;
- }
- }
- if (!chosen_header) {
- if (!d_ok_to_block)
+ ResetEvent(d_wave_write_event);
+ for (int i = 0; i < nPeriods; i++)
{
- // drop the input data, print warning, and return control.
- printf("aO");
- return noutput_items;
+ if (d_buffers[i]->dwFlags & WHDR_DONE) {
+ // uncomment the below to see which buffers are being consumed
+ // printf("%d ", i);
+ chosen_header = d_buffers[i];
+ break;
+ }
}
- else {
- WaitForSingleObject(d_wave_write_event, 100);
+ if (!chosen_header) {
+ if (!d_ok_to_block)
+ {
+ // drop the input data, print warning, and return control.
+ printf("aO");
+ return noutput_items;
+ }
+ else {
+ WaitForSingleObject(d_wave_write_event, 100);
+ }
}
- }
- if (c++ > 10) {
- // After waiting for 1 second, then something else is seriously wrong so let's
- // just fail and give some debugging information about the status
- // of the buffers.
- for (int i = 0; i < nPeriods; i++) {
- printf("%d: %d\n", i, d_buffers[i]->dwFlags);
+ if (c++ > 10) {
+ // After waiting for 1 second, then something else is seriously wrong so let's
+ // just fail and give some debugging information about the status
+ // of the buffers.
+ for (int i = 0; i < nPeriods; i++) {
+ printf("%d: %d\n", i, d_buffers[i]->dwFlags);
+ }
+ perror("audio_windows_sink: no audio buffers available");
+ return -1;
}
- perror("audio_windows_sink: no audio buffers available");
- return -1;
}
- }
- short *d_buffer = (short *)chosen_header->lpData;
+ short *d_buffer = (short *)chosen_header->lpData;
+ samples_tosend = noutput_items - samples_sent >= d_chunk_size ? d_chunk_size : noutput_items - samples_sent;
- switch (input_items.size()) {
- case 1: // mono input
- f0 = (const float*)input_items[0];
- for (int i = 0; i < noutput_items; i += d_chunk_size) {
- for (int j = 0; j < d_chunk_size; j++) {
+ switch (input_items.size()) {
+ case 1: // mono input
+ for (int j = 0; j < samples_tosend; j++) {
d_buffer[2 * j + 0] = (short)(f0[j] * 32767);
d_buffer[2 * j + 1] = (short)(f0[j] * 32767);
}
- f0 += d_chunk_size;
- }
- break;
- case 2: // stereo input
- f0 = (const float*)input_items[0];
- f1 = (const float*)input_items[1];
-
- for (int i = 0; i < noutput_items; i += d_chunk_size) {
- for (int j = 0; j < d_chunk_size; j++) {
+ f0 += samples_tosend;
+ break;
+ case 2: // stereo input
+ for (int j = 0; j < samples_tosend; j++) {
d_buffer[2 * j + 0] = (short)(f0[j] * 32767);
d_buffer[2 * j + 1] = (short)(f1[j] * 32767);
}
- f0 += d_chunk_size;
- f1 += d_chunk_size;
+ f0 += samples_tosend;
+ f1 += samples_tosend;
+ break;
}
- break;
- }
- if (write_waveout
- (chosen_header) < 0) {
- perror("audio_windows_sink: write failed");
+ if (write_waveout(chosen_header) < 0) {
+ perror("audio_windows_sink: write failed");
+ }
+ samples_sent += samples_tosend;
}
-
- return noutput_items;
+ return samples_sent;
}
int
@@ -331,7 +337,7 @@ namespace gr {
}
int
- windows_sink::write_waveout(LPWAVEHDR lp_wave_hdr)
+ windows_sink::write_waveout(LPWAVEHDR lp_wave_hdr)
{
UINT w_result;
@@ -351,22 +357,22 @@ namespace gr {
if (w_result != 0) {
perror("audio_windows_sink: Failed to write block to device");
switch (w_result) {
- case MMSYSERR_INVALHANDLE:
- fprintf(stderr, "Specified device handle is invalid.\n");
- break;
- case MMSYSERR_NODRIVER:
- fprintf(stderr, " No device driver is present.\n");
- break;
- case MMSYSERR_NOMEM:
- fprintf(stderr, " Unable to allocate or lock memory.\n");
- break;
- case WAVERR_UNPREPARED:
- fprintf(stderr,
- " The data block pointed to by the pwh parameter hasn't been prepared.\n");
- break;
- default:
- fprintf(stderr, "Unknown error %i\n", w_result);
- }
+ case MMSYSERR_INVALHANDLE:
+ fprintf(stderr, "Specified device handle is invalid.\n");
+ break;
+ case MMSYSERR_NODRIVER:
+ fprintf(stderr, " No device driver is present.\n");
+ break;
+ case MMSYSERR_NOMEM:
+ fprintf(stderr, " Unable to allocate or lock memory.\n");
+ break;
+ case WAVERR_UNPREPARED:
+ fprintf(stderr,
+ " The data block pointed to by the pwh parameter hasn't been prepared.\n");
+ break;
+ default:
+ fprintf(stderr, "Unknown error %i\n", w_result);
+ }
waveOutUnprepareHeader(d_h_waveout, lp_wave_hdr, sizeof(WAVEHDR));
return -1;
}