Play Audio
as part of an Interface
.
import Time
import Web
import Web.Audio
type alias State =
{ audioSource : Maybe (Result Web.AudioSourceLoadError Web.AudioSource)
, audioStartTime : Maybe Time.Posix
}
{ initialState =
{ audioSource = Nothing
, audioStartTime = Nothing
}
, interface =
\state ->
case state.audioSource of
Just (Ok audioSource) ->
case state.audioStartTime of
Just startTime
Web.Audio.fromSource audioSource startTime
|> Web.Audio.play
Nothing ->
Web.Time.posixRequest
|> Web.interfaceFutureMap
(\time -> { state | audioSTartTime = time |> Just })
Nothing ->
Web.Audio.sourceLoad "https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/Yodel_Sound_Effect.mp3"
|> Web.interfaceFutureMap
(\result -> { state | audioSource = result |> Just })
Just (Err _) ->
Web.Console.error "audio failed to load"
}
sourceLoad : String -> Web.Interface (Result Web.AudioSourceLoadError Web.AudioSource)
An Interface
for fetching audio data from a given url
and returning an AudioSource
to use with fromSource
.
fromSource : Web.AudioSource -> Time.Posix -> Web.Audio
Create Audio
from an given loaded source
which will play at a given time
-- play a song at half speed and wait 2 seconds after the usual song start time before starting
Web.Audio.fromSource
myCoolSong
(Duration.addTo usualSongStartTime (Duration.seconds 2))
|> Web.Audio.speedScaleBy (Web.Audio.Parameter.at 0.5)
Note that in some browsers audio will be muted until the user interacts with the webpage.
play : Web.Audio -> Web.Interface future_
An Interface
for playing Audio
created with Audio.fromSource
.
To play multiple audios:
[ audio0, audio1, audio2 ]
|> List.map Web.Audio.play
|> Web.interfaceBatch
volumeScaleBy : Web.AudioParameterTimeline -> Web.Audio -> Web.Audio
Scale how loud it is. 1 preserves the current volume, 0.5 halves it, and 0 mutes it. If the the volume is less than 0, 0 will be used instead.
speedScaleBy : Web.AudioParameterTimeline -> Web.Audio -> Web.Audio
Scale the playback rate by a given factor. This will also affect pitch.
For example, Web.Audio.speedScaleBy 0.5
means playback will take twice as long and the pitch will be one octave lower, see AudioBufferSourceNode.playbackRate
In general, to pitch by semitones:
Web.Audio.speedScaleBy
(Web.Audio.Parameter.at (2 ^ (semitones / 12)))
Note: It would be possible to modify the signal to compensate for the pitch change, see Audio time stretching and pitch scaling. Help appreciated!
stereoPan : Web.AudioParameterTimeline -> Web.Audio -> Web.Audio
Change the stereo panning with a given a signed percentage parameter.
Web.Audio.pan -0.9
for example means that the sound is almost fully balanced towards the left speaker
addLinearConvolutionWith : Web.AudioSource -> Web.Audio -> Web.Audio
Usually used to apply reverb and or echo.
Given a loaded AudioSource
containing the impulse response,
it performs a Convolution with the Audio
If you need some nice impulse wavs to try it out, there's a few at dhiogoboza/audio-convolution
.
If you know more nice ones, don't hesitate to open an issue or a PR.
addHighpassFromFrequency : Web.AudioParameterTimeline -> Web.Audio -> Web.Audio
Frequencies below a given cutoff parameter are attenuated; frequencies above it pass through.
Has a 12dB/octave rolloff and no peak at the cutoff.