diff options
68 files changed, 2718 insertions, 5216 deletions
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; // <stdint.h> 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/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/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<AMessage> &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<MediaPlayerListener> mListener; void* mCookie; media_player_states mCurrentState; - int mDuration; int mCurrentPosition; int mSeekPosition; bool mPrepareSync; diff --git a/include/media/stagefright/ACodec.h b/include/media/stagefright/ACodec.h index 99548a0..b42a4ac 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<AMessage> &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/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<IRemoteDisplay> @@ -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/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/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<IRemoteDisplayClient> &client, const char *iface); + virtual status_t pause(); + virtual status_t resume(); virtual status_t dispose(); protected: 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<AMessage> extra; + + uint8_t type = buffer[1]; + + sp<AMessage> 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<AMessage> &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<NuPlayerDriver> 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<AMessage> &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<AMessage> &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<AMessage> &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<AMessage> 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<NuPlayerDriver> 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<AMessage> &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<AMessage> &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<ABuffer> *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<ABuffer> *accessUnit); + virtual uint32_t flags() const; + protected: virtual ~MP4Source(); diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp index e86bf63..19bf28a 100644 --- a/media/libstagefright/ACodec.cpp +++ b/media/libstagefright/ACodec.cpp @@ -978,7 +978,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); @@ -1027,6 +1028,10 @@ status_t ACodec::configureCodec( } } + if (err != OK) { + return err; + } + if (!msg->findInt32("encoder-delay", &mEncoderDelay)) { mEncoderDelay = 0; } @@ -1666,6 +1671,43 @@ status_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) { return err; } +status_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) { + OMX_VIDEO_PARAM_INTRAREFRESHTYPE params; + InitOMXParams(¶ms); + params.nPortIndex = kPortIndexOutput; + + params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(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; @@ -1861,11 +1903,22 @@ status_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &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) { 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/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 <URL suppressed> @%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<M3UParser> LiveSession::fetchPlaylist(const char *url, bool *unchanged) { + ALOGV("fetchPlaylist '%s'", url); + *unchanged = false; sp<ABuffer> buffer; @@ -364,6 +368,37 @@ sp<M3UParser> 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<AMessage> 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<ABuffer> 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<AMessage> &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<AMessage> 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/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<DataSource> &source) +ID3::ID3(const sp<DataSource> &source, bool ignoreV1) : mIsValid(false), mData(NULL), mSize(0), @@ -38,7 +38,7 @@ ID3::ID3(const sp<DataSource> &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<DataSource> &source); + ID3(const sp<DataSource> &source, bool ignoreV1 = false); ~ID3(); bool isValid() const; 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<AMessage> meta(); @@ -54,6 +55,7 @@ private: bool mIsExtM3U; bool mIsVariantPlaylist; bool mIsComplete; + bool mIsEvent; sp<AMessage> mMeta; Vector<Item> 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<AMessage> &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<AMessage> &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)); 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<ABuffer> &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 07160f2..b3ec4d6 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 <math.h> +#include <string.h> + +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 <sys/types.h> + +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..7a87444 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<AMessage> 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)) { @@ -156,17 +161,63 @@ 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("prepend-sps-pps-to-idr-frames", 1); + 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()); - status_t err = mEncoder->configure( - mOutputFormat, - NULL /* nativeWindow */, - NULL /* crypto */, - MediaCodec::CONFIGURE_FLAG_ENCODE); + mNeedToManuallyPrependSPSPPS = false; + + status_t err = NO_INIT; + + if (!isAudio) { + sp<AMessage> 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<AMessage> getOutputFormat() const; + bool needToManuallyPrependSPSPPS() const; void feedAccessUnit(const sp<ABuffer> &accessUnit); void signalEOS(); @@ -78,6 +79,7 @@ private: bool mIsVideo; bool mIsPCMAudio; sp<AMessage> mOutputFormat; + bool mNeedToManuallyPrependSPSPPS; sp<MediaCodec> mEncoder; sp<AMessage> mEncoderActivityNotify; 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<MetaData> meta = source->getFormat(); const char *mime; CHECK(meta->findCString(kKeyMIMEType, &mime)); @@ -71,6 +72,14 @@ void MediaPuller::stopAsync(const sp<AMessage> ¬ify) { msg->post(); } +void MediaPuller::pause() { + (new AMessage(kWhatPause, id()))->post(); +} + +void MediaPuller::resume() { + (new AMessage(kWhatResume, id()))->post(); +} + void MediaPuller::onMessageReceived(const sp<AMessage> &msg) { switch (msg->what()) { case kWhatStart: @@ -95,7 +104,6 @@ void MediaPuller::onMessageReceived(const sp<AMessage> &msg) { uint32_t replyID; CHECK(msg->senderAwaitsResponse(&replyID)); - response->postReply(replyID); break; } @@ -130,6 +138,16 @@ void MediaPuller::onMessageReceived(const sp<AMessage> &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<AMessage> &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<AMessage> ¬ify); + void pause(); + void resume(); + protected: virtual void onMessageReceived(const sp<AMessage> &msg); virtual ~MediaPuller(); @@ -44,12 +47,15 @@ private: kWhatStart, kWhatStop, kWhatPull, + kWhatPause, + kWhatResume, }; sp<MediaSource> mSource; sp<AMessage> mNotify; int32_t mPullGeneration; bool mIsAudio; + bool mPaused; status_t postSynchronouslyAndReturnError(const sp<AMessage> &msg); void schedulePull(); diff --git a/media/libstagefright/wifi-display/source/PlaybackSession.cpp b/media/libstagefright/wifi-display/source/PlaybackSession.cpp index f1e7140..916f797 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 <binder/IServiceManager.h> #include <gui/ISurfaceComposer.h> @@ -75,13 +76,19 @@ struct WifiDisplaySource::PlaybackSession::Track : public AHandler { status_t start(); void stopAsync(); + void pause(); + void resume(); + void queueAccessUnit(const sp<ABuffer> &accessUnit); sp<ABuffer> dequeueAccessUnit(); bool hasOutputBuffer(int64_t *timeUs) const; void queueOutputBuffer(const sp<ABuffer> &accessUnit); sp<ABuffer> dequeueOutputBuffer(); + +#if SUSPEND_VIDEO_IF_IDLE bool isSuspended() const; +#endif size_t countQueuedOutputBuffers() const { return mQueuedOutputBuffers.size(); @@ -204,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<AMessage> &msg) { switch (msg->what()) { @@ -279,7 +294,6 @@ bool WifiDisplaySource::PlaybackSession::Track::hasOutputBuffer( void WifiDisplaySource::PlaybackSession::Track::queueOutputBuffer( const sp<ABuffer> &accessUnit) { mQueuedOutputBuffers.push_back(accessUnit); - mLastOutputBufferQueuedTimeUs = ALooper::GetNowUs(); } @@ -292,6 +306,7 @@ sp<ABuffer> WifiDisplaySource::PlaybackSession::Track::dequeueOutputBuffer() { return outputBuffer; } +#if SUSPEND_VIDEO_IF_IDLE bool WifiDisplaySource::PlaybackSession::Track::isSuspended() const { if (!mQueuedOutputBuffers.empty()) { return false; @@ -307,6 +322,7 @@ bool WifiDisplaySource::PlaybackSession::Track::isSuspended() const { // this track suspended for the time being. return (ALooper::GetNowUs() - mLastOutputBufferQueuedTimeUs) > 60000ll; } +#endif //////////////////////////////////////////////////////////////////////////////// @@ -320,6 +336,7 @@ WifiDisplaySource::PlaybackSession::PlaybackSession( mInterfaceAddr(interfaceAddr), mHDCP(hdcp), mWeAreDead(false), + mPaused(false), mLastLifesignUs(), mVideoTrackIndex(-1), mPrevTimeUs(-1ll), @@ -378,6 +395,8 @@ void WifiDisplaySource::PlaybackSession::updateLiveness() { status_t WifiDisplaySource::PlaybackSession::play() { updateLiveness(); + (new AMessage(kWhatResume, id()))->post(); + return OK; } @@ -408,6 +427,8 @@ status_t WifiDisplaySource::PlaybackSession::onFinishPlay2() { status_t WifiDisplaySource::PlaybackSession::pause() { updateLiveness(); + (new AMessage(kWhatPause, id()))->post(); + return OK; } @@ -443,8 +464,13 @@ void WifiDisplaySource::PlaybackSession::onMessageReceived( ssize_t packetizerTrackIndex = track->packetizerTrackIndex(); if (packetizerTrackIndex < 0) { - packetizerTrackIndex = - mPacketizer->addTrack(track->getFormat()); + sp<AMessage> 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); @@ -580,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(); } @@ -642,8 +696,10 @@ status_t WifiDisplaySource::PlaybackSession::addSource( sp<Converter> 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 +791,19 @@ sp<ISurfaceTexture> 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 +831,7 @@ bool WifiDisplaySource::PlaybackSession::allTracksHavePacketizerIndex() { } status_t WifiDisplaySource::PlaybackSession::packetizeAccessUnit( - size_t trackIndex, const sp<ABuffer> &accessUnit, + size_t trackIndex, sp<ABuffer> accessUnit, sp<ABuffer> *packets) { const sp<Track> &track = mTracks.valueFor(trackIndex); @@ -776,9 +840,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 +933,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 +1007,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 +1036,7 @@ bool WifiDisplaySource::PlaybackSession::drainAccessUnit() { if (err != OK) { notifySessionDead(); + return false; } if ((ssize_t)minTrackIndex == mVideoTrackIndex) { @@ -957,6 +1044,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..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<ANetworkSession> mNetSession; @@ -93,6 +95,7 @@ private: in_addr mInterfaceAddr; sp<IHDCP> mHDCP; bool mWeAreDead; + bool mPaused; int64_t mLastLifesignUs; @@ -127,7 +130,7 @@ private: bool allTracksHavePacketizerIndex(); status_t packetizeAccessUnit( - size_t trackIndex, const sp<ABuffer> &accessUnit, + size_t trackIndex, sp<ABuffer> accessUnit, sp<ABuffer> *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 <media/stagefright/foundation/AHandlerReflector.h> #include <media/stagefright/MediaSource.h> +#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 <media/stagefright/foundation/ABuffer.h> #include <media/stagefright/foundation/ADebug.h> @@ -29,79 +30,8 @@ #include <media/stagefright/MediaErrors.h> #include <media/stagefright/Utils.h> -#include <math.h> - -#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<AMessage> ¬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<AMessage> rtpNotify = new AMessage(kWhatRTPNotify, id()); sp<AMessage> rtcpNotify = new AMessage(kWhatRTCPNotify, id()); -#if ENABLE_RETRANSMISSION +#if ENABLE_RETRANSMISSION && RETRANSMISSION_ACCORDING_TO_RFC_XXXX sp<AMessage> 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<ABuffer> &packets) { - bool isVideo = false; + int64_t timeUs, const sp<ABuffer> &tsPackets) { + const size_t numTSPackets = tsPackets->size() / 188; + + const size_t numRTPPackets = + (numTSPackets + kMaxNumTSPacketsPerRTPPacket - 1) + / kMaxNumTSPacketsPerRTPPacket; + + sp<ABuffer> 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<AMessage> 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<AMessage> 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<AMessage> &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<AMessage> &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<AMessage> &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<AMessage> &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<AMessage> &msg) { break; } - case kWhatQueuePackets: + case kWhatDrainQueue: { - sp<ABuffer> packets; - CHECK(msg->findBuffer("packets", &packets)); + sp<ABuffer> udpPackets; + CHECK(msg->findBuffer("udpPackets", &udpPackets)); - onQueuePackets(packets); + onDrainQueue(udpPackets); break; } @@ -532,156 +482,6 @@ void Sender::onMessageReceived(const sp<AMessage> &msg) { } } -void Sender::onQueuePackets(const sp<ABuffer> &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<AMessage> notify = mNotify->dup(); - notify->setInt32("what", kWhatBinaryData); - - sp<ABuffer> 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<ABuffer> 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<ABuffer> &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<AMessage> notify = mNotify->dup(); + notify->setInt32("what", kWhatBinaryData); + + sp<ABuffer> 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<ABuffer> 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..66951f7 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 1 + +// 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<ABuffer> &packets); + void queuePackets(int64_t timeUs, const sp<ABuffer> &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<ANetworkSession> mNetSession; sp<AMessage> mNotify; - sp<ABuffer> 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<ABuffer> &buffer); - void addSDES(const sp<ABuffer> &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<ABuffer> &packets); + void onSendSR(); + void addSR(const sp<ABuffer> &buffer); + void addSDES(const sp<ABuffer> &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<ABuffer> &buffer); @@ -158,6 +159,8 @@ private: void notifyInitDone(); void notifySessionDead(); + void onDrainQueue(const sp<ABuffer> &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<ABuffer> 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 29e9e3d..eecc59b 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<AMessage> msg = new AMessage(kWhatStart, id()); - msg->setString("iface", iface); - - sp<AMessage> response; - status_t err = msg->postAndAwaitResponse(&response); +static status_t PostAndAwaitResponse( + const sp<AMessage> &msg, sp<AMessage> *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<AMessage> msg = new AMessage(kWhatStart, id()); + msg->setString("iface", iface); + + sp<AMessage> response; + return PostAndAwaitResponse(msg, &response); +} + status_t WifiDisplaySource::stop() { sp<AMessage> msg = new AMessage(kWhatStop, id()); sp<AMessage> response; - status_t err = msg->postAndAwaitResponse(&response); + return PostAndAwaitResponse(msg, &response); +} - if (err != OK) { - return err; - } +status_t WifiDisplaySource::pause() { + sp<AMessage> msg = new AMessage(kWhatPause, id()); - if (!response->findInt32("err", &err)) { - err = OK; - } + sp<AMessage> response; + return PostAndAwaitResponse(msg, &response); +} - return err; +status_t WifiDisplaySource::resume() { + sp<AMessage> msg = new AMessage(kWhatResume, id()); + + sp<AMessage> response; + return PostAndAwaitResponse(msg, &response); } void WifiDisplaySource::onMessageReceived(const sp<AMessage> &msg) { @@ -236,6 +245,20 @@ void WifiDisplaySource::onMessageReceived(const sp<AMessage> &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<AMessage> &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<AMessage> &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<AMessage> 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<AMessage> response = new AMessage; + response->setInt32("err", err); + response->postReply(replyID); + break; + } + case kWhatReapDeadClients: { mReaperPending = false; @@ -400,7 +463,7 @@ void WifiDisplaySource::onMessageReceived(const sp<AMessage> &msg) { if (mSetupTriggerDeferred) { mSetupTriggerDeferred = false; - sendM5(mClientSessionID, false /* requestShutdown */); + sendTrigger(mClientSessionID, TRIGGER_SETUP); } break; } @@ -534,9 +597,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", @@ -568,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"); @@ -776,8 +857,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; } } @@ -802,7 +885,7 @@ status_t WifiDisplaySource::onReceiveM4Response( return OK; } - return sendM5(sessionID, false /* requestShutdown */); + return sendTrigger(sessionID, TRIGGER_SETUP); } status_t WifiDisplaySource::onReceiveM5Response( @@ -1179,6 +1262,11 @@ status_t WifiDisplaySource::onPlayRequest( return err; } + if (mState == PAUSED_TO_PLAYING) { + mState = PLAYING; + return OK; + } + playbackSession->finishPlay(); CHECK_EQ(mState, AWAITING_CLIENT_PLAY); @@ -1200,6 +1288,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); @@ -1209,6 +1303,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 02fa0a6..974e070 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; @@ -42,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<AMessage> &msg); @@ -57,6 +62,9 @@ private: AWAITING_CLIENT_PLAY, ABOUT_TO_PLAY, PLAYING, + PLAYING_TO_PAUSED, + PAUSED, + PAUSED_TO_PLAYING, AWAITING_CLIENT_TEARDOWN, STOPPING, STOPPED, @@ -66,6 +74,8 @@ private: kWhatStart, kWhatRTSPNotify, kWhatStop, + kWhatPause, + kWhatResume, kWhatReapDeadClients, kWhatPlaybackSessionNotify, kWhatKeepAlive, @@ -145,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( 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 <binder/ProcessState.h> #include <binder/IServiceManager.h> +#include <gui/SurfaceComposerClient.h> +#include <media/AudioSystem.h> #include <media/IMediaPlayerService.h> +#include <media/IRemoteDisplay.h> +#include <media/IRemoteDisplayClient.h> #include <media/stagefright/DataSource.h> #include <media/stagefright/foundation/ADebug.h> 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<ISurfaceTexture> &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<SurfaceComposerClient> mComposerClient; + sp<ISurfaceTexture> mSurfaceTexture; + sp<IBinder> 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<ISurfaceTexture> &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<IServiceManager> sm = defaultServiceManager(); + sp<IBinder> binder = sm->getService(String16("media.player")); + sp<IMediaPlayerService> service = + interface_cast<IMediaPlayerService>(binder); + + CHECK(service.get() != NULL); + + enableAudioSubmix(true /* enable */); + + String8 iface; + iface.append(addr.c_str()); + iface.append(StringPrintf(":%d", port).c_str()); + + sp<RemoteDisplayClient> client = new RemoteDisplayClient; + sp<IRemoteDisplay> 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"); diff --git a/media/mediaserver/main_mediaserver.cpp b/media/mediaserver/main_mediaserver.cpp index b8fddc4..993715e 100644 --- a/media/mediaserver/main_mediaserver.cpp +++ b/media/mediaserver/main_mediaserver.cpp @@ -39,6 +39,7 @@ void instantiate(void); int main(int argc, char** argv) { + signal(SIGPIPE, SIG_IGN); sp<ProcessState> proc(ProcessState::self()); sp<IServiceManager> sm = defaultServiceManager(); ALOGI("ServiceManager: %p", sm.get()); diff --git a/services/audioflinger/Android.mk b/services/audioflinger/Android.mk index c2b97d8..a14c205 100644 --- a/services/audioflinger/Android.mk +++ b/services/audioflinger/Android.mk @@ -23,11 +23,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() @@ -84,4 +82,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/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp index d260074..bcb9756 100644 --- a/services/audioflinger/AudioFlinger.cpp +++ b/services/audioflinger/AudioFlinger.cpp @@ -5038,7 +5038,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 diff --git a/services/audioflinger/AudioMixer.cpp b/services/audioflinger/AudioMixer.cpp index ced0453..ab6f38f 100644 --- a/services/audioflinger/AudioMixer.cpp +++ b/services/audioflinger/AudioMixer.cpp @@ -1102,6 +1102,12 @@ void AudioMixer::process__genericNoResampling(state_t* state, int64_t pts) e0 &= ~(1<<i); track_t& t = state->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; 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 <malloc.h> #include <string.h> -#include "AudioResamplerSinc.h" +#include <stdlib.h> #include <dlfcn.h> + +#include <cutils/compiler.h> #include <cutils/properties.h> -#include <stdlib.h> + #include <utils/Log.h> +#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<<c->coefsBits)-1) << c->cShift; c->pShift = kNumPhaseBits - c->coefsBits - pLerpBits; c->pMask = ((1<<pLerpBits)-1) << c->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<int CHANNELS> 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<CHANNELS ; i++) { + head[i] = in[inputIndex*CHANNELS + i]; + } // handle boundary case - int32_t l, r; - while (outputIndex < outputSampleCount) { - filterCoefficient<CHANNELS>(l, r, phaseFraction, impulse); - out[outputIndex++] += 2 * mulRL(1, l, vRL); - out[outputIndex++] += 2 * mulRL(0, r, vRL); + while (CC_LIKELY(outputIndex < outputSampleCount)) { + filterCoefficient<CHANNELS>(&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<CHANNELS>(impulse, phaseFraction, in, inputIndex); - } else if (phaseIndex == 2) { // maximum value + const size_t phaseIndex = phaseFraction >> kNumPhaseBits; + for (size_t i=0 ; i<phaseIndex ; i++) { inputIndex++; - if (inputIndex >= frameCount) - break; // 0 frame available, 2 frames needed - // read first frame - read<CHANNELS>(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<CHANNELS>(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<<kNumPhaseBits; - if (impulse >= 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<CHANNELS ; i++) { + head[i] = in[inputIndex*CHANNELS + i]; + } } template<int CHANNELS> 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<CHANNELS>(l, r, coefs+indexP, lerpP, sP); - interpolate<CHANNELS>(l, r, coefs+indexN, lerpN, sN); - sP -= CHANNELS; sN += CHANNELS; coefs += 1 << c->coefsBits; - interpolate<CHANNELS>(l, r, coefs+indexP, lerpP, sP); - interpolate<CHANNELS>(l, r, coefs+indexN, lerpN, sN); - sP -= CHANNELS; sN += CHANNELS; coefs += 1 << c->coefsBits; - interpolate<CHANNELS>(l, r, coefs+indexP, lerpP, sP); - interpolate<CHANNELS>(l, r, coefs+indexN, lerpN, sN); - sP -= CHANNELS; sN += CHANNELS; coefs += 1 << c->coefsBits; - interpolate<CHANNELS>(l, r, coefs+indexP, lerpP, sP); - interpolate<CHANNELS>(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<count ; i++) { + interpolate<CHANNELS>(l, r, coefsP++, offset, lerpP, sP); + sP -= CHANNELS; + interpolate<CHANNELS>(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<int CHANNELS> 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<const uint32_t*>(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<int CHANNELS> void resample(int32_t* out, size_t outFrameCount, AudioBufferProvider* provider); template<int CHANNELS> 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<int CHANNELS> 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<int CHANNELS> 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..d45d697 100644 --- a/services/audioflinger/audio-resampler/AudioResamplerCoefficients.cpp +++ b/services/audioflinger/audio-resampler/AudioResamplerCoefficients.cpp @@ -14,42 +14,41 @@ * limitations under the License. */ -#include <dnsampler_filter_coefficients_x128_10112011.h> -#include <resampler_filter_coefficients_10042011.h> -#undef LOG_TAG -#include <utils/Log.h> -//#include "common_log.h" #define LOG_TAG "ResamplerCoefficients" -#define LOG_NDEBUG 0 +//#define LOG_NDEBUG 0 + +#include <utils/Log.h> -const int32_t RESAMPLE_FIR_NUM_COEF = 16; -const int32_t RESAMPLE_FIR_LERP_INT_BITS = 7; +#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 <stdlib.h> - -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 <stdlib.h> + +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 <stdlib.h> - -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 <media/AudioBufferProvider.h> +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <fcntl.h> +#include <string.h> +#include <sys/mman.h> +#include <sys/stat.h> +#include <errno.h> +#include <time.h> +#include <math.h> + +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] [<input-file>] <output-file>\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 ; i<input_frames ; i++) { + double t = double(i) / input_freq; + double y = sin(M_PI * k * t * t); + int16_t yi = floor(y * 32767.0 + 0.5); + for (size_t j=0 ; j<(size_t)channels ; j++) { + in[i*channels + j] = yi / (1+j); + } + } + } + + // ---------------------------------------------------------- + + class Provider: public AudioBufferProvider { + int16_t* mAddr; + size_t mNumFrames; + public: + Provider(const void* addr, size_t size, int channels) { + mAddr = (int16_t*) addr; + mNumFrames = size / (channels*sizeof(int16_t)); + } + virtual status_t getNextBuffer(Buffer* buffer, + int64_t pts = kInvalidPTS) { + buffer->frameCount = 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<channels ; j++) { + int32_t s = out[i * 2 + 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/services/camera/libcameraservice/Camera2Client.cpp b/services/camera/libcameraservice/Camera2Client.cpp index d45881d..bddcb8c 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<Camera2Client> 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<ZslProcessor> 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<Camera2Client> client) { + sp<Camera2Client> 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<ZslProcessor> 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<Camera2Client> client); + sp<Camera2Client> client, int msgType); }; }; // namespace camera2 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 <math.h> +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <string.h> + +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<argc ; i++) { + printf("%s ", argv[i]); + } + printf("\n"); + if (!polyphase) { + printf("const int32_t RESAMPLE_FIR_SIZE = %d;\n", N); + printf("const int32_t RESAMPLE_FIR_LERP_INT_BITS = %d;\n", nz); + printf("const int32_t RESAMPLE_FIR_NUM_COEF = %d;\n", nzc); + } else { + printf("const int32_t RESAMPLE_FIR_SIZE = %d;\n", 2*nzc*polyN); + printf("const int32_t RESAMPLE_FIR_NUM_COEF = %d;\n", 2*nzc); + } + if (!format) { + printf("const int32_t RESAMPLE_FIR_COEF_BITS = %d;\n", nc); + } + printf("\n"); + printf("static %s resampleFIR[] = {", !format ? "int32_t" : "float"); + } + + if (!polyphase) { + for (int i=0 ; i<=M ; i++) { // an extra set of coefs for interpolation + for (int j=0 ; j<nzc ; j++) { + int ix = j*M + i; + double x = (2.0 * M_PI * ix * Fcr) / (1 << nz); + double y = kaiser(ix+N, 2*N, beta) * sinc(x) * 2.0 * Fcr; + y *= atten; + + if (!debug) { + if (j == 0) + printf("\n "); + } + + if (!format) { + int64_t yi = floor(y * ((1ULL<<(nc-1))) + 0.5); + if (yi >= (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<polyN ; j++) { + // calculate the phase + double p = ((polyM*j) % polyN) / double(polyN); + if (!debug) printf("\n "); + else printf("\n"); + // generate a FIR per phase + for (int i=-nzc ; i<nzc ; i++) { + double x = 2.0 * M_PI * Fcr * (i + p); + double y = kaiser(i+N, 2*N, beta) * sinc(x) * 2.0 * Fcr;; + y *= atten; + if (!format) { + int64_t yi = floor(y * ((1ULL<<(nc-1))) + 0.5); + if (yi >= (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 + + |