From c7c0b86afa255983db3def0a15e1201455ade460 Mon Sep 17 00:00:00 2001
From: Tom Rondeau
Date: Sat, 30 Oct 2010 16:29:27 -0400
Subject: Added a check in alsa sink if error has occurred due to blocking; if
 so, it will just drop samples and not get backed up. Patch taken from Marcus
 Leech 10/29/2010.

---
 gr-audio-alsa/src/audio_alsa_sink.cc | 12 +++++++++---
 gr-audio-alsa/src/audio_alsa_sink.h  |  1 +
 2 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/gr-audio-alsa/src/audio_alsa_sink.cc b/gr-audio-alsa/src/audio_alsa_sink.cc
index d6b7f84cf..c28e23fea 100644
--- a/gr-audio-alsa/src/audio_alsa_sink.cc
+++ b/gr-audio-alsa/src/audio_alsa_sink.cc
@@ -90,7 +90,7 @@ audio_alsa_sink::audio_alsa_sink (int sampling_rate,
     d_period_size (0),
     d_buffer_size_bytes (0), d_buffer (0),
     d_worker (0), d_special_case_mono_to_stereo (false),
-    d_nunderuns (0), d_nsuspends (0)
+    d_nunderuns (0), d_nsuspends (0), d_ok_to_block(ok_to_block)
 {
   CHATTY_DEBUG = gr_prefs::singleton()->get_bool("audio_alsa", "verbose", false);
 
@@ -100,6 +100,8 @@ audio_alsa_sink::audio_alsa_sink (int sampling_rate,
   // open the device for playback
   error = snd_pcm_open(&d_pcm_handle, d_device_name.c_str (),
 		       SND_PCM_STREAM_PLAYBACK, 0);
+  if (ok_to_block == false)
+    snd_pcm_nonblock(d_pcm_handle, !ok_to_block);
   if (error < 0){
     fprintf (stderr, "audio_alsa_sink[%s]: %s\n",
 	     d_device_name.c_str(), snd_strerror(error));
@@ -287,7 +289,6 @@ audio_alsa_sink::check_topology (int ninputs, int noutputs)
   default:
     assert (0);
   }
-
   return true;
 }
 
@@ -489,7 +490,12 @@ audio_alsa_sink::write_buffer (const void *vbuffer,
   while (nframes > 0){
     int r = snd_pcm_writei (d_pcm_handle, buffer, nframes);
     if (r == -EAGAIN)
-      continue;			// try again
+    {
+      if (d_ok_to_block == true)
+	continue;		// try again
+      
+      break;
+    }
 
     else if (r == -EPIPE){	// underrun
       d_nunderuns++;
diff --git a/gr-audio-alsa/src/audio_alsa_sink.h b/gr-audio-alsa/src/audio_alsa_sink.h
index d4b540382..f3007f60f 100644
--- a/gr-audio-alsa/src/audio_alsa_sink.h
+++ b/gr-audio-alsa/src/audio_alsa_sink.h
@@ -83,6 +83,7 @@ class audio_alsa_sink : public gr_sync_block {
   // random stats
   int			d_nunderuns;		// count of underruns
   int			d_nsuspends;		// count of suspends
+  bool			d_ok_to_block;      // defaults to "true", controls blocking/non-block I/O
 
   void output_error_msg (const char *msg, int err);
   void bail (const char *msg, int err) throw (std::runtime_error);
-- 
cgit 


From ed4abf6f759a421bc845d9138f82df84bb4bbf96 Mon Sep 17 00:00:00 2001
From: Tom Rondeau
Date: Mon, 6 Dec 2010 20:22:22 -0500
Subject: Adding a "change in progress" check to alsa sink.

---
 gr-audio-alsa/src/audio_alsa_sink.cc | 18 +++++++++++++++++-
 gr-audio-alsa/src/audio_alsa_sink.h  |  1 +
 2 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/gr-audio-alsa/src/audio_alsa_sink.cc b/gr-audio-alsa/src/audio_alsa_sink.cc
index c28e23fea..84bf49151 100644
--- a/gr-audio-alsa/src/audio_alsa_sink.cc
+++ b/gr-audio-alsa/src/audio_alsa_sink.cc
@@ -90,7 +90,8 @@ audio_alsa_sink::audio_alsa_sink (int sampling_rate,
     d_period_size (0),
     d_buffer_size_bytes (0), d_buffer (0),
     d_worker (0), d_special_case_mono_to_stereo (false),
-    d_nunderuns (0), d_nsuspends (0), d_ok_to_block(ok_to_block)
+    d_nunderuns (0), d_nsuspends (0), d_ok_to_block(ok_to_block),
+    d_change_in_progress(false)
 {
   CHATTY_DEBUG = gr_prefs::singleton()->get_bool("audio_alsa", "verbose", false);
 
@@ -224,6 +225,11 @@ audio_alsa_sink::check_topology (int ninputs, int noutputs)
   // FIXME check_topology may be called more than once.
   // Ensure that the pcm is in a state where we can still mess with the hw_params
 
+  d_change_in_progress = true;
+  
+  if (snd_pcm_state (d_pcm_handle) == SND_PCM_STATE_RUNNING)
+    snd_pcm_drop (d_pcm_handle);
+  
   bool special_case = nchan == 1 && d_special_case_mono_to_stereo;
   if (special_case)
     nchan = 2;
@@ -232,6 +238,7 @@ audio_alsa_sink::check_topology (int ninputs, int noutputs)
 
   if (err < 0){
     output_error_msg ("set_channels failed", err);
+    d_change_in_progress = false;
     return false;
   }
 
@@ -239,6 +246,7 @@ audio_alsa_sink::check_topology (int ninputs, int noutputs)
   err = snd_pcm_hw_params(d_pcm_handle, d_hw_params);
   if (err < 0){
     output_error_msg ("snd_pcm_hw_params failed", err);
+    d_change_in_progress = false;
     return false;
   }
 
@@ -289,6 +297,7 @@ audio_alsa_sink::check_topology (int ninputs, int noutputs)
   default:
     assert (0);
   }
+  d_change_in_progress = false;
   return true;
 }
 
@@ -487,6 +496,13 @@ audio_alsa_sink::write_buffer (const void *vbuffer,
 {
   const unsigned char *buffer = (const unsigned char *) vbuffer;
 
+  int change_counter = 10;
+  while (d_change_in_progress == true && change_counter >= 0) {
+    change_counter--;
+    usleep(10000);
+  }
+  d_change_in_progress = false;
+	
   while (nframes > 0){
     int r = snd_pcm_writei (d_pcm_handle, buffer, nframes);
     if (r == -EAGAIN)
diff --git a/gr-audio-alsa/src/audio_alsa_sink.h b/gr-audio-alsa/src/audio_alsa_sink.h
index f3007f60f..811cc6c8c 100644
--- a/gr-audio-alsa/src/audio_alsa_sink.h
+++ b/gr-audio-alsa/src/audio_alsa_sink.h
@@ -83,6 +83,7 @@ class audio_alsa_sink : public gr_sync_block {
   // random stats
   int			d_nunderuns;		// count of underruns
   int			d_nsuspends;		// count of suspends
+  bool                  d_change_in_progress;   // Topology change in progress--used as spinlock for write_buffer
   bool			d_ok_to_block;      // defaults to "true", controls blocking/non-block I/O
 
   void output_error_msg (const char *msg, int err);
-- 
cgit 


From a8e58dba4d820e0b66d89bf05af29c381e46eef9 Mon Sep 17 00:00:00 2001
From: Tom Rondeau
Date: Wed, 22 Dec 2010 17:11:44 -0500
Subject: Reverting last change in alsa.

---
 gr-audio-alsa/src/audio_alsa_sink.cc | 18 +-----------------
 gr-audio-alsa/src/audio_alsa_sink.h  |  1 -
 2 files changed, 1 insertion(+), 18 deletions(-)

diff --git a/gr-audio-alsa/src/audio_alsa_sink.cc b/gr-audio-alsa/src/audio_alsa_sink.cc
index 84bf49151..c28e23fea 100644
--- a/gr-audio-alsa/src/audio_alsa_sink.cc
+++ b/gr-audio-alsa/src/audio_alsa_sink.cc
@@ -90,8 +90,7 @@ audio_alsa_sink::audio_alsa_sink (int sampling_rate,
     d_period_size (0),
     d_buffer_size_bytes (0), d_buffer (0),
     d_worker (0), d_special_case_mono_to_stereo (false),
-    d_nunderuns (0), d_nsuspends (0), d_ok_to_block(ok_to_block),
-    d_change_in_progress(false)
+    d_nunderuns (0), d_nsuspends (0), d_ok_to_block(ok_to_block)
 {
   CHATTY_DEBUG = gr_prefs::singleton()->get_bool("audio_alsa", "verbose", false);
 
@@ -225,11 +224,6 @@ audio_alsa_sink::check_topology (int ninputs, int noutputs)
   // FIXME check_topology may be called more than once.
   // Ensure that the pcm is in a state where we can still mess with the hw_params
 
-  d_change_in_progress = true;
-  
-  if (snd_pcm_state (d_pcm_handle) == SND_PCM_STATE_RUNNING)
-    snd_pcm_drop (d_pcm_handle);
-  
   bool special_case = nchan == 1 && d_special_case_mono_to_stereo;
   if (special_case)
     nchan = 2;
@@ -238,7 +232,6 @@ audio_alsa_sink::check_topology (int ninputs, int noutputs)
 
   if (err < 0){
     output_error_msg ("set_channels failed", err);
-    d_change_in_progress = false;
     return false;
   }
 
@@ -246,7 +239,6 @@ audio_alsa_sink::check_topology (int ninputs, int noutputs)
   err = snd_pcm_hw_params(d_pcm_handle, d_hw_params);
   if (err < 0){
     output_error_msg ("snd_pcm_hw_params failed", err);
-    d_change_in_progress = false;
     return false;
   }
 
@@ -297,7 +289,6 @@ audio_alsa_sink::check_topology (int ninputs, int noutputs)
   default:
     assert (0);
   }
-  d_change_in_progress = false;
   return true;
 }
 
@@ -496,13 +487,6 @@ audio_alsa_sink::write_buffer (const void *vbuffer,
 {
   const unsigned char *buffer = (const unsigned char *) vbuffer;
 
-  int change_counter = 10;
-  while (d_change_in_progress == true && change_counter >= 0) {
-    change_counter--;
-    usleep(10000);
-  }
-  d_change_in_progress = false;
-	
   while (nframes > 0){
     int r = snd_pcm_writei (d_pcm_handle, buffer, nframes);
     if (r == -EAGAIN)
diff --git a/gr-audio-alsa/src/audio_alsa_sink.h b/gr-audio-alsa/src/audio_alsa_sink.h
index 811cc6c8c..f3007f60f 100644
--- a/gr-audio-alsa/src/audio_alsa_sink.h
+++ b/gr-audio-alsa/src/audio_alsa_sink.h
@@ -83,7 +83,6 @@ class audio_alsa_sink : public gr_sync_block {
   // random stats
   int			d_nunderuns;		// count of underruns
   int			d_nsuspends;		// count of suspends
-  bool                  d_change_in_progress;   // Topology change in progress--used as spinlock for write_buffer
   bool			d_ok_to_block;      // defaults to "true", controls blocking/non-block I/O
 
   void output_error_msg (const char *msg, int err);
-- 
cgit 


From 64ee9a2973e6c217c54f8cb0433ab24b0e52e2cc Mon Sep 17 00:00:00 2001
From: Tom Rondeau
Date: Wed, 22 Dec 2010 17:41:30 -0500
Subject: A new patch for fixing the alsa restart issue. Submitted by Volker
 Schroer.

---
 gr-audio-alsa/src/audio_alsa_sink.cc | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/gr-audio-alsa/src/audio_alsa_sink.cc b/gr-audio-alsa/src/audio_alsa_sink.cc
index c28e23fea..d44a93b3f 100644
--- a/gr-audio-alsa/src/audio_alsa_sink.cc
+++ b/gr-audio-alsa/src/audio_alsa_sink.cc
@@ -221,9 +221,15 @@ audio_alsa_sink::check_topology (int ninputs, int noutputs)
   int nchan = ninputs;
   int err;
 
-  // FIXME check_topology may be called more than once.
+  // Check the state of the stream
   // Ensure that the pcm is in a state where we can still mess with the hw_params
-
+  snd_pcm_state_t state;
+  state=snd_pcm_state(d_pcm_handle);
+  if ( state== SND_PCM_STATE_RUNNING)
+    return true;  // If stream is running, don't change any parameters
+  else if(state == SND_PCM_STATE_XRUN )
+    snd_pcm_prepare ( d_pcm_handle ); // Prepare stream on underrun, and we can set parameters;
+  
   bool special_case = nchan == 1 && d_special_case_mono_to_stereo;
   if (special_case)
     nchan = 2;
-- 
cgit