Would someone make a midi machine that could make the sustain pedal function as a sostenuto pedal? Is that even possible?

I’ve noticed most vsts don’t have sostenuto functionality. Keyboard players can live without it by playing a chord and holding it, then playing melodies on top of it, while we guitarists don’t have that luxury. Would that be possible to make for MG2?

1 Like

Try this:

function OnNote(channel, pitch, velocity)
– for any note played, send out the exact same note
Note(channel, pitch, velocity)
end

function OnControl(channel, cc, value)
if cc == 64 then
Control(channel, 66, value)
else
Control(channel, cc, value)
end
end

function OnStart(info)
– assign a description to be displayed in the header
info.description = "transforms sustain to sostenuto "
end

How do you trig this?

You click on a MIDI FX and open “Create custom MIDI Effects…”
Then a the right side click new
delete everything in the left big frame and paste in the code I did send.
Click on rename on the right side and give it a name you like in the left top field.
Then click apply in the top middle.

I assume you already have configured your sustain-pedal in the control field in the interface-view.
And that should do it. Hoping the Synth understands it.
If not let me know.

It gives out “Line 2: unexpected symbol near char(226)”

I don’t code, but doesn’t that script just change cc64 to cc66?
Which still wouldn’t work with plugins that don’t support sostenuto functionality

I get it now. Should have read the topic more carefully.
That would be quite more complicated.
The error probably comes from copying from the forum.
No error here. Try first to copy to something like textedit and then into midimachine.
Did you delete everything else first. There is no char(226) in line 2 in the above code.
On the other side you don’t need it anyway.
When I have more time I might try to write a midi-machine for the real topic.
Sorry for the simple non-solution.

1 Like

This is because a comment start with "-- ", not “-”.
It is the same for the last comment.

You did not understand my question, I’m used to using midi machines and I’ve already written and modified several routines in lua.
The code you’ve written simply transforms one cc value into another, but there are no calls to knobs controlling the stated functions or calls to a foot pedal.

This would be very useful as my scripting knowledge is limited and I have not managed to write any code for the sostenuto function.

1 Like

Get it. I found that when you copy/paste code into the forum, doublehyphen become char(226) and a hyphen. I am new to the forum. Do you know how to post code in a post that can be used by copying?
About the triggering I obviously misunderstood.
As I understand and as I do it you set the Midi-controller in the Interface-view(tab) under control.
After that you can transform the incoming MIDI with the code.
How I understand it you want to send a CC66(value 127) and all the notes that are playing at this moment shouldn’t get a note-off until you send a CC66(value 0) .
If you want to use any CC for that, yes you would need a knob to select that CC-number, otherwise no knob needed.
I would probably save the last 6(maybe more) note-ons in a array, and always delete them from the array on receiving a note-off of a note in the array.
On getting a CC66(or whatever defined) I would block notes-off for the notes still in the array and on a CC66value0 send a note-off to all notes in the array. That is a first idea. There are probably more things to consider and to be learned by testing. As I am new to Lua I will have to have a look at the spec to see how to do that all in Lua. Probably not different to other languages.
I try to find time for that. Maybe you could give it a try, too. Maybe you are faster.
You are right, it would be a useful midi-machine.

Copy/paste the code in a text editor (Windows NotePad, OSX TextEdit), save it with .lua extension and upload it with the “upoload” icon.

On the subject of the cc66, I don’t understand how you make it work for sostenuto: my midi pedal is set to cc66 but after trying out a dozen plugins, it either acts like a sustainer or has no effect at all, but no sostenuto.

Thanks. will do so.
The last code would transform cc64 to cc66.
As I understand you don’t want to receive a CC64 from your pedal and let the midi-machine imitate the sostenuto. You want to have a sostenuto-behavior for synth that don’t accept sostenuto (cc66).
When we implement a knob to choose the CC you can use any controller.
To the synth only the notes out of the midi-machine would be send.
I got curious and started experimenting. maybe it will not take long.

