コード例 #1
0
    public void DisconnectionByHandle_ProducesDefaultSamples_InInputPorts(DSPGraph.ExecutionMode executionMode)
    {
        using (var testData = TestData.Create(true, TestData.DefaultChannelCount, TestData.DefaultSoundFormat, executionMode))
        {
            var channelCount = 1;
            var attenuation1 = 0.5F;
            testData.Attenuate(testData.Connection, attenuation1);
            var nodeData     = testData.CreateGeneratorNode();
            var attenuation2 = 0.25F;
            testData.Attenuate(nodeData.Connection, attenuation2);
            using (var buff = new NativeArray <float>(TestData.DefaultBufferSize * channelCount, Allocator.Temp))
                testData.Mix(buff, buff.Length / channelCount, channelCount);

            using (var block = testData.Graph.CreateCommandBlock())
                block.Disconnect(testData.Connection);

            testData.CheckMix(attenuation2);

            using (var block = testData.Graph.CreateCommandBlock())
                block.Disconnect(nodeData.Connection);

            testData.CheckMix(0.0F);

            testData.RemoveNode(nodeData.Node);
        }
    }
コード例 #2
0
    public void UncompletedBlock_IsNotExecuted(DSPGraph.ExecutionMode executionMode)
    {
        using (var setup = new GraphSetup())
        {
            var block = setup.Graph.CreateCommandBlock();
            var node  = block.CreateDSPNode <NoParameters, NoProviders, GenerateOne>();
            block.AddOutletPort(node, GraphSetup.ChannelCount, GraphSetup.SoundFormat);
            block.Connect(node, 0, setup.Graph.RootDSP, 0);

            using (var buffer = new NativeArray <float>(setup.Graph.DSPBufferSize * GraphSetup.ChannelCount, Allocator.Temp, NativeArrayOptions.ClearMemory))
            {
                setup.Graph.BeginMix(setup.Graph.DSPBufferSize, executionMode);
                setup.Graph.ReadMix(buffer, setup.Graph.DSPBufferSize, GraphSetup.ChannelCount);
                foreach (var sample in buffer)
                {
                    Assert.AreEqual(0.0f, sample, 0.001f);
                }

                block.Complete();
                setup.Graph.BeginMix(setup.Graph.DSPBufferSize, executionMode);
                setup.Graph.ReadMix(buffer, setup.Graph.DSPBufferSize, GraphSetup.ChannelCount);
                foreach (var sample in buffer)
                {
                    Assert.AreEqual(1.0f, sample, 0.001f);
                }

                using (block = setup.Graph.CreateCommandBlock())
                    block.ReleaseDSPNode(node);
            }
        }
    }
コード例 #3
0
 public void InvalidExecutionMode_Throws(DSPGraph.ExecutionMode executionMode)
 {
     using (var testData = TestData.Create(false, TestData.DefaultChannelCount, TestData.DefaultSoundFormat, executionMode))
     {
         Assert.Throws <ArgumentException>(() => testData.CheckMix(0.0F));
     }
 }
コード例 #4
0
 public void ReadSampleProvider_PlaysSignal(DSPGraph.ExecutionMode executionMode)
 {
     using (var testData = CreateTestData <ReadSampleProviderKernel, Providers>(
                (block, node) => AddProviderToNode <ReadSampleProviderKernel>(block, node)))
     {
         CheckOutputBuffer(testData.Graph, (buffer) => CheckBufferHasValue(buffer, kSignalValueA), executionMode);
     }
 }
コード例 #5
0
 public void AttenuatedInput_ProducesAttenuatedResults_InInputPorts(DSPGraph.ExecutionMode executionMode)
 {
     using (var testData = TestData.Create(true, TestData.DefaultChannelCount, TestData.DefaultSoundFormat, executionMode))
     {
         var attenuation = 0.5F;
         testData.Attenuate(testData.Connection, attenuation);
         testData.CheckMix(attenuation);
     }
 }
