Formerly pd-andy/elm-web-audio. Search finds this package by either name.
Represents a value of some property. Our audio graphs are supposed to be declarative, so we don't want to be able to change the values of properties – you'd just return a different graph with the property you wanted changed.
This type enumerates the different types of values that might be assigned to
a property like an Elm String or Float, etc.
Create a custom property for a node. This is like writing node.type = 'sine'
in JavaScript:
import WebAudio.Property exposing (Property)
sine : Property
sine =
WebAudio.Property.property "type" (WebAudio.Property.string "sine")Ideally you'll end up using one of the predifined properties like type_
instead of this function, but it's provided in case you have custom audio nodes
with properties we might not know about.
Create a custom audio param for a node. This is like writing
node.frequency.value = 880 in JavaScript:
import WebAudio.Property exposing (Property)
middleA : Property
middleA =
WebAudio.Property.audioParam "frequency" 440Ideally you'll end up using one of the predifined properties like
frequency instead of this function, but it's provided in case you
have custom audio nodes with properties we might not know about.
Schedule an update to a property to take place at some point in the future.
This is like writing node.frequency.setValueAtTime(880, context.currentTime + 1)
in JavaScript:
import WebAudio.Property exposing (Property)
setAfterOneSecond : Float -> Property
setAfterOneSecond time =
WebAudio.Property.setValueAtTime
(time + 1)
(WebAudio.Property.frequency 880)❗️ Note that we're taking in a Float here for the current time, and using that
to calculate the time at which we want to set the value. Because our audio graphs
are declarative we don't schedule things from now, but rather we schedule
things for fixed, known values of time.
The best way to get the current time is to use every
or at to trigger a message carrying the context's
current time. If you want to trigger things to happen based on the time a
particular user event such as a click occured you can use
currentTime to get the current time from the
context.
import WebAudio
import WebAudio.Context exposing (Context)
import WebAudio.Property
type Event
= NoteOn Float
| ...
audio : Context -> Event -> List WebAudio.Node
audio context event =
case event of
NoteOn time ->
[ WebAudio.oscillator
-- See the docs further down for what
-- `linearRampToValueAtTime` does!
[ WebAudio.Property.linearRampToValueAtTime
(WebAudio.Context.currentTime context + 1)
(WebAudio.Property.frequency 880)
]
[ WebAudio.gain
[ WebAudio.Property.gain 0.5 ]
[ WebAudio.audioDestination ]
]
]
_ ->
...Be really careful when doing this, you can accidentally schedule a bunch of overlapping events if you're not paying attention!
Where setValueAtTime sets a property at a specific time,
linearRampToValueAtTime will smoothly ramp the property from its current value
to the target value until the given time.
Where setValueAtTime sets a property at a specific time,
exponentialRampToValueAtTime will ramp the property from its current value
to the target value until the given time using an exponential curve.
Often we perceive exponential curves as more natural than linear curves, so this is a good choice for things like gain or frequency.
Properties are how we configure the behaviour of audio nodes: things like an oscillator's frequency or a filter's cutoff.
This example showcases the different types of properties you can construct:
propertiesliketype_. These are typical object properties that are set on the node like any other JavaScript object, and might be abool,float,string, etc.audioParamslikefrequencyare special, and represent values that can be changed over time using the scheduled updates described below. These are alwaysFloats!Scheduled updates like
linearRampToValueAtTime. These describe how a property should change over time. These scheduled updates only work with audio params, and not normal properties.