mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-12 16:47:31 -05:00
#30 - changes audio broadcaster to send full/complete MP3 frames instead of partial frames in order to reduce remote server disconnnects due to MP3 frame sync loss on remote server.
This commit is contained in:
@@ -265,7 +265,7 @@ public abstract class AudioBroadcaster implements IAudioPacketListener
|
||||
{
|
||||
if(mBroadcastState != state)
|
||||
{
|
||||
mLog.info("[" + getStreamName() + "] changing state to: " + state);
|
||||
mLog.info("[" + getStreamName() + "] state: " + state);
|
||||
mBroadcastState = state;
|
||||
|
||||
broadcast(new BroadcastEvent(this, BroadcastEvent.Event.BROADCASTER_STATE_CHANGE));
|
||||
@@ -332,8 +332,9 @@ public abstract class AudioBroadcaster implements IAudioPacketListener
|
||||
{
|
||||
private AtomicBoolean mProcessing = new AtomicBoolean();
|
||||
private ByteArrayInputStream mInputStream;
|
||||
private int mAverageBytesPerInterval;
|
||||
private long mFinalSilencePadding = 0;
|
||||
private int mBytesStreamedActual = 0;
|
||||
private int mBytesStreamedRequired = 0;
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
@@ -353,13 +354,20 @@ public abstract class AudioBroadcaster implements IAudioPacketListener
|
||||
|
||||
if(mInputStream != null)
|
||||
{
|
||||
int length = Math.min(mAverageBytesPerInterval, mInputStream.available());
|
||||
//We need to stream at 13.888 fps (144 byte frame) to achieve 2000 Bps or 16 kbps
|
||||
mBytesStreamedRequired += 2000; //2000 bytes per second for 16 kbps data rate
|
||||
int bytesToStream = mBytesStreamedRequired - mBytesStreamedActual;
|
||||
|
||||
//Trim length to whole-frame intervals (144 byte frame)
|
||||
bytesToStream -= (bytesToStream % 144);
|
||||
|
||||
int length = Math.min(bytesToStream, mInputStream.available());
|
||||
|
||||
byte[] audio = new byte[length];
|
||||
|
||||
try
|
||||
{
|
||||
mInputStream.read(audio);
|
||||
mBytesStreamedActual += mInputStream.read(audio);
|
||||
|
||||
broadcastAudio(audio);
|
||||
}
|
||||
@@ -382,6 +390,9 @@ public abstract class AudioBroadcaster implements IAudioPacketListener
|
||||
*/
|
||||
private void nextRecording()
|
||||
{
|
||||
mBytesStreamedActual = 0;
|
||||
mBytesStreamedRequired = 0;
|
||||
|
||||
boolean metadataUpdateRequired = false;
|
||||
|
||||
if(mInputStream != null)
|
||||
@@ -408,15 +419,13 @@ public abstract class AudioBroadcaster implements IAudioPacketListener
|
||||
{
|
||||
mInputStream = new ByteArrayInputStream(audio);
|
||||
|
||||
double intervals = (double)recording.getRecordingLength() / (double)PROCESSOR_RUN_INTERVAL_MS;
|
||||
mFinalSilencePadding = PROCESSOR_RUN_INTERVAL_MS -
|
||||
(recording.getRecordingLength() % PROCESSOR_RUN_INTERVAL_MS);
|
||||
|
||||
mAverageBytesPerInterval = (int)((double)mInputStream.available() / intervals);
|
||||
|
||||
int wholeIntervals = (int)Math.floor(intervals) + 1;
|
||||
|
||||
//Silence padding to transmit at the end to keep stream length at multiples of run interval
|
||||
mFinalSilencePadding = (wholeIntervals * PROCESSOR_RUN_INTERVAL_MS) -
|
||||
recording.getRecordingLength();
|
||||
while(mFinalSilencePadding >= PROCESSOR_RUN_INTERVAL_MS)
|
||||
{
|
||||
mFinalSilencePadding -= PROCESSOR_RUN_INTERVAL_MS;
|
||||
}
|
||||
|
||||
if(connected())
|
||||
{
|
||||
|
||||
@@ -248,7 +248,6 @@ public class ShoutcastV1AudioBroadcaster extends ShoutcastAudioBroadcaster
|
||||
@Override
|
||||
public void messageReceived(IoSession session, Object object) throws Exception
|
||||
{
|
||||
mLog.debug("Message Received:" + object.toString());
|
||||
if(object instanceof String)
|
||||
{
|
||||
String message = (String)object;
|
||||
|
||||
@@ -57,18 +57,27 @@ public class MP3SilenceGenerator implements ISilenceGenerator
|
||||
{
|
||||
mLog.debug("Starting ...");
|
||||
|
||||
MP3SilenceGenerator generator = new MP3SilenceGenerator();
|
||||
// MP3SilenceGenerator generator = new MP3SilenceGenerator();
|
||||
//
|
||||
// int sampleCount = 0;
|
||||
//
|
||||
// int block = 1;
|
||||
//
|
||||
// for(long x = 0; x < 5000; x ++)
|
||||
// {
|
||||
// byte[] silence = generator.generate(block);
|
||||
//
|
||||
// sampleCount += block;
|
||||
//
|
||||
// if(silence.length > 0)
|
||||
// {
|
||||
// mLog.debug("Silence:" + x + " Count:" + sampleCount + " Length:" + silence.length);
|
||||
// }
|
||||
// }
|
||||
|
||||
int sampleCount = 0;
|
||||
|
||||
int block = 1;
|
||||
|
||||
for(long x = 0; x < 500; x ++)
|
||||
for(int x = 1; x <= 288; x++)
|
||||
{
|
||||
byte[] silence = generator.generate(block);
|
||||
|
||||
sampleCount += block;
|
||||
mLog.debug("Silence:" + x + " Count:" + sampleCount + " Length:" + silence.length);
|
||||
mLog.debug(x + ": " + (x / 144));
|
||||
}
|
||||
|
||||
mLog.debug("Finished");
|
||||
|
||||
Reference in New Issue
Block a user