Improves handler for DTMF events: when sending several DTMF tones in a short frame, the notification sound is no more clipped but played entirely. The net.java.sip.communicator.service.protocol.maximalRtpDtmfToneDuration property is added to define a maximal duration for the RFC 2833/4733 DTMF tones.

cusax-fix
Vincent Lucas 13 years ago
parent 1a9146d86e
commit 9c86edf286

@ -28,7 +28,8 @@
* @author Lyubomir Marinov
*/
public class DTMFHandler
implements KeyEventDispatcher
implements KeyEventDispatcher,
Runnable
{
/**
* The <tt>Logger</tt> used by the <tt>DTMFHandler</tt> class and its
@ -64,6 +65,17 @@ public class DTMFHandler
*/
public static final String DTMF_TONE_PREFIX = "DTMFTone.";
/**
* The list of audio DTMF tones to play.
*/
private Vector<DTMFToneInfo> dmtfToneNotifications
= new Vector<DTMFToneInfo>(1, 1);
/**
* The thread which plays the audio DTMF notifications.
*/
private Thread dtmfToneNotificationThread;
/**
* All available tones and its properties like images for buttons, and
* sounds to be played during send.
@ -411,8 +423,19 @@ private synchronized void startSendingDtmfTone(DTMFToneInfo info)
{
if(info.sound != null)
{
currentlyPlayingTone = GuiActivator.getNotificationService()
.fireNotification(DTMF_TONE_PREFIX + info.tone.getValue());
synchronized(dmtfToneNotifications)
{
boolean startThread = (dmtfToneNotifications.size() == 0);
dmtfToneNotifications.add(info);
if(startThread)
{
dtmfToneNotificationThread
= new Thread(
this,
"DTMFHandler: DTMF tone notification player");
dtmfToneNotificationThread.start();
}
}
}
if (callContainer != null)
@ -477,10 +500,6 @@ private void startSendingDtmfTone(Call call, DTMFToneInfo info)
*/
public synchronized void stopSendingDtmfTone()
{
if(currentlyPlayingTone != null)
GuiActivator.getNotificationService()
.stopNotification(currentlyPlayingTone);
if (callContainer != null)
{
stopSendingDtmfTone(
@ -591,4 +610,39 @@ public DTMFToneInfo(
this.sound = sound;
}
}
/**
* Runnable used to read all waiting DTMF tone notification.
*/
public void run()
{
boolean moreToPlay = (dmtfToneNotifications.size() > 0);
DTMFToneInfo toneToPlay = null;
while(moreToPlay)
{
toneToPlay = dmtfToneNotifications.get(0);
if(toneToPlay.sound != null)
{
// Plays the next DTMF sond notification.
currentlyPlayingTone
= GuiActivator.getNotificationService().fireNotification(
DTMF_TONE_PREFIX + toneToPlay.tone.getValue());
// Waits for the current notification to end.
while(GuiActivator.getNotificationService()
.isPlayingNotification(currentlyPlayingTone))
{
Thread.yield();
}
// Removes the ended notification from the DTMF list.
GuiActivator.getNotificationService()
.stopNotification(currentlyPlayingTone);
synchronized(dmtfToneNotifications)
{
dmtfToneNotifications.remove(0);
moreToPlay = (dmtfToneNotifications.size() > 0);
}
}
}
}
}

@ -257,6 +257,37 @@ public void stop(NotificationData data)
}
}
/**
* Tells if the given notification sound is currently played.
*
* @param data Additional data for the event.
*/
public boolean isPlaying(NotificationData data)
{
AudioNotifierService audioNotifService
= NotificationActivator.getAudioNotifier();
if (audioNotifService != null)
{
synchronized(playedClips)
{
Iterator<Map.Entry<SCAudioClip, NotificationData>> i
= playedClips.entrySet().iterator();
while (i.hasNext())
{
Map.Entry<SCAudioClip, NotificationData> e = i.next();
if (e.getValue() == data)
{
return e.getKey().isStarted();
}
}
}
}
return false;
}
/**
* Beeps the PC speaker.
*/

@ -43,6 +43,11 @@ public class OperationSetDTMFJabberImpl
*/
private int minimalToneDuration;
/**
* The maximal tone duration.
*/
private int maximalToneDuration;
/**
* Constructor.
*
@ -52,6 +57,7 @@ public OperationSetDTMFJabberImpl(ProtocolProviderServiceJabberImpl pps)
{
this.dtmfMethod = this.getDTMFMethod(pps);
this.minimalToneDuration = this.getMinimalToneDuration(pps);
this.maximalToneDuration = this.getMaximalToneDuration();
}
/**
@ -107,7 +113,11 @@ public synchronized void startSendingDTMF(CallPeer callPeer, DTMFTone tone)
}
((AudioMediaStream)cp.getMediaHandler().getStream(MediaType.AUDIO))
.startSendingDTMF(tone, cpDTMFMethod, minimalToneDuration);
.startSendingDTMF(
tone,
cpDTMFMethod,
minimalToneDuration,
maximalToneDuration);
}
/**
@ -236,7 +246,7 @@ private int getMinimalToneDuration(ProtocolProviderServiceJabberImpl pps)
{
minimalToneDuration = Integer.valueOf(minimalToneDurationString);
}
// Else look at the globl property.
// Else look at the global property.
else
{
ConfigurationService cfg
@ -251,4 +261,28 @@ private int getMinimalToneDuration(ProtocolProviderServiceJabberImpl pps)
}
return minimalToneDuration;
}
/**
* Gets the maximal DTMF tone duration for this account.
*
* @return The maximal DTMF tone duration for this account.
*/
private int getMaximalToneDuration()
{
int maximalToneDuration
= OperationSetDTMF.DEFAULT_DTMF_MAXIMAL_TONE_DURATION;
// Look at the global property.
ConfigurationService cfg
= JabberActivator.getConfigurationService();
// Check if there is a custom value for the maximal tone duration.
if(cfg != null)
{
maximalToneDuration = cfg.getInt(
OperationSetDTMF.PROP_MAXIMAL_RTP_DTMF_TONE_DURATION,
maximalToneDuration);
}
return maximalToneDuration;
}
}

