From 1c6833afd6cfdbc6c696ed0719ceedc37ec0b534 Mon Sep 17 00:00:00 2001 From: Glenn Kasten Date: Wed, 17 Oct 2012 12:16:50 -0700 Subject: Ignore SIGPIPE during write() to broken pipe This happens occasionally when taking a bugreport. Bug: 6447319 Change-Id: Ia6531a4a3658461f8fd3f7106e7996da7cc5933a --- media/mediaserver/main_mediaserver.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/media/mediaserver/main_mediaserver.cpp b/media/mediaserver/main_mediaserver.cpp index 6b1abb1..ddd5b84 100644 --- a/media/mediaserver/main_mediaserver.cpp +++ b/media/mediaserver/main_mediaserver.cpp @@ -33,6 +33,7 @@ using namespace android; int main(int argc, char** argv) { + signal(SIGPIPE, SIG_IGN); sp proc(ProcessState::self()); sp sm = defaultServiceManager(); ALOGI("ServiceManager: %p", sm.get()); -- cgit v1.1 From 0224bf170a3904576bba81593eaab113c5d3a4e7 Mon Sep 17 00:00:00 2001 From: Andreas Huber Date: Mon, 12 Nov 2012 13:08:44 -0800 Subject: Various improvements of wifi display code - manually prepend SPS/PPS if encoder doesn't support it - latency improvements - support for "our" method of optional RTP retransmission - improvements to the wfd commandline tool for testing - make it easier to turn on/off suspension of the video pipeline on idle - fixes an issue where an error during encryption would cause a SEGV - add HDCP descriptor if necessary Squashed commit of the following: commit 1115be0ebb3b885b4f1b7dba56761ca013d0ec4a Author: Andreas Huber Date: Fri Nov 9 11:32:23 2012 -0800 Better shutdown of wfd -l sessions. Change-Id: Id898a14ae21efd3b065b00a729830063d39195a7 commit 0e7d106dfe4eb6e2640b0b66c65deaba265f7ff0 Author: Andreas Huber Date: Thu Nov 8 16:38:55 2012 -0800 No more sending delay, create rtp packets upfront. Change-Id: I809a225f664fdb485c7d9a49a27886601a6a26b2 commit d399e8571b77353d59afb57508dfd2a82c1ef93a Author: Andreas Huber Date: Thu Nov 8 14:19:43 2012 -0800 Restore AudioSource buffer size, factor out TimeSeries, make suspending video optional. Change-Id: Ifdfe4d447b901e714abf52856b4641d1d55a5d41 commit f8b649f0b8f917d59f4b8a2e8e6d7db61a684a78 Author: Andreas Huber Date: Thu Nov 8 09:34:06 2012 -0800 Pull 480 frames at a time from AudioSource/AudioRecord Change-Id: I1e215abd329faec3da026631122c0f4c800c0ac4 commit 1bc13452eb35eebbba00f5da93fa86535be5db59 Author: Andreas Huber Date: Thu Nov 8 08:50:30 2012 -0800 fixed bitrate traffic simulation Change-Id: Ic5efb7cbb0b5d3b4917bc77b8ba73d447249e695 commit 016cdff18e74bdc631a5679e97192645ed095aa2 Author: Andreas Huber Date: Wed Nov 7 14:00:03 2012 -0800 resurrected "our" style of retransmission. Change-Id: I34d757aba67428437cb39b8293a9651750ad20d9 commit 384cf1a3c8fb4ec410bdf8fa5722c298e6028f3e Author: Andreas Huber Date: Tue Nov 6 09:38:55 2012 -0800 Changes to make wfd work on manta. Change-Id: I7a4e00cf16581fe2146edd1b359af195774090e4 commit 9628f24b22b35f28630d99dda3614babf51bc07e Author: Andreas Huber Date: Wed Nov 7 09:15:44 2012 -0800 Patch up rtp timestamps to more accurately measure network jitter. Change-Id: I9502a4615575f97f98a215a13131a89a6ae93c6d commit 7c891a1a24f08bbd50f55be13f7d05f43e807eb8 Author: Andreas Huber Date: Tue Nov 6 09:37:24 2012 -0800 Additions to the "wfd" tool to create a local wfd source. Change-Id: I99558653a70fdc703f9d13990b3ce1c4d3ae227a Change-Id: Ia94c63fc390f597014531073485f0cfc53b3418a --- .../wifi-display/ANetworkSession.cpp | 21 ++ media/libstagefright/wifi-display/Android.mk | 1 + media/libstagefright/wifi-display/TimeSeries.cpp | 67 ++++ media/libstagefright/wifi-display/TimeSeries.h | 46 +++ .../wifi-display/source/Converter.cpp | 46 ++- .../libstagefright/wifi-display/source/Converter.h | 2 + .../wifi-display/source/PlaybackSession.cpp | 68 +++- .../wifi-display/source/PlaybackSession.h | 2 +- .../wifi-display/source/RepeaterSource.cpp | 5 +- .../wifi-display/source/RepeaterSource.h | 2 + .../libstagefright/wifi-display/source/Sender.cpp | 415 ++++++++------------- media/libstagefright/wifi-display/source/Sender.h | 43 ++- .../wifi-display/source/TSPacketizer.cpp | 19 + .../wifi-display/source/WifiDisplaySource.cpp | 12 +- .../wifi-display/source/WifiDisplaySource.h | 2 + media/libstagefright/wifi-display/wfd.cpp | 184 ++++++++- 16 files changed, 633 insertions(+), 302 deletions(-) create mode 100644 media/libstagefright/wifi-display/TimeSeries.cpp create mode 100644 media/libstagefright/wifi-display/TimeSeries.h diff --git a/media/libstagefright/wifi-display/ANetworkSession.cpp b/media/libstagefright/wifi-display/ANetworkSession.cpp index 819cd62..62a6e7f 100644 --- a/media/libstagefright/wifi-display/ANetworkSession.cpp +++ b/media/libstagefright/wifi-display/ANetworkSession.cpp @@ -407,6 +407,24 @@ status_t ANetworkSession::Session::writeMore() { do { const sp &datagram = *mOutDatagrams.begin(); + uint8_t *data = datagram->data(); + if (data[0] == 0x80 && (data[1] & 0x7f) == 33) { + int64_t nowUs = ALooper::GetNowUs(); + + uint32_t prevRtpTime = U32_AT(&data[4]); + + // 90kHz time scale + uint32_t rtpTime = (nowUs * 9ll) / 100ll; + int32_t diffTime = (int32_t)rtpTime - (int32_t)prevRtpTime; + + ALOGV("correcting rtpTime by %.0f ms", diffTime / 90.0); + + data[4] = rtpTime >> 24; + data[5] = (rtpTime >> 16) & 0xff; + data[6] = (rtpTime >> 8) & 0xff; + data[7] = rtpTime & 0xff; + } + int n; do { n = send(mSocket, datagram->data(), datagram->size(), 0); @@ -424,6 +442,9 @@ status_t ANetworkSession::Session::writeMore() { } while (err == OK && !mOutDatagrams.empty()); if (err == -EAGAIN) { + if (!mOutDatagrams.empty()) { + ALOGI("%d datagrams remain queued.", mOutDatagrams.size()); + } err = OK; } diff --git a/media/libstagefright/wifi-display/Android.mk b/media/libstagefright/wifi-display/Android.mk index 611bfff..75098f1 100644 --- a/media/libstagefright/wifi-display/Android.mk +++ b/media/libstagefright/wifi-display/Android.mk @@ -17,6 +17,7 @@ LOCAL_SRC_FILES:= \ source/Sender.cpp \ source/TSPacketizer.cpp \ source/WifiDisplaySource.cpp \ + TimeSeries.cpp \ LOCAL_C_INCLUDES:= \ $(TOP)/frameworks/av/media/libstagefright \ diff --git a/media/libstagefright/wifi-display/TimeSeries.cpp b/media/libstagefright/wifi-display/TimeSeries.cpp new file mode 100644 index 0000000..d882d98 --- /dev/null +++ b/media/libstagefright/wifi-display/TimeSeries.cpp @@ -0,0 +1,67 @@ +/* + * Copyright 2012, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "TimeSeries.h" + +#include +#include + +namespace android { + +TimeSeries::TimeSeries() + : mCount(0), + mSum(0.0) { +} + +void TimeSeries::add(double val) { + if (mCount < kHistorySize) { + mValues[mCount++] = val; + mSum += val; + } else { + mSum -= mValues[0]; + memmove(&mValues[0], &mValues[1], (kHistorySize - 1) * sizeof(double)); + mValues[kHistorySize - 1] = val; + mSum += val; + } +} + +double TimeSeries::mean() const { + if (mCount < 1) { + return 0.0; + } + + return mSum / mCount; +} + +double TimeSeries::sdev() const { + if (mCount < 1) { + return 0.0; + } + + double m = mean(); + + double sum = 0.0; + for (size_t i = 0; i < mCount; ++i) { + double tmp = mValues[i] - m; + tmp *= tmp; + + sum += tmp; + } + + return sqrt(sum / mCount); +} + +} // namespace android diff --git a/media/libstagefright/wifi-display/TimeSeries.h b/media/libstagefright/wifi-display/TimeSeries.h new file mode 100644 index 0000000..c818d51 --- /dev/null +++ b/media/libstagefright/wifi-display/TimeSeries.h @@ -0,0 +1,46 @@ +/* + * Copyright 2012, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef TIME_SERIES_H_ + +#define TIME_SERIES_H_ + +#include + +namespace android { + +struct TimeSeries { + TimeSeries(); + + void add(double val); + + double mean() const; + double sdev() const; + +private: + enum { + kHistorySize = 20 + }; + double mValues[kHistorySize]; + + size_t mCount; + double mSum; +}; + +} // namespace android + +#endif // TIME_SERIES_H_ + diff --git a/media/libstagefright/wifi-display/source/Converter.cpp b/media/libstagefright/wifi-display/source/Converter.cpp index 01a394f..82c98b9 100644 --- a/media/libstagefright/wifi-display/source/Converter.cpp +++ b/media/libstagefright/wifi-display/source/Converter.cpp @@ -48,6 +48,7 @@ Converter::Converter( mInputFormat(format), mIsVideo(false), mIsPCMAudio(usePCMAudio), + mNeedToManuallyPrependSPSPPS(false), mDoMoreWorkPending(false) #if ENABLE_SILENCE_DETECTION ,mFirstSilentFrameUs(-1ll) @@ -94,6 +95,10 @@ sp Converter::getOutputFormat() const { return mOutputFormat; } +bool Converter::needToManuallyPrependSPSPPS() const { + return mNeedToManuallyPrependSPSPPS; +} + static int32_t getBitrate(const char *propName, int32_t defaultValue) { char val[PROPERTY_VALUE_MAX]; if (property_get(propName, val, NULL)) { @@ -157,16 +162,45 @@ status_t Converter::initEncoder() { mOutputFormat->setInt32("bitrate-mode", OMX_Video_ControlRateConstant); mOutputFormat->setInt32("frame-rate", 30); mOutputFormat->setInt32("i-frame-interval", 1); // Iframes every 1 secs - mOutputFormat->setInt32("prepend-sps-pps-to-idr-frames", 1); } ALOGV("output format is '%s'", mOutputFormat->debugString(0).c_str()); - status_t err = mEncoder->configure( - mOutputFormat, - NULL /* nativeWindow */, - NULL /* crypto */, - MediaCodec::CONFIGURE_FLAG_ENCODE); + mNeedToManuallyPrependSPSPPS = false; + + status_t err = NO_INIT; + + if (!isAudio) { + sp tmp = mOutputFormat->dup(); + tmp->setInt32("prepend-sps-pps-to-idr-frames", 1); + + err = mEncoder->configure( + tmp, + NULL /* nativeWindow */, + NULL /* crypto */, + MediaCodec::CONFIGURE_FLAG_ENCODE); + + if (err == OK) { + // Encoder supported prepending SPS/PPS, we don't need to emulate + // it. + mOutputFormat = tmp; + } else { + mNeedToManuallyPrependSPSPPS = true; + + ALOGI("We going to manually prepend SPS and PPS to IDR frames."); + } + } + + if (err != OK) { + // We'll get here for audio or if we failed to configure the encoder + // to automatically prepend SPS/PPS in the case of video. + + err = mEncoder->configure( + mOutputFormat, + NULL /* nativeWindow */, + NULL /* crypto */, + MediaCodec::CONFIGURE_FLAG_ENCODE); + } if (err != OK) { return err; diff --git a/media/libstagefright/wifi-display/source/Converter.h b/media/libstagefright/wifi-display/source/Converter.h index 2cdeda3..0665eea 100644 --- a/media/libstagefright/wifi-display/source/Converter.h +++ b/media/libstagefright/wifi-display/source/Converter.h @@ -44,6 +44,7 @@ struct Converter : public AHandler { size_t getInputBufferCount() const; sp getOutputFormat() const; + bool needToManuallyPrependSPSPPS() const; void feedAccessUnit(const sp &accessUnit); void signalEOS(); @@ -78,6 +79,7 @@ private: bool mIsVideo; bool mIsPCMAudio; sp mOutputFormat; + bool mNeedToManuallyPrependSPSPPS; sp mEncoder; sp mEncoderActivityNotify; diff --git a/media/libstagefright/wifi-display/source/PlaybackSession.cpp b/media/libstagefright/wifi-display/source/PlaybackSession.cpp index f1e7140..4e5eb52 100644 --- a/media/libstagefright/wifi-display/source/PlaybackSession.cpp +++ b/media/libstagefright/wifi-display/source/PlaybackSession.cpp @@ -26,6 +26,7 @@ #include "Sender.h" #include "TSPacketizer.h" #include "include/avc_utils.h" +#include "WifiDisplaySource.h" #include #include @@ -81,7 +82,10 @@ struct WifiDisplaySource::PlaybackSession::Track : public AHandler { bool hasOutputBuffer(int64_t *timeUs) const; void queueOutputBuffer(const sp &accessUnit); sp dequeueOutputBuffer(); + +#if SUSPEND_VIDEO_IF_IDLE bool isSuspended() const; +#endif size_t countQueuedOutputBuffers() const { return mQueuedOutputBuffers.size(); @@ -279,7 +283,6 @@ bool WifiDisplaySource::PlaybackSession::Track::hasOutputBuffer( void WifiDisplaySource::PlaybackSession::Track::queueOutputBuffer( const sp &accessUnit) { mQueuedOutputBuffers.push_back(accessUnit); - mLastOutputBufferQueuedTimeUs = ALooper::GetNowUs(); } @@ -292,6 +295,7 @@ sp WifiDisplaySource::PlaybackSession::Track::dequeueOutputBuffer() { return outputBuffer; } +#if SUSPEND_VIDEO_IF_IDLE bool WifiDisplaySource::PlaybackSession::Track::isSuspended() const { if (!mQueuedOutputBuffers.empty()) { return false; @@ -307,6 +311,7 @@ bool WifiDisplaySource::PlaybackSession::Track::isSuspended() const { // this track suspended for the time being. return (ALooper::GetNowUs() - mLastOutputBufferQueuedTimeUs) > 60000ll; } +#endif //////////////////////////////////////////////////////////////////////////////// @@ -443,8 +448,13 @@ void WifiDisplaySource::PlaybackSession::onMessageReceived( ssize_t packetizerTrackIndex = track->packetizerTrackIndex(); if (packetizerTrackIndex < 0) { - packetizerTrackIndex = - mPacketizer->addTrack(track->getFormat()); + sp trackFormat = track->getFormat()->dup(); + if (mHDCP != NULL && !track->isAudio()) { + // HDCP2.0 _and_ HDCP 2.1 specs say to set the version + // inside the HDCP descriptor to 0x20!!! + trackFormat->setInt32("hdcp-version", 0x20); + } + packetizerTrackIndex = mPacketizer->addTrack(trackFormat); CHECK_GE(packetizerTrackIndex, 0); @@ -642,8 +652,10 @@ status_t WifiDisplaySource::PlaybackSession::addSource( sp converter = new Converter(notify, codecLooper, format, usePCMAudio); - if (converter->initCheck() != OK) { - return converter->initCheck(); + err = converter->initCheck(); + if (err != OK) { + ALOGE("%s converter returned err %d", isVideo ? "video" : "audio", err); + return err; } looper()->registerHandler(converter); @@ -735,11 +747,19 @@ sp WifiDisplaySource::PlaybackSession::getSurfaceTexture() { } int32_t WifiDisplaySource::PlaybackSession::width() const { +#if USE_1080P + return 1920; +#else return 1280; +#endif } int32_t WifiDisplaySource::PlaybackSession::height() const { +#if USE_1080P + return 1080; +#else return 720; +#endif } void WifiDisplaySource::PlaybackSession::requestIDRFrame() { @@ -767,7 +787,7 @@ bool WifiDisplaySource::PlaybackSession::allTracksHavePacketizerIndex() { } status_t WifiDisplaySource::PlaybackSession::packetizeAccessUnit( - size_t trackIndex, const sp &accessUnit, + size_t trackIndex, sp accessUnit, sp *packets) { const sp &track = mTracks.valueFor(trackIndex); @@ -776,9 +796,20 @@ status_t WifiDisplaySource::PlaybackSession::packetizeAccessUnit( bool isHDCPEncrypted = false; uint64_t inputCTR; uint8_t HDCP_private_data[16]; + + bool manuallyPrependSPSPPS = + !track->isAudio() + && track->converter()->needToManuallyPrependSPSPPS() + && IsIDR(accessUnit); + if (mHDCP != NULL && !track->isAudio()) { isHDCPEncrypted = true; + if (manuallyPrependSPSPPS) { + accessUnit = mPacketizer->prependCSD( + track->packetizerTrackIndex(), accessUnit); + } + status_t err = mHDCP->encrypt( accessUnit->data(), accessUnit->size(), trackIndex /* streamCTR */, @@ -858,6 +889,8 @@ status_t WifiDisplaySource::PlaybackSession::packetizeAccessUnit( #endif flags |= TSPacketizer::IS_ENCRYPTED; + } else if (manuallyPrependSPSPPS) { + flags |= TSPacketizer::PREPEND_SPS_PPS_TO_IDR_FRAMES; } int64_t timeUs = ALooper::GetNowUs(); @@ -930,12 +963,21 @@ bool WifiDisplaySource::PlaybackSession::drainAccessUnit() { minTrackIndex = mTracks.keyAt(i); minTimeUs = timeUs; } - } else if (!track->isSuspended()) { + } +#if SUSPEND_VIDEO_IF_IDLE + else if (!track->isSuspended()) { // We still consider this track "live", so it should keep // delivering output data whose time stamps we'll have to // consider for proper interleaving. return false; } +#else + else { + // We need access units available on all tracks to be able to + // dequeue the earliest one. + return false; + } +#endif } if (minTrackIndex < 0) { @@ -950,6 +992,7 @@ bool WifiDisplaySource::PlaybackSession::drainAccessUnit() { if (err != OK) { notifySessionDead(); + return false; } if ((ssize_t)minTrackIndex == mVideoTrackIndex) { @@ -957,6 +1000,17 @@ bool WifiDisplaySource::PlaybackSession::drainAccessUnit() { } mSender->queuePackets(minTimeUs, packets); +#if 0 + if (minTrackIndex == mVideoTrackIndex) { + int64_t nowUs = ALooper::GetNowUs(); + + // Latency from "data acquired" to "ready to send if we wanted to". + ALOGI("[%s] latencyUs = %lld ms", + minTrackIndex == mVideoTrackIndex ? "video" : "audio", + (nowUs - minTimeUs) / 1000ll); + } +#endif + return true; } diff --git a/media/libstagefright/wifi-display/source/PlaybackSession.h b/media/libstagefright/wifi-display/source/PlaybackSession.h index cc8b244..dabc1c4 100644 --- a/media/libstagefright/wifi-display/source/PlaybackSession.h +++ b/media/libstagefright/wifi-display/source/PlaybackSession.h @@ -127,7 +127,7 @@ private: bool allTracksHavePacketizerIndex(); status_t packetizeAccessUnit( - size_t trackIndex, const sp &accessUnit, + size_t trackIndex, sp accessUnit, sp *packets); status_t packetizeQueuedAccessUnits(); diff --git a/media/libstagefright/wifi-display/source/RepeaterSource.cpp b/media/libstagefright/wifi-display/source/RepeaterSource.cpp index 641e63f..72be927 100644 --- a/media/libstagefright/wifi-display/source/RepeaterSource.cpp +++ b/media/libstagefright/wifi-display/source/RepeaterSource.cpp @@ -125,11 +125,14 @@ status_t RepeaterSource::read( return mResult; } +#if SUSPEND_VIDEO_IF_IDLE int64_t nowUs = ALooper::GetNowUs(); if (nowUs - mLastBufferUpdateUs > 1000000ll) { mLastBufferUpdateUs = -1ll; stale = true; - } else { + } else +#endif + { mBuffer->add_ref(); *buffer = mBuffer; (*buffer)->meta_data()->setInt64(kKeyTime, bufferTimeUs); diff --git a/media/libstagefright/wifi-display/source/RepeaterSource.h b/media/libstagefright/wifi-display/source/RepeaterSource.h index e4aa2b6..a13973c 100644 --- a/media/libstagefright/wifi-display/source/RepeaterSource.h +++ b/media/libstagefright/wifi-display/source/RepeaterSource.h @@ -6,6 +6,8 @@ #include #include +#define SUSPEND_VIDEO_IF_IDLE 1 + namespace android { // This MediaSource delivers frames at a constant rate by repeating buffers diff --git a/media/libstagefright/wifi-display/source/Sender.cpp b/media/libstagefright/wifi-display/source/Sender.cpp index ea12424..9048691 100644 --- a/media/libstagefright/wifi-display/source/Sender.cpp +++ b/media/libstagefright/wifi-display/source/Sender.cpp @@ -21,6 +21,7 @@ #include "Sender.h" #include "ANetworkSession.h" +#include "TimeSeries.h" #include #include @@ -29,79 +30,8 @@ #include #include -#include - -#define DEBUG_JITTER 0 - namespace android { -//////////////////////////////////////////////////////////////////////////////// - -#if DEBUG_JITTER -struct TimeSeries { - TimeSeries(); - - void add(double val); - - double mean() const; - double sdev() const; - -private: - enum { - kHistorySize = 20 - }; - double mValues[kHistorySize]; - - size_t mCount; - double mSum; -}; - -TimeSeries::TimeSeries() - : mCount(0), - mSum(0.0) { -} - -void TimeSeries::add(double val) { - if (mCount < kHistorySize) { - mValues[mCount++] = val; - mSum += val; - } else { - mSum -= mValues[0]; - memmove(&mValues[0], &mValues[1], (kHistorySize - 1) * sizeof(double)); - mValues[kHistorySize - 1] = val; - mSum += val; - } -} - -double TimeSeries::mean() const { - if (mCount < 1) { - return 0.0; - } - - return mSum / mCount; -} - -double TimeSeries::sdev() const { - if (mCount < 1) { - return 0.0; - } - - double m = mean(); - - double sum = 0.0; - for (size_t i = 0; i < mCount; ++i) { - double tmp = mValues[i] - m; - tmp *= tmp; - - sum += tmp; - } - - return sqrt(sum / mCount); -} -#endif // DEBUG_JITTER - -//////////////////////////////////////////////////////////////////////////////// - static size_t kMaxRTPPacketSize = 1500; static size_t kMaxNumTSPacketsPerRTPPacket = (kMaxRTPPacketSize - 12) / 188; @@ -110,14 +40,13 @@ Sender::Sender( const sp ¬ify) : mNetSession(netSession), mNotify(notify), - mTSQueue(new ABuffer(12 + kMaxNumTSPacketsPerRTPPacket * 188)), mTransportMode(TRANSPORT_UDP), mRTPChannel(0), mRTCPChannel(0), mRTPPort(0), mRTPSessionID(0), mRTCPSessionID(0), -#if ENABLE_RETRANSMISSION +#if ENABLE_RETRANSMISSION && RETRANSMISSION_ACCORDING_TO_RFC_XXXX mRTPRetransmissionSessionID(0), mRTCPRetransmissionSessionID(0), #endif @@ -128,7 +57,7 @@ Sender::Sender( mFirstOutputBufferReadyTimeUs(-1ll), mFirstOutputBufferSentTimeUs(-1ll), mRTPSeqNo(0), -#if ENABLE_RETRANSMISSION +#if ENABLE_RETRANSMISSION && RETRANSMISSION_ACCORDING_TO_RFC_XXXX mRTPRetransmissionSeqNo(0), #endif mLastNTPTime(0), @@ -148,15 +77,13 @@ Sender::Sender( ,mLogFile(NULL) #endif { - mTSQueue->setRange(0, 12); - #if LOG_TRANSPORT_STREAM mLogFile = fopen("/system/etc/log.ts", "wb"); #endif } Sender::~Sender() { -#if ENABLE_RETRANSMISSION +#if ENABLE_RETRANSMISSION && RETRANSMISSION_ACCORDING_TO_RFC_XXXX if (mRTCPRetransmissionSessionID != 0) { mNetSession->destroySession(mRTCPRetransmissionSessionID); } @@ -217,7 +144,7 @@ status_t Sender::init( sp rtpNotify = new AMessage(kWhatRTPNotify, id()); sp rtcpNotify = new AMessage(kWhatRTCPNotify, id()); -#if ENABLE_RETRANSMISSION +#if ENABLE_RETRANSMISSION && RETRANSMISSION_ACCORDING_TO_RFC_XXXX sp rtpRetransmissionNotify = new AMessage(kWhatRTPRetransmissionNotify, id()); @@ -264,7 +191,7 @@ status_t Sender::init( } } -#if ENABLE_RETRANSMISSION +#if ENABLE_RETRANSMISSION && RETRANSMISSION_ACCORDING_TO_RFC_XXXX if (mTransportMode == TRANSPORT_UDP) { int32_t rtpRetransmissionSession; @@ -358,44 +285,67 @@ int32_t Sender::getRTPPort() const { } void Sender::queuePackets( - int64_t timeUs, const sp &packets) { - bool isVideo = false; + int64_t timeUs, const sp &tsPackets) { + const size_t numTSPackets = tsPackets->size() / 188; + + const size_t numRTPPackets = + (numTSPackets + kMaxNumTSPacketsPerRTPPacket - 1) + / kMaxNumTSPacketsPerRTPPacket; + + sp udpPackets = new ABuffer( + numRTPPackets * (12 + kMaxNumTSPacketsPerRTPPacket * 188)); + + udpPackets->meta()->setInt64("timeUs", timeUs); + + size_t dstOffset = 0; + for (size_t i = 0; i < numTSPackets; ++i) { + if ((i % kMaxNumTSPacketsPerRTPPacket) == 0) { + static const bool kMarkerBit = false; + + uint8_t *rtp = udpPackets->data() + dstOffset; + rtp[0] = 0x80; + rtp[1] = 33 | (kMarkerBit ? (1 << 7) : 0); // M-bit + rtp[2] = (mRTPSeqNo >> 8) & 0xff; + rtp[3] = mRTPSeqNo & 0xff; + rtp[4] = 0x00; // rtp time to be filled in later. + rtp[5] = 0x00; + rtp[6] = 0x00; + rtp[7] = 0x00; + rtp[8] = kSourceID >> 24; + rtp[9] = (kSourceID >> 16) & 0xff; + rtp[10] = (kSourceID >> 8) & 0xff; + rtp[11] = kSourceID & 0xff; + + ++mRTPSeqNo; + + dstOffset += 12; + } + + memcpy(udpPackets->data() + dstOffset, + tsPackets->data() + 188 * i, + 188); - int32_t dummy; - if (packets->meta()->findInt32("isVideo", &dummy)) { - isVideo = true; + dstOffset += 188; } - int64_t delayUs; - int64_t whenUs; + udpPackets->setRange(0, dstOffset); - if (mFirstOutputBufferReadyTimeUs < 0ll) { - mFirstOutputBufferReadyTimeUs = timeUs; - mFirstOutputBufferSentTimeUs = whenUs = ALooper::GetNowUs(); - delayUs = 0ll; - } else { - int64_t nowUs = ALooper::GetNowUs(); - - whenUs = (timeUs - mFirstOutputBufferReadyTimeUs) - + mFirstOutputBufferSentTimeUs; + sp msg = new AMessage(kWhatDrainQueue, id()); + msg->setBuffer("udpPackets", udpPackets); + msg->post(); - delayUs = whenUs - nowUs; +#if LOG_TRANSPORT_STREAM + if (mLogFile != NULL) { + fwrite(tsPackets->data(), 1, tsPackets->size(), mLogFile); } - - sp msg = new AMessage(kWhatQueuePackets, id()); - msg->setBuffer("packets", packets); - - packets->meta()->setInt64("timeUs", timeUs); - packets->meta()->setInt64("whenUs", whenUs); - packets->meta()->setInt64("delayUs", delayUs); - msg->post(delayUs > 0 ? delayUs : 0); +#endif } void Sender::onMessageReceived(const sp &msg) { switch (msg->what()) { case kWhatRTPNotify: case kWhatRTCPNotify: -#if ENABLE_RETRANSMISSION +#if ENABLE_RETRANSMISSION && RETRANSMISSION_ACCORDING_TO_RFC_XXXX case kWhatRTPRetransmissionNotify: case kWhatRTCPRetransmissionNotify: #endif @@ -419,7 +369,7 @@ void Sender::onMessageReceived(const sp &msg) { CHECK(msg->findString("detail", &detail)); if ((msg->what() == kWhatRTPNotify -#if ENABLE_RETRANSMISSION +#if ENABLE_RETRANSMISSION && RETRANSMISSION_ACCORDING_TO_RFC_XXXX || msg->what() == kWhatRTPRetransmissionNotify #endif ) && !errorOccuredDuringSend) { @@ -443,7 +393,7 @@ void Sender::onMessageReceived(const sp &msg) { } else if (sessionID == mRTCPSessionID) { mRTCPSessionID = 0; } -#if ENABLE_RETRANSMISSION +#if ENABLE_RETRANSMISSION && RETRANSMISSION_ACCORDING_TO_RFC_XXXX else if (sessionID == mRTPRetransmissionSessionID) { mRTPRetransmissionSessionID = 0; } else if (sessionID == mRTCPRetransmissionSessionID) { @@ -465,7 +415,7 @@ void Sender::onMessageReceived(const sp &msg) { status_t err; if (msg->what() == kWhatRTCPNotify -#if ENABLE_RETRANSMISSION +#if ENABLE_RETRANSMISSION && RETRANSMISSION_ACCORDING_TO_RFC_XXXX || msg->what() == kWhatRTCPRetransmissionNotify #endif ) @@ -507,12 +457,12 @@ void Sender::onMessageReceived(const sp &msg) { break; } - case kWhatQueuePackets: + case kWhatDrainQueue: { - sp packets; - CHECK(msg->findBuffer("packets", &packets)); + sp udpPackets; + CHECK(msg->findBuffer("udpPackets", &udpPackets)); - onQueuePackets(packets); + onDrainQueue(udpPackets); break; } @@ -532,156 +482,6 @@ void Sender::onMessageReceived(const sp &msg) { } } -void Sender::onQueuePackets(const sp &packets) { -#if DEBUG_JITTER - int32_t dummy; - if (packets->meta()->findInt32("isVideo", &dummy)) { - static int64_t lastTimeUs = 0ll; - int64_t nowUs = ALooper::GetNowUs(); - - static TimeSeries series; - series.add((double)(nowUs - lastTimeUs)); - - ALOGI("deltaTimeUs = %lld us, mean %.2f, sdev %.2f", - nowUs - lastTimeUs, series.mean(), series.sdev()); - - lastTimeUs = nowUs; - } -#endif - - int64_t startTimeUs = ALooper::GetNowUs(); - - for (size_t offset = 0; - offset < packets->size(); offset += 188) { - bool lastTSPacket = (offset + 188 >= packets->size()); - - appendTSData( - packets->data() + offset, - 188, - true /* timeDiscontinuity */, - lastTSPacket /* flush */); - } - -#if 0 - int64_t netTimeUs = ALooper::GetNowUs() - startTimeUs; - - int64_t whenUs; - CHECK(packets->meta()->findInt64("whenUs", &whenUs)); - - int64_t delayUs; - CHECK(packets->meta()->findInt64("delayUs", &delayUs)); - - bool isVideo = false; - int32_t dummy; - if (packets->meta()->findInt32("isVideo", &dummy)) { - isVideo = true; - } - - int64_t nowUs = ALooper::GetNowUs(); - - if (nowUs - whenUs > 2000) { - ALOGI("[%s] delayUs = %lld us, delta = %lld us", - isVideo ? "video" : "audio", delayUs, nowUs - netTimeUs - whenUs); - } -#endif - -#if LOG_TRANSPORT_STREAM - if (mLogFile != NULL) { - fwrite(packets->data(), 1, packets->size(), mLogFile); - } -#endif -} - -ssize_t Sender::appendTSData( - const void *data, size_t size, bool timeDiscontinuity, bool flush) { - CHECK_EQ(size, 188); - - CHECK_LE(mTSQueue->size() + size, mTSQueue->capacity()); - - memcpy(mTSQueue->data() + mTSQueue->size(), data, size); - mTSQueue->setRange(0, mTSQueue->size() + size); - - if (flush || mTSQueue->size() == mTSQueue->capacity()) { - // flush - - int64_t nowUs = ALooper::GetNowUs(); - -#if TRACK_BANDWIDTH - if (mFirstPacketTimeUs < 0ll) { - mFirstPacketTimeUs = nowUs; - } -#endif - - // 90kHz time scale - uint32_t rtpTime = (nowUs * 9ll) / 100ll; - - uint8_t *rtp = mTSQueue->data(); - rtp[0] = 0x80; - rtp[1] = 33 | (timeDiscontinuity ? (1 << 7) : 0); // M-bit - rtp[2] = (mRTPSeqNo >> 8) & 0xff; - rtp[3] = mRTPSeqNo & 0xff; - rtp[4] = rtpTime >> 24; - rtp[5] = (rtpTime >> 16) & 0xff; - rtp[6] = (rtpTime >> 8) & 0xff; - rtp[7] = rtpTime & 0xff; - rtp[8] = kSourceID >> 24; - rtp[9] = (kSourceID >> 16) & 0xff; - rtp[10] = (kSourceID >> 8) & 0xff; - rtp[11] = kSourceID & 0xff; - - ++mRTPSeqNo; - ++mNumRTPSent; - mNumRTPOctetsSent += mTSQueue->size() - 12; - - mLastRTPTime = rtpTime; - mLastNTPTime = GetNowNTP(); - - if (mTransportMode == TRANSPORT_TCP_INTERLEAVED) { - sp notify = mNotify->dup(); - notify->setInt32("what", kWhatBinaryData); - - sp data = new ABuffer(mTSQueue->size()); - memcpy(data->data(), rtp, mTSQueue->size()); - - notify->setInt32("channel", mRTPChannel); - notify->setBuffer("data", data); - notify->post(); - } else { - sendPacket(mRTPSessionID, rtp, mTSQueue->size()); - -#if TRACK_BANDWIDTH - mTotalBytesSent += mTSQueue->size(); - int64_t delayUs = ALooper::GetNowUs() - mFirstPacketTimeUs; - - if (delayUs > 0ll) { - ALOGI("approx. net bandwidth used: %.2f Mbit/sec", - mTotalBytesSent * 8.0 / delayUs); - } -#endif - } - -#if ENABLE_RETRANSMISSION - mTSQueue->setInt32Data(mRTPSeqNo - 1); - - mHistory.push_back(mTSQueue); - ++mHistoryLength; - - if (mHistoryLength > kMaxHistoryLength) { - mTSQueue = *mHistory.begin(); - mHistory.erase(mHistory.begin()); - - --mHistoryLength; - } else { - mTSQueue = new ABuffer(12 + kMaxNumTSPacketsPerRTPPacket * 188); - } -#endif - - mTSQueue->setRange(0, 12); - } - - return size; -} - void Sender::scheduleSendSR() { if (mSendSRPending || mRTCPSessionID == 0) { return; @@ -851,6 +651,7 @@ status_t Sender::parseTSFB( if (retransmit) { ALOGI("retransmitting seqNo %d", bufferSeqNo); +#if RETRANSMISSION_ACCORDING_TO_RFC_XXXX sp retransRTP = new ABuffer(2 + buffer->size()); uint8_t *rtp = retransRTP->data(); memcpy(rtp, buffer->data(), 12); @@ -865,6 +666,10 @@ status_t Sender::parseTSFB( sendPacket( mRTPRetransmissionSessionID, retransRTP->data(), retransRTP->size()); +#else + sendPacket( + mRTPSessionID, buffer->data(), buffer->size()); +#endif if (bufferSeqNo == seqNo) { foundSeqNo = true; @@ -975,5 +780,91 @@ void Sender::notifySessionDead() { notify->post(); } +void Sender::onDrainQueue(const sp &udpPackets) { + static const size_t kFullRTPPacketSize = + 12 + 188 * kMaxNumTSPacketsPerRTPPacket; + + size_t srcOffset = 0; + while (srcOffset < udpPackets->size()) { + uint8_t *rtp = udpPackets->data() + srcOffset; + + size_t rtpPacketSize = udpPackets->size() - srcOffset; + if (rtpPacketSize > kFullRTPPacketSize) { + rtpPacketSize = kFullRTPPacketSize; + } + + int64_t nowUs = ALooper::GetNowUs(); + mLastNTPTime = GetNowNTP(); + + // 90kHz time scale + uint32_t rtpTime = (nowUs * 9ll) / 100ll; + + rtp[4] = rtpTime >> 24; + rtp[5] = (rtpTime >> 16) & 0xff; + rtp[6] = (rtpTime >> 8) & 0xff; + rtp[7] = rtpTime & 0xff; + + ++mNumRTPSent; + mNumRTPOctetsSent += rtpPacketSize - 12; + + mLastRTPTime = rtpTime; + + if (mTransportMode == TRANSPORT_TCP_INTERLEAVED) { + sp notify = mNotify->dup(); + notify->setInt32("what", kWhatBinaryData); + + sp data = new ABuffer(rtpPacketSize); + memcpy(data->data(), rtp, rtpPacketSize); + + notify->setInt32("channel", mRTPChannel); + notify->setBuffer("data", data); + notify->post(); + } else { + sendPacket(mRTPSessionID, rtp, rtpPacketSize); + +#if TRACK_BANDWIDTH + mTotalBytesSent += rtpPacketSize->size(); + int64_t delayUs = ALooper::GetNowUs() - mFirstPacketTimeUs; + + if (delayUs > 0ll) { + ALOGI("approx. net bandwidth used: %.2f Mbit/sec", + mTotalBytesSent * 8.0 / delayUs); + } +#endif + } + +#if ENABLE_RETRANSMISSION + addToHistory(rtp, rtpPacketSize); +#endif + + srcOffset += rtpPacketSize; + } + +#if 0 + int64_t timeUs; + CHECK(udpPackets->meta()->findInt64("timeUs", &timeUs)); + + ALOGI("dTimeUs = %lld us", ALooper::GetNowUs() - timeUs); +#endif +} + +#if ENABLE_RETRANSMISSION +void Sender::addToHistory(const uint8_t *rtp, size_t rtpPacketSize) { + sp packet = new ABuffer(rtpPacketSize); + memcpy(packet->data(), rtp, rtpPacketSize); + + unsigned rtpSeqNo = U16_AT(&rtp[2]); + packet->setInt32Data(rtpSeqNo); + + mHistory.push_back(packet); + ++mHistoryLength; + + if (mHistoryLength > kMaxHistoryLength) { + mHistory.erase(mHistory.begin()); + --mHistoryLength; + } +} +#endif + } // namespace android diff --git a/media/libstagefright/wifi-display/source/Sender.h b/media/libstagefright/wifi-display/source/Sender.h index e476e84..73e3d19 100644 --- a/media/libstagefright/wifi-display/source/Sender.h +++ b/media/libstagefright/wifi-display/source/Sender.h @@ -23,9 +23,17 @@ namespace android { #define LOG_TRANSPORT_STREAM 0 -#define ENABLE_RETRANSMISSION 0 #define TRACK_BANDWIDTH 0 +#define ENABLE_RETRANSMISSION 0 + +// If retransmission is enabled the following define determines what +// kind we support, if RETRANSMISSION_ACCORDING_TO_RFC_XXXX is 0 +// we'll send NACKs on the original RTCP channel and retransmit packets +// on the original RTP channel, otherwise a separate channel pair is used +// for this purpose. +#define RETRANSMISSION_ACCORDING_TO_RFC_XXXX 0 + struct ABuffer; struct ANetworkSession; @@ -51,7 +59,7 @@ struct Sender : public AHandler { int32_t getRTPPort() const; - void queuePackets(int64_t timeUs, const sp &packets); + void queuePackets(int64_t timeUs, const sp &tsPackets); void scheduleSendSR(); protected: @@ -60,13 +68,13 @@ protected: private: enum { - kWhatQueuePackets, + kWhatDrainQueue, kWhatSendSR, kWhatRTPNotify, kWhatRTCPNotify, -#if ENABLE_RETRANSMISSION +#if ENABLE_RETRANSMISSION && RETRANSMISSION_ACCORDING_TO_RFC_XXXX kWhatRTPRetransmissionNotify, - kWhatRTCPRetransmissionNotify + kWhatRTCPRetransmissionNotify, #endif }; @@ -75,15 +83,13 @@ private: static const uint32_t kSourceID = 0xdeadbeef; static const size_t kMaxHistoryLength = 128; -#if ENABLE_RETRANSMISSION +#if ENABLE_RETRANSMISSION && RETRANSMISSION_ACCORDING_TO_RFC_XXXX static const size_t kRetransmissionPortOffset = 120; #endif sp mNetSession; sp mNotify; - sp mTSQueue; - TransportMode mTransportMode; AString mClientIP; @@ -96,7 +102,7 @@ private: int32_t mRTPSessionID; int32_t mRTCPSessionID; -#if ENABLE_RETRANSMISSION +#if ENABLE_RETRANSMISSION && RETRANSMISSION_ACCORDING_TO_RFC_XXXX int32_t mRTPRetransmissionSessionID; int32_t mRTCPRetransmissionSessionID; #endif @@ -106,12 +112,11 @@ private: bool mRTPConnected; bool mRTCPConnected; - int64_t mFirstOutputBufferReadyTimeUs; int64_t mFirstOutputBufferSentTimeUs; uint32_t mRTPSeqNo; -#if ENABLE_RETRANSMISSION +#if ENABLE_RETRANSMISSION && RETRANSMISSION_ACCORDING_TO_RFC_XXXX uint32_t mRTPRetransmissionSeqNo; #endif @@ -133,22 +138,18 @@ private: uint64_t mTotalBytesSent; #endif - void onSendSR(); - void addSR(const sp &buffer); - void addSDES(const sp &buffer); - static uint64_t GetNowNTP(); - #if LOG_TRANSPORT_STREAM FILE *mLogFile; #endif - ssize_t appendTSData( - const void *data, size_t size, bool timeDiscontinuity, bool flush); - - void onQueuePackets(const sp &packets); + void onSendSR(); + void addSR(const sp &buffer); + void addSDES(const sp &buffer); + static uint64_t GetNowNTP(); #if ENABLE_RETRANSMISSION status_t parseTSFB(const uint8_t *data, size_t size); + void addToHistory(const uint8_t *rtp, size_t rtpPacketSize); #endif status_t parseRTCP(const sp &buffer); @@ -158,6 +159,8 @@ private: void notifyInitDone(); void notifySessionDead(); + void onDrainQueue(const sp &udpPackets); + DISALLOW_EVIL_CONSTRUCTORS(Sender); }; diff --git a/media/libstagefright/wifi-display/source/TSPacketizer.cpp b/media/libstagefright/wifi-display/source/TSPacketizer.cpp index a5679ad..ef57a4d 100644 --- a/media/libstagefright/wifi-display/source/TSPacketizer.cpp +++ b/media/libstagefright/wifi-display/source/TSPacketizer.cpp @@ -314,6 +314,25 @@ void TSPacketizer::Track::finalize() { mDescriptors.push_back(descriptor); } + int32_t hdcpVersion; + if (mFormat->findInt32("hdcp-version", &hdcpVersion)) { + // HDCP descriptor + + CHECK(hdcpVersion == 0x20 || hdcpVersion == 0x21); + + sp descriptor = new ABuffer(7); + uint8_t *data = descriptor->data(); + data[0] = 0x05; // descriptor_tag + data[1] = 5; // descriptor_length + data[2] = 'H'; + data[3] = 'D'; + data[4] = 'C'; + data[5] = 'P'; + data[6] = hdcpVersion; + + mDescriptors.push_back(descriptor); + } + mFinalized = true; } diff --git a/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp b/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp index b16c5d0..78d6e62 100644 --- a/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp +++ b/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp @@ -534,9 +534,15 @@ status_t WifiDisplaySource::sendM4(int32_t sessionID) { // use "28 00 02 02 00000020 00000000 00000000 00 0000 0000 00 none none\r\n" // For 720p24: // use "78 00 02 02 00008000 00000000 00000000 00 0000 0000 00 none none\r\n" + // For 1080p30: + // use "38 00 02 02 00000080 00000000 00000000 00 0000 0000 00 none none\r\n" AString body = StringPrintf( "wfd_video_formats: " +#if USE_1080P + "38 00 02 02 00000080 00000000 00000000 00 0000 0000 00 none none\r\n" +#else "28 00 02 02 00000020 00000000 00000000 00 0000 0000 00 none none\r\n" +#endif "wfd_audio_codecs: %s\r\n" "wfd_presentation_URL: rtsp://%s/wfd1.0/streamid=0 none\r\n" "wfd_client_rtp_ports: RTP/AVP/%s;unicast %d 0 mode=play\r\n", @@ -773,8 +779,10 @@ status_t WifiDisplaySource::onReceiveM3Response( status_t err = makeHDCP(); if (err != OK) { - ALOGE("Unable to instantiate HDCP component."); - return err; + ALOGE("Unable to instantiate HDCP component. " + "Not using HDCP after all."); + + mUsingHDCP = false; } } diff --git a/media/libstagefright/wifi-display/source/WifiDisplaySource.h b/media/libstagefright/wifi-display/source/WifiDisplaySource.h index 02fa0a6..1e855e7 100644 --- a/media/libstagefright/wifi-display/source/WifiDisplaySource.h +++ b/media/libstagefright/wifi-display/source/WifiDisplaySource.h @@ -26,6 +26,8 @@ namespace android { +#define USE_1080P 0 + struct IHDCP; struct IRemoteDisplayClient; struct ParsedMessage; diff --git a/media/libstagefright/wifi-display/wfd.cpp b/media/libstagefright/wifi-display/wfd.cpp index 011edab..03a1123 100644 --- a/media/libstagefright/wifi-display/wfd.cpp +++ b/media/libstagefright/wifi-display/wfd.cpp @@ -23,22 +23,163 @@ #include #include +#include +#include #include +#include +#include #include #include namespace android { -} // namespace android - static void usage(const char *me) { fprintf(stderr, "usage:\n" " %s -c host[:port]\tconnect to wifi source\n" - " -u uri \tconnect to an rtsp uri\n", + " -u uri \tconnect to an rtsp uri\n" + " -l ip[:port] \tlisten on the specified port " + "(create a sink)\n", me); } +struct RemoteDisplayClient : public BnRemoteDisplayClient { + RemoteDisplayClient(); + + virtual void onDisplayConnected( + const sp &surfaceTexture, + uint32_t width, + uint32_t height, + uint32_t flags); + + virtual void onDisplayDisconnected(); + virtual void onDisplayError(int32_t error); + + void waitUntilDone(); + +protected: + virtual ~RemoteDisplayClient(); + +private: + Mutex mLock; + Condition mCondition; + + bool mDone; + + sp mComposerClient; + sp mSurfaceTexture; + sp mDisplayBinder; + + DISALLOW_EVIL_CONSTRUCTORS(RemoteDisplayClient); +}; + +RemoteDisplayClient::RemoteDisplayClient() + : mDone(false) { + mComposerClient = new SurfaceComposerClient; + CHECK_EQ(mComposerClient->initCheck(), (status_t)OK); +} + +RemoteDisplayClient::~RemoteDisplayClient() { +} + +void RemoteDisplayClient::onDisplayConnected( + const sp &surfaceTexture, + uint32_t width, + uint32_t height, + uint32_t flags) { + ALOGI("onDisplayConnected width=%u, height=%u, flags = 0x%08x", + width, height, flags); + + mSurfaceTexture = surfaceTexture; + mDisplayBinder = mComposerClient->createDisplay( + String8("foo"), false /* secure */); + + SurfaceComposerClient::openGlobalTransaction(); + mComposerClient->setDisplaySurface(mDisplayBinder, mSurfaceTexture); + + Rect layerStackRect(1280, 720); // XXX fix this. + Rect displayRect(1280, 720); + + mComposerClient->setDisplayProjection( + mDisplayBinder, 0 /* 0 degree rotation */, + layerStackRect, + displayRect); + + SurfaceComposerClient::closeGlobalTransaction(); +} + +void RemoteDisplayClient::onDisplayDisconnected() { + ALOGI("onDisplayDisconnected"); + + Mutex::Autolock autoLock(mLock); + mDone = true; + mCondition.broadcast(); +} + +void RemoteDisplayClient::onDisplayError(int32_t error) { + ALOGI("onDisplayError error=%d", error); + + Mutex::Autolock autoLock(mLock); + mDone = true; + mCondition.broadcast(); +} + +void RemoteDisplayClient::waitUntilDone() { + Mutex::Autolock autoLock(mLock); + while (!mDone) { + mCondition.wait(mLock); + } +} + +static status_t enableAudioSubmix(bool enable) { + status_t err = AudioSystem::setDeviceConnectionState( + AUDIO_DEVICE_IN_REMOTE_SUBMIX, + enable + ? AUDIO_POLICY_DEVICE_STATE_AVAILABLE + : AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, + NULL /* device_address */); + + if (err != OK) { + return err; + } + + err = AudioSystem::setDeviceConnectionState( + AUDIO_DEVICE_OUT_REMOTE_SUBMIX, + enable + ? AUDIO_POLICY_DEVICE_STATE_AVAILABLE + : AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, + NULL /* device_address */); + + return err; +} + +static void createSource(const AString &addr, int32_t port) { + sp sm = defaultServiceManager(); + sp binder = sm->getService(String16("media.player")); + sp service = + interface_cast(binder); + + CHECK(service.get() != NULL); + + enableAudioSubmix(true /* enable */); + + String8 iface; + iface.append(addr.c_str()); + iface.append(StringPrintf(":%d", port).c_str()); + + sp client = new RemoteDisplayClient; + sp display = service->listenForRemoteDisplay(client, iface); + + client->waitUntilDone(); + + display->dispose(); + display.clear(); + + enableAudioSubmix(false /* enable */); +} + +} // namespace android + int main(int argc, char **argv) { using namespace android; @@ -50,6 +191,9 @@ int main(int argc, char **argv) { int32_t connectToPort = -1; AString uri; + AString listenOnAddr; + int32_t listenOnPort = -1; + int res; while ((res = getopt(argc, argv, "hc:l:u:")) >= 0) { switch (res) { @@ -81,6 +225,28 @@ int main(int argc, char **argv) { break; } + case 'l': + { + const char *colonPos = strrchr(optarg, ':'); + + if (colonPos == NULL) { + listenOnAddr = optarg; + listenOnPort = WifiDisplaySource::kWifiDisplayDefaultPort; + } else { + listenOnAddr.setTo(optarg, colonPos - optarg); + + char *end; + listenOnPort = strtol(colonPos + 1, &end, 10); + + if (*end != '\0' || end == colonPos + 1 + || listenOnPort < 1 || listenOnPort > 65535) { + fprintf(stderr, "Illegal port specified.\n"); + exit(1); + } + } + break; + } + case '?': case 'h': default: @@ -89,6 +255,18 @@ int main(int argc, char **argv) { } } + if (connectToPort >= 0 && listenOnPort >= 0) { + fprintf(stderr, + "You can connect to a source or create one, " + "but not both at the same time.\n"); + exit(1); + } + + if (listenOnPort >= 0) { + createSource(listenOnAddr, listenOnPort); + exit(0); + } + if (connectToPort < 0 && uri.empty()) { fprintf(stderr, "You need to select either source host or uri.\n"); -- cgit v1.1 From 4471e47ece77be5b4159cc9cbbcef4d43900d36f Mon Sep 17 00:00:00 2001 From: Andreas Huber Date: Wed, 14 Nov 2012 09:06:33 -0800 Subject: Properly signal an error if codec configuration goes wrong. previously any error signaled by setupXXX inside ACodec::configureCodec would be overwritten with the result of setMinBufferSize at the end of the function. Change-Id: Id4beb571ca52ea4646239d0af006e09ce1130268 related-to-bug: 7542181 --- media/libstagefright/ACodec.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp index 0ca027b..84b4962 100644 --- a/media/libstagefright/ACodec.cpp +++ b/media/libstagefright/ACodec.cpp @@ -937,7 +937,8 @@ status_t ACodec::configureCodec( } err = setupAACCodec( - encoder, numChannels, sampleRate, bitRate, aacProfile, isADTS != 0); + encoder, numChannels, sampleRate, bitRate, aacProfile, + isADTS != 0); } } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) { err = setupAMRCodec(encoder, false /* isWAMR */, bitRate); @@ -986,6 +987,10 @@ status_t ACodec::configureCodec( } } + if (err != OK) { + return err; + } + if (!msg->findInt32("encoder-delay", &mEncoderDelay)) { mEncoderDelay = 0; } -- cgit v1.1 From d983364b3655a547b55bb11dbe148103198c011d Mon Sep 17 00:00:00 2001 From: Glenn Kasten Date: Thu, 15 Nov 2012 14:13:16 -0800 Subject: Static AudioTrack plays twice initially Bug: 7528721 Change-Id: I10bc16a26f33dba6572b730a170cb3bf00e68e30 --- services/audioflinger/AudioFlinger.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp index 76d6447..1913b6f 100644 --- a/services/audioflinger/AudioFlinger.cpp +++ b/services/audioflinger/AudioFlinger.cpp @@ -4681,7 +4681,7 @@ void AudioFlinger::PlaybackThread::Track::flush() if (thread != 0) { Mutex::Autolock _l(thread->mLock); if (mState != STOPPING_1 && mState != STOPPING_2 && mState != STOPPED && mState != PAUSED && - mState != PAUSING) { + mState != PAUSING && mState != IDLE && mState != FLUSHED) { return; } // No point remaining in PAUSED state after a flush => go to -- cgit v1.1 From aa9e3e01b86bd9bfb5ac36c0f360d5fe478cbb2d Mon Sep 17 00:00:00 2001 From: Igor Murashkin Date: Mon, 26 Nov 2012 10:50:55 -0800 Subject: Camera: Play shutter sound iff enableShutterSound(true) && ShutterCallback !null Bug: 7564718 Change-Id: Ie7821cdee57966d88af048759578439a3e6ecb2e --- services/camera/libcameraservice/Camera2Client.cpp | 2 +- .../camera/libcameraservice/camera2/CaptureSequencer.cpp | 16 ++++++++++------ .../camera/libcameraservice/camera2/CaptureSequencer.h | 5 +++-- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/services/camera/libcameraservice/Camera2Client.cpp b/services/camera/libcameraservice/Camera2Client.cpp index e59a240..0f1e650 100644 --- a/services/camera/libcameraservice/Camera2Client.cpp +++ b/services/camera/libcameraservice/Camera2Client.cpp @@ -1111,7 +1111,7 @@ status_t Camera2Client::takePicture(int msgType) { // Need HAL to have correct settings before (possibly) triggering precapture syncWithDevice(); - res = mCaptureSequencer->startCapture(); + res = mCaptureSequencer->startCapture(msgType); if (res != OK) { ALOGE("%s: Camera %d: Unable to start capture: %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res); diff --git a/services/camera/libcameraservice/camera2/CaptureSequencer.cpp b/services/camera/libcameraservice/camera2/CaptureSequencer.cpp index fe4abc0..072453b 100644 --- a/services/camera/libcameraservice/camera2/CaptureSequencer.cpp +++ b/services/camera/libcameraservice/camera2/CaptureSequencer.cpp @@ -45,7 +45,8 @@ CaptureSequencer::CaptureSequencer(wp client): mCaptureState(IDLE), mTriggerId(0), mTimeoutCount(0), - mCaptureId(Camera2Client::kCaptureRequestIdStart) { + mCaptureId(Camera2Client::kCaptureRequestIdStart), + mMsgType(0) { ALOGV("%s", __FUNCTION__); } @@ -58,7 +59,7 @@ void CaptureSequencer::setZslProcessor(wp processor) { mZslProcessor = processor; } -status_t CaptureSequencer::startCapture() { +status_t CaptureSequencer::startCapture(int msgType) { ALOGV("%s", __FUNCTION__); ATRACE_CALL(); Mutex::Autolock l(mInputMutex); @@ -67,6 +68,7 @@ status_t CaptureSequencer::startCapture() { return INVALID_OPERATION; } if (!mStartCapture) { + mMsgType = msgType; mStartCapture = true; mStartCaptureSignal.signal(); } @@ -343,7 +345,7 @@ CaptureSequencer::CaptureState CaptureSequencer::manageZslStart( SharedParameters::Lock l(client->getParameters()); /* warning: this also locks a SharedCameraClient */ - shutterNotifyLocked(l.mParameters, client); + shutterNotifyLocked(l.mParameters, client, mMsgType); mShutterNotified = true; mTimeoutCount = kMaxTimeoutsForCaptureEnd; return STANDARD_CAPTURE_WAIT; @@ -495,7 +497,7 @@ CaptureSequencer::CaptureState CaptureSequencer::manageStandardCaptureWait( if (mNewFrameReceived && !mShutterNotified) { SharedParameters::Lock l(client->getParameters()); /* warning: this also locks a SharedCameraClient */ - shutterNotifyLocked(l.mParameters, client); + shutterNotifyLocked(l.mParameters, client, mMsgType); mShutterNotified = true; } while (mNewFrameReceived && !mNewCaptureReceived) { @@ -639,10 +641,12 @@ status_t CaptureSequencer::updateCaptureRequest(const Parameters ¶ms, } /*static*/ void CaptureSequencer::shutterNotifyLocked(const Parameters ¶ms, - sp client) { + sp client, int msgType) { ATRACE_CALL(); - if (params.state == Parameters::STILL_CAPTURE && params.playShutterSound) { + if (params.state == Parameters::STILL_CAPTURE + && params.playShutterSound + && (msgType & CAMERA_MSG_SHUTTER)) { client->getCameraService()->playSound(CameraService::SOUND_SHUTTER); } diff --git a/services/camera/libcameraservice/camera2/CaptureSequencer.h b/services/camera/libcameraservice/camera2/CaptureSequencer.h index 4cde9c8..c42df05 100644 --- a/services/camera/libcameraservice/camera2/CaptureSequencer.h +++ b/services/camera/libcameraservice/camera2/CaptureSequencer.h @@ -51,7 +51,7 @@ class CaptureSequencer: void setZslProcessor(wp processor); // Begin still image capture - status_t startCapture(); + status_t startCapture(int msgType); // Wait until current image capture completes; returns immediately if no // capture is active. Returns TIMED_OUT if capture does not complete during @@ -138,6 +138,7 @@ class CaptureSequencer: bool mAeInPrecapture; int32_t mCaptureId; + int mMsgType; // Main internal methods @@ -167,7 +168,7 @@ class CaptureSequencer: // Emit Shutter/Raw callback to java, and maybe play a shutter sound static void shutterNotifyLocked(const Parameters ¶ms, - sp client); + sp client, int msgType); }; }; // namespace camera2 -- cgit v1.1 From 9bcb476a95a26e62f5706d1f00f4873cf44f9e04 Mon Sep 17 00:00:00 2001 From: Glenn Kasten Date: Mon, 19 Nov 2012 09:00:47 -0800 Subject: New VHQ resampler Squashed commit of the following: commit 12b6952da9f25e94d06dd7185bce255924e7e791 Author: Mathias Agopian Date: Mon Nov 19 15:27:26 2012 -0800 fix a typo in SINC resampler that prevented tracks to be mixed we were always erasing the current mix instead of mixing into it. Change-Id: Ib229245f9e5a0d384f1727640a59e9f0469211a2 commit 0019ce082df430278f14ab922e900ce33b64897d Author: Dave Bort Date: Tue Nov 13 01:30:32 2007 -0800 Rename "TARGET" to "MODULE" in the build system. Part one of the grand renaming. API_CHANGE: Third parties may need to update their makefiles. Any variables with "LOCAL" and "TARGET" in their names should now use "MODULE" instead of "TARGET"; e.g., LOCAL_MODULE, LOCAL_MODULE_TAGS. PRESUBMIT=passed OCL=39840 Change-Id: Ica9a7937d3d9552ab84db46ac6eea8a290e404fe Signed-off-by: Glenn Kasten commit f01adc0cef0e39e75c76d9195ac26a94cac0a100 Author: Glenn Kasten Date: Wed Nov 14 08:32:08 2012 -0800 Fix build warnings Change-Id: Ic43bcca166a529a6431711b05a7fa21849b6a38b commit 9bb031a565c753a03d9c9397edea318947d80528 Author: Mathias Agopian Date: Sat Nov 10 04:44:30 2012 -0800 more optimizations... calculate the offsets from the phase differently, this happens to reduce the register pressure in the main loop, which in turns allows the compiler to generate much better code (doesn't need to spill a lot of stuff on the stack). this gives another 15% performance increase Change-Id: I2ce3479dd48b9e6941adb80e6d443d6e14d64d96 commit 5a951598f31217b8cd2babd0720c9608ee17291a Author: Mathias Agopian Date: Sat Nov 10 03:26:39 2012 -0800 refactor code to improve neon code we want to make sure we don't transfer data from the neon unit to the arm register file, as this can be quite slow. instead we do all the calculation on the neon side and write the result directly to main memory. Change-Id: Ibb56664d3ab03098ae2798b75e2b6927ac900187 commit b381ee9e83bc9fd18986e79c7809841514ed590e Author: Mathias Agopian Date: Sun Nov 4 15:16:13 2012 -0800 NEON optimized SINC resampler this currently gives us a 60% to 80% boost depending on the quality level selected. Change-Id: I7db385007e811ed7bffe5fd3403b44e300894f5b commit bea077354210242ea193a50b0dbab0fedab25df3 Author: Mathias Agopian Date: Mon Nov 5 01:51:37 2012 -0800 minor cleanups Change-Id: Ia12ee4fb59e90221761bec85e6450db29197591f commit 8f4ed7decbe161a5ff38200b218f5216d80aba46 Author: Mathias Agopian Date: Sun Nov 4 18:49:14 2012 -0800 improve resample test - handle stereo input - input file can now be ommited, in this case a linear chirp will be used automatically - better usage information Change-Id: I5d62a6c26a9054a1c1a517a065b4df5a2cdcda22 commit 5fcd634ea6cb4df27c495abe20f5f9b8ff55d128 Author: Mathias Agopian Date: Sun Nov 4 02:03:49 2012 -0800 change how we store the FIR coefficients The coefficient table is now transposed and shows much better its polyphase nature: we now have a FIR per line, each line corresponding to a phase. This doesn't change at all the results produced by the filter, but allows us to make slightly better use of the data cache and improves performance a bit (although not as much as I thought it would). The main benefit is that it is the first step before we can make much larger optimizations (like using NEON). Change-Id: Iebf7695825dcbd41f25861efcaefbaa3365ecb43 commit d652231abf4c7e2ea1fc89caae730cec1f7259a1 Author: Mathias Agopian Date: Sat Nov 3 23:37:53 2012 -0700 improve SINC resampler performance The improvement is about 60% by just tweaking a few things to help the compiler generate better code. It turns out that inlining too much stuff manually was hurting us. Change-Id: I8068f0f75051f95ac600e50ce552572dd1e8c304 commit 9dc68ef5b94c700c4ee68790e8cbb334c90a538d Author: Mathias Agopian Date: Thu Nov 1 21:03:46 2012 -0700 new coefficients for the vhq resampler previous coefficients were provided by a 3rd party and didn't have a way to re-generate them. we're now using the 'fir' utility. the performance of the filter is virtually identical, except for the down-sampling case which seems slightly better now: It looks like both the previous and new coefficients are generating some sort of clipping for full-scale signals in the down-sampling case (although the new ones seem better), the reason for that is unknown (see bug: 7453062) Also updated the HQ coefficients for the down-samplers, previous ones were a little bit too conservative -- the new ones push the cut-off frequency up by about 1 KHz. Change-Id: I54a827b5c707c7cc41268ed01283758dce1d7647 commit 38e0b8560a6fc1b7124e22e0e09a84a285182f8e Author: Mathias Agopian Date: Tue Oct 30 13:51:44 2012 -0700 fix SINC resampler on non ARM architectures make sure the C version of the code generates the same output than the ARM assemply version. Change-Id: Ide218785c35d02598b2d7278e646b1b178148698 commit a1878128b182696ba508569b4d211d0dfae92463 Author: Mathias Agopian Date: Tue Oct 30 12:49:07 2012 -0700 fix another issue with generating FIR coefficients the impulse response of a low-pass is 2*f*sinc(2*pi*f*k), we were missing the 2*f scale factor. This explains why we were seeing clipping and had to manually scale the filter down. Change-Id: I86d0bb82ecdd99681c8ba5a8112a8257bf6f0186 commit 1a0fb993430acc9f601e6c538305bc407c20ac5d Author: Mathias Agopian Date: Mon Oct 29 17:13:20 2012 -0700 fir a typo that caused up-sampling coefficiens to be wrong up-sample coefficient were generated with a cut-off frequency of 24KHz intead of ~20KHz, which caused more aliasing in the audible band. also increased the attenuation to 1.3 dB on both up and down sampling coefficient to avoid clipping. Change-Id: Ie8aeecf1429190541b656810c6716b6aae5ece2e commit 9520ad6862bd682ad075a9d9e3e94ada9f6e58b6 Author: Mathias Agopian Date: Mon Oct 29 17:13:16 2012 -0700 test-resample: clip instead of overflowing Change-Id: I550e5a59e51c11e1095ca338222b094f92b96878 commit ba36656300f250f7f1fdeb75149749344260e6cb Author: Mathias Agopian Date: Sun Oct 21 01:01:38 2012 -0700 a test app for the resamplers Change-Id: I66852d90d384f1d9e77b51ad1a1ebdbaf61d0607 commit 056a08b9bfd33cf27228c992adc8293a56b01be8 Author: Mathias Agopian Date: Fri Oct 26 14:11:01 2012 -0700 reenable the cubic resampler cubic resampler was disabled because it hadn't been qualified, however after I did some tests, it does improve significantly the sound quality over the order-1 resampler, even if it is still quite bad. also HIGH_QUALITY resampler was partially disabled, it's now fully enabled. It's a big improvement over the cubic resampler in terms of aliasing noise (it's not as good in the pass-band). Change-Id: I70e3658c255896588642697be9eb594ff4ec0f8b commit 8c0241d3ff50ae85167f69b3bd369244894cfa44 Author: Mathias Agopian Date: Fri Oct 26 13:48:42 2012 -0700 improve SINC resampler coefficients - we increase the interpolation precision from 4 to 7 bits this doesn't increase CPU power required, it only increases the size of the filter table but significantly reduces the noise introduced by the quantization of the impulse response. - the parameters of the filter are set such that aliasing is rejected at 80 dB below 20 KHz. Because we don't use a lot of coefficient (to save compute power), there are quite a bit of attenuation in the pass-band: starting at 9KHz for the down-sampler (48 to 44.1), and starting at 13 KHz for the up-sampler (44.1 to 48) -- the transition band is about 15 KHz. Change-Id: I855548d2aab8a0fb0d2a2da3a364b6842d7d3838 commit 69e7dab2192adc1f780464146810629ebd01b145 Author: Pixelflinger Date: Thu Oct 25 19:43:49 2012 -0700 improve fir tool: cleanup, better default, bug fixes - all parameters can be changed on the command-line - added float output - added debug option - added an option to generate a polyphase filter coefficients - added an attenuation option in dBFS - added a lot of comments and references - fixed kaiser window parameter also the default should generate a filter with 80 dB rejection (of the 24 KHz aliasing) above 20 KHz and a 15 KHz transition band around ~20 KHz (for 48 KHz sampling rate). It's not very good but corresponds to the current code. commit 8347499d105a50257c18e9dac652e750b06428b1 Author: Glenn Kasten Date: Mon Oct 22 17:09:27 2012 -0700 Increase allowed number of VHQ resamplers to 3 Bug: 7378660 Change-Id: I69e33ca2eb4bb9bd38e2c63df62cd1130d68baf6 commit f91cf3cad7f5c4d52614271c89ab468741c5d24c Author: Mathias Agopian Date: Sun Oct 21 03:04:05 2012 -0700 Fix a typo that caused the high quality resampler to produce garbage the problem is that if libaudio_resampler is present, it is those coefficients that will always be selected, but the correct meta-data. Bug: 7385994 Change-Id: Ieebeb37b4dfb62a1a051bc29fae2ce056dbc6621 commit e158a9e4262a174c59469a205658bc3ca4078234 Author: Dan Bornstein Date: Fri Oct 3 10:34:57 2008 -0700 Manually merge change #111620 from tc3 to mainline, to keep the automerger from choking on it. p4 sync p4 integrate -r -b android_to_tc3 //...@111620,111620 p4 resolve -a p4 resolve # resolve a couple merge travesties PRESUBMIT=passed BUG=1399648 TBR=edheyl OCL=111902 Change-Id: I854b01553dd92bbf9c864f5a9bd51a3d665f0ac2 Signed-off-by: Glenn Kasten commit b9f3c26032be7a6ea01a10d93d94826f449e68ab Author: Dave Bort Date: Fri Jan 18 14:51:05 2008 -0800 Rename "Makefile" to "Android.mk" throughout the tree. For . I've tested this as much as I can, but 1500 open files = easy to mess things up. Please let me know if there's a problem rather than rolling back this change. PRESUBMIT=passed BUG=960416 TBR=joeo OCL=46537 Change-Id: I5a404caf0f398a7afa7ae7abaf2f2a1c6ab490eb Signed-off-by: Glenn Kasten commit 0c22a9a44c4103483fba1d944acf1354c5eb1617 Author: Mathias Agopian Date: Mon Oct 29 23:44:25 2007 -0700 Tweak the SINC resampler parameters and double the performance. It's using about 10% CPU in the worse case now. Change-Id: I50ac7e6c6702a427fa36ab6d976c507155057507 Signed-off-by: Glenn Kasten commit b85e41487983ad085b859acf8251e7e54480308a Author: Mathias Agopian Date: Mon Oct 29 04:34:36 2007 -0700 A sinc resampler for Audioflinger. It's not enabled yet, but fully functional and apparently working. It need more "quality" tests. In the 48->44 KHz, it takes about 25% of the CPU time. Change-Id: I80eb5185e13ebdb907e0b85c49ba1272c23d60ec Signed-off-by: Glenn Kasten commit ba3949ef17cac2ba71cc3096c413782a49c922e5 Author: Mathias Agopian Date: Thu Aug 23 21:01:28 2007 -0700 fix a few small typos in the FIR computation Change-Id: I6e56b514fe520f30f7487f85c64ea5d2a7c19b40 Signed-off-by: Glenn Kasten commit 7474bfa7de2604021963794dddfe44985648db6a Author: Mathias Agopian Date: Thu Aug 23 03:16:02 2007 -0700 This is a tool to compute the the reconstruction filter coefficients for a sinc audio resampler. Change-Id: I99be2505139b8e0e7647200e1647509d4f7e6067 Signed-off-by: Glenn Kasten Bug: 7577965 Change-Id: I2c84a9283a1668723bad83e1a119c849c88c3e6b --- services/audioflinger/Android.mk | 27 +- services/audioflinger/AudioResampler.cpp | 4 - services/audioflinger/AudioResamplerSinc.cpp | 659 ++++- services/audioflinger/AudioResamplerSinc.h | 13 +- .../audio-resampler/AudioResamplerCoefficients.cpp | 29 +- .../dnsampler_filter_coefficients_x128_10112011.h | 2585 -------------------- .../audio-resampler/filter_coefficients.h | 285 +++ .../resampler_filter_coefficients_10042011.h | 2071 ---------------- services/audioflinger/test-resample.cpp | 274 +++ tools/resampler_tools/Android.mk | 17 + tools/resampler_tools/fir.cpp | 281 +++ 11 files changed, 1427 insertions(+), 4818 deletions(-) delete mode 100644 services/audioflinger/audio-resampler/dnsampler_filter_coefficients_x128_10112011.h create mode 100644 services/audioflinger/audio-resampler/filter_coefficients.h delete mode 100644 services/audioflinger/audio-resampler/resampler_filter_coefficients_10042011.h create mode 100644 services/audioflinger/test-resample.cpp create mode 100644 tools/resampler_tools/Android.mk create mode 100644 tools/resampler_tools/fir.cpp diff --git a/services/audioflinger/Android.mk b/services/audioflinger/Android.mk index bd9421c..2899953 100644 --- a/services/audioflinger/Android.mk +++ b/services/audioflinger/Android.mk @@ -19,11 +19,9 @@ LOCAL_SRC_FILES:= \ AudioResampler.cpp.arm \ AudioPolicyService.cpp \ ServiceUtilities.cpp \ + AudioResamplerCubic.cpp.arm \ AudioResamplerSinc.cpp.arm -# uncomment to enable AudioResampler::MED_QUALITY -# LOCAL_SRC_FILES += AudioResamplerCubic.cpp.arm - LOCAL_SRC_FILES += StateQueue.cpp # uncomment for debugging timing problems related to StateQueue::push() @@ -80,4 +78,27 @@ LOCAL_CFLAGS += -UFAST_TRACKS_AT_NON_NATIVE_SAMPLE_RATE include $(BUILD_SHARED_LIBRARY) +# +# build audio resampler test tool +# +include $(CLEAR_VARS) + +LOCAL_SRC_FILES:= \ + test-resample.cpp \ + AudioResampler.cpp.arm \ + AudioResamplerCubic.cpp.arm \ + AudioResamplerSinc.cpp.arm + +LOCAL_SHARED_LIBRARIES := \ + libdl \ + libcutils \ + libutils + +LOCAL_MODULE:= test-resample + +LOCAL_MODULE_TAGS := optional + +include $(BUILD_EXECUTABLE) + + include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/services/audioflinger/AudioResampler.cpp b/services/audioflinger/AudioResampler.cpp index ffea9b9..2c3c719 100644 --- a/services/audioflinger/AudioResampler.cpp +++ b/services/audioflinger/AudioResampler.cpp @@ -82,10 +82,8 @@ bool AudioResampler::qualityIsSupported(src_quality quality) switch (quality) { case DEFAULT_QUALITY: case LOW_QUALITY: -#if 0 // these have not been qualified recently so are not supported unless explicitly requested case MED_QUALITY: case HIGH_QUALITY: -#endif case VERY_HIGH_QUALITY: return true; default: @@ -190,12 +188,10 @@ AudioResampler* AudioResampler::create(int bitDepth, int inChannelCount, ALOGV("Create linear Resampler"); resampler = new AudioResamplerOrder1(bitDepth, inChannelCount, sampleRate); break; -#if 0 // disabled because it has not been qualified recently, if requested will use default: case MED_QUALITY: ALOGV("Create cubic Resampler"); resampler = new AudioResamplerCubic(bitDepth, inChannelCount, sampleRate); break; -#endif case HIGH_QUALITY: ALOGV("Create HIGH_QUALITY sinc Resampler"); resampler = new AudioResamplerSinc(bitDepth, inChannelCount, sampleRate); diff --git a/services/audioflinger/AudioResamplerSinc.cpp b/services/audioflinger/AudioResamplerSinc.cpp index 9e8447a..3f22ca6 100644 --- a/services/audioflinger/AudioResamplerSinc.cpp +++ b/services/audioflinger/AudioResamplerSinc.cpp @@ -17,13 +17,33 @@ #define LOG_TAG "AudioResamplerSinc" //#define LOG_NDEBUG 0 +#include #include -#include "AudioResamplerSinc.h" +#include #include + +#include #include -#include + #include +#include "AudioResamplerSinc.h" + + + +#if defined(__arm__) && !defined(__thumb__) +#define USE_INLINE_ASSEMBLY (true) +#else +#define USE_INLINE_ASSEMBLY (false) +#endif + +#if USE_INLINE_ASSEMBLY && defined(__ARM_NEON__) +#define USE_NEON (true) +#else +#define USE_NEON (false) +#endif + + namespace android { // ---------------------------------------------------------------------------- @@ -31,37 +51,274 @@ namespace android { /* * These coeficients are computed with the "fir" utility found in * tools/resampler_tools - * TODO: A good optimization would be to transpose this matrix, to take - * better advantage of the data-cache. + * cmd-line: fir -l 7 -s 48000 -c 20478 */ -const int32_t AudioResamplerSinc::mFirCoefsUp[] = { - 0x7fffffff, 0x7f15d078, 0x7c5e0da6, 0x77ecd867, 0x71e2e251, 0x6a6c304a, 0x61be7269, 0x58170412, 0x4db8ab05, 0x42e92ea6, 0x37eee214, 0x2d0e3bb1, 0x22879366, 0x18951e95, 0x0f693d0d, 0x072d2621, - 0x00000000, 0xf9f66655, 0xf51a5fd7, 0xf16bbd84, 0xeee0d9ac, 0xed67a922, 0xece70de6, 0xed405897, 0xee50e505, 0xeff3be30, 0xf203370f, 0xf45a6741, 0xf6d67d53, 0xf957db66, 0xfbc2f647, 0xfe00f2b9, - 0x00000000, 0x01b37218, 0x0313a0c6, 0x041d930d, 0x04d28057, 0x053731b0, 0x05534dff, 0x05309bfd, 0x04da440d, 0x045c1aee, 0x03c1fcdd, 0x03173ef5, 0x02663ae8, 0x01b7f736, 0x0113ec79, 0x007fe6a9, - 0x00000000, 0xff96b229, 0xff44f99f, 0xff0a86be, 0xfee5f803, 0xfed518fd, 0xfed521fd, 0xfee2f4fd, 0xfefb54f8, 0xff1b159b, 0xff3f4203, 0xff6539e0, 0xff8ac502, 0xffae1ddd, 0xffcdf3f9, 0xffe96798, - 0x00000000, 0x00119de6, 0x001e6b7e, 0x0026cb7a, 0x002b4830, 0x002c83d6, 0x002b2a82, 0x0027e67a, 0x002356f9, 0x001e098e, 0x001875e4, 0x0012fbbe, 0x000de2d1, 0x00095c10, 0x00058414, 0x00026636, - 0x00000000, 0xfffe44a9, 0xfffd206d, 0xfffc7b7f, 0xfffc3c8f, 0xfffc4ac2, 0xfffc8f2b, 0xfffcf5c4, 0xfffd6df3, 0xfffdeab2, 0xfffe6275, 0xfffececf, 0xffff2c07, 0xffff788c, 0xffffb471, 0xffffe0f2, - 0x00000000, 0x000013e6, 0x00001f03, 0x00002396, 0x00002399, 0x000020b6, 0x00001c3c, 0x00001722, 0x00001216, 0x00000d81, 0x0000099c, 0x0000067c, 0x00000419, 0x0000025f, 0x00000131, 0x00000070, - 0x00000000, 0xffffffc7, 0xffffffb3, 0xffffffb3, 0xffffffbe, 0xffffffcd, 0xffffffdb, 0xffffffe7, 0xfffffff0, 0xfffffff7, 0xfffffffb, 0xfffffffe, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, - 0x00000000 // this one is needed for lerping the last coefficient +const int32_t AudioResamplerSinc::mFirCoefsUp[] __attribute__ ((aligned (32))) = { + 0x6d374bc7, 0x111c6ba0, 0xf3240e61, 0x07d14a38, 0xfc509e64, 0x0139cee9, 0xffc8c866, 0xfffcc300, + 0x6d35278a, 0x103e8192, 0xf36b9dfd, 0x07bdfaa5, 0xfc5102d0, 0x013d618d, 0xffc663b9, 0xfffd9592, + 0x6d2ebafe, 0x0f62811a, 0xf3b3d8ac, 0x07a9f399, 0xfc51d9a6, 0x0140bea5, 0xffc41212, 0xfffe631e, + 0x6d24069d, 0x0e8875ad, 0xf3fcb43e, 0x07953976, 0xfc53216f, 0x0143e67c, 0xffc1d373, 0xffff2b9f, + 0x6d150b35, 0x0db06a89, 0xf4462690, 0x077fd0ac, 0xfc54d8ae, 0x0146d965, 0xffbfa7d9, 0xffffef10, + 0x6d01c9e3, 0x0cda6ab5, 0xf4902587, 0x0769bdaf, 0xfc56fdda, 0x014997bb, 0xffbd8f40, 0x0000ad6e, + 0x6cea4418, 0x0c0680fe, 0xf4daa718, 0x07530501, 0xfc598f60, 0x014c21db, 0xffbb89a1, 0x000166b6, + 0x6cce7b97, 0x0b34b7f5, 0xf525a143, 0x073bab28, 0xfc5c8ba5, 0x014e782a, 0xffb996f3, 0x00021ae5, + 0x6cae7272, 0x0a6519f4, 0xf5710a17, 0x0723b4b4, 0xfc5ff105, 0x01509b14, 0xffb7b728, 0x0002c9fd, + 0x6c8a2b0f, 0x0997b116, 0xf5bcd7b1, 0x070b2639, 0xfc63bdd3, 0x01528b08, 0xffb5ea31, 0x000373fb, + 0x6c61a823, 0x08cc873c, 0xf609003f, 0x06f20453, 0xfc67f05a, 0x0154487b, 0xffb42ffc, 0x000418e2, + 0x6c34ecb5, 0x0803a60a, 0xf6557a00, 0x06d853a2, 0xfc6c86dd, 0x0155d3e8, 0xffb28876, 0x0004b8b3, + 0x6c03fc1c, 0x073d16e7, 0xf6a23b44, 0x06be18cd, 0xfc717f97, 0x01572dcf, 0xffb0f388, 0x00055371, + 0x6bced9ff, 0x0678e2fc, 0xf6ef3a6e, 0x06a3587e, 0xfc76d8bc, 0x015856b6, 0xffaf7118, 0x0005e921, + 0x6b958a54, 0x05b71332, 0xf73c6df4, 0x06881761, 0xfc7c9079, 0x01594f25, 0xffae010b, 0x000679c5, + 0x6b581163, 0x04f7b037, 0xf789cc61, 0x066c5a27, 0xfc82a4f4, 0x015a17ab, 0xffaca344, 0x00070564, + 0x6b1673c1, 0x043ac276, 0xf7d74c53, 0x06502583, 0xfc89144d, 0x015ab0db, 0xffab57a1, 0x00078c04, + 0x6ad0b652, 0x0380521c, 0xf824e480, 0x06337e2a, 0xfc8fdc9f, 0x015b1b4e, 0xffaa1e02, 0x00080dab, + 0x6a86de48, 0x02c86715, 0xf8728bb3, 0x061668d2, 0xfc96fbfc, 0x015b579e, 0xffa8f641, 0x00088a62, + 0x6a38f123, 0x0213090c, 0xf8c038d0, 0x05f8ea30, 0xfc9e7074, 0x015b666c, 0xffa7e039, 0x00090230, + 0x69e6f4b1, 0x01603f6e, 0xf90de2d1, 0x05db06fc, 0xfca63810, 0x015b485b, 0xffa6dbc0, 0x0009751e, + 0x6990ef0b, 0x00b01162, 0xf95b80cb, 0x05bcc3ed, 0xfcae50d6, 0x015afe14, 0xffa5e8ad, 0x0009e337, + 0x6936e697, 0x000285d0, 0xf9a909ea, 0x059e25b5, 0xfcb6b8c4, 0x015a8843, 0xffa506d2, 0x000a4c85, + 0x68d8e206, 0xff57a35e, 0xf9f67577, 0x057f310a, 0xfcbf6dd8, 0x0159e796, 0xffa43603, 0x000ab112, + 0x6876e855, 0xfeaf706f, 0xfa43bad2, 0x055fea9d, 0xfcc86e09, 0x01591cc0, 0xffa3760e, 0x000b10ec, + 0x681100c9, 0xfe09f323, 0xfa90d17b, 0x0540571a, 0xfcd1b74c, 0x01582878, 0xffa2c6c2, 0x000b6c1d, + 0x67a732f4, 0xfd673159, 0xfaddb10c, 0x05207b2f, 0xfcdb4793, 0x01570b77, 0xffa227ec, 0x000bc2b3, + 0x673986ac, 0xfcc730aa, 0xfb2a513b, 0x05005b82, 0xfce51ccb, 0x0155c678, 0xffa19957, 0x000c14bb, + 0x66c80413, 0xfc29f670, 0xfb76a9dd, 0x04dffcb6, 0xfcef34e1, 0x01545a3c, 0xffa11acb, 0x000c6244, + 0x6652b392, 0xfb8f87bd, 0xfbc2b2e4, 0x04bf6369, 0xfcf98dbe, 0x0152c783, 0xffa0ac11, 0x000cab5c, + 0x65d99dd5, 0xfaf7e963, 0xfc0e6461, 0x049e9433, 0xfd04254a, 0x01510f13, 0xffa04cf0, 0x000cf012, + 0x655ccbd3, 0xfa631fef, 0xfc59b685, 0x047d93a8, 0xfd0ef969, 0x014f31b2, 0xff9ffd2c, 0x000d3075, + 0x64dc46c3, 0xf9d12fab, 0xfca4a19f, 0x045c6654, 0xfd1a0801, 0x014d3029, 0xff9fbc89, 0x000d6c97, + 0x64581823, 0xf9421c9d, 0xfcef1e20, 0x043b10bd, 0xfd254ef4, 0x014b0b45, 0xff9f8ac9, 0x000da486, + 0x63d049b4, 0xf8b5ea87, 0xfd392498, 0x04199760, 0xfd30cc24, 0x0148c3d2, 0xff9f67ae, 0x000dd854, + 0x6344e578, 0xf82c9ce7, 0xfd82adba, 0x03f7feb4, 0xfd3c7d73, 0x01465a9f, 0xff9f52f7, 0x000e0812, + 0x62b5f5b2, 0xf7a636fa, 0xfdcbb25a, 0x03d64b27, 0xfd4860c2, 0x0143d07f, 0xff9f4c65, 0x000e33d3, + 0x622384e8, 0xf722bbb5, 0xfe142b6e, 0x03b4811d, 0xfd5473f3, 0x01412643, 0xff9f53b4, 0x000e5ba7, + 0x618d9ddc, 0xf6a22dcf, 0xfe5c120f, 0x0392a4f4, 0xfd60b4e7, 0x013e5cc0, 0xff9f68a1, 0x000e7fa1, + 0x60f44b91, 0xf6248fb6, 0xfea35f79, 0x0370bafc, 0xfd6d2180, 0x013b74ca, 0xff9f8ae9, 0x000e9fd5, + 0x60579947, 0xf5a9e398, 0xfeea0d0c, 0x034ec77f, 0xfd79b7a1, 0x01386f3a, 0xff9fba47, 0x000ebc54, + 0x5fb79278, 0xf5322b61, 0xff30144a, 0x032ccebb, 0xfd86752e, 0x01354ce7, 0xff9ff674, 0x000ed533, + 0x5f1442dc, 0xf4bd68b6, 0xff756edc, 0x030ad4e1, 0xfd93580d, 0x01320ea9, 0xffa03f2b, 0x000eea84, + 0x5e6db665, 0xf44b9cfe, 0xffba168d, 0x02e8de19, 0xfda05e23, 0x012eb55a, 0xffa09425, 0x000efc5c, + 0x5dc3f93c, 0xf3dcc959, 0xfffe054e, 0x02c6ee7f, 0xfdad855b, 0x012b41d3, 0xffa0f519, 0x000f0ace, + 0x5d1717c4, 0xf370eea9, 0x00413536, 0x02a50a22, 0xfdbacb9e, 0x0127b4f1, 0xffa161bf, 0x000f15ef, + 0x5c671e96, 0xf3080d8c, 0x0083a081, 0x02833506, 0xfdc82edb, 0x01240f8e, 0xffa1d9cf, 0x000f1dd2, + 0x5bb41a80, 0xf2a2265e, 0x00c54190, 0x02617321, 0xfdd5ad01, 0x01205285, 0xffa25cfe, 0x000f228d, + 0x5afe1886, 0xf23f393b, 0x010612eb, 0x023fc85c, 0xfde34403, 0x011c7eb2, 0xffa2eb04, 0x000f2434, + 0x5a4525df, 0xf1df45fd, 0x01460f41, 0x021e3891, 0xfdf0f1d6, 0x011894f0, 0xffa38395, 0x000f22dc, + 0x59894ff3, 0xf1824c3e, 0x01853165, 0x01fcc78f, 0xfdfeb475, 0x0114961b, 0xffa42668, 0x000f1e99, + 0x58caa45b, 0xf1284b58, 0x01c37452, 0x01db7914, 0xfe0c89db, 0x0110830f, 0xffa4d332, 0x000f1781, + 0x580930e1, 0xf0d14267, 0x0200d32c, 0x01ba50d2, 0xfe1a7009, 0x010c5ca6, 0xffa589a6, 0x000f0da8, + 0x5745037c, 0xf07d3043, 0x023d493c, 0x0199526b, 0xfe286505, 0x010823ba, 0xffa6497c, 0x000f0125, + 0x567e2a51, 0xf02c138a, 0x0278d1f2, 0x01788170, 0xfe3666d5, 0x0103d927, 0xffa71266, 0x000ef20b, + 0x55b4b3af, 0xefddea9a, 0x02b368e6, 0x0157e166, 0xfe447389, 0x00ff7dc4, 0xffa7e41a, 0x000ee070, + 0x54e8ae13, 0xef92b393, 0x02ed09d7, 0x013775bf, 0xfe528931, 0x00fb126b, 0xffa8be4c, 0x000ecc69, + 0x541a281e, 0xef4a6c58, 0x0325b0ad, 0x011741df, 0xfe60a5e5, 0x00f697f3, 0xffa9a0b1, 0x000eb60b, + 0x5349309e, 0xef051290, 0x035d5977, 0x00f7491a, 0xfe6ec7c0, 0x00f20f32, 0xffaa8afe, 0x000e9d6b, + 0x5275d684, 0xeec2a3a3, 0x0394006a, 0x00d78eb3, 0xfe7cece2, 0x00ed78ff, 0xffab7ce7, 0x000e829e, + 0x51a028e8, 0xee831cc3, 0x03c9a1e5, 0x00b815da, 0xfe8b1373, 0x00e8d62d, 0xffac7621, 0x000e65ba, + 0x50c83704, 0xee467ae1, 0x03fe3a6f, 0x0098e1b3, 0xfe99399f, 0x00e4278f, 0xffad7662, 0x000e46d3, + 0x4fee1037, 0xee0cbab9, 0x0431c6b5, 0x0079f54c, 0xfea75d97, 0x00df6df7, 0xffae7d5f, 0x000e25fd, + 0x4f11c3fe, 0xedd5d8ca, 0x0464438c, 0x005b53a4, 0xfeb57d92, 0x00daaa34, 0xffaf8acd, 0x000e034f, + 0x4e3361f7, 0xeda1d15c, 0x0495adf2, 0x003cffa9, 0xfec397cf, 0x00d5dd16, 0xffb09e63, 0x000ddedb, + 0x4d52f9df, 0xed70a07d, 0x04c6030d, 0x001efc35, 0xfed1aa92, 0x00d10769, 0xffb1b7d8, 0x000db8b7, + 0x4c709b8e, 0xed424205, 0x04f54029, 0x00014c12, 0xfedfb425, 0x00cc29f7, 0xffb2d6e1, 0x000d90f6, + 0x4b8c56f8, 0xed16b196, 0x052362ba, 0xffe3f1f7, 0xfeedb2da, 0x00c7458a, 0xffb3fb37, 0x000d67ae, + 0x4aa63c2c, 0xecedea99, 0x0550685d, 0xffc6f08a, 0xfefba508, 0x00c25ae8, 0xffb52490, 0x000d3cf1, + 0x49be5b50, 0xecc7e845, 0x057c4ed4, 0xffaa4a5d, 0xff09890f, 0x00bd6ad7, 0xffb652a7, 0x000d10d5, + 0x48d4c4a2, 0xeca4a59b, 0x05a7140b, 0xff8e01f1, 0xff175d53, 0x00b87619, 0xffb78533, 0x000ce36b, + 0x47e98874, 0xec841d68, 0x05d0b612, 0xff7219b3, 0xff252042, 0x00b37d70, 0xffb8bbed, 0x000cb4c8, + 0x46fcb72d, 0xec664a48, 0x05f93324, 0xff5693fe, 0xff32d04f, 0x00ae8198, 0xffb9f691, 0x000c84ff, + 0x460e6148, 0xec4b26a2, 0x0620899e, 0xff3b731b, 0xff406bf8, 0x00a9834e, 0xffbb34d8, 0x000c5422, + 0x451e9750, 0xec32acb0, 0x0646b808, 0xff20b93e, 0xff4df1be, 0x00a4834c, 0xffbc767f, 0x000c2245, + 0x442d69de, 0xec1cd677, 0x066bbd0d, 0xff066889, 0xff5b602c, 0x009f8249, 0xffbdbb42, 0x000bef79, + 0x433ae99c, 0xec099dcf, 0x068f9781, 0xfeec830d, 0xff68b5d5, 0x009a80f8, 0xffbf02dd, 0x000bbbd2, + 0x4247273f, 0xebf8fc64, 0x06b2465b, 0xfed30ac5, 0xff75f153, 0x0095800c, 0xffc04d0f, 0x000b8760, + 0x41523389, 0xebeaebaf, 0x06d3c8bb, 0xfeba0199, 0xff831148, 0x00908034, 0xffc19996, 0x000b5235, + 0x405c1f43, 0xebdf6500, 0x06f41de3, 0xfea16960, 0xff90145e, 0x008b821b, 0xffc2e832, 0x000b1c64, + 0x3f64fb40, 0xebd6617b, 0x0713453d, 0xfe8943dc, 0xff9cf947, 0x0086866b, 0xffc438a3, 0x000ae5fc, + 0x3e6cd85b, 0xebcfda19, 0x07313e56, 0xfe7192bd, 0xffa9bebe, 0x00818dcb, 0xffc58aaa, 0x000aaf0f, + 0x3d73c772, 0xebcbc7a7, 0x074e08e0, 0xfe5a579d, 0xffb66386, 0x007c98de, 0xffc6de09, 0x000a77ac, + 0x3c79d968, 0xebca22cc, 0x0769a4b2, 0xfe439407, 0xffc2e669, 0x0077a845, 0xffc83285, 0x000a3fe5, + 0x3b7f1f23, 0xebcae405, 0x078411c7, 0xfe2d496f, 0xffcf463a, 0x0072bc9d, 0xffc987e0, 0x000a07c9, + 0x3a83a989, 0xebce03aa, 0x079d503b, 0xfe177937, 0xffdb81d6, 0x006dd680, 0xffcadde1, 0x0009cf67, + 0x3987897f, 0xebd379eb, 0x07b56051, 0xfe0224b0, 0xffe79820, 0x0068f687, 0xffcc344c, 0x000996ce, + 0x388acfe9, 0xebdb3ed5, 0x07cc426c, 0xfded4d13, 0xfff38806, 0x00641d44, 0xffcd8aeb, 0x00095e0e, + 0x378d8da8, 0xebe54a4f, 0x07e1f712, 0xfdd8f38b, 0xffff507b, 0x005f4b4a, 0xffcee183, 0x00092535, + 0x368fd397, 0xebf1941f, 0x07f67eec, 0xfdc5192d, 0x000af07f, 0x005a8125, 0xffd037e0, 0x0008ec50, + 0x3591b28b, 0xec0013e8, 0x0809dac3, 0xfdb1befc, 0x00166718, 0x0055bf60, 0xffd18dcc, 0x0008b36e, + 0x34933b50, 0xec10c12c, 0x081c0b84, 0xfd9ee5e7, 0x0021b355, 0x00510682, 0xffd2e311, 0x00087a9c, + 0x33947eab, 0xec23934f, 0x082d1239, 0xfd8c8ecc, 0x002cd44d, 0x004c570f, 0xffd4377d, 0x000841e8, + 0x32958d55, 0xec388194, 0x083cf010, 0xfd7aba74, 0x0037c922, 0x0047b186, 0xffd58ade, 0x0008095d, + 0x319677fa, 0xec4f8322, 0x084ba654, 0xfd696998, 0x004290fc, 0x00431666, 0xffd6dd02, 0x0007d108, + 0x30974f3b, 0xec688f02, 0x08593671, 0xfd589cdc, 0x004d2b0e, 0x003e8628, 0xffd82dba, 0x000798f5, + 0x2f9823a8, 0xec839c22, 0x0865a1f1, 0xfd4854d3, 0x00579691, 0x003a0141, 0xffd97cd6, 0x00076130, + 0x2e9905c1, 0xeca0a156, 0x0870ea7e, 0xfd3891fd, 0x0061d2ca, 0x00358824, 0xffdaca2a, 0x000729c4, + 0x2d9a05f4, 0xecbf9558, 0x087b11de, 0xfd2954c8, 0x006bdf05, 0x00311b41, 0xffdc1588, 0x0006f2bb, + 0x2c9b349e, 0xece06ecb, 0x088419f6, 0xfd1a9d91, 0x0075ba95, 0x002cbb03, 0xffdd5ec6, 0x0006bc21, + 0x2b9ca203, 0xed032439, 0x088c04c8, 0xfd0c6ca2, 0x007f64da, 0x002867d2, 0xffdea5bb, 0x000685ff, + 0x2a9e5e57, 0xed27ac16, 0x0892d470, 0xfcfec233, 0x0088dd38, 0x00242213, 0xffdfea3c, 0x0006505f, + 0x29a079b2, 0xed4dfcc2, 0x08988b2a, 0xfcf19e6b, 0x0092231e, 0x001fea27, 0xffe12c22, 0x00061b4b, + 0x28a30416, 0xed760c88, 0x089d2b4a, 0xfce50161, 0x009b3605, 0x001bc06b, 0xffe26b48, 0x0005e6cb, + 0x27a60d6a, 0xed9fd1a2, 0x08a0b740, 0xfcd8eb17, 0x00a4156b, 0x0017a53b, 0xffe3a788, 0x0005b2e8, + 0x26a9a57b, 0xedcb4237, 0x08a33196, 0xfccd5b82, 0x00acc0da, 0x001398ec, 0xffe4e0bf, 0x00057faa, + 0x25addbf9, 0xedf8545b, 0x08a49cf0, 0xfcc25285, 0x00b537e1, 0x000f9bd2, 0xffe616c8, 0x00054d1a, + 0x24b2c075, 0xee26fe17, 0x08a4fc0d, 0xfcb7cff0, 0x00bd7a1c, 0x000bae3c, 0xffe74984, 0x00051b3e, + 0x23b86263, 0xee573562, 0x08a451c0, 0xfcadd386, 0x00c5872a, 0x0007d075, 0xffe878d3, 0x0004ea1d, + 0x22bed116, 0xee88f026, 0x08a2a0f8, 0xfca45cf7, 0x00cd5eb7, 0x000402c8, 0xffe9a494, 0x0004b9c0, + 0x21c61bc0, 0xeebc2444, 0x089fecbb, 0xfc9b6be5, 0x00d50075, 0x00004579, 0xffeaccaa, 0x00048a2b, + 0x20ce516f, 0xeef0c78d, 0x089c3824, 0xfc92ffe1, 0x00dc6c1e, 0xfffc98c9, 0xffebf0fa, 0x00045b65, + 0x1fd7810f, 0xef26cfca, 0x08978666, 0xfc8b186d, 0x00e3a175, 0xfff8fcf7, 0xffed1166, 0x00042d74, + 0x1ee1b965, 0xef5e32bd, 0x0891dac8, 0xfc83b4fc, 0x00eaa045, 0xfff5723d, 0xffee2dd7, 0x0004005e, + 0x1ded0911, 0xef96e61c, 0x088b38a9, 0xfc7cd4f0, 0x00f16861, 0xfff1f8d2, 0xffef4632, 0x0003d426, + 0x1cf97e8b, 0xefd0df9a, 0x0883a378, 0xfc76779e, 0x00f7f9a3, 0xffee90eb, 0xfff05a60, 0x0003a8d2, + 0x1c072823, 0xf00c14e1, 0x087b1ebc, 0xfc709c4d, 0x00fe53ef, 0xffeb3ab8, 0xfff16a4a, 0x00037e65, + 0x1b1613ff, 0xf0487b98, 0x0871ae0d, 0xfc6b4233, 0x0104772e, 0xffe7f666, 0xfff275db, 0x000354e5, + 0x1a26501b, 0xf0860962, 0x08675516, 0xfc66687a, 0x010a6353, 0xffe4c41e, 0xfff37d00, 0x00032c54, + 0x1937ea47, 0xf0c4b3e0, 0x085c1794, 0xfc620e3d, 0x01101858, 0xffe1a408, 0xfff47fa5, 0x000304b7, + 0x184af025, 0xf10470b0, 0x084ff957, 0xfc5e328c, 0x0115963d, 0xffde9646, 0xfff57db8, 0x0002de0e, + 0x175f6f2b, 0xf1453571, 0x0842fe3d, 0xfc5ad465, 0x011add0b, 0xffdb9af8, 0xfff67729, 0x0002b85f, + 0x1675749e, 0xf186f7c0, 0x08352a35, 0xfc57f2be, 0x011fecd3, 0xffd8b23b, 0xfff76be9, 0x000293aa, + 0x158d0d95, 0xf1c9ad40, 0x0826813e, 0xfc558c7c, 0x0124c5ab, 0xffd5dc28, 0xfff85be8, 0x00026ff2, + 0x14a646f6, 0xf20d4b92, 0x08170767, 0xfc53a07b, 0x012967b1, 0xffd318d6, 0xfff9471b, 0x00024d39, + 0x13c12d73, 0xf251c85d, 0x0806c0cb, 0xfc522d88, 0x012dd30a, 0xffd06858, 0xfffa2d74, 0x00022b7f, + 0x12ddcd8f, 0xf297194d, 0x07f5b193, 0xfc513266, 0x013207e4, 0xffcdcabe, 0xfffb0ee9, 0x00020ac7, + 0x11fc3395, 0xf2dd3411, 0x07e3ddf7, 0xfc50adcc, 0x01360670, 0xffcb4014, 0xfffbeb70, 0x0001eb10, + 0x111c6ba0, 0xf3240e61, 0x07d14a38, 0xfc509e64, 0x0139cee9, 0xffc8c866, 0xfffcc300, 0x0001cc5c, }; /* - * These coefficients are optimized for 48KHz -> 44.1KHz (stop-band at 22.050KHz) - * It's possible to use the above coefficient for any down-sampling - * at the expense of a slower processing loop (we can interpolate - * these coefficient from the above by "Stretching" them in time). + * These coefficients are optimized for 48KHz -> 44.1KHz + * cmd-line: fir -l 7 -s 48000 -c 17189 */ -const int32_t AudioResamplerSinc::mFirCoefsDown[] = { - 0x7fffffff, 0x7f55e46d, 0x7d5b4c60, 0x7a1b4b98, 0x75a7fb14, 0x7019f0bd, 0x698f875a, 0x622bfd59, 0x5a167256, 0x5178cc54, 0x487e8e6c, 0x3f53aae8, 0x36235ad4, 0x2d17047b, 0x245539ab, 0x1c00d540, - 0x14383e57, 0x0d14d5ca, 0x06aa910b, 0x0107c38b, 0xfc351654, 0xf835abae, 0xf5076b45, 0xf2a37202, 0xf0fe9faa, 0xf00a3bbd, 0xefb4aa81, 0xefea2b05, 0xf0959716, 0xf1a11e83, 0xf2f6f7a0, 0xf481fff4, - 0xf62e48ce, 0xf7e98ca5, 0xf9a38b4c, 0xfb4e4bfa, 0xfcde456f, 0xfe4a6d30, 0xff8c2fdf, 0x009f5555, 0x0181d393, 0x0233940f, 0x02b62f06, 0x030ca07d, 0x033afa62, 0x03461725, 0x03334f83, 0x030835fa, - 0x02ca59cc, 0x027f12d1, 0x022b570d, 0x01d39a49, 0x017bb78f, 0x0126e414, 0x00d7aaaf, 0x008feec7, 0x0050f584, 0x001b73e3, 0xffefa063, 0xffcd46ed, 0xffb3ddcd, 0xffa29aaa, 0xff988691, 0xff949066, - 0xff959d24, 0xff9a959e, 0xffa27195, 0xffac4011, 0xffb72d2b, 0xffc28569, 0xffcdb706, 0xffd85171, 0xffe20364, 0xffea97e9, 0xfff1f2b2, 0xfff80c06, 0xfffcec92, 0x0000a955, 0x00035fd8, 0x000532cf, - 0x00064735, 0x0006c1f9, 0x0006c62d, 0x000673ba, 0x0005e68f, 0x00053630, 0x000475a3, 0x0003b397, 0x0002fac1, 0x00025257, 0x0001be9e, 0x0001417a, 0x0000dafd, 0x000089eb, 0x00004c28, 0x00001f1d, - 0x00000000, 0xffffec10, 0xffffe0be, 0xffffdbc5, 0xffffdb39, 0xffffdd8b, 0xffffe182, 0xffffe638, 0xffffeb0a, 0xffffef8f, 0xfffff38b, 0xfffff6e3, 0xfffff993, 0xfffffba6, 0xfffffd30, 0xfffffe4a, - 0xffffff09, 0xffffff85, 0xffffffd1, 0xfffffffb, 0x0000000f, 0x00000016, 0x00000015, 0x00000012, 0x0000000d, 0x00000009, 0x00000006, 0x00000003, 0x00000002, 0x00000001, 0x00000000, 0x00000000, - 0x00000000 // this one is needed for lerping the last coefficient +const int32_t AudioResamplerSinc::mFirCoefsDown[] __attribute__ ((aligned (32))) = { + 0x5bacb6f4, 0x1ded1a1d, 0xf0398d56, 0x0394f674, 0x0193a5f9, 0xfe66dbeb, 0x00791043, 0xfffe6631, + 0x5bab6c81, 0x1d3ddccd, 0xf0421d2c, 0x03af9995, 0x01818dc9, 0xfe6bb63e, 0x0079812a, 0xfffdc37d, + 0x5ba78d37, 0x1c8f2cf9, 0xf04beb1d, 0x03c9a04a, 0x016f8aca, 0xfe70a511, 0x0079e34d, 0xfffd2545, + 0x5ba1194f, 0x1be11231, 0xf056f2c7, 0x03e309fe, 0x015d9e64, 0xfe75a79f, 0x007a36e2, 0xfffc8b86, + 0x5b981122, 0x1b3393f8, 0xf0632fb7, 0x03fbd625, 0x014bc9fa, 0xfe7abd23, 0x007a7c20, 0xfffbf639, + 0x5b8c7530, 0x1a86b9bf, 0xf0709d74, 0x04140449, 0x013a0ee9, 0xfe7fe4db, 0x007ab33d, 0xfffb655b, + 0x5b7e461a, 0x19da8ae5, 0xf07f3776, 0x042b93fd, 0x01286e86, 0xfe851e05, 0x007adc72, 0xfffad8e4, + 0x5b6d84a8, 0x192f0eb7, 0xf08ef92d, 0x044284e6, 0x0116ea22, 0xfe8a67dd, 0x007af7f6, 0xfffa50ce, + 0x5b5a31c6, 0x18844c70, 0xf09fddfe, 0x0458d6b7, 0x01058306, 0xfe8fc1a5, 0x007b0603, 0xfff9cd12, + 0x5b444e81, 0x17da4b37, 0xf0b1e143, 0x046e8933, 0x00f43a74, 0xfe952a9b, 0x007b06d4, 0xfff94da9, + 0x5b2bdc0e, 0x17311222, 0xf0c4fe50, 0x04839c29, 0x00e311a9, 0xfe9aa201, 0x007afaa1, 0xfff8d28c, + 0x5b10dbc2, 0x1688a832, 0xf0d9306d, 0x04980f79, 0x00d209db, 0xfea02719, 0x007ae1a7, 0xfff85bb1, + 0x5af34f18, 0x15e11453, 0xf0ee72db, 0x04abe310, 0x00c12439, 0xfea5b926, 0x007abc20, 0xfff7e910, + 0x5ad337af, 0x153a5d5e, 0xf104c0d2, 0x04bf16e9, 0x00b061eb, 0xfeab576d, 0x007a8a49, 0xfff77a9f, + 0x5ab09748, 0x14948a16, 0xf11c1583, 0x04d1ab0d, 0x009fc413, 0xfeb10134, 0x007a4c5d, 0xfff71057, + 0x5a8b6fc7, 0x13efa12c, 0xf1346c17, 0x04e39f93, 0x008f4bcb, 0xfeb6b5c0, 0x007a029a, 0xfff6aa2b, + 0x5a63c336, 0x134ba937, 0xf14dbfb1, 0x04f4f4a2, 0x007efa29, 0xfebc745c, 0x0079ad3d, 0xfff64812, + 0x5a3993c0, 0x12a8a8bb, 0xf1680b6e, 0x0505aa6a, 0x006ed038, 0xfec23c50, 0x00794c82, 0xfff5ea02, + 0x5a0ce3b2, 0x1206a625, 0xf1834a63, 0x0515c12d, 0x005ecf01, 0xfec80ce8, 0x0078e0a9, 0xfff58ff0, + 0x59ddb57f, 0x1165a7cc, 0xf19f77a0, 0x05253938, 0x004ef782, 0xfecde571, 0x007869ee, 0xfff539cf, + 0x59ac0bba, 0x10c5b3ef, 0xf1bc8e31, 0x053412e4, 0x003f4ab4, 0xfed3c538, 0x0077e891, 0xfff4e794, + 0x5977e919, 0x1026d0b8, 0xf1da891b, 0x05424e9b, 0x002fc98a, 0xfed9ab8f, 0x00775ccf, 0xfff49934, + 0x59415075, 0x0f890437, 0xf1f96360, 0x054feccf, 0x002074ed, 0xfedf97c6, 0x0076c6e8, 0xfff44ea3, + 0x590844c9, 0x0eec5465, 0xf21917ff, 0x055cee03, 0x00114dc3, 0xfee58932, 0x00762719, 0xfff407d2, + 0x58ccc930, 0x0e50c723, 0xf239a1ef, 0x056952c3, 0x000254e8, 0xfeeb7f27, 0x00757da3, 0xfff3c4b7, + 0x588ee0ea, 0x0db6623b, 0xf25afc29, 0x05751baa, 0xfff38b32, 0xfef178fc, 0x0074cac4, 0xfff38542, + 0x584e8f56, 0x0d1d2b5d, 0xf27d219f, 0x0580495c, 0xffe4f171, 0xfef7760c, 0x00740ebb, 0xfff34968, + 0x580bd7f4, 0x0c85281f, 0xf2a00d43, 0x058adc8d, 0xffd6886d, 0xfefd75af, 0x007349c7, 0xfff3111b, + 0x57c6be67, 0x0bee5dff, 0xf2c3ba04, 0x0594d5fa, 0xffc850e6, 0xff037744, 0x00727c27, 0xfff2dc4c, + 0x577f4670, 0x0b58d262, 0xf2e822ce, 0x059e366c, 0xffba4b98, 0xff097a29, 0x0071a61b, 0xfff2aaef, + 0x573573f2, 0x0ac48a92, 0xf30d428e, 0x05a6feb9, 0xffac7936, 0xff0f7dbf, 0x0070c7e1, 0xfff27cf3, + 0x56e94af1, 0x0a318bc1, 0xf333142f, 0x05af2fbf, 0xff9eda6d, 0xff15816a, 0x006fe1b8, 0xfff2524c, + 0x569acf90, 0x099fdb04, 0xf359929a, 0x05b6ca6b, 0xff916fe1, 0xff1b848e, 0x006ef3df, 0xfff22aea, + 0x564a0610, 0x090f7d57, 0xf380b8ba, 0x05bdcfb2, 0xff843a32, 0xff218692, 0x006dfe94, 0xfff206bf, + 0x55f6f2d3, 0x0880779d, 0xf3a88179, 0x05c44095, 0xff7739f7, 0xff2786e1, 0x006d0217, 0xfff1e5bb, + 0x55a19a5c, 0x07f2ce9b, 0xf3d0e7c2, 0x05ca1e1f, 0xff6a6fc1, 0xff2d84e5, 0x006bfea4, 0xfff1c7d0, + 0x554a0148, 0x076686fc, 0xf3f9e680, 0x05cf6965, 0xff5ddc1a, 0xff33800e, 0x006af47b, 0xfff1acef, + 0x54f02c56, 0x06dba551, 0xf42378a0, 0x05d42387, 0xff517f86, 0xff3977cb, 0x0069e3d9, 0xfff19508, + 0x54942061, 0x06522e0f, 0xf44d9912, 0x05d84daf, 0xff455a80, 0xff3f6b8f, 0x0068ccfa, 0xfff1800b, + 0x5435e263, 0x05ca258f, 0xf47842c5, 0x05dbe90f, 0xff396d7f, 0xff455acf, 0x0067b01e, 0xfff16de9, + 0x53d57774, 0x0543900d, 0xf4a370ad, 0x05def6e4, 0xff2db8f2, 0xff4b4503, 0x00668d80, 0xfff15e93, + 0x5372e4c6, 0x04be71ab, 0xf4cf1dbf, 0x05e17873, 0xff223d40, 0xff5129a3, 0x0065655d, 0xfff151f9, + 0x530e2fac, 0x043ace6e, 0xf4fb44f4, 0x05e36f0d, 0xff16faca, 0xff57082e, 0x006437f1, 0xfff1480b, + 0x52a75d90, 0x03b8aa40, 0xf527e149, 0x05e4dc08, 0xff0bf1ed, 0xff5ce021, 0x00630577, 0xfff140b9, + 0x523e73fd, 0x033808eb, 0xf554edbd, 0x05e5c0c6, 0xff0122fc, 0xff62b0fd, 0x0061ce2c, 0xfff13bf3, + 0x51d37897, 0x02b8ee22, 0xf5826555, 0x05e61eae, 0xfef68e45, 0xff687a47, 0x00609249, 0xfff139aa, + 0x5166711c, 0x023b5d76, 0xf5b0431a, 0x05e5f733, 0xfeec340f, 0xff6e3b84, 0x005f520a, 0xfff139cd, + 0x50f76368, 0x01bf5a5e, 0xf5de8218, 0x05e54bcd, 0xfee2149b, 0xff73f43d, 0x005e0da8, 0xfff13c4c, + 0x5086556f, 0x0144e834, 0xf60d1d63, 0x05e41dfe, 0xfed83023, 0xff79a3fe, 0x005cc55c, 0xfff14119, + 0x50134d3e, 0x00cc0a36, 0xf63c1012, 0x05e26f4e, 0xfece86db, 0xff7f4a54, 0x005b7961, 0xfff14821, + 0x4f9e50ff, 0x0054c382, 0xf66b5544, 0x05e0414d, 0xfec518f1, 0xff84e6d0, 0x005a29ed, 0xfff15156, + 0x4f2766f2, 0xffdf171b, 0xf69ae81d, 0x05dd9593, 0xfebbe68c, 0xff8a7905, 0x0058d738, 0xfff15ca8, + 0x4eae9571, 0xff6b07e7, 0xf6cac3c7, 0x05da6dbe, 0xfeb2efcd, 0xff900089, 0x0057817b, 0xfff16a07, + 0x4e33e2ee, 0xfef898ae, 0xf6fae373, 0x05d6cb72, 0xfeaa34d0, 0xff957cf4, 0x005628ec, 0xfff17962, + 0x4db755f3, 0xfe87cc1b, 0xf72b425b, 0x05d2b05c, 0xfea1b5a9, 0xff9aede0, 0x0054cdc0, 0xfff18aab, + 0x4d38f520, 0xfe18a4bc, 0xf75bdbbd, 0x05ce1e2d, 0xfe997268, 0xffa052ec, 0x0053702d, 0xfff19dd1, + 0x4cb8c72e, 0xfdab2501, 0xf78caae0, 0x05c9169d, 0xfe916b15, 0xffa5abb8, 0x00521068, 0xfff1b2c5, + 0x4c36d2eb, 0xfd3f4f3d, 0xf7bdab16, 0x05c39b6a, 0xfe899fb2, 0xffaaf7e6, 0x0050aea5, 0xfff1c976, + 0x4bb31f3c, 0xfcd525a5, 0xf7eed7b4, 0x05bdae57, 0xfe82103f, 0xffb0371c, 0x004f4b17, 0xfff1e1d6, + 0x4b2db31a, 0xfc6caa53, 0xf8202c1c, 0x05b7512e, 0xfe7abcb1, 0xffb56902, 0x004de5f1, 0xfff1fbd5, + 0x4aa69594, 0xfc05df40, 0xf851a3b6, 0x05b085bc, 0xfe73a4fb, 0xffba8d44, 0x004c7f66, 0xfff21764, + 0x4a1dcdce, 0xfba0c64b, 0xf88339f5, 0x05a94dd5, 0xfe6cc909, 0xffbfa38d, 0x004b17a6, 0xfff23473, + 0x499362ff, 0xfb3d6133, 0xf8b4ea55, 0x05a1ab52, 0xfe6628c1, 0xffc4ab8f, 0x0049aee3, 0xfff252f3, + 0x49075c72, 0xfadbb19a, 0xf8e6b059, 0x0599a00e, 0xfe5fc405, 0xffc9a4fc, 0x0048454b, 0xfff272d6, + 0x4879c185, 0xfa7bb908, 0xf9188793, 0x05912dea, 0xfe599aaf, 0xffce8f8a, 0x0046db0f, 0xfff2940b, + 0x47ea99a9, 0xfa1d78e3, 0xf94a6b9b, 0x058856cd, 0xfe53ac97, 0xffd36af1, 0x0045705c, 0xfff2b686, + 0x4759ec60, 0xf9c0f276, 0xf97c5815, 0x057f1c9e, 0xfe4df98e, 0xffd836eb, 0x00440561, 0xfff2da36, + 0x46c7c140, 0xf96626f0, 0xf9ae48af, 0x0575814c, 0xfe48815e, 0xffdcf336, 0x00429a4a, 0xfff2ff0d, + 0x46341fed, 0xf90d1761, 0xf9e03924, 0x056b86c6, 0xfe4343d0, 0xffe19f91, 0x00412f43, 0xfff324fd, + 0x459f101d, 0xf8b5c4be, 0xfa122537, 0x05612f00, 0xfe3e40a6, 0xffe63bc0, 0x003fc478, 0xfff34bf9, + 0x45089996, 0xf8602fdc, 0xfa4408ba, 0x05567bf1, 0xfe39779a, 0xffeac787, 0x003e5a12, 0xfff373f0, + 0x4470c42d, 0xf80c5977, 0xfa75df87, 0x054b6f92, 0xfe34e867, 0xffef42af, 0x003cf03d, 0xfff39cd7, + 0x43d797c7, 0xf7ba422b, 0xfaa7a586, 0x05400be1, 0xfe3092bf, 0xfff3ad01, 0x003b871f, 0xfff3c69f, + 0x433d1c56, 0xf769ea78, 0xfad956ab, 0x053452dc, 0xfe2c7650, 0xfff8064b, 0x003a1ee3, 0xfff3f13a, + 0x42a159dc, 0xf71b52c4, 0xfb0aeef6, 0x05284685, 0xfe2892c5, 0xfffc4e5c, 0x0038b7ae, 0xfff41c9c, + 0x42045865, 0xf6ce7b57, 0xfb3c6a73, 0x051be8dd, 0xfe24e7c3, 0x00008507, 0x003751a7, 0xfff448b7, + 0x4166200e, 0xf683645a, 0xfb6dc53c, 0x050f3bec, 0xfe2174ec, 0x0004aa1f, 0x0035ecf4, 0xfff4757e, + 0x40c6b8fd, 0xf63a0ddf, 0xfb9efb77, 0x050241b6, 0xfe1e39da, 0x0008bd7c, 0x003489b9, 0xfff4a2e5, + 0x40262b65, 0xf5f277d9, 0xfbd00956, 0x04f4fc46, 0xfe1b3628, 0x000cbef7, 0x0033281a, 0xfff4d0de, + 0x3f847f83, 0xf5aca21f, 0xfc00eb1b, 0x04e76da3, 0xfe18696a, 0x0010ae6e, 0x0031c83a, 0xfff4ff5d, + 0x3ee1bda2, 0xf5688c6d, 0xfc319d13, 0x04d997d8, 0xfe15d32f, 0x00148bbd, 0x00306a3b, 0xfff52e57, + 0x3e3dee13, 0xf5263665, 0xfc621b9a, 0x04cb7cf2, 0xfe137304, 0x001856c7, 0x002f0e3f, 0xfff55dbf, + 0x3d991932, 0xf4e59f8a, 0xfc926319, 0x04bd1efb, 0xfe114872, 0x001c0f6e, 0x002db466, 0xfff58d89, + 0x3cf34766, 0xf4a6c748, 0xfcc27008, 0x04ae8000, 0xfe0f52fc, 0x001fb599, 0x002c5cd0, 0xfff5bdaa, + 0x3c4c811c, 0xf469aced, 0xfcf23eec, 0x049fa20f, 0xfe0d9224, 0x0023492f, 0x002b079a, 0xfff5ee17, + 0x3ba4cec9, 0xf42e4faf, 0xfd21cc59, 0x04908733, 0xfe0c0567, 0x0026ca1c, 0x0029b4e4, 0xfff61ec5, + 0x3afc38eb, 0xf3f4aea6, 0xfd5114f0, 0x0481317a, 0xfe0aac3f, 0x002a384c, 0x002864c9, 0xfff64fa8, + 0x3a52c805, 0xf3bcc8d3, 0xfd801564, 0x0471a2ef, 0xfe098622, 0x002d93ae, 0x00271766, 0xfff680b5, + 0x39a884a1, 0xf3869d1a, 0xfdaeca73, 0x0461dda0, 0xfe089283, 0x0030dc34, 0x0025ccd7, 0xfff6b1e4, + 0x38fd774e, 0xf3522a49, 0xfddd30eb, 0x0451e396, 0xfe07d0d3, 0x003411d2, 0x00248535, 0xfff6e329, + 0x3851a8a2, 0xf31f6f0f, 0xfe0b45aa, 0x0441b6dd, 0xfe07407d, 0x0037347d, 0x0023409a, 0xfff7147a, + 0x37a52135, 0xf2ee6a07, 0xfe39059b, 0x0431597d, 0xfe06e0eb, 0x003a442e, 0x0021ff1f, 0xfff745cd, + 0x36f7e9a4, 0xf2bf19ae, 0xfe666dbc, 0x0420cd80, 0xfe06b184, 0x003d40e0, 0x0020c0dc, 0xfff7771a, + 0x364a0a90, 0xf2917c6d, 0xfe937b15, 0x041014eb, 0xfe06b1ac, 0x00402a8e, 0x001f85e6, 0xfff7a857, + 0x359b8c9d, 0xf265908f, 0xfec02ac2, 0x03ff31c3, 0xfe06e0c4, 0x00430137, 0x001e4e56, 0xfff7d97a, + 0x34ec786f, 0xf23b544b, 0xfeec79ec, 0x03ee260d, 0xfe073e2a, 0x0045c4dd, 0x001d1a3f, 0xfff80a7c, + 0x343cd6af, 0xf212c5be, 0xff1865cd, 0x03dcf3ca, 0xfe07c93a, 0x00487582, 0x001be9b7, 0xfff83b52, + 0x338cb004, 0xf1ebe2ec, 0xff43ebac, 0x03cb9cf9, 0xfe08814e, 0x004b132b, 0x001abcd0, 0xfff86bf6, + 0x32dc0d17, 0xf1c6a9c3, 0xff6f08e4, 0x03ba2398, 0xfe0965bc, 0x004d9dde, 0x0019939d, 0xfff89c60, + 0x322af693, 0xf1a3181a, 0xff99badb, 0x03a889a1, 0xfe0a75da, 0x005015a5, 0x00186e31, 0xfff8cc86, + 0x3179751f, 0xf1812bb0, 0xffc3ff0c, 0x0396d10c, 0xfe0bb0f9, 0x00527a8a, 0x00174c9c, 0xfff8fc62, + 0x30c79163, 0xf160e22d, 0xffedd2fd, 0x0384fbd1, 0xfe0d166b, 0x0054cc9a, 0x00162eef, 0xfff92bec, + 0x30155404, 0xf1423924, 0x00173447, 0x03730be0, 0xfe0ea57e, 0x00570be4, 0x00151538, 0xfff95b1e, + 0x2f62c5a7, 0xf1252e0f, 0x00402092, 0x0361032a, 0xfe105d7e, 0x00593877, 0x0013ff88, 0xfff989ef, + 0x2eafeeed, 0xf109be56, 0x00689598, 0x034ee39b, 0xfe123db6, 0x005b5267, 0x0012edea, 0xfff9b85b, + 0x2dfcd873, 0xf0efe748, 0x0090911f, 0x033caf1d, 0xfe144570, 0x005d59c6, 0x0011e06d, 0xfff9e65a, + 0x2d498ad3, 0xf0d7a622, 0x00b81102, 0x032a6796, 0xfe1673f2, 0x005f4eac, 0x0010d71d, 0xfffa13e5, + 0x2c960ea3, 0xf0c0f808, 0x00df1328, 0x03180ee7, 0xfe18c884, 0x0061312e, 0x000fd205, 0xfffa40f8, + 0x2be26c73, 0xf0abda0e, 0x0105958c, 0x0305a6f0, 0xfe1b4268, 0x00630167, 0x000ed130, 0xfffa6d8d, + 0x2b2eaccf, 0xf0984931, 0x012b9635, 0x02f3318a, 0xfe1de0e2, 0x0064bf71, 0x000dd4a7, 0xfffa999d, + 0x2a7ad83c, 0xf086425a, 0x0151133e, 0x02e0b08d, 0xfe20a335, 0x00666b68, 0x000cdc74, 0xfffac525, + 0x29c6f738, 0xf075c260, 0x01760ad1, 0x02ce25ca, 0xfe2388a1, 0x0068056b, 0x000be89f, 0xfffaf01e, + 0x2913123c, 0xf066c606, 0x019a7b27, 0x02bb9310, 0xfe269065, 0x00698d98, 0x000af931, 0xfffb1a84, + 0x285f31b7, 0xf05949fb, 0x01be628c, 0x02a8fa2a, 0xfe29b9c1, 0x006b0411, 0x000a0e2f, 0xfffb4453, + 0x27ab5e12, 0xf04d4ade, 0x01e1bf58, 0x02965cdb, 0xfe2d03f2, 0x006c68f8, 0x000927a0, 0xfffb6d86, + 0x26f79fab, 0xf042c539, 0x02048ff8, 0x0283bce6, 0xfe306e35, 0x006dbc71, 0x00084589, 0xfffb961a, + 0x2643feda, 0xf039b587, 0x0226d2e6, 0x02711c05, 0xfe33f7c7, 0x006efea0, 0x000767f0, 0xfffbbe09, + 0x259083eb, 0xf032182f, 0x024886ad, 0x025e7bf0, 0xfe379fe3, 0x00702fae, 0x00068ed8, 0xfffbe552, + 0x24dd3721, 0xf02be98a, 0x0269a9e9, 0x024bde5a, 0xfe3b65c4, 0x00714fc0, 0x0005ba46, 0xfffc0bef, + 0x242a20b3, 0xf02725dc, 0x028a3b44, 0x023944ee, 0xfe3f48a5, 0x00725f02, 0x0004ea3a, 0xfffc31df, + 0x237748cf, 0xf023c95d, 0x02aa397b, 0x0226b156, 0xfe4347c0, 0x00735d9c, 0x00041eb9, 0xfffc571e, + 0x22c4b795, 0xf021d031, 0x02c9a359, 0x02142533, 0xfe476250, 0x00744bba, 0x000357c2, 0xfffc7ba9, + 0x2212751a, 0xf0213671, 0x02e877b9, 0x0201a223, 0xfe4b978e, 0x0075298a, 0x00029558, 0xfffc9f7e, + 0x21608968, 0xf021f823, 0x0306b586, 0x01ef29be, 0xfe4fe6b3, 0x0075f739, 0x0001d779, 0xfffcc29a, + 0x20aefc79, 0xf0241140, 0x03245bbc, 0x01dcbd96, 0xfe544efb, 0x0076b4f5, 0x00011e26, 0xfffce4fc, + 0x1ffdd63b, 0xf0277db1, 0x03416966, 0x01ca5f37, 0xfe58cf9d, 0x007762f0, 0x0000695e, 0xfffd06a1, + 0x1f4d1e8e, 0xf02c3953, 0x035ddd9e, 0x01b81028, 0xfe5d67d4, 0x0078015a, 0xffffb91f, 0xfffd2787, + 0x1e9cdd43, 0xf0323ff5, 0x0379b790, 0x01a5d1ea, 0xfe6216db, 0x00789065, 0xffff0d66, 0xfffd47ae, + 0x1ded1a1d, 0xf0398d56, 0x0394f674, 0x0193a5f9, 0xfe66dbeb, 0x00791043, 0xfffe6631, 0xfffd6713, }; // we use 15 bits to interpolate between these samples @@ -96,12 +353,16 @@ void AudioResamplerSinc::init_routine() return; } - readResampleCoefficients = (readCoefficientsFn) dlsym(resampleCoeffLib, - "readResamplerCoefficients"); - readResampleFirNumCoeffFn readResampleFirNumCoeff = (readResampleFirNumCoeffFn) + readResampleFirNumCoeffFn readResampleFirNumCoeff; + readResampleFirLerpIntBitsFn readResampleFirLerpIntBits; + + readResampleCoefficients = (readCoefficientsFn) + dlsym(resampleCoeffLib, "readResamplerCoefficients"); + readResampleFirNumCoeff = (readResampleFirNumCoeffFn) dlsym(resampleCoeffLib, "readResampleFirNumCoeff"); - readResampleFirLerpIntBitsFn readResampleFirLerpIntBits = (readResampleFirLerpIntBitsFn) + readResampleFirLerpIntBits = (readResampleFirLerpIntBitsFn) dlsym(resampleCoeffLib, "readResampleFirLerpIntBits"); + if (!readResampleCoefficients || !readResampleFirNumCoeff || !readResampleFirLerpIntBits) { readResampleCoefficients = NULL; dlclose(resampleCoeffLib); @@ -111,15 +372,14 @@ void AudioResamplerSinc::init_routine() } c = &veryHighQualityConstants; - // we have 16 coefs samples per zero-crossing c->coefsBits = readResampleFirLerpIntBits(); - ALOGV("coefsBits = %d", c->coefsBits); c->cShift = kNumPhaseBits - c->coefsBits; c->cMask = ((1<coefsBits)-1) << c->cShift; c->pShift = kNumPhaseBits - c->coefsBits - pLerpBits; c->pMask = ((1<pShift; // number of zero-crossing on each side c->halfNumCoefs = readResampleFirNumCoeff(); + ALOGV("coefsBits = %d", c->coefsBits); ALOGV("halfNumCoefs = %d", c->halfNumCoefs); // note that we "leak" resampleCoeffLib until the process exits } @@ -129,7 +389,7 @@ void AudioResamplerSinc::init_routine() static inline int32_t mulRL(int left, int32_t in, uint32_t vRL) { -#if defined(__arm__) && !defined(__thumb__) +#if USE_INLINE_ASSEMBLY int32_t out; if (left) { asm( "smultb %[out], %[in], %[vRL] \n" @@ -144,18 +404,15 @@ int32_t mulRL(int left, int32_t in, uint32_t vRL) } return out; #else - if (left) { - return int16_t(in>>16) * int16_t(vRL&0xFFFF); - } else { - return int16_t(in>>16) * int16_t(vRL>>16); - } + int16_t v = left ? int16_t(vRL) : int16_t(vRL>>16); + return int32_t((int64_t(in) * v) >> 16); #endif } static inline int32_t mulAdd(int16_t in, int32_t v, int32_t a) { -#if defined(__arm__) && !defined(__thumb__) +#if USE_INLINE_ASSEMBLY int32_t out; asm( "smlawb %[out], %[v], %[in], %[a] \n" : [out]"=r"(out) @@ -163,16 +420,14 @@ int32_t mulAdd(int16_t in, int32_t v, int32_t a) : ); return out; #else - return a + in * (v>>16); - // improved precision - // return a + in * (v>>16) + ((in * (v & 0xffff)) >> 16); + return a + int32_t((int64_t(v) * in) >> 16); #endif } static inline int32_t mulAddRL(int left, uint32_t inRL, int32_t v, int32_t a) { -#if defined(__arm__) && !defined(__thumb__) +#if USE_INLINE_ASSEMBLY int32_t out; if (left) { asm( "smlawb %[out], %[v], %[inRL], %[a] \n" @@ -187,13 +442,8 @@ int32_t mulAddRL(int left, uint32_t inRL, int32_t v, int32_t a) } return out; #else - if (left) { - return a + (int16_t(inRL&0xFFFF) * (v>>16)); - //improved precision - // return a + (int16_t(inRL&0xFFFF) * (v>>16)) + ((int16_t(inRL&0xFFFF) * (v & 0xffff)) >> 16); - } else { - return a + (int16_t(inRL>>16) * (v>>16)); - } + int16_t s = left ? int16_t(inRL) : int16_t(inRL>>16); + return a + int32_t((int64_t(v) * s) >> 16); #endif } @@ -202,7 +452,7 @@ int32_t mulAddRL(int left, uint32_t inRL, int32_t v, int32_t a) AudioResamplerSinc::AudioResamplerSinc(int bitDepth, int inChannelCount, int32_t sampleRate, src_quality quality) : AudioResampler(bitDepth, inChannelCount, sampleRate, quality), - mState(0) + mState(0), mImpulse(0), mRingFull(0), mFirCoefs(0) { /* * Layout of the state buffer for 32 tap: @@ -220,44 +470,48 @@ AudioResamplerSinc::AudioResamplerSinc(int bitDepth, * */ + mVolumeSIMD[0] = 0; + mVolumeSIMD[1] = 0; + // Load the constants for coefficients int ok = pthread_once(&once_control, init_routine); if (ok != 0) { ALOGE("%s pthread_once failed: %d", __func__, ok); } - mConstants = (quality == VERY_HIGH_QUALITY) ? &veryHighQualityConstants : &highQualityConstants; + mConstants = (quality == VERY_HIGH_QUALITY) ? + &veryHighQualityConstants : &highQualityConstants; } -AudioResamplerSinc::~AudioResamplerSinc() -{ - delete[] mState; +AudioResamplerSinc::~AudioResamplerSinc() { + free(mState); } void AudioResamplerSinc::init() { - const Constants *c = mConstants; - - const size_t numCoefs = 2*c->halfNumCoefs; + const Constants& c(*mConstants); + const size_t numCoefs = 2 * c.halfNumCoefs; const size_t stateSize = numCoefs * mChannelCount * 2; - mState = new int16_t[stateSize]; + mState = (int16_t*)memalign(32, stateSize*sizeof(int16_t)); memset(mState, 0, sizeof(int16_t)*stateSize); - mImpulse = mState + (c->halfNumCoefs-1)*mChannelCount; + mImpulse = mState + (c.halfNumCoefs-1)*mChannelCount; mRingFull = mImpulse + (numCoefs+1)*mChannelCount; } +void AudioResamplerSinc::setVolume(int16_t left, int16_t right) { + AudioResampler::setVolume(left, right); + mVolumeSIMD[0] = int32_t(left)<<16; + mVolumeSIMD[1] = int32_t(right)<<16; +} + void AudioResamplerSinc::resample(int32_t* out, size_t outFrameCount, AudioBufferProvider* provider) { - // FIXME store current state (up or down sample) and only load the coefs when the state // changes. Or load two pointers one for up and one for down in the init function. // Not critical now since the read functions are fast, but would be important if read was slow. if (mConstants == &veryHighQualityConstants && readResampleCoefficients) { - ALOGV("get coefficient from libmm-audio resampler library"); - mFirCoefs = (mInSampleRate <= mSampleRate) ? readResampleCoefficients(true) : - readResampleCoefficients(false); + mFirCoefs = readResampleCoefficients( mInSampleRate <= mSampleRate ); } else { - ALOGV("Use default coefficients"); mFirCoefs = (mInSampleRate <= mSampleRate) ? mFirCoefsUp : mFirCoefsDown; } @@ -270,7 +524,6 @@ void AudioResamplerSinc::resample(int32_t* out, size_t outFrameCount, resample<2>(out, outFrameCount, provider); break; } - } @@ -278,7 +531,8 @@ template void AudioResamplerSinc::resample(int32_t* out, size_t outFrameCount, AudioBufferProvider* provider) { - const Constants *c = mConstants; + const Constants& c(*mConstants); + const size_t headOffset = c.halfNumCoefs*CHANNELS; int16_t* impulse = mImpulse; uint32_t vRL = mVolumeRL; size_t inputIndex = mInputIndex; @@ -313,43 +567,31 @@ void AudioResamplerSinc::resample(int32_t* out, size_t outFrameCount, } } } - int16_t *in = mBuffer.i16; + int16_t const * const in = mBuffer.i16; const size_t frameCount = mBuffer.frameCount; // Always read-in the first samples from the input buffer - int16_t* head = impulse + c->halfNumCoefs*CHANNELS; - head[0] = in[inputIndex*CHANNELS + 0]; - if (CHANNELS == 2) - head[1] = in[inputIndex*CHANNELS + 1]; + int16_t* head = impulse + headOffset; + for (size_t i=0 ; i(l, r, phaseFraction, impulse); - out[outputIndex++] += 2 * mulRL(1, l, vRL); - out[outputIndex++] += 2 * mulRL(0, r, vRL); + while (CC_LIKELY(outputIndex < outputSampleCount)) { + filterCoefficient(&out[outputIndex], phaseFraction, impulse, vRL); + outputIndex += 2; phaseFraction += phaseIncrement; - const uint32_t phaseIndex = phaseFraction >> kNumPhaseBits; - if (phaseIndex == 1) { - inputIndex++; - if (inputIndex >= frameCount) - break; // need a new buffer - read(impulse, phaseFraction, in, inputIndex); - } else if (phaseIndex == 2) { // maximum value + const size_t phaseIndex = phaseFraction >> kNumPhaseBits; + for (size_t i=0 ; i= frameCount) - break; // 0 frame available, 2 frames needed - // read first frame - read(impulse, phaseFraction, in, inputIndex); - inputIndex++; - if (inputIndex >= frameCount) - break; // 0 frame available, 1 frame needed - // read second frame + if (inputIndex >= frameCount) { + goto done; // need a new buffer + } read(impulse, phaseFraction, in, inputIndex); } } - +done: // if done with buffer, save samples if (inputIndex >= frameCount) { inputIndex -= frameCount; @@ -375,66 +617,215 @@ void AudioResamplerSinc::read( int16_t*& impulse, uint32_t& phaseFraction, const int16_t* in, size_t inputIndex) { - const Constants *c = mConstants; - const uint32_t phaseIndex = phaseFraction >> kNumPhaseBits; impulse += CHANNELS; phaseFraction -= 1LU<= mRingFull) { - const size_t stateSize = (c->halfNumCoefs*2)*CHANNELS; + + const Constants& c(*mConstants); + if (CC_UNLIKELY(impulse >= mRingFull)) { + const size_t stateSize = (c.halfNumCoefs*2)*CHANNELS; memcpy(mState, mState+stateSize, sizeof(int16_t)*stateSize); impulse -= stateSize; } - int16_t* head = impulse + c->halfNumCoefs*CHANNELS; - head[0] = in[inputIndex*CHANNELS + 0]; - if (CHANNELS == 2) - head[1] = in[inputIndex*CHANNELS + 1]; + + int16_t* head = impulse + c.halfNumCoefs*CHANNELS; + for (size_t i=0 ; i void AudioResamplerSinc::filterCoefficient( - int32_t& l, int32_t& r, uint32_t phase, const int16_t *samples) + int32_t* out, uint32_t phase, const int16_t *samples, uint32_t vRL) { - const Constants *c = mConstants; + // NOTE: be very careful when modifying the code here. register + // pressure is very high and a small change might cause the compiler + // to generate far less efficient code. + // Always sanity check the result with objdump or test-resample. // compute the index of the coefficient on the positive side and // negative side - uint32_t indexP = (phase & c->cMask) >> c->cShift; - uint16_t lerpP = (phase & c->pMask) >> c->pShift; - uint32_t indexN = (-phase & c->cMask) >> c->cShift; - uint16_t lerpN = (-phase & c->pMask) >> c->pShift; - if ((indexP == 0) && (lerpP == 0)) { - indexN = c->cMask >> c->cShift; - lerpN = c->pMask >> c->pShift; - } - - l = 0; - r = 0; - const int32_t* coefs = mFirCoefs; - const int16_t *sP = samples; - const int16_t *sN = samples+CHANNELS; - for (unsigned int i=0 ; i < c->halfNumCoefs/4 ; i++) { - interpolate(l, r, coefs+indexP, lerpP, sP); - interpolate(l, r, coefs+indexN, lerpN, sN); - sP -= CHANNELS; sN += CHANNELS; coefs += 1 << c->coefsBits; - interpolate(l, r, coefs+indexP, lerpP, sP); - interpolate(l, r, coefs+indexN, lerpN, sN); - sP -= CHANNELS; sN += CHANNELS; coefs += 1 << c->coefsBits; - interpolate(l, r, coefs+indexP, lerpP, sP); - interpolate(l, r, coefs+indexN, lerpN, sN); - sP -= CHANNELS; sN += CHANNELS; coefs += 1 << c->coefsBits; - interpolate(l, r, coefs+indexP, lerpP, sP); - interpolate(l, r, coefs+indexN, lerpN, sN); - sP -= CHANNELS; sN += CHANNELS; coefs += 1 << c->coefsBits; + const Constants& c(*mConstants); + const int32_t ONE = c.cMask | c.pMask; + uint32_t indexP = ( phase & c.cMask) >> c.cShift; + uint32_t lerpP = ( phase & c.pMask) >> c.pShift; + uint32_t indexN = ((ONE-phase) & c.cMask) >> c.cShift; + uint32_t lerpN = ((ONE-phase) & c.pMask) >> c.pShift; + + const size_t offset = c.halfNumCoefs; + indexP *= offset; + indexN *= offset; + + int32_t const* coefsP = mFirCoefs + indexP; + int32_t const* coefsN = mFirCoefs + indexN; + int16_t const* sP = samples; + int16_t const* sN = samples + CHANNELS; + + size_t count = offset; + + if (!USE_NEON) { + int32_t l = 0; + int32_t r = 0; + for (size_t i=0 ; i(l, r, coefsP++, offset, lerpP, sP); + sP -= CHANNELS; + interpolate(l, r, coefsN++, offset, lerpN, sN); + sN += CHANNELS; + } + out[0] += 2 * mulRL(1, l, vRL); + out[1] += 2 * mulRL(0, r, vRL); + } else if (CHANNELS == 1) { + int32_t const* coefsP1 = coefsP + offset; + int32_t const* coefsN1 = coefsN + offset; + sP -= CHANNELS*3; + asm ( + "vmov.32 d2[0], %[lerpP] \n" // load the positive phase + "vmov.32 d2[1], %[lerpN] \n" // load the negative phase + "veor q0, q0, q0 \n" // result, initialize to 0 + "vshl.s32 d2, d2, #16 \n" // convert to 32 bits + + "1: \n" + "vld1.16 { d4}, [%[sP]] \n" // load 4 16-bits stereo samples + "vld1.32 { q8}, [%[coefsP0]:128]! \n" // load 4 32-bits coefs + "vld1.32 { q9}, [%[coefsP1]:128]! \n" // load 4 32-bits coefs for interpolation + "vld1.16 { d6}, [%[sN]]! \n" // load 4 16-bits stereo samples + "vld1.32 {q10}, [%[coefsN0]:128]! \n" // load 4 32-bits coefs + "vld1.32 {q11}, [%[coefsN1]:128]! \n" // load 4 32-bits coefs for interpolation + + "vrev64.16 d4, d4 \n" // reverse 2 frames of the positive side + + "vsub.s32 q9, q9, q8 \n" // interpolate (step1) 1st set of coefs + "vsub.s32 q11, q11, q10 \n" // interpolate (step1) 2nd set of coets + "vshll.s16 q12, d4, #15 \n" // extend samples to 31 bits + + "vqrdmulh.s32 q9, q9, d2[0] \n" // interpolate (step2) 1st set of coefs + "vqrdmulh.s32 q11, q11, d2[1] \n" // interpolate (step3) 2nd set of coefs + "vshll.s16 q14, d6, #15 \n" // extend samples to 31 bits + + "vadd.s32 q8, q8, q9 \n" // interpolate (step3) 1st set + "vadd.s32 q10, q10, q11 \n" // interpolate (step4) 2nd set + "subs %[count], %[count], #4 \n" // update loop counter + + "vqrdmulh.s32 q12, q12, q8 \n" // multiply samples by interpolated coef + "vqrdmulh.s32 q14, q14, q10 \n" // multiply samples by interpolated coef + "sub %[sP], %[sP], #8 \n" // move pointer to next set of samples + + "vadd.s32 q0, q0, q12 \n" // accumulate result + "vadd.s32 q0, q0, q14 \n" // accumulate result + + "bne 1b \n" // loop + + "vld1.s32 {d2}, [%[vLR]] \n" // load volumes + "vld1.s32 {d3}, %[out] \n" // load the output + "vpadd.s32 d0, d0, d1 \n" // add all 4 partial sums + "vpadd.s32 d0, d0, d0 \n" // together + "vdup.i32 d0, d0[0] \n" // interleave L,R channels + "vqrdmulh.s32 d0, d0, d2 \n" // apply volume + "vadd.s32 d3, d3, d0 \n" // accumulate result + "vst1.s32 {d3}, %[out] \n" // store result + + : [out] "=Uv" (out[0]), + [count] "+r" (count), + [coefsP0] "+r" (coefsP), + [coefsP1] "+r" (coefsP1), + [coefsN0] "+r" (coefsN), + [coefsN1] "+r" (coefsN1), + [sP] "+r" (sP), + [sN] "+r" (sN) + : [lerpP] "r" (lerpP), + [lerpN] "r" (lerpN), + [vLR] "r" (mVolumeSIMD) + : "cc", "memory", + "q0", "q1", "q2", "q3", + "q8", "q9", "q10", "q11", + "q12", "q14" + ); + } else if (CHANNELS == 2) { + int32_t const* coefsP1 = coefsP + offset; + int32_t const* coefsN1 = coefsN + offset; + sP -= CHANNELS*3; + asm ( + "vmov.32 d2[0], %[lerpP] \n" // load the positive phase + "vmov.32 d2[1], %[lerpN] \n" // load the negative phase + "veor q0, q0, q0 \n" // result, initialize to 0 + "veor q4, q4, q4 \n" // result, initialize to 0 + "vshl.s32 d2, d2, #16 \n" // convert to 32 bits + + "1: \n" + "vld2.16 {d4,d5}, [%[sP]] \n" // load 4 16-bits stereo samples + "vld1.32 { q8}, [%[coefsP0]:128]! \n" // load 4 32-bits coefs + "vld1.32 { q9}, [%[coefsP1]:128]! \n" // load 4 32-bits coefs for interpolation + "vld2.16 {d6,d7}, [%[sN]]! \n" // load 4 16-bits stereo samples + "vld1.32 {q10}, [%[coefsN0]:128]! \n" // load 4 32-bits coefs + "vld1.32 {q11}, [%[coefsN1]:128]! \n" // load 4 32-bits coefs for interpolation + + "vrev64.16 d4, d4 \n" // reverse 2 frames of the positive side + "vrev64.16 d5, d5 \n" // reverse 2 frames of the positive side + + "vsub.s32 q9, q9, q8 \n" // interpolate (step1) 1st set of coefs + "vsub.s32 q11, q11, q10 \n" // interpolate (step1) 2nd set of coets + "vshll.s16 q12, d4, #15 \n" // extend samples to 31 bits + "vshll.s16 q13, d5, #15 \n" // extend samples to 31 bits + + "vqrdmulh.s32 q9, q9, d2[0] \n" // interpolate (step2) 1st set of coefs + "vqrdmulh.s32 q11, q11, d2[1] \n" // interpolate (step3) 2nd set of coefs + "vshll.s16 q14, d6, #15 \n" // extend samples to 31 bits + "vshll.s16 q15, d7, #15 \n" // extend samples to 31 bits + + "vadd.s32 q8, q8, q9 \n" // interpolate (step3) 1st set + "vadd.s32 q10, q10, q11 \n" // interpolate (step4) 2nd set + "subs %[count], %[count], #4 \n" // update loop counter + + "vqrdmulh.s32 q12, q12, q8 \n" // multiply samples by interpolated coef + "vqrdmulh.s32 q13, q13, q8 \n" // multiply samples by interpolated coef + "vqrdmulh.s32 q14, q14, q10 \n" // multiply samples by interpolated coef + "vqrdmulh.s32 q15, q15, q10 \n" // multiply samples by interpolated coef + "sub %[sP], %[sP], #16 \n" // move pointer to next set of samples + + "vadd.s32 q0, q0, q12 \n" // accumulate result + "vadd.s32 q4, q4, q13 \n" // accumulate result + "vadd.s32 q0, q0, q14 \n" // accumulate result + "vadd.s32 q4, q4, q15 \n" // accumulate result + + "bne 1b \n" // loop + + "vld1.s32 {d2}, [%[vLR]] \n" // load volumes + "vld1.s32 {d3}, %[out] \n" // load the output + "vpadd.s32 d0, d0, d1 \n" // add all 4 partial sums from q0 + "vpadd.s32 d8, d8, d9 \n" // add all 4 partial sums from q4 + "vpadd.s32 d0, d0, d0 \n" // together + "vpadd.s32 d8, d8, d8 \n" // together + "vtrn.s32 d0, d8 \n" // interlace L,R channels + "vqrdmulh.s32 d0, d0, d2 \n" // apply volume + "vadd.s32 d3, d3, d0 \n" // accumulate result + "vst1.s32 {d3}, %[out] \n" // store result + + : [out] "=Uv" (out[0]), + [count] "+r" (count), + [coefsP0] "+r" (coefsP), + [coefsP1] "+r" (coefsP1), + [coefsN0] "+r" (coefsN), + [coefsN1] "+r" (coefsN1), + [sP] "+r" (sP), + [sN] "+r" (sN) + : [lerpP] "r" (lerpP), + [lerpN] "r" (lerpN), + [vLR] "r" (mVolumeSIMD) + : "cc", "memory", + "q0", "q1", "q2", "q3", "q4", + "q8", "q9", "q10", "q11", + "q12", "q13", "q14", "q15" + ); } } template void AudioResamplerSinc::interpolate( int32_t& l, int32_t& r, - const int32_t* coefs, int16_t lerp, const int16_t* samples) + const int32_t* coefs, size_t offset, + int32_t lerp, const int16_t* samples) { int32_t c0 = coefs[0]; - int32_t c1 = coefs[1]; + int32_t c1 = coefs[offset]; int32_t sinc = mulAdd(lerp, (c1-c0)<<1, c0); if (CHANNELS == 2) { uint32_t rl = *reinterpret_cast(samples); diff --git a/services/audioflinger/AudioResamplerSinc.h b/services/audioflinger/AudioResamplerSinc.h index 25fc025..09c6866 100644 --- a/services/audioflinger/AudioResamplerSinc.h +++ b/services/audioflinger/AudioResamplerSinc.h @@ -44,18 +44,21 @@ public: private: void init(); + virtual void setVolume(int16_t left, int16_t right); + template void resample(int32_t* out, size_t outFrameCount, AudioBufferProvider* provider); template inline void filterCoefficient( - int32_t& l, int32_t& r, uint32_t phase, const int16_t *samples); + int32_t* out, uint32_t phase, const int16_t *samples, uint32_t vRL); template inline void interpolate( int32_t& l, int32_t& r, - const int32_t* coefs, int16_t lerp, const int16_t* samples); + const int32_t* coefs, size_t offset, + int32_t lerp, const int16_t* samples); template inline void read(int16_t*& impulse, uint32_t& phaseFraction, @@ -64,6 +67,7 @@ private: int16_t *mState; int16_t *mImpulse; int16_t *mRingFull; + int32_t mVolumeSIMD[2]; const int32_t * mFirCoefs; static const int32_t mFirCoefsDown[]; @@ -71,17 +75,14 @@ private: // ---------------------------------------------------------------------------- static const int32_t RESAMPLE_FIR_NUM_COEF = 8; - static const int32_t RESAMPLE_FIR_LERP_INT_BITS = 4; + static const int32_t RESAMPLE_FIR_LERP_INT_BITS = 7; struct Constants { - // we have 16 coefs samples per zero-crossing int coefsBits; int cShift; uint32_t cMask; - int pShift; uint32_t pMask; - // number of zero-crossing on each side unsigned int halfNumCoefs; }; diff --git a/services/audioflinger/audio-resampler/AudioResamplerCoefficients.cpp b/services/audioflinger/audio-resampler/AudioResamplerCoefficients.cpp index ade58a7..af3e40d 100644 --- a/services/audioflinger/audio-resampler/AudioResamplerCoefficients.cpp +++ b/services/audioflinger/audio-resampler/AudioResamplerCoefficients.cpp @@ -14,42 +14,41 @@ * limitations under the License. */ -#include -#include -#undef LOG_TAG -#include -//#include "common_log.h" #define LOG_TAG "ResamplerCoefficients" #define LOG_NDEBUG 0 -const int32_t RESAMPLE_FIR_NUM_COEF = 16; -const int32_t RESAMPLE_FIR_LERP_INT_BITS = 7; +#include + +#include "filter_coefficients.h" + +const int32_t RESAMPLE_FIR_NUM_COEF = 16; +const int32_t RESAMPLE_FIR_LERP_INT_BITS = 7; using namespace android; + #ifdef __cplusplus extern "C" { #endif + const int32_t* readResamplerCoefficients(bool upSample) { ALOGV("readResamplerCoefficients"); - if(upSample) { - return resampler_filter_coefficients_10042011; + if (upSample) { + return up_sampler_filter_coefficients; + } else { + return dn_sampler_filter_coefficients; } - else { - return dnsampler_filter_coefficients_x128_10112011; - } } int32_t readResampleFirNumCoeff() { - return RESAMPLE_FIR_NUM_COEF; } int32_t readResampleFirLerpIntBits() { - - return RESAMPLE_FIR_LERP_INT_BITS; + return RESAMPLE_FIR_LERP_INT_BITS; } + #ifdef __cplusplus } #endif diff --git a/services/audioflinger/audio-resampler/dnsampler_filter_coefficients_x128_10112011.h b/services/audioflinger/audio-resampler/dnsampler_filter_coefficients_x128_10112011.h deleted file mode 100644 index eb2944c..0000000 --- a/services/audioflinger/audio-resampler/dnsampler_filter_coefficients_x128_10112011.h +++ /dev/null @@ -1,2585 +0,0 @@ - -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include - -namespace android { - -const int32_t dnsampler_filter_coefficients_x128_10112011[] = { -1849391518, -1849249650, -1848824221, -1848115177, -1847122891, -1845847499, -1844289491, -1842449129, -1840327103, -1837923861, -1835240203, -1832276710, -1829034388, -1825513999, -1821716652, -1817643240, -1813295074, -1808673214, -1803779065, -1798613825, -1793179109, -1787476282, -1781507048, -1775272909, -1768775774, -1762017295, -1754999460, -1747724062, -1740193297, -1732409109, -1724373764, -1716089338, -1707558293, -1698782831, -1689765473, -1680508558, -1671014814, -1661286715, -1651327042, -1641138399, -1630723762, -1620085842, -1609227651, -1598152036, -1586862206, -1575361116, -1563652006, -1551737947, -1539622358, -1527308388, -1514799466, -1502098869, -1489210218, -1476136877, -1462882477, -1449450498, -1435844739, -1422068735, -1408126274, -1394021008, -1379756900, -1365337657, -1350767225, -1336049408, -1321188297, -1306187721, -1291051731, -1275784259, -1260389523, -1244871491, -1229234343, -1213482137, -1197619187, -1181649550, -1165577481, -1149407125, -1133142876, -1116788884, -1100349476, -1083828868, -1067231493, -1050561533, -1033823337, -1017021160, -1000159475, -983242522, -966274693, -949260282, -932203771, -915109401, -897981548, -880824504, -863642743, -846440509, -829222164, -811991981, -794754382, -777513558, -760273800, -743039333, -725814532, -708603558, -691410662, -674240023, -657095935, -639982476, -622903794, -605863979, -588867231, -571917545, -555018972, -538175499, -521391190, -504669905, -488015541, -471431958, -454923090, -438492688, -422144531, -405882352, -389709927, -373630848, -357648715, -341767096, -325989596, -310319649, -294760687, -279316098, -263989284, -248783473, -233701878, -218747691, -203924116, -189234208, -174680993, -160267473, -145996632, -131871305, -117894282, -104068338, -90396230, -76880575, -63523937, -50328860, -37297842, -24433248, -11737378, --787473, --13139049, --25315210, --37313887, --49133021, --60770615, --72224791, --83493750, --94575698, --105468905, --116171744, --126682678, --137000178, --147122799, --157049194, --166778112, --176308299, --185638576, --194767849, --203695121, --212419395, --220939772, --229255432, --237365662, --245269744, --252967058, --260457050, --267739278, --274813300, --281678782, --288335451, --294783151, --301021713, --307051072, --312871207, --318482217, --323884189, --329077326, --334061875, --338838202, --343406662, --347767725, --351921891, --355869785, --359612019, --363149327, --366482470, --369612329, --372539768, --375265766, --377791316, --380117528, --382245500, --384176449, --385911601, --387452302, --388799883, --389955791, --390921477, --391698507, --392288434, --392692926, --392913649, --392952381, --392810881, --392491020, --391994654, --391323748, --390480249, --389466214, --388283683, --386934801, --385421695, --383746599, --381911725, --379919384, --377771869, --375471577, --373020872, --370422215, --367678046, --364790904, --361763287, --358597785, --355296968, --351863496, --348299986, --344609141, --340793645, --336856270, --332799742, --328626863, --324340418, --319943269, --315438225, --310828168, --306115960, --301304533, --296396768, --291395607, --286303973, --281124849, --275861163, --270515897, --265092015, --259592541, --254020439, --248378720, --242670378, --236898450, --231065914, --225175783, --219231057, --213234773, --207189910, --201099474, --194966455, --188793871, --182584674, --176341840, --170068330, --163767128, --157441156, --151093349, --144726627, --138343919, --131948090, --125542009, --119128533, --112710525, --106290787, --99872116, --93457296, --87049105, --80650255, --74263449, --67891377, --61536721, --55202101, --48890119, --42603362, --36344397, --30115726, --23919828, --17759168, --11636191, --5553280, -487212, -6482947, -12431620, -18330990, -24178851, -29973011, -35711312, -41391655, -47011985, -52570260, -58064483, -63492718, -68853076, -74143678, -79362692, -84508338, -89578892, -94572639, -99487923, -104323138, -109076739, -113747190, -118333012, -122832775, -127245111, -131568663, -135802141, -139944301, -143993966, -147949965, -151811195, -155576593, -159245166, -162815931, -166287976, -169660430, -172932498, -176103387, -179172383, -182138803, -185002039, -187761495, -190416648, -192967011, -195412171, -197751720, -199985330, -202112693, -204133584, -206047780, -207855140, -209555545, -211148956, -212635338, -214014737, -215287214, -216452911, -217511975, -218464633, -219311127, -220051778, -220686909, -221216923, -221642232, -221963326, -222180699, -222294922, -222306577, -222216320, -222024810, -221732784, -221340984, -220850224, -220261321, -219575167, -218792653, -217914741, -216942395, -215876649, -214718535, -213469149, -212129590, -210701024, -209184611, -207581573, -205893134, -204120584, -202265202, -200328328, -198311300, -196215518, -194042369, -191793295, -189469738, -187073198, -184605160, -182067159, -179460730, -176787462, -174048923, -171246730, -168382500, -165457899, -162474572, -159434208, -156338493, -153189156, -149987902, -146736470, -143436603, -140090079, -136698650, -133264101, -129788215, -126272805, -122719654, -119130572, -115507371, -111851884, -108165922, -104451311, -100709877, -96943466, -93153889, -89342976, -85512554, -81664466, -77800525, -73922553, -70032372, -66131809, -62222659, -58306723, -54385799, -50461691, -46536172, -42611011, -38687978, -34768834, -30855311, -26949132, -23052017, -19165682, -15291809, -11432068, -7588126, -3761633, --45792, --3832550, --7597044, --11337694, --15052951, --18741290, --22401190, --26031153, --29629717, --33195444, --36726898, --40222670, --43681381, --47101682, --50482228, --53821707, --57118836, --60372370, --63581062, --66743703, --69859111, --72926141, --75943654, --78910550, --81825759, --84688251, --87496999, --90251018, --92949348, --95591074, --98175284, --100701113, --103167725, --105574326, --107920130, --110204396, --112426408, --114585497, --116681001, --118712307, --120678826, --122580018, --124415349, --126184333, --127886505, --129521449, --131088758, --132588075, --134019062, --135381436, --136674915, --137899273, --139054300, --140139836, --141155730, --142101884, --142978213, --143784688, --144521281, --145188022, --145784950, --146312156, --146769738, --147157848, --147476649, --147726356, --147907187, --148019419, --148063331, --148039258, --147947536, --147788557, --147562717, --147270463, --146912244, --146488563, --145999923, --145446877, --144829983, --144149847, --143407076, --142602324, --141736248, --140809557, --139822954, --138777189, --137673015, --136511230, --135292629, --134018047, --132688326, --131304347, --129866988, --128377166, --126835801, --125243852, --123602271, --121912047, --120174172, --118389676, --116559578, --114684934, --112766800, --110806267, --108804411, --106762342, --104681172, --102562041, --100406081, --98214447, --95988299, --93728821, --91437183, --89114578, --86762204, --84381279, --81973009, --79538619, --77079333, --74596397, --72091035, --69564491, --67018008, --64452847, --61870249, --59271470, --56657765, --54030397, --51390615, --48739670, --46078819, --43409324, --40732431, --38049385, --35361437, --32669835, --29975809, --27280589, --24585404, --21891486, --19200045, --16512287, --13829420, --11152644, --8483140, --5822079, --3170634, --529970, -2098768, -4714446, -7315931, -9902105, -12471869, -15024139, -17557833, -20071880, -22565234, -25036861, -27485734, -29910841, -32311195, -34685828, -37033773, -39354083, -41645834, -43908123, -46140049, -48340738, -50509337, -52645015, -54746948, -56814333, -58846388, -60842359, -62801494, -64723072, -66606390, -68450776, -70255559, -72020101, -73743779, -75426002, -77066186, -78663776, -80218238, -81729070, -83195771, -84617877, -85994939, -87326540, -88612269, -89851753, -91044631, -92190579, -93289279, -94340447, -95343813, -96299144, -97206213, -98064827, -98874809, -99636019, -100348318, -101011607, -101625796, -102190834, -102706673, -103173303, -103590724, -103958975, -104278097, -104548170, -104769282, -104941559, -105065128, -105140157, -105166820, -105145327, -105075891, -104958764, -104794201, -104582494, -104323937, -104018863, -103667606, -103270537, -102828031, -102340497, -101808346, -101232024, -100611979, -99948695, -99242655, -98494373, -97704368, -96873190, -96001391, -95089549, -94138248, -93148103, -92119724, -91053751, -89950827, -88811624, -87636812, -86427086, -85183142, -83905705, -82595493, -81253249, -79879717, -78475668, -77041865, -75579093, -74088140, -72569815, -71024919, -69454270, -67858693, -66239031, -64596117, -62930801, -61243936, -59536392, -57809025, -56062708, -54298314, -52516733, -50718843, -48905532, -47077692, -45236223, -43382015, -41515965, -39638972, -37751945, -35855780, -33951378, -32039643, -30121481, -28197786, -26269454, -24337383, -22402475, -20465617, -18527696, -16589601, -14652220, -12716424, -10783083, -8853070, -6927251, -5006483, -3091612, -1183489, --717043, --2609159, --4492039, --6364862, --8226816, --10077103, --11914934, --13739523, --15550093, --17345884, --19126146, --20890132, --22637106, --24366346, --26077146, --27768800, --29440618, --31091927, --32722068, --34330384, --35916235, --37478994, --39018053, --40532806, --42022667, --43487063, --44925444, --46337259, --47721979, --49079087, --50408090, --51708495, --52979834, --54221651, --55433514, --56614992, --57765679, --58885178, --59973119, --61029133, --62052877, --63044020, --64002256, --64927281, --65818818, --66676601, --67500387, --68289938, --69045045, --69765506, --70451147, --71101796, --71717309, --72297549, --72842408, --73351780, --73825587, --74263759, --74666254, --75033033, --75364085, --75659405, --75919016, --76142943, --76331242, --76483972, --76601219, --76683074, --76729655, --76741083, --76717507, --76659078, --76565976, --76438382, --76276507, --76080561, --75850784, --75587416, --75290725, --74960980, --74598477, --74203511, --73776405, --73317481, --72827089, --72305578, --71753320, --71170691, --70558089, --69915913, --69244582, --68544519, --67816171, --67059982, --66276416, --65465942, --64629046, --63766215, --62877953, --61964766, --61027182, --60065722, --59080928, --58073342, --57043524, --55992029, --54919428, --53826296, --52713221, --51580788, --50429596, --49260245, --48073350, --46869516, --45649365, --44413516, --43162604, --41897255, --40618108, --39325799, --38020978, --36704285, --35376367, --34037875, --32689467, --31331794, --29965512, --28591278, --27209755, --25821597, --24427461, --23028006, --21623896, --20215785, --18804329, --17390186, --15974013, --14556459, --13138172, --11719802, --10301999, --8885401, --7470647, --6058375, --4649221, --3243807, --1842755, --446687, -943782, -2328043, -3705495, -5075537, -6437575, -7791026, -9135312, -10469860, -11794099, -13107474, -14409434, -15699433, -16976932, -18241406, -19492338, -20729214, -21951528, -23158786, -24350507, -25526208, -26685422, -27827692, -28952575, -30059626, -31148419, -32218533, -33269565, -34301113, -35312788, -36304216, -37275034, -38224885, -39153423, -40060316, -40945246, -41807897, -42647972, -43465182, -44259258, -45029930, -45776947, -46500068, -47199069, -47873729, -48523844, -49149222, -49749687, -50325066, -50875204, -51399956, -51899193, -52372790, -52820642, -53242651, -53638739, -54008828, -54352864, -54670795, -54962591, -55228223, -55467686, -55680976, -55868110, -56029109, -56164013, -56272864, -56355729, -56412671, -56443780, -56449143, -56428871, -56383077, -56311893, -56215452, -56093910, -55947423, -55776167, -55580318, -55360074, -55115633, -54847211, -54555028, -54239319, -53900322, -53538294, -53153491, -52746187, -52316657, -51865197, -51392097, -50897668, -50382220, -49846081, -49289577, -48713047, -48116836, -47501302, -46866801, -46213703, -45542381, -44853220, -44146603, -43422927, -42682590, -41926002, -41153572, -40365719, -39562864, -38745438, -37913870, -37068598, -36210060, -35338709, -34454988, -33559353, -32652259, -31734171, -30805546, -29866852, -28918556, -27961133, -26995053, -26020792, -25038826, -24049638, -23053702, -22051499, -21043509, -20030219, -19012108, -17989658, -16963352, -15933674, -14901104, -13866119, -12829202, -11790833, -10751487, -9711638, -8671763, -7632335, -6593820, -5556683, -4521391, -3488407, -2458187, -1431187, -407859, --611345, --1625983, --2635618, --3639811, --4638127, --5630141, --6615431, --7593576, --8564163, --9526785, --10481043, --11426537, --12362876, --13289673, --14206552, --15113136, --16009059, --16893959, --17767487, --18629291, --19479032, --20316375, --21140997, --21952575, --22750798, --23535360, --24305970, --25062334, --25804171, --26531205, --27243175, --27939817, --28620882, --29286128, --29935325, --30568244, --31184668, --31784388, --32367206, --32932927, --33481369, --34012357, --34525729, --35021324, --35498994, --35958600, --36400012, --36823105, --37227767, --37613893, --37981391, --38330171, --38660157, --38971278, --39263479, --39536704, --39790914, --40026074, --40242163, --40439161, --40617065, --40775874, --40915600, --41036259, --41137883, --41220502, --41284167, --41328926, --41354844, --41361987, --41350437, --41320276, --41271601, --41204513, --41119123, --41015546, --40893911, --40754348, --40597001, --40422014, --40229546, --40019757, --39792819, --39548906, --39288206, --39010907, --38717208, --38407310, --38081429, --37739776, --37382578, --37010062, --36622464, --36220024, --35802990, --35371611, --34926149, --34466863, --33994021, --33507895, --33008767, --32496915, --31972628, --31436196, --30887917, --30328089, --29757014, --29175000, --28582360, --27979405, --27366455, --26743828, --26111852, --25470849, --24821150, --24163084, --23496990, --22823200, --22142053, --21453889, --20759052, --20057882, --19350724, --18637922, --17919826, --17196782, --16469137, --15737241, --15001445, --14262095, --13519542, --12774133, --12026222, --11276155, --10524279, --9770942, --9016494, --8261277, --7505635, --6749910, --5994447, --5239585, --4485659, --3733007, --2981966, --2232865, --1486032, --741794, --479, -737595, -1472108, -2202745, -2929192, -3651141, -4368289, -5080331, -5786969, -6487909, -7182860, -7871535, -8553649, -9228926, -9897092, -10557878, -11211015, -11856245, -12493314, -13121967, -13741959, -14353050, -14955005, -15547593, -16130588, -16703768, -17266923, -17819839, -18362313, -18894148, -19415155, -19925144, -20423935, -20911353, -21387231, -21851406, -22303720, -22744023, -23172174, -23588031, -23991464, -24382346, -24760559, -25125987, -25478524, -25818069, -26144531, -26457817, -26757849, -27044549, -27317851, -27577690, -27824011, -28056763, -28275905, -28481398, -28673213, -28851323, -29015713, -29166367, -29303283, -29426459, -29535904, -29631629, -29713655, -29782006, -29836715, -29877818, -29905359, -29919387, -29919958, -29907132, -29880978, -29841566, -29788975, -29723288, -29644596, -29552991, -29448575, -29331452, -29201735, -29059537, -28904981, -28738192, -28559303, -28368447, -28165766, -27951404, -27725513, -27488244, -27239759, -26980219, -26709793, -26428650, -26136967, -25834922, -25522700, -25200487, -24868475, -24526855, -24175830, -23815596, -23446360, -23068326, -22681709, -22286719, -21883572, -21472486, -21053686, -20627392, -20193830, -19753228, -19305819, -18851833, -18391506, -17925071, -17452770, -16974838, -16491518, -16003049, -15509677, -15011645, -14509198, -14002580, -13492042, -12977828, -12460185, -11939362, -11415608, -10889171, -10360299, -9829240, -9296245, -8761559, -8225429, -7688103, -7149828, -6610849, -6071411, -5531756, -4992131, -4452774, -3913926, -3375826, -2838712, -2302821, -1768384, -1235637, -704811, -176132, --350173, --873879, --1394763, --1912606, --2427192, --2938303, --3445727, --3949255, --4448681, --4943802, --5434414, --5920319, --6401326, --6877239, --7347870, --7813034, --8272552, --8726243, --9173932, --9615448, --10050623, --10479293, --10901295, --11316474, --11724679, --12125759, --12519569, --12905967, --13284818, --13655986, --14019344, --14374766, --14722134, --15061330, --15392240, --15714758, --16028781, --16334207, --16630942, --16918895, --17197981, --17468118, --17729228, --17981237, --18224079, --18457687, --18682004, --18896973, --19102546, --19298674, --19485318, --19662437, --19830002, --19987982, --20136353, --20275096, --20404197, --20523643, --20633430, --20733554, --20824018, --20904829, --20975997, --21037538, --21089473, --21131822, --21164617, --21187886, --21201668, --21206001, --21200931, --21186504, --21162774, --21129796, --21087631, --21036341, --20975996, --20906666, --20828426, --20741355, --20645535, --20541051, --20427994, --20306454, --20176529, --20038316, --19891920, --19737444, --19574998, --19404692, --19226642, --19040965, --18847782, --18647215, --18439392, --18224439, --18002487, --17773669, --17538123, --17295986, --17047397, --16792499, --16531439, --16264360, --15991413, --15712746, --15428514, --15138869, --14843968, --14543967, --14239027, --13929305, --13614963, --13296164, --12973072, --12645852, --12314669, --11979690, --11641084, --11299018, --10953660, --10605181, --10253752, --9899543, --9542724, --9183468, --8821947, --8458330, --8092791, --7725499, --7356629, --6986351, --6614835, --6242252, --5868775, --5494571, --5119810, --4744660, --4369291, --3993868, --3618559, --3243529, --2868942, --2494962, --2121750, --1749467, --1378274, --1008329, --639789, --272809, -92455, -455851, -817231, -1176442, -1533338, -1887773, -2239604, -2588688, -2934884, -3278056, -3618068, -3954787, -4288079, -4617816, -4943871, -5266119, -5584437, -5898705, -6208806, -6514625, -6816049, -7112968, -7405275, -7692864, -7975633, -8253483, -8526319, -8794045, -9056570, -9313805, -9565666, -9812069, -10052933, -10288182, -10517742, -10741541, -10959512, -11171587, -11377707, -11577809, -11771839, -11959741, -12141468, -12316971, -12486205, -12649128, -12805703, -12955894, -13099669, -13236996, -13367853, -13492214, -13610059, -13721371, -13826136, -13924343, -14015982, -14101050, -14179544, -14251463, -14316813, -14375598, -14427829, -14473516, -14512676, -14545324, -14571484, -14591176, -14604428, -14611268, -14611727, -14605840, -14593643, -14575174, -14550478, -14519596, -14482577, -14439469, -14390325, -14335196, -14274142, -14207219, -14134490, -14056016, -13971864, -13882101, -13786797, -13686023, -13579854, -13468364, -13351632, -13229736, -13102759, -12970783, -12833894, -12692177, -12545721, -12394615, -12238951, -12078822, -11914322, -11745546, -11572592, -11395558, -11214544, -11029649, -10840977, -10648630, -10452712, -10253328, -10050584, -9844586, -9635444, -9423263, -9208154, -8990226, -8769590, -8546356, -8320637, -8092543, -7862188, -7629684, -7395143, -7158678, -6920405, -6680434, -6438881, -6195859, -5951482, -5705863, -5459115, -5211352, -4962688, -4713234, -4463103, -4212408, -3961262, -3709774, -3458055, -3206216, -2954367, -2702617, -2451073, -2199845, -1949039, -1698760, -1449115, -1200206, -952139, -705015, -458936, -214002, --29687, --272033, --512941, --752313, --990055, --1226074, --1460278, --1692576, --1922878, --2151097, --2377147, --2600942, --2822399, --3041435, --3257970, --3471925, --3683223, --3891787, --4097545, --4300424, --4500352, --4697261, --4891083, --5081754, --5269208, --5453384, --5634222, --5811664, --5985653, --6156134, --6323055, --6486364, --6646013, --6801954, --6954144, --7102537, --7247093, --7387773, --7524538, --7657353, --7786184, --7910999, --8031770, --8148467, --8261064, --8369539, --8473868, --8574031, --8670011, --8761790, --8849356, --8932694, --9011796, --9086651, --9157254, --9223598, --9285682, --9343504, --9397065, --9446367, --9491415, --9532214, --9568774, --9601103, --9629214, --9653119, --9672835, --9688376, --9699763, --9707015, --9710154, --9709202, --9704187, --9695132, --9682068, --9665024, --9644031, --9619121, --9590330, --9557692, --9521245, --9481028, --9437080, --9389443, --9338159, --9283272, --9224828, --9162872, --9097452, --9028617, --8956417, --8880903, --8802127, --8720142, --8635003, --8546764, --8455484, --8361217, --8264022, --8163959, --8061088, --7955468, --7847161, --7736229, --7622737, --7506745, --7388320, --7267525, --7144428, --7019092, --6891585, --6761974, --6630327, --6496711, --6361194, --6223845, --6084734, --5943929, --5801500, --5657517, --5512050, --5365168, --5216942, --5067443, --4916741, --4764906, --4612009, --4458120, --4303311, --4147650, --3991209, --3834057, --3676265, --3517901, --3359037, --3199740, --3040080, --2880126, --2719945, --2559606, --2399177, --2238724, --2078315, --1918015, --1757891, --1598007, --1438428, --1279218, --1120441, --962159, --804435, --647330, --490906, --335223, --180338, --26312, -126797, -278933, -430040, -580062, -728943, -876632, -1023074, -1168219, -1312015, -1454411, -1595360, -1734812, -1872720, -2009038, -2143721, -2276725, -2408006, -2537522, -2665233, -2791097, -2915076, -3037131, -3157228, -3275328, -3391399, -3505405, -3617315, -3727097, -3834720, -3940156, -4043377, -4144356, -4243067, -4339485, -4433587, -4525351, -4614755, -4701780, -4786406, -4868616, -4948393, -5025721, -5100587, -5172977, -5242878, -5310279, -5375172, -5437547, -5497396, -5554712, -5609491, -5661728, -5711419, -5758562, -5803157, -5845203, -5884701, -5921652, -5956061, -5987931, -6017267, -6044075, -6068363, -6090138, -6109409, -6126186, -6140482, -6152306, -6161673, -6168595, -6173088, -6175167, -6174849, -6172151, -6167091, -6159687, -6149960, -6137930, -6123618, -6107046, -6088238, -6067217, -6044007, -6018632, -5991120, -5961496, -5929787, -5896020, -5860225, -5822429, -5782663, -5740956, -5697338, -5651841, -5604497, -5555336, -5504393, -5451699, -5397289, -5341196, -5283454, -5224099, -5163164, -5100686, -5036700, -4971242, -4904348, -4836055, -4766400, -4695420, -4623152, -4549633, -4474901, -4398995, -4321952, -4243810, -4164608, -4084383, -4003175, -3921021, -3837960, -3754032, -3669273, -3583724, -3497422, -3410406, -3322714, -3234384, -3145456, -3055967, -2965954, -2875457, -2784513, -2693159, -2601433, -2509371, -2417012, -2324391, -2231545, -2138511, -2045325, -1952022, -1858638, -1765208, -1671768, -1578350, -1484991, -1391723, -1298581, -1205597, -1112804, -1020235, -927921, -835894, -744186, -652826, -561846, -471276, -381143, -291479, -202310, -113666, -25572, --61942, --148851, --235129, --320751, --405691, --489926, --573430, --656181, --738156, --819332, --899688, --979202, --1057854, --1135623, --1212489, --1288435, --1363441, --1437489, --1510563, --1582644, --1653718, --1723769, --1792781, --1860740, --1927631, --1993443, --2058161, --2121774, --2184270, --2245638, --2305868, --2364949, --2422873, --2479630, --2535212, --2589613, --2642824, --2694840, --2745654, --2795261, --2843656, --2890834, --2936793, --2981528, --3025036, --3067316, --3108366, --3148185, --3186772, --3224126, --3260249, --3295140, --3328802, --3361236, --3392444, --3422430, --3451195, --3478744, --3505081, --3530210, --3554136, --3576865, --3598402, --3618754, --3637927, --3655929, --3672765, --3688446, --3702978, --3716370, --3728631, --3739770, --3749797, --3758721, --3766553, --3773304, --3778983, --3783603, --3787174, --3789709, --3791219, --3791717, --3791215, --3789725, --3787262, --3783838, --3779466, --3774160, --3767934, --3760802, --3752778, --3743877, --3734113, --3723501, --3712056, --3699792, --3686725, --3672871, --3658244, --3642860, --3626735, --3609884, --3592324, --3574069, --3555137, --3535542, --3515302, --3494432, --3472947, --3450866, --3428203, --3404974, --3381197, --3356887, --3332060, --3306732, --3280921, --3254641, --3227909, --3200741, --3173153, --3145162, --3116781, --3088029, --3058920, --3029469, --2999694, --2969608, --2939228, --2908568, --2877644, --2846472, --2815064, --2783438, --2751607, --2719586, --2687389, --2655030, --2622524, --2589885, --2557126, --2524261, --2491304, --2458268, --2425166, --2392011, --2358815, --2325592, --2292354, --2259114, --2225882, --2192671, --2159493, --2126359, --2093281, --2060269, --2027334, --1994487, --1961738, --1929098, --1896576, --1864183, --1831927, --1799818, --1767865, --1736078, --1704464, --1673032, --1641791, --1610748, --1579911, --1549288, --1518886, --1488713, --1458774, --1429078, --1399630, --1370436, --1341503, --1312836, --1284441, --1256324, --1228489, --1200941, --1173686, --1146727, --1120069, --1093717, --1067673, --1041942, --1016527, --991432, --966659, --942211, --918092, --894303, --870846, --847724, --824940, --802493, --780386, --758621, --737199, --716120, --695385, --674996, --654951, --635253, --615901, --596895, --578234, --559919, --541949, --524324, --507042, --490103, --473505, --457248, --441330, --425750, --410506, --395596, --381019, --366773, --352855, --339263, --325995, --313049, --300421, --288110, --276112, --264425, --253046, --241972, --231199, --220725, --210546, --200659, --191060, --181746, --172713, --163958, --155477, --147266, --139321, --131639, --124215, --117045, --110126, --103453, --97022, --90829, --84870, --79140, --73636, --68352, --63285, --58431, --53784, --49341, --45097, --41048, --37188, --33515, --30023, --26708, --23566, --20592, --17782, --15130, --12634, --10289, --8089, --6031, --4111, --2324, --666, -868, -2281, -3578, -4763, -5839, -6812, -7685, -8462, -9146, -9743, -10255, -10686, -11041, -11322, -11533, -11679, -11762, -11785, -11753, -11668, -11533, -11352, -11128, -10864, -10563, -10227, -9860, -9464, -9042, -8596, -8129, -7644, -7142, -6626, -6099, -5562, -5017, -4467, -3913, -3357, -2800, -2245, -1694, -1146, -605, -71, --454, --970, --1474, --1966, --2446, --2911, --3362, --3797, --4215, --4617, --5001, --5367, --5714, --6043, --6352, --6641, --6910, --7160, --7389, --7598, --7786, --7954, --8102, --8230, --8338, --8426, --8495, --8545, --8575, --8587, --8582, --8558, --8517, --8460, --8386, --8297, --8192, --8073, --7940, --7794, --7635, --7464, --7281, --7088, --6885, --6672, --6450, --6221, --5984, --5740, --5490, --5235, --4975, --4711, --4443, --4173, --3901, --3627, --3352, --3077, --2803, --2529, --2257, --1986, --1719, --1454, --1193, --935, --683, --435, --192, -45, -276, -501, -719, -930, -1134, -1331, -1519, -1700, -1873, -2038, -2194, -2342, -2481, -2611, -2733, -2846, -2950, -3046, -3133, -3211, -3281, -3343, -3396, -3441, -3477, -3506, -3527, -3541, -3547, -3546, -3538, -3523, -3502, -3474, -3441, -3401, -3357, -3307, -3252, -3192, -3128, -3060, -2989, -2913, -2835, -2753, -2669, -2583, -2494, -2403, -2311, -2218, -2124, -2028, -1933, -1837, -1741, -1645, -1550, -1455, -1361, -1268, -1176, -1086, -997, -910, -825, -741, -660, -581, -504, -429, -357, -287, -220, -156, -94, -35, --22, --75, --126, --175, --220, --263, --303, --341, --375, --408, --437, --464, --489, --511, --531, --548, --564, --577, --588, --597, --604, --610, --613, --615, --616, --614, --612, --608, --603, --597, --590, --582, --573, --563, --553, --542, --530, --518, --506, --493, --480, --466, --453, --439, --425, --411, --398, --384, --370, --357, --344, --331, --318, --305, --293, --281, --269, --258, --247, --237, --227, --217, --208, --199, --190, --182, --174, --167, --160, --154, --147, --142, --136, --131, --126, --121, --117, --113, --109, --106, --102, --99, --96, --93, --90, --87, --85, --82, --80, --78, --76, --74, --72, --70, --68, --66, --64, --62, --60, --58, --57, --55, --53, --51, --50, --48, --46, --45, --43, --41, --40, --38, --36, --35, --33, --31, --30, --28, --27, --25, --24, --22, --21, --20, --18, --17, --16, --15, --13, --12, --11, --10, --9, --9, --8, --7, --6, -}; -} diff --git a/services/audioflinger/audio-resampler/filter_coefficients.h b/services/audioflinger/audio-resampler/filter_coefficients.h new file mode 100644 index 0000000..bf70c63 --- /dev/null +++ b/services/audioflinger/audio-resampler/filter_coefficients.h @@ -0,0 +1,285 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include + +namespace android { + +// cmd-line: fir -l 7 -s 48000 -c 23400 -n 16 -b 9.62 +const int32_t up_sampler_filter_coefficients[] __attribute__ ((aligned (32))) = { + 0x7ccccccd, 0x0323eb7f, 0xfd086246, 0x02b2aa5c, 0xfda45e2c, 0x01fa5183, 0xfe694e12, 0x0137e672, 0xff1c87d3, 0x009ce6d8, 0xff9a68b0, 0x003d150d, 0xffde727a, 0x00106595, 0xfff93679, 0x00021fc5, + 0x7cc9b757, 0x022ac835, 0xfd7e3a71, 0x026b7da1, 0xfdd2b905, 0x01db7c90, 0xfe7db77c, 0x012aa7bf, 0xff24dc32, 0x0097dfc9, 0xff9d4ae9, 0x003b8742, 0xffdf38e5, 0x00100be5, 0xfff959f5, 0x0002144b, + 0x7cc0773c, 0x01354bc1, 0xfdf365e8, 0x0224726d, 0xfe011d2e, 0x01bc908b, 0xfe923a2b, 0x011d528d, 0xff2d426f, 0x0092cbc0, 0xffa035cc, 0x0039f42e, 0xffe00236, 0x000fb0d2, 0xfff97dfa, 0x000208b0, + 0x7cb10d52, 0x0043843f, 0xfe67d5a8, 0x01dd92df, 0xfe2f83c1, 0x019d9230, 0xfea6d2e5, 0x010fe901, 0xff35b924, 0x008dab9d, 0xffa328d4, 0x00385c1d, 0xffe0ce46, 0x000f5471, 0xfff9a27f, 0x0001fcf5, + 0x7c9b7afd, 0xff557f58, 0xfedb7ae9, 0x0196e8fe, 0xfe5de5e3, 0x017e8635, 0xfebb7e75, 0x01026d40, 0xff3e3eed, 0x0088803e, 0xffa6237a, 0x0036bf58, 0xffe19cec, 0x000ef6d4, 0xfff9c77d, 0x0001f11e, + 0x7c7fc22f, 0xfe6b4a44, 0xff4e471d, 0x01507eb8, 0xfe8c3cc3, 0x015f714d, 0xfed039a8, 0x00f4e16f, 0xff46d266, 0x00834a83, 0xffa9253b, 0x00351e2d, 0xffe26e01, 0x000e980f, 0xfff9eceb, 0x0001e52e, + 0x7c5de56a, 0xfd84f1c8, 0xffc02bf2, 0x010a5de2, 0xfeba819d, 0x01405821, 0xfee5014c, 0x00e747b0, 0xff4f722b, 0x007e0b4b, 0xffac2d8f, 0x003378e7, 0xffe3415d, 0x000e3834, 0xfffa12c0, 0x0001d927, + 0x7c35e7bb, 0xfca28234, 0x00311b54, 0x00c49034, 0xfee8adba, 0x01213f58, 0xfef9d232, 0x00d9a226, 0xff581cd8, 0x0078c375, 0xffaf3bf2, 0x0031cfd1, 0xffe416d8, 0x000dd758, 0xfffa38f5, 0x0001cd0d, + 0x7c07ccbe, 0xfbc40766, 0x00a1076e, 0x007f1f4b, 0xff16ba71, 0x01022b90, 0xff0ea931, 0x00cbf2f0, 0xff60d10b, 0x007373de, 0xffb24fde, 0x00302337, 0xffe4ee4b, 0x000d758d, 0xfffa5f81, 0x0001c0e1, + 0x7bd3989d, 0xfae98cc5, 0x010fe2ab, 0x003a14a6, 0xff44a128, 0x00e3215e, 0xff238322, 0x00be3c2d, 0xff698d62, 0x006e1d66, 0xffb568ce, 0x002e7363, 0xffe5c78d, 0x000d12e6, 0xfffa865d, 0x0001b4a8, + 0x7b99500c, 0xfa131d41, 0x017d9fb8, 0xfff579a3, 0xff725b54, 0x00c42551, 0xff385ce3, 0x00b07ff8, 0xff72507e, 0x0068c0e9, 0xffb8863e, 0x002cc0a2, 0xffe6a277, 0x000caf76, 0xfffaad81, 0x0001a863, + 0x7b58f84d, 0xf940c355, 0x01ea3184, 0xffb15783, 0xff9fe27d, 0x00a53bed, 0xff4d3358, 0x00a2c06b, 0xff7b18fe, 0x00635f45, 0xffbba7aa, 0x002b0b3d, 0xffe77ee2, 0x000c4b50, 0xfffad4e4, 0x00019c15, + 0x7b12972d, 0xf8728902, 0x02558b43, 0xff6db764, 0xffcd303b, 0x008669ae, 0xff620368, 0x0094ff9b, 0xff83e586, 0x005df954, 0xffbecc8d, 0x00295380, 0xffe85ca7, 0x000be687, 0xfffafc7f, 0x00018fc1, + 0x7ac63304, 0xf7a877d4, 0x02bfa06d, 0xff2aa243, 0xfffa3e37, 0x0067b303, 0xff76ca02, 0x00873f9b, 0xff8cb4bb, 0x00588ff1, 0xffc1f465, 0x002799b3, 0xffe93b9e, 0x000b812d, 0xfffb244a, 0x0001836a, + 0x7a73d2b5, 0xf6e298db, 0x032864c1, 0xfee820f8, 0x00270631, 0x00491c54, 0xff8b841a, 0x0079827a, 0xff958542, 0x005323f7, 0xffc51eaf, 0x0025de22, 0xffea1ba2, 0x000b1b55, 0xfffb4c3e, 0x00017712, + 0x7a1b7daa, 0xf620f4b2, 0x038fcc44, 0xfea63c38, 0x005381fa, 0x002aa9fa, 0xffa02eac, 0x006bca44, 0xff9e55c6, 0x004db63c, 0xffc84ae9, 0x00242115, 0xffeafc8b, 0x000ab510, 0xfffb7452, 0x00016abb, + 0x79bd3bd8, 0xf5639376, 0x03f5cb46, 0xfe64fc93, 0x007fab77, 0x000c6043, 0xffb4c6b9, 0x005e1900, 0xffa724f0, 0x00484799, 0xffcb7893, 0x002262d6, 0xffebde33, 0x000a4e72, 0xfffb9c80, 0x00015e68, + 0x795915bc, 0xf4aa7cce, 0x045a565c, 0xfe246a72, 0x00ab7ca6, 0xffee4372, 0xffc9494b, 0x005070b0, 0xffaff16f, 0x0042d8e1, 0xffcea72c, 0x0020a3ad, 0xffecc075, 0x0009e78c, 0xfffbc4bf, 0x0001521b, + 0x78ef1457, 0xf3f5b7e4, 0x04bd6269, 0xfde48e17, 0x00d6ef99, 0xffd057bb, 0xffddb374, 0x0042d353, 0xffb8b9f3, 0x003d6aea, 0xffd1d635, 0x001ee3e1, 0xffeda32a, 0x00098070, 0xfffbed0a, 0x000145d7, + 0x787f4134, 0xf3454b6a, 0x051ee498, 0xfda56f9c, 0x0101fe7a, 0xffb2a145, 0xfff2024e, 0x003542e2, 0xffc17d30, 0x0037fe85, 0xffd50530, 0x001d23b9, 0xffee862e, 0x0009192f, 0xfffc1558, 0x0001399e, + 0x7809a65e, 0xf2993d95, 0x057ed264, 0xfd6716f2, 0x012ca389, 0xff952429, 0x000632fa, 0x0027c151, 0xffca39dd, 0x00329483, 0xffd833a0, 0x001b637e, 0xffef695c, 0x0008b1db, 0xfffc3da2, 0x00012d72, + 0x778e4e68, 0xf1f19421, 0x05dd218f, 0xfd298be0, 0x0156d920, 0xff77e470, 0x001a42a4, 0x001a508e, 0xffd2eeb3, 0x002d2db0, 0xffdb6109, 0x0019a373, 0xfff04c8f, 0x00084a86, 0xfffc65e2, 0x00012155, + 0x770d4466, 0xf14e544f, 0x0639c82d, 0xfcecd602, 0x018099b2, 0xff5ae614, 0x002e2e82, 0x000cf281, 0xffdb9a70, 0x0027cada, 0xffde8cf1, 0x0017e3df, 0xfff12fa3, 0x0007e33f, 0xfffc8e11, 0x0001154a, + 0x768693ec, 0xf0af82e4, 0x0694bca0, 0xfcb0fcca, 0x01a9dfcc, 0xff3e2d01, 0x0041f3d2, 0xffffa90e, 0xffe43bd5, 0x00226ccb, 0xffe1b6dd, 0x00162507, 0xfff21275, 0x00077c17, 0xfffcb628, 0x00010952, + 0x75fa4911, 0xf015242b, 0x06edf595, 0xfc76077b, 0x01d2a615, 0xff21bd11, 0x00558fdc, 0xfff27611, 0xffecd1a6, 0x001d144a, 0xffe4de56, 0x0014672d, 0xfff2f4e0, 0x00071520, 0xfffcde20, 0x0000fd6f, + 0x75687068, 0xef7f3bf5, 0x07456a0e, 0xfc3bfd2e, 0x01fae74e, 0xff059a0e, 0x0068fff3, 0xffe55b60, 0xfff55aae, 0x0017c21c, 0xffe802e6, 0x0012aa95, 0xfff3d6c3, 0x0006ae6a, 0xfffd05f3, 0x0000f1a4, + 0x74d11703, 0xeeedcd98, 0x079b1158, 0xfc02e4cc, 0x02229e57, 0xfee9c7af, 0x007c4177, 0xffd85ac9, 0xfffdd5b8, 0x00127704, 0xffeb2416, 0x0010ef82, 0xfff4b7fb, 0x00064804, 0xfffd2d9b, 0x0000e5f3, + 0x74344a70, 0xee60dbee, 0x07eee314, 0xfbcac510, 0x0249c629, 0xfece499d, 0x008f51cf, 0xffcb7615, 0x00064197, 0x000d33c3, 0xffee4174, 0x000f3633, 0xfff59866, 0x0005e1fe, 0xfffd5511, 0x0000da5c, + 0x739218b8, 0xedd86958, 0x0840d732, 0xfb93a486, 0x027059da, 0xfeb3236b, 0x00a22e71, 0xffbeaf06, 0x000e9d1f, 0x0007f915, 0xfff15a8d, 0x000d7eea, 0xfff677e2, 0x00057c68, 0xfffd7c4f, 0x0000cee3, + 0x72ea905a, 0xed5477be, 0x0890e5f7, 0xfb5d898c, 0x029654a0, 0xfe98589b, 0x00b4d4dd, 0xffb20754, 0x0016e72c, 0x0002c7b6, 0xfff46ef1, 0x000bc9e6, 0xfff75650, 0x00051750, 0xfffda350, 0x0000c388, + 0x723dc051, 0xecd5088e, 0x08df07f6, 0xfb287a4d, 0x02bbb1cc, 0xfe7dec9c, 0x00c7429f, 0xffa580b1, 0x001f1e9b, 0xfffda05c, 0xfff77e31, 0x000a1765, 0xfff8338e, 0x0004b2c7, 0xfffdca0d, 0x0000b84d, + 0x718bb80b, 0xec5a1cbc, 0x092b3617, 0xfaf47cc4, 0x02e06ccf, 0xfe63e2cc, 0x00d97550, 0xff991cc9, 0x00274253, 0xfff883be, 0xfffa87df, 0x000867a5, 0xfff90f7c, 0x00044eda, 0xfffdf080, 0x0000ad34, + 0x70d4876b, 0xebe3b4c5, 0x09756994, 0xfac196bb, 0x03048139, 0xfe4a3e70, 0x00eb6a95, 0xff8cdd3c, 0x002f513a, 0xfff3728d, 0xfffd8b92, 0x0006bae1, 0xfff9e9fd, 0x0003eb98, 0xfffe16a6, 0x0000a23f, + 0x70183ec5, 0xeb71d0ab, 0x09bd9bfb, 0xfa8fcdca, 0x0327eab8, 0xfe3102bd, 0x00fd2022, 0xff80c3a4, 0x00374a40, 0xffee6d78, 0x000088df, 0x00051157, 0xfffac2f0, 0x0003890e, 0xfffe3c76, 0x0000976e, + 0x6f56eee1, 0xeb046ffc, 0x0a03c72b, 0xfa5f2755, 0x034aa51b, 0xfe1832d4, 0x010e93b5, 0xff74d194, 0x003f2c57, 0xffe97529, 0x00037f60, 0x00036b3f, 0xfffb9a38, 0x0003274c, 0xfffe61ee, 0x00008cc4, + 0x6e90a8f2, 0xea9b91cc, 0x0a47e559, 0xfa2fa890, 0x036cac52, 0xfdffd1bd, 0x011fc31c, 0xff690894, 0x0046f679, 0xffe48a4a, 0x00066eae, 0x0001c8d2, 0xfffc6fb8, 0x0002c65d, 0xfffe8707, 0x00008241, + 0x6dc57e9b, 0xea3734bb, 0x0a89f10c, 0xfa015679, 0x038dfc6c, 0xfde7e26f, 0x0130ac31, 0xff5d6a24, 0x004ea7a3, 0xffdfad7f, 0x00095666, 0x00002a4a, 0xfffd4352, 0x00026650, 0xfffeabbd, 0x000077e8, + 0x6cf581e8, 0xe9d756f3, 0x0ac9e521, 0xf9d435dc, 0x03ae919a, 0xfdd067ca, 0x01414cdd, 0xff51f7bb, 0x00563edb, 0xffdadf69, 0x000c3627, 0xfffe8fdc, 0xfffe14eb, 0x00020730, 0xfffed00a, 0x00006db9, + 0x6c20c550, 0xe97bf627, 0x0b07bcc6, 0xf9a84b50, 0x03ce682d, 0xfdb96498, 0x0151a317, 0xff46b2c7, 0x005dbb29, 0xffd620a6, 0x000f0d91, 0xfffcf9be, 0xfffee466, 0x0001a90b, 0xfffef3ea, 0x000063b5, + 0x6b475bb0, 0xe9250f99, 0x0b437380, 0xf97d9b37, 0x03ed7c9a, 0xfda2db8c, 0x0161ace5, 0xff3b9cad, 0x00651b9c, 0xffd171d1, 0x0011dc47, 0xfffb6825, 0xffffb1aa, 0x00014bed, 0xffff1759, 0x000059dd, + 0x6a69584a, 0xe8d2a017, 0x0b7d0525, 0xf95429c0, 0x040bcb77, 0xfd8ccf46, 0x01716859, 0xff30b6c8, 0x006c5f4b, 0xffccd380, 0x0014a1ee, 0xfff9db44, 0x00007c9c, 0x0000efe1, 0xffff3a53, 0x00005033, + 0x6986cec4, 0xe884a3fb, 0x0bb46de2, 0xf92bfae4, 0x0429517b, 0xfd77424c, 0x0180d397, 0xff260269, 0x00738551, 0xffc84645, 0x00175e2d, 0xfff8534d, 0x00014521, 0x000094f3, 0xffff5cd2, 0x000046b8, + 0x689fd324, 0xe83b1731, 0x0be9aa34, 0xf9051266, 0x04460b81, 0xfd62370e, 0x018fecd1, 0xff1b80da, 0x007a8cd0, 0xffc3cab1, 0x001a10ad, 0xfff6d070, 0x00020b23, 0x00003b2e, 0xffff7ed3, 0x00003d6c, + 0x67b479cf, 0xe7f5f531, 0x0c1cb6ef, 0xf8df73d6, 0x0461f688, 0xfd4dafe6, 0x019eb246, 0xff113358, 0x008174ef, 0xffbf614e, 0x001cb91a, 0xfff552de, 0x0002ce87, 0xffffe29d, 0xffffa052, 0x00003450, + 0x66c4d787, 0xe7b53908, 0x0c4d913a, 0xf8bb228c, 0x047d0fb1, 0xfd39af17, 0x01ad2249, 0xff071b16, 0x00883cdc, 0xffbb0aa3, 0x001f5723, 0xfff3dac3, 0x00038f37, 0xffff8b4b, 0xffffc14b, 0x00002b66, + 0x65d10168, 0xe778dd50, 0x0c7c368d, 0xf89821ac, 0x0497543f, 0xfd2636ca, 0x01bb3b37, 0xfefd3941, 0x008ee3cd, 0xffb6c735, 0x0021ea76, 0xfff2684e, 0x00044d1b, 0xffff3540, 0xffffe1bc, 0x000022ad, + 0x64d90ce7, 0xe740dc3c, 0x0ca8a4b7, 0xf8767422, 0x04b0c19a, 0xfd134913, 0x01c8fb81, 0xfef38ef6, 0x009568fc, 0xffb29782, 0x002472c8, 0xfff0fba9, 0x0005081f, 0xfffee088, 0x0000019f, 0x00001a28, + 0x63dd0fcd, 0xe70d2f8d, 0x0cd2d9d5, 0xf8561ca7, 0x04c9554e, 0xfd00e7ec, 0x01d661a6, 0xfeea1d4c, 0x009bcbab, 0xffae7c06, 0x0026efcc, 0xffef94fe, 0x0005c02c, 0xfffe8d2c, 0x000020f3, 0x000011d5, + 0x62dd2039, 0xe6ddd09f, 0x0cfad45a, 0xf8371dbb, 0x04e10d0a, 0xfcef153a, 0x01e36c34, 0xfee0e54e, 0x00a20b23, 0xffaa7538, 0x0029613a, 0xffee3477, 0x0006752d, 0xfffe3b35, 0x00003fb3, 0x000009b6, + 0x61d95497, 0xe6b2b862, 0x0d209309, 0xf81979ab, 0x04f7e6a2, 0xfcddd2c7, 0x01f019cb, 0xfed7e7fd, 0x00a826b2, 0xffa6838c, 0x002bc6cd, 0xffecda3b, 0x0007270f, 0xfffdeaaa, 0x00005ddd, 0x000001cc, + 0x60d1c3a6, 0xe68bdf5e, 0x0d4414f9, 0xf7fd328c, 0x050de00d, 0xfccd2246, 0x01fc691b, 0xfecf2650, 0x00ae1dae, 0xffa2a770, 0x002e2040, 0xffeb866f, 0x0007d5bf, 0xfffd9b96, 0x00007b6f, 0xfffffa17, + 0x5fc68470, 0xe6693db5, 0x0d65598f, 0xf7e24a3c, 0x0522f766, 0xfcbd0551, 0x020858e2, 0xfec6a130, 0x00b3ef73, 0xff9ee150, 0x00306d52, 0xffea3939, 0x0008812a, 0xfffd4dff, 0x00009865, 0xfffff297, + 0x5eb7ae46, 0xe64acb24, 0x0d846084, 0xf7c8c267, 0x05372aee, 0xfcad7d6b, 0x0213e7f0, 0xfebe5980, 0x00b99b65, 0xff9b3192, 0x0032adc4, 0xffe8f2bb, 0x0009293e, 0xfffd01ee, 0x0000b4bd, 0xffffeb4c, + 0x5da558c5, 0xe6307f05, 0x0da129df, 0xf7b09c7f, 0x054a7909, 0xfc9e8bfd, 0x021f1526, 0xfeb65015, 0x00bf20ee, 0xff979898, 0x0034e15b, 0xffe7b317, 0x0009cdeb, 0xfffcb769, 0x0000d074, 0xffffe438, + 0x5c8f9bcb, 0xe61a504f, 0x0dbbb5f6, 0xf799d9c4, 0x055ce03f, 0xfc903258, 0x0229df75, 0xfeae85bb, 0x00c47f7f, 0xff9416c1, 0x003707dc, 0xffe67a6f, 0x000a6f20, 0xfffc6e78, 0x0000eb89, 0xffffdd5a, + 0x5b768f7a, 0xe6083599, 0x0dd40571, 0xf7847b3d, 0x056e5f3d, 0xfc8271b4, 0x023445dd, 0xfea6fb32, 0x00c9b691, 0xff90ac66, 0x00392111, 0xffe548e0, 0x000b0cce, 0xfffc2720, 0x000105f9, 0xffffd6b2, + 0x5a5a4c32, 0xe5fa2519, 0x0dea1943, 0xf77081be, 0x057ef4d3, 0xfc754b32, 0x023e4772, 0xfe9fb12e, 0x00cec5a1, 0xff8d59dd, 0x003b2cc5, 0xffe41e88, 0x000ba6e5, 0xfffbe169, 0x00011fc3, 0xffffd041, + 0x593aea93, 0xe5f014aa, 0x0dfdf2ae, 0xf75dede5, 0x058e9ff8, 0xfc68bfd7, 0x0247e354, 0xfe98a85b, 0x00d3ac38, 0xff8a1f77, 0x003d2ac6, 0xffe2fb83, 0x000c3d59, 0xfffb9d59, 0x000138e4, 0xffffca06, + 0x58188376, 0xe5e9f9ca, 0x0e0f9342, 0xf74cc01c, 0x059d5fc5, 0xfc5cd092, 0x025118b8, 0xfe91e159, 0x00d869e1, 0xff86fd81, 0x003f1ae4, 0xffe1dfec, 0x000cd01b, 0xfffb5af3, 0x0001515c, 0xffffc402, + 0x56f32fea, 0xe5e7c99e, 0x0e1efcdb, 0xf73cf898, 0x05ab3377, 0xfc517e38, 0x0259e6e1, 0xfe8b5cba, 0x00dcfe32, 0xff83f443, 0x0040fcf3, 0xffe0cbdc, 0x000d5f1f, 0xfffb1a3f, 0x00016928, 0xffffbe35, + 0x55cb0935, 0xe5e978f0, 0x0e2c319d, 0xf72e9758, 0x05b81a70, 0xfc46c987, 0x02624d23, 0xfe851b09, 0x00e168c5, 0xff810401, 0x0042d0c9, 0xffdfbf6b, 0x000dea5a, 0xfffadb40, 0x00018048, 0xffffb89f, + 0x54a028d0, 0xe5eefc35, 0x0e3733fc, 0xf7219c2a, 0x05c41435, 0xfc3cb323, 0x026a4ae5, 0xfe7f1cc4, 0x00e5a93c, 0xff7e2cfb, 0x0044963d, 0xffdebaaf, 0x000e71c1, 0xfffa9dfa, 0x000196ba, 0xffffb340, + 0x5372a862, 0xe5f8478d, 0x0e4006b2, 0xf71606a6, 0x05cf2070, 0xfc333b97, 0x0271df9c, 0xfe79625e, 0x00e9bf43, 0xff7b6f6c, 0x00464d2b, 0xffddbdbd, 0x000ef549, 0xfffa6273, 0x0001ac7d, 0xffffae17, + 0x5242a1c1, 0xe6054ec6, 0x0e46acc4, 0xf70bd632, 0x05d93eee, 0xfc2a6356, 0x02790ace, 0xfe73ec40, 0x00edaa88, 0xff78cb8c, 0x0047f571, 0xffdcc8a9, 0x000f74e9, 0xfffa28ad, 0x0001c191, 0xffffa924, + 0x51102eec, 0xe616055a, 0x0e4b297c, 0xf7030a01, 0x05e26f9f, 0xfc222abb, 0x027fcc12, 0xfe6ebac6, 0x00f16ac4, 0xff76418b, 0x00498eed, 0xffdbdb84, 0x000ff098, 0xfff9f0ac, 0x0001d5f4, 0xffffa467, + 0x4fdb6a09, 0xe62a5e76, 0x0e4d806f, 0xf6fba113, 0x05eab296, 0xfc1a9208, 0x02862311, 0xfe69ce43, 0x00f4ffb6, 0xff73d199, 0x004b1984, 0xffdaf65e, 0x0010684e, 0xfff9ba73, 0x0001e9a7, 0xffff9fe0, + 0x4ea46d66, 0xe6424cf8, 0x0e4db575, 0xf6f59a36, 0x05f20809, 0xfc139968, 0x028c0f83, 0xfe6526fe, 0x00f86924, 0xff717bdf, 0x004c951b, 0xffda1948, 0x0010dc05, 0xfff98604, 0x0001fca8, 0xffff9b8f, + 0x4d6b536f, 0xe65dc373, 0x0e4bccac, 0xf6f0f407, 0x05f87053, 0xfc0d40ec, 0x0291912f, 0xfe60c533, 0x00fba6da, 0xff6f4083, 0x004e0199, 0xffd9444e, 0x00114bb4, 0xfff95363, 0x00020ef7, 0xffff9773, + 0x4c3036b2, 0xe67cb42f, 0x0e47ca78, 0xf6edacf2, 0x05fdebee, 0xfc07888e, 0x0296a7f0, 0xfe5ca913, 0x00feb8ad, 0xff6d1fa5, 0x004f5ee9, 0xffd8777d, 0x0011b757, 0xfff92290, 0x00022095, 0xffff938c, + 0x4af331d9, 0xe69f112f, 0x0e41b37c, 0xf6ebc332, 0x06027b78, 0xfc027031, 0x029b53af, 0xfe58d2c5, 0x01019e78, 0xff6b1961, 0x0050acf7, 0xffd7b2e0, 0x00121ee9, 0xfff8f38e, 0x00023181, 0xffff8fd9, + 0x49b45fa8, 0xe6c4cc2e, 0x0e398c9f, 0xf6eb34d4, 0x06061fb2, 0xfbfdf79e, 0x029f9466, 0xfe554265, 0x0104581c, 0xff692dd2, 0x0051ebb4, 0xffd6f67f, 0x00128265, 0xfff8c65d, 0x000241bb, 0xffff8c5a, + 0x4873daf7, 0xe6edd6a4, 0x0e2f5b0b, 0xf6ebffb2, 0x0608d97c, 0xfbfa1e88, 0x02a36a1e, 0xfe51f802, 0x0106e583, 0xff675d09, 0x00531b12, 0xffd64264, 0x0012e1c8, 0xfff89b00, 0x00025143, 0xffff890e, + 0x4731beb7, 0xe71a21c7, 0x0e232425, 0xf6ee217b, 0x060aa9da, 0xfbf6e48c, 0x02a6d4f0, 0xfe4ef3a4, 0x0109469d, 0xff65a718, 0x00543b04, 0xffd59695, 0x00133d0e, 0xfff87176, 0x0002601b, 0xffff85f5, + 0x45ee25e7, 0xe7499e8f, 0x0e14ed93, 0xf6f197ad, 0x060b91ee, 0xfbf4492d, 0x02a9d508, 0xfe4c3546, 0x010b7b61, 0xff640c08, 0x00554b83, 0xffd4f316, 0x00139436, 0xfff849c0, 0x00026e41, 0xffff830e, + 0x44a92b96, 0xe77c3db4, 0x0e04bd39, 0xf6f65f9b, 0x060b92ff, 0xfbf24bd9, 0x02ac6a9e, 0xfe49bcd9, 0x010d83cb, 0xff628be3, 0x00564c88, 0xffd457ec, 0x0013e73e, 0xfff823dd, 0x00027bb8, 0xffff805a, + 0x4362eadc, 0xe7b1efb4, 0x0df29936, 0xf6fc766a, 0x060aae6e, 0xfbf0ebe7, 0x02ae95fb, 0xfe478a42, 0x010f5fe2, 0xff6126a9, 0x00573e0f, 0xffd3c519, 0x00143626, 0xfff7ffce, 0x0002887f, 0xffff7dd6, + 0x421b7edf, 0xe7eaa4d4, 0x0dde87e2, 0xf703d912, 0x0608e5c2, 0xfbf02896, 0x02b05779, 0xfe459d5e, 0x01110faf, 0xff5fdc5b, 0x00582016, 0xffd33a9e, 0x001480ec, 0xfff7dd92, 0x00029497, 0xffff7b82, + 0x40d302c5, 0xe8264d21, 0x0dc88fd2, 0xf70c8461, 0x06063a9d, 0xfbf00112, 0x02b1af7f, 0xfe43f5ff, 0x01129344, 0xff5eacf3, 0x0058f29f, 0xffd2b87c, 0x0014c792, 0xfff7bd28, 0x0002a002, 0xffff795f, + 0x3f8991bd, 0xe864d874, 0x0db0b7d1, 0xf71674fa, 0x0602aec3, 0xfbf0746e, 0x02b29e84, 0xfe4293ec, 0x0113eabb, 0xff5d9867, 0x0059b5ad, 0xffd23eaf, 0x00150a19, 0xfff79e8f, 0x0002aac0, 0xffff776a, + 0x3e3f46f2, 0xe8a63671, 0x0d9706e1, 0xf721a756, 0x05fe4414, 0xfbf181a9, 0x02b3250f, 0xfe4176e2, 0x01151632, 0xff5c9eaa, 0x005a6946, 0xffd1cd37, 0x00154883, 0xfff781c5, 0x0002b4d2, 0xffff75a3, + 0x3cf43d8f, 0xe8ea568f, 0x0d7b843b, 0xf72e17c4, 0x05f8fc8f, 0xfbf327ab, 0x02b343b5, 0xfe409e95, 0x011615ce, 0xff5bbfaa, 0x005b0d72, 0xffd1640e, 0x001582d3, 0xfff766c8, 0x0002be3b, 0xffff740a, + 0x3ba890b9, 0xe9312813, 0x0d5e3749, 0xf73bc26b, 0x05f2da52, 0xfbf56549, 0x02b2fb1a, 0xfe400aae, 0x0116e9bc, 0xff5afb53, 0x005ba23b, 0xffd1032f, 0x0015b90b, 0xfff74d97, 0x0002c6fa, 0xffff729e, + 0x3a5c5b8e, 0xe97a9a17, 0x0d3f27ab, 0xf74aa34c, 0x05ebdf97, 0xfbf83941, 0x02b24bf1, 0xfe3fbacd, 0x0117922f, 0xff5a5189, 0x005c27af, 0xffd0aa93, 0x0015eb2f, 0xfff7362f, 0x0002cf12, 0xffff715d, + 0x390fb920, 0xe9c69b8c, 0x0d1e5d32, 0xf75ab63f, 0x05e40eb3, 0xfbfba23f, 0x02b136f9, 0xfe3fae87, 0x01180f5d, 0xff59c230, 0x005c9ddc, 0xffd05a33, 0x00161944, 0xfff7208d, 0x0002d684, 0xffff7047, + 0x37c2c474, 0xea151b3a, 0x0cfbdfdd, 0xf76bf6f7, 0x05db6a19, 0xfbff9ed7, 0x02afbd02, 0xfe3fe569, 0x01186187, 0xff594d27, 0x005d04d4, 0xffd01205, 0x0016434f, 0xfff70caf, 0x0002dd53, 0xffff6f5c, + 0x36759880, 0xea6607c4, 0x0cd7b7dd, 0xf77e6103, 0x05d1f459, 0xfc042d8e, 0x02addee8, 0xfe405ef6, 0x011888f2, 0xff58f249, 0x005d5cab, 0xffcfd1ff, 0x00166956, 0xfff6fa92, 0x0002e37e, 0xffff6e99, + 0x35285026, 0xeab94fa9, 0x0cb1ed8c, 0xf791efcb, 0x05c7b01a, 0xfc094cd2, 0x02ab9d96, 0xfe411aa8, 0x011885e7, 0xff58b16c, 0x005da575, 0xffcf9a15, 0x00168b5e, 0xfff6ea31, 0x0002e90a, 0xffff6dff, + 0x33db0631, 0xeb0ee148, 0x0c8a8973, 0xf7a69e96, 0x05bca021, 0xfc0efafe, 0x02a8fa03, 0xfe4217ef, 0x011858b9, 0xff588a65, 0x005ddf4c, 0xffcf6a3b, 0x0016a96f, 0xfff6db89, 0x0002edf6, 0xffff6d8d, + 0x328dd556, 0xeb66aae0, 0x0c619444, 0xf7bc6889, 0x05b0c74b, 0xfc15365c, 0x02a5f535, 0xfe435633, 0x011801be, 0xff587d03, 0x005e0a48, 0xffcf4262, 0x0016c390, 0xfff6ce97, 0x0002f246, 0xffff6d40, + 0x3140d82e, 0xebc09a94, 0x0c3716da, 0xf7d348a4, 0x05a42890, 0xfc1bfd22, 0x02a2903e, 0xfe44d4d3, 0x01178152, 0xff588913, 0x005e2687, 0xffcf227b, 0x0016d9c9, 0xfff6c356, 0x0002f5fc, 0xffff6d1a, + 0x2ff42933, 0xec1c9e6d, 0x0c0b1a37, 0xf7eb39cc, 0x0596c6ff, 0xfc234d75, 0x029ecc3c, 0xfe469325, 0x0116d7d7, 0xff58ae5d, 0x005e3427, 0xffcf0a77, 0x0016ec22, 0xfff6b9c1, 0x0002f919, 0xffff6d17, + 0x2ea7e2c0, 0xec7aa45b, 0x0bdda783, 0xf80436c0, 0x0588a5bf, 0xfc2b2567, 0x029aaa5a, 0xfe489077, 0x011605b5, 0xff58eca8, 0x005e3347, 0xffcefa44, 0x0016faa5, 0xfff6b1d5, 0x0002fba0, 0xffff6d38, + 0x2d5c1f0e, 0xecda9a39, 0x0baec80a, 0xf81e3a25, 0x0579c812, 0xfc3382fb, 0x02962bd1, 0xfe4acc0e, 0x01150b5a, 0xff5943b4, 0x005e240a, 0xffcef1cf, 0x0017055b, 0xfff6ab8c, 0x0002fd94, 0xffff6d7c, + 0x2c10f82d, 0xed3c6dce, 0x0b7e853c, 0xf8393e81, 0x056a314b, 0xfc3c6420, 0x029151e3, 0xfe4d4526, 0x0113e937, 0xff59b340, 0x005e0694, 0xffcef106, 0x00170c4f, 0xfff6a6e2, 0x0002fef6, 0xffff6de2, + 0x2ac68807, 0xeda00cd1, 0x0b4ce8a8, 0xf8553e3c, 0x0559e4da, 0xfc45c6b6, 0x028c1de0, 0xfe4ffaf6, 0x01129fc5, 0xff5a3b09, 0x005ddb0b, 0xffcef7d4, 0x00170f8a, 0xfff6a3d0, 0x0002ffc9, 0xffff6e67, + 0x297ce85a, 0xee0564e8, 0x0b19fbfe, 0xf87233a4, 0x0548e63f, 0xfc4fa88f, 0x02869122, 0xfe52ecab, 0x01112f81, 0xff5adac6, 0x005da198, 0xffcf0623, 0x00170f18, 0xfff6a252, 0x00030010, 0xffff6f0d, + 0x283432b9, 0xee6c63ad, 0x0ae5c90b, 0xf89018eb, 0x05373912, 0xfc5a076a, 0x0280ad0f, 0xfe561969, 0x010f98eb, 0xff5b922d, 0x005d5a62, 0xffcf1bde, 0x00170b04, 0xfff6a262, 0x0002ffcd, 0xffff6fd1, + 0x26ec8083, 0xeed4f6b0, 0x0ab059bc, 0xf8aee828, 0x0524e100, 0xfc64e0f9, 0x027a7318, 0xfe598050, 0x010ddc8c, 0xff5c60ee, 0x005d0597, 0xffcf38ec, 0x0017035a, 0xfff6a3f9, 0x0002ff03, 0xffff70b2, + 0x25a5eae8, 0xef3f0b78, 0x0a79b814, 0xf8ce9b5d, 0x0511e1c6, 0xfc7032de, 0x0273e4b8, 0xfe5d2075, 0x010bfaee, 0xff5d46bb, 0x005ca363, 0xffcf5d36, 0x0016f828, 0xfff6a713, 0x0002fdb4, 0xffff71b0, + 0x24608ae2, 0xefaa8f87, 0x0a41ee32, 0xf8ef2c71, 0x04fe3f39, 0xfc7bfaad, 0x026d0374, 0xfe60f8ea, 0x0109f4a2, 0xff5e433e, 0x005c33f6, 0xffcf88a2, 0x0016e979, 0xfff6aba9, 0x0002fbe4, 0xffff72c9, + 0x231c7932, 0xf017705a, 0x0a09064e, 0xf9109535, 0x04e9fd3c, 0xfc8835ed, 0x0265d0dd, 0xfe6508b6, 0x0107ca3c, 0xff5f5621, 0x005bb77f, 0xffcfbb17, 0x0016d75b, 0xfff6b1b4, 0x0002f995, 0xffff73fc, + 0x21d9ce63, 0xf0859b6e, 0x09cf0ab4, 0xf932cf65, 0x04d51fc6, 0xfc94e216, 0x025e4e8b, 0xfe694edd, 0x01057c57, 0xff607f0b, 0x005b2e31, 0xffcff478, 0x0016c1dc, 0xfff6b92d, 0x0002f6c9, 0xffff7549, + 0x2098a2bf, 0xf0f4fe3d, 0x099405c6, 0xf955d4a7, 0x04bfaadf, 0xfca1fc96, 0x02567e22, 0xfe6dca58, 0x01030b8e, 0xff61bd9f, 0x005a9840, 0xffd034ac, 0x0016a90a, 0xfff6c20f, 0x0002f385, 0xffff76ae, + 0x1f590e55, 0xf1658649, 0x095801f8, 0xf9799e8f, 0x04a9a29e, 0xfcaf82ca, 0x024e614c, 0xfe727a1f, 0x01007885, 0xff631180, 0x0059f5e1, 0xffd07b95, 0x00168cf2, 0xfff6cc52, 0x0002efca, 0xffff782a, + 0x1e1b28f2, 0xf1d72114, 0x091b09d1, 0xf99e269e, 0x04930b2b, 0xfcbd7206, 0x0245f9bf, 0xfe775d1f, 0x00fdc3e0, 0xff647a4b, 0x0059474a, 0xffd0c915, 0x00166da5, 0xfff6d7f0, 0x0002eb9c, 0xffff79bc, + 0x1cdf0a20, 0xf249bc2c, 0x08dd27e6, 0xf9c36642, 0x047be8bc, 0xfccbc793, 0x023d4937, 0xfe7c7243, 0x00faee49, 0xff65f79e, 0x00588cb4, 0xffd11d0f, 0x00164b32, 0xfff6e4e1, 0x0002e6fe, 0xffff7b63, + 0x1ba4c923, 0xf2bd4523, 0x089e66dd, 0xf9e956da, 0x04643f95, 0xfcda80ad, 0x0234517a, 0xfe81b86d, 0x00f7f86e, 0xff678912, 0x0057c658, 0xffd17764, 0x001625a7, 0xfff6f31d, 0x0002e1f3, 0xffff7d1f, + 0x1a6c7cf9, 0xf331a99b, 0x085ed167, 0xfa0ff1b6, 0x044c1409, 0xfce99a86, 0x022b1455, 0xfe872e7c, 0x00f4e2ff, 0xff692e3f, 0x0056f471, 0xffd1d7f5, 0x0015fd15, 0xfff7029f, 0x0002dc7d, 0xffff7eed, + 0x19363c54, 0xf3a6d741, 0x081e7241, 0xfa373017, 0x04336a75, 0xfcf91246, 0x0221939d, 0xfe8cd349, 0x00f1aeb2, 0xff6ae6ba, 0x0056173b, 0xffd23ea1, 0x0015d18b, 0xfff7135d, 0x0002d6a0, 0xffff80cd, + 0x18021d9d, 0xf41cbbd3, 0x07dd5430, 0xfa5f0b30, 0x041a4744, 0xfd08e50c, 0x0217d12d, 0xfe92a5a7, 0x00ee5c3e, 0xff6cb218, 0x00552ef3, 0xffd2ab47, 0x0015a31b, 0xfff72551, 0x0002d060, 0xffff82bf, + 0x16d036eb, 0xf493451f, 0x079b8203, 0xfa877c29, 0x0400aeec, 0xfd190fed, 0x020dcee8, 0xfe98a466, 0x00eaec5e, 0xff6e8fe9, 0x00543bd8, 0xffd31dc7, 0x001571d5, 0xfff73873, 0x0002c9be, 0xffff84c0, + 0x15a09e09, 0xf50a610a, 0x0759068f, 0xfab07c1d, 0x03e6a5ee, 0xfd298ff6, 0x02038eb7, 0xfe9ece4f, 0x00e75fd1, 0xff707fbd, 0x00533e29, 0xffd395fd, 0x00153dca, 0xfff74cba, 0x0002c2be, 0xffff86d0, + 0x1473686d, 0xf581fd8b, 0x0715ecae, 0xfada0420, 0x03cc30d4, 0xfd3a622b, 0x01f9128a, 0xfea52227, 0x00e3b758, 0xff728121, 0x00523626, 0xffd413c9, 0x0015070b, 0xfff76220, 0x0002bb64, 0xffff88ee, + 0x1348ab3a, 0xf5fa08b5, 0x06d23f3d, 0xfb040d3b, 0x03b15431, 0xfd4b8389, 0x01ee5c55, 0xfeab9eb2, 0x00dff3b7, 0xff7493a2, 0x00512412, 0xffd49705, 0x0014cdab, 0xfff7789c, 0x0002b3b3, 0xffff8b19, + 0x12207b3e, 0xf67270b1, 0x068e091c, 0xfb2e906f, 0x039614a1, 0xfd5cf105, 0x01e36e14, 0xfeb242ac, 0x00dc15b4, 0xff76b6ca, 0x0050082f, 0xffd51f90, 0x001491b9, 0xfff79026, 0x0002abad, 0xffff8d50, + 0x10faecee, 0xf6eb23c6, 0x0649552a, 0xfb5986b6, 0x037a76c7, 0xfd6ea790, 0x01d849c7, 0xfeb90cce, 0x00d81e1a, 0xff78ea20, 0x004ee2c1, 0xffd5ad44, 0x00145349, 0xfff7a8b6, 0x0002a357, 0xffff8f92, + 0x0fd81464, 0xf7641059, 0x06042e45, 0xfb84e906, 0x035e7f4e, 0xfd80a411, 0x01ccf173, 0xfebffbd0, 0x00d40db3, 0xff7b2d2d, 0x004db40c, 0xffd63ffe, 0x0014126c, 0xfff7c245, 0x00029ab2, 0xffff91de, + 0x0eb80562, 0xf7dd24ef, 0x05be9f49, 0xfbb0b04e, 0x034232e6, 0xfd92e36c, 0x01c16720, 0xfec70e64, 0x00cfe54f, 0xff7d7f76, 0x004c7c55, 0xffd6d798, 0x0013cf36, 0xfff7dcc8, 0x000291c3, 0xffff9434, + 0x0d9ad348, 0xf856502d, 0x0578b30e, 0xfbdcd57a, 0x03259644, 0xfda5627e, 0x01b5acdd, 0xfece433a, 0x00cba5bc, 0xff7fe07f, 0x004b3be3, 0xffd773ed, 0x001389b7, 0xfff7f83a, 0x0002888c, 0xffff9691, + 0x0c80911b, 0xf8cf80de, 0x05327467, 0xfc095174, 0x0308ae24, 0xfdb81e22, 0x01a9c4bc, 0xfed598fe, 0x00c74fce, 0xff824fca, 0x0049f2fc, 0xffd814d7, 0x00134204, 0xfff81490, 0x00027f11, 0xffff98f5, + 0x0b69517e, 0xf948a5f0, 0x04ebee1c, 0xfc361d25, 0x02eb7f44, 0xfdcb132d, 0x019db0d0, 0xfedd0e5c, 0x00c2e457, 0xff84ccdb, 0x0048a1e7, 0xffd8ba31, 0x0012f82e, 0xfff831c3, 0x00027555, 0xffff9b60, + 0x0a5526b0, 0xf9c1ae7b, 0x04a52af2, 0xfc633173, 0x02ce0e67, 0xfdde3e6f, 0x01917334, 0xfee4a1fa, 0x00be642f, 0xff875731, 0x004748ed, 0xffd963d4, 0x0012ac48, 0xfff84fcb, 0x00026b5b, 0xffff9dd0, + 0x0944228e, 0xfa3a89be, 0x045e359f, 0xfc908746, 0x02b0604f, 0xfdf19cb9, 0x01850e00, 0xfeec527e, 0x00b9d02b, 0xff89ee4d, 0x0045e856, 0xffda1199, 0x00125e66, 0xfff86e9e, 0x00026126, 0xffffa045, + 0x08365690, 0xfab32723, 0x041718d2, 0xfcbe1789, 0x029279c4, 0xfe052ad4, 0x01788354, 0xfef41e8c, 0x00b52925, 0xff8c91ad, 0x0044806c, 0xffdac35a, 0x00120e9b, 0xfff88e35, 0x000256b9, 0xffffa2be, + 0x072bd3c5, 0xfb2b7641, 0x03cfdf29, 0xfcebdb26, 0x02745f8c, 0xfe18e58c, 0x016bd54f, 0xfefc04c6, 0x00b06ff7, 0xff8f40d0, 0x00431177, 0xffdb78ef, 0x0011bcf9, 0xfff8ae88, 0x00024c18, 0xffffa539, + 0x0624aad6, 0xfba366df, 0x03889336, 0xfd19cb0e, 0x02561670, 0xfe2cc9a7, 0x015f0612, 0xff0403cc, 0x00aba57c, 0xff91fb31, 0x00419bc2, 0xffdc3231, 0x00116994, 0xfff8cf8d, 0x00024146, 0xffffa7b7, + 0x0520ec00, 0xfc1ae8f2, 0x03413f7b, 0xfd47e035, 0x0237a337, 0xfe40d3ed, 0x015217c0, 0xff0c1a3c, 0x00a6ca90, 0xff94c04f, 0x00401f98, 0xffdceef9, 0x00111480, 0xfff8f13c, 0x00023645, 0xffffaa35, + 0x0420a716, 0xfc91eca1, 0x02f9ee68, 0xfd761395, 0x02190aa6, 0xfe550124, 0x01450c7f, 0xff1446b5, 0x00a1e00f, 0xff978fa6, 0x003e9d42, 0xffddaf1e, 0x0010bdcf, 0xfff9138e, 0x00022b19, 0xffffacb4, + 0x0323eb7f, 0xfd086246, 0x02b2aa5c, 0xfda45e2c, 0x01fa5183, 0xfe694e12, 0x0137e672, 0xff1c87d3, 0x009ce6d8, 0xff9a68b0, 0x003d150d, 0xffde727a, 0x00106595, 0xfff93679, 0x00021fc5, 0xffffaf33, +}; + +// cmd-line: fir -l 7 -s 44100 -c 19876 -n 16 -b 9.62 +const int32_t dn_sampler_filter_coefficients[] __attribute__ ((aligned (32))) = { + 0x736144b5, 0x0c333a22, 0xf4fca390, 0x09424904, 0xf8c92a41, 0x052ac04c, 0xfca4fc64, 0x01ed8cc7, 0xff119cc0, 0x0053ba6e, 0xfff9a80d, 0xffeaeaab, 0x001690d9, 0xfff11dcd, 0x000715d9, 0xfffdb4b9, + 0x735ed3aa, 0x0b433de8, 0xf560f0f3, 0x091282c4, 0xf8dd5ccf, 0x0525cb66, 0xfca23e3d, 0x01f33960, 0xff0bc9c2, 0x00586127, 0xfff68603, 0xffecbad5, 0x0015ab8b, 0xfff17c10, 0x0006f71a, 0xfffdbc2f, + 0x735780bb, 0x0a55a98f, 0xf5c5b2a1, 0x08e1ea27, 0xf8f25767, 0x0520366d, 0xfc9ff262, 0x01f89c98, 0xff0620a4, 0x005cf349, 0xfff36c0d, 0xffee8913, 0x0014c5dc, 0xfff1db1a, 0x0006d7d7, 0xfffdc3db, + 0x734b4c77, 0x096a8a51, 0xf62adb7c, 0x08b086aa, 0xf9081629, 0x051a030f, 0xfc9e186a, 0x01fdb637, 0xff00a1d8, 0x00617065, 0xfff05a84, 0xfff0552d, 0x0013dfed, 0xfff23ada, 0x0006b817, 0xfffdcbba, + 0x733a37d2, 0x0881ed1f, 0xf6905e79, 0x087e5fd7, 0xf91e9521, 0x05133308, 0xfc9cafe0, 0x0202860e, 0xfefb4dc7, 0x0065d80c, 0xffed51bc, 0xfff21ee8, 0x0012f9de, 0xfff29b40, 0x000697e0, 0xfffdd3ca, + 0x7324441e, 0x079bdea7, 0xf6f62e9d, 0x084b7d43, 0xf935d048, 0x050bc828, 0xfc9bb83e, 0x02070bf9, 0xfef624d8, 0x006a29d6, 0xffea520a, 0xfff3e60f, 0x001213d0, 0xfff2fc3d, 0x00067739, 0xfffddc07, + 0x7309730f, 0x06b86b52, 0xf75c3eff, 0x0817e68c, 0xf94dc388, 0x0503c44d, 0xfc9b30f3, 0x020b47dd, 0xfef12766, 0x006e655c, 0xffe75bbe, 0xfff5aa69, 0x00112de1, 0xfff35dc1, 0x00065629, 0xfffde470, + 0x72e9c6b8, 0x05d79f40, 0xf7c282cb, 0x07e3a35a, 0xf9666ab7, 0x04fb2969, 0xfc9b195f, 0x020f39ab, 0xfeec55cc, 0x00728a3d, 0xffe46f2a, 0xfff76bc2, 0x00104831, 0xfff3bfbc, 0x000634b6, 0xfffded03, + 0x72c5418e, 0x04f98649, 0xf828ed43, 0x07aebb5d, 0xf97fc19e, 0x04f1f97c, 0xfc9b70d6, 0x0212e15c, 0xfee7b059, 0x0076981a, 0xffe18c9a, 0xfff929e3, 0x000f62de, 0xfff4221f, 0x000612e8, 0xfffdf5bc, + 0x729be665, 0x041e2bfe, 0xf88f71bf, 0x0779364a, 0xf999c3f4, 0x04e83697, 0xfc9c369c, 0x02163ef1, 0xfee33759, 0x007a8e98, 0xffdeb45b, 0xfffae49b, 0x000e7e08, 0xfff484db, 0x0005f0c4, 0xfffdfe9b, + 0x726db871, 0x03459ba4, 0xf8f603ae, 0x07431bdf, 0xf9b46d64, 0x04dde2da, 0xfc9d69eb, 0x02195278, 0xfedeeb11, 0x007e6d61, 0xffdbe6b6, 0xfffc9bb4, 0x000d99cc, 0xfff4e7e1, 0x0005ce51, 0xfffe079b, + 0x723abb44, 0x026fe039, 0xf95c9699, 0x070c73dd, 0xf9cfb988, 0x04d30074, 0xfc9f09ee, 0x021c1c06, 0xfedacbbf, 0x00823422, 0xffd923f4, 0xfffe4efd, 0x000cb647, 0xfff54b20, 0x0005ab95, 0xfffe10bc, + 0x7202f2d3, 0x019d046d, 0xf9c31e22, 0x06d5460b, 0xf9eba3ef, 0x04c791a4, 0xfca115c5, 0x021e9bbb, 0xfed6d99c, 0x0085e28b, 0xffd66c59, 0xfffffe46, 0x000bd397, 0xfff5ae8c, 0x00058898, 0xfffe19fa, + 0x71c6636d, 0x00cd12a4, 0xfa298e07, 0x069d9a31, 0xfa082817, 0x04bb98b5, 0xfca38c83, 0x0220d1bf, 0xfed314da, 0x00897851, 0xffd3c02a, 0x0001a95d, 0x000af1d9, 0xfff61214, 0x0005655e, 0xfffe2354, + 0x718511c2, 0x000014f8, 0xfa8fda21, 0x0665781b, 0xfa254176, 0x04af1804, 0xfca66d2e, 0x0222be45, 0xfecf7da3, 0x008cf52d, 0xffd11fa9, 0x00035015, 0x000a1129, 0xfff675ab, 0x000541f0, 0xfffe2cc8, + 0x713f02e0, 0xff361534, 0xfaf5f669, 0x062ce795, 0xfa42eb75, 0x04a211f8, 0xfca9b6bf, 0x02246187, 0xfecc141d, 0x009058da, 0xffce8b13, 0x0004f23e, 0x000931a3, 0xfff6d942, 0x00051e52, 0xfffe3652, + 0x70f43c32, 0xfe6f1cd7, 0xfb5bd6f4, 0x05f3f06b, 0xfa61216f, 0x04948906, 0xfcad6827, 0x0225bbca, 0xfec8d867, 0x0093a31a, 0xffcc02a8, 0x00068fad, 0x00085362, 0xfff73ccb, 0x0004fa8b, 0xfffe3ff2, + 0x70a4c37f, 0xfdab350f, 0xfbc16ff6, 0x05ba9a6b, 0xfa7fdeba, 0x04867fb3, 0xfcb18047, 0x0226cd5b, 0xfec5ca9a, 0x0096d3af, 0xffc986a1, 0x00082835, 0x00077681, 0xfff7a037, 0x0004d6a1, 0xfffe49a4, + 0x70509eec, 0xfcea66be, 0xfc26b5c5, 0x0580ed5f, 0xfa9f1e9e, 0x0477f88d, 0xfcb5fdf7, 0x02279691, 0xfec2eaca, 0x0099ea62, 0xffc71738, 0x0009bbab, 0x00069b1b, 0xfff8037a, 0x0004b29a, 0xfffe5367, + 0x6ff7d4f8, 0xfc2cba75, 0xfc8b9cda, 0x0546f10f, 0xfabedc5a, 0x0468f62e, 0xfcbae002, 0x022817ca, 0xfec03901, 0x009ce6fe, 0xffc4b4a4, 0x000b49e6, 0x0005c149, 0xfff86686, 0x00048e7c, 0xfffe5d38, + 0x6f9a6c7f, 0xfb723876, 0xfcf019cd, 0x050cad3f, 0xfadf1328, 0x04597b40, 0xfcc0252b, 0x0228516f, 0xfebdb547, 0x009fc954, 0xffc25f1a, 0x000cd2bd, 0x0004e926, 0xfff8c94c, 0x00046a4c, 0xfffe6716, + 0x6f386cb6, 0xfabae8b2, 0xfd54215c, 0x04d229b1, 0xfaffbe36, 0x04498a72, 0xfcc5cc26, 0x022843f0, 0xfebb5f9b, 0x00a29136, 0xffc016cb, 0x000e5609, 0x000412c9, 0xfff92bc0, 0x00044612, 0xfffe70ff, + 0x6ed1dd2e, 0xfa06d2ca, 0xfdb7a869, 0x04976e20, 0xfb20d8ad, 0x04392684, 0xfccbd3a0, 0x0227efc6, 0xfeb937f9, 0x00a53e7b, 0xffbddbe8, 0x000fd3a3, 0x00033e4c, 0xfff98dd6, 0x000421d2, 0xfffe7aef, + 0x6e66c5ce, 0xf955fe0c, 0xfe1aa3fc, 0x045c8240, 0xfb425db0, 0x0428523d, 0xfcd23a3a, 0x02275572, 0xfeb73e54, 0x00a7d0ff, 0xffbbae9f, 0x00114b67, 0x00026bc6, 0xfff9ef80, 0x0003fd92, 0xfffe84e7, + 0x6df72ed9, 0xf8a87178, 0xfe7d0942, 0x04216dc0, 0xfb64485b, 0x0417106e, 0xfcd8fe8b, 0x0226757e, 0xfeb5729b, 0x00aa48a0, 0xffb98f1c, 0x0012bd30, 0x00019b4e, 0xfffa50b1, 0x0003d957, 0xfffe8ee3, + 0x6d8320e6, 0xf7fe33ba, 0xfedecd90, 0x03e63846, 0xfb8693c6, 0x040563f4, 0xfce01f21, 0x0225507c, 0xfeb3d4b7, 0x00aca542, 0xffb77d88, 0x001428db, 0x0000ccfc, 0xfffab15e, 0x0003b527, 0xfffe98e2, + 0x6d0aa4e6, 0xf7574b2b, 0xff3fe663, 0x03aae970, 0xfba93b01, 0x03f34fb2, 0xfce79a7f, 0x0223e706, 0xfeb26489, 0x00aee6ca, 0xffb57a0b, 0x00158e47, 0x000000e6, 0xfffb117a, 0x00039108, 0xfffea2e1, + 0x6c8dc41f, 0xf6b3bdd3, 0xffa04963, 0x036f88d2, 0xfbcc391d, 0x03e0d697, 0xfcef6f20, 0x022239bc, 0xfeb121ee, 0x00b10d23, 0xffb384ca, 0x0016ed53, 0xffff3721, 0xfffb70fa, 0x00036cfe, 0xfffeacdf, + 0x6c0c882a, 0xf6139169, 0xffffec5f, 0x03341df4, 0xfbef8924, 0x03cdfb99, 0xfcf79b75, 0x02204949, 0xfeb00cbf, 0x00b3183c, 0xffb19de7, 0x001845e0, 0xfffe6fc3, 0xfffbcfd2, 0x00034910, 0xfffeb6db, + 0x6b86faf8, 0xf576cb4e, 0x005ec552, 0x02f8b055, 0xfc13261f, 0x03bac1b4, 0xfd001de8, 0x021e165d, 0xfeaf24cc, 0x00b50805, 0xffafc584, 0x001997d0, 0xfffdaadf, 0xfffc2df6, 0x00032541, 0xfffec0d2, + 0x6afd26cb, 0xf4dd7092, 0x00bcca63, 0x02bd4768, 0xfc370b14, 0x03a72bf0, 0xfd08f4d6, 0x021ba1b2, 0xfeae69e1, 0x00b6dc75, 0xffadfbbe, 0x001ae306, 0xfffce88b, 0xfffc8b5c, 0x00030196, 0xfffecac3, + 0x6a6f1638, 0xf44785f1, 0x0119f1e4, 0x0281ea90, 0xfc5b3309, 0x03933d58, 0xfd121e99, 0x0218ec06, 0xfeaddbc4, 0x00b89584, 0xffac40b3, 0x001c2765, 0xfffc28d9, 0xfffce7f8, 0x0002de16, 0xfffed4ab, + 0x69dcd425, 0xf3b50fd6, 0x01763256, 0x0246a125, 0xfc7f9902, 0x037ef900, 0xfd1b9980, 0x0215f621, 0xfead7a37, 0x00ba3330, 0xffaa947c, 0x001d64d5, 0xfffb6bdd, 0xfffd43c1, 0x0002bac4, 0xfffede8a, + 0x69466bc8, 0xf3261255, 0x01d18265, 0x020b726f, 0xfca43803, 0x036a6201, 0xfd2563d3, 0x0212c0d2, 0xfead44f4, 0x00bbb579, 0xffa8f730, 0x001e9b3a, 0xfffab1a8, 0xfffd9eab, 0x000297a5, 0xfffee85e, + 0x68abe8a8, 0xf29a9133, 0x022bd8ee, 0x01d065a8, 0xfcc90b12, 0x03557b7a, 0xfd2f7bd1, 0x020f4cec, 0xfead3bb2, 0x00bd1c63, 0xffa768e6, 0x001fca7d, 0xfff9fa4d, 0xfffdf8ae, 0x000274be, 0xfffef225, + 0x680d5698, 0xf2128fde, 0x02852cfc, 0x019581f9, 0xfcee0d33, 0x03404890, 0xfd39dfb4, 0x020b9b4c, 0xfead5e22, 0x00be67f6, 0xffa5e9b1, 0x0020f288, 0xfff945dc, 0xfffe51be, 0x00025214, 0xfffefbde, + 0x676ac1bb, 0xf18e1174, 0x02dd75ca, 0x015ace79, 0xfd133970, 0x032acc6d, 0xfd448dae, 0x0207acd4, 0xfeadabef, 0x00bf983d, 0xffa479a2, 0x00221344, 0xfff89465, 0xfffea9d2, 0x00022fa9, 0xffff0587, + 0x66c4367d, 0xf10d18bd, 0x0334aac4, 0x0120522f, 0xfd388ad1, 0x03150a3f, 0xfd4f83eb, 0x0203826c, 0xfeae24c1, 0x00c0ad48, 0xffa318c7, 0x00232c9d, 0xfff7e5f9, 0xffff00e1, 0x00020d84, 0xffff0f1f, + 0x6619c197, 0xf08fa82f, 0x038ac385, 0x00e6140f, 0xfd5dfc63, 0x02ff0538, 0xfd5ac08e, 0x01ff1d04, 0xfeaec838, 0x00c1a728, 0xffa1c72f, 0x00243e7f, 0xfff73aa7, 0xffff56e3, 0x0001eba8, 0xffff18a4, + 0x656b700a, 0xf015c1ee, 0x03dfb7dd, 0x00ac1af9, 0xfd838938, 0x02e8c08e, 0xfd6641b8, 0x01fa7d91, 0xfeaf95f2, 0x00c285f4, 0xffa084e3, 0x002548d9, 0xfff6927e, 0xffffabcd, 0x0001ca18, 0xffff2215, + 0x64b94f22, 0xef9f67cb, 0x04337fcb, 0x00726dbb, 0xfda92c63, 0x02d23f7a, 0xfd720581, 0x01f5a50d, 0xfeb08d86, 0x00c349c4, 0xff9f51eb, 0x00264b9a, 0xfff5ed8b, 0xffffff99, 0x0001a8da, 0xffff2b70, + 0x64036c6f, 0xef2c9b43, 0x04861383, 0x0039130c, 0xfdcee0ff, 0x02bb8537, 0xfd7e09fc, 0x01f0947a, 0xfeb1ae87, 0x00c3f2b6, 0xff9e2e50, 0x002746b2, 0xfff54bdc, 0x0000523d, 0x000187f0, 0xffff34b6, + 0x6349d5c9, 0xeebd5d81, 0x04d76b6b, 0x00001191, 0xfdf4a22a, 0x02a49505, 0xfd8a4d37, 0x01eb4cde, 0xfeb2f884, 0x00c480e9, 0xff9d1a14, 0x00283a12, 0xfff4ad7e, 0x0000a3b3, 0x0001675f, 0xffff3de3, + 0x628c994c, 0xee51af5f, 0x0527801d, 0xffc76fd5, 0xfe1a6b08, 0x028d7223, 0xfd96cd3d, 0x01e5cf44, 0xfeb46b07, 0x00c4f480, 0xff9c1539, 0x002925ae, 0xfff4127d, 0x0000f3f1, 0x00014729, 0xffff46f7, + 0x61cbc559, 0xede99165, 0x05764a68, 0xff8f344f, 0xfe4036c5, 0x02761fd3, 0xfda3880f, 0x01e01cbe, 0xfeb60596, 0x00c54da2, 0xff9b1fc1, 0x002a0979, 0xfff37ae4, 0x000142f1, 0x00012754, 0xffff4ff1, + 0x61076890, 0xed8503c7, 0x05c3c34e, 0xff576560, 0xfe660094, 0x025ea157, 0xfdb07bb0, 0x01da3661, 0xfeb7c7b0, 0x00c58c79, 0xff9a39a9, 0x002ae568, 0xfff2e6bf, 0x000190ac, 0x000107e1, 0xffff58d0, + 0x603f91d5, 0xed24066b, 0x060fe408, 0xff20094d, 0xfe8bc3ad, 0x0246f9f3, 0xfdbda61a, 0x01d41d4a, 0xfeb9b0d3, 0x00c5b132, 0xff9962ec, 0x002bb971, 0xfff25619, 0x0001dd1b, 0x0000e8d4, 0xffff6192, + 0x5f745049, 0xecc698e6, 0x065aa604, 0xfee92646, 0xfeb17b53, 0x022f2cea, 0xfdcb0546, 0x01cdd297, 0xfebbc078, 0x00c5bbfc, 0xff989b85, 0x002c858d, 0xfff1c8fa, 0x00022837, 0x0000ca30, 0xffff6a38, + 0x5ea5b34c, 0xec6cba79, 0x06a402e4, 0xfeb2c261, 0xfed722d0, 0x02173d81, 0xfdd89727, 0x01c7576d, 0xfebdf613, 0x00c5ad0a, 0xff97e36c, 0x002d49b4, 0xfff13f6c, 0x000271fa, 0x0000abf8, 0xffff72be, + 0x5dd3ca7a, 0xec166a19, 0x06ebf483, 0xfe7ce399, 0xfefcb57a, 0x01ff2ef9, 0xfde659af, 0x01c0acf5, 0xfec05114, 0x00c58494, 0xff973a96, 0x002e05df, 0xfff0b977, 0x0002ba5f, 0x00008e30, 0xffff7b26, + 0x5cfea5aa, 0xebc3a669, 0x073274f1, 0xfe478fd2, 0xff222eac, 0x01e70494, 0xfdf44acc, 0x01b9d45b, 0xfec2d0e8, 0x00c542d1, 0xff96a0f8, 0x002eba0a, 0xfff03724, 0x0003015f, 0x000070d9, 0xffff836d, + 0x5c2654ed, 0xeb746dbe, 0x07777e74, 0xfe12ccd1, 0xff4789d1, 0x01cec194, 0xfe026869, 0x01b2ced1, 0xfec574f9, 0x00c4e7fe, 0xff961684, 0x002f6630, 0xffefb87a, 0x000346f6, 0x000053f7, 0xffff8b93, + 0x5b4ae88d, 0xeb28be1f, 0x07bb0b8b, 0xfddea042, 0xff6cc25a, 0x01b66936, 0xfe10b06f, 0x01ab9d8b, 0xfec83caa, 0x00c47459, 0xff959b29, 0x00300a4f, 0xffef3d7f, 0x00038b1d, 0x0000378c, 0xffff9398, + 0x5a6c7108, 0xeae09544, 0x07fd16eb, 0xfdab0fb6, 0xff91d3c6, 0x019dfeb6, 0xfe1f20c5, 0x01a441c2, 0xfecb275e, 0x00c3e824, 0xff952ed7, 0x0030a665, 0xffeec63a, 0x0003cdd1, 0x00001b9a, 0xffff9b7a, + 0x598aff13, 0xea9bf097, 0x083d9b81, 0xfd7820a0, 0xffb6b99f, 0x0185854f, 0xfe2db74f, 0x019cbcb1, 0xfece3472, 0x00c343a4, 0xff94d178, 0x00313a72, 0xffee52b1, 0x00040f0d, 0x00000024, 0xffffa339, + 0x58a6a397, 0xea5acd38, 0x087c9471, 0xfd45d856, 0xffdb6f7c, 0x016d0037, 0xfe3c71f1, 0x01950f98, 0xfed16342, 0x00c2871f, 0xff9482f8, 0x0031c677, 0xffede2e7, 0x00044ecb, 0xffffe52d, 0xffffaad3, + 0x57bf6fae, 0xea1d27f7, 0x08b9fd18, 0xfd143c12, 0xfffff100, 0x015472a1, 0xfe4b4e8c, 0x018d3bb8, 0xfed4b325, 0x00c1b2e0, 0xff944340, 0x00324a74, 0xffed76e3, 0x00048d0a, 0xffffcab5, 0xffffb249, + 0x56d574a2, 0xe9e2fd5b, 0x08f5d10a, 0xfce350f0, 0x002439db, 0x013bdfbc, 0xfe5a4b03, 0x01854258, 0xfed82370, 0x00c0c731, 0xff941236, 0x0032c66e, 0xffed0ea7, 0x0004c9c4, 0xffffb0bf, 0xffffb99a, + 0x55e8c3ee, 0xe9ac49a0, 0x09300c14, 0xfcb31bec, 0x004845cc, 0x01234ab4, 0xfe696534, 0x017d24bf, 0xfedbb373, 0x00bfc463, 0xff93efbf, 0x00333a67, 0xffecaa36, 0x000504f6, 0xffff974d, 0xffffc0c5, + 0x54f96f37, 0xe97908b8, 0x0968aa3b, 0xfc83a1e5, 0x006c10a0, 0x010ab6b0, 0xfe789b01, 0x0174e437, 0xfedf627d, 0x00beaac6, 0xff93dbc0, 0x0033a665, 0xffec4994, 0x00053e9e, 0xffff7e61, 0xffffc7ca, + 0x54078851, 0xe9493649, 0x099fa7bb, 0xfc54e79a, 0x008f9631, 0x00f226d0, 0xfe87ea47, 0x016c820d, 0xfee32fdb, 0x00bd7aae, 0xff93d618, 0x00340a6d, 0xffebecc2, 0x000576b8, 0xffff65fc, 0xffffcea8, + 0x53132138, 0xe91ccdb5, 0x09d5010b, 0xfc26f1ad, 0x00b2d26b, 0x00d99e31, 0xfe9750e8, 0x0163ff90, 0xfee71ad4, 0x00bc3470, 0xff93deaa, 0x00346687, 0xffeb93c3, 0x0005ad41, 0xffff4e20, 0xffffd55f, + 0x521c4c10, 0xe8f3ca12, 0x0a08b2d9, 0xfbf9c49d, 0x00d5c147, 0x00c11feb, 0xfea6ccc3, 0x015b5e11, 0xfeeb22af, 0x00bad866, 0xff93f552, 0x0034babb, 0xffeb3e96, 0x0005e238, 0xffff36ce, 0xffffdbee, + 0x51231b26, 0xe8ce2631, 0x0a3aba09, 0xfbcd64ca, 0x00f85ecf, 0x00a8af0c, 0xfeb65bb9, 0x01529ee3, 0xfeef46b0, 0x00b966e9, 0xff9419ef, 0x00350711, 0xffeaed3c, 0x00061599, 0xffff2007, 0xffffe255, + 0x5027a0e9, 0xe8abdc9d, 0x0a6b13bc, 0xfba1d673, 0x011aa71d, 0x00904ea0, 0xfec5fbac, 0x0149c35a, 0xfef3861a, 0x00b7e055, 0xff944c5a, 0x00354b94, 0xffea9fb6, 0x00064764, 0xffff09ce, 0xffffe894, + 0x4f29efed, 0xe88ce79a, 0x0a99bd47, 0xfb771db9, 0x013c965b, 0x007801aa, 0xfed5aa7e, 0x0140cccb, 0xfef7e02a, 0x00b6450a, 0xff948c6e, 0x0035884f, 0xffea5602, 0x00067797, 0xfffef421, 0xffffeeaa, + 0x4e2a1ae8, 0xe871412a, 0x0ac6b43a, 0xfb4d3e97, 0x015e28c7, 0x005fcb26, 0xfee56614, 0x0137bc8f, 0xfefc541e, 0x00b49568, 0xff94da03, 0x0035bd4e, 0xffea1020, 0x0006a630, 0xfffedf04, 0xfffff498, + 0x4d2834b0, 0xe858e30a, 0x0af1f65d, 0xfb243cea, 0x017f5aad, 0x0047ae09, 0xfef52c54, 0x012e93fc, 0xff00e133, 0x00b2d1d1, 0xff9534f0, 0x0035ea9d, 0xffe9ce0d, 0x0006d32f, 0xfffeca76, 0xfffffa5d, + 0x4c245038, 0xe843c6b5, 0x0b1b81ad, 0xfafc1c6e, 0x01a0286c, 0x002fad3f, 0xff04fb25, 0x0125546c, 0xff0586a0, 0x00b0faaa, 0xff959d0a, 0x0036104b, 0xffe98fc8, 0x0006fe92, 0xfffeb678, 0xfffffff8, + 0x4b1e8091, 0xe831e563, 0x0b435462, 0xfad4e0b9, 0x01c08e78, 0x0017cbae, 0xff14d073, 0x011bff38, 0xff0a439e, 0x00af1059, 0xff961224, 0x00362e66, 0xffe9554c, 0x00072859, 0xfffea30b, 0x0000056a, + 0x4a16d8e5, 0xe823380d, 0x0b696ceb, 0xfaae8d43, 0x01e08952, 0x00000c33, 0xff24aa2a, 0x011295bb, 0xff0f1762, 0x00ad1346, 0xff969412, 0x003644fd, 0xffe91e99, 0x00075084, 0xfffe9030, 0x00000ab3, + 0x490d6c79, 0xe817b76c, 0x0b8dc9ed, 0xfa89255f, 0x02001593, 0xffe871a0, 0xff348639, 0x0109194f, 0xff140121, 0x00ab03da, 0xff9722a5, 0x00365422, 0xffe8eba8, 0x00077712, 0xfffe7de7, 0x00000fd2, + 0x48024ea7, 0xe80f5bfb, 0x0bb06a47, 0xfa64ac3f, 0x021f2fe5, 0xffd0fec1, 0xff446293, 0x00ff8b4f, 0xff19000e, 0x00a8e282, 0xff97bdac, 0x00365be6, 0xffe8bc77, 0x00079c04, 0xfffe6c2f, 0x000014c8, + 0x46f592e2, 0xe80a1df5, 0x0bd14d0b, 0xfa4124f2, 0x023dd505, 0xffb9b656, 0xff543d2e, 0x00f5ed15, 0xff1e135b, 0x00a6afa8, 0xff9864f6, 0x00365c5b, 0xffe89101, 0x0007bf5b, 0xfffe5b0b, 0x00001994, + 0x45e74cad, 0xe807f55b, 0x0bf07186, 0xfa1e9262, 0x025c01c5, 0xffa29b18, 0xff641402, 0x00ec3ffc, 0xff233a39, 0x00a46bbc, 0xff991851, 0x00365594, 0xffe8693f, 0x0007e116, 0xfffe4a79, 0x00001e37, + 0x44d78fa0, 0xe808d9f1, 0x0c0dd738, 0xf9fcf758, 0x0279b30b, 0xff8bafb3, 0xff73e50e, 0x00e2855d, 0xff2873d6, 0x00a2172d, 0xff99d789, 0x003647a5, 0xffe8452d, 0x00080137, 0xfffe3a79, 0x000022b1, + 0x43c66f62, 0xe80cc342, 0x0c297dd9, 0xf9dc567b, 0x0296e5d0, 0xff74f6cc, 0xff83ae52, 0x00d8be92, 0xff2dbf61, 0x009fb26c, 0xff9aa268, 0x003632a2, 0xffe824c5, 0x00081fbf, 0xfffe2b0d, 0x00002701, + 0x42b3ffa9, 0xe813a89f, 0x0c436557, 0xf9bcb24a, 0x02b39724, 0xff5e72fb, 0xff936dd2, 0x00ceecf5, 0xff331c08, 0x009d3deb, 0xff9b78ba, 0x003616a2, 0xffe807ff, 0x00083cb0, 0xfffe1c32, 0x00002b28, + 0x41a05437, 0xe81d8122, 0x0c5b8dd4, 0xf99e0d26, 0x02cfc429, 0xff4826cf, 0xffa3219a, 0x00c511dc, 0xff3888f8, 0x009aba1d, 0xff9c5a47, 0x0035f3b9, 0xffe7eed5, 0x0008580a, 0xfffe0dea, 0x00002f26, + 0x408b80d9, 0xe82a43ac, 0x0c71f7a9, 0xf980694a, 0x02eb6a18, 0xff3214c9, 0xffb2c7b6, 0x00bb2e9f, 0xff3e055d, 0x00982778, 0xff9d46d6, 0x0035ca00, 0xffe7d93f, 0x000871cf, 0xfffe0034, 0x000032fb, + 0x3f759967, 0xe839e6e9, 0x0c86a361, 0xf963c8cc, 0x03068640, 0xff1c3f63, 0xffc25e3b, 0x00b14493, 0xff439064, 0x0095866f, 0xff9e3e30, 0x0035998d, 0xffe7c735, 0x00088a02, 0xfffdf310, 0x000036a8, + 0x3e5eb1bd, 0xe84c6152, 0x0c9991be, 0xf9482da0, 0x03211603, 0xff06a907, 0xffd1e340, 0x00a7550c, 0xff492937, 0x0092d77b, 0xff9f4019, 0x00356279, 0xffe7b8af, 0x0008a0a5, 0xfffde67c, 0x00003a2d, + 0x3d46ddc1, 0xe861a92b, 0x0caac3b5, 0xf92d9997, 0x033b16dc, 0xfef15417, 0xffe154e3, 0x009d615d, 0xff4ecf02, 0x00901b11, 0xffa04c57, 0x003524dd, 0xffe7ada5, 0x0008b5ba, 0xfffdda79, 0x00003d89, + 0x3c2e315a, 0xe879b487, 0x0cba3a6d, 0xf9140e5e, 0x03548659, 0xfedc42e7, 0xfff0b148, 0x00936ad6, 0xff5480f0, 0x008d51ab, 0xffa162ae, 0x0034e0d3, 0xffe7a60d, 0x0008c944, 0xfffdcf05, 0x000040be, + 0x3b14c072, 0xe8947947, 0x0cc7f742, 0xf8fb8d7d, 0x036d621f, 0xfec777be, 0xfffff697, 0x008972c7, 0xff5a3e2c, 0x008a7bc1, 0xffa282e1, 0x00349674, 0xffe7a1de, 0x0008db46, 0xfffdc421, 0x000043cc, + 0x39fa9ef3, 0xe8b1ed1c, 0x0cd3fbc0, 0xf8e4185a, 0x0385a7eb, 0xfeb2f4d9, 0x000f22fe, 0x007f7a7c, 0xff6005e1, 0x008799cd, 0xffa3acb4, 0x003445dc, 0xffe7a10d, 0x0008ebc1, 0xfffdb9cb, 0x000046b2, + 0x38dfe0c6, 0xe8d2058b, 0x0cde49a8, 0xf8cdb036, 0x039d558e, 0xfe9ebc66, 0x001e34b4, 0x00758341, 0xff65d73a, 0x0084ac48, 0xffa4dfe8, 0x0033ef25, 0xffe7a391, 0x0008fabb, 0xfffdb002, 0x00004972, + 0x37c499d0, 0xe8f4b7e9, 0x0ce6e2ea, 0xf8b85631, 0x03b468f1, 0xfe8ad087, 0x002d29f3, 0x006b8e5c, 0xff6bb163, 0x0081b3af, 0xffa61c3e, 0x0033926d, 0xffe7a95f, 0x00090836, 0xfffda6c5, 0x00004c0b, + 0x36a8ddf3, 0xe919f961, 0x0cedc9a7, 0xf8a40b44, 0x03cae014, 0xfe773351, 0x003c00fd, 0x00619d15, 0xff719388, 0x007eb07b, 0xffa76176, 0x00332fcf, 0xffe7b26c, 0x00091435, 0xfffd9e13, 0x00004e7f, + 0x358cc109, 0xe941bef3, 0x0cf30031, 0xf890d048, 0x03e0b90d, 0xfe63e6cb, 0x004ab81b, 0x0057b0ae, 0xff777cd6, 0x007ba32a, 0xffa8af51, 0x0032c769, 0xffe7bead, 0x00091ebd, 0xfffd95eb, 0x000050cd, + 0x347056e3, 0xe96bfd76, 0x0cf6890a, 0xf87ea5f1, 0x03f5f20a, 0xfe50ecf0, 0x00594d9d, 0x004dca68, 0xff7d6c79, 0x00788c36, 0xffaa058d, 0x00325958, 0xffe7ce16, 0x000927d1, 0xfffd8e4d, 0x000052f7, + 0x3353b349, 0xe998a999, 0x0cf866e1, 0xf86d8cd1, 0x040a894e, 0xfe3e47ac, 0x0067bfd8, 0x0043eb7f, 0xff83619f, 0x00756c1d, 0xffab63ea, 0x0031e5ba, 0xffe7e09c, 0x00092f75, 0xfffd8735, 0x000054fc, + 0x3236e9f7, 0xe9c7b7e3, 0x0cf89c96, 0xf85d8555, 0x041e7d34, 0xfe2bf8de, 0x00760d2a, 0x003a152f, 0xff895b77, 0x0072435b, 0xffacca25, 0x00316cae, 0xffe7f631, 0x000935ad, 0xfffd80a4, 0x000056dd, + 0x311a0e9b, 0xe9f91cb9, 0x0cf72d34, 0xf84e8fc9, 0x0431cc31, 0xfe1a0256, 0x008433f9, 0x003048ae, 0xff8f5930, 0x006f126b, 0xffae37fd, 0x0030ee53, 0xffe80eca, 0x00093a7f, 0xfffd7a98, 0x0000589b, + 0x2ffd34d4, 0xea2ccc59, 0x0cf41bf7, 0xf840ac57, 0x044474ce, 0xfe0865d7, 0x009232b2, 0x0026872f, 0xff9559fb, 0x006bd9cd, 0xffafad2e, 0x00306ac8, 0xffe82a59, 0x00093ded, 0xfffd750f, 0x00005a36, + 0x2ee07030, 0xea62bae0, 0x0cef6c43, 0xf833db04, 0x045675ab, 0xfdf72515, 0x00a007c9, 0x001cd1e4, 0xff9b5d0a, 0x006899fb, 0xffb12976, 0x002fe22c, 0xffe848d3, 0x00093ffe, 0xfffd7008, 0x00005baf, + 0x2dc3d429, 0xea9adc49, 0x0ce921ab, 0xf8281bb6, 0x0467cd83, 0xfde641b7, 0x00adb1bb, 0x001329f7, 0xffa16190, 0x00655372, 0xffb2ac90, 0x002f54a1, 0xffe86a29, 0x000940b6, 0xfffd6b81, 0x00005d06, + 0x2ca77428, 0xead52471, 0x0ce13feb, 0xf81d6e2e, 0x04787b24, 0xfdd5bd53, 0x00bb2f0b, 0x00099093, 0xffa766c0, 0x006206b1, 0xffb4363a, 0x002ec246, 0xffe88e4d, 0x00094019, 0xfffd6779, 0x00005e3d, + 0x2b8b637b, 0xeb118714, 0x0cd7caec, 0xf813d20d, 0x04887d76, 0xfdc59972, 0x00c87e47, 0x000006db, 0xffad6bd0, 0x005eb431, 0xffb5c630, 0x002e2b3c, 0xffe8b532, 0x00093e2e, 0xfffd63ed, 0x00005f52, + 0x2a6fb55e, 0xeb4ff7d4, 0x0cccc6bc, 0xf80b46d3, 0x0497d378, 0xfdb5d78f, 0x00d59e03, 0xfff68df1, 0xffb36ff9, 0x005b5c71, 0xffb75c2c, 0x002d8fa4, 0xffe8decb, 0x00093af8, 0xfffd60dd, 0x00006048, + 0x29547ced, 0xeb906a35, 0x0cc03797, 0xf803cbdc, 0x04a67c41, 0xfda67913, 0x00e28cdd, 0xffed26f0, 0xffb97271, 0x0057ffec, 0xffb8f7ea, 0x002cefa1, 0xffe90b08, 0x0009367e, 0xfffd5e46, 0x0000611f, + 0x2839cd30, 0xebd2d1a1, 0x0cb221de, 0xf7fd6065, 0x04b476fe, 0xfd977f5d, 0x00ef497a, 0xffe3d2f2, 0xffbf7274, 0x00549f1c, 0xffba9927, 0x002c4b53, 0xffe939db, 0x000930c4, 0xfffd5c26, 0x000061d8, + 0x271fb90d, 0xec17216b, 0x0ca28a1a, 0xf7f8038c, 0x04c1c2f3, 0xfd88ebb9, 0x00fbd28a, 0xffda930a, 0xffc56f3e, 0x00513a7e, 0xffbc3f9d, 0x002ba2dc, 0xffe96b35, 0x000929d1, 0xfffd5a7c, 0x00006272, + 0x2606534e, 0xec5d4ccd, 0x0c9174fa, 0xf7f3b44b, 0x04ce5f7d, 0xfd7abf64, 0x010826c4, 0xffd16848, 0xffcb680e, 0x004dd28c, 0xffbdeb07, 0x002af65f, 0xffe99f08, 0x000921aa, 0xfffd5945, 0x000062f0, + 0x24edae9c, 0xeca546eb, 0x0c7ee754, 0xf7f0717e, 0x04da4c10, 0xfd6cfb8e, 0x011444e7, 0xffc853b6, 0xffd15c22, 0x004a67c0, 0xffbf9b21, 0x002a45fe, 0xffe9d545, 0x00091854, 0xfffd5880, 0x00006351, + 0x23d5dd81, 0xecef02d5, 0x0c6ae622, 0xf7ee39e2, 0x04e58836, 0xfd5fa157, 0x01202bbe, 0xffbf565a, 0xffd74abe, 0x0046fa93, 0xffc14fa5, 0x002991db, 0xffea0ddc, 0x00090dd6, 0xfffd582a, 0x00006396, + 0x22bef262, 0xed3a7388, 0x0c557681, 0xf7ed0c12, 0x04f01392, 0xfd52b1cf, 0x012bda1b, 0xffb67137, 0xffdd3325, 0x00438b7e, 0xffc3084f, 0x0028da1a, 0xffea48be, 0x00090236, 0xfffd5842, 0x000063c0, + 0x21a8ff7e, 0xed878bf0, 0x0c3e9db5, 0xf7ece68c, 0x04f9edda, 0xfd462df6, 0x01374eda, 0xffada547, 0xffe3149e, 0x00401af9, 0xffc4c4da, 0x00281edd, 0xffea85dc, 0x0008f57a, 0xfffd58c5, 0x000063d0, + 0x209416f2, 0xedd63ee5, 0x0c26611f, 0xf7edc7af, 0x050316e0, 0xfd3a16c0, 0x014288e0, 0xffa4f383, 0xffe8ee72, 0x003ca97b, 0xffc68502, 0x00276046, 0xffeac525, 0x0008e7a7, 0xfffd59b2, 0x000063c6, + 0x1f804ab0, 0xee267f35, 0x0c0cc646, 0xf7efadbd, 0x050b8e8a, 0xfd2e6d0d, 0x014d871b, 0xff9c5cdc, 0xffeebfec, 0x0039377a, 0xffc84881, 0x00269e7a, 0xffeb068a, 0x0008d8c4, 0xfffd5b05, 0x000063a3, + 0x1e6dac83, 0xee783f9e, 0x0bf1d2d0, 0xf7f296d7, 0x051354d5, 0xfd2331b0, 0x01584883, 0xff93e241, 0xfff48859, 0x0035c56c, 0xffca0f14, 0x0025d99b, 0xffeb49fc, 0x0008c8d7, 0xfffd5cbe, 0x00006368, + 0x1d5c4e09, 0xeecb72d1, 0x0bd58c81, 0xf7f68103, 0x051a69d4, 0xfd18656f, 0x0162cc19, 0xff8b8498, 0xfffa470a, 0x003253c6, 0xffcbd876, 0x002511cd, 0xffeb8f6a, 0x0008b7e7, 0xfffd5ed8, 0x00006316, + 0x1c4c40b6, 0xef200b76, 0x0bb7f940, 0xf7fb6a29, 0x0520cdb1, 0xfd0e08fb, 0x016d10e9, 0xff8344c4, 0xfffffb51, 0x002ee2fa, 0xffcda463, 0x00244733, 0xffebd6c4, 0x0008a5fa, 0xfffd6154, 0x000062ad, + 0x1b3d95d1, 0xef75fc2b, 0x0b991f0f, 0xf8015015, 0x052680ae, 0xfd041cfa, 0x01771608, 0xff7b23a1, 0x0005a483, 0x002b737b, 0xffcf7299, 0x002379ef, 0xffec1ffa, 0x00089316, 0xfffd642d, 0x0000622e, + 0x1a305e70, 0xefcd3787, 0x0b79040c, 0xf8083077, 0x052b8320, 0xfcfaa200, 0x0180da94, 0xff732209, 0x000b41fa, 0x002805ba, 0xffd142d3, 0x0022aa26, 0xffec6afc, 0x00087f43, 0xfffd6762, 0x0000619a, + 0x1924ab7b, 0xf025b01a, 0x0b57ae75, 0xf81008e2, 0x052fd573, 0xfcf19894, 0x018a5db5, 0xff6b40cb, 0x0010d30e, 0x00249a28, 0xffd314cf, 0x0021d7fa, 0xffecb7b9, 0x00086a86, 0xfffd6af1, 0x000060f1, + 0x181a8da5, 0xf07f586e, 0x0b3524a0, 0xf818d6cf, 0x0533782a, 0xfce9012c, 0x01939e9e, 0xff6380b5, 0x00165720, 0x00213134, 0xffd4e84a, 0x00210390, 0xffed0621, 0x000854e6, 0xfffd6ed6, 0x00006035, + 0x17121573, 0xf0da230b, 0x0b116cff, 0xf822979b, 0x05366bdc, 0xfce0dc2f, 0x019c9c8b, 0xff5be28d, 0x001bcd8e, 0x001dcb4a, 0xffd6bd01, 0x00202d09, 0xffed5624, 0x00083e6a, 0xfffd7310, 0x00005f66, + 0x160b5331, 0xf1360276, 0x0aec8e1c, 0xf82d488c, 0x0538b136, 0xfcd929f4, 0x01a556c1, 0xff546713, 0x002135bd, 0x001a68d8, 0xffd892b4, 0x001f5489, 0xffeda7b1, 0x00082718, 0xfffd779d, 0x00005e84, + 0x150656f8, 0xf192e932, 0x0ac68e9b, 0xf838e6c9, 0x053a48fa, 0xfcd1eac3, 0x01adcc91, 0xff4d0f02, 0x00268f13, 0x00170a47, 0xffda6921, 0x001e7a33, 0xffedfab8, 0x00080ef7, 0xfffd7c7a, 0x00005d92, + 0x140330a9, 0xf1f0c9c5, 0x0a9f7537, 0xf8456f65, 0x053b3400, 0xfccb1ed7, 0x01b5fd54, 0xff45db10, 0x002bd8fa, 0x0013b003, 0xffdc4007, 0x001d9e2a, 0xffee4f29, 0x0007f60f, 0xfffd81a4, 0x00005c8e, + 0x1301efed, 0xf24f96b5, 0x0a7748c0, 0xf852df56, 0x053b7332, 0xfcc4c658, 0x01bde86f, 0xff3ecbea, 0x003112e0, 0x00105a72, 0xffde1726, 0x001cc091, 0xffeea4f2, 0x0007dc65, 0xfffd8719, 0x00005b7b, + 0x1202a434, 0xf2af428c, 0x0a4e101f, 0xf861337c, 0x053b0791, 0xfcbee162, 0x01c58d50, 0xff37e23b, 0x00363c35, 0x000d09fc, 0xffdfee3f, 0x001be18a, 0xffeefc04, 0x0007c201, 0xfffd8cd7, 0x00005a58, + 0x11055cb4, 0xf30fbfd7, 0x0a23d24e, 0xf870689f, 0x0539f231, 0xfcb97001, 0x01cceb6e, 0xff311ea4, 0x003b546b, 0x0009bf05, 0xffe1c511, 0x001b0138, 0xffef544e, 0x0007a6e9, 0xfffd92db, 0x00005927, + 0x100a2864, 0xf371012c, 0x09f8965d, 0xf8807b70, 0x0538343a, 0xfcb47232, 0x01d4024c, 0xff2a81c4, 0x00405afa, 0x000679f2, 0xffe39b60, 0x001a1fbc, 0xffefadc0, 0x00078b24, 0xfffd9923, 0x000057e9, + 0x0f111603, 0xf3d2f926, 0x09cc636e, 0xf8916889, 0x0535cee9, 0xfcafe7e2, 0x01dad175, 0xff240c2f, 0x00454f5d, 0x00033b23, 0xffe570ed, 0x00193d3a, 0xfff00849, 0x00076eba, 0xfffd9fac, 0x0000569d, + 0x0e1a340d, 0xf4359a6a, 0x099f40b5, 0xf8a32c6e, 0x0532c38c, 0xfcabd0f2, 0x01e15880, 0xff1dbe77, 0x004a310f, 0x000002f9, 0xffe7457c, 0x001859d2, 0xfff063d9, 0x000751b0, 0xfffda675, 0x00005545, + 0x0d2590c3, 0xf498d7a5, 0x09713575, 0xf8b5c38d, 0x052f1386, 0xfca82d32, 0x01e7970e, 0xff179926, 0x004eff94, 0xfffcd1d3, 0xffe918ce, 0x001775a7, 0xfff0c060, 0x0007340d, 0xfffdad79, 0x000053e2, + 0x0c333a22, 0xf4fca390, 0x09424904, 0xf8c92a41, 0x052ac04c, 0xfca4fc64, 0x01ed8cc7, 0xff119cc0, 0x0053ba6e, 0xfff9a80d, 0xffeaeaab, 0x001690d9, 0xfff11dcd, 0x000715d9, 0xfffdb4b9, 0x00005274, +}; +} diff --git a/services/audioflinger/audio-resampler/resampler_filter_coefficients_10042011.h b/services/audioflinger/audio-resampler/resampler_filter_coefficients_10042011.h deleted file mode 100644 index 8c6a899..0000000 --- a/services/audioflinger/audio-resampler/resampler_filter_coefficients_10042011.h +++ /dev/null @@ -1,2071 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include - -namespace android { - -const int32_t resampler_filter_coefficients_10042011[] = { -2075076504, -2074870219, -2074269557, -2073262841, -2071862786, -2070051926, -2067849110, -2065243563, -2062248465, -2058846262, -2055055548, -2050866069, -2046291635, -2041315273, -2035955897, -2030204167, -2024074532, -2017550518, -2010651175, -2003368165, -1995716923, -1987682243, -1979283938, -1970514752, -1961390076, -1951894181, -1942045775, -1931837943, -1921286728, -1910377736, -1899130344, -1887538902, -1875619770, -1863358864, -1850775104, -1837863721, -1824641940, -1811097380, -1797249776, -1783095528, -1768651291, -1753903742, -1738870726, -1723548746, -1707955054, -1692078274, -1675937190, -1659529795, -1642873313, -1625956474, -1608797063, -1591393772, -1573764495, -1555899971, -1537818785, -1519520784, -1501022796, -1482314240, -1463411160, -1444313227, -1425037741, -1405576492, -1385946622, -1366149382, -1346201706, -1326095287, -1305845828, -1285455045, -1264940308, -1244295464, -1223536951, -1202667530, -1181703085, -1160635857, -1139479271, -1118235636, -1096921134, -1075530585, -1054078577, -1032568949, -1011017224, -989417949, -967783970, -946119336, -924439752, -902741900, -881039249, -859336703, -837648175, -815968557, -794308053, -772670861, -751070988, -729505896, -707986911, -686519594, -665117063, -643776375, -622506966, -601314359, -580211607, -559197735, -538282662, -517472516, -496778402, -476197491, -455736426, -435400430, -415200497, -395136166, -375215078, -355443561, -335831583, -316378199, -297089183, -277970603, -259032151, -240274557, -221703918, -203326638, -185150446, -167174280, -149401179, -131836509, -114487708, -97355714, -80444376, -63759844, -47308498, -31090767, -15108809, --631654, --16124677, --31368536, --46360908, --61095999, --75569692, --89781876, --103732869, --117417959, --130833461, --143977734, --156850513, --169446641, --181763420, --193799687, --205556559, --217029409, --228216068, --239114500, --249725794, --260045485, --270072966, --279807538, --289252364, --298404017, --307262396, --315825804, --324097052, --332072584, --339753137, --347137398, --354229167, --361025450, --367527527, --373733643, --379647676, --385266970, --390594013, --395628043, --400374357, --404831217, --409001628, --412884357, --416484569, --419800667, --422836272, --425590412, --428068799, --430270358, --432199204, --433854305, --435241518, --436360214, --437215297, --437806349, --438139967, --438216244, --438040549, --437612462, --436938620, --436019455, --434860689, --433462013, --431830172, --429966019, --427875663, --425559045, --423023081, --420269108, --417303590, --414126712, --410745497, --407161766, --403382348, --399407797, --395245305, --390897144, --386370224, --381665062, --376788564, --371743279, --366536360, --361168782, --355647611, --349975843, --344160581, --338202705, --332108851, --325882239, --319530194, --313054213, --306461164, --299754744, --292942106, --286024571, --279008412, --271897436, --264698872, --257414606, --250051032, --242612307, --235105276, --227531464, --219896432, --212204319, --204462036, --196671840, --188839540, --180969700, --173068854, --165138974, --157185076, --149211664, --141225186, --133228184, --125225726, --117222535, --109224429, --101233397, --93253442, --85289050, --77345947, --69426846, --61535955, --53678071, --45858404, --38079310, --30344121, --22657427, --15024209, --7447312, -69952, -7522929, -14907403, -22221174, -29462063, -36625813, -43708432, -50707112, -57619541, -64441301, -71168979, -77800149, -84333341, -90764454, -97090405, -103308422, -109417126, -115412500, -121292248, -127054242, -132698149, -138220442, -143619140, -148891701, -154037743, -159053739, -163938275, -168689170, -173306749, -177787867, -182131495, -186335286, -190399716, -194321853, -198101380, -201736519, -205228586, -208575166, -211776310, -214830056, -217737773, -220497194, -223108861, -225571114, -227885824, -230051117, -232067922, -233934597, -235653195, -237222146, -238642925, -239914316, -241038916, -242015623, -242846277, -243529706, -244068632, -244462216, -244712654, -244818983, -244784181, -244607765, -244292268, -243836913, -243244874, -242516010, -241653201, -240655918, -239527557, -238268354, -236881508, -235366743, -233727638, -231964766, -230081521, -228077731, -225956985, -223720128, -221370808, -218909157, -216338938, -213661333, -210880096, -207995414, -205010946, -201928111, -198750891, -195479864, -192118892, -188669741, -185136417, -181519490, -177822602, -174047687, -170198894, -166277172, -162286302, -158228508, -154107834, -149925117, -145683777, -141386129, -137036351, -132635752, -128187958, -123695608, -119162747, -114590586, -109982363, -105340765, -100669861, -95971242, -91248228, -86503703, -81741443, -76962776, -72170457, -67367307, -62557108, -57741653, -52923856, -48106777, -43293939, -38486954, -33688240, -28900789, -24128036, -19371931, -14634917, -9920080, -5230446, -567618, --4066612, --8669336, --13237622, --17769457, --22262939, --26715017, --31123091, --35485370, --39800471, --44065504, --48278050, --52436071, --56538223, --60581634, --64564356, --68484740, --72342096, --76133828, --79858170, --83513191, --87098163, --90610469, --94048704, --97411174, --100697628, --103905676, --107034151, --110081227, --113046738, --115928406, --118725517, --121436605, --124062060, --126599916, --129049689, --131409767, --133680567, --135860199, --137948517, --139944122, --141847799, --143657917, --145374591, --146996418, --148524310, --149956828, --151294475, --152536152, --153683178, --154734431, --155690674, --156550825, --157316298, --157986149, --158561410, --159041176, --159427086, --159718451, --159916548, --160020582, --160032332, --159951337, --159779143, --159515147, --159161329, --158717499, --158185432, --157564678, --156857347, --156063474, --155185008, --154221601, --153175426, --152046727, --150837654, --149548057, --148180246, --146734704, --145213706, --143617181, --141947434, --140205146, --138392776, --136510514, --134560819, --132544622, --130464445, --128320507, --126115178, --123849532, --121526221, --119145720, --116710510, --114221879, --111682456, --109092675, --106454825, --103770291, --101041818, --98270160, --95457755, --92606223, --89718259, --86794577, --83837395, --80848397, --77830331, --74784179, --71712237, --68616354, --65499123, --62361390, --59205117, --56032152, --52845129, --49645224, --46434530, --43215084, --39989380, --36758496, --33524217, --30288565, --27054001, --23821849, --20593926, --17372347, --14159320, --10955954, --7763647, --4584416, --1420431, -1726908, -4856115, -7965053, -11051765, -14114989, -17153587, -20165512, -23148908, -26102328, -29024647, -31913805, -34768253, -37586799, -40368755, -43112232, -45815788, -48478013, -51098183, -53674369, -56205373, -58689945, -61127693, -63516834, -65856322, -68144797, -70381920, -72565965, -74696201, -76771518, -78791971, -80756044, -82663155, -84512076, -86302872, -88034067, -89705316, -91315544, -92865092, -94352657, -95778072, -97140241, -98439585, -99674922, -100846363, -101953029, -102995643, -103973242, -104886114, -105733366, -106515783, -107232507, -107884029, -108469586, -108990146, -109445031, -109834907, -110159075, -110418598, -110612956, -110743021, -110808247, -110809873, -110747573, -110622392, -110433872, -110183341, -109870630, -109496925, -109061853, -108566821, -108011814, -107398172, -106725651, -105995758, -105208649, -104365776, -103466973, -102513780, -101506507, -100446746, -99334505, -98171433, -96958015, -95695913, -94385172, -93027406, -91623219, -90174378, -88681103, -87145094, -85567114, -83948941, -82290788, -80594255, -78860190, -77090470, -75285527, -73447070, -71576122, -69674546, -67742761, -65782346, -63794384, -61780793, -59742181, -57680191, -55596034, -53491542, -51367245, -49224577, -47064766, -44889688, -42700109, -40497558, -38283410, -36059459, -33826411, -31585598, -29338397, -27086596, -24831081, -22573215, -20314456, -18056430, -15799888, -13545910, -11295904, -9051483, -6813612, -4583444, -2362482, -152205, --2046514, --4232760, --6405078, --8562051, --10702661, --12825994, --14930573, --17015184, --19078982, --21121361, --23140947, --25136591, --27107282, --29052375, --30970456, --32860543, --34721731, --36553615, --38354874, --40124623, --41861868, --43566233, --45236425, --46871781, --48471484, --50035443, --51562506, --53052109, --54503334, --55916090, --57289239, --58622387, --59914726, --61166369, --62376298, --63544241, --64669360, --65751822, --66790682, --67785875, --68736719, --69643614, --70505769, --71323237, --72095315, --72822435, --73503872, --74139832, --74729705, --75274073, --75772337, --76224828, --76630970, --76991410, --77305656, --77574197, --77796578, --77973591, --78104888, --78191082, --78231765, --78227787, --78178906, --78085845, --77948266, --77767093, --77542200, --77274423, --76963506, --76610446, --76215234, --75778805, --75300971, --74782775, --74224327, --73626669, --72989720, --72314602, --71601546, --70851655, --70064886, --69242354, --68384382, --67492158, --66565755, --65606354, --64614392, --63591082, --62536507, --61451798, --60337466, --59194800, --58024034, --56826376, --55602460, --54353584, --53079977, --51782773, --50462662, --49120984, --47758105, --46375208, --44973078, --43553013, --42115335, --40661095, --39191102, --37706696, --36208364, --34697230, --33174211, --31640600, --30096851, --28543956, --26982847, --25414822, --23840464, --22260795, --20676812, --19089709, --17499984, --15908468, --14316132, --12724175, --11133249, --9544240, --7958198, --6376234, --4798939, --3227038, --1661555, --103565, -1446230, -2987101, -4517998, -6037984, -7546475, -9042956, -10526443, -11996036, -13451023, -14890857, -16314514, -17721207, -19110300, -20481414, -21833586, -23166092, -24478220, -25769611, -27039309, -28286749, -29511342, -30712939, -31890678, -33044057, -34172405, -35275563, -36352672, -37403349, -38427003, -39423626, -40392440, -41333144, -42245116, -43128383, -43982211, -44806449, -45600591, -46364840, -47098569, -47801711, -48473727, -49114838, -49724455, -50302623, -50848874, -51363545, -51846135, -52296779, -52715020, -53101240, -53455010, -53776585, -54065600, -54322557, -54547131, -54739663, -54899810, -55028111, -55124307, -55188827, -55221380, -55222572, -55192228, -55130859, -55038225, -54914980, -54761033, -54576974, -54362622, -54118682, -53845150, -53542695, -53211202, -52851427, -52463450, -52047991, -51604968, -51135146, -50638673, -50116337, -49568129, -48994861, -48396765, -47774658, -47128548, -46459228, -45766990, -45052710, -44316493, -43559189, -42781174, -41983339, -41165794, -40329347, -39474419, -38601939, -37712110, -36805777, -35883432, -34945984, -33993615, -33027089, -32046926, -31054070, -30048815, -29031979, -28004160, -26966277, -25918608, -24861885, -23796723, -22724052, -21644243, -20558050, -19466141, -18369382, -17268088, -16162890, -15054445, -13943628, -12830865, -11716830, -10602238, -9487911, -8374236, -7261776, -6151235, -5043417, -3938790, -2837924, -1741550, -650377, --435204, --1514773, --2587638, --3653109, --4710700, --5759963, --6800171, --7830712, --8851149, --9861153, --10860035, --11847221, --12822216, --13784698, --14733981, --15669597, --16591140, --17498438, --18390866, --19267997, --20129356, --20974762, --21803581, --22615471, --23410012, --24187134, --24946258, --25687095, --26409195, --27112509, --27796483, --28460937, --29105505, --29730269, --30334749, --30918819, --31482081, --32024624, --32545988, --33046126, --33524693, --33981867, --34417247, --34830850, --35222329, --35591891, --35939181, --36264307, --36566990, --36847536, --37105661, --37341533, --37554878, --37746021, --37914721, --38061211, --38185256, --38287239, --38366977, --38424762, --38460388, --38474270, --38466280, --38436775, --38385595, --38313205, --38219543, --38105021, --37969515, --37813522, --37637035, --37440507, --37223843, --36987554, --36731686, --36456739, --36162666, --35850010, --35518873, --35169788, --34802724, --34418227, --34016443, --33597949, --33162777, --32711507, --32244345, --31761885, --31264164, --30751745, --30224868, --29684158, --29129713, --28562123, --27981679, --27389002, --26784181, --26167762, --25540059, --24901722, --24252917, --23594223, --22926012, --22248923, --21563113, --20869110, --20167303, --19458342, --18742448, --18020168, --17291929, --16558346, --15819604, --15076174, --14328481, --13577150, --12822445, --12064865, --11304882, --10543086, --9779720, --9015209, --8250021, --7484741, --6719667, --5955234, --5191932, --4430285, --3670541, --2913036, --2158236, --1406657, --658617, -85527, -825280, -1560174, -2289926, -3014260, -3732701, -4444806, -5150245, -5848747, -6539832, -7223129, -7898368, -8565383, -9223733, -9873071, -10513075, -11143565, -11764092, -12374365, -12974099, -13563194, -14141234, -14707964, -15263070, -15806466, -16337748, -16856735, -17363175, -17857079, -18338088, -18806059, -19260708, -19702046, -20129723, -20543652, -20943584, -21329597, -21701383, -22058894, -22401875, -22730421, -23044252, -23343385, -23627618, -23897120, -24151661, -24391299, -24615824, -24825417, -25019868, -25199285, -25363488, -25512702, -25646760, -25765809, -25869680, -25958622, -26032502, -26091517, -26135536, -26164850, -26179375, -26179344, -26164644, -26135585, -26092113, -26034498, -25962646, -25876887, -25777203, -25663899, -25536906, -25396578, -25242934, -25076305, -24896644, -24704311, -24499364, -24282163, -24052697, -23811348, -23558211, -23293664, -23017702, -22730703, -22432787, -22124357, -21805445, -21476448, -21137523, -20789074, -20431134, -20064079, -19688086, -19303582, -18910646, -18509679, -18100894, -17684716, -17261223, -16830785, -16393630, -15950197, -15500602, -15045231, -14584340, -14118348, -13647355, -13171699, -12691641, -12207609, -11719754, -11228437, -10733948, -10236700, -9736830, -9234652, -8730459, -8224662, -7717439, -7209110, -6699986, -6190443, -5680626, -5170792, -4661242, -4152348, -3644304, -3137385, -2631912, -2128229, -1626510, -1126973, -629931, -135715, --355469, --843402, --1327763, --1808270, --2284755, --2757069, --3224916, --3688026, --4146190, --4599250, --5046898, --5488901, --5925074, --6355314, --6779333, --7196918, --7607862, --8012069, --8409254, --8799255, --9181907, --9557181, --9924822, --10284691, --10636595, --10980501, --11316157, --11643459, --11962240, --12272514, --12574056, --12866786, --13150528, --13425307, --13690910, --13947306, --14194356, --14432139, --14660477, --14879363, --15088645, --15288408, --15478483, --15658898, --15829522, --15990474, --16141613, --16282992, --16414484, --16536222, --16648083, --16750160, --16842353, --16924831, --16997506, --17060493, --17113697, --17157297, --17191222, --17215613, --17230389, --17235750, --17231648, --17218249, --17195484, --17163567, --17122473, --17072392, --17013271, --16945340, --16868599, --16783258, --16689284, --16586915, --16476178, --16357294, --16230239, --16095254, --15952382, --15801866, --15643700, --15478137, --15305245, --15125274, --14938221, --14744336, --14543701, --14336583, --14123005, --13903232, --13677369, --13445685, --13208205, --12965179, --12716724, --12463120, --12204418, --11940874, --11672628, --11399952, --11122887, --10841668, --10556438, --10267479, --9974863, --9678839, --9379572, --9077334, --8772193, --8464370, --8154033, --7841459, --7526740, --7210102, --6891729, --6571875, --6250617, --5928143, --5604631, --5280339, --4955374, --4629936, --4304221, --3978468, --3652773, --3327303, --3002250, --2677848, --2354215, --2031520, --1709962, --1389747, --1070968, --753751, --438281, --124760, -186691, -495939, -802786, -1107056, -1408639, -1707439, -2003270, -2295964, -2585396, -2871472, -3154006, -3432861, -3707940, -3979193, -4246453, -4509594, -4768498, -5023110, -5273258, -5518843, -5759760, -5995988, -6227371, -6453823, -6675229, -6891575, -7102708, -7308575, -7509086, -7704267, -7893987, -8078205, -8256820, -8429855, -8597183, -8758786, -8914577, -9064605, -9208760, -9347039, -9479353, -9605758, -9726154, -9840566, -9948924, -10051316, -10147660, -10237999, -10322257, -10400525, -10472731, -10538934, -10599070, -10653248, -10701410, -10743630, -10779849, -10810183, -10834587, -10853155, -10865840, -10872775, -10873933, -10869421, -10859197, -10843400, -10822013, -10795156, -10762793, -10725068, -10681980, -10633658, -10580078, -10521391, -10457608, -10388869, -10315156, -10236621, -10153290, -10065313, -9972683, -9875561, -9773986, -9668111, -9557933, -9443609, -9325184, -9202823, -9076535, -8946481, -8812721, -8675419, -8534581, -8390359, -8242821, -8092134, -7938325, -7781551, -7621894, -7459519, -7294449, -7126832, -6956750, -6784374, -6609741, -6433003, -6254252, -6073651, -5891227, -5707114, -5521403, -5334259, -5145731, -4955957, -4765041, -4573140, -4380296, -4186630, -3992245, -3797298, -3601843, -3406004, -3209891, -3013645, -2817308, -2620977, -2424757, -2228787, -2033128, -1837884, -1643168, -1449107, -1255755, -1063192, -871528, -680885, -491329, -302942, -115833, --69891, --254183, --436990, --618208, --797740, --975518, --1151487, --1325539, --1497588, --1667578, --1835474, --2001175, --2164603, --2325693, --2484411, --2640658, --2794375, --2945514, --3094068, --3239949, --3383105, --3523475, --3661049, --3795739, --3927507, --4056301, --4182128, --4304909, --4424616, --4541189, --4654642, --4764898, --4871946, --4975742, --5076322, --5173620, --5267633, --5358312, --5445689, --5529702, --5610360, --5687620, --5761528, --5832032, --5899149, --5962833, --6023137, --6080011, --6133489, --6183535, --6230216, --6273495, --6313411, --6349927, --6383111, --6412929, --6439430, --6462582, --6482459, --6499037, --6512371, --6522432, --6529297, --6532949, --6533453, --6530785, --6525030, --6516181, --6504306, --6489387, --6471510, --6450672, --6426949, --6400323, --6370884, --6338633, --6303653, --6265930, --6225556, --6182542, --6136972, --6088835, --6038222, --5985148, --5929704, --5871883, --5811781, --5749418, --5684887, --5618180, --5549390, --5478541, --5405727, --5330951, --5254303, --5175817, --5095584, --5013604, --4929960, --4844689, --4757882, --4669550, --4579780, --4488613, --4396142, --4302370, --4207380, --4111213, --4013962, --3915640, --3816329, --3716076, --3614967, --3513009, --3410272, --3306801, --3202684, --3097938, --2992636, --2886829, --2780600, --2673962, --2566977, --2459696, --2352199, --2244507, --2136684, --2028782, --1920874, --1812971, --1705121, --1597373, --1489799, --1382421, --1275290, --1168459, --1061994, --955913, --850253, --745067, --640414, --536322, --432828, --329984, --227841, --126414, --25726, -74177, -173245, -271455, -368780, -465170, -560585, -655003, -748412, -840765, -932024, -1022164, -1111173, -1199003, -1285630, -1371035, -1455222, -1538151, -1619799, -1700140, -1779174, -1856860, -1933182, -2008118, -2081679, -2153827, -2224550, -2293824, -2361659, -2428020, -2492903, -2556292, -2618211, -2678631, -2737549, -2794945, -2850839, -2905201, -2958036, -3009325, -3059097, -3107325, -3154018, -3199156, -3242768, -3284829, -3325357, -3364336, -3401806, -3437747, -3472179, -3505082, -3536494, -3566396, -3594812, -3621723, -3647174, -3671149, -3693673, -3714729, -3734362, -3752557, -3769346, -3784715, -3798715, -3811334, -3822606, -3832516, -3841112, -3848384, -3854368, -3859049, -3862479, -3864649, -3865599, -3865314, -3863845, -3861188, -3857383, -3852418, -3846346, -3839164, -3830915, -3821584, -3811225, -3799836, -3787460, -3774084, -3759760, -3744487, -3728310, -3711218, -3693263, -3674447, -3654814, -3634352, -3613113, -3591098, -3568353, -3544866, -3520689, -3495824, -3470316, -3444153, -3417383, -3390012, -3362082, -3333586, -3304570, -3275042, -3245044, -3214563, -3183645, -3152295, -3120556, -3088416, -3055921, -3023078, -2989927, -2956457, -2922708, -2888688, -2854437, -2819945, -2785255, -2750373, -2715338, -2680135, -2644802, -2609344, -2573798, -2538153, -2502446, -2466684, -2430901, -2395085, -2359269, -2323458, -2287688, -2251947, -2216270, -2180661, -2145152, -2109728, -2074417, -2039222, -2004173, -1969258, -1934504, -1899918, -1865524, -1831311, -1797303, -1763503, -1729936, -1696594, -1663499, -1630656, -1598085, -1565774, -1533740, -1501984, -1470527, -1439358, -1408495, -1377941, -1347715, -1317803, -1288221, -1258970, -1230067, -1201504, -1173294, -1145440, -1117954, -1090824, -1064057, -1037655, -1011629, -985969, -960683, -935774, -911250, -887101, -863334, -839947, -816951, -794337, -772110, -750271, -728827, -707764, -687085, -666787, -646876, -627343, -608189, -589415, -571023, -553003, -535356, -518081, -501181, -484646, -468479, -452677, -437242, -422161, -407434, -393055, -379026, -365337, -351987, -338974, -326296, -313944, -301916, -290208, -278820, -267744, -256978, -246518, -236362, -226500, -216928, -207640, -198636, -189906, -181447, -173255, -165327, -157655, -150236, -143064, -136137, -129449, -122995, -116772, -110776, -104999, -99436, -94081, -88932, -83981, -79224, -74658, -70277, -66077, -62052, -58198, -54512, -50989, -47624, -44413, -41353, -38438, -35663, -33023, -30515, -28134, -25876, -23736, -21712, -19799, -17992, -16290, -14687, -13182, -11769, -10446, -9210, -8057, -6982, -5983, -5056, -4198, -3407, -2678, -2010, -1400, -844, -341, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -}; -} diff --git a/services/audioflinger/test-resample.cpp b/services/audioflinger/test-resample.cpp new file mode 100644 index 0000000..b082e8c --- /dev/null +++ b/services/audioflinger/test-resample.cpp @@ -0,0 +1,274 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "AudioResampler.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace android; + +struct HeaderWav { + HeaderWav(size_t size, int nc, int sr, int bits) { + strncpy(RIFF, "RIFF", 4); + chunkSize = size + sizeof(HeaderWav); + strncpy(WAVE, "WAVE", 4); + strncpy(fmt, "fmt ", 4); + fmtSize = 16; + audioFormat = 1; + numChannels = nc; + samplesRate = sr; + byteRate = sr * numChannels * (bits/8); + align = nc*(bits/8); + bitsPerSample = bits; + strncpy(data, "data", 4); + dataSize = size; + } + + char RIFF[4]; // RIFF + uint32_t chunkSize; // File size + char WAVE[4]; // WAVE + char fmt[4]; // fmt\0 + uint32_t fmtSize; // fmt size + uint16_t audioFormat; // 1=PCM + uint16_t numChannels; // num channels + uint32_t samplesRate; // sample rate in hz + uint32_t byteRate; // Bps + uint16_t align; // 2=16-bit mono, 4=16-bit stereo + uint16_t bitsPerSample; // bits per sample + char data[4]; // "data" + uint32_t dataSize; // size +}; + +static int usage(const char* name) { + fprintf(stderr,"Usage: %s [-p] [-h] [-s] [-q {dq|lq|mq|hq|vhq}] [-i input-sample-rate] " + "[-o output-sample-rate] [] \n", name); + fprintf(stderr," -p enable profiling\n"); + fprintf(stderr," -h create wav file\n"); + fprintf(stderr," -s stereo\n"); + fprintf(stderr," -q resampler quality\n"); + fprintf(stderr," dq : default quality\n"); + fprintf(stderr," lq : low quality\n"); + fprintf(stderr," mq : medium quality\n"); + fprintf(stderr," hq : high quality\n"); + fprintf(stderr," vhq : very high quality\n"); + fprintf(stderr," -i input file sample rate\n"); + fprintf(stderr," -o output file sample rate\n"); + return -1; +} + +int main(int argc, char* argv[]) { + + const char* const progname = argv[0]; + bool profiling = false; + bool writeHeader = false; + int channels = 1; + int input_freq = 0; + int output_freq = 0; + AudioResampler::src_quality quality = AudioResampler::DEFAULT_QUALITY; + + int ch; + while ((ch = getopt(argc, argv, "phsq:i:o:")) != -1) { + switch (ch) { + case 'p': + profiling = true; + break; + case 'h': + writeHeader = true; + break; + case 's': + channels = 2; + break; + case 'q': + if (!strcmp(optarg, "dq")) + quality = AudioResampler::DEFAULT_QUALITY; + else if (!strcmp(optarg, "lq")) + quality = AudioResampler::LOW_QUALITY; + else if (!strcmp(optarg, "mq")) + quality = AudioResampler::MED_QUALITY; + else if (!strcmp(optarg, "hq")) + quality = AudioResampler::HIGH_QUALITY; + else if (!strcmp(optarg, "vhq")) + quality = AudioResampler::VERY_HIGH_QUALITY; + else { + usage(progname); + return -1; + } + break; + case 'i': + input_freq = atoi(optarg); + break; + case 'o': + output_freq = atoi(optarg); + break; + case '?': + default: + usage(progname); + return -1; + } + } + argc -= optind; + argv += optind; + + const char* file_in = NULL; + const char* file_out = NULL; + if (argc == 1) { + file_out = argv[0]; + } else if (argc == 2) { + file_in = argv[0]; + file_out = argv[1]; + } else { + usage(progname); + return -1; + } + + // ---------------------------------------------------------- + + size_t input_size; + void* input_vaddr; + if (argc == 2) { + struct stat st; + if (stat(file_in, &st) < 0) { + fprintf(stderr, "stat: %s\n", strerror(errno)); + return -1; + } + + int input_fd = open(file_in, O_RDONLY); + if (input_fd < 0) { + fprintf(stderr, "open: %s\n", strerror(errno)); + return -1; + } + + input_size = st.st_size; + input_vaddr = mmap(0, input_size, PROT_READ, MAP_PRIVATE, input_fd, 0); + if (input_vaddr == MAP_FAILED ) { + fprintf(stderr, "mmap: %s\n", strerror(errno)); + return -1; + } + } else { + double k = 1000; // Hz / s + double time = (input_freq / 2) / k; + size_t input_frames = size_t(input_freq * time); + input_size = channels * sizeof(int16_t) * input_frames; + input_vaddr = malloc(input_size); + int16_t* in = (int16_t*)input_vaddr; + for (size_t i=0 ; iframeCount = mNumFrames; + buffer->i16 = mAddr; + return NO_ERROR; + } + virtual void releaseBuffer(Buffer* buffer) { + } + } provider(input_vaddr, input_size, channels); + + size_t input_frames = input_size / (channels * sizeof(int16_t)); + size_t output_size = 2 * 4 * ((int64_t) input_frames * output_freq) / input_freq; + output_size &= ~7; // always stereo, 32-bits + + void* output_vaddr = malloc(output_size); + + if (profiling) { + AudioResampler* resampler = AudioResampler::create(16, channels, + output_freq, quality); + + size_t out_frames = output_size/8; + resampler->setSampleRate(input_freq); + resampler->setVolume(0x1000, 0x1000); + + memset(output_vaddr, 0, output_size); + timespec start, end; + clock_gettime(CLOCK_MONOTONIC_HR, &start); + resampler->resample((int*) output_vaddr, out_frames, &provider); + resampler->resample((int*) output_vaddr, out_frames, &provider); + resampler->resample((int*) output_vaddr, out_frames, &provider); + resampler->resample((int*) output_vaddr, out_frames, &provider); + clock_gettime(CLOCK_MONOTONIC_HR, &end); + int64_t start_ns = start.tv_sec * 1000000000LL + start.tv_nsec; + int64_t end_ns = end.tv_sec * 1000000000LL + end.tv_nsec; + int64_t time = (end_ns - start_ns)/4; + printf("%f Mspl/s\n", out_frames/(time/1e9)/1e6); + + delete resampler; + } + + AudioResampler* resampler = AudioResampler::create(16, channels, + output_freq, quality); + size_t out_frames = output_size/8; + resampler->setSampleRate(input_freq); + resampler->setVolume(0x1000, 0x1000); + + memset(output_vaddr, 0, output_size); + resampler->resample((int*) output_vaddr, out_frames, &provider); + + // down-mix (we just truncate and keep the left channel) + int32_t* out = (int32_t*) output_vaddr; + int16_t* convert = (int16_t*) malloc(out_frames * channels * sizeof(int16_t)); + for (size_t i = 0; i < out_frames; i++) { + for (int j=0 ; j> 12; + if (s > 32767) s = 32767; + else if (s < -32768) s = -32768; + convert[i * channels + j] = int16_t(s); + } + } + + // write output to disk + int output_fd = open(file_out, O_WRONLY | O_CREAT | O_TRUNC, + S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + if (output_fd < 0) { + fprintf(stderr, "open: %s\n", strerror(errno)); + return -1; + } + + if (writeHeader) { + HeaderWav wav(out_frames * channels * sizeof(int16_t), channels, output_freq, 16); + write(output_fd, &wav, sizeof(wav)); + } + + write(output_fd, convert, out_frames * channels * sizeof(int16_t)); + close(output_fd); + + return 0; +} diff --git a/tools/resampler_tools/Android.mk b/tools/resampler_tools/Android.mk new file mode 100644 index 0000000..e8cbe39 --- /dev/null +++ b/tools/resampler_tools/Android.mk @@ -0,0 +1,17 @@ +# Copyright 2005 The Android Open Source Project +# +# Android.mk for resampler_tools +# + + +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := \ + fir.cpp + +LOCAL_MODULE := fir + +include $(BUILD_HOST_EXECUTABLE) + + diff --git a/tools/resampler_tools/fir.cpp b/tools/resampler_tools/fir.cpp new file mode 100644 index 0000000..cc3d509 --- /dev/null +++ b/tools/resampler_tools/fir.cpp @@ -0,0 +1,281 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include + +static double sinc(double x) { + if (fabs(x) == 0.0f) return 1.0f; + return sin(x) / x; +} + +static double sqr(double x) { + return x*x; +} + +static double I0(double x) { + // from the Numerical Recipes in C p. 237 + double ax,ans,y; + ax=fabs(x); + if (ax < 3.75) { + y=x/3.75; + y*=y; + ans=1.0+y*(3.5156229+y*(3.0899424+y*(1.2067492 + +y*(0.2659732+y*(0.360768e-1+y*0.45813e-2))))); + } else { + y=3.75/ax; + ans=(exp(ax)/sqrt(ax))*(0.39894228+y*(0.1328592e-1 + +y*(0.225319e-2+y*(-0.157565e-2+y*(0.916281e-2 + +y*(-0.2057706e-1+y*(0.2635537e-1+y*(-0.1647633e-1 + +y*0.392377e-2)))))))); + } + return ans; +} + +static double kaiser(int k, int N, double beta) { + if (k < 0 || k > N) + return 0; + return I0(beta * sqrt(1.0 - sqr((2.0*k)/N - 1.0))) / I0(beta); +} + + +static void usage(char* name) { + fprintf(stderr, + "usage: %s [-h] [-d] [-s sample_rate] [-c cut-off_frequency] [-n half_zero_crossings] [-f {float|fixed}] [-b beta] [-v dBFS] [-l lerp]\n" + " %s [-h] [-d] [-s sample_rate] [-c cut-off_frequency] [-n half_zero_crossings] [-f {float|fixed}] [-b beta] [-v dBFS] -p M/N\n" + " -h this help message\n" + " -d debug, print comma-separated coefficient table\n" + " -p generate poly-phase filter coefficients, with sample increment M/N\n" + " -s sample rate (48000)\n" + " -c cut-off frequency (20478)\n" + " -n number of zero-crossings on one side (8)\n" + " -l number of lerping bits (4)\n" + " -f output format, can be fixed-point or floating-point (fixed)\n" + " -b kaiser window parameter beta (7.865 [-80dB])\n" + " -v attenuation in dBFS (0)\n", + name, name + ); + exit(0); +} + +int main(int argc, char** argv) +{ + // nc is the number of bits to store the coefficients + const int nc = 32; + + bool polyphase = false; + unsigned int polyM = 160; + unsigned int polyN = 147; + bool debug = false; + double Fs = 48000; + double Fc = 20478; + double atten = 1; + int format = 0; + + + // in order to keep the errors associated with the linear + // interpolation of the coefficients below the quantization error + // we must satisfy: + // 2^nz >= 2^(nc/2) + // + // for 16 bit coefficients that would be 256 + // + // note that increasing nz only increases memory requirements, + // but doesn't increase the amount of computation to do. + // + // + // see: + // Smith, J.O. Digital Audio Resampling Home Page + // https://ccrma.stanford.edu/~jos/resample/, 2011-03-29 + // + int nz = 4; + + // | 0.1102*(A - 8.7) A > 50 + // beta = | 0.5842*(A - 21)^0.4 + 0.07886*(A - 21) 21 <= A <= 50 + // | 0 A < 21 + // with A is the desired stop-band attenuation in dBFS + // + // for eg: + // + // 30 dB 2.210 + // 40 dB 3.384 + // 50 dB 4.538 + // 60 dB 5.658 + // 70 dB 6.764 + // 80 dB 7.865 + // 90 dB 8.960 + // 100 dB 10.056 + double beta = 7.865; + + + // 2*nzc = (A - 8) / (2.285 * dw) + // with dw the transition width = 2*pi*dF/Fs + // + int nzc = 8; + + // + // Example: + // 44.1 KHz to 48 KHz resampling + // 100 dB rejection above 28 KHz + // (the spectrum will fold around 24 KHz and we want 100 dB rejection + // at the point where the folding reaches 20 KHz) + // ...___|_____ + // | \| + // | ____/|\____ + // |/alias| \ + // ------/------+------\---------> KHz + // 20 24 28 + + // Transition band 8 KHz, or dw = 1.0472 + // + // beta = 10.056 + // nzc = 20 + // + + int ch; + while ((ch = getopt(argc, argv, ":hds:c:n:f:l:b:p:v:")) != -1) { + switch (ch) { + case 'd': + debug = true; + break; + case 'p': + if (sscanf(optarg, "%u/%u", &polyM, &polyN) != 2) { + usage(argv[0]); + } + polyphase = true; + break; + case 's': + Fs = atof(optarg); + break; + case 'c': + Fc = atof(optarg); + break; + case 'n': + nzc = atoi(optarg); + break; + case 'l': + nz = atoi(optarg); + break; + case 'f': + if (!strcmp(optarg,"fixed")) format = 0; + else if (!strcmp(optarg,"float")) format = 1; + else usage(argv[0]); + break; + case 'b': + beta = atof(optarg); + break; + case 'v': + atten = pow(10, -fabs(atof(optarg))*0.05 ); + break; + case 'h': + default: + usage(argv[0]); + break; + } + } + + // cut off frequency ratio Fc/Fs + double Fcr = Fc / Fs; + + + // total number of coefficients (one side) + const int M = (1 << nz); + const int N = M * nzc; + + // generate the right half of the filter + if (!debug) { + printf("// cmd-line: "); + for (int i=1 ; i= (1LL<<(nc-1))) yi = (1LL<<(nc-1))-1; + printf("0x%08x, ", int32_t(yi)); + } else { + printf("%.9g%s ", y, debug ? "," : "f,"); + } + } + } + } else { + for (int j=0 ; j= (1LL<<(nc-1))) yi = (1LL<<(nc-1))-1; + printf("0x%08x", int32_t(yi)); + } else { + printf("%.9g%s", y, debug ? "" : "f"); + } + + if (debug && (i==nzc-1)) { + } else { + printf(", "); + } + } + } + } + + if (!debug) { + printf("\n};"); + } + printf("\n"); + return 0; +} + +// http://www.csee.umbc.edu/help/sound/AFsp-V2R1/html/audio/ResampAudio.html + + -- cgit v1.1 From b7c8e91880463ff4981e3e53e98e45d68e2fe374 Mon Sep 17 00:00:00 2001 From: Andreas Huber Date: Tue, 27 Nov 2012 15:02:53 -0800 Subject: Add support for HLS playlists of type 'event'. related-to-bug: 6870049 Squashed commit of the following: commit eee2f3ba6bb7335f4e285632726db85645669929 Author: Andreas Huber Date: Tue Nov 27 15:02:01 2012 -0800 Make everything a lot less verbose by default. Change-Id: I884d7a7901aa1e7d4ff590f065ca57a79d2af8b3 commit 6bbdb837ed5bd88008e45efb8faf595e4051ba26 Author: Andreas Huber Date: Tue Nov 27 14:34:46 2012 -0800 HLS now properly signals media time changes at discontinuities including the start of playback (which may not necessarily be at time 0 if the playlist is of type 'event' and hasn't completed yet). Change-Id: I5ab747d024f9b8d0df72a4e06a12ebb29f62802e commit 1555589832b1878a144a976a643e1af4d61f877c Author: Andreas Huber Date: Tue Nov 27 14:32:28 2012 -0800 As part of a time discontinuity, clients of IStreamListener can now signal the corresponding media time after the discontinuity, i.e. the first PTS timestamp following the discontinuity will be considered equivalent to the specified media time and media buffers timestamped accordingly. Change-Id: Id7db7679b7faa6efd6270620ff52e34e884f3e92 commit 5c24c605c073a11c426d025b1e7478fc1ad8365a Author: Andreas Huber Date: Tue Nov 27 13:00:56 2012 -0800 NuPlayer sources now expose flags() and can announce that duration may change (increase) dynamically, in which case duration will be polled at 1 second intervals and communicated to the upper layers. Change-Id: I45102909b7a19eed0dda576747e3814d742a0eea commit ecb71de8e281e61971a2cd73e7161a97540bc357 Author: Andreas Huber Date: Tue Nov 27 12:57:47 2012 -0800 Stop caching duration in MediaPlayer, duration could increase dynamically. Change-Id: I7bb2f16c0abe49debdf45c776d2266aa069d7791 commit 544aec5823e6d7a3e97e15b6b23546616bcd343e Author: Andreas Huber Date: Tue Nov 27 08:46:28 2012 -0800 An attempt to add support for "event" style HLS playlists. Change-Id: I3dfb2e801ecaff8f5d8bdb3a4fca1b18aeeb2c60 Change-Id: I48cf7f65a654d33f2f49ded74f8be22aed9e3b98 --- include/media/IStreamSource.h | 5 ++ include/media/mediaplayer.h | 1 - media/libmedia/IStreamSource.cpp | 3 + media/libmedia/mediaplayer.cpp | 36 ++++++--- .../nuplayer/GenericSource.cpp | 4 +- .../libmediaplayerservice/nuplayer/GenericSource.h | 3 +- .../nuplayer/HTTPLiveSource.cpp | 28 ++++++- .../nuplayer/HTTPLiveSource.h | 3 +- media/libmediaplayerservice/nuplayer/NuPlayer.cpp | 49 ++++++++++++ media/libmediaplayerservice/nuplayer/NuPlayer.h | 6 ++ .../nuplayer/NuPlayerSource.h | 9 ++- .../libmediaplayerservice/nuplayer/RTSPSource.cpp | 4 +- media/libmediaplayerservice/nuplayer/RTSPSource.h | 3 +- .../nuplayer/StreamingSource.cpp | 20 ++++- .../nuplayer/StreamingSource.h | 2 + .../nuplayer/mp4/MP4Source.cpp | 4 + .../libmediaplayerservice/nuplayer/mp4/MP4Source.h | 2 + .../chromium_http/ChromiumHTTPDataSource.cpp | 7 +- media/libstagefright/httplive/LiveSession.cpp | 92 +++++++++++++++++++--- media/libstagefright/httplive/M3UParser.cpp | 9 ++- media/libstagefright/include/LiveSession.h | 14 +++- media/libstagefright/include/M3UParser.h | 2 + media/libstagefright/mpeg2ts/ATSParser.cpp | 16 +++- 23 files changed, 276 insertions(+), 46 deletions(-) diff --git a/include/media/IStreamSource.h b/include/media/IStreamSource.h index 61b9d5a..39e0a9e 100644 --- a/include/media/IStreamSource.h +++ b/include/media/IStreamSource.h @@ -73,6 +73,11 @@ struct IStreamListener : public IInterface { // ATSParser::DiscontinuityType. static const char *const kKeyDiscontinuityMask; + // Optionally signalled as part of a discontinuity that includes + // DISCONTINUITY_TIME. It indicates the media time (in us) to be associated + // with the next PTS occuring in the stream. The value is of type int64_t. + static const char *const kKeyMediaTimeUs; + virtual void issueCommand( Command cmd, bool synchronous, const sp &msg = NULL) = 0; }; diff --git a/include/media/mediaplayer.h b/include/media/mediaplayer.h index f7cebc5..d753eba 100644 --- a/include/media/mediaplayer.h +++ b/include/media/mediaplayer.h @@ -249,7 +249,6 @@ private: sp mListener; void* mCookie; media_player_states mCurrentState; - int mDuration; int mCurrentPosition; int mSeekPosition; bool mPrepareSync; diff --git a/media/libmedia/IStreamSource.cpp b/media/libmedia/IStreamSource.cpp index 78d810d..68ffca8 100644 --- a/media/libmedia/IStreamSource.cpp +++ b/media/libmedia/IStreamSource.cpp @@ -32,6 +32,9 @@ const char *const IStreamListener::kKeyResumeAtPTS = "resume-at-PTS"; // static const char *const IStreamListener::kKeyDiscontinuityMask = "discontinuity-mask"; +// static +const char *const IStreamListener::kKeyMediaTimeUs = "media-time-us"; + enum { // IStreamSource SET_LISTENER = IBinder::FIRST_CALL_TRANSACTION, diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp index b52a37d..bbbf4b6 100644 --- a/media/libmedia/mediaplayer.cpp +++ b/media/libmedia/mediaplayer.cpp @@ -47,7 +47,6 @@ MediaPlayer::MediaPlayer() ALOGV("constructor"); mListener = NULL; mCookie = NULL; - mDuration = -1; mStreamType = AUDIO_STREAM_MUSIC; mCurrentPosition = -1; mSeekPosition = -1; @@ -90,7 +89,6 @@ void MediaPlayer::disconnect() // always call with lock held void MediaPlayer::clear_l() { - mDuration = -1; mCurrentPosition = -1; mSeekPosition = -1; mVideoWidth = mVideoHeight = 0; @@ -395,14 +393,14 @@ status_t MediaPlayer::getCurrentPosition(int *msec) status_t MediaPlayer::getDuration_l(int *msec) { - ALOGV("getDuration"); + ALOGV("getDuration_l"); bool isValidState = (mCurrentState & (MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_STARTED | MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_STOPPED | MEDIA_PLAYER_PLAYBACK_COMPLETE)); if (mPlayer != 0 && isValidState) { - status_t ret = NO_ERROR; - if (mDuration <= 0) - ret = mPlayer->getDuration(&mDuration); - if (msec) - *msec = mDuration; + int durationMs; + status_t ret = mPlayer->getDuration(&durationMs); + if (msec) { + *msec = durationMs; + } return ret; } ALOGE("Attempt to call getDuration without a valid mediaplayer"); @@ -422,14 +420,28 @@ status_t MediaPlayer::seekTo_l(int msec) if ( msec < 0 ) { ALOGW("Attempt to seek to invalid position: %d", msec); msec = 0; - } else if ((mDuration > 0) && (msec > mDuration)) { - ALOGW("Attempt to seek to past end of file: request = %d, EOF = %d", msec, mDuration); - msec = mDuration; } + + int durationMs; + status_t err = mPlayer->getDuration(&durationMs); + + if (err != OK) { + ALOGW("Stream has no duration and is therefore not seekable."); + return err; + } + + if (msec > durationMs) { + ALOGW("Attempt to seek to past end of file: request = %d, " + "durationMs = %d", + msec, + durationMs); + + msec = durationMs; + } + // cache duration mCurrentPosition = msec; if (mSeekPosition < 0) { - getDuration_l(NULL); mSeekPosition = msec; return mPlayer->seekTo(msec); } diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp index f0c3240..f281879 100644 --- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp +++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp @@ -258,8 +258,8 @@ void NuPlayer::GenericSource::readBuffer( } } -bool NuPlayer::GenericSource::isSeekable() { - return true; +uint32_t NuPlayer::GenericSource::flags() const { + return FLAG_SEEKABLE; } } // namespace android diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.h b/media/libmediaplayerservice/nuplayer/GenericSource.h index e50b855..e1ce2c1 100644 --- a/media/libmediaplayerservice/nuplayer/GenericSource.h +++ b/media/libmediaplayerservice/nuplayer/GenericSource.h @@ -47,7 +47,8 @@ struct NuPlayer::GenericSource : public NuPlayer::Source { virtual status_t getDuration(int64_t *durationUs); virtual status_t seekTo(int64_t seekTimeUs); - virtual bool isSeekable(); + + virtual uint32_t flags() const; protected: virtual ~GenericSource(); diff --git a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp index 1e98f35..5dcca12 100644 --- a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp +++ b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp @@ -121,9 +121,20 @@ status_t NuPlayer::HTTPLiveSource::feedMoreTSData() { } else { if (buffer[0] == 0x00) { // XXX legacy - sp extra; + + uint8_t type = buffer[1]; + + sp extra = new AMessage; + + if (type & 2) { + int64_t mediaTimeUs; + memcpy(&mediaTimeUs, &buffer[2], sizeof(mediaTimeUs)); + + extra->setInt64(IStreamListener::kKeyMediaTimeUs, mediaTimeUs); + } + mTSParser->signalDiscontinuity( - buffer[1] == 0x00 + ((type & 1) == 0) ? ATSParser::DISCONTINUITY_SEEK : ATSParser::DISCONTINUITY_FORMATCHANGE, extra); @@ -181,8 +192,17 @@ status_t NuPlayer::HTTPLiveSource::seekTo(int64_t seekTimeUs) { return OK; } -bool NuPlayer::HTTPLiveSource::isSeekable() { - return mLiveSession->isSeekable(); +uint32_t NuPlayer::HTTPLiveSource::flags() const { + uint32_t flags = 0; + if (mLiveSession->isSeekable()) { + flags |= FLAG_SEEKABLE; + } + + if (mLiveSession->hasDynamicDuration()) { + flags |= FLAG_DYNAMIC_DURATION; + } + + return flags; } } // namespace android diff --git a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h index 9950a9e..79f4ab8 100644 --- a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h +++ b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h @@ -41,7 +41,8 @@ struct NuPlayer::HTTPLiveSource : public NuPlayer::Source { virtual status_t getDuration(int64_t *durationUs); virtual status_t seekTo(int64_t seekTimeUs); - virtual bool isSeekable(); + + virtual uint32_t flags() const; protected: virtual ~HTTPLiveSource(); diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp index 1ddf775..ff27873 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp @@ -59,6 +59,7 @@ NuPlayer::NuPlayer() mVideoEOS(false), mScanSourcesPending(false), mScanSourcesGeneration(0), + mPollDurationGeneration(0), mTimeDiscontinuityPending(false), mFlushingAudio(NONE), mFlushingVideo(NONE), @@ -210,6 +211,28 @@ void NuPlayer::onMessageReceived(const sp &msg) { break; } + case kWhatPollDuration: + { + int32_t generation; + CHECK(msg->findInt32("generation", &generation)); + + if (generation != mPollDurationGeneration) { + // stale + break; + } + + int64_t durationUs; + if (mDriver != NULL && mSource->getDuration(&durationUs) == OK) { + sp driver = mDriver.promote(); + if (driver != NULL) { + driver->notifyDuration(durationUs); + } + } + + msg->post(1000000ll); // poll again in a second. + break; + } + case kWhatSetVideoNativeWindow: { ALOGV("kWhatSetVideoNativeWindow"); @@ -274,6 +297,9 @@ void NuPlayer::onMessageReceived(const sp &msg) { ALOGV("scanning sources haveAudio=%d, haveVideo=%d", mAudioDecoder != NULL, mVideoDecoder != NULL); + bool mHadAnySourcesBefore = + (mAudioDecoder != NULL) || (mVideoDecoder != NULL); + if (mNativeWindow != NULL) { instantiateDecoder(false, &mVideoDecoder); } @@ -282,6 +308,17 @@ void NuPlayer::onMessageReceived(const sp &msg) { instantiateDecoder(true, &mAudioDecoder); } + if (!mHadAnySourcesBefore + && (mAudioDecoder != NULL || mVideoDecoder != NULL)) { + // This is the first time we've found anything playable. + + uint32_t flags = mSource->flags(); + + if (flags & Source::FLAG_DYNAMIC_DURATION) { + schedulePollDuration(); + } + } + status_t err; if ((err = mSource->feedMoreTSData()) != OK) { if (mAudioDecoder == NULL && mVideoDecoder == NULL) { @@ -534,6 +571,8 @@ void NuPlayer::onMessageReceived(const sp &msg) { { ALOGV("kWhatReset"); + cancelPollDuration(); + if (mRenderer != NULL) { // There's an edge case where the renderer owns all output // buffers and is paused, therefore the decoder will not read @@ -976,4 +1015,14 @@ status_t NuPlayer::setVideoScalingMode(int32_t mode) { return OK; } +void NuPlayer::schedulePollDuration() { + sp msg = new AMessage(kWhatPollDuration, id()); + msg->setInt32("generation", mPollDurationGeneration); + msg->post(); +} + +void NuPlayer::cancelPollDuration() { + ++mPollDurationGeneration; +} + } // namespace android diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h index 36d3a9c..31efb2e 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h @@ -88,6 +88,7 @@ private: kWhatSeek = 'seek', kWhatPause = 'paus', kWhatResume = 'rsme', + kWhatPollDuration = 'polD', }; wp mDriver; @@ -107,6 +108,8 @@ private: bool mScanSourcesPending; int32_t mScanSourcesGeneration; + int32_t mPollDurationGeneration; + enum FlushStatus { NONE, AWAITING_DISCONTINUITY, @@ -150,6 +153,9 @@ private: void finishReset(); void postScanSources(); + void schedulePollDuration(); + void cancelPollDuration(); + DISALLOW_EVIL_CONSTRUCTORS(NuPlayer); }; diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerSource.h b/media/libmediaplayerservice/nuplayer/NuPlayerSource.h index 66aeff3..a635340 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerSource.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayerSource.h @@ -25,6 +25,11 @@ namespace android { struct ABuffer; struct NuPlayer::Source : public RefBase { + enum Flags { + FLAG_SEEKABLE = 1, + FLAG_DYNAMIC_DURATION = 2, + }; + Source() {} virtual void start() = 0; @@ -47,9 +52,7 @@ struct NuPlayer::Source : public RefBase { return INVALID_OPERATION; } - virtual bool isSeekable() { - return false; - } + virtual uint32_t flags() const = 0; protected: virtual ~Source() {} diff --git a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp index 5a7a785..cf455bd 100644 --- a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp +++ b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp @@ -210,8 +210,8 @@ void NuPlayer::RTSPSource::performSeek(int64_t seekTimeUs) { mHandler->seek(seekTimeUs); } -bool NuPlayer::RTSPSource::isSeekable() { - return true; +uint32_t NuPlayer::RTSPSource::flags() const { + return FLAG_SEEKABLE; } void NuPlayer::RTSPSource::onMessageReceived(const sp &msg) { diff --git a/media/libmediaplayerservice/nuplayer/RTSPSource.h b/media/libmediaplayerservice/nuplayer/RTSPSource.h index f07c724..779d791 100644 --- a/media/libmediaplayerservice/nuplayer/RTSPSource.h +++ b/media/libmediaplayerservice/nuplayer/RTSPSource.h @@ -46,7 +46,8 @@ struct NuPlayer::RTSPSource : public NuPlayer::Source { virtual status_t getDuration(int64_t *durationUs); virtual status_t seekTo(int64_t seekTimeUs); - virtual bool isSeekable(); + + virtual uint32_t flags() const; void onMessageReceived(const sp &msg); diff --git a/media/libmediaplayerservice/nuplayer/StreamingSource.cpp b/media/libmediaplayerservice/nuplayer/StreamingSource.cpp index a1fd2ed..7159404 100644 --- a/media/libmediaplayerservice/nuplayer/StreamingSource.cpp +++ b/media/libmediaplayerservice/nuplayer/StreamingSource.cpp @@ -93,8 +93,22 @@ status_t NuPlayer::StreamingSource::feedMoreTSData() { } else { if (buffer[0] == 0x00) { // XXX legacy + + if (extra == NULL) { + extra = new AMessage; + } + + uint8_t type = buffer[1]; + + if (type & 2) { + int64_t mediaTimeUs; + memcpy(&mediaTimeUs, &buffer[2], sizeof(mediaTimeUs)); + + extra->setInt64(IStreamListener::kKeyMediaTimeUs, mediaTimeUs); + } + mTSParser->signalDiscontinuity( - buffer[1] == 0x00 + ((type & 1) == 0) ? ATSParser::DISCONTINUITY_SEEK : ATSParser::DISCONTINUITY_FORMATCHANGE, extra); @@ -159,5 +173,9 @@ status_t NuPlayer::StreamingSource::dequeueAccessUnit( return err; } +uint32_t NuPlayer::StreamingSource::flags() const { + return 0; +} + } // namespace android diff --git a/media/libmediaplayerservice/nuplayer/StreamingSource.h b/media/libmediaplayerservice/nuplayer/StreamingSource.h index 3971e2a..a27b58a 100644 --- a/media/libmediaplayerservice/nuplayer/StreamingSource.h +++ b/media/libmediaplayerservice/nuplayer/StreamingSource.h @@ -35,6 +35,8 @@ struct NuPlayer::StreamingSource : public NuPlayer::Source { virtual status_t dequeueAccessUnit(bool audio, sp *accessUnit); + virtual uint32_t flags() const; + protected: virtual ~StreamingSource(); diff --git a/media/libmediaplayerservice/nuplayer/mp4/MP4Source.cpp b/media/libmediaplayerservice/nuplayer/mp4/MP4Source.cpp index ffb3a65..a62d5a2 100644 --- a/media/libmediaplayerservice/nuplayer/mp4/MP4Source.cpp +++ b/media/libmediaplayerservice/nuplayer/mp4/MP4Source.cpp @@ -133,4 +133,8 @@ status_t MP4Source::dequeueAccessUnit( return mParser->dequeueAccessUnit(audio, accessUnit); } +uint32_t MP4Source::flags() const { + return 0; +} + } // namespace android diff --git a/media/libmediaplayerservice/nuplayer/mp4/MP4Source.h b/media/libmediaplayerservice/nuplayer/mp4/MP4Source.h index 4e927af..abca236 100644 --- a/media/libmediaplayerservice/nuplayer/mp4/MP4Source.h +++ b/media/libmediaplayerservice/nuplayer/mp4/MP4Source.h @@ -35,6 +35,8 @@ struct MP4Source : public NuPlayer::Source { virtual status_t dequeueAccessUnit( bool audio, sp *accessUnit); + virtual uint32_t flags() const; + protected: virtual ~MP4Source(); diff --git a/media/libstagefright/chromium_http/ChromiumHTTPDataSource.cpp b/media/libstagefright/chromium_http/ChromiumHTTPDataSource.cpp index 32a0ec8..91ce175 100644 --- a/media/libstagefright/chromium_http/ChromiumHTTPDataSource.cpp +++ b/media/libstagefright/chromium_http/ChromiumHTTPDataSource.cpp @@ -65,7 +65,10 @@ status_t ChromiumHTTPDataSource::connect( if (getUID(&uid)) { mDelegate->setUID(uid); } + +#if defined(LOG_NDEBUG) && !LOG_NDEBUG LOG_PRI(ANDROID_LOG_VERBOSE, LOG_TAG, "connect on behalf of uid %d", uid); +#endif return connect_l(uri, headers, offset); } @@ -78,8 +81,10 @@ status_t ChromiumHTTPDataSource::connect_l( disconnect_l(); } - LOG_PRI(ANDROID_LOG_INFO, LOG_TAG, +#if defined(LOG_NDEBUG) && !LOG_NDEBUG + LOG_PRI(ANDROID_LOG_VERBOSE, LOG_TAG, "connect to @%lld", offset); +#endif mURI = uri; mContentType = String8("application/octet-stream"); diff --git a/media/libstagefright/httplive/LiveSession.cpp b/media/libstagefright/httplive/LiveSession.cpp index 93d6429..733753b 100644 --- a/media/libstagefright/httplive/LiveSession.cpp +++ b/media/libstagefright/httplive/LiveSession.cpp @@ -55,7 +55,9 @@ LiveSession::LiveSession(uint32_t flags, bool uidValid, uid_t uid) mSeqNumber(-1), mSeekTimeUs(-1), mNumRetries(0), + mStartOfPlayback(true), mDurationUs(-1), + mDurationFixed(false), mSeekDone(false), mDisconnectPending(false), mMonitorQueueGeneration(0), @@ -311,6 +313,8 @@ status_t LiveSession::fetchFile( } sp LiveSession::fetchPlaylist(const char *url, bool *unchanged) { + ALOGV("fetchPlaylist '%s'", url); + *unchanged = false; sp buffer; @@ -364,6 +368,37 @@ sp LiveSession::fetchPlaylist(const char *url, bool *unchanged) { return playlist; } +int64_t LiveSession::getSegmentStartTimeUs(int32_t seqNumber) const { + CHECK(mPlaylist != NULL); + + int32_t firstSeqNumberInPlaylist; + if (mPlaylist->meta() == NULL || !mPlaylist->meta()->findInt32( + "media-sequence", &firstSeqNumberInPlaylist)) { + firstSeqNumberInPlaylist = 0; + } + + int32_t lastSeqNumberInPlaylist = + firstSeqNumberInPlaylist + (int32_t)mPlaylist->size() - 1; + + CHECK_GE(seqNumber, firstSeqNumberInPlaylist); + CHECK_LE(seqNumber, lastSeqNumberInPlaylist); + + int64_t segmentStartUs = 0ll; + for (int32_t index = 0; + index < seqNumber - firstSeqNumberInPlaylist; ++index) { + sp itemMeta; + CHECK(mPlaylist->itemAt( + index, NULL /* uri */, &itemMeta)); + + int64_t itemDurationUs; + CHECK(itemMeta->findInt64("durationUs", &itemDurationUs)); + + segmentStartUs += itemDurationUs; + } + + return segmentStartUs; +} + static double uniformRand() { return (double)rand() / RAND_MAX; } @@ -512,8 +547,6 @@ rinse_repeat: url = mMasterURL; } - bool firstTime = (mPlaylist == NULL); - if ((ssize_t)bandwidthIndex != mPrevBandwidthIndex) { // If we switch bandwidths, do not pay any heed to whether // playlists changed since the last time... @@ -535,11 +568,12 @@ rinse_repeat: mPlaylist = playlist; } - if (firstTime) { + if (!mDurationFixed) { Mutex::Autolock autoLock(mLock); - if (!mPlaylist->isComplete()) { + if (!mPlaylist->isComplete() && !mPlaylist->isEvent()) { mDurationUs = -1; + mDurationFixed = true; } else { mDurationUs = 0; for (size_t i = 0; i < mPlaylist->size(); ++i) { @@ -552,6 +586,8 @@ rinse_repeat: mDurationUs += itemDurationUs; } + + mDurationFixed = mPlaylist->isComplete(); } } @@ -569,7 +605,7 @@ rinse_repeat: bool bandwidthChanged = false; if (mSeekTimeUs >= 0) { - if (mPlaylist->isComplete()) { + if (mPlaylist->isComplete() || mPlaylist->isEvent()) { size_t index = 0; int64_t segmentStartUs = 0; while (index < mPlaylist->size()) { @@ -617,13 +653,21 @@ rinse_repeat: mCondition.broadcast(); } + const int32_t lastSeqNumberInPlaylist = + firstSeqNumberInPlaylist + (int32_t)mPlaylist->size() - 1; + if (mSeqNumber < 0) { - mSeqNumber = firstSeqNumberInPlaylist; + if (mPlaylist->isComplete()) { + mSeqNumber = firstSeqNumberInPlaylist; + } else { + // If this is a live session, start 3 segments from the end. + mSeqNumber = lastSeqNumberInPlaylist - 3; + if (mSeqNumber < firstSeqNumberInPlaylist) { + mSeqNumber = firstSeqNumberInPlaylist; + } + } } - int32_t lastSeqNumberInPlaylist = - firstSeqNumberInPlaylist + (int32_t)mPlaylist->size() - 1; - if (mSeqNumber < firstSeqNumberInPlaylist || mSeqNumber > lastSeqNumberInPlaylist) { if (mPrevBandwidthIndex != (ssize_t)bandwidthIndex) { @@ -686,6 +730,9 @@ rinse_repeat: range_length = -1; } + ALOGV("fetching segment %d from (%d .. %d)", + mSeqNumber, firstSeqNumberInPlaylist, lastSeqNumberInPlaylist); + sp buffer; status_t err = fetchFile(uri.c_str(), &buffer, range_offset, range_length); if (err != OK) { @@ -737,6 +784,11 @@ rinse_repeat: bandwidthChanged = false; } + if (mStartOfPlayback) { + seekDiscontinuity = true; + mStartOfPlayback = false; + } + if (seekDiscontinuity || explicitDiscontinuity || bandwidthChanged) { // Signal discontinuity. @@ -747,7 +799,19 @@ rinse_repeat: memset(tmp->data(), 0, tmp->size()); // signal a 'hard' discontinuity for explicit or bandwidthChanged. - tmp->data()[1] = (explicitDiscontinuity || bandwidthChanged) ? 1 : 0; + uint8_t type = (explicitDiscontinuity || bandwidthChanged) ? 1 : 0; + + if (mPlaylist->isComplete() || mPlaylist->isEvent()) { + // If this was a live event this made no sense since + // we don't have access to all the segment before the current + // one. + int64_t segmentStartTimeUs = getSegmentStartTimeUs(mSeqNumber); + memcpy(tmp->data() + 2, &segmentStartTimeUs, sizeof(segmentStartTimeUs)); + + type |= 2; + } + + tmp->data()[1] = type; mDataSource->queueBuffer(tmp); } @@ -923,17 +987,21 @@ void LiveSession::onSeek(const sp &msg) { postMonitorQueue(); } -status_t LiveSession::getDuration(int64_t *durationUs) { +status_t LiveSession::getDuration(int64_t *durationUs) const { Mutex::Autolock autoLock(mLock); *durationUs = mDurationUs; return OK; } -bool LiveSession::isSeekable() { +bool LiveSession::isSeekable() const { int64_t durationUs; return getDuration(&durationUs) == OK && durationUs >= 0; } +bool LiveSession::hasDynamicDuration() const { + return !mDurationFixed; +} + } // namespace android diff --git a/media/libstagefright/httplive/M3UParser.cpp b/media/libstagefright/httplive/M3UParser.cpp index 7d3cf05..44e03dc 100644 --- a/media/libstagefright/httplive/M3UParser.cpp +++ b/media/libstagefright/httplive/M3UParser.cpp @@ -32,7 +32,8 @@ M3UParser::M3UParser( mBaseURI(baseURI), mIsExtM3U(false), mIsVariantPlaylist(false), - mIsComplete(false) { + mIsComplete(false), + mIsEvent(false) { mInitCheck = parse(data, size); } @@ -55,6 +56,10 @@ bool M3UParser::isComplete() const { return mIsComplete; } +bool M3UParser::isEvent() const { + return mIsEvent; +} + sp M3UParser::meta() { return mMeta; } @@ -200,6 +205,8 @@ status_t M3UParser::parse(const void *_data, size_t size) { err = parseCipherInfo(line, &itemMeta, mBaseURI); } else if (line.startsWith("#EXT-X-ENDLIST")) { mIsComplete = true; + } else if (line.startsWith("#EXT-X-PLAYLIST-TYPE:EVENT")) { + mIsEvent = true; } else if (line.startsWith("#EXTINF")) { if (mIsVariantPlaylist) { return ERROR_MALFORMED; diff --git a/media/libstagefright/include/LiveSession.h b/media/libstagefright/include/LiveSession.h index 3a11612..f329cc9 100644 --- a/media/libstagefright/include/LiveSession.h +++ b/media/libstagefright/include/LiveSession.h @@ -48,8 +48,10 @@ struct LiveSession : public AHandler { // Blocks until seek is complete. void seekTo(int64_t timeUs); - status_t getDuration(int64_t *durationUs); - bool isSeekable(); + status_t getDuration(int64_t *durationUs) const; + + bool isSeekable() const; + bool hasDynamicDuration() const; protected: virtual ~LiveSession(); @@ -95,10 +97,12 @@ private: int32_t mSeqNumber; int64_t mSeekTimeUs; int32_t mNumRetries; + bool mStartOfPlayback; - Mutex mLock; + mutable Mutex mLock; Condition mCondition; int64_t mDurationUs; + bool mDurationFixed; // Duration has been determined once and for all. bool mSeekDone; bool mDisconnectPending; @@ -136,6 +140,10 @@ private: static int SortByBandwidth(const BandwidthItem *, const BandwidthItem *); + // Returns the media time in us of the segment specified by seqNumber. + // This is computed by summing the durations of all segments before it. + int64_t getSegmentStartTimeUs(int32_t seqNumber) const; + DISALLOW_EVIL_CONSTRUCTORS(LiveSession); }; diff --git a/media/libstagefright/include/M3UParser.h b/media/libstagefright/include/M3UParser.h index e30d6fd..2d2f50f 100644 --- a/media/libstagefright/include/M3UParser.h +++ b/media/libstagefright/include/M3UParser.h @@ -33,6 +33,7 @@ struct M3UParser : public RefBase { bool isExtM3U() const; bool isVariantPlaylist() const; bool isComplete() const; + bool isEvent() const; sp meta(); @@ -54,6 +55,7 @@ private: bool mIsExtM3U; bool mIsVariantPlaylist; bool mIsComplete; + bool mIsEvent; sp mMeta; Vector mItems; diff --git a/media/libstagefright/mpeg2ts/ATSParser.cpp b/media/libstagefright/mpeg2ts/ATSParser.cpp index 9faa6bc..4f6c4b2 100644 --- a/media/libstagefright/mpeg2ts/ATSParser.cpp +++ b/media/libstagefright/mpeg2ts/ATSParser.cpp @@ -215,6 +215,14 @@ bool ATSParser::Program::parsePID( void ATSParser::Program::signalDiscontinuity( DiscontinuityType type, const sp &extra) { + int64_t mediaTimeUs; + if ((type & DISCONTINUITY_TIME) + && extra != NULL + && extra->findInt64( + IStreamListener::kKeyMediaTimeUs, &mediaTimeUs)) { + mFirstPTSValid = false; + } + for (size_t i = 0; i < mStreams.size(); ++i) { mStreams.editValueAt(i)->signalDiscontinuity(type, extra); } @@ -929,7 +937,13 @@ status_t ATSParser::feedTSPacket(const void *data, size_t size) { void ATSParser::signalDiscontinuity( DiscontinuityType type, const sp &extra) { - if (type == DISCONTINUITY_ABSOLUTE_TIME) { + int64_t mediaTimeUs; + if ((type & DISCONTINUITY_TIME) + && extra != NULL + && extra->findInt64( + IStreamListener::kKeyMediaTimeUs, &mediaTimeUs)) { + mAbsoluteTimeAnchorUs = mediaTimeUs; + } else if (type == DISCONTINUITY_ABSOLUTE_TIME) { int64_t timeUs; CHECK(extra->findInt64("timeUs", &timeUs)); -- cgit v1.1 From 0dbe5a9321b24b6883fbb2fe97cd9d525128b0b5 Mon Sep 17 00:00:00 2001 From: James Dong Date: Thu, 15 Nov 2012 14:00:26 -0800 Subject: Added optional intra macroblock refresh support for encoding o related-to-bug: 7524791 Change-Id: I95ac4ee925e2dbeb00b3cfb2e29c611698c5cc9f --- include/media/stagefright/ACodec.h | 1 + media/libstagefright/ACodec.cpp | 50 +++++++++++++++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/include/media/stagefright/ACodec.h b/include/media/stagefright/ACodec.h index cba8a6b..df1c46b 100644 --- a/include/media/stagefright/ACodec.h +++ b/include/media/stagefright/ACodec.h @@ -184,6 +184,7 @@ private: bool mChannelMaskPresent; int32_t mChannelMask; + status_t setCyclicIntraMacroblockRefresh(const sp &msg, int32_t mode); status_t allocateBuffersOnPort(OMX_U32 portIndex); status_t freeBuffersOnPort(OMX_U32 portIndex); status_t freeBuffer(OMX_U32 portIndex, size_t i); diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp index 84b4962..a01d03f 100644 --- a/media/libstagefright/ACodec.cpp +++ b/media/libstagefright/ACodec.cpp @@ -1630,6 +1630,43 @@ status_t ACodec::setupVideoEncoder(const char *mime, const sp &msg) { return err; } +status_t ACodec::setCyclicIntraMacroblockRefresh(const sp &msg, int32_t mode) { + OMX_VIDEO_PARAM_INTRAREFRESHTYPE params; + InitOMXParams(¶ms); + params.nPortIndex = kPortIndexOutput; + + params.eRefreshMode = static_cast(mode); + + if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic || + params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) { + int32_t mbs; + if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) { + return INVALID_OPERATION; + } + params.nCirMBs = mbs; + } + + if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive || + params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) { + int32_t mbs; + if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) { + return INVALID_OPERATION; + } + params.nAirMBs = mbs; + + int32_t ref; + if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) { + return INVALID_OPERATION; + } + params.nAirRef = ref; + } + + status_t err = mOMX->setParameter( + mNode, OMX_IndexParamVideoIntraRefresh, + ¶ms, sizeof(params)); + return err; +} + static OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) { if (iFramesInterval < 0) { return 0xFFFFFFFF; @@ -1825,11 +1862,22 @@ status_t ACodec::setupAVCEncoderParameters(const sp &msg) { frameRate = (float)tmp; } + status_t err = OK; + int32_t intraRefreshMode = 0; + if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) { + err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode); + if (err != OK) { + ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x", + err, intraRefreshMode); + return err; + } + } + OMX_VIDEO_PARAM_AVCTYPE h264type; InitOMXParams(&h264type); h264type.nPortIndex = kPortIndexOutput; - status_t err = mOMX->getParameter( + err = mOMX->getParameter( mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type)); if (err != OK) { -- cgit v1.1 From 13e8a0e8a14faaf3fe0bcebf4da1f2694d59565d Mon Sep 17 00:00:00 2001 From: James Dong Date: Thu, 15 Nov 2012 18:31:50 -0800 Subject: Reduce the frequency of IDR frames and add intra-fresh mode support for WiFi display The time interval between periodic neighboring IDR frames is increased from 1 second to 15 seconds. o related-to-bug: 7524791 Change-Id: Ic32f37448f952f329549eda5e73637ee3b02f046 --- .../libstagefright/wifi-display/source/Converter.cpp | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/media/libstagefright/wifi-display/source/Converter.cpp b/media/libstagefright/wifi-display/source/Converter.cpp index 82c98b9..7a87444 100644 --- a/media/libstagefright/wifi-display/source/Converter.cpp +++ b/media/libstagefright/wifi-display/source/Converter.cpp @@ -161,7 +161,24 @@ status_t Converter::initEncoder() { mOutputFormat->setInt32("bitrate", videoBitrate); mOutputFormat->setInt32("bitrate-mode", OMX_Video_ControlRateConstant); mOutputFormat->setInt32("frame-rate", 30); - mOutputFormat->setInt32("i-frame-interval", 1); // Iframes every 1 secs + mOutputFormat->setInt32("i-frame-interval", 15); // Iframes every 15 secs + + // Configure encoder to use intra macroblock refresh mode + mOutputFormat->setInt32("intra-refresh-mode", OMX_VIDEO_IntraRefreshCyclic); + + int width, height, mbs; + if (!mOutputFormat->findInt32("width", &width) + || !mOutputFormat->findInt32("height", &height)) { + return ERROR_UNSUPPORTED; + } + + // Update macroblocks in a cyclic fashion with 10% of all MBs within + // frame gets updated at one time. It takes about 10 frames to + // completely update a whole video frame. If the frame rate is 30, + // it takes about 333 ms in the best case (if next frame is not an IDR) + // to recover from a lost/corrupted packet. + mbs = (((width + 15) / 16) * ((height + 15) / 16) * 10) / 100; + mOutputFormat->setInt32("intra-refresh-CIR-mbs", mbs); } ALOGV("output format is '%s'", mOutputFormat->debugString(0).c_str()); -- cgit v1.1 From 5131d127a042ee88f903370be88845dc8c9f8578 Mon Sep 17 00:00:00 2001 From: Andreas Huber Date: Fri, 16 Nov 2012 10:38:11 -0800 Subject: [wfd] Support a low(er) power state by triggering PAUSE/RESUME. Change-Id: Ibe42bfa73816bbfeb7e652d435254d0171b89727 related-to-bug: 7638150 --- include/media/IRemoteDisplay.h | 3 + media/libmedia/IRemoteDisplay.cpp | 31 +++++ media/libmediaplayerservice/RemoteDisplay.cpp | 8 ++ media/libmediaplayerservice/RemoteDisplay.h | 2 + .../wifi-display/source/MediaPuller.cpp | 34 ++++- .../wifi-display/source/MediaPuller.h | 6 + .../wifi-display/source/PlaybackSession.cpp | 44 +++++++ .../wifi-display/source/PlaybackSession.h | 3 + .../wifi-display/source/WifiDisplaySource.cpp | 146 +++++++++++++++++---- .../wifi-display/source/WifiDisplaySource.h | 20 ++- 10 files changed, 267 insertions(+), 30 deletions(-) diff --git a/include/media/IRemoteDisplay.h b/include/media/IRemoteDisplay.h index a61704e..c8baae9 100644 --- a/include/media/IRemoteDisplay.h +++ b/include/media/IRemoteDisplay.h @@ -39,6 +39,9 @@ class IRemoteDisplay : public IInterface public: DECLARE_META_INTERFACE(RemoteDisplay); + virtual status_t pause() = 0; + virtual status_t resume() = 0; + // Disconnects the remote display and stops listening for new connections. virtual status_t dispose() = 0; }; diff --git a/media/libmedia/IRemoteDisplay.cpp b/media/libmedia/IRemoteDisplay.cpp index da25a15..1e15434 100644 --- a/media/libmedia/IRemoteDisplay.cpp +++ b/media/libmedia/IRemoteDisplay.cpp @@ -23,6 +23,8 @@ namespace android { enum { DISPOSE = IBinder::FIRST_CALL_TRANSACTION, + PAUSE, + RESUME, }; class BpRemoteDisplay: public BpInterface @@ -33,6 +35,20 @@ public: { } + virtual status_t pause() { + Parcel data, reply; + data.writeInterfaceToken(IRemoteDisplay::getInterfaceDescriptor()); + remote()->transact(PAUSE, data, &reply); + return reply.readInt32(); + } + + virtual status_t resume() { + Parcel data, reply; + data.writeInterfaceToken(IRemoteDisplay::getInterfaceDescriptor()); + remote()->transact(RESUME, data, &reply); + return reply.readInt32(); + } + status_t dispose() { Parcel data, reply; @@ -55,6 +71,21 @@ status_t BnRemoteDisplay::onTransact( reply->writeInt32(dispose()); return NO_ERROR; } + + case PAUSE: + { + CHECK_INTERFACE(IRemoteDisplay, data, reply); + reply->writeInt32(pause()); + return OK; + } + + case RESUME: + { + CHECK_INTERFACE(IRemoteDisplay, data, reply); + reply->writeInt32(resume()); + return OK; + } + default: return BBinder::onTransact(code, data, reply, flags); } diff --git a/media/libmediaplayerservice/RemoteDisplay.cpp b/media/libmediaplayerservice/RemoteDisplay.cpp index 5baa3ad..20e6513 100644 --- a/media/libmediaplayerservice/RemoteDisplay.cpp +++ b/media/libmediaplayerservice/RemoteDisplay.cpp @@ -40,6 +40,14 @@ RemoteDisplay::RemoteDisplay( RemoteDisplay::~RemoteDisplay() { } +status_t RemoteDisplay::pause() { + return mSource->pause(); +} + +status_t RemoteDisplay::resume() { + return mSource->resume(); +} + status_t RemoteDisplay::dispose() { mSource->stop(); diff --git a/media/libmediaplayerservice/RemoteDisplay.h b/media/libmediaplayerservice/RemoteDisplay.h index 0d87250..bd8b684 100644 --- a/media/libmediaplayerservice/RemoteDisplay.h +++ b/media/libmediaplayerservice/RemoteDisplay.h @@ -33,6 +33,8 @@ struct WifiDisplaySource; struct RemoteDisplay : public BnRemoteDisplay { RemoteDisplay(const sp &client, const char *iface); + virtual status_t pause(); + virtual status_t resume(); virtual status_t dispose(); protected: diff --git a/media/libstagefright/wifi-display/source/MediaPuller.cpp b/media/libstagefright/wifi-display/source/MediaPuller.cpp index ab69c4a..189bea3 100644 --- a/media/libstagefright/wifi-display/source/MediaPuller.cpp +++ b/media/libstagefright/wifi-display/source/MediaPuller.cpp @@ -34,7 +34,8 @@ MediaPuller::MediaPuller( : mSource(source), mNotify(notify), mPullGeneration(0), - mIsAudio(false) { + mIsAudio(false), + mPaused(false) { sp meta = source->getFormat(); const char *mime; CHECK(meta->findCString(kKeyMIMEType, &mime)); @@ -71,6 +72,14 @@ void MediaPuller::stopAsync(const sp ¬ify) { msg->post(); } +void MediaPuller::pause() { + (new AMessage(kWhatPause, id()))->post(); +} + +void MediaPuller::resume() { + (new AMessage(kWhatResume, id()))->post(); +} + void MediaPuller::onMessageReceived(const sp &msg) { switch (msg->what()) { case kWhatStart: @@ -95,7 +104,6 @@ void MediaPuller::onMessageReceived(const sp &msg) { uint32_t replyID; CHECK(msg->senderAwaitsResponse(&replyID)); - response->postReply(replyID); break; } @@ -130,6 +138,16 @@ void MediaPuller::onMessageReceived(const sp &msg) { MediaBuffer *mbuf; status_t err = mSource->read(&mbuf); + if (mPaused) { + if (err == OK) { + mbuf->release(); + mbuf = NULL; + } + + schedulePull(); + break; + } + if (err != OK) { if (err == ERROR_END_OF_STREAM) { ALOGI("stream ended."); @@ -176,6 +194,18 @@ void MediaPuller::onMessageReceived(const sp &msg) { break; } + case kWhatPause: + { + mPaused = true; + break; + } + + case kWhatResume: + { + mPaused = false; + break; + } + default: TRESPASS(); } diff --git a/media/libstagefright/wifi-display/source/MediaPuller.h b/media/libstagefright/wifi-display/source/MediaPuller.h index 728da7b..1291bb3 100644 --- a/media/libstagefright/wifi-display/source/MediaPuller.h +++ b/media/libstagefright/wifi-display/source/MediaPuller.h @@ -35,6 +35,9 @@ struct MediaPuller : public AHandler { status_t start(); void stopAsync(const sp ¬ify); + void pause(); + void resume(); + protected: virtual void onMessageReceived(const sp &msg); virtual ~MediaPuller(); @@ -44,12 +47,15 @@ private: kWhatStart, kWhatStop, kWhatPull, + kWhatPause, + kWhatResume, }; sp mSource; sp mNotify; int32_t mPullGeneration; bool mIsAudio; + bool mPaused; status_t postSynchronouslyAndReturnError(const sp &msg); void schedulePull(); diff --git a/media/libstagefright/wifi-display/source/PlaybackSession.cpp b/media/libstagefright/wifi-display/source/PlaybackSession.cpp index 4e5eb52..916f797 100644 --- a/media/libstagefright/wifi-display/source/PlaybackSession.cpp +++ b/media/libstagefright/wifi-display/source/PlaybackSession.cpp @@ -76,6 +76,9 @@ struct WifiDisplaySource::PlaybackSession::Track : public AHandler { status_t start(); void stopAsync(); + void pause(); + void resume(); + void queueAccessUnit(const sp &accessUnit); sp dequeueAccessUnit(); @@ -208,6 +211,14 @@ void WifiDisplaySource::PlaybackSession::Track::stopAsync() { } } +void WifiDisplaySource::PlaybackSession::Track::pause() { + mMediaPuller->pause(); +} + +void WifiDisplaySource::PlaybackSession::Track::resume() { + mMediaPuller->resume(); +} + void WifiDisplaySource::PlaybackSession::Track::onMessageReceived( const sp &msg) { switch (msg->what()) { @@ -325,6 +336,7 @@ WifiDisplaySource::PlaybackSession::PlaybackSession( mInterfaceAddr(interfaceAddr), mHDCP(hdcp), mWeAreDead(false), + mPaused(false), mLastLifesignUs(), mVideoTrackIndex(-1), mPrevTimeUs(-1ll), @@ -383,6 +395,8 @@ void WifiDisplaySource::PlaybackSession::updateLiveness() { status_t WifiDisplaySource::PlaybackSession::play() { updateLiveness(); + (new AMessage(kWhatResume, id()))->post(); + return OK; } @@ -413,6 +427,8 @@ status_t WifiDisplaySource::PlaybackSession::onFinishPlay2() { status_t WifiDisplaySource::PlaybackSession::pause() { updateLiveness(); + (new AMessage(kWhatPause, id()))->post(); + return OK; } @@ -590,6 +606,34 @@ void WifiDisplaySource::PlaybackSession::onMessageReceived( break; } + case kWhatPause: + { + if (mPaused) { + break; + } + + for (size_t i = 0; i < mTracks.size(); ++i) { + mTracks.editValueAt(i)->pause(); + } + + mPaused = true; + break; + } + + case kWhatResume: + { + if (!mPaused) { + break; + } + + for (size_t i = 0; i < mTracks.size(); ++i) { + mTracks.editValueAt(i)->resume(); + } + + mPaused = false; + break; + } + default: TRESPASS(); } diff --git a/media/libstagefright/wifi-display/source/PlaybackSession.h b/media/libstagefright/wifi-display/source/PlaybackSession.h index dabc1c4..b9d193b 100644 --- a/media/libstagefright/wifi-display/source/PlaybackSession.h +++ b/media/libstagefright/wifi-display/source/PlaybackSession.h @@ -84,6 +84,8 @@ private: kWhatUpdateSurface, kWhatFinishPlay, kWhatPacketize, + kWhatPause, + kWhatResume, }; sp mNetSession; @@ -93,6 +95,7 @@ private: in_addr mInterfaceAddr; sp mHDCP; bool mWeAreDead; + bool mPaused; int64_t mLastLifesignUs; diff --git a/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp b/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp index 78d6e62..08f67f9 100644 --- a/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp +++ b/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp @@ -65,41 +65,50 @@ WifiDisplaySource::WifiDisplaySource( WifiDisplaySource::~WifiDisplaySource() { } -status_t WifiDisplaySource::start(const char *iface) { - CHECK_EQ(mState, INITIALIZED); - - sp msg = new AMessage(kWhatStart, id()); - msg->setString("iface", iface); - - sp response; - status_t err = msg->postAndAwaitResponse(&response); +static status_t PostAndAwaitResponse( + const sp &msg, sp *response) { + status_t err = msg->postAndAwaitResponse(response); if (err != OK) { return err; } - if (!response->findInt32("err", &err)) { + if (response == NULL || !(*response)->findInt32("err", &err)) { err = OK; } return err; } +status_t WifiDisplaySource::start(const char *iface) { + CHECK_EQ(mState, INITIALIZED); + + sp msg = new AMessage(kWhatStart, id()); + msg->setString("iface", iface); + + sp response; + return PostAndAwaitResponse(msg, &response); +} + status_t WifiDisplaySource::stop() { sp msg = new AMessage(kWhatStop, id()); sp response; - status_t err = msg->postAndAwaitResponse(&response); + return PostAndAwaitResponse(msg, &response); +} - if (err != OK) { - return err; - } +status_t WifiDisplaySource::pause() { + sp msg = new AMessage(kWhatPause, id()); - if (!response->findInt32("err", &err)) { - err = OK; - } + sp response; + return PostAndAwaitResponse(msg, &response); +} - return err; +status_t WifiDisplaySource::resume() { + sp msg = new AMessage(kWhatResume, id()); + + sp response; + return PostAndAwaitResponse(msg, &response); } void WifiDisplaySource::onMessageReceived(const sp &msg) { @@ -236,6 +245,20 @@ void WifiDisplaySource::onMessageReceived(const sp &msg) { mClient->onDisplayError( IRemoteDisplayClient::kDisplayErrorUnknown); } + +#if 0 + // testing only. + char val[PROPERTY_VALUE_MAX]; + if (property_get("media.wfd.trigger", val, NULL)) { + if (!strcasecmp(val, "pause") && mState == PLAYING) { + mState = PLAYING_TO_PAUSED; + sendTrigger(mClientSessionID, TRIGGER_PAUSE); + } else if (!strcasecmp(val, "play") && mState == PAUSED) { + mState = PAUSED_TO_PLAYING; + sendTrigger(mClientSessionID, TRIGGER_PLAY); + } + } +#endif break; } @@ -254,8 +277,8 @@ void WifiDisplaySource::onMessageReceived(const sp &msg) { if (mState >= AWAITING_CLIENT_PLAY) { // We have a session, i.e. a previous SETUP succeeded. - status_t err = sendM5( - mClientSessionID, true /* requestShutdown */); + status_t err = sendTrigger( + mClientSessionID, TRIGGER_TEARDOWN); if (err == OK) { mState = AWAITING_CLIENT_TEARDOWN; @@ -273,6 +296,46 @@ void WifiDisplaySource::onMessageReceived(const sp &msg) { break; } + case kWhatPause: + { + uint32_t replyID; + CHECK(msg->senderAwaitsResponse(&replyID)); + + status_t err = OK; + + if (mState != PLAYING) { + err = INVALID_OPERATION; + } else { + mState = PLAYING_TO_PAUSED; + sendTrigger(mClientSessionID, TRIGGER_PAUSE); + } + + sp response = new AMessage; + response->setInt32("err", err); + response->postReply(replyID); + break; + } + + case kWhatResume: + { + uint32_t replyID; + CHECK(msg->senderAwaitsResponse(&replyID)); + + status_t err = OK; + + if (mState != PAUSED) { + err = INVALID_OPERATION; + } else { + mState = PAUSED_TO_PLAYING; + sendTrigger(mClientSessionID, TRIGGER_PLAY); + } + + sp response = new AMessage; + response->setInt32("err", err); + response->postReply(replyID); + break; + } + case kWhatReapDeadClients: { mReaperPending = false; @@ -400,7 +463,7 @@ void WifiDisplaySource::onMessageReceived(const sp &msg) { if (mSetupTriggerDeferred) { mSetupTriggerDeferred = false; - sendM5(mClientSessionID, false /* requestShutdown */); + sendTrigger(mClientSessionID, TRIGGER_SETUP); } break; } @@ -574,13 +637,25 @@ status_t WifiDisplaySource::sendM4(int32_t sessionID) { return OK; } -status_t WifiDisplaySource::sendM5(int32_t sessionID, bool requestShutdown) { +status_t WifiDisplaySource::sendTrigger( + int32_t sessionID, TriggerType triggerType) { AString body = "wfd_trigger_method: "; - if (requestShutdown) { - ALOGI("Sending TEARDOWN trigger."); - body.append("TEARDOWN"); - } else { - body.append("SETUP"); + switch (triggerType) { + case TRIGGER_SETUP: + body.append("SETUP"); + break; + case TRIGGER_TEARDOWN: + ALOGI("Sending TEARDOWN trigger."); + body.append("TEARDOWN"); + break; + case TRIGGER_PAUSE: + body.append("PAUSE"); + break; + case TRIGGER_PLAY: + body.append("PLAY"); + break; + default: + TRESPASS(); } body.append("\r\n"); @@ -807,7 +882,7 @@ status_t WifiDisplaySource::onReceiveM4Response( return OK; } - return sendM5(sessionID, false /* requestShutdown */); + return sendTrigger(sessionID, TRIGGER_SETUP); } status_t WifiDisplaySource::onReceiveM5Response( @@ -1184,6 +1259,11 @@ status_t WifiDisplaySource::onPlayRequest( return err; } + if (mState == PAUSED_TO_PLAYING) { + mState = PLAYING; + return OK; + } + playbackSession->finishPlay(); CHECK_EQ(mState, AWAITING_CLIENT_PLAY); @@ -1205,6 +1285,12 @@ status_t WifiDisplaySource::onPauseRequest( return ERROR_MALFORMED; } + ALOGI("Received PAUSE request."); + + if (mState != PLAYING_TO_PAUSED) { + return INVALID_OPERATION; + } + status_t err = playbackSession->pause(); CHECK_EQ(err, (status_t)OK); @@ -1214,6 +1300,12 @@ status_t WifiDisplaySource::onPauseRequest( err = mNetSession->sendRequest(sessionID, response.c_str()); + if (err != OK) { + return err; + } + + mState = PAUSED; + return err; } diff --git a/media/libstagefright/wifi-display/source/WifiDisplaySource.h b/media/libstagefright/wifi-display/source/WifiDisplaySource.h index 1e855e7..974e070 100644 --- a/media/libstagefright/wifi-display/source/WifiDisplaySource.h +++ b/media/libstagefright/wifi-display/source/WifiDisplaySource.h @@ -44,6 +44,9 @@ struct WifiDisplaySource : public AHandler { status_t start(const char *iface); status_t stop(); + status_t pause(); + status_t resume(); + protected: virtual ~WifiDisplaySource(); virtual void onMessageReceived(const sp &msg); @@ -59,6 +62,9 @@ private: AWAITING_CLIENT_PLAY, ABOUT_TO_PLAY, PLAYING, + PLAYING_TO_PAUSED, + PAUSED, + PAUSED_TO_PLAYING, AWAITING_CLIENT_TEARDOWN, STOPPING, STOPPED, @@ -68,6 +74,8 @@ private: kWhatStart, kWhatRTSPNotify, kWhatStop, + kWhatPause, + kWhatResume, kWhatReapDeadClients, kWhatPlaybackSessionNotify, kWhatKeepAlive, @@ -147,7 +155,17 @@ private: status_t sendM1(int32_t sessionID); status_t sendM3(int32_t sessionID); status_t sendM4(int32_t sessionID); - status_t sendM5(int32_t sessionID, bool requestShutdown); + + enum TriggerType { + TRIGGER_SETUP, + TRIGGER_TEARDOWN, + TRIGGER_PAUSE, + TRIGGER_PLAY, + }; + + // M5 + status_t sendTrigger(int32_t sessionID, TriggerType triggerType); + status_t sendM16(int32_t sessionID); status_t onReceiveM1Response( -- cgit v1.1 From e5aed03d30ea0ce49728873c5b74f89ba05a9541 Mon Sep 17 00:00:00 2001 From: Andreas Huber Date: Thu, 29 Nov 2012 09:54:42 -0800 Subject: Enable retransmission of UDP packets in case we want to use it in our upcoming wfd _sink_ implementation. Change-Id: I4509c30d5a7b992bc841b73d63db902bbcf8f76a related-to-bug: 7638155 --- media/libstagefright/wifi-display/source/Sender.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/media/libstagefright/wifi-display/source/Sender.h b/media/libstagefright/wifi-display/source/Sender.h index 73e3d19..66951f7 100644 --- a/media/libstagefright/wifi-display/source/Sender.h +++ b/media/libstagefright/wifi-display/source/Sender.h @@ -25,7 +25,7 @@ namespace android { #define LOG_TRANSPORT_STREAM 0 #define TRACK_BANDWIDTH 0 -#define ENABLE_RETRANSMISSION 0 +#define ENABLE_RETRANSMISSION 1 // If retransmission is enabled the following define determines what // kind we support, if RETRANSMISSION_ACCORDING_TO_RFC_XXXX is 0 -- cgit v1.1 From 5dea84c39b5e790315b525009c635806e33c97e0 Mon Sep 17 00:00:00 2001 From: Glenn Kasten Date: Thu, 29 Nov 2012 14:09:41 -0800 Subject: Fix log spam Change-Id: Ie6c982af906dcfd3cdea4b771dfab1f7e47745ca --- services/audioflinger/audio-resampler/AudioResamplerCoefficients.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/audioflinger/audio-resampler/AudioResamplerCoefficients.cpp b/services/audioflinger/audio-resampler/AudioResamplerCoefficients.cpp index af3e40d..d45d697 100644 --- a/services/audioflinger/audio-resampler/AudioResamplerCoefficients.cpp +++ b/services/audioflinger/audio-resampler/AudioResamplerCoefficients.cpp @@ -15,7 +15,7 @@ */ #define LOG_TAG "ResamplerCoefficients" -#define LOG_NDEBUG 0 +//#define LOG_NDEBUG 0 #include -- cgit v1.1 From 47c1a5f7c13d82aa8834fd4543bd1d713b97808e Mon Sep 17 00:00:00 2001 From: Dylan Powers Date: Tue, 27 Nov 2012 16:06:38 -0800 Subject: Bug fix for the MediaPlayer::prepare() api. For an MP3 source, within the prepare command, ID3 tags are checked in search of gapless playback info. This causes problems for streamed sources. If ID3v2 tags aren't present, then a check is done for ID3v1 tags. This results in a read command that asks the cache to jump to the end of the file, and subsequently make an extra http call to request those bytes. For a streamed source, this causes the file to not be downloaded automatically when MediaPlayer::prepare() is called, and causes stuttering and extra buffering time to be needed when start() is finally called. The solution is to ignore the ID3v1 tags as the gapless info would never exist there, and only check for ID3v2 tags. Cherrypicked from external contribution ffd6ffc5429c45577fd8e9f8fa90e79bb91b8a84 b/7638165 Change-Id: I7d1b94cffbfe7c38ca094834dedbc92a58855e20 --- media/libstagefright/MP3Extractor.cpp | 6 ++++-- media/libstagefright/id3/ID3.cpp | 4 ++-- media/libstagefright/include/ID3.h | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/media/libstagefright/MP3Extractor.cpp b/media/libstagefright/MP3Extractor.cpp index d94054b..380dab4 100644 --- a/media/libstagefright/MP3Extractor.cpp +++ b/media/libstagefright/MP3Extractor.cpp @@ -350,8 +350,10 @@ MP3Extractor::MP3Extractor( mInitCheck = OK; - // get iTunes-style gapless info if present - ID3 id3(mDataSource); + // Get iTunes-style gapless info if present. + // When getting the id3 tag, skip the V1 tags to prevent the source cache + // from being iterated to the end of the file. + ID3 id3(mDataSource, true); if (id3.isValid()) { ID3::Iterator *com = new ID3::Iterator(id3, "COM"); if (com->done()) { diff --git a/media/libstagefright/id3/ID3.cpp b/media/libstagefright/id3/ID3.cpp index 69274ca..22c2f5a 100644 --- a/media/libstagefright/id3/ID3.cpp +++ b/media/libstagefright/id3/ID3.cpp @@ -30,7 +30,7 @@ namespace android { static const size_t kMaxMetadataSize = 3 * 1024 * 1024; -ID3::ID3(const sp &source) +ID3::ID3(const sp &source, bool ignoreV1) : mIsValid(false), mData(NULL), mSize(0), @@ -38,7 +38,7 @@ ID3::ID3(const sp &source) mVersion(ID3_UNKNOWN) { mIsValid = parseV2(source); - if (!mIsValid) { + if (!mIsValid && !ignoreV1) { mIsValid = parseV1(source); } } diff --git a/media/libstagefright/include/ID3.h b/media/libstagefright/include/ID3.h index 8714008..3028f56 100644 --- a/media/libstagefright/include/ID3.h +++ b/media/libstagefright/include/ID3.h @@ -35,7 +35,7 @@ struct ID3 { ID3_V2_4, }; - ID3(const sp &source); + ID3(const sp &source, bool ignoreV1 = false); ~ID3(); bool isValid() const; -- cgit v1.1 From f0ff908da019a44115109f1b4d1b6864b35a8a29 Mon Sep 17 00:00:00 2001 From: Glenn Kasten Date: Fri, 7 Dec 2012 14:13:35 -0800 Subject: Logging to investigate a crash Bug: 6490974 Change-Id: Ib926a9258bde4ee05ed42eea662dff68e426a997 --- include/media/AudioBufferProvider.h | 12 +++++++++++- services/audioflinger/AudioMixer.cpp | 6 ++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/include/media/AudioBufferProvider.h b/include/media/AudioBufferProvider.h index 43e4de7..865ed7e 100644 --- a/include/media/AudioBufferProvider.h +++ b/include/media/AudioBufferProvider.h @@ -36,8 +36,11 @@ public: size_t frameCount; }; - virtual ~AudioBufferProvider() {} +protected: + AudioBufferProvider() : mValid(kValid) { } + virtual ~AudioBufferProvider() { mValid = kDead; } +public: // value representing an invalid presentation timestamp static const int64_t kInvalidPTS = 0x7FFFFFFFFFFFFFFFLL; // is too painful @@ -47,6 +50,13 @@ public: virtual status_t getNextBuffer(Buffer* buffer, int64_t pts = kInvalidPTS) = 0; virtual void releaseBuffer(Buffer* buffer) = 0; + + int getValid() const { return mValid; } + static const int kValid = 'GOOD'; + static const int kDead = 'DEAD'; + +private: + int mValid; }; // ---------------------------------------------------------------------------- diff --git a/services/audioflinger/AudioMixer.cpp b/services/audioflinger/AudioMixer.cpp index af169d5..1e4049a 100644 --- a/services/audioflinger/AudioMixer.cpp +++ b/services/audioflinger/AudioMixer.cpp @@ -1098,6 +1098,12 @@ void AudioMixer::process__genericNoResampling(state_t* state, int64_t pts) e0 &= ~(1<tracks[i]; t.buffer.frameCount = state->frameCount; + int valid = t.bufferProvider->getValid(); + if (valid != AudioBufferProvider::kValid) { + ALOGE("invalid bufferProvider=%p name=%d frameCount=%d valid=%#x enabledTracks=%#x", + t.bufferProvider, i, t.buffer.frameCount, valid, enabledTracks); + // expect to crash + } t.bufferProvider->getNextBuffer(&t.buffer, pts); t.frameCount = t.buffer.frameCount; t.in = t.buffer.raw; -- cgit v1.1