From 7b1a542097cd8dd0f5e446463147ae1b3775f0cd Mon Sep 17 00:00:00 2001
From: Damian Minkov <damencho@jitsi.org>
Date: Fri, 12 Oct 2012 10:35:37 +0000
Subject: [PATCH] Adds more options to sound notifications and their config.
 Sound notifications now can use playback, notification or pc speaker device.

---
 .../notify/AudioNotifierServiceImpl.java      | 85 ++++++++++++++++---
 .../neomedia/notify/AudioSystemClipImpl.java  | 16 +++-
 .../audionotifier/AudioNotifierService.java   | 11 ++-
 3 files changed, 97 insertions(+), 15 deletions(-)

diff --git a/src/org/jitsi/impl/neomedia/notify/AudioNotifierServiceImpl.java b/src/org/jitsi/impl/neomedia/notify/AudioNotifierServiceImpl.java
index 46adaec2..09b4a26a 100644
--- a/src/org/jitsi/impl/neomedia/notify/AudioNotifierServiceImpl.java
+++ b/src/org/jitsi/impl/neomedia/notify/AudioNotifierServiceImpl.java
@@ -26,10 +26,10 @@ public class AudioNotifierServiceImpl
                PropertyChangeListener
 {
     /**
-     * Map of differents audio clips.
+     * Map of different audio clips.
      */
-    private static final Map<String, SCAudioClipImpl> audioClips =
-        new HashMap<String, SCAudioClipImpl>();
+    private static final Map<AudioClipsKey, SCAudioClipImpl> audioClips =
+        new HashMap<AudioClipsKey, SCAudioClipImpl>();
 
     /**
      * If the sound is currently disabled.
@@ -56,20 +56,34 @@ public AudioNotifierServiceImpl()
 
     /**
      * Creates an SCAudioClip from the given URI and adds it to the list of
-     * available audio-s.
+     * available audio-s. Uses notification device if any.
      *
      * @param uri the path where the audio file could be found
      * @return a newly created <tt>SCAudioClip</tt> from <tt>uri</tt>
      */
     public SCAudioClipImpl createAudio(String uri)
+    {
+        return createAudio(uri, false);
+    }
+
+    /**
+     * Creates an SCAudioClip from the given URI and adds it to the list of
+     * available audio-s.
+     *
+     * @param uri the path where the audio file could be found
+     * @param playback use or not the playback device.
+     * @return a newly created <tt>SCAudioClip</tt> from <tt>uri</tt>
+     */
+    public SCAudioClipImpl createAudio(String uri, boolean playback)
     {
         SCAudioClipImpl audioClip;
 
         synchronized (audioClips)
         {
-            if(audioClips.containsKey(uri))
+            AudioClipsKey key = new AudioClipsKey(uri, playback);
+            if(audioClips.containsKey(key))
             {
-                audioClip = audioClips.get(uri);
+                audioClip = audioClips.get(key);
             }
             else
             {
@@ -106,8 +120,8 @@ else if (NoneAudioSystem.LOCATOR_PROTOCOL.equalsIgnoreCase(
                         audioClip = null;
                     else
                     {
-                        audioClip
-                            = new AudioSystemClipImpl(url, this, audioSystem);
+                        audioClip = new AudioSystemClipImpl(
+                                            url, this, audioSystem, playback);
                     }
                 }
                 catch (Throwable t)
@@ -118,7 +132,7 @@ else if (NoneAudioSystem.LOCATOR_PROTOCOL.equalsIgnoreCase(
                     return null;
                 }
 
-                audioClips.put(uri, audioClip);
+                audioClips.put(key, audioClip);
             }
         }
 
@@ -134,7 +148,18 @@ public void destroyAudio(SCAudioClip audioClip)
     {
         synchronized (audioClips)
         {
-            audioClips.remove(audioClip);
+            AudioClipsKey keyToRemove = null;
+            for(Map.Entry<AudioClipsKey, SCAudioClipImpl> entry
+                : audioClips.entrySet())
+            {
+                if(entry.getValue().equals(audioClip))
+                {
+                    keyToRemove = entry.getKey();
+                    break;
+                }
+            }
+
+            audioClips.remove(keyToRemove);
         }
     }
 
@@ -192,4 +217,44 @@ public void propertyChange(PropertyChangeEvent event)
             audioClips.clear();
         }
     }
+
+    /**
+     * Key for clips.
+     */
+    private static class AudioClipsKey
+    {
+        /**
+         * The uri.
+         */
+        private String uri;
+
+        /**
+         * Is it playback.
+         */
+        private boolean isPlayback;
+
+        /**
+         * Constructs key.
+         * @param uri by uri
+         * @param playback and playback
+         */
+        private AudioClipsKey(String uri, boolean playback)
+        {
+            this.uri = uri;
+            isPlayback = playback;
+        }
+
+        @Override
+        public boolean equals(Object o)
+        {
+            AudioClipsKey that = (AudioClipsKey) o;
+
+            if(isPlayback != that.isPlayback)
+                return false;
+            if(uri != null ? !uri.equals(that.uri) : that.uri != null)
+                return false;
+
+            return true;
+        }
+    }
 }
diff --git a/src/org/jitsi/impl/neomedia/notify/AudioSystemClipImpl.java b/src/org/jitsi/impl/neomedia/notify/AudioSystemClipImpl.java
index 5b608bf4..d62c6dcc 100644
--- a/src/org/jitsi/impl/neomedia/notify/AudioSystemClipImpl.java
+++ b/src/org/jitsi/impl/neomedia/notify/AudioSystemClipImpl.java
@@ -42,24 +42,28 @@ public class AudioSystemClipImpl
 
     private final URL url;
 
+    private boolean isPlayback = false;
+
     /**
      * Creates the audio clip and initializes the listener used from the
      * loop timer.
      *
      * @param url the URL pointing to the audio file
      * @param audioNotifier the audio notify service
+     * @param playback to use playback or notification device
      * @throws IOException cannot audio clip with supplied URL.
      */
     public AudioSystemClipImpl(
             URL url,
             AudioNotifierServiceImpl audioNotifier,
-            org.jitsi.impl.neomedia.device.AudioSystem
-                audioSystem)
+            org.jitsi.impl.neomedia.device.AudioSystem audioSystem,
+            boolean playback)
         throws IOException
     {
         this.url = url;
         this.audioNotifier = audioNotifier;
         this.audioSystem = audioSystem;
+        this.isPlayback = playback;
     }
 
     /**
@@ -130,7 +134,8 @@ private void runInPlayThread()
         Buffer buffer = new Buffer();
         byte[] bufferData = new byte[1024];
         // don't enable volume control for notifications
-        Renderer renderer = audioSystem.createRenderer(false);
+
+        Renderer renderer = audioSystem.createRenderer(isPlayback);
 
         buffer.setData(bufferData);
         while (started)
@@ -160,7 +165,10 @@ private void runInPlayThread()
                     {
                         try
                         {
-                            syncObject.wait(getLoopInterval());
+                            // only wait if lonnger than 0
+                            // or we will wait forever
+                            if(getLoopInterval() > 0)
+                                syncObject.wait(getLoopInterval());
                         }
                         catch (InterruptedException e)
                         {
diff --git a/src/org/jitsi/service/audionotifier/AudioNotifierService.java b/src/org/jitsi/service/audionotifier/AudioNotifierService.java
index 80e9a609..95de4045 100644
--- a/src/org/jitsi/service/audionotifier/AudioNotifierService.java
+++ b/src/org/jitsi/service/audionotifier/AudioNotifierService.java
@@ -18,12 +18,21 @@
 public interface AudioNotifierService
 {
     /**
-     * Creates an SCAudioClip and returns it.
+     * Creates an SCAudioClip and returns it. By default using notification
+     * device.
      * @param uri the uri, which will be the source of the audio
      * @return the created SCAudioClip, that could be played.
      */
     public SCAudioClip createAudio(String uri);
 
+    /**
+     * Creates an SCAudioClip and returns it.
+     * @param uri the uri, which will be the source of the audio
+     * @param playback use or not the playback device.
+     * @return the created SCAudioClip, that could be played.
+     */
+    public SCAudioClip createAudio(String uri, boolean playback);
+
     /**
      * Destroys the given audio.
      *
-- 
GitLab