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

📄 alsasequencer.java

📁 linux下建立JAVA虚拟机的源码KAFFE
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* *	AlsaSequencer.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.midi.device.alsa;import	java.util.Arrays;import	javax.sound.midi.InvalidMidiDataException;import	javax.sound.midi.MetaMessage;import	javax.sound.midi.MidiDevice;import	javax.sound.midi.MidiEvent;import	javax.sound.midi.MidiMessage;import	javax.sound.midi.MidiUnavailableException;import	javax.sound.midi.Receiver;import	javax.sound.midi.ShortMessage;import	javax.sound.midi.Sequence;import	javax.sound.midi.Sequencer;import	javax.sound.midi.Track;import	javax.sound.midi.Transmitter;import	org.tritonus.lowlevel.alsa.AlsaSeq;import	org.tritonus.lowlevel.alsa.AlsaSeqPortSubscribe;import	org.tritonus.lowlevel.alsa.AlsaSeqQueueInfo;import	org.tritonus.lowlevel.alsa.AlsaSeqEvent;import	org.tritonus.lowlevel.alsa.AlsaSeqQueueStatus;import	org.tritonus.lowlevel.alsa.AlsaSeqQueueTempo;import	org.tritonus.share.TDebug;import	org.tritonus.share.midi.MidiUtils;import	org.tritonus.share.midi.TMidiDevice.TReceiver;import	org.tritonus.share.midi.TMidiDevice.TTransmitter;import	org.tritonus.share.midi.TSequencer;public class AlsaSequencer// TODO: derive from TPreloadingSequencerextends TSequencer{	/**	The syncronization modes the sequencer can sync to.	 */	private static final SyncMode[]	MASTER_SYNC_MODES = {SyncMode.INTERNAL_CLOCK};	/**	The syncronization modes the sequencer can send.	 */	private static final SyncMode[]	SLAVE_SYNC_MODES = {SyncMode.NO_SYNC, SyncMode.MIDI_SYNC};	/**	The ALSA event tag used for MIDI clock events	 */	private static final int	CLOCK_EVENT_TAG = 255;	private AlsaSeq				m_playbackAlsaSeq;	private AlsaSeq				m_recordingAlsaSeq;	private int					m_nRecordingPort;	private int					m_nPlaybackPort;	private int					m_nQueue;	private AlsaSeqQueueInfo	m_queueInfo;	private AlsaSeqQueueStatus	m_queueStatus;	private AlsaSeqQueueTempo	m_queueTempo;	private AlsaMidiIn			m_playbackAlsaMidiIn;	private AlsaMidiOut			m_playbackAlsaMidiOut;	private AlsaMidiIn			m_recordingAlsaMidiIn;	private Thread				m_loaderThread;	private Thread				m_syncThread;	private AlsaSeqEvent		m_queueControlEvent;	private AlsaSeqEvent		m_clockEvent;	private boolean				m_bRecording;	private Track				m_track;	private AlsaSeqEvent		m_allNotesOffEvent;	private Sequencer.SyncMode	m_oldSlaveSyncMode;	private float				m_fCachedRealMPQ;	public AlsaSequencer(MidiDevice.Info info)	{		super(info,		      Arrays.asList(MASTER_SYNC_MODES),		      Arrays.asList(SLAVE_SYNC_MODES));		if (TDebug.TraceSequencer) { TDebug.out("AlsaSequencer.<init>(): begin"); }		m_fCachedRealMPQ = -1.0F;		if (TDebug.TraceSequencer) { TDebug.out("AlsaSequencer.<init>(): end"); }	}	private int getPlaybackClient()	{		int	nClient = getPlaybackAlsaSeq().getClientId();		return nClient;	}	private int getPlaybackPort()	{		return m_nPlaybackPort;	}	private int getRecordingClient()	{		int	nClient = getRecordingAlsaSeq().getClientId();		return nClient;	}	private int getRecordingPort()	{		return m_nRecordingPort;	}	private int getQueue()	{		return m_nQueue;	}	private AlsaSeqQueueStatus getQueueStatus()	{		return m_queueStatus;	}	private AlsaSeqQueueTempo getQueueTempo()	{		return m_queueTempo;	}	private AlsaSeq getPlaybackAlsaSeq()	{		return m_playbackAlsaSeq;	}	private AlsaSeq getRecordingAlsaSeq()	{		return m_recordingAlsaSeq;	}	private void updateQueueStatus()	{		if (TDebug.TraceSequencer) { TDebug.out("AlsaSequencer.updateQueueStatus(): begin"); }		// TODO: error handling		// getRecordingAlsaSeq().getQueueStatus(getQueue(), getQueueStatus());		getPlaybackAlsaSeq().getQueueStatus(getQueue(), getQueueStatus());		if (TDebug.TraceSequencer) { TDebug.out("AlsaSequencer.updateQueueStatus(): end"); }	}	protected void openImpl()	{		if (TDebug.TraceSequencer) { TDebug.out("AlsaSequencer.openImpl(): begin"); }		m_recordingAlsaSeq = new AlsaSeq("Tritonus ALSA Sequencer (recording/synchronization)");		m_nRecordingPort = getRecordingAlsaSeq().createPort("recording/synchronization port", AlsaSeq.SND_SEQ_PORT_CAP_WRITE | AlsaSeq.SND_SEQ_PORT_CAP_SUBS_WRITE | AlsaSeq.SND_SEQ_PORT_CAP_READ | AlsaSeq.SND_SEQ_PORT_CAP_SUBS_READ, 0, AlsaSeq.SND_SEQ_PORT_TYPE_APPLICATION, 0, 0, 0);		m_playbackAlsaSeq = new AlsaSeq("Tritonus ALSA Sequencer (playback)");		m_nPlaybackPort = getPlaybackAlsaSeq().createPort("playback port", AlsaSeq.SND_SEQ_PORT_CAP_WRITE | AlsaSeq.SND_SEQ_PORT_CAP_SUBS_WRITE | AlsaSeq.SND_SEQ_PORT_CAP_READ | AlsaSeq.SND_SEQ_PORT_CAP_SUBS_READ, 0, AlsaSeq.SND_SEQ_PORT_TYPE_APPLICATION, 0, 0, 0);		m_nQueue = getPlaybackAlsaSeq().allocQueue();		m_queueInfo = new AlsaSeqQueueInfo();		m_queueStatus = new AlsaSeqQueueStatus();		m_queueTempo = new AlsaSeqQueueTempo();		getPlaybackAlsaSeq().getQueueInfo(getQueue(), m_queueInfo);		m_queueInfo.setLocked(false);		getPlaybackAlsaSeq().setQueueInfo(getQueue(), m_queueInfo);		m_playbackAlsaMidiOut = new AlsaMidiOut(getPlaybackAlsaSeq(), getPlaybackPort(), getQueue());		m_playbackAlsaMidiOut.setHandleMetaMessages(true);		getRecordingAlsaSeq().setQueueUsage(getQueue(), true);		// this establishes the subscription, too		AlsaMidiIn.AlsaMidiInListener	playbackListener = new PlaybackAlsaMidiInListener();		m_playbackAlsaMidiIn = new AlsaMidiIn(getPlaybackAlsaSeq(), getPlaybackPort(), getPlaybackClient(), getPlaybackPort(), playbackListener);		// start the receiving thread		m_playbackAlsaMidiIn.start();		if (TDebug.TraceSequencer) { TDebug.out("AlsaSequencer.openImpl(): end"); }		m_queueControlEvent = new AlsaSeqEvent();		m_clockEvent = new AlsaSeqEvent();		m_clockEvent.setCommon(			AlsaSeq.SND_SEQ_EVENT_CLOCK,	// type			AlsaSeq.SND_SEQ_TIME_STAMP_TICK | AlsaSeq.SND_SEQ_TIME_MODE_ABS,			CLOCK_EVENT_TAG,	// tag			getQueue(),			0L,	// timestamp; not yet known			0,				// source client			getRecordingPort(),		// source port			AlsaSeq.SND_SEQ_ADDRESS_SUBSCRIBERS,	// dest client			AlsaSeq.SND_SEQ_ADDRESS_UNKNOWN);	// dest port		m_allNotesOffEvent = new AlsaSeqEvent();		m_oldSlaveSyncMode = getSlaveSyncMode();		if (m_fCachedRealMPQ != -1.0F)		{			setTempoImpl(m_fCachedRealMPQ);			m_fCachedRealMPQ = -1.0F;		}		m_loaderThread = new LoaderThread();		m_loaderThread.start();		// this is for sending clock events		// m_syncThread = new MasterSynchronizer();		// m_syncThread.start();	}	protected void closeImpl()	{		if (TDebug.TraceSequencer) { TDebug.out("AlsaSequencer.closeImpl(): begin"); }		m_playbackAlsaMidiIn.interrupt();		m_playbackAlsaMidiIn = null;		getQueueStatus().free();		m_queueStatus = null;		getQueueTempo().free();		m_queueTempo = null;		// TODO:		// m_aSequencer.releaseQueue(getQueue());		// m_aSequencer.destroyPort(getPort());		getRecordingAlsaSeq().close();		m_recordingAlsaSeq = null;		getPlaybackAlsaSeq().close();		m_playbackAlsaSeq = null;		m_queueControlEvent.free();		m_queueControlEvent = null;		m_clockEvent.free();		m_clockEvent = null;		m_allNotesOffEvent.free();		m_allNotesOffEvent = null;		if (TDebug.TraceSequencer) { TDebug.out("AlsaSequencer.closeImpl(): end"); }	}	protected void startImpl()	{		if (TDebug.TraceSequencer) { TDebug.out("AlsaSequencer.startImpl(): begin"); }		if (getTickPosition() == 0)		{			startQueue();		}		else		{			continueQueue();		}		synchronized (m_loaderThread)		{			if (TDebug.TraceSequencer) { TDebug.out("AlsaSequencer.startImpl(): notifying loader thread"); }			m_loaderThread.notify();		}		// TODO: should depend on sync mode// 		synchronized (m_syncThread)// 		{// 			if (TDebug.TraceSequencer) { TDebug.out("AlsaSequencer.startImpl(): notifying synchronizer thread"); }// 			m_syncThread.notify();// 		}		if (! getSlaveSyncMode(). equals(Sequencer.SyncMode.NO_SYNC))		{			sendStartEvent();		}		if (TDebug.TraceSequencer) { TDebug.out("AlsaSequencer.startImpl(): end"); }	}	protected void stopImpl()	{		if (TDebug.TraceSequencer) { TDebug.out("AlsaSequencer.stopImpl(): begin"); }		stopQueue();		sendAllNotesOff();		// should be in base class?		stopRecording();		if (! getSlaveSyncMode(). equals(Sequencer.SyncMode.NO_SYNC))		{			sendStopEvent();		}		if (TDebug.TraceSequencer) { TDebug.out("AlsaSequencer.stopImpl(): end"); }	}	public boolean isRunning()	{		if (TDebug.TraceSequencer) { TDebug.out("AlsaSequencer.isRunning(): begin"); }		boolean bRunning = false;		if (isOpen())		{			updateQueueStatus();			int	nStatus = getQueueStatus().getStatus();			if (TDebug.TraceSequencer) { TDebug.out("AlsaSequencer.isRunning(): queue status: " + nStatus); }			bRunning = (nStatus != 0);		}		if (TDebug.TraceSequencer) { TDebug.out("AlsaSequencer.isRunning(): end"); }		return bRunning;	}	public void startRecording()	{		checkOpen(); // may throw IllegalStateException		m_bRecording = true;		start();	}	public void stopRecording()	{		checkOpen(); // may throw IllegalStateException		m_bRecording = false;	}	public boolean isRecording()	{		return m_bRecording;	}	// name should be: enableRecording	public void recordEnable(Track track, int nChannel)	{		// TODO: hacky		m_track = track;	}	// name should be: disableRecording	public void recordDisable(Track track)	{		// TODO:	}	protected void setTempoImpl(float fRealMPQ)	{		if (TDebug.TraceSequencer) { TDebug.out("AlsaSequencer.setTempoImpl(): begin"); }		if (isOpen())		{			if (TDebug.TraceSequencer) { TDebug.out("AlsaSequencer.setTempoImpl(): setting tempo to " + (int) fRealMPQ); }			getQueueTempo().setTempo((int) fRealMPQ);			getQueueTempo().setPpq(getResolution());			getPlaybackAlsaSeq().setQueueTempo(getQueue(), getQueueTempo());		}		else		{			if (TDebug.TraceSequencer) { TDebug.out("AlsaSequencer.setTempoImpl(): ignoring because sequencer is not opened"); }			m_fCachedRealMPQ = fRealMPQ;		}		if (TDebug.TraceSequencer) { TDebug.out("AlsaSequencer.setTempoImpl(): end"); }	}	public long getTickPosition()	{		if (TDebug.TraceSequencer) { TDebug.out("AlsaSequencer.getTickPosition(): begin"); }		long	lPosition;		if (isOpen())		{			updateQueueStatus();			lPosition = getQueueStatus().getTickTime();		}		else		{			if (TDebug.TraceSequencer) { TDebug.out("AlsaSequencer.getTickPosition(): sequencer not open, returning 0"); }			lPosition = 0;		}		if (TDebug.TraceSequencer) { TDebug.out("AlsaSequencer.getTickPosition(): end"); }		return lPosition;	}	public void setTickPosition(long lTick)	{		if (TDebug.TraceSequencer) { TDebug.out("AlsaSequencer.setTickPosition(): begin"); }		if (isOpen())		{			int	nSourcePort = getRecordingPort();			int	nQueue = getQueue();			long	lTime = lTick;			sendQueueControlEvent(				AlsaSeq.SND_SEQ_EVENT_SETPOS_TICK,				AlsaSeq.SND_SEQ_TIME_STAMP_REAL | AlsaSeq.SND_SEQ_TIME_MODE_REL, 0, AlsaSeq.SND_SEQ_QUEUE_DIRECT, 0L,				nSourcePort, AlsaSeq.SND_SEQ_CLIENT_SYSTEM, AlsaSeq.SND_SEQ_PORT_SYSTEM_TIMER,				nQueue, 0, lTime);		}		else		{			if (TDebug.TraceSequencer) { TDebug.out("AlsaSequencer.setTickPosition(): ignored because sequencer is not open"); }		}		if (TDebug.TraceSequencer) { TDebug.out("AlsaSequencer.setTickPosition(): end"); }	}	public long getMicrosecondPosition()	{		if (TDebug.TraceSequencer) { TDebug.out("AlsaSequencer.getMicrosecondPosition(): begin"); }		long	lPosition;		if (isOpen())		{			updateQueueStatus();			long	lNanoSeconds = getQueueStatus().getRealTime();			lPosition = lNanoSeconds / 1000;		}		else		{			if (TDebug.TraceSequencer) { TDebug.out("AlsaSequencer.getMicrosecondPosition(): sequencer not open, returning 0"); }			lPosition = 0;		}		if (TDebug.TraceSequencer) { TDebug.out("AlsaSequencer.getMicrosecondPosition(): end"); }		return lPosition;	}	public void setMicrosecondPosition(long lMicroseconds)	{		if (TDebug.TraceSequencer) { TDebug.out("AlsaSequencer.setMicrosecondPosition(): begin"); }		if (isOpen())		{			long	lNanoSeconds = lMicroseconds * 1000;			int	nSourcePort = getRecordingPort();			int	nQueue = getQueue();			long	lTime = lNanoSeconds;			sendQueueControlEvent(				AlsaSeq.SND_SEQ_EVENT_SETPOS_TIME,				AlsaSeq.SND_SEQ_TIME_STAMP_REAL | AlsaSeq.SND_SEQ_TIME_MODE_REL, 0, AlsaSeq.SND_SEQ_QUEUE_DIRECT, 0L,				nSourcePort, AlsaSeq.SND_SEQ_CLIENT_SYSTEM, AlsaSeq.SND_SEQ_PORT_SYSTEM_TIMER,				nQueue, 0, lTime);		}		else		{			if (TDebug.TraceSequencer) { TDebug.out("AlsaSequencer.setMicrosecondPosition(): ignoring because sequencer is not open"); }		}		if (TDebug.TraceSequencer) { TDebug.out("AlsaSequencer.setMicrosecondPosition(): end"); }	}	protected void setMasterSyncModeImpl(SyncMode syncMode)	{		// TODO:	}	protected void setSlaveSyncModeImpl(SyncMode syncMode)	{		if (isRunning())		{			if (m_oldSlaveSyncMode.equals(Sequencer.SyncMode.NO_SYNC) && (syncMode.equals(Sequencer.SyncMode.MIDI_SYNC) || syncMode.equals(Sequencer.SyncMode.MIDI_TIME_CODE)) )			{				sendStartEvent();				// TODO: notify sync thread 			}			else if ((m_oldSlaveSyncMode.equals(Sequencer.SyncMode.MIDI_SYNC) || m_oldSlaveSyncMode.equals(Sequencer.SyncMode.MIDI_TIME_CODE)) && syncMode.equals(Sequencer.SyncMode.NO_SYNC) )			{				sendStopEvent();				// TODO: remove enqueued messages from queue (and buffer). perhaps do this by putting the code to do so after the main loop of the sync thread.			}		}	}	protected void setTrackEnabledImpl(int nTrack, boolean bEnabled)	{		/**	If the enabled state changes to true, the events			between	the current playback position and the current			loading position are enqueued.			If the enabled state of a track changed to false,			the events belonging to this track are removed from			the queue, besides the 'off'-events.		*/		if (bEnabled)		{			// TODO: reload events		}		else		{			// TODO: remove events

⌨️ 快捷键说明

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