Old 06-17-2011, 09:00 AM   #1
rudeog
Human being with feelings
 
Join Date: Dec 2006
Posts: 27
Default Arabic scale (quarter-tone) script

Hi All,
I've written the below JS script to allow me to play my hardware synths using Arabic scales. These scales have quarter-tones and thus cannot normally be played on a regular keyboard. A friend of mine has a small hardware box that he hooks up to his keyboard to remap the keys so that quarter-tones are possible. This made me wonder if the same thing could be done in reaper using JS. And as I found it was very easy to do.
I'm posting this in case of the unlikely event that there are other Reaper users playing Arabic maqamat.


/* MIDI filter that converts notes to "quarter tones" for Arabic music.
This allows you to play Arabic scales like Bayati and Rast on a regular
keyboard using your regular softsynths or even outboard gear.

by A. Shakinovsky (andrew@binarydog.com)

To use: insert into your FX chain before your softsynth. If you are using
outboard gear, you'll need to turn local control off on your synth and
route the MIDI output of the channel back to the midi out port.

How it works: It simply sends a pitch bend before each note played. If the
note is one you've selected to sharpen or flatten, it will apply an upward
or downward pitch bend before that note. It will bend it by the percentage
specified. For best results, set your synth pitch bend range to one semitone
and set this bend percentage to 50.
*/

desc: MIDI QuarterTone

