Permalink
Browse files

style fixes

  • Loading branch information...
wizgrav committed Jan 1, 2018
1 parent 13d0256 commit c1b78a0d8dc6bf8eef6205c2d6fb227299ceffd9
Showing with 22 additions and 26 deletions.
  1. +13 −17 README.md
  2. +2 −2 tool/main.js
  3. +7 −7 tool/tool.html
View
@@ -1,29 +1,28 @@
clubber
Clubber
========
![Clubber tool screenshot](https://wizgrav.github.io/clubber/screen.png)
This lib analyzes the frequency data from audio sources and extracts the underlying rhythmic information. The linear frequency energies are converted into midi notes which music theory suggests to be a better segregation for music audio.
This small js library listens to audio sources and extracts the underlying rhythmic information. The linear frequency energies are converted into midi notes which music theory suggests to be a better segregation for music audio.
A set of meaningful measurements are produced in a form suitable for direct use in webgl shaders, or any other context. This simple flow provides a powerful framework for the rapid development of awesome audio reactive visualisations.
[A short introduction to the music vectorization technique on Medium.com](https://medium.com/@wizgrav/music-reactive-visualizations-924df006f2ae#.6z10i27c1)
[ClubberToy](http://wizgrav.github.io/clubber/) - A collection of several rewired shadertoys as a vjing tool(Currently getting refactored).
[Clubber Tool](http://wizgrav.github.io/clubber/tool) - A web app for prototyping audio reactive visualizations. This is the best place to start playing around with clubber as it can export the patches you create for use in your own applications. It also happens to be a first class tool for music analysis and thanks to web midi output a very advanced sidechaining mechanism. This can come handy for driving parameters on external software, ranging from djing and music production to driving visuals. Everything that accepts midi control change messages basically.
[Clubber Tool](http://wizgrav.github.io/clubber/tool) - A web app for making awesome audio reactive visualizations. It's also a first class tool for music analysis and, probably, the most advanced sidechaining mechanism you could hope for.
[Documentation for the tool](https://github.com/wizgrav/clubber/tree/master/tool)
[Check the documentation for the tool](https://github.com/wizgrav/clubber/tree/master/tool)
[A short introduction to the music vectorization technique on Medium.com](https://medium.com/@wizgrav/music-reactive-visualizations-924df006f2ae#.6z10i27c1)
Some example patches for your audiovisual enjoyment:
[Imperial Sea]()
[Imperial Sea](https://goo.gl/p4HwTH)
Older but still good:
[Sea, Sun & Zorba](https://goo.gl/7tDFmr), [Cubes & Roses](https://goo.gl/411PTg), [Electro Fractal Land](https://goo.gl/9yBZnJ), [Bello Electro](https://goo.gl/VTGmz7), [Boom Generators](https://goo.gl/XH88Gf)
[Clubberize](https://github.com/wizgrav/clubberize) - A helper lib to utilize the tool's modulators in js apps, webgl or other.(Kind of obsolete now since the tool can export its state in pure javascript)
[Clubberize](https://github.com/wizgrav/clubberize) - A helper lib to utilize the tool's modulators in js apps, webgl or other.(Mostly obsolete now since the tool can export its state in pure javascript)
### Usage ###
@@ -54,7 +53,7 @@ require('clubber')
### Instructions ###
First we instantiate a Clubber object and have it listen to an audio element. When we need to process a fresh set of audio samples we call Clubber.update(), usually once per render iteration.
First we instantiate a Clubber object and have it listen to an audio element. When we need to process a fresh set of audio samples we call Clubber.update(). This will usually need to be performed once per render iteration when live or when a new buffer is available when offline. Mind that in the later case the appropriate time needs to be provided manually to clubber.update(time). That time should be an incrementing sum of 1000 * <bufferSize>/<sampleRate>
```javascript
var clubber = new Clubber({
@@ -65,8 +64,8 @@ var clubber = new Clubber({
// Specify the audio source to analyse. Can be an audio/video element or an instance of AudioNode.
clubber.listen(audioSource);
clubber.update(currentTime); // currentTime is optional and specified in ms.
console.log(clubber.notes); // array containing the audio energy per midi note.
clubber.update(currentTime); // currentTime is optional and specified in milliseconds.
console.log(clubber.notes); // This is the array containing the audio energy per midi note.
```
The energy per midi note will be contained in the Clubber.notes array. A mechanism for analysis is provided by the library called 'bands'. These are implemented as closures that, when called, will process the current note energies and update Float32Arrays | Arrays | THREE.VectorX objects passed as the first argument, with the second argument being an offset for the case when arrays are used. Their output data can be passed directly to webgl shaders as vecs. The data coming out are readily usable as modulators but they can also be aggregated through time for more elaborate transitions etc.
@@ -137,20 +136,17 @@ clubber.update(time, noteArray, true);
```
There's no need to listen to anything on the rendering box in this case. You just create and use bands as usual. Time is optional and you can just provide it with a null value to use the internal clock.
There's no need to listen to anything on the rendering box in this case. You just create and use bands as usual. Time is optional and you can just provide it with a null value to use performance.now() internally.
### Tips ###
Usually one would instantiate several bands, each covering a range of midi notes, low mid high etc, calling them every render iteration and passing the returned arrays/vec4s as uniforms to modulate webgl shaders. Other uses are equally easy, just pick and use elements from the arrays as needed.
By creatively combining the results of the analysis, the rhythmic patterns in the music will emerge in the graphics as well. Simple combinations could be finding the min/max between adjacent band notes/energies or multiply/sub them.
By creatively combining the results of the analysis, the rhythmic patterns in the music will emerge in the graphics as well. Simple combinations could be finding the min/max between adjacent band notes/energies or multiply/sub them.
A strategy that works well would be to interpret the analysis results as vectors and operate on these. For instance map a bands strongest note on the x axis, the average note on the Y axis and calculate the length of the vector. You can go further and combine notes with powers and elements from different bands/rects.
And since we're dealing with vectors why not just measure their distances or even dot them and see what comes out(Good stuff :) These combinations are all plausible, you can check some of them in the glsl demos that come with the source. You can also experiment on your own and design your modulators in this [very helpful tool](http://wizgrav.github.io/clubber/tool).
You can also tune smoothing via Clubber.smoothing which is a shortcut for the internal analyser's smoothingTimeConstant(the web audio default is 0.8 and is quite sensitive).
And since we're dealing with vectors why not just measure their distances or even dot them to calculate the angle beetween them and see what comes out(Good stuff :) These combinations are all plausible, you can check some of them in the glsl demos that come with the source. You can also experiment on your own and design your modulators in this [very helpful tool](http://wizgrav.github.io/clubber/tool). If you come up with something good, please consider sharing.
### Clubber in the wild ###
View
@@ -490,12 +490,12 @@ function render(time) {
gl.viewport(0, h * 0.52, w, h * 0.25);
uniforms.iResolution[1] = h * 0.25;
uniforms.iResolution[2] = h * 0.52;
shaders[1].transition = altShader ? 0.7 : 1.0;
shaders[1].transition = altShader ? 0.8 : 1.0;
shaders[1].render(data, true);
gl.viewport(0, 0, w, h * 0.49);
uniforms.iResolution[1] = h * 0.49;
uniforms.iResolution[2] = 0;
shaders[2].transition = altShader ? 0.9 : 1.0;
shaders[2].transition = altShader ? 0.96 : 1.0;
shaders[2].render(data, false);
}
}
View
@@ -352,23 +352,23 @@
</div>
<div id="config">
<select id="band" onchange="selectBand(this.selectedIndex)">
<option style="background-color: rgb(64,64,64); color: white">$0 - iMusic[0]</option>
<option style="background-color: rgb(128,128,128); color: white">$1 - Music[1]</option>
<option style="background-color: rgb(192,192,192); color: black;">$2 - iMusic[2]</option>
<option style="background-color: rgb(255,255,255); color: black;">$3 - iMusic[3]</option>
<option style="background-color: rgb(64,64,64); color: white">iMusic[0] - $0</option>
<option style="background-color: rgb(128,128,128); color: white">iMusic[1] - $1</option>
<option style="background-color: rgb(192,192,192); color: black;">iMusic[2] - $2</option>
<option style="background-color: rgb(255,255,255); color: black;">iMusic[3] - $3</option>
</select>
<button id="template" onclick="changeTemplate(this); return false;">0123</button>
<span> rect:</span>
<span> Bounds:</span>
<input type="number" min="0" max="127" step="1" onchange="updateBand()"/>
<input type="number" min="0" max="127" step="1" onchange="updateBand()"/>
<input type="number" min="0" max="127" step="1" onchange="updateBand()"/>
<input type="number" min="0" max="127" step="1" onchange="updateBand()"/>
<span> smooth:</span>
<span> Smooth:</span>
<input type="number" min="-1" max="1" step="0.01" onchange="updateBand()"/>
<input type="number" min="-1" max="1" step="0.01" onchange="updateBand()"/>
<input type="number" min="-1" max="1" step="0.01" onchange="updateBand()"/>
<input type="number" min="-1" max="1" step="0.01" onchange="updateBand()"/>
<span> adapt:</span>
<span> Adapt:</span>
<input type="number" min="-1" max="1" step="0.01" onchange="updateBand()"/>
<input type="number" min="-1" max="1" step="0.01" onchange="updateBand()"/>
<input type="number" min="-1" max="1" step="0.01" onchange="updateBand()"/>

0 comments on commit c1b78a0

Please sign in to comment.