use of com.sun.voip.SpeexException in project Openfire by igniterealtime.
the class MemberReceiver method initialize.
/**
* Initialize this member. The call has been established and
* we now know the port at which the member (CallParticipant)
* listens for data.
*/
public void initialize(ConferenceManager conferenceManager, CallHandler callHandler, byte mediaPayload, byte telephoneEventPayload, RtcpReceiver rtcpReceiver) {
this.conferenceManager = conferenceManager;
this.telephoneEventPayload = telephoneEventPayload;
this.rtcpReceiver = rtcpReceiver;
this.callHandler = callHandler;
Logger.writeFile("Call " + cp + " MemberReceiver initialization started..." + cp.getProtocol());
conferenceWhisperGroup = conferenceManager.getWGManager().getConferenceWhisperGroup();
MediaInfo conferenceMediaInfo = conferenceManager.getMediaInfo();
int outSampleRate = conferenceMediaInfo.getSampleRate();
int outChannels = conferenceMediaInfo.getChannels();
jitterManager = new JitterManager("Call " + cp.toString());
if (cp.voiceDetection()) {
if (Logger.logLevel >= Logger.LOG_MOREINFO) {
Logger.println("Call " + cp + " starting speech Detector...");
}
speechDetector = new SpeechDetector(this.toString(), conferenceMediaInfo);
}
if (cp.getProtocol() != null && ("WebRtc".equals(cp.getProtocol()) || "Rtmfp".equals(cp.getProtocol()) || "Speaker".equals(cp.getProtocol()))) {
conferenceManager.getConferenceReceiver().addMember(this);
if (cp.getJoinConfirmationTimeout() == 0) {
joinConfirmationReceived = true;
readyToReceiveData = true;
playJoinTreatment();
}
} else {
try {
myMediaInfo = SdpManager.findMediaInfo(mediaPayload);
} catch (ParseException e) {
Logger.println("Call " + cp + " Invalid mediaPayload " + mediaPayload);
callHandler.cancelRequest("Invalid mediaPayload " + mediaPayload);
return;
}
Logger.println("My media info: " + myMediaInfo);
int inSampleRate = myMediaInfo.getSampleRate();
int inChannels = myMediaInfo.getChannels();
//if (cp.getPhoneNumber().indexOf("@") >= 0) {
ConferenceReceiver conferenceReceiver = conferenceManager.getConferenceReceiver();
conferenceManager.getConferenceReceiver().addMember(this);
/*
* For input treatments, the treatment manager does the resampling.
*/
if (cp.getInputTreatment() == null) {
if (inSampleRate != outSampleRate || inChannels != outChannels) {
try {
Logger.println("Call " + cp + " resample received data from " + inSampleRate + "/" + inChannels + " to " + outSampleRate + "/" + outChannels);
inSampleRateConverter = new SampleRateConverter(this.toString(), inSampleRate, inChannels, outSampleRate, outChannels);
} catch (IOException e) {
callHandler.cancelRequest(e.getMessage());
return;
}
}
}
packet = new RtpReceiverPacket(cp.toString(), myMediaInfo.getEncoding(), inSampleRate, inChannels);
if (initializationDone) {
/*
* This is a re-initialize
*/
return;
}
//if (telephoneEventPayload == 0 && (cp.dtmfDetection() || cp.getJoinConfirmationTimeout() != 0)) {
Logger.println("Call " + cp + " starting dtmf Detector..." + telephoneEventPayload + " " + cp.dtmfDetection());
dtmfDecoder = new DtmfDecoder(this, myMediaInfo);
if (myMediaInfo.getEncoding() == RtpPacket.SPEEX_ENCODING) {
try {
speexDecoder = new SpeexDecoder(inSampleRate, inChannels);
Logger.println("Call " + cp + " created SpeexDecoder");
} catch (SpeexException e) {
Logger.println("Call " + cp + e.getMessage());
callHandler.cancelRequest(e.getMessage());
return;
}
} else if (myMediaInfo.getEncoding() == RtpPacket.PCM_ENCODING) {
try {
opusDecoder = Opus.decoder_create(opusSampleRate, opusChannels);
if (opusDecoder == 0) {
Logger.println("Call " + cp + " OPUS decoder creation error ");
callHandler.cancelRequest("OPUS decoder creation error ");
return;
}
} catch (Exception e) {
e.printStackTrace();
}
}
if (cp.getJoinConfirmationTimeout() == 0) {
joinConfirmationReceived = true;
readyToReceiveData = true;
playJoinTreatment();
}
if (cp.getInputTreatment() != null && cp.getInputTreatment().length() > 0) {
String absolutePath = cp.getInputTreatment();
try {
if (cp.getRecordDirectory() != null) {
absolutePath = Recorder.getAbsolutePath(cp.getRecordDirectory(), cp.getInputTreatment());
}
if (Logger.logLevel >= Logger.LOG_INFO) {
Logger.println("Call " + cp + " New input treatment: " + absolutePath);
}
synchronized (this) {
new InputTreatment(this, absolutePath, 0, conferenceMediaInfo.getSampleRate(), conferenceMediaInfo.getChannels());
}
} catch (IOException e) {
e.printStackTrace();
Logger.println("MemberReceiver: Invalid input treatment " + absolutePath + ": " + e.getMessage());
callHandler.cancelRequest("Invalid input treatment " + absolutePath + ": " + e.getMessage());
return;
}
}
String forwardingCallId = cp.getForwardingCallId();
if (forwardingCallId != null) {
CallHandler forwardingCall = CallHandler.findCall(forwardingCallId);
if (forwardingCall == null) {
Logger.println("Invalid forwardingCallId: " + forwardingCallId);
callHandler.cancelRequest("Invalid forwardingCallId: " + forwardingCallId);
return;
}
ConferenceMember m = forwardingCall.getMember();
m.getMemberReceiver().addForwardMember(member.getMemberSender());
/*
* If the source of the data is an input treatment, there
* is no need to have the forwarding call receive data
* from the remote side.
*/
if (cp.getInputTreatment() != null) {
m.setConferenceMuted(true);
}
}
}
initializationDone = true;
Logger.writeFile("Call " + cp + " MemberReceiver initialization done...");
}
use of com.sun.voip.SpeexException in project Openfire by igniterealtime.
the class MemberReceiver method receive.
public void receive(InetSocketAddress fromAddress, byte[] receivedData, int length) {
member.getMemberSender().setSendAddress(fromAddress);
if (packet == null)
return;
/*
* receivedData has a 12 byte RTP header at the beginning
* and length includes the RTP header.
*/
timeCurrentPacketReceived = System.currentTimeMillis();
packetsReceived++;
if (packetsReceived == 1) {
Logger.println("Call " + cp + " got first packet, length " + length);
packet.setBuffer(receivedData);
/*
* TODO: Get the synchonization source for this call.
*/
}
if (cp.getInputTreatment() != null) {
return;
}
if (dropPackets != 0) {
if ((packetsReceived % dropPackets) == 0) {
return;
}
}
/*
* For debugging
*/
if (traceCall || Logger.logLevel == -11) {
Logger.writeFile("Call " + cp + " got packet, len " + length);
}
/*
* Decrypt data if it's encrypted
*/
long start = 0;
if (decryptCipher != null) {
if (traceCall || Logger.logLevel == -1) {
start = System.nanoTime();
}
receivedData = decrypt(receivedData);
if (traceCall || Logger.logLevel == -1) {
Logger.println("Call " + cp + " decrypt time " + ((System.nanoTime() - start) / 1000000000.) + " seconds");
}
}
recordPacket(receivedData, length);
packet.setBuffer(receivedData);
packet.setLength(length);
byte payload = packet.getRtpPayload();
int elapsedTime = (int) (timeCurrentPacketReceived - timePreviousPacketReceived);
if (gotComfortPayload || packetsReceived == 1) {
/*
* We don't want to count the time when the remote stopped
* sending to us.
*/
// make sure MARK bit is set
packet.setMark();
if (gotComfortPayload) {
gotComfortPayload = false;
if (traceCall || Logger.logLevel >= Logger.LOG_MOREINFO) {
Logger.println("Call " + cp + " received packet after comfort payload");
}
}
}
if (packet.isMarkSet() == true) {
elapsedTime = RtpPacket.PACKET_PERIOD;
}
totalTime += elapsedTime;
synchronized (jitterManager) {
/*
* Insert place holder for this packet
*/
jitterManager.insertPacket(packet.getRtpSequenceNumber(), elapsedTime);
}
int rtpTimestampAdjustment = length - RtpPacket.HEADER_SIZE;
if (payload == RtpPacket.COMFORT_PAYLOAD || payload == 19) {
/*
* Asterisk seems to have a bug in which the bridge offers
* 13 decimal as the comfort payload and asterisk replies with
* 13 hex (19 decimal).
* For now, we'll treat 19 as the comfort noise payload as well.
*/
receiveComfortPayload(packet, elapsedTime);
if (inSampleRateConverter != null) {
inSampleRateConverter.reset();
}
if (speechDetector != null) {
if (speechDetector.isSpeaking()) {
callHandler.speakingChanged(false);
}
speechDetector.reset();
}
} else if (payload == 18) {
/*
* We sometimes get payload 18 which is undefined according to
* the RFC. The data looks like audio data.
* But for now, we just drop the packet.
*/
Logger.error("Call " + cp + " unexpected payload " + payload + " dropping packet ");
Util.dump("bad payload 18 data", packet.getData(), 0, 16);
} else if (payload == myMediaInfo.getPayload()) {
if (traceCall || Logger.logLevel == -1) {
start = System.nanoTime();
}
try {
rtpTimestampAdjustment = receiveMedia(receivedData, length);
} catch (SpeexException e) {
Logger.println("speex decorder failed: " + e.getMessage());
e.printStackTrace();
callHandler.cancelRequest("Call " + cp + e.getMessage());
return;
}
if (traceCall || Logger.logLevel == -1) {
Logger.println("Call " + cp + " receiveMedia time " + ((System.nanoTime() - start) / 1000000000.) + " seconds");
}
int processTime = (int) (System.currentTimeMillis() - timeCurrentPacketReceived);
timeToProcessMediaPackets += processTime;
mediaPacketsReceived++;
} else if (payload != 0 && payload == telephoneEventPayload) {
if (cp.ignoreTelephoneEvents() == false) {
receiveDtmfPayload(packet);
}
} else {
if ((badPayloads % 1000) == 0) {
badPayloads++;
Logger.error("Call " + cp + " unexpected payload " + payload + " length " + length);
Util.dump("unexpected payload", receivedData, 0, 16);
}
if (badPayloads >= 1000 && mediaPacketsReceived == 0) {
callHandler.cancelRequest("Call " + cp + " bad media payload being sent by call");
}
}
packet.updateRtpHeader(rtpTimestampAdjustment);
timePreviousPacketReceived = timeCurrentPacketReceived;
}
use of com.sun.voip.SpeexException in project Openfire by igniterealtime.
the class MemberSender method initialize.
/**
* Initialize this member. The call has been established and
* we now know the port at which the member (CallParticipant)
* listens for data.
*/
public void initialize(ConferenceManager conferenceManager, CallHandler callHandler, InetSocketAddress memberAddress, byte mediaPayload, byte telephoneEventPayload) {
this.conferenceManager = conferenceManager;
this.memberAddress = memberAddress;
this.telephoneEventPayload = telephoneEventPayload;
this.callHandler = callHandler;
Logger.writeFile("Call " + cp + " MemberSender initialization started ..." + cp.getProtocol());
conferenceMediaInfo = conferenceManager.getMediaInfo();
outSampleRate = conferenceMediaInfo.getSampleRate();
outChannels = conferenceMediaInfo.getChannels();
try {
myMediaInfo = SdpManager.findMediaInfo(mediaPayload);
} catch (ParseException e) {
Logger.println("Call " + cp + " Invalid mediaPayload " + mediaPayload);
callHandler.cancelRequest("Invalid mediaPayload " + mediaPayload);
return;
}
int inSampleRate = myMediaInfo.getSampleRate();
int inChannels = myMediaInfo.getChannels();
/*
* No data is ever sent to an input treatment unless it's a recorder
*/
if (cp.getInputTreatment() == null || cp.isRecorder() == true) {
if (inSampleRate != outSampleRate || inChannels != outChannels) {
Logger.println("Call " + cp + " resample data to send from " + inSampleRate + "/" + inChannels + " to " + outSampleRate + "/" + outChannels);
try {
outSampleRateConverter = new SampleRateConverter(this.toString(), outSampleRate, outChannels, inSampleRate, inChannels);
} catch (IOException e) {
callHandler.cancelRequest(e.getMessage());
return;
}
}
}
senderPacket = new RtpSenderPacket(myMediaInfo.getEncoding(), inSampleRate, inChannels);
if (myMediaInfo.getEncoding() == RtpPacket.SPEEX_ENCODING) {
try {
speexEncoder = new SpeexEncoder(inSampleRate, inChannels);
Logger.println("Call " + cp + " created SpeexEncoder");
} catch (SpeexException e) {
Logger.println("Call " + cp + " Speex initialization for encoding failed: " + e.getMessage());
callHandler.cancelRequest(e.getMessage());
return;
}
}
if (myMediaInfo.getEncoding() == RtpPacket.PCM_ENCODING) {
try {
opusEncoder = Opus.encoder_create(opusSampleRate, opusChannels);
if (opusEncoder == 0) {
Logger.println("Call " + cp + " OPUS encoder creation error ");
callHandler.cancelRequest("OPUS encoder creation error ");
return;
}
} catch (Exception e) {
e.printStackTrace();
}
}
initializationDone = true;
Logger.writeFile("Call " + cp + " MemberSender initialization done...");
}
use of com.sun.voip.SpeexException in project Openfire by igniterealtime.
the class MemberSender method sendData.
public synchronized boolean sendData(int[] dataToSend) {
if (dtmfKeyToSend != null) {
if (telephoneEventPayload != 0) {
sendDtmfKey();
return true;
} else {
if (Logger.logLevel >= Logger.LOG_INFO) {
Logger.println("Call " + cp + " Telephone event payload not supported. " + "Can't send " + dtmfKeyToSend);
}
dtmfKeyToSend = null;
}
}
long start = System.nanoTime();
if (dataToSend == null) {
if (Logger.logLevel == -77) {
Logger.println("Call " + cp + " no data to send");
}
if (comfortNoiseType == CN_USE_PAYLOAD) {
if (senderPacket.getRtpPayload() != RtpPacket.COMFORT_PAYLOAD) {
if (Logger.logLevel == -77) {
Logger.println("Call " + cp + " sending comfort payload");
}
if (relayChannel == null) {
if (cp.getRtmfpSendStream() == null && "SIP".equals(cp.getProtocol()))
sendComfortNoisePayload();
} else
relayChannel.sendComfortNoisePayload();
}
}
mustSetMarkBit = true;
return false;
}
if (senderPacket.getRtpPayload() == RtpPacket.COMFORT_PAYLOAD) {
// account for pause
senderPacket.adjustRtpTimestamp();
}
senderPacket.setRtpPayload(myMediaInfo.getPayload());
if (mustSetMarkBit) {
if (Logger.logLevel == -77 || Logger.logLevel >= Logger.LOG_MOREINFO) {
Logger.println("Setting MARK for " + cp);
}
if (Logger.logLevel != -77) {
/*
* Adjust RTP timestamp to account for long pause
*/
if (timePreviousPacketSent != 0) {
senderPacket.adjustRtpTimestamp(System.currentTimeMillis() - timePreviousPacketSent);
}
}
senderPacket.setMark();
/* Set MARK_BIT */
mustSetMarkBit = false;
}
if (outputVolume != 1.0) {
callHandler.getMember().adjustVolume(dataToSend, outputVolume);
}
dataToSend = normalize(dataToSend);
try {
/*
* Resample if needed
*/
if (outSampleRateConverter != null) {
dataToSend = outSampleRateConverter.resample(dataToSend);
}
} catch (IOException e) {
Logger.println("Call " + cp + " can't resample data to send! " + e.getMessage());
callHandler.cancelRequest("Call " + cp + " can't resample data to send! " + e.getMessage());
return false;
}
byte[] rtpData = senderPacket.getData();
if (Logger.logLevel == -37) {
boolean silence = true;
for (int i = RtpPacket.HEADER_SIZE; i < rtpData.length - RtpPacket.HEADER_SIZE; i++) {
if (rtpData[i] != 0) {
silence = false;
break;
}
}
if (silence) {
//Logger.println("Call " + cp + " sending silence");
return false;
}
}
//Util.dump("Call " + cp + " sending data " + dataToSend.length,
// dataToSend, 0, 8);
//Logger.println("Call " + cp + " Sending data...");
byte[] opusBytes = null;
if (myMediaInfo.getEncoding() == RtpPacket.PCMU_ENCODING) {
/*
* Convert to ulaw
*/
AudioConversion.linearToUlaw(dataToSend, rtpData, RtpPacket.HEADER_SIZE);
senderPacket.setLength(rtpData.length);
//Util.dump("Call " + cp + " sending ulaw data " + rtpData.length,
// rtpData, 0, 16);
} else if (myMediaInfo.getEncoding() == RtpPacket.SPEEX_ENCODING) {
try {
if (Logger.logLevel >= Logger.LOG_MOREDETAIL) {
Logger.writeFile("Call " + cp + " speex encoding data ");
}
int length = speexEncoder.encode(dataToSend, rtpData, RtpPacket.HEADER_SIZE);
senderPacket.setLength(length + RtpPacket.HEADER_SIZE);
} catch (SpeexException e) {
Logger.println("Call " + this + ": " + e.getMessage());
return false;
}
} else if (myMediaInfo.getEncoding() == RtpPacket.PCM_ENCODING) {
if (relayChannel != null && relayChannel.encode()) {
byte[] input = AudioConversion.littleEndianIntsToBytes(dataToSend);
byte[] output = new byte[Opus.MAX_PACKET];
int outLength = Opus.encode(opusEncoder, input, 0, frameSizeInSamplesPerChannel, output, 0, output.length);
opusBytes = new byte[outLength];
System.arraycopy(output, 0, opusBytes, 0, outLength);
System.arraycopy(output, 0, rtpData, RtpPacket.HEADER_SIZE, outLength);
senderPacket.setLength(outLength + RtpPacket.HEADER_SIZE);
//Logger.println("RtpPacket.PCM_ENCODING " + outLength);
}
} else {
AudioConversion.intsToBytes(dataToSend, rtpData, RtpPacket.HEADER_SIZE);
}
recordPacket(rtpData, senderPacket.getLength());
recordAudio(rtpData, RtpPacket.HEADER_SIZE, senderPacket.getLength() - RtpPacket.HEADER_SIZE);
/*
* Encrypt data if required
*/
if (needToEncrypt()) {
encrypt(rtpData, senderPacket.getLength());
}
if (Logger.logLevel == -78) {
Logger.println("Call " + cp + " sending data from socket " + datagramChannel.socket().getLocalAddress() + ":" + datagramChannel.socket().getLocalPort() + " to " + senderPacket.getSocketAddress());
}
if (relayChannel == null) {
if (// RTMFP
cp.getRtmfpSendStream() != null) {
if (RtmfpCallAgent.publishHandlers.containsKey(cp.getRtmfpSendStream())) {
int ts = (int) (System.currentTimeMillis() - startTime);
byte[] rtmfp = new byte[rtpData.length + 1 - RtpPacket.HEADER_SIZE];
rtmfp[0] = (byte) 130;
System.arraycopy(rtpData, RtpPacket.HEADER_SIZE, rtmfp, 1, rtmfp.length - 1);
RtmfpCallAgent.publishHandlers.get(cp.getRtmfpSendStream()).B(ts, new AudioPacket(rtmfp, rtmfp.length), 0);
}
} else if ("SIP".equals(cp.getProtocol())) {
if (cp.getInputTreatment() == null) {
try {
senderPacket.setSocketAddress(memberAddress);
datagramChannel.send(ByteBuffer.wrap(senderPacket.getData(), 0, senderPacket.getLength()), memberAddress);
if (Logger.logLevel >= Logger.LOG_MOREDETAIL) {
Logger.writeFile("Call " + cp + " back from sending data");
}
} catch (Exception e) {
if (!done) {
Logger.error("Call " + cp + " sendData " + e.getMessage());
e.printStackTrace();
}
return false;
}
}
} else {
return true;
}
} else {
try {
if (relayChannel.encode())
relayChannel.pushAudio(senderPacket.getData(), opusBytes);
else
relayChannel.pushAudio(dataToSend);
} catch (Exception e) {
return false;
}
}
senderPacket.setBuffer(rtpData);
if (Logger.logLevel >= Logger.LOG_DEBUG) {
log(true);
}
timePreviousPacketSent = System.currentTimeMillis();
if (Logger.logLevel >= Logger.LOG_MOREDETAIL) {
Logger.println("Call " + cp + " sendLength " + rtpData.length);
}
totalTimeToGetData += (System.nanoTime() - start);
packetsSent++;
senderPacket.updateRtpHeader(rtpData.length);
return true;
}
Aggregations