Plug-ins, Hosts, Apps,
Hardware, Soundware
Developers
(Brands)
Videos Groups
Whats's in?
Banks & Patches
Download & Upload
Music Search
KVR
   
KVR Forum » DSP and Plug-in Development
Thread Read
My weekend hack: Write VST plugins in JavaScript
Goto page 1, 2  Next
abstractbill
KVRer
- profile
- pm
PostPosted: Wed May 30, 2012 12:31 pm reply with quote
Hi guys, this is something I put together over the long weekend - would love to hear any and all feedback! Right now it will create a universal OS X VST for you, but I think expanding to Windows wouldn't be too much harder, so I'll be doing that soon. Feel free to play with it as much as you like!

Here's the site: http://boomsk.com/

And here are a few more examples: http://boomsk.com/examples.html

Cheers,
Bill.
^ Joined: 15 May 2012  Member: #280464  Location: California
mystran
KVRAF
- profile
- pm
- e-mail
- www
PostPosted: Wed May 30, 2012 4:03 pm reply with quote
I'm on Windows only, so I can't try it, but out of curiousity, are you using some stock javascript engine or did you write your own? I assume you do end up with native code, right?
----
<- my plugins | my music -> @Soundcloud
^ Joined: 11 Feb 2006  Member: #97939  Location: Helsinki, Finland
jupiter8
KVRAF
- profile
- pm
- e-mail
PostPosted: Wed May 30, 2012 10:21 pm reply with quote
Cool,i was just looking for a plugin that works in a similar fashion written in Java just yesterday but couldn't find it.I had an idea i quickly wanted to try.
Now i don't have a Mac so i'm looking forward to the Windows version. Thanks.
----
At school they taught me how to be.
So pure in thought and word and deed.
They didn't quite succeed.
^ Joined: 17 Sep 2002  Member: #3863  Location: Gothenburg Sweden
declassified
KVRian
- profile
- pm
PostPosted: Thu May 31, 2012 12:31 am reply with quote
Great idea! Nice for people who don't know C++ and just need some quick effect.

I noticed that the delay (the example code) uses quite a lot of CPU, considering how little it does...I'm not complaining, it's just something you might want to look into Wink
^ Joined: 24 May 2004  Member: #26803  
arakula
KVRAF
- profile
- pm
- e-mail
- www
PostPosted: Thu May 31, 2012 5:44 am reply with quote
If you look at the JavaScript code, you'll notice that it works on a per-sample base. Also readHead is completely recalculated once for each sample frame.

Regardless of whether it's based on a JITC JavaScript implementation, this is damned inefficient.
----
"Until you spread your wings, you'll have no idea how far you can walk."
^ Joined: 16 Aug 2004  Member: #37236  Location: Vienna, Austria
stratum
KVRist
- profile
- pm
PostPosted: Thu May 31, 2012 11:05 am reply with quote
For a task like realtime audio processing, one is normally concerned about things like running into denormals as a result of calculations which may cause abrupt inefficiencies that cause small glitches that are nevertheless audible (few other developers usually even heard of such problems), the idea of using a garbage collecting language that isn't even compiled sounds like a strange taste of intellectual curiosity. I guess this is one of "I did it because I can" kind of things.

On the other hand, if this has emerged from a real need, perhaps of quick prototyping, check out "Faust" http://en.wikipedia.org/wiki/FAUST_(programming_language)

Looks like it would take some time to learn though, so I'm not sure that's a very good idea either. Your prototype may take less time to finish in c++.
----
~stratum~
^ Joined: 29 May 2012  Member: #281392  
AdmiralQuality
KVRAF
- profile
- pm
- e-mail
- www
PostPosted: Thu May 31, 2012 11:18 am reply with quote
stratum wrote:
I guess this is one of "I did it because I can" kind of things.


I think that was implied by abstractbill when he said he threw it together over a long weekend. It's what it is, and if it works (I haven't tried it yet) that's cool!

I think an actual C compiler would make more sense though. (If you can understand enough JavaScript to code an effect, you can certainly understand enough C!) And I think it actually should call the process on a per-sample basis. The sample loop can be done by the framework, as it's the same every time. I also think 1 sample frame sized buffers are going to be very common in near future DAWs.
^ Joined: 10 Oct 2005  Member: #83902  Location: Toronto, Canada
stratum
KVRist
- profile
- pm
PostPosted: Thu May 31, 2012 11:27 am reply with quote
Quote:
I think that was implied by abstractbill when he said he threw it together over a long weekend. It's what it is, and if it works (I haven't tried it yet) that's cool!


