From d1b328fd7e188147c681b68c3202cdb619bab624 Mon Sep 17 00:00:00 2001 From: Damian Minkov Date: Mon, 19 Oct 2009 13:00:41 +0000 Subject: [PATCH] Fix playing portaudio notifications, remove writer thread in portaudio renderer seems to be the issue with low quality of played sound durring call. --- .../notify/AudioNotifierServiceImpl.java | 18 +++- .../impl/media/notify/PortAudioClipImpl.java | 28 +---- .../renderer/audio/PortAudioRenderer.java | 100 ++++-------------- 3 files changed, 43 insertions(+), 103 deletions(-) diff --git a/src/net/java/sip/communicator/impl/media/notify/AudioNotifierServiceImpl.java b/src/net/java/sip/communicator/impl/media/notify/AudioNotifierServiceImpl.java index 633b9f073..2fad5adc3 100644 --- a/src/net/java/sip/communicator/impl/media/notify/AudioNotifierServiceImpl.java +++ b/src/net/java/sip/communicator/impl/media/notify/AudioNotifierServiceImpl.java @@ -12,6 +12,7 @@ import net.java.sip.communicator.impl.media.*; import net.java.sip.communicator.impl.media.device.*; import net.java.sip.communicator.service.audionotifier.*; +import net.java.sip.communicator.util.*; /** * The implementation of the AudioNotifierService. @@ -19,7 +20,8 @@ * @author Yana Stamcheva */ public class AudioNotifierServiceImpl - implements AudioNotifierService + implements AudioNotifierService, + PropertyChangeListener { private static final Map audioClips = new HashMap(); @@ -38,6 +40,7 @@ public class AudioNotifierServiceImpl public AudioNotifierServiceImpl(DeviceConfiguration deviceConfiguration) { this.deviceConfiguration = deviceConfiguration; + deviceConfiguration.addPropertyChangeListener(this); } /** @@ -156,4 +159,17 @@ 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(); + } + } } diff --git a/src/net/java/sip/communicator/impl/media/notify/PortAudioClipImpl.java b/src/net/java/sip/communicator/impl/media/notify/PortAudioClipImpl.java index 5505556ba..1dce3e239 100644 --- a/src/net/java/sip/communicator/impl/media/notify/PortAudioClipImpl.java +++ b/src/net/java/sip/communicator/impl/media/notify/PortAudioClipImpl.java @@ -12,7 +12,6 @@ import javax.sound.sampled.*; import net.java.sip.communicator.impl.media.protocol.portaudio.*; -import net.java.sip.communicator.impl.media.device.*; import net.java.sip.communicator.util.*; /** @@ -22,19 +21,14 @@ */ public class PortAudioClipImpl extends SCAudioClipImpl - implements PropertyChangeListener { private static final Logger logger = Logger.getLogger(PortAudioClipImpl.class); private final AudioNotifierServiceImpl audioNotifier; - private Thread playThread = new Thread(new PlayThread()); - private boolean started = false; - private long portAudioStream = 0; - private URL url = null; /** @@ -50,8 +44,6 @@ public PortAudioClipImpl(URL url, AudioNotifierServiceImpl audioNotifier) { this.audioNotifier = audioNotifier; this.url = url; - - audioNotifier.getDeviceConfiguration().addPropertyChangeListener(this); } /** @@ -62,7 +54,7 @@ public void play() if ((url != null) && !audioNotifier.isMute()) { started = true; - playThread.start(); + new Thread(new PlayThread()).start(); } } @@ -79,7 +71,7 @@ public void playInLoop(int interval) if(!audioNotifier.isMute()) { started = true; - playThread.start(); + new Thread(new PlayThread()).start(); } } @@ -105,24 +97,10 @@ public void internalStop() started = false; } - /** - * Notified when device configuration has changed. - * @param evt the event of the change - */ - public void propertyChange(PropertyChangeEvent evt) - { - if(evt.getPropertyName().equals( - DeviceConfiguration.AUDIO_NOTIFY_DEVICE)) - { - // make the stream 0, to be sure next time the new - // device will be used - portAudioStream = 0; - } - } - private class PlayThread implements Runnable { + private long portAudioStream = 0; byte[] buffer = new byte[1024]; public void run() diff --git a/src/net/java/sip/communicator/impl/media/renderer/audio/PortAudioRenderer.java b/src/net/java/sip/communicator/impl/media/renderer/audio/PortAudioRenderer.java index 8bb04d34f..e8f105f5b 100644 --- a/src/net/java/sip/communicator/impl/media/renderer/audio/PortAudioRenderer.java +++ b/src/net/java/sip/communicator/impl/media/renderer/audio/PortAudioRenderer.java @@ -42,9 +42,7 @@ public class PortAudioRenderer boolean started = false; - private WriterThread writerThread = null; - private final Object bufferSync = new Object(); - private byte[] buffer = null; +// private final Object bufferSync = new Object(); private static int deviceIndex = -1; @@ -98,20 +96,16 @@ public void start() /** * Halts the rendering process. */ - public void stop() + public synchronized void stop() { - synchronized(bufferSync) + try { - try - { - started = false; - PortAudio.Pa_CloseStream(stream); - writerThread = null; - } - catch (PortAudioException e) - { - logger.error("Closing portaudio stream failed", e); - } + started = false; + PortAudio.Pa_CloseStream(stream); + } + catch (PortAudioException e) + { + logger.error("Closing portaudio stream failed", e); } } @@ -121,26 +115,24 @@ public void stop() * @param inputBuffer the input data. * @return BUFFER_PROCESSED_OK if the processing is successful. */ - public int process(Buffer inputBuffer) + public synchronized int process(Buffer inputBuffer) { - synchronized(bufferSync) - { - byte[] buff = new byte[inputBuffer.getLength()]; - System.arraycopy( - (byte[])inputBuffer.getData(), - inputBuffer.getOffset(), - buff, - 0, - buff.length); + byte[] buff = new byte[inputBuffer.getLength()]; + System.arraycopy( + (byte[])inputBuffer.getData(), + inputBuffer.getOffset(), + buff, + 0, + buff.length); - buffer = buff; - bufferSync.notifyAll(); + try + { + PortAudio.Pa_WriteStream( + stream, buff, buff.length/frameSize); } - - if(writerThread == null) + catch (PortAudioException e) { - writerThread = new WriterThread(); - writerThread.start(); + logger.error("Error writing to device", e); } return BUFFER_PROCESSED_OK; @@ -273,50 +265,4 @@ public static void setDevice(MediaLocator locator) = PortAudio.Pa_GetSampleSize(PortAudio.SAMPLE_FORMAT_INT16) * outputChannels; } - - /** - * Writes data to the portaudio stream. If there is no data for - * particular time write some silence so we wont hear some cracks in - * the sound. - */ - private class WriterThread - extends Thread - { - - public WriterThread() - { - setName("Portaudio Renderer"); - } - - public void run() - { - while(true) - { - try - { - synchronized(bufferSync) - { - // put some silence if there is no data - if(buffer == null) - { - buffer = new byte[1024]; - } - - PortAudio.Pa_WriteStream( - stream, buffer, buffer.length/frameSize); - - buffer = null; - bufferSync.wait(90); - } - - if(!started) - return; - } - catch (Exception e) - { - logger.error("writing to stream", e); - } - } - } - } }