⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tsequencer.java

📁 linux下建立JAVA虚拟机的源码KAFFE
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* *	TSequencer.java *//* *  Copyright (c) 1999 - 2003 by Matthias Pfisterer * *   This program is free software; you can redistribute it and/or modify *   it under the terms of the GNU Library General Public License as published *   by the Free Software Foundation; either version 2 of the License, or *   (at your option) any later version. * *   This program 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 Library General Public License for more details. * *   You should have received a copy of the GNU Library General Public *   License along with this program; if not, write to the Free Software *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */package	org.tritonus.share.midi;import java.io.IOException;import java.io.InputStream;import java.util.BitSet;import java.util.Collection;import java.util.Iterator;import java.util.Set;import javax.sound.midi.ControllerEventListener;import javax.sound.midi.InvalidMidiDataException;import javax.sound.midi.MetaEventListener;import javax.sound.midi.MetaMessage;import javax.sound.midi.MidiDevice;import javax.sound.midi.MidiMessage;import javax.sound.midi.MidiSystem;import javax.sound.midi.Sequence;import javax.sound.midi.Sequencer;import javax.sound.midi.ShortMessage;import org.tritonus.share.ArraySet;import org.tritonus.share.TDebug;public abstract class TSequencer	extends		TMidiDevice	implements	Sequencer{	private static final float	MPQ_BPM_FACTOR = 6.0E7F;	// This is for use in Collection.toArray(Object[]).	private static final SyncMode[]	EMPTY_SYNCMODE_ARRAY = new SyncMode[0];	private boolean		m_bRunning;	/**	The Sequence to play or to record to.	 */	private Sequence	m_sequence;	/**	The listeners that want to be notified of MetaMessages.	 */	private Set		m_metaListeners;	/**	The listeners that want to be notified of control change events.	 *	They are organized as follows: this array is indexed with	 *	the number of the controller change events listeners are	 *	interested in. If there is any interest, the array element	 *	contains a reference to a Set containing the listeners.	 *	These sets are allocated on demand.	 */	private Set[]		m_aControllerListeners;	private float		m_fNominalTempoInMPQ;	private float		m_fTempoFactor;	private Collection	m_masterSyncModes;	private Collection	m_slaveSyncModes;	private SyncMode	m_masterSyncMode;	private SyncMode	m_slaveSyncMode;	private BitSet		m_muteBitSet;	private BitSet		m_soloBitSet;	/**	Contains the enabled state of the tracks.		This BitSet holds the pre-calculated effect of mute and		solo status.	*/	private BitSet		m_enabledBitSet;	protected TSequencer(MidiDevice.Info info,			     Collection masterSyncModes,			     Collection slaveSyncModes)	{		super(info);		if (TDebug.TraceSequencer) { TDebug.out("TSequencer.<init>(): begin"); }		m_bRunning = false;		m_sequence = null;		m_metaListeners = new ArraySet();		m_aControllerListeners = new Set[128];		setTempoInMPQ(500000);		setTempoFactor(1.0F);		m_masterSyncModes = masterSyncModes;		m_slaveSyncModes = slaveSyncModes;		if (getMasterSyncModes().length > 0)		{			m_masterSyncMode = getMasterSyncModes()[0];		}		if (getSlaveSyncModes().length > 0)		{			m_slaveSyncMode = getSlaveSyncModes()[0];		}		m_muteBitSet = new BitSet();		m_soloBitSet = new BitSet();		m_enabledBitSet = new BitSet();		updateEnabled();		if (TDebug.TraceSequencer) { TDebug.out("TSequencer.<init>(): end"); }	}	public void setSequence(Sequence sequence)		throws	InvalidMidiDataException	{		if (TDebug.TraceSequencer) { TDebug.out("TSequencer.setSequence(Sequence): begin"); }		// TODO: what if playing is in progress?		m_sequence = sequence;		// yes, this is required by the specification		setTempoFactor(1.0F);		if (TDebug.TraceSequencer) { TDebug.out("TSequencer.setSequence(Sequence): end"); }	}	public void setSequence(InputStream inputStream)		throws	InvalidMidiDataException, IOException	{		if (TDebug.TraceSequencer) { TDebug.out("TSequencer.setSequence(InputStream): begin"); }		Sequence	sequence = MidiSystem.getSequence(inputStream);		setSequence(sequence);		if (TDebug.TraceSequencer) { TDebug.out("TSequencer.setSequence(InputStream): end"); }	}	public Sequence getSequence()	{		if (TDebug.TraceSequencer) { TDebug.out("TSequencer.getSequence(): begin"); }		if (TDebug.TraceSequencer) { TDebug.out("TSequencer.getSequence(): end"); }		return m_sequence;	}	public synchronized void start()	{		if (TDebug.TraceSequencer) { TDebug.out("TSequencer.start(): begin"); }		checkOpen();		if (! isRunning())		{			m_bRunning = true;			// TODO: perhaps check if sequence present			startImpl();		}		if (TDebug.TraceSequencer) { TDebug.out("TSequencer.start(): end"); }	}	/**	 *	Subclasses have to override this method to be notified of	 *	starting.	 */	protected void startImpl()	{		if (TDebug.TraceMidiDevice) { TDebug.out("TSequencer.startImpl(): begin"); }		if (TDebug.TraceMidiDevice) { TDebug.out("TSequencer.startImpl(): end"); }	}	public synchronized void stop()	{		if (TDebug.TraceSequencer) { TDebug.out("TSequencer.stop(): begin"); }		checkOpen();		if (isRunning())		{			stopImpl();			m_bRunning = false;		}		if (TDebug.TraceSequencer) { TDebug.out("TSequencer.stop(): end"); }	}	/**	 *	Subclasses have to override this method to be notified of	 *	stopping.	 */	protected void stopImpl()	{		if (TDebug.TraceMidiDevice) { TDebug.out("TSequencer.stopImpl(): begin"); }		if (TDebug.TraceMidiDevice) { TDebug.out("TSequencer.stopImpl(): end"); }	}	public synchronized boolean isRunning()	{		return m_bRunning;	}	/** Checks if the Sequencer is open.		This method is intended to be called by		{@link javax.sound.midi.Sequencer#start start},		{@link javax.sound.midi.Sequencer#stop stop},		{@link javax.sound.midi.Sequencer#startRecording startRecording}		and {@link javax.sound.midi.Sequencer#stop stopRecording}.		@throws IllegalStateException if the <code>Sequencer</code> is not open	 */	protected void checkOpen()	{		if (! isOpen())		{			throw new IllegalStateException("Sequencer is not open");		}	}	/**	Returns the resolution (ticks per quarter) of the current sequence.		If no sequence is set, a bogus default value != 0 is returned.	*/	protected int getResolution()	{		if (TDebug.TraceSequencer) { TDebug.out("TSequencer.getResolution(): begin"); }		Sequence	sequence = getSequence();		int		nResolution;		if (sequence != null)		{			nResolution = sequence.getResolution();		}		else		{			nResolution = 1;		}		if (TDebug.TraceSequencer) { TDebug.out("TSequencer.getResolution(): end"); }		return nResolution;	}	protected void setRealTempo()	{		if (TDebug.TraceSequencer) { TDebug.out("TSequencer.setRealTempo(): begin"); }		float	fRealTempo = getTempoInMPQ() / getTempoFactor();		if (TDebug.TraceSequencer) { TDebug.out("TSequencer.setRealTempo(): real tempo: " + fRealTempo); }		setTempoImpl(fRealTempo);		if (TDebug.TraceSequencer) { TDebug.out("TSequencer.setRealTempo(): end"); }	}	public float getTempoInBPM()	{		if (TDebug.TraceSequencer) { TDebug.out("TSequencer.getTempoInBPM(): begin"); }		float	fBPM = MPQ_BPM_FACTOR / getTempoInMPQ();		if (TDebug.TraceSequencer) { TDebug.out("TSequencer.getTempoInBPM(): end"); }		return fBPM;	}	public void setTempoInBPM(float fBPM)	{		if (TDebug.TraceSequencer) { TDebug.out("TSequencer.setTempoInBPM(): begin"); }		float	fMPQ = MPQ_BPM_FACTOR / fBPM;		setTempoInMPQ(fMPQ);		if (TDebug.TraceSequencer) { TDebug.out("TSequencer.setTempoInBPM(): end"); }	}	public float getTempoInMPQ()	{		if (TDebug.TraceSequencer) { TDebug.out("TSequencer.getTempoInMPQ(): begin"); }		if (TDebug.TraceSequencer) { TDebug.out("TSequencer.getTempoInMPQ(): end"); }		return m_fNominalTempoInMPQ;	}	/** Sets the tempo.		Implementation classes are required to call this method for changing		the tempo in reaction to a tempo change event.	 */	public void setTempoInMPQ(float fMPQ)	{		if (TDebug.TraceSequencer) { TDebug.out("TSequencer.setTempoInMPQ(): begin"); } 		m_fNominalTempoInMPQ = fMPQ; 		setRealTempo();		if (TDebug.TraceSequencer) { TDebug.out("TSequencer.setTempoInMPQ(): end"); }	}	public void setTempoFactor(float fFactor)	{		if (TDebug.TraceSequencer) { TDebug.out("TSequencer.setTempoFactor(): begin"); }		m_fTempoFactor = fFactor;		setRealTempo();		if (TDebug.TraceSequencer) { TDebug.out("TSequencer.setTempoFactor(): end"); }	}	public float getTempoFactor()	{		if (TDebug.TraceSequencer) { TDebug.out("TSequencer.getTempoFactor(): begin"); }		if (TDebug.TraceSequencer) { TDebug.out("TSequencer.getTempoFactor(): end"); }		return m_fTempoFactor;	}	/**	Change the tempo of the native sequencer part.	 *	This method has to be defined by subclasses according	 *	to the native facilities they use for sequenceing.	 *	The implementation should not take into account the	 *	tempo factor. This is handled elsewhere.	 */	protected abstract void setTempoImpl(float fMPQ);	// NOTE: has to be redefined if recording is done natively	public long getTickLength()	{		if (TDebug.TraceSequencer) { TDebug.out("TSequencer.getTickLength(): begin"); }		long	lLength = 0;		if (getSequence() != null)		{			lLength = getSequence().getTickLength();		}		if (TDebug.TraceSequencer) { TDebug.out("TSequencer.getTickLength(): end"); }		return lLength;	}	// NOTE: has to be redefined if recording is done natively	public long getMicrosecondLength()	{		if (TDebug.TraceSequencer) { TDebug.out("TSequencer.getMicrosecondLength(): begin"); }		long	lLength = 0;		if (getSequence() != null)		{			lLength = getSequence().getMicrosecondLength();		}		if (TDebug.TraceSequencer) { TDebug.out("TSequencer.getMicrosecondLength(): end"); }		return lLength;	}	public boolean addMetaEventListener(MetaEventListener listener)	{		synchronized (m_metaListeners)		{			return m_metaListeners.add(listener);		}	}	public void removeMetaEventListener(MetaEventListener listener)	{		synchronized (m_metaListeners)		{			m_metaListeners.remove(listener);		}	}	protected Iterator getMetaEventListeners()	{		synchronized (m_metaListeners)		{			return m_metaListeners.iterator();		}	}	protected void sendMetaMessage(MetaMessage message)	{		Iterator	iterator = getMetaEventListeners();		while (iterator.hasNext())		{			MetaEventListener	metaEventListener = (MetaEventListener) iterator.next();			MetaMessage	copiedMessage = (MetaMessage) message.clone();			metaEventListener.meta(copiedMessage);		}	}	public int[] addControllerEventListener(ControllerEventListener listener, int[] anControllers)	{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -