package com.frinika.project; import java.io.Serializable; import java.lang.reflect.Method; /* * Created on Sep 19, 2006 * * Copyright (c) 2004-2006 Peter Johan Salomonsen (http://www.petersalomonsen.com) * * http://www.frinika.com * * This file is part of Frinika. * * Frinika is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Frinika is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Frinika; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ import javax.sound.midi.MidiDevice; import javax.sound.midi.MidiSystem; import javax.sound.midi.MidiUnavailableException; import javax.sound.sampled.Mixer; import javax.swing.Icon; import com.frinika.project.gui.ProjectFrame; import com.frinika.sequencer.gui.mixer.MidiDeviceIconProvider; import com.frinika.sequencer.gui.mixer.SynthWrapper; import com.frinika.sequencer.model.Lane; import com.frinika.sequencer.model.SynthLane; import com.frinika.synth.SynthRack; /** * A serializable representation of a Midi Device used in a Frinika project. * Contains resources neccesary for re-opening the correct midi device. * * @author Peter Johan Salomonsen */ public class MidiDeviceDescriptor implements Serializable, MidiDeviceIconProvider { private static final long serialVersionUID = 1L; String midiDeviceName; String projectName; protected Serializable serializableMidiDevice = null; transient MidiDevice midiDevice; transient private boolean isInstalled = false; /** * Construct a new MidiDeviceDescriptor from a MidiDevice * * @param midiDevice */ public MidiDeviceDescriptor(MidiDevice midiDevice) { this.midiDevice = midiDevice; this.midiDeviceName = midiDevice.getDeviceInfo().getName(); this.projectName = midiDeviceName; if (midiDevice instanceof SynthWrapper) { SynthWrapper synthwrapper = (SynthWrapper) midiDevice; if (synthwrapper.getRealDevice() instanceof Serializable) serializableMidiDevice = (Serializable) synthwrapper .getRealDevice(); } } /** * Name of the midi device as registered in MidiSystem * * @return */ public String getMidiDeviceName() { return midiDeviceName; } /** * Set the name of the midi device as registered in MidiSystem * * @param midiDeviceName */ public void setMidiDeviceName(String midiDeviceName) { this.midiDeviceName = midiDeviceName; } /** * Get the name of the midi device as the user has set for it in the Frinika * project * * @return */ public String getProjectName() { return projectName; } /** * Set the name of the midi device as the user wants to name it in the * Frinika project * * @param projectName */ public void setProjectName(String projectName) { this.projectName = projectName; if (midiDevice instanceof SynthWrapper) { SynthWrapper synthwrapper = (SynthWrapper) midiDevice; MidiDevice realdevice = synthwrapper.getRealDevice(); try { Method setName = realdevice.getClass().getMethod("setName", String.class); setName.invoke(realdevice, projectName); } catch (Exception e) { } } } /** * Install a MidiDevice that this descriptor describes into the given * project * * @param container */ final public void install(ProjectContainer project) { if (isInstalled) return; if (serializableMidiDevice != null) { if (serializableMidiDevice instanceof MidiDevice) { midiDevice = new SynthWrapper(project, (MidiDevice) serializableMidiDevice); try { midiDevice.open(); project.loadMidiOutDevice(this); isInstalled = true; attachToSynthLane(project); // PJL return; } catch (MidiUnavailableException e) { System.out.println(" Failed to open MidiDevice " + midiDeviceName); e.printStackTrace(); } } } installImp(project); isInstalled = true; if (midiDevice instanceof SynthWrapper) { SynthWrapper synthwrapper = (SynthWrapper) midiDevice; if (synthwrapper.getRealDevice() instanceof Serializable) serializableMidiDevice = (Serializable) synthwrapper .getRealDevice(); } attachToSynthLane(project); setProjectName(projectName); } private void attachToSynthLane(ProjectContainer project ) { // **************** PJL // System. out.println(" Resolving Synth lane "); boolean found = false; for (Lane lane : project.projectLane.getChildren()) { if (lane instanceof SynthLane) { SynthLane sl=(SynthLane) lane; if (sl.getMidiDescriptor() != this ) continue; if (sl.install(this)) { MidiDevice dev = sl.getMidiDescriptor().getMidiDevice(); if (dev instanceof SynthWrapper && ((SynthWrapper)dev).getAudioProcess() != null || dev instanceof SynthRack ){ sl.attachAudioProcessToMixer(); } found = true; break; } } } if (!found) { System.out.println("Unable to find a SynthLane for synth " + midiDevice); SynthLane lane = project.createSynthLane(this); lane.attachAudioProcessToMixer(); } } /** * Called from install to actually do the work. Typically you want to * override this but make sure super.installImp is called. * * * @param project */ protected void installImp(ProjectContainer project) { MidiDevice dev = null; try { for (MidiDevice.Info info : MidiSystem.getMidiDeviceInfo()) { if (info.getName().equals(midiDeviceName)) { dev = MidiSystem.getMidiDevice(info); // Assure that this is actually a MidOutDevice if (dev.getMaxReceivers() != 0) break; else dev = null; } } // Bypass MidiHub // dev = MidiHub.getMidiOutDeviceByName(midiDeviceName); if (dev == null) { System.out.println(" Failed to find MidiDevice " + midiDeviceName); } else { midiDevice = new SynthWrapper(project, dev); //midiDevice.open(); project.loadMidiOutDevice(this); } } catch (MidiUnavailableException e) { System.out.println(" Failed to open MidiDevice " + midiDeviceName); e.printStackTrace(); } } public MidiDevice getMidiDevice() { return midiDevice; } public Serializable getSerializableMidiDevice() { return serializableMidiDevice; } @Override public String toString() { return getProjectName() + " (" + getMidiDeviceName() + ")"; } public Icon getIcon() { return ProjectFrame.getMidiDeviceIcon(midiDevice); } public Icon getLargeIcon() { return ProjectFrame.getMidiDeviceLargeIcon(midiDevice); } }