Skip to content

Commit

Permalink
Resolves #387 10 second/10 minute audio recording time limit.
Browse files Browse the repository at this point in the history
Updated audio packet wave recorder to correctly dequeue audio packets
to ensure that the overflowable buffer queue accounting process was
working correctly.

Updated overflowable buffer queue's poll() method to correctly decrement
the queue size counter.

Resolved issue where the mutable metadata was being prematurely reset
and causing the end audio packet to be mis-identified.  This resulted
in the recording manager not stopping the recording on command with the
timeout mechanism kicking in after a brief delay.
  • Loading branch information
Denny committed Oct 8, 2018
1 parent d95c78c commit eb79d9e
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 27 deletions.
Expand Up @@ -114,6 +114,8 @@ public MutableMetadata getMutableMetadata()
@Override
public void reset()
{
getMutableMetadata().resetTemporalAttributes();

broadcast(new DecoderStateEvent(this, Event.RESET, State.IDLE));

mState = State.IDLE;
Expand Down Expand Up @@ -401,8 +403,6 @@ private void processTeardownState()
{
broadcast(SquelchState.SQUELCH);

getMutableMetadata().resetTemporalAttributes();

mState = State.TEARDOWN;

mMutableMetadata.receive(new AttributeChangeRequest<State>(Attribute.CHANNEL_STATE, mState));
Expand Down
@@ -1,20 +1,22 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
/*
* ******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2018 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* *****************************************************************************
*/
package io.github.dsheirer.record.config;

import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
Expand All @@ -24,32 +26,64 @@
import java.util.ArrayList;
import java.util.List;

/**
* Contains the types of recordings specified for a channel
*/
public class RecordConfiguration extends Configuration
{
/**
* Recording types requested for this configuration
*/
private List<RecorderType> mRecorders = new ArrayList<>();

/**
* Constructs a recording configuration instance
*/
public RecordConfiguration()
{
//Empty constructor required for deserialization
}

/**
* List of recorder types specified in this configuration
*/
@JacksonXmlProperty(isAttribute = false, localName = "recorder")
public List<RecorderType> getRecorders()
{
return mRecorders;
}

/**
* Sets the (complete) list of recorder types for this configuration, erasing any existing recording types.
*/
public void setRecorders(List<RecorderType> recorders)
{
mRecorders = recorders;
}

/**
* Adds the recorder type to the configuration
*/
public void addRecorder(RecorderType recorder)
{
mRecorders.add(recorder);
}

/**
* Clears all recorder types from this configuration
*/
public void clearRecorders()
{
mRecorders.clear();
}

/**
* Indicates if this configuration has the specified recorder type
* @param recorderType to check
* @return true if this configuration contains the specified recorder type
*/
public boolean contains(RecorderType recorderType)
{
return mRecorders.contains(recorderType);
}
}
Expand Up @@ -32,6 +32,8 @@
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
Expand All @@ -54,6 +56,7 @@ public class AudioPacketWaveRecorder extends Module implements Listener<Reusable
private ScheduledFuture<?> mProcessorHandle;
private Metadata mMetadata;
private long mLastBufferReceived;
private List<ReusableAudioPacket> mAudioPacketsToProcess = new ArrayList<>();

private AtomicBoolean mRunning = new AtomicBoolean();

Expand Down Expand Up @@ -186,24 +189,24 @@ public void reset()
*/
private void write() throws IOException
{
ReusableAudioPacket audioPacket = mTransferQueue.poll();
mTransferQueue.drainTo(mAudioPacketsToProcess);

while(audioPacket != null && audioPacket.getType() == ReusableAudioPacket.Type.AUDIO)
for(ReusableAudioPacket audioPacket: mAudioPacketsToProcess)
{
if(audioPacket.hasMetadata())
if(audioPacket.getType() == ReusableAudioPacket.Type.AUDIO)
{
mMetadata = audioPacket.getMetadata();
if(audioPacket.hasMetadata())
{
mMetadata = audioPacket.getMetadata();
}

mWriter.writeData(ConversionUtils.convertToSigned16BitSamples(audioPacket.getAudioSamples()));
}

mWriter.writeData(ConversionUtils.convertToSigned16BitSamples(audioPacket.getAudioSamples()));
audioPacket.decrementUserCount();
audioPacket = mTransferQueue.poll();
}

if(audioPacket != null)
{
audioPacket.decrementUserCount();
}
mAudioPacketsToProcess.clear();
}

/**
Expand Down
Expand Up @@ -101,7 +101,14 @@ protected void overflow(E e)
*/
public E poll()
{
return mQueue.poll();
E element = mQueue.poll();

if(element != null)
{
mCounter.decrementAndGet();
}

return element;
}

/**
Expand Down

1 comment on commit eb79d9e

@ImagoTrigger
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

Please sign in to comment.