@ -50,6 +50,11 @@ public class OperationSetDTMFSipImpl
*/
private int minimalToneDuration;
/**
* The maximal tone duration.
*/
private int maximalToneDuration;
/**
* Constructor.
*
@ -59,6 +64,7 @@ public OperationSetDTMFSipImpl(ProtocolProviderServiceSipImpl pps)
{
this.dtmfMethod = this.getDTMFMethod(pps);
this.minimalToneDuration = this.getMinimalToneDuration(pps);
this.maximalToneDuration = this.getMaximalToneDuration();
dtmfModeInfo = new DTMFInfo(pps);
}
@ -124,7 +130,11 @@ public synchronized void startSendingDTMF(CallPeer callPeer, DTMFTone tone)
}
((AudioMediaStream)cp.getMediaHandler().getStream(MediaType.AUDIO))
.startSendingDTMF(tone, cpDTMFMethod, minimalToneDuration);
.startSendingDTMF(
tone,
cpDTMFMethod,
minimalToneDuration,
maximalToneDuration);
}
}
@ -278,7 +288,7 @@ private int getMinimalToneDuration(ProtocolProviderServiceSipImpl pps)
{
minimalToneDuration = Integer.valueOf(minimalToneDurationString);
}
// Else look at the globl property.
// Else look at the global property.
else
{
ConfigurationService cfg = SipActivator.getConfigurationService();
@ -292,4 +302,28 @@ private int getMinimalToneDuration(ProtocolProviderServiceSipImpl pps)
}
return minimalToneDuration;
}
/**
* Gets the maximal DTMF tone duration for this account.
*
* @return The maximal DTMF tone duration for this account.
*/
private int getMaximalToneDuration()
{
int maximalToneDuration
= OperationSetDTMF.DEFAULT_DTMF_MAXIMAL_TONE_DURATION;
// Look at the global property.
ConfigurationService cfg
= SipActivator.getConfigurationService();
// Check if there is a custom value for the maximal tone duration.
if(cfg != null)
{
maximalToneDuration = cfg.getInt(
OperationSetDTMF.PROP_MAXIMAL_RTP_DTMF_TONE_DURATION,
maximalToneDuration);
}
return maximalToneDuration;
}
}

@ -334,4 +334,11 @@ public NotificationData fireNotification(
* types - returns <code>false</code>.
*/
public boolean isActive(String eventType);
/**
* Tells if the given sound notification is currently played.
*
* @param data Additional data for the event.
*/
public boolean isPlayingNotification(NotificationData data);
}

@ -1296,4 +1296,32 @@ public void stopNotification(NotificationData data)
}
}
}
/**
* Tells if the given sound notification is currently played.
*
* @param data Additional data for the event.
*/
public boolean isPlayingNotification(NotificationData data)
{
boolean isPlaying = false;
Iterable<NotificationHandler> soundHandlers
= getActionHandlers(NotificationAction.ACTION_SOUND);
// There could be no sound action handler for this event type
if (soundHandlers != null)
{
for (NotificationHandler handler : soundHandlers)
{
if (handler instanceof SoundNotificationHandler)
{
isPlaying
|= ((SoundNotificationHandler) handler).isPlaying(data);
}
}
}
return isPlaying;
}
}

@ -45,4 +45,11 @@ public interface SoundNotificationHandler
* @return TRUE if currently the sound is off, FALSE otherwise
*/
public boolean isMute();
/**
* Tells if the given notification sound is currently played.
*
* @param data Additional data for the event.
*/
public boolean isPlaying(NotificationData data);
}

@ -22,6 +22,12 @@ public interface OperationSetDTMF
*/
public static final int DEFAULT_DTMF_MINIMAL_TONE_DURATION = 70;
/**
* The maximal tone duration value is -1 in order to stop sending tone only
* when user requests to stop it.
*/
public static final int DEFAULT_DTMF_MAXIMAL_TONE_DURATION = -1;
/**
* The name of the <tt>ConfigurationService</tt> <tt>int</tt> property
* which indicates the minimal duration for a DTMF tone.
@ -30,6 +36,15 @@ public interface OperationSetDTMF
public static final String PROP_MINIMAL_RTP_DTMF_TONE_DURATION =
"net.java.sip.communicator.service.protocol.minimalRtpDtmfToneDuration";
/**
* The name of the <tt>ConfigurationService</tt> <tt>int</tt> property
* which indicates the maximal duration for a DTMF tone (in ms).
* The default value is -1 to tell to stop DTMF tones only following user
* will.
*/
public static final String PROP_MAXIMAL_RTP_DTMF_TONE_DURATION =
"net.java.sip.communicator.service.protocol.maximalRtpDtmfToneDuration";
/**
* Sends the <tt>DTMFTone</tt> <tt>tone</tt> to <tt>callPeer</tt>.
*

Loading…
Cancel
Save