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