Loading services/audioflinger/AudioStreamOut.cpp +75 −10 Original line number Diff line number Diff line Loading @@ -27,11 +27,16 @@ namespace android { // ---------------------------------------------------------------------------- AudioStreamOut::AudioStreamOut(AudioHwDevice *dev, audio_output_flags_t flags) : audioHwDev(dev) , stream(NULL) , flags(flags) , mFramesWritten(0) , mFramesWrittenAtStandby(0) , mRenderPosition(0) , mRateMultiplier(1) , mHalFormatIsLinearPcm(false) , mHalFrameSize(0) { } Loading @@ -40,12 +45,41 @@ audio_hw_device_t* AudioStreamOut::hwDev() const return audioHwDev->hwDevice(); } status_t AudioStreamOut::getRenderPosition(uint32_t *frames) status_t AudioStreamOut::getRenderPosition(uint64_t *frames) { if (stream == NULL) { return NO_INIT; } return stream->get_render_position(stream, frames); uint32_t halPosition = 0; status_t status = stream->get_render_position(stream, &halPosition); if (status != NO_ERROR) { return status; } // Maintain a 64-bit render position using the 32-bit result from the HAL. // This delta calculation relies on the arithmetic overflow behavior // of integers. For example (100 - 0xFFFFFFF0) = 116. uint32_t truncatedPosition = (uint32_t)mRenderPosition; int32_t deltaHalPosition = (int32_t)(halPosition - truncatedPosition); if (deltaHalPosition > 0) { mRenderPosition += deltaHalPosition; } // Scale from HAL sample rate to application rate. *frames = mRenderPosition / mRateMultiplier; return status; } // return bottom 32-bits of the render position status_t AudioStreamOut::getRenderPosition(uint32_t *frames) { uint64_t position64 = 0; status_t status = getRenderPosition(&position64); if (status == NO_ERROR) { *frames = (uint32_t)position64; } return status; } status_t AudioStreamOut::getPresentationPosition(uint64_t *frames, struct timespec *timestamp) Loading @@ -53,7 +87,26 @@ status_t AudioStreamOut::getPresentationPosition(uint64_t *frames, struct timesp if (stream == NULL) { return NO_INIT; } return stream->get_presentation_position(stream, frames, timestamp); uint64_t halPosition = 0; status_t status = stream->get_presentation_position(stream, &halPosition, timestamp); if (status != NO_ERROR) { return status; } // Adjust for standby using HAL rate frames. // Only apply this correction if the HAL is getting PCM frames. if (mHalFormatIsLinearPcm) { uint64_t adjustedPosition = (halPosition <= mFramesWrittenAtStandby) ? 0 : (halPosition - mFramesWrittenAtStandby); // Scale from HAL sample rate to application rate. *frames = adjustedPosition / mRateMultiplier; } else { // For offloaded MP3 and other compressed formats. *frames = halPosition; } return status; } status_t AudioStreamOut::open( Loading Loading @@ -82,6 +135,9 @@ status_t AudioStreamOut::open( if (status == NO_ERROR) { stream = outStream; mHalFormatIsLinearPcm = audio_is_linear_pcm(config->format); ALOGI("AudioStreamOut::open(), mHalFormatIsLinearPcm = %d", (int)mHalFormatIsLinearPcm); mHalFrameSize = audio_stream_out_frame_size(stream); } return status; Loading @@ -89,13 +145,15 @@ status_t AudioStreamOut::open( size_t AudioStreamOut::getFrameSize() { ALOG_ASSERT(stream != NULL); return audio_stream_out_frame_size(stream); return mHalFrameSize; } int AudioStreamOut::flush() { ALOG_ASSERT(stream != NULL); mRenderPosition = 0; mFramesWritten = 0; mFramesWrittenAtStandby = 0; if (stream->flush != NULL) { return stream->flush(stream); } Loading @@ -105,13 +163,20 @@ int AudioStreamOut::flush() int AudioStreamOut::standby() { ALOG_ASSERT(stream != NULL); mRenderPosition = 0; mFramesWrittenAtStandby = mFramesWritten; ALOGI("AudioStreamOut::standby(), mFramesWrittenAtStandby = %llu", mFramesWrittenAtStandby); return stream->common.standby(&stream->common); } ssize_t AudioStreamOut::write(const void* buffer, size_t bytes) ssize_t AudioStreamOut::write(const void *buffer, size_t numBytes) { ALOG_ASSERT(stream != NULL); return stream->write(stream, buffer, bytes); ssize_t bytesWritten = stream->write(stream, buffer, numBytes); if (bytesWritten > 0 && mHalFrameSize > 0) { mFramesWritten += bytesWritten / mHalFrameSize; } return bytesWritten; } } // namespace android services/audioflinger/AudioStreamOut.h +12 −1 Original line number Diff line number Diff line Loading @@ -53,7 +53,10 @@ public: virtual ~AudioStreamOut() { } virtual status_t getRenderPosition(uint32_t *frames); // Get the bottom 32-bits of the 64-bit render position. status_t getRenderPosition(uint32_t *frames); virtual status_t getRenderPosition(uint64_t *frames); virtual status_t getPresentationPosition(uint64_t *frames, struct timespec *timestamp); Loading @@ -76,6 +79,14 @@ public: virtual status_t flush(); virtual status_t standby(); protected: uint64_t mFramesWritten; // reset by flush uint64_t mFramesWrittenAtStandby; uint64_t mRenderPosition; // reset by flush or standby int mRateMultiplier; bool mHalFormatIsLinearPcm; size_t mHalFrameSize; }; } // namespace android Loading services/audioflinger/SpdifStreamOut.cpp +0 −47 Original line number Diff line number Diff line Loading @@ -36,10 +36,7 @@ SpdifStreamOut::SpdifStreamOut(AudioHwDevice *dev, audio_output_flags_t flags, audio_format_t format) : AudioStreamOut(dev,flags) , mRateMultiplier(1) , mSpdifEncoder(this, format) , mRenderPositionHal(0) , mPreviousHalPosition32(0) { } Loading Loading @@ -97,62 +94,18 @@ status_t SpdifStreamOut::open( return status; } // Account for possibly higher sample rate. status_t SpdifStreamOut::getRenderPosition(uint32_t *frames) { uint32_t halPosition = 0; status_t status = AudioStreamOut::getRenderPosition(&halPosition); if (status != NO_ERROR) { return status; } // Accumulate a 64-bit position so that we wrap at the right place. if (mRateMultiplier != 1) { // Maintain a 64-bit render position. int32_t deltaHalPosition = (int32_t)(halPosition - mPreviousHalPosition32); mPreviousHalPosition32 = halPosition; mRenderPositionHal += deltaHalPosition; // Scale from device sample rate to application rate. uint64_t renderPositionApp = mRenderPositionHal / mRateMultiplier; ALOGV("SpdifStreamOut::getRenderPosition() " "renderPositionAppRate = %llu = %llu / %u\n", renderPositionApp, mRenderPositionHal, mRateMultiplier); *frames = (uint32_t)renderPositionApp; } else { *frames = halPosition; } return status; } int SpdifStreamOut::flush() { mSpdifEncoder.reset(); mRenderPositionHal = 0; mPreviousHalPosition32 = 0; return AudioStreamOut::flush(); } int SpdifStreamOut::standby() { mSpdifEncoder.reset(); mRenderPositionHal = 0; mPreviousHalPosition32 = 0; return AudioStreamOut::standby(); } // Account for possibly higher sample rate. // This is much easier when all the values are 64-bit. status_t SpdifStreamOut::getPresentationPosition(uint64_t *frames, struct timespec *timestamp) { uint64_t halFrames = 0; status_t status = AudioStreamOut::getPresentationPosition(&halFrames, timestamp); *frames = halFrames / mRateMultiplier; return status; } size_t SpdifStreamOut::getFrameSize() { return sizeof(int8_t); Loading services/audioflinger/SpdifStreamOut.h +0 −9 Original line number Diff line number Diff line Loading @@ -49,10 +49,6 @@ public: struct audio_config *config, const char *address); virtual status_t getRenderPosition(uint32_t *frames); virtual status_t getPresentationPosition(uint64_t *frames, struct timespec *timestamp); /** * Write audio buffer to driver. Returns number of bytes written, or a * negative status_t. If at least one frame was written successfully prior to the error, Loading Loading @@ -92,13 +88,8 @@ private: SpdifStreamOut * const mSpdifStreamOut; }; int mRateMultiplier; MySPDIFEncoder mSpdifEncoder; // Used to implement getRenderPosition() int64_t mRenderPositionHal; uint32_t mPreviousHalPosition32; ssize_t writeDataBurst(const void* data, size_t bytes); ssize_t writeInternal(const void* buffer, size_t bytes); Loading Loading
services/audioflinger/AudioStreamOut.cpp +75 −10 Original line number Diff line number Diff line Loading @@ -27,11 +27,16 @@ namespace android { // ---------------------------------------------------------------------------- AudioStreamOut::AudioStreamOut(AudioHwDevice *dev, audio_output_flags_t flags) : audioHwDev(dev) , stream(NULL) , flags(flags) , mFramesWritten(0) , mFramesWrittenAtStandby(0) , mRenderPosition(0) , mRateMultiplier(1) , mHalFormatIsLinearPcm(false) , mHalFrameSize(0) { } Loading @@ -40,12 +45,41 @@ audio_hw_device_t* AudioStreamOut::hwDev() const return audioHwDev->hwDevice(); } status_t AudioStreamOut::getRenderPosition(uint32_t *frames) status_t AudioStreamOut::getRenderPosition(uint64_t *frames) { if (stream == NULL) { return NO_INIT; } return stream->get_render_position(stream, frames); uint32_t halPosition = 0; status_t status = stream->get_render_position(stream, &halPosition); if (status != NO_ERROR) { return status; } // Maintain a 64-bit render position using the 32-bit result from the HAL. // This delta calculation relies on the arithmetic overflow behavior // of integers. For example (100 - 0xFFFFFFF0) = 116. uint32_t truncatedPosition = (uint32_t)mRenderPosition; int32_t deltaHalPosition = (int32_t)(halPosition - truncatedPosition); if (deltaHalPosition > 0) { mRenderPosition += deltaHalPosition; } // Scale from HAL sample rate to application rate. *frames = mRenderPosition / mRateMultiplier; return status; } // return bottom 32-bits of the render position status_t AudioStreamOut::getRenderPosition(uint32_t *frames) { uint64_t position64 = 0; status_t status = getRenderPosition(&position64); if (status == NO_ERROR) { *frames = (uint32_t)position64; } return status; } status_t AudioStreamOut::getPresentationPosition(uint64_t *frames, struct timespec *timestamp) Loading @@ -53,7 +87,26 @@ status_t AudioStreamOut::getPresentationPosition(uint64_t *frames, struct timesp if (stream == NULL) { return NO_INIT; } return stream->get_presentation_position(stream, frames, timestamp); uint64_t halPosition = 0; status_t status = stream->get_presentation_position(stream, &halPosition, timestamp); if (status != NO_ERROR) { return status; } // Adjust for standby using HAL rate frames. // Only apply this correction if the HAL is getting PCM frames. if (mHalFormatIsLinearPcm) { uint64_t adjustedPosition = (halPosition <= mFramesWrittenAtStandby) ? 0 : (halPosition - mFramesWrittenAtStandby); // Scale from HAL sample rate to application rate. *frames = adjustedPosition / mRateMultiplier; } else { // For offloaded MP3 and other compressed formats. *frames = halPosition; } return status; } status_t AudioStreamOut::open( Loading Loading @@ -82,6 +135,9 @@ status_t AudioStreamOut::open( if (status == NO_ERROR) { stream = outStream; mHalFormatIsLinearPcm = audio_is_linear_pcm(config->format); ALOGI("AudioStreamOut::open(), mHalFormatIsLinearPcm = %d", (int)mHalFormatIsLinearPcm); mHalFrameSize = audio_stream_out_frame_size(stream); } return status; Loading @@ -89,13 +145,15 @@ status_t AudioStreamOut::open( size_t AudioStreamOut::getFrameSize() { ALOG_ASSERT(stream != NULL); return audio_stream_out_frame_size(stream); return mHalFrameSize; } int AudioStreamOut::flush() { ALOG_ASSERT(stream != NULL); mRenderPosition = 0; mFramesWritten = 0; mFramesWrittenAtStandby = 0; if (stream->flush != NULL) { return stream->flush(stream); } Loading @@ -105,13 +163,20 @@ int AudioStreamOut::flush() int AudioStreamOut::standby() { ALOG_ASSERT(stream != NULL); mRenderPosition = 0; mFramesWrittenAtStandby = mFramesWritten; ALOGI("AudioStreamOut::standby(), mFramesWrittenAtStandby = %llu", mFramesWrittenAtStandby); return stream->common.standby(&stream->common); } ssize_t AudioStreamOut::write(const void* buffer, size_t bytes) ssize_t AudioStreamOut::write(const void *buffer, size_t numBytes) { ALOG_ASSERT(stream != NULL); return stream->write(stream, buffer, bytes); ssize_t bytesWritten = stream->write(stream, buffer, numBytes); if (bytesWritten > 0 && mHalFrameSize > 0) { mFramesWritten += bytesWritten / mHalFrameSize; } return bytesWritten; } } // namespace android
services/audioflinger/AudioStreamOut.h +12 −1 Original line number Diff line number Diff line Loading @@ -53,7 +53,10 @@ public: virtual ~AudioStreamOut() { } virtual status_t getRenderPosition(uint32_t *frames); // Get the bottom 32-bits of the 64-bit render position. status_t getRenderPosition(uint32_t *frames); virtual status_t getRenderPosition(uint64_t *frames); virtual status_t getPresentationPosition(uint64_t *frames, struct timespec *timestamp); Loading @@ -76,6 +79,14 @@ public: virtual status_t flush(); virtual status_t standby(); protected: uint64_t mFramesWritten; // reset by flush uint64_t mFramesWrittenAtStandby; uint64_t mRenderPosition; // reset by flush or standby int mRateMultiplier; bool mHalFormatIsLinearPcm; size_t mHalFrameSize; }; } // namespace android Loading
services/audioflinger/SpdifStreamOut.cpp +0 −47 Original line number Diff line number Diff line Loading @@ -36,10 +36,7 @@ SpdifStreamOut::SpdifStreamOut(AudioHwDevice *dev, audio_output_flags_t flags, audio_format_t format) : AudioStreamOut(dev,flags) , mRateMultiplier(1) , mSpdifEncoder(this, format) , mRenderPositionHal(0) , mPreviousHalPosition32(0) { } Loading Loading @@ -97,62 +94,18 @@ status_t SpdifStreamOut::open( return status; } // Account for possibly higher sample rate. status_t SpdifStreamOut::getRenderPosition(uint32_t *frames) { uint32_t halPosition = 0; status_t status = AudioStreamOut::getRenderPosition(&halPosition); if (status != NO_ERROR) { return status; } // Accumulate a 64-bit position so that we wrap at the right place. if (mRateMultiplier != 1) { // Maintain a 64-bit render position. int32_t deltaHalPosition = (int32_t)(halPosition - mPreviousHalPosition32); mPreviousHalPosition32 = halPosition; mRenderPositionHal += deltaHalPosition; // Scale from device sample rate to application rate. uint64_t renderPositionApp = mRenderPositionHal / mRateMultiplier; ALOGV("SpdifStreamOut::getRenderPosition() " "renderPositionAppRate = %llu = %llu / %u\n", renderPositionApp, mRenderPositionHal, mRateMultiplier); *frames = (uint32_t)renderPositionApp; } else { *frames = halPosition; } return status; } int SpdifStreamOut::flush() { mSpdifEncoder.reset(); mRenderPositionHal = 0; mPreviousHalPosition32 = 0; return AudioStreamOut::flush(); } int SpdifStreamOut::standby() { mSpdifEncoder.reset(); mRenderPositionHal = 0; mPreviousHalPosition32 = 0; return AudioStreamOut::standby(); } // Account for possibly higher sample rate. // This is much easier when all the values are 64-bit. status_t SpdifStreamOut::getPresentationPosition(uint64_t *frames, struct timespec *timestamp) { uint64_t halFrames = 0; status_t status = AudioStreamOut::getPresentationPosition(&halFrames, timestamp); *frames = halFrames / mRateMultiplier; return status; } size_t SpdifStreamOut::getFrameSize() { return sizeof(int8_t); Loading
services/audioflinger/SpdifStreamOut.h +0 −9 Original line number Diff line number Diff line Loading @@ -49,10 +49,6 @@ public: struct audio_config *config, const char *address); virtual status_t getRenderPosition(uint32_t *frames); virtual status_t getPresentationPosition(uint64_t *frames, struct timespec *timestamp); /** * Write audio buffer to driver. Returns number of bytes written, or a * negative status_t. If at least one frame was written successfully prior to the error, Loading Loading @@ -92,13 +88,8 @@ private: SpdifStreamOut * const mSpdifStreamOut; }; int mRateMultiplier; MySPDIFEncoder mSpdifEncoder; // Used to implement getRenderPosition() int64_t mRenderPositionHal; uint32_t mPreviousHalPosition32; ssize_t writeDataBurst(const void* data, size_t bytes); ssize_t writeInternal(const void* buffer, size_t bytes); Loading