Merge "Stagefright command line tool: input file name last"
diff --git a/include/media/AudioRecord.h b/include/media/AudioRecord.h
index f9f6e8d..2672db1 100644
--- a/include/media/AudioRecord.h
+++ b/include/media/AudioRecord.h
@@ -57,13 +57,6 @@
     class Buffer
     {
     public:
-        enum {
-            MUTE    = 0x00000001
-        };
-        uint32_t    flags;
-        int         channelCount;
-        audio_format_t format;
-
         size_t      frameCount;     // number of sample frames corresponding to size;
                                     // on input it is the number of frames available,
                                     // on output is the number of frames actually drained
@@ -192,7 +185,7 @@
             audio_format_t format() const;
             int         channelCount() const;
             uint32_t    frameCount() const;
-            size_t      frameSize() const;
+            size_t      frameSize() const { return mFrameSize; }
             audio_source_t inputSource() const;
 
 
@@ -385,6 +378,7 @@
     uint32_t                mFrameCount;
     audio_format_t          mFormat;
     uint8_t                 mChannelCount;
+    size_t                  mFrameSize;         // app-level frame size == AudioFlinger frame size
     audio_source_t          mInputSource;
     status_t                mStatus;
     uint32_t                mLatency;
@@ -396,6 +390,7 @@
     sp<IAudioRecord>        mAudioRecord;
     sp<IMemory>             mCblkMemory;
     audio_track_cblk_t*     mCblk;
+    void*                   mBuffers;           // starting address of buffers in shared memory
 
     int                     mPreviousPriority;          // before start()
     SchedPolicy             mPreviousSchedulingGroup;
diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h
index 2218fad..33078bb 100644
--- a/include/media/AudioSystem.h
+++ b/include/media/AudioSystem.h
@@ -87,7 +87,7 @@
     static float linearToLog(int volume);
     static int logToLinear(float volume);
 
-    static status_t getOutputSamplingRate(int* samplingRate,
+    static status_t getOutputSamplingRate(uint32_t* samplingRate,
             audio_stream_type_t stream = AUDIO_STREAM_DEFAULT);
     static status_t getOutputFrameCount(int* frameCount,
             audio_stream_type_t stream = AUDIO_STREAM_DEFAULT);
@@ -95,7 +95,7 @@
             audio_stream_type_t stream = AUDIO_STREAM_DEFAULT);
     static status_t getSamplingRate(audio_io_handle_t output,
                                           audio_stream_type_t streamType,
-                                          int* samplingRate);
+                                          uint32_t* samplingRate);
     // returns the number of frames per audio HAL write buffer. Corresponds to
     // audio_stream->get_buffer_size()/audio_stream_frame_size()
     static status_t getFrameCount(audio_io_handle_t output,
@@ -107,12 +107,6 @@
                                audio_stream_type_t stream,
                                uint32_t* latency);
 
-    // DEPRECATED
-    static status_t getOutputSamplingRate(int* samplingRate, int stream = AUDIO_STREAM_DEFAULT);
-
-    // DEPRECATED
-    static status_t getOutputFrameCount(int* frameCount, int stream = AUDIO_STREAM_DEFAULT);
-
     static bool routedToA2dpOutput(audio_stream_type_t streamType);
 
     static status_t getInputBufferSize(uint32_t sampleRate, audio_format_t format,
@@ -243,7 +237,7 @@
     static const sp<IAudioPolicyService>& get_audio_policy_service();
 
     // helpers for android.media.AudioManager.getProperty(), see description there for meaning
-    static int32_t getPrimaryOutputSamplingRate();
+    static uint32_t getPrimaryOutputSamplingRate();
     static int32_t getPrimaryOutputFrameCount();
 
     // ----------------------------------------------------------------------------
diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h
index 76af2f8..6fd1b9e 100644
--- a/include/media/AudioTrack.h
+++ b/include/media/AudioTrack.h
@@ -70,14 +70,6 @@
     class Buffer
     {
     public:
-        enum {
-            MUTE    = 0x00000001
-        };
-        uint32_t    flags;        // 0 or MUTE
-        audio_format_t format;    // but AUDIO_FORMAT_PCM_8_BIT -> AUDIO_FORMAT_PCM_16_BIT
-        // accessed directly by WebKit ANP callback
-        int         channelCount; // will be removed in the future, do not use
-
         size_t      frameCount;   // number of sample frames corresponding to size;
                                   // on input it is the number of frames desired,
                                   // on output is the number of frames actually filled
@@ -237,7 +229,7 @@
     /* Return channelCount * (bit depth per channel / 8).
      * channelCount is determined from channelMask, and bit depth comes from format.
      */
-            size_t      frameSize() const;
+            size_t      frameSize() const { return mFrameSize; }
 
             sp<IMemory>& sharedBuffer();
 
@@ -273,9 +265,14 @@
 
     /* Set volume for this track, mostly used for games' sound effects
      * left and right volumes. Levels must be >= 0.0 and <= 1.0.
+     * This is the older API.  New applications should use setVolume(float) when possible.
      */
             status_t    setVolume(float left, float right);
-            void        getVolume(float* left, float* right) const;
+
+    /* Set volume for all channels.  This is the preferred API for new applications,
+     * especially for multi-channel content.
+     */
+            status_t    setVolume(float volume);
 
     /* Set the send level for this track. An auxiliary effect should be attached
      * to the track with attachEffect(). Level must be >= 0.0 and <= 1.0.
@@ -285,7 +282,9 @@
 
     /* Set sample rate for this track in Hz, mostly used for games' sound effects
      */
-            status_t    setSampleRate(int sampleRate);
+            status_t    setSampleRate(uint32_t sampleRate);
+
+    /* Return current sample rate in Hz, or 0 if unknown */
             uint32_t    getSampleRate() const;
 
     /* Enables looping and sets the start and end points of looping.
@@ -418,6 +417,18 @@
      *  +n  limits wait time to n * WAIT_PERIOD_MS,
      *  -1  causes an (almost) infinite wait time,
      *   0  non-blocking.
+     *
+     * Buffer fields
+     * On entry:
+     *  frameCount  number of frames requested
+     * After error return:
+     *  frameCount  0
+     *  size        0
+     *  raw         undefined
+     * After successful return:
+     *  frameCount  actual number of frames available, <= number requested
+     *  size        actual number of bytes available
+     *  raw         pointer to the buffer
      */
 
         enum {
@@ -478,6 +489,7 @@
             // body of AudioTrackThread::threadLoop()
             bool processAudioBuffer(const sp<AudioTrackThread>& thread);
 
+            // caller must hold lock on mLock for all _l methods
             status_t createTrack_l(audio_stream_type_t streamType,
                                  uint32_t sampleRate,
                                  audio_format_t format,
@@ -500,13 +512,27 @@
     float                   mSendLevel;
     uint32_t                mFrameCount;
 
-    audio_track_cblk_t*     mCblk;
-    audio_format_t          mFormat;
+    audio_track_cblk_t*     mCblk;                  // re-load after mLock.unlock()
+
+            // Starting address of buffers in shared memory.  If there is a shared buffer, mBuffers
+            // is the value of pointer() for the shared buffer, otherwise mBuffers points
+            // immediately after the control block.  This address is for the mapping within client
+            // address space.  AudioFlinger::TrackBase::mBuffer is for the server address space.
+    void*                   mBuffers;
+
+    audio_format_t          mFormat;                // as requested by client, not forced to 16-bit
     audio_stream_type_t     mStreamType;
     uint8_t                 mChannelCount;
     uint8_t                 mMuted;
     uint8_t                 mReserved;
     audio_channel_mask_t    mChannelMask;
+
+                // mFrameSize is equal to mFrameSizeAF for non-PCM or 16-bit PCM data.
+                // For 8-bit PCM data, mFrameSizeAF is
+                // twice as large because data is expanded to 16-bit before being stored in buffer.
+    size_t                  mFrameSize;             // app-level frame size
+    size_t                  mFrameSizeAF;           // AudioFlinger frame size
+
     status_t                mStatus;
     uint32_t                mLatency;
 
@@ -532,8 +558,13 @@
     audio_output_flags_t    mFlags;
     int                     mSessionId;
     int                     mAuxEffectId;
+
+    // When locking both mLock and mCblk->lock, must lock in this order to avoid deadlock:
+    //      1. mLock
+    //      2. mCblk->lock
+    // It is OK to lock only mCblk->lock.
     mutable Mutex           mLock;
-    status_t                mRestoreStatus;
+
     bool                    mIsTimed;
     int                     mPreviousPriority;          // before start()
     SchedPolicy             mPreviousSchedulingGroup;
diff --git a/include/media/IAudioFlinger.h b/include/media/IAudioFlinger.h
index 359780e..5fd5044 100644
--- a/include/media/IAudioFlinger.h
+++ b/include/media/IAudioFlinger.h
@@ -62,7 +62,7 @@
                                 audio_format_t format,
                                 audio_channel_mask_t channelMask,
                                 int frameCount,
-                                track_flags_t flags,
+                                track_flags_t *flags,
                                 const sp<IMemory>& sharedBuffer,
                                 audio_io_handle_t output,
                                 pid_t tid,  // -1 means unused, otherwise must be valid non-0
@@ -192,7 +192,7 @@
     // helpers for android.media.AudioManager.getProperty(), see description there for meaning
     // FIXME move these APIs to AudioPolicy to permit a more accurate implementation
     // that looks on primary device for a stream with fast flag, primary flag, or first one.
-    virtual int32_t getPrimaryOutputSamplingRate() = 0;
+    virtual uint32_t getPrimaryOutputSamplingRate() = 0;
     virtual int32_t getPrimaryOutputFrameCount() = 0;
 
 };
diff --git a/include/media/ToneGenerator.h b/include/media/ToneGenerator.h
index 29c8fd9..0529bcd 100644
--- a/include/media/ToneGenerator.h
+++ b/include/media/ToneGenerator.h
@@ -263,7 +263,7 @@
 
     unsigned short mLoopCounter; // Current tone loopback count
 
-    int mSamplingRate;  // AudioFlinger Sampling rate
+    uint32_t mSamplingRate;  // AudioFlinger Sampling rate
     AudioTrack *mpAudioTrack;  // Pointer to audio track used for playback
     Mutex mLock;  // Mutex to control concurent access to ToneGenerator object from audio callback and application API
     Mutex mCbkCondLock; // Mutex associated to mWaitCbkCond
diff --git a/include/private/media/AudioTrackShared.h b/include/private/media/AudioTrackShared.h
index 6a86a00..bbc5e26 100644
--- a/include/private/media/AudioTrackShared.h
+++ b/include/private/media/AudioTrackShared.h
@@ -31,17 +31,12 @@
                                         // init time
 #define MAX_RUN_TIMEOUT_MS      1000
 #define WAIT_PERIOD_MS          10
-#define RESTORE_TIMEOUT_MS      5000    // Maximum waiting time for a track to be restored
 
 #define CBLK_UNDERRUN   0x01 // set: underrun (out) or overrrun (in), clear: no underrun or overrun
-#define CBLK_DIRECTION  0x02 // set: cblk is for an AudioTrack, clear: for AudioRecord
-#define CBLK_FORCEREADY 0x04 // set: track is considered ready immediately by AudioFlinger,
+#define CBLK_FORCEREADY 0x02 // set: track is considered ready immediately by AudioFlinger,
                              // clear: track is ready when buffer full
-#define CBLK_INVALID    0x08 // track buffer invalidated by AudioFlinger, need to re-create
-#define CBLK_DISABLED   0x10 // track disabled by AudioFlinger due to underrun, need to re-start
-#define CBLK_RESTORING  0x20 // track is being restored after invalidation by AudioFlinger
-#define CBLK_RESTORED   0x40 // track has been restored after invalidation by AudioFlinger
-#define CBLK_FAST       0x80 // AudioFlinger successfully created a fast track
+#define CBLK_INVALID    0x04 // track buffer invalidated by AudioFlinger, need to re-create
+#define CBLK_DISABLED   0x08 // track disabled by AudioFlinger due to underrun, need to re-start
 
 // Important: do not add any virtual methods, including ~
 struct audio_track_cblk_t
@@ -58,12 +53,11 @@
                 uint32_t    userBase;
                 uint32_t    serverBase;
 
-                // if there is a shared buffer, "buffers" is the value of pointer() for the shared
-                // buffer, otherwise "buffers" points immediately after the control block
-                void*       buffers;
+                int         mPad1;          // unused, but preserves cache line alignment
+
                 uint32_t    frameCount;
 
-                // Cache line boundary
+                // Cache line boundary (32 bytes)
 
                 uint32_t    loopStart;
                 uint32_t    loopEnd;        // read-only for server, read/write for client
@@ -79,12 +73,9 @@
 
                 uint32_t    sampleRate;
 
-                // NOTE: audio_track_cblk_t::frameSize is not equal to AudioTrack::frameSize() for
-                // 8 bit PCM data: in this case,  mCblk->frameSize is based on a sample size of
-                // 16 bit because data is converted to 16 bit before being stored in buffer
+                uint8_t     mPad2;           // unused
 
                 // read-only for client, server writes once at initialization and is then read-only
-                uint8_t     frameSize;       // would normally be size_t, but 8 bits is plenty
                 uint8_t     mName;           // normal tracks: track name, fast tracks: track index
 
                 // used by client only
@@ -103,13 +94,25 @@
                 // Since the control block is always located in shared memory, this constructor
                 // is only used for placement new().  It is never used for regular new() or stack.
                             audio_track_cblk_t();
-                uint32_t    stepUser(uint32_t frameCount);      // called by client only, where
-                // client includes regular AudioTrack and AudioFlinger::PlaybackThread::OutputTrack
-                bool        stepServer(uint32_t frameCount);    // called by server only
-                void*       buffer(uint32_t offset) const;
-                uint32_t    framesAvailable();
-                uint32_t    framesAvailable_l();
-                uint32_t    framesReady();                      // called by server only
+
+                // called by client only, where client includes regular
+                // AudioTrack and AudioFlinger::PlaybackThread::OutputTrack
+                uint32_t    stepUserIn(uint32_t frameCount) { return stepUser(frameCount, false); }
+                uint32_t    stepUserOut(uint32_t frameCount) { return stepUser(frameCount, true); }
+
+                bool        stepServer(uint32_t frameCount, bool isOut);
+
+                // if there is a shared buffer, "buffers" is the value of pointer() for the shared
+                // buffer, otherwise "buffers" points immediately after the control block
+                void*       buffer(void *buffers, uint32_t frameSize, uint32_t offset) const;
+
+                uint32_t    framesAvailableIn() { return framesAvailable(false); }
+                uint32_t    framesAvailableOut() { return framesAvailable(true); }
+                uint32_t    framesAvailableIn_l() { return framesAvailable_l(false); }
+                uint32_t    framesAvailableOut_l() { return framesAvailable_l(true); }
+                uint32_t    framesReadyIn() { return framesReady(false); }
+                uint32_t    framesReadyOut() { return framesReady(true); }
+
                 bool        tryLock();
 
                 // No barriers on the following operations, so the ordering of loads/stores
@@ -135,6 +138,12 @@
                     return mVolumeLR;
                 }
 
+private:
+                // isOut == true means AudioTrack, isOut == false means AudioRecord
+                uint32_t    stepUser(uint32_t frameCount, bool isOut);
+                uint32_t    framesAvailable(bool isOut);
+                uint32_t    framesAvailable_l(bool isOut);
+                uint32_t    framesReady(bool isOut);
 };
 
 
diff --git a/libvideoeditor/lvpp/VideoEditorPlayer.cpp b/libvideoeditor/lvpp/VideoEditorPlayer.cpp
index fc9fb49..d34b6d3 100755
--- a/libvideoeditor/lvpp/VideoEditorPlayer.cpp
+++ b/libvideoeditor/lvpp/VideoEditorPlayer.cpp
@@ -406,7 +406,7 @@
     }
     ALOGV("open(%u, %d, %d, %d)", sampleRate, channelCount, format, bufferCount);
     if (mTrack) close();
-    int afSampleRate;
+    uint32_t afSampleRate;
     int afFrameCount;
     int frameCount;
 
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index bd558fa..8f45a57 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -54,7 +54,7 @@
     }
 
     if (size == 0) {
-        ALOGE("Unsupported configuration: sampleRate %d, format %d, channelMask %#x",
+        ALOGE("Unsupported configuration: sampleRate %u, format %d, channelMask %#x",
             sampleRate, format, channelMask);
         return BAD_VALUE;
     }
@@ -127,7 +127,7 @@
         int sessionId)
 {
 
-    ALOGV("set(): sampleRate %d, channelMask %#x, frameCount %d",sampleRate, channelMask,
+    ALOGV("set(): sampleRate %u, channelMask %#x, frameCount %d", sampleRate, channelMask,
             frameCount);
 
     AutoMutex lock(mLock);
@@ -213,6 +213,13 @@
     mFrameCount = mCblk->frameCount;
     mChannelCount = (uint8_t)channelCount;
     mChannelMask = channelMask;
+
+    if (audio_is_linear_pcm(mFormat)) {
+        mFrameSize = channelCount * audio_bytes_per_sample(format);
+    } else {
+        mFrameSize = sizeof(uint8_t);
+    }
+
     mActive = false;
     mCbf = cbf;
     mNotificationFrames = notificationFrames;
@@ -258,15 +265,6 @@
     return mFrameCount;
 }
 
-size_t AudioRecord::frameSize() const
-{
-    if (audio_is_linear_pcm(mFormat)) {
-        return channelCount()*audio_bytes_per_sample(mFormat);
-    } else {
-        return sizeof(uint8_t);
-    }
-}
-
 audio_source_t AudioRecord::inputSource() const
 {
     return mInputSource;
@@ -302,7 +300,9 @@
             }
         }
         if (cblk->flags & CBLK_INVALID) {
-            ret = restoreRecord_l(cblk);
+            audio_track_cblk_t* temp = cblk;
+            ret = restoreRecord_l(temp);
+            cblk = temp;
         }
         cblk->lock.unlock();
         if (ret == NO_ERROR) {
@@ -433,6 +433,7 @@
     status_t status;
     const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger();
     if (audioFlinger == 0) {
+        ALOGE("Could not get audioflinger");
         return NO_INIT;
     }
 
@@ -455,20 +456,20 @@
         ALOGE("AudioFlinger could not create record track, status: %d", status);
         return status;
     }
-    sp<IMemory> cblk = record->getCblk();
-    if (cblk == 0) {
+    sp<IMemory> iMem = record->getCblk();
+    if (iMem == 0) {
         ALOGE("Could not get control block");
         return NO_INIT;
     }
     mAudioRecord.clear();
     mAudioRecord = record;
     mCblkMemory.clear();
-    mCblkMemory = cblk;
-    mCblk = static_cast<audio_track_cblk_t*>(cblk->pointer());
-    mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t);
-    android_atomic_and(~CBLK_DIRECTION, &mCblk->flags);
-    mCblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
-    mCblk->waitTimeMs = 0;
+    mCblkMemory = iMem;
+    audio_track_cblk_t* cblk = static_cast<audio_track_cblk_t*>(iMem->pointer());
+    mCblk = cblk;
+    mBuffers = (char*)cblk + sizeof(audio_track_cblk_t);
+    cblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
+    cblk->waitTimeMs = 0;
     return NO_ERROR;
 }
 
@@ -484,7 +485,7 @@
     audioBuffer->frameCount  = 0;
     audioBuffer->size        = 0;
 
-    uint32_t framesReady = cblk->framesReady();
+    uint32_t framesReady = cblk->framesReadyIn();
 
     if (framesReady == 0) {
         cblk->lock.lock();
@@ -501,12 +502,17 @@
             }
             if (!(cblk->flags & CBLK_INVALID)) {
                 mLock.unlock();
+                // this condition is in shared memory, so if IAudioRecord and control block
+                // are replaced due to mediaserver death or IAudioRecord invalidation then
+                // cv won't be signalled, but fortunately the timeout will limit the wait
                 result = cblk->cv.waitRelative(cblk->lock, milliseconds(waitTimeMs));
                 cblk->lock.unlock();
                 mLock.lock();
                 if (!mActive) {
                     return status_t(STOPPED);
                 }
+                // IAudioRecord may have been re-created while mLock was unlocked
+                cblk = mCblk;
                 cblk->lock.lock();
             }
             if (cblk->flags & CBLK_INVALID) {
@@ -524,7 +530,9 @@
                     if (result == DEAD_OBJECT) {
                         android_atomic_or(CBLK_INVALID, &cblk->flags);
 create_new_record:
-                        result = AudioRecord::restoreRecord_l(cblk);
+                        audio_track_cblk_t* temp = cblk;
+                        result = AudioRecord::restoreRecord_l(temp);
+                        cblk = temp;
                     }
                     if (result != NO_ERROR) {
                         ALOGW("obtainBuffer create Track error %d", result);
@@ -540,7 +548,7 @@
             }
             // read the server count again
         start_loop_here:
-            framesReady = cblk->framesReady();
+            framesReady = cblk->framesReadyIn();
         }
         cblk->lock.unlock();
     }
@@ -560,12 +568,9 @@
         framesReq = bufferEnd - u;
     }
 
-    audioBuffer->flags       = 0;
-    audioBuffer->channelCount= mChannelCount;
-    audioBuffer->format      = mFormat;
     audioBuffer->frameCount  = framesReq;
-    audioBuffer->size        = framesReq*cblk->frameSize;
-    audioBuffer->raw         = (int8_t*)cblk->buffer(u);
+    audioBuffer->size        = framesReq * mFrameSize;
+    audioBuffer->raw         = cblk->buffer(mBuffers, mFrameSize, u);
     active = mActive;
     return active ? status_t(NO_ERROR) : status_t(STOPPED);
 }
@@ -573,7 +578,7 @@
 void AudioRecord::releaseBuffer(Buffer* audioBuffer)
 {
     AutoMutex lock(mLock);
-    mCblk->stepUser(audioBuffer->frameCount);
+    mCblk->stepUserIn(audioBuffer->frameCount);
 }
 
 audio_io_handle_t AudioRecord::getInput() const
@@ -735,7 +740,7 @@
 
 
     // Manage overrun callback
-    if (active && (cblk->framesAvailable() == 0)) {
+    if (active && (cblk->framesAvailableIn() == 0)) {
         // The value of active is stale, but we are almost sure to be active here because
         // otherwise we would have exited when obtainBuffer returned STOPPED earlier.
         ALOGV("Overrun user: %x, server: %x, flags %04x", cblk->user, cblk->server, cblk->flags);
@@ -755,57 +760,41 @@
 // must be called with mLock and cblk.lock held. Callers must also hold strong references on
 // the IAudioRecord and IMemory in case they are recreated here.
 // If the IAudioRecord is successfully restored, the cblk pointer is updated
-status_t AudioRecord::restoreRecord_l(audio_track_cblk_t*& cblk)
+status_t AudioRecord::restoreRecord_l(audio_track_cblk_t*& refCblk)
 {
     status_t result;
 
-    if (!(android_atomic_or(CBLK_RESTORING, &cblk->flags) & CBLK_RESTORING)) {
-        ALOGW("dead IAudioRecord, creating a new one");
-        // signal old cblk condition so that other threads waiting for available buffers stop
-        // waiting now
-        cblk->cv.broadcast();
-        cblk->lock.unlock();
+    audio_track_cblk_t* cblk = refCblk;
+    audio_track_cblk_t* newCblk = cblk;
+    ALOGW("dead IAudioRecord, creating a new one");
 
-        // if the new IAudioRecord is created, openRecord_l() will modify the
-        // following member variables: mAudioRecord, mCblkMemory and mCblk.
-        // It will also delete the strong references on previous IAudioRecord and IMemory
-        result = openRecord_l(cblk->sampleRate, mFormat, mChannelMask,
-                mFrameCount, getInput_l());
-        if (result == NO_ERROR) {
-            // callback thread or sync event hasn't changed
-            result = mAudioRecord->start(AudioSystem::SYNC_EVENT_SAME, 0);
-        }
-        if (result != NO_ERROR) {
-            mActive = false;
-        }
+    // signal old cblk condition so that other threads waiting for available buffers stop
+    // waiting now
+    cblk->cv.broadcast();
+    cblk->lock.unlock();
 
-        // signal old cblk condition for other threads waiting for restore completion
-        android_atomic_or(CBLK_RESTORED, &cblk->flags);
-        cblk->cv.broadcast();
-    } else {
-        if (!(cblk->flags & CBLK_RESTORED)) {
-            ALOGW("dead IAudioRecord, waiting for a new one to be created");
-            mLock.unlock();
-            result = cblk->cv.waitRelative(cblk->lock, milliseconds(RESTORE_TIMEOUT_MS));
-            cblk->lock.unlock();
-            mLock.lock();
-        } else {
-            ALOGW("dead IAudioRecord, already restored");
-            result = NO_ERROR;
-            cblk->lock.unlock();
-        }
-        if (result != NO_ERROR || !mActive) {
-            result = status_t(STOPPED);
-        }
+    // if the new IAudioRecord is created, openRecord_l() will modify the
+    // following member variables: mAudioRecord, mCblkMemory and mCblk.
+    // It will also delete the strong references on previous IAudioRecord and IMemory
+    result = openRecord_l(cblk->sampleRate, mFormat, mChannelMask,
+            mFrameCount, getInput_l());
+    if (result == NO_ERROR) {
+        newCblk = mCblk;
+        // callback thread or sync event hasn't changed
+        result = mAudioRecord->start(AudioSystem::SYNC_EVENT_SAME, 0);
     }
+    if (result != NO_ERROR) {
+        mActive = false;
+    }
+
     ALOGV("restoreRecord_l() status %d mActive %d cblk %p, old cblk %p flags %08x old flags %08x",
-        result, mActive, mCblk, cblk, mCblk->flags, cblk->flags);
+        result, mActive, newCblk, cblk, newCblk->flags, cblk->flags);
 
     if (result == NO_ERROR) {
         // from now on we switch to the newly created cblk
-        cblk = mCblk;
+        refCblk = newCblk;
     }
-    cblk->lock.lock();
+    newCblk->lock.lock();
 
     ALOGW_IF(result != NO_ERROR, "restoreRecord_l() error %d", result);
 
diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp
index 767c452..f3b74a2 100644
--- a/media/libmedia/AudioSystem.cpp
+++ b/media/libmedia/AudioSystem.cpp
@@ -205,12 +205,7 @@
     return volume ? 100 - int(dBConvertInverse * log(volume) + 0.5) : 0;
 }
 
-// DEPRECATED
-status_t AudioSystem::getOutputSamplingRate(int* samplingRate, int streamType) {
-    return getOutputSamplingRate(samplingRate, (audio_stream_type_t)streamType);
-}
-
-status_t AudioSystem::getOutputSamplingRate(int* samplingRate, audio_stream_type_t streamType)
+status_t AudioSystem::getOutputSamplingRate(uint32_t* samplingRate, audio_stream_type_t streamType)
 {
     audio_io_handle_t output;
 
@@ -228,7 +223,7 @@
 
 status_t AudioSystem::getSamplingRate(audio_io_handle_t output,
                                       audio_stream_type_t streamType,
-                                      int* samplingRate)
+                                      uint32_t* samplingRate)
 {
     OutputDescriptor *outputDesc;
 
@@ -246,17 +241,12 @@
         gLock.unlock();
     }
 
-    ALOGV("getSamplingRate() streamType %d, output %d, sampling rate %d", streamType, output,
+    ALOGV("getSamplingRate() streamType %d, output %d, sampling rate %u", streamType, output,
             *samplingRate);
 
     return NO_ERROR;
 }
 
-// DEPRECATED
-status_t AudioSystem::getOutputFrameCount(int* frameCount, int streamType) {
-    return getOutputFrameCount(frameCount, (audio_stream_type_t)streamType);
-}
-
 status_t AudioSystem::getOutputFrameCount(int* frameCount, audio_stream_type_t streamType)
 {
     audio_io_handle_t output;
@@ -452,7 +442,7 @@
 
         OutputDescriptor *outputDesc =  new OutputDescriptor(*desc);
         gOutputs.add(ioHandle, outputDesc);
-        ALOGV("ioConfigChanged() new output samplingRate %d, format %d channels %#x frameCount %d "
+        ALOGV("ioConfigChanged() new output samplingRate %u, format %d channels %#x frameCount %d "
                 "latency %d",
                 outputDesc->samplingRate, outputDesc->format, outputDesc->channels,
                 outputDesc->frameCount, outputDesc->latency);
@@ -476,7 +466,7 @@
         if (param2 == NULL) break;
         desc = (const OutputDescriptor *)param2;
 
-        ALOGV("ioConfigChanged() new config for output %d samplingRate %d, format %d channels %#x "
+        ALOGV("ioConfigChanged() new config for output %d samplingRate %u, format %d channels %#x "
                 "frameCount %d latency %d",
                 ioHandle, desc->samplingRate, desc->format,
                 desc->channels, desc->frameCount, desc->latency);
@@ -750,7 +740,7 @@
     return NO_ERROR;
 }
 
-int32_t AudioSystem::getPrimaryOutputSamplingRate()
+uint32_t AudioSystem::getPrimaryOutputSamplingRate()
 {
     const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
     if (af == 0) return 0;
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index 9f087c2..5fb36ee 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -65,7 +65,7 @@
     //          audio_format_t format
     //          audio_channel_mask_t channelMask
     //          audio_output_flags_t flags
-    int afSampleRate;
+    uint32_t afSampleRate;
     if (AudioSystem::getOutputSamplingRate(&afSampleRate, streamType) != NO_ERROR) {
         return NO_INIT;
     }
@@ -193,7 +193,7 @@
     }
 
     if (sampleRate == 0) {
-        int afSampleRate;
+        uint32_t afSampleRate;
         if (AudioSystem::getOutputSamplingRate(&afSampleRate, streamType) != NO_ERROR) {
             return NO_INIT;
         }
@@ -286,6 +286,15 @@
     mFormat = format;
     mChannelMask = channelMask;
     mChannelCount = channelCount;
+
+    if (audio_is_linear_pcm(format)) {
+        mFrameSize = channelCount * audio_bytes_per_sample(format);
+        mFrameSizeAF = channelCount * sizeof(int16_t);
+    } else {
+        mFrameSize = sizeof(uint8_t);
+        mFrameSizeAF = sizeof(uint8_t);
+    }
+
     mSharedBuffer = sharedBuffer;
     mMuted = false;
     mActive = false;
@@ -297,7 +306,6 @@
     mUpdatePeriod = 0;
     mFlushed = false;
     AudioSystem::acquireAudioSessionId(mSessionId);
-    mRestoreStatus = NO_ERROR;
     return NO_ERROR;
 }
 
@@ -333,15 +341,6 @@
     return mCblk->frameCount;
 }
 
-size_t AudioTrack::frameSize() const
-{
-    if (audio_is_linear_pcm(mFormat)) {
-        return channelCount()*audio_bytes_per_sample(mFormat);
-    } else {
-        return sizeof(uint8_t);
-    }
-}
-
 sp<IMemory>& AudioTrack::sharedBuffer()
 {
     return mSharedBuffer;
@@ -378,7 +377,7 @@
             androidSetThreadPriority(0, ANDROID_PRIORITY_AUDIO);
         }
 
-        ALOGV("start %p before lock cblk %p", this, mCblk);
+        ALOGV("start %p before lock cblk %p", this, cblk);
         status_t status = NO_ERROR;
         if (!(cblk->flags & CBLK_INVALID)) {
             cblk->lock.unlock();
@@ -390,7 +389,9 @@
             }
         }
         if (cblk->flags & CBLK_INVALID) {
-            status = restoreTrack_l(cblk, true);
+            audio_track_cblk_t* temp = cblk;
+            status = restoreTrack_l(temp, true /*fromStart*/);
+            cblk = temp;
         }
         cblk->lock.unlock();
         if (status != NO_ERROR) {
@@ -507,14 +508,9 @@
     return NO_ERROR;
 }
 
-void AudioTrack::getVolume(float* left, float* right) const
+status_t AudioTrack::setVolume(float volume)
 {
-    if (left != NULL) {
-        *left  = mVolume[LEFT];
-    }
-    if (right != NULL) {
-        *right = mVolume[RIGHT];
-    }
+    return setVolume(volume, volume);
 }
 
 status_t AudioTrack::setAuxEffectSendLevel(float level)
@@ -539,9 +535,9 @@
     }
 }
 
