Commit 1619ea4d authored by Dele Olajide's avatar Dele Olajide Committed by dele

First upload of Rayo Plugin

git-svn-id: http://svn.igniterealtime.org/svn/repos/openfire/trunk@13749 b35dd754-fafc-0310-a699-88a17e54d16e
parent a79899d5
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Rayo Plugin Changelog</title>
<style type="text/css">
BODY {
font-size: 100%;
}
BODY, TD, TH {
font-family: tahoma, verdana, arial, helvetica, sans-serif;
font-size: 0.8em;
}
H2 {
font-size: 10pt;
font-weight: bold;
padding-left: 1em;
}
A:hover {
text-decoration: none;
}
H1 {
font-family: tahoma, arial, helvetica, sans-serif;
font-size: 1.4em;
font-weight: bold;
border-bottom: 1px #ccc solid;
padding-bottom: 2px;
}
TT {
font-family: courier new;
font-weight: bold;
color: #060;
}
PRE {
font-family: courier new;
font-size: 100%;
}
</style>
</head>
<body>
<h1>
Rayo Plugin Changelog
</h1>
<p><b>0.0.1</b> -- June 1, 2013</p>
<ul>
<li>Initial release.</li>
</ul>
</body>
</html>
<?xml version="1.0" encoding="UTF-8"?>
<plugin>
<class>org.ifsoft.rayo.RayoPlugin</class>
<name>Rayo Plugin</name>
<description>Provides support for XEP-0327</description>
<author>Ignite Realtime Community</author>
<version>0.0.1</version>
<date>2/6/2013</date>
<minServerVersion>3.8.1</minServerVersion>
<adminconsole>
<tab id="tab-server">
<sidebar id="siderbar-rayo" name="${admin.item.rayo}">
<item id="rayo" name="${admin.item.rayo.settings.name}"
description="${admin.item.rayo.settings.description}" url="rayo.jsp"/>
</sidebar>
</tab>
</adminconsole>
</plugin>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Rayo Plugin Readme</title>
<style type="text/css">
BODY {
font-size: 100%;
}
BODY, TD, TH {
font-family: tahoma, verdana, arial, helvetica, sans-serif;
font-size: 0.8em;
}
H2 {
font-size: 10pt;
font-weight: bold;
}
A:hover {
text-decoration: none;
}
H1 {
font-family: tahoma, arial, helvetica, sans-serif;
font-size: 1.4em;
font-weight: bold;
border-bottom: 1px #ccc solid;
padding-bottom: 2px;
}
TT {
font-family: courier new;
font-weight: bold;
color: #060;
}
PRE {
font-family: courier new;
font-size: 100%;
}
</style>
</head>
<body>
<h1>
Rayo Plugin Readme
</h1>
<h2>Overview</h2>
<p>
XEP-0327: Rayo defines an XMPP protocol extension for the third-party control of telephone calls and other similar media sessions. The protocol includes support for session management/signaling, as well as advanced media resources such as speech recognizers, speech synthesizers and audio/video recorders. The protocol serves a different purpose from that of first-party protocols such as Jingle or SIP, and is compatible with those protocols.
</p>
<h2>Installation</h2>
<p>Make sure Openfire is running on a Public IP interface and with Firewall opened for UDP Traffic both ways on port
range 30000 to 50000.</p>
</body>
</html>
login.title = Admin Console
admin.item.rayo=Rayo
admin.item.rayo.settings.name=Rayo Status
admin.item.rayo.settings.description=XEP-0327:XMPP protocol extension for the third-party control of telephone calls and other similar media sessions.
rayo.verified.ip=Verified Public IP
rayo.active.channels=Active Channels
rayo.settings.title=Rayo Status
rayo.verified.ip.warning=Rayo Requires a Public IP. Public IP Found:
rayo.settings.update.settings =Update Settings
rayo.settings.overrideip= Override Public IP
rayo.settings.invalid.publicip =Invalid Public IP Address
\ No newline at end of file
package com.rayo.core.verb;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
public class Handset extends BaseVerb {
public static final String MISSING_CRYPTO_SUITE = "Missing Crypto Suite";
public static final String MISSING_LOCAL_CRYPTO = "Missing Local Crypto";
public static final String MISSING_REMOTE_CRYPTO = "Missing Remote Crypto";
public static final String MISSING_MIXER = "Missing Mixer";
public static final String MISSING_CODEC = "Missing Codec";
public static final String MISSING_STEREO = "Missing Stereo";
@NotNull(message=Handset.MISSING_CRYPTO_SUITE)
public String cryptoSuite;
@NotNull(message=Handset.MISSING_LOCAL_CRYPTO)
public String localCrypto;
@NotNull(message=Handset.MISSING_REMOTE_CRYPTO)
public String remoteCrypto;
@NotNull(message=Handset.MISSING_MIXER)
public String mixer;
@NotNull(message=Handset.MISSING_CODEC)
public String codec;
@NotNull(message=Handset.MISSING_STEREO)
public String stereo;
public Handset(String cryptoSuite, String localCrypto, String remoteCrypto, String mixer, String codec, String stereo)
{
this.cryptoSuite = cryptoSuite;
this.localCrypto = localCrypto;
this.remoteCrypto = remoteCrypto;
this.mixer = mixer;
this.codec = codec;
this.stereo = stereo;
}
@Override
public String toString() {
return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
.append("callId", getCallId())
.append("verbId", getVerbId())
.append("cryptoSuite",cryptoSuite)
.append("localCrypto",localCrypto)
.append("remoteCrypto",remoteCrypto)
.append("mixer",mixer)
.append("codec",codec)
.append("stereo",stereo)
.toString();
}
}
package com.rayo.core.verb;
public class OffHookCommand extends AbstractVerbCommand {
}
package com.rayo.core.verb;
public class OnHookCommand extends AbstractVerbCommand {
}
package com.rayo.core.xml.providers;
import java.net.URISyntaxException;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Namespace;
import org.dom4j.QName;
import com.rayo.core.verb.OnHookCommand;
import com.rayo.core.verb.OffHookCommand;
import com.rayo.core.verb.Handset;
import com.rayo.core.verb.SayCompleteEvent;
import com.rayo.core.verb.SayCompleteEvent.Reason;
public class HandsetProvider extends BaseProvider {
// XML -> Object
// ================================================================================
private static final Namespace NAMESPACE = new Namespace("", "urn:xmpp:rayo:handset:1");
private static final Namespace COMPLETE_NAMESPACE = new Namespace("", "urn:xmpp:rayo:handset:complete:1");
private static final QName ONHOOK_QNAME = new QName("onhook", NAMESPACE);
private static final QName OFFHOOK_QNAME = new QName("offhook", NAMESPACE);
@Override
protected Object processElement(Element element) throws Exception
{
if (element.getName().equals("handset")) {
return buildHandset(element);
} else if (ONHOOK_QNAME.equals(element.getQName())) {
return buildOnHookCommand(element);
} else if (OFFHOOK_QNAME.equals(element.getQName())) {
return buildOffHookCommand(element);
} else if (element.getNamespace().equals(RAYO_COMPONENT_NAMESPACE)) {
return buildCompleteCommand(element);
}
return null;
}
private Object buildCompleteCommand(Element element) {
Element reasonElement = (Element)element.elements().get(0);
String reasonValue = reasonElement.getName().toUpperCase();
Reason reason = Reason.valueOf(reasonValue);
SayCompleteEvent complete = new SayCompleteEvent();
complete.setReason(reason);
return complete;
}
private Object buildHandset(Element element) throws URISyntaxException
{
Handset handset = new Handset( element.attributeValue("cryptoSuite"),
element.attributeValue("localCrypto"),
element.attributeValue("remoteCrypto"),
element.attributeValue("mixer"),
element.attributeValue("codec"),
element.attributeValue("stereo"));
return handset;
}
private Object buildOnHookCommand(Element element) throws URISyntaxException {
return new OnHookCommand();
}
private Object buildOffHookCommand(Element element) throws URISyntaxException {
return new OffHookCommand();
}
// Object -> XML
// ================================================================================
@Override
protected void generateDocument(Object object, Document document) throws Exception {
if (object instanceof Handset) {
createHandset((Handset) object, document);
} else if (object instanceof OnHookCommand) {
createOnHookCommand((OnHookCommand) object, document);
} else if (object instanceof OffHookCommand) {
createOffHookCommand((OffHookCommand) object, document);
} else if (object instanceof SayCompleteEvent) {
createHandsetCompleteEvent((SayCompleteEvent) object, document);
}
}
private void createHandset(Handset handset, Document document) throws Exception {
Element root = document.addElement(new QName("handset", NAMESPACE));
root.addAttribute("cryptoSuite", handset.cryptoSuite);
root.addAttribute("localCrypto", handset.localCrypto);
root.addAttribute("remoteCrypto", handset.cryptoSuite);
root.addAttribute("mixer", handset.mixer);
root.addAttribute("codec", handset.codec);
root.addAttribute("stereo", handset.stereo);
}
private void createOnHookCommand(OnHookCommand command, Document document) throws Exception {
document.addElement(new QName("onhook", NAMESPACE));
}
private void createOffHookCommand(OffHookCommand command, Document document) throws Exception {
document.addElement(new QName("offhook", NAMESPACE));
}
private void createHandsetCompleteEvent(SayCompleteEvent event, Document document) throws Exception {
addCompleteElement(document, event, COMPLETE_NAMESPACE);
}
}
This diff is collapsed.
/*
* Copyright 2007 Sun Microsystems, Inc.
*
* This file is part of jVoiceBridge.
*
* jVoiceBridge is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation and distributed hereunder
* to you.
*
* jVoiceBridge 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
* Sun designates this particular file as subject to the "Classpath"
* exception as provided by Sun in the License file that accompanied this
* code.
*/
package com.sun.voip;
import java.io.IOException;
/*
* Interface for an audio data source.
* Implementations are DotAuAudioSource and LinearDataAudioSource.
* Another implemention might generate sine waves.
*/
public interface AudioSource {
public static final int ULAW = 1;
public static final int LINEAR = 3;
public int[] getLinearData(int sampleTime) throws IOException;
public void rewind() throws IOException;
public void done();
public int getSampleRate();
public int getChannels();
}
/*
* Copyright 2007 Sun Microsystems, Inc.
*
* This file is part of jVoiceBridge.
*
* jVoiceBridge is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation and distributed hereunder
* to you.
*
* jVoiceBridge 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
* Sun designates this particular file as subject to the "Classpath"
* exception as provided by Sun in the License file that accompanied this
* code.
*/
package com.sun.voip;
public class BridgeVersion {
private static String version = "SIPDialer/1.0";
private BridgeVersion() {
}
public static String getVersion() {
return version;
}
}
/*
* Copyright 2007 Sun Microsystems, Inc.
*
* This file is part of jVoiceBridge.
*
* jVoiceBridge is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation and distributed hereunder
* to you.
*
* jVoiceBridge 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
* Sun designates this particular file as subject to the "Classpath"
* exception as provided by Sun in the License file that accompanied this
* code.
*/
package com.sun.voip;
import java.net.InetSocketAddress;
public class CallEvent {
public static final int NEW_CONNECTION = 0;
public static final int STATE_CHANGED = 1;
public static final int NO_SUCH_WHISPER_GROUP = 2;
public static final int JOIN_TIMEOUT = 3;
public static final int CALL_ANSWER_TIMEOUT = 4;
public static final int NUMBER_OF_CALLS = 5;
public static final int TREATMENT_DONE = 6;
public static final int STARTED_SPEAKING = 7;
public static final int STOPPED_SPEAKING = 8;
public static final int DTMF_KEY = 9;
public static final int MIGRATED = 10;
public static final int MIGRATION_FAILED = 11;
public static final int CALL_TRANSFERRED = 12;
public static final int BUSY_HERE = 13;
public static final int CANT_START_CONFERENCE = 14;
public static final int CANT_CREATE_MEMBER = 15;
public static final int H323_NOT_IMPLEMENTED = 16;
public static final int INFO = 17;
private static final int LAST_EVENT = 17;
private static String[] eventString = {
"000 New Connection",
"001 STATE CHANGED",
"050 NO SUCH WHISPER GROUP",
"120 JOIN CONFIRMATION TIMEOUT",
"127 CALL ANSWER TIMEOUT",
"220 NUMBER OF CALLS",
"230 TREATMENT DONE",
"250 STARTED SPEAKING",
"259 STOPPED SPEAKING",
"269 DTMF",
"270 MIGRATED",
"275 MIGRATION FAILED no answer",
"279 CALL TRANSFERRED",
"486 Busy Here",
"900 Can't start conference",
"910 Can't create member",
"920 H323 is not implemented",
""
};
private int event;
private String info;
private String callId;
private String conferenceId;
private String callInfo;
private CallState callState;
private boolean startedSpeaking;
private boolean stoppedSpeaking;
private String dtmfKey;
private String treatmentId;
private int numberOfCalls;
public CallEvent(int event) {
this.event = event;
info = "";
}
public CallEvent(String s) {
for (int i = 0; i < LAST_EVENT; i++) {
int ix;
if ((ix = s.indexOf(eventString[i])) < 0) {
continue;
}
event = i;
s = s.substring(ix + eventString[i].length() + 1);
info = getInfo(s);
if ((callId = getValue(s, "CallId=")) == null) {
break;
}
if ((conferenceId = getValue(s, "ConferenceId=")) == null) {
break;
}
if ((callInfo = getValue(s, "CallInfo=")) == null) {
break;
}
return;
}
event = INFO;
info = s;
}
private String getInfo(String s) {
int ix = s.indexOf("CallId=");
if (ix <= 0) {
return "";
}
return s.substring(0, ix);
}
private String getValue(String s, String key) {
int ix;
if ((ix = s.indexOf(key)) < 0) {
if (Logger.logLevel >= Logger.LOG_INFO) {
Logger.println("Missing " + key + ": " + s);
}
return null;
}
if (ix > 0) {
info = s.substring(0, ix);
}
if ((ix = s.indexOf("'")) < 0) {
Logger.println("Missing quote: " + s);
return null;
}
s = s.substring(ix + 1);
if ((ix = s.indexOf("'")) < 0) {
Logger.println("Missing quote: " + s);
return null;
}
return s.substring(0, ix);
}
public int getEvent() {
return event;
}
public void setInfo(String info) {
this.info = info;
if (this.info == null) {
this.info = "";
}
}
public String getInfo() {
return info;
}
public void setCallId(String callId) {
this.callId = callId;
}
public String getCallId() {
return callId;
}
public void setConferenceId(String conferenceId) {
this.conferenceId = conferenceId;
}
public String getConferenceId() {
return conferenceId;
}
public void setCallInfo(String callInfo) {
this.callInfo = callInfo;
}
public String getCallInfo() {
return callInfo;
}
public void setCallState(CallState callState) {
this.callState = callState;
}
public CallState getCallState() {
return callState;
}
public void setStartedSpeaking() {
startedSpeaking = true;
}
public boolean startedSpeaking() {
return startedSpeaking;
}
public void setStoppedSpeaking() {
stoppedSpeaking = true;
}
public boolean stoppedSpeaking() {
return stoppedSpeaking;
}
public void setDtmfKey(String dtmfKey) {
this.dtmfKey = dtmfKey;
}
public String getDtmfKey() {
return dtmfKey;
}
public void setTreatmentId(String treatmentId) {
this.treatmentId = treatmentId;
}
public String getTreatmentId() {
return treatmentId;
}
public void setNumberOfCalls(int numberOfCalls) {
this.numberOfCalls = numberOfCalls;
}
public int getNumberOfCalls() {
return numberOfCalls;
}
public boolean equals(int event) {
return this.event == event;
}
public static String getEventString(int event) {
if (event < 0 || event > LAST_EVENT) {
return "Invalid Event: " + event;
}
return eventString[event];
}
public String toString() {
if (event < 0 || event > LAST_EVENT) {
return "Invalid Event: " + event;
}
String s = eventString[event];
if (event == STATE_CHANGED) {
s = callState.toString();
}
if (info != null && info.length() > 0) {
s += " " + info;
}
if (event == DTMF_KEY) {
s += " DTMFKey='" + dtmfKey + "'";
} else if (event == TREATMENT_DONE) {
s += " Treatment='" + treatmentId + "'";
} else if (event == NUMBER_OF_CALLS) {
s += " NumberOfCalls='" + numberOfCalls + "'";
}
if (callId != null && callId.length() > 0) {
s += " CallId='" + callId + "'";
}
if (conferenceId != null && conferenceId.length() > 0) {
s += " ConferenceId='" + conferenceId +"'";
}
if (callInfo != null && callInfo.length() > 0) {
s += " CallInfo='" + callInfo + "'";
}
return BridgeVersion.getVersion() + " " + s;
}
}
/*
* Copyright 2007 Sun Microsystems, Inc.
*
* This file is part of jVoiceBridge.
*
* jVoiceBridge is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation and distributed hereunder
* to you.
*
* jVoiceBridge 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
* Sun designates this particular file as subject to the "Classpath"
* exception as provided by Sun in the License file that accompanied this
* code.
*/
package com.sun.voip;
/**
* Get notification of call events
*/
public interface CallEventListener {
void callEventNotification(CallEvent event);
}
This diff is collapsed.
/*
* Copyright 2007 Sun Microsystems, Inc.
*
* This file is part of jVoiceBridge.
*
* jVoiceBridge is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation and distributed hereunder
* to you.
*
* jVoiceBridge 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
* Sun designates this particular file as subject to the "Classpath"
* exception as provided by Sun in the License file that accompanied this
* code.
*/
package com.sun.voip;
/*
* Call state
*/
public class CallState {
public static final int UNINITIALIZED = 0;
public static final int INVITED = 1;
public static final int ANSWERED = 2;
public static final int ESTABLISHED = 3;
public static final int ENDING = 4;
public static final int ENDED = 5;
public static final int INCOMING = 6;
private static final int LAST_STATE = 6;
private int state;
private String[] stateString = {
"000 UNINITIALIZED",
"100 INVITED",
"110 ANSWERED",
"200 ESTABLISHED",
"290 ENDING",
"299 ENDED"
};
public CallState() {
state = UNINITIALIZED;
}
public CallState(int state) {
this.state = state;
}
public int getState() {
return state;
}
public boolean equals(int state) {
return this.state == state;
}
public String toString() {
if (state < 0 || state > LAST_STATE) {
return ("Unknown state " + state);
}
return stateString[state];
}
}
/*
* Copyright 2007 Sun Microsystems, Inc.
*
* This file is part of jVoiceBridge.
*
* jVoiceBridge is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation and distributed hereunder
* to you.
*
* jVoiceBridge 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
* Sun designates this particular file as subject to the "Classpath"
* exception as provided by Sun in the License file that accompanied this
* code.
*/
package com.sun.voip;
/*
* Various strings of call status
*/
public class CallStatus {
public static final String UNINITIALIZED = "000 UNINITIALIZED";
public static final String NO_SUCH_WHISPER_GROUP = "050 NO SUCH WHISPER GROUP";
public static final String INVITED = "100 INVITED";
public static final String ANSWERED = "110 ANSWERED";
public static final String JOIN_TIMEOUT = "120 JOIN CONFIRMATION TIMEOUT";
public static final String CALL_ANSWER_TIMEOUT = "127 CALL ANSWER TIMEOUT";
public static final String ESTABLISHED = "200 ESTABLISHED";
public static final String NUMBER_OF_CALLS = "220 NUMBER OF CALLS";
public static final String TREATMENT_DONE = "230 TREATMENT DONE";
public static final String STARTED_SPEAKING = "250 STARTED SPEAKING";
public static final String STOPPED_SPEAKING = "259 STOPPED SPEAKING";
public static final String DTMF_KEY = "269 DTMF DTMFKey=";
public static final String MIGRATED = "270 MIGRATED";
public static final String MIGRATION_FAILED = "275 MIGRATION FAILED no answer";
public static final String ENDING = "290 ENDING";
public static final String ENDED = "299 ENDED";
public static final String BUSY_HERE = "486 Busy Here";
public static final String CANT_START_CONFERENCE = "900 Can't start conference";
public static final String CANT_CREATE_MEMBER = "910 Can't create member";
public static final String H323_NOT_IMPLEMENTED = "920 H323 is not implemented";
}
/*
* Copyright 2007 Sun Microsystems, Inc.
*
* This file is part of jVoiceBridge.
*
* jVoiceBridge is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation and distributed hereunder
* to you.
*
* jVoiceBridge 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
* Sun designates this particular file as subject to the "Classpath"
* exception as provided by Sun in the License file that accompanied this
* code.
*/
package com.sun.voip;
/**
* Get notification of call status changes
*/
public interface CallStatusListener {
public void callStatusNotification(String s);
}
/*
* Copyright 2007 Sun Microsystems, Inc.
*
* This file is part of jVoiceBridge.
*
* jVoiceBridge is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation and distributed hereunder
* to you.
*
* jVoiceBridge 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
* Sun designates this particular file as subject to the "Classpath"
* exception as provided by Sun in the License file that accompanied this
* code.
*/
package com.sun.voip;
import java.net.InetSocketAddress;
public class ConferenceEvent {
public static final int CONFERENCE_STARTED = 1;
public static final int CONFERENCE_ENDED = 2;
public static final int MEMBER_JOINED = 3;
public static final int MEMBER_LEFT = 4;
private int event;
private String conferenceId;
private String callId;
private InetSocketAddress memberAddress;
private boolean isDistributedBridge = false;
private int memberCount;
public ConferenceEvent(int event, String conferenceId) {
this.event = event;
this.conferenceId = conferenceId;
}
public int getEvent() {
return event;
}
public String getConferenceId() {
return conferenceId;
}
public void setCallId(String callId) {
this.callId = callId;
}
public String getCallId() {
return callId;
}
public void setMemberCount(int memberCount) {
this.memberCount = memberCount;
}
public int getMemberCount() {
return memberCount;
}
public void setMemberAddress(InetSocketAddress memberAddress) {
this.memberAddress = memberAddress;
}
public InetSocketAddress getMemberAddress() {
return memberAddress;
}
public void setIsDistributedBridge(boolean isDistributedBridge) {
this.isDistributedBridge = isDistributedBridge;
}
public boolean isDistributedBridge() {
return isDistributedBridge;
}
public boolean equals(int event) {
return this.event == event;
}
public String toString() {
String s;
switch (event) {
case CONFERENCE_STARTED:
s = "CONFERENCE_STARTED(" + event + ")"
+ ", conferenceId " + conferenceId;
break;
case CONFERENCE_ENDED:
s = "CONFERENCE_ENDED(" + event + ")"
+ ", conferenceId " + conferenceId;
break;
case MEMBER_JOINED:
s = "MEMBER_JOINED(" + event + ")"
+ ", conferenceId " + conferenceId
+ ", callId " + callId
+ ", count " + memberCount
+ ", memberAddress " + memberAddress;
break;
case MEMBER_LEFT:
s = "MEMBER_LEFT(" + event + ")"
+ ", conferenceId " + conferenceId
+ ", callId " + callId
+ ", count " + memberCount
+ ", memberAddress " + memberAddress;
break;
default:
s = "UNKNOWN ConferenceEevent(" + event + ")"
+ ", conferenceId " + conferenceId
+ ", callId " + callId
+ ", memberAddress " + memberAddress;
break;
}
return s;
}
}
/*
* Copyright 2007 Sun Microsystems, Inc.
*
* This file is part of jVoiceBridge.
*
* jVoiceBridge is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation and distributed hereunder
* to you.
*
* jVoiceBridge 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
* Sun designates this particular file as subject to the "Classpath"
* exception as provided by Sun in the License file that accompanied this
* code.
*/
package com.sun.voip;
import java.lang.reflect.*;
public class CurrentTime {
private CurrentTime() {
}
/*
* Return System.nanoTime() if running java 1.5
* Otherwise return System.currentTimeMillis()
*/
private static Method currentTime = null;
private static Class systemClass = null;
private static int timeUnitsPerSecond = 0;
public static long getTime() {
if (currentTime == null) {
try {
systemClass = Class.forName("java.lang.System");
} catch (Exception e) {
return System.currentTimeMillis(); // something is wrong
}
Method[] methods = systemClass.getMethods();
Method currentTimeMillis = null;
for (int i = 0; i < methods.length; i++) {
Method m = methods[i];
if (m.getName().equals("currentTimeMillis")) {
currentTimeMillis = m;
timeUnitsPerSecond = 1000;
} else if (m.getName().equals("nanoTime")) {
timeUnitsPerSecond = 1000000000;
currentTime = m;
}
}
if (currentTime == null) {
currentTime = currentTimeMillis;
}
if (currentTime == null) {
return System.currentTimeMillis();
}
}
try {
Long now = (Long) currentTime.invoke(systemClass, (Object[]) null);
return now.longValue();
} catch (Exception e) {
return System.currentTimeMillis();
}
}
public static double getElapsedSeconds(long start) {
double elapsed = getTime() - start;
return elapsed / timeUnitsPerSecond;
}
public static int getTimeUnitsPerSecond() {
if (timeUnitsPerSecond == 0) {
getTime();
}
return timeUnitsPerSecond;
}
public static String getTimeUnits() {
long time = CurrentTime.getTime(); // get time units
String s = "milliseconds";
if (timeUnitsPerSecond != 1000) {
s = "nanoseconds";
}
return s;
}
public static void main(String[] args) {
long time = CurrentTime.getTime();
int n = 100000;
if (args.length > 0) {
try {
n = Integer.parseInt(args[0]);
} catch (NumberFormatException e) {
System.out.println(
"invalid count specified. defaulting to " + n);
}
}
long totalTime = 0;
long start = CurrentTime.getTime();
long s = System.currentTimeMillis();
for (int i = 0; i < n; i++) {
long begin = CurrentTime.getTime();
totalTime += (CurrentTime.getTime() - begin);
}
try {
Thread.sleep(20);
} catch (InterruptedException e) {
}
System.out.println("Time units: " + getTimeUnits());
System.out.println("Average time to getTime(): "
+ ((double)totalTime / n / getTimeUnitsPerSecond()));
System.out.println ("elapsed using getTime() "
+ CurrentTime.getElapsedSeconds(start));
System.out.println ("elapsed using currentTimeMillis() "
+ (System.currentTimeMillis() - s));
}
}
/*
* Copyright 2007 Sun Microsystems, Inc.
*
* This file is part of jVoiceBridge.
*
* jVoiceBridge is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation and distributed hereunder
* to you.
*
* jVoiceBridge 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
* Sun designates this particular file as subject to the "Classpath"
* exception as provided by Sun in the License file that accompanied this
* code.
*/
package com.sun.voip;
public interface DataUpdater {
public int getData();
public void windowClosed();
}
/*
* Copyright 2007 Sun Microsystems, Inc.
*
* This file is part of jVoiceBridge.
*
* jVoiceBridge is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation and distributed hereunder
* to you.
*
* jVoiceBridge 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
* Sun designates this particular file as subject to the "Classpath"
* exception as provided by Sun in the License file that accompanied this
* code.
*/
package com.sun.voip;
import java.net.InetSocketAddress;
public interface DistributedBridge {
public void conferenceEventNotification(ConferenceEvent event);
public void dropDb();
public String getDistributedConferenceInfo();
public int getNumberOfMembers(String conferenceId);
}
/*
* Copyright 2007 Sun Microsystems, Inc.
*
* This file is part of jVoiceBridge.
*
* jVoiceBridge is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation and distributed hereunder
* to you.
*
* jVoiceBridge 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
* Sun designates this particular file as subject to the "Classpath"
* exception as provided by Sun in the License file that accompanied this
* code.
*/
package com.sun.voip;
import java.io.IOException;
import java.io.InputStream;
/**
* Read audio samples from a Sun .au file.
* Up/down sample as necessary.
*/
public class DotAuAudioSource extends FileAudioSource {
private String path;
private int sampleRate;
private int channels;
private int encoding;
private static final int AUDIO_FILE_HEADER_SIZE = 24;
private InputStream in;
/*
* Read an audio file. Pad with linear silence.
*/
public DotAuAudioSource(String path) throws IOException {
this.path = path;
initialize();
}
private void initialize() throws IOException {
done();
in = getInputStream(path);
/*
* Audio file header
*
* int magic = 0x2e 0x73 0x6e 0x64 which is ".snd"
* int hdr_size;
* int data_size;
* int encoding = 1 for ulaw, 3 for linear;
* int sample_rate;
* int channels;
*/
int bytesAvailable = 0;
try {
bytesAvailable = in.available();
} catch (IOException ioe) {
throw new IOException("available() failed " + path);
}
if (bytesAvailable < AUDIO_FILE_HEADER_SIZE) {
throw new IOException ("audiofile " + path + " is too small " +
bytesAvailable);
}
byte[] audioFileHeader = new byte[AUDIO_FILE_HEADER_SIZE];
try {
in.read(audioFileHeader, 0, AUDIO_FILE_HEADER_SIZE);
} catch (Exception e) {
throw new IOException("error reading " + path + " "
+ e.getMessage());
}
encoding = audioFileHeader[15];
channels = audioFileHeader[23];
if (audioFileHeader[0] != 0x2e || audioFileHeader[1] != 0x73 ||
audioFileHeader[2] != 0x6e || audioFileHeader[3] != 0x64 ||
(encoding != ULAW && encoding != LINEAR) ||
channels > 16) {
throw new IOException("bad audio file header " + path);
}
sampleRate =
((((int)audioFileHeader[16]) << 24) & 0xff000000) +
((((int)audioFileHeader[17]) << 16) & 0x00ff0000) +
((((int)audioFileHeader[18]) << 8) & 0x0000ff00) +
(((int)audioFileHeader[19]) & 0xff);
if (Logger.logLevel >= Logger.LOG_MOREINFO) {
Logger.println("AudioFile is " + path + ". Resource is " +
DotAuAudioSource.class.getResource(path) + ". size "
+ in.available() + " encoding " + encoding
+ " channels " + channels + " sampleRate "
+ sampleRate);
}
try {
bytesAvailable = in.available();
int hdr_size =
((audioFileHeader[4] << 24) & 0xff0000) |
((audioFileHeader[5] << 16) & 0xff0000) |
((audioFileHeader[6] << 8) & 0xff00) |
(audioFileHeader[7] & 0xff);
if (hdr_size > AUDIO_FILE_HEADER_SIZE) {
/*
* read remainder of the header and discard
*/
int excess_hdr_size =
hdr_size - AUDIO_FILE_HEADER_SIZE;
byte[] data = new byte[excess_hdr_size];
in.read(data, 0, excess_hdr_size);
if (Logger.logLevel >= Logger.LOG_MOREINFO) {
Logger.println("Reading excess header "
+ " hdr size " + hdr_size
+ " excess " + excess_hdr_size);
}
}
} catch (Exception e) {
throw new IOException("Can't read data! " + path + " "
+ e.getMessage());
}
}
public int[] getLinearData(int sampleTime) throws IOException {
byte[] fileData = readAudioFile(sampleTime);
if (fileData == null) {
return null;
}
int[] linearData;
if (encoding == ULAW) {
// 1 ulaw byte for each int
linearData = new int[fileData.length];
AudioConversion.ulawToLinear(fileData, 0, fileData.length,
linearData);
} else {
// 2 linear bytes for each int
linearData = new int[fileData.length / 2];
for (int i = 0; i < linearData.length; i++) {
linearData[i] = (int)
((short)(((fileData[2 * i] << 8) & 0xff00) |
(fileData[(2 * i) + 1] & 0xff)));
}
}
return linearData;
}
private byte[] readAudioFile(int sampleTime) throws IOException {
int bytesAvailable;
if (in == null || (bytesAvailable = in.available()) == 0) {
done();
return null;
}
int sampleSize = 2;
if (encoding == AudioSource.ULAW) {
sampleSize = 1;
}
int len =
sampleRate * sampleTime * channels * sampleSize / 1000;
byte[] data = new byte[len];
try {
int readSize;
readSize = Math.min(len, bytesAvailable);
/*
* Read the file
*/
in.read(data, 0, readSize);
byte b;
if (encoding == ULAW) {
b = AudioConversion.PCMU_SILENCE;
} else {
b = AudioConversion.PCM_SILENCE;
}
for (int i = readSize; i < len; i++) {
data[i] = b;
}
} catch (IOException e) {
throw new IOException("Can't read data! " + path + " "
+ e.getMessage());
}
return data;
}
public int getSampleRate() {
return sampleRate;
}
public int getChannels() {
return channels;
}
public void rewind() throws IOException {
initialize();
}
public void done() {
if (in != null) {
try {
in.close();
} catch (IOException e) {
}
}
}
}
/*
* Copyright 2007 Sun Microsystems, Inc.
*
* This file is part of jVoiceBridge.
*
* jVoiceBridge is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation and distributed hereunder
* to you.
*
* jVoiceBridge 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
* Sun designates this particular file as subject to the "Classpath"
* exception as provided by Sun in the License file that accompanied this
* code.
*/
package com.sun.voip;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.File;
import java.io.IOException;
/**
* Down sample
*/
public class Downsampler extends Resampler {
private long totalTime;
private int resampleCount;
/*
* XXX We only support big endian 16 bit samples!
*/
public Downsampler(String id, int inSampleRate, int inChannels,
int outSampleRate, int outChannels) throws IOException {
super(id, inSampleRate, inChannels, outSampleRate, outChannels);
if (inSampleRate < outSampleRate) {
throw new IOException("Downsampler inSampleRate "
+ inSampleRate + " < outSampleRate " + outSampleRate);
}
if (Logger.logLevel >= Logger.LOG_MOREINFO) {
Logger.println("New DownSampler: from "
+ inSampleRate + "/" + inChannels + " to "
+ outSampleRate + "/" + outChannels);
}
}
public void reset() {
}
public byte[] resample(byte[] inSamples, int offset, int length)
throws IOException {
length = length & ~1; // round down
int[] ints = new int[length / 2];
AudioConversion.bytesToInts(inSamples, offset, length, ints);
ints = resample(ints);
byte[] bytes = new byte[ints.length * 2];
AudioConversion.intsToBytes(ints, bytes, offset);
return bytes;
}
public int[] resample(int[] inSamples) throws
IOException {
if (inSampleRate == outSampleRate && inChannels == outChannels) {
return inSamples;
}
resampleCount++;
long start = CurrentTime.getTime();
int[] outSamples = reChannel(inSamples);
if (inSampleRate == outSampleRate) {
return outSamples; // no need to resample
}
outSamples = lowPassFilter.lpf(outSamples);
outSamples = downsample(outSamples);
totalTime += (CurrentTime.getTime() - start);
return outSamples;
}
public int[] downsample(int[] inSamples) {
int nFrames = inSamples.length / outChannels;
int sampleTime = nFrames * 1000 / inSampleRate;
if (sampleTime == 0) {
sampleTime = 1;
}
int outLength =
(sampleTime * outSampleRate * outChannels / 1000);
if ((outLength & 1) != 0) {
outLength++;
}
if (outLength == 0 || Logger.logLevel == -9) {
Logger.println("downsample: inLength " + inSamples.length
+ " nFrames " + nFrames
+ " sampleTime " + sampleTime + " outLength " + outLength);
}
int[] outSamples = new int[outLength];
double frameIncr = (double)inSampleRate / (double)outSampleRate;
int ix;
double i = 0;
int outIx = 0;
if (Logger.logLevel == -9) {
Logger.println("downsample frameIncr " + frameIncr
+ " nFrames " + nFrames + " inLength " + inSamples.length
+ " outLength " + outLength);
Logger.println("inSamples");
}
/*
* Linear interpolation between the two closest samples.
*/
while (true) {
ix = (int)i * outChannels;
if (ix >= inSamples.length - outChannels) {
// Don't we need to continue until outIx >= outLength?
if (Logger.logLevel == -9) {
Logger.println("Out of here! ix " + ix + " outIx " + outIx);
}
break;
}
int s1 = inSamples[ix];
int s2 = inSamples[ix + outChannels];
if (Logger.logLevel == -9) {
Logger.println("s1 " + s1 + " s2 " + s2 + " int i " + (int)i
+ " ix " + ix + " outIx " + outIx);
}
outSamples[outIx] = (int) ((s1 + ((s2 - s1) * (i - (int)i))));
outIx++;
if (outChannels == 2) {
ix++;
s1 = inSamples[ix];
s2 = inSamples[ix + outChannels];
outSamples[outIx] = (int) ((s1 + ((s2 - s1) * (i - (int)i))));
if (Logger.logLevel == -9) {
Logger.println("+s1 " + s1 + " s2 " + s2 + " int i " + (int)i
+ " ix " + ix + " outIx " + outIx);
}
outIx++;
}
if (outIx >= outLength) {
if (Logger.logLevel == -9) {
Logger.println("Out of here! outIX " + outIx
+ " ix " + ix);
}
break;
}
i += frameIncr;
}
if (Logger.logLevel == -9) {
Logger.logLevel = 3;
Logger.println("downsample in len " + inSamples.length);
Logger.println("downsample out len " + outSamples.length);
}
return outSamples;
}
public void printStatistics() {
if (resampleCount == 0) {
return;
}
double avg = (double)totalTime / resampleCount;
long timeUnitsPerSecond = CurrentTime.getTimeUnitsPerSecond();
avg = (avg / timeUnitsPerSecond) * 1000;
String s = "";
if (id != null) {
s += "Call " + id + ": ";
}
Logger.writeFile(s
+ avg + "ms avg downsample time from "
+ inSampleRate + "/" + inChannels + " to " + outSampleRate + "/"
+ outChannels);
lowPassFilter.printStatistics();
}
}
/*
* Copyright 2007 Sun Microsystems, Inc.
*
* This file is part of jVoiceBridge.
*
* jVoiceBridge is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation and distributed hereunder
* to you.
*
* jVoiceBridge 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
* Sun designates this particular file as subject to the "Classpath"
* exception as provided by Sun in the License file that accompanied this
* code.
*/
package com.sun.voip;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
/**
* Abstract superclass of audio sources that read data from a file.
* @author jkaplan
*/
public abstract class FileAudioSource implements AudioSource {
private static Map<String, Class<? extends FileAudioSource>> types =
new HashMap<String, Class<? extends FileAudioSource>>();
// initialize the map
static {
types.put(".au", DotAuAudioSource.class);
}
/**
* Get a file audio source for the given file. This looks at
* the extension of the source and decides which AudioSource type
* to load.
* <p>
* All audio sources are expected to have a constructor that takes
* the path as an argument and throws an IOException in the case of
* an error.
*
* @param path the path to the audio file
* @return a FileAudioSource for playing the path or null if there is
* an error finding an audio source for the given type
*/
public static FileAudioSource getAudioSource(String path) {
// get the extension
int extIdx = path.lastIndexOf(".");
if (extIdx == -1) {
Logger.error("Unable to determine extension of " + path);
return null;
}
String ext = path.substring(extIdx);
Class<? extends FileAudioSource> clazz = types.get(ext);
if (clazz == null) {
Logger.error("No player for extension " + ext);
return null;
}
try {
Constructor<? extends FileAudioSource> c =
clazz.getConstructor(String.class);
return c.newInstance(path);
} catch (Exception e) {
if (e instanceof IOException) {
Logger.println("getAudioSource for " + path + " got IOException: "
+ e.getMessage());
} else {
if (Logger.logLevel >= Logger.LOG_INFO) {
Logger.exception("Error instantiating class " + clazz, e);
}
}
return null;
}
}
/**
* Register a new type of audio source. There can be one
* decoder for each audio file type, identified by extension.
* @param extension the extension of files to decode, e.g. ".au"
* @param clazz the class to use to decode the given audio source
*/
public static void registerAudioSource(String extension,
Class<? extends FileAudioSource> clazz)
{
types.put(extension, clazz);
}
/**
* Load the audio source from the given path. The path may be either
* in the jar file which FileAudioSource is read from or in the
* file system. The jar file is checked first.
* @param path the path to load from
* @return an InputStream read from the given path
* @throws IOException if there is an error loading the stream
*/
protected InputStream getInputStream(String path) throws IOException {
/*
* replace back slashes with slash.
*/
path = path.replaceAll(Matcher.quoteReplacement("\\"), "/");
// try to load the stream as a resource
InputStream in = getClass().getResourceAsStream(path);
if (in != null) {
in = new BufferedInputStream(in, 16*1024);
if (Logger.logLevel >= Logger.LOG_MOREINFO) {
Logger.println("Successfully opened as stream '" + path + "'");
}
} else {
// no luck, try the file system
if (File.separator.equals("\\")) {
/*
* Replace slash with back slash
*/
path = path.replaceAll("/", Matcher.quoteReplacement("\\"));
}
if (Logger.logLevel >= Logger.LOG_MOREINFO) {
Logger.println("can't read audio resource, trying as a file: "
+ path);
}
try {
in = new FileInputStream(path);
} catch (FileNotFoundException e) {
throw new IOException("DotAuAudioSource error " + path + ": " +
e.getMessage());
}
}
return in;
}
}
This diff is collapsed.
This diff is collapsed.
/*
* Copyright 2007 Sun Microsystems, Inc.
*
* This file is part of jVoiceBridge.
*
* jVoiceBridge is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation and distributed hereunder
* to you.
*
* jVoiceBridge 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
* Sun designates this particular file as subject to the "Classpath"
* exception as provided by Sun in the License file that accompanied this
* code.
*/
package com.sun.voip;
/*
* The JitterManager maintains a list of JitterObjects.
* data is kept as Object because it can be either a byte[] when used
* byte the softphone or int[] when used by the bridge.
*
* Only the JitterManager creates JitterObjects and it has two
* separate insertPacket() methods, one with a byte[] argument and
* the other with a int[] argument.
*/
public class JitterObject {
public int sequence;
public boolean isMissing;
public Object data;
public JitterObject(int sequence, boolean isMissing, Object data) {
this.sequence = sequence;
this.isMissing = isMissing;
this.data = data;
}
public String toString() {
return "sequence " + sequence
+ ", isMissing " + isMissing
+ ", data " + data;
}
}
/*
* Copyright 2007 Sun Microsystems, Inc.
*
* This file is part of jVoiceBridge.
*
* jVoiceBridge is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation and distributed hereunder
* to you.
*
* jVoiceBridge 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
* Sun designates this particular file as subject to the "Classpath"
* exception as provided by Sun in the License file that accompanied this
* code.
*/
package com.sun.voip;
import java.io.IOException;
/*
* Return samples from a linear data array.
* FreeTTS generates a linear data array.
*/
public class LinearDataAudioSource implements AudioSource {
private int[] linearData;
private int sampleRate;
private int channels;
private int linearOffset = 0;
public LinearDataAudioSource(int[] linearData,
int sampleRate, int channels) {
this.linearData = linearData;
this.sampleRate = sampleRate;
this.channels = channels;
}
/*
* Get linear data from the linear data array.
*/
public int[] getLinearData(int sampleTime) throws IOException {
if (linearOffset >= linearData.length) {
return null;
}
int byteLen = sampleRate * sampleTime * channels * 2 / 1000;
int[] data = new int[byteLen / 2];
int dataOffset = 0;
for (int i = 0; i < byteLen; i += 2) {
if (linearOffset >= linearData.length) {
/*
* We've reached the end of the linear data.
* Pad the rest of linearData will be zero which
* is linear silence.
*/
break;
}
data[dataOffset++] = linearData[linearOffset++];
}
return data;
}
public void rewind() throws IOException {
linearOffset = 0;
}
public void done() {
}
public int getSampleRate() {
return sampleRate;
}
public int getChannels() {
return channels;
}
}
This diff is collapsed.
This diff is collapsed.
/*
* Copyright 2007 Sun Microsystems, Inc.
*
* This file is part of jVoiceBridge.
*
* jVoiceBridge is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation and distributed hereunder
* to you.
*
* jVoiceBridge 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
* Sun designates this particular file as subject to the "Classpath"
* exception as provided by Sun in the License file that accompanied this
* code.
*/
package com.sun.voip;
import java.io.IOException;
import java.util.ArrayList;
public class MediaInfo {
private byte payload;
private int encoding;
private int sampleRate;
private int channels;
private boolean isTelephoneEventPayload;
private int samplesPerPacket;
private static ArrayList supportedMedia = new ArrayList();
static {
supportedMedia.add(new MediaInfo(
(byte)0, RtpPacket.PCMU_ENCODING, 8000, 1, false));
supportedMedia.add(new MediaInfo(
(byte)101, RtpPacket.PCM_ENCODING, 8000, 1, true));
supportedMedia.add(new MediaInfo(
(byte)102, RtpPacket.PCM_ENCODING, 8000, 2, false));
supportedMedia.add(new MediaInfo(
(byte)103, RtpPacket.PCM_ENCODING, 16000, 1, false));
supportedMedia.add(new MediaInfo(
(byte)104, RtpPacket.PCM_ENCODING, 16000, 2, false));
supportedMedia.add(new MediaInfo(
(byte)105, RtpPacket.PCM_ENCODING, 32000, 1, false));
supportedMedia.add(new MediaInfo(
(byte)106, RtpPacket.PCM_ENCODING, 32000, 2, false));
supportedMedia.add(new MediaInfo(
(byte)107, RtpPacket.PCM_ENCODING, 44100, 1, false));
supportedMedia.add(new MediaInfo(
(byte)108, RtpPacket.PCM_ENCODING, 44100, 2, false));
if (false) {
supportedMedia.add(new MediaInfo(
(byte)109, RtpPacket.PCM_ENCODING, 48000, 1, false));
supportedMedia.add(new MediaInfo(
(byte)110, RtpPacket.PCM_ENCODING, 48000, 2, false));
}
supportedMedia.add(new MediaInfo(
(byte)111, RtpPacket.PCM_ENCODING, 48000, 2, false));
supportedMedia.add(new MediaInfo(
(byte)112, RtpPacket.PCMU_ENCODING, 16000, 1, false));
supportedMedia.add(new MediaInfo(
(byte)113, RtpPacket.PCMU_ENCODING, 16000, 2, false));
supportedMedia.add(new MediaInfo(
(byte)114, RtpPacket.PCMU_ENCODING, 32000, 1, false));
supportedMedia.add(new MediaInfo(
(byte)115, RtpPacket.PCMU_ENCODING, 32000, 2, false));
if (false) {
supportedMedia.add(new MediaInfo(
(byte)116, RtpPacket.PCMU_ENCODING, 44100, 1, false));
supportedMedia.add(new MediaInfo(
(byte)117, RtpPacket.PCMU_ENCODING, 44100, 2, false));
supportedMedia.add(new MediaInfo(
(byte)118, RtpPacket.PCMU_ENCODING, 48000, 1, false));
supportedMedia.add(new MediaInfo(
(byte)119, RtpPacket.PCMU_ENCODING, 48000, 2, false));
}
supportedMedia.add(new MediaInfo(
(byte)120, RtpPacket.SPEEX_ENCODING, 8000, 1, false));
supportedMedia.add(new MediaInfo(
(byte)121, RtpPacket.SPEEX_ENCODING, 8000, 2, false));
supportedMedia.add(new MediaInfo(
(byte)122, RtpPacket.SPEEX_ENCODING, 16000, 1, false));
supportedMedia.add(new MediaInfo(
(byte)123, RtpPacket.SPEEX_ENCODING, 16000, 2, false));
supportedMedia.add(new MediaInfo(
(byte)124, RtpPacket.SPEEX_ENCODING, 32000, 1, false));
supportedMedia.add(new MediaInfo(
(byte)125, RtpPacket.SPEEX_ENCODING, 32000, 2, false));
}
public MediaInfo(byte payload , int encoding, int sampleRate,
int channels, boolean isTelephoneEventPayload) {
this.payload = payload;
this.encoding = encoding;
this.sampleRate = sampleRate;
this.channels = channels;
this.isTelephoneEventPayload = isTelephoneEventPayload;
samplesPerPacket =
sampleRate * channels / (1000 / RtpPacket.PACKET_PERIOD);
}
public static MediaInfo findMediaInfo(int encoding, int sampleRate,
int channels) throws IOException {
for (int i = 0; i < supportedMedia.size(); i++) {
MediaInfo mediaInfo = (MediaInfo) supportedMedia.get(i);
if (mediaInfo.getEncoding() == encoding &&
mediaInfo.getSampleRate() == sampleRate &&
mediaInfo.getChannels() == channels) {
return mediaInfo;
}
}
throw new IOException("Unsupported media " + encoding
+ "/" + sampleRate + "/" + channels);
}
public static MediaInfo findMediaInfo(byte payload) throws IOException {
for (int i = 0; i < supportedMedia.size(); i++) {
MediaInfo mediaInfo = (MediaInfo) supportedMedia.get(i);
if (mediaInfo.getPayload() == payload) {
return mediaInfo;
}
}
throw new IOException("Unsupported payload " + payload);
}
public byte getPayload() {
return payload;
}
public int getEncoding() {
return encoding;
}
public String getEncodingString() {
if (encoding == RtpPacket.PCMU_ENCODING) {
return "PCMU";
}
if (encoding == RtpPacket.PCM_ENCODING) {
return "PCM";
}
return "SPEEX";
}
public int getSampleRate() {
return sampleRate;
}
public int getChannels() {
return channels;
}
public int getSamplesPerPacket() {
return samplesPerPacket;
}
public boolean isTelephoneEventPayload() {
return isTelephoneEventPayload;
}
public String toString() {
String s = "PCMU";
if (encoding == RtpPacket.PCM_ENCODING) {
s = "PCM";
} else if (encoding == RtpPacket.SPEEX_ENCODING) {
s = "SPEEX";
}
return payload + ":" + s + "/" + sampleRate + "/" + channels;
}
}
/*
* Copyright 2007 Sun Microsystems, Inc.
*
* This file is part of jVoiceBridge.
*
* jVoiceBridge is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation and distributed hereunder
* to you.
*
* jVoiceBridge 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
* Sun designates this particular file as subject to the "Classpath"
* exception as provided by Sun in the License file that accompanied this
* code.
*/
package com.sun.voip;
public interface MixDataSource {
public String getSourceId();
public void saveCurrentContribution();
public int[] getPreviousContribution();
public int[] getCurrentContribution();
public boolean contributionIsInCommonMix();
public String toAbbreviatedString();
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment