[jmsl] Playing Through An External Midi Device

jmsl at music.columbia.edu jmsl at music.columbia.edu
Wed Apr 15 01:48:40 EDT 2009


Hi Chi

I have a prerelease posted at http://www.algomusic.com/prerelease/
This prerelease include MidiIO_JavaSound support of external output 
devices (not input devices yet)
Thanks very much for your work on this!  It helped me get this rolled 
into JMSL in a straightforward manner....

Oddly, JavaSound's device indexes do not distinguish between input and 
output devices, so people that use the Midi Device editor will see the 
input list is the same as the output list, with all devices listed in 
each... I'll fix that later.

Don't celebrate the timestamps too soon! Even though there is an 
argument for timestamps, none of the midi devices I have support the 
time stamp. I think it's there as a place holder. I understand the only 
way to get accurate MIDI from JavaSound is to use their Real Time 
Sequencer. Something to look at. But right now, this works OK: you can 
select the midi output device and JMSL.midi will send!  For this 
prerelease MidiIO_JavaSound is the default midi device for JMSL.  But 
right now if people want rhythmically accurate MIDI output, use MidiShare

A summary of changes since last prerelease follows (note there's a bunch 
of music font stuff there, so if any of you have Sonata music font 
installed you'll see that JMSL Score looks quite different now!)

Thanks,
Nick Didkovsky

JMSL PRERELEASE 20090414
12/13/08    Fixed bug in 
com.softsynth.jmsl.score.midi.WriteScoreMidiFile. Chord Intervals with 
Midi Velocities greater than 1 were being multiplied by 128, erroneously 
assuming they were amplitudes. Fixed, thanks Georg Hajdu
12/13/08    MIDIFileToMusicShape now taking absolute values of meta time 
signature data. Greg Wilder provided 2 MIDI files which included 
negative time signatures that crashed the midi file transcriber.
12/27/08    TiedNoteAccumulator sets hold time to accumulated duration. 
This fixes the problem Joel Mellin discovered when the transcriber 
extends long hold times with tied notes    and lets them sustain the 
full hold time.
02/02/09    LilyPond export handles colored noteheads now. Thanks Joel 
Mellin for feature request. See jmsltestsuite.TwoTracksPerStaff
02/02/09    Notehead color attribute saved and loaded to/from score xml
02/02/09    Punos Music plug-in with text-only color chooser for 
Notehead Color. "NoteHeadColorTransform". Not a serious color chooser gui.
03/06/09    Music Font Rendering using Sonata font, major progress. 
noteheads, clefs, stems, expression marks, dynamics, time signatures
03/06/09    Bug fix: clicking on score canvas triggered two renders. 
Removed extra call to score.render()
04/06/09    ScoreFrame has support to use JavaSound MIDI, searches for 
soundbank.gm in classpath/javasound
04/06/09    run_jmsl_score scripts now include ../classes in classpath 
(so that javasound/soundbank.gm can be found)
04/8/09      MusicGlyphRenderers are per Score now, not static any more
04/14/09    Support for external MIDI devices in JavaSound MIDI (Thanks 
Chi!)
04/14/09    Default JMSL.midi is now MidiIO_JavaSound (no longer MidiShare)



jmsl at music.columbia.edu wrote:
> I'm glad it worked. It even supports time stamp, so it's time to ditch 
> MidiShare and move to applet! :) JavaSound seem to have bunch of other 
> stuff for midi (like writing midi file to OutputStream), so it might 
> be worth checking out the program guide when you get a chance.
> How long do you think will take to implement external Midi device 
> support with JavaSound? Let me know when you release new jmsl update.
> Thanks,
>
> Chi
> ----- Original Message ----- From: <jmsl at music.columbia.edu>
> To: <jmsl at music.columbia.edu>
> Sent: Tuesday, April 14, 2009 10:43 PM
> Subject: Re: [jmsl] Playing Through An External Midi Device
>
>
>> OK! I can successfully send midi notes to an external piano module 
>> using this code. I tested it with two different MIDI interfaces: 
>> XSession and Presonus Firepod
>> Works great!
>> thanks
>> Nick
>>
>>
>> jmsl at music.columbia.edu wrote:
>>> Run this and then select the device from the console. It'll play a 
>>> short note.
>>> device.getMicrosecondPosition();
>>> This method returns -1 if the device ignores time stamps. Otherwise, 
>>> it returns the device's current notion of time, which you as the 
>>> sender can use as an offset when determining the time stamps for 
>>> messages you subsequently send. For example, if you want to send a 
>>> message with a time stamp for five milliseconds in the future, you 
>>> can get the device's current position in microseconds, add 5000 
>>> microseconds, and use that as the time stamp. Keep in mind that the 
>>> MidiDevice's notion of time always places time zero at the time the 
>>> device was opened.
>>>
>>>
>>> import java.io.BufferedReader;
>>>
>>> import java.io.IOException;
>>>
>>> import java.io.InputStreamReader;
>>>
>>> import javax.sound.midi.InvalidMidiDataException;
>>>
>>> import javax.sound.midi.MidiDevice;
>>>
>>> import javax.sound.midi.MidiSystem;
>>>
>>> import javax.sound.midi.MidiUnavailableException;
>>>
>>> import javax.sound.midi.ShortMessage;
>>>
>>>
>>> public class Test {
>>>
>>> public static void main(String args[]) throws 
>>> InvalidMidiDataException, MidiUnavailableException, IOException {
>>>
>>>
>>> MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo();
>>>
>>> for (int i = 0; i < infos.length; i++) {
>>>
>>> System.out.println(i+": "+infos[i]);
>>>
>>> }
>>>
>>>
>>> BufferedReader bf = new BufferedReader(new 
>>> InputStreamReader(System.in));
>>>
>>> System.out.println("Which device?");
>>>
>>> int n = 0;
>>>
>>> try {
>>>
>>> n = Integer.parseInt(bf.readLine());
>>>
>>> } catch (NumberFormatException e) {}
>>>
>>>
>>> MidiDevice device = null;
>>>
>>> try {
>>>
>>> device = MidiSystem.getMidiDevice(infos[n]);
>>>
>>> } catch (MidiUnavailableException e) {}
>>>
>>> if (!(device.isOpen())) {
>>>
>>> try {
>>>
>>> device.open();
>>>
>>> } catch (MidiUnavailableException e) {
>>>
>>> // Handle or throw exception...
>>>
>>> }
>>>
>>> }
>>>
>>>
>>> ShortMessage msg = new ShortMessage();
>>>
>>> msg.setMessage(ShortMessage.NOTE_ON, 0, 60, 93);
>>>
>>> long timeStamp = -1;
>>>
>>> javax.sound.midi.Receiver rcvr = device.getReceiver();
>>>
>>> rcvr.send(msg, timeStamp);
>>>
>>> System.exit(0);
>>>
>>> }
>>>
>>>
>>> }
>>>
>>>
>>>
>>> ----- Original Message ----- From: <jmsl at music.columbia.edu>
>>> To: <jmsl at music.columbia.edu>
>>> Sent: Tuesday, April 14, 2009 11:50 AM
>>> Subject: Re: [jmsl] Playing Through An External Midi Device
>>>
>>>
>>>> Hi Chi
>>>>
>>>> Please help me out here, I don't have a lot of resources currently 
>>>> to work on this.  If you can do the following in a few lines of 
>>>> pure Java (no JMSL at all), then I will implement it in JMSL's 
>>>> JavaSound support
>>>>
>>>> If someone already knows how to do this, please share it here.
>>>>
>>>> You already know how to enumerate through midi device info.
>>>>
>>>> You can create a MidiDevice using minfo like this:
>>>> MidiDevice mdev = MidiSystem.getMidiDevice(infos[i]);
>>>>
>>>> Your challenge is to open the mdev you want, get the transmitter or 
>>>> receiver or whatever it is one needs to do to send a midi message 
>>>> out to it, and send it a simple MidiMessage like a noteon.
>>>> I've tried it but cannot get a receiver or a transmitter for these 
>>>> midi devices, I just get nulls or exceptions.  Something's missing 
>>>> and I don't know what it is.
>>>>
>>>> My code follows...
>>>> MidiDevice.Info[] minfo= MidiSystem.getMidiDeviceInfo();
>>>> for (int i = 0; i < minfo.length; i++) {
>>>>                MidiDevice mdev = MidiSystem.getMidiDevice(minfo[i]);
>>>>                String info = minfo[i].getDescription() + ", " +
>>>>                minfo[i].getName() + ", " +
>>>>                minfo[i].getVendor() + ", " +
>>>>                minfo[i].getVersion();
>>>>                System.out.println("\nDevice " + i + " = " + 
>>>> minfo[i] + " ... " + mdev.toString());
>>>>                System.out.println("CLASS: " + mdev.getClass());
>>>>                mdev.open();
>>>>                try {
>>>>                    System.out.println("transmitter for this: " + 
>>>> mdev.getTransmitter());
>>>>                    System.out.println("receiver for this : " + 
>>>> mdev.getReceiver());
>>>>                } catch (MidiUnavailableException e) {
>>>>                    System.out.println("can't get transmitter or 
>>>> receiver for this");
>>>>                }               mdev.close();
>>>> }
>>>>
>>>> Thanks
>>>> Nick
>>>>
>>>> jmsl at music.columbia.edu wrote:
>>>>> How can I hookup JavaSound ports to JMSL? If I do this I can see 
>>>>> all the external midi devices I have on my computer.
>>>>>
>>>>> MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo();
>>>>> for (int i = 0; i < infos.length; i++) {
>>>>>    System.out.println(infos[i]);
>>>>> }
>>>>>
>>>>> /*
>>>>> Result:
>>>>> USB Audio Device
>>>>> Microsoft MIDI Mapper
>>>>> USB Audio Device
>>>>> SB X-Fi Synth A [BC00]
>>>>> SB X-Fi Synth B [BC00]
>>>>> Microsoft GS Wavetable SW Synth
>>>>> Real Time Sequencer
>>>>> Java Sound Synthesizer
>>>>> */
>>>>>
>>>>> If I do this, I get an error.
>>>>> JMSL.midi = MidiIO_JavaSound.instance();
>>>>> String[] deviceNames = JMSL.midi.getOutputDeviceNames();
>>>>> System.out.println("There are " + deviceNames.length + "midi 
>>>>> devices.");
>>>>> for (int i=0; i<deviceNames.length; i++) {
>>>>> System.out.println(deviceNames[i]);
>>>>> }
>>>>>
>>>>> /*
>>>>> Result:
>>>>> There are 1midi devices.
>>>>> Unimplemented
>>>>> */
>>>>>
>>>>> _______________________________________________
>>>>> jmsl mailing list
>>>>> jmsl at music.columbia.edu
>>>>> http://music.columbia.edu/mailman/listinfo/jmsl
>>>> _______________________________________________
>>>> jmsl mailing list
>>>> jmsl at music.columbia.edu
>>>> http://music.columbia.edu/mailman/listinfo/jmsl
>>>>
>>>
>>> _______________________________________________
>>> jmsl mailing list
>>> jmsl at music.columbia.edu
>>> http://music.columbia.edu/mailman/listinfo/jmsl
>> _______________________________________________
>> jmsl mailing list
>> jmsl at music.columbia.edu
>> http://music.columbia.edu/mailman/listinfo/jmsl
>>
>
> _______________________________________________
> jmsl mailing list
> jmsl at music.columbia.edu
> http://music.columbia.edu/mailman/listinfo/jmsl


More information about the jmsl mailing list