Topic: Record notes to different MIDI channels

Hello,
I would like to record a piano piece and then use a program to generate sheet music. However, when I record the MIDI, everything is written to one MIDI channel. Is it possible to write the notes to a different MIDI channel above a certain pitch?

Many thanks in advance,
Max

Re: Record notes to different MIDI channels

Max8 wrote:

Hello,
I would like to record a piano piece and then use a program to generate sheet music. However, when I record the MIDI, everything is written to one MIDI channel. Is it possible to write the notes to a different MIDI channel above a certain pitch?

Many thanks in advance,
Max

Pianoteq's MIDI recording functionality is a convenient feature, but not a substitute for a more comprehensive MIDI recording environment and tool set. For what you are asking, a DAW and some MIDI filter or transformer capabilities, either included within the DAW or as a plugin or as a standalone MIDI management-and-manipulation app would probably be a better choice. I find the Bome MIDI Translator Pro app very capable and versatile--

Bome MIDI Translator Pro
https://www.bome.com/products/miditranslator

--
Linux, Mac OS, Pianoteq Pro, Organteq

Re: Record notes to different MIDI channels

Max8 wrote:

Is it possible to write the notes to a different MIDI channel above a certain pitch?

Any DAW (digital audio workstation) permits copy and paste on a piano roll and from one channel to another.

MODARTT itself promotes GIG PERFORMER.  Its promotional offer is a 10% price reduction whether you buy GIG PERFORMER PRO or GIG PERFORMER ESSENTIALS.  Either permits MIDI channel routing as you play. 

If you want to get the 10% discount you'll need to access gigperformer.com, firstly, from the User area and a click onto the 'Proceed to website' button, or simply use this link.  Please be sure to specify whether you'll want to purchase GIG PERFORMER PRO or GIG PERFORMER ESSENTIALS.

People on macOS have MidiPipe that they can use.  It's shareware.

Additionally, you may want to check into your keyboard if it permits any channel routing.

Lastly, look over some of the MIDI boxes, hardware interfaces like CME H2MIDI Pro.

Last edited by Amen Ptah Ra (14-12-2025 01:53)
Pianoteq 8 Studio Bundle, Pearl malletSTATION EM1, Roland (DRUM SOUND MODULE TD-30, HandSonic 10, AX-1), Akai EWI USB, Yamaha DIGITAL PIANO P-95, M-Audio STUDIOPHILE BX5, Focusrite Saffire PRO 24 DSP.

Re: Record notes to different MIDI channels

Max8 wrote:

Hello,
I would like to record a piano piece and then use a program to generate sheet music. However, when I record the MIDI, everything is written to one MIDI channel. Is it possible to write the notes to a different MIDI channel above a certain pitch?

Many thanks in advance,
Max

There might be a more effective direction from which to approach this. For example, when I import piano MIDI into Dorico, it’s a single MIDI channel; Dorico has the option, on import, either to split staves at a certain pitch or to “guess” where the split should be. (I think the free version can do that, but I’ve been on Pro for quite a while, so I don’t always remember what’s in free and what isn’t.) So I think it would be the program producing the notation that’s best able to separate the piece onto staves, rather than trying to do it in the MIDI.

That said, Dorico isn’t that good at translating the result to readable sheet music. It gets all the notes, and the pedal ups and downs, but it is too literal about it. It doesn’t know how to notate the sense of the piece.

If you find a program that can do that, I’d love to hear about it. As it is, I usually find it’s less time consuming to go through measure by measure, playing what I play and then noting that into Dorico, than to try to turn its overly precise translation of MIDI into proper notation.

Last edited by Coises (13-12-2025 23:04)

Re: Record notes to different MIDI channels

Max8 wrote:

Hello,
I would like to record a piano piece and then use a program to generate sheet music. However, when I record the MIDI, everything is written to one MIDI channel. Is it possible to write the notes to a different MIDI channel above a certain pitch?

Many thanks in advance,
Max

Easy way is to use a DAW that runs on your operating system and that supports scripting such as Reaper  ( Windows, Mac OS, Linux)  or Logic Pro ( Mac OS)   
Then ask Gemini or ChatGPT or DeepSeek to write your script.

For instance here is a  script in Reaper that does what you want :
Create a new action in Reaper (ReaScript)   and use Python as the language
Copy paste the following code ( here generated by Gemini ) in the action
In this case the cut off pitch is C4 , and notes below will be written to channel 1, and notes above to channel 2
Load or Record your midi file  in a track , and run the action. That's it.

In this example you transform the code after recording and perform the loop on midi events.
You could also write a script that works in realtime , intercept the note-on events and depending on the note on pick value assign a midi channel.



