Keyboard mapping script

Dear Marc

I copied pasted your script lines.

pitch_to_instrument_and_pitches = {

    "1-60": [piano, [40, 48, 56, 64, 72]],

    "61-127": [flute, [70, 71, 72, 73, 74]]

}

I receive in Shell:

*Traceback (most recent call last):*
*File "/Users/PaulTimmermans/Desktop/Midinotes> chords. try new.py", line 33*
*}*
*^*
_**SyntaxError: invalid syntax**_

Strange

Thanks in advance to follow up.

Paul

Hello Marc

I cannot proceed my project about Scamp script.

Can you found the solution for the synthaxerror in my script

pitch_to_instrument_and_pitches = {

    "1-60": [piano, [40, 48, 56, 64, 72]],

    "61-127": [flute, [70, 71, 72, 73, 74]]

}

Many thanks in advance for your expert input.

Paul

There isn’t an issue with those lines, so probably it’s an issue somewhere else in the script that just seems to be in those lines.

Again, just want to check that I’m understanding correctly that you want to be using two different keyboards, “SX900” and “Roland Go: Keys”? What prints when you run

from scamp import *
print_available_midi_input_devices()

with each of them plugged in?

HELLO MARC

I WISH YOU A HEALTHY AND CORONA-FREE NEW YEAR FOR YOU AND YOUR LOVELY FAMILY.
I WISH YOU UNEXPECTED ARTISTIC SUCCESSES IN 2021.

IN ATTACHMENT I SEND YOU THE SHELL AND ASSISTANT NOTES (.DOC FILE) WHILE RUNNING THE THONNY FILE CONNECTED TO GO:KEYS.
I HOPE YOU NOW CAN CLEAR UP THE CONFLICT ERRORS.

I STILL DON’T HEAR FROM MY MIDI KEYBOARD WHILE RUNNING THE ATTACHED THONNY FILE. IT IS INDEED DIFFICULT THAT I CAN’T CONTINUE AND THAT I HAVE TO FALL YOU EVERYWHERE BECAUSE THE SCRIPT STILL NOT WORK.
WHAT I SEND TO YOU NOW, I CAN’T MORE.

I HOPE YOU CAN REALLY HELP ME THIS TIME SOON.
THANK YOU IN ADVANCE FOR YOUR VERY NEEDED HELP TO GET THONNY UNDER CONTROL.

BEST

PAUL

(Attachment Midinotes> chords 26 Dec 2020 Go-keys.py is missing)

(Attachment SHELL + ASSISTANT RUNNING THONNY CONNECTED TO GO-KEYS…docx is missing)

The THONNY file I 'M trying to upload is not authorized AND IS REJECTED TO SEND .
SO I COPY THE SCRIPT BELOW:

“”"
A script written at the request of Paul Timmermans, in which different pitches or ranges of pitches
on the keyboard can be mapped to particular instruments and chords. The heart of the script is the
dictionary pitch_to_instrument_and_pitches, which expresses, for each key, which pitches and on
which instrument should be played.
“”"
from scamp import *
s = Session()

This is where you define all of the instrument that you want to play back notes with.

The note_on_and_off_only=True flag is helpful in keeping the midi messages simple if

your not doing any pitch bending, glissandi, microtonal stuff, or dynamic envelopes.

The new_midi_part call will open an outgoing midi stream, in this case to IAC, which

is a virtual midi cable that can be used (on macs) to route playback between applications

piano = s.new_midi_part(“GO:keys”,“Go:keys”, note_on_and_off_only=True)

The new_part calls create parts that play back using the default soundfont

flute = s.new_part(“flute”, note_on_and_off_only=True)
clarinet = s.new_part(“clarinet”, note_on_and_off_only=True)

This is where the magic happens! Each entry in this dictionary determines what happens

when you play a pitch in a certain key or range of keys.

pitch_to_instrument_and_pitches = {
“1-60”: [piano, [40, 48, 56, 64, 72]],
“61-127”: [flute, [70, 71, 72, 73, 74]]
}