コード例 #6
0
 public void AttenuatedInput_ProducesMultiChannelAttenuatedResults_InInputPorts(DSPGraph.ExecutionMode executionMode)
 {
     using (var testData = TestData.Create(true, 2, SoundFormat.Stereo, executionMode))
     {
         var attenuationLeft  = 0.3F;
         var attenuationRight = 0.7F;
         testData.Attenuate(testData.Connection, 0, attenuationLeft, attenuationRight);
         testData.CheckMix(attenuationLeft, attenuationRight);
     }
 }
コード例 #7
0
 public void ReadOverwrittenSampleProvider_PlaysNewSignal(DSPGraph.ExecutionMode executionMode)
 {
     using (var testData = CreateTestData <ReadSampleProviderKernel, Providers>(
                (block, node) => AddProviderToNode <ReadSampleProviderKernel>(block, node)))
     {
         using (var block = testData.Graph.CreateCommandBlock())
             AddProviderToNode <ReadSampleProviderKernel>(block, testData.Node, 0, kSignalValueB);
         CheckOutputBuffer(testData.Graph, (buffer) => CheckBufferHasValue(buffer, kSignalValueB), executionMode);
     }
 }
コード例 #8
0
 public void DSPClockIncrementsByLength(DSPGraph.ExecutionMode executionMode)
 {
     using (var setup = new GraphSetup())
     {
         for (int i = 0; i < 10; ++i)
         {
             Assert.AreEqual(i * setup.Graph.DSPBufferSize, setup.Graph.DSPClock);
             setup.PumpGraph();
         }
     }
 }
コード例 #9
0
 public void CancelingBlock_InvalidatesHandle(DSPGraph.ExecutionMode executionMode)
 {
     using (var setup = new GraphSetup())
     {
         var block = setup.Graph.CreateCommandBlock();
         var node  = block.CreateDSPNode <NoParameters, NoProviders, GenerateOne>();
         block.AddOutletPort(node, GraphSetup.ChannelCount, GraphSetup.SoundFormat);
         block.Connect(node, 0, setup.Graph.RootDSP, 0);
         block.Cancel();
         Assert.False(block.Valid);
     }
 }
コード例 #10
0
 public void MultiAttenuatedInput_ProducesSummedAttenuatedResults_InInputPorts(DSPGraph.ExecutionMode executionMode)
 {
     using (var testData = TestData.Create(true, TestData.DefaultChannelCount, TestData.DefaultSoundFormat, executionMode))
     {
         var attenuation1 = 0.5F;
         testData.Attenuate(testData.Connection, attenuation1);
         var nodeData     = testData.CreateGeneratorNode();
         var attenuation2 = 0.25F;
         testData.Attenuate(nodeData.Connection, attenuation2);
         testData.CheckMix(attenuation1 + attenuation2);
         testData.RemoveNode(nodeData.Node);
     }
 }
コード例 #11
0
    public void DSPNode_WithNoInputsOrOutputs_IsNotExecuted(DSPGraph.ExecutionMode executionMode)
    {
        DSPNode node = default;

        using (var setup = new GraphSetup((graphSetup, graph, block) =>
        {
            node = graphSetup.CreateDSPNode <NoParameters, NoProviders, LifecycleTracking>();
        }))
        {
            setup.PumpGraph();
            Assert.AreEqual(0, LifecycleTracking.Executed);
        }
    }
コード例 #12
0
 public void MultipleBeginMix_Works(DSPGraph.ExecutionMode executionMode)
 {
     using (var setup = new GraphSetup())
     {
         using (var buffer = new NativeArray <float>(setup.Graph.DSPBufferSize * GraphSetup.ChannelCount, Allocator.Temp))
         {
             int i;
             for (i = 0; i < 10; ++i)
             {
                 setup.Graph.BeginMix(setup.Graph.DSPBufferSize);
             }
             setup.Graph.ReadMix(buffer, setup.Graph.DSPBufferSize, GraphSetup.ChannelCount);
             Assert.AreEqual(i * setup.Graph.DSPBufferSize, setup.Graph.DSPClock);
         }
     }
 }
