#438 Adds feature for duplicate call audio detection and suppression for playback, recording and streaming. (#835)

Co-authored-by: Denny <denny@denny-desktop>
This commit is contained in:
Denny Sheirer
2020-05-27 06:08:53 -04:00
committed by GitHub
parent ad194d1bab
commit a1e8c761ef
16 changed files with 858 additions and 33 deletions

View File

@@ -381,8 +381,9 @@ public abstract class AudioOutput implements LineListener, Listener<IdentifierUp
try
{
//Remove an assigned audio segment that's subsequently flagged as do not monitor before playback
if(mNextAudioSegment.isDoNotMonitor())
//Remove an assigned segment that's subsequently flagged as duplicate or do not monitor before playback
if(mNextAudioSegment.isDoNotMonitor() || (mNextAudioSegment.isDuplicate() &&
mUserPreferences.getDuplicateCallDetectionPreference().isDuplicatePlaybackSuppressionEnabled()))
{
mNextAudioSegment = null;
@@ -456,9 +457,11 @@ public abstract class AudioOutput implements LineListener, Listener<IdentifierUp
if(mCurrentAudioSegment != null)
{
//Check for completed audio segment or a segment flagged as Do Not Monitor
if(mCurrentAudioSegment.isDoNotMonitor() || (mCurrentAudioSegment.completeProperty().get() &&
mCurrentBufferIndex >= mCurrentAudioSegment.getAudioBufferCount()))
//Check for completed audio segment or a segment flagged as duplicate or Do Not Monitor
if(mCurrentAudioSegment.isDoNotMonitor() ||
(mCurrentAudioSegment.isDuplicate() &&
mUserPreferences.getDuplicateCallDetectionPreference().isDuplicatePlaybackSuppressionEnabled()) ||
(mCurrentAudioSegment.completeProperty().get() && mCurrentBufferIndex >= mCurrentAudioSegment.getAudioBufferCount()))
{
if(mCurrentAudioSegment.isDoNotMonitor())
{
@@ -490,7 +493,8 @@ public abstract class AudioOutput implements LineListener, Listener<IdentifierUp
//segment is a linked segment, ignore it so that we can close out the current segment.
while(mCurrentAudioSegment != null && (mNextAudioSegment == null || mNextAudioSegment.isLinked()) &&
mCurrentBufferIndex < mCurrentAudioSegment.getAudioBufferCount() &&
!mCurrentAudioSegment.isDoNotMonitor())
!mCurrentAudioSegment.isDoNotMonitor() && !(mCurrentAudioSegment.isDuplicate() &&
mUserPreferences.getDuplicateCallDetectionPreference().isDuplicatePlaybackSuppressionEnabled()))
{
float[] audioBuffer = mCurrentAudioSegment.getAudioBuffers().get(mCurrentBufferIndex++);

View File

@@ -27,20 +27,15 @@ import io.github.dsheirer.audio.IAudioController;
import io.github.dsheirer.eventbus.MyEventBus;
import io.github.dsheirer.preference.PreferenceType;
import io.github.dsheirer.preference.UserPreferences;
import io.github.dsheirer.properties.SystemProperties;
import io.github.dsheirer.sample.Broadcaster;
import io.github.dsheirer.sample.Listener;
import io.github.dsheirer.source.mixer.MixerChannel;
import io.github.dsheirer.source.mixer.MixerChannelConfiguration;
import io.github.dsheirer.source.mixer.MixerManager;
import io.github.dsheirer.util.ThreadPool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Mixer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
@@ -123,7 +118,12 @@ public class AudioPlaybackManager implements Listener<AudioSegment>, IAudioContr
while(newSegment != null)
{
if(newSegment.hasAudio())
if(newSegment.isDuplicate() &&
mUserPreferences.getDuplicateCallDetectionPreference().isDuplicatePlaybackSuppressionEnabled())
{
newSegment.decrementConsumerCount();
}
else if(newSegment.hasAudio())
{
mAudioSegments.add(newSegment);
}
@@ -146,7 +146,13 @@ public class AudioPlaybackManager implements Listener<AudioSegment>, IAudioContr
{
audioSegment = it.next();
if(audioSegment.hasAudio())
if(audioSegment.isDuplicate() &&
mUserPreferences.getDuplicateCallDetectionPreference().isDuplicatePlaybackSuppressionEnabled())
{
it.remove();
audioSegment.decrementConsumerCount();
}
else if(audioSegment.hasAudio())
{
//Queue it up for replay
it.remove();
@@ -174,7 +180,8 @@ public class AudioPlaybackManager implements Listener<AudioSegment>, IAudioContr
{
audioSegment = it.next();
if(audioSegment.isDoNotMonitor())
if(audioSegment.isDoNotMonitor() || (audioSegment.isDuplicate() &&
mUserPreferences.getDuplicateCallDetectionPreference().isDuplicatePlaybackSuppressionEnabled()))
{
it.remove();
audioSegment.decrementConsumerCount();
@@ -235,7 +242,8 @@ public class AudioPlaybackManager implements Listener<AudioSegment>, IAudioContr
{
audioSegment = it.next();
if(audioSegment.completeProperty().get())
if(audioSegment.completeProperty().get() || (audioSegment.isDuplicate() &&
mUserPreferences.getDuplicateCallDetectionPreference().isDuplicatePlaybackSuppressionEnabled()))
{
it.remove();
audioSegment.decrementConsumerCount();