Skip to content

Commit

Permalink
Moves the active speaker code.
Browse files Browse the repository at this point in the history
  • Loading branch information
bgrozev committed Apr 1, 2019
1 parent fb8922e commit c8eaf8b
Show file tree
Hide file tree
Showing 5 changed files with 1,829 additions and 0 deletions.
119 changes: 119 additions & 0 deletions src/main/java/org/jitsi/utils/dsi/AbstractActiveSpeakerDetector.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
/*
* Copyright @ 2015 Atlassian Pty Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jitsi.utils.dsi;

import java.util.*;

/**
* Provides a base {@link ActiveSpeakerDetector} which aids the implementations
* of actual algorithms for the detection/identification of the active/dominant
* speaker in a multipoint conference.
*
* @author Boris Grozev
* @author Lyubomir Marinov
*/
public abstract class AbstractActiveSpeakerDetector
implements ActiveSpeakerDetector
{
/**
* An empty array with element type <tt>ActiveSpeakerChangedListener</tt>.
* Explicitly defined for the purposes of reducing the total number of
* unnecessary allocations and the undesired effects of the garbage
* collector.
*/
private static final ActiveSpeakerChangedListener[] NO_LISTENERS
= new ActiveSpeakerChangedListener[0];

/**
* The list of listeners to be notified by this detector when the active
* speaker changes.
*/
private final List<ActiveSpeakerChangedListener> listeners
= new LinkedList<ActiveSpeakerChangedListener>();

/**
* {@inheritDoc}
*
* @throws NullPointerException if the specified <tt>listener</tt> is
* <tt>null</tt>
*/
@Override
public void addActiveSpeakerChangedListener(
ActiveSpeakerChangedListener listener)
{
if (listener == null)
throw new NullPointerException("listener");

synchronized (listeners)
{
if (!listeners.contains(listener))
listeners.add(listener);
}
}

/**
* Notifies the <tt>ActiveSpeakerChangedListener</tt>s registered with this
* instance that the active speaker in multipoint conference associated with
* this instance has changed and is identified by a specific synchronization
* source identifier/SSRC.
*
* @param ssrc the synchronization source identifier/SSRC of the active
* speaker in the multipoint conference
*/
protected void fireActiveSpeakerChanged(long ssrc)
{
ActiveSpeakerChangedListener[] listeners
= getActiveSpeakerChangedListeners();

for (ActiveSpeakerChangedListener listener : listeners)
listener.activeSpeakerChanged(ssrc);
}

/**
* Gets the list of listeners to be notified by this detector when the
* active speaker changes.
*
* @return an array of the listeners to be notified by this detector when
* the active speaker changes. If no such listeners are registered with this
* instance, an empty array is returned.
*/
protected ActiveSpeakerChangedListener[] getActiveSpeakerChangedListeners()
{
synchronized (listeners)
{
return
(listeners.size() == 0)
? NO_LISTENERS
: listeners.toArray(NO_LISTENERS);
}
}

/**
* {@inheritDoc}
*/
@Override
public void removeActiveSpeakerChangedListener(
ActiveSpeakerChangedListener listener)
{
if (listener != null)
{
synchronized (listeners)
{
listeners.remove(listener);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright @ 2015 Atlassian Pty Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jitsi.utils.dsi;

/**
* Implementing classes can be notified about changes to the 'active' stream
* (identified by its SSRC) using {@link #activeSpeakerChanged(long)}.
*
* @author Boris Grozev
*/
public interface ActiveSpeakerChangedListener
{
/**
* Notifies this listener that the active/dominant stream/speaker has been
* changed to one identified by a specific synchronization source
* identifier/SSRC.
*
* @param ssrc the SSRC of the latest/current active/dominant
* stream/speaker
*/
public void activeSpeakerChanged(long ssrc);
}
68 changes: 68 additions & 0 deletions src/main/java/org/jitsi/utils/dsi/ActiveSpeakerDetector.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* Copyright @ 2015 Atlassian Pty Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jitsi.utils.dsi;

/**
* Represents an algorithm for the detection/identification of the
* active/dominant speaker/participant/endpoint/stream in a multipoint
* conference.
* <p>
* Implementations of <tt>ActiveSpeakerDetector</tt> get notified about the
* (current) audio levels of multiple audio streams (identified by their
* synchronization source identifiers/SSRCs) via calls to
* {@link #levelChanged(long, int)} and determine/identify which stream is
* dominant/active (in terms of speech). When the active stream changes,
* listeners registered via
* {@link #addActiveSpeakerChangedListener(ActiveSpeakerChangedListener)} are
* notified.
* </p>
*
* @author Boris Grozev
* @author Lyubomir Marinov
*/
public interface ActiveSpeakerDetector
{
/**
* Adds a listener to be notified by this active speaker detector when the
* active stream changes.
*
* @param listener the listener to register with this instance for
* notifications about changes of the active speaker
*/
public void addActiveSpeakerChangedListener(
ActiveSpeakerChangedListener listener);

/**
* Notifies this <tt>ActiveSpeakerDetector</tt> about the latest/current
* audio level of a stream/speaker identified by a specific synchronization
* source identifier/SSRC.
*
* @param ssrc the SSRC of the stream/speaker
* @param level the latest/current audio level of the stream/speaker with
* the specified <tt>ssrc</tt>
*/
public void levelChanged(long ssrc, int level);

/**
* Removes a listener to no longer be notified by this active speaker
* detector when the active stream changes.
*
* @param listener the listener to unregister with this instance for
* notifications about changes of the active speaker
*/
public void removeActiveSpeakerChangedListener(
ActiveSpeakerChangedListener listener);
}
Loading

0 comments on commit c8eaf8b

Please sign in to comment.