Example #1
0
        private async Task RunConnect()
        {
            var ct      = ProcessCancel.Token;
            var taskSet = new HashSet <Task>();

            var blockSize = (int)(Param.SamplingRate * Param.SampleLength);

            Logger.LogInformation($"[loop3] blockSize {blockSize}");

            var audioInterval = (long)(10_000_000.0 * Param.SampleLength);

            Logger.LogInformation($"[loop3] audioInterval {audioInterval}");
            var videoInterval = (long)(10_000_000.0 / Param.MaxFrameRate);

            Logger.LogInformation($"[loop3] videoInterval {videoInterval}");

            var counter = new ElapsedTimeCounter();

            using var audioWaiter   = new Waiter(counter, audioInterval);
            using var videoWaiter   = new Waiter(counter, videoInterval);
            using var buf           = new IPCBuffer <float>(Param.EffectName, blockSize * 2 * Param.BufferCount, LoggerFactory);
            using var vstBufferPool = new BufferPool <VstBuffer2 <float> >(Param.BufferCount, () => new VstBuffer2 <float>(blockSize, 2, buf), LoggerFactory);
            using var pcmPool       = new BufferPool <PcmBuffer <float> >(Param.BufferCount, () => new PcmBuffer <float>(blockSize, 2), LoggerFactory);
            using var audioPool     = new BufferPool <OpusOutputBuffer>(Param.BufferCount, () => new OpusOutputBuffer(5000), LoggerFactory);
            using var pcmDrowPool   = new BufferPool <PcmBuffer <float> >(Param.BufferCount, () => new PcmBuffer <float>(blockSize, 2), LoggerFactory);
            using var bmpPool       = new BufferPool <H264InputBuffer>(Param.BufferCount, () => new H264InputBuffer(Param.Width, Param.Height), LoggerFactory);
            using var videoPool     = new BufferPool <H264OutputBuffer>(Param.BufferCount, () => new H264OutputBuffer(200000), LoggerFactory);
            using var vst           = new AudioMaster <float>(Param.SamplingRate, blockSize, LoggerFactory, counter, DllManager);
            using var toPcm         = new ToPcm <float>(LoggerFactory, counter);
            using var opus          = new OpusEncoder(SamplingRate.Sampling48000, Channels.Stereo, LoggerFactory, counter);
            using var fft           = new FFTEncoder(Param.Width, Param.Height, Param.MaxFrameRate, LoggerFactory, counter);
            using var h264          = new H264Encoder(Param.Width, Param.Height, Param.TargetBitrate, Param.MaxFrameRate, LoggerFactory, counter);
            var effect = vst.AddEffect(Param.EffectName);

            using var ftl = new FtlIngest(StreamKey, IngestHostname, LoggerFactory, counter, audioInterval, videoInterval, default, CaInfoPath);
Example #2
0
    public VstHost(
        int samplingRate,
        int blockSize,
        ILoggerFactory loggerFactory
        )
    {
        _loggerFactory = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory));
        _logger        = _loggerFactory.CreateLogger <VstHost>();

        _param = new("vstTimeInfo", 1, _loggerFactory);
        var p = _param.AsSpan(0, 1);

        p[0].vstTimeInfo.samplePos          = 0.0;
        p[0].vstTimeInfo.sampleRate         = samplingRate;
        p[0].vstTimeInfo.nanoSeconds        = 0.0;
        p[0].vstTimeInfo.ppqPos             = 0.0;
        p[0].vstTimeInfo.tempo              = 240.0;
        p[0].vstTimeInfo.barStartPos        = 0.0;
        p[0].vstTimeInfo.cycleStartPos      = 0.0;
        p[0].vstTimeInfo.cycleEndPos        = 0.0;
        p[0].vstTimeInfo.timeSigNumerator   = 4;
        p[0].vstTimeInfo.timeSigDenominator = 4;
        p[0].vstTimeInfo.smpteOffset        = 0;
        p[0].vstTimeInfo.smpteFrameRate     = VstTimeInfo.VstSmpteFrameRate.kVstSmpte24fps;
        p[0].vstTimeInfo.samplesToNextClock = 0;
        p[0].vstTimeInfo.flags              = VstTimeInfo.VstTimeInfoFlags.kVstTempoValid | VstTimeInfo.VstTimeInfoFlags.kVstNanosValid;

        p[0].vstProcessLevels = VstProcessLevels.kVstProcessLevelRealtime;
        p[0].samplingRate     = samplingRate;
        p[0].blockSize        = blockSize;
    }
