From 82f658f9983cd07c8eb01a0b8f093bd6e988adfe Mon Sep 17 00:00:00 2001 From: Damian Minkov Date: Fri, 20 Nov 2009 07:52:51 +0000 Subject: [PATCH] Adds local user sound level indicators and their implementation. Change Players to be Processors in neomedia service impl, in order to have control on codec chain and to add there the sound level indicators. --- .../communicator/impl/gui/GuiActivator.java | 22 ++ .../call/conference/ConferenceCallPanel.java | 5 +- .../call/conference/ConferencePeerPanel.java | 1 + .../impl/gui/swing.ui.manifest.mf | 2 + .../impl/neomedia/AudioMediaStreamImpl.java | 27 ++ .../impl/neomedia/MediaServiceImpl.java | 69 +++++ .../audio/SoundLevelIndicatorEffect.java | 282 ++++++++++++++++++ .../neomedia/device/MediaDeviceSession.java | 186 +++++++----- .../device/VideoMediaDeviceSession.java | 34 ++- ...SetTelephonyConferencingGibberishImpl.java | 13 - .../service/neomedia/AudioMediaStream.java | 23 +- .../service/neomedia/MediaService.java | 14 + .../event/LocalUserSoundLevelEvent.java | 12 +- .../event/LocalUserSoundLevelListener.java | 2 +- .../AbstractOperationSetBasicTelephony.java | 65 ---- .../protocol/OperationSetBasicTelephony.java | 13 - 16 files changed, 579 insertions(+), 191 deletions(-) create mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/SoundLevelIndicatorEffect.java rename src/net/java/sip/communicator/service/{protocol => neomedia}/event/LocalUserSoundLevelEvent.java (86%) rename src/net/java/sip/communicator/service/{protocol => neomedia}/event/LocalUserSoundLevelListener.java (91%) diff --git a/src/net/java/sip/communicator/impl/gui/GuiActivator.java b/src/net/java/sip/communicator/impl/gui/GuiActivator.java index 0ef5a5346..fcf1d9e3e 100644 --- a/src/net/java/sip/communicator/impl/gui/GuiActivator.java +++ b/src/net/java/sip/communicator/impl/gui/GuiActivator.java @@ -19,6 +19,7 @@ import net.java.sip.communicator.service.gui.*; import net.java.sip.communicator.service.keybindings.*; import net.java.sip.communicator.service.metahistory.*; +import net.java.sip.communicator.service.neomedia.*; import net.java.sip.communicator.service.notification.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.resources.*; @@ -66,6 +67,8 @@ public class GuiActivator implements BundleActivator private static DesktopService desktopService; + private static MediaService mediaService; + private static final Map providerFactoriesMap = new Hashtable(); @@ -453,6 +456,25 @@ public static DesktopService getDesktopService() return desktopService; } + /** + * Returns the MediaService obtained from the bundle context. + * + * @return the MediaService obtained from the bundle context + */ + public static MediaService getMediaService() + { + if (mediaService == null) + { + ServiceReference serviceReference = bundleContext + .getServiceReference(MediaService.class.getName()); + + mediaService = (MediaService) bundleContext + .getService(serviceReference); + } + + return mediaService; + } + /** * Implements the ServiceListener. Verifies whether the * passed event concerns a NotificationService and if so diff --git a/src/net/java/sip/communicator/impl/gui/main/call/conference/ConferenceCallPanel.java b/src/net/java/sip/communicator/impl/gui/main/call/conference/ConferenceCallPanel.java index 3c1c0e7fa..a2dc26c0a 100644 --- a/src/net/java/sip/communicator/impl/gui/main/call/conference/ConferenceCallPanel.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/conference/ConferenceCallPanel.java @@ -11,8 +11,8 @@ import javax.swing.*; +import net.java.sip.communicator.impl.gui.*; import net.java.sip.communicator.impl.gui.main.call.*; -import net.java.sip.communicator.impl.gui.main.call.CallPeerAdapter; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.util.swing.*; @@ -129,7 +129,8 @@ private void addLocalCallPeer() .getOperationSet(OperationSetBasicTelephony.class); if (telephonyOpSet != null) - telephonyOpSet.addLocalUserSoundLevelListener(localPeerPanel); + GuiActivator.getMediaService(). + addLocalUserSoundLevelListener(localPeerPanel); } /** diff --git a/src/net/java/sip/communicator/impl/gui/main/call/conference/ConferencePeerPanel.java b/src/net/java/sip/communicator/impl/gui/main/call/conference/ConferencePeerPanel.java index 57fca07f4..ca955c3a8 100644 --- a/src/net/java/sip/communicator/impl/gui/main/call/conference/ConferencePeerPanel.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/conference/ConferencePeerPanel.java @@ -18,6 +18,7 @@ import net.java.sip.communicator.impl.gui.utils.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.event.*; +import net.java.sip.communicator.service.neomedia.event.*; import net.java.sip.communicator.util.swing.*; /** diff --git a/src/net/java/sip/communicator/impl/gui/swing.ui.manifest.mf b/src/net/java/sip/communicator/impl/gui/swing.ui.manifest.mf index c605ca02d..eb2786248 100644 --- a/src/net/java/sip/communicator/impl/gui/swing.ui.manifest.mf +++ b/src/net/java/sip/communicator/impl/gui/swing.ui.manifest.mf @@ -23,6 +23,8 @@ Import-Package: org.osgi.framework, net.java.sip.communicator.service.keybindings, net.java.sip.communicator.service.metahistory, net.java.sip.communicator.service.msghistory, + net.java.sip.communicator.service.neomedia, + net.java.sip.communicator.service.neomedia.event, net.java.sip.communicator.service.notification, net.java.sip.communicator.service.protocol, net.java.sip.communicator.service.protocol.event, diff --git a/src/net/java/sip/communicator/impl/neomedia/AudioMediaStreamImpl.java b/src/net/java/sip/communicator/impl/neomedia/AudioMediaStreamImpl.java index 76a7084f6..7dee0a90e 100644 --- a/src/net/java/sip/communicator/impl/neomedia/AudioMediaStreamImpl.java +++ b/src/net/java/sip/communicator/impl/neomedia/AudioMediaStreamImpl.java @@ -109,6 +109,20 @@ public void addSoundLevelListener(SoundLevelListener listener) // TODO Auto-generated method stub } + /** + * Adds listener to the list of SoundLevelListeners + * registered to receive notifications for changes in the levels of + * conference participants that the remote party could be mixing. + * + * @param listener the SoundLevelListener that we'd like to + * register. + */ + public void addConferenceMemberSoundLevelListener( + SoundLevelListener listener) + { + + } + /** * Registers {@link #CUSTOM_CODEC_FORMATS} with a specific * RTPManager. @@ -180,6 +194,19 @@ public void removeSoundLevelListener(SoundLevelListener listener) // TODO Auto-generated method stub } + /** + * Removes listener from the list of SoundLevelListeners + * registered to receive notification events upon changes of the sound + * level. + * + * @param listener the listener that we'd like to unregister. + */ + public void removeConferenceMemberSoundLevelListener( + SoundLevelListener listener) + { + + } + /** * Starts sending the specified DTMFTone until the * stopSendingDTMF() method is called. Callers should keep in mind diff --git a/src/net/java/sip/communicator/impl/neomedia/MediaServiceImpl.java b/src/net/java/sip/communicator/impl/neomedia/MediaServiceImpl.java index 3fc11dde0..59c0fb25d 100644 --- a/src/net/java/sip/communicator/impl/neomedia/MediaServiceImpl.java +++ b/src/net/java/sip/communicator/impl/neomedia/MediaServiceImpl.java @@ -15,6 +15,7 @@ import net.java.sip.communicator.impl.neomedia.format.*; import net.java.sip.communicator.service.neomedia.*; import net.java.sip.communicator.service.neomedia.device.*; +import net.java.sip.communicator.service.neomedia.event.*; import net.java.sip.communicator.service.neomedia.format.*; /** @@ -91,6 +92,12 @@ public class MediaServiceImpl private final List videoDevices = new ArrayList(); + /** + * A list of listeners registered for local user sound level events. + */ + private final List soundLevelListeners + = new Vector(); + /** * Creates a new MediaStream instance which will use the specified * MediaDevice for both capture and playback of media exchanged @@ -428,4 +435,66 @@ void start() void stop() { } + + /** + * Adds the given LocalUserSoundLevelListener to this operation set. + * @param l the LocalUserSoundLevelListener to add + */ + public void addLocalUserSoundLevelListener(LocalUserSoundLevelListener l) + { + synchronized(soundLevelListeners) + { + if (!soundLevelListeners.contains(l)) + soundLevelListeners.add(l); + } + } + + /** + * Removes the given LocalUserSoundLevelListener from this + * operation set. + * @param l the LocalUserSoundLevelListener to remove + */ + public void removeLocalUserSoundLevelListener(LocalUserSoundLevelListener l) + { + synchronized(soundLevelListeners) + { + soundLevelListeners.remove(l); + } + } + + /** + * Creates and dispatches a LocalUserSoundLevelEvent notifying + * registered listeners that the local user sound level has changed. + * + * @param level the new level + */ + public void fireLocalUserSoundLevelEvent(int level) + { + LocalUserSoundLevelEvent soundLevelEvent + = new LocalUserSoundLevelEvent(this, level); + List listeners; + + synchronized (soundLevelListeners) + { + listeners = + new ArrayList(soundLevelListeners); + } + + for (Iterator listenerIter + = listeners.iterator(); listenerIter.hasNext();) + { + LocalUserSoundLevelListener listener = listenerIter.next(); + + listener.localUserSoundLevelChanged(soundLevelEvent); + } + } + + /** + * All the local sound level listeners. + * @return the soundLevelListeners interested in local sound level changes. + */ + public List getLocalSoundLevelListeners() + { + return soundLevelListeners; + } } diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/SoundLevelIndicatorEffect.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/SoundLevelIndicatorEffect.java new file mode 100644 index 000000000..af7acfb40 --- /dev/null +++ b/src/net/java/sip/communicator/impl/neomedia/codec/audio/SoundLevelIndicatorEffect.java @@ -0,0 +1,282 @@ +/* + * 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.codec.audio; + +import javax.media.*; +import javax.media.format.*; + +/** + * An effect that calculates the power of the signal and fire an event + * with the current level. + * + * @author Damian Minkov + */ +public class SoundLevelIndicatorEffect + implements Effect +{ + private Format[] supportedAudioFormats; + + /** + * Input Format + */ + private AudioFormat inputFormat; + + /** + * Output Format + */ + private AudioFormat outputFormat; + + private double levelRatio; + + private static int MAX_SOUND_LEVEL = Short.MAX_VALUE; + private static int MIN_SOUND_LEVEL = Short.MIN_VALUE; + + private int lastLevel = 0; + + private SoundLevelIndicatorListener listener = null; + + /** + * The minimum and maximum values of the scale + * @param minLevel min level. + * @param maxLevel max lavel. + * @param listener the listener of the sound level changes. + */ + public SoundLevelIndicatorEffect(int minLevel, int maxLevel, + SoundLevelIndicatorListener listener) + { + this.listener = listener; + + levelRatio = MAX_SOUND_LEVEL/(maxLevel - minLevel); + + supportedAudioFormats = new Format[]{ + new AudioFormat( + AudioFormat.LINEAR, + Format.NOT_SPECIFIED, + 16, + 1, + AudioFormat.LITTLE_ENDIAN, + AudioFormat.SIGNED, + 16, + Format.NOT_SPECIFIED, + Format.byteArray) + }; + } + + /** + * Lists all of the input formats that this codec accepts. + * @return An array that contains the supported input Formats. + */ + public Format[] getSupportedInputFormats() + { + return supportedAudioFormats; + } + + /** + * Lists the output formats that this codec can generate. + * @param input The Format of the data to be used + * as input to the plug-in. + * @return An array that contains the supported output Formats. + */ + public Format[] getSupportedOutputFormats(Format input) + { + return supportedAudioFormats; + } + + /** + * Sets the format of the data to be input to this codec. + * @param format The Format to be set. + * @return The Format that was set. + */ + public Format setInputFormat(Format format) + { + this.inputFormat = (AudioFormat)format; + return inputFormat; + } + + /** + * Sets the format for the data this codec outputs. + * @param format The Format to be set. + * @return The Format that was set. + */ + public Format setOutputFormat(Format format) + { + this.outputFormat = (AudioFormat)format; + return outputFormat; + } + + /** + * Performs the media processing defined by this codec. + * @param inputBuffer The Buffer that contains the media data + * to be processed. + * @param outputBuffer The Buffer in which to store + * the processed media data. + * @return BUFFER_PROCESSED_OK if the processing is successful. + * @see PlugIn + */ + public int process(Buffer inputBuffer, Buffer outputBuffer) + { + byte[] b = new byte[inputBuffer.getLength()]; + System.arraycopy(inputBuffer.getData(), inputBuffer.getOffset(), b, 0, b.length); + outputBuffer.setData(b); + + outputBuffer.setData(b); + outputBuffer.setFormat(inputBuffer.getFormat()); + outputBuffer.setLength(inputBuffer.getLength()); + outputBuffer.setOffset(inputBuffer.getOffset()); + outputBuffer.setHeader(inputBuffer.getHeader()); + outputBuffer.setSequenceNumber(inputBuffer.getSequenceNumber()); + outputBuffer.setTimeStamp(inputBuffer.getTimeStamp()); + outputBuffer.setFlags(inputBuffer.getFlags()); + outputBuffer.setDiscard(inputBuffer.isDiscard()); + outputBuffer.setEOM(inputBuffer.isEOM()); + outputBuffer.setDuration(inputBuffer.getDuration()); + + int newLevel = calculateCurrentSignalPower( + b, 0, b.length, levelRatio); + + if(newLevel != lastLevel) + listener.soundLevelChanged(newLevel); + + lastLevel = newLevel; + + return BUFFER_PROCESSED_OK; + } + + + /** + * Estimates the signal power and use the levelRatio to + * scale it to the needed levels. + * @param buff the buffer with the data. + * @param offset the offset that data starts. + * @param len the length of the data + * @param levelRatio the ratio for scaling to the needed levels + * @return the power of the signal in dB SWL. + */ + public static int calculateCurrentSignalPower( + byte[] buff, int offset, int len, double levelRatio) + { + if(len == 0) + return 0; + + int samplesNumber = len/2; + int absoluteMeanSoundLevel = 0; + // Do the processing + for (int i = 0; i < samplesNumber; i++) + { + int tempL = buff[offset++]; + int tempH = buff[offset++]; + int soundLevel = tempH << 8 | (tempL & 255); + + if (soundLevel > MAX_SOUND_LEVEL) + { + soundLevel = MAX_SOUND_LEVEL; + } else if (soundLevel < MIN_SOUND_LEVEL) { + soundLevel = MIN_SOUND_LEVEL; + } + + absoluteMeanSoundLevel += Math.abs(soundLevel); + } + + return (int)(absoluteMeanSoundLevel/samplesNumber/levelRatio); + } + + /** + * Gets the name of this plug-in as a human-readable string. + * @return A String that contains the descriptive name of the + * plug-in. + */ + public String getName() + { + return "SoundLevelIndicator Effect"; + } + + /** + * Opens this effect. + * @throws ResourceUnavailableException If all of the required resources + * cannot be acquired. + */ + public void open() + throws ResourceUnavailableException + { + } + + /** + * Closes this effect. + */ + public void close() + { + } + + /** + * Restes its state. + */ + public void reset() + { + } + + /** + * Obtain the collection of objects that + * control the object that implements this interface. + *

+ * + * If no controls are supported, a zero length + * array is returned. + * + * @return the collection of object controls + */ + public Object[] getControls() + { + return new Control[0]; + } + + /** + * Obtain the object that implements the specified + * Class or Interface + * The full class or interface name must be used. + *

+ * + * If the control is not supported then null + * is returned. + * + * @param controlType the control type to return. + * @return the object that implements the control, + * or null. + */ + public Object getControl(String controlType) + { + try + { + Class cls = Class.forName(controlType); + Object cs[] = getControls(); + for(int i = 0; i < cs.length; i++) + { + if(cls.isInstance(cs[i])) + { + return cs[i]; + } + } + return null; + + } + catch (Exception e) + { + return null; + } + } + + /** + * Lister for the changes in the sound level. + */ + public static interface SoundLevelIndicatorListener + { + /** + * Called when the sound level is changing. + * @param level the new level. + */ + public void soundLevelChanged(int level); + } +} diff --git a/src/net/java/sip/communicator/impl/neomedia/device/MediaDeviceSession.java b/src/net/java/sip/communicator/impl/neomedia/device/MediaDeviceSession.java index 501204b54..30cf6b46c 100644 --- a/src/net/java/sip/communicator/impl/neomedia/device/MediaDeviceSession.java +++ b/src/net/java/sip/communicator/impl/neomedia/device/MediaDeviceSession.java @@ -17,9 +17,11 @@ import javax.media.rtp.*; import net.java.sip.communicator.impl.neomedia.*; +import net.java.sip.communicator.impl.neomedia.codec.audio.*; import net.java.sip.communicator.impl.neomedia.format.*; import net.java.sip.communicator.service.neomedia.*; import net.java.sip.communicator.service.neomedia.device.*; +import net.java.sip.communicator.service.neomedia.event.*; import net.java.sip.communicator.service.neomedia.format.*; import net.java.sip.communicator.util.*; @@ -86,15 +88,15 @@ public class MediaDeviceSession private ControllerListener playerControllerListener; /** - * The Players rendering ReceiveStreams on the + * The Processors rendering ReceiveStreams on the * MediaDevice represented by this instance. Associated with * DataSource because different ReceiveStreams may be * added with one and the same DataSource so it has to be clear - * when a new Player is to be created and when it is to be - * disposed. + * when a new Processor is to be created and when it is to be + * disposed. The Processor is used as a Player. */ - private final Map players - = new HashMap(); + private final Map players + = new HashMap(); /** * The JMF Processor which transcodes {@link #captureDevice} into @@ -200,7 +202,7 @@ protected void addReceiveStream( synchronized (players) { - Player player = players.get(receiveStreamDataSource); + Processor player = players.get(receiveStreamDataSource); if (player == null) { @@ -208,7 +210,7 @@ protected void addReceiveStream( try { - player = Manager.createPlayer(receiveStreamDataSource); + player = Manager.createProcessor(receiveStreamDataSource); } catch (IOException ioe) { @@ -227,29 +229,39 @@ protected void addReceiveStream( exception); else { - if (playerControllerListener == null) - playerControllerListener = new ControllerListener() - { - - /** - * Notifies this ControllerListener that - * the Controller which it is registered - * with has generated an event. - * - * @param event the ControllerEvent - * specifying the Controller which is the - * source of the event and the very type of the - * event - * @see ControllerListener#controllerUpdate( - * ControllerEvent) - */ - public void controllerUpdate(ControllerEvent event) - { - playerControllerUpdate(event); - } - }; - player.addControllerListener(playerControllerListener); - player.realize(); + waitForState(player, Processor.Configured); +// // here we add sound level indicator for every incoming +// //stream +// try +// { +// TrackControl tc[] = player.getTrackControls(); +// if (tc != null) +// { +// for (int i = 0; i < tc.length; i++) +// { +// if (tc[i].getFormat() instanceof AudioFormat) +// { +// // Assume there is only one audio track +// tc[i].setCodecChain(new Codec[]{ +// new SoundLevelIndicatorEffect()}); +// break; +// } +// } +// } +// } +// catch (UnsupportedPlugInException ex) +// { +// logger.error("The processor does not support effects", ex); +// } + // to use the processor as player we must se its + // content descriptor to null + player.setContentDescriptor(null); + + waitForState(player, Processor.Realized); + + player.start(); + + realizeComplete(player); if (logger.isTraceEnabled()) logger @@ -421,16 +433,17 @@ private void disconnectCaptureDevice() } /** - * Releases the resources allocated by a specific Player in the + * Releases the resources allocated by a specific Processor in the * course of its execution and prepares it to be garbage collected. + * The Processor is used as a Player. * - * @param player the Player to dispose of + * @param player the Processor to dispose of */ - protected void disposePlayer(Player player) + protected void disposePlayer(Processor player) { synchronized (players) { - Iterator> playerIter + Iterator> playerIter = players.entrySet().iterator(); while (playerIter.hasNext()) @@ -456,7 +469,7 @@ private void disposePlayers() { synchronized (players) { - for (Player player : getPlayers()) + for (Processor player : getPlayers()) disposePlayer(player); } } @@ -638,20 +651,21 @@ public DataSource getOutputDataSource() } /** - * Gets the Players rendering ReceiveStreams for this + * Gets the Processorss rendering ReceiveStreams for this * instance on its associated MediaDevice. The returned * List is a copy of the internal storage and, consequently, * modifications to it do not affect this instance. + * The Processors are used as a Players. * - * @return a new List of Players rendering + * @return a new List of Processors rendering * ReceiveStreams for this instance on its associated * MediaDevice */ - protected List getPlayers() + protected List getPlayers() { synchronized (players) { - return new ArrayList(players.values()); + return new ArrayList(players.values()); } } @@ -784,35 +798,6 @@ public List getSupportedFormats() return supportedMediaFormats; } - /** - * Gets notified about ControllerEvents generated by the - * Player instances in {@link #players}. - * - * @param event the ControllerEvent specifying the - * Controller which is the source of the event and the very type of - * the event - */ - private void playerControllerUpdate(ControllerEvent event) - { - if (event instanceof RealizeCompleteEvent) - { - Player player = (Player) event.getSourceController(); - - if (player != null) - { - if (logger.isTraceEnabled()) - logger - .trace( - "Realized Player with hashCode " - + player.hashCode()); - - player.start(); - - realizeComplete(player); - } - } - } - /** * Gets notified about ControllerEvents generated by * {@link #processor}. @@ -846,6 +831,33 @@ private void processorControllerUpdate(ControllerEvent event) if (format != null) setFormat(processor, format); + + if(NeomediaActivator.getMediaServiceImpl() + .getLocalSoundLevelListeners().size() > 0) + { + // here we add sound level indicator for captured media + // from the microphone if there are interested listeners + try + { + TrackControl tc[] = processor.getTrackControls(); + if (tc != null) + { + for (int i = 0; i < tc.length; i++) + { + if (tc[i].getFormat() instanceof AudioFormat) + { + addSpundLevelIndicator(tc[i]); + break; + } + } + } + } + catch (UnsupportedPlugInException ex) + { + logger.error( + "Unsupported sound level indicator effect", ex); + } + } } } else if (event instanceof ControllerClosedEvent) @@ -865,14 +877,40 @@ else if (event instanceof ControllerClosedEvent) } /** - * Notifies this instance that a specific Player of remote content - * has generated a RealizeCompleteEvent. Allows extenders to carry - * out additional processing on the Player. + * Creates sound level indicator effect and add it to the + * codec chain of the TrackControl and + * assumes there is only one audio track. + * @param tc the track control. + * @throws UnsupportedPlugInException + */ + private void addSpundLevelIndicator(TrackControl tc) + throws UnsupportedPlugInException + { + SoundLevelIndicatorEffect slie = new SoundLevelIndicatorEffect( + LocalUserSoundLevelEvent.MIN_LEVEL, + LocalUserSoundLevelEvent.MAX_LEVEL, + new SoundLevelIndicatorEffect.SoundLevelIndicatorListener() + { + public void soundLevelChanged(int level) + { + NeomediaActivator.getMediaServiceImpl() + .fireLocalUserSoundLevelEvent(level); + } + }); + // Assume there is only one audio track + tc.setCodecChain(new Codec[]{slie}); + } + + /** + * Notifies this instance that a specific Processor of + * remote content has generated a RealizeCompleteEvent. + * Allows extenders to carry out additional processing on the + * Processor. The Processor is used as a Player. * - * @param player the Player which is the source of a + * @param player the Processor which is the source of a * RealizeCompleteEvent */ - protected void realizeComplete(Player player) + protected void realizeComplete(Processor player) { } @@ -893,7 +931,7 @@ public void removeReceiveStream(ReceiveStream receiveStream) && !receiveStreams.containsValue(receiveStreamDataSource)) synchronized (players) { - Player player = players.get(receiveStreamDataSource); + Processor player = players.get(receiveStreamDataSource); if (player != null) disposePlayer(player); diff --git a/src/net/java/sip/communicator/impl/neomedia/device/VideoMediaDeviceSession.java b/src/net/java/sip/communicator/impl/neomedia/device/VideoMediaDeviceSession.java index f2f0b4798..0e4338438 100644 --- a/src/net/java/sip/communicator/impl/neomedia/device/VideoMediaDeviceSession.java +++ b/src/net/java/sip/communicator/impl/neomedia/device/VideoMediaDeviceSession.java @@ -86,18 +86,19 @@ protected void checkDevice(AbstractMediaDevice device) } /** - * Releases the resources allocated by a specific Player in the + * Releases the resources allocated by a specific Processor in the * course of its execution and prepares it to be garbage collected. If the - * specified Player is rendering video, notifies the + * specified Processor is rendering video, notifies the * VideoListeners of this instance that its visual * Component is to no longer be used by firing a * {@link VideoEvent#VIDEO_REMOVED} VideoEvent. * - * @param player the Player to dispose of + * @param player the Processor to dispose of, + * the processor is used as Player. * @see MediaDeviceSession#disposePlayer(Player) */ @Override - protected void disposePlayer(Player player) + protected void disposePlayer(Processor player) { /* @@ -159,7 +160,7 @@ protected boolean fireVideoEvent( */ public Component getVisualComponent() { - for (Player player : getPlayers()) + for (Processor player : getPlayers()) { Component visualComponent = getVisualComponent(player); @@ -170,17 +171,19 @@ public Component getVisualComponent() } /** - * Gets the visual Component of a specific Player if it + * Gets the visual Component of a specific Processor if it * has one and ignores the failure to access it if the specified - * Player is unrealized. + * Processor is unrealized. + * The Processor is used as Player. * * @param player the Player to get the visual Component of * if it has one * @return the visual Component of the specified Player if - * it has one; null if the specified Player does not have - * a visual Component or the Player is unrealized + * it has one; null if the specified Processor + * does not have a visual Component or + * the Processor is unrealized. */ - private static Component getVisualComponent(Player player) + private static Component getVisualComponent(Processor player) { Component visualComponent; @@ -204,15 +207,16 @@ private static Component getVisualComponent(Player player) } /** - * Notifies this instance that a specific Player of remote content - * has generated a RealizeCompleteEvent. + * Notifies this instance that a specific Processor of remote + * content has generated a RealizeCompleteEvent. + * The Processor is used as Player. * - * @param player the Player which is the source of a - * RealizeCompleteEvent + * @param player the Processor which is the source of a + * RealizeCompleteEvent. * @see MediaDeviceSession#realizeComplete(Player) */ @Override - protected void realizeComplete(Player player) + protected void realizeComplete(Processor player) { super.realizeComplete(player); diff --git a/src/net/java/sip/communicator/impl/protocol/gibberish/OperationSetTelephonyConferencingGibberishImpl.java b/src/net/java/sip/communicator/impl/protocol/gibberish/OperationSetTelephonyConferencingGibberishImpl.java index 225460578..cae3631d8 100644 --- a/src/net/java/sip/communicator/impl/protocol/gibberish/OperationSetTelephonyConferencingGibberishImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/gibberish/OperationSetTelephonyConferencingGibberishImpl.java @@ -82,19 +82,6 @@ public Call createConfCall(String[] callees) telephonyOpSet.fireCallEvent(CallEvent.CALL_INITIATED, newCall); - final Random random = new Random(); - Timer timer1 = new Timer(false); - timer1.scheduleAtFixedRate(new TimerTask() - { - @Override - public void run() - { - telephonyOpSet.fireLocalUserSoundLevelEvent( - protocolProvider, - random.nextInt(255)); - } - }, 500, 100); - return newCall; } diff --git a/src/net/java/sip/communicator/service/neomedia/AudioMediaStream.java b/src/net/java/sip/communicator/service/neomedia/AudioMediaStream.java index 242800cb0..d3a0dbff5 100644 --- a/src/net/java/sip/communicator/service/neomedia/AudioMediaStream.java +++ b/src/net/java/sip/communicator/service/neomedia/AudioMediaStream.java @@ -20,7 +20,7 @@ public interface AudioMediaStream /** * Adds listener to the list of SoundLevelListeners * registered to receive notifications for changes in the levels of - * conference participants that the remote party could be mixing. + * remote participant. * * @param listener the SoundLevelListener that we'd like to * register. @@ -36,6 +36,27 @@ public interface AudioMediaStream */ public void removeSoundLevelListener(SoundLevelListener listener); + /** + * Adds listener to the list of SoundLevelListeners + * registered to receive notifications for changes in the levels of + * conference participants that the remote party could be mixing. + * + * @param listener the SoundLevelListener that we'd like to + * register. + */ + public void addConferenceMemberSoundLevelListener( + SoundLevelListener listener); + + /** + * Removes listener from the list of SoundLevelListeners + * registered to receive notification events upon changes of the sound + * level. + * + * @param listener the listener that we'd like to unregister. + */ + public void removeConferenceMemberSoundLevelListener( + SoundLevelListener listener); + /** * Starts sending the specified DTMFTone until the * stopSendingDTMF() method is called. Callers should keep in mind diff --git a/src/net/java/sip/communicator/service/neomedia/MediaService.java b/src/net/java/sip/communicator/service/neomedia/MediaService.java index 0eff6a22a..444f47216 100644 --- a/src/net/java/sip/communicator/service/neomedia/MediaService.java +++ b/src/net/java/sip/communicator/service/neomedia/MediaService.java @@ -9,6 +9,7 @@ import java.util.*; import net.java.sip.communicator.service.neomedia.device.*; +import net.java.sip.communicator.service.neomedia.event.*; import net.java.sip.communicator.service.neomedia.format.*; /** @@ -87,4 +88,17 @@ public MediaStream createMediaStream(StreamConnector connector, * with the MediaStreams created by this MediaService */ public MediaFormatFactory getFormatFactory(); + + /** + * Adds the given LocalUserSoundLevelListener to this operation set. + * @param l the LocalUserSoundLevelListener to add + */ + public void addLocalUserSoundLevelListener(LocalUserSoundLevelListener l); + + /** + * Removes the given LocalUserSoundLevelListener from this + * operation set. + * @param l the LocalUserSoundLevelListener to remove + */ + public void removeLocalUserSoundLevelListener(LocalUserSoundLevelListener l); } diff --git a/src/net/java/sip/communicator/service/protocol/event/LocalUserSoundLevelEvent.java b/src/net/java/sip/communicator/service/neomedia/event/LocalUserSoundLevelEvent.java similarity index 86% rename from src/net/java/sip/communicator/service/protocol/event/LocalUserSoundLevelEvent.java rename to src/net/java/sip/communicator/service/neomedia/event/LocalUserSoundLevelEvent.java index 742b089b7..3e38c21f8 100644 --- a/src/net/java/sip/communicator/service/protocol/event/LocalUserSoundLevelEvent.java +++ b/src/net/java/sip/communicator/service/neomedia/event/LocalUserSoundLevelEvent.java @@ -4,7 +4,7 @@ * Distributable under LGPL license. * See terms of license at gnu.org. */ -package net.java.sip.communicator.service.protocol.event; +package net.java.sip.communicator.service.neomedia.event; import java.util.*; @@ -38,15 +38,13 @@ public class LocalUserSoundLevelEvent /** * Creates an StreamSoundLevelEvent for the given callPeer * by indicating the current sound level of the audio stream. - * - * @param protocolProvider the ProtocolProviderService + * + * @param source the source of the new LocalUserSoundLevelEvent. * @param level the current sound level of the audio stream */ - public LocalUserSoundLevelEvent( - ProtocolProviderService protocolProvider, int level) + public LocalUserSoundLevelEvent(Object source, int level) { - super(protocolProvider); - + super(source); this.level = level; } diff --git a/src/net/java/sip/communicator/service/protocol/event/LocalUserSoundLevelListener.java b/src/net/java/sip/communicator/service/neomedia/event/LocalUserSoundLevelListener.java similarity index 91% rename from src/net/java/sip/communicator/service/protocol/event/LocalUserSoundLevelListener.java rename to src/net/java/sip/communicator/service/neomedia/event/LocalUserSoundLevelListener.java index 2a0bdb8d5..b6b37a75a 100644 --- a/src/net/java/sip/communicator/service/protocol/event/LocalUserSoundLevelListener.java +++ b/src/net/java/sip/communicator/service/neomedia/event/LocalUserSoundLevelListener.java @@ -4,7 +4,7 @@ * Distributable under LGPL license. * See terms of license at gnu.org. */ -package net.java.sip.communicator.service.protocol.event; +package net.java.sip.communicator.service.neomedia.event; /** * Notifies interested parties in sound level changes of the local user audio diff --git a/src/net/java/sip/communicator/service/protocol/AbstractOperationSetBasicTelephony.java b/src/net/java/sip/communicator/service/protocol/AbstractOperationSetBasicTelephony.java index a01d31f87..307ffd1a9 100644 --- a/src/net/java/sip/communicator/service/protocol/AbstractOperationSetBasicTelephony.java +++ b/src/net/java/sip/communicator/service/protocol/AbstractOperationSetBasicTelephony.java @@ -32,12 +32,6 @@ public abstract class AbstractOperationSetBasicTelephony */ private final List callListeners = new Vector(); - /** - * A list of listeners registered for local user sound level events. - */ - private final List soundLevelListeners - = new Vector(); - /** * Registers listener with this provider so that it * could be notified when incoming calls are received. @@ -127,63 +121,4 @@ public void setMute(CallPeer peer, boolean mute) * this implementation takes inspiration from them. */ } - - /** - * Adds the given LocalUserSoundLevelListener to this operation set. - * @param l the LocalUserSoundLevelListener to add - */ - public void addLocalUserSoundLevelListener(LocalUserSoundLevelListener l) - { - synchronized(soundLevelListeners) - { - if (!soundLevelListeners.contains(l)) - soundLevelListeners.add(l); - } - } - - /** - * Removes the given LocalUserSoundLevelListener from this - * operation set. - * @param l the LocalUserSoundLevelListener to remove - */ - public void removeLocalUserSoundLevelListener(LocalUserSoundLevelListener l) - { - synchronized(soundLevelListeners) - { - soundLevelListeners.remove(l); - } - } - - /** - * Creates and dispatches a LocalUserSoundLevelEvent notifying - * registered listeners that the local user sound level has changed. - * - * @param protocolProvider the protocol provider for which the level is - * @param level the new level - */ - public void fireLocalUserSoundLevelEvent( - ProtocolProviderService protocolProvider, int level) - { - LocalUserSoundLevelEvent soundLevelEvent - = new LocalUserSoundLevelEvent(protocolProvider, level); - List listeners; - - synchronized (soundLevelListeners) - { - listeners = new ArrayList( - soundLevelListeners); - } - - logger.debug("Dispatching a LocalUserSoundLevelEvent to " - + listeners.size() - + " listeners. event is: " + soundLevelEvent); - - for (Iterator listenerIter - = listeners.iterator(); listenerIter.hasNext();) - { - LocalUserSoundLevelListener listener = listenerIter.next(); - - listener.localUserSoundLevelChanged(soundLevelEvent); - } - } } diff --git a/src/net/java/sip/communicator/service/protocol/OperationSetBasicTelephony.java b/src/net/java/sip/communicator/service/protocol/OperationSetBasicTelephony.java index 23963e966..42af141f1 100644 --- a/src/net/java/sip/communicator/service/protocol/OperationSetBasicTelephony.java +++ b/src/net/java/sip/communicator/service/protocol/OperationSetBasicTelephony.java @@ -149,17 +149,4 @@ public void hangupCallPeer(CallPeer peer) * peer; otherwise, false */ public void setMute(CallPeer peer, boolean mute); - - /** - * Adds the given LocalUserSoundLevelListener to this operation set. - * @param l the LocalUserSoundLevelListener to add - */ - public void addLocalUserSoundLevelListener(LocalUserSoundLevelListener l); - - /** - * Removes the given LocalUserSoundLevelListener from this - * operation set. - * @param l the LocalUserSoundLevelListener to remove - */ - public void removeLocalUserSoundLevelListener(LocalUserSoundLevelListener l); }