#30 WIP - broadcastify multi-channel streaming is functional.

This commit is contained in:
Denny
2016-11-27 11:58:34 -05:00
parent ecfac83eb4
commit b71415b82a
37 changed files with 2049 additions and 715 deletions

View File

@@ -55,6 +55,8 @@ public abstract class AudioRecorder extends Module implements Listener<AudioPack
private BufferProcessor mBufferProcessor;
private ScheduledFuture<?> mProcessorHandle;
private long mSampleCount;
/**
* Abstract audio recorder that implements audio packet queueing and threaded audio conversion/writing to a file
*
@@ -95,6 +97,15 @@ public abstract class AudioRecorder extends Module implements Listener<AudioPack
return mTimeRecordingStart;
}
/**
* Recording length in milliseconds
*/
public long getRecordingLength()
{
//Assumes audio sample rate of 8000 samples/second or 8 samples/milli-second
return mSampleCount / 8;
}
/**
* Implements the IAudioPacketListener interface and simply redirects to the Listener<AudioPacket> interface.
* This is necessary since you can't have multiple methods with the same erasure (ie Listener<xxx>) in the
@@ -137,7 +148,7 @@ public abstract class AudioRecorder extends Module implements Listener<AudioPack
*/
protected OutputStream getOutputStream()
{
return null;
return mFileOutputStream;
}
/**
@@ -169,6 +180,7 @@ public abstract class AudioRecorder extends Module implements Listener<AudioPack
{
try
{
mFileOutputStream.flush();
mFileOutputStream.close();
}
catch (IOException e)
@@ -204,8 +216,6 @@ public abstract class AudioRecorder extends Module implements Listener<AudioPack
{
mFileOutputStream = new FileOutputStream(mPath.toFile());
mLog.info("Created Audio Recording [" + getPath().toString() + "]");
/* Schedule the handler to run every half second */
mProcessorHandle = executor.scheduleAtFixedRate(mBufferProcessor, 0, 500, TimeUnit.MILLISECONDS);
}
@@ -230,6 +240,14 @@ public abstract class AudioRecorder extends Module implements Listener<AudioPack
try
{
record(mPacketsToProcess);
for(AudioPacket packet: mPacketsToProcess)
{
if(packet.getType() == AudioPacket.Type.AUDIO)
{
mSampleCount += packet.getAudioBuffer().getSamples().length;
}
}
}
catch(IOException ioe)
{

View File

@@ -95,26 +95,50 @@ public class MP3Recorder extends AudioRecorder
public static void main(String[] args)
{
Path inputPath = Paths.get("/home/denny/Music/PCM.wav");
Path outputPath = Paths.get("/home/denny/Music/denny_test/PCM.mp3");
mLog.debug("Starting ...");
// Path inputPath = Paths.get("/home/denny/Music/PCM.wav");
// Path outputPath = Paths.get("/home/denny/Music/denny_test/PCM.mp3");
//
// mLog.debug("Reading: " + inputPath.toString());
// mLog.debug("Writing: " + outputPath.toString());
//
// final MP3Recorder recorder = new MP3Recorder(outputPath);
// recorder.start(Executors.newSingleThreadScheduledExecutor());
//
// try (AudioPacketMonoWaveReader reader = new AudioPacketMonoWaveReader(inputPath, true))
// {
// reader.setListener(recorder);
// reader.read();
// recorder.stop();
// }
// catch (IOException e)
// {
// mLog.error("Error", e);
// }
//
Path outputPath = Paths.get("/home/denny/Music/Silence_test_10_seconds.mp3");
mLog.debug("Reading: " + inputPath.toString());
mLog.debug("Writing: " + outputPath.toString());
final MP3Recorder recorder = new MP3Recorder(outputPath);
recorder.start(Executors.newSingleThreadScheduledExecutor());
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
recorder.start(executor);
try (AudioPacketMonoWaveReader reader = new AudioPacketMonoWaveReader(inputPath, true))
long duration = 1165;
int length = (int)(duration * 8); //8000 Hz sample rate
float[] silence = new float[length];
AudioPacket silencePacket = new AudioPacket(silence, null);
for(int x = 0; x < 10; x++)
{
reader.setListener(recorder);
reader.read();
recorder.stop();
}
catch (IOException e)
{
mLog.error("Error", e);
recorder.receive(silencePacket);
}
recorder.stop();
executor.shutdown();
mLog.debug("Finished");
}
}