-status_t AudioTrack::setSampleRate(int rate)
+status_t AudioTrack::setSampleRate(uint32_t rate)
 {
-    int afSamplingRate;
+    uint32_t afSamplingRate;
 
     if (mIsTimed) {
         return INVALID_OPERATION;
@@ -551,7 +547,7 @@
         return NO_INIT;
     }
     // Resampler implementation limits input sampling rate to 2 x output sampling rate.
-    if (rate <= 0 || rate > afSamplingRate*2 ) return BAD_VALUE;
+    if (rate == 0 || rate > afSamplingRate*2 ) return BAD_VALUE;
 
     AutoMutex lock(mLock);
     mCblk->sampleRate = rate;
@@ -561,7 +557,7 @@
 uint32_t AudioTrack::getSampleRate() const
 {
     if (mIsTimed) {
-        return INVALID_OPERATION;
+        return 0;
     }
 
     AutoMutex lock(mLock);
@@ -664,12 +660,13 @@
 
     if (!stopped_l()) return INVALID_OPERATION;
 
-    Mutex::Autolock _l(mCblk->lock);
+    audio_track_cblk_t* cblk = mCblk;
+    Mutex::Autolock _l(cblk->lock);
 
-    if (position > mCblk->user) return BAD_VALUE;
+    if (position > cblk->user) return BAD_VALUE;
 
-    mCblk->server = position;
-    android_atomic_or(CBLK_FORCEREADY, &mCblk->flags);
+    cblk->server = position;
+    android_atomic_or(CBLK_FORCEREADY, &cblk->flags);
 
     return NO_ERROR;
 }
@@ -691,7 +688,8 @@
 
     flush_l();
 
-    mCblk->stepUser(mCblk->frameCount);
+    audio_track_cblk_t* cblk = mCblk;
+    cblk->stepUserOut(cblk->frameCount);
 
     return NO_ERROR;
 }
@@ -804,7 +802,7 @@
     } else if (!(flags & AUDIO_OUTPUT_FLAG_FAST)) {
 
         // FIXME move these calculations and associated checks to server
-        int afSampleRate;
+        uint32_t afSampleRate;
         if (AudioSystem::getSamplingRate(output, streamType, &afSampleRate) != NO_ERROR) {
             return NO_INIT;
         }
@@ -818,7 +816,7 @@
         if (minBufCount < 2) minBufCount = 2;
 
         int minFrameCount = (afFrameCount*sampleRate*minBufCount)/afSampleRate;
-        ALOGV("minFrameCount: %d, afFrameCount=%d, minBufCount=%d, sampleRate=%d, afSampleRate=%d"
+        ALOGV("minFrameCount: %d, afFrameCount=%d, minBufCount=%d, sampleRate=%u, afSampleRate=%u"
                 ", afLatency=%d",
                 minFrameCount, afFrameCount, minBufCount, sampleRate, afSampleRate, afLatency);
 
@@ -860,10 +858,12 @@
     sp<IAudioTrack> track = audioFlinger->createTrack(getpid(),
                                                       streamType,
                                                       sampleRate,
-                                                      format,
+                                                      // AudioFlinger only sees 16-bit PCM
+                                                      format == AUDIO_FORMAT_PCM_8_BIT ?
+                                                              AUDIO_FORMAT_PCM_16_BIT : format,
                                                       channelMask,
                                                       frameCount,
-                                                      trackFlags,
+                                                      &trackFlags,
                                                       sharedBuffer,
                                                       output,
                                                       tid,
@@ -874,50 +874,49 @@
         ALOGE("AudioFlinger could not create track, status: %d", status);
         return status;
     }
-    sp<IMemory> cblk = track->getCblk();
-    if (cblk == 0) {
+    sp<IMemory> iMem = track->getCblk();
+    if (iMem == 0) {
         ALOGE("Could not get control block");
         return NO_INIT;
     }
     mAudioTrack = track;
-    mCblkMemory = cblk;
-    mCblk = static_cast<audio_track_cblk_t*>(cblk->pointer());
-    // old has the previous value of mCblk->flags before the "or" operation
-    int32_t old = android_atomic_or(CBLK_DIRECTION, &mCblk->flags);
+    mCblkMemory = iMem;
+    audio_track_cblk_t* cblk = static_cast<audio_track_cblk_t*>(iMem->pointer());
+    mCblk = cblk;
     if (flags & AUDIO_OUTPUT_FLAG_FAST) {
-        if (old & CBLK_FAST) {
-            ALOGV("AUDIO_OUTPUT_FLAG_FAST successful; frameCount %u", mCblk->frameCount);
+        if (trackFlags & IAudioFlinger::TRACK_FAST) {
+            ALOGV("AUDIO_OUTPUT_FLAG_FAST successful; frameCount %u", cblk->frameCount);
         } else {
-            ALOGV("AUDIO_OUTPUT_FLAG_FAST denied by server; frameCount %u", mCblk->frameCount);
+            ALOGV("AUDIO_OUTPUT_FLAG_FAST denied by server; frameCount %u", cblk->frameCount);
             // once denied, do not request again if IAudioTrack is re-created
             flags = (audio_output_flags_t) (flags & ~AUDIO_OUTPUT_FLAG_FAST);
             mFlags = flags;
         }
         if (sharedBuffer == 0) {
-            mNotificationFramesAct = mCblk->frameCount/2;
+            mNotificationFramesAct = cblk->frameCount/2;
         }
     }
     if (sharedBuffer == 0) {
-        mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t);
+        mBuffers = (char*)cblk + sizeof(audio_track_cblk_t);
     } else {
-        mCblk->buffers = sharedBuffer->pointer();
+        mBuffers = sharedBuffer->pointer();
         // Force buffer full condition as data is already present in shared memory
-        mCblk->stepUser(mCblk->frameCount);
+        cblk->stepUserOut(cblk->frameCount);
     }
 
-    mCblk->setVolumeLR((uint32_t(uint16_t(mVolume[RIGHT] * 0x1000)) << 16) |
+    cblk->setVolumeLR((uint32_t(uint16_t(mVolume[RIGHT] * 0x1000)) << 16) |
             uint16_t(mVolume[LEFT] * 0x1000));
-    mCblk->setSendLevel(mSendLevel);
+    cblk->setSendLevel(mSendLevel);
     mAudioTrack->attachAuxEffect(mAuxEffectId);
-    mCblk->bufferTimeoutMs = MAX_STARTUP_TIMEOUT_MS;
-    mCblk->waitTimeMs = 0;
+    cblk->bufferTimeoutMs = MAX_STARTUP_TIMEOUT_MS;
+    cblk->waitTimeMs = 0;
     mRemainingFrames = mNotificationFramesAct;
     // FIXME don't believe this lie
-    mLatency = afLatency + (1000*mCblk->frameCount) / sampleRate;
+    mLatency = afLatency + (1000*cblk->frameCount) / sampleRate;
     // If IAudioTrack is re-created, don't let the requested frameCount
     // decrease.  This can confuse clients that cache frameCount().
-    if (mCblk->frameCount > mFrameCount) {
-        mFrameCount = mCblk->frameCount;
+    if (cblk->frameCount > mFrameCount) {
+        mFrameCount = cblk->frameCount;
     }
     return NO_ERROR;
 }
@@ -934,7 +933,7 @@
     audioBuffer->frameCount  = 0;
     audioBuffer->size = 0;
 
-    uint32_t framesAvail = cblk->framesAvailable();
+    uint32_t framesAvail = cblk->framesAvailableOut();
 
     cblk->lock.lock();
     if (cblk->flags & CBLK_INVALID) {
@@ -958,12 +957,17 @@
             }
             if (!(cblk->flags & CBLK_INVALID)) {
                 mLock.unlock();
+                // this condition is in shared memory, so if IAudioTrack and control block
+                // are replaced due to mediaserver death or IAudioTrack invalidation then
+                // cv won't be signalled, but fortunately the timeout will limit the wait
                 result = cblk->cv.waitRelative(cblk->lock, milliseconds(waitTimeMs));
                 cblk->lock.unlock();
                 mLock.lock();
                 if (!mActive) {
                     return status_t(STOPPED);
                 }
+                // IAudioTrack may have been re-created while mLock was unlocked
+                cblk = mCblk;
                 cblk->lock.lock();
             }
 
@@ -985,7 +989,9 @@
                         if (result == DEAD_OBJECT) {
                             android_atomic_or(CBLK_INVALID, &cblk->flags);
 create_new_track:
-                            result = restoreTrack_l(cblk, false);
+                            audio_track_cblk_t* temp = cblk;
+                            result = restoreTrack_l(temp, false /*fromStart*/);
+                            cblk = temp;
                         }
                         if (result != NO_ERROR) {
                             ALOGW("obtainBuffer create Track error %d", result);
@@ -1003,7 +1009,7 @@
             }
             // read the server count again
         start_loop_here:
-            framesAvail = cblk->framesAvailable_l();
+            framesAvail = cblk->framesAvailableOut_l();
         }
         cblk->lock.unlock();
     }
@@ -1021,16 +1027,9 @@
         framesReq = bufferEnd - u;
     }
 
-    audioBuffer->flags = mMuted ? Buffer::MUTE : 0;
-    audioBuffer->channelCount = mChannelCount;
     audioBuffer->frameCount = framesReq;
-    audioBuffer->size = framesReq * cblk->frameSize;
-    if (audio_is_linear_pcm(mFormat)) {
-        audioBuffer->format = AUDIO_FORMAT_PCM_16_BIT;
-    } else {
-        audioBuffer->format = mFormat;
-    }
-    audioBuffer->raw = (int8_t *)cblk->buffer(u);
+    audioBuffer->size = framesReq * mFrameSizeAF;
+    audioBuffer->raw = cblk->buffer(mBuffers, mFrameSizeAF, u);
     active = mActive;
     return active ? status_t(NO_ERROR) : status_t(STOPPED);
 }