Put here the name of the device MIDI messages are coming in from

from scamp import *
print_available_midi_input_devices()
print_available_midi_output_devices()

the input and output device can be the same or different

for instance, you might want to take midi in from the keyboard,

but send any note playback messages to a softsynth like pianoteq

MIDI_INPUT_DEVICE = “Go:keys”
MIDI_OUTPUT_DEVICE = “Go:keys”

# Uncomment these lines if you want to see which midi input and output devices are available

print_available_midi_input_devices()

print_available_midi_output_devices()

--------------------------------------------- IMPLEMENTATION -----------------------------------------------

----- process pitch_to_instrument_and_pitches -----

processed_pitch_to_instrument_and_pitches = {}
for key, value in pitch_to_instrument_and_pitches.items():
if isinstance(key, str) and “-” in key:
start_pitch, end_pitch = key.split("-")
for p in range(int(start_pitch), int(end_pitch) + 1):
processed_pitch_to_instrument_and_pitches[p] = value
for key, value in pitch_to_instrument_and_pitches.items():
if not isinstance(key, str):
processed_pitch_to_instrument_and_pitches[key] = value

for key, value in processed_pitch_to_instrument_and_pitches.items():
instrument, pitches = value
if isinstance(pitches, str) and key != “default”:
processed_pitch_to_instrument_and_pitches[key] = [instrument, eval(pitches, {}, {“p”: key})]
processed_pitch_to_instrument_and_pitches[“default”] = pitch_to_instrument_and_pitches[“default”]
notes_down = [[] for _ in range(128)]
pedal_held_notes = [[] for _ in range(128)]
pedal_down = False

def midi_callback(midi_message):
global notes_down, pedal_held_notes, pedal_down

function that handles any incoming midi messages from the keyboard

print(midi_message)
code, pitch, volume = midi_message
if volume > 0 and code == 144:

note on message causes us to fork a new moonlight sonata gesture at the given pitch and volume

if pitch in processed_pitch_to_instrument_and_pitches:
instrument, pitches = processed_pitch_to_instrument_and_pitches[pitch]
else:
instrument, pitches = processed_pitch_to_instrument_and_pitches[“default”]
if isinstance(pitches, str):
pitches = eval(pitches, {}, {“p”: pitch})
if hasattr(pitches, ‘len’):
notes_down[pitch].append(instrument.start_chord(pitches, volume / 127))
else:
notes_down[pitch].append(instrument.start_note(pitches, volume / 127))
elif volume == 0 and code == 144 or code == 143 or code == 128:

note off message (or note on message with 0 velocity, which is sometimes how it’s implemented)

we use it to kill the gesture running for the note at the given pitch

if pedal_down:
pedal_held_notes[pitch].extend(notes_down[pitch])
notes_down[pitch].clear()
else:
for note in notes_down[pitch]:
note.end()
notes_down[pitch].clear()
elif code == 176 and pitch == 64:

pedal change messages just get passed straight along to the MIDI_OUTPUT_DEVICE

(with some warping of the values)

pedal_down = volume > 0
if volume == 0:
for pitch_notes in pedal_held_notes:
for note in pitch_notes:
note.end()
pitch_notes.clear()

s.register_midi_listener(“Go:keys”, midi_callback)
s.wait_forever()

Dear Marc

MIDI Input Devices Available:
[Port 0]: GO:KEYS
[Port 1]: IAC Driver Bus 1
[Port 2]: IAC Driver IAC-bus 2
MIDI Output Devices Available:
[Port 0]: GO:KEYS
[Port 1]: IAC Driver Bus 1
[Port 2]: IAC Driver IAC-bus 2

Python 3.7.6 (bundled)

%cd /Users/PaulTimmermans/Desktop
%Run ‘januari 2021.py’
Traceback (most recent call last):
File “/Users/PaulTimmermans/Desktop/januari 2021.py”, line 1
----- process pitch_to_instrument_and_pitches -----
^
SyntaxError: invalid syntax

