Comments (11)
The range is from -1.0 to 1.0. I created this code that you can paste into the web demo. You can use the CC30 to change the k
.
fun shaper(x,k) {
val pi = 3.1415;
return (3.0 + k) * x * 20.0 * (pi/180.0)/(pi + k * abs(x));
}
fun process(input:real){
mem k;
return shaper(input,k);
}
and noteOn(note:int,velocity:int,channel:int){}
and noteOff(note:int,channel:int) {}
and controlChange(control:int,value:int,channel:int){
if(control==30)
k = real(value)/ 1.0;
}
and default(){}
As you increase the k
is possible to hear the harmonics. If you have a fixed k
it's possible to use the @[table()]
attribute. I haven't tried to create very large tables, but the intention behind the implementation is to be able to use small tables that produce a nice sound. The interpolation used with @[table()]
is second order. One would require large tables when using first order interpolation.
In this code I created the wave shaper with the @[table()]
attribute, and if you move the CC30 if will change between the two implementations. I cannot hear any difference between them.
fun shaper_original(x,k) {
val pi = 3.1415;
return (3.0 + k) * x * 20.0 * (pi/180.0)/(pi + k * abs(x));
}
fun shaper_table(x) @[table(size=127, min=-2.0, max=2.0)] {
val pi = 3.1415;
val k = 10.0;
return (3.0 + k) * x * 20.0 * (pi/180.0)/(pi + k * abs(x));
}
fun process(input:real){
mem mix;
val o = if mix > 0.5 then shaper_original(input,10.0) else shaper_table(input);
return o;
}
and noteOn(note:int,velocity:int,channel:int){}
and noteOff(note:int,channel:int) {}
and controlChange(control:int,value:int,channel:int){
if(control==30)
mix = real(value)/127.0;
}
and default(){}
from vult.
Thanks.
Yes, I feel the harmonics if I turn the knob with my karplus-strong process function. Apart from being simplified and taking k as an input, your implementation is substantially equivalent to mine, but the output is still underwhelming and the effect very subtle, so I guess there's something else in play here. For comparison, pizzicatojs uses the same waveshaper with 0 < k < 100, but their "Distortion" demo sound much more "distorted" than my waveshaper. Maybe the Web Audio API is doing something else in the background? I'll investigate.
Thanks for the table example! That's really cool, and I still had a couple of doubts about tables that your example solved. I still don't understand why you generate the table in a -2.0, 2.0 range, since the input ranges from -1 to -1. Is it to prevent clipping input to return the wrong value? What would happen if I called it with 5, for example?
from vult.
When called outside the range, you get the extrapolated value of the limits. That's why I always leave a little bit of space in the range. If possible, I clip the input value to fit the range (check the implementation of saturate
here https://github.com/modlfo/vult-examples/blob/master/src/util.vult
In your example, if you want more aggressive distortion, you can do what's done in the guitar pedals, multiply the input. For example:
fun shaper(x,k) {
val pi = 3.1415;
return (3.0 + k) * x * 20.0 * (pi/180.0)/(pi + k * abs(x));
}
fun process(input:real){
mem gain;
return shaper(gain*input,10.0);
}
and noteOn(note:int,velocity:int,channel:int){}
and noteOff(note:int,channel:int) {}
and controlChange(control:int,value:int,channel:int){
if(control==30)
gain = 1.0 + real(value);
}
and default(){
gain = 1.0;
}
As the gain increases, the sine wave becomes a square signal.
from vult.
Yep, saturate
was what triggered https://github.com/modlfo/vult/issues/18 :)
Clipping with gain helps a bit, but the sound is still different and underwhelming. I will investigate. Thanks!
from vult.
I updated the code. You should be able to use tanh
in the web.
from vult.
By the way. I tested a tanh
distortion with a sample of a real guitar and the distortion sounds really cool. While the same shaper with very ideal waveforms (like sine, or saw) sounds very week.
from vult.
Actually I'm generating the guitar string sounds from a simple Karplus-Strong model (one of the reasons I'm using Vult is to experiment with physical models and feedback). Turns out that the same model, written in javascript, sounds very weak even with the WAA wavershaper node.
Normally what people do is adding a bit of presence with a cabinet emulation based on an impulse response, which I guess is ok - I just need to write the convolution bit. The only hard thing is that I will have to manually load the IR somehow - any plans to add file i/o to Vult in the future, @modlfo? :D
from vult.
Yes. I have been experimenting with Wav file reading at compile time. I want to be able of embedding wav files as arrays. But I'm not sure how this can work on the web demo. It will require to generate the code from the terminal and somehow load it on the browser.
As a workaround you can declare an external function that takes an index and gives you back the sample of an IR and provide that function as external Js.
I'll let you know when I have this available.
from vult.
What comes to mind is just let the user specify a baseurl
, then wrap the generated code in a fetch
callback and put the retrieved file in a typed array. The user just has to host the files somewhere. But of course the CORS headers should be enabled on the hosting side and that would be complicated.
What would be really cool would be an online IDE that hosts the files (code and data) for the user. Then the user would prototype online and loading externals + loading data files would automagically work. Then the user could just export for a given target with a button and download the result. It could even be a service - write once, save as vst / code for dsp board / web audio component.
Is it easy to operate the compiler from javascript? I understand you generate a javascript lib with an utility that traslates ocaml to js. If all the APIs are there, I would like to try and do a PoC. Not being able to load externals in the web IDE is kind of frustrating, so the first target could be that :)
from vult.
The compiler API exposes the all the command line options, but the input files need to be passed as strings. This is the npm library https://www.npmjs.com/package/vultlib
In the web demo I add a few wrappers for that code.
Regarding the online IDE, I have one idea and I made some progress. Here's the basic idea https://github.com/modlfo/VultPlatform/wiki
I worked a bit in the (local) (AudioEngine)[https://github.com/modlfo/AudioEngine] but I have been slow with the development of the clients. I have been trying to write a simple client (in a private repo) in Elm.
Other idea that I have in mind is making a Visual Studio Code plugin that connects to the AudioEngine to run the code.
If you have a recommendation on how I should generate/export the Js code so is easy to use let me know.
from vult.
The Vult Platform idea is really cool. IMHO it should support multiple files. Also, if many people use it, a pseudo-registry (maybe a thin layer over GitHub) would be a quick win.
Exporting code to Javascript could be complex if loading files comes into play, depending on what is the target. You could probably solve it like this:
Previewing in demo:
Have the user upload its audio assets. Generate the javascript code like you do now, but wrap it in parallel fetch
calls (maybe using async) to get the assets from whenever they're stored. Firebase Storage, for example, is dirty cheap and easy to use.
Exporting to a file:
The user can select whether to export as a ES6 module or an inline module. Generate the code like you do now, then:
- ES6: prepend
import assetName1 from './asset1.wav'
statements. The user will need to use a webpack loader or some equivalent technique to load the file as a blob / typed array. - Inline: Just inline the audio assets as a blob / typed array.
from vult.
Related Issues (20)
- vcv prototype plugin: getSwitch(n) error HOT 1
- Problem with multiple independently compiled files when included (redefinition error) HOT 1
- Feature request: Add code example / template for ESP32 (I2S)
- Dynamic Memory Allocation (making ESP32 external RAM work) HOT 9
- Arduino Template / Example HOT 2
- Window puredata example build fail HOT 2
- V2 Rack browser crash HOT 2
- Trummor2 bug / VCVRAck v2 Beta1 / OsX10.10.5 HOT 3
- vult.sublime-syntax HOT 1
- MacOS puredata examples build fail HOT 3
- Range or scaling factors of parameters? HOT 3
- How to include Vult source ? HOT 2
- Error calling `random()` method in VCV Rack HOT 3
- ccode flag generates invalid C (references) HOT 1
- web playground HOT 1
- Modifying fixed point type in vult runtime HOT 1
- v1 branch build error (cygwin/Windows) HOT 1
- Raspberry Pi Pure data building examples HOT 1
- Simple installation issue HOT 1
- Initializations with @[init] ? HOT 5
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from vult.