slider1:12<0,12,1{C,C#,D,D#,E,F,F#,G,G#,A,A#,B,Non e}>Half Flat 1
slider2:12<0,12,1{C,C#,D,D#,E,F,F#,G,G#,A,A#,B,Non e}>Half Flat 2
slider3:12<0,12,1{C,C#,D,D#,E,F,F#,G,G#,A,A#,B,Non e}>Half Flat 3
slider4:12<0,12,1{C,C#,D,D#,E,F,F#,G,G#,A,A#,B,Non e}>Half Flat 4
slider5:12<0,12,1{C,C#,D,D#,E,F,F#,G,G#,A,A#,B,Non e}>Half Flat 5
slider6:12<0,12,1{C,C#,D,D#,E,F,F#,G,G#,A,A#,B,Non e}>Half Flat 6
slider7:12<0,12,1{C,C#,D,D#,E,F,F#,G,G#,A,A#,B,Non e}>Half Sharp 1
slider8:12<0,12,1{C,C#,D,D#,E,F,F#,G,G#,A,A#,B,Non e}>Half Sharp 2
slider9:12<0,12,1{C,C#,D,D#,E,F,F#,G,G#,A,A#,B,Non e}>Half Sharp 3
slider10:12<0,12,1{C,C#,D,D#,E,F,F#,G,G#,A,A#,B,No ne}>Half Sharp 4
slider11:12<0,12,1{C,C#,D,D#,E,F,F#,G,G#,A,A#,B,No ne}>Half Sharp 5
slider12:12<0,12,1{C,C#,D,D#,E,F,F#,G,G#,A,A#,B,No ne}>Half Sharp 6
slider13:50<0,100,1>Bend percentage
in_pin:none
out_pin:none
@init
msg1=msg23=0;
flattennotes=0;
sharpennotes=6;
status=channel=0;
@slider

// determine which notes to flatten/sharpen
flattennotes[0]=slider1;
flattennotes[1]=slider2;
flattennotes[2]=slider3;
flattennotes[3]=slider4;
flattennotes[4]=slider5;
flattennotes[5]=slider6;
sharpennotes[0]=slider7;
sharpennotes[1]=slider8;
sharpennotes[2]=slider9;
sharpennotes[3]=slider10;
sharpennotes[4]=slider11;
sharpennotes[5]=slider12;
bendamt=slider13/100;
@block
while
(
midirecv(offset,msg1,msg23) ?
(
//Check status byte
status = msg1 & 240; // High four bits is type (240 == 11110000)
channel = msg1 & 15; //Low four bits is channel number (15 == 00001111)

// is it a note down (1001)
(status == 144) ?
(
// get note number, then mod 12 to get the note (where C is 0)
// the 2nd byte of the midi message is in the low order 8 bits
// the 3rd byte is in the high order 8 bits,
// which in the case of note-on contains velocity
//
note = (msg23 & 127) % 12;
// check to see if it's one we care about
i=0;
bend=8192; // no bend
loop(6,
(flattennotes[i]==note) ? (
bend -= (8192 * bendamt); // flatten
) : (sharpennotes[i]==note) ? (
// sharpen by sending max pitch bend
bend += (8192 * bendamt); // sharpen
);
i+=1;
); // end loop
// send the bend data (pitch bend is 224)
midibend = bend & $xFF80; // take everything except lo 7
midibend = midibend * 2; // shift left
midibend += (bend & $x7F); // and add back the lo 7
midisend(offset, 224+channel, midibend);

); // if note on
// send original message
midisend(offset,msg1,msg23);
);
);
rudeog is offline   Reply With Quote
Old 01-25-2012, 08:03 AM   #2
amagalma
Human being with feelings
 
amagalma's Avatar
 
Join Date: Apr 2011
Posts: 3,451
Default

Great! Thank you very much!! )

Is it possible to do a modified version of this plugin that would be able to tune each one note in cents? (± 100 cents)
It would have 12 sliders for each of the twelve notes of the chromatic scale, centered to 0 with lowest value -100cents (down a semitone) and maximum value +100cents (up a semitone).
Something like this:
C: -100 ---------- 0 ---------- 100
C#: -100 ---------- 0 ---------- 100
D: -100 ---------- 0 ---------- 100
D#: -100 ---------- 0 ---------- 100
E: -100 ---------- 0 ---------- 100
etc etc

This way one could use it for any kind of microtonal music, be it classical, arabic, turkish, gamelan, byzantine, whatever..
amagalma is offline   Reply With Quote
Old 01-25-2012, 09:24 PM   #3
amagalma
Human being with feelings
 
amagalma's Avatar
 
Join Date: Apr 2011
Posts: 3,451
Default

Well, I tried to do it myself - I have no idea on programming - just tried to reverse engineer what you did.. but it does not work correctly!
Could someone have a look and tell me what is the problem?

Thanks!

desc: MIDI Tuning

slider1:0<-100,100,1>C
slider2:0<-100,100,1>C#
slider3:0<-100,100,1>D
slider4:0<-100,100,1>D#
slider5:0<-100,100,1>E
slider6:0<-100,100,1>F
slider7:0<-100,100,1>F#
slider8:0<-100,100,1>G
slider9:0<-100,100,1>G#
slider10:0<-100,100,1>A
slider11:0<-100,100,1>A#
slider12:0<-100,100,1>B
in_pin:none
out_pin:none

@init
msg1=msg23=0;
status=channel=0;
bend=8192

@slider
tunednote[0]=slider1*40.96;
tunednote[1]=slider2*40.96;
tunednote[2]=slider3*40.96;
tunednote[3]=slider4*40.96;
tunednote[4]=slider5*40.96;
tunednote[5]=slider6*40.96;
tunednote[6]=slider7*40.96;
tunednote[7]=slider8*40.96;
tunednote[8]=slider9*40.96;
tunednote[9]=slider10*40.96;
tunednote[10]=slider11*40.96;
tunednote[11]=slider12*40.96;

@block
while
(
midirecv(offset,msg1,msg23) ?
(
//Check status byte
status = msg1 & 240; // High four bits is type (240 == 11110000)
channel = msg1 & 15; //Low four bits is channel number (15 == 00001111)

// is it a note down (1001)
(status == 144) ?
(
// get note number, then mod 12 to get the note (where C is 0)
// the 2nd byte of the midi message is in the low order 8 bits
// the 3rd byte is in the high order 8 bits,
// which in the case of note-on contains velocity
//
i = (msg23 & 127) % 12;

bend = (8192+tunednote[i]);

// send the bend data (pitch bend is 224)
midibend = bend & $xFF80; // take everything except lo 7
midibend = midibend * 2; // shift left
midibend += (bend & $x7F); // and add back the lo 7
midisend(offset, 224+channel, midibend);

); // if note on
// send original message
midisend(offset,msg1,msg23);
);
);
amagalma is offline   Reply With Quote
Old 01-31-2012, 02:41 AM   #4
amagalma
Human being with feelings
 
amagalma's Avatar
 
Join Date: Apr 2011
Posts: 3,451
Default

I changed it and it is working now.. But the tuning is still not very correct! Could someone have a look and tell me what is wrong in the code? Thanks!

Code:
desc: MIDI Tuning (in cents)

slider1:0<-100,100,0.01>C
slider2:0<-100,100,0.01>C#
slider3:0<-100,100,0.01>D
slider4:0<-100,100,0.01>D#
slider5:0<-100,100,0.01>E
slider6:0<-100,100,0.01>F
slider7:0<-100,100,0.01>F#
slider8:0<-100,100,0.01>G
slider9:0<-100,100,0.01>G#
slider10:0<-100,100,0.01>A
slider11:0<-100,100,0.01>A#
slider12:0<-100,100,0.01>B
in_pin:none
out_pin:none

@init
msg1=msg23=0;
status=channel=0;

@slider
tunednote[0]=slider1*40.96;
tunednote[1]=slider2*40.96;
tunednote[2]=slider3*40.96;
tunednote[3]=slider4*40.96;
tunednote[4]=slider5*40.96;
tunednote[5]=slider6*40.96;
tunednote[6]=slider7*40.96;
tunednote[7]=slider8*40.96;
tunednote[8]=slider9*40.96;
tunednote[9]=slider10*40.96;
tunednote[10]=slider11*40.96;
tunednote[11]=slider12*40.96;

@block
while
(
midirecv(offset,msg1,msg23) ?
(
//Check status byte
status = msg1 & 240; // High four bits is type (240 == 11110000)
channel = msg1 & 15; //Low four bits is channel number (15 == 00001111)

// is it a note down (1001)
(status == 144) ?
(
// get note number, then mod 12 to get the note (where C is 0)
// the 2nd byte of the midi message is in the low order 8 bits
// the 3rd byte is in the high order 8 bits,
// which in the case of note-on contains velocity
//
note = (msg23 & 127) % 12;
// check to see if it's one we care about
i=0;
bend=8192; // no bend

loop(12,
(i==note) ? (
bend += tunednote[i];
);
i+=1;
); // end loop 

// send the bend data (pitch bend is 224)
midibend = bend & $xFF80; // take everything except lo 7
midibend = midibend * 2; // shift left
midibend += (bend & $x7F); // and add back the lo 7
midisend(offset, 224+channel, midibend);

); // if note on
// send original message
midisend(offset,msg1,msg23);
);
);
amagalma is offline   Reply With Quote
Old 02-11-2012, 10:43 AM   #5
Kamjam7
Human being with feelings
 
Join Date: Feb 2012
Posts: 1
Default

Great idea! This would be very useful to me, but i don't know much about scripting.

I've tried running all the codes listed above, but each shows an Indentation error on line 1, and i swear there's no problems with it. Could this be because I'm still using the evaluation version of Reaper, and it's a glitch that would fixed with the updates when purchasing a license? If so, i was planning on buying a license soon anyway
Kamjam7 is offline   Reply With Quote
Old 11-18-2012, 10:24 AM   #6
memyselfandus
Human being with feelings
 
memyselfandus's Avatar
 
Join Date: Oct 2008
Posts: 1,598
Default

Quote:
Originally Posted by rudeog View Post
Hi All,
I've written the below JS script to allow me to play my hardware synths using Arabic scales. These scales have quarter-tones and thus cannot normally be played on a regular keyboard. A friend of mine has a small hardware box that he hooks up to his keyboard to remap the keys so that quarter-tones are possible. This made me wonder if the same thing could be done in reaper using JS. And as I found it was very easy to do.
I'm posting this in case of the unlikely event that there are other Reaper users playing Arabic maqamat.


/* MIDI filter that converts notes to "quarter tones" for Arabic music.
This allows you to play Arabic scales like Bayati and Rast on a regular
keyboard using your regular softsynths or even outboard gear.

by A. Shakinovsky (andrew@binarydog.com)

To use: insert into your FX chain before your softsynth. If you are using
outboard gear, you'll need to turn local control off on your synth and
route the MIDI output of the channel back to the midi out port.

How it works: It simply sends a pitch bend before each note played. If the
note is one you've selected to sharpen or flatten, it will apply an upward
or downward pitch bend before that note. It will bend it by the percentage
specified. For best results, set your synth pitch bend range to one semitone
and set this bend percentage to 50.
*/

desc: MIDI QuarterTone

slider1:12<0,12,1{C,C#,D,D#,E,F,F#,G,G#,A,A#,B,Non e}>Half Flat 1
slider2:12<0,12,1{C,C#,D,D#,E,F,F#,G,G#,A,A#,B,Non e}>Half Flat 2
slider3:12<0,12,1{C,C#,D,D#,E,F,F#,G,G#,A,A#,B,Non e}>Half Flat 3
slider4:12<0,12,1{C,C#,D,D#,E,F,F#,G,G#,A,A#,B,Non e}>Half Flat 4
slider5:12<0,12,1{C,C#,D,D#,E,F,F#,G,G#,A,A#,B,Non e}>Half Flat 5
slider6:12<0,12,1{C,C#,D,D#,E,F,F#,G,G#,A,A#,B,Non e}>Half Flat 6
slider7:12<0,12,1{C,C#,D,D#,E,F,F#,G,G#,A,A#,B,Non e}>Half Sharp 1
slider8:12<0,12,1{C,C#,D,D#,E,F,F#,G,G#,A,A#,B,Non e}>Half Sharp 2
slider9:12<0,12,1{C,C#,D,D#,E,F,F#,G,G#,A,A#,B,Non e}>Half Sharp 3
slider10:12<0,12,1{C,C#,D,D#,E,F,F#,G,G#,A,A#,B,No ne}>Half Sharp 4
slider11:12<0,12,1{C,C#,D,D#,E,F,F#,G,G#,A,A#,B,No ne}>Half Sharp 5
slider12:12<0,12,1{C,C#,D,D#,E,F,F#,G,G#,A,A#,B,No ne}>Half Sharp 6
slider13:50<0,100,1>Bend percentage
in_pin:none
out_pin:none
@init
msg1=msg23=0;
flattennotes=0;
sharpennotes=6;
status=channel=0;
@slider

// determine which notes to flatten/sharpen
flattennotes[0]=slider1;
flattennotes[1]=slider2;
flattennotes[2]=slider3;
flattennotes[3]=slider4;
flattennotes[4]=slider5;
flattennotes[5]=slider6;
sharpennotes[0]=slider7;
sharpennotes[1]=slider8;
sharpennotes[2]=slider9;
sharpennotes[3]=slider10;
sharpennotes[4]=slider11;
sharpennotes[5]=slider12;
bendamt=slider13/100;
@block
while
(
midirecv(offset,msg1,msg23) ?
(
//Check status byte
status = msg1 & 240; // High four bits is type (240 == 11110000)
channel = msg1 & 15; //Low four bits is channel number (15 == 00001111)

// is it a note down (1001)
(status == 144) ?
(
// get note number, then mod 12 to get the note (where C is 0)
// the 2nd byte of the midi message is in the low order 8 bits
// the 3rd byte is in the high order 8 bits,
// which in the case of note-on contains velocity
//
note = (msg23 & 127) % 12;
// check to see if it's one we care about
i=0;
bend=8192; // no bend
loop(6,
(flattennotes[i]==note) ? (
bend -= (8192 * bendamt); // flatten
) : (sharpennotes[i]==note) ? (
// sharpen by sending max pitch bend
bend += (8192 * bendamt); // sharpen
);
i+=1;
); // end loop
// send the bend data (pitch bend is 224)
midibend = bend & $xFF80; // take everything except lo 7
midibend = midibend * 2; // shift left
midibend += (bend & $x7F); // and add back the lo 7
midisend(offset, 224+channel, midibend);

); // if note on
// send original message
midisend(offset,msg1,msg23);
);
);
how do we use this? text file?
memyselfandus is offline   Reply With Quote
Old 11-18-2012, 01:55 PM   #7
xpander
Human being with feelings
 
xpander's Avatar
 
Join Date: Jun 2007
Location: Terra incognita
Posts: 7,670
Default

Just on quick try I cannot see the sliders using rudeog's script. The one amagalma showed on post #4 works, but apparently it is not doing exactly what he/she wants to do with it? At any rate, to make that text a working JS effect do this:

-copy the script text to notepad and save from there
-give the file a name like the one in desc line (ie. MIDI Tuning)
-save without the file extension (.txt) or rename the already saved text file like that
-copy the file into the Effects folder in user resource path. For example in WinXP it is C:\Documents and Settings\[user name]\Application Data\REAPER \Effects
-inside reaper, open JS Effects folder and choose your effect
xpander is offline   Reply With Quote
Old 01-31-2015, 09:54 PM   #8
memyselfandus
Human being with feelings
 
memyselfandus's Avatar
 
Join Date: Oct 2008
Posts: 1,598
Default

Missed this! thank you
memyselfandus is offline   Reply With Quote
Old 02-01-2015, 02:25 AM   #9
amagalma
Human being with feelings
 
amagalma's Avatar
 
Join Date: Apr 2011
Posts: 3,451
Default

Could someone make it work?

Code:
desc: MIDI Tuning (in cents)

slider1:0<-100,100,0.01>C
slider2:0<-100,100,0.01>C#
slider3:0<-100,100,0.01>D
slider4:0<-100,100,0.01>D#
slider5:0<-100,100,0.01>E
slider6:0<-100,100,0.01>F
slider7:0<-100,100,0.01>F#
slider8:0<-100,100,0.01>G
slider9:0<-100,100,0.01>G#
slider10:0<-100,100,0.01>A
slider11:0<-100,100,0.01>A#
slider12:0<-100,100,0.01>B
in_pin:none
out_pin:none

@init
msg1=msg23=0;
status=channel=0;

@slider
tunednote[0]=slider1*40.96;
tunednote[1]=slider2*40.96;
tunednote[2]=slider3*40.96;
tunednote[3]=slider4*40.96;
tunednote[4]=slider5*40.96;
tunednote[5]=slider6*40.96;
tunednote[6]=slider7*40.96;
tunednote[7]=slider8*40.96;
tunednote[8]=slider9*40.96;
tunednote[9]=slider10*40.96;
tunednote[10]=slider11*40.96;
tunednote[11]=slider12*40.96;

@block
while
(
midirecv(offset,msg1,msg23) ?
(
//Check status byte
status = msg1 & 240; // High four bits is type (240 == 11110000)
channel = msg1 & 15; //Low four bits is channel number (15 == 00001111)

// is it a note down (1001)
(status == 144) ?
(
// get note number, then mod 12 to get the note (where C is 0)
// the 2nd byte of the midi message is in the low order 8 bits
// the 3rd byte is in the high order 8 bits,
// which in the case of note-on contains velocity
//
note = (msg23 & 127) % 12;
// check to see if it's one we care about
i=0;
bend=8192; // no bend

loop(12,
(i==note) ? (
bend += tunednote[i];
);
i+=1;
); // end loop 

// send the bend data (pitch bend is 224)
midibend = bend & $xFF80; // take everything except lo 7
midibend = midibend * 2; // shift left
midibend += (bend & $x7F); // and add back the lo 7
midisend(offset, 224+channel, midibend);

); // if note on
// send original message
midisend(offset,msg1,msg23);
);
);
amagalma is offline   Reply With Quote
Old 02-01-2015, 06:28 AM   #10
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 9,875
Default

maybe you can try alt-tuner | microtonal software | Tall Kite for micro tuning in REAPER ?
X-Raym is offline   Reply With Quote
Old 02-03-2015, 02:16 PM   #11
amagalma
Human being with feelings
 
amagalma's Avatar
 
Join Date: Apr 2011
Posts: 3,451
Default

I've seen it.. too expensive!!
amagalma 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 02:45 PM.


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