I used to have such weekends. Nowadays I prefer going to somewhere outdoors with an old 4x4 (old ones are cheap). Long trips in nature are pretty cool and relaxing.. it even gives you some silent time to think about life in general and what you want to do. A friend of mine used to say swimming is similar.

Anyway.. javascript is cool and I guess it's easy compared to reading papers, and that may also be a relaxing hobby.
----
~stratum~
^ Joined: 29 May 2012  Member: #281392  
abstractbill
KVRer
- profile
- pm
PostPosted: Thu May 31, 2012 5:28 pm reply with quote
Thanks for the feedback everyone!

I'll see what I can do about getting a Windows version up soon. Hopefully it won't take too long.

The JavaScript engine is Spidermonkey (from Mozilla). It's a decent JIT - actually faster than both V8 and JavaScriptCore in the testing I did a while back. So yeah, it *is* compiled, and we do wind up with native code in the end, strictly speaking Wink I'm actually not *too* worried about efficiency - as AdmiralQuality pointed out, the framework could easily pull out your code from the function and do the loop automatically for you (it doesn't right now, but it would be really easy).

Anyway, yeah it was a weekend hack mostly, but I'm not sure it's a complete dead-end just yet. I'm going to keep going with it and see if I can't make it into something useful. JavaScript seems like a good choice to me, because:

- Using JS means we could audition your effect in the web browser itself, making the development cycle a lot faster
- There are many more JavaScript than c++ programmers
- People are working hard on making JS engines more efficient

Please keep the feedback coming if you have more, it's great to have some thoughtful replies to my post!

Thanks,
Bill.
^ Joined: 15 May 2012  Member: #280464  Location: California
arakula
KVRAF
- profile
- pm
- e-mail
- www
PostPosted: Thu May 31, 2012 10:37 pm reply with quote
AdmiralQuality wrote:
And I think it actually should call the process on a per-sample basis. The sample loop can be done by the framework, as it's the same every time. I also think 1 sample frame sized buffers are going to be very common in near future DAWs.

Agreed, but still... things that only change whenever a parameter changes (such as the offset between the buffer read and write pointers in a delay) should not be recalculated upon each sample. Look at the current JavaScript sample code from the web site:
var bufferLen = 5 * 96000;  // a reasonable maximum
var leftBuffer = new Float64Array(bufferLen);
var rightBuffer = new Float64Array(bufferLen);
var writeHead = 0;

function processAudio(input, output, params) {
    leftBuffer[writeHead % bufferLen] = input[left];
    rightBuffer[writeHead % bufferLen] = input[right];
    var readHead = ((Math.round(writeHead - (params.delay * params.sampleRate))) + bufferLen) % bufferLen;
    output[left] = input[left] * (1 - params.wet) + leftBuffer[readHead] * params.wet;
    output[right] = input[right] * (1 - params.wet) + rightBuffer[readHead] * params.wet;
    writeHead++;
}

readHead is a local variable that's recalculated each time, although it should be easy to move it into a global variable (like writeHead), simply increment it like writeHead in processAudio(), and only recalculate the difference to writeHead whenever one of the parameters changes. This, of course, would require either a costly "if delay or sampleRate changed, recalculate difference", which would defeat the purpose of saving CPU cycles, or another exposed function like setParameter() in which the new offset would be calculated (much better solution).

Other areas that might benefit of a little redesign, depending on the JIT compilers' capabilities:

.) "writeHead % bufferLen" is calculated twice for no reason;
should be done at the bottom as "writehead = (writeHead + 1) % bufferLen;"
Depending on how clever the JIT compiler is, this might save some CPU cycles.

.) input[left], input[right], params.wet could be read into local variables at the start of the function so that they don't need to be fetched twice. OTOH, this might be bad because of the garbage collector; I don't know...


Oh, and one more remark that I just can't keep to myself...
abstractbill wrote:
- There are many more JavaScript than c++ programmers

