/knob

Primary LanguageJavaScriptMIT LicenseMIT

All toguether

What is this?

A declarative step sequencer built with the vue-skeleton + Tone JS + Nexus UI

The goal is to mix a bunch of vue components in a page and declaratively compose sequencers linked to each other.

<synthetizer>
  <volume></volume>
  <frequency></frequency>
  <steps></steps>
<synthetizer>

Try it!

goo.gl/5vW85m

Why?

To learn stuff

How?

There are three types of components:

  1. Source components: The sound instances
  2. Data manipulation: Controllers to change the source components data (sound)
  3. Fancy visuals: Fancy visualization for the source components

Source components

GlobalController

Creates and controls the global Tone js instance

Data:

  • bpm: Global bpm
  <GlobalController>
  </GlobalController>

Synth

Tone js Polyphonic Synthetizer

Props:

  • type: Synth type, one of: synth, am, duo, fm, membrane, mono

Data:

  • polySynth: PolySynth instance
  <Synth :type="'am'">
  </Synth>

SampleSteps

A step sequencer to play audio samples

Steps

Props:

  • label: Label to show
  • steps: Ammount of steps for the sequencer
  • files: An array of file routes
  • time: The duration the sample should play in seconds
  <SampleSteps
    :label="'Atmosphere'"
    :steps="48"
    :files="[
    `${$versionRoot}/mp3/idm-kit/K01Atmos-01.mp3`,
    `${$versionRoot}/mp3/idm-kit/K01Atmos-02.mp3`,
    `${$versionRoot}/mp3/idm-kit/K01Atmos-03.mp3`,
    `${$versionRoot}/mp3/idm-kit/K01Atmos-04.mp3`,
    `${$versionRoot}/mp3/idm-kit/K01Atmos-05.mp3`,
    ]"
    :time="8"
  >
  </SampleSteps>

Data manipulation

Components that change the source components data

Knob

A dial control

knob

Props:

  • min: Minimum value
  • max: Maximun value
  • step: The increment or decrement of the control
  • input: Property to change in the parent element
  • label: Label to show
<Knob :min="-10" :max="6" :step="1" :input="'volume'" :label="'Volume'"></Knob>

Slider

Horizontal slider

slider

Props:

  • min: Minimum value
  • max: Maximun value
  • step: The increment or decrement of the control
  • input: Property to change in the parent element
  • label: Label to show
<Slider :min="-10" :max="6" :step="1" :input="'volume'" :label="'Volume'"></Slider>

Number

Draggable number interface

Number

Props:

  • min: Minimum value
  • max: Maximun value
  • step: The increment or decrement of the control
  • input: Property to change in the parent element
  • label: Label to show
<Number :min="1" :max="300" :step="1" :input="'bpm'" :label="'bpm'"></Number>

Steps

Step sequencer

Steps

Props:

  • label: Label to show
  • steps: Ammount of steps for the sequencer
  • notes: An array of notes in octave notation
  • time: Duration of the notes in seconds
  <Steps
    :label="'AM synth'"
    :steps="32"
    :notes="['E3', 'G3', 'A3', 'B4', 'D4', 'E4', 'G4', 'A4']"
    :time="0.5">
  </Steps>

Fancy visuals 💃

Sound visualization

OscVisualization

Fancy oscilloscope visualization

Osc

Props:

  • input: The parent's sound context to connect to the visualization
<OscVisualization :input="'polySynth'"></OscVisualization>

How to use it ??

You always have to create a new tone instance, for that purpose you can use the GlobalController component

  <GlobalController>
  </GlobalController>

the user should be able to modify the global bpm, so you can add a data manipulation component inside the GlobalController. The global controller have the bpm property in the data(), you can use it as an input for a data manipulation component

  <GlobalController>
    <Number :min="1" :max="300" :step="1" :input="'bpm'" :label="'bpm'"></Number>
    <!--Knob :min="1" :max="300" :step="1" :input="'bpm'" :label="'bpm'"></Knob>
    <Slider :min="1" :max="300" :step="1" :input="'bpm'" :label="'bpm'"></Slider-->
  </GlobalController>

You can also add some fancy visuals inside the GlobalController, the visuals input should be a Tone context, so you can use the global context that's exposed in the GlobalController data()

  <GlobalController>
    <Number :min="1" :max="300" :step="1" :input="'bpm'" :label="'bpm'"></Number>
    <!--Knob :min="1" :max="300" :step="1" :input="'bpm'" :label="'bpm'"></Knob>
    <Slider :min="1" :max="300" :step="1" :input="'bpm'" :label="'bpm'"></Slider-->
    <OscVisualization :input="'context'"></OscVisualization>
  </GlobalController>

Now, lets make some sounds. First let's add a Synth component

    <Synth :type="'am'">
    </Synth>

Inside the synth component you can manipulate some of the synth properties depending on the synth type, for example in an AM synth you can change the detune value

  <Synth :type="'am'">
    <Knob :min="-3000" :max="3000" :step="1" :input="'detune'" :label="'Detune'"></Knob>
  </Synth>

This is a step sequencer, so you need some steps to make sound

  <Synth :type="'am'">
    <Knob :min="-3000" :max="3000" :step="1" :input="'detune'" :label="'Detune'"></Knob>
    <Steps
        :label="'AM synth'"
        :steps="32"
        :notes="['E3', 'G3', 'A3', 'B4', 'D4', 'E4', 'G4', 'A4']"
        :time="0.5">
      </Steps>
  </Synth>

Now you can tap on the steps and make some preety sounds 🎶

Add a bunch of step sequencers to a page and have fun!! check out the HomePage of this project.