📄 vojxtacallcontrol.java
字号:
/* * VoJxtaCallControl.java * * Created on March 3, 2005, 3:38 AM */package net.jxta.myjxta.plugins.vojxta;import net.jxta.endpoint.ByteArrayMessageElement;import net.jxta.endpoint.MessageElement;import net.jxta.endpoint.StringMessageElement;import net.jxta.logging.Logging;import net.jxta.myjxta.MyJXTA;import net.jxta.myjxta.View;import net.jxta.myjxta.dialog.Dialog;import net.jxta.myjxta.dialog.DialogMessage;import java.util.Date;import java.util.HashMap;import java.util.Hashtable;import java.util.Iterator;import java.util.logging.Level;import java.util.logging.Logger;/** * @author Jeff Moore * @version .1 * @modified 2005-03-28 jamoore : add call control protocol * @modified 2005-03-03 jamoore : add audio control accessors * @modified 2005-03-10 jamoore : add hold, resume to protocol * @modified 2005-03-14 jamoore : add quality map for user selectable quality * @modified 2005-03-15 jamoore : add quality element to start session command * @modified 2005-03-16 jamoore : add accessors for statistics * @modified 2005-03-26 jamoore : add MessageAckThread, ReceivedMessageTimeout thread */public final class VoJxtaCallControl { /** * Time to wait for response after a command (not voice) message is sent * out. Default is 10 seconds. */ private static final long DEFAULT_MESSAGE_ACK_TIMEOUT = 20000; /** * Minimum time we will wait till a message ack comes back */ private static final long MINIMUM_MESSAGE_ACK_TIMEOUT = 2000; /** * Tag for an element element carrying voice data */ public static final String TAG_VOICE_DATA = "VoiceData"; /** * Element tag denoting a message containing vojxta session command data */ public static final String TAG_SESSION_COMMAND = "VoJxtaSessionCommand"; public static final String TAG_QUALITY_ELEMENT = "VoJxtaVoiceQuality"; /** * commands sent btn peers managing the vojxta session */ public static final String COMMAND_VOJXTA_INVITE_REQUEST = "VoJxtaInviteRequest"; public static final String COMMAND_VOJXTA_INVITE_ACCEPT = "VoJxtaInviteAccept"; public static final String COMMAND_VOJXTA_START_REQUEST = "VoJxtaStartRequest"; public static final String COMMAND_VOJXTA_START_ACCEPT = "VoJxtaStartAccept"; public static final String COMMAND_VOJXTA_DATA = "VoJxtaData"; public static final String COMMAND_VOJXTA_HOLD_REQUEST = "VoJxtaHoldRequest"; public static final String COMMAND_VOJXTA_HOLD_ACCEPT = "VoJxtaHoldAccept"; public static final String COMMAND_VOJXTA_RESUME_REQUEST = "VoJxtaResumeRequest"; public static final String COMMAND_VOJXTA_RESUME_ACCEPT = "VoJxtaResumeAccept"; public static final String COMMAND_VOJXTA_HANGUP_REQUEST = "VoJxtaHangUpRequest"; public static final String COMMAND_VOJXTA_HANGUP_ACCEPT = "VoJxtaHangUpAccept"; public static final String COMMAND_VOJXTA_DISCONNECT_REQUEST = "VoJxtaDisconnectRequest"; public static final String COMMAND_VOJXTA_DISCONNECT_ACCEPT = "VoJxtaDisconnectAccept"; /** * internal session state */ public static final int SESSION_VOJXTA_DISCONNECTED = 10; public static final int SESSION_VOJXTA_DISCONNECTING = 11; public static final int SESSION_VOJXTA_CONNECTED = 12; public static final int SESSION_VOJXTA_CONNECTING = 13; public static final int SESSION_VOJXTA_STARTING = 20; public static final int SESSION_VOJXTA_STARTED = 30; public static final int SESSION_VOJXTA_ENDING = 40; public static final int SESSION_VOJXTA_ENDED = 50; public static final int SESSION_VOJXTA_INCALL = 100; public static final int SESSION_VOJXTA_HOLDING = 110; public static final int SESSION_VOJXTA_DISCONNECT_REQUEST_SENT = 210; public static final int SESSION_VOJXTA_DISCONNECT_REQUEST_RECEIVED = 220; public static final int SESSION_VOJXTA_DISCONNECT_ACCEPT_SENT = 230; public static final int SESSION_VOJXTA_DISCONNECT_ACCEPT_RECEIVED = 240; public static final int SESSION_VOJXTA_RESUME_REQUEST_SENT = 250; public static final int SESSION_VOJXTA_RESUME_REQUEST_RECEIVED = 260; public static final int SESSION_VOJXTA_RESUME_ACCEPT_SENT = 270; public static final int SESSION_VOJXTA_RESUME_ACCEPT_RECEIVED = 280; public static final int SESSION_VOJXTA_HOLD_ACCEPT_SENT = 290; public static final int SESSION_VOJXTA_HOLD_ACCEPT_RECEIVED = 310; public static final int SESSION_VOJXTA_HOLD_REQUEST_SENT = 320; public static final int SESSION_VOJXTA_HOLD_REQUEST_RECEIVED = 330; public static final int SESSION_VOJXTA_START_REQUEST_SENT = 340; public static final int SESSION_VOJXTA_START_REQUEST_RECEIVED = 350; public static final int SESSION_VOJXTA_START_ACCEPT_SENT = 360; public static final int SESSION_VOJXTA_START_ACCEPT_RECEIVED = 370; public static final int SESSION_VOJXTA_HANGUP_ACCEPT_RECEIVED = 380; public static final int SESSION_VOJXTA_HANGUP_ACCEPT_SENT = 390; public static final int SESSION_VOJXTA_HANGUP_REQUEST_RECEIVED = 410; public static final int SESSION_VOJXTA_HANGUP_REQUEST_SENT = 420; public static final int SESSION_VOJXTA_INVITE_REQUEST_SENT = 430; public static final int SESSION_VOJXTA_INVITE_REQUEST_RECEIVED = 440; public static final int SESSION_VOJXTA_INVITE_ACCEPT_SENT = 450; public static final int SESSION_VOJXTA_INVITE_ACCEPT_RECEIVED = 460; public int sessionState = SESSION_VOJXTA_DISCONNECTED; public int protocolState = SESSION_VOJXTA_DISCONNECTED; public static final int MINIMUM_QUALITY = 0; public static final int MAXIMUM_QUALITY = 10; public static final int DEFAULT_QUALITY = 1; public static final long SECOND = 1000; public static final long MINUTE = SECOND * 60; public static final long HOUR = MINUTE * 60; public static final String TIME_SEPARATOR = ":"; private int localVoiceQuality = DEFAULT_QUALITY; private int remoteVoiceQuality = DEFAULT_QUALITY; private long messageAckTimeout = DEFAULT_MESSAGE_ACK_TIMEOUT; private Dialog vojxtaDialog = null; private View view = null; private MyJXTA controller = null; private DialogMessage templateMessage = null; private VoJxtaDialogView vojxtaView = null; private static final int CONNECT_SLEEP_TIME = 200; private boolean sessionPersisted = false; private String sessionFileName = null; static final Logger LOG = Logger.getLogger(VoJxtaCallControl.class.getName()); private long callStartTime = 0; private long callEndTime = 0; private long callElapsedTime = 0; /** * audio device OUT */ private VoiceSpeakerOutput speakerControl = null; /** * audio device IN */ private VoiceMicrophoneInput micControl = null; private final boolean locallyInitiated = false; private ReceivedMessageTimeoutThread receiveTimeoutThread = null; /** * started on command message dispatch. waits for ack to message (notofy) * then dies */ private MessageAckThread messageAckThread = null; public static final Hashtable qualityByteMap = new Hashtable(); /** This maps quality level to encoded message byte size gleaned from * speex. Do it this way allows us to dynamically change quality in a session * as well as alowing the user to select quality at session start */ static { qualityByteMap.put(new Integer(0), new Integer(10)); qualityByteMap.put(new Integer(1), new Integer(15)); qualityByteMap.put(new Integer(2), new Integer(20)); qualityByteMap.put(new Integer(3), new Integer(25)); qualityByteMap.put(new Integer(4), new Integer(32)); qualityByteMap.put(new Integer(5), new Integer(42)); qualityByteMap.put(new Integer(6), new Integer(52)); qualityByteMap.put(new Integer(7), new Integer(60)); qualityByteMap.put(new Integer(8), new Integer(70)); qualityByteMap.put(new Integer(9), new Integer(86)); qualityByteMap.put(new Integer(10), new Integer(106)); } /** * Creates a new instance of VojxtaCallControl */ public VoJxtaCallControl(VoJxtaDialogView vojxtaView, View p_view, Dialog dialog, boolean locallyInitiated) { LOG.setLevel(Level.INFO); this.vojxtaView = vojxtaView; this.vojxtaDialog = dialog; // wait for pipes to connect if (this.vojxtaDialog != null) { new Thread(new Runnable() { public void run() { while (!VoJxtaCallControl.this.vojxtaDialog.isConnected()) { try { Thread.sleep(CONNECT_SLEEP_TIME); if (Logging.SHOW_INFO && LOG.isLoggable(Level.INFO)) { LOG.info("Waiting for is connected "); } } catch (InterruptedException ignored) { } } } }, getClass().getName() + ":isConnected").start(); } this.view = p_view; this.controller = p_view.getControl(); if (!this.vojxtaDialog.isConnected()) { if (Logging.SHOW_INFO && LOG.isLoggable(Level.INFO)) { LOG.info("Constructor : VoJxtaDialog NOT connected!! Resources released. Module Shutdown."); } } else { if (Logging.SHOW_INFO && LOG.isLoggable(Level.INFO)) { LOG.info("Constructor : VoJxtaDialog Connected!! Obtaining Resources. Starting Module"); } this.speakerControl = new VoiceSpeakerOutput(this); this.micControl = new VoiceMicrophoneInput(this); templateMessage = new DialogMessage(this.vojxtaDialog.getGroup() .getPeerGroup().getPeerName(), null, this.vojxtaDialog.getGroup() .getPeerGroup().getPeerGroupID().toString(), this.vojxtaDialog .getGroup().getPeerGroup().getPeerGroupName()); } }//constructor /** * A templete DialogMessage is already constructed. All we need do is call * this method and clone. This will cleanup the code for message production * as well offer the possibility of a speedup in message creation. * * @return templeted DialogMessage */ public DialogMessage getTemplateMessage() { return this.templateMessage; } public String getOriginator() { return speakerControl.getOriginator(); } /** The following methods are offered as an interface to the UI for any * statistics we can gather. */ /** * Returns the system time in ms this call was started. Only valid after * call ha started */ public long getCallStartTime() { return callStartTime; } /** * Returns a formated string of the call start time */ public String getCallStartTimeString() { return new Date(callStartTime).toString(); } /** * Returns the system time is ms this call ended. Is only valid after call * has ended. */ public long getCallEndTime() { return callEndTime; } /** * Returns a formated string of hte call end time. */ public String getCallEndTimeString() { return ((callEndTime != 0) ? new Date(callEndTime).toString() : ""); } /** * Returns the time elapsed in ms from call start time. Only valid after * call has started */ public long getCallElapsedTime() { return callElapsedTime = System.currentTimeMillis() - getCallStartTime(); } /** * Returns formated string of the call elapsed time */ public String getCallElapseTimeString() { return formatElapsedTime(getCallElapsedTime()); } /** * Returns the size of outgoing messages. Outgoing messages are those that * have been encoded and are ready for delivery */ public int getEncodeMessageSize() { return micControl.getEncodedMessageSize(); } /** * Returns the size of the FIFO byte buffer holding encoded messages that * ready for delivery. */ public int getEncodeBufferSize() { return micControl.getEncodedBufferSize(); } /** * Returns the quality of voice encoding performed on audio in blocks. */ public int getQualityOfService() { return micControl.getEncodeQuality(); } /** * Returns the ratio as int of raw audio in block to encoded audio blocks */ public int getCompressionRatio() { int blockSize = micControl.getEncodedBlockSize(); if (blockSize == 0) { blockSize = 1; } return micControl.getAudioBlockSize() / blockSize; } /** * Returns the average time it takes to encode raw bytes from audio in. */ public int getAverageEncodeTime() { return micControl.getAverageEncodeTime(); } /** * Returns the average time it takes to decode encoded bytes from pipe in */ public long getAverageDecodeTime() { return speakerControl.getAverageDecodeTime(); } /** * Returns a string formated to represent hours:minutes:seconds of the time * elapsed since call start. */ protected String formatElapsedTime(long elapsedTime) { long tmp = elapsedTime; long hours = tmp / HOUR; tmp = tmp - (hours * HOUR); long minutes = tmp / MINUTE; tmp = tmp - (minutes * MINUTE); long seconds = tmp / SECOND; String timeString = null; if (hours < 10) { timeString = "0"; } timeString = String.valueOf(hours) + this.TIME_SEPARATOR; ; if (minutes < 10) { timeString = timeString + "0"; } timeString = timeString + String.valueOf(minutes) + this.TIME_SEPARATOR; if (seconds < 10) { timeString = timeString + "0"; } timeString = timeString + String.valueOf(seconds); return timeString; } /** * Sets the size of the outgoing buffer holding encoded audio blocks. This * Should be adjusted along with the encoded message size or a buffer * overflow could occur. */ public void setOutgoingEncodedBufferSize(int bufferSize) { micControl.setEncodedBufferSize(bufferSize); } /** * Sets the size of the incoming buffer holding encoded audio blocks. This * should be adjusted along with the encoded message size or a buffer * overflow could occur. */ public void setIncomingEncodedBufferSize(int bufferSize) { speakerControl.setEncodedBufferSize(bufferSize); } /** * Returns the size of the outgoing buffer holding the encoded audio * blocks. */ public int getOutgoingEncodedBufferSize() { return micControl.getEncodedBufferSize(); } /** * Returns the size of the incoming buffer holding the encoded audio * blocks */ public int getIncomingEncodedBufferSize() { return speakerControl.getEncodedBufferSize();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -