﻿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;
    }
}
