Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 8 of 8

Thread: quantise midi note data

  1. #1

    quantise midi note data

    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!

  2. #2
    caveat: some of my interval arrays could be up to 12 entries, some might be 5.

  3. #3
    Senior Member
    Join Date
    Jul 2020
    Posts
    1,180
    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.

  4. #4
    Quote Originally Posted by MarkT View Post
    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);

  5. #5
    Senior Member oddson's Avatar
    Join Date
    Feb 2013
    Location
    Isle in the Salish Sea
    Posts
    1,410
    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 by oddson; 07-06-2021 at 03:57 AM.

  6. #6
    Senior Member
    Join Date
    Jul 2020
    Posts
    1,180
    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"?

  7. #7
    Senior Member oddson's Avatar
    Join Date
    Feb 2013
    Location
    Isle in the Salish Sea
    Posts
    1,410
    Quote Originally Posted by MarkT View Post
    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 by oddson; 07-08-2021 at 06:08 AM.

  8. #8
    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,1 20,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

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •