Bug 1277198. Part 1 - add AudioClock::GetInputRate/GetOutputRate. r=kinetik.
MozReview-Commit-ID: HsaiSq83MtD
--- a/dom/media/AudioStream.cpp
+++ b/dom/media/AudioStream.cpp
@@ -157,17 +157,17 @@ AudioStream::SizeOfIncludingThis(MallocS
return amount;
}
nsresult AudioStream::EnsureTimeStretcherInitializedUnlocked()
{
mMonitor.AssertCurrentThreadOwns();
if (!mTimeStretcher) {
mTimeStretcher = soundtouch::createSoundTouchObj();
- mTimeStretcher->setSampleRate(mInRate);
+ mTimeStretcher->setSampleRate(mAudioClock.GetInputRate());
mTimeStretcher->setChannels(mOutChannels);
mTimeStretcher->setPitch(1.0);
}
return NS_OK;
}
nsresult AudioStream::SetPlaybackRate(double aPlaybackRate)
{
@@ -183,17 +183,16 @@ nsresult AudioStream::SetPlaybackRate(do
return NS_OK;
}
if (EnsureTimeStretcherInitializedUnlocked() != NS_OK) {
return NS_ERROR_FAILURE;
}
mAudioClock.SetPlaybackRate(aPlaybackRate);
- mOutRate = mInRate / aPlaybackRate;
if (mAudioClock.GetPreservesPitch()) {
mTimeStretcher->setTempo(aPlaybackRate);
mTimeStretcher->setRate(1.0f);
} else {
mTimeStretcher->setTempo(1.0f);
mTimeStretcher->setRate(aPlaybackRate);
}
@@ -498,18 +497,18 @@ AudioStream::GetPositionInFramesUnlocked
return -1;
}
return std::min<uint64_t>(position, INT64_MAX);
}
bool
AudioStream::IsValidAudioFormat(Chunk* aChunk)
{
- if (aChunk->Rate() != mInRate) {
- LOGW("mismatched sample %u, mInRate=%u", aChunk->Rate(), mInRate);
+ if (aChunk->Rate() != mAudioClock.GetInputRate()) {
+ LOGW("mismatched sample %u, mInRate=%u", aChunk->Rate(), mAudioClock.GetInputRate());
return false;
}
if (aChunk->Channels() > 8) {
return false;
}
return true;
@@ -554,18 +553,18 @@ AudioStream::GetTimeStretched(AudioBuffe
{
mMonitor.AssertCurrentThreadOwns();
// We need to call the non-locking version, because we already have the lock.
if (EnsureTimeStretcherInitializedUnlocked() != NS_OK) {
return;
}
- double playbackRate = static_cast<double>(mInRate) / mOutRate;
- uint32_t toPopFrames = ceil(aWriter.Available() * playbackRate);
+ uint32_t toPopFrames =
+ ceil(aWriter.Available() * mAudioClock.GetPlaybackRate());
while (mTimeStretcher->numSamples() < aWriter.Available()) {
UniquePtr<Chunk> c = mDataSource.PopFrames(toPopFrames);
if (c->Frames() == 0) {
break;
}
MOZ_ASSERT(c->Frames() <= toPopFrames);
if (IsValidAudioFormat(c.get())) {
@@ -600,17 +599,17 @@ AudioStream::DataCallback(void* aBuffer,
NS_WARNING("data callback fires before cubeb_stream_start() is called");
mAudioClock.UpdateFrameHistory(0, aFrames);
return writer.WriteZeros(aFrames);
}
// NOTE: wasapi (others?) can call us back *after* stop()/Shutdown() (mState == SHUTDOWN)
// Bug 996162
- if (mInRate == mOutRate) {
+ if (mAudioClock.GetInputRate() == mAudioClock.GetOutputRate()) {
GetUnprocessed(writer);
} else {
GetTimeStretched(writer);
}
// Always send audible frames first, and silent frames later.
// Otherwise it will break the assumption of FrameHistory.
if (!mDataSource.Ended()) {
--- a/dom/media/AudioStream.h
+++ b/dom/media/AudioStream.h
@@ -67,16 +67,19 @@ public:
double GetPlaybackRate() const;
// Set if we are preserving the pitch.
// Called on the audio thread.
void SetPreservesPitch(bool aPreservesPitch);
// Get the current pitch preservation state.
// Called on the audio thread.
bool GetPreservesPitch() const;
+ uint32_t GetInputRate() const { return mInRate; }
+ uint32_t GetOutputRate() const { return mOutRate; }
+
private:
// Output rate in Hz (characteristic of the playback rate)
uint32_t mOutRate;
// Input rate in Hz (characteristic of the media being played)
uint32_t mInRate;
// True if the we are timestretching, false if we are resampling.
bool mPreservesPitch;
// The history of frames sent to the audio engine in each DataCallback.