コード例 #1
0
ファイル: gstlevel.c プロジェクト: Lachann/gst-plugins-good
static void
gst_level_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstLevel *filter = GST_LEVEL (object);

  switch (prop_id) {
    case PROP_POST_MESSAGES:
      /* fall-through */
    case PROP_MESSAGE:
      filter->post_messages = g_value_get_boolean (value);
      break;
    case PROP_INTERVAL:
      filter->interval = g_value_get_uint64 (value);
      if (GST_AUDIO_INFO_RATE (&filter->info)) {
        filter->interval_frames =
            GST_CLOCK_TIME_TO_FRAMES (filter->interval,
            GST_AUDIO_INFO_RATE (&filter->info));
      }
      break;
    case PROP_PEAK_TTL:
      filter->decay_peak_ttl =
          gst_guint64_to_gdouble (g_value_get_uint64 (value));
      break;
    case PROP_PEAK_FALLOFF:
      filter->decay_peak_falloff = g_value_get_double (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}
コード例 #2
0
/**
 * gst_audio_info_is_equal:
 * @info: a #GstAudioInfo
 * @other: a #GstAudioInfo
 *
 * Compares two #GstAudioInfo and returns whether they are equal or not
 *
 * Returns: %TRUE if @info and @other are equal, else %FALSE.
 *
 * Since: 1.2
 *
 */
gboolean
gst_audio_info_is_equal (const GstAudioInfo * info, const GstAudioInfo * other)
{
  if (info == other)
    return TRUE;
  if (info->finfo == NULL || other->finfo == NULL)
    return FALSE;
  if (GST_AUDIO_INFO_FORMAT (info) != GST_AUDIO_INFO_FORMAT (other))
    return FALSE;
  if (GST_AUDIO_INFO_FLAGS (info) != GST_AUDIO_INFO_FLAGS (other))
    return FALSE;
  if (GST_AUDIO_INFO_LAYOUT (info) != GST_AUDIO_INFO_LAYOUT (other))
    return FALSE;
  if (GST_AUDIO_INFO_RATE (info) != GST_AUDIO_INFO_RATE (other))
    return FALSE;
  if (GST_AUDIO_INFO_CHANNELS (info) != GST_AUDIO_INFO_CHANNELS (other))
    return FALSE;
  if (GST_AUDIO_INFO_CHANNELS (info) > 64)
    return TRUE;
  if (memcmp (info->position, other->position,
          GST_AUDIO_INFO_CHANNELS (info) * sizeof (GstAudioChannelPosition)) !=
      0)
    return FALSE;

  return TRUE;
}
コード例 #3
0
ファイル: gstopusenc.c プロジェクト: kanongil/gst-plugins-bad
static gboolean
gst_opus_enc_set_format (GstAudioEncoder * benc, GstAudioInfo * info)
{
  GstOpusEnc *enc;

  enc = GST_OPUS_ENC (benc);

  g_mutex_lock (enc->property_lock);

  enc->n_channels = GST_AUDIO_INFO_CHANNELS (info);
  enc->sample_rate = GST_AUDIO_INFO_RATE (info);
  gst_opus_enc_setup_channel_mappings (enc, info);
  GST_DEBUG_OBJECT (benc, "Setup with %d channels, %d Hz", enc->n_channels,
      enc->sample_rate);

  /* handle reconfigure */
  if (enc->state) {
    opus_multistream_encoder_destroy (enc->state);
    enc->state = NULL;
  }
  if (!gst_opus_enc_setup (enc))
    return FALSE;

  enc->frame_samples = gst_opus_enc_get_frame_samples (enc);

  /* feedback to base class */
  gst_opus_enc_setup_base_class (enc, benc);

  g_mutex_unlock (enc->property_lock);

  return TRUE;
}
コード例 #4
0
ファイル: gstlevel.c プロジェクト: nnikos123/gst-plugins-good
static void
gst_level_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstLevel *filter = GST_LEVEL (object);

  switch (prop_id) {
    case PROP_POST_MESSAGES:
      /* fall-through */
    case PROP_MESSAGE:
      filter->post_messages = g_value_get_boolean (value);
      break;
    case PROP_INTERVAL:
      filter->interval = g_value_get_uint64 (value);
      /* Not exactly thread-safe, but property does not advertise that it
       * can be changed at runtime anyway */
      if (GST_AUDIO_INFO_RATE (&filter->info)) {
        gst_level_recalc_interval_frames (filter);
      }
      break;
    case PROP_PEAK_TTL:
      filter->decay_peak_ttl =
          gst_guint64_to_gdouble (g_value_get_uint64 (value));
      break;
    case PROP_PEAK_FALLOFF:
      filter->decay_peak_falloff = g_value_get_double (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}
コード例 #5
0
ファイル: gstlv2source.c プロジェクト: 0p1pp1/gst-plugins-bad
static gboolean
gst_lv2_source_set_caps (GstBaseSrc * base, GstCaps * caps)
{
  GstLV2Source *lv2 = (GstLV2Source *) base;
  GstAudioInfo info;

  if (!gst_audio_info_from_caps (&info, caps)) {
    GST_ERROR_OBJECT (base, "received invalid caps");
    return FALSE;
  }

  GST_DEBUG_OBJECT (lv2, "negotiated to caps %" GST_PTR_FORMAT, caps);

  lv2->info = info;

  gst_base_src_set_blocksize (base,
      GST_AUDIO_INFO_BPF (&info) * lv2->samples_per_buffer);

  if (!gst_lv2_setup (&lv2->lv2, GST_AUDIO_INFO_RATE (&info)))
    goto no_instance;

  return TRUE;

no_instance:
  {
    GST_ERROR_OBJECT (lv2, "could not create instance");
    return FALSE;
  }
}
コード例 #6
0
ファイル: gstaudiofilter.c プロジェクト: johlim/study
static gboolean
gst_audio_filter_template_setup (GstAudioFilter * filter,
    const GstAudioInfo * info)
{
  GstAudioFilterTemplate *filter_template;
  GstAudioFormat fmt;
  gint chans, rate;

  filter_template = GST_AUDIO_FILTER_TEMPLATE (filter);

  rate = GST_AUDIO_INFO_RATE (info);
  chans = GST_AUDIO_INFO_CHANNELS (info);
  fmt = GST_AUDIO_INFO_FORMAT (info);

  GST_INFO_OBJECT (filter_template, "format %d (%s), rate %d, %d channels",
      fmt, GST_AUDIO_INFO_NAME (info), rate, chans);

  /* if any setup needs to be done (like memory allocated), do it here */

  /* The audio filter base class also saves the audio info in
   * GST_AUDIO_FILTER_INFO(filter) so it's automatically available
   * later from there as well */

  return TRUE;
}
コード例 #7
0
ファイル: gstlv2source.c プロジェクト: 0p1pp1/gst-plugins-bad
/* seek to time, will be called when we operate in push mode. In pull mode we
 * get the requested byte offset. */
static gboolean
gst_lv2_source_do_seek (GstBaseSrc * base, GstSegment * segment)
{
  GstLV2Source *lv2 = (GstLV2Source *) base;
  GstClockTime time;
  gint samplerate, bpf;
  gint64 next_sample;

  GST_DEBUG_OBJECT (lv2, "seeking %" GST_SEGMENT_FORMAT, segment);

  time = segment->position;
  lv2->reverse = (segment->rate < 0.0);

  samplerate = GST_AUDIO_INFO_RATE (&lv2->info);
  bpf = GST_AUDIO_INFO_BPF (&lv2->info);

  /* now move to the time indicated, don't seek to the sample *after* the time */
  next_sample = gst_util_uint64_scale_int (time, samplerate, GST_SECOND);
  lv2->next_byte = next_sample * bpf;
  if (samplerate == 0)
    lv2->next_time = 0;
  else
    lv2->next_time =
        gst_util_uint64_scale_round (next_sample, GST_SECOND, samplerate);

  GST_DEBUG_OBJECT (lv2, "seeking next_sample=%" G_GINT64_FORMAT
      " next_time=%" GST_TIME_FORMAT, next_sample,
      GST_TIME_ARGS (lv2->next_time));

  g_assert (lv2->next_time <= time);

  lv2->next_sample = next_sample;

  if (!lv2->reverse) {
    if (GST_CLOCK_TIME_IS_VALID (segment->start)) {
      segment->time = segment->start;
    }
  } else {
    if (GST_CLOCK_TIME_IS_VALID (segment->stop)) {
      segment->time = segment->stop;
    }
  }

  if (GST_CLOCK_TIME_IS_VALID (segment->stop)) {
    time = segment->stop;
    lv2->sample_stop =
        gst_util_uint64_scale_round (time, samplerate, GST_SECOND);
    lv2->check_seek_stop = TRUE;
  } else {
    lv2->check_seek_stop = FALSE;
  }
  lv2->eos_reached = FALSE;

  return TRUE;
}
コード例 #8
0
gboolean
gst_pulse_fill_format_info (GstAudioRingBufferSpec * spec, pa_format_info ** f,
    guint * channels)
{
  pa_format_info *format;
  pa_sample_format_t sf = PA_SAMPLE_INVALID;
  GstAudioInfo *ainfo = &spec->info;

  format = pa_format_info_new ();

  if (spec->type == GST_AUDIO_RING_BUFFER_FORMAT_TYPE_MU_LAW
      && GST_AUDIO_INFO_WIDTH (ainfo) == 8) {
    format->encoding = PA_ENCODING_PCM;
    sf = PA_SAMPLE_ULAW;
  } else if (spec->type == GST_AUDIO_RING_BUFFER_FORMAT_TYPE_A_LAW
      && GST_AUDIO_INFO_WIDTH (ainfo) == 8) {
    format->encoding = PA_ENCODING_PCM;
    sf = PA_SAMPLE_ALAW;
  } else if (spec->type == GST_AUDIO_RING_BUFFER_FORMAT_TYPE_RAW) {
    format->encoding = PA_ENCODING_PCM;
    if (!gstaudioformat_to_pasampleformat (GST_AUDIO_INFO_FORMAT (ainfo), &sf))
      goto fail;
  } else if (spec->type == GST_AUDIO_RING_BUFFER_FORMAT_TYPE_AC3) {
    format->encoding = PA_ENCODING_AC3_IEC61937;
  } else if (spec->type == GST_AUDIO_RING_BUFFER_FORMAT_TYPE_EAC3) {
    format->encoding = PA_ENCODING_EAC3_IEC61937;
  } else if (spec->type == GST_AUDIO_RING_BUFFER_FORMAT_TYPE_DTS) {
    format->encoding = PA_ENCODING_DTS_IEC61937;
  } else if (spec->type == GST_AUDIO_RING_BUFFER_FORMAT_TYPE_MPEG) {
    format->encoding = PA_ENCODING_MPEG_IEC61937;
  } else {
    goto fail;
  }

  if (format->encoding == PA_ENCODING_PCM) {
    pa_format_info_set_sample_format (format, sf);
    pa_format_info_set_channels (format, GST_AUDIO_INFO_CHANNELS (ainfo));
  }

  pa_format_info_set_rate (format, GST_AUDIO_INFO_RATE (ainfo));

  if (!pa_format_info_valid (format))
    goto fail;

  *f = format;
  *channels = GST_AUDIO_INFO_CHANNELS (ainfo);

  return TRUE;

fail:
  if (format)
    pa_format_info_free (format);
  return FALSE;
}
コード例 #9
0
static gboolean
gst_decklink_audio_sink_ringbuffer_acquire (GstAudioRingBuffer * rb,
    GstAudioRingBufferSpec * spec)
{
  GstDecklinkAudioSinkRingBuffer *self =
      GST_DECKLINK_AUDIO_SINK_RING_BUFFER_CAST (rb);
  HRESULT ret;
  BMDAudioSampleType sample_depth;

  GST_DEBUG_OBJECT (self->sink, "Acquire");

  if (spec->info.finfo->format == GST_AUDIO_FORMAT_S16LE) {
    sample_depth = bmdAudioSampleType16bitInteger;
  } else {
    sample_depth = bmdAudioSampleType32bitInteger;
  }

  ret = self->output->output->EnableAudioOutput (bmdAudioSampleRate48kHz,
      sample_depth, 2, bmdAudioOutputStreamContinuous);
  if (ret != S_OK) {
    GST_WARNING_OBJECT (self->sink, "Failed to enable audio output 0x%08x",
        ret);
    return FALSE;
  }

  g_mutex_lock (&self->output->lock);
  self->output->audio_enabled = TRUE;
  if (self->output->start_scheduled_playback)
    self->output->start_scheduled_playback (self->output->videosink);
  g_mutex_unlock (&self->output->lock);

  ret =
      self->output->
      output->SetAudioCallback (new GStreamerAudioOutputCallback (self));
  if (ret != S_OK) {
    GST_WARNING_OBJECT (self->sink,
        "Failed to set audio output callback 0x%08x", ret);
    return FALSE;
  }

  spec->segsize =
      (spec->latency_time * GST_AUDIO_INFO_RATE (&spec->info) /
      G_USEC_PER_SEC) * GST_AUDIO_INFO_BPF (&spec->info);
  spec->segtotal = spec->buffer_time / spec->latency_time;
  // set latency to one more segment as we need some headroom
  spec->seglatency = spec->segtotal + 1;

  rb->size = spec->segtotal * spec->segsize;
  rb->memory = (guint8 *) g_malloc0 (rb->size);

  return TRUE;
}
コード例 #10
0
/* get notified of caps and plug in the correct process function */
static gboolean
gst_audio_iir_filter_setup (GstAudioFilter * base, const GstAudioInfo * info)
{
  GstAudioIIRFilter *self = GST_AUDIO_IIR_FILTER (base);
  gint new_rate = GST_AUDIO_INFO_RATE (info);

  if (GST_AUDIO_FILTER_RATE (self) != new_rate) {
    g_signal_emit (G_OBJECT (self),
        gst_audio_iir_filter_signals[SIGNAL_RATE_CHANGED], 0, new_rate);
  }

  return GST_AUDIO_FILTER_CLASS (parent_class)->setup (base, info);
}
コード例 #11
0
static gboolean
gst_audio_aggregator_mix_buffer (GstAudioAggregator * aagg,
    GstAudioAggregatorPad * pad, GstBuffer * inbuf, GstBuffer * outbuf)
{
  guint overlap;
  guint out_start;
  gboolean filled;
  guint blocksize;

  blocksize = gst_util_uint64_scale (aagg->priv->output_buffer_duration,
      GST_AUDIO_INFO_RATE (&aagg->info), GST_SECOND);
  blocksize = MAX (1, blocksize);

  /* Overlap => mix */
  if (aagg->priv->offset < pad->priv->output_offset)
    out_start = pad->priv->output_offset - aagg->priv->offset;
  else
    out_start = 0;

  overlap = pad->priv->size - pad->priv->position;
  if (overlap > blocksize - out_start)
    overlap = blocksize - out_start;

  if (GST_BUFFER_FLAG_IS_SET (inbuf, GST_BUFFER_FLAG_GAP)) {
    /* skip gap buffer */
    GST_LOG_OBJECT (pad, "skipping GAP buffer");
    pad->priv->output_offset += pad->priv->size - pad->priv->position;
    pad->priv->position = pad->priv->size;

    gst_buffer_replace (&pad->priv->buffer, NULL);
    return FALSE;
  }

  filled = GST_AUDIO_AGGREGATOR_GET_CLASS (aagg)->aggregate_one_buffer (aagg,
      pad, inbuf, pad->priv->position, outbuf, out_start, overlap);

  if (filled)
    GST_BUFFER_FLAG_UNSET (outbuf, GST_BUFFER_FLAG_GAP);

  pad->priv->position += overlap;
  pad->priv->output_offset += overlap;

  if (pad->priv->position == pad->priv->size) {
    /* Buffer done, drop it */
    gst_buffer_replace (&pad->priv->buffer, NULL);
    GST_DEBUG_OBJECT (pad, "Finished mixing buffer, waiting for next");
    return FALSE;
  }

  return TRUE;
}
コード例 #12
0
ファイル: gstceltenc.c プロジェクト: dylansong77/gstreamer
static gboolean
gst_celt_enc_set_format (GstAudioEncoder * benc, GstAudioInfo * info)
{
  GstCeltEnc *enc;
  GstCaps *otherpadcaps;

  enc = GST_CELT_ENC (benc);

  enc->channels = GST_AUDIO_INFO_CHANNELS (info);
  enc->rate = GST_AUDIO_INFO_RATE (info);

  /* handle reconfigure */
  if (enc->state) {
    celt_encoder_destroy (enc->state);
    enc->state = NULL;
  }
  if (enc->mode) {
    celt_mode_destroy (enc->mode);
    enc->mode = NULL;
  }
  memset (&enc->header, 0, sizeof (enc->header));

  otherpadcaps = gst_pad_get_allowed_caps (GST_AUDIO_ENCODER_SRC_PAD (enc));
  if (otherpadcaps) {
    if (!gst_caps_is_empty (otherpadcaps)) {
      GstStructure *ps = gst_caps_get_structure (otherpadcaps, 0);
      gst_structure_get_int (ps, "frame-size", &enc->frame_size);
    }
    gst_caps_unref (otherpadcaps);
  }

  if (enc->requested_frame_size > 0)
    enc->frame_size = enc->requested_frame_size;

  GST_DEBUG_OBJECT (enc, "channels=%d rate=%d frame-size=%d",
      enc->channels, enc->rate, enc->frame_size);

  if (!gst_celt_enc_setup (enc))
    return FALSE;

  /* feedback to base class */
  gst_audio_encoder_set_latency (benc,
      gst_celt_enc_get_latency (enc), gst_celt_enc_get_latency (enc));
  gst_audio_encoder_set_frame_samples_min (benc, enc->frame_size);
  gst_audio_encoder_set_frame_samples_max (benc, enc->frame_size);
  gst_audio_encoder_set_frame_max (benc, 1);

  return TRUE;
}
コード例 #13
0
static void
gst_freeverb_init_rev_model (GstFreeverb * filter)
{
    gfloat srfactor = GST_AUDIO_INFO_RATE (&filter->info) / 44100.0f;
    GstFreeverbPrivate *priv = filter->priv;

    freeverb_revmodel_free (filter);

    priv->gain = fixedgain;

    freeverb_comb_setbuffer (&priv->combL[0], combtuningL1 * srfactor);
    freeverb_comb_setbuffer (&priv->combR[0], combtuningR1 * srfactor);
    freeverb_comb_setbuffer (&priv->combL[1], combtuningL2 * srfactor);
    freeverb_comb_setbuffer (&priv->combR[1], combtuningR2 * srfactor);
    freeverb_comb_setbuffer (&priv->combL[2], combtuningL3 * srfactor);
    freeverb_comb_setbuffer (&priv->combR[2], combtuningR3 * srfactor);
    freeverb_comb_setbuffer (&priv->combL[3], combtuningL4 * srfactor);
    freeverb_comb_setbuffer (&priv->combR[3], combtuningR4 * srfactor);
    freeverb_comb_setbuffer (&priv->combL[4], combtuningL5 * srfactor);
    freeverb_comb_setbuffer (&priv->combR[4], combtuningR5 * srfactor);
    freeverb_comb_setbuffer (&priv->combL[5], combtuningL6 * srfactor);
    freeverb_comb_setbuffer (&priv->combR[5], combtuningR6 * srfactor);
    freeverb_comb_setbuffer (&priv->combL[6], combtuningL7 * srfactor);
    freeverb_comb_setbuffer (&priv->combR[6], combtuningR7 * srfactor);
    freeverb_comb_setbuffer (&priv->combL[7], combtuningL8 * srfactor);
    freeverb_comb_setbuffer (&priv->combR[7], combtuningR8 * srfactor);
    freeverb_allpass_setbuffer (&priv->allpassL[0], allpasstuningL1 * srfactor);
    freeverb_allpass_setbuffer (&priv->allpassR[0], allpasstuningR1 * srfactor);
    freeverb_allpass_setbuffer (&priv->allpassL[1], allpasstuningL2 * srfactor);
    freeverb_allpass_setbuffer (&priv->allpassR[1], allpasstuningR2 * srfactor);
    freeverb_allpass_setbuffer (&priv->allpassL[2], allpasstuningL3 * srfactor);
    freeverb_allpass_setbuffer (&priv->allpassR[2], allpasstuningR3 * srfactor);
    freeverb_allpass_setbuffer (&priv->allpassL[3], allpasstuningL4 * srfactor);
    freeverb_allpass_setbuffer (&priv->allpassR[3], allpasstuningR4 * srfactor);

    /* clear buffers */
    freeverb_revmodel_init (filter);

    /* set default values */
    freeverb_allpass_setfeedback (&priv->allpassL[0], 0.5f);
    freeverb_allpass_setfeedback (&priv->allpassR[0], 0.5f);
    freeverb_allpass_setfeedback (&priv->allpassL[1], 0.5f);
    freeverb_allpass_setfeedback (&priv->allpassR[1], 0.5f);
    freeverb_allpass_setfeedback (&priv->allpassL[2], 0.5f);
    freeverb_allpass_setfeedback (&priv->allpassR[2], 0.5f);
    freeverb_allpass_setfeedback (&priv->allpassL[3], 0.5f);
    freeverb_allpass_setfeedback (&priv->allpassR[3], 0.5f);
}
コード例 #14
0
static GstBuffer *
gst_audio_aggregator_do_clip (GstAggregator * agg,
    GstAggregatorPad * bpad, GstBuffer * buffer)
{
  GstAudioAggregatorPad *pad = GST_AUDIO_AGGREGATOR_PAD (bpad);
  gint rate, bpf;

  rate = GST_AUDIO_INFO_RATE (&pad->info);
  bpf = GST_AUDIO_INFO_BPF (&pad->info);

  GST_OBJECT_LOCK (bpad);
  buffer = gst_audio_buffer_clip (buffer, &bpad->segment, rate, bpf);
  GST_OBJECT_UNLOCK (bpad);

  return buffer;
}
コード例 #15
0
ファイル: deinterleave.c プロジェクト: PeterXu/gst-mobile
static void
gst_deinterleave_add_new_pads (GstDeinterleave * self, GstCaps * caps)
{
  GstPad *pad;
  guint i;

  for (i = 0; i < GST_AUDIO_INFO_CHANNELS (&self->audio_info); i++) {
    gchar *name = g_strdup_printf ("src_%u", i);
    GstCaps *srccaps;
    GstAudioInfo info;
    GstAudioFormat format = GST_AUDIO_INFO_FORMAT (&self->audio_info);
    gint rate = GST_AUDIO_INFO_RATE (&self->audio_info);
    GstAudioChannelPosition position = GST_AUDIO_CHANNEL_POSITION_MONO;
    CopyStickyEventsData data;

    /* Set channel position if we know it */
    if (self->keep_positions)
      position = GST_AUDIO_INFO_POSITION (&self->audio_info, i);

    gst_audio_info_init (&info);
    gst_audio_info_set_format (&info, format, rate, 1, &position);

    srccaps = gst_audio_info_to_caps (&info);

    pad = gst_pad_new_from_static_template (&src_template, name);
    g_free (name);

    gst_pad_use_fixed_caps (pad);
    gst_pad_set_query_function (pad,
        GST_DEBUG_FUNCPTR (gst_deinterleave_src_query));
    gst_pad_set_active (pad, TRUE);

    data.pad = pad;
    data.caps = srccaps;
    gst_pad_sticky_events_foreach (self->sink, copy_sticky_events, &data);
    if (data.caps)
      gst_pad_set_caps (pad, data.caps);
    gst_element_add_pad (GST_ELEMENT (self), pad);
    self->srcpads = g_list_prepend (self->srcpads, gst_object_ref (pad));

    gst_caps_unref (srccaps);
  }

  gst_element_no_more_pads (GST_ELEMENT (self));
  self->srcpads = g_list_reverse (self->srcpads);
}
コード例 #16
0
static guint
gst_osx_audio_ring_buffer_delay (GstAudioRingBuffer * buf)
{
  GstOsxAudioRingBuffer *osxbuf;
  double latency;
  guint samples;

  osxbuf = GST_OSX_AUDIO_RING_BUFFER (buf);

  if (!gst_core_audio_get_samples_and_latency (osxbuf->core_audio,
          GST_AUDIO_INFO_RATE (&buf->spec.info), &samples, &latency)) {
    return 0;
  }
  GST_DEBUG_OBJECT (buf, "Got latency: %f seconds -> %d samples",
      latency, samples);
  return samples;
}
コード例 #17
0
static void
pcm_config_from_spec (struct pcm_config *config,
    const GstAudioRingBufferSpec * spec)
{
  gint64 frames;

  config->format = pcm_format_from_gst (GST_AUDIO_INFO_FORMAT (&spec->info));
  config->channels = GST_AUDIO_INFO_CHANNELS (&spec->info);
  config->rate = GST_AUDIO_INFO_RATE (&spec->info);

  gst_audio_info_convert (&spec->info,
      GST_FORMAT_TIME, spec->latency_time * GST_USECOND,
      GST_FORMAT_DEFAULT /* frames */ , &frames);

  config->period_size = frames;
  config->period_count = spec->buffer_time / spec->latency_time;
}
コード例 #18
0
static gboolean
gst_ladspa_sink_type_set_caps (GstBaseSink * base, GstCaps * caps)
{
  GstLADSPASink *ladspa = GST_LADSPA_SINK (base);
  GstAudioInfo info;

  if (!gst_audio_info_from_caps (&info, caps)) {
    GST_ERROR_OBJECT (base, "received invalid caps");
    return FALSE;
  }

  GST_DEBUG_OBJECT (ladspa, "negotiated to caps %" GST_PTR_FORMAT, caps);

  ladspa->info = info;

  return gst_ladspa_setup (&ladspa->ladspa, GST_AUDIO_INFO_RATE (&info));
}
コード例 #19
0
static GstFlowReturn
gst_chromaprint_transform_ip (GstBaseTransform * trans, GstBuffer * buf)
{
  GstChromaprint *chromaprint = GST_CHROMAPRINT (trans);
  GstAudioFilter *filter = GST_AUDIO_FILTER (trans);
  GstMapInfo map_info;
  guint nsamples;
  gint rate, channels;

  rate = GST_AUDIO_INFO_RATE (&filter->info);
  channels = GST_AUDIO_INFO_CHANNELS (&filter->info);

  if (G_UNLIKELY (rate <= 0 || channels <= 0))
    return GST_FLOW_NOT_NEGOTIATED;

  if (!chromaprint->record)
    return GST_FLOW_OK;

  if (!gst_buffer_map (buf, &map_info, GST_MAP_READ))
    return GST_FLOW_ERROR;

  nsamples = map_info.size / (channels * 2);

  if (nsamples == 0)
    goto end;

  if (chromaprint->nsamples == 0) {
    chromaprint_start (chromaprint->context, rate, channels);
  }
  chromaprint->nsamples += nsamples;
  chromaprint->duration = chromaprint->nsamples / rate;

  chromaprint_feed (chromaprint->context, map_info.data,
      map_info.size / sizeof (guint16));

  if (chromaprint->duration >= chromaprint->max_duration
      && !chromaprint->fingerprint) {
    gst_chromaprint_create_fingerprint (chromaprint);
  }

end:
  gst_buffer_unmap (buf, &map_info);

  return GST_FLOW_OK;
}
コード例 #20
0
static gboolean
gst_ladspa_source_type_set_caps (GstBaseSrc * base, GstCaps * caps)
{
  GstLADSPASource *ladspa = GST_LADSPA_SOURCE (base);
  GstAudioInfo info;

  if (!gst_audio_info_from_caps (&info, caps)) {
    GST_ERROR_OBJECT (base, "received invalid caps");
    return FALSE;
  }

  GST_DEBUG_OBJECT (ladspa, "negotiated to caps %" GST_PTR_FORMAT, caps);

  ladspa->info = info;

  gst_base_src_set_blocksize (base,
      GST_AUDIO_INFO_BPF (&info) * ladspa->samples_per_buffer);

  return gst_ladspa_setup (&ladspa->ladspa, GST_AUDIO_INFO_RATE (&info));
}
コード例 #21
0
static gboolean
gst_vorbis_enc_set_format (GstAudioEncoder * enc, GstAudioInfo * info)
{
  GstVorbisEnc *vorbisenc;

  vorbisenc = GST_VORBISENC (enc);

  vorbisenc->channels = GST_AUDIO_INFO_CHANNELS (info);
  vorbisenc->frequency = GST_AUDIO_INFO_RATE (info);

  /* if re-configured, we were drained and cleared already */
  if (!gst_vorbis_enc_setup (vorbisenc))
    return FALSE;

  /* feedback to base class */
  gst_audio_encoder_set_latency (enc,
      gst_vorbis_enc_get_latency (vorbisenc),
      gst_vorbis_enc_get_latency (vorbisenc));

  return TRUE;
}
コード例 #22
0
static gboolean
gst_speex_enc_set_format (GstAudioEncoder * benc, GstAudioInfo * info)
{
  GstSpeexEnc *enc;

  enc = GST_SPEEX_ENC (benc);

  enc->channels = GST_AUDIO_INFO_CHANNELS (info);
  enc->rate = GST_AUDIO_INFO_RATE (info);

  /* handle reconfigure */
  if (enc->state) {
    speex_encoder_destroy (enc->state);
    enc->state = NULL;
  }

  if (!gst_speex_enc_setup (enc))
    return FALSE;

  /* feedback to base class */
  gst_audio_encoder_set_latency (benc,
      gst_speex_enc_get_latency (enc), gst_speex_enc_get_latency (enc));
  gst_audio_encoder_set_lookahead (benc, enc->lookahead);

  if (enc->nframes == 0) {
    /* as many frames as available input allows */
    gst_audio_encoder_set_frame_samples_min (benc, enc->frame_size);
    gst_audio_encoder_set_frame_samples_max (benc, enc->frame_size);
    gst_audio_encoder_set_frame_max (benc, 0);
  } else {
    /* exactly as many frames as configured */
    gst_audio_encoder_set_frame_samples_min (benc,
        enc->frame_size * enc->nframes);
    gst_audio_encoder_set_frame_samples_max (benc,
        enc->frame_size * enc->nframes);
    gst_audio_encoder_set_frame_max (benc, 1);
  }

  return TRUE;
}
コード例 #23
0
GstFlowReturn AudioFileReader::handleSample(GstAppSink* sink)
{
    GstSample* sample = gst_app_sink_pull_sample(sink);
    if (!sample)
        return GST_FLOW_ERROR;

    GstBuffer* buffer = gst_sample_get_buffer(sample);
    if (!buffer) {
        gst_sample_unref(sample);
        return GST_FLOW_ERROR;
    }

    GstCaps* caps = gst_sample_get_caps(sample);
    if (!caps) {
        gst_sample_unref(sample);
        return GST_FLOW_ERROR;
    }

    GstAudioInfo info;
    gst_audio_info_from_caps(&info, caps);
    int frames = GST_CLOCK_TIME_TO_FRAMES(GST_BUFFER_DURATION(buffer), GST_AUDIO_INFO_RATE(&info));

    // Check the first audio channel. The buffer is supposed to store
    // data of a single channel anyway.
    switch (GST_AUDIO_INFO_POSITION(&info, 0)) {
    case GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT:
        gst_buffer_list_add(m_frontLeftBuffers, gst_buffer_ref(buffer));
        m_channelSize += frames;
        break;
    case GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT:
        gst_buffer_list_add(m_frontRightBuffers, gst_buffer_ref(buffer));
        break;
    default:
        break;
    }

    gst_sample_unref(sample);
    return GST_FLOW_OK;

}
コード例 #24
0
gboolean
gst_pulse_fill_sample_spec (GstAudioRingBufferSpec * spec, pa_sample_spec * ss)
{
  if (spec->type == GST_AUDIO_RING_BUFFER_FORMAT_TYPE_RAW) {
    if (!gstaudioformat_to_pasampleformat (GST_AUDIO_INFO_FORMAT (&spec->info),
            &ss->format))
      return FALSE;
  } else if (spec->type == GST_AUDIO_RING_BUFFER_FORMAT_TYPE_MU_LAW) {
    ss->format = PA_SAMPLE_ULAW;
  } else if (spec->type == GST_AUDIO_RING_BUFFER_FORMAT_TYPE_A_LAW) {
    ss->format = PA_SAMPLE_ALAW;
  } else
    return FALSE;

  ss->channels = GST_AUDIO_INFO_CHANNELS (&spec->info);
  ss->rate = GST_AUDIO_INFO_RATE (&spec->info);

  if (!pa_sample_spec_valid (ss))
    return FALSE;

  return TRUE;
}
コード例 #25
0
ファイル: gstcemp3enc.c プロジェクト: RidgeRun/gst-ce-plugin
static gboolean
gst_ce_mp3_enc_set_src_caps (GstCeAudEnc * ceaudenc, GstAudioInfo * info,
    GstCaps ** caps, GstBuffer ** codec_data)
{
  GstCeMp3Enc *mp3enc = GST_CE_MP3ENC (ceaudenc);
  const gchar *mpegversion = NULL;
  gboolean ret = TRUE;

  ITTIAM_MP3ENC_Params *params;

  mp3enc->channels = GST_AUDIO_INFO_CHANNELS (info);
  GST_INFO_OBJECT (mp3enc, "Set src channels to %i", mp3enc->channels);
  mp3enc->rate = GST_AUDIO_INFO_RATE (info);
  if (mp3enc->rate >= 16000 & mp3enc->rate <= 24000) {
    GST_DEBUG_OBJECT (mp3enc, "Setting samples per frame to 576");
    gst_ce_audenc_set_frame_samples (ceaudenc, 576, 576);
  } else {
    GST_DEBUG_OBJECT (mp3enc, "Setting samples per frame to 1152");
    gst_ce_audenc_set_frame_samples (ceaudenc, 1152, 1152);
  }
  return ret;
}
コード例 #26
0
ファイル: gstlevel.c プロジェクト: nnikos123/gst-plugins-good
static void
gst_level_recalc_interval_frames (GstLevel * level)
{
  GstClockTime interval = level->interval;
  guint sample_rate = GST_AUDIO_INFO_RATE (&level->info);
  guint interval_frames;

  interval_frames = GST_CLOCK_TIME_TO_FRAMES (interval, sample_rate);

  if (interval_frames == 0) {
    GST_WARNING_OBJECT (level, "interval %" GST_TIME_FORMAT " is too small, "
        "should be at least %" GST_TIME_FORMAT " for sample rate %u",
        GST_TIME_ARGS (interval),
        GST_TIME_ARGS (GST_FRAMES_TO_CLOCK_TIME (1, sample_rate)), sample_rate);
    interval_frames = 1;
  }

  level->interval_frames = interval_frames;

  GST_INFO_OBJECT (level, "interval_frames now %u for interval "
      "%" GST_TIME_FORMAT " and sample rate %u", interval_frames,
      GST_TIME_ARGS (interval), sample_rate);
}
コード例 #27
0
static gboolean
gst_amrnbenc_set_format (GstAudioEncoder * enc, GstAudioInfo * info)
{
  GstAmrnbEnc *amrnbenc;
  GstCaps *copy;

  amrnbenc = GST_AMRNBENC (enc);

  /* parameters already parsed for us */
  amrnbenc->rate = GST_AUDIO_INFO_RATE (info);
  amrnbenc->channels = GST_AUDIO_INFO_CHANNELS (info);

  /* we do not really accept other input, but anyway ... */
  /* this is not wrong but will sound bad */
  if (amrnbenc->channels != 1) {
    g_warning ("amrnbdec is only optimized for mono channels");
  }
  if (amrnbenc->rate != 8000) {
    g_warning ("amrnbdec is only optimized for 8000 Hz samplerate");
  }

  /* create reverse caps */
  copy = gst_caps_new_simple ("audio/AMR",
      "channels", G_TYPE_INT, amrnbenc->channels,
      "rate", G_TYPE_INT, amrnbenc->rate, NULL);

  gst_audio_encoder_set_output_format (GST_AUDIO_ENCODER (amrnbenc), copy);
  gst_caps_unref (copy);

  /* report needs to base class: hand one frame at a time */
  gst_audio_encoder_set_frame_samples_min (enc, 160);
  gst_audio_encoder_set_frame_samples_max (enc, 160);
  gst_audio_encoder_set_frame_max (enc, 1);

  return TRUE;
}
コード例 #28
0
static gboolean
gst_audio_segment_clip_set_caps (GstSegmentClip * base, GstCaps * caps)
{
  GstAudioSegmentClip *self = GST_AUDIO_SEGMENT_CLIP (base);
  gboolean ret;
  GstAudioInfo info;
  gint rate, channels, width;

  gst_audio_info_init (&info);
  ret = gst_audio_info_from_caps (&info, caps);

  if (ret) {
    rate = GST_AUDIO_INFO_RATE (&info);
    channels = GST_AUDIO_INFO_CHANNELS (&info);
    width = GST_AUDIO_INFO_WIDTH (&info);

    GST_DEBUG_OBJECT (self, "Configured: rate %d channels %d width %d",
        rate, channels, width);
    self->rate = rate;
    self->framesize = (width / 8) * channels;
  }

  return ret;
}
コード例 #29
0
static gboolean
gst_directsound_src_prepare (GstAudioSrc * asrc, GstAudioRingBufferSpec * spec)
{
  GstDirectSoundSrc *dsoundsrc;
  WAVEFORMATEX wfx;             /* Wave format structure */
  HRESULT hRes;                 /* Result for windows functions */
  DSCBUFFERDESC descSecondary;  /* Capturebuffer description */

  dsoundsrc = GST_DIRECTSOUND_SRC (asrc);

  GST_DEBUG_OBJECT (asrc, "preparing directsoundsrc");

  /* Define buffer */
  memset (&wfx, 0, sizeof (WAVEFORMATEX));
  wfx.wFormatTag = WAVE_FORMAT_PCM;
  wfx.nChannels = GST_AUDIO_INFO_CHANNELS (&spec->info);
  wfx.nSamplesPerSec = GST_AUDIO_INFO_RATE (&spec->info);
  wfx.wBitsPerSample = GST_AUDIO_INFO_BPF (&spec->info) * 8 / wfx.nChannels;
  wfx.nBlockAlign = GST_AUDIO_INFO_BPF (&spec->info);
  wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;
  /* Ignored for WAVE_FORMAT_PCM. */
  wfx.cbSize = 0;

  if (wfx.wBitsPerSample != 16 && wfx.wBitsPerSample != 8)
    goto dodgy_width;

  /* Set the buffer size to two seconds. 
     This should never reached. 
   */
  dsoundsrc->buffer_size = wfx.nAvgBytesPerSec * 2;

  GST_DEBUG_OBJECT (asrc, "Buffer size: %d", dsoundsrc->buffer_size);

  /* Init secondary buffer desciption */
  memset (&descSecondary, 0, sizeof (DSCBUFFERDESC));
  descSecondary.dwSize = sizeof (DSCBUFFERDESC);
  descSecondary.dwFlags = 0;
  descSecondary.dwReserved = 0;

  /* This is not primary buffer so have to set size  */
  descSecondary.dwBufferBytes = dsoundsrc->buffer_size;
  descSecondary.lpwfxFormat = &wfx;

  /* Create buffer */
  hRes = IDirectSoundCapture_CreateCaptureBuffer (dsoundsrc->pDSC,
      &descSecondary, &dsoundsrc->pDSBSecondary, NULL);
  if (hRes != DS_OK)
    goto capture_buffer;

  dsoundsrc->bytes_per_sample = GST_AUDIO_INFO_BPF (&spec->info);

  GST_DEBUG ("latency time: %" G_GUINT64_FORMAT " - buffer time: %"
      G_GUINT64_FORMAT, spec->latency_time, spec->buffer_time);

  /* Buffer-time should be always more than 2*latency */
  if (spec->buffer_time < spec->latency_time * 2) {
    spec->buffer_time = spec->latency_time * 2;
    GST_WARNING ("buffer-time was less than latency");
  }

  /* Save the times */
  dsoundsrc->buffer_time = spec->buffer_time;
  dsoundsrc->latency_time = spec->latency_time;

  dsoundsrc->latency_size = (gint) wfx.nAvgBytesPerSec *
      dsoundsrc->latency_time / 1000000.0;

  spec->segsize = (guint) (((double) spec->buffer_time / 1000000.0) *
      wfx.nAvgBytesPerSec);

  /* just in case */
  if (spec->segsize < 1)
    spec->segsize = 1;

  spec->segtotal = GST_AUDIO_INFO_BPF (&spec->info) * 8 *
      (wfx.nAvgBytesPerSec / spec->segsize);

  GST_DEBUG_OBJECT (asrc,
      "bytes/sec: %lu, buffer size: %d, segsize: %d, segtotal: %d",
      wfx.nAvgBytesPerSec, dsoundsrc->buffer_size, spec->segsize,
      spec->segtotal);

  /* Not read anything yet */
  dsoundsrc->current_circular_offset = 0;

  GST_DEBUG_OBJECT (asrc, "channels: %d, rate: %d, bytes_per_sample: %d"
      " WAVEFORMATEX.nSamplesPerSec: %ld, WAVEFORMATEX.wBitsPerSample: %d,"
      " WAVEFORMATEX.nBlockAlign: %d, WAVEFORMATEX.nAvgBytesPerSec: %ld",
      GST_AUDIO_INFO_CHANNELS (&spec->info), GST_AUDIO_INFO_RATE (&spec->info),
      GST_AUDIO_INFO_BPF (&spec->info), wfx.nSamplesPerSec, wfx.wBitsPerSample,
      wfx.nBlockAlign, wfx.nAvgBytesPerSec);

  return TRUE;

capture_buffer:
  {
    GST_ELEMENT_ERROR (dsoundsrc, RESOURCE, OPEN_READ,
        ("Unable to create capturebuffer"), (NULL));
    return FALSE;
  }
dodgy_width:
  {
    GST_ELEMENT_ERROR (dsoundsrc, RESOURCE, OPEN_READ,
        ("Unexpected width %d", wfx.wBitsPerSample), (NULL));
    return FALSE;
  }
}
コード例 #30
0
static void
gst_audio_wsinclimit_build_kernel (GstAudioWSincLimit * self,
    const GstAudioInfo * info)
{
  gint i = 0;
  gdouble sum = 0.0;
  gint len = 0;
  gdouble w;
  gdouble *kernel = NULL;
  gint rate, channels;

  len = self->kernel_length;

  if (info) {
    rate = GST_AUDIO_INFO_RATE (info);
    channels = GST_AUDIO_INFO_CHANNELS (info);
  } else {
    rate = GST_AUDIO_FILTER_RATE (self);
    channels = GST_AUDIO_FILTER_CHANNELS (self);
  }

  if (rate == 0) {
    GST_DEBUG ("rate not set yet");
    return;
  }

  if (channels == 0) {
    GST_DEBUG ("channels not set yet");
    return;
  }

  /* Clamp cutoff frequency between 0 and the nyquist frequency */
  self->cutoff = CLAMP (self->cutoff, 0.0, rate / 2);

  GST_DEBUG ("gst_audio_wsinclimit_: initializing filter kernel of length %d "
      "with cutoff %.2lf Hz "
      "for mode %s",
      len, self->cutoff,
      (self->mode == MODE_LOW_PASS) ? "low-pass" : "high-pass");

  /* fill the kernel */
  w = 2 * G_PI * (self->cutoff / rate);

  kernel = g_new (gdouble, len);

  for (i = 0; i < len; ++i) {
    if (i == (len - 1) / 2.0)
      kernel[i] = w;
    else
      kernel[i] = sin (w * (i - (len - 1) / 2)) / (i - (len - 1) / 2.0);

    /* windowing */
    switch (self->window) {
      case WINDOW_HAMMING:
        kernel[i] *= (0.54 - 0.46 * cos (2 * G_PI * i / (len - 1)));
        break;
      case WINDOW_BLACKMAN:
        kernel[i] *= (0.42 - 0.5 * cos (2 * G_PI * i / (len - 1)) +
            0.08 * cos (4 * G_PI * i / (len - 1)));
        break;
      case WINDOW_GAUSSIAN:
        kernel[i] *= exp (-0.5 * POW2 (3.0 / len * (2 * i - (len - 1))));
        break;
      case WINDOW_COSINE:
        kernel[i] *= cos (G_PI * i / (len - 1) - G_PI / 2);
        break;
      case WINDOW_HANN:
        kernel[i] *= 0.5 * (1 - cos (2 * G_PI * i / (len - 1)));
        break;
    }
  }

  /* normalize for unity gain at DC */
  for (i = 0; i < len; ++i)
    sum += kernel[i];
  for (i = 0; i < len; ++i)
    kernel[i] /= sum;

  /* convert to highpass if specified */
  if (self->mode == MODE_HIGH_PASS) {
    for (i = 0; i < len; ++i)
      kernel[i] = -kernel[i];

    if (len % 2 == 1) {
      kernel[(len - 1) / 2] += 1.0;
    } else {
      kernel[len / 2 - 1] += 0.5;
      kernel[len / 2] += 0.5;
    }
  }

  gst_audio_fx_base_fir_filter_set_kernel (GST_AUDIO_FX_BASE_FIR_FILTER (self),
      kernel, self->kernel_length, (len - 1) / 2, info);
}