Removing warnings in portaudio source/sink.
[debian/gnuradio] / gr-audio-portaudio / src / audio_portaudio_source.cc
index 653c16e023b0f3054f87c529e71e3688060f84d8..e508fda22f6d1aa8f708459465654b92439ac6e5 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2006 Free Software Foundation, Inc.
+ * Copyright 2006,2010 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -32,9 +32,9 @@
 #include <unistd.h>
 #include <stdexcept>
 #include <gri_portaudio.h>
-#include <omnithread.h>
+#include <string.h>
 
-#define        LOGGING 0               // define to 0 or 1
+//#define      LOGGING 0               // define to 0 or 1
 
 #define SAMPLE_FORMAT          paFloat32
 typedef float sample_t;
@@ -83,36 +83,35 @@ portaudio_source_callback (const void *inputBuffer,
   int nframes_room = self->d_writer->space_available() / nchan;
 
   if (nframes_to_copy <= nframes_room){  // We've got room for the data ..
-    if (LOGGING)
-      self->d_log->printf("PAsrc  cb: f/b = %4ld\n", framesPerBuffer);
+    //if (LOGGING)
+    //  self->d_log->printf("PAsrc  cb: f/b = %4ld\n", framesPerBuffer);
 
     // copy from input buffer to ringbuffer
-    memcpy(self->d_writer->write_pointer(),
-          inputBuffer,
-          nframes_to_copy * nchan * sizeof(sample_t));
-    self->d_writer->update_write_pointer(nframes_to_copy * nchan);
+    {
+      gruel::scoped_lock(d_ringbuffer_mutex);
+
+      memcpy(self->d_writer->write_pointer(),
+            inputBuffer,
+            nframes_to_copy * nchan * sizeof(sample_t));
+      self->d_writer->update_write_pointer(nframes_to_copy * nchan);
         
-    // Tell the source thread there is new data in the ringbuffer.
-    self->d_ringbuffer_ready.post();
+      // Tell the source thread there is new data in the ringbuffer.
+      self->d_ringbuffer_ready = true;
+    }
+
+    self->d_ringbuffer_cond.notify_one();
     return paContinue;
   }
 
   else {                       // overrun
-    if (LOGGING)
-      self->d_log->printf("PAsrc  cb: f/b = %4ld OVERRUN\n", framesPerBuffer);
-
     self->d_noverruns++;
-    ::write(2, "aO", 2);       // FIXME change to non-blocking call
-
-#if 0
-    // copy any frames that will fit
-    memcpy(self->d_writer->write_pointer(),
-          inputBuffer,
-          nframes_room * nchan * sizeof(sample_t));
-    self->d_writer->update_write_pointer(nframes_room * nchan);
-#endif  
+    ssize_t r = ::write(2, "aO", 2);   // FIXME change to non-blocking call
+    if(r == -1) {
+      perror("audio_portaudio_source::portaudio_source_callback write error to stderr.");
+    }
 
-    self->d_ringbuffer_ready.post();  // Tell the sink to get going!
+    self->d_ringbuffer_ready = false;
+    self->d_ringbuffer_cond.notify_one();  // Tell the sink to get going!
     return paContinue;
   }
 }
@@ -123,7 +122,7 @@ portaudio_source_callback (const void *inputBuffer,
 audio_portaudio_source_sptr
 audio_portaudio_make_source (int sampling_rate, const std::string dev, bool ok_to_block)
 {
-  return audio_portaudio_source_sptr (new audio_portaudio_source (sampling_rate,
+  return gnuradio::get_initial_sptr(new audio_portaudio_source (sampling_rate,
                                                                  dev, ok_to_block));
 }
 
@@ -139,12 +138,14 @@ audio_portaudio_source::audio_portaudio_source(int sampling_rate,
     d_verbose(gr_prefs::singleton()->get_bool("audio_portaudio", "verbose", false)),
     d_portaudio_buffer_size_frames(0),
     d_stream(0),
-    d_ringbuffer_ready(1, 1),          // binary semaphore
+    d_ringbuffer_mutex(),
+    d_ringbuffer_cond(),
+    d_ringbuffer_ready(false),
     d_noverruns(0)
 {
   memset(&d_input_parameters, 0, sizeof(d_input_parameters));
-  if (LOGGING)
-    d_log = gri_logger::singleton();
+  //if (LOGGING)
+  //  d_log = gri_logger::singleton();
 
   PaError            err;
   int                i, numDevices;
@@ -302,11 +303,13 @@ audio_portaudio_source::work (int noutput_items,
       if (k > 0)               // If we've produced anything so far, return that
        return k;
 
-      if (d_ok_to_block){
-       d_ringbuffer_ready.wait();      // block here, then try again
+      if (d_ok_to_block) {
+       gruel:: scoped_lock guard(d_ringbuffer_mutex);
+       while (d_ringbuffer_ready == false)
+         d_ringbuffer_cond.wait(guard);        // block here, then try again
        continue;
       }
-
+      
       assert(k == 0);
 
       // There's no data and we're not allowed to block.
@@ -319,27 +322,38 @@ audio_portaudio_source::work (int noutput_items,
       // FIXME We'll fill with zeros for now.  Yes, it will "click"...
 
       // Fill with some frames of zeros
-      int nf = std::min(noutput_items - k, (int) d_portaudio_buffer_size_frames);
-      for (int i = 0; i < nf; i++){
-       for (unsigned int c = 0; c < nchan; c++){
-         out[c][k + i] = 0;
+      {
+       gruel::scoped_lock guard(d_ringbuffer_mutex);
+
+       int nf = std::min(noutput_items - k, (int) d_portaudio_buffer_size_frames);
+       for (int i = 0; i < nf; i++){
+         for (unsigned int c = 0; c < nchan; c++){
+           out[c][k + i] = 0;
+         }
        }
+       k += nf;
+
+       d_ringbuffer_ready = false;
+       return k;
       }
-      k += nf;
-      return k;
     }
 
     // We can read the smaller of the request and what's in the buffer.
-    int nf = std::min(noutput_items - k, nframes);
+    {
+      gruel::scoped_lock guard(d_ringbuffer_mutex);
 
-    const float *p = (const float *) d_reader->read_pointer();
-    for (int i = 0; i < nf; i++){
-      for (unsigned int c = 0; c < nchan; c++){
-       out[c][k + i] = *p++;
+      int nf = std::min(noutput_items - k, nframes);
+      
+      const float *p = (const float *) d_reader->read_pointer();
+      for (int i = 0; i < nf; i++){
+       for (unsigned int c = 0; c < nchan; c++){
+         out[c][k + i] = *p++;
+       }
       }
+      d_reader->update_read_pointer(nf * nchan);
+      k += nf;
+      d_ringbuffer_ready = false;
     }
-    d_reader->update_read_pointer(nf * nchan);
-    k += nf;
   }
 
   return k;  // tell how many we actually did