============================================

# SCRIPT: Split MIDI Notes by Pitch and Assign Channels
# LANGUAGE: Python
# AUTHOR: Gemini (Adapted from Python pretty_midi logic)

from reaper_python import *
import struct

# --- CONFIGURATION ---
# MIDI Note Number (0-127). 60 = Middle C (C4).
PITCH_CUTOFF = 60

# MIDI Channel assignments (1-16)
LOW_NOTES_CHANNEL = 1
HIGH_NOTES_CHANNEL = 2
# Note: MIDI channel is 0-indexed in the MIDI message (0-15).
# So Channel 1 is 0x00, Channel 2 is 0x01, etc.
LOW_CHANNEL_BYTE = (LOW_NOTES_CHANNEL - 1)
HIGH_CHANNEL_BYTE = (HIGH_NOTES_CHANNEL - 1)
# ---------------------

def main():
    # 1. Check for selected MIDI item
    item = RPR_GetSelectedMediaItem(0, 0) # Get the first selected item
    if not item:
        RPR_ShowConsoleMsg("Error: Select a MIDI item first.\n")
        return

    take = RPR_GetActiveTake(item)
    if not take:
        RPR_ShowConsoleMsg("Error: Selected item has no active take.\n")
        return

    # 2. Open MIDI item for editing (required for modification)
    RPR_MIDI_SetItemTakeChannelMap(take, -1, 0) # Clear channel map to avoid conflicts
    RPR_MIDI_SetItemTakeChannelMap(take, -1, 0)
    RPR_MIDI_SetItemTakeChannelMap(take, -1, 0)

    RPR_MIDI_SetItemTakeChannelMap(take, 0, 0)
    RPR_MIDI_SetItemTakeChannelMap(take, 1, 1)

    # RPR_MIDI_SetItemTakeChannelMap(take, LOW_CHANNEL_BYTE, 0) # Assign Channel 1
    # RPR_MIDI_SetItemTakeChannelMap(take, HIGH_CHANNEL_BYTE, 1) # Assign Channel 2

    RPR_Undo_BeginBlock2(0) # Start Undo Block

    # 3. Iterate through all MIDI events
    # index: 0 is the starting index.
    # We use a loop and increment the index until RPR_MIDI_EnumItemInTake only returns 0
   
    # event_idx: the index of the event
    # is_selected: whether the event is selected
    # is_muted: whether the event is muted
    # ppq_pos: position in PPQ (Pulses Per Quarter note)
    # message: the raw MIDI message bytes
   
    event_idx = 0
    while True:
        (ret, take, event_idx, is_selected, is_muted, ppq_pos, message) = RPR_MIDI_GetEvt(take, event_idx)
       
        if ret == 0:
            # End of events list
            break

        # Check if the message is a Note-On event (Status byte 0x90 to 0x9F)
        # Note-On message status byte: 0x90 + channel (0-15)
        # We only care about the first byte's high nibble (0x9_)
        status = message[0] & 0xF0
       
        # Check if it's a Note-On event (0x90) and not a Note-Off with velocity 0
        if status == 0x90 and len(message) >= 3 and message[2] > 0:
           
            # Message is: [Status+Channel, Note/Pitch, Velocity]
            pitch = message[1]

            if pitch < PITCH_CUTOFF:
                # Assign to LOW_NOTES_CHANNEL
                new_status = 0x90 | LOW_CHANNEL_BYTE
            else:
                # Assign to HIGH_NOTES_CHANNEL
                new_status = 0x90 | HIGH_CHANNEL_BYTE
               
            # Create the new message with the modified channel
            new_message = struct.pack('BBB', new_status, message[1], message[2])
           
            # Update the event in the MIDI item
            RPR_MIDI_SetEvt(take, event_idx, is_selected, is_muted, ppq_pos, new_message)

        # Increment index to get the next event
        event_idx += 1

    # 4. Update and close the MIDI item
    RPR_MIDI_Sort(take)
    RPR_UpdateItemInProject(item)
    RPR_Undo_EndBlock2(0, "Split MIDI Notes by Pitch and Channel", -1)
   
    RPR_ShowConsoleMsg(f"\n✅ Successfully split notes in the selected item!")
    RPR_ShowConsoleMsg(f"   - Cutoff Pitch: {PITCH_CUTOFF}")
    RPR_ShowConsoleMsg(f"   - Notes < Cutoff assigned to MIDI Channel {LOW_NOTES_CHANNEL}")
    RPR_ShowConsoleMsg(f"   - Notes >= Cutoff assigned to MIDI Channel {HIGH_NOTES_CHANNEL}")

main()

Last edited by Pianistically (14-12-2025 00:53)