001/* 002 * Title: CoreMIDI4J 003 * Description: Core MIDI Device Provider for Java on OS X 004 * Copyright: Copyright (c) 2015-2016 005 * Company: x.factory Librarians 006 * 007 * @author Derek Cook 008 * 009 * CoreMIDI4J is an open source Service Provider Interface for supporting external MIDI devices on MAC OS X 010 * 011 * CREDITS - This library uses principles established by OSXMIDI4J, but converted so it operates at the JNI level with no additional libraries required 012 * 013 */ 014 015package uk.co.xfactorylibrarians.coremidi4j; 016 017import javax.sound.midi.MidiDevice; 018import javax.sound.midi.MidiDeviceReceiver; 019import javax.sound.midi.MidiMessage; 020import java.util.concurrent.atomic.AtomicBoolean; 021 022/** 023 * CoreMidiReceiver - used to receive data from the application and send it to the connected device. 024 * 025 */ 026 027public class CoreMidiReceiver implements MidiDeviceReceiver { 028 029 private final CoreMidiDestination device; 030 private final AtomicBoolean closed = new AtomicBoolean(false); 031 032 033 /** 034 * CoreMidiReceiver constructor 035 * 036 * @param device The MIDI device that contains the information required to send MIDI data via OSX core MIDI 037 */ 038 039 CoreMidiReceiver(final CoreMidiDestination device) { 040 041 this.device = device; 042 043 } 044 045 /** 046 * Sends a MIDI message 047 * 048 * @see javax.sound.midi.Receiver#send(javax.sound.midi.MidiMessage, long) 049 * 050 */ 051 052 @Override 053 public void send(MidiMessage message, long timeStamp) { 054 055 if ( closed.get() == true ) { 056 057 throw new IllegalStateException("Can't call send() with a closed receiver"); 058 059 } 060 061 if ( device.isOpen() == false ) { 062 063 throw new IllegalStateException("Can't call send with a receiver attached to a device that is not open: " + device); 064 065 } 066 067 try { 068 069 // Convert from Java-oriented port-relative microsecends to CoreMIDI-oriented boot-relative microseconds, 070 // and from signed Java semantics of -1 meaning now to unsigned CoreMIDI semantics of 0 meaning now. 071 final long coreTimestamp = (timeStamp == -1) ? 0 : timeStamp + device.getStartTime(); 072 073 CoreMidiDeviceProvider.getOutputPort().send(((CoreMidiDeviceInfo)device.getDeviceInfo()).getEndPointReference(), message, coreTimestamp); 074 075 } catch (CoreMidiException e) { 076 077 e.printStackTrace(); 078 079 } 080 081 } 082 083 /** 084 * Closes the MIDI Receiver 085 * 086 * @see javax.sound.midi.Receiver#close() 087 * 088 */ 089 090 @Override 091 public void close() { 092 093 if ( closed.compareAndSet(false, true) == true ) { 094 095 device.receiverClosed(this); 096 097 } 098 099 } 100 101 /** 102 * Gets the MIDI Device that this receiver is attached to 103 * 104 * @return the MIDI Device that this receiver is attached to 105 * 106 */ 107 108 @Override 109 public MidiDevice getMidiDevice() { 110 111 return device; 112 113 } 114 115}