MIDI Score Manipulation using SimpleMIDIFile (wslib)

Hello Everyone,
I’m here again :slight_smile:

I thought the best thing to do to write a score and manipulate it, should be to sketch the idea using a software like Finale or Sibelius and manipulate it with different .methods in SC

Honestly for my project to use a stave or similar notation it could be really clear to document everything and to see visually what will happen on the lights/speakers and having 6 lights I could esily use different notes for each of them. eg:(d = firsl light, f = second, a = third … etc)

But …
after doing a few tests I saw that the MIDI file outputted was “strange” with shortcomings, with wrong rewritten parts.

Here I’m going to add vel paramenters and rewrite the parts

First of all I can’t get the correct Velocity.
for instance:

  1. I wrote my 4 bars

  1. I exported from Sibelius in .mid and Imported In Ableton to write the velocity (I saw it’s possible to do it in Sibelius directly…(I’m also learning it)) , then I exported with the velocity.

  1. In Sc I imported the .mid file, extracted the vel paramenters
    noteSustainEvents { |channel, track|  
    		// [track, absTime, \noteOn, channel, note, velo, dur, upVelo]
    			var temp, noteOns, noteOffs;
    			temp = this.copy.convertNoteOns;
    			noteOns = temp.noteOnEvents(channel, track);
    			noteOffs = temp.noteOffEvents(channel, track);
    			^noteOns.collect({ |item|
    				var note, noteOff;
    				note = [ item[0], item[3], item[4] ]; // [track, channel, note]
    				noteOff = noteOffs.detect({ |subitem|
    					[ subitem[0], subitem[3], subitem[4] ] == note });
    				noteOffs.remove( noteOff );
    				if( noteOff.isNil ) { // infinite sustain if no noteOff found
    					noteOff = [ nil, inf, 64 ];
    				};
    				item ++ [ noteOff[1] - item[1], noteOff.last ]; // add sustain and upVelo
    				});
    			}

SimpleMIDIFile reading and writing with Velocity via Pattern

m = SimpleMIDIFile.read("C:/Users/../Desktop/tuplets_Ableton.mid" );

(
x = m.generatePatternSeqs.flatten(1).debug("midifile: ");
~a = (0..x.size);
x.size.do({ |i|
// m.noteSustainEvents(channel:0, track:0).wrapAt(i).wrapAt(5)
	~a.put(i,m.noteSustainEvents(channel:0, track:0).wrapAt(i).wrapAt(5));
});
~a.asArray.postcs;

)


// for now I just avoid to apply any methods...
(
p = Pbind(
	\amp, 127.0/Pseq(~a,1).poll,
	[\midinote, \dur], Pseq(x,inf),
);


m = SimpleMIDIFile( "C:/Users/../Desktop/tuplets_Ableton_out.mid" );
//m.init1( 0, 120, "4/4" );
m.fromPattern( p );
)

m.write; // when writing to file note numbers are rounded (MIDI file format doesn't allow floats)

But If I open the output file in Ableton the velocity is 127 for every note… the bars are 9…

and the score in Sibelius is like that…

Any hint?
Are there settings to keep in mind when working like that?
How to include the correct velocity in the output .mid file?
Why there are 9 bars (8 I could understand… )
etc etc…

Thanks in advance like always.

Not sure about the rest of your questions, but assuming your ~a values happen to be a list of velocities from 0-127, shouldn’t this be Pseq(~a,1)/127, rather than the inverse? Otherwise, you’ll always have amps >= 1, and possibly even infinite amps if velocity is 0, and likely these “over” values are being clamped to full volume (velocity 127) during the MIDI export. Just a thought.

Thanks, for the reply.
My fault the code is not complete… And you are right, I divide the array values in ~a /127 before listening the pseq and writing the midi file.