コード例 #13
0
    public void Connect_WithInterleavedBlocks_DoesntCrash(DSPGraph.ExecutionMode executionMode)
    {
        using (var setup = new GraphSetup())
        {
            using (var outerBlock = setup.Graph.CreateCommandBlock())
            {
                var node = outerBlock.CreateDSPNode <NoParameters, NoProviders, NullAudioKernel>();
                using (var innerBlock = setup.Graph.CreateCommandBlock())
                {
                    innerBlock.AddOutletPort(node, GraphSetup.ChannelCount, GraphSetup.SoundFormat);
                    innerBlock.Connect(node, 0, setup.Graph.RootDSP, 0);
                }
            }

            LogAssert.Expect(LogType.Exception, kArgumentException);
        }
    }
コード例 #14
0
 public void MultiNoopInput_ProducesSummedAttenuatedResults_InInputPorts(DSPGraph.ExecutionMode executionMode)
 {
     // This test covers buffer stealing when inputs are noop (i.e. having a 1.0 non-animated attenuation).
     // Because buffer stealing is only applicable to inputs that don't belong to the root node, we
     // use an intermediate pass-through node (hence passing false to Create in order for it to not create the
     // generator that it normally creates and create a PassThrough instead).
     using (var testData = TestData.Create(false, TestData.DefaultChannelCount, TestData.DefaultSoundFormat, executionMode))
     {
         var generator1   = testData.CreateGeneratorNode(testData.Node);
         var attenuation1 = 1.0F;
         testData.Attenuate(generator1.Connection, attenuation1);
         var generator2   = testData.CreateGeneratorNode(testData.Node);
         var attenuation2 = 0.25F;
         testData.Attenuate(generator2.Connection, attenuation2);
         testData.CheckMix(attenuation1 + attenuation2);
         testData.RemoveNode(generator1.Node);
         testData.RemoveNode(generator2.Node);
     }
 }
コード例 #15
0
    public void ReleasingDSPNode_InChain_KillsSignal(DSPGraph.ExecutionMode executionMode)
    {
        DSPNode generator   = default;
        DSPNode passthrough = default;

        using (var setup = new GraphSetup((graphSetup, graph, block) =>
        {
            generator = block.CreateDSPNode <NoParameters, NoProviders, GenerateOne>();
            block.AddOutletPort(generator, GraphSetup.ChannelCount, GraphSetup.SoundFormat);

            passthrough = block.CreateDSPNode <NoParameters, NoProviders, PassThrough>();
            block.AddInletPort(passthrough, GraphSetup.ChannelCount, GraphSetup.SoundFormat);
            block.AddOutletPort(passthrough, GraphSetup.ChannelCount, GraphSetup.SoundFormat);

            block.Connect(generator, 0, passthrough, 0);
            block.Connect(passthrough, 0, graph.RootDSP, 0);
        }))
        {
            using (var buffer = new NativeArray <float>(setup.Graph.DSPBufferSize * GraphSetup.ChannelCount, Allocator.Temp))
            {
                setup.Graph.BeginMix(setup.Graph.DSPBufferSize);
                setup.Graph.ReadMix(buffer, setup.Graph.DSPBufferSize, GraphSetup.ChannelCount);
                foreach (var sample in buffer)
                {
                    Assert.AreEqual(1.0f, sample, 0.001f);
                }

                using (var block = setup.Graph.CreateCommandBlock())
                    block.ReleaseDSPNode(passthrough);

                setup.Graph.BeginMix(setup.Graph.DSPBufferSize);
                setup.Graph.ReadMix(buffer, setup.Graph.DSPBufferSize, GraphSetup.ChannelCount);
                foreach (var sample in buffer)
                {
                    Assert.AreEqual(0.0f, sample, 0.001f);
                }

                using (var block = setup.Graph.CreateCommandBlock())
                    block.ReleaseDSPNode(generator);
            }
        }
    }
