am 8b6ce0a2: (-s ours) Reconcile with jb-mr1-release - do not merge
* commit '8b6ce0a269ba67995766980f5b83937302143e64':
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_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_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 @@
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_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_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_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/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 @@
// 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 @@
// 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/AudioSystem.h b/include/media/AudioSystem.h
index 49e1afc..2218fad 100644
--- a/include/media/AudioSystem.h
+++ b/include/media/AudioSystem.h
@@ -87,9 +87,12 @@
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(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 getSamplingRate(audio_io_handle_t output,
audio_stream_type_t streamType,
int* samplingRate);
@@ -126,7 +129,8 @@
// - 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(uint32_t *halFrames, uint32_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);
@@ -147,8 +151,8 @@
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 +166,8 @@
};
// 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 +187,10 @@
//
// 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);
diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h
index 34108b3..7dd22e8 100644
--- a/include/media/AudioTrack.h
+++ b/include/media/AudioTrack.h
@@ -53,9 +53,12 @@
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_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.
};
@@ -312,7 +315,8 @@
/* 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 +334,8 @@
* 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 +364,8 @@
* 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);
@@ -518,8 +524,10 @@
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
+ 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;
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 @@
// -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 @@
//
// 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 @@
// *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..359780e 100644
--- a/include/media/IAudioFlinger.h
+++ b/include/media/IAudioFlinger.h
@@ -123,7 +123,8 @@
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;
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 @@
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 @@
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/private/media/AudioTrackShared.h b/include/private/media/AudioTrackShared.h
index 5b133f3..fe42afa 100644
--- a/include/private/media/AudioTrackShared.h
+++ b/include/private/media/AudioTrackShared.h
@@ -27,7 +27,8 @@
// ----------------------------------------------------------------------------
// 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
@@ -100,7 +101,8 @@
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:
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 @@
libGLESv2 \
libgui \
libmedia \
- libmedia_native \
libdrmframework \
libstagefright \
libstagefright_foundation \
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_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 @@
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 @@
/*--- 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 @@
* 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_MODULE:= libmusicbundle
-
-
LOCAL_C_INCLUDES += \
$(LOCAL_PATH)/Eq/lib \
$(LOCAL_PATH)/Eq/src \
@@ -121,8 +119,12 @@
$(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_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_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_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 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 @@
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
--- a/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
+++ b/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
@@ -186,30 +186,6 @@
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 @@
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
--- a/media/libeffects/preprocessing/Android.mk
+++ b/media/libeffects/preprocessing/Android.mk
@@ -29,4 +29,6 @@
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
--- a/media/libeffects/preprocessing/PreProcessing.cpp
+++ b/media/libeffects/preprocessing/PreProcessing.cpp
@@ -1818,30 +1818,6 @@
// 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 @@
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 @@
//--- 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 @@
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 @@
/*--- 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 @@
.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 @@
* 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 @@
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 @@
//--- 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 @@
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_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 @@
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 @@
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, ¶m->status);
+ return mIEffect->command(EFFECT_CMD_SET_PARAM, sizeof (effect_param_t) + psize, param, &size,
+ ¶m->status);
}
status_t AudioEffect::setParameterDeferred(effect_param_t *param)
@@ -321,11 +324,14 @@
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::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..bdbee0d 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -127,7 +127,8 @@
int sessionId)
{
- ALOGV("set(): sampleRate %d, channelMask %#x, frameCount %d",sampleRate, channelMask, frameCount);
+ ALOGV("set(): sampleRate %d, channelMask %#x, frameCount %d",sampleRate, channelMask,
+ frameCount);
AutoMutex lock(mLock);
@@ -701,7 +702,8 @@
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;
diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp
index 207f96f..767c452 100644
--- a/media/libmedia/AudioSystem.cpp
+++ b/media/libmedia/AudioSystem.cpp
@@ -246,7 +246,8 @@
gLock.unlock();
}
- ALOGV("getSamplingRate() streamType %d, output %d, sampling rate %d", streamType, output, *samplingRate);
+ ALOGV("getSamplingRate() streamType %d, output %d, sampling rate %d", streamType, output,
+ *samplingRate);
return NO_ERROR;
}
@@ -290,7 +291,8 @@
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 +371,8 @@
return af->setVoiceVolume(value);
}
-status_t AudioSystem::getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames, audio_stream_type_t stream)
+status_t AudioSystem::getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames,
+ audio_stream_type_t stream)
{
const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
if (af == 0) return PERMISSION_DENIED;
@@ -449,8 +452,10 @@
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 %d, format %d channels %#x frameCount %d "
+ "latency %d",
+ outputDesc->samplingRate, outputDesc->format, outputDesc->channels,
+ outputDesc->frameCount, outputDesc->latency);
} break;
case OUTPUT_CLOSED: {
if (gOutputs.indexOfKey(ioHandle) < 0) {
@@ -471,7 +476,8 @@
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 %d, 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 +516,7 @@
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();
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index 362d022..5fc9b07 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -198,7 +198,8 @@
int sessionId)
{
- 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);
@@ -617,12 +618,14 @@
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;
}
@@ -924,7 +927,8 @@
mCblk->stepUser(mCblk->frameCount);
}
- mCblk->setVolumeLR((uint32_t(uint16_t(mVolume[RIGHT] * 0x1000)) << 16) | uint16_t(mVolume[LEFT] * 0x1000));
+ mCblk->setVolumeLR((uint32_t(uint16_t(mVolume[RIGHT] * 0x1000)) << 16) |
+ uint16_t(mVolume[LEFT] * 0x1000));
mCblk->setSendLevel(mSendLevel);
mAudioTrack->attachAuxEffect(mAuxEffectId);
mCblk->bufferTimeoutMs = MAX_STARTUP_TIMEOUT_MS;
@@ -994,8 +998,8 @@
// 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();
@@ -1265,7 +1269,8 @@
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;
@@ -1439,11 +1444,14 @@
String8 result;
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, mCblk->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(%d), status(%d), muted(%d)\n",
+ (mCblk == 0) ? 0 : mCblk->sampleRate, mStatus, mMuted);
result.append(buffer);
snprintf(buffer, 255, " active(%d), latency (%d)\n", mActive, mLatency);
result.append(buffer);
diff --git a/media/libmedia/IAudioFlinger.cpp b/media/libmedia/IAudioFlinger.cpp
index ce8ffc4..f412591 100644
--- a/media/libmedia/IAudioFlinger.cpp
+++ b/media/libmedia/IAudioFlinger.cpp
@@ -865,7 +865,8 @@
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;
@@ -1043,7 +1044,8 @@
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 @@
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 @@
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 @@
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/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 @@
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 @@
//-------------------------------------------------------------------------
-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 @@
libdl \
libgui \
libmedia \
- libmedia_native \
libsonivox \
libstagefright \
libstagefright_foundation \
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 @@
}
}
} else if (what == Renderer::kWhatFlushComplete) {
- CHECK_EQ(what, (int32_t)Renderer::kWhatFlushComplete);
-
int32_t audio;
CHECK(msg->findInt32("audio", &audio));
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 @@
libicuuc \
liblog \
libmedia \
- libmedia_native \
libsonivox \
libssl \
libstagefright_omx \
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 @@
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 @@
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/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 @@
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/mediaserver/main_mediaserver.cpp b/media/mediaserver/main_mediaserver.cpp
index 6b1abb1..ddd5b84 100644
--- a/media/mediaserver/main_mediaserver.cpp
+++ b/media/mediaserver/main_mediaserver.cpp
@@ -33,6 +33,7 @@
int main(int argc, char** argv)
{
+ signal(SIGPIPE, SIG_IGN);
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm = defaultServiceManager();
ALOGI("ServiceManager: %p", sm.get());
diff --git a/services/audioflinger/Android.mk b/services/audioflinger/Android.mk
index bd9421c..4416b52 100644
--- a/services/audioflinger/Android.mk
+++ b/services/audioflinger/Android.mk
@@ -19,11 +19,9 @@
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 @@
$(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 @@
libutils \
libbinder \
libmedia \
- libmedia_native \
libnbaio \
libhardware \
libhardware_legacy \
@@ -74,10 +70,37 @@
# 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..35bd431 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -417,6 +417,12 @@
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;
@@ -941,8 +947,8 @@
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 +1118,8 @@
// 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 +1222,8 @@
{
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 +1252,8 @@
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;
@@ -1661,7 +1670,8 @@
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);
@@ -1791,7 +1801,7 @@
if (mType == DIRECT) {
if ((format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_PCM) {
if (sampleRate != mSampleRate || format != mFormat || channelMask != mChannelMask) {
- ALOGE("createTrack_l() Bad parameter: sampleRate %d format %d, channelMask 0x%08x \""
+ ALOGE("createTrack_l() Bad parameter: sampleRate %d format %d, channelMask 0x%08x "
"for output %p with format %d",
sampleRate, format, channelMask, mOutput, mFormat);
lStatus = BAD_VALUE;
@@ -1959,7 +1969,8 @@
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 +2036,8 @@
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 +2045,8 @@
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 +2075,8 @@
// 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 +2095,10 @@
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 +2112,8 @@
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];
@@ -2235,7 +2251,8 @@
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)) {
@@ -2891,7 +2908,8 @@
} 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
}
@@ -3125,7 +3143,8 @@
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 +3157,8 @@
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 +3288,8 @@
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.
@@ -3362,7 +3383,8 @@
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 +3397,8 @@
// 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));
}
@@ -3580,39 +3603,18 @@
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];
@@ -3660,6 +3662,34 @@
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 +3761,7 @@
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 +3822,7 @@
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 +4012,8 @@
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);
@@ -4103,18 +4134,21 @@
}
-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;
}
}
@@ -4161,7 +4195,8 @@
// mChannelCount
// mChannelMask
{
- ALOGV_IF(sharedBuffer != 0, "sharedBuffer: %p, size: %d", sharedBuffer->pointer(), sharedBuffer->size());
+ 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);
@@ -4322,7 +4357,8 @@
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
@@ -4341,7 +4377,8 @@
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);
+ 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;
@@ -4366,7 +4403,8 @@
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 +4446,8 @@
/*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 mFrCnt 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)
@@ -4636,7 +4674,8 @@
// 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();
@@ -5395,7 +5434,8 @@
}
// 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;
@@ -5587,7 +5627,8 @@
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,7 +5640,8 @@
}
}
- 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);
pInBuffer->frameCount -= outFrames;
@@ -5612,7 +5654,8 @@
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 +5671,14 @@
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,14 +5703,15 @@
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();
@@ -5921,13 +5968,14 @@
*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 +5994,8 @@
// ----------------------------------------------------------------------------
-AudioFlinger::RecordHandle::RecordHandle(const sp<AudioFlinger::RecordThread::RecordTrack>& recordTrack)
+AudioFlinger::RecordHandle::RecordHandle(
+ const sp<AudioFlinger::RecordThread::RecordTrack>& recordTrack)
: BnAudioRecord(),
mRecordTrack(recordTrack)
{
@@ -5961,7 +6010,8 @@
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 +6038,21 @@
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 +6159,8 @@
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->mCblk->frameSize;
if (framesIn > framesOut)
framesIn = framesOut;
mRsmpInIndex += framesIn;
@@ -6125,14 +6179,17 @@
}
}
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 +6202,9 @@
mRsmpInIndex = mFrameCount;
framesOut = 0;
buffer.frameCount = 0;
+ } else if (mTeeSink != 0) {
+ (void) mTeeSink->write(readInto,
+ mBytesRead >> Format_frameBitShift(mTeeSink->format()));
}
}
}
@@ -6156,12 +6216,14 @@
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 {
@@ -6635,7 +6697,8 @@
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 +6720,8 @@
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 +6731,10 @@
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 +6828,8 @@
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;
}
@@ -6989,7 +7056,8 @@
&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 +7110,8 @@
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 +7146,8 @@
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 +7234,17 @@
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 +7255,66 @@
}
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 +8122,8 @@
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 +8714,7 @@
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 +8965,15 @@
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 +9057,8 @@
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 +9173,8 @@
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 +9185,9 @@
// 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 +9327,8 @@
}
// 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 +9487,8 @@
// 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 +9539,8 @@
}
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 +9571,8 @@
}
}
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 +9796,8 @@
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 +9823,8 @@
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..2251b45 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -269,12 +269,14 @@
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 @@
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();
@@ -746,7 +748,8 @@
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 {
@@ -788,7 +791,8 @@
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 +814,7 @@
// implement FastMixerState::VolumeProvider interface
virtual uint32_t getVolumeLR();
+
virtual status_t setSyncEvent(const sp<SyncEvent>& event);
protected:
@@ -822,7 +827,8 @@
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;
@@ -876,8 +882,8 @@
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
private:
IAudioFlinger::track_flags_t mFlags;
@@ -986,7 +992,7 @@
class OutputTrack : public Track {
public:
- class Buffer: public AudioBufferProvider::Buffer {
+ class Buffer : public AudioBufferProvider::Buffer {
public:
int16_t *mBuffer;
};
@@ -999,7 +1005,8 @@
int 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 +1020,8 @@
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()
@@ -1025,8 +1033,8 @@
DuplicatingThread* const mSourceThread; // for waitTimeMs() in write()
}; // 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);
@@ -1185,7 +1193,8 @@
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 +1257,11 @@
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 +1314,8 @@
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 +1335,11 @@
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 +1348,8 @@
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
@@ -1453,7 +1462,8 @@
// 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);
@@ -1465,7 +1475,8 @@
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 +1487,8 @@
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 ?
@@ -1572,6 +1584,9 @@
// 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 +1622,7 @@
// 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 +1796,8 @@
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 +1810,11 @@
// 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 +2080,13 @@
// 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 @@
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 @@
// 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 @@
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 @@
// 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 @@
// 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::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__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 @@
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::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 @@
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 @@
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 @@
}
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 @@
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 @@
// 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 @@
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 @@
/*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 @@
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 @@
// 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 @@
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 @@
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 @@
}
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 @@
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 @@
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 @@
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 @@
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..e0ea4a4 100644
--- a/services/audioflinger/AudioResamplerSinc.cpp
+++ b/services/audioflinger/AudioResamplerSinc.cpp
@@ -31,36 +31,33 @@
/*
* 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,
+ 0x6d374bc7, 0x6d35278a, 0x6d2ebafe, 0x6d24069d, 0x6d150b35, 0x6d01c9e3, 0x6cea4418, 0x6cce7b97, 0x6cae7272, 0x6c8a2b0f, 0x6c61a823, 0x6c34ecb5, 0x6c03fc1c, 0x6bced9ff, 0x6b958a54, 0x6b581163, 0x6b1673c1, 0x6ad0b652, 0x6a86de48, 0x6a38f123, 0x69e6f4b1, 0x6990ef0b, 0x6936e697, 0x68d8e206, 0x6876e855, 0x681100c9, 0x67a732f4, 0x673986ac, 0x66c80413, 0x6652b392, 0x65d99dd5, 0x655ccbd3, 0x64dc46c3, 0x64581823, 0x63d049b4, 0x6344e578, 0x62b5f5b2, 0x622384e8, 0x618d9ddc, 0x60f44b91, 0x60579947, 0x5fb79278, 0x5f1442dc, 0x5e6db665, 0x5dc3f93c, 0x5d1717c4, 0x5c671e96, 0x5bb41a80, 0x5afe1886, 0x5a4525df, 0x59894ff3, 0x58caa45b, 0x580930e1, 0x5745037c, 0x567e2a51, 0x55b4b3af, 0x54e8ae13, 0x541a281e, 0x5349309e, 0x5275d684, 0x51a028e8, 0x50c83704, 0x4fee1037, 0x4f11c3fe, 0x4e3361f7, 0x4d52f9df, 0x4c709b8e, 0x4b8c56f8, 0x4aa63c2c, 0x49be5b50, 0x48d4c4a2, 0x47e98874, 0x46fcb72d, 0x460e6148, 0x451e9750, 0x442d69de, 0x433ae99c, 0x4247273f, 0x41523389, 0x405c1f43, 0x3f64fb40, 0x3e6cd85b, 0x3d73c772, 0x3c79d968, 0x3b7f1f23, 0x3a83a989, 0x3987897f, 0x388acfe9, 0x378d8da8, 0x368fd397, 0x3591b28b, 0x34933b50, 0x33947eab, 0x32958d55, 0x319677fa, 0x30974f3b, 0x2f9823a8, 0x2e9905c1, 0x2d9a05f4, 0x2c9b349e, 0x2b9ca203, 0x2a9e5e57, 0x29a079b2, 0x28a30416, 0x27a60d6a, 0x26a9a57b, 0x25addbf9, 0x24b2c075, 0x23b86263, 0x22bed116, 0x21c61bc0, 0x20ce516f, 0x1fd7810f, 0x1ee1b965, 0x1ded0911, 0x1cf97e8b, 0x1c072823, 0x1b1613ff, 0x1a26501b, 0x1937ea47, 0x184af025, 0x175f6f2b, 0x1675749e, 0x158d0d95, 0x14a646f6, 0x13c12d73, 0x12ddcd8f, 0x11fc3395,
+ 0x111c6ba0, 0x103e8192, 0x0f62811a, 0x0e8875ad, 0x0db06a89, 0x0cda6ab5, 0x0c0680fe, 0x0b34b7f5, 0x0a6519f4, 0x0997b116, 0x08cc873c, 0x0803a60a, 0x073d16e7, 0x0678e2fc, 0x05b71332, 0x04f7b037, 0x043ac276, 0x0380521c, 0x02c86715, 0x0213090c, 0x01603f6e, 0x00b01162, 0x000285d0, 0xff57a35e, 0xfeaf706f, 0xfe09f323, 0xfd673159, 0xfcc730aa, 0xfc29f670, 0xfb8f87bd, 0xfaf7e963, 0xfa631fef, 0xf9d12fab, 0xf9421c9d, 0xf8b5ea87, 0xf82c9ce7, 0xf7a636fa, 0xf722bbb5, 0xf6a22dcf, 0xf6248fb6, 0xf5a9e398, 0xf5322b61, 0xf4bd68b6, 0xf44b9cfe, 0xf3dcc959, 0xf370eea9, 0xf3080d8c, 0xf2a2265e, 0xf23f393b, 0xf1df45fd, 0xf1824c3e, 0xf1284b58, 0xf0d14267, 0xf07d3043, 0xf02c138a, 0xefddea9a, 0xef92b393, 0xef4a6c58, 0xef051290, 0xeec2a3a3, 0xee831cc3, 0xee467ae1, 0xee0cbab9, 0xedd5d8ca, 0xeda1d15c, 0xed70a07d, 0xed424205, 0xed16b196, 0xecedea99, 0xecc7e845, 0xeca4a59b, 0xec841d68, 0xec664a48, 0xec4b26a2, 0xec32acb0, 0xec1cd677, 0xec099dcf, 0xebf8fc64, 0xebeaebaf, 0xebdf6500, 0xebd6617b, 0xebcfda19, 0xebcbc7a7, 0xebca22cc, 0xebcae405, 0xebce03aa, 0xebd379eb, 0xebdb3ed5, 0xebe54a4f, 0xebf1941f, 0xec0013e8, 0xec10c12c, 0xec23934f, 0xec388194, 0xec4f8322, 0xec688f02, 0xec839c22, 0xeca0a156, 0xecbf9558, 0xece06ecb, 0xed032439, 0xed27ac16, 0xed4dfcc2, 0xed760c88, 0xed9fd1a2, 0xedcb4237, 0xedf8545b, 0xee26fe17, 0xee573562, 0xee88f026, 0xeebc2444, 0xeef0c78d, 0xef26cfca, 0xef5e32bd, 0xef96e61c, 0xefd0df9a, 0xf00c14e1, 0xf0487b98, 0xf0860962, 0xf0c4b3e0, 0xf10470b0, 0xf1453571, 0xf186f7c0, 0xf1c9ad40, 0xf20d4b92, 0xf251c85d, 0xf297194d, 0xf2dd3411,
+ 0xf3240e61, 0xf36b9dfd, 0xf3b3d8ac, 0xf3fcb43e, 0xf4462690, 0xf4902587, 0xf4daa718, 0xf525a143, 0xf5710a17, 0xf5bcd7b1, 0xf609003f, 0xf6557a00, 0xf6a23b44, 0xf6ef3a6e, 0xf73c6df4, 0xf789cc61, 0xf7d74c53, 0xf824e480, 0xf8728bb3, 0xf8c038d0, 0xf90de2d1, 0xf95b80cb, 0xf9a909ea, 0xf9f67577, 0xfa43bad2, 0xfa90d17b, 0xfaddb10c, 0xfb2a513b, 0xfb76a9dd, 0xfbc2b2e4, 0xfc0e6461, 0xfc59b685, 0xfca4a19f, 0xfcef1e20, 0xfd392498, 0xfd82adba, 0xfdcbb25a, 0xfe142b6e, 0xfe5c120f, 0xfea35f79, 0xfeea0d0c, 0xff30144a, 0xff756edc, 0xffba168d, 0xfffe054e, 0x00413536, 0x0083a081, 0x00c54190, 0x010612eb, 0x01460f41, 0x01853165, 0x01c37452, 0x0200d32c, 0x023d493c, 0x0278d1f2, 0x02b368e6, 0x02ed09d7, 0x0325b0ad, 0x035d5977, 0x0394006a, 0x03c9a1e5, 0x03fe3a6f, 0x0431c6b5, 0x0464438c, 0x0495adf2, 0x04c6030d, 0x04f54029, 0x052362ba, 0x0550685d, 0x057c4ed4, 0x05a7140b, 0x05d0b612, 0x05f93324, 0x0620899e, 0x0646b808, 0x066bbd0d, 0x068f9781, 0x06b2465b, 0x06d3c8bb, 0x06f41de3, 0x0713453d, 0x07313e56, 0x074e08e0, 0x0769a4b2, 0x078411c7, 0x079d503b, 0x07b56051, 0x07cc426c, 0x07e1f712, 0x07f67eec, 0x0809dac3, 0x081c0b84, 0x082d1239, 0x083cf010, 0x084ba654, 0x08593671, 0x0865a1f1, 0x0870ea7e, 0x087b11de, 0x088419f6, 0x088c04c8, 0x0892d470, 0x08988b2a, 0x089d2b4a, 0x08a0b740, 0x08a33196, 0x08a49cf0, 0x08a4fc0d, 0x08a451c0, 0x08a2a0f8, 0x089fecbb, 0x089c3824, 0x08978666, 0x0891dac8, 0x088b38a9, 0x0883a378, 0x087b1ebc, 0x0871ae0d, 0x08675516, 0x085c1794, 0x084ff957, 0x0842fe3d, 0x08352a35, 0x0826813e, 0x08170767, 0x0806c0cb, 0x07f5b193, 0x07e3ddf7,
+ 0x07d14a38, 0x07bdfaa5, 0x07a9f399, 0x07953976, 0x077fd0ac, 0x0769bdaf, 0x07530501, 0x073bab28, 0x0723b4b4, 0x070b2639, 0x06f20453, 0x06d853a2, 0x06be18cd, 0x06a3587e, 0x06881761, 0x066c5a27, 0x06502583, 0x06337e2a, 0x061668d2, 0x05f8ea30, 0x05db06fc, 0x05bcc3ed, 0x059e25b5, 0x057f310a, 0x055fea9d, 0x0540571a, 0x05207b2f, 0x05005b82, 0x04dffcb6, 0x04bf6369, 0x049e9433, 0x047d93a8, 0x045c6654, 0x043b10bd, 0x04199760, 0x03f7feb4, 0x03d64b27, 0x03b4811d, 0x0392a4f4, 0x0370bafc, 0x034ec77f, 0x032ccebb, 0x030ad4e1, 0x02e8de19, 0x02c6ee7f, 0x02a50a22, 0x02833506, 0x02617321, 0x023fc85c, 0x021e3891, 0x01fcc78f, 0x01db7914, 0x01ba50d2, 0x0199526b, 0x01788170, 0x0157e166, 0x013775bf, 0x011741df, 0x00f7491a, 0x00d78eb3, 0x00b815da, 0x0098e1b3, 0x0079f54c, 0x005b53a4, 0x003cffa9, 0x001efc35, 0x00014c12, 0xffe3f1f7, 0xffc6f08a, 0xffaa4a5d, 0xff8e01f1, 0xff7219b3, 0xff5693fe, 0xff3b731b, 0xff20b93e, 0xff066889, 0xfeec830d, 0xfed30ac5, 0xfeba0199, 0xfea16960, 0xfe8943dc, 0xfe7192bd, 0xfe5a579d, 0xfe439407, 0xfe2d496f, 0xfe177937, 0xfe0224b0, 0xfded4d13, 0xfdd8f38b, 0xfdc5192d, 0xfdb1befc, 0xfd9ee5e7, 0xfd8c8ecc, 0xfd7aba74, 0xfd696998, 0xfd589cdc, 0xfd4854d3, 0xfd3891fd, 0xfd2954c8, 0xfd1a9d91, 0xfd0c6ca2, 0xfcfec233, 0xfcf19e6b, 0xfce50161, 0xfcd8eb17, 0xfccd5b82, 0xfcc25285, 0xfcb7cff0, 0xfcadd386, 0xfca45cf7, 0xfc9b6be5, 0xfc92ffe1, 0xfc8b186d, 0xfc83b4fc, 0xfc7cd4f0, 0xfc76779e, 0xfc709c4d, 0xfc6b4233, 0xfc66687a, 0xfc620e3d, 0xfc5e328c, 0xfc5ad465, 0xfc57f2be, 0xfc558c7c, 0xfc53a07b, 0xfc522d88, 0xfc513266, 0xfc50adcc,
+ 0xfc509e64, 0xfc5102d0, 0xfc51d9a6, 0xfc53216f, 0xfc54d8ae, 0xfc56fdda, 0xfc598f60, 0xfc5c8ba5, 0xfc5ff105, 0xfc63bdd3, 0xfc67f05a, 0xfc6c86dd, 0xfc717f97, 0xfc76d8bc, 0xfc7c9079, 0xfc82a4f4, 0xfc89144d, 0xfc8fdc9f, 0xfc96fbfc, 0xfc9e7074, 0xfca63810, 0xfcae50d6, 0xfcb6b8c4, 0xfcbf6dd8, 0xfcc86e09, 0xfcd1b74c, 0xfcdb4793, 0xfce51ccb, 0xfcef34e1, 0xfcf98dbe, 0xfd04254a, 0xfd0ef969, 0xfd1a0801, 0xfd254ef4, 0xfd30cc24, 0xfd3c7d73, 0xfd4860c2, 0xfd5473f3, 0xfd60b4e7, 0xfd6d2180, 0xfd79b7a1, 0xfd86752e, 0xfd93580d, 0xfda05e23, 0xfdad855b, 0xfdbacb9e, 0xfdc82edb, 0xfdd5ad01, 0xfde34403, 0xfdf0f1d6, 0xfdfeb475, 0xfe0c89db, 0xfe1a7009, 0xfe286505, 0xfe3666d5, 0xfe447389, 0xfe528931, 0xfe60a5e5, 0xfe6ec7c0, 0xfe7cece2, 0xfe8b1373, 0xfe99399f, 0xfea75d97, 0xfeb57d92, 0xfec397cf, 0xfed1aa92, 0xfedfb425, 0xfeedb2da, 0xfefba508, 0xff09890f, 0xff175d53, 0xff252042, 0xff32d04f, 0xff406bf8, 0xff4df1be, 0xff5b602c, 0xff68b5d5, 0xff75f153, 0xff831148, 0xff90145e, 0xff9cf947, 0xffa9bebe, 0xffb66386, 0xffc2e669, 0xffcf463a, 0xffdb81d6, 0xffe79820, 0xfff38806, 0xffff507b, 0x000af07f, 0x00166718, 0x0021b355, 0x002cd44d, 0x0037c922, 0x004290fc, 0x004d2b0e, 0x00579691, 0x0061d2ca, 0x006bdf05, 0x0075ba95, 0x007f64da, 0x0088dd38, 0x0092231e, 0x009b3605, 0x00a4156b, 0x00acc0da, 0x00b537e1, 0x00bd7a1c, 0x00c5872a, 0x00cd5eb7, 0x00d50075, 0x00dc6c1e, 0x00e3a175, 0x00eaa045, 0x00f16861, 0x00f7f9a3, 0x00fe53ef, 0x0104772e, 0x010a6353, 0x01101858, 0x0115963d, 0x011add0b, 0x011fecd3, 0x0124c5ab, 0x012967b1, 0x012dd30a, 0x013207e4, 0x01360670,
+ 0x0139cee9, 0x013d618d, 0x0140bea5, 0x0143e67c, 0x0146d965, 0x014997bb, 0x014c21db, 0x014e782a, 0x01509b14, 0x01528b08, 0x0154487b, 0x0155d3e8, 0x01572dcf, 0x015856b6, 0x01594f25, 0x015a17ab, 0x015ab0db, 0x015b1b4e, 0x015b579e, 0x015b666c, 0x015b485b, 0x015afe14, 0x015a8843, 0x0159e796, 0x01591cc0, 0x01582878, 0x01570b77, 0x0155c678, 0x01545a3c, 0x0152c783, 0x01510f13, 0x014f31b2, 0x014d3029, 0x014b0b45, 0x0148c3d2, 0x01465a9f, 0x0143d07f, 0x01412643, 0x013e5cc0, 0x013b74ca, 0x01386f3a, 0x01354ce7, 0x01320ea9, 0x012eb55a, 0x012b41d3, 0x0127b4f1, 0x01240f8e, 0x01205285, 0x011c7eb2, 0x011894f0, 0x0114961b, 0x0110830f, 0x010c5ca6, 0x010823ba, 0x0103d927, 0x00ff7dc4, 0x00fb126b, 0x00f697f3, 0x00f20f32, 0x00ed78ff, 0x00e8d62d, 0x00e4278f, 0x00df6df7, 0x00daaa34, 0x00d5dd16, 0x00d10769, 0x00cc29f7, 0x00c7458a, 0x00c25ae8, 0x00bd6ad7, 0x00b87619, 0x00b37d70, 0x00ae8198, 0x00a9834e, 0x00a4834c, 0x009f8249, 0x009a80f8, 0x0095800c, 0x00908034, 0x008b821b, 0x0086866b, 0x00818dcb, 0x007c98de, 0x0077a845, 0x0072bc9d, 0x006dd680, 0x0068f687, 0x00641d44, 0x005f4b4a, 0x005a8125, 0x0055bf60, 0x00510682, 0x004c570f, 0x0047b186, 0x00431666, 0x003e8628, 0x003a0141, 0x00358824, 0x00311b41, 0x002cbb03, 0x002867d2, 0x00242213, 0x001fea27, 0x001bc06b, 0x0017a53b, 0x001398ec, 0x000f9bd2, 0x000bae3c, 0x0007d075, 0x000402c8, 0x00004579, 0xfffc98c9, 0xfff8fcf7, 0xfff5723d, 0xfff1f8d2, 0xffee90eb, 0xffeb3ab8, 0xffe7f666, 0xffe4c41e, 0xffe1a408, 0xffde9646, 0xffdb9af8, 0xffd8b23b, 0xffd5dc28, 0xffd318d6, 0xffd06858, 0xffcdcabe, 0xffcb4014,
+ 0xffc8c866, 0xffc663b9, 0xffc41212, 0xffc1d373, 0xffbfa7d9, 0xffbd8f40, 0xffbb89a1, 0xffb996f3, 0xffb7b728, 0xffb5ea31, 0xffb42ffc, 0xffb28876, 0xffb0f388, 0xffaf7118, 0xffae010b, 0xffaca344, 0xffab57a1, 0xffaa1e02, 0xffa8f641, 0xffa7e039, 0xffa6dbc0, 0xffa5e8ad, 0xffa506d2, 0xffa43603, 0xffa3760e, 0xffa2c6c2, 0xffa227ec, 0xffa19957, 0xffa11acb, 0xffa0ac11, 0xffa04cf0, 0xff9ffd2c, 0xff9fbc89, 0xff9f8ac9, 0xff9f67ae, 0xff9f52f7, 0xff9f4c65, 0xff9f53b4, 0xff9f68a1, 0xff9f8ae9, 0xff9fba47, 0xff9ff674, 0xffa03f2b, 0xffa09425, 0xffa0f519, 0xffa161bf, 0xffa1d9cf, 0xffa25cfe, 0xffa2eb04, 0xffa38395, 0xffa42668, 0xffa4d332, 0xffa589a6, 0xffa6497c, 0xffa71266, 0xffa7e41a, 0xffa8be4c, 0xffa9a0b1, 0xffaa8afe, 0xffab7ce7, 0xffac7621, 0xffad7662, 0xffae7d5f, 0xffaf8acd, 0xffb09e63, 0xffb1b7d8, 0xffb2d6e1, 0xffb3fb37, 0xffb52490, 0xffb652a7, 0xffb78533, 0xffb8bbed, 0xffb9f691, 0xffbb34d8, 0xffbc767f, 0xffbdbb42, 0xffbf02dd, 0xffc04d0f, 0xffc19996, 0xffc2e832, 0xffc438a3, 0xffc58aaa, 0xffc6de09, 0xffc83285, 0xffc987e0, 0xffcadde1, 0xffcc344c, 0xffcd8aeb, 0xffcee183, 0xffd037e0, 0xffd18dcc, 0xffd2e311, 0xffd4377d, 0xffd58ade, 0xffd6dd02, 0xffd82dba, 0xffd97cd6, 0xffdaca2a, 0xffdc1588, 0xffdd5ec6, 0xffdea5bb, 0xffdfea3c, 0xffe12c22, 0xffe26b48, 0xffe3a788, 0xffe4e0bf, 0xffe616c8, 0xffe74984, 0xffe878d3, 0xffe9a494, 0xffeaccaa, 0xffebf0fa, 0xffed1166, 0xffee2dd7, 0xffef4632, 0xfff05a60, 0xfff16a4a, 0xfff275db, 0xfff37d00, 0xfff47fa5, 0xfff57db8, 0xfff67729, 0xfff76be9, 0xfff85be8, 0xfff9471b, 0xfffa2d74, 0xfffb0ee9, 0xfffbeb70,
+ 0xfffcc300, 0xfffd9592, 0xfffe631e, 0xffff2b9f, 0xffffef10, 0x0000ad6e, 0x000166b6, 0x00021ae5, 0x0002c9fd, 0x000373fb, 0x000418e2, 0x0004b8b3, 0x00055371, 0x0005e921, 0x000679c5, 0x00070564, 0x00078c04, 0x00080dab, 0x00088a62, 0x00090230, 0x0009751e, 0x0009e337, 0x000a4c85, 0x000ab112, 0x000b10ec, 0x000b6c1d, 0x000bc2b3, 0x000c14bb, 0x000c6244, 0x000cab5c, 0x000cf012, 0x000d3075, 0x000d6c97, 0x000da486, 0x000dd854, 0x000e0812, 0x000e33d3, 0x000e5ba7, 0x000e7fa1, 0x000e9fd5, 0x000ebc54, 0x000ed533, 0x000eea84, 0x000efc5c, 0x000f0ace, 0x000f15ef, 0x000f1dd2, 0x000f228d, 0x000f2434, 0x000f22dc, 0x000f1e99, 0x000f1781, 0x000f0da8, 0x000f0125, 0x000ef20b, 0x000ee070, 0x000ecc69, 0x000eb60b, 0x000e9d6b, 0x000e829e, 0x000e65ba, 0x000e46d3, 0x000e25fd, 0x000e034f, 0x000ddedb, 0x000db8b7, 0x000d90f6, 0x000d67ae, 0x000d3cf1, 0x000d10d5, 0x000ce36b, 0x000cb4c8, 0x000c84ff, 0x000c5422, 0x000c2245, 0x000bef79, 0x000bbbd2, 0x000b8760, 0x000b5235, 0x000b1c64, 0x000ae5fc, 0x000aaf0f, 0x000a77ac, 0x000a3fe5, 0x000a07c9, 0x0009cf67, 0x000996ce, 0x00095e0e, 0x00092535, 0x0008ec50, 0x0008b36e, 0x00087a9c, 0x000841e8, 0x0008095d, 0x0007d108, 0x000798f5, 0x00076130, 0x000729c4, 0x0006f2bb, 0x0006bc21, 0x000685ff, 0x0006505f, 0x00061b4b, 0x0005e6cb, 0x0005b2e8, 0x00057faa, 0x00054d1a, 0x00051b3e, 0x0004ea1d, 0x0004b9c0, 0x00048a2b, 0x00045b65, 0x00042d74, 0x0004005e, 0x0003d426, 0x0003a8d2, 0x00037e65, 0x000354e5, 0x00032c54, 0x000304b7, 0x0002de0e, 0x0002b85f, 0x000293aa, 0x00026ff2, 0x00024d39, 0x00022b7f, 0x00020ac7, 0x0001eb10,
0x00000000 // this one is needed for lerping the last coefficient
};
/*
- * 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 16600
*/
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,
+ 0x58888889, 0x58875d88, 0x5883dc96, 0x587e05e0, 0x5875d9b3, 0x586b587d, 0x585e82c6, 0x584f593a, 0x583ddc9f, 0x582a0dde, 0x5813edfb, 0x57fb7e1a, 0x57e0bf7f, 0x57c3b389, 0x57a45bb8, 0x5782b9aa, 0x575ecf1a, 0x57389de0, 0x571027f6, 0x56e56f6f, 0x56b8767e, 0x56893f73, 0x5657ccbb, 0x562420e2, 0x55ee3e8d, 0x55b62882, 0x557be1a0, 0x553f6ce6, 0x5500cd6d, 0x54c0066a, 0x547d1b2e, 0x54380f26, 0x53f0e5da, 0x53a7a2ed, 0x535c4a1e, 0x530edf46, 0x52bf6657, 0x526de360, 0x521a5a86, 0x51c4d00c, 0x516d484a, 0x5113c7b6, 0x50b852d9, 0x505aee59, 0x4ffb9ef2, 0x4f9a6979, 0x4f3752d9, 0x4ed26016, 0x4e6b9649, 0x4e02faa3, 0x4d98926b, 0x4d2c62fd, 0x4cbe71cc, 0x4c4ec45e, 0x4bdd6050, 0x4b6a4b53, 0x4af58b2b, 0x4a7f25b0, 0x4a0720cd, 0x498d8283, 0x491250e1, 0x4895920c, 0x48174c37, 0x479785ab, 0x471644bd, 0x46938fd7, 0x460f6d70, 0x4589e411, 0x4502fa51, 0x447ab6d5, 0x43f12053, 0x43663d8d, 0x42da1554, 0x424cae85, 0x41be100a, 0x412e40db, 0x409d47f9, 0x400b2c72, 0x3f77f561, 0x3ee3a9e7, 0x3e4e5132, 0x3db7f27a, 0x3d2094ff, 0x3c88400b, 0x3beefaee, 0x3b54cd01, 0x3ab9bda6, 0x3a1dd444, 0x39811848, 0x38e39127, 0x3845465a, 0x37a63f5f, 0x370683ba, 0x36661af1, 0x35c50c90, 0x35236024, 0x34811d3f, 0x33de4b72, 0x333af253, 0x32971979, 0x31f2c87a, 0x314e06ed, 0x30a8dc6a, 0x30035089, 0x2f5d6ade, 0x2eb732fe, 0x2e10b07d, 0x2d69eaeb, 0x2cc2e9d4, 0x2c1bb4c4, 0x2b745340, 0x2acccccc, 0x2a2528e6, 0x297d6f06, 0x28d5a6a0, 0x282dd722, 0x278607f2, 0x26de4072, 0x263687fa, 0x258ee5dd, 0x24e76163, 0x244001cf, 0x2398ce58, 0x22f1ce2e, 0x224b0876, 0x21a4844b, 0x20fe48be, 0x20585cd5,
+ 0x1fb2c78a, 0x1f0d8fcb, 0x1e68bc7d, 0x1dc45475, 0x1d205e7d, 0x1c7ce150, 0x1bd9e39e, 0x1b376c06, 0x1a95811c, 0x19f42964, 0x19536b51, 0x18b34d4a, 0x1813d5a3, 0x17750aa3, 0x16d6f27f, 0x1639935b, 0x159cf34b, 0x15011851, 0x1466085d, 0x13cbc94f, 0x133260f3, 0x1299d502, 0x12022b24, 0x116b68ed, 0x10d593dd, 0x1040b162, 0x0facc6d4, 0x0f19d979, 0x0e87ee81, 0x0df70b09, 0x0d673417, 0x0cd86e9d, 0x0c4abf78, 0x0bbe2b70, 0x0b32b735, 0x0aa86763, 0x0a1f407f, 0x099746f9, 0x09107f29, 0x088aed4f, 0x08069598, 0x07837c17, 0x0701a4c8, 0x06811392, 0x0601cc40, 0x0583d28b, 0x05072a0f, 0x048bd653, 0x0411dac7, 0x03993abf, 0x0321f97b, 0x02ac1a20, 0x02379fbb, 0x01c48d42, 0x0152e590, 0x00e2ab69, 0x0073e179, 0x00068a52, 0xff9aa86c, 0xff303e29, 0xfec74dd1, 0xfe5fd993, 0xfdf9e383, 0xfd956da0, 0xfd3279cd, 0xfcd109d6, 0xfc711f6d, 0xfc12bc2a, 0xfbb5e18f, 0xfb5a9103, 0xfb00cbd4, 0xfaa89339, 0xfa51e84e, 0xf9fccc18, 0xf9a93f82, 0xf9574361, 0xf906d86d, 0xf8b7ff4b, 0xf86ab883, 0xf81f0487, 0xf7d4e3b0, 0xf78c5641, 0xf7455c62, 0xf6fff625, 0xf6bc2385, 0xf679e463, 0xf639388a, 0xf5fa1fae, 0xf5bc996b, 0xf580a547, 0xf54642b1, 0xf50d70ff, 0xf4d62f74, 0xf4a07d3b, 0xf46c5967, 0xf439c2f9, 0xf408b8d8, 0xf3d939d9, 0xf3ab44b9, 0xf37ed821, 0xf353f2a5, 0xf32a92c3, 0xf302b6e6, 0xf2dc5d64, 0xf2b7847f, 0xf2942a64, 0xf2724d2e, 0xf251eae4, 0xf2330179, 0xf2158ece, 0xf1f990b1, 0xf1df04de, 0xf1c5e8ff, 0xf1ae3aaa, 0xf197f765, 0xf1831ca6, 0xf16fa7d0, 0xf15d9634, 0xf14ce516, 0xf13d91a7, 0xf12f9909, 0xf122f84e, 0xf117ac79, 0xf10db27d, 0xf1050741, 0xf0fda799, 0xf0f7904e, 0xf0f2be1a,
+ 0xf0ef2dab, 0xf0ecdba0, 0xf0ebc48a, 0xf0ebe4f1, 0xf0ed394e, 0xf0efbe0d, 0xf0f36f92, 0xf0f84a32, 0xf0fe4a39, 0xf1056be8, 0xf10dab74, 0xf117050a, 0xf12174cd, 0xf12cf6d5, 0xf1398732, 0xf14721ec, 0xf155c300, 0xf1656666, 0xf176080d, 0xf187a3db, 0xf19a35b1, 0xf1adb969, 0xf1c22ad4, 0xf1d785c1, 0xf1edc5f5, 0xf204e733, 0xf21ce537, 0xf235bbb8, 0xf24f6669, 0xf269e0fa, 0xf2852715, 0xf2a13462, 0xf2be0485, 0xf2db9321, 0xf2f9dbd3, 0xf318da38, 0xf33889ec, 0xf358e688, 0xf379eba4, 0xf39b94d7, 0xf3bdddb7, 0xf3e0c1db, 0xf4043cd8, 0xf4284a45, 0xf44ce5ba, 0xf4720ace, 0xf497b51a, 0xf4bde03a, 0xf4e487c9, 0xf50ba766, 0xf5333ab3, 0xf55b3d52, 0xf583aaec, 0xf5ac7f29, 0xf5d5b5b7, 0xf5ff4a47, 0xf6293890, 0xf6537c4a, 0xf67e1134, 0xf6a8f311, 0xf6d41dab, 0xf6ff8cce, 0xf72b3c4f, 0xf7572808, 0xf7834bd7, 0xf7afa3a3, 0xf7dc2b58, 0xf808deec, 0xf835ba59, 0xf862b9a0, 0xf88fd8cc, 0xf8bd13f0, 0xf8ea6724, 0xf917ce8a, 0xf945464f, 0xf972caa4, 0xf9a057c6, 0xf9cde9fb, 0xf9fb7d90, 0xfa290edf, 0xfa569a49, 0xfa841c3a, 0xfab19127, 0xfadef591, 0xfb0c4601, 0xfb397f0d, 0xfb669d55, 0xfb939d83, 0xfbc07c4c, 0xfbed3671, 0xfc19c8bf, 0xfc46300d, 0xfc72693e, 0xfc9e7141, 0xfcca4511, 0xfcf5e1b4, 0xfd21443e, 0xfd4c69cd, 0xfd774f8e, 0xfda1f2b7, 0xfdcc508d, 0xfdf66662, 0xfe203193, 0xfe49af8a, 0xfe72ddbf, 0xfe9bb9b7, 0xfec44103, 0xfeec7141, 0xff14481d, 0xff3bc351, 0xff62e0a2, 0xff899de5, 0xffaff8f9, 0xffd5efce, 0xfffb8060, 0x0020a8b7, 0x004566eb, 0x0069b920, 0x008d9d89, 0x00b11264, 0x00d415ff, 0x00f6a6b5, 0x0118c2ef, 0x013a6922, 0x015b97d1, 0x017c4d8f, 0x019c88f9, 0x01bc48bd,
+ 0x01db8b94, 0x01fa5045, 0x021895a6, 0x02365a98, 0x02539e0b, 0x02705efd, 0x028c9c77, 0x02a85592, 0x02c38972, 0x02de3749, 0x02f85e57, 0x0311fde7, 0x032b1552, 0x0343a3ff, 0x035ba961, 0x037324f6, 0x038a164c, 0x03a07cfa, 0x03b658a7, 0x03cba904, 0x03e06dcf, 0x03f4a6d1, 0x040853e2, 0x041b74e4, 0x042e09c4, 0x0440127d, 0x04518f14, 0x04627f9b, 0x0472e42e, 0x0482bcf5, 0x04920a24, 0x04a0cbf7, 0x04af02ba, 0x04bcaebe, 0x04c9d064, 0x04d66814, 0x04e27642, 0x04edfb6c, 0x04f8f819, 0x05036cdc, 0x050d5a51, 0x0516c11c, 0x051fa1ee, 0x0527fd7e, 0x052fd48d, 0x053727e8, 0x053df861, 0x054446d5, 0x054a1429, 0x054f614a, 0x05542f2f, 0x05587ed5, 0x055c5141, 0x055fa783, 0x056282ae, 0x0564e3e1, 0x0566cc3e, 0x05683cf1, 0x0569372c, 0x0569bc29, 0x0569cd27, 0x05696b6b, 0x05689842, 0x056754fe, 0x0565a2f9, 0x0563838f, 0x0560f824, 0x055e0222, 0x055aa2f6, 0x0556dc14, 0x0552aef5, 0x054e1d14, 0x054927f4, 0x0543d11a, 0x053e1a11, 0x05380465, 0x053191aa, 0x052ac373, 0x05239b5b, 0x051c1afe, 0x051443fa, 0x050c17f3, 0x0503988d, 0x04fac770, 0x04f1a647, 0x04e836bd, 0x04de7a82, 0x04d47346, 0x04ca22bc, 0x04bf8a97, 0x04b4ac8c, 0x04a98a54, 0x049e25a4, 0x04928037, 0x04869bc6, 0x047a7a0b, 0x046e1cc1, 0x046185a3, 0x0454b66c, 0x0447b0d7, 0x043a76a1, 0x042d0983, 0x041f6b39, 0x04119d7b, 0x0403a204, 0x03f57a8c, 0x03e728c9, 0x03d8ae73, 0x03ca0d3e, 0x03bb46dd, 0x03ac5d03, 0x039d5160, 0x038e25a2, 0x037edb76, 0x036f7486, 0x035ff27a, 0x035056f9, 0x0340a3a5, 0x0330da20, 0x0320fc08, 0x03110af8, 0x03010889, 0x02f0f64f, 0x02e0d5df, 0x02d0a8c6, 0x02c07090, 0x02b02ec6, 0x029fe4ec,
+ 0x028f9484, 0x027f3f0b, 0x026ee5fa, 0x025e8ac8, 0x024e2ee5, 0x023dd3c0, 0x022d7ac1, 0x021d254d, 0x020cd4c6, 0x01fc8a88, 0x01ec47ea, 0x01dc0e40, 0x01cbded8, 0x01bbbafd, 0x01aba3f2, 0x019b9afa, 0x018ba14e, 0x017bb826, 0x016be0b3, 0x015c1c20, 0x014c6b97, 0x013cd038, 0x012d4b20, 0x011ddd67, 0x010e8820, 0x00ff4c57, 0x00f02b13, 0x00e12558, 0x00d23c22, 0x00c37068, 0x00b4c31c, 0x00a6352a, 0x0097c778, 0x00897ae9, 0x007b5057, 0x006d4899, 0x005f647f, 0x0051a4d3, 0x00440a5a, 0x003695d5, 0x002947fc, 0x001c2183, 0x000f231a, 0x00024d68, 0xfff5a111, 0xffe91eb2, 0xffdcc6e4, 0xffd09a37, 0xffc49939, 0xffb8c471, 0xffad1c5f, 0xffa1a180, 0xff965449, 0xff8b352a, 0xff804490, 0xff7582e0, 0xff6af079, 0xff608db6, 0xff565aec, 0xff4c586c, 0xff42867e, 0xff38e569, 0xff2f756c, 0xff2636c2, 0xff1d29a0, 0xff144e36, 0xff0ba4ae, 0xff032d30, 0xfefae7db, 0xfef2d4cc, 0xfeeaf419, 0xfee345d5, 0xfedbca0b, 0xfed480c6, 0xfecd6a07, 0xfec685cf, 0xfebfd416, 0xfeb954d4, 0xfeb307f8, 0xfeaced6f, 0xfea70522, 0xfea14ef4, 0xfe9bcac5, 0xfe96786f, 0xfe9157cb, 0xfe8c68ab, 0xfe87aadd, 0xfe831e2e, 0xfe7ec263, 0xfe7a9741, 0xfe769c85, 0xfe72d1ed, 0xfe6f3731, 0xfe6bcc04, 0xfe689017, 0xfe658319, 0xfe62a4b3, 0xfe5ff48d, 0xfe5d7249, 0xfe5b1d89, 0xfe58f5ea, 0xfe56fb06, 0xfe552c76, 0xfe5389cc, 0xfe52129d, 0xfe50c676, 0xfe4fa4e5, 0xfe4ead73, 0xfe4ddfa8, 0xfe4d3b09, 0xfe4cbf19, 0xfe4c6b59, 0xfe4c3f47, 0xfe4c3a5e, 0xfe4c5c1b, 0xfe4ca3f4, 0xfe4d1160, 0xfe4da3d4, 0xfe4e5ac3, 0xfe4f359e, 0xfe5033d5, 0xfe5154d6, 0xfe52980d, 0xfe53fce6, 0xfe5582cb, 0xfe572926, 0xfe58ef5d, 0xfe5ad4d7,
+ 0xfe5cd8fa, 0xfe5efb2b, 0xfe613ace, 0xfe639746, 0xfe660ff5, 0xfe68a43c, 0xfe6b537e, 0xfe6e1d1b, 0xfe710072, 0xfe73fce5, 0xfe7711d2, 0xfe7a3e98, 0xfe7d8297, 0xfe80dd2e, 0xfe844dbc, 0xfe87d39f, 0xfe8b6e37, 0xfe8f1ce3, 0xfe92df02, 0xfe96b3f4, 0xfe9a9b19, 0xfe9e93d1, 0xfea29d7d, 0xfea6b77d, 0xfeaae135, 0xfeaf1a05, 0xfeb36152, 0xfeb7b67e, 0xfebc18ef, 0xfec0880a, 0xfec50334, 0xfec989d5, 0xfece1b54, 0xfed2b71b, 0xfed75c94, 0xfedc0b2a, 0xfee0c249, 0xfee5815e, 0xfeea47d8, 0xfeef1528, 0xfef3e8be, 0xfef8c20c, 0xfefda088, 0xff0283a5, 0xff076adc, 0xff0c55a4, 0xff114377, 0xff1633d0, 0xff1b262d, 0xff201a0c, 0xff250eee, 0xff2a0453, 0xff2ef9c1, 0xff33eebc, 0xff38e2cb, 0xff3dd578, 0xff42c64c, 0xff47b4d6, 0xff4ca0a2, 0xff518941, 0xff566e47, 0xff5b4f45, 0xff602bd4, 0xff65038a, 0xff69d601, 0xff6ea2d6, 0xff7369a7, 0xff782a12, 0xff7ce3bb, 0xff819645, 0xff864157, 0xff8ae498, 0xff8f7fb2, 0xff941251, 0xff989c25, 0xff9d1cdc, 0xffa1942a, 0xffa601c3, 0xffaa655e, 0xffaebeb2, 0xffb30d7c, 0xffb75177, 0xffbb8a62, 0xffbfb7ff, 0xffc3da11, 0xffc7f05c, 0xffcbfaa8, 0xffcff8be, 0xffd3ea6a, 0xffd7cf79, 0xffdba7b9, 0xffdf72fe, 0xffe33119, 0xffe6e1e1, 0xffea852e, 0xffee1ad8, 0xfff1a2bb, 0xfff51cb5, 0xfff888a4, 0xfffbe66b, 0xffff35ed, 0x0002770f, 0x0005a9b8, 0x0008cdd0, 0x000be344, 0x000ee9ff, 0x0011e1f0, 0x0014cb08, 0x0017a538, 0x001a7075, 0x001d2cb3, 0x001fd9eb, 0x00227816, 0x0025072f, 0x00278731, 0x0029f81b, 0x002c59ed, 0x002eaca8, 0x0030f04f, 0x003324e6, 0x00354a74, 0x003760ff, 0x00396892, 0x003b6135, 0x003d4af6, 0x003f25e1, 0x0040f206, 0x0042af73,
+ 0x00445e3a, 0x0045fe6e, 0x00479023, 0x0049136d, 0x004a8864, 0x004bef1e, 0x004d47b5, 0x004e9242, 0x004fcedf, 0x0050fdaa, 0x00521ebe, 0x0053323b, 0x0054383e, 0x005530e9, 0x00561c5b, 0x0056fab7, 0x0057cc20, 0x005890b9, 0x005948a7, 0x0059f40e, 0x005a9315, 0x005b25e2, 0x005bac9d, 0x005c276d, 0x005c967d, 0x005cf9f4, 0x005d51fd, 0x005d9ec3, 0x005de071, 0x005e1731, 0x005e4331, 0x005e649d, 0x005e7ba1, 0x005e886c, 0x005e8b2b, 0x005e840c, 0x005e733e, 0x005e58ef, 0x005e354e, 0x005e088c, 0x005dd2d6, 0x005d945e, 0x005d4d53, 0x005cfde5, 0x005ca645, 0x005c46a2, 0x005bdf2d, 0x005b7017, 0x005af990, 0x005a7bc9, 0x0059f6f2, 0x00596b3b, 0x0058d8d6, 0x00583ff2, 0x0057a0c0, 0x0056fb70, 0x00565032, 0x00559f36, 0x0054e8ac, 0x00542cc2, 0x00536baa, 0x0052a591, 0x0051daa6, 0x00510b19, 0x00503717, 0x004f5ece, 0x004e826d, 0x004da220, 0x004cbe15, 0x004bd678, 0x004aeb75, 0x0049fd39, 0x00490bef, 0x004817c2, 0x004720dd, 0x0046276a, 0x00452b92, 0x00442d80, 0x00432d5b, 0x00422b4c, 0x0041277c, 0x00402210, 0x003f1b31, 0x003e1304, 0x003d09b0, 0x003bff58, 0x003af423, 0x0039e833, 0x0038dbad, 0x0037ceb3, 0x0036c168, 0x0035b3ed, 0x0034a664, 0x003398ed, 0x00328ba7, 0x00317eb3, 0x0030722e, 0x002f6638, 0x002e5aec, 0x002d5069, 0x002c46c9, 0x002b3e2a, 0x002a36a5, 0x00293054, 0x00282b52, 0x002727b7, 0x0026259c, 0x00252518, 0x00242641, 0x00232930, 0x00222df8, 0x002134b0, 0x00203d6b, 0x001f483d, 0x001e5539, 0x001d6473, 0x001c75fb, 0x001b89e3, 0x001aa03b, 0x0019b913, 0x0018d47b, 0x0017f281, 0x00171334, 0x001636a0, 0x00155cd2, 0x001485d7, 0x0013b1ba, 0x0012e086,
+ 0x00121246, 0x00114703, 0x00107ec6, 0x000fb999, 0x000ef783, 0x000e388c, 0x000d7cba, 0x000cc414, 0x000c0ea0, 0x000b5c64, 0x000aad63, 0x000a01a2, 0x00095925, 0x0008b3f0, 0x00081204, 0x00077364, 0x0006d811, 0x0006400e, 0x0005ab5a, 0x000519f6, 0x00048be2, 0x0004011d, 0x000379a7, 0x0002f57d, 0x0002749e, 0x0001f708, 0x00017cb7, 0x000105a9, 0x000091da, 0x00002147, 0xffffb3eb, 0xffff49c1, 0xfffee2c6, 0xfffe7ef2, 0xfffe1e41, 0xfffdc0ad, 0xfffd6630, 0xfffd0ec3, 0xfffcba5f, 0xfffc68fd, 0xfffc1a97, 0xfffbcf23, 0xfffb869a, 0xfffb40f4, 0xfffafe29, 0xfffabe30, 0xfffa8100, 0xfffa4690, 0xfffa0ed7, 0xfff9d9cc, 0xfff9a764, 0xfff97796, 0xfff94a58, 0xfff91fa0, 0xfff8f764, 0xfff8d199, 0xfff8ae34, 0xfff88d2b, 0xfff86e74, 0xfff85203, 0xfff837cd, 0xfff81fc7, 0xfff809e6, 0xfff7f61f, 0xfff7e467, 0xfff7d4b1, 0xfff7c6f4, 0xfff7bb22, 0xfff7b132, 0xfff7a917, 0xfff7a2c6, 0xfff79e33, 0xfff79b52, 0xfff79a19, 0xfff79a7b, 0xfff79c6e, 0xfff79fe5, 0xfff7a4d5, 0xfff7ab33, 0xfff7b2f3, 0xfff7bc0a, 0xfff7c66d, 0xfff7d210, 0xfff7dee8, 0xfff7eceb, 0xfff7fc0c, 0xfff80c41, 0xfff81d80, 0xfff82fbc, 0xfff842ed, 0xfff85707, 0xfff86bff, 0xfff881cb, 0xfff89861, 0xfff8afb7, 0xfff8c7c3, 0xfff8e07b, 0xfff8f9d4, 0xfff913c6, 0xfff92e46, 0xfff9494c, 0xfff964ce, 0xfff980c3, 0xfff99d23, 0xfff9b9e3, 0xfff9d6fc, 0xfff9f465, 0xfffa1216, 0xfffa3006, 0xfffa4e2d, 0xfffa6c84, 0xfffa8b03, 0xfffaa9a3, 0xfffac85b, 0xfffae725, 0xfffb05f9, 0xfffb24d2, 0xfffb43a7, 0xfffb6273, 0xfffb812f, 0xfffb9fd5, 0xfffbbe5f, 0xfffbdcc6, 0xfffbfb07, 0xfffc191a, 0xfffc36fa, 0xfffc54a4, 0xfffc7210,
0x00000000 // this one is needed for lerping the last coefficient
};
@@ -144,11 +141,8 @@
}
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
}
@@ -163,9 +157,7 @@
: );
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
}
@@ -187,13 +179,8 @@
}
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
}
diff --git a/services/audioflinger/AudioResamplerSinc.h b/services/audioflinger/AudioResamplerSinc.h
index 25fc025..48bc747 100644
--- a/services/audioflinger/AudioResamplerSinc.h
+++ b/services/audioflinger/AudioResamplerSinc.h
@@ -71,7 +71,7 @@
// ----------------------------------------------------------------------------
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
diff --git a/services/audioflinger/StateQueue.h b/services/audioflinger/StateQueue.h
index eba190c..c9b5111 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
diff --git a/services/audioflinger/test-resample.cpp b/services/audioflinger/test-resample.cpp
new file mode 100644
index 0000000..151313b
--- /dev/null
+++ b/services/audioflinger/test-resample.cpp
@@ -0,0 +1,233 @@
+/*
+ * 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>
+
+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] [-q <dq|lq|mq|hq|vhq>] [-i <input-sample-rate>] "
+ "[-o <output-sample-rate>] <input-file> <output-file>\n", name);
+ fprintf(stderr,"-p - enable profiling\n");
+ fprintf(stderr,"-h - create wav file\n");
+ fprintf(stderr,"-q - resampler quality\n");
+ fprintf(stderr," dq : default quality\n");
+ fprintf(stderr," lq : low quality\n");
+ fprintf(stderr," mq : medium quality\n");
+ fprintf(stderr," hq : high quality\n");
+ fprintf(stderr," vhq : very high quality\n");
+ fprintf(stderr,"-i - input file sample rate\n");
+ fprintf(stderr,"-o - output file sample rate\n");
+ return -1;
+}
+
+int main(int argc, char* argv[]) {
+
+ bool profiling = false;
+ bool writeHeader = false;
+ int input_freq = 0;
+ int output_freq = 0;
+ AudioResampler::src_quality quality = AudioResampler::DEFAULT_QUALITY;
+
+ int ch;
+ while ((ch = getopt(argc, argv, "phq:i:o:")) != -1) {
+ switch (ch) {
+ case 'p':
+ profiling = true;
+ break;
+ case 'h':
+ writeHeader = true;
+ 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(argv[0]);
+ return -1;
+ }
+ break;
+ case 'i':
+ input_freq = atoi(optarg);
+ break;
+ case 'o':
+ output_freq = atoi(optarg);
+ break;
+ case '?':
+ default:
+ usage(argv[0]);
+ return -1;
+ }
+ }
+ argc -= optind;
+
+ if (argc != 2) {
+ usage(argv[0]);
+ return -1;
+ }
+
+ argv += optind;
+
+ // ----------------------------------------------------------
+
+ struct stat st;
+ if (stat(argv[0], &st) < 0) {
+ fprintf(stderr, "stat: %s\n", strerror(errno));
+ return -1;
+ }
+
+ int input_fd = open(argv[0], O_RDONLY);
+ if (input_fd < 0) {
+ fprintf(stderr, "open: %s\n", strerror(errno));
+ return -1;
+ }
+
+ size_t input_size = st.st_size;
+ void* input_vaddr = mmap(0, input_size, PROT_READ, MAP_PRIVATE, input_fd,
+ 0);
+ if (input_vaddr == MAP_FAILED ) {
+ fprintf(stderr, "mmap: %s\n", strerror(errno));
+ return -1;
+ }
+
+// printf("input sample rate: %d Hz\n", input_freq);
+// printf("output sample rate: %d Hz\n", output_freq);
+// printf("input mmap: %p, size=%u\n", input_vaddr, input_size);
+
+ // ----------------------------------------------------------
+
+ class Provider: public AudioBufferProvider {
+ int16_t* mAddr;
+ size_t mNumFrames;
+ public:
+ Provider(const void* addr, size_t size) {
+ mAddr = (int16_t*) addr;
+ mNumFrames = size / 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);
+
+ size_t output_size = 2 * 2 * ((int64_t) input_size * output_freq)
+ / input_freq;
+ output_size &= ~7; // always stereo, 32-bits
+
+ void* output_vaddr = malloc(output_size);
+ memset(output_vaddr, 0, output_size);
+
+ AudioResampler* resampler = AudioResampler::create(16, 1, output_freq,
+ quality);
+
+ size_t out_frames = output_size/8;
+ resampler->setSampleRate(input_freq);
+ resampler->setVolume(0x1000, 0x1000);
+ resampler->resample((int*) output_vaddr, out_frames, &provider);
+
+ if (profiling) {
+ memset(output_vaddr, 0, output_size);
+ timespec start, end;
+ clock_gettime(CLOCK_MONOTONIC_HR, &start);
+ 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;
+ printf("%f Mspl/s\n", out_frames/(time/1e9)/1e6);
+ }
+
+ // down-mix (we just truncate and keep the left channel)
+ int32_t* out = (int32_t*) output_vaddr;
+ int16_t* convert = (int16_t*) malloc(out_frames * sizeof(int16_t));
+ for (size_t i = 0; i < out_frames; i++) {
+ int32_t s = out[i * 2] >> 12;
+ if (s > 32767) s = 32767;
+ else if (s < -32768) s = -32768;
+ convert[i] = int16_t(s);
+ }
+
+ // write output to disk
+ int output_fd = open(argv[1], 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*sizeof(int16_t), 1, output_freq, 16);
+ write(output_fd, &wav, sizeof(wav));
+ }
+
+ write(output_fd, convert, out_frames * 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 @@
libbinder \
libcutils \
libmedia \
- libmedia_native \
libcamera_client \
libgui \
libhardware \
@@ -40,6 +39,9 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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::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::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 @@
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::dump(int fd,
- const Vector<String16>& args) {
+ const Vector<String16>& /*args*/) {
ATRACE_CALL();
String8 result;
status_t notLocked;
@@ -894,12 +893,13 @@
{
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_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::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::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 @@
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 @@
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 @@
/**
* 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 @@
#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() {
}
-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 @@
CpuConsumer::LockedBuffer* BurstCapture::jpegEncode(
CpuConsumer::LockedBuffer *imgBuffer,
- int quality)
+ int /*quality*/)
{
ALOGV("%s", __FUNCTION__);
@@ -91,7 +92,7 @@
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 @@
}
}
-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::deleteStream() {
ATRACE_CALL();
- status_t res;
Mutex::Autolock l(mInputMutex);
@@ -144,7 +143,7 @@
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 @@
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::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 @@
};
bool CaptureSequencer::threadLoop() {
- status_t res;
sp<Camera2Client> client = mClient.promote();
if (client == 0) return false;
@@ -213,7 +212,8 @@
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::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::manageStandardPrecaptureWait(
- sp<Camera2Client> &client) {
+ sp<Camera2Client> &/*client*/) {
status_t res;
ATRACE_CALL();
Mutex::Autolock l(mInputMutex);
@@ -578,7 +578,7 @@
}
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 @@
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 @@
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 @@
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 @@
}
// 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 @@
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::deleteStream() {
ATRACE_CALL();
- status_t res;
Mutex::Autolock l(mInputMutex);
@@ -164,7 +163,7 @@
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 @@
// 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 @@
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 @@
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 @@
}
}
+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 @@
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 @@
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 @@
ATRACE_CALL();
Mutex::Autolock m(mMutex);
- status_t res;
mPreviewRequestId++;
if (mPreviewRequestId >= Camera2Client::kPreviewRequestIdEnd) {
mPreviewRequestId = Camera2Client::kPreviewRequestIdStart;
@@ -628,7 +627,7 @@
}
-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(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 @@
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..ea3ef50 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 @@
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,162 @@
// 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;
- // total number of coefficients
+
+ // 2*nzc = (A - 8) / (2.285 * dw)
+ // with dw the transition width = 2*pi*dF/Fs
+ //
+ int nzc = 8;
+
+ //
+ // Example:
+ // 44.1 KHz to 48 KHz resampling
+ // 100 dB rejection above 28 KHz
+ // (the spectrum will fold around 24 KHz and we want 100 dB rejection
+ // at the point where the folding reaches 20 KHz)
+ // ...___|_____
+ // | \|
+ // | ____/|\____
+ // |/alias| \
+ // ------/------+------\---------> KHz
+ // 20 24 28
+
+ // Transition band 8 KHz, or dw = 1.0472
+ //
+ // beta = 10.056
+ // nzc = 20
+ //
+
+ int ch;
+ while ((ch = getopt(argc, argv, ":hds:c:n:f:l:b:p:v:")) != -1) {
+ switch (ch) {
+ case 'd':
+ debug = true;
+ break;
+ case 'p':
+ if (sscanf(optarg, "%u/%u", &polyM, &polyN) != 2) {
+ usage(argv[0]);
+ }
+ polyphase = true;
+ break;
+ case 's':
+ Fs = atof(optarg);
+ break;
+ case 'c':
+ Fc = atof(optarg);
+ break;
+ case 'n':
+ nzc = atoi(optarg);
+ break;
+ case 'l':
+ nz = atoi(optarg);
+ break;
+ case 'f':
+ if (!strcmp(optarg,"fixed")) format = 0;
+ else if (!strcmp(optarg,"float")) format = 1;
+ else usage(argv[0]);
+ break;
+ case 'b':
+ beta = atof(optarg);
+ break;
+ case 'v':
+ atten = pow(10, -fabs(atof(optarg))*0.05 );
+ break;
+ case 'h':
+ default:
+ usage(argv[0]);
+ break;
+ }
+ }
+
+ // cut off frequency ratio Fc/Fs
+ double Fcr = Fc / Fs;
+
+
+ // total number of coefficients (one side)
const int N = (1 << nz) * 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");
}
- printf("\n};\n");
- return 0;
- }
-// http://www.dsptutor.freeuk.com/KaiserFilterDesign/KaiserFilterDesign.html
+ if (!polyphase) {
+ for (int i=0 ; i<N ; i++) {
+ double x = (2.0 * M_PI * i * Fcr) / (1 << nz);
+ double y = kaiser(i+N, 2*N, beta) * sinc(x) * 2.0 * Fcr;
+ y *= atten;
+
+ if (!debug) {
+ if ((i % (1<<nz)) == 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) {
+ if (!format) {
+ printf("\n 0x%08x ", 0);
+ } else {
+ printf("\n %.9g ", 0.0f);
+ }
+ printf("\n};");
+ }
+ printf("\n");
+ return 0;
+}
+
// http://www.csee.umbc.edu/help/sound/AFsp-V2R1/html/audio/ResampAudio.html
-
+