Example #3
0
    public VstBuffer2(int blockSize, int channels, IPCBuffer <T> buf)
    {
        if (blockSize < 1)
        {
            throw new ArgumentOutOfRangeException(nameof(blockSize), blockSize, "1以上にしてください");
        }

        if (channels < 1)
        {
            throw new ArgumentOutOfRangeException(nameof(channels), channels, "1以上にしてください");
        }

        if (buf == default)
        {
            throw new ArgumentNullException(nameof(buf));
        }

        Buffer    = new(new IntPtr[channels]);
        Log       = new();
        BlockSize = blockSize;
        for (var i = 0; i < channels; i++)
        {
            Buffer.Target[i] = buf.Allocate(blockSize);
        }
    }
        public AudioMaster(
            int samplingRate,
            int blockSize,
            ILoggerFactory loggerFactory,
            ElapsedTimeCounter counter,
            IDllManager dllManager
            )
        {
            _loggerFactory = loggerFactory;
            _logger        = _loggerFactory.CreateLogger <AudioMaster <T> >();
            _counter       = counter;
            DllManager     = dllManager;

            _param = new("vstTimeInfo", 1, _loggerFactory);
            var p = _param.AsSpan(0, 1);

            p[0].vstTimeInfo.samplePos          = 0.0;
            p[0].vstTimeInfo.sampleRate         = samplingRate;
            p[0].vstTimeInfo.nanoSeconds        = 0.0;
            p[0].vstTimeInfo.ppqPos             = 0.0;
            p[0].vstTimeInfo.tempo              = 240.0;
            p[0].vstTimeInfo.barStartPos        = 0.0;
            p[0].vstTimeInfo.cycleStartPos      = 0.0;
            p[0].vstTimeInfo.cycleEndPos        = 0.0;
            p[0].vstTimeInfo.timeSigNumerator   = 4;
            p[0].vstTimeInfo.timeSigDenominator = 4;
            p[0].vstTimeInfo.smpteOffset        = 0;
            p[0].vstTimeInfo.smpteFrameRate     = VstTimeInfo.VstSmpteFrameRate.kVstSmpte24fps;
            p[0].vstTimeInfo.samplesToNextClock = 0;
            p[0].vstTimeInfo.flags              = VstTimeInfo.VstTimeInfoFlags.kVstTempoValid | VstTimeInfo.VstTimeInfoFlags.kVstNanosValid;

            p[0].vstProcessLevels = VstProcessLevels.kVstProcessLevelRealtime;
            p[0].samplingRate     = samplingRate;
            p[0].blockSize        = blockSize;
        }
        public void Test1()
        {
            var configuration =
                new ConfigurationBuilder()
                .AddJsonFile("appsettings.json")
                .Build();

            using var loggerFactory = LoggerFactory.Create(builder =>
            {
                builder.AddConfiguration(configuration);
                builder.AddConsole();
                builder.AddDebug();
            });

            using var test = new IPCBuffer <Struct>("test", 2, loggerFactory);
            {
                var s1 = test.AsSpan(0, 2);

                s1[0].a = 10;
                s1[0].b = 20;
                s1[0].c = 30;
                s1[0].d = 40;

                s1[1].a = 50;
                s1[1].b = 60;
                s1[1].c = 70;
                s1[1].d = 80;

                var s2 = test.AsSpan(0, 1);
                Assert.Equal(10, s2[0].a);
                Assert.Equal(20, s2[0].b);
                Assert.Equal(30, s2[0].c);
                Assert.Equal(40, s2[0].d);

                var s3 = test.AsSpan(1, 1);
                Assert.Equal(50, s3[0].a);
                Assert.Equal(60, s3[0].b);
                Assert.Equal(70, s3[0].c);
                Assert.Equal(80, s3[0].d);
            }
        }
