virtual HRESULT RenderAudioSamples (bool preroll)
  {
    guint8 *ptr;
    gint seg;
    gint len;
    gint bpf;
    guint written, written_sum;
    HRESULT res;

    GST_LOG_OBJECT (m_ringbuffer->sink, "Writing audio samples (preroll: %d)",
        preroll);

    if (!gst_audio_ring_buffer_prepare_read (GST_AUDIO_RING_BUFFER_CAST
            (m_ringbuffer), &seg, &ptr, &len)) {
      GST_WARNING_OBJECT (m_ringbuffer->sink, "No segment available");
      return E_FAIL;
    }

    bpf =
        GST_AUDIO_INFO_BPF (&GST_AUDIO_RING_BUFFER_CAST (m_ringbuffer)->
        spec.info);
    len /= bpf;
    GST_LOG_OBJECT (m_ringbuffer->sink,
        "Write audio samples: %p size %d segment: %d", ptr, len, seg);

    written_sum = 0;
    do {
      res =
          m_ringbuffer->output->output->ScheduleAudioSamples (ptr, len,
          0, 0, &written);
      len -= written;
      ptr += written * bpf;
      written_sum += written;
    } while (len > 0 && res == S_OK);

    GST_LOG_OBJECT (m_ringbuffer->sink, "Wrote %u samples: 0x%08x", written_sum,
        res);

    gst_audio_ring_buffer_clear (GST_AUDIO_RING_BUFFER_CAST (m_ringbuffer),
        seg);
    gst_audio_ring_buffer_advance (GST_AUDIO_RING_BUFFER_CAST (m_ringbuffer),
        1);

    return res;
  }
static GstAudioRingBuffer *
gst_decklink_audio_sink_create_ringbuffer (GstAudioBaseSink * absink)
{
  GstAudioRingBuffer *ret;

  GST_DEBUG_OBJECT (absink, "Creating ringbuffer");

  ret =
      GST_AUDIO_RING_BUFFER_CAST (g_object_new
      (GST_TYPE_DECKLINK_AUDIO_SINK_RING_BUFFER, NULL));

  GST_DECKLINK_AUDIO_SINK_RING_BUFFER_CAST (ret)->sink =
      (GstDecklinkAudioSink *) gst_object_ref (absink);

  return ret;
}
Beispiel #3
0
/* this is the callback of jack. This should RT-safe.
 */
static int
jack_process_cb (jack_nframes_t nframes, void *arg)
{
  GstJackAudioSink *sink;
  GstAudioRingBuffer *buf;
  gint readseg, len;
  guint8 *readptr;
  gint i, j, flen, channels;
  sample_t *data;

  buf = GST_AUDIO_RING_BUFFER_CAST (arg);
  sink = GST_JACK_AUDIO_SINK (GST_OBJECT_PARENT (buf));

  channels = GST_AUDIO_INFO_CHANNELS (&buf->spec.info);

  /* get target buffers */
  for (i = 0; i < channels; i++) {
    sink->buffers[i] =
        (sample_t *) jack_port_get_buffer (sink->ports[i], nframes);
  }

  if (gst_audio_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_audio_ring_buffer_clear (buf, readseg);

    /* we wrote one segment */
    gst_audio_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;
  }
}