I am sorry. I give up on this.
midi-machine is not working as I was expecting. You cannot send Note(…) from OnControl. You only can send Note from OnNote etc.
Maybe someone else can help.

EDIT: perhaps the noteof on pedalrelease must be relayed to the onFrame handler. bit rusty didnt do any LUA scripts in 3 years. The logic here should however be ok. I’ll debug it later, didnt test a thing
EDIT 2: relayed the pedal release noteoff to the onframe handler.
EDIT 3: fixed a typo. works!

I think I’ve got all the things to make sustenuto here in this script.
There are 2 arays to keep trakc of things:
currentNotes[] = notes that you are actually playing
holdNotes[] = notes on hold
-on pedal press, the holdNotes[] are copied from the currentNotes[]
-noteoffs of holdNotes[] are postponed.
-noteons on holdNotes[] get a retrigger noteoff added in front
-on pedal release all holdNotes[] that are not also in currentNotes[] get a noteoff…
The script will work with any polyphonic MIDI instrument, since the handling is all done here.

`


-- COPY START
-- 
-- SOSTENUTO
-- Paul Driessen 2023
-- our global stack:
pedalDown = false
pedalReleased = false -- used to trigger onframe functions
cc = 66
myChannel=1
-- arrays to store 
currentNotes= {}
holdNotes= {}

function OnNote(channel, pitch, velocity)
  if(velocity<1) then
    —noteoff
    if (holdNotes[pitch]>0) then
        -- no noteoff when note is on hold
        currentNotes[pitch] = 0
      else
        currentNotes[pitch] = 0
        Note(channel, pitch, velocity)  
    end 
  else
     -- note on  
     if(holdNotes[pitch]>0) then
            --retrigger, shut off first
             Note(channel, pitch, 0)
     end   
     currentNotes[pitch]=velocity
     myChannel=channel
     Note(channel, pitch, velocity)
  end
end

function markNotes()
   for i=20,120 do 
     holdNotes[i] = currentNotes[i]
   end
end


function OnBend(channel, pitch, bend)
 Bend(channel, pitch, bend) -- alters every incoming bend message 
end

function OnControl(channel, incc, value)
if(incc==cc) then
   if(pedalDown) then
     if(value<64) then
        pedalDown=false
        pedalReleased=true   -- let the OnFrame handler do it!            
     end
   else
     if(value>63) then
        pedalDown=true
        markNotes()             
     end
   end
else
   Control(channel, cc, value) -- alters every incoming continuous controller 
end
end


function OnFrame(notes)
if( pedalReleased ) then
  for i=20,120 do 
    if( holdNotes[i] > 0 ) then
      if( currentNotes[i] < 1 ) then
       -- no currently fingered
       Note(myChannel, i, 0)
      end 
       holdNotes[i]=0
    end
  end
  -- only do this once, reset our trigger
  pedalReleased = false
end
end


function OnAfterTouch(channel, pitch, velocity)
AfterTouch(channel, pitch, velocity)
end


function OnStart(info)
info.description = "Sustenuto"
--info.link = "jamor"

Knob("cc", 0, 1,120, 1)  — Typo was here cc var is underscore.. ;)

Text(0,"Sustenuto on cc")

 for i=20,120 do 
     holdNotes[i] = 0
     currentNotes[i] = 0
 end
end

--COPY END
1 Like

You may need to copy the updated “EDIT 2” version of the script. I’ll check whether it works within an hour.

EDIT 3 version works here.

I’ve just tested it: it works perfectly.
Thank you Paul and it looks like you have not lost your touch with lua scripting. :grinning:

1 Like

yes, that is a known quirk. Solution: You can offload the noteon() calls for the pedal release to the OnFrame() handler. See my sostenuto script above.

Here a pre-baked script to download and install into the midimachine folder in the MIDIMachiens folder.
(win/mac only: click in MG preferences “midi guitar data folder”,
subfolder MIDIMachines )

2 Likes