Example #6
0
        private async Task RunLocal()
        {
            var ct      = ProcessCancel.Token;
            var taskSet = new HashSet <Task>();

            var blockSize = (int)(Param.SamplingRate * Param.SampleLength);

            Logger.LogInformation($"[loop5] blockSize {blockSize}");

            var audioInterval = (long)(10_000_000.0 * Param.SampleLength);

            Logger.LogInformation($"[loop5] audioInterval {audioInterval}");
            var videoInterval = (long)(10_000_000.0 / Param.MaxFrameRate);

            Logger.LogInformation($"[loop5] videoInterval {videoInterval}");

            var counter = new ElapsedTimeCounter();

            using var audioWaiter   = new Waiter(counter, audioInterval);
            using var videoWaiter   = new Waiter(counter, videoInterval);
            using var buf           = new IPCBuffer <float>(Param.EffectName, blockSize * 2 * Param.BufferCount, LoggerFactory);
            using var vstBufferPool = new BufferPool <VstBuffer2 <float> >(Param.BufferCount, () => new VstBuffer2 <float>(blockSize, 2, buf), LoggerFactory);
            using var pcmPool       = new BufferPool <PcmBuffer <float> >(Param.BufferCount, () => new PcmBuffer <float>(blockSize, 2), LoggerFactory);
            using var audioPool     = new BufferPool <OpusOutputBuffer>(Param.BufferCount, () => new OpusOutputBuffer(5000), LoggerFactory);
            using var pcmDrowPool   = new BufferPool <PcmBuffer <float> >(Param.BufferCount, () => new PcmBuffer <float>(blockSize, 2), LoggerFactory);
            using var bmpPool       = new BufferPool <H264InputBuffer>(Param.BufferCount, () => new H264InputBuffer(Param.Width, Param.Height), LoggerFactory);
            using var videoPool     = new BufferPool <H264OutputBuffer>(Param.BufferCount, () => new H264OutputBuffer(200000), LoggerFactory);
            using var vst           = new AudioMaster <float>(Param.SamplingRate, blockSize, LoggerFactory, counter, DllManager);
            using var toPcm         = new ToPcm <float>(LoggerFactory, counter);
            using var opus          = new OpusEncoder(SamplingRate.Sampling48000, Channels.Stereo, LoggerFactory, counter);
            using var fft           = new FFTEncoder(Param.Width, Param.Height, Param.MaxFrameRate, LoggerFactory, counter);
            using var h264          = new H264Encoder(Param.Width, Param.Height, Param.TargetBitrate, Param.MaxFrameRate, LoggerFactory, counter);
            var effect = vst.AddEffect(Param.EffectName);

            var options = new ExecutionDataflowBlockOptions
            {
                CancellationToken      = ct,
                MaxDegreeOfParallelism = 1,
                MaxMessagesPerTask     = DataflowBlockOptions.Unbounded
            };

            {
                var audioBlock =
                    new ActionBlock <VstBuffer2 <float> >(async buffer =>
                {
                    var pcmTask   = pcmPool.ReceiveAsync(ct);
                    var audioTask = audioPool.ReceiveAsync(ct);

                    buffer.Log.Clear();
                    audioWaiter.Wait();
                    buffer.Log.Add("[audio] start", counter.NowTicks);

                    //VST
                    var nowTime = counter.NowTicks / 10;
                    effect.ProcessEvent(nowTime, MidiEventInput);
                    effect.ProcessReplacing(nowTime, buffer);

                    //trans
                    var pcm = await pcmTask.ConfigureAwait(false);
                    buffer.Log.Add("[audio] opus input get", counter.NowTicks);
                    toPcm.Execute(buffer, pcm);
                    vstBufferPool.Post(buffer);

                    var audio = await audioTask.ConfigureAwait(false);
                    pcm.Log.Add("[audio] opus output get", counter.NowTicks);
                    opus.Execute(pcm, audio);

                    pcmDrowPool.Post(pcm);

                    //FTL
                    //   ftl.Execute(audio);

                    audioPool.Post(audio);
                }, options);
                taskSet.Add(audioBlock.Completion);
                vstBufferPool.LinkTo(audioBlock);
            }

            {
                var midiDataStoreBlock =
                    new ActionBlock <MIDIMessageEvent2>(buffer =>
                {
                    fft.Receive(buffer);
                }, options);
                taskSet.Add(midiDataStoreBlock.Completion);
                MidiEventOutput.LinkTo(midiDataStoreBlock);

                var pcmDataStoreBlock =
                    new ActionBlock <PcmBuffer <float> >(buffer =>
                {
                    fft.Receive(buffer);
                    pcmPool.Post(buffer);
                }, options);
                taskSet.Add(pcmDataStoreBlock.Completion);
                pcmDrowPool.LinkTo(pcmDataStoreBlock);

                var intraFrameCount = 0.0;

                var videoBlock =
                    new ActionBlock <H264InputBuffer>(async buffer =>
                {
                    var videoTask = videoPool.ReceiveAsync(ct);

                    buffer.Log.Clear();

                    videoWaiter.Wait();
                    buffer.Log.Add("[video] start", counter.NowTicks);

                    //FFT
                    fft.Execute(buffer);

                    //H264
                    var video = await videoTask.ConfigureAwait(false);
                    buffer.Log.Add("[video] h264 output get", counter.NowTicks);

                    var insertIntraFrame = (intraFrameCount <= 0);
                    h264.Execute(buffer, video, insertIntraFrame);

                    bmpPool.Post(buffer);
                    if (insertIntraFrame)
                    {
                        intraFrameCount = Param.IntraFrameIntervalUs;
                    }
                    intraFrameCount -= videoInterval;

                    //FTL
                    //ftl.Execute(video);

                    videoPool.Post(video);
                }, options);
                taskSet.Add(videoBlock.Completion);
                bmpPool.LinkTo(videoBlock);
            }

            while (taskSet.Count > 0)
            {
                var task = await Task.WhenAny(taskSet).ConfigureAwait(false);

                taskSet.Remove(task);
                if (task.IsFaulted)
                {
                    ProcessCancel.Cancel();
                    Logger.LogError(task.Exception, "Process Exception");
                }
            }
        }