/**
* $RCSfile: ,v $
* $Revision: $
* $Date: $
*
* Copyright (C) 2004-2011 Jive Software. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.java.sipmack.common;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import org.jivesoftware.spark.plugin.phone.resource.PhoneRes;
import sun.audio.AudioPlayer;
import sun.audio.AudioStream;
/**
* This handles the playing of dial tone sounds when a user is dialing a number.
* Title: SIPark
* Description:JAIN-SIP Audio/Video phone application
*
* @author Thiago Rocha Camargo (thiago@jivesoftware.com)
*/
public class DialSoundManager {
AudioPlayer audioPlayer = AudioPlayer.player;
AudioStream[] audioStreams;
private Vector<String> playQueue = new Vector<String>();
private boolean running = true;
Thread playerThread;
public DialSoundManager() {
audioStreams = new AudioStream[12];
for (int i = 0; i < 12; i++) {
initializeAudioStream(i);
}
playerThread = new Thread(new Runnable() {
@Override
public void run() {
while (running) {
try {
if (playQueue.size() == 0) {
synchronized(playQueue) {
playQueue.wait();
}
continue;
}
play(playQueue.remove(0));
Thread.sleep(40);
}
catch (InterruptedException ex) {
if (running == false) {
break;
}
}
} // while
}
});
playerThread.start();
}
private void initializeAudioStream(int i) {
try {
if (audioStreams[i] != null) {
audioStreams[i].close();
audioStreams[i] = null;
}
InputStreamEventSource is = new InputStreamEventSource(i,
PhoneRes.getURL("DTMF" + i + "_SOUND").openStream());
is.addListener(new InputStreamListener() {
@Override
public void handleEndOfStream(int n) {
initializeAudioStream(n);
}
});
audioStreams[i] = new AudioStream(is);
}
catch (IOException e) {
e.printStackTrace();
}
}
@Override
protected void finalize() throws Throwable {
if (playerThread != null) {
running = false;
playerThread.interrupt();
playerThread = null;
}
super.finalize();
}
/**
* A mechanism to allow DTMF sounds to be played by the internal worker thread.
* @param s
*/
public void enqueue(String s) {
playQueue.add(s);
synchronized(playQueue) {
playQueue.notify();
}
}
protected void play(int n) {
audioPlayer.start(audioStreams[n]);
}
protected void play(String s) {
int n = -1;
if (s.equals("*")) {
n = 10;
}
else if (s.equals("#")) {
n = 11;
}
else {
try {
n = Integer.parseInt(s);
}
catch (Exception e) {
}
}
if (n >= 0 && n <= 11) {
play(n);
}
}
}
class InputStreamEventSource extends InputStream {
private InputStream is;
int i;
public InputStreamEventSource(int i, InputStream is) {
this.i = i;
this.is = is;
}
@Override
public int read() throws IOException {
int result = is.read();
if (result == -1) {
handleEndOfStream();
}
return result;
}
@Override
public void close() throws IOException {
is.close();
}
public void handleEndOfStream() {
for (InputStreamListener item : listeners) {
item.handleEndOfStream(i);
}
}
public void addListener(InputStreamListener item) {
listeners.add(item);
}
List<InputStreamListener> listeners = new ArrayList<InputStreamListener>();
}
interface InputStreamListener {
void handleEndOfStream(int i);
}