The AudioGraph module provides methods to construct detailed, type safe, web audio processing graphs in Elm. You can then use the AudioGraph.Encode module to serialise these graphs into JSON for proper reconstruction in javascript.
The AudioGraph keeps track of all active audio nodes and their connections.
createAudioGraph : AudioGraph
The primary method of creating a new AudioGraph. It is empty except for the default destination node stored under "__destination" NodeID. This typically represents the speaker output of your device.
See createAudioDestinationNote for more information.
setNode : NodeID -> AudioNode -> AudioGraph -> AudioGraph
Inserts a new AudioNode into the graph with the supplied id string. If a node already exists at the supplied id, the current node is replaced with the new one.
getNode : NodeID -> AudioGraph -> Maybe AudioNode
Queries the graph for the AudioNode at the supplied id string.
Can return Just AudioNode
or Nothing
if no node exists at that id.
removeNode : NodeID -> AudioGraph -> AudioGraph
Removes the AudioNode at the supplied id string from the graph. This is a no-op if no node exists at that id.
addConnection : Connection -> AudioGraph -> AudioGraph
Adds a new connection for the graph to track. There is a guard to prevent duplicate connections being added.
removeConnection : Connection -> AudioGraph -> AudioGraph
Removes the supplied connection from the graph. If the connection doesn't exist this is a no-op.
AudioNodes are the central focus of an AudioGraph. They represent any arbitrary audio processing node in a graph and can have any number of inputs, outputs, parameters, and properties.
InputChannel
s that are numbered from 0, or InputParam
s that expose
the node's params for connection. See NodeInput for more details.String
A simple type alias for more expressive type annotations. NodeIDs are used as keys in the AudioGraph nodes dictionary.
Describes what type of node an AudioNode represents. These are 1:1 mappings of the audio nodes detailed in the Web Audio API so refer here for more information on each node.
The AudioParam type represents a Web Audio audio param. The follow description is abridged from the Web Audio API docs:
The Web Audio API's AudioParam interface represents an audio-related parameter, usually a parameter of an AudioNode (such as GainNode.gain)
There are two kinds of AudioParam, a-rate and k-rate parameters:
- An a-rate AudioParam takes the current audio parameter value for each sample frame of the audio signal.
- A k-rate AudioParam uses the same initial audio parameter value for the whole block processed, that is 128 sample frames.
The distinction between a-rate and k-rate is useful to know when processing audio,
but does not impact how params are used. All AudioParam
s can be modulated by
AudioNode
s.
A NodeProperty is used in much the same way as an AudioParam.
The key distinction is that NodeProperties cannot be modulated by other AudioNodes
.
While their values can be updated programmatically, they cannot be continuously modulated by an audio signal.
Every AudioNode can have some number of inputs, and these inputs can correspond to a direct audio input channel on the node, or an AudioParam.
label
of the parameter to connect to.createAnalyserNode : AudioNode
Creates an AnalyserNode.
AudioNode
{ nodeType = AnalyserNode
, params = []
, properties =
[ NodeProperty { label = "fftSize", value = FFT_Size 2048 }
, NodeProperty { label = "minDecibels", value = Decibels -100 }
, NodeProperty { label = "maxDecibels", value = Decibels -30 }
, NodeProperty { label = "smoothingTimeConstant", value = Number 0.8 }
]
, inputs =
[ InputChannel 0
]
, numOutputs = 1
}
createAudioBufferSourceNode : AudioNode
Creates an AudioBufferSourceNode.
AudioNode
{ nodeType = AudioBufferSourceNode
, params =
[ AudioParam { label = "detune", value = Cents 0 }
, AudioParam { label = "playbackRate", value = Number 1.0 }
]
, properties =
[ NodeProperty { label = "buffer", value = Buffer [] }
, NodeProperty { label = "loop", value = Attribute False }
, NodeProperty { label = "loopStart", value = Number 0 }
, NodeProperty { label = "loopEnd", value = Number 0 }
]
, inputs =
[ InputParam "detune"
, InputParam "playerbackRate"
]
, numOutputs = 1
}
createAudioDestinationNode : AudioNode
Creates an AudioDestinationNode.
AudioNode
{ nodeType = AudioDestinationNode
, params = []
, properties = []
, inputs =
[ InputChannel 0
]
, numOutputs = 0
}
createBiquadFilterNode : AudioNode
Creates a BiquadFilterNode.
AudioNode
{ nodeType = BiquadFilterNode
, params =
[ AudioParam { label = "frequency", value = Hertz 350 }
, AudioParam { label = "detune", value = Cents 0 }
, AudioParam { label = "Q", value = Number 1.0 }
]
, properties =
[ NodeProperty { label = "type", value = FilterType Lowpass }
]
, inputs =
[ InputParam "frequency"
, InputParam "detune"
, InputParam "Q"
]
, numOutputs = 1
}
createChannelMergerNode : AudioNode
Creates a ChannelMergerNode.
AudioNode
{ nodeType = ChannelMergerNode
, params = []
, properties = []
, inputs =
[ InputChannel 0
, InputChannel 1
, InputChannel 2
, InputChannel 3
, InputChannel 4
, InputChannel 5
]
, numOutputs = 1
}
createChannelSplitterNode : AudioNode
Creates a ChannelSplitterNode.
AudioNode
{ nodeType = ChannelSplitterNode
, params = []
, properties = []
, inputs =
[ InputChannel 0
]
, numOutputs = 6
}
createConstantSourceNode : AudioNode
Creates a ConstantSourceNode.
AudioNode
{ nodeType = ConstantSourceNode
, params =
[ AudioParam { label = "offset", value = Number 1.0 }
]
, properties = []
, inputs =
[ InputParam "offset"
]
, numOutputs = 1
}
createConvolverNode : AudioNode
Creates a ConvolverNode.
AudioNode
{ nodeType = ConvolverNode
, params = []
, properties =
[ NodeProperty { label = "buffer", value = Buffer [] }
, NodeProperty { label = "normalize", value = Attribute False }
]
, inputs =
[ InputChannel 0
]
, numOutputs = 1
}
createDelayNode : AudioNode
Creates a DelayNode.
AudioNode
{ nodeType = DelayNode
, params =
[ AudioParam { label = "delayTime", value = Number 0 }
]
, properties =
[ NodeProperty { label = "maxDelayTime", value = Number 1.0 }
]
, inputs =
[ InputChannel 0
, InputParam "delayTime"
]
, numOutputs = 1
}
createDynamicsCompressorNode : AudioNode
Creates a DynamicsCompressorNode.
AudioNode
{ nodeType = DynamicsCompressorNode
, params =
[ AudioParam { label = "threshold", value = Decibels -24 }
, AudioParam { label = "knee", value = Decibels 30 }
, AudioParam { label = "ratio", value = Number 12 }
, AudioParam { label = "attack", value = Number 0.003 }
, AudioParam { label = "release", value = Number 0.25 }
]
, properties = []
, inputs =
[ InputChannel 0
, InputParam "threshold"
, InputParam "knee"
, InputParam "ratio"
, InputParam "attack"
, InputParam "release"
]
, numOutputs = 1
}
createGainNode : AudioNode
Creates a GainNode.
AudioNode
{ nodeType = GainNode
, params =
[ AudioParam { label = "gain", value = Number 1.0 }
]
, properties = []
, inputs =
[ InputChannel 0
, InputParam "gain"
]
, numOutputs = 1
}
createIIRFilterNode : AudioNode
Creates an IIRFilterNode.
AudioNode
{ nodeType = IIRFilterNode
, params =
[ AudioParam { label = "feedforward", value = Coefficients [] }
, AudioParam { label = "feedbackward", value = Coefficients [] }
]
, properties = []
, inputs =
[ InputChannel 0
, InputParam "feedforward"
, InputParam "feedbackward"
]
, numOutputs = 1
}
createOscillatorNode : AudioNode
Creates an OscillatorNode.
AudioNode
{ nodeType = OscillatorNode
, params =
[ AudioParam { label = "frequency", value = Hertz 350 }
, AudioParam { label = "detune", value = Cents 0 }
]
, properties =
[ NodeProperty { label = "type", value = WaveformType Sine }
]
, inputs =
[ InputParam "frequency"
, InputParam "detune"
]
, numOutputs = 1
}
createPannerNode : AudioNode
Creates a PannerNode.
AudioNode
{ nodeType = PannerNode
, params =
[ AudioParam { label = "orientationX", value = Number 1 }
, AudioParam { label = "orientationY", value = Number 0 }
, AudioParam { label = "orientationZ", value = Number 0 }
, AudioParam { label = "positionX", value = Number 0 }
, AudioParam { label = "positionY", value = Number 0 }
, AudioParam { label = "positionZ", value = Number 0 }
]
, properties =
[ NodeProperty { label = "coneInnerAngle", value = Number 360 }
, NodeProperty { label = "coneOuterAngle", value = Number 0 }
, NodeProperty { label = "coneOuterGain", value = Number 0 }
, NodeProperty { label = "distanceModel", value = DistanceModelType Inverse }
, NodeProperty { label = "maxDistance", value = Number 10000 }
, NodeProperty { label = "panningModel", value = PanningModelType EqualPower }
, NodeProperty { label = "refDistance", value = Number 1 }
, NodeProperty { label = "rolloffFactor", value = Number 1 }
]
, inputs =
[ InputChannel 0
, InputParam "orientationX"
, InputParam "orientationY"
, InputParam "orientationZ"
, InputParam "positionX"
, InputParam "positionY"
, InputParam "positionZ"
]
, numOutputs = 1
}
createStereoPannerNode : AudioNode
Creates a StereoPannerNode.
AudioNode
{ nodeType = StereoPannerNode
, params =
[ AudioParam { label = "pan", value = Number 0 }
]
, properties = []
, inputs =
[ InputChannel 0
, InputParam "pan"
]
, numOutputs = 1
}
createWaveShaperNode : AudioNode
Creates a WaveShaperNode.
AudioNode
{ nodeType = WaveShaperNode
, params = []
, properties =
[ NodeProperty { label = "curve", value = WaveshaperCurve [] }
, NodeProperty { label = "oversample", value = OversampleType None }
]
, inputs =
[ InputChannel 0
]
, numOutputs = 1
}
updateParam : String -> Units.Value -> AudioNode -> AudioNode
Update the Value stored in an AudioParam.
Note: If an AudioNode is connected to this param, updateParam
will
have no effect.
updateProperty : String -> Units.Value -> AudioNode -> AudioNode
Update the Value stored in a NodeProperty.
{ outputNode : NodeID
, outputChannel : Basics.Int
, inputNode : NodeID
, inputDestination : NodeInput
}
A Connection describes how one AudioNode connects to another. A connection can exist in two forms: either a node can connect directly to another node's audio input, or a node can connect to another node's params. The type of connection is detailed by the inputDestination field.
See the NodeInput definition for more information.
-- Connect the output of "oscA" to the first input
-- of "gain".
connect "oscA" 0 "gain" (InputChannel 0)
-- Connect the output of "oscB" to the frequency param
-- of "oscA" to perform frequency modulation.
connect "oscB" 0 "oscA" (InputParam "frequency")
connect : NodeID -> Basics.Int -> NodeID -> NodeInput -> Connection
A simple helper function to create a Connection. This is the preferred way to construct Connections to avoid breaking API changes if the Conncection type alias changes.