コード例 #16
0
 public void MixOverwritesData(DSPGraph.ExecutionMode executionMode)
 {
     using (var setup = new GraphSetup((graphSetup, graph, block) =>
     {
         DSPNode node = graphSetup.CreateDSPNode <NoParameters, NoProviders, GenerateOne>();
         block.AddOutletPort(node, GraphSetup.ChannelCount, GraphSetup.SoundFormat);
         block.Connect(node, 0, graph.RootDSP, 0);
     }))
     {
         using (var buffer = new NativeArray <float>(setup.Graph.DSPBufferSize * GraphSetup.ChannelCount, Allocator.Temp, NativeArrayOptions.ClearMemory))
         {
             setup.Graph.BeginMix(setup.Graph.DSPBufferSize, executionMode);
             setup.Graph.ReadMix(buffer, setup.Graph.DSPBufferSize, GraphSetup.ChannelCount);
             foreach (var sample in buffer)
             {
                 Assert.AreEqual(1.0f, sample, 0.001f);
             }
         }
     }
 }
コード例 #17
0
    public void UpdateRequestCallsDelegate(DSPGraph.ExecutionMode executionMode)
    {
        var channelCount = 2;
        var soundFormat  = SoundFormat.Stereo;

        using (var graph = DSPGraph.Create(soundFormat, channelCount, 100, 1000))
        {
            DSPNode node;
            using (var block = graph.CreateCommandBlock())
            {
                node = block.CreateDSPNode <NoParameters, NoProviders, NullAudioKernel>();
                block.AddOutletPort(node, channelCount, soundFormat);
                block.Connect(node, 0, graph.RootDSP, 0);
            }

            using (var buff = new NativeArray <float>(200, Allocator.Temp))
            {
                graph.BeginMix(0, executionMode);
                graph.ReadMix(buff, buff.Length / channelCount, channelCount);

                var called = false;
                DSPNodeUpdateRequest <NullAudioKernelUpdater, NoParameters, NoProviders, NullAudioKernel> updateRequest;
                using (var block = graph.CreateCommandBlock())
                    updateRequest = block.CreateUpdateRequest <NullAudioKernelUpdater, NoParameters, NoProviders, NullAudioKernel>(
                        new NullAudioKernelUpdater(), node,
                        req => { called = true; });

                graph.BeginMix(0, executionMode);
                graph.ReadMix(buff, buff.Length / channelCount, channelCount);

                Assert.False(called);
                graph.Update();
                Assert.True(called);
                updateRequest.Dispose();
            }

            using (var block = graph.CreateCommandBlock())
                block.ReleaseDSPNode(node);
        }
    }
コード例 #18
0
    public void WritingToInputBuffer_Throws(DSPGraph.ExecutionMode executionMode)
    {
        using (var setup = new GraphSetup((graphSetup, graph, block) =>
        {
            DSPNode generator = graphSetup.CreateDSPNode <NoParameters, NoProviders, GenerateOne>();
            block.AddOutletPort(generator, kChannelCount, kSoundFormat);

            DSPNode node = graphSetup.CreateDSPNode <NoParameters, NoProviders, WritingToInputBufferKernel>();
            block.AddInletPort(node, kChannelCount, kSoundFormat);
            block.AddOutletPort(node, kChannelCount, kSoundFormat);

            block.Connect(generator, 0, node, 0);
            block.Connect(node, 0, graph.RootDSP, 0);
        }))
        {
            using (var buff = new NativeArray <float>(200, Allocator.TempJob))
            {
                setup.Graph.BeginMix(0, executionMode);
                setup.Graph.ReadMix(buff, 200 / kChannelCount, kChannelCount);
            }
        }
    }
コード例 #19
0
    public void AttenuatedInterpolatedInput_ProducesInterpolatedResults_InInputPorts(DSPGraph.ExecutionMode executionMode)
    {
        var channelCount = 2;
        var soundFormat  = SoundFormat.Stereo;

        using (var testData = TestData.Create(true, channelCount, soundFormat, executionMode))
        {
            var attenuation = 0.0F;
            testData.Attenuate(testData.Connection, attenuation, TestData.DefaultBufferSize);
            using (var buff = new NativeArray <float>(TestData.DefaultBufferSize * channelCount, Allocator.Temp))
            {
                testData.Mix(buff, buff.Length / channelCount, channelCount);
                VerifyInterpolatedAttenuation(buff, 0, TestData.DefaultBufferSize, channelCount,
                                              new[] { DSPConnection.DefaultAttenuation, DSPConnection.DefaultAttenuation },
                                              new []
                {
                    -1.0f / (TestData.DefaultBufferSize - 1),
                    -1.0f / (TestData.DefaultBufferSize - 1),
                });
            }
        }
    }
