/* * 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.audionotifier; 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 SCAudioClipImpl implements SCAudioClip { private static Constructor<AudioClip> acConstructor = null; private Timer playAudioTimer = new Timer(1000, null); private AudioClip audioClip; private boolean isInvalid; private boolean isLooping; private int loopInterval; private ActionListener audioListener; private AudioNotifierService audioNotifier; /** * Creates the audio clip and initialize the listener used from the * loop timer. * * @param url the url pointing to the audio file */ public SCAudioClipImpl(URL url, AudioNotifierService audioNotifier) { InputStream inputstream; try { inputstream = url.openStream(); this.createAppletAudioClip(inputstream); } catch (IOException e) { e.printStackTrace(); } this.audioListener = new PlayAudioListener(audioClip); this.playAudioTimer.addActionListener(audioListener); this.audioNotifier = audioNotifier; } public SCAudioClipImpl(InputStream inputstream, AudioNotifierService audioNotifier) { try { this.createAppletAudioClip(inputstream); } catch (IOException e) { e.printStackTrace(); } this.audioListener = new PlayAudioListener(audioClip); this.playAudioTimer.addActionListener(audioListener); this.audioNotifier = audioNotifier; } /** * 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(); } } this.loopInterval = interval; this.isLooping = true; } /** * Stops this audio. */ public void stop() { if (audioClip != null) audioClip.stop(); if(isLooping) { playAudioTimer.stop(); this.isLooping = 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 void createAppletAudioClip(InputStream inputstream) throws IOException { if(acConstructor == null) { try { acConstructor = AccessController .doPrivileged(new PrivilegedExceptionAction<Constructor<AudioClip>>() { @SuppressWarnings("unchecked") public Constructor<AudioClip> run() throws NoSuchMethodException, SecurityException, ClassNotFoundException { Class<?> class1 = null; try { class1 = Class.forName( "com.sun.media.sound.JavaSoundAudioClip", true, ClassLoader.getSystemClassLoader()); } catch(ClassNotFoundException classnotfoundexception) { class1 = Class.forName( "sun.audio.SunAudioClip", true, null); } Class<?> aclass[] = new Class[1]; aclass[0] = Class.forName("java.io.InputStream"); return (Constructor<AudioClip>) class1.getConstructor(aclass); } }); } catch(PrivilegedActionException privilegedactionexception) { throw new IOException("Failed to get AudioClip constructor: " + privilegedactionexception.getException()); } } try { Object aobj[] = { inputstream }; audioClip = acConstructor.newInstance(aobj); } catch(Exception exception) { throw new IOException("Failed to construct the AudioClip: " + exception); } } /** * Plays an audio clip. Used in the playAudioTimer to play an audio in loop. */ private static class PlayAudioListener implements ActionListener { private AudioClip audio; public PlayAudioListener(AudioClip audio) { this.audio = audio; } public void actionPerformed(ActionEvent e) { audio.stop(); audio.play(); } } /** * 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.isInvalid = 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; } }