void Start() { var format = ChannelEnumConverter.GetSoundFormatFromSpeakerMode(AudioSettings.speakerMode); var channels = ChannelEnumConverter.GetChannelCountFromSoundFormat(format); AudioSettings.GetDSPBufferSize(out var bufferLength, out var numBuffers); var sampleRate = AudioSettings.outputSampleRate; m_Graph = DSPGraph.Create(format, channels, bufferLength, sampleRate); var driver = new DefaultDSPGraphDriver { Graph = m_Graph }; m_Output = driver.AttachToDefaultOutput(); // Add an event handler delegate to the graph for ClipStopped. So we are notified // of when a clip is stopped in the node and can handle the resources on the main thread. m_HandlerID = m_Graph.AddNodeEventHandler <ClipStopped>((node, evt) => { Debug.Log("Received ClipStopped event on main thread, cleaning resources"); }); // All async interaction with the graph must be done through a DSPCommandBlock. // Create it here and complete it once all commands are added. var block = m_Graph.CreateCommandBlock(); m_Node = block.CreateDSPNode <PlayClipNode.Parameters, PlayClipNode.SampleProviders, PlayClipNode>(); // Currently input and output ports are dynamic and added via this API to a node. // This will change to a static definition of nodes in the future. block.AddOutletPort(m_Node, 2, SoundFormat.Stereo); // Connect the node to the root of the graph. m_Connection = block.Connect(m_Node, 0, m_Graph.RootDSP, 0); // We are done, fire off the command block atomically to the mixer thread. block.Complete(); }