コード例 #20
0
    public void SustainedAttenuation_ProducesSameAttenuation_InInputPorts(DSPGraph.ExecutionMode executionMode)
    {
        var channelCount    = 2;
        var soundFormat     = SoundFormat.Stereo;
        var baseAttenuation = new[] { 0.0f, 0.0f };

        using (var testData = TestData.Create(true, channelCount, soundFormat, executionMode))
        {
            using (var block = testData.Graph.CreateCommandBlock())
            {
                block.SetAttenuation(testData.Connection, baseAttenuation[0]);
                block.AddAttenuationKey(testData.Connection, 49, 100.0f);
                block.SustainAttenuation(testData.Connection, 99);
            }

            using (var buff = new NativeArray <float>(TestData.DefaultBufferSize * channelCount, Allocator.Temp))
            {
                testData.Mix(buff, buff.Length / channelCount, channelCount);
                VerifyInterpolatedAttenuation(buff, 0, 50, channelCount,
                                              baseAttenuation,
                                              new []
                {
                    100.0f / 49,
                    100.0f / 49,
                });
                VerifyInterpolatedAttenuation(buff, 50, 50, channelCount,
                                              new[]
                {
                    100.0f,
                    100.0f,
                },
                                              new []
                {
                    0.0f,
                    0.0f,
                });
            }
        }
    }
コード例 #21
0
    public void UpdateValueFromKernel(DSPGraph.ExecutionMode executionMode)
    {
        var channelCount = 2;
        var soundFormat  = SoundFormat.Stereo;

        using (var graph = DSPGraph.Create(soundFormat, channelCount, 100, 1000))
        {
            DSPNode node;
            using (var block = graph.CreateCommandBlock())
            {
                node = block.CreateDSPNode <NoParameters, NoProviders, TestUpdateKernel>();
                block.AddOutletPort(node, channelCount, soundFormat);
                block.Connect(node, 0, graph.RootDSP, 0);
            }

            using (var buff = new NativeArray <float>(200, Allocator.Temp))
            {
                graph.BeginMix(0, executionMode);
                graph.ReadMix(buff, buff.Length / channelCount, channelCount);

                using (var block = graph.CreateCommandBlock())
                {
                    var kernelUpdater = new TestValueKernelUpdater
                    {
                        ValueToDrop = 69.0f
                    };

                    block.UpdateAudioKernel <TestValueKernelUpdater, NoParameters, NoProviders, TestUpdateKernel>(kernelUpdater, node);
                }

                graph.BeginMix(0, executionMode);
                graph.ReadMix(buff, buff.Length / channelCount, channelCount);
            }

            using (var block = graph.CreateCommandBlock())
                block.ReleaseDSPNode(node);
        }
    }
コード例 #22
0
    public void UnattachedSubtreesAreNotExecutedWithModeDisabled(DSPGraph.ExecutionMode executionMode)
    {
        using (var testData = TestData.Create(false, TestData.DefaultChannelCount, TestData.DefaultSoundFormat, executionMode))
        {
            DSPNode unattachedNode;
            using (var block = testData.Graph.CreateCommandBlock())
            {
                // Create a node that doesn't have an output path to the root of the graph
                unattachedNode = block.CreateDSPNode <NoParameters, NoProviders, LifecycleTracking>();
                block.AddOutletPort(testData.Node, TestData.DefaultChannelCount, TestData.DefaultSoundFormat);
                block.AddInletPort(unattachedNode, TestData.DefaultChannelCount, TestData.DefaultSoundFormat);
                block.AddOutletPort(unattachedNode, TestData.DefaultChannelCount, TestData.DefaultSoundFormat);
                block.Connect(testData.Node, 1, unattachedNode, 0);
            }
            testData.CheckMix(0.0F);

            // The lifecycle node should not be executing
            Assert.AreEqual(LifecycleTracking.LifecyclePhase.Initialized, LifecycleTracking.Phase);

            using (var block = testData.Graph.CreateCommandBlock())
                block.ReleaseDSPNode(unattachedNode);
        }
    }
