/* this is the callback of jack. This should be RT-safe. * Writes samples from the jack input port's buffer to the gst ring buffer. */ static int jack_process_cb (jack_nframes_t nframes, void *arg) { GstJackAudioSrc *src; GstRingBuffer *buf; GstJackRingBuffer *abuf; gint len, givenLen; guint8 *writeptr, *dataStart; gint writeseg; gint channels, i, j; sample_t **buffers, *data; buf = GST_RING_BUFFER_CAST (arg); abuf = GST_JACK_RING_BUFFER_CAST (arg); src = GST_JACK_AUDIO_SRC (GST_OBJECT_PARENT (buf)); channels = buf->spec.channels; len = sizeof (sample_t) * nframes * channels; /* alloc pointers to samples */ buffers = g_alloca (sizeof (sample_t *) * channels); data = g_alloca (len); /* get input buffers */ for (i = 0; i < channels; i++) buffers[i] = (sample_t *) jack_port_get_buffer (src->ports[i], nframes); //writeptr = data; dataStart = (guint8 *) data; /* the samples in the jack input buffers have to be interleaved into the * ringbuffer */ for (i = 0; i < nframes; ++i) for (j = 0; j < channels; ++j) *data++ = buffers[j][i]; if (gst_ring_buffer_prepare_read (buf, &writeseg, &writeptr, &givenLen)) { memcpy (writeptr, (char *) dataStart, givenLen); GST_DEBUG ("copy %d frames: %p, %d bytes, %d channels", nframes, writeptr, len / channels, channels); /* clear written samples in the ringbuffer */ // gst_ring_buffer_clear(buf, 0); /* we wrote one segment */ gst_ring_buffer_advance (buf, 1); } return 0; }
/* this is the callback of jack. This should be RT-safe. * Writes samples from the jack input port's buffer to the gst ring buffer. */ static int jack_process_cb (jack_nframes_t nframes, void *arg) { GstJackAudioSrc *src; GstRingBuffer *buf; gint len; guint8 *writeptr; gint writeseg; gint channels, i, j, flen; sample_t *data; buf = GST_RING_BUFFER_CAST (arg); src = GST_JACK_AUDIO_SRC (GST_OBJECT_PARENT (buf)); channels = buf->spec.channels; /* get input buffers */ for (i = 0; i < channels; i++) src->buffers[i] = (sample_t *) jack_port_get_buffer (src->ports[i], nframes); if (gst_ring_buffer_prepare_read (buf, &writeseg, &writeptr, &len)) { flen = len / channels; /* the number of samples must be exactly the segment size */ if (nframes * sizeof (sample_t) != flen) goto wrong_size; /* the samples in the jack input buffers have to be interleaved into the * ringbuffer */ data = (sample_t *) writeptr; for (i = 0; i < nframes; ++i) for (j = 0; j < channels; ++j) *data++ = src->buffers[j][i]; GST_DEBUG ("copy %d frames: %p, %d bytes, %d channels", nframes, writeptr, len / channels, channels); /* we wrote one segment */ gst_ring_buffer_advance (buf, 1); } return 0; /* ERRORS */ wrong_size: { GST_ERROR_OBJECT (src, "nbytes (%d) != flen (%d)", (gint) (nframes * sizeof (sample_t)), flen); return 1; } }
/* this is the callback of jack. This should RT-safe. */ static int jack_process_cb (jack_nframes_t nframes, void *arg) { GstJackAudioSink *sink; GstRingBuffer *buf; gint readseg, len; guint8 *readptr; gint i, j, flen, channels; sample_t *data; buf = GST_RING_BUFFER_CAST (arg); sink = GST_JACK_AUDIO_SINK (GST_OBJECT_PARENT (buf)); channels = buf->spec.channels; /* get target buffers */ for (i = 0; i < channels; i++) { sink->buffers[i] = (sample_t *) jack_port_get_buffer (sink->ports[i], nframes); } if (gst_ring_buffer_prepare_read (buf, &readseg, &readptr, &len)) { flen = len / channels; /* the number of samples must be exactly the segment size */ if (nframes * sizeof (sample_t) != flen) goto wrong_size; GST_DEBUG_OBJECT (sink, "copy %d frames: %p, %d bytes, %d channels", nframes, readptr, flen, channels); data = (sample_t *) readptr; /* the samples in the ringbuffer have the channels interleaved, we need to * deinterleave into the jack target buffers */ for (i = 0; i < nframes; i++) { for (j = 0; j < channels; j++) { sink->buffers[j][i] = *data++; } } /* clear written samples in the ringbuffer */ gst_ring_buffer_clear (buf, readseg); /* we wrote one segment */ gst_ring_buffer_advance (buf, 1); } else { GST_DEBUG_OBJECT (sink, "write %d frames silence", nframes); /* We are not allowed to read from the ringbuffer, write silence to all * jack output buffers */ for (i = 0; i < channels; i++) { memset (sink->buffers[i], 0, nframes * sizeof (sample_t)); } } return 0; /* ERRORS */ wrong_size: { GST_ERROR_OBJECT (sink, "nbytes (%d) != flen (%d)", (gint) (nframes * sizeof (sample_t)), flen); return 1; } }