You are here

force all midi notes into a single octave?

For anything relating to music-making on Windows computers, with lots of FAQs. Moderated by Martin Walker.

force all midi notes into a single octave?

Postby bluemoves » Sat Sep 22, 2018 1:12 pm

I'm looking for a tool / program / plugin that will look at a source midi file and render all of the various pitches into a single octave..

eg. let's say my chosen octave is C3-B3, if there's an F5 (or any other F) in the music I want it displayed as an F3 - and so on for all the other pitches.

So basically, all notes grouped by pitch 'class' in a single octave.

No other changes to the layout are necessary - ie. the rhythm stays the same etc.

It's for some harmonic analysis I'm doing

Anyone know a tool that will do this?

It would be great if it's a DAW plugin for Cubase as that's what I mostly use.

I'm on PC.

Thanks :)
bluemoves
Posts: 1
Joined: Sat Sep 22, 2018 1:11 pm

Re: force all midi notes into a single octave?

Postby Kwackman » Sat Sep 22, 2018 1:48 pm

I'll bet that sort of thing is possible in the Logical Editor in Cubase.
User avatar
Kwackman
Frequent Poster
Posts: 1182
Joined: Thu Nov 07, 2002 1:00 am
Location: Belfast
Cubase, guitars.

Re: force all midi notes into a single octave?

Postby Martin Walker » Sat Sep 22, 2018 3:33 pm

...although in my experience it's often quicker to do things by hand than think your way all the way through the logical editor experience ;)

If it's a really long part then probably worth the effort of setting it up though :thumbup:


Martin
User avatar
Martin Walker
Moderator
Posts: 12824
Joined: Wed Jan 13, 2010 9:44 am
Location: Cornwall, UK

Re: force all midi notes into a single octave?

Postby BJG145 » Sat Sep 22, 2018 10:12 pm

That's a pretty weird thing to do; I doubt you'll find it off the peg. You'd have to do it manually or code it yourself in some MIDI-mangler like Max or Bome (or Cubase or whatever).
User avatar
BJG145
Frequent Poster (Level2)
Posts: 3450
Joined: Sat Aug 06, 2005 12:00 am

Re: force all midi notes into a single octave?

Postby Dynamic Mike » Mon Sep 24, 2018 12:30 am

Could you split the keyboard into octaves, load the same VSTi into each slot & then set each instance to -2, -1, 0, +1, +2... from your chosen octave? No idea if it's what you're after, just thinking out loud really.
Dynamic Mike
Frequent Poster (Level2)
Posts: 2854
Joined: Sun Dec 31, 2006 1:00 am

#indyref/bestof3


Re: force all midi notes into a single octave?

Postby Jumpeyspyder » Mon Sep 24, 2018 1:14 am

Is there an arpegiator in cubase where you can limit the octave range ?

If so, can you feed it through and limit it to just one octave ?

I guess it would mangle the rhythms - but might be worth the trade off ?
User avatar
Jumpeyspyder
Frequent Poster
Posts: 1002
Joined: Fri Jan 20, 2006 1:00 am
Location: Yorkshire

Re: force all midi notes into a single octave?

Postby Matt Houghton » Mon Sep 24, 2018 9:38 am

I've note tried it, but I'm fairly certain you could use Cubase's Transformer MIDI plug-in for this.

Create a new MIDI track and set it to receive from the original MIDI part — you'll need a virtual MIDI cable for this, such as the Mac's built-in IAC system... you may have to download something else for Windows if you haven't already.

Insert this MIDI plug-in on the new track and set the parameters so that in the upper section it first identifies notes, then defines the desired note range. Then in the bottom section, get it to add 12 (ie an octave) to any notes outside the range. Set the plug-in to 'Record Output To Track' (a button on the insert slot, not in the plug-in itself).