That may be the case, but doesn't make JavaScript a good language for realtime audio processing.
MIDI processing, for example, would be a better area to show its strengths.
----
"Until you spread your wings, you'll have no idea how far you can walk."
^ Joined: 16 Aug 2004  Member: #37236  Location: Vienna, Austria
BertKoor
KVRAF
- profile
- pm
PostPosted: Fri Jun 01, 2012 2:47 am reply with quote
arakula wrote:
.) "writeHead % bufferLen" is calculated twice for no reason;
should be done at the bottom as "writehead = (writeHead + 1) % bufferLen;"
Depending on how clever the JIT compiler is, this might save some CPU cycles.
I'd never ever rely on the optimizations supposedly done by a compiler. I'm a strong supporter of making code as efficient as humanly possible.
abstractbill wrote:
- There are many more JavaScript than c++ programmers
Really?? That's a scary development... Would you know of any published figures to support that statement?
----
We are the KVR collective. Resistance is futile. You will be assimilated.
My MusicCalc is back online!!
^ Joined: 08 Mar 2005  Member: #60794  Location: Utrecht, Holland
stratum
KVRist
- profile
- pm
PostPosted: Fri Jun 01, 2012 4:02 am reply with quote
Quote:
Really?? That's a scary development... Would you know of any published figures to support that statement?


C++ is notorious for things that it never deserved to be criticized about, so I'm not surprized that such a comment may be made without any published figures.
The only thing I dislike about C++ is that code completion software never seems to work right for c++. Intellisense, Visualassist, etc all are crap compared to the way visual studio works with C#, but with C++ it leaves a lot to be desired. Other IDE's are not different, often worse. Returning back to the comment about that there are more javascript programmers than there are c++ programmers, it may be true or false, but in the end it doesn't matter. For example I know c++ but that doesn't mean I have a very cool idea about a vst plugin that will shake the market.Smile
----
~stratum~
^ Joined: 29 May 2012  Member: #281392  
Big Tick
KVRAF
- profile
- pm
- e-mail
- www
PostPosted: Fri Jun 01, 2012 8:25 am reply with quote
Actually... I wouldn't want to use JavaScript for the dsp part, but for the UI, it would definitely make sense to follow what's being done in the gaming industry, and use a scripting engine for all non-realtime code. Given that a plugin consists of 80%-90% UI code, this could be a real time saver.
^ Joined: 28 May 2001  Member: #586  Location: New York, NY
abstractbill
KVRer
- profile
- pm
PostPosted: Fri Jun 01, 2012 10:10 am reply with quote
Heh, yeah forget what I said about there being more JS programmers - I have no data to back it up, it's only a hunch. The more interesting observation might be that the *overlap* between c++ and JavaScript programmers is likely to be quite small, and my idea is to open up plugin development to people who haven't been able to do it before. With that in mind, the JavaScript code is written to be readable first and foremost, with all considerations of efficiency quite firmly punted Wink

Having said that, I just loaded up a couple of dozen instances of the basic echo plugin into Ableton on my puny little macbook air. They all run at the same time, with the cpu still at under 50% and without any artifacts that I can hear. Although the code is written to be readable, there's nothing in it that should cause GC to happen - the SpiderMonkey JIT represents numbers as doubles, and Float64Arrays as very lightweight wrappers around arrays of doubles.

Big Tick, yes I've definitely been thinking along these lines too Smile
^ Joined: 15 May 2012  Member: #280464  Location: California
kuniklo
KVRAF
- profile
- pm
- www
PostPosted: Fri Jun 01, 2012 9:35 pm reply with quote
At the rate javascript is going, if there aren't already many more JS programmers than C++ programmers there surely soon will be.

But I agree that doing DSP in JS just doesn't make that much sense. There is already such a glut of plugins on the market that nobody is going to use anything that's 10x slower than a similar C++ implementation.

However, doing UI with JS does make sense. You could also build your core DSP components in C++ and then expose a JS interface that lets you assemble them into processing graphs, sorta like Max/MSP but with a textual programming language. In fact, IIRC you can do this in Max with JS already.
^ Joined: 28 Jan 2004  Member: #12072  Location: Nha Trang, Vietnam
All times are GMT - 8 Hours

Printable version
Page 1 of 2
Goto page 1, 2  Next
Display posts from previous:   
ReplyNew TopicPrevious TopicNext Topic
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
Username: Password:  
KVR Developer Challenge 2012