| 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 */  | 
 | 
 | 
 | 
package com.sun.media.sound;  | 
 | 
 | 
 | 
import javax.sound.midi.*;  | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 */  | 
 | 
final class MidiOutDevice extends AbstractMidiDevice { | 
 | 
 | 
 | 
    // CONSTRUCTOR  | 
 | 
 | 
 | 
    MidiOutDevice(AbstractMidiDeviceProvider.Info info) { | 
 | 
                super(info);  | 
 | 
                if(Printer.trace) Printer.trace("MidiOutDevice CONSTRUCTOR"); | 
 | 
    }  | 
 | 
 | 
 | 
 | 
 | 
    // IMPLEMENTATION OF ABSTRACT MIDI DEVICE METHODS  | 
 | 
 | 
 | 
    protected synchronized void implOpen() throws MidiUnavailableException { | 
 | 
        if (Printer.trace) Printer.trace("> MidiOutDevice: implOpen()"); | 
 | 
        int index = ((AbstractMidiDeviceProvider.Info)getDeviceInfo()).getIndex();  | 
 | 
        id = nOpen(index);   | 
 | 
        if (id == 0) { | 
 | 
            throw new MidiUnavailableException("Unable to open native device"); | 
 | 
        }  | 
 | 
        if (Printer.trace) Printer.trace("< MidiOutDevice: implOpen(): completed."); | 
 | 
    }  | 
 | 
 | 
 | 
 | 
 | 
    protected synchronized void implClose() { | 
 | 
        if (Printer.trace) Printer.trace("> MidiOutDevice: implClose()"); | 
 | 
          | 
 | 
        long oldId = id;  | 
 | 
        id = 0;  | 
 | 
 | 
 | 
        super.implClose();  | 
 | 
 | 
 | 
          | 
 | 
        nClose(oldId);  | 
 | 
        if (Printer.trace) Printer.trace("< MidiOutDevice: implClose(): completed"); | 
 | 
    }  | 
 | 
 | 
 | 
 | 
 | 
    public long getMicrosecondPosition() { | 
 | 
        long timestamp = -1;  | 
 | 
        if (isOpen()) { | 
 | 
            timestamp = nGetTimeStamp(id);  | 
 | 
        }  | 
 | 
        return timestamp;  | 
 | 
    }  | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
    // OVERRIDES OF ABSTRACT MIDI DEVICE METHODS  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
    */  | 
 | 
    protected boolean hasReceivers() { | 
 | 
        return true;  | 
 | 
    }  | 
 | 
 | 
 | 
 | 
 | 
    protected Receiver createReceiver() { | 
 | 
        return new MidiOutReceiver();  | 
 | 
    }  | 
 | 
 | 
 | 
 | 
 | 
    // INNER CLASSES  | 
 | 
 | 
 | 
    final class MidiOutReceiver extends AbstractReceiver { | 
 | 
 | 
 | 
        void implSend(final MidiMessage message, final long timeStamp) { | 
 | 
            final int length = message.getLength();  | 
 | 
            final int status = message.getStatus();  | 
 | 
            if (length <= 3 && status != 0xF0 && status != 0xF7) { | 
 | 
                int packedMsg;  | 
 | 
                if (message instanceof ShortMessage) { | 
 | 
                    if (message instanceof FastShortMessage) { | 
 | 
                        packedMsg = ((FastShortMessage) message).getPackedMsg();  | 
 | 
                    } else { | 
 | 
                        ShortMessage msg = (ShortMessage) message;  | 
 | 
                        packedMsg = (status & 0xFF)  | 
 | 
                            | ((msg.getData1() & 0xFF) << 8)  | 
 | 
                            | ((msg.getData2() & 0xFF) << 16);  | 
 | 
                    }  | 
 | 
                } else { | 
 | 
                    packedMsg = 0;  | 
 | 
                    byte[] data = message.getMessage();  | 
 | 
                    if (length>0) { | 
 | 
                        packedMsg = data[0] & 0xFF;  | 
 | 
                        if (length>1) { | 
 | 
                              | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
                               have a Meta message. */  | 
 | 
                            if (status == 0xFF) { | 
 | 
                                return;  | 
 | 
                            }  | 
 | 
                            packedMsg |= (data[1] & 0xFF) << 8;  | 
 | 
                            if (length>2) { | 
 | 
                                packedMsg |= (data[2] & 0xFF) << 16;  | 
 | 
                            }  | 
 | 
                        }  | 
 | 
                    }  | 
 | 
                }  | 
 | 
                nSendShortMessage(id, packedMsg, timeStamp);  | 
 | 
            } else { | 
 | 
                final byte[] data;  | 
 | 
                if (message instanceof FastSysexMessage) { | 
 | 
                    data = ((FastSysexMessage) message).getReadOnlyMessage();  | 
 | 
                } else { | 
 | 
                    data = message.getMessage();  | 
 | 
                }  | 
 | 
                final int dataLength = Math.min(length, data.length);  | 
 | 
                if (dataLength > 0) { | 
 | 
                    nSendLongMessage(id, data, dataLength, timeStamp);  | 
 | 
                }  | 
 | 
            }  | 
 | 
        }  | 
 | 
 | 
 | 
          | 
 | 
        synchronized void sendPackedMidiMessage(int packedMsg, long timeStamp) { | 
 | 
            if (isOpen() && id != 0) { | 
 | 
                nSendShortMessage(id, packedMsg, timeStamp);  | 
 | 
            }  | 
 | 
        }  | 
 | 
 | 
 | 
 | 
 | 
    } // class MidiOutReceiver  | 
 | 
 | 
 | 
 | 
 | 
    // NATIVE METHODS  | 
 | 
 | 
 | 
    private native long nOpen(int index) throws MidiUnavailableException;  | 
 | 
    private native void nClose(long id);  | 
 | 
 | 
 | 
    private native void nSendShortMessage(long id, int packedMsg, long timeStamp);  | 
 | 
    private native void nSendLongMessage(long id, byte[] data, int size, long timeStamp);  | 
 | 
    private native long nGetTimeStamp(long id);  | 
 | 
 | 
 | 
} // class MidiOutDevice  |