summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--config/grc_gr_audio_portaudio.m41
-rw-r--r--gnuradio-core/src/lib/io/Makefile.am2
-rw-r--r--gnuradio-core/src/lib/io/gri_logger.cc178
-rw-r--r--gnuradio-core/src/lib/io/gri_logger.h59
-rw-r--r--gr-audio-portaudio/src/Makefile.am1
-rw-r--r--gr-audio-portaudio/src/audio_portaudio_sink.cc67
-rw-r--r--gr-audio-portaudio/src/audio_portaudio_sink.h6
-rw-r--r--gr-audio-portaudio/src/audio_portaudio_source.cc82
-rw-r--r--gr-audio-portaudio/src/audio_portaudio_source.h13
9 files changed, 97 insertions, 312 deletions
diff --git a/config/grc_gr_audio_portaudio.m4 b/config/grc_gr_audio_portaudio.m4
index 08d71f8fb..ff551b38a 100644
--- a/config/grc_gr_audio_portaudio.m4
+++ b/config/grc_gr_audio_portaudio.m4
@@ -22,7 +22,6 @@ AC_DEFUN([GRC_GR_AUDIO_PORTAUDIO],[
dnl Don't do gr-audio-portaudio if gnuradio-core skipped
GRC_CHECK_DEPENDENCY(gr-audio-portaudio, gnuradio-core)
- GRC_CHECK_DEPENDENCY(gr-audio-portaudio, omnithread)
dnl If execution gets to here, $passed will be:
dnl with : if the --with code didn't error out
diff --git a/gnuradio-core/src/lib/io/Makefile.am b/gnuradio-core/src/lib/io/Makefile.am
index 9eacd137d..c52554645 100644
--- a/gnuradio-core/src/lib/io/Makefile.am
+++ b/gnuradio-core/src/lib/io/Makefile.am
@@ -39,7 +39,6 @@ libio_la_SOURCES = \
gr_oscope_guts.cc \
gr_oscope_sink_f.cc \
gr_oscope_sink_x.cc \
- gri_logger.cc \
i2c.cc \
i2c_bitbang.cc \
i2c_bbio.cc \
@@ -72,7 +71,6 @@ grinclude_HEADERS = \
gr_oscope_sink_f.h \
gr_oscope_sink_x.h \
gr_trigger_mode.h \
- gri_logger.h \
i2c.h \
i2c_bitbang.h \
i2c_bbio.h \
diff --git a/gnuradio-core/src/lib/io/gri_logger.cc b/gnuradio-core/src/lib/io/gri_logger.cc
deleted file mode 100644
index 473a7c5ed..000000000
--- a/gnuradio-core/src/lib/io/gri_logger.cc
+++ /dev/null
@@ -1,178 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2006,2009 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#if 0 // This needs reimplementation with boost threads and synchronization
-
-#include <gri_logger.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <stdexcept>
-#include <boost/weak_ptr.hpp>
-#include <string.h>
-
-
-/*
- * This class creates the thread that reads from the ringbuffer and
- * and writes to the file. This is opaque to the user.
- */
-class gri_log_poster : public omni_thread
-{
- FILE *d_fp;
- gr_buffer_sptr d_writer;
- gr_buffer_reader_sptr d_reader;
- omni_semaphore d_ringbuffer_ready;
- volatile bool d_time_to_die;
- volatile bool d_writer_overrun;
-
- virtual void* run_undetached(void * arg);
-
-public:
- gri_log_poster(const char *filename);
- ~gri_log_poster();
-
- void kill() { d_time_to_die = true; post(); }
- gr_buffer_sptr writer() const { return d_writer; }
- void post() { d_ringbuffer_ready.post(); }
- void note_writer_overrun() { d_writer_overrun = true; }
-};
-
-gri_log_poster::gri_log_poster(const char *filename)
- : omni_thread(),
- d_ringbuffer_ready(1, 1), // binary semaphore
- d_time_to_die(false),
- d_writer_overrun(false)
-{
- if ((d_fp = fopen(filename, "w")) == 0){
- perror (filename);
- throw std::runtime_error("can't open file");
- }
-
- // Create a 1MB buffer.
- d_writer = gr_make_buffer(1 * 1024 * 1024, sizeof(unsigned char));
- d_reader = gr_buffer_add_reader(d_writer, 0);
-
- start_undetached(); // start the thread
-}
-
-gri_log_poster::~gri_log_poster()
-{
- if (d_fp != 0){
- fclose(d_fp);
- d_fp = 0;
- }
-}
-
-/*
- * This is the body of the logging thread.
- */
-void *
-gri_log_poster::run_undetached(void *arg)
-{
- int nbytes;
-
- //fprintf(stderr, "Enter: run_undetached!\n");
-
- while (!d_time_to_die){
- while ((nbytes = d_reader->items_available()) > 0){
- fwrite(d_reader->read_pointer(), 1, nbytes, d_fp);
- d_reader->update_read_pointer(nbytes);
- }
- fflush(d_fp);
- d_ringbuffer_ready.wait();
-
- if (d_writer_overrun){
- fputs(">>>>> gri_logger: writer overrun. Info lost <<<<<\n", d_fp);
- d_writer_overrun = false;
- }
- }
-
- // fprintf(stderr, "Exit: run_undetached!\n");
- return 0;
-}
-
-// ------------------------------------------------------------------------
-
-static boost::weak_ptr<gri_logger> s_singleton; // weak pointer IQ test ;-)
-static omni_mutex s_singleton_mutex;
-
-gri_logger_sptr
-gri_logger::singleton()
-{
- omni_mutex_lock l(s_singleton_mutex);
- gri_logger_sptr r;
-
- if (r = s_singleton.lock())
- return r;
-
- r = gri_logger_sptr(new gri_logger("gri_logger.log"));
- s_singleton = r;
- return r;
-}
-
-
-gri_logger::gri_logger(const char *filename)
-{
- d_poster = new gri_log_poster(filename);
-}
-
-gri_logger::~gri_logger()
-{
- d_poster->kill();
- d_poster->join(NULL);
-}
-
-void
-gri_logger::write(const void *buf, size_t count)
-{
- omni_mutex_lock l(d_write_mutex);
- gr_buffer_sptr writer = d_poster->writer();
-
- // either write it all, or drop it on the ground
- if (count <= (size_t) writer->space_available()){
- memcpy(writer->write_pointer(), buf, count);
- writer->update_write_pointer(count);
- d_poster->post();
- }
- else {
- d_poster->note_writer_overrun();
- }
-}
-
-void
-gri_logger::printf(const char *format, ...)
-{
- va_list ap;
- char buf[4096];
- int n;
-
- va_start(ap, format);
- n = vsnprintf(buf, sizeof(buf), format, ap);
- va_end(ap);
- if (n > -1 && n < (ssize_t) sizeof(buf))
- write(buf, n);
-}
-
-#endif
diff --git a/gnuradio-core/src/lib/io/gri_logger.h b/gnuradio-core/src/lib/io/gri_logger.h
deleted file mode 100644
index 0a1414540..000000000
--- a/gnuradio-core/src/lib/io/gri_logger.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2006,2009 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-#ifndef INCLUDED_GRI_LOGGER_H
-#define INCLUDED_GRI_LOGGER_H
-
-#if 0 // This needs reimplementation with boost threads and synchronization
-
-#include <stddef.h>
-#include <gnuradio/omnithread.h>
-#include <gr_buffer.h>
-
-class gri_log_poster;
-class gri_logger;
-typedef boost::shared_ptr<gri_logger> gri_logger_sptr;
-
-
-/*!
- * \brief non-blocking logging to a file.
- *
- * In reality, this may block, but only for a bounded time.
- * Trust me, it's safe to use from portaudio and JACK callbacks.
- */
-class gri_logger
-{
- gri_log_poster *d_poster;
- omni_mutex d_write_mutex;
-
-public:
- static gri_logger_sptr singleton();
-
- gri_logger(const char *filename);
- ~gri_logger();
-
- void write(const void *buf, size_t count);
- void printf(const char *format, ...);
-};
-
-#endif
-
-#endif /* INCLUDED_GRI_LOGGER_H */
diff --git a/gr-audio-portaudio/src/Makefile.am b/gr-audio-portaudio/src/Makefile.am
index 20213d16b..1df6bbcea 100644
--- a/gr-audio-portaudio/src/Makefile.am
+++ b/gr-audio-portaudio/src/Makefile.am
@@ -46,7 +46,6 @@ libgnuradio_audio_portaudio_la_SOURCES = \
libgnuradio_audio_portaudio_la_LIBADD = \
$(GNURADIO_CORE_LA) \
- $(OMNITHREAD_LA) \
$(PORTAUDIO_LIBS)
libgnuradio_audio_portaudio_la_LDFLAGS = \
diff --git a/gr-audio-portaudio/src/audio_portaudio_sink.cc b/gr-audio-portaudio/src/audio_portaudio_sink.cc
index 2e48feb4a..65a38f911 100644
--- a/gr-audio-portaudio/src/audio_portaudio_sink.cc
+++ b/gr-audio-portaudio/src/audio_portaudio_sink.cc
@@ -32,7 +32,6 @@
#include <unistd.h>
#include <stdexcept>
#include <gri_portaudio.h>
-#include <gnuradio/omnithread.h>
#include <string.h>
//#define LOGGING 0 // define to 0 or 1
@@ -84,31 +83,33 @@ portaudio_sink_callback (const void *inputBuffer,
int navail_samples = self->d_reader->items_available();
- if (nreqd_samples <= navail_samples){ // We've got enough data...
- //if (LOGGING)
- // self->d_log->printf("PAsink cb: f/b = %4ld\n", framesPerBuffer);
- // copy from ringbuffer into output buffer
- memcpy(outputBuffer,
- self->d_reader->read_pointer(),
- nreqd_samples * sizeof(sample_t));
- self->d_reader->update_read_pointer(nreqd_samples);
-
+ if (nreqd_samples <= navail_samples) { // We've got enough data...
+ {
+ gruel::scoped_lock guard(self->d_ringbuffer_mutex);
+
+ memcpy(outputBuffer,
+ self->d_reader->read_pointer(),
+ nreqd_samples * sizeof(sample_t));
+ self->d_reader->update_read_pointer(nreqd_samples);
+
+ self->d_ringbuffer_ready = true;
+ }
+
// Tell the sink thread there is new room in the ringbuffer.
- self->d_ringbuffer_ready.post();
+ self->d_ringbuffer_cond.notify_one();
return paContinue;
}
else { // underrun
- //if (LOGGING)
- // self->d_log->printf("PAsink cb: f/b = %4ld UNDERRUN\n", framesPerBuffer);
-
self->d_nunderuns++;
::write(2, "aU", 2); // FIXME change to non-blocking call
// FIXME we should transfer what we've got and pad the rest
memset(outputBuffer, 0, nreqd_samples * sizeof(sample_t));
- self->d_ringbuffer_ready.post(); // Tell the sink to get going!
+ self->d_ringbuffer_ready = true;
+ self->d_ringbuffer_cond.notify_one(); // Tell the sink to get going!
+
return paContinue;
}
}
@@ -135,7 +136,9 @@ audio_portaudio_sink::audio_portaudio_sink(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_nunderuns(0)
{
memset(&d_output_parameters, 0, sizeof(d_output_parameters));
@@ -297,12 +300,17 @@ audio_portaudio_sink::work (int noutput_items,
const unsigned nchan = d_output_parameters.channelCount; // # of channels == samples/frame
int k;
- for (k = 0; k < noutput_items; ){
+ for (k = 0; k < noutput_items; ){
int nframes = d_writer->space_available() / nchan; // How much space in ringbuffer
if (nframes == 0){ // no room...
if (d_ok_to_block){
- d_ringbuffer_ready.wait(); // block here, then try again
+ {
+ gruel::scoped_lock guard(d_ringbuffer_mutex);
+ while (!d_ringbuffer_ready)
+ d_ringbuffer_cond.wait(guard);
+ }
+
continue;
}
else {
@@ -316,16 +324,21 @@ audio_portaudio_sink::work (int noutput_items,
}
// We can write the smaller of the request and the room we've got
- int nf = std::min(noutput_items - k, nframes);
-
- float *p = (float *) d_writer->write_pointer();
- for (int i = 0; i < nf; i++){
- for (unsigned int c = 0; c < nchan; c++){
- *p++ = in[c][k + i];
- }
+ {
+ gruel::scoped_lock guard(d_ringbuffer_mutex);
+
+ int nf = std::min(noutput_items - k, nframes);
+ float *p = (float *) d_writer->write_pointer();
+
+ for (int i = 0; i < nf; i++)
+ for (unsigned int c = 0; c < nchan; c++)
+ *p++ = in[c][k + i];
+
+ d_writer->update_write_pointer(nf * nchan);
+ k += nf;
+
+ d_ringbuffer_ready = false;
}
- d_writer->update_write_pointer(nf * nchan);
- k += nf;
}
return k; // tell how many we actually did
diff --git a/gr-audio-portaudio/src/audio_portaudio_sink.h b/gr-audio-portaudio/src/audio_portaudio_sink.h
index 1a0729799..71cbfcf9f 100644
--- a/gr-audio-portaudio/src/audio_portaudio_sink.h
+++ b/gr-audio-portaudio/src/audio_portaudio_sink.h
@@ -24,7 +24,7 @@
#include <gr_sync_block.h>
#include <gr_buffer.h>
-#include <gnuradio/omnithread.h>
+#include <gruel/thread.h>
#include <string>
#include <portaudio.h>
#include <stdexcept>
@@ -74,8 +74,10 @@ class audio_portaudio_sink : public gr_sync_block {
gr_buffer_sptr d_writer; // buffer used between work and callback
gr_buffer_reader_sptr d_reader;
- omni_semaphore d_ringbuffer_ready; // binary semaphore
+ gruel::mutex d_ringbuffer_mutex;
+ gruel::condition_variable d_ringbuffer_cond;
+ bool d_ringbuffer_ready;
// random stats
int d_nunderuns; // count of underruns
diff --git a/gr-audio-portaudio/src/audio_portaudio_source.cc b/gr-audio-portaudio/src/audio_portaudio_source.cc
index 9e883ad8a..484b7f1e5 100644
--- a/gr-audio-portaudio/src/audio_portaudio_source.cc
+++ b/gr-audio-portaudio/src/audio_portaudio_source.cc
@@ -32,7 +32,6 @@
#include <unistd.h>
#include <stdexcept>
#include <gri_portaudio.h>
-#include <gnuradio/omnithread.h>
#include <string.h>
//#define LOGGING 0 // define to 0 or 1
@@ -88,32 +87,28 @@ portaudio_source_callback (const void *inputBuffer,
// 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
-
- 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;
}
}
@@ -140,7 +135,9 @@ 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));
@@ -303,11 +300,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.
@@ -320,27 +319,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
diff --git a/gr-audio-portaudio/src/audio_portaudio_source.h b/gr-audio-portaudio/src/audio_portaudio_source.h
index 3102db739..31e70a127 100644
--- a/gr-audio-portaudio/src/audio_portaudio_source.h
+++ b/gr-audio-portaudio/src/audio_portaudio_source.h
@@ -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
*
@@ -24,11 +24,10 @@
#include <gr_sync_block.h>
#include <gr_buffer.h>
-#include <gnuradio/omnithread.h>
+#include <gruel/thread.h>
#include <string>
#include <portaudio.h>
#include <stdexcept>
-//#include <gri_logger.h>
class audio_portaudio_source;
typedef boost::shared_ptr<audio_portaudio_source> audio_portaudio_source_sptr;
@@ -74,11 +73,13 @@ class audio_portaudio_source : public gr_sync_block {
gr_buffer_sptr d_writer; // buffer used between work and callback
gr_buffer_reader_sptr d_reader;
- omni_semaphore d_ringbuffer_ready; // binary semaphore
+
+ gruel::mutex d_ringbuffer_mutex;
+ gruel::condition_variable d_ringbuffer_cond;
+ bool d_ringbuffer_ready;
// random stats
int d_noverruns; // count of overruns
- //gri_logger_sptr d_log; // handle to non-blocking logging instance
void output_error_msg (const char *msg, int err);
void bail (const char *msg, int err) throw (std::runtime_error);
@@ -87,7 +88,7 @@ class audio_portaudio_source : public gr_sync_block {
protected:
audio_portaudio_source (int sampling_rate, const std::string device_name,
- bool ok_to_block);
+ bool ok_to_block);
public:
~audio_portaudio_source ();