How do I reprogram a midi pedal with MidiPipe using Applescript?

Hello everybody, I’m a pianist with passion for music editing.

I’m trying to learn AppleScript applied to Midipipe by Subtlesoft, but I’ve been able to find very few hints and basically no manual out there. This forum seems to be the right place to start. I’ve tried to figure out the issue by myself through previous post reading, but I’m not strong enough with AppleScript to success. As many knows, Midipipe software allows to control and edit midi message through AppleScript syntax.

I hope someone might help me with the syntax in order to properly configure a midi pedal and be able to send the right messages to any audio editor (Garageband / Logic / other). The pedal is intended to send a Sustain CC message ON when pressed (176, 64, 127), and the same OFF message when released (176, 64, 0), but randomly it also generates additional (unwanted) note on-off messages, maybe due to the range of its mechanical movement and how electronic sensor translate it to midi. I noticed that random unwanted messages depends also on the force or velocity applied to the pedal when pressed.

The midi pedal behaves as follows when pressed.

NORMAL BEHAVIOR:

Action Message Channel Data
Pressed Control Change 066. Sostenuto on/off 1 176, 66, 127
Released Control Change 066. Sostenuto on/off 1 176, 66, 0

Here I just want to reprogram to switch from a Sostenuto to a Sustain (176, 64, 127) when pressed, and off the sustain when released (176, 64 ,0). Pretty easy with an IF cycle.

The problem are the “random behavior” that sometime happen, and these are the “noisy” message that I’m trying to filter.

RANDOM BEHAVIORS:

First kind: it generates a note off instead of control change off.

Action Message Channel Data
Pressed Control Change 066. Sostenuto on/off 1 176, 66, 127
Released Note Off F# 5 1 144, 66, 0

Second kind: it generates a note on instead of control change on.

Action Message Channel Data
Pressed Note On F#5 1 144, 66, 127
Released Control Change 066. Sostenuto on/off 1 176, 66, 0

Third kind: it generates both a note on - off instead of control change on - off

Action Message Channel Data
Pressed Note On F#5 1 144, 66, 127
Released Note Off F# 5 1 144, 66, 0

Then, through my script I’m trying to filter the following:

  • If the pedal behaves normally, I simply convert the Sostenuto into Sustain messages (converting the second item of message from 66 to 64, both on and off messages).
  • If the pedal triggers a loud F#5 on pressed, I want to convert that note on (144, 66, 127) in a Sustain message (176, 64, 127)
  • If the pedal is released with a NoteOff F#5 is the most tricky to solve for me, because I don’t want to interfere with the piano keyboard (which also have a F#5 key). While is quite improbable (if not impossible) to play a loud F#5 with fingers (Note On can be easily filtered with a IF cycle too), the NoteOff F#5 can be produced by both pedal and key release.

So, I want to find a way to translate a normal note off generated by piano keyboard, from a noisy note off generated by pedal (both transmit on channel 1, unfortunately).

Is there any way to duplicate any Note Off F#5 message in order to split it in 2 messages:

  • The note off
  • The sustain off

That’s not a perfect behavior, because a note off on keyboard also mutes the sustain effect from pedal, but I could live with that. Of course, if you guys have a smarter solution, I would appreciate! Thanks for your help. Marco, Italy.

My script:


-- this script tries to convert a note on/off message to a sustain message 

on runme(message)
-- if the message passed by pressed pedal is a Sostenuto ON
if (item 1 of message = 176) and (item 2 of message = 66) and (item 3 of message = 127) then
-- insert cc64 to convert to a Sustain ON
return {176, 64, 127}
end if

-- if the message passed by pressed pedal is a loud F#5 note
if (item 1 of message = 144) and (item 2 of message = 66) and (item 3 of message = 127) then
-- insert cc64 to convert to a Sustain ON
return {176, 64, 127}
end if

-- if the message passed by released pedal is a Sostenuto OFF
if (item 1 of message = 176) and (item 2 of message = 66) and (item 3 of message = 0) then
-- insert cc64 to convert to a Sustain OFF
return {176, 64, 0}
end if

-- if the message passed by released pedal is a F#5 note OFF
if (item 1 of message = 144) and (item 2 of message = 66) and (item 3 of message = 0) then
-- insert cc64 to convert to a Sustain OFF (but any F#5 played by keyboard lasts forever, here is where I wish to duplicate the message in order to have both sustain off and note off)
return {176, 64, 0}
end if

return message
end runme

Model: iMac, Yamaha P-155 piano,
Browser: Safari 537.36
Operating System: macOS 10.13

welcome to AppleScript.
yeah it’s MIDI interfacing is not great.
You can do this with MIDI pipe but i’ve found it frustrating,
For myself i ended up implementing VVMIDI Framework and using ASObj-C, let me know
if your ever interested in that.

So one AppleScript programming you should learn about:

Functions
(or in this link they refer to them as sub-routines)
https://www.macosxautomation.com/applescript/sbrt/index.html

To translate that into basic code:
if (the message is a Note off F#5) then

  1. run code to create the Sustain Off
  2. return original message (Note off F#5)
    or run code to create a Note off F#5
    end if
on runme(message)
-- removed the ON stuff

-- if the message passed by released pedal is a Sostenuto OFF
if (item 1 of message = 176) and (item 2 of message = 66) and (item 3 of message = 0) then
-- call subroutine to return SustainOff
my sustainOff()
end if

-- if the message passed by released pedal is a F#5 note OFF
if (item 1 of message = 144) and (item 2 of message = 66) and (item 3 of message = 0) then
-- call subroutine to return SustainOff then call subroutine to return F#5 off
my sustainOff()
my fSharpFiveOff()
end if

return message
end runme

on sustainOff()
return {176, 64, 0}
end sustainOff

on fSharpFiveOff()
return {144, 66, 0}
end fSharpFiveOff


on thing i’m note sure if MIDI Pipe will allow you return two messages before it moves on.
You’ll have to test and see what happens.
If so you may have to call the runMe(144,66,0) back on itself again.
^^^ whoops that won’t work just will end up in loop
my runMe({176, 64, 0})

Also you should be able to Achieve what your looking at doing directly in MIDIPipe itself.

Thank you technomorph! Your suggestions and link helped a lot!:slight_smile: