From 0cf26da94e21799cb6ef5c4ee190ab3826dd5339 Mon Sep 17 00:00:00 2001 From: Denny Date: Sat, 7 Jan 2017 10:56:57 -0500 Subject: [PATCH] #65 resolves issue where on audio recorder startup an IO exception is thrown. Traps the exception and shuts down the recorder. --- src/record/RecorderManager.java | 290 ++++++++++++++++---------------- 1 file changed, 142 insertions(+), 148 deletions(-) diff --git a/src/record/RecorderManager.java b/src/record/RecorderManager.java index cd7c526f..e71689b7 100644 --- a/src/record/RecorderManager.java +++ b/src/record/RecorderManager.java @@ -1,181 +1,175 @@ /******************************************************************************* * SDR Trunk - * Copyright (C) 2014-2016 Dennis Sheirer - * + * Copyright (C) 2014-2017 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 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 ******************************************************************************/ package record; -import java.io.File; -import java.util.HashMap; -import java.util.Map; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import properties.SystemProperties; -import record.wave.ComplexBufferWaveRecorder; -import record.wave.RealBufferWaveRecorder; -import sample.Listener; import audio.AudioPacket; import audio.metadata.Metadata; import audio.metadata.MetadataType; import controller.ThreadPoolManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import properties.SystemProperties; +import record.wave.ComplexBufferWaveRecorder; +import record.wave.RealBufferWaveRecorder; +import sample.Listener; + +import java.io.File; +import java.util.HashMap; +import java.util.Map; public class RecorderManager implements Listener { - private static final Logger mLog = LoggerFactory.getLogger( RecorderManager.class ); + private static final Logger mLog = LoggerFactory.getLogger(RecorderManager.class); - public static final int AUDIO_SAMPLE_RATE = 8000; - - private Map mRecorders = new HashMap<>(); - - private ThreadPoolManager mThreadPoolManager; - - private boolean mCanStartNewRecorders = true; + public static final int AUDIO_SAMPLE_RATE = 8000; - public RecorderManager( ThreadPoolManager threadPoolManager ) - { - mThreadPoolManager = threadPoolManager; - } - - public void dispose() - { - mThreadPoolManager = null; - } - - @Override - public void receive( AudioPacket audioPacket ) - { - if( audioPacket.hasAudioMetadata() && - audioPacket.getAudioMetadata().isRecordable() ) - { - String identifier = audioPacket.getAudioMetadata().getIdentifier(); + private Map mRecorders = new HashMap<>(); - if( mRecorders.containsKey( identifier ) ) - { - RealBufferWaveRecorder recorder = mRecorders.get( identifier ); + private ThreadPoolManager mThreadPoolManager; - if( audioPacket.getType() == AudioPacket.Type.AUDIO ) - { - recorder.receive( audioPacket.getAudioBuffer() ); - } - else if( audioPacket.getType() == AudioPacket.Type.END ) - { - RealBufferWaveRecorder finished = mRecorders.remove( identifier ); - finished.stop(); - } - } - else if( audioPacket.getType() == AudioPacket.Type.AUDIO ) - { - if( mCanStartNewRecorders ) - { - String filePrefix = getFilePrefix( audioPacket ); + private boolean mCanStartNewRecorders = true; - try - { - RealBufferWaveRecorder recorder = - new RealBufferWaveRecorder( AUDIO_SAMPLE_RATE, filePrefix ); - - recorder.start( mThreadPoolManager.getScheduledExecutorService() ); + /** + * Manages starting and stopping all system recorders and distributes channel audio to each of the recorders. + */ + public RecorderManager(ThreadPoolManager threadPoolManager) + { + mThreadPoolManager = threadPoolManager; + } - recorder.receive( audioPacket.getAudioBuffer() ); - mRecorders.put( identifier, recorder ); - } - catch( Exception ioe ) - { - mCanStartNewRecorders = false; - - mLog.error( "Error attempting to start new audio wave recorder." - + " All (future) audio recording is disabled", ioe ); - } - } - } - } - } - - /** - * Constructs a file name and path for an audio recording - */ - private String getFilePrefix( AudioPacket packet ) - { - StringBuilder sb = new StringBuilder(); - - sb.append( SystemProperties.getInstance() - .getApplicationFolder( "recordings" ) ); - - sb.append( File.separator ); - - Metadata systemMetadata = packet.getAudioMetadata() - .getMetadata( MetadataType.SYSTEM ); + public void dispose() + { + mThreadPoolManager = null; + } - sb.append( systemMetadata != null ? - systemMetadata.getValue() : "UNKNOWN_SYSTEM" ); - - Metadata toMetadata = packet.getAudioMetadata() - .getMetadata( MetadataType.TO ); - - if( toMetadata != null ) - { - sb.append( "_TO_" ); - sb.append( toMetadata.getValue() ); - - Metadata fromMetadata = packet.getAudioMetadata() - .getMetadata( MetadataType.FROM ); - - if( fromMetadata != null ) - { - sb.append( "_FROM_" ); - sb.append( fromMetadata.getValue() ); - } - } - else - { - Metadata siteMetadata = packet.getAudioMetadata() - .getMetadata( MetadataType.SITE_ID ); - - if( siteMetadata != null ) - { - sb.append( "_" ); - sb.append( siteMetadata.getValue() ); - } - - Metadata channelMetadata = packet.getAudioMetadata() - .getMetadata( MetadataType.CHANNEL_NAME ); - - if( channelMetadata != null ) - { - sb.append( "_" ); - sb.append( channelMetadata.getValue() ); - } - } + @Override + public void receive(AudioPacket audioPacket) + { + if(audioPacket.hasAudioMetadata() && + audioPacket.getAudioMetadata().isRecordable()) + { + String identifier = audioPacket.getAudioMetadata().getIdentifier(); - return sb.toString(); - } + if(mRecorders.containsKey(identifier)) + { + RealBufferWaveRecorder recorder = mRecorders.get(identifier); - /** - * Constructs a baseband recorder for use in a processing chain. - */ - public ComplexBufferWaveRecorder getBasebandRecorder( String channelName ) - { - StringBuilder sb = new StringBuilder(); - sb.append( SystemProperties.getInstance() - .getApplicationFolder( "recordings" ) ); - sb.append( File.separator ); - sb.append( channelName ); - sb.append( "_baseband" ); + if(audioPacket.getType() == AudioPacket.Type.AUDIO) + { + recorder.receive(audioPacket.getAudioBuffer()); + } + else if(audioPacket.getType() == AudioPacket.Type.END) + { + RealBufferWaveRecorder finished = mRecorders.remove(identifier); + finished.stop(); + } + } + else if(audioPacket.getType() == AudioPacket.Type.AUDIO) + { + if(mCanStartNewRecorders) + { + String filePrefix = getFilePrefix(audioPacket); - return new ComplexBufferWaveRecorder( AUDIO_SAMPLE_RATE, sb.toString() ); - } + RealBufferWaveRecorder recorder = null; + + try + { + recorder = new RealBufferWaveRecorder(AUDIO_SAMPLE_RATE, filePrefix); + + recorder.start(mThreadPoolManager.getScheduledExecutorService()); + + recorder.receive(audioPacket.getAudioBuffer()); + mRecorders.put(identifier, recorder); + } + catch(Exception ioe) + { + mCanStartNewRecorders = false; + + mLog.error("Error attempting to start new audio wave recorder. All (future) audio recording " + + "is disabled", ioe); + + if(recorder != null) + { + recorder.stop(); + } + } + } + } + } + } + + /** + * Constructs a file name and path for an audio recording + */ + private String getFilePrefix(AudioPacket packet) + { + StringBuilder sb = new StringBuilder(); + + sb.append(SystemProperties.getInstance().getApplicationFolder("recordings")); + + sb.append(File.separator); + + Metadata systemMetadata = packet.getAudioMetadata().getMetadata(MetadataType.SYSTEM); + + sb.append(systemMetadata != null ? systemMetadata.getValue() : "UNKNOWN_SYSTEM"); + + Metadata toMetadata = packet.getAudioMetadata().getMetadata(MetadataType.TO); + + if(toMetadata != null) + { + sb.append("_TO_").append(toMetadata.getValue()); + + Metadata fromMetadata = packet.getAudioMetadata().getMetadata(MetadataType.FROM); + + if(fromMetadata != null) + { + sb.append("_FROM_").append(fromMetadata.getValue()); + } + } + else + { + Metadata siteMetadata = packet.getAudioMetadata().getMetadata(MetadataType.SITE_ID); + + if(siteMetadata != null) + { + sb.append("_").append(siteMetadata.getValue()); + } + + Metadata channelMetadata = packet.getAudioMetadata().getMetadata(MetadataType.CHANNEL_NAME); + + if(channelMetadata != null) + { + sb.append("_").append(channelMetadata.getValue()); + } + } + + return sb.toString(); + } + + /** + * Constructs a baseband recorder for use in a processing chain. + */ + public ComplexBufferWaveRecorder getBasebandRecorder(String channelName) + { + StringBuilder sb = new StringBuilder(); + sb.append(SystemProperties.getInstance().getApplicationFolder("recordings")); + sb.append(File.separator).append(channelName).append("_baseband"); + + return new ComplexBufferWaveRecorder(AUDIO_SAMPLE_RATE, sb.toString()); + } }