[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