[{"name":"WebAudio","comment":"\n\n\n# Types\n\n@docs Node\n\n\n# Basic Constructors\n\n@docs node, ref, keyed, param\n\n\n# Web Audio Nodes\n\n\n## Common audio nodes\n\n@docs oscillator, osc, gain, audioDestination, dac, delay\n\n\n## Utility nodes\n\n@docs channelMerger, channelSplitter, constantSource\n\n\n## Signal processing nodes\n\n@docs biquadFilter, convolver, dynamicsCompressor, iirFilter, panner\n@docs stereoPanner, waveShaper\n\n@docs encode\n\n","unions":[{"name":"Node","comment":" Represents a node in an audio processing singal graph. There are a handful\nof basic constructors: [`node`](#node) for creating typical audio nodes,\n[`keyed`](#keyed) for attaching a key or id to an existing node, and [`ref`](#ref)\nfor referencing a node elsewhere in the graph by id.\n\nThere are also a number of constructors for specific audio nodes, such as\n[`oscillator`](#oscillator) and [`gain`](#gain). These constructors mirror the\nlow-level nodes provided by the Web Audio API: they make great building blocks!\n\n    import WebAudio\n    import WebAudio.Property\n\n    synth : Float -> Float -> List WebAudio.Node -> WebAudio.Node\n    synth freq gain connections =\n        WebAudio.oscillator\n            [ WebAudio.Parameters.frequency freq ]\n            [ WebAudio.gain\n                [ WebAudio.Parameters.gain gain ]\n                connections\n            ]\n\n","args":[],"cases":[]}],"aliases":[],"values":[{"name":"audioDestination","comment":" The audio destination is... the destination of our audio! Connect to this\nnode to get sound coming out of your speakers.\n\nIt doesn't have any parameters itself, and it doesn't make sense to connect\nthe destination to anything else; it's the end of the line.\n\n    import WebAudio\n    import WebAudio.Property\n\n    audio : List WebAudio.Node\n    audio =\n        [ WebAudio.oscillator\n            [ WebAudio.Property.frequency 440 ]\n            [ WebAudio.audioDestination ]\n        ]\n\nSee: <https://developer.mozilla.org/en-US/docs/Web/API/AudioDestinationNode>\n\n","type":"WebAudio.Node"},{"name":"biquadFilter","comment":" See: <https://developer.mozilla.org/en-US/docs/Web/API/BiquadFilterNode>\nCommon properties:\n\n  - frequency\n  - detune\n  - Q\n  - type\n\n","type":"List.List WebAudio.Property.Property -> List.List WebAudio.Node -> WebAudio.Node"},{"name":"channelMerger","comment":" See: <https://developer.mozilla.org/en-US/docs/Web/API/ChannelMergerNode>\n","type":"List.List WebAudio.Property.Property -> List.List WebAudio.Node -> WebAudio.Node"},{"name":"channelSplitter","comment":" See: <https://developer.mozilla.org/en-US/docs/Web/API/ChanneSplliterNode>\n","type":"List.List WebAudio.Property.Property -> List.List WebAudio.Node -> WebAudio.Node"},{"name":"constantSource","comment":" See: <https://developer.mozilla.org/en-US/docs/Web/API/ConstantSourceNode>\nCommon properties:\n\n  - offset\n\n","type":"List.List WebAudio.Property.Property -> List.List WebAudio.Node -> WebAudio.Node"},{"name":"convolver","comment":" See: <https://developer.mozilla.org/en-US/docs/Web/API/ConvolverNode>\nCommon properties:\n\n  - buffer\n  - normalize | normalise\n\n","type":"List.List WebAudio.Property.Property -> List.List WebAudio.Node -> WebAudio.Node"},{"name":"dac","comment":" An alias for `audioDestination`. DAC is another common name for output: it\nstands for _digital to analog converter_.\n","type":"WebAudio.Node"},{"name":"delay","comment":" See: <https://developer.mozilla.org/en-US/docs/Web/API/DelayNode>\nCommon properties:\n\n  - delayTime\n\n","type":"List.List WebAudio.Property.Property -> List.List WebAudio.Node -> WebAudio.Node"},{"name":"dynamicsCompressor","comment":" See: <https://developer.mozilla.org/en-US/docs/Web/API/DynamicsCompressorNode>\nCommon properties:\n\n  - threshold\n  - knee\n  - ratio\n  - reduction\n  - attack\n  - release\n\n","type":"List.List WebAudio.Property.Property -> List.List WebAudio.Node -> WebAudio.Node"},{"name":"encode","comment":" Converts a `Node` into a value we can through a port to some JavaScript that\ncan actually convert our signal graph into Web Audio code.\n\nYou could also go on to seriliase the graph with `Json.Encode.encode` and send\nit to a server, store it in LocalStorage, or other fun things.\n\n","type":"WebAudio.Node -> Json.Encode.Value"},{"name":"gain","comment":" See: <https://developer.mozilla.org/en-US/docs/Web/API/GainNode>\nCommon properties:\n\n  - gain\n\n","type":"List.List WebAudio.Property.Property -> List.List WebAudio.Node -> WebAudio.Node"},{"name":"iirFilter","comment":" See: <https://developer.mozilla.org/en-US/docs/Web/API/>\n","type":"List.List WebAudio.Property.Property -> List.List WebAudio.Node -> WebAudio.Node"},{"name":"keyed","comment":" Attach a key or id to an existing node. This is commonly used in conjunction\nwith [`ref`](#ref) nodes to create feedback loops and other more complex signal\ngraphs.\n","type":"String.String -> WebAudio.Node -> WebAudio.Node"},{"name":"node","comment":" The most general way to construct Web Audio nodes. This is used to create all\nthe helper functions below.\n\nYou can use this function to define custom nodes by partially applying just the\n`type` parameter. This is handy if you're using a library like Tone.js and want\nto use those nodes in Elm.\n\n    import WebAudio\n    import WebAudio.Property exposing (Property)\n\n    omniOscillator : List Property -> List WebAudio.Node -> WebAudio.Node\n    omniOscillator =\n        WebAudio.node \"Tone-OmniOscillatorNode\"\n\n    myOsc : WebAudio.Node\n    myOsc =\n        omniOscillator\n            [ WebAudio.Property.frequency 440 ]\n            [ WebAudio.dac ]\n\n","type":"String.String -> List.List WebAudio.Property.Property -> List.List WebAudio.Node -> WebAudio.Node"},{"name":"osc","comment":" An alias for `oscillator`.\n\nIt turns out oscillators are pretty common in lots of audio signal graphs. It\nalso turns out that \"oscillator\" is a pretty long word, so you can use `osc`\ninstead to save your fingers and your eyes.\n\n","type":"List.List WebAudio.Property.Property -> List.List WebAudio.Node -> WebAudio.Node"},{"name":"oscillator","comment":" See: <https://developer.mozilla.org/en-US/docs/Web/API/OscillatorNode>\nCommon properties:\n\n  - frequency\n  - detune\n  - type\n\n","type":"List.List WebAudio.Property.Property -> List.List WebAudio.Node -> WebAudio.Node"},{"name":"panner","comment":" See: <https://developer.mozilla.org/en-US/docs/Web/API/PannerNode>\nCommon properties:\n\n  - coneInnerAngle\n  - coneOuterAngle\n  - coneOuterGain\n  - distanceModel\n  - maxDistance\n  - orientationX\n  - orientationY\n  - orientationZ\n  - panningModel\n  - positionX\n  - positionY\n  - positionZ\n  - refDistance\n  - rolloffFactor\n\n","type":"List.List WebAudio.Property.Property -> List.List WebAudio.Node -> WebAudio.Node"},{"name":"param","comment":" Typically we chain audio nodes together either implicitly by nesting them or\nexplicitly by using [`ref`](#ref) nodes but there is a third way to connect\naudio nodes: by connecting them to certain audio params!\n\nThis is useful for common synthesis techniques like AM and FM synthesis, or\nmodulating parameters like cutoff frequencer of a filter using an oscillator.\n\n    import WebAudio\n    import WebAudio.Property\n\n    audio : List WebAudio.Node\n    audio =\n        [ WebAudio.oscillator\n            [ WebAudio.Property.frequency 5 ]\n            -- Connect to the \"frequency\" parameter of the \"carrier\" node\n            [ WebAudio.param \"carrier\" \"frequency\" ]\n        , WebAudio.keyed \"carrier\" <|\n            WebAudio.oscillator []\n                [ WebAudio.dac ]\n        ]\n\n","type":"String.String -> String.String -> WebAudio.Node"},{"name":"ref","comment":" A ref node is used to refer to some other audio node by id. We can do things\nlike create a feedback loop by connecting a node back into itself.\n\n    import WebAudio\n    import WebAudio.Property exposing (Property)\n\n    feedbackDelay : Float -> Float -> List WebAudio.Node -> WebAudio.Node\n    feedbackDelay amount time connections =\n        WebAudio.keyed \"feedback-delay\" <|\n            WebAudio.delay\n                [ WebAudio.Property.delayTime time ]\n                [ WebAudio.gain\n                    [ WebAudio.Property.gain gain ]\n                    -- Reference the delay node above by its key. This sends\n                    -- the output of the gain node back into the delay node,\n                    -- creating a feedback loop!\n                    (WebAudio.ref \"feedback-delay\" :: connections)\n                ]\n\n    synth : Float -> Float -> WebAudio.Node\n    synth freq gain =\n        WebAudio.oscillator\n            [ WebAudio.Parameters.frequency freq ]\n            [ WebAudio.gain\n                [ WebAudio.Parameters.gain gain ]\n                [ feedbackDelay 0.45 250 <|\n                    [ WebAudio.dac ]\n                ]\n            ]\n\n","type":"String.String -> WebAudio.Node"},{"name":"stereoPanner","comment":" See: <https://developer.mozilla.org/en-US/docs/Web/API/StereoPannerNode>\nCommon properties:\n\n  - pan\n\n","type":"List.List WebAudio.Property.Property -> List.List WebAudio.Node -> WebAudio.Node"},{"name":"waveShaper","comment":" See: <https://developer.mozilla.org/en-US/docs/Web/API/WaveShaperNode>\nCommon properties:\n\n  - curve\n  - oversample\n\n","type":"List.List WebAudio.Property.Property -> List.List WebAudio.Node -> WebAudio.Node"}],"binops":[]},{"name":"WebAudio.Context","comment":"\n\n\n# Types\n\n@docs AudioContext, State\n\n\n# Constructors\n\n@docs from\n\n\n# AudioContext Property Accessors\n\n@docs currentTime, sampleRate, state, baseLatency, outputLatency\n\n\n# Subscriptions\n\n@docs every\n\n","unions":[{"name":"AudioContext","comment":" An AudioContext is a simple alias for a Json.Decode.Value. By making clever\nuse of a context's [computed properties](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get)\nwe can decode information such as the current time or the context's state whenver\nwe need it.\n\n```javascript\nconst context = new AudioContext()\nconst App = Elm.Main.init({\n  node: document.querySelector('#app'),\n  flags: context\n})\n```\n\nBy passing an AudioContext to the Elm app through flags, we can pass it on to the\nproperty accessors below whenever we need to query the state of the context.\n\n","args":[],"cases":[]},{"name":"State","comment":" The state of an AudioContext encoded as a nice Elm union type. Mostly handy\nto prevent unecessary calcultions of audio graphs if the context is suspended or\nclosed.\n","args":[],"cases":[["Suspended",[]],["Running",[]],["Closed",[]]]}],"aliases":[],"values":[{"name":"baseLatency","comment":" The base latency of an AudioContext is the number of seconds of processing\nlatency incurred by the AudioContext passing the audio from the AudioDestinationNode\nto the audio subsystem.\n","type":"WebAudio.Context.AudioContext -> Basics.Float"},{"name":"currentTime","comment":" Get the time since an AudioContext was started. This is necessary if you want\nto use scheduled audio properties to update values in the future (like an amplitude\nenvelope perhaps).\n","type":"WebAudio.Context.AudioContext -> Basics.Float"},{"name":"every","comment":" This function works like Time.every, and allows us to get an AudioContext's\ncurrent time according to some interval. There are some important differences\nbetween this and Time.every, however.\n\nIn javascript land setInterval can be hugely inconsistent, making musical timing\ndifficult as the interval drifts over time. To combat this we can combine setInterval\nwith a short interval and an AudioContext to look ahead in time, making it possible\nto schedule sample-accurate updates.\n\nBecause of this, the AudioContext time returned by `every` will usually be a few\nmilliseconds in the future. This works great when combined with scheduled parameter\nupdates!\n\n    type alias Model =\n      { time : Float\n      , context : AudioContext\n      , freq : Float\n      , ...\n      }\n\n    type Msg\n      = NoOp\n      | NextStep Float\n      | ...\n\n    audio model =\n      osc [ setValueAtTime (freq model.freq) model.time ]\n        [ dac ]\n\n    ...\n\n    -- Every 250ms move to the next step in a sequencer.\n    subscriptions model =\n      every 0.25 model.time NoOp NextStep model.context\n\nBecause we poll rapidly with Time.every, we provide a NoOp msg to return whenver\nwe're _not_ at the next time interval. This is a necessary evil because of how\nElm handles time subscriptions.\n\n","type":"Basics.Float -> Basics.Float -> msg -> (Basics.Float -> msg) -> WebAudio.Context.AudioContext -> Platform.Sub.Sub msg"},{"name":"from","comment":" ","type":"Json.Decode.Value -> Maybe.Maybe WebAudio.Context.AudioContext"},{"name":"outputLatency","comment":" The output latency of an Audio Context is the time, in seconds, between the\nbrowser requesting the host system to play a buffer and the time at which the first\nsample in the buffer is actually processed by the audio output device.\n","type":"WebAudio.Context.AudioContext -> Basics.Float"},{"name":"sampleRate","comment":" Find out what sample rate an AudioContext is running at, in samples per second.\n","type":"WebAudio.Context.AudioContext -> Basics.Float"},{"name":"state","comment":" Find out what state an AudioContext is currently in. An AudioContext can either\nbe Suspended, Running, or Closed.\n\nIt is common for AudioContexts to start in a Suspended state and must be resumed\nafter some user interaction event. By using a port we can resume an AudioContext\nafter a user interactios with our Elm app.\n\n","type":"WebAudio.Context.AudioContext -> WebAudio.Context.State"}],"binops":[]},{"name":"WebAudio.Property","comment":"\n\n\n# Types\n\n@docs Property, Value\n\n\n# Basic Constructors\n\n@docs property, audioParam\n@docs setValueAtTime, linearRampToValueAtTime, exponentialRampToValueAtTime\n\n\n## Primatives\n\n@docs bool, float, floatList, int, string\n\n\n# Properties\n\n@docs amp, attack, coneInnerAngle, coneOuterAngle, coneOuterGain, curve\n@docs delayTime, detune, distanceModel, fftSize, frequency, freq, gain, knee\n@docs loop, loopEnd, loopStart, maxChannelCount, maxDecibels, minDecibels\n@docs normalize, offset, orientationX, orientationY, orientationZ, oversample\n@docs pan, panningModel, playbackRate, positionX, positionY, positionZ, q, ratio\n@docs reduction, refDistance, release, rolloffFactor, smoothingTimeConstant\n@docs threshold, type_\n\n\n# JSON Encoding\n\n@docs encode\n\n","unions":[{"name":"Property","comment":" Properties are how we configure the behaviour of audio nodes: things like\nan oscillator's frequency or a filter's cutoff.\n\n    import WebAudio\n    import WebAudio.Property\n\n    myOsc =\n        WebAudio.oscillator\n            [ WebAudio.Property.linearRampToValueAtTime 1 <|\n                WebAudio.Property.frequency 880\n            , WebAudio.Property.type_ \"sine\"\n            ]\n            [ WebAudio.gain\n                [ WebAudio.Property.gain 0.5 ]\n                [ WebAudio.audioDestination ]\n            ]\n\nThis example showcases the different types of properties you can construct:\n\n  - [`properties`](#property) like [`type_`](#type_). These are typical object\n    properties that are set on the node like any other JavaScript object, and\n    might be a [`bool`](#bool), [`float`](#float), [`string`](#string), etc.\n\n  - [`audioParams`](#audioParam) like [`frequency`](#frequency) are special,\n    and represent values that can be changed over time using the scheduled updates\n    described below. These are always `Float`s!\n\n  - Scheduled updates like [`linearRampToValueAtTime`](#linearRampToValueAtTime).\n    These describe how a property should change over time. These scheduled updates\n    only work with audio params, and not normal properties.\n\n","args":[],"cases":[]},{"name":"Value","comment":" Represents a value of some property. Our audio graphs are supposed to be\n_declarative_, so we don't want to be able to change the values of properties –\nyou'd just return a different graph with the property you wanted changed.\n\nThis type enumerates the different types of values that might be assigned to\na property like an Elm `String` or `Float`, etc.\n\n","args":[],"cases":[]}],"aliases":[],"values":[{"name":"amp","comment":" ","type":"Basics.Float -> WebAudio.Property.Property"},{"name":"attack","comment":" ","type":"Basics.Float -> WebAudio.Property.Property"},{"name":"audioParam","comment":" Create a custom audio param for a node. This is like writing\n`node.frequency.value = 880` in JavaScript:\n\n    import WebAudio.Property exposing (Property)\n\n    middleA : Property\n    middleA =\n        WebAudio.Property.audioParam \"frequency\" 440\n\nIdeally you'll end up using one of the predifined properties like\n[`frequency`](#frequency) instead of this function, but it's provided in case you\nhave custom audio nodes with properties we might not know about.\n\n","type":"String.String -> Basics.Float -> WebAudio.Property.Property"},{"name":"bool","comment":" ","type":"Basics.Bool -> WebAudio.Property.Value"},{"name":"coneInnerAngle","comment":" ","type":"Basics.Float -> WebAudio.Property.Property"},{"name":"coneOuterAngle","comment":" ","type":"Basics.Float -> WebAudio.Property.Property"},{"name":"coneOuterGain","comment":" ","type":"Basics.Float -> WebAudio.Property.Property"},{"name":"curve","comment":" ","type":"List.List Basics.Float -> WebAudio.Property.Property"},{"name":"delayTime","comment":" ","type":"Basics.Float -> WebAudio.Property.Property"},{"name":"detune","comment":" ","type":"Basics.Float -> WebAudio.Property.Property"},{"name":"distanceModel","comment":" ","type":"String.String -> WebAudio.Property.Property"},{"name":"encode","comment":" ","type":"WebAudio.Property.Property -> Json.Encode.Value"},{"name":"exponentialRampToValueAtTime","comment":" Where [`setValueAtTime`](#setValueAtTime) sets a property at a specific time,\n`exponentialRampToValueAtTime` will ramp the property from its current value\nto the target value until the given time using an exponential curve.\n\nOften we perceive exponential curves as more natural than linear curves, so this\nis a good choice for things like gain or frequency.\n\n","type":"Basics.Float -> WebAudio.Property.Property -> WebAudio.Property.Property"},{"name":"fftSize","comment":" ","type":"Basics.Int -> WebAudio.Property.Property"},{"name":"float","comment":" ","type":"Basics.Float -> WebAudio.Property.Value"},{"name":"floatList","comment":" ","type":"List.List Basics.Float -> WebAudio.Property.Value"},{"name":"freq","comment":" ","type":"Basics.Float -> WebAudio.Property.Property"},{"name":"frequency","comment":" ","type":"Basics.Float -> WebAudio.Property.Property"},{"name":"gain","comment":" ","type":"Basics.Float -> WebAudio.Property.Property"},{"name":"int","comment":" ","type":"Basics.Int -> WebAudio.Property.Value"},{"name":"knee","comment":" ","type":"Basics.Float -> WebAudio.Property.Property"},{"name":"linearRampToValueAtTime","comment":" Where [`setValueAtTime`](#setValueAtTime) sets a property at a specific time,\n`linearRampToValueAtTime` will smoothly ramp the property from its current value\nto the target value until the given time.\n","type":"Basics.Float -> WebAudio.Property.Property -> WebAudio.Property.Property"},{"name":"loop","comment":" ","type":"Basics.Bool -> WebAudio.Property.Property"},{"name":"loopEnd","comment":" ","type":"Basics.Float -> WebAudio.Property.Property"},{"name":"loopStart","comment":" ","type":"Basics.Float -> WebAudio.Property.Property"},{"name":"maxChannelCount","comment":" ","type":"Basics.Int -> WebAudio.Property.Property"},{"name":"maxDecibels","comment":" ","type":"Basics.Float -> WebAudio.Property.Property"},{"name":"minDecibels","comment":" ","type":"Basics.Float -> WebAudio.Property.Property"},{"name":"normalize","comment":" ","type":"Basics.Bool -> WebAudio.Property.Property"},{"name":"offset","comment":" ","type":"Basics.Float -> WebAudio.Property.Property"},{"name":"orientationX","comment":" ","type":"Basics.Float -> WebAudio.Property.Property"},{"name":"orientationY","comment":" ","type":"Basics.Float -> WebAudio.Property.Property"},{"name":"orientationZ","comment":" ","type":"Basics.Float -> WebAudio.Property.Property"},{"name":"oversample","comment":" ","type":"String.String -> WebAudio.Property.Property"},{"name":"pan","comment":" ","type":"Basics.Float -> WebAudio.Property.Property"},{"name":"panningModel","comment":" ","type":"String.String -> WebAudio.Property.Property"},{"name":"playbackRate","comment":" ","type":"Basics.Float -> WebAudio.Property.Property"},{"name":"positionX","comment":" ","type":"Basics.Float -> WebAudio.Property.Property"},{"name":"positionY","comment":" ","type":"Basics.Float -> WebAudio.Property.Property"},{"name":"positionZ","comment":" ","type":"Basics.Float -> WebAudio.Property.Property"},{"name":"property","comment":" Create a custom property for a node. This is like writing `node.type = 'sine'`\nin JavaScript:\n\n    import WebAudio.Property exposing (Property)\n\n    sine : Property\n    sine =\n        WebAudio.Property.property \"type\" (WebAudio.Property.string \"sine\")\n\nIdeally you'll end up using one of the predifined properties like [`type_`](#type_)\ninstead of this function, but it's provided in case you have custom audio nodes\nwith properties we might not know about.\n\n","type":"String.String -> WebAudio.Property.Value -> WebAudio.Property.Property"},{"name":"q","comment":" ","type":"Basics.Float -> WebAudio.Property.Property"},{"name":"ratio","comment":" ","type":"Basics.Float -> WebAudio.Property.Property"},{"name":"reduction","comment":" ","type":"Basics.Float -> WebAudio.Property.Property"},{"name":"refDistance","comment":" ","type":"Basics.Float -> WebAudio.Property.Property"},{"name":"release","comment":" ","type":"Basics.Float -> WebAudio.Property.Property"},{"name":"rolloffFactor","comment":" ","type":"Basics.Float -> WebAudio.Property.Property"},{"name":"setValueAtTime","comment":" Schedule an update to a property to take place at some point in the future.\nThis is like writing `node.frequency.setValueAtTime(880, context.currentTime + 1)`\nin JavaScript:\n\n    import WebAudio.Property exposing (Property)\n\n    setAfterOneSecond : Float -> Property\n    setAfterOneSecond time =\n        WebAudio.Property.setValueAtTime\n            (time + 1)\n            (WebAudio.Property.frequency 880)\n\n❗️\n\n","type":"Basics.Float -> WebAudio.Property.Property -> WebAudio.Property.Property"},{"name":"smoothingTimeConstant","comment":" ","type":"Basics.Float -> WebAudio.Property.Property"},{"name":"string","comment":" ","type":"String.String -> WebAudio.Property.Value"},{"name":"threshold","comment":" ","type":"Basics.Float -> WebAudio.Property.Property"},{"name":"type_","comment":" ","type":"String.String -> WebAudio.Property.Property"}],"binops":[]}]