Bug 991504 - Detect silent chunk when resampling, and properly handle them. r=roc

This commit is contained in:
Paul Adenot 2014-04-07 18:22:11 +02:00
parent aba9070c3e
commit 847f810b87
3 changed files with 23 additions and 1 deletions

View File

@ -24,6 +24,8 @@ enum AudioSampleFormat
AUDIO_FORMAT_S16,
// Signed 32-bit float samples
AUDIO_FORMAT_FLOAT32,
// Silence: format will be chosen later
AUDIO_FORMAT_SILENCE,
// The format used for output by AudioStream.
#ifdef MOZ_SAMPLE_TYPE_S16
AUDIO_OUTPUT_FORMAT = AUDIO_FORMAT_S16

View File

@ -52,6 +52,9 @@ InterleaveAndConvertBuffer(const void** aSourceChannels,
aChannels,
aOutput);
break;
case AUDIO_FORMAT_SILENCE:
// nothing to do here.
break;
}
}
@ -121,7 +124,18 @@ void AudioSegment::ResampleChunks(SpeexResamplerState* aResampler)
speex_resampler_get_rate(aResampler, &inRate, &outRate);
switch (mChunks[0].mBufferFormat) {
AudioSampleFormat format = AUDIO_FORMAT_SILENCE;
for (ChunkIterator ci(*this); !ci.IsEnded(); ci.Next()) {
if (ci->mBufferFormat != AUDIO_FORMAT_SILENCE) {
format = ci->mBufferFormat;
}
}
switch (format) {
// If the format is silence at this point, all the chunks are silent. The
// actual function we use does not matter, it's just a matter of changing
// the chunks duration.
case AUDIO_FORMAT_SILENCE:
case AUDIO_FORMAT_FLOAT32:
Resample<float>(aResampler, inRate, outRate);
break;

View File

@ -110,6 +110,7 @@ struct AudioChunk {
mChannelData.Clear();
mDuration = aDuration;
mVolume = 1.0f;
mBufferFormat = AUDIO_FORMAT_SILENCE;
}
int ChannelCount() const { return mChannelData.Length(); }
@ -144,6 +145,11 @@ public:
nsAutoTArray<nsTArray<T>, GUESS_AUDIO_CHANNELS> output;
nsAutoTArray<const T*, GUESS_AUDIO_CHANNELS> bufferPtrs;
AudioChunk& c = *ci;
// If this chunk is null, don't bother resampling, just alter its duration
if (c.IsNull()) {
c.mDuration *= aOutRate / aInRate;
mDuration += c.mDuration;
}
uint32_t channels = c.mChannelData.Length();
output.SetLength(channels);
bufferPtrs.SetLength(channels);