SimpleMidiFile: playing a midi file with various instruments

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

SimpleMidiFile: playing a midi file with various instruments

prko
This post was updated on .
Hi,


As far as I know, SimpleMidiFile can play a MIDI file and it allows to
specify an instrument.

        m = SimpleMIDIFile.read( "~/Desktop/toccata1.mid" );
       
        m.p.play;
       
        (
        SynthDef( "organ", { |freq = 440, sustain = 1, amp = 0.1|
        var sig;
        sig = LFPar.ar( freq * [1,2,3,5], 0, amp/[2,4,5,7] );
        Out.ar( 0, Env([0,1,1,0], [0.025,sustain,0.025]).kr(2) * sig.dup )
        }).add;
        );

        x = m.p( \organ ).play;
        x.stop;

I am wondering if the following is possible:

Case 1: playing a multichannel midi file in format 0 with various
instruments.
Case 2: playing a multitrack midi file in format 1 with various instruments.

e.g. for case 1:
- A MIDI file has one track with two channels.
- I have two SynthDef: \synth1 and \synth2
- The second channel is played with \synth2 while the first channel is
played with \synth1.

e.g. for case 2:
- A MIDI file has two tracks.
- I have two SynthDef: \synth1 and \synth2
- The second track is played with \synth2 while the first track is played
with \synth1.

I could not find such an example in <
http://quark.sccode.org/wslib/wslib-help/SimpleMIDIFile.html > and I am not
sure if I can configure this from the given examples in the help file.


best,
prko
Reply | Threaded
Open this post in threaded view
|

Re: SimpleMidiFile: playing a midi file with various instruments

prko
Hi,

I have found the following thread:

However, I could not find a solution.
Should I modify SIMPLEMIDIFILE class or write a class?


On 8 February 2018 at 09:24, PyoungRyang Ko <[hidden email]> wrote:
Hi,


As far as I know, SimpleMidiFile can play a MIDI file and it allows to specify an instrument.

m = SimpleMIDIFile.read( "~/Desktop/toccata1.mid" );


m.p.play; 


(

SynthDef( "organ", { |freq = 440, sustain = 1, amp = 0.1|

var sig;

sig = LFPar.ar( freq * [1,2,3,5], 0, amp/[2,4,5,7] );

Out.ar( 0, Env([0,1,1,0], [0.025,sustain,0.025]).kr(2) * sig.dup )

}).add;

);


x = m.p( \organ ).play;

x.stop;


I am wondering if the following is possible:

Case 1: playing a multichannel midi file in format 0 with various instruments.
Case 2: playing a multitrack midi file in format 1 with various instruments.

e.g. for case 1:
- A MIDI file has one track with two channels.
- I have two SynthDef: \synth1 and \synth2
- The second channel is played with \synth2 while the first channel is played with \synth1.

e.g. for case 2:
- A MIDI file has two tracks.
- I have two SynthDef: \synth1 and \synth2
- The second track is played with \synth2 while the first track is played with \synth1.

I could not find such an example in < http://quark.sccode.org/wslib/wslib-help/SimpleMIDIFile.html > and I am not sure if I can configure this from the given examples in the help file.


best,
prko
Reply | Threaded
Open this post in threaded view
|

Aw: [sc-users] Re: SimpleMidiFile: playing a midi file with various instruments

daniel-mayer
Hi,

this looks like a bug in the .p method.
From the source code:

\instrument, inst.wrapAt( tr + 1 )

So it should actually be possible to pass an array of instruments,
but this leads to an error message


ERROR: Message 'secs2beats' not understood.
RECEIVER:
Instance of Array

As a workaround you could do this:

use the midiChannelEvents method to select tracks/channels and rewrite as SimpleMIDIFiles.
Then separate files can be played in parallel (Ppar) with different instruments.
With a dedicated Function this should not be too difficult.

All the best

Daniel

-------------------------
http://daniel-mayer.at
-------------------------
 


_______________________________________________
sc-users mailing list

info (subscription, etc.): http://www.birmingham.ac.uk/facilities/ea-studios/research/supercollider/mailinglist.aspx
archive: http://www.listarc.bham.ac.uk/marchives/sc-users/
search: http://www.listarc.bham.ac.uk/lists/sc-users/search/
Reply | Threaded
Open this post in threaded view
|

Re: SimpleMidiFile: playing a midi file with various instruments

prko
Thank you for your kind explanation.

However, How can I rewrite the array processed by .midiChannelEvents as a SimpleMIDIFile?

The following is what I have tried to do:

~multitrackMIDIFile= "C:/Users/pyoun/OneDrive/Desktop/Untitled1.mid"; // ok
~multitrackMIDIFileLoaded= SimpleMIDIFile.read(~multitrackMIDIFile); // ok

~track1= ~multitrackMIDIFileLoaded.midiTrackEvents(1); // ok .midiChannelEvents works as well
~track2= ~multitrackMIDIFileLoaded.midiTrackEvents(2); // ok

~track1.dopostln; // ok
~track2.dopostln; // ok

~track1FromMultitrackMIDIFile= "C:/Users/pyoun/OneDrive/Desktop/Untitled1.mid"; // ok

~track1_MIDInew1= MIDIEventRecorder(~track1FromMultitrackMIDIFile); // ok
~track1_MIDInew1.add(~track1);
~track1_MIDInew1.dopostln;
// not added

~track1_MIDInew2= SimpleMIDIFile(~track1FromMultitrackMIDIFile); // ok
~track1_MIDInew2.addAllMIDIEvents(~track1);
~track1_MIDInew2.dopostln;
// not added

~track1_MIDInew3= SimpleMIDIFile(~track1FromMultitrackMIDIFile); // ok
~track1_MIDInew3.addAllMIDIEventsToTrack(~track1, 1);
~track1_MIDInew3.dopostln;
// not added

~track1_MIDInew4= SimpleMIDIFile(~track1FromMultitrackMIDIFile); // ok
~track1_MIDInew4.addAllMIDITypeEvents(~track1, 1);
~track1_MIDInew4.dopostln;
// not added

~track1_MIDInew5= SimpleMIDIFile(~track1FromMultitrackMIDIFile); // ok
~track1_MIDInew5.addMIDIEvent(~track1[0], sort: true);
~track1_MIDInew5.dopostln;
// not added

// an attempt by using the example code block in the help file of SimpleMIDIFile
(
~track1_MIDInew6 = SimpleMIDIFile(~track1FromMultitrackMIDIFile);

/*
SimpleMIDIFile.getTime(~multitrackMIDIFile) // does not work
*/

~track1_MIDInew6.init1( 1, ~multitrackMIDIFileLoaded.getTempo, "4/4" )

~track1_MIDInew6.timeMode = \ticks;

~track1.do{
|events|
events[2].postln;
case
{ events[2] == 'cc'}
{~track1_MIDInew6.addCC( items[4], items[5], items[1], items[3], items[0] )}
{ events[2] == 'program'}
{"program parameter is not programed..."}
{ events[2] == 'noteOn'}
{~track1_MIDInew6.addNote( items[4], items[5], items[1], duration, upVelo, items[3], items[0] )}
// I do not know how to get the duration upVelo.....
// I must connect the time information and up velocity from the 'noteOff'. 
// but, I am very perflexed to make an appropriate algorithm. 
}
)