From 93e9a127b879bce8e7d73de201efa787afed08aa Mon Sep 17 00:00:00 2001 From: Marek Blok <Marek.Blok@pg.edu.pl> Date: Fri, 10 Sep 2021 09:46:18 +0200 Subject: [PATCH] DSP::WMM_object_t and DSP::SOUND_object_t minor fix --- CHANGELOG | 3 +++ src/cpp/ALSA_support.cpp | 4 ++-- src/cpp/DSP_IO.cpp | 2 +- src/cpp/WMM_support.cpp | 43 ++++++++++++++++++++++++++++++++++---- src/include/ALSA_support.h | 2 +- src/include/DSP_lib.h | 2 +- src/include/DSP_types.h | 7 ++++++- src/include/WMM_support.h | 3 ++- 8 files changed, 55 insertions(+), 11 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index d861133..0b860c4 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -6,6 +6,9 @@ TODO:: LAST DONE: CHANGES: +- ver. 0.20.009 - <b>2021.09.10</b> Changed: + - Fixed: DSP::WMM_object_t and DSP::SOUND_object_t now send to sound card all pending data and wait for finish before closing + - ver. 0.20.008 - <b>2021.05.16</b> Changed: - Added SOUND_object_t::get_wave_in_raw_buffer for non-callback input operations - DSP::u::AudioInput now falls back to non-callback mode if SOUND_object_t doesn't support callbacks diff --git a/src/cpp/ALSA_support.cpp b/src/cpp/ALSA_support.cpp index 00a65d9..a54f695 100644 --- a/src/cpp/ALSA_support.cpp +++ b/src/cpp/ALSA_support.cpp @@ -281,9 +281,9 @@ bool DSP::ALSA_object_t::close_PCM_device_input(void) { return true; } -bool DSP::ALSA_object_t::close_PCM_device_output(void) { +bool DSP::ALSA_object_t::close_PCM_device_output(bool do_drain) { assert(!"DSP::ALSA_object_t::close_PCM_device_output not implemented yet"); - close_alsa_device(true); + close_alsa_device(do_drain); return true; } diff --git a/src/cpp/DSP_IO.cpp b/src/cpp/DSP_IO.cpp index 7187567..c5a112a 100644 --- a/src/cpp/DSP_IO.cpp +++ b/src/cpp/DSP_IO.cpp @@ -4179,7 +4179,7 @@ DSP::u::AudioOutput::~AudioOutput() { // if device was opened successfully snd_object.stop_playback(); - snd_object.close_PCM_device_output(); + snd_object.close_PCM_device_output(true); // #ifdef WINMMAPI // result = waveOutReset(hWaveOut); diff --git a/src/cpp/WMM_support.cpp b/src/cpp/WMM_support.cpp index 6c50e81..f935df6 100644 --- a/src/cpp/WMM_support.cpp +++ b/src/cpp/WMM_support.cpp @@ -30,7 +30,7 @@ DSP::WMM_object_t::~WMM_object_t() close_PCM_device_input(); } if (is_device_output_open) { - close_PCM_device_output(); + close_PCM_device_output(true); } } @@ -139,7 +139,21 @@ unsigned int DSP::WMM_object_t::select_input_device_by_number(const unsigned int bool DSP::WMM_object_t::stop_playback(void) { StopPlayback = true; - //! \TODO can we do more ? + + // if there are still buffers that haven't been yet sent to sound card then do it now + if (IsPlayingNow == false) + { + if (NextBufferOutInd == DSP::NoOfAudioOutputBuffers - 2) //all but one spare buffer are filled up + { // send all data from buffers to soundcard to start playback + for (unsigned int ind=0; ind < DSP::NoOfAudioOutputBuffers-1; ind++) //one spare buffer + { + result=waveOutWrite(hWaveOut, + &(waveHeaderOut[ind]), sizeof(WAVEHDR)); + DSP::f::AudioCheckError(result); + } + IsPlayingNow = true; + } + } return true; } @@ -269,7 +283,7 @@ long DSP::WMM_object_t::open_PCM_device_4_output(const int &no_of_channels, int if (is_device_output_open) { DSP::log << "DSP::WMM_object_t::open_PCM_device_4_output" << DSP::e::LogMode::second << "Device has been already opened: closing device before reopening" << endl; - close_PCM_device_output(); + close_PCM_device_output(false); } switch (no_of_bits) @@ -390,7 +404,28 @@ bool DSP::WMM_object_t::close_PCM_device_input(void) { return true; } -bool DSP::WMM_object_t::close_PCM_device_output(void) { +bool DSP::WMM_object_t::close_PCM_device_output(const bool &do_drain) { + stop_playback(); // just to be sure that all prepared buffershave been sent to sound card + + if (do_drain == true) { + bool still_playing = true; + while (still_playing) { + int counter = 0; + for (unsigned int ind=0; ind < DSP::NoOfAudioOutputBuffers; ind++) //one spare buffer + { + if (waveHeaderOut[NextBufferOutInd].dwFlags & WHDR_DONE) + counter++; + } + if (counter == DSP::NoOfAudioOutputBuffers) { + still_playing = false; + } + else { + // let system process others and then check again + DSP::f::Sleep(0); + } + } + } + result = waveOutReset(hWaveOut); DSP::f::AudioCheckError(result); diff --git a/src/include/ALSA_support.h b/src/include/ALSA_support.h index 7e803fb..5d413b7 100644 --- a/src/include/ALSA_support.h +++ b/src/include/ALSA_support.h @@ -42,7 +42,7 @@ namespace DSP { long open_PCM_device_4_output(const int &no_of_channels, int no_of_bits, const long &sampling_rate, const long &audio_outbuffer_size = -1); long open_PCM_device_4_input(const int &no_of_channels, int no_of_bits, const long &sampling_rate, const long &audio_inbuffer_size = -1); bool close_PCM_device_input(void); - bool close_PCM_device_output(void); + bool close_PCM_device_output(const bool &do_drain); //! returns true is the playback is on bool is_device_playing(void); diff --git a/src/include/DSP_lib.h b/src/include/DSP_lib.h index bca9649..e0ff366 100644 --- a/src/include/DSP_lib.h +++ b/src/include/DSP_lib.h @@ -11,7 +11,7 @@ #define DSP_VER_MAJOR 0 #define DSP_VER_MINOR 20 -#define DSP_VER_BUILD 8 // !!! without zeroes before, else this will be treated as octal number +#define DSP_VER_BUILD 9 // !!! without zeroes before, else this will be treated as octal number #define DSP_VER_YEAR 2021 #define DSP_VER DSP_VER_MAJOR.DSP_VER_MINOR.DSP_VER_BUILD diff --git a/src/include/DSP_types.h b/src/include/DSP_types.h index a99afd5..ffbd22d 100644 --- a/src/include/DSP_types.h +++ b/src/include/DSP_types.h @@ -573,11 +573,16 @@ namespace DSP { //! audio_inbuffer_size is in samples (note that, for example, sample for 16bit stereo is represented by 4bytes) virtual long open_PCM_device_4_input(const int &no_of_channels, int no_of_bits, const long &sampling_rate, const long &audio_inbuffer_size = -1) = 0; virtual bool close_PCM_device_input(void) = 0; - virtual bool close_PCM_device_output(void) = 0; + //! close sound card output + /*! if do_drain == true wait until sound card stops playing + */ + virtual bool close_PCM_device_output(const bool &do_drain) = 0; //! returns true is the playback is on virtual bool is_device_playing(void) = 0; //! initializes playback stopping + /*! If there are still buffers that haven't been yet sent to sound card then do it now + */ virtual bool stop_playback(void) = 0; //! returns true is the sound capture is on virtual bool is_device_recording(void) = 0; diff --git a/src/include/WMM_support.h b/src/include/WMM_support.h index 63af568..05f907f 100644 --- a/src/include/WMM_support.h +++ b/src/include/WMM_support.h @@ -83,8 +83,9 @@ namespace DSP { //! opens default PCM device for capture and returns selected sampling rate on success or negative error code long open_PCM_device_4_input(const int &no_of_channels, int no_of_bits, const long &sampling_rate, const long &audio_inbuffer_size = -1); + bool close_PCM_device_input(void); - bool close_PCM_device_output(void); + bool close_PCM_device_output(const bool &do_drain); bool stop_playback(void); bool stop_recording(void); -- GitLab