From d00dc201ea70b3e18bd369754d3f6ac7eedd52aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damian=20Kara=C5=9B?= <s176030@student.pg.edu.pl> Date: Tue, 16 Nov 2021 18:37:18 +0100 Subject: [PATCH] ALSA_support: improved open device for input MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Damian KaraĹ <s176030@student.pg.edu.pl> --- src/cpp/ALSA_support.cpp | 165 +++++++++++++++++-------------------- src/include/ALSA_support.h | 8 +- 2 files changed, 82 insertions(+), 91 deletions(-) diff --git a/src/cpp/ALSA_support.cpp b/src/cpp/ALSA_support.cpp index d7726de..f067c58 100644 --- a/src/cpp/ALSA_support.cpp +++ b/src/cpp/ALSA_support.cpp @@ -51,6 +51,7 @@ DSP::ALSA_object_t::ALSA_object_t() no_of_bytes_in_channel = 2; audio_inbuffer_size_in_frames = 8000; + audio_outbuffer_size_in_frames = 8000; size_b = 32; } @@ -208,32 +209,69 @@ int DSP::ALSA_object_t::open_alsa_device(snd_pcm_stream_t stream_type) snd_pcm_hw_params_set_rate_near(alsa_handle, params, &sampling_rate_alsa, &dir); - if (audio_inbuffer_size_in_frames <= 0) - audio_inbuffer_size_in_frames = 8000; + if (stream_type == SND_PCM_STREAM_PLAYBACK) + { + if (audio_outbuffer_size_in_frames <= 0) + audio_outbuffer_size_in_frames = 8000; + + size_b = audio_outbuffer_size_in_frames * no_of_channels_alsa * no_of_bytes_in_channel; - rc = snd_pcm_hw_params_set_buffer_size(alsa_handle, params, DSP::NoOfAudioOutputBuffers*audio_inbuffer_size_in_frames); + rc = snd_pcm_hw_params_set_buffer_size(alsa_handle, params, DSP::NoOfAudioOutputBuffers*audio_outbuffer_size_in_frames); - snd_pcm_uframes_t requested_audio_inbuffer_size_in_frames = audio_inbuffer_size_in_frames; + snd_pcm_uframes_t requested_audio_outbuffer_size_in_frames = audio_outbuffer_size_in_frames; - if (rc < 0) - { - DSP::log << "Unable to set a buffer size with error code: " << rc << endl; - return -5; + if (rc < 0) + { + DSP::log << "Unable to set a buffer size with error code: " << rc << endl; + return -5; + } + + /*! Set period size to desired number of frames. */ + snd_pcm_hw_params_set_period_size_near(alsa_handle, params, &audio_outbuffer_size_in_frames, &dir); + + #ifdef AUDIO_DEBUG_MESSAGES_ON + if (audio_outbuffer_size_in_frames != requested_audio_outbuffer_size_in_frames) + { + DSP::log << "Current frames value should be equal: " << requested_audio_outbuffer_size_in_frames << endl; + DSP::log << "Frames is not equal to tmp_frames! Frames: " << audio_outbuffer_size_in_frames << endl; + } + + else + DSP::log << "Frames has been set correctly." << endl; + #endif // AUDIO_DEBUG_MESSAGES_ON } - /*! Set period size to desired number of frames. */ - snd_pcm_hw_params_set_period_size_near(alsa_handle, params, &audio_inbuffer_size_in_frames, &dir); + else // stream_type == SND_PCM_STREAM_CAPTURE + { + if (audio_inbuffer_size_in_frames <= 0) + audio_inbuffer_size_in_frames = 8000; + + size_b = audio_inbuffer_size_in_frames * no_of_channels_alsa * no_of_bytes_in_channel; + + rc = snd_pcm_hw_params_set_buffer_size(alsa_handle, params, size_b); + + snd_pcm_uframes_t requested_audio_inbuffer_size_in_frames = audio_inbuffer_size_in_frames; - #ifdef AUDIO_DEBUG_MESSAGES_ON - if (audio_inbuffer_size_in_frames != requested_audio_inbuffer_size_in_frames) + if (rc < 0) { - DSP::log << "Current frames value should be equal: " << requested_audio_inbuffer_size_in_frames << endl; - DSP::log << "Frames is not equal to tmp_frames! Frames: " << audio_inbuffer_size_in_frames << endl; + DSP::log << "Unable to set a buffer size with error code: " << rc << endl; + return -5; } - else - DSP::log << "Frames has been set correctly." << endl; - #endif // AUDIO_DEBUG_MESSAGES_ON + /*! Set period size to desired number of frames. */ + snd_pcm_hw_params_set_period_size_near(alsa_handle, params, &audio_inbuffer_size_in_frames, &dir); + + #ifdef AUDIO_DEBUG_MESSAGES_ON + if (audio_inbuffer_size_in_frames != requested_audio_inbuffer_size_in_frames) + { + DSP::log << "Current frames value should be equal: " << requested_audio_inbuffer_size_in_frames << endl; + DSP::log << "Frames is not equal to tmp_frames! Frames: " << audio_inbuffer_size_in_frames << endl; + } + + else + DSP::log << "Frames has been set correctly." << endl; + #endif // AUDIO_DEBUG_MESSAGES_ON + } /* Write the parameters to the driver */ rc = snd_pcm_hw_params(alsa_handle, params); @@ -281,8 +319,17 @@ int DSP::ALSA_object_t::open_alsa_device(snd_pcm_stream_t stream_type) snd_pcm_hw_params_get_period_time(hw_params, &val, &dir); DSP::log << "period time = " << val << " us" << endl; - snd_pcm_hw_params_get_period_size(hw_params, &audio_inbuffer_size_in_frames, &dir); - DSP::log << "period size = " << (int) audio_inbuffer_size_in_frames << " frames" << endl; + if (stream_type == SND_PCM_STREAM_PLAYBACK) + { + snd_pcm_hw_params_get_period_size(hw_params, &audio_outbuffer_size_in_frames, &dir); + DSP::log << "period size = " << (int) audio_outbuffer_size_in_frames << " frames" << endl; + } + + else // stream_type == SND_PCM_STREAM_CAPTURE + { + snd_pcm_hw_params_get_period_size(hw_params, &audio_inbuffer_size_in_frames, &dir); + DSP::log << "period size = " << (int) audio_inbuffer_size_in_frames << " frames" << endl; + } snd_pcm_hw_params_get_buffer_time(hw_params, &val, &dir); DSP::log << "buffer time = " << val << " us" << endl; @@ -353,8 +400,6 @@ int DSP::ALSA_object_t::open_alsa_device(snd_pcm_stream_t stream_type) // Can be useful: // snd_pcm_hw_params_get_period_size(hw_params, &frames, &dir); - - size_b = audio_inbuffer_size_in_frames * no_of_channels_alsa * no_of_bytes_in_channel; if (stream_type == SND_PCM_STREAM_PLAYBACK) { @@ -430,74 +475,15 @@ int DSP::ALSA_object_t::open_alsa_device(snd_pcm_stream_t stream_type) } else // (stream_type == SND_PCM_STREAM_CAPTURE) { - pcm_buffer.resize(DSP::NoOfAudioInputBuffers); - pcm_buffer_size_in_frames.resize(DSP::NoOfAudioInputBuffers); - switch (no_of_bytes_in_channel) - { - case 1: - buffers_8bit.resize(DSP::NoOfAudioInputBuffers); - - for(unsigned int ind = 0; ind < DSP::NoOfAudioInputBuffers; ind++) - { - buffers_8bit[ind].resize(size_b / no_of_bytes_in_channel); - pcm_buffer[ind] = (uint8_t *)(buffers_8bit[ind].data()); - pcm_buffer_size_in_frames[ind] = (snd_pcm_sframes_t) buffers_8bit[ind].size() / no_of_channels_alsa; - } - break; - - case 2: - buffers_16bit.resize(DSP::NoOfAudioInputBuffers); - - for(unsigned int ind = 0; ind < DSP::NoOfAudioInputBuffers; ind++) - { - buffers_16bit[ind].resize(size_b / no_of_bytes_in_channel); - pcm_buffer[ind] = (uint8_t *)(buffers_16bit[ind].data()); - pcm_buffer_size_in_frames[ind] = (snd_pcm_sframes_t) buffers_16bit[ind].size() / no_of_channels_alsa; - } - break; - - case 3: - case 4: - if (IsHigherQualityMode) - { - buffers_32bit.resize(DSP::NoOfAudioInputBuffers); - - for(unsigned int ind = 0; ind < DSP::NoOfAudioInputBuffers; ind++) - { - buffers_32bit[ind].resize(size_b / no_of_bytes_in_channel); - pcm_buffer[ind] = (uint8_t *)(buffers_32bit[ind].data()); - pcm_buffer_size_in_frames[ind] = (snd_pcm_sframes_t) buffers_32bit[ind].size() / no_of_channels_alsa; - } - } - - else //! native mode - { - buffers_32bit_f.resize(DSP::NoOfAudioInputBuffers); - - for(unsigned int ind = 0; ind < DSP::NoOfAudioInputBuffers; ind++) - { - buffers_32bit_f[ind].resize(size_b / no_of_bytes_in_channel); - pcm_buffer[ind] = (uint8_t *)(buffers_32bit_f[ind].data()); - pcm_buffer_size_in_frames[ind] = (snd_pcm_sframes_t) buffers_32bit_f[ind].size() / no_of_channels_alsa; - } - } - break; - - case 8: - buffers_64bit.resize(DSP::NoOfAudioInputBuffers); - - for(unsigned int ind = 0; ind < DSP::NoOfAudioInputBuffers; ind++) - { - buffers_64bit[ind].resize(size_b / no_of_bytes_in_channel); - pcm_buffer[ind] = (uint8_t *)(buffers_64bit[ind].data()); - pcm_buffer_size_in_frames[ind] = (snd_pcm_sframes_t) buffers_64bit[ind].size() / no_of_channels_alsa; - } - break; + pcm_buffer.resize(1); + pcm_buffer_size_in_frames.resize(1); + + capture_buffer.resize(size_b / no_of_bytes_in_channel); - default: - DSP::log << "Unsupported no of bytes in channel" << endl; - return -6; - break; + for(unsigned int ind = 0; ind < pcm_buffer.size(); ind++) + { + pcm_buffer[ind] = (uint8_t *)(capture_buffer.data()); + pcm_buffer_size_in_frames[ind] = (snd_pcm_sframes_t) capture_buffer.size() / no_of_channels_alsa; } switch (no_of_bytes_in_channel) @@ -682,7 +668,7 @@ long DSP::ALSA_object_t::open_PCM_device_4_output(const int &no_of_channels, int no_of_channels_alsa = (unsigned int) no_of_channels; no_of_bytes_in_channel = (unsigned int) no_of_bits / 8; sampling_rate_alsa = (unsigned int) sampling_rate; - audio_inbuffer_size_in_frames = (snd_pcm_uframes_t) audio_outbuffer_size; + audio_outbuffer_size_in_frames = (snd_pcm_uframes_t) audio_outbuffer_size; rc = open_alsa_device(SND_PCM_STREAM_PLAYBACK); @@ -973,6 +959,7 @@ bool DSP::ALSA_object_t::get_wave_in_raw_buffer(DSP::e::SampleType &InSampleType #endif // AUDIO_DEBUG_MESSAGES_ON pcm_buffer_size_in_frames[ind] = 0; + return false; } break; } diff --git a/src/include/ALSA_support.h b/src/include/ALSA_support.h index 99e7e65..0c7b59e 100644 --- a/src/include/ALSA_support.h +++ b/src/include/ALSA_support.h @@ -50,12 +50,15 @@ namespace DSP { /*! It is better to use STD containers - they are more convenient, and they mean fewer problems with memory leaks. */ - //! buffers depending on samples type + //! outbuffers depending on samples type std::vector<std::vector<uint8_t>> buffers_8bit; std::vector<std::vector<int16_t>> buffers_16bit; std::vector<std::vector<int32_t>> buffers_32bit; std::vector<std::vector<float>> buffers_32bit_f; std::vector<std::vector<double>> buffers_64bit; + + //! inbuffer + std::vector<int8_t> capture_buffer; //! samples are integers rather than float values bool IsHigherQualityMode; @@ -75,7 +78,8 @@ namespace DSP { bool IsRecordingNow; //! just samples - snd_pcm_uframes_t audio_inbuffer_size_in_frames; // M.B. more meaningful variable name + snd_pcm_uframes_t audio_inbuffer_size_in_frames; + snd_pcm_uframes_t audio_outbuffer_size_in_frames; //! Type of samples in WaveInBuffers DSP::e::SampleType InSampleTypeALSA; -- GitLab