Trying to run your last appreciate proposals in a file .py I cannot run the script (nothing works) because I receive from the first line a syntax error. It would be great if you integrate my script in your Moonlight example.py because this script I can use playing on my GO:KEYS keyboard succesfully. Maybe this would the last possibility to get going. Thanks in advance. Paul

Try running the attached script exactly as-is. What happens?

keyboard_map.py (6.5 KB)

Thank you so much, Marc, for the fast feedback. It finally works!
Some details.
Three numbers appear on the shell, e.g. on C1 piano 144, 36, 64 next 128, 36, 64 (cancel the note), G1 trumpet (!) 144, 43, 45 followed by 128,43,64, on G2 144,55,21 next 128, 55, 64 Each key produces GO: KEYS piano sound plus different piano pitch (in py) So would that attached piano sound sound an octave higher or are there each time different distances between scripted notes?
C1-C3 piano sound except G1 = trumpet
D3 -C4 organ sound
C4- - C6 piano sound
I understand that the tone played is linked to a different pitch, either from the same sound, or piano + different sound.

Nice start to continue in the script in the direction of chords of 3 or more notes per key pressed.
So teach me with minimum 1 example integrated in your updated script how I program a cluster per key. Let’s start with two different soundpatches spread across the GO: KEYS keyboard for example piano on C1-B2 and flute sound on C3-C6.
Is it feasible that the played key of GO: KEYS does not sound and therefore only f.e. the 3-note chord that is generated in the script for the played key?

At a later stage I dream to incorporate nuances (eg / dynamics) in the script , and in a final phase I want to determine microtonally different distances between the three or 5 notes of the pressed keys.
In any case, we finally are on the route for a nice experience. Thanks in advance for your reply.
Paul

Additional to my earlier message: I like also to receive the script (integrated in your programming) to play the chords two options: as chord and in arpeggio with tempo variation, staccato, legato.
I’m in the flow, Marc. Can you assist me quickly? Many thanks in advance.

Paul

Hi Paul,

Glad to hear that the script works now.

At this point, however, I cannot put more time into it. The truth is, given all of the variations you would like to implement, you really need to learn Python, or enlist the help of someone else who knows Python well.

As far as learning Python is concerned, I think this video series is an excellent resource:

And, in terms of learning SCAMP more specifically, you can look at the tutorial videos I have created:

I can answer the occasional question along the way, but I can’t spend the time to develop the script myself. I do think if you find a good Python programmer to help you, they would be able to start with the script I have provided and modify it to fit your needs.

Of course, dear Marc, I am happy that you started me with a basic script. Thanks for the time and efforts.
I was certainly not supposed to use you to work out the entire script as I envision it. From a pragmatic point of view, of course, I am looking forward to a professional who can handle programming language such as Pyton smoothly. I thought of you in the first place because you could easily build in "micro"types of script in terms of: 1 example of a chord. And if possible, have the 3-4-5 notes of the chord played as an arpeggio.
And only at last would I think about making those arpeggio chords or full chords more flexible (dynamic, tempo, staccato, legato, random notes). To have the ultimate dream: to build a microtonal scale so that the traditional distance between the keys would be micrononized or maximized. Only ONE type of example each time.
I have made a small donation before. I was wondering if you would be willing to put me on the right track for $ 30. If not, I will turn to Clarence Barlow who will undoubtedly want to help me or bring someone who wants to do this kind of musical programming.

Kind regards

Paul

Dear Marc

Have you still thought about my proposal for limited further assistance?

Paul

Hi Paul,

What you’re asking would still involve a fair time commitment, which I can’t commit to myself. And I’m not sure that Clarence really has the Python background to be able to help in this instance. That said, I’ll reach out to a friend or two and see if they are interested in helping. However, you will almost certainly need to offer them more than $30. It’s an interesting project, but would take at least a few hours to build the script you are envisioning.

Best,

Marc