quantise midi note data

Status
Not open for further replies.

snowsh

Well-known member
My midi sequencer project....

I have a function that generates numbers. I need to "quantise" these numbers to the nearest number that fits a desired scale.

example of the array that holds the allowed notes as intervals from a set key:


Code:
uint8_t key = 60;    // 60 = c4

uint8_t intervalArray[7] = {0,2,4,5,7,9,11,12}

my number generator could spit out any number within a defined range. How do I go about mapping these numbers to my interval array. It needs to first off determine what the entire map is raange 24 (c1) to 108 (c8) based on the given root note and interval map, and then adjust up or down the generated number to match to the closest allowed note. Point me in the right direction!
 
Since MIDI notes are semitones and most scales have whole tone intervals this is ambiguous:
do you sharpen a rogue note or flatten it? Only with intervals of 3 semitones or more can "closest
allowed note" have meaning.
 
Since MIDI notes are semitones and most scales have whole tone intervals this is ambiguous:
do you sharpen a rogue note or flatten it? Only with intervals of 3 semitones or more can "closest
allowed note" have meaning.

no, the intervals in the array define the note from the root. its all semitones. I have a full definition of arrays in place and already have it working in other scenarios where my sytem is just calculating sequences based on interval. My issue is not with music theory ;)

I now have a new function working that just makes numbers that I need to tally up or "map" to the intervals, ie note quantise them. The question really is how do I get an integer to map to its nearest integer as defined in the array. eg:

Code:
uint8_t noteToQuantise = 68;

uint8_t quantiseAr[] = {  // this I can generate from the root note and the original interval array. its here just for example
  60,
  62,
  65,
  67,
  69,
  70,
  73,
};

uint8_t quantise(uint8_t note)
{
  // need to map the note, 68 to its nearest in the array, in this case it could be 67 or 69, the direction isnt really too important.
  // this is where I am looking for advice
  return note;
}

quantise(noteToQuantise);
 
how do I get an integer to map to its nearest integer as defined in the array

Get the modulo of the MIDI by 12 and use the result as an offset to map each scale.

Each scale is just a 12 value array saying how to shift to allowed notes from each non-allowed offset from the tonic.

Then restore the octave multiplying by 12 again.


uint8_t intervalArray[7] = {0,2,4,5,7,9,11,12}

becomes

offsetArray[12] = {0,0,2,4,4,5,5,7,7,9,9,11}

This way you can make musical decisions about where to move from a provided offset.

(Edit... I had a bunch of stuff wrong but I've left the core idea here... you can decide where the note goes on all those ties
 
Last edited:
I still don't see what you are trying to do:
how do I get an integer to map to its nearest integer
Is 61 nearer to 60 than to 62? Its fundamentally ambiguous. Perhaps you didn't mean "nearest"?
 
Perhaps you didn't mean "nearest"?

Certainly 'quantizing' doesn't really capture the issue either.

Trying to put together the above reply I noticed how unclear the answer was musically too. It depends on what the 'signal' you are starting with is like I guess.

Mapping seems to me what OP is looking for. It might be he's looking to take the output from quantization (to semitones expressed as MIDI values) and further 'quantize' to scale-tones. I think an offset method lets you achieve this fairly cleanly but if 'round up' is enough you could likely use the 'member-list' scales...
 
Last edited:
yes, its all a bit unclear... lets try to recap and ignore any mention of midi, music or quantise.....

I think odsons answer #5 has it, but I was wondering if there is another approach.

I have a number, it could be anything from 0 to 127. doesnt matter.

I have a list of acceptable numbers,

0,3,6,7,8,10,14,17,22,45,65,70,71,75,78,79,80,99,120,126 - again its really not important to worry about what these numbers are. But these lists are defined based on the example of intervals above, I will come back to that in a moment.

I need a function to send an integer (uin8_t) to, and that function only returns a number that is present in the acceptable list, it finds the number closest. it could be the lowest close match, or highest close match. I will probably radomise that anyway.

at its most basic based on the list above:

Code:
getClosestMatch(20)
{
   return 22;
}


intervals to the list:

uint8_t intervalArray[7] = {0,2,4,5,7,9,11,12}

root note (c4) happens to be 60.

so:

to min 0<<<<----60,62,64,65,67,71,72--->>>>>> to max 127
 
Status
Not open for further replies.
Back
Top