예제 #1
0
static void
gst_bml_transform_init (GstBMLTransform * bml_transform)
{
  GstBMLTransformClass *klass = GST_BML_TRANSFORM_GET_CLASS (bml_transform);
  GstBMLClass *bml_class = GST_BML_CLASS (klass);
  GstBML *bml = GST_BML (bml_transform);

  GST_INFO ("initializing instance: elem=%p, bml=%p, bml_class=%p",
      bml_transform, bml, bml_class);
  GST_INFO ("bmh=0x%p, src=%d, sink=%d", bml_class->bmh, bml_class->numsrcpads,
      bml_class->numsinkpads);

  bml (gstbml_init (bml, bml_class, GST_ELEMENT (bml_transform)));
  /* this is not nedded when using the base class
     bml(gstbml_init_pads(GST_ELEMENT(bml_transform),bml,gst_bml_transform_link));

     if (sinkcount == 1) {
     // with one sink (input ports) we can use the chain function
     // effects
     GST_DEBUG_OBJECT(bml, "chain mode");
     gst_pad_set_chain_function(bml->sinkpads[0], gst_bml_transform_chain);
     }
     else if (sinkcount > 1) {
     // more than one sink (input ports) pad needs loop mode
     // auxbus based effects
     GST_DEBUG_OBJECT(bml, "loop mode with %d sink pads and %d src pads", sinkcount, srccount);
     gst_element_set_loop_function(GST_ELEMENT(bml_transform), gst_bml_transform_loop);
     }
   */

  gst_base_transform_set_gap_aware (GST_BASE_TRANSFORM (bml_transform), TRUE);

  GST_DEBUG ("  done");
}
예제 #2
0
static void
gst_bml_transform_base_finalize (GstBMLTransformClass * klass)
{
  GstBMLClass *bml_class = GST_BML_CLASS (klass);

  gstbml_preset_finalize (bml_class);
  bml (gstbml_base_finalize (bml_class));
}
예제 #3
0
static gboolean
gst_bml_preset_delete_preset (GstPreset * preset, const gchar * name)
{
  GstBMLTransform *bml_transform = GST_BML_TRANSFORM (preset);
  GstBMLTransformClass *klass = GST_BML_TRANSFORM_GET_CLASS (bml_transform);
  GstBMLClass *bml_class = GST_BML_CLASS (klass);

  return (gstbml_preset_delete_preset (bml_class, name));
}
예제 #4
0
static gboolean
gst_bml_get_meta (GstPreset * preset, const gchar * name, const gchar * tag,
    gchar ** value)
{
  GstBMLTransform *bml_transform = GST_BML_TRANSFORM (preset);
  GstBMLTransformClass *klass = GST_BML_TRANSFORM_GET_CLASS (bml_transform);
  GstBMLClass *bml_class = GST_BML_CLASS (klass);

  return (gstbml_preset_get_meta (bml_class, name, tag, value));
}
예제 #5
0
static gboolean
gst_bml_preset_rename_preset (GstPreset * preset, const gchar * old_name,
    const gchar * new_name)
{
  GstBMLTransform *bml_transform = GST_BML_TRANSFORM (preset);
  GstBMLTransformClass *klass = GST_BML_TRANSFORM_GET_CLASS (bml_transform);
  GstBMLClass *bml_class = GST_BML_CLASS (klass);

  return gstbml_preset_rename_preset (bml_class, old_name, new_name);
}
예제 #6
0
static void
gst_bml_transform_get_property (GObject * object, guint prop_id, GValue * value,
    GParamSpec * pspec)
{
  GstBMLTransform *bml_transform = GST_BML_TRANSFORM (object);
  GstBMLTransformClass *klass = GST_BML_TRANSFORM_GET_CLASS (bml_transform);
  GstBML *bml = GST_BML (bml_transform);
  GstBMLClass *bml_class = GST_BML_CLASS (klass);

  bml (gstbml_get_property (bml, bml_class, prop_id, value, pspec));
}
예제 #7
0
static gchar *
gst_bml_property_meta_describe_property (GstBtPropertyMeta * property_meta,
    guint prop_id, const GValue * value)
{
  GstBMLTransform *bml_transform = GST_BML_TRANSFORM (property_meta);
  GstBML *bml = GST_BML (bml_transform);
  GstBMLTransformClass *klass = GST_BML_TRANSFORM_GET_CLASS (bml_transform);
  GstBMLClass *bml_class = GST_BML_CLASS (klass);

  return (bml (gstbml_property_meta_describe_property (bml_class, bml,
              prop_id, value)));
}
예제 #8
0
static void
gst_bml_transform_base_init (GstBMLTransformClass * klass)
{
  GstBMLClass *bml_class = GST_BML_CLASS (klass);
  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
  //GstPadTemplate *templ;
  gpointer bmh;
  static GstPadTemplate *mono_src_pad_template = NULL;
  static GstPadTemplate *stereo_src_pad_template = NULL;
  static GstPadTemplate *mono_sink_pad_template = NULL;
  static GstPadTemplate *stereo_sink_pad_template = NULL;

  GST_INFO ("initializing base");

  bmh =
      bml (gstbml_class_base_init (bml_class, G_TYPE_FROM_CLASS (klass), 1, 1));

  if (bml_class->output_channels == 1) {
    if (G_UNLIKELY (!mono_src_pad_template))
      mono_src_pad_template =
          gst_static_pad_template_get (&bml_pad_caps_mono_src_template);
    gst_element_class_add_pad_template (element_class, mono_src_pad_template);
    GST_INFO ("  added mono src pad template");
  } else {
    if (G_UNLIKELY (!stereo_src_pad_template))
      stereo_src_pad_template =
          gst_static_pad_template_get (&bml_pad_caps_stereo_src_template);
    gst_element_class_add_pad_template (element_class, stereo_src_pad_template);
    GST_INFO ("  added stereo src pad template");
  }
  if (bml_class->input_channels == 1) {
    if (G_UNLIKELY (!mono_sink_pad_template))
      mono_sink_pad_template =
          gst_static_pad_template_get (&bml_pad_caps_mono_sink_template);
    gst_element_class_add_pad_template (element_class, mono_sink_pad_template);
    GST_INFO ("  added mono sink pad template");
  } else {
    if (G_UNLIKELY (!stereo_sink_pad_template))
      stereo_sink_pad_template =
          gst_static_pad_template_get (&bml_pad_caps_stereo_sink_template);
    gst_element_class_add_pad_template (element_class,
        stereo_sink_pad_template);
    GST_INFO ("  added stereo sink pad template");
  }

  bml (gstbml_class_set_details (element_class, bml_class, bmh,
          "Filter/Effect/Audio/BML"));
}
예제 #9
0
static void
gst_bml_transform_init (GstBMLTransform * bml_transform)
{
  GstBMLTransformClass *klass = GST_BML_TRANSFORM_GET_CLASS (bml_transform);
  GstBMLClass *bml_class = GST_BML_CLASS (klass);
  GstBML *bml = GST_BML (bml_transform);

  GST_INFO ("initializing instance: elem=%p, bml=%p, bml_class=%p",
      bml_transform, bml, bml_class);
  GST_INFO ("bmh=0x%p, src=%d, sink=%d", bml_class->bmh, bml_class->numsrcpads,
      bml_class->numsinkpads);

  bml (gstbml_init (bml, bml_class, GST_ELEMENT (bml_transform)));

  gst_base_transform_set_gap_aware (GST_BASE_TRANSFORM (bml_transform), TRUE);

  GST_DEBUG ("  done");
}
예제 #10
0
static void
gst_bml_transform_class_init (GstBMLTransformClass * klass)
{
  GstBMLClass *bml_class = GST_BML_CLASS (klass);
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
  GstBaseTransformClass *gstbasetransform_class =
      GST_BASE_TRANSFORM_CLASS (klass);

  GST_INFO ("initializing class");
  parent_class = g_type_class_peek_parent (klass);

  // override methods
  gobject_class->set_property =
      GST_DEBUG_FUNCPTR (gst_bml_transform_set_property);
  gobject_class->get_property =
      GST_DEBUG_FUNCPTR (gst_bml_transform_get_property);
  gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_bml_transform_dispose);
  gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_bml_transform_finalize);
  element_class->set_context = GST_DEBUG_FUNCPTR (gstbt_bml_src_set_context);
  gstbasetransform_class->set_caps =
      GST_DEBUG_FUNCPTR (gst_bml_transform_set_caps);
  gstbasetransform_class->stop = GST_DEBUG_FUNCPTR (gst_bml_transform_stop);
  if (bml_class->output_channels == 1) {
    gstbasetransform_class->transform_ip =
        GST_DEBUG_FUNCPTR (gst_bml_transform_transform_ip_mono);
  } else {
    if (bml_class->input_channels == 1) {
      gstbasetransform_class->transform =
          GST_DEBUG_FUNCPTR (gst_bml_transform_transform_mono_to_stereo);
      gstbasetransform_class->get_unit_size =
          GST_DEBUG_FUNCPTR (gst_bml_transform_get_unit_size);
      gstbasetransform_class->transform_caps =
          GST_DEBUG_FUNCPTR (gst_bml_transform_transform_caps);
    } else {
      gstbasetransform_class->transform_ip =
          GST_DEBUG_FUNCPTR (gst_bml_transform_transform_ip_stereo);
    }
  }

  // override interface properties and register parameters as gobject properties
  bml (gstbml_class_prepare_properties (gobject_class, bml_class));
}
예제 #11
0
static GstCaps *
gst_bml_transform_transform_caps (GstBaseTransform * base,
    GstPadDirection direction, GstCaps * caps, GstCaps * filter)
{
  GstBMLTransformClass *klass = GST_BML_TRANSFORM_GET_CLASS (base);
  GstBMLClass *bml_class = GST_BML_CLASS (klass);
  GstCaps *res = gst_caps_copy (caps);
  GstStructure *structure;
  gint i, n = gst_caps_get_size (res);

  for (i = 0; i < n; i++) {
    structure = gst_caps_get_structure (res, i);
    /* if we should produce this output, what can we accept */
    if (direction == GST_PAD_SRC) {
      GST_INFO_OBJECT (base, "allow %d input channel",
          bml_class->input_channels);
      gst_structure_set (structure, "channels", G_TYPE_INT,
          bml_class->input_channels, NULL);
      gst_structure_remove_field (structure, "channel-mask");
    } else {
      GST_INFO_OBJECT (base, "allow %d output channels",
          bml_class->output_channels);
      gst_structure_set (structure, "channels", G_TYPE_INT,
          bml_class->output_channels, NULL);
    }
  }

  if (filter) {
    GstCaps *tmp =
        gst_caps_intersect_full (filter, res, GST_CAPS_INTERSECT_FIRST);
    gst_caps_unref (res);
    res = tmp;
  }

  return res;
}
예제 #12
0
static GstFlowReturn
gst_bml_transform_transform_mono_to_stereo (GstBaseTransform * base,
    GstBuffer * inbuf, GstBuffer * outbuf)
{
  GstMapInfo infoi, infoo;
  GstBMLTransform *bml_transform = GST_BML_TRANSFORM (base);
  GstBMLTransformClass *klass = GST_BML_TRANSFORM_GET_CLASS (bml_transform);
  GstBML *bml = GST_BML (bml_transform);
  GstBMLClass *bml_class = GST_BML_CLASS (klass);
  BMLData *datai, *datao, *seg_datai, *seg_datao;
  gpointer bm = bml->bm;
  guint todo, seg_size, samples_per_buffer;
  gboolean has_data;
  guint mode = 3;               /*WM_READWRITE */

  bml->running_time =
      gst_segment_to_stream_time (&base->segment, GST_FORMAT_TIME,
      GST_BUFFER_TIMESTAMP (inbuf));

  if (GST_BUFFER_FLAG_IS_SET (outbuf, GST_BUFFER_FLAG_DISCONT)) {
    bml->subtick_count = (!bml->reverse) ? bml->subticks_per_tick : 1;
  }

  if (bml->subtick_count >= bml->subticks_per_tick) {
    bml (gstbml_reset_triggers (bml, bml_class));
    bml (gstbml_sync_values (bml, bml_class, GST_BUFFER_TIMESTAMP (outbuf)));
    bml (tick (bm));
    bml->subtick_count = 1;
  } else {
    bml->subtick_count++;
  }

  /* don't process data in passthrough-mode */
  if (gst_base_transform_is_passthrough (base)) {
    // we would actually need to convert mono to stereo here
    // but this is not even called
    GST_WARNING_OBJECT (bml_transform, "m2s in passthrough mode");
    //return GST_FLOW_OK;
  }

  if (!gst_buffer_map (inbuf, &infoi, GST_MAP_READ)) {
    GST_WARNING_OBJECT (base, "unable to map input buffer for read");
    return GST_FLOW_ERROR;
  }
  datai = (BMLData *) infoi.data;
  samples_per_buffer = infoi.size / sizeof (BMLData);
  if (!gst_buffer_map (outbuf, &infoo, GST_MAP_READ | GST_MAP_WRITE)) {
    GST_WARNING_OBJECT (base, "unable to map output buffer for read & write");
    return GST_FLOW_ERROR;
  }
  datao = (BMLData *) infoo.data;

  // some buzzmachines expect a cleared buffer
  //for(i=0;i<samples_per_buffer*2;i++) datao[i]=0.0f;
  memset (datao, 0, samples_per_buffer * 2 * sizeof (BMLData));

  /* if buffer has only silence process with different mode */
  if (GST_BUFFER_FLAG_IS_SET (outbuf, GST_BUFFER_FLAG_GAP)) {
    mode = 2;                   /* WM_WRITE */
  } else {
    gfloat fc = 32768.0;
    orc_scalarmultiply_f32_ns (datai, datai, fc, samples_per_buffer);
  }

  GST_DEBUG_OBJECT (bml_transform, "  calling work_m2s(%d,%d)",
      samples_per_buffer, mode);
  todo = samples_per_buffer;
  seg_datai = datai;
  seg_datao = datao;
  has_data = FALSE;
  while (todo) {
    // 256 is MachineInterface.h::MAX_BUFFER_LENGTH
    seg_size = (todo > 256) ? 256 : todo;
    has_data |= bml (work_m2s (bm, seg_datai, seg_datao, (int) seg_size, mode));
    seg_datai = &seg_datai[seg_size];
    seg_datao = &seg_datao[seg_size * 2];
    todo -= seg_size;
  }
  if (gstbml_fix_data ((GstElement *) bml_transform, &infoo, has_data)) {
    GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_GAP);
  } else {
    GST_BUFFER_FLAG_UNSET (outbuf, GST_BUFFER_FLAG_GAP);
  }

  gst_buffer_unmap (inbuf, &infoi);
  gst_buffer_unmap (outbuf, &infoo);
  return (GST_FLOW_OK);
}
예제 #13
0
static GstFlowReturn
gst_bml_transform_transform_ip_stereo (GstBaseTransform * base,
    GstBuffer * outbuf)
{
  GstMapInfo info;
  GstBMLTransform *bml_transform = GST_BML_TRANSFORM (base);
  GstBMLTransformClass *klass = GST_BML_TRANSFORM_GET_CLASS (bml_transform);
  GstBML *bml = GST_BML (bml_transform);
  GstBMLClass *bml_class = GST_BML_CLASS (klass);
  BMLData *data, *seg_data;
  gpointer bm = bml->bm;
  guint todo, seg_size, samples_per_buffer;
  gboolean has_data;
  guint mode = 3;               /*WM_READWRITE */

  bml->running_time =
      gst_segment_to_stream_time (&base->segment, GST_FORMAT_TIME,
      GST_BUFFER_TIMESTAMP (outbuf));

  if (GST_BUFFER_FLAG_IS_SET (outbuf, GST_BUFFER_FLAG_DISCONT)) {
    bml->subtick_count = (!bml->reverse) ? bml->subticks_per_tick : 1;
  }

  /* TODO(ensonic): sync on subticks ? */
  if (bml->subtick_count >= bml->subticks_per_tick) {
    bml (gstbml_reset_triggers (bml, bml_class));
    bml (gstbml_sync_values (bml, bml_class, GST_BUFFER_TIMESTAMP (outbuf)));
    bml (tick (bm));
    bml->subtick_count = 1;
  } else {
    bml->subtick_count++;
  }

  /* don't process data in passthrough-mode */
  if (gst_base_transform_is_passthrough (base))
    return GST_FLOW_OK;

  if (!gst_buffer_map (outbuf, &info, GST_MAP_READ | GST_MAP_WRITE)) {
    GST_WARNING_OBJECT (base, "unable to map buffer for read & write");
    return GST_FLOW_ERROR;
  }
  data = (BMLData *) info.data;
  samples_per_buffer = info.size / (sizeof (BMLData) * 2);

  /* if buffer has only silence process with different mode */
  if (GST_BUFFER_FLAG_IS_SET (outbuf, GST_BUFFER_FLAG_GAP)) {
    mode = 2;                   /* WM_WRITE */
  } else {
    gfloat fc = 32768.0;
    orc_scalarmultiply_f32_ns (data, data, fc, samples_per_buffer * 2);
  }

  GST_DEBUG_OBJECT (bml_transform, "  calling work_m2s(%d,%d)",
      samples_per_buffer, mode);
  todo = samples_per_buffer;
  seg_data = data;
  has_data = FALSE;
  while (todo) {
    // 256 is MachineInterface.h::MAX_BUFFER_LENGTH
    seg_size = (todo > 256) ? 256 : todo;
    // first seg_data can be NULL, its ignored
    has_data |= bml (work_m2s (bm, seg_data, seg_data, (int) seg_size, mode));
    seg_data = &seg_data[seg_size * 2];
    todo -= seg_size;
  }
  if (gstbml_fix_data ((GstElement *) bml_transform, &info, has_data)) {
    GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_GAP);
  } else {
    GST_BUFFER_FLAG_UNSET (outbuf, GST_BUFFER_FLAG_GAP);
  }

  gst_buffer_unmap (outbuf, &info);

  return (GST_FLOW_OK);
}