コード例 #23
0
    public void InterruptedAttenuation_ContinuesWithAttenuatedValue(DSPGraph.ExecutionMode executionMode)
    {
        var channelCount = 2;
        var soundFormat  = SoundFormat.Stereo;

        using (var testData = TestData.Create(true, channelCount, soundFormat, executionMode))
        {
            var attenuation       = 0.0f;
            var attenuationLength = 2 * TestData.DefaultBufferSize;
            testData.Attenuate(testData.Connection, attenuation, attenuationLength);
            using (var buff = new NativeArray <float>(TestData.DefaultBufferSize * channelCount, Allocator.Temp))
            {
                float[] baseAttenuationValue = { DSPConnection.DefaultAttenuation, DSPConnection.DefaultAttenuation };
                float[] attenuationDelta     = { (-1 / ((float)(TestData.DefaultBufferSize * 2) - 1)), (-1 / ((float)(TestData.DefaultBufferSize * 2) - 1)) };

                testData.Mix(buff, buff.Length / channelCount, channelCount);
                VerifyInterpolatedAttenuation(buff, 0, TestData.DefaultBufferSize, channelCount, baseAttenuationValue, attenuationDelta);

                // Lookup updated connection from graph
                var connection = testData.Graph.LookupConnection(testData.Connection.Handle);
                baseAttenuationValue = new[] { connection.Attenuation.Value[0], connection.Attenuation.Value[1] };
                Assert.AreEqual(buff[(TestData.DefaultBufferSize * channelCount) - 1], baseAttenuationValue[0], 0.0001);

                testData.Attenuate(testData.Connection, DSPConnection.DefaultAttenuation, TestData.DefaultBufferSize);
                testData.Mix(buff, buff.Length / channelCount, channelCount);
                attenuationDelta = new[]
                {
                    (DSPConnection.DefaultAttenuation - baseAttenuationValue[0]) / (TestData.DefaultBufferSize - 1),
                    (DSPConnection.DefaultAttenuation - baseAttenuationValue[1]) / (TestData.DefaultBufferSize - 1),
                };
                VerifyInterpolatedAttenuation(buff, 0, TestData.DefaultBufferSize, channelCount, baseAttenuationValue, attenuationDelta);

                connection = testData.Graph.LookupConnection(testData.Connection.Handle);
                Assert.AreEqual(DSPConnection.DefaultAttenuation, connection.Attenuation.Value[0]);
            }
        }
    }
コード例 #24
0
 void CheckOutputBuffer(DSPGraph graph, Action <NativeArray <float> > check = null, DSPGraph.ExecutionMode executionMode = DSPGraph.ExecutionMode.Jobified)
 {
     using (var buffer = new NativeArray <float>(kChannelCount * kDspBufferSize, Allocator.Temp))
     {
         graph.BeginMix(0, executionMode);
         graph.ReadMix(buffer, kDspBufferSize, kChannelCount);
         check?.Invoke(buffer);
     }
 }
コード例 #25
0
 public void ConnectNodes_ProducesResults_InInputPorts(DSPGraph.ExecutionMode executionMode)
 {
     using (var testData = TestData.Create(true, TestData.DefaultChannelCount, TestData.DefaultSoundFormat, executionMode))
         testData.CheckMix(1.0F);
 }
コード例 #26
0
        public static TestData Create(bool createGenerator = true, int channelCount = DefaultChannelCount, SoundFormat soundFormat = DefaultSoundFormat, DSPGraph.ExecutionMode executionMode = DSPGraph.ExecutionMode.Jobified)
        {
            var      graph = DSPGraph.Create(soundFormat, channelCount, DefaultBufferSize, 1000);
            NodeData nodeData;

            using (var block = graph.CreateCommandBlock())
                nodeData = createGenerator ? CreateGeneratorNode(block, graph.RootDSP, channelCount, soundFormat) : CreatePassthroughNode(block, graph, channelCount, soundFormat);
            return(new TestData
            {
                Graph = graph,
                Node = nodeData.Node,
                Connection = nodeData.Connection,
                ExecutionMode = executionMode,
            });
        }