Add more than one instance of this plug-in, to do multiple passes of adding/subtracting octaves until everything was in range. (Set the last plug-in to record its output to the track.

Record-arm the new MIDI track and hit record.

I haven't time to check this out now, but give it a try and let us know if it works!
Matt Houghton
Frequent Poster
Posts: 920
Joined: Wed Aug 08, 2007 12:00 am
SOS Reviews Editor

Re: force all midi notes into a single octave?

Postby OneWorld » Thu Sep 27, 2018 2:19 pm

Martin Walker wrote:...although in my experience it's often quicker to do things by hand than think your way all the way through the logical editor experience ;)

If it's a really long part then probably worth the effort of setting it up though :thumbup:


Martin

Martin Walker wrote:...although in my experience it's often quicker to do things by hand than think your way all the way through the logical editor experience ;)

If it's a really long part then probably worth the effort of setting it up though :thumbup:


Martin

My first thought was Logical Editor but if for example all the notes were to be in the range C2-B2 and some of the notes were just a semitone away and others were a 7th away, both above and below C2-B7 how could Logical Editor deal with that because it has to do sort of......

IF <note> GREATER THAN B7 THEN NOTE=NOTE-X where X is the number semitones to be moved. But if the notes appear in an arbitary pattern then we won't know what X has to be? That's if the notes to be moved are more than an octave away

Given that the Logical Editor does allow the AND/OR options and allows adding a set of rules, the it could be done, but a rule would have to be written for each note in the sort of rule

We have the accepted range C2-B2, so....

IF <<note>> EQUAL C3 THEN <<note>> =<<note>> -12
IF <<note>> EQUAL #C3 THEN <<note>> =<<note>> -12
.
.
.
.
IF <<note>> EQUAL C4 THEN <<note>> =<<note>> -24

etc

And of course similar rules for those notes below the range C2-B2

That's about the only way I can see of doing it in one pass. He could of course write a rule saying....

IF <<note>> GREATER THAN B2 THEN <<note>> = <<note>> - 12

and so on doing rules for those notes 2 octaves away, but these cannot be done in one pass of course.

And I suppose the exercise depends to some extent of the complexity of the music itself, if it's EDM etc then not so hard, but if it's Coltrane/Debussy/Stravinsky et al then the poster has his work cut out!
OneWorld
Frequent Poster (Level2)
Posts: 2360
Joined: Tue Apr 07, 2009 12:00 am

Re: force all midi notes into a single octave?

Postby Matt Houghton » Thu Sep 27, 2018 4:01 pm

You could do anything you want in what appears to the user as one pass by creating a Macro that executes multiple PLE presets -- repeating the same steps as often as necessary.
Matt Houghton
Frequent Poster
Posts: 920
Joined: Wed Aug 08, 2007 12:00 am
SOS Reviews Editor

Re: force all midi notes into a single octave?

Postby Temp » Fri Sep 28, 2018 9:02 pm

Here's a simple function in PHP (you could easily port it to JavaScript or Python). I've just spent a few hours attempting to build this in SynthEdit so you could use it as a VST, but my SE kung-fu isn't so good and my brain started to melt.

Code: Select all
$midi_note_num = 29 // Input MIDI note number (29=F1)
$min = 48; // Start of range MIDI note number (C3 = 48)
$max = 59; // End of range MIDI note number (B3 = 59)
$noteshift = 12; // Semitones to shift by - default is 12 (i.e. an octave)

while ($midi_note_num < $min || $midi_note_num > $max){
   $midi_note_num += ($midi_note_num < $min) ? $noteshift : -$noteshift;
}

echo $midi_note_num; // Should output 53 (F3)


Or as a recursive function:

Code: Select all
echo forceRange(29,48,59,12);

function forceRange($midi_note_num,$min,$max,$noteshift=12){
   if ($midi_note_num < $min){
      $midi_note_num += $noteshift;
      return forceRange($midi_note_num,$min,$max,$noteshift);
   } else if ($midi_note_num > $max){
      $midi_note_num -= $noteshift;
      return forceRange($midi_note_num,$min,$max,$noteshift);
   } else {
      return $midi_note_num;
   }
}


In conjuction with something like PHP MIDI (http://valentin.dasdeck.com/midi/), you could probably get this up and running relatively quickly.

Cheers.
User avatar
Temp
Regular
Posts: 169
Joined: Mon Apr 25, 2005 12:00 am
Location: Medway, UK

Re: force all midi notes into a single octave?

Postby OneWorld » Sat Sep 29, 2018 11:59 am

Temp wrote:Here's a simple function in PHP (you could easily port it to JavaScript or Python). I've just spent a few hours attempting to build this in SynthEdit so you could use it as a VST, but my SE kung-fu isn't so good and my brain started to melt.

Code: Select all
$midi_note_num = 29 // Input MIDI note number (29=F1)
$min = 48; // Start of range MIDI note number (C3 = 48)
$max = 59; // End of range MIDI note number (B3 = 59)
$noteshift = 12; // Semitones to shift by - default is 12 (i.e. an octave)

while ($midi_note_num < $min || $midi_note_num > $max){
   $midi_note_num += ($midi_note_num < $min) ? $noteshift : -$noteshift;
}

echo $midi_note_num; // Should output 53 (F3)


Or as a recursive function:

Code: Select all
echo forceRange(29,48,59,12);

function forceRange($midi_note_num,$min,$max,$noteshift=12){
   if ($midi_note_num < $min){
      $midi_note_num += $noteshift;
      return forceRange($midi_note_num,$min,$max,$noteshift);
   } else if ($midi_note_num > $max){
      $midi_note_num -= $noteshift;
      return forceRange($midi_note_num,$min,$max,$noteshift);
   } else {
      return $midi_note_num;
   }
}


In conjuction with something like PHP MIDI (http://valentin.dasdeck.com/midi/), you could probably get this up and running relatively quickly.

Cheers.

But how would this deal with notes more than 1 octave away, in either direction, as $noteshift=12, surely you would need to recurse deeper to allow for notes more than one octave away from $min=C3 $max=B3?

An interesting little conundrum and a coder's instinct is to do things in one pass but I cannot see how, unless there was a group of ORs at the input - representing the different ranges above and below C3-B3?

Just out of interest could you step me though it?
OneWorld
Frequent Poster (Level2)
Posts: 2360
Joined: Tue Apr 07, 2009 12:00 am

Re: force all midi notes into a single octave?

Postby Temp » Sat Sep 29, 2018 3:01 pm

But how would this deal with notes more than 1 octave away, in either direction, as $noteshift=12, surely you would need to recurse deeper to allow for notes more than one octave away from $min=C3 $max=B3?

Both approaches above should handle notes that are more than one octave away. The while loop iterates until the note is within range, and the recursive function calls itself until the same is achieved (i.e. the noteshift value is added/subracted every time the loop is run). In this sense, it's not strictly a single pass. I've stuck up a JavaScript version of the while() loop method so you can take a look at it in action.

http://promixing.com/midi-restrict/

This could be applied to a set (array) of midinotes, so you could run through a whole MIDI track and spit it back out the other end (let me know if this would be of any help and I'll stick up a version for that).

Cheers.
User avatar
Temp
Regular
Posts: 169
Joined: Mon Apr 25, 2005 12:00 am
Location: Medway, UK

Re: force all midi notes into a single octave?

Postby Temp » Sat Sep 29, 2018 9:47 pm

I've now updated this so you can upload a *.mid file, perform the range restriction, and download the result.

http://promixing.com/midi-restrict/

Cheers.
User avatar
Temp
Regular
Posts: 169
Joined: Mon Apr 25, 2005 12:00 am
Location: Medway, UK

Re: force all midi notes into a single octave?

Postby OneWorld » Sun Sep 30, 2018 12:51 pm

Temp wrote:
But how would this deal with notes more than 1 octave away, in either direction, as $noteshift=12, surely you would need to recurse deeper to allow for notes more than one octave away from $min=C3 $max=B3?

Both approaches above should handle notes that are more than one octave away. The while loop iterates until the note is within range, and the recursive function calls itself until the same is achieved (i.e. the noteshift value is added/subracted every time the loop is run). In this sense, it's not strictly a single pass. I've stuck up a JavaScript version of the while() loop method so you can take a look at it in action.

http://promixing.com/midi-restrict/

This could be applied to a set (array) of midinotes, so you could run through a whole MIDI track and spit it back out the other end (let me know if this would be of any help and I'll stick up a version for that).

Cheers.

Yep, right, that's what I thought and really should have realised, in truth hardly anything is done in one pass. Way back when I used to do coding to get computers to process unseen seen natural text, in theory process any utterance and get the computer to understand - the forerunner to things like predictive text and Cortana etc Back in the day the endeavours, after flurries of activity, didn't come to much, the processing and storage was so expensive back then I remember the department put out a tender to buy a 20gig SCSI drive and the lowest quote we got was £1800!!!!!! How things have changed.

But yes, a phrase would of course include a word or words (except the epsilon of course) and the code would recurse through the phrase, identifying each single word and deciding if it were determiner, noun, verb, adjective etc, consulting the grammar rules, then establish the phrase was a legitimate sentence. We used LISP (the daddy of all recursion) and Prolog

The C++'ers in the computer science department said it would all come to nothing, we knew they were wrong though!
OneWorld
Frequent Poster (Level2)
Posts: 2360
Joined: Tue Apr 07, 2009 12:00 am

Re: force all midi notes into a single octave?

Postby Temp » Mon Oct 01, 2018 2:03 pm

This has got my little brain working and I think I might've cracked it with a single pass (i.e. without recursion). The input/min/max must be valid MIDI note numbers between 21 and 108, and shift must be >= 1 and <= 12 (the input value can be as far away from the range as you like):

Code: Select all
$input = 29;
$min = 48;
$max = 59;
$shift = 12;

// If input is less than range minimum
if ($input < $min){
   // If difference is a multiple of shift already (i.e. modulo == 0)
   if (($min-$input) % $shift == 0){
      $output = $input + ($min - $input);
   // If range minimum is less than an octave away, shift it
   } else if (($min - $input) < $shift){
      $output = $input + $shift;
   } else {
   // Else use required multiple of shift
      $output = $input + (round((($min - $input) + $shift/2)/$shift)*$shift);
   }
// Else if input is more than range maximum
} else if ($input > $max){
   // If difference is a multiple of shift already (i.e. modulo == 0)
   if (($input-$max) % $shift == 0){
      $output = $input - ($input - $max);
   // If range maximum is less than an octave away, shift it
   } else if (($input - $max) < $shift){
      $output = $input - $shift;
   } else {
   // Else use required multiple of shift
      $output = $input - (round((($input - $max) + $shift/2)/$shift)*$shift);
   }
// Else input is already within range, just pass it through
} else {
   $output = $input;
}

echo $output;

Lemme know what you think - I've tried it with some test cases but I may well have missed something.
User avatar
Temp
Regular
Posts: 169
Joined: Mon Apr 25, 2005 12:00 am
Location: Medway, UK


Who is online

Users browsing this forum: No registered users