mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-12 16:47:31 -05:00
Resolves #387 10 second/10 minute audio recording time limit.
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.
This commit is contained in:
@@ -114,6 +114,8 @@ public class ChannelState extends Module implements ICallEventProvider, IDecoder
|
||||
@Override
|
||||
public void reset()
|
||||
{
|
||||
getMutableMetadata().resetTemporalAttributes();
|
||||
|
||||
broadcast(new DecoderStateEvent(this, Event.RESET, State.IDLE));
|
||||
|
||||
mState = State.IDLE;
|
||||
@@ -401,8 +403,6 @@ public class ChannelState extends Module implements ICallEventProvider, IDecoder
|
||||
{
|
||||
broadcast(SquelchState.SQUELCH);
|
||||
|
||||
getMutableMetadata().resetTemporalAttributes();
|
||||
|
||||
mState = State.TEARDOWN;
|
||||
|
||||
mMutableMetadata.receive(new AttributeChangeRequest<State>(Attribute.CHANNEL_STATE, mState));
|
||||
|
||||
@@ -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;
|
||||
@@ -24,32 +26,64 @@ import io.github.dsheirer.record.RecorderType;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,8 @@ import javax.sound.sampled.AudioFormat;
|
||||
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;
|
||||
@@ -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();
|
||||
|
||||
@@ -186,24 +189,24 @@ public class AudioPacketWaveRecorder extends Module implements Listener<Reusable
|
||||
*/
|
||||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -101,7 +101,14 @@ public class OverflowableTransferQueue<E>
|
||||
*/
|
||||
public E poll()
|
||||
{
|
||||
return mQueue.poll();
|
||||
E element = mQueue.poll();
|
||||
|
||||
if(element != null)
|
||||
{
|
||||
mCounter.decrementAndGet();
|
||||
}
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user