[jmsl] Playing Through An External Midi Device
jmsl at music.columbia.edu
jmsl at music.columbia.edu
Wed Apr 15 07:11:34 EDT 2009
Can you try this? Most of my devices supports time stamp.
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.Receiver;
import javax.sound.midi.ShortMessage;
import com.softsynth.jmsl.JMSL;
import com.softsynth.jmsl.MusicJob;
import com.softsynth.jmsl.SequentialCollection;
public class Test extends MusicJob {
private MidiDevice device;
private Receiver rcvr;
private ShortMessage startMsg, stopMsg;
public double start(double playTime) {
System.out.println("starting at " + device.getMicrosecondPosition());
return playTime;
}
public double repeat(double playTime) {
System.out.println("Repeating at " + device.getMicrosecondPosition());
rcvr.send(stopMsg, -1);
rcvr.send(startMsg, -1);
return playTime;
}
public double stop (double playTime) {
System.out.println("Stopping at " + device.getMicrosecondPosition());
rcvr.send(stopMsg, -1);
System.exit(0);
return playTime;
}
public Test () {
initDevice();
startMsg = new ShortMessage();
try {
startMsg.setMessage(ShortMessage.NOTE_ON, 0, 60, 93);
} catch (InvalidMidiDataException e) {
// e.printStackTrace();
}
stopMsg = new ShortMessage();
try {
stopMsg.setMessage(ShortMessage.NOTE_OFF, 0, 60, 93);
} catch (InvalidMidiDataException e) {
// e.printStackTrace();
}
}
public void initDevice() {
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) {} catch (IOException e) {
// e.printStackTrace();
}
try {
device = MidiSystem.getMidiDevice(infos[n]);
} catch (MidiUnavailableException e) {}
if (!(device.isOpen())) {
try {
device.open();
} catch (MidiUnavailableException e) {
e.printStackTrace();
}
}
try {
rcvr = device.getReceiver();
} catch (MidiUnavailableException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
JMSL.clock.setAdvance(0.1);
Test mj = new Test();
mj.setRepeats(5);
mj.setRepeatPause(2);
mj.launch(JMSL.now());
}
}
----- Original Message -----
From: <jmsl at music.columbia.edu>
To: <jmsl at music.columbia.edu>
Sent: Wednesday, April 15, 2009 1:48 AM
Subject: Re: [jmsl] Playing Through An External Midi Device
> 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
> _______________________________________________
> jmsl mailing list
> jmsl at music.columbia.edu
> http://music.columbia.edu/mailman/listinfo/jmsl
>
More information about the jmsl
mailing list