MIDI-OX User Forum (http://www.midiox.com/cgi-bin/yabb/YaBB.pl)
MIDI-OX >> Scripting Questions >> Solo Script?
(Message started by: browntoven on May 26th, 2006, 12:05pm)

Title: Solo Script?
Post by browntoven on May 26th, 2006, 12:05pm
Hi all. The MIDI organ I play on at work has an option where one can have the lowest note being played on the great, and have it play through the pedal channel. It is called an auto-bass or bass coupler, in effect relieving one from playing the pedals.

I can get all the notes in a certain range to play on another channel with the mapping transforms of course, but does anyone know how I might go about scripting so just the LOWEST note ONLY gets routed to the output channel? In effect an inverted "solo" stop.

thnx in advace

Title: Re: Solo Script?
Post by Jamie OConnell on May 26th, 2006, 1:04pm
Pseudo code might be something like:

. . .


SOLOCHAN = 7 // arbitrary
static int LowestNote = 128

if EVENT = NOTE_ON AND Velocity > 0
  if EVENT.NOTE < LowestNote
     if LowestNote < 128
         send( SOLOCHAN, NOTE_OFF, LowestNote, 0 )
     end
     LowestNote = EVENT.NOTE
     send( SOLOCHAN, NOTE_ON, LowestNote, velocity )
  else
     send( chan, NOTE_ON, EVENT.NOTE, velocity )
  end
else if EVENT = NOTE_OFF OR Velocity = 0
  if EVENT.NOTE == LowestNote
     send( SOLOCHAN, NOTE_OFF, LowestNote, 0 )
     LowestNote = 128
  else
     send( chan, NOTE_OFF, EVENT.NOTE, velocity )
  end
end


. . .

Title: Re: Solo Script?
Post by Jamie OConnell on May 27th, 2006, 4:00pm
Here's the MIDI input/output connection point function for an actual implementation in JScript:


// Global data, used by MIDI subroutine
var lowestNote;
var soloChan;
var mapChan;
var noteSplit;

// Global Initialization
lowestNote = 128; // init to outside range
soloChan   = 13;  // MIDI channels are numbered 0 - 15  
mapChan    = 11;
noteSplit  = 60;  // only map MIDI notes below middle C


function On_MidiInput( ts, port, stat, dat1, dat2)
{
  var status;
  var chan;

  status = stat & 0x0F0;
  chan   = stat & 0x00F;

  if (chan == mapChan)
  {
     if (status == 0x090 && dat2 > 0)
     {
        // event is a Note On on our mapping channel
        if (dat1 < noteSplit && dat1 < lowestNote)
        {
           if (lowestNote < 128) // we're sounding one: turn off
              mox.OutputMidiMsg( -1, 0x080 | soloChan, lowestNote, 0 );

           lowestNote = dat1;    // new lowest note: sound on solo channel
           mox.OutputMidiMsg( -1, status | soloChan, lowestNote, dat2 );

           return; // done - get out
           //////
        }
     }

     if (status == 0x080 || (status == 0x090 && dat2 == 0))
     {
        // event is a Note Off on our mapping channel
        if (dat1 == lowestNote)
        {
           // turn off solo channel note we're sounding
           mox.OutputMidiMsg( -1, status | soloChan, dat1, dat2 );
           lowestNote = 128;     // reset value to "no lowest note"
           
           return;  // done - get out
           //////
        }
     }
  }

  // If we arrive here, just output the original event  
  mox.OutputMidiMsg( -1, stat, dat1, dat2 );

}      



And here's the full working script:
http://www.midiox.com/moxscript/OrganSolo.js

Caveats: A new lowest note can't be detected unless it is A) lower than the current lowest note, or B) the current lowest note is lifted.  So you can't play it with any 'legato'.




MIDI-OX User Forum » Powered by YaBB 1 Gold - SP 1.3.1!
YaBB © 2000-2003. All Rights Reserved.