Advertisement
Guest User

Untitled

a guest
Mar 18th, 2019
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.79 KB | None | 0 0
  1. import Program from "../../src/program/instrument"
  2.  
  3. import * as Html from "../../src/html/element"
  4. import * as Attr from "../../src/html/attribute"
  5. import * as Evnt from "../../src/html/event"
  6.  
  7. import * as Node from "../../src/audio/node"
  8. import * as Prop from "../../src/audio/property"
  9.  
  10. // These get passed in as flags to the Program
  11. // We use root to know where to inject the html
  12. // generated by view, and context to store a
  13. // reference to the Web Audio Context.
  14. const root = document.querySelector("#app")
  15. const context = new AudioContext()
  16.  
  17. // Audio Contexts now start in a disabled state
  18. // and must be resumed by some user interaction
  19. document.querySelector('body').addEventListener('click', () => {
  20. context.resume()
  21. })
  22.  
  23. // Init should be an array that contains the following:
  24. // 0: Program flags
  25. // 1: Initial state
  26. // 2: Initial effect
  27. const init = [{ root, context }, {
  28. freq: 220,
  29. gain: 0.5
  30. }]
  31.  
  32. // These are our Actions. Actions are how html
  33. // and the audio graph can affect our program
  34. // state.
  35. const Octave_Up = "octave_up"
  36. const Octave_Down = "octave_down"
  37. const Set_Gain = "set_gain"
  38.  
  39. // The update function is called with an array
  40. // containing the Action that triggered the update
  41. // and optionally some additional data, as well
  42. // as the current program state.
  43. const update = ([ action, ...data ], state) => {
  44. switch (action) {
  45. case Octave_Up:
  46. return [{ ...state,
  47. freq: state.freq * 2
  48. }]
  49.  
  50. case Octave_Down:
  51. return [{ ...state,
  52. freq: state.freq * 0.5
  53. }]
  54.  
  55. case Set_Gain:
  56. const [ e ] = data
  57.  
  58. return [{ ...state,
  59. // Slider values are 0 - 100
  60. gain: e.target.valueAsNumber / 100
  61. }]
  62. }
  63. }
  64.  
  65. // This is our audio processing graph.
  66. const audio = (state, dispatch) => {
  67. return [
  68. Node.oscillator("osc", [ Prop.frequency(state.freq) ], [], [
  69. Node.gain("gain", [ Prop.gain(state.gain) ], [], [
  70. Node.audioDestination()
  71. ])
  72. ])
  73. ]
  74. }
  75.  
  76. // This is our view, it should turn our
  77. // state into html.
  78. const view = (state, dispatch) => {
  79. return Html.div([], [], [
  80. // Events take a function to call, and apply
  81. // the rest of the arguments to that function when
  82. // the event is triggered. Additionally, the Event
  83. // object is passed as the final argument to any
  84. // event handler. In this case a click event will
  85. // call: dispatch(Octave_Up, e)
  86. Html.button([], [ Evnt.click(dispatch, Octave_Up) ], [ "+" ]),
  87. // Strings become TextNodes in the dom.
  88. `${ state.freq }`,
  89. Html.button([], [ Evnt.click(dispatch, Octave_Down) ], [ "-" ]),
  90. Html.input([
  91. Attr.class_("gain"),
  92. Attr.type("range"),
  93. Attr.min(0),
  94. Attr.max(100),
  95. Attr.value(50)
  96. ], [ Evnt.input(dispatch, Set_Gain) ], []),
  97. `${ state.gain }`,
  98. ])
  99. }
  100.  
  101. const app = Program({ init, update, audio, view })
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement