-
-
Save Hyp-X/a5df43224f09a3ccb8faee57c7220e53 to your computer and use it in GitHub Desktop.
A quick example of how to play a mouse-controlled sine wave using the DSPGraph preview package
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using Unity.Collections; | |
using Unity.Audio; | |
using Unity.Mathematics; | |
using Unity.Burst; | |
/* | |
For allocations inside AudioKernels, use Allocator.AudioKernel | |
*/ | |
public class DspApplication : MonoBehaviour { | |
private DSPGraph _graph; | |
private AudioOutputHandle _outputHandle; | |
private DSPNode _node; | |
private const int SAMPLERATE = 48000; | |
private const int NUMFRAMES = 1024; | |
private const int NUMCHANNELS = 2; | |
private bool _isRunning; | |
private void Awake() { | |
var audioConfig = AudioSettings.GetConfiguration(); | |
Debug.Log("Unity Audio Config:"); | |
Debug.Log(audioConfig.sampleRate); | |
Debug.Log(audioConfig.dspBufferSize); | |
Debug.Log(audioConfig.speakerMode); | |
_graph = DSPGraph.Create(SoundFormat.Stereo, NUMCHANNELS, NUMFRAMES, SAMPLERATE); | |
// Create a driver that just drives the graph mix based on when the system wants samples | |
var driver = new DefaultDspGraphDriver { _graph = _graph }; | |
// Attach this driver and graph to the audio output that's configured in Unity | |
_outputHandle = driver.AttachToDefaultOutput(); | |
var cmd = _graph.CreateCommandBlock(); | |
_node = cmd.CreateDSPNode<OscParams, OscProviders, Osc>(); | |
cmd.AddOutletPort(_node, NUMCHANNELS, SoundFormat.Stereo); | |
cmd.Connect(_node, 0, _graph.RootDSP, 0); | |
cmd.SetFloat<OscParams, OscProviders, Osc>(_node, OscParams.Frequency, 440f); | |
cmd.Complete(); | |
} | |
private void OnDestroy() { | |
var cmd = _graph.CreateCommandBlock(); | |
cmd.ReleaseDSPNode(_node); | |
cmd.Complete(); | |
_outputHandle.Dispose(); | |
} | |
private void Update() { | |
var cmd = _graph.CreateCommandBlock(); | |
float pitch = 440f + 220f * Input.GetAxis("Mouse Y"); | |
cmd.SetFloat<OscParams, OscProviders, Osc>(_node, OscParams.Frequency, pitch); | |
cmd.Complete(); | |
} | |
private const float TWOPI = math.PI * 2f; | |
private enum OscParams { | |
Frequency | |
} | |
private enum OscProviders { | |
Provider | |
} | |
[BurstCompile] | |
private struct Osc : IAudioKernel<OscParams, OscProviders> { | |
private float _phase; | |
private float _phaseStep; | |
private float _freq; | |
public void Initialize() {} | |
public void Dispose() {} | |
public void Execute(ref ExecuteContext<OscParams, OscProviders> context) { | |
for (int outIdx = 0; outIdx < context.Outputs.Count; outIdx++) { | |
var sampleBuffer = context.Outputs.GetSampleBuffer(outIdx); | |
var buffer = sampleBuffer.Buffer; | |
for (int i = 0; i < NUMFRAMES; i++) { | |
/* | |
Manually interpolate frequency parameter (have not yet been able to get the | |
automatic parameter interpolation system to behave yet) | |
*/ | |
_freq = math.lerp(_freq, context.Parameters.GetFloat(OscParams.Frequency, i), 0.001f); | |
_phaseStep = (TWOPI * _freq) / (float)SAMPLERATE; | |
buffer[i*NUMCHANNELS] = math.sin(_phase); | |
buffer[i*NUMCHANNELS+1] = buffer[i * NUMCHANNELS]; | |
_phase += _phaseStep; | |
if (_phase > TWOPI) { | |
_phase -= TWOPI; | |
} | |
} | |
} | |
} | |
} | |
} | |
[BurstCompile] | |
public struct DefaultDspGraphDriver : IAudioOutput { | |
public DSPGraph _graph; | |
private int _channelCount; | |
public void Initialize(int channelCount, SoundFormat format, int sampleRate, long dspBufferSize) { | |
_channelCount = channelCount; | |
} | |
public void BeginMix(int frameCount) { | |
_graph.BeginMix(frameCount); | |
} | |
public void EndMix(NativeArray<float> output, int frames) { | |
_graph.ReadMix(output, frames, _channelCount); | |
} | |
public void Dispose() { | |
_graph.Dispose(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment