Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import Program from "../../src/program/instrument"
- import * as Html from "../../src/html/element"
- import * as Attr from "../../src/html/attribute"
- import * as Evnt from "../../src/html/event"
- import * as Node from "../../src/audio/node"
- import * as Prop from "../../src/audio/property"
- // These get passed in as flags to the Program
- // We use root to know where to inject the html
- // generated by view, and context to store a
- // reference to the Web Audio Context.
- const root = document.querySelector("#app")
- const context = new AudioContext()
- // Audio Contexts now start in a disabled state
- // and must be resumed by some user interaction
- document.querySelector('body').addEventListener('click', () => {
- context.resume()
- })
- // Init should be an array that contains the following:
- // 0: Program flags
- // 1: Initial state
- // 2: Initial effect
- const init = [{ root, context }, {
- freq: 220,
- gain: 0.5
- }]
- // These are our Actions. Actions are how html
- // and the audio graph can affect our program
- // state.
- const Octave_Up = "octave_up"
- const Octave_Down = "octave_down"
- const Set_Gain = "set_gain"
- // The update function is called with an array
- // containing the Action that triggered the update
- // and optionally some additional data, as well
- // as the current program state.
- const update = ([ action, ...data ], state) => {
- switch (action) {
- case Octave_Up:
- return [{ ...state,
- freq: state.freq * 2
- }]
- case Octave_Down:
- return [{ ...state,
- freq: state.freq * 0.5
- }]
- case Set_Gain:
- const [ e ] = data
- return [{ ...state,
- // Slider values are 0 - 100
- gain: e.target.valueAsNumber / 100
- }]
- }
- }
- // This is our audio processing graph.
- const audio = (state, dispatch) => {
- return [
- Node.oscillator("osc", [ Prop.frequency(state.freq) ], [], [
- Node.gain("gain", [ Prop.gain(state.gain) ], [], [
- Node.audioDestination()
- ])
- ])
- ]
- }
- // This is our view, it should turn our
- // state into html.
- const view = (state, dispatch) => {
- return Html.div([], [], [
- // Events take a function to call, and apply
- // the rest of the arguments to that function when
- // the event is triggered. Additionally, the Event
- // object is passed as the final argument to any
- // event handler. In this case a click event will
- // call: dispatch(Octave_Up, e)
- Html.button([], [ Evnt.click(dispatch, Octave_Up) ], [ "+" ]),
- // Strings become TextNodes in the dom.
- `${ state.freq }`,
- Html.button([], [ Evnt.click(dispatch, Octave_Down) ], [ "-" ]),
- Html.input([
- Attr.class_("gain"),
- Attr.type("range"),
- Attr.min(0),
- Attr.max(100),
- Attr.value(50)
- ], [ Evnt.input(dispatch, Set_Gain) ], []),
- `${ state.gain }`,
- ])
- }
- const app = Program({ init, update, audio, view })
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement