| using GLib; | |
| using Gst; | |
| using System; | |
| using System.Collections.Generic; | |
| using System.Linq; | |
| using System.Reflection; | |
| using System.Runtime.InteropServices; | |
| using System.Text; | |
| namespace GstreamerSharp | |
| { | |
| class Program | |
| { | |
| static void Main(string[] args) | |
| { | |
| Gst.Application.Init(ref args); | |
| Element src = ElementFactory.Make("audiotestsrc"); | |
| Element convert = ElementFactory.Make("audioconvert"); | |
| Element volume = new ExampleVolume(); | |
| Element sink = ElementFactory.Make("autoaudiosink"); | |
| Pipeline pipeline = new Pipeline(); | |
| pipeline.Add(src, convert, volume, sink); | |
| Element.Link(src, convert, volume, sink); | |
| pipeline.SetState(State.Playing); | |
| MainLoop loop = new MainLoop(); | |
| loop.Run(); | |
| pipeline.SetState(State.Null); | |
| Console.ReadLine(); | |
| } | |
| } | |
| class ExampleVolume : Element | |
| { | |
| public ExampleVolume() | |
| { | |
| Volume = 0.5; | |
| _sink = new Pad(__sinkTemplate, "sink"); | |
| _sink.ChainFunctionFull = Chain; | |
| _sink.Flags |= PadFlags.ProxyCaps; | |
| AddPad(_sink); | |
| _src = new Pad(__srcTemplate, "src"); | |
| _src.Flags |= PadFlags.ProxyCaps; | |
| AddPad(_src); | |
| } | |
| public double Volume { get; set; } | |
| FlowReturn Chain(Pad pad, Gst.Object parent, Gst.Buffer buffer) | |
| { | |
| if (Volume == 1.0) | |
| { | |
| return _src.Push(buffer); | |
| } | |
| buffer.MakeWritable(); | |
| MapInfo mapInfo; | |
| buffer.Map(out mapInfo, MapFlags.Read | MapFlags.Write); | |
| ScaleInt16(mapInfo.DataPtr, mapInfo.Size / 2, Volume); | |
| buffer.Unmap(mapInfo); | |
| return _src.Push(buffer); | |
| } | |
| private unsafe void ScaleInt16(IntPtr data, ulong size, double volume) | |
| { | |
| Int16* sample = (Int16*)data; | |
| for (ulong i = 0; i < size; i++) | |
| { | |
| *sample = ClampInt16(*sample * volume); | |
| sample++; | |
| } | |
| } | |
| private Int16 ClampInt16(double d) | |
| { | |
| int i = (int)Math.Round(d); | |
| if (i > Int16.MaxValue) | |
| { | |
| return Int16.MaxValue; | |
| } | |
| else if (i < Int16.MinValue) | |
| { | |
| return Int16.MinValue; | |
| } | |
| else | |
| { | |
| return (Int16)i; | |
| } | |
| } | |
| Pad _src; | |
| Pad _sink; | |
| static ExampleVolume() | |
| { | |
| Caps audioCaps = Caps.FromString("audio/x-raw, format=(string) S16LE, rate=(int) [1, MAX], channels=(int) 2, layout=(string) interleaved"); | |
| __srcTemplate = new PadTemplate("src", PadDirection.Src, PadPresence.Always, audioCaps); | |
| __sinkTemplate = new PadTemplate("sink", PadDirection.Sink, PadPresence.Always, audioCaps); | |
| } | |
| static PadTemplate __srcTemplate; | |
| static PadTemplate __sinkTemplate; | |
| } | |
| } |