summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CleanSpec.mk52
-rw-r--r--camera/CameraParameters.cpp5
-rw-r--r--cmds/stagefright/Android.mk8
-rw-r--r--cmds/stagefright/stagefright.cpp6
-rw-r--r--include/camera/CameraParameters.h10
-rw-r--r--include/media/AudioRecord.h92
-rw-r--r--include/media/AudioSystem.h42
-rw-r--r--include/media/AudioTrack.h124
-rw-r--r--include/media/EffectsFactoryApi.h18
-rw-r--r--include/media/IAudioFlinger.h17
-rw-r--r--include/media/IAudioPolicyService.h5
-rw-r--r--include/media/SoundPool.h6
-rw-r--r--include/media/ToneGenerator.h2
-rw-r--r--include/media/nbaio/NBAIO.h14
-rw-r--r--include/media/stagefright/MediaDefs.h1
-rw-r--r--include/private/media/AudioTrackShared.h80
-rwxr-xr-xlibvideoeditor/lvpp/Android.mk1
-rwxr-xr-xlibvideoeditor/lvpp/VideoEditorPlayer.cpp4
-rw-r--r--media/libeffects/downmix/Android.mk2
-rw-r--r--media/libeffects/downmix/EffectDownmix.c23
-rw-r--r--media/libeffects/downmix/EffectDownmix.h3
-rw-r--r--media/libeffects/lvm/lib/Android.mk9
-rw-r--r--media/libeffects/lvm/wrapper/Android.mk11
-rw-r--r--media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp40
-rw-r--r--[-rwxr-xr-x]media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp28
-rw-r--r--[-rwxr-xr-x]media/libeffects/preprocessing/Android.mk2
-rw-r--r--[-rwxr-xr-x]media/libeffects/preprocessing/PreProcessing.cpp28
-rw-r--r--media/libeffects/testlibs/EffectEqualizer.cpp19
-rw-r--r--media/libeffects/testlibs/EffectReverb.c19
-rw-r--r--media/libeffects/testlibs/EffectReverb.h3
-rw-r--r--media/libeffects/visualizer/Android.mk2
-rw-r--r--media/libeffects/visualizer/EffectVisualizer.cpp22
-rw-r--r--media/libmedia/Android.mk2
-rw-r--r--media/libmedia/AudioEffect.cpp21
-rw-r--r--media/libmedia/AudioRecord.cpp163
-rw-r--r--media/libmedia/AudioSystem.cpp44
-rw-r--r--media/libmedia/AudioTrack.cpp459
-rw-r--r--media/libmedia/IAudioFlinger.cpp38
-rw-r--r--media/libmedia/IAudioFlingerClient.cpp3
-rw-r--r--media/libmedia/IAudioPolicyService.cpp9
-rw-r--r--media/libmedia/SoundPool.cpp4
-rw-r--r--media/libmedia/ToneGenerator.cpp2
-rw-r--r--media/libmedia/Visualizer.cpp6
-rw-r--r--media/libmedia_native/Android.mk11
-rw-r--r--media/libmediaplayerservice/Android.mk1
-rw-r--r--media/libmediaplayerservice/MediaPlayerService.cpp4
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayer.cpp2
-rw-r--r--media/libnbaio/NBAIO.cpp124
-rw-r--r--media/libstagefright/ACodec.cpp2
-rw-r--r--media/libstagefright/Android.mk1
-rw-r--r--media/libstagefright/AudioSource.cpp2
-rw-r--r--[-rwxr-xr-x]media/libstagefright/CameraSource.cpp0
-rw-r--r--[-rwxr-xr-x]media/libstagefright/MPEG4Writer.cpp0
-rw-r--r--media/libstagefright/MediaDefs.cpp1
-rw-r--r--[-rwxr-xr-x]media/libstagefright/OMXCodec.cpp2
-rw-r--r--[-rwxr-xr-x]media/libstagefright/SkipCutBuffer.cpp0
-rw-r--r--media/libstagefright/StagefrightMediaScanner.cpp2
-rw-r--r--media/libstagefright/ThrottledSource.cpp12
-rw-r--r--media/libstagefright/WAVExtractor.cpp61
-rw-r--r--media/libstagefright/codecs/gsm/Android.mk4
-rw-r--r--media/libstagefright/codecs/gsm/dec/Android.mk21
-rw-r--r--media/libstagefright/codecs/gsm/dec/MODULE_LICENSE_APACHE20
-rw-r--r--media/libstagefright/codecs/gsm/dec/NOTICE190
-rw-r--r--media/libstagefright/codecs/gsm/dec/SoftGSM.cpp269
-rw-r--r--media/libstagefright/codecs/gsm/dec/SoftGSM.h65
-rw-r--r--media/libstagefright/codecs/on2/dec/SoftVPX.cpp2
-rw-r--r--media/libstagefright/include/FragmentedMP4Parser.h2
-rw-r--r--media/libstagefright/include/ThrottledSource.h36
-rw-r--r--media/libstagefright/matroska/MatroskaExtractor.cpp74
-rw-r--r--media/libstagefright/mp4/FragmentedMP4Parser.cpp4
-rw-r--r--media/libstagefright/omx/SoftOMXPlugin.cpp1
-rw-r--r--media/libstagefright/wifi-display/sink/TunnelRenderer.cpp5
-rw-r--r--media/libstagefright/wifi-display/sink/WifiDisplaySink.cpp7
-rw-r--r--services/audioflinger/Android.mk33
-rw-r--r--services/audioflinger/AudioFlinger.cpp603
-rw-r--r--services/audioflinger/AudioFlinger.h146
-rw-r--r--services/audioflinger/AudioMixer.cpp56
-rw-r--r--services/audioflinger/AudioMixer.h33
-rw-r--r--services/audioflinger/AudioPolicyService.cpp5
-rw-r--r--services/audioflinger/AudioPolicyService.h10
-rw-r--r--services/audioflinger/AudioResampler.cpp4
-rw-r--r--services/audioflinger/AudioResamplerSinc.cpp659
-rw-r--r--services/audioflinger/AudioResamplerSinc.h13
-rw-r--r--services/audioflinger/StateQueue.h68
-rw-r--r--services/audioflinger/audio-resampler/AudioResamplerCoefficients.cpp29
-rw-r--r--services/audioflinger/audio-resampler/dnsampler_filter_coefficients_x128_10112011.h2585
-rw-r--r--services/audioflinger/audio-resampler/filter_coefficients.h285
-rw-r--r--services/audioflinger/audio-resampler/resampler_filter_coefficients_10042011.h2071
-rw-r--r--services/audioflinger/test-resample.cpp274
-rw-r--r--services/camera/libcameraservice/Android.mk4
-rw-r--r--services/camera/libcameraservice/Camera2Client.cpp15
-rw-r--r--services/camera/libcameraservice/Camera2Device.cpp14
-rw-r--r--services/camera/libcameraservice/CameraClient.cpp4
-rw-r--r--services/camera/libcameraservice/CameraHardwareInterface.h5
-rw-r--r--services/camera/libcameraservice/camera2/BurstCapture.cpp9
-rw-r--r--services/camera/libcameraservice/camera2/CallbackProcessor.cpp4
-rw-r--r--services/camera/libcameraservice/camera2/CaptureSequencer.cpp14
-rw-r--r--services/camera/libcameraservice/camera2/FrameProcessor.cpp5
-rw-r--r--services/camera/libcameraservice/camera2/JpegCompressor.cpp6
-rw-r--r--services/camera/libcameraservice/camera2/JpegProcessor.cpp5
-rw-r--r--services/camera/libcameraservice/camera2/Parameters.cpp19
-rw-r--r--services/camera/libcameraservice/camera2/Parameters.h2
-rw-r--r--services/camera/libcameraservice/camera2/StreamingProcessor.cpp3
-rw-r--r--services/camera/libcameraservice/camera2/ZslProcessor.cpp5
-rw-r--r--tools/resampler_tools/fir.cpp264
105 files changed, 3500 insertions, 6106 deletions
diff --git a/CleanSpec.mk b/CleanSpec.mk
new file mode 100644
index 0000000..e6d9ebf
--- /dev/null
+++ b/CleanSpec.mk
@@ -0,0 +1,52 @@
+# Copyright (C) 2012 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# If you don't need to do a full clean build but would like to touch
+# a file or delete some intermediate files, add a clean step to the end
+# of the list. These steps will only be run once, if they haven't been
+# run before.
+#
+# E.g.:
+# $(call add-clean-step, touch -c external/sqlite/sqlite3.h)
+# $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libz_intermediates)
+#
+# Always use "touch -c" and "rm -f" or "rm -rf" to gracefully deal with
+# files that are missing or have been moved.
+#
+# Use $(PRODUCT_OUT) to get to the "out/target/product/blah/" directory.
+# Use $(OUT_DIR) to refer to the "out" directory.
+#
+# If you need to re-do something that's already mentioned, just copy
+# the command and add it to the bottom of the list. E.g., if a change
+# that you made last week required touching a file and a change you
+# made today requires touching the same file, just copy the old
+# touch step and add it to the end of the list.
+#
+# ************************************************
+# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
+# ************************************************
+
+# For example:
+#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/AndroidTests_intermediates)
+#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/core_intermediates)
+#$(call add-clean-step, find $(OUT_DIR) -type f -name "IGTalkSession*" -print0 | xargs -0 rm -f)
+#$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libmedia_native_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/lib/libmedia_native.so)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/symbols/system/lib/libmedia_native.so)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/libmedia_native.so)
+# ************************************************
+# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
+# ************************************************
diff --git a/camera/CameraParameters.cpp b/camera/CameraParameters.cpp
index fd91bf2..d10f2e5 100644
--- a/camera/CameraParameters.cpp
+++ b/camera/CameraParameters.cpp
@@ -90,6 +90,7 @@ const char CameraParameters::KEY_RECORDING_HINT[] = "recording-hint";
const char CameraParameters::KEY_VIDEO_SNAPSHOT_SUPPORTED[] = "video-snapshot-supported";
const char CameraParameters::KEY_VIDEO_STABILIZATION[] = "video-stabilization";
const char CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED[] = "video-stabilization-supported";
+const char CameraParameters::KEY_LIGHTFX[] = "light-fx";
const char CameraParameters::TRUE[] = "true";
const char CameraParameters::FALSE[] = "false";
@@ -167,6 +168,10 @@ const char CameraParameters::FOCUS_MODE_EDOF[] = "edof";
const char CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO[] = "continuous-video";
const char CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE[] = "continuous-picture";
+// Values for light fx settings
+const char CameraParameters::LIGHTFX_LOWLIGHT[] = "low-light";
+const char CameraParameters::LIGHTFX_HDR[] = "high-dynamic-range";
+
CameraParameters::CameraParameters()
: mMap()
{
diff --git a/cmds/stagefright/Android.mk b/cmds/stagefright/Android.mk
index 1247588..f60b1a4 100644
--- a/cmds/stagefright/Android.mk
+++ b/cmds/stagefright/Android.mk
@@ -8,7 +8,7 @@ LOCAL_SRC_FILES:= \
SineSource.cpp
LOCAL_SHARED_LIBRARIES := \
- libstagefright libmedia libmedia_native libutils libbinder libstagefright_foundation \
+ libstagefright libmedia libutils libbinder libstagefright_foundation \
libjpeg libgui
LOCAL_C_INCLUDES:= \
@@ -104,7 +104,7 @@ LOCAL_SRC_FILES:= \
LOCAL_SHARED_LIBRARIES := \
libstagefright liblog libutils libbinder libgui \
- libstagefright_foundation libmedia libmedia_native libcutils
+ libstagefright_foundation libmedia libcutils
LOCAL_C_INCLUDES:= \
frameworks/av/media/libstagefright \
@@ -127,7 +127,7 @@ LOCAL_SRC_FILES:= \
LOCAL_SHARED_LIBRARIES := \
libstagefright liblog libutils libbinder libstagefright_foundation \
- libmedia libmedia_native libgui libcutils libui
+ libmedia libgui libcutils libui
LOCAL_C_INCLUDES:= \
frameworks/av/media/libstagefright \
@@ -151,7 +151,7 @@ LOCAL_SRC_FILES:= \
LOCAL_SHARED_LIBRARIES := \
libstagefright liblog libutils libbinder libstagefright_foundation \
- libmedia libmedia_native libgui libcutils libui
+ libmedia libgui libcutils libui
LOCAL_C_INCLUDES:= \
frameworks/av/media/libstagefright \
diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp
index b92a8a0..1e0e7f8 100644
--- a/cmds/stagefright/stagefright.cpp
+++ b/cmds/stagefright/stagefright.cpp
@@ -589,7 +589,7 @@ static void performSeekTest(const sp<MediaSource> &source) {
}
static void usage(const char *me) {
- fprintf(stderr, "usage: %s\n", me);
+ fprintf(stderr, "usage: %s [options] [input_filename]\n", me);
fprintf(stderr, " -h(elp)\n");
fprintf(stderr, " -a(udio)\n");
fprintf(stderr, " -n repetitions\n");
@@ -607,8 +607,8 @@ static void usage(const char *me) {
"(video only)\n");
fprintf(stderr, " -S allocate buffers from a surface\n");
fprintf(stderr, " -T allocate buffers from a surface texture\n");
- fprintf(stderr, " -d(ump) filename (raw stream data to a file)\n");
- fprintf(stderr, " -D(ump) filename (decoded PCM data to a file)\n");
+ fprintf(stderr, " -d(ump) output_filename (raw stream data to a file)\n");
+ fprintf(stderr, " -D(ump) output_filename (decoded PCM data to a file)\n");
}
static void dumpCodecProfiles(const sp<IOMX>& omx, bool queryDecoders) {
diff --git a/include/camera/CameraParameters.h b/include/camera/CameraParameters.h
index 5540d32..d521543 100644
--- a/include/camera/CameraParameters.h
+++ b/include/camera/CameraParameters.h
@@ -525,6 +525,10 @@ public:
// stream and record stabilized videos.
static const char KEY_VIDEO_STABILIZATION_SUPPORTED[];
+ // Supported modes for special effects with light.
+ // Example values: "lowlight,hdr".
+ static const char KEY_LIGHTFX[];
+
// Value for KEY_ZOOM_SUPPORTED or KEY_SMOOTH_ZOOM_SUPPORTED.
static const char TRUE[];
static const char FALSE[];
@@ -664,6 +668,12 @@ public:
// other modes.
static const char FOCUS_MODE_CONTINUOUS_PICTURE[];
+ // Values for light special effects
+ // Low-light enhancement mode
+ static const char LIGHTFX_LOWLIGHT[];
+ // High-dynamic range mode
+ static const char LIGHTFX_HDR[];
+
private:
DefaultKeyedVector<String8,String8> mMap;
};
diff --git a/include/media/AudioRecord.h b/include/media/AudioRecord.h
index 156c592..cd7ff92 100644
--- a/include/media/AudioRecord.h
+++ b/include/media/AudioRecord.h
@@ -43,46 +43,43 @@ public:
*/
enum event_type {
EVENT_MORE_DATA = 0, // Request to read more data from PCM buffer.
- EVENT_OVERRUN = 1, // PCM buffer overrun occured.
+ EVENT_OVERRUN = 1, // PCM buffer overrun occurred.
EVENT_MARKER = 2, // Record head is at the specified marker position
// (See setMarkerPosition()).
EVENT_NEW_POS = 3, // Record head is at a new position
// (See setPositionUpdatePeriod()).
};
- /* Create Buffer on the stack and pass it to obtainBuffer()
- * and releaseBuffer().
+ /* Client should declare Buffer on the stack and pass address to obtainBuffer()
+ * and releaseBuffer(). See also callback_t for EVENT_MORE_DATA.
*/
class Buffer
{
public:
- enum {
- MUTE = 0x00000001
- };
- uint32_t flags;
- int channelCount;
- audio_format_t format;
- size_t frameCount;
+ 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
+
size_t size; // total size in bytes == frameCount * frameSize
union {
void* raw;
- short* i16;
- int8_t* i8;
+ short* i16; // signed 16-bit
+ int8_t* i8; // unsigned 8-bit, offset by 0x80
};
};
/* As a convenience, if a callback is supplied, a handler thread
* is automatically created with the appropriate priority. This thread
- * invokes the callback when a new buffer becomes ready or an overrun condition occurs.
+ * invokes the callback when a new buffer becomes ready or various conditions occur.
* Parameters:
*
* event: type of event notified (see enum AudioRecord::event_type).
* user: Pointer to context for use by the callback receiver.
* info: Pointer to optional parameter according to event type:
* - EVENT_MORE_DATA: pointer to AudioRecord::Buffer struct. The callback must not read
- * more bytes than indicated by 'size' field and update 'size' if less bytes are
- * read.
+ * more bytes than indicated by 'size' field and update 'size' if fewer bytes are
+ * consumed.
* - EVENT_OVERRUN: unused.
* - EVENT_MARKER: pointer to const uint32_t containing the marker position in frames.
* - EVENT_NEW_POS: pointer to const uint32_t containing the new position in frames.
@@ -98,7 +95,7 @@ public:
* - BAD_VALUE: unsupported configuration
*/
- static status_t getMinFrameCount(int* frameCount,
+ static status_t getMinFrameCount(size_t* frameCount,
uint32_t sampleRate,
audio_format_t format,
audio_channel_mask_t channelMask);
@@ -108,7 +105,7 @@ public:
*/
AudioRecord();
- /* Creates an AudioRecord track and registers it with AudioFlinger.
+ /* Creates an AudioRecord object and registers it with AudioFlinger.
* Once created, the track needs to be started before it can be used.
* Unspecified values are set to the audio hardware's current
* values.
@@ -120,10 +117,13 @@ public:
* format: Audio format (e.g AUDIO_FORMAT_PCM_16_BIT for signed
* 16 bits per sample).
* channelMask: Channel mask.
- * frameCount: Total size of track PCM buffer in frames. This defines the
- * latency of the track.
+ * frameCount: Minimum size of track PCM buffer in frames. This defines the
+ * application's contribution to the
+ * latency of the track. The actual size selected by the AudioRecord could
+ * be larger if the requested size is not compatible with current audio HAL
+ * latency. Zero means to use a default value.
* cbf: Callback function. If not null, this function is called periodically
- * to provide new PCM data.
+ * to consume new PCM data.
* user: Context for use by the callback receiver.
* notificationFrames: The callback function is called each time notificationFrames PCM
* frames are ready in record track output buffer.
@@ -154,7 +154,7 @@ public:
* - BAD_VALUE: invalid parameter (channels, format, sampleRate...)
* - NO_INIT: audio server or audio hardware not initialized
* - PERMISSION_DENIED: recording is not allowed for the requesting process
- * */
+ */
status_t set(audio_source_t inputSource = AUDIO_SOURCE_DEFAULT,
uint32_t sampleRate = 0,
audio_format_t format = AUDIO_FORMAT_DEFAULT,
@@ -168,14 +168,14 @@ public:
/* Result of constructing the AudioRecord. This must be checked
- * before using any AudioRecord API (except for set()), using
+ * before using any AudioRecord API (except for set()), because using
* an uninitialized AudioRecord produces undefined results.
* See set() method above for possible return codes.
*/
status_t initCheck() const;
- /* Returns this track's latency in milliseconds.
- * This includes the latency due to AudioRecord buffer size
+ /* Returns this track's estimated latency in milliseconds.
+ * This includes the latency due to AudioRecord buffer size,
* and audio hardware driver.
*/
uint32_t latency() const;
@@ -184,14 +184,14 @@ public:
audio_format_t format() const;
int channelCount() const;
- uint32_t frameCount() const;
- size_t frameSize() const;
+ size_t frameCount() const;
+ size_t frameSize() const { return mFrameSize; }
audio_source_t inputSource() const;
/* After it's created the track is not active. Call start() to
* make it active. If set, the callback will start being called.
- * if event is not AudioSystem::SYNC_EVENT_NONE, the capture start will be delayed until
+ * If event is not AudioSystem::SYNC_EVENT_NONE, the capture start will be delayed until
* the specified event occurs on the specified trigger session.
*/
status_t start(AudioSystem::sync_event_t event = AudioSystem::SYNC_EVENT_NONE,
@@ -199,12 +199,12 @@ public:
/* Stop a track. If set, the callback will cease being called and
* obtainBuffer returns STOPPED. Note that obtainBuffer() still works
- * and will fill up buffers until the pool is exhausted.
+ * and will drain buffers until the pool is exhausted.
*/
void stop();
bool stopped() const;
- /* get sample rate for this record track
+ /* Get sample rate for this record track in Hz.
*/
uint32_t getSampleRate() const;
@@ -258,7 +258,7 @@ public:
*/
status_t getPosition(uint32_t *position) const;
- /* returns a handle on the audio input used by this AudioRecord.
+ /* Returns a handle on the audio input used by this AudioRecord.
*
* Parameters:
* none.
@@ -268,7 +268,7 @@ public:
*/
audio_io_handle_t getInput() const;
- /* returns the audio session ID associated with this AudioRecord.
+ /* Returns the audio session ID associated with this AudioRecord.
*
* Parameters:
* none.
@@ -278,22 +278,30 @@ public:
*/
int getSessionId() const;
- /* obtains a buffer of "frameCount" frames. The buffer must be
- * filled entirely. If the track is stopped, obtainBuffer() returns
+ /* Obtains a buffer of "frameCount" frames. The buffer must be
+ * drained entirely, and then released with releaseBuffer().
+ * If the track is stopped, obtainBuffer() returns
* STOPPED instead of NO_ERROR as long as there are buffers available,
* at which point NO_MORE_BUFFERS is returned.
- * Buffers will be returned until the pool (buffercount())
+ * Buffers will be returned until the pool
* is exhausted, at which point obtainBuffer() will either block
* or return WOULD_BLOCK depending on the value of the "blocking"
* parameter.
+ *
+ * Interpretation of waitCount:
+ * +n limits wait time to n * WAIT_PERIOD_MS,
+ * -1 causes an (almost) infinite wait time,
+ * 0 non-blocking.
*/
enum {
- NO_MORE_BUFFERS = 0x80000001,
+ NO_MORE_BUFFERS = 0x80000001, // same name in AudioFlinger.h, ok to be different value
STOPPED = 1
};
status_t obtainBuffer(Buffer* audioBuffer, int32_t waitCount);
+
+ /* Release an emptied buffer of "frameCount" frames for AudioFlinger to re-fill. */
void releaseBuffer(Buffer* audioBuffer);
@@ -302,16 +310,16 @@ public:
*/
ssize_t read(void* buffer, size_t size);
- /* Return the amount of input frames lost in the audio driver since the last call of this
+ /* Return the number of input frames lost in the audio driver since the last call of this
* function. Audio driver is expected to reset the value to 0 and restart counting upon
* returning the current value by this function call. Such loss typically occurs when the
* user space process is blocked longer than the capacity of audio driver buffers.
- * Unit: the number of input audio frames
+ * Units: the number of input audio frames.
*/
unsigned int getInputFramesLost() const;
private:
- /* copying audio tracks is not allowed */
+ /* copying audio record objects is not allowed */
AudioRecord(const AudioRecord& other);
AudioRecord& operator = (const AudioRecord& other);
@@ -344,7 +352,7 @@ private:
status_t openRecord_l(uint32_t sampleRate,
audio_format_t format,
audio_channel_mask_t channelMask,
- int frameCount,
+ size_t frameCount,
audio_io_handle_t input);
audio_io_handle_t getInput_l();
status_t restoreRecord_l(audio_track_cblk_t*& cblk);
@@ -355,7 +363,7 @@ private:
bool mActive; // protected by mLock
// for client callback handler
- callback_t mCbf;
+ callback_t mCbf; // callback handler for events, or NULL
void* mUserData;
// for notification APIs
@@ -367,9 +375,10 @@ private:
uint32_t mUpdatePeriod; // in ms
// constant after constructor or set()
- uint32_t mFrameCount;
+ size_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;
@@ -381,6 +390,7 @@ private:
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 49e1afc..126ef12 100644
--- a/include/media/AudioSystem.h
+++ b/include/media/AudioSystem.h
@@ -87,29 +87,26 @@ public:
static float linearToLog(int volume);
static int logToLinear(float volume);
- static status_t getOutputSamplingRate(int* samplingRate, audio_stream_type_t stream = AUDIO_STREAM_DEFAULT);
- static status_t getOutputFrameCount(int* frameCount, audio_stream_type_t stream = AUDIO_STREAM_DEFAULT);
- static status_t getOutputLatency(uint32_t* latency, audio_stream_type_t stream = AUDIO_STREAM_DEFAULT);
+ static status_t getOutputSamplingRate(uint32_t* samplingRate,
+ audio_stream_type_t stream = AUDIO_STREAM_DEFAULT);
+ static status_t getOutputFrameCount(size_t* frameCount,
+ audio_stream_type_t stream = AUDIO_STREAM_DEFAULT);
+ static status_t getOutputLatency(uint32_t* latency,
+ 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,
audio_stream_type_t stream,
- int* frameCount);
+ size_t* frameCount);
// returns the audio output stream latency in ms. Corresponds to
// audio_stream_out->get_latency()
static status_t getLatency(audio_io_handle_t output,
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,
@@ -126,10 +123,11 @@ public:
// - BAD_VALUE: invalid parameter
// NOTE: this feature is not supported on all hardware platforms and it is
// necessary to check returned status before using the returned values.
- static status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames, audio_stream_type_t stream = AUDIO_STREAM_DEFAULT);
+ static status_t getRenderPosition(size_t *halFrames, size_t *dspFrames,
+ audio_stream_type_t stream = AUDIO_STREAM_DEFAULT);
// return the number of input frames lost by HAL implementation, or 0 if the handle is invalid
- static unsigned int getInputFramesLost(audio_io_handle_t ioHandle);
+ static size_t getInputFramesLost(audio_io_handle_t ioHandle);
static int newAudioSessionId();
static void acquireAudioSessionId(int audioSession);
@@ -147,8 +145,8 @@ public:
NUM_CONFIG_EVENTS
};
- // audio output descriptor used to cache output configurations in client process to avoid frequent calls
- // through IAudioFlinger
+ // audio output descriptor used to cache output configurations in client process to avoid
+ // frequent calls through IAudioFlinger
class OutputDescriptor {
public:
OutputDescriptor()
@@ -162,8 +160,8 @@ public:
};
// Events used to synchronize actions between audio sessions.
- // For instance SYNC_EVENT_PRESENTATION_COMPLETE can be used to delay recording start until playback
- // is complete on another audio session.
+ // For instance SYNC_EVENT_PRESENTATION_COMPLETE can be used to delay recording start until
+ // playback is complete on another audio session.
// See definitions in MediaSyncEvent.java
enum sync_event_t {
SYNC_EVENT_SAME = -1, // used internally to indicate restart with same event
@@ -183,8 +181,10 @@ public:
//
// IAudioPolicyService interface (see AudioPolicyInterface for method descriptions)
//
- static status_t setDeviceConnectionState(audio_devices_t device, audio_policy_dev_state_t state, const char *device_address);
- static audio_policy_dev_state_t getDeviceConnectionState(audio_devices_t device, const char *device_address);
+ static status_t setDeviceConnectionState(audio_devices_t device, audio_policy_dev_state_t state,
+ const char *device_address);
+ static audio_policy_dev_state_t getDeviceConnectionState(audio_devices_t device,
+ const char *device_address);
static status_t setPhoneState(audio_mode_t state);
static status_t setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config);
static audio_policy_forced_cfg_t getForceUse(audio_policy_force_use_t usage);
@@ -237,8 +237,8 @@ public:
static const sp<IAudioPolicyService>& get_audio_policy_service();
// helpers for android.media.AudioManager.getProperty(), see description there for meaning
- static int32_t getPrimaryOutputSamplingRate();
- static int32_t getPrimaryOutputFrameCount();
+ static uint32_t getPrimaryOutputSamplingRate();
+ static size_t getPrimaryOutputFrameCount();
// ----------------------------------------------------------------------------
diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h
index 34108b3..f1b26b5 100644
--- a/include/media/AudioTrack.h
+++ b/include/media/AudioTrack.h
@@ -49,13 +49,17 @@ public:
};
/* Events used by AudioTrack callback function (audio_track_cblk_t).
+ * Keep in sync with frameworks/base/media/java/android/media/AudioTrack.java NATIVE_EVENT_*.
*/
enum event_type {
EVENT_MORE_DATA = 0, // Request to write more data to PCM buffer.
- EVENT_UNDERRUN = 1, // PCM buffer underrun occured.
- EVENT_LOOP_END = 2, // Sample loop end was reached; playback restarted from loop start if loop count was not 0.
- EVENT_MARKER = 3, // Playback head is at the specified marker position (See setMarkerPosition()).
- EVENT_NEW_POS = 4, // Playback head is at a new position (See setPositionUpdatePeriod()).
+ EVENT_UNDERRUN = 1, // PCM buffer underrun occurred.
+ EVENT_LOOP_END = 2, // Sample loop end was reached; playback restarted from
+ // loop start if loop count was not 0.
+ EVENT_MARKER = 3, // Playback head is at the specified marker position
+ // (See setMarkerPosition()).
+ EVENT_NEW_POS = 4, // Playback head is at a new position
+ // (See setPositionUpdatePeriod()).
EVENT_BUFFER_END = 5 // Playback head is at the end of the buffer.
};
@@ -66,14 +70,6 @@ public:
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
@@ -114,7 +110,7 @@ public:
* - NO_INIT: audio server or audio hardware not initialized
*/
- static status_t getMinFrameCount(int* frameCount,
+ static status_t getMinFrameCount(size_t* frameCount,
audio_stream_type_t streamType = AUDIO_STREAM_DEFAULT,
uint32_t sampleRate = 0);
@@ -123,7 +119,7 @@ public:
*/
AudioTrack();
- /* Creates an audio track and registers it with AudioFlinger.
+ /* Creates an AudioTrack object and registers it with AudioFlinger.
* Once created, the track needs to be started before it can be used.
* Unspecified values are set to the audio hardware's current
* values.
@@ -137,12 +133,13 @@ public:
* 16 bits per sample).
* channelMask: Channel mask.
* frameCount: Minimum size of track PCM buffer in frames. This defines the
+ * application's contribution to the
* latency of the track. The actual size selected by the AudioTrack could be
* larger if the requested size is not compatible with current audio HAL
* latency. Zero means to use a default value.
* flags: See comments on audio_output_flags_t in <system/audio.h>.
* cbf: Callback function. If not null, this function is called periodically
- * to request new PCM data.
+ * to provide new PCM data.
* user: Context for use by the callback receiver.
* notificationFrames: The callback function is called each time notificationFrames PCM
* frames have been consumed from track input buffer.
@@ -162,18 +159,6 @@ public:
int notificationFrames = 0,
int sessionId = 0);
- // DEPRECATED
- explicit AudioTrack( int streamType,
- uint32_t sampleRate = 0,
- int format = AUDIO_FORMAT_DEFAULT,
- int channelMask = 0,
- int frameCount = 0,
- uint32_t flags = (uint32_t) AUDIO_OUTPUT_FLAG_NONE,
- callback_t cbf = 0,
- void* user = 0,
- int notificationFrames = 0,
- int sessionId = 0);
-
/* Creates an audio track and registers it with AudioFlinger. With this constructor,
* the PCM data to be rendered by AudioTrack is passed in a shared memory buffer
* identified by the argument sharedBuffer. This prototype is for static buffer playback.
@@ -206,7 +191,7 @@ public:
* - INVALID_OPERATION: AudioTrack is already initialized
* - BAD_VALUE: invalid parameter (channelMask, format, sampleRate...)
* - NO_INIT: audio server or audio hardware not initialized
- * */
+ */
status_t set(audio_stream_type_t streamType = AUDIO_STREAM_DEFAULT,
uint32_t sampleRate = 0,
audio_format_t format = AUDIO_FORMAT_DEFAULT,
@@ -244,7 +229,7 @@ public:
/* 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();
@@ -280,9 +265,14 @@ public:
/* 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.
@@ -290,9 +280,11 @@ public:
status_t setAuxEffectSendLevel(float level);
void getAuxEffectSendLevel(float* level) const;
- /* Set sample rate for this track, mostly used for games' sound effects
+ /* 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.
@@ -312,7 +304,8 @@ public:
/* Sets marker position. When playback reaches the number of frames specified, a callback with
* event type EVENT_MARKER is called. Calling setMarkerPosition with marker == 0 cancels marker
* notification callback.
- * If the AudioTrack has been opened with no callback function associated, the operation will fail.
+ * If the AudioTrack has been opened with no callback function associated, the operation will
+ * fail.
*
* Parameters:
*
@@ -330,7 +323,8 @@ public:
* a callback with event type EVENT_NEW_POS is called.
* Calling setPositionUpdatePeriod with updatePeriod == 0 cancels new position notification
* callback.
- * If the AudioTrack has been opened with no callback function associated, the operation will fail.
+ * If the AudioTrack has been opened with no callback function associated, the operation will
+ * fail.
*
* Parameters:
*
@@ -359,7 +353,8 @@ public:
* Returned status (from utils/Errors.h) can be:
* - NO_ERROR: successful operation
* - INVALID_OPERATION: the AudioTrack is not stopped.
- * - BAD_VALUE: The specified position is beyond the number of frames present in AudioTrack buffer
+ * - BAD_VALUE: The specified position is beyond the number of frames present in AudioTrack
+ * buffer
*/
status_t setPosition(uint32_t position);
status_t getPosition(uint32_t *position);
@@ -413,7 +408,7 @@ public:
* If the track is stopped, obtainBuffer() returns
* STOPPED instead of NO_ERROR as long as there are buffers available,
* at which point NO_MORE_BUFFERS is returned.
- * Buffers will be returned until the pool (buffercount())
+ * Buffers will be returned until the pool
* is exhausted, at which point obtainBuffer() will either block
* or return WOULD_BLOCK depending on the value of the "blocking"
* parameter.
@@ -422,6 +417,18 @@ public:
* +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 {
@@ -482,11 +489,12 @@ protected:
// 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,
audio_channel_mask_t channelMask,
- int frameCount,
+ size_t frameCount,
audio_output_flags_t flags,
const sp<IMemory>& sharedBuffer,
audio_io_handle_t output);
@@ -504,35 +512,59 @@ protected:
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;
bool mActive; // protected by mLock
callback_t mCbf; // callback handler for events, or NULL
- void* mUserData;
- uint32_t mNotificationFramesReq; // requested number of frames between each notification callback
- uint32_t mNotificationFramesAct; // actual number of frames between each notification callback
+ void* mUserData; // for client callback handler
+
+ // for notification APIs
+ uint32_t mNotificationFramesReq; // requested number of frames between each
+ // notification callback
+ uint32_t mNotificationFramesAct; // actual number of frames between each
+ // notification callback
sp<IMemory> mSharedBuffer;
int mLoopCount;
uint32_t mRemainingFrames;
- uint32_t mMarkerPosition;
+ uint32_t mMarkerPosition; // in frames
bool mMarkerReached;
- uint32_t mNewPosition;
- uint32_t mUpdatePeriod;
+ uint32_t mNewPosition; // in frames
+ uint32_t mUpdatePeriod; // in frames
+
bool mFlushed; // FIXME will be made obsolete by making flush() synchronous
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/EffectsFactoryApi.h b/include/media/EffectsFactoryApi.h
index 65c26f4..b1ed7b0 100644
--- a/include/media/EffectsFactoryApi.h
+++ b/include/media/EffectsFactoryApi.h
@@ -74,7 +74,8 @@ int EffectQueryNumberEffects(uint32_t *pNumEffects);
// -ENOENT no more effect available
// -ENODEV factory failed to initialize
// -EINVAL invalid pDescriptor
-// -ENOSYS effect list has changed since last execution of EffectQueryNumberEffects()
+// -ENOSYS effect list has changed since last execution of
+// EffectQueryNumberEffects()
// *pDescriptor: updated with the effect descriptor.
//
////////////////////////////////////////////////////////////////////////////////
@@ -91,12 +92,12 @@ int EffectQueryEffect(uint32_t index, effect_descriptor_t *pDescriptor);
//
// Input:
// pEffectUuid: pointer to the effect uuid.
-// sessionId: audio session to which this effect instance will be attached. All effects created
-// with the same session ID are connected in series and process the same signal stream.
-// Knowing that two effects are part of the same effect chain can help the library implement
-// some kind of optimizations.
-// ioId: identifies the output or input stream this effect is directed to at audio HAL. For future
-// use especially with tunneled HW accelerated effects
+// sessionId: audio session to which this effect instance will be attached. All effects
+// created with the same session ID are connected in series and process the same signal
+// stream. Knowing that two effects are part of the same effect chain can help the
+// library implement some kind of optimizations.
+// ioId: identifies the output or input stream this effect is directed to at audio HAL.
+// For future use especially with tunneled HW accelerated effects
//
// Input/Output:
// pHandle: address where to return the effect handle.
@@ -109,7 +110,8 @@ int EffectQueryEffect(uint32_t index, effect_descriptor_t *pDescriptor);
// *pHandle: updated with the effect handle.
//
////////////////////////////////////////////////////////////////////////////////
-int EffectCreate(const effect_uuid_t *pEffectUuid, int32_t sessionId, int32_t ioId, effect_handle_t *pHandle);
+int EffectCreate(const effect_uuid_t *pEffectUuid, int32_t sessionId, int32_t ioId,
+ effect_handle_t *pHandle);
////////////////////////////////////////////////////////////////////////////////
//
diff --git a/include/media/IAudioFlinger.h b/include/media/IAudioFlinger.h
index 5170a87..9727143 100644
--- a/include/media/IAudioFlinger.h
+++ b/include/media/IAudioFlinger.h
@@ -61,8 +61,8 @@ public:
uint32_t sampleRate,
audio_format_t format,
audio_channel_mask_t channelMask,
- int frameCount,
- track_flags_t flags,
+ size_t frameCount,
+ 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
@@ -75,7 +75,7 @@ public:
uint32_t sampleRate,
audio_format_t format,
audio_channel_mask_t channelMask,
- int frameCount,
+ size_t frameCount,
track_flags_t flags,
pid_t tid, // -1 means unused, otherwise must be valid non-0
int *sessionId,
@@ -123,7 +123,8 @@ public:
virtual status_t setParameters(audio_io_handle_t ioHandle,
const String8& keyValuePairs) = 0;
- virtual String8 getParameters(audio_io_handle_t ioHandle, const String8& keys) const = 0;
+ virtual String8 getParameters(audio_io_handle_t ioHandle, const String8& keys)
+ const = 0;
// register a current process for audio output change notifications
virtual void registerClient(const sp<IAudioFlingerClient>& client) = 0;
@@ -156,10 +157,10 @@ public:
virtual status_t setVoiceVolume(float volume) = 0;
- virtual status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames,
+ virtual status_t getRenderPosition(size_t *halFrames, size_t *dspFrames,
audio_io_handle_t output) const = 0;
- virtual unsigned int getInputFramesLost(audio_io_handle_t ioHandle) const = 0;
+ virtual size_t getInputFramesLost(audio_io_handle_t ioHandle) const = 0;
virtual int newAudioSessionId() = 0;
@@ -191,8 +192,8 @@ public:
// 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 int32_t getPrimaryOutputFrameCount() = 0;
+ virtual uint32_t getPrimaryOutputSamplingRate() = 0;
+ virtual size_t getPrimaryOutputFrameCount() = 0;
};
diff --git a/include/media/IAudioPolicyService.h b/include/media/IAudioPolicyService.h
index cc2e069..f5b0604 100644
--- a/include/media/IAudioPolicyService.h
+++ b/include/media/IAudioPolicyService.h
@@ -44,9 +44,10 @@ public:
audio_policy_dev_state_t state,
const char *device_address) = 0;
virtual audio_policy_dev_state_t getDeviceConnectionState(audio_devices_t device,
- const char *device_address) = 0;
+ const char *device_address) = 0;
virtual status_t setPhoneState(audio_mode_t state) = 0;
- virtual status_t setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config) = 0;
+ virtual status_t setForceUse(audio_policy_force_use_t usage,
+ audio_policy_forced_cfg_t config) = 0;
virtual audio_policy_forced_cfg_t getForceUse(audio_policy_force_use_t usage) = 0;
virtual audio_io_handle_t getOutput(audio_stream_type_t stream,
uint32_t samplingRate = 0,
diff --git a/include/media/SoundPool.h b/include/media/SoundPool.h
index 002b045..7bf3069 100644
--- a/include/media/SoundPool.h
+++ b/include/media/SoundPool.h
@@ -65,8 +65,10 @@ public:
sp<IMemory> getIMemory() { return mData; }
// hack
- void init(int numChannels, int sampleRate, audio_format_t format, size_t size, sp<IMemory> data ) {
- mNumChannels = numChannels; mSampleRate = sampleRate; mFormat = format; mSize = size; mData = data; }
+ void init(int numChannels, int sampleRate, audio_format_t format, size_t size,
+ sp<IMemory> data ) {
+ mNumChannels = numChannels; mSampleRate = sampleRate; mFormat = format; mSize = size;
+ mData = data; }
private:
void init();
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 @@ private:
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/media/nbaio/NBAIO.h b/include/media/nbaio/NBAIO.h
index 81f42ed..f5d6eb5 100644
--- a/include/media/nbaio/NBAIO.h
+++ b/include/media/nbaio/NBAIO.h
@@ -45,17 +45,15 @@ enum {
// Negotiation of format is based on the data provider and data sink, or the data consumer and
// data source, exchanging prioritized arrays of offers and counter-offers until a single offer is
// mutually agreed upon. Each offer is an NBAIO_Format. For simplicity and performance,
-// NBAIO_Format is an enum that ties together the most important combinations of the various
+// NBAIO_Format is a typedef that ties together the most important combinations of the various
// attributes, rather than a struct with separate fields for format, sample rate, channel count,
// interleave, packing, alignment, etc. The reason is that NBAIO_Format tries to abstract out only
-// the combinations that are actually needed within AudioFligner. If the list of combinations grows
+// the combinations that are actually needed within AudioFlinger. If the list of combinations grows
// too large, then this decision should be re-visited.
-enum NBAIO_Format {
- Format_Invalid,
- Format_SR44_1_C2_I16, // 44.1 kHz PCM stereo interleaved 16-bit signed
- Format_SR48_C2_I16, // 48 kHz PCM stereo interleaved 16-bit signed
- Format_SR44_1_C1_I16, // 44.1 kHz PCM mono interleaved 16-bit signed
- Format_SR48_C1_I16, // 48 kHz PCM mono interleaved 16-bit signed
+// Sample rate and channel count are explicit, PCM interleaved 16-bit is assumed.
+typedef unsigned NBAIO_Format;
+enum {
+ Format_Invalid
};
// Return the frame size of an NBAIO_Format in bytes
diff --git a/include/media/stagefright/MediaDefs.h b/include/media/stagefright/MediaDefs.h
index 457d5d7..81de6e4 100644
--- a/include/media/stagefright/MediaDefs.h
+++ b/include/media/stagefright/MediaDefs.h
@@ -42,6 +42,7 @@ extern const char *MEDIA_MIMETYPE_AUDIO_G711_MLAW;
extern const char *MEDIA_MIMETYPE_AUDIO_RAW;
extern const char *MEDIA_MIMETYPE_AUDIO_FLAC;
extern const char *MEDIA_MIMETYPE_AUDIO_AAC_ADTS;
+extern const char *MEDIA_MIMETYPE_AUDIO_MSGSM;
extern const char *MEDIA_MIMETYPE_CONTAINER_MPEG4;
extern const char *MEDIA_MIMETYPE_CONTAINER_WAV;
diff --git a/include/private/media/AudioTrackShared.h b/include/private/media/AudioTrackShared.h
index 5b133f3..bbc5e26 100644
--- a/include/private/media/AudioTrackShared.h
+++ b/include/private/media/AudioTrackShared.h
@@ -27,33 +27,16 @@ namespace android {
// ----------------------------------------------------------------------------
// Maximum cumulated timeout milliseconds before restarting audioflinger thread
-#define MAX_STARTUP_TIMEOUT_MS 3000 // Longer timeout period at startup to cope with A2DP init time
+#define MAX_STARTUP_TIMEOUT_MS 3000 // Longer timeout period at startup to cope with A2DP
+ // 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_MSK 0x0001
-#define CBLK_UNDERRUN_ON 0x0001 // underrun (out) or overrrun (in) indication
-#define CBLK_UNDERRUN_OFF 0x0000 // no underrun
-#define CBLK_DIRECTION_MSK 0x0002
-#define CBLK_DIRECTION_OUT 0x0002 // this cblk is for an AudioTrack
-#define CBLK_DIRECTION_IN 0x0000 // this cblk is for an AudioRecord
-#define CBLK_FORCEREADY_MSK 0x0004
-#define CBLK_FORCEREADY_ON 0x0004 // track is considered ready immediately by AudioFlinger
-#define CBLK_FORCEREADY_OFF 0x0000 // track is ready when buffer full
-#define CBLK_INVALID_MSK 0x0008
-#define CBLK_INVALID_ON 0x0008 // track buffer is invalidated by AudioFlinger:
-#define CBLK_INVALID_OFF 0x0000 // must be re-created
-#define CBLK_DISABLED_MSK 0x0010
-#define CBLK_DISABLED_ON 0x0010 // track disabled by AudioFlinger due to underrun:
-#define CBLK_DISABLED_OFF 0x0000 // must be re-started
-#define CBLK_RESTORING_MSK 0x0020
-#define CBLK_RESTORING_ON 0x0020 // track is being restored after invalidation
-#define CBLK_RESTORING_OFF 0x0000 // by AudioFlinger
-#define CBLK_RESTORED_MSK 0x0040
-#define CBLK_RESTORED_ON 0x0040 // track has been restored after invalidation
-#define CBLK_RESTORED_OFF 0x0040 // by AudioFlinger
-#define CBLK_FAST 0x0080 // AudioFlinger successfully created a fast track
+
+#define CBLK_UNDERRUN 0x01 // set: underrun (out) or overrrun (in), clear: no underrun or overrun
+#define CBLK_FORCEREADY 0x02 // set: track is considered ready immediately by AudioFlinger,
+ // clear: track is ready when buffer full
+#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
@@ -70,12 +53,11 @@ struct audio_track_cblk_t
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
@@ -91,16 +73,14 @@ public:
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
- uint16_t bufferTimeoutMs; // Maximum cumulated timeout before restarting audioflinger
+ uint16_t bufferTimeoutMs; // Maximum cumulated timeout before restarting
+ // audioflinger
uint16_t waitTimeMs; // Cumulated wait time, used by client only
private:
@@ -114,13 +94,25 @@ public:
// 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
@@ -146,6 +138,12 @@ public:
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/Android.mk b/libvideoeditor/lvpp/Android.mk
index 0ed7e6c..778c5ac 100755
--- a/libvideoeditor/lvpp/Android.mk
+++ b/libvideoeditor/lvpp/Android.mk
@@ -54,7 +54,6 @@ LOCAL_SHARED_LIBRARIES := \
libGLESv2 \
libgui \
libmedia \
- libmedia_native \
libdrmframework \
libstagefright \
libstagefright_foundation \
diff --git a/libvideoeditor/lvpp/VideoEditorPlayer.cpp b/libvideoeditor/lvpp/VideoEditorPlayer.cpp
index fc9fb49..a47fc15 100755
--- a/libvideoeditor/lvpp/VideoEditorPlayer.cpp
+++ b/libvideoeditor/lvpp/VideoEditorPlayer.cpp
@@ -406,8 +406,8 @@ status_t VideoEditorPlayer::VeAudioOutput::open(
}
ALOGV("open(%u, %d, %d, %d)", sampleRate, channelCount, format, bufferCount);
if (mTrack) close();
- int afSampleRate;
- int afFrameCount;
+ uint32_t afSampleRate;
+ size_t afFrameCount;
int frameCount;
if (AudioSystem::getOutputFrameCount(&afFrameCount, mStreamType) !=
diff --git a/media/libeffects/downmix/Android.mk b/media/libeffects/downmix/Android.mk
index 95ca6fd..3052ad9 100644
--- a/media/libeffects/downmix/Android.mk
+++ b/media/libeffects/downmix/Android.mk
@@ -25,4 +25,6 @@ LOCAL_C_INCLUDES := \
LOCAL_PRELINK_MODULE := false
+LOCAL_CFLAGS += -fvisibility=hidden
+
include $(BUILD_SHARED_LIBRARY)
diff --git a/media/libeffects/downmix/EffectDownmix.c b/media/libeffects/downmix/EffectDownmix.c
index 5bf052a..f17a6e8 100644
--- a/media/libeffects/downmix/EffectDownmix.c
+++ b/media/libeffects/downmix/EffectDownmix.c
@@ -58,13 +58,13 @@ const struct effect_interface_s gDownmixInterface = {
NULL /* no process_reverse function, no reference stream needed */
};
+// This is the only symbol that needs to be exported
+__attribute__ ((visibility ("default")))
audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = {
tag : AUDIO_EFFECT_LIBRARY_TAG,
version : EFFECT_LIBRARY_API_VERSION,
name : "Downmix Library",
implementor : "The Android Open Source Project",
- query_num_effects : DownmixLib_QueryNumberEffects,
- query_effect : DownmixLib_QueryEffect,
create_effect : DownmixLib_Create,
release_effect : DownmixLib_Release,
get_descriptor : DownmixLib_GetDescriptor,
@@ -159,25 +159,6 @@ void Downmix_testIndexComputation(uint32_t mask) {
/*--- Effect Library Interface Implementation ---*/
-int32_t DownmixLib_QueryNumberEffects(uint32_t *pNumEffects) {
- ALOGV("DownmixLib_QueryNumberEffects()");
- *pNumEffects = kNbEffects;
- return 0;
-}
-
-int32_t DownmixLib_QueryEffect(uint32_t index, effect_descriptor_t *pDescriptor) {
- ALOGV("DownmixLib_QueryEffect() index=%d", index);
- if (pDescriptor == NULL) {
- return -EINVAL;
- }
- if (index >= (uint32_t)kNbEffects) {
- return -EINVAL;
- }
- memcpy(pDescriptor, gDescriptors[index], sizeof(effect_descriptor_t));
- return 0;
-}
-
-
int32_t DownmixLib_Create(const effect_uuid_t *uuid,
int32_t sessionId,
int32_t ioId,
diff --git a/media/libeffects/downmix/EffectDownmix.h b/media/libeffects/downmix/EffectDownmix.h
index be3ca3f..cb6b957 100644
--- a/media/libeffects/downmix/EffectDownmix.h
+++ b/media/libeffects/downmix/EffectDownmix.h
@@ -65,9 +65,6 @@ const uint32_t kUnsupported =
* Effect API
*------------------------------------
*/
-int32_t DownmixLib_QueryNumberEffects(uint32_t *pNumEffects);
-int32_t DownmixLib_QueryEffect(uint32_t index,
- effect_descriptor_t *pDescriptor);
int32_t DownmixLib_Create(const effect_uuid_t *uuid,
int32_t sessionId,
int32_t ioId,
diff --git a/media/libeffects/lvm/lib/Android.mk b/media/libeffects/lvm/lib/Android.mk
index f49267e..bb56c75 100644
--- a/media/libeffects/lvm/lib/Android.mk
+++ b/media/libeffects/lvm/lib/Android.mk
@@ -105,8 +105,6 @@ LOCAL_SRC_FILES:= \
LOCAL_MODULE:= libmusicbundle
-
-
LOCAL_C_INCLUDES += \
$(LOCAL_PATH)/Eq/lib \
$(LOCAL_PATH)/Eq/src \
@@ -121,8 +119,12 @@ LOCAL_C_INCLUDES += \
$(LOCAL_PATH)/StereoWidening/src \
$(LOCAL_PATH)/StereoWidening/lib
+LOCAL_CFLAGS += -fvisibility=hidden
+
include $(BUILD_STATIC_LIBRARY)
+
+
# Reverb library
include $(CLEAR_VARS)
@@ -168,12 +170,11 @@ LOCAL_SRC_FILES:= \
LOCAL_MODULE:= libreverb
-
-
LOCAL_C_INCLUDES += \
$(LOCAL_PATH)/Reverb/lib \
$(LOCAL_PATH)/Reverb/src \
$(LOCAL_PATH)/Common/lib \
$(LOCAL_PATH)/Common/src
+LOCAL_CFLAGS += -fvisibility=hidden
include $(BUILD_STATIC_LIBRARY)
diff --git a/media/libeffects/lvm/wrapper/Android.mk b/media/libeffects/lvm/wrapper/Android.mk
index 4313424..f1af389 100644
--- a/media/libeffects/lvm/wrapper/Android.mk
+++ b/media/libeffects/lvm/wrapper/Android.mk
@@ -9,28 +9,27 @@ LOCAL_ARM_MODE := arm
LOCAL_SRC_FILES:= \
Bundle/EffectBundle.cpp
+LOCAL_CFLAGS += -fvisibility=hidden
+
LOCAL_MODULE:= libbundlewrapper
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/soundfx
-
-
LOCAL_STATIC_LIBRARIES += libmusicbundle
LOCAL_SHARED_LIBRARIES := \
libcutils \
libdl
-
LOCAL_C_INCLUDES += \
$(LOCAL_PATH)/Bundle \
$(LOCAL_PATH)/../lib/Common/lib/ \
$(LOCAL_PATH)/../lib/Bundle/lib/ \
$(call include-path-for, audio-effects)
-
include $(BUILD_SHARED_LIBRARY)
+
# reverb wrapper
include $(CLEAR_VARS)
@@ -39,12 +38,12 @@ LOCAL_ARM_MODE := arm
LOCAL_SRC_FILES:= \
Reverb/EffectReverb.cpp
+LOCAL_CFLAGS += -fvisibility=hidden
+
LOCAL_MODULE:= libreverbwrapper
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/soundfx
-
-
LOCAL_STATIC_LIBRARIES += libreverb
LOCAL_SHARED_LIBRARIES := \
diff --git a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
index d706c2d..94b9acf 100644
--- a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
+++ b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
@@ -158,42 +158,6 @@ int Volume_getParameter (EffectContext *pContext,
int Effect_setEnabled(EffectContext *pContext, bool enabled);
/* Effect Library Interface Implementation */
-extern "C" int EffectQueryNumberEffects(uint32_t *pNumEffects){
- ALOGV("\n\tEffectQueryNumberEffects start");
- *pNumEffects = 4;
- ALOGV("\tEffectQueryNumberEffects creating %d effects", *pNumEffects);
- ALOGV("\tEffectQueryNumberEffects end\n");
- return 0;
-} /* end EffectQueryNumberEffects */
-
-extern "C" int EffectQueryEffect(uint32_t index, effect_descriptor_t *pDescriptor){
- ALOGV("\n\tEffectQueryEffect start");
- ALOGV("\tEffectQueryEffect processing index %d", index);
-
- if (pDescriptor == NULL){
- ALOGV("\tLVM_ERROR : EffectQueryEffect was passed NULL pointer");
- return -EINVAL;
- }
- if (index > 3){
- ALOGV("\tLVM_ERROR : EffectQueryEffect index out of range %d", index);
- return -ENOENT;
- }
- if(index == LVM_BASS_BOOST){
- ALOGV("\tEffectQueryEffect processing LVM_BASS_BOOST");
- *pDescriptor = gBassBoostDescriptor;
- }else if(index == LVM_VIRTUALIZER){
- ALOGV("\tEffectQueryEffect processing LVM_VIRTUALIZER");
- *pDescriptor = gVirtualizerDescriptor;
- } else if(index == LVM_EQUALIZER){
- ALOGV("\tEffectQueryEffect processing LVM_EQUALIZER");
- *pDescriptor = gEqualizerDescriptor;
- } else if(index == LVM_VOLUME){
- ALOGV("\tEffectQueryEffect processing LVM_VOLUME");
- *pDescriptor = gVolumeDescriptor;
- }
- ALOGV("\tEffectQueryEffect end\n");
- return 0;
-} /* end EffectQueryEffect */
extern "C" int EffectCreate(const effect_uuid_t *uuid,
int32_t sessionId,
@@ -3299,13 +3263,13 @@ const struct effect_interface_s gLvmEffectInterface = {
NULL,
}; /* end gLvmEffectInterface */
+// This is the only symbol that needs to be exported
+__attribute__ ((visibility ("default")))
audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = {
tag : AUDIO_EFFECT_LIBRARY_TAG,
version : EFFECT_LIBRARY_API_VERSION,
name : "Effect Bundle Library",
implementor : "NXP Software Ltd.",
- query_num_effects : android::EffectQueryNumberEffects,
- query_effect : android::EffectQueryEffect,
create_effect : android::EffectCreate,
release_effect : android::EffectRelease,
get_descriptor : android::EffectGetDescriptor,
diff --git a/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp b/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
index 941d651..87e2c85 100755..100644
--- a/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
+++ b/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
@@ -186,30 +186,6 @@ int Reverb_getParameter (ReverbContext *pContext,
int Reverb_LoadPreset (ReverbContext *pContext);
/* Effect Library Interface Implementation */
-extern "C" int EffectQueryNumberEffects(uint32_t *pNumEffects){
- ALOGV("\n\tEffectQueryNumberEffects start");
- *pNumEffects = sizeof(gDescriptors) / sizeof(const effect_descriptor_t *);
- ALOGV("\tEffectQueryNumberEffects creating %d effects", *pNumEffects);
- ALOGV("\tEffectQueryNumberEffects end\n");
- return 0;
-} /* end EffectQueryNumberEffects */
-
-extern "C" int EffectQueryEffect(uint32_t index,
- effect_descriptor_t *pDescriptor){
- ALOGV("\n\tEffectQueryEffect start");
- ALOGV("\tEffectQueryEffect processing index %d", index);
- if (pDescriptor == NULL){
- ALOGV("\tLVM_ERROR : EffectQueryEffect was passed NULL pointer");
- return -EINVAL;
- }
- if (index >= sizeof(gDescriptors) / sizeof(const effect_descriptor_t *)) {
- ALOGV("\tLVM_ERROR : EffectQueryEffect index out of range %d", index);
- return -ENOENT;
- }
- *pDescriptor = *gDescriptors[index];
- ALOGV("\tEffectQueryEffect end\n");
- return 0;
-} /* end EffectQueryEffect */
extern "C" int EffectCreate(const effect_uuid_t *uuid,
int32_t sessionId,
@@ -2170,13 +2146,13 @@ const struct effect_interface_s gReverbInterface = {
NULL,
}; /* end gReverbInterface */
+// This is the only symbol that needs to be exported
+__attribute__ ((visibility ("default")))
audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = {
tag : AUDIO_EFFECT_LIBRARY_TAG,
version : EFFECT_LIBRARY_API_VERSION,
name : "Reverb Library",
implementor : "NXP Software Ltd.",
- query_num_effects : android::EffectQueryNumberEffects,
- query_effect : android::EffectQueryEffect,
create_effect : android::EffectCreate,
release_effect : android::EffectRelease,
get_descriptor : android::EffectGetDescriptor,
diff --git a/media/libeffects/preprocessing/Android.mk b/media/libeffects/preprocessing/Android.mk
index c13b9d4..dfa1711 100755..100644
--- a/media/libeffects/preprocessing/Android.mk
+++ b/media/libeffects/preprocessing/Android.mk
@@ -29,4 +29,6 @@ else
LOCAL_SHARED_LIBRARIES += libdl
endif
+LOCAL_CFLAGS += -fvisibility=hidden
+
include $(BUILD_SHARED_LIBRARY)
diff --git a/media/libeffects/preprocessing/PreProcessing.cpp b/media/libeffects/preprocessing/PreProcessing.cpp
index 597866a..25586e8 100755..100644
--- a/media/libeffects/preprocessing/PreProcessing.cpp
+++ b/media/libeffects/preprocessing/PreProcessing.cpp
@@ -1818,30 +1818,6 @@ const struct effect_interface_s sEffectInterfaceReverse = {
// Effect Library Interface Implementation
//------------------------------------------------------------------------------
-int PreProcessingLib_QueryNumberEffects(uint32_t *pNumEffects)
-{
- if (PreProc_Init() != 0) {
- return sInitStatus;
- }
- if (pNumEffects == NULL) {
- return -EINVAL;
- }
- *pNumEffects = PREPROC_NUM_EFFECTS;
- return sInitStatus;
-}
-
-int PreProcessingLib_QueryEffect(uint32_t index, effect_descriptor_t *pDescriptor)
-{
- if (PreProc_Init() != 0) {
- return sInitStatus;
- }
- if (index >= PREPROC_NUM_EFFECTS) {
- return -EINVAL;
- }
- *pDescriptor = *sDescriptors[index];
- return 0;
-}
-
int PreProcessingLib_Create(const effect_uuid_t *uuid,
int32_t sessionId,
int32_t ioId,
@@ -1913,13 +1889,13 @@ int PreProcessingLib_GetDescriptor(const effect_uuid_t *uuid,
return 0;
}
+// This is the only symbol that needs to be exported
+__attribute__ ((visibility ("default")))
audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = {
tag : AUDIO_EFFECT_LIBRARY_TAG,
version : EFFECT_LIBRARY_API_VERSION,
name : "Audio Preprocessing Library",
implementor : "The Android Open Source Project",
- query_num_effects : PreProcessingLib_QueryNumberEffects,
- query_effect : PreProcessingLib_QueryEffect,
create_effect : PreProcessingLib_Create,
release_effect : PreProcessingLib_Release,
get_descriptor : PreProcessingLib_GetDescriptor
diff --git a/media/libeffects/testlibs/EffectEqualizer.cpp b/media/libeffects/testlibs/EffectEqualizer.cpp
index 90ebe1f..c35453b 100644
--- a/media/libeffects/testlibs/EffectEqualizer.cpp
+++ b/media/libeffects/testlibs/EffectEqualizer.cpp
@@ -123,23 +123,6 @@ int Equalizer_setParameter(AudioEqualizer * pEqualizer, int32_t *pParam, void *p
//--- Effect Library Interface Implementation
//
-extern "C" int EffectQueryNumberEffects(uint32_t *pNumEffects) {
- *pNumEffects = 1;
- return 0;
-} /* end EffectQueryNumberEffects */
-
-extern "C" int EffectQueryEffect(uint32_t index,
- effect_descriptor_t *pDescriptor) {
- if (pDescriptor == NULL) {
- return -EINVAL;
- }
- if (index > 0) {
- return -EINVAL;
- }
- *pDescriptor = gEqualizerDescriptor;
- return 0;
-} /* end EffectQueryNext */
-
extern "C" int EffectCreate(const effect_uuid_t *uuid,
int32_t sessionId,
int32_t ioId,
@@ -771,8 +754,6 @@ audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = {
version : EFFECT_LIBRARY_API_VERSION,
name : "Test Equalizer Library",
implementor : "The Android Open Source Project",
- query_num_effects : android::EffectQueryNumberEffects,
- query_effect : android::EffectQueryEffect,
create_effect : android::EffectCreate,
release_effect : android::EffectRelease,
get_descriptor : android::EffectGetDescriptor,
diff --git a/media/libeffects/testlibs/EffectReverb.c b/media/libeffects/testlibs/EffectReverb.c
index a87a834..c37f392 100644
--- a/media/libeffects/testlibs/EffectReverb.c
+++ b/media/libeffects/testlibs/EffectReverb.c
@@ -94,23 +94,6 @@ static const effect_descriptor_t * const gDescriptors[] = {
/*--- Effect Library Interface Implementation ---*/
-int EffectQueryNumberEffects(uint32_t *pNumEffects) {
- *pNumEffects = sizeof(gDescriptors) / sizeof(const effect_descriptor_t *);
- return 0;
-}
-
-int EffectQueryEffect(uint32_t index, effect_descriptor_t *pDescriptor) {
- if (pDescriptor == NULL) {
- return -EINVAL;
- }
- if (index >= sizeof(gDescriptors) / sizeof(const effect_descriptor_t *)) {
- return -EINVAL;
- }
- memcpy(pDescriptor, gDescriptors[index],
- sizeof(effect_descriptor_t));
- return 0;
-}
-
int EffectCreate(const effect_uuid_t *uuid,
int32_t sessionId,
int32_t ioId,
@@ -2222,8 +2205,6 @@ audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = {
.version = EFFECT_LIBRARY_API_VERSION,
.name = "Test Equalizer Library",
.implementor = "The Android Open Source Project",
- .query_num_effects = EffectQueryNumberEffects,
- .query_effect = EffectQueryEffect,
.create_effect = EffectCreate,
.release_effect = EffectRelease,
.get_descriptor = EffectGetDescriptor,
diff --git a/media/libeffects/testlibs/EffectReverb.h b/media/libeffects/testlibs/EffectReverb.h
index 1fb14a7..e5248fe 100644
--- a/media/libeffects/testlibs/EffectReverb.h
+++ b/media/libeffects/testlibs/EffectReverb.h
@@ -300,9 +300,6 @@ typedef struct reverb_module_s {
* Effect API
*------------------------------------
*/
-int EffectQueryNumberEffects(uint32_t *pNumEffects);
-int EffectQueryEffect(uint32_t index,
- effect_descriptor_t *pDescriptor);
int EffectCreate(const effect_uuid_t *effectUID,
int32_t sessionId,
int32_t ioId,
diff --git a/media/libeffects/visualizer/Android.mk b/media/libeffects/visualizer/Android.mk
index 76b5110..49cf4fa 100644
--- a/media/libeffects/visualizer/Android.mk
+++ b/media/libeffects/visualizer/Android.mk
@@ -6,7 +6,7 @@ include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
EffectVisualizer.cpp
-LOCAL_CFLAGS+= -O2
+LOCAL_CFLAGS+= -O2 -fvisibility=hidden
LOCAL_SHARED_LIBRARIES := \
libcutils \
diff --git a/media/libeffects/visualizer/EffectVisualizer.cpp b/media/libeffects/visualizer/EffectVisualizer.cpp
index 44baf93..e7eccf1 100644
--- a/media/libeffects/visualizer/EffectVisualizer.cpp
+++ b/media/libeffects/visualizer/EffectVisualizer.cpp
@@ -177,23 +177,6 @@ int Visualizer_init(VisualizerContext *pContext)
//--- Effect Library Interface Implementation
//
-int VisualizerLib_QueryNumberEffects(uint32_t *pNumEffects) {
- *pNumEffects = 1;
- return 0;
-}
-
-int VisualizerLib_QueryEffect(uint32_t index,
- effect_descriptor_t *pDescriptor) {
- if (pDescriptor == NULL) {
- return -EINVAL;
- }
- if (index > 0) {
- return -EINVAL;
- }
- *pDescriptor = gVisualizerDescriptor;
- return 0;
-}
-
int VisualizerLib_Create(const effect_uuid_t *uuid,
int32_t sessionId,
int32_t ioId,
@@ -574,14 +557,13 @@ const struct effect_interface_s gVisualizerInterface = {
NULL,
};
-
+// This is the only symbol that needs to be exported
+__attribute__ ((visibility ("default")))
audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = {
tag : AUDIO_EFFECT_LIBRARY_TAG,
version : EFFECT_LIBRARY_API_VERSION,
name : "Visualizer Library",
implementor : "The Android Open Source Project",
- query_num_effects : VisualizerLib_QueryNumberEffects,
- query_effect : VisualizerLib_QueryEffect,
create_effect : VisualizerLib_Create,
release_effect : VisualizerLib_Release,
get_descriptor : VisualizerLib_GetDescriptor,
diff --git a/media/libmedia/Android.mk b/media/libmedia/Android.mk
index 54666fb..f2b6441 100644
--- a/media/libmedia/Android.mk
+++ b/media/libmedia/Android.mk
@@ -54,7 +54,7 @@ LOCAL_SRC_FILES:= \
LOCAL_SHARED_LIBRARIES := \
libui libcutils libutils libbinder libsonivox libicuuc libexpat \
libcamera_client libstagefright_foundation \
- libgui libdl libaudioutils libmedia_native
+ libgui libdl libaudioutils
LOCAL_WHOLE_STATIC_LIBRARY := libmedia_helper
diff --git a/media/libmedia/AudioEffect.cpp b/media/libmedia/AudioEffect.cpp
index 680604b..3317d57 100644
--- a/media/libmedia/AudioEffect.cpp
+++ b/media/libmedia/AudioEffect.cpp
@@ -152,7 +152,8 @@ status_t AudioEffect::set(const effect_uuid_t *type,
mCblk->buffer = (uint8_t *)mCblk + bufOffset;
iEffect->asBinder()->linkToDeath(mIEffectClient);
- ALOGV("set() %p OK effect: %s id: %d status %d enabled %d", this, mDescriptor.name, mId, mStatus, mEnabled);
+ ALOGV("set() %p OK effect: %s id: %d status %d enabled %d", this, mDescriptor.name, mId,
+ mStatus, mEnabled);
return mStatus;
}
@@ -266,9 +267,11 @@ status_t AudioEffect::setParameter(effect_param_t *param)
uint32_t size = sizeof(int);
uint32_t psize = ((param->psize - 1) / sizeof(int) + 1) * sizeof(int) + param->vsize;
- ALOGV("setParameter: param: %d, param2: %d", *(int *)param->data, (param->psize == 8) ? *((int *)param->data + 1): -1);
+ ALOGV("setParameter: param: %d, param2: %d", *(int *)param->data,
+ (param->psize == 8) ? *((int *)param->data + 1): -1);
- return mIEffect->command(EFFECT_CMD_SET_PARAM, sizeof (effect_param_t) + psize, param, &size, &param->status);
+ return mIEffect->command(EFFECT_CMD_SET_PARAM, sizeof (effect_param_t) + psize, param, &size,
+ &param->status);
}
status_t AudioEffect::setParameterDeferred(effect_param_t *param)
@@ -321,11 +324,14 @@ status_t AudioEffect::getParameter(effect_param_t *param)
return BAD_VALUE;
}
- ALOGV("getParameter: param: %d, param2: %d", *(int *)param->data, (param->psize == 8) ? *((int *)param->data + 1): -1);
+ ALOGV("getParameter: param: %d, param2: %d", *(int *)param->data,
+ (param->psize == 8) ? *((int *)param->data + 1): -1);
- uint32_t psize = sizeof(effect_param_t) + ((param->psize - 1) / sizeof(int) + 1) * sizeof(int) + param->vsize;
+ uint32_t psize = sizeof(effect_param_t) + ((param->psize - 1) / sizeof(int) + 1) * sizeof(int) +
+ param->vsize;
- return mIEffect->command(EFFECT_CMD_GET_PARAM, sizeof(effect_param_t) + param->psize, param, &psize, param);
+ return mIEffect->command(EFFECT_CMD_GET_PARAM, sizeof(effect_param_t) + param->psize, param,
+ &psize, param);
}
@@ -346,7 +352,8 @@ void AudioEffect::binderDied()
void AudioEffect::controlStatusChanged(bool controlGranted)
{
- ALOGV("controlStatusChanged %p control %d callback %p mUserData %p", this, controlGranted, mCbf, mUserData);
+ ALOGV("controlStatusChanged %p control %d callback %p mUserData %p", this, controlGranted, mCbf,
+ mUserData);
if (controlGranted) {
if (mStatus == ALREADY_EXISTS) {
mStatus = NO_ERROR;
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index 8ea6306..0587651 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -36,7 +36,7 @@ namespace android {
// static
status_t AudioRecord::getMinFrameCount(
- int* frameCount,
+ size_t* frameCount,
uint32_t sampleRate,
audio_format_t format,
audio_channel_mask_t channelMask)
@@ -54,7 +54,7 @@ status_t AudioRecord::getMinFrameCount(
}
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;
}
@@ -119,15 +119,22 @@ status_t AudioRecord::set(
uint32_t sampleRate,
audio_format_t format,
audio_channel_mask_t channelMask,
- int frameCount,
+ int frameCountInt,
callback_t cbf,
void* user,
int notificationFrames,
bool threadCanCallJava,
int sessionId)
{
+ // FIXME "int" here is legacy and will be replaced by size_t later
+ if (frameCountInt < 0) {
+ ALOGE("Invalid frame count %d", frameCountInt);
+ return BAD_VALUE;
+ }
+ size_t frameCount = frameCountInt;
- ALOGV("set(): sampleRate %d, channelMask %#x, frameCount %d",sampleRate, channelMask, frameCount);
+ ALOGV("set(): sampleRate %u, channelMask %#x, frameCount %u", sampleRate, channelMask,
+ frameCount);
AutoMutex lock(mLock);
@@ -176,7 +183,7 @@ status_t AudioRecord::set(
}
// validate framecount
- int minFrameCount = 0;
+ size_t minFrameCount = 0;
status_t status = getMinFrameCount(&minFrameCount, sampleRate, format, channelMask);
if (status != NO_ERROR) {
return status;
@@ -212,6 +219,13 @@ status_t AudioRecord::set(
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;
@@ -252,20 +266,11 @@ int AudioRecord::channelCount() const
return mChannelCount;
}
-uint32_t AudioRecord::frameCount() const
+size_t AudioRecord::frameCount() const
{
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;
@@ -291,17 +296,19 @@ status_t AudioRecord::start(AudioSystem::sync_event_t event, int triggerSession)
mActive = true;
cblk->lock.lock();
- if (!(cblk->flags & CBLK_INVALID_MSK)) {
+ if (!(cblk->flags & CBLK_INVALID)) {
cblk->lock.unlock();
ALOGV("mAudioRecord->start()");
ret = mAudioRecord->start(event, triggerSession);
cblk->lock.lock();
if (ret == DEAD_OBJECT) {
- android_atomic_or(CBLK_INVALID_ON, &cblk->flags);
+ android_atomic_or(CBLK_INVALID, &cblk->flags);
}
}
- if (cblk->flags & CBLK_INVALID_MSK) {
- ret = restoreRecord_l(cblk);
+ if (cblk->flags & CBLK_INVALID) {
+ audio_track_cblk_t* temp = cblk;
+ ret = restoreRecord_l(temp);
+ cblk = temp;
}
cblk->lock.unlock();
if (ret == NO_ERROR) {
@@ -426,12 +433,13 @@ status_t AudioRecord::openRecord_l(
uint32_t sampleRate,
audio_format_t format,
audio_channel_mask_t channelMask,
- int frameCount,
+ size_t frameCount,
audio_io_handle_t input)
{
status_t status;
const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger();
if (audioFlinger == 0) {
+ ALOGE("Could not get audioflinger");
return NO_INIT;
}
@@ -454,20 +462,20 @@ status_t AudioRecord::openRecord_l(
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_MSK, &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;
}
@@ -483,7 +491,7 @@ status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount)
audioBuffer->frameCount = 0;
audioBuffer->size = 0;
- uint32_t framesReady = cblk->framesReady();
+ uint32_t framesReady = cblk->framesReadyIn();
if (framesReady == 0) {
cblk->lock.lock();
@@ -498,17 +506,22 @@ status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount)
cblk->lock.unlock();
return WOULD_BLOCK;
}
- if (!(cblk->flags & CBLK_INVALID_MSK)) {
+ 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_MSK) {
+ if (cblk->flags & CBLK_INVALID) {
goto create_new_record;
}
if (CC_UNLIKELY(result != NO_ERROR)) {
@@ -521,9 +534,11 @@ status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount)
result = mAudioRecord->start(AudioSystem::SYNC_EVENT_SAME, 0);
cblk->lock.lock();
if (result == DEAD_OBJECT) {
- android_atomic_or(CBLK_INVALID_ON, &cblk->flags);
+ 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);
@@ -539,7 +554,7 @@ create_new_record:
}
// read the server count again
start_loop_here:
- framesReady = cblk->framesReady();
+ framesReady = cblk->framesReadyIn();
}
cblk->lock.unlock();
}
@@ -559,12 +574,9 @@ create_new_record:
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);
}
@@ -572,7 +584,7 @@ create_new_record:
void AudioRecord::releaseBuffer(Buffer* audioBuffer)
{
AutoMutex lock(mLock);
- mCblk->stepUser(audioBuffer->frameCount);
+ mCblk->stepUserIn(audioBuffer->frameCount);
}
audio_io_handle_t AudioRecord::getInput() const
@@ -701,7 +713,8 @@ bool AudioRecord::processAudioBuffer(const sp<AudioRecordThread>& thread)
status_t err = obtainBuffer(&audioBuffer, 1);
if (err < NO_ERROR) {
if (err != TIMED_OUT) {
- ALOGE_IF(err != status_t(NO_MORE_BUFFERS), "Error obtaining an audio buffer, giving up.");
+ ALOGE_IF(err != status_t(NO_MORE_BUFFERS),
+ "Error obtaining an audio buffer, giving up.");
return false;
}
break;
@@ -733,11 +746,11 @@ bool AudioRecord::processAudioBuffer(const sp<AudioRecordThread>& thread)
// 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);
- if (!(android_atomic_or(CBLK_UNDERRUN_ON, &cblk->flags) & CBLK_UNDERRUN_MSK)) {
+ if (!(android_atomic_or(CBLK_UNDERRUN, &cblk->flags) & CBLK_UNDERRUN)) {
mCbf(EVENT_OVERRUN, mUserData, NULL);
}
}
@@ -753,57 +766,41 @@ bool AudioRecord::processAudioBuffer(const sp<AudioRecordThread>& thread)
// 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_ON, &cblk->flags) & CBLK_RESTORING_MSK)) {
- 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_ON, &cblk->flags);
- cblk->cv.broadcast();
- } else {
- if (!(cblk->flags & CBLK_RESTORED_MSK)) {
- 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 207f96f..028e4a3 100644
--- a/media/libmedia/AudioSystem.cpp
+++ b/media/libmedia/AudioSystem.cpp
@@ -205,12 +205,7 @@ int AudioSystem::logToLinear(float volume)
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::getOutputSamplingRate(int* samplingRate, audio_stream_type
status_t AudioSystem::getSamplingRate(audio_io_handle_t output,
audio_stream_type_t streamType,
- int* samplingRate)
+ uint32_t* samplingRate)
{
OutputDescriptor *outputDesc;
@@ -246,17 +241,13 @@ status_t AudioSystem::getSamplingRate(audio_io_handle_t output,
gLock.unlock();
}
- ALOGV("getSamplingRate() streamType %d, output %d, sampling rate %d", streamType, output, *samplingRate);
+ 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)
+status_t AudioSystem::getOutputFrameCount(size_t* frameCount, audio_stream_type_t streamType)
{
audio_io_handle_t output;
@@ -274,7 +265,7 @@ status_t AudioSystem::getOutputFrameCount(int* frameCount, audio_stream_type_t s
status_t AudioSystem::getFrameCount(audio_io_handle_t output,
audio_stream_type_t streamType,
- int* frameCount)
+ size_t* frameCount)
{
OutputDescriptor *outputDesc;
@@ -290,7 +281,8 @@ status_t AudioSystem::getFrameCount(audio_io_handle_t output,
gLock.unlock();
}
- ALOGV("getFrameCount() streamType %d, output %d, frameCount %d", streamType, output, *frameCount);
+ ALOGV("getFrameCount() streamType %d, output %d, frameCount %d", streamType, output,
+ *frameCount);
return NO_ERROR;
}
@@ -369,7 +361,8 @@ status_t AudioSystem::setVoiceVolume(float value)
return af->setVoiceVolume(value);
}
-status_t AudioSystem::getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames, audio_stream_type_t stream)
+status_t AudioSystem::getRenderPosition(size_t *halFrames, size_t *dspFrames,
+ audio_stream_type_t stream)
{
const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
if (af == 0) return PERMISSION_DENIED;
@@ -381,7 +374,7 @@ status_t AudioSystem::getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames
return af->getRenderPosition(halFrames, dspFrames, getOutput(stream));
}
-unsigned int AudioSystem::getInputFramesLost(audio_io_handle_t ioHandle) {
+size_t AudioSystem::getInputFramesLost(audio_io_handle_t ioHandle) {
const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
unsigned int result = 0;
if (af == 0) return result;
@@ -449,8 +442,10 @@ void AudioSystem::AudioFlingerClient::ioConfigChanged(int event, audio_io_handle
OutputDescriptor *outputDesc = new OutputDescriptor(*desc);
gOutputs.add(ioHandle, outputDesc);
- ALOGV("ioConfigChanged() new output samplingRate %d, format %d channels %#x frameCount %d latency %d",
- outputDesc->samplingRate, outputDesc->format, outputDesc->channels, outputDesc->frameCount, outputDesc->latency);
+ ALOGV("ioConfigChanged() new output samplingRate %u, format %d channels %#x frameCount %u "
+ "latency %d",
+ outputDesc->samplingRate, outputDesc->format, outputDesc->channels,
+ outputDesc->frameCount, outputDesc->latency);
} break;
case OUTPUT_CLOSED: {
if (gOutputs.indexOfKey(ioHandle) < 0) {
@@ -471,7 +466,8 @@ void AudioSystem::AudioFlingerClient::ioConfigChanged(int event, audio_io_handle
if (param2 == NULL) break;
desc = (const OutputDescriptor *)param2;
- ALOGV("ioConfigChanged() new config for output %d samplingRate %d, format %d channels %#x frameCount %d latency %d",
+ 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);
OutputDescriptor *outputDesc = gOutputs.valueAt(index);
@@ -510,7 +506,7 @@ sp<IAudioPolicyService> AudioSystem::gAudioPolicyService;
sp<AudioSystem::AudioPolicyServiceClient> AudioSystem::gAudioPolicyServiceClient;
-// establish binder interface to AudioFlinger service
+// establish binder interface to AudioPolicy service
const sp<IAudioPolicyService>& AudioSystem::get_audio_policy_service()
{
gLock.lock();
@@ -744,14 +740,14 @@ status_t AudioSystem::isSourceActive(audio_source_t stream, bool* state)
return NO_ERROR;
}
-int32_t AudioSystem::getPrimaryOutputSamplingRate()
+uint32_t AudioSystem::getPrimaryOutputSamplingRate()
{
const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
if (af == 0) return 0;
return af->getPrimaryOutputSamplingRate();
}
-int32_t AudioSystem::getPrimaryOutputFrameCount()
+size_t AudioSystem::getPrimaryOutputFrameCount()
{
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 362d022..979ee37 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -50,7 +50,7 @@ namespace android {
// static
status_t AudioTrack::getMinFrameCount(
- int* frameCount,
+ size_t* frameCount,
audio_stream_type_t streamType,
uint32_t sampleRate)
{
@@ -65,11 +65,11 @@ status_t AudioTrack::getMinFrameCount(
// 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;
}
- int afFrameCount;
+ size_t afFrameCount;
if (AudioSystem::getOutputFrameCount(&afFrameCount, streamType) != NO_ERROR) {
return NO_INIT;
}
@@ -120,28 +120,6 @@ AudioTrack::AudioTrack(
0 /*sharedBuffer*/, false /*threadCanCallJava*/, sessionId);
}
-// DEPRECATED
-AudioTrack::AudioTrack(
- int streamType,
- uint32_t sampleRate,
- int format,
- int channelMask,
- int frameCount,
- uint32_t flags,
- callback_t cbf,
- void* user,
- int notificationFrames,
- int sessionId)
- : mStatus(NO_INIT),
- mIsTimed(false),
- mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT)
-{
- mStatus = set((audio_stream_type_t)streamType, sampleRate, (audio_format_t)format,
- (audio_channel_mask_t) channelMask,
- frameCount, (audio_output_flags_t)flags, cbf, user, notificationFrames,
- 0 /*sharedBuffer*/, false /*threadCanCallJava*/, sessionId);
-}
-
AudioTrack::AudioTrack(
audio_stream_type_t streamType,
uint32_t sampleRate,
@@ -188,7 +166,7 @@ status_t AudioTrack::set(
uint32_t sampleRate,
audio_format_t format,
audio_channel_mask_t channelMask,
- int frameCount,
+ int frameCountInt,
audio_output_flags_t flags,
callback_t cbf,
void* user,
@@ -197,10 +175,17 @@ status_t AudioTrack::set(
bool threadCanCallJava,
int sessionId)
{
+ // FIXME "int" here is legacy and will be replaced by size_t later
+ if (frameCountInt < 0) {
+ ALOGE("Invalid frame count %d", frameCountInt);
+ return BAD_VALUE;
+ }
+ size_t frameCount = frameCountInt;
- ALOGV_IF(sharedBuffer != 0, "sharedBuffer: %p, size: %d", sharedBuffer->pointer(), sharedBuffer->size());
+ ALOGV_IF(sharedBuffer != 0, "sharedBuffer: %p, size: %d", sharedBuffer->pointer(),
+ sharedBuffer->size());
- ALOGV("set() streamType %d frameCount %d flags %04x", streamType, frameCount, flags);
+ ALOGV("set() streamType %d frameCount %u flags %04x", streamType, frameCount, flags);
AutoMutex lock(mLock);
if (mAudioTrack != 0) {
@@ -214,7 +199,7 @@ status_t AudioTrack::set(
}
if (sampleRate == 0) {
- int afSampleRate;
+ uint32_t afSampleRate;
if (AudioSystem::getOutputSamplingRate(&afSampleRate, streamType) != NO_ERROR) {
return NO_INIT;
}
@@ -307,6 +292,15 @@ status_t AudioTrack::set(
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;
@@ -318,7 +312,6 @@ status_t AudioTrack::set(
mUpdatePeriod = 0;
mFlushed = false;
AudioSystem::acquireAudioSessionId(mSessionId);
- mRestoreStatus = NO_ERROR;
return NO_ERROR;
}
@@ -349,20 +342,11 @@ int AudioTrack::channelCount() const
return mChannelCount;
}
-uint32_t AudioTrack::frameCount() const
+size_t AudioTrack::frameCount() const
{
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;
@@ -390,7 +374,7 @@ void AudioTrack::start()
cblk->lock.lock();
cblk->bufferTimeoutMs = MAX_STARTUP_TIMEOUT_MS;
cblk->waitTimeMs = 0;
- android_atomic_and(~CBLK_DISABLED_ON, &cblk->flags);
+ android_atomic_and(~CBLK_DISABLED, &cblk->flags);
if (t != 0) {
t->resume();
} else {
@@ -399,19 +383,21 @@ void AudioTrack::start()
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_MSK)) {
+ if (!(cblk->flags & CBLK_INVALID)) {
cblk->lock.unlock();
ALOGV("mAudioTrack->start()");
status = mAudioTrack->start();
cblk->lock.lock();
if (status == DEAD_OBJECT) {
- android_atomic_or(CBLK_INVALID_ON, &cblk->flags);
+ android_atomic_or(CBLK_INVALID, &cblk->flags);
}
}
- if (cblk->flags & CBLK_INVALID_MSK) {
- status = restoreTrack_l(cblk, true);
+ if (cblk->flags & CBLK_INVALID) {
+ audio_track_cblk_t* temp = cblk;
+ status = restoreTrack_l(temp, true /*fromStart*/);
+ cblk = temp;
}
cblk->lock.unlock();
if (status != NO_ERROR) {
@@ -528,14 +514,9 @@ status_t AudioTrack::setVolume(float left, float right)
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)
@@ -560,9 +541,9 @@ void AudioTrack::getAuxEffectSendLevel(float* level) const
}
}
-status_t AudioTrack::setSampleRate(int rate)
+status_t AudioTrack::setSampleRate(uint32_t rate)
{
- int afSamplingRate;
+ uint32_t afSamplingRate;
if (mIsTimed) {
return INVALID_OPERATION;
@@ -572,7 +553,7 @@ status_t AudioTrack::setSampleRate(int rate)
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;
@@ -582,7 +563,7 @@ status_t AudioTrack::setSampleRate(int rate)
uint32_t AudioTrack::getSampleRate() const
{
if (mIsTimed) {
- return INVALID_OPERATION;
+ return 0;
}
AutoMutex lock(mLock);
@@ -617,12 +598,14 @@ status_t AudioTrack::setLoop_l(uint32_t loopStart, uint32_t loopEnd, int loopCou
if (loopStart >= loopEnd ||
loopEnd - loopStart > cblk->frameCount ||
cblk->server > loopStart) {
- ALOGE("setLoop invalid value: loopStart %d, loopEnd %d, loopCount %d, framecount %d, user %d", loopStart, loopEnd, loopCount, cblk->frameCount, cblk->user);
+ ALOGE("setLoop invalid value: loopStart %d, loopEnd %d, loopCount %d, framecount %d, "
+ "user %d", loopStart, loopEnd, loopCount, cblk->frameCount, cblk->user);
return BAD_VALUE;
}
if ((mSharedBuffer != 0) && (loopEnd > cblk->frameCount)) {
- ALOGE("setLoop invalid value: loop markers beyond data: loopStart %d, loopEnd %d, framecount %d",
+ ALOGE("setLoop invalid value: loop markers beyond data: loopStart %d, loopEnd %d, "
+ "framecount %d",
loopStart, loopEnd, cblk->frameCount);
return BAD_VALUE;
}
@@ -683,12 +666,13 @@ status_t AudioTrack::setPosition(uint32_t position)
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_ON, &mCblk->flags);
+ cblk->server = position;
+ android_atomic_or(CBLK_FORCEREADY, &cblk->flags);
return NO_ERROR;
}
@@ -710,7 +694,8 @@ status_t AudioTrack::reload()
flush_l();
- mCblk->stepUser(mCblk->frameCount);
+ audio_track_cblk_t* cblk = mCblk;
+ cblk->stepUserOut(cblk->frameCount);
return NO_ERROR;
}
@@ -751,7 +736,7 @@ status_t AudioTrack::createTrack_l(
uint32_t sampleRate,
audio_format_t format,
audio_channel_mask_t channelMask,
- int frameCount,
+ size_t frameCount,
audio_output_flags_t flags,
const sp<IMemory>& sharedBuffer,
audio_io_handle_t output)
@@ -791,7 +776,7 @@ status_t AudioTrack::createTrack_l(
// Same comment as below about ignoring frameCount parameter for set()
frameCount = sharedBuffer->size();
} else if (frameCount == 0) {
- int afFrameCount;
+ size_t afFrameCount;
if (AudioSystem::getFrameCount(output, streamType, &afFrameCount) != NO_ERROR) {
return NO_INIT;
}
@@ -823,11 +808,11 @@ status_t AudioTrack::createTrack_l(
} 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;
}
- int afFrameCount;
+ size_t afFrameCount;
if (AudioSystem::getFrameCount(output, streamType, &afFrameCount) != NO_ERROR) {
return NO_INIT;
}
@@ -836,8 +821,8 @@ status_t AudioTrack::createTrack_l(
uint32_t minBufCount = afLatency / ((1000 * afFrameCount)/afSampleRate);
if (minBufCount < 2) minBufCount = 2;
- int minFrameCount = (afFrameCount*sampleRate*minBufCount)/afSampleRate;
- ALOGV("minFrameCount: %d, afFrameCount=%d, minBufCount=%d, sampleRate=%d, afSampleRate=%d"
+ size_t minFrameCount = (afFrameCount*sampleRate*minBufCount)/afSampleRate;
+ ALOGV("minFrameCount: %u, afFrameCount=%d, minBufCount=%d, sampleRate=%u, afSampleRate=%u"
", afLatency=%d",
minFrameCount, afFrameCount, minBufCount, sampleRate, afSampleRate, afLatency);
@@ -849,7 +834,7 @@ status_t AudioTrack::createTrack_l(
}
// Make sure that application is notified with sufficient margin
// before underrun
- if (mNotificationFramesAct > (uint32_t)frameCount/2) {
+ if (mNotificationFramesAct > frameCount/2) {
mNotificationFramesAct = frameCount/2;
}
if (frameCount < minFrameCount) {
@@ -879,10 +864,12 @@ status_t AudioTrack::createTrack_l(
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,
@@ -893,49 +880,49 @@ status_t AudioTrack::createTrack_l(
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_OUT, &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) | uint16_t(mVolume[LEFT] * 0x1000));
- mCblk->setSendLevel(mSendLevel);
+ cblk->setVolumeLR((uint32_t(uint16_t(mVolume[RIGHT] * 0x1000)) << 16) |
+ uint16_t(mVolume[LEFT] * 0x1000));
+ 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;
}
@@ -952,10 +939,10 @@ status_t AudioTrack::obtainBuffer(Buffer* audioBuffer, int32_t waitCount)
audioBuffer->frameCount = 0;
audioBuffer->size = 0;
- uint32_t framesAvail = cblk->framesAvailable();
+ uint32_t framesAvail = cblk->framesAvailableOut();
cblk->lock.lock();
- if (cblk->flags & CBLK_INVALID_MSK) {
+ if (cblk->flags & CBLK_INVALID) {
goto create_new_track;
}
cblk->lock.unlock();
@@ -974,18 +961,23 @@ status_t AudioTrack::obtainBuffer(Buffer* audioBuffer, int32_t waitCount)
cblk->lock.unlock();
return WOULD_BLOCK;
}
- if (!(cblk->flags & CBLK_INVALID_MSK)) {
+ 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();
}
- if (cblk->flags & CBLK_INVALID_MSK) {
+ if (cblk->flags & CBLK_INVALID) {
goto create_new_track;
}
if (CC_UNLIKELY(result != NO_ERROR)) {
@@ -994,16 +986,18 @@ status_t AudioTrack::obtainBuffer(Buffer* audioBuffer, int32_t waitCount)
// timing out when a loop has been set and we have already written upto loop end
// is a normal condition: no need to wake AudioFlinger up.
if (cblk->user < cblk->loopEnd) {
- ALOGW( "obtainBuffer timed out (is the CPU pegged?) %p name=%#x"
- "user=%08x, server=%08x", this, cblk->mName, cblk->user, cblk->server);
+ ALOGW("obtainBuffer timed out (is the CPU pegged?) %p name=%#x user=%08x, "
+ "server=%08x", this, cblk->mName, cblk->user, cblk->server);
//unlock cblk mutex before calling mAudioTrack->start() (see issue #1617140)
cblk->lock.unlock();
result = mAudioTrack->start();
cblk->lock.lock();
if (result == DEAD_OBJECT) {
- android_atomic_or(CBLK_INVALID_ON, &cblk->flags);
+ 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);
@@ -1021,7 +1015,7 @@ create_new_track:
}
// read the server count again
start_loop_here:
- framesAvail = cblk->framesAvailable_l();
+ framesAvail = cblk->framesAvailableOut_l();
}
cblk->lock.unlock();
}
@@ -1039,16 +1033,9 @@ create_new_track:
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);
}
@@ -1056,12 +1043,13 @@ create_new_track:
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_MSK)) {
- android_atomic_and(~CBLK_DISABLED_ON, &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();
}
}
@@ -1096,6 +1084,9 @@ ssize_t AudioTrack::write(const void* buffer, size_t userSize)
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;
@@ -1121,8 +1112,8 @@ ssize_t AudioTrack::write(const void* buffer, size_t userSize)
} else {
toWrite = audioBuffer.size;
memcpy(audioBuffer.i8, src, toWrite);
- src += toWrite;
}
+ src += toWrite;
userSize -= toWrite;
written += toWrite;
@@ -1140,24 +1131,33 @@ TimedAudioTrack::TimedAudioTrack() {
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_MSK)) {
+ 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_ON, &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_MSK) {
- 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);
@@ -1172,10 +1172,11 @@ status_t TimedAudioTrack::queueTimedBuffer(const sp<IMemory>& buffer,
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_MSK)) {
- android_atomic_and(~CBLK_DISABLED_ON, &mCblk->flags);
+ mActive && (cblk->flags & CBLK_DISABLED)) {
+ android_atomic_and(~CBLK_DISABLED, &cblk->flags);
ALOGW("queueTimedBuffer() track %p disabled, restarting", this);
mAudioTrack->start();
}
@@ -1206,10 +1207,13 @@ bool AudioTrack::processAudioBuffer(const sp<AudioTrackThread>& thread)
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_ON, &cblk->flags) & CBLK_UNDERRUN_MSK)) {
+ if (!(android_atomic_or(CBLK_UNDERRUN, &cblk->flags) & CBLK_UNDERRUN)) {
mCbf(EVENT_UNDERRUN, mUserData, 0);
if (cblk->server == cblk->frameCount) {
mCbf(EVENT_BUFFER_END, mUserData, 0);
@@ -1265,7 +1269,8 @@ bool AudioTrack::processAudioBuffer(const sp<AudioTrackThread>& thread)
status_t err = obtainBuffer(&audioBuffer, waitCount);
if (err < NO_ERROR) {
if (err != TIMED_OUT) {
- ALOGE_IF(err != status_t(NO_MORE_BUFFERS), "Error obtaining an audio buffer, giving up.");
+ ALOGE_IF(err != status_t(NO_MORE_BUFFERS),
+ "Error obtaining an audio buffer, giving up.");
return false;
}
break;
@@ -1302,10 +1307,10 @@ bool AudioTrack::processAudioBuffer(const sp<AudioTrackThread>& thread)
}
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;
@@ -1321,110 +1326,90 @@ bool AudioTrack::processAudioBuffer(const sp<AudioTrackThread>& thread)
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_ON, &cblk->flags) & CBLK_RESTORING_MSK)) {
- 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();
-
- // 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_ON, &mCblk->flags);
- // stepUser() clears CBLK_UNDERRUN_ON flag enabling underrun callbacks to
- // the client
- mCblk->stepUser(frames);
+ // 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 (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);
}
+ // 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 (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;
- }
}
- if (result != NO_ERROR) {
- android_atomic_and(~CBLK_RESTORING_ON, &cblk->flags);
- ALOGW_IF(result != NO_ERROR, "restoreTrack_l() failed status %d", result);
+ if (mSharedBuffer != 0) {
+ newCblk->stepUserOut(newCblk->frameCount);
+ }
+ if (mActive) {
+ result = mAudioTrack->start();
+ ALOGW_IF(result != NO_ERROR, "restoreTrack_l() start() failed status %d", result);
}
- mRestoreStatus = result;
- // signal old cblk condition for other threads waiting for restore completion
- android_atomic_or(CBLK_RESTORED_ON, &cblk->flags);
- cblk->cv.broadcast();
- } else {
- if (!(cblk->flags & CBLK_RESTORED_MSK)) {
- ALOGW("dead IAudioTrack, waiting for a new one TID %d", gettid());
- mLock.unlock();
- result = cblk->cv.waitRelative(cblk->lock, milliseconds(RESTORE_TIMEOUT_MS));
- if (result == NO_ERROR) {
- result = mRestoreStatus;
- }
- cblk->lock.unlock();
- mLock.lock();
- } else {
- ALOGW("dead IAudioTrack, already restored TID %d", gettid());
- result = mRestoreStatus;
- cblk->lock.unlock();
+ 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());
@@ -1438,12 +1423,16 @@ status_t AudioTrack::dump(int fd, const Vector<String16>& args) const
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]);
+ 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);
+ snprintf(buffer, 255, " format(%d), channel count(%d), frame count(%d)\n", mFormat,
+ 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);
@@ -1505,20 +1494,20 @@ void AudioTrack::AudioTrackThread::resume()
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_MSK) {
+ 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;
@@ -1542,14 +1531,14 @@ uint32_t audio_track_cblk_t::stepUser(uint32_t frameCount)
user = u;
// Clear flow control error condition as new data has been written/read to/from buffer.
- if (flags & CBLK_UNDERRUN_MSK) {
- android_atomic_and(~CBLK_UNDERRUN_MSK, &flags);
+ if (flags & CBLK_UNDERRUN) {
+ android_atomic_and(~CBLK_UNDERRUN, &flags);
}
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);
@@ -1562,7 +1551,7 @@ bool audio_track_cblk_t::stepServer(uint32_t frameCount)
bool flushed = (s == user);
s += frameCount;
- if (flags & CBLK_DIRECTION_MSK) {
+ 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) {
@@ -1600,30 +1589,30 @@ bool audio_track_cblk_t::stepServer(uint32_t frameCount)
server = s;
- if (!(flags & CBLK_INVALID_MSK)) {
+ if (!(flags & CBLK_INVALID)) {
cv.signal();
}
lock.unlock();
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_MSK) {
+ if (isOut) {
uint32_t limit = (s < loopStart) ? s : loopStart;
return limit + frameCount - u;
} else {
@@ -1631,12 +1620,12 @@ uint32_t audio_track_cblk_t::framesAvailable_l()
}
}
-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_MSK) {
+ if (isOut) {
if (u < loopEnd) {
return u - s;
} else {
diff --git a/media/libmedia/IAudioFlinger.cpp b/media/libmedia/IAudioFlinger.cpp
index ce8ffc4..79c3361 100644
--- a/media/libmedia/IAudioFlinger.cpp
+++ b/media/libmedia/IAudioFlinger.cpp
@@ -89,8 +89,8 @@ public:
uint32_t sampleRate,
audio_format_t format,
audio_channel_mask_t channelMask,
- int frameCount,
- track_flags_t flags,
+ size_t frameCount,
+ track_flags_t *flags,
const sp<IMemory>& sharedBuffer,
audio_io_handle_t output,
pid_t tid,
@@ -106,7 +106,8 @@ public:
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 @@ public:
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;
@@ -138,7 +143,7 @@ public:
uint32_t sampleRate,
audio_format_t format,
audio_channel_mask_t channelMask,
- int frameCount,
+ size_t frameCount,
track_flags_t flags,
pid_t tid,
int *sessionId,
@@ -522,7 +527,7 @@ public:
return status;
}
- virtual unsigned int getInputFramesLost(audio_io_handle_t ioHandle) const
+ virtual size_t getInputFramesLost(audio_io_handle_t ioHandle) const
{
Parcel data, reply;
data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
@@ -690,7 +695,7 @@ public:
return (audio_module_handle_t) reply.readInt32();
}
- virtual int32_t getPrimaryOutputSamplingRate()
+ virtual uint32_t getPrimaryOutputSamplingRate()
{
Parcel data, reply;
data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
@@ -698,7 +703,7 @@ public:
return reply.readInt32();
}
- virtual int32_t getPrimaryOutputFrameCount()
+ virtual size_t getPrimaryOutputFrameCount()
{
Parcel data, reply;
data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
@@ -723,7 +728,7 @@ status_t BnAudioFlinger::onTransact(
uint32_t sampleRate = data.readInt32();
audio_format_t format = (audio_format_t) data.readInt32();
audio_channel_mask_t channelMask = data.readInt32();
- size_t bufferCount = data.readInt32();
+ size_t frameCount = data.readInt32();
track_flags_t flags = (track_flags_t) data.readInt32();
sp<IMemory> buffer = interface_cast<IMemory>(data.readStrongBinder());
audio_io_handle_t output = (audio_io_handle_t) data.readInt32();
@@ -732,7 +737,8 @@ status_t BnAudioFlinger::onTransact(
status_t status;
sp<IAudioTrack> track = createTrack(pid,
(audio_stream_type_t) streamType, sampleRate, format,
- channelMask, bufferCount, flags, buffer, output, tid, &sessionId, &status);
+ channelMask, frameCount, &flags, buffer, output, tid, &sessionId, &status);
+ reply->writeInt32(flags);
reply->writeInt32(sessionId);
reply->writeInt32(status);
reply->writeStrongBinder(track->asBinder());
@@ -745,13 +751,13 @@ status_t BnAudioFlinger::onTransact(
uint32_t sampleRate = data.readInt32();
audio_format_t format = (audio_format_t) data.readInt32();
audio_channel_mask_t channelMask = data.readInt32();
- size_t bufferCount = data.readInt32();
+ size_t frameCount = data.readInt32();
track_flags_t flags = (track_flags_t) data.readInt32();
pid_t tid = (pid_t) data.readInt32();
int sessionId = data.readInt32();
status_t status;
sp<IAudioRecord> record = openRecord(pid, input,
- sampleRate, format, channelMask, bufferCount, flags, tid, &sessionId, &status);
+ sampleRate, format, channelMask, frameCount, flags, tid, &sessionId, &status);
reply->writeInt32(sessionId);
reply->writeInt32(status);
reply->writeStrongBinder(record->asBinder());
@@ -865,7 +871,8 @@ status_t BnAudioFlinger::onTransact(
case REGISTER_CLIENT: {
CHECK_INTERFACE(IAudioFlinger, data, reply);
- sp<IAudioFlingerClient> client = interface_cast<IAudioFlingerClient>(data.readStrongBinder());
+ sp<IAudioFlingerClient> client = interface_cast<IAudioFlingerClient>(
+ data.readStrongBinder());
registerClient(client);
return NO_ERROR;
} break;
@@ -965,8 +972,8 @@ status_t BnAudioFlinger::onTransact(
case GET_RENDER_POSITION: {
CHECK_INTERFACE(IAudioFlinger, data, reply);
audio_io_handle_t output = (audio_io_handle_t) data.readInt32();
- uint32_t halFrames;
- uint32_t dspFrames;
+ size_t halFrames;
+ size_t dspFrames;
status_t status = getRenderPosition(&halFrames, &dspFrames, output);
reply->writeInt32(status);
if (status == NO_ERROR) {
@@ -1043,7 +1050,8 @@ status_t BnAudioFlinger::onTransact(
int id;
int enabled;
- sp<IEffect> effect = createEffect(pid, &desc, client, priority, output, sessionId, &status, &id, &enabled);
+ sp<IEffect> effect = createEffect(pid, &desc, client, priority, output, sessionId,
+ &status, &id, &enabled);
reply->writeInt32(status);
reply->writeInt32(id);
reply->writeInt32(enabled);
diff --git a/media/libmedia/IAudioFlingerClient.cpp b/media/libmedia/IAudioFlingerClient.cpp
index 4178b29..2d1e0f8 100644
--- a/media/libmedia/IAudioFlingerClient.cpp
+++ b/media/libmedia/IAudioFlingerClient.cpp
@@ -50,7 +50,8 @@ public:
ALOGV("ioConfigChanged stream %d", stream);
data.writeInt32(stream);
} else if (event != AudioSystem::OUTPUT_CLOSED && event != AudioSystem::INPUT_CLOSED) {
- const AudioSystem::OutputDescriptor *desc = (const AudioSystem::OutputDescriptor *)param2;
+ const AudioSystem::OutputDescriptor *desc =
+ (const AudioSystem::OutputDescriptor *)param2;
data.writeInt32(desc->samplingRate);
data.writeInt32(desc->format);
data.writeInt32(desc->channels);
diff --git a/media/libmedia/IAudioPolicyService.cpp b/media/libmedia/IAudioPolicyService.cpp
index 401437c..769deae 100644
--- a/media/libmedia/IAudioPolicyService.cpp
+++ b/media/libmedia/IAudioPolicyService.cpp
@@ -399,13 +399,15 @@ status_t BnAudioPolicyService::onTransact(
case SET_PHONE_STATE: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
- reply->writeInt32(static_cast <uint32_t>(setPhoneState((audio_mode_t) data.readInt32())));
+ reply->writeInt32(static_cast <uint32_t>(setPhoneState(
+ (audio_mode_t) data.readInt32())));
return NO_ERROR;
} break;
case SET_FORCE_USE: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
- audio_policy_force_use_t usage = static_cast <audio_policy_force_use_t>(data.readInt32());
+ audio_policy_force_use_t usage = static_cast <audio_policy_force_use_t>(
+ data.readInt32());
audio_policy_forced_cfg_t config =
static_cast <audio_policy_forced_cfg_t>(data.readInt32());
reply->writeInt32(static_cast <uint32_t>(setForceUse(usage, config)));
@@ -414,7 +416,8 @@ status_t BnAudioPolicyService::onTransact(
case GET_FORCE_USE: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
- audio_policy_force_use_t usage = static_cast <audio_policy_force_use_t>(data.readInt32());
+ audio_policy_force_use_t usage = static_cast <audio_policy_force_use_t>(
+ data.readInt32());
reply->writeInt32(static_cast <uint32_t>(getForceUse(usage)));
return NO_ERROR;
} break;
diff --git a/media/libmedia/SoundPool.cpp b/media/libmedia/SoundPool.cpp
index abc8899..204e0ce 100644
--- a/media/libmedia/SoundPool.cpp
+++ b/media/libmedia/SoundPool.cpp
@@ -568,8 +568,8 @@ void SoundChannel::play(const sp<Sample>& sample, int nextChannelID, float leftV
}
// initialize track
- int afFrameCount;
- int afSampleRate;
+ size_t afFrameCount;
+ 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 @@ bool ToneGenerator::initAudioTrack() {
goto initAudioTrack_exit;
}
- mpAudioTrack->setVolume(mVolume, mVolume);
+ mpAudioTrack->setVolume(mVolume);
mState = TONE_INIT;
diff --git a/media/libmedia/Visualizer.cpp b/media/libmedia/Visualizer.cpp
index 8196e10..5b4071b 100644
--- a/media/libmedia/Visualizer.cpp
+++ b/media/libmedia/Visualizer.cpp
@@ -88,7 +88,8 @@ status_t Visualizer::setEnabled(bool enabled)
return status;
}
-status_t Visualizer::setCaptureCallBack(capture_cbk_t cbk, void* user, uint32_t flags, uint32_t rate)
+status_t Visualizer::setCaptureCallBack(capture_cbk_t cbk, void* user, uint32_t flags,
+ uint32_t rate)
{
if (rate > CAPTURE_RATE_MAX) {
return BAD_VALUE;
@@ -334,7 +335,8 @@ void Visualizer::controlStatusChanged(bool controlGranted) {
//-------------------------------------------------------------------------
-Visualizer::CaptureThread::CaptureThread(Visualizer& receiver, uint32_t captureRate, bool bCanCallJava)
+Visualizer::CaptureThread::CaptureThread(Visualizer& receiver, uint32_t captureRate,
+ bool bCanCallJava)
: Thread(bCanCallJava), mReceiver(receiver)
{
mSleepTimeUs = 1000000000 / captureRate;
diff --git a/media/libmedia_native/Android.mk b/media/libmedia_native/Android.mk
deleted file mode 100644
index 065a90f..0000000
--- a/media/libmedia_native/Android.mk
+++ /dev/null
@@ -1,11 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES :=
-
-LOCAL_MODULE:= libmedia_native
-
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/media/libmediaplayerservice/Android.mk b/media/libmediaplayerservice/Android.mk
index 5b5ed71..48f48e4 100644
--- a/media/libmediaplayerservice/Android.mk
+++ b/media/libmediaplayerservice/Android.mk
@@ -28,7 +28,6 @@ LOCAL_SHARED_LIBRARIES := \
libdl \
libgui \
libmedia \
- libmedia_native \
libsonivox \
libstagefright \
libstagefright_foundation \
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 9bedff1..c3e5c40 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -1387,8 +1387,8 @@ status_t MediaPlayerService::AudioOutput::open(
}
ALOGV("open(%u, %d, 0x%x, %d, %d, %d)", sampleRate, channelCount, channelMask,
format, bufferCount, mSessionId);
- int afSampleRate;
- int afFrameCount;
+ uint32_t afSampleRate;
+ size_t afFrameCount;
uint32_t frameCount;
if (AudioSystem::getOutputFrameCount(&afFrameCount, mStreamType) != NO_ERROR) {
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index 1ddf775..756e76a 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -513,8 +513,6 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
}
}
} else if (what == Renderer::kWhatFlushComplete) {
- CHECK_EQ(what, (int32_t)Renderer::kWhatFlushComplete);
-
int32_t audio;
CHECK(msg->findInt32("audio", &audio));
diff --git a/media/libnbaio/NBAIO.cpp b/media/libnbaio/NBAIO.cpp
index 00d2017..e0d2c21 100644
--- a/media/libnbaio/NBAIO.cpp
+++ b/media/libnbaio/NBAIO.cpp
@@ -24,44 +24,55 @@ namespace android {
size_t Format_frameSize(NBAIO_Format format)
{
- switch (format) {
- case Format_SR44_1_C2_I16:
- case Format_SR48_C2_I16:
- return 2 * sizeof(short);
- case Format_SR44_1_C1_I16:
- case Format_SR48_C1_I16:
- return 1 * sizeof(short);
- case Format_Invalid:
- default:
- return 0;
- }
+ return Format_channelCount(format) * sizeof(short);
}
size_t Format_frameBitShift(NBAIO_Format format)
{
- switch (format) {
- case Format_SR44_1_C2_I16:
- case Format_SR48_C2_I16:
- return 2; // 1 << 2 == 2 * sizeof(short)
- case Format_SR44_1_C1_I16:
- case Format_SR48_C1_I16:
- return 1; // 1 << 1 == 1 * sizeof(short)
- case Format_Invalid:
- default:
- return 0;
- }
+ // sizeof(short) == 2, so frame size == 1 << channels
+ return Format_channelCount(format);
}
+enum {
+ Format_SR_8000,
+ Format_SR_11025,
+ Format_SR_16000,
+ Format_SR_22050,
+ Format_SR_24000,
+ Format_SR_32000,
+ Format_SR_44100,
+ Format_SR_48000,
+ Format_SR_Mask = 7
+};
+
+enum {
+ Format_C_1 = 0x08,
+ Format_C_2 = 0x10,
+ Format_C_Mask = 0x18
+};
+
unsigned Format_sampleRate(NBAIO_Format format)
{
- switch (format) {
- case Format_SR44_1_C1_I16:
- case Format_SR44_1_C2_I16:
+ if (format == Format_Invalid) {
+ return 0;
+ }
+ switch (format & Format_SR_Mask) {
+ case Format_SR_8000:
+ return 8000;
+ case Format_SR_11025:
+ return 11025;
+ case Format_SR_16000:
+ return 16000;
+ case Format_SR_22050:
+ return 22050;
+ case Format_SR_24000:
+ return 24000;
+ case Format_SR_32000:
+ return 32000;
+ case Format_SR_44100:
return 44100;
- case Format_SR48_C1_I16:
- case Format_SR48_C2_I16:
+ case Format_SR_48000:
return 48000;
- case Format_Invalid:
default:
return 0;
}
@@ -69,14 +80,14 @@ unsigned Format_sampleRate(NBAIO_Format format)
unsigned Format_channelCount(NBAIO_Format format)
{
- switch (format) {
- case Format_SR44_1_C1_I16:
- case Format_SR48_C1_I16:
+ if (format == Format_Invalid) {
+ return 0;
+ }
+ switch (format & Format_C_Mask) {
+ case Format_C_1:
return 1;
- case Format_SR44_1_C2_I16:
- case Format_SR48_C2_I16:
+ case Format_C_2:
return 2;
- case Format_Invalid:
default:
return 0;
}
@@ -84,11 +95,46 @@ unsigned Format_channelCount(NBAIO_Format format)
NBAIO_Format Format_from_SR_C(unsigned sampleRate, unsigned channelCount)
{
- if (sampleRate == 44100 && channelCount == 2) return Format_SR44_1_C2_I16;
- if (sampleRate == 48000 && channelCount == 2) return Format_SR48_C2_I16;
- if (sampleRate == 44100 && channelCount == 1) return Format_SR44_1_C1_I16;
- if (sampleRate == 48000 && channelCount == 1) return Format_SR48_C1_I16;
- return Format_Invalid;
+ NBAIO_Format format;
+ switch (sampleRate) {
+ case 8000:
+ format = Format_SR_8000;
+ break;
+ case 11025:
+ format = Format_SR_11025;
+ break;
+ case 16000:
+ format = Format_SR_16000;
+ break;
+ case 22050:
+ format = Format_SR_22050;
+ break;
+ case 24000:
+ format = Format_SR_24000;
+ break;
+ case 32000:
+ format = Format_SR_32000;
+ break;
+ case 44100:
+ format = Format_SR_44100;
+ break;
+ case 48000:
+ format = Format_SR_48000;
+ break;
+ default:
+ return Format_Invalid;
+ }
+ switch (channelCount) {
+ case 1:
+ format |= Format_C_1;
+ break;
+ case 2:
+ format |= Format_C_2;
+ break;
+ default:
+ return Format_Invalid;
+ }
+ return format;
}
// This is a default implementation; it is expected that subclasses will optimize this.
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 84b4962..a135222 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -803,6 +803,8 @@ status_t ACodec::setComponentRole(
"audio_decoder.raw", "audio_encoder.raw" },
{ MEDIA_MIMETYPE_AUDIO_FLAC,
"audio_decoder.flac", "audio_encoder.flac" },
+ { MEDIA_MIMETYPE_AUDIO_MSGSM,
+ "audio_decoder.gsm", "audio_encoder.gsm" },
};
static const size_t kNumMimeToRole =
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index faa0f31..a056706 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -78,7 +78,6 @@ LOCAL_SHARED_LIBRARIES := \
libicuuc \
liblog \
libmedia \
- libmedia_native \
libsonivox \
libssl \
libstagefright_omx \
diff --git a/media/libstagefright/AudioSource.cpp b/media/libstagefright/AudioSource.cpp
index 861aebe..3cf4d5c 100644
--- a/media/libstagefright/AudioSource.cpp
+++ b/media/libstagefright/AudioSource.cpp
@@ -58,7 +58,7 @@ AudioSource::AudioSource(
ALOGV("sampleRate: %d, channelCount: %d", sampleRate, channelCount);
CHECK(channelCount == 1 || channelCount == 2);
- int minFrameCount;
+ size_t minFrameCount;
status_t status = AudioRecord::getMinFrameCount(&minFrameCount,
sampleRate,
AUDIO_FORMAT_PCM_16_BIT,
diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp
index efd7af7..efd7af7 100755..100644
--- a/media/libstagefright/CameraSource.cpp
+++ b/media/libstagefright/CameraSource.cpp
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index 8b52e15..8b52e15 100755..100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
diff --git a/media/libstagefright/MediaDefs.cpp b/media/libstagefright/MediaDefs.cpp
index e7b5903..5d8029c 100644
--- a/media/libstagefright/MediaDefs.cpp
+++ b/media/libstagefright/MediaDefs.cpp
@@ -40,6 +40,7 @@ const char *MEDIA_MIMETYPE_AUDIO_G711_MLAW = "audio/g711-mlaw";
const char *MEDIA_MIMETYPE_AUDIO_RAW = "audio/raw";
const char *MEDIA_MIMETYPE_AUDIO_FLAC = "audio/flac";
const char *MEDIA_MIMETYPE_AUDIO_AAC_ADTS = "audio/aac-adts";
+const char *MEDIA_MIMETYPE_AUDIO_MSGSM = "audio/gsm";
const char *MEDIA_MIMETYPE_CONTAINER_MPEG4 = "video/mp4";
const char *MEDIA_MIMETYPE_CONTAINER_WAV = "audio/x-wav";
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 70de174..22aefcc 100755..100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -1390,6 +1390,8 @@ void OMXCodec::setComponentRole(
"audio_decoder.raw", "audio_encoder.raw" },
{ MEDIA_MIMETYPE_AUDIO_FLAC,
"audio_decoder.flac", "audio_encoder.flac" },
+ { MEDIA_MIMETYPE_AUDIO_MSGSM,
+ "audio_decoder.gsm", "audio_encoder.gsm" },
};
static const size_t kNumMimeToRole =
diff --git a/media/libstagefright/SkipCutBuffer.cpp b/media/libstagefright/SkipCutBuffer.cpp
index 773854f..773854f 100755..100644
--- a/media/libstagefright/SkipCutBuffer.cpp
+++ b/media/libstagefright/SkipCutBuffer.cpp
diff --git a/media/libstagefright/StagefrightMediaScanner.cpp b/media/libstagefright/StagefrightMediaScanner.cpp
index bccffd8..af8186c 100644
--- a/media/libstagefright/StagefrightMediaScanner.cpp
+++ b/media/libstagefright/StagefrightMediaScanner.cpp
@@ -42,7 +42,7 @@ static bool FileHasAcceptableExtension(const char *extension) {
".mpeg", ".ogg", ".mid", ".smf", ".imy", ".wma", ".aac",
".wav", ".amr", ".midi", ".xmf", ".rtttl", ".rtx", ".ota",
".mkv", ".mka", ".webm", ".ts", ".fl", ".flac", ".mxmf",
- ".avi", ".mpeg", ".mpg", ".mpga"
+ ".avi", ".mpeg", ".mpg", ".awb", ".mpga"
};
static const size_t kNumValidExtensions =
sizeof(kValidExtensions) / sizeof(kValidExtensions[0]);
diff --git a/media/libstagefright/ThrottledSource.cpp b/media/libstagefright/ThrottledSource.cpp
index 348a9d3..7496752 100644
--- a/media/libstagefright/ThrottledSource.cpp
+++ b/media/libstagefright/ThrottledSource.cpp
@@ -31,10 +31,6 @@ ThrottledSource::ThrottledSource(
CHECK(mBandwidthLimitBytesPerSecond > 0);
}
-status_t ThrottledSource::initCheck() const {
- return mSource->initCheck();
-}
-
ssize_t ThrottledSource::readAt(off64_t offset, void *data, size_t size) {
Mutex::Autolock autoLock(mLock);
@@ -62,17 +58,9 @@ ssize_t ThrottledSource::readAt(off64_t offset, void *data, size_t size) {
if (whenUs > nowUs) {
usleep(whenUs - nowUs);
}
-
return n;
}
-status_t ThrottledSource::getSize(off64_t *size) {
- return mSource->getSize(size);
-}
-
-uint32_t ThrottledSource::flags() {
- return mSource->flags();
-}
} // namespace android
diff --git a/media/libstagefright/WAVExtractor.cpp b/media/libstagefright/WAVExtractor.cpp
index a38400b..d32f4fb 100644
--- a/media/libstagefright/WAVExtractor.cpp
+++ b/media/libstagefright/WAVExtractor.cpp
@@ -38,6 +38,7 @@ enum {
WAVE_FORMAT_PCM = 0x0001,
WAVE_FORMAT_ALAW = 0x0006,
WAVE_FORMAT_MULAW = 0x0007,
+ WAVE_FORMAT_MSGSM = 0x0031,
WAVE_FORMAT_EXTENSIBLE = 0xFFFE
};
@@ -178,6 +179,7 @@ status_t WAVExtractor::init() {
if (mWaveFormat != WAVE_FORMAT_PCM
&& mWaveFormat != WAVE_FORMAT_ALAW
&& mWaveFormat != WAVE_FORMAT_MULAW
+ && mWaveFormat != WAVE_FORMAT_MSGSM
&& mWaveFormat != WAVE_FORMAT_EXTENSIBLE) {
return ERROR_UNSUPPORTED;
}
@@ -216,6 +218,10 @@ status_t WAVExtractor::init() {
&& mBitsPerSample != 24) {
return ERROR_UNSUPPORTED;
}
+ } else if (mWaveFormat == WAVE_FORMAT_MSGSM) {
+ if (mBitsPerSample != 0) {
+ return ERROR_UNSUPPORTED;
+ }
} else {
CHECK(mWaveFormat == WAVE_FORMAT_MULAW
|| mWaveFormat == WAVE_FORMAT_ALAW);
@@ -283,6 +289,10 @@ status_t WAVExtractor::init() {
mTrackMeta->setCString(
kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_G711_ALAW);
break;
+ case WAVE_FORMAT_MSGSM:
+ mTrackMeta->setCString(
+ kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MSGSM);
+ break;
default:
CHECK_EQ(mWaveFormat, (uint16_t)WAVE_FORMAT_MULAW);
mTrackMeta->setCString(
@@ -294,11 +304,17 @@ status_t WAVExtractor::init() {
mTrackMeta->setInt32(kKeyChannelMask, mChannelMask);
mTrackMeta->setInt32(kKeySampleRate, mSampleRate);
- size_t bytesPerSample = mBitsPerSample >> 3;
-
- int64_t durationUs =
- 1000000LL * (mDataSize / (mNumChannels * bytesPerSample))
- / mSampleRate;
+ int64_t durationUs = 0;
+ if (mWaveFormat == WAVE_FORMAT_MSGSM) {
+ // 65 bytes decode to 320 8kHz samples
+ durationUs =
+ 1000000LL * (mDataSize / 65 * 320) / 8000;
+ } else {
+ size_t bytesPerSample = mBitsPerSample >> 3;
+ durationUs =
+ 1000000LL * (mDataSize / (mNumChannels * bytesPerSample))
+ / mSampleRate;
+ }
mTrackMeta->setInt64(kKeyDuration, durationUs);
@@ -388,7 +404,16 @@ status_t WAVSource::read(
int64_t seekTimeUs;
ReadOptions::SeekMode mode;
if (options != NULL && options->getSeekTo(&seekTimeUs, &mode)) {
- int64_t pos = (seekTimeUs * mSampleRate) / 1000000 * mNumChannels * (mBitsPerSample >> 3);
+ int64_t pos = 0;
+
+ if (mWaveFormat == WAVE_FORMAT_MSGSM) {
+ // 65 bytes decode to 320 8kHz samples
+ int64_t samplenumber = (seekTimeUs * mSampleRate) / 1000000;
+ int64_t framenumber = samplenumber / 320;
+ pos = framenumber * 65;
+ } else {
+ pos = (seekTimeUs * mSampleRate) / 1000000 * mNumChannels * (mBitsPerSample >> 3);
+ }
if (pos > mSize) {
pos = mSize;
}
@@ -412,6 +437,15 @@ status_t WAVSource::read(
maxBytesToRead = maxBytesAvailable;
}
+ if (mWaveFormat == WAVE_FORMAT_MSGSM) {
+ // Microsoft packs 2 frames into 65 bytes, rather than using separate 33-byte frames,
+ // so read multiples of 65, and use smaller buffers to account for ~10:1 expansion ratio
+ if (maxBytesToRead > 1024) {
+ maxBytesToRead = 1024;
+ }
+ maxBytesToRead = (maxBytesToRead / 65) * 65;
+ }
+
ssize_t n = mDataSource->readAt(
mCurrentPos, buffer->data(),
maxBytesToRead);
@@ -468,12 +502,17 @@ status_t WAVSource::read(
}
}
- size_t bytesPerSample = mBitsPerSample >> 3;
+ int64_t timeStampUs = 0;
+
+ if (mWaveFormat == WAVE_FORMAT_MSGSM) {
+ timeStampUs = 1000000LL * (mCurrentPos - mOffset) * 320 / 65 / mSampleRate;
+ } else {
+ size_t bytesPerSample = mBitsPerSample >> 3;
+ timeStampUs = 1000000LL * (mCurrentPos - mOffset)
+ / (mNumChannels * bytesPerSample) / mSampleRate;
+ }
- buffer->meta_data()->setInt64(
- kKeyTime,
- 1000000LL * (mCurrentPos - mOffset)
- / (mNumChannels * bytesPerSample) / mSampleRate);
+ buffer->meta_data()->setInt64(kKeyTime, timeStampUs);
buffer->meta_data()->setInt32(kKeyIsSyncFrame, 1);
mCurrentPos += n;
diff --git a/media/libstagefright/codecs/gsm/Android.mk b/media/libstagefright/codecs/gsm/Android.mk
new file mode 100644
index 0000000..2e43120
--- /dev/null
+++ b/media/libstagefright/codecs/gsm/Android.mk
@@ -0,0 +1,4 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/media/libstagefright/codecs/gsm/dec/Android.mk b/media/libstagefright/codecs/gsm/dec/Android.mk
new file mode 100644
index 0000000..9c0c6ae
--- /dev/null
+++ b/media/libstagefright/codecs/gsm/dec/Android.mk
@@ -0,0 +1,21 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+ SoftGSM.cpp
+
+LOCAL_C_INCLUDES := \
+ frameworks/av/media/libstagefright/include \
+ frameworks/native/include/media/openmax \
+ external/libgsm/inc
+
+LOCAL_SHARED_LIBRARIES := \
+ libstagefright libstagefright_omx libstagefright_foundation libutils
+
+LOCAL_STATIC_LIBRARIES := \
+ libgsm
+
+LOCAL_MODULE := libstagefright_soft_gsmdec
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/media/libstagefright/codecs/gsm/dec/MODULE_LICENSE_APACHE2 b/media/libstagefright/codecs/gsm/dec/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/libstagefright/codecs/gsm/dec/MODULE_LICENSE_APACHE2
diff --git a/media/libstagefright/codecs/gsm/dec/NOTICE b/media/libstagefright/codecs/gsm/dec/NOTICE
new file mode 100644
index 0000000..c5b1efa
--- /dev/null
+++ b/media/libstagefright/codecs/gsm/dec/NOTICE
@@ -0,0 +1,190 @@
+
+ Copyright (c) 2005-2008, 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.
+
+ 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.
+
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
diff --git a/media/libstagefright/codecs/gsm/dec/SoftGSM.cpp b/media/libstagefright/codecs/gsm/dec/SoftGSM.cpp
new file mode 100644
index 0000000..00e0c85
--- /dev/null
+++ b/media/libstagefright/codecs/gsm/dec/SoftGSM.cpp
@@ -0,0 +1,269 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "SoftGSM"
+#include <utils/Log.h>
+
+#include "SoftGSM.h"
+
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/MediaDefs.h>
+
+namespace android {
+
+template<class T>
+static void InitOMXParams(T *params) {
+ params->nSize = sizeof(T);
+ params->nVersion.s.nVersionMajor = 1;
+ params->nVersion.s.nVersionMinor = 0;
+ params->nVersion.s.nRevision = 0;
+ params->nVersion.s.nStep = 0;
+}
+
+SoftGSM::SoftGSM(
+ const char *name,
+ const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData,
+ OMX_COMPONENTTYPE **component)
+ : SimpleSoftOMXComponent(name, callbacks, appData, component),
+ mSignalledError(false) {
+
+ CHECK(!strcmp(name, "OMX.google.gsm.decoder"));
+
+ mGsm = gsm_create();
+ CHECK(mGsm);
+ int msopt = 1;
+ gsm_option(mGsm, GSM_OPT_WAV49, &msopt);
+
+ initPorts();
+}
+
+SoftGSM::~SoftGSM() {
+ gsm_destroy(mGsm);
+}
+
+void SoftGSM::initPorts() {
+ OMX_PARAM_PORTDEFINITIONTYPE def;
+ InitOMXParams(&def);
+
+ def.nPortIndex = 0;
+ def.eDir = OMX_DirInput;
+ def.nBufferCountMin = kNumBuffers;
+ def.nBufferCountActual = def.nBufferCountMin;
+ def.nBufferSize = sizeof(gsm_frame);
+ def.bEnabled = OMX_TRUE;
+ def.bPopulated = OMX_FALSE;
+ def.eDomain = OMX_PortDomainAudio;
+ def.bBuffersContiguous = OMX_FALSE;
+ def.nBufferAlignment = 1;
+
+ def.format.audio.cMIMEType =
+ const_cast<char *>(MEDIA_MIMETYPE_AUDIO_MSGSM);
+
+ def.format.audio.pNativeRender = NULL;
+ def.format.audio.bFlagErrorConcealment = OMX_FALSE;
+ def.format.audio.eEncoding = OMX_AUDIO_CodingGSMFR;
+
+ addPort(def);
+
+ def.nPortIndex = 1;
+ def.eDir = OMX_DirOutput;
+ def.nBufferCountMin = kNumBuffers;
+ def.nBufferCountActual = def.nBufferCountMin;
+ def.nBufferSize = kMaxNumSamplesPerFrame * sizeof(int16_t);
+ def.bEnabled = OMX_TRUE;
+ def.bPopulated = OMX_FALSE;
+ def.eDomain = OMX_PortDomainAudio;
+ def.bBuffersContiguous = OMX_FALSE;
+ def.nBufferAlignment = 2;
+
+ def.format.audio.cMIMEType = const_cast<char *>("audio/raw");
+ def.format.audio.pNativeRender = NULL;
+ def.format.audio.bFlagErrorConcealment = OMX_FALSE;
+ def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
+
+ addPort(def);
+}
+
+OMX_ERRORTYPE SoftGSM::internalGetParameter(
+ OMX_INDEXTYPE index, OMX_PTR params) {
+ switch (index) {
+ case OMX_IndexParamAudioPcm:
+ {
+ OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
+ (OMX_AUDIO_PARAM_PCMMODETYPE *)params;
+
+ if (pcmParams->nPortIndex > 1) {
+ return OMX_ErrorUndefined;
+ }
+
+ pcmParams->eNumData = OMX_NumericalDataSigned;
+ pcmParams->eEndian = OMX_EndianBig;
+ pcmParams->bInterleaved = OMX_TRUE;
+ pcmParams->nBitPerSample = 16;
+ pcmParams->ePCMMode = OMX_AUDIO_PCMModeLinear;
+ pcmParams->eChannelMapping[0] = OMX_AUDIO_ChannelLF;
+ pcmParams->eChannelMapping[1] = OMX_AUDIO_ChannelRF;
+
+ pcmParams->nChannels = 1;
+ pcmParams->nSamplingRate = 8000;
+
+ return OMX_ErrorNone;
+ }
+
+ default:
+ return SimpleSoftOMXComponent::internalGetParameter(index, params);
+ }
+}
+
+OMX_ERRORTYPE SoftGSM::internalSetParameter(
+ OMX_INDEXTYPE index, const OMX_PTR params) {
+ switch (index) {
+ case OMX_IndexParamAudioPcm:
+ {
+ OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
+ (OMX_AUDIO_PARAM_PCMMODETYPE *)params;
+
+ if (pcmParams->nPortIndex != 0 && pcmParams->nPortIndex != 1) {
+ return OMX_ErrorUndefined;
+ }
+
+ if (pcmParams->nChannels != 1) {
+ return OMX_ErrorUndefined;
+ }
+
+ if (pcmParams->nSamplingRate != 8000) {
+ return OMX_ErrorUndefined;
+ }
+
+ return OMX_ErrorNone;
+ }
+
+ case OMX_IndexParamStandardComponentRole:
+ {
+ const OMX_PARAM_COMPONENTROLETYPE *roleParams =
+ (const OMX_PARAM_COMPONENTROLETYPE *)params;
+
+ if (strncmp((const char *)roleParams->cRole,
+ "audio_decoder.gsm",
+ OMX_MAX_STRINGNAME_SIZE - 1)) {
+ return OMX_ErrorUndefined;
+ }
+
+ return OMX_ErrorNone;
+ }
+
+ default:
+ return SimpleSoftOMXComponent::internalSetParameter(index, params);
+ }
+}
+
+void SoftGSM::onQueueFilled(OMX_U32 portIndex) {
+ if (mSignalledError) {
+ return;
+ }
+
+ List<BufferInfo *> &inQueue = getPortQueue(0);
+ List<BufferInfo *> &outQueue = getPortQueue(1);
+
+ while (!inQueue.empty() && !outQueue.empty()) {
+ BufferInfo *inInfo = *inQueue.begin();
+ OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
+
+ BufferInfo *outInfo = *outQueue.begin();
+ OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
+
+ if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
+ inQueue.erase(inQueue.begin());
+ inInfo->mOwnedByUs = false;
+ notifyEmptyBufferDone(inHeader);
+
+ outHeader->nFilledLen = 0;
+ outHeader->nFlags = OMX_BUFFERFLAG_EOS;
+
+ outQueue.erase(outQueue.begin());
+ outInfo->mOwnedByUs = false;
+ notifyFillBufferDone(outHeader);
+ return;
+ }
+
+ if (inHeader->nFilledLen > kMaxNumSamplesPerFrame) {
+ ALOGE("input buffer too large (%ld).", inHeader->nFilledLen);
+ notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+ mSignalledError = true;
+ }
+
+ if(((inHeader->nFilledLen / 65) * 65) != inHeader->nFilledLen) {
+ ALOGE("input buffer not multiple of 65 (%ld).", inHeader->nFilledLen);
+ notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+ mSignalledError = true;
+ }
+
+ uint8_t *inputptr = inHeader->pBuffer + inHeader->nOffset;
+
+ int n = mSignalledError ? 0 : DecodeGSM(mGsm,
+ reinterpret_cast<int16_t *>(outHeader->pBuffer), inputptr, inHeader->nFilledLen);
+
+ outHeader->nTimeStamp = inHeader->nTimeStamp;
+ outHeader->nOffset = 0;
+ outHeader->nFilledLen = n * sizeof(int16_t);
+ outHeader->nFlags = 0;
+
+ inInfo->mOwnedByUs = false;
+ inQueue.erase(inQueue.begin());
+ inInfo = NULL;
+ notifyEmptyBufferDone(inHeader);
+ inHeader = NULL;
+
+ outInfo->mOwnedByUs = false;
+ outQueue.erase(outQueue.begin());
+ outInfo = NULL;
+ notifyFillBufferDone(outHeader);
+ outHeader = NULL;
+ }
+}
+
+
+// static
+int SoftGSM::DecodeGSM(gsm handle,
+ int16_t *out, uint8_t *in, size_t inSize) {
+
+ int ret = 0;
+ while (inSize > 0) {
+ gsm_decode(handle, in, out);
+ in += 33;
+ inSize -= 33;
+ out += 160;
+ ret += 160;
+ gsm_decode(handle, in, out);
+ in += 32;
+ inSize -= 32;
+ out += 160;
+ ret += 160;
+ }
+ return ret;
+}
+
+
+} // namespace android
+
+android::SoftOMXComponent *createSoftOMXComponent(
+ const char *name, const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData, OMX_COMPONENTTYPE **component) {
+ return new android::SoftGSM(name, callbacks, appData, component);
+}
+
diff --git a/media/libstagefright/codecs/gsm/dec/SoftGSM.h b/media/libstagefright/codecs/gsm/dec/SoftGSM.h
new file mode 100644
index 0000000..8ab6116
--- /dev/null
+++ b/media/libstagefright/codecs/gsm/dec/SoftGSM.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SOFT_GSM_H_
+
+#define SOFT_GSM_H_
+
+#include "SimpleSoftOMXComponent.h"
+
+extern "C" {
+#include "gsm.h"
+}
+
+namespace android {
+
+struct SoftGSM : public SimpleSoftOMXComponent {
+ SoftGSM(const char *name,
+ const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData,
+ OMX_COMPONENTTYPE **component);
+
+protected:
+ virtual ~SoftGSM();
+
+ virtual OMX_ERRORTYPE internalGetParameter(
+ OMX_INDEXTYPE index, OMX_PTR params);
+
+ virtual OMX_ERRORTYPE internalSetParameter(
+ OMX_INDEXTYPE index, const OMX_PTR params);
+
+ virtual void onQueueFilled(OMX_U32 portIndex);
+
+private:
+ enum {
+ kNumBuffers = 4,
+ kMaxNumSamplesPerFrame = 16384,
+ };
+
+ bool mSignalledError;
+ gsm mGsm;
+
+ void initPorts();
+
+ static int DecodeGSM(gsm handle, int16_t *out, uint8_t *in, size_t inSize);
+
+ DISALLOW_EVIL_CONSTRUCTORS(SoftGSM);
+};
+
+} // namespace android
+
+#endif // SOFT_GSM_H_
+
diff --git a/media/libstagefright/codecs/on2/dec/SoftVPX.cpp b/media/libstagefright/codecs/on2/dec/SoftVPX.cpp
index bf9ab3a..a400b4c 100644
--- a/media/libstagefright/codecs/on2/dec/SoftVPX.cpp
+++ b/media/libstagefright/codecs/on2/dec/SoftVPX.cpp
@@ -66,7 +66,7 @@ void SoftVPX::initPorts() {
def.eDir = OMX_DirInput;
def.nBufferCountMin = kNumBuffers;
def.nBufferCountActual = def.nBufferCountMin;
- def.nBufferSize = 256 * 1024;
+ def.nBufferSize = 768 * 1024;
def.bEnabled = OMX_TRUE;
def.bPopulated = OMX_FALSE;
def.eDomain = OMX_PortDomainVideo;
diff --git a/media/libstagefright/include/FragmentedMP4Parser.h b/media/libstagefright/include/FragmentedMP4Parser.h
index 0edafb9..dbe02b8 100644
--- a/media/libstagefright/include/FragmentedMP4Parser.h
+++ b/media/libstagefright/include/FragmentedMP4Parser.h
@@ -263,7 +263,7 @@ private:
void copyBuffer(
sp<ABuffer> *dst,
- size_t offset, uint64_t size, size_t extra = 0) const;
+ size_t offset, uint64_t size) const;
DISALLOW_EVIL_CONSTRUCTORS(FragmentedMP4Parser);
};
diff --git a/media/libstagefright/include/ThrottledSource.h b/media/libstagefright/include/ThrottledSource.h
index 7fe7c06..673268b 100644
--- a/media/libstagefright/include/ThrottledSource.h
+++ b/media/libstagefright/include/ThrottledSource.h
@@ -28,18 +28,44 @@ struct ThrottledSource : public DataSource {
const sp<DataSource> &source,
int32_t bandwidthLimitBytesPerSecond);
- virtual status_t initCheck() const;
-
+ // implementation of readAt() that sleeps to achieve the desired max throughput
virtual ssize_t readAt(off64_t offset, void *data, size_t size);
- virtual status_t getSize(off64_t *size);
- virtual uint32_t flags();
+ // returns an empty string to prevent callers from using the Uri to construct a new datasource
+ virtual String8 getUri() {
+ return String8();
+ }
+
+ // following methods all call through to the wrapped DataSource's methods
+
+ status_t initCheck() const {
+ return mSource->initCheck();
+ }
+
+ virtual status_t getSize(off64_t *size) {
+ return mSource->getSize(size);
+ }
+
+ virtual uint32_t flags() {
+ return mSource->flags();
+ }
+
+ virtual status_t reconnectAtOffset(off64_t offset) {
+ return mSource->reconnectAtOffset(offset);
+ }
+
+ virtual sp<DecryptHandle> DrmInitialization(const char *mime = NULL) {
+ return mSource->DrmInitialization(mime);
+ }
+
+ virtual void getDrmInfo(sp<DecryptHandle> &handle, DrmManagerClient **client) {
+ mSource->getDrmInfo(handle, client);
+ };
virtual String8 getMIMEType() const {
return mSource->getMIMEType();
}
-
private:
Mutex mLock;
diff --git a/media/libstagefright/matroska/MatroskaExtractor.cpp b/media/libstagefright/matroska/MatroskaExtractor.cpp
index 8f7d12b..7fc7037 100644
--- a/media/libstagefright/matroska/MatroskaExtractor.cpp
+++ b/media/libstagefright/matroska/MatroskaExtractor.cpp
@@ -758,31 +758,69 @@ static void addESDSFromCodecPrivate(
esds = NULL;
}
-void addVorbisCodecInfo(
+status_t addVorbisCodecInfo(
const sp<MetaData> &meta,
const void *_codecPrivate, size_t codecPrivateSize) {
- // printf("vorbis private data follows:\n");
// hexdump(_codecPrivate, codecPrivateSize);
- CHECK(codecPrivateSize >= 3);
+ if (codecPrivateSize < 1) {
+ return ERROR_MALFORMED;
+ }
const uint8_t *codecPrivate = (const uint8_t *)_codecPrivate;
- CHECK(codecPrivate[0] == 0x02);
- size_t len1 = codecPrivate[1];
- size_t len2 = codecPrivate[2];
+ if (codecPrivate[0] != 0x02) {
+ return ERROR_MALFORMED;
+ }
- CHECK(codecPrivateSize > 3 + len1 + len2);
+ // codecInfo starts with two lengths, len1 and len2, that are
+ // "Xiph-style-lacing encoded"...
- CHECK(codecPrivate[3] == 0x01);
- meta->setData(kKeyVorbisInfo, 0, &codecPrivate[3], len1);
+ size_t offset = 1;
+ size_t len1 = 0;
+ while (offset < codecPrivateSize && codecPrivate[offset] == 0xff) {
+ len1 += 0xff;
+ ++offset;
+ }
+ if (offset >= codecPrivateSize) {
+ return ERROR_MALFORMED;
+ }
+ len1 += codecPrivate[offset++];
- CHECK(codecPrivate[len1 + 3] == 0x03);
+ size_t len2 = 0;
+ while (offset < codecPrivateSize && codecPrivate[offset] == 0xff) {
+ len2 += 0xff;
+ ++offset;
+ }
+ if (offset >= codecPrivateSize) {
+ return ERROR_MALFORMED;
+ }
+ len2 += codecPrivate[offset++];
+
+ if (codecPrivateSize < offset + len1 + len2) {
+ return ERROR_MALFORMED;
+ }
+
+ if (codecPrivate[offset] != 0x01) {
+ return ERROR_MALFORMED;
+ }
+ meta->setData(kKeyVorbisInfo, 0, &codecPrivate[offset], len1);
+
+ offset += len1;
+ if (codecPrivate[offset] != 0x03) {
+ return ERROR_MALFORMED;
+ }
+
+ offset += len2;
+ if (codecPrivate[offset] != 0x05) {
+ return ERROR_MALFORMED;
+ }
- CHECK(codecPrivate[len1 + len2 + 3] == 0x05);
meta->setData(
- kKeyVorbisBooks, 0, &codecPrivate[len1 + len2 + 3],
- codecPrivateSize - len1 - len2 - 3);
+ kKeyVorbisBooks, 0, &codecPrivate[offset],
+ codecPrivateSize - offset);
+
+ return OK;
}
void MatroskaExtractor::addTracks() {
@@ -809,6 +847,8 @@ void MatroskaExtractor::addTracks() {
sp<MetaData> meta = new MetaData;
+ status_t err = OK;
+
switch (track->GetType()) {
case VIDEO_TRACK:
{
@@ -855,7 +895,8 @@ void MatroskaExtractor::addTracks() {
} else if (!strcmp("A_VORBIS", codecID)) {
meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_VORBIS);
- addVorbisCodecInfo(meta, codecPrivate, codecPrivateSize);
+ err = addVorbisCodecInfo(
+ meta, codecPrivate, codecPrivateSize);
} else if (!strcmp("A_MPEG/L3", codecID)) {
meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG);
} else {
@@ -872,6 +913,11 @@ void MatroskaExtractor::addTracks() {
continue;
}
+ if (err != OK) {
+ ALOGE("skipping track, codec specific data was malformed.");
+ continue;
+ }
+
long long durationNs = mSegment->GetDuration();
meta->setInt64(kKeyDuration, (durationNs + 500) / 1000);
diff --git a/media/libstagefright/mp4/FragmentedMP4Parser.cpp b/media/libstagefright/mp4/FragmentedMP4Parser.cpp
index 7fe4e63..54c3d63 100644
--- a/media/libstagefright/mp4/FragmentedMP4Parser.cpp
+++ b/media/libstagefright/mp4/FragmentedMP4Parser.cpp
@@ -1971,8 +1971,8 @@ status_t FragmentedMP4Parser::parseTrackFragmentRun(
}
void FragmentedMP4Parser::copyBuffer(
- sp<ABuffer> *dst, size_t offset, uint64_t size, size_t extra) const {
- sp<ABuffer> buf = new ABuffer(size + extra);
+ sp<ABuffer> *dst, size_t offset, uint64_t size) const {
+ sp<ABuffer> buf = new ABuffer(size);
memcpy(buf->data(), mBuffer->data() + offset, size);
*dst = buf;
diff --git a/media/libstagefright/omx/SoftOMXPlugin.cpp b/media/libstagefright/omx/SoftOMXPlugin.cpp
index 3747b3b..6e1c04d 100644
--- a/media/libstagefright/omx/SoftOMXPlugin.cpp
+++ b/media/libstagefright/omx/SoftOMXPlugin.cpp
@@ -53,6 +53,7 @@ static const struct {
{ "OMX.google.vpx.decoder", "vpxdec", "video_decoder.vpx" },
{ "OMX.google.raw.decoder", "rawdec", "audio_decoder.raw" },
{ "OMX.google.flac.encoder", "flacenc", "audio_encoder.flac" },
+ { "OMX.google.gsm.decoder", "gsmdec", "audio_decoder.gsm" },
};
static const size_t kNumComponents =
diff --git a/media/libstagefright/wifi-display/sink/TunnelRenderer.cpp b/media/libstagefright/wifi-display/sink/TunnelRenderer.cpp
index bc35aef..b913124 100644
--- a/media/libstagefright/wifi-display/sink/TunnelRenderer.cpp
+++ b/media/libstagefright/wifi-display/sink/TunnelRenderer.cpp
@@ -271,6 +271,7 @@ sp<ABuffer> TunnelRenderer::dequeueBuffer() {
if (mFirstFailedAttemptUs + 50000ll > ALooper::GetNowUs()) {
// We're willing to wait a little while to get the right packet.
+#if 0
if (!mRequestedRetransmission) {
ALOGI("requesting retransmission of seqNo %d",
(mLastDequeuedExtSeqNo + 1) & 0xffff);
@@ -280,7 +281,9 @@ sp<ABuffer> TunnelRenderer::dequeueBuffer() {
notify->post();
mRequestedRetransmission = true;
- } else {
+ } else
+#endif
+ {
ALOGI("still waiting for the correct packet to arrive.");
}
diff --git a/media/libstagefright/wifi-display/sink/WifiDisplaySink.cpp b/media/libstagefright/wifi-display/sink/WifiDisplaySink.cpp
index fcd20d4..c3e0470 100644
--- a/media/libstagefright/wifi-display/sink/WifiDisplaySink.cpp
+++ b/media/libstagefright/wifi-display/sink/WifiDisplaySink.cpp
@@ -475,9 +475,10 @@ void WifiDisplaySink::onGetParameterRequest(
int32_t cseq,
const sp<ParsedMessage> &data) {
AString body =
- "wfd_video_formats: xxx\r\n"
- "wfd_audio_codecs: xxx\r\n"
- "wfd_client_rtp_ports: RTP/AVP/UDP;unicast xxx 0 mode=play\r\n";
+ "wfd_video_formats: "
+ "28 00 02 02 FFFFFFFF 0000000 00000000 00 0000 0000 00 none none\r\n"
+ "wfd_audio_codecs: AAC 0000000F 00\r\n"
+ "wfd_client_rtp_ports: RTP/AVP/UDP;unicast 19000 0 mode=play\r\n";
AString response = "RTSP/1.0 200 OK\r\n";
AppendCommonResponse(&response, cseq);
diff --git a/services/audioflinger/Android.mk b/services/audioflinger/Android.mk
index bd9421c..4416b52 100644
--- a/services/audioflinger/Android.mk
+++ b/services/audioflinger/Android.mk
@@ -19,11 +19,9 @@ LOCAL_SRC_FILES:= \
AudioResampler.cpp.arm \
AudioPolicyService.cpp \
ServiceUtilities.cpp \
+ AudioResamplerCubic.cpp.arm \
AudioResamplerSinc.cpp.arm
-# uncomment to enable AudioResampler::MED_QUALITY
-# LOCAL_SRC_FILES += AudioResamplerCubic.cpp.arm
-
LOCAL_SRC_FILES += StateQueue.cpp
# uncomment for debugging timing problems related to StateQueue::push()
@@ -33,7 +31,6 @@ LOCAL_C_INCLUDES := \
$(call include-path-for, audio-effects) \
$(call include-path-for, audio-utils)
-# FIXME keep libmedia_native but remove libmedia after split
LOCAL_SHARED_LIBRARIES := \
libaudioutils \
libcommon_time_client \
@@ -41,7 +38,6 @@ LOCAL_SHARED_LIBRARIES := \
libutils \
libbinder \
libmedia \
- libmedia_native \
libnbaio \
libhardware \
libhardware_legacy \
@@ -74,10 +70,37 @@ LOCAL_CFLAGS += -UFAST_TRACKS_AT_NON_NATIVE_SAMPLE_RATE
# 47.5 seconds at 44.1 kHz, 8 megabytes
# LOCAL_CFLAGS += -DTEE_SINK_FRAMES=0x200000
+# uncomment for dumpsys to write most recent audio input to .wav file
+# 47.5 seconds at 44.1 kHz, 8 megabytes
+# LOCAL_CFLAGS += -DTEE_SINK_INPUT_FRAMES=0x200000
+
# uncomment to enable the audio watchdog
# LOCAL_SRC_FILES += AudioWatchdog.cpp
# LOCAL_CFLAGS += -DAUDIO_WATCHDOG
include $(BUILD_SHARED_LIBRARY)
+#
+# build audio resampler test tool
+#
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+ test-resample.cpp \
+ AudioResampler.cpp.arm \
+ AudioResamplerCubic.cpp.arm \
+ AudioResamplerSinc.cpp.arm
+
+LOCAL_SHARED_LIBRARIES := \
+ libdl \
+ libcutils \
+ libutils
+
+LOCAL_MODULE:= test-resample
+
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_EXECUTABLE)
+
+
include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 76d6447..384f268 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -417,6 +417,12 @@ status_t AudioFlinger::dump(int fd, const Vector<String16>& args)
audio_hw_device_t *dev = mAudioHwDevs.valueAt(i)->hwDevice();
dev->dump(dev, fd);
}
+
+ // dump the serially shared record tee sink
+ if (mRecordTeeSource != 0) {
+ dumpTee(fd, mRecordTeeSource);
+ }
+
if (locked) mLock.unlock();
}
return NO_ERROR;
@@ -444,8 +450,8 @@ sp<IAudioTrack> AudioFlinger::createTrack(
uint32_t sampleRate,
audio_format_t format,
audio_channel_mask_t channelMask,
- int frameCount,
- IAudioFlinger::track_flags_t flags,
+ size_t frameCount,
+ IAudioFlinger::track_flags_t *flags,
const sp<IMemory>& sharedBuffer,
audio_io_handle_t output,
pid_t tid,
@@ -466,6 +472,14 @@ sp<IAudioTrack> AudioFlinger::createTrack(
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);
@@ -941,8 +955,8 @@ status_t AudioFlinger::setParameters(audio_io_handle_t ioHandle, const String8&
String8 AudioFlinger::getParameters(audio_io_handle_t ioHandle, const String8& keys) const
{
-// ALOGV("getParameters() io %d, keys %s, tid %d, calling pid %d",
-// ioHandle, keys.string(), gettid(), IPCThreadState::self()->getCallingPid());
+ ALOGVV("getParameters() io %d, keys %s, tid %d, calling pid %d",
+ ioHandle, keys.string(), gettid(), IPCThreadState::self()->getCallingPid());
Mutex::Autolock _l(mLock);
@@ -1112,7 +1126,8 @@ void AudioFlinger::audioConfigChanged_l(int event, audio_io_handle_t ioHandle, c
// removeClient_l() must be called with AudioFlinger::mLock held
void AudioFlinger::removeClient_l(pid_t pid)
{
- ALOGV("removeClient_l() pid %d, tid %d, calling tid %d", pid, gettid(), IPCThreadState::self()->getCallingPid());
+ ALOGV("removeClient_l() pid %d, tid %d, calling tid %d", pid, gettid(),
+ IPCThreadState::self()->getCallingPid());
mClients.removeItem(pid);
}
@@ -1215,7 +1230,8 @@ void AudioFlinger::ThreadBase::sendIoConfigEvent_l(int event, int param)
{
IoConfigEvent *ioEvent = new IoConfigEvent(event, param);
mConfigEvents.add(static_cast<ConfigEvent *>(ioEvent));
- ALOGV("sendIoConfigEvent() num events %d event %d, param %d", mConfigEvents.size(), event, param);
+ ALOGV("sendIoConfigEvent() num events %d event %d, param %d", mConfigEvents.size(), event,
+ param);
mWaitWorkCV.signal();
}
@@ -1244,7 +1260,8 @@ void AudioFlinger::ThreadBase::processConfigEvents()
PrioConfigEvent *prioEvent = static_cast<PrioConfigEvent *>(event);
int err = requestPriority(prioEvent->pid(), prioEvent->tid(), prioEvent->prio());
if (err != 0) {
- ALOGW("Policy SCHED_FIFO priority %d is unavailable for pid %d tid %d; error %d",
+ ALOGW("Policy SCHED_FIFO priority %d is unavailable for pid %d tid %d; "
+ "error %d",
prioEvent->prio(), prioEvent->pid(), prioEvent->tid(), err);
}
} break;
@@ -1282,7 +1299,7 @@ void AudioFlinger::ThreadBase::dumpBase(int fd, const Vector<String16>& args)
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);
@@ -1661,7 +1678,8 @@ void AudioFlinger::PlaybackThread::dumpInternals(int fd, const Vector<String16>&
snprintf(buffer, SIZE, "\nOutput thread %p internals\n", this);
result.append(buffer);
- snprintf(buffer, SIZE, "last write occurred (msecs): %llu\n", ns2ms(systemTime() - mLastWriteTime));
+ snprintf(buffer, SIZE, "last write occurred (msecs): %llu\n",
+ ns2ms(systemTime() - mLastWriteTime));
result.append(buffer);
snprintf(buffer, SIZE, "total writes: %d\n", mNumWrites);
result.append(buffer);
@@ -1712,20 +1730,20 @@ sp<AudioFlinger::PlaybackThread::Track> AudioFlinger::PlaybackThread::createTrac
uint32_t sampleRate,
audio_format_t format,
audio_channel_mask_t channelMask,
- int frameCount,
+ size_t 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) &&
@@ -1766,12 +1784,12 @@ sp<AudioFlinger::PlaybackThread::Track> AudioFlinger::PlaybackThread::createTrac
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.
@@ -1781,7 +1799,7 @@ sp<AudioFlinger::PlaybackThread::Track> AudioFlinger::PlaybackThread::createTrac
if (minBufCount < 2) {
minBufCount = 2;
}
- int minFrameCount = mNormalFrameCount * minBufCount;
+ size_t minFrameCount = mNormalFrameCount * minBufCount;
if (frameCount < minFrameCount) {
frameCount = minFrameCount;
}
@@ -1791,7 +1809,7 @@ sp<AudioFlinger::PlaybackThread::Track> AudioFlinger::PlaybackThread::createTrac
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;
@@ -1801,7 +1819,7 @@ sp<AudioFlinger::PlaybackThread::Track> AudioFlinger::PlaybackThread::createTrac
} 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;
}
@@ -1835,7 +1853,7 @@ sp<AudioFlinger::PlaybackThread::Track> AudioFlinger::PlaybackThread::createTrac
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);
@@ -1854,7 +1872,7 @@ sp<AudioFlinger::PlaybackThread::Track> AudioFlinger::PlaybackThread::createTrac
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
@@ -1959,7 +1977,8 @@ status_t AudioFlinger::PlaybackThread::addTrack_l(const sp<Track>& track)
if (track->mainBuffer() != mMixBuffer) {
sp<EffectChain> chain = getEffectChain_l(track->sessionId());
if (chain != 0) {
- ALOGV("addTrack_l() starting track on chain %p for session %d", chain.get(), track->sessionId());
+ ALOGV("addTrack_l() starting track on chain %p for session %d", chain.get(),
+ track->sessionId());
chain->incActiveTrackCnt();
}
}
@@ -2025,7 +2044,8 @@ void AudioFlinger::PlaybackThread::audioConfigChanged_l(int event, int param) {
AudioSystem::OutputDescriptor desc;
void *param2 = NULL;
- ALOGV("PlaybackThread::audioConfigChanged_l, thread %p, event %d, param %d", this, event, param);
+ ALOGV("PlaybackThread::audioConfigChanged_l, thread %p, event %d, param %d", this, event,
+ param);
switch (event) {
case AudioSystem::OUTPUT_OPENED:
@@ -2033,7 +2053,8 @@ void AudioFlinger::PlaybackThread::audioConfigChanged_l(int event, int param) {
desc.channels = mChannelMask;
desc.samplingRate = mSampleRate;
desc.format = mFormat;
- desc.frameCount = mNormalFrameCount; // FIXME see AudioFlinger::frameCount(audio_io_handle_t)
+ desc.frameCount = mNormalFrameCount; // FIXME see
+ // AudioFlinger::frameCount(audio_io_handle_t)
desc.latency = latency();
param2 = &desc;
break;
@@ -2062,7 +2083,8 @@ void AudioFlinger::PlaybackThread::readOutputParameters()
// Calculate size of normal mix buffer relative to the HAL output buffer size
double multiplier = 1.0;
- if (mType == MIXER && (kUseFastMixer == FastMixer_Static || kUseFastMixer == FastMixer_Dynamic)) {
+ if (mType == MIXER && (kUseFastMixer == FastMixer_Static ||
+ kUseFastMixer == FastMixer_Dynamic)) {
size_t minNormalFrameCount = (kMinNormalMixBufferSizeMs * mSampleRate) / 1000;
size_t maxNormalFrameCount = (kMaxNormalMixBufferSizeMs * mSampleRate) / 1000;
// round up minimum and round down maximum to nearest 16 frames to satisfy AudioMixer
@@ -2081,9 +2103,10 @@ void AudioFlinger::PlaybackThread::readOutputParameters()
multiplier = (double) maxNormalFrameCount / (double) mFrameCount;
}
} else {
- // prefer an even multiplier, for compatibility with doubling of fast tracks due to HAL SRC
- // (it would be unusual for the normal mix buffer size to not be a multiple of fast
- // track, but we sometimes have to do this to satisfy the maximum frame count constraint)
+ // prefer an even multiplier, for compatibility with doubling of fast tracks due to HAL
+ // SRC (it would be unusual for the normal mix buffer size to not be a multiple of fast
+ // track, but we sometimes have to do this to satisfy the maximum frame count
+ // constraint)
// FIXME this rounding up should not be done if no HAL SRC
uint32_t truncMult = (uint32_t) multiplier;
if ((truncMult & 1)) {
@@ -2097,7 +2120,8 @@ void AudioFlinger::PlaybackThread::readOutputParameters()
mNormalFrameCount = multiplier * mFrameCount;
// round up to nearest 16 frames to satisfy AudioMixer
mNormalFrameCount = (mNormalFrameCount + 15) & ~15;
- ALOGI("HAL output buffer size %u frames, normal mix buffer size %u frames", mFrameCount, mNormalFrameCount);
+ ALOGI("HAL output buffer size %u frames, normal mix buffer size %u frames", mFrameCount,
+ mNormalFrameCount);
delete[] mMixBuffer;
mMixBuffer = new int16_t[mNormalFrameCount * mChannelCount];
@@ -2151,7 +2175,7 @@ uint32_t AudioFlinger::PlaybackThread::hasAudioSession(int sessionId) const
for (size_t i = 0; i < mTracks.size(); ++i) {
sp<Track> track = mTracks[i];
if (sessionId == track->sessionId() &&
- !(track->mCblk->flags & CBLK_INVALID_MSK)) {
+ !(track->mCblk->flags & CBLK_INVALID)) {
result |= TRACK_SESSION;
break;
}
@@ -2170,7 +2194,7 @@ uint32_t AudioFlinger::PlaybackThread::getStrategyForSession_l(int sessionId)
for (size_t i = 0; i < mTracks.size(); i++) {
sp<Track> track = mTracks[i];
if (sessionId == track->sessionId() &&
- !(track->mCblk->flags & CBLK_INVALID_MSK)) {
+ !(track->mCblk->flags & CBLK_INVALID)) {
return AudioSystem::getStrategyForStream(track->streamType());
}
}
@@ -2235,7 +2259,8 @@ bool AudioFlinger::PlaybackThread::isValidSyncEvent(const sp<SyncEvent>& event)
return event->type() == AudioSystem::SYNC_EVENT_PRESENTATION_COMPLETE;
}
-void AudioFlinger::PlaybackThread::threadLoop_removeTracks(const Vector< sp<Track> >& tracksToRemove)
+void AudioFlinger::PlaybackThread::threadLoop_removeTracks(
+ const Vector< sp<Track> >& tracksToRemove)
{
size_t count = tracksToRemove.size();
if (CC_UNLIKELY(count)) {
@@ -2263,7 +2288,7 @@ AudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, Aud
// 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);
@@ -2891,7 +2916,8 @@ void AudioFlinger::MixerThread::threadLoop_sleepTime()
} else if (mBytesWritten != 0 || (mMixerStatus == MIXER_TRACKS_ENABLED)) {
memset (mMixBuffer, 0, mixBufferSize);
sleepTime = 0;
- ALOGV_IF((mBytesWritten == 0 && (mMixerStatus == MIXER_TRACKS_ENABLED)), "anticipated start");
+ ALOGV_IF((mBytesWritten == 0 && (mMixerStatus == MIXER_TRACKS_ENABLED)),
+ "anticipated start");
}
// TODO add standby time extension fct of effect tail
}
@@ -3014,7 +3040,7 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTrac
}
// indicate to client process that the track was disabled because of underrun;
// it will then automatically call start() when data is available
- android_atomic_or(CBLK_DISABLED_ON, &track->mCblk->flags);
+ android_atomic_or(CBLK_DISABLED, &track->mCblk->flags);
// remove from active list, but state remains ACTIVE [confusing but true]
isActive = false;
break;
@@ -3108,7 +3134,7 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTrac
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
@@ -3125,7 +3151,8 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTrac
if ((track->framesReady() >= minFrames) && track->isReady() &&
!track->isPaused() && !track->isTerminated())
{
- //ALOGV("track %d u=%08x, s=%08x [OK] on thread %p", name, cblk->user, cblk->server, this);
+ ALOGVV("track %d u=%08x, s=%08x [OK] on thread %p", name, cblk->user, cblk->server,
+ this);
mixedTracks++;
@@ -3138,7 +3165,8 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTrac
if (chain != 0) {
tracksWithEffect++;
} else {
- ALOGW("prepareTracks_l(): track %d attached to effect but no chain found on session %d",
+ ALOGW("prepareTracks_l(): track %d attached to effect but no chain found on "
+ "session %d",
name, track->sessionId());
}
}
@@ -3268,7 +3296,8 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTrac
chain->clearInputBuffer();
}
- //ALOGV("track %d u=%08x, s=%08x [NOT READY] on thread %p", name, cblk->user, cblk->server, this);
+ ALOGVV("track %d u=%08x, s=%08x [NOT READY] on thread %p", name, cblk->user,
+ cblk->server, this);
if ((track->sharedBuffer() != 0) || track->isTerminated() ||
track->isStopped() || track->isPaused()) {
// We have consumed all the buffers of this track.
@@ -3293,7 +3322,7 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTrac
tracksToRemove->add(track);
// indicate to client process that the track was disabled because of underrun;
// it will then automatically call start() when data is available
- android_atomic_or(CBLK_DISABLED_ON, &cblk->flags);
+ android_atomic_or(CBLK_DISABLED, &cblk->flags);
// If one track is not ready, mark the mixer also not ready if:
// - the mixer was ready during previous round OR
// - no other track is ready
@@ -3362,7 +3391,8 @@ track_is_ready: ;
if (track->mainBuffer() != mMixBuffer) {
chain = getEffectChain_l(track->sessionId());
if (chain != 0) {
- ALOGV("stopping track on chain %p for session Id: %d", chain.get(), track->sessionId());
+ ALOGV("stopping track on chain %p for session Id: %d", chain.get(),
+ track->sessionId());
chain->decActiveTrackCnt();
}
}
@@ -3375,7 +3405,8 @@ track_is_ready: ;
// mix buffer must be cleared if all tracks are connected to an
// effect chain as in this case the mixer will not write to
// mix buffer and track effects will accumulate into it
- if ((mixedTracks != 0 && mixedTracks == tracksWithEffect) || (mixedTracks == 0 && fastTracks > 0)) {
+ if ((mixedTracks != 0 && mixedTracks == tracksWithEffect) ||
+ (mixedTracks == 0 && fastTracks > 0)) {
// FIXME as a performance optimization, should remember previous zero status
memset(mMixBuffer, 0, mNormalFrameCount * mChannelCount * sizeof(int16_t));
}
@@ -3424,7 +3455,7 @@ void AudioFlinger::PlaybackThread::invalidateTracks(audio_stream_type_t streamTy
for (size_t i = 0; i < size; i++) {
sp<Track> t = mTracks[i];
if (t->streamType() == streamType) {
- android_atomic_or(CBLK_INVALID_ON, &t->mCblk->flags);
+ android_atomic_or(CBLK_INVALID, &t->mCblk->flags);
t->mCblk->cv.signal();
}
}
@@ -3580,39 +3611,18 @@ bool AudioFlinger::MixerThread::checkForNewParameters_l()
return reconfig;
}
-void AudioFlinger::MixerThread::dumpInternals(int fd, const Vector<String16>& args)
+void AudioFlinger::dumpTee(int fd, const sp<NBAIO_Source>& source, audio_io_handle_t id)
{
- const size_t SIZE = 256;
- char buffer[SIZE];
- String8 result;
-
- PlaybackThread::dumpInternals(fd, args);
-
- snprintf(buffer, SIZE, "AudioMixer tracks: %08x\n", mAudioMixer->trackNames());
- result.append(buffer);
- write(fd, result.string(), result.size());
-
- // Make a non-atomic copy of fast mixer dump state so it won't change underneath us
- FastMixerDumpState copy = mFastMixerDumpState;
- copy.dump(fd);
-
-#ifdef STATE_QUEUE_DUMP
- // Similar for state queue
- StateQueueObserverDump observerCopy = mStateQueueObserverDump;
- observerCopy.dump(fd);
- StateQueueMutatorDump mutatorCopy = mStateQueueMutatorDump;
- mutatorCopy.dump(fd);
-#endif
-
- // Write the tee output to a .wav file
- NBAIO_Source *teeSource = mTeeSource.get();
+ NBAIO_Source *teeSource = source.get();
if (teeSource != NULL) {
- char teePath[64];
+ char teeTime[16];
struct timeval tv;
gettimeofday(&tv, NULL);
struct tm tm;
localtime_r(&tv.tv_sec, &tm);
- strftime(teePath, sizeof(teePath), "/data/misc/media/%T.wav", &tm);
+ strftime(teeTime, sizeof(teeTime), "%T", &tm);
+ char teePath[64];
+ sprintf(teePath, "/data/misc/media/%s_%d.wav", teeTime, id);
int teeFd = open(teePath, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
if (teeFd >= 0) {
char wavHeader[44];
@@ -3622,7 +3632,7 @@ void AudioFlinger::MixerThread::dumpInternals(int fd, const Vector<String16>& ar
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;
@@ -3660,6 +3670,34 @@ void AudioFlinger::MixerThread::dumpInternals(int fd, const Vector<String16>& ar
fdprintf(fd, "FastMixer unable to create tee %s: \n", strerror(errno));
}
}
+}
+
+void AudioFlinger::MixerThread::dumpInternals(int fd, const Vector<String16>& args)
+{
+ const size_t SIZE = 256;
+ char buffer[SIZE];
+ String8 result;
+
+ PlaybackThread::dumpInternals(fd, args);
+
+ snprintf(buffer, SIZE, "AudioMixer tracks: %08x\n", mAudioMixer->trackNames());
+ result.append(buffer);
+ write(fd, result.string(), result.size());
+
+ // Make a non-atomic copy of fast mixer dump state so it won't change underneath us
+ FastMixerDumpState copy = mFastMixerDumpState;
+ copy.dump(fd);
+
+#ifdef STATE_QUEUE_DUMP
+ // Similar for state queue
+ StateQueueObserverDump observerCopy = mStateQueueObserverDump;
+ observerCopy.dump(fd);
+ StateQueueMutatorDump mutatorCopy = mStateQueueMutatorDump;
+ mutatorCopy.dump(fd);
+#endif
+
+ // Write the tee output to a .wav file
+ dumpTee(fd, mTeeSource, mId);
#ifdef AUDIO_WATCHDOG
if (mAudioWatchdog != 0) {
@@ -3731,7 +3769,7 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep
if ((track->framesReady() >= minFrames) && track->isReady() &&
!track->isPaused() && !track->isTerminated())
{
- //ALOGV("track %d u=%08x, s=%08x [OK]", track->name(), cblk->user, cblk->server);
+ ALOGVV("track %d u=%08x, s=%08x [OK]", track->name(), cblk->user, cblk->server);
if (track->mFillingUpStatus == Track::FS_FILLED) {
track->mFillingUpStatus = Track::FS_ACTIVE;
@@ -3792,7 +3830,7 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep
mEffectChains[0]->clearInputBuffer();
}
- //ALOGV("track %d u=%08x, s=%08x [NOT READY]", track->name(), cblk->user, cblk->server);
+ ALOGVV("track %d u=%08x, s=%08x [NOT READY]", track->name(), cblk->user, cblk->server);
if ((track->sharedBuffer() != 0) || track->isTerminated() ||
track->isStopped() || track->isPaused()) {
// We have consumed all the buffers of this track.
@@ -3982,7 +4020,8 @@ void AudioFlinger::DirectOutputThread::cacheParameters_l()
AudioFlinger::DuplicatingThread::DuplicatingThread(const sp<AudioFlinger>& audioFlinger,
AudioFlinger::MixerThread* mainThread, audio_io_handle_t id)
- : MixerThread(audioFlinger, mainThread->getOutput(), id, mainThread->outDevice(), DUPLICATING),
+ : MixerThread(audioFlinger, mainThread->getOutput(), id, mainThread->outDevice(),
+ DUPLICATING),
mWaitTimeMs(UINT_MAX)
{
addOutputTrack(mainThread);
@@ -4058,7 +4097,7 @@ void AudioFlinger::DuplicatingThread::addOutputTrack(MixerThread *thread)
{
Mutex::Autolock _l(mLock);
// FIXME explain this formula
- int frameCount = (3 * mNormalFrameCount * mSampleRate) / thread->sampleRate();
+ size_t frameCount = (3 * mNormalFrameCount * mSampleRate) / thread->sampleRate();
OutputTrack *outputTrack = new OutputTrack(thread,
this,
mSampleRate,
@@ -4103,18 +4142,21 @@ void AudioFlinger::DuplicatingThread::updateWaitTime_l()
}
-bool AudioFlinger::DuplicatingThread::outputsReady(const SortedVector< sp<OutputTrack> > &outputTracks)
+bool AudioFlinger::DuplicatingThread::outputsReady(
+ const SortedVector< sp<OutputTrack> > &outputTracks)
{
for (size_t i = 0; i < outputTracks.size(); i++) {
sp<ThreadBase> thread = outputTracks[i]->thread().promote();
if (thread == 0) {
- ALOGW("DuplicatingThread::outputsReady() could not promote thread on output track %p", outputTracks[i].get());
+ ALOGW("DuplicatingThread::outputsReady() could not promote thread on output track %p",
+ outputTracks[i].get());
return false;
}
PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
// see note at standby() declaration
if (playbackThread->standby() && !playbackThread->isSuspended()) {
- ALOGV("DuplicatingThread output track %p on thread %p Not Ready", outputTracks[i].get(), thread.get());
+ ALOGV("DuplicatingThread output track %p on thread %p Not Ready", outputTracks[i].get(),
+ thread.get());
return false;
}
}
@@ -4143,7 +4185,7 @@ AudioFlinger::ThreadBase::TrackBase::TrackBase(
uint32_t sampleRate,
audio_format_t format,
audio_channel_mask_t channelMask,
- int frameCount,
+ size_t frameCount,
const sp<IMemory>& sharedBuffer,
int sessionId)
: RefBase(),
@@ -4152,52 +4194,35 @@ AudioFlinger::ThreadBase::TrackBase::TrackBase(
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
{
- ALOGV_IF(sharedBuffer != 0, "sharedBuffer: %p, size: %d", sharedBuffer->pointer(), sharedBuffer->size());
+ // client == 0 implies sharedBuffer == 0
+ ALOG_ASSERT(!(client == 0 && sharedBuffer != 0));
+
+ ALOGV_IF(sharedBuffer != 0, "sharedBuffer: %p, size: %d", sharedBuffer->pointer(),
+ sharedBuffer->size());
// 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;
}
- if (client != NULL) {
+ if (client != 0) {
mCblkMemory = client->heap()->allocate(size);
if (mCblkMemory != 0) {
mCblk = static_cast<audio_track_cblk_t *>(mCblkMemory->pointer());
- if (mCblk != NULL) { // construct the shared structure in-place.
- new(mCblk) audio_track_cblk_t();
- // clear all buffers
- mCblk->frameCount = frameCount;
- mCblk->sampleRate = sampleRate;
-// uncomment the following lines to quickly test 32-bit wraparound
-// mCblk->user = 0xffff0000;
-// 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));
- // Force underrun condition to avoid false underrun callback until first data is
- // written to buffer (other flags are cleared)
- mCblk->flags = CBLK_UNDERRUN_ON;
- } else {
- mBuffer = sharedBuffer->pointer();
- }
- mBufferEnd = (uint8_t *)mBuffer + bufferSize;
- }
+ // can't assume mCblk != NULL
} else {
ALOGE("not enough memory for AudioTrack size=%u", size);
client->heap()->dump("AudioTrack");
@@ -4205,23 +4230,29 @@ AudioFlinger::ThreadBase::TrackBase::TrackBase(
}
} else {
mCblk = (audio_track_cblk_t *)(new uint8_t[size]);
- // construct the shared structure in-place.
+ // assume mCblk != NULL
+ }
+
+ // construct the shared structure in-place.
+ if (mCblk != NULL) {
new(mCblk) audio_track_cblk_t();
// clear all buffers
mCblk->frameCount = frameCount;
mCblk->sampleRate = sampleRate;
// uncomment the following lines to quickly test 32-bit wraparound
-// mCblk->user = 0xffff0000;
-// mCblk->server = 0xffff0000;
-// mCblk->userBase = 0xffff0000;
-// mCblk->serverBase = 0xffff0000;
- mChannelCount = channelCount;
- mChannelMask = channelMask;
- mBuffer = (char*)mCblk + sizeof(audio_track_cblk_t);
- memset(mBuffer, 0, frameCount*channelCount*sizeof(int16_t));
- // Force underrun condition to avoid false underrun callback until first data is
- // written to buffer (other flags are cleared)
- mCblk->flags = CBLK_UNDERRUN_ON;
+// mCblk->user = 0xffff0000;
+// mCblk->server = 0xffff0000;
+// mCblk->userBase = 0xffff0000;
+// mCblk->serverBase = 0xffff0000;
+ if (sharedBuffer == 0) {
+ mBuffer = (char*)mCblk + sizeof(audio_track_cblk_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;
+ } else {
+ mBuffer = sharedBuffer->pointer();
+ }
mBufferEnd = (uint8_t *)mBuffer + bufferSize;
}
}
@@ -4252,7 +4283,7 @@ AudioFlinger::ThreadBase::TrackBase::~TrackBase()
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;
@@ -4262,7 +4293,7 @@ bool AudioFlinger::ThreadBase::TrackBase::step() {
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;
@@ -4281,23 +4312,22 @@ void AudioFlinger::ThreadBase::TrackBase::reset() {
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;
}
@@ -4318,11 +4348,12 @@ AudioFlinger::PlaybackThread::Track::Track(
uint32_t sampleRate,
audio_format_t format,
audio_channel_mask_t channelMask,
- int frameCount,
+ size_t frameCount,
const sp<IMemory>& sharedBuffer,
int sessionId,
IAudioFlinger::track_flags_t flags)
- : TrackBase(thread, client, sampleRate, format, channelMask, frameCount, sharedBuffer, sessionId),
+ : TrackBase(thread, client, sampleRate, format, channelMask, frameCount, sharedBuffer,
+ sessionId),
mMute(false),
mFillingUpStatus(FS_INVALID),
// mRetryCount initialized later when needed
@@ -4339,9 +4370,6 @@ AudioFlinger::PlaybackThread::Track::Track(
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;
@@ -4351,7 +4379,6 @@ AudioFlinger::PlaybackThread::Track::Track(
}
// 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);
@@ -4366,7 +4393,8 @@ AudioFlinger::PlaybackThread::Track::Track(
thread->mFastTrackAvailMask &= ~(1 << i);
}
}
- ALOGV("Track constructor name %d, calling pid %d", mName, IPCThreadState::self()->getCallingPid());
+ ALOGV("Track constructor name %d, calling pid %d", mName,
+ IPCThreadState::self()->getCallingPid());
}
AudioFlinger::PlaybackThread::Track::~Track()
@@ -4408,8 +4436,8 @@ void AudioFlinger::PlaybackThread::Track::destroy()
/*static*/ void AudioFlinger::PlaybackThread::Track::appendDumpHeader(String8& result)
{
- result.append(" Name Client Type Fmt Chn mask Session mFrCnt fCount S M F SRate L dB R dB "
- " Server User Main buf Aux Buf Flags Underruns\n");
+ 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");
}
void AudioFlinger::PlaybackThread::Track::dump(char* buffer, size_t size)
@@ -4479,7 +4507,7 @@ void AudioFlinger::PlaybackThread::Track::dump(char* buffer, size_t size)
mFormat,
mChannelMask,
mSessionId,
- mFrameCount,
+ mStepCount,
mCblk->frameCount,
stateChar,
mMute,
@@ -4519,7 +4547,7 @@ status_t AudioFlinger::PlaybackThread::Track::getNextBuffer(
}
// FIXME Same as above
- framesReady = cblk->framesReady();
+ framesReady = cblk->framesReadyOut();
if (CC_LIKELY(framesReady)) {
uint32_t s = cblk->server;
@@ -4554,7 +4582,7 @@ getNextBuffer_exit:
// 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
@@ -4562,9 +4590,9 @@ bool AudioFlinger::PlaybackThread::Track::isReady() const {
if (mFillingUpStatus != FS_FILLING || isStopped() || isPausing()) return true;
if (framesReady() >= mCblk->frameCount ||
- (mCblk->flags & CBLK_FORCEREADY_MSK)) {
+ (mCblk->flags & CBLK_FORCEREADY)) {
mFillingUpStatus = FS_FILLED;
- android_atomic_and(~CBLK_FORCEREADY_MSK, &mCblk->flags);
+ android_atomic_and(~CBLK_FORCEREADY, &mCblk->flags);
return true;
}
return false;
@@ -4636,7 +4664,8 @@ void AudioFlinger::PlaybackThread::Track::stop()
// and then to STOPPED and reset() when presentation is complete
mState = STOPPING_1;
}
- ALOGV("not stopping/stopped => stopping/stopped (%d) on thread %p", mName, playbackThread);
+ ALOGV("not stopping/stopped => stopping/stopped (%d) on thread %p", mName,
+ playbackThread);
}
if (!isOutputTrack() && (state == ACTIVE || state == RESUMING)) {
thread->mLock.unlock();
@@ -4681,7 +4710,7 @@ void AudioFlinger::PlaybackThread::Track::flush()
if (thread != 0) {
Mutex::Autolock _l(thread->mLock);
if (mState != STOPPING_1 && mState != STOPPING_2 && mState != STOPPED && mState != PAUSED &&
- mState != PAUSING) {
+ mState != PAUSING && mState != IDLE && mState != FLUSHED) {
return;
}
// No point remaining in PAUSED state after a flush => go to
@@ -4706,8 +4735,8 @@ void AudioFlinger::PlaybackThread::Track::reset()
TrackBase::reset();
// Force underrun condition to avoid false underrun callback until first data is
// written to buffer
- android_atomic_and(~CBLK_FORCEREADY_MSK, &mCblk->flags);
- android_atomic_or(CBLK_UNDERRUN_ON, &mCblk->flags);
+ android_atomic_and(~CBLK_FORCEREADY, &mCblk->flags);
+ android_atomic_or(CBLK_UNDERRUN, &mCblk->flags);
mFillingUpStatus = FS_FILLING;
mResetDone = true;
if (mState == FLUSHED) {
@@ -4848,6 +4877,11 @@ status_t AudioFlinger::PlaybackThread::Track::setSyncEvent(const sp<SyncEvent>&
return NO_ERROR;
}
+bool AudioFlinger::PlaybackThread::Track::isOut() const
+{
+ return true;
+}
+
// timed audio tracks
sp<AudioFlinger::PlaybackThread::TimedTrack>
@@ -4858,7 +4892,7 @@ AudioFlinger::PlaybackThread::TimedTrack::create(
uint32_t sampleRate,
audio_format_t format,
audio_channel_mask_t channelMask,
- int frameCount,
+ size_t frameCount,
const sp<IMemory>& sharedBuffer,
int sessionId) {
if (!client->reserveTimedTrack())
@@ -4876,7 +4910,7 @@ AudioFlinger::PlaybackThread::TimedTrack::TimedTrack(
uint32_t sampleRate,
audio_format_t format,
audio_channel_mask_t channelMask,
- int frameCount,
+ size_t frameCount,
const sp<IMemory>& sharedBuffer,
int sessionId)
: Track(thread, client, streamType, sampleRate, format, channelMask,
@@ -4982,7 +5016,7 @@ void AudioFlinger::PlaybackThread::TimedTrack::trimTimedBufferQueue_l() {
// 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)) {
@@ -5042,7 +5076,7 @@ void AudioFlinger::PlaybackThread::TimedTrack::updateFramesPendingAfterTrim_l(
" 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"
@@ -5063,7 +5097,7 @@ status_t AudioFlinger::PlaybackThread::TimedTrack::queueTimedBuffer(
Mutex::Autolock _l(mTimedBufferQueueLock);
- uint32_t bufFrames = buffer->size() / mCblk->frameSize;
+ uint32_t bufFrames = buffer->size() / mFrameSize;
mFramesPendingInQueue += bufFrames;
mTimedBufferQueue.add(TimedBuffer(buffer, pts));
@@ -5160,7 +5194,7 @@ status_t AudioFlinger::PlaybackThread::TimedTrack::getNextBuffer(
// 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.
@@ -5225,7 +5259,7 @@ status_t AudioFlinger::PlaybackThread::TimedTrack::getNextBuffer(
// 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
@@ -5260,7 +5294,7 @@ void AudioFlinger::PlaybackThread::TimedTrack::timedYieldSamples_l(
head.position());
uint32_t framesLeftInHead = ((head.buffer()->size() - head.position()) /
- mCblk->frameSize);
+ mFrameSize);
size_t framesRequested = buffer->frameCount;
buffer->frameCount = min(framesLeftInHead, framesRequested);
@@ -5275,9 +5309,9 @@ void AudioFlinger::PlaybackThread::TimedTrack::timedYieldSilence_l(
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);
}
@@ -5325,7 +5359,7 @@ void AudioFlinger::PlaybackThread::TimedTrack::releaseBuffer(
start, end, buffer->raw);
head.setPosition(head.position() +
- (buffer->frameCount * mCblk->frameSize));
+ (buffer->frameCount * mFrameSize));
mQueueHeadInFlight = false;
ALOG_ASSERT(mFramesPendingInQueue >= buffer->frameCount,
@@ -5371,22 +5405,13 @@ AudioFlinger::RecordThread::RecordTrack::RecordTrack(
uint32_t sampleRate,
audio_format_t format,
audio_channel_mask_t channelMask,
- int frameCount,
+ size_t frameCount,
int sessionId)
: TrackBase(thread, client, sampleRate, format,
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()
@@ -5395,7 +5420,8 @@ AudioFlinger::RecordThread::RecordTrack::~RecordTrack()
}
// AudioBufferProvider interface
-status_t AudioFlinger::RecordThread::RecordTrack::getNextBuffer(AudioBufferProvider::Buffer* buffer, int64_t pts)
+status_t AudioFlinger::RecordThread::RecordTrack::getNextBuffer(AudioBufferProvider::Buffer* buffer,
+ int64_t pts)
{
audio_track_cblk_t* cblk = this->cblk();
uint32_t framesAvail;
@@ -5408,7 +5434,8 @@ status_t AudioFlinger::RecordThread::RecordTrack::getNextBuffer(AudioBufferProvi
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;
@@ -5455,7 +5482,7 @@ void AudioFlinger::RecordThread::RecordTrack::stop()
TrackBase::reset();
// Force overrun condition to avoid false overrun callback until first data is
// read from buffer
- android_atomic_or(CBLK_UNDERRUN_ON, &mCblk->flags);
+ android_atomic_or(CBLK_UNDERRUN, &mCblk->flags);
}
recordThread->mLock.unlock();
if (doStop) {
@@ -5466,7 +5493,7 @@ void AudioFlinger::RecordThread::RecordTrack::stop()
/*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)
@@ -5476,7 +5503,7 @@ void AudioFlinger::RecordThread::RecordTrack::dump(char* buffer, size_t size)
mFormat,
mChannelMask,
mSessionId,
- mFrameCount,
+ mStepCount,
mState,
mCblk->sampleRate,
mCblk->server,
@@ -5484,6 +5511,10 @@ void AudioFlinger::RecordThread::RecordTrack::dump(char* buffer, size_t size)
mCblk->frameCount);
}
+bool AudioFlinger::RecordThread::RecordTrack::isOut() const
+{
+ return false;
+}
// ----------------------------------------------------------------------------
@@ -5493,19 +5524,18 @@ AudioFlinger::PlaybackThread::OutputTrack::OutputTrack(
uint32_t sampleRate,
audio_format_t format,
audio_channel_mask_t channelMask,
- int frameCount)
+ size_t 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_OUT;
- 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 {
@@ -5587,7 +5617,8 @@ bool AudioFlinger::PlaybackThread::OutputTrack::write(int16_t* data, uint32_t fr
mOutBuffer.frameCount = pInBuffer->frameCount;
nsecs_t startTime = systemTime();
if (obtainBuffer(&mOutBuffer, waitTimeLeftMs) == (status_t)NO_MORE_BUFFERS) {
- ALOGV ("OutputTrack::write() %p thread %p no more output buffers", this, mThread.unsafe_get());
+ ALOGV ("OutputTrack::write() %p thread %p no more output buffers", this,
+ mThread.unsafe_get());
outputBufferFull = true;
break;
}
@@ -5599,9 +5630,10 @@ bool AudioFlinger::PlaybackThread::OutputTrack::write(int16_t* data, uint32_t fr
}
}
- uint32_t outFrames = pInBuffer->frameCount > mOutBuffer.frameCount ? mOutBuffer.frameCount : pInBuffer->frameCount;
+ 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;
@@ -5612,7 +5644,8 @@ bool AudioFlinger::PlaybackThread::OutputTrack::write(int16_t* data, uint32_t fr
mBufferQueue.removeAt(0);
delete [] pInBuffer->mBuffer;
delete pInBuffer;
- ALOGV("OutputTrack::write() %p thread %p released overflow buffer %d", this, mThread.unsafe_get(), mBufferQueue.size());
+ ALOGV("OutputTrack::write() %p thread %p released overflow buffer %d", this,
+ mThread.unsafe_get(), mBufferQueue.size());
} else {
break;
}
@@ -5628,11 +5661,14 @@ bool AudioFlinger::PlaybackThread::OutputTrack::write(int16_t* data, uint32_t fr
pInBuffer->mBuffer = new int16_t[inBuffer.frameCount * channelCount];
pInBuffer->frameCount = inBuffer.frameCount;
pInBuffer->i16 = pInBuffer->mBuffer;
- memcpy(pInBuffer->raw, inBuffer.raw, inBuffer.frameCount * channelCount * sizeof(int16_t));
+ memcpy(pInBuffer->raw, inBuffer.raw, inBuffer.frameCount * channelCount *
+ sizeof(int16_t));
mBufferQueue.add(pInBuffer);
- ALOGV("OutputTrack::write() %p thread %p adding overflow buffer %d", this, mThread.unsafe_get(), mBufferQueue.size());
+ ALOGV("OutputTrack::write() %p thread %p adding overflow buffer %d", this,
+ mThread.unsafe_get(), mBufferQueue.size());
} else {
- ALOGW("OutputTrack::write() %p thread %p no more overflow buffers", mThread.unsafe_get(), this);
+ ALOGW("OutputTrack::write() %p thread %p no more overflow buffers",
+ mThread.unsafe_get(), this);
}
}
}
@@ -5657,17 +5693,18 @@ bool AudioFlinger::PlaybackThread::OutputTrack::write(int16_t* data, uint32_t fr
return outputBufferFull;
}
-status_t AudioFlinger::PlaybackThread::OutputTrack::obtainBuffer(AudioBufferProvider::Buffer* buffer, uint32_t waitTimeMs)
+status_t AudioFlinger::PlaybackThread::OutputTrack::obtainBuffer(
+ AudioBufferProvider::Buffer* buffer, uint32_t waitTimeMs)
{
int active;
status_t result;
audio_track_cblk_t* cblk = mCblk;
uint32_t framesReq = buffer->frameCount;
-// ALOGV("OutputTrack::obtainBuffer user %d, server %d", cblk->user, cblk->server);
+ 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) {
@@ -5685,7 +5722,7 @@ status_t AudioFlinger::PlaybackThread::OutputTrack::obtainBuffer(AudioBufferProv
}
// read the server count again
start_loop_here:
- framesAvail = cblk->framesAvailable_l();
+ framesAvail = cblk->framesAvailableOut_l();
}
}
@@ -5705,7 +5742,7 @@ status_t AudioFlinger::PlaybackThread::OutputTrack::obtainBuffer(AudioBufferProv
}
buffer->frameCount = framesReq;
- buffer->raw = (void *)cblk->buffer(u);
+ buffer->raw = cblk->buffer(mBuffers, mFrameSize, u);
return NO_ERROR;
}
@@ -5881,7 +5918,7 @@ sp<IAudioRecord> AudioFlinger::openRecord(
uint32_t sampleRate,
audio_format_t format,
audio_channel_mask_t channelMask,
- int frameCount,
+ size_t frameCount,
IAudioFlinger::track_flags_t flags,
pid_t tid,
int *sessionId,
@@ -5921,13 +5958,14 @@ sp<IAudioRecord> AudioFlinger::openRecord(
*sessionId = lSessionId;
}
}
- // create new record track. The record track uses one track in mHardwareMixerThread by convention.
+ // create new record track.
+ // The record track uses one track in mHardwareMixerThread by convention.
recordTrack = thread->createRecordTrack_l(client, sampleRate, format, channelMask,
frameCount, lSessionId, flags, tid, &lStatus);
}
if (lStatus != NO_ERROR) {
- // remove local strong reference to Client before deleting the RecordTrack so that the Client
- // destructor is called by the TrackBase destructor with mLock held
+ // remove local strong reference to Client before deleting the RecordTrack so that the
+ // Client destructor is called by the TrackBase destructor with mLock held
client.clear();
recordTrack.clear();
goto Exit;
@@ -5946,7 +5984,8 @@ Exit:
// ----------------------------------------------------------------------------
-AudioFlinger::RecordHandle::RecordHandle(const sp<AudioFlinger::RecordThread::RecordTrack>& recordTrack)
+AudioFlinger::RecordHandle::RecordHandle(
+ const sp<AudioFlinger::RecordThread::RecordTrack>& recordTrack)
: BnAudioRecord(),
mRecordTrack(recordTrack)
{
@@ -5961,7 +6000,8 @@ sp<IMemory> AudioFlinger::RecordHandle::getCblk() const {
return mRecordTrack->getCblk();
}
-status_t AudioFlinger::RecordHandle::start(int /*AudioSystem::sync_event_t*/ event, int triggerSession) {
+status_t AudioFlinger::RecordHandle::start(int /*AudioSystem::sync_event_t*/ event,
+ int triggerSession) {
ALOGV("RecordHandle::start()");
return mRecordTrack->start((AudioSystem::sync_event_t)event, triggerSession);
}
@@ -5988,18 +6028,21 @@ AudioFlinger::RecordThread::RecordThread(const sp<AudioFlinger>& audioFlinger,
uint32_t sampleRate,
audio_channel_mask_t channelMask,
audio_io_handle_t id,
- audio_devices_t device) :
+ audio_devices_t device,
+ const sp<NBAIO_Sink>& teeSink) :
ThreadBase(audioFlinger, id, AUDIO_DEVICE_NONE, device, RECORD),
mInput(input), mResampler(NULL), mRsmpOutBuffer(NULL), mRsmpInBuffer(NULL),
// mRsmpInIndex and mInputBytes set by readInputParameters()
mReqChannelCount(popcount(channelMask)),
- mReqSampleRate(sampleRate)
+ mReqSampleRate(sampleRate),
// mBytesRead is only meaningful while active, and so is cleared in start()
// (but might be better to also clear here for dump?)
+ mTeeSink(teeSink)
{
snprintf(mName, kNameLength, "AudioIn_%X", id);
readInputParameters();
+
}
@@ -6106,7 +6149,8 @@ bool AudioFlinger::RecordThread::threadLoop()
size_t framesIn = mFrameCount - mRsmpInIndex;
if (framesIn) {
int8_t *src = (int8_t *)mRsmpInBuffer + mRsmpInIndex * mFrameSize;
- int8_t *dst = buffer.i8 + (buffer.frameCount - framesOut) * mActiveTrack->mCblk->frameSize;
+ int8_t *dst = buffer.i8 + (buffer.frameCount - framesOut) *
+ mActiveTrack->mFrameSize;
if (framesIn > framesOut)
framesIn = framesOut;
mRsmpInIndex += framesIn;
@@ -6125,14 +6169,17 @@ bool AudioFlinger::RecordThread::threadLoop()
}
}
if (framesOut && mFrameCount == mRsmpInIndex) {
+ void *readInto;
if (framesOut == mFrameCount &&
- ((int)mChannelCount == mReqChannelCount || mFormat != AUDIO_FORMAT_PCM_16_BIT)) {
- mBytesRead = mInput->stream->read(mInput->stream, buffer.raw, mInputBytes);
+ ((int)mChannelCount == mReqChannelCount ||
+ mFormat != AUDIO_FORMAT_PCM_16_BIT)) {
+ readInto = buffer.raw;
framesOut = 0;
} else {
- mBytesRead = mInput->stream->read(mInput->stream, mRsmpInBuffer, mInputBytes);
+ readInto = mRsmpInBuffer;
mRsmpInIndex = 0;
}
+ mBytesRead = mInput->stream->read(mInput->stream, readInto, mInputBytes);
if (mBytesRead <= 0) {
if ((mBytesRead < 0) && (mActiveTrack->mState == TrackBase::ACTIVE))
{
@@ -6145,6 +6192,9 @@ bool AudioFlinger::RecordThread::threadLoop()
mRsmpInIndex = mFrameCount;
framesOut = 0;
buffer.frameCount = 0;
+ } else if (mTeeSink != 0) {
+ (void) mTeeSink->write(readInto,
+ mBytesRead >> Format_frameBitShift(mTeeSink->format()));
}
}
}
@@ -6156,12 +6206,14 @@ bool AudioFlinger::RecordThread::threadLoop()
if (mChannelCount == 1 && mReqChannelCount == 1) {
framesOut >>= 1;
}
- mResampler->resample(mRsmpOutBuffer, framesOut, this /* AudioBufferProvider* */);
- // ditherAndClamp() works as long as all buffers returned by mActiveTrack->getNextBuffer()
- // are 32 bit aligned which should be always true.
+ mResampler->resample(mRsmpOutBuffer, framesOut,
+ this /* AudioBufferProvider* */);
+ // ditherAndClamp() works as long as all buffers returned by
+ // mActiveTrack->getNextBuffer() are 32 bit aligned which should be always true.
if (mChannelCount == 2 && mReqChannelCount == 1) {
ditherAndClamp(mRsmpOutBuffer, mRsmpOutBuffer, framesOut);
- // the resampler always outputs stereo samples: do post stereo to mono conversion
+ // the resampler always outputs stereo samples:
+ // do post stereo to mono conversion
downmix_to_mono_i16_from_stereo_i16(buffer.i16, (int16_t *)mRsmpOutBuffer,
framesOut);
} else {
@@ -6243,7 +6295,7 @@ sp<AudioFlinger::RecordThread::RecordTrack> AudioFlinger::RecordThread::createR
uint32_t sampleRate,
audio_format_t format,
audio_channel_mask_t channelMask,
- int frameCount,
+ size_t frameCount,
int sessionId,
IAudioFlinger::track_flags_t flags,
pid_t tid,
@@ -6500,7 +6552,7 @@ void AudioFlinger::RecordThread::dumpInternals(int fd, const Vector<String16>& a
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");
@@ -6595,7 +6647,7 @@ bool AudioFlinger::RecordThread::checkForNewParameters_l()
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) {
@@ -6635,7 +6687,8 @@ bool AudioFlinger::RecordThread::checkForNewParameters_l()
status = BAD_VALUE;
} else {
mInDevice = value;
- // disable AEC and NS if the device is a BT SCO headset supporting those pre processings
+ // disable AEC and NS if the device is a BT SCO headset supporting those
+ // pre processings
if (mTracks.size() > 0) {
bool suspend = audio_is_bluetooth_sco_device(mInDevice) &&
mAudioFlinger->btNrecIsOff();
@@ -6657,7 +6710,8 @@ bool AudioFlinger::RecordThread::checkForNewParameters_l()
mAudioSource = (audio_source_t)value;
}
if (status == NO_ERROR) {
- status = mInput->stream->common.set_parameters(&mInput->stream->common, keyValuePair.string());
+ status = mInput->stream->common.set_parameters(&mInput->stream->common,
+ keyValuePair.string());
if (status == INVALID_OPERATION) {
inputStandBy();
status = mInput->stream->common.set_parameters(&mInput->stream->common,
@@ -6667,8 +6721,10 @@ bool AudioFlinger::RecordThread::checkForNewParameters_l()
if (status == BAD_VALUE &&
reqFormat == mInput->stream->common.get_format(&mInput->stream->common) &&
reqFormat == AUDIO_FORMAT_PCM_16_BIT &&
- ((int)mInput->stream->common.get_sample_rate(&mInput->stream->common) <= (2 * reqSamplingRate)) &&
- popcount(mInput->stream->common.get_channels(&mInput->stream->common)) <= FCC_2 &&
+ ((int)mInput->stream->common.get_sample_rate(&mInput->stream->common)
+ <= (2 * reqSamplingRate)) &&
+ popcount(mInput->stream->common.get_channels(&mInput->stream->common))
+ <= FCC_2 &&
(reqChannelCount <= FCC_2)) {
status = NO_ERROR;
}
@@ -6762,7 +6818,8 @@ void AudioFlinger::RecordThread::readInputParameters()
mResampler->setVolume(AudioMixer::UNITY_GAIN, AudioMixer::UNITY_GAIN);
mRsmpOutBuffer = new int32_t[mFrameCount * 2];
- // optmization: if mono to mono, alter input frame count as if we were inputing stereo samples
+ // optmization: if mono to mono, alter input frame count as if we were inputing
+ // stereo samples
if (mChannelCount == 1 && mReqChannelCount == 1) {
mFrameCount >>= 1;
}
@@ -6924,14 +6981,14 @@ audio_module_handle_t AudioFlinger::loadHwModule_l(const char *name)
// ----------------------------------------------------------------------------
-int32_t AudioFlinger::getPrimaryOutputSamplingRate()
+uint32_t AudioFlinger::getPrimaryOutputSamplingRate()
{
Mutex::Autolock _l(mLock);
PlaybackThread *thread = primaryPlaybackThread_l();
return thread != NULL ? thread->sampleRate() : 0;
}
-int32_t AudioFlinger::getPrimaryOutputFrameCount()
+size_t AudioFlinger::getPrimaryOutputFrameCount()
{
Mutex::Autolock _l(mLock);
PlaybackThread *thread = primaryPlaybackThread_l();
@@ -6989,7 +7046,8 @@ audio_io_handle_t AudioFlinger::openOutput(audio_module_handle_t module,
&outStream);
mHardwareStatus = AUDIO_HW_IDLE;
- ALOGV("openOutput() openOutputStream returned output %p, SamplingRate %d, Format %d, Channels %x, status %d",
+ ALOGV("openOutput() openOutputStream returned output %p, SamplingRate %d, Format %d, "
+ "Channels %x, status %d",
outStream,
config.sample_rate,
config.format,
@@ -7042,7 +7100,8 @@ audio_io_handle_t AudioFlinger::openDuplicateOutput(audio_io_handle_t output1,
MixerThread *thread2 = checkMixerThread_l(output2);
if (thread1 == NULL || thread2 == NULL) {
- ALOGW("openDuplicateOutput() wrong output mixer type for output %d or %d", output1, output2);
+ ALOGW("openDuplicateOutput() wrong output mixer type for output %d or %d", output1,
+ output2);
return 0;
}
@@ -7077,7 +7136,8 @@ status_t AudioFlinger::closeOutput_nonvirtual(audio_io_handle_t output)
if (thread->type() == ThreadBase::MIXER) {
for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
if (mPlaybackThreads.valueAt(i)->type() == ThreadBase::DUPLICATING) {
- DuplicatingThread *dupThread = (DuplicatingThread *)mPlaybackThreads.valueAt(i).get();
+ DuplicatingThread *dupThread =
+ (DuplicatingThread *)mPlaybackThreads.valueAt(i).get();
dupThread->removeOutputTrack((MixerThread *)thread.get());
}
}
@@ -7164,16 +7224,17 @@ audio_io_handle_t AudioFlinger::openInput(audio_module_handle_t module,
status = inHwHal->open_input_stream(inHwHal, id, *pDevices, &config,
&inStream);
- ALOGV("openInput() openInputStream returned input %p, SamplingRate %d, Format %d, Channels %x, status %d",
+ ALOGV("openInput() openInputStream returned input %p, SamplingRate %d, Format %d, Channels %x, "
+ "status %d",
inStream,
config.sample_rate,
config.format,
config.channel_mask,
status);
- // If the input could not be opened with the requested parameters and we can handle the conversion internally,
- // try to open again with the proposed parameters. The AudioFlinger can resample the input and do mono to stereo
- // or stereo to mono conversions on 16 bit PCM inputs.
+ // If the input could not be opened with the requested parameters and we can handle the
+ // conversion internally, try to open again with the proposed parameters. The AudioFlinger can
+ // resample the input and do mono to stereo or stereo to mono conversions on 16 bit PCM inputs.
if (status == BAD_VALUE &&
reqFormat == config.format && config.format == AUDIO_FORMAT_PCM_16_BIT &&
(config.sample_rate <= 2 * reqSamplingRate) &&
@@ -7184,18 +7245,66 @@ audio_io_handle_t AudioFlinger::openInput(audio_module_handle_t module,
}
if (status == NO_ERROR && inStream != NULL) {
+
+ // Try to re-use most recently used Pipe to archive a copy of input for dumpsys,
+ // or (re-)create if current Pipe is idle and does not match the new format
+ sp<NBAIO_Sink> teeSink;
+#ifdef TEE_SINK_INPUT_FRAMES
+ enum {
+ TEE_SINK_NO, // don't copy input
+ TEE_SINK_NEW, // copy input using a new pipe
+ TEE_SINK_OLD, // copy input using an existing pipe
+ } kind;
+ NBAIO_Format format = Format_from_SR_C(inStream->common.get_sample_rate(&inStream->common),
+ popcount(inStream->common.get_channels(&inStream->common)));
+ if (format == Format_Invalid) {
+ kind = TEE_SINK_NO;
+ } else if (mRecordTeeSink == 0) {
+ kind = TEE_SINK_NEW;
+ } else if (mRecordTeeSink->getStrongCount() != 1) {
+ kind = TEE_SINK_NO;
+ } else if (format == mRecordTeeSink->format()) {
+ kind = TEE_SINK_OLD;
+ } else {
+ kind = TEE_SINK_NEW;
+ }
+ switch (kind) {
+ case TEE_SINK_NEW: {
+ Pipe *pipe = new Pipe(TEE_SINK_INPUT_FRAMES, format);
+ size_t numCounterOffers = 0;
+ const NBAIO_Format offers[1] = {format};
+ ssize_t index = pipe->negotiate(offers, 1, NULL, numCounterOffers);
+ ALOG_ASSERT(index == 0);
+ PipeReader *pipeReader = new PipeReader(*pipe);
+ numCounterOffers = 0;
+ index = pipeReader->negotiate(offers, 1, NULL, numCounterOffers);
+ ALOG_ASSERT(index == 0);
+ mRecordTeeSink = pipe;
+ mRecordTeeSource = pipeReader;
+ teeSink = pipe;
+ }
+ break;
+ case TEE_SINK_OLD:
+ teeSink = mRecordTeeSink;
+ break;
+ case TEE_SINK_NO:
+ default:
+ break;
+ }
+#endif
AudioStreamIn *input = new AudioStreamIn(inHwDev, inStream);
// Start record thread
// RecorThread require both input and output device indication to forward to audio
// pre processing modules
audio_devices_t device = (*pDevices) | primaryOutputDevice_l();
+
thread = new RecordThread(this,
input,
reqSamplingRate,
reqChannels,
id,
- device);
+ device, teeSink);
mRecordThreads.add(id, thread);
ALOGV("openInput() created record thread: ID %d thread %p", id, thread);
if (pSamplingRate != NULL) *pSamplingRate = reqSamplingRate;
@@ -8003,7 +8112,8 @@ status_t AudioFlinger::PlaybackThread::addEffectChain_l(const sp<EffectChain>& c
for (size_t i = 0; i < mTracks.size(); ++i) {
sp<Track> track = mTracks[i];
if (session == track->sessionId()) {
- ALOGV("addEffectChain_l() track->setMainBuffer track %p buffer %p", track.get(), buffer);
+ ALOGV("addEffectChain_l() track->setMainBuffer track %p buffer %p", track.get(),
+ buffer);
track->setMainBuffer(buffer);
chain->incTrackCnt();
}
@@ -8594,7 +8704,7 @@ status_t AudioFlinger::EffectModule::command(uint32_t cmdCode,
void *pReplyData)
{
Mutex::Autolock _l(mLock);
-// ALOGV("command(), cmdCode: %d, mEffectInterface: %p", cmdCode, mEffectInterface);
+ ALOGVV("command(), cmdCode: %d, mEffectInterface: %p", cmdCode, mEffectInterface);
if (mState == DESTROYED || mEffectInterface == NULL) {
return NO_INIT;
@@ -8845,12 +8955,15 @@ void AudioFlinger::EffectModule::dump(int fd, const Vector<String16>& args)
result.append("\t\tDescriptor:\n");
snprintf(buffer, SIZE, "\t\t- UUID: %08X-%04X-%04X-%04X-%02X%02X%02X%02X%02X%02X\n",
mDescriptor.uuid.timeLow, mDescriptor.uuid.timeMid, mDescriptor.uuid.timeHiAndVersion,
- mDescriptor.uuid.clockSeq, mDescriptor.uuid.node[0], mDescriptor.uuid.node[1],mDescriptor.uuid.node[2],
+ mDescriptor.uuid.clockSeq, mDescriptor.uuid.node[0], mDescriptor.uuid.node[1],
+ mDescriptor.uuid.node[2],
mDescriptor.uuid.node[3],mDescriptor.uuid.node[4],mDescriptor.uuid.node[5]);
result.append(buffer);
snprintf(buffer, SIZE, "\t\t- TYPE: %08X-%04X-%04X-%04X-%02X%02X%02X%02X%02X%02X\n",
- mDescriptor.type.timeLow, mDescriptor.type.timeMid, mDescriptor.type.timeHiAndVersion,
- mDescriptor.type.clockSeq, mDescriptor.type.node[0], mDescriptor.type.node[1],mDescriptor.type.node[2],
+ mDescriptor.type.timeLow, mDescriptor.type.timeMid,
+ mDescriptor.type.timeHiAndVersion,
+ mDescriptor.type.clockSeq, mDescriptor.type.node[0], mDescriptor.type.node[1],
+ mDescriptor.type.node[2],
mDescriptor.type.node[3],mDescriptor.type.node[4],mDescriptor.type.node[5]);
result.append(buffer);
snprintf(buffer, SIZE, "\t\t- apiVersion: %08X\n\t\t- flags: %08X\n",
@@ -8934,7 +9047,8 @@ AudioFlinger::EffectHandle::EffectHandle(const sp<EffectModule>& effect,
mBuffer = (uint8_t *)mCblk + bufOffset;
}
} else {
- ALOGE("not enough memory for Effect size=%u", EFFECT_PARAM_BUFFER_SIZE + sizeof(effect_param_cblk_t));
+ ALOGE("not enough memory for Effect size=%u", EFFECT_PARAM_BUFFER_SIZE +
+ sizeof(effect_param_cblk_t));
return;
}
}
@@ -9049,8 +9163,8 @@ status_t AudioFlinger::EffectHandle::command(uint32_t cmdCode,
uint32_t *replySize,
void *pReplyData)
{
-// ALOGV("command(), cmdCode: %d, mHasControl: %d, mEffect: %p",
-// cmdCode, mHasControl, (mEffect == 0) ? 0 : mEffect.get());
+ ALOGVV("command(), cmdCode: %d, mHasControl: %d, mEffect: %p",
+ cmdCode, mHasControl, (mEffect == 0) ? 0 : mEffect.get());
// only get parameter command is permitted for applications not controlling the effect
if (!mHasControl && cmdCode != EFFECT_CMD_GET_PARAM) {
@@ -9061,8 +9175,9 @@ status_t AudioFlinger::EffectHandle::command(uint32_t cmdCode,
// handle commands that are not forwarded transparently to effect engine
if (cmdCode == EFFECT_CMD_SET_PARAM_COMMIT) {
- // No need to trylock() here as this function is executed in the binder thread serving a particular client process:
- // no risk to block the whole media server process or mixer threads is we are stuck here
+ // No need to trylock() here as this function is executed in the binder thread serving a
+ // particular client process: no risk to block the whole media server process or mixer
+ // threads if we are stuck here
Mutex::Autolock _l(mCblk->lock);
if (mCblk->clientIndex > EFFECT_PARAM_BUFFER_SIZE ||
mCblk->serverIndex > EFFECT_PARAM_BUFFER_SIZE) {
@@ -9202,7 +9317,8 @@ AudioFlinger::EffectChain::~EffectChain()
}
// getEffectFromDesc_l() must be called with ThreadBase::mLock held
-sp<AudioFlinger::EffectModule> AudioFlinger::EffectChain::getEffectFromDesc_l(effect_descriptor_t *descriptor)
+sp<AudioFlinger::EffectModule> AudioFlinger::EffectChain::getEffectFromDesc_l(
+ effect_descriptor_t *descriptor)
{
size_t size = mEffects.size();
@@ -9361,7 +9477,8 @@ status_t AudioFlinger::EffectChain::addEffect_l(const sp<EffectModule>& effect)
// check invalid effect chaining combinations
if (insertPref == EFFECT_FLAG_INSERT_EXCLUSIVE ||
iPref == EFFECT_FLAG_INSERT_EXCLUSIVE) {
- ALOGW("addEffect_l() could not insert effect %s: exclusive conflict with %s", desc.name, d.name);
+ ALOGW("addEffect_l() could not insert effect %s: exclusive conflict with %s",
+ desc.name, d.name);
return INVALID_OPERATION;
}
// remember position of first insert effect and by default
@@ -9412,7 +9529,8 @@ status_t AudioFlinger::EffectChain::addEffect_l(const sp<EffectModule>& effect)
}
mEffects.insertAt(effect, idx_insert);
- ALOGV("addEffect_l() effect %p, added in chain %p at rank %d", effect.get(), this, idx_insert);
+ ALOGV("addEffect_l() effect %p, added in chain %p at rank %d", effect.get(), this,
+ idx_insert);
}
effect->configure();
return NO_ERROR;
@@ -9443,7 +9561,8 @@ size_t AudioFlinger::EffectChain::removeEffect_l(const sp<EffectModule>& effect)
}
}
mEffects.removeAt(i);
- ALOGV("removeEffect_l() effect %p, removed from chain %p at rank %d", effect.get(), this, i);
+ ALOGV("removeEffect_l() effect %p, removed from chain %p at rank %d", effect.get(),
+ this, i);
break;
}
}
@@ -9667,7 +9786,8 @@ void AudioFlinger::EffectChain::setEffectSuspendedAll_l(bool suspend)
for (size_t i = 0; i < types.size(); i++) {
setEffectSuspended_l(types[i], false);
}
- ALOGV("setEffectSuspendedAll_l() remove entry for %08x", mSuspendedEffects.keyAt(index));
+ ALOGV("setEffectSuspendedAll_l() remove entry for %08x",
+ mSuspendedEffects.keyAt(index));
mSuspendedEffects.removeItem((int)kKeyForSuspendAll);
}
}
@@ -9693,7 +9813,8 @@ bool AudioFlinger::EffectChain::isEffectEligibleForSuspend(const effect_descript
return true;
}
-void AudioFlinger::EffectChain::getSuspendEligibleEffects(Vector< sp<AudioFlinger::EffectModule> > &effects)
+void AudioFlinger::EffectChain::getSuspendEligibleEffects(
+ Vector< sp<AudioFlinger::EffectModule> > &effects)
{
effects.clear();
for (size_t i = 0; i < mEffects.size(); i++) {
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 49e2b2c..830dfe9 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -92,8 +92,8 @@ public:
uint32_t sampleRate,
audio_format_t format,
audio_channel_mask_t channelMask,
- int frameCount,
- IAudioFlinger::track_flags_t flags,
+ size_t frameCount,
+ IAudioFlinger::track_flags_t *flags,
const sp<IMemory>& sharedBuffer,
audio_io_handle_t output,
pid_t tid,
@@ -106,7 +106,7 @@ public:
uint32_t sampleRate,
audio_format_t format,
audio_channel_mask_t channelMask,
- int frameCount,
+ size_t frameCount,
IAudioFlinger::track_flags_t flags,
pid_t tid,
int *sessionId,
@@ -207,8 +207,8 @@ public:
virtual audio_module_handle_t loadHwModule(const char *name);
- virtual int32_t getPrimaryOutputSamplingRate();
- virtual int32_t getPrimaryOutputFrameCount();
+ virtual uint32_t getPrimaryOutputSamplingRate();
+ virtual size_t getPrimaryOutputFrameCount();
virtual status_t onTransact(
uint32_t code,
@@ -269,12 +269,14 @@ private:
virtual ~AudioFlinger();
// call in any IAudioFlinger method that accesses mPrimaryHardwareDev
- status_t initCheck() const { return mPrimaryHardwareDev == NULL ? NO_INIT : NO_ERROR; }
+ status_t initCheck() const { return mPrimaryHardwareDev == NULL ?
+ NO_INIT : NO_ERROR; }
// RefBase
virtual void onFirstRef();
- AudioHwDevice* findSuitableHwDev_l(audio_module_handle_t module, audio_devices_t devices);
+ AudioHwDevice* findSuitableHwDev_l(audio_module_handle_t module,
+ audio_devices_t devices);
void purgeStaleEffects_l();
// standby delay for MIXER and DUPLICATING playback threads is read from property
@@ -356,7 +358,7 @@ private:
RECORD // Thread class is RecordThread
};
- ThreadBase (const sp<AudioFlinger>& audioFlinger, audio_io_handle_t id,
+ ThreadBase(const sp<AudioFlinger>& audioFlinger, audio_io_handle_t id,
audio_devices_t outDevice, audio_devices_t inDevice, type_t type);
virtual ~ThreadBase();
@@ -388,7 +390,7 @@ private:
uint32_t sampleRate,
audio_format_t format,
audio_channel_mask_t channelMask,
- int frameCount,
+ size_t frameCount,
const sp<IMemory>& sharedBuffer,
int sessionId);
virtual ~TrackBase();
@@ -421,7 +423,7 @@ private:
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
@@ -451,9 +453,12 @@ private:
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;
@@ -461,16 +466,20 @@ private:
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;
};
@@ -746,7 +755,8 @@ private:
const sp<PMDeathRecipient> mDeathRecipient;
// list of suspended effects per session and per type. The first vector is
// keyed by session ID, the second by type UUID timeLow field
- KeyedVector< int, KeyedVector< int, sp<SuspendedSessionDesc> > > mSuspendedSessions;
+ KeyedVector< int, KeyedVector< int, sp<SuspendedSessionDesc> > >
+ mSuspendedSessions;
};
struct stream_type_t {
@@ -780,7 +790,7 @@ private:
uint32_t sampleRate,
audio_format_t format,
audio_channel_mask_t channelMask,
- int frameCount,
+ size_t frameCount,
const sp<IMemory>& sharedBuffer,
int sessionId,
IAudioFlinger::track_flags_t flags);
@@ -788,7 +798,8 @@ private:
static void appendDumpHeader(String8& result);
void dump(char* buffer, size_t size);
- virtual status_t start(AudioSystem::sync_event_t event = AudioSystem::SYNC_EVENT_NONE,
+ virtual status_t start(AudioSystem::sync_event_t event =
+ AudioSystem::SYNC_EVENT_NONE,
int triggerSession = 0);
virtual void stop();
void pause();
@@ -810,6 +821,7 @@ private:
// implement FastMixerState::VolumeProvider interface
virtual uint32_t getVolumeLR();
+
virtual status_t setSyncEvent(const sp<SyncEvent>& event);
protected:
@@ -822,7 +834,8 @@ private:
Track& operator = (const Track&);
// AudioBufferProvider interface
- virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer, int64_t pts = kInvalidPTS);
+ virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer,
+ int64_t pts = kInvalidPTS);
// releaseBuffer() not overridden
virtual size_t framesReady() const;
@@ -847,12 +860,16 @@ private:
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:
@@ -876,8 +893,9 @@ private:
int32_t *mAuxBuffer;
int mAuxEffectId;
bool mHasVolumeController;
- size_t mPresentationCompleteFrames; // number of frames written to the audio HAL
- // when this track will be fully rendered
+ 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;
@@ -904,7 +922,7 @@ private:
uint32_t sampleRate,
audio_format_t format,
audio_channel_mask_t channelMask,
- int frameCount,
+ size_t frameCount,
const sp<IMemory>& sharedBuffer,
int sessionId);
virtual ~TimedTrack();
@@ -947,7 +965,7 @@ private:
uint32_t sampleRate,
audio_format_t format,
audio_channel_mask_t channelMask,
- int frameCount,
+ size_t frameCount,
const sp<IMemory>& sharedBuffer,
int sessionId);
@@ -982,11 +1000,11 @@ private:
};
- // playback track
+ // playback track, used by DuplicatingThread
class OutputTrack : public Track {
public:
- class Buffer: public AudioBufferProvider::Buffer {
+ class Buffer : public AudioBufferProvider::Buffer {
public:
int16_t *mBuffer;
};
@@ -996,10 +1014,11 @@ private:
uint32_t sampleRate,
audio_format_t format,
audio_channel_mask_t channelMask,
- int frameCount);
+ size_t frameCount);
virtual ~OutputTrack();
- virtual status_t start(AudioSystem::sync_event_t event = AudioSystem::SYNC_EVENT_NONE,
+ virtual status_t start(AudioSystem::sync_event_t event =
+ AudioSystem::SYNC_EVENT_NONE,
int triggerSession = 0);
virtual void stop();
bool write(int16_t* data, uint32_t frames);
@@ -1013,7 +1032,8 @@ private:
NO_MORE_BUFFERS = 0x80000001, // same in AudioTrack.h, ok to be different value
};
- status_t obtainBuffer(AudioBufferProvider::Buffer* buffer, uint32_t waitTimeMs);
+ status_t obtainBuffer(AudioBufferProvider::Buffer* buffer,
+ uint32_t waitTimeMs);
void clearBufferQueue();
// Maximum number of pending buffers allocated by OutputTrack::write()
@@ -1023,10 +1043,11 @@ private:
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,
- audio_io_handle_t id, audio_devices_t device, type_t type);
+ PlaybackThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output,
+ audio_io_handle_t id, audio_devices_t device, type_t type);
virtual ~PlaybackThread();
void dump(int fd, const Vector<String16>& args);
@@ -1078,10 +1099,10 @@ public:
uint32_t sampleRate,
audio_format_t format,
audio_channel_mask_t channelMask,
- int frameCount,
+ size_t frameCount,
const sp<IMemory>& sharedBuffer,
int sessionId,
- IAudioFlinger::track_flags_t flags,
+ IAudioFlinger::track_flags_t *flags,
pid_t tid,
status_t *status);
@@ -1185,7 +1206,8 @@ public:
void dumpTracks(int fd, const Vector<String16>& args);
SortedVector< sp<Track> > mTracks;
- // mStreamTypes[] uses 1 additional stream type internally for the OutputTrack used by DuplicatingThread
+ // mStreamTypes[] uses 1 additional stream type internally for the OutputTrack used by
+ // DuplicatingThread
stream_type_t mStreamTypes[AUDIO_STREAM_CNT + 1];
AudioStreamOut *mOutput;
@@ -1248,11 +1270,11 @@ public:
class MixerThread : public PlaybackThread {
public:
- MixerThread (const sp<AudioFlinger>& audioFlinger,
- AudioStreamOut* output,
- audio_io_handle_t id,
- audio_devices_t device,
- type_t type = MIXER);
+ MixerThread(const sp<AudioFlinger>& audioFlinger,
+ AudioStreamOut* output,
+ audio_io_handle_t id,
+ audio_devices_t device,
+ type_t type = MIXER);
virtual ~MixerThread();
// Thread virtuals
@@ -1305,8 +1327,8 @@ public:
class DirectOutputThread : public PlaybackThread {
public:
- DirectOutputThread (const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output,
- audio_io_handle_t id, audio_devices_t device);
+ DirectOutputThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output,
+ audio_io_handle_t id, audio_devices_t device);
virtual ~DirectOutputThread();
// Thread virtuals
@@ -1326,11 +1348,11 @@ public:
virtual void threadLoop_mix();
virtual void threadLoop_sleepTime();
+ private:
// volumes last sent to audio HAL with stream->set_volume()
float mLeftVolFloat;
float mRightVolFloat;
-private:
// prepareTracks_l() tells threadLoop_mix() the name of the single active track
sp<Track> mActiveTrack;
public:
@@ -1339,8 +1361,8 @@ private:
class DuplicatingThread : public MixerThread {
public:
- DuplicatingThread (const sp<AudioFlinger>& audioFlinger, MixerThread* mainThread,
- audio_io_handle_t id);
+ DuplicatingThread(const sp<AudioFlinger>& audioFlinger, MixerThread* mainThread,
+ audio_io_handle_t id);
virtual ~DuplicatingThread();
// Thread virtuals
@@ -1441,7 +1463,7 @@ private:
uint32_t sampleRate,
audio_format_t format,
audio_channel_mask_t channelMask,
- int frameCount,
+ size_t frameCount,
int sessionId);
virtual ~RecordTrack();
@@ -1453,11 +1475,14 @@ private:
// clear the buffer overflow flag
void clearOverflow() { mOverflow = false; }
// set the buffer overflow flag and return previous value
- bool setOverflow() { bool tmp = mOverflow; mOverflow = true; return tmp; }
+ bool setOverflow() { bool tmp = mOverflow; mOverflow = true;
+ return tmp; }
static void appendDumpHeader(String8& result);
void dump(char* buffer, size_t size);
+ virtual bool isOut() const;
+
private:
friend class AudioFlinger; // for mState
@@ -1465,7 +1490,8 @@ private:
RecordTrack& operator = (const RecordTrack&);
// AudioBufferProvider interface
- virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer, int64_t pts = kInvalidPTS);
+ virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer,
+ int64_t pts = kInvalidPTS);
// releaseBuffer() not overridden
bool mOverflow; // overflow on most recent attempt to fill client buffer
@@ -1476,7 +1502,8 @@ private:
uint32_t sampleRate,
audio_channel_mask_t channelMask,
audio_io_handle_t id,
- audio_devices_t device);
+ audio_devices_t device,
+ const sp<NBAIO_Sink>& teeSink);
virtual ~RecordThread();
// no addTrack_l ?
@@ -1499,7 +1526,7 @@ private:
uint32_t sampleRate,
audio_format_t format,
audio_channel_mask_t channelMask,
- int frameCount,
+ size_t frameCount,
int sessionId,
IAudioFlinger::track_flags_t flags,
pid_t tid,
@@ -1572,6 +1599,9 @@ private:
// when < 0, maximum frames to drop before starting capture even if sync event is
// not received
ssize_t mFramestoDrop;
+
+ // For dumpsys
+ const sp<NBAIO_Sink> mTeeSink;
};
// server side of the client's IAudioRecord
@@ -1607,7 +1637,7 @@ private:
// ramping when effects are activated/deactivated.
// When controlling an auxiliary effect, the EffectModule also provides an input buffer used by
// the attached track(s) to accumulate their auxiliary channel.
- class EffectModule: public RefBase {
+ class EffectModule : public RefBase {
public:
EffectModule(ThreadBase *thread,
const wp<AudioFlinger::EffectChain>& chain,
@@ -1781,7 +1811,8 @@ mutable Mutex mLock; // mutex for process, commands and handl
sp<IEffectClient> mEffectClient; // callback interface for client notifications
/*const*/ sp<Client> mClient; // client for shared memory allocation, see disconnect()
sp<IMemory> mCblkMemory; // shared memory for control block
- effect_param_cblk_t* mCblk; // control block for deferred parameter setting via shared memory
+ effect_param_cblk_t* mCblk; // control block for deferred parameter setting via
+ // shared memory
uint8_t* mBuffer; // pointer to parameter area in shared memory
int mPriority; // client application priority to control the effect
bool mHasControl; // true if this handle is controlling the effect
@@ -1794,11 +1825,11 @@ mutable Mutex mLock; // mutex for process, commands and handl
// the EffectChain class represents a group of effects associated to one audio session.
// There can be any number of EffectChain objects per output mixer thread (PlaybackThread).
// The EffecChain with session ID 0 contains global effects applied to the output mix.
- // Effects in this chain can be insert or auxiliary. Effects in other chains (attached to tracks)
- // are insert only. The EffectChain maintains an ordered list of effect module, the order corresponding
- // in the effect process order. When attached to a track (session ID != 0), it also provide it's own
- // input buffer used by the track as accumulation buffer.
- class EffectChain: public RefBase {
+ // Effects in this chain can be insert or auxiliary. Effects in other chains (attached to
+ // tracks) are insert only. The EffectChain maintains an ordered list of effect module, the
+ // order corresponding in the effect process order. When attached to a track (session ID != 0),
+ // it also provide it's own input buffer used by the track as accumulation buffer.
+ class EffectChain : public RefBase {
public:
EffectChain(const wp<ThreadBase>& wThread, int sessionId);
EffectChain(ThreadBase *thread, int sessionId);
@@ -2064,6 +2095,13 @@ private:
// for use from destructor
status_t closeOutput_nonvirtual(audio_io_handle_t output);
status_t closeInput_nonvirtual(audio_io_handle_t input);
+
+ // all record threads serially share a common tee sink, which is re-created on format change
+ sp<NBAIO_Sink> mRecordTeeSink;
+ sp<NBAIO_Source> mRecordTeeSource;
+
+public:
+ static void dumpTee(int fd, const sp<NBAIO_Source>& source, audio_io_handle_t id = 0);
};
diff --git a/services/audioflinger/AudioMixer.cpp b/services/audioflinger/AudioMixer.cpp
index af169d5..b3ca877 100644
--- a/services/audioflinger/AudioMixer.cpp
+++ b/services/audioflinger/AudioMixer.cpp
@@ -106,8 +106,16 @@ AudioMixer::AudioMixer(size_t frameCount, uint32_t sampleRate, uint32_t maxNumTr
ALOG_ASSERT(maxNumTracks <= MAX_NUM_TRACKS, "maxNumTracks %u > MAX_NUM_TRACKS %u",
maxNumTracks, MAX_NUM_TRACKS);
+ // AudioMixer is not yet capable of more than 32 active track inputs
+ ALOG_ASSERT(32 >= MAX_NUM_TRACKS, "bad MAX_NUM_TRACKS %d", MAX_NUM_TRACKS);
+
+ // AudioMixer is not yet capable of multi-channel output beyond stereo
+ ALOG_ASSERT(2 == MAX_NUM_CHANNELS, "bad MAX_NUM_CHANNELS %d", MAX_NUM_CHANNELS);
+
LocalClock lc;
+ pthread_once(&sOnceControl, &sInitRoutine);
+
mState.enabledTracks= 0;
mState.needsChanged = 0;
mState.frameCount = frameCount;
@@ -121,8 +129,6 @@ AudioMixer::AudioMixer(size_t frameCount, uint32_t sampleRate, uint32_t maxNumTr
// and mTrackNames is initially 0. However, leave it here until that's verified.
track_t* t = mState.tracks;
for (unsigned i=0 ; i < MAX_NUM_TRACKS ; i++) {
- // FIXME redundant per track
- t->localTimeFreq = lc.getLocalFreq();
t->resampler = NULL;
t->downmixerBufferProvider = NULL;
t++;
@@ -192,7 +198,6 @@ int AudioMixer::getTrackName(audio_channel_mask_t channelMask, int sessionId)
t->sessionId = sessionId;
// setBufferProvider(name, AudioBufferProvider *) is required before enable(name)
t->bufferProvider = NULL;
- t->downmixerBufferProvider = NULL;
t->buffer.raw = NULL;
// no initialization needed
// t->buffer.frameCount
@@ -203,7 +208,7 @@ int AudioMixer::getTrackName(audio_channel_mask_t channelMask, int sessionId)
// setParameter(name, TRACK, MAIN_BUFFER, mixBuffer) is required before enable(name)
t->mainBuffer = NULL;
t->auxBuffer = NULL;
- // see t->localTimeFreq in constructor above
+ t->downmixerBufferProvider = NULL;
status_t status = initTrackDownmix(&mState.tracks[n], n, channelMask);
if (status == OK) {
@@ -556,7 +561,7 @@ bool AudioMixer::track_t::setResampler(uint32_t value, uint32_t devSampleRate)
// the resampler sees the number of channels after the downmixer, if any
downmixerBufferProvider != NULL ? MAX_NUM_CHANNELS : channelCount,
devSampleRate, quality);
- resampler->setLocalTimeFreq(localTimeFreq);
+ resampler->setLocalTimeFreq(sLocalTimeFreq);
}
return true;
}
@@ -760,7 +765,8 @@ void AudioMixer::process__validate(state_t* state, int64_t pts)
}
-void AudioMixer::track__genericResample(track_t* t, int32_t* out, size_t outFrameCount, int32_t* temp, int32_t* aux)
+void AudioMixer::track__genericResample(track_t* t, int32_t* out, size_t outFrameCount,
+ int32_t* temp, int32_t* aux)
{
t->resampler->setSampleRate(t->sampleRate);
@@ -793,11 +799,13 @@ void AudioMixer::track__genericResample(track_t* t, int32_t* out, size_t outFram
}
}
-void AudioMixer::track__nop(track_t* t, int32_t* out, size_t outFrameCount, int32_t* temp, int32_t* aux)
+void AudioMixer::track__nop(track_t* t, int32_t* out, size_t outFrameCount, int32_t* temp,
+ int32_t* aux)
{
}
-void AudioMixer::volumeRampStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux)
+void AudioMixer::volumeRampStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp,
+ int32_t* aux)
{
int32_t vl = t->prevVolume[0];
int32_t vr = t->prevVolume[1];
@@ -839,7 +847,8 @@ void AudioMixer::volumeRampStereo(track_t* t, int32_t* out, size_t frameCount, i
t->adjustVolumeRamp(aux != NULL);
}
-void AudioMixer::volumeStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux)
+void AudioMixer::volumeStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp,
+ int32_t* aux)
{
const int16_t vl = t->volume[0];
const int16_t vr = t->volume[1];
@@ -867,7 +876,8 @@ void AudioMixer::volumeStereo(track_t* t, int32_t* out, size_t frameCount, int32
}
}
-void AudioMixer::track__16BitsStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux)
+void AudioMixer::track__16BitsStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp,
+ int32_t* aux)
{
const int16_t *in = static_cast<const int16_t *>(t->in);
@@ -957,7 +967,8 @@ void AudioMixer::track__16BitsStereo(track_t* t, int32_t* out, size_t frameCount
t->in = in;
}
-void AudioMixer::track__16BitsMono(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux)
+void AudioMixer::track__16BitsMono(track_t* t, int32_t* out, size_t frameCount, int32_t* temp,
+ int32_t* aux)
{
const int16_t *in = static_cast<int16_t const *>(t->in);
@@ -1142,7 +1153,8 @@ void AudioMixer::process__genericNoResampling(state_t* state, int64_t pts)
while (outFrames) {
size_t inFrames = (t.frameCount > outFrames)?outFrames:t.frameCount;
if (inFrames) {
- t.hook(&t, outTemp + (BLOCKSIZE-outFrames)*MAX_NUM_CHANNELS, inFrames, state->resampleTemp, aux);
+ t.hook(&t, outTemp + (BLOCKSIZE-outFrames)*MAX_NUM_CHANNELS, inFrames,
+ state->resampleTemp, aux);
t.frameCount -= inFrames;
outFrames -= inFrames;
if (CC_UNLIKELY(aux != NULL)) {
@@ -1151,7 +1163,8 @@ void AudioMixer::process__genericNoResampling(state_t* state, int64_t pts)
}
if (t.frameCount == 0 && outFrames) {
t.bufferProvider->releaseBuffer(&t.buffer);
- t.buffer.frameCount = (state->frameCount - numFrames) - (BLOCKSIZE - outFrames);
+ t.buffer.frameCount = (state->frameCount - numFrames) -
+ (BLOCKSIZE - outFrames);
int64_t outputPTS = calculateOutputPTS(
t, pts, numFrames + (BLOCKSIZE - outFrames));
t.bufferProvider->getNextBuffer(&t.buffer, outputPTS);
@@ -1241,7 +1254,8 @@ void AudioMixer::process__genericResampling(state_t* state, int64_t pts)
if (CC_UNLIKELY(aux != NULL)) {
aux += outFrames;
}
- t.hook(&t, outTemp + outFrames*MAX_NUM_CHANNELS, t.buffer.frameCount, state->resampleTemp, aux);
+ t.hook(&t, outTemp + outFrames*MAX_NUM_CHANNELS, t.buffer.frameCount,
+ state->resampleTemp, aux);
outFrames += t.buffer.frameCount;
t.bufferProvider->releaseBuffer(&t.buffer);
}
@@ -1281,7 +1295,8 @@ void AudioMixer::process__OneTrack16BitsStereoNoResampling(state_t* state,
// been enabled for mixing.
if (in == NULL || ((unsigned long)in & 3)) {
memset(out, 0, numFrames*MAX_NUM_CHANNELS*sizeof(int16_t));
- ALOGE_IF(((unsigned long)in & 3), "process stereo track: input buffer alignment pb: buffer %p track %d, channels %d, needs %08x",
+ ALOGE_IF(((unsigned long)in & 3), "process stereo track: input buffer alignment pb: "
+ "buffer %p track %d, channels %d, needs %08x",
in, i, t.channelCount, t.needs);
return;
}
@@ -1423,7 +1438,16 @@ int64_t AudioMixer::calculateOutputPTS(const track_t& t, int64_t basePTS,
if (AudioBufferProvider::kInvalidPTS == basePTS)
return AudioBufferProvider::kInvalidPTS;
- return basePTS + ((outputFrameIndex * t.localTimeFreq) / t.sampleRate);
+ return basePTS + ((outputFrameIndex * sLocalTimeFreq) / t.sampleRate);
+}
+
+/*static*/ uint64_t AudioMixer::sLocalTimeFreq;
+/*static*/ pthread_once_t AudioMixer::sOnceControl = PTHREAD_ONCE_INIT;
+
+/*static*/ void AudioMixer::sInitRoutine()
+{
+ LocalClock lc;
+ sLocalTimeFreq = lc.getLocalFreq();
}
// ----------------------------------------------------------------------------
diff --git a/services/audioflinger/AudioMixer.h b/services/audioflinger/AudioMixer.h
index 6333357..fd21fda 100644
--- a/services/audioflinger/AudioMixer.h
+++ b/services/audioflinger/AudioMixer.h
@@ -41,8 +41,15 @@ public:
/*virtual*/ ~AudioMixer(); // non-virtual saves a v-table, restore if sub-classed
+
+ // This mixer has a hard-coded upper limit of 32 active track inputs.
+ // Adding support for > 32 tracks would require more than simply changing this value.
static const uint32_t MAX_NUM_TRACKS = 32;
// maximum number of channels supported by the mixer
+
+ // This mixer has a hard-coded upper limit of 2 channels for output.
+ // There is support for > 2 channel tracks down-mixed to 2 channel output via a down-mix effect.
+ // Adding support for > 2 channel output would require more than simply changing this value.
static const uint32_t MAX_NUM_CHANNELS = 2;
// maximum number of channels supported for the content
static const uint32_t MAX_NUM_CHANNELS_TO_DOWNMIX = 8;
@@ -139,7 +146,8 @@ private:
struct track_t;
class DownmixerBufferProvider;
- typedef void (*hook_t)(track_t* t, int32_t* output, size_t numOutFrames, int32_t* temp, int32_t* aux);
+ typedef void (*hook_t)(track_t* t, int32_t* output, size_t numOutFrames, int32_t* temp,
+ int32_t* aux);
static const int BLOCKSIZE = 16; // 4 cache lines
struct track_t {
@@ -188,12 +196,12 @@ private:
// 16-byte boundary
- uint64_t localTimeFreq;
-
DownmixerBufferProvider* downmixerBufferProvider; // 4 bytes
int32_t sessionId;
+ int32_t padding[2];
+
// 16-byte boundary
bool setResampler(uint32_t sampleRate, uint32_t devSampleRate);
@@ -254,12 +262,17 @@ private:
static status_t prepareTrackForDownmix(track_t* pTrack, int trackNum);
static void unprepareTrackForDownmix(track_t* pTrack, int trackName);
- static void track__genericResample(track_t* t, int32_t* out, size_t numFrames, int32_t* temp, int32_t* aux);
+ static void track__genericResample(track_t* t, int32_t* out, size_t numFrames, int32_t* temp,
+ int32_t* aux);
static void track__nop(track_t* t, int32_t* out, size_t numFrames, int32_t* temp, int32_t* aux);
- static void track__16BitsStereo(track_t* t, int32_t* out, size_t numFrames, int32_t* temp, int32_t* aux);
- static void track__16BitsMono(track_t* t, int32_t* out, size_t numFrames, int32_t* temp, int32_t* aux);
- static void volumeRampStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux);
- static void volumeStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux);
+ static void track__16BitsStereo(track_t* t, int32_t* out, size_t numFrames, int32_t* temp,
+ int32_t* aux);
+ static void track__16BitsMono(track_t* t, int32_t* out, size_t numFrames, int32_t* temp,
+ int32_t* aux);
+ static void volumeRampStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp,
+ int32_t* aux);
+ static void volumeStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp,
+ int32_t* aux);
static void process__validate(state_t* state, int64_t pts);
static void process__nop(state_t* state, int64_t pts);
@@ -274,6 +287,10 @@ private:
static int64_t calculateOutputPTS(const track_t& t, int64_t basePTS,
int outputFrameIndex);
+
+ static uint64_t sLocalTimeFreq;
+ static pthread_once_t sOnceControl;
+ static void sInitRoutine();
};
// ----------------------------------------------------------------------------
diff --git a/services/audioflinger/AudioPolicyService.cpp b/services/audioflinger/AudioPolicyService.cpp
index 8b99bd2..ea130ba 100644
--- a/services/audioflinger/AudioPolicyService.cpp
+++ b/services/audioflinger/AudioPolicyService.cpp
@@ -227,7 +227,8 @@ audio_io_handle_t AudioPolicyService::getOutput(audio_stream_type_t stream,
}
ALOGV("getOutput() tid %d", gettid());
Mutex::Autolock _l(mLock);
- return mpAudioPolicy->get_output(mpAudioPolicy, stream, samplingRate, format, channelMask, flags);
+ return mpAudioPolicy->get_output(mpAudioPolicy, stream, samplingRate, format, channelMask,
+ flags);
}
status_t AudioPolicyService::startOutput(audio_io_handle_t output,
@@ -280,7 +281,7 @@ audio_io_handle_t AudioPolicyService::getInput(audio_source_t inputSource,
Mutex::Autolock _l(mLock);
// the audio_in_acoustics_t parameter is ignored by get_input()
audio_io_handle_t input = mpAudioPolicy->get_input(mpAudioPolicy, inputSource, samplingRate,
- format, channelMask, (audio_in_acoustics_t) 0);
+ format, channelMask, (audio_in_acoustics_t) 0);
if (input == 0) {
return input;
diff --git a/services/audioflinger/AudioPolicyService.h b/services/audioflinger/AudioPolicyService.h
index 63f9549..92653c1 100644
--- a/services/audioflinger/AudioPolicyService.h
+++ b/services/audioflinger/AudioPolicyService.h
@@ -142,11 +142,11 @@ private:
status_t dumpInternals(int fd);
// Thread used for tone playback and to send audio config commands to audio flinger
- // For tone playback, using a separate thread is necessary to avoid deadlock with mLock because startTone()
- // and stopTone() are normally called with mLock locked and requesting a tone start or stop will cause
- // calls to AudioPolicyService and an attempt to lock mLock.
- // For audio config commands, it is necessary because audio flinger requires that the calling process (user)
- // has permission to modify audio settings.
+ // For tone playback, using a separate thread is necessary to avoid deadlock with mLock because
+ // startTone() and stopTone() are normally called with mLock locked and requesting a tone start
+ // or stop will cause calls to AudioPolicyService and an attempt to lock mLock.
+ // For audio config commands, it is necessary because audio flinger requires that the calling
+ // process (user) has permission to modify audio settings.
class AudioCommandThread : public Thread {
class AudioCommand;
public:
diff --git a/services/audioflinger/AudioResampler.cpp b/services/audioflinger/AudioResampler.cpp
index ffea9b9..2c3c719 100644
--- a/services/audioflinger/AudioResampler.cpp
+++ b/services/audioflinger/AudioResampler.cpp
@@ -82,10 +82,8 @@ bool AudioResampler::qualityIsSupported(src_quality quality)
switch (quality) {
case DEFAULT_QUALITY:
case LOW_QUALITY:
-#if 0 // these have not been qualified recently so are not supported unless explicitly requested
case MED_QUALITY:
case HIGH_QUALITY:
-#endif
case VERY_HIGH_QUALITY:
return true;
default:
@@ -190,12 +188,10 @@ AudioResampler* AudioResampler::create(int bitDepth, int inChannelCount,
ALOGV("Create linear Resampler");
resampler = new AudioResamplerOrder1(bitDepth, inChannelCount, sampleRate);
break;
-#if 0 // disabled because it has not been qualified recently, if requested will use default:
case MED_QUALITY:
ALOGV("Create cubic Resampler");
resampler = new AudioResamplerCubic(bitDepth, inChannelCount, sampleRate);
break;
-#endif
case HIGH_QUALITY:
ALOGV("Create HIGH_QUALITY sinc Resampler");
resampler = new AudioResamplerSinc(bitDepth, inChannelCount, sampleRate);
diff --git a/services/audioflinger/AudioResamplerSinc.cpp b/services/audioflinger/AudioResamplerSinc.cpp
index 9e8447a..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 <stdlib.h>
#include <dlfcn.h>
+
+#include <cutils/compiler.h>
#include <cutils/properties.h>
-#include <stdlib.h>
+
#include <utils/Log.h>
+#include "AudioResamplerSinc.h"
+
+
+
+#if defined(__arm__) && !defined(__thumb__)
+#define USE_INLINE_ASSEMBLY (true)
+#else
+#define USE_INLINE_ASSEMBLY (false)
+#endif
+
+#if USE_INLINE_ASSEMBLY && defined(__ARM_NEON__)
+#define USE_NEON (true)
+#else
+#define USE_NEON (false)
+#endif
+
+
namespace android {
// ----------------------------------------------------------------------------
@@ -31,37 +51,274 @@ namespace android {
/*
* These coeficients are computed with the "fir" utility found in
* tools/resampler_tools
- * TODO: A good optimization would be to transpose this matrix, to take
- * better advantage of the data-cache.
+ * cmd-line: fir -l 7 -s 48000 -c 20478
*/
-const int32_t AudioResamplerSinc::mFirCoefsUp[] = {
- 0x7fffffff, 0x7f15d078, 0x7c5e0da6, 0x77ecd867, 0x71e2e251, 0x6a6c304a, 0x61be7269, 0x58170412, 0x4db8ab05, 0x42e92ea6, 0x37eee214, 0x2d0e3bb1, 0x22879366, 0x18951e95, 0x0f693d0d, 0x072d2621,
- 0x00000000, 0xf9f66655, 0xf51a5fd7, 0xf16bbd84, 0xeee0d9ac, 0xed67a922, 0xece70de6, 0xed405897, 0xee50e505, 0xeff3be30, 0xf203370f, 0xf45a6741, 0xf6d67d53, 0xf957db66, 0xfbc2f647, 0xfe00f2b9,
- 0x00000000, 0x01b37218, 0x0313a0c6, 0x041d930d, 0x04d28057, 0x053731b0, 0x05534dff, 0x05309bfd, 0x04da440d, 0x045c1aee, 0x03c1fcdd, 0x03173ef5, 0x02663ae8, 0x01b7f736, 0x0113ec79, 0x007fe6a9,
- 0x00000000, 0xff96b229, 0xff44f99f, 0xff0a86be, 0xfee5f803, 0xfed518fd, 0xfed521fd, 0xfee2f4fd, 0xfefb54f8, 0xff1b159b, 0xff3f4203, 0xff6539e0, 0xff8ac502, 0xffae1ddd, 0xffcdf3f9, 0xffe96798,
- 0x00000000, 0x00119de6, 0x001e6b7e, 0x0026cb7a, 0x002b4830, 0x002c83d6, 0x002b2a82, 0x0027e67a, 0x002356f9, 0x001e098e, 0x001875e4, 0x0012fbbe, 0x000de2d1, 0x00095c10, 0x00058414, 0x00026636,
- 0x00000000, 0xfffe44a9, 0xfffd206d, 0xfffc7b7f, 0xfffc3c8f, 0xfffc4ac2, 0xfffc8f2b, 0xfffcf5c4, 0xfffd6df3, 0xfffdeab2, 0xfffe6275, 0xfffececf, 0xffff2c07, 0xffff788c, 0xffffb471, 0xffffe0f2,
- 0x00000000, 0x000013e6, 0x00001f03, 0x00002396, 0x00002399, 0x000020b6, 0x00001c3c, 0x00001722, 0x00001216, 0x00000d81, 0x0000099c, 0x0000067c, 0x00000419, 0x0000025f, 0x00000131, 0x00000070,
- 0x00000000, 0xffffffc7, 0xffffffb3, 0xffffffb3, 0xffffffbe, 0xffffffcd, 0xffffffdb, 0xffffffe7, 0xfffffff0, 0xfffffff7, 0xfffffffb, 0xfffffffe, 0xffffffff, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000 // this one is needed for lerping the last coefficient
+const int32_t AudioResamplerSinc::mFirCoefsUp[] __attribute__ ((aligned (32))) = {
+ 0x6d374bc7, 0x111c6ba0, 0xf3240e61, 0x07d14a38, 0xfc509e64, 0x0139cee9, 0xffc8c866, 0xfffcc300,
+ 0x6d35278a, 0x103e8192, 0xf36b9dfd, 0x07bdfaa5, 0xfc5102d0, 0x013d618d, 0xffc663b9, 0xfffd9592,
+ 0x6d2ebafe, 0x0f62811a, 0xf3b3d8ac, 0x07a9f399, 0xfc51d9a6, 0x0140bea5, 0xffc41212, 0xfffe631e,
+ 0x6d24069d, 0x0e8875ad, 0xf3fcb43e, 0x07953976, 0xfc53216f, 0x0143e67c, 0xffc1d373, 0xffff2b9f,
+ 0x6d150b35, 0x0db06a89, 0xf4462690, 0x077fd0ac, 0xfc54d8ae, 0x0146d965, 0xffbfa7d9, 0xffffef10,
+ 0x6d01c9e3, 0x0cda6ab5, 0xf4902587, 0x0769bdaf, 0xfc56fdda, 0x014997bb, 0xffbd8f40, 0x0000ad6e,
+ 0x6cea4418, 0x0c0680fe, 0xf4daa718, 0x07530501, 0xfc598f60, 0x014c21db, 0xffbb89a1, 0x000166b6,
+ 0x6cce7b97, 0x0b34b7f5, 0xf525a143, 0x073bab28, 0xfc5c8ba5, 0x014e782a, 0xffb996f3, 0x00021ae5,
+ 0x6cae7272, 0x0a6519f4, 0xf5710a17, 0x0723b4b4, 0xfc5ff105, 0x01509b14, 0xffb7b728, 0x0002c9fd,
+ 0x6c8a2b0f, 0x0997b116, 0xf5bcd7b1, 0x070b2639, 0xfc63bdd3, 0x01528b08, 0xffb5ea31, 0x000373fb,
+ 0x6c61a823, 0x08cc873c, 0xf609003f, 0x06f20453, 0xfc67f05a, 0x0154487b, 0xffb42ffc, 0x000418e2,
+ 0x6c34ecb5, 0x0803a60a, 0xf6557a00, 0x06d853a2, 0xfc6c86dd, 0x0155d3e8, 0xffb28876, 0x0004b8b3,
+ 0x6c03fc1c, 0x073d16e7, 0xf6a23b44, 0x06be18cd, 0xfc717f97, 0x01572dcf, 0xffb0f388, 0x00055371,
+ 0x6bced9ff, 0x0678e2fc, 0xf6ef3a6e, 0x06a3587e, 0xfc76d8bc, 0x015856b6, 0xffaf7118, 0x0005e921,
+ 0x6b958a54, 0x05b71332, 0xf73c6df4, 0x06881761, 0xfc7c9079, 0x01594f25, 0xffae010b, 0x000679c5,
+ 0x6b581163, 0x04f7b037, 0xf789cc61, 0x066c5a27, 0xfc82a4f4, 0x015a17ab, 0xffaca344, 0x00070564,
+ 0x6b1673c1, 0x043ac276, 0xf7d74c53, 0x06502583, 0xfc89144d, 0x015ab0db, 0xffab57a1, 0x00078c04,
+ 0x6ad0b652, 0x0380521c, 0xf824e480, 0x06337e2a, 0xfc8fdc9f, 0x015b1b4e, 0xffaa1e02, 0x00080dab,
+ 0x6a86de48, 0x02c86715, 0xf8728bb3, 0x061668d2, 0xfc96fbfc, 0x015b579e, 0xffa8f641, 0x00088a62,
+ 0x6a38f123, 0x0213090c, 0xf8c038d0, 0x05f8ea30, 0xfc9e7074, 0x015b666c, 0xffa7e039, 0x00090230,
+ 0x69e6f4b1, 0x01603f6e, 0xf90de2d1, 0x05db06fc, 0xfca63810, 0x015b485b, 0xffa6dbc0, 0x0009751e,
+ 0x6990ef0b, 0x00b01162, 0xf95b80cb, 0x05bcc3ed, 0xfcae50d6, 0x015afe14, 0xffa5e8ad, 0x0009e337,
+ 0x6936e697, 0x000285d0, 0xf9a909ea, 0x059e25b5, 0xfcb6b8c4, 0x015a8843, 0xffa506d2, 0x000a4c85,
+ 0x68d8e206, 0xff57a35e, 0xf9f67577, 0x057f310a, 0xfcbf6dd8, 0x0159e796, 0xffa43603, 0x000ab112,
+ 0x6876e855, 0xfeaf706f, 0xfa43bad2, 0x055fea9d, 0xfcc86e09, 0x01591cc0, 0xffa3760e, 0x000b10ec,
+ 0x681100c9, 0xfe09f323, 0xfa90d17b, 0x0540571a, 0xfcd1b74c, 0x01582878, 0xffa2c6c2, 0x000b6c1d,
+ 0x67a732f4, 0xfd673159, 0xfaddb10c, 0x05207b2f, 0xfcdb4793, 0x01570b77, 0xffa227ec, 0x000bc2b3,
+ 0x673986ac, 0xfcc730aa, 0xfb2a513b, 0x05005b82, 0xfce51ccb, 0x0155c678, 0xffa19957, 0x000c14bb,
+ 0x66c80413, 0xfc29f670, 0xfb76a9dd, 0x04dffcb6, 0xfcef34e1, 0x01545a3c, 0xffa11acb, 0x000c6244,
+ 0x6652b392, 0xfb8f87bd, 0xfbc2b2e4, 0x04bf6369, 0xfcf98dbe, 0x0152c783, 0xffa0ac11, 0x000cab5c,
+ 0x65d99dd5, 0xfaf7e963, 0xfc0e6461, 0x049e9433, 0xfd04254a, 0x01510f13, 0xffa04cf0, 0x000cf012,
+ 0x655ccbd3, 0xfa631fef, 0xfc59b685, 0x047d93a8, 0xfd0ef969, 0x014f31b2, 0xff9ffd2c, 0x000d3075,
+ 0x64dc46c3, 0xf9d12fab, 0xfca4a19f, 0x045c6654, 0xfd1a0801, 0x014d3029, 0xff9fbc89, 0x000d6c97,
+ 0x64581823, 0xf9421c9d, 0xfcef1e20, 0x043b10bd, 0xfd254ef4, 0x014b0b45, 0xff9f8ac9, 0x000da486,
+ 0x63d049b4, 0xf8b5ea87, 0xfd392498, 0x04199760, 0xfd30cc24, 0x0148c3d2, 0xff9f67ae, 0x000dd854,
+ 0x6344e578, 0xf82c9ce7, 0xfd82adba, 0x03f7feb4, 0xfd3c7d73, 0x01465a9f, 0xff9f52f7, 0x000e0812,
+ 0x62b5f5b2, 0xf7a636fa, 0xfdcbb25a, 0x03d64b27, 0xfd4860c2, 0x0143d07f, 0xff9f4c65, 0x000e33d3,
+ 0x622384e8, 0xf722bbb5, 0xfe142b6e, 0x03b4811d, 0xfd5473f3, 0x01412643, 0xff9f53b4, 0x000e5ba7,
+ 0x618d9ddc, 0xf6a22dcf, 0xfe5c120f, 0x0392a4f4, 0xfd60b4e7, 0x013e5cc0, 0xff9f68a1, 0x000e7fa1,
+ 0x60f44b91, 0xf6248fb6, 0xfea35f79, 0x0370bafc, 0xfd6d2180, 0x013b74ca, 0xff9f8ae9, 0x000e9fd5,
+ 0x60579947, 0xf5a9e398, 0xfeea0d0c, 0x034ec77f, 0xfd79b7a1, 0x01386f3a, 0xff9fba47, 0x000ebc54,
+ 0x5fb79278, 0xf5322b61, 0xff30144a, 0x032ccebb, 0xfd86752e, 0x01354ce7, 0xff9ff674, 0x000ed533,
+ 0x5f1442dc, 0xf4bd68b6, 0xff756edc, 0x030ad4e1, 0xfd93580d, 0x01320ea9, 0xffa03f2b, 0x000eea84,
+ 0x5e6db665, 0xf44b9cfe, 0xffba168d, 0x02e8de19, 0xfda05e23, 0x012eb55a, 0xffa09425, 0x000efc5c,
+ 0x5dc3f93c, 0xf3dcc959, 0xfffe054e, 0x02c6ee7f, 0xfdad855b, 0x012b41d3, 0xffa0f519, 0x000f0ace,
+ 0x5d1717c4, 0xf370eea9, 0x00413536, 0x02a50a22, 0xfdbacb9e, 0x0127b4f1, 0xffa161bf, 0x000f15ef,
+ 0x5c671e96, 0xf3080d8c, 0x0083a081, 0x02833506, 0xfdc82edb, 0x01240f8e, 0xffa1d9cf, 0x000f1dd2,
+ 0x5bb41a80, 0xf2a2265e, 0x00c54190, 0x02617321, 0xfdd5ad01, 0x01205285, 0xffa25cfe, 0x000f228d,
+ 0x5afe1886, 0xf23f393b, 0x010612eb, 0x023fc85c, 0xfde34403, 0x011c7eb2, 0xffa2eb04, 0x000f2434,
+ 0x5a4525df, 0xf1df45fd, 0x01460f41, 0x021e3891, 0xfdf0f1d6, 0x011894f0, 0xffa38395, 0x000f22dc,
+ 0x59894ff3, 0xf1824c3e, 0x01853165, 0x01fcc78f, 0xfdfeb475, 0x0114961b, 0xffa42668, 0x000f1e99,
+ 0x58caa45b, 0xf1284b58, 0x01c37452, 0x01db7914, 0xfe0c89db, 0x0110830f, 0xffa4d332, 0x000f1781,
+ 0x580930e1, 0xf0d14267, 0x0200d32c, 0x01ba50d2, 0xfe1a7009, 0x010c5ca6, 0xffa589a6, 0x000f0da8,
+ 0x5745037c, 0xf07d3043, 0x023d493c, 0x0199526b, 0xfe286505, 0x010823ba, 0xffa6497c, 0x000f0125,
+ 0x567e2a51, 0xf02c138a, 0x0278d1f2, 0x01788170, 0xfe3666d5, 0x0103d927, 0xffa71266, 0x000ef20b,
+ 0x55b4b3af, 0xefddea9a, 0x02b368e6, 0x0157e166, 0xfe447389, 0x00ff7dc4, 0xffa7e41a, 0x000ee070,
+ 0x54e8ae13, 0xef92b393, 0x02ed09d7, 0x013775bf, 0xfe528931, 0x00fb126b, 0xffa8be4c, 0x000ecc69,
+ 0x541a281e, 0xef4a6c58, 0x0325b0ad, 0x011741df, 0xfe60a5e5, 0x00f697f3, 0xffa9a0b1, 0x000eb60b,
+ 0x5349309e, 0xef051290, 0x035d5977, 0x00f7491a, 0xfe6ec7c0, 0x00f20f32, 0xffaa8afe, 0x000e9d6b,
+ 0x5275d684, 0xeec2a3a3, 0x0394006a, 0x00d78eb3, 0xfe7cece2, 0x00ed78ff, 0xffab7ce7, 0x000e829e,
+ 0x51a028e8, 0xee831cc3, 0x03c9a1e5, 0x00b815da, 0xfe8b1373, 0x00e8d62d, 0xffac7621, 0x000e65ba,
+ 0x50c83704, 0xee467ae1, 0x03fe3a6f, 0x0098e1b3, 0xfe99399f, 0x00e4278f, 0xffad7662, 0x000e46d3,
+ 0x4fee1037, 0xee0cbab9, 0x0431c6b5, 0x0079f54c, 0xfea75d97, 0x00df6df7, 0xffae7d5f, 0x000e25fd,
+ 0x4f11c3fe, 0xedd5d8ca, 0x0464438c, 0x005b53a4, 0xfeb57d92, 0x00daaa34, 0xffaf8acd, 0x000e034f,
+ 0x4e3361f7, 0xeda1d15c, 0x0495adf2, 0x003cffa9, 0xfec397cf, 0x00d5dd16, 0xffb09e63, 0x000ddedb,
+ 0x4d52f9df, 0xed70a07d, 0x04c6030d, 0x001efc35, 0xfed1aa92, 0x00d10769, 0xffb1b7d8, 0x000db8b7,
+ 0x4c709b8e, 0xed424205, 0x04f54029, 0x00014c12, 0xfedfb425, 0x00cc29f7, 0xffb2d6e1, 0x000d90f6,
+ 0x4b8c56f8, 0xed16b196, 0x052362ba, 0xffe3f1f7, 0xfeedb2da, 0x00c7458a, 0xffb3fb37, 0x000d67ae,
+ 0x4aa63c2c, 0xecedea99, 0x0550685d, 0xffc6f08a, 0xfefba508, 0x00c25ae8, 0xffb52490, 0x000d3cf1,
+ 0x49be5b50, 0xecc7e845, 0x057c4ed4, 0xffaa4a5d, 0xff09890f, 0x00bd6ad7, 0xffb652a7, 0x000d10d5,
+ 0x48d4c4a2, 0xeca4a59b, 0x05a7140b, 0xff8e01f1, 0xff175d53, 0x00b87619, 0xffb78533, 0x000ce36b,
+ 0x47e98874, 0xec841d68, 0x05d0b612, 0xff7219b3, 0xff252042, 0x00b37d70, 0xffb8bbed, 0x000cb4c8,
+ 0x46fcb72d, 0xec664a48, 0x05f93324, 0xff5693fe, 0xff32d04f, 0x00ae8198, 0xffb9f691, 0x000c84ff,
+ 0x460e6148, 0xec4b26a2, 0x0620899e, 0xff3b731b, 0xff406bf8, 0x00a9834e, 0xffbb34d8, 0x000c5422,
+ 0x451e9750, 0xec32acb0, 0x0646b808, 0xff20b93e, 0xff4df1be, 0x00a4834c, 0xffbc767f, 0x000c2245,
+ 0x442d69de, 0xec1cd677, 0x066bbd0d, 0xff066889, 0xff5b602c, 0x009f8249, 0xffbdbb42, 0x000bef79,
+ 0x433ae99c, 0xec099dcf, 0x068f9781, 0xfeec830d, 0xff68b5d5, 0x009a80f8, 0xffbf02dd, 0x000bbbd2,
+ 0x4247273f, 0xebf8fc64, 0x06b2465b, 0xfed30ac5, 0xff75f153, 0x0095800c, 0xffc04d0f, 0x000b8760,
+ 0x41523389, 0xebeaebaf, 0x06d3c8bb, 0xfeba0199, 0xff831148, 0x00908034, 0xffc19996, 0x000b5235,
+ 0x405c1f43, 0xebdf6500, 0x06f41de3, 0xfea16960, 0xff90145e, 0x008b821b, 0xffc2e832, 0x000b1c64,
+ 0x3f64fb40, 0xebd6617b, 0x0713453d, 0xfe8943dc, 0xff9cf947, 0x0086866b, 0xffc438a3, 0x000ae5fc,
+ 0x3e6cd85b, 0xebcfda19, 0x07313e56, 0xfe7192bd, 0xffa9bebe, 0x00818dcb, 0xffc58aaa, 0x000aaf0f,
+ 0x3d73c772, 0xebcbc7a7, 0x074e08e0, 0xfe5a579d, 0xffb66386, 0x007c98de, 0xffc6de09, 0x000a77ac,
+ 0x3c79d968, 0xebca22cc, 0x0769a4b2, 0xfe439407, 0xffc2e669, 0x0077a845, 0xffc83285, 0x000a3fe5,
+ 0x3b7f1f23, 0xebcae405, 0x078411c7, 0xfe2d496f, 0xffcf463a, 0x0072bc9d, 0xffc987e0, 0x000a07c9,
+ 0x3a83a989, 0xebce03aa, 0x079d503b, 0xfe177937, 0xffdb81d6, 0x006dd680, 0xffcadde1, 0x0009cf67,
+ 0x3987897f, 0xebd379eb, 0x07b56051, 0xfe0224b0, 0xffe79820, 0x0068f687, 0xffcc344c, 0x000996ce,
+ 0x388acfe9, 0xebdb3ed5, 0x07cc426c, 0xfded4d13, 0xfff38806, 0x00641d44, 0xffcd8aeb, 0x00095e0e,
+ 0x378d8da8, 0xebe54a4f, 0x07e1f712, 0xfdd8f38b, 0xffff507b, 0x005f4b4a, 0xffcee183, 0x00092535,
+ 0x368fd397, 0xebf1941f, 0x07f67eec, 0xfdc5192d, 0x000af07f, 0x005a8125, 0xffd037e0, 0x0008ec50,
+ 0x3591b28b, 0xec0013e8, 0x0809dac3, 0xfdb1befc, 0x00166718, 0x0055bf60, 0xffd18dcc, 0x0008b36e,
+ 0x34933b50, 0xec10c12c, 0x081c0b84, 0xfd9ee5e7, 0x0021b355, 0x00510682, 0xffd2e311, 0x00087a9c,
+ 0x33947eab, 0xec23934f, 0x082d1239, 0xfd8c8ecc, 0x002cd44d, 0x004c570f, 0xffd4377d, 0x000841e8,
+ 0x32958d55, 0xec388194, 0x083cf010, 0xfd7aba74, 0x0037c922, 0x0047b186, 0xffd58ade, 0x0008095d,
+ 0x319677fa, 0xec4f8322, 0x084ba654, 0xfd696998, 0x004290fc, 0x00431666, 0xffd6dd02, 0x0007d108,
+ 0x30974f3b, 0xec688f02, 0x08593671, 0xfd589cdc, 0x004d2b0e, 0x003e8628, 0xffd82dba, 0x000798f5,
+ 0x2f9823a8, 0xec839c22, 0x0865a1f1, 0xfd4854d3, 0x00579691, 0x003a0141, 0xffd97cd6, 0x00076130,
+ 0x2e9905c1, 0xeca0a156, 0x0870ea7e, 0xfd3891fd, 0x0061d2ca, 0x00358824, 0xffdaca2a, 0x000729c4,
+ 0x2d9a05f4, 0xecbf9558, 0x087b11de, 0xfd2954c8, 0x006bdf05, 0x00311b41, 0xffdc1588, 0x0006f2bb,
+ 0x2c9b349e, 0xece06ecb, 0x088419f6, 0xfd1a9d91, 0x0075ba95, 0x002cbb03, 0xffdd5ec6, 0x0006bc21,
+ 0x2b9ca203, 0xed032439, 0x088c04c8, 0xfd0c6ca2, 0x007f64da, 0x002867d2, 0xffdea5bb, 0x000685ff,
+ 0x2a9e5e57, 0xed27ac16, 0x0892d470, 0xfcfec233, 0x0088dd38, 0x00242213, 0xffdfea3c, 0x0006505f,
+ 0x29a079b2, 0xed4dfcc2, 0x08988b2a, 0xfcf19e6b, 0x0092231e, 0x001fea27, 0xffe12c22, 0x00061b4b,
+ 0x28a30416, 0xed760c88, 0x089d2b4a, 0xfce50161, 0x009b3605, 0x001bc06b, 0xffe26b48, 0x0005e6cb,
+ 0x27a60d6a, 0xed9fd1a2, 0x08a0b740, 0xfcd8eb17, 0x00a4156b, 0x0017a53b, 0xffe3a788, 0x0005b2e8,
+ 0x26a9a57b, 0xedcb4237, 0x08a33196, 0xfccd5b82, 0x00acc0da, 0x001398ec, 0xffe4e0bf, 0x00057faa,
+ 0x25addbf9, 0xedf8545b, 0x08a49cf0, 0xfcc25285, 0x00b537e1, 0x000f9bd2, 0xffe616c8, 0x00054d1a,
+ 0x24b2c075, 0xee26fe17, 0x08a4fc0d, 0xfcb7cff0, 0x00bd7a1c, 0x000bae3c, 0xffe74984, 0x00051b3e,
+ 0x23b86263, 0xee573562, 0x08a451c0, 0xfcadd386, 0x00c5872a, 0x0007d075, 0xffe878d3, 0x0004ea1d,
+ 0x22bed116, 0xee88f026, 0x08a2a0f8, 0xfca45cf7, 0x00cd5eb7, 0x000402c8, 0xffe9a494, 0x0004b9c0,
+ 0x21c61bc0, 0xeebc2444, 0x089fecbb, 0xfc9b6be5, 0x00d50075, 0x00004579, 0xffeaccaa, 0x00048a2b,
+ 0x20ce516f, 0xeef0c78d, 0x089c3824, 0xfc92ffe1, 0x00dc6c1e, 0xfffc98c9, 0xffebf0fa, 0x00045b65,
+ 0x1fd7810f, 0xef26cfca, 0x08978666, 0xfc8b186d, 0x00e3a175, 0xfff8fcf7, 0xffed1166, 0x00042d74,
+ 0x1ee1b965, 0xef5e32bd, 0x0891dac8, 0xfc83b4fc, 0x00eaa045, 0xfff5723d, 0xffee2dd7, 0x0004005e,
+ 0x1ded0911, 0xef96e61c, 0x088b38a9, 0xfc7cd4f0, 0x00f16861, 0xfff1f8d2, 0xffef4632, 0x0003d426,
+ 0x1cf97e8b, 0xefd0df9a, 0x0883a378, 0xfc76779e, 0x00f7f9a3, 0xffee90eb, 0xfff05a60, 0x0003a8d2,
+ 0x1c072823, 0xf00c14e1, 0x087b1ebc, 0xfc709c4d, 0x00fe53ef, 0xffeb3ab8, 0xfff16a4a, 0x00037e65,
+ 0x1b1613ff, 0xf0487b98, 0x0871ae0d, 0xfc6b4233, 0x0104772e, 0xffe7f666, 0xfff275db, 0x000354e5,
+ 0x1a26501b, 0xf0860962, 0x08675516, 0xfc66687a, 0x010a6353, 0xffe4c41e, 0xfff37d00, 0x00032c54,
+ 0x1937ea47, 0xf0c4b3e0, 0x085c1794, 0xfc620e3d, 0x01101858, 0xffe1a408, 0xfff47fa5, 0x000304b7,
+ 0x184af025, 0xf10470b0, 0x084ff957, 0xfc5e328c, 0x0115963d, 0xffde9646, 0xfff57db8, 0x0002de0e,
+ 0x175f6f2b, 0xf1453571, 0x0842fe3d, 0xfc5ad465, 0x011add0b, 0xffdb9af8, 0xfff67729, 0x0002b85f,
+ 0x1675749e, 0xf186f7c0, 0x08352a35, 0xfc57f2be, 0x011fecd3, 0xffd8b23b, 0xfff76be9, 0x000293aa,
+ 0x158d0d95, 0xf1c9ad40, 0x0826813e, 0xfc558c7c, 0x0124c5ab, 0xffd5dc28, 0xfff85be8, 0x00026ff2,
+ 0x14a646f6, 0xf20d4b92, 0x08170767, 0xfc53a07b, 0x012967b1, 0xffd318d6, 0xfff9471b, 0x00024d39,
+ 0x13c12d73, 0xf251c85d, 0x0806c0cb, 0xfc522d88, 0x012dd30a, 0xffd06858, 0xfffa2d74, 0x00022b7f,
+ 0x12ddcd8f, 0xf297194d, 0x07f5b193, 0xfc513266, 0x013207e4, 0xffcdcabe, 0xfffb0ee9, 0x00020ac7,
+ 0x11fc3395, 0xf2dd3411, 0x07e3ddf7, 0xfc50adcc, 0x01360670, 0xffcb4014, 0xfffbeb70, 0x0001eb10,
+ 0x111c6ba0, 0xf3240e61, 0x07d14a38, 0xfc509e64, 0x0139cee9, 0xffc8c866, 0xfffcc300, 0x0001cc5c,
};
/*
- * These coefficients are optimized for 48KHz -> 44.1KHz (stop-band at 22.050KHz)
- * It's possible to use the above coefficient for any down-sampling
- * at the expense of a slower processing loop (we can interpolate
- * these coefficient from the above by "Stretching" them in time).
+ * These coefficients are optimized for 48KHz -> 44.1KHz
+ * cmd-line: fir -l 7 -s 48000 -c 17189
*/
-const int32_t AudioResamplerSinc::mFirCoefsDown[] = {
- 0x7fffffff, 0x7f55e46d, 0x7d5b4c60, 0x7a1b4b98, 0x75a7fb14, 0x7019f0bd, 0x698f875a, 0x622bfd59, 0x5a167256, 0x5178cc54, 0x487e8e6c, 0x3f53aae8, 0x36235ad4, 0x2d17047b, 0x245539ab, 0x1c00d540,
- 0x14383e57, 0x0d14d5ca, 0x06aa910b, 0x0107c38b, 0xfc351654, 0xf835abae, 0xf5076b45, 0xf2a37202, 0xf0fe9faa, 0xf00a3bbd, 0xefb4aa81, 0xefea2b05, 0xf0959716, 0xf1a11e83, 0xf2f6f7a0, 0xf481fff4,
- 0xf62e48ce, 0xf7e98ca5, 0xf9a38b4c, 0xfb4e4bfa, 0xfcde456f, 0xfe4a6d30, 0xff8c2fdf, 0x009f5555, 0x0181d393, 0x0233940f, 0x02b62f06, 0x030ca07d, 0x033afa62, 0x03461725, 0x03334f83, 0x030835fa,
- 0x02ca59cc, 0x027f12d1, 0x022b570d, 0x01d39a49, 0x017bb78f, 0x0126e414, 0x00d7aaaf, 0x008feec7, 0x0050f584, 0x001b73e3, 0xffefa063, 0xffcd46ed, 0xffb3ddcd, 0xffa29aaa, 0xff988691, 0xff949066,
- 0xff959d24, 0xff9a959e, 0xffa27195, 0xffac4011, 0xffb72d2b, 0xffc28569, 0xffcdb706, 0xffd85171, 0xffe20364, 0xffea97e9, 0xfff1f2b2, 0xfff80c06, 0xfffcec92, 0x0000a955, 0x00035fd8, 0x000532cf,
- 0x00064735, 0x0006c1f9, 0x0006c62d, 0x000673ba, 0x0005e68f, 0x00053630, 0x000475a3, 0x0003b397, 0x0002fac1, 0x00025257, 0x0001be9e, 0x0001417a, 0x0000dafd, 0x000089eb, 0x00004c28, 0x00001f1d,
- 0x00000000, 0xffffec10, 0xffffe0be, 0xffffdbc5, 0xffffdb39, 0xffffdd8b, 0xffffe182, 0xffffe638, 0xffffeb0a, 0xffffef8f, 0xfffff38b, 0xfffff6e3, 0xfffff993, 0xfffffba6, 0xfffffd30, 0xfffffe4a,
- 0xffffff09, 0xffffff85, 0xffffffd1, 0xfffffffb, 0x0000000f, 0x00000016, 0x00000015, 0x00000012, 0x0000000d, 0x00000009, 0x00000006, 0x00000003, 0x00000002, 0x00000001, 0x00000000, 0x00000000,
- 0x00000000 // this one is needed for lerping the last coefficient
+const int32_t AudioResamplerSinc::mFirCoefsDown[] __attribute__ ((aligned (32))) = {
+ 0x5bacb6f4, 0x1ded1a1d, 0xf0398d56, 0x0394f674, 0x0193a5f9, 0xfe66dbeb, 0x00791043, 0xfffe6631,
+ 0x5bab6c81, 0x1d3ddccd, 0xf0421d2c, 0x03af9995, 0x01818dc9, 0xfe6bb63e, 0x0079812a, 0xfffdc37d,
+ 0x5ba78d37, 0x1c8f2cf9, 0xf04beb1d, 0x03c9a04a, 0x016f8aca, 0xfe70a511, 0x0079e34d, 0xfffd2545,
+ 0x5ba1194f, 0x1be11231, 0xf056f2c7, 0x03e309fe, 0x015d9e64, 0xfe75a79f, 0x007a36e2, 0xfffc8b86,
+ 0x5b981122, 0x1b3393f8, 0xf0632fb7, 0x03fbd625, 0x014bc9fa, 0xfe7abd23, 0x007a7c20, 0xfffbf639,
+ 0x5b8c7530, 0x1a86b9bf, 0xf0709d74, 0x04140449, 0x013a0ee9, 0xfe7fe4db, 0x007ab33d, 0xfffb655b,
+ 0x5b7e461a, 0x19da8ae5, 0xf07f3776, 0x042b93fd, 0x01286e86, 0xfe851e05, 0x007adc72, 0xfffad8e4,
+ 0x5b6d84a8, 0x192f0eb7, 0xf08ef92d, 0x044284e6, 0x0116ea22, 0xfe8a67dd, 0x007af7f6, 0xfffa50ce,
+ 0x5b5a31c6, 0x18844c70, 0xf09fddfe, 0x0458d6b7, 0x01058306, 0xfe8fc1a5, 0x007b0603, 0xfff9cd12,
+ 0x5b444e81, 0x17da4b37, 0xf0b1e143, 0x046e8933, 0x00f43a74, 0xfe952a9b, 0x007b06d4, 0xfff94da9,
+ 0x5b2bdc0e, 0x17311222, 0xf0c4fe50, 0x04839c29, 0x00e311a9, 0xfe9aa201, 0x007afaa1, 0xfff8d28c,
+ 0x5b10dbc2, 0x1688a832, 0xf0d9306d, 0x04980f79, 0x00d209db, 0xfea02719, 0x007ae1a7, 0xfff85bb1,
+ 0x5af34f18, 0x15e11453, 0xf0ee72db, 0x04abe310, 0x00c12439, 0xfea5b926, 0x007abc20, 0xfff7e910,
+ 0x5ad337af, 0x153a5d5e, 0xf104c0d2, 0x04bf16e9, 0x00b061eb, 0xfeab576d, 0x007a8a49, 0xfff77a9f,
+ 0x5ab09748, 0x14948a16, 0xf11c1583, 0x04d1ab0d, 0x009fc413, 0xfeb10134, 0x007a4c5d, 0xfff71057,
+ 0x5a8b6fc7, 0x13efa12c, 0xf1346c17, 0x04e39f93, 0x008f4bcb, 0xfeb6b5c0, 0x007a029a, 0xfff6aa2b,
+ 0x5a63c336, 0x134ba937, 0xf14dbfb1, 0x04f4f4a2, 0x007efa29, 0xfebc745c, 0x0079ad3d, 0xfff64812,
+ 0x5a3993c0, 0x12a8a8bb, 0xf1680b6e, 0x0505aa6a, 0x006ed038, 0xfec23c50, 0x00794c82, 0xfff5ea02,
+ 0x5a0ce3b2, 0x1206a625, 0xf1834a63, 0x0515c12d, 0x005ecf01, 0xfec80ce8, 0x0078e0a9, 0xfff58ff0,
+ 0x59ddb57f, 0x1165a7cc, 0xf19f77a0, 0x05253938, 0x004ef782, 0xfecde571, 0x007869ee, 0xfff539cf,
+ 0x59ac0bba, 0x10c5b3ef, 0xf1bc8e31, 0x053412e4, 0x003f4ab4, 0xfed3c538, 0x0077e891, 0xfff4e794,
+ 0x5977e919, 0x1026d0b8, 0xf1da891b, 0x05424e9b, 0x002fc98a, 0xfed9ab8f, 0x00775ccf, 0xfff49934,
+ 0x59415075, 0x0f890437, 0xf1f96360, 0x054feccf, 0x002074ed, 0xfedf97c6, 0x0076c6e8, 0xfff44ea3,
+ 0x590844c9, 0x0eec5465, 0xf21917ff, 0x055cee03, 0x00114dc3, 0xfee58932, 0x00762719, 0xfff407d2,
+ 0x58ccc930, 0x0e50c723, 0xf239a1ef, 0x056952c3, 0x000254e8, 0xfeeb7f27, 0x00757da3, 0xfff3c4b7,
+ 0x588ee0ea, 0x0db6623b, 0xf25afc29, 0x05751baa, 0xfff38b32, 0xfef178fc, 0x0074cac4, 0xfff38542,
+ 0x584e8f56, 0x0d1d2b5d, 0xf27d219f, 0x0580495c, 0xffe4f171, 0xfef7760c, 0x00740ebb, 0xfff34968,
+ 0x580bd7f4, 0x0c85281f, 0xf2a00d43, 0x058adc8d, 0xffd6886d, 0xfefd75af, 0x007349c7, 0xfff3111b,
+ 0x57c6be67, 0x0bee5dff, 0xf2c3ba04, 0x0594d5fa, 0xffc850e6, 0xff037744, 0x00727c27, 0xfff2dc4c,
+ 0x577f4670, 0x0b58d262, 0xf2e822ce, 0x059e366c, 0xffba4b98, 0xff097a29, 0x0071a61b, 0xfff2aaef,
+ 0x573573f2, 0x0ac48a92, 0xf30d428e, 0x05a6feb9, 0xffac7936, 0xff0f7dbf, 0x0070c7e1, 0xfff27cf3,
+ 0x56e94af1, 0x0a318bc1, 0xf333142f, 0x05af2fbf, 0xff9eda6d, 0xff15816a, 0x006fe1b8, 0xfff2524c,
+ 0x569acf90, 0x099fdb04, 0xf359929a, 0x05b6ca6b, 0xff916fe1, 0xff1b848e, 0x006ef3df, 0xfff22aea,
+ 0x564a0610, 0x090f7d57, 0xf380b8ba, 0x05bdcfb2, 0xff843a32, 0xff218692, 0x006dfe94, 0xfff206bf,
+ 0x55f6f2d3, 0x0880779d, 0xf3a88179, 0x05c44095, 0xff7739f7, 0xff2786e1, 0x006d0217, 0xfff1e5bb,
+ 0x55a19a5c, 0x07f2ce9b, 0xf3d0e7c2, 0x05ca1e1f, 0xff6a6fc1, 0xff2d84e5, 0x006bfea4, 0xfff1c7d0,
+ 0x554a0148, 0x076686fc, 0xf3f9e680, 0x05cf6965, 0xff5ddc1a, 0xff33800e, 0x006af47b, 0xfff1acef,
+ 0x54f02c56, 0x06dba551, 0xf42378a0, 0x05d42387, 0xff517f86, 0xff3977cb, 0x0069e3d9, 0xfff19508,
+ 0x54942061, 0x06522e0f, 0xf44d9912, 0x05d84daf, 0xff455a80, 0xff3f6b8f, 0x0068ccfa, 0xfff1800b,
+ 0x5435e263, 0x05ca258f, 0xf47842c5, 0x05dbe90f, 0xff396d7f, 0xff455acf, 0x0067b01e, 0xfff16de9,
+ 0x53d57774, 0x0543900d, 0xf4a370ad, 0x05def6e4, 0xff2db8f2, 0xff4b4503, 0x00668d80, 0xfff15e93,
+ 0x5372e4c6, 0x04be71ab, 0xf4cf1dbf, 0x05e17873, 0xff223d40, 0xff5129a3, 0x0065655d, 0xfff151f9,
+ 0x530e2fac, 0x043ace6e, 0xf4fb44f4, 0x05e36f0d, 0xff16faca, 0xff57082e, 0x006437f1, 0xfff1480b,
+ 0x52a75d90, 0x03b8aa40, 0xf527e149, 0x05e4dc08, 0xff0bf1ed, 0xff5ce021, 0x00630577, 0xfff140b9,
+ 0x523e73fd, 0x033808eb, 0xf554edbd, 0x05e5c0c6, 0xff0122fc, 0xff62b0fd, 0x0061ce2c, 0xfff13bf3,
+ 0x51d37897, 0x02b8ee22, 0xf5826555, 0x05e61eae, 0xfef68e45, 0xff687a47, 0x00609249, 0xfff139aa,
+ 0x5166711c, 0x023b5d76, 0xf5b0431a, 0x05e5f733, 0xfeec340f, 0xff6e3b84, 0x005f520a, 0xfff139cd,
+ 0x50f76368, 0x01bf5a5e, 0xf5de8218, 0x05e54bcd, 0xfee2149b, 0xff73f43d, 0x005e0da8, 0xfff13c4c,
+ 0x5086556f, 0x0144e834, 0xf60d1d63, 0x05e41dfe, 0xfed83023, 0xff79a3fe, 0x005cc55c, 0xfff14119,
+ 0x50134d3e, 0x00cc0a36, 0xf63c1012, 0x05e26f4e, 0xfece86db, 0xff7f4a54, 0x005b7961, 0xfff14821,
+ 0x4f9e50ff, 0x0054c382, 0xf66b5544, 0x05e0414d, 0xfec518f1, 0xff84e6d0, 0x005a29ed, 0xfff15156,
+ 0x4f2766f2, 0xffdf171b, 0xf69ae81d, 0x05dd9593, 0xfebbe68c, 0xff8a7905, 0x0058d738, 0xfff15ca8,
+ 0x4eae9571, 0xff6b07e7, 0xf6cac3c7, 0x05da6dbe, 0xfeb2efcd, 0xff900089, 0x0057817b, 0xfff16a07,
+ 0x4e33e2ee, 0xfef898ae, 0xf6fae373, 0x05d6cb72, 0xfeaa34d0, 0xff957cf4, 0x005628ec, 0xfff17962,
+ 0x4db755f3, 0xfe87cc1b, 0xf72b425b, 0x05d2b05c, 0xfea1b5a9, 0xff9aede0, 0x0054cdc0, 0xfff18aab,
+ 0x4d38f520, 0xfe18a4bc, 0xf75bdbbd, 0x05ce1e2d, 0xfe997268, 0xffa052ec, 0x0053702d, 0xfff19dd1,
+ 0x4cb8c72e, 0xfdab2501, 0xf78caae0, 0x05c9169d, 0xfe916b15, 0xffa5abb8, 0x00521068, 0xfff1b2c5,
+ 0x4c36d2eb, 0xfd3f4f3d, 0xf7bdab16, 0x05c39b6a, 0xfe899fb2, 0xffaaf7e6, 0x0050aea5, 0xfff1c976,
+ 0x4bb31f3c, 0xfcd525a5, 0xf7eed7b4, 0x05bdae57, 0xfe82103f, 0xffb0371c, 0x004f4b17, 0xfff1e1d6,
+ 0x4b2db31a, 0xfc6caa53, 0xf8202c1c, 0x05b7512e, 0xfe7abcb1, 0xffb56902, 0x004de5f1, 0xfff1fbd5,
+ 0x4aa69594, 0xfc05df40, 0xf851a3b6, 0x05b085bc, 0xfe73a4fb, 0xffba8d44, 0x004c7f66, 0xfff21764,
+ 0x4a1dcdce, 0xfba0c64b, 0xf88339f5, 0x05a94dd5, 0xfe6cc909, 0xffbfa38d, 0x004b17a6, 0xfff23473,
+ 0x499362ff, 0xfb3d6133, 0xf8b4ea55, 0x05a1ab52, 0xfe6628c1, 0xffc4ab8f, 0x0049aee3, 0xfff252f3,
+ 0x49075c72, 0xfadbb19a, 0xf8e6b059, 0x0599a00e, 0xfe5fc405, 0xffc9a4fc, 0x0048454b, 0xfff272d6,
+ 0x4879c185, 0xfa7bb908, 0xf9188793, 0x05912dea, 0xfe599aaf, 0xffce8f8a, 0x0046db0f, 0xfff2940b,
+ 0x47ea99a9, 0xfa1d78e3, 0xf94a6b9b, 0x058856cd, 0xfe53ac97, 0xffd36af1, 0x0045705c, 0xfff2b686,
+ 0x4759ec60, 0xf9c0f276, 0xf97c5815, 0x057f1c9e, 0xfe4df98e, 0xffd836eb, 0x00440561, 0xfff2da36,
+ 0x46c7c140, 0xf96626f0, 0xf9ae48af, 0x0575814c, 0xfe48815e, 0xffdcf336, 0x00429a4a, 0xfff2ff0d,
+ 0x46341fed, 0xf90d1761, 0xf9e03924, 0x056b86c6, 0xfe4343d0, 0xffe19f91, 0x00412f43, 0xfff324fd,
+ 0x459f101d, 0xf8b5c4be, 0xfa122537, 0x05612f00, 0xfe3e40a6, 0xffe63bc0, 0x003fc478, 0xfff34bf9,
+ 0x45089996, 0xf8602fdc, 0xfa4408ba, 0x05567bf1, 0xfe39779a, 0xffeac787, 0x003e5a12, 0xfff373f0,
+ 0x4470c42d, 0xf80c5977, 0xfa75df87, 0x054b6f92, 0xfe34e867, 0xffef42af, 0x003cf03d, 0xfff39cd7,
+ 0x43d797c7, 0xf7ba422b, 0xfaa7a586, 0x05400be1, 0xfe3092bf, 0xfff3ad01, 0x003b871f, 0xfff3c69f,
+ 0x433d1c56, 0xf769ea78, 0xfad956ab, 0x053452dc, 0xfe2c7650, 0xfff8064b, 0x003a1ee3, 0xfff3f13a,
+ 0x42a159dc, 0xf71b52c4, 0xfb0aeef6, 0x05284685, 0xfe2892c5, 0xfffc4e5c, 0x0038b7ae, 0xfff41c9c,
+ 0x42045865, 0xf6ce7b57, 0xfb3c6a73, 0x051be8dd, 0xfe24e7c3, 0x00008507, 0x003751a7, 0xfff448b7,
+ 0x4166200e, 0xf683645a, 0xfb6dc53c, 0x050f3bec, 0xfe2174ec, 0x0004aa1f, 0x0035ecf4, 0xfff4757e,
+ 0x40c6b8fd, 0xf63a0ddf, 0xfb9efb77, 0x050241b6, 0xfe1e39da, 0x0008bd7c, 0x003489b9, 0xfff4a2e5,
+ 0x40262b65, 0xf5f277d9, 0xfbd00956, 0x04f4fc46, 0xfe1b3628, 0x000cbef7, 0x0033281a, 0xfff4d0de,
+ 0x3f847f83, 0xf5aca21f, 0xfc00eb1b, 0x04e76da3, 0xfe18696a, 0x0010ae6e, 0x0031c83a, 0xfff4ff5d,
+ 0x3ee1bda2, 0xf5688c6d, 0xfc319d13, 0x04d997d8, 0xfe15d32f, 0x00148bbd, 0x00306a3b, 0xfff52e57,
+ 0x3e3dee13, 0xf5263665, 0xfc621b9a, 0x04cb7cf2, 0xfe137304, 0x001856c7, 0x002f0e3f, 0xfff55dbf,
+ 0x3d991932, 0xf4e59f8a, 0xfc926319, 0x04bd1efb, 0xfe114872, 0x001c0f6e, 0x002db466, 0xfff58d89,
+ 0x3cf34766, 0xf4a6c748, 0xfcc27008, 0x04ae8000, 0xfe0f52fc, 0x001fb599, 0x002c5cd0, 0xfff5bdaa,
+ 0x3c4c811c, 0xf469aced, 0xfcf23eec, 0x049fa20f, 0xfe0d9224, 0x0023492f, 0x002b079a, 0xfff5ee17,
+ 0x3ba4cec9, 0xf42e4faf, 0xfd21cc59, 0x04908733, 0xfe0c0567, 0x0026ca1c, 0x0029b4e4, 0xfff61ec5,
+ 0x3afc38eb, 0xf3f4aea6, 0xfd5114f0, 0x0481317a, 0xfe0aac3f, 0x002a384c, 0x002864c9, 0xfff64fa8,
+ 0x3a52c805, 0xf3bcc8d3, 0xfd801564, 0x0471a2ef, 0xfe098622, 0x002d93ae, 0x00271766, 0xfff680b5,
+ 0x39a884a1, 0xf3869d1a, 0xfdaeca73, 0x0461dda0, 0xfe089283, 0x0030dc34, 0x0025ccd7, 0xfff6b1e4,
+ 0x38fd774e, 0xf3522a49, 0xfddd30eb, 0x0451e396, 0xfe07d0d3, 0x003411d2, 0x00248535, 0xfff6e329,
+ 0x3851a8a2, 0xf31f6f0f, 0xfe0b45aa, 0x0441b6dd, 0xfe07407d, 0x0037347d, 0x0023409a, 0xfff7147a,
+ 0x37a52135, 0xf2ee6a07, 0xfe39059b, 0x0431597d, 0xfe06e0eb, 0x003a442e, 0x0021ff1f, 0xfff745cd,
+ 0x36f7e9a4, 0xf2bf19ae, 0xfe666dbc, 0x0420cd80, 0xfe06b184, 0x003d40e0, 0x0020c0dc, 0xfff7771a,
+ 0x364a0a90, 0xf2917c6d, 0xfe937b15, 0x041014eb, 0xfe06b1ac, 0x00402a8e, 0x001f85e6, 0xfff7a857,
+ 0x359b8c9d, 0xf265908f, 0xfec02ac2, 0x03ff31c3, 0xfe06e0c4, 0x00430137, 0x001e4e56, 0xfff7d97a,
+ 0x34ec786f, 0xf23b544b, 0xfeec79ec, 0x03ee260d, 0xfe073e2a, 0x0045c4dd, 0x001d1a3f, 0xfff80a7c,
+ 0x343cd6af, 0xf212c5be, 0xff1865cd, 0x03dcf3ca, 0xfe07c93a, 0x00487582, 0x001be9b7, 0xfff83b52,
+ 0x338cb004, 0xf1ebe2ec, 0xff43ebac, 0x03cb9cf9, 0xfe08814e, 0x004b132b, 0x001abcd0, 0xfff86bf6,
+ 0x32dc0d17, 0xf1c6a9c3, 0xff6f08e4, 0x03ba2398, 0xfe0965bc, 0x004d9dde, 0x0019939d, 0xfff89c60,
+ 0x322af693, 0xf1a3181a, 0xff99badb, 0x03a889a1, 0xfe0a75da, 0x005015a5, 0x00186e31, 0xfff8cc86,
+ 0x3179751f, 0xf1812bb0, 0xffc3ff0c, 0x0396d10c, 0xfe0bb0f9, 0x00527a8a, 0x00174c9c, 0xfff8fc62,
+ 0x30c79163, 0xf160e22d, 0xffedd2fd, 0x0384fbd1, 0xfe0d166b, 0x0054cc9a, 0x00162eef, 0xfff92bec,
+ 0x30155404, 0xf1423924, 0x00173447, 0x03730be0, 0xfe0ea57e, 0x00570be4, 0x00151538, 0xfff95b1e,
+ 0x2f62c5a7, 0xf1252e0f, 0x00402092, 0x0361032a, 0xfe105d7e, 0x00593877, 0x0013ff88, 0xfff989ef,
+ 0x2eafeeed, 0xf109be56, 0x00689598, 0x034ee39b, 0xfe123db6, 0x005b5267, 0x0012edea, 0xfff9b85b,
+ 0x2dfcd873, 0xf0efe748, 0x0090911f, 0x033caf1d, 0xfe144570, 0x005d59c6, 0x0011e06d, 0xfff9e65a,
+ 0x2d498ad3, 0xf0d7a622, 0x00b81102, 0x032a6796, 0xfe1673f2, 0x005f4eac, 0x0010d71d, 0xfffa13e5,
+ 0x2c960ea3, 0xf0c0f808, 0x00df1328, 0x03180ee7, 0xfe18c884, 0x0061312e, 0x000fd205, 0xfffa40f8,
+ 0x2be26c73, 0xf0abda0e, 0x0105958c, 0x0305a6f0, 0xfe1b4268, 0x00630167, 0x000ed130, 0xfffa6d8d,
+ 0x2b2eaccf, 0xf0984931, 0x012b9635, 0x02f3318a, 0xfe1de0e2, 0x0064bf71, 0x000dd4a7, 0xfffa999d,
+ 0x2a7ad83c, 0xf086425a, 0x0151133e, 0x02e0b08d, 0xfe20a335, 0x00666b68, 0x000cdc74, 0xfffac525,
+ 0x29c6f738, 0xf075c260, 0x01760ad1, 0x02ce25ca, 0xfe2388a1, 0x0068056b, 0x000be89f, 0xfffaf01e,
+ 0x2913123c, 0xf066c606, 0x019a7b27, 0x02bb9310, 0xfe269065, 0x00698d98, 0x000af931, 0xfffb1a84,
+ 0x285f31b7, 0xf05949fb, 0x01be628c, 0x02a8fa2a, 0xfe29b9c1, 0x006b0411, 0x000a0e2f, 0xfffb4453,
+ 0x27ab5e12, 0xf04d4ade, 0x01e1bf58, 0x02965cdb, 0xfe2d03f2, 0x006c68f8, 0x000927a0, 0xfffb6d86,
+ 0x26f79fab, 0xf042c539, 0x02048ff8, 0x0283bce6, 0xfe306e35, 0x006dbc71, 0x00084589, 0xfffb961a,
+ 0x2643feda, 0xf039b587, 0x0226d2e6, 0x02711c05, 0xfe33f7c7, 0x006efea0, 0x000767f0, 0xfffbbe09,
+ 0x259083eb, 0xf032182f, 0x024886ad, 0x025e7bf0, 0xfe379fe3, 0x00702fae, 0x00068ed8, 0xfffbe552,
+ 0x24dd3721, 0xf02be98a, 0x0269a9e9, 0x024bde5a, 0xfe3b65c4, 0x00714fc0, 0x0005ba46, 0xfffc0bef,
+ 0x242a20b3, 0xf02725dc, 0x028a3b44, 0x023944ee, 0xfe3f48a5, 0x00725f02, 0x0004ea3a, 0xfffc31df,
+ 0x237748cf, 0xf023c95d, 0x02aa397b, 0x0226b156, 0xfe4347c0, 0x00735d9c, 0x00041eb9, 0xfffc571e,
+ 0x22c4b795, 0xf021d031, 0x02c9a359, 0x02142533, 0xfe476250, 0x00744bba, 0x000357c2, 0xfffc7ba9,
+ 0x2212751a, 0xf0213671, 0x02e877b9, 0x0201a223, 0xfe4b978e, 0x0075298a, 0x00029558, 0xfffc9f7e,
+ 0x21608968, 0xf021f823, 0x0306b586, 0x01ef29be, 0xfe4fe6b3, 0x0075f739, 0x0001d779, 0xfffcc29a,
+ 0x20aefc79, 0xf0241140, 0x03245bbc, 0x01dcbd96, 0xfe544efb, 0x0076b4f5, 0x00011e26, 0xfffce4fc,
+ 0x1ffdd63b, 0xf0277db1, 0x03416966, 0x01ca5f37, 0xfe58cf9d, 0x007762f0, 0x0000695e, 0xfffd06a1,
+ 0x1f4d1e8e, 0xf02c3953, 0x035ddd9e, 0x01b81028, 0xfe5d67d4, 0x0078015a, 0xffffb91f, 0xfffd2787,
+ 0x1e9cdd43, 0xf0323ff5, 0x0379b790, 0x01a5d1ea, 0xfe6216db, 0x00789065, 0xffff0d66, 0xfffd47ae,
+ 0x1ded1a1d, 0xf0398d56, 0x0394f674, 0x0193a5f9, 0xfe66dbeb, 0x00791043, 0xfffe6631, 0xfffd6713,
};
// we use 15 bits to interpolate between these samples
@@ -96,12 +353,16 @@ void AudioResamplerSinc::init_routine()
return;
}
- readResampleCoefficients = (readCoefficientsFn) dlsym(resampleCoeffLib,
- "readResamplerCoefficients");
- readResampleFirNumCoeffFn readResampleFirNumCoeff = (readResampleFirNumCoeffFn)
+ readResampleFirNumCoeffFn readResampleFirNumCoeff;
+ readResampleFirLerpIntBitsFn readResampleFirLerpIntBits;
+
+ readResampleCoefficients = (readCoefficientsFn)
+ dlsym(resampleCoeffLib, "readResamplerCoefficients");
+ readResampleFirNumCoeff = (readResampleFirNumCoeffFn)
dlsym(resampleCoeffLib, "readResampleFirNumCoeff");
- readResampleFirLerpIntBitsFn readResampleFirLerpIntBits = (readResampleFirLerpIntBitsFn)
+ readResampleFirLerpIntBits = (readResampleFirLerpIntBitsFn)
dlsym(resampleCoeffLib, "readResampleFirLerpIntBits");
+
if (!readResampleCoefficients || !readResampleFirNumCoeff || !readResampleFirLerpIntBits) {
readResampleCoefficients = NULL;
dlclose(resampleCoeffLib);
@@ -111,15 +372,14 @@ void AudioResamplerSinc::init_routine()
}
c = &veryHighQualityConstants;
- // we have 16 coefs samples per zero-crossing
c->coefsBits = readResampleFirLerpIntBits();
- ALOGV("coefsBits = %d", c->coefsBits);
c->cShift = kNumPhaseBits - c->coefsBits;
c->cMask = ((1<<c->coefsBits)-1) << c->cShift;
c->pShift = kNumPhaseBits - c->coefsBits - pLerpBits;
c->pMask = ((1<<pLerpBits)-1) << c->pShift;
// number of zero-crossing on each side
c->halfNumCoefs = readResampleFirNumCoeff();
+ ALOGV("coefsBits = %d", c->coefsBits);
ALOGV("halfNumCoefs = %d", c->halfNumCoefs);
// note that we "leak" resampleCoeffLib until the process exits
}
@@ -129,7 +389,7 @@ void AudioResamplerSinc::init_routine()
static inline
int32_t mulRL(int left, int32_t in, uint32_t vRL)
{
-#if defined(__arm__) && !defined(__thumb__)
+#if USE_INLINE_ASSEMBLY
int32_t out;
if (left) {
asm( "smultb %[out], %[in], %[vRL] \n"
@@ -144,18 +404,15 @@ int32_t mulRL(int left, int32_t in, uint32_t vRL)
}
return out;
#else
- if (left) {
- return int16_t(in>>16) * int16_t(vRL&0xFFFF);
- } else {
- return int16_t(in>>16) * int16_t(vRL>>16);
- }
+ int16_t v = left ? int16_t(vRL) : int16_t(vRL>>16);
+ return int32_t((int64_t(in) * v) >> 16);
#endif
}
static inline
int32_t mulAdd(int16_t in, int32_t v, int32_t a)
{
-#if defined(__arm__) && !defined(__thumb__)
+#if USE_INLINE_ASSEMBLY
int32_t out;
asm( "smlawb %[out], %[v], %[in], %[a] \n"
: [out]"=r"(out)
@@ -163,16 +420,14 @@ int32_t mulAdd(int16_t in, int32_t v, int32_t a)
: );
return out;
#else
- return a + in * (v>>16);
- // improved precision
- // return a + in * (v>>16) + ((in * (v & 0xffff)) >> 16);
+ return a + int32_t((int64_t(v) * in) >> 16);
#endif
}
static inline
int32_t mulAddRL(int left, uint32_t inRL, int32_t v, int32_t a)
{
-#if defined(__arm__) && !defined(__thumb__)
+#if USE_INLINE_ASSEMBLY
int32_t out;
if (left) {
asm( "smlawb %[out], %[v], %[inRL], %[a] \n"
@@ -187,13 +442,8 @@ int32_t mulAddRL(int left, uint32_t inRL, int32_t v, int32_t a)
}
return out;
#else
- if (left) {
- return a + (int16_t(inRL&0xFFFF) * (v>>16));
- //improved precision
- // return a + (int16_t(inRL&0xFFFF) * (v>>16)) + ((int16_t(inRL&0xFFFF) * (v & 0xffff)) >> 16);
- } else {
- return a + (int16_t(inRL>>16) * (v>>16));
- }
+ int16_t s = left ? int16_t(inRL) : int16_t(inRL>>16);
+ return a + int32_t((int64_t(v) * s) >> 16);
#endif
}
@@ -202,7 +452,7 @@ int32_t mulAddRL(int left, uint32_t inRL, int32_t v, int32_t a)
AudioResamplerSinc::AudioResamplerSinc(int bitDepth,
int inChannelCount, int32_t sampleRate, src_quality quality)
: AudioResampler(bitDepth, inChannelCount, sampleRate, quality),
- mState(0)
+ mState(0), mImpulse(0), mRingFull(0), mFirCoefs(0)
{
/*
* Layout of the state buffer for 32 tap:
@@ -220,44 +470,48 @@ AudioResamplerSinc::AudioResamplerSinc(int bitDepth,
*
*/
+ mVolumeSIMD[0] = 0;
+ mVolumeSIMD[1] = 0;
+
// Load the constants for coefficients
int ok = pthread_once(&once_control, init_routine);
if (ok != 0) {
ALOGE("%s pthread_once failed: %d", __func__, ok);
}
- mConstants = (quality == VERY_HIGH_QUALITY) ? &veryHighQualityConstants : &highQualityConstants;
+ mConstants = (quality == VERY_HIGH_QUALITY) ?
+ &veryHighQualityConstants : &highQualityConstants;
}
-AudioResamplerSinc::~AudioResamplerSinc()
-{
- delete[] mState;
+AudioResamplerSinc::~AudioResamplerSinc() {
+ free(mState);
}
void AudioResamplerSinc::init() {
- const Constants *c = mConstants;
-
- const size_t numCoefs = 2*c->halfNumCoefs;
+ const Constants& c(*mConstants);
+ const size_t numCoefs = 2 * c.halfNumCoefs;
const size_t stateSize = numCoefs * mChannelCount * 2;
- mState = new int16_t[stateSize];
+ mState = (int16_t*)memalign(32, stateSize*sizeof(int16_t));
memset(mState, 0, sizeof(int16_t)*stateSize);
- mImpulse = mState + (c->halfNumCoefs-1)*mChannelCount;
+ mImpulse = mState + (c.halfNumCoefs-1)*mChannelCount;
mRingFull = mImpulse + (numCoefs+1)*mChannelCount;
}
+void AudioResamplerSinc::setVolume(int16_t left, int16_t right) {
+ AudioResampler::setVolume(left, right);
+ mVolumeSIMD[0] = int32_t(left)<<16;
+ mVolumeSIMD[1] = int32_t(right)<<16;
+}
+
void AudioResamplerSinc::resample(int32_t* out, size_t outFrameCount,
AudioBufferProvider* provider)
{
-
// FIXME store current state (up or down sample) and only load the coefs when the state
// changes. Or load two pointers one for up and one for down in the init function.
// Not critical now since the read functions are fast, but would be important if read was slow.
if (mConstants == &veryHighQualityConstants && readResampleCoefficients) {
- ALOGV("get coefficient from libmm-audio resampler library");
- mFirCoefs = (mInSampleRate <= mSampleRate) ? readResampleCoefficients(true) :
- readResampleCoefficients(false);
+ mFirCoefs = readResampleCoefficients( mInSampleRate <= mSampleRate );
} else {
- ALOGV("Use default coefficients");
mFirCoefs = (mInSampleRate <= mSampleRate) ? mFirCoefsUp : mFirCoefsDown;
}
@@ -270,7 +524,6 @@ void AudioResamplerSinc::resample(int32_t* out, size_t outFrameCount,
resample<2>(out, outFrameCount, provider);
break;
}
-
}
@@ -278,7 +531,8 @@ template<int CHANNELS>
void AudioResamplerSinc::resample(int32_t* out, size_t outFrameCount,
AudioBufferProvider* provider)
{
- const Constants *c = mConstants;
+ const Constants& c(*mConstants);
+ const size_t headOffset = c.halfNumCoefs*CHANNELS;
int16_t* impulse = mImpulse;
uint32_t vRL = mVolumeRL;
size_t inputIndex = mInputIndex;
@@ -313,43 +567,31 @@ void AudioResamplerSinc::resample(int32_t* out, size_t outFrameCount,
}
}
}
- int16_t *in = mBuffer.i16;
+ int16_t const * const in = mBuffer.i16;
const size_t frameCount = mBuffer.frameCount;
// Always read-in the first samples from the input buffer
- int16_t* head = impulse + c->halfNumCoefs*CHANNELS;
- head[0] = in[inputIndex*CHANNELS + 0];
- if (CHANNELS == 2)
- head[1] = in[inputIndex*CHANNELS + 1];
+ int16_t* head = impulse + headOffset;
+ for (size_t i=0 ; i<CHANNELS ; i++) {
+ head[i] = in[inputIndex*CHANNELS + i];
+ }
// handle boundary case
- int32_t l, r;
- while (outputIndex < outputSampleCount) {
- filterCoefficient<CHANNELS>(l, r, phaseFraction, impulse);
- out[outputIndex++] += 2 * mulRL(1, l, vRL);
- out[outputIndex++] += 2 * mulRL(0, r, vRL);
+ while (CC_LIKELY(outputIndex < outputSampleCount)) {
+ filterCoefficient<CHANNELS>(&out[outputIndex], phaseFraction, impulse, vRL);
+ outputIndex += 2;
phaseFraction += phaseIncrement;
- const uint32_t phaseIndex = phaseFraction >> kNumPhaseBits;
- if (phaseIndex == 1) {
- inputIndex++;
- if (inputIndex >= frameCount)
- break; // need a new buffer
- read<CHANNELS>(impulse, phaseFraction, in, inputIndex);
- } else if (phaseIndex == 2) { // maximum value
+ const size_t phaseIndex = phaseFraction >> kNumPhaseBits;
+ for (size_t i=0 ; i<phaseIndex ; i++) {
inputIndex++;
- if (inputIndex >= frameCount)
- break; // 0 frame available, 2 frames needed
- // read first frame
- read<CHANNELS>(impulse, phaseFraction, in, inputIndex);
- inputIndex++;
- if (inputIndex >= frameCount)
- break; // 0 frame available, 1 frame needed
- // read second frame
+ if (inputIndex >= frameCount) {
+ goto done; // need a new buffer
+ }
read<CHANNELS>(impulse, phaseFraction, in, inputIndex);
}
}
-
+done:
// if done with buffer, save samples
if (inputIndex >= frameCount) {
inputIndex -= frameCount;
@@ -375,66 +617,215 @@ void AudioResamplerSinc::read(
int16_t*& impulse, uint32_t& phaseFraction,
const int16_t* in, size_t inputIndex)
{
- const Constants *c = mConstants;
- const uint32_t phaseIndex = phaseFraction >> kNumPhaseBits;
impulse += CHANNELS;
phaseFraction -= 1LU<<kNumPhaseBits;
- if (impulse >= mRingFull) {
- const size_t stateSize = (c->halfNumCoefs*2)*CHANNELS;
+
+ const Constants& c(*mConstants);
+ if (CC_UNLIKELY(impulse >= mRingFull)) {
+ const size_t stateSize = (c.halfNumCoefs*2)*CHANNELS;
memcpy(mState, mState+stateSize, sizeof(int16_t)*stateSize);
impulse -= stateSize;
}
- int16_t* head = impulse + c->halfNumCoefs*CHANNELS;
- head[0] = in[inputIndex*CHANNELS + 0];
- if (CHANNELS == 2)
- head[1] = in[inputIndex*CHANNELS + 1];
+
+ int16_t* head = impulse + c.halfNumCoefs*CHANNELS;
+ for (size_t i=0 ; i<CHANNELS ; i++) {
+ head[i] = in[inputIndex*CHANNELS + i];
+ }
}
template<int CHANNELS>
void AudioResamplerSinc::filterCoefficient(
- int32_t& l, int32_t& r, uint32_t phase, const int16_t *samples)
+ int32_t* out, uint32_t phase, const int16_t *samples, uint32_t vRL)
{
- const Constants *c = mConstants;
+ // NOTE: be very careful when modifying the code here. register
+ // pressure is very high and a small change might cause the compiler
+ // to generate far less efficient code.
+ // Always sanity check the result with objdump or test-resample.
// compute the index of the coefficient on the positive side and
// negative side
- uint32_t indexP = (phase & c->cMask) >> c->cShift;
- uint16_t lerpP = (phase & c->pMask) >> c->pShift;
- uint32_t indexN = (-phase & c->cMask) >> c->cShift;
- uint16_t lerpN = (-phase & c->pMask) >> c->pShift;
- if ((indexP == 0) && (lerpP == 0)) {
- indexN = c->cMask >> c->cShift;
- lerpN = c->pMask >> c->pShift;
- }
-
- l = 0;
- r = 0;
- const int32_t* coefs = mFirCoefs;
- const int16_t *sP = samples;
- const int16_t *sN = samples+CHANNELS;
- for (unsigned int i=0 ; i < c->halfNumCoefs/4 ; i++) {
- interpolate<CHANNELS>(l, r, coefs+indexP, lerpP, sP);
- interpolate<CHANNELS>(l, r, coefs+indexN, lerpN, sN);
- sP -= CHANNELS; sN += CHANNELS; coefs += 1 << c->coefsBits;
- interpolate<CHANNELS>(l, r, coefs+indexP, lerpP, sP);
- interpolate<CHANNELS>(l, r, coefs+indexN, lerpN, sN);
- sP -= CHANNELS; sN += CHANNELS; coefs += 1 << c->coefsBits;
- interpolate<CHANNELS>(l, r, coefs+indexP, lerpP, sP);
- interpolate<CHANNELS>(l, r, coefs+indexN, lerpN, sN);
- sP -= CHANNELS; sN += CHANNELS; coefs += 1 << c->coefsBits;
- interpolate<CHANNELS>(l, r, coefs+indexP, lerpP, sP);
- interpolate<CHANNELS>(l, r, coefs+indexN, lerpN, sN);
- sP -= CHANNELS; sN += CHANNELS; coefs += 1 << c->coefsBits;
+ const Constants& c(*mConstants);
+ const int32_t ONE = c.cMask | c.pMask;
+ uint32_t indexP = ( phase & c.cMask) >> c.cShift;
+ uint32_t lerpP = ( phase & c.pMask) >> c.pShift;
+ uint32_t indexN = ((ONE-phase) & c.cMask) >> c.cShift;
+ uint32_t lerpN = ((ONE-phase) & c.pMask) >> c.pShift;
+
+ const size_t offset = c.halfNumCoefs;
+ indexP *= offset;
+ indexN *= offset;
+
+ int32_t const* coefsP = mFirCoefs + indexP;
+ int32_t const* coefsN = mFirCoefs + indexN;
+ int16_t const* sP = samples;
+ int16_t const* sN = samples + CHANNELS;
+
+ size_t count = offset;
+
+ if (!USE_NEON) {
+ int32_t l = 0;
+ int32_t r = 0;
+ for (size_t i=0 ; i<count ; i++) {
+ interpolate<CHANNELS>(l, r, coefsP++, offset, lerpP, sP);
+ sP -= CHANNELS;
+ interpolate<CHANNELS>(l, r, coefsN++, offset, lerpN, sN);
+ sN += CHANNELS;
+ }
+ out[0] += 2 * mulRL(1, l, vRL);
+ out[1] += 2 * mulRL(0, r, vRL);
+ } else if (CHANNELS == 1) {
+ int32_t const* coefsP1 = coefsP + offset;
+ int32_t const* coefsN1 = coefsN + offset;
+ sP -= CHANNELS*3;
+ asm (
+ "vmov.32 d2[0], %[lerpP] \n" // load the positive phase
+ "vmov.32 d2[1], %[lerpN] \n" // load the negative phase
+ "veor q0, q0, q0 \n" // result, initialize to 0
+ "vshl.s32 d2, d2, #16 \n" // convert to 32 bits
+
+ "1: \n"
+ "vld1.16 { d4}, [%[sP]] \n" // load 4 16-bits stereo samples
+ "vld1.32 { q8}, [%[coefsP0]:128]! \n" // load 4 32-bits coefs
+ "vld1.32 { q9}, [%[coefsP1]:128]! \n" // load 4 32-bits coefs for interpolation
+ "vld1.16 { d6}, [%[sN]]! \n" // load 4 16-bits stereo samples
+ "vld1.32 {q10}, [%[coefsN0]:128]! \n" // load 4 32-bits coefs
+ "vld1.32 {q11}, [%[coefsN1]:128]! \n" // load 4 32-bits coefs for interpolation
+
+ "vrev64.16 d4, d4 \n" // reverse 2 frames of the positive side
+
+ "vsub.s32 q9, q9, q8 \n" // interpolate (step1) 1st set of coefs
+ "vsub.s32 q11, q11, q10 \n" // interpolate (step1) 2nd set of coets
+ "vshll.s16 q12, d4, #15 \n" // extend samples to 31 bits
+
+ "vqrdmulh.s32 q9, q9, d2[0] \n" // interpolate (step2) 1st set of coefs
+ "vqrdmulh.s32 q11, q11, d2[1] \n" // interpolate (step3) 2nd set of coefs
+ "vshll.s16 q14, d6, #15 \n" // extend samples to 31 bits
+
+ "vadd.s32 q8, q8, q9 \n" // interpolate (step3) 1st set
+ "vadd.s32 q10, q10, q11 \n" // interpolate (step4) 2nd set
+ "subs %[count], %[count], #4 \n" // update loop counter
+
+ "vqrdmulh.s32 q12, q12, q8 \n" // multiply samples by interpolated coef
+ "vqrdmulh.s32 q14, q14, q10 \n" // multiply samples by interpolated coef
+ "sub %[sP], %[sP], #8 \n" // move pointer to next set of samples
+
+ "vadd.s32 q0, q0, q12 \n" // accumulate result
+ "vadd.s32 q0, q0, q14 \n" // accumulate result
+
+ "bne 1b \n" // loop
+
+ "vld1.s32 {d2}, [%[vLR]] \n" // load volumes
+ "vld1.s32 {d3}, %[out] \n" // load the output
+ "vpadd.s32 d0, d0, d1 \n" // add all 4 partial sums
+ "vpadd.s32 d0, d0, d0 \n" // together
+ "vdup.i32 d0, d0[0] \n" // interleave L,R channels
+ "vqrdmulh.s32 d0, d0, d2 \n" // apply volume
+ "vadd.s32 d3, d3, d0 \n" // accumulate result
+ "vst1.s32 {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 25fc025..09c6866 100644
--- a/services/audioflinger/AudioResamplerSinc.h
+++ b/services/audioflinger/AudioResamplerSinc.h
@@ -44,18 +44,21 @@ public:
private:
void init();
+ virtual void setVolume(int16_t left, int16_t right);
+
template<int CHANNELS>
void resample(int32_t* out, size_t outFrameCount,
AudioBufferProvider* provider);
template<int CHANNELS>
inline void filterCoefficient(
- int32_t& l, int32_t& r, uint32_t phase, const int16_t *samples);
+ int32_t* out, uint32_t phase, const int16_t *samples, uint32_t vRL);
template<int CHANNELS>
inline void interpolate(
int32_t& l, int32_t& r,
- const int32_t* coefs, int16_t lerp, const int16_t* samples);
+ const int32_t* coefs, size_t offset,
+ int32_t lerp, const int16_t* samples);
template<int CHANNELS>
inline void read(int16_t*& impulse, uint32_t& phaseFraction,
@@ -64,6 +67,7 @@ private:
int16_t *mState;
int16_t *mImpulse;
int16_t *mRingFull;
+ int32_t mVolumeSIMD[2];
const int32_t * mFirCoefs;
static const int32_t mFirCoefsDown[];
@@ -71,17 +75,14 @@ private:
// ----------------------------------------------------------------------------
static const int32_t RESAMPLE_FIR_NUM_COEF = 8;
- static const int32_t RESAMPLE_FIR_LERP_INT_BITS = 4;
+ static const int32_t RESAMPLE_FIR_LERP_INT_BITS = 7;
struct Constants {
- // we have 16 coefs samples per zero-crossing
int coefsBits;
int cShift;
uint32_t cMask;
-
int pShift;
uint32_t pMask;
-
// number of zero-crossing on each side
unsigned int halfNumCoefs;
};
diff --git a/services/audioflinger/StateQueue.h b/services/audioflinger/StateQueue.h
index eba190c..e33b3c6 100644
--- a/services/audioflinger/StateQueue.h
+++ b/services/audioflinger/StateQueue.h
@@ -17,6 +17,72 @@
#ifndef ANDROID_AUDIO_STATE_QUEUE_H
#define ANDROID_AUDIO_STATE_QUEUE_H
+// The state queue template class was originally driven by this use case / requirements:
+// There are two threads: a fast mixer, and a normal mixer, and they share state.
+// The interesting part of the shared state is a set of active fast tracks,
+// and the output HAL configuration (buffer size in frames, sample rate, etc.).
+// Fast mixer thread:
+// periodic with typical period < 10 ms
+// FIFO/RR scheduling policy and a low fixed priority
+// ok to block for bounded time using nanosleep() to achieve desired period
+// must not block on condition wait, mutex lock, atomic operation spin, I/O, etc.
+// under typical operations of mixing, writing, or adding/removing tracks
+// ok to block for unbounded time when the output HAL configuration changes,
+// and this may result in an audible artifact
+// needs read-only access to a recent stable state,
+// but not necessarily the most current one
+// Normal mixer thread:
+// periodic with typical period ~40 ms
+// SCHED_OTHER scheduling policy and nice priority == urgent audio
+// ok to block, but prefer to avoid as much as possible
+// needs read/write access to state
+// The normal mixer may need to temporarily suspend the fast mixer thread during mode changes.
+// It will do this using the state -- one of the fields tells the fast mixer to idle.
+
+// Additional requirements:
+// - observer must always be able to poll for and view the latest pushed state; it must never be
+// blocked from seeing that state
+// - observer does not need to see every state in sequence; it is OK for it to skip states
+// [see below for more on this]
+// - mutator must always be able to read/modify a state, it must never be blocked from reading or
+// modifying state
+// - reduce memcpy where possible
+// - work well if the observer runs more frequently than the mutator,
+// as is the case with fast mixer/normal mixer.
+// It is not a requirement to work well if the roles were reversed,
+// and the mutator were to run more frequently than the observer.
+// In this case, the mutator could get blocked waiting for a slot to fill up for
+// it to work with. This could be solved somewhat by increasing the depth of the queue, but it would
+// still limit the mutator to a finite number of changes before it would block. A future
+// possibility, not implemented here, would be to allow the mutator to safely overwrite an already
+// pushed state. This could be done by the mutator overwriting mNext, but then being prepared to
+// read an mAck which is actually for the earlier mNext (since there is a race).
+
+// Solution:
+// Let's call the fast mixer thread the "observer" and normal mixer thread the "mutator".
+// We assume there is only a single observer and a single mutator; this is critical.
+// Each state is of type <T>, and should contain only POD (Plain Old Data) and raw pointers, as
+// memcpy() may be used to copy state, and the destructors are run in unpredictable order.
+// The states in chronological order are: previous, current, next, and mutating:
+// previous read-only, observer can compare vs. current to see the subset that changed
+// current read-only, this is the primary state for observer
+// next read-only, when observer is ready to accept a new state it will shift it in:
+// previous = current
+// current = next
+// and the slot formerly used by previous is now available to the mutator.
+// mutating invisible to observer, read/write to mutator
+// Initialization is tricky, especially for the observer. If the observer starts execution
+// before the mutator, there are no previous, current, or next states. And even if the observer
+// starts execution after the mutator, there is a next state but no previous or current states.
+// To solve this, we'll have the observer idle until there is a next state,
+// and it will have to deal with the case where there is no previous state.
+// The states are stored in a shared FIFO queue represented using a circular array.
+// The observer polls for mutations, and receives a new state pointer after a
+// a mutation is pushed onto the queue. To the observer, the state pointers are
+// effectively in random order, that is the observer should not do address
+// arithmetic on the state pointers. However to the mutator, the state pointers
+// are in a definite circular order.
+
namespace android {
#ifdef STATE_QUEUE_DUMP
@@ -108,7 +174,7 @@ public:
#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/AudioResamplerCoefficients.cpp b/services/audioflinger/audio-resampler/AudioResamplerCoefficients.cpp
index ade58a7..af3e40d 100644
--- a/services/audioflinger/audio-resampler/AudioResamplerCoefficients.cpp
+++ b/services/audioflinger/audio-resampler/AudioResamplerCoefficients.cpp
@@ -14,42 +14,41 @@
* limitations under the License.
*/
-#include <dnsampler_filter_coefficients_x128_10112011.h>
-#include <resampler_filter_coefficients_10042011.h>
-#undef LOG_TAG
-#include <utils/Log.h>
-//#include "common_log.h"
#define LOG_TAG "ResamplerCoefficients"
#define LOG_NDEBUG 0
-const int32_t RESAMPLE_FIR_NUM_COEF = 16;
-const int32_t RESAMPLE_FIR_LERP_INT_BITS = 7;
+#include <utils/Log.h>
+
+#include "filter_coefficients.h"
+
+const int32_t RESAMPLE_FIR_NUM_COEF = 16;
+const int32_t RESAMPLE_FIR_LERP_INT_BITS = 7;
using namespace android;
+
#ifdef __cplusplus
extern "C" {
#endif
+
const int32_t* readResamplerCoefficients(bool upSample) {
ALOGV("readResamplerCoefficients");
- if(upSample) {
- return resampler_filter_coefficients_10042011;
+ if (upSample) {
+ return up_sampler_filter_coefficients;
+ } else {
+ return dn_sampler_filter_coefficients;
}
- else {
- return dnsampler_filter_coefficients_x128_10112011;
- }
}
int32_t readResampleFirNumCoeff() {
-
return RESAMPLE_FIR_NUM_COEF;
}
int32_t readResampleFirLerpIntBits() {
-
- return RESAMPLE_FIR_LERP_INT_BITS;
+ return RESAMPLE_FIR_LERP_INT_BITS;
}
+
#ifdef __cplusplus
}
#endif
diff --git a/services/audioflinger/audio-resampler/dnsampler_filter_coefficients_x128_10112011.h b/services/audioflinger/audio-resampler/dnsampler_filter_coefficients_x128_10112011.h
deleted file mode 100644
index eb2944c..0000000
--- a/services/audioflinger/audio-resampler/dnsampler_filter_coefficients_x128_10112011.h
+++ /dev/null
@@ -1,2585 +0,0 @@
-
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdlib.h>
-
-namespace android {
-
-const int32_t dnsampler_filter_coefficients_x128_10112011[] = {
-1849391518,
-1849249650,
-1848824221,
-1848115177,
-1847122891,
-1845847499,
-1844289491,
-1842449129,
-1840327103,
-1837923861,
-1835240203,
-1832276710,
-1829034388,
-1825513999,
-1821716652,
-1817643240,
-1813295074,
-1808673214,
-1803779065,
-1798613825,
-1793179109,
-1787476282,
-1781507048,
-1775272909,
-1768775774,
-1762017295,
-1754999460,
-1747724062,
-1740193297,
-1732409109,
-1724373764,
-1716089338,
-1707558293,
-1698782831,
-1689765473,
-1680508558,
-1671014814,
-1661286715,
-1651327042,
-1641138399,
-1630723762,
-1620085842,
-1609227651,
-1598152036,
-1586862206,
-1575361116,
-1563652006,
-1551737947,
-1539622358,
-1527308388,
-1514799466,
-1502098869,
-1489210218,
-1476136877,
-1462882477,
-1449450498,
-1435844739,
-1422068735,
-1408126274,
-1394021008,
-1379756900,
-1365337657,
-1350767225,
-1336049408,
-1321188297,
-1306187721,
-1291051731,
-1275784259,
-1260389523,
-1244871491,
-1229234343,
-1213482137,
-1197619187,
-1181649550,
-1165577481,
-1149407125,
-1133142876,
-1116788884,
-1100349476,
-1083828868,
-1067231493,
-1050561533,
-1033823337,
-1017021160,
-1000159475,
-983242522,
-966274693,
-949260282,
-932203771,
-915109401,
-897981548,
-880824504,
-863642743,
-846440509,
-829222164,
-811991981,
-794754382,
-777513558,
-760273800,
-743039333,
-725814532,
-708603558,
-691410662,
-674240023,
-657095935,
-639982476,
-622903794,
-605863979,
-588867231,
-571917545,
-555018972,
-538175499,
-521391190,
-504669905,
-488015541,
-471431958,
-454923090,
-438492688,
-422144531,
-405882352,
-389709927,
-373630848,
-357648715,
-341767096,
-325989596,
-310319649,
-294760687,
-279316098,
-263989284,
-248783473,
-233701878,
-218747691,
-203924116,
-189234208,
-174680993,
-160267473,
-145996632,
-131871305,
-117894282,
-104068338,
-90396230,
-76880575,
-63523937,
-50328860,
-37297842,
-24433248,
-11737378,
--787473,
--13139049,
--25315210,
--37313887,
--49133021,
--60770615,
--72224791,
--83493750,
--94575698,
--105468905,
--116171744,
--126682678,
--137000178,
--147122799,
--157049194,
--166778112,
--176308299,
--185638576,
--194767849,
--203695121,
--212419395,
--220939772,
--229255432,
--237365662,
--245269744,
--252967058,
--260457050,
--267739278,
--274813300,
--281678782,
--288335451,
--294783151,
--301021713,
--307051072,
--312871207,
--318482217,
--323884189,
--329077326,
--334061875,
--338838202,
--343406662,
--347767725,
--351921891,
--355869785,
--359612019,
--363149327,
--366482470,
--369612329,
--372539768,
--375265766,
--377791316,
--380117528,
--382245500,
--384176449,
--385911601,
--387452302,
--388799883,
--389955791,
--390921477,
--391698507,
--392288434,
--392692926,
--392913649,
--392952381,
--392810881,
--392491020,
--391994654,
--391323748,
--390480249,
--389466214,
--388283683,
--386934801,
--385421695,
--383746599,
--381911725,
--379919384,
--377771869,
--375471577,
--373020872,
--370422215,
--367678046,
--364790904,
--361763287,
--358597785,
--355296968,
--351863496,
--348299986,
--344609141,
--340793645,
--336856270,
--332799742,
--328626863,
--324340418,
--319943269,
--315438225,
--310828168,
--306115960,
--301304533,
--296396768,
--291395607,
--286303973,
--281124849,
--275861163,
--270515897,
--265092015,
--259592541,
--254020439,
--248378720,
--242670378,
--236898450,
--231065914,
--225175783,
--219231057,
--213234773,
--207189910,
--201099474,
--194966455,
--188793871,
--182584674,
--176341840,
--170068330,
--163767128,
--157441156,
--151093349,
--144726627,
--138343919,
--131948090,
--125542009,
--119128533,
--112710525,
--106290787,
--99872116,
--93457296,
--87049105,
--80650255,
--74263449,
--67891377,
--61536721,
--55202101,
--48890119,
--42603362,
--36344397,
--30115726,
--23919828,
--17759168,
--11636191,
--5553280,
-487212,
-6482947,
-12431620,
-18330990,
-24178851,
-29973011,
-35711312,
-41391655,
-47011985,
-52570260,
-58064483,
-63492718,
-68853076,
-74143678,
-79362692,
-84508338,
-89578892,
-94572639,
-99487923,
-104323138,
-109076739,
-113747190,
-118333012,
-122832775,
-127245111,
-131568663,
-135802141,
-139944301,
-143993966,
-147949965,
-151811195,
-155576593,
-159245166,
-162815931,
-166287976,
-169660430,
-172932498,
-176103387,
-179172383,
-182138803,
-185002039,
-187761495,
-190416648,
-192967011,
-195412171,
-197751720,
-199985330,
-202112693,
-204133584,
-206047780,
-207855140,
-209555545,
-211148956,
-212635338,
-214014737,
-215287214,
-216452911,
-217511975,
-218464633,
-219311127,
-220051778,
-220686909,
-221216923,
-221642232,
-221963326,
-222180699,
-222294922,
-222306577,
-222216320,
-222024810,
-221732784,
-221340984,
-220850224,
-220261321,
-219575167,
-218792653,
-217914741,
-216942395,
-215876649,
-214718535,
-213469149,
-212129590,
-210701024,
-209184611,
-207581573,
-205893134,
-204120584,
-202265202,
-200328328,
-198311300,
-196215518,
-194042369,
-191793295,
-189469738,
-187073198,
-184605160,
-182067159,
-179460730,
-176787462,
-174048923,
-171246730,
-168382500,
-165457899,
-162474572,
-159434208,
-156338493,
-153189156,
-149987902,
-146736470,
-143436603,
-140090079,
-136698650,
-133264101,
-129788215,
-126272805,
-122719654,
-119130572,
-115507371,
-111851884,
-108165922,
-104451311,
-100709877,
-96943466,
-93153889,
-89342976,
-85512554,
-81664466,
-77800525,
-73922553,
-70032372,
-66131809,
-62222659,
-58306723,
-54385799,
-50461691,
-46536172,
-42611011,
-38687978,
-34768834,
-30855311,
-26949132,
-23052017,
-19165682,
-15291809,
-11432068,
-7588126,
-3761633,
--45792,
--3832550,
--7597044,
--11337694,
--15052951,
--18741290,
--22401190,
--26031153,
--29629717,
--33195444,
--36726898,
--40222670,
--43681381,
--47101682,
--50482228,
--53821707,
--57118836,
--60372370,
--63581062,
--66743703,
--69859111,
--72926141,
--75943654,
--78910550,
--81825759,
--84688251,
--87496999,
--90251018,
--92949348,
--95591074,
--98175284,
--100701113,
--103167725,
--105574326,
--107920130,
--110204396,
--112426408,
--114585497,
--116681001,
--118712307,
--120678826,
--122580018,
--124415349,
--126184333,
--127886505,
--129521449,
--131088758,
--132588075,
--134019062,
--135381436,
--136674915,
--137899273,
--139054300,
--140139836,
--141155730,
--142101884,
--142978213,
--143784688,
--144521281,
--145188022,
--145784950,
--146312156,
--146769738,
--147157848,
--147476649,
--147726356,
--147907187,
--148019419,
--148063331,
--148039258,
--147947536,
--147788557,
--147562717,
--147270463,
--146912244,
--146488563,
--145999923,
--145446877,
--144829983,
--144149847,
--143407076,
--142602324,
--141736248,
--140809557,
--139822954,
--138777189,
--137673015,
--136511230,
--135292629,
--134018047,
--132688326,
--131304347,
--129866988,
--128377166,
--126835801,
--125243852,
--123602271,
--121912047,
--120174172,
--118389676,
--116559578,
--114684934,
--112766800,
--110806267,
--108804411,
--106762342,
--104681172,
--102562041,
--100406081,
--98214447,
--95988299,
--93728821,
--91437183,
--89114578,
--86762204,
--84381279,
--81973009,
--79538619,
--77079333,
--74596397,
--72091035,
--69564491,
--67018008,
--64452847,
--61870249,
--59271470,
--56657765,
--54030397,
--51390615,
--48739670,
--46078819,
--43409324,
--40732431,
--38049385,
--35361437,
--32669835,
--29975809,
--27280589,
--24585404,
--21891486,
--19200045,
--16512287,
--13829420,
--11152644,
--8483140,
--5822079,
--3170634,
--529970,
-2098768,
-4714446,
-7315931,
-9902105,
-12471869,
-15024139,
-17557833,
-20071880,
-22565234,
-25036861,
-27485734,
-29910841,
-32311195,
-34685828,
-37033773,
-39354083,
-41645834,
-43908123,
-46140049,
-48340738,
-50509337,
-52645015,
-54746948,
-56814333,
-58846388,
-60842359,
-62801494,
-64723072,
-66606390,
-68450776,
-70255559,
-72020101,
-73743779,
-75426002,
-77066186,
-78663776,
-80218238,
-81729070,
-83195771,
-84617877,
-85994939,
-87326540,
-88612269,
-89851753,
-91044631,
-92190579,
-93289279,
-94340447,
-95343813,
-96299144,
-97206213,
-98064827,
-98874809,
-99636019,
-100348318,
-101011607,
-101625796,
-102190834,
-102706673,
-103173303,
-103590724,
-103958975,
-104278097,
-104548170,
-104769282,
-104941559,
-105065128,
-105140157,
-105166820,
-105145327,
-105075891,
-104958764,
-104794201,
-104582494,
-104323937,
-104018863,
-103667606,
-103270537,
-102828031,
-102340497,
-101808346,
-101232024,
-100611979,
-99948695,
-99242655,
-98494373,
-97704368,
-96873190,
-96001391,
-95089549,
-94138248,
-93148103,
-92119724,
-91053751,
-89950827,
-88811624,
-87636812,
-86427086,
-85183142,
-83905705,
-82595493,
-81253249,
-79879717,
-78475668,
-77041865,
-75579093,
-74088140,
-72569815,
-71024919,
-69454270,
-67858693,
-66239031,
-64596117,
-62930801,
-61243936,
-59536392,
-57809025,
-56062708,
-54298314,
-52516733,
-50718843,
-48905532,
-47077692,
-45236223,
-43382015,
-41515965,
-39638972,
-37751945,
-35855780,
-33951378,
-32039643,
-30121481,
-28197786,
-26269454,
-24337383,
-22402475,
-20465617,
-18527696,
-16589601,
-14652220,
-12716424,
-10783083,
-8853070,
-6927251,
-5006483,
-3091612,
-1183489,
--717043,
--2609159,
--4492039,
--6364862,
--8226816,
--10077103,
--11914934,
--13739523,
--15550093,
--17345884,
--19126146,
--20890132,
--22637106,
--24366346,
--26077146,
--27768800,
--29440618,
--31091927,
--32722068,
--34330384,
--35916235,
--37478994,
--39018053,
--40532806,
--42022667,
--43487063,
--44925444,
--46337259,
--47721979,
--49079087,
--50408090,
--51708495,
--52979834,
--54221651,
--55433514,
--56614992,
--57765679,
--58885178,
--59973119,
--61029133,
--62052877,
--63044020,
--64002256,
--64927281,
--65818818,
--66676601,
--67500387,
--68289938,
--69045045,
--69765506,
--70451147,
--71101796,
--71717309,
--72297549,
--72842408,
--73351780,
--73825587,
--74263759,
--74666254,
--75033033,
--75364085,
--75659405,
--75919016,
--76142943,
--76331242,
--76483972,
--76601219,
--76683074,
--76729655,
--76741083,
--76717507,
--76659078,
--76565976,
--76438382,
--76276507,
--76080561,
--75850784,
--75587416,
--75290725,
--74960980,
--74598477,
--74203511,
--73776405,
--73317481,
--72827089,
--72305578,
--71753320,
--71170691,
--70558089,
--69915913,
--69244582,
--68544519,
--67816171,
--67059982,
--66276416,
--65465942,
--64629046,
--63766215,
--62877953,
--61964766,
--61027182,
--60065722,
--59080928,
--58073342,
--57043524,
--55992029,
--54919428,
--53826296,
--52713221,
--51580788,
--50429596,
--49260245,
--48073350,
--46869516,
--45649365,
--44413516,
--43162604,
--41897255,
--40618108,
--39325799,
--38020978,
--36704285,
--35376367,
--34037875,
--32689467,
--31331794,
--29965512,
--28591278,
--27209755,
--25821597,
--24427461,
--23028006,
--21623896,
--20215785,
--18804329,
--17390186,
--15974013,
--14556459,
--13138172,
--11719802,
--10301999,
--8885401,
--7470647,
--6058375,
--4649221,
--3243807,
--1842755,
--446687,
-943782,
-2328043,
-3705495,
-5075537,
-6437575,
-7791026,
-9135312,
-10469860,
-11794099,
-13107474,
-14409434,
-15699433,
-16976932,
-18241406,
-19492338,
-20729214,
-21951528,
-23158786,
-24350507,
-25526208,
-26685422,
-27827692,
-28952575,
-30059626,
-31148419,
-32218533,
-33269565,
-34301113,
-35312788,
-36304216,
-37275034,
-38224885,
-39153423,
-40060316,
-40945246,
-41807897,
-42647972,
-43465182,
-44259258,
-45029930,
-45776947,
-46500068,
-47199069,
-47873729,
-48523844,
-49149222,
-49749687,
-50325066,
-50875204,
-51399956,
-51899193,
-52372790,
-52820642,
-53242651,
-53638739,
-54008828,
-54352864,
-54670795,
-54962591,
-55228223,
-55467686,
-55680976,
-55868110,
-56029109,
-56164013,
-56272864,
-56355729,
-56412671,
-56443780,
-56449143,
-56428871,
-56383077,
-56311893,
-56215452,
-56093910,
-55947423,
-55776167,
-55580318,
-55360074,
-55115633,
-54847211,
-54555028,
-54239319,
-53900322,
-53538294,
-53153491,
-52746187,
-52316657,
-51865197,
-51392097,
-50897668,
-50382220,
-49846081,
-49289577,
-48713047,
-48116836,
-47501302,
-46866801,
-46213703,
-45542381,
-44853220,
-44146603,
-43422927,
-42682590,
-41926002,
-41153572,
-40365719,
-39562864,
-38745438,
-37913870,
-37068598,
-36210060,
-35338709,
-34454988,
-33559353,
-32652259,
-31734171,
-30805546,
-29866852,
-28918556,
-27961133,
-26995053,
-26020792,
-25038826,
-24049638,
-23053702,
-22051499,
-21043509,
-20030219,
-19012108,
-17989658,
-16963352,
-15933674,
-14901104,
-13866119,
-12829202,
-11790833,
-10751487,
-9711638,
-8671763,
-7632335,
-6593820,
-5556683,
-4521391,
-3488407,
-2458187,
-1431187,
-407859,
--611345,
--1625983,
--2635618,
--3639811,
--4638127,
--5630141,
--6615431,
--7593576,
--8564163,
--9526785,
--10481043,
--11426537,
--12362876,
--13289673,
--14206552,
--15113136,
--16009059,
--16893959,
--17767487,
--18629291,
--19479032,
--20316375,
--21140997,
--21952575,
--22750798,
--23535360,
--24305970,
--25062334,
--25804171,
--26531205,
--27243175,
--27939817,
--28620882,
--29286128,
--29935325,
--30568244,
--31184668,
--31784388,
--32367206,
--32932927,
--33481369,
--34012357,
--34525729,
--35021324,
--35498994,
--35958600,
--36400012,
--36823105,
--37227767,
--37613893,
--37981391,
--38330171,
--38660157,
--38971278,
--39263479,
--39536704,
--39790914,
--40026074,
--40242163,
--40439161,
--40617065,
--40775874,
--40915600,
--41036259,
--41137883,
--41220502,
--41284167,
--41328926,
--41354844,
--41361987,
--41350437,
--41320276,
--41271601,
--41204513,
--41119123,
--41015546,
--40893911,
--40754348,
--40597001,
--40422014,
--40229546,
--40019757,
--39792819,
--39548906,
--39288206,
--39010907,
--38717208,
--38407310,
--38081429,
--37739776,
--37382578,
--37010062,
--36622464,
--36220024,
--35802990,
--35371611,
--34926149,
--34466863,
--33994021,
--33507895,
--33008767,
--32496915,
--31972628,
--31436196,
--30887917,
--30328089,
--29757014,
--29175000,
--28582360,
--27979405,
--27366455,
--26743828,
--26111852,
--25470849,
--24821150,
--24163084,
--23496990,
--22823200,
--22142053,
--21453889,
--20759052,
--20057882,
--19350724,
--18637922,
--17919826,
--17196782,
--16469137,
--15737241,
--15001445,
--14262095,
--13519542,
--12774133,
--12026222,
--11276155,
--10524279,
--9770942,
--9016494,
--8261277,
--7505635,
--6749910,
--5994447,
--5239585,
--4485659,
--3733007,
--2981966,
--2232865,
--1486032,
--741794,
--479,
-737595,
-1472108,
-2202745,
-2929192,
-3651141,
-4368289,
-5080331,
-5786969,
-6487909,
-7182860,
-7871535,
-8553649,
-9228926,
-9897092,
-10557878,
-11211015,
-11856245,
-12493314,
-13121967,
-13741959,
-14353050,
-14955005,
-15547593,
-16130588,
-16703768,
-17266923,
-17819839,
-18362313,
-18894148,
-19415155,
-19925144,
-20423935,
-20911353,
-21387231,
-21851406,
-22303720,
-22744023,
-23172174,
-23588031,
-23991464,
-24382346,
-24760559,
-25125987,
-25478524,
-25818069,
-26144531,
-26457817,
-26757849,
-27044549,
-27317851,
-27577690,
-27824011,
-28056763,
-28275905,
-28481398,
-28673213,
-28851323,
-29015713,
-29166367,
-29303283,
-29426459,
-29535904,
-29631629,
-29713655,
-29782006,
-29836715,
-29877818,
-29905359,
-29919387,
-29919958,
-29907132,
-29880978,
-29841566,
-29788975,
-29723288,
-29644596,
-29552991,
-29448575,
-29331452,
-29201735,
-29059537,
-28904981,
-28738192,
-28559303,
-28368447,
-28165766,
-27951404,
-27725513,
-27488244,
-27239759,
-26980219,
-26709793,
-26428650,
-26136967,
-25834922,
-25522700,
-25200487,
-24868475,
-24526855,
-24175830,
-23815596,
-23446360,
-23068326,
-22681709,
-22286719,
-21883572,
-21472486,
-21053686,
-20627392,
-20193830,
-19753228,
-19305819,
-18851833,
-18391506,
-17925071,
-17452770,
-16974838,
-16491518,
-16003049,
-15509677,
-15011645,
-14509198,
-14002580,
-13492042,
-12977828,
-12460185,
-11939362,
-11415608,
-10889171,
-10360299,
-9829240,
-9296245,
-8761559,
-8225429,
-7688103,
-7149828,
-6610849,
-6071411,
-5531756,
-4992131,
-4452774,
-3913926,
-3375826,
-2838712,
-2302821,
-1768384,
-1235637,
-704811,
-176132,
--350173,
--873879,
--1394763,
--1912606,
--2427192,
--2938303,
--3445727,
--3949255,
--4448681,
--4943802,
--5434414,
--5920319,
--6401326,
--6877239,
--7347870,
--7813034,
--8272552,
--8726243,
--9173932,
--9615448,
--10050623,
--10479293,
--10901295,
--11316474,
--11724679,
--12125759,
--12519569,
--12905967,
--13284818,
--13655986,
--14019344,
--14374766,
--14722134,
--15061330,
--15392240,
--15714758,
--16028781,
--16334207,
--16630942,
--16918895,
--17197981,
--17468118,
--17729228,
--17981237,
--18224079,
--18457687,
--18682004,
--18896973,
--19102546,
--19298674,
--19485318,
--19662437,
--19830002,
--19987982,
--20136353,
--20275096,
--20404197,
--20523643,
--20633430,
--20733554,
--20824018,
--20904829,
--20975997,
--21037538,
--21089473,
--21131822,
--21164617,
--21187886,
--21201668,
--21206001,
--21200931,
--21186504,
--21162774,
--21129796,
--21087631,
--21036341,
--20975996,
--20906666,
--20828426,
--20741355,
--20645535,
--20541051,
--20427994,
--20306454,
--20176529,
--20038316,
--19891920,
--19737444,
--19574998,
--19404692,
--19226642,
--19040965,
--18847782,
--18647215,
--18439392,
--18224439,
--18002487,
--17773669,
--17538123,
--17295986,
--17047397,
--16792499,
--16531439,
--16264360,
--15991413,
--15712746,
--15428514,
--15138869,
--14843968,
--14543967,
--14239027,
--13929305,
--13614963,
--13296164,
--12973072,
--12645852,
--12314669,
--11979690,
--11641084,
--11299018,
--10953660,
--10605181,
--10253752,
--9899543,
--9542724,
--9183468,
--8821947,
--8458330,
--8092791,
--7725499,
--7356629,
--6986351,
--6614835,
--6242252,
--5868775,
--5494571,
--5119810,
--4744660,
--4369291,
--3993868,
--3618559,
--3243529,
--2868942,
--2494962,
--2121750,
--1749467,
--1378274,
--1008329,
--639789,
--272809,
-92455,
-455851,
-817231,
-1176442,
-1533338,
-1887773,
-2239604,
-2588688,
-2934884,
-3278056,
-3618068,
-3954787,
-4288079,
-4617816,
-4943871,
-5266119,
-5584437,
-5898705,
-6208806,
-6514625,
-6816049,
-7112968,
-7405275,
-7692864,
-7975633,
-8253483,
-8526319,
-8794045,
-9056570,
-9313805,
-9565666,
-9812069,
-10052933,
-10288182,
-10517742,
-10741541,
-10959512,
-11171587,
-11377707,
-11577809,
-11771839,
-11959741,
-12141468,
-12316971,
-12486205,
-12649128,
-12805703,
-12955894,
-13099669,
-13236996,
-13367853,
-13492214,
-13610059,
-13721371,
-13826136,
-13924343,
-14015982,
-14101050,
-14179544,
-14251463,
-14316813,
-14375598,
-14427829,
-14473516,
-14512676,
-14545324,
-14571484,
-14591176,
-14604428,
-14611268,
-14611727,
-14605840,
-14593643,
-14575174,
-14550478,
-14519596,
-14482577,
-14439469,
-14390325,
-14335196,
-14274142,
-14207219,
-14134490,
-14056016,
-13971864,
-13882101,
-13786797,
-13686023,
-13579854,
-13468364,
-13351632,
-13229736,
-13102759,
-12970783,
-12833894,
-12692177,
-12545721,
-12394615,
-12238951,
-12078822,
-11914322,
-11745546,
-11572592,
-11395558,
-11214544,
-11029649,
-10840977,
-10648630,
-10452712,
-10253328,
-10050584,
-9844586,
-9635444,
-9423263,
-9208154,
-8990226,
-8769590,
-8546356,
-8320637,
-8092543,
-7862188,
-7629684,
-7395143,
-7158678,
-6920405,
-6680434,
-6438881,
-6195859,
-5951482,
-5705863,
-5459115,
-5211352,
-4962688,
-4713234,
-4463103,
-4212408,
-3961262,
-3709774,
-3458055,
-3206216,
-2954367,
-2702617,
-2451073,
-2199845,
-1949039,
-1698760,
-1449115,
-1200206,
-952139,
-705015,
-458936,
-214002,
--29687,
--272033,
--512941,
--752313,
--990055,
--1226074,
--1460278,
--1692576,
--1922878,
--2151097,
--2377147,
--2600942,
--2822399,
--3041435,
--3257970,
--3471925,
--3683223,
--3891787,
--4097545,
--4300424,
--4500352,
--4697261,
--4891083,
--5081754,
--5269208,
--5453384,
--5634222,
--5811664,
--5985653,
--6156134,
--6323055,
--6486364,
--6646013,
--6801954,
--6954144,
--7102537,
--7247093,
--7387773,
--7524538,
--7657353,
--7786184,
--7910999,
--8031770,
--8148467,
--8261064,
--8369539,
--8473868,
--8574031,
--8670011,
--8761790,
--8849356,
--8932694,
--9011796,
--9086651,
--9157254,
--9223598,
--9285682,
--9343504,
--9397065,
--9446367,
--9491415,
--9532214,
--9568774,
--9601103,
--9629214,
--9653119,
--9672835,
--9688376,
--9699763,
--9707015,
--9710154,
--9709202,
--9704187,
--9695132,
--9682068,
--9665024,
--9644031,
--9619121,
--9590330,
--9557692,
--9521245,
--9481028,
--9437080,
--9389443,
--9338159,
--9283272,
--9224828,
--9162872,
--9097452,
--9028617,
--8956417,
--8880903,
--8802127,
--8720142,
--8635003,
--8546764,
--8455484,
--8361217,
--8264022,
--8163959,
--8061088,
--7955468,
--7847161,
--7736229,
--7622737,
--7506745,
--7388320,
--7267525,
--7144428,
--7019092,
--6891585,
--6761974,
--6630327,
--6496711,
--6361194,
--6223845,
--6084734,
--5943929,
--5801500,
--5657517,
--5512050,
--5365168,
--5216942,
--5067443,
--4916741,
--4764906,
--4612009,
--4458120,
--4303311,
--4147650,
--3991209,
--3834057,
--3676265,
--3517901,
--3359037,
--3199740,
--3040080,
--2880126,
--2719945,
--2559606,
--2399177,
--2238724,
--2078315,
--1918015,
--1757891,
--1598007,
--1438428,
--1279218,
--1120441,
--962159,
--804435,
--647330,
--490906,
--335223,
--180338,
--26312,
-126797,
-278933,
-430040,
-580062,
-728943,
-876632,
-1023074,
-1168219,
-1312015,
-1454411,
-1595360,
-1734812,
-1872720,
-2009038,
-2143721,
-2276725,
-2408006,
-2537522,
-2665233,
-2791097,
-2915076,
-3037131,
-3157228,
-3275328,
-3391399,
-3505405,
-3617315,
-3727097,
-3834720,
-3940156,
-4043377,
-4144356,
-4243067,
-4339485,
-4433587,
-4525351,
-4614755,
-4701780,
-4786406,
-4868616,
-4948393,
-5025721,
-5100587,
-5172977,
-5242878,
-5310279,
-5375172,
-5437547,
-5497396,
-5554712,
-5609491,
-5661728,
-5711419,
-5758562,
-5803157,
-5845203,
-5884701,
-5921652,
-5956061,
-5987931,
-6017267,
-6044075,
-6068363,
-6090138,
-6109409,
-6126186,
-6140482,
-6152306,
-6161673,
-6168595,
-6173088,
-6175167,
-6174849,
-6172151,
-6167091,
-6159687,
-6149960,
-6137930,
-6123618,
-6107046,
-6088238,
-6067217,
-6044007,
-6018632,
-5991120,
-5961496,
-5929787,
-5896020,
-5860225,
-5822429,
-5782663,
-5740956,
-5697338,
-5651841,
-5604497,
-5555336,
-5504393,
-5451699,
-5397289,
-5341196,
-5283454,
-5224099,
-5163164,
-5100686,
-5036700,
-4971242,
-4904348,
-4836055,
-4766400,
-4695420,
-4623152,
-4549633,
-4474901,
-4398995,
-4321952,
-4243810,
-4164608,
-4084383,
-4003175,
-3921021,
-3837960,
-3754032,
-3669273,
-3583724,
-3497422,
-3410406,
-3322714,
-3234384,
-3145456,
-3055967,
-2965954,
-2875457,
-2784513,
-2693159,
-2601433,
-2509371,
-2417012,
-2324391,
-2231545,
-2138511,
-2045325,
-1952022,
-1858638,
-1765208,
-1671768,
-1578350,
-1484991,
-1391723,
-1298581,
-1205597,
-1112804,
-1020235,
-927921,
-835894,
-744186,
-652826,
-561846,
-471276,
-381143,
-291479,
-202310,
-113666,
-25572,
--61942,
--148851,
--235129,
--320751,
--405691,
--489926,
--573430,
--656181,
--738156,
--819332,
--899688,
--979202,
--1057854,
--1135623,
--1212489,
--1288435,
--1363441,
--1437489,
--1510563,
--1582644,
--1653718,
--1723769,
--1792781,
--1860740,
--1927631,
--1993443,
--2058161,
--2121774,
--2184270,
--2245638,
--2305868,
--2364949,
--2422873,
--2479630,
--2535212,
--2589613,
--2642824,
--2694840,
--2745654,
--2795261,
--2843656,
--2890834,
--2936793,
--2981528,
--3025036,
--3067316,
--3108366,
--3148185,
--3186772,
--3224126,
--3260249,
--3295140,
--3328802,
--3361236,
--3392444,
--3422430,
--3451195,
--3478744,
--3505081,
--3530210,
--3554136,
--3576865,
--3598402,
--3618754,
--3637927,
--3655929,
--3672765,
--3688446,
--3702978,
--3716370,
--3728631,
--3739770,
--3749797,
--3758721,
--3766553,
--3773304,
--3778983,
--3783603,
--3787174,
--3789709,
--3791219,
--3791717,
--3791215,
--3789725,
--3787262,
--3783838,
--3779466,
--3774160,
--3767934,
--3760802,
--3752778,
--3743877,
--3734113,
--3723501,
--3712056,
--3699792,
--3686725,
--3672871,
--3658244,
--3642860,
--3626735,
--3609884,
--3592324,
--3574069,
--3555137,
--3535542,
--3515302,
--3494432,
--3472947,
--3450866,
--3428203,
--3404974,
--3381197,
--3356887,
--3332060,
--3306732,
--3280921,
--3254641,
--3227909,
--3200741,
--3173153,
--3145162,
--3116781,
--3088029,
--3058920,
--3029469,
--2999694,
--2969608,
--2939228,
--2908568,
--2877644,
--2846472,
--2815064,
--2783438,
--2751607,
--2719586,
--2687389,
--2655030,
--2622524,
--2589885,
--2557126,
--2524261,
--2491304,
--2458268,
--2425166,
--2392011,
--2358815,
--2325592,
--2292354,
--2259114,
--2225882,
--2192671,
--2159493,
--2126359,
--2093281,
--2060269,
--2027334,
--1994487,
--1961738,
--1929098,
--1896576,
--1864183,
--1831927,
--1799818,
--1767865,
--1736078,
--1704464,
--1673032,
--1641791,
--1610748,
--1579911,
--1549288,
--1518886,
--1488713,
--1458774,
--1429078,
--1399630,
--1370436,
--1341503,
--1312836,
--1284441,
--1256324,
--1228489,
--1200941,
--1173686,
--1146727,
--1120069,
--1093717,
--1067673,
--1041942,
--1016527,
--991432,
--966659,
--942211,
--918092,
--894303,
--870846,
--847724,
--824940,
--802493,
--780386,
--758621,
--737199,
--716120,
--695385,
--674996,
--654951,
--635253,
--615901,
--596895,
--578234,
--559919,
--541949,
--524324,
--507042,
--490103,
--473505,
--457248,
--441330,
--425750,
--410506,
--395596,
--381019,
--366773,
--352855,
--339263,
--325995,
--313049,
--300421,
--288110,
--276112,
--264425,
--253046,
--241972,
--231199,
--220725,
--210546,
--200659,
--191060,
--181746,
--172713,
--163958,
--155477,
--147266,
--139321,
--131639,
--124215,
--117045,
--110126,
--103453,
--97022,
--90829,
--84870,
--79140,
--73636,
--68352,
--63285,
--58431,
--53784,
--49341,
--45097,
--41048,
--37188,
--33515,
--30023,
--26708,
--23566,
--20592,
--17782,
--15130,
--12634,
--10289,
--8089,
--6031,
--4111,
--2324,
--666,
-868,
-2281,
-3578,
-4763,
-5839,
-6812,
-7685,
-8462,
-9146,
-9743,
-10255,
-10686,
-11041,
-11322,
-11533,
-11679,
-11762,
-11785,
-11753,
-11668,
-11533,
-11352,
-11128,
-10864,
-10563,
-10227,
-9860,
-9464,
-9042,
-8596,
-8129,
-7644,
-7142,
-6626,
-6099,
-5562,
-5017,
-4467,
-3913,
-3357,
-2800,
-2245,
-1694,
-1146,
-605,
-71,
--454,
--970,
--1474,
--1966,
--2446,
--2911,
--3362,
--3797,
--4215,
--4617,
--5001,
--5367,
--5714,
--6043,
--6352,
--6641,
--6910,
--7160,
--7389,
--7598,
--7786,
--7954,
--8102,
--8230,
--8338,
--8426,
--8495,
--8545,
--8575,
--8587,
--8582,
--8558,
--8517,
--8460,
--8386,
--8297,
--8192,
--8073,
--7940,
--7794,
--7635,
--7464,
--7281,
--7088,
--6885,
--6672,
--6450,
--6221,
--5984,
--5740,
--5490,
--5235,
--4975,
--4711,
--4443,
--4173,
--3901,
--3627,
--3352,
--3077,
--2803,
--2529,
--2257,
--1986,
--1719,
--1454,
--1193,
--935,
--683,
--435,
--192,
-45,
-276,
-501,
-719,
-930,
-1134,
-1331,
-1519,
-1700,
-1873,
-2038,
-2194,
-2342,
-2481,
-2611,
-2733,
-2846,
-2950,
-3046,
-3133,
-3211,
-3281,
-3343,
-3396,
-3441,
-3477,
-3506,
-3527,
-3541,
-3547,
-3546,
-3538,
-3523,
-3502,
-3474,
-3441,
-3401,
-3357,
-3307,
-3252,
-3192,
-3128,
-3060,
-2989,
-2913,
-2835,
-2753,
-2669,
-2583,
-2494,
-2403,
-2311,
-2218,
-2124,
-2028,
-1933,
-1837,
-1741,
-1645,
-1550,
-1455,
-1361,
-1268,
-1176,
-1086,
-997,
-910,
-825,
-741,
-660,
-581,
-504,
-429,
-357,
-287,
-220,
-156,
-94,
-35,
--22,
--75,
--126,
--175,
--220,
--263,
--303,
--341,
--375,
--408,
--437,
--464,
--489,
--511,
--531,
--548,
--564,
--577,
--588,
--597,
--604,
--610,
--613,
--615,
--616,
--614,
--612,
--608,
--603,
--597,
--590,
--582,
--573,
--563,
--553,
--542,
--530,
--518,
--506,
--493,
--480,
--466,
--453,
--439,
--425,
--411,
--398,
--384,
--370,
--357,
--344,
--331,
--318,
--305,
--293,
--281,
--269,
--258,
--247,
--237,
--227,
--217,
--208,
--199,
--190,
--182,
--174,
--167,
--160,
--154,
--147,
--142,
--136,
--131,
--126,
--121,
--117,
--113,
--109,
--106,
--102,
--99,
--96,
--93,
--90,
--87,
--85,
--82,
--80,
--78,
--76,
--74,
--72,
--70,
--68,
--66,
--64,
--62,
--60,
--58,
--57,
--55,
--53,
--51,
--50,
--48,
--46,
--45,
--43,
--41,
--40,
--38,
--36,
--35,
--33,
--31,
--30,
--28,
--27,
--25,
--24,
--22,
--21,
--20,
--18,
--17,
--16,
--15,
--13,
--12,
--11,
--10,
--9,
--9,
--8,
--7,
--6,
-};
-}
diff --git a/services/audioflinger/audio-resampler/filter_coefficients.h b/services/audioflinger/audio-resampler/filter_coefficients.h
new file mode 100644
index 0000000..bf70c63
--- /dev/null
+++ b/services/audioflinger/audio-resampler/filter_coefficients.h
@@ -0,0 +1,285 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <stdlib.h>
+
+namespace android {
+
+// cmd-line: fir -l 7 -s 48000 -c 23400 -n 16 -b 9.62
+const int32_t up_sampler_filter_coefficients[] __attribute__ ((aligned (32))) = {
+ 0x7ccccccd, 0x0323eb7f, 0xfd086246, 0x02b2aa5c, 0xfda45e2c, 0x01fa5183, 0xfe694e12, 0x0137e672, 0xff1c87d3, 0x009ce6d8, 0xff9a68b0, 0x003d150d, 0xffde727a, 0x00106595, 0xfff93679, 0x00021fc5,
+ 0x7cc9b757, 0x022ac835, 0xfd7e3a71, 0x026b7da1, 0xfdd2b905, 0x01db7c90, 0xfe7db77c, 0x012aa7bf, 0xff24dc32, 0x0097dfc9, 0xff9d4ae9, 0x003b8742, 0xffdf38e5, 0x00100be5, 0xfff959f5, 0x0002144b,
+ 0x7cc0773c, 0x01354bc1, 0xfdf365e8, 0x0224726d, 0xfe011d2e, 0x01bc908b, 0xfe923a2b, 0x011d528d, 0xff2d426f, 0x0092cbc0, 0xffa035cc, 0x0039f42e, 0xffe00236, 0x000fb0d2, 0xfff97dfa, 0x000208b0,
+ 0x7cb10d52, 0x0043843f, 0xfe67d5a8, 0x01dd92df, 0xfe2f83c1, 0x019d9230, 0xfea6d2e5, 0x010fe901, 0xff35b924, 0x008dab9d, 0xffa328d4, 0x00385c1d, 0xffe0ce46, 0x000f5471, 0xfff9a27f, 0x0001fcf5,
+ 0x7c9b7afd, 0xff557f58, 0xfedb7ae9, 0x0196e8fe, 0xfe5de5e3, 0x017e8635, 0xfebb7e75, 0x01026d40, 0xff3e3eed, 0x0088803e, 0xffa6237a, 0x0036bf58, 0xffe19cec, 0x000ef6d4, 0xfff9c77d, 0x0001f11e,
+ 0x7c7fc22f, 0xfe6b4a44, 0xff4e471d, 0x01507eb8, 0xfe8c3cc3, 0x015f714d, 0xfed039a8, 0x00f4e16f, 0xff46d266, 0x00834a83, 0xffa9253b, 0x00351e2d, 0xffe26e01, 0x000e980f, 0xfff9eceb, 0x0001e52e,
+ 0x7c5de56a, 0xfd84f1c8, 0xffc02bf2, 0x010a5de2, 0xfeba819d, 0x01405821, 0xfee5014c, 0x00e747b0, 0xff4f722b, 0x007e0b4b, 0xffac2d8f, 0x003378e7, 0xffe3415d, 0x000e3834, 0xfffa12c0, 0x0001d927,
+ 0x7c35e7bb, 0xfca28234, 0x00311b54, 0x00c49034, 0xfee8adba, 0x01213f58, 0xfef9d232, 0x00d9a226, 0xff581cd8, 0x0078c375, 0xffaf3bf2, 0x0031cfd1, 0xffe416d8, 0x000dd758, 0xfffa38f5, 0x0001cd0d,
+ 0x7c07ccbe, 0xfbc40766, 0x00a1076e, 0x007f1f4b, 0xff16ba71, 0x01022b90, 0xff0ea931, 0x00cbf2f0, 0xff60d10b, 0x007373de, 0xffb24fde, 0x00302337, 0xffe4ee4b, 0x000d758d, 0xfffa5f81, 0x0001c0e1,
+ 0x7bd3989d, 0xfae98cc5, 0x010fe2ab, 0x003a14a6, 0xff44a128, 0x00e3215e, 0xff238322, 0x00be3c2d, 0xff698d62, 0x006e1d66, 0xffb568ce, 0x002e7363, 0xffe5c78d, 0x000d12e6, 0xfffa865d, 0x0001b4a8,
+ 0x7b99500c, 0xfa131d41, 0x017d9fb8, 0xfff579a3, 0xff725b54, 0x00c42551, 0xff385ce3, 0x00b07ff8, 0xff72507e, 0x0068c0e9, 0xffb8863e, 0x002cc0a2, 0xffe6a277, 0x000caf76, 0xfffaad81, 0x0001a863,
+ 0x7b58f84d, 0xf940c355, 0x01ea3184, 0xffb15783, 0xff9fe27d, 0x00a53bed, 0xff4d3358, 0x00a2c06b, 0xff7b18fe, 0x00635f45, 0xffbba7aa, 0x002b0b3d, 0xffe77ee2, 0x000c4b50, 0xfffad4e4, 0x00019c15,
+ 0x7b12972d, 0xf8728902, 0x02558b43, 0xff6db764, 0xffcd303b, 0x008669ae, 0xff620368, 0x0094ff9b, 0xff83e586, 0x005df954, 0xffbecc8d, 0x00295380, 0xffe85ca7, 0x000be687, 0xfffafc7f, 0x00018fc1,
+ 0x7ac63304, 0xf7a877d4, 0x02bfa06d, 0xff2aa243, 0xfffa3e37, 0x0067b303, 0xff76ca02, 0x00873f9b, 0xff8cb4bb, 0x00588ff1, 0xffc1f465, 0x002799b3, 0xffe93b9e, 0x000b812d, 0xfffb244a, 0x0001836a,
+ 0x7a73d2b5, 0xf6e298db, 0x032864c1, 0xfee820f8, 0x00270631, 0x00491c54, 0xff8b841a, 0x0079827a, 0xff958542, 0x005323f7, 0xffc51eaf, 0x0025de22, 0xffea1ba2, 0x000b1b55, 0xfffb4c3e, 0x00017712,
+ 0x7a1b7daa, 0xf620f4b2, 0x038fcc44, 0xfea63c38, 0x005381fa, 0x002aa9fa, 0xffa02eac, 0x006bca44, 0xff9e55c6, 0x004db63c, 0xffc84ae9, 0x00242115, 0xffeafc8b, 0x000ab510, 0xfffb7452, 0x00016abb,
+ 0x79bd3bd8, 0xf5639376, 0x03f5cb46, 0xfe64fc93, 0x007fab77, 0x000c6043, 0xffb4c6b9, 0x005e1900, 0xffa724f0, 0x00484799, 0xffcb7893, 0x002262d6, 0xffebde33, 0x000a4e72, 0xfffb9c80, 0x00015e68,
+ 0x795915bc, 0xf4aa7cce, 0x045a565c, 0xfe246a72, 0x00ab7ca6, 0xffee4372, 0xffc9494b, 0x005070b0, 0xffaff16f, 0x0042d8e1, 0xffcea72c, 0x0020a3ad, 0xffecc075, 0x0009e78c, 0xfffbc4bf, 0x0001521b,
+ 0x78ef1457, 0xf3f5b7e4, 0x04bd6269, 0xfde48e17, 0x00d6ef99, 0xffd057bb, 0xffddb374, 0x0042d353, 0xffb8b9f3, 0x003d6aea, 0xffd1d635, 0x001ee3e1, 0xffeda32a, 0x00098070, 0xfffbed0a, 0x000145d7,
+ 0x787f4134, 0xf3454b6a, 0x051ee498, 0xfda56f9c, 0x0101fe7a, 0xffb2a145, 0xfff2024e, 0x003542e2, 0xffc17d30, 0x0037fe85, 0xffd50530, 0x001d23b9, 0xffee862e, 0x0009192f, 0xfffc1558, 0x0001399e,
+ 0x7809a65e, 0xf2993d95, 0x057ed264, 0xfd6716f2, 0x012ca389, 0xff952429, 0x000632fa, 0x0027c151, 0xffca39dd, 0x00329483, 0xffd833a0, 0x001b637e, 0xffef695c, 0x0008b1db, 0xfffc3da2, 0x00012d72,
+ 0x778e4e68, 0xf1f19421, 0x05dd218f, 0xfd298be0, 0x0156d920, 0xff77e470, 0x001a42a4, 0x001a508e, 0xffd2eeb3, 0x002d2db0, 0xffdb6109, 0x0019a373, 0xfff04c8f, 0x00084a86, 0xfffc65e2, 0x00012155,
+ 0x770d4466, 0xf14e544f, 0x0639c82d, 0xfcecd602, 0x018099b2, 0xff5ae614, 0x002e2e82, 0x000cf281, 0xffdb9a70, 0x0027cada, 0xffde8cf1, 0x0017e3df, 0xfff12fa3, 0x0007e33f, 0xfffc8e11, 0x0001154a,
+ 0x768693ec, 0xf0af82e4, 0x0694bca0, 0xfcb0fcca, 0x01a9dfcc, 0xff3e2d01, 0x0041f3d2, 0xffffa90e, 0xffe43bd5, 0x00226ccb, 0xffe1b6dd, 0x00162507, 0xfff21275, 0x00077c17, 0xfffcb628, 0x00010952,
+ 0x75fa4911, 0xf015242b, 0x06edf595, 0xfc76077b, 0x01d2a615, 0xff21bd11, 0x00558fdc, 0xfff27611, 0xffecd1a6, 0x001d144a, 0xffe4de56, 0x0014672d, 0xfff2f4e0, 0x00071520, 0xfffcde20, 0x0000fd6f,
+ 0x75687068, 0xef7f3bf5, 0x07456a0e, 0xfc3bfd2e, 0x01fae74e, 0xff059a0e, 0x0068fff3, 0xffe55b60, 0xfff55aae, 0x0017c21c, 0xffe802e6, 0x0012aa95, 0xfff3d6c3, 0x0006ae6a, 0xfffd05f3, 0x0000f1a4,
+ 0x74d11703, 0xeeedcd98, 0x079b1158, 0xfc02e4cc, 0x02229e57, 0xfee9c7af, 0x007c4177, 0xffd85ac9, 0xfffdd5b8, 0x00127704, 0xffeb2416, 0x0010ef82, 0xfff4b7fb, 0x00064804, 0xfffd2d9b, 0x0000e5f3,
+ 0x74344a70, 0xee60dbee, 0x07eee314, 0xfbcac510, 0x0249c629, 0xfece499d, 0x008f51cf, 0xffcb7615, 0x00064197, 0x000d33c3, 0xffee4174, 0x000f3633, 0xfff59866, 0x0005e1fe, 0xfffd5511, 0x0000da5c,
+ 0x739218b8, 0xedd86958, 0x0840d732, 0xfb93a486, 0x027059da, 0xfeb3236b, 0x00a22e71, 0xffbeaf06, 0x000e9d1f, 0x0007f915, 0xfff15a8d, 0x000d7eea, 0xfff677e2, 0x00057c68, 0xfffd7c4f, 0x0000cee3,
+ 0x72ea905a, 0xed5477be, 0x0890e5f7, 0xfb5d898c, 0x029654a0, 0xfe98589b, 0x00b4d4dd, 0xffb20754, 0x0016e72c, 0x0002c7b6, 0xfff46ef1, 0x000bc9e6, 0xfff75650, 0x00051750, 0xfffda350, 0x0000c388,
+ 0x723dc051, 0xecd5088e, 0x08df07f6, 0xfb287a4d, 0x02bbb1cc, 0xfe7dec9c, 0x00c7429f, 0xffa580b1, 0x001f1e9b, 0xfffda05c, 0xfff77e31, 0x000a1765, 0xfff8338e, 0x0004b2c7, 0xfffdca0d, 0x0000b84d,
+ 0x718bb80b, 0xec5a1cbc, 0x092b3617, 0xfaf47cc4, 0x02e06ccf, 0xfe63e2cc, 0x00d97550, 0xff991cc9, 0x00274253, 0xfff883be, 0xfffa87df, 0x000867a5, 0xfff90f7c, 0x00044eda, 0xfffdf080, 0x0000ad34,
+ 0x70d4876b, 0xebe3b4c5, 0x09756994, 0xfac196bb, 0x03048139, 0xfe4a3e70, 0x00eb6a95, 0xff8cdd3c, 0x002f513a, 0xfff3728d, 0xfffd8b92, 0x0006bae1, 0xfff9e9fd, 0x0003eb98, 0xfffe16a6, 0x0000a23f,
+ 0x70183ec5, 0xeb71d0ab, 0x09bd9bfb, 0xfa8fcdca, 0x0327eab8, 0xfe3102bd, 0x00fd2022, 0xff80c3a4, 0x00374a40, 0xffee6d78, 0x000088df, 0x00051157, 0xfffac2f0, 0x0003890e, 0xfffe3c76, 0x0000976e,
+ 0x6f56eee1, 0xeb046ffc, 0x0a03c72b, 0xfa5f2755, 0x034aa51b, 0xfe1832d4, 0x010e93b5, 0xff74d194, 0x003f2c57, 0xffe97529, 0x00037f60, 0x00036b3f, 0xfffb9a38, 0x0003274c, 0xfffe61ee, 0x00008cc4,
+ 0x6e90a8f2, 0xea9b91cc, 0x0a47e559, 0xfa2fa890, 0x036cac52, 0xfdffd1bd, 0x011fc31c, 0xff690894, 0x0046f679, 0xffe48a4a, 0x00066eae, 0x0001c8d2, 0xfffc6fb8, 0x0002c65d, 0xfffe8707, 0x00008241,
+ 0x6dc57e9b, 0xea3734bb, 0x0a89f10c, 0xfa015679, 0x038dfc6c, 0xfde7e26f, 0x0130ac31, 0xff5d6a24, 0x004ea7a3, 0xffdfad7f, 0x00095666, 0x00002a4a, 0xfffd4352, 0x00026650, 0xfffeabbd, 0x000077e8,
+ 0x6cf581e8, 0xe9d756f3, 0x0ac9e521, 0xf9d435dc, 0x03ae919a, 0xfdd067ca, 0x01414cdd, 0xff51f7bb, 0x00563edb, 0xffdadf69, 0x000c3627, 0xfffe8fdc, 0xfffe14eb, 0x00020730, 0xfffed00a, 0x00006db9,
+ 0x6c20c550, 0xe97bf627, 0x0b07bcc6, 0xf9a84b50, 0x03ce682d, 0xfdb96498, 0x0151a317, 0xff46b2c7, 0x005dbb29, 0xffd620a6, 0x000f0d91, 0xfffcf9be, 0xfffee466, 0x0001a90b, 0xfffef3ea, 0x000063b5,
+ 0x6b475bb0, 0xe9250f99, 0x0b437380, 0xf97d9b37, 0x03ed7c9a, 0xfda2db8c, 0x0161ace5, 0xff3b9cad, 0x00651b9c, 0xffd171d1, 0x0011dc47, 0xfffb6825, 0xffffb1aa, 0x00014bed, 0xffff1759, 0x000059dd,
+ 0x6a69584a, 0xe8d2a017, 0x0b7d0525, 0xf95429c0, 0x040bcb77, 0xfd8ccf46, 0x01716859, 0xff30b6c8, 0x006c5f4b, 0xffccd380, 0x0014a1ee, 0xfff9db44, 0x00007c9c, 0x0000efe1, 0xffff3a53, 0x00005033,
+ 0x6986cec4, 0xe884a3fb, 0x0bb46de2, 0xf92bfae4, 0x0429517b, 0xfd77424c, 0x0180d397, 0xff260269, 0x00738551, 0xffc84645, 0x00175e2d, 0xfff8534d, 0x00014521, 0x000094f3, 0xffff5cd2, 0x000046b8,
+ 0x689fd324, 0xe83b1731, 0x0be9aa34, 0xf9051266, 0x04460b81, 0xfd62370e, 0x018fecd1, 0xff1b80da, 0x007a8cd0, 0xffc3cab1, 0x001a10ad, 0xfff6d070, 0x00020b23, 0x00003b2e, 0xffff7ed3, 0x00003d6c,
+ 0x67b479cf, 0xe7f5f531, 0x0c1cb6ef, 0xf8df73d6, 0x0461f688, 0xfd4dafe6, 0x019eb246, 0xff113358, 0x008174ef, 0xffbf614e, 0x001cb91a, 0xfff552de, 0x0002ce87, 0xffffe29d, 0xffffa052, 0x00003450,
+ 0x66c4d787, 0xe7b53908, 0x0c4d913a, 0xf8bb228c, 0x047d0fb1, 0xfd39af17, 0x01ad2249, 0xff071b16, 0x00883cdc, 0xffbb0aa3, 0x001f5723, 0xfff3dac3, 0x00038f37, 0xffff8b4b, 0xffffc14b, 0x00002b66,
+ 0x65d10168, 0xe778dd50, 0x0c7c368d, 0xf89821ac, 0x0497543f, 0xfd2636ca, 0x01bb3b37, 0xfefd3941, 0x008ee3cd, 0xffb6c735, 0x0021ea76, 0xfff2684e, 0x00044d1b, 0xffff3540, 0xffffe1bc, 0x000022ad,
+ 0x64d90ce7, 0xe740dc3c, 0x0ca8a4b7, 0xf8767422, 0x04b0c19a, 0xfd134913, 0x01c8fb81, 0xfef38ef6, 0x009568fc, 0xffb29782, 0x002472c8, 0xfff0fba9, 0x0005081f, 0xfffee088, 0x0000019f, 0x00001a28,
+ 0x63dd0fcd, 0xe70d2f8d, 0x0cd2d9d5, 0xf8561ca7, 0x04c9554e, 0xfd00e7ec, 0x01d661a6, 0xfeea1d4c, 0x009bcbab, 0xffae7c06, 0x0026efcc, 0xffef94fe, 0x0005c02c, 0xfffe8d2c, 0x000020f3, 0x000011d5,
+ 0x62dd2039, 0xe6ddd09f, 0x0cfad45a, 0xf8371dbb, 0x04e10d0a, 0xfcef153a, 0x01e36c34, 0xfee0e54e, 0x00a20b23, 0xffaa7538, 0x0029613a, 0xffee3477, 0x0006752d, 0xfffe3b35, 0x00003fb3, 0x000009b6,
+ 0x61d95497, 0xe6b2b862, 0x0d209309, 0xf81979ab, 0x04f7e6a2, 0xfcddd2c7, 0x01f019cb, 0xfed7e7fd, 0x00a826b2, 0xffa6838c, 0x002bc6cd, 0xffecda3b, 0x0007270f, 0xfffdeaaa, 0x00005ddd, 0x000001cc,
+ 0x60d1c3a6, 0xe68bdf5e, 0x0d4414f9, 0xf7fd328c, 0x050de00d, 0xfccd2246, 0x01fc691b, 0xfecf2650, 0x00ae1dae, 0xffa2a770, 0x002e2040, 0xffeb866f, 0x0007d5bf, 0xfffd9b96, 0x00007b6f, 0xfffffa17,
+ 0x5fc68470, 0xe6693db5, 0x0d65598f, 0xf7e24a3c, 0x0522f766, 0xfcbd0551, 0x020858e2, 0xfec6a130, 0x00b3ef73, 0xff9ee150, 0x00306d52, 0xffea3939, 0x0008812a, 0xfffd4dff, 0x00009865, 0xfffff297,
+ 0x5eb7ae46, 0xe64acb24, 0x0d846084, 0xf7c8c267, 0x05372aee, 0xfcad7d6b, 0x0213e7f0, 0xfebe5980, 0x00b99b65, 0xff9b3192, 0x0032adc4, 0xffe8f2bb, 0x0009293e, 0xfffd01ee, 0x0000b4bd, 0xffffeb4c,
+ 0x5da558c5, 0xe6307f05, 0x0da129df, 0xf7b09c7f, 0x054a7909, 0xfc9e8bfd, 0x021f1526, 0xfeb65015, 0x00bf20ee, 0xff979898, 0x0034e15b, 0xffe7b317, 0x0009cdeb, 0xfffcb769, 0x0000d074, 0xffffe438,
+ 0x5c8f9bcb, 0xe61a504f, 0x0dbbb5f6, 0xf799d9c4, 0x055ce03f, 0xfc903258, 0x0229df75, 0xfeae85bb, 0x00c47f7f, 0xff9416c1, 0x003707dc, 0xffe67a6f, 0x000a6f20, 0xfffc6e78, 0x0000eb89, 0xffffdd5a,
+ 0x5b768f7a, 0xe6083599, 0x0dd40571, 0xf7847b3d, 0x056e5f3d, 0xfc8271b4, 0x023445dd, 0xfea6fb32, 0x00c9b691, 0xff90ac66, 0x00392111, 0xffe548e0, 0x000b0cce, 0xfffc2720, 0x000105f9, 0xffffd6b2,
+ 0x5a5a4c32, 0xe5fa2519, 0x0dea1943, 0xf77081be, 0x057ef4d3, 0xfc754b32, 0x023e4772, 0xfe9fb12e, 0x00cec5a1, 0xff8d59dd, 0x003b2cc5, 0xffe41e88, 0x000ba6e5, 0xfffbe169, 0x00011fc3, 0xffffd041,
+ 0x593aea93, 0xe5f014aa, 0x0dfdf2ae, 0xf75dede5, 0x058e9ff8, 0xfc68bfd7, 0x0247e354, 0xfe98a85b, 0x00d3ac38, 0xff8a1f77, 0x003d2ac6, 0xffe2fb83, 0x000c3d59, 0xfffb9d59, 0x000138e4, 0xffffca06,
+ 0x58188376, 0xe5e9f9ca, 0x0e0f9342, 0xf74cc01c, 0x059d5fc5, 0xfc5cd092, 0x025118b8, 0xfe91e159, 0x00d869e1, 0xff86fd81, 0x003f1ae4, 0xffe1dfec, 0x000cd01b, 0xfffb5af3, 0x0001515c, 0xffffc402,
+ 0x56f32fea, 0xe5e7c99e, 0x0e1efcdb, 0xf73cf898, 0x05ab3377, 0xfc517e38, 0x0259e6e1, 0xfe8b5cba, 0x00dcfe32, 0xff83f443, 0x0040fcf3, 0xffe0cbdc, 0x000d5f1f, 0xfffb1a3f, 0x00016928, 0xffffbe35,
+ 0x55cb0935, 0xe5e978f0, 0x0e2c319d, 0xf72e9758, 0x05b81a70, 0xfc46c987, 0x02624d23, 0xfe851b09, 0x00e168c5, 0xff810401, 0x0042d0c9, 0xffdfbf6b, 0x000dea5a, 0xfffadb40, 0x00018048, 0xffffb89f,
+ 0x54a028d0, 0xe5eefc35, 0x0e3733fc, 0xf7219c2a, 0x05c41435, 0xfc3cb323, 0x026a4ae5, 0xfe7f1cc4, 0x00e5a93c, 0xff7e2cfb, 0x0044963d, 0xffdebaaf, 0x000e71c1, 0xfffa9dfa, 0x000196ba, 0xffffb340,
+ 0x5372a862, 0xe5f8478d, 0x0e4006b2, 0xf71606a6, 0x05cf2070, 0xfc333b97, 0x0271df9c, 0xfe79625e, 0x00e9bf43, 0xff7b6f6c, 0x00464d2b, 0xffddbdbd, 0x000ef549, 0xfffa6273, 0x0001ac7d, 0xffffae17,
+ 0x5242a1c1, 0xe6054ec6, 0x0e46acc4, 0xf70bd632, 0x05d93eee, 0xfc2a6356, 0x02790ace, 0xfe73ec40, 0x00edaa88, 0xff78cb8c, 0x0047f571, 0xffdcc8a9, 0x000f74e9, 0xfffa28ad, 0x0001c191, 0xffffa924,
+ 0x51102eec, 0xe616055a, 0x0e4b297c, 0xf7030a01, 0x05e26f9f, 0xfc222abb, 0x027fcc12, 0xfe6ebac6, 0x00f16ac4, 0xff76418b, 0x00498eed, 0xffdbdb84, 0x000ff098, 0xfff9f0ac, 0x0001d5f4, 0xffffa467,
+ 0x4fdb6a09, 0xe62a5e76, 0x0e4d806f, 0xf6fba113, 0x05eab296, 0xfc1a9208, 0x02862311, 0xfe69ce43, 0x00f4ffb6, 0xff73d199, 0x004b1984, 0xffdaf65e, 0x0010684e, 0xfff9ba73, 0x0001e9a7, 0xffff9fe0,
+ 0x4ea46d66, 0xe6424cf8, 0x0e4db575, 0xf6f59a36, 0x05f20809, 0xfc139968, 0x028c0f83, 0xfe6526fe, 0x00f86924, 0xff717bdf, 0x004c951b, 0xffda1948, 0x0010dc05, 0xfff98604, 0x0001fca8, 0xffff9b8f,
+ 0x4d6b536f, 0xe65dc373, 0x0e4bccac, 0xf6f0f407, 0x05f87053, 0xfc0d40ec, 0x0291912f, 0xfe60c533, 0x00fba6da, 0xff6f4083, 0x004e0199, 0xffd9444e, 0x00114bb4, 0xfff95363, 0x00020ef7, 0xffff9773,
+ 0x4c3036b2, 0xe67cb42f, 0x0e47ca78, 0xf6edacf2, 0x05fdebee, 0xfc07888e, 0x0296a7f0, 0xfe5ca913, 0x00feb8ad, 0xff6d1fa5, 0x004f5ee9, 0xffd8777d, 0x0011b757, 0xfff92290, 0x00022095, 0xffff938c,
+ 0x4af331d9, 0xe69f112f, 0x0e41b37c, 0xf6ebc332, 0x06027b78, 0xfc027031, 0x029b53af, 0xfe58d2c5, 0x01019e78, 0xff6b1961, 0x0050acf7, 0xffd7b2e0, 0x00121ee9, 0xfff8f38e, 0x00023181, 0xffff8fd9,
+ 0x49b45fa8, 0xe6c4cc2e, 0x0e398c9f, 0xf6eb34d4, 0x06061fb2, 0xfbfdf79e, 0x029f9466, 0xfe554265, 0x0104581c, 0xff692dd2, 0x0051ebb4, 0xffd6f67f, 0x00128265, 0xfff8c65d, 0x000241bb, 0xffff8c5a,
+ 0x4873daf7, 0xe6edd6a4, 0x0e2f5b0b, 0xf6ebffb2, 0x0608d97c, 0xfbfa1e88, 0x02a36a1e, 0xfe51f802, 0x0106e583, 0xff675d09, 0x00531b12, 0xffd64264, 0x0012e1c8, 0xfff89b00, 0x00025143, 0xffff890e,
+ 0x4731beb7, 0xe71a21c7, 0x0e232425, 0xf6ee217b, 0x060aa9da, 0xfbf6e48c, 0x02a6d4f0, 0xfe4ef3a4, 0x0109469d, 0xff65a718, 0x00543b04, 0xffd59695, 0x00133d0e, 0xfff87176, 0x0002601b, 0xffff85f5,
+ 0x45ee25e7, 0xe7499e8f, 0x0e14ed93, 0xf6f197ad, 0x060b91ee, 0xfbf4492d, 0x02a9d508, 0xfe4c3546, 0x010b7b61, 0xff640c08, 0x00554b83, 0xffd4f316, 0x00139436, 0xfff849c0, 0x00026e41, 0xffff830e,
+ 0x44a92b96, 0xe77c3db4, 0x0e04bd39, 0xf6f65f9b, 0x060b92ff, 0xfbf24bd9, 0x02ac6a9e, 0xfe49bcd9, 0x010d83cb, 0xff628be3, 0x00564c88, 0xffd457ec, 0x0013e73e, 0xfff823dd, 0x00027bb8, 0xffff805a,
+ 0x4362eadc, 0xe7b1efb4, 0x0df29936, 0xf6fc766a, 0x060aae6e, 0xfbf0ebe7, 0x02ae95fb, 0xfe478a42, 0x010f5fe2, 0xff6126a9, 0x00573e0f, 0xffd3c519, 0x00143626, 0xfff7ffce, 0x0002887f, 0xffff7dd6,
+ 0x421b7edf, 0xe7eaa4d4, 0x0dde87e2, 0xf703d912, 0x0608e5c2, 0xfbf02896, 0x02b05779, 0xfe459d5e, 0x01110faf, 0xff5fdc5b, 0x00582016, 0xffd33a9e, 0x001480ec, 0xfff7dd92, 0x00029497, 0xffff7b82,
+ 0x40d302c5, 0xe8264d21, 0x0dc88fd2, 0xf70c8461, 0x06063a9d, 0xfbf00112, 0x02b1af7f, 0xfe43f5ff, 0x01129344, 0xff5eacf3, 0x0058f29f, 0xffd2b87c, 0x0014c792, 0xfff7bd28, 0x0002a002, 0xffff795f,
+ 0x3f8991bd, 0xe864d874, 0x0db0b7d1, 0xf71674fa, 0x0602aec3, 0xfbf0746e, 0x02b29e84, 0xfe4293ec, 0x0113eabb, 0xff5d9867, 0x0059b5ad, 0xffd23eaf, 0x00150a19, 0xfff79e8f, 0x0002aac0, 0xffff776a,
+ 0x3e3f46f2, 0xe8a63671, 0x0d9706e1, 0xf721a756, 0x05fe4414, 0xfbf181a9, 0x02b3250f, 0xfe4176e2, 0x01151632, 0xff5c9eaa, 0x005a6946, 0xffd1cd37, 0x00154883, 0xfff781c5, 0x0002b4d2, 0xffff75a3,
+ 0x3cf43d8f, 0xe8ea568f, 0x0d7b843b, 0xf72e17c4, 0x05f8fc8f, 0xfbf327ab, 0x02b343b5, 0xfe409e95, 0x011615ce, 0xff5bbfaa, 0x005b0d72, 0xffd1640e, 0x001582d3, 0xfff766c8, 0x0002be3b, 0xffff740a,
+ 0x3ba890b9, 0xe9312813, 0x0d5e3749, 0xf73bc26b, 0x05f2da52, 0xfbf56549, 0x02b2fb1a, 0xfe400aae, 0x0116e9bc, 0xff5afb53, 0x005ba23b, 0xffd1032f, 0x0015b90b, 0xfff74d97, 0x0002c6fa, 0xffff729e,
+ 0x3a5c5b8e, 0xe97a9a17, 0x0d3f27ab, 0xf74aa34c, 0x05ebdf97, 0xfbf83941, 0x02b24bf1, 0xfe3fbacd, 0x0117922f, 0xff5a5189, 0x005c27af, 0xffd0aa93, 0x0015eb2f, 0xfff7362f, 0x0002cf12, 0xffff715d,
+ 0x390fb920, 0xe9c69b8c, 0x0d1e5d32, 0xf75ab63f, 0x05e40eb3, 0xfbfba23f, 0x02b136f9, 0xfe3fae87, 0x01180f5d, 0xff59c230, 0x005c9ddc, 0xffd05a33, 0x00161944, 0xfff7208d, 0x0002d684, 0xffff7047,
+ 0x37c2c474, 0xea151b3a, 0x0cfbdfdd, 0xf76bf6f7, 0x05db6a19, 0xfbff9ed7, 0x02afbd02, 0xfe3fe569, 0x01186187, 0xff594d27, 0x005d04d4, 0xffd01205, 0x0016434f, 0xfff70caf, 0x0002dd53, 0xffff6f5c,
+ 0x36759880, 0xea6607c4, 0x0cd7b7dd, 0xf77e6103, 0x05d1f459, 0xfc042d8e, 0x02addee8, 0xfe405ef6, 0x011888f2, 0xff58f249, 0x005d5cab, 0xffcfd1ff, 0x00166956, 0xfff6fa92, 0x0002e37e, 0xffff6e99,
+ 0x35285026, 0xeab94fa9, 0x0cb1ed8c, 0xf791efcb, 0x05c7b01a, 0xfc094cd2, 0x02ab9d96, 0xfe411aa8, 0x011885e7, 0xff58b16c, 0x005da575, 0xffcf9a15, 0x00168b5e, 0xfff6ea31, 0x0002e90a, 0xffff6dff,
+ 0x33db0631, 0xeb0ee148, 0x0c8a8973, 0xf7a69e96, 0x05bca021, 0xfc0efafe, 0x02a8fa03, 0xfe4217ef, 0x011858b9, 0xff588a65, 0x005ddf4c, 0xffcf6a3b, 0x0016a96f, 0xfff6db89, 0x0002edf6, 0xffff6d8d,
+ 0x328dd556, 0xeb66aae0, 0x0c619444, 0xf7bc6889, 0x05b0c74b, 0xfc15365c, 0x02a5f535, 0xfe435633, 0x011801be, 0xff587d03, 0x005e0a48, 0xffcf4262, 0x0016c390, 0xfff6ce97, 0x0002f246, 0xffff6d40,
+ 0x3140d82e, 0xebc09a94, 0x0c3716da, 0xf7d348a4, 0x05a42890, 0xfc1bfd22, 0x02a2903e, 0xfe44d4d3, 0x01178152, 0xff588913, 0x005e2687, 0xffcf227b, 0x0016d9c9, 0xfff6c356, 0x0002f5fc, 0xffff6d1a,
+ 0x2ff42933, 0xec1c9e6d, 0x0c0b1a37, 0xf7eb39cc, 0x0596c6ff, 0xfc234d75, 0x029ecc3c, 0xfe469325, 0x0116d7d7, 0xff58ae5d, 0x005e3427, 0xffcf0a77, 0x0016ec22, 0xfff6b9c1, 0x0002f919, 0xffff6d17,
+ 0x2ea7e2c0, 0xec7aa45b, 0x0bdda783, 0xf80436c0, 0x0588a5bf, 0xfc2b2567, 0x029aaa5a, 0xfe489077, 0x011605b5, 0xff58eca8, 0x005e3347, 0xffcefa44, 0x0016faa5, 0xfff6b1d5, 0x0002fba0, 0xffff6d38,
+ 0x2d5c1f0e, 0xecda9a39, 0x0baec80a, 0xf81e3a25, 0x0579c812, 0xfc3382fb, 0x02962bd1, 0xfe4acc0e, 0x01150b5a, 0xff5943b4, 0x005e240a, 0xffcef1cf, 0x0017055b, 0xfff6ab8c, 0x0002fd94, 0xffff6d7c,
+ 0x2c10f82d, 0xed3c6dce, 0x0b7e853c, 0xf8393e81, 0x056a314b, 0xfc3c6420, 0x029151e3, 0xfe4d4526, 0x0113e937, 0xff59b340, 0x005e0694, 0xffcef106, 0x00170c4f, 0xfff6a6e2, 0x0002fef6, 0xffff6de2,
+ 0x2ac68807, 0xeda00cd1, 0x0b4ce8a8, 0xf8553e3c, 0x0559e4da, 0xfc45c6b6, 0x028c1de0, 0xfe4ffaf6, 0x01129fc5, 0xff5a3b09, 0x005ddb0b, 0xffcef7d4, 0x00170f8a, 0xfff6a3d0, 0x0002ffc9, 0xffff6e67,
+ 0x297ce85a, 0xee0564e8, 0x0b19fbfe, 0xf87233a4, 0x0548e63f, 0xfc4fa88f, 0x02869122, 0xfe52ecab, 0x01112f81, 0xff5adac6, 0x005da198, 0xffcf0623, 0x00170f18, 0xfff6a252, 0x00030010, 0xffff6f0d,
+ 0x283432b9, 0xee6c63ad, 0x0ae5c90b, 0xf89018eb, 0x05373912, 0xfc5a076a, 0x0280ad0f, 0xfe561969, 0x010f98eb, 0xff5b922d, 0x005d5a62, 0xffcf1bde, 0x00170b04, 0xfff6a262, 0x0002ffcd, 0xffff6fd1,
+ 0x26ec8083, 0xeed4f6b0, 0x0ab059bc, 0xf8aee828, 0x0524e100, 0xfc64e0f9, 0x027a7318, 0xfe598050, 0x010ddc8c, 0xff5c60ee, 0x005d0597, 0xffcf38ec, 0x0017035a, 0xfff6a3f9, 0x0002ff03, 0xffff70b2,
+ 0x25a5eae8, 0xef3f0b78, 0x0a79b814, 0xf8ce9b5d, 0x0511e1c6, 0xfc7032de, 0x0273e4b8, 0xfe5d2075, 0x010bfaee, 0xff5d46bb, 0x005ca363, 0xffcf5d36, 0x0016f828, 0xfff6a713, 0x0002fdb4, 0xffff71b0,
+ 0x24608ae2, 0xefaa8f87, 0x0a41ee32, 0xf8ef2c71, 0x04fe3f39, 0xfc7bfaad, 0x026d0374, 0xfe60f8ea, 0x0109f4a2, 0xff5e433e, 0x005c33f6, 0xffcf88a2, 0x0016e979, 0xfff6aba9, 0x0002fbe4, 0xffff72c9,
+ 0x231c7932, 0xf017705a, 0x0a09064e, 0xf9109535, 0x04e9fd3c, 0xfc8835ed, 0x0265d0dd, 0xfe6508b6, 0x0107ca3c, 0xff5f5621, 0x005bb77f, 0xffcfbb17, 0x0016d75b, 0xfff6b1b4, 0x0002f995, 0xffff73fc,
+ 0x21d9ce63, 0xf0859b6e, 0x09cf0ab4, 0xf932cf65, 0x04d51fc6, 0xfc94e216, 0x025e4e8b, 0xfe694edd, 0x01057c57, 0xff607f0b, 0x005b2e31, 0xffcff478, 0x0016c1dc, 0xfff6b92d, 0x0002f6c9, 0xffff7549,
+ 0x2098a2bf, 0xf0f4fe3d, 0x099405c6, 0xf955d4a7, 0x04bfaadf, 0xfca1fc96, 0x02567e22, 0xfe6dca58, 0x01030b8e, 0xff61bd9f, 0x005a9840, 0xffd034ac, 0x0016a90a, 0xfff6c20f, 0x0002f385, 0xffff76ae,
+ 0x1f590e55, 0xf1658649, 0x095801f8, 0xf9799e8f, 0x04a9a29e, 0xfcaf82ca, 0x024e614c, 0xfe727a1f, 0x01007885, 0xff631180, 0x0059f5e1, 0xffd07b95, 0x00168cf2, 0xfff6cc52, 0x0002efca, 0xffff782a,
+ 0x1e1b28f2, 0xf1d72114, 0x091b09d1, 0xf99e269e, 0x04930b2b, 0xfcbd7206, 0x0245f9bf, 0xfe775d1f, 0x00fdc3e0, 0xff647a4b, 0x0059474a, 0xffd0c915, 0x00166da5, 0xfff6d7f0, 0x0002eb9c, 0xffff79bc,
+ 0x1cdf0a20, 0xf249bc2c, 0x08dd27e6, 0xf9c36642, 0x047be8bc, 0xfccbc793, 0x023d4937, 0xfe7c7243, 0x00faee49, 0xff65f79e, 0x00588cb4, 0xffd11d0f, 0x00164b32, 0xfff6e4e1, 0x0002e6fe, 0xffff7b63,
+ 0x1ba4c923, 0xf2bd4523, 0x089e66dd, 0xf9e956da, 0x04643f95, 0xfcda80ad, 0x0234517a, 0xfe81b86d, 0x00f7f86e, 0xff678912, 0x0057c658, 0xffd17764, 0x001625a7, 0xfff6f31d, 0x0002e1f3, 0xffff7d1f,
+ 0x1a6c7cf9, 0xf331a99b, 0x085ed167, 0xfa0ff1b6, 0x044c1409, 0xfce99a86, 0x022b1455, 0xfe872e7c, 0x00f4e2ff, 0xff692e3f, 0x0056f471, 0xffd1d7f5, 0x0015fd15, 0xfff7029f, 0x0002dc7d, 0xffff7eed,
+ 0x19363c54, 0xf3a6d741, 0x081e7241, 0xfa373017, 0x04336a75, 0xfcf91246, 0x0221939d, 0xfe8cd349, 0x00f1aeb2, 0xff6ae6ba, 0x0056173b, 0xffd23ea1, 0x0015d18b, 0xfff7135d, 0x0002d6a0, 0xffff80cd,
+ 0x18021d9d, 0xf41cbbd3, 0x07dd5430, 0xfa5f0b30, 0x041a4744, 0xfd08e50c, 0x0217d12d, 0xfe92a5a7, 0x00ee5c3e, 0xff6cb218, 0x00552ef3, 0xffd2ab47, 0x0015a31b, 0xfff72551, 0x0002d060, 0xffff82bf,
+ 0x16d036eb, 0xf493451f, 0x079b8203, 0xfa877c29, 0x0400aeec, 0xfd190fed, 0x020dcee8, 0xfe98a466, 0x00eaec5e, 0xff6e8fe9, 0x00543bd8, 0xffd31dc7, 0x001571d5, 0xfff73873, 0x0002c9be, 0xffff84c0,
+ 0x15a09e09, 0xf50a610a, 0x0759068f, 0xfab07c1d, 0x03e6a5ee, 0xfd298ff6, 0x02038eb7, 0xfe9ece4f, 0x00e75fd1, 0xff707fbd, 0x00533e29, 0xffd395fd, 0x00153dca, 0xfff74cba, 0x0002c2be, 0xffff86d0,
+ 0x1473686d, 0xf581fd8b, 0x0715ecae, 0xfada0420, 0x03cc30d4, 0xfd3a622b, 0x01f9128a, 0xfea52227, 0x00e3b758, 0xff728121, 0x00523626, 0xffd413c9, 0x0015070b, 0xfff76220, 0x0002bb64, 0xffff88ee,
+ 0x1348ab3a, 0xf5fa08b5, 0x06d23f3d, 0xfb040d3b, 0x03b15431, 0xfd4b8389, 0x01ee5c55, 0xfeab9eb2, 0x00dff3b7, 0xff7493a2, 0x00512412, 0xffd49705, 0x0014cdab, 0xfff7789c, 0x0002b3b3, 0xffff8b19,
+ 0x12207b3e, 0xf67270b1, 0x068e091c, 0xfb2e906f, 0x039614a1, 0xfd5cf105, 0x01e36e14, 0xfeb242ac, 0x00dc15b4, 0xff76b6ca, 0x0050082f, 0xffd51f90, 0x001491b9, 0xfff79026, 0x0002abad, 0xffff8d50,
+ 0x10faecee, 0xf6eb23c6, 0x0649552a, 0xfb5986b6, 0x037a76c7, 0xfd6ea790, 0x01d849c7, 0xfeb90cce, 0x00d81e1a, 0xff78ea20, 0x004ee2c1, 0xffd5ad44, 0x00145349, 0xfff7a8b6, 0x0002a357, 0xffff8f92,
+ 0x0fd81464, 0xf7641059, 0x06042e45, 0xfb84e906, 0x035e7f4e, 0xfd80a411, 0x01ccf173, 0xfebffbd0, 0x00d40db3, 0xff7b2d2d, 0x004db40c, 0xffd63ffe, 0x0014126c, 0xfff7c245, 0x00029ab2, 0xffff91de,
+ 0x0eb80562, 0xf7dd24ef, 0x05be9f49, 0xfbb0b04e, 0x034232e6, 0xfd92e36c, 0x01c16720, 0xfec70e64, 0x00cfe54f, 0xff7d7f76, 0x004c7c55, 0xffd6d798, 0x0013cf36, 0xfff7dcc8, 0x000291c3, 0xffff9434,
+ 0x0d9ad348, 0xf856502d, 0x0578b30e, 0xfbdcd57a, 0x03259644, 0xfda5627e, 0x01b5acdd, 0xfece433a, 0x00cba5bc, 0xff7fe07f, 0x004b3be3, 0xffd773ed, 0x001389b7, 0xfff7f83a, 0x0002888c, 0xffff9691,
+ 0x0c80911b, 0xf8cf80de, 0x05327467, 0xfc095174, 0x0308ae24, 0xfdb81e22, 0x01a9c4bc, 0xfed598fe, 0x00c74fce, 0xff824fca, 0x0049f2fc, 0xffd814d7, 0x00134204, 0xfff81490, 0x00027f11, 0xffff98f5,
+ 0x0b69517e, 0xf948a5f0, 0x04ebee1c, 0xfc361d25, 0x02eb7f44, 0xfdcb132d, 0x019db0d0, 0xfedd0e5c, 0x00c2e457, 0xff84ccdb, 0x0048a1e7, 0xffd8ba31, 0x0012f82e, 0xfff831c3, 0x00027555, 0xffff9b60,
+ 0x0a5526b0, 0xf9c1ae7b, 0x04a52af2, 0xfc633173, 0x02ce0e67, 0xfdde3e6f, 0x01917334, 0xfee4a1fa, 0x00be642f, 0xff875731, 0x004748ed, 0xffd963d4, 0x0012ac48, 0xfff84fcb, 0x00026b5b, 0xffff9dd0,
+ 0x0944228e, 0xfa3a89be, 0x045e359f, 0xfc908746, 0x02b0604f, 0xfdf19cb9, 0x01850e00, 0xfeec527e, 0x00b9d02b, 0xff89ee4d, 0x0045e856, 0xffda1199, 0x00125e66, 0xfff86e9e, 0x00026126, 0xffffa045,
+ 0x08365690, 0xfab32723, 0x041718d2, 0xfcbe1789, 0x029279c4, 0xfe052ad4, 0x01788354, 0xfef41e8c, 0x00b52925, 0xff8c91ad, 0x0044806c, 0xffdac35a, 0x00120e9b, 0xfff88e35, 0x000256b9, 0xffffa2be,
+ 0x072bd3c5, 0xfb2b7641, 0x03cfdf29, 0xfcebdb26, 0x02745f8c, 0xfe18e58c, 0x016bd54f, 0xfefc04c6, 0x00b06ff7, 0xff8f40d0, 0x00431177, 0xffdb78ef, 0x0011bcf9, 0xfff8ae88, 0x00024c18, 0xffffa539,
+ 0x0624aad6, 0xfba366df, 0x03889336, 0xfd19cb0e, 0x02561670, 0xfe2cc9a7, 0x015f0612, 0xff0403cc, 0x00aba57c, 0xff91fb31, 0x00419bc2, 0xffdc3231, 0x00116994, 0xfff8cf8d, 0x00024146, 0xffffa7b7,
+ 0x0520ec00, 0xfc1ae8f2, 0x03413f7b, 0xfd47e035, 0x0237a337, 0xfe40d3ed, 0x015217c0, 0xff0c1a3c, 0x00a6ca90, 0xff94c04f, 0x00401f98, 0xffdceef9, 0x00111480, 0xfff8f13c, 0x00023645, 0xffffaa35,
+ 0x0420a716, 0xfc91eca1, 0x02f9ee68, 0xfd761395, 0x02190aa6, 0xfe550124, 0x01450c7f, 0xff1446b5, 0x00a1e00f, 0xff978fa6, 0x003e9d42, 0xffddaf1e, 0x0010bdcf, 0xfff9138e, 0x00022b19, 0xffffacb4,
+ 0x0323eb7f, 0xfd086246, 0x02b2aa5c, 0xfda45e2c, 0x01fa5183, 0xfe694e12, 0x0137e672, 0xff1c87d3, 0x009ce6d8, 0xff9a68b0, 0x003d150d, 0xffde727a, 0x00106595, 0xfff93679, 0x00021fc5, 0xffffaf33,
+};
+
+// cmd-line: fir -l 7 -s 44100 -c 19876 -n 16 -b 9.62
+const int32_t dn_sampler_filter_coefficients[] __attribute__ ((aligned (32))) = {
+ 0x736144b5, 0x0c333a22, 0xf4fca390, 0x09424904, 0xf8c92a41, 0x052ac04c, 0xfca4fc64, 0x01ed8cc7, 0xff119cc0, 0x0053ba6e, 0xfff9a80d, 0xffeaeaab, 0x001690d9, 0xfff11dcd, 0x000715d9, 0xfffdb4b9,
+ 0x735ed3aa, 0x0b433de8, 0xf560f0f3, 0x091282c4, 0xf8dd5ccf, 0x0525cb66, 0xfca23e3d, 0x01f33960, 0xff0bc9c2, 0x00586127, 0xfff68603, 0xffecbad5, 0x0015ab8b, 0xfff17c10, 0x0006f71a, 0xfffdbc2f,
+ 0x735780bb, 0x0a55a98f, 0xf5c5b2a1, 0x08e1ea27, 0xf8f25767, 0x0520366d, 0xfc9ff262, 0x01f89c98, 0xff0620a4, 0x005cf349, 0xfff36c0d, 0xffee8913, 0x0014c5dc, 0xfff1db1a, 0x0006d7d7, 0xfffdc3db,
+ 0x734b4c77, 0x096a8a51, 0xf62adb7c, 0x08b086aa, 0xf9081629, 0x051a030f, 0xfc9e186a, 0x01fdb637, 0xff00a1d8, 0x00617065, 0xfff05a84, 0xfff0552d, 0x0013dfed, 0xfff23ada, 0x0006b817, 0xfffdcbba,
+ 0x733a37d2, 0x0881ed1f, 0xf6905e79, 0x087e5fd7, 0xf91e9521, 0x05133308, 0xfc9cafe0, 0x0202860e, 0xfefb4dc7, 0x0065d80c, 0xffed51bc, 0xfff21ee8, 0x0012f9de, 0xfff29b40, 0x000697e0, 0xfffdd3ca,
+ 0x7324441e, 0x079bdea7, 0xf6f62e9d, 0x084b7d43, 0xf935d048, 0x050bc828, 0xfc9bb83e, 0x02070bf9, 0xfef624d8, 0x006a29d6, 0xffea520a, 0xfff3e60f, 0x001213d0, 0xfff2fc3d, 0x00067739, 0xfffddc07,
+ 0x7309730f, 0x06b86b52, 0xf75c3eff, 0x0817e68c, 0xf94dc388, 0x0503c44d, 0xfc9b30f3, 0x020b47dd, 0xfef12766, 0x006e655c, 0xffe75bbe, 0xfff5aa69, 0x00112de1, 0xfff35dc1, 0x00065629, 0xfffde470,
+ 0x72e9c6b8, 0x05d79f40, 0xf7c282cb, 0x07e3a35a, 0xf9666ab7, 0x04fb2969, 0xfc9b195f, 0x020f39ab, 0xfeec55cc, 0x00728a3d, 0xffe46f2a, 0xfff76bc2, 0x00104831, 0xfff3bfbc, 0x000634b6, 0xfffded03,
+ 0x72c5418e, 0x04f98649, 0xf828ed43, 0x07aebb5d, 0xf97fc19e, 0x04f1f97c, 0xfc9b70d6, 0x0212e15c, 0xfee7b059, 0x0076981a, 0xffe18c9a, 0xfff929e3, 0x000f62de, 0xfff4221f, 0x000612e8, 0xfffdf5bc,
+ 0x729be665, 0x041e2bfe, 0xf88f71bf, 0x0779364a, 0xf999c3f4, 0x04e83697, 0xfc9c369c, 0x02163ef1, 0xfee33759, 0x007a8e98, 0xffdeb45b, 0xfffae49b, 0x000e7e08, 0xfff484db, 0x0005f0c4, 0xfffdfe9b,
+ 0x726db871, 0x03459ba4, 0xf8f603ae, 0x07431bdf, 0xf9b46d64, 0x04dde2da, 0xfc9d69eb, 0x02195278, 0xfedeeb11, 0x007e6d61, 0xffdbe6b6, 0xfffc9bb4, 0x000d99cc, 0xfff4e7e1, 0x0005ce51, 0xfffe079b,
+ 0x723abb44, 0x026fe039, 0xf95c9699, 0x070c73dd, 0xf9cfb988, 0x04d30074, 0xfc9f09ee, 0x021c1c06, 0xfedacbbf, 0x00823422, 0xffd923f4, 0xfffe4efd, 0x000cb647, 0xfff54b20, 0x0005ab95, 0xfffe10bc,
+ 0x7202f2d3, 0x019d046d, 0xf9c31e22, 0x06d5460b, 0xf9eba3ef, 0x04c791a4, 0xfca115c5, 0x021e9bbb, 0xfed6d99c, 0x0085e28b, 0xffd66c59, 0xfffffe46, 0x000bd397, 0xfff5ae8c, 0x00058898, 0xfffe19fa,
+ 0x71c6636d, 0x00cd12a4, 0xfa298e07, 0x069d9a31, 0xfa082817, 0x04bb98b5, 0xfca38c83, 0x0220d1bf, 0xfed314da, 0x00897851, 0xffd3c02a, 0x0001a95d, 0x000af1d9, 0xfff61214, 0x0005655e, 0xfffe2354,
+ 0x718511c2, 0x000014f8, 0xfa8fda21, 0x0665781b, 0xfa254176, 0x04af1804, 0xfca66d2e, 0x0222be45, 0xfecf7da3, 0x008cf52d, 0xffd11fa9, 0x00035015, 0x000a1129, 0xfff675ab, 0x000541f0, 0xfffe2cc8,
+ 0x713f02e0, 0xff361534, 0xfaf5f669, 0x062ce795, 0xfa42eb75, 0x04a211f8, 0xfca9b6bf, 0x02246187, 0xfecc141d, 0x009058da, 0xffce8b13, 0x0004f23e, 0x000931a3, 0xfff6d942, 0x00051e52, 0xfffe3652,
+ 0x70f43c32, 0xfe6f1cd7, 0xfb5bd6f4, 0x05f3f06b, 0xfa61216f, 0x04948906, 0xfcad6827, 0x0225bbca, 0xfec8d867, 0x0093a31a, 0xffcc02a8, 0x00068fad, 0x00085362, 0xfff73ccb, 0x0004fa8b, 0xfffe3ff2,
+ 0x70a4c37f, 0xfdab350f, 0xfbc16ff6, 0x05ba9a6b, 0xfa7fdeba, 0x04867fb3, 0xfcb18047, 0x0226cd5b, 0xfec5ca9a, 0x0096d3af, 0xffc986a1, 0x00082835, 0x00077681, 0xfff7a037, 0x0004d6a1, 0xfffe49a4,
+ 0x70509eec, 0xfcea66be, 0xfc26b5c5, 0x0580ed5f, 0xfa9f1e9e, 0x0477f88d, 0xfcb5fdf7, 0x02279691, 0xfec2eaca, 0x0099ea62, 0xffc71738, 0x0009bbab, 0x00069b1b, 0xfff8037a, 0x0004b29a, 0xfffe5367,
+ 0x6ff7d4f8, 0xfc2cba75, 0xfc8b9cda, 0x0546f10f, 0xfabedc5a, 0x0468f62e, 0xfcbae002, 0x022817ca, 0xfec03901, 0x009ce6fe, 0xffc4b4a4, 0x000b49e6, 0x0005c149, 0xfff86686, 0x00048e7c, 0xfffe5d38,
+ 0x6f9a6c7f, 0xfb723876, 0xfcf019cd, 0x050cad3f, 0xfadf1328, 0x04597b40, 0xfcc0252b, 0x0228516f, 0xfebdb547, 0x009fc954, 0xffc25f1a, 0x000cd2bd, 0x0004e926, 0xfff8c94c, 0x00046a4c, 0xfffe6716,
+ 0x6f386cb6, 0xfabae8b2, 0xfd54215c, 0x04d229b1, 0xfaffbe36, 0x04498a72, 0xfcc5cc26, 0x022843f0, 0xfebb5f9b, 0x00a29136, 0xffc016cb, 0x000e5609, 0x000412c9, 0xfff92bc0, 0x00044612, 0xfffe70ff,
+ 0x6ed1dd2e, 0xfa06d2ca, 0xfdb7a869, 0x04976e20, 0xfb20d8ad, 0x04392684, 0xfccbd3a0, 0x0227efc6, 0xfeb937f9, 0x00a53e7b, 0xffbddbe8, 0x000fd3a3, 0x00033e4c, 0xfff98dd6, 0x000421d2, 0xfffe7aef,
+ 0x6e66c5ce, 0xf955fe0c, 0xfe1aa3fc, 0x045c8240, 0xfb425db0, 0x0428523d, 0xfcd23a3a, 0x02275572, 0xfeb73e54, 0x00a7d0ff, 0xffbbae9f, 0x00114b67, 0x00026bc6, 0xfff9ef80, 0x0003fd92, 0xfffe84e7,
+ 0x6df72ed9, 0xf8a87178, 0xfe7d0942, 0x04216dc0, 0xfb64485b, 0x0417106e, 0xfcd8fe8b, 0x0226757e, 0xfeb5729b, 0x00aa48a0, 0xffb98f1c, 0x0012bd30, 0x00019b4e, 0xfffa50b1, 0x0003d957, 0xfffe8ee3,
+ 0x6d8320e6, 0xf7fe33ba, 0xfedecd90, 0x03e63846, 0xfb8693c6, 0x040563f4, 0xfce01f21, 0x0225507c, 0xfeb3d4b7, 0x00aca542, 0xffb77d88, 0x001428db, 0x0000ccfc, 0xfffab15e, 0x0003b527, 0xfffe98e2,
+ 0x6d0aa4e6, 0xf7574b2b, 0xff3fe663, 0x03aae970, 0xfba93b01, 0x03f34fb2, 0xfce79a7f, 0x0223e706, 0xfeb26489, 0x00aee6ca, 0xffb57a0b, 0x00158e47, 0x000000e6, 0xfffb117a, 0x00039108, 0xfffea2e1,
+ 0x6c8dc41f, 0xf6b3bdd3, 0xffa04963, 0x036f88d2, 0xfbcc391d, 0x03e0d697, 0xfcef6f20, 0x022239bc, 0xfeb121ee, 0x00b10d23, 0xffb384ca, 0x0016ed53, 0xffff3721, 0xfffb70fa, 0x00036cfe, 0xfffeacdf,
+ 0x6c0c882a, 0xf6139169, 0xffffec5f, 0x03341df4, 0xfbef8924, 0x03cdfb99, 0xfcf79b75, 0x02204949, 0xfeb00cbf, 0x00b3183c, 0xffb19de7, 0x001845e0, 0xfffe6fc3, 0xfffbcfd2, 0x00034910, 0xfffeb6db,
+ 0x6b86faf8, 0xf576cb4e, 0x005ec552, 0x02f8b055, 0xfc13261f, 0x03bac1b4, 0xfd001de8, 0x021e165d, 0xfeaf24cc, 0x00b50805, 0xffafc584, 0x001997d0, 0xfffdaadf, 0xfffc2df6, 0x00032541, 0xfffec0d2,
+ 0x6afd26cb, 0xf4dd7092, 0x00bcca63, 0x02bd4768, 0xfc370b14, 0x03a72bf0, 0xfd08f4d6, 0x021ba1b2, 0xfeae69e1, 0x00b6dc75, 0xffadfbbe, 0x001ae306, 0xfffce88b, 0xfffc8b5c, 0x00030196, 0xfffecac3,
+ 0x6a6f1638, 0xf44785f1, 0x0119f1e4, 0x0281ea90, 0xfc5b3309, 0x03933d58, 0xfd121e99, 0x0218ec06, 0xfeaddbc4, 0x00b89584, 0xffac40b3, 0x001c2765, 0xfffc28d9, 0xfffce7f8, 0x0002de16, 0xfffed4ab,
+ 0x69dcd425, 0xf3b50fd6, 0x01763256, 0x0246a125, 0xfc7f9902, 0x037ef900, 0xfd1b9980, 0x0215f621, 0xfead7a37, 0x00ba3330, 0xffaa947c, 0x001d64d5, 0xfffb6bdd, 0xfffd43c1, 0x0002bac4, 0xfffede8a,
+ 0x69466bc8, 0xf3261255, 0x01d18265, 0x020b726f, 0xfca43803, 0x036a6201, 0xfd2563d3, 0x0212c0d2, 0xfead44f4, 0x00bbb579, 0xffa8f730, 0x001e9b3a, 0xfffab1a8, 0xfffd9eab, 0x000297a5, 0xfffee85e,
+ 0x68abe8a8, 0xf29a9133, 0x022bd8ee, 0x01d065a8, 0xfcc90b12, 0x03557b7a, 0xfd2f7bd1, 0x020f4cec, 0xfead3bb2, 0x00bd1c63, 0xffa768e6, 0x001fca7d, 0xfff9fa4d, 0xfffdf8ae, 0x000274be, 0xfffef225,
+ 0x680d5698, 0xf2128fde, 0x02852cfc, 0x019581f9, 0xfcee0d33, 0x03404890, 0xfd39dfb4, 0x020b9b4c, 0xfead5e22, 0x00be67f6, 0xffa5e9b1, 0x0020f288, 0xfff945dc, 0xfffe51be, 0x00025214, 0xfffefbde,
+ 0x676ac1bb, 0xf18e1174, 0x02dd75ca, 0x015ace79, 0xfd133970, 0x032acc6d, 0xfd448dae, 0x0207acd4, 0xfeadabef, 0x00bf983d, 0xffa479a2, 0x00221344, 0xfff89465, 0xfffea9d2, 0x00022fa9, 0xffff0587,
+ 0x66c4367d, 0xf10d18bd, 0x0334aac4, 0x0120522f, 0xfd388ad1, 0x03150a3f, 0xfd4f83eb, 0x0203826c, 0xfeae24c1, 0x00c0ad48, 0xffa318c7, 0x00232c9d, 0xfff7e5f9, 0xffff00e1, 0x00020d84, 0xffff0f1f,
+ 0x6619c197, 0xf08fa82f, 0x038ac385, 0x00e6140f, 0xfd5dfc63, 0x02ff0538, 0xfd5ac08e, 0x01ff1d04, 0xfeaec838, 0x00c1a728, 0xffa1c72f, 0x00243e7f, 0xfff73aa7, 0xffff56e3, 0x0001eba8, 0xffff18a4,
+ 0x656b700a, 0xf015c1ee, 0x03dfb7dd, 0x00ac1af9, 0xfd838938, 0x02e8c08e, 0xfd6641b8, 0x01fa7d91, 0xfeaf95f2, 0x00c285f4, 0xffa084e3, 0x002548d9, 0xfff6927e, 0xffffabcd, 0x0001ca18, 0xffff2215,
+ 0x64b94f22, 0xef9f67cb, 0x04337fcb, 0x00726dbb, 0xfda92c63, 0x02d23f7a, 0xfd720581, 0x01f5a50d, 0xfeb08d86, 0x00c349c4, 0xff9f51eb, 0x00264b9a, 0xfff5ed8b, 0xffffff99, 0x0001a8da, 0xffff2b70,
+ 0x64036c6f, 0xef2c9b43, 0x04861383, 0x0039130c, 0xfdcee0ff, 0x02bb8537, 0xfd7e09fc, 0x01f0947a, 0xfeb1ae87, 0x00c3f2b6, 0xff9e2e50, 0x002746b2, 0xfff54bdc, 0x0000523d, 0x000187f0, 0xffff34b6,
+ 0x6349d5c9, 0xeebd5d81, 0x04d76b6b, 0x00001191, 0xfdf4a22a, 0x02a49505, 0xfd8a4d37, 0x01eb4cde, 0xfeb2f884, 0x00c480e9, 0xff9d1a14, 0x00283a12, 0xfff4ad7e, 0x0000a3b3, 0x0001675f, 0xffff3de3,
+ 0x628c994c, 0xee51af5f, 0x0527801d, 0xffc76fd5, 0xfe1a6b08, 0x028d7223, 0xfd96cd3d, 0x01e5cf44, 0xfeb46b07, 0x00c4f480, 0xff9c1539, 0x002925ae, 0xfff4127d, 0x0000f3f1, 0x00014729, 0xffff46f7,
+ 0x61cbc559, 0xede99165, 0x05764a68, 0xff8f344f, 0xfe4036c5, 0x02761fd3, 0xfda3880f, 0x01e01cbe, 0xfeb60596, 0x00c54da2, 0xff9b1fc1, 0x002a0979, 0xfff37ae4, 0x000142f1, 0x00012754, 0xffff4ff1,
+ 0x61076890, 0xed8503c7, 0x05c3c34e, 0xff576560, 0xfe660094, 0x025ea157, 0xfdb07bb0, 0x01da3661, 0xfeb7c7b0, 0x00c58c79, 0xff9a39a9, 0x002ae568, 0xfff2e6bf, 0x000190ac, 0x000107e1, 0xffff58d0,
+ 0x603f91d5, 0xed24066b, 0x060fe408, 0xff20094d, 0xfe8bc3ad, 0x0246f9f3, 0xfdbda61a, 0x01d41d4a, 0xfeb9b0d3, 0x00c5b132, 0xff9962ec, 0x002bb971, 0xfff25619, 0x0001dd1b, 0x0000e8d4, 0xffff6192,
+ 0x5f745049, 0xecc698e6, 0x065aa604, 0xfee92646, 0xfeb17b53, 0x022f2cea, 0xfdcb0546, 0x01cdd297, 0xfebbc078, 0x00c5bbfc, 0xff989b85, 0x002c858d, 0xfff1c8fa, 0x00022837, 0x0000ca30, 0xffff6a38,
+ 0x5ea5b34c, 0xec6cba79, 0x06a402e4, 0xfeb2c261, 0xfed722d0, 0x02173d81, 0xfdd89727, 0x01c7576d, 0xfebdf613, 0x00c5ad0a, 0xff97e36c, 0x002d49b4, 0xfff13f6c, 0x000271fa, 0x0000abf8, 0xffff72be,
+ 0x5dd3ca7a, 0xec166a19, 0x06ebf483, 0xfe7ce399, 0xfefcb57a, 0x01ff2ef9, 0xfde659af, 0x01c0acf5, 0xfec05114, 0x00c58494, 0xff973a96, 0x002e05df, 0xfff0b977, 0x0002ba5f, 0x00008e30, 0xffff7b26,
+ 0x5cfea5aa, 0xebc3a669, 0x073274f1, 0xfe478fd2, 0xff222eac, 0x01e70494, 0xfdf44acc, 0x01b9d45b, 0xfec2d0e8, 0x00c542d1, 0xff96a0f8, 0x002eba0a, 0xfff03724, 0x0003015f, 0x000070d9, 0xffff836d,
+ 0x5c2654ed, 0xeb746dbe, 0x07777e74, 0xfe12ccd1, 0xff4789d1, 0x01cec194, 0xfe026869, 0x01b2ced1, 0xfec574f9, 0x00c4e7fe, 0xff961684, 0x002f6630, 0xffefb87a, 0x000346f6, 0x000053f7, 0xffff8b93,
+ 0x5b4ae88d, 0xeb28be1f, 0x07bb0b8b, 0xfddea042, 0xff6cc25a, 0x01b66936, 0xfe10b06f, 0x01ab9d8b, 0xfec83caa, 0x00c47459, 0xff959b29, 0x00300a4f, 0xffef3d7f, 0x00038b1d, 0x0000378c, 0xffff9398,
+ 0x5a6c7108, 0xeae09544, 0x07fd16eb, 0xfdab0fb6, 0xff91d3c6, 0x019dfeb6, 0xfe1f20c5, 0x01a441c2, 0xfecb275e, 0x00c3e824, 0xff952ed7, 0x0030a665, 0xffeec63a, 0x0003cdd1, 0x00001b9a, 0xffff9b7a,
+ 0x598aff13, 0xea9bf097, 0x083d9b81, 0xfd7820a0, 0xffb6b99f, 0x0185854f, 0xfe2db74f, 0x019cbcb1, 0xfece3472, 0x00c343a4, 0xff94d178, 0x00313a72, 0xffee52b1, 0x00040f0d, 0x00000024, 0xffffa339,
+ 0x58a6a397, 0xea5acd38, 0x087c9471, 0xfd45d856, 0xffdb6f7c, 0x016d0037, 0xfe3c71f1, 0x01950f98, 0xfed16342, 0x00c2871f, 0xff9482f8, 0x0031c677, 0xffede2e7, 0x00044ecb, 0xffffe52d, 0xffffaad3,
+ 0x57bf6fae, 0xea1d27f7, 0x08b9fd18, 0xfd143c12, 0xfffff100, 0x015472a1, 0xfe4b4e8c, 0x018d3bb8, 0xfed4b325, 0x00c1b2e0, 0xff944340, 0x00324a74, 0xffed76e3, 0x00048d0a, 0xffffcab5, 0xffffb249,
+ 0x56d574a2, 0xe9e2fd5b, 0x08f5d10a, 0xfce350f0, 0x002439db, 0x013bdfbc, 0xfe5a4b03, 0x01854258, 0xfed82370, 0x00c0c731, 0xff941236, 0x0032c66e, 0xffed0ea7, 0x0004c9c4, 0xffffb0bf, 0xffffb99a,
+ 0x55e8c3ee, 0xe9ac49a0, 0x09300c14, 0xfcb31bec, 0x004845cc, 0x01234ab4, 0xfe696534, 0x017d24bf, 0xfedbb373, 0x00bfc463, 0xff93efbf, 0x00333a67, 0xffecaa36, 0x000504f6, 0xffff974d, 0xffffc0c5,
+ 0x54f96f37, 0xe97908b8, 0x0968aa3b, 0xfc83a1e5, 0x006c10a0, 0x010ab6b0, 0xfe789b01, 0x0174e437, 0xfedf627d, 0x00beaac6, 0xff93dbc0, 0x0033a665, 0xffec4994, 0x00053e9e, 0xffff7e61, 0xffffc7ca,
+ 0x54078851, 0xe9493649, 0x099fa7bb, 0xfc54e79a, 0x008f9631, 0x00f226d0, 0xfe87ea47, 0x016c820d, 0xfee32fdb, 0x00bd7aae, 0xff93d618, 0x00340a6d, 0xffebecc2, 0x000576b8, 0xffff65fc, 0xffffcea8,
+ 0x53132138, 0xe91ccdb5, 0x09d5010b, 0xfc26f1ad, 0x00b2d26b, 0x00d99e31, 0xfe9750e8, 0x0163ff90, 0xfee71ad4, 0x00bc3470, 0xff93deaa, 0x00346687, 0xffeb93c3, 0x0005ad41, 0xffff4e20, 0xffffd55f,
+ 0x521c4c10, 0xe8f3ca12, 0x0a08b2d9, 0xfbf9c49d, 0x00d5c147, 0x00c11feb, 0xfea6ccc3, 0x015b5e11, 0xfeeb22af, 0x00bad866, 0xff93f552, 0x0034babb, 0xffeb3e96, 0x0005e238, 0xffff36ce, 0xffffdbee,
+ 0x51231b26, 0xe8ce2631, 0x0a3aba09, 0xfbcd64ca, 0x00f85ecf, 0x00a8af0c, 0xfeb65bb9, 0x01529ee3, 0xfeef46b0, 0x00b966e9, 0xff9419ef, 0x00350711, 0xffeaed3c, 0x00061599, 0xffff2007, 0xffffe255,
+ 0x5027a0e9, 0xe8abdc9d, 0x0a6b13bc, 0xfba1d673, 0x011aa71d, 0x00904ea0, 0xfec5fbac, 0x0149c35a, 0xfef3861a, 0x00b7e055, 0xff944c5a, 0x00354b94, 0xffea9fb6, 0x00064764, 0xffff09ce, 0xffffe894,
+ 0x4f29efed, 0xe88ce79a, 0x0a99bd47, 0xfb771db9, 0x013c965b, 0x007801aa, 0xfed5aa7e, 0x0140cccb, 0xfef7e02a, 0x00b6450a, 0xff948c6e, 0x0035884f, 0xffea5602, 0x00067797, 0xfffef421, 0xffffeeaa,
+ 0x4e2a1ae8, 0xe871412a, 0x0ac6b43a, 0xfb4d3e97, 0x015e28c7, 0x005fcb26, 0xfee56614, 0x0137bc8f, 0xfefc541e, 0x00b49568, 0xff94da03, 0x0035bd4e, 0xffea1020, 0x0006a630, 0xfffedf04, 0xfffff498,
+ 0x4d2834b0, 0xe858e30a, 0x0af1f65d, 0xfb243cea, 0x017f5aad, 0x0047ae09, 0xfef52c54, 0x012e93fc, 0xff00e133, 0x00b2d1d1, 0xff9534f0, 0x0035ea9d, 0xffe9ce0d, 0x0006d32f, 0xfffeca76, 0xfffffa5d,
+ 0x4c245038, 0xe843c6b5, 0x0b1b81ad, 0xfafc1c6e, 0x01a0286c, 0x002fad3f, 0xff04fb25, 0x0125546c, 0xff0586a0, 0x00b0faaa, 0xff959d0a, 0x0036104b, 0xffe98fc8, 0x0006fe92, 0xfffeb678, 0xfffffff8,
+ 0x4b1e8091, 0xe831e563, 0x0b435462, 0xfad4e0b9, 0x01c08e78, 0x0017cbae, 0xff14d073, 0x011bff38, 0xff0a439e, 0x00af1059, 0xff961224, 0x00362e66, 0xffe9554c, 0x00072859, 0xfffea30b, 0x0000056a,
+ 0x4a16d8e5, 0xe823380d, 0x0b696ceb, 0xfaae8d43, 0x01e08952, 0x00000c33, 0xff24aa2a, 0x011295bb, 0xff0f1762, 0x00ad1346, 0xff969412, 0x003644fd, 0xffe91e99, 0x00075084, 0xfffe9030, 0x00000ab3,
+ 0x490d6c79, 0xe817b76c, 0x0b8dc9ed, 0xfa89255f, 0x02001593, 0xffe871a0, 0xff348639, 0x0109194f, 0xff140121, 0x00ab03da, 0xff9722a5, 0x00365422, 0xffe8eba8, 0x00077712, 0xfffe7de7, 0x00000fd2,
+ 0x48024ea7, 0xe80f5bfb, 0x0bb06a47, 0xfa64ac3f, 0x021f2fe5, 0xffd0fec1, 0xff446293, 0x00ff8b4f, 0xff19000e, 0x00a8e282, 0xff97bdac, 0x00365be6, 0xffe8bc77, 0x00079c04, 0xfffe6c2f, 0x000014c8,
+ 0x46f592e2, 0xe80a1df5, 0x0bd14d0b, 0xfa4124f2, 0x023dd505, 0xffb9b656, 0xff543d2e, 0x00f5ed15, 0xff1e135b, 0x00a6afa8, 0xff9864f6, 0x00365c5b, 0xffe89101, 0x0007bf5b, 0xfffe5b0b, 0x00001994,
+ 0x45e74cad, 0xe807f55b, 0x0bf07186, 0xfa1e9262, 0x025c01c5, 0xffa29b18, 0xff641402, 0x00ec3ffc, 0xff233a39, 0x00a46bbc, 0xff991851, 0x00365594, 0xffe8693f, 0x0007e116, 0xfffe4a79, 0x00001e37,
+ 0x44d78fa0, 0xe808d9f1, 0x0c0dd738, 0xf9fcf758, 0x0279b30b, 0xff8bafb3, 0xff73e50e, 0x00e2855d, 0xff2873d6, 0x00a2172d, 0xff99d789, 0x003647a5, 0xffe8452d, 0x00080137, 0xfffe3a79, 0x000022b1,
+ 0x43c66f62, 0xe80cc342, 0x0c297dd9, 0xf9dc567b, 0x0296e5d0, 0xff74f6cc, 0xff83ae52, 0x00d8be92, 0xff2dbf61, 0x009fb26c, 0xff9aa268, 0x003632a2, 0xffe824c5, 0x00081fbf, 0xfffe2b0d, 0x00002701,
+ 0x42b3ffa9, 0xe813a89f, 0x0c436557, 0xf9bcb24a, 0x02b39724, 0xff5e72fb, 0xff936dd2, 0x00ceecf5, 0xff331c08, 0x009d3deb, 0xff9b78ba, 0x003616a2, 0xffe807ff, 0x00083cb0, 0xfffe1c32, 0x00002b28,
+ 0x41a05437, 0xe81d8122, 0x0c5b8dd4, 0xf99e0d26, 0x02cfc429, 0xff4826cf, 0xffa3219a, 0x00c511dc, 0xff3888f8, 0x009aba1d, 0xff9c5a47, 0x0035f3b9, 0xffe7eed5, 0x0008580a, 0xfffe0dea, 0x00002f26,
+ 0x408b80d9, 0xe82a43ac, 0x0c71f7a9, 0xf980694a, 0x02eb6a18, 0xff3214c9, 0xffb2c7b6, 0x00bb2e9f, 0xff3e055d, 0x00982778, 0xff9d46d6, 0x0035ca00, 0xffe7d93f, 0x000871cf, 0xfffe0034, 0x000032fb,
+ 0x3f759967, 0xe839e6e9, 0x0c86a361, 0xf963c8cc, 0x03068640, 0xff1c3f63, 0xffc25e3b, 0x00b14493, 0xff439064, 0x0095866f, 0xff9e3e30, 0x0035998d, 0xffe7c735, 0x00088a02, 0xfffdf310, 0x000036a8,
+ 0x3e5eb1bd, 0xe84c6152, 0x0c9991be, 0xf9482da0, 0x03211603, 0xff06a907, 0xffd1e340, 0x00a7550c, 0xff492937, 0x0092d77b, 0xff9f4019, 0x00356279, 0xffe7b8af, 0x0008a0a5, 0xfffde67c, 0x00003a2d,
+ 0x3d46ddc1, 0xe861a92b, 0x0caac3b5, 0xf92d9997, 0x033b16dc, 0xfef15417, 0xffe154e3, 0x009d615d, 0xff4ecf02, 0x00901b11, 0xffa04c57, 0x003524dd, 0xffe7ada5, 0x0008b5ba, 0xfffdda79, 0x00003d89,
+ 0x3c2e315a, 0xe879b487, 0x0cba3a6d, 0xf9140e5e, 0x03548659, 0xfedc42e7, 0xfff0b148, 0x00936ad6, 0xff5480f0, 0x008d51ab, 0xffa162ae, 0x0034e0d3, 0xffe7a60d, 0x0008c944, 0xfffdcf05, 0x000040be,
+ 0x3b14c072, 0xe8947947, 0x0cc7f742, 0xf8fb8d7d, 0x036d621f, 0xfec777be, 0xfffff697, 0x008972c7, 0xff5a3e2c, 0x008a7bc1, 0xffa282e1, 0x00349674, 0xffe7a1de, 0x0008db46, 0xfffdc421, 0x000043cc,
+ 0x39fa9ef3, 0xe8b1ed1c, 0x0cd3fbc0, 0xf8e4185a, 0x0385a7eb, 0xfeb2f4d9, 0x000f22fe, 0x007f7a7c, 0xff6005e1, 0x008799cd, 0xffa3acb4, 0x003445dc, 0xffe7a10d, 0x0008ebc1, 0xfffdb9cb, 0x000046b2,
+ 0x38dfe0c6, 0xe8d2058b, 0x0cde49a8, 0xf8cdb036, 0x039d558e, 0xfe9ebc66, 0x001e34b4, 0x00758341, 0xff65d73a, 0x0084ac48, 0xffa4dfe8, 0x0033ef25, 0xffe7a391, 0x0008fabb, 0xfffdb002, 0x00004972,
+ 0x37c499d0, 0xe8f4b7e9, 0x0ce6e2ea, 0xf8b85631, 0x03b468f1, 0xfe8ad087, 0x002d29f3, 0x006b8e5c, 0xff6bb163, 0x0081b3af, 0xffa61c3e, 0x0033926d, 0xffe7a95f, 0x00090836, 0xfffda6c5, 0x00004c0b,
+ 0x36a8ddf3, 0xe919f961, 0x0cedc9a7, 0xf8a40b44, 0x03cae014, 0xfe773351, 0x003c00fd, 0x00619d15, 0xff719388, 0x007eb07b, 0xffa76176, 0x00332fcf, 0xffe7b26c, 0x00091435, 0xfffd9e13, 0x00004e7f,
+ 0x358cc109, 0xe941bef3, 0x0cf30031, 0xf890d048, 0x03e0b90d, 0xfe63e6cb, 0x004ab81b, 0x0057b0ae, 0xff777cd6, 0x007ba32a, 0xffa8af51, 0x0032c769, 0xffe7bead, 0x00091ebd, 0xfffd95eb, 0x000050cd,
+ 0x347056e3, 0xe96bfd76, 0x0cf6890a, 0xf87ea5f1, 0x03f5f20a, 0xfe50ecf0, 0x00594d9d, 0x004dca68, 0xff7d6c79, 0x00788c36, 0xffaa058d, 0x00325958, 0xffe7ce16, 0x000927d1, 0xfffd8e4d, 0x000052f7,
+ 0x3353b349, 0xe998a999, 0x0cf866e1, 0xf86d8cd1, 0x040a894e, 0xfe3e47ac, 0x0067bfd8, 0x0043eb7f, 0xff83619f, 0x00756c1d, 0xffab63ea, 0x0031e5ba, 0xffe7e09c, 0x00092f75, 0xfffd8735, 0x000054fc,
+ 0x3236e9f7, 0xe9c7b7e3, 0x0cf89c96, 0xf85d8555, 0x041e7d34, 0xfe2bf8de, 0x00760d2a, 0x003a152f, 0xff895b77, 0x0072435b, 0xffacca25, 0x00316cae, 0xffe7f631, 0x000935ad, 0xfffd80a4, 0x000056dd,
+ 0x311a0e9b, 0xe9f91cb9, 0x0cf72d34, 0xf84e8fc9, 0x0431cc31, 0xfe1a0256, 0x008433f9, 0x003048ae, 0xff8f5930, 0x006f126b, 0xffae37fd, 0x0030ee53, 0xffe80eca, 0x00093a7f, 0xfffd7a98, 0x0000589b,
+ 0x2ffd34d4, 0xea2ccc59, 0x0cf41bf7, 0xf840ac57, 0x044474ce, 0xfe0865d7, 0x009232b2, 0x0026872f, 0xff9559fb, 0x006bd9cd, 0xffafad2e, 0x00306ac8, 0xffe82a59, 0x00093ded, 0xfffd750f, 0x00005a36,
+ 0x2ee07030, 0xea62bae0, 0x0cef6c43, 0xf833db04, 0x045675ab, 0xfdf72515, 0x00a007c9, 0x001cd1e4, 0xff9b5d0a, 0x006899fb, 0xffb12976, 0x002fe22c, 0xffe848d3, 0x00093ffe, 0xfffd7008, 0x00005baf,
+ 0x2dc3d429, 0xea9adc49, 0x0ce921ab, 0xf8281bb6, 0x0467cd83, 0xfde641b7, 0x00adb1bb, 0x001329f7, 0xffa16190, 0x00655372, 0xffb2ac90, 0x002f54a1, 0xffe86a29, 0x000940b6, 0xfffd6b81, 0x00005d06,
+ 0x2ca77428, 0xead52471, 0x0ce13feb, 0xf81d6e2e, 0x04787b24, 0xfdd5bd53, 0x00bb2f0b, 0x00099093, 0xffa766c0, 0x006206b1, 0xffb4363a, 0x002ec246, 0xffe88e4d, 0x00094019, 0xfffd6779, 0x00005e3d,
+ 0x2b8b637b, 0xeb118714, 0x0cd7caec, 0xf813d20d, 0x04887d76, 0xfdc59972, 0x00c87e47, 0x000006db, 0xffad6bd0, 0x005eb431, 0xffb5c630, 0x002e2b3c, 0xffe8b532, 0x00093e2e, 0xfffd63ed, 0x00005f52,
+ 0x2a6fb55e, 0xeb4ff7d4, 0x0cccc6bc, 0xf80b46d3, 0x0497d378, 0xfdb5d78f, 0x00d59e03, 0xfff68df1, 0xffb36ff9, 0x005b5c71, 0xffb75c2c, 0x002d8fa4, 0xffe8decb, 0x00093af8, 0xfffd60dd, 0x00006048,
+ 0x29547ced, 0xeb906a35, 0x0cc03797, 0xf803cbdc, 0x04a67c41, 0xfda67913, 0x00e28cdd, 0xffed26f0, 0xffb97271, 0x0057ffec, 0xffb8f7ea, 0x002cefa1, 0xffe90b08, 0x0009367e, 0xfffd5e46, 0x0000611f,
+ 0x2839cd30, 0xebd2d1a1, 0x0cb221de, 0xf7fd6065, 0x04b476fe, 0xfd977f5d, 0x00ef497a, 0xffe3d2f2, 0xffbf7274, 0x00549f1c, 0xffba9927, 0x002c4b53, 0xffe939db, 0x000930c4, 0xfffd5c26, 0x000061d8,
+ 0x271fb90d, 0xec17216b, 0x0ca28a1a, 0xf7f8038c, 0x04c1c2f3, 0xfd88ebb9, 0x00fbd28a, 0xffda930a, 0xffc56f3e, 0x00513a7e, 0xffbc3f9d, 0x002ba2dc, 0xffe96b35, 0x000929d1, 0xfffd5a7c, 0x00006272,
+ 0x2606534e, 0xec5d4ccd, 0x0c9174fa, 0xf7f3b44b, 0x04ce5f7d, 0xfd7abf64, 0x010826c4, 0xffd16848, 0xffcb680e, 0x004dd28c, 0xffbdeb07, 0x002af65f, 0xffe99f08, 0x000921aa, 0xfffd5945, 0x000062f0,
+ 0x24edae9c, 0xeca546eb, 0x0c7ee754, 0xf7f0717e, 0x04da4c10, 0xfd6cfb8e, 0x011444e7, 0xffc853b6, 0xffd15c22, 0x004a67c0, 0xffbf9b21, 0x002a45fe, 0xffe9d545, 0x00091854, 0xfffd5880, 0x00006351,
+ 0x23d5dd81, 0xecef02d5, 0x0c6ae622, 0xf7ee39e2, 0x04e58836, 0xfd5fa157, 0x01202bbe, 0xffbf565a, 0xffd74abe, 0x0046fa93, 0xffc14fa5, 0x002991db, 0xffea0ddc, 0x00090dd6, 0xfffd582a, 0x00006396,
+ 0x22bef262, 0xed3a7388, 0x0c557681, 0xf7ed0c12, 0x04f01392, 0xfd52b1cf, 0x012bda1b, 0xffb67137, 0xffdd3325, 0x00438b7e, 0xffc3084f, 0x0028da1a, 0xffea48be, 0x00090236, 0xfffd5842, 0x000063c0,
+ 0x21a8ff7e, 0xed878bf0, 0x0c3e9db5, 0xf7ece68c, 0x04f9edda, 0xfd462df6, 0x01374eda, 0xffada547, 0xffe3149e, 0x00401af9, 0xffc4c4da, 0x00281edd, 0xffea85dc, 0x0008f57a, 0xfffd58c5, 0x000063d0,
+ 0x209416f2, 0xedd63ee5, 0x0c26611f, 0xf7edc7af, 0x050316e0, 0xfd3a16c0, 0x014288e0, 0xffa4f383, 0xffe8ee72, 0x003ca97b, 0xffc68502, 0x00276046, 0xffeac525, 0x0008e7a7, 0xfffd59b2, 0x000063c6,
+ 0x1f804ab0, 0xee267f35, 0x0c0cc646, 0xf7efadbd, 0x050b8e8a, 0xfd2e6d0d, 0x014d871b, 0xff9c5cdc, 0xffeebfec, 0x0039377a, 0xffc84881, 0x00269e7a, 0xffeb068a, 0x0008d8c4, 0xfffd5b05, 0x000063a3,
+ 0x1e6dac83, 0xee783f9e, 0x0bf1d2d0, 0xf7f296d7, 0x051354d5, 0xfd2331b0, 0x01584883, 0xff93e241, 0xfff48859, 0x0035c56c, 0xffca0f14, 0x0025d99b, 0xffeb49fc, 0x0008c8d7, 0xfffd5cbe, 0x00006368,
+ 0x1d5c4e09, 0xeecb72d1, 0x0bd58c81, 0xf7f68103, 0x051a69d4, 0xfd18656f, 0x0162cc19, 0xff8b8498, 0xfffa470a, 0x003253c6, 0xffcbd876, 0x002511cd, 0xffeb8f6a, 0x0008b7e7, 0xfffd5ed8, 0x00006316,
+ 0x1c4c40b6, 0xef200b76, 0x0bb7f940, 0xf7fb6a29, 0x0520cdb1, 0xfd0e08fb, 0x016d10e9, 0xff8344c4, 0xfffffb51, 0x002ee2fa, 0xffcda463, 0x00244733, 0xffebd6c4, 0x0008a5fa, 0xfffd6154, 0x000062ad,
+ 0x1b3d95d1, 0xef75fc2b, 0x0b991f0f, 0xf8015015, 0x052680ae, 0xfd041cfa, 0x01771608, 0xff7b23a1, 0x0005a483, 0x002b737b, 0xffcf7299, 0x002379ef, 0xffec1ffa, 0x00089316, 0xfffd642d, 0x0000622e,
+ 0x1a305e70, 0xefcd3787, 0x0b79040c, 0xf8083077, 0x052b8320, 0xfcfaa200, 0x0180da94, 0xff732209, 0x000b41fa, 0x002805ba, 0xffd142d3, 0x0022aa26, 0xffec6afc, 0x00087f43, 0xfffd6762, 0x0000619a,
+ 0x1924ab7b, 0xf025b01a, 0x0b57ae75, 0xf81008e2, 0x052fd573, 0xfcf19894, 0x018a5db5, 0xff6b40cb, 0x0010d30e, 0x00249a28, 0xffd314cf, 0x0021d7fa, 0xffecb7b9, 0x00086a86, 0xfffd6af1, 0x000060f1,
+ 0x181a8da5, 0xf07f586e, 0x0b3524a0, 0xf818d6cf, 0x0533782a, 0xfce9012c, 0x01939e9e, 0xff6380b5, 0x00165720, 0x00213134, 0xffd4e84a, 0x00210390, 0xffed0621, 0x000854e6, 0xfffd6ed6, 0x00006035,
+ 0x17121573, 0xf0da230b, 0x0b116cff, 0xf822979b, 0x05366bdc, 0xfce0dc2f, 0x019c9c8b, 0xff5be28d, 0x001bcd8e, 0x001dcb4a, 0xffd6bd01, 0x00202d09, 0xffed5624, 0x00083e6a, 0xfffd7310, 0x00005f66,
+ 0x160b5331, 0xf1360276, 0x0aec8e1c, 0xf82d488c, 0x0538b136, 0xfcd929f4, 0x01a556c1, 0xff546713, 0x002135bd, 0x001a68d8, 0xffd892b4, 0x001f5489, 0xffeda7b1, 0x00082718, 0xfffd779d, 0x00005e84,
+ 0x150656f8, 0xf192e932, 0x0ac68e9b, 0xf838e6c9, 0x053a48fa, 0xfcd1eac3, 0x01adcc91, 0xff4d0f02, 0x00268f13, 0x00170a47, 0xffda6921, 0x001e7a33, 0xffedfab8, 0x00080ef7, 0xfffd7c7a, 0x00005d92,
+ 0x140330a9, 0xf1f0c9c5, 0x0a9f7537, 0xf8456f65, 0x053b3400, 0xfccb1ed7, 0x01b5fd54, 0xff45db10, 0x002bd8fa, 0x0013b003, 0xffdc4007, 0x001d9e2a, 0xffee4f29, 0x0007f60f, 0xfffd81a4, 0x00005c8e,
+ 0x1301efed, 0xf24f96b5, 0x0a7748c0, 0xf852df56, 0x053b7332, 0xfcc4c658, 0x01bde86f, 0xff3ecbea, 0x003112e0, 0x00105a72, 0xffde1726, 0x001cc091, 0xffeea4f2, 0x0007dc65, 0xfffd8719, 0x00005b7b,
+ 0x1202a434, 0xf2af428c, 0x0a4e101f, 0xf861337c, 0x053b0791, 0xfcbee162, 0x01c58d50, 0xff37e23b, 0x00363c35, 0x000d09fc, 0xffdfee3f, 0x001be18a, 0xffeefc04, 0x0007c201, 0xfffd8cd7, 0x00005a58,
+ 0x11055cb4, 0xf30fbfd7, 0x0a23d24e, 0xf870689f, 0x0539f231, 0xfcb97001, 0x01cceb6e, 0xff311ea4, 0x003b546b, 0x0009bf05, 0xffe1c511, 0x001b0138, 0xffef544e, 0x0007a6e9, 0xfffd92db, 0x00005927,
+ 0x100a2864, 0xf371012c, 0x09f8965d, 0xf8807b70, 0x0538343a, 0xfcb47232, 0x01d4024c, 0xff2a81c4, 0x00405afa, 0x000679f2, 0xffe39b60, 0x001a1fbc, 0xffefadc0, 0x00078b24, 0xfffd9923, 0x000057e9,
+ 0x0f111603, 0xf3d2f926, 0x09cc636e, 0xf8916889, 0x0535cee9, 0xfcafe7e2, 0x01dad175, 0xff240c2f, 0x00454f5d, 0x00033b23, 0xffe570ed, 0x00193d3a, 0xfff00849, 0x00076eba, 0xfffd9fac, 0x0000569d,
+ 0x0e1a340d, 0xf4359a6a, 0x099f40b5, 0xf8a32c6e, 0x0532c38c, 0xfcabd0f2, 0x01e15880, 0xff1dbe77, 0x004a310f, 0x000002f9, 0xffe7457c, 0x001859d2, 0xfff063d9, 0x000751b0, 0xfffda675, 0x00005545,
+ 0x0d2590c3, 0xf498d7a5, 0x09713575, 0xf8b5c38d, 0x052f1386, 0xfca82d32, 0x01e7970e, 0xff179926, 0x004eff94, 0xfffcd1d3, 0xffe918ce, 0x001775a7, 0xfff0c060, 0x0007340d, 0xfffdad79, 0x000053e2,
+ 0x0c333a22, 0xf4fca390, 0x09424904, 0xf8c92a41, 0x052ac04c, 0xfca4fc64, 0x01ed8cc7, 0xff119cc0, 0x0053ba6e, 0xfff9a80d, 0xffeaeaab, 0x001690d9, 0xfff11dcd, 0x000715d9, 0xfffdb4b9, 0x00005274,
+};
+}
diff --git a/services/audioflinger/audio-resampler/resampler_filter_coefficients_10042011.h b/services/audioflinger/audio-resampler/resampler_filter_coefficients_10042011.h
deleted file mode 100644
index 8c6a899..0000000
--- a/services/audioflinger/audio-resampler/resampler_filter_coefficients_10042011.h
+++ /dev/null
@@ -1,2071 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include <stdlib.h>
-
-namespace android {
-
-const int32_t resampler_filter_coefficients_10042011[] = {
-2075076504,
-2074870219,
-2074269557,
-2073262841,
-2071862786,
-2070051926,
-2067849110,
-2065243563,
-2062248465,
-2058846262,
-2055055548,
-2050866069,
-2046291635,
-2041315273,
-2035955897,
-2030204167,
-2024074532,
-2017550518,
-2010651175,
-2003368165,
-1995716923,
-1987682243,
-1979283938,
-1970514752,
-1961390076,
-1951894181,
-1942045775,
-1931837943,
-1921286728,
-1910377736,
-1899130344,
-1887538902,
-1875619770,
-1863358864,
-1850775104,
-1837863721,
-1824641940,
-1811097380,
-1797249776,
-1783095528,
-1768651291,
-1753903742,
-1738870726,
-1723548746,
-1707955054,
-1692078274,
-1675937190,
-1659529795,
-1642873313,
-1625956474,
-1608797063,
-1591393772,
-1573764495,
-1555899971,
-1537818785,
-1519520784,
-1501022796,
-1482314240,
-1463411160,
-1444313227,
-1425037741,
-1405576492,
-1385946622,
-1366149382,
-1346201706,
-1326095287,
-1305845828,
-1285455045,
-1264940308,
-1244295464,
-1223536951,
-1202667530,
-1181703085,
-1160635857,
-1139479271,
-1118235636,
-1096921134,
-1075530585,
-1054078577,
-1032568949,
-1011017224,
-989417949,
-967783970,
-946119336,
-924439752,
-902741900,
-881039249,
-859336703,
-837648175,
-815968557,
-794308053,
-772670861,
-751070988,
-729505896,
-707986911,
-686519594,
-665117063,
-643776375,
-622506966,
-601314359,
-580211607,
-559197735,
-538282662,
-517472516,
-496778402,
-476197491,
-455736426,
-435400430,
-415200497,
-395136166,
-375215078,
-355443561,
-335831583,
-316378199,
-297089183,
-277970603,
-259032151,
-240274557,
-221703918,
-203326638,
-185150446,
-167174280,
-149401179,
-131836509,
-114487708,
-97355714,
-80444376,
-63759844,
-47308498,
-31090767,
-15108809,
--631654,
--16124677,
--31368536,
--46360908,
--61095999,
--75569692,
--89781876,
--103732869,
--117417959,
--130833461,
--143977734,
--156850513,
--169446641,
--181763420,
--193799687,
--205556559,
--217029409,
--228216068,
--239114500,
--249725794,
--260045485,
--270072966,
--279807538,
--289252364,
--298404017,
--307262396,
--315825804,
--324097052,
--332072584,
--339753137,
--347137398,
--354229167,
--361025450,
--367527527,
--373733643,
--379647676,
--385266970,
--390594013,
--395628043,
--400374357,
--404831217,
--409001628,
--412884357,
--416484569,
--419800667,
--422836272,
--425590412,
--428068799,
--430270358,
--432199204,
--433854305,
--435241518,
--436360214,
--437215297,
--437806349,
--438139967,
--438216244,
--438040549,
--437612462,
--436938620,
--436019455,
--434860689,
--433462013,
--431830172,
--429966019,
--427875663,
--425559045,
--423023081,
--420269108,
--417303590,
--414126712,
--410745497,
--407161766,
--403382348,
--399407797,
--395245305,
--390897144,
--386370224,
--381665062,
--376788564,
--371743279,
--366536360,
--361168782,
--355647611,
--349975843,
--344160581,
--338202705,
--332108851,
--325882239,
--319530194,
--313054213,
--306461164,
--299754744,
--292942106,
--286024571,
--279008412,
--271897436,
--264698872,
--257414606,
--250051032,
--242612307,
--235105276,
--227531464,
--219896432,
--212204319,
--204462036,
--196671840,
--188839540,
--180969700,
--173068854,
--165138974,
--157185076,
--149211664,
--141225186,
--133228184,
--125225726,
--117222535,
--109224429,
--101233397,
--93253442,
--85289050,
--77345947,
--69426846,
--61535955,
--53678071,
--45858404,
--38079310,
--30344121,
--22657427,
--15024209,
--7447312,
-69952,
-7522929,
-14907403,
-22221174,
-29462063,
-36625813,
-43708432,
-50707112,
-57619541,
-64441301,
-71168979,
-77800149,
-84333341,
-90764454,
-97090405,
-103308422,
-109417126,
-115412500,
-121292248,
-127054242,
-132698149,
-138220442,
-143619140,
-148891701,
-154037743,
-159053739,
-163938275,
-168689170,
-173306749,
-177787867,
-182131495,
-186335286,
-190399716,
-194321853,
-198101380,
-201736519,
-205228586,
-208575166,
-211776310,
-214830056,
-217737773,
-220497194,
-223108861,
-225571114,
-227885824,
-230051117,
-232067922,
-233934597,
-235653195,
-237222146,
-238642925,
-239914316,
-241038916,
-242015623,
-242846277,
-243529706,
-244068632,
-244462216,
-244712654,
-244818983,
-244784181,
-244607765,
-244292268,
-243836913,
-243244874,
-242516010,
-241653201,
-240655918,
-239527557,
-238268354,
-236881508,
-235366743,
-233727638,
-231964766,
-230081521,
-228077731,
-225956985,
-223720128,
-221370808,
-218909157,
-216338938,
-213661333,
-210880096,
-207995414,
-205010946,
-201928111,
-198750891,
-195479864,
-192118892,
-188669741,
-185136417,
-181519490,
-177822602,
-174047687,
-170198894,
-166277172,
-162286302,
-158228508,
-154107834,
-149925117,
-145683777,
-141386129,
-137036351,
-132635752,
-128187958,
-123695608,
-119162747,
-114590586,
-109982363,
-105340765,
-100669861,
-95971242,
-91248228,
-86503703,
-81741443,
-76962776,
-72170457,
-67367307,
-62557108,
-57741653,
-52923856,
-48106777,
-43293939,
-38486954,
-33688240,
-28900789,
-24128036,
-19371931,
-14634917,
-9920080,
-5230446,
-567618,
--4066612,
--8669336,
--13237622,
--17769457,
--22262939,
--26715017,
--31123091,
--35485370,
--39800471,
--44065504,
--48278050,
--52436071,
--56538223,
--60581634,
--64564356,
--68484740,
--72342096,
--76133828,
--79858170,
--83513191,
--87098163,
--90610469,
--94048704,
--97411174,
--100697628,
--103905676,
--107034151,
--110081227,
--113046738,
--115928406,
--118725517,
--121436605,
--124062060,
--126599916,
--129049689,
--131409767,
--133680567,
--135860199,
--137948517,
--139944122,
--141847799,
--143657917,
--145374591,
--146996418,
--148524310,
--149956828,
--151294475,
--152536152,
--153683178,
--154734431,
--155690674,
--156550825,
--157316298,
--157986149,
--158561410,
--159041176,
--159427086,
--159718451,
--159916548,
--160020582,
--160032332,
--159951337,
--159779143,
--159515147,
--159161329,
--158717499,
--158185432,
--157564678,
--156857347,
--156063474,
--155185008,
--154221601,
--153175426,
--152046727,
--150837654,
--149548057,
--148180246,
--146734704,
--145213706,
--143617181,
--141947434,
--140205146,
--138392776,
--136510514,
--134560819,
--132544622,
--130464445,
--128320507,
--126115178,
--123849532,
--121526221,
--119145720,
--116710510,
--114221879,
--111682456,
--109092675,
--106454825,
--103770291,
--101041818,
--98270160,
--95457755,
--92606223,
--89718259,
--86794577,
--83837395,
--80848397,
--77830331,
--74784179,
--71712237,
--68616354,
--65499123,
--62361390,
--59205117,
--56032152,
--52845129,
--49645224,
--46434530,
--43215084,
--39989380,
--36758496,
--33524217,
--30288565,
--27054001,
--23821849,
--20593926,
--17372347,
--14159320,
--10955954,
--7763647,
--4584416,
--1420431,
-1726908,
-4856115,
-7965053,
-11051765,
-14114989,
-17153587,
-20165512,
-23148908,
-26102328,
-29024647,
-31913805,
-34768253,
-37586799,
-40368755,
-43112232,
-45815788,
-48478013,
-51098183,
-53674369,
-56205373,
-58689945,
-61127693,
-63516834,
-65856322,
-68144797,
-70381920,
-72565965,
-74696201,
-76771518,
-78791971,
-80756044,
-82663155,
-84512076,
-86302872,
-88034067,
-89705316,
-91315544,
-92865092,
-94352657,
-95778072,
-97140241,
-98439585,
-99674922,
-100846363,
-101953029,
-102995643,
-103973242,
-104886114,
-105733366,
-106515783,
-107232507,
-107884029,
-108469586,
-108990146,
-109445031,
-109834907,
-110159075,
-110418598,
-110612956,
-110743021,
-110808247,
-110809873,
-110747573,
-110622392,
-110433872,
-110183341,
-109870630,
-109496925,
-109061853,
-108566821,
-108011814,
-107398172,
-106725651,
-105995758,
-105208649,
-104365776,
-103466973,
-102513780,
-101506507,
-100446746,
-99334505,
-98171433,
-96958015,
-95695913,
-94385172,
-93027406,
-91623219,
-90174378,
-88681103,
-87145094,
-85567114,
-83948941,
-82290788,
-80594255,
-78860190,
-77090470,
-75285527,
-73447070,
-71576122,
-69674546,
-67742761,
-65782346,
-63794384,
-61780793,
-59742181,
-57680191,
-55596034,
-53491542,
-51367245,
-49224577,
-47064766,
-44889688,
-42700109,
-40497558,
-38283410,
-36059459,
-33826411,
-31585598,
-29338397,
-27086596,
-24831081,
-22573215,
-20314456,
-18056430,
-15799888,
-13545910,
-11295904,
-9051483,
-6813612,
-4583444,
-2362482,
-152205,
--2046514,
--4232760,
--6405078,
--8562051,
--10702661,
--12825994,
--14930573,
--17015184,
--19078982,
--21121361,
--23140947,
--25136591,
--27107282,
--29052375,
--30970456,
--32860543,
--34721731,
--36553615,
--38354874,
--40124623,
--41861868,
--43566233,
--45236425,
--46871781,
--48471484,
--50035443,
--51562506,
--53052109,
--54503334,
--55916090,
--57289239,
--58622387,
--59914726,
--61166369,
--62376298,
--63544241,
--64669360,
--65751822,
--66790682,
--67785875,
--68736719,
--69643614,
--70505769,
--71323237,
--72095315,
--72822435,
--73503872,
--74139832,
--74729705,
--75274073,
--75772337,
--76224828,
--76630970,
--76991410,
--77305656,
--77574197,
--77796578,
--77973591,
--78104888,
--78191082,
--78231765,
--78227787,
--78178906,
--78085845,
--77948266,
--77767093,
--77542200,
--77274423,
--76963506,
--76610446,
--76215234,
--75778805,
--75300971,
--74782775,
--74224327,
--73626669,
--72989720,
--72314602,
--71601546,
--70851655,
--70064886,
--69242354,
--68384382,
--67492158,
--66565755,
--65606354,
--64614392,
--63591082,
--62536507,
--61451798,
--60337466,
--59194800,
--58024034,
--56826376,
--55602460,
--54353584,
--53079977,
--51782773,
--50462662,
--49120984,
--47758105,
--46375208,
--44973078,
--43553013,
--42115335,
--40661095,
--39191102,
--37706696,
--36208364,
--34697230,
--33174211,
--31640600,
--30096851,
--28543956,
--26982847,
--25414822,
--23840464,
--22260795,
--20676812,
--19089709,
--17499984,
--15908468,
--14316132,
--12724175,
--11133249,
--9544240,
--7958198,
--6376234,
--4798939,
--3227038,
--1661555,
--103565,
-1446230,
-2987101,
-4517998,
-6037984,
-7546475,
-9042956,
-10526443,
-11996036,
-13451023,
-14890857,
-16314514,
-17721207,
-19110300,
-20481414,
-21833586,
-23166092,
-24478220,
-25769611,
-27039309,
-28286749,
-29511342,
-30712939,
-31890678,
-33044057,
-34172405,
-35275563,
-36352672,
-37403349,
-38427003,
-39423626,
-40392440,
-41333144,
-42245116,
-43128383,
-43982211,
-44806449,
-45600591,
-46364840,
-47098569,
-47801711,
-48473727,
-49114838,
-49724455,
-50302623,
-50848874,
-51363545,
-51846135,
-52296779,
-52715020,
-53101240,
-53455010,
-53776585,
-54065600,
-54322557,
-54547131,
-54739663,
-54899810,
-55028111,
-55124307,
-55188827,
-55221380,
-55222572,
-55192228,
-55130859,
-55038225,
-54914980,
-54761033,
-54576974,
-54362622,
-54118682,
-53845150,
-53542695,
-53211202,
-52851427,
-52463450,
-52047991,
-51604968,
-51135146,
-50638673,
-50116337,
-49568129,
-48994861,
-48396765,
-47774658,
-47128548,
-46459228,
-45766990,
-45052710,
-44316493,
-43559189,
-42781174,
-41983339,
-41165794,
-40329347,
-39474419,
-38601939,
-37712110,
-36805777,
-35883432,
-34945984,
-33993615,
-33027089,
-32046926,
-31054070,
-30048815,
-29031979,
-28004160,
-26966277,
-25918608,
-24861885,
-23796723,
-22724052,
-21644243,
-20558050,
-19466141,
-18369382,
-17268088,
-16162890,
-15054445,
-13943628,
-12830865,
-11716830,
-10602238,
-9487911,
-8374236,
-7261776,
-6151235,
-5043417,
-3938790,
-2837924,
-1741550,
-650377,
--435204,
--1514773,
--2587638,
--3653109,
--4710700,
--5759963,
--6800171,
--7830712,
--8851149,
--9861153,
--10860035,
--11847221,
--12822216,
--13784698,
--14733981,
--15669597,
--16591140,
--17498438,
--18390866,
--19267997,
--20129356,
--20974762,
--21803581,
--22615471,
--23410012,
--24187134,
--24946258,
--25687095,
--26409195,
--27112509,
--27796483,
--28460937,
--29105505,
--29730269,
--30334749,
--30918819,
--31482081,
--32024624,
--32545988,
--33046126,
--33524693,
--33981867,
--34417247,
--34830850,
--35222329,
--35591891,
--35939181,
--36264307,
--36566990,
--36847536,
--37105661,
--37341533,
--37554878,
--37746021,
--37914721,
--38061211,
--38185256,
--38287239,
--38366977,
--38424762,
--38460388,
--38474270,
--38466280,
--38436775,
--38385595,
--38313205,
--38219543,
--38105021,
--37969515,
--37813522,
--37637035,
--37440507,
--37223843,
--36987554,
--36731686,
--36456739,
--36162666,
--35850010,
--35518873,
--35169788,
--34802724,
--34418227,
--34016443,
--33597949,
--33162777,
--32711507,
--32244345,
--31761885,
--31264164,
--30751745,
--30224868,
--29684158,
--29129713,
--28562123,
--27981679,
--27389002,
--26784181,
--26167762,
--25540059,
--24901722,
--24252917,
--23594223,
--22926012,
--22248923,
--21563113,
--20869110,
--20167303,
--19458342,
--18742448,
--18020168,
--17291929,
--16558346,
--15819604,
--15076174,
--14328481,
--13577150,
--12822445,
--12064865,
--11304882,
--10543086,
--9779720,
--9015209,
--8250021,
--7484741,
--6719667,
--5955234,
--5191932,
--4430285,
--3670541,
--2913036,
--2158236,
--1406657,
--658617,
-85527,
-825280,
-1560174,
-2289926,
-3014260,
-3732701,
-4444806,
-5150245,
-5848747,
-6539832,
-7223129,
-7898368,
-8565383,
-9223733,
-9873071,
-10513075,
-11143565,
-11764092,
-12374365,
-12974099,
-13563194,
-14141234,
-14707964,
-15263070,
-15806466,
-16337748,
-16856735,
-17363175,
-17857079,
-18338088,
-18806059,
-19260708,
-19702046,
-20129723,
-20543652,
-20943584,
-21329597,
-21701383,
-22058894,
-22401875,
-22730421,
-23044252,
-23343385,
-23627618,
-23897120,
-24151661,
-24391299,
-24615824,
-24825417,
-25019868,
-25199285,
-25363488,
-25512702,
-25646760,
-25765809,
-25869680,
-25958622,
-26032502,
-26091517,
-26135536,
-26164850,
-26179375,
-26179344,
-26164644,
-26135585,
-26092113,
-26034498,
-25962646,
-25876887,
-25777203,
-25663899,
-25536906,
-25396578,
-25242934,
-25076305,
-24896644,
-24704311,
-24499364,
-24282163,
-24052697,
-23811348,
-23558211,
-23293664,
-23017702,
-22730703,
-22432787,
-22124357,
-21805445,
-21476448,
-21137523,
-20789074,
-20431134,
-20064079,
-19688086,
-19303582,
-18910646,
-18509679,
-18100894,
-17684716,
-17261223,
-16830785,
-16393630,
-15950197,
-15500602,
-15045231,
-14584340,
-14118348,
-13647355,
-13171699,
-12691641,
-12207609,
-11719754,
-11228437,
-10733948,
-10236700,
-9736830,
-9234652,
-8730459,
-8224662,
-7717439,
-7209110,
-6699986,
-6190443,
-5680626,
-5170792,
-4661242,
-4152348,
-3644304,
-3137385,
-2631912,
-2128229,
-1626510,
-1126973,
-629931,
-135715,
--355469,
--843402,
--1327763,
--1808270,
--2284755,
--2757069,
--3224916,
--3688026,
--4146190,
--4599250,
--5046898,
--5488901,
--5925074,
--6355314,
--6779333,
--7196918,
--7607862,
--8012069,
--8409254,
--8799255,
--9181907,
--9557181,
--9924822,
--10284691,
--10636595,
--10980501,
--11316157,
--11643459,
--11962240,
--12272514,
--12574056,
--12866786,
--13150528,
--13425307,
--13690910,
--13947306,
--14194356,
--14432139,
--14660477,
--14879363,
--15088645,
--15288408,
--15478483,
--15658898,
--15829522,
--15990474,
--16141613,
--16282992,
--16414484,
--16536222,
--16648083,
--16750160,
--16842353,
--16924831,
--16997506,
--17060493,
--17113697,
--17157297,
--17191222,
--17215613,
--17230389,
--17235750,
--17231648,
--17218249,
--17195484,
--17163567,
--17122473,
--17072392,
--17013271,
--16945340,
--16868599,
--16783258,
--16689284,
--16586915,
--16476178,
--16357294,
--16230239,
--16095254,
--15952382,
--15801866,
--15643700,
--15478137,
--15305245,
--15125274,
--14938221,
--14744336,
--14543701,
--14336583,
--14123005,
--13903232,
--13677369,
--13445685,
--13208205,
--12965179,
--12716724,
--12463120,
--12204418,
--11940874,
--11672628,
--11399952,
--11122887,
--10841668,
--10556438,
--10267479,
--9974863,
--9678839,
--9379572,
--9077334,
--8772193,
--8464370,
--8154033,
--7841459,
--7526740,
--7210102,
--6891729,
--6571875,
--6250617,
--5928143,
--5604631,
--5280339,
--4955374,
--4629936,
--4304221,
--3978468,
--3652773,
--3327303,
--3002250,
--2677848,
--2354215,
--2031520,
--1709962,
--1389747,
--1070968,
--753751,
--438281,
--124760,
-186691,
-495939,
-802786,
-1107056,
-1408639,
-1707439,
-2003270,
-2295964,
-2585396,
-2871472,
-3154006,
-3432861,
-3707940,
-3979193,
-4246453,
-4509594,
-4768498,
-5023110,
-5273258,
-5518843,
-5759760,
-5995988,
-6227371,
-6453823,
-6675229,
-6891575,
-7102708,
-7308575,
-7509086,
-7704267,
-7893987,
-8078205,
-8256820,
-8429855,
-8597183,
-8758786,
-8914577,
-9064605,
-9208760,
-9347039,
-9479353,
-9605758,
-9726154,
-9840566,
-9948924,
-10051316,
-10147660,
-10237999,
-10322257,
-10400525,
-10472731,
-10538934,
-10599070,
-10653248,
-10701410,
-10743630,
-10779849,
-10810183,
-10834587,
-10853155,
-10865840,
-10872775,
-10873933,
-10869421,
-10859197,
-10843400,
-10822013,
-10795156,
-10762793,
-10725068,
-10681980,
-10633658,
-10580078,
-10521391,
-10457608,
-10388869,
-10315156,
-10236621,
-10153290,
-10065313,
-9972683,
-9875561,
-9773986,
-9668111,
-9557933,
-9443609,
-9325184,
-9202823,
-9076535,
-8946481,
-8812721,
-8675419,
-8534581,
-8390359,
-8242821,
-8092134,
-7938325,
-7781551,
-7621894,
-7459519,
-7294449,
-7126832,
-6956750,
-6784374,
-6609741,
-6433003,
-6254252,
-6073651,
-5891227,
-5707114,
-5521403,
-5334259,
-5145731,
-4955957,
-4765041,
-4573140,
-4380296,
-4186630,
-3992245,
-3797298,
-3601843,
-3406004,
-3209891,
-3013645,
-2817308,
-2620977,
-2424757,
-2228787,
-2033128,
-1837884,
-1643168,
-1449107,
-1255755,
-1063192,
-871528,
-680885,
-491329,
-302942,
-115833,
--69891,
--254183,
--436990,
--618208,
--797740,
--975518,
--1151487,
--1325539,
--1497588,
--1667578,
--1835474,
--2001175,
--2164603,
--2325693,
--2484411,
--2640658,
--2794375,
--2945514,
--3094068,
--3239949,
--3383105,
--3523475,
--3661049,
--3795739,
--3927507,
--4056301,
--4182128,
--4304909,
--4424616,
--4541189,
--4654642,
--4764898,
--4871946,
--4975742,
--5076322,
--5173620,
--5267633,
--5358312,
--5445689,
--5529702,
--5610360,
--5687620,
--5761528,
--5832032,
--5899149,
--5962833,
--6023137,
--6080011,
--6133489,
--6183535,
--6230216,
--6273495,
--6313411,
--6349927,
--6383111,
--6412929,
--6439430,
--6462582,
--6482459,
--6499037,
--6512371,
--6522432,
--6529297,
--6532949,
--6533453,
--6530785,
--6525030,
--6516181,
--6504306,
--6489387,
--6471510,
--6450672,
--6426949,
--6400323,
--6370884,
--6338633,
--6303653,
--6265930,
--6225556,
--6182542,
--6136972,
--6088835,
--6038222,
--5985148,
--5929704,
--5871883,
--5811781,
--5749418,
--5684887,
--5618180,
--5549390,
--5478541,
--5405727,
--5330951,
--5254303,
--5175817,
--5095584,
--5013604,
--4929960,
--4844689,
--4757882,
--4669550,
--4579780,
--4488613,
--4396142,
--4302370,
--4207380,
--4111213,
--4013962,
--3915640,
--3816329,
--3716076,
--3614967,
--3513009,
--3410272,
--3306801,
--3202684,
--3097938,
--2992636,
--2886829,
--2780600,
--2673962,
--2566977,
--2459696,
--2352199,
--2244507,
--2136684,
--2028782,
--1920874,
--1812971,
--1705121,
--1597373,
--1489799,
--1382421,
--1275290,
--1168459,
--1061994,
--955913,
--850253,
--745067,
--640414,
--536322,
--432828,
--329984,
--227841,
--126414,
--25726,
-74177,
-173245,
-271455,
-368780,
-465170,
-560585,
-655003,
-748412,
-840765,
-932024,
-1022164,
-1111173,
-1199003,
-1285630,
-1371035,
-1455222,
-1538151,
-1619799,
-1700140,
-1779174,
-1856860,
-1933182,
-2008118,
-2081679,
-2153827,
-2224550,
-2293824,
-2361659,
-2428020,
-2492903,
-2556292,
-2618211,
-2678631,
-2737549,
-2794945,
-2850839,
-2905201,
-2958036,
-3009325,
-3059097,
-3107325,
-3154018,
-3199156,
-3242768,
-3284829,
-3325357,
-3364336,
-3401806,
-3437747,
-3472179,
-3505082,
-3536494,
-3566396,
-3594812,
-3621723,
-3647174,
-3671149,
-3693673,
-3714729,
-3734362,
-3752557,
-3769346,
-3784715,
-3798715,
-3811334,
-3822606,
-3832516,
-3841112,
-3848384,
-3854368,
-3859049,
-3862479,
-3864649,
-3865599,
-3865314,
-3863845,
-3861188,
-3857383,
-3852418,
-3846346,
-3839164,
-3830915,
-3821584,
-3811225,
-3799836,
-3787460,
-3774084,
-3759760,
-3744487,
-3728310,
-3711218,
-3693263,
-3674447,
-3654814,
-3634352,
-3613113,
-3591098,
-3568353,
-3544866,
-3520689,
-3495824,
-3470316,
-3444153,
-3417383,
-3390012,
-3362082,
-3333586,
-3304570,
-3275042,
-3245044,
-3214563,
-3183645,
-3152295,
-3120556,
-3088416,
-3055921,
-3023078,
-2989927,
-2956457,
-2922708,
-2888688,
-2854437,
-2819945,
-2785255,
-2750373,
-2715338,
-2680135,
-2644802,
-2609344,
-2573798,
-2538153,
-2502446,
-2466684,
-2430901,
-2395085,
-2359269,
-2323458,
-2287688,
-2251947,
-2216270,
-2180661,
-2145152,
-2109728,
-2074417,
-2039222,
-2004173,
-1969258,
-1934504,
-1899918,
-1865524,
-1831311,
-1797303,
-1763503,
-1729936,
-1696594,
-1663499,
-1630656,
-1598085,
-1565774,
-1533740,
-1501984,
-1470527,
-1439358,
-1408495,
-1377941,
-1347715,
-1317803,
-1288221,
-1258970,
-1230067,
-1201504,
-1173294,
-1145440,
-1117954,
-1090824,
-1064057,
-1037655,
-1011629,
-985969,
-960683,
-935774,
-911250,
-887101,
-863334,
-839947,
-816951,
-794337,
-772110,
-750271,
-728827,
-707764,
-687085,
-666787,
-646876,
-627343,
-608189,
-589415,
-571023,
-553003,
-535356,
-518081,
-501181,
-484646,
-468479,
-452677,
-437242,
-422161,
-407434,
-393055,
-379026,
-365337,
-351987,
-338974,
-326296,
-313944,
-301916,
-290208,
-278820,
-267744,
-256978,
-246518,
-236362,
-226500,
-216928,
-207640,
-198636,
-189906,
-181447,
-173255,
-165327,
-157655,
-150236,
-143064,
-136137,
-129449,
-122995,
-116772,
-110776,
-104999,
-99436,
-94081,
-88932,
-83981,
-79224,
-74658,
-70277,
-66077,
-62052,
-58198,
-54512,
-50989,
-47624,
-44413,
-41353,
-38438,
-35663,
-33023,
-30515,
-28134,
-25876,
-23736,
-21712,
-19799,
-17992,
-16290,
-14687,
-13182,
-11769,
-10446,
-9210,
-8057,
-6982,
-5983,
-5056,
-4198,
-3407,
-2678,
-2010,
-1400,
-844,
-341,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-};
-}
diff --git a/services/audioflinger/test-resample.cpp b/services/audioflinger/test-resample.cpp
new file mode 100644
index 0000000..b082e8c
--- /dev/null
+++ b/services/audioflinger/test-resample.cpp
@@ -0,0 +1,274 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "AudioResampler.h"
+#include <media/AudioBufferProvider.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <time.h>
+#include <math.h>
+
+using namespace android;
+
+struct HeaderWav {
+ HeaderWav(size_t size, int nc, int sr, int bits) {
+ strncpy(RIFF, "RIFF", 4);
+ chunkSize = size + sizeof(HeaderWav);
+ strncpy(WAVE, "WAVE", 4);
+ strncpy(fmt, "fmt ", 4);
+ fmtSize = 16;
+ audioFormat = 1;
+ numChannels = nc;
+ samplesRate = sr;
+ byteRate = sr * numChannels * (bits/8);
+ align = nc*(bits/8);
+ bitsPerSample = bits;
+ strncpy(data, "data", 4);
+ dataSize = size;
+ }
+
+ char RIFF[4]; // RIFF
+ uint32_t chunkSize; // File size
+ char WAVE[4]; // WAVE
+ char fmt[4]; // fmt\0
+ uint32_t fmtSize; // fmt size
+ uint16_t audioFormat; // 1=PCM
+ uint16_t numChannels; // num channels
+ uint32_t samplesRate; // sample rate in hz
+ uint32_t byteRate; // Bps
+ uint16_t align; // 2=16-bit mono, 4=16-bit stereo
+ uint16_t bitsPerSample; // bits per sample
+ char data[4]; // "data"
+ uint32_t dataSize; // size
+};
+
+static int usage(const char* name) {
+ fprintf(stderr,"Usage: %s [-p] [-h] [-s] [-q {dq|lq|mq|hq|vhq}] [-i input-sample-rate] "
+ "[-o output-sample-rate] [<input-file>] <output-file>\n", name);
+ fprintf(stderr," -p enable profiling\n");
+ fprintf(stderr," -h create wav file\n");
+ fprintf(stderr," -s stereo\n");
+ fprintf(stderr," -q resampler quality\n");
+ fprintf(stderr," dq : default quality\n");
+ fprintf(stderr," lq : low quality\n");
+ fprintf(stderr," mq : medium quality\n");
+ fprintf(stderr," hq : high quality\n");
+ fprintf(stderr," vhq : very high quality\n");
+ fprintf(stderr," -i input file sample rate\n");
+ fprintf(stderr," -o output file sample rate\n");
+ return -1;
+}
+
+int main(int argc, char* argv[]) {
+
+ const char* const progname = argv[0];
+ bool profiling = false;
+ bool writeHeader = false;
+ int channels = 1;
+ int input_freq = 0;
+ int output_freq = 0;
+ AudioResampler::src_quality quality = AudioResampler::DEFAULT_QUALITY;
+
+ int ch;
+ while ((ch = getopt(argc, argv, "phsq:i:o:")) != -1) {
+ switch (ch) {
+ case 'p':
+ profiling = true;
+ break;
+ case 'h':
+ writeHeader = true;
+ break;
+ case 's':
+ channels = 2;
+ break;
+ case 'q':
+ if (!strcmp(optarg, "dq"))
+ quality = AudioResampler::DEFAULT_QUALITY;
+ else if (!strcmp(optarg, "lq"))
+ quality = AudioResampler::LOW_QUALITY;
+ else if (!strcmp(optarg, "mq"))
+ quality = AudioResampler::MED_QUALITY;
+ else if (!strcmp(optarg, "hq"))
+ quality = AudioResampler::HIGH_QUALITY;
+ else if (!strcmp(optarg, "vhq"))
+ quality = AudioResampler::VERY_HIGH_QUALITY;
+ else {
+ usage(progname);
+ return -1;
+ }
+ break;
+ case 'i':
+ input_freq = atoi(optarg);
+ break;
+ case 'o':
+ output_freq = atoi(optarg);
+ break;
+ case '?':
+ default:
+ usage(progname);
+ return -1;
+ }
+ }
+ argc -= optind;
+ argv += optind;
+
+ const char* file_in = NULL;
+ const char* file_out = NULL;
+ if (argc == 1) {
+ file_out = argv[0];
+ } else if (argc == 2) {
+ file_in = argv[0];
+ file_out = argv[1];
+ } else {
+ usage(progname);
+ return -1;
+ }
+
+ // ----------------------------------------------------------
+
+ size_t input_size;
+ void* input_vaddr;
+ if (argc == 2) {
+ struct stat st;
+ if (stat(file_in, &st) < 0) {
+ fprintf(stderr, "stat: %s\n", strerror(errno));
+ return -1;
+ }
+
+ int input_fd = open(file_in, O_RDONLY);
+ if (input_fd < 0) {
+ fprintf(stderr, "open: %s\n", strerror(errno));
+ return -1;
+ }
+
+ input_size = st.st_size;
+ input_vaddr = mmap(0, input_size, PROT_READ, MAP_PRIVATE, input_fd, 0);
+ if (input_vaddr == MAP_FAILED ) {
+ fprintf(stderr, "mmap: %s\n", strerror(errno));
+ return -1;
+ }
+ } else {
+ double k = 1000; // Hz / s
+ double time = (input_freq / 2) / k;
+ size_t input_frames = size_t(input_freq * time);
+ input_size = channels * sizeof(int16_t) * input_frames;
+ input_vaddr = malloc(input_size);
+ int16_t* in = (int16_t*)input_vaddr;
+ for (size_t i=0 ; i<input_frames ; i++) {
+ double t = double(i) / input_freq;
+ double y = sin(M_PI * k * t * t);
+ int16_t yi = floor(y * 32767.0 + 0.5);
+ for (size_t j=0 ; j<(size_t)channels ; j++) {
+ in[i*channels + j] = yi / (1+j);
+ }
+ }
+ }
+
+ // ----------------------------------------------------------
+
+ class Provider: public AudioBufferProvider {
+ int16_t* mAddr;
+ size_t mNumFrames;
+ public:
+ Provider(const void* addr, size_t size, int channels) {
+ mAddr = (int16_t*) addr;
+ mNumFrames = size / (channels*sizeof(int16_t));
+ }
+ virtual status_t getNextBuffer(Buffer* buffer,
+ int64_t pts = kInvalidPTS) {
+ buffer->frameCount = mNumFrames;
+ buffer->i16 = mAddr;
+ return NO_ERROR;
+ }
+ virtual void releaseBuffer(Buffer* buffer) {
+ }
+ } provider(input_vaddr, input_size, channels);
+
+ size_t input_frames = input_size / (channels * sizeof(int16_t));
+ size_t output_size = 2 * 4 * ((int64_t) input_frames * output_freq) / input_freq;
+ output_size &= ~7; // always stereo, 32-bits
+
+ void* output_vaddr = malloc(output_size);
+
+ if (profiling) {
+ AudioResampler* resampler = AudioResampler::create(16, channels,
+ output_freq, quality);
+
+ size_t out_frames = output_size/8;
+ resampler->setSampleRate(input_freq);
+ resampler->setVolume(0x1000, 0x1000);
+
+ memset(output_vaddr, 0, output_size);
+ timespec start, end;
+ clock_gettime(CLOCK_MONOTONIC_HR, &start);
+ resampler->resample((int*) output_vaddr, out_frames, &provider);
+ resampler->resample((int*) output_vaddr, out_frames, &provider);
+ resampler->resample((int*) output_vaddr, out_frames, &provider);
+ resampler->resample((int*) output_vaddr, out_frames, &provider);
+ clock_gettime(CLOCK_MONOTONIC_HR, &end);
+ int64_t start_ns = start.tv_sec * 1000000000LL + start.tv_nsec;
+ int64_t end_ns = end.tv_sec * 1000000000LL + end.tv_nsec;
+ int64_t time = (end_ns - start_ns)/4;
+ printf("%f Mspl/s\n", out_frames/(time/1e9)/1e6);
+
+ delete resampler;
+ }
+
+ AudioResampler* resampler = AudioResampler::create(16, channels,
+ output_freq, quality);
+ size_t out_frames = output_size/8;
+ resampler->setSampleRate(input_freq);
+ resampler->setVolume(0x1000, 0x1000);
+
+ memset(output_vaddr, 0, output_size);
+ resampler->resample((int*) output_vaddr, out_frames, &provider);
+
+ // down-mix (we just truncate and keep the left channel)
+ int32_t* out = (int32_t*) output_vaddr;
+ int16_t* convert = (int16_t*) malloc(out_frames * channels * sizeof(int16_t));
+ for (size_t i = 0; i < out_frames; i++) {
+ for (int j=0 ; j<channels ; j++) {
+ int32_t s = out[i * 2 + j] >> 12;
+ if (s > 32767) s = 32767;
+ else if (s < -32768) s = -32768;
+ convert[i * channels + j] = int16_t(s);
+ }
+ }
+
+ // write output to disk
+ int output_fd = open(file_out, O_WRONLY | O_CREAT | O_TRUNC,
+ S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+ if (output_fd < 0) {
+ fprintf(stderr, "open: %s\n", strerror(errno));
+ return -1;
+ }
+
+ if (writeHeader) {
+ HeaderWav wav(out_frames * channels * sizeof(int16_t), channels, output_freq, 16);
+ write(output_fd, &wav, sizeof(wav));
+ }
+
+ write(output_fd, convert, out_frames * channels * sizeof(int16_t));
+ close(output_fd);
+
+ return 0;
+}
diff --git a/services/camera/libcameraservice/Android.mk b/services/camera/libcameraservice/Android.mk
index eff47c8..5245983 100644
--- a/services/camera/libcameraservice/Android.mk
+++ b/services/camera/libcameraservice/Android.mk
@@ -28,7 +28,6 @@ LOCAL_SHARED_LIBRARIES:= \
libbinder \
libcutils \
libmedia \
- libmedia_native \
libcamera_client \
libgui \
libhardware \
@@ -40,6 +39,9 @@ LOCAL_C_INCLUDES += \
system/media/camera/include \
external/jpeg
+
+LOCAL_CFLAGS += -Wall -Wextra
+
LOCAL_MODULE:= libcameraservice
include $(BUILD_SHARED_LIBRARY)
diff --git a/services/camera/libcameraservice/Camera2Client.cpp b/services/camera/libcameraservice/Camera2Client.cpp
index e59a240..9627416 100644
--- a/services/camera/libcameraservice/Camera2Client.cpp
+++ b/services/camera/libcameraservice/Camera2Client.cpp
@@ -37,10 +37,6 @@ static int getCallingPid() {
return IPCThreadState::self()->getCallingPid();
}
-static int getCallingUid() {
- return IPCThreadState::self()->getCallingUid();
-}
-
// Interface used by CameraService
Camera2Client::Camera2Client(const sp<CameraService>& cameraService,
@@ -370,7 +366,6 @@ status_t Camera2Client::dump(int fd, const Vector<String16>& args) {
void Camera2Client::disconnect() {
ATRACE_CALL();
Mutex::Autolock icl(mICameraLock);
- status_t res;
// Allow both client and the media server to disconnect at all times
int callingPid = getCallingPid();
@@ -575,7 +570,7 @@ void Camera2Client::setPreviewCallbackFlag(int flag) {
ATRACE_CALL();
ALOGV("%s: Camera %d: Flag 0x%x", __FUNCTION__, mCameraId, flag);
Mutex::Autolock icl(mICameraLock);
- status_t res;
+
if ( checkPid(__FUNCTION__) != OK) return;
SharedParameters::Lock l(mParameters);
@@ -1062,7 +1057,7 @@ status_t Camera2Client::cancelAutoFocus() {
return OK;
}
-status_t Camera2Client::takePicture(int msgType) {
+status_t Camera2Client::takePicture(int /*msgType*/) {
ATRACE_CALL();
Mutex::Autolock icl(mICameraLock);
status_t res;
@@ -1244,7 +1239,7 @@ status_t Camera2Client::commandPlayRecordingSoundL() {
return OK;
}
-status_t Camera2Client::commandStartFaceDetectionL(int type) {
+status_t Camera2Client::commandStartFaceDetectionL(int /*type*/) {
ALOGV("%s: Camera %d: Starting face detection",
__FUNCTION__, mCameraId);
status_t res;
@@ -1331,6 +1326,8 @@ void Camera2Client::notifyError(int errorCode, int arg1, int arg2) {
}
void Camera2Client::notifyShutter(int frameNumber, nsecs_t timestamp) {
+ (void)frameNumber;
+ (void)timestamp;
ALOGV("%s: Shutter notification for frame %d at time %lld", __FUNCTION__,
frameNumber, timestamp);
}
@@ -1452,6 +1449,8 @@ void Camera2Client::notifyAutoExposure(uint8_t newState, int triggerId) {
}
void Camera2Client::notifyAutoWhitebalance(uint8_t newState, int triggerId) {
+ (void)newState;
+ (void)triggerId;
ALOGV("%s: Auto-whitebalance state now %d, last trigger %d",
__FUNCTION__, newState, triggerId);
}
diff --git a/services/camera/libcameraservice/Camera2Device.cpp b/services/camera/libcameraservice/Camera2Device.cpp
index d6445c1..5bfa085 100644
--- a/services/camera/libcameraservice/Camera2Device.cpp
+++ b/services/camera/libcameraservice/Camera2Device.cpp
@@ -765,7 +765,6 @@ status_t Camera2Device::MetadataQueue::setStreamSlot(
ATRACE_CALL();
ALOGV("%s: E", __FUNCTION__);
Mutex::Autolock l(mMutex);
- status_t res;
if (mStreamSlotCount > 0) {
freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
@@ -785,7 +784,7 @@ status_t Camera2Device::MetadataQueue::setStreamSlot(
}
status_t Camera2Device::MetadataQueue::dump(int fd,
- const Vector<String16>& args) {
+ const Vector<String16>& /*args*/) {
ATRACE_CALL();
String8 result;
status_t notLocked;
@@ -894,12 +893,13 @@ int Camera2Device::MetadataQueue::consumer_free(
{
ATRACE_CALL();
MetadataQueue *queue = getInstance(q);
+ (void)queue;
free_camera_metadata(old_buffer);
return OK;
}
int Camera2Device::MetadataQueue::producer_dequeue(
- const camera2_frame_queue_dst_ops_t *q,
+ const camera2_frame_queue_dst_ops_t * /*q*/,
size_t entries, size_t bytes,
camera_metadata_t **buffer)
{
@@ -912,7 +912,7 @@ int Camera2Device::MetadataQueue::producer_dequeue(
}
int Camera2Device::MetadataQueue::producer_cancel(
- const camera2_frame_queue_dst_ops_t *q,
+ const camera2_frame_queue_dst_ops_t * /*q*/,
camera_metadata_t *old_buffer)
{
ATRACE_CALL();
@@ -1184,7 +1184,7 @@ status_t Camera2Device::StreamAdapter::setTransform(int transform) {
}
status_t Camera2Device::StreamAdapter::dump(int fd,
- const Vector<String16>& args) {
+ const Vector<String16>& /*args*/) {
ATRACE_CALL();
String8 result = String8::format(" Stream %d: %d x %d, format 0x%x\n",
mId, mWidth, mHeight, mFormat);
@@ -1423,7 +1423,7 @@ status_t Camera2Device::ReprocessStreamAdapter::pushIntoStream(
}
status_t Camera2Device::ReprocessStreamAdapter::dump(int fd,
- const Vector<String16>& args) {
+ const Vector<String16>& /*args*/) {
ATRACE_CALL();
String8 result =
String8::format(" Reprocess stream %d: %d x %d, fmt 0x%x\n",
@@ -1444,7 +1444,7 @@ int Camera2Device::ReprocessStreamAdapter::acquire_buffer(
const camera2_stream_in_ops_t *w,
buffer_handle_t** buffer) {
ATRACE_CALL();
- int res;
+
ReprocessStreamAdapter* stream =
const_cast<ReprocessStreamAdapter*>(
static_cast<const ReprocessStreamAdapter*>(w));
diff --git a/services/camera/libcameraservice/CameraClient.cpp b/services/camera/libcameraservice/CameraClient.cpp
index b930c02..006a9c9 100644
--- a/services/camera/libcameraservice/CameraClient.cpp
+++ b/services/camera/libcameraservice/CameraClient.cpp
@@ -34,10 +34,6 @@ static int getCallingPid() {
return IPCThreadState::self()->getCallingPid();
}
-static int getCallingUid() {
- return IPCThreadState::self()->getCallingUid();
-}
-
CameraClient::CameraClient(const sp<CameraService>& cameraService,
const sp<ICameraClient>& cameraClient,
int cameraId, int cameraFacing, int clientPid, int servicePid):
diff --git a/services/camera/libcameraservice/CameraHardwareInterface.h b/services/camera/libcameraservice/CameraHardwareInterface.h
index 05ac9fa..167b37c 100644
--- a/services/camera/libcameraservice/CameraHardwareInterface.h
+++ b/services/camera/libcameraservice/CameraHardwareInterface.h
@@ -427,7 +427,7 @@ public:
/**
* Dump state of the camera hardware
*/
- status_t dump(int fd, const Vector<String16>& args) const
+ status_t dump(int fd, const Vector<String16>& /*args*/) const
{
ALOGV("%s(%s)", __FUNCTION__, mName.string());
if (mDevice->ops->dump)
@@ -584,9 +584,10 @@ private:
#endif
static int __lock_buffer(struct preview_stream_ops* w,
- buffer_handle_t* buffer)
+ buffer_handle_t* /*buffer*/)
{
ANativeWindow *a = anw(w);
+ (void)a;
return 0;
}
diff --git a/services/camera/libcameraservice/camera2/BurstCapture.cpp b/services/camera/libcameraservice/camera2/BurstCapture.cpp
index f56c50c..192d419 100644
--- a/services/camera/libcameraservice/camera2/BurstCapture.cpp
+++ b/services/camera/libcameraservice/camera2/BurstCapture.cpp
@@ -38,7 +38,8 @@ BurstCapture::BurstCapture(wp<Camera2Client> client, wp<CaptureSequencer> sequen
BurstCapture::~BurstCapture() {
}
-status_t BurstCapture::start(Vector<CameraMetadata> &metadatas, int32_t firstCaptureId) {
+status_t BurstCapture::start(Vector<CameraMetadata> &/*metadatas*/,
+ int32_t /*firstCaptureId*/) {
ALOGE("Not completely implemented");
return INVALID_OPERATION;
}
@@ -75,7 +76,7 @@ bool BurstCapture::threadLoop() {
CpuConsumer::LockedBuffer* BurstCapture::jpegEncode(
CpuConsumer::LockedBuffer *imgBuffer,
- int quality)
+ int /*quality*/)
{
ALOGV("%s", __FUNCTION__);
@@ -91,7 +92,7 @@ CpuConsumer::LockedBuffer* BurstCapture::jpegEncode(
buffers.push_back(imgEncoded);
sp<JpegCompressor> jpeg = new JpegCompressor();
- status_t res = jpeg->start(buffers, 1);
+ jpeg->start(buffers, 1);
bool success = jpeg->waitForDone(10 * 1e9);
if(success) {
@@ -103,7 +104,7 @@ CpuConsumer::LockedBuffer* BurstCapture::jpegEncode(
}
}
-status_t BurstCapture::processFrameAvailable(sp<Camera2Client> &client) {
+status_t BurstCapture::processFrameAvailable(sp<Camera2Client> &/*client*/) {
ALOGE("Not implemented");
return INVALID_OPERATION;
}
diff --git a/services/camera/libcameraservice/camera2/CallbackProcessor.cpp b/services/camera/libcameraservice/camera2/CallbackProcessor.cpp
index 3e9c255..307cfab 100644
--- a/services/camera/libcameraservice/camera2/CallbackProcessor.cpp
+++ b/services/camera/libcameraservice/camera2/CallbackProcessor.cpp
@@ -119,7 +119,6 @@ status_t CallbackProcessor::updateStream(const Parameters &params) {
status_t CallbackProcessor::deleteStream() {
ATRACE_CALL();
- status_t res;
Mutex::Autolock l(mInputMutex);
@@ -144,7 +143,7 @@ int CallbackProcessor::getStreamId() const {
return mCallbackStreamId;
}
-void CallbackProcessor::dump(int fd, const Vector<String16>& args) const {
+void CallbackProcessor::dump(int /*fd*/, const Vector<String16>& /*args*/) const {
}
bool CallbackProcessor::threadLoop() {
@@ -173,7 +172,6 @@ status_t CallbackProcessor::processNewCallback(sp<Camera2Client> &client) {
ATRACE_CALL();
status_t res;
- int callbackHeapId;
sp<Camera2Heap> callbackHeap;
size_t heapIdx;
diff --git a/services/camera/libcameraservice/camera2/CaptureSequencer.cpp b/services/camera/libcameraservice/camera2/CaptureSequencer.cpp
index fe4abc0..b228faf 100644
--- a/services/camera/libcameraservice/camera2/CaptureSequencer.cpp
+++ b/services/camera/libcameraservice/camera2/CaptureSequencer.cpp
@@ -128,7 +128,7 @@ void CaptureSequencer::onCaptureAvailable(nsecs_t timestamp,
}
-void CaptureSequencer::dump(int fd, const Vector<String16>& args) {
+void CaptureSequencer::dump(int fd, const Vector<String16>& /*args*/) {
String8 result;
if (mCaptureRequest.entryCount() != 0) {
result = " Capture request:\n";
@@ -182,7 +182,6 @@ const CaptureSequencer::StateManager
};
bool CaptureSequencer::threadLoop() {
- status_t res;
sp<Camera2Client> client = mClient.promote();
if (client == 0) return false;
@@ -213,7 +212,8 @@ bool CaptureSequencer::threadLoop() {
return true;
}
-CaptureSequencer::CaptureState CaptureSequencer::manageIdle(sp<Camera2Client> &client) {
+CaptureSequencer::CaptureState CaptureSequencer::manageIdle(
+ sp<Camera2Client> &/*client*/) {
status_t res;
Mutex::Autolock l(mInputMutex);
while (!mStartCapture) {
@@ -350,13 +350,13 @@ CaptureSequencer::CaptureState CaptureSequencer::manageZslStart(
}
CaptureSequencer::CaptureState CaptureSequencer::manageZslWaiting(
- sp<Camera2Client> &client) {
+ sp<Camera2Client> &/*client*/) {
ALOGV("%s", __FUNCTION__);
return DONE;
}
CaptureSequencer::CaptureState CaptureSequencer::manageZslReprocessing(
- sp<Camera2Client> &client) {
+ sp<Camera2Client> &/*client*/) {
ALOGV("%s", __FUNCTION__);
return START;
}
@@ -378,7 +378,7 @@ CaptureSequencer::CaptureState CaptureSequencer::manageStandardStart(
}
CaptureSequencer::CaptureState CaptureSequencer::manageStandardPrecaptureWait(
- sp<Camera2Client> &client) {
+ sp<Camera2Client> &/*client*/) {
status_t res;
ATRACE_CALL();
Mutex::Autolock l(mInputMutex);
@@ -578,7 +578,7 @@ CaptureSequencer::CaptureState CaptureSequencer::manageBurstCaptureStart(
}
CaptureSequencer::CaptureState CaptureSequencer::manageBurstCaptureWait(
- sp<Camera2Client> &client) {
+ sp<Camera2Client> &/*client*/) {
status_t res;
ATRACE_CALL();
diff --git a/services/camera/libcameraservice/camera2/FrameProcessor.cpp b/services/camera/libcameraservice/camera2/FrameProcessor.cpp
index 064607c..e032522 100644
--- a/services/camera/libcameraservice/camera2/FrameProcessor.cpp
+++ b/services/camera/libcameraservice/camera2/FrameProcessor.cpp
@@ -62,7 +62,7 @@ status_t FrameProcessor::removeListener(int32_t minId,
return OK;
}
-void FrameProcessor::dump(int fd, const Vector<String16>& args) {
+void FrameProcessor::dump(int fd, const Vector<String16>& /*args*/) {
String8 result(" Latest received frame:\n");
write(fd, result.string(), result.size());
mLastFrame.dump(fd, 2, 6);
@@ -128,7 +128,6 @@ void FrameProcessor::processNewFrames(sp<Camera2Client> &client) {
status_t FrameProcessor::processListeners(const CameraMetadata &frame,
sp<Camera2Client> &client) {
- status_t res;
ATRACE_CALL();
camera_metadata_ro_entry_t entry;
@@ -173,7 +172,7 @@ status_t FrameProcessor::processFaceDetect(const CameraMetadata &frame,
ATRACE_CALL();
camera_metadata_ro_entry_t entry;
bool enableFaceDetect;
- int maxFaces;
+
{
SharedParameters::Lock l(client->getParameters());
enableFaceDetect = l.mParameters.enableFaceDetect;
diff --git a/services/camera/libcameraservice/camera2/JpegCompressor.cpp b/services/camera/libcameraservice/camera2/JpegCompressor.cpp
index 702ef58..c9af71e 100644
--- a/services/camera/libcameraservice/camera2/JpegCompressor.cpp
+++ b/services/camera/libcameraservice/camera2/JpegCompressor.cpp
@@ -144,7 +144,7 @@ bool JpegCompressor::isBusy() {
}
// old function -- TODO: update for new buffer type
-bool JpegCompressor::isStreamInUse(uint32_t id) {
+bool JpegCompressor::isStreamInUse(uint32_t /*id*/) {
ALOGV("%s", __FUNCTION__);
Mutex::Autolock lock(mBusyMutex);
@@ -203,14 +203,14 @@ void JpegCompressor::jpegInitDestination(j_compress_ptr cinfo) {
dest->free_in_buffer = kMaxJpegSize;
}
-boolean JpegCompressor::jpegEmptyOutputBuffer(j_compress_ptr cinfo) {
+boolean JpegCompressor::jpegEmptyOutputBuffer(j_compress_ptr /*cinfo*/) {
ALOGV("%s", __FUNCTION__);
ALOGE("%s: JPEG destination buffer overflow!",
__FUNCTION__);
return true;
}
-void JpegCompressor::jpegTermDestination(j_compress_ptr cinfo) {
+void JpegCompressor::jpegTermDestination(j_compress_ptr /*cinfo*/) {
ALOGV("%s", __FUNCTION__);
ALOGV("%s: Done writing JPEG data. %d bytes left in buffer",
__FUNCTION__, cinfo->dest->free_in_buffer);
diff --git a/services/camera/libcameraservice/camera2/JpegProcessor.cpp b/services/camera/libcameraservice/camera2/JpegProcessor.cpp
index ffc072b..6280f83 100644
--- a/services/camera/libcameraservice/camera2/JpegProcessor.cpp
+++ b/services/camera/libcameraservice/camera2/JpegProcessor.cpp
@@ -139,7 +139,6 @@ status_t JpegProcessor::updateStream(const Parameters &params) {
status_t JpegProcessor::deleteStream() {
ATRACE_CALL();
- status_t res;
Mutex::Autolock l(mInputMutex);
@@ -164,7 +163,7 @@ int JpegProcessor::getStreamId() const {
return mCaptureStreamId;
}
-void JpegProcessor::dump(int fd, const Vector<String16>& args) const {
+void JpegProcessor::dump(int /*fd*/, const Vector<String16>& /*args*/) const {
}
bool JpegProcessor::threadLoop() {
@@ -356,7 +355,7 @@ size_t JpegProcessor::findJpegSize(uint8_t* jpegBuffer, size_t maxSize) {
// Find End of Image
// Scan JPEG buffer until End of Image (EOI)
bool foundEnd = false;
- for (size; size <= maxSize - MARKER_LENGTH; size++) {
+ for ( ; size <= maxSize - MARKER_LENGTH; size++) {
if ( checkJpegEnd(jpegBuffer + size) ) {
foundEnd = true;
size += MARKER_LENGTH;
diff --git a/services/camera/libcameraservice/camera2/Parameters.cpp b/services/camera/libcameraservice/camera2/Parameters.cpp
index 9a0083a..93927e6 100644
--- a/services/camera/libcameraservice/camera2/Parameters.cpp
+++ b/services/camera/libcameraservice/camera2/Parameters.cpp
@@ -951,7 +951,6 @@ status_t Parameters::buildQuirks() {
camera_metadata_ro_entry_t Parameters::staticInfo(uint32_t tag,
size_t minCount, size_t maxCount) const {
- status_t res;
camera_metadata_ro_entry_t entry = info->find(tag);
if (CC_UNLIKELY( entry.count == 0 )) {
@@ -1567,6 +1566,10 @@ status_t Parameters::set(const String8& paramString) {
ALOGE("%s: Video stabilization not supported", __FUNCTION__);
}
+ // LIGHTFX
+ validatedParams.lightFx = lightFxStringToEnum(
+ newParams.get(CameraParameters::KEY_LIGHTFX));
+
/** Update internal parameters */
*this = validatedParams;
@@ -2094,6 +2097,18 @@ const char *Parameters::focusModeEnumToString(focusMode_t focusMode) {
}
}
+Parameters::Parameters::lightFxMode_t Parameters::lightFxStringToEnum(
+ const char *lightFxMode) {
+ return
+ !lightFxMode ?
+ Parameters::LIGHTFX_NONE :
+ !strcmp(lightFxMode, CameraParameters::LIGHTFX_LOWLIGHT) ?
+ Parameters::LIGHTFX_LOWLIGHT :
+ !strcmp(lightFxMode, CameraParameters::LIGHTFX_HDR) ?
+ Parameters::LIGHTFX_HDR :
+ Parameters::LIGHTFX_NONE;
+}
+
status_t Parameters::parseAreas(const char *areasCStr,
Vector<Parameters::Area> *areas) {
static const size_t NUM_FIELDS = 5;
@@ -2414,7 +2429,7 @@ Parameters::CropRegion Parameters::calculateCropRegion(
return crop;
}
-int32_t Parameters::fpsFromRange(int32_t min, int32_t max) const {
+int32_t Parameters::fpsFromRange(int32_t /*min*/, int32_t max) const {
return max;
}
diff --git a/services/camera/libcameraservice/camera2/Parameters.h b/services/camera/libcameraservice/camera2/Parameters.h
index 54b1e8c..6d32bf6 100644
--- a/services/camera/libcameraservice/camera2/Parameters.h
+++ b/services/camera/libcameraservice/camera2/Parameters.h
@@ -261,6 +261,8 @@ struct Parameters {
static const char* flashModeEnumToString(flashMode_t flashMode);
static focusMode_t focusModeStringToEnum(const char *focusMode);
static const char* focusModeEnumToString(focusMode_t focusMode);
+ static lightFxMode_t lightFxStringToEnum(const char *lightFxMode);
+
static status_t parseAreas(const char *areasCStr,
Vector<Area> *areas);
diff --git a/services/camera/libcameraservice/camera2/StreamingProcessor.cpp b/services/camera/libcameraservice/camera2/StreamingProcessor.cpp
index 207f780..6ea27b2 100644
--- a/services/camera/libcameraservice/camera2/StreamingProcessor.cpp
+++ b/services/camera/libcameraservice/camera2/StreamingProcessor.cpp
@@ -447,7 +447,6 @@ status_t StreamingProcessor::incrementStreamingIds() {
ATRACE_CALL();
Mutex::Autolock m(mMutex);
- status_t res;
mPreviewRequestId++;
if (mPreviewRequestId >= Camera2Client::kPreviewRequestIdEnd) {
mPreviewRequestId = Camera2Client::kPreviewRequestIdStart;
@@ -628,7 +627,7 @@ void StreamingProcessor::releaseRecordingFrame(const sp<IMemory>& mem) {
}
-status_t StreamingProcessor::dump(int fd, const Vector<String16>& args) {
+status_t StreamingProcessor::dump(int fd, const Vector<String16>& /*args*/) {
String8 result;
result.append(" Current requests:\n");
diff --git a/services/camera/libcameraservice/camera2/ZslProcessor.cpp b/services/camera/libcameraservice/camera2/ZslProcessor.cpp
index 1937955..9584028 100644
--- a/services/camera/libcameraservice/camera2/ZslProcessor.cpp
+++ b/services/camera/libcameraservice/camera2/ZslProcessor.cpp
@@ -69,11 +69,12 @@ void ZslProcessor::onFrameAvailable() {
}
}
-void ZslProcessor::onFrameAvailable(int32_t frameId, const CameraMetadata &frame) {
+void ZslProcessor::onFrameAvailable(int32_t /*frameId*/, const CameraMetadata &frame) {
Mutex::Autolock l(mInputMutex);
camera_metadata_ro_entry_t entry;
entry = frame.find(ANDROID_SENSOR_TIMESTAMP);
nsecs_t timestamp = entry.data.i64[0];
+ (void)timestamp;
ALOGVV("Got preview frame for timestamp %lld", timestamp);
if (mState != RUNNING) return;
@@ -367,7 +368,7 @@ status_t ZslProcessor::clearZslQueueLocked() {
return OK;
}
-void ZslProcessor::dump(int fd, const Vector<String16>& args) const {
+void ZslProcessor::dump(int fd, const Vector<String16>& /*args*/) const {
Mutex::Autolock l(mInputMutex);
if (!mLatestCapturedRequest.isEmpty()) {
String8 result(" Latest ZSL capture request:\n");
diff --git a/tools/resampler_tools/fir.cpp b/tools/resampler_tools/fir.cpp
index 377814f..cc3d509 100644
--- a/tools/resampler_tools/fir.cpp
+++ b/tools/resampler_tools/fir.cpp
@@ -16,6 +16,9 @@
#include <math.h>
#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
static double sinc(double x) {
if (fabs(x) == 0.0f) return 1.0f;
@@ -34,44 +37,82 @@ static double I0(double x) {
y=x/3.75;
y*=y;
ans=1.0+y*(3.5156229+y*(3.0899424+y*(1.2067492
- +y*(0.2659732+y*(0.360768e-1+y*0.45813e-2)))));
+ +y*(0.2659732+y*(0.360768e-1+y*0.45813e-2)))));
} else {
y=3.75/ax;
ans=(exp(ax)/sqrt(ax))*(0.39894228+y*(0.1328592e-1
- +y*(0.225319e-2+y*(-0.157565e-2+y*(0.916281e-2
- +y*(-0.2057706e-1+y*(0.2635537e-1+y*(-0.1647633e-1
- +y*0.392377e-2))))))));
+ +y*(0.225319e-2+y*(-0.157565e-2+y*(0.916281e-2
+ +y*(-0.2057706e-1+y*(0.2635537e-1+y*(-0.1647633e-1
+ +y*0.392377e-2))))))));
}
return ans;
}
-static double kaiser(int k, int N, double alpha) {
+static double kaiser(int k, int N, double beta) {
if (k < 0 || k > N)
return 0;
- return I0(M_PI*alpha * sqrt(1.0 - sqr((2.0*k)/N - 1.0))) / I0(M_PI*alpha);
+ return I0(beta * sqrt(1.0 - sqr((2.0*k)/N - 1.0))) / I0(beta);
+}
+
+
+static void usage(char* name) {
+ fprintf(stderr,
+ "usage: %s [-h] [-d] [-s sample_rate] [-c cut-off_frequency] [-n half_zero_crossings] [-f {float|fixed}] [-b beta] [-v dBFS] [-l lerp]\n"
+ " %s [-h] [-d] [-s sample_rate] [-c cut-off_frequency] [-n half_zero_crossings] [-f {float|fixed}] [-b beta] [-v dBFS] -p M/N\n"
+ " -h this help message\n"
+ " -d debug, print comma-separated coefficient table\n"
+ " -p generate poly-phase filter coefficients, with sample increment M/N\n"
+ " -s sample rate (48000)\n"
+ " -c cut-off frequency (20478)\n"
+ " -n number of zero-crossings on one side (8)\n"
+ " -l number of lerping bits (4)\n"
+ " -f output format, can be fixed-point or floating-point (fixed)\n"
+ " -b kaiser window parameter beta (7.865 [-80dB])\n"
+ " -v attenuation in dBFS (0)\n",
+ name, name
+ );
+ exit(0);
}
int main(int argc, char** argv)
{
// nc is the number of bits to store the coefficients
- int nc = 32;
+ const int nc = 32;
- // ni is the minimum number of bits needed for interpolation
- // (not used for generating the coefficients)
- const int ni = nc / 2;
+ bool polyphase = false;
+ unsigned int polyM = 160;
+ unsigned int polyN = 147;
+ bool debug = false;
+ double Fs = 48000;
+ double Fc = 20478;
+ double atten = 1;
+ int format = 0;
- // cut off frequency ratio Fc/Fs
- // The bigger the stop-band, the less coefficients we'll need.
- double Fcr = 20000.0 / 48000.0;
- // nzc is the number of zero-crossing on one half of the filter
- int nzc = 8;
-
- // alpha parameter of the kaiser window
- // Larger numbers reduce ripples in the rejection band but increase
- // the width of the transition band.
- // the table below gives some value of alpha for a given
- // stop-band attenuation.
+ // in order to keep the errors associated with the linear
+ // interpolation of the coefficients below the quantization error
+ // we must satisfy:
+ // 2^nz >= 2^(nc/2)
+ //
+ // for 16 bit coefficients that would be 256
+ //
+ // note that increasing nz only increases memory requirements,
+ // but doesn't increase the amount of computation to do.
+ //
+ //
+ // see:
+ // Smith, J.O. Digital Audio Resampling Home Page
+ // https://ccrma.stanford.edu/~jos/resample/, 2011-03-29
+ //
+ int nz = 4;
+
+ // | 0.1102*(A - 8.7) A > 50
+ // beta = | 0.5842*(A - 21)^0.4 + 0.07886*(A - 21) 21 <= A <= 50
+ // | 0 A < 21
+ // with A is the desired stop-band attenuation in dBFS
+ //
+ // for eg:
+ //
// 30 dB 2.210
// 40 dB 3.384
// 50 dB 4.538
@@ -80,42 +121,161 @@ int main(int argc, char** argv)
// 80 dB 7.865
// 90 dB 8.960
// 100 dB 10.056
- double alpha = 7.865; // -80dB stop-band attenuation
-
- // 2^nz is the number coefficients per zero-crossing
- // (int theory this should be 1<<(nc/2))
- const int nz = 4;
+ double beta = 7.865;
+
+
+ // 2*nzc = (A - 8) / (2.285 * dw)
+ // with dw the transition width = 2*pi*dF/Fs
+ //
+ int nzc = 8;
+
+ //
+ // Example:
+ // 44.1 KHz to 48 KHz resampling
+ // 100 dB rejection above 28 KHz
+ // (the spectrum will fold around 24 KHz and we want 100 dB rejection
+ // at the point where the folding reaches 20 KHz)
+ // ...___|_____
+ // | \|
+ // | ____/|\____
+ // |/alias| \
+ // ------/------+------\---------> KHz
+ // 20 24 28
+
+ // Transition band 8 KHz, or dw = 1.0472
+ //
+ // beta = 10.056
+ // nzc = 20
+ //
+
+ int ch;
+ while ((ch = getopt(argc, argv, ":hds:c:n:f:l:b:p:v:")) != -1) {
+ switch (ch) {
+ case 'd':
+ debug = true;
+ break;
+ case 'p':
+ if (sscanf(optarg, "%u/%u", &polyM, &polyN) != 2) {
+ usage(argv[0]);
+ }
+ polyphase = true;
+ break;
+ case 's':
+ Fs = atof(optarg);
+ break;
+ case 'c':
+ Fc = atof(optarg);
+ break;
+ case 'n':
+ nzc = atoi(optarg);
+ break;
+ case 'l':
+ nz = atoi(optarg);
+ break;
+ case 'f':
+ if (!strcmp(optarg,"fixed")) format = 0;
+ else if (!strcmp(optarg,"float")) format = 1;
+ else usage(argv[0]);
+ break;
+ case 'b':
+ beta = atof(optarg);
+ break;
+ case 'v':
+ atten = pow(10, -fabs(atof(optarg))*0.05 );
+ break;
+ case 'h':
+ default:
+ usage(argv[0]);
+ break;
+ }
+ }
+
+ // cut off frequency ratio Fc/Fs
+ double Fcr = Fc / Fs;
+
- // total number of coefficients
- const int N = (1 << nz) * nzc;
+ // total number of coefficients (one side)
+ const int M = (1 << nz);
+ const int N = M * nzc;
// generate the right half of the filter
- printf("const int32_t RESAMPLE_FIR_SIZE = %d;\n", N);
- printf("const int32_t RESAMPLE_FIR_NUM_COEF = %d;\n", nzc);
- printf("const int32_t RESAMPLE_FIR_COEF_BITS = %d;\n", nc);
- printf("const int32_t RESAMPLE_FIR_LERP_FRAC_BITS = %d;\n", ni);
- printf("const int32_t RESAMPLE_FIR_LERP_INT_BITS = %d;\n", nz);
- printf("\n");
- printf("static int16_t resampleFIR[%d] = {", N);
- for (int i=0 ; i<N ; i++)
- {
- double x = (2.0 * M_PI * i * Fcr) / (1 << nz);
- double y = kaiser(i+N, 2*N, alpha) * sinc(x);
-
- long yi = floor(y * ((1ULL<<(nc-1))) + 0.5);
- if (yi >= (1LL<<(nc-1))) yi = (1LL<<(nc-1))-1;
-
- if ((i % (1 << 4)) == 0) printf("\n ");
- if (nc > 16)
- printf("0x%08x, ", int(yi));
- else
- printf("0x%04x, ", int(yi)&0xFFFF);
+ if (!debug) {
+ printf("// cmd-line: ");
+ for (int i=1 ; i<argc ; i++) {
+ printf("%s ", argv[i]);
+ }
+ printf("\n");
+ if (!polyphase) {
+ printf("const int32_t RESAMPLE_FIR_SIZE = %d;\n", N);
+ printf("const int32_t RESAMPLE_FIR_LERP_INT_BITS = %d;\n", nz);
+ printf("const int32_t RESAMPLE_FIR_NUM_COEF = %d;\n", nzc);
+ } else {
+ printf("const int32_t RESAMPLE_FIR_SIZE = %d;\n", 2*nzc*polyN);
+ printf("const int32_t RESAMPLE_FIR_NUM_COEF = %d;\n", 2*nzc);
+ }
+ if (!format) {
+ printf("const int32_t RESAMPLE_FIR_COEF_BITS = %d;\n", nc);
+ }
+ printf("\n");
+ printf("static %s resampleFIR[] = {", !format ? "int32_t" : "float");
+ }
+
+ if (!polyphase) {
+ for (int i=0 ; i<=M ; i++) { // an extra set of coefs for interpolation
+ for (int j=0 ; j<nzc ; j++) {
+ int ix = j*M + i;
+ double x = (2.0 * M_PI * ix * Fcr) / (1 << nz);
+ double y = kaiser(ix+N, 2*N, beta) * sinc(x) * 2.0 * Fcr;
+ y *= atten;
+
+ if (!debug) {
+ if (j == 0)
+ printf("\n ");
+ }
+
+ if (!format) {
+ int64_t yi = floor(y * ((1ULL<<(nc-1))) + 0.5);
+ if (yi >= (1LL<<(nc-1))) yi = (1LL<<(nc-1))-1;
+ printf("0x%08x, ", int32_t(yi));
+ } else {
+ printf("%.9g%s ", y, debug ? "," : "f,");
+ }
+ }
+ }
+ } else {
+ for (int j=0 ; j<polyN ; j++) {
+ // calculate the phase
+ double p = ((polyM*j) % polyN) / double(polyN);
+ if (!debug) printf("\n ");
+ else printf("\n");
+ // generate a FIR per phase
+ for (int i=-nzc ; i<nzc ; i++) {
+ double x = 2.0 * M_PI * Fcr * (i + p);
+ double y = kaiser(i+N, 2*N, beta) * sinc(x) * 2.0 * Fcr;;
+ y *= atten;
+ if (!format) {
+ int64_t yi = floor(y * ((1ULL<<(nc-1))) + 0.5);
+ if (yi >= (1LL<<(nc-1))) yi = (1LL<<(nc-1))-1;
+ printf("0x%08x", int32_t(yi));
+ } else {
+ printf("%.9g%s", y, debug ? "" : "f");
+ }
+
+ if (debug && (i==nzc-1)) {
+ } else {
+ printf(", ");
+ }
+ }
+ }
+ }
+
+ if (!debug) {
+ printf("\n};");
}
- printf("\n};\n");
+ printf("\n");
return 0;
- }
+}
-// http://www.dsptutor.freeuk.com/KaiserFilterDesign/KaiserFilterDesign.html
// http://www.csee.umbc.edu/help/sound/AFsp-V2R1/html/audio/ResampAudio.html
-
+