Old 11-29-2018, 02:29 PM   #1
inscript
Human being with feelings
 
Join Date: Aug 2018
Posts: 19
Default JSFX and IDE help

I would like to start experimenting with JSFX programming using the built in IDE and I'm wondering a few things:

After doing some searching, it seems like there is very little tutorial/beginner-oriented JSFX development content around. Am I missing sites or places on the forums?

I am under the impression that Lua can't interact directly with the audio engine, that's to say, we aren't able to program effects directly in Lua, correct?

Is there a way to increase the font size on the built-in IDE? I've tried some other solutions getting syntax highlighting to work in other editors (including the VSCode tools to no avail), but all I would really like to do is increase the font size. Additionally, is there a place someone can point me for themes for the IDE? Perhaps a larger font would be inside one of these themes?

Thanks in advance for responses
inscript is offline   Reply With Quote
Old 11-29-2018, 03:08 PM   #2
nofish
Human being with feelings
 
nofish's Avatar
 
Join Date: Oct 2007
Location: home is where the heart is
Posts: 12,096
Default

Hi,

for increasing font size in the built in IDE (didn't test this myself)

Quote:
Change Config-variable edit_fontsize or the reaper.ini entry [REAPER]->edit_fontsize to the fontsize you need.
(it's mespotine's current signature.)
nofish is offline   Reply With Quote
Old 11-29-2018, 03:44 PM   #3
Edgemeal
Human being with feelings
 
Edgemeal's Avatar
 
Join Date: Apr 2016
Location: ASU`ogacihC
Posts: 3,913
Default

Quote:
Originally Posted by inscript View Post
Is there a way to increase the font size on the built-in IDE?
On Windows I just use Control key + Mousewheel.
Edgemeal is offline   Reply With Quote
Old 11-29-2018, 06:30 PM   #4
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 8,062
Default

Quote:
Originally Posted by inscript View Post
I am under the impression that Lua can't interact directly with the audio engine, that's to say, we aren't able to program effects directly in Lua, correct?
That's correct, at least with Lua in Reaper. But there's for example Protoplug that allows writing audio plugins with Lua (I don't know how well that works and is supported these days, though) :

http://www.osar.fr/protoplug/
__________________
I am no longer part of the REAPER community. Please don't contact me with any REAPER-related issues.
Xenakios is offline   Reply With Quote
Old 11-29-2018, 10:13 PM   #5
inscript
Human being with feelings
 
Join Date: Aug 2018
Posts: 19
Default

Thanks for the responses. Funny enough, I have Protoplug installed on my machine and that documentation is as equally scarce as the JSFX reference. I actually just emailed the developer and asked him if the project is still alive. I'm surprised no one has written any tutorial content for JS. I'm not really at the point where I can open up a JS plugin like "very basic softclipper" and use it as a starting point. I don't even know where to begin with JS.I've checked out the useful code snippets sticky, but that deals with implementing algorithms more than anything directed at a beginner. I'm really curious how someone like Saike took the JSFX reference and turned it into a great plugin like Filther. How did you guys go from point A to point B?

Edit: Ctrl + mousewheel works great! Can I be really picky and ask if there's a way to change the font?

Last edited by inscript; 11-30-2018 at 12:25 AM.
inscript is offline   Reply With Quote
Old 12-04-2018, 06:32 AM   #6
sai'ke
Human being with feelings
 
sai'ke's Avatar
 
Join Date: Aug 2009
Location: NL
Posts: 1,453
Default

It's difficult to give solid advice, since we don't know what languages and DSP concepts you are familiar with. Are you familiar with C or some other language that's relatively close to the metal?

I think the lack of entry-level tutorials on jsfx is generally because DSP tends to have a fairly steep learning curve and people familiar with DSP tend to be used to programming in different languages. This makes it easier to familiarize with new languages.

A jsfx is a script where you define sections that get called on specific events (the @ sections). Events such as script initialization, slider modification, starting the next sample block, processing a sample (here you typically do the actual audio processing), updating the gfx. In each of these blocks you can stuff some code that gets evaluated when reaper calls these functions. Be warned though that some of these can be accessed concurrently (running at the same time)!

Variables can be stored and read just like you'd expect:
Code:
a=5; // a is now 5
But it can also be accessed in an address like manner (kind of like a pointer) like so:
Code:
blah = 10;  // blah is set to 10
blah[] = 5; // You can read [] as at. Now the memory at location 10 is set to 5.

blah = blah + 1; // You can also write blah += 1 for shorthand
// Blah is now set to 11, if we were to read blah[] we'd be looking at what is stored at address 11 now.
blah[] = 20; // Now the memory at address 10 contains 5 and the memory at address 11 contains 20.

blah -= 1; // blah is once again set to 10 after this command.
blah[] = 6; // Now the memory at address 10 contains 6 and the memory at address 11 still contains 20.
You also have loops, which can run a set number of times. What you'll often see in jsfx is pointers iterating over some array and reading/writing values from/to them.

JSFX has several built in variables that can be accessed (and sometimes modified). You should refer to the reference for these. For example, you can get the current sample on channel 0 with spl0 in the @sample block.

So let's say we want to invert the left channel, we can just go
Code:
spl0 = -spl0;
in @sample.

By default, variables are defined globally, but you can also define functions, which can be called on an instance of something, which can provide you with a smaller environment that is encapsulated and protected from the global namespace (this is generally a good idea when you want multiple of something, or just to avoid overwriting variables).
__________________
[Tracker Plugin: Thread|Github|Reapack] | [Routing Plugin: Thread|Reapack] | [More JSFX: Thread|Descriptions|Reapack]

Last edited by sai'ke; 12-04-2018 at 06:38 AM.
sai'ke is offline   Reply With Quote
Old 12-05-2018, 10:19 PM   #7
Time Waster
Human being with feelings
 
Time Waster's Avatar
 
Join Date: Aug 2013
Location: Bowral, Australia
Posts: 1,638
Default

There is this, which helped me to get started: https://wiki.cockos.com/wiki/index.p...onic_Tutorials
__________________
Mal, aka The Wasters of Time
Mal's JSFX: ReaRack2 Modular Synth
Time Waster is offline   Reply With Quote
Old 12-08-2018, 02:25 PM   #8
inscript
Human being with feelings
 
Join Date: Aug 2018
Posts: 19
Default Functions?

Thanks for chiming in all! TimeWaster, ReaRack is brilliant! This is a nice little primer. I'm coming from Max/Pure Data, and a little bit of Supercollider, but definitely have more of a background in mixing than development. So I'm not new to DSP but haven't really delved in deep yet. I think an analogy for the distinction between beginner and intermediate users doing DSP (excuse the lack of knowledge here) might be knowing how to implement an oscillator and send it to the speakers vs. knowing how to perform multiple implementations of an oscillator, and what their advantages/disadvantages are, for instance. I'm definitely in that former category. Doing some research and just getting the first few sounds from JSFX now. I apologize if I came off a little frustrated in the last post, and I will attempt to be more deliberate here in the future. Turning this into a "how I'm learning JSFX" thread. Feel free to chime in wherever you would like with help/answers. I'm sure I'll have questions, which I'll either post here or in a separate thread if I think it would be more useful. One of the things I'm doing as an exercise is making a copy of an effect (like Schwa's soft-clipper, or the Tone Generator) and going through line by line, commenting what each bit of code does. I've now gotten the jist of how a script is structured, and I'm writing a script that's as minimal as possible so I can figure out what is and isn't necessary for a given script. I've been looking to build a phasor function for the beginnings of an oscillator and I'm encountering a problem:


Code:
@init

function osc(freq, amp)
(
phase = phase+(freq/srate);
(phase >= 2.0*$pi) ? phase -= 2.0*$pi;
phase = phase * amp
);

@sample

osc1 = osc(400, 1);
osc2 = osc(600, 1);
out = osc1 + osc2;

spl0 = out + spl0;
spl1 = out + spl1;
Two phasors summed to the output, right? But it appears that the only output I get is the second instance of the osc function. The operation between the oscillators matters less right now than the fact that I don't think both are working. I must be missing something. I've seen in the cookdsp code a bunch of "this" and "do" in regards to functions but I'm not sure what those do, and the JSFX reference take a lot about namespace and such but I havent gotten that far. How do functions work in JSFX?
inscript is offline   Reply With Quote
Old 12-09-2018, 03:32 AM   #9
Tale
Human being with feelings
 
Tale's Avatar
 
Join Date: Jul 2008
Location: The Netherlands
Posts: 3,645
Default

You could try this:

Code:
@init

function osc(freq, amp)
  instance(phase, out)
(
  phase = phase+(freq/srate);
  (phase >= 1.0) ? phase -= 1.0;
  out = (phase * 2 - 1) * amp;
);

@sample

osc1.osc(400, 0.25);
osc2.osc(600, 0.25);
out = osc1.out + osc2.out;

spl0 = out + spl0;
spl1 = out + spl1;
It makes the phase and output instance variables from the caller (osc1, osc2) instead of global variables.

Do note that this will produce a non-bandlimited (naive) saw, so it will alias pretty bad. Also, this code could be optimized...
Tale is offline   Reply With Quote
Old 12-24-2018, 09:40 AM   #10
Dyl
Human being with feelings
 
Join Date: Oct 2018
Posts: 59
Default Saving JSfx properly

Hi,
I'm trying to figure out how I save a modified (existing JSfx) under my own fx name.
I followed the forum advice to change the "desc: name here" line in the IDE and all sorts of oddness followed.
After changing the desc line I used CTL + S to save (as indicated at the bottom of the IDE).
I did this and it still forced the old name out when I tried loading an fx from the "Add fx" window in the mixer. But it had some of the changes I'd made. So it was some weird hybrid.
I restarted Reaper and the original was gone but my newly named botch-up had the original code/script? Can you tell I don't have a clue??

I could no longer access the original so had to copy text from a (fortunate notepad txt save). In doing this I ended up with a the original name showing in the mixer but my new name showing in the fx floating window for the same fx.

I tried updating Reaper (to regain the original Stillwell fx. This seemed to work but it's left me really confused as to what the actual process should be.
The JSfx programming guide just says save a copy of any modified JSfx. Not really clear how you do that given it's talking about a txt file.

I don't want to do anything fancy, I'm just trying to change the values on a couple of EQ bands, the frequencies and the dB cut/boost increments.

So, can you help me with a line by line process for saving an existing JSfx as a renamed fx. One that doesn't require the flipping about like I've just experienced.
As a bonus, how would I create and save a new JSfx using the IDE?

Thanks everyone.
Gary
Dyl is offline   Reply With Quote
Old 12-24-2018, 10:20 AM   #11
Meo-Ada Mespotine
Human being with feelings
 
Meo-Ada Mespotine's Avatar
 
Join Date: May 2017
Location: Leipzig
Posts: 6,621
Default

In the resources-folder of Reaper, there"s a folder called Effects.
In there, search for the effect that you want to alter(usually the effect-name itself).
Make a copy of that file and rename that file to a new name.

Restart Reaper, open the FX-Dialog and search for the effect-name.
It should contain now two instances of the same effect, where your copy has the path and filename at the end of the effectname. This is the one, that you can edit and alter.

It will also remain, after you updated Reaper, though you should keep a copy of it, after you made all your changes, so in the case of a fresh reinstall of Reaper, you still have it.

In the case of a fresh reinstall of Reaper, copy your altered effect back into the Effects folder in the resources-folder.

The rest should work as you already tried it.
__________________
Use you/she/her.Ultraschall-Api Lua Api4Reaper - Donate, if you wish

On vacation for the time being...
Meo-Ada Mespotine is offline   Reply With Quote
Old 12-24-2018, 11:15 AM   #12
Dyl
Human being with feelings
 
Join Date: Oct 2018
Posts: 59
Default Success

Brilliant,
thank you, thank you.
I had a couple of runs at this and I can follow what it should be doing now.
Initially, I was a little confused by the naming process in your example, the modified name appearing as an extension to the original name. Now I can understand that as I haven't yet changed the desc: my name line in the IDE by just creating a copy.
But when I'm looking for my copy in the effects folder it just uses the new name I've given it.
Got it now.
Thanks again.

If I want to create a new JSfx I have discovered I can do so from the add fx window,
select fx and create new.
When I save this it drops it into the last slot of the effects folder. I'm about to try out creating a new folder and dropping it into that.
An option to create the folder when I'm saving the new JSfx would be nice and useful.
Dyl is offline   Reply With Quote
Old 12-24-2018, 11:23 AM   #13
Meo-Ada Mespotine
Human being with feelings
 
Meo-Ada Mespotine's Avatar
 
Join Date: May 2017
Location: Leipzig
Posts: 6,621
Default

Quote:
Originally Posted by Dyl View Post
Brilliant,
thank you, thank you.

You"re welcome
__________________
Use you/she/her.Ultraschall-Api Lua Api4Reaper - Donate, if you wish

On vacation for the time being...
Meo-Ada Mespotine is offline   Reply With Quote
Old 12-24-2018, 11:47 AM   #14
Dyl
Human being with feelings
 
Join Date: Oct 2018
Posts: 59
Default

Quote:
Originally Posted by Dyl View Post
If I want to create a new JSfx I have discovered I can do so from the add fx window,
select fx and create new.
When I save this it drops it into the last slot of the effects folder. I'm about to try out creating a new folder and dropping it into that.
An option to create the folder when I'm saving the new JSfx would be nice and useful.
Ok, this seems to create a JSfx called myfxname in myname folder in the effects folder. I cannot figure out how to get it to recognise the new name in the add fx window though.
I've looked at the text file in notepad and ensured I've renamed the fx in line with the name I've given it in the effects folder. I've double checked the desc: myname line in the IDE. Everything matches up and when I look for it in Add fx in Reaper the only option is "new effect", it's refusing to recognise the name I've given it.
Dyl is offline   Reply With Quote
Old 12-24-2018, 12:01 PM   #15
Meo-Ada Mespotine
Human being with feelings
 
Meo-Ada Mespotine's Avatar
 
Join Date: May 2017
Location: Leipzig
Posts: 6,621
Default

You can have a look into the file: reaper-jsfx.ini
It is located in the resources-folder as well.
Browse through it and try to change the name in it.

There's an entry that begins with NAME and a later one that begins with REV

Change the second entry in the accompanying NAME-line, as this hold the name of the JSFX-file.
Change the first entry in the accompanying REV-entry as well.

Save the reaper-jsfx.ini and restart Reaper.
__________________
Use you/she/her.Ultraschall-Api Lua Api4Reaper - Donate, if you wish

On vacation for the time being...
Meo-Ada Mespotine is offline   Reply With Quote
Old 12-24-2018, 12:15 PM   #16
Meo-Ada Mespotine
Human being with feelings
 
Meo-Ada Mespotine's Avatar
 
Join Date: May 2017
Location: Leipzig
Posts: 6,621
Default

Ahh...this doesn't work, as somehow Reaper can't load the effect anymore...

Edit:
Put the name into the desc-line in the script, as you tried before and rename the newly created script. After that restart Reaper. This worked here, though I'm pretty sure, there's an easier way for doing that.
__________________
Use you/she/her.Ultraschall-Api Lua Api4Reaper - Donate, if you wish

On vacation for the time being...
Meo-Ada Mespotine is offline   Reply With Quote
Old 12-24-2018, 01:14 PM   #17
Dyl
Human being with feelings
 
Join Date: Oct 2018
Posts: 59
Default

Yeah, that last comment pretty much describes what I've been doing so far.
The only thing I tried differently was to rescan for new plug-ins and now my new effect is showing up with it's proper name, no longer "new effect".
I had just tried closing and restarting Reaper (which I had been doing all along).

I'm too inexperienced to tell whether this is buggy or user error. Either way, you've helped me figure it out.
Thanks again.
Dyl is offline   Reply With Quote
Old 12-28-2018, 02:12 PM   #18
inscript
Human being with feelings
 
Join Date: Aug 2018
Posts: 19
Default Key Input and Functions

Glad to see more users asking questions here. Feel free. I've been trying to do some basic key input, and I'm having an issue where both parameters are increment and decrement together. What I'm trying to achieve here is one number increments and decrements with the w and s keys, and another does the same with a and d keys, but independently. I think it could be an issue with function scope or memory, but I'm not quite sure. Could it be that I'm not correctly passing a variable to a pointer?

I'm also a little confused about the relationship between arguments and instance variables. I shouldn't need to duplicate the arguments as I've done here, but I know I need each instance of the function to contain local variables.

Eventually, I'd like to be able to have a list of parameters that are inc/decremented with "up" and "down", and be able to choose which parameter is currently edited with "left" and "right", but so far, my tests haven't worked out.

Code:
@init

function param(name, inc, dec, init, min, max, step)
  instance(name, inc, dec, init, min, max, step)
  (
    init = value;
    (inc == 1) ? value += step;
    (dec == 1) ? value -= step;
    (value < min) ? value = min;
    (value > max) ? value = max;
    parameter[name] = value;
  );

@gfx 200 200

up = gfx_getchar(119); //ascii w
down = gfx_getchar(115); //ascii s
left = gfx_getchar(97); //ascii a
right = gfx_getchar(100); //ascii d

num = param1.param(param1, up, down, 0, 0, 20, 0.5);
num2 = param2.param(param2, right, left, 0, 0, 20, 0.5);

gfx_x = 40;
gfx_y = 40;
gfx_r = 256;
gfx_setfont(1,"Calibri",30,'b');
gfx_drawnumber(num, 0);
gfx_x = 60;
gfx_y = 40;
gfx_drawnumber(num2, 0);
Thanks in advance for any help. Also, thanks Tale for the tip above. Works great!
inscript is offline   Reply With Quote
Old 12-29-2018, 12:48 AM   #19
inscript
Human being with feelings
 
Join Date: Aug 2018
Posts: 19
Default issue above solved

It looks like I've solved the issue above by turning "name" and "value" into instance variables. Will report back once I get stuck somewhere again.
inscript is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -7. The time now is 11:31 AM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.