mirror of https://github.com/sipwise/jitsi.git
parent
b518e93f84
commit
6f62b3b802
@ -0,0 +1,175 @@
|
|||||||
|
/*
|
||||||
|
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
|
||||||
|
*
|
||||||
|
* Distributable under LGPL license.
|
||||||
|
* See terms of license at gnu.org.
|
||||||
|
*/
|
||||||
|
package net.java.sip.communicator.impl.neomedia.notify;
|
||||||
|
|
||||||
|
import java.net.*;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
import net.java.sip.communicator.impl.neomedia.*;
|
||||||
|
import net.java.sip.communicator.impl.neomedia.device.*;
|
||||||
|
import net.java.sip.communicator.service.audionotifier.*;
|
||||||
|
import net.java.sip.communicator.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The implementation of the AudioNotifierService.
|
||||||
|
*
|
||||||
|
* @author Yana Stamcheva
|
||||||
|
*/
|
||||||
|
public class AudioNotifierServiceImpl
|
||||||
|
implements AudioNotifierService,
|
||||||
|
PropertyChangeListener
|
||||||
|
{
|
||||||
|
private static final Map<String, SCAudioClipImpl> audioClips =
|
||||||
|
new HashMap<String, SCAudioClipImpl>();
|
||||||
|
|
||||||
|
private boolean isMute;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Device config to look for notify device.
|
||||||
|
*/
|
||||||
|
private DeviceConfiguration deviceConfiguration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates audio notify service.
|
||||||
|
* @param deviceConfiguration the device configuration.
|
||||||
|
*/
|
||||||
|
public AudioNotifierServiceImpl(DeviceConfiguration deviceConfiguration)
|
||||||
|
{
|
||||||
|
this.deviceConfiguration = deviceConfiguration;
|
||||||
|
deviceConfiguration.addPropertyChangeListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
public SCAudioClipImpl createAudio(String uri)
|
||||||
|
{
|
||||||
|
SCAudioClipImpl audioClip;
|
||||||
|
|
||||||
|
synchronized (audioClips)
|
||||||
|
{
|
||||||
|
if(audioClips.containsKey(uri))
|
||||||
|
{
|
||||||
|
audioClip = audioClips.get(uri);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
URL url =
|
||||||
|
NeomediaActivator.getResources().getSoundURLForPath(uri);
|
||||||
|
|
||||||
|
if (url == null)
|
||||||
|
{
|
||||||
|
// Not found by the class loader. Perhaps it's a local file.
|
||||||
|
try
|
||||||
|
{
|
||||||
|
url = new URL(uri);
|
||||||
|
}
|
||||||
|
catch (MalformedURLException e)
|
||||||
|
{
|
||||||
|
//logger.error("The given uri could not be parsed.", e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if(getDeviceConfiguration().getAudioSystem().equals(
|
||||||
|
DeviceConfiguration.AUDIO_SYSTEM_JAVASOUND))
|
||||||
|
{
|
||||||
|
audioClip = new JMFAudioClipImpl(url, this);
|
||||||
|
}
|
||||||
|
else if(getDeviceConfiguration().getAudioSystem().equals(
|
||||||
|
DeviceConfiguration.AUDIO_SYSTEM_PORTAUDIO))
|
||||||
|
{
|
||||||
|
audioClip = new PortAudioClipImpl(url, this);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
catch (Throwable e)
|
||||||
|
{
|
||||||
|
// Cannot create audio to play
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
audioClips.put(uri, audioClip);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return audioClip;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the given audio from the list of available audio clips.
|
||||||
|
*
|
||||||
|
* @param audioClip the audio to destroy
|
||||||
|
*/
|
||||||
|
public void destroyAudio(SCAudioClip audioClip)
|
||||||
|
{
|
||||||
|
synchronized (audioClips) {
|
||||||
|
audioClips.remove(audioClip);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables or disables the sound in the application. If FALSE, we try to
|
||||||
|
* restore all looping sounds if any.
|
||||||
|
*
|
||||||
|
* @param isMute when TRUE disables the sound, otherwise enables the sound.
|
||||||
|
*/
|
||||||
|
public void setMute(boolean isMute)
|
||||||
|
{
|
||||||
|
this.isMute = isMute;
|
||||||
|
|
||||||
|
for (SCAudioClipImpl audioClip : audioClips.values())
|
||||||
|
{
|
||||||
|
if (isMute)
|
||||||
|
{
|
||||||
|
audioClip.internalStop();
|
||||||
|
}
|
||||||
|
else if (audioClip.isLooping())
|
||||||
|
{
|
||||||
|
audioClip.playInLoop(audioClip.getLoopInterval());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns TRUE if the sound is currently disabled, FALSE otherwise.
|
||||||
|
* @return TRUE if the sound is currently disabled, FALSE otherwise
|
||||||
|
*/
|
||||||
|
public boolean isMute()
|
||||||
|
{
|
||||||
|
return isMute;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The device configuration.
|
||||||
|
*
|
||||||
|
* @return the deviceConfiguration
|
||||||
|
*/
|
||||||
|
public DeviceConfiguration getDeviceConfiguration()
|
||||||
|
{
|
||||||
|
return deviceConfiguration;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listens for changes in notify device
|
||||||
|
* @param evt the event that notify device has changed.
|
||||||
|
*/
|
||||||
|
public void propertyChange(PropertyChangeEvent evt)
|
||||||
|
{
|
||||||
|
if(evt.getPropertyName().equals(
|
||||||
|
DeviceConfiguration.AUDIO_NOTIFY_DEVICE))
|
||||||
|
{
|
||||||
|
audioClips.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,201 @@
|
|||||||
|
/*
|
||||||
|
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
|
||||||
|
*
|
||||||
|
* Distributable under LGPL license.
|
||||||
|
* See terms of license at gnu.org.
|
||||||
|
*/
|
||||||
|
package net.java.sip.communicator.impl.neomedia.notify;
|
||||||
|
|
||||||
|
import java.applet.*;
|
||||||
|
import java.awt.event.*;
|
||||||
|
import java.io.*;
|
||||||
|
import java.lang.reflect.*;
|
||||||
|
import java.net.*;
|
||||||
|
import java.security.*;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
|
||||||
|
import net.java.sip.communicator.service.audionotifier.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of SCAudioClip.
|
||||||
|
*
|
||||||
|
* @author Yana Stamcheva
|
||||||
|
*/
|
||||||
|
public class JMFAudioClipImpl
|
||||||
|
extends SCAudioClipImpl
|
||||||
|
implements ActionListener
|
||||||
|
|
||||||
|
{
|
||||||
|
private static Constructor<AudioClip> acConstructor = null;
|
||||||
|
|
||||||
|
private final Timer playAudioTimer = new Timer(1000, null);
|
||||||
|
|
||||||
|
private final AudioClip audioClip;
|
||||||
|
|
||||||
|
private final AudioNotifierService audioNotifier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the audio clip and initialize the listener used from the
|
||||||
|
* loop timer.
|
||||||
|
*
|
||||||
|
* @param url the url pointing to the audio file
|
||||||
|
* @param audioNotifier the audio notify service
|
||||||
|
* @throws IOException cannot audio clip with supplied url.
|
||||||
|
*/
|
||||||
|
public JMFAudioClipImpl(URL url, AudioNotifierService audioNotifier)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
this.audioClip = createAppletAudioClip(url.openStream());
|
||||||
|
this.audioNotifier = audioNotifier;
|
||||||
|
|
||||||
|
this.playAudioTimer.addActionListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Plays this audio.
|
||||||
|
*/
|
||||||
|
public void play()
|
||||||
|
{
|
||||||
|
if ((audioClip != null) && !audioNotifier.isMute())
|
||||||
|
audioClip.play();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Plays this audio in loop.
|
||||||
|
*
|
||||||
|
* @param interval the loop interval
|
||||||
|
*/
|
||||||
|
public void playInLoop(int interval)
|
||||||
|
{
|
||||||
|
if(!audioNotifier.isMute())
|
||||||
|
{
|
||||||
|
if(interval == 0)
|
||||||
|
audioClip.loop();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//first play the audio and then start the timer and wait
|
||||||
|
audioClip.play();
|
||||||
|
playAudioTimer.setDelay(interval);
|
||||||
|
playAudioTimer.setRepeats(true);
|
||||||
|
|
||||||
|
playAudioTimer.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setLoopInterval(interval);
|
||||||
|
setIsLooping(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stops this audio.
|
||||||
|
*/
|
||||||
|
public void stop()
|
||||||
|
{
|
||||||
|
if (audioClip != null)
|
||||||
|
audioClip.stop();
|
||||||
|
|
||||||
|
if (isLooping())
|
||||||
|
{
|
||||||
|
playAudioTimer.stop();
|
||||||
|
setIsLooping(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stops this audio without setting the isLooping property in the case of
|
||||||
|
* a looping audio. The AudioNotifier uses this method to stop the audio
|
||||||
|
* when setMute(true) is invoked. This allows us to restore all looping
|
||||||
|
* audios when the sound is restored by calling setMute(false).
|
||||||
|
*/
|
||||||
|
public void internalStop()
|
||||||
|
{
|
||||||
|
if (audioClip != null)
|
||||||
|
audioClip.stop();
|
||||||
|
|
||||||
|
if (isLooping())
|
||||||
|
playAudioTimer.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an AppletAudioClip.
|
||||||
|
*
|
||||||
|
* @param inputstream the audio input stream
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
private static AudioClip createAppletAudioClip(InputStream inputstream)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
if (acConstructor == null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
acConstructor
|
||||||
|
= AccessController.doPrivileged(
|
||||||
|
new PrivilegedExceptionAction<Constructor<AudioClip>>()
|
||||||
|
{
|
||||||
|
public Constructor<AudioClip> run()
|
||||||
|
throws ClassNotFoundException,
|
||||||
|
NoSuchMethodException,
|
||||||
|
SecurityException
|
||||||
|
{
|
||||||
|
return createAcConstructor();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (PrivilegedActionException paex)
|
||||||
|
{
|
||||||
|
throw
|
||||||
|
new IOException(
|
||||||
|
"Failed to get AudioClip constructor: "
|
||||||
|
+ paex.getException());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return acConstructor.newInstance(inputstream);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
throw new IOException("Failed to construct the AudioClip: " + ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private static Constructor<AudioClip> createAcConstructor()
|
||||||
|
throws ClassNotFoundException,
|
||||||
|
NoSuchMethodException,
|
||||||
|
SecurityException
|
||||||
|
{
|
||||||
|
Class<?> class1;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
class1
|
||||||
|
= Class.forName(
|
||||||
|
"com.sun.media.sound.JavaSoundAudioClip",
|
||||||
|
true,
|
||||||
|
ClassLoader.getSystemClassLoader());
|
||||||
|
}
|
||||||
|
catch (ClassNotFoundException cnfex)
|
||||||
|
{
|
||||||
|
class1
|
||||||
|
= Class.forName("sun.audio.SunAudioClip", true, null);
|
||||||
|
}
|
||||||
|
return
|
||||||
|
(Constructor<AudioClip>) class1.getConstructor(InputStream.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Plays an audio clip. Used in the playAudioTimer to play an audio in loop.
|
||||||
|
* @param e the event.
|
||||||
|
*/
|
||||||
|
public void actionPerformed(ActionEvent e)
|
||||||
|
{
|
||||||
|
if (audioClip != null)
|
||||||
|
{
|
||||||
|
audioClip.stop();
|
||||||
|
audioClip.play();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,170 @@
|
|||||||
|
/*
|
||||||
|
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
|
||||||
|
*
|
||||||
|
* Distributable under LGPL license.
|
||||||
|
* See terms of license at gnu.org.
|
||||||
|
*/
|
||||||
|
package net.java.sip.communicator.impl.neomedia.notify;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.net.*;
|
||||||
|
|
||||||
|
import javax.sound.sampled.*;
|
||||||
|
|
||||||
|
import net.java.sip.communicator.impl.media.protocol.portaudio.*;
|
||||||
|
import net.java.sip.communicator.impl.media.protocol.portaudio.streams.*;
|
||||||
|
import net.java.sip.communicator.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of SCAudioClip using PortAudio.
|
||||||
|
*
|
||||||
|
* @author Damian Minkov
|
||||||
|
*/
|
||||||
|
public class PortAudioClipImpl
|
||||||
|
extends SCAudioClipImpl
|
||||||
|
{
|
||||||
|
private static final Logger logger
|
||||||
|
= Logger.getLogger(PortAudioClipImpl.class);
|
||||||
|
|
||||||
|
private final AudioNotifierServiceImpl audioNotifier;
|
||||||
|
|
||||||
|
private boolean started = false;
|
||||||
|
|
||||||
|
private final URL url;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the audio clip and initialize the listener used from the
|
||||||
|
* loop timer.
|
||||||
|
*
|
||||||
|
* @param url the url pointing to the audio file
|
||||||
|
* @param audioNotifier the audio notify service
|
||||||
|
* @throws IOException cannot audio clip with supplied url.
|
||||||
|
*/
|
||||||
|
public PortAudioClipImpl(URL url, AudioNotifierServiceImpl audioNotifier)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
this.audioNotifier = audioNotifier;
|
||||||
|
this.url = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Plays this audio.
|
||||||
|
*/
|
||||||
|
public void play()
|
||||||
|
{
|
||||||
|
if ((url != null) && !audioNotifier.isMute())
|
||||||
|
{
|
||||||
|
started = true;
|
||||||
|
new Thread(new PlayThread()).start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Plays this audio in loop.
|
||||||
|
*
|
||||||
|
* @param interval the loop interval
|
||||||
|
*/
|
||||||
|
public void playInLoop(int interval)
|
||||||
|
{
|
||||||
|
setLoopInterval(interval);
|
||||||
|
setIsLooping(true);
|
||||||
|
|
||||||
|
play();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stops this audio.
|
||||||
|
*/
|
||||||
|
public void stop()
|
||||||
|
{
|
||||||
|
internalStop();
|
||||||
|
setIsLooping(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stops this audio without setting the isLooping property in the case of
|
||||||
|
* a looping audio. The AudioNotifier uses this method to stop the audio
|
||||||
|
* when setMute(true) is invoked. This allows us to restore all looping
|
||||||
|
* audios when the sound is restored by calling setMute(false).
|
||||||
|
*/
|
||||||
|
public void internalStop()
|
||||||
|
{
|
||||||
|
if (url != null)
|
||||||
|
started = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class PlayThread
|
||||||
|
implements Runnable
|
||||||
|
{
|
||||||
|
byte[] buffer = new byte[1024];
|
||||||
|
private OutputPortAudioStream portAudioStream = null;
|
||||||
|
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
while(true)
|
||||||
|
{
|
||||||
|
AudioInputStream audioStream =
|
||||||
|
AudioSystem.getAudioInputStream(url);
|
||||||
|
AudioFormat audioStreamFormat = audioStream.getFormat();
|
||||||
|
|
||||||
|
if (portAudioStream == null)
|
||||||
|
{
|
||||||
|
int deviceIndex =
|
||||||
|
PortAudioUtils.getDeviceIndexFromLocator(
|
||||||
|
audioNotifier.getDeviceConfiguration().
|
||||||
|
getAudioNotifyDevice().getLocator());
|
||||||
|
|
||||||
|
portAudioStream = PortAudioManager.getInstance().
|
||||||
|
getOutputStream(
|
||||||
|
deviceIndex,
|
||||||
|
audioStreamFormat.getSampleRate(),
|
||||||
|
audioStreamFormat.getChannels(),
|
||||||
|
PortAudioUtils.getPortAudioSampleFormat(
|
||||||
|
audioStreamFormat.getSampleSizeInBits()));
|
||||||
|
portAudioStream.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!started)
|
||||||
|
{
|
||||||
|
portAudioStream.stop();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while(audioStream.read(buffer) != -1)
|
||||||
|
{
|
||||||
|
portAudioStream.write(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!isLooping())
|
||||||
|
{
|
||||||
|
portAudioStream.stop();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Thread.sleep(getLoopInterval());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (PortAudioException e)
|
||||||
|
{
|
||||||
|
logger.error(
|
||||||
|
"Cannot open portaudio device for notifications", e);
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
logger.error("Error reading from audio resource", e);
|
||||||
|
}
|
||||||
|
catch (InterruptedException e)
|
||||||
|
{
|
||||||
|
logger.error("Cannot wait the interval between plays", e);
|
||||||
|
}
|
||||||
|
catch (UnsupportedAudioFileException e)
|
||||||
|
{
|
||||||
|
logger.error("Unknown file format", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,94 @@
|
|||||||
|
/*
|
||||||
|
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
|
||||||
|
*
|
||||||
|
* Distributable under LGPL license.
|
||||||
|
* See terms of license at gnu.org.
|
||||||
|
*/
|
||||||
|
package net.java.sip.communicator.impl.neomedia.notify;
|
||||||
|
|
||||||
|
import net.java.sip.communicator.service.audionotifier.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Common properties impl for SCAudioClip.
|
||||||
|
*
|
||||||
|
* @author Damian Minkov
|
||||||
|
*/
|
||||||
|
public abstract class SCAudioClipImpl
|
||||||
|
implements SCAudioClip
|
||||||
|
{
|
||||||
|
private boolean isLooping;
|
||||||
|
|
||||||
|
private int loopInterval;
|
||||||
|
|
||||||
|
private boolean isInvalid;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns TRUE if this audio is invalid, FALSE otherwise.
|
||||||
|
*
|
||||||
|
* @return TRUE if this audio is invalid, FALSE otherwise
|
||||||
|
*/
|
||||||
|
public boolean isInvalid()
|
||||||
|
{
|
||||||
|
return isInvalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Marks this audio as invalid or not.
|
||||||
|
*
|
||||||
|
* @param isInvalid TRUE to mark this audio as invalid, FALSE otherwise
|
||||||
|
*/
|
||||||
|
public void setInvalid(boolean isInvalid)
|
||||||
|
{
|
||||||
|
this.setIsInvalid(isInvalid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns TRUE if this audio is currently playing in loop, FALSE otherwise.
|
||||||
|
* @return TRUE if this audio is currently playing in loop, FALSE otherwise.
|
||||||
|
*/
|
||||||
|
public boolean isLooping()
|
||||||
|
{
|
||||||
|
return isLooping;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the loop interval if this audio is looping.
|
||||||
|
* @return the loop interval if this audio is looping
|
||||||
|
*/
|
||||||
|
public int getLoopInterval()
|
||||||
|
{
|
||||||
|
return loopInterval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param isLooping the isLooping to set
|
||||||
|
*/
|
||||||
|
public void setIsLooping(boolean isLooping)
|
||||||
|
{
|
||||||
|
this.isLooping = isLooping;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param loopInterval the loopInterval to set
|
||||||
|
*/
|
||||||
|
public void setLoopInterval(int loopInterval)
|
||||||
|
{
|
||||||
|
this.loopInterval = loopInterval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param isInvalid the isInvalid to set
|
||||||
|
*/
|
||||||
|
public void setIsInvalid(boolean isInvalid)
|
||||||
|
{
|
||||||
|
this.isInvalid = isInvalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stops this audio without setting the isLooping property in the case of
|
||||||
|
* a looping audio. The AudioNotifier uses this method to stop the audio
|
||||||
|
* when setMute(true) is invoked. This allows us to restore all looping
|
||||||
|
* audios when the sound is restored by calling setMute(false).
|
||||||
|
*/
|
||||||
|
public abstract void internalStop();
|
||||||
|
}
|
||||||
Loading…
Reference in new issue