commit-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Commit-gnuradio] [gnuradio] 01/12: Support for >1 jack port, various si


From: git
Subject: [Commit-gnuradio] [gnuradio] 01/12: Support for >1 jack port, various sizes of jack buffers
Date: Thu, 16 Jan 2014 20:33:24 +0000 (UTC)

This is an automated email from the git hooks/post-receive script.

jcorgan pushed a commit to branch master
in repository gnuradio.

commit 95a88be60209a04d37b062cc5548e3d123d9a595
Author: Steve Haynal <address@hidden>
Date:   Mon Dec 9 17:01:00 2013 -0800

    Support for >1 jack port, various sizes of jack buffers
---
 gr-audio/lib/jack/jack_sink.cc   | 111 +++++++++++++++++++++++---------------
 gr-audio/lib/jack/jack_sink.h    |   6 ++-
 gr-audio/lib/jack/jack_source.cc | 112 ++++++++++++++++++++++++---------------
 gr-audio/lib/jack/jack_source.h  |   6 ++-
 4 files changed, 145 insertions(+), 90 deletions(-)

diff --git a/gr-audio/lib/jack/jack_sink.cc b/gr-audio/lib/jack/jack_sink.cc
index c47c37a..ed3f63b 100644
--- a/gr-audio/lib/jack/jack_sink.cc
+++ b/gr-audio/lib/jack/jack_sink.cc
@@ -67,16 +67,19 @@ namespace gr {
       jack_sink *self = (jack_sink *)arg;
       unsigned int read_size = nframes*sizeof(sample_t);
 
-      if(jack_ringbuffer_read_space(self->d_ringbuffer) < read_size) {
-        self->d_nunderuns++;
-        // FIXME: move this fputs out, we shouldn't use blocking calls in 
process()
-        fputs("jU", stderr);
-        return 0;
-      }
+      for(int i = 0; i < self->d_portcount; i++) {
 
-      char *buffer = (char *)jack_port_get_buffer(self->d_jack_output_port, 
nframes);
+        if(jack_ringbuffer_read_space(self->d_ringbuffer[i]) < read_size) {
+          self->d_nunderuns++;
+          // FIXME: move this fputs out, we shouldn't use blocking calls in 
process()
+          fputs("jU", stderr);
+          return 0;
+        }
 
-      jack_ringbuffer_read(self->d_ringbuffer, buffer, read_size);
+        char *buffer = (char 
*)jack_port_get_buffer(self->d_jack_output_port[i], nframes);
+
+        jack_ringbuffer_read(self->d_ringbuffer[i], buffer, read_size);
+      }
 
 #ifndef NO_PTHREAD
       // Tell the sink thread there is room in the ringbuffer.
@@ -105,7 +108,9 @@ namespace gr {
         d_device_name(device_name.empty() ? default_device_name() : 
device_name),
         d_ok_to_block(ok_to_block),
         d_jack_client(0),
-        d_ringbuffer(0),
+        d_portcount(0),
+        d_jack_output_port(),
+        d_ringbuffer(),
         d_nunderuns(0)
     {
 #ifndef NO_PTHREAD
@@ -135,22 +140,15 @@ namespace gr {
 
       //jack_on_shutdown (d_jack_client, &jack_shutdown, (void*)this);
 
-      d_jack_output_port =
-        jack_port_register(d_jack_client, "out",
-                           JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
-
 
       d_jack_buffer_size = jack_get_buffer_size(d_jack_client);
 
       set_output_multiple(d_jack_buffer_size);
 
-      d_ringbuffer =
-        jack_ringbuffer_create(N_BUFFERS*d_jack_buffer_size*sizeof(sample_t));
-      if(d_ringbuffer == NULL)
-        bail("jack_ringbuffer_create failed", 0);
 
       assert(sizeof(float)==sizeof(sample_t));
-      set_input_signature(io_signature::make(1, 1, sizeof(sample_t)));
+      // Real number of outputs is set in check_topology
+      set_input_signature(io_signature::make(1, MAX_PORTS, sizeof(sample_t)));
 
       jack_nframes_t sample_rate = jack_get_sample_rate(d_jack_client);
 
@@ -164,9 +162,25 @@ namespace gr {
     bool
     jack_sink::check_topology (int ninputs, int noutputs)
     {
-      if(ninputs != 1)
+      if(ninputs > MAX_PORTS)
         return false;
 
+      d_portcount = ninputs;  // # of channels we're really using
+
+      // Create ports and ringbuffers
+      for(int i = 0; i < d_portcount; i++) {
+        std::string portname("out" + boost::to_string(i));
+
+        d_jack_output_port[i] =
+          jack_port_register(d_jack_client, portname.c_str(),
+                            JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
+
+        d_ringbuffer[i] =
+          
jack_ringbuffer_create(N_BUFFERS*d_jack_buffer_size*sizeof(sample_t));
+        if(d_ringbuffer[i] == NULL)
+          bail("jack_ringbuffer_create failed", 0);
+      }
+
       // tell the JACK server that we are ready to roll
       if(jack_activate (d_jack_client))
         throw std::runtime_error("audio_jack_sink");
@@ -177,7 +191,9 @@ namespace gr {
     jack_sink::~jack_sink()
     {
       jack_client_close(d_jack_client);
-      jack_ringbuffer_free(d_ringbuffer);
+
+      for(int i = 0; i < d_portcount; i++)
+        jack_ringbuffer_free(d_ringbuffer[i]);
     }
 
     int
@@ -185,39 +201,48 @@ namespace gr {
                     gr_vector_const_void_star &input_items,
                     gr_vector_void_star &output_items)
     {
-      // write_size and work_size are in bytes
-      int work_size = noutput_items*sizeof(sample_t);
-      unsigned int write_size;
 
-      while(work_size > 0) {
-        unsigned int write_space;    // bytes
+      const float **in = (const float **)&input_items[0];
+
+      for(int i = 0; i < d_portcount; i++) {
+
+        int k = 0;
+
+        // write_size and work_size are in bytes
+        int work_size = noutput_items*sizeof(sample_t);
+        unsigned int write_size;
+
+        while(work_size > 0) {
+          unsigned int write_space;    // bytes
 
 #ifdef NO_PTHREAD
-        while((write_space=jack_ringbuffer_write_space(d_ringbuffer)) <
-              d_jack_buffer_size*sizeof(sample_t)) {
-          
usleep(1000000*((d_jack_buffer_size-write_space/sizeof(sample_t))/d_sampling_rate));
-        }
+          while((write_space=jack_ringbuffer_write_space(d_ringbuffer[i])) <
+                d_jack_buffer_size*sizeof(sample_t)) {
+            
usleep(1000000*((d_jack_buffer_size-write_space/sizeof(sample_t))/d_sampling_rate));
+          }
 #else
-        // JACK actually requires POSIX
+          // JACK actually requires POSIX
 
-        pthread_mutex_lock(&d_jack_process_lock);
-        while((write_space = jack_ringbuffer_write_space(d_ringbuffer)) <
-              d_jack_buffer_size*sizeof(sample_t)) {
+          pthread_mutex_lock(&d_jack_process_lock);
+          while((write_space = jack_ringbuffer_write_space(d_ringbuffer[i])) <
+                d_jack_buffer_size*sizeof(sample_t)) {
 
-          // wait until jack_sink_process() signals more room
-          pthread_cond_wait(&d_ringbuffer_ready, &d_jack_process_lock);
-        }
-        pthread_mutex_unlock(&d_jack_process_lock);
+            // wait until jack_sink_process() signals more room
+            pthread_cond_wait(&d_ringbuffer_ready, &d_jack_process_lock);
+          }
+          pthread_mutex_unlock(&d_jack_process_lock);
 #endif
 
-        write_space -= write_space%(d_jack_buffer_size*sizeof(sample_t));
-        write_size = std::min(write_space, (unsigned int)work_size);
+          write_space -= write_space%(d_jack_buffer_size*sizeof(sample_t));
+          write_size = std::min(write_space, (unsigned int)work_size);
 
-        if(jack_ringbuffer_write(d_ringbuffer, (char *) input_items[0],
-                                 write_size) < write_size) {
-          bail("jack_ringbuffer_write failed", 0);
+          if(jack_ringbuffer_write(d_ringbuffer[i], (char *) &(in[i][k]),
+                                   write_size) < write_size) {
+            bail("jack_ringbuffer_write failed", 0);
+          }
+          work_size -= write_size;
+          k += write_size/sizeof(sample_t);
         }
-        work_size -= write_size;
       }
 
       return noutput_items;
diff --git a/gr-audio/lib/jack/jack_sink.h b/gr-audio/lib/jack/jack_sink.h
index de34120..9c97b34 100644
--- a/gr-audio/lib/jack/jack_sink.h
+++ b/gr-audio/lib/jack/jack_sink.h
@@ -55,8 +55,10 @@ namespace gr {
       bool         d_ok_to_block;
 
       jack_client_t     *d_jack_client;
-      jack_port_t       *d_jack_output_port;
-      jack_ringbuffer_t *d_ringbuffer;
+      static const int MAX_PORTS = 10; 
+      int d_portcount;
+      jack_port_t       *d_jack_output_port[MAX_PORTS];
+      jack_ringbuffer_t *d_ringbuffer[MAX_PORTS];
       jack_nframes_t     d_jack_buffer_size;
       pthread_cond_t     d_ringbuffer_ready;
       pthread_mutex_t    d_jack_process_lock;
diff --git a/gr-audio/lib/jack/jack_source.cc b/gr-audio/lib/jack/jack_source.cc
index a897785..d2a1698 100644
--- a/gr-audio/lib/jack/jack_source.cc
+++ b/gr-audio/lib/jack/jack_source.cc
@@ -67,16 +67,18 @@ namespace gr {
       jack_source *self = (jack_source *)arg;
       unsigned int write_size = nframes*sizeof(sample_t);
       
-      if(jack_ringbuffer_write_space (self->d_ringbuffer) < write_size) {
-        self->d_noverruns++;
-        // FIXME: move this fputs out, we shouldn't use blocking calls in 
process()
-        fputs ("jO", stderr);
-        return 0;
-      }
-
-      char *buffer = (char *)jack_port_get_buffer(self->d_jack_input_port, 
nframes);
+      for(int i = 0; i < self->d_portcount; i++) {
+        if(jack_ringbuffer_write_space (self->d_ringbuffer[i]) < write_size) {
+          self->d_noverruns++;
+          // FIXME: move this fputs out, we shouldn't use blocking calls in 
process()
+          fputs ("jO", stderr);
+          return 0;
+        }
+        
+        char *buffer = (char 
*)jack_port_get_buffer(self->d_jack_input_port[i], nframes);
 
-      jack_ringbuffer_write (self->d_ringbuffer, buffer, write_size);
+        jack_ringbuffer_write (self->d_ringbuffer[i], buffer, write_size);
+      }
 
 #ifndef NO_PTHREAD
       // Tell the source thread there is data in the ringbuffer.
@@ -106,7 +108,9 @@ namespace gr {
         d_device_name(device_name.empty() ? default_device_name() : 
device_name),
         d_ok_to_block(ok_to_block),
         d_jack_client(0),
-        d_ringbuffer(0),
+        d_portcount(0),
+        d_jack_input_port(),        
+        d_ringbuffer(),
         d_noverruns(0)
     {
 #ifndef NO_PTHREAD
@@ -136,20 +140,12 @@ namespace gr {
 
       //jack_on_shutdown (d_jack_client, &jack_shutdown, (void*)this);
 
-      d_jack_input_port = jack_port_register(d_jack_client, "in",
-                                             JACK_DEFAULT_AUDIO_TYPE,
-                                             JackPortIsInput, 0);
-
       d_jack_buffer_size = jack_get_buffer_size(d_jack_client);
 
       set_output_multiple(d_jack_buffer_size);
 
-      d_ringbuffer = 
jack_ringbuffer_create(N_BUFFERS*d_jack_buffer_size*sizeof(sample_t));
-      if(d_ringbuffer == NULL)
-        bail("jack_ringbuffer_create failed", 0);
-
       assert(sizeof(float)==sizeof(sample_t));
-      set_output_signature(io_signature::make(1, 1, sizeof(sample_t)));
+      set_output_signature(io_signature::make(1, MAX_PORTS, sizeof(sample_t)));
 
       jack_nframes_t sample_rate = jack_get_sample_rate(d_jack_client);
 
@@ -163,6 +159,24 @@ namespace gr {
     bool
     jack_source::check_topology(int ninputs, int noutputs)
     {
+
+      if(noutputs > MAX_PORTS)
+        return false;
+
+      d_portcount = noutputs;  // # of channels we're really using
+
+      // Create ports and ringbuffers
+      for(int i = 0; i < d_portcount; i++) {
+        std::string portname("in" + boost::to_string(i));
+
+        d_jack_input_port[i] = jack_port_register(d_jack_client, 
portname.c_str(),
+          JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
+
+        d_ringbuffer[i] = 
jack_ringbuffer_create(N_BUFFERS*d_jack_buffer_size*sizeof(sample_t));
+        if(d_ringbuffer[i] == NULL)
+          bail("jack_ringbuffer_create failed", 0);
+      }
+
       // tell the JACK server that we are ready to roll
       if(jack_activate (d_jack_client))
         throw std::runtime_error("audio_jack_source");
@@ -173,7 +187,10 @@ namespace gr {
     jack_source::~jack_source()
     {
       jack_client_close(d_jack_client);
-      jack_ringbuffer_free(d_ringbuffer);
+
+
+      for(int i = 0; i < d_portcount; i++)
+        jack_ringbuffer_free(d_ringbuffer[i]);
     }
 
     int
@@ -181,42 +198,51 @@ namespace gr {
                       gr_vector_const_void_star &input_items,
                       gr_vector_void_star &output_items)
     {
-      // read_size and work_size are in bytes
-      unsigned int read_size;
+
+      const float **out = (const float **)&output_items[0];
 
       // Minimize latency
       noutput_items = std::min (noutput_items, (int)d_jack_buffer_size);
 
-      int work_size = noutput_items*sizeof(sample_t);
+      for(int i = 0; i < d_portcount; i++) {
 
-      while(work_size > 0) {
-        unsigned int read_space;    // bytes
+        int k = 0;
+
+        // read_size and work_size are in bytes
+        unsigned int read_size;
+
+        int work_size = noutput_items*sizeof(sample_t);
+
+        while(work_size > 0) {
+          unsigned int read_space;    // bytes
 
 #ifdef NO_PTHREAD
-        while((read_space=jack_ringbuffer_read_space (d_ringbuffer)) <
-              d_jack_buffer_size*sizeof(sample_t)) {
-          
usleep(1000000*((d_jack_buffer_size-read_space/sizeof(sample_t))/d_sampling_rate));
-        }
+          while((read_space=jack_ringbuffer_read_space (d_ringbuffer[i])) <
+                d_jack_buffer_size*sizeof(sample_t)) {
+            
usleep(1000000*((d_jack_buffer_size-read_space/sizeof(sample_t))/d_sampling_rate));
+          }
 #else
 
-        // JACK actually requires POSIX
-        pthread_mutex_lock(&d_jack_process_lock);
-        while((read_space = jack_ringbuffer_read_space(d_ringbuffer)) <
-              d_jack_buffer_size*sizeof(sample_t)) {
-          // wait until jack_source_process() signals more data
-          pthread_cond_wait(&d_ringbuffer_ready, &d_jack_process_lock);
-        }
-        pthread_mutex_unlock(&d_jack_process_lock);
+          // JACK actually requires POSIX
+          pthread_mutex_lock(&d_jack_process_lock);
+          while((read_space = jack_ringbuffer_read_space(d_ringbuffer[i])) <
+                d_jack_buffer_size*sizeof(sample_t)) {
+            // wait until jack_source_process() signals more data
+            pthread_cond_wait(&d_ringbuffer_ready, &d_jack_process_lock);
+          }
+          pthread_mutex_unlock(&d_jack_process_lock);
 #endif
 
-        read_space -= read_space%(d_jack_buffer_size*sizeof(sample_t));
-        read_size = std::min(read_space, (unsigned int)work_size);
+          read_space -= read_space%(d_jack_buffer_size*sizeof(sample_t));
+          read_size = std::min(read_space, (unsigned int)work_size);
 
-        if(jack_ringbuffer_read(d_ringbuffer, (char *) output_items[0],
-                                read_size) < read_size) {
-          bail("jack_ringbuffer_read failed", 0);
+          if(jack_ringbuffer_read(d_ringbuffer[i], (char *) &(out[i][k]),
+                                  read_size) < read_size) {
+            bail("jack_ringbuffer_read failed", 0);
+          }
+          work_size -= read_size;
+          k += read_size/sizeof(sample_t);
         }
-        work_size -= read_size;
       }
 
       return noutput_items;
diff --git a/gr-audio/lib/jack/jack_source.h b/gr-audio/lib/jack/jack_source.h
index 6651392..2f7a016 100644
--- a/gr-audio/lib/jack/jack_source.h
+++ b/gr-audio/lib/jack/jack_source.h
@@ -55,8 +55,10 @@ namespace gr {
       bool         d_ok_to_block;
 
       jack_client_t     *d_jack_client;
-      jack_port_t       *d_jack_input_port;
-      jack_ringbuffer_t *d_ringbuffer;
+      static const int MAX_PORTS = 10; 
+      int d_portcount;      
+      jack_port_t       *d_jack_input_port[MAX_PORTS];
+      jack_ringbuffer_t *d_ringbuffer[MAX_PORTS];
       jack_nframes_t     d_jack_buffer_size;
       pthread_cond_t     d_ringbuffer_ready;
       pthread_mutex_t    d_jack_process_lock;



reply via email to

[Prev in Thread] Current Thread [Next in Thread]