@@ -1038,12 +1037,13 @@
 void AudioTrack::releaseBuffer(Buffer* audioBuffer)
 {
     AutoMutex lock(mLock);
-    mCblk->stepUser(audioBuffer->frameCount);
+    audio_track_cblk_t* cblk = mCblk;
+    cblk->stepUserOut(audioBuffer->frameCount);
     if (audioBuffer->frameCount > 0) {
         // restart track if it was disabled by audioflinger due to previous underrun
-        if (mActive && (mCblk->flags & CBLK_DISABLED)) {
-            android_atomic_and(~CBLK_DISABLED, &mCblk->flags);
-            ALOGW("releaseBuffer() track %p name=%#x disabled, restarting", this, mCblk->mName);
+        if (mActive && (cblk->flags & CBLK_DISABLED)) {
+            android_atomic_and(~CBLK_DISABLED, &cblk->flags);
+            ALOGW("releaseBuffer() track %p name=%#x disabled, restarting", this, cblk->mName);
             mAudioTrack->start();
         }
     }
@@ -1078,6 +1078,9 @@
     sp<IMemory> iMem = mCblkMemory;
     mLock.unlock();
 
+    // since mLock is unlocked the IAudioTrack and shared memory may be re-created,
+    // so all cblk references might still refer to old shared memory, but that should be benign
+
     ssize_t written = 0;
     const int8_t *src = (const int8_t *)buffer;
     Buffer audioBuffer;
@@ -1103,8 +1106,8 @@
         } else {
             toWrite = audioBuffer.size;
             memcpy(audioBuffer.i8, src, toWrite);
-            src += toWrite;
         }
+        src += toWrite;
         userSize -= toWrite;
         written += toWrite;
 
@@ -1122,24 +1125,33 @@
 
 status_t TimedAudioTrack::allocateTimedBuffer(size_t size, sp<IMemory>* buffer)
 {
+    AutoMutex lock(mLock);
     status_t result = UNKNOWN_ERROR;
 
+    // acquire a strong reference on the IMemory and IAudioTrack so that they cannot be destroyed
+    // while we are accessing the cblk
+    sp<IAudioTrack> audioTrack = mAudioTrack;
+    sp<IMemory> iMem = mCblkMemory;
+
     // If the track is not invalid already, try to allocate a buffer.  alloc
     // fails indicating that the server is dead, flag the track as invalid so
     // we can attempt to restore in just a bit.
-    if (!(mCblk->flags & CBLK_INVALID)) {
+    audio_track_cblk_t* cblk = mCblk;
+    if (!(cblk->flags & CBLK_INVALID)) {
         result = mAudioTrack->allocateTimedBuffer(size, buffer);
         if (result == DEAD_OBJECT) {
-            android_atomic_or(CBLK_INVALID, &mCblk->flags);
+            android_atomic_or(CBLK_INVALID, &cblk->flags);
         }
     }
 
     // If the track is invalid at this point, attempt to restore it. and try the
     // allocation one more time.
-    if (mCblk->flags & CBLK_INVALID) {
-        mCblk->lock.lock();
-        result = restoreTrack_l(mCblk, false);
-        mCblk->lock.unlock();
+    if (cblk->flags & CBLK_INVALID) {
+        cblk->lock.lock();
+        audio_track_cblk_t* temp = cblk;
+        result = restoreTrack_l(temp, false /*fromStart*/);
+        cblk = temp;
+        cblk->lock.unlock();
 
         if (result == OK)
             result = mAudioTrack->allocateTimedBuffer(size, buffer);
@@ -1154,10 +1166,11 @@
     status_t status = mAudioTrack->queueTimedBuffer(buffer, pts);
     {
         AutoMutex lock(mLock);
+        audio_track_cblk_t* cblk = mCblk;
         // restart track if it was disabled by audioflinger due to previous underrun
         if (buffer->size() != 0 && status == NO_ERROR &&
-                mActive && (mCblk->flags & CBLK_DISABLED)) {
-            android_atomic_and(~CBLK_DISABLED, &mCblk->flags);
+                mActive && (cblk->flags & CBLK_DISABLED)) {
+            android_atomic_and(~CBLK_DISABLED, &cblk->flags);
             ALOGW("queueTimedBuffer() track %p disabled, restarting", this);
             mAudioTrack->start();
         }
@@ -1188,8 +1201,11 @@
     bool active = mActive;
     mLock.unlock();
 
+    // since mLock is unlocked the IAudioTrack and shared memory may be re-created,
+    // so all cblk references might still refer to old shared memory, but that should be benign
+
     // Manage underrun callback
-    if (active && (cblk->framesAvailable() == cblk->frameCount)) {
+    if (active && (cblk->framesAvailableOut() == cblk->frameCount)) {
         ALOGV("Underrun user: %x, server: %x, flags %04x", cblk->user, cblk->server, cblk->flags);
         if (!(android_atomic_or(CBLK_UNDERRUN, &cblk->flags) & CBLK_UNDERRUN)) {
             mCbf(EVENT_UNDERRUN, mUserData, 0);
@@ -1285,10 +1301,10 @@
         }
 
         audioBuffer.size = writtenSize;
-        // NOTE: mCblk->frameSize is not equal to AudioTrack::frameSize() for
-        // 8 bit PCM data: in this case,  mCblk->frameSize is based on a sample size of
+        // NOTE: cblk->frameSize is not equal to AudioTrack::frameSize() for
+        // 8 bit PCM data: in this case,  cblk->frameSize is based on a sample size of
         // 16 bit.
-        audioBuffer.frameCount = writtenSize/mCblk->frameSize;
+        audioBuffer.frameCount = writtenSize / mFrameSizeAF;
 
         frames -= audioBuffer.frameCount;
 
@@ -1304,118 +1320,90 @@
     return true;
 }
 
-// must be called with mLock and cblk.lock held. Callers must also hold strong references on
+// must be called with mLock and refCblk.lock held. Callers must also hold strong references on
 // the IAudioTrack and IMemory in case they are recreated here.
-// If the IAudioTrack is successfully restored, the cblk pointer is updated
-status_t AudioTrack::restoreTrack_l(audio_track_cblk_t*& cblk, bool fromStart)
+// If the IAudioTrack is successfully restored, the refCblk pointer is updated
+// FIXME Don't depend on caller to hold strong references.
+status_t AudioTrack::restoreTrack_l(audio_track_cblk_t*& refCblk, bool fromStart)
 {
     status_t result;
 
-    if (!(android_atomic_or(CBLK_RESTORING, &cblk->flags) & CBLK_RESTORING)) {
-        ALOGW("dead IAudioTrack, creating a new one from %s TID %d",
-            fromStart ? "start()" : "obtainBuffer()", gettid());
+    audio_track_cblk_t* cblk = refCblk;
+    audio_track_cblk_t* newCblk = cblk;
+    ALOGW("dead IAudioTrack, creating a new one from %s TID %d",
+        fromStart ? "start()" : "obtainBuffer()", gettid());
 
-        // signal old cblk condition so that other threads waiting for available buffers stop
-        // waiting now
-        cblk->cv.broadcast();
-        cblk->lock.unlock();
+    // signal old cblk condition so that other threads waiting for available buffers stop
+    // waiting now
+    cblk->cv.broadcast();
+    cblk->lock.unlock();
 
-        // refresh the audio configuration cache in this process to make sure we get new
-        // output parameters in getOutput_l() and createTrack_l()
-        AudioSystem::clearAudioConfigCache();
+    // refresh the audio configuration cache in this process to make sure we get new
+    // output parameters in getOutput_l() and createTrack_l()
+    AudioSystem::clearAudioConfigCache();
 
-        // if the new IAudioTrack is created, createTrack_l() will modify the
-        // following member variables: mAudioTrack, mCblkMemory and mCblk.
-        // It will also delete the strong references on previous IAudioTrack and IMemory
-        result = createTrack_l(mStreamType,
-                               cblk->sampleRate,
-                               mFormat,
-                               mChannelMask,
-                               mFrameCount,
-                               mFlags,
-                               mSharedBuffer,
-                               getOutput_l());
+    // if the new IAudioTrack is created, createTrack_l() will modify the
+    // following member variables: mAudioTrack, mCblkMemory and mCblk.
+    // It will also delete the strong references on previous IAudioTrack and IMemory
+    result = createTrack_l(mStreamType,
+                           cblk->sampleRate,
+                           mFormat,
+                           mChannelMask,
+                           mFrameCount,
+                           mFlags,
+                           mSharedBuffer,
+                           getOutput_l());
 
-        if (result == NO_ERROR) {
-            uint32_t user = cblk->user;
-            uint32_t server = cblk->server;
-            // restore write index and set other indexes to reflect empty buffer status
-            mCblk->user = user;
-            mCblk->server = user;
-            mCblk->userBase = user;
-            mCblk->serverBase = user;
-            // restore loop: this is not guaranteed to succeed if new frame count is not
-            // compatible with loop length
-            setLoop_l(cblk->loopStart, cblk->loopEnd, cblk->loopCount);
-            if (!fromStart) {
-                mCblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
-                // Make sure that a client relying on callback events indicating underrun or
-                // the actual amount of audio frames played (e.g SoundPool) receives them.
-                if (mSharedBuffer == 0) {
-                    uint32_t frames = 0;
-                    if (user > server) {
-                        frames = ((user - server) > mCblk->frameCount) ?
-                                mCblk->frameCount : (user - server);
-                        memset(mCblk->buffers, 0, frames * mCblk->frameSize);
-                    }
-                    // restart playback even if buffer is not completely filled.
-                    android_atomic_or(CBLK_FORCEREADY, &mCblk->flags);
-                    // stepUser() clears CBLK_UNDERRUN flag enabling underrun callbacks to
-                    // the client
-                    mCblk->stepUser(frames);
+    if (result == NO_ERROR) {
+        uint32_t user = cblk->user;
+        uint32_t server = cblk->server;
+        // restore write index and set other indexes to reflect empty buffer status
+        newCblk = mCblk;
+        newCblk->user = user;
+        newCblk->server = user;
+        newCblk->userBase = user;
+        newCblk->serverBase = user;
+        // restore loop: this is not guaranteed to succeed if new frame count is not
+        // compatible with loop length
+        setLoop_l(cblk->loopStart, cblk->loopEnd, cblk->loopCount);
+        if (!fromStart) {
+            newCblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
+            // Make sure that a client relying on callback events indicating underrun or
+            // the actual amount of audio frames played (e.g SoundPool) receives them.
+            if (mSharedBuffer == 0) {
+                uint32_t frames = 0;
+                if (user > server) {
+                    frames = ((user - server) > newCblk->frameCount) ?
+                            newCblk->frameCount : (user - server);
+                    memset(mBuffers, 0, frames * mFrameSizeAF);
                 }
-            }
-            if (mSharedBuffer != 0) {
-                mCblk->stepUser(mCblk->frameCount);
-            }
-            if (mActive) {
-                result = mAudioTrack->start();
-                ALOGW_IF(result != NO_ERROR, "restoreTrack_l() start() failed status %d", result);
-            }
-            if (fromStart && result == NO_ERROR) {
-                mNewPosition = mCblk->server + mUpdatePeriod;
+                // restart playback even if buffer is not completely filled.
+                android_atomic_or(CBLK_FORCEREADY, &newCblk->flags);
+                // stepUser() clears CBLK_UNDERRUN flag enabling underrun callbacks to
+                // the client
+                newCblk->stepUserOut(frames);
             }
         }
-        if (result != NO_ERROR) {
-            android_atomic_and(~CBLK_RESTORING, &cblk->flags);
-            ALOGW_IF(result != NO_ERROR, "restoreTrack_l() failed status %d", result);
+        if (mSharedBuffer != 0) {
+            newCblk->stepUserOut(newCblk->frameCount);
         }
-        mRestoreStatus = result;
-        // signal old cblk condition for other threads waiting for restore completion
-        android_atomic_or(CBLK_RESTORED, &cblk->flags);
-        cblk->cv.broadcast();
-    } else {
-        bool haveLogged = false;
-        for (;;) {
-            if (cblk->flags & CBLK_RESTORED) {
-                ALOGW("dead IAudioTrack restored");
-                result = mRestoreStatus;
-                cblk->lock.unlock();
-                break;
-            }
-            if (!haveLogged) {
-                ALOGW("dead IAudioTrack, waiting for a new one");
-                haveLogged = true;
-            }
-            mLock.unlock();
-            result = cblk->cv.waitRelative(cblk->lock, milliseconds(RESTORE_TIMEOUT_MS));
-            cblk->lock.unlock();
-            mLock.lock();
-            if (result != NO_ERROR) {
-                ALOGW("timed out");
-                break;
-            }
-            cblk->lock.lock();
+        if (mActive) {
+            result = mAudioTrack->start();
+            ALOGW_IF(result != NO_ERROR, "restoreTrack_l() start() failed status %d", result);
+        }
+        if (fromStart && result == NO_ERROR) {
+            mNewPosition = newCblk->server + mUpdatePeriod;
         }
     }
+    ALOGW_IF(result != NO_ERROR, "restoreTrack_l() failed status %d", result);
     ALOGV("restoreTrack_l() status %d mActive %d cblk %p, old cblk %p flags %08x old flags %08x",
-        result, mActive, mCblk, cblk, mCblk->flags, cblk->flags);
+        result, mActive, newCblk, cblk, newCblk->flags, cblk->flags);
 
     if (result == NO_ERROR) {
         // from now on we switch to the newly created cblk
-        cblk = mCblk;
+        refCblk = newCblk;
     }
-    cblk->lock.lock();
+    newCblk->lock.lock();
 
     ALOGW_IF(result != NO_ERROR, "restoreTrack_l() error %d TID %d", result, gettid());
 
@@ -1429,15 +1417,16 @@
     char buffer[SIZE];
     String8 result;
 
+    audio_track_cblk_t* cblk = mCblk;
     result.append(" AudioTrack::dump\n");
     snprintf(buffer, 255, "  stream type(%d), left - right volume(%f, %f)\n", mStreamType,
             mVolume[0], mVolume[1]);
     result.append(buffer);
     snprintf(buffer, 255, "  format(%d), channel count(%d), frame count(%d)\n", mFormat,
-            mChannelCount, mCblk->frameCount);
+            mChannelCount, cblk->frameCount);
     result.append(buffer);
-    snprintf(buffer, 255, "  sample rate(%d), status(%d), muted(%d)\n",
-            (mCblk == 0) ? 0 : mCblk->sampleRate, mStatus, mMuted);
+    snprintf(buffer, 255, "  sample rate(%u), status(%d), muted(%d)\n",
+            (cblk == 0) ? 0 : cblk->sampleRate, mStatus, mMuted);
     result.append(buffer);
     snprintf(buffer, 255, "  active(%d), latency (%d)\n", mActive, mLatency);
     result.append(buffer);
@@ -1499,20 +1488,20 @@
 
 audio_track_cblk_t::audio_track_cblk_t()
     : lock(Mutex::SHARED), cv(Condition::SHARED), user(0), server(0),
-    userBase(0), serverBase(0), buffers(NULL), frameCount(0),
+    userBase(0), serverBase(0), frameCount(0),
     loopStart(UINT_MAX), loopEnd(UINT_MAX), loopCount(0), mVolumeLR(0x10001000),
     mSendLevel(0), flags(0)
 {
 }
 
-uint32_t audio_track_cblk_t::stepUser(uint32_t frameCount)
+uint32_t audio_track_cblk_t::stepUser(uint32_t frameCount, bool isOut)
 {
     ALOGV("stepuser %08x %08x %d", user, server, frameCount);
 
     uint32_t u = user;
     u += frameCount;
     // Ensure that user is never ahead of server for AudioRecord
-    if (flags & CBLK_DIRECTION) {
+    if (isOut) {
         // If stepServer() has been called once, switch to normal obtainBuffer() timeout period
         if (bufferTimeoutMs == MAX_STARTUP_TIMEOUT_MS-1) {
             bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
@@ -1543,7 +1532,7 @@
     return u;
 }
 
-bool audio_track_cblk_t::stepServer(uint32_t frameCount)
+bool audio_track_cblk_t::stepServer(uint32_t frameCount, bool isOut)
 {
     ALOGV("stepserver %08x %08x %d", user, server, frameCount);
 
@@ -1556,7 +1545,7 @@
     bool flushed = (s == user);
 
     s += frameCount;
-    if (flags & CBLK_DIRECTION) {
+    if (isOut) {
         // Mark that we have read the first buffer so that next time stepUser() is called
         // we switch to normal obtainBuffer() timeout period
         if (bufferTimeoutMs == MAX_STARTUP_TIMEOUT_MS) {
@@ -1601,23 +1590,23 @@
     return true;
 }
 
-void* audio_track_cblk_t::buffer(uint32_t offset) const
+void* audio_track_cblk_t::buffer(void *buffers, size_t frameSize, uint32_t offset) const
 {
     return (int8_t *)buffers + (offset - userBase) * frameSize;
 }
 
-uint32_t audio_track_cblk_t::framesAvailable()
+uint32_t audio_track_cblk_t::framesAvailable(bool isOut)
 {
     Mutex::Autolock _l(lock);
-    return framesAvailable_l();
+    return framesAvailable_l(isOut);
 }
 
-uint32_t audio_track_cblk_t::framesAvailable_l()
+uint32_t audio_track_cblk_t::framesAvailable_l(bool isOut)
 {
     uint32_t u = user;
     uint32_t s = server;
 
-    if (flags & CBLK_DIRECTION) {
+    if (isOut) {
         uint32_t limit = (s < loopStart) ? s : loopStart;
         return limit + frameCount - u;
     } else {
@@ -1625,12 +1614,12 @@
     }
 }
 
-uint32_t audio_track_cblk_t::framesReady()
+uint32_t audio_track_cblk_t::framesReady(bool isOut)
 {
     uint32_t u = user;
     uint32_t s = server;
 
-    if (flags & CBLK_DIRECTION) {
+    if (isOut) {
         if (u < loopEnd) {
             return u - s;
         } else {
diff --git a/media/libmedia/IAudioFlinger.cpp b/media/libmedia/IAudioFlinger.cpp
index f412591..0eeb6d9 100644
--- a/media/libmedia/IAudioFlinger.cpp
+++ b/media/libmedia/IAudioFlinger.cpp
@@ -90,7 +90,7 @@
                                 audio_format_t format,
                                 audio_channel_mask_t channelMask,
                                 int frameCount,
-                                track_flags_t flags,
+                                track_flags_t *flags,
                                 const sp<IMemory>& sharedBuffer,
                                 audio_io_handle_t output,
                                 pid_t tid,
@@ -106,7 +106,8 @@
         data.writeInt32(format);
         data.writeInt32(channelMask);
         data.writeInt32(frameCount);
-        data.writeInt32((int32_t) flags);
+        track_flags_t lFlags = flags != NULL ? *flags : (track_flags_t) TRACK_DEFAULT;
+        data.writeInt32(lFlags);
         data.writeStrongBinder(sharedBuffer->asBinder());
         data.writeInt32((int32_t) output);
         data.writeInt32((int32_t) tid);
@@ -119,6 +120,10 @@
         if (lStatus != NO_ERROR) {
             ALOGE("createTrack error: %s", strerror(-lStatus));
         } else {
+            lFlags = reply.readInt32();
+            if (flags != NULL) {
+                *flags = lFlags;
+            }
             lSessionId = reply.readInt32();
             if (sessionId != NULL) {
                 *sessionId = lSessionId;
@@ -690,7 +695,7 @@
         return (audio_module_handle_t) reply.readInt32();
     }
 
-    virtual int32_t getPrimaryOutputSamplingRate()
+    virtual uint32_t getPrimaryOutputSamplingRate()
     {
         Parcel data, reply;
         data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
@@ -732,7 +737,8 @@
             status_t status;
             sp<IAudioTrack> track = createTrack(pid,
                     (audio_stream_type_t) streamType, sampleRate, format,
-                    channelMask, bufferCount, flags, buffer, output, tid, &sessionId, &status);
+                    channelMask, bufferCount, &flags, buffer, output, tid, &sessionId, &status);
+            reply->writeInt32(flags);
             reply->writeInt32(sessionId);
             reply->writeInt32(status);
             reply->writeStrongBinder(track->asBinder());
diff --git a/media/libmedia/SoundPool.cpp b/media/libmedia/SoundPool.cpp
index abc8899..b321e92 100644
--- a/media/libmedia/SoundPool.cpp
+++ b/media/libmedia/SoundPool.cpp
@@ -569,7 +569,7 @@
 
         // initialize track
         int afFrameCount;
-        int afSampleRate;
+        uint32_t afSampleRate;
         audio_stream_type_t streamType = mSoundPool->streamType();
         if (AudioSystem::getOutputFrameCount(&afFrameCount, streamType) != NO_ERROR) {
             afFrameCount = kDefaultFrameCount;
diff --git a/media/libmedia/ToneGenerator.cpp b/media/libmedia/ToneGenerator.cpp
index 253602d..42584fe 100644
--- a/media/libmedia/ToneGenerator.cpp
+++ b/media/libmedia/ToneGenerator.cpp
@@ -1036,7 +1036,7 @@
         goto initAudioTrack_exit;
     }
 
-    mpAudioTrack->setVolume(mVolume, mVolume);
+    mpAudioTrack->setVolume(mVolume);
 
     mState = TONE_INIT;
 
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 9bedff1..769b322 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -1387,7 +1387,7 @@
     }
     ALOGV("open(%u, %d, 0x%x, %d, %d, %d)", sampleRate, channelCount, channelMask,
             format, bufferCount, mSessionId);
-    int afSampleRate;
+    uint32_t afSampleRate;
     int afFrameCount;
     uint32_t frameCount;
 
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 0ca027b..84b4962 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -937,7 +937,8 @@
             }
 
             err = setupAACCodec(
-                    encoder, numChannels, sampleRate, bitRate, aacProfile, isADTS != 0);
+                    encoder, numChannels, sampleRate, bitRate, aacProfile,
+                    isADTS != 0);
         }
     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
         err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
@@ -986,6 +987,10 @@
         }
     }
 
+    if (err != OK) {
+        return err;
+    }
+
     if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
         mEncoderDelay = 0;
     }
diff --git a/media/libstagefright/StagefrightMediaScanner.cpp b/media/libstagefright/StagefrightMediaScanner.cpp
index b7cf96e..359f2be 100644
--- a/media/libstagefright/StagefrightMediaScanner.cpp
+++ b/media/libstagefright/StagefrightMediaScanner.cpp
@@ -42,7 +42,7 @@
         ".mpeg", ".ogg", ".mid", ".smf", ".imy", ".wma", ".aac",
         ".wav", ".amr", ".midi", ".xmf", ".rtttl", ".rtx", ".ota",
         ".mkv", ".mka", ".webm", ".ts", ".fl", ".flac", ".mxmf",
-        ".avi", ".mpeg", ".mpg"
+        ".avi", ".mpeg", ".mpg", ".awb"
     };
     static const size_t kNumValidExtensions =
         sizeof(kValidExtensions) / sizeof(kValidExtensions[0]);
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 @@
         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 @@
         } while (err == OK && !mOutDatagrams.empty());
 
         if (err == -EAGAIN) {
+            if (!mOutDatagrams.empty()) {
+                ALOGI("%d datagrams remain queued.", mOutDatagrams.size());
+            }
             err = OK;
         }
 
diff --git a/media/libstagefright/wifi-display/Android.mk b/media/libstagefright/wifi-display/Android.mk
index 611bfff..75098f1 100644
--- a/media/libstagefright/wifi-display/Android.mk
+++ b/media/libstagefright/wifi-display/Android.mk
@@ -17,6 +17,7 @@
         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..82c98b9 100644
--- a/media/libstagefright/wifi-display/source/Converter.cpp
+++ b/media/libstagefright/wifi-display/source/Converter.cpp
@@ -48,6 +48,7 @@
       mInputFormat(format),
       mIsVideo(false),
       mIsPCMAudio(usePCMAudio),
+      mNeedToManuallyPrependSPSPPS(false),
       mDoMoreWorkPending(false)
 #if ENABLE_SILENCE_DETECTION
       ,mFirstSilentFrameUs(-1ll)
@@ -94,6 +95,10 @@
     return mOutputFormat;
 }
 
+bool Converter::needToManuallyPrependSPSPPS() const {
+    return mNeedToManuallyPrependSPSPPS;
+}
+
 static int32_t getBitrate(const char *propName, int32_t defaultValue) {
     char val[PROPERTY_VALUE_MAX];
     if (property_get(propName, val, NULL)) {
@@ -157,16 +162,45 @@
         mOutputFormat->setInt32("bitrate-mode", OMX_Video_ControlRateConstant);
         mOutputFormat->setInt32("frame-rate", 30);
         mOutputFormat->setInt32("i-frame-interval", 1);  // Iframes every 1 secs
-        mOutputFormat->setInt32("prepend-sps-pps-to-idr-frames", 1);
     }
 
     ALOGV("output format is '%s'", mOutputFormat->debugString(0).c_str());
 
-    status_t err = mEncoder->configure(
-            mOutputFormat,
-            NULL /* nativeWindow */,
-            NULL /* crypto */,
-            MediaCodec::CONFIGURE_FLAG_ENCODE);
+    mNeedToManuallyPrependSPSPPS = false;
+
+    status_t err = NO_INIT;
+
+    if (!isAudio) {
+        sp<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 @@
     size_t getInputBufferCount() const;
 
     sp<AMessage> getOutputFormat() const;
+    bool needToManuallyPrependSPSPPS() const;
 
     void feedAccessUnit(const sp<ABuffer> &accessUnit);
     void signalEOS();
@@ -78,6 +79,7 @@
     bool mIsVideo;
     bool mIsPCMAudio;
     sp<AMessage> mOutputFormat;
+    bool mNeedToManuallyPrependSPSPPS;
 
     sp<MediaCodec> mEncoder;
     sp<AMessage> mEncoderActivityNotify;
diff --git a/media/libstagefright/wifi-display/source/PlaybackSession.cpp b/media/libstagefright/wifi-display/source/PlaybackSession.cpp
index f1e7140..4e5eb52 100644
--- a/media/libstagefright/wifi-display/source/PlaybackSession.cpp
+++ b/media/libstagefright/wifi-display/source/PlaybackSession.cpp
@@ -26,6 +26,7 @@
 #include "Sender.h"
 #include "TSPacketizer.h"
 #include "include/avc_utils.h"
+#include "WifiDisplaySource.h"
 
 #include <binder/IServiceManager.h>
 #include <gui/ISurfaceComposer.h>
@@ -81,7 +82,10 @@
     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();
@@ -279,7 +283,6 @@
 void WifiDisplaySource::PlaybackSession::Track::queueOutputBuffer(
         const sp<ABuffer> &accessUnit) {
     mQueuedOutputBuffers.push_back(accessUnit);
-
     mLastOutputBufferQueuedTimeUs = ALooper::GetNowUs();
 }
 
@@ -292,6 +295,7 @@
     return outputBuffer;
 }
 
+#if SUSPEND_VIDEO_IF_IDLE
 bool WifiDisplaySource::PlaybackSession::Track::isSuspended() const {
     if (!mQueuedOutputBuffers.empty()) {
         return false;
@@ -307,6 +311,7 @@
     // this track suspended for the time being.
     return (ALooper::GetNowUs() - mLastOutputBufferQueuedTimeUs) > 60000ll;
 }
+#endif
 
 ////////////////////////////////////////////////////////////////////////////////
 
@@ -443,8 +448,13 @@
                 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);
 
@@ -642,8 +652,10 @@
     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 +747,19 @@
 }
 
 int32_t WifiDisplaySource::PlaybackSession::width() const {
+#if USE_1080P
+    return 1920;
+#else
     return 1280;
+#endif
 }
 
 int32_t WifiDisplaySource::PlaybackSession::height() const {
+#if USE_1080P
+    return 1080;
+#else
     return 720;
+#endif
 }
 
 void WifiDisplaySource::PlaybackSession::requestIDRFrame() {
@@ -767,7 +787,7 @@
 }
 
 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 +796,20 @@
     bool isHDCPEncrypted = false;
     uint64_t inputCTR;
     uint8_t HDCP_private_data[16];
+
+    bool manuallyPrependSPSPPS =
+        !track->isAudio()
+        && track->converter()->needToManuallyPrependSPSPPS()
+        && IsIDR(accessUnit);
+
     if (mHDCP != NULL && !track->isAudio()) {
         isHDCPEncrypted = true;
 
+        if (manuallyPrependSPSPPS) {
+            accessUnit = mPacketizer->prependCSD(
+                    track->packetizerTrackIndex(), accessUnit);
+        }
+
         status_t err = mHDCP->encrypt(
                 accessUnit->data(), accessUnit->size(),
                 trackIndex  /* streamCTR */,
@@ -858,6 +889,8 @@
 #endif
 
         flags |= TSPacketizer::IS_ENCRYPTED;
+    } else if (manuallyPrependSPSPPS) {
+        flags |= TSPacketizer::PREPEND_SPS_PPS_TO_IDR_FRAMES;
     }
 
     int64_t timeUs = ALooper::GetNowUs();
@@ -930,12 +963,21 @@
                 minTrackIndex = mTracks.keyAt(i);
                 minTimeUs = timeUs;
             }
-        } else if (!track->isSuspended()) {
+        }
+#if SUSPEND_VIDEO_IF_IDLE
+        else if (!track->isSuspended()) {
             // We still consider this track "live", so it should keep
             // delivering output data whose time stamps we'll have to
             // consider for proper interleaving.
             return false;
         }
+#else
+        else {
+            // We need access units available on all tracks to be able to
+            // dequeue the earliest one.
+            return false;
+        }
+#endif
     }
 
     if (minTrackIndex < 0) {
@@ -950,6 +992,7 @@
 
     if (err != OK) {
         notifySessionDead();
+        return false;
     }
 
     if ((ssize_t)minTrackIndex == mVideoTrackIndex) {
@@ -957,6 +1000,17 @@
     }
     mSender->queuePackets(minTimeUs, packets);
 
+#if 0
+    if (minTrackIndex == mVideoTrackIndex) {
+        int64_t nowUs = ALooper::GetNowUs();
+
+        // Latency from "data acquired" to "ready to send if we wanted to".
+        ALOGI("[%s] latencyUs = %lld ms",
+              minTrackIndex == mVideoTrackIndex ? "video" : "audio",
+              (nowUs - minTimeUs) / 1000ll);
+    }
+#endif
+
     return true;
 }
 
diff --git a/media/libstagefright/wifi-display/source/PlaybackSession.h b/media/libstagefright/wifi-display/source/PlaybackSession.h
index cc8b244..dabc1c4 100644
--- a/media/libstagefright/wifi-display/source/PlaybackSession.h
+++ b/media/libstagefright/wifi-display/source/PlaybackSession.h
@@ -127,7 +127,7 @@
     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 @@
                 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 @@
         const sp<AMessage> &notify)
     : 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 @@
       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 @@
     ,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 @@
     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 @@
             }
         }
 
-#if ENABLE_RETRANSMISSION
+#if ENABLE_RETRANSMISSION && RETRANSMISSION_ACCORDING_TO_RFC_XXXX
         if (mTransportMode == TRANSPORT_UDP) {
             int32_t rtpRetransmissionSession;
 
@@ -358,44 +285,67 @@
 }
 
 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;
 
-    int32_t dummy;
-    if (packets->meta()->findInt32("isVideo", &dummy)) {
-        isVideo = true;
+    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);
+
+        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();
+    sp<AMessage> msg = new AMessage(kWhatDrainQueue, id());
+    msg->setBuffer("udpPackets", udpPackets);
+    msg->post();
 
-        whenUs = (timeUs - mFirstOutputBufferReadyTimeUs)
-                + mFirstOutputBufferSentTimeUs;
-
-        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 @@
                     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 @@
                     } 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 @@
 
                     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 @@
             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::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 @@
             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 @@
                 sendPacket(
                         mRTPRetransmissionSessionID,
                         retransRTP->data(), retransRTP->size());
+#else
+                sendPacket(
+                        mRTPSessionID, buffer->data(), buffer->size());
+#endif
 
                 if (bufferSeqNo == seqNo) {
                     foundSeqNo = true;
@@ -975,5 +780,91 @@
     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..73e3d19 100644
--- a/media/libstagefright/wifi-display/source/Sender.h
+++ b/media/libstagefright/wifi-display/source/Sender.h
@@ -23,9 +23,17 @@
 namespace android {
 
 #define LOG_TRANSPORT_STREAM            0
-#define ENABLE_RETRANSMISSION           0
 #define TRACK_BANDWIDTH                 0
 
+#define ENABLE_RETRANSMISSION                   0
+
+// If retransmission is enabled the following define determines what
+// kind we support, if RETRANSMISSION_ACCORDING_TO_RFC_XXXX is 0
+// we'll send NACKs on the original RTCP channel and retransmit packets
+// on the original RTP channel, otherwise a separate channel pair is used
+// for this purpose.
+#define RETRANSMISSION_ACCORDING_TO_RFC_XXXX    0
+
 struct ABuffer;
 struct ANetworkSession;
 
@@ -51,7 +59,7 @@
 
     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 @@
 
 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 @@
     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 @@
     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 @@
     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 @@
     uint64_t mTotalBytesSent;
 #endif
 
+#if LOG_TRANSPORT_STREAM
+    FILE *mLogFile;
+#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);
-
 #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 @@
     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 @@
         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 b16c5d0..78d6e62 100644
--- a/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp
+++ b/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp
@@ -534,9 +534,15 @@
     //   use "28 00 02 02 00000020 00000000 00000000 00 0000 0000 00 none none\r\n"
     // For 720p24:
     //   use "78 00 02 02 00008000 00000000 00000000 00 0000 0000 00 none none\r\n"
+    // For 1080p30:
+    //   use "38 00 02 02 00000080 00000000 00000000 00 0000 0000 00 none none\r\n"
     AString body = StringPrintf(
         "wfd_video_formats: "
+#if USE_1080P
+        "38 00 02 02 00000080 00000000 00000000 00 0000 0000 00 none none\r\n"
+#else
         "28 00 02 02 00000020 00000000 00000000 00 0000 0000 00 none none\r\n"
+#endif
         "wfd_audio_codecs: %s\r\n"
         "wfd_presentation_URL: rtsp://%s/wfd1.0/streamid=0 none\r\n"
         "wfd_client_rtp_ports: RTP/AVP/%s;unicast %d 0 mode=play\r\n",
@@ -773,8 +779,10 @@
 
         status_t err = makeHDCP();
         if (err != OK) {
-            ALOGE("Unable to instantiate HDCP component.");
-            return err;
+            ALOGE("Unable to instantiate HDCP component. "
+                  "Not using HDCP after all.");
+
+            mUsingHDCP = false;
         }
     }
 
diff --git a/media/libstagefright/wifi-display/source/WifiDisplaySource.h b/media/libstagefright/wifi-display/source/WifiDisplaySource.h
index 02fa0a6..1e855e7 100644
--- a/media/libstagefright/wifi-display/source/WifiDisplaySource.h
+++ b/media/libstagefright/wifi-display/source/WifiDisplaySource.h
@@ -26,6 +26,8 @@
 
 namespace android {
 
+#define USE_1080P       0
+
 struct IHDCP;
 struct IRemoteDisplayClient;
 struct ParsedMessage;
diff --git a/media/libstagefright/wifi-display/wfd.cpp b/media/libstagefright/wifi-display/wfd.cpp
index 011edab..03a1123 100644
--- a/media/libstagefright/wifi-display/wfd.cpp
+++ b/media/libstagefright/wifi-display/wfd.cpp
@@ -23,22 +23,163 @@
 
 #include <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 @@
     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 @@
                 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 @@
         }
     }
 
+    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/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index cb44114..10f4410 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -451,7 +451,7 @@
         audio_format_t format,
         audio_channel_mask_t channelMask,
         int frameCount,
-        IAudioFlinger::track_flags_t flags,
+        IAudioFlinger::track_flags_t *flags,
         const sp<IMemory>& sharedBuffer,
         audio_io_handle_t output,
         pid_t tid,
@@ -472,6 +472,14 @@
         goto Exit;
     }
 
+    // client is responsible for conversion of 8-bit PCM to 16-bit PCM,
+    // and we don't yet support 8.24 or 32-bit PCM
+    if (audio_is_linear_pcm(format) && format != AUDIO_FORMAT_PCM_16_BIT) {
+        ALOGE("createTrack() invalid format %d", format);
+        lStatus = BAD_VALUE;
+        goto Exit;
+    }
+
     {
         Mutex::Autolock _l(mLock);
         PlaybackThread *thread = checkPlaybackThread_l(output);
@@ -1291,7 +1299,7 @@
     result.append(buffer);
     snprintf(buffer, SIZE, "standby: %d\n", mStandby);
     result.append(buffer);
-    snprintf(buffer, SIZE, "Sample rate: %d\n", mSampleRate);
+    snprintf(buffer, SIZE, "Sample rate: %u\n", mSampleRate);
     result.append(buffer);
     snprintf(buffer, SIZE, "HAL frame count: %d\n", mFrameCount);
     result.append(buffer);
@@ -1725,17 +1733,17 @@
         int frameCount,
         const sp<IMemory>& sharedBuffer,
         int sessionId,
-        IAudioFlinger::track_flags_t flags,
+        IAudioFlinger::track_flags_t *flags,
         pid_t tid,
         status_t *status)
 {
     sp<Track> track;
     status_t lStatus;
 
-    bool isTimed = (flags & IAudioFlinger::TRACK_TIMED) != 0;
+    bool isTimed = (*flags & IAudioFlinger::TRACK_TIMED) != 0;
 
     // client expresses a preference for FAST, but we get the final say
-    if (flags & IAudioFlinger::TRACK_FAST) {
+    if (*flags & IAudioFlinger::TRACK_FAST) {
       if (
             // not timed
             (!isTimed) &&
@@ -1776,12 +1784,12 @@
                 frameCount, mFrameCount);
       } else {
         ALOGV("AUDIO_OUTPUT_FLAG_FAST denied: isTimed=%d sharedBuffer=%p frameCount=%d "
-                "mFrameCount=%d format=%d isLinear=%d channelMask=%#x sampleRate=%d mSampleRate=%d "
+                "mFrameCount=%d format=%d isLinear=%d channelMask=%#x sampleRate=%u mSampleRate=%u "
                 "hasFastMixer=%d tid=%d fastTrackAvailMask=%#x",
                 isTimed, sharedBuffer.get(), frameCount, mFrameCount, format,
                 audio_is_linear_pcm(format),
                 channelMask, sampleRate, mSampleRate, hasFastMixer(), tid, mFastTrackAvailMask);
-        flags &= ~IAudioFlinger::TRACK_FAST;
+        *flags &= ~IAudioFlinger::TRACK_FAST;
         // For compatibility with AudioTrack calculation, buffer depth is forced
         // to be at least 2 x the normal mixer frame count and cover audio hardware latency.
         // This is probably too conservative, but legacy application code may depend on it.
@@ -1801,7 +1809,7 @@
     if (mType == DIRECT) {
         if ((format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_PCM) {
             if (sampleRate != mSampleRate || format != mFormat || channelMask != mChannelMask) {
-                ALOGE("createTrack_l() Bad parameter: sampleRate %d format %d, channelMask 0x%08x "
+                ALOGE("createTrack_l() Bad parameter: sampleRate %u format %d, channelMask 0x%08x "
                         "for output %p with format %d",
                         sampleRate, format, channelMask, mOutput, mFormat);
                 lStatus = BAD_VALUE;
@@ -1811,7 +1819,7 @@
     } else {
         // Resampler implementation limits input sampling rate to 2 x output sampling rate.
         if (sampleRate > mSampleRate*2) {
-            ALOGE("Sample rate out of range: %d mSampleRate %d", sampleRate, mSampleRate);
+            ALOGE("Sample rate out of range: %u mSampleRate %u", sampleRate, mSampleRate);
             lStatus = BAD_VALUE;
             goto Exit;
         }
@@ -1845,7 +1853,7 @@
 
         if (!isTimed) {
             track = new Track(this, client, streamType, sampleRate, format,
-                    channelMask, frameCount, sharedBuffer, sessionId, flags);
+                    channelMask, frameCount, sharedBuffer, sessionId, *flags);
         } else {
             track = TimedTrack::create(this, client, streamType, sampleRate, format,
                     channelMask, frameCount, sharedBuffer, sessionId);
@@ -1864,7 +1872,7 @@
             chain->incTrackCnt();
         }
 
-        if ((flags & IAudioFlinger::TRACK_FAST) && (tid != -1)) {
+        if ((*flags & IAudioFlinger::TRACK_FAST) && (tid != -1)) {
             pid_t callingPid = IPCThreadState::self()->getCallingPid();
             // we don't have CAP_SYS_NICE, nor do we want to have it as it's too powerful,
             // so ask activity manager to do this on our behalf
@@ -2280,7 +2288,7 @@
         // mNormalSink below
 {
     ALOGV("MixerThread() id=%d device=%#x type=%d", id, device, type);
-    ALOGV("mSampleRate=%d, mChannelMask=%#x, mChannelCount=%d, mFormat=%d, mFrameSize=%d, "
+    ALOGV("mSampleRate=%u, mChannelMask=%#x, mChannelCount=%d, mFormat=%d, mFrameSize=%u, "
             "mFrameCount=%d, mNormalFrameCount=%d",
             mSampleRate, mChannelMask, mChannelCount, mFormat, mFrameSize, mFrameCount,
             mNormalFrameCount);
@@ -3126,7 +3134,7 @@
         uint32_t minFrames = 1;
         if ((track->sharedBuffer() == 0) && !track->isStopped() && !track->isPausing() &&
                 (mMixerStatusIgnoringFastTracks == MIXER_TRACKS_READY)) {
-            if (t->sampleRate() == (int)mSampleRate) {
+            if (t->sampleRate() == mSampleRate) {
                 minFrames = mNormalFrameCount;
             } else {
                 // +1 for rounding and +1 for additional sample needed for interpolation
@@ -3624,7 +3632,7 @@
             NBAIO_Format format = teeSource->format();
             unsigned channelCount = Format_channelCount(format);
             ALOG_ASSERT(channelCount <= FCC_2);
-            unsigned sampleRate = Format_sampleRate(format);
+            uint32_t sampleRate = Format_sampleRate(format);
             wavHeader[22] = channelCount;       // number of channels
             wavHeader[24] = sampleRate;         // sample rate
             wavHeader[25] = sampleRate >> 8;
@@ -4186,14 +4194,16 @@
         mCblk(NULL),
         // mBuffer
         // mBufferEnd
-        mFrameCount(0),
+        mStepCount(0),
         mState(IDLE),
         mSampleRate(sampleRate),
         mFormat(format),
+        mChannelMask(channelMask),
+        mChannelCount(popcount(channelMask)),
+        mFrameSize(audio_is_linear_pcm(format) ?
+                mChannelCount * audio_bytes_per_sample(format) : sizeof(int8_t)),
         mStepServerFailed(false),
         mSessionId(sessionId)
-        // mChannelCount
-        // mChannelMask
 {
     // client == 0 implies sharedBuffer == 0
     ALOG_ASSERT(!(client == 0 && sharedBuffer != 0));
@@ -4203,8 +4213,7 @@
 
     // ALOGD("Creating track with %d buffers @ %d bytes", bufferCount, bufferSize);
     size_t size = sizeof(audio_track_cblk_t);
-    uint8_t channelCount = popcount(channelMask);
-    size_t bufferSize = frameCount*channelCount*sizeof(int16_t);
+    size_t bufferSize = frameCount * mFrameSize;
     if (sharedBuffer == 0) {
         size += bufferSize;
     }
@@ -4235,11 +4244,9 @@
 //      mCblk->server = 0xffff0000;
 //      mCblk->userBase = 0xffff0000;
 //      mCblk->serverBase = 0xffff0000;
-        mChannelCount = channelCount;
-        mChannelMask = channelMask;
         if (sharedBuffer == 0) {
             mBuffer = (char*)mCblk + sizeof(audio_track_cblk_t);
-            memset(mBuffer, 0, frameCount*channelCount*sizeof(int16_t));
+            memset(mBuffer, 0, bufferSize);
             // Force underrun condition to avoid false underrun callback until first data is
             // written to buffer (other flags are cleared)
             mCblk->flags = CBLK_UNDERRUN;
@@ -4276,7 +4283,7 @@
 void AudioFlinger::ThreadBase::TrackBase::releaseBuffer(AudioBufferProvider::Buffer* buffer)
 {
     buffer->raw = NULL;
-    mFrameCount = buffer->frameCount;
+    mStepCount = buffer->frameCount;
     // FIXME See note at getNextBuffer()
     (void) step();      // ignore return value of step()
     buffer->frameCount = 0;
@@ -4286,7 +4293,7 @@
     bool result;
     audio_track_cblk_t* cblk = this->cblk();
 
-    result = cblk->stepServer(mFrameCount);
+    result = cblk->stepServer(mStepCount, isOut());
     if (!result) {
         ALOGV("stepServer failed acquiring cblk mutex");
         mStepServerFailed = true;
@@ -4305,23 +4312,22 @@
     ALOGV("TrackBase::reset");
 }
 
-int AudioFlinger::ThreadBase::TrackBase::sampleRate() const {
-    return (int)mCblk->sampleRate;
+uint32_t AudioFlinger::ThreadBase::TrackBase::sampleRate() const {
+    return mCblk->sampleRate;
 }
 
 void* AudioFlinger::ThreadBase::TrackBase::getBuffer(uint32_t offset, uint32_t frames) const {
     audio_track_cblk_t* cblk = this->cblk();
-    size_t frameSize = cblk->frameSize;
-    int8_t *bufferStart = (int8_t *)mBuffer + (offset-cblk->serverBase)*frameSize;
-    int8_t *bufferEnd = bufferStart + frames * frameSize;
+    int8_t *bufferStart = (int8_t *)mBuffer + (offset-cblk->serverBase) * mFrameSize;
+    int8_t *bufferEnd = bufferStart + frames * mFrameSize;
 
     // Check validity of returned pointer in case the track control block would have been corrupted.
     ALOG_ASSERT(!(bufferStart < mBuffer || bufferStart > bufferEnd || bufferEnd > mBufferEnd),
             "TrackBase::getBuffer buffer out of range:\n"
                 "    start: %p, end %p , mBuffer %p mBufferEnd %p\n"
-                "    server %u, serverBase %u, user %u, userBase %u, frameSize %d",
+                "    server %u, serverBase %u, user %u, userBase %u, frameSize %u",
                 bufferStart, bufferEnd, mBuffer, mBufferEnd,
-                cblk->server, cblk->serverBase, cblk->user, cblk->userBase, frameSize);
+                cblk->server, cblk->serverBase, cblk->user, cblk->userBase, mFrameSize);
 
     return bufferStart;
 }
@@ -4364,10 +4370,6 @@
     mCachedVolume(1.0)
 {
     if (mCblk != NULL) {
-        // NOTE: audio_track_cblk_t::frameSize for 8 bit PCM data is based on a sample size of
-        // 16 bit because data is converted to 16 bit before being stored in buffer by AudioTrack
-        mCblk->frameSize = audio_is_linear_pcm(format) ? mChannelCount * sizeof(int16_t) :
-                sizeof(uint8_t);
         // to avoid leaking a track name, do not allocate one unless there is an mCblk
         mName = thread->getTrackName_l(channelMask, sessionId);
         mCblk->mName = mName;
@@ -4377,7 +4379,6 @@
         }
         // only allocate a fast track index if we were able to allocate a normal track name
         if (flags & IAudioFlinger::TRACK_FAST) {
-            mCblk->flags |= CBLK_FAST;  // atomic op not needed yet
             ALOG_ASSERT(thread->mFastTrackAvailMask != 0);
             int i = __builtin_ctz(thread->mFastTrackAvailMask);
             ALOG_ASSERT(0 < i && i < (int)FastMixerState::kMaxFastTracks);
@@ -4435,7 +4436,7 @@
 
 /*static*/ void AudioFlinger::PlaybackThread::Track::appendDumpHeader(String8& result)
 {
-    result.append("   Name Client Type Fmt Chn mask   Session mFrCnt fCount S M F SRate  "
+    result.append("   Name Client Type Fmt Chn mask   Session StpCnt fCount S M F SRate  "
                   "L dB  R dB    Server      User     Main buf    Aux Buf  Flags Underruns\n");
 }
 
@@ -4506,7 +4507,7 @@
             mFormat,
             mChannelMask,
             mSessionId,
-            mFrameCount,
+            mStepCount,
             mCblk->frameCount,
             stateChar,
             mMute,
@@ -4546,7 +4547,7 @@
     }
 
     // FIXME Same as above
-    framesReady = cblk->framesReady();
+    framesReady = cblk->framesReadyOut();
 
     if (CC_LIKELY(framesReady)) {
         uint32_t s = cblk->server;
@@ -4581,7 +4582,7 @@
 // the tryLock() could block for up to 1 ms, and a sequence of these could delay fast mixer.
 // FIXME Replace AudioTrackShared control block implementation by a non-blocking FIFO queue.
 size_t AudioFlinger::PlaybackThread::Track::framesReady() const {
-    return mCblk->framesReady();
+    return mCblk->framesReadyOut();
 }
 
 // Don't call for fast tracks; the framesReady() could result in priority inversion
@@ -4876,6 +4877,11 @@
     return NO_ERROR;
 }
 
+bool AudioFlinger::PlaybackThread::Track::isOut() const
+{
+    return true;
+}
+
 // timed audio tracks
 
 sp<AudioFlinger::PlaybackThread::TimedTrack>
@@ -5010,7 +5016,7 @@
             // this frame in media time units and adding it to the PTS of the
             // buffer.
             int64_t frameCount = mTimedBufferQueue[trimEnd].buffer()->size()
-                               / mCblk->frameSize;
+                               / mFrameSize;
 
             if (!mMediaTimeToSampleTransform.doReverseTransform(frameCount,
                                                                 &bufEnd)) {
@@ -5070,7 +5076,7 @@
                 " bytes.  (update reason: \"%s\")",
                 bufBytes, consumedAlready, logTag);
 
-    uint32_t bufFrames = (bufBytes - consumedAlready) / mCblk->frameSize;
+    uint32_t bufFrames = (bufBytes - consumedAlready) / mFrameSize;
     ALOG_ASSERT(mFramesPendingInQueue >= bufFrames,
                 "Bad bookkeeping while updating frames pending.  Should have at"
                 " least %u queued frames, but we think we have only %u.  (update"
@@ -5091,7 +5097,7 @@
 
     Mutex::Autolock _l(mTimedBufferQueueLock);
 
-    uint32_t bufFrames = buffer->size() / mCblk->frameSize;
+    uint32_t bufFrames = buffer->size() / mFrameSize;
     mFramesPendingInQueue += bufFrames;
     mTimedBufferQueue.add(TimedBuffer(buffer, pts));
 
@@ -5188,7 +5194,7 @@
         // adjust the head buffer's PTS to reflect the portion of the head buffer
         // that has already been consumed
         int64_t effectivePTS = headLocalPTS +
-                ((head.position() / mCblk->frameSize) * mLocalTimeFreq / sampleRate());
+                ((head.position() / mFrameSize) * mLocalTimeFreq / sampleRate());
 
         // Calculate the delta in samples between the head of the input buffer
         // queue and the start of the next output buffer that will be written.
@@ -5253,7 +5259,7 @@
             // the next input sample is late
             uint32_t lateFrames = static_cast<uint32_t>(-((sampleDelta + 0x80000000) >> 32));
             size_t onTimeSamplePosition =
-                    head.position() + lateFrames * mCblk->frameSize;
+                    head.position() + lateFrames * mFrameSize;
 
             if (onTimeSamplePosition > head.buffer()->size()) {
                 // all the remaining samples in the head are too late, so
@@ -5288,7 +5294,7 @@
                    head.position());
 
     uint32_t framesLeftInHead = ((head.buffer()->size() - head.position()) /
-                                 mCblk->frameSize);
+                                 mFrameSize);
     size_t framesRequested = buffer->frameCount;
     buffer->frameCount = min(framesLeftInHead, framesRequested);
 
@@ -5303,9 +5309,9 @@
     uint32_t numFrames, AudioBufferProvider::Buffer* buffer) {
 
     // lazily allocate a buffer filled with silence
-    if (mTimedSilenceBufferSize < numFrames * mCblk->frameSize) {
+    if (mTimedSilenceBufferSize < numFrames * mFrameSize) {
         delete [] mTimedSilenceBuffer;
-        mTimedSilenceBufferSize = numFrames * mCblk->frameSize;
+        mTimedSilenceBufferSize = numFrames * mFrameSize;
         mTimedSilenceBuffer = new uint8_t[mTimedSilenceBufferSize];
         memset(mTimedSilenceBuffer, 0, mTimedSilenceBufferSize);
     }
@@ -5353,7 +5359,7 @@
                     start, end, buffer->raw);
 
         head.setPosition(head.position() +
-                (buffer->frameCount * mCblk->frameSize));
+                (buffer->frameCount * mFrameSize));
         mQueueHeadInFlight = false;
 
         ALOG_ASSERT(mFramesPendingInQueue >= buffer->frameCount,
@@ -5405,16 +5411,7 @@
                   channelMask, frameCount, 0 /*sharedBuffer*/, sessionId),
         mOverflow(false)
 {
-    if (mCblk != NULL) {
-        ALOGV("RecordTrack constructor, size %d", (int)mBufferEnd - (int)mBuffer);
-        if (format == AUDIO_FORMAT_PCM_16_BIT) {
-            mCblk->frameSize = mChannelCount * sizeof(int16_t);
-        } else if (format == AUDIO_FORMAT_PCM_8_BIT) {
-            mCblk->frameSize = mChannelCount * sizeof(int8_t);
-        } else {
-            mCblk->frameSize = sizeof(int8_t);
-        }
-    }
+    ALOGV("RecordTrack constructor, size %d", (int)mBufferEnd - (int)mBuffer);
 }
 
 AudioFlinger::RecordThread::RecordTrack::~RecordTrack()
@@ -5437,7 +5434,8 @@
         mStepServerFailed = false;
     }
 
-    framesAvail = cblk->framesAvailable_l();
+    // FIXME lock is not actually held, so overrun is possible
+    framesAvail = cblk->framesAvailableIn_l();
 
     if (CC_LIKELY(framesAvail)) {
         uint32_t s = cblk->server;
@@ -5495,7 +5493,7 @@
 
 /*static*/ void AudioFlinger::RecordThread::RecordTrack::appendDumpHeader(String8& result)
 {
-    result.append("   Clien Fmt Chn mask   Session Buf  S SRate  Serv     User   FrameCount\n");
+    result.append("   Clien Fmt Chn mask   Session Step S SRate  Serv     User   FrameCount\n");
 }
 
 void AudioFlinger::RecordThread::RecordTrack::dump(char* buffer, size_t size)
@@ -5505,7 +5503,7 @@
             mFormat,
             mChannelMask,
             mSessionId,
-            mFrameCount,
+            mStepCount,
             mState,
             mCblk->sampleRate,
             mCblk->server,
@@ -5513,6 +5511,10 @@
             mCblk->frameCount);
 }
 
+bool AudioFlinger::RecordThread::RecordTrack::isOut() const
+{
+    return false;
+}
 
 // ----------------------------------------------------------------------------
 
@@ -5525,16 +5527,15 @@
             int frameCount)
     :   Track(playbackThread, NULL, AUDIO_STREAM_CNT, sampleRate, format, channelMask, frameCount,
                 NULL, 0, IAudioFlinger::TRACK_DEFAULT),
-    mActive(false), mSourceThread(sourceThread)
+    mActive(false), mSourceThread(sourceThread), mBuffers(NULL)
 {
 
     if (mCblk != NULL) {
-        mCblk->flags |= CBLK_DIRECTION;
-        mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t);
+        mBuffers = (char*)mCblk + sizeof(audio_track_cblk_t);
         mOutBuffer.frameCount = 0;
         playbackThread->mTracks.add(this);
         ALOGV("OutputTrack constructor mCblk %p, mBuffer %p, mCblk->buffers %p, " \
-                "mCblk->frameCount %d, mCblk->sampleRate %d, mChannelMask 0x%08x mBufferEnd %p",
+                "mCblk->frameCount %d, mCblk->sampleRate %u, mChannelMask 0x%08x mBufferEnd %p",
                 mCblk, mBuffer, mCblk->buffers,
                 mCblk->frameCount, mCblk->sampleRate, mChannelMask, mBufferEnd);
     } else {
@@ -5632,7 +5633,7 @@
         uint32_t outFrames = pInBuffer->frameCount > mOutBuffer.frameCount ? mOutBuffer.frameCount :
                 pInBuffer->frameCount;
         memcpy(mOutBuffer.raw, pInBuffer->raw, outFrames * channelCount * sizeof(int16_t));
-        mCblk->stepUser(outFrames);
+        mCblk->stepUserOut(outFrames);
         pInBuffer->frameCount -= outFrames;
         pInBuffer->i16 += outFrames * channelCount;
         mOutBuffer.frameCount -= outFrames;
@@ -5703,7 +5704,7 @@
     ALOGVV("OutputTrack::obtainBuffer user %d, server %d", cblk->user, cblk->server);
     buffer->frameCount  = 0;
 
-    uint32_t framesAvail = cblk->framesAvailable();
+    uint32_t framesAvail = cblk->framesAvailableOut();
 
 
     if (framesAvail == 0) {
@@ -5721,7 +5722,7 @@
             }
             // read the server count again
         start_loop_here:
-            framesAvail = cblk->framesAvailable_l();
+            framesAvail = cblk->framesAvailableOut_l();
         }
     }
 
@@ -5741,7 +5742,7 @@
     }
 
     buffer->frameCount  = framesReq;
-    buffer->raw         = (void *)cblk->buffer(u);
+    buffer->raw         = cblk->buffer(mBuffers, mFrameSize, u);
     return NO_ERROR;
 }
 
@@ -6149,7 +6150,7 @@
                         if (framesIn) {
                             int8_t *src = (int8_t *)mRsmpInBuffer + mRsmpInIndex * mFrameSize;
                             int8_t *dst = buffer.i8 + (buffer.frameCount - framesOut) *
-                                    mActiveTrack->mCblk->frameSize;
+                                    mActiveTrack->mFrameSize;
                             if (framesIn > framesOut)
                                 framesIn = framesOut;
                             mRsmpInIndex += framesIn;
@@ -6551,7 +6552,7 @@
         result.append(buffer);
         snprintf(buffer, SIZE, "Out channel count: %d\n", mReqChannelCount);
         result.append(buffer);
-        snprintf(buffer, SIZE, "Out sample rate: %d\n", mReqSampleRate);
+        snprintf(buffer, SIZE, "Out sample rate: %u\n", mReqSampleRate);
         result.append(buffer);
     } else {
         result.append("No active record client\n");
@@ -6646,7 +6647,7 @@
         AudioParameter param = AudioParameter(keyValuePair);
         int value;
         audio_format_t reqFormat = mFormat;
-        int reqSamplingRate = mReqSampleRate;
+        uint32_t reqSamplingRate = mReqSampleRate;
         int reqChannelCount = mReqChannelCount;
 
         if (param.getInt(String8(AudioParameter::keySamplingRate), value) == NO_ERROR) {
@@ -6980,7 +6981,7 @@
 
 // ----------------------------------------------------------------------------
 
-int32_t AudioFlinger::getPrimaryOutputSamplingRate()
+uint32_t AudioFlinger::getPrimaryOutputSamplingRate()
 {
     Mutex::Autolock _l(mLock);
     PlaybackThread *thread = primaryPlaybackThread_l();
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 2251b45..9ddfe28 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -93,7 +93,7 @@
                                 audio_format_t format,
                                 audio_channel_mask_t channelMask,
                                 int frameCount,
-                                IAudioFlinger::track_flags_t flags,
+                                IAudioFlinger::track_flags_t *flags,
                                 const sp<IMemory>& sharedBuffer,
                                 audio_io_handle_t output,
                                 pid_t tid,
@@ -207,7 +207,7 @@
 
     virtual audio_module_handle_t loadHwModule(const char *name);
 
-    virtual int32_t getPrimaryOutputSamplingRate();
+    virtual uint32_t getPrimaryOutputSamplingRate();
     virtual int32_t getPrimaryOutputFrameCount();
 
     virtual     status_t    onTransact(
@@ -423,7 +423,7 @@
 
             audio_channel_mask_t channelMask() const { return mChannelMask; }
 
-            int sampleRate() const; // FIXME inline after cblk sr moved
+            uint32_t sampleRate() const;    // FIXME inline after cblk sr moved
 
             // Return a pointer to the start of a contiguous slice of the track buffer.
             // Parameter 'offset' is the requested start position, expressed in
@@ -453,9 +453,12 @@
                 return mState == TERMINATED;
             }
 
-            bool step();
+            bool step();    // mStepCount is an implicit input
             void reset();
 
+            virtual bool isOut() const = 0; // true for Track and TimedTrack, false for RecordTrack,
+                                            // this could be a track type if needed later
+
             const wp<ThreadBase> mThread;
             /*const*/ sp<Client> mClient;   // see explanation at ~TrackBase() why not const
             sp<IMemory>         mCblkMemory;
@@ -463,16 +466,20 @@
             void*               mBuffer;    // start of track buffer, typically in shared memory
             void*               mBufferEnd; // &mBuffer[mFrameCount * frameSize], where frameSize
                                             //   is based on mChannelCount and 16-bit samples
-            uint32_t            mFrameCount;
+            uint32_t            mStepCount; // saves AudioBufferProvider::Buffer::frameCount as of
+                                            // time of releaseBuffer() for later use by step()
             // we don't really need a lock for these
             track_state         mState;
             const uint32_t      mSampleRate;    // initial sample rate only; for tracks which
                                 // support dynamic rates, the current value is in control block
             const audio_format_t mFormat;
+            const audio_channel_mask_t mChannelMask;
+            const uint8_t       mChannelCount;
+            const size_t        mFrameSize; // AudioFlinger's view of frame size in shared memory,
+                                            // where for AudioTrack (but not AudioRecord),
+                                            // 8-bit PCM samples are stored as 16-bit
             bool                mStepServerFailed;
             const int           mSessionId;
-            uint8_t             mChannelCount;
-            audio_channel_mask_t mChannelMask;
             Vector < sp<SyncEvent> >mSyncEvents;
         };
 
@@ -853,12 +860,16 @@
 
             sp<IMemory> sharedBuffer() const { return mSharedBuffer; }
 
+            // framesWritten is cumulative, never reset, and is shared all tracks
+            // audioHalFrames is derived from output latency
+            // FIXME parameters not needed, could get them from the thread
             bool presentationComplete(size_t framesWritten, size_t audioHalFrames);
 
         public:
             void triggerEvents(AudioSystem::sync_event_t type);
             virtual bool isTimedTrack() const { return false; }
             bool isFastTrack() const { return (mFlags & IAudioFlinger::TRACK_FAST) != 0; }
+            virtual bool isOut() const;
 
         protected:
 
@@ -884,6 +895,7 @@
             bool                mHasVolumeController;
             size_t              mPresentationCompleteFrames; // number of frames written to the
                                             // audio HAL when this track will be fully rendered
+                                            // zero means not monitoring
         private:
             IAudioFlinger::track_flags_t mFlags;
 
@@ -988,7 +1000,7 @@
         };
 
 
-        // playback track
+        // playback track, used by DuplicatingThread
         class OutputTrack : public Track {
         public:
 
@@ -1031,6 +1043,7 @@
             AudioBufferProvider::Buffer mOutBuffer;
             bool                        mActive;
             DuplicatingThread* const mSourceThread; // for waitTimeMs() in write()
+            void*                       mBuffers;   // starting address of buffers in plain memory
         };  // end of OutputTrack
 
         PlaybackThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output,
@@ -1089,7 +1102,7 @@
                                     int frameCount,
                                     const sp<IMemory>& sharedBuffer,
                                     int sessionId,
-                                    IAudioFlinger::track_flags_t flags,
+                                    IAudioFlinger::track_flags_t *flags,
                                     pid_t tid,
                                     status_t *status);
 
@@ -1468,6 +1481,8 @@
             static  void        appendDumpHeader(String8& result);
                     void        dump(char* buffer, size_t size);
 
+            virtual bool isOut() const;
+
         private:
             friend class AudioFlinger;  // for mState
 
diff --git a/services/audioflinger/AudioResamplerSinc.cpp b/services/audioflinger/AudioResamplerSinc.cpp
index 5f25760..d68b839 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 <dlfcn.h>
-#include <cutils/properties.h>
 #include <stdlib.h>
+#include <dlfcn.h>
+
+#include <cutils/compiler.h>
+#include <cutils/properties.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 {
 // ----------------------------------------------------------------------------
 
@@ -33,32 +53,272 @@
  * tools/resampler_tools
  * cmd-line: fir -l 7 -s 48000 -c 20478
  */
-const int32_t AudioResamplerSinc::mFirCoefsUp[] = {
-        0x6d374bc7, 0x6d35278a, 0x6d2ebafe, 0x6d24069d, 0x6d150b35, 0x6d01c9e3, 0x6cea4418, 0x6cce7b97, 0x6cae7272, 0x6c8a2b0f, 0x6c61a823, 0x6c34ecb5, 0x6c03fc1c, 0x6bced9ff, 0x6b958a54, 0x6b581163, 0x6b1673c1, 0x6ad0b652, 0x6a86de48, 0x6a38f123, 0x69e6f4b1, 0x6990ef0b, 0x6936e697, 0x68d8e206, 0x6876e855, 0x681100c9, 0x67a732f4, 0x673986ac, 0x66c80413, 0x6652b392, 0x65d99dd5, 0x655ccbd3, 0x64dc46c3, 0x64581823, 0x63d049b4, 0x6344e578, 0x62b5f5b2, 0x622384e8, 0x618d9ddc, 0x60f44b91, 0x60579947, 0x5fb79278, 0x5f1442dc, 0x5e6db665, 0x5dc3f93c, 0x5d1717c4, 0x5c671e96, 0x5bb41a80, 0x5afe1886, 0x5a4525df, 0x59894ff3, 0x58caa45b, 0x580930e1, 0x5745037c, 0x567e2a51, 0x55b4b3af, 0x54e8ae13, 0x541a281e, 0x5349309e, 0x5275d684, 0x51a028e8, 0x50c83704, 0x4fee1037, 0x4f11c3fe, 0x4e3361f7, 0x4d52f9df, 0x4c709b8e, 0x4b8c56f8, 0x4aa63c2c, 0x49be5b50, 0x48d4c4a2, 0x47e98874, 0x46fcb72d, 0x460e6148, 0x451e9750, 0x442d69de, 0x433ae99c, 0x4247273f, 0x41523389, 0x405c1f43, 0x3f64fb40, 0x3e6cd85b, 0x3d73c772, 0x3c79d968, 0x3b7f1f23, 0x3a83a989, 0x3987897f, 0x388acfe9, 0x378d8da8, 0x368fd397, 0x3591b28b, 0x34933b50, 0x33947eab, 0x32958d55, 0x319677fa, 0x30974f3b, 0x2f9823a8, 0x2e9905c1, 0x2d9a05f4, 0x2c9b349e, 0x2b9ca203, 0x2a9e5e57, 0x29a079b2, 0x28a30416, 0x27a60d6a, 0x26a9a57b, 0x25addbf9, 0x24b2c075, 0x23b86263, 0x22bed116, 0x21c61bc0, 0x20ce516f, 0x1fd7810f, 0x1ee1b965, 0x1ded0911, 0x1cf97e8b, 0x1c072823, 0x1b1613ff, 0x1a26501b, 0x1937ea47, 0x184af025, 0x175f6f2b, 0x1675749e, 0x158d0d95, 0x14a646f6, 0x13c12d73, 0x12ddcd8f, 0x11fc3395,
-        0x111c6ba0, 0x103e8192, 0x0f62811a, 0x0e8875ad, 0x0db06a89, 0x0cda6ab5, 0x0c0680fe, 0x0b34b7f5, 0x0a6519f4, 0x0997b116, 0x08cc873c, 0x0803a60a, 0x073d16e7, 0x0678e2fc, 0x05b71332, 0x04f7b037, 0x043ac276, 0x0380521c, 0x02c86715, 0x0213090c, 0x01603f6e, 0x00b01162, 0x000285d0, 0xff57a35e, 0xfeaf706f, 0xfe09f323, 0xfd673159, 0xfcc730aa, 0xfc29f670, 0xfb8f87bd, 0xfaf7e963, 0xfa631fef, 0xf9d12fab, 0xf9421c9d, 0xf8b5ea87, 0xf82c9ce7, 0xf7a636fa, 0xf722bbb5, 0xf6a22dcf, 0xf6248fb6, 0xf5a9e398, 0xf5322b61, 0xf4bd68b6, 0xf44b9cfe, 0xf3dcc959, 0xf370eea9, 0xf3080d8c, 0xf2a2265e, 0xf23f393b, 0xf1df45fd, 0xf1824c3e, 0xf1284b58, 0xf0d14267, 0xf07d3043, 0xf02c138a, 0xefddea9a, 0xef92b393, 0xef4a6c58, 0xef051290, 0xeec2a3a3, 0xee831cc3, 0xee467ae1, 0xee0cbab9, 0xedd5d8ca, 0xeda1d15c, 0xed70a07d, 0xed424205, 0xed16b196, 0xecedea99, 0xecc7e845, 0xeca4a59b, 0xec841d68, 0xec664a48, 0xec4b26a2, 0xec32acb0, 0xec1cd677, 0xec099dcf, 0xebf8fc64, 0xebeaebaf, 0xebdf6500, 0xebd6617b, 0xebcfda19, 0xebcbc7a7, 0xebca22cc, 0xebcae405, 0xebce03aa, 0xebd379eb, 0xebdb3ed5, 0xebe54a4f, 0xebf1941f, 0xec0013e8, 0xec10c12c, 0xec23934f, 0xec388194, 0xec4f8322, 0xec688f02, 0xec839c22, 0xeca0a156, 0xecbf9558, 0xece06ecb, 0xed032439, 0xed27ac16, 0xed4dfcc2, 0xed760c88, 0xed9fd1a2, 0xedcb4237, 0xedf8545b, 0xee26fe17, 0xee573562, 0xee88f026, 0xeebc2444, 0xeef0c78d, 0xef26cfca, 0xef5e32bd, 0xef96e61c, 0xefd0df9a, 0xf00c14e1, 0xf0487b98, 0xf0860962, 0xf0c4b3e0, 0xf10470b0, 0xf1453571, 0xf186f7c0, 0xf1c9ad40, 0xf20d4b92, 0xf251c85d, 0xf297194d, 0xf2dd3411,
-        0xf3240e61, 0xf36b9dfd, 0xf3b3d8ac, 0xf3fcb43e, 0xf4462690, 0xf4902587, 0xf4daa718, 0xf525a143, 0xf5710a17, 0xf5bcd7b1, 0xf609003f, 0xf6557a00, 0xf6a23b44, 0xf6ef3a6e, 0xf73c6df4, 0xf789cc61, 0xf7d74c53, 0xf824e480, 0xf8728bb3, 0xf8c038d0, 0xf90de2d1, 0xf95b80cb, 0xf9a909ea, 0xf9f67577, 0xfa43bad2, 0xfa90d17b, 0xfaddb10c, 0xfb2a513b, 0xfb76a9dd, 0xfbc2b2e4, 0xfc0e6461, 0xfc59b685, 0xfca4a19f, 0xfcef1e20, 0xfd392498, 0xfd82adba, 0xfdcbb25a, 0xfe142b6e, 0xfe5c120f, 0xfea35f79, 0xfeea0d0c, 0xff30144a, 0xff756edc, 0xffba168d, 0xfffe054e, 0x00413536, 0x0083a081, 0x00c54190, 0x010612eb, 0x01460f41, 0x01853165, 0x01c37452, 0x0200d32c, 0x023d493c, 0x0278d1f2, 0x02b368e6, 0x02ed09d7, 0x0325b0ad, 0x035d5977, 0x0394006a, 0x03c9a1e5, 0x03fe3a6f, 0x0431c6b5, 0x0464438c, 0x0495adf2, 0x04c6030d, 0x04f54029, 0x052362ba, 0x0550685d, 0x057c4ed4, 0x05a7140b, 0x05d0b612, 0x05f93324, 0x0620899e, 0x0646b808, 0x066bbd0d, 0x068f9781, 0x06b2465b, 0x06d3c8bb, 0x06f41de3, 0x0713453d, 0x07313e56, 0x074e08e0, 0x0769a4b2, 0x078411c7, 0x079d503b, 0x07b56051, 0x07cc426c, 0x07e1f712, 0x07f67eec, 0x0809dac3, 0x081c0b84, 0x082d1239, 0x083cf010, 0x084ba654, 0x08593671, 0x0865a1f1, 0x0870ea7e, 0x087b11de, 0x088419f6, 0x088c04c8, 0x0892d470, 0x08988b2a, 0x089d2b4a, 0x08a0b740, 0x08a33196, 0x08a49cf0, 0x08a4fc0d, 0x08a451c0, 0x08a2a0f8, 0x089fecbb, 0x089c3824, 0x08978666, 0x0891dac8, 0x088b38a9, 0x0883a378, 0x087b1ebc, 0x0871ae0d, 0x08675516, 0x085c1794, 0x084ff957, 0x0842fe3d, 0x08352a35, 0x0826813e, 0x08170767, 0x0806c0cb, 0x07f5b193, 0x07e3ddf7,
-        0x07d14a38, 0x07bdfaa5, 0x07a9f399, 0x07953976, 0x077fd0ac, 0x0769bdaf, 0x07530501, 0x073bab28, 0x0723b4b4, 0x070b2639, 0x06f20453, 0x06d853a2, 0x06be18cd, 0x06a3587e, 0x06881761, 0x066c5a27, 0x06502583, 0x06337e2a, 0x061668d2, 0x05f8ea30, 0x05db06fc, 0x05bcc3ed, 0x059e25b5, 0x057f310a, 0x055fea9d, 0x0540571a, 0x05207b2f, 0x05005b82, 0x04dffcb6, 0x04bf6369, 0x049e9433, 0x047d93a8, 0x045c6654, 0x043b10bd, 0x04199760, 0x03f7feb4, 0x03d64b27, 0x03b4811d, 0x0392a4f4, 0x0370bafc, 0x034ec77f, 0x032ccebb, 0x030ad4e1, 0x02e8de19, 0x02c6ee7f, 0x02a50a22, 0x02833506, 0x02617321, 0x023fc85c, 0x021e3891, 0x01fcc78f, 0x01db7914, 0x01ba50d2, 0x0199526b, 0x01788170, 0x0157e166, 0x013775bf, 0x011741df, 0x00f7491a, 0x00d78eb3, 0x00b815da, 0x0098e1b3, 0x0079f54c, 0x005b53a4, 0x003cffa9, 0x001efc35, 0x00014c12, 0xffe3f1f7, 0xffc6f08a, 0xffaa4a5d, 0xff8e01f1, 0xff7219b3, 0xff5693fe, 0xff3b731b, 0xff20b93e, 0xff066889, 0xfeec830d, 0xfed30ac5, 0xfeba0199, 0xfea16960, 0xfe8943dc, 0xfe7192bd, 0xfe5a579d, 0xfe439407, 0xfe2d496f, 0xfe177937, 0xfe0224b0, 0xfded4d13, 0xfdd8f38b, 0xfdc5192d, 0xfdb1befc, 0xfd9ee5e7, 0xfd8c8ecc, 0xfd7aba74, 0xfd696998, 0xfd589cdc, 0xfd4854d3, 0xfd3891fd, 0xfd2954c8, 0xfd1a9d91, 0xfd0c6ca2, 0xfcfec233, 0xfcf19e6b, 0xfce50161, 0xfcd8eb17, 0xfccd5b82, 0xfcc25285, 0xfcb7cff0, 0xfcadd386, 0xfca45cf7, 0xfc9b6be5, 0xfc92ffe1, 0xfc8b186d, 0xfc83b4fc, 0xfc7cd4f0, 0xfc76779e, 0xfc709c4d, 0xfc6b4233, 0xfc66687a, 0xfc620e3d, 0xfc5e328c, 0xfc5ad465, 0xfc57f2be, 0xfc558c7c, 0xfc53a07b, 0xfc522d88, 0xfc513266, 0xfc50adcc,
-        0xfc509e64, 0xfc5102d0, 0xfc51d9a6, 0xfc53216f, 0xfc54d8ae, 0xfc56fdda, 0xfc598f60, 0xfc5c8ba5, 0xfc5ff105, 0xfc63bdd3, 0xfc67f05a, 0xfc6c86dd, 0xfc717f97, 0xfc76d8bc, 0xfc7c9079, 0xfc82a4f4, 0xfc89144d, 0xfc8fdc9f, 0xfc96fbfc, 0xfc9e7074, 0xfca63810, 0xfcae50d6, 0xfcb6b8c4, 0xfcbf6dd8, 0xfcc86e09, 0xfcd1b74c, 0xfcdb4793, 0xfce51ccb, 0xfcef34e1, 0xfcf98dbe, 0xfd04254a, 0xfd0ef969, 0xfd1a0801, 0xfd254ef4, 0xfd30cc24, 0xfd3c7d73, 0xfd4860c2, 0xfd5473f3, 0xfd60b4e7, 0xfd6d2180, 0xfd79b7a1, 0xfd86752e, 0xfd93580d, 0xfda05e23, 0xfdad855b, 0xfdbacb9e, 0xfdc82edb, 0xfdd5ad01, 0xfde34403, 0xfdf0f1d6, 0xfdfeb475, 0xfe0c89db, 0xfe1a7009, 0xfe286505, 0xfe3666d5, 0xfe447389, 0xfe528931, 0xfe60a5e5, 0xfe6ec7c0, 0xfe7cece2, 0xfe8b1373, 0xfe99399f, 0xfea75d97, 0xfeb57d92, 0xfec397cf, 0xfed1aa92, 0xfedfb425, 0xfeedb2da, 0xfefba508, 0xff09890f, 0xff175d53, 0xff252042, 0xff32d04f, 0xff406bf8, 0xff4df1be, 0xff5b602c, 0xff68b5d5, 0xff75f153, 0xff831148, 0xff90145e, 0xff9cf947, 0xffa9bebe, 0xffb66386, 0xffc2e669, 0xffcf463a, 0xffdb81d6, 0xffe79820, 0xfff38806, 0xffff507b, 0x000af07f, 0x00166718, 0x0021b355, 0x002cd44d, 0x0037c922, 0x004290fc, 0x004d2b0e, 0x00579691, 0x0061d2ca, 0x006bdf05, 0x0075ba95, 0x007f64da, 0x0088dd38, 0x0092231e, 0x009b3605, 0x00a4156b, 0x00acc0da, 0x00b537e1, 0x00bd7a1c, 0x00c5872a, 0x00cd5eb7, 0x00d50075, 0x00dc6c1e, 0x00e3a175, 0x00eaa045, 0x00f16861, 0x00f7f9a3, 0x00fe53ef, 0x0104772e, 0x010a6353, 0x01101858, 0x0115963d, 0x011add0b, 0x011fecd3, 0x0124c5ab, 0x012967b1, 0x012dd30a, 0x013207e4, 0x01360670,
-        0x0139cee9, 0x013d618d, 0x0140bea5, 0x0143e67c, 0x0146d965, 0x014997bb, 0x014c21db, 0x014e782a, 0x01509b14, 0x01528b08, 0x0154487b, 0x0155d3e8, 0x01572dcf, 0x015856b6, 0x01594f25, 0x015a17ab, 0x015ab0db, 0x015b1b4e, 0x015b579e, 0x015b666c, 0x015b485b, 0x015afe14, 0x015a8843, 0x0159e796, 0x01591cc0, 0x01582878, 0x01570b77, 0x0155c678, 0x01545a3c, 0x0152c783, 0x01510f13, 0x014f31b2, 0x014d3029, 0x014b0b45, 0x0148c3d2, 0x01465a9f, 0x0143d07f, 0x01412643, 0x013e5cc0, 0x013b74ca, 0x01386f3a, 0x01354ce7, 0x01320ea9, 0x012eb55a, 0x012b41d3, 0x0127b4f1, 0x01240f8e, 0x01205285, 0x011c7eb2, 0x011894f0, 0x0114961b, 0x0110830f, 0x010c5ca6, 0x010823ba, 0x0103d927, 0x00ff7dc4, 0x00fb126b, 0x00f697f3, 0x00f20f32, 0x00ed78ff, 0x00e8d62d, 0x00e4278f, 0x00df6df7, 0x00daaa34, 0x00d5dd16, 0x00d10769, 0x00cc29f7, 0x00c7458a, 0x00c25ae8, 0x00bd6ad7, 0x00b87619, 0x00b37d70, 0x00ae8198, 0x00a9834e, 0x00a4834c, 0x009f8249, 0x009a80f8, 0x0095800c, 0x00908034, 0x008b821b, 0x0086866b, 0x00818dcb, 0x007c98de, 0x0077a845, 0x0072bc9d, 0x006dd680, 0x0068f687, 0x00641d44, 0x005f4b4a, 0x005a8125, 0x0055bf60, 0x00510682, 0x004c570f, 0x0047b186, 0x00431666, 0x003e8628, 0x003a0141, 0x00358824, 0x00311b41, 0x002cbb03, 0x002867d2, 0x00242213, 0x001fea27, 0x001bc06b, 0x0017a53b, 0x001398ec, 0x000f9bd2, 0x000bae3c, 0x0007d075, 0x000402c8, 0x00004579, 0xfffc98c9, 0xfff8fcf7, 0xfff5723d, 0xfff1f8d2, 0xffee90eb, 0xffeb3ab8, 0xffe7f666, 0xffe4c41e, 0xffe1a408, 0xffde9646, 0xffdb9af8, 0xffd8b23b, 0xffd5dc28, 0xffd318d6, 0xffd06858, 0xffcdcabe, 0xffcb4014,
-        0xffc8c866, 0xffc663b9, 0xffc41212, 0xffc1d373, 0xffbfa7d9, 0xffbd8f40, 0xffbb89a1, 0xffb996f3, 0xffb7b728, 0xffb5ea31, 0xffb42ffc, 0xffb28876, 0xffb0f388, 0xffaf7118, 0xffae010b, 0xffaca344, 0xffab57a1, 0xffaa1e02, 0xffa8f641, 0xffa7e039, 0xffa6dbc0, 0xffa5e8ad, 0xffa506d2, 0xffa43603, 0xffa3760e, 0xffa2c6c2, 0xffa227ec, 0xffa19957, 0xffa11acb, 0xffa0ac11, 0xffa04cf0, 0xff9ffd2c, 0xff9fbc89, 0xff9f8ac9, 0xff9f67ae, 0xff9f52f7, 0xff9f4c65, 0xff9f53b4, 0xff9f68a1, 0xff9f8ae9, 0xff9fba47, 0xff9ff674, 0xffa03f2b, 0xffa09425, 0xffa0f519, 0xffa161bf, 0xffa1d9cf, 0xffa25cfe, 0xffa2eb04, 0xffa38395, 0xffa42668, 0xffa4d332, 0xffa589a6, 0xffa6497c, 0xffa71266, 0xffa7e41a, 0xffa8be4c, 0xffa9a0b1, 0xffaa8afe, 0xffab7ce7, 0xffac7621, 0xffad7662, 0xffae7d5f, 0xffaf8acd, 0xffb09e63, 0xffb1b7d8, 0xffb2d6e1, 0xffb3fb37, 0xffb52490, 0xffb652a7, 0xffb78533, 0xffb8bbed, 0xffb9f691, 0xffbb34d8, 0xffbc767f, 0xffbdbb42, 0xffbf02dd, 0xffc04d0f, 0xffc19996, 0xffc2e832, 0xffc438a3, 0xffc58aaa, 0xffc6de09, 0xffc83285, 0xffc987e0, 0xffcadde1, 0xffcc344c, 0xffcd8aeb, 0xffcee183, 0xffd037e0, 0xffd18dcc, 0xffd2e311, 0xffd4377d, 0xffd58ade, 0xffd6dd02, 0xffd82dba, 0xffd97cd6, 0xffdaca2a, 0xffdc1588, 0xffdd5ec6, 0xffdea5bb, 0xffdfea3c, 0xffe12c22, 0xffe26b48, 0xffe3a788, 0xffe4e0bf, 0xffe616c8, 0xffe74984, 0xffe878d3, 0xffe9a494, 0xffeaccaa, 0xffebf0fa, 0xffed1166, 0xffee2dd7, 0xffef4632, 0xfff05a60, 0xfff16a4a, 0xfff275db, 0xfff37d00, 0xfff47fa5, 0xfff57db8, 0xfff67729, 0xfff76be9, 0xfff85be8, 0xfff9471b, 0xfffa2d74, 0xfffb0ee9, 0xfffbeb70,
-        0xfffcc300, 0xfffd9592, 0xfffe631e, 0xffff2b9f, 0xffffef10, 0x0000ad6e, 0x000166b6, 0x00021ae5, 0x0002c9fd, 0x000373fb, 0x000418e2, 0x0004b8b3, 0x00055371, 0x0005e921, 0x000679c5, 0x00070564, 0x00078c04, 0x00080dab, 0x00088a62, 0x00090230, 0x0009751e, 0x0009e337, 0x000a4c85, 0x000ab112, 0x000b10ec, 0x000b6c1d, 0x000bc2b3, 0x000c14bb, 0x000c6244, 0x000cab5c, 0x000cf012, 0x000d3075, 0x000d6c97, 0x000da486, 0x000dd854, 0x000e0812, 0x000e33d3, 0x000e5ba7, 0x000e7fa1, 0x000e9fd5, 0x000ebc54, 0x000ed533, 0x000eea84, 0x000efc5c, 0x000f0ace, 0x000f15ef, 0x000f1dd2, 0x000f228d, 0x000f2434, 0x000f22dc, 0x000f1e99, 0x000f1781, 0x000f0da8, 0x000f0125, 0x000ef20b, 0x000ee070, 0x000ecc69, 0x000eb60b, 0x000e9d6b, 0x000e829e, 0x000e65ba, 0x000e46d3, 0x000e25fd, 0x000e034f, 0x000ddedb, 0x000db8b7, 0x000d90f6, 0x000d67ae, 0x000d3cf1, 0x000d10d5, 0x000ce36b, 0x000cb4c8, 0x000c84ff, 0x000c5422, 0x000c2245, 0x000bef79, 0x000bbbd2, 0x000b8760, 0x000b5235, 0x000b1c64, 0x000ae5fc, 0x000aaf0f, 0x000a77ac, 0x000a3fe5, 0x000a07c9, 0x0009cf67, 0x000996ce, 0x00095e0e, 0x00092535, 0x0008ec50, 0x0008b36e, 0x00087a9c, 0x000841e8, 0x0008095d, 0x0007d108, 0x000798f5, 0x00076130, 0x000729c4, 0x0006f2bb, 0x0006bc21, 0x000685ff, 0x0006505f, 0x00061b4b, 0x0005e6cb, 0x0005b2e8, 0x00057faa, 0x00054d1a, 0x00051b3e, 0x0004ea1d, 0x0004b9c0, 0x00048a2b, 0x00045b65, 0x00042d74, 0x0004005e, 0x0003d426, 0x0003a8d2, 0x00037e65, 0x000354e5, 0x00032c54, 0x000304b7, 0x0002de0e, 0x0002b85f, 0x000293aa, 0x00026ff2, 0x00024d39, 0x00022b7f, 0x00020ac7, 0x0001eb10,
-        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
  * cmd-line: fir -l 7 -s 48000 -c 17189
  */
-const int32_t AudioResamplerSinc::mFirCoefsDown[] = {
-        0x5bacb6f4, 0x5bab6c81, 0x5ba78d37, 0x5ba1194f, 0x5b981122, 0x5b8c7530, 0x5b7e461a, 0x5b6d84a8, 0x5b5a31c6, 0x5b444e81, 0x5b2bdc0e, 0x5b10dbc2, 0x5af34f18, 0x5ad337af, 0x5ab09748, 0x5a8b6fc7, 0x5a63c336, 0x5a3993c0, 0x5a0ce3b2, 0x59ddb57f, 0x59ac0bba, 0x5977e919, 0x59415075, 0x590844c9, 0x58ccc930, 0x588ee0ea, 0x584e8f56, 0x580bd7f4, 0x57c6be67, 0x577f4670, 0x573573f2, 0x56e94af1, 0x569acf90, 0x564a0610, 0x55f6f2d3, 0x55a19a5c, 0x554a0148, 0x54f02c56, 0x54942061, 0x5435e263, 0x53d57774, 0x5372e4c6, 0x530e2fac, 0x52a75d90, 0x523e73fd, 0x51d37897, 0x5166711c, 0x50f76368, 0x5086556f, 0x50134d3e, 0x4f9e50ff, 0x4f2766f2, 0x4eae9571, 0x4e33e2ee, 0x4db755f3, 0x4d38f520, 0x4cb8c72e, 0x4c36d2eb, 0x4bb31f3c, 0x4b2db31a, 0x4aa69594, 0x4a1dcdce, 0x499362ff, 0x49075c72, 0x4879c185, 0x47ea99a9, 0x4759ec60, 0x46c7c140, 0x46341fed, 0x459f101d, 0x45089996, 0x4470c42d, 0x43d797c7, 0x433d1c56, 0x42a159dc, 0x42045865, 0x4166200e, 0x40c6b8fd, 0x40262b65, 0x3f847f83, 0x3ee1bda2, 0x3e3dee13, 0x3d991932, 0x3cf34766, 0x3c4c811c, 0x3ba4cec9, 0x3afc38eb, 0x3a52c805, 0x39a884a1, 0x38fd774e, 0x3851a8a2, 0x37a52135, 0x36f7e9a4, 0x364a0a90, 0x359b8c9d, 0x34ec786f, 0x343cd6af, 0x338cb004, 0x32dc0d17, 0x322af693, 0x3179751f, 0x30c79163, 0x30155404, 0x2f62c5a7, 0x2eafeeed, 0x2dfcd873, 0x2d498ad3, 0x2c960ea3, 0x2be26c73, 0x2b2eaccf, 0x2a7ad83c, 0x29c6f738, 0x2913123c, 0x285f31b7, 0x27ab5e12, 0x26f79fab, 0x2643feda, 0x259083eb, 0x24dd3721, 0x242a20b3, 0x237748cf, 0x22c4b795, 0x2212751a, 0x21608968, 0x20aefc79, 0x1ffdd63b, 0x1f4d1e8e, 0x1e9cdd43,
-        0x1ded1a1d, 0x1d3ddccd, 0x1c8f2cf9, 0x1be11231, 0x1b3393f8, 0x1a86b9bf, 0x19da8ae5, 0x192f0eb7, 0x18844c70, 0x17da4b37, 0x17311222, 0x1688a832, 0x15e11453, 0x153a5d5e, 0x14948a16, 0x13efa12c, 0x134ba937, 0x12a8a8bb, 0x1206a625, 0x1165a7cc, 0x10c5b3ef, 0x1026d0b8, 0x0f890437, 0x0eec5465, 0x0e50c723, 0x0db6623b, 0x0d1d2b5d, 0x0c85281f, 0x0bee5dff, 0x0b58d262, 0x0ac48a92, 0x0a318bc1, 0x099fdb04, 0x090f7d57, 0x0880779d, 0x07f2ce9b, 0x076686fc, 0x06dba551, 0x06522e0f, 0x05ca258f, 0x0543900d, 0x04be71ab, 0x043ace6e, 0x03b8aa40, 0x033808eb, 0x02b8ee22, 0x023b5d76, 0x01bf5a5e, 0x0144e834, 0x00cc0a36, 0x0054c382, 0xffdf171b, 0xff6b07e7, 0xfef898ae, 0xfe87cc1b, 0xfe18a4bc, 0xfdab2501, 0xfd3f4f3d, 0xfcd525a5, 0xfc6caa53, 0xfc05df40, 0xfba0c64b, 0xfb3d6133, 0xfadbb19a, 0xfa7bb908, 0xfa1d78e3, 0xf9c0f276, 0xf96626f0, 0xf90d1761, 0xf8b5c4be, 0xf8602fdc, 0xf80c5977, 0xf7ba422b, 0xf769ea78, 0xf71b52c4, 0xf6ce7b57, 0xf683645a, 0xf63a0ddf, 0xf5f277d9, 0xf5aca21f, 0xf5688c6d, 0xf5263665, 0xf4e59f8a, 0xf4a6c748, 0xf469aced, 0xf42e4faf, 0xf3f4aea6, 0xf3bcc8d3, 0xf3869d1a, 0xf3522a49, 0xf31f6f0f, 0xf2ee6a07, 0xf2bf19ae, 0xf2917c6d, 0xf265908f, 0xf23b544b, 0xf212c5be, 0xf1ebe2ec, 0xf1c6a9c3, 0xf1a3181a, 0xf1812bb0, 0xf160e22d, 0xf1423924, 0xf1252e0f, 0xf109be56, 0xf0efe748, 0xf0d7a622, 0xf0c0f808, 0xf0abda0e, 0xf0984931, 0xf086425a, 0xf075c260, 0xf066c606, 0xf05949fb, 0xf04d4ade, 0xf042c539, 0xf039b587, 0xf032182f, 0xf02be98a, 0xf02725dc, 0xf023c95d, 0xf021d031, 0xf0213671, 0xf021f823, 0xf0241140, 0xf0277db1, 0xf02c3953, 0xf0323ff5,
-        0xf0398d56, 0xf0421d2c, 0xf04beb1d, 0xf056f2c7, 0xf0632fb7, 0xf0709d74, 0xf07f3776, 0xf08ef92d, 0xf09fddfe, 0xf0b1e143, 0xf0c4fe50, 0xf0d9306d, 0xf0ee72db, 0xf104c0d2, 0xf11c1583, 0xf1346c17, 0xf14dbfb1, 0xf1680b6e, 0xf1834a63, 0xf19f77a0, 0xf1bc8e31, 0xf1da891b, 0xf1f96360, 0xf21917ff, 0xf239a1ef, 0xf25afc29, 0xf27d219f, 0xf2a00d43, 0xf2c3ba04, 0xf2e822ce, 0xf30d428e, 0xf333142f, 0xf359929a, 0xf380b8ba, 0xf3a88179, 0xf3d0e7c2, 0xf3f9e680, 0xf42378a0, 0xf44d9912, 0xf47842c5, 0xf4a370ad, 0xf4cf1dbf, 0xf4fb44f4, 0xf527e149, 0xf554edbd, 0xf5826555, 0xf5b0431a, 0xf5de8218, 0xf60d1d63, 0xf63c1012, 0xf66b5544, 0xf69ae81d, 0xf6cac3c7, 0xf6fae373, 0xf72b425b, 0xf75bdbbd, 0xf78caae0, 0xf7bdab16, 0xf7eed7b4, 0xf8202c1c, 0xf851a3b6, 0xf88339f5, 0xf8b4ea55, 0xf8e6b059, 0xf9188793, 0xf94a6b9b, 0xf97c5815, 0xf9ae48af, 0xf9e03924, 0xfa122537, 0xfa4408ba, 0xfa75df87, 0xfaa7a586, 0xfad956ab, 0xfb0aeef6, 0xfb3c6a73, 0xfb6dc53c, 0xfb9efb77, 0xfbd00956, 0xfc00eb1b, 0xfc319d13, 0xfc621b9a, 0xfc926319, 0xfcc27008, 0xfcf23eec, 0xfd21cc59, 0xfd5114f0, 0xfd801564, 0xfdaeca73, 0xfddd30eb, 0xfe0b45aa, 0xfe39059b, 0xfe666dbc, 0xfe937b15, 0xfec02ac2, 0xfeec79ec, 0xff1865cd, 0xff43ebac, 0xff6f08e4, 0xff99badb, 0xffc3ff0c, 0xffedd2fd, 0x00173447, 0x00402092, 0x00689598, 0x0090911f, 0x00b81102, 0x00df1328, 0x0105958c, 0x012b9635, 0x0151133e, 0x01760ad1, 0x019a7b27, 0x01be628c, 0x01e1bf58, 0x02048ff8, 0x0226d2e6, 0x024886ad, 0x0269a9e9, 0x028a3b44, 0x02aa397b, 0x02c9a359, 0x02e877b9, 0x0306b586, 0x03245bbc, 0x03416966, 0x035ddd9e, 0x0379b790,
-        0x0394f674, 0x03af9995, 0x03c9a04a, 0x03e309fe, 0x03fbd625, 0x04140449, 0x042b93fd, 0x044284e6, 0x0458d6b7, 0x046e8933, 0x04839c29, 0x04980f79, 0x04abe310, 0x04bf16e9, 0x04d1ab0d, 0x04e39f93, 0x04f4f4a2, 0x0505aa6a, 0x0515c12d, 0x05253938, 0x053412e4, 0x05424e9b, 0x054feccf, 0x055cee03, 0x056952c3, 0x05751baa, 0x0580495c, 0x058adc8d, 0x0594d5fa, 0x059e366c, 0x05a6feb9, 0x05af2fbf, 0x05b6ca6b, 0x05bdcfb2, 0x05c44095, 0x05ca1e1f, 0x05cf6965, 0x05d42387, 0x05d84daf, 0x05dbe90f, 0x05def6e4, 0x05e17873, 0x05e36f0d, 0x05e4dc08, 0x05e5c0c6, 0x05e61eae, 0x05e5f733, 0x05e54bcd, 0x05e41dfe, 0x05e26f4e, 0x05e0414d, 0x05dd9593, 0x05da6dbe, 0x05d6cb72, 0x05d2b05c, 0x05ce1e2d, 0x05c9169d, 0x05c39b6a, 0x05bdae57, 0x05b7512e, 0x05b085bc, 0x05a94dd5, 0x05a1ab52, 0x0599a00e, 0x05912dea, 0x058856cd, 0x057f1c9e, 0x0575814c, 0x056b86c6, 0x05612f00, 0x05567bf1, 0x054b6f92, 0x05400be1, 0x053452dc, 0x05284685, 0x051be8dd, 0x050f3bec, 0x050241b6, 0x04f4fc46, 0x04e76da3, 0x04d997d8, 0x04cb7cf2, 0x04bd1efb, 0x04ae8000, 0x049fa20f, 0x04908733, 0x0481317a, 0x0471a2ef, 0x0461dda0, 0x0451e396, 0x0441b6dd, 0x0431597d, 0x0420cd80, 0x041014eb, 0x03ff31c3, 0x03ee260d, 0x03dcf3ca, 0x03cb9cf9, 0x03ba2398, 0x03a889a1, 0x0396d10c, 0x0384fbd1, 0x03730be0, 0x0361032a, 0x034ee39b, 0x033caf1d, 0x032a6796, 0x03180ee7, 0x0305a6f0, 0x02f3318a, 0x02e0b08d, 0x02ce25ca, 0x02bb9310, 0x02a8fa2a, 0x02965cdb, 0x0283bce6, 0x02711c05, 0x025e7bf0, 0x024bde5a, 0x023944ee, 0x0226b156, 0x02142533, 0x0201a223, 0x01ef29be, 0x01dcbd96, 0x01ca5f37, 0x01b81028, 0x01a5d1ea,
-        0x0193a5f9, 0x01818dc9, 0x016f8aca, 0x015d9e64, 0x014bc9fa, 0x013a0ee9, 0x01286e86, 0x0116ea22, 0x01058306, 0x00f43a74, 0x00e311a9, 0x00d209db, 0x00c12439, 0x00b061eb, 0x009fc413, 0x008f4bcb, 0x007efa29, 0x006ed038, 0x005ecf01, 0x004ef782, 0x003f4ab4, 0x002fc98a, 0x002074ed, 0x00114dc3, 0x000254e8, 0xfff38b32, 0xffe4f171, 0xffd6886d, 0xffc850e6, 0xffba4b98, 0xffac7936, 0xff9eda6d, 0xff916fe1, 0xff843a32, 0xff7739f7, 0xff6a6fc1, 0xff5ddc1a, 0xff517f86, 0xff455a80, 0xff396d7f, 0xff2db8f2, 0xff223d40, 0xff16faca, 0xff0bf1ed, 0xff0122fc, 0xfef68e45, 0xfeec340f, 0xfee2149b, 0xfed83023, 0xfece86db, 0xfec518f1, 0xfebbe68c, 0xfeb2efcd, 0xfeaa34d0, 0xfea1b5a9, 0xfe997268, 0xfe916b15, 0xfe899fb2, 0xfe82103f, 0xfe7abcb1, 0xfe73a4fb, 0xfe6cc909, 0xfe6628c1, 0xfe5fc405, 0xfe599aaf, 0xfe53ac97, 0xfe4df98e, 0xfe48815e, 0xfe4343d0, 0xfe3e40a6, 0xfe39779a, 0xfe34e867, 0xfe3092bf, 0xfe2c7650, 0xfe2892c5, 0xfe24e7c3, 0xfe2174ec, 0xfe1e39da, 0xfe1b3628, 0xfe18696a, 0xfe15d32f, 0xfe137304, 0xfe114872, 0xfe0f52fc, 0xfe0d9224, 0xfe0c0567, 0xfe0aac3f, 0xfe098622, 0xfe089283, 0xfe07d0d3, 0xfe07407d, 0xfe06e0eb, 0xfe06b184, 0xfe06b1ac, 0xfe06e0c4, 0xfe073e2a, 0xfe07c93a, 0xfe08814e, 0xfe0965bc, 0xfe0a75da, 0xfe0bb0f9, 0xfe0d166b, 0xfe0ea57e, 0xfe105d7e, 0xfe123db6, 0xfe144570, 0xfe1673f2, 0xfe18c884, 0xfe1b4268, 0xfe1de0e2, 0xfe20a335, 0xfe2388a1, 0xfe269065, 0xfe29b9c1, 0xfe2d03f2, 0xfe306e35, 0xfe33f7c7, 0xfe379fe3, 0xfe3b65c4, 0xfe3f48a5, 0xfe4347c0, 0xfe476250, 0xfe4b978e, 0xfe4fe6b3, 0xfe544efb, 0xfe58cf9d, 0xfe5d67d4, 0xfe6216db,
-        0xfe66dbeb, 0xfe6bb63e, 0xfe70a511, 0xfe75a79f, 0xfe7abd23, 0xfe7fe4db, 0xfe851e05, 0xfe8a67dd, 0xfe8fc1a5, 0xfe952a9b, 0xfe9aa201, 0xfea02719, 0xfea5b926, 0xfeab576d, 0xfeb10134, 0xfeb6b5c0, 0xfebc745c, 0xfec23c50, 0xfec80ce8, 0xfecde571, 0xfed3c538, 0xfed9ab8f, 0xfedf97c6, 0xfee58932, 0xfeeb7f27, 0xfef178fc, 0xfef7760c, 0xfefd75af, 0xff037744, 0xff097a29, 0xff0f7dbf, 0xff15816a, 0xff1b848e, 0xff218692, 0xff2786e1, 0xff2d84e5, 0xff33800e, 0xff3977cb, 0xff3f6b8f, 0xff455acf, 0xff4b4503, 0xff5129a3, 0xff57082e, 0xff5ce021, 0xff62b0fd, 0xff687a47, 0xff6e3b84, 0xff73f43d, 0xff79a3fe, 0xff7f4a54, 0xff84e6d0, 0xff8a7905, 0xff900089, 0xff957cf4, 0xff9aede0, 0xffa052ec, 0xffa5abb8, 0xffaaf7e6, 0xffb0371c, 0xffb56902, 0xffba8d44, 0xffbfa38d, 0xffc4ab8f, 0xffc9a4fc, 0xffce8f8a, 0xffd36af1, 0xffd836eb, 0xffdcf336, 0xffe19f91, 0xffe63bc0, 0xffeac787, 0xffef42af, 0xfff3ad01, 0xfff8064b, 0xfffc4e5c, 0x00008507, 0x0004aa1f, 0x0008bd7c, 0x000cbef7, 0x0010ae6e, 0x00148bbd, 0x001856c7, 0x001c0f6e, 0x001fb599, 0x0023492f, 0x0026ca1c, 0x002a384c, 0x002d93ae, 0x0030dc34, 0x003411d2, 0x0037347d, 0x003a442e, 0x003d40e0, 0x00402a8e, 0x00430137, 0x0045c4dd, 0x00487582, 0x004b132b, 0x004d9dde, 0x005015a5, 0x00527a8a, 0x0054cc9a, 0x00570be4, 0x00593877, 0x005b5267, 0x005d59c6, 0x005f4eac, 0x0061312e, 0x00630167, 0x0064bf71, 0x00666b68, 0x0068056b, 0x00698d98, 0x006b0411, 0x006c68f8, 0x006dbc71, 0x006efea0, 0x00702fae, 0x00714fc0, 0x00725f02, 0x00735d9c, 0x00744bba, 0x0075298a, 0x0075f739, 0x0076b4f5, 0x007762f0, 0x0078015a, 0x00789065,
-        0x00791043, 0x0079812a, 0x0079e34d, 0x007a36e2, 0x007a7c20, 0x007ab33d, 0x007adc72, 0x007af7f6, 0x007b0603, 0x007b06d4, 0x007afaa1, 0x007ae1a7, 0x007abc20, 0x007a8a49, 0x007a4c5d, 0x007a029a, 0x0079ad3d, 0x00794c82, 0x0078e0a9, 0x007869ee, 0x0077e891, 0x00775ccf, 0x0076c6e8, 0x00762719, 0x00757da3, 0x0074cac4, 0x00740ebb, 0x007349c7, 0x00727c27, 0x0071a61b, 0x0070c7e1, 0x006fe1b8, 0x006ef3df, 0x006dfe94, 0x006d0217, 0x006bfea4, 0x006af47b, 0x0069e3d9, 0x0068ccfa, 0x0067b01e, 0x00668d80, 0x0065655d, 0x006437f1, 0x00630577, 0x0061ce2c, 0x00609249, 0x005f520a, 0x005e0da8, 0x005cc55c, 0x005b7961, 0x005a29ed, 0x0058d738, 0x0057817b, 0x005628ec, 0x0054cdc0, 0x0053702d, 0x00521068, 0x0050aea5, 0x004f4b17, 0x004de5f1, 0x004c7f66, 0x004b17a6, 0x0049aee3, 0x0048454b, 0x0046db0f, 0x0045705c, 0x00440561, 0x00429a4a, 0x00412f43, 0x003fc478, 0x003e5a12, 0x003cf03d, 0x003b871f, 0x003a1ee3, 0x0038b7ae, 0x003751a7, 0x0035ecf4, 0x003489b9, 0x0033281a, 0x0031c83a, 0x00306a3b, 0x002f0e3f, 0x002db466, 0x002c5cd0, 0x002b079a, 0x0029b4e4, 0x002864c9, 0x00271766, 0x0025ccd7, 0x00248535, 0x0023409a, 0x0021ff1f, 0x0020c0dc, 0x001f85e6, 0x001e4e56, 0x001d1a3f, 0x001be9b7, 0x001abcd0, 0x0019939d, 0x00186e31, 0x00174c9c, 0x00162eef, 0x00151538, 0x0013ff88, 0x0012edea, 0x0011e06d, 0x0010d71d, 0x000fd205, 0x000ed130, 0x000dd4a7, 0x000cdc74, 0x000be89f, 0x000af931, 0x000a0e2f, 0x000927a0, 0x00084589, 0x000767f0, 0x00068ed8, 0x0005ba46, 0x0004ea3a, 0x00041eb9, 0x000357c2, 0x00029558, 0x0001d779, 0x00011e26, 0x0000695e, 0xffffb91f, 0xffff0d66,
-        0xfffe6631, 0xfffdc37d, 0xfffd2545, 0xfffc8b86, 0xfffbf639, 0xfffb655b, 0xfffad8e4, 0xfffa50ce, 0xfff9cd12, 0xfff94da9, 0xfff8d28c, 0xfff85bb1, 0xfff7e910, 0xfff77a9f, 0xfff71057, 0xfff6aa2b, 0xfff64812, 0xfff5ea02, 0xfff58ff0, 0xfff539cf, 0xfff4e794, 0xfff49934, 0xfff44ea3, 0xfff407d2, 0xfff3c4b7, 0xfff38542, 0xfff34968, 0xfff3111b, 0xfff2dc4c, 0xfff2aaef, 0xfff27cf3, 0xfff2524c, 0xfff22aea, 0xfff206bf, 0xfff1e5bb, 0xfff1c7d0, 0xfff1acef, 0xfff19508, 0xfff1800b, 0xfff16de9, 0xfff15e93, 0xfff151f9, 0xfff1480b, 0xfff140b9, 0xfff13bf3, 0xfff139aa, 0xfff139cd, 0xfff13c4c, 0xfff14119, 0xfff14821, 0xfff15156, 0xfff15ca8, 0xfff16a07, 0xfff17962, 0xfff18aab, 0xfff19dd1, 0xfff1b2c5, 0xfff1c976, 0xfff1e1d6, 0xfff1fbd5, 0xfff21764, 0xfff23473, 0xfff252f3, 0xfff272d6, 0xfff2940b, 0xfff2b686, 0xfff2da36, 0xfff2ff0d, 0xfff324fd, 0xfff34bf9, 0xfff373f0, 0xfff39cd7, 0xfff3c69f, 0xfff3f13a, 0xfff41c9c, 0xfff448b7, 0xfff4757e, 0xfff4a2e5, 0xfff4d0de, 0xfff4ff5d, 0xfff52e57, 0xfff55dbf, 0xfff58d89, 0xfff5bdaa, 0xfff5ee17, 0xfff61ec5, 0xfff64fa8, 0xfff680b5, 0xfff6b1e4, 0xfff6e329, 0xfff7147a, 0xfff745cd, 0xfff7771a, 0xfff7a857, 0xfff7d97a, 0xfff80a7c, 0xfff83b52, 0xfff86bf6, 0xfff89c60, 0xfff8cc86, 0xfff8fc62, 0xfff92bec, 0xfff95b1e, 0xfff989ef, 0xfff9b85b, 0xfff9e65a, 0xfffa13e5, 0xfffa40f8, 0xfffa6d8d, 0xfffa999d, 0xfffac525, 0xfffaf01e, 0xfffb1a84, 0xfffb4453, 0xfffb6d86, 0xfffb961a, 0xfffbbe09, 0xfffbe552, 0xfffc0bef, 0xfffc31df, 0xfffc571e, 0xfffc7ba9, 0xfffc9f7e, 0xfffcc29a, 0xfffce4fc, 0xfffd06a1, 0xfffd2787, 0xfffd47ae,
-        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
@@ -93,12 +353,16 @@
         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);
@@ -108,15 +372,14 @@
     }
 
     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
 }
@@ -126,7 +389,7 @@
 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"
@@ -149,7 +412,7 @@
 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)
@@ -164,7 +427,7 @@
 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"
@@ -189,7 +452,7 @@
 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:
@@ -207,44 +470,48 @@
      *
      */
 
+    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;
     }
 
@@ -257,7 +524,6 @@
         resample<2>(out, outFrameCount, provider);
         break;
     }
-
 }
 
 
@@ -265,7 +531,8 @@
 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;
@@ -300,43 +567,31 @@
                 }
             }
         }
-        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) {
+            const size_t phaseIndex = phaseFraction >> kNumPhaseBits;
+            for (size_t i=0 ; i<phaseIndex ; i++) {
                 inputIndex++;
-                if (inputIndex >= frameCount)
-                    break;  // need a new buffer
-                read<CHANNELS>(impulse, phaseFraction, in, inputIndex);
-            } else if (phaseIndex == 2) {    // maximum value
-                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;
@@ -362,66 +617,215 @@
         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;
-    }
+    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;
 
-    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 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       {d0}, %[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       {d0}, %[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 48bc747..09c6866 100644
--- a/services/audioflinger/AudioResamplerSinc.h
+++ b/services/audioflinger/AudioResamplerSinc.h
@@ -44,18 +44,21 @@
 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 @@
     int16_t *mState;
     int16_t *mImpulse;
     int16_t *mRingFull;
+    int32_t mVolumeSIMD[2];
 
     const int32_t * mFirCoefs;
     static const int32_t mFirCoefsDown[];
@@ -74,14 +78,11 @@
     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/StateQueue.h b/services/audioflinger/StateQueue.h
index c9b5111..e33b3c6 100644
--- a/services/audioflinger/StateQueue.h
+++ b/services/audioflinger/StateQueue.h
@@ -174,7 +174,7 @@
 #endif
 
 private:
-    static const unsigned kN = 4;       // values != 4 are not supported by this code
+    static const unsigned kN = 4;       // values < 4 are not supported by this code
     T                 mStates[kN];      // written by mutator, read by observer
 
     // "volatile" is meaningless with SMP, but here it indicates that we're using atomic ops
diff --git a/services/audioflinger/audio-resampler/filter_coefficients.h b/services/audioflinger/audio-resampler/filter_coefficients.h
index bd98136..bf70c63 100644
--- a/services/audioflinger/audio-resampler/filter_coefficients.h
+++ b/services/audioflinger/audio-resampler/filter_coefficients.h
@@ -18,44 +18,268 @@
 namespace android {
 
 // cmd-line: fir -l 7 -s 48000 -c 23400 -n 16 -b 9.62
-const int32_t up_sampler_filter_coefficients[] = {
-        0x7ccccccd, 0x7cc9b757, 0x7cc0773c, 0x7cb10d52, 0x7c9b7afd, 0x7c7fc22f, 0x7c5de56a, 0x7c35e7bb, 0x7c07ccbe, 0x7bd3989d, 0x7b99500c, 0x7b58f84d, 0x7b12972d, 0x7ac63304, 0x7a73d2b5, 0x7a1b7daa, 0x79bd3bd8, 0x795915bc, 0x78ef1457, 0x787f4134, 0x7809a65e, 0x778e4e68, 0x770d4466, 0x768693ec, 0x75fa4911, 0x75687068, 0x74d11703, 0x74344a70, 0x739218b8, 0x72ea905a, 0x723dc051, 0x718bb80b, 0x70d4876b, 0x70183ec5, 0x6f56eee1, 0x6e90a8f2, 0x6dc57e9b, 0x6cf581e8, 0x6c20c550, 0x6b475bb0, 0x6a69584a, 0x6986cec4, 0x689fd324, 0x67b479cf, 0x66c4d787, 0x65d10168, 0x64d90ce7, 0x63dd0fcd, 0x62dd2039, 0x61d95497, 0x60d1c3a6, 0x5fc68470, 0x5eb7ae46, 0x5da558c5, 0x5c8f9bcb, 0x5b768f7a, 0x5a5a4c32, 0x593aea93, 0x58188376, 0x56f32fea, 0x55cb0935, 0x54a028d0, 0x5372a862, 0x5242a1c1, 0x51102eec, 0x4fdb6a09, 0x4ea46d66, 0x4d6b536f, 0x4c3036b2, 0x4af331d9, 0x49b45fa8, 0x4873daf7, 0x4731beb7, 0x45ee25e7, 0x44a92b96, 0x4362eadc, 0x421b7edf, 0x40d302c5, 0x3f8991bd, 0x3e3f46f2, 0x3cf43d8f, 0x3ba890b9, 0x3a5c5b8e, 0x390fb920, 0x37c2c474, 0x36759880, 0x35285026, 0x33db0631, 0x328dd556, 0x3140d82e, 0x2ff42933, 0x2ea7e2c0, 0x2d5c1f0e, 0x2c10f82d, 0x2ac68807, 0x297ce85a, 0x283432b9, 0x26ec8083, 0x25a5eae8, 0x24608ae2, 0x231c7932, 0x21d9ce63, 0x2098a2bf, 0x1f590e55, 0x1e1b28f2, 0x1cdf0a20, 0x1ba4c923, 0x1a6c7cf9, 0x19363c54, 0x18021d9d, 0x16d036eb, 0x15a09e09, 0x1473686d, 0x1348ab3a, 0x12207b3e, 0x10faecee, 0x0fd81464, 0x0eb80562, 0x0d9ad348, 0x0c80911b, 0x0b69517e, 0x0a5526b0, 0x0944228e, 0x08365690, 0x072bd3c5, 0x0624aad6, 0x0520ec00, 0x0420a716,
-        0x0323eb7f, 0x022ac835, 0x01354bc1, 0x0043843f, 0xff557f58, 0xfe6b4a44, 0xfd84f1c8, 0xfca28234, 0xfbc40766, 0xfae98cc5, 0xfa131d41, 0xf940c355, 0xf8728902, 0xf7a877d4, 0xf6e298db, 0xf620f4b2, 0xf5639376, 0xf4aa7cce, 0xf3f5b7e4, 0xf3454b6a, 0xf2993d95, 0xf1f19421, 0xf14e544f, 0xf0af82e4, 0xf015242b, 0xef7f3bf5, 0xeeedcd98, 0xee60dbee, 0xedd86958, 0xed5477be, 0xecd5088e, 0xec5a1cbc, 0xebe3b4c5, 0xeb71d0ab, 0xeb046ffc, 0xea9b91cc, 0xea3734bb, 0xe9d756f3, 0xe97bf627, 0xe9250f99, 0xe8d2a017, 0xe884a3fb, 0xe83b1731, 0xe7f5f531, 0xe7b53908, 0xe778dd50, 0xe740dc3c, 0xe70d2f8d, 0xe6ddd09f, 0xe6b2b862, 0xe68bdf5e, 0xe6693db5, 0xe64acb24, 0xe6307f05, 0xe61a504f, 0xe6083599, 0xe5fa2519, 0xe5f014aa, 0xe5e9f9ca, 0xe5e7c99e, 0xe5e978f0, 0xe5eefc35, 0xe5f8478d, 0xe6054ec6, 0xe616055a, 0xe62a5e76, 0xe6424cf8, 0xe65dc373, 0xe67cb42f, 0xe69f112f, 0xe6c4cc2e, 0xe6edd6a4, 0xe71a21c7, 0xe7499e8f, 0xe77c3db4, 0xe7b1efb4, 0xe7eaa4d4, 0xe8264d21, 0xe864d874, 0xe8a63671, 0xe8ea568f, 0xe9312813, 0xe97a9a17, 0xe9c69b8c, 0xea151b3a, 0xea6607c4, 0xeab94fa9, 0xeb0ee148, 0xeb66aae0, 0xebc09a94, 0xec1c9e6d, 0xec7aa45b, 0xecda9a39, 0xed3c6dce, 0xeda00cd1, 0xee0564e8, 0xee6c63ad, 0xeed4f6b0, 0xef3f0b78, 0xefaa8f87, 0xf017705a, 0xf0859b6e, 0xf0f4fe3d, 0xf1658649, 0xf1d72114, 0xf249bc2c, 0xf2bd4523, 0xf331a99b, 0xf3a6d741, 0xf41cbbd3, 0xf493451f, 0xf50a610a, 0xf581fd8b, 0xf5fa08b5, 0xf67270b1, 0xf6eb23c6, 0xf7641059, 0xf7dd24ef, 0xf856502d, 0xf8cf80de, 0xf948a5f0, 0xf9c1ae7b, 0xfa3a89be, 0xfab32723, 0xfb2b7641, 0xfba366df, 0xfc1ae8f2, 0xfc91eca1,
-        0xfd086246, 0xfd7e3a71, 0xfdf365e8, 0xfe67d5a8, 0xfedb7ae9, 0xff4e471d, 0xffc02bf2, 0x00311b54, 0x00a1076e, 0x010fe2ab, 0x017d9fb8, 0x01ea3184, 0x02558b43, 0x02bfa06d, 0x032864c1, 0x038fcc44, 0x03f5cb46, 0x045a565c, 0x04bd6269, 0x051ee498, 0x057ed264, 0x05dd218f, 0x0639c82d, 0x0694bca0, 0x06edf595, 0x07456a0e, 0x079b1158, 0x07eee314, 0x0840d732, 0x0890e5f7, 0x08df07f6, 0x092b3617, 0x09756994, 0x09bd9bfb, 0x0a03c72b, 0x0a47e559, 0x0a89f10c, 0x0ac9e521, 0x0b07bcc6, 0x0b437380, 0x0b7d0525, 0x0bb46de2, 0x0be9aa34, 0x0c1cb6ef, 0x0c4d913a, 0x0c7c368d, 0x0ca8a4b7, 0x0cd2d9d5, 0x0cfad45a, 0x0d209309, 0x0d4414f9, 0x0d65598f, 0x0d846084, 0x0da129df, 0x0dbbb5f6, 0x0dd40571, 0x0dea1943, 0x0dfdf2ae, 0x0e0f9342, 0x0e1efcdb, 0x0e2c319d, 0x0e3733fc, 0x0e4006b2, 0x0e46acc4, 0x0e4b297c, 0x0e4d806f, 0x0e4db575, 0x0e4bccac, 0x0e47ca78, 0x0e41b37c, 0x0e398c9f, 0x0e2f5b0b, 0x0e232425, 0x0e14ed93, 0x0e04bd39, 0x0df29936, 0x0dde87e2, 0x0dc88fd2, 0x0db0b7d1, 0x0d9706e1, 0x0d7b843b, 0x0d5e3749, 0x0d3f27ab, 0x0d1e5d32, 0x0cfbdfdd, 0x0cd7b7dd, 0x0cb1ed8c, 0x0c8a8973, 0x0c619444, 0x0c3716da, 0x0c0b1a37, 0x0bdda783, 0x0baec80a, 0x0b7e853c, 0x0b4ce8a8, 0x0b19fbfe, 0x0ae5c90b, 0x0ab059bc, 0x0a79b814, 0x0a41ee32, 0x0a09064e, 0x09cf0ab4, 0x099405c6, 0x095801f8, 0x091b09d1, 0x08dd27e6, 0x089e66dd, 0x085ed167, 0x081e7241, 0x07dd5430, 0x079b8203, 0x0759068f, 0x0715ecae, 0x06d23f3d, 0x068e091c, 0x0649552a, 0x06042e45, 0x05be9f49, 0x0578b30e, 0x05327467, 0x04ebee1c, 0x04a52af2, 0x045e359f, 0x041718d2, 0x03cfdf29, 0x03889336, 0x03413f7b, 0x02f9ee68,
-        0x02b2aa5c, 0x026b7da1, 0x0224726d, 0x01dd92df, 0x0196e8fe, 0x01507eb8, 0x010a5de2, 0x00c49034, 0x007f1f4b, 0x003a14a6, 0xfff579a3, 0xffb15783, 0xff6db764, 0xff2aa243, 0xfee820f8, 0xfea63c38, 0xfe64fc93, 0xfe246a72, 0xfde48e17, 0xfda56f9c, 0xfd6716f2, 0xfd298be0, 0xfcecd602, 0xfcb0fcca, 0xfc76077b, 0xfc3bfd2e, 0xfc02e4cc, 0xfbcac510, 0xfb93a486, 0xfb5d898c, 0xfb287a4d, 0xfaf47cc4, 0xfac196bb, 0xfa8fcdca, 0xfa5f2755, 0xfa2fa890, 0xfa015679, 0xf9d435dc, 0xf9a84b50, 0xf97d9b37, 0xf95429c0, 0xf92bfae4, 0xf9051266, 0xf8df73d6, 0xf8bb228c, 0xf89821ac, 0xf8767422, 0xf8561ca7, 0xf8371dbb, 0xf81979ab, 0xf7fd328c, 0xf7e24a3c, 0xf7c8c267, 0xf7b09c7f, 0xf799d9c4, 0xf7847b3d, 0xf77081be, 0xf75dede5, 0xf74cc01c, 0xf73cf898, 0xf72e9758, 0xf7219c2a, 0xf71606a6, 0xf70bd632, 0xf7030a01, 0xf6fba113, 0xf6f59a36, 0xf6f0f407, 0xf6edacf2, 0xf6ebc332, 0xf6eb34d4, 0xf6ebffb2, 0xf6ee217b, 0xf6f197ad, 0xf6f65f9b, 0xf6fc766a, 0xf703d912, 0xf70c8461, 0xf71674fa, 0xf721a756, 0xf72e17c4, 0xf73bc26b, 0xf74aa34c, 0xf75ab63f, 0xf76bf6f7, 0xf77e6103, 0xf791efcb, 0xf7a69e96, 0xf7bc6889, 0xf7d348a4, 0xf7eb39cc, 0xf80436c0, 0xf81e3a25, 0xf8393e81, 0xf8553e3c, 0xf87233a4, 0xf89018eb, 0xf8aee828, 0xf8ce9b5d, 0xf8ef2c71, 0xf9109535, 0xf932cf65, 0xf955d4a7, 0xf9799e8f, 0xf99e269e, 0xf9c36642, 0xf9e956da, 0xfa0ff1b6, 0xfa373017, 0xfa5f0b30, 0xfa877c29, 0xfab07c1d, 0xfada0420, 0xfb040d3b, 0xfb2e906f, 0xfb5986b6, 0xfb84e906, 0xfbb0b04e, 0xfbdcd57a, 0xfc095174, 0xfc361d25, 0xfc633173, 0xfc908746, 0xfcbe1789, 0xfcebdb26, 0xfd19cb0e, 0xfd47e035, 0xfd761395,
-        0xfda45e2c, 0xfdd2b905, 0xfe011d2e, 0xfe2f83c1, 0xfe5de5e3, 0xfe8c3cc3, 0xfeba819d, 0xfee8adba, 0xff16ba71, 0xff44a128, 0xff725b54, 0xff9fe27d, 0xffcd303b, 0xfffa3e37, 0x00270631, 0x005381fa, 0x007fab77, 0x00ab7ca6, 0x00d6ef99, 0x0101fe7a, 0x012ca389, 0x0156d920, 0x018099b2, 0x01a9dfcc, 0x01d2a615, 0x01fae74e, 0x02229e57, 0x0249c629, 0x027059da, 0x029654a0, 0x02bbb1cc, 0x02e06ccf, 0x03048139, 0x0327eab8, 0x034aa51b, 0x036cac52, 0x038dfc6c, 0x03ae919a, 0x03ce682d, 0x03ed7c9a, 0x040bcb77, 0x0429517b, 0x04460b81, 0x0461f688, 0x047d0fb1, 0x0497543f, 0x04b0c19a, 0x04c9554e, 0x04e10d0a, 0x04f7e6a2, 0x050de00d, 0x0522f766, 0x05372aee, 0x054a7909, 0x055ce03f, 0x056e5f3d, 0x057ef4d3, 0x058e9ff8, 0x059d5fc5, 0x05ab3377, 0x05b81a70, 0x05c41435, 0x05cf2070, 0x05d93eee, 0x05e26f9f, 0x05eab296, 0x05f20809, 0x05f87053, 0x05fdebee, 0x06027b78, 0x06061fb2, 0x0608d97c, 0x060aa9da, 0x060b91ee, 0x060b92ff, 0x060aae6e, 0x0608e5c2, 0x06063a9d, 0x0602aec3, 0x05fe4414, 0x05f8fc8f, 0x05f2da52, 0x05ebdf97, 0x05e40eb3, 0x05db6a19, 0x05d1f459, 0x05c7b01a, 0x05bca021, 0x05b0c74b, 0x05a42890, 0x0596c6ff, 0x0588a5bf, 0x0579c812, 0x056a314b, 0x0559e4da, 0x0548e63f, 0x05373912, 0x0524e100, 0x0511e1c6, 0x04fe3f39, 0x04e9fd3c, 0x04d51fc6, 0x04bfaadf, 0x04a9a29e, 0x04930b2b, 0x047be8bc, 0x04643f95, 0x044c1409, 0x04336a75, 0x041a4744, 0x0400aeec, 0x03e6a5ee, 0x03cc30d4, 0x03b15431, 0x039614a1, 0x037a76c7, 0x035e7f4e, 0x034232e6, 0x03259644, 0x0308ae24, 0x02eb7f44, 0x02ce0e67, 0x02b0604f, 0x029279c4, 0x02745f8c, 0x02561670, 0x0237a337, 0x02190aa6,
-        0x01fa5183, 0x01db7c90, 0x01bc908b, 0x019d9230, 0x017e8635, 0x015f714d, 0x01405821, 0x01213f58, 0x01022b90, 0x00e3215e, 0x00c42551, 0x00a53bed, 0x008669ae, 0x0067b303, 0x00491c54, 0x002aa9fa, 0x000c6043, 0xffee4372, 0xffd057bb, 0xffb2a145, 0xff952429, 0xff77e470, 0xff5ae614, 0xff3e2d01, 0xff21bd11, 0xff059a0e, 0xfee9c7af, 0xfece499d, 0xfeb3236b, 0xfe98589b, 0xfe7dec9c, 0xfe63e2cc, 0xfe4a3e70, 0xfe3102bd, 0xfe1832d4, 0xfdffd1bd, 0xfde7e26f, 0xfdd067ca, 0xfdb96498, 0xfda2db8c, 0xfd8ccf46, 0xfd77424c, 0xfd62370e, 0xfd4dafe6, 0xfd39af17, 0xfd2636ca, 0xfd134913, 0xfd00e7ec, 0xfcef153a, 0xfcddd2c7, 0xfccd2246, 0xfcbd0551, 0xfcad7d6b, 0xfc9e8bfd, 0xfc903258, 0xfc8271b4, 0xfc754b32, 0xfc68bfd7, 0xfc5cd092, 0xfc517e38, 0xfc46c987, 0xfc3cb323, 0xfc333b97, 0xfc2a6356, 0xfc222abb, 0xfc1a9208, 0xfc139968, 0xfc0d40ec, 0xfc07888e, 0xfc027031, 0xfbfdf79e, 0xfbfa1e88, 0xfbf6e48c, 0xfbf4492d, 0xfbf24bd9, 0xfbf0ebe7, 0xfbf02896, 0xfbf00112, 0xfbf0746e, 0xfbf181a9, 0xfbf327ab, 0xfbf56549, 0xfbf83941, 0xfbfba23f, 0xfbff9ed7, 0xfc042d8e, 0xfc094cd2, 0xfc0efafe, 0xfc15365c, 0xfc1bfd22, 0xfc234d75, 0xfc2b2567, 0xfc3382fb, 0xfc3c6420, 0xfc45c6b6, 0xfc4fa88f, 0xfc5a076a, 0xfc64e0f9, 0xfc7032de, 0xfc7bfaad, 0xfc8835ed, 0xfc94e216, 0xfca1fc96, 0xfcaf82ca, 0xfcbd7206, 0xfccbc793, 0xfcda80ad, 0xfce99a86, 0xfcf91246, 0xfd08e50c, 0xfd190fed, 0xfd298ff6, 0xfd3a622b, 0xfd4b8389, 0xfd5cf105, 0xfd6ea790, 0xfd80a411, 0xfd92e36c, 0xfda5627e, 0xfdb81e22, 0xfdcb132d, 0xfdde3e6f, 0xfdf19cb9, 0xfe052ad4, 0xfe18e58c, 0xfe2cc9a7, 0xfe40d3ed, 0xfe550124,
-        0xfe694e12, 0xfe7db77c, 0xfe923a2b, 0xfea6d2e5, 0xfebb7e75, 0xfed039a8, 0xfee5014c, 0xfef9d232, 0xff0ea931, 0xff238322, 0xff385ce3, 0xff4d3358, 0xff620368, 0xff76ca02, 0xff8b841a, 0xffa02eac, 0xffb4c6b9, 0xffc9494b, 0xffddb374, 0xfff2024e, 0x000632fa, 0x001a42a4, 0x002e2e82, 0x0041f3d2, 0x00558fdc, 0x0068fff3, 0x007c4177, 0x008f51cf, 0x00a22e71, 0x00b4d4dd, 0x00c7429f, 0x00d97550, 0x00eb6a95, 0x00fd2022, 0x010e93b5, 0x011fc31c, 0x0130ac31, 0x01414cdd, 0x0151a317, 0x0161ace5, 0x01716859, 0x0180d397, 0x018fecd1, 0x019eb246, 0x01ad2249, 0x01bb3b37, 0x01c8fb81, 0x01d661a6, 0x01e36c34, 0x01f019cb, 0x01fc691b, 0x020858e2, 0x0213e7f0, 0x021f1526, 0x0229df75, 0x023445dd, 0x023e4772, 0x0247e354, 0x025118b8, 0x0259e6e1, 0x02624d23, 0x026a4ae5, 0x0271df9c, 0x02790ace, 0x027fcc12, 0x02862311, 0x028c0f83, 0x0291912f, 0x0296a7f0, 0x029b53af, 0x029f9466, 0x02a36a1e, 0x02a6d4f0, 0x02a9d508, 0x02ac6a9e, 0x02ae95fb, 0x02b05779, 0x02b1af7f, 0x02b29e84, 0x02b3250f, 0x02b343b5, 0x02b2fb1a, 0x02b24bf1, 0x02b136f9, 0x02afbd02, 0x02addee8, 0x02ab9d96, 0x02a8fa03, 0x02a5f535, 0x02a2903e, 0x029ecc3c, 0x029aaa5a, 0x02962bd1, 0x029151e3, 0x028c1de0, 0x02869122, 0x0280ad0f, 0x027a7318, 0x0273e4b8, 0x026d0374, 0x0265d0dd, 0x025e4e8b, 0x02567e22, 0x024e614c, 0x0245f9bf, 0x023d4937, 0x0234517a, 0x022b1455, 0x0221939d, 0x0217d12d, 0x020dcee8, 0x02038eb7, 0x01f9128a, 0x01ee5c55, 0x01e36e14, 0x01d849c7, 0x01ccf173, 0x01c16720, 0x01b5acdd, 0x01a9c4bc, 0x019db0d0, 0x01917334, 0x01850e00, 0x01788354, 0x016bd54f, 0x015f0612, 0x015217c0, 0x01450c7f,
-        0x0137e672, 0x012aa7bf, 0x011d528d, 0x010fe901, 0x01026d40, 0x00f4e16f, 0x00e747b0, 0x00d9a226, 0x00cbf2f0, 0x00be3c2d, 0x00b07ff8, 0x00a2c06b, 0x0094ff9b, 0x00873f9b, 0x0079827a, 0x006bca44, 0x005e1900, 0x005070b0, 0x0042d353, 0x003542e2, 0x0027c151, 0x001a508e, 0x000cf281, 0xffffa90e, 0xfff27611, 0xffe55b60, 0xffd85ac9, 0xffcb7615, 0xffbeaf06, 0xffb20754, 0xffa580b1, 0xff991cc9, 0xff8cdd3c, 0xff80c3a4, 0xff74d194, 0xff690894, 0xff5d6a24, 0xff51f7bb, 0xff46b2c7, 0xff3b9cad, 0xff30b6c8, 0xff260269, 0xff1b80da, 0xff113358, 0xff071b16, 0xfefd3941, 0xfef38ef6, 0xfeea1d4c, 0xfee0e54e, 0xfed7e7fd, 0xfecf2650, 0xfec6a130, 0xfebe5980, 0xfeb65015, 0xfeae85bb, 0xfea6fb32, 0xfe9fb12e, 0xfe98a85b, 0xfe91e159, 0xfe8b5cba, 0xfe851b09, 0xfe7f1cc4, 0xfe79625e, 0xfe73ec40, 0xfe6ebac6, 0xfe69ce43, 0xfe6526fe, 0xfe60c533, 0xfe5ca913, 0xfe58d2c5, 0xfe554265, 0xfe51f802, 0xfe4ef3a4, 0xfe4c3546, 0xfe49bcd9, 0xfe478a42, 0xfe459d5e, 0xfe43f5ff, 0xfe4293ec, 0xfe4176e2, 0xfe409e95, 0xfe400aae, 0xfe3fbacd, 0xfe3fae87, 0xfe3fe569, 0xfe405ef6, 0xfe411aa8, 0xfe4217ef, 0xfe435633, 0xfe44d4d3, 0xfe469325, 0xfe489077, 0xfe4acc0e, 0xfe4d4526, 0xfe4ffaf6, 0xfe52ecab, 0xfe561969, 0xfe598050, 0xfe5d2075, 0xfe60f8ea, 0xfe6508b6, 0xfe694edd, 0xfe6dca58, 0xfe727a1f, 0xfe775d1f, 0xfe7c7243, 0xfe81b86d, 0xfe872e7c, 0xfe8cd349, 0xfe92a5a7, 0xfe98a466, 0xfe9ece4f, 0xfea52227, 0xfeab9eb2, 0xfeb242ac, 0xfeb90cce, 0xfebffbd0, 0xfec70e64, 0xfece433a, 0xfed598fe, 0xfedd0e5c, 0xfee4a1fa, 0xfeec527e, 0xfef41e8c, 0xfefc04c6, 0xff0403cc, 0xff0c1a3c, 0xff1446b5,
-        0xff1c87d3, 0xff24dc32, 0xff2d426f, 0xff35b924, 0xff3e3eed, 0xff46d266, 0xff4f722b, 0xff581cd8, 0xff60d10b, 0xff698d62, 0xff72507e, 0xff7b18fe, 0xff83e586, 0xff8cb4bb, 0xff958542, 0xff9e55c6, 0xffa724f0, 0xffaff16f, 0xffb8b9f3, 0xffc17d30, 0xffca39dd, 0xffd2eeb3, 0xffdb9a70, 0xffe43bd5, 0xffecd1a6, 0xfff55aae, 0xfffdd5b8, 0x00064197, 0x000e9d1f, 0x0016e72c, 0x001f1e9b, 0x00274253, 0x002f513a, 0x00374a40, 0x003f2c57, 0x0046f679, 0x004ea7a3, 0x00563edb, 0x005dbb29, 0x00651b9c, 0x006c5f4b, 0x00738551, 0x007a8cd0, 0x008174ef, 0x00883cdc, 0x008ee3cd, 0x009568fc, 0x009bcbab, 0x00a20b23, 0x00a826b2, 0x00ae1dae, 0x00b3ef73, 0x00b99b65, 0x00bf20ee, 0x00c47f7f, 0x00c9b691, 0x00cec5a1, 0x00d3ac38, 0x00d869e1, 0x00dcfe32, 0x00e168c5, 0x00e5a93c, 0x00e9bf43, 0x00edaa88, 0x00f16ac4, 0x00f4ffb6, 0x00f86924, 0x00fba6da, 0x00feb8ad, 0x01019e78, 0x0104581c, 0x0106e583, 0x0109469d, 0x010b7b61, 0x010d83cb, 0x010f5fe2, 0x01110faf, 0x01129344, 0x0113eabb, 0x01151632, 0x011615ce, 0x0116e9bc, 0x0117922f, 0x01180f5d, 0x01186187, 0x011888f2, 0x011885e7, 0x011858b9, 0x011801be, 0x01178152, 0x0116d7d7, 0x011605b5, 0x01150b5a, 0x0113e937, 0x01129fc5, 0x01112f81, 0x010f98eb, 0x010ddc8c, 0x010bfaee, 0x0109f4a2, 0x0107ca3c, 0x01057c57, 0x01030b8e, 0x01007885, 0x00fdc3e0, 0x00faee49, 0x00f7f86e, 0x00f4e2ff, 0x00f1aeb2, 0x00ee5c3e, 0x00eaec5e, 0x00e75fd1, 0x00e3b758, 0x00dff3b7, 0x00dc15b4, 0x00d81e1a, 0x00d40db3, 0x00cfe54f, 0x00cba5bc, 0x00c74fce, 0x00c2e457, 0x00be642f, 0x00b9d02b, 0x00b52925, 0x00b06ff7, 0x00aba57c, 0x00a6ca90, 0x00a1e00f,
-        0x009ce6d8, 0x0097dfc9, 0x0092cbc0, 0x008dab9d, 0x0088803e, 0x00834a83, 0x007e0b4b, 0x0078c375, 0x007373de, 0x006e1d66, 0x0068c0e9, 0x00635f45, 0x005df954, 0x00588ff1, 0x005323f7, 0x004db63c, 0x00484799, 0x0042d8e1, 0x003d6aea, 0x0037fe85, 0x00329483, 0x002d2db0, 0x0027cada, 0x00226ccb, 0x001d144a, 0x0017c21c, 0x00127704, 0x000d33c3, 0x0007f915, 0x0002c7b6, 0xfffda05c, 0xfff883be, 0xfff3728d, 0xffee6d78, 0xffe97529, 0xffe48a4a, 0xffdfad7f, 0xffdadf69, 0xffd620a6, 0xffd171d1, 0xffccd380, 0xffc84645, 0xffc3cab1, 0xffbf614e, 0xffbb0aa3, 0xffb6c735, 0xffb29782, 0xffae7c06, 0xffaa7538, 0xffa6838c, 0xffa2a770, 0xff9ee150, 0xff9b3192, 0xff979898, 0xff9416c1, 0xff90ac66, 0xff8d59dd, 0xff8a1f77, 0xff86fd81, 0xff83f443, 0xff810401, 0xff7e2cfb, 0xff7b6f6c, 0xff78cb8c, 0xff76418b, 0xff73d199, 0xff717bdf, 0xff6f4083, 0xff6d1fa5, 0xff6b1961, 0xff692dd2, 0xff675d09, 0xff65a718, 0xff640c08, 0xff628be3, 0xff6126a9, 0xff5fdc5b, 0xff5eacf3, 0xff5d9867, 0xff5c9eaa, 0xff5bbfaa, 0xff5afb53, 0xff5a5189, 0xff59c230, 0xff594d27, 0xff58f249, 0xff58b16c, 0xff588a65, 0xff587d03, 0xff588913, 0xff58ae5d, 0xff58eca8, 0xff5943b4, 0xff59b340, 0xff5a3b09, 0xff5adac6, 0xff5b922d, 0xff5c60ee, 0xff5d46bb, 0xff5e433e, 0xff5f5621, 0xff607f0b, 0xff61bd9f, 0xff631180, 0xff647a4b, 0xff65f79e, 0xff678912, 0xff692e3f, 0xff6ae6ba, 0xff6cb218, 0xff6e8fe9, 0xff707fbd, 0xff728121, 0xff7493a2, 0xff76b6ca, 0xff78ea20, 0xff7b2d2d, 0xff7d7f76, 0xff7fe07f, 0xff824fca, 0xff84ccdb, 0xff875731, 0xff89ee4d, 0xff8c91ad, 0xff8f40d0, 0xff91fb31, 0xff94c04f, 0xff978fa6,
-        0xff9a68b0, 0xff9d4ae9, 0xffa035cc, 0xffa328d4, 0xffa6237a, 0xffa9253b, 0xffac2d8f, 0xffaf3bf2, 0xffb24fde, 0xffb568ce, 0xffb8863e, 0xffbba7aa, 0xffbecc8d, 0xffc1f465, 0xffc51eaf, 0xffc84ae9, 0xffcb7893, 0xffcea72c, 0xffd1d635, 0xffd50530, 0xffd833a0, 0xffdb6109, 0xffde8cf1, 0xffe1b6dd, 0xffe4de56, 0xffe802e6, 0xffeb2416, 0xffee4174, 0xfff15a8d, 0xfff46ef1, 0xfff77e31, 0xfffa87df, 0xfffd8b92, 0x000088df, 0x00037f60, 0x00066eae, 0x00095666, 0x000c3627, 0x000f0d91, 0x0011dc47, 0x0014a1ee, 0x00175e2d, 0x001a10ad, 0x001cb91a, 0x001f5723, 0x0021ea76, 0x002472c8, 0x0026efcc, 0x0029613a, 0x002bc6cd, 0x002e2040, 0x00306d52, 0x0032adc4, 0x0034e15b, 0x003707dc, 0x00392111, 0x003b2cc5, 0x003d2ac6, 0x003f1ae4, 0x0040fcf3, 0x0042d0c9, 0x0044963d, 0x00464d2b, 0x0047f571, 0x00498eed, 0x004b1984, 0x004c951b, 0x004e0199, 0x004f5ee9, 0x0050acf7, 0x0051ebb4, 0x00531b12, 0x00543b04, 0x00554b83, 0x00564c88, 0x00573e0f, 0x00582016, 0x0058f29f, 0x0059b5ad, 0x005a6946, 0x005b0d72, 0x005ba23b, 0x005c27af, 0x005c9ddc, 0x005d04d4, 0x005d5cab, 0x005da575, 0x005ddf4c, 0x005e0a48, 0x005e2687, 0x005e3427, 0x005e3347, 0x005e240a, 0x005e0694, 0x005ddb0b, 0x005da198, 0x005d5a62, 0x005d0597, 0x005ca363, 0x005c33f6, 0x005bb77f, 0x005b2e31, 0x005a9840, 0x0059f5e1, 0x0059474a, 0x00588cb4, 0x0057c658, 0x0056f471, 0x0056173b, 0x00552ef3, 0x00543bd8, 0x00533e29, 0x00523626, 0x00512412, 0x0050082f, 0x004ee2c1, 0x004db40c, 0x004c7c55, 0x004b3be3, 0x0049f2fc, 0x0048a1e7, 0x004748ed, 0x0045e856, 0x0044806c, 0x00431177, 0x00419bc2, 0x00401f98, 0x003e9d42,
-        0x003d150d, 0x003b8742, 0x0039f42e, 0x00385c1d, 0x0036bf58, 0x00351e2d, 0x003378e7, 0x0031cfd1, 0x00302337, 0x002e7363, 0x002cc0a2, 0x002b0b3d, 0x00295380, 0x002799b3, 0x0025de22, 0x00242115, 0x002262d6, 0x0020a3ad, 0x001ee3e1, 0x001d23b9, 0x001b637e, 0x0019a373, 0x0017e3df, 0x00162507, 0x0014672d, 0x0012aa95, 0x0010ef82, 0x000f3633, 0x000d7eea, 0x000bc9e6, 0x000a1765, 0x000867a5, 0x0006bae1, 0x00051157, 0x00036b3f, 0x0001c8d2, 0x00002a4a, 0xfffe8fdc, 0xfffcf9be, 0xfffb6825, 0xfff9db44, 0xfff8534d, 0xfff6d070, 0xfff552de, 0xfff3dac3, 0xfff2684e, 0xfff0fba9, 0xffef94fe, 0xffee3477, 0xffecda3b, 0xffeb866f, 0xffea3939, 0xffe8f2bb, 0xffe7b317, 0xffe67a6f, 0xffe548e0, 0xffe41e88, 0xffe2fb83, 0xffe1dfec, 0xffe0cbdc, 0xffdfbf6b, 0xffdebaaf, 0xffddbdbd, 0xffdcc8a9, 0xffdbdb84, 0xffdaf65e, 0xffda1948, 0xffd9444e, 0xffd8777d, 0xffd7b2e0, 0xffd6f67f, 0xffd64264, 0xffd59695, 0xffd4f316, 0xffd457ec, 0xffd3c519, 0xffd33a9e, 0xffd2b87c, 0xffd23eaf, 0xffd1cd37, 0xffd1640e, 0xffd1032f, 0xffd0aa93, 0xffd05a33, 0xffd01205, 0xffcfd1ff, 0xffcf9a15, 0xffcf6a3b, 0xffcf4262, 0xffcf227b, 0xffcf0a77, 0xffcefa44, 0xffcef1cf, 0xffcef106, 0xffcef7d4, 0xffcf0623, 0xffcf1bde, 0xffcf38ec, 0xffcf5d36, 0xffcf88a2, 0xffcfbb17, 0xffcff478, 0xffd034ac, 0xffd07b95, 0xffd0c915, 0xffd11d0f, 0xffd17764, 0xffd1d7f5, 0xffd23ea1, 0xffd2ab47, 0xffd31dc7, 0xffd395fd, 0xffd413c9, 0xffd49705, 0xffd51f90, 0xffd5ad44, 0xffd63ffe, 0xffd6d798, 0xffd773ed, 0xffd814d7, 0xffd8ba31, 0xffd963d4, 0xffda1199, 0xffdac35a, 0xffdb78ef, 0xffdc3231, 0xffdceef9, 0xffddaf1e,
-        0xffde727a, 0xffdf38e5, 0xffe00236, 0xffe0ce46, 0xffe19cec, 0xffe26e01, 0xffe3415d, 0xffe416d8, 0xffe4ee4b, 0xffe5c78d, 0xffe6a277, 0xffe77ee2, 0xffe85ca7, 0xffe93b9e, 0xffea1ba2, 0xffeafc8b, 0xffebde33, 0xffecc075, 0xffeda32a, 0xffee862e, 0xffef695c, 0xfff04c8f, 0xfff12fa3, 0xfff21275, 0xfff2f4e0, 0xfff3d6c3, 0xfff4b7fb, 0xfff59866, 0xfff677e2, 0xfff75650, 0xfff8338e, 0xfff90f7c, 0xfff9e9fd, 0xfffac2f0, 0xfffb9a38, 0xfffc6fb8, 0xfffd4352, 0xfffe14eb, 0xfffee466, 0xffffb1aa, 0x00007c9c, 0x00014521, 0x00020b23, 0x0002ce87, 0x00038f37, 0x00044d1b, 0x0005081f, 0x0005c02c, 0x0006752d, 0x0007270f, 0x0007d5bf, 0x0008812a, 0x0009293e, 0x0009cdeb, 0x000a6f20, 0x000b0cce, 0x000ba6e5, 0x000c3d59, 0x000cd01b, 0x000d5f1f, 0x000dea5a, 0x000e71c1, 0x000ef549, 0x000f74e9, 0x000ff098, 0x0010684e, 0x0010dc05, 0x00114bb4, 0x0011b757, 0x00121ee9, 0x00128265, 0x0012e1c8, 0x00133d0e, 0x00139436, 0x0013e73e, 0x00143626, 0x001480ec, 0x0014c792, 0x00150a19, 0x00154883, 0x001582d3, 0x0015b90b, 0x0015eb2f, 0x00161944, 0x0016434f, 0x00166956, 0x00168b5e, 0x0016a96f, 0x0016c390, 0x0016d9c9, 0x0016ec22, 0x0016faa5, 0x0017055b, 0x00170c4f, 0x00170f8a, 0x00170f18, 0x00170b04, 0x0017035a, 0x0016f828, 0x0016e979, 0x0016d75b, 0x0016c1dc, 0x0016a90a, 0x00168cf2, 0x00166da5, 0x00164b32, 0x001625a7, 0x0015fd15, 0x0015d18b, 0x0015a31b, 0x001571d5, 0x00153dca, 0x0015070b, 0x0014cdab, 0x001491b9, 0x00145349, 0x0014126c, 0x0013cf36, 0x001389b7, 0x00134204, 0x0012f82e, 0x0012ac48, 0x00125e66, 0x00120e9b, 0x0011bcf9, 0x00116994, 0x00111480, 0x0010bdcf,
-        0x00106595, 0x00100be5, 0x000fb0d2, 0x000f5471, 0x000ef6d4, 0x000e980f, 0x000e3834, 0x000dd758, 0x000d758d, 0x000d12e6, 0x000caf76, 0x000c4b50, 0x000be687, 0x000b812d, 0x000b1b55, 0x000ab510, 0x000a4e72, 0x0009e78c, 0x00098070, 0x0009192f, 0x0008b1db, 0x00084a86, 0x0007e33f, 0x00077c17, 0x00071520, 0x0006ae6a, 0x00064804, 0x0005e1fe, 0x00057c68, 0x00051750, 0x0004b2c7, 0x00044eda, 0x0003eb98, 0x0003890e, 0x0003274c, 0x0002c65d, 0x00026650, 0x00020730, 0x0001a90b, 0x00014bed, 0x0000efe1, 0x000094f3, 0x00003b2e, 0xffffe29d, 0xffff8b4b, 0xffff3540, 0xfffee088, 0xfffe8d2c, 0xfffe3b35, 0xfffdeaaa, 0xfffd9b96, 0xfffd4dff, 0xfffd01ee, 0xfffcb769, 0xfffc6e78, 0xfffc2720, 0xfffbe169, 0xfffb9d59, 0xfffb5af3, 0xfffb1a3f, 0xfffadb40, 0xfffa9dfa, 0xfffa6273, 0xfffa28ad, 0xfff9f0ac, 0xfff9ba73, 0xfff98604, 0xfff95363, 0xfff92290, 0xfff8f38e, 0xfff8c65d, 0xfff89b00, 0xfff87176, 0xfff849c0, 0xfff823dd, 0xfff7ffce, 0xfff7dd92, 0xfff7bd28, 0xfff79e8f, 0xfff781c5, 0xfff766c8, 0xfff74d97, 0xfff7362f, 0xfff7208d, 0xfff70caf, 0xfff6fa92, 0xfff6ea31, 0xfff6db89, 0xfff6ce97, 0xfff6c356, 0xfff6b9c1, 0xfff6b1d5, 0xfff6ab8c, 0xfff6a6e2, 0xfff6a3d0, 0xfff6a252, 0xfff6a262, 0xfff6a3f9, 0xfff6a713, 0xfff6aba9, 0xfff6b1b4, 0xfff6b92d, 0xfff6c20f, 0xfff6cc52, 0xfff6d7f0, 0xfff6e4e1, 0xfff6f31d, 0xfff7029f, 0xfff7135d, 0xfff72551, 0xfff73873, 0xfff74cba, 0xfff76220, 0xfff7789c, 0xfff79026, 0xfff7a8b6, 0xfff7c245, 0xfff7dcc8, 0xfff7f83a, 0xfff81490, 0xfff831c3, 0xfff84fcb, 0xfff86e9e, 0xfff88e35, 0xfff8ae88, 0xfff8cf8d, 0xfff8f13c, 0xfff9138e,
-        0xfff93679, 0xfff959f5, 0xfff97dfa, 0xfff9a27f, 0xfff9c77d, 0xfff9eceb, 0xfffa12c0, 0xfffa38f5, 0xfffa5f81, 0xfffa865d, 0xfffaad81, 0xfffad4e4, 0xfffafc7f, 0xfffb244a, 0xfffb4c3e, 0xfffb7452, 0xfffb9c80, 0xfffbc4bf, 0xfffbed0a, 0xfffc1558, 0xfffc3da2, 0xfffc65e2, 0xfffc8e11, 0xfffcb628, 0xfffcde20, 0xfffd05f3, 0xfffd2d9b, 0xfffd5511, 0xfffd7c4f, 0xfffda350, 0xfffdca0d, 0xfffdf080, 0xfffe16a6, 0xfffe3c76, 0xfffe61ee, 0xfffe8707, 0xfffeabbd, 0xfffed00a, 0xfffef3ea, 0xffff1759, 0xffff3a53, 0xffff5cd2, 0xffff7ed3, 0xffffa052, 0xffffc14b, 0xffffe1bc, 0x0000019f, 0x000020f3, 0x00003fb3, 0x00005ddd, 0x00007b6f, 0x00009865, 0x0000b4bd, 0x0000d074, 0x0000eb89, 0x000105f9, 0x00011fc3, 0x000138e4, 0x0001515c, 0x00016928, 0x00018048, 0x000196ba, 0x0001ac7d, 0x0001c191, 0x0001d5f4, 0x0001e9a7, 0x0001fca8, 0x00020ef7, 0x00022095, 0x00023181, 0x000241bb, 0x00025143, 0x0002601b, 0x00026e41, 0x00027bb8, 0x0002887f, 0x00029497, 0x0002a002, 0x0002aac0, 0x0002b4d2, 0x0002be3b, 0x0002c6fa, 0x0002cf12, 0x0002d684, 0x0002dd53, 0x0002e37e, 0x0002e90a, 0x0002edf6, 0x0002f246, 0x0002f5fc, 0x0002f919, 0x0002fba0, 0x0002fd94, 0x0002fef6, 0x0002ffc9, 0x00030010, 0x0002ffcd, 0x0002ff03, 0x0002fdb4, 0x0002fbe4, 0x0002f995, 0x0002f6c9, 0x0002f385, 0x0002efca, 0x0002eb9c, 0x0002e6fe, 0x0002e1f3, 0x0002dc7d, 0x0002d6a0, 0x0002d060, 0x0002c9be, 0x0002c2be, 0x0002bb64, 0x0002b3b3, 0x0002abad, 0x0002a357, 0x00029ab2, 0x000291c3, 0x0002888c, 0x00027f11, 0x00027555, 0x00026b5b, 0x00026126, 0x000256b9, 0x00024c18, 0x00024146, 0x00023645, 0x00022b19,
-        0x00021fc5, 0x0002144b, 0x000208b0, 0x0001fcf5, 0x0001f11e, 0x0001e52e, 0x0001d927, 0x0001cd0d, 0x0001c0e1, 0x0001b4a8, 0x0001a863, 0x00019c15, 0x00018fc1, 0x0001836a, 0x00017712, 0x00016abb, 0x00015e68, 0x0001521b, 0x000145d7, 0x0001399e, 0x00012d72, 0x00012155, 0x0001154a, 0x00010952, 0x0000fd6f, 0x0000f1a4, 0x0000e5f3, 0x0000da5c, 0x0000cee3, 0x0000c388, 0x0000b84d, 0x0000ad34, 0x0000a23f, 0x0000976e, 0x00008cc4, 0x00008241, 0x000077e8, 0x00006db9, 0x000063b5, 0x000059dd, 0x00005033, 0x000046b8, 0x00003d6c, 0x00003450, 0x00002b66, 0x000022ad, 0x00001a28, 0x000011d5, 0x000009b6, 0x000001cc, 0xfffffa17, 0xfffff297, 0xffffeb4c, 0xffffe438, 0xffffdd5a, 0xffffd6b2, 0xffffd041, 0xffffca06, 0xffffc402, 0xffffbe35, 0xffffb89f, 0xffffb340, 0xffffae17, 0xffffa924, 0xffffa467, 0xffff9fe0, 0xffff9b8f, 0xffff9773, 0xffff938c, 0xffff8fd9, 0xffff8c5a, 0xffff890e, 0xffff85f5, 0xffff830e, 0xffff805a, 0xffff7dd6, 0xffff7b82, 0xffff795f, 0xffff776a, 0xffff75a3, 0xffff740a, 0xffff729e, 0xffff715d, 0xffff7047, 0xffff6f5c, 0xffff6e99, 0xffff6dff, 0xffff6d8d, 0xffff6d40, 0xffff6d1a, 0xffff6d17, 0xffff6d38, 0xffff6d7c, 0xffff6de2, 0xffff6e67, 0xffff6f0d, 0xffff6fd1, 0xffff70b2, 0xffff71b0, 0xffff72c9, 0xffff73fc, 0xffff7549, 0xffff76ae, 0xffff782a, 0xffff79bc, 0xffff7b63, 0xffff7d1f, 0xffff7eed, 0xffff80cd, 0xffff82bf, 0xffff84c0, 0xffff86d0, 0xffff88ee, 0xffff8b19, 0xffff8d50, 0xffff8f92, 0xffff91de, 0xffff9434, 0xffff9691, 0xffff98f5, 0xffff9b60, 0xffff9dd0, 0xffffa045, 0xffffa2be, 0xffffa539, 0xffffa7b7, 0xffffaa35, 0xffffacb4,
-        0x00000000
+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[] = {
-        0x736144b5, 0x735ed3aa, 0x735780bb, 0x734b4c77, 0x733a37d2, 0x7324441e, 0x7309730f, 0x72e9c6b8, 0x72c5418e, 0x729be665, 0x726db871, 0x723abb44, 0x7202f2d3, 0x71c6636d, 0x718511c2, 0x713f02e0, 0x70f43c32, 0x70a4c37f, 0x70509eec, 0x6ff7d4f8, 0x6f9a6c7f, 0x6f386cb6, 0x6ed1dd2e, 0x6e66c5ce, 0x6df72ed9, 0x6d8320e6, 0x6d0aa4e6, 0x6c8dc41f, 0x6c0c882a, 0x6b86faf8, 0x6afd26cb, 0x6a6f1638, 0x69dcd425, 0x69466bc8, 0x68abe8a8, 0x680d5698, 0x676ac1bb, 0x66c4367d, 0x6619c197, 0x656b700a, 0x64b94f22, 0x64036c6f, 0x6349d5c9, 0x628c994c, 0x61cbc559, 0x61076890, 0x603f91d5, 0x5f745049, 0x5ea5b34c, 0x5dd3ca7a, 0x5cfea5aa, 0x5c2654ed, 0x5b4ae88d, 0x5a6c7108, 0x598aff13, 0x58a6a397, 0x57bf6fae, 0x56d574a2, 0x55e8c3ee, 0x54f96f37, 0x54078851, 0x53132138, 0x521c4c10, 0x51231b26, 0x5027a0e9, 0x4f29efed, 0x4e2a1ae8, 0x4d2834b0, 0x4c245038, 0x4b1e8091, 0x4a16d8e5, 0x490d6c79, 0x48024ea7, 0x46f592e2, 0x45e74cad, 0x44d78fa0, 0x43c66f62, 0x42b3ffa9, 0x41a05437, 0x408b80d9, 0x3f759967, 0x3e5eb1bd, 0x3d46ddc1, 0x3c2e315a, 0x3b14c072, 0x39fa9ef3, 0x38dfe0c6, 0x37c499d0, 0x36a8ddf3, 0x358cc109, 0x347056e3, 0x3353b349, 0x3236e9f7, 0x311a0e9b, 0x2ffd34d4, 0x2ee07030, 0x2dc3d429, 0x2ca77428, 0x2b8b637b, 0x2a6fb55e, 0x29547ced, 0x2839cd30, 0x271fb90d, 0x2606534e, 0x24edae9c, 0x23d5dd81, 0x22bef262, 0x21a8ff7e, 0x209416f2, 0x1f804ab0, 0x1e6dac83, 0x1d5c4e09, 0x1c4c40b6, 0x1b3d95d1, 0x1a305e70, 0x1924ab7b, 0x181a8da5, 0x17121573, 0x160b5331, 0x150656f8, 0x140330a9, 0x1301efed, 0x1202a434, 0x11055cb4, 0x100a2864, 0x0f111603, 0x0e1a340d, 0x0d2590c3,
-        0x0c333a22, 0x0b433de8, 0x0a55a98f, 0x096a8a51, 0x0881ed1f, 0x079bdea7, 0x06b86b52, 0x05d79f40, 0x04f98649, 0x041e2bfe, 0x03459ba4, 0x026fe039, 0x019d046d, 0x00cd12a4, 0x000014f8, 0xff361534, 0xfe6f1cd7, 0xfdab350f, 0xfcea66be, 0xfc2cba75, 0xfb723876, 0xfabae8b2, 0xfa06d2ca, 0xf955fe0c, 0xf8a87178, 0xf7fe33ba, 0xf7574b2b, 0xf6b3bdd3, 0xf6139169, 0xf576cb4e, 0xf4dd7092, 0xf44785f1, 0xf3b50fd6, 0xf3261255, 0xf29a9133, 0xf2128fde, 0xf18e1174, 0xf10d18bd, 0xf08fa82f, 0xf015c1ee, 0xef9f67cb, 0xef2c9b43, 0xeebd5d81, 0xee51af5f, 0xede99165, 0xed8503c7, 0xed24066b, 0xecc698e6, 0xec6cba79, 0xec166a19, 0xebc3a669, 0xeb746dbe, 0xeb28be1f, 0xeae09544, 0xea9bf097, 0xea5acd38, 0xea1d27f7, 0xe9e2fd5b, 0xe9ac49a0, 0xe97908b8, 0xe9493649, 0xe91ccdb5, 0xe8f3ca12, 0xe8ce2631, 0xe8abdc9d, 0xe88ce79a, 0xe871412a, 0xe858e30a, 0xe843c6b5, 0xe831e563, 0xe823380d, 0xe817b76c, 0xe80f5bfb, 0xe80a1df5, 0xe807f55b, 0xe808d9f1, 0xe80cc342, 0xe813a89f, 0xe81d8122, 0xe82a43ac, 0xe839e6e9, 0xe84c6152, 0xe861a92b, 0xe879b487, 0xe8947947, 0xe8b1ed1c, 0xe8d2058b, 0xe8f4b7e9, 0xe919f961, 0xe941bef3, 0xe96bfd76, 0xe998a999, 0xe9c7b7e3, 0xe9f91cb9, 0xea2ccc59, 0xea62bae0, 0xea9adc49, 0xead52471, 0xeb118714, 0xeb4ff7d4, 0xeb906a35, 0xebd2d1a1, 0xec17216b, 0xec5d4ccd, 0xeca546eb, 0xecef02d5, 0xed3a7388, 0xed878bf0, 0xedd63ee5, 0xee267f35, 0xee783f9e, 0xeecb72d1, 0xef200b76, 0xef75fc2b, 0xefcd3787, 0xf025b01a, 0xf07f586e, 0xf0da230b, 0xf1360276, 0xf192e932, 0xf1f0c9c5, 0xf24f96b5, 0xf2af428c, 0xf30fbfd7, 0xf371012c, 0xf3d2f926, 0xf4359a6a, 0xf498d7a5,
-        0xf4fca390, 0xf560f0f3, 0xf5c5b2a1, 0xf62adb7c, 0xf6905e79, 0xf6f62e9d, 0xf75c3eff, 0xf7c282cb, 0xf828ed43, 0xf88f71bf, 0xf8f603ae, 0xf95c9699, 0xf9c31e22, 0xfa298e07, 0xfa8fda21, 0xfaf5f669, 0xfb5bd6f4, 0xfbc16ff6, 0xfc26b5c5, 0xfc8b9cda, 0xfcf019cd, 0xfd54215c, 0xfdb7a869, 0xfe1aa3fc, 0xfe7d0942, 0xfedecd90, 0xff3fe663, 0xffa04963, 0xffffec5f, 0x005ec552, 0x00bcca63, 0x0119f1e4, 0x01763256, 0x01d18265, 0x022bd8ee, 0x02852cfc, 0x02dd75ca, 0x0334aac4, 0x038ac385, 0x03dfb7dd, 0x04337fcb, 0x04861383, 0x04d76b6b, 0x0527801d, 0x05764a68, 0x05c3c34e, 0x060fe408, 0x065aa604, 0x06a402e4, 0x06ebf483, 0x073274f1, 0x07777e74, 0x07bb0b8b, 0x07fd16eb, 0x083d9b81, 0x087c9471, 0x08b9fd18, 0x08f5d10a, 0x09300c14, 0x0968aa3b, 0x099fa7bb, 0x09d5010b, 0x0a08b2d9, 0x0a3aba09, 0x0a6b13bc, 0x0a99bd47, 0x0ac6b43a, 0x0af1f65d, 0x0b1b81ad, 0x0b435462, 0x0b696ceb, 0x0b8dc9ed, 0x0bb06a47, 0x0bd14d0b, 0x0bf07186, 0x0c0dd738, 0x0c297dd9, 0x0c436557, 0x0c5b8dd4, 0x0c71f7a9, 0x0c86a361, 0x0c9991be, 0x0caac3b5, 0x0cba3a6d, 0x0cc7f742, 0x0cd3fbc0, 0x0cde49a8, 0x0ce6e2ea, 0x0cedc9a7, 0x0cf30031, 0x0cf6890a, 0x0cf866e1, 0x0cf89c96, 0x0cf72d34, 0x0cf41bf7, 0x0cef6c43, 0x0ce921ab, 0x0ce13feb, 0x0cd7caec, 0x0cccc6bc, 0x0cc03797, 0x0cb221de, 0x0ca28a1a, 0x0c9174fa, 0x0c7ee754, 0x0c6ae622, 0x0c557681, 0x0c3e9db5, 0x0c26611f, 0x0c0cc646, 0x0bf1d2d0, 0x0bd58c81, 0x0bb7f940, 0x0b991f0f, 0x0b79040c, 0x0b57ae75, 0x0b3524a0, 0x0b116cff, 0x0aec8e1c, 0x0ac68e9b, 0x0a9f7537, 0x0a7748c0, 0x0a4e101f, 0x0a23d24e, 0x09f8965d, 0x09cc636e, 0x099f40b5, 0x09713575,
-        0x09424904, 0x091282c4, 0x08e1ea27, 0x08b086aa, 0x087e5fd7, 0x084b7d43, 0x0817e68c, 0x07e3a35a, 0x07aebb5d, 0x0779364a, 0x07431bdf, 0x070c73dd, 0x06d5460b, 0x069d9a31, 0x0665781b, 0x062ce795, 0x05f3f06b, 0x05ba9a6b, 0x0580ed5f, 0x0546f10f, 0x050cad3f, 0x04d229b1, 0x04976e20, 0x045c8240, 0x04216dc0, 0x03e63846, 0x03aae970, 0x036f88d2, 0x03341df4, 0x02f8b055, 0x02bd4768, 0x0281ea90, 0x0246a125, 0x020b726f, 0x01d065a8, 0x019581f9, 0x015ace79, 0x0120522f, 0x00e6140f, 0x00ac1af9, 0x00726dbb, 0x0039130c, 0x00001191, 0xffc76fd5, 0xff8f344f, 0xff576560, 0xff20094d, 0xfee92646, 0xfeb2c261, 0xfe7ce399, 0xfe478fd2, 0xfe12ccd1, 0xfddea042, 0xfdab0fb6, 0xfd7820a0, 0xfd45d856, 0xfd143c12, 0xfce350f0, 0xfcb31bec, 0xfc83a1e5, 0xfc54e79a, 0xfc26f1ad, 0xfbf9c49d, 0xfbcd64ca, 0xfba1d673, 0xfb771db9, 0xfb4d3e97, 0xfb243cea, 0xfafc1c6e, 0xfad4e0b9, 0xfaae8d43, 0xfa89255f, 0xfa64ac3f, 0xfa4124f2, 0xfa1e9262, 0xf9fcf758, 0xf9dc567b, 0xf9bcb24a, 0xf99e0d26, 0xf980694a, 0xf963c8cc, 0xf9482da0, 0xf92d9997, 0xf9140e5e, 0xf8fb8d7d, 0xf8e4185a, 0xf8cdb036, 0xf8b85631, 0xf8a40b44, 0xf890d048, 0xf87ea5f1, 0xf86d8cd1, 0xf85d8555, 0xf84e8fc9, 0xf840ac57, 0xf833db04, 0xf8281bb6, 0xf81d6e2e, 0xf813d20d, 0xf80b46d3, 0xf803cbdc, 0xf7fd6065, 0xf7f8038c, 0xf7f3b44b, 0xf7f0717e, 0xf7ee39e2, 0xf7ed0c12, 0xf7ece68c, 0xf7edc7af, 0xf7efadbd, 0xf7f296d7, 0xf7f68103, 0xf7fb6a29, 0xf8015015, 0xf8083077, 0xf81008e2, 0xf818d6cf, 0xf822979b, 0xf82d488c, 0xf838e6c9, 0xf8456f65, 0xf852df56, 0xf861337c, 0xf870689f, 0xf8807b70, 0xf8916889, 0xf8a32c6e, 0xf8b5c38d,
-        0xf8c92a41, 0xf8dd5ccf, 0xf8f25767, 0xf9081629, 0xf91e9521, 0xf935d048, 0xf94dc388, 0xf9666ab7, 0xf97fc19e, 0xf999c3f4, 0xf9b46d64, 0xf9cfb988, 0xf9eba3ef, 0xfa082817, 0xfa254176, 0xfa42eb75, 0xfa61216f, 0xfa7fdeba, 0xfa9f1e9e, 0xfabedc5a, 0xfadf1328, 0xfaffbe36, 0xfb20d8ad, 0xfb425db0, 0xfb64485b, 0xfb8693c6, 0xfba93b01, 0xfbcc391d, 0xfbef8924, 0xfc13261f, 0xfc370b14, 0xfc5b3309, 0xfc7f9902, 0xfca43803, 0xfcc90b12, 0xfcee0d33, 0xfd133970, 0xfd388ad1, 0xfd5dfc63, 0xfd838938, 0xfda92c63, 0xfdcee0ff, 0xfdf4a22a, 0xfe1a6b08, 0xfe4036c5, 0xfe660094, 0xfe8bc3ad, 0xfeb17b53, 0xfed722d0, 0xfefcb57a, 0xff222eac, 0xff4789d1, 0xff6cc25a, 0xff91d3c6, 0xffb6b99f, 0xffdb6f7c, 0xfffff100, 0x002439db, 0x004845cc, 0x006c10a0, 0x008f9631, 0x00b2d26b, 0x00d5c147, 0x00f85ecf, 0x011aa71d, 0x013c965b, 0x015e28c7, 0x017f5aad, 0x01a0286c, 0x01c08e78, 0x01e08952, 0x02001593, 0x021f2fe5, 0x023dd505, 0x025c01c5, 0x0279b30b, 0x0296e5d0, 0x02b39724, 0x02cfc429, 0x02eb6a18, 0x03068640, 0x03211603, 0x033b16dc, 0x03548659, 0x036d621f, 0x0385a7eb, 0x039d558e, 0x03b468f1, 0x03cae014, 0x03e0b90d, 0x03f5f20a, 0x040a894e, 0x041e7d34, 0x0431cc31, 0x044474ce, 0x045675ab, 0x0467cd83, 0x04787b24, 0x04887d76, 0x0497d378, 0x04a67c41, 0x04b476fe, 0x04c1c2f3, 0x04ce5f7d, 0x04da4c10, 0x04e58836, 0x04f01392, 0x04f9edda, 0x050316e0, 0x050b8e8a, 0x051354d5, 0x051a69d4, 0x0520cdb1, 0x052680ae, 0x052b8320, 0x052fd573, 0x0533782a, 0x05366bdc, 0x0538b136, 0x053a48fa, 0x053b3400, 0x053b7332, 0x053b0791, 0x0539f231, 0x0538343a, 0x0535cee9, 0x0532c38c, 0x052f1386,
-        0x052ac04c, 0x0525cb66, 0x0520366d, 0x051a030f, 0x05133308, 0x050bc828, 0x0503c44d, 0x04fb2969, 0x04f1f97c, 0x04e83697, 0x04dde2da, 0x04d30074, 0x04c791a4, 0x04bb98b5, 0x04af1804, 0x04a211f8, 0x04948906, 0x04867fb3, 0x0477f88d, 0x0468f62e, 0x04597b40, 0x04498a72, 0x04392684, 0x0428523d, 0x0417106e, 0x040563f4, 0x03f34fb2, 0x03e0d697, 0x03cdfb99, 0x03bac1b4, 0x03a72bf0, 0x03933d58, 0x037ef900, 0x036a6201, 0x03557b7a, 0x03404890, 0x032acc6d, 0x03150a3f, 0x02ff0538, 0x02e8c08e, 0x02d23f7a, 0x02bb8537, 0x02a49505, 0x028d7223, 0x02761fd3, 0x025ea157, 0x0246f9f3, 0x022f2cea, 0x02173d81, 0x01ff2ef9, 0x01e70494, 0x01cec194, 0x01b66936, 0x019dfeb6, 0x0185854f, 0x016d0037, 0x015472a1, 0x013bdfbc, 0x01234ab4, 0x010ab6b0, 0x00f226d0, 0x00d99e31, 0x00c11feb, 0x00a8af0c, 0x00904ea0, 0x007801aa, 0x005fcb26, 0x0047ae09, 0x002fad3f, 0x0017cbae, 0x00000c33, 0xffe871a0, 0xffd0fec1, 0xffb9b656, 0xffa29b18, 0xff8bafb3, 0xff74f6cc, 0xff5e72fb, 0xff4826cf, 0xff3214c9, 0xff1c3f63, 0xff06a907, 0xfef15417, 0xfedc42e7, 0xfec777be, 0xfeb2f4d9, 0xfe9ebc66, 0xfe8ad087, 0xfe773351, 0xfe63e6cb, 0xfe50ecf0, 0xfe3e47ac, 0xfe2bf8de, 0xfe1a0256, 0xfe0865d7, 0xfdf72515, 0xfde641b7, 0xfdd5bd53, 0xfdc59972, 0xfdb5d78f, 0xfda67913, 0xfd977f5d, 0xfd88ebb9, 0xfd7abf64, 0xfd6cfb8e, 0xfd5fa157, 0xfd52b1cf, 0xfd462df6, 0xfd3a16c0, 0xfd2e6d0d, 0xfd2331b0, 0xfd18656f, 0xfd0e08fb, 0xfd041cfa, 0xfcfaa200, 0xfcf19894, 0xfce9012c, 0xfce0dc2f, 0xfcd929f4, 0xfcd1eac3, 0xfccb1ed7, 0xfcc4c658, 0xfcbee162, 0xfcb97001, 0xfcb47232, 0xfcafe7e2, 0xfcabd0f2, 0xfca82d32,
-        0xfca4fc64, 0xfca23e3d, 0xfc9ff262, 0xfc9e186a, 0xfc9cafe0, 0xfc9bb83e, 0xfc9b30f3, 0xfc9b195f, 0xfc9b70d6, 0xfc9c369c, 0xfc9d69eb, 0xfc9f09ee, 0xfca115c5, 0xfca38c83, 0xfca66d2e, 0xfca9b6bf, 0xfcad6827, 0xfcb18047, 0xfcb5fdf7, 0xfcbae002, 0xfcc0252b, 0xfcc5cc26, 0xfccbd3a0, 0xfcd23a3a, 0xfcd8fe8b, 0xfce01f21, 0xfce79a7f, 0xfcef6f20, 0xfcf79b75, 0xfd001de8, 0xfd08f4d6, 0xfd121e99, 0xfd1b9980, 0xfd2563d3, 0xfd2f7bd1, 0xfd39dfb4, 0xfd448dae, 0xfd4f83eb, 0xfd5ac08e, 0xfd6641b8, 0xfd720581, 0xfd7e09fc, 0xfd8a4d37, 0xfd96cd3d, 0xfda3880f, 0xfdb07bb0, 0xfdbda61a, 0xfdcb0546, 0xfdd89727, 0xfde659af, 0xfdf44acc, 0xfe026869, 0xfe10b06f, 0xfe1f20c5, 0xfe2db74f, 0xfe3c71f1, 0xfe4b4e8c, 0xfe5a4b03, 0xfe696534, 0xfe789b01, 0xfe87ea47, 0xfe9750e8, 0xfea6ccc3, 0xfeb65bb9, 0xfec5fbac, 0xfed5aa7e, 0xfee56614, 0xfef52c54, 0xff04fb25, 0xff14d073, 0xff24aa2a, 0xff348639, 0xff446293, 0xff543d2e, 0xff641402, 0xff73e50e, 0xff83ae52, 0xff936dd2, 0xffa3219a, 0xffb2c7b6, 0xffc25e3b, 0xffd1e340, 0xffe154e3, 0xfff0b148, 0xfffff697, 0x000f22fe, 0x001e34b4, 0x002d29f3, 0x003c00fd, 0x004ab81b, 0x00594d9d, 0x0067bfd8, 0x00760d2a, 0x008433f9, 0x009232b2, 0x00a007c9, 0x00adb1bb, 0x00bb2f0b, 0x00c87e47, 0x00d59e03, 0x00e28cdd, 0x00ef497a, 0x00fbd28a, 0x010826c4, 0x011444e7, 0x01202bbe, 0x012bda1b, 0x01374eda, 0x014288e0, 0x014d871b, 0x01584883, 0x0162cc19, 0x016d10e9, 0x01771608, 0x0180da94, 0x018a5db5, 0x01939e9e, 0x019c9c8b, 0x01a556c1, 0x01adcc91, 0x01b5fd54, 0x01bde86f, 0x01c58d50, 0x01cceb6e, 0x01d4024c, 0x01dad175, 0x01e15880, 0x01e7970e,
-        0x01ed8cc7, 0x01f33960, 0x01f89c98, 0x01fdb637, 0x0202860e, 0x02070bf9, 0x020b47dd, 0x020f39ab, 0x0212e15c, 0x02163ef1, 0x02195278, 0x021c1c06, 0x021e9bbb, 0x0220d1bf, 0x0222be45, 0x02246187, 0x0225bbca, 0x0226cd5b, 0x02279691, 0x022817ca, 0x0228516f, 0x022843f0, 0x0227efc6, 0x02275572, 0x0226757e, 0x0225507c, 0x0223e706, 0x022239bc, 0x02204949, 0x021e165d, 0x021ba1b2, 0x0218ec06, 0x0215f621, 0x0212c0d2, 0x020f4cec, 0x020b9b4c, 0x0207acd4, 0x0203826c, 0x01ff1d04, 0x01fa7d91, 0x01f5a50d, 0x01f0947a, 0x01eb4cde, 0x01e5cf44, 0x01e01cbe, 0x01da3661, 0x01d41d4a, 0x01cdd297, 0x01c7576d, 0x01c0acf5, 0x01b9d45b, 0x01b2ced1, 0x01ab9d8b, 0x01a441c2, 0x019cbcb1, 0x01950f98, 0x018d3bb8, 0x01854258, 0x017d24bf, 0x0174e437, 0x016c820d, 0x0163ff90, 0x015b5e11, 0x01529ee3, 0x0149c35a, 0x0140cccb, 0x0137bc8f, 0x012e93fc, 0x0125546c, 0x011bff38, 0x011295bb, 0x0109194f, 0x00ff8b4f, 0x00f5ed15, 0x00ec3ffc, 0x00e2855d, 0x00d8be92, 0x00ceecf5, 0x00c511dc, 0x00bb2e9f, 0x00b14493, 0x00a7550c, 0x009d615d, 0x00936ad6, 0x008972c7, 0x007f7a7c, 0x00758341, 0x006b8e5c, 0x00619d15, 0x0057b0ae, 0x004dca68, 0x0043eb7f, 0x003a152f, 0x003048ae, 0x0026872f, 0x001cd1e4, 0x001329f7, 0x00099093, 0x000006db, 0xfff68df1, 0xffed26f0, 0xffe3d2f2, 0xffda930a, 0xffd16848, 0xffc853b6, 0xffbf565a, 0xffb67137, 0xffada547, 0xffa4f383, 0xff9c5cdc, 0xff93e241, 0xff8b8498, 0xff8344c4, 0xff7b23a1, 0xff732209, 0xff6b40cb, 0xff6380b5, 0xff5be28d, 0xff546713, 0xff4d0f02, 0xff45db10, 0xff3ecbea, 0xff37e23b, 0xff311ea4, 0xff2a81c4, 0xff240c2f, 0xff1dbe77, 0xff179926,
-        0xff119cc0, 0xff0bc9c2, 0xff0620a4, 0xff00a1d8, 0xfefb4dc7, 0xfef624d8, 0xfef12766, 0xfeec55cc, 0xfee7b059, 0xfee33759, 0xfedeeb11, 0xfedacbbf, 0xfed6d99c, 0xfed314da, 0xfecf7da3, 0xfecc141d, 0xfec8d867, 0xfec5ca9a, 0xfec2eaca, 0xfec03901, 0xfebdb547, 0xfebb5f9b, 0xfeb937f9, 0xfeb73e54, 0xfeb5729b, 0xfeb3d4b7, 0xfeb26489, 0xfeb121ee, 0xfeb00cbf, 0xfeaf24cc, 0xfeae69e1, 0xfeaddbc4, 0xfead7a37, 0xfead44f4, 0xfead3bb2, 0xfead5e22, 0xfeadabef, 0xfeae24c1, 0xfeaec838, 0xfeaf95f2, 0xfeb08d86, 0xfeb1ae87, 0xfeb2f884, 0xfeb46b07, 0xfeb60596, 0xfeb7c7b0, 0xfeb9b0d3, 0xfebbc078, 0xfebdf613, 0xfec05114, 0xfec2d0e8, 0xfec574f9, 0xfec83caa, 0xfecb275e, 0xfece3472, 0xfed16342, 0xfed4b325, 0xfed82370, 0xfedbb373, 0xfedf627d, 0xfee32fdb, 0xfee71ad4, 0xfeeb22af, 0xfeef46b0, 0xfef3861a, 0xfef7e02a, 0xfefc541e, 0xff00e133, 0xff0586a0, 0xff0a439e, 0xff0f1762, 0xff140121, 0xff19000e, 0xff1e135b, 0xff233a39, 0xff2873d6, 0xff2dbf61, 0xff331c08, 0xff3888f8, 0xff3e055d, 0xff439064, 0xff492937, 0xff4ecf02, 0xff5480f0, 0xff5a3e2c, 0xff6005e1, 0xff65d73a, 0xff6bb163, 0xff719388, 0xff777cd6, 0xff7d6c79, 0xff83619f, 0xff895b77, 0xff8f5930, 0xff9559fb, 0xff9b5d0a, 0xffa16190, 0xffa766c0, 0xffad6bd0, 0xffb36ff9, 0xffb97271, 0xffbf7274, 0xffc56f3e, 0xffcb680e, 0xffd15c22, 0xffd74abe, 0xffdd3325, 0xffe3149e, 0xffe8ee72, 0xffeebfec, 0xfff48859, 0xfffa470a, 0xfffffb51, 0x0005a483, 0x000b41fa, 0x0010d30e, 0x00165720, 0x001bcd8e, 0x002135bd, 0x00268f13, 0x002bd8fa, 0x003112e0, 0x00363c35, 0x003b546b, 0x00405afa, 0x00454f5d, 0x004a310f, 0x004eff94,
-        0x0053ba6e, 0x00586127, 0x005cf349, 0x00617065, 0x0065d80c, 0x006a29d6, 0x006e655c, 0x00728a3d, 0x0076981a, 0x007a8e98, 0x007e6d61, 0x00823422, 0x0085e28b, 0x00897851, 0x008cf52d, 0x009058da, 0x0093a31a, 0x0096d3af, 0x0099ea62, 0x009ce6fe, 0x009fc954, 0x00a29136, 0x00a53e7b, 0x00a7d0ff, 0x00aa48a0, 0x00aca542, 0x00aee6ca, 0x00b10d23, 0x00b3183c, 0x00b50805, 0x00b6dc75, 0x00b89584, 0x00ba3330, 0x00bbb579, 0x00bd1c63, 0x00be67f6, 0x00bf983d, 0x00c0ad48, 0x00c1a728, 0x00c285f4, 0x00c349c4, 0x00c3f2b6, 0x00c480e9, 0x00c4f480, 0x00c54da2, 0x00c58c79, 0x00c5b132, 0x00c5bbfc, 0x00c5ad0a, 0x00c58494, 0x00c542d1, 0x00c4e7fe, 0x00c47459, 0x00c3e824, 0x00c343a4, 0x00c2871f, 0x00c1b2e0, 0x00c0c731, 0x00bfc463, 0x00beaac6, 0x00bd7aae, 0x00bc3470, 0x00bad866, 0x00b966e9, 0x00b7e055, 0x00b6450a, 0x00b49568, 0x00b2d1d1, 0x00b0faaa, 0x00af1059, 0x00ad1346, 0x00ab03da, 0x00a8e282, 0x00a6afa8, 0x00a46bbc, 0x00a2172d, 0x009fb26c, 0x009d3deb, 0x009aba1d, 0x00982778, 0x0095866f, 0x0092d77b, 0x00901b11, 0x008d51ab, 0x008a7bc1, 0x008799cd, 0x0084ac48, 0x0081b3af, 0x007eb07b, 0x007ba32a, 0x00788c36, 0x00756c1d, 0x0072435b, 0x006f126b, 0x006bd9cd, 0x006899fb, 0x00655372, 0x006206b1, 0x005eb431, 0x005b5c71, 0x0057ffec, 0x00549f1c, 0x00513a7e, 0x004dd28c, 0x004a67c0, 0x0046fa93, 0x00438b7e, 0x00401af9, 0x003ca97b, 0x0039377a, 0x0035c56c, 0x003253c6, 0x002ee2fa, 0x002b737b, 0x002805ba, 0x00249a28, 0x00213134, 0x001dcb4a, 0x001a68d8, 0x00170a47, 0x0013b003, 0x00105a72, 0x000d09fc, 0x0009bf05, 0x000679f2, 0x00033b23, 0x000002f9, 0xfffcd1d3,
-        0xfff9a80d, 0xfff68603, 0xfff36c0d, 0xfff05a84, 0xffed51bc, 0xffea520a, 0xffe75bbe, 0xffe46f2a, 0xffe18c9a, 0xffdeb45b, 0xffdbe6b6, 0xffd923f4, 0xffd66c59, 0xffd3c02a, 0xffd11fa9, 0xffce8b13, 0xffcc02a8, 0xffc986a1, 0xffc71738, 0xffc4b4a4, 0xffc25f1a, 0xffc016cb, 0xffbddbe8, 0xffbbae9f, 0xffb98f1c, 0xffb77d88, 0xffb57a0b, 0xffb384ca, 0xffb19de7, 0xffafc584, 0xffadfbbe, 0xffac40b3, 0xffaa947c, 0xffa8f730, 0xffa768e6, 0xffa5e9b1, 0xffa479a2, 0xffa318c7, 0xffa1c72f, 0xffa084e3, 0xff9f51eb, 0xff9e2e50, 0xff9d1a14, 0xff9c1539, 0xff9b1fc1, 0xff9a39a9, 0xff9962ec, 0xff989b85, 0xff97e36c, 0xff973a96, 0xff96a0f8, 0xff961684, 0xff959b29, 0xff952ed7, 0xff94d178, 0xff9482f8, 0xff944340, 0xff941236, 0xff93efbf, 0xff93dbc0, 0xff93d618, 0xff93deaa, 0xff93f552, 0xff9419ef, 0xff944c5a, 0xff948c6e, 0xff94da03, 0xff9534f0, 0xff959d0a, 0xff961224, 0xff969412, 0xff9722a5, 0xff97bdac, 0xff9864f6, 0xff991851, 0xff99d789, 0xff9aa268, 0xff9b78ba, 0xff9c5a47, 0xff9d46d6, 0xff9e3e30, 0xff9f4019, 0xffa04c57, 0xffa162ae, 0xffa282e1, 0xffa3acb4, 0xffa4dfe8, 0xffa61c3e, 0xffa76176, 0xffa8af51, 0xffaa058d, 0xffab63ea, 0xffacca25, 0xffae37fd, 0xffafad2e, 0xffb12976, 0xffb2ac90, 0xffb4363a, 0xffb5c630, 0xffb75c2c, 0xffb8f7ea, 0xffba9927, 0xffbc3f9d, 0xffbdeb07, 0xffbf9b21, 0xffc14fa5, 0xffc3084f, 0xffc4c4da, 0xffc68502, 0xffc84881, 0xffca0f14, 0xffcbd876, 0xffcda463, 0xffcf7299, 0xffd142d3, 0xffd314cf, 0xffd4e84a, 0xffd6bd01, 0xffd892b4, 0xffda6921, 0xffdc4007, 0xffde1726, 0xffdfee3f, 0xffe1c511, 0xffe39b60, 0xffe570ed, 0xffe7457c, 0xffe918ce,
-        0xffeaeaab, 0xffecbad5, 0xffee8913, 0xfff0552d, 0xfff21ee8, 0xfff3e60f, 0xfff5aa69, 0xfff76bc2, 0xfff929e3, 0xfffae49b, 0xfffc9bb4, 0xfffe4efd, 0xfffffe46, 0x0001a95d, 0x00035015, 0x0004f23e, 0x00068fad, 0x00082835, 0x0009bbab, 0x000b49e6, 0x000cd2bd, 0x000e5609, 0x000fd3a3, 0x00114b67, 0x0012bd30, 0x001428db, 0x00158e47, 0x0016ed53, 0x001845e0, 0x001997d0, 0x001ae306, 0x001c2765, 0x001d64d5, 0x001e9b3a, 0x001fca7d, 0x0020f288, 0x00221344, 0x00232c9d, 0x00243e7f, 0x002548d9, 0x00264b9a, 0x002746b2, 0x00283a12, 0x002925ae, 0x002a0979, 0x002ae568, 0x002bb971, 0x002c858d, 0x002d49b4, 0x002e05df, 0x002eba0a, 0x002f6630, 0x00300a4f, 0x0030a665, 0x00313a72, 0x0031c677, 0x00324a74, 0x0032c66e, 0x00333a67, 0x0033a665, 0x00340a6d, 0x00346687, 0x0034babb, 0x00350711, 0x00354b94, 0x0035884f, 0x0035bd4e, 0x0035ea9d, 0x0036104b, 0x00362e66, 0x003644fd, 0x00365422, 0x00365be6, 0x00365c5b, 0x00365594, 0x003647a5, 0x003632a2, 0x003616a2, 0x0035f3b9, 0x0035ca00, 0x0035998d, 0x00356279, 0x003524dd, 0x0034e0d3, 0x00349674, 0x003445dc, 0x0033ef25, 0x0033926d, 0x00332fcf, 0x0032c769, 0x00325958, 0x0031e5ba, 0x00316cae, 0x0030ee53, 0x00306ac8, 0x002fe22c, 0x002f54a1, 0x002ec246, 0x002e2b3c, 0x002d8fa4, 0x002cefa1, 0x002c4b53, 0x002ba2dc, 0x002af65f, 0x002a45fe, 0x002991db, 0x0028da1a, 0x00281edd, 0x00276046, 0x00269e7a, 0x0025d99b, 0x002511cd, 0x00244733, 0x002379ef, 0x0022aa26, 0x0021d7fa, 0x00210390, 0x00202d09, 0x001f5489, 0x001e7a33, 0x001d9e2a, 0x001cc091, 0x001be18a, 0x001b0138, 0x001a1fbc, 0x00193d3a, 0x001859d2, 0x001775a7,
-        0x001690d9, 0x0015ab8b, 0x0014c5dc, 0x0013dfed, 0x0012f9de, 0x001213d0, 0x00112de1, 0x00104831, 0x000f62de, 0x000e7e08, 0x000d99cc, 0x000cb647, 0x000bd397, 0x000af1d9, 0x000a1129, 0x000931a3, 0x00085362, 0x00077681, 0x00069b1b, 0x0005c149, 0x0004e926, 0x000412c9, 0x00033e4c, 0x00026bc6, 0x00019b4e, 0x0000ccfc, 0x000000e6, 0xffff3721, 0xfffe6fc3, 0xfffdaadf, 0xfffce88b, 0xfffc28d9, 0xfffb6bdd, 0xfffab1a8, 0xfff9fa4d, 0xfff945dc, 0xfff89465, 0xfff7e5f9, 0xfff73aa7, 0xfff6927e, 0xfff5ed8b, 0xfff54bdc, 0xfff4ad7e, 0xfff4127d, 0xfff37ae4, 0xfff2e6bf, 0xfff25619, 0xfff1c8fa, 0xfff13f6c, 0xfff0b977, 0xfff03724, 0xffefb87a, 0xffef3d7f, 0xffeec63a, 0xffee52b1, 0xffede2e7, 0xffed76e3, 0xffed0ea7, 0xffecaa36, 0xffec4994, 0xffebecc2, 0xffeb93c3, 0xffeb3e96, 0xffeaed3c, 0xffea9fb6, 0xffea5602, 0xffea1020, 0xffe9ce0d, 0xffe98fc8, 0xffe9554c, 0xffe91e99, 0xffe8eba8, 0xffe8bc77, 0xffe89101, 0xffe8693f, 0xffe8452d, 0xffe824c5, 0xffe807ff, 0xffe7eed5, 0xffe7d93f, 0xffe7c735, 0xffe7b8af, 0xffe7ada5, 0xffe7a60d, 0xffe7a1de, 0xffe7a10d, 0xffe7a391, 0xffe7a95f, 0xffe7b26c, 0xffe7bead, 0xffe7ce16, 0xffe7e09c, 0xffe7f631, 0xffe80eca, 0xffe82a59, 0xffe848d3, 0xffe86a29, 0xffe88e4d, 0xffe8b532, 0xffe8decb, 0xffe90b08, 0xffe939db, 0xffe96b35, 0xffe99f08, 0xffe9d545, 0xffea0ddc, 0xffea48be, 0xffea85dc, 0xffeac525, 0xffeb068a, 0xffeb49fc, 0xffeb8f6a, 0xffebd6c4, 0xffec1ffa, 0xffec6afc, 0xffecb7b9, 0xffed0621, 0xffed5624, 0xffeda7b1, 0xffedfab8, 0xffee4f29, 0xffeea4f2, 0xffeefc04, 0xffef544e, 0xffefadc0, 0xfff00849, 0xfff063d9, 0xfff0c060,
-        0xfff11dcd, 0xfff17c10, 0xfff1db1a, 0xfff23ada, 0xfff29b40, 0xfff2fc3d, 0xfff35dc1, 0xfff3bfbc, 0xfff4221f, 0xfff484db, 0xfff4e7e1, 0xfff54b20, 0xfff5ae8c, 0xfff61214, 0xfff675ab, 0xfff6d942, 0xfff73ccb, 0xfff7a037, 0xfff8037a, 0xfff86686, 0xfff8c94c, 0xfff92bc0, 0xfff98dd6, 0xfff9ef80, 0xfffa50b1, 0xfffab15e, 0xfffb117a, 0xfffb70fa, 0xfffbcfd2, 0xfffc2df6, 0xfffc8b5c, 0xfffce7f8, 0xfffd43c1, 0xfffd9eab, 0xfffdf8ae, 0xfffe51be, 0xfffea9d2, 0xffff00e1, 0xffff56e3, 0xffffabcd, 0xffffff99, 0x0000523d, 0x0000a3b3, 0x0000f3f1, 0x000142f1, 0x000190ac, 0x0001dd1b, 0x00022837, 0x000271fa, 0x0002ba5f, 0x0003015f, 0x000346f6, 0x00038b1d, 0x0003cdd1, 0x00040f0d, 0x00044ecb, 0x00048d0a, 0x0004c9c4, 0x000504f6, 0x00053e9e, 0x000576b8, 0x0005ad41, 0x0005e238, 0x00061599, 0x00064764, 0x00067797, 0x0006a630, 0x0006d32f, 0x0006fe92, 0x00072859, 0x00075084, 0x00077712, 0x00079c04, 0x0007bf5b, 0x0007e116, 0x00080137, 0x00081fbf, 0x00083cb0, 0x0008580a, 0x000871cf, 0x00088a02, 0x0008a0a5, 0x0008b5ba, 0x0008c944, 0x0008db46, 0x0008ebc1, 0x0008fabb, 0x00090836, 0x00091435, 0x00091ebd, 0x000927d1, 0x00092f75, 0x000935ad, 0x00093a7f, 0x00093ded, 0x00093ffe, 0x000940b6, 0x00094019, 0x00093e2e, 0x00093af8, 0x0009367e, 0x000930c4, 0x000929d1, 0x000921aa, 0x00091854, 0x00090dd6, 0x00090236, 0x0008f57a, 0x0008e7a7, 0x0008d8c4, 0x0008c8d7, 0x0008b7e7, 0x0008a5fa, 0x00089316, 0x00087f43, 0x00086a86, 0x000854e6, 0x00083e6a, 0x00082718, 0x00080ef7, 0x0007f60f, 0x0007dc65, 0x0007c201, 0x0007a6e9, 0x00078b24, 0x00076eba, 0x000751b0, 0x0007340d,
-        0x000715d9, 0x0006f71a, 0x0006d7d7, 0x0006b817, 0x000697e0, 0x00067739, 0x00065629, 0x000634b6, 0x000612e8, 0x0005f0c4, 0x0005ce51, 0x0005ab95, 0x00058898, 0x0005655e, 0x000541f0, 0x00051e52, 0x0004fa8b, 0x0004d6a1, 0x0004b29a, 0x00048e7c, 0x00046a4c, 0x00044612, 0x000421d2, 0x0003fd92, 0x0003d957, 0x0003b527, 0x00039108, 0x00036cfe, 0x00034910, 0x00032541, 0x00030196, 0x0002de16, 0x0002bac4, 0x000297a5, 0x000274be, 0x00025214, 0x00022fa9, 0x00020d84, 0x0001eba8, 0x0001ca18, 0x0001a8da, 0x000187f0, 0x0001675f, 0x00014729, 0x00012754, 0x000107e1, 0x0000e8d4, 0x0000ca30, 0x0000abf8, 0x00008e30, 0x000070d9, 0x000053f7, 0x0000378c, 0x00001b9a, 0x00000024, 0xffffe52d, 0xffffcab5, 0xffffb0bf, 0xffff974d, 0xffff7e61, 0xffff65fc, 0xffff4e20, 0xffff36ce, 0xffff2007, 0xffff09ce, 0xfffef421, 0xfffedf04, 0xfffeca76, 0xfffeb678, 0xfffea30b, 0xfffe9030, 0xfffe7de7, 0xfffe6c2f, 0xfffe5b0b, 0xfffe4a79, 0xfffe3a79, 0xfffe2b0d, 0xfffe1c32, 0xfffe0dea, 0xfffe0034, 0xfffdf310, 0xfffde67c, 0xfffdda79, 0xfffdcf05, 0xfffdc421, 0xfffdb9cb, 0xfffdb002, 0xfffda6c5, 0xfffd9e13, 0xfffd95eb, 0xfffd8e4d, 0xfffd8735, 0xfffd80a4, 0xfffd7a98, 0xfffd750f, 0xfffd7008, 0xfffd6b81, 0xfffd6779, 0xfffd63ed, 0xfffd60dd, 0xfffd5e46, 0xfffd5c26, 0xfffd5a7c, 0xfffd5945, 0xfffd5880, 0xfffd582a, 0xfffd5842, 0xfffd58c5, 0xfffd59b2, 0xfffd5b05, 0xfffd5cbe, 0xfffd5ed8, 0xfffd6154, 0xfffd642d, 0xfffd6762, 0xfffd6af1, 0xfffd6ed6, 0xfffd7310, 0xfffd779d, 0xfffd7c7a, 0xfffd81a4, 0xfffd8719, 0xfffd8cd7, 0xfffd92db, 0xfffd9923, 0xfffd9fac, 0xfffda675, 0xfffdad79,
-        0xfffdb4b9, 0xfffdbc2f, 0xfffdc3db, 0xfffdcbba, 0xfffdd3ca, 0xfffddc07, 0xfffde470, 0xfffded03, 0xfffdf5bc, 0xfffdfe9b, 0xfffe079b, 0xfffe10bc, 0xfffe19fa, 0xfffe2354, 0xfffe2cc8, 0xfffe3652, 0xfffe3ff2, 0xfffe49a4, 0xfffe5367, 0xfffe5d38, 0xfffe6716, 0xfffe70ff, 0xfffe7aef, 0xfffe84e7, 0xfffe8ee3, 0xfffe98e2, 0xfffea2e1, 0xfffeacdf, 0xfffeb6db, 0xfffec0d2, 0xfffecac3, 0xfffed4ab, 0xfffede8a, 0xfffee85e, 0xfffef225, 0xfffefbde, 0xffff0587, 0xffff0f1f, 0xffff18a4, 0xffff2215, 0xffff2b70, 0xffff34b6, 0xffff3de3, 0xffff46f7, 0xffff4ff1, 0xffff58d0, 0xffff6192, 0xffff6a38, 0xffff72be, 0xffff7b26, 0xffff836d, 0xffff8b93, 0xffff9398, 0xffff9b7a, 0xffffa339, 0xffffaad3, 0xffffb249, 0xffffb99a, 0xffffc0c5, 0xffffc7ca, 0xffffcea8, 0xffffd55f, 0xffffdbee, 0xffffe255, 0xffffe894, 0xffffeeaa, 0xfffff498, 0xfffffa5d, 0xfffffff8, 0x0000056a, 0x00000ab3, 0x00000fd2, 0x000014c8, 0x00001994, 0x00001e37, 0x000022b1, 0x00002701, 0x00002b28, 0x00002f26, 0x000032fb, 0x000036a8, 0x00003a2d, 0x00003d89, 0x000040be, 0x000043cc, 0x000046b2, 0x00004972, 0x00004c0b, 0x00004e7f, 0x000050cd, 0x000052f7, 0x000054fc, 0x000056dd, 0x0000589b, 0x00005a36, 0x00005baf, 0x00005d06, 0x00005e3d, 0x00005f52, 0x00006048, 0x0000611f, 0x000061d8, 0x00006272, 0x000062f0, 0x00006351, 0x00006396, 0x000063c0, 0x000063d0, 0x000063c6, 0x000063a3, 0x00006368, 0x00006316, 0x000062ad, 0x0000622e, 0x0000619a, 0x000060f1, 0x00006035, 0x00005f66, 0x00005e84, 0x00005d92, 0x00005c8e, 0x00005b7b, 0x00005a58, 0x00005927, 0x000057e9, 0x0000569d, 0x00005545, 0x000053e2,
-        0x00000000
+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/test-resample.cpp b/services/audioflinger/test-resample.cpp
index 151313b..b082e8c 100644
--- a/services/audioflinger/test-resample.cpp
+++ b/services/audioflinger/test-resample.cpp
@@ -25,6 +25,7 @@
 #include <sys/stat.h>
 #include <errno.h>
 #include <time.h>
+#include <math.h>
 
 using namespace android;
 
@@ -61,31 +62,34 @@
 };
 
 static int usage(const char* name) {
-    fprintf(stderr,"Usage: %s [-p] [-h] [-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,"-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");
+    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, "phq:i:o:")) != -1) {
+    while ((ch = getopt(argc, argv, "phsq:i:o:")) != -1) {
         switch (ch) {
         case 'p':
             profiling = true;
@@ -93,6 +97,9 @@
         case 'h':
             writeHeader = true;
             break;
+        case 's':
+            channels = 2;
+            break;
         case 'q':
             if (!strcmp(optarg, "dq"))
                 quality = AudioResampler::DEFAULT_QUALITY;
@@ -105,7 +112,7 @@
             else if (!strcmp(optarg, "vhq"))
                 quality = AudioResampler::VERY_HIGH_QUALITY;
             else {
-                usage(argv[0]);
+                usage(progname);
                 return -1;
             }
             break;
@@ -117,54 +124,74 @@
             break;
         case '?':
         default:
-            usage(argv[0]);
+            usage(progname);
             return -1;
         }
     }
     argc -= optind;
+    argv += optind;
 
-    if (argc != 2) {
-        usage(argv[0]);
+    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;
     }
 
-    argv += optind;
-
     // ----------------------------------------------------------
 
-    struct stat st;
-    if (stat(argv[0], &st) < 0) {
-        fprintf(stderr, "stat: %s\n", strerror(errno));
-        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(argv[0], O_RDONLY);
-    if (input_fd < 0) {
-        fprintf(stderr, "open: %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;
+        }
 
-    size_t input_size = st.st_size;
-    void* 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;
+        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);
+            }
+        }
     }
 
-//    printf("input  sample rate: %d Hz\n", input_freq);
-//    printf("output sample rate: %d Hz\n", output_freq);
-//    printf("input mmap: %p, size=%u\n", input_vaddr, input_size);
-
     // ----------------------------------------------------------
 
     class Provider: public AudioBufferProvider {
         int16_t* mAddr;
         size_t mNumFrames;
     public:
-        Provider(const void* addr, size_t size) {
+        Provider(const void* addr, size_t size, int channels) {
             mAddr = (int16_t*) addr;
-            mNumFrames = size / sizeof(int16_t);
+            mNumFrames = size / (channels*sizeof(int16_t));
         }
         virtual status_t getNextBuffer(Buffer* buffer,
                 int64_t pts = kInvalidPTS) {
@@ -174,47 +201,61 @@
         }
         virtual void releaseBuffer(Buffer* buffer) {
         }
-    } provider(input_vaddr, input_size);
+    } provider(input_vaddr, input_size, channels);
 
-    size_t output_size = 2 * 2 * ((int64_t) input_size * output_freq)
-            / input_freq;
+    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);
-    memset(output_vaddr, 0, output_size);
-
-    AudioResampler* resampler = AudioResampler::create(16, 1, output_freq,
-            quality);
-
-    size_t out_frames = output_size/8;
-    resampler->setSampleRate(input_freq);
-    resampler->setVolume(0x1000, 0x1000);
-    resampler->resample((int*) output_vaddr, out_frames, &provider);
 
     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;
+        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 * sizeof(int16_t));
+    int16_t* convert = (int16_t*) malloc(out_frames * channels * sizeof(int16_t));
     for (size_t i = 0; i < out_frames; i++) {
-        int32_t s = out[i * 2] >> 12;
-        if (s > 32767)       s =  32767;
-        else if (s < -32768) s = -32768;
-        convert[i] = int16_t(s);
+        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(argv[1], O_WRONLY | O_CREAT | O_TRUNC,
+    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));
@@ -222,11 +263,11 @@
     }
 
     if (writeHeader) {
-        HeaderWav wav(out_frames*sizeof(int16_t), 1, output_freq, 16);
+        HeaderWav wav(out_frames * channels * sizeof(int16_t), channels, output_freq, 16);
         write(output_fd, &wav, sizeof(wav));
     }
 
-    write(output_fd, convert, out_frames * sizeof(int16_t));
+    write(output_fd, convert, out_frames * channels * sizeof(int16_t));
     close(output_fd);
 
     return 0;
diff --git a/tools/resampler_tools/fir.cpp b/tools/resampler_tools/fir.cpp
index ea3ef50..cc3d509 100644
--- a/tools/resampler_tools/fir.cpp
+++ b/tools/resampler_tools/fir.cpp
@@ -195,7 +195,8 @@
 
 
     // total number of coefficients (one side)
-    const int N = (1 << nz) * nzc;
+    const int M = (1 << nz);
+    const int N = M * nzc;
 
     // generate the right half of the filter
     if (!debug) {
@@ -220,22 +221,25 @@
     }
 
     if (!polyphase) {
-        for (int i=0 ; i<N ; i++) {
-            double x = (2.0 * M_PI * i * Fcr) / (1 << nz);
-            double y = kaiser(i+N, 2*N, beta) * sinc(x) * 2.0 * Fcr;
-            y *= atten;
+        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 ((i % (1<<nz)) == 0)
-                    printf("\n    ");
-            }
+                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,");
+                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 {
@@ -266,11 +270,6 @@
     }
 
     if (!debug) {
-        if (!format) {
-            printf("\n    0x%08x ", 0);
-        } else {
-            printf("\n    %.9g ", 0.0f);
-        }
         printf("\n};");
     }
     printf("\n");