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"); }
static guint gst_bml_child_proxy_get_children_count (GstChildProxy * child_proxy) { GstBMLTransform *bml_transform = GST_BML_TRANSFORM (child_proxy); GstBML *bml = GST_BML (bml_transform); return (bml->num_voices); }
static void gst_bml_transform_finalize (GObject * object) { GstBMLTransform *bml_transform = GST_BML_TRANSFORM (object); GstBML *bml = GST_BML (bml_transform); bml (gstbml_finalize (bml)); G_OBJECT_CLASS (parent_class)->finalize (object); }
static void gst_bml_tempo_change_tempo (GstBtTempo * tempo, glong beats_per_minute, glong ticks_per_beat, glong subticks_per_tick) { GstBMLTransform *bml_transform = GST_BML_TRANSFORM (tempo); GstBML *bml = GST_BML (bml_transform); bml (gstbml_tempo_change_tempo (G_OBJECT (bml_transform), bml, beats_per_minute, ticks_per_beat, subticks_per_tick)); }
static void gst_bml_transform_dispose (GObject * object) { GstBMLTransform *bml_transform = GST_BML_TRANSFORM (object); GstBML *bml = GST_BML (bml_transform); gstbml_dispose (bml); G_OBJECT_CLASS (parent_class)->dispose (object); }
static gboolean gst_bml_transform_stop (GstBaseTransform * base) { GstBMLTransform *bml_transform = GST_BML_TRANSFORM (base); GstBML *bml = GST_BML (bml_transform); gpointer bm = bml->bm; bml (stop (bm)); return TRUE; }
static GObject * gst_bml_child_proxy_get_child_by_index (GstChildProxy * child_proxy, guint index) { GstBMLTransform *bml_transform = GST_BML_TRANSFORM (child_proxy); GstBML *bml = GST_BML (bml_transform); g_return_val_if_fail (index < bml->num_voices, NULL); return (gst_object_ref (g_list_nth_data (bml->voices, index))); }
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)); }
static gboolean gst_bml_preset_save_preset (GstPreset * preset, const gchar * name) { GstBMLTransform *bml_transform = GST_BML_TRANSFORM (preset); GstBMLTransformClass *klass = GST_BML_TRANSFORM_GET_CLASS (bml_transform); GstBML *bml = GST_BML (bml_transform); GstBMLClass *bml_class = GST_BML_CLASS (klass); return (gstbml_preset_save_preset (GST_OBJECT (preset), bml, bml_class, name)); }
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))); }
static void gstbt_bml_src_set_context (GstElement * element, GstContext * context) { guint bpm, tpb, stpb; if (gstbt_audio_tempo_context_get_tempo (context, &bpm, &tpb, &stpb)) { GstBML *bml = GST_BML (GST_BML_TRANSFORM (element)); bml (gstbml_tempo_change_tempo (G_OBJECT (element), bml, bpm, tpb, stpb)); } #if GST_CHECK_VERSION (1,8,0) GST_ELEMENT_CLASS (parent_class)->set_context (element, context); #else if (GST_ELEMENT_CLASS (parent_class)->set_context) { GST_ELEMENT_CLASS (parent_class)->set_context (element, context); } #endif }
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"); }
/* get notified of caps and reject unsupported ones */ static gboolean gst_bml_transform_set_caps (GstBaseTransform * base, GstCaps * incaps, GstCaps * outcaps) { GstBMLTransform *bml_transform = GST_BML_TRANSFORM (base); GstBML *bml = GST_BML (bml_transform); GstStructure *structure; gboolean ret; gint samplerate = bml->samplerate; GST_DEBUG ("set_caps: in %" GST_PTR_FORMAT " out %" GST_PTR_FORMAT, incaps, outcaps); structure = gst_caps_get_structure (incaps, 0); if ((ret = gst_structure_get_int (structure, "rate", &bml->samplerate)) && (samplerate != bml->samplerate)) { bml (set_master_info (bml->beats_per_minute, bml->ticks_per_beat, bml->samplerate)); // TODO(ensonic): irks, this resets all parameter to their default //bml(init(bml->bm,0,NULL)); } return ret; }
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); }
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); }