Merge "Fix a crash happening in NBLog's 'writeHistToFile'" into oc-dr1-dev am: 4f771e05db
am: 2a78bf88d4
Change-Id: Ie82fd23b310aa55f33568c8f4a3bf5eda57964d6
diff --git a/Android.bp b/Android.bp
index b207a96..a3679b1 100644
--- a/Android.bp
+++ b/Android.bp
@@ -2,6 +2,5 @@
"camera",
"drm/*",
"media/*",
- "radio",
"soundtrigger",
]
diff --git a/drm/libmediadrm/Android.bp b/drm/libmediadrm/Android.bp
index 66f5fc2..1dd5139 100644
--- a/drm/libmediadrm/Android.bp
+++ b/drm/libmediadrm/Android.bp
@@ -5,26 +5,14 @@
cc_library_shared {
name: "libmediadrm",
- aidl: {
- local_include_dirs: ["aidl"],
- export_aidl_headers: true,
- },
srcs: [
- "aidl/android/media/ICas.aidl",
- "aidl/android/media/ICasListener.aidl",
- "aidl/android/media/IDescrambler.aidl",
- "aidl/android/media/IMediaCasService.aidl",
-
- "CasImpl.cpp",
- "DescramblerImpl.cpp",
"DrmPluginPath.cpp",
"DrmSessionManager.cpp",
"ICrypto.cpp",
"IDrm.cpp",
"IDrmClient.cpp",
"IMediaDrmService.cpp",
- "MediaCasDefs.cpp",
"SharedLibrary.cpp",
"DrmHal.cpp",
"CryptoHal.cpp",
diff --git a/drm/libmediadrm/CasImpl.cpp b/drm/libmediadrm/CasImpl.cpp
deleted file mode 100644
index 1a33bb0..0000000
--- a/drm/libmediadrm/CasImpl.cpp
+++ /dev/null
@@ -1,224 +0,0 @@
-
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-//#define LOG_NDEBUG 0
-#define LOG_TAG "CasImpl"
-
-#include <android/media/ICasListener.h>
-#include <media/cas/CasAPI.h>
-#include <media/CasImpl.h>
-#include <media/SharedLibrary.h>
-#include <utils/Log.h>
-
-namespace android {
-
-static Status getBinderStatus(status_t err) {
- if (err == OK) {
- return Status::ok();
- }
- if (err == BAD_VALUE) {
- return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
- }
- if (err == INVALID_OPERATION) {
- return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
- }
- return Status::fromServiceSpecificError(err);
-}
-
-static String8 sessionIdToString(const CasSessionId &sessionId) {
- String8 result;
- for (size_t i = 0; i < sessionId.size(); i++) {
- result.appendFormat("%02x ", sessionId[i]);
- }
- if (result.isEmpty()) {
- result.append("(null)");
- }
- return result;
-}
-
-struct CasImpl::PluginHolder : public RefBase {
-public:
- explicit PluginHolder(CasPlugin *plugin) : mPlugin(plugin) {}
- ~PluginHolder() { if (mPlugin != NULL) delete mPlugin; }
- CasPlugin* get() { return mPlugin; }
-
-private:
- CasPlugin *mPlugin;
- DISALLOW_EVIL_CONSTRUCTORS(PluginHolder);
-};
-
-CasImpl::CasImpl(const sp<ICasListener> &listener)
- : mPluginHolder(NULL), mListener(listener) {
- ALOGV("CTOR");
-}
-
-CasImpl::~CasImpl() {
- ALOGV("DTOR");
- release();
-}
-
-//static
-void CasImpl::OnEvent(
- void *appData,
- int32_t event,
- int32_t arg,
- uint8_t *data,
- size_t size) {
- if (appData == NULL) {
- ALOGE("Invalid appData!");
- return;
- }
- CasImpl *casImpl = static_cast<CasImpl *>(appData);
- casImpl->onEvent(event, arg, data, size);
-}
-
-void CasImpl::init(const sp<SharedLibrary>& library, CasPlugin *plugin) {
- mLibrary = library;
- mPluginHolder = new PluginHolder(plugin);
-}
-
-void CasImpl::onEvent(
- int32_t event, int32_t arg, uint8_t *data, size_t size) {
- if (mListener == NULL) {
- return;
- }
-
- std::unique_ptr<CasData> eventData;
- if (data != NULL && size > 0) {
- eventData.reset(new CasData(data, data + size));
- }
-
- mListener->onEvent(event, arg, eventData);
-}
-
-Status CasImpl::setPrivateData(const CasData& pvtData) {
- ALOGV("setPrivateData");
- sp<PluginHolder> holder = mPluginHolder;
- if (holder == NULL) {
- return getBinderStatus(INVALID_OPERATION);
- }
- return getBinderStatus(holder->get()->setPrivateData(pvtData));
-}
-
-Status CasImpl::openSession(CasSessionId* sessionId) {
- ALOGV("openSession");
- sp<PluginHolder> holder = mPluginHolder;
- if (holder == NULL) {
- return getBinderStatus(INVALID_OPERATION);
- }
- status_t err = holder->get()->openSession(sessionId);
-
- ALOGV("openSession: session opened, sessionId=%s",
- sessionIdToString(*sessionId).string());
-
- return getBinderStatus(err);
-}
-
-Status CasImpl::setSessionPrivateData(
- const CasSessionId &sessionId, const CasData& pvtData) {
- ALOGV("setSessionPrivateData: sessionId=%s",
- sessionIdToString(sessionId).string());
- sp<PluginHolder> holder = mPluginHolder;
- if (holder == NULL) {
- return getBinderStatus(INVALID_OPERATION);
- }
- return getBinderStatus(holder->get()->setSessionPrivateData(sessionId, pvtData));
-}
-
-Status CasImpl::closeSession(const CasSessionId &sessionId) {
- ALOGV("closeSession: sessionId=%s",
- sessionIdToString(sessionId).string());
- sp<PluginHolder> holder = mPluginHolder;
- if (holder == NULL) {
- return getBinderStatus(INVALID_OPERATION);
- }
- return getBinderStatus(holder->get()->closeSession(sessionId));
-}
-
-Status CasImpl::processEcm(const CasSessionId &sessionId, const ParcelableCasData& ecm) {
- ALOGV("processEcm: sessionId=%s",
- sessionIdToString(sessionId).string());
- sp<PluginHolder> holder = mPluginHolder;
- if (holder == NULL) {
- return getBinderStatus(INVALID_OPERATION);
- }
-
- return getBinderStatus(holder->get()->processEcm(sessionId, ecm));
-}
-
-Status CasImpl::processEmm(const ParcelableCasData& emm) {
- ALOGV("processEmm");
- sp<PluginHolder> holder = mPluginHolder;
- if (holder == NULL) {
- return getBinderStatus(INVALID_OPERATION);
- }
-
- return getBinderStatus(holder->get()->processEmm(emm));
-}
-
-Status CasImpl::sendEvent(
- int32_t event, int32_t arg, const ::std::unique_ptr<CasData> &eventData) {
- ALOGV("sendEvent");
- sp<PluginHolder> holder = mPluginHolder;
- if (holder == NULL) {
- return getBinderStatus(INVALID_OPERATION);
- }
-
- status_t err;
- if (eventData == nullptr) {
- err = holder->get()->sendEvent(event, arg, CasData());
- } else {
- err = holder->get()->sendEvent(event, arg, *eventData);
- }
- return getBinderStatus(err);
-}
-
-Status CasImpl::provision(const String16& provisionString) {
- ALOGV("provision: provisionString=%s", String8(provisionString).string());
- sp<PluginHolder> holder = mPluginHolder;
- if (holder == NULL) {
- return getBinderStatus(INVALID_OPERATION);
- }
-
- return getBinderStatus(holder->get()->provision(String8(provisionString)));
-}
-
-Status CasImpl::refreshEntitlements(
- int32_t refreshType, const ::std::unique_ptr<CasData> &refreshData) {
- ALOGV("refreshEntitlements");
- sp<PluginHolder> holder = mPluginHolder;
- if (holder == NULL) {
- return getBinderStatus(INVALID_OPERATION);
- }
-
- status_t err;
- if (refreshData == nullptr) {
- err = holder->get()->refreshEntitlements(refreshType, CasData());
- } else {
- err = holder->get()->refreshEntitlements(refreshType, *refreshData);
- }
- return getBinderStatus(err);
-}
-
-Status CasImpl::release() {
- ALOGV("release: plugin=%p",
- mPluginHolder == NULL ? mPluginHolder->get() : NULL);
- mPluginHolder.clear();
- return Status::ok();
-}
-
-} // namespace android
-
diff --git a/drm/libmediadrm/DescramblerImpl.cpp b/drm/libmediadrm/DescramblerImpl.cpp
deleted file mode 100644
index 94e09e2..0000000
--- a/drm/libmediadrm/DescramblerImpl.cpp
+++ /dev/null
@@ -1,107 +0,0 @@
-
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-//#define LOG_NDEBUG 0
-#define LOG_TAG "DescramblerImpl"
-
-#include <media/cas/DescramblerAPI.h>
-#include <media/DescramblerImpl.h>
-#include <media/SharedLibrary.h>
-#include <utils/Log.h>
-#include <binder/IMemory.h>
-
-namespace android {
-
-static Status getBinderStatus(status_t err) {
- if (err == OK) {
- return Status::ok();
- }
- if (err == BAD_VALUE) {
- return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
- }
- if (err == INVALID_OPERATION) {
- return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
- }
- return Status::fromServiceSpecificError(err);
-}
-
-static String8 sessionIdToString(const CasSessionId &sessionId) {
- String8 result;
- for (size_t i = 0; i < sessionId.size(); i++) {
- result.appendFormat("%02x ", sessionId[i]);
- }
- if (result.isEmpty()) {
- result.append("(null)");
- }
- return result;
-}
-
-DescramblerImpl::DescramblerImpl(
- const sp<SharedLibrary>& library, DescramblerPlugin *plugin) :
- mLibrary(library), mPlugin(plugin) {
- ALOGV("CTOR: mPlugin=%p", mPlugin);
-}
-
-DescramblerImpl::~DescramblerImpl() {
- ALOGV("DTOR: mPlugin=%p", mPlugin);
- release();
-}
-
-Status DescramblerImpl::setMediaCasSession(const CasSessionId& sessionId) {
- ALOGV("setMediaCasSession: sessionId=%s",
- sessionIdToString(sessionId).string());
-
- return getBinderStatus(mPlugin->setMediaCasSession(sessionId));
-}
-
-Status DescramblerImpl::requiresSecureDecoderComponent(
- const String16& mime, bool *result) {
- *result = mPlugin->requiresSecureDecoderComponent(String8(mime));
-
- return getBinderStatus(OK);
-}
-
-Status DescramblerImpl::descramble(
- const DescrambleInfo& info, int32_t *result) {
- ALOGV("descramble");
-
- *result = mPlugin->descramble(
- info.dstType != DescrambleInfo::kDestinationTypeVmPointer,
- info.scramblingControl,
- info.numSubSamples,
- info.subSamples,
- info.srcMem->pointer(),
- info.srcOffset,
- info.dstType == DescrambleInfo::kDestinationTypeVmPointer ?
- info.srcMem->pointer() : info.dstPtr,
- info.dstOffset,
- NULL);
-
- return getBinderStatus(*result >= 0 ? OK : *result);
-}
-
-Status DescramblerImpl::release() {
- ALOGV("release: mPlugin=%p", mPlugin);
-
- if (mPlugin != NULL) {
- delete mPlugin;
- mPlugin = NULL;
- }
- return Status::ok();
-}
-
-} // namespace android
-
diff --git a/drm/libmediadrm/MediaCasDefs.cpp b/drm/libmediadrm/MediaCasDefs.cpp
deleted file mode 100644
index 9c2ba38..0000000
--- a/drm/libmediadrm/MediaCasDefs.cpp
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-//#define LOG_NDEBUG 0
-#define LOG_TAG "MediaCas"
-
-#include <media/MediaCasDefs.h>
-#include <utils/Log.h>
-#include <binder/IMemory.h>
-
-namespace android {
-namespace media {
-
-///////////////////////////////////////////////////////////////////////////////
-namespace MediaCas {
-
-status_t ParcelableCasData::readFromParcel(const Parcel* parcel) {
- return parcel->readByteVector(this);
-}
-
-status_t ParcelableCasData::writeToParcel(Parcel* parcel) const {
- return parcel->writeByteVector(*this);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-status_t ParcelableCasPluginDescriptor::readFromParcel(const Parcel* /*parcel*/) {
- ALOGE("CAPluginDescriptor::readFromParcel() shouldn't be called");
- return INVALID_OPERATION;
-}
-
-status_t ParcelableCasPluginDescriptor::writeToParcel(Parcel* parcel) const {
- status_t err = parcel->writeInt32(mCASystemId);
- if (err != NO_ERROR) {
- return err;
- }
- return parcel->writeString16(mName);
-}
-
-} // namespace MediaCas
-///////////////////////////////////////////////////////////////////////////////
-
-namespace MediaDescrambler {
-
-DescrambleInfo::DescrambleInfo() {}
-
-DescrambleInfo::~DescrambleInfo() {}
-
-status_t DescrambleInfo::readFromParcel(const Parcel* parcel) {
- status_t err = parcel->readInt32((int32_t*)&dstType);
- if (err != OK) {
- return err;
- }
- if (dstType != kDestinationTypeNativeHandle
- && dstType != kDestinationTypeVmPointer) {
- return BAD_VALUE;
- }
-
- err = parcel->readInt32((int32_t*)&scramblingControl);
- if (err != OK) {
- return err;
- }
-
- err = parcel->readUint32((uint32_t*)&numSubSamples);
- if (err != OK) {
- return err;
- }
- if (numSubSamples > 0xffff) {
- return BAD_VALUE;
- }
-
- subSamples = new DescramblerPlugin::SubSample[numSubSamples];
- if (subSamples == NULL) {
- return NO_MEMORY;
- }
-
- for (size_t i = 0; i < numSubSamples; i++) {
- err = parcel->readUint32(&subSamples[i].mNumBytesOfClearData);
- if (err != OK) {
- return err;
- }
- err = parcel->readUint32(&subSamples[i].mNumBytesOfEncryptedData);
- if (err != OK) {
- return err;
- }
- }
-
- srcMem = interface_cast<IMemory>(parcel->readStrongBinder());
- if (srcMem == NULL) {
- return BAD_VALUE;
- }
-
- err = parcel->readInt32(&srcOffset);
- if (err != OK) {
- return err;
- }
-
- native_handle_t *nativeHandle = NULL;
- if (dstType == kDestinationTypeNativeHandle) {
- nativeHandle = parcel->readNativeHandle();
- dstPtr = static_cast<void *>(nativeHandle);
- } else {
- dstPtr = NULL;
- }
-
- err = parcel->readInt32(&dstOffset);
- if (err != OK) {
- return err;
- }
-
- return OK;
-}
-
-status_t DescrambleInfo::writeToParcel(Parcel* parcel) const {
- if (dstType != kDestinationTypeNativeHandle
- && dstType != kDestinationTypeVmPointer) {
- return BAD_VALUE;
- }
-
- status_t err = parcel->writeInt32((int32_t)dstType);
- if (err != OK) {
- return err;
- }
-
- err = parcel->writeInt32(scramblingControl);
- if (err != OK) {
- return err;
- }
-
- err = parcel->writeUint32(numSubSamples);
- if (err != OK) {
- return err;
- }
-
- for (size_t i = 0; i < numSubSamples; i++) {
- err = parcel->writeUint32(subSamples[i].mNumBytesOfClearData);
- if (err != OK) {
- return err;
- }
- err = parcel->writeUint32(subSamples[i].mNumBytesOfEncryptedData);
- if (err != OK) {
- return err;
- }
- }
-
- err = parcel->writeStrongBinder(IInterface::asBinder(srcMem));
- if (err != OK) {
- return err;
- }
-
- err = parcel->writeInt32(srcOffset);
- if (err != OK) {
- return err;
- }
-
- if (dstType == kDestinationTypeNativeHandle) {
- parcel->writeNativeHandle(static_cast<native_handle_t *>(dstPtr));
- }
-
- err = parcel->writeInt32(dstOffset);
- if (err != OK) {
- return err;
- }
-
- return OK;
-}
-
-} // namespace MediaDescrambler
-
-} // namespace media
-} // namespace android
-
diff --git a/drm/libmediadrm/aidl/android/media/ICas.aidl b/drm/libmediadrm/aidl/android/media/ICas.aidl
deleted file mode 100644
index 9746593..0000000
--- a/drm/libmediadrm/aidl/android/media/ICas.aidl
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-package android.media;
-
-import android.media.MediaCas;
-
-/** @hide */
-interface ICas {
- void setPrivateData(in byte[] pvtData);
- byte[] openSession();
- void closeSession(in byte[] sessionId);
- void setSessionPrivateData(in byte[] sessionId, in byte[] pvtData);
- void processEcm(in byte[] sessionId, in MediaCas.ParcelableCasData ecm);
- void processEmm(in MediaCas.ParcelableCasData emm);
- void sendEvent(int event, int arg, in @nullable byte[] eventData);
- void provision(String provisionString);
- void refreshEntitlements(int refreshType, in @nullable byte[] refreshData);
- void release();
-}
\ No newline at end of file
diff --git a/drm/libmediadrm/aidl/android/media/ICasListener.aidl b/drm/libmediadrm/aidl/android/media/ICasListener.aidl
deleted file mode 100644
index 01a5abc..0000000
--- a/drm/libmediadrm/aidl/android/media/ICasListener.aidl
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-package android.media;
-
-/** @hide */
-interface ICasListener {
- void onEvent(int event, int arg, in @nullable byte[] data);
-}
\ No newline at end of file
diff --git a/drm/libmediadrm/aidl/android/media/IMediaCasService.aidl b/drm/libmediadrm/aidl/android/media/IMediaCasService.aidl
deleted file mode 100644
index 44f6825..0000000
--- a/drm/libmediadrm/aidl/android/media/IMediaCasService.aidl
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-package android.media;
-
-import android.media.IDescrambler;
-import android.media.ICas;
-import android.media.ICasListener;
-import android.media.MediaCas;
-
-/** @hide */
-interface IMediaCasService {
- MediaCas.ParcelableCasPluginDescriptor[] enumeratePlugins();
- boolean isSystemIdSupported(int CA_system_id);
- ICas createPlugin(int CA_system_id, ICasListener listener);
- boolean isDescramblerSupported(int CA_system_id);
- IDescrambler createDescrambler(int CA_system_id);
-}
-
diff --git a/drm/libmediadrm/aidl/android/media/MediaCas.aidl b/drm/libmediadrm/aidl/android/media/MediaCas.aidl
deleted file mode 100644
index cb8d0c6..0000000
--- a/drm/libmediadrm/aidl/android/media/MediaCas.aidl
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-package android.media;
-
-/** @hide */
-parcelable MediaCas.ParcelableCasPluginDescriptor cpp_header "media/MediaCasDefs.h";
-
-/** @hide */
-parcelable MediaCas.ParcelableCasData cpp_header "media/MediaCasDefs.h";
\ No newline at end of file
diff --git a/drm/libmediadrm/aidl/android/media/MediaDescrambler.aidl b/drm/libmediadrm/aidl/android/media/MediaDescrambler.aidl
deleted file mode 100644
index e789244..0000000
--- a/drm/libmediadrm/aidl/android/media/MediaDescrambler.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-package android.media;
-
-/** @hide */
-parcelable MediaDescrambler.DescrambleInfo cpp_header "media/MediaCasDefs.h";
\ No newline at end of file
diff --git a/drm/mediacas/plugins/clearkey/Android.mk b/drm/mediacas/plugins/clearkey/Android.mk
index 8fd866c..4b139a8 100644
--- a/drm/mediacas/plugins/clearkey/Android.mk
+++ b/drm/mediacas/plugins/clearkey/Android.mk
@@ -28,8 +28,7 @@
LOCAL_MODULE := libclearkeycasplugin
-#TODO: move this back to /vendor/lib after conversion to treble
-#LOCAL_PROPRIETARY_MODULE := true
+LOCAL_PROPRIETARY_MODULE := true
LOCAL_MODULE_RELATIVE_PATH := mediacas
LOCAL_SHARED_LIBRARIES := \
@@ -39,6 +38,9 @@
libstagefright_foundation \
libprotobuf-cpp-lite \
+LOCAL_HEADER_LIBRARIES := \
+ media_plugin_headers
+
LOCAL_STATIC_LIBRARIES := \
libjsmn \
diff --git a/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp b/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp
index 4ed5fce..e27631f 100644
--- a/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp
+++ b/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp
@@ -121,7 +121,7 @@
sp<ClearKeyCasSession> session =
ClearKeySessionLibrary::get()->findSession(sessionId);
if (session == NULL) {
- return ERROR_DRM_SESSION_NOT_OPENED;
+ return ERROR_CAS_SESSION_NOT_OPENED;
}
ClearKeySessionLibrary::get()->destroySession(sessionId);
@@ -135,7 +135,7 @@
sp<ClearKeyCasSession> session =
ClearKeySessionLibrary::get()->findSession(sessionId);
if (session == NULL) {
- return ERROR_DRM_SESSION_NOT_OPENED;
+ return ERROR_CAS_SESSION_NOT_OPENED;
}
return OK;
}
@@ -146,7 +146,7 @@
sp<ClearKeyCasSession> session =
ClearKeySessionLibrary::get()->findSession(sessionId);
if (session == NULL) {
- return ERROR_DRM_SESSION_NOT_OPENED;
+ return ERROR_CAS_SESSION_NOT_OPENED;
}
Mutex::Autolock lock(mKeyFetcherLock);
@@ -293,7 +293,7 @@
status_t ClearKeyCasSession::updateECM(
KeyFetcher *keyFetcher, void *ecm, size_t size) {
if (keyFetcher == nullptr) {
- return ERROR_DRM_NOT_PROVISIONED;
+ return ERROR_CAS_NOT_PROVISIONED;
}
if (size < kEcmHeaderLength) {
@@ -344,7 +344,7 @@
size_t numSubSamples, const DescramblerPlugin::SubSample *subSamples,
const void *srcPtr, void *dstPtr, AString * /* errorDetailMsg */) {
if (secure) {
- return ERROR_DRM_CANNOT_HANDLE;
+ return ERROR_CAS_CANNOT_HANDLE;
}
AES_KEY contentKey;
@@ -356,7 +356,7 @@
int32_t keyIndex = (scramblingControl & 1);
if (!mKeyInfo[keyIndex].valid) {
ALOGE("decrypt: key %d is invalid", keyIndex);
- return ERROR_DRM_DECRYPT;
+ return ERROR_CAS_DECRYPT;
}
contentKey = mKeyInfo[keyIndex].contentKey;
}
@@ -420,7 +420,7 @@
if (session == NULL) {
ALOGE("ClearKeyDescramblerPlugin: session not found");
- return ERROR_DRM_SESSION_NOT_OPENED;
+ return ERROR_CAS_SESSION_NOT_OPENED;
}
mCASSession = session;
@@ -446,7 +446,7 @@
if (mCASSession == NULL) {
ALOGE("Uninitialized CAS session!");
- return ERROR_DRM_DECRYPT_UNIT_NOT_INITIALIZED;
+ return ERROR_CAS_DECRYPT_UNIT_NOT_INITIALIZED;
}
return mCASSession->decrypt(
diff --git a/drm/mediacas/plugins/clearkey/JsonAssetLoader.cpp b/drm/mediacas/plugins/clearkey/JsonAssetLoader.cpp
index 9cd77e9..6e1004c 100644
--- a/drm/mediacas/plugins/clearkey/JsonAssetLoader.cpp
+++ b/drm/mediacas/plugins/clearkey/JsonAssetLoader.cpp
@@ -48,24 +48,24 @@
* Extract a clear key asset from a JSON string.
*
* Returns OK if a clear key asset is extracted successfully,
- * or ERROR_DRM_NO_LICENSE if the string doesn't contain a valid
+ * or ERROR_CAS_NO_LICENSE if the string doesn't contain a valid
* clear key asset.
*/
status_t JsonAssetLoader::extractAssetFromString(
const String8& jsonAssetString, Asset *asset) {
if (!parseJsonAssetString(jsonAssetString, &mJsonObjects)) {
- return ERROR_DRM_NO_LICENSE;
+ return ERROR_CAS_NO_LICENSE;
}
if (mJsonObjects.size() < 1) {
- return ERROR_DRM_NO_LICENSE;
+ return ERROR_CAS_NO_LICENSE;
}
if (!parseJsonObject(mJsonObjects[0], &mTokens))
- return ERROR_DRM_NO_LICENSE;
+ return ERROR_CAS_NO_LICENSE;
if (!findKey(mJsonObjects[0], asset)) {
- return ERROR_DRM_NO_LICENSE;
+ return ERROR_CAS_NO_LICENSE;
}
return OK;
}
diff --git a/drm/mediacas/plugins/clearkey/ecm_generator.h b/drm/mediacas/plugins/clearkey/ecm_generator.h
index 2ef06c4..5fbdea5 100644
--- a/drm/mediacas/plugins/clearkey/ecm_generator.h
+++ b/drm/mediacas/plugins/clearkey/ecm_generator.h
@@ -29,7 +29,7 @@
namespace android {
namespace clearkeycas {
enum {
- CLEARKEY_STATUS_BASE = ERROR_DRM_VENDOR_MAX,
+ CLEARKEY_STATUS_BASE = ERROR_CAS_VENDOR_MAX,
CLEARKEY_STATUS_INVALIDASSETID = CLEARKEY_STATUS_BASE - 1,
CLEARKEY_STATUS_INVALIDSYSTEMID = CLEARKEY_STATUS_BASE - 2,
CLEARKEY_STATUS_INVALID_PARAMETER = CLEARKEY_STATUS_BASE - 3,
diff --git a/drm/mediacas/plugins/clearkey/tests/Android.mk b/drm/mediacas/plugins/clearkey/tests/Android.mk
index cbf7be7..e1545af 100644
--- a/drm/mediacas/plugins/clearkey/tests/Android.mk
+++ b/drm/mediacas/plugins/clearkey/tests/Android.mk
@@ -21,12 +21,13 @@
ClearKeyFetcherTest.cpp
LOCAL_MODULE := ClearKeyFetcherTest
+LOCAL_VENDOR_MODULE := true
# LOCAL_LDFLAGS is needed here for the test to use the plugin, because
# the plugin is not in standard library search path. Without this .so
# loading fails at run-time (linking is okay).
LOCAL_LDFLAGS := \
- -Wl,--rpath,\$${ORIGIN}/../../../system/lib/mediacas -Wl,--enable-new-dtags
+ -Wl,--rpath,\$${ORIGIN}/../../../system/vendor/lib/mediacas -Wl,--enable-new-dtags
LOCAL_SHARED_LIBRARIES := \
libutils libclearkeycasplugin libstagefright_foundation libprotobuf-cpp-lite liblog
diff --git a/drm/mediacas/plugins/mock/Android.mk b/drm/mediacas/plugins/mock/Android.mk
index a97fac6..a1d61da 100644
--- a/drm/mediacas/plugins/mock/Android.mk
+++ b/drm/mediacas/plugins/mock/Android.mk
@@ -28,6 +28,8 @@
LOCAL_SHARED_LIBRARIES := \
libutils liblog
+LOCAL_HEADER_LIBRARIES := media_plugin_headers
+
LOCAL_C_INCLUDES += \
$(TOP)/frameworks/av/include \
$(TOP)/frameworks/native/include/media \
diff --git a/drm/mediadrm/plugins/clearkey/tests/Android.bp b/drm/mediadrm/plugins/clearkey/tests/Android.bp
index ac57d65..0fcfc64 100644
--- a/drm/mediadrm/plugins/clearkey/tests/Android.bp
+++ b/drm/mediadrm/plugins/clearkey/tests/Android.bp
@@ -34,4 +34,5 @@
"libstagefright_foundation",
"libutils",
],
+ header_libs: ["media_plugin_headers"],
}
diff --git a/drm/mediadrm/plugins/mock/Android.bp b/drm/mediadrm/plugins/mock/Android.bp
index 7f44819..abd1884 100644
--- a/drm/mediadrm/plugins/mock/Android.bp
+++ b/drm/mediadrm/plugins/mock/Android.bp
@@ -22,6 +22,8 @@
vendor: true,
relative_install_path: "mediadrm",
+ header_libs: ["media_plugin_headers"],
+
shared_libs: [
"libutils",
"liblog",
diff --git a/include/media/AudioClient.h b/include/media/AudioClient.h
deleted file mode 120000
index a0530e4..0000000
--- a/include/media/AudioClient.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libaudioclient/include/media/AudioClient.h
\ No newline at end of file
diff --git a/drm/libmediadrm/aidl/android/media/IDescrambler.aidl b/include/media/AudioClient.h
similarity index 61%
rename from drm/libmediadrm/aidl/android/media/IDescrambler.aidl
rename to include/media/AudioClient.h
index fdf99eb..9efd76d 100644
--- a/drm/libmediadrm/aidl/android/media/IDescrambler.aidl
+++ b/include/media/AudioClient.h
@@ -14,14 +14,25 @@
* limitations under the License.
*/
-package android.media;
-import android.media.MediaDescrambler;
+#ifndef ANDROID_AUDIO_CLIENT_H
+#define ANDROID_AUDIO_CLIENT_H
-/** @hide */
-interface IDescrambler {
- void setMediaCasSession(in byte[] sessionId);
- boolean requiresSecureDecoderComponent(String mime);
- int descramble(in MediaDescrambler.DescrambleInfo descrambleInfo);
- void release();
-}
\ No newline at end of file
+#include <system/audio.h>
+#include <utils/String16.h>
+
+namespace android {
+
+class AudioClient {
+ public:
+ AudioClient() :
+ clientUid(-1), clientPid(-1), packageName("") {}
+
+ uid_t clientUid;
+ pid_t clientPid;
+ String16 packageName;
+};
+
+}; // namespace android
+
+#endif // ANDROID_AUDIO_CLIENT_H
diff --git a/include/media/AudioResampler.h b/include/media/AudioResampler.h
index 50e12f4..771f1b8 120000
--- a/include/media/AudioResampler.h
+++ b/include/media/AudioResampler.h
@@ -1 +1 @@
-../../media/libaudioprocessing/include/AudioResampler.h
\ No newline at end of file
+../../media/libaudioprocessing/include/media/AudioResampler.h
\ No newline at end of file
diff --git a/include/media/AudioResamplerPublic.h b/include/media/AudioResamplerPublic.h
index 309c23d..ce30a78 120000
--- a/include/media/AudioResamplerPublic.h
+++ b/include/media/AudioResamplerPublic.h
@@ -1 +1 @@
-../../media/libaudioprocessing/include/AudioResamplerPublic.h
\ No newline at end of file
+../../media/libaudioprocessing/include/media/AudioResamplerPublic.h
\ No newline at end of file
diff --git a/include/media/CasImpl.h b/include/media/CasImpl.h
deleted file mode 100644
index 726f1ce..0000000
--- a/include/media/CasImpl.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef CAS_IMPL_H_
-#define CAS_IMPL_H_
-
-#include <media/stagefright/foundation/ABase.h>
-#include <android/media/BnCas.h>
-
-namespace android {
-namespace media {
-class ICasListener;
-}
-using namespace media;
-using namespace MediaCas;
-using binder::Status;
-struct CasPlugin;
-class SharedLibrary;
-
-class CasImpl : public BnCas {
-public:
- CasImpl(const sp<ICasListener> &listener);
- virtual ~CasImpl();
-
- static void OnEvent(
- void *appData,
- int32_t event,
- int32_t arg,
- uint8_t *data,
- size_t size);
-
- void init(const sp<SharedLibrary>& library, CasPlugin *plugin);
- void onEvent(
- int32_t event,
- int32_t arg,
- uint8_t *data,
- size_t size);
-
- // ICas inherits
-
- virtual Status setPrivateData(
- const CasData& pvtData) override;
-
- virtual Status openSession(CasSessionId* _aidl_return) override;
-
- virtual Status closeSession(const CasSessionId& sessionId) override;
-
- virtual Status setSessionPrivateData(
- const CasSessionId& sessionId,
- const CasData& pvtData) override;
-
- virtual Status processEcm(
- const CasSessionId& sessionId, const ParcelableCasData& ecm) override;
-
- virtual Status processEmm(const ParcelableCasData& emm) override;
-
- virtual Status sendEvent(
- int32_t event, int32_t arg, const ::std::unique_ptr<CasData> &eventData) override;
-
- virtual Status provision(const String16& provisionString) override;
-
- virtual Status refreshEntitlements(
- int32_t refreshType, const ::std::unique_ptr<CasData> &refreshData) override;
-
- virtual Status release() override;
-
-private:
- struct PluginHolder;
- sp<SharedLibrary> mLibrary;
- sp<PluginHolder> mPluginHolder;
- sp<ICasListener> mListener;
-
- DISALLOW_EVIL_CONSTRUCTORS(CasImpl);
-};
-
-} // namespace android
-
-#endif // CAS_IMPL_H_
diff --git a/include/media/DescramblerImpl.h b/include/media/DescramblerImpl.h
deleted file mode 100644
index 9f212ac..0000000
--- a/include/media/DescramblerImpl.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef DESCRAMBLER_IMPL_H_
-#define DESCRAMBLER_IMPL_H_
-
-#include <media/stagefright/foundation/ABase.h>
-#include <android/media/BnDescrambler.h>
-
-namespace android {
-using namespace media;
-using namespace MediaDescrambler;
-using binder::Status;
-struct DescramblerPlugin;
-class SharedLibrary;
-
-class DescramblerImpl : public BnDescrambler {
-public:
- DescramblerImpl(const sp<SharedLibrary>& library, DescramblerPlugin *plugin);
- virtual ~DescramblerImpl();
-
- virtual Status setMediaCasSession(
- const CasSessionId& sessionId) override;
-
- virtual Status requiresSecureDecoderComponent(
- const String16& mime, bool *result) override;
-
- virtual Status descramble(
- const DescrambleInfo& descrambleInfo, int32_t *result) override;
-
- virtual Status release() override;
-
-private:
- sp<SharedLibrary> mLibrary;
- DescramblerPlugin *mPlugin;
-
- DISALLOW_EVIL_CONSTRUCTORS(DescramblerImpl);
-};
-
-} // namespace android
-
-#endif // DESCRAMBLER_IMPL_H_
diff --git a/include/media/MediaCasDefs.h b/include/media/MediaCasDefs.h
deleted file mode 100644
index 8c5a967..0000000
--- a/include/media/MediaCasDefs.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef MEDIA_CAS_DEFS_H_
-#define MEDIA_CAS_DEFS_H_
-
-#include <binder/Parcel.h>
-#include <media/cas/CasAPI.h>
-#include <media/cas/DescramblerAPI.h>
-#include <media/stagefright/foundation/ABase.h>
-
-namespace android {
-class IMemory;
-namespace media {
-
-namespace MediaCas {
-class ParcelableCasData : public CasData,
- public Parcelable {
-public:
- ParcelableCasData() {}
- ParcelableCasData(const uint8_t *data, size_t size) :
- CasData(data, data + size) {}
- virtual ~ParcelableCasData() {}
- status_t readFromParcel(const Parcel* parcel) override;
- status_t writeToParcel(Parcel* parcel) const override;
-
-private:
- DISALLOW_EVIL_CONSTRUCTORS(ParcelableCasData);
-};
-
-class ParcelableCasPluginDescriptor : public Parcelable {
-public:
- ParcelableCasPluginDescriptor(int32_t CA_system_id, const char *name)
- : mCASystemId(CA_system_id), mName(name) {}
-
- ParcelableCasPluginDescriptor() : mCASystemId(0) {}
-
- ParcelableCasPluginDescriptor(ParcelableCasPluginDescriptor&& desc) = default;
-
- virtual ~ParcelableCasPluginDescriptor() {}
-
- status_t readFromParcel(const Parcel* parcel) override;
- status_t writeToParcel(Parcel* parcel) const override;
-
-private:
- int32_t mCASystemId;
- String16 mName;
- DISALLOW_EVIL_CONSTRUCTORS(ParcelableCasPluginDescriptor);
-};
-}
-
-namespace MediaDescrambler {
-class DescrambleInfo : public Parcelable {
-public:
- enum DestinationType {
- kDestinationTypeVmPointer, // non-secure
- kDestinationTypeNativeHandle // secure
- };
-
- DestinationType dstType;
- DescramblerPlugin::ScramblingControl scramblingControl;
- size_t numSubSamples;
- DescramblerPlugin::SubSample *subSamples;
- sp<IMemory> srcMem;
- int32_t srcOffset;
- void *dstPtr;
- int32_t dstOffset;
-
- DescrambleInfo();
- virtual ~DescrambleInfo();
- status_t readFromParcel(const Parcel* parcel) override;
- status_t writeToParcel(Parcel* parcel) const override;
-
-private:
-
- DISALLOW_EVIL_CONSTRUCTORS(DescrambleInfo);
-};
-}
-
-} // namespace media
-} // namespace android
-
-
-#endif // MEDIA_CAS_DEFS_H_
diff --git a/include/media/audiohal b/include/media/audiohal
index 37e2c39..f400582 120000
--- a/include/media/audiohal
+++ b/include/media/audiohal
@@ -1 +1 @@
-../../media/libaudiohal/include
\ No newline at end of file
+../../media/libaudiohal/include/media/audiohal/
\ No newline at end of file
diff --git a/include/media/nbaio b/include/media/nbaio
deleted file mode 120000
index 67d0ba6..0000000
--- a/include/media/nbaio
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libnbaio/include
\ No newline at end of file
diff --git a/include/media/nbaio/AudioBufferProviderSource.h b/include/media/nbaio/AudioBufferProviderSource.h
new file mode 120000
index 0000000..55841e7
--- /dev/null
+++ b/include/media/nbaio/AudioBufferProviderSource.h
@@ -0,0 +1 @@
+../../../media/libnbaio/include/media/nbaio/AudioBufferProviderSource.h
\ No newline at end of file
diff --git a/include/media/nbaio/AudioStreamInSource.h b/include/media/nbaio/AudioStreamInSource.h
new file mode 120000
index 0000000..f5bcc76
--- /dev/null
+++ b/include/media/nbaio/AudioStreamInSource.h
@@ -0,0 +1 @@
+../../../media/libnbaio/include/media/nbaio/AudioStreamInSource.h
\ No newline at end of file
diff --git a/include/media/nbaio/AudioStreamOutSink.h b/include/media/nbaio/AudioStreamOutSink.h
new file mode 120000
index 0000000..43bfac5
--- /dev/null
+++ b/include/media/nbaio/AudioStreamOutSink.h
@@ -0,0 +1 @@
+../../../media/libnbaio/include/media/nbaio/AudioStreamOutSink.h
\ No newline at end of file
diff --git a/include/media/nbaio/LibsndfileSink.h b/include/media/nbaio/LibsndfileSink.h
new file mode 120000
index 0000000..8a13b6c
--- /dev/null
+++ b/include/media/nbaio/LibsndfileSink.h
@@ -0,0 +1 @@
+../../../media/libnbaio/include/media/nbaio/LibsndfileSink.h
\ No newline at end of file
diff --git a/include/media/nbaio/LibsndfileSource.h b/include/media/nbaio/LibsndfileSource.h
new file mode 120000
index 0000000..2750fde
--- /dev/null
+++ b/include/media/nbaio/LibsndfileSource.h
@@ -0,0 +1 @@
+../../../media/libnbaio/include/media/nbaio/LibsndfileSource.h
\ No newline at end of file
diff --git a/include/media/nbaio/MonoPipe.h b/include/media/nbaio/MonoPipe.h
new file mode 120000
index 0000000..4ea43be
--- /dev/null
+++ b/include/media/nbaio/MonoPipe.h
@@ -0,0 +1 @@
+../../../media/libnbaio/include_mono/media/nbaio/MonoPipe.h
\ No newline at end of file
diff --git a/include/media/nbaio/MonoPipeReader.h b/include/media/nbaio/MonoPipeReader.h
new file mode 120000
index 0000000..30f426c
--- /dev/null
+++ b/include/media/nbaio/MonoPipeReader.h
@@ -0,0 +1 @@
+../../../media/libnbaio/include_mono/media/nbaio/MonoPipeReader.h
\ No newline at end of file
diff --git a/include/media/nbaio/NBAIO.h b/include/media/nbaio/NBAIO.h
new file mode 120000
index 0000000..ff6a151
--- /dev/null
+++ b/include/media/nbaio/NBAIO.h
@@ -0,0 +1 @@
+../../../media/libnbaio/include_mono/media/nbaio/NBAIO.h
\ No newline at end of file
diff --git a/include/media/nbaio/NBLog.h b/include/media/nbaio/NBLog.h
new file mode 120000
index 0000000..c35401e
--- /dev/null
+++ b/include/media/nbaio/NBLog.h
@@ -0,0 +1 @@
+../../../media/libnbaio/include/media/nbaio/NBLog.h
\ No newline at end of file
diff --git a/include/media/nbaio/PerformanceAnalysis.h b/include/media/nbaio/PerformanceAnalysis.h
new file mode 120000
index 0000000..7acfc90
--- /dev/null
+++ b/include/media/nbaio/PerformanceAnalysis.h
@@ -0,0 +1 @@
+../../../media/libnbaio/include/media/nbaio/PerformanceAnalysis.h
\ No newline at end of file
diff --git a/include/media/nbaio/Pipe.h b/include/media/nbaio/Pipe.h
new file mode 120000
index 0000000..a4bbbc9
--- /dev/null
+++ b/include/media/nbaio/Pipe.h
@@ -0,0 +1 @@
+../../../media/libnbaio/include/media/nbaio/Pipe.h
\ No newline at end of file
diff --git a/include/media/nbaio/PipeReader.h b/include/media/nbaio/PipeReader.h
new file mode 120000
index 0000000..64b21cf
--- /dev/null
+++ b/include/media/nbaio/PipeReader.h
@@ -0,0 +1 @@
+../../../media/libnbaio/include/media/nbaio/PipeReader.h
\ No newline at end of file
diff --git a/include/media/nbaio/SourceAudioBufferProvider.h b/include/media/nbaio/SourceAudioBufferProvider.h
new file mode 120000
index 0000000..74a3b06
--- /dev/null
+++ b/include/media/nbaio/SourceAudioBufferProvider.h
@@ -0,0 +1 @@
+../../../media/libnbaio/include/media/nbaio/SourceAudioBufferProvider.h
\ No newline at end of file
diff --git a/include/media/omx/1.0/Conversion.h b/include/media/omx/1.0/Conversion.h
new file mode 120000
index 0000000..06d0ae8
--- /dev/null
+++ b/include/media/omx/1.0/Conversion.h
@@ -0,0 +1 @@
+/usr/local/google/home/pawin/master/frameworks/av/media/libmedia/omx/1.0/include/media/omx/1.0/Conversion.h
\ No newline at end of file
diff --git a/include/media/omx/1.0/WGraphicBufferSource.h b/include/media/omx/1.0/WGraphicBufferSource.h
new file mode 120000
index 0000000..a875e8b
--- /dev/null
+++ b/include/media/omx/1.0/WGraphicBufferSource.h
@@ -0,0 +1 @@
+/usr/local/google/home/pawin/master/frameworks/av/media/libmedia/omx/1.0/include/media/omx/1.0/WGraphicBufferSource.h
\ No newline at end of file
diff --git a/include/media/omx/1.0/WOmx.h b/include/media/omx/1.0/WOmx.h
new file mode 120000
index 0000000..196b306
--- /dev/null
+++ b/include/media/omx/1.0/WOmx.h
@@ -0,0 +1 @@
+/usr/local/google/home/pawin/master/frameworks/av/media/libmedia/omx/1.0/include/media/omx/1.0/WOmx.h
\ No newline at end of file
diff --git a/include/media/omx/1.0/WOmxBufferSource.h b/include/media/omx/1.0/WOmxBufferSource.h
new file mode 120000
index 0000000..8237c6c
--- /dev/null
+++ b/include/media/omx/1.0/WOmxBufferSource.h
@@ -0,0 +1 @@
+/usr/local/google/home/pawin/master/frameworks/av/media/libmedia/omx/1.0/include/media/omx/1.0/WOmxBufferSource.h
\ No newline at end of file
diff --git a/include/media/omx/1.0/WOmxNode.h b/include/media/omx/1.0/WOmxNode.h
new file mode 120000
index 0000000..f30d59c
--- /dev/null
+++ b/include/media/omx/1.0/WOmxNode.h
@@ -0,0 +1 @@
+/usr/local/google/home/pawin/master/frameworks/av/media/libmedia/omx/1.0/include/media/omx/1.0/WOmxNode.h
\ No newline at end of file
diff --git a/include/media/omx/1.0/WOmxObserver.h b/include/media/omx/1.0/WOmxObserver.h
new file mode 120000
index 0000000..1b86143
--- /dev/null
+++ b/include/media/omx/1.0/WOmxObserver.h
@@ -0,0 +1 @@
+/usr/local/google/home/pawin/master/frameworks/av/media/libmedia/omx/1.0/include/media/omx/1.0/WOmxObserver.h
\ No newline at end of file
diff --git a/include/private/media/AudioTrackShared.h b/include/private/media/AudioTrackShared.h
index 9da5ef3..ff440bc 100644
--- a/include/private/media/AudioTrackShared.h
+++ b/include/private/media/AudioTrackShared.h
@@ -568,6 +568,9 @@
// which may include non-contiguous frames
virtual size_t framesReady();
+ // Safe frames ready query used by dump() - this has no side effects.
+ virtual size_t framesReadySafe() const;
+
// Currently AudioFlinger will call framesReady() for a fast track from two threads:
// FastMixer thread, and normal mixer thread. This is dangerous, as the proxy is intended
// to be called from at most one thread of server, and one thread of client.
@@ -620,6 +623,7 @@
public:
virtual size_t framesReady();
+ virtual size_t framesReadySafe() const override;
virtual void framesReadyIsCalledByMultipleThreads();
virtual status_t obtainBuffer(Buffer* buffer, bool ackFlush);
virtual void releaseBuffer(Buffer* buffer);
diff --git a/include/radio/IRadio.h b/include/radio/IRadio.h
deleted file mode 100644
index 1877f8f..0000000
--- a/include/radio/IRadio.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_IRADIO_H
-#define ANDROID_HARDWARE_IRADIO_H
-
-#include <utils/RefBase.h>
-#include <binder/IInterface.h>
-#include <binder/IMemory.h>
-#include <binder/Parcel.h>
-#include <system/radio.h>
-
-namespace android {
-
-class IRadio : public IInterface
-{
-public:
-
- DECLARE_META_INTERFACE(Radio);
-
- virtual void detach() = 0;
-
- virtual status_t setConfiguration(const struct radio_band_config *config) = 0;
-
- virtual status_t getConfiguration(struct radio_band_config *config) = 0;
-
- virtual status_t setMute(bool mute) = 0;
-
- virtual status_t getMute(bool *mute) = 0;
-
- virtual status_t step(radio_direction_t direction, bool skipSubChannel) = 0;
-
- virtual status_t scan(radio_direction_t direction, bool skipSubChannel) = 0;
-
- virtual status_t tune(unsigned int channel, unsigned int subChannel) = 0;
-
- virtual status_t cancel() = 0;
-
- virtual status_t getProgramInformation(struct radio_program_info *info) = 0;
-
- virtual status_t hasControl(bool *hasControl) = 0;
-};
-
-// ----------------------------------------------------------------------------
-
-class BnRadio: public BnInterface<IRadio>
-{
-public:
- virtual status_t onTransact( uint32_t code,
- const Parcel& data,
- Parcel* reply,
- uint32_t flags = 0);
-};
-
-}; // namespace android
-
-#endif //ANDROID_HARDWARE_IRADIO_H
diff --git a/include/radio/IRadioClient.h b/include/radio/IRadioClient.h
deleted file mode 100644
index 9062ad6..0000000
--- a/include/radio/IRadioClient.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_IRADIO_CLIENT_H
-#define ANDROID_HARDWARE_IRADIO_CLIENT_H
-
-#include <utils/RefBase.h>
-#include <binder/IInterface.h>
-#include <binder/IMemory.h>
-#include <binder/Parcel.h>
-
-namespace android {
-
-class IRadioClient : public IInterface
-{
-public:
-
- DECLARE_META_INTERFACE(RadioClient);
-
- virtual void onEvent(const sp<IMemory>& eventMemory) = 0;
-
-};
-
-// ----------------------------------------------------------------------------
-
-class BnRadioClient : public BnInterface<IRadioClient>
-{
-public:
- virtual status_t onTransact( uint32_t code,
- const Parcel& data,
- Parcel* reply,
- uint32_t flags = 0);
-};
-
-}; // namespace android
-
-#endif //ANDROID_HARDWARE_IRADIO_CLIENT_H
diff --git a/include/radio/IRadioService.h b/include/radio/IRadioService.h
deleted file mode 100644
index a946dd5..0000000
--- a/include/radio/IRadioService.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_IRADIO_SERVICE_H
-#define ANDROID_HARDWARE_IRADIO_SERVICE_H
-
-#include <utils/RefBase.h>
-#include <binder/IInterface.h>
-#include <binder/Parcel.h>
-#include <system/radio.h>
-
-namespace android {
-
-class IRadio;
-class IRadioClient;
-
-class IRadioService : public IInterface
-{
-public:
-
- DECLARE_META_INTERFACE(RadioService);
-
- virtual status_t listModules(struct radio_properties *properties,
- uint32_t *numModules) = 0;
-
- virtual status_t attach(const radio_handle_t handle,
- const sp<IRadioClient>& client,
- const struct radio_band_config *config,
- bool withAudio,
- sp<IRadio>& radio) = 0;
-};
-
-// ----------------------------------------------------------------------------
-
-class BnRadioService: public BnInterface<IRadioService>
-{
-public:
- virtual status_t onTransact( uint32_t code,
- const Parcel& data,
- Parcel* reply,
- uint32_t flags = 0);
-};
-
-}; // namespace android
-
-#endif //ANDROID_HARDWARE_IRADIO_SERVICE_H
diff --git a/include/radio/Radio.h b/include/radio/Radio.h
deleted file mode 100644
index fb4dd2f..0000000
--- a/include/radio/Radio.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_RADIO_H
-#define ANDROID_HARDWARE_RADIO_H
-
-#include <binder/IBinder.h>
-#include <utils/threads.h>
-#include <radio/RadioCallback.h>
-#include <radio/IRadio.h>
-#include <radio/IRadioService.h>
-#include <radio/IRadioClient.h>
-#include <system/radio.h>
-
-namespace android {
-
-class MemoryDealer;
-
-class Radio : public BnRadioClient,
- public IBinder::DeathRecipient
-{
-public:
-
- virtual ~Radio();
-
- static status_t listModules(struct radio_properties *properties,
- uint32_t *numModules);
- static sp<Radio> attach(radio_handle_t handle,
- const struct radio_band_config *config,
- bool withAudio,
- const sp<RadioCallback>& callback);
-
-
- void detach();
-
- status_t setConfiguration(const struct radio_band_config *config);
-
- status_t getConfiguration(struct radio_band_config *config);
-
- status_t setMute(bool mute);
-
- status_t getMute(bool *mute);
-
- status_t step(radio_direction_t direction, bool skipSubChannel);
-
- status_t scan(radio_direction_t direction, bool skipSubChannel);
-
- status_t tune(unsigned int channel, unsigned int subChannel);
-
- status_t cancel();
-
- status_t getProgramInformation(struct radio_program_info *info);
-
- status_t hasControl(bool *hasControl);
-
- // BpRadioClient
- virtual void onEvent(const sp<IMemory>& eventMemory);
-
- //IBinder::DeathRecipient
- virtual void binderDied(const wp<IBinder>& who);
-
-private:
- Radio(radio_handle_t handle,
- const sp<RadioCallback>&);
- static const sp<IRadioService> getRadioService();
-
- Mutex mLock;
- sp<IRadio> mIRadio;
- sp<RadioCallback> mCallback;
-};
-
-}; // namespace android
-
-#endif //ANDROID_HARDWARE_RADIO_H
diff --git a/include/radio/RadioCallback.h b/include/radio/RadioCallback.h
deleted file mode 100644
index 4a7f1a6..0000000
--- a/include/radio/RadioCallback.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_RADIO_CALLBACK_H
-#define ANDROID_HARDWARE_RADIO_CALLBACK_H
-
-#include <utils/RefBase.h>
-#include <system/radio.h>
-
-namespace android {
-
-class RadioCallback : public RefBase
-{
-public:
-
- RadioCallback() {}
- virtual ~RadioCallback() {}
-
- virtual void onEvent(struct radio_event *event) = 0;
-
-};
-
-}; // namespace android
-
-#endif //ANDROID_HARDWARE_RADIO_CALLBACK_H
diff --git a/media/audioserver/Android.mk b/media/audioserver/Android.mk
index afd1189..3ee7494 100644
--- a/media/audioserver/Android.mk
+++ b/media/audioserver/Android.mk
@@ -14,7 +14,6 @@
liblog \
libmedialogservice \
libnbaio \
- libradioservice \
libsoundtriggerservice \
libutils \
libhwbinder
diff --git a/media/audioserver/main_audioserver.cpp b/media/audioserver/main_audioserver.cpp
index ee02d23..34c629b 100644
--- a/media/audioserver/main_audioserver.cpp
+++ b/media/audioserver/main_audioserver.cpp
@@ -36,7 +36,6 @@
#include "AudioPolicyService.h"
#include "AAudioService.h"
#include "MediaLogService.h"
-#include "RadioService.h"
#include "SoundTriggerHwService.h"
using namespace android;
@@ -133,7 +132,6 @@
AudioFlinger::instantiate();
AudioPolicyService::instantiate();
AAudioService::instantiate();
- RadioService::instantiate();
SoundTriggerHwService::instantiate();
ProcessState::self()->startThreadPool();
diff --git a/media/libaaudio/Android.bp b/media/libaaudio/Android.bp
index f539ba9..6e60f24 100644
--- a/media/libaaudio/Android.bp
+++ b/media/libaaudio/Android.bp
@@ -16,12 +16,14 @@
name: "libAAudio_headers",
from: "include",
to: "",
- srcs: ["include/aaudio/*.h"],
+ // omit AAudioTesting.h; supplied separately to those who need it
+ srcs: ["include/aaudio/AAudio.h"],
license: "include/aaudio/NOTICE",
}
ndk_library {
name: "libaaudio",
+ // deliberately includes symbols from AAudioTesting.h
symbol_file: "libaaudio.map.txt",
first_version: "26",
unversioned_until: "current",
diff --git a/media/libaaudio/OWNERS b/media/libaaudio/OWNERS
new file mode 100644
index 0000000..f4d51f9
--- /dev/null
+++ b/media/libaaudio/OWNERS
@@ -0,0 +1 @@
+philburk@google.com
diff --git a/media/libaaudio/examples/input_monitor/src/input_monitor.cpp b/media/libaaudio/examples/input_monitor/src/input_monitor.cpp
index 910b10c..edf644a 100644
--- a/media/libaaudio/examples/input_monitor/src/input_monitor.cpp
+++ b/media/libaaudio/examples/input_monitor/src/input_monitor.cpp
@@ -74,7 +74,7 @@
deviceId = AAudioStream_getDeviceId(aaudioStream);
printf("deviceId = %d\n", deviceId);
- actualSamplesPerFrame = AAudioStream_getSamplesPerFrame(aaudioStream);
+ actualSamplesPerFrame = AAudioStream_getChannelCount(aaudioStream);
printf("SamplesPerFrame = %d\n", actualSamplesPerFrame);
actualSampleRate = AAudioStream_getSampleRate(aaudioStream);
printf("SamplesPerFrame = %d\n", actualSampleRate);
diff --git a/media/libaaudio/examples/utils/AAudioSimpleRecorder.h b/media/libaaudio/examples/utils/AAudioSimpleRecorder.h
index cb12fda..6be9112 100644
--- a/media/libaaudio/examples/utils/AAudioSimpleRecorder.h
+++ b/media/libaaudio/examples/utils/AAudioSimpleRecorder.h
@@ -77,7 +77,7 @@
if (mStream == nullptr) {
return AAUDIO_ERROR_INVALID_STATE;
}
- return AAudioStream_getChannelCount(mStream);
+ return AAudioStream_getChannelCount(mStream);;
}
/**
* Only call this after open() has been called.
@@ -179,7 +179,7 @@
// Write zero data to fill up the buffer and prevent underruns.
aaudio_result_t prime() {
- int32_t samplesPerFrame = AAudioStream_getSamplesPerFrame(mStream);
+ int32_t samplesPerFrame = AAudioStream_getChannelCount(mStream);
const int numFrames = 32; // arbitrary
float zeros[numFrames * samplesPerFrame];
memset(zeros, 0, sizeof(zeros));
@@ -252,7 +252,7 @@
}
PeakTrackerData_t *data = (PeakTrackerData_t *) userData;
// printf("MyCallbackProc(): frameCount = %d\n", numFrames);
- int32_t samplesPerFrame = AAudioStream_getSamplesPerFrame(stream);
+ int32_t samplesPerFrame = AAudioStream_getChannelCount(stream);
float sample;
// This code assume mono or stereo.
switch (AAudioStream_getFormat(stream)) {
diff --git a/media/libaaudio/include/aaudio/AAudio.h b/media/libaaudio/include/aaudio/AAudio.h
index e1886ac..e5f0deb 100644
--- a/media/libaaudio/include/aaudio/AAudio.h
+++ b/media/libaaudio/include/aaudio/AAudio.h
@@ -234,14 +234,6 @@
int32_t channelCount);
/**
- *
- * @deprecated use AAudioStreamBuilder_setChannelCount()
- */
-// TODO remove as soon as the NDK and OS are in sync, before RC1
-AAUDIO_API void AAudioStreamBuilder_setSamplesPerFrame(AAudioStreamBuilder* builder,
- int32_t samplesPerFrame);
-
-/**
* Request a sample data format, for example AAUDIO_FORMAT_PCM_I16.
*
* The default, if you do not call this function, is AAUDIO_UNSPECIFIED.
@@ -729,15 +721,6 @@
AAUDIO_API int32_t AAudioStream_getChannelCount(AAudioStream* stream);
/**
- * The samplesPerFrame is also known as channelCount.
- *
- * @deprecated use AAudioStream_getChannelCount()
- * @param stream reference provided by AAudioStreamBuilder_openStream()
- * @return actual samples per frame
- */
-AAUDIO_API int32_t AAudioStream_getSamplesPerFrame(AAudioStream* stream);
-
-/**
* @param stream reference provided by AAudioStreamBuilder_openStream()
* @return actual device ID
*/
diff --git a/media/libaaudio/libaaudio.map.txt b/media/libaaudio/libaaudio.map.txt
index 2ba5250..b9012e5 100644
--- a/media/libaaudio/libaaudio.map.txt
+++ b/media/libaaudio/libaaudio.map.txt
@@ -11,7 +11,6 @@
AAudioStreamBuilder_setErrorCallback;
AAudioStreamBuilder_setFramesPerDataCallback;
AAudioStreamBuilder_setSampleRate;
- AAudioStreamBuilder_setSamplesPerFrame;
AAudioStreamBuilder_setChannelCount;
AAudioStreamBuilder_setFormat;
AAudioStreamBuilder_setSharingMode;
@@ -35,7 +34,6 @@
AAudioStream_getBufferCapacityInFrames;
AAudioStream_getXRunCount;
AAudioStream_getSampleRate;
- AAudioStream_getSamplesPerFrame;
AAudioStream_getChannelCount;
AAudioStream_getPerformanceMode;
AAudioStream_getDeviceId;
diff --git a/media/libaaudio/src/core/AAudioAudio.cpp b/media/libaaudio/src/core/AAudioAudio.cpp
index 3f5de77..ca42444 100644
--- a/media/libaaudio/src/core/AAudioAudio.cpp
+++ b/media/libaaudio/src/core/AAudioAudio.cpp
@@ -150,13 +150,6 @@
streamBuilder->setSamplesPerFrame(channelCount);
}
-AAUDIO_API void AAudioStreamBuilder_setSamplesPerFrame(AAudioStreamBuilder* builder,
- int32_t samplesPerFrame)
-{
- AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
- streamBuilder->setSamplesPerFrame(samplesPerFrame);
-}
-
AAUDIO_API void AAudioStreamBuilder_setDirection(AAudioStreamBuilder* builder,
aaudio_direction_t direction)
{
@@ -357,12 +350,6 @@
return audioStream->getSamplesPerFrame();
}
-AAUDIO_API int32_t AAudioStream_getSamplesPerFrame(AAudioStream* stream)
-{
- AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
- return audioStream->getSamplesPerFrame();
-}
-
AAUDIO_API aaudio_stream_state_t AAudioStream_getState(AAudioStream* stream)
{
AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index 2f710bd..211bd7d 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -1297,7 +1297,7 @@
}
void AudioSystem::AudioPolicyServiceClient::onRecordingConfigurationUpdate(
- int event, audio_session_t session, audio_source_t source,
+ int event, const record_client_info_t *clientInfo,
const audio_config_base_t *clientConfig, const audio_config_base_t *deviceConfig,
audio_patch_handle_t patchHandle) {
record_config_callback cb = NULL;
@@ -1307,7 +1307,7 @@
}
if (cb != NULL) {
- cb(event, session, source, clientConfig, deviceConfig, patchHandle);
+ cb(event, clientInfo, clientConfig, deviceConfig, patchHandle);
}
}
diff --git a/media/libaudioclient/AudioTrack.cpp b/media/libaudioclient/AudioTrack.cpp
index b0b01db..31e1e2b 100644
--- a/media/libaudioclient/AudioTrack.cpp
+++ b/media/libaudioclient/AudioTrack.cpp
@@ -22,6 +22,7 @@
#include <math.h>
#include <sys/resource.h>
+#include <audio_utils/clock.h>
#include <audio_utils/primitives.h>
#include <binder/IPCThreadState.h>
#include <media/AudioTrack.h>
@@ -62,11 +63,6 @@
return tv.tv_sec * 1000000ll + tv.tv_nsec / 1000;
}
-static inline nsecs_t convertTimespecToNs(const struct timespec &tv)
-{
- return tv.tv_sec * (long long)NANOS_PER_SECOND + tv.tv_nsec;
-}
-
// current monotonic time in microseconds.
static int64_t getNowUs()
{
@@ -2563,7 +2559,7 @@
// We update the timestamp time even when paused.
if (mState == STATE_PAUSED /* not needed: STATE_PAUSED_STOPPING */) {
const int64_t now = systemTime();
- const int64_t at = convertTimespecToNs(timestamp.mTime);
+ const int64_t at = audio_utils_ns_from_timespec(×tamp.mTime);
const int64_t lag =
(ets.mTimeNs[ExtendedTimestamp::LOCATION_SERVER_LASTKERNELOK] < 0 ||
ets.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL_LASTKERNELOK] < 0)
@@ -2695,8 +2691,9 @@
// This is sometimes caused by erratic reports of the available space in the ALSA drivers.
if (status == NO_ERROR) {
if (previousTimestampValid) {
- const int64_t previousTimeNanos = convertTimespecToNs(mPreviousTimestamp.mTime);
- const int64_t currentTimeNanos = convertTimespecToNs(timestamp.mTime);
+ const int64_t previousTimeNanos =
+ audio_utils_ns_from_timespec(&mPreviousTimestamp.mTime);
+ const int64_t currentTimeNanos = audio_utils_ns_from_timespec(×tamp.mTime);
if (currentTimeNanos < previousTimeNanos) {
ALOGW("retrograde timestamp time corrected, %lld < %lld",
(long long)currentTimeNanos, (long long)previousTimeNanos);
@@ -2726,7 +2723,7 @@
#if 0
// Uncomment this to verify audio timestamp rate.
const int64_t deltaTime =
- convertTimespecToNs(timestamp.mTime) - previousTimeNanos;
+ audio_utils_ns_from_timespec(×tamp.mTime) - previousTimeNanos;
if (deltaTime != 0) {
const int64_t computedSampleRate =
deltaPosition * (long long)NANOS_PER_SECOND / deltaTime;
diff --git a/media/libaudioclient/AudioTrackShared.cpp b/media/libaudioclient/AudioTrackShared.cpp
index 2ce6c63..e49945b 100644
--- a/media/libaudioclient/AudioTrackShared.cpp
+++ b/media/libaudioclient/AudioTrackShared.cpp
@@ -36,7 +36,7 @@
// a value between "other" + 1 and "other" + INT32_MAX, the choice of
// which needs to be the "least recently used" sequence value for "self".
// In general, this means (new_self) returned is max(self, other) + 1.
-
+__attribute__((no_sanitize("integer")))
static uint32_t incrementSequence(uint32_t self, uint32_t other) {
int32_t diff = (int32_t) self - (int32_t) other;
if (diff >= 0 && diff < INT32_MAX) {
@@ -389,6 +389,7 @@
// ---------------------------------------------------------------------------
+__attribute__((no_sanitize("integer")))
void AudioTrackClientProxy::flush()
{
// This works for mFrameCountP2 <= 2^30
@@ -832,6 +833,25 @@
return filled;
}
+__attribute__((no_sanitize("integer")))
+size_t AudioTrackServerProxy::framesReadySafe() const
+{
+ if (mIsShutdown) {
+ return 0;
+ }
+ const audio_track_cblk_t* cblk = mCblk;
+ const int32_t flush = android_atomic_acquire_load(&cblk->u.mStreaming.mFlush);
+ if (flush != mFlush) {
+ return mFrameCount;
+ }
+ const int32_t rear = android_atomic_acquire_load(&cblk->u.mStreaming.mRear);
+ const ssize_t filled = rear - cblk->u.mStreaming.mFront;
+ if (!(0 <= filled && (size_t) filled <= mFrameCount)) {
+ return 0; // error condition, silently return 0.
+ }
+ return filled;
+}
+
bool AudioTrackServerProxy::setStreamEndDone() {
audio_track_cblk_t* cblk = mCblk;
bool old =
@@ -843,6 +863,7 @@
return old;
}
+__attribute__((no_sanitize("integer")))
void AudioTrackServerProxy::tallyUnderrunFrames(uint32_t frameCount)
{
audio_track_cblk_t* cblk = mCblk;
@@ -900,6 +921,11 @@
return mFramesReadySafe;
}
+size_t StaticAudioTrackServerProxy::framesReadySafe() const
+{
+ return mFramesReadySafe;
+}
+
status_t StaticAudioTrackServerProxy::updateStateWithLoop(
StaticAudioTrackState *localState, const StaticAudioTrackState &update) const
{
@@ -993,6 +1019,7 @@
return (ssize_t) mState.mPosition;
}
+__attribute__((no_sanitize("integer")))
status_t StaticAudioTrackServerProxy::obtainBuffer(Buffer* buffer, bool ackFlush)
{
if (mIsShutdown) {
@@ -1037,6 +1064,7 @@
return NO_ERROR;
}
+__attribute__((no_sanitize("integer")))
void StaticAudioTrackServerProxy::releaseBuffer(Buffer* buffer)
{
size_t stepCount = buffer->mFrameCount;
diff --git a/media/libaudioclient/IAudioPolicyServiceClient.cpp b/media/libaudioclient/IAudioPolicyServiceClient.cpp
index 98a0521..ad7f1de 100644
--- a/media/libaudioclient/IAudioPolicyServiceClient.cpp
+++ b/media/libaudioclient/IAudioPolicyServiceClient.cpp
@@ -48,6 +48,18 @@
data.writeInt32((int32_t) config->format);
}
+inline void readRecordClientInfoFromParcel(const Parcel& data, record_client_info_t *clientInfo) {
+ clientInfo->uid = (uid_t) data.readUint32();
+ clientInfo->session = (audio_session_t) data.readInt32();
+ clientInfo->source = (audio_source_t) data.readInt32();
+}
+
+inline void writeRecordClientInfoFromParcel(Parcel& data, const record_client_info_t *clientInfo) {
+ data.writeUint32((uint32_t) clientInfo->uid);
+ data.writeInt32((int32_t) clientInfo->session);
+ data.writeInt32((int32_t) clientInfo->source);
+}
+
// ----------------------------------------------------------------------
class BpAudioPolicyServiceClient : public BpInterface<IAudioPolicyServiceClient>
{
@@ -80,14 +92,13 @@
remote()->transact(MIX_STATE_UPDATE, data, &reply, IBinder::FLAG_ONEWAY);
}
- void onRecordingConfigurationUpdate(int event, audio_session_t session,
- audio_source_t source, const audio_config_base_t *clientConfig,
+ void onRecordingConfigurationUpdate(int event, const record_client_info_t *clientInfo,
+ const audio_config_base_t *clientConfig,
const audio_config_base_t *deviceConfig, audio_patch_handle_t patchHandle) {
Parcel data, reply;
data.writeInterfaceToken(IAudioPolicyServiceClient::getInterfaceDescriptor());
data.writeInt32(event);
- data.writeInt32(session);
- data.writeInt32(source);
+ writeRecordClientInfoFromParcel(data, clientInfo);
writeAudioConfigBaseToParcel(data, clientConfig);
writeAudioConfigBaseToParcel(data, deviceConfig);
data.writeInt32(patchHandle);
@@ -123,14 +134,14 @@
case RECORDING_CONFIGURATION_UPDATE: {
CHECK_INTERFACE(IAudioPolicyServiceClient, data, reply);
int event = (int) data.readInt32();
- audio_session_t session = (audio_session_t) data.readInt32();
- audio_source_t source = (audio_source_t) data.readInt32();
+ record_client_info_t clientInfo;
audio_config_base_t clientConfig;
audio_config_base_t deviceConfig;
+ readRecordClientInfoFromParcel(data, &clientInfo);
readAudioConfigBaseFromParcel(data, &clientConfig);
readAudioConfigBaseFromParcel(data, &deviceConfig);
audio_patch_handle_t patchHandle = (audio_patch_handle_t) data.readInt32();
- onRecordingConfigurationUpdate(event, session, source, &clientConfig, &deviceConfig,
+ onRecordingConfigurationUpdate(event, &clientInfo, &clientConfig, &deviceConfig,
patchHandle);
return NO_ERROR;
} break;
diff --git a/media/libaudioclient/OWNERS b/media/libaudioclient/OWNERS
new file mode 100644
index 0000000..482b9fb
--- /dev/null
+++ b/media/libaudioclient/OWNERS
@@ -0,0 +1,3 @@
+gkasten@google.com
+jmtrivi@google.com
+mnaganov@google.com
diff --git a/media/libaudioclient/include/media/AudioSystem.h b/media/libaudioclient/include/media/AudioSystem.h
index 2e39d23..4d5b317 100644
--- a/media/libaudioclient/include/media/AudioSystem.h
+++ b/media/libaudioclient/include/media/AudioSystem.h
@@ -33,7 +33,7 @@
typedef void (*audio_error_callback)(status_t err);
typedef void (*dynamic_policy_callback)(int event, String8 regId, int val);
-typedef void (*record_config_callback)(int event, audio_session_t session, int source,
+typedef void (*record_config_callback)(int event, const record_client_info_t *clientInfo,
const audio_config_base_t *clientConfig, const audio_config_base_t *deviceConfig,
audio_patch_handle_t patchHandle);
@@ -440,8 +440,9 @@
virtual void onAudioPortListUpdate();
virtual void onAudioPatchListUpdate();
virtual void onDynamicPolicyMixStateUpdate(String8 regId, int32_t state);
- virtual void onRecordingConfigurationUpdate(int event, audio_session_t session,
- audio_source_t source, const audio_config_base_t *clientConfig,
+ virtual void onRecordingConfigurationUpdate(int event,
+ const record_client_info_t *clientInfo,
+ const audio_config_base_t *clientConfig,
const audio_config_base_t *deviceConfig, audio_patch_handle_t patchHandle);
private:
diff --git a/media/libaudioclient/include/media/IAudioPolicyServiceClient.h b/media/libaudioclient/include/media/IAudioPolicyServiceClient.h
index d94ad00..e0d2495 100644
--- a/media/libaudioclient/include/media/IAudioPolicyServiceClient.h
+++ b/media/libaudioclient/include/media/IAudioPolicyServiceClient.h
@@ -26,6 +26,16 @@
// ----------------------------------------------------------------------------
+struct record_client_info {
+ uid_t uid;
+ audio_session_t session;
+ audio_source_t source;
+};
+
+typedef struct record_client_info record_client_info_t;
+
+// ----------------------------------------------------------------------------
+
class IAudioPolicyServiceClient : public IInterface
{
public:
@@ -38,8 +48,8 @@
// Notifies a change in the mixing state of a specific mix in a dynamic audio policy
virtual void onDynamicPolicyMixStateUpdate(String8 regId, int32_t state) = 0;
// Notifies a change of audio recording configuration
- virtual void onRecordingConfigurationUpdate(int event, audio_session_t session,
- audio_source_t source,
+ virtual void onRecordingConfigurationUpdate(int event,
+ const record_client_info_t *clientInfo,
const audio_config_base_t *clientConfig,
const audio_config_base_t *deviceConfig,
audio_patch_handle_t patchHandle) = 0;
diff --git a/media/libaudiohal/Android.mk b/media/libaudiohal/Android.mk
index e592169..827908e 100644
--- a/media/libaudiohal/Android.mk
+++ b/media/libaudiohal/Android.mk
@@ -3,6 +3,7 @@
include $(CLEAR_VARS)
LOCAL_SHARED_LIBRARIES := \
+ libaudioutils \
libcutils \
liblog \
libutils \
diff --git a/media/libaudiohal/DeviceHalHidl.cpp b/media/libaudiohal/DeviceHalHidl.cpp
index 71fbd98..49ef991 100644
--- a/media/libaudiohal/DeviceHalHidl.cpp
+++ b/media/libaudiohal/DeviceHalHidl.cpp
@@ -98,7 +98,8 @@
} // namespace
DeviceHalHidl::DeviceHalHidl(const sp<IDevice>& device)
- : ConversionHelperHidl("Device"), mDevice(device) {
+ : ConversionHelperHidl("Device"), mDevice(device),
+ mPrimaryDevice(IPrimaryDevice::castFrom(device)) {
}
DeviceHalHidl::~DeviceHalHidl() {
@@ -120,24 +121,21 @@
status_t DeviceHalHidl::setVoiceVolume(float volume) {
if (mDevice == 0) return NO_INIT;
- sp<IPrimaryDevice> primaryDev = IPrimaryDevice::castFrom(mDevice);
- if (primaryDev == 0) return INVALID_OPERATION;
- return processReturn("setVoiceVolume", primaryDev->setVoiceVolume(volume));
+ if (mPrimaryDevice == 0) return INVALID_OPERATION;
+ return processReturn("setVoiceVolume", mPrimaryDevice->setVoiceVolume(volume));
}
status_t DeviceHalHidl::setMasterVolume(float volume) {
if (mDevice == 0) return NO_INIT;
- sp<IPrimaryDevice> primaryDev = IPrimaryDevice::castFrom(mDevice);
- if (primaryDev == 0) return INVALID_OPERATION;
- return processReturn("setMasterVolume", primaryDev->setMasterVolume(volume));
+ if (mPrimaryDevice == 0) return INVALID_OPERATION;
+ return processReturn("setMasterVolume", mPrimaryDevice->setMasterVolume(volume));
}
status_t DeviceHalHidl::getMasterVolume(float *volume) {
if (mDevice == 0) return NO_INIT;
- sp<IPrimaryDevice> primaryDev = IPrimaryDevice::castFrom(mDevice);
- if (primaryDev == 0) return INVALID_OPERATION;
+ if (mPrimaryDevice == 0) return INVALID_OPERATION;
Result retval;
- Return<void> ret = primaryDev->getMasterVolume(
+ Return<void> ret = mPrimaryDevice->getMasterVolume(
[&](Result r, float v) {
retval = r;
if (retval == Result::OK) {
@@ -149,9 +147,8 @@
status_t DeviceHalHidl::setMode(audio_mode_t mode) {
if (mDevice == 0) return NO_INIT;
- sp<IPrimaryDevice> primaryDev = IPrimaryDevice::castFrom(mDevice);
- if (primaryDev == 0) return INVALID_OPERATION;
- return processReturn("setMode", primaryDev->setMode(AudioMode(mode)));
+ if (mPrimaryDevice == 0) return INVALID_OPERATION;
+ return processReturn("setMode", mPrimaryDevice->setMode(AudioMode(mode)));
}
status_t DeviceHalHidl::setMicMute(bool state) {
diff --git a/media/libaudiohal/DeviceHalHidl.h b/media/libaudiohal/DeviceHalHidl.h
index 9da02a4..8651b51 100644
--- a/media/libaudiohal/DeviceHalHidl.h
+++ b/media/libaudiohal/DeviceHalHidl.h
@@ -18,11 +18,13 @@
#define ANDROID_HARDWARE_DEVICE_HAL_HIDL_H
#include <android/hardware/audio/2.0/IDevice.h>
+#include <android/hardware/audio/2.0/IPrimaryDevice.h>
#include <media/audiohal/DeviceHalInterface.h>
#include "ConversionHelperHidl.h"
using ::android::hardware::audio::V2_0::IDevice;
+using ::android::hardware::audio::V2_0::IPrimaryDevice;
using ::android::hardware::Return;
namespace android {
@@ -110,6 +112,7 @@
private:
friend class DevicesFactoryHalHidl;
sp<IDevice> mDevice;
+ sp<IPrimaryDevice> mPrimaryDevice; // Null if it's not a primary device.
// Can not be constructed directly by clients.
explicit DeviceHalHidl(const sp<IDevice>& device);
diff --git a/media/libaudiohal/OWNERS b/media/libaudiohal/OWNERS
new file mode 100644
index 0000000..1456ab6
--- /dev/null
+++ b/media/libaudiohal/OWNERS
@@ -0,0 +1,2 @@
+krocard@google.com
+mnaganov@google.com
diff --git a/media/libaudiohal/StreamHalHidl.cpp b/media/libaudiohal/StreamHalHidl.cpp
index 42785d5..176abee 100644
--- a/media/libaudiohal/StreamHalHidl.cpp
+++ b/media/libaudiohal/StreamHalHidl.cpp
@@ -48,6 +48,18 @@
: ConversionHelperHidl("Stream"),
mStream(stream),
mHalThreadPriority(HAL_THREAD_PRIORITY_DEFAULT) {
+
+ // Instrument audio signal power logging.
+ // Note: This assumes channel mask, format, and sample rate do not change after creation.
+ if (mStream != nullptr && mStreamPowerLog.isUserDebugOrEngBuild()) {
+ // Obtain audio properties (see StreamHalHidl::getAudioProperties() below).
+ Return<void> ret = mStream->getAudioProperties(
+ [&](uint32_t sr, AudioChannelMask m, AudioFormat f) {
+ mStreamPowerLog.init(sr,
+ static_cast<audio_channel_mask_t>(m),
+ static_cast<audio_format_t>(f));
+ });
+ }
}
StreamHalHidl::~StreamHalHidl() {
@@ -135,6 +147,7 @@
hidlHandle->data[0] = fd;
Return<void> ret = mStream->debugDump(hidlHandle);
native_handle_delete(hidlHandle);
+ mStreamPowerLog.dump(fd);
return processReturn("dump", ret);
}
@@ -311,7 +324,7 @@
return status;
}
- return callWriterThread(
+ status = callWriterThread(
WriteCommand::WRITE, "write", static_cast<const uint8_t*>(buffer), bytes,
[&] (const WriteStatus& writeStatus) {
*written = writeStatus.reply.written;
@@ -320,6 +333,8 @@
"hal reports more bytes written than asked for: %lld > %lld",
(long long)*written, (long long)bytes);
});
+ mStreamPowerLog.log(buffer, *written);
+ return status;
}
status_t StreamOutHalHidl::callWriterThread(
@@ -580,7 +595,7 @@
ReadParameters params;
params.command = ReadCommand::READ;
params.params.read = bytes;
- return callReaderThread(params, "read",
+ status = callReaderThread(params, "read",
[&](const ReadStatus& readStatus) {
const size_t availToRead = mDataMQ->availableToRead();
if (!mDataMQ->read(static_cast<uint8_t*>(buffer), std::min(bytes, availToRead))) {
@@ -591,6 +606,8 @@
(int32_t)availToRead, (int32_t)readStatus.reply.read);
*read = readStatus.reply.read;
});
+ mStreamPowerLog.log(buffer, *read);
+ return status;
}
status_t StreamInHalHidl::callReaderThread(
diff --git a/media/libaudiohal/StreamHalHidl.h b/media/libaudiohal/StreamHalHidl.h
index a7df276..a69cce8 100644
--- a/media/libaudiohal/StreamHalHidl.h
+++ b/media/libaudiohal/StreamHalHidl.h
@@ -27,6 +27,7 @@
#include <media/audiohal/StreamHalInterface.h>
#include "ConversionHelperHidl.h"
+#include "StreamPowerLog.h"
using ::android::hardware::audio::V2_0::IStream;
using ::android::hardware::audio::V2_0::IStreamIn;
@@ -103,6 +104,9 @@
bool requestHalThreadPriority(pid_t threadPid, pid_t threadId);
+ // mStreamPowerLog is used for audio signal power logging.
+ StreamPowerLog mStreamPowerLog;
+
private:
const int HAL_THREAD_PRIORITY_DEFAULT = -1;
IStream *mStream;
diff --git a/media/libaudiohal/StreamHalLocal.cpp b/media/libaudiohal/StreamHalLocal.cpp
index 05800a0..dc17f5c 100644
--- a/media/libaudiohal/StreamHalLocal.cpp
+++ b/media/libaudiohal/StreamHalLocal.cpp
@@ -27,7 +27,15 @@
namespace android {
StreamHalLocal::StreamHalLocal(audio_stream_t *stream, sp<DeviceHalLocal> device)
- : mDevice(device), mStream(stream) {
+ : mDevice(device),
+ mStream(stream) {
+ // Instrument audio signal power logging.
+ // Note: This assumes channel mask, format, and sample rate do not change after creation.
+ if (mStream != nullptr && mStreamPowerLog.isUserDebugOrEngBuild()) {
+ mStreamPowerLog.init(mStream->get_sample_rate(mStream),
+ mStream->get_channels(mStream),
+ mStream->get_format(mStream));
+ }
}
StreamHalLocal::~StreamHalLocal() {
@@ -95,7 +103,9 @@
}
status_t StreamHalLocal::dump(int fd) {
- return mStream->dump(mStream, fd);
+ status_t status = mStream->dump(mStream, fd);
+ mStreamPowerLog.dump(fd);
+ return status;
}
status_t StreamHalLocal::setHalThreadPriority(int) {
@@ -133,6 +143,7 @@
ssize_t writeResult = mStream->write(mStream, buffer, bytes);
if (writeResult > 0) {
*written = writeResult;
+ mStreamPowerLog.log(buffer, *written);
return OK;
} else {
*written = 0;
@@ -266,6 +277,7 @@
ssize_t readResult = mStream->read(mStream, buffer, bytes);
if (readResult > 0) {
*read = readResult;
+ mStreamPowerLog.log( buffer, *read);
return OK;
} else {
*read = 0;
diff --git a/media/libaudiohal/StreamHalLocal.h b/media/libaudiohal/StreamHalLocal.h
index 8c96c1f..c7136df 100644
--- a/media/libaudiohal/StreamHalLocal.h
+++ b/media/libaudiohal/StreamHalLocal.h
@@ -18,6 +18,7 @@
#define ANDROID_HARDWARE_STREAM_HAL_LOCAL_H
#include <media/audiohal/StreamHalInterface.h>
+#include "StreamPowerLog.h"
namespace android {
@@ -83,6 +84,9 @@
sp<DeviceHalLocal> mDevice;
+ // mStreamPowerLog is used for audio signal power logging.
+ StreamPowerLog mStreamPowerLog;
+
private:
audio_stream_t *mStream;
};
diff --git a/media/libaudiohal/StreamPowerLog.h b/media/libaudiohal/StreamPowerLog.h
new file mode 100644
index 0000000..a78b1aa
--- /dev/null
+++ b/media/libaudiohal/StreamPowerLog.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_STREAM_POWER_LOG_H
+#define ANDROID_HARDWARE_STREAM_POWER_LOG_H
+
+#include <audio_utils/clock.h>
+#include <audio_utils/PowerLog.h>
+#include <cutils/properties.h>
+#include <system/audio.h>
+
+namespace android {
+
+class StreamPowerLog {
+public:
+ StreamPowerLog() :
+ mIsUserDebugOrEngBuild(is_userdebug_or_eng_build()),
+ mPowerLog(nullptr),
+ mFrameSize(0) {
+ // use init() to set up the power log.
+ }
+
+ ~StreamPowerLog() {
+ power_log_destroy(mPowerLog); // OK for null mPowerLog
+ mPowerLog = nullptr;
+ }
+
+ // A one-time initialization (do not call twice) before using StreamPowerLog.
+ void init(uint32_t sampleRate, audio_channel_mask_t channelMask, audio_format_t format) {
+ if (mPowerLog == nullptr) {
+ // Note: A way to get channel count for both input and output channel masks
+ // but does not check validity of the channel mask.
+ const uint32_t channelCount = popcount(audio_channel_mask_get_bits(channelMask));
+ mFrameSize = channelCount * audio_bytes_per_sample(format);
+ if (mFrameSize > 0) {
+ const size_t kPowerLogFramesPerEntry =
+ (long long)sampleRate * kPowerLogSamplingIntervalMs / 1000;
+ mPowerLog = power_log_create(
+ sampleRate,
+ channelCount,
+ format,
+ kPowerLogEntries,
+ kPowerLogFramesPerEntry);
+ }
+ }
+ // mPowerLog may be NULL (not the right build, format not accepted, etc.).
+ }
+
+ // Dump the power log to fd.
+ void dump(int fd) const {
+ // OK for null mPowerLog
+ (void)power_log_dump(
+ mPowerLog, fd, " " /* prefix */, kPowerLogLines, 0 /* limit_ns */);
+ }
+
+ // Log the audio data contained in buffer.
+ void log(const void *buffer, size_t sizeInBytes) const {
+ if (mPowerLog != nullptr) { // mFrameSize is always nonzero if mPowerLog exists.
+ power_log_log(
+ mPowerLog, buffer, sizeInBytes / mFrameSize, audio_utils_get_real_time_ns());
+ }
+ }
+
+ bool isUserDebugOrEngBuild() const {
+ return mIsUserDebugOrEngBuild;
+ }
+
+private:
+
+ static inline bool is_userdebug_or_eng_build() {
+ char value[PROPERTY_VALUE_MAX];
+ (void)property_get("ro.build.type", value, "unknown"); // ignore actual length
+ return strcmp(value, "userdebug") == 0 || strcmp(value, "eng") == 0;
+ }
+
+ // Audio signal power log configuration.
+ static const size_t kPowerLogLines = 40;
+ static const size_t kPowerLogSamplingIntervalMs = 50;
+ static const size_t kPowerLogEntries = (1 /* minutes */ * 60 /* seconds */ * 1000 /* msec */
+ / kPowerLogSamplingIntervalMs);
+
+ const bool mIsUserDebugOrEngBuild;
+ power_log_t *mPowerLog;
+ size_t mFrameSize;
+};
+
+} // namespace android
+
+#endif // ANDROID_HARDWARE_STREAM_POWER_LOG_H
diff --git a/media/libaudiohal/include/DeviceHalInterface.h b/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
similarity index 100%
rename from media/libaudiohal/include/DeviceHalInterface.h
rename to media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
diff --git a/media/libaudiohal/include/DevicesFactoryHalInterface.h b/media/libaudiohal/include/media/audiohal/DevicesFactoryHalInterface.h
similarity index 100%
rename from media/libaudiohal/include/DevicesFactoryHalInterface.h
rename to media/libaudiohal/include/media/audiohal/DevicesFactoryHalInterface.h
diff --git a/media/libaudiohal/include/EffectBufferHalInterface.h b/media/libaudiohal/include/media/audiohal/EffectBufferHalInterface.h
similarity index 100%
rename from media/libaudiohal/include/EffectBufferHalInterface.h
rename to media/libaudiohal/include/media/audiohal/EffectBufferHalInterface.h
diff --git a/media/libaudiohal/include/EffectHalInterface.h b/media/libaudiohal/include/media/audiohal/EffectHalInterface.h
similarity index 100%
rename from media/libaudiohal/include/EffectHalInterface.h
rename to media/libaudiohal/include/media/audiohal/EffectHalInterface.h
diff --git a/media/libaudiohal/include/EffectsFactoryHalInterface.h b/media/libaudiohal/include/media/audiohal/EffectsFactoryHalInterface.h
similarity index 100%
rename from media/libaudiohal/include/EffectsFactoryHalInterface.h
rename to media/libaudiohal/include/media/audiohal/EffectsFactoryHalInterface.h
diff --git a/media/libaudiohal/include/StreamHalInterface.h b/media/libaudiohal/include/media/audiohal/StreamHalInterface.h
similarity index 100%
rename from media/libaudiohal/include/StreamHalInterface.h
rename to media/libaudiohal/include/media/audiohal/StreamHalInterface.h
diff --git a/media/libaudiohal/include/hidl/HalDeathHandler.h b/media/libaudiohal/include/media/audiohal/hidl/HalDeathHandler.h
similarity index 100%
rename from media/libaudiohal/include/hidl/HalDeathHandler.h
rename to media/libaudiohal/include/media/audiohal/hidl/HalDeathHandler.h
diff --git a/media/libaudioprocessing/include/AudioResampler.h b/media/libaudioprocessing/include/media/AudioResampler.h
similarity index 100%
rename from media/libaudioprocessing/include/AudioResampler.h
rename to media/libaudioprocessing/include/media/AudioResampler.h
diff --git a/media/libaudioprocessing/include/AudioResamplerPublic.h b/media/libaudioprocessing/include/media/AudioResamplerPublic.h
similarity index 100%
rename from media/libaudioprocessing/include/AudioResamplerPublic.h
rename to media/libaudioprocessing/include/media/AudioResamplerPublic.h
diff --git a/media/libeffects/Android.bp b/media/libeffects/Android.bp
index ccaa2b4..0dd3f17 100644
--- a/media/libeffects/Android.bp
+++ b/media/libeffects/Android.bp
@@ -1 +1 @@
-subdirs = ["factory"]
+subdirs = ["factory", "config"]
diff --git a/media/libeffects/OWNERS b/media/libeffects/OWNERS
new file mode 100644
index 0000000..7e3de13
--- /dev/null
+++ b/media/libeffects/OWNERS
@@ -0,0 +1,3 @@
+krocard@google.com
+mnaganov@google.com
+rago@google.com
diff --git a/media/libeffects/config/Android.bp b/media/libeffects/config/Android.bp
new file mode 100644
index 0000000..4398a91
--- /dev/null
+++ b/media/libeffects/config/Android.bp
@@ -0,0 +1,17 @@
+// Effect configuration
+cc_library_shared {
+ name: "libeffectsconfig",
+ vendor_available: true,
+
+ srcs: ["src/EffectsConfig.cpp"],
+
+ shared_libs: [
+ "liblog",
+ "libtinyxml2",
+ ],
+
+ header_libs: ["libaudio_system_headers"],
+ export_header_lib_headers: ["libaudio_system_headers"],
+
+ export_include_dirs: ["include"],
+}
diff --git a/media/libeffects/config/include/media/EffectsConfig.h b/media/libeffects/config/include/media/EffectsConfig.h
new file mode 100644
index 0000000..811730c
--- /dev/null
+++ b/media/libeffects/config/include/media/EffectsConfig.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef ANDROID_MEDIA_EFFECTSCONFIG_H
+#define ANDROID_MEDIA_EFFECTSCONFIG_H
+
+/** @file Parses audio effects configuration file to C and C++ structure.
+ * @see audio_effects_conf_V2_0.xsd for documentation on each structure
+ */
+
+#include <system/audio_effect.h>
+
+#include <map>
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace android {
+namespace effectsConfig {
+
+/** Default path of effect configuration file. */
+constexpr char DEFAULT_PATH[] = "/vendor/etc/audio_effects.xml";
+
+/** Directories where the effect libraries will be search for. */
+constexpr const char* LD_EFFECT_LIBRARY_PATH[] =
+#ifdef __LP64__
+ {"/odm/lib64/soundfx", "/vendor/lib64/soundfx", "/system/lib64/soundfx"};
+#else
+ {"/odm/lib/soundfx", "/vendor/lib/soundfx", "/system/lib/soundfx"};
+#endif
+
+struct Library {
+ std::string name;
+ std::string path;
+};
+using Libraries = std::vector<Library>;
+
+struct EffectImpl {
+ Library* library; //< Only valid as long as the associated library vector is unmodified
+ effect_uuid_t uuid;
+};
+
+struct Effect : public EffectImpl {
+ std::string name;
+ bool isProxy;
+ EffectImpl libSw; //< Only valid if isProxy
+ EffectImpl libHw; //< Only valid if isProxy
+};
+
+using Effects = std::vector<Effect>;
+
+template <class Type>
+struct Stream {
+ Type type;
+ std::vector<std::reference_wrapper<Effect>> effects;
+};
+using OutputStream = Stream<audio_stream_type_t>;
+using InputStream = Stream<audio_source_t>;
+
+/** Parsed configuration.
+ * Intended to be a transient structure only used for deserialization.
+ * Note: Everything is copied in the configuration from the xml dom.
+ * If copies needed to be avoided due to performance issue,
+ * consider keeping a private handle on the xml dom and replace all strings by dom pointers.
+ * Or even better, use SAX parsing to avoid the allocations all together.
+ */
+struct Config {
+ float version;
+ Libraries libraries;
+ Effects effects;
+ std::vector<OutputStream> postprocess;
+ std::vector<InputStream> preprocess;
+};
+
+/** Result of `parse(const char*)` */
+struct ParsingResult {
+ /** Parsed config, nullptr if the xml lib could not load the file */
+ std::unique_ptr<Config> parsedConfig;
+ size_t nbSkippedElement; //< Number of skipped invalid library, effect or processing chain
+};
+
+/** Parses the provided effect configuration.
+ * Parsing do not stop of first invalid element, but continues to the next.
+ * @see ParsingResult::nbSkippedElement
+ */
+ParsingResult parse(const char* path = DEFAULT_PATH);
+
+} // namespace effectsConfig
+} // namespace android
+#endif // ANDROID_MEDIA_EFFECTSCONFIG_H
diff --git a/media/libeffects/config/src/EffectsConfig.cpp b/media/libeffects/config/src/EffectsConfig.cpp
new file mode 100644
index 0000000..97462f8
--- /dev/null
+++ b/media/libeffects/config/src/EffectsConfig.cpp
@@ -0,0 +1,302 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "EffectsConfig"
+
+#include <algorithm>
+#include <cstdint>
+#include <functional>
+#include <string>
+
+#include <tinyxml2.h>
+#include <log/log.h>
+
+#include <media/EffectsConfig.h>
+
+using namespace tinyxml2;
+
+namespace android {
+namespace effectsConfig {
+
+/** All functions except `parse(const char*)` are static. */
+namespace {
+
+/** @return all `node`s children that are elements and match the tag if provided. */
+std::vector<std::reference_wrapper<const XMLElement>> getChildren(const XMLNode& node,
+ const char* childTag = nullptr) {
+ std::vector<std::reference_wrapper<const XMLElement>> children;
+ for (auto* child = node.FirstChildElement(childTag); child != nullptr;
+ child = child->NextSiblingElement(childTag)) {
+ children.emplace_back(*child);
+ }
+ return children;
+}
+
+/** @return xml dump of the provided element.
+ * By not providing a printer, it is implicitly created in the caller context.
+ * In such case the return pointer has the same lifetime as the expression containing dump().
+ */
+const char* dump(const XMLElement& element, XMLPrinter&& printer = {}) {
+ element.Accept(&printer);
+ return printer.CStr();
+}
+
+
+bool stringToUuid(const char *str, effect_uuid_t *uuid)
+{
+ uint32_t tmp[10];
+
+ if (sscanf(str, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x",
+ tmp, tmp+1, tmp+2, tmp+3, tmp+4, tmp+5, tmp+6, tmp+7, tmp+8, tmp+9) < 10) {
+ return false;
+ }
+ uuid->timeLow = (uint32_t)tmp[0];
+ uuid->timeMid = (uint16_t)tmp[1];
+ uuid->timeHiAndVersion = (uint16_t)tmp[2];
+ uuid->clockSeq = (uint16_t)tmp[3];
+ uuid->node[0] = (uint8_t)tmp[4];
+ uuid->node[1] = (uint8_t)tmp[5];
+ uuid->node[2] = (uint8_t)tmp[6];
+ uuid->node[3] = (uint8_t)tmp[7];
+ uuid->node[4] = (uint8_t)tmp[8];
+ uuid->node[5] = (uint8_t)tmp[9];
+
+ return true;
+}
+
+/** Map the enum and string representation of a string type.
+ * Intended to be specialized for each enum to deserialize.
+ * The general template is disabled.
+ */
+template <class Enum>
+constexpr std::enable_if<false, Enum> STREAM_NAME_MAP;
+
+/** All output stream types which support effects.
+ * This need to be kept in sink with the xsd streamOutputType.
+ */
+template <>
+constexpr std::pair<audio_stream_type_t, const char*> STREAM_NAME_MAP<audio_stream_type_t>[] = {
+ {AUDIO_STREAM_VOICE_CALL, "voice_call"},
+ {AUDIO_STREAM_SYSTEM, "system"},
+ {AUDIO_STREAM_RING, "ring"},
+ {AUDIO_STREAM_MUSIC, "music"},
+ {AUDIO_STREAM_ALARM, "alarm"},
+ {AUDIO_STREAM_NOTIFICATION, "notification"},
+ {AUDIO_STREAM_BLUETOOTH_SCO, "bluetooth_sco"},
+ {AUDIO_STREAM_ENFORCED_AUDIBLE, "enforced_audible"},
+ {AUDIO_STREAM_DTMF, "dtmf"},
+ {AUDIO_STREAM_TTS, "tts"},
+};
+
+/** All input stream types which support effects.
+ * This need to be kept in sink with the xsd streamOutputType.
+ */
+template <>
+constexpr std::pair<audio_source_t, const char*> STREAM_NAME_MAP<audio_source_t>[] = {
+ {AUDIO_SOURCE_MIC, "mic"},
+ {AUDIO_SOURCE_VOICE_UPLINK, "voice_uplink"},
+ {AUDIO_SOURCE_VOICE_DOWNLINK, "voice_downlink"},
+ {AUDIO_SOURCE_VOICE_CALL, "voice_call"},
+ {AUDIO_SOURCE_CAMCORDER, "camcorder"},
+ {AUDIO_SOURCE_VOICE_RECOGNITION, "voice_recognition"},
+ {AUDIO_SOURCE_VOICE_COMMUNICATION, "voice_communication"},
+ {AUDIO_SOURCE_UNPROCESSED, "unprocessed"},
+};
+
+/** Find the stream type enum corresponding to the stream type name or return false */
+template <class Type>
+bool stringToStreamType(const char *streamName, Type* type)
+{
+ for (auto& streamNamePair : STREAM_NAME_MAP<Type>) {
+ if (strcmp(streamNamePair.second, streamName) == 0) {
+ *type = streamNamePair.first;
+ return true;
+ }
+ }
+ return false;
+}
+
+/** Parse a library xml note and push the result in libraries or return false on failure. */
+bool parseLibrary(const XMLElement& xmlLibrary, Libraries* libraries) {
+ const char* name = xmlLibrary.Attribute("name");
+ const char* path = xmlLibrary.Attribute("path");
+ if (name == nullptr || path == nullptr) {
+ ALOGE("library must have a name and a path: %s", dump(xmlLibrary));
+ return false;
+ }
+ libraries->push_back({name, path});
+ return true;
+}
+
+/** Find an element in a collection by its name.
+ * @return nullptr if not found, the ellements address if found.
+ */
+template <class T>
+T* findByName(const char* name, std::vector<T>& collection) {
+ auto it = find_if(begin(collection), end(collection),
+ [name] (auto& item) { return item.name == name; });
+ return it != end(collection) ? &*it : nullptr;
+}
+
+/** Parse an effect from an xml element describing it.
+ * @return true and pushes the effect in effects on success,
+ * false on failure. */
+bool parseEffect(const XMLElement& xmlEffect, Libraries& libraries, Effects* effects) {
+ Effect effect{};
+
+ const char* name = xmlEffect.Attribute("name");
+ if (name == nullptr) {
+ ALOGE("%s must have a name: %s", xmlEffect.Value(), dump(xmlEffect));
+ return false;
+ }
+ effect.name = name;
+
+ // Function to parse effect.library and effect.uuid from xml
+ auto parseImpl = [&libraries](const XMLElement& xmlImpl, EffectImpl& effect) {
+ // Retrieve library name and uuid from xml
+ const char* libraryName = xmlImpl.Attribute("library");
+ const char* uuid = xmlImpl.Attribute("uuid");
+ if (libraryName == nullptr || uuid == nullptr) {
+ ALOGE("effect must have a library name and a uuid: %s", dump(xmlImpl));
+ return false;
+ }
+
+ // Convert library name to a pointer to the previously loaded library
+ auto* library = findByName(libraryName, libraries);
+ if (library == nullptr) {
+ ALOGE("Could not find library referenced in: %s", dump(xmlImpl));
+ return false;
+ }
+ effect.library = library;
+
+ if (!stringToUuid(uuid, &effect.uuid)) {
+ ALOGE("Invalid uuid in: %s", dump(xmlImpl));
+ return false;
+ }
+ return true;
+ };
+
+ if (!parseImpl(xmlEffect, effect)) {
+ return false;
+ }
+
+ // Handle proxy effects
+ effect.isProxy = false;
+ if (std::strcmp(xmlEffect.Name(), "effectProxy") == 0) {
+ effect.isProxy = true;
+
+ // Function to parse libhw and libsw
+ auto parseProxy = [&xmlEffect, &parseImpl](const char* tag, EffectImpl& proxyLib) {
+ auto* xmlProxyLib = xmlEffect.FirstChildElement(tag);
+ if (xmlProxyLib == nullptr) {
+ ALOGE("effectProxy must contain a <%s>: %s", tag, dump(*xmlProxyLib));
+ return false;
+ }
+ return parseImpl(*xmlProxyLib, proxyLib);
+ };
+ if (!parseProxy("libhw", effect.libHw) || !parseProxy("libsw", effect.libSw)) {
+ return false;
+ }
+ }
+
+ effects->push_back(std::move(effect));
+ return true;
+}
+
+/** Parse an stream from an xml element describing it.
+ * @return true and pushes the stream in streams on success,
+ * false on failure. */
+template <class Stream>
+bool parseStream(const XMLElement& xmlStream, Effects& effects, std::vector<Stream>* streams) {
+ const char* streamType = xmlStream.Attribute("type");
+ if (streamType == nullptr) {
+ ALOGE("stream must have a type: %s", dump(xmlStream));
+ return false;
+ }
+ Stream stream;
+ if (!stringToStreamType(streamType, &stream.type)) {
+ ALOGE("Invalid stream type %s: %s", streamType, dump(xmlStream));
+ return false;
+ }
+
+ for (auto& xmlApply : getChildren(xmlStream, "apply")) {
+ const char* effectName = xmlApply.get().Attribute("effect");
+ if (effectName == nullptr) {
+ ALOGE("stream/apply must have reference an effect: %s", dump(xmlApply));
+ return false;
+ }
+ auto* effect = findByName(effectName, effects);
+ if (effect == nullptr) {
+ ALOGE("Could not find effect referenced in: %s", dump(xmlApply));
+ return false;
+ }
+ stream.effects.emplace_back(*effect);
+ }
+ streams->push_back(std::move(stream));
+ return true;
+}
+
+}; // namespace
+
+ParsingResult parse(const char* path) {
+ XMLDocument doc;
+ doc.LoadFile(path);
+ if (doc.Error()) {
+ ALOGE("Failed to parse %s: Tinyxml2 error (%d): %s %s", path,
+ doc.ErrorID(), doc.GetErrorStr1(), doc.GetErrorStr2());
+ return {nullptr, 0};
+ }
+
+ auto config = std::make_unique<Config>();
+ size_t nbSkippedElements = 0;
+ auto registerFailure = [&nbSkippedElements](bool result) {
+ nbSkippedElements += result ? 0 : 1;
+ };
+ for (auto& xmlConfig : getChildren(doc, "audio_effects_conf")) {
+
+ // Parse library
+ for (auto& xmlLibraries : getChildren(xmlConfig, "libraries")) {
+ for (auto& xmlLibrary : getChildren(xmlLibraries, "library")) {
+ registerFailure(parseLibrary(xmlLibrary, &config->libraries));
+ }
+ }
+
+ // Parse effects
+ for (auto& xmlEffects : getChildren(xmlConfig, "effects")) {
+ for (auto& xmlEffect : getChildren(xmlEffects)) {
+ registerFailure(parseEffect(xmlEffect, config->libraries, &config->effects));
+ }
+ }
+
+ // Parse pre processing chains
+ for (auto& xmlPreprocess : getChildren(xmlConfig, "preprocess")) {
+ for (auto& xmlStream : getChildren(xmlPreprocess, "stream")) {
+ registerFailure(parseStream(xmlStream, config->effects, &config->preprocess));
+ }
+ }
+
+ // Parse post processing chains
+ for (auto& xmlPostprocess : getChildren(xmlConfig, "postprocess")) {
+ for (auto& xmlStream : getChildren(xmlPostprocess, "stream")) {
+ registerFailure(parseStream(xmlStream, config->effects, &config->postprocess));
+ }
+ }
+ }
+ return {std::move(config), nbSkippedElements};
+}
+
+} // namespace effectsConfig
+} // namespace android
diff --git a/media/libeffects/downmix/Android.mk b/media/libeffects/downmix/Android.mk
index 73f6ef5..28b96d5 100644
--- a/media/libeffects/downmix/Android.mk
+++ b/media/libeffects/downmix/Android.mk
@@ -20,7 +20,7 @@
$(call include-path-for, audio-effects) \
$(call include-path-for, audio-utils)
-LOCAL_CFLAGS += -fvisibility=hidden
+LOCAL_CFLAGS += -fvisibility=hidden -DBUILD_FLOAT
LOCAL_CFLAGS += -Wall -Werror
LOCAL_HEADER_LIBRARIES += libhardware_headers
diff --git a/media/libeffects/downmix/EffectDownmix.c b/media/libeffects/downmix/EffectDownmix.c
index f27d5ca..519f4a8 100644
--- a/media/libeffects/downmix/EffectDownmix.c
+++ b/media/libeffects/downmix/EffectDownmix.c
@@ -33,6 +33,10 @@
#define MINUS_3_DB_IN_Q19_12 2896 // -3dB = 0.707 * 2^12 = 2896
+#ifdef BUILD_FLOAT
+#define MINUS_3_DB_IN_FLOAT 0.70710678f // -3dB = 0.70710678f
+#endif
+
// subset of possible audio_channel_mask_t values, and AUDIO_CHANNEL_OUT_* renamed to CHANNEL_MASK_*
typedef enum {
CHANNEL_MASK_QUAD_BACK = AUDIO_CHANNEL_OUT_QUAD_BACK,
@@ -82,8 +86,19 @@
// number of effects in this library
const int kNbEffects = sizeof(gDescriptors) / sizeof(const effect_descriptor_t *);
-
-
+#ifdef BUILD_FLOAT
+static LVM_FLOAT clamp_float(LVM_FLOAT a) {
+ if (a > 1.0f) {
+ return 1.0f;
+ }
+ else if (a < -1.0f) {
+ return -1.0f;
+ }
+ else {
+ return a;
+ }
+}
+#endif
/*----------------------------------------------------------------------------
* Test code
*--------------------------------------------------------------------------*/
@@ -286,7 +301,7 @@
return -EINVAL;
}
-
+#ifndef BUILD_FLOAT
/*--- Effect Control Interface Implementation ---*/
static int Downmix_Process(effect_handle_t self,
@@ -385,7 +400,108 @@
return 0;
}
+#else /*BUILD_FLOAT*/
+/*--- Effect Control Interface Implementation ---*/
+static int Downmix_Process(effect_handle_t self,
+ audio_buffer_t *inBuffer, audio_buffer_t *outBuffer) {
+
+ downmix_object_t *pDownmixer;
+ LVM_FLOAT *pSrc, *pDst;
+ downmix_module_t *pDwmModule = (downmix_module_t *)self;
+
+ if (pDwmModule == NULL) {
+ return -EINVAL;
+ }
+
+ if (inBuffer == NULL || inBuffer->raw == NULL ||
+ outBuffer == NULL || outBuffer->raw == NULL ||
+ inBuffer->frameCount != outBuffer->frameCount) {
+ return -EINVAL;
+ }
+
+ pDownmixer = (downmix_object_t*) &pDwmModule->context;
+
+ if (pDownmixer->state == DOWNMIX_STATE_UNINITIALIZED) {
+ ALOGE("Downmix_Process error: trying to use an uninitialized downmixer");
+ return -EINVAL;
+ } else if (pDownmixer->state == DOWNMIX_STATE_INITIALIZED) {
+ ALOGE("Downmix_Process error: trying to use a non-configured downmixer");
+ return -ENODATA;
+ }
+
+ pSrc = (LVM_FLOAT *) inBuffer->s16;
+ pDst = (LVM_FLOAT *) outBuffer->s16;
+ size_t numFrames = outBuffer->frameCount;
+
+ const bool accumulate =
+ (pDwmModule->config.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE);
+ const uint32_t downmixInputChannelMask = pDwmModule->config.inputCfg.channels;
+
+ switch(pDownmixer->type) {
+
+ case DOWNMIX_TYPE_STRIP:
+ if (accumulate) {
+ while (numFrames) {
+ pDst[0] = clamp_float(pDst[0] + pSrc[0]);
+ pDst[1] = clamp_float(pDst[1] + pSrc[1]);
+ pSrc += pDownmixer->input_channel_count;
+ pDst += 2;
+ numFrames--;
+ }
+ } else {
+ while (numFrames) {
+ pDst[0] = pSrc[0];
+ pDst[1] = pSrc[1];
+ pSrc += pDownmixer->input_channel_count;
+ pDst += 2;
+ numFrames--;
+ }
+ }
+ break;
+
+ case DOWNMIX_TYPE_FOLD:
+#ifdef DOWNMIX_ALWAYS_USE_GENERIC_DOWNMIXER
+ // bypass the optimized downmix routines for the common formats
+ if (!Downmix_foldGeneric(
+ downmixInputChannelMask, pSrc, pDst, numFrames, accumulate)) {
+ ALOGE("Multichannel configuration 0x%" PRIx32 " is not supported",
+ downmixInputChannelMask);
+ return -EINVAL;
+ }
+ break;
+#endif
+ // optimize for the common formats
+ switch((downmix_input_channel_mask_t)downmixInputChannelMask) {
+ case CHANNEL_MASK_QUAD_BACK:
+ case CHANNEL_MASK_QUAD_SIDE:
+ Downmix_foldFromQuad(pSrc, pDst, numFrames, accumulate);
+ break;
+ case CHANNEL_MASK_5POINT1_BACK:
+ case CHANNEL_MASK_5POINT1_SIDE:
+ Downmix_foldFrom5Point1(pSrc, pDst, numFrames, accumulate);
+ break;
+ case CHANNEL_MASK_7POINT1:
+ Downmix_foldFrom7Point1(pSrc, pDst, numFrames, accumulate);
+ break;
+ default:
+ if (!Downmix_foldGeneric(
+ downmixInputChannelMask, pSrc, pDst, numFrames, accumulate)) {
+ ALOGE("Multichannel configuration 0x%" PRIx32 " is not supported",
+ downmixInputChannelMask);
+ return -EINVAL;
+ }
+ break;
+ }
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+#endif
static int Downmix_Command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdSize,
void *pCmdData, uint32_t *replySize, void *pReplyData) {
@@ -818,6 +934,7 @@
*
*----------------------------------------------------------------------------
*/
+#ifndef BUILD_FLOAT
void Downmix_foldFromQuad(int16_t *pSrc, int16_t*pDst, size_t numFrames, bool accumulate) {
// sample at index 0 is FL
// sample at index 1 is FR
@@ -845,7 +962,35 @@
}
}
}
-
+#else
+void Downmix_foldFromQuad(LVM_FLOAT *pSrc, LVM_FLOAT *pDst, size_t numFrames, bool accumulate) {
+ // sample at index 0 is FL
+ // sample at index 1 is FR
+ // sample at index 2 is RL
+ // sample at index 3 is RR
+ if (accumulate) {
+ while (numFrames) {
+ // FL + RL
+ pDst[0] = clamp_float(pDst[0] + ((pSrc[0] + pSrc[2]) / 2.0f));
+ // FR + RR
+ pDst[1] = clamp_float(pDst[1] + ((pSrc[1] + pSrc[3]) / 2.0f));
+ pSrc += 4;
+ pDst += 2;
+ numFrames--;
+ }
+ } else { // same code as above but without adding and clamping pDst[i] to itself
+ while (numFrames) {
+ // FL + RL
+ pDst[0] = clamp_float((pSrc[0] + pSrc[2]) / 2.0f);
+ // FR + RR
+ pDst[1] = clamp_float((pSrc[1] + pSrc[3]) / 2.0f);
+ pSrc += 4;
+ pDst += 2;
+ numFrames--;
+ }
+ }
+}
+#endif
/*----------------------------------------------------------------------------
* Downmix_foldFrom5Point1()
@@ -864,6 +1009,7 @@
*
*----------------------------------------------------------------------------
*/
+#ifndef BUILD_FLOAT
void Downmix_foldFrom5Point1(int16_t *pSrc, int16_t*pDst, size_t numFrames, bool accumulate) {
int32_t lt, rt, centerPlusLfeContrib; // samples in Q19.12 format
// sample at index 0 is FL
@@ -908,7 +1054,52 @@
}
}
}
-
+#else
+void Downmix_foldFrom5Point1(LVM_FLOAT *pSrc, LVM_FLOAT *pDst, size_t numFrames, bool accumulate) {
+ LVM_FLOAT lt, rt, centerPlusLfeContrib; // samples in Q19.12 format
+ // sample at index 0 is FL
+ // sample at index 1 is FR
+ // sample at index 2 is FC
+ // sample at index 3 is LFE
+ // sample at index 4 is RL
+ // sample at index 5 is RR
+ // code is mostly duplicated between the two values of accumulate to avoid repeating the test
+ // for every sample
+ if (accumulate) {
+ while (numFrames) {
+ // centerPlusLfeContrib = FC(-3dB) + LFE(-3dB)
+ centerPlusLfeContrib = (pSrc[2] * MINUS_3_DB_IN_FLOAT)
+ + (pSrc[3] * MINUS_3_DB_IN_FLOAT);
+ // FL + centerPlusLfeContrib + RL
+ lt = pSrc[0] + centerPlusLfeContrib + pSrc[4];
+ // FR + centerPlusLfeContrib + RR
+ rt = pSrc[1] + centerPlusLfeContrib + pSrc[5];
+ // accumulate in destination
+ pDst[0] = clamp_float(pDst[0] + (lt / 2.0f));
+ pDst[1] = clamp_float(pDst[1] + (rt / 2.0f));
+ pSrc += 6;
+ pDst += 2;
+ numFrames--;
+ }
+ } else { // same code as above but without adding and clamping pDst[i] to itself
+ while (numFrames) {
+ // centerPlusLfeContrib = FC(-3dB) + LFE(-3dB)
+ centerPlusLfeContrib = (pSrc[2] * MINUS_3_DB_IN_FLOAT)
+ + (pSrc[3] * MINUS_3_DB_IN_FLOAT);
+ // FL + centerPlusLfeContrib + RL
+ lt = pSrc[0] + centerPlusLfeContrib + pSrc[4];
+ // FR + centerPlusLfeContrib + RR
+ rt = pSrc[1] + centerPlusLfeContrib + pSrc[5];
+ // store in destination
+ pDst[0] = clamp_float(lt / 2.0f); // differs from when accumulate is true above
+ pDst[1] = clamp_float(rt / 2.0f); // differs from when accumulate is true above
+ pSrc += 6;
+ pDst += 2;
+ numFrames--;
+ }
+ }
+}
+#endif
/*----------------------------------------------------------------------------
* Downmix_foldFrom7Point1()
@@ -927,6 +1118,7 @@
*
*----------------------------------------------------------------------------
*/
+#ifndef BUILD_FLOAT
void Downmix_foldFrom7Point1(int16_t *pSrc, int16_t*pDst, size_t numFrames, bool accumulate) {
int32_t lt, rt, centerPlusLfeContrib; // samples in Q19.12 format
// sample at index 0 is FL
@@ -973,8 +1165,54 @@
}
}
}
-
-
+#else
+void Downmix_foldFrom7Point1(LVM_FLOAT *pSrc, LVM_FLOAT *pDst, size_t numFrames, bool accumulate) {
+ LVM_FLOAT lt, rt, centerPlusLfeContrib; // samples in Q19.12 format
+ // sample at index 0 is FL
+ // sample at index 1 is FR
+ // sample at index 2 is FC
+ // sample at index 3 is LFE
+ // sample at index 4 is RL
+ // sample at index 5 is RR
+ // sample at index 6 is SL
+ // sample at index 7 is SR
+ // code is mostly duplicated between the two values of accumulate to avoid repeating the test
+ // for every sample
+ if (accumulate) {
+ while (numFrames) {
+ // centerPlusLfeContrib = FC(-3dB) + LFE(-3dB)
+ centerPlusLfeContrib = (pSrc[2] * MINUS_3_DB_IN_Q19_12)
+ + (pSrc[3] * MINUS_3_DB_IN_Q19_12);
+ // FL + centerPlusLfeContrib + SL + RL
+ lt = pSrc[0] + centerPlusLfeContrib + pSrc[6] + pSrc[4];
+ // FR + centerPlusLfeContrib + SR + RR
+ rt = pSrc[1] + centerPlusLfeContrib + pSrc[7] + pSrc[5];
+ //accumulate in destination
+ pDst[0] = clamp_float(pDst[0] + (lt / 2.0f));
+ pDst[1] = clamp_float(pDst[1] + (rt / 2.0f));
+ pSrc += 8;
+ pDst += 2;
+ numFrames--;
+ }
+ } else { // same code as above but without adding and clamping pDst[i] to itself
+ while (numFrames) {
+ // centerPlusLfeContrib = FC(-3dB) + LFE(-3dB)
+ centerPlusLfeContrib = (pSrc[2] * MINUS_3_DB_IN_FLOAT)
+ + (pSrc[3] * MINUS_3_DB_IN_FLOAT);
+ // FL + centerPlusLfeContrib + SL + RL
+ lt = pSrc[0] + centerPlusLfeContrib + pSrc[6] + pSrc[4];
+ // FR + centerPlusLfeContrib + SR + RR
+ rt = pSrc[1] + centerPlusLfeContrib + pSrc[7] + pSrc[5];
+ // store in destination
+ pDst[0] = clamp_float(lt / 2.0f); // differs from when accumulate is true above
+ pDst[1] = clamp_float(rt / 2.0f); // differs from when accumulate is true above
+ pSrc += 8;
+ pDst += 2;
+ numFrames--;
+ }
+ }
+}
+#endif
/*----------------------------------------------------------------------------
* Downmix_foldGeneric()
*----------------------------------------------------------------------------
@@ -1001,6 +1239,7 @@
*
*----------------------------------------------------------------------------
*/
+#ifndef BUILD_FLOAT
bool Downmix_foldGeneric(
uint32_t mask, int16_t *pSrc, int16_t*pDst, size_t numFrames, bool accumulate) {
@@ -1092,3 +1331,96 @@
}
return true;
}
+#else
+bool Downmix_foldGeneric(
+ uint32_t mask, LVM_FLOAT *pSrc, LVM_FLOAT *pDst, size_t numFrames, bool accumulate) {
+
+ if (!Downmix_validChannelMask(mask)) {
+ return false;
+ }
+
+ const bool hasSides = (mask & kSides) != 0;
+ const bool hasBacks = (mask & kBacks) != 0;
+
+ const int numChan = audio_channel_count_from_out_mask(mask);
+ const bool hasFC = ((mask & AUDIO_CHANNEL_OUT_FRONT_CENTER) == AUDIO_CHANNEL_OUT_FRONT_CENTER);
+ const bool hasLFE =
+ ((mask & AUDIO_CHANNEL_OUT_LOW_FREQUENCY) == AUDIO_CHANNEL_OUT_LOW_FREQUENCY);
+ const bool hasBC = ((mask & AUDIO_CHANNEL_OUT_BACK_CENTER) == AUDIO_CHANNEL_OUT_BACK_CENTER);
+ // compute at what index each channel is: samples will be in the following order:
+ // FL FR FC LFE BL BR BC SL SR
+ // when a channel is not present, its index is set to the same as the index of the preceding
+ // channel
+ const int indexFC = hasFC ? 2 : 1; // front center
+ const int indexLFE = hasLFE ? indexFC + 1 : indexFC; // low frequency
+ const int indexBL = hasBacks ? indexLFE + 1 : indexLFE; // back left
+ const int indexBR = hasBacks ? indexBL + 1 : indexBL; // back right
+ const int indexBC = hasBC ? indexBR + 1 : indexBR; // back center
+ const int indexSL = hasSides ? indexBC + 1 : indexBC; // side left
+ const int indexSR = hasSides ? indexSL + 1 : indexSL; // side right
+
+ LVM_FLOAT lt, rt, centersLfeContrib;
+ // code is mostly duplicated between the two values of accumulate to avoid repeating the test
+ // for every sample
+ if (accumulate) {
+ while (numFrames) {
+ // compute contribution of FC, BC and LFE
+ centersLfeContrib = 0;
+ if (hasFC) { centersLfeContrib += pSrc[indexFC]; }
+ if (hasLFE) { centersLfeContrib += pSrc[indexLFE]; }
+ if (hasBC) { centersLfeContrib += pSrc[indexBC]; }
+ centersLfeContrib *= MINUS_3_DB_IN_FLOAT;
+ // always has FL/FR
+ lt = pSrc[0];
+ rt = pSrc[1];
+ // mix in sides and backs
+ if (hasSides) {
+ lt += pSrc[indexSL];
+ rt += pSrc[indexSR];
+ }
+ if (hasBacks) {
+ lt += pSrc[indexBL];
+ rt += pSrc[indexBR];
+ }
+ lt += centersLfeContrib;
+ rt += centersLfeContrib;
+ // accumulate in destination
+ pDst[0] = clamp_float(pDst[0] + (lt / 2.0f));
+ pDst[1] = clamp_float(pDst[1] + (rt / 2.0f));
+ pSrc += numChan;
+ pDst += 2;
+ numFrames--;
+ }
+ } else {
+ while (numFrames) {
+ // compute contribution of FC, BC and LFE
+ centersLfeContrib = 0;
+ if (hasFC) { centersLfeContrib += pSrc[indexFC]; }
+ if (hasLFE) { centersLfeContrib += pSrc[indexLFE]; }
+ if (hasBC) { centersLfeContrib += pSrc[indexBC]; }
+ centersLfeContrib *= MINUS_3_DB_IN_FLOAT;
+ // always has FL/FR
+ lt = pSrc[0];
+ rt = pSrc[1];
+ // mix in sides and backs
+ if (hasSides) {
+ lt += pSrc[indexSL];
+ rt += pSrc[indexSR];
+ }
+ if (hasBacks) {
+ lt += pSrc[indexBL];
+ rt += pSrc[indexBR];
+ }
+ lt += centersLfeContrib;
+ rt += centersLfeContrib;
+ // store in destination
+ pDst[0] = clamp_float(lt / 2.0f); // differs from when accumulate is true above
+ pDst[1] = clamp_float(rt / 2.0f); // differs from when accumulate is true above
+ pSrc += numChan;
+ pDst += 2;
+ numFrames--;
+ }
+ }
+ return true;
+}
+#endif
\ No newline at end of file
diff --git a/media/libeffects/downmix/EffectDownmix.h b/media/libeffects/downmix/EffectDownmix.h
index 2399abd..c1be0f2 100644
--- a/media/libeffects/downmix/EffectDownmix.h
+++ b/media/libeffects/downmix/EffectDownmix.h
@@ -27,7 +27,9 @@
*/
#define DOWNMIX_OUTPUT_CHANNELS AUDIO_CHANNEL_OUT_STEREO
-
+#ifdef BUILD_FLOAT
+#define LVM_FLOAT float
+#endif
typedef enum {
DOWNMIX_STATE_UNINITIALIZED,
DOWNMIX_STATE_INITIALIZED,
@@ -95,11 +97,18 @@
int Downmix_Reset(downmix_object_t *pDownmixer, bool init);
int Downmix_setParameter(downmix_object_t *pDownmixer, int32_t param, uint32_t size, void *pValue);
int Downmix_getParameter(downmix_object_t *pDownmixer, int32_t param, uint32_t *pSize, void *pValue);
-
+#ifdef BUILD_FLOAT
+void Downmix_foldFromQuad(LVM_FLOAT *pSrc, LVM_FLOAT *pDst, size_t numFrames, bool accumulate);
+void Downmix_foldFrom5Point1(LVM_FLOAT *pSrc, LVM_FLOAT *pDst, size_t numFrames, bool accumulate);
+void Downmix_foldFrom7Point1(LVM_FLOAT *pSrc, LVM_FLOAT *pDst, size_t numFrames, bool accumulate);
+bool Downmix_foldGeneric(
+ uint32_t mask, LVM_FLOAT *pSrc, LVM_FLOAT *pDst, size_t numFrames, bool accumulate);
+#else
void Downmix_foldFromQuad(int16_t *pSrc, int16_t*pDst, size_t numFrames, bool accumulate);
void Downmix_foldFrom5Point1(int16_t *pSrc, int16_t*pDst, size_t numFrames, bool accumulate);
void Downmix_foldFrom7Point1(int16_t *pSrc, int16_t*pDst, size_t numFrames, bool accumulate);
bool Downmix_foldGeneric(
uint32_t mask, int16_t *pSrc, int16_t*pDst, size_t numFrames, bool accumulate);
+#endif
#endif /*ANDROID_EFFECTDOWNMIX_H_*/
diff --git a/media/libeffects/factory/Android.bp b/media/libeffects/factory/Android.bp
index 16680bd..ddbfdd8 100644
--- a/media/libeffects/factory/Android.bp
+++ b/media/libeffects/factory/Android.bp
@@ -10,18 +10,47 @@
cc_library_shared {
name: "libeffects",
vendor: true,
- srcs: ["EffectsFactory.c"],
+ srcs: [
+ "EffectsFactory.c",
+ "EffectsConfigLoader.c",
+ "EffectsFactoryState.c",
+ "EffectsXmlConfigLoader.cpp",
+ ],
shared_libs: [
"libcutils",
"liblog",
"libdl",
+ "libeffectsconfig",
],
-
- include_dirs: ["system/media/audio_effects/include"],
+ cflags: ["-fvisibility=hidden"],
local_include_dirs:["include/media"],
- header_libs: ["libeffects_headers"],
+ header_libs: [
+ "libaudioeffects",
+ "libeffects_headers",
+ ],
export_header_lib_headers: ["libeffects_headers"],
}
+
+cc_binary {
+ name: "dumpEffectConfigFile",
+ vendor: true,
+ srcs: ["test/DumpConfig.cpp"],
+
+ compile_multilib: "32",
+
+ cflags: [
+ "-Wall",
+ "-Wextra",
+ "-Werror",
+ ],
+
+
+ shared_libs: [
+ "libeffectsconfig",
+ "libeffects",
+ ],
+ local_include_dirs:[".", "include"],
+}
diff --git a/media/libeffects/factory/EffectsConfigLoader.c b/media/libeffects/factory/EffectsConfigLoader.c
new file mode 100644
index 0000000..fcef36f
--- /dev/null
+++ b/media/libeffects/factory/EffectsConfigLoader.c
@@ -0,0 +1,439 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "EffectsFactoryConfigLoader"
+//#define LOG_NDEBUG 0
+
+#include <dlfcn.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <cutils/config_utils.h>
+#include <cutils/misc.h>
+#include <log/log.h>
+
+#include <system/audio_effects/audio_effects_conf.h>
+
+#include "EffectsConfigLoader.h"
+#include "EffectsFactoryState.h"
+
+/////////////////////////////////////////////////
+// Local functions prototypes
+/////////////////////////////////////////////////
+
+static int loadEffectConfigFile(const char *path);
+static int loadLibraries(cnode *root);
+static int loadLibrary(cnode *root, const char *name);
+static int loadEffects(cnode *root);
+static int loadEffect(cnode *node);
+// To get and add the effect pointed by the passed node to the gSubEffectList
+static int addSubEffect(cnode *root);
+static lib_entry_t *getLibrary(const char *path);
+
+static lib_entry_t *gCachedLibrary; // last library accessed by getLibrary()
+
+int EffectLoadEffectConfig()
+{
+ if (access(AUDIO_EFFECT_VENDOR_CONFIG_FILE, R_OK) == 0) {
+ return loadEffectConfigFile(AUDIO_EFFECT_VENDOR_CONFIG_FILE);
+ } else if (access(AUDIO_EFFECT_DEFAULT_CONFIG_FILE, R_OK) == 0) {
+ return loadEffectConfigFile(AUDIO_EFFECT_DEFAULT_CONFIG_FILE);
+ }
+ return 0;
+}
+
+int loadEffectConfigFile(const char *path)
+{
+ cnode *root;
+ char *data;
+
+ data = load_file(path, NULL);
+ if (data == NULL) {
+ return -ENODEV;
+ }
+ root = config_node("", "");
+ config_load(root, data);
+ loadLibraries(root);
+ loadEffects(root);
+ config_free(root);
+ free(root);
+ free(data);
+
+ return 0;
+}
+
+int loadLibraries(cnode *root)
+{
+ cnode *node;
+
+ node = config_find(root, LIBRARIES_TAG);
+ if (node == NULL) {
+ return -ENOENT;
+ }
+ node = node->first_child;
+ while (node) {
+ loadLibrary(node, node->name);
+ node = node->next;
+ }
+ return 0;
+}
+
+#ifdef __LP64__
+// audio_effects.conf always specifies 32 bit lib path: convert to 64 bit path if needed
+static const char *kLibraryPathRoot[] =
+ {"/odm/lib64/soundfx", "/vendor/lib64/soundfx", "/system/lib64/soundfx"};
+#else
+static const char *kLibraryPathRoot[] =
+ {"/odm/lib/soundfx", "/vendor/lib/soundfx", "/system/lib/soundfx"};
+#endif
+
+static const int kLibraryPathRootSize =
+ (sizeof(kLibraryPathRoot) / sizeof(kLibraryPathRoot[0]));
+
+// Checks if the library path passed as lib_path_in can be opened and if not
+// tries in standard effect library directories with just the library name and returns correct path
+// in lib_path_out
+int checkLibraryPath(const char *lib_path_in, char *lib_path_out) {
+ char *str;
+ const char *lib_name;
+ size_t len;
+
+ if (lib_path_in == NULL || lib_path_out == NULL) {
+ return -EINVAL;
+ }
+
+ strlcpy(lib_path_out, lib_path_in, PATH_MAX);
+
+ // Try exact path first
+ str = strstr(lib_path_out, "/lib/soundfx/");
+ if (str == NULL) {
+ return -EINVAL;
+ }
+
+ // Extract library name from input path
+ len = str - lib_path_out;
+ lib_name = lib_path_in + len + strlen("/lib/soundfx/");
+
+ // Then try with library name and standard path names in order of preference
+ for (int i = 0; i < kLibraryPathRootSize; i++) {
+ char path[PATH_MAX];
+
+ snprintf(path,
+ PATH_MAX,
+ "%s/%s",
+ kLibraryPathRoot[i],
+ lib_name);
+ if (F_OK == access(path, 0)) {
+ strcpy(lib_path_out, path);
+ ALOGW_IF(strncmp(lib_path_out, lib_path_in, PATH_MAX) != 0,
+ "checkLibraryPath() corrected library path %s to %s", lib_path_in, lib_path_out);
+ return 0;
+ }
+ }
+ return -EINVAL;
+}
+
+
+
+int loadLibrary(cnode *root, const char *name)
+{
+ cnode *node;
+ void *hdl = NULL;
+ audio_effect_library_t *desc;
+ list_elem_t *e;
+ lib_entry_t *l;
+ char path[PATH_MAX];
+
+ node = config_find(root, PATH_TAG);
+ if (node == NULL) {
+ return -EINVAL;
+ }
+
+ if (checkLibraryPath((const char *)node->value, path) != 0) {
+ ALOGW("loadLibrary() could not find library %s", path);
+ goto error;
+ }
+
+ hdl = dlopen(path, RTLD_NOW);
+ if (hdl == NULL) {
+ ALOGW("loadLibrary() failed to open %s", path);
+ goto error;
+ }
+
+ desc = (audio_effect_library_t *)dlsym(hdl, AUDIO_EFFECT_LIBRARY_INFO_SYM_AS_STR);
+ if (desc == NULL) {
+ ALOGW("loadLibrary() could not find symbol %s", AUDIO_EFFECT_LIBRARY_INFO_SYM_AS_STR);
+ goto error;
+ }
+
+ if (AUDIO_EFFECT_LIBRARY_TAG != desc->tag) {
+ ALOGW("getLibrary() bad tag %08x in lib info struct", desc->tag);
+ goto error;
+ }
+
+ if (EFFECT_API_VERSION_MAJOR(desc->version) !=
+ EFFECT_API_VERSION_MAJOR(EFFECT_LIBRARY_API_VERSION)) {
+ ALOGW("loadLibrary() bad lib version %08x", desc->version);
+ goto error;
+ }
+
+ // add entry for library in gLibraryList
+ l = malloc(sizeof(lib_entry_t));
+ l->name = strndup(name, PATH_MAX);
+ l->path = strndup(path, PATH_MAX);
+ l->handle = hdl;
+ l->desc = desc;
+ l->effects = NULL;
+ pthread_mutex_init(&l->lock, NULL);
+
+ e = malloc(sizeof(list_elem_t));
+ e->object = l;
+ pthread_mutex_lock(&gLibLock);
+ e->next = gLibraryList;
+ gLibraryList = e;
+ pthread_mutex_unlock(&gLibLock);
+ ALOGV("getLibrary() linked library %p for path %s", l, path);
+
+ return 0;
+
+error:
+ if (hdl != NULL) {
+ dlclose(hdl);
+ }
+ //add entry for library errors in gLibraryFailedList
+ lib_failed_entry_t *fl = malloc(sizeof(lib_failed_entry_t));
+ fl->name = strndup(name, PATH_MAX);
+ fl->path = strndup(path, PATH_MAX);
+
+ list_elem_t *fe = malloc(sizeof(list_elem_t));
+ fe->object = fl;
+ fe->next = gLibraryFailedList;
+ gLibraryFailedList = fe;
+ ALOGV("getLibrary() linked error in library %p for path %s", fl, path);
+
+ return -EINVAL;
+}
+
+// This will find the library and UUID tags of the sub effect pointed by the
+// node, gets the effect descriptor and lib_entry_t and adds the subeffect -
+// sub_entry_t to the gSubEffectList
+int addSubEffect(cnode *root)
+{
+ ALOGV("addSubEffect");
+ cnode *node;
+ effect_uuid_t uuid;
+ effect_descriptor_t *d;
+ lib_entry_t *l;
+ list_elem_t *e;
+ node = config_find(root, LIBRARY_TAG);
+ if (node == NULL) {
+ return -EINVAL;
+ }
+ l = getLibrary(node->value);
+ if (l == NULL) {
+ ALOGW("addSubEffect() could not get library %s", node->value);
+ return -EINVAL;
+ }
+ node = config_find(root, UUID_TAG);
+ if (node == NULL) {
+ return -EINVAL;
+ }
+ if (stringToUuid(node->value, &uuid) != 0) {
+ ALOGW("addSubEffect() invalid uuid %s", node->value);
+ return -EINVAL;
+ }
+ d = malloc(sizeof(effect_descriptor_t));
+ if (l->desc->get_descriptor(&uuid, d) != 0) {
+ char s[40];
+ uuidToString(&uuid, s, 40);
+ ALOGW("Error querying effect %s on lib %s", s, l->name);
+ free(d);
+ return -EINVAL;
+ }
+#if (LOG_NDEBUG==0)
+ char s[512];
+ dumpEffectDescriptor(d, s, sizeof(s), 0 /* indent */);
+ ALOGV("addSubEffect() read descriptor %p:%s",d, s);
+#endif
+ if (EFFECT_API_VERSION_MAJOR(d->apiVersion) !=
+ EFFECT_API_VERSION_MAJOR(EFFECT_CONTROL_API_VERSION)) {
+ ALOGW("Bad API version %08x on lib %s", d->apiVersion, l->name);
+ free(d);
+ return -EINVAL;
+ }
+ sub_effect_entry_t *sub_effect = malloc(sizeof(sub_effect_entry_t));
+ sub_effect->object = d;
+ // lib_entry_t is stored since the sub effects are not linked to the library
+ sub_effect->lib = l;
+ e = malloc(sizeof(list_elem_t));
+ e->object = sub_effect;
+ e->next = gSubEffectList->sub_elem;
+ gSubEffectList->sub_elem = e;
+ ALOGV("addSubEffect end");
+ return 0;
+}
+
+int loadEffects(cnode *root)
+{
+ cnode *node;
+
+ node = config_find(root, EFFECTS_TAG);
+ if (node == NULL) {
+ return -ENOENT;
+ }
+ node = node->first_child;
+ while (node) {
+ loadEffect(node);
+ node = node->next;
+ }
+ return 0;
+}
+
+int loadEffect(cnode *root)
+{
+ cnode *node;
+ effect_uuid_t uuid;
+ lib_entry_t *l;
+ effect_descriptor_t *d;
+ list_elem_t *e;
+
+ node = config_find(root, LIBRARY_TAG);
+ if (node == NULL) {
+ return -EINVAL;
+ }
+
+ l = getLibrary(node->value);
+ if (l == NULL) {
+ ALOGW("loadEffect() could not get library %s", node->value);
+ return -EINVAL;
+ }
+
+ node = config_find(root, UUID_TAG);
+ if (node == NULL) {
+ return -EINVAL;
+ }
+ if (stringToUuid(node->value, &uuid) != 0) {
+ ALOGW("loadEffect() invalid uuid %s", node->value);
+ return -EINVAL;
+ }
+ lib_entry_t *tmp;
+ bool skip = false;
+ if (findEffect(NULL, &uuid, &tmp, NULL) == 0) {
+ ALOGW("skipping duplicate uuid %s %s", node->value,
+ node->next ? "and its sub-effects" : "");
+ skip = true;
+ }
+
+ d = malloc(sizeof(effect_descriptor_t));
+ if (l->desc->get_descriptor(&uuid, d) != 0) {
+ char s[40];
+ uuidToString(&uuid, s, 40);
+ ALOGW("Error querying effect %s on lib %s", s, l->name);
+ free(d);
+ return -EINVAL;
+ }
+#if (LOG_NDEBUG==0)
+ char s[512];
+ dumpEffectDescriptor(d, s, sizeof(s), 0 /* indent */);
+ ALOGV("loadEffect() read descriptor %p:%s",d, s);
+#endif
+ if (EFFECT_API_VERSION_MAJOR(d->apiVersion) !=
+ EFFECT_API_VERSION_MAJOR(EFFECT_CONTROL_API_VERSION)) {
+ ALOGW("Bad API version %08x on lib %s", d->apiVersion, l->name);
+ free(d);
+ return -EINVAL;
+ }
+ e = malloc(sizeof(list_elem_t));
+ e->object = d;
+ if (skip) {
+ e->next = gSkippedEffects;
+ gSkippedEffects = e;
+ return -EINVAL;
+ } else {
+ e->next = l->effects;
+ l->effects = e;
+ }
+
+ // After the UUID node in the config_tree, if node->next is valid,
+ // that would be sub effect node.
+ // Find the sub effects and add them to the gSubEffectList
+ node = node->next;
+ int count = 2;
+ bool hwSubefx = false, swSubefx = false;
+ list_sub_elem_t *sube = NULL;
+ if (node != NULL) {
+ ALOGV("Adding the effect to gEffectSubList as there are sub effects");
+ sube = malloc(sizeof(list_sub_elem_t));
+ sube->object = d;
+ sube->sub_elem = NULL;
+ sube->next = gSubEffectList;
+ gSubEffectList = sube;
+ }
+ while (node != NULL && count) {
+ if (addSubEffect(node)) {
+ ALOGW("loadEffect() could not add subEffect %s", node->value);
+ // Change the gSubEffectList to point to older list;
+ gSubEffectList = sube->next;
+ free(sube->sub_elem);// Free an already added sub effect
+ sube->sub_elem = NULL;
+ free(sube);
+ return -ENOENT;
+ }
+ sub_effect_entry_t *subEntry = (sub_effect_entry_t*)gSubEffectList->sub_elem->object;
+ effect_descriptor_t *subEffectDesc = (effect_descriptor_t*)(subEntry->object);
+ // Since we return a dummy descriptor for the proxy during
+ // get_descriptor call,we replace it with the correspoding
+ // sw effect descriptor, but with Proxy UUID
+ // check for Sw desc
+ if (!((subEffectDesc->flags & EFFECT_FLAG_HW_ACC_MASK) ==
+ EFFECT_FLAG_HW_ACC_TUNNEL)) {
+ swSubefx = true;
+ *d = *subEffectDesc;
+ d->uuid = uuid;
+ ALOGV("loadEffect() Changed the Proxy desc");
+ } else
+ hwSubefx = true;
+ count--;
+ node = node->next;
+ }
+ // 1 HW and 1 SW sub effect found. Set the offload flag in the Proxy desc
+ if (hwSubefx && swSubefx) {
+ d->flags |= EFFECT_FLAG_OFFLOAD_SUPPORTED;
+ }
+ return 0;
+}
+
+lib_entry_t *getLibrary(const char *name)
+{
+ list_elem_t *e;
+
+ if (gCachedLibrary &&
+ !strncmp(gCachedLibrary->name, name, PATH_MAX)) {
+ return gCachedLibrary;
+ }
+
+ e = gLibraryList;
+ while (e) {
+ lib_entry_t *l = (lib_entry_t *)e->object;
+ if (!strcmp(l->name, name)) {
+ gCachedLibrary = l;
+ return l;
+ }
+ e = e->next;
+ }
+
+ return NULL;
+}
diff --git a/media/libeffects/factory/EffectsConfigLoader.h b/media/libeffects/factory/EffectsConfigLoader.h
new file mode 100644
index 0000000..3f82609
--- /dev/null
+++ b/media/libeffects/factory/EffectsConfigLoader.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_EFFECTSCONFIGLOADER_H
+#define ANDROID_EFFECTSCONFIGLOADER_H
+
+#include <cutils/compiler.h>
+#include "EffectsFactoryState.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** Parses the platform effect configuration
+ * and stores its content in the global EffectFactoryState. */
+ANDROID_API
+int EffectLoadEffectConfig();
+
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // ANDROID_EFFECTSCONFIGLOADER_H
diff --git a/media/libeffects/factory/EffectsFactory.c b/media/libeffects/factory/EffectsFactory.c
index 37c0bb7..cd0e765 100644
--- a/media/libeffects/factory/EffectsFactory.c
+++ b/media/libeffects/factory/EffectsFactory.c
@@ -17,65 +17,46 @@
#define LOG_TAG "EffectsFactory"
//#define LOG_NDEBUG 0
-#include "EffectsFactory.h"
-
-#include <dlfcn.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
-#include <cutils/config_utils.h>
-#include <cutils/misc.h>
#include <cutils/properties.h>
#include <log/log.h>
-#include <system/audio_effects/audio_effects_conf.h>
+#include <media/EffectsFactoryApi.h>
+
+#include "EffectsConfigLoader.h"
+#include "EffectsFactoryState.h"
+#include "EffectsXmlConfigLoader.h"
+
+#include "EffectsFactory.h"
static list_elem_t *gEffectList; // list of effect_entry_t: all currently created effects
-static list_elem_t *gLibraryList; // list of lib_entry_t: all currently loaded libraries
-static list_elem_t *gSkippedEffects; // list of effects skipped because of duplicate uuid
-// list of effect_descriptor and list of sub effects : all currently loaded
-// It does not contain effects without sub effects.
-static list_sub_elem_t *gSubEffectList;
-static pthread_mutex_t gLibLock = PTHREAD_MUTEX_INITIALIZER; // controls access to gLibraryList
static uint32_t gNumEffects; // total number number of effects
static list_elem_t *gCurLib; // current library in enumeration process
static list_elem_t *gCurEffect; // current effect in enumeration process
static uint32_t gCurEffectIdx; // current effect index in enumeration process
-static lib_entry_t *gCachedLibrary; // last library accessed by getLibrary()
+/** Number of elements skipped during the effects configuration loading.
+ * -1 if the config loader failed
+ * -2 if config load was skipped
+ */
+static ssize_t gConfigNbElemSkipped = -2;
static int gInitDone; // true is global initialization has been preformed
static int gCanQueryEffect; // indicates that call to EffectQueryEffect() is valid, i.e. that the list of effects
// was not modified since last call to EffectQueryNumberEffects()
-
-static list_elem_t *gLibraryFailedList; //list of lib_failed_entry_t: libraries failed to load
-
/////////////////////////////////////////////////
// Local functions prototypes
/////////////////////////////////////////////////
static int init();
-static int loadEffectConfigFile(const char *path);
-static int loadLibraries(cnode *root);
-static int loadLibrary(cnode *root, const char *name);
-static int loadEffects(cnode *root);
-static int loadEffect(cnode *node);
-// To get and add the effect pointed by the passed node to the gSubEffectList
-static int addSubEffect(cnode *root);
-static lib_entry_t *getLibrary(const char *path);
static void resetEffectEnumeration();
static uint32_t updateNumEffects();
-static int findEffect(const effect_uuid_t *type,
- const effect_uuid_t *uuid,
- lib_entry_t **lib,
- effect_descriptor_t **desc);
// To search a subeffect in the gSubEffectList
static int findSubEffect(const effect_uuid_t *uuid,
lib_entry_t **lib,
effect_descriptor_t **desc);
-static void dumpEffectDescriptor(effect_descriptor_t *desc, char *str, size_t len, int indent);
-static int stringToUuid(const char *str, effect_uuid_t *uuid);
-static int uuidToString(const effect_uuid_t *uuid, char *str, size_t maxLen);
/////////////////////////////////////////////////
// Effect Control Interface functions
@@ -461,10 +442,12 @@
if (ignoreFxConfFiles) {
ALOGI("Audio effects in configuration files will be ignored");
} else {
- if (access(AUDIO_EFFECT_VENDOR_CONFIG_FILE, R_OK) == 0) {
- loadEffectConfigFile(AUDIO_EFFECT_VENDOR_CONFIG_FILE);
- } else if (access(AUDIO_EFFECT_DEFAULT_CONFIG_FILE, R_OK) == 0) {
- loadEffectConfigFile(AUDIO_EFFECT_DEFAULT_CONFIG_FILE);
+ gConfigNbElemSkipped = EffectLoadXmlEffectConfig(NULL);
+ if (gConfigNbElemSkipped < 0) {
+ ALOGW("Failed to load XML effect configuration, fallback to .conf");
+ EffectLoadEffectConfig();
+ } else if (gConfigNbElemSkipped > 0) {
+ ALOGE("Effect config is partially invalid, skipped %zd elements", gConfigNbElemSkipped);
}
}
@@ -474,367 +457,6 @@
return 0;
}
-int loadEffectConfigFile(const char *path)
-{
- cnode *root;
- char *data;
-
- data = load_file(path, NULL);
- if (data == NULL) {
- return -ENODEV;
- }
- root = config_node("", "");
- config_load(root, data);
- loadLibraries(root);
- loadEffects(root);
- config_free(root);
- free(root);
- free(data);
-
- return 0;
-}
-
-int loadLibraries(cnode *root)
-{
- cnode *node;
-
- node = config_find(root, LIBRARIES_TAG);
- if (node == NULL) {
- return -ENOENT;
- }
- node = node->first_child;
- while (node) {
- loadLibrary(node, node->name);
- node = node->next;
- }
- return 0;
-}
-
-#ifdef __LP64__
-// audio_effects.conf always specifies 32 bit lib path: convert to 64 bit path if needed
-static const char *kLibraryPathRoot[] =
- {"/odm/lib64/soundfx", "/vendor/lib64/soundfx", "/system/lib64/soundfx"};
-#else
-static const char *kLibraryPathRoot[] =
- {"/odm/lib/soundfx", "/vendor/lib/soundfx", "/system/lib/soundfx"};
-#endif
-
-static const int kLibraryPathRootSize =
- (sizeof(kLibraryPathRoot) / sizeof(kLibraryPathRoot[0]));
-
-// Checks if the library path passed as lib_path_in can be opened and if not
-// tries in standard effect library directories with just the library name and returns correct path
-// in lib_path_out
-int checkLibraryPath(const char *lib_path_in, char *lib_path_out) {
- char *str;
- const char *lib_name;
- size_t len;
-
- if (lib_path_in == NULL || lib_path_out == NULL) {
- return -EINVAL;
- }
-
- strlcpy(lib_path_out, lib_path_in, PATH_MAX);
-
- // Try exact path first
- str = strstr(lib_path_out, "/lib/soundfx/");
- if (str == NULL) {
- return -EINVAL;
- }
-
- // Extract library name from input path
- len = str - lib_path_out;
- lib_name = lib_path_in + len + strlen("/lib/soundfx/");
-
- // Then try with library name and standard path names in order of preference
- for (int i = 0; i < kLibraryPathRootSize; i++) {
- char path[PATH_MAX];
-
- snprintf(path,
- PATH_MAX,
- "%s/%s",
- kLibraryPathRoot[i],
- lib_name);
- if (F_OK == access(path, 0)) {
- strcpy(lib_path_out, path);
- ALOGW_IF(strncmp(lib_path_out, lib_path_in, PATH_MAX) != 0,
- "checkLibraryPath() corrected library path %s to %s", lib_path_in, lib_path_out);
- return 0;
- }
- }
- return -EINVAL;
-}
-
-
-
-int loadLibrary(cnode *root, const char *name)
-{
- cnode *node;
- void *hdl = NULL;
- audio_effect_library_t *desc;
- list_elem_t *e;
- lib_entry_t *l;
- char path[PATH_MAX];
-
- node = config_find(root, PATH_TAG);
- if (node == NULL) {
- return -EINVAL;
- }
-
- if (checkLibraryPath((const char *)node->value, path) != 0) {
- ALOGW("loadLibrary() could not find library %s", path);
- goto error;
- }
-
- hdl = dlopen(path, RTLD_NOW);
- if (hdl == NULL) {
- ALOGW("loadLibrary() failed to open %s", path);
- goto error;
- }
-
- desc = (audio_effect_library_t *)dlsym(hdl, AUDIO_EFFECT_LIBRARY_INFO_SYM_AS_STR);
- if (desc == NULL) {
- ALOGW("loadLibrary() could not find symbol %s", AUDIO_EFFECT_LIBRARY_INFO_SYM_AS_STR);
- goto error;
- }
-
- if (AUDIO_EFFECT_LIBRARY_TAG != desc->tag) {
- ALOGW("getLibrary() bad tag %08x in lib info struct", desc->tag);
- goto error;
- }
-
- if (EFFECT_API_VERSION_MAJOR(desc->version) !=
- EFFECT_API_VERSION_MAJOR(EFFECT_LIBRARY_API_VERSION)) {
- ALOGW("loadLibrary() bad lib version %08x", desc->version);
- goto error;
- }
-
- // add entry for library in gLibraryList
- l = malloc(sizeof(lib_entry_t));
- l->name = strndup(name, PATH_MAX);
- l->path = strndup(path, PATH_MAX);
- l->handle = hdl;
- l->desc = desc;
- l->effects = NULL;
- pthread_mutex_init(&l->lock, NULL);
-
- e = malloc(sizeof(list_elem_t));
- e->object = l;
- pthread_mutex_lock(&gLibLock);
- e->next = gLibraryList;
- gLibraryList = e;
- pthread_mutex_unlock(&gLibLock);
- ALOGV("getLibrary() linked library %p for path %s", l, path);
-
- return 0;
-
-error:
- if (hdl != NULL) {
- dlclose(hdl);
- }
- //add entry for library errors in gLibraryFailedList
- lib_failed_entry_t *fl = malloc(sizeof(lib_failed_entry_t));
- fl->name = strndup(name, PATH_MAX);
- fl->path = strndup(path, PATH_MAX);
-
- list_elem_t *fe = malloc(sizeof(list_elem_t));
- fe->object = fl;
- fe->next = gLibraryFailedList;
- gLibraryFailedList = fe;
- ALOGV("getLibrary() linked error in library %p for path %s", fl, path);
-
- return -EINVAL;
-}
-
-// This will find the library and UUID tags of the sub effect pointed by the
-// node, gets the effect descriptor and lib_entry_t and adds the subeffect -
-// sub_entry_t to the gSubEffectList
-int addSubEffect(cnode *root)
-{
- ALOGV("addSubEffect");
- cnode *node;
- effect_uuid_t uuid;
- effect_descriptor_t *d;
- lib_entry_t *l;
- list_elem_t *e;
- node = config_find(root, LIBRARY_TAG);
- if (node == NULL) {
- return -EINVAL;
- }
- l = getLibrary(node->value);
- if (l == NULL) {
- ALOGW("addSubEffect() could not get library %s", node->value);
- return -EINVAL;
- }
- node = config_find(root, UUID_TAG);
- if (node == NULL) {
- return -EINVAL;
- }
- if (stringToUuid(node->value, &uuid) != 0) {
- ALOGW("addSubEffect() invalid uuid %s", node->value);
- return -EINVAL;
- }
- d = malloc(sizeof(effect_descriptor_t));
- if (l->desc->get_descriptor(&uuid, d) != 0) {
- char s[40];
- uuidToString(&uuid, s, 40);
- ALOGW("Error querying effect %s on lib %s", s, l->name);
- free(d);
- return -EINVAL;
- }
-#if (LOG_NDEBUG==0)
- char s[512];
- dumpEffectDescriptor(d, s, sizeof(s), 0 /* indent */);
- ALOGV("addSubEffect() read descriptor %p:%s",d, s);
-#endif
- if (EFFECT_API_VERSION_MAJOR(d->apiVersion) !=
- EFFECT_API_VERSION_MAJOR(EFFECT_CONTROL_API_VERSION)) {
- ALOGW("Bad API version %08x on lib %s", d->apiVersion, l->name);
- free(d);
- return -EINVAL;
- }
- sub_effect_entry_t *sub_effect = malloc(sizeof(sub_effect_entry_t));
- sub_effect->object = d;
- // lib_entry_t is stored since the sub effects are not linked to the library
- sub_effect->lib = l;
- e = malloc(sizeof(list_elem_t));
- e->object = sub_effect;
- e->next = gSubEffectList->sub_elem;
- gSubEffectList->sub_elem = e;
- ALOGV("addSubEffect end");
- return 0;
-}
-
-int loadEffects(cnode *root)
-{
- cnode *node;
-
- node = config_find(root, EFFECTS_TAG);
- if (node == NULL) {
- return -ENOENT;
- }
- node = node->first_child;
- while (node) {
- loadEffect(node);
- node = node->next;
- }
- return 0;
-}
-
-int loadEffect(cnode *root)
-{
- cnode *node;
- effect_uuid_t uuid;
- lib_entry_t *l;
- effect_descriptor_t *d;
- list_elem_t *e;
-
- node = config_find(root, LIBRARY_TAG);
- if (node == NULL) {
- return -EINVAL;
- }
-
- l = getLibrary(node->value);
- if (l == NULL) {
- ALOGW("loadEffect() could not get library %s", node->value);
- return -EINVAL;
- }
-
- node = config_find(root, UUID_TAG);
- if (node == NULL) {
- return -EINVAL;
- }
- if (stringToUuid(node->value, &uuid) != 0) {
- ALOGW("loadEffect() invalid uuid %s", node->value);
- return -EINVAL;
- }
- lib_entry_t *tmp;
- bool skip = false;
- if (findEffect(NULL, &uuid, &tmp, NULL) == 0) {
- ALOGW("skipping duplicate uuid %s %s", node->value,
- node->next ? "and its sub-effects" : "");
- skip = true;
- }
-
- d = malloc(sizeof(effect_descriptor_t));
- if (l->desc->get_descriptor(&uuid, d) != 0) {
- char s[40];
- uuidToString(&uuid, s, 40);
- ALOGW("Error querying effect %s on lib %s", s, l->name);
- free(d);
- return -EINVAL;
- }
-#if (LOG_NDEBUG==0)
- char s[512];
- dumpEffectDescriptor(d, s, sizeof(s), 0 /* indent */);
- ALOGV("loadEffect() read descriptor %p:%s",d, s);
-#endif
- if (EFFECT_API_VERSION_MAJOR(d->apiVersion) !=
- EFFECT_API_VERSION_MAJOR(EFFECT_CONTROL_API_VERSION)) {
- ALOGW("Bad API version %08x on lib %s", d->apiVersion, l->name);
- free(d);
- return -EINVAL;
- }
- e = malloc(sizeof(list_elem_t));
- e->object = d;
- if (skip) {
- e->next = gSkippedEffects;
- gSkippedEffects = e;
- return -EINVAL;
- } else {
- e->next = l->effects;
- l->effects = e;
- }
-
- // After the UUID node in the config_tree, if node->next is valid,
- // that would be sub effect node.
- // Find the sub effects and add them to the gSubEffectList
- node = node->next;
- int count = 2;
- bool hwSubefx = false, swSubefx = false;
- list_sub_elem_t *sube = NULL;
- if (node != NULL) {
- ALOGV("Adding the effect to gEffectSubList as there are sub effects");
- sube = malloc(sizeof(list_sub_elem_t));
- sube->object = d;
- sube->sub_elem = NULL;
- sube->next = gSubEffectList;
- gSubEffectList = sube;
- }
- while (node != NULL && count) {
- if (addSubEffect(node)) {
- ALOGW("loadEffect() could not add subEffect %s", node->value);
- // Change the gSubEffectList to point to older list;
- gSubEffectList = sube->next;
- free(sube->sub_elem);// Free an already added sub effect
- sube->sub_elem = NULL;
- free(sube);
- return -ENOENT;
- }
- sub_effect_entry_t *subEntry = (sub_effect_entry_t*)gSubEffectList->sub_elem->object;
- effect_descriptor_t *subEffectDesc = (effect_descriptor_t*)(subEntry->object);
- // Since we return a dummy descriptor for the proxy during
- // get_descriptor call,we replace it with the correspoding
- // sw effect descriptor, but with Proxy UUID
- // check for Sw desc
- if (!((subEffectDesc->flags & EFFECT_FLAG_HW_ACC_MASK) ==
- EFFECT_FLAG_HW_ACC_TUNNEL)) {
- swSubefx = true;
- *d = *subEffectDesc;
- d->uuid = uuid;
- ALOGV("loadEffect() Changed the Proxy desc");
- } else
- hwSubefx = true;
- count--;
- node = node->next;
- }
- // 1 HW and 1 SW sub effect found. Set the offload flag in the Proxy desc
- if (hwSubefx && swSubefx) {
- d->flags |= EFFECT_FLAG_OFFLOAD_SUPPORTED;
- }
- return 0;
-}
-
// Searches the sub effect matching to the specified uuid
// in the gSubEffectList. It gets the lib_entry_t for
// the matched sub_effect . Used in EffectCreate of sub effects
@@ -881,29 +503,6 @@
return ret;
}
-lib_entry_t *getLibrary(const char *name)
-{
- list_elem_t *e;
-
- if (gCachedLibrary &&
- !strncmp(gCachedLibrary->name, name, PATH_MAX)) {
- return gCachedLibrary;
- }
-
- e = gLibraryList;
- while (e) {
- lib_entry_t *l = (lib_entry_t *)e->object;
- if (!strcmp(l->name, name)) {
- gCachedLibrary = l;
- return l;
- }
- e = e->next;
- }
-
- return NULL;
-}
-
-
void resetEffectEnumeration()
{
gCurLib = gLibraryList;
@@ -935,114 +534,6 @@
return cnt;
}
-int findEffect(const effect_uuid_t *type,
- const effect_uuid_t *uuid,
- lib_entry_t **lib,
- effect_descriptor_t **desc)
-{
- list_elem_t *e = gLibraryList;
- lib_entry_t *l = NULL;
- effect_descriptor_t *d = NULL;
- int found = 0;
- int ret = 0;
-
- while (e && !found) {
- l = (lib_entry_t *)e->object;
- list_elem_t *efx = l->effects;
- while (efx) {
- d = (effect_descriptor_t *)efx->object;
- if (type != NULL && memcmp(&d->type, type, sizeof(effect_uuid_t)) == 0) {
- found = 1;
- break;
- }
- if (uuid != NULL && memcmp(&d->uuid, uuid, sizeof(effect_uuid_t)) == 0) {
- found = 1;
- break;
- }
- efx = efx->next;
- }
- e = e->next;
- }
- if (!found) {
- ALOGV("findEffect() effect not found");
- ret = -ENOENT;
- } else {
- ALOGV("findEffect() found effect: %s in lib %s", d->name, l->name);
- *lib = l;
- if (desc) {
- *desc = d;
- }
- }
-
- return ret;
-}
-
-void dumpEffectDescriptor(effect_descriptor_t *desc, char *str, size_t len, int indent) {
- char s[256];
- char ss[256];
- char idt[indent + 1];
-
- memset(idt, ' ', indent);
- idt[indent] = 0;
-
- str[0] = 0;
-
- snprintf(s, sizeof(s), "%s%s / %s\n", idt, desc->name, desc->implementor);
- strlcat(str, s, len);
-
- uuidToString(&desc->uuid, s, sizeof(s));
- snprintf(ss, sizeof(ss), "%s UUID: %s\n", idt, s);
- strlcat(str, ss, len);
-
- uuidToString(&desc->type, s, sizeof(s));
- snprintf(ss, sizeof(ss), "%s TYPE: %s\n", idt, s);
- strlcat(str, ss, len);
-
- sprintf(s, "%s apiVersion: %08X\n%s flags: %08X\n", idt,
- desc->apiVersion, idt, desc->flags);
- strlcat(str, s, len);
-}
-
-int stringToUuid(const char *str, effect_uuid_t *uuid)
-{
- int tmp[10];
-
- if (sscanf(str, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x",
- tmp, tmp+1, tmp+2, tmp+3, tmp+4, tmp+5, tmp+6, tmp+7, tmp+8, tmp+9) < 10) {
- return -EINVAL;
- }
- uuid->timeLow = (uint32_t)tmp[0];
- uuid->timeMid = (uint16_t)tmp[1];
- uuid->timeHiAndVersion = (uint16_t)tmp[2];
- uuid->clockSeq = (uint16_t)tmp[3];
- uuid->node[0] = (uint8_t)tmp[4];
- uuid->node[1] = (uint8_t)tmp[5];
- uuid->node[2] = (uint8_t)tmp[6];
- uuid->node[3] = (uint8_t)tmp[7];
- uuid->node[4] = (uint8_t)tmp[8];
- uuid->node[5] = (uint8_t)tmp[9];
-
- return 0;
-}
-
-int uuidToString(const effect_uuid_t *uuid, char *str, size_t maxLen)
-{
-
- snprintf(str, maxLen, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x",
- uuid->timeLow,
- uuid->timeMid,
- uuid->timeHiAndVersion,
- uuid->clockSeq,
- uuid->node[0],
- uuid->node[1],
- uuid->node[2],
- uuid->node[3],
- uuid->node[4],
- uuid->node[5]);
-
- return 0;
-}
-
int EffectDumpEffects(int fd) {
char s[512];
@@ -1092,6 +583,20 @@
e = e->next;
}
}
+ switch (gConfigNbElemSkipped) {
+ case -2:
+ dprintf(fd, "Effect configuration loading skipped.\n");
+ break;
+ case -1:
+ dprintf(fd, "XML effect configuration failed to load.\n");
+ break;
+ case 0:
+ dprintf(fd, "XML effect configuration loaded successfully.\n");
+ break;
+ default:
+ dprintf(fd, "XML effect configuration partially loaded, skipped %zd elements.\n",
+ gConfigNbElemSkipped);
+ }
return ret;
}
diff --git a/media/libeffects/factory/EffectsFactory.h b/media/libeffects/factory/EffectsFactory.h
index 72e0931..29dbc9c 100644
--- a/media/libeffects/factory/EffectsFactory.h
+++ b/media/libeffects/factory/EffectsFactory.h
@@ -20,7 +20,7 @@
#include <dirent.h>
#include <pthread.h>
-#include <android/log.h>
+#include <cutils/compiler.h>
#include <hardware/audio_effect.h>
#if __cplusplus
@@ -96,6 +96,7 @@
// *pDescriptor: updated with the sub effect descriptors.
//
////////////////////////////////////////////////////////////////////////////////
+ANDROID_API
int EffectGetSubEffects(const effect_uuid_t *pEffectUuid,
sub_effect_entry_t **pSube,
size_t size);
diff --git a/media/libeffects/factory/EffectsFactoryState.c b/media/libeffects/factory/EffectsFactoryState.c
new file mode 100644
index 0000000..b364004
--- /dev/null
+++ b/media/libeffects/factory/EffectsFactoryState.c
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "EffectsFactoryState"
+
+#include "EffectsFactoryState.h"
+
+#include "log/log.h"
+
+list_elem_t *gLibraryList;
+list_elem_t *gSkippedEffects;
+list_sub_elem_t *gSubEffectList;
+pthread_mutex_t gLibLock = PTHREAD_MUTEX_INITIALIZER;
+
+list_elem_t *gLibraryFailedList; //list of lib_failed_entry_t: libraries failed to load
+
+
+int findEffect(const effect_uuid_t *type,
+ const effect_uuid_t *uuid,
+ lib_entry_t **lib,
+ effect_descriptor_t **desc)
+{
+ list_elem_t *e = gLibraryList;
+ lib_entry_t *l = NULL;
+ effect_descriptor_t *d = NULL;
+ int found = 0;
+ int ret = 0;
+
+ while (e && !found) {
+ l = (lib_entry_t *)e->object;
+ list_elem_t *efx = l->effects;
+ while (efx) {
+ d = (effect_descriptor_t *)efx->object;
+ if (type != NULL && memcmp(&d->type, type, sizeof(effect_uuid_t)) == 0) {
+ found = 1;
+ break;
+ }
+ if (uuid != NULL && memcmp(&d->uuid, uuid, sizeof(effect_uuid_t)) == 0) {
+ found = 1;
+ break;
+ }
+ efx = efx->next;
+ }
+ e = e->next;
+ }
+ if (!found) {
+ ALOGV("findEffect() effect not found");
+ ret = -ENOENT;
+ } else {
+ ALOGV("findEffect() found effect: %s in lib %s", d->name, l->name);
+ *lib = l;
+ if (desc) {
+ *desc = d;
+ }
+ }
+
+ return ret;
+}
+
+int stringToUuid(const char *str, effect_uuid_t *uuid)
+{
+ int tmp[10];
+
+ if (sscanf(str, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x",
+ tmp, tmp+1, tmp+2, tmp+3, tmp+4, tmp+5, tmp+6, tmp+7, tmp+8, tmp+9) < 10) {
+ return -EINVAL;
+ }
+ uuid->timeLow = (uint32_t)tmp[0];
+ uuid->timeMid = (uint16_t)tmp[1];
+ uuid->timeHiAndVersion = (uint16_t)tmp[2];
+ uuid->clockSeq = (uint16_t)tmp[3];
+ uuid->node[0] = (uint8_t)tmp[4];
+ uuid->node[1] = (uint8_t)tmp[5];
+ uuid->node[2] = (uint8_t)tmp[6];
+ uuid->node[3] = (uint8_t)tmp[7];
+ uuid->node[4] = (uint8_t)tmp[8];
+ uuid->node[5] = (uint8_t)tmp[9];
+
+ return 0;
+}
+
+int uuidToString(const effect_uuid_t *uuid, char *str, size_t maxLen)
+{
+
+ snprintf(str, maxLen, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x",
+ uuid->timeLow,
+ uuid->timeMid,
+ uuid->timeHiAndVersion,
+ uuid->clockSeq,
+ uuid->node[0],
+ uuid->node[1],
+ uuid->node[2],
+ uuid->node[3],
+ uuid->node[4],
+ uuid->node[5]);
+
+ return 0;
+}
+
+
+void dumpEffectDescriptor(effect_descriptor_t *desc, char *str, size_t len, int indent) {
+ char s[256];
+ char ss[256];
+ char idt[indent + 1];
+
+ memset(idt, ' ', indent);
+ idt[indent] = 0;
+
+ str[0] = 0;
+
+ snprintf(s, sizeof(s), "%s%s / %s\n", idt, desc->name, desc->implementor);
+ strlcat(str, s, len);
+
+ uuidToString(&desc->uuid, s, sizeof(s));
+ snprintf(ss, sizeof(ss), "%s UUID: %s\n", idt, s);
+ strlcat(str, ss, len);
+
+ uuidToString(&desc->type, s, sizeof(s));
+ snprintf(ss, sizeof(ss), "%s TYPE: %s\n", idt, s);
+ strlcat(str, ss, len);
+
+ sprintf(s, "%s apiVersion: %08X\n%s flags: %08X\n", idt,
+ desc->apiVersion, idt, desc->flags);
+ strlcat(str, s, len);
+}
diff --git a/media/libeffects/factory/EffectsFactoryState.h b/media/libeffects/factory/EffectsFactoryState.h
new file mode 100644
index 0000000..aef945e
--- /dev/null
+++ b/media/libeffects/factory/EffectsFactoryState.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_EFFECTSFACTORYSTATE_H_
+#define ANDROID_EFFECTSFACTORYSTATE_H_
+
+#include "EffectsFactory.h"
+
+#if __cplusplus
+extern "C" {
+#endif
+
+/** @file Contains the state shared with configuration loader of the Effect factory.
+ * This global state should probably be refactor in a structure
+ * provided by the config loader on EffectsFactory init.
+ * This header also contains some helper functions to work on the state.
+ */
+
+extern list_elem_t *gLibraryList; // list of lib_entry_t: all currently loaded libraries
+// list of effects skipped because of duplicate uuid or invalid version
+extern list_elem_t *gSkippedEffects;
+// list of effect_descriptor and list of sub effects : all currently loaded
+// It does not contain effects without sub effects.
+extern list_sub_elem_t *gSubEffectList;
+extern pthread_mutex_t gLibLock; // controls access to gLibraryList
+
+extern list_elem_t *gLibraryFailedList; //list of lib_failed_entry_t: libraries failed to load
+
+
+
+int findEffect(const effect_uuid_t *type,
+ const effect_uuid_t *uuid,
+ lib_entry_t **lib,
+ effect_descriptor_t **desc);
+
+int stringToUuid(const char *str, effect_uuid_t *uuid);
+/** Used to log UUIDs */
+int uuidToString(const effect_uuid_t *uuid, char *str, size_t maxLen);
+
+/** Used for debuging. */
+void dumpEffectDescriptor(effect_descriptor_t *desc, char *str, size_t len, int indent);
+
+#if __cplusplus
+} // extern "C"
+#endif
+
+#endif // ANDROID_EFFECTSFACTORYSTATE_H_
diff --git a/media/libeffects/factory/EffectsXmlConfigLoader.cpp b/media/libeffects/factory/EffectsXmlConfigLoader.cpp
new file mode 100644
index 0000000..438b787
--- /dev/null
+++ b/media/libeffects/factory/EffectsXmlConfigLoader.cpp
@@ -0,0 +1,335 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "EffectsFactoryConfigLoader"
+//#define LOG_NDEBUG 0
+
+#include <dlfcn.h>
+#include <set>
+#include <stdlib.h>
+#include <string>
+
+#include <log/log.h>
+
+#include <media/EffectsConfig.h>
+
+#include "EffectsConfigLoader.h"
+#include "EffectsFactoryState.h"
+#include "EffectsXmlConfigLoader.h"
+
+namespace android {
+
+using namespace effectsConfig;
+
+/////////////////////////////////////////////////
+// Local functions
+/////////////////////////////////////////////////
+
+namespace {
+
+/** Similarly to dlopen, looks for the provided path in LD_EFFECT_LIBRARY_PATH.
+ * @return true if the library is found and set resolvedPath to its absolute path.
+ * false if not found
+ */
+bool resolveLibrary(const std::string& path, std::string* resolvedPath) {
+ for (auto* libraryDirectory : LD_EFFECT_LIBRARY_PATH) {
+ std::string candidatePath = std::string(libraryDirectory) + '/' + path;
+ if (access(candidatePath.c_str(), R_OK) == 0) {
+ *resolvedPath = std::move(candidatePath);
+ return true;
+ }
+ }
+ return false;
+}
+
+/** Loads a library given its relative path and stores the result in libEntry.
+ * @return true on success with libEntry's path, handle and desc filled
+ * false on success with libEntry's path filled with the path of the failed lib
+ * The caller MUST free the resources path (free) and handle (dlclose) if filled.
+ */
+bool loadLibrary(const char* relativePath, lib_entry_t* libEntry) noexcept {
+
+ std::string absolutePath;
+ if (!resolveLibrary(relativePath, &absolutePath)) {
+ ALOGE("Could not find library in effect directories: %s", relativePath);
+ libEntry->path = strdup(relativePath);
+ return false;
+ }
+ const char* path = absolutePath.c_str();
+ libEntry->path = strdup(path);
+
+ // Make sure the lib is closed on early return
+ std::unique_ptr<void, decltype(dlclose)*> libHandle(dlopen(path, RTLD_NOW),
+ dlclose);
+ if (libHandle == nullptr) {
+ ALOGE("Could not dlopen library %s: %s", path, dlerror());
+ return false;
+ }
+
+ auto* description = static_cast<audio_effect_library_t*>(
+ dlsym(libHandle.get(), AUDIO_EFFECT_LIBRARY_INFO_SYM_AS_STR));
+ if (description == nullptr) {
+ ALOGE("Invalid effect library, failed not find symbol '%s' in %s: %s",
+ AUDIO_EFFECT_LIBRARY_INFO_SYM_AS_STR, path, dlerror());
+ return false;
+ }
+
+ if (description->tag != AUDIO_EFFECT_LIBRARY_TAG) {
+ ALOGE("Bad tag %#08x in description structure, expected %#08x for library %s",
+ description->tag, AUDIO_EFFECT_LIBRARY_TAG, path);
+ return false;
+ }
+
+ uint32_t majorVersion = EFFECT_API_VERSION_MAJOR(description->version);
+ uint32_t expectedMajorVersion = EFFECT_API_VERSION_MAJOR(EFFECT_LIBRARY_API_VERSION);
+ if (majorVersion != expectedMajorVersion) {
+ ALOGE("Unsupported major version %#08x, expected %#08x for library %s",
+ majorVersion, expectedMajorVersion, path);
+ return false;
+ }
+
+ libEntry->handle = libHandle.release();
+ libEntry->desc = description;
+ return true;
+}
+
+/** Because the structures will be destroyed by c code, using new to allocate shared structure
+ * is not possible. Provide a equivalent of unique_ptr for malloc/freed structure to make sure
+ * they are not leaked in the c++ code.
+ @{ */
+struct FreeDeleter {
+ void operator()(void* p) {
+ free(p);
+ }
+};
+/** unique_ptr for object created with malloc. */
+template <class T>
+using UniqueCPtr = std::unique_ptr<T, FreeDeleter>;
+
+/** c version of std::make_unique. Uses malloc and free. */
+template <class T>
+UniqueCPtr<T> makeUniqueC() {
+ T* ptr = new (malloc(sizeof(T))) T{}; // Use placement new to initialize the structure
+ return UniqueCPtr<T>{ptr};
+}
+
+/** @} */
+
+/** Push an not owned element in a list_elem link list with an optional lock. */
+template <class T, class ListElem>
+void listPush(T* object, ListElem** list, pthread_mutex_t* mutex = nullptr) noexcept {
+ auto listElem = makeUniqueC<ListElem>();
+ listElem->object = object;
+ if (mutex != nullptr) {
+ pthread_mutex_lock(mutex);
+ }
+ listElem->next = *list;
+ *list = listElem.release();
+ if (mutex != nullptr) {
+ pthread_mutex_unlock(mutex);
+ }
+}
+
+/** Push an owned element in a list_elem link list with an optional lock. */
+template <class T, class ListElem>
+void listPush(UniqueCPtr<T>&& object, ListElem** list, pthread_mutex_t* mutex = nullptr) noexcept {
+ listPush(object.release(), list, mutex);
+}
+
+size_t loadLibraries(const effectsConfig::Libraries& libs,
+ list_elem_t** libList, pthread_mutex_t* libListLock,
+ list_elem_t** libFailedList)
+{
+ size_t nbSkippedElement = 0;
+ for (auto& library : libs) {
+
+ // Construct a lib entry
+ auto libEntry = makeUniqueC<lib_entry_t>();
+ libEntry->name = strdup(library.name.c_str());
+ libEntry->effects = nullptr;
+ pthread_mutex_init(&libEntry->lock, nullptr);
+
+ if (!loadLibrary(library.path.c_str(), libEntry.get())) {
+ // Register library load failure
+ listPush(std::move(libEntry), libFailedList);
+ ++nbSkippedElement;
+ continue;
+ }
+ listPush(std::move(libEntry), libList, libListLock);
+ }
+ return nbSkippedElement;
+}
+
+/** Find a library with the given name in the given list. */
+lib_entry_t* findLibrary(const char* name, list_elem_t* list) {
+
+ while (list != nullptr) {
+ auto* object = static_cast<lib_entry_t*>(list->object);
+ if (strcmp(object->name, name) == 0) {
+ return object;
+ }
+ list = list->next;
+ }
+ return nullptr;
+}
+
+struct UuidStr {
+ /** Length of an uuid represented as string. @TODO: use a constant instead of 40. */
+ char buff[40];
+};
+
+/** @return a string representing the provided uuid.
+ * By not providing an output buffer, it is implicitly created in the caller context.
+ * In such case the return pointer has the same lifetime as the expression containing uuidToString()
+ */
+char* uuidToString(const effect_uuid_t& uuid, UuidStr&& str = {}) {
+ uuidToString(&uuid, str.buff, sizeof(str.buff));
+ return str.buff;
+}
+
+struct LoadEffectResult {
+ /** true if the effect is usable (aka, existing lib, desc, right version, unique uuid) */
+ bool success = false;
+ /** Set if the effect lib was found*/
+ lib_entry_t* lib = nullptr;
+ //* Set if the description was successfuly retrieved from the lib */
+ UniqueCPtr<effect_descriptor_t> effectDesc;
+};
+
+LoadEffectResult loadEffect(const EffectImpl& effect, const std::string& name,
+ list_elem_t* libList) {
+ LoadEffectResult result;
+
+ // Find the effect library
+ result.lib = findLibrary(effect.library->name.c_str(), libList);
+ if (result.lib == nullptr) {
+ ALOGE("Could not find library %s to load effect %s",
+ effect.library->name.c_str(), name.c_str());
+ return result;
+ }
+
+ result.effectDesc = makeUniqueC<effect_descriptor_t>();
+
+ // Get the effect descriptor
+ if (result.lib->desc->get_descriptor(&effect.uuid, result.effectDesc.get()) != 0) {
+ ALOGE("Error querying effect %s on lib %s",
+ uuidToString(effect.uuid), result.lib->name);
+ result.effectDesc.reset();
+ return result;
+ }
+
+ // Dump effect for debug
+#if (LOG_NDEBUG==0)
+ char s[512];
+ dumpEffectDescriptor(result.effectDesc.get(), s, sizeof(s), 0 /* indent */);
+ ALOGV("loadEffect() read descriptor %p:%s", result.effectDesc.get(), s);
+#endif
+
+ // Check effect is supported
+ uint32_t expectedMajorVersion = EFFECT_API_VERSION_MAJOR(EFFECT_CONTROL_API_VERSION);
+ if (EFFECT_API_VERSION_MAJOR(result.effectDesc->apiVersion) != expectedMajorVersion) {
+ ALOGE("Bad API version %#08x for effect %s in lib %s, expected major %#08x",
+ result.effectDesc->apiVersion, name.c_str(), result.lib->name, expectedMajorVersion);
+ return result;
+ }
+
+ lib_entry_t *_;
+ if (findEffect(nullptr, &effect.uuid, &_, nullptr) == 0) {
+ ALOGE("Effect %s uuid %s already exist", uuidToString(effect.uuid), name.c_str());
+ return result;
+ }
+
+ result.success = true;
+ return result;
+}
+
+size_t loadEffects(const Effects& effects, list_elem_t* libList, list_elem_t** skippedEffects,
+ list_sub_elem_t** subEffectList) {
+ size_t nbSkippedElement = 0;
+
+ for (auto& effect : effects) {
+
+ auto effectLoadResult = loadEffect(effect, effect.name, libList);
+ if (!effectLoadResult.success) {
+ if (effectLoadResult.effectDesc != nullptr) {
+ listPush(std::move(effectLoadResult.effectDesc), skippedEffects);
+ }
+ ++nbSkippedElement;
+ continue;
+ }
+
+ if (effect.isProxy) {
+ auto swEffectLoadResult = loadEffect(effect.libSw, effect.name + " libsw", libList);
+ auto hwEffectLoadResult = loadEffect(effect.libHw, effect.name + " libhw", libList);
+ if (!swEffectLoadResult.success || !hwEffectLoadResult.success) {
+ // Push the main effect in the skipped list even if only a subeffect is invalid
+ // as the main effect is not usable without its subeffects.
+ listPush(std::move(effectLoadResult.effectDesc), skippedEffects);
+ ++nbSkippedElement;
+ continue;
+ }
+ listPush(effectLoadResult.effectDesc.get(), subEffectList);
+
+ // Since we return a dummy descriptor for the proxy during
+ // get_descriptor call, we replace it with the corresponding
+ // sw effect descriptor, but keep the Proxy UUID
+ *effectLoadResult.effectDesc = *swEffectLoadResult.effectDesc;
+ effectLoadResult.effectDesc->uuid = effect.uuid;
+
+ effectLoadResult.effectDesc->flags |= EFFECT_FLAG_OFFLOAD_SUPPORTED;
+
+ auto registerSubEffect = [subEffectList](auto&& result) {
+ auto entry = makeUniqueC<sub_effect_entry_t>();
+ entry->object = result.effectDesc.release();
+ // lib_entry_t is stored since the sub effects are not linked to the library
+ entry->lib = result.lib;
+ listPush(std::move(entry), &(*subEffectList)->sub_elem);
+ };
+ registerSubEffect(std::move(swEffectLoadResult));
+ registerSubEffect(std::move(hwEffectLoadResult));
+ }
+
+ listPush(std::move(effectLoadResult.effectDesc), &effectLoadResult.lib->effects);
+ }
+ return nbSkippedElement;
+}
+
+} // namespace
+
+/////////////////////////////////////////////////
+// Interface function
+/////////////////////////////////////////////////
+
+extern "C" ssize_t EffectLoadXmlEffectConfig(const char* path)
+{
+ using effectsConfig::parse;
+ auto result = path ? parse(path) : parse();
+ if (result.parsedConfig == nullptr) {
+ ALOGE("Failed to parse XML configuration file");
+ return -1;
+ }
+ result.nbSkippedElement += loadLibraries(result.parsedConfig->libraries,
+ &gLibraryList, &gLibLock, &gLibraryFailedList) +
+ loadEffects(result.parsedConfig->effects, gLibraryList,
+ &gSkippedEffects, &gSubEffectList);
+
+ ALOGE_IF(result.nbSkippedElement != 0, "%zu errors during loading of configuration: %s",
+ result.nbSkippedElement, path ?: effectsConfig::DEFAULT_PATH);
+
+ return result.nbSkippedElement;
+}
+
+} // namespace android
diff --git a/media/libeffects/factory/EffectsXmlConfigLoader.h b/media/libeffects/factory/EffectsXmlConfigLoader.h
new file mode 100644
index 0000000..a3fe9a3
--- /dev/null
+++ b/media/libeffects/factory/EffectsXmlConfigLoader.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_EFFECTSXMLCONFIGLOADER_H
+#define ANDROID_EFFECTSXMLCONFIGLOADER_H
+
+#include <unistd.h>
+
+#include <cutils/compiler.h>
+
+#include "EffectsFactoryState.h"
+
+#if __cplusplus
+extern "C" {
+#endif
+
+/** Parses the platform effect xml configuration and stores its content in EffectFactoryState.
+ * @param[in] path of the configuration file or NULL to load the default one
+ * @return -1 on unrecoverable error (eg: no configuration file)
+ * 0 on success
+ * the number of invalid elements (lib & effect) skipped if the config is partially invalid
+ * @note this function is exported for test purpose only. Do not call from outside this library.
+ */
+ANDROID_API
+ssize_t EffectLoadXmlEffectConfig(const char* path);
+
+#if __cplusplus
+} // extern "C"
+#endif
+
+#endif // ANDROID_EFFECTSXMLCONFIGLOADER_H
diff --git a/media/libeffects/factory/include/media/EffectsFactoryApi.h b/media/libeffects/factory/include/media/EffectsFactoryApi.h
index 64a3212..a5a12eb 100644
--- a/media/libeffects/factory/include/media/EffectsFactoryApi.h
+++ b/media/libeffects/factory/include/media/EffectsFactoryApi.h
@@ -17,6 +17,7 @@
#ifndef ANDROID_EFFECTSFACTORYAPI_H_
#define ANDROID_EFFECTSFACTORYAPI_H_
+#include <cutils/compiler.h>
#include <errno.h>
#include <stdint.h>
#include <sys/types.h>
@@ -52,6 +53,7 @@
// *pNumEffects: updated with number of effects in factory
//
////////////////////////////////////////////////////////////////////////////////
+ANDROID_API
int EffectQueryNumberEffects(uint32_t *pNumEffects);
////////////////////////////////////////////////////////////////////////////////
@@ -79,6 +81,7 @@
// *pDescriptor: updated with the effect descriptor.
//
////////////////////////////////////////////////////////////////////////////////
+ANDROID_API
int EffectQueryEffect(uint32_t index, effect_descriptor_t *pDescriptor);
////////////////////////////////////////////////////////////////////////////////
@@ -110,6 +113,7 @@
// *pHandle: updated with the effect handle.
//
////////////////////////////////////////////////////////////////////////////////
+ANDROID_API
int EffectCreate(const effect_uuid_t *pEffectUuid, int32_t sessionId, int32_t ioId,
effect_handle_t *pHandle);
@@ -130,6 +134,7 @@
// -EINVAL invalid interface handle
//
////////////////////////////////////////////////////////////////////////////////
+ANDROID_API
int EffectRelease(effect_handle_t handle);
////////////////////////////////////////////////////////////////////////////////
@@ -153,6 +158,7 @@
// *pDescriptor: updated with the effect descriptor.
//
////////////////////////////////////////////////////////////////////////////////
+ANDROID_API
int EffectGetDescriptor(const effect_uuid_t *pEffectUuid, effect_descriptor_t *pDescriptor);
////////////////////////////////////////////////////////////////////////////////
@@ -169,8 +175,10 @@
// 1 if uuid is equal to EFFECT_UUID_NULL.
//
////////////////////////////////////////////////////////////////////////////////
+ANDROID_API
int EffectIsNullUuid(const effect_uuid_t *pEffectUuid);
+ANDROID_API
int EffectDumpEffects(int fd);
#if __cplusplus
diff --git a/media/libeffects/factory/test/DumpConfig.cpp b/media/libeffects/factory/test/DumpConfig.cpp
new file mode 100644
index 0000000..0a156b4
--- /dev/null
+++ b/media/libeffects/factory/test/DumpConfig.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2017 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 <media/EffectsFactoryApi.h>
+#include <unistd.h>
+#include "EffectsXmlConfigLoader.h"
+#include "EffectsConfigLoader.h"
+
+int main(int argc, char* argv[]) {
+ const char* path = nullptr;
+ bool legacyFormat;
+
+ if (argc == 2 && strcmp(argv[1], "--legacy") == 0) {
+ legacyFormat = true;
+ fprintf(stderr, "Dumping legacy effect config file\n");
+ } else if ((argc == 2 || argc == 3) && strcmp(argv[1], "--xml") == 0) {
+ legacyFormat = false;
+ if (argc == 3) {
+ fprintf(stderr, "Dumping XML effect config file: %s\n", path);
+ } else {
+ fprintf(stderr, "Dumping default XML effect config file.\n");
+ }
+ } else {
+ fprintf(stderr, "Invalid arguments.\n"
+ "Usage: %s [--legacy|--xml [FILE]]\n", argv[0]);
+ return 1;
+ }
+
+ if (!legacyFormat) {
+ ssize_t ret = EffectLoadXmlEffectConfig(path);
+ if (ret < 0) {
+ fprintf(stderr, "loadXmlEffectConfig failed, see logcat for detail.\n");
+ return 2;
+ }
+ if (ret > 0) {
+ fprintf(stderr, "Partially failed to load config. Skipped %zu elements, "
+ "see logcat for detail.\n", (size_t)ret);
+ }
+ }
+
+ if (legacyFormat) {
+ auto ret = EffectLoadEffectConfig();
+ if (ret < 0) {
+ fprintf(stderr, "loadEffectConfig failed, see logcat for detail.\n");
+ return 3;
+ }
+ fprintf(stderr, "legacy loadEffectConfig has probably succeed, see logcat to make sure.\n");
+ }
+
+ if (EffectDumpEffects(STDOUT_FILENO) != 0) {
+ fprintf(stderr, "Effect dump failed, see logcat for detail.\n");
+ return 4;
+ }
+}
diff --git a/media/libeffects/lvm/lib/Android.mk b/media/libeffects/lvm/lib/Android.mk
index 83e8288..941eb3e 100644
--- a/media/libeffects/lvm/lib/Android.mk
+++ b/media/libeffects/lvm/lib/Android.mk
@@ -72,19 +72,25 @@
Common/src/From2iToMono_16.c \
Common/src/Copy_16.c \
Common/src/MonoTo2I_16.c \
+ Common/src/MonoTo2I_32.c \
Common/src/LoadConst_16.c \
+ Common/src/LoadConst_32.c \
Common/src/dB_to_Lin32.c \
Common/src/Shift_Sat_v16xv16.c \
+ Common/src/Shift_Sat_v32xv32.c \
Common/src/Abs_32.c \
Common/src/Int32RShiftToInt16_Sat_32x16.c \
Common/src/From2iToMono_32.c \
Common/src/mult3s_16x16.c \
+ Common/src/Mult3s_32x16.c \
Common/src/NonLinComp_D16.c \
Common/src/DelayMix_16x16.c \
Common/src/MSTo2i_Sat_16x16.c \
Common/src/From2iToMS_16x16.c \
Common/src/Mac3s_Sat_16x16.c \
+ Common/src/Mac3s_Sat_32x16.c \
Common/src/Add2_Sat_16x16.c \
+ Common/src/Add2_Sat_32x32.c \
Common/src/LVC_MixSoft_1St_2i_D16C31_SAT.c \
Common/src/LVC_MixSoft_1St_D16C31_SAT.c \
Common/src/LVC_Mixer_VarSlope_SetTimeConstant.c \
@@ -120,7 +126,7 @@
$(LOCAL_PATH)/StereoWidening/src \
$(LOCAL_PATH)/StereoWidening/lib
-LOCAL_CFLAGS += -fvisibility=hidden
+LOCAL_CFLAGS += -fvisibility=hidden -DBUILD_FLOAT -DHIGHER_FS
LOCAL_CFLAGS += -Wall -Werror
include $(BUILD_STATIC_LIBRARY)
@@ -179,6 +185,7 @@
$(LOCAL_PATH)/Common/lib \
$(LOCAL_PATH)/Common/src
-LOCAL_CFLAGS += -fvisibility=hidden
+LOCAL_CFLAGS += -fvisibility=hidden -DBUILD_FLOAT -DHIGHER_FS
LOCAL_CFLAGS += -Wall -Werror
+
include $(BUILD_STATIC_LIBRARY)
diff --git a/media/libeffects/lvm/lib/Bass/lib/LVDBE.h b/media/libeffects/lvm/lib/Bass/lib/LVDBE.h
index 228977d..4c2b954 100644
--- a/media/libeffects/lvm/lib/Bass/lib/LVDBE.h
+++ b/media/libeffects/lvm/lib/Bass/lib/LVDBE.h
@@ -198,6 +198,10 @@
#define LVDBE_CAP_FS_32000 64
#define LVDBE_CAP_FS_44100 128
#define LVDBE_CAP_FS_48000 256
+#if defined(BUILD_FLOAT) && defined(HIGHER_FS)
+#define LVDBE_CAP_FS_96000 512
+#define LVDBE_CAP_FS_192000 1024
+#endif
typedef enum
{
@@ -210,6 +214,10 @@
LVDBE_FS_32000 = 6,
LVDBE_FS_44100 = 7,
LVDBE_FS_48000 = 8,
+#if defined(BUILD_FLOAT) && defined(HIGHER_FS)
+ LVDBE_FS_96000 = 9,
+ LVDBE_FS_192000 = 10,
+#endif
LVDBE_FS_MAX = LVM_MAXINT_32
} LVDBE_Fs_en;
@@ -450,12 +458,17 @@
/* NOTES: */
/* */
/****************************************************************************************/
-
+#ifdef BUILD_FLOAT
+LVDBE_ReturnStatus_en LVDBE_Process(LVDBE_Handle_t hInstance,
+ const LVM_FLOAT *pInData,
+ LVM_FLOAT *pOutData,
+ LVM_UINT16 NumSamples);
+#else
LVDBE_ReturnStatus_en LVDBE_Process(LVDBE_Handle_t hInstance,
const LVM_INT16 *pInData,
LVM_INT16 *pOutData,
LVM_UINT16 NumSamples);
-
+#endif
#ifdef __cplusplus
}
diff --git a/media/libeffects/lvm/lib/Bass/src/LVDBE_Coeffs.h b/media/libeffects/lvm/lib/Bass/src/LVDBE_Coeffs.h
index b1ebadf..f32ed30 100644
--- a/media/libeffects/lvm/lib/Bass/src/LVDBE_Coeffs.h
+++ b/media/libeffects/lvm/lib/Bass/src/LVDBE_Coeffs.h
@@ -19,6 +19,7 @@
#define __LVDBE_COEFFS_H__
+#ifndef BUILD_FLOAT
/************************************************************************************/
/* */
/* General */
@@ -514,5 +515,632 @@
#define MIX_TC_Fs44100 32097 /* Floating point value 0.979515 */
#define MIX_TC_Fs48000 32150 /* Floating point value 0.981150 */
+#else /*BUILD_FLOAT*/
+/************************************************************************************/
+/* */
+/* General */
+/* */
+/************************************************************************************/
+
+#define LVDBE_SCALESHIFT 10 /* As a power of 2 */
+
+
+/************************************************************************************/
+/* */
+/* High Pass Filter coefficients */
+/* */
+/************************************************************************************/
+
+ /* Coefficients for centre frequency 55Hz */
+#define HPF_Fs8000_Fc55_A0 0.958849f
+#define HPF_Fs8000_Fc55_A1 -1.917698f
+#define HPF_Fs8000_Fc55_A2 0.958849f
+#define HPF_Fs8000_Fc55_B1 -1.939001f
+#define HPF_Fs8000_Fc55_B2 0.940807f
+#define HPF_Fs11025_Fc55_A0 0.966909f
+#define HPF_Fs11025_Fc55_A1 -1.933818f
+#define HPF_Fs11025_Fc55_A2 0.966909f
+#define HPF_Fs11025_Fc55_B1 -1.955732f
+#define HPF_Fs11025_Fc55_B2 0.956690f
+#define HPF_Fs12000_Fc55_A0 0.968650f
+#define HPF_Fs12000_Fc55_A1 -1.937300f
+#define HPF_Fs12000_Fc55_A2 0.968650f
+#define HPF_Fs12000_Fc55_B1 -1.959327f
+#define HPF_Fs12000_Fc55_B2 0.960138f
+#define HPF_Fs16000_Fc55_A0 0.973588f
+#define HPF_Fs16000_Fc55_A1 -1.947176f
+#define HPF_Fs16000_Fc55_A2 0.973588f
+#define HPF_Fs16000_Fc55_B1 -1.969494f
+#define HPF_Fs16000_Fc55_B2 0.969952f
+#define HPF_Fs22050_Fc55_A0 0.977671f
+#define HPF_Fs22050_Fc55_A1 -1.955343f
+#define HPF_Fs22050_Fc55_A2 0.977671f
+#define HPF_Fs22050_Fc55_B1 -1.977863f
+#define HPF_Fs22050_Fc55_B2 0.978105f
+#define HPF_Fs24000_Fc55_A0 0.978551f
+#define HPF_Fs24000_Fc55_A1 -1.957102f
+#define HPF_Fs24000_Fc55_A2 0.978551f
+#define HPF_Fs24000_Fc55_B1 -1.979662f
+#define HPF_Fs24000_Fc55_B2 0.979866f
+#define HPF_Fs32000_Fc55_A0 0.981042f
+#define HPF_Fs32000_Fc55_A1 -1.962084f
+#define HPF_Fs32000_Fc55_A2 0.981042f
+#define HPF_Fs32000_Fc55_B1 -1.984746f
+#define HPF_Fs32000_Fc55_B2 0.984861f
+#define HPF_Fs44100_Fc55_A0 0.983097f
+#define HPF_Fs44100_Fc55_A1 -1.966194f
+#define HPF_Fs44100_Fc55_A2 0.983097f
+#define HPF_Fs44100_Fc55_B1 -1.988931f
+#define HPF_Fs44100_Fc55_B2 0.988992f
+#define HPF_Fs48000_Fc55_A0 0.983539f
+#define HPF_Fs48000_Fc55_A1 -1.967079f
+#define HPF_Fs48000_Fc55_A2 0.983539f
+#define HPF_Fs48000_Fc55_B1 -1.989831f
+#define HPF_Fs48000_Fc55_B2 0.989882f
+
+#ifdef HIGHER_FS
+#define HPF_Fs96000_Fc55_A0 0.986040f
+#define HPF_Fs96000_Fc55_A1 -1.972080f
+#define HPF_Fs96000_Fc55_A2 0.986040f
+#define HPF_Fs96000_Fc55_B1 -1.994915f
+#define HPF_Fs96000_Fc55_B2 0.994928f
+
+#define HPF_Fs192000_Fc55_A0 0.987294f
+#define HPF_Fs192000_Fc55_A1 -1.974588f
+#define HPF_Fs192000_Fc55_A2 0.987294f
+#define HPF_Fs192000_Fc55_B1 -1.997458f
+#define HPF_Fs192000_Fc55_B2 0.997461f
#endif
+
+
+ /* Coefficients for centre frequency 66Hz */
+#define HPF_Fs8000_Fc66_A0 0.953016f
+#define HPF_Fs8000_Fc66_A1 -1.906032f
+#define HPF_Fs8000_Fc66_A2 0.953016f
+#define HPF_Fs8000_Fc66_B1 -1.926810f
+#define HPF_Fs8000_Fc66_B2 0.929396f
+#define HPF_Fs11025_Fc66_A0 0.962638f
+#define HPF_Fs11025_Fc66_A1 -1.925275f
+#define HPF_Fs11025_Fc66_A2 0.962638f
+#define HPF_Fs11025_Fc66_B1 -1.946881f
+#define HPF_Fs11025_Fc66_B2 0.948256f
+#define HPF_Fs12000_Fc66_A0 0.964718f
+#define HPF_Fs12000_Fc66_A1 -1.929435f
+#define HPF_Fs12000_Fc66_A2 0.964718f
+#define HPF_Fs12000_Fc66_B1 -1.951196f
+#define HPF_Fs12000_Fc66_B2 0.952359f
+#define HPF_Fs16000_Fc66_A0 0.970622f
+#define HPF_Fs16000_Fc66_A1 -1.941244f
+#define HPF_Fs16000_Fc66_A2 0.970622f
+#define HPF_Fs16000_Fc66_B1 -1.963394f
+#define HPF_Fs16000_Fc66_B2 0.964052f
+#define HPF_Fs22050_Fc66_A0 0.975509f
+#define HPF_Fs22050_Fc66_A1 -1.951019f
+#define HPF_Fs22050_Fc66_A2 0.975509f
+#define HPF_Fs22050_Fc66_B1 -1.973436f
+#define HPF_Fs22050_Fc66_B2 0.973784f
+#define HPF_Fs24000_Fc66_A0 0.976563f
+#define HPF_Fs24000_Fc66_A1 -1.953125f
+#define HPF_Fs24000_Fc66_A2 0.976563f
+#define HPF_Fs24000_Fc66_B1 -1.975594f
+#define HPF_Fs24000_Fc66_B2 0.975889f
+#define HPF_Fs32000_Fc66_A0 0.979547f
+#define HPF_Fs32000_Fc66_A1 -1.959093f
+#define HPF_Fs32000_Fc66_A2 0.979547f
+#define HPF_Fs32000_Fc66_B1 -1.981695f
+#define HPF_Fs32000_Fc66_B2 0.981861f
+#define HPF_Fs44100_Fc66_A0 0.982010f
+#define HPF_Fs44100_Fc66_A1 -1.964019f
+#define HPF_Fs44100_Fc66_A2 0.982010f
+#define HPF_Fs44100_Fc66_B1 -1.986718f
+#define HPF_Fs44100_Fc66_B2 0.986805f
+#define HPF_Fs48000_Fc66_A0 0.982540f
+#define HPF_Fs48000_Fc66_A1 -1.965079f
+#define HPF_Fs48000_Fc66_A2 0.982540f
+#define HPF_Fs48000_Fc66_B1 -1.987797f
+#define HPF_Fs48000_Fc66_B2 0.987871f
+
+#ifdef HIGHER_FS
+#define HPF_Fs96000_Fc66_A0 0.985539f
+#define HPF_Fs96000_Fc66_A1 -1.971077f
+#define HPF_Fs96000_Fc66_A2 0.985539f
+#define HPF_Fs96000_Fc66_B1 -1.993898f
+#define HPF_Fs96000_Fc66_B2 0.993917f
+
+#define HPF_Fs192000_Fc66_A0 0.987043f
+#define HPF_Fs192000_Fc66_A1 -1.974086f
+#define HPF_Fs192000_Fc66_A2 0.987043f
+#define HPF_Fs192000_Fc66_B1 -1.996949f
+#define HPF_Fs192000_Fc66_B2 0.996954f
+#endif
+
+/* Coefficients for centre frequency 78Hz */
+#define HPF_Fs8000_Fc78_A0 0.946693f
+#define HPF_Fs8000_Fc78_A1 -1.893387f
+#define HPF_Fs8000_Fc78_A2 0.946693f
+#define HPF_Fs8000_Fc78_B1 -1.913517f
+#define HPF_Fs8000_Fc78_B2 0.917105f
+#define HPF_Fs11025_Fc78_A0 0.957999f
+#define HPF_Fs11025_Fc78_A1 -1.915998f
+#define HPF_Fs11025_Fc78_A2 0.957999f
+#define HPF_Fs11025_Fc78_B1 -1.937229f
+#define HPF_Fs11025_Fc78_B2 0.939140f
+#define HPF_Fs12000_Fc78_A0 0.960446f
+#define HPF_Fs12000_Fc78_A1 -1.920892f
+#define HPF_Fs12000_Fc78_A2 0.960446f
+#define HPF_Fs12000_Fc78_B1 -1.942326f
+#define HPF_Fs12000_Fc78_B2 0.943944f
+#define HPF_Fs16000_Fc78_A0 0.967397f
+#define HPF_Fs16000_Fc78_A1 -1.934794f
+#define HPF_Fs16000_Fc78_A2 0.967397f
+#define HPF_Fs16000_Fc78_B1 -1.956740f
+#define HPF_Fs16000_Fc78_B2 0.957656f
+#define HPF_Fs22050_Fc78_A0 0.973156f
+#define HPF_Fs22050_Fc78_A1 -1.946313f
+#define HPF_Fs22050_Fc78_A2 0.973156f
+#define HPF_Fs22050_Fc78_B1 -1.968607f
+#define HPF_Fs22050_Fc78_B2 0.969092f
+#define HPF_Fs24000_Fc78_A0 0.974398f
+#define HPF_Fs24000_Fc78_A1 -1.948797f
+#define HPF_Fs24000_Fc78_A2 0.974398f
+#define HPF_Fs24000_Fc78_B1 -1.971157f
+#define HPF_Fs24000_Fc78_B2 0.971568f
+#define HPF_Fs32000_Fc78_A0 0.977918f
+#define HPF_Fs32000_Fc78_A1 -1.955836f
+#define HPF_Fs32000_Fc78_A2 0.977918f
+#define HPF_Fs32000_Fc78_B1 -1.978367f
+#define HPF_Fs32000_Fc78_B2 0.978599f
+#define HPF_Fs44100_Fc78_A0 0.980824f
+#define HPF_Fs44100_Fc78_A1 -1.961649f
+#define HPF_Fs44100_Fc78_A2 0.980824f
+#define HPF_Fs44100_Fc78_B1 -1.984303f
+#define HPF_Fs44100_Fc78_B2 0.984425f
+#define HPF_Fs48000_Fc78_A0 0.981450f
+#define HPF_Fs48000_Fc78_A1 -1.962900f
+#define HPF_Fs48000_Fc78_A2 0.981450f
+#define HPF_Fs48000_Fc78_B1 -1.985578f
+#define HPF_Fs48000_Fc78_B2 0.985681f
+
+#ifdef HIGHER_FS
+#define HPF_Fs96000_Fc78_A0 0.984992f
+#define HPF_Fs96000_Fc78_A1 -1.969984f
+#define HPF_Fs96000_Fc78_A2 0.984992f
+#define HPF_Fs96000_Fc78_B1 -1.992789f
+#define HPF_Fs96000_Fc78_B2 0.992815f
+
+#define HPF_Fs192000_Fc78_A0 0.986769f
+#define HPF_Fs192000_Fc78_A1 -1.973539f
+#define HPF_Fs192000_Fc78_A2 0.986769f
+#define HPF_Fs192000_Fc78_B1 -1.996394f
+#define HPF_Fs192000_Fc78_B2 0.996401f
+#endif
+
+/* Coefficients for centre frequency 90Hz */
+#define HPF_Fs8000_Fc90_A0 0.940412f
+#define HPF_Fs8000_Fc90_A1 -1.880825f
+#define HPF_Fs8000_Fc90_A2 0.940412f
+#define HPF_Fs8000_Fc90_B1 -1.900231f
+#define HPF_Fs8000_Fc90_B2 0.904977f
+#define HPF_Fs11025_Fc90_A0 0.953383f
+#define HPF_Fs11025_Fc90_A1 -1.906766f
+#define HPF_Fs11025_Fc90_A2 0.953383f
+#define HPF_Fs11025_Fc90_B1 -1.927579f
+#define HPF_Fs11025_Fc90_B2 0.930111f
+#define HPF_Fs12000_Fc90_A0 0.956193f
+#define HPF_Fs12000_Fc90_A1 -1.912387f
+#define HPF_Fs12000_Fc90_A2 0.956193f
+#define HPF_Fs12000_Fc90_B1 -1.933459f
+#define HPF_Fs12000_Fc90_B2 0.935603f
+#define HPF_Fs16000_Fc90_A0 0.964183f
+#define HPF_Fs16000_Fc90_A1 -1.928365f
+#define HPF_Fs16000_Fc90_A2 0.964183f
+#define HPF_Fs16000_Fc90_B1 -1.950087f
+#define HPF_Fs16000_Fc90_B2 0.951303f
+#define HPF_Fs22050_Fc90_A0 0.970809f
+#define HPF_Fs22050_Fc90_A1 -1.941618f
+#define HPF_Fs22050_Fc90_A2 0.970809f
+#define HPF_Fs22050_Fc90_B1 -1.963778f
+#define HPF_Fs22050_Fc90_B2 0.964423f
+#define HPF_Fs24000_Fc90_A0 0.972239f
+#define HPF_Fs24000_Fc90_A1 -1.944477f
+#define HPF_Fs24000_Fc90_A2 0.972239f
+#define HPF_Fs24000_Fc90_B1 -1.966721f
+#define HPF_Fs24000_Fc90_B2 0.967266f
+#define HPF_Fs32000_Fc90_A0 0.976292f
+#define HPF_Fs32000_Fc90_A1 -1.952584f
+#define HPF_Fs32000_Fc90_A2 0.976292f
+#define HPF_Fs32000_Fc90_B1 -1.975040f
+#define HPF_Fs32000_Fc90_B2 0.975347f
+#define HPF_Fs44100_Fc90_A0 0.979641f
+#define HPF_Fs44100_Fc90_A1 -1.959282f
+#define HPF_Fs44100_Fc90_A2 0.979641f
+#define HPF_Fs44100_Fc90_B1 -1.981888f
+#define HPF_Fs44100_Fc90_B2 0.982050f
+#define HPF_Fs48000_Fc90_A0 0.980362f
+#define HPF_Fs48000_Fc90_A1 -1.960724f
+#define HPF_Fs48000_Fc90_A2 0.980362f
+#define HPF_Fs48000_Fc90_B1 -1.983359f
+#define HPF_Fs48000_Fc90_B2 0.983497f
+
+#ifdef HIGHER_FS
+#define HPF_Fs96000_Fc90_A0 0.984446f
+#define HPF_Fs96000_Fc90_A1 -1.968892f
+#define HPF_Fs96000_Fc90_A2 0.984446f
+#define HPF_Fs96000_Fc90_B1 -1.991680f
+#define HPF_Fs96000_Fc90_B2 0.991714f
+
+#define HPF_Fs192000_Fc90_A0 0.986496f
+#define HPF_Fs192000_Fc90_A1 -1.972992f
+#define HPF_Fs192000_Fc90_A2 0.986496f
+#define HPF_Fs192000_Fc90_B1 -1.995840f
+#define HPF_Fs192000_Fc90_B2 0.995848f
+#endif
+
+/************************************************************************************/
+/* */
+/* Band Pass Filter coefficients */
+/* */
+/************************************************************************************/
+
+/* Coefficients for centre frequency 55Hz */
+#define BPF_Fs8000_Fc55_A0 0.009197f
+#define BPF_Fs8000_Fc55_A1 0.000000f
+#define BPF_Fs8000_Fc55_A2 -0.009197f
+#define BPF_Fs8000_Fc55_B1 -1.979545f
+#define BPF_Fs8000_Fc55_B2 0.981393f
+#define BPF_Fs11025_Fc55_A0 0.006691f
+#define BPF_Fs11025_Fc55_A1 0.000000f
+#define BPF_Fs11025_Fc55_A2 -0.006691f
+#define BPF_Fs11025_Fc55_B1 -1.985488f
+#define BPF_Fs11025_Fc55_B2 0.986464f
+#define BPF_Fs12000_Fc55_A0 0.006150f
+#define BPF_Fs12000_Fc55_A1 0.000000f
+#define BPF_Fs12000_Fc55_A2 -0.006150f
+#define BPF_Fs12000_Fc55_B1 -1.986733f
+#define BPF_Fs12000_Fc55_B2 0.987557f
+#define BPF_Fs16000_Fc55_A0 0.004620f
+#define BPF_Fs16000_Fc55_A1 0.000000f
+#define BPF_Fs16000_Fc55_A2 -0.004620f
+#define BPF_Fs16000_Fc55_B1 -1.990189f
+#define BPF_Fs16000_Fc55_B2 0.990653f
+#define BPF_Fs22050_Fc55_A0 0.003357f
+#define BPF_Fs22050_Fc55_A1 0.000000f
+#define BPF_Fs22050_Fc55_A2 -0.003357f
+#define BPF_Fs22050_Fc55_B1 -1.992964f
+#define BPF_Fs22050_Fc55_B2 0.993209f
+#define BPF_Fs24000_Fc55_A0 0.003085f
+#define BPF_Fs24000_Fc55_A1 0.000000f
+#define BPF_Fs24000_Fc55_A2 -0.003085f
+#define BPF_Fs24000_Fc55_B1 -1.993552f
+#define BPF_Fs24000_Fc55_B2 0.993759f
+#define BPF_Fs32000_Fc55_A0 0.002315f
+#define BPF_Fs32000_Fc55_A1 0.000000f
+#define BPF_Fs32000_Fc55_A2 -0.002315f
+#define BPF_Fs32000_Fc55_B1 -1.995199f
+#define BPF_Fs32000_Fc55_B2 0.995316f
+#define BPF_Fs44100_Fc55_A0 0.001681f
+#define BPF_Fs44100_Fc55_A1 0.000000f
+#define BPF_Fs44100_Fc55_A2 -0.001681f
+#define BPF_Fs44100_Fc55_B1 -1.996537f
+#define BPF_Fs44100_Fc55_B2 0.996599f
+#define BPF_Fs48000_Fc55_A0 0.001545f
+#define BPF_Fs48000_Fc55_A1 0.000000f
+#define BPF_Fs48000_Fc55_A2 -0.001545f
+#define BPF_Fs48000_Fc55_B1 -1.996823f
+#define BPF_Fs48000_Fc55_B2 0.996875f
+
+#ifdef HIGHER_FS
+#define BPF_Fs96000_Fc55_A0 0.000762f
+#define BPF_Fs96000_Fc55_A1 0.000000f
+#define BPF_Fs96000_Fc55_A2 -0.000762f
+#define BPF_Fs96000_Fc55_B1 -1.998461f
+#define BPF_Fs96000_Fc55_B2 0.998477f
+
+#define BPF_Fs192000_Fc55_A0 0.000381f
+#define BPF_Fs192000_Fc55_A1 0.000000f
+#define BPF_Fs192000_Fc55_A2 -0.000381f
+#define BPF_Fs192000_Fc55_B1 -1.999234f
+#define BPF_Fs192000_Fc55_B2 0.999238f
+#endif
+
+/* Coefficients for centre frequency 66Hz */
+#define BPF_Fs8000_Fc66_A0 0.012648f
+#define BPF_Fs8000_Fc66_A1 0.000000f
+#define BPF_Fs8000_Fc66_A2 -0.012648f
+#define BPF_Fs8000_Fc66_B1 -1.971760f
+#define BPF_Fs8000_Fc66_B2 0.974412f
+#define BPF_Fs11025_Fc66_A0 0.009209f
+#define BPF_Fs11025_Fc66_A1 0.000000f
+#define BPF_Fs11025_Fc66_A2 -0.009209f
+#define BPF_Fs11025_Fc66_B1 -1.979966f
+#define BPF_Fs11025_Fc66_B2 0.981368f
+#define BPF_Fs12000_Fc66_A0 0.008468f
+#define BPF_Fs12000_Fc66_A1 0.000000f
+#define BPF_Fs12000_Fc66_A2 -0.008468f
+#define BPF_Fs12000_Fc66_B1 -1.981685f
+#define BPF_Fs12000_Fc66_B2 0.982869f
+#define BPF_Fs16000_Fc66_A0 0.006364f
+#define BPF_Fs16000_Fc66_A1 0.000000f
+#define BPF_Fs16000_Fc66_A2 -0.006364f
+#define BPF_Fs16000_Fc66_B1 -1.986457f
+#define BPF_Fs16000_Fc66_B2 0.987124f
+#define BPF_Fs22050_Fc66_A0 0.004626f
+#define BPF_Fs22050_Fc66_A1 0.000000f
+#define BPF_Fs22050_Fc66_A2 -0.004626f
+#define BPF_Fs22050_Fc66_B1 -1.990288f
+#define BPF_Fs22050_Fc66_B2 0.990641f
+#define BPF_Fs24000_Fc66_A0 0.004252f
+#define BPF_Fs24000_Fc66_A1 0.000000f
+#define BPF_Fs24000_Fc66_A2 -0.004252f
+#define BPF_Fs24000_Fc66_B1 -1.991100f
+#define BPF_Fs24000_Fc66_B2 0.991398f
+#define BPF_Fs32000_Fc66_A0 0.003192f
+#define BPF_Fs32000_Fc66_A1 0.000000f
+#define BPF_Fs32000_Fc66_A2 -0.003192f
+#define BPF_Fs32000_Fc66_B1 -1.993374f
+#define BPF_Fs32000_Fc66_B2 0.993541f
+#define BPF_Fs44100_Fc66_A0 0.002318f
+#define BPF_Fs44100_Fc66_A1 0.000000f
+#define BPF_Fs44100_Fc66_A2 -0.002318f
+#define BPF_Fs44100_Fc66_B1 -1.995221f
+#define BPF_Fs44100_Fc66_B2 0.995309f
+#define BPF_Fs48000_Fc66_A0 0.002131f
+#define BPF_Fs48000_Fc66_A1 0.000000f
+#define BPF_Fs48000_Fc66_A2 -0.002131f
+#define BPF_Fs48000_Fc66_B1 -1.995615f
+#define BPF_Fs48000_Fc66_B2 0.995690f
+
+#ifdef HIGHER_FS
+#define BPF_Fs96000_Fc66_A0 0.001055f
+#define BPF_Fs96000_Fc66_A1 0.000000f
+#define BPF_Fs96000_Fc66_A2 -0.001055f
+#define BPF_Fs96000_Fc66_B1 -1.997868f
+#define BPF_Fs96000_Fc66_B2 0.997891f
+
+#define BPF_Fs192000_Fc66_A0 0.000528f
+#define BPF_Fs192000_Fc66_A1 0.000000f
+#define BPF_Fs192000_Fc66_A2 -0.000528f
+#define BPF_Fs192000_Fc66_B1 -1.998939f
+#define BPF_Fs192000_Fc66_B2 0.998945f
+#endif
+
+/* Coefficients for centre frequency 78Hz */
+#define BPF_Fs8000_Fc78_A0 0.018572f
+#define BPF_Fs8000_Fc78_A1 0.000000f
+#define BPF_Fs8000_Fc78_A2 -0.018572f
+#define BPF_Fs8000_Fc78_B1 -1.958745f
+#define BPF_Fs8000_Fc78_B2 0.962427f
+#define BPF_Fs11025_Fc78_A0 0.013545f
+#define BPF_Fs11025_Fc78_A1 0.000000f
+#define BPF_Fs11025_Fc78_A2 -0.013545f
+#define BPF_Fs11025_Fc78_B1 -1.970647f
+#define BPF_Fs11025_Fc78_B2 0.972596f
+#define BPF_Fs12000_Fc78_A0 0.012458f
+#define BPF_Fs12000_Fc78_A1 0.000000f
+#define BPF_Fs12000_Fc78_A2 -0.012458f
+#define BPF_Fs12000_Fc78_B1 -1.973148f
+#define BPF_Fs12000_Fc78_B2 0.974795f
+#define BPF_Fs16000_Fc78_A0 0.009373f
+#define BPF_Fs16000_Fc78_A1 0.000000f
+#define BPF_Fs16000_Fc78_A2 -0.009373f
+#define BPF_Fs16000_Fc78_B1 -1.980108f
+#define BPF_Fs16000_Fc78_B2 0.981037f
+#define BPF_Fs22050_Fc78_A0 0.006819f
+#define BPF_Fs22050_Fc78_A1 0.000000f
+#define BPF_Fs22050_Fc78_A2 -0.006819f
+#define BPF_Fs22050_Fc78_B1 -1.985714f
+#define BPF_Fs22050_Fc78_B2 0.986204f
+#define BPF_Fs24000_Fc78_A0 0.006268f
+#define BPF_Fs24000_Fc78_A1 0.000000f
+#define BPF_Fs24000_Fc78_A2 -0.006268f
+#define BPF_Fs24000_Fc78_B1 -1.986904f
+#define BPF_Fs24000_Fc78_B2 0.987318f
+#define BPF_Fs32000_Fc78_A0 0.004709f
+#define BPF_Fs32000_Fc78_A1 0.000000f
+#define BPF_Fs32000_Fc78_A2 -0.004709f
+#define BPF_Fs32000_Fc78_B1 -1.990240f
+#define BPF_Fs32000_Fc78_B2 0.990473f
+#define BPF_Fs44100_Fc78_A0 0.003421f
+#define BPF_Fs44100_Fc78_A1 0.000000f
+#define BPF_Fs44100_Fc78_A2 -0.003421f
+#define BPF_Fs44100_Fc78_B1 -1.992955f
+#define BPF_Fs44100_Fc78_B2 0.993078f
+#define BPF_Fs48000_Fc78_A0 0.003144f
+#define BPF_Fs48000_Fc78_A1 0.000000f
+#define BPF_Fs48000_Fc78_A2 -0.003144f
+#define BPF_Fs48000_Fc78_B1 -1.993535f
+#define BPF_Fs48000_Fc78_B2 0.993639f
+
+#ifdef HIGHER_FS
+#define BPF_Fs96000_Fc78_A0 0.001555f
+#define BPF_Fs96000_Fc78_A1 0.000000f
+#define BPF_Fs96000_Fc78_A2 -0.0015555f
+#define BPF_Fs96000_Fc78_B1 -1.996860f
+#define BPF_Fs96000_Fc78_B2 0.996891f
+
+#define BPF_Fs192000_Fc78_A0 0.000778f
+#define BPF_Fs192000_Fc78_A1 0.000000f
+#define BPF_Fs192000_Fc78_A2 -0.000778f
+#define BPF_Fs192000_Fc78_B1 -1.998437f
+#define BPF_Fs192000_Fc78_B2 0.998444f
+#endif
+
+/* Coefficients for centre frequency 90Hz */
+#define BPF_Fs8000_Fc90_A0 0.022760f
+#define BPF_Fs8000_Fc90_A1 0.000000f
+#define BPF_Fs8000_Fc90_A2 -0.022760f
+#define BPF_Fs8000_Fc90_B1 -1.949073f
+#define BPF_Fs8000_Fc90_B2 0.953953f
+#define BPF_Fs11025_Fc90_A0 0.016619f
+#define BPF_Fs11025_Fc90_A1 0.000000f
+#define BPF_Fs11025_Fc90_A2 -0.016619f
+#define BPF_Fs11025_Fc90_B1 -1.963791f
+#define BPF_Fs11025_Fc90_B2 0.966377f
+#define BPF_Fs12000_Fc90_A0 0.015289f
+#define BPF_Fs12000_Fc90_A1 0.000000f
+#define BPF_Fs12000_Fc90_A2 -0.015289f
+#define BPF_Fs12000_Fc90_B1 -1.966882f
+#define BPF_Fs12000_Fc90_B2 0.969067f
+#define BPF_Fs16000_Fc90_A0 0.011511f
+#define BPF_Fs16000_Fc90_A1 0.000000f
+#define BPF_Fs16000_Fc90_A2 -0.011511f
+#define BPF_Fs16000_Fc90_B1 -1.975477f
+#define BPF_Fs16000_Fc90_B2 0.976711f
+#define BPF_Fs22050_Fc90_A0 0.008379f
+#define BPF_Fs22050_Fc90_A1 0.000000f
+#define BPF_Fs22050_Fc90_A2 -0.008379f
+#define BPF_Fs22050_Fc90_B1 -1.982395f
+#define BPF_Fs22050_Fc90_B2 0.983047f
+#define BPF_Fs24000_Fc90_A0 0.007704f
+#define BPF_Fs24000_Fc90_A1 0.000000f
+#define BPF_Fs24000_Fc90_A2 -0.007704f
+#define BPF_Fs24000_Fc90_B1 -1.983863f
+#define BPF_Fs24000_Fc90_B2 0.984414f
+#define BPF_Fs32000_Fc90_A0 0.005789f
+#define BPF_Fs32000_Fc90_A1 0.000000f
+#define BPF_Fs32000_Fc90_A2 -0.005789f
+#define BPF_Fs32000_Fc90_B1 -1.987977f
+#define BPF_Fs32000_Fc90_B2 0.988288f
+#define BPF_Fs44100_Fc90_A0 0.004207f
+#define BPF_Fs44100_Fc90_A1 0.000000f
+#define BPF_Fs44100_Fc90_A2 -0.004207f
+#define BPF_Fs44100_Fc90_B1 -1.991324f
+#define BPF_Fs44100_Fc90_B2 0.991488f
+#define BPF_Fs48000_Fc90_A0 0.003867f
+#define BPF_Fs48000_Fc90_A1 0.000000f
+#define BPF_Fs48000_Fc90_A2 -0.003867f
+#define BPF_Fs48000_Fc90_B1 -1.992038f
+#define BPF_Fs48000_Fc90_B2 0.992177f
+
+#ifdef HIGHER_FS
+#define BPF_Fs96000_Fc90_A0 0.001913f
+#define BPF_Fs96000_Fc90_A1 0.000000f
+#define BPF_Fs96000_Fc90_A2 -0.001913f
+#define BPF_Fs96000_Fc90_B1 -1.996134f
+#define BPF_Fs96000_Fc90_B2 0.996174f
+
+#define BPF_Fs192000_Fc90_A0 0.000958f
+#define BPF_Fs192000_Fc90_A1 0.000000f
+#define BPF_Fs192000_Fc90_A2 -0.000958f
+#define BPF_Fs192000_Fc90_B1 -1.998075f
+#define BPF_Fs192000_Fc90_B2 0.998085f
+#endif
+
+/************************************************************************************/
+/* */
+/* Automatic Gain Control time constants and gain settings */
+/* */
+/************************************************************************************/
+
+/* AGC Time constants */
+#define AGC_ATTACK_Fs8000 0.841395f
+#define AGC_ATTACK_Fs11025 0.882223f
+#define AGC_ATTACK_Fs12000 0.891251f
+#define AGC_ATTACK_Fs16000 0.917276f
+#define AGC_ATTACK_Fs22050 0.939267f
+#define AGC_ATTACK_Fs24000 0.944061f
+#define AGC_ATTACK_Fs32000 0.957745f
+#define AGC_ATTACK_Fs44100 0.969158f
+#define AGC_ATTACK_Fs48000 0.971628f
+
+#ifdef HIGHER_FS
+#define AGC_ATTACK_Fs96000 0.985712f
+#define AGC_ATTACK_Fs192000 0.992830f
+#endif
+
+#define DECAY_SHIFT 10
+
+#define AGC_DECAY_Fs8000 0.000042f
+#define AGC_DECAY_Fs11025 0.000030f
+#define AGC_DECAY_Fs12000 0.000028f
+#define AGC_DECAY_Fs16000 0.000021f
+#define AGC_DECAY_Fs22050 0.000015f
+#define AGC_DECAY_Fs24000 0.000014f
+#define AGC_DECAY_Fs32000 0.000010f
+#define AGC_DECAY_Fs44100 0.000008f
+#define AGC_DECAY_Fs48000 0.000007f
+
+#ifdef HIGHER_FS
+#define AGC_DECAY_FS96000 0.0000035f
+#define AGC_DECAY_FS192000 0.00000175f
+#endif
+
+/* AGC Gain settings */
+#define AGC_GAIN_SCALE 31 /* As a power of 2 */
+#define AGC_GAIN_SHIFT 4 /* As a power of 2 */
+#define AGC_TARGETLEVEL 0.988553f
+#define AGC_HPFGAIN_0dB 0.412538f
+#define AGC_GAIN_0dB 0.000000f
+#define AGC_HPFGAIN_1dB 0.584893f
+#define AGC_GAIN_1dB 0.122018f
+#define AGC_HPFGAIN_2dB 0.778279f
+#define AGC_GAIN_2dB 0.258925f
+#define AGC_HPFGAIN_3dB 0.995262f
+#define AGC_GAIN_3dB 0.412538f
+#define AGC_HPFGAIN_4dB 1.238721f
+#define AGC_GAIN_4dB 0.584893f
+#define AGC_HPFGAIN_5dB 1.511886f
+#define AGC_GAIN_5dB 0.778279f
+#define AGC_HPFGAIN_6dB 1.818383f
+#define AGC_GAIN_6dB 0.995262f
+#define AGC_HPFGAIN_7dB 2.162278f
+#define AGC_GAIN_7dB 1.238721f
+#define AGC_HPFGAIN_8dB 2.548134f
+#define AGC_GAIN_8dB 1.511886f
+#define AGC_HPFGAIN_9dB 2.981072f
+#define AGC_GAIN_9dB 1.818383f
+#define AGC_HPFGAIN_10dB 3.466836f
+#define AGC_GAIN_10dB 2.162278f
+#define AGC_HPFGAIN_11dB 4.011872f
+#define AGC_GAIN_11dB 2.548134f
+#define AGC_HPFGAIN_12dB 4.623413f
+#define AGC_GAIN_12dB 2.981072f
+#define AGC_HPFGAIN_13dB 5.309573f
+#define AGC_GAIN_13dB 3.466836f
+#define AGC_HPFGAIN_14dB 6.079458f
+#define AGC_GAIN_14dB 4.011872f
+#define AGC_HPFGAIN_15dB 6.943282f
+#define AGC_GAIN_15dB 4.623413f
+
+/************************************************************************************/
+/* */
+/* Volume control */
+/* */
+/************************************************************************************/
+
+/* Volume control gain */
+#define VOLUME_MAX 0 /* In dBs */
+#define VOLUME_SHIFT 0 /* In dBs */
+
+/* Volume control time constants */
+#define VOL_TC_SHIFT 21 /* As a power of 2 */
+#define VOL_TC_Fs8000 0.024690f
+#define VOL_TC_Fs11025 0.017977f
+#define VOL_TC_Fs12000 0.016529f
+#define VOL_TC_Fs16000 0.012422f
+#define VOL_TC_Fs22050 0.009029f
+#define VOL_TC_Fs24000 0.008299f
+#define VOL_TC_Fs32000 0.006231f
+#define VOL_TC_Fs44100 0.004525f
+#define VOL_TC_Fs48000 0.004158f
+#ifdef HIGHER_FS
+#define VOL_TC_Fs96000 0.002079f
+#define VOL_TC_Fs192000 0.001039f
+#endif
+#define MIX_TC_Fs8000 29365 /* Floating point value 0.896151 */
+#define MIX_TC_Fs11025 30230 /* Floating point value 0.922548 */
+#define MIX_TC_Fs12000 30422 /* Floating point value 0.928415 */
+#define MIX_TC_Fs16000 30978 /* Floating point value 0.945387 */
+#define MIX_TC_Fs22050 31451 /* Floating point value 0.959804 */
+#define MIX_TC_Fs24000 31554 /* Floating point value 0.962956 */
+#define MIX_TC_Fs32000 31850 /* Floating point value 0.971973 */
+#define MIX_TC_Fs44100 32097 /* Floating point value 0.979515 */
+#define MIX_TC_Fs48000 32150 /* Floating point value 0.981150 */
+#ifdef HIGHER_FS
+#define MIX_TC_Fs96000 32456 /* Floating point value 0.990530 */
+#define MIX_TC_Fs192000 32611 /* Floating point value 0.992524 */
+#endif
+
+#endif /*BUILD_FLOAT*/
+#endif
\ No newline at end of file
diff --git a/media/libeffects/lvm/lib/Bass/src/LVDBE_Control.c b/media/libeffects/lvm/lib/Bass/src/LVDBE_Control.c
index b6632a3..fd4016b 100644
--- a/media/libeffects/lvm/lib/Bass/src/LVDBE_Control.c
+++ b/media/libeffects/lvm/lib/Bass/src/LVDBE_Control.c
@@ -107,35 +107,68 @@
LVDBE_Params_t *pParams)
{
+#if defined(BUILD_FLOAT) && defined(HIGHER_FS)
/*
* Calculate the table offsets
*/
- LVM_UINT16 Offset = (LVM_UINT16)((LVM_UINT16)pParams->SampleRate + (LVM_UINT16)(pParams->CentreFrequency * (1+LVDBE_FS_48000)));
-
+ LVM_UINT16 Offset = (LVM_UINT16)((LVM_UINT16)pParams->SampleRate + \
+ (LVM_UINT16)(pParams->CentreFrequency * (1+LVDBE_FS_192000)));
+#else
+ /*
+ * Calculate the table offsets
+ */
+ LVM_UINT16 Offset = (LVM_UINT16)((LVM_UINT16)pParams->SampleRate + \
+ (LVM_UINT16)(pParams->CentreFrequency * (1+LVDBE_FS_48000)));
+#endif
/*
* Setup the high pass filter
*/
- LoadConst_16(0, /* Clear the history, value 0 */
- (void *)&pInstance->pData->HPFTaps, /* Destination Cast to void: \
- no dereferencing in function*/
+#ifndef BUILD_FLOAT
+ LoadConst_16(0, /* Clear the history, value 0 */
+ (void *)&pInstance->pData->HPFTaps, /* Destination Cast to void: \
+ no dereferencing in function*/
sizeof(pInstance->pData->HPFTaps)/sizeof(LVM_INT16)); /* Number of words */
- BQ_2I_D32F32Cll_TRC_WRA_01_Init(&pInstance->pCoef->HPFInstance, /* Initialise the filter */
+#else
+ LoadConst_Float(0, /* Clear the history, value 0 */
+ (void *)&pInstance->pData->HPFTaps, /* Destination Cast to void: \
+ no dereferencing in function*/
+ sizeof(pInstance->pData->HPFTaps) / sizeof(LVM_FLOAT)); /* Number of words */
+#endif
+#ifndef BUILD_FLOAT
+ BQ_2I_D32F32Cll_TRC_WRA_01_Init(&pInstance->pCoef->HPFInstance, /* Initialise the filter */
&pInstance->pData->HPFTaps,
(BQ_C32_Coefs_t *)&LVDBE_HPF_Table[Offset]);
+#else
+ BQ_2I_D32F32Cll_TRC_WRA_01_Init(&pInstance->pCoef->HPFInstance, /* Initialise the filter */
+ &pInstance->pData->HPFTaps,
+ (BQ_FLOAT_Coefs_t *)&LVDBE_HPF_Table[Offset]);
+#endif
/*
* Setup the band pass filter
*/
+#ifndef BUILD_FLOAT
LoadConst_16(0, /* Clear the history, value 0 */
- (void *)&pInstance->pData->BPFTaps, /* Destination Cast to void:\
+ (void *)&pInstance->pData->BPFTaps, /* Destination Cast to void: \
no dereferencing in function*/
sizeof(pInstance->pData->BPFTaps)/sizeof(LVM_INT16)); /* Number of words */
+#else
+ LoadConst_Float(0, /* Clear the history, value 0 */
+ (void *)&pInstance->pData->BPFTaps, /* Destination Cast to void: \
+ no dereferencing in function*/
+ sizeof(pInstance->pData->BPFTaps) / sizeof(LVM_FLOAT)); /* Number of words */
+#endif
+#ifndef BUILD_FLOAT
BP_1I_D32F32Cll_TRC_WRA_02_Init(&pInstance->pCoef->BPFInstance, /* Initialise the filter */
&pInstance->pData->BPFTaps,
(BP_C32_Coefs_t *)&LVDBE_BPF_Table[Offset]);
-
+#else
+ BP_1I_D32F32Cll_TRC_WRA_02_Init(&pInstance->pCoef->BPFInstance, /* Initialise the filter */
+ &pInstance->pData->BPFTaps,
+ (BP_FLOAT_Coefs_t *)&LVDBE_BPF_Table[Offset]);
+#endif
}
@@ -175,7 +208,9 @@
{
pInstance->pData->AGCInstance.AGC_MaxGain = LVDBE_AGC_GAIN_Table[(LVM_UINT16)pParams->EffectLevel]; /* High pass filter off */
}
+#ifndef BUILD_FLOAT
pInstance->pData->AGCInstance.AGC_GainShift = AGC_GAIN_SHIFT;
+#endif
pInstance->pData->AGCInstance.AGC_Target = AGC_TARGETLEVEL;
}
@@ -212,6 +247,9 @@
LVM_UINT16 dBOffset; /* Table offset */
LVM_INT16 Volume = 0; /* Required volume in dBs */
+#ifdef BUILD_FLOAT
+ LVM_FLOAT dBShifts_fac;
+#endif
/*
* Apply the volume if enabled
*/
@@ -237,33 +275,58 @@
dBOffset = (LVM_UINT16)(6 + Volume % 6); /* Get the dBs 0-5 */
dBShifts = (LVM_UINT16)(Volume / -6); /* Get the 6dB shifts */
-
+#ifdef BUILD_FLOAT
+ dBShifts_fac = (LVM_FLOAT)(1 << dBShifts);
+#endif
/*
* When DBE is enabled use AGC volume
*/
+#ifndef BUILD_FLOAT
pInstance->pData->AGCInstance.Target = ((LVM_INT32)LVDBE_VolumeTable[dBOffset] << 16);
pInstance->pData->AGCInstance.Target = pInstance->pData->AGCInstance.Target >> dBShifts;
-
+#else
+ pInstance->pData->AGCInstance.Target = (LVDBE_VolumeTable[dBOffset]);
+ pInstance->pData->AGCInstance.Target = pInstance->pData->AGCInstance.Target / dBShifts_fac;
+#endif
pInstance->pData->AGCInstance.VolumeTC = LVDBE_VolumeTCTable[(LVM_UINT16)pParams->SampleRate]; /* Volume update time constant */
+#ifndef BUILD_FLOAT
pInstance->pData->AGCInstance.VolumeShift = VOLUME_SHIFT+1;
+#endif
/*
* When DBE is disabled use the bypass volume control
*/
if(dBShifts > 0)
{
+#ifndef BUILD_FLOAT
LVC_Mixer_SetTarget(&pInstance->pData->BypassVolume.MixerStream[0],(((LVM_INT32)LVDBE_VolumeTable[dBOffset]) >> dBShifts));
+#else
+ LVC_Mixer_SetTarget(&pInstance->pData->BypassVolume.MixerStream[0],
+ LVDBE_VolumeTable[dBOffset] / dBShifts_fac);
+#endif
}
else
{
+#ifndef BUILD_FLOAT
LVC_Mixer_SetTarget(&pInstance->pData->BypassVolume.MixerStream[0],(LVM_INT32)LVDBE_VolumeTable[dBOffset]);
+#else
+ LVC_Mixer_SetTarget(&pInstance->pData->BypassVolume.MixerStream[0],
+ LVDBE_VolumeTable[dBOffset]);
+#endif
}
pInstance->pData->BypassVolume.MixerStream[0].CallbackSet = 1;
+#ifndef BUILD_FLOAT
LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->pData->BypassVolume.MixerStream[0],
LVDBE_MIXER_TC,
(LVM_Fs_en)pInstance->Params.SampleRate,
2);
+#else
+ LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->pData->BypassVolume.MixerStream[0],
+ LVDBE_MIXER_TC,
+ (LVM_Fs_en)pInstance->Params.SampleRate,
+ 2);
+#endif
}
@@ -309,7 +372,11 @@
{
LVDBE_Instance_t *pInstance =(LVDBE_Instance_t *)hInstance;
+#ifndef BUILD_FLOAT
LVMixer3_2St_st *pBypassMixer_Instance = &pInstance->pData->BypassMixer;
+#else
+ LVMixer3_2St_FLOAT_st *pBypassMixer_Instance = &pInstance->pData->BypassMixer;
+#endif
/*
@@ -332,12 +399,19 @@
{
LVDBE_SetAGC(pInstance, /* Instance pointer */
pParams); /* New parameters */
-
+#ifndef BUILD_FLOAT
LVC_Mixer_SetTimeConstant(&pBypassMixer_Instance->MixerStream[0],
LVDBE_BYPASS_MIXER_TC,(LVM_Fs_en)pParams->SampleRate,2);
LVC_Mixer_SetTimeConstant(&pBypassMixer_Instance->MixerStream[1],
LVDBE_BYPASS_MIXER_TC,(LVM_Fs_en)pParams->SampleRate,2);
+#else
+ LVC_Mixer_SetTimeConstant(&pBypassMixer_Instance->MixerStream[0],
+ LVDBE_BYPASS_MIXER_TC,(LVM_Fs_en)pParams->SampleRate, 2);
+
+ LVC_Mixer_SetTimeConstant(&pBypassMixer_Instance->MixerStream[1],
+ LVDBE_BYPASS_MIXER_TC,(LVM_Fs_en)pParams->SampleRate, 2);
+#endif
}
@@ -357,13 +431,23 @@
if (pInstance->Params.OperatingMode==LVDBE_ON && pParams->OperatingMode==LVDBE_OFF)
{
+#ifndef BUILD_FLOAT
LVC_Mixer_SetTarget(&pInstance->pData->BypassMixer.MixerStream[0],0);
LVC_Mixer_SetTarget(&pInstance->pData->BypassMixer.MixerStream[1],0x00007FFF);
+#else
+ LVC_Mixer_SetTarget(&pInstance->pData->BypassMixer.MixerStream[0], 0);
+ LVC_Mixer_SetTarget(&pInstance->pData->BypassMixer.MixerStream[1], 1.0f);
+#endif
}
if (pInstance->Params.OperatingMode==LVDBE_OFF && pParams->OperatingMode==LVDBE_ON)
{
+#ifndef BUILD_FLOAT
LVC_Mixer_SetTarget(&pInstance->pData->BypassMixer.MixerStream[0],0x00007FFF);
LVC_Mixer_SetTarget(&pInstance->pData->BypassMixer.MixerStream[1],0);
+#else
+ LVC_Mixer_SetTarget(&pInstance->pData->BypassMixer.MixerStream[0], 1.0f);
+ LVC_Mixer_SetTarget(&pInstance->pData->BypassMixer.MixerStream[1], 0);
+#endif
}
/*
diff --git a/media/libeffects/lvm/lib/Bass/src/LVDBE_Init.c b/media/libeffects/lvm/lib/Bass/src/LVDBE_Init.c
index a3623bc..3fff2a2 100644
--- a/media/libeffects/lvm/lib/Bass/src/LVDBE_Init.c
+++ b/media/libeffects/lvm/lib/Bass/src/LVDBE_Init.c
@@ -80,7 +80,11 @@
/*
* Data memory
*/
+#ifdef BUILD_FLOAT
+ pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_DATA].Size = sizeof(LVDBE_Data_FLOAT_t);
+#else
pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_DATA].Size = sizeof(LVDBE_Data_t);
+#endif
pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_DATA].Alignment = LVDBE_PERSISTENT_DATA_ALIGN;
pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_DATA].Type = LVDBE_PERSISTENT_DATA;
pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_DATA].pBaseAddress = LVM_NULL;
@@ -88,7 +92,11 @@
/*
* Coef memory
*/
- pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_COEF].Size = sizeof(LVDBE_Coef_t);
+#ifdef BUILD_FLOAT
+ pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_COEF].Size = sizeof(LVDBE_Coef_FLOAT_t);
+#else
+ pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_COEF].Size = sizeof(LVDBE_Coef_t);
+#endif
pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_COEF].Alignment = LVDBE_PERSISTENT_COEF_ALIGN;
pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_COEF].Type = LVDBE_PERSISTENT_COEF;
pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_COEF].pBaseAddress = LVM_NULL;
@@ -96,7 +104,12 @@
/*
* Scratch memory
*/
+#ifdef BUILD_FLOAT
+ ScratchSize = (LVM_UINT32)(LVDBE_SCRATCHBUFFERS_INPLACE*sizeof(LVM_FLOAT) * \
+ pCapabilities->MaxBlockSize);
+#else /*BUILD_FLOAT*/
ScratchSize = (LVM_UINT32)(LVDBE_SCRATCHBUFFERS_INPLACE*sizeof(LVM_INT16)*pCapabilities->MaxBlockSize);
+#endif
pMemoryTable->Region[LVDBE_MEMREGION_SCRATCH].Size = ScratchSize;
pMemoryTable->Region[LVDBE_MEMREGION_SCRATCH].Alignment = LVDBE_SCRATCH_ALIGN;
pMemoryTable->Region[LVDBE_MEMREGION_SCRATCH].Type = LVDBE_SCRATCH;
@@ -151,10 +164,16 @@
{
LVDBE_Instance_t *pInstance;
+#ifdef BUILD_FLOAT
+ LVMixer3_1St_FLOAT_st *pMixer_Instance;
+ LVMixer3_2St_FLOAT_st *pBypassMixer_Instance;
+ LVM_FLOAT MixGain;
+#else
LVMixer3_1St_st *pMixer_Instance;
LVMixer3_2St_st *pBypassMixer_Instance;
- LVM_INT16 i;
LVM_INT32 MixGain;
+#endif
+ LVM_INT16 i;
/*
@@ -235,7 +254,11 @@
// initialize the mixer with some fixes values since otherwise LVDBE_SetVolume ends up
// reading uninitialized data
pMixer_Instance = &pInstance->pData->BypassVolume;
+#ifndef BUILD_FLOAT
LVC_Mixer_Init(&pMixer_Instance->MixerStream[0],0x00007FFF,0x00007FFF);
+#else
+ LVC_Mixer_Init(&pMixer_Instance->MixerStream[0], 1.0, 1.0);
+#endif
/*
* Initialise the volume
@@ -245,9 +268,13 @@
pInstance->pData->AGCInstance.Volume = pInstance->pData->AGCInstance.Target;
/* Initialise as the target */
-
+#ifndef BUILD_FLOAT
MixGain = LVC_Mixer_GetTarget(&pMixer_Instance->MixerStream[0]);
LVC_Mixer_Init(&pMixer_Instance->MixerStream[0],MixGain,MixGain);
+#else
+ MixGain = LVC_Mixer_GetTarget(&pMixer_Instance->MixerStream[0]);
+ LVC_Mixer_Init(&pMixer_Instance->MixerStream[0], MixGain, MixGain);
+#endif
/* Configure the mixer process path */
pMixer_Instance->MixerStream[0].CallbackParam = 0;
@@ -268,9 +295,11 @@
pBypassMixer_Instance->MixerStream[0].pCallbackHandle = LVM_NULL;
pBypassMixer_Instance->MixerStream[0].pCallBack = LVM_NULL;
pBypassMixer_Instance->MixerStream[0].CallbackSet=0;
+
LVC_Mixer_Init(&pBypassMixer_Instance->MixerStream[0],0,0);
LVC_Mixer_SetTimeConstant(&pBypassMixer_Instance->MixerStream[0],
LVDBE_BYPASS_MIXER_TC,(LVM_Fs_en)pInstance->Params.SampleRate,2);
+
/*
* Setup the mixer gain for the unprocessed path
*/
@@ -278,9 +307,15 @@
pBypassMixer_Instance->MixerStream[1].pCallbackHandle = LVM_NULL;
pBypassMixer_Instance->MixerStream[1].pCallBack = LVM_NULL;
pBypassMixer_Instance->MixerStream[1].CallbackSet=0;
+#ifndef BUILD_FLOAT
LVC_Mixer_Init(&pBypassMixer_Instance->MixerStream[1],0x00007FFF,0x00007FFF);
LVC_Mixer_SetTimeConstant(&pBypassMixer_Instance->MixerStream[1],
LVDBE_BYPASS_MIXER_TC,(LVM_Fs_en)pInstance->Params.SampleRate,2);
+#else
+ LVC_Mixer_Init(&pBypassMixer_Instance->MixerStream[1], 1.0, 1.0);
+ LVC_Mixer_SetTimeConstant(&pBypassMixer_Instance->MixerStream[1],
+ LVDBE_BYPASS_MIXER_TC,(LVM_Fs_en)pInstance->Params.SampleRate, 2);
+#endif
return(LVDBE_SUCCESS);
}
diff --git a/media/libeffects/lvm/lib/Bass/src/LVDBE_Private.h b/media/libeffects/lvm/lib/Bass/src/LVDBE_Private.h
index 8339d3c..4e5207f 100644
--- a/media/libeffects/lvm/lib/Bass/src/LVDBE_Private.h
+++ b/media/libeffects/lvm/lib/Bass/src/LVDBE_Private.h
@@ -77,6 +77,7 @@
/****************************************************************************************/
/* Data structure */
+#ifndef BUILD_FLOAT
typedef struct
{
/* AGC parameters */
@@ -98,7 +99,29 @@
Biquad_Instance_t BPFInstance; /* Band pass filter instance */
} LVDBE_Coef_t;
+#else
+/* Data structure */
+typedef struct
+{
+ /* AGC parameters */
+ AGC_MIX_VOL_2St1Mon_FLOAT_t AGCInstance; /* AGC instance parameters */
+ /* Process variables */
+ Biquad_2I_Order2_FLOAT_Taps_t HPFTaps; /* High pass filter taps */
+ Biquad_1I_Order2_FLOAT_Taps_t BPFTaps; /* Band pass filter taps */
+ LVMixer3_1St_FLOAT_st BypassVolume; /* Bypass volume scaler */
+ LVMixer3_2St_FLOAT_st BypassMixer; /* Bypass Mixer for Click Removal */
+
+} LVDBE_Data_FLOAT_t;
+
+/* Coefs structure */
+typedef struct
+{
+ /* Process variables */
+ Biquad_FLOAT_Instance_t HPFInstance; /* High pass filter instance */
+ Biquad_FLOAT_Instance_t BPFInstance; /* Band pass filter instance */
+} LVDBE_Coef_FLOAT_t;
+#endif
/* Instance structure */
typedef struct
{
@@ -108,8 +131,13 @@
LVDBE_Capabilities_t Capabilities; /* Instance capabilities */
/* Data and coefficient pointers */
+#ifndef BUILD_FLOAT
LVDBE_Data_t *pData; /* Instance data */
LVDBE_Coef_t *pCoef; /* Instance coefficients */
+#else
+ LVDBE_Data_FLOAT_t *pData; /* Instance data */
+ LVDBE_Coef_FLOAT_t *pCoef; /* Instance coefficients */
+#endif
} LVDBE_Instance_t;
@@ -136,5 +164,3 @@
#endif /* __cplusplus */
#endif /* __LVDBE_PRIVATE_H__ */
-
-
diff --git a/media/libeffects/lvm/lib/Bass/src/LVDBE_Process.c b/media/libeffects/lvm/lib/Bass/src/LVDBE_Process.c
index 69d79d2..10ea700 100644
--- a/media/libeffects/lvm/lib/Bass/src/LVDBE_Process.c
+++ b/media/libeffects/lvm/lib/Bass/src/LVDBE_Process.c
@@ -27,7 +27,6 @@
#include "AGC.h"
#include "LVDBE_Coeffs.h" /* Filter coefficients */
-
/********************************************************************************************/
/* */
/* FUNCTION: LVDBE_Process */
@@ -72,136 +71,236 @@
/* overall end to end gain is odB. */
/* */
/********************************************************************************************/
+#ifndef BUILD_FLOAT
+LVDBE_ReturnStatus_en LVDBE_Process(LVDBE_Handle_t hInstance,
+ const LVM_INT16 *pInData, LVM_INT16 *pOutData, LVM_UINT16 NumSamples) {
-LVDBE_ReturnStatus_en LVDBE_Process(LVDBE_Handle_t hInstance,
- const LVM_INT16 *pInData,
- LVM_INT16 *pOutData,
- LVM_UINT16 NumSamples)
+ LVDBE_Instance_t *pInstance = (LVDBE_Instance_t *) hInstance;
+ LVM_INT32 *pScratch =
+ (LVM_INT32 *) pInstance->MemoryTable.Region[LVDBE_MEMREGION_SCRATCH].pBaseAddress;
+ LVM_INT32 *pMono;
+ LVM_INT16 *pInput = (LVM_INT16 *) pInData;
+
+ /* Scratch for Volume Control starts at offset of 2*NumSamples short values from pScratch */
+ LVM_INT16 *pScratchVol = (LVM_INT16 *) (&pScratch[NumSamples]);
+
+ /* Scratch for Mono path starts at offset of 2*NumSamples 32-bit values from pScratch */
+ pMono = &pScratch[2 * NumSamples];
+
+ /*
+ * Check the number of samples is not too large
+ */
+ if (NumSamples > pInstance->Capabilities.MaxBlockSize) {
+ return (LVDBE_TOOMANYSAMPLES);
+ }
+
+ /*
+ * Check if the algorithm is enabled
+ */
+ /* DBE path is processed when DBE is ON or during On/Off transitions */
+ if ((pInstance->Params.OperatingMode == LVDBE_ON)
+ || (LVC_Mixer_GetCurrent(
+ &pInstance->pData->BypassMixer.MixerStream[0])
+ != LVC_Mixer_GetTarget(
+ &pInstance->pData->BypassMixer.MixerStream[0]))) {
+
+ /*
+ * Convert 16-bit samples to 32-bit and scale
+ * (For a 16-bit implementation apply headroom loss here)
+ */
+ Int16LShiftToInt32_16x32(pInput, /* Source 16-bit data */
+ pScratch, /* Dest. 32-bit data */
+ (LVM_INT16) (2 * NumSamples), /* Left and right */
+ LVDBE_SCALESHIFT); /* Shift scale */
+
+ /*
+ * Apply the high pass filter if selected
+ */
+ if (pInstance->Params.HPFSelect == LVDBE_HPF_ON) {
+ BQ_2I_D32F32C30_TRC_WRA_01(&pInstance->pCoef->HPFInstance,/* Filter instance */
+ (LVM_INT32 *) pScratch, /* Source */
+ (LVM_INT32 *) pScratch, /* Destination */
+ (LVM_INT16) NumSamples); /* Number of samples */
+ }
+
+ /*
+ * Create the mono stream
+ */
+ From2iToMono_32(pScratch, /* Stereo source */
+ pMono, /* Mono destination */
+ (LVM_INT16) NumSamples); /* Number of samples */
+
+ /*
+ * Apply the band pass filter
+ */
+ BP_1I_D32F32C30_TRC_WRA_02(&pInstance->pCoef->BPFInstance, /* Filter instance */
+ (LVM_INT32 *) pMono, /* Source */
+ (LVM_INT32 *) pMono, /* Destination */
+ (LVM_INT16) NumSamples); /* Number of samples */
+
+ /*
+ * Apply the AGC and mix
+ */
+ AGC_MIX_VOL_2St1Mon_D32_WRA(&pInstance->pData->AGCInstance, /* Instance pointer */
+ pScratch, /* Stereo source */
+ pMono, /* Mono band pass source */
+ pScratch, /* Stereo destination */
+ NumSamples); /* Number of samples */
+
+ /*
+ * Convert 32-bit samples to 16-bit and saturate
+ * (Not required for 16-bit implemenations)
+ */
+ Int32RShiftToInt16_Sat_32x16(pScratch, /* Source 32-bit data */
+ (LVM_INT16 *) pScratch, /* Dest. 16-bit data */
+ (LVM_INT16) (2 * NumSamples), /* Left and right */
+ LVDBE_SCALESHIFT); /* Shift scale */
+
+ }
+
+ /* Bypass Volume path is processed when DBE is OFF or during On/Off transitions */
+ if ((pInstance->Params.OperatingMode == LVDBE_OFF)
+ || (LVC_Mixer_GetCurrent(
+ &pInstance->pData->BypassMixer.MixerStream[1])
+ != LVC_Mixer_GetTarget(
+ &pInstance->pData->BypassMixer.MixerStream[1]))) {
+
+ /*
+ * The algorithm is disabled but volume management is required to compensate for
+ * headroom and volume (if enabled)
+ */
+ LVC_MixSoft_1St_D16C31_SAT(&pInstance->pData->BypassVolume, pInData,
+ pScratchVol, (LVM_INT16) (2 * NumSamples)); /* Left and right */
+
+ }
+
+ /*
+ * Mix DBE processed path and bypass volume path
+ */
+ LVC_MixSoft_2St_D16C31_SAT(&pInstance->pData->BypassMixer,
+ (LVM_INT16 *) pScratch, pScratchVol, pOutData,
+ (LVM_INT16) (2 * NumSamples));
+
+ return (LVDBE_SUCCESS);
+}
+#else /*BUILD_FLOAT*/
+LVDBE_ReturnStatus_en LVDBE_Process(LVDBE_Handle_t hInstance,
+ const LVM_FLOAT *pInData,
+ LVM_FLOAT *pOutData,
+ LVM_UINT16 NumSamples)
{
- LVDBE_Instance_t *pInstance =(LVDBE_Instance_t *)hInstance;
- LVM_INT32 *pScratch = (LVM_INT32 *)pInstance->MemoryTable.Region[LVDBE_MEMREGION_SCRATCH].pBaseAddress;
- LVM_INT32 *pMono;
- LVM_INT16 *pInput = (LVM_INT16 *)pInData;
+ LVDBE_Instance_t *pInstance =(LVDBE_Instance_t *)hInstance;
+ LVM_FLOAT *pScratch_in = (LVM_FLOAT *)pInstance->MemoryTable.Region
+ [LVDBE_MEMREGION_SCRATCH].pBaseAddress;
+ LVM_FLOAT *pScratch = pScratch_in + 2 * NumSamples;
+ LVM_FLOAT *pMono;
+ LVM_INT32 ii = 0;
+ /* Scratch for Volume Control starts at offset of 4*NumSamples float values from pScratch */
+ LVM_FLOAT *pScratchVol = (LVM_FLOAT *)(&pScratch_in[4 * NumSamples]);
+// LVM_INT16 *pScratchVol_int = (LVM_INT16 *)(pScratchVol);
- /* Scratch for Volume Control starts at offset of 2*NumSamples short values from pScratch */
- LVM_INT16 *pScratchVol = (LVM_INT16 *)(&pScratch[NumSamples]);
+ /* Scratch for Mono path starts at offset of 6*NumSamples 32-bit values from pScratch */
+ pMono = &pScratch_in[4 * NumSamples];
- /* Scratch for Mono path starts at offset of 2*NumSamples 32-bit values from pScratch */
- pMono = &pScratch[2*NumSamples];
+ /*
+ * Check the number of samples is not too large
+ */
+ if (NumSamples > pInstance->Capabilities.MaxBlockSize)
+ {
+ return(LVDBE_TOOMANYSAMPLES);
+ }
+
+ /*
+ * Convert 16-bit samples to Float
+ */
+ Copy_Float(pInData, /* Source 16-bit data */
+ pScratch_in, /* Dest. 32-bit data */
+ (LVM_INT16)(2 * NumSamples)); /* Left and right */
+
+ for (ii = 0; ii < 2 * NumSamples; ii++) {
+ pScratch[ii] = pScratch_in[ii];
+ }
+ /*
+ * Check if the algorithm is enabled
+ */
+ /* DBE path is processed when DBE is ON or during On/Off transitions */
+ if ((pInstance->Params.OperatingMode == LVDBE_ON)||
+ (LVC_Mixer_GetCurrent(&pInstance->pData->BypassMixer.MixerStream[0])
+ !=LVC_Mixer_GetTarget(&pInstance->pData->BypassMixer.MixerStream[0])))
+ {
/*
- * Check the number of samples is not too large
+ * Apply the high pass filter if selected
*/
- if (NumSamples > pInstance->Capabilities.MaxBlockSize)
+ if (pInstance->Params.HPFSelect == LVDBE_HPF_ON)
{
- return(LVDBE_TOOMANYSAMPLES);
+ BQ_2I_D32F32C30_TRC_WRA_01(&pInstance->pCoef->HPFInstance,/* Filter instance */
+ (LVM_FLOAT *)pScratch, /* Source */
+ (LVM_FLOAT *)pScratch, /* Destination */
+ (LVM_INT16)NumSamples); /* Number of samples */
}
/*
- * Check if the algorithm is enabled
+ * Create the mono stream
*/
- /* DBE path is processed when DBE is ON or during On/Off transitions */
- if ((pInstance->Params.OperatingMode == LVDBE_ON)||
- (LVC_Mixer_GetCurrent(&pInstance->pData->BypassMixer.MixerStream[0])
- !=LVC_Mixer_GetTarget(&pInstance->pData->BypassMixer.MixerStream[0])))
- {
-
- /*
- * Convert 16-bit samples to 32-bit and scale
- * (For a 16-bit implementation apply headroom loss here)
- */
- Int16LShiftToInt32_16x32(pInput, /* Source 16-bit data */
- pScratch, /* Dest. 32-bit data */
- (LVM_INT16)(2*NumSamples), /* Left and right */
- LVDBE_SCALESHIFT); /* Shift scale */
-
-
- /*
- * Apply the high pass filter if selected
- */
- if (pInstance->Params.HPFSelect == LVDBE_HPF_ON)
- {
- BQ_2I_D32F32C30_TRC_WRA_01(&pInstance->pCoef->HPFInstance,/* Filter instance */
- (LVM_INT32 *)pScratch, /* Source */
- (LVM_INT32 *)pScratch, /* Destination */
- (LVM_INT16)NumSamples); /* Number of samples */
- }
-
-
- /*
- * Create the mono stream
- */
- From2iToMono_32(pScratch, /* Stereo source */
- pMono, /* Mono destination */
- (LVM_INT16)NumSamples); /* Number of samples */
-
-
- /*
- * Apply the band pass filter
- */
- BP_1I_D32F32C30_TRC_WRA_02(&pInstance->pCoef->BPFInstance, /* Filter instance */
- (LVM_INT32 *)pMono, /* Source */
- (LVM_INT32 *)pMono, /* Destination */
- (LVM_INT16)NumSamples); /* Number of samples */
-
-
- /*
- * Apply the AGC and mix
- */
- AGC_MIX_VOL_2St1Mon_D32_WRA(&pInstance->pData->AGCInstance, /* Instance pointer */
- pScratch, /* Stereo source */
- pMono, /* Mono band pass source */
- pScratch, /* Stereo destination */
- NumSamples); /* Number of samples */
-
- /*
- * Convert 32-bit samples to 16-bit and saturate
- * (Not required for 16-bit implemenations)
- */
- Int32RShiftToInt16_Sat_32x16(pScratch, /* Source 32-bit data */
- (LVM_INT16 *)pScratch, /* Dest. 16-bit data */
- (LVM_INT16)(2*NumSamples), /* Left and right */
- LVDBE_SCALESHIFT); /* Shift scale */
-
- }
-
- /* Bypass Volume path is processed when DBE is OFF or during On/Off transitions */
- if ((pInstance->Params.OperatingMode == LVDBE_OFF)||
- (LVC_Mixer_GetCurrent(&pInstance->pData->BypassMixer.MixerStream[1])
- !=LVC_Mixer_GetTarget(&pInstance->pData->BypassMixer.MixerStream[1])))
- {
-
- /*
- * The algorithm is disabled but volume management is required to compensate for
- * headroom and volume (if enabled)
- */
- LVC_MixSoft_1St_D16C31_SAT(&pInstance->pData->BypassVolume,
- pInData,
- pScratchVol,
- (LVM_INT16)(2*NumSamples)); /* Left and right */
-
- }
+ From2iToMono_Float((LVM_FLOAT *)pScratch, /* Stereo source */
+ pMono, /* Mono destination */
+ (LVM_INT16)NumSamples); /* Number of samples */
/*
- * Mix DBE processed path and bypass volume path
+ * Apply the band pass filter
*/
- LVC_MixSoft_2St_D16C31_SAT(&pInstance->pData->BypassMixer,
- (LVM_INT16 *) pScratch,
- pScratchVol,
- pOutData,
- (LVM_INT16)(2*NumSamples));
+ BP_1I_D32F32C30_TRC_WRA_02(&pInstance->pCoef->BPFInstance, /* Filter instance */
+ (LVM_FLOAT *)pMono, /* Source */
+ (LVM_FLOAT *)pMono, /* Destination */
+ (LVM_INT16)NumSamples); /* Number of samples */
- return(LVDBE_SUCCESS);
+ /*
+ * Apply the AGC and mix
+ */
+ AGC_MIX_VOL_2St1Mon_D32_WRA(&pInstance->pData->AGCInstance, /* Instance pointer */
+ pScratch, /* Stereo source */
+ pMono, /* Mono band pass source */
+ pScratch, /* Stereo destination */
+ NumSamples); /* Number of samples */
+
+ for (ii = 0; ii < 2 * NumSamples; ii++) {
+ //TODO: replace with existing clamping function
+ if(pScratch[ii] < -1.0) {
+ pScratch[ii] = -1.0;
+ } else if(pScratch[ii] > 1.0) {
+ pScratch[ii] = 1.0;
+ }
+ }
+ }
+
+ /* Bypass Volume path is processed when DBE is OFF or during On/Off transitions */
+ if ((pInstance->Params.OperatingMode == LVDBE_OFF)||
+ (LVC_Mixer_GetCurrent(&pInstance->pData->BypassMixer.MixerStream[1])
+ !=LVC_Mixer_GetTarget(&pInstance->pData->BypassMixer.MixerStream[1])))
+ {
+
+ /*
+ * The algorithm is disabled but volume management is required to compensate for
+ * headroom and volume (if enabled)
+ */
+ LVC_MixSoft_1St_D16C31_SAT(&pInstance->pData->BypassVolume,
+ pScratch_in,
+ pScratchVol,
+ (LVM_INT16)(2 * NumSamples)); /* Left and right */
+ }
+
+ /*
+ * Mix DBE processed path and bypass volume path
+ */
+ LVC_MixSoft_2St_D16C31_SAT(&pInstance->pData->BypassMixer,
+ pScratch,
+ pScratchVol,
+ pOutData,
+ (LVM_INT16)(2 * NumSamples));
+
+ return(LVDBE_SUCCESS);
}
-
-
-
-
-
-
-
-
-
-
+#endif
diff --git a/media/libeffects/lvm/lib/Bass/src/LVDBE_Tables.c b/media/libeffects/lvm/lib/Bass/src/LVDBE_Tables.c
index f5d229e..c4a9b14 100644
--- a/media/libeffects/lvm/lib/Bass/src/LVDBE_Tables.c
+++ b/media/libeffects/lvm/lib/Bass/src/LVDBE_Tables.c
@@ -36,7 +36,11 @@
/*
* High Pass Filter Coefficient table
*/
+#ifndef BUILD_FLOAT
const BQ_C32_Coefs_t LVDBE_HPF_Table[] = {
+#else /*BUILD_FLOAT*/
+const BQ_FLOAT_Coefs_t LVDBE_HPF_Table[] = {
+#endif /*BUILD_FLOAT*/
/* Coefficients for 55Hz centre frequency */
{HPF_Fs8000_Fc55_A2, /* 8kS/s coefficients */
HPF_Fs8000_Fc55_A1,
@@ -83,6 +87,18 @@
HPF_Fs48000_Fc55_A0,
-HPF_Fs48000_Fc55_B2,
-HPF_Fs48000_Fc55_B1},
+#ifdef HIGHER_FS
+ {HPF_Fs96000_Fc55_A2, /* 96kS/s coefficients */
+ HPF_Fs96000_Fc55_A1,
+ HPF_Fs96000_Fc55_A0,
+ -HPF_Fs96000_Fc55_B2,
+ -HPF_Fs96000_Fc55_B1},
+ {HPF_Fs192000_Fc55_A2, /* 192kS/s coefficients */
+ HPF_Fs192000_Fc55_A1,
+ HPF_Fs192000_Fc55_A0,
+ -HPF_Fs192000_Fc55_B2,
+ -HPF_Fs192000_Fc55_B1},
+#endif
/* Coefficients for 66Hz centre frequency */
{HPF_Fs8000_Fc66_A2, /* 8kS/s coefficients */
@@ -130,6 +146,19 @@
HPF_Fs48000_Fc66_A0,
-HPF_Fs48000_Fc66_B2,
-HPF_Fs48000_Fc66_B1},
+#ifdef HIGHER_FS
+ {HPF_Fs96000_Fc66_A2, /* 96kS/s coefficients */
+ HPF_Fs96000_Fc66_A1,
+ HPF_Fs96000_Fc66_A0,
+ -HPF_Fs96000_Fc66_B2,
+ -HPF_Fs96000_Fc66_B1},
+ {HPF_Fs192000_Fc66_A2, /* 192kS/s coefficients */
+ HPF_Fs192000_Fc66_A1,
+ HPF_Fs192000_Fc66_A0,
+ -HPF_Fs192000_Fc66_B2,
+ -HPF_Fs192000_Fc66_B1},
+#endif
+
/* Coefficients for 78Hz centre frequency */
{HPF_Fs8000_Fc78_A2, /* 8kS/s coefficients */
@@ -177,6 +206,19 @@
HPF_Fs48000_Fc78_A0,
-HPF_Fs48000_Fc78_B2,
-HPF_Fs48000_Fc78_B1},
+#ifdef HIGHER_FS
+ {HPF_Fs96000_Fc78_A2, /* 96kS/s coefficients */
+ HPF_Fs96000_Fc78_A1,
+ HPF_Fs96000_Fc78_A0,
+ -HPF_Fs96000_Fc78_B2,
+ -HPF_Fs96000_Fc78_B1},
+ {HPF_Fs192000_Fc78_A2, /* 192kS/s coefficients */
+ HPF_Fs192000_Fc78_A1,
+ HPF_Fs192000_Fc78_A0,
+ -HPF_Fs192000_Fc78_B2,
+ -HPF_Fs192000_Fc78_B1},
+#endif
+
/* Coefficients for 90Hz centre frequency */
{HPF_Fs8000_Fc90_A2, /* 8kS/s coefficients */
@@ -223,12 +265,32 @@
HPF_Fs48000_Fc90_A1,
HPF_Fs48000_Fc90_A0,
-HPF_Fs48000_Fc90_B2,
- -HPF_Fs48000_Fc90_B1}};
+ -HPF_Fs48000_Fc90_B1}
+
+#ifdef HIGHER_FS
+ ,
+ {HPF_Fs96000_Fc90_A2, /* 96kS/s coefficients */
+ HPF_Fs96000_Fc90_A1,
+ HPF_Fs96000_Fc90_A0,
+ -HPF_Fs96000_Fc90_B2,
+ -HPF_Fs96000_Fc90_B1},
+ {HPF_Fs192000_Fc90_A2, /* 192kS/s coefficients */
+ HPF_Fs192000_Fc90_A1,
+ HPF_Fs192000_Fc90_A0,
+ -HPF_Fs192000_Fc90_B2,
+ -HPF_Fs192000_Fc90_B1}
+#endif
+
+};
/*
* Band Pass Filter coefficient table
*/
+#ifndef BUILD_FLOAT
const BP_C32_Coefs_t LVDBE_BPF_Table[] = {
+#else /*BUILD_FLOAT*/
+const BP_FLOAT_Coefs_t LVDBE_BPF_Table[] = {
+#endif /*BUILD_FLOAT*/
/* Coefficients for 55Hz centre frequency */
{BPF_Fs8000_Fc55_A0, /* 8kS/s coefficients */
-BPF_Fs8000_Fc55_B2,
@@ -257,6 +319,14 @@
{BPF_Fs48000_Fc55_A0, /* 48kS/s coefficients */
-BPF_Fs48000_Fc55_B2,
-BPF_Fs48000_Fc55_B1},
+#ifdef HIGHER_FS
+ {BPF_Fs96000_Fc55_A0, /* 96kS/s coefficients */
+ -BPF_Fs96000_Fc55_B2,
+ -BPF_Fs96000_Fc55_B1},
+ {BPF_Fs192000_Fc55_A0, /* 192kS/s coefficients */
+ -BPF_Fs192000_Fc55_B2,
+ -BPF_Fs192000_Fc55_B1},
+#endif
/* Coefficients for 66Hz centre frequency */
{BPF_Fs8000_Fc66_A0, /* 8kS/s coefficients */
@@ -286,6 +356,14 @@
{BPF_Fs48000_Fc66_A0, /* 48kS/s coefficients */
-BPF_Fs48000_Fc66_B2,
-BPF_Fs48000_Fc66_B1},
+#ifdef HIGHER_FS
+ {BPF_Fs96000_Fc66_A0, /* 96kS/s coefficients */
+ -BPF_Fs96000_Fc66_B2,
+ -BPF_Fs96000_Fc66_B1},
+ {BPF_Fs192000_Fc66_A0, /* 192kS/s coefficients */
+ -BPF_Fs192000_Fc66_B2,
+ -BPF_Fs192000_Fc66_B1},
+#endif
/* Coefficients for 78Hz centre frequency */
{BPF_Fs8000_Fc78_A0, /* 8kS/s coefficients */
@@ -315,6 +393,14 @@
{BPF_Fs48000_Fc78_A0, /* 48kS/s coefficients */
-BPF_Fs48000_Fc78_B2,
-BPF_Fs48000_Fc78_B1},
+#ifdef HIGHER_FS
+ {BPF_Fs96000_Fc78_A0, /* 96kS/s coefficients */
+ -BPF_Fs96000_Fc78_B2,
+ -BPF_Fs96000_Fc78_B1},
+ {BPF_Fs192000_Fc78_A0, /* 192kS/s coefficients */
+ -BPF_Fs192000_Fc78_B2,
+ -BPF_Fs192000_Fc78_B1},
+#endif
/* Coefficients for 90Hz centre frequency */
{BPF_Fs8000_Fc90_A0, /* 8kS/s coefficients */
@@ -343,7 +429,19 @@
-BPF_Fs44100_Fc90_B1},
{BPF_Fs48000_Fc90_A0, /* 48kS/s coefficients */
-BPF_Fs48000_Fc90_B2,
- -BPF_Fs48000_Fc90_B1}};
+ -BPF_Fs48000_Fc90_B1}
+#ifdef HIGHER_FS
+ ,
+ {BPF_Fs96000_Fc90_A0, /* 96kS/s coefficients */
+ -BPF_Fs96000_Fc90_B2,
+ -BPF_Fs96000_Fc90_B1},
+ {BPF_Fs192000_Fc90_A0, /* 192kS/s coefficients */
+ -BPF_Fs192000_Fc90_B2,
+ -BPF_Fs192000_Fc90_B1}
+#endif
+
+
+};
/************************************************************************************/
@@ -353,7 +451,11 @@
/************************************************************************************/
/* Attack time (signal too large) */
+#ifndef BUILD_FLOAT
const LVM_INT16 LVDBE_AGC_ATTACK_Table[] = {
+#else /*BUILD_FLOAT*/
+const LVM_FLOAT LVDBE_AGC_ATTACK_Table[] = {
+#endif /*BUILD_FLOAT*/
AGC_ATTACK_Fs8000,
AGC_ATTACK_Fs11025,
AGC_ATTACK_Fs12000,
@@ -362,10 +464,20 @@
AGC_ATTACK_Fs24000,
AGC_ATTACK_Fs32000,
AGC_ATTACK_Fs44100,
- AGC_ATTACK_Fs48000};
+ AGC_ATTACK_Fs48000
+#ifdef HIGHER_FS
+ ,AGC_ATTACK_Fs96000
+ ,AGC_ATTACK_Fs192000
+#endif
+
+};
/* Decay time (signal too small) */
+#ifndef BUILD_FLOAT
const LVM_INT16 LVDBE_AGC_DECAY_Table[] = {
+#else /*BUILD_FLOAT*/
+const LVM_FLOAT LVDBE_AGC_DECAY_Table[] = {
+#endif /*BUILD_FLOAT*/
AGC_DECAY_Fs8000,
AGC_DECAY_Fs11025,
AGC_DECAY_Fs12000,
@@ -374,10 +486,20 @@
AGC_DECAY_Fs24000,
AGC_DECAY_Fs32000,
AGC_DECAY_Fs44100,
- AGC_DECAY_Fs48000};
+ AGC_DECAY_Fs48000
+#ifdef HIGHER_FS
+ ,AGC_DECAY_FS96000
+ ,AGC_DECAY_FS192000
+#endif
+
+};
/* Gain for use without the high pass filter */
+#ifndef BUILD_FLOAT
const LVM_INT32 LVDBE_AGC_GAIN_Table[] = {
+#else /*BUILD_FLOAT*/
+const LVM_FLOAT LVDBE_AGC_GAIN_Table[] = {
+#endif /*BUILD_FLOAT*/
AGC_GAIN_0dB,
AGC_GAIN_1dB,
AGC_GAIN_2dB,
@@ -396,7 +518,11 @@
AGC_GAIN_15dB};
/* Gain for use with the high pass filter */
+#ifndef BUILD_FLOAT
const LVM_INT32 LVDBE_AGC_HPFGAIN_Table[] = {
+#else /*BUILD_FLOAT*/
+const LVM_FLOAT LVDBE_AGC_HPFGAIN_Table[] = {
+#endif /*BUILD_FLOAT*/
AGC_HPFGAIN_0dB,
AGC_HPFGAIN_1dB,
AGC_HPFGAIN_2dB,
@@ -422,6 +548,7 @@
/************************************************************************************/
/* dB to linear conversion table */
+#ifndef BUILD_FLOAT
const LVM_INT16 LVDBE_VolumeTable[] = {
0x4000, /* -6dB */
0x47FB, /* -5dB */
@@ -430,8 +557,22 @@
0x65AD, /* -2dB */
0x7215, /* -1dB */
0x7FFF}; /* 0dB */
+#else /*BUILD_FLOAT*/
+const LVM_FLOAT LVDBE_VolumeTable[] = {
+ 0.500000f, /* -6dB */
+ 0.562341f, /* -5dB */
+ 0.630957f, /* -4dB */
+ 0.707946f, /* -3dB */
+ 0.794328f, /* -2dB */
+ 0.891251f, /* -1dB */
+ 1.000000f}; /* 0dB */
+#endif /*BUILD_FLOAT*/
+#ifndef BUILD_FLOAT
const LVM_INT16 LVDBE_VolumeTCTable[] = {
+#else /*BUILD_FLOAT*/
+const LVM_FLOAT LVDBE_VolumeTCTable[] = {
+#endif /*BUILD_FLOAT*/
VOL_TC_Fs8000,
VOL_TC_Fs11025,
VOL_TC_Fs12000,
@@ -440,9 +581,17 @@
VOL_TC_Fs24000,
VOL_TC_Fs32000,
VOL_TC_Fs44100,
- VOL_TC_Fs48000};
+ VOL_TC_Fs48000
+#ifdef HIGHER_FS
+ ,VOL_TC_Fs96000
+ ,VOL_TC_Fs192000
+#endif
+};
+
+
const LVM_INT16 LVDBE_MixerTCTable[] = {
+
MIX_TC_Fs8000,
MIX_TC_Fs11025,
MIX_TC_Fs12000,
@@ -451,6 +600,10 @@
MIX_TC_Fs24000,
MIX_TC_Fs32000,
MIX_TC_Fs44100,
- MIX_TC_Fs48000};
+ MIX_TC_Fs48000
+#ifdef HIGHER_FS
+ ,MIX_TC_Fs96000
+ ,MIX_TC_Fs192000
+#endif
-
+};
diff --git a/media/libeffects/lvm/lib/Bass/src/LVDBE_Tables.h b/media/libeffects/lvm/lib/Bass/src/LVDBE_Tables.h
index 476e6a0..ca46e37 100644
--- a/media/libeffects/lvm/lib/Bass/src/LVDBE_Tables.h
+++ b/media/libeffects/lvm/lib/Bass/src/LVDBE_Tables.h
@@ -31,6 +31,7 @@
#include "BIQUAD.h"
#include "LVM_Types.h"
+#ifndef BUILD_FLOAT
/************************************************************************************/
/* */
/* Coefficients constant table */
@@ -76,8 +77,57 @@
extern const LVM_INT16 LVDBE_VolumeTCTable[];
+#else /*BUILD_FLOAT*/
+
+/************************************************************************************/
+/* */
+/* Coefficients constant table */
+/* */
+/************************************************************************************/
+
+/*
+ * High Pass Filter Coefficient table
+ */
+extern const BQ_FLOAT_Coefs_t LVDBE_HPF_Table[];
+
+/*
+ * Band Pass Filter coefficient table
+ */
+extern const BP_FLOAT_Coefs_t LVDBE_BPF_Table[];
+
+/************************************************************************************/
+/* */
+/* AGC constant tables */
+/* */
+/************************************************************************************/
+
+/* Attack time (signal too large) */
+extern const LVM_FLOAT LVDBE_AGC_ATTACK_Table[];
+
+/* Decay time (signal too small) */
+extern const LVM_FLOAT LVDBE_AGC_DECAY_Table[];
+
+/* Gain for use without the high pass filter */
+extern const LVM_FLOAT LVDBE_AGC_GAIN_Table[];
+
+/* Gain for use with the high pass filter */
+extern const LVM_FLOAT LVDBE_AGC_HPFGAIN_Table[];
+
+/************************************************************************************/
+/* */
+/* Volume control gain and time constant tables */
+/* */
+/************************************************************************************/
+
+/* dB to linear conversion table */
+extern const LVM_FLOAT LVDBE_VolumeTable[];
+extern const LVM_FLOAT LVDBE_VolumeTCTable[];
+
+#endif /*BUILD_FLOAT*/
+
extern const LVM_INT16 LVDBE_MixerTCTable[];
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/media/libeffects/lvm/lib/Bundle/lib/LVM.h b/media/libeffects/lvm/lib/Bundle/lib/LVM.h
index 1ff2a2c..9b6da31 100644
--- a/media/libeffects/lvm/lib/Bundle/lib/LVM.h
+++ b/media/libeffects/lvm/lib/Bundle/lib/LVM.h
@@ -514,11 +514,19 @@
/* STEREO the number of sample pairs in the block */
/* */
/****************************************************************************************/
+#ifdef BUILD_FLOAT
+LVM_ReturnStatus_en LVM_Process(LVM_Handle_t hInstance,
+ const LVM_FLOAT *pInData,
+ LVM_FLOAT *pOutData,
+ LVM_UINT16 NumSamples,
+ LVM_UINT32 AudioTime);
+#else
LVM_ReturnStatus_en LVM_Process(LVM_Handle_t hInstance,
const LVM_INT16 *pInData,
LVM_INT16 *pOutData,
LVM_UINT16 NumSamples,
LVM_UINT32 AudioTime);
+#endif
/****************************************************************************************/
diff --git a/media/libeffects/lvm/lib/Bundle/src/LVM_Buffers.c b/media/libeffects/lvm/lib/Bundle/src/LVM_Buffers.c
index 6cbee7d..0a3c30e 100644
--- a/media/libeffects/lvm/lib/Bundle/src/LVM_Buffers.c
+++ b/media/libeffects/lvm/lib/Bundle/src/LVM_Buffers.c
@@ -48,7 +48,152 @@
/* NOTES: */
/* */
/****************************************************************************************/
+#ifdef BUILD_FLOAT
+void LVM_BufferManagedIn(LVM_Handle_t hInstance,
+ const LVM_FLOAT *pInData,
+ LVM_FLOAT **pToProcess,
+ LVM_FLOAT **pProcessed,
+ LVM_UINT16 *pNumSamples)
+{
+ LVM_INT16 SampleCount; /* Number of samples to be processed this call */
+ LVM_INT16 NumSamples; /* Number of samples in scratch buffer */
+ LVM_FLOAT *pStart;
+ LVM_Instance_t *pInstance = (LVM_Instance_t *)hInstance;
+ LVM_Buffer_t *pBuffer;
+ LVM_FLOAT *pDest;
+ LVM_INT16 NumChannels = 2;
+
+
+ /*
+ * Set the processing address pointers
+ */
+ pBuffer = pInstance->pBufferManagement;
+ pDest = pBuffer->pScratch;
+ *pToProcess = pBuffer->pScratch;
+ *pProcessed = pBuffer->pScratch;
+
+ /*
+ * Check if it is the first call of a block
+ */
+ if (pInstance->SamplesToProcess == 0)
+ {
+ /*
+ * First call for a new block of samples
+ */
+ pInstance->SamplesToProcess = (LVM_INT16)(*pNumSamples + pBuffer->InDelaySamples);
+ pInstance->pInputSamples = (LVM_FLOAT *)pInData;
+ pBuffer->BufferState = LVM_FIRSTCALL;
+ }
+ pStart = pInstance->pInputSamples; /* Pointer to the input samples */
+ pBuffer->SamplesToOutput = 0; /* Samples to output is same as
+ number read for inplace processing */
+
+
+ /*
+ * Calculate the number of samples to process this call and update the buffer state
+ */
+ if (pInstance->SamplesToProcess > pInstance->InternalBlockSize)
+ {
+ /*
+ * Process the maximum bock size of samples.
+ */
+ SampleCount = pInstance->InternalBlockSize;
+ NumSamples = pInstance->InternalBlockSize;
+ }
+ else
+ {
+ /*
+ * Last call for the block, so calculate how many frames and samples to process
+ */
+ LVM_INT16 NumFrames;
+
+ NumSamples = pInstance->SamplesToProcess;
+ NumFrames = (LVM_INT16)(NumSamples >> MIN_INTERNAL_BLOCKSHIFT);
+ SampleCount = (LVM_INT16)(NumFrames << MIN_INTERNAL_BLOCKSHIFT);
+
+ /*
+ * Update the buffer state
+ */
+ if (pBuffer->BufferState == LVM_FIRSTCALL)
+ {
+ pBuffer->BufferState = LVM_FIRSTLASTCALL;
+ }
+ else
+ {
+ pBuffer->BufferState = LVM_LASTCALL;
+ }
+ }
+ *pNumSamples = (LVM_UINT16)SampleCount; /* Set the number of samples to process this call */
+
+
+ /*
+ * Copy samples from the delay buffer as required
+ */
+ if (((pBuffer->BufferState == LVM_FIRSTCALL) ||
+ (pBuffer->BufferState == LVM_FIRSTLASTCALL)) &&
+ (pBuffer->InDelaySamples != 0))
+ {
+ Copy_Float(&pBuffer->InDelayBuffer[0], /* Source */
+ pDest, /* Destination */
+ (LVM_INT16)(NumChannels * pBuffer->InDelaySamples)); /* Number of delay \
+ samples, left and right */
+ NumSamples = (LVM_INT16)(NumSamples - pBuffer->InDelaySamples); /* Update sample count */
+ pDest += NumChannels * pBuffer->InDelaySamples; /* Update the destination pointer */
+ }
+
+
+ /*
+ * Copy the rest of the samples for this call from the input buffer
+ */
+ if (NumSamples > 0)
+ {
+ Copy_Float(pStart, /* Source */
+ pDest, /* Destination */
+ (LVM_INT16)(NumChannels * NumSamples)); /* Number of input samples */
+ pStart += NumChannels * NumSamples; /* Update the input pointer */
+
+ /*
+ * Update the input data pointer and samples to output
+ */
+ /* Update samples to output */
+ pBuffer->SamplesToOutput = (LVM_INT16)(pBuffer->SamplesToOutput + NumSamples);
+ }
+
+
+ /*
+ * Update the sample count and input pointer
+ */
+ /* Update the count of samples */
+ pInstance->SamplesToProcess = (LVM_INT16)(pInstance->SamplesToProcess - SampleCount);
+ pInstance->pInputSamples = pStart; /* Update input sample pointer */
+
+
+ /*
+ * Save samples to the delay buffer if any left unprocessed
+ */
+ if ((pBuffer->BufferState == LVM_FIRSTLASTCALL) ||
+ (pBuffer->BufferState == LVM_LASTCALL))
+ {
+ NumSamples = pInstance->SamplesToProcess;
+ pStart = pBuffer->pScratch; /* Start of the buffer */
+ pStart += NumChannels * SampleCount; /* Offset by the number of processed samples */
+ if (NumSamples != 0)
+ {
+ Copy_Float(pStart, /* Source */
+ &pBuffer->InDelayBuffer[0], /* Destination */
+ (LVM_INT16)(NumChannels * NumSamples)); /* Number of input samples */
+ }
+
+
+ /*
+ * Update the delay sample count
+ */
+ pBuffer->InDelaySamples = NumSamples; /* Number of delay sample pairs */
+ pInstance->SamplesToProcess = 0; /* All Samples used */
+ }
+}
+#else
void LVM_BufferManagedIn(LVM_Handle_t hInstance,
const LVM_INT16 *pInData,
LVM_INT16 **pToProcess,
@@ -189,7 +334,7 @@
pInstance->SamplesToProcess = 0; /* All Samples used */
}
}
-
+#endif
/****************************************************************************************/
/* */
@@ -213,7 +358,47 @@
/* NOTES: */
/* */
/****************************************************************************************/
+#ifdef BUILD_FLOAT
+void LVM_BufferUnmanagedIn(LVM_Handle_t hInstance,
+ LVM_FLOAT **pToProcess,
+ LVM_FLOAT **pProcessed,
+ LVM_UINT16 *pNumSamples)
+{
+ LVM_Instance_t *pInstance = (LVM_Instance_t *)hInstance;
+
+
+ /*
+ * Check if this is the first call of a block
+ */
+ if (pInstance->SamplesToProcess == 0)
+ {
+ pInstance->SamplesToProcess = (LVM_INT16)*pNumSamples; /* Get the number of samples
+ on first call */
+ pInstance->pInputSamples = *pToProcess; /* Get the I/O pointers */
+ pInstance->pOutputSamples = *pProcessed;
+
+
+ /*
+ * Set te block size to process
+ */
+ if (pInstance->SamplesToProcess > pInstance->InternalBlockSize)
+ {
+ *pNumSamples = (LVM_UINT16)pInstance->InternalBlockSize;
+ }
+ else
+ {
+ *pNumSamples = (LVM_UINT16)pInstance->SamplesToProcess;
+ }
+ }
+
+ /*
+ * Set the process pointers
+ */
+ *pToProcess = pInstance->pInputSamples;
+ *pProcessed = pInstance->pOutputSamples;
+}
+#else
void LVM_BufferUnmanagedIn(LVM_Handle_t hInstance,
LVM_INT16 **pToProcess,
LVM_INT16 **pProcessed,
@@ -252,7 +437,7 @@
*pToProcess = pInstance->pInputSamples;
*pProcessed = pInstance->pOutputSamples;
}
-
+#endif
/****************************************************************************************/
/* */
@@ -278,6 +463,7 @@
/* */
/****************************************************************************************/
+#ifndef BUILD_FLOAT
void LVM_BufferOptimisedIn(LVM_Handle_t hInstance,
const LVM_INT16 *pInData,
LVM_INT16 **pToProcess,
@@ -416,7 +602,7 @@
}
}
}
-
+#endif
/****************************************************************************************/
/* */
/* FUNCTION: LVM_BufferIn */
@@ -471,7 +657,37 @@
/* NOTES: */
/* */
/****************************************************************************************/
+#ifdef BUILD_FLOAT
+void LVM_BufferIn(LVM_Handle_t hInstance,
+ const LVM_FLOAT *pInData,
+ LVM_FLOAT **pToProcess,
+ LVM_FLOAT **pProcessed,
+ LVM_UINT16 *pNumSamples)
+{
+ LVM_Instance_t *pInstance = (LVM_Instance_t *)hInstance;
+
+
+ /*
+ * Check which mode, managed or unmanaged
+ */
+ if (pInstance->InstParams.BufferMode == LVM_MANAGED_BUFFERS)
+ {
+ LVM_BufferManagedIn(hInstance,
+ pInData,
+ pToProcess,
+ pProcessed,
+ pNumSamples);
+ }
+ else
+ {
+ LVM_BufferUnmanagedIn(hInstance,
+ pToProcess,
+ pProcessed,
+ pNumSamples);
+ }
+}
+#else
void LVM_BufferIn(LVM_Handle_t hInstance,
const LVM_INT16 *pInData,
LVM_INT16 **pToProcess,
@@ -501,7 +717,7 @@
pNumSamples);
}
}
-
+#endif
/****************************************************************************************/
/* */
/* FUNCTION: LVM_BufferManagedOut */
@@ -522,7 +738,156 @@
/* NOTES: */
/* */
/****************************************************************************************/
+#ifdef BUILD_FLOAT
+void LVM_BufferManagedOut(LVM_Handle_t hInstance,
+ LVM_FLOAT *pOutData,
+ LVM_UINT16 *pNumSamples)
+{
+ LVM_Instance_t *pInstance = (LVM_Instance_t *)hInstance;
+ LVM_Buffer_t *pBuffer = pInstance->pBufferManagement;
+ LVM_INT16 SampleCount = (LVM_INT16)*pNumSamples;
+ LVM_INT16 NumSamples;
+ LVM_FLOAT *pStart;
+ LVM_FLOAT *pDest;
+
+
+ /*
+ * Set the pointers
+ */
+ NumSamples = pBuffer->SamplesToOutput;
+ pStart = pBuffer->pScratch;
+
+
+ /*
+ * check if it is the first call of a block
+ */
+ if ((pBuffer->BufferState == LVM_FIRSTCALL) ||
+ (pBuffer->BufferState == LVM_FIRSTLASTCALL))
+ {
+ /* First call for a new block */
+ pInstance->pOutputSamples = pOutData; /* Initialise the destination */
+ }
+ pDest = pInstance->pOutputSamples; /* Set the output address */
+
+
+ /*
+ * If the number of samples is non-zero then there are still samples to send to
+ * the output buffer
+ */
+ if ((NumSamples != 0) &&
+ (pBuffer->OutDelaySamples != 0))
+ {
+ /*
+ * Copy the delayed output buffer samples to the output
+ */
+ if (pBuffer->OutDelaySamples <= NumSamples)
+ {
+ /*
+ * Copy all output delay samples to the output
+ */
+ Copy_Float(&pBuffer->OutDelayBuffer[0], /* Source */
+ pDest, /* Detsination */
+ (LVM_INT16)(2 * pBuffer->OutDelaySamples)); /* Number of delay samples */
+
+ /*
+ * Update the pointer and sample counts
+ */
+ pDest += 2 * pBuffer->OutDelaySamples; /* Output sample pointer */
+ NumSamples = (LVM_INT16)(NumSamples - pBuffer->OutDelaySamples); /* Samples left \
+ to send */
+ pBuffer->OutDelaySamples = 0; /* No samples left in the buffer */
+ }
+ else
+ {
+ /*
+ * Copy only some of the ouput delay samples to the output
+ */
+ Copy_Float(&pBuffer->OutDelayBuffer[0], /* Source */
+ pDest, /* Detsination */
+ (LVM_INT16)(2 * NumSamples)); /* Number of delay samples */
+
+ /*
+ * Update the pointer and sample counts
+ */
+ pDest += 2 * NumSamples; /* Output sample pointer */
+ /* No samples left in the buffer */
+ pBuffer->OutDelaySamples = (LVM_INT16)(pBuffer->OutDelaySamples - NumSamples);
+
+ /*
+ * Realign the delay buffer data to avoid using circular buffer management
+ */
+ Copy_Float(&pBuffer->OutDelayBuffer[2 * NumSamples], /* Source */
+ &pBuffer->OutDelayBuffer[0], /* Destination */
+ (LVM_INT16)(2 * pBuffer->OutDelaySamples)); /* Number of samples to move */
+ NumSamples = 0; /* Samples left to send */
+ }
+ }
+
+
+ /*
+ * Copy the processed results to the output
+ */
+ if ((NumSamples != 0) &&
+ (SampleCount != 0))
+ {
+ if (SampleCount <= NumSamples)
+ {
+ /*
+ * Copy all processed samples to the output
+ */
+ Copy_Float(pStart, /* Source */
+ pDest, /* Detsination */
+ (LVM_INT16)(2 * SampleCount)); /* Number of processed samples */
+ /*
+ * Update the pointer and sample counts
+ */
+ pDest += 2 * SampleCount; /* Output sample pointer */
+ NumSamples = (LVM_INT16)(NumSamples - SampleCount); /* Samples left to send */
+ SampleCount = 0; /* No samples left in the buffer */
+ }
+ else
+ {
+ /*
+ * Copy only some processed samples to the output
+ */
+ Copy_Float(pStart, /* Source */
+ pDest, /* Destination */
+ (LVM_INT16)(2 * NumSamples)); /* Number of processed samples */
+ /*
+ * Update the pointers and sample counts
+ */
+ pStart += 2 * NumSamples; /* Processed sample pointer */
+ pDest += 2 * NumSamples; /* Output sample pointer */
+ SampleCount = (LVM_INT16)(SampleCount - NumSamples); /* Processed samples left */
+ NumSamples = 0; /* Clear the sample count */
+ }
+ }
+
+
+ /*
+ * Copy the remaining processed data to the output delay buffer
+ */
+ if (SampleCount != 0)
+ {
+ Copy_Float(pStart, /* Source */
+ &pBuffer->OutDelayBuffer[2 * pBuffer->OutDelaySamples], /* Destination */
+ (LVM_INT16)(2 * SampleCount)); /* Number of processed samples */
+ /* Update the buffer count */
+ pBuffer->OutDelaySamples = (LVM_INT16)(pBuffer->OutDelaySamples + SampleCount);
+ }
+
+ /*
+ * pointers, counts and set default buffer processing
+ */
+ pBuffer->SamplesToOutput = NumSamples; /* Samples left to send */
+ pInstance->pOutputSamples = pDest; /* Output sample pointer */
+ pBuffer->BufferState = LVM_MAXBLOCKCALL; /* Set for the default call \
+ block size */
+ /* This will terminate the loop when all samples processed */
+ *pNumSamples = (LVM_UINT16)pInstance->SamplesToProcess;
+}
+#else
void LVM_BufferManagedOut(LVM_Handle_t hInstance,
LVM_INT16 *pOutData,
LVM_UINT16 *pNumSamples)
@@ -672,7 +1037,7 @@
pBuffer->BufferState = LVM_MAXBLOCKCALL; /* Set for the default call block size */
*pNumSamples = (LVM_UINT16)pInstance->SamplesToProcess; /* This will terminate the loop when all samples processed */
}
-
+#endif
/****************************************************************************************/
/* */
@@ -741,6 +1106,7 @@
/* */
/****************************************************************************************/
+#ifndef BUILD_FLOAT
void LVM_BufferOptimisedOut(LVM_Handle_t hInstance,
LVM_UINT16 *pNumSamples)
{
@@ -805,7 +1171,7 @@
}
}
}
-
+#endif
/****************************************************************************************/
/* */
@@ -843,7 +1209,31 @@
/* NOTES: */
/* */
/****************************************************************************************/
+#ifdef BUILD_FLOAT
+void LVM_BufferOut(LVM_Handle_t hInstance,
+ LVM_FLOAT *pOutData,
+ LVM_UINT16 *pNumSamples)
+{
+ LVM_Instance_t *pInstance = (LVM_Instance_t *)hInstance;
+
+
+ /*
+ * Check which mode, managed or unmanaged
+ */
+ if (pInstance->InstParams.BufferMode == LVM_MANAGED_BUFFERS)
+ {
+ LVM_BufferManagedOut(hInstance,
+ pOutData,
+ pNumSamples);
+ }
+ else
+ {
+ LVM_BufferUnmanagedOut(hInstance,
+ pNumSamples);
+ }
+}
+#else
void LVM_BufferOut(LVM_Handle_t hInstance,
LVM_INT16 *pOutData,
LVM_UINT16 *pNumSamples)
@@ -867,4 +1257,4 @@
pNumSamples);
}
}
-
+#endif
diff --git a/media/libeffects/lvm/lib/Bundle/src/LVM_Coeffs.h b/media/libeffects/lvm/lib/Bundle/src/LVM_Coeffs.h
index 2712b2c..353560c 100644
--- a/media/libeffects/lvm/lib/Bundle/src/LVM_Coeffs.h
+++ b/media/libeffects/lvm/lib/Bundle/src/LVM_Coeffs.h
@@ -26,10 +26,655 @@
/************************************************************************************/
#define TrebleBoostCorner 8000
-#define TrebleBoostMinRate 4
-#define TrebleBoostSteps 15
+#define TrebleBoostMinRate 4
+#define TrebleBoostSteps 15
+#ifdef BUILD_FLOAT
+/* Coefficients for sample rate 22050Hz */
+ /* Gain = 1.000000 dB */
+#define HPF_Fs22050_Gain1_A0 1.038434
+#define HPF_Fs22050_Gain1_A1 0.331599
+#define HPF_Fs22050_Gain1_A2 0.000000
+#define HPF_Fs22050_Gain1_B1 0.370033
+#define HPF_Fs22050_Gain1_B2 0.000000
+ /* Gain = 2.000000 dB */
+#define HPF_Fs22050_Gain2_A0 1.081557
+#define HPF_Fs22050_Gain2_A1 0.288475
+#define HPF_Fs22050_Gain2_A2 0.000000
+#define HPF_Fs22050_Gain2_B1 0.370033
+#define HPF_Fs22050_Gain2_B2 0.000000
+ /* Gain = 3.000000 dB */
+#define HPF_Fs22050_Gain3_A0 1.129943
+#define HPF_Fs22050_Gain3_A1 0.240090
+#define HPF_Fs22050_Gain3_A2 0.000000
+#define HPF_Fs22050_Gain3_B1 0.370033
+#define HPF_Fs22050_Gain3_B2 0.000000
+ /* Gain = 4.000000 dB */
+#define HPF_Fs22050_Gain4_A0 1.184232
+#define HPF_Fs22050_Gain4_A1 0.185801
+#define HPF_Fs22050_Gain4_A2 0.000000
+#define HPF_Fs22050_Gain4_B1 0.370033
+#define HPF_Fs22050_Gain4_B2 0.000000
+ /* Gain = 5.000000 dB */
+#define HPF_Fs22050_Gain5_A0 1.245145
+#define HPF_Fs22050_Gain5_A1 0.124887
+#define HPF_Fs22050_Gain5_A2 0.000000
+#define HPF_Fs22050_Gain5_B1 0.370033
+#define HPF_Fs22050_Gain5_B2 0.000000
+ /* Gain = 6.000000 dB */
+#define HPF_Fs22050_Gain6_A0 1.313491
+#define HPF_Fs22050_Gain6_A1 0.056541
+#define HPF_Fs22050_Gain6_A2 0.000000
+#define HPF_Fs22050_Gain6_B1 0.370033
+#define HPF_Fs22050_Gain6_B2 0.000000
+ /* Gain = 7.000000 dB */
+#define HPF_Fs22050_Gain7_A0 1.390177
+#define HPF_Fs22050_Gain7_A1 -0.020144
+#define HPF_Fs22050_Gain7_A2 0.000000
+#define HPF_Fs22050_Gain7_B1 0.370033
+#define HPF_Fs22050_Gain7_B2 0.000000
+ /* Gain = 8.000000 dB */
+#define HPF_Fs22050_Gain8_A0 1.476219
+#define HPF_Fs22050_Gain8_A1 -0.106187
+#define HPF_Fs22050_Gain8_A2 0.000000
+#define HPF_Fs22050_Gain8_B1 0.370033
+#define HPF_Fs22050_Gain8_B2 0.000000
+ /* Gain = 9.000000 dB */
+#define HPF_Fs22050_Gain9_A0 1.572761
+#define HPF_Fs22050_Gain9_A1 -0.202728
+#define HPF_Fs22050_Gain9_A2 0.000000
+#define HPF_Fs22050_Gain9_B1 0.370033
+#define HPF_Fs22050_Gain9_B2 0.000000
+ /* Gain = 10.000000 dB */
+#define HPF_Fs22050_Gain10_A0 1.681082
+#define HPF_Fs22050_Gain10_A1 -0.311049
+#define HPF_Fs22050_Gain10_A2 0.000000
+#define HPF_Fs22050_Gain10_B1 0.370033
+#define HPF_Fs22050_Gain10_B2 0.000000
+ /* Gain = 11.000000 dB */
+#define HPF_Fs22050_Gain11_A0 1.802620
+#define HPF_Fs22050_Gain11_A1 -0.432588
+#define HPF_Fs22050_Gain11_A2 0.000000
+#define HPF_Fs22050_Gain11_B1 0.370033
+#define HPF_Fs22050_Gain11_B2 0.000000
+ /* Gain = 12.000000 dB */
+#define HPF_Fs22050_Gain12_A0 1.938989
+#define HPF_Fs22050_Gain12_A1 -0.568956
+#define HPF_Fs22050_Gain12_A2 0.000000
+#define HPF_Fs22050_Gain12_B1 0.370033
+#define HPF_Fs22050_Gain12_B2 0.000000
+ /* Gain = 13.000000 dB */
+#define HPF_Fs22050_Gain13_A0 2.091997
+#define HPF_Fs22050_Gain13_A1 -0.721964
+#define HPF_Fs22050_Gain13_A2 0.000000
+#define HPF_Fs22050_Gain13_B1 0.370033
+#define HPF_Fs22050_Gain13_B2 0.000000
+ /* Gain = 14.000000 dB */
+#define HPF_Fs22050_Gain14_A0 2.263674
+#define HPF_Fs22050_Gain14_A1 -0.893641
+#define HPF_Fs22050_Gain14_A2 0.000000
+#define HPF_Fs22050_Gain14_B1 0.370033
+#define HPF_Fs22050_Gain14_B2 0.000000
+ /* Gain = 15.000000 dB */
+#define HPF_Fs22050_Gain15_A0 2.456300
+#define HPF_Fs22050_Gain15_A1 -1.086267
+#define HPF_Fs22050_Gain15_A2 0.000000
+#define HPF_Fs22050_Gain15_B1 0.370033
+#define HPF_Fs22050_Gain15_B2 0.000000
+/* Coefficients for sample rate 24000Hz */
+ /* Gain = 1.000000 dB */
+#define HPF_Fs24000_Gain1_A0 1.044662
+#define HPF_Fs24000_Gain1_A1 0.223287
+#define HPF_Fs24000_Gain1_A2 0.000000
+#define HPF_Fs24000_Gain1_B1 0.267949
+#define HPF_Fs24000_Gain1_B2 0.000000
+ /* Gain = 2.000000 dB */
+#define HPF_Fs24000_Gain2_A0 1.094773
+#define HPF_Fs24000_Gain2_A1 0.173176
+#define HPF_Fs24000_Gain2_A2 0.000000
+#define HPF_Fs24000_Gain2_B1 0.267949
+#define HPF_Fs24000_Gain2_B2 0.000000
+ /* Gain = 3.000000 dB */
+#define HPF_Fs24000_Gain3_A0 1.150999
+#define HPF_Fs24000_Gain3_A1 0.116950
+#define HPF_Fs24000_Gain3_A2 0.000000
+#define HPF_Fs24000_Gain3_B1 0.267949
+#define HPF_Fs24000_Gain3_B2 0.000000
+ /* Gain = 4.000000 dB */
+#define HPF_Fs24000_Gain4_A0 1.214086
+#define HPF_Fs24000_Gain4_A1 0.053863
+#define HPF_Fs24000_Gain4_A2 0.000000
+#define HPF_Fs24000_Gain4_B1 0.267949
+#define HPF_Fs24000_Gain4_B2 0.000000
+ /* Gain = 5.000000 dB */
+#define HPF_Fs24000_Gain5_A0 1.284870
+#define HPF_Fs24000_Gain5_A1 -0.016921
+#define HPF_Fs24000_Gain5_A2 0.000000
+#define HPF_Fs24000_Gain5_B1 0.267949
+#define HPF_Fs24000_Gain5_B2 0.000000
+ /* Gain = 6.000000 dB */
+#define HPF_Fs24000_Gain6_A0 1.364291
+#define HPF_Fs24000_Gain6_A1 -0.096342
+#define HPF_Fs24000_Gain6_A2 0.000000
+#define HPF_Fs24000_Gain6_B1 0.267949
+#define HPF_Fs24000_Gain6_B2 0.000000
+ /* Gain = 7.000000 dB */
+#define HPF_Fs24000_Gain7_A0 1.453403
+#define HPF_Fs24000_Gain7_A1 -0.185454
+#define HPF_Fs24000_Gain7_A2 0.000000
+#define HPF_Fs24000_Gain7_B1 0.267949
+#define HPF_Fs24000_Gain7_B2 0.000000
+ /* Gain = 8.000000 dB */
+#define HPF_Fs24000_Gain8_A0 1.553389
+#define HPF_Fs24000_Gain8_A1 -0.285440
+#define HPF_Fs24000_Gain8_A2 0.000000
+#define HPF_Fs24000_Gain8_B1 0.267949
+#define HPF_Fs24000_Gain8_B2 0.000000
+ /* Gain = 9.000000 dB */
+#define HPF_Fs24000_Gain9_A0 1.665574
+#define HPF_Fs24000_Gain9_A1 -0.397625
+#define HPF_Fs24000_Gain9_A2 0.000000
+#define HPF_Fs24000_Gain9_B1 0.267949
+#define HPF_Fs24000_Gain9_B2 0.000000
+ /* Gain = 10.000000 dB */
+#define HPF_Fs24000_Gain10_A0 1.791449
+#define HPF_Fs24000_Gain10_A1 -0.523499
+#define HPF_Fs24000_Gain10_A2 0.000000
+#define HPF_Fs24000_Gain10_B1 0.267949
+#define HPF_Fs24000_Gain10_B2 0.000000
+ /* Gain = 11.000000 dB */
+#define HPF_Fs24000_Gain11_A0 1.932682
+#define HPF_Fs24000_Gain11_A1 -0.664733
+#define HPF_Fs24000_Gain11_A2 0.000000
+#define HPF_Fs24000_Gain11_B1 0.267949
+#define HPF_Fs24000_Gain11_B2 0.000000
+ /* Gain = 12.000000 dB */
+#define HPF_Fs24000_Gain12_A0 2.091148
+#define HPF_Fs24000_Gain12_A1 -0.823199
+#define HPF_Fs24000_Gain12_A2 0.000000
+#define HPF_Fs24000_Gain12_B1 0.267949
+#define HPF_Fs24000_Gain12_B2 0.000000
+ /* Gain = 13.000000 dB */
+#define HPF_Fs24000_Gain13_A0 2.268950
+#define HPF_Fs24000_Gain13_A1 -1.001001
+#define HPF_Fs24000_Gain13_A2 0.000000
+#define HPF_Fs24000_Gain13_B1 0.267949
+#define HPF_Fs24000_Gain13_B2 0.000000
+ /* Gain = 14.000000 dB */
+#define HPF_Fs24000_Gain14_A0 2.468447
+#define HPF_Fs24000_Gain14_A1 -1.200498
+#define HPF_Fs24000_Gain14_A2 0.000000
+#define HPF_Fs24000_Gain14_B1 0.267949
+#define HPF_Fs24000_Gain14_B2 0.000000
+ /* Gain = 15.000000 dB */
+#define HPF_Fs24000_Gain15_A0 2.692287
+#define HPF_Fs24000_Gain15_A1 -1.424338
+#define HPF_Fs24000_Gain15_A2 0.000000
+#define HPF_Fs24000_Gain15_B1 0.267949
+#define HPF_Fs24000_Gain15_B2 0.000000
+/* Coefficients for sample rate 32000Hz */
+ /* Gain = 1.000000 dB */
+#define HPF_Fs32000_Gain1_A0 1.061009
+#define HPF_Fs32000_Gain1_A1 -0.061009
+#define HPF_Fs32000_Gain1_A2 0.000000
+#define HPF_Fs32000_Gain1_B1 -0.000000
+#define HPF_Fs32000_Gain1_B2 0.000000
+ /* Gain = 2.000000 dB */
+#define HPF_Fs32000_Gain2_A0 1.129463
+#define HPF_Fs32000_Gain2_A1 -0.129463
+#define HPF_Fs32000_Gain2_A2 0.000000
+#define HPF_Fs32000_Gain2_B1 -0.000000
+#define HPF_Fs32000_Gain2_B2 0.000000
+ /* Gain = 3.000000 dB */
+#define HPF_Fs32000_Gain3_A0 1.206267
+#define HPF_Fs32000_Gain3_A1 -0.206267
+#define HPF_Fs32000_Gain3_A2 0.000000
+#define HPF_Fs32000_Gain3_B1 -0.000000
+#define HPF_Fs32000_Gain3_B2 0.000000
+ /* Gain = 4.000000 dB */
+#define HPF_Fs32000_Gain4_A0 1.292447
+#define HPF_Fs32000_Gain4_A1 -0.292447
+#define HPF_Fs32000_Gain4_A2 0.000000
+#define HPF_Fs32000_Gain4_B1 -0.000000
+#define HPF_Fs32000_Gain4_B2 0.000000
+ /* Gain = 5.000000 dB */
+#define HPF_Fs32000_Gain5_A0 1.389140
+#define HPF_Fs32000_Gain5_A1 -0.389140
+#define HPF_Fs32000_Gain5_A2 0.000000
+#define HPF_Fs32000_Gain5_B1 -0.000000
+#define HPF_Fs32000_Gain5_B2 0.000000
+ /* Gain = 6.000000 dB */
+#define HPF_Fs32000_Gain6_A0 1.497631
+#define HPF_Fs32000_Gain6_A1 -0.497631
+#define HPF_Fs32000_Gain6_A2 0.000000
+#define HPF_Fs32000_Gain6_B1 -0.000000
+#define HPF_Fs32000_Gain6_B2 0.000000
+ /* Gain = 7.000000 dB */
+#define HPF_Fs32000_Gain7_A0 1.619361
+#define HPF_Fs32000_Gain7_A1 -0.619361
+#define HPF_Fs32000_Gain7_A2 0.000000
+#define HPF_Fs32000_Gain7_B1 -0.000000
+#define HPF_Fs32000_Gain7_B2 0.000000
+ /* Gain = 8.000000 dB */
+#define HPF_Fs32000_Gain8_A0 1.755943
+#define HPF_Fs32000_Gain8_A1 -0.755943
+#define HPF_Fs32000_Gain8_A2 0.000000
+#define HPF_Fs32000_Gain8_B1 -0.000000
+#define HPF_Fs32000_Gain8_B2 0.000000
+ /* Gain = 9.000000 dB */
+#define HPF_Fs32000_Gain9_A0 1.909191
+#define HPF_Fs32000_Gain9_A1 -0.909191
+#define HPF_Fs32000_Gain9_A2 0.000000
+#define HPF_Fs32000_Gain9_B1 -0.000000
+#define HPF_Fs32000_Gain9_B2 0.000000
+ /* Gain = 10.000000 dB */
+#define HPF_Fs32000_Gain10_A0 2.081139
+#define HPF_Fs32000_Gain10_A1 -1.081139
+#define HPF_Fs32000_Gain10_A2 0.000000
+#define HPF_Fs32000_Gain10_B1 -0.000000
+#define HPF_Fs32000_Gain10_B2 0.000000
+ /* Gain = 11.000000 dB */
+#define HPF_Fs32000_Gain11_A0 2.274067
+#define HPF_Fs32000_Gain11_A1 -1.274067
+#define HPF_Fs32000_Gain11_A2 0.000000
+#define HPF_Fs32000_Gain11_B1 -0.000000
+#define HPF_Fs32000_Gain11_B2 0.000000
+ /* Gain = 12.000000 dB */
+#define HPF_Fs32000_Gain12_A0 2.490536
+#define HPF_Fs32000_Gain12_A1 -1.490536
+#define HPF_Fs32000_Gain12_A2 0.000000
+#define HPF_Fs32000_Gain12_B1 -0.000000
+#define HPF_Fs32000_Gain12_B2 0.000000
+ /* Gain = 13.000000 dB */
+#define HPF_Fs32000_Gain13_A0 2.733418
+#define HPF_Fs32000_Gain13_A1 -1.733418
+#define HPF_Fs32000_Gain13_A2 0.000000
+#define HPF_Fs32000_Gain13_B1 -0.000000
+#define HPF_Fs32000_Gain13_B2 0.000000
+ /* Gain = 14.000000 dB */
+#define HPF_Fs32000_Gain14_A0 3.005936
+#define HPF_Fs32000_Gain14_A1 -2.005936
+#define HPF_Fs32000_Gain14_A2 0.000000
+#define HPF_Fs32000_Gain14_B1 -0.000000
+#define HPF_Fs32000_Gain14_B2 0.000000
+ /* Gain = 15.000000 dB */
+#define HPF_Fs32000_Gain15_A0 3.311707
+#define HPF_Fs32000_Gain15_A1 -2.311707
+#define HPF_Fs32000_Gain15_A2 0.000000
+#define HPF_Fs32000_Gain15_B1 -0.000000
+#define HPF_Fs32000_Gain15_B2 0.000000
+/* Coefficients for sample rate 44100Hz */
+ /* Gain = 1.000000 dB */
+#define HPF_Fs44100_Gain1_A0 1.074364
+#define HPF_Fs44100_Gain1_A1 -0.293257
+#define HPF_Fs44100_Gain1_A2 0.000000
+#define HPF_Fs44100_Gain1_B1 -0.218894
+#define HPF_Fs44100_Gain1_B2 0.000000
+ /* Gain = 2.000000 dB */
+#define HPF_Fs44100_Gain2_A0 1.157801
+#define HPF_Fs44100_Gain2_A1 -0.376695
+#define HPF_Fs44100_Gain2_A2 0.000000
+#define HPF_Fs44100_Gain2_B1 -0.218894
+#define HPF_Fs44100_Gain2_B2 0.000000
+ /* Gain = 3.000000 dB */
+#define HPF_Fs44100_Gain3_A0 1.251420
+#define HPF_Fs44100_Gain3_A1 -0.470313
+#define HPF_Fs44100_Gain3_A2 0.000000
+#define HPF_Fs44100_Gain3_B1 -0.218894
+#define HPF_Fs44100_Gain3_B2 0.000000
+ /* Gain = 4.000000 dB */
+#define HPF_Fs44100_Gain4_A0 1.356461
+#define HPF_Fs44100_Gain4_A1 -0.575355
+#define HPF_Fs44100_Gain4_A2 0.000000
+#define HPF_Fs44100_Gain4_B1 -0.218894
+#define HPF_Fs44100_Gain4_B2 0.000000
+ /* Gain = 5.000000 dB */
+#define HPF_Fs44100_Gain5_A0 1.474320
+#define HPF_Fs44100_Gain5_A1 -0.693213
+#define HPF_Fs44100_Gain5_A2 0.000000
+#define HPF_Fs44100_Gain5_B1 -0.218894
+#define HPF_Fs44100_Gain5_B2 0.000000
+ /* Gain = 6.000000 dB */
+#define HPF_Fs44100_Gain6_A0 1.606559
+#define HPF_Fs44100_Gain6_A1 -0.825453
+#define HPF_Fs44100_Gain6_A2 0.000000
+#define HPF_Fs44100_Gain6_B1 -0.218894
+#define HPF_Fs44100_Gain6_B2 0.000000
+ /* Gain = 7.000000 dB */
+#define HPF_Fs44100_Gain7_A0 1.754935
+#define HPF_Fs44100_Gain7_A1 -0.973828
+#define HPF_Fs44100_Gain7_A2 0.000000
+#define HPF_Fs44100_Gain7_B1 -0.218894
+#define HPF_Fs44100_Gain7_B2 0.000000
+ /* Gain = 8.000000 dB */
+#define HPF_Fs44100_Gain8_A0 1.921414
+#define HPF_Fs44100_Gain8_A1 -1.140308
+#define HPF_Fs44100_Gain8_A2 0.000000
+#define HPF_Fs44100_Gain8_B1 -0.218894
+#define HPF_Fs44100_Gain8_B2 0.000000
+ /* Gain = 9.000000 dB */
+#define HPF_Fs44100_Gain9_A0 2.108208
+#define HPF_Fs44100_Gain9_A1 -1.327101
+#define HPF_Fs44100_Gain9_A2 0.000000
+#define HPF_Fs44100_Gain9_B1 -0.218894
+#define HPF_Fs44100_Gain9_B2 0.000000
+ /* Gain = 10.000000 dB */
+#define HPF_Fs44100_Gain10_A0 2.317793
+#define HPF_Fs44100_Gain10_A1 -1.536687
+#define HPF_Fs44100_Gain10_A2 0.000000
+#define HPF_Fs44100_Gain10_B1 -0.218894
+#define HPF_Fs44100_Gain10_B2 0.000000
+ /* Gain = 11.000000 dB */
+#define HPF_Fs44100_Gain11_A0 2.552952
+#define HPF_Fs44100_Gain11_A1 -1.771846
+#define HPF_Fs44100_Gain11_A2 0.000000
+#define HPF_Fs44100_Gain11_B1 -0.218894
+#define HPF_Fs44100_Gain11_B2 0.000000
+ /* Gain = 12.000000 dB */
+#define HPF_Fs44100_Gain12_A0 2.816805
+#define HPF_Fs44100_Gain12_A1 -2.035698
+#define HPF_Fs44100_Gain12_A2 0.000000
+#define HPF_Fs44100_Gain12_B1 -0.218894
+#define HPF_Fs44100_Gain12_B2 0.000000
+ /* Gain = 13.000000 dB */
+#define HPF_Fs44100_Gain13_A0 3.112852
+#define HPF_Fs44100_Gain13_A1 -2.331746
+#define HPF_Fs44100_Gain13_A2 0.000000
+#define HPF_Fs44100_Gain13_B1 -0.218894
+#define HPF_Fs44100_Gain13_B2 0.000000
+ /* Gain = 14.000000 dB */
+#define HPF_Fs44100_Gain14_A0 3.445023
+#define HPF_Fs44100_Gain14_A1 -2.663916
+#define HPF_Fs44100_Gain14_A2 0.000000
+#define HPF_Fs44100_Gain14_B1 -0.218894
+#define HPF_Fs44100_Gain14_B2 0.000000
+ /* Gain = 15.000000 dB */
+#define HPF_Fs44100_Gain15_A0 3.817724
+#define HPF_Fs44100_Gain15_A1 -3.036618
+#define HPF_Fs44100_Gain15_A2 0.000000
+#define HPF_Fs44100_Gain15_B1 -0.218894
+#define HPF_Fs44100_Gain15_B2 0.000000
+/* Coefficients for sample rate 48000Hz */
+ /* Gain = 1.000000 dB */
+#define HPF_Fs48000_Gain1_A0 1.077357
+#define HPF_Fs48000_Gain1_A1 -0.345306
+#define HPF_Fs48000_Gain1_A2 0.000000
+#define HPF_Fs48000_Gain1_B1 -0.267949
+#define HPF_Fs48000_Gain1_B2 0.000000
+ /* Gain = 2.000000 dB */
+#define HPF_Fs48000_Gain2_A0 1.164152
+#define HPF_Fs48000_Gain2_A1 -0.432101
+#define HPF_Fs48000_Gain2_A2 0.000000
+#define HPF_Fs48000_Gain2_B1 -0.267949
+#define HPF_Fs48000_Gain2_B2 0.000000
+ /* Gain = 3.000000 dB */
+#define HPF_Fs48000_Gain3_A0 1.261538
+#define HPF_Fs48000_Gain3_A1 -0.529488
+#define HPF_Fs48000_Gain3_A2 0.000000
+#define HPF_Fs48000_Gain3_B1 -0.267949
+#define HPF_Fs48000_Gain3_B2 0.000000
+ /* Gain = 4.000000 dB */
+#define HPF_Fs48000_Gain4_A0 1.370807
+#define HPF_Fs48000_Gain4_A1 -0.638757
+#define HPF_Fs48000_Gain4_A2 0.000000
+#define HPF_Fs48000_Gain4_B1 -0.267949
+#define HPF_Fs48000_Gain4_B2 0.000000
+ /* Gain = 5.000000 dB */
+#define HPF_Fs48000_Gain5_A0 1.493409
+#define HPF_Fs48000_Gain5_A1 -0.761359
+#define HPF_Fs48000_Gain5_A2 0.000000
+#define HPF_Fs48000_Gain5_B1 -0.267949
+#define HPF_Fs48000_Gain5_B2 0.000000
+ /* Gain = 6.000000 dB */
+#define HPF_Fs48000_Gain6_A0 1.630971
+#define HPF_Fs48000_Gain6_A1 -0.898920
+#define HPF_Fs48000_Gain6_A2 0.000000
+#define HPF_Fs48000_Gain6_B1 -0.267949
+#define HPF_Fs48000_Gain6_B2 0.000000
+ /* Gain = 7.000000 dB */
+#define HPF_Fs48000_Gain7_A0 1.785318
+#define HPF_Fs48000_Gain7_A1 -1.053267
+#define HPF_Fs48000_Gain7_A2 0.000000
+#define HPF_Fs48000_Gain7_B1 -0.267949
+#define HPF_Fs48000_Gain7_B2 0.000000
+ /* Gain = 8.000000 dB */
+#define HPF_Fs48000_Gain8_A0 1.958498
+#define HPF_Fs48000_Gain8_A1 -1.226447
+#define HPF_Fs48000_Gain8_A2 0.000000
+#define HPF_Fs48000_Gain8_B1 -0.267949
+#define HPF_Fs48000_Gain8_B2 0.000000
+ /* Gain = 9.000000 dB */
+#define HPF_Fs48000_Gain9_A0 2.152809
+#define HPF_Fs48000_Gain9_A1 -1.420758
+#define HPF_Fs48000_Gain9_A2 0.000000
+#define HPF_Fs48000_Gain9_B1 -0.267949
+#define HPF_Fs48000_Gain9_B2 0.000000
+ /* Gain = 10.000000 dB */
+#define HPF_Fs48000_Gain10_A0 2.370829
+#define HPF_Fs48000_Gain10_A1 -1.638778
+#define HPF_Fs48000_Gain10_A2 0.000000
+#define HPF_Fs48000_Gain10_B1 -0.267949
+#define HPF_Fs48000_Gain10_B2 0.000000
+ /* Gain = 11.000000 dB */
+#define HPF_Fs48000_Gain11_A0 2.615452
+#define HPF_Fs48000_Gain11_A1 -1.883401
+#define HPF_Fs48000_Gain11_A2 0.000000
+#define HPF_Fs48000_Gain11_B1 -0.267949
+#define HPF_Fs48000_Gain11_B2 0.000000
+ /* Gain = 12.000000 dB */
+#define HPF_Fs48000_Gain12_A0 2.889924
+#define HPF_Fs48000_Gain12_A1 -2.157873
+#define HPF_Fs48000_Gain12_A2 0.000000
+#define HPF_Fs48000_Gain12_B1 -0.267949
+#define HPF_Fs48000_Gain12_B2 0.000000
+ /* Gain = 13.000000 dB */
+#define HPF_Fs48000_Gain13_A0 3.197886
+#define HPF_Fs48000_Gain13_A1 -2.465835
+#define HPF_Fs48000_Gain13_A2 0.000000
+#define HPF_Fs48000_Gain13_B1 -0.267949
+#define HPF_Fs48000_Gain13_B2 0.000000
+ /* Gain = 14.000000 dB */
+#define HPF_Fs48000_Gain14_A0 3.543425
+#define HPF_Fs48000_Gain14_A1 -2.811374
+#define HPF_Fs48000_Gain14_A2 0.000000
+#define HPF_Fs48000_Gain14_B1 -0.267949
+#define HPF_Fs48000_Gain14_B2 0.000000
+ /* Gain = 15.000000 dB */
+#define HPF_Fs48000_Gain15_A0 3.931127
+#define HPF_Fs48000_Gain15_A1 -3.199076
+#define HPF_Fs48000_Gain15_A2 0.000000
+#define HPF_Fs48000_Gain15_B1 -0.267949
+#define HPF_Fs48000_Gain15_B2 0.000000
+#ifdef HIGHER_FS
+
+/* Coefficients for sample rate 96000Hz */
+ /* Gain = 1.000000 dB */
+#define HPF_Fs96000_Gain1_A0 1.096233
+#define HPF_Fs96000_Gain1_A1 -0.673583
+#define HPF_Fs96000_Gain1_A2 0.000000
+#define HPF_Fs96000_Gain1_B1 -0.577350
+#define HPF_Fs96000_Gain1_B2 0.000000
+ /* Gain = 2.000000 dB */
+#define HPF_Fs96000_Gain2_A0 1.204208
+#define HPF_Fs96000_Gain2_A1 -0.781558
+#define HPF_Fs96000_Gain2_A2 0.000000
+#define HPF_Fs96000_Gain2_B1 -0.577350
+#define HPF_Fs96000_Gain2_B2 0.000000
+ /* Gain = 3.000000 dB */
+#define HPF_Fs96000_Gain3_A0 1.325358
+#define HPF_Fs96000_Gain3_A1 -0.902708
+#define HPF_Fs96000_Gain3_A2 0.000000
+#define HPF_Fs96000_Gain3_B1 -0.577350
+#define HPF_Fs96000_Gain3_B2 0.000000
+ /* Gain = 4.000000 dB */
+#define HPF_Fs96000_Gain4_A0 1.461291
+#define HPF_Fs96000_Gain4_A1 -1.038641
+#define HPF_Fs96000_Gain4_A2 0.000000
+#define HPF_Fs96000_Gain4_B1 -0.577350
+#define HPF_Fs96000_Gain4_B2 0.000000
+ /* Gain = 5.000000 dB */
+#define HPF_Fs96000_Gain5_A0 1.613810
+#define HPF_Fs96000_Gain5_A1 -1.191160
+#define HPF_Fs96000_Gain5_A2 0.000000
+#define HPF_Fs96000_Gain5_B1 -0.577350
+#define HPF_Fs96000_Gain5_B2 0.000000
+ /* Gain = 6.000000 dB */
+#define HPF_Fs96000_Gain6_A0 1.784939
+#define HPF_Fs96000_Gain6_A1 -1.362289
+#define HPF_Fs96000_Gain6_A2 0.000000
+#define HPF_Fs96000_Gain6_B1 -0.577350
+#define HPF_Fs96000_Gain6_B2 0.000000
+ /* Gain = 7.000000 dB */
+#define HPF_Fs96000_Gain7_A0 1.976949
+#define HPF_Fs96000_Gain7_A1 -1.554299
+#define HPF_Fs96000_Gain7_A2 0.000000
+#define HPF_Fs96000_Gain7_B1 -0.577350
+#define HPF_Fs96000_Gain7_B2 0.000000
+ /* Gain = 8.000000 dB */
+#define HPF_Fs96000_Gain8_A0 2.192387
+#define HPF_Fs96000_Gain8_A1 -1.769738
+#define HPF_Fs96000_Gain8_A2 0.000000
+#define HPF_Fs96000_Gain8_B1 -0.577350
+#define HPF_Fs96000_Gain8_B2 0.000000
+ /* Gain = 9.000000 dB */
+#define HPF_Fs96000_Gain9_A0 2.434113
+#define HPF_Fs96000_Gain9_A1 -2.011464
+#define HPF_Fs96000_Gain9_A2 0.000000
+#define HPF_Fs96000_Gain9_B1 -0.577350
+#define HPF_Fs96000_Gain9_B2 0.000000
+ /* Gain = 10.000000 dB */
+#define HPF_Fs96000_Gain10_A0 2.705335
+#define HPF_Fs96000_Gain10_A1 -2.282685
+#define HPF_Fs96000_Gain10_A2 0.000000
+#define HPF_Fs96000_Gain10_B1 -0.577350
+#define HPF_Fs96000_Gain10_B2 0.000000
+ /* Gain = 11.000000 dB */
+#define HPF_Fs96000_Gain11_A0 3.009650
+#define HPF_Fs96000_Gain11_A1 -2.587000
+#define HPF_Fs96000_Gain11_A2 0.000000
+#define HPF_Fs96000_Gain11_B1 -0.577350
+#define HPF_Fs96000_Gain11_B2 0.000000
+ /* Gain = 12.000000 dB */
+#define HPF_Fs96000_Gain12_A0 3.351097
+#define HPF_Fs96000_Gain12_A1 -2.928447
+#define HPF_Fs96000_Gain12_A2 0.000000
+#define HPF_Fs96000_Gain12_B1 -0.577350
+#define HPF_Fs96000_Gain12_B2 0.000000
+ /* Gain = 13.000000 dB */
+#define HPF_Fs96000_Gain13_A0 3.734207
+#define HPF_Fs96000_Gain13_A1 -3.311558
+#define HPF_Fs96000_Gain13_A2 0.000000
+#define HPF_Fs96000_Gain13_B1 -0.577350
+#define HPF_Fs96000_Gain13_B2 0.000000
+ /* Gain = 14.000000 dB */
+#define HPF_Fs96000_Gain14_A0 4.164064
+#define HPF_Fs96000_Gain14_A1 -3.741414
+#define HPF_Fs96000_Gain14_A2 0.000000
+#define HPF_Fs96000_Gain14_B1 -0.577350
+#define HPF_Fs96000_Gain14_B2 0.000000
+ /* Gain = 15.000000 dB */
+#define HPF_Fs96000_Gain15_A0 4.646371
+#define HPF_Fs96000_Gain15_A1 -4.223721
+#define HPF_Fs96000_Gain15_A2 0.000000
+#define HPF_Fs96000_Gain15_B1 -0.577350
+#define HPF_Fs96000_Gain15_B2 0.000000
+
+/* Coefficients for sample rate 192000Hz */
+ /* Gain = 1.000000 dB */
+#define HPF_Fs192000_Gain1_A0 1.107823
+#define HPF_Fs192000_Gain1_A1 -0.875150
+#define HPF_Fs192000_Gain1_A2 0.000000
+#define HPF_Fs192000_Gain1_B1 -0.767327
+#define HPF_Fs192000_Gain1_B2 0.000000
+ /* Gain = 2.000000 dB */
+#define HPF_Fs192000_Gain2_A0 1.228803
+#define HPF_Fs192000_Gain2_A1 -0.996130
+#define HPF_Fs192000_Gain2_A2 0.000000
+#define HPF_Fs192000_Gain2_B1 -0.767327
+#define HPF_Fs192000_Gain2_B2 0.000000
+ /* Gain = 3.000000 dB */
+#define HPF_Fs192000_Gain3_A0 1.364544
+#define HPF_Fs192000_Gain3_A1 -1.131871
+#define HPF_Fs192000_Gain3_A2 0.000000
+#define HPF_Fs192000_Gain3_B1 -0.767327
+#define HPF_Fs192000_Gain3_B2 0.000000
+ /* Gain = 4.000000 dB */
+#define HPF_Fs192000_Gain4_A0 1.516849
+#define HPF_Fs192000_Gain4_A1 -1.284176
+#define HPF_Fs192000_Gain4_A2 0.000000
+#define HPF_Fs192000_Gain4_B1 -0.767327
+#define HPF_Fs192000_Gain4_B2 0.000000
+ /* Gain = 5.000000 dB */
+#define HPF_Fs192000_Gain5_A0 1.687737
+#define HPF_Fs192000_Gain5_A1 -1.455064
+#define HPF_Fs192000_Gain5_A2 0.000000
+#define HPF_Fs192000_Gain5_B1 -0.767327
+#define HPF_Fs192000_Gain5_B2 0.000000
+ /* Gain = 6.000000 dB */
+#define HPF_Fs192000_Gain6_A0 1.879477
+#define HPF_Fs192000_Gain6_A1 -1.646804
+#define HPF_Fs192000_Gain6_A2 0.000000
+#define HPF_Fs192000_Gain6_B1 -0.767327
+#define HPF_Fs192000_Gain6_B2 0.000000
+ /* Gain = 7.000000 dB */
+#define HPF_Fs192000_Gain7_A0 2.094613
+#define HPF_Fs192000_Gain7_A1 -1.861940
+#define HPF_Fs192000_Gain7_A2 0.000000
+#define HPF_Fs192000_Gain7_B1 -0.767327
+#define HPF_Fs192000_Gain7_B2 0.000000
+ /* Gain = 8.000000 dB */
+#define HPF_Fs192000_Gain8_A0 2.335999
+#define HPF_Fs192000_Gain8_A1 -2.103326
+#define HPF_Fs192000_Gain8_A2 0.000000
+#define HPF_Fs192000_Gain8_B1 -0.767327
+#define HPF_Fs192000_Gain8_B2 0.000000
+ /* Gain = 9.000000 dB */
+#define HPF_Fs192000_Gain9_A0 2.606839
+#define HPF_Fs192000_Gain9_A1 -2.374166
+#define HPF_Fs192000_Gain9_A2 0.000000
+#define HPF_Fs192000_Gain9_B1 -0.767327
+#define HPF_Fs192000_Gain9_B2 0.000000
+ /* Gain = 10.000000 dB */
+#define HPF_Fs192000_Gain10_A0 2.910726
+#define HPF_Fs192000_Gain10_A1 -2.678053
+#define HPF_Fs192000_Gain10_A2 0.000000
+#define HPF_Fs192000_Gain10_B1 -0.767327
+#define HPF_Fs192000_Gain10_B2 0.000000
+ /* Gain = 11.000000 dB */
+#define HPF_Fs192000_Gain11_A0 3.251693
+#define HPF_Fs192000_Gain11_A1 -3.019020
+#define HPF_Fs192000_Gain11_A2 0.000000
+#define HPF_Fs192000_Gain11_B1 -0.767327
+#define HPF_Fs192000_Gain11_B2 0.000000
+ /* Gain = 12.000000 dB */
+#define HPF_Fs192000_Gain12_A0 3.634264
+#define HPF_Fs192000_Gain12_A1 -3.401591
+#define HPF_Fs192000_Gain12_A2 0.000000
+#define HPF_Fs192000_Gain12_B1 -0.767327
+#define HPF_Fs192000_Gain12_B2 0.000000
+ /* Gain = 13.000000 dB */
+#define HPF_Fs192000_Gain13_A0 4.063516
+#define HPF_Fs192000_Gain13_A1 -3.830843
+#define HPF_Fs192000_Gain13_A2 0.000000
+#define HPF_Fs192000_Gain13_B1 -0.767327
+#define HPF_Fs192000_Gain13_B2 0.000000
+ /* Gain = 14.000000 dB */
+#define HPF_Fs192000_Gain14_A0 4.545145
+#define HPF_Fs192000_Gain14_A1 -4.312472
+#define HPF_Fs192000_Gain14_A2 0.000000
+#define HPF_Fs192000_Gain14_B1 -0.767327
+#define HPF_Fs192000_Gain14_B2 0.000000
+ /* Gain = 15.000000 dB */
+#define HPF_Fs192000_Gain15_A0 5.085542
+#define HPF_Fs192000_Gain15_A1 -4.852868
+#define HPF_Fs192000_Gain15_A2 0.000000
+#define HPF_Fs192000_Gain15_B1 -0.767327
+#define HPF_Fs192000_Gain15_B2 0.000000
+
+#endif
+
+#else
/* Coefficients for sample rate 22050Hz */
/* Gain = 1.000000 dB */
#define HPF_Fs22050_Gain1_A0 5383 /* Floating point value 0.164291 */
@@ -571,3 +1216,4 @@
#endif
+#endif
\ No newline at end of file
diff --git a/media/libeffects/lvm/lib/Bundle/src/LVM_Control.c b/media/libeffects/lvm/lib/Bundle/src/LVM_Control.c
index 72564d4..cfe53b8 100644
--- a/media/libeffects/lvm/lib/Bundle/src/LVM_Control.c
+++ b/media/libeffects/lvm/lib/Bundle/src/LVM_Control.c
@@ -65,9 +65,16 @@
if(
/* General parameters */
((pParams->OperatingMode != LVM_MODE_OFF) && (pParams->OperatingMode != LVM_MODE_ON)) ||
+#if defined(BUILD_FLOAT) && defined(HIGHER_FS)
+ ((pParams->SampleRate != LVM_FS_8000) && (pParams->SampleRate != LVM_FS_11025) && (pParams->SampleRate != LVM_FS_12000) &&
+ (pParams->SampleRate != LVM_FS_16000) && (pParams->SampleRate != LVM_FS_22050) && (pParams->SampleRate != LVM_FS_24000) &&
+ (pParams->SampleRate != LVM_FS_32000) && (pParams->SampleRate != LVM_FS_44100) && (pParams->SampleRate != LVM_FS_48000) &&
+ (pParams->SampleRate != LVM_FS_96000) && (pParams->SampleRate != LVM_FS_192000)) ||
+#else
((pParams->SampleRate != LVM_FS_8000) && (pParams->SampleRate != LVM_FS_11025) && (pParams->SampleRate != LVM_FS_12000) &&
(pParams->SampleRate != LVM_FS_16000) && (pParams->SampleRate != LVM_FS_22050) && (pParams->SampleRate != LVM_FS_24000) &&
(pParams->SampleRate != LVM_FS_32000) && (pParams->SampleRate != LVM_FS_44100) && (pParams->SampleRate != LVM_FS_48000)) ||
+#endif
((pParams->SourceFormat != LVM_STEREO) && (pParams->SourceFormat != LVM_MONOINSTEREO) && (pParams->SourceFormat != LVM_MONO)) ||
(pParams->SpeakerType > LVM_EX_HEADPHONES))
{
@@ -268,7 +275,12 @@
void LVM_SetTrebleBoost(LVM_Instance_t *pInstance,
LVM_ControlParams_t *pParams)
{
+#ifdef BUILD_FLOAT
+ extern FO_FLOAT_LShx_Coefs_t LVM_TrebleBoostCoefs[];
+#else
extern FO_C16_LShx_Coefs_t LVM_TrebleBoostCoefs[];
+#endif
+
LVM_INT16 Offset;
LVM_INT16 EffectLevel = 0;
@@ -298,6 +310,20 @@
* Load the coefficients and enabled the treble boost
*/
Offset = (LVM_INT16)(EffectLevel - 1 + TrebleBoostSteps * (pParams->SampleRate - TrebleBoostMinRate));
+#ifdef BUILD_FLOAT
+ FO_2I_D16F32Css_LShx_TRC_WRA_01_Init(&pInstance->pTE_State->TrebleBoost_State,
+ &pInstance->pTE_Taps->TrebleBoost_Taps,
+ &LVM_TrebleBoostCoefs[Offset]);
+
+ /*
+ * Clear the taps
+ */
+ LoadConst_Float((LVM_FLOAT)0, /* Value */
+ (void *)&pInstance->pTE_Taps->TrebleBoost_Taps, /* Destination.\
+ Cast to void: no dereferencing in function */
+ (LVM_UINT16)(sizeof(pInstance->pTE_Taps->TrebleBoost_Taps) / \
+ sizeof(LVM_FLOAT))); /* Number of words */
+#else
FO_2I_D16F32Css_LShx_TRC_WRA_01_Init(&pInstance->pTE_State->TrebleBoost_State,
&pInstance->pTE_Taps->TrebleBoost_Taps,
&LVM_TrebleBoostCoefs[Offset]);
@@ -309,6 +335,7 @@
(void *)&pInstance->pTE_Taps->TrebleBoost_Taps, /* Destination.\
Cast to void: no dereferencing in function */
(LVM_UINT16)(sizeof(pInstance->pTE_Taps->TrebleBoost_Taps)/sizeof(LVM_INT16))); /* Number of words */
+#endif
}
}
else
@@ -342,6 +369,9 @@
LVM_UINT16 dBShifts; /* 6dB shifts */
LVM_UINT16 dBOffset; /* Table offset */
LVM_INT16 Volume = 0; /* Required volume in dBs */
+#ifdef BUILD_FLOAT
+ LVM_FLOAT Temp;
+#endif
/*
* Limit the gain to the maximum allowed
@@ -401,22 +431,46 @@
*/
if(dBShifts == 0)
{
+#ifdef BUILD_FLOAT
+ LVC_Mixer_SetTarget(&pInstance->VC_Volume.MixerStream[0],
+ (LVM_FLOAT)LVM_VolumeTable[dBOffset]);
+#else
LVC_Mixer_SetTarget(&pInstance->VC_Volume.MixerStream[0],
(LVM_INT32)LVM_VolumeTable[dBOffset]);
- }
+#endif
+ }
else
{
+#ifdef BUILD_FLOAT
+ Temp = LVM_VolumeTable[dBOffset];
+ while(dBShifts) {
+ Temp = Temp / 2.0f;
+ dBShifts--;
+ }
+ LVC_Mixer_SetTarget(&pInstance->VC_Volume.MixerStream[0], Temp);
+#else
LVC_Mixer_SetTarget(&pInstance->VC_Volume.MixerStream[0],
(((LVM_INT32)LVM_VolumeTable[dBOffset])>>dBShifts));
+#endif
}
pInstance->VC_Volume.MixerStream[0].CallbackSet = 1;
if(pInstance->NoSmoothVolume == LVM_TRUE)
{
+#ifdef BUILD_FLOAT
+ LVC_Mixer_SetTimeConstant(&pInstance->VC_Volume.MixerStream[0], 0,
+ pInstance->Params.SampleRate, 2);
+#else
LVC_Mixer_SetTimeConstant(&pInstance->VC_Volume.MixerStream[0],0,pInstance->Params.SampleRate,2);
+#endif
}
else
{
+#ifdef BUILD_FLOAT
+ LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_Volume.MixerStream[0],
+ LVM_VC_MIXER_TIME, pInstance->Params.SampleRate, 2);
+#else
LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_Volume.MixerStream[0],LVM_VC_MIXER_TIME,pInstance->Params.SampleRate,2);
+#endif
}
}
@@ -554,8 +608,23 @@
/* Configure Mixer module for gradual changes to volume*/
if(LocalParams.VC_Balance < 0)
{
+#ifdef BUILD_FLOAT
+ LVM_FLOAT Target_Float;
+#else
LVM_INT32 Target;
+#endif
/* Drop in right channel volume*/
+#ifdef BUILD_FLOAT
+ Target_Float = LVM_MAXFLOAT;
+ LVC_Mixer_SetTarget(&pInstance->VC_BalanceMix.MixerStream[0], Target_Float);
+ LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_BalanceMix.MixerStream[0],
+ LVM_VC_MIXER_TIME, LocalParams.SampleRate, 1);
+
+ Target_Float = dB_to_LinFloat((LVM_INT16)(LocalParams.VC_Balance << 4));
+ LVC_Mixer_SetTarget(&pInstance->VC_BalanceMix.MixerStream[1], Target_Float);
+ LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_BalanceMix.MixerStream[1],
+ LVM_VC_MIXER_TIME, LocalParams.SampleRate, 1);
+#else
Target = LVM_MAXINT_16;
LVC_Mixer_SetTarget(&pInstance->VC_BalanceMix.MixerStream[0],Target);
LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_BalanceMix.MixerStream[0],LVM_VC_MIXER_TIME,LocalParams.SampleRate,1);
@@ -563,11 +632,27 @@
Target = dB_to_Lin32((LVM_INT16)(LocalParams.VC_Balance<<4));
LVC_Mixer_SetTarget(&pInstance->VC_BalanceMix.MixerStream[1],Target);
LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_BalanceMix.MixerStream[1],LVM_VC_MIXER_TIME,LocalParams.SampleRate,1);
+#endif
}
else if(LocalParams.VC_Balance >0)
{
+#ifdef BUILD_FLOAT
+ LVM_FLOAT Target_Float;
+#else
LVM_INT32 Target;
+#endif
/* Drop in left channel volume*/
+#ifdef BUILD_FLOAT
+ Target_Float = dB_to_LinFloat((LVM_INT16)((-LocalParams.VC_Balance) << 4));
+ LVC_Mixer_SetTarget(&pInstance->VC_BalanceMix.MixerStream[0], Target_Float);
+ LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_BalanceMix.MixerStream[0],
+ LVM_VC_MIXER_TIME, LocalParams.SampleRate, 1);
+
+ Target_Float = LVM_MAXFLOAT;
+ LVC_Mixer_SetTarget(&pInstance->VC_BalanceMix.MixerStream[1], Target_Float);
+ LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_BalanceMix.MixerStream[1],
+ LVM_VC_MIXER_TIME, LocalParams.SampleRate, 1);
+#else
Target = dB_to_Lin32((LVM_INT16)((-LocalParams.VC_Balance)<<4));
LVC_Mixer_SetTarget(&pInstance->VC_BalanceMix.MixerStream[0],Target);
LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_BalanceMix.MixerStream[0],LVM_VC_MIXER_TIME,LocalParams.SampleRate,1);
@@ -575,17 +660,36 @@
Target = LVM_MAXINT_16;
LVC_Mixer_SetTarget(&pInstance->VC_BalanceMix.MixerStream[1],Target);
LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_BalanceMix.MixerStream[1],LVM_VC_MIXER_TIME,LocalParams.SampleRate,1);
+#endif
}
else
{
+#ifdef BUILD_FLOAT
+ LVM_FLOAT Target_Float;
+#else
LVM_INT32 Target;
+#endif
/* No drop*/
+#ifdef BUILD_FLOAT
+ Target_Float = LVM_MAXFLOAT;
+#else
Target = LVM_MAXINT_16;
+#endif
+#ifdef BUILD_FLOAT
+ LVC_Mixer_SetTarget(&pInstance->VC_BalanceMix.MixerStream[0],Target_Float);
+ LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_BalanceMix.MixerStream[0],
+ LVM_VC_MIXER_TIME,LocalParams.SampleRate, 1);
+
+ LVC_Mixer_SetTarget(&pInstance->VC_BalanceMix.MixerStream[1],Target_Float);
+ LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_BalanceMix.MixerStream[1],
+ LVM_VC_MIXER_TIME,LocalParams.SampleRate, 1);
+#else
LVC_Mixer_SetTarget(&pInstance->VC_BalanceMix.MixerStream[0],Target);
LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_BalanceMix.MixerStream[0],LVM_VC_MIXER_TIME,LocalParams.SampleRate,1);
LVC_Mixer_SetTarget(&pInstance->VC_BalanceMix.MixerStream[1],Target);
LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_BalanceMix.MixerStream[1],LVM_VC_MIXER_TIME,LocalParams.SampleRate,1);
+#endif
}
}
/*
@@ -1008,18 +1112,30 @@
short CallBackParam)
{
LVM_Instance_t *pInstance =(LVM_Instance_t *)pBundleHandle;
+#ifdef BUILD_FLOAT
+ LVM_FLOAT Target;
+#else
LVM_INT32 Target;
+#endif
(void) pGeneralPurpose;
(void) CallBackParam;
/* When volume mixer has reached 0 dB target then stop it to avoid
unnecessary processing. */
+#ifdef BUILD_FLOAT
+ Target = LVC_Mixer_GetTarget(&pInstance->VC_Volume.MixerStream[0]);
+ if(Target == 1.0f)
+ {
+ pInstance->VC_Active = LVM_FALSE;
+ }
+#else
Target = LVC_Mixer_GetTarget(&pInstance->VC_Volume.MixerStream[0]);
if(Target == 0x7FFF)
{
pInstance->VC_Active = LVM_FALSE;
}
+#endif
return 1;
}
diff --git a/media/libeffects/lvm/lib/Bundle/src/LVM_Init.c b/media/libeffects/lvm/lib/Bundle/src/LVM_Init.c
index 542c3c8..26c1c4f 100644
--- a/media/libeffects/lvm/lib/Bundle/src/LVM_Init.c
+++ b/media/libeffects/lvm/lib/Bundle/src/LVM_Init.c
@@ -232,7 +232,11 @@
/*
* Set the capabilities
*/
+#if defined(BUILD_FLOAT) && defined(HIGHER_FS)
+ DBE_Capabilities.SampleRate = LVDBE_CAP_FS_8000 | LVDBE_CAP_FS_11025 | LVDBE_CAP_FS_12000 | LVDBE_CAP_FS_16000 | LVDBE_CAP_FS_22050 | LVDBE_CAP_FS_24000 | LVDBE_CAP_FS_32000 | LVDBE_CAP_FS_44100 | LVDBE_CAP_FS_48000 | LVDBE_CAP_FS_96000 | LVDBE_CAP_FS_192000;
+#else
DBE_Capabilities.SampleRate = LVDBE_CAP_FS_8000 | LVDBE_CAP_FS_11025 | LVDBE_CAP_FS_12000 | LVDBE_CAP_FS_16000 | LVDBE_CAP_FS_22050 | LVDBE_CAP_FS_24000 | LVDBE_CAP_FS_32000 | LVDBE_CAP_FS_44100 | LVDBE_CAP_FS_48000;
+#endif
DBE_Capabilities.CentreFrequency = LVDBE_CAP_CENTRE_55Hz | LVDBE_CAP_CENTRE_55Hz | LVDBE_CAP_CENTRE_66Hz | LVDBE_CAP_CENTRE_78Hz | LVDBE_CAP_CENTRE_90Hz;
DBE_Capabilities.MaxBlockSize = InternalBlockSize;
@@ -265,7 +269,11 @@
/*
* Set the capabilities
*/
+#if defined(BUILD_FLOAT) && defined(HIGHER_FS)
+ EQNB_Capabilities.SampleRate = LVEQNB_CAP_FS_8000 | LVEQNB_CAP_FS_11025 | LVEQNB_CAP_FS_12000 | LVEQNB_CAP_FS_16000 | LVEQNB_CAP_FS_22050 | LVEQNB_CAP_FS_24000 | LVEQNB_CAP_FS_32000 | LVEQNB_CAP_FS_44100 | LVEQNB_CAP_FS_48000 | LVEQNB_CAP_FS_96000 | LVEQNB_CAP_FS_192000;
+#else
EQNB_Capabilities.SampleRate = LVEQNB_CAP_FS_8000 | LVEQNB_CAP_FS_11025 | LVEQNB_CAP_FS_12000 | LVEQNB_CAP_FS_16000 | LVEQNB_CAP_FS_22050 | LVEQNB_CAP_FS_24000 | LVEQNB_CAP_FS_32000 | LVEQNB_CAP_FS_44100 | LVEQNB_CAP_FS_48000;
+#endif
EQNB_Capabilities.SourceFormat = LVEQNB_CAP_STEREO | LVEQNB_CAP_MONOINSTEREO;
EQNB_Capabilities.MaxBlockSize = InternalBlockSize;
EQNB_Capabilities.MaxBands = pInstParams->EQNB_NumBands;
@@ -542,10 +550,15 @@
BundleScratchSize = (LVM_INT32)(6 * (MIN_INTERNAL_BLOCKSIZE + InternalBlockSize) * sizeof(LVM_INT16));
pInstance->pBufferManagement->pScratch = InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_TEMPORARY_FAST], /* Scratch 1 buffer */
(LVM_UINT32)BundleScratchSize);
-
+#ifdef BUILD_FLOAT
+ LoadConst_Float(0, /* Clear the input delay buffer */
+ (LVM_FLOAT *)&pInstance->pBufferManagement->InDelayBuffer,
+ (LVM_INT16)(2 * MIN_INTERNAL_BLOCKSIZE));
+#else
LoadConst_16(0, /* Clear the input delay buffer */
(LVM_INT16 *)&pInstance->pBufferManagement->InDelayBuffer,
(LVM_INT16)(2 * MIN_INTERNAL_BLOCKSIZE));
+#endif
pInstance->pBufferManagement->InDelaySamples = MIN_INTERNAL_BLOCKSIZE; /* Set the number of delay samples */
pInstance->pBufferManagement->OutDelaySamples = 0; /* No samples in the output buffer */
pInstance->pBufferManagement->BufferState = LVM_FIRSTCALL; /* Set the state ready for the first call */
@@ -598,14 +611,26 @@
/* In managed buffering, start with low signal level as delay in buffer management causes a click*/
if (pInstParams->BufferMode == LVM_MANAGED_BUFFERS)
{
+#ifdef BUILD_FLOAT
+ LVC_Mixer_Init(&pInstance->VC_Volume.MixerStream[0], 0, 0);
+#else
LVC_Mixer_Init(&pInstance->VC_Volume.MixerStream[0],0,0);
+#endif
}
else
{
+#ifdef BUILD_FLOAT
+ LVC_Mixer_Init(&pInstance->VC_Volume.MixerStream[0], LVM_MAXFLOAT, LVM_MAXFLOAT);
+#else
LVC_Mixer_Init(&pInstance->VC_Volume.MixerStream[0],LVM_MAXINT_16,LVM_MAXINT_16);
+#endif
}
+#ifdef BUILD_FLOAT
LVC_Mixer_SetTimeConstant(&pInstance->VC_Volume.MixerStream[0],0,LVM_FS_8000,2);
+#else
+ LVC_Mixer_SetTimeConstant(&pInstance->VC_Volume.MixerStream[0], 0, LVM_FS_8000, 2);
+#endif
pInstance->VC_VolumedB = 0;
pInstance->VC_AVLFixedVolume = 0;
@@ -615,15 +640,24 @@
pInstance->VC_BalanceMix.MixerStream[0].CallbackSet = 0;
pInstance->VC_BalanceMix.MixerStream[0].pCallbackHandle = pInstance;
pInstance->VC_BalanceMix.MixerStream[0].pCallBack = LVM_VCCallBack;
+#ifdef BUILD_FLOAT
+ LVC_Mixer_Init(&pInstance->VC_BalanceMix.MixerStream[0], LVM_MAXFLOAT, LVM_MAXFLOAT);
+#else
LVC_Mixer_Init(&pInstance->VC_BalanceMix.MixerStream[0],LVM_MAXINT_16,LVM_MAXINT_16);
+#endif
LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_BalanceMix.MixerStream[0],LVM_VC_MIXER_TIME,LVM_FS_8000,2);
pInstance->VC_BalanceMix.MixerStream[1].CallbackParam = 0;
pInstance->VC_BalanceMix.MixerStream[1].CallbackSet = 0;
pInstance->VC_BalanceMix.MixerStream[1].pCallbackHandle = pInstance;
pInstance->VC_BalanceMix.MixerStream[1].pCallBack = LVM_VCCallBack;
+#ifdef BUILD_FLOAT
+ LVC_Mixer_Init(&pInstance->VC_BalanceMix.MixerStream[1], LVM_MAXFLOAT, LVM_MAXFLOAT);
+#else
LVC_Mixer_Init(&pInstance->VC_BalanceMix.MixerStream[1],LVM_MAXINT_16,LVM_MAXINT_16);
+#endif
LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_BalanceMix.MixerStream[1],LVM_VC_MIXER_TIME,LVM_FS_8000,2);
+
/*
* Set the default EQNB pre-gain and pointer to the band definitions
*/
@@ -709,7 +743,11 @@
/*
* Set the initialisation capabilities
*/
+#if defined(BUILD_FLOAT) && defined(HIGHER_FS)
+ DBE_Capabilities.SampleRate = LVDBE_CAP_FS_8000 | LVDBE_CAP_FS_11025 | LVDBE_CAP_FS_12000 | LVDBE_CAP_FS_16000 | LVDBE_CAP_FS_22050 | LVDBE_CAP_FS_24000 | LVDBE_CAP_FS_32000 | LVDBE_CAP_FS_44100 | LVDBE_CAP_FS_48000 | LVDBE_CAP_FS_96000 | LVDBE_CAP_FS_192000;
+#else
DBE_Capabilities.SampleRate = LVDBE_CAP_FS_8000 | LVDBE_CAP_FS_11025 | LVDBE_CAP_FS_12000 | LVDBE_CAP_FS_16000 | LVDBE_CAP_FS_22050 | LVDBE_CAP_FS_24000 | LVDBE_CAP_FS_32000 | LVDBE_CAP_FS_44100 | LVDBE_CAP_FS_48000;
+#endif
DBE_Capabilities.CentreFrequency = LVDBE_CAP_CENTRE_55Hz | LVDBE_CAP_CENTRE_55Hz | LVDBE_CAP_CENTRE_66Hz | LVDBE_CAP_CENTRE_78Hz | LVDBE_CAP_CENTRE_90Hz;
DBE_Capabilities.MaxBlockSize = (LVM_UINT16)InternalBlockSize;
@@ -763,7 +801,11 @@
/*
* Set the initialisation capabilities
*/
+#if defined(BUILD_FLOAT) && defined(HIGHER_FS)
+ EQNB_Capabilities.SampleRate = LVEQNB_CAP_FS_8000 | LVEQNB_CAP_FS_11025 | LVEQNB_CAP_FS_12000 | LVEQNB_CAP_FS_16000 | LVEQNB_CAP_FS_22050 | LVEQNB_CAP_FS_24000 | LVEQNB_CAP_FS_32000 | LVEQNB_CAP_FS_44100 | LVEQNB_CAP_FS_48000 | LVEQNB_CAP_FS_96000 | LVEQNB_CAP_FS_192000;
+#else
EQNB_Capabilities.SampleRate = LVEQNB_CAP_FS_8000 | LVEQNB_CAP_FS_11025 | LVEQNB_CAP_FS_12000 | LVEQNB_CAP_FS_16000 | LVEQNB_CAP_FS_22050 | LVEQNB_CAP_FS_24000 | LVEQNB_CAP_FS_32000 | LVEQNB_CAP_FS_44100 | LVEQNB_CAP_FS_48000;
+#endif
EQNB_Capabilities.MaxBlockSize = (LVM_UINT16)InternalBlockSize;
EQNB_Capabilities.MaxBands = pInstParams->EQNB_NumBands;
EQNB_Capabilities.SourceFormat = LVEQNB_CAP_STEREO | LVEQNB_CAP_MONOINSTEREO;
@@ -868,9 +910,14 @@
PSA_MemTab.Region[LVM_PERSISTENT_FAST_COEF].Size);
/* Fast Temporary */
+#ifdef BUILD_FLOAT
pInstance->pPSAInput = InstAlloc_AddMember(&AllocMem[LVM_TEMPORARY_FAST],
- (LVM_UINT32) MAX_INTERNAL_BLOCKSIZE * sizeof(LVM_INT16));
-
+ (LVM_UINT32) MAX_INTERNAL_BLOCKSIZE * \
+ sizeof(LVM_FLOAT));
+#else
+ pInstance->pPSAInput = InstAlloc_AddMember(&AllocMem[LVM_TEMPORARY_FAST],
+ (LVM_UINT32) MAX_INTERNAL_BLOCKSIZE * sizeof(LVM_INT16));
+#endif
PSA_MemTab.Region[LVM_TEMPORARY_FAST].pBaseAddress = (void *)InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_TEMPORARY_FAST],0);
@@ -994,7 +1041,6 @@
/* DC removal filter */
DC_2I_D16_TRC_WRA_01_Init(&pInstance->DC_RemovalInstance);
-
return LVM_SUCCESS;
}
diff --git a/media/libeffects/lvm/lib/Bundle/src/LVM_Private.h b/media/libeffects/lvm/lib/Bundle/src/LVM_Private.h
index 2e85f77..b453222 100644
--- a/media/libeffects/lvm/lib/Bundle/src/LVM_Private.h
+++ b/media/libeffects/lvm/lib/Bundle/src/LVM_Private.h
@@ -138,6 +138,23 @@
/* Buffer Management */
+#ifdef BUILD_FLOAT
+typedef struct
+{
+ LVM_FLOAT *pScratch; /* Bundle scratch buffer */
+
+ LVM_INT16 BufferState; /* Buffer status */
+ LVM_FLOAT InDelayBuffer[6 * MIN_INTERNAL_BLOCKSIZE]; /* Input buffer delay line, \
+ left and right */
+ LVM_INT16 InDelaySamples; /* Number of samples in the input delay buffer */
+
+ LVM_FLOAT OutDelayBuffer[2 * MIN_INTERNAL_BLOCKSIZE]; /* Output buffer delay \
+ line */
+ LVM_INT16 OutDelaySamples; /* Number of samples in the output delay buffer, \
+ left and right */
+ LVM_INT16 SamplesToOutput; /* Samples to write to the output */
+} LVM_Buffer_t;
+#else
typedef struct
{
LVM_INT16 *pScratch; /* Bundle scratch buffer */
@@ -150,22 +167,28 @@
LVM_INT16 OutDelaySamples; /* Number of samples in the output delay buffer, left and right */
LVM_INT16 SamplesToOutput; /* Samples to write to the output */
} LVM_Buffer_t;
-
+#endif
/* Filter taps */
typedef struct
{
+#ifdef BUILD_FLOAT
+ Biquad_2I_Order1_FLOAT_Taps_t TrebleBoost_Taps; /* Treble boost Taps */
+#else
Biquad_2I_Order1_Taps_t TrebleBoost_Taps; /* Treble boost Taps */
+#endif
} LVM_TE_Data_t;
-
/* Coefficients */
typedef struct
{
+#ifdef BUILD_FLOAT
+ Biquad_FLOAT_Instance_t TrebleBoost_State; /* State for the treble boost filter */
+#else
Biquad_Instance_t TrebleBoost_State; /* State for the treble boost filter */
+#endif
} LVM_TE_Coefs_t;
-
typedef struct
{
/* Public parameters */
@@ -181,15 +204,24 @@
LVM_INT16 InternalBlockSize; /* Maximum internal block size */
LVM_Buffer_t *pBufferManagement; /* Buffer management variables */
LVM_INT16 SamplesToProcess; /* Input samples left to process */
+#ifdef BUILD_FLOAT
+ LVM_FLOAT *pInputSamples; /* External input sample pointer */
+ LVM_FLOAT *pOutputSamples; /* External output sample pointer */
+#else
LVM_INT16 *pInputSamples; /* External input sample pointer */
LVM_INT16 *pOutputSamples; /* External output sample pointer */
+#endif
/* Configuration number */
LVM_INT32 ConfigurationNumber;
LVM_INT32 BlickSizeMultiple;
/* DC removal */
+#ifdef BUILD_FLOAT
+ Biquad_FLOAT_Instance_t DC_RemovalInstance; /* DC removal filter instance */
+#else
Biquad_Instance_t DC_RemovalInstance; /* DC removal filter instance */
+#endif
/* Concert Sound */
LVCS_Handle_t hCSInstance; /* Concert Sound instance handle */
@@ -209,8 +241,16 @@
LVM_INT16 DBE_Active; /* Control flag */
/* Volume Control */
+#ifdef BUILD_FLOAT
+ LVMixer3_1St_FLOAT_st VC_Volume; /* Volume scaler */
+#else
LVMixer3_1St_st VC_Volume; /* Volume scaler */
+#endif
+#ifdef BUILD_FLOAT
+ LVMixer3_2St_FLOAT_st VC_BalanceMix; /* VC balance mixer */
+#else
LVMixer3_2St_st VC_BalanceMix; /* VC balance mixer */
+#endif
LVM_INT16 VC_VolumedB; /* Gain in dB */
LVM_INT16 VC_Active; /* Control flag */
LVM_INT16 VC_AVLFixedVolume; /* AVL fixed volume */
@@ -234,7 +274,11 @@
LVPSA_ControlParams_t PSA_ControlParams; /* Spectrum Analyzer control parameters */
LVM_INT16 PSA_GainOffset; /* Tone control flag */
LVM_Callback CallBack;
+#ifdef BUILD_FLOAT
+ LVM_FLOAT *pPSAInput; /* PSA input pointer */
+#else
LVM_INT16 *pPSAInput; /* PSA input pointer */
+#endif
LVM_INT16 NoSmoothVolume; /* Enable or disable smooth volume changes*/
@@ -261,16 +305,28 @@
void LVM_SetHeadroom( LVM_Instance_t *pInstance,
LVM_ControlParams_t *pParams);
-
+#ifdef BUILD_FLOAT
+void LVM_BufferIn( LVM_Handle_t hInstance,
+ const LVM_FLOAT *pInData,
+ LVM_FLOAT **pToProcess,
+ LVM_FLOAT **pProcessed,
+ LVM_UINT16 *pNumSamples);
+#else
void LVM_BufferIn( LVM_Handle_t hInstance,
const LVM_INT16 *pInData,
LVM_INT16 **pToProcess,
LVM_INT16 **pProcessed,
LVM_UINT16 *pNumSamples);
-
+#endif
+#ifdef BUILD_FLOAT
+void LVM_BufferOut( LVM_Handle_t hInstance,
+ LVM_FLOAT *pOutData,
+ LVM_UINT16 *pNumSamples);
+#else
void LVM_BufferOut( LVM_Handle_t hInstance,
LVM_INT16 *pOutData,
LVM_UINT16 *pNumSamples);
+#endif
LVM_INT32 LVM_AlgoCallBack( void *pBundleHandle,
void *pData,
diff --git a/media/libeffects/lvm/lib/Bundle/src/LVM_Process.c b/media/libeffects/lvm/lib/Bundle/src/LVM_Process.c
index f5a01f3..4a19a13 100644
--- a/media/libeffects/lvm/lib/Bundle/src/LVM_Process.c
+++ b/media/libeffects/lvm/lib/Bundle/src/LVM_Process.c
@@ -51,7 +51,231 @@
/* NOTES: */
/* */
/****************************************************************************************/
+#ifdef BUILD_FLOAT
+LVM_ReturnStatus_en LVM_Process(LVM_Handle_t hInstance,
+ const LVM_FLOAT *pInData,
+ LVM_FLOAT *pOutData,
+ LVM_UINT16 NumSamples,
+ LVM_UINT32 AudioTime)
+{
+ LVM_Instance_t *pInstance = (LVM_Instance_t *)hInstance;
+ LVM_UINT16 SampleCount = NumSamples;
+ LVM_FLOAT *pInput = (LVM_FLOAT *)pInData;
+ LVM_FLOAT *pToProcess = (LVM_FLOAT *)pInData;
+ LVM_FLOAT *pProcessed = pOutData;
+ LVM_ReturnStatus_en Status;
+
+ /*
+ * Check if the number of samples is zero
+ */
+ if (NumSamples == 0)
+ {
+ return(LVM_SUCCESS);
+ }
+
+
+ /*
+ * Check valid points have been given
+ */
+ if ((hInstance == LVM_NULL) || (pInData == LVM_NULL) || (pOutData == LVM_NULL))
+ {
+ return (LVM_NULLADDRESS);
+ }
+
+ /*
+ * For unmanaged mode only
+ */
+ if(pInstance->InstParams.BufferMode == LVM_UNMANAGED_BUFFERS)
+ {
+ /*
+ * Check if the number of samples is a good multiple (unmanaged mode only)
+ */
+ if((NumSamples % pInstance->BlickSizeMultiple) != 0)
+ {
+ return(LVM_INVALIDNUMSAMPLES);
+ }
+
+ /*
+ * Check the buffer alignment
+ */
+ if((((uintptr_t)pInData % 4) != 0) || (((uintptr_t)pOutData % 4) != 0))
+ {
+ return(LVM_ALIGNMENTERROR);
+ }
+ }
+
+
+ /*
+ * Update new parameters if necessary
+ */
+ if (pInstance->ControlPending == LVM_TRUE)
+ {
+ Status = LVM_ApplyNewSettings(hInstance);
+
+ if(Status != LVM_SUCCESS)
+ {
+ return Status;
+ }
+ }
+
+
+ /*
+ * Convert from Mono if necessary
+ */
+ if (pInstance->Params.SourceFormat == LVM_MONO)
+ {
+ MonoTo2I_Float(pInData, /* Source */
+ pOutData, /* Destination */
+ (LVM_INT16)NumSamples); /* Number of input samples */
+ pInput = pOutData;
+ pToProcess = pOutData;
+ }
+
+
+ /*
+ * Process the data with managed buffers
+ */
+ while (SampleCount != 0)
+ {
+ /*
+ * Manage the input buffer and frame processing
+ */
+ LVM_BufferIn(hInstance,
+ pInput,
+ &pToProcess,
+ &pProcessed,
+ &SampleCount);
+
+ /*
+ * Only process data when SampleCount is none zero, a zero count can occur when
+ * the BufferIn routine is working in managed mode.
+ */
+ if (SampleCount != 0)
+ {
+
+ /*
+ * Apply ConcertSound if required
+ */
+ if (pInstance->CS_Active == LVM_TRUE)
+ {
+ (void)LVCS_Process(pInstance->hCSInstance, /* Concert Sound instance handle */
+ pToProcess,
+ pProcessed,
+ SampleCount);
+ pToProcess = pProcessed;
+ }
+
+ /*
+ * Apply volume if required
+ */
+ if (pInstance->VC_Active!=0)
+ {
+ LVC_MixSoft_1St_D16C31_SAT(&pInstance->VC_Volume,
+ pToProcess,
+ pProcessed,
+ (LVM_INT16)(2 * SampleCount)); /* Left and right*/
+ pToProcess = pProcessed;
+ }
+
+ /*
+ * Call N-Band equaliser if enabled
+ */
+ if (pInstance->EQNB_Active == LVM_TRUE)
+ {
+ LVEQNB_Process(pInstance->hEQNBInstance, /* N-Band equaliser instance handle */
+ pToProcess,
+ pProcessed,
+ SampleCount);
+ pToProcess = pProcessed;
+ }
+
+ /*
+ * Call bass enhancement if enabled
+ */
+ if (pInstance->DBE_Active == LVM_TRUE)
+ {
+ LVDBE_Process(pInstance->hDBEInstance, /* Dynamic Bass Enhancement \
+ instance handle */
+ pToProcess,
+ pProcessed,
+ SampleCount);
+ pToProcess = pProcessed;
+ }
+
+ /*
+ * Bypass mode or everything off, so copy the input to the output
+ */
+ if (pToProcess != pProcessed)
+ {
+ Copy_Float(pToProcess, /* Source */
+ pProcessed, /* Destination */
+ (LVM_INT16)(2 * SampleCount)); /* Left and right */
+ }
+
+ /*
+ * Apply treble boost if required
+ */
+ if (pInstance->TE_Active == LVM_TRUE)
+ {
+ /*
+ * Apply the filter
+ */
+ FO_2I_D16F32C15_LShx_TRC_WRA_01(&pInstance->pTE_State->TrebleBoost_State,
+ pProcessed,
+ pProcessed,
+ (LVM_INT16)SampleCount);
+
+ }
+
+ /*
+ * Volume balance
+ */
+ LVC_MixSoft_1St_2i_D16C31_SAT(&pInstance->VC_BalanceMix,
+ pProcessed,
+ pProcessed,
+ SampleCount);
+
+ /*
+ * Perform Parametric Spectum Analysis
+ */
+ if ((pInstance->Params.PSA_Enable == LVM_PSA_ON) &&
+ (pInstance->InstParams.PSA_Included == LVM_PSA_ON))
+ {
+ From2iToMono_Float(pProcessed,
+ pInstance->pPSAInput,
+ (LVM_INT16)(SampleCount));
+
+ LVPSA_Process(pInstance->hPSAInstance,
+ pInstance->pPSAInput,
+ (LVM_UINT16)(SampleCount),
+ AudioTime);
+ }
+
+
+ /*
+ * DC removal
+ */
+ DC_2I_D16_TRC_WRA_01(&pInstance->DC_RemovalInstance,
+ pProcessed,
+ pProcessed,
+ (LVM_INT16)SampleCount);
+
+
+ }
+
+ /*
+ * Manage the output buffer
+ */
+ LVM_BufferOut(hInstance,
+ pOutData,
+ &SampleCount);
+
+ }
+
+ return(LVM_SUCCESS);
+}
+#else
LVM_ReturnStatus_en LVM_Process(LVM_Handle_t hInstance,
const LVM_INT16 *pInData,
LVM_INT16 *pOutData,
@@ -273,3 +497,4 @@
return(LVM_SUCCESS);
}
+#endif
\ No newline at end of file
diff --git a/media/libeffects/lvm/lib/Bundle/src/LVM_Tables.c b/media/libeffects/lvm/lib/Bundle/src/LVM_Tables.c
index e14f909..199ddde 100644
--- a/media/libeffects/lvm/lib/Bundle/src/LVM_Tables.c
+++ b/media/libeffects/lvm/lib/Bundle/src/LVM_Tables.c
@@ -29,7 +29,342 @@
/* Treble Boost Filter Coefficients */
/* */
/************************************************************************************/
+#ifdef BUILD_FLOAT
+FO_FLOAT_LShx_Coefs_t LVM_TrebleBoostCoefs[] = {
+
+ /* 22kHz sampling rate */
+ {HPF_Fs22050_Gain1_A1, /* Gain setting 1 */
+ HPF_Fs22050_Gain1_A0,
+ -HPF_Fs22050_Gain1_B1},
+ {HPF_Fs22050_Gain2_A1, /* Gain setting 2 */
+ HPF_Fs22050_Gain2_A0,
+ -HPF_Fs22050_Gain2_B1},
+ {HPF_Fs22050_Gain3_A1, /* Gain setting 3 */
+ HPF_Fs22050_Gain3_A0,
+ -HPF_Fs22050_Gain3_B1},
+ {HPF_Fs22050_Gain4_A1, /* Gain setting 4 */
+ HPF_Fs22050_Gain4_A0,
+ -HPF_Fs22050_Gain4_B1},
+ {HPF_Fs22050_Gain5_A1, /* Gain setting 5 */
+ HPF_Fs22050_Gain5_A0,
+ -HPF_Fs22050_Gain5_B1},
+ {HPF_Fs22050_Gain6_A1, /* Gain setting 6 */
+ HPF_Fs22050_Gain6_A0,
+ -HPF_Fs22050_Gain6_B1},
+ {HPF_Fs22050_Gain7_A1, /* Gain setting 7 */
+ HPF_Fs22050_Gain7_A0,
+ -HPF_Fs22050_Gain7_B1},
+ {HPF_Fs22050_Gain8_A1, /* Gain setting 8 */
+ HPF_Fs22050_Gain8_A0,
+ -HPF_Fs22050_Gain8_B1},
+ {HPF_Fs22050_Gain9_A1, /* Gain setting 9 */
+ HPF_Fs22050_Gain9_A0,
+ -HPF_Fs22050_Gain9_B1},
+ {HPF_Fs22050_Gain10_A1, /* Gain setting 10 */
+ HPF_Fs22050_Gain10_A0,
+ -HPF_Fs22050_Gain10_B1},
+ {HPF_Fs22050_Gain11_A1, /* Gain setting 11 */
+ HPF_Fs22050_Gain11_A0,
+ -HPF_Fs22050_Gain11_B1},
+ {HPF_Fs22050_Gain12_A1, /* Gain setting 12 */
+ HPF_Fs22050_Gain12_A0,
+ -HPF_Fs22050_Gain12_B1},
+ {HPF_Fs22050_Gain13_A1, /* Gain setting 13 */
+ HPF_Fs22050_Gain13_A0,
+ -HPF_Fs22050_Gain13_B1},
+ {HPF_Fs22050_Gain14_A1, /* Gain setting 14 */
+ HPF_Fs22050_Gain14_A0,
+ -HPF_Fs22050_Gain14_B1},
+ {HPF_Fs22050_Gain15_A1, /* Gain setting 15 */
+ HPF_Fs22050_Gain15_A0,
+ -HPF_Fs22050_Gain15_B1},
+
+ /* 24kHz sampling rate */
+ {HPF_Fs24000_Gain1_A1, /* Gain setting 1 */
+ HPF_Fs24000_Gain1_A0,
+ -HPF_Fs24000_Gain1_B1},
+ {HPF_Fs24000_Gain2_A1, /* Gain setting 2 */
+ HPF_Fs24000_Gain2_A0,
+ -HPF_Fs24000_Gain2_B1},
+ {HPF_Fs24000_Gain3_A1, /* Gain setting 3 */
+ HPF_Fs24000_Gain3_A0,
+ -HPF_Fs24000_Gain3_B1},
+ {HPF_Fs24000_Gain4_A1, /* Gain setting 4 */
+ HPF_Fs24000_Gain4_A0,
+ -HPF_Fs24000_Gain4_B1},
+ {HPF_Fs24000_Gain5_A1, /* Gain setting 5 */
+ HPF_Fs24000_Gain5_A0,
+ -HPF_Fs24000_Gain5_B1},
+ {HPF_Fs24000_Gain6_A1, /* Gain setting 6 */
+ HPF_Fs24000_Gain6_A0,
+ -HPF_Fs24000_Gain6_B1},
+ {HPF_Fs24000_Gain7_A1, /* Gain setting 7 */
+ HPF_Fs24000_Gain7_A0,
+ -HPF_Fs24000_Gain7_B1},
+ {HPF_Fs24000_Gain8_A1, /* Gain setting 8 */
+ HPF_Fs24000_Gain8_A0,
+ -HPF_Fs24000_Gain8_B1},
+ {HPF_Fs24000_Gain9_A1, /* Gain setting 9 */
+ HPF_Fs24000_Gain9_A0,
+ -HPF_Fs24000_Gain9_B1},
+ {HPF_Fs24000_Gain10_A1, /* Gain setting 10 */
+ HPF_Fs24000_Gain10_A0,
+ -HPF_Fs24000_Gain10_B1},
+ {HPF_Fs24000_Gain11_A1, /* Gain setting 11 */
+ HPF_Fs24000_Gain11_A0,
+ -HPF_Fs24000_Gain11_B1},
+ {HPF_Fs24000_Gain12_A1, /* Gain setting 12 */
+ HPF_Fs24000_Gain12_A0,
+ -HPF_Fs24000_Gain12_B1},
+ {HPF_Fs24000_Gain13_A1, /* Gain setting 13 */
+ HPF_Fs24000_Gain13_A0,
+ -HPF_Fs24000_Gain13_B1},
+ {HPF_Fs24000_Gain14_A1, /* Gain setting 14 */
+ HPF_Fs24000_Gain14_A0,
+ -HPF_Fs24000_Gain14_B1},
+ {HPF_Fs24000_Gain15_A1, /* Gain setting 15 */
+ HPF_Fs24000_Gain15_A0,
+ -HPF_Fs24000_Gain15_B1},
+
+ /* 32kHz sampling rate */
+ {HPF_Fs32000_Gain1_A1, /* Gain setting 1 */
+ HPF_Fs32000_Gain1_A0,
+ -HPF_Fs32000_Gain1_B1},
+ {HPF_Fs32000_Gain2_A1, /* Gain setting 2 */
+ HPF_Fs32000_Gain2_A0,
+ -HPF_Fs32000_Gain2_B1},
+ {HPF_Fs32000_Gain3_A1, /* Gain setting 3 */
+ HPF_Fs32000_Gain3_A0,
+ -HPF_Fs32000_Gain3_B1},
+ {HPF_Fs32000_Gain4_A1, /* Gain setting 4 */
+ HPF_Fs32000_Gain4_A0,
+ -HPF_Fs32000_Gain4_B1},
+ {HPF_Fs32000_Gain5_A1, /* Gain setting 5 */
+ HPF_Fs32000_Gain5_A0,
+ -HPF_Fs32000_Gain5_B1},
+ {HPF_Fs32000_Gain6_A1, /* Gain setting 6 */
+ HPF_Fs32000_Gain6_A0,
+ -HPF_Fs32000_Gain6_B1},
+ {HPF_Fs32000_Gain7_A1, /* Gain setting 7 */
+ HPF_Fs32000_Gain7_A0,
+ -HPF_Fs32000_Gain7_B1},
+ {HPF_Fs32000_Gain8_A1, /* Gain setting 8 */
+ HPF_Fs32000_Gain8_A0,
+ -HPF_Fs32000_Gain8_B1},
+ {HPF_Fs32000_Gain9_A1, /* Gain setting 9 */
+ HPF_Fs32000_Gain9_A0,
+ -HPF_Fs32000_Gain9_B1},
+ {HPF_Fs32000_Gain10_A1, /* Gain setting 10 */
+ HPF_Fs32000_Gain10_A0,
+ -HPF_Fs32000_Gain10_B1},
+ {HPF_Fs32000_Gain11_A1, /* Gain setting 11 */
+ HPF_Fs32000_Gain11_A0,
+ -HPF_Fs32000_Gain11_B1},
+ {HPF_Fs32000_Gain12_A1, /* Gain setting 12 */
+ HPF_Fs32000_Gain12_A0,
+ -HPF_Fs32000_Gain12_B1},
+ {HPF_Fs32000_Gain13_A1, /* Gain setting 13 */
+ HPF_Fs32000_Gain13_A0,
+ -HPF_Fs32000_Gain13_B1},
+ {HPF_Fs32000_Gain14_A1, /* Gain setting 14 */
+ HPF_Fs32000_Gain14_A0,
+ -HPF_Fs32000_Gain14_B1},
+ {HPF_Fs32000_Gain15_A1, /* Gain setting 15 */
+ HPF_Fs32000_Gain15_A0,
+ -HPF_Fs32000_Gain15_B1},
+
+ /* 44kHz sampling rate */
+ {HPF_Fs44100_Gain1_A1, /* Gain setting 1 */
+ HPF_Fs44100_Gain1_A0,
+ -HPF_Fs44100_Gain1_B1,},
+ {HPF_Fs44100_Gain2_A1, /* Gain setting 2 */
+ HPF_Fs44100_Gain2_A0,
+ -HPF_Fs44100_Gain2_B1},
+ {HPF_Fs44100_Gain3_A1, /* Gain setting 3 */
+ HPF_Fs44100_Gain3_A0,
+ -HPF_Fs44100_Gain3_B1},
+ {HPF_Fs44100_Gain4_A1, /* Gain setting 4 */
+ HPF_Fs44100_Gain4_A0,
+ -HPF_Fs44100_Gain4_B1},
+ {HPF_Fs44100_Gain5_A1, /* Gain setting 5 */
+ HPF_Fs44100_Gain5_A0,
+ -HPF_Fs44100_Gain5_B1},
+ {HPF_Fs44100_Gain6_A1, /* Gain setting 6 */
+ HPF_Fs44100_Gain6_A0,
+ -HPF_Fs44100_Gain6_B1},
+ {HPF_Fs44100_Gain7_A1, /* Gain setting 7 */
+ HPF_Fs44100_Gain7_A0,
+ -HPF_Fs44100_Gain7_B1},
+ {HPF_Fs44100_Gain8_A1, /* Gain setting 8 */
+ HPF_Fs44100_Gain8_A0,
+ -HPF_Fs44100_Gain8_B1},
+ {HPF_Fs44100_Gain9_A1, /* Gain setting 9 */
+ HPF_Fs44100_Gain9_A0,
+ -HPF_Fs44100_Gain9_B1},
+ {HPF_Fs44100_Gain10_A1, /* Gain setting 10 */
+ HPF_Fs44100_Gain10_A0,
+ -HPF_Fs44100_Gain10_B1},
+ {HPF_Fs44100_Gain11_A1, /* Gain setting 11 */
+ HPF_Fs44100_Gain11_A0,
+ -HPF_Fs44100_Gain11_B1},
+ {HPF_Fs44100_Gain12_A1, /* Gain setting 12 */
+ HPF_Fs44100_Gain12_A0,
+ -HPF_Fs44100_Gain12_B1},
+ {HPF_Fs44100_Gain13_A1, /* Gain setting 13 */
+ HPF_Fs44100_Gain13_A0,
+ -HPF_Fs44100_Gain13_B1},
+ {HPF_Fs44100_Gain14_A1, /* Gain setting 14 */
+ HPF_Fs44100_Gain14_A0,
+ -HPF_Fs44100_Gain14_B1},
+ {HPF_Fs44100_Gain15_A1, /* Gain setting 15 */
+ HPF_Fs44100_Gain15_A0,
+ -HPF_Fs44100_Gain15_B1},
+
+ /* 48kHz sampling rate */
+ {HPF_Fs48000_Gain1_A1, /* Gain setting 1 */
+ HPF_Fs48000_Gain1_A0,
+ -HPF_Fs48000_Gain1_B1},
+ {HPF_Fs48000_Gain2_A1, /* Gain setting 2 */
+ HPF_Fs48000_Gain2_A0,
+ -HPF_Fs48000_Gain2_B1},
+ {HPF_Fs48000_Gain3_A1, /* Gain setting 3 */
+ HPF_Fs48000_Gain3_A0,
+ -HPF_Fs48000_Gain3_B1},
+ {HPF_Fs48000_Gain4_A1, /* Gain setting 4 */
+ HPF_Fs48000_Gain4_A0,
+ -HPF_Fs48000_Gain4_B1},
+ {HPF_Fs48000_Gain5_A1, /* Gain setting 5 */
+ HPF_Fs48000_Gain5_A0,
+ -HPF_Fs48000_Gain5_B1},
+ {HPF_Fs48000_Gain6_A1, /* Gain setting 6 */
+ HPF_Fs48000_Gain6_A0,
+ -HPF_Fs48000_Gain6_B1},
+ {HPF_Fs48000_Gain7_A1, /* Gain setting 7 */
+ HPF_Fs48000_Gain7_A0,
+ -HPF_Fs48000_Gain7_B1},
+ {HPF_Fs48000_Gain8_A1, /* Gain setting 8 */
+ HPF_Fs48000_Gain8_A0,
+ -HPF_Fs48000_Gain8_B1},
+ {HPF_Fs48000_Gain9_A1, /* Gain setting 9 */
+ HPF_Fs48000_Gain9_A0,
+ -HPF_Fs48000_Gain9_B1},
+ {HPF_Fs48000_Gain10_A1, /* Gain setting 10 */
+ HPF_Fs48000_Gain10_A0,
+ -HPF_Fs48000_Gain10_B1},
+ {HPF_Fs48000_Gain11_A1, /* Gain setting 11 */
+ HPF_Fs48000_Gain11_A0,
+ -HPF_Fs48000_Gain11_B1},
+ {HPF_Fs48000_Gain12_A1, /* Gain setting 12 */
+ HPF_Fs48000_Gain12_A0,
+ -HPF_Fs48000_Gain12_B1},
+ {HPF_Fs48000_Gain13_A1, /* Gain setting 13 */
+ HPF_Fs48000_Gain13_A0,
+ -HPF_Fs48000_Gain13_B1},
+ {HPF_Fs48000_Gain14_A1, /* Gain setting 14 */
+ HPF_Fs48000_Gain14_A0,
+ -HPF_Fs48000_Gain14_B1},
+ {HPF_Fs48000_Gain15_A1, /* Gain setting 15 */
+ HPF_Fs48000_Gain15_A0,
+ -HPF_Fs48000_Gain15_B1}
+#ifdef HIGHER_FS
+ ,
+ /* 96kHz sampling rate */
+ {HPF_Fs96000_Gain1_A1, /* Gain setting 1 */
+ HPF_Fs96000_Gain1_A0,
+ -HPF_Fs96000_Gain1_B1},
+ {HPF_Fs96000_Gain2_A1, /* Gain setting 2 */
+ HPF_Fs96000_Gain2_A0,
+ -HPF_Fs96000_Gain2_B1},
+ {HPF_Fs96000_Gain3_A1, /* Gain setting 3 */
+ HPF_Fs96000_Gain3_A0,
+ -HPF_Fs96000_Gain3_B1},
+ {HPF_Fs96000_Gain4_A1, /* Gain setting 4 */
+ HPF_Fs96000_Gain4_A0,
+ -HPF_Fs96000_Gain4_B1},
+ {HPF_Fs96000_Gain5_A1, /* Gain setting 5 */
+ HPF_Fs96000_Gain5_A0,
+ -HPF_Fs96000_Gain5_B1},
+ {HPF_Fs96000_Gain6_A1, /* Gain setting 6 */
+ HPF_Fs96000_Gain6_A0,
+ -HPF_Fs96000_Gain6_B1},
+ {HPF_Fs96000_Gain7_A1, /* Gain setting 7 */
+ HPF_Fs96000_Gain7_A0,
+ -HPF_Fs96000_Gain7_B1},
+ {HPF_Fs96000_Gain8_A1, /* Gain setting 8 */
+ HPF_Fs96000_Gain8_A0,
+ -HPF_Fs96000_Gain8_B1},
+ {HPF_Fs96000_Gain9_A1, /* Gain setting 9 */
+ HPF_Fs96000_Gain9_A0,
+ -HPF_Fs96000_Gain9_B1},
+ {HPF_Fs96000_Gain10_A1, /* Gain setting 10 */
+ HPF_Fs96000_Gain10_A0,
+ -HPF_Fs96000_Gain10_B1},
+ {HPF_Fs96000_Gain11_A1, /* Gain setting 11 */
+ HPF_Fs96000_Gain11_A0,
+ -HPF_Fs96000_Gain11_B1},
+ {HPF_Fs96000_Gain12_A1, /* Gain setting 12 */
+ HPF_Fs96000_Gain12_A0,
+ -HPF_Fs96000_Gain12_B1},
+ {HPF_Fs96000_Gain13_A1, /* Gain setting 13 */
+ HPF_Fs96000_Gain13_A0,
+ -HPF_Fs96000_Gain13_B1},
+ {HPF_Fs96000_Gain14_A1, /* Gain setting 14 */
+ HPF_Fs96000_Gain14_A0,
+ -HPF_Fs96000_Gain14_B1},
+ {HPF_Fs96000_Gain15_A1, /* Gain setting 15 */
+ HPF_Fs96000_Gain15_A0,
+ -HPF_Fs96000_Gain15_B1},
+
+ /* 192kHz sampling rate */
+ {HPF_Fs192000_Gain1_A1, /* Gain setting 1 */
+ HPF_Fs192000_Gain1_A0,
+ -HPF_Fs192000_Gain1_B1},
+ {HPF_Fs192000_Gain2_A1, /* Gain setting 2 */
+ HPF_Fs192000_Gain2_A0,
+ -HPF_Fs192000_Gain2_B1},
+ {HPF_Fs192000_Gain3_A1, /* Gain setting 3 */
+ HPF_Fs192000_Gain3_A0,
+ -HPF_Fs192000_Gain3_B1},
+ {HPF_Fs192000_Gain4_A1, /* Gain setting 4 */
+ HPF_Fs192000_Gain4_A0,
+ -HPF_Fs192000_Gain4_B1},
+ {HPF_Fs192000_Gain5_A1, /* Gain setting 5 */
+ HPF_Fs192000_Gain5_A0,
+ -HPF_Fs192000_Gain5_B1},
+ {HPF_Fs192000_Gain6_A1, /* Gain setting 6 */
+ HPF_Fs192000_Gain6_A0,
+ -HPF_Fs192000_Gain6_B1},
+ {HPF_Fs192000_Gain7_A1, /* Gain setting 7 */
+ HPF_Fs192000_Gain7_A0,
+ -HPF_Fs192000_Gain7_B1},
+ {HPF_Fs192000_Gain8_A1, /* Gain setting 8 */
+ HPF_Fs192000_Gain8_A0,
+ -HPF_Fs192000_Gain8_B1},
+ {HPF_Fs192000_Gain9_A1, /* Gain setting 9 */
+ HPF_Fs192000_Gain9_A0,
+ -HPF_Fs192000_Gain9_B1},
+ {HPF_Fs192000_Gain10_A1, /* Gain setting 10 */
+ HPF_Fs192000_Gain10_A0,
+ -HPF_Fs192000_Gain10_B1},
+ {HPF_Fs192000_Gain11_A1, /* Gain setting 11 */
+ HPF_Fs192000_Gain11_A0,
+ -HPF_Fs192000_Gain11_B1},
+ {HPF_Fs192000_Gain12_A1, /* Gain setting 12 */
+ HPF_Fs192000_Gain12_A0,
+ -HPF_Fs192000_Gain12_B1},
+ {HPF_Fs192000_Gain13_A1, /* Gain setting 13 */
+ HPF_Fs192000_Gain13_A0,
+ -HPF_Fs192000_Gain13_B1},
+ {HPF_Fs192000_Gain14_A1, /* Gain setting 14 */
+ HPF_Fs192000_Gain14_A0,
+ -HPF_Fs192000_Gain14_B1},
+ {HPF_Fs192000_Gain15_A1, /* Gain setting 15 */
+ HPF_Fs192000_Gain15_A0,
+ -HPF_Fs192000_Gain15_B1}
+#endif
+ };
+#else
FO_C16_LShx_Coefs_t LVM_TrebleBoostCoefs[] = {
/* 22kHz sampling rate */
@@ -340,8 +675,9 @@
{HPF_Fs48000_Gain15_A1, /* Gain setting 15 */
HPF_Fs48000_Gain15_A0,
-HPF_Fs48000_Gain15_B1,
- HPF_Fs48000_Gain15_Shift}};
-
+ HPF_Fs48000_Gain15_Shift}
+ };
+#endif
/************************************************************************************/
/* */
@@ -350,6 +686,16 @@
/************************************************************************************/
/* dB to linear conversion table */
+#ifdef BUILD_FLOAT
+const LVM_FLOAT LVM_VolumeTable[] = {
+ 1.000f, /* 0dB */
+ 0.891f, /* -1dB */
+ 0.794f, /* -2dB */
+ 0.708f, /* -3dB */
+ 0.631f, /* -4dB */
+ 0.562f, /* -5dB */
+ 0.501f}; /* -6dB */
+#else
const LVM_INT16 LVM_VolumeTable[] = {
0x7FFF, /* 0dB */
0x7215, /* -1dB */
@@ -358,6 +704,7 @@
0x50C3, /* -4dB */
0x47FB, /* -5dB */
0x4000}; /* -6dB */
+#endif
/************************************************************************************/
/* */
diff --git a/media/libeffects/lvm/lib/Bundle/src/LVM_Tables.h b/media/libeffects/lvm/lib/Bundle/src/LVM_Tables.h
index a7601ff..4cf7119 100644
--- a/media/libeffects/lvm/lib/Bundle/src/LVM_Tables.h
+++ b/media/libeffects/lvm/lib/Bundle/src/LVM_Tables.h
@@ -37,16 +37,23 @@
/* */
/************************************************************************************/
+#ifdef BUILD_FLOAT
+extern FO_FLOAT_LShx_Coefs_t LVM_TrebleBoostCoefs[];
+#else
extern FO_C16_LShx_Coefs_t LVM_TrebleBoostCoefs[];
-
+#endif
/************************************************************************************/
/* */
/* Volume control gain and time constant tables */
/* */
/************************************************************************************/
-
+#ifdef BUILD_FLOAT
+extern const LVM_FLOAT LVM_VolumeTable[];
+#else
extern const LVM_INT16 LVM_VolumeTable[];
+#endif
+
extern const LVM_INT16 LVM_MixerTCTable[];
diff --git a/media/libeffects/lvm/lib/Common/lib/AGC.h b/media/libeffects/lvm/lib/Common/lib/AGC.h
index 2080d64..9a3d35d 100644
--- a/media/libeffects/lvm/lib/Common/lib/AGC.h
+++ b/media/libeffects/lvm/lib/Common/lib/AGC.h
@@ -37,7 +37,7 @@
/* Types */
/* */
/**********************************************************************************/
-
+#ifndef BUILD_FLOAT
typedef struct
{
LVM_INT32 AGC_Gain; /* The current AGC gain */
@@ -52,20 +52,39 @@
LVM_INT16 VolumeTC; /* Volume update time constant */
} AGC_MIX_VOL_2St1Mon_D32_t;
+#else
+typedef struct
+{
+ LVM_FLOAT AGC_Gain; /* The current AGC gain */
+ LVM_FLOAT AGC_MaxGain; /* The maximum AGC gain */
+ LVM_FLOAT Volume; /* The current volume setting */
+ LVM_FLOAT Target; /* The target volume setting */
+ LVM_FLOAT AGC_Target; /* AGC target level */
+ LVM_FLOAT AGC_Attack; /* AGC attack scaler */
+ LVM_FLOAT AGC_Decay; /* AGC decay scaler */
+ LVM_FLOAT VolumeTC; /* Volume update time constant */
+} AGC_MIX_VOL_2St1Mon_FLOAT_t;
+#endif
/**********************************************************************************/
/* */
/* Function Prototypes */
/* */
/**********************************************************************************/
-
+#ifdef BUILD_FLOAT
+void AGC_MIX_VOL_2St1Mon_D32_WRA(AGC_MIX_VOL_2St1Mon_FLOAT_t *pInstance, /* Instance pointer */
+ const LVM_FLOAT *pStSrc, /* Stereo source */
+ const LVM_FLOAT *pMonoSrc, /* Mono source */
+ LVM_FLOAT *pDst, /* Stereo destination */
+ LVM_UINT16 n); /* Number of samples */
+#else
void AGC_MIX_VOL_2St1Mon_D32_WRA(AGC_MIX_VOL_2St1Mon_D32_t *pInstance, /* Instance pointer */
const LVM_INT32 *pStSrc, /* Stereo source */
const LVM_INT32 *pMonoSrc, /* Mono source */
LVM_INT32 *pDst, /* Stereo destination */
LVM_UINT16 n); /* Number of samples */
-
+#endif
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/media/libeffects/lvm/lib/Common/lib/BIQUAD.h b/media/libeffects/lvm/lib/Common/lib/BIQUAD.h
index 7ac7fbd..3ee7f63 100644
--- a/media/libeffects/lvm/lib/Common/lib/BIQUAD.h
+++ b/media/libeffects/lvm/lib/Common/lib/BIQUAD.h
@@ -27,19 +27,34 @@
/**********************************************************************************
INSTANCE MEMORY TYPE DEFINITION
***********************************************************************************/
+#ifdef BUILD_FLOAT
+typedef struct
+{
+ LVM_FLOAT Storage[6];
+} Biquad_FLOAT_Instance_t;
+#else
typedef struct
{
LVM_INT32 Storage[6];
} Biquad_Instance_t;
-
-
+#endif
/**********************************************************************************
COEFFICIENT TYPE DEFINITIONS
***********************************************************************************/
/*** Biquad coefficients **********************************************************/
+#ifdef BUILD_FLOAT
+typedef struct
+{
+ LVM_FLOAT A2; /* a2 */
+ LVM_FLOAT A1; /* a1 */
+ LVM_FLOAT A0; /* a0 */
+ LVM_FLOAT B2; /* -b2! */
+ LVM_FLOAT B1; /* -b1! */
+} BQ_FLOAT_Coefs_t;
+#else
typedef struct
{
LVM_INT16 A2; /* a2 */
@@ -57,8 +72,17 @@
LVM_INT32 B2; /* -b2! */
LVM_INT32 B1; /* -b1! */
} BQ_C32_Coefs_t;
+#endif
/*** First order coefficients *****************************************************/
+#ifdef BUILD_FLOAT
+typedef struct
+{
+ LVM_FLOAT A1; /* a1 */
+ LVM_FLOAT A0; /* a0 */
+ LVM_FLOAT B1; /* -b1! */
+} FO_FLOAT_Coefs_t;
+#else
typedef struct
{
LVM_INT16 A1; /* a1 */
@@ -72,8 +96,17 @@
LVM_INT32 A0; /* a0 */
LVM_INT32 B1; /* -b1! */
} FO_C32_Coefs_t;
+#endif
/*** First order coefficients with Shift*****************************************************/
+#ifdef BUILD_FLOAT
+typedef struct
+{
+ LVM_FLOAT A1; /* a1 */
+ LVM_FLOAT A0; /* a0 */
+ LVM_FLOAT B1; /* -b1! */
+} FO_FLOAT_LShx_Coefs_t;
+#else
typedef struct
{
LVM_INT16 A1; /* a1 */
@@ -81,8 +114,16 @@
LVM_INT16 B1; /* -b1! */
LVM_INT16 Shift; /* Shift */
} FO_C16_LShx_Coefs_t;
-
+#endif
/*** Band pass coefficients *******************************************************/
+#ifdef BUILD_FLOAT
+typedef struct
+{
+ LVM_FLOAT A0; /* a0 */
+ LVM_FLOAT B2; /* -b2! */
+ LVM_FLOAT B1; /* -b1! */
+} BP_FLOAT_Coefs_t;
+#else
typedef struct
{
LVM_INT16 A0; /* a0 */
@@ -96,8 +137,18 @@
LVM_INT32 B2; /* -b2! */
LVM_INT32 B1; /* -b1! */
} BP_C32_Coefs_t;
+#endif
/*** Peaking coefficients *********************************************************/
+#ifdef BUILD_FLOAT
+typedef struct
+{
+ LVM_FLOAT A0; /* a0 */
+ LVM_FLOAT B2; /* -b2! */
+ LVM_FLOAT B1; /* -b1! */
+ LVM_FLOAT G; /* Gain */
+} PK_FLOAT_Coefs_t;
+#else
typedef struct
{
LVM_INT16 A0; /* a0 */
@@ -113,16 +164,26 @@
LVM_INT32 B1; /* -b1! */
LVM_INT16 G; /* Gain */
} PK_C32_Coefs_t;
-
+#endif
/**********************************************************************************
TAPS TYPE DEFINITIONS
***********************************************************************************/
/*** Types used for first order and shelving filter *******************************/
+#ifdef BUILD_FLOAT
+typedef struct
+{
+ LVM_FLOAT Storage[ (1 * 2) ]; /* One channel, two taps of size LVM_INT32 */
+} Biquad_1I_Order1_FLOAT_Taps_t;
typedef struct
{
+ LVM_FLOAT Storage[ (2 * 2) ]; /* Two channels, two taps of size LVM_INT32 */
+} Biquad_2I_Order1_FLOAT_Taps_t;
+#else
+typedef struct
+{
LVM_INT32 Storage[ (1*2) ]; /* One channel, two taps of size LVM_INT32 */
} Biquad_1I_Order1_Taps_t;
@@ -130,12 +191,22 @@
{
LVM_INT32 Storage[ (2*2) ]; /* Two channels, two taps of size LVM_INT32 */
} Biquad_2I_Order1_Taps_t;
-
+#endif
/*** Types used for biquad, band pass and peaking filter **************************/
+#ifdef BUILD_FLOAT
+typedef struct
+{
+ LVM_FLOAT Storage[ (1 * 4) ]; /* One channel, four taps of size LVM_INT32 */
+} Biquad_1I_Order2_FLOAT_Taps_t;
typedef struct
{
+ LVM_FLOAT Storage[ (2 * 4) ]; /* Two channels, four taps of size LVM_INT32 */
+} Biquad_2I_Order2_FLOAT_Taps_t;
+#else
+typedef struct
+{
LVM_INT32 Storage[ (1*4) ]; /* One channel, four taps of size LVM_INT32 */
} Biquad_1I_Order2_Taps_t;
@@ -143,7 +214,7 @@
{
LVM_INT32 Storage[ (2*4) ]; /* Two channels, four taps of size LVM_INT32 */
} Biquad_2I_Order2_Taps_t;
-
+#endif
/* The names of the functions are changed to satisfy QAC rules: Name should be Unique withing 16 characters*/
#define BQ_2I_D32F32Cll_TRC_WRA_01_Init Init_BQ_2I_D32F32Cll_TRC_WRA_01
#define BP_1I_D32F32C30_TRC_WRA_02 TWO_BP_1I_D32F32C30_TRC_WRA_02
@@ -154,59 +225,148 @@
/*** 16 bit data path *************************************************************/
+
+#ifdef BUILD_FLOAT
+void BQ_2I_D16F32Css_TRC_WRA_01_Init ( Biquad_FLOAT_Instance_t *pInstance,
+ Biquad_2I_Order2_FLOAT_Taps_t *pTaps,
+ BQ_FLOAT_Coefs_t *pCoef);
+#else
void BQ_2I_D16F32Css_TRC_WRA_01_Init ( Biquad_Instance_t *pInstance,
Biquad_2I_Order2_Taps_t *pTaps,
BQ_C16_Coefs_t *pCoef);
+#endif
+#ifdef BUILD_FLOAT
+void BQ_2I_D16F32C15_TRC_WRA_01 ( Biquad_FLOAT_Instance_t *pInstance,
+ LVM_FLOAT *pDataIn,
+ LVM_FLOAT *pDataOut,
+ LVM_INT16 NrSamples);
+#else
void BQ_2I_D16F32C15_TRC_WRA_01 ( Biquad_Instance_t *pInstance,
LVM_INT16 *pDataIn,
LVM_INT16 *pDataOut,
LVM_INT16 NrSamples);
+#endif
+#ifdef BUILD_FLOAT
+void BQ_2I_D16F32C14_TRC_WRA_01 ( Biquad_FLOAT_Instance_t *pInstance,
+ LVM_FLOAT *pDataIn,
+ LVM_FLOAT *pDataOut,
+ LVM_INT16 NrSamples);
+#else
void BQ_2I_D16F32C14_TRC_WRA_01 ( Biquad_Instance_t *pInstance,
LVM_INT16 *pDataIn,
LVM_INT16 *pDataOut,
LVM_INT16 NrSamples);
+#endif
+
+#ifdef BUILD_FLOAT
+void BQ_2I_D16F32C13_TRC_WRA_01 ( Biquad_FLOAT_Instance_t *pInstance,
+ LVM_FLOAT *pDataIn,
+ LVM_FLOAT *pDataOut,
+ LVM_INT16 NrSamples);
+#else
void BQ_2I_D16F32C13_TRC_WRA_01 ( Biquad_Instance_t *pInstance,
LVM_INT16 *pDataIn,
LVM_INT16 *pDataOut,
LVM_INT16 NrSamples);
+#endif
+
+#ifdef BUILD_FLOAT
+void BQ_2I_D16F16Css_TRC_WRA_01_Init ( Biquad_FLOAT_Instance_t *pInstance,
+ Biquad_2I_Order2_FLOAT_Taps_t *pTaps,
+ BQ_FLOAT_Coefs_t *pCoef);
+#else
void BQ_2I_D16F16Css_TRC_WRA_01_Init ( Biquad_Instance_t *pInstance,
Biquad_2I_Order2_Taps_t *pTaps,
BQ_C16_Coefs_t *pCoef);
+#endif
+
+#ifdef BUILD_FLOAT
+void BQ_2I_D16F16C15_TRC_WRA_01( Biquad_FLOAT_Instance_t *pInstance,
+ LVM_FLOAT *pDataIn,
+ LVM_FLOAT *pDataOut,
+ LVM_INT16 NrSamples);
+#else
void BQ_2I_D16F16C15_TRC_WRA_01( Biquad_Instance_t *pInstance,
LVM_INT16 *pDataIn,
LVM_INT16 *pDataOut,
LVM_INT16 NrSamples);
+#endif
+
+#ifdef BUILD_FLOAT
+void BQ_2I_D16F16C14_TRC_WRA_01( Biquad_FLOAT_Instance_t *pInstance,
+ LVM_FLOAT *pDataIn,
+ LVM_FLOAT *pDataOut,
+ LVM_INT16 NrSamples);
+#else
void BQ_2I_D16F16C14_TRC_WRA_01( Biquad_Instance_t *pInstance,
LVM_INT16 *pDataIn,
LVM_INT16 *pDataOut,
LVM_INT16 NrSamples);
+#endif
+#ifdef BUILD_FLOAT
+void BQ_1I_D16F16Css_TRC_WRA_01_Init ( Biquad_FLOAT_Instance_t *pInstance,
+ Biquad_1I_Order2_FLOAT_Taps_t *pTaps,
+ BQ_FLOAT_Coefs_t *pCoef);
+#else
void BQ_1I_D16F16Css_TRC_WRA_01_Init ( Biquad_Instance_t *pInstance,
Biquad_1I_Order2_Taps_t *pTaps,
BQ_C16_Coefs_t *pCoef);
+#endif
+
+#ifdef BUILD_FLOAT
+void BQ_1I_D16F16C15_TRC_WRA_01 ( Biquad_FLOAT_Instance_t *pInstance,
+ LVM_FLOAT *pDataIn,
+ LVM_FLOAT *pDataOut,
+ LVM_INT16 NrSamples);
+#else
void BQ_1I_D16F16C15_TRC_WRA_01( Biquad_Instance_t *pInstance,
LVM_INT16 *pDataIn,
LVM_INT16 *pDataOut,
LVM_INT16 NrSamples);
+#endif
+
+#ifdef BUILD_FLOAT
+void BQ_1I_D16F32Css_TRC_WRA_01_Init ( Biquad_FLOAT_Instance_t *pInstance,
+ Biquad_1I_Order2_FLOAT_Taps_t *pTaps,
+ BQ_FLOAT_Coefs_t *pCoef);
+#else
void BQ_1I_D16F32Css_TRC_WRA_01_Init ( Biquad_Instance_t *pInstance,
Biquad_1I_Order2_Taps_t *pTaps,
BQ_C16_Coefs_t *pCoef);
+#endif
+
+#ifdef BUILD_FLOAT
+void BQ_1I_D16F32C14_TRC_WRA_01 ( Biquad_FLOAT_Instance_t *pInstance,
+ LVM_FLOAT *pDataIn,
+ LVM_FLOAT *pDataOut,
+ LVM_INT16 NrSamples);
+#else
void BQ_1I_D16F32C14_TRC_WRA_01 ( Biquad_Instance_t *pInstance,
LVM_INT16 *pDataIn,
LVM_INT16 *pDataOut,
LVM_INT16 NrSamples);
+#endif
/*** 32 bit data path *************************************************************/
-
+#ifdef BUILD_FLOAT
+void BQ_2I_D32F32Cll_TRC_WRA_01_Init ( Biquad_FLOAT_Instance_t *pInstance,
+ Biquad_2I_Order2_FLOAT_Taps_t *pTaps,
+ BQ_FLOAT_Coefs_t *pCoef);
+void BQ_2I_D32F32C30_TRC_WRA_01 ( Biquad_FLOAT_Instance_t *pInstance,
+ LVM_FLOAT *pDataIn,
+ LVM_FLOAT *pDataOut,
+ LVM_INT16 NrSamples);
+#else
void BQ_2I_D32F32Cll_TRC_WRA_01_Init ( Biquad_Instance_t *pInstance,
Biquad_2I_Order2_Taps_t *pTaps,
BQ_C32_Coefs_t *pCoef);
@@ -215,33 +375,66 @@
LVM_INT32 *pDataIn,
LVM_INT32 *pDataOut,
LVM_INT16 NrSamples);
+#endif
/**********************************************************************************
FUNCTION PROTOTYPES: FIRST ORDER FILTERS
***********************************************************************************/
/*** 16 bit data path *************************************************************/
-
+#ifdef BUILD_FLOAT
+void FO_1I_D16F16Css_TRC_WRA_01_Init( Biquad_FLOAT_Instance_t *pInstance,
+ Biquad_1I_Order1_FLOAT_Taps_t *pTaps,
+ FO_FLOAT_Coefs_t *pCoef);
+#else
void FO_1I_D16F16Css_TRC_WRA_01_Init( Biquad_Instance_t *pInstance,
Biquad_1I_Order1_Taps_t *pTaps,
FO_C16_Coefs_t *pCoef);
+#endif
+#ifdef BUILD_FLOAT
+void FO_1I_D16F16C15_TRC_WRA_01( Biquad_FLOAT_Instance_t *pInstance,
+ LVM_FLOAT *pDataIn,
+ LVM_FLOAT *pDataOut,
+ LVM_INT16 NrSamples);
+#else
void FO_1I_D16F16C15_TRC_WRA_01( Biquad_Instance_t *pInstance,
LVM_INT16 *pDataIn,
LVM_INT16 *pDataOut,
LVM_INT16 NrSamples);
+#endif
+#ifdef BUILD_FLOAT
+void FO_2I_D16F32Css_LShx_TRC_WRA_01_Init(Biquad_FLOAT_Instance_t *pInstance,
+ Biquad_2I_Order1_FLOAT_Taps_t *pTaps,
+ FO_FLOAT_LShx_Coefs_t *pCoef);
+#else
void FO_2I_D16F32Css_LShx_TRC_WRA_01_Init(Biquad_Instance_t *pInstance,
Biquad_2I_Order1_Taps_t *pTaps,
FO_C16_LShx_Coefs_t *pCoef);
+#endif
+#ifdef BUILD_FLOAT
+void FO_2I_D16F32C15_LShx_TRC_WRA_01(Biquad_FLOAT_Instance_t *pInstance,
+ LVM_FLOAT *pDataIn,
+ LVM_FLOAT *pDataOut,
+ LVM_INT16 NrSamples);
+#else
void FO_2I_D16F32C15_LShx_TRC_WRA_01(Biquad_Instance_t *pInstance,
LVM_INT16 *pDataIn,
LVM_INT16 *pDataOut,
LVM_INT16 NrSamples);
-
+#endif
/*** 32 bit data path *************************************************************/
-
+#ifdef BUILD_FLOAT
+void FO_1I_D32F32Cll_TRC_WRA_01_Init( Biquad_FLOAT_Instance_t *pInstance,
+ Biquad_1I_Order1_FLOAT_Taps_t *pTaps,
+ FO_FLOAT_Coefs_t *pCoef);
+void FO_1I_D32F32C31_TRC_WRA_01( Biquad_FLOAT_Instance_t *pInstance,
+ LVM_FLOAT *pDataIn,
+ LVM_FLOAT *pDataOut,
+ LVM_INT16 NrSamples);
+#else
void FO_1I_D32F32Cll_TRC_WRA_01_Init( Biquad_Instance_t *pInstance,
Biquad_1I_Order1_Taps_t *pTaps,
FO_C32_Coefs_t *pCoef);
@@ -250,13 +443,28 @@
LVM_INT32 *pDataIn,
LVM_INT32 *pDataOut,
LVM_INT16 NrSamples);
-
+#endif
/**********************************************************************************
FUNCTION PROTOTYPES: BAND PASS FILTERS
***********************************************************************************/
/*** 16 bit data path *************************************************************/
-
+#ifdef BUILD_FLOAT
+void BP_1I_D16F16Css_TRC_WRA_01_Init( Biquad_FLOAT_Instance_t *pInstance,
+ Biquad_1I_Order2_FLOAT_Taps_t *pTaps,
+ BP_FLOAT_Coefs_t *pCoef);
+void BP_1I_D16F16C14_TRC_WRA_01 ( Biquad_FLOAT_Instance_t *pInstance,
+ LVM_FLOAT *pDataIn,
+ LVM_FLOAT *pDataOut,
+ LVM_INT16 NrSamples);
+void BP_1I_D16F32Cll_TRC_WRA_01_Init (Biquad_FLOAT_Instance_t *pInstance,
+ Biquad_1I_Order2_FLOAT_Taps_t *pTaps,
+ BP_FLOAT_Coefs_t *pCoef);
+void BP_1I_D16F32C30_TRC_WRA_01 ( Biquad_FLOAT_Instance_t *pInstance,
+ LVM_FLOAT *pDataIn,
+ LVM_FLOAT *pDataOut,
+ LVM_INT16 NrSamples);
+#else
void BP_1I_D16F16Css_TRC_WRA_01_Init ( Biquad_Instance_t *pInstance,
Biquad_1I_Order2_Taps_t *pTaps,
BP_C16_Coefs_t *pCoef);
@@ -274,10 +482,17 @@
LVM_INT16 *pDataIn,
LVM_INT16 *pDataOut,
LVM_INT16 NrSamples);
-
-
+#endif
/*** 32 bit data path *************************************************************/
-
+#ifdef BUILD_FLOAT
+void BP_1I_D32F32Cll_TRC_WRA_02_Init ( Biquad_FLOAT_Instance_t *pInstance,
+ Biquad_1I_Order2_FLOAT_Taps_t *pTaps,
+ BP_FLOAT_Coefs_t *pCoef);
+void BP_1I_D32F32C30_TRC_WRA_02( Biquad_FLOAT_Instance_t *pInstance,
+ LVM_FLOAT *pDataIn,
+ LVM_FLOAT *pDataOut,
+ LVM_INT16 NrSamples);
+#else
void BP_1I_D32F32Cll_TRC_WRA_02_Init ( Biquad_Instance_t *pInstance,
Biquad_1I_Order2_Taps_t *pTaps,
BP_C32_Coefs_t *pCoef);
@@ -286,42 +501,59 @@
LVM_INT32 *pDataIn,
LVM_INT32 *pDataOut,
LVM_INT16 NrSamples);
-
+#endif
/*** 32 bit data path STEREO ******************************************************/
-
+#ifndef BUILD_FLOAT
void PK_2I_D32F32CllGss_TRC_WRA_01_Init ( Biquad_Instance_t *pInstance,
Biquad_2I_Order2_Taps_t *pTaps,
PK_C32_Coefs_t *pCoef);
-
void PK_2I_D32F32C30G11_TRC_WRA_01 ( Biquad_Instance_t *pInstance,
LVM_INT32 *pDataIn,
LVM_INT32 *pDataOut,
LVM_INT16 NrSamples);
-
+#endif
+#ifdef BUILD_FLOAT
+void PK_2I_D32F32CssGss_TRC_WRA_01_Init ( Biquad_FLOAT_Instance_t *pInstance,
+ Biquad_2I_Order2_FLOAT_Taps_t *pTaps,
+ PK_FLOAT_Coefs_t *pCoef);
+#else
void PK_2I_D32F32CssGss_TRC_WRA_01_Init ( Biquad_Instance_t *pInstance,
Biquad_2I_Order2_Taps_t *pTaps,
PK_C16_Coefs_t *pCoef);
-
+#endif
+#ifdef BUILD_FLOAT
+void PK_2I_D32F32C14G11_TRC_WRA_01( Biquad_FLOAT_Instance_t *pInstance,
+ LVM_FLOAT *pDataIn,
+ LVM_FLOAT *pDataOut,
+ LVM_INT16 NrSamples);
+#else
void PK_2I_D32F32C14G11_TRC_WRA_01 ( Biquad_Instance_t *pInstance,
LVM_INT32 *pDataIn,
LVM_INT32 *pDataOut,
LVM_INT16 NrSamples);
-
+#endif
/**********************************************************************************
FUNCTION PROTOTYPES: DC REMOVAL FILTERS
***********************************************************************************/
/*** 16 bit data path STEREO ******************************************************/
+#ifdef BUILD_FLOAT
+void DC_2I_D16_TRC_WRA_01_Init ( Biquad_FLOAT_Instance_t *pInstance);
+void DC_2I_D16_TRC_WRA_01 ( Biquad_FLOAT_Instance_t *pInstance,
+ LVM_FLOAT *pDataIn,
+ LVM_FLOAT *pDataOut,
+ LVM_INT16 NrSamples);
+#else
void DC_2I_D16_TRC_WRA_01_Init ( Biquad_Instance_t *pInstance);
void DC_2I_D16_TRC_WRA_01 ( Biquad_Instance_t *pInstance,
LVM_INT16 *pDataIn,
LVM_INT16 *pDataOut,
LVM_INT16 NrSamples);
-
+#endif
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/media/libeffects/lvm/lib/Common/lib/CompLim.h b/media/libeffects/lvm/lib/Common/lib/CompLim.h
index 4cb8aa2..498faa3 100644
--- a/media/libeffects/lvm/lib/Common/lib/CompLim.h
+++ b/media/libeffects/lvm/lib/Common/lib/CompLim.h
@@ -66,13 +66,17 @@
/* Function Prototypes */
/* */
/************************************************************************************/
-
+#ifdef BUILD_FLOAT
+void NonLinComp_Float(LVM_FLOAT Gain,
+ LVM_FLOAT *pDataIn,
+ LVM_FLOAT *pDataOut,
+ LVM_INT32 BlockLength);
+#else
void NonLinComp_D16(LVM_INT16 Gain,
LVM_INT16 *pSterBfIn,
LVM_INT16 *pSterBfOut,
LVM_INT32 BlockLength);
-
-
+#endif
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/media/libeffects/lvm/lib/Common/lib/Filter.h b/media/libeffects/lvm/lib/Common/lib/Filter.h
index 229701a..0c8955d 100644
--- a/media/libeffects/lvm/lib/Common/lib/Filter.h
+++ b/media/libeffects/lvm/lib/Common/lib/Filter.h
@@ -33,11 +33,32 @@
DEFINES
***********************************************************************************/
#define FILTER_LOSS 32730 /* -0.01dB loss to avoid wrapping due to band ripple */
-
+#ifdef BUILD_FLOAT
+#define FILTER_LOSS_FLOAT 0.998849f
+#endif
/**********************************************************************************
FUNCTION PROTOTYPES
***********************************************************************************/
+#ifdef BUILD_FLOAT
+LVM_FLOAT LVM_Power10( LVM_FLOAT X);
+
+LVM_FLOAT LVM_Polynomial(LVM_UINT16 N,
+ LVM_FLOAT *pCoefficients,
+ LVM_FLOAT X);
+#ifdef HIGHER_FS
+LVM_FLOAT LVM_GetOmega(LVM_UINT32 Fc,
+#else
+LVM_FLOAT LVM_GetOmega(LVM_UINT16 Fc,
+#endif
+ LVM_Fs_en SampleRate);
+
+LVM_FLOAT LVM_FO_LPF( LVM_FLOAT w,
+ FO_FLOAT_Coefs_t *pCoeffs);
+
+LVM_FLOAT LVM_FO_HPF( LVM_FLOAT w,
+ FO_FLOAT_Coefs_t *pCoeffs);
+#else
LVM_INT32 LVM_Polynomial(LVM_UINT16 N,
LVM_INT32 *pCoefficients,
LVM_INT32 X);
@@ -52,7 +73,7 @@
LVM_INT32 LVM_GetOmega(LVM_UINT16 Fc,
LVM_Fs_en SampleRate);
-
+#endif
/**********************************************************************************/
#ifdef __cplusplus
}
diff --git a/media/libeffects/lvm/lib/Common/lib/LVM_Types.h b/media/libeffects/lvm/lib/Common/lib/LVM_Types.h
index 68c55f7..cb15b60 100644
--- a/media/libeffects/lvm/lib/Common/lib/LVM_Types.h
+++ b/media/libeffects/lvm/lib/Common/lib/LVM_Types.h
@@ -44,6 +44,9 @@
#define LVM_MAXINT_8 127 /* Maximum positive integer size */
#define LVM_MAXINT_16 32767
+#ifdef BUILD_FLOAT
+#define LVM_MAXFLOAT 1.0f
+#endif
#define LVM_MAXINT_32 2147483647
#define LVM_MAXENUM 2147483647
@@ -95,7 +98,9 @@
typedef int32_t LVM_INT32; /* Signed 32-bit word */
typedef uint32_t LVM_UINT32; /* Unsigned 32-bit word */
-
+#ifdef BUILD_FLOAT
+typedef float LVM_FLOAT; /* single precission floating point*/
+#endif
/****************************************************************************************/
/* */
/* Standard Enumerated types */
@@ -133,6 +138,10 @@
LVM_FS_32000 = 6,
LVM_FS_44100 = 7,
LVM_FS_48000 = 8,
+#ifdef HIGHER_FS
+ LVM_FS_96000 = 9,
+ LVM_FS_192000 = 10,
+#endif
LVM_FS_INVALID = LVM_MAXENUM-1,
LVM_FS_DUMMY = LVM_MAXENUM
} LVM_Fs_en;
diff --git a/media/libeffects/lvm/lib/Common/lib/Mixer.h b/media/libeffects/lvm/lib/Common/lib/Mixer.h
index 89deb0d..07c53cd 100644
--- a/media/libeffects/lvm/lib/Common/lib/Mixer.h
+++ b/media/libeffects/lvm/lib/Common/lib/Mixer.h
@@ -30,6 +30,43 @@
INSTANCE MEMORY TYPE DEFINITION
***********************************************************************************/
+#ifdef BUILD_FLOAT /* BUILD_FLOAT*/
+typedef struct
+{
+ LVM_FLOAT Alpha; /* Time constant. Set by calling application. \
+ Can be changed at any time */
+ LVM_FLOAT Target; /* Target value. Set by calling application. \
+ Can be changed at any time */
+ LVM_FLOAT Current; /* Current value. Set by the mixer function. */
+ LVM_INT16 CallbackSet; /* Boolean. Should be set by calling application \
+ each time the target value is updated */
+ LVM_INT16 CallbackParam; /* Parameter that will be used in the calback function */
+ void *pCallbackHandle; /* Pointer to the instance of the callback function */
+ void *pGeneralPurpose; /* Pointer for general purpose usage */
+ LVM_Callback pCallBack; /* Pointer to the callback function */
+} Mix_1St_Cll_FLOAT_t;
+typedef struct
+{
+ LVM_FLOAT Alpha1;
+ LVM_FLOAT Target1;
+ LVM_FLOAT Current1;
+ LVM_INT16 CallbackSet1;
+ LVM_INT16 CallbackParam1;
+ void *pCallbackHandle1;
+ void *pGeneralPurpose1;
+ LVM_Callback pCallBack1;
+
+ LVM_FLOAT Alpha2; /* Warning the address of this location is passed as a \
+ pointer to Mix_1St_Cll_t in some functions */
+ LVM_FLOAT Target2;
+ LVM_FLOAT Current2;
+ LVM_INT16 CallbackSet2;
+ LVM_INT16 CallbackParam2;
+ void *pCallbackHandle2;
+ void *pGeneralPurpose2;
+ LVM_Callback pCallBack2;
+} Mix_2St_Cll_FLOAT_t;
+#else
typedef struct
{
LVM_INT32 Alpha; /* Time constant. Set by calling application. Can be changed at any time */
@@ -64,9 +101,35 @@
} Mix_2St_Cll_t;
+#endif
/*** General functions ************************************************************/
+#ifdef BUILD_FLOAT
+LVM_FLOAT LVM_Mixer_TimeConstant(LVM_UINT32 tc,
+#ifdef HIGHER_FS
+ LVM_UINT32 Fs,
+#else
+ LVM_UINT16 Fs,
+#endif
+ LVM_UINT16 NumChannels);
+
+void MixSoft_1St_D32C31_WRA( Mix_1St_Cll_FLOAT_t *pInstance,
+ const LVM_FLOAT *src,
+ LVM_FLOAT *dst,
+ LVM_INT16 n);
+
+void MixSoft_2St_D32C31_SAT( Mix_2St_Cll_FLOAT_t *pInstance,
+ const LVM_FLOAT *src1,
+ const LVM_FLOAT *src2,
+ LVM_FLOAT *dst,
+ LVM_INT16 n);
+
+void MixInSoft_D32C31_SAT( Mix_1St_Cll_FLOAT_t *pInstance,
+ const LVM_FLOAT *src,
+ LVM_FLOAT *dst,
+ LVM_INT16 n);
+#else
LVM_UINT32 LVM_Mixer_TimeConstant(LVM_UINT32 tc,
LVM_UINT16 Fs,
LVM_UINT16 NumChannels);
@@ -88,10 +151,26 @@
LVM_INT32 *dst,
LVM_INT16 n);
+#endif
+
/**********************************************************************************
FUNCTION PROTOTYPES (LOW LEVEL SUBFUNCTIONS)
***********************************************************************************/
-
+#ifdef BUILD_FLOAT
+void Core_MixSoft_1St_D32C31_WRA( Mix_1St_Cll_FLOAT_t *pInstance,
+ const LVM_FLOAT *src,
+ LVM_FLOAT *dst,
+ LVM_INT16 n);
+void Core_MixHard_2St_D32C31_SAT( Mix_2St_Cll_FLOAT_t *pInstance,
+ const LVM_FLOAT *src1,
+ const LVM_FLOAT *src2,
+ LVM_FLOAT *dst,
+ LVM_INT16 n);
+void Core_MixInSoft_D32C31_SAT( Mix_1St_Cll_FLOAT_t *pInstance,
+ const LVM_FLOAT *src,
+ LVM_FLOAT *dst,
+ LVM_INT16 n);
+#else
void Core_MixSoft_1St_D32C31_WRA( Mix_1St_Cll_t *pInstance,
const LVM_INT32 *src,
LVM_INT32 *dst,
@@ -107,6 +186,7 @@
const LVM_INT32 *src,
LVM_INT32 *dst,
LVM_INT16 n);
+#endif
#ifdef __cplusplus
}
#endif /* __cplusplus */
@@ -115,13 +195,3 @@
/**********************************************************************************/
#endif /* __MIXER_H__ */
-
-
-
-
-
-
-
-
-
-
diff --git a/media/libeffects/lvm/lib/Common/lib/ScalarArithmetic.h b/media/libeffects/lvm/lib/Common/lib/ScalarArithmetic.h
index 3d62704..cdb3837 100644
--- a/media/libeffects/lvm/lib/Common/lib/ScalarArithmetic.h
+++ b/media/libeffects/lvm/lib/Common/lib/ScalarArithmetic.h
@@ -34,7 +34,12 @@
/*######################################################################################*/
/* Absolute value including the corner case for the extreme negative value */
+
+#ifdef BUILD_FLOAT
+LVM_FLOAT Abs_Float(LVM_FLOAT input);
+#else
LVM_INT32 Abs_32(LVM_INT32 input);
+#endif
/****************************************************************************************
* Name : dB_to_Lin32()
@@ -48,8 +53,11 @@
* (15->01) = decimal part
* Returns : Lin value format 1.16.15
****************************************************************************************/
-
+#ifdef BUILD_FLOAT
+LVM_FLOAT dB_to_LinFloat(LVM_INT16 db_fix);
+#else
LVM_INT32 dB_to_Lin32(LVM_INT16 db_fix);
+#endif
#ifdef __cplusplus
}
diff --git a/media/libeffects/lvm/lib/Common/lib/VectorArithmetic.h b/media/libeffects/lvm/lib/Common/lib/VectorArithmetic.h
index 2b791bd..0ba20a3 100644
--- a/media/libeffects/lvm/lib/Common/lib/VectorArithmetic.h
+++ b/media/libeffects/lvm/lib/Common/lib/VectorArithmetic.h
@@ -29,6 +29,11 @@
VARIOUS FUNCTIONS
***********************************************************************************/
+#ifdef BUILD_FLOAT
+void LoadConst_Float( const LVM_FLOAT val,
+ LVM_FLOAT *dst,
+ LVM_INT16 n );
+#else
void LoadConst_16( const LVM_INT16 val,
LVM_INT16 *dst,
LVM_INT16 n );
@@ -36,10 +41,17 @@
void LoadConst_32( const LVM_INT32 val,
LVM_INT32 *dst,
LVM_INT16 n );
+#endif
+#ifdef BUILD_FLOAT
+void Copy_Float( const LVM_FLOAT *src,
+ LVM_FLOAT *dst,
+ LVM_INT16 n );
+#else
void Copy_16( const LVM_INT16 *src,
LVM_INT16 *dst,
LVM_INT16 n );
+#endif
/*********************************************************************************
* note: In Mult3s_16x16() saturation of result is not taken care when *
@@ -49,10 +61,17 @@
* This is the only case which will give wrong result. *
* For more information refer to Vector_Arithmetic.doc in /doc folder *
*********************************************************************************/
+#ifdef BUILD_FLOAT
+void Mult3s_Float( const LVM_FLOAT *src,
+ const LVM_FLOAT val,
+ LVM_FLOAT *dst,
+ LVM_INT16 n);
+#else
void Mult3s_16x16( const LVM_INT16 *src,
const LVM_INT16 val,
- LVM_INT16 *dst,
- LVM_INT16 n);
+ LVM_INT16 *dst,
+ LVM_INT16 n);
+#endif
/*********************************************************************************
* note: In Mult3s_32x16() saturation of result is not taken care when *
@@ -66,20 +85,31 @@
const LVM_INT16 val,
LVM_INT32 *dst,
LVM_INT16 n);
-
+#ifdef BUILD_FLOAT
+void DelayMix_Float(const LVM_FLOAT *src, /* Source 1, to be delayed */
+ LVM_FLOAT *delay, /* Delay buffer */
+ LVM_INT16 size, /* Delay size */
+ LVM_FLOAT *dst, /* Source/destination */
+ LVM_INT16 *pOffset, /* Delay offset */
+ LVM_INT16 n) ; /* Number of stereo samples */
+#else
void DelayMix_16x16( const LVM_INT16 *src,
LVM_INT16 *delay,
LVM_INT16 size,
LVM_INT16 *dst,
LVM_INT16 *pOffset,
LVM_INT16 n);
-
+#endif
void DelayWrite_32( const LVM_INT32 *src, /* Source 1, to be delayed */
LVM_INT32 *delay, /* Delay buffer */
LVM_UINT16 size, /* Delay size */
LVM_UINT16 *pOffset, /* Delay offset */
LVM_INT16 n);
-
+#ifdef BUILD_FLOAT
+void Add2_Sat_Float( const LVM_FLOAT *src,
+ LVM_FLOAT *dst,
+ LVM_INT16 n );
+#else
void Add2_Sat_16x16( const LVM_INT16 *src,
LVM_INT16 *dst,
LVM_INT16 n );
@@ -87,7 +117,13 @@
void Add2_Sat_32x32( const LVM_INT32 *src,
LVM_INT32 *dst,
LVM_INT16 n );
-
+#endif
+#ifdef BUILD_FLOAT
+void Mac3s_Sat_Float( const LVM_FLOAT *src,
+ const LVM_FLOAT val,
+ LVM_FLOAT *dst,
+ LVM_INT16 n);
+#else
void Mac3s_Sat_16x16( const LVM_INT16 *src,
const LVM_INT16 val,
LVM_INT16 *dst,
@@ -97,7 +133,7 @@
const LVM_INT16 val,
LVM_INT32 *dst,
LVM_INT16 n);
-
+#endif
void DelayAllPass_Sat_32x16To32( LVM_INT32 *delay, /* Delay buffer */
LVM_UINT16 size, /* Delay size */
LVM_INT16 coeff, /* All pass filter coefficient */
@@ -109,7 +145,12 @@
/**********************************************************************************
SHIFT FUNCTIONS
***********************************************************************************/
-
+#ifdef BUILD_FLOAT
+void Shift_Sat_Float (const LVM_INT16 val,
+ const LVM_FLOAT *src,
+ LVM_FLOAT *dst,
+ LVM_INT16 n);
+#else
void Shift_Sat_v16xv16 ( const LVM_INT16 val,
const LVM_INT16 *src,
LVM_INT16 *dst,
@@ -119,11 +160,15 @@
const LVM_INT32 *src,
LVM_INT32 *dst,
LVM_INT16 n);
-
+#endif
/**********************************************************************************
AUDIO FORMAT CONVERSION FUNCTIONS
***********************************************************************************/
-
+#ifdef BUILD_FLOAT
+void MonoTo2I_Float( const LVM_FLOAT *src,
+ LVM_FLOAT *dst,
+ LVM_INT16 n);
+#else
void MonoTo2I_16( const LVM_INT16 *src,
LVM_INT16 *dst,
LVM_INT16 n);
@@ -131,29 +176,52 @@
void MonoTo2I_32( const LVM_INT32 *src,
LVM_INT32 *dst,
LVM_INT16 n);
-
+#endif
+#ifdef BUILD_FLOAT
+void From2iToMono_Float( const LVM_FLOAT *src,
+ LVM_FLOAT *dst,
+ LVM_INT16 n);
+#else
void From2iToMono_32( const LVM_INT32 *src,
LVM_INT32 *dst,
LVM_INT16 n);
-
+#endif
+#ifdef BUILD_FLOAT
+void MSTo2i_Sat_Float( const LVM_FLOAT *srcM,
+ const LVM_FLOAT *srcS,
+ LVM_FLOAT *dst,
+ LVM_INT16 n );
+#else
void MSTo2i_Sat_16x16( const LVM_INT16 *srcM,
const LVM_INT16 *srcS,
LVM_INT16 *dst,
LVM_INT16 n );
-
+#endif
+#ifdef BUILD_FLOAT
+void From2iToMS_Float( const LVM_FLOAT *src,
+ LVM_FLOAT *dstM,
+ LVM_FLOAT *dstS,
+ LVM_INT16 n );
+#else
void From2iToMS_16x16( const LVM_INT16 *src,
LVM_INT16 *dstM,
LVM_INT16 *dstS,
LVM_INT16 n );
-
+#endif
+#ifdef BUILD_FLOAT
+void JoinTo2i_Float( const LVM_FLOAT *srcL,
+ const LVM_FLOAT *srcR,
+ LVM_FLOAT *dst,
+ LVM_INT16 n );
+#else
void From2iToMono_16( const LVM_INT16 *src,
LVM_INT16 *dst,
LVM_INT16 n);
-
void JoinTo2i_32x32( const LVM_INT32 *srcL,
const LVM_INT32 *srcR,
- LVM_INT32 *dst,
- LVM_INT16 n );
+ LVM_INT32 *dst,
+ LVM_INT16 n );
+#endif
/**********************************************************************************
DATA TYPE CONVERSION FUNCTIONS
diff --git a/media/libeffects/lvm/lib/Common/src/AGC_MIX_VOL_2St1Mon_D32_WRA.c b/media/libeffects/lvm/lib/Common/src/AGC_MIX_VOL_2St1Mon_D32_WRA.c
index 920b515..fa9f01f 100644
--- a/media/libeffects/lvm/lib/Common/src/AGC_MIX_VOL_2St1Mon_D32_WRA.c
+++ b/media/libeffects/lvm/lib/Common/src/AGC_MIX_VOL_2St1Mon_D32_WRA.c
@@ -33,7 +33,10 @@
#define VOL_TC_SHIFT 21 /* As a power of 2 */
#define DECAY_SHIFT 10 /* As a power of 2 */
-
+#ifdef BUILD_FLOAT
+#define VOL_TC_FLOAT 2.0f /* As a power of 2 */
+#define DECAY_FAC_FLOAT 64.0f /* As a power of 2 */
+#endif
/****************************************************************************************/
/* */
@@ -69,7 +72,7 @@
/* NOTES: */
/* */
/****************************************************************************************/
-
+#ifndef BUILD_FLOAT
void AGC_MIX_VOL_2St1Mon_D32_WRA(AGC_MIX_VOL_2St1Mon_D32_t *pInstance, /* Instance pointer */
const LVM_INT32 *pStSrc, /* Stereo source */
const LVM_INT32 *pMonoSrc, /* Mono source */
@@ -193,4 +196,113 @@
return;
}
+#else
+void AGC_MIX_VOL_2St1Mon_D32_WRA(AGC_MIX_VOL_2St1Mon_FLOAT_t *pInstance, /* Instance pointer */
+ const LVM_FLOAT *pStSrc, /* Stereo source */
+ const LVM_FLOAT *pMonoSrc, /* Mono source */
+ LVM_FLOAT *pDst, /* Stereo destination */
+ LVM_UINT16 NumSamples) /* Number of samples */
+{
+ /*
+ * General variables
+ */
+ LVM_UINT16 i; /* Sample index */
+ LVM_FLOAT Left; /* Left sample */
+ LVM_FLOAT Right; /* Right sample */
+ LVM_FLOAT Mono; /* Mono sample */
+ LVM_FLOAT AbsPeak; /* Absolute peak signal */
+ LVM_FLOAT AGC_Mult; /* Short AGC gain */
+ LVM_FLOAT Vol_Mult; /* Short volume */
+
+
+ /*
+ * Instance control variables
+ */
+ LVM_FLOAT AGC_Gain = pInstance->AGC_Gain; /* Get the current AGC gain */
+ LVM_FLOAT AGC_MaxGain = pInstance->AGC_MaxGain; /* Get maximum AGC gain */
+ LVM_FLOAT AGC_Attack = pInstance->AGC_Attack; /* Attack scaler */
+ LVM_FLOAT AGC_Decay = (pInstance->AGC_Decay * (1 << (DECAY_SHIFT)));/* Decay scaler */
+ LVM_FLOAT AGC_Target = pInstance->AGC_Target; /* Get the target level */
+ LVM_FLOAT Vol_Current = pInstance->Volume; /* Actual volume setting */
+ LVM_FLOAT Vol_Target = pInstance->Target; /* Target volume setting */
+ LVM_FLOAT Vol_TC = pInstance->VolumeTC; /* Time constant */
+
+
+ /*
+ * Process on a sample by sample basis
+ */
+ for (i = 0; i < NumSamples; i++) /* For each sample */
+ {
+
+ /*
+ * Get the short scalers
+ */
+ AGC_Mult = (LVM_FLOAT)(AGC_Gain); /* Get the short AGC gain */
+ Vol_Mult = (LVM_FLOAT)(Vol_Current); /* Get the short volume gain */
+
+
+ /*
+ * Get the input samples
+ */
+ Left = *pStSrc++; /* Get the left sample */
+ Right = *pStSrc++; /* Get the right sample */
+ Mono = *pMonoSrc++; /* Get the mono sample */
+
+
+ /*
+ * Apply the AGC gain to the mono input and mix with the stereo signal
+ */
+ Left += (Mono * AGC_Mult); /* Mix in the mono signal */
+ Right += (Mono * AGC_Mult);
+
+ /*
+ * Apply the volume and write to the output stream
+ */
+ Left = Left * Vol_Mult;
+ Right = Right * Vol_Mult;
+ *pDst++ = Left; /* Save the results */
+ *pDst++ = Right;
+
+ /*
+ * Update the AGC gain
+ */
+ AbsPeak = Abs_Float(Left) > Abs_Float(Right) ? Abs_Float(Left) : Abs_Float(Right);
+ if (AbsPeak > AGC_Target)
+ {
+ /*
+ * The signal is too large so decrease the gain
+ */
+ AGC_Gain = AGC_Gain * AGC_Attack;
+ }
+ else
+ {
+ /*
+ * The signal is too small so increase the gain
+ */
+ if (AGC_Gain > AGC_MaxGain)
+ {
+ AGC_Gain -= (AGC_Decay);
+ }
+ else
+ {
+ AGC_Gain += (AGC_Decay);
+ }
+ }
+
+ /*
+ * Update the gain
+ */
+ Vol_Current += (Vol_Target - Vol_Current) * ((LVM_FLOAT)Vol_TC / VOL_TC_FLOAT);
+ }
+
+
+ /*
+ * Update the parameters
+ */
+ pInstance->Volume = Vol_Current; /* Actual volume setting */
+ pInstance->AGC_Gain = AGC_Gain;
+
+ return;
+}
+#endif /*BUILD_FLOAT*/
diff --git a/media/libeffects/lvm/lib/Common/src/Abs_32.c b/media/libeffects/lvm/lib/Common/src/Abs_32.c
index 9128b82..84fabd8 100644
--- a/media/libeffects/lvm/lib/Common/src/Abs_32.c
+++ b/media/libeffects/lvm/lib/Common/src/Abs_32.c
@@ -47,4 +47,14 @@
}
return input;
}
-
+#ifdef BUILD_FLOAT
+LVM_FLOAT Abs_Float(LVM_FLOAT input)
+{
+ if(input < 0)
+ {
+ /* Negative input, so invert */
+ input = (LVM_FLOAT)(-input);
+ }
+ return input;
+}
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/Add2_Sat_32x32.c b/media/libeffects/lvm/lib/Common/src/Add2_Sat_32x32.c
index 69d357e..e3edccc 100644
--- a/media/libeffects/lvm/lib/Common/src/Add2_Sat_32x32.c
+++ b/media/libeffects/lvm/lib/Common/src/Add2_Sat_32x32.c
@@ -57,4 +57,33 @@
return;
}
+#ifdef BUILD_FLOAT
+void Add2_Sat_Float( const LVM_FLOAT *src,
+ LVM_FLOAT *dst,
+ LVM_INT16 n )
+{
+ LVM_FLOAT Temp;
+ LVM_INT16 ii;
+ for (ii = n; ii != 0; ii--)
+ {
+ Temp = ((LVM_FLOAT) *src) + ((LVM_FLOAT) *dst);
+ src++;
+
+ if (Temp > 1.000000f)
+ {
+ *dst = 1.000000f;
+ }
+ else if (Temp < -1.000000f)
+ {
+ *dst = -1.000000f;
+ }
+ else
+ {
+ *dst = Temp;
+ }
+ dst++;
+ }
+ return;
+}
+#endif
/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/BP_1I_D16F16C14_TRC_WRA_01.c b/media/libeffects/lvm/lib/Common/src/BP_1I_D16F16C14_TRC_WRA_01.c
index f4c5757..88f9986 100644
--- a/media/libeffects/lvm/lib/Common/src/BP_1I_D16F16C14_TRC_WRA_01.c
+++ b/media/libeffects/lvm/lib/Common/src/BP_1I_D16F16C14_TRC_WRA_01.c
@@ -33,7 +33,51 @@
pBiquadState->pDelays[2] is y(n-1)L in Q0 format
pBiquadState->pDelays[3] is y(n-2)L in Q0 format
***************************************************************************/
+#ifdef BUILD_FLOAT
+void BP_1I_D16F16C14_TRC_WRA_01 ( Biquad_FLOAT_Instance_t *pInstance,
+ LVM_FLOAT *pDataIn,
+ LVM_FLOAT *pDataOut,
+ LVM_INT16 NrSamples)
+
+ {
+ LVM_FLOAT ynL;
+ LVM_INT16 ii;
+ PFilter_State_FLOAT pBiquadState = (PFilter_State_FLOAT) pInstance;
+
+ for (ii = NrSamples; ii != 0; ii--)
+ {
+
+
+ /**************************************************************************
+ PROCESSING OF THE LEFT CHANNEL
+ ***************************************************************************/
+ // ynL= (A0 * (x(n)L - x(n-2)L ) )
+ ynL = pBiquadState->coefs[0] * ((*pDataIn)-pBiquadState->pDelays[1]);
+
+ // ynL+= ((-B2 * y(n-2)L ) )
+ ynL += pBiquadState->coefs[1] * pBiquadState->pDelays[3];
+
+ // ynL+= ((-B1 * y(n-1)L ) )
+ ynL += pBiquadState->coefs[2] * pBiquadState->pDelays[2];
+
+ /**************************************************************************
+ UPDATING THE DELAYS
+ ***************************************************************************/
+ pBiquadState->pDelays[3] = pBiquadState->pDelays[2]; // y(n-2)L=y(n-1)L
+ pBiquadState->pDelays[1] = pBiquadState->pDelays[0]; // x(n-2)L=x(n-1)L
+ pBiquadState->pDelays[2] = ynL; // Update y(n-1)L
+ pBiquadState->pDelays[0] = (*pDataIn++); // Update x(n-1)L
+
+ /**************************************************************************
+ WRITING THE OUTPUT
+ ***************************************************************************/
+ *pDataOut++=ynL; // Write Left output
+
+ }
+
+ }
+#else
void BP_1I_D16F16C14_TRC_WRA_01 ( Biquad_Instance_t *pInstance,
LVM_INT16 *pDataIn,
LVM_INT16 *pDataOut,
@@ -78,4 +122,5 @@
}
}
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/BP_1I_D16F16Css_TRC_WRA_01_Init.c b/media/libeffects/lvm/lib/Common/src/BP_1I_D16F16Css_TRC_WRA_01_Init.c
index 88914ad..27ab57a 100644
--- a/media/libeffects/lvm/lib/Common/src/BP_1I_D16F16Css_TRC_WRA_01_Init.c
+++ b/media/libeffects/lvm/lib/Common/src/BP_1I_D16F16Css_TRC_WRA_01_Init.c
@@ -38,6 +38,19 @@
/* RETURNS: */
/* void return code */
/*-------------------------------------------------------------------------*/
+#ifdef BUILD_FLOAT
+void BP_1I_D16F16Css_TRC_WRA_01_Init ( Biquad_FLOAT_Instance_t *pInstance,
+ Biquad_1I_Order2_FLOAT_Taps_t *pTaps,
+ BP_FLOAT_Coefs_t *pCoef)
+{
+ PFilter_State_FLOAT pBiquadState = (PFilter_State_FLOAT) pInstance;
+ pBiquadState->pDelays = (LVM_FLOAT *) pTaps;
+
+ pBiquadState->coefs[0] = pCoef->A0;
+ pBiquadState->coefs[1] = pCoef->B2;
+ pBiquadState->coefs[2] = pCoef->B1;
+}
+#else
void BP_1I_D16F16Css_TRC_WRA_01_Init ( Biquad_Instance_t *pInstance,
Biquad_1I_Order2_Taps_t *pTaps,
BP_C16_Coefs_t *pCoef)
@@ -49,6 +62,7 @@
pBiquadState->coefs[1]=pCoef->B2;
pBiquadState->coefs[2]=pCoef->B1;
}
+#endif
/*-------------------------------------------------------------------------*/
/* End Of File: BP_1I_D16F16Css_TRC_WRA_01_Init.c */
diff --git a/media/libeffects/lvm/lib/Common/src/BP_1I_D16F16Css_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/BP_1I_D16F16Css_TRC_WRA_01_Private.h
index 980539c..e194f92 100644
--- a/media/libeffects/lvm/lib/Common/src/BP_1I_D16F16Css_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/BP_1I_D16F16Css_TRC_WRA_01_Private.h
@@ -27,4 +27,13 @@
typedef Filter_State * PFilter_State ;
+#ifdef BUILD_FLOAT
+typedef struct _Filter_State_FLOAT
+{
+
+ LVM_FLOAT * pDelays; /* pointer to the delayed samples (data of 32 bits) */
+ LVM_FLOAT coefs[3]; /* pointer to the filter coefficients */
+}Filter_State_FLOAT;
+typedef Filter_State_FLOAT * PFilter_State_FLOAT ;
+#endif
#endif /*_BP_1I_D16F16CSS_TRC_WRA_01_PRIVATE_H_*/
diff --git a/media/libeffects/lvm/lib/Common/src/BP_1I_D16F32C30_TRC_WRA_01.c b/media/libeffects/lvm/lib/Common/src/BP_1I_D16F32C30_TRC_WRA_01.c
index ba1a42f..3abdd43 100644
--- a/media/libeffects/lvm/lib/Common/src/BP_1I_D16F32C30_TRC_WRA_01.c
+++ b/media/libeffects/lvm/lib/Common/src/BP_1I_D16F32C30_TRC_WRA_01.c
@@ -33,7 +33,48 @@
pBiquadState->pDelays[2] is y(n-1)L in Q16 format
pBiquadState->pDelays[3] is y(n-2)L in Q16 format
***************************************************************************/
+#ifdef BUILD_FLOAT
+void BP_1I_D16F32C30_TRC_WRA_01 ( Biquad_FLOAT_Instance_t *pInstance,
+ LVM_FLOAT *pDataIn,
+ LVM_FLOAT *pDataOut,
+ LVM_INT16 NrSamples)
+{
+ LVM_FLOAT ynL,templ;
+ LVM_INT16 ii;
+ PFilter_State_FLOAT pBiquadState = (PFilter_State_FLOAT)pInstance;
+ for (ii = NrSamples; ii != 0; ii--)
+ {
+ /**************************************************************************
+ PROCESSING OF THE LEFT CHANNEL
+ ***************************************************************************/
+ // ynL= (A0 * (x(n)L - x(n-2)L ))
+ templ = (LVM_FLOAT) *pDataIn - pBiquadState->pDelays[1];
+ ynL = pBiquadState->coefs[0] * templ;
+
+ // ynL+= ((-B2 * y(n-2)L ) )
+ templ = pBiquadState->coefs[1] * pBiquadState->pDelays[3];
+ ynL += templ;
+
+ // ynL+= ((-B1 * y(n-1)L ))
+ templ = pBiquadState->coefs[2] * pBiquadState->pDelays[2];
+ ynL += templ;
+
+ /**************************************************************************
+ UPDATING THE DELAYS
+ ***************************************************************************/
+ pBiquadState->pDelays[3] = pBiquadState->pDelays[2]; // y(n-2)L=y(n-1)L
+ pBiquadState->pDelays[1] = pBiquadState->pDelays[0]; // x(n-2)L=x(n-1)L
+ pBiquadState->pDelays[2] = ynL; // Update y(n-1)L in Q16
+ pBiquadState->pDelays[0] = (*pDataIn++); // Update x(n-1)L in Q0
+
+ /**************************************************************************
+ WRITING THE OUTPUT
+ ***************************************************************************/
+ *pDataOut++ = (ynL); // Write Left output
+ }
+}
+#else
void BP_1I_D16F32C30_TRC_WRA_01 ( Biquad_Instance_t *pInstance,
LVM_INT16 *pDataIn,
LVM_INT16 *pDataOut,
@@ -80,4 +121,4 @@
}
}
-
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/BP_1I_D16F32Cll_TRC_WRA_01_Init.c b/media/libeffects/lvm/lib/Common/src/BP_1I_D16F32Cll_TRC_WRA_01_Init.c
index e833218..d6e047a 100644
--- a/media/libeffects/lvm/lib/Common/src/BP_1I_D16F32Cll_TRC_WRA_01_Init.c
+++ b/media/libeffects/lvm/lib/Common/src/BP_1I_D16F32Cll_TRC_WRA_01_Init.c
@@ -48,6 +48,20 @@
/* RETURNS: */
/* void return code */
/*-------------------------------------------------------------------------*/
+#ifdef BUILD_FLOAT
+void BP_1I_D16F32Cll_TRC_WRA_01_Init ( Biquad_FLOAT_Instance_t *pInstance,
+ Biquad_1I_Order2_FLOAT_Taps_t *pTaps,
+ BP_FLOAT_Coefs_t *pCoef)
+{
+ PFilter_State_FLOAT pBiquadState = (PFilter_State_FLOAT) pInstance;
+ pBiquadState->pDelays =(LVM_FLOAT *) pTaps;
+
+
+ pBiquadState->coefs[0] = pCoef->A0;
+ pBiquadState->coefs[1] = pCoef->B2;
+ pBiquadState->coefs[2] = pCoef->B1;
+}
+#else
void BP_1I_D16F32Cll_TRC_WRA_01_Init ( Biquad_Instance_t *pInstance,
Biquad_1I_Order2_Taps_t *pTaps,
BP_C32_Coefs_t *pCoef)
@@ -59,6 +73,7 @@
pBiquadState->coefs[1] = pCoef->B2;
pBiquadState->coefs[2] = pCoef->B1;
}
+#endif
/*-------------------------------------------------------------------------*/
/* End Of File: BP_1I_D16F32Cll_TRC_WRA_01_Init.c */
diff --git a/media/libeffects/lvm/lib/Common/src/BP_1I_D16F32Cll_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/BP_1I_D16F32Cll_TRC_WRA_01_Private.h
index 9cca627..aa9e669 100644
--- a/media/libeffects/lvm/lib/Common/src/BP_1I_D16F32Cll_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/BP_1I_D16F32Cll_TRC_WRA_01_Private.h
@@ -26,5 +26,12 @@
}Filter_State;
typedef Filter_State * PFilter_State ;
-
+#ifdef BUILD_FLOAT
+typedef struct _Filter_State_FLOAT
+{
+ LVM_FLOAT * pDelays; /* pointer to the delayed samples (data of 32 bits) */
+ LVM_FLOAT coefs[3]; /* pointer to the filter coefficients */
+}Filter_State_Float;
+typedef Filter_State_Float * PFilter_State_FLOAT ;
+#endif
#endif /*_BP_1I_D16F32CLL_TRC_WRA_01_PRIVATE_H_*/
diff --git a/media/libeffects/lvm/lib/Common/src/BP_1I_D32F32C30_TRC_WRA_02.c b/media/libeffects/lvm/lib/Common/src/BP_1I_D32F32C30_TRC_WRA_02.c
index b09c1aa..abdb2f7 100644
--- a/media/libeffects/lvm/lib/Common/src/BP_1I_D32F32C30_TRC_WRA_02.c
+++ b/media/libeffects/lvm/lib/Common/src/BP_1I_D32F32C30_TRC_WRA_02.c
@@ -33,7 +33,52 @@
pBiquadState->pDelays[2] is y(n-1)L in Q0 format
pBiquadState->pDelays[3] is y(n-2)L in Q0 format
***************************************************************************/
+#ifdef BUILD_FLOAT
+void BP_1I_D32F32C30_TRC_WRA_02 ( Biquad_FLOAT_Instance_t *pInstance,
+ LVM_FLOAT *pDataIn,
+ LVM_FLOAT *pDataOut,
+ LVM_INT16 NrSamples)
+ {
+ LVM_FLOAT ynL,templ;
+ LVM_INT16 ii;
+ PFilter_State_FLOAT pBiquadState = (PFilter_State_FLOAT) pInstance;
+ for (ii = NrSamples; ii != 0; ii--)
+ {
+
+
+ /**************************************************************************
+ PROCESSING OF THE LEFT CHANNEL
+ ***************************************************************************/
+ // ynL= (A0 * (x(n)L - x(n-2)L ) )
+ templ = (*pDataIn) - pBiquadState->pDelays[1];
+ ynL = pBiquadState->coefs[0] * templ;
+
+ // ynL+= ((-B2 * y(n-2)L ) )
+ templ = pBiquadState->coefs[1] * pBiquadState->pDelays[3];
+ ynL += templ;
+
+ // ynL+= ((-B1 * y(n-1)L ) )
+ templ = pBiquadState->coefs[2] * pBiquadState->pDelays[2];
+ ynL += templ;
+
+ /**************************************************************************
+ UPDATING THE DELAYS
+ ***************************************************************************/
+ pBiquadState->pDelays[3] = pBiquadState->pDelays[2]; // y(n-2)L=y(n-1)L
+ pBiquadState->pDelays[1] = pBiquadState->pDelays[0]; // x(n-2)L=x(n-1)L
+ pBiquadState->pDelays[2] = ynL; // Update y(n-1)L
+ pBiquadState->pDelays[0] = (*pDataIn++); // Update x(n-1)L
+
+ /**************************************************************************
+ WRITING THE OUTPUT
+ ***************************************************************************/
+ *pDataOut++ = ynL; // Write Left output in Q0
+
+ }
+
+ }
+#else
void BP_1I_D32F32C30_TRC_WRA_02 ( Biquad_Instance_t *pInstance,
LVM_INT32 *pDataIn,
LVM_INT32 *pDataOut,
@@ -78,4 +123,4 @@
}
}
-
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/BP_1I_D32F32Cll_TRC_WRA_02_Init.c b/media/libeffects/lvm/lib/Common/src/BP_1I_D32F32Cll_TRC_WRA_02_Init.c
index 9367912..5590c32 100644
--- a/media/libeffects/lvm/lib/Common/src/BP_1I_D32F32Cll_TRC_WRA_02_Init.c
+++ b/media/libeffects/lvm/lib/Common/src/BP_1I_D32F32Cll_TRC_WRA_02_Init.c
@@ -37,6 +37,21 @@
/* RETURNS: */
/* void return code */
/*-------------------------------------------------------------------------*/
+#ifdef BUILD_FLOAT
+void BP_1I_D32F32Cll_TRC_WRA_02_Init ( Biquad_FLOAT_Instance_t *pInstance,
+ Biquad_1I_Order2_FLOAT_Taps_t *pTaps,
+ BP_FLOAT_Coefs_t *pCoef)
+{
+ PFilter_State_FLOAT pBiquadState = (PFilter_State_FLOAT) pInstance;
+ pBiquadState->pDelays =(LVM_FLOAT *) pTaps;
+
+ pBiquadState->coefs[0] = pCoef->A0;
+
+ pBiquadState->coefs[1] = pCoef->B2;
+
+ pBiquadState->coefs[2] = pCoef->B1;
+}
+#else
void BP_1I_D32F32Cll_TRC_WRA_02_Init ( Biquad_Instance_t *pInstance,
Biquad_1I_Order2_Taps_t *pTaps,
BP_C32_Coefs_t *pCoef)
@@ -50,6 +65,7 @@
pBiquadState->coefs[2]=pCoef->B1;
}
+#endif
/*-------------------------------------------------------------------------*/
/* End Of File: BP_1I_D32F32Cll_TRC_WRA_02_Init.c */
diff --git a/media/libeffects/lvm/lib/Common/src/BP_1I_D32F32Cll_TRC_WRA_02_Private.h b/media/libeffects/lvm/lib/Common/src/BP_1I_D32F32Cll_TRC_WRA_02_Private.h
index 5cc1ce2..80c3920 100644
--- a/media/libeffects/lvm/lib/Common/src/BP_1I_D32F32Cll_TRC_WRA_02_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/BP_1I_D32F32Cll_TRC_WRA_02_Private.h
@@ -26,5 +26,13 @@
}Filter_State;
typedef Filter_State * PFilter_State ;
+#ifdef BUILD_FLOAT
+typedef struct _Filter_State_FLOAT
+{
+ LVM_FLOAT * pDelays; /* pointer to the delayed samples (data of 32 bits) */
+ LVM_FLOAT coefs[3]; /* pointer to the filter coefficients */
+}Filter_State_Float;
+typedef Filter_State_Float* PFilter_State_FLOAT ;
+#endif
#endif /*_BP_1I_D32F32CLL_TRC_WRA_02_PRIVATE_H_*/
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F16C15_TRC_WRA_01.c b/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F16C15_TRC_WRA_01.c
index f2f8c6b..ee9bf7a 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F16C15_TRC_WRA_01.c
+++ b/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F16C15_TRC_WRA_01.c
@@ -32,7 +32,56 @@
pBiquadState->pDelays[2] is y(n-1)L in Q0 format
pBiquadState->pDelays[3] is y(n-2)L in Q0 format
***************************************************************************/
+#ifdef BUILD_FLOAT
+void BQ_1I_D16F16C15_TRC_WRA_01 ( Biquad_FLOAT_Instance_t *pInstance,
+ LVM_FLOAT *pDataIn,
+ LVM_FLOAT *pDataOut,
+ LVM_INT16 NrSamples)
+ {
+ LVM_FLOAT ynL;
+ LVM_INT16 ii;
+ PFilter_State_FLOAT pBiquadState = (PFilter_State_FLOAT) pInstance;
+ for (ii = NrSamples; ii != 0; ii--)
+ {
+
+
+ /**************************************************************************
+ PROCESSING OF THE LEFT CHANNEL
+ ***************************************************************************/
+ // ynL=A2 * x(n-2)L
+ ynL = (LVM_FLOAT)pBiquadState->coefs[0] * pBiquadState->pDelays[1];
+
+ // ynL+=A1 * x(n-1)L
+ ynL += (LVM_FLOAT)pBiquadState->coefs[1] * pBiquadState->pDelays[0];
+
+ // ynL+=A0 * x(n)L
+ ynL += (LVM_FLOAT)pBiquadState->coefs[2] * (*pDataIn);
+
+ // ynL+= (-B2 * y(n-2)L )
+ ynL += (LVM_FLOAT)pBiquadState->coefs[3] * pBiquadState->pDelays[3];
+
+ // ynL+= (-B1 * y(n-1)L )
+ ynL += (LVM_FLOAT)pBiquadState->coefs[4] * pBiquadState->pDelays[2];
+
+ /**************************************************************************
+ UPDATING THE DELAYS
+ ***************************************************************************/
+ pBiquadState->pDelays[3] = pBiquadState->pDelays[2]; // y(n-2)L=y(n-1)L
+ pBiquadState->pDelays[1] = pBiquadState->pDelays[0]; // x(n-2)L=x(n-1)L
+ pBiquadState->pDelays[2] = ynL; // Update y(n-1)L
+ pBiquadState->pDelays[0] = (*pDataIn++); // Update x(n-1)L
+
+ /**************************************************************************
+ WRITING THE OUTPUT
+ ***************************************************************************/
+ *pDataOut++ = (LVM_FLOAT)ynL; // Write Left output in Q0
+
+
+ }
+
+ }
+#else
void BQ_1I_D16F16C15_TRC_WRA_01 ( Biquad_Instance_t *pInstance,
LVM_INT16 *pDataIn,
LVM_INT16 *pDataOut,
@@ -82,4 +131,4 @@
}
}
-
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F16Css_TRC_WRA_01_Init.c b/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F16Css_TRC_WRA_01_Init.c
index baf0c1a..3d5befa 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F16Css_TRC_WRA_01_Init.c
+++ b/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F16Css_TRC_WRA_01_Init.c
@@ -37,6 +37,26 @@
/* RETURNS: */
/* void return code */
/*-------------------------------------------------------------------------*/
+#ifdef BUILD_FLOAT
+void BQ_1I_D16F16Css_TRC_WRA_01_Init ( Biquad_FLOAT_Instance_t *pInstance,
+ Biquad_1I_Order2_FLOAT_Taps_t *pTaps,
+ BQ_FLOAT_Coefs_t *pCoef)
+{
+ LVM_FLOAT temp;
+ PFilter_State_FLOAT pBiquadState = (PFilter_State_FLOAT) pInstance;
+ pBiquadState->pDelays = (LVM_FLOAT *) pTaps ;
+ temp = pCoef->A2;
+ pBiquadState->coefs[0] = temp;
+ temp = pCoef->A1;
+ pBiquadState->coefs[1] = temp;
+ temp = pCoef->A0;
+ pBiquadState->coefs[2] = temp;
+ temp = pCoef->B2;
+ pBiquadState->coefs[3] = temp;
+ temp = pCoef->B1;
+ pBiquadState->coefs[4] = temp;
+}
+#else
void BQ_1I_D16F16Css_TRC_WRA_01_Init ( Biquad_Instance_t *pInstance,
Biquad_1I_Order2_Taps_t *pTaps,
BQ_C16_Coefs_t *pCoef)
@@ -56,6 +76,7 @@
temp=pCoef->B1;
pBiquadState->coefs[4]=temp;
}
+#endif
/*-------------------------------------------------------------------------*/
/* End Of File: BQ_1I_D16F16Css_TRC_WRA_01_Init.c */
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F16Css_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F16Css_TRC_WRA_01_Private.h
index 909c699..811da8b 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F16Css_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F16Css_TRC_WRA_01_Private.h
@@ -27,4 +27,13 @@
typedef Filter_State * PFilter_State ;
+#ifdef BUILD_FLOAT
+typedef struct _Filter_State_FLOAT
+{
+ LVM_FLOAT * pDelays; /* pointer to the delayed samples (data of 32 bits) */
+ LVM_FLOAT coefs[5]; /* pointer to the filter coefficients */
+
+}Filter_State_FLOAT;
+typedef Filter_State_FLOAT * PFilter_State_FLOAT ;
+#endif
#endif /*_BQ_1I_D16F16CSS_TRC_WRA_01_PRIVATE_H_ */
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F32C14_TRC_WRA_01.c b/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F32C14_TRC_WRA_01.c
index 92f6caf..c74a137 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F32C14_TRC_WRA_01.c
+++ b/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F32C14_TRC_WRA_01.c
@@ -32,7 +32,54 @@
pBiquadState->pDelays[2] is y(n-1)L in Q16 format
pBiquadState->pDelays[3] is y(n-2)L in Q16 format
***************************************************************************/
+#ifdef BUILD_FLOAT
+void BQ_1I_D16F32C14_TRC_WRA_01 ( Biquad_FLOAT_Instance_t *pInstance,
+ LVM_FLOAT *pDataIn,
+ LVM_FLOAT *pDataOut,
+ LVM_INT16 NrSamples)
+ {
+ LVM_FLOAT ynL;
+ LVM_INT16 ii;
+ PFilter_State_FLOAT pBiquadState = (PFilter_State_FLOAT) pInstance;
+ for (ii = NrSamples; ii != 0; ii--)
+ {
+
+
+ /**************************************************************************
+ PROCESSING OF THE LEFT CHANNEL
+ ***************************************************************************/
+ // ynL=A2 * x(n-2)L
+ ynL = (LVM_FLOAT)pBiquadState->coefs[0] * pBiquadState->pDelays[1];
+
+ // ynL+=A1 * x(n-1)L
+ ynL += (LVM_FLOAT)pBiquadState->coefs[1] * pBiquadState->pDelays[0];
+
+ // ynL+=A0 * x(n)L
+ ynL += (LVM_FLOAT)pBiquadState->coefs[2] * (*pDataIn);
+
+ // ynL+= ( (-B2 * y(n-2)L )
+ ynL += pBiquadState->pDelays[3] * pBiquadState->coefs[3];
+
+ // ynL+= -B1 * y(n-1)L
+ ynL += pBiquadState->pDelays[2] * pBiquadState->coefs[4];
+
+ /**************************************************************************
+ UPDATING THE DELAYS
+ ***************************************************************************/
+ pBiquadState->pDelays[3] = pBiquadState->pDelays[2]; // y(n-2)L=y(n-1)L
+ pBiquadState->pDelays[1] = pBiquadState->pDelays[0]; // x(n-2)L=x(n-1)L
+ pBiquadState->pDelays[2] = ynL; // Update y(n-1)L
+ pBiquadState->pDelays[0] = (*pDataIn++); // Update x(n-1)L
+
+ /**************************************************************************
+ WRITING THE OUTPUT
+ ***************************************************************************/
+ *pDataOut++ = (LVM_FLOAT)(ynL); // Write Left output
+
+ }
+ }
+#else
void BQ_1I_D16F32C14_TRC_WRA_01 ( Biquad_Instance_t *pInstance,
LVM_INT16 *pDataIn,
LVM_INT16 *pDataOut,
@@ -81,4 +128,4 @@
}
}
-
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F32Css_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F32Css_TRC_WRA_01_Private.h
index aea10f0..9812274 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F32Css_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F32Css_TRC_WRA_01_Private.h
@@ -27,4 +27,13 @@
typedef Filter_State * PFilter_State ;
+#ifdef BUILD_FLOAT
+typedef struct _Filter_State_FLOAT
+{
+ LVM_FLOAT * pDelays; /* pointer to the delayed samples (data of 32 bits) */
+ LVM_FLOAT coefs[5]; /* pointer to the filter coefficients */
+
+}Filter_State_FLOAT;
+typedef Filter_State_FLOAT * PFilter_State_FLOAT ;
+#endif
#endif /*_BQ_1I_D16F32CSS_TRC_WRA_01_PRIVATE_H_*/
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F32Css_TRC_WRA_01_init.c b/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F32Css_TRC_WRA_01_init.c
index 1d6be4e..feae20d 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F32Css_TRC_WRA_01_init.c
+++ b/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F32Css_TRC_WRA_01_init.c
@@ -38,6 +38,27 @@
/* RETURNS: */
/* void return code */
/*-------------------------------------------------------------------------*/
+#ifdef BUILD_FLOAT
+void BQ_1I_D16F32Css_TRC_WRA_01_Init ( Biquad_FLOAT_Instance_t *pInstance,
+ Biquad_1I_Order2_FLOAT_Taps_t *pTaps,
+ BQ_FLOAT_Coefs_t *pCoef)
+{
+ LVM_FLOAT temp;
+ PFilter_State_FLOAT pBiquadState = (PFilter_State_FLOAT) pInstance;
+ pBiquadState->pDelays = (LVM_FLOAT *)pTaps;
+
+ temp = pCoef->A2;
+ pBiquadState->coefs[0] = temp;
+ temp = pCoef->A1;
+ pBiquadState->coefs[1] = temp;
+ temp = pCoef->A0;
+ pBiquadState->coefs[2] = temp;
+ temp = pCoef->B2;
+ pBiquadState->coefs[3] = temp;
+ temp = pCoef->B1;
+ pBiquadState->coefs[4] = temp;
+}
+#else
void BQ_1I_D16F32Css_TRC_WRA_01_Init ( Biquad_Instance_t *pInstance,
Biquad_1I_Order2_Taps_t *pTaps,
BQ_C16_Coefs_t *pCoef)
@@ -57,6 +78,7 @@
temp=pCoef->B1;
pBiquadState->coefs[4]=temp;
}
+#endif
/*-------------------------------------------------------------------------*/
/* End Of File: BQ_1I_D16F32Css_TRC_WRA_01_Init */
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16C14_TRC_WRA_01.c b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16C14_TRC_WRA_01.c
index 972e704..9b0fde3 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16C14_TRC_WRA_01.c
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16C14_TRC_WRA_01.c
@@ -37,7 +37,81 @@
pBiquadState->pDelays[6] is y(n-2)L in Q0 format
pBiquadState->pDelays[7] is y(n-2)R in Q0 format
***************************************************************************/
+#ifdef BUILD_FLOAT
+void BQ_2I_D16F16C14_TRC_WRA_01 ( Biquad_FLOAT_Instance_t *pInstance,
+ LVM_FLOAT *pDataIn,
+ LVM_FLOAT *pDataOut,
+ LVM_INT16 NrSamples)
+ {
+ LVM_FLOAT ynL,ynR;
+ LVM_INT16 ii;
+ PFilter_State_FLOAT pBiquadState = (PFilter_State_FLOAT) pInstance;
+ for (ii = NrSamples; ii != 0; ii--)
+ {
+
+ /**************************************************************************
+ PROCESSING OF THE LEFT CHANNEL
+ ***************************************************************************/
+ // ynL=A2 * x(n-2)L
+ ynL = (LVM_FLOAT)pBiquadState->coefs[0] * pBiquadState->pDelays[2];
+
+ // ynL+=A1 * x(n-1)L
+ ynL += (LVM_FLOAT)pBiquadState->coefs[1] * pBiquadState->pDelays[0];
+
+ // ynL+=A0 * x(n)L
+ ynL += (LVM_FLOAT)pBiquadState->coefs[2] * (*pDataIn);
+
+ // ynL+= ( -B2 * y(n-2)L )
+ ynL += (LVM_FLOAT)pBiquadState->coefs[3] * pBiquadState->pDelays[6];
+
+ // ynL+=( -B1 * y(n-1)L )
+ ynL += (LVM_FLOAT)pBiquadState->coefs[4] * pBiquadState->pDelays[4];
+
+
+
+ /**************************************************************************
+ PROCESSING OF THE RIGHT CHANNEL
+ ***************************************************************************/
+ // ynR=A2 * x(n-2)R
+ ynR = (LVM_FLOAT)pBiquadState->coefs[0] * pBiquadState->pDelays[3];
+
+ // ynR+=A1 * x(n-1)R
+ ynR += (LVM_FLOAT)pBiquadState->coefs[1] * pBiquadState->pDelays[1];
+
+ // ynR+=A0 * x(n)R
+ ynR += (LVM_FLOAT)pBiquadState->coefs[2] * (*(pDataIn+1));
+
+ // ynR+= ( -B2 * y(n-2)R )
+ ynR += (LVM_FLOAT)pBiquadState->coefs[3] * pBiquadState->pDelays[7];
+
+ // ynR+=( -B1 * y(n-1)R )
+ ynR += (LVM_FLOAT)pBiquadState->coefs[4] * pBiquadState->pDelays[5];
+
+
+ /**************************************************************************
+ UPDATING THE DELAYS
+ ***************************************************************************/
+ pBiquadState->pDelays[7] = pBiquadState->pDelays[5]; // y(n-2)R=y(n-1)R
+ pBiquadState->pDelays[6] = pBiquadState->pDelays[4]; // y(n-2)L=y(n-1)L
+ pBiquadState->pDelays[3] = pBiquadState->pDelays[1]; // x(n-2)R=x(n-1)R
+ pBiquadState->pDelays[2] = pBiquadState->pDelays[0]; // x(n-2)L=x(n-1)L
+ pBiquadState->pDelays[5] = ynR; // Update y(n-1)R
+ pBiquadState->pDelays[4] = ynL; // Update y(n-1)L
+ pBiquadState->pDelays[0] = (*pDataIn++); // Update x(n-1)L
+ pBiquadState->pDelays[1] = (*pDataIn++); // Update x(n-1)R
+
+ /**************************************************************************
+ WRITING THE OUTPUT
+ ***************************************************************************/
+ *pDataOut++ = (LVM_FLOAT)ynL; // Write Left output
+ *pDataOut++ = (LVM_FLOAT)ynR; // Write Right ouput
+
+
+ }
+
+ }
+#else
void BQ_2I_D16F16C14_TRC_WRA_01 ( Biquad_Instance_t *pInstance,
LVM_INT16 *pDataIn,
LVM_INT16 *pDataOut,
@@ -112,3 +186,4 @@
}
+#endif
\ No newline at end of file
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16C15_TRC_WRA_01.c b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16C15_TRC_WRA_01.c
index e056373..f24db8f 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16C15_TRC_WRA_01.c
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16C15_TRC_WRA_01.c
@@ -37,7 +37,81 @@
pBiquadState->pDelays[6] is y(n-2)L in Q0 format
pBiquadState->pDelays[7] is y(n-2)R in Q0 format
***************************************************************************/
+#ifdef BUILD_FLOAT
+void BQ_2I_D16F16C15_TRC_WRA_01 ( Biquad_FLOAT_Instance_t *pInstance,
+ LVM_FLOAT *pDataIn,
+ LVM_FLOAT *pDataOut,
+ LVM_INT16 NrSamples)
+ {
+ LVM_FLOAT ynL,ynR;
+ LVM_INT16 ii;
+ PFilter_State_FLOAT pBiquadState = (PFilter_State_FLOAT) pInstance;
+ for (ii = NrSamples; ii != 0; ii--)
+ {
+
+
+ /**************************************************************************
+ PROCESSING OF THE LEFT CHANNEL
+ ***************************************************************************/
+ // ynL=A2 * x(n-2)L
+ ynL = (LVM_FLOAT)pBiquadState->coefs[0] * pBiquadState->pDelays[2];
+
+ // ynL+=A1 * x(n-1)L
+ ynL += (LVM_FLOAT)pBiquadState->coefs[1] * pBiquadState->pDelays[0];
+
+ // ynL+=A0 * x(n)L
+ ynL += (LVM_FLOAT)pBiquadState->coefs[2] * (*pDataIn);
+
+ // ynL+= ( -B2 * y(n-2)L
+ ynL += (LVM_FLOAT)pBiquadState->coefs[3] * pBiquadState->pDelays[6];
+
+ // ynL+=( -B1 * y(n-1)L
+ ynL += (LVM_FLOAT)pBiquadState->coefs[4] * pBiquadState->pDelays[4];
+
+
+
+ /**************************************************************************
+ PROCESSING OF THE RIGHT CHANNEL
+ ***************************************************************************/
+ // ynR=A2 * x(n-2)R
+ ynR = (LVM_FLOAT)pBiquadState->coefs[0] * pBiquadState->pDelays[3];
+
+ // ynR+=A1 * x(n-1)R
+ ynR += (LVM_FLOAT)pBiquadState->coefs[1] * pBiquadState->pDelays[1];
+
+ // ynR+=A0 * x(n)R
+ ynR += (LVM_FLOAT)pBiquadState->coefs[2] * (*(pDataIn+1));
+
+ // ynR+= ( -B2 * y(n-2)R )
+ ynR += (LVM_FLOAT)pBiquadState->coefs[3] * pBiquadState->pDelays[7];
+
+ // ynR+=( -B1 * y(n-1)R )
+ ynR += (LVM_FLOAT)pBiquadState->coefs[4] * pBiquadState->pDelays[5];
+
+
+ /**************************************************************************
+ UPDATING THE DELAYS
+ ***************************************************************************/
+ pBiquadState->pDelays[7] = pBiquadState->pDelays[5]; // y(n-2)R=y(n-1)R
+ pBiquadState->pDelays[6] = pBiquadState->pDelays[4]; // y(n-2)L=y(n-1)L
+ pBiquadState->pDelays[3] = pBiquadState->pDelays[1]; // x(n-2)R=x(n-1)R
+ pBiquadState->pDelays[2] = pBiquadState->pDelays[0]; // x(n-2)L=x(n-1)L
+ pBiquadState->pDelays[5] = ynR; // Update y(n-1)R
+ pBiquadState->pDelays[4] = ynL; // Update y(n-1)L
+ pBiquadState->pDelays[0] = (*pDataIn++); // Update x(n-1)L
+ pBiquadState->pDelays[1] = (*pDataIn++); // Update x(n-1)R
+
+ /**************************************************************************
+ WRITING THE OUTPUT
+ ***************************************************************************/
+ *pDataOut++ = (LVM_FLOAT)ynL; // Write Left output
+ *pDataOut++ = (LVM_FLOAT)ynR; // Write Right ouput
+
+ }
+
+ }
+#else
void BQ_2I_D16F16C15_TRC_WRA_01 ( Biquad_Instance_t *pInstance,
LVM_INT16 *pDataIn,
LVM_INT16 *pDataOut,
@@ -111,4 +185,4 @@
}
}
-
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16Css_TRC_WRA_01_Init.c b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16Css_TRC_WRA_01_Init.c
index 0a8ac35..39e1bda 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16Css_TRC_WRA_01_Init.c
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16Css_TRC_WRA_01_Init.c
@@ -38,6 +38,27 @@
/* RETURNS: */
/* void return code */
/*-------------------------------------------------------------------------*/
+#ifdef BUILD_FLOAT
+void BQ_2I_D16F16Css_TRC_WRA_01_Init ( Biquad_FLOAT_Instance_t *pInstance,
+ Biquad_2I_Order2_FLOAT_Taps_t *pTaps,
+ BQ_FLOAT_Coefs_t *pCoef)
+{
+ LVM_FLOAT temp;
+ PFilter_State_FLOAT pBiquadState = (PFilter_State_FLOAT) pInstance;
+ pBiquadState->pDelays = (LVM_FLOAT *) pTaps ;
+
+ temp = pCoef->A2;
+ pBiquadState->coefs[0] = temp;
+ temp = pCoef->A1;
+ pBiquadState->coefs[1] = temp;
+ temp = pCoef->A0;
+ pBiquadState->coefs[2] = temp;
+ temp = pCoef->B2;
+ pBiquadState->coefs[3] = temp;
+ temp = pCoef->B1;
+ pBiquadState->coefs[4] = temp;
+}
+#else
void BQ_2I_D16F16Css_TRC_WRA_01_Init ( Biquad_Instance_t *pInstance,
Biquad_2I_Order2_Taps_t *pTaps,
BQ_C16_Coefs_t *pCoef)
@@ -57,6 +78,7 @@
temp=pCoef->B1;
pBiquadState->coefs[4]=temp;
}
+#endif
/*-------------------------------------------------------------------------*/
/* End Of File: BQ_2I_D16F16Css_TRC_WRA_01_Init.c */
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16Css_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16Css_TRC_WRA_01_Private.h
index 7d42ced..0691b8c 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16Css_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16Css_TRC_WRA_01_Private.h
@@ -28,4 +28,14 @@
typedef Filter_State * PFilter_State ;
+#ifdef BUILD_FLOAT
+typedef struct _Filter_State_FLOAT
+{
+ LVM_FLOAT * pDelays; /* pointer to the delayed samples (data of 32 bits) */
+ LVM_FLOAT coefs[5]; /* pointer to the filter coefficients */
+
+}Filter_State_FLOAT;
+typedef Filter_State_FLOAT * PFilter_State_FLOAT ;
+#endif
+
#endif /* _BQ_2I_D16F16CSS_TRC_WRA_01_PRIVATE_H_ */
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32C13_TRC_WRA_01.c b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32C13_TRC_WRA_01.c
index 4a0cce4..61c07c7 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32C13_TRC_WRA_01.c
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32C13_TRC_WRA_01.c
@@ -37,7 +37,79 @@
pBiquadState->pDelays[6] is y(n-2)L in Q16 format
pBiquadState->pDelays[7] is y(n-2)R in Q16 format
***************************************************************************/
+#ifdef BUILD_FLOAT
+void BQ_2I_D16F32C13_TRC_WRA_01 ( Biquad_FLOAT_Instance_t *pInstance,
+ LVM_FLOAT *pDataIn,
+ LVM_FLOAT *pDataOut,
+ LVM_INT16 NrSamples)
+ {
+ LVM_FLOAT ynL,ynR;
+ LVM_INT16 ii;
+ PFilter_State_FLOAT pBiquadState = (PFilter_State_FLOAT) pInstance;
+ for (ii = NrSamples; ii != 0; ii--)
+ {
+
+ /**************************************************************************
+ PROCESSING OF THE LEFT CHANNEL
+ ***************************************************************************/
+ /* ynL=A2 * x(n-2)L */
+ ynL = (LVM_FLOAT)pBiquadState->coefs[0] * pBiquadState->pDelays[2];
+
+ /* ynL+=A1* x(n-1)L */
+ ynL += (LVM_FLOAT)pBiquadState->coefs[1] * pBiquadState->pDelays[0];
+
+ /* ynL+=A0* x(n)L */
+ ynL += (LVM_FLOAT)pBiquadState->coefs[2] * (*pDataIn);
+
+ /* ynL+=-B2*y(n-2)L */
+ ynL += pBiquadState->pDelays[6] * pBiquadState->coefs[3];
+
+ /* ynL+=-B1*y(n-1)L */
+ ynL += pBiquadState->pDelays[4] * pBiquadState->coefs[4];
+
+ /**************************************************************************
+ PROCESSING OF THE RIGHT CHANNEL
+ ***************************************************************************/
+ /* ynR=A2 * x(n-2)R */
+ ynR = (LVM_FLOAT)pBiquadState->coefs[0] * pBiquadState->pDelays[3];
+
+ /* ynR+=A1* x(n-1)R */
+ ynR += (LVM_FLOAT)pBiquadState->coefs[1] * pBiquadState->pDelays[1];
+
+ /* ynR+=A0* x(n)R */
+ ynR += (LVM_FLOAT)pBiquadState->coefs[2] * (*(pDataIn+1));
+
+ /* ynR+=-B2 * y(n-2)R */
+ ynR += pBiquadState->pDelays[7] * pBiquadState->coefs[3];
+
+ /* ynR+=-B1 * y(n-1)R */
+ ynR += pBiquadState->pDelays[5] * pBiquadState->coefs[4];
+
+ /**************************************************************************
+ UPDATING THE DELAYS
+ ***************************************************************************/
+ pBiquadState->pDelays[7] = pBiquadState->pDelays[5]; /* y(n-2)R=y(n-1)R*/
+ pBiquadState->pDelays[6] = pBiquadState->pDelays[4]; /* y(n-2)L=y(n-1)L*/
+ pBiquadState->pDelays[3] = pBiquadState->pDelays[1]; /* x(n-2)R=x(n-1)R*/
+ pBiquadState->pDelays[2] = pBiquadState->pDelays[0]; /* x(n-2)L=x(n-1)L*/
+ pBiquadState->pDelays[5] = ynR; /* Update y(n-1)R */
+ pBiquadState->pDelays[4] = ynL; /* Update y(n-1)L */
+ pBiquadState->pDelays[0] = (*pDataIn); /* Update x(n-1)L */
+ pDataIn++;
+ pBiquadState->pDelays[1] = (*pDataIn); /* Update x(n-1)R */
+ pDataIn++;
+
+ /**************************************************************************
+ WRITING THE OUTPUT
+ ***************************************************************************/
+ *pDataOut = (LVM_FLOAT)(ynL); /* Write Left output */
+ pDataOut++;
+ *pDataOut = (LVM_FLOAT)(ynR); /* Write Right ouput */
+ pDataOut++;
+ }
+ }
+#else
void BQ_2I_D16F32C13_TRC_WRA_01 ( Biquad_Instance_t *pInstance,
LVM_INT16 *pDataIn,
LVM_INT16 *pDataOut,
@@ -115,4 +187,4 @@
}
}
-
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32C14_TRC_WRA_01.c b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32C14_TRC_WRA_01.c
index 052e2a0..cf19e06 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32C14_TRC_WRA_01.c
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32C14_TRC_WRA_01.c
@@ -36,7 +36,82 @@
pBiquadState->pDelays[6] is y(n-2)L in Q16 format
pBiquadState->pDelays[7] is y(n-2)R in Q16 format
***************************************************************************/
+#ifdef BUILD_FLOAT
+void BQ_2I_D16F32C14_TRC_WRA_01 ( Biquad_FLOAT_Instance_t *pInstance,
+ LVM_FLOAT *pDataIn,
+ LVM_FLOAT *pDataOut,
+ LVM_INT16 NrSamples)
+ {
+ LVM_FLOAT ynL,ynR;
+ LVM_INT16 ii;
+ PFilter_State_FLOAT pBiquadState = (PFilter_State_FLOAT) pInstance;
+ for (ii = NrSamples; ii != 0; ii--)
+ {
+
+
+ /**************************************************************************
+ PROCESSING OF THE LEFT CHANNEL
+ ***************************************************************************/
+ /* ynL=A2 * x(n-2)L */
+ ynL = (LVM_FLOAT)pBiquadState->coefs[0] * pBiquadState->pDelays[2];
+
+ /* ynL+=A1 * x(n-1)L */
+ ynL += (LVM_FLOAT)pBiquadState->coefs[1] * pBiquadState->pDelays[0];
+
+ /* ynL+=A0 * x(n)L */
+ ynL += (LVM_FLOAT)pBiquadState->coefs[2] * (*pDataIn);
+
+ /* ynL+= ( (-B2 * y(n-2)L ))*/
+ ynL += pBiquadState->pDelays[6] * pBiquadState->coefs[3];
+
+
+ /* ynL+=( (-B1 * y(n-1)L )) */
+ ynL += pBiquadState->pDelays[4] * pBiquadState->coefs[4];
+
+ /**************************************************************************
+ PROCESSING OF THE RIGHT CHANNEL
+ ***************************************************************************/
+ /* ynR=A2 * x(n-2)R */
+ ynR = (LVM_FLOAT)pBiquadState->coefs[0] * pBiquadState->pDelays[3];
+
+ /* ynR+=A1 * x(n-1)R */
+ ynR += (LVM_FLOAT)pBiquadState->coefs[1] * pBiquadState->pDelays[1];
+
+ /* ynR+=A0 * x(n)R */
+ ynR += (LVM_FLOAT)pBiquadState->coefs[2] * (*(pDataIn+1));
+
+ /* ynR+= ( (-B2 * y(n-2)R ))*/
+ ynR += pBiquadState->pDelays[7] * pBiquadState->coefs[3];
+
+ /* ynR+=( (-B1 * y(n-1)R )) */
+ ynR += pBiquadState->pDelays[5] * pBiquadState->coefs[4];
+
+ /**************************************************************************
+ UPDATING THE DELAYS
+ ***************************************************************************/
+ pBiquadState->pDelays[7] = pBiquadState->pDelays[5]; /* y(n-2)R=y(n-1)R*/
+ pBiquadState->pDelays[6] = pBiquadState->pDelays[4]; /* y(n-2)L=y(n-1)L*/
+ pBiquadState->pDelays[3] = pBiquadState->pDelays[1]; /* x(n-2)R=x(n-1)R*/
+ pBiquadState->pDelays[2] = pBiquadState->pDelays[0]; /* x(n-2)L=x(n-1)L*/
+ pBiquadState->pDelays[5] = ynR; /* Update y(n-1)R */
+ pBiquadState->pDelays[4] = ynL; /* Update y(n-1)L */
+ pBiquadState->pDelays[0] = (*pDataIn); /* Update x(n-1)L */
+ pDataIn++;
+ pBiquadState->pDelays[1] = (*pDataIn); /* Update x(n-1)R */
+ pDataIn++;
+
+ /**************************************************************************
+ WRITING THE OUTPUT
+ ***************************************************************************/
+ *pDataOut = (LVM_FLOAT)(ynL); /* Write Left output */
+ pDataOut++;
+ *pDataOut = (LVM_FLOAT)(ynR); /* Write Right ouput */
+ pDataOut++;
+ }
+
+ }
+#else
void BQ_2I_D16F32C14_TRC_WRA_01 ( Biquad_Instance_t *pInstance,
LVM_INT16 *pDataIn,
LVM_INT16 *pDataOut,
@@ -114,4 +189,4 @@
}
}
-
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32C15_TRC_WRA_01.c b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32C15_TRC_WRA_01.c
index 8c741e1..2611b19 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32C15_TRC_WRA_01.c
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32C15_TRC_WRA_01.c
@@ -36,7 +36,84 @@
pBiquadState->pDelays[6] is y(n-2)L in Q16 format
pBiquadState->pDelays[7] is y(n-2)R in Q16 format
***************************************************************************/
+#ifdef BUILD_FLOAT
+void BQ_2I_D16F32C15_TRC_WRA_01 ( Biquad_FLOAT_Instance_t *pInstance,
+ LVM_FLOAT *pDataIn,
+ LVM_FLOAT *pDataOut,
+ LVM_INT16 NrSamples)
+ {
+ LVM_FLOAT ynL,ynR;
+ LVM_INT16 ii;
+ PFilter_State_FLOAT pBiquadState = (PFilter_State_FLOAT) pInstance;
+ for (ii = NrSamples; ii != 0; ii--)
+ {
+
+
+ /**************************************************************************
+ PROCESSING OF THE LEFT CHANNEL
+ ***************************************************************************/
+ /* ynL=A2 * x(n-2)L */
+ ynL = (LVM_FLOAT)pBiquadState->coefs[0] * pBiquadState->pDelays[2];
+
+ /* ynL+=A1 * x(n-1)L */
+ ynL += (LVM_FLOAT)pBiquadState->coefs[1] * pBiquadState->pDelays[0];
+
+ /* ynL+=A0 * x(n)L */
+ ynL += (LVM_FLOAT)pBiquadState->coefs[2] * (*pDataIn);
+
+ /* ynL+= ( (-B2 * y(n-2)L ) */
+ ynL += pBiquadState->pDelays[6] * pBiquadState->coefs[3];
+
+
+ /* ynL+=( (-B1 * y(n-1)L )) */
+ ynL += pBiquadState->pDelays[4] * pBiquadState->coefs[4];
+
+
+ /**************************************************************************
+ PROCESSING OF THE RIGHT CHANNEL
+ ***************************************************************************/
+ /* ynR=A2 * x(n-2)R */
+ ynR = (LVM_FLOAT)pBiquadState->coefs[0] * pBiquadState->pDelays[3];
+
+ /* ynR+=A1 * x(n-1)R */
+ ynR += (LVM_FLOAT)pBiquadState->coefs[1] * pBiquadState->pDelays[1];
+
+ /* ynR+=A0 * x(n)R */
+ ynR += (LVM_FLOAT)pBiquadState->coefs[2] * (*(pDataIn+1));
+
+ /* ynR+= ( (-B2 * y(n-2)R ) */
+ ynR += pBiquadState->pDelays[7] * pBiquadState->coefs[3];
+
+
+ /* ynR+=( (-B1 * y(n-1)R )) in Q15 */
+ ynR += pBiquadState->pDelays[5] * pBiquadState->coefs[4];
+
+ /**************************************************************************
+ UPDATING THE DELAYS
+ ***************************************************************************/
+ pBiquadState->pDelays[7] = pBiquadState->pDelays[5]; /* y(n-2)R=y(n-1)R*/
+ pBiquadState->pDelays[6] = pBiquadState->pDelays[4]; /* y(n-2)L=y(n-1)L*/
+ pBiquadState->pDelays[3] = pBiquadState->pDelays[1]; /* x(n-2)R=x(n-1)R*/
+ pBiquadState->pDelays[2] = pBiquadState->pDelays[0]; /* x(n-2)L=x(n-1)L*/
+ pBiquadState->pDelays[5] = ynR; /* Update y(n-1)R*/
+ pBiquadState->pDelays[4] = ynL; /* Update y(n-1)L*/
+ pBiquadState->pDelays[0] = (*pDataIn); /* Update x(n-1)L*/
+ pDataIn++;
+ pBiquadState->pDelays[1] = (*pDataIn); /* Update x(n-1)R*/
+ pDataIn++;
+
+ /**************************************************************************
+ WRITING THE OUTPUT
+ ***************************************************************************/
+ *pDataOut = (LVM_FLOAT)(ynL); /* Write Left output*/
+ pDataOut++;
+ *pDataOut = (LVM_FLOAT)(ynR); /* Write Right ouput*/
+ pDataOut++;
+ }
+
+ }
+#else
void BQ_2I_D16F32C15_TRC_WRA_01 ( Biquad_Instance_t *pInstance,
LVM_INT16 *pDataIn,
LVM_INT16 *pDataOut,
@@ -114,4 +191,4 @@
}
}
-
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32Css_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32Css_TRC_WRA_01_Private.h
index 4f0cf67..c0319c9 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32Css_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32Css_TRC_WRA_01_Private.h
@@ -28,4 +28,14 @@
typedef Filter_State * PFilter_State ;
+#ifdef BUILD_FLOAT
+typedef struct _Filter_State_FLOAT
+{
+ LVM_FLOAT * pDelays; /* pointer to the delayed samples \
+ (data of 32 bits) */
+ LVM_FLOAT coefs[5]; /* pointer to the filter coefficients */
+}Filter_State_FLOAT;
+typedef Filter_State_FLOAT * PFilter_State_FLOAT ;
+#endif
+
#endif /* _BQ_2I_D16F32CSS_TRC_WRA_01_PRIVATE_H_ */
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32Css_TRC_WRA_01_init.c b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32Css_TRC_WRA_01_init.c
index 4591ee0..4d9bbfe 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32Css_TRC_WRA_01_init.c
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32Css_TRC_WRA_01_init.c
@@ -37,6 +37,26 @@
/* RETURNS: */
/* void return code */
/*-------------------------------------------------------------------------*/
+#ifdef BUILD_FLOAT
+void BQ_2I_D16F32Css_TRC_WRA_01_Init ( Biquad_FLOAT_Instance_t *pInstance,
+ Biquad_2I_Order2_FLOAT_Taps_t *pTaps,
+ BQ_FLOAT_Coefs_t *pCoef)
+{
+ LVM_FLOAT temp;
+ PFilter_State_FLOAT pBiquadState = (PFilter_State_FLOAT) pInstance;
+ pBiquadState->pDelays = (LVM_FLOAT *) pTaps;
+ temp = pCoef->A2;
+ pBiquadState->coefs[0] = temp;
+ temp = pCoef->A1;
+ pBiquadState->coefs[1] = temp;
+ temp = pCoef->A0;
+ pBiquadState->coefs[2] = temp;
+ temp = pCoef->B2;
+ pBiquadState->coefs[3] = temp;
+ temp = pCoef->B1;
+ pBiquadState->coefs[4] = temp;
+}
+#else
void BQ_2I_D16F32Css_TRC_WRA_01_Init ( Biquad_Instance_t *pInstance,
Biquad_2I_Order2_Taps_t *pTaps,
BQ_C16_Coefs_t *pCoef)
@@ -56,6 +76,7 @@
temp=pCoef->B1;
pBiquadState->coefs[4]=temp;
}
+#endif
/*-------------------------------------------------------------------------*/
/* End Of File: BQ_2I_D16F32Css_TRC_WRA_01_Init */
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32C30_TRC_WRA_01.c b/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32C30_TRC_WRA_01.c
index fd8212e4..960de79 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32C30_TRC_WRA_01.c
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32C30_TRC_WRA_01.c
@@ -36,7 +36,94 @@
pBiquadState->pDelays[6] is y(n-2)L in Q0 format
pBiquadState->pDelays[7] is y(n-2)R in Q0 format
***************************************************************************/
+#ifdef BUILD_FLOAT
+void BQ_2I_D32F32C30_TRC_WRA_01 ( Biquad_FLOAT_Instance_t *pInstance,
+ LVM_FLOAT *pDataIn,
+ LVM_FLOAT *pDataOut,
+ LVM_INT16 NrSamples)
+
+ {
+ LVM_FLOAT ynL,ynR,templ,tempd;
+ LVM_INT16 ii;
+ PFilter_State_FLOAT pBiquadState = (PFilter_State_FLOAT) pInstance;
+
+ for (ii = NrSamples; ii != 0; ii--)
+ {
+
+
+ /**************************************************************************
+ PROCESSING OF THE LEFT CHANNEL
+ ***************************************************************************/
+ /* ynL= ( A2 * x(n-2)L ) */
+ ynL = pBiquadState->coefs[0] * pBiquadState->pDelays[2];
+
+ /* ynL+= ( A1 * x(n-1)L )*/
+ templ = pBiquadState->coefs[1] * pBiquadState->pDelays[0];
+ ynL += templ;
+
+ /* ynL+= ( A0 * x(n)L ) */
+ templ = pBiquadState->coefs[2] * (*pDataIn);
+ ynL += templ;
+
+ /* ynL+= (-B2 * y(n-2)L ) */
+ templ = pBiquadState->coefs[3] * pBiquadState->pDelays[6];
+ ynL += templ;
+
+ /* ynL+= (-B1 * y(n-1)L )*/
+ templ = pBiquadState->coefs[4] * pBiquadState->pDelays[4];
+ ynL += templ;
+
+ /**************************************************************************
+ PROCESSING OF THE RIGHT CHANNEL
+ ***************************************************************************/
+ /* ynR= ( A2 * x(n-2)R ) */
+ ynR = pBiquadState->coefs[0] * pBiquadState->pDelays[3];
+
+ /* ynR+= ( A1 * x(n-1)R ) */
+ templ = pBiquadState->coefs[1] * pBiquadState->pDelays[1];
+ ynR += templ;
+
+ /* ynR+= ( A0 * x(n)R ) */
+ tempd =* (pDataIn+1);
+ templ = pBiquadState->coefs[2] * tempd;
+ ynR += templ;
+
+ /* ynR+= (-B2 * y(n-2)R ) */
+ templ = pBiquadState->coefs[3] * pBiquadState->pDelays[7];
+ ynR += templ;
+
+ /* ynR+= (-B1 * y(n-1)R ) */
+ templ = pBiquadState->coefs[4] * pBiquadState->pDelays[5];
+ ynR += templ;
+
+ /**************************************************************************
+ UPDATING THE DELAYS
+ ***************************************************************************/
+ pBiquadState->pDelays[7] = pBiquadState->pDelays[5]; /* y(n-2)R=y(n-1)R*/
+ pBiquadState->pDelays[6] = pBiquadState->pDelays[4]; /* y(n-2)L=y(n-1)L*/
+ pBiquadState->pDelays[3] = pBiquadState->pDelays[1]; /* x(n-2)R=x(n-1)R*/
+ pBiquadState->pDelays[2] = pBiquadState->pDelays[0]; /* x(n-2)L=x(n-1)L*/
+ pBiquadState->pDelays[5] = (LVM_FLOAT)ynR; /* Update y(n-1)R */
+ pBiquadState->pDelays[4] = (LVM_FLOAT)ynL; /* Update y(n-1)L */
+ pBiquadState->pDelays[0] = (*pDataIn); /* Update x(n-1)L */
+ pDataIn++;
+ pBiquadState->pDelays[1] = (*pDataIn); /* Update x(n-1)R */
+ pDataIn++;
+
+ /**************************************************************************
+ WRITING THE OUTPUT
+ ***************************************************************************/
+ *pDataOut = (LVM_FLOAT)ynL; /* Write Left output */
+ pDataOut++;
+ *pDataOut = (LVM_FLOAT)ynR; /* Write Right ouput */
+ pDataOut++;
+
+
+ }
+
+ }
+#else
void BQ_2I_D32F32C30_TRC_WRA_01 ( Biquad_Instance_t *pInstance,
LVM_INT32 *pDataIn,
LVM_INT32 *pDataOut,
@@ -123,4 +210,4 @@
}
}
-
+#endif /*BUILD_FLOAT*/
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32Cll_TRC_WRA_01_Init.c b/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32Cll_TRC_WRA_01_Init.c
index 1709f71..fff05ed 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32Cll_TRC_WRA_01_Init.c
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32Cll_TRC_WRA_01_Init.c
@@ -37,6 +37,26 @@
/* RETURNS: */
/* void return code */
/*-------------------------------------------------------------------------*/
+#ifdef BUILD_FLOAT
+void BQ_2I_D32F32Cll_TRC_WRA_01_Init ( Biquad_FLOAT_Instance_t *pInstance,
+ Biquad_2I_Order2_FLOAT_Taps_t *pTaps,
+ BQ_FLOAT_Coefs_t *pCoef)
+{
+ LVM_FLOAT temp;
+ PFilter_State_FLOAT pBiquadState = (PFilter_State_FLOAT) pInstance;
+ pBiquadState->pDelays = (LVM_FLOAT *) pTaps;
+ temp = pCoef->A2;
+ pBiquadState->coefs[0] = temp;
+ temp = pCoef->A1;
+ pBiquadState->coefs[1] = temp;
+ temp = pCoef->A0;
+ pBiquadState->coefs[2] = temp;
+ temp = pCoef->B2;
+ pBiquadState->coefs[3] = temp;
+ temp = pCoef->B1;
+ pBiquadState->coefs[4] = temp;
+}
+#else
void BQ_2I_D32F32Cll_TRC_WRA_01_Init ( Biquad_Instance_t *pInstance,
Biquad_2I_Order2_Taps_t *pTaps,
BQ_C32_Coefs_t *pCoef)
@@ -56,6 +76,7 @@
temp=pCoef->B1;
pBiquadState->coefs[4]=temp;
}
+#endif
/*-------------------------------------------------------------------------*/
/* End Of File: BQ_2I_D32F32C32_TRC_WRA_01_Init.c */
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32Cll_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32Cll_TRC_WRA_01_Private.h
index 747af6a..c0f0dcc 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32Cll_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32Cll_TRC_WRA_01_Private.h
@@ -29,4 +29,14 @@
typedef Filter_State * PFilter_State ;
+#ifdef BUILD_FLOAT
+typedef struct _Filter_State_FLOAT
+{
+ LVM_FLOAT * pDelays; /* pointer to the delayed samples \
+ (data of 32 bits) */
+ LVM_FLOAT coefs[5]; /* pointer to the filter coefficients */
+}Filter_State_FLOAT;
+typedef Filter_State_FLOAT * PFilter_State_FLOAT ;
+#endif
+
#endif /* _BQ_2I_D32F32CLL_TRC_WRA_01_PRIVATE_H_*/
diff --git a/media/libeffects/lvm/lib/Common/src/Copy_16.c b/media/libeffects/lvm/lib/Common/src/Copy_16.c
index 20404ad..e489031 100644
--- a/media/libeffects/lvm/lib/Common/src/Copy_16.c
+++ b/media/libeffects/lvm/lib/Common/src/Copy_16.c
@@ -54,5 +54,35 @@
return;
}
+#ifdef BUILD_FLOAT
+void Copy_Float( const LVM_FLOAT *src,
+ LVM_FLOAT *dst,
+ LVM_INT16 n )
+{
+ LVM_INT16 ii;
+ if (src > dst)
+ {
+ for (ii = n; ii != 0; ii--)
+ {
+ *dst = *src;
+ dst++;
+ src++;
+ }
+ }
+ else
+ {
+ src += n - 1;
+ dst += n - 1;
+ for (ii = n; ii != 0; ii--)
+ {
+ *dst = *src;
+ dst--;
+ src--;
+ }
+ }
+
+ return;
+}
+#endif
/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/Core_MixHard_2St_D32C31_SAT.c b/media/libeffects/lvm/lib/Common/src/Core_MixHard_2St_D32C31_SAT.c
index bf69e35..ea98041 100644
--- a/media/libeffects/lvm/lib/Common/src/Core_MixHard_2St_D32C31_SAT.c
+++ b/media/libeffects/lvm/lib/Common/src/Core_MixHard_2St_D32C31_SAT.c
@@ -25,7 +25,37 @@
/**********************************************************************************
FUNCTION CORE_MIXHARD_2ST_D32C31_SAT
***********************************************************************************/
+#ifdef BUILD_FLOAT
+void Core_MixHard_2St_D32C31_SAT( Mix_2St_Cll_FLOAT_t *pInstance,
+ const LVM_FLOAT *src1,
+ const LVM_FLOAT *src2,
+ LVM_FLOAT *dst,
+ LVM_INT16 n)
+{
+ LVM_FLOAT Temp1,Temp2,Temp3;
+ LVM_INT16 ii;
+ LVM_FLOAT Current1Short;
+ LVM_FLOAT Current2Short;
+ Current1Short = (pInstance->Current1);
+ Current2Short = (pInstance->Current2);
+
+ for (ii = n; ii != 0; ii--){
+ Temp1 = *src1++;
+ Temp3 = Temp1 * Current1Short;
+ Temp2 = *src2++;
+ Temp1 = Temp2 * Current2Short;
+ Temp2 = (Temp1 / 2.0f) + (Temp3 / 2.0f);
+ if (Temp2 > 0.5f)
+ Temp2 = 1.0f;
+ else if (Temp2 < -0.5f )
+ Temp2 = -1.0f;
+ else
+ Temp2 = (Temp2 * 2);
+ *dst++ = Temp2;
+ }
+}
+#else
void Core_MixHard_2St_D32C31_SAT( Mix_2St_Cll_t *pInstance,
const LVM_INT32 *src1,
const LVM_INT32 *src2,
@@ -55,6 +85,5 @@
*dst++ = Temp2;
}
}
-
-
+#endif
/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/Core_MixInSoft_D32C31_SAT.c b/media/libeffects/lvm/lib/Common/src/Core_MixInSoft_D32C31_SAT.c
index 3471f05..2814f19 100644
--- a/media/libeffects/lvm/lib/Common/src/Core_MixInSoft_D32C31_SAT.c
+++ b/media/libeffects/lvm/lib/Common/src/Core_MixInSoft_D32C31_SAT.c
@@ -26,6 +26,70 @@
FUNCTION CORE_MIXSOFT_1ST_D32C31_WRA
***********************************************************************************/
+#ifdef BUILD_FLOAT /* BUILD_FLOAT */
+void Core_MixInSoft_D32C31_SAT( Mix_1St_Cll_FLOAT_t *pInstance,
+ const LVM_FLOAT *src,
+ LVM_FLOAT *dst,
+ LVM_INT16 n)
+{
+ LVM_FLOAT Temp1,Temp2,Temp3;
+ LVM_INT16 OutLoop;
+ LVM_INT16 InLoop;
+ LVM_FLOAT TargetTimesOneMinAlpha;
+ LVM_FLOAT CurrentTimesAlpha;
+ LVM_INT16 ii,jj;
+
+
+ InLoop = (LVM_INT16)(n >> 2); /* Process per 4 samples */
+ OutLoop = (LVM_INT16)(n - (InLoop << 2));
+
+ TargetTimesOneMinAlpha = ((1.0f -pInstance->Alpha) * pInstance->Target);
+ if (pInstance->Target >= pInstance->Current){
+ TargetTimesOneMinAlpha +=(LVM_FLOAT)(2.0f / 2147483647.0f); /* Ceil*/
+ }
+
+ if (OutLoop){
+
+ CurrentTimesAlpha = pInstance->Current * pInstance->Alpha;
+ pInstance->Current = TargetTimesOneMinAlpha + CurrentTimesAlpha;
+
+ for (ii = OutLoop; ii != 0; ii--){
+ Temp1 = *src++;
+ Temp2 = *dst;
+
+ Temp3 = Temp1 * (pInstance->Current);
+ Temp1 = Temp2 + Temp3;
+
+ if (Temp1 > 1.0f)
+ Temp1 = 1.0f;
+ else if (Temp1 < -1.0f)
+ Temp1 = -1.0f;
+
+ *dst++ = Temp1;
+ }
+ }
+
+ for (ii = InLoop; ii != 0; ii--){
+
+ CurrentTimesAlpha = pInstance->Current * pInstance->Alpha;
+ pInstance->Current = TargetTimesOneMinAlpha + CurrentTimesAlpha;
+
+ for (jj = 4; jj!=0 ; jj--){
+ Temp1 = *src++;
+ Temp2 = *dst;
+
+ Temp3 = Temp1 * (pInstance->Current);
+ Temp1 = Temp2 + Temp3;
+
+ if (Temp1 > 1.0f)
+ Temp1 = 1.0f;
+ else if (Temp1 < -1.0f)
+ Temp1 = -1.0f;
+ *dst++ = Temp1;
+ }
+ }
+}
+#else
void Core_MixInSoft_D32C31_SAT( Mix_1St_Cll_t *pInstance,
const LVM_INT32 *src,
LVM_INT32 *dst,
@@ -89,6 +153,5 @@
}
}
}
-
-
+#endif
/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/Core_MixSoft_1St_D32C31_WRA.c b/media/libeffects/lvm/lib/Common/src/Core_MixSoft_1St_D32C31_WRA.c
index 709c304..814ccee 100644
--- a/media/libeffects/lvm/lib/Common/src/Core_MixSoft_1St_D32C31_WRA.c
+++ b/media/libeffects/lvm/lib/Common/src/Core_MixSoft_1St_D32C31_WRA.c
@@ -25,7 +25,79 @@
/**********************************************************************************
FUNCTION CORE_MIXSOFT_1ST_D32C31_WRA
***********************************************************************************/
+#ifdef BUILD_FLOAT
+void Core_MixSoft_1St_D32C31_WRA( Mix_1St_Cll_FLOAT_t *pInstance,
+ const LVM_FLOAT *src,
+ LVM_FLOAT *dst,
+ LVM_INT16 n)
+{
+ LVM_FLOAT Temp1,Temp2;
+ LVM_INT16 OutLoop;
+ LVM_INT16 InLoop;
+ LVM_FLOAT TargetTimesOneMinAlpha;
+ LVM_FLOAT CurrentTimesAlpha;
+ LVM_INT16 ii;
+
+ InLoop = (LVM_INT16)(n >> 2); /* Process per 4 samples */
+ OutLoop = (LVM_INT16)(n - (InLoop << 2));
+
+ TargetTimesOneMinAlpha = (1.0f - pInstance->Alpha) * pInstance->Target; /* float * float in float */
+ if (pInstance->Target >= pInstance->Current)
+ {
+ TargetTimesOneMinAlpha += (LVM_FLOAT)(2.0f / 2147483647.0f); /* Ceil*/
+ }
+
+ if (OutLoop != 0)
+ {
+ CurrentTimesAlpha = (pInstance->Current * pInstance->Alpha);
+ pInstance->Current = TargetTimesOneMinAlpha + CurrentTimesAlpha;
+
+ for (ii = OutLoop; ii != 0; ii--)
+ {
+ Temp1 = *src;
+ src++;
+
+ Temp2 = Temp1 * (pInstance->Current);
+ *dst = Temp2;
+ dst++;
+ }
+ }
+
+ for (ii = InLoop; ii != 0; ii--)
+ {
+ CurrentTimesAlpha = pInstance->Current * pInstance->Alpha;
+ pInstance->Current = TargetTimesOneMinAlpha + CurrentTimesAlpha;
+
+ Temp1 = *src;
+ src++;
+
+ Temp2 = Temp1 * (pInstance->Current);
+ *dst = Temp2;
+ dst++;
+
+ Temp1 = *src;
+ src++;
+
+ Temp2 = Temp1 * (pInstance->Current);
+ *dst = Temp2;
+ dst++;
+
+ Temp1 = *src;
+ src++;
+
+ Temp2 = Temp1 * (pInstance->Current);
+ *dst = Temp2;
+ dst++;
+
+ Temp1 = *src;
+ src++;
+ Temp2 = Temp1 * (pInstance->Current);
+ *dst = Temp2;
+ dst++;
+ }
+}
+#else
void Core_MixSoft_1St_D32C31_WRA( Mix_1St_Cll_t *pInstance,
const LVM_INT32 *src,
LVM_INT32 *dst,
@@ -98,6 +170,5 @@
dst++;
}
}
-
-
+#endif
/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01.c b/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01.c
index 49fa184..d261c9e 100644
--- a/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01.c
+++ b/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01.c
@@ -18,7 +18,53 @@
#include "BIQUAD.h"
#include "DC_2I_D16_TRC_WRA_01_Private.h"
#include "LVM_Macros.h"
+#ifdef BUILD_FLOAT
+void DC_2I_D16_TRC_WRA_01( Biquad_FLOAT_Instance_t *pInstance,
+ LVM_FLOAT *pDataIn,
+ LVM_FLOAT *pDataOut,
+ LVM_INT16 NrSamples)
+ {
+ LVM_FLOAT LeftDC,RightDC;
+ LVM_FLOAT Diff;
+ LVM_INT32 j;
+ PFilter_FLOAT_State pBiquadState = (PFilter_FLOAT_State) pInstance;
+ LeftDC = pBiquadState->LeftDC;
+ RightDC = pBiquadState->RightDC;
+ for(j = NrSamples-1; j >= 0; j--)
+ {
+ /* Subtract DC an saturate */
+ Diff =* (pDataIn++) - (LeftDC);
+ if (Diff > 1.0f) {
+ Diff = 1.0f; }
+ else if (Diff < -1.0f) {
+ Diff = -1.0f; }
+ *(pDataOut++) = (LVM_FLOAT)Diff;
+ if (Diff < 0) {
+ LeftDC -= DC_FLOAT_STEP; }
+ else {
+ LeftDC += DC_FLOAT_STEP; }
+
+
+ /* Subtract DC an saturate */
+ Diff =* (pDataIn++) - (RightDC);
+ if (Diff > 1.0f) {
+ Diff = 1.0f; }
+ else if (Diff < -1.0f) {
+ Diff = -1.0f; }
+ *(pDataOut++) = (LVM_FLOAT)Diff;
+ if (Diff < 0) {
+ RightDC -= DC_FLOAT_STEP; }
+ else {
+ RightDC += DC_FLOAT_STEP; }
+
+ }
+ pBiquadState->LeftDC = LeftDC;
+ pBiquadState->RightDC = RightDC;
+
+
+ }
+#else
void DC_2I_D16_TRC_WRA_01( Biquad_Instance_t *pInstance,
LVM_INT16 *pDataIn,
LVM_INT16 *pDataOut,
@@ -64,4 +110,4 @@
}
-
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01_Init.c b/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01_Init.c
index 468a88d..4f4fcd8 100644
--- a/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01_Init.c
+++ b/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01_Init.c
@@ -17,11 +17,18 @@
#include "BIQUAD.h"
#include "DC_2I_D16_TRC_WRA_01_Private.h"
-
+#ifdef BUILD_FLOAT
+void DC_2I_D16_TRC_WRA_01_Init(Biquad_FLOAT_Instance_t *pInstance)
+{
+ PFilter_FLOAT_State pBiquadState = (PFilter_FLOAT_State) pInstance;
+ pBiquadState->LeftDC = 0.0f;
+ pBiquadState->RightDC = 0.0f;
+}
+#else
void DC_2I_D16_TRC_WRA_01_Init(Biquad_Instance_t *pInstance)
{
PFilter_State pBiquadState = (PFilter_State) pInstance;
pBiquadState->LeftDC = 0;
pBiquadState->RightDC = 0;
}
-
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01_Private.h
index 89a4e68..fa6b729 100644
--- a/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01_Private.h
@@ -18,11 +18,23 @@
#ifndef _DC_2I_D16_TRC_WRA_01_PRIVATE_H_
#define _DC_2I_D16_TRC_WRA_01_PRIVATE_H_
+#ifdef BUILD_FLOAT
+#define DC_FLOAT_STEP 0.0000002384f;
+#else
#define DC_D16_STEP 0x200;
+#endif
/* The internal state variables are implemented in a (for the user) hidden structure */
/* In this (private) file, the internal structure is declared fro private use.*/
+#ifdef BUILD_FLOAT
+typedef struct _Filter_FLOAT_State_
+{
+ LVM_FLOAT LeftDC; /* LeftDC */
+ LVM_FLOAT RightDC; /* RightDC */
+}Filter_FLOAT_State;
+typedef Filter_FLOAT_State * PFilter_FLOAT_State ;
+#else
typedef struct _Filter_State_
{
LVM_INT32 LeftDC; /* LeftDC */
@@ -30,5 +42,5 @@
}Filter_State;
typedef Filter_State * PFilter_State ;
-
+#endif
#endif /* _DC_2I_D16_TRC_WRA_01_PRIVATE_H_ */
diff --git a/media/libeffects/lvm/lib/Common/src/DelayMix_16x16.c b/media/libeffects/lvm/lib/Common/src/DelayMix_16x16.c
index 7e3182d..f502716 100644
--- a/media/libeffects/lvm/lib/Common/src/DelayMix_16x16.c
+++ b/media/libeffects/lvm/lib/Common/src/DelayMix_16x16.c
@@ -36,10 +36,55 @@
LVM_INT16 Offset = *pOffset;
LVM_INT16 temp;
+ for (i = 0; i < n; i++)
+ {
+ /* Left channel */
+ temp = (LVM_INT16)((LVM_UINT32)((LVM_INT32)(*dst) + (LVM_INT32)delay[Offset]) >> 1);
+ *dst = temp;
+ dst++;
+
+ delay[Offset] = *src;
+ Offset++;
+ src++;
+
+
+ /* Right channel */
+ temp = (LVM_INT16)((LVM_UINT32)((LVM_INT32)(*dst) - (LVM_INT32)delay[Offset]) >> 1);
+ *dst = temp;
+ dst++;
+
+ delay[Offset] = *src;
+ Offset++;
+ src++;
+
+ /* Make the reverb delay buffer a circular buffer */
+ if (Offset >= size)
+ {
+ Offset = 0;
+ }
+ }
+
+ /* Update the offset */
+ *pOffset = Offset;
+
+ return;
+}
+#ifdef BUILD_FLOAT
+void DelayMix_Float(const LVM_FLOAT *src, /* Source 1, to be delayed */
+ LVM_FLOAT *delay, /* Delay buffer */
+ LVM_INT16 size, /* Delay size */
+ LVM_FLOAT *dst, /* Source/destination */
+ LVM_INT16 *pOffset, /* Delay offset */
+ LVM_INT16 n) /* Number of stereo samples */
+{
+ LVM_INT16 i;
+ LVM_INT16 Offset = *pOffset;
+ LVM_FLOAT temp;
+
for (i=0; i<n; i++)
{
/* Left channel */
- temp = (LVM_INT16)((LVM_UINT32)((LVM_INT32)(*dst) + (LVM_INT32)delay[Offset]) >> 1);
+ temp = (LVM_FLOAT)((LVM_FLOAT)(*dst + (LVM_FLOAT)delay[Offset]) / 2.0f);
*dst = temp;
dst++;
@@ -49,7 +94,7 @@
/* Right channel */
- temp = (LVM_INT16)((LVM_UINT32)((LVM_INT32)(*dst) - (LVM_INT32)delay[Offset]) >> 1);
+ temp = (LVM_FLOAT)((LVM_FLOAT)(*dst - (LVM_FLOAT)delay[Offset]) / 2.0f);
*dst = temp;
dst++;
@@ -69,5 +114,5 @@
return;
}
-
+#endif
/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/FO_1I_D16F16C15_TRC_WRA_01.c b/media/libeffects/lvm/lib/Common/src/FO_1I_D16F16C15_TRC_WRA_01.c
index de77361..039c88c 100644
--- a/media/libeffects/lvm/lib/Common/src/FO_1I_D16F16C15_TRC_WRA_01.c
+++ b/media/libeffects/lvm/lib/Common/src/FO_1I_D16F16C15_TRC_WRA_01.c
@@ -31,6 +31,46 @@
pBiquadState->pDelays[1] is y(n-1)L in Q0 format
***************************************************************************/
+#ifdef BUILD_FLOAT
+void FO_1I_D16F16C15_TRC_WRA_01( Biquad_FLOAT_Instance_t *pInstance,
+ LVM_FLOAT *pDataIn,
+ LVM_FLOAT *pDataOut,
+ LVM_INT16 NrSamples)
+ {
+ LVM_FLOAT ynL;
+ LVM_INT16 ii;
+ PFilter_State_FLOAT pBiquadState = (PFilter_State_FLOAT) pInstance;
+
+ for (ii = NrSamples; ii != 0; ii--)
+ {
+
+ /**************************************************************************
+ PROCESSING OF THE LEFT CHANNEL
+ ***************************************************************************/
+ // ynL=A1 * x(n-1)L
+ ynL = (LVM_FLOAT)pBiquadState->coefs[0] * pBiquadState->pDelays[0];
+
+ // ynL+=A0 * x(n)L
+ ynL += (LVM_FLOAT)pBiquadState->coefs[1] * (*pDataIn);
+
+ // ynL+= (-B1 * y(n-1)L
+ ynL += (LVM_FLOAT)pBiquadState->coefs[2] * pBiquadState->pDelays[1];
+
+ /**************************************************************************
+ UPDATING THE DELAYS
+ ***************************************************************************/
+ pBiquadState->pDelays[1] = ynL; // Update y(n-1)L
+ pBiquadState->pDelays[0] = (*pDataIn++); // Update x(n-1)L
+
+ /**************************************************************************
+ WRITING THE OUTPUT
+ ***************************************************************************/
+ *pDataOut++ = (LVM_FLOAT)ynL; // Write Left output
+
+ }
+
+ }
+#else
void FO_1I_D16F16C15_TRC_WRA_01( Biquad_Instance_t *pInstance,
LVM_INT16 *pDataIn,
LVM_INT16 *pDataOut,
@@ -71,4 +111,4 @@
}
}
-
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/FO_1I_D16F16Css_TRC_WRA_01_Init.c b/media/libeffects/lvm/lib/Common/src/FO_1I_D16F16Css_TRC_WRA_01_Init.c
index 96252cc..b21b8a4 100644
--- a/media/libeffects/lvm/lib/Common/src/FO_1I_D16F16Css_TRC_WRA_01_Init.c
+++ b/media/libeffects/lvm/lib/Common/src/FO_1I_D16F16Css_TRC_WRA_01_Init.c
@@ -38,6 +38,22 @@
/* RETURNS: */
/* void return code */
/*-------------------------------------------------------------------------*/
+#ifdef BUILD_FLOAT
+void FO_1I_D16F16Css_TRC_WRA_01_Init( Biquad_FLOAT_Instance_t *pInstance,
+ Biquad_1I_Order1_FLOAT_Taps_t *pTaps,
+ FO_FLOAT_Coefs_t *pCoef)
+{
+ LVM_FLOAT temp;
+ PFilter_State_FLOAT pBiquadState = (PFilter_State_FLOAT) pInstance;
+ pBiquadState->pDelays = (LVM_FLOAT *)pTaps;
+ temp = pCoef->A1;
+ pBiquadState->coefs[0] = temp;
+ temp = pCoef->A0;
+ pBiquadState->coefs[1] = temp;
+ temp = pCoef->B1;
+ pBiquadState->coefs[2] = temp;
+}
+#else
void FO_1I_D16F16Css_TRC_WRA_01_Init( Biquad_Instance_t *pInstance,
Biquad_1I_Order1_Taps_t *pTaps,
FO_C16_Coefs_t *pCoef)
@@ -53,6 +69,7 @@
temp=pCoef->B1;
pBiquadState->coefs[2]=temp;
}
+#endif
/*------------------------------------------------*/
/* End Of File: FO_1I_D16F16Css_TRC_WRA_01_Init.c */
diff --git a/media/libeffects/lvm/lib/Common/src/FO_1I_D16F16Css_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/FO_1I_D16F16Css_TRC_WRA_01_Private.h
index 516ca83..6fdb039 100644
--- a/media/libeffects/lvm/lib/Common/src/FO_1I_D16F16Css_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/FO_1I_D16F16Css_TRC_WRA_01_Private.h
@@ -28,4 +28,14 @@
typedef Filter_State * PFilter_State ;
+#ifdef BUILD_FLOAT
+typedef struct _Filter_State_FLOAT
+{
+ LVM_FLOAT * pDelays; /* pointer to the delayed samples \
+ (data of 32 bits) */
+ LVM_FLOAT coefs[3]; /* pointer to the filter coefficients */
+}Filter_State_FLOAT;
+
+typedef Filter_State_FLOAT * PFilter_State_FLOAT ;
+#endif
#endif /* _FO_1I_D16F16CSS_TRC_WRA_01_PRIVATE_H_ */
diff --git a/media/libeffects/lvm/lib/Common/src/FO_1I_D32F32C31_TRC_WRA_01.c b/media/libeffects/lvm/lib/Common/src/FO_1I_D32F32C31_TRC_WRA_01.c
index 0f1d5bc..416e8eb 100644
--- a/media/libeffects/lvm/lib/Common/src/FO_1I_D32F32C31_TRC_WRA_01.c
+++ b/media/libeffects/lvm/lib/Common/src/FO_1I_D32F32C31_TRC_WRA_01.c
@@ -31,7 +31,47 @@
pBiquadState->pDelays[0] is x(n-1)L in Q0 format
pBiquadState->pDelays[1] is y(n-1)L in Q0 format
***************************************************************************/
+#ifdef BUILD_FLOAT
+void FO_1I_D32F32C31_TRC_WRA_01( Biquad_FLOAT_Instance_t *pInstance,
+ LVM_FLOAT *pDataIn,
+ LVM_FLOAT *pDataOut,
+ LVM_INT16 NrSamples)
+ {
+ LVM_FLOAT ynL,templ;
+ LVM_INT16 ii;
+ PFilter_State_FLOAT pBiquadState = (PFilter_State_FLOAT) pInstance;
+ for (ii = NrSamples; ii != 0; ii--)
+ {
+
+ /**************************************************************************
+ PROCESSING OF THE LEFT CHANNEL
+ ***************************************************************************/
+ // ynL=A1 * x(n-1)L
+ ynL = pBiquadState->coefs[0] * pBiquadState->pDelays[0];
+
+ // ynL+=A0 * x(n)L
+ templ = pBiquadState->coefs[1] * (*pDataIn);
+ ynL += templ;
+
+ // ynL+= (-B1 * y(n-1)L
+ templ = pBiquadState->coefs[2] * pBiquadState->pDelays[1];
+ ynL += templ;
+
+ /**************************************************************************
+ UPDATING THE DELAYS
+ ***************************************************************************/
+ pBiquadState->pDelays[1] = ynL; // Update y(n-1)L
+ pBiquadState->pDelays[0] = (*pDataIn++); // Update x(n-1)L
+
+ /**************************************************************************
+ WRITING THE OUTPUT
+ ***************************************************************************/
+ *pDataOut++ = (LVM_FLOAT)ynL; // Write Left output in Q0
+ }
+
+ }
+#else
void FO_1I_D32F32C31_TRC_WRA_01( Biquad_Instance_t *pInstance,
LVM_INT32 *pDataIn,
LVM_INT32 *pDataOut,
@@ -71,4 +111,4 @@
}
}
-
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/FO_1I_D32F32Cll_TRC_WRA_01_Init.c b/media/libeffects/lvm/lib/Common/src/FO_1I_D32F32Cll_TRC_WRA_01_Init.c
index 136e4f6..f33d24d 100644
--- a/media/libeffects/lvm/lib/Common/src/FO_1I_D32F32Cll_TRC_WRA_01_Init.c
+++ b/media/libeffects/lvm/lib/Common/src/FO_1I_D32F32Cll_TRC_WRA_01_Init.c
@@ -37,6 +37,23 @@
/* RETURNS: */
/* void return code */
/*-------------------------------------------------------------------------*/
+#ifdef BUILD_FLOAT
+void FO_1I_D32F32Cll_TRC_WRA_01_Init( Biquad_FLOAT_Instance_t *pInstance,
+ Biquad_1I_Order1_FLOAT_Taps_t *pTaps,
+ FO_FLOAT_Coefs_t *pCoef)
+{
+ LVM_FLOAT temp;
+ PFilter_State_FLOAT pBiquadState = (PFilter_State_FLOAT) pInstance;
+ pBiquadState->pDelays = (LVM_FLOAT *) pTaps;
+
+ temp = pCoef->A1;
+ pBiquadState->coefs[0] = temp;
+ temp = pCoef->A0;
+ pBiquadState->coefs[1] = temp;
+ temp = pCoef->B1;
+ pBiquadState->coefs[2] = temp;
+}
+#else
void FO_1I_D32F32Cll_TRC_WRA_01_Init( Biquad_Instance_t *pInstance,
Biquad_1I_Order1_Taps_t *pTaps,
FO_C32_Coefs_t *pCoef)
@@ -52,6 +69,7 @@
temp=pCoef->B1;
pBiquadState->coefs[2]=temp;
}
+#endif
/*------------------------------------------------*/
/* End Of File: FO_1I_D32F32Cll_TRC_WRA_01_Init.c */
diff --git a/media/libeffects/lvm/lib/Common/src/FO_1I_D32F32Cll_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/FO_1I_D32F32Cll_TRC_WRA_01_Private.h
index 94ad48c..fdb528b 100644
--- a/media/libeffects/lvm/lib/Common/src/FO_1I_D32F32Cll_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/FO_1I_D32F32Cll_TRC_WRA_01_Private.h
@@ -29,4 +29,13 @@
typedef Filter_State * PFilter_State ;
+#ifdef BUILD_FLOAT
+typedef struct _Filter_State_FLOAT_
+{
+ LVM_FLOAT * pDelays; /* pointer to the delayed samples (data of 32 bits) */
+ LVM_FLOAT coefs[3]; /* pointer to the filter coefficients */
+}Filter_State_FLOAT;
+
+typedef Filter_State_FLOAT * PFilter_State_FLOAT ;
+#endif
#endif /* _FO_1I_D32F32CLL_TRC_WRA_01_PRIVATE_H_ */
diff --git a/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32C15_LShx_TRC_WRA_01.c b/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32C15_LShx_TRC_WRA_01.c
index 8388050..192927c 100644
--- a/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32C15_LShx_TRC_WRA_01.c
+++ b/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32C15_LShx_TRC_WRA_01.c
@@ -32,7 +32,92 @@
pBiquadState->pDelays[2] is x(n-1)R in Q15 format
pBiquadState->pDelays[3] is y(n-1)R in Q30 format
***************************************************************************/
+#ifdef BUILD_FLOAT
+void FO_2I_D16F32C15_LShx_TRC_WRA_01(Biquad_FLOAT_Instance_t *pInstance,
+ LVM_FLOAT *pDataIn,
+ LVM_FLOAT *pDataOut,
+ LVM_INT16 NrSamples)
+ {
+ LVM_FLOAT ynL,ynR;
+ LVM_FLOAT Temp;
+ LVM_FLOAT NegSatValue;
+ LVM_INT16 ii;
+ PFilter_Float_State pBiquadState = (PFilter_Float_State) pInstance;
+
+ NegSatValue = -1.0f;
+
+ for (ii = NrSamples; ii != 0; ii--)
+ {
+
+ /**************************************************************************
+ PROCESSING OF THE LEFT CHANNEL
+ ***************************************************************************/
+
+ // ynL =A1 * x(n-1)L
+ ynL = (LVM_FLOAT)pBiquadState->coefs[0] * pBiquadState->pDelays[0];
+ // ynR =A1 * x(n-1)R
+ ynR = (LVM_FLOAT)pBiquadState->coefs[0] * pBiquadState->pDelays[2];
+
+
+ // ynL+=A0 * x(n)L
+ ynL += (LVM_FLOAT)pBiquadState->coefs[1] * (*pDataIn);
+ // ynR+=A0 * x(n)L
+ ynR += (LVM_FLOAT)pBiquadState->coefs[1] * (*(pDataIn+1));
+
+
+ // ynL += (-B1 * y(n-1)L )
+ Temp = pBiquadState->pDelays[1] * pBiquadState->coefs[2];
+ ynL += Temp;
+ // ynR += (-B1 * y(n-1)R ) )
+ Temp = pBiquadState->pDelays[3] * pBiquadState->coefs[2];
+ ynR += Temp;
+
+
+ /**************************************************************************
+ UPDATING THE DELAYS
+ ***************************************************************************/
+ pBiquadState->pDelays[1] = ynL; // Update y(n-1)L
+ pBiquadState->pDelays[0] = (*pDataIn++); // Update x(n-1)L
+
+ pBiquadState->pDelays[3] = ynR; // Update y(n-1)R
+ pBiquadState->pDelays[2] = (*pDataIn++); // Update x(n-1)R
+
+ /**************************************************************************
+ WRITING THE OUTPUT
+ ***************************************************************************/
+
+ /*Saturate results*/
+ if(ynL > 1.0f)
+ {
+ ynL = 1.0f;
+ }
+ else
+ {
+ if(ynL < NegSatValue)
+ {
+ ynL = NegSatValue;
+ }
+ }
+
+ if(ynR > 1.0f)
+ {
+ ynR = 1.0f;
+ }
+ else
+ {
+ if(ynR < NegSatValue)
+ {
+ ynR = NegSatValue;
+ }
+ }
+
+ *pDataOut++ = (LVM_FLOAT)ynL;
+ *pDataOut++ = (LVM_FLOAT)ynR;
+ }
+
+ }
+#else
void FO_2I_D16F32C15_LShx_TRC_WRA_01(Biquad_Instance_t *pInstance,
LVM_INT16 *pDataIn,
LVM_INT16 *pDataOut,
@@ -125,4 +210,4 @@
}
}
-
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32Css_LShx_TRC_WRA_01_Init.c b/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32Css_LShx_TRC_WRA_01_Init.c
index a19c32c..33ca6cf 100644
--- a/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32Css_LShx_TRC_WRA_01_Init.c
+++ b/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32Css_LShx_TRC_WRA_01_Init.c
@@ -37,6 +37,23 @@
/* RETURNS: */
/* void return code */
/*-------------------------------------------------------------------------*/
+#ifdef BUILD_FLOAT
+void FO_2I_D16F32Css_LShx_TRC_WRA_01_Init(Biquad_FLOAT_Instance_t *pInstance,
+ Biquad_2I_Order1_FLOAT_Taps_t *pTaps,
+ FO_FLOAT_LShx_Coefs_t *pCoef)
+{
+ LVM_FLOAT temp;
+ PFilter_Float_State pBiquadState = (PFilter_Float_State) pInstance;
+ pBiquadState->pDelays = (LVM_FLOAT *) pTaps ;
+
+ temp = pCoef->A1;
+ pBiquadState->coefs[0] = temp;
+ temp = pCoef->A0;
+ pBiquadState->coefs[1] = temp;
+ temp = pCoef->B1;
+ pBiquadState->coefs[2] = temp;
+}
+#else
void FO_2I_D16F32Css_LShx_TRC_WRA_01_Init(Biquad_Instance_t *pInstance,
Biquad_2I_Order1_Taps_t *pTaps,
FO_C16_LShx_Coefs_t *pCoef)
@@ -55,6 +72,7 @@
temp=pCoef->Shift;
pBiquadState->Shift = temp;
}
+#endif
/*-------------------------------------------------------------------------*/
/* End Of File: FO_2I_D16F32Css_LShx_TRC_WRA_01_Init.c */
diff --git a/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32Css_LShx_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32Css_LShx_TRC_WRA_01_Private.h
index 4640743..368bfce 100644
--- a/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32Css_LShx_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32Css_LShx_TRC_WRA_01_Private.h
@@ -20,6 +20,15 @@
/* The internal state variables are implemented in a (for the user) hidden structure */
/* In this (private) file, the internal structure is declared fro private use. */
+#ifdef BUILD_FLOAT
+typedef struct _Filter_State_
+{
+ LVM_FLOAT *pDelays; /* pointer to the delayed samples (data of 32 bits) */
+ LVM_FLOAT coefs[3]; /* pointer to the filter coefficients */
+}Filter_Float_State;
+
+typedef Filter_Float_State * PFilter_Float_State ;
+#else
typedef struct _Filter_State_
{
LVM_INT32 *pDelays; /* pointer to the delayed samples (data of 32 bits) */
@@ -28,5 +37,5 @@
}Filter_State;
typedef Filter_State * PFilter_State ;
-
+#endif
#endif /* _FO_2I_D16F32CSS_LSHX_TRC_WRA_01_PRIVATE_H_ */
diff --git a/media/libeffects/lvm/lib/Common/src/Filters.h b/media/libeffects/lvm/lib/Common/src/Filters.h
index 4d32df1..b1fde0c 100644
--- a/media/libeffects/lvm/lib/Common/src/Filters.h
+++ b/media/libeffects/lvm/lib/Common/src/Filters.h
@@ -34,6 +34,7 @@
* Biquad with coefficients A0, A1, A2, B1 and B2 coefficients
*/
/* Single precision (16-bit) Biquad section coefficients */
+#ifndef BUILD_FLOAT
typedef struct
{
LVM_INT16 A0;
@@ -43,12 +44,22 @@
LVM_INT16 B2;
LVM_UINT16 Scale;
} BiquadA012B12CoefsSP_t;
-
-
+#else
+typedef struct
+{
+ LVM_FLOAT A0;
+ LVM_FLOAT A1;
+ LVM_FLOAT A2;
+ LVM_FLOAT B1;
+ LVM_FLOAT B2;
+ LVM_UINT16 Scale;
+} BiquadA012B12CoefsSP_t;
+#endif
/*
* Biquad with coefficients A0, A1 and B1 coefficients
*/
/* Single precision (16-bit) Biquad section coefficients */
+#ifndef BUILD_FLOAT
typedef struct
{
LVM_INT16 A0;
@@ -56,8 +67,15 @@
LVM_INT16 B1;
LVM_UINT16 Scale;
} BiquadA01B1CoefsSP_t;
-
-
+#else
+typedef struct
+{
+ LVM_FLOAT A0;
+ LVM_FLOAT A1;
+ LVM_FLOAT B1;
+ LVM_UINT16 Scale;
+} BiquadA01B1CoefsSP_t;
+#endif
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/media/libeffects/lvm/lib/Common/src/From2iToMS_16x16.c b/media/libeffects/lvm/lib/Common/src/From2iToMS_16x16.c
index 7975e8b..2c6e6c3 100644
--- a/media/libeffects/lvm/lib/Common/src/From2iToMS_16x16.c
+++ b/media/libeffects/lvm/lib/Common/src/From2iToMS_16x16.c
@@ -53,5 +53,34 @@
return;
}
+#ifdef BUILD_FLOAT
+void From2iToMS_Float( const LVM_FLOAT *src,
+ LVM_FLOAT *dstM,
+ LVM_FLOAT *dstS,
+ LVM_INT16 n )
+{
+ LVM_FLOAT temp1,left,right;
+ LVM_INT16 ii;
+ for (ii = n; ii != 0; ii--)
+ {
+ left = (LVM_FLOAT)*src;
+ src++;
+ right = (LVM_FLOAT)*src;
+ src++;
+
+ /* Compute M signal*/
+ temp1 = (left + right) / 2.0f;
+ *dstM = (LVM_FLOAT)temp1;
+ dstM++;
+
+ /* Compute S signal*/
+ temp1 = (left - right) / 2.0f;
+ *dstS = (LVM_FLOAT)temp1;
+ dstS++;
+ }
+
+ return;
+}
+#endif
/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/From2iToMono_32.c b/media/libeffects/lvm/lib/Common/src/From2iToMono_32.c
index 8bb292f..ac1eea8 100644
--- a/media/libeffects/lvm/lib/Common/src/From2iToMono_32.c
+++ b/media/libeffects/lvm/lib/Common/src/From2iToMono_32.c
@@ -46,5 +46,27 @@
return;
}
+#ifdef BUILD_FLOAT
+void From2iToMono_Float( const LVM_FLOAT *src,
+ LVM_FLOAT *dst,
+ LVM_INT16 n)
+{
+ LVM_INT16 ii;
+ LVM_FLOAT Temp;
+ for (ii = n; ii != 0; ii--)
+ {
+ Temp = (*src);
+ src++;
+
+ Temp += (*src);
+ src++;
+
+ *dst = Temp / 2.0f;
+ dst++;
+ }
+
+ return;
+}
+#endif
/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/JoinTo2i_32x32.c b/media/libeffects/lvm/lib/Common/src/JoinTo2i_32x32.c
index 9b938bd..ebc477e 100644
--- a/media/libeffects/lvm/lib/Common/src/JoinTo2i_32x32.c
+++ b/media/libeffects/lvm/lib/Common/src/JoinTo2i_32x32.c
@@ -49,6 +49,31 @@
return;
}
+#ifdef BUILD_FLOAT
+void JoinTo2i_Float( const LVM_FLOAT *srcL,
+ const LVM_FLOAT *srcR,
+ LVM_FLOAT *dst,
+ LVM_INT16 n )
+{
+ LVM_INT16 ii;
+ srcL += n - 1;
+ srcR += n - 1;
+ dst += ((2 * n) - 1);
+
+ for (ii = n; ii != 0; ii--)
+ {
+ *dst = *srcR;
+ dst--;
+ srcR--;
+
+ *dst = *srcL;
+ dst--;
+ srcL--;
+ }
+
+ return;
+}
+#endif
/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixHard_1St_2i_D16C31_SAT.c b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixHard_1St_2i_D16C31_SAT.c
index 3d39b93..eb5755e 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixHard_1St_2i_D16C31_SAT.c
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixHard_1St_2i_D16C31_SAT.c
@@ -27,7 +27,39 @@
/**********************************************************************************
FUNCTION LVC_Core_MixHard_1St_2i_D16C31_SAT
***********************************************************************************/
+#ifdef BUILD_FLOAT
+void LVC_Core_MixHard_1St_2i_D16C31_SAT( LVMixer3_FLOAT_st *ptrInstance1,
+ LVMixer3_FLOAT_st *ptrInstance2,
+ const LVM_FLOAT *src,
+ LVM_FLOAT *dst,
+ LVM_INT16 n)
+{
+ LVM_FLOAT Temp;
+ LVM_INT16 ii;
+ Mix_Private_FLOAT_st *pInstance1 = (Mix_Private_FLOAT_st *)(ptrInstance1->PrivateParams);
+ Mix_Private_FLOAT_st *pInstance2 = (Mix_Private_FLOAT_st *)(ptrInstance2->PrivateParams);
+ for (ii = n; ii != 0; ii--)
+ {
+ Temp = ((LVM_FLOAT)*(src++) * (LVM_FLOAT)pInstance1->Current);
+ if (Temp > 1.0f)
+ *dst++ = 1.0f;
+ else if (Temp < -1.0f)
+ *dst++ = -1.0f;
+ else
+ *dst++ = (LVM_FLOAT)Temp;
+ Temp = ((LVM_FLOAT)*(src++) * (LVM_FLOAT)pInstance2->Current);
+ if (Temp > 1.0f)
+ *dst++ = 1.0f;
+ else if (Temp < -1.0f)
+ *dst++ = -1.0f;
+ else
+ *dst++ = (LVM_FLOAT)Temp;
+ }
+
+
+}
+#else
void LVC_Core_MixHard_1St_2i_D16C31_SAT( LVMixer3_st *ptrInstance1,
LVMixer3_st *ptrInstance2,
const LVM_INT16 *src,
@@ -66,4 +98,5 @@
}
+#endif
/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixHard_2St_D16C31_SAT.c b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixHard_2St_D16C31_SAT.c
index 2daf74a..ec0baaf 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixHard_2St_D16C31_SAT.c
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixHard_2St_D16C31_SAT.c
@@ -24,7 +24,37 @@
/**********************************************************************************
FUNCTION LVCore_MIXHARD_2ST_D16C31_SAT
***********************************************************************************/
+#ifdef BUILD_FLOAT
+void LVC_Core_MixHard_2St_D16C31_SAT( LVMixer3_FLOAT_st *ptrInstance1,
+ LVMixer3_FLOAT_st *ptrInstance2,
+ const LVM_FLOAT *src1,
+ const LVM_FLOAT *src2,
+ LVM_FLOAT *dst,
+ LVM_INT16 n)
+{
+ LVM_FLOAT Temp;
+ LVM_INT16 ii;
+ LVM_FLOAT Current1;
+ LVM_FLOAT Current2;
+ Mix_Private_FLOAT_st *pInstance1 = (Mix_Private_FLOAT_st *)(ptrInstance1->PrivateParams);
+ Mix_Private_FLOAT_st *pInstance2 = (Mix_Private_FLOAT_st *)(ptrInstance2->PrivateParams);
+
+ Current1 = (pInstance1->Current);
+ Current2 = (pInstance2->Current);
+
+ for (ii = n; ii != 0; ii--){
+ Temp = (((LVM_FLOAT)*(src1++) * (LVM_FLOAT)Current1)) +
+ (((LVM_FLOAT)*(src2++) * (LVM_FLOAT)Current2));
+ if (Temp > 1.0f)
+ *dst++ = 1.0f;
+ else if (Temp < -1.0f)
+ *dst++ = -1.0f;
+ else
+ *dst++ = Temp;
+ }
+}
+#else
void LVC_Core_MixHard_2St_D16C31_SAT( LVMixer3_st *ptrInstance1,
LVMixer3_st *ptrInstance2,
const LVM_INT16 *src1,
@@ -54,6 +84,5 @@
*dst++ = (LVM_INT16)Temp;
}
}
-
-
+#endif
/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixInSoft_D16C31_SAT.c b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixInSoft_D16C31_SAT.c
index caa0951..d2694cc 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixInSoft_D16C31_SAT.c
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixInSoft_D16C31_SAT.c
@@ -25,7 +25,96 @@
/**********************************************************************************
FUNCTION LVCore_MIXSOFT_1ST_D16C31_WRA
***********************************************************************************/
+#ifdef BUILD_FLOAT
+void LVC_Core_MixInSoft_D16C31_SAT( LVMixer3_FLOAT_st *ptrInstance,
+ const LVM_FLOAT *src,
+ LVM_FLOAT *dst,
+ LVM_INT16 n)
+{
+ LVM_INT16 OutLoop;
+ LVM_INT16 InLoop;
+ LVM_INT32 ii,jj;
+ Mix_Private_FLOAT_st *pInstance = (Mix_Private_FLOAT_st *)(ptrInstance->PrivateParams);
+ LVM_FLOAT Delta = pInstance->Delta;
+ LVM_FLOAT Current = pInstance->Current;
+ LVM_FLOAT Target = pInstance->Target;
+ LVM_FLOAT Temp;
+
+ InLoop = (LVM_INT16)(n >> 2); /* Process per 4 samples */
+ OutLoop = (LVM_INT16)(n - (InLoop << 2));
+
+ if(Current < Target){
+ if (OutLoop){
+ Temp = Current + Delta;
+ Current = Temp;
+ if (Current > Target)
+ Current = Target;
+
+ for (ii = OutLoop; ii != 0; ii--){
+ Temp = ((LVM_FLOAT)*dst) + (((LVM_FLOAT)*(src++) * Current));
+ if (Temp > 1.0f)
+ *dst++ = 1.0f;
+ else if (Temp < -1.0f)
+ *dst++ = -1.0f;
+ else
+ *dst++ = (LVM_FLOAT)Temp;
+ }
+ }
+
+ for (ii = InLoop; ii != 0; ii--){
+ Temp = Current + Delta;
+ Current = Temp;
+ if (Current > Target)
+ Current = Target;
+
+ for (jj = 4; jj != 0 ; jj--){
+ Temp = ((LVM_FLOAT)*dst) + (((LVM_FLOAT)*(src++) * Current));
+ if (Temp > 1.0f)
+ *dst++ = 1.0f;
+ else if (Temp < -1.0f)
+ *dst++ = -1.0f;
+ else
+ *dst++ = (LVM_FLOAT)Temp;
+ }
+ }
+ }
+ else{
+ if (OutLoop){
+ Current -= Delta;
+ if (Current < Target)
+ Current = Target;
+
+ for (ii = OutLoop; ii != 0; ii--){
+ Temp = ((LVM_FLOAT)*dst) + (((LVM_FLOAT)*(src++) * Current));
+ if (Temp > 1.0f)
+ *dst++ = 1.0f;
+ else if (Temp < -1.0f)
+ *dst++ = -1.0f;
+ else
+ *dst++ = (LVM_FLOAT)Temp;
+ }
+ }
+
+ for (ii = InLoop; ii != 0; ii--){
+ Current -= Delta;
+ if (Current < Target)
+ Current = Target;
+
+ for (jj = 4; jj != 0 ; jj--){
+ Temp = ((LVM_FLOAT)*dst) + (((LVM_FLOAT)*(src++) * Current));
+ if (Temp > 1.0f)
+ *dst++ = 1.0f;
+ else if (Temp < -1.0f)
+ *dst++ = -1.0f;
+ else
+ *dst++ = (LVM_FLOAT)Temp;
+ }
+ }
+ }
+ pInstance->Current = Current;
+}
+#else
void LVC_Core_MixInSoft_D16C31_SAT( LVMixer3_st *ptrInstance,
const LVM_INT16 *src,
LVM_INT16 *dst,
@@ -123,6 +212,5 @@
}
pInstance->Current=Current;
}
-
-
+#endif
/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixSoft_1St_2i_D16C31_WRA.c b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixSoft_1St_2i_D16C31_WRA.c
index 09ec427..656a117 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixSoft_1St_2i_D16C31_WRA.c
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixSoft_1St_2i_D16C31_WRA.c
@@ -26,7 +26,127 @@
/**********************************************************************************
FUNCTION LVC_Core_MixSoft_1St_2i_D16C31_WRA
***********************************************************************************/
+#ifdef BUILD_FLOAT
+static LVM_FLOAT ADD2_SAT_FLOAT(LVM_FLOAT a,
+ LVM_FLOAT b,
+ LVM_FLOAT c)
+{
+ LVM_FLOAT temp;
+ temp = a + b ;
+ if (temp < -1.0f)
+ c = -1.0f;
+ else if (temp > 1.0f)
+ c = 1.0f;
+ else
+ c = temp;
+ return c;
+}
+void LVC_Core_MixSoft_1St_2i_D16C31_WRA( LVMixer3_FLOAT_st *ptrInstance1,
+ LVMixer3_FLOAT_st *ptrInstance2,
+ const LVM_FLOAT *src,
+ LVM_FLOAT *dst,
+ LVM_INT16 n)
+{
+ LVM_INT16 OutLoop;
+ LVM_INT16 InLoop;
+ LVM_INT32 ii;
+ Mix_Private_FLOAT_st *pInstanceL = (Mix_Private_FLOAT_st *)(ptrInstance1->PrivateParams);
+ Mix_Private_FLOAT_st *pInstanceR = (Mix_Private_FLOAT_st *)(ptrInstance2->PrivateParams);
+ LVM_FLOAT DeltaL = pInstanceL->Delta;
+ LVM_FLOAT CurrentL = pInstanceL->Current;
+ LVM_FLOAT TargetL = pInstanceL->Target;
+
+ LVM_FLOAT DeltaR = pInstanceR->Delta;
+ LVM_FLOAT CurrentR = pInstanceR->Current;
+ LVM_FLOAT TargetR = pInstanceR->Target;
+
+ LVM_FLOAT Temp = 0;
+
+ InLoop = (LVM_INT16)(n >> 2); /* Process per 4 samples */
+ OutLoop = (LVM_INT16)(n - (InLoop << 2));
+
+ if (OutLoop)
+ {
+ if(CurrentL < TargetL)
+ {
+ ADD2_SAT_FLOAT(CurrentL, DeltaL, Temp);
+ CurrentL = Temp;
+ if (CurrentL > TargetL)
+ CurrentL = TargetL;
+ }
+ else
+ {
+ CurrentL -= DeltaL;
+ if (CurrentL < TargetL)
+ CurrentL = TargetL;
+ }
+
+ if(CurrentR < TargetR)
+ {
+ ADD2_SAT_FLOAT(CurrentR, DeltaR, Temp);
+ CurrentR = Temp;
+ if (CurrentR > TargetR)
+ CurrentR = TargetR;
+ }
+ else
+ {
+ CurrentR -= DeltaR;
+ if (CurrentR < TargetR)
+ CurrentR = TargetR;
+ }
+
+ for (ii = OutLoop * 2; ii != 0; ii -= 2)
+ {
+ *(dst++) = (LVM_FLOAT)(((LVM_FLOAT)*(src++) * (LVM_FLOAT)CurrentL));
+ *(dst++) = (LVM_FLOAT)(((LVM_FLOAT)*(src++) * (LVM_FLOAT)CurrentR));
+ }
+ }
+
+ for (ii = InLoop * 2; ii != 0; ii-=2)
+ {
+ if(CurrentL < TargetL)
+ {
+ ADD2_SAT_FLOAT(CurrentL, DeltaL, Temp);
+ CurrentL = Temp;
+ if (CurrentL > TargetL)
+ CurrentL = TargetL;
+ }
+ else
+ {
+ CurrentL -= DeltaL;
+ if (CurrentL < TargetL)
+ CurrentL = TargetL;
+ }
+
+ if(CurrentR < TargetR)
+ {
+ ADD2_SAT_FLOAT(CurrentR, DeltaR, Temp);
+ CurrentR = Temp;
+ if (CurrentR > TargetR)
+ CurrentR = TargetR;
+ }
+ else
+ {
+ CurrentR -= DeltaR;
+ if (CurrentR < TargetR)
+ CurrentR = TargetR;
+ }
+
+ *(dst++) = (LVM_FLOAT)(((LVM_FLOAT)*(src++) * (LVM_FLOAT)CurrentL));
+ *(dst++) = (LVM_FLOAT)(((LVM_FLOAT)*(src++) * (LVM_FLOAT)CurrentR));
+ *(dst++) = (LVM_FLOAT)(((LVM_FLOAT)*(src++) * (LVM_FLOAT)CurrentL));
+ *(dst++) = (LVM_FLOAT)(((LVM_FLOAT)*(src++) * (LVM_FLOAT)CurrentR));
+ *(dst++) = (LVM_FLOAT)(((LVM_FLOAT)*(src++) * (LVM_FLOAT)CurrentL));
+ *(dst++) = (LVM_FLOAT)(((LVM_FLOAT)*(src++) * (LVM_FLOAT)CurrentR));
+ *(dst++) = (LVM_FLOAT)(((LVM_FLOAT)*(src++) * (LVM_FLOAT)CurrentL));
+ *(dst++) = (LVM_FLOAT)(((LVM_FLOAT)*(src++) * (LVM_FLOAT)CurrentR));
+ }
+ pInstanceL->Current = CurrentL;
+ pInstanceR->Current = CurrentR;
+
+}
+#else
void LVC_Core_MixSoft_1St_2i_D16C31_WRA( LVMixer3_st *ptrInstance1,
LVMixer3_st *ptrInstance2,
const LVM_INT16 *src,
@@ -140,4 +260,5 @@
pInstanceR->Current=CurrentR;
}
+#endif
/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixSoft_1St_D16C31_WRA.c b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixSoft_1St_D16C31_WRA.c
index f1a9ca3..b5e7f5c 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixSoft_1St_D16C31_WRA.c
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixSoft_1St_D16C31_WRA.c
@@ -26,7 +26,86 @@
/**********************************************************************************
FUNCTION LVCore_MIXSOFT_1ST_D16C31_WRA
***********************************************************************************/
+#ifdef BUILD_FLOAT
+void LVC_Core_MixSoft_1St_D16C31_WRA( LVMixer3_FLOAT_st *ptrInstance,
+ const LVM_FLOAT *src,
+ LVM_FLOAT *dst,
+ LVM_INT16 n)
+{
+ LVM_INT16 OutLoop;
+ LVM_INT16 InLoop;
+ LVM_INT32 ii;
+ Mix_Private_FLOAT_st *pInstance=(Mix_Private_FLOAT_st *)(ptrInstance->PrivateParams);
+ LVM_FLOAT Delta= (LVM_FLOAT)pInstance->Delta;
+ LVM_FLOAT Current = (LVM_FLOAT)pInstance->Current;
+ LVM_FLOAT Target= (LVM_FLOAT)pInstance->Target;
+ LVM_FLOAT Temp;
+ InLoop = (LVM_INT16)(n >> 2); /* Process per 4 samples */
+ OutLoop = (LVM_INT16)(n - (InLoop << 2));
+
+ if(Current<Target){
+ if (OutLoop){
+
+ Temp = Current + Delta;
+ if (Temp > 1.0f)
+ Temp = 1.0f;
+ else if (Temp < -1.0f)
+ Temp = -1.0f;
+
+ Current=Temp;
+ if (Current > Target)
+ Current = Target;
+
+ for (ii = OutLoop; ii != 0; ii--){
+ *(dst++) = (((LVM_FLOAT)*(src++) * (LVM_FLOAT)Current));
+ }
+ }
+
+ for (ii = InLoop; ii != 0; ii--){
+
+ Temp = Current + Delta;
+
+ if (Temp > 1.0f)
+ Temp = 1.0f;
+ else if (Temp < -1.0f)
+ Temp = -1.0f;
+
+ Current=Temp;
+ if (Current > Target)
+ Current = Target;
+
+ *(dst++) = (((LVM_FLOAT)*(src++) * Current) );
+ *(dst++) = (((LVM_FLOAT)*(src++) * Current) );
+ *(dst++) = (((LVM_FLOAT)*(src++) * Current) );
+ *(dst++) = (((LVM_FLOAT)*(src++) * Current) );
+ }
+ }
+ else{
+ if (OutLoop){
+ Current -= Delta;
+ if (Current < Target)
+ Current = Target;
+
+ for (ii = OutLoop; ii != 0; ii--){
+ *(dst++) = (((LVM_FLOAT)*(src++) * Current));
+ }
+ }
+
+ for (ii = InLoop; ii != 0; ii--){
+ Current -= Delta;
+ if (Current < Target)
+ Current = Target;
+
+ *(dst++) = (((LVM_FLOAT)*(src++) * Current));
+ *(dst++) = (((LVM_FLOAT)*(src++) * Current));
+ *(dst++) = (((LVM_FLOAT)*(src++) * Current));
+ *(dst++) = (((LVM_FLOAT)*(src++) * Current));
+ }
+ }
+ pInstance->Current=Current;
+}
+#else
void LVC_Core_MixSoft_1St_D16C31_WRA( LVMixer3_st *ptrInstance,
const LVM_INT16 *src,
LVM_INT16 *dst,
@@ -101,6 +180,5 @@
}
pInstance->Current=Current;
}
-
-
+#endif
/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_MixInSoft_D16C31_SAT.c b/media/libeffects/lvm/lib/Common/src/LVC_MixInSoft_D16C31_SAT.c
index 0052dd7..192f126 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_MixInSoft_D16C31_SAT.c
+++ b/media/libeffects/lvm/lib/Common/src/LVC_MixInSoft_D16C31_SAT.c
@@ -33,7 +33,80 @@
/**********************************************************************************
FUNCTION MIXINSOFT_D16C31_SAT
***********************************************************************************/
+#ifdef BUILD_FLOAT
+void LVC_MixInSoft_D16C31_SAT( LVMixer3_1St_FLOAT_st *ptrInstance,
+ LVM_FLOAT *src,
+ LVM_FLOAT *dst,
+ LVM_INT16 n)
+{
+ char HardMixing = TRUE;
+ LVM_FLOAT TargetGain;
+ Mix_Private_FLOAT_st *pInstance = \
+ (Mix_Private_FLOAT_st *)(ptrInstance->MixerStream[0].PrivateParams);
+ if(n <= 0) return;
+
+ /******************************************************************************
+ SOFT MIXING
+ *******************************************************************************/
+ if (pInstance->Current != pInstance->Target)
+ {
+ if(pInstance->Delta == 1.0f){
+ pInstance->Current = pInstance->Target;
+ TargetGain = pInstance->Target;
+ LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[0]), TargetGain);
+ }else if (Abs_Float(pInstance->Current - pInstance->Target) < pInstance->Delta){
+ pInstance->Current = pInstance->Target; /* Difference is not significant anymore. \
+ Make them equal. */
+ TargetGain = pInstance->Target;
+ LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[0]), TargetGain);
+ }else{
+ /* Soft mixing has to be applied */
+ HardMixing = FALSE;
+ LVC_Core_MixInSoft_D16C31_SAT(&(ptrInstance->MixerStream[0]), src, dst, n);
+ }
+ }
+
+ /******************************************************************************
+ HARD MIXING
+ *******************************************************************************/
+
+ if (HardMixing){
+ if (pInstance->Target != 0){ /* Nothing to do in case Target = 0 */
+ if ((pInstance->Target) == 1.0f){
+ Add2_Sat_Float(src, dst, n);
+ }
+ else{
+ Mac3s_Sat_Float(src, (pInstance->Target), dst, n);
+ /* In case the LVCore function would have changed the Current value */
+ pInstance->Current = pInstance->Target;
+ }
+ }
+ }
+
+
+ /******************************************************************************
+ CALL BACK
+ *******************************************************************************/
+
+ if (ptrInstance->MixerStream[0].CallbackSet){
+ if (Abs_Float(pInstance->Current - pInstance->Target) < pInstance->Delta){
+ pInstance->Current = pInstance->Target; /* Difference is not significant anymore. \
+ Make them equal. */
+ TargetGain = pInstance->Target;
+ LVC_Mixer_SetTarget(ptrInstance->MixerStream, TargetGain);
+ ptrInstance->MixerStream[0].CallbackSet = FALSE;
+ if (ptrInstance->MixerStream[0].pCallBack != 0){
+ (*ptrInstance->MixerStream[0].pCallBack) ( \
+ ptrInstance->MixerStream[0].pCallbackHandle,
+ ptrInstance->MixerStream[0].pGeneralPurpose,
+ ptrInstance->MixerStream[0].CallbackParam );
+ }
+ }
+ }
+
+}
+#else
void LVC_MixInSoft_D16C31_SAT( LVMixer3_1St_st *ptrInstance,
LVM_INT16 *src,
LVM_INT16 *dst,
@@ -108,5 +181,5 @@
}
}
-
+#endif
/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_1St_2i_D16C31_SAT.c b/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_1St_2i_D16C31_SAT.c
index f443c8f..bd5a925 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_1St_2i_D16C31_SAT.c
+++ b/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_1St_2i_D16C31_SAT.c
@@ -33,7 +33,138 @@
/**********************************************************************************
FUNCTION LVC_MixSoft_1St_2i_D16C31_SAT
***********************************************************************************/
+#ifdef BUILD_FLOAT
+void LVC_MixSoft_1St_2i_D16C31_SAT( LVMixer3_2St_FLOAT_st *ptrInstance,
+ const LVM_FLOAT *src,
+ LVM_FLOAT *dst,
+ LVM_INT16 n)
+{
+ char HardMixing = TRUE;
+ LVM_FLOAT TargetGain;
+ Mix_Private_FLOAT_st *pInstance1 = \
+ (Mix_Private_FLOAT_st *)(ptrInstance->MixerStream[0].PrivateParams);
+ Mix_Private_FLOAT_st *pInstance2 = \
+ (Mix_Private_FLOAT_st *)(ptrInstance->MixerStream[1].PrivateParams);
+ if(n <= 0) return;
+
+ /******************************************************************************
+ SOFT MIXING
+ *******************************************************************************/
+ if ((pInstance1->Current != pInstance1->Target) || (pInstance2->Current != pInstance2->Target))
+ {
+ if(pInstance1->Delta == 1.0f)
+ {
+ pInstance1->Current = pInstance1->Target;
+ TargetGain = pInstance1->Target;
+ LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[0]), TargetGain);
+ }
+ else if (Abs_Float(pInstance1->Current - pInstance1->Target) < pInstance1->Delta)
+ {
+ pInstance1->Current = pInstance1->Target; /* Difference is not significant anymore. \
+ Make them equal. */
+ TargetGain = pInstance1->Target;
+ LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[0]), TargetGain);
+ }
+ else
+ {
+ /* Soft mixing has to be applied */
+ HardMixing = FALSE;
+ }
+
+ if(HardMixing == TRUE)
+ {
+ if(pInstance2->Delta == 1.0f)
+ {
+ pInstance2->Current = pInstance2->Target;
+ TargetGain = pInstance2->Target;
+ LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[1]), TargetGain);
+ }
+ else if (Abs_Float(pInstance2->Current - pInstance2->Target) < pInstance2->Delta)
+ {
+ pInstance2->Current = pInstance2->Target; /* Difference is not significant anymore. \
+ Make them equal. */
+ TargetGain = pInstance2->Target;
+ LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[1]), TargetGain);
+ }
+ else
+ {
+ /* Soft mixing has to be applied */
+ HardMixing = FALSE;
+ }
+ }
+
+ if(HardMixing == FALSE)
+ {
+ LVC_Core_MixSoft_1St_2i_D16C31_WRA( &(ptrInstance->MixerStream[0]),
+ &(ptrInstance->MixerStream[1]),
+ src, dst, n);
+ }
+ }
+
+ /******************************************************************************
+ HARD MIXING
+ *******************************************************************************/
+
+ if (HardMixing)
+ {
+ if ((pInstance1->Target == 1.0f) && (pInstance2->Target == 1.0f))
+ {
+ if(src != dst)
+ {
+ Copy_Float(src, dst, n);
+ }
+ }
+ else
+ {
+ LVC_Core_MixHard_1St_2i_D16C31_SAT(&(ptrInstance->MixerStream[0]),
+ &(ptrInstance->MixerStream[1]),
+ src, dst, n);
+ }
+ }
+
+ /******************************************************************************
+ CALL BACK
+ *******************************************************************************/
+
+ if (ptrInstance->MixerStream[0].CallbackSet)
+ {
+ if (Abs_Float(pInstance1->Current - pInstance1->Target) < pInstance1->Delta)
+ {
+ pInstance1->Current = pInstance1->Target; /* Difference is not significant anymore. \
+ Make them equal. */
+ TargetGain = pInstance1->Target;
+ LVC_Mixer_SetTarget(&ptrInstance->MixerStream[0], TargetGain);
+ ptrInstance->MixerStream[0].CallbackSet = FALSE;
+ if (ptrInstance->MixerStream[0].pCallBack != 0)
+ {
+ (*ptrInstance->MixerStream[0].pCallBack) ( \
+ ptrInstance->MixerStream[0].pCallbackHandle,
+ ptrInstance->MixerStream[0].pGeneralPurpose,
+ ptrInstance->MixerStream[0].CallbackParam );
+ }
+ }
+ }
+ if (ptrInstance->MixerStream[1].CallbackSet)
+ {
+ if (Abs_Float(pInstance2->Current - pInstance2->Target) < pInstance2->Delta)
+ {
+ pInstance2->Current = pInstance2->Target; /* Difference is not significant anymore.
+ Make them equal. */
+ TargetGain = pInstance2->Target;
+ LVC_Mixer_SetTarget(&ptrInstance->MixerStream[1], TargetGain);
+ ptrInstance->MixerStream[1].CallbackSet = FALSE;
+ if (ptrInstance->MixerStream[1].pCallBack != 0)
+ {
+ (*ptrInstance->MixerStream[1].pCallBack) (
+ ptrInstance->MixerStream[1].pCallbackHandle,
+ ptrInstance->MixerStream[1].pGeneralPurpose,
+ ptrInstance->MixerStream[1].CallbackParam );
+ }
+ }
+ }
+}
+#else
void LVC_MixSoft_1St_2i_D16C31_SAT( LVMixer3_2St_st *ptrInstance,
const LVM_INT16 *src,
LVM_INT16 *dst,
@@ -148,5 +279,5 @@
}
}
}
-
+#endif
/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_1St_D16C31_SAT.c b/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_1St_D16C31_SAT.c
index c8dcad7..1017de3 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_1St_D16C31_SAT.c
+++ b/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_1St_D16C31_SAT.c
@@ -33,7 +33,77 @@
/**********************************************************************************
FUNCTION LVMixer3_MIXSOFT_1ST_D16C31_SAT
***********************************************************************************/
+#ifdef BUILD_FLOAT
+void LVC_MixSoft_1St_D16C31_SAT( LVMixer3_1St_FLOAT_st *ptrInstance,
+ const LVM_FLOAT *src,
+ LVM_FLOAT *dst,
+ LVM_INT16 n)
+{
+ char HardMixing = TRUE;
+ LVM_FLOAT TargetGain;
+ Mix_Private_FLOAT_st *pInstance = \
+ (Mix_Private_FLOAT_st *)(ptrInstance->MixerStream[0].PrivateParams);
+ if(n <= 0) return;
+
+ /******************************************************************************
+ SOFT MIXING
+ *******************************************************************************/
+ if (pInstance->Current != pInstance->Target)
+ {
+ if(pInstance->Delta == 1.0f){
+ pInstance->Current = pInstance->Target;
+ TargetGain = pInstance->Target;
+ LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[0]), TargetGain);
+ }else if (Abs_Float(pInstance->Current - pInstance->Target) < pInstance->Delta){
+ pInstance->Current = pInstance->Target; /* Difference is not significant anymore. \
+ Make them equal. */
+ TargetGain = pInstance->Target;
+ LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[0]), TargetGain);
+ }else{
+ /* Soft mixing has to be applied */
+ HardMixing = FALSE;
+ LVC_Core_MixSoft_1St_D16C31_WRA(&(ptrInstance->MixerStream[0]), src, dst, n);
+ }
+ }
+
+ /******************************************************************************
+ HARD MIXING
+ *******************************************************************************/
+
+ if (HardMixing){
+ if (pInstance->Target == 0)
+ LoadConst_Float(0.0, dst, n);
+ else {
+ if ((pInstance->Target) != 1.0f)
+ Mult3s_Float(src, (pInstance->Target), dst, n);
+ else if(src != dst)
+ Copy_Float(src, dst, n);
+ }
+
+ }
+
+ /******************************************************************************
+ CALL BACK
+ *******************************************************************************/
+
+ if (ptrInstance->MixerStream[0].CallbackSet){
+ if (Abs_Float(pInstance->Current - pInstance->Target) < pInstance->Delta){
+ pInstance->Current = pInstance->Target; /* Difference is not significant anymore. \
+ Make them equal. */
+ TargetGain = pInstance->Target;
+ LVC_Mixer_SetTarget(ptrInstance->MixerStream, TargetGain);
+ ptrInstance->MixerStream[0].CallbackSet = FALSE;
+ if (ptrInstance->MixerStream[0].pCallBack != 0){
+ (*ptrInstance->MixerStream[0].pCallBack) ( \
+ ptrInstance->MixerStream[0].pCallbackHandle,
+ ptrInstance->MixerStream[0].pGeneralPurpose,
+ ptrInstance->MixerStream[0].CallbackParam );
+ }
+ }
+ }
+}
+#else
void LVC_MixSoft_1St_D16C31_SAT( LVMixer3_1St_st *ptrInstance,
const LVM_INT16 *src,
LVM_INT16 *dst,
@@ -107,5 +177,5 @@
}
}
}
-
+#endif/*BUILD_FLOAT*/
/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_2St_D16C31_SAT.c b/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_2St_D16C31_SAT.c
index 7240705..3c90071 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_2St_D16C31_SAT.c
+++ b/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_2St_D16C31_SAT.c
@@ -25,7 +25,49 @@
/**********************************************************************************
FUNCTION LVC_MixSoft_2St_D16C31_SAT.c
***********************************************************************************/
+#ifdef BUILD_FLOAT
+void LVC_MixSoft_2St_D16C31_SAT( LVMixer3_2St_FLOAT_st *ptrInstance,
+ const LVM_FLOAT *src1,
+ LVM_FLOAT *src2,
+ LVM_FLOAT *dst,
+ LVM_INT16 n)
+{
+ Mix_Private_FLOAT_st *pInstance1 = \
+ (Mix_Private_FLOAT_st *)(ptrInstance->MixerStream[0].PrivateParams);
+ Mix_Private_FLOAT_st *pInstance2 = \
+ (Mix_Private_FLOAT_st *)(ptrInstance->MixerStream[1].PrivateParams);
+ if(n <= 0) return;
+
+ /******************************************************************************
+ SOFT MIXING
+ *******************************************************************************/
+ if ((pInstance1->Current == pInstance1->Target) && (pInstance1->Current == 0)){
+ LVC_MixSoft_1St_D16C31_SAT((LVMixer3_1St_FLOAT_st *)(&ptrInstance->MixerStream[1]),
+ src2, dst, n);
+ }
+ else if ((pInstance2->Current == pInstance2->Target) && (pInstance2->Current == 0)){
+ LVC_MixSoft_1St_D16C31_SAT((LVMixer3_1St_FLOAT_st *)(&ptrInstance->MixerStream[0]),
+ src1, dst, n);
+ }
+ else if ((pInstance1->Current != pInstance1->Target) || \
+ (pInstance2->Current != pInstance2->Target))
+ {
+ LVC_MixSoft_1St_D16C31_SAT((LVMixer3_1St_FLOAT_st *)(&ptrInstance->MixerStream[0]),
+ src1, dst, n);
+ LVC_MixInSoft_D16C31_SAT((LVMixer3_1St_FLOAT_st *)(&ptrInstance->MixerStream[1]),
+ src2, dst, n);
+ }
+ else{
+ /******************************************************************************
+ HARD MIXING
+ *******************************************************************************/
+ LVC_Core_MixHard_2St_D16C31_SAT( &ptrInstance->MixerStream[0],
+ &ptrInstance->MixerStream[1],
+ src1, src2, dst, n);
+ }
+}
+#else
void LVC_MixSoft_2St_D16C31_SAT( LVMixer3_2St_st *ptrInstance,
const LVM_INT16 *src1,
LVM_INT16 *src2,
@@ -66,5 +108,5 @@
LVC_Core_MixHard_2St_D16C31_SAT( &ptrInstance->MixerStream[0], &ptrInstance->MixerStream[1], src1, src2, dst, n);
}
}
-
+#endif /*BUILD_FLOAT*/
/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Mixer.h b/media/libeffects/lvm/lib/Common/src/LVC_Mixer.h
index 980c783..f904915 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_Mixer.h
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Mixer.h
@@ -31,6 +31,19 @@
***********************************************************************************/
/* LVMixer3_st structure stores Instance parameters for one audio stream */
+#ifdef BUILD_FLOAT
+typedef struct
+{
+ LVM_FLOAT PrivateParams[3]; /* Private Instance params for \
+ Audio Stream shift parameter */
+ LVM_INT16 CallbackSet; /* Boolean. Should be set by calling application \
+ each time the target value is updated */
+ LVM_INT16 CallbackParam; /* Parameter that will be used in the calback function */
+ void *pCallbackHandle; /* Pointer to the instance of the callback function */
+ void *pGeneralPurpose; /* Pointer for general purpose usage */
+ LVM_Callback pCallBack; /* Pointer to the callback function */
+} LVMixer3_FLOAT_st;
+#else
typedef struct
{
LVM_INT32 PrivateParams[4]; /* Private Instance params for Audio Stream */
@@ -40,22 +53,35 @@
void *pGeneralPurpose; /* Pointer for general purpose usage */
LVM_Callback pCallBack; /* Pointer to the callback function */
} LVMixer3_st;
-
+#endif
+#ifdef BUILD_FLOAT
+typedef struct
+{
+ LVMixer3_FLOAT_st MixerStream[1]; /* Instance Params for one Audio Stream */
+} LVMixer3_1St_FLOAT_st;
+#else
typedef struct
{
LVMixer3_st MixerStream[1]; /* Instance Params for one Audio Stream */
} LVMixer3_1St_st;
-
+#endif
+#ifdef BUILD_FLOAT
+typedef struct
+{
+ LVMixer3_FLOAT_st MixerStream[2]; /* Instance Params for two Audio Streams */
+} LVMixer3_2St_FLOAT_st;
+#else
typedef struct
{
LVMixer3_st MixerStream[2]; /* Instance Params for two Audio Streams */
} LVMixer3_2St_st;
-
+#endif
+#ifndef BUILD_FLOAT
typedef struct
{
LVMixer3_st MixerStream[3]; /* Instance Params for three Audio Streams */
} LVMixer3_3St_st;
-
+#endif
/**********************************************************************************
FUNCTION PROTOTYPES (HIGH LEVEL FUNCTIONS)
***********************************************************************************/
@@ -75,57 +101,115 @@
/* then the calculation will give an incorrect value for alpha, see the mixer */
/* documentation for further details. */
/* ********************************************************************************/
+#ifdef BUILD_FLOAT
+void LVC_Mixer_SetTarget( LVMixer3_FLOAT_st *pStream,
+ LVM_FLOAT TargetGain);
+#else
void LVC_Mixer_SetTarget( LVMixer3_st *pStream,
LVM_INT32 TargetGain);
-
+#endif
+#ifdef BUILD_FLOAT
+LVM_FLOAT LVC_Mixer_GetTarget( LVMixer3_FLOAT_st *pStream);
+#else
LVM_INT32 LVC_Mixer_GetTarget( LVMixer3_st *pStream);
+#endif
+#ifdef BUILD_FLOAT
+LVM_FLOAT LVC_Mixer_GetCurrent( LVMixer3_FLOAT_st *pStream);
+#else
LVM_INT32 LVC_Mixer_GetCurrent( LVMixer3_st *pStream);
+#endif
+#ifdef BUILD_FLOAT
+void LVC_Mixer_Init( LVMixer3_FLOAT_st *pStream,
+ LVM_FLOAT TargetGain,
+ LVM_FLOAT CurrentGain);
+#else
void LVC_Mixer_Init( LVMixer3_st *pStream,
LVM_INT32 TargetGain,
LVM_INT32 CurrentGain);
+#endif
+#ifdef BUILD_FLOAT
+void LVC_Mixer_SetTimeConstant( LVMixer3_FLOAT_st *pStream,
+ LVM_INT32 Tc_millisec,
+ LVM_Fs_en Fs,
+ LVM_INT16 NumChannels);
+#else
void LVC_Mixer_SetTimeConstant( LVMixer3_st *pStream,
LVM_INT32 Tc_millisec,
LVM_Fs_en Fs,
LVM_INT16 NumChannels);
+#endif
+#ifdef BUILD_FLOAT
+void LVC_Mixer_VarSlope_SetTimeConstant( LVMixer3_FLOAT_st *pStream,
+ LVM_INT32 Tc_millisec,
+ LVM_Fs_en Fs,
+ LVM_INT16 NumChannels);
+#else
void LVC_Mixer_VarSlope_SetTimeConstant( LVMixer3_st *pStream,
LVM_INT32 Tc_millisec,
LVM_Fs_en Fs,
LVM_INT16 NumChannels);
+#endif
/*** 16 bit functions *************************************************************/
+#ifdef BUILD_FLOAT
+void LVC_MixSoft_1St_D16C31_SAT( LVMixer3_1St_FLOAT_st *pInstance,
+ const LVM_FLOAT *src,
+ LVM_FLOAT *dst,
+ LVM_INT16 n);
+#else
void LVC_MixSoft_1St_D16C31_SAT( LVMixer3_1St_st *pInstance,
const LVM_INT16 *src,
LVM_INT16 *dst,
LVM_INT16 n);
+#endif
+#ifdef BUILD_FLOAT
+void LVC_MixInSoft_D16C31_SAT( LVMixer3_1St_FLOAT_st *pInstance,
+ LVM_FLOAT *src,
+ LVM_FLOAT *dst,
+ LVM_INT16 n);
+#else
void LVC_MixInSoft_D16C31_SAT( LVMixer3_1St_st *pInstance,
LVM_INT16 *src,
LVM_INT16 *dst,
LVM_INT16 n);
+#endif
+#ifdef BUILD_FLOAT
+void LVC_MixSoft_2St_D16C31_SAT( LVMixer3_2St_FLOAT_st *pInstance,
+ const LVM_FLOAT *src1,
+ LVM_FLOAT *src2,
+ LVM_FLOAT *dst, /* dst cannot be equal to src2 */
+ LVM_INT16 n);
+#else
void LVC_MixSoft_2St_D16C31_SAT( LVMixer3_2St_st *pInstance,
const LVM_INT16 *src1,
LVM_INT16 *src2,
LVM_INT16 *dst, /* dst cannot be equal to src2 */
LVM_INT16 n);
-
+#endif
/**********************************************************************************/
/* For applying different gains to Left and right chennals */
/* MixerStream[0] applies to Left channel */
/* MixerStream[1] applies to Right channel */
/* Gain values should not be more that 1.0 */
/**********************************************************************************/
+#ifdef BUILD_FLOAT
+void LVC_MixSoft_1St_2i_D16C31_SAT( LVMixer3_2St_FLOAT_st *pInstance,
+ const LVM_FLOAT *src,
+ LVM_FLOAT *dst, /* dst can be equal to src */
+ LVM_INT16 n); /* Number of stereo samples */
+#else
void LVC_MixSoft_1St_2i_D16C31_SAT( LVMixer3_2St_st *pInstance,
const LVM_INT16 *src,
LVM_INT16 *dst, /* dst can be equal to src */
LVM_INT16 n); /* Number of stereo samples */
-
-
+#endif
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Mixer_GetCurrent.c b/media/libeffects/lvm/lib/Common/src/LVC_Mixer_GetCurrent.c
index b5ae264..5990412 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_Mixer_GetCurrent.c
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Mixer_GetCurrent.c
@@ -31,7 +31,15 @@
/* CurrentGain - CurrentGain value in Q 16.15 format */
/* */
/************************************************************************/
-
+#ifdef BUILD_FLOAT
+LVM_FLOAT LVC_Mixer_GetCurrent( LVMixer3_FLOAT_st *pStream)
+{
+ LVM_FLOAT CurrentGain;
+ Mix_Private_FLOAT_st *pInstance = (Mix_Private_FLOAT_st *)pStream->PrivateParams;
+ CurrentGain = pInstance->Current; // CurrentGain
+ return CurrentGain;
+}
+#else
LVM_INT32 LVC_Mixer_GetCurrent( LVMixer3_st *pStream)
{
LVM_INT32 CurrentGain;
@@ -39,3 +47,4 @@
CurrentGain=pInstance->Current>>(16-pInstance->Shift); // CurrentGain in Q16.15 format
return CurrentGain;
}
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Mixer_GetTarget.c b/media/libeffects/lvm/lib/Common/src/LVC_Mixer_GetTarget.c
index dc2f8e9..c67455a 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_Mixer_GetTarget.c
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Mixer_GetTarget.c
@@ -30,7 +30,16 @@
/* TargetGain - TargetGain value in Q 16.15 format */
/* */
/************************************************************************/
-
+#ifdef BUILD_FLOAT
+LVM_FLOAT LVC_Mixer_GetTarget( LVMixer3_FLOAT_st *pStream)
+{
+ LVM_FLOAT TargetGain;
+ Mix_Private_FLOAT_st *pInstance = (Mix_Private_FLOAT_st *)pStream->PrivateParams;
+
+ TargetGain = pInstance->Target; // TargetGain
+ return TargetGain;
+}
+#else
LVM_INT32 LVC_Mixer_GetTarget( LVMixer3_st *pStream)
{
LVM_INT32 TargetGain;
@@ -40,3 +49,4 @@
return TargetGain;
}
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Mixer_Init.c b/media/libeffects/lvm/lib/Common/src/LVC_Mixer_Init.c
index 449e7b1..737e26b 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_Mixer_Init.c
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Mixer_Init.c
@@ -44,7 +44,19 @@
/* void */
/* */
/************************************************************************/
-
+#ifdef BUILD_FLOAT
+void LVC_Mixer_Init( LVMixer3_FLOAT_st *pStream,
+ LVM_FLOAT TargetGain,
+ LVM_FLOAT CurrentGain)
+{
+ LVM_FLOAT MaxGain = TargetGain;
+ Mix_Private_FLOAT_st *pInstance = (Mix_Private_FLOAT_st *)pStream->PrivateParams;
+ if(CurrentGain > MaxGain)
+ MaxGain = CurrentGain;
+ pInstance->Target = TargetGain; // Update fractional gain Target
+ pInstance->Current = CurrentGain; // Update fractional gain Current
+}
+#else
void LVC_Mixer_Init( LVMixer3_st *pStream,
LVM_INT32 TargetGain,
LVM_INT32 CurrentGain)
@@ -64,4 +76,4 @@
pInstance->Current=CurrentGain<<(16-Shift); // Update fractional gain Current
pInstance->Shift=Shift; // Update Shift
}
-
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Mixer_Private.h b/media/libeffects/lvm/lib/Common/src/LVC_Mixer_Private.h
index 294e05c..d0d0e1f 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_Mixer_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Mixer_Private.h
@@ -26,6 +26,15 @@
#include "VectorArithmetic.h"
/* Instance parameter structure */
+#ifdef BUILD_FLOAT
+typedef struct
+{
+ /* General */
+ LVM_FLOAT Target; /*number specifying value of Target Gain */
+ LVM_FLOAT Current; /*number specifying value of Current Gain */
+ LVM_FLOAT Delta; /*number specifying value of Delta Gain */
+} Mix_Private_FLOAT_st;
+#else
typedef struct
{
/* General */
@@ -34,8 +43,7 @@
LVM_INT32 Shift; /* Left Shift for Integer part of Gain */
LVM_INT32 Delta; /* 32 bit number specifying the fractional value of Delta Gain */
} Mix_Private_st;
-
-
+#endif
/**********************************************************************************
DEFINITIONS
@@ -49,23 +57,43 @@
***********************************************************************************/
/*** 16 bit functions *************************************************************/
-
+#ifdef BUILD_FLOAT
+void LVC_Core_MixInSoft_D16C31_SAT( LVMixer3_FLOAT_st *ptrInstance,
+ const LVM_FLOAT *src,
+ LVM_FLOAT *dst,
+ LVM_INT16 n);
+#else
void LVC_Core_MixInSoft_D16C31_SAT( LVMixer3_st *pInstance,
const LVM_INT16 *src,
LVM_INT16 *dst,
LVM_INT16 n);
-
+#endif
+#ifdef BUILD_FLOAT
+void LVC_Core_MixSoft_1St_D16C31_WRA( LVMixer3_FLOAT_st *ptrInstance,
+ const LVM_FLOAT *src,
+ LVM_FLOAT *dst,
+ LVM_INT16 n);
+#else
void LVC_Core_MixSoft_1St_D16C31_WRA( LVMixer3_st *pInstance,
const LVM_INT16 *src,
LVM_INT16 *dst,
LVM_INT16 n);
-
+#endif
+#ifdef BUILD_FLOAT
+void LVC_Core_MixHard_2St_D16C31_SAT( LVMixer3_FLOAT_st *pInstance1,
+ LVMixer3_FLOAT_st *pInstance2,
+ const LVM_FLOAT *src1,
+ const LVM_FLOAT *src2,
+ LVM_FLOAT *dst,
+ LVM_INT16 n);
+#else
void LVC_Core_MixHard_2St_D16C31_SAT( LVMixer3_st *pInstance1,
LVMixer3_st *pInstance2,
const LVM_INT16 *src1,
const LVM_INT16 *src2,
LVM_INT16 *dst,
LVM_INT16 n);
+#endif
/**********************************************************************************/
/* For applying different gains to Left and right chennals */
@@ -73,12 +101,19 @@
/* ptrInstance2 applies to Right channel */
/* Gain values should not be more that 1.0 */
/**********************************************************************************/
-
+#ifdef BUILD_FLOAT
+void LVC_Core_MixSoft_1St_2i_D16C31_WRA( LVMixer3_FLOAT_st *ptrInstance1,
+ LVMixer3_FLOAT_st *ptrInstance2,
+ const LVM_FLOAT *src,
+ LVM_FLOAT *dst,
+ LVM_INT16 n);
+#else
void LVC_Core_MixSoft_1St_2i_D16C31_WRA( LVMixer3_st *ptrInstance1,
LVMixer3_st *ptrInstance2,
const LVM_INT16 *src,
LVM_INT16 *dst, /* dst can be equal to src */
LVM_INT16 n); /* Number of stereo samples */
+#endif
/**********************************************************************************/
/* For applying different gains to Left and right chennals */
@@ -86,16 +121,22 @@
/* ptrInstance2 applies to Right channel */
/* Gain values should not be more that 1.0 */
/**********************************************************************************/
+#ifdef BUILD_FLOAT
+void LVC_Core_MixHard_1St_2i_D16C31_SAT( LVMixer3_FLOAT_st *ptrInstance1,
+ LVMixer3_FLOAT_st *ptrInstance2,
+ const LVM_FLOAT *src,
+ LVM_FLOAT *dst,
+ LVM_INT16 n);
+#else
void LVC_Core_MixHard_1St_2i_D16C31_SAT( LVMixer3_st *ptrInstance1,
LVMixer3_st *ptrInstance2,
const LVM_INT16 *src,
LVM_INT16 *dst, /* dst can be equal to src */
LVM_INT16 n); /* Number of stereo samples */
-
-
+#endif
/*** 32 bit functions *************************************************************/
-
+#ifndef BUILD_FLOAT
void LVC_Core_MixInSoft_D32C31_SAT( LVMixer3_st *pInstance,
const LVM_INT32 *src,
LVM_INT32 *dst,
@@ -112,7 +153,7 @@
const LVM_INT32 *src2,
LVM_INT32 *dst,
LVM_INT16 n);
-
+#endif
/**********************************************************************************/
#endif //#ifndef __LVC_MIXER_PRIVATE_H__
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Mixer_SetTarget.c b/media/libeffects/lvm/lib/Common/src/LVC_Mixer_SetTarget.c
index 5efa501..577179d 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_Mixer_SetTarget.c
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Mixer_SetTarget.c
@@ -43,7 +43,14 @@
/* void */
/* */
/************************************************************************/
-
+#ifdef BUILD_FLOAT
+void LVC_Mixer_SetTarget(LVMixer3_FLOAT_st *pStream,
+ LVM_FLOAT TargetGain)
+{
+ Mix_Private_FLOAT_st *pInstance = (Mix_Private_FLOAT_st *)pStream->PrivateParams;
+ pInstance->Target = TargetGain; // Update gain Target
+}
+#else
void LVC_Mixer_SetTarget(LVMixer3_st *pStream,
LVM_INT32 TargetGain)
{
@@ -64,3 +71,4 @@
pInstance->Current=CurrentGain<<(16-Shift); // Update fractional gain Current
pInstance->Shift=Shift; // Update Shift
}
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Mixer_SetTimeConstant.c b/media/libeffects/lvm/lib/Common/src/LVC_Mixer_SetTimeConstant.c
index 4c1c8b2..48f5d54 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_Mixer_SetTimeConstant.c
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Mixer_SetTimeConstant.c
@@ -44,7 +44,51 @@
/* RETURNS: */
/* void */
/************************************************************************/
+#ifdef BUILD_FLOAT
+void LVC_Mixer_SetTimeConstant(LVMixer3_FLOAT_st *pStream,
+ LVM_INT32 Tc_millisec,
+ LVM_Fs_en Fs,
+ LVM_INT16 NumChannels)
+{
+#ifdef HIGHER_FS
+ LVM_FLOAT DeltaTable[11] = {0.500000f,/*8000*/
+ 0.362812f,/*11025*/
+ 0.333333f,/*12000*/
+ 0.250000f,/*16000*/
+ 0.181406f,/*22050*/
+ 0.166666f,/*24000*/
+ 0.125000f,/*32000*/
+ 0.090703f,/*44100*/
+ 0.083333f,/*48000*/
+ 0.041667f,/*96000*/
+ 0.020833f};/*192000*/
+#else
+ LVM_FLOAT DeltaTable[9] = {0.500000f,/*8000*/
+ 0.362812f,/*11025*/
+ 0.333333f,/*12000*/
+ 0.250000f,/*16000*/
+ 0.181406f,/*22050*/
+ 0.166666f,/*24000*/
+ 0.125000f,/*32000*/
+ 0.090703f,/*44100*/
+ 0.083333f};/*48000*/
+#endif
+ Mix_Private_FLOAT_st *pInstance = (Mix_Private_FLOAT_st *)pStream->PrivateParams;
+ LVM_FLOAT Delta = DeltaTable[Fs];
+ Delta = Delta / (NumChannels);
+
+ if(Tc_millisec == 0)
+ Delta = 1.000000f;
+ else
+ Delta = Delta / Tc_millisec;
+
+ if(Delta == 0)
+ Delta = 0.0000000005f; /* If Time Constant is so large that Delta is 0, \
+ assign minimum value to Delta */
+ pInstance->Delta = Delta; // Delta=(2147483647*4*1000)/(NumChannels*SampleRate*Tc_millisec)
+}
+#else
void LVC_Mixer_SetTimeConstant(LVMixer3_st *pStream,
LVM_INT32 Tc_millisec,
LVM_Fs_en Fs,
@@ -73,3 +117,4 @@
pInstance->Delta=Delta; // Delta=(2147483647*4*1000)/(NumChannels*SampleRate*Tc_millisec) in Q 0.31 format
}
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Mixer_VarSlope_SetTimeConstant.c b/media/libeffects/lvm/lib/Common/src/LVC_Mixer_VarSlope_SetTimeConstant.c
index 8d5304e..9dc7d21 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_Mixer_VarSlope_SetTimeConstant.c
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Mixer_VarSlope_SetTimeConstant.c
@@ -45,7 +45,72 @@
/* RETURNS: */
/* void */
/************************************************************************/
+#ifdef BUILD_FLOAT
+void LVC_Mixer_VarSlope_SetTimeConstant( LVMixer3_FLOAT_st *pStream,
+ LVM_INT32 Tc_millisec,
+ LVM_Fs_en Fs,
+ LVM_INT16 NumChannels)
+{
+#ifdef HIGHER_FS
+ LVM_FLOAT DeltaTable[11] = {0.500000f,/*8000*/
+ 0.362812f,/*11025*/
+ 0.333333f,/*12000*/
+ 0.250000f,/*16000*/
+ 0.181406f,/*22050*/
+ 0.166666f,/*24000*/
+ 0.125000f,/*32000*/
+ 0.090703f,/*44100*/
+ 0.083333f,/*48000*/
+ 0.041666f,/*96000*/
+ 0.020833f};/*192000*/
+#else
+ LVM_FLOAT DeltaTable[9] = {0.500000f,/*8000*/
+ 0.362812f,/*11025*/
+ 0.333333f,/*12000*/
+ 0.250000f,/*16000*/
+ 0.181406f,/*22050*/
+ 0.166666f,/*24000*/
+ 0.125000f,/*32000*/
+ 0.090703f,/*44100*/
+ 0.083333f};/*48000*/
+#endif
+ LVM_FLOAT Tc_millisec_float;
+ Mix_Private_FLOAT_st *pInstance = (Mix_Private_FLOAT_st *)pStream->PrivateParams;
+ LVM_FLOAT Delta = DeltaTable[Fs];
+ LVM_FLOAT Current;
+ LVM_FLOAT Target;
+
+ Delta=Delta / (NumChannels);
+
+ /* Get gain values */
+ Current = pInstance->Current;
+ Target = pInstance->Target;
+
+ if (Current != Target)
+ {
+ Tc_millisec_float = (LVM_FLOAT)(Tc_millisec) / (Current - Target);
+ if (Tc_millisec_float < 0)
+ Tc_millisec_float = -Tc_millisec_float;
+
+ if(Tc_millisec == 0)
+ Delta = 1.000000f;
+ else
+ Delta = Delta / Tc_millisec_float;
+
+ if(Delta == 0)
+ Delta = 0.0000000005f; /* If Time Constant is so large that Delta is 0, \
+ assign minimum value to Delta */
+ }
+ else
+ {
+ Delta = 0.0000000005f; /* Minimum value for proper call-backs \
+ (setting it to zero has some problems, to be corrected) */
+ }
+
+ pInstance->Delta = Delta; // Delta=(2147483647*4*1000)/(NumChannels*SampleRate*Tc_millisec)
+}
+#else
void LVC_Mixer_VarSlope_SetTimeConstant( LVMixer3_st *pStream,
LVM_INT32 Tc_millisec,
LVM_Fs_en Fs,
@@ -93,3 +158,4 @@
pInstance->Delta=Delta; // Delta=(2147483647*4*1000)/(NumChannels*SampleRate*Tc_millisec) in Q 0.31 format
}
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/LVM_FO_HPF.c b/media/libeffects/lvm/lib/Common/src/LVM_FO_HPF.c
index 6d8fe46..9094622 100644
--- a/media/libeffects/lvm/lib/Common/src/LVM_FO_HPF.c
+++ b/media/libeffects/lvm/lib/Common/src/LVM_FO_HPF.c
@@ -53,7 +53,7 @@
/* A9 194669577 */
/* A10 8 */
/* */
-/* Y = (A0 + A1*X + A2*X2 + A3*X3 + Â….. + AN*xN) << AN+1 */
+/* Y = (A0 + A1*X + A2*X2 + A3*X3 + �.. + AN*xN) << AN+1 */
/* */
/* */
/* PARAMETERS: */
@@ -68,7 +68,36 @@
/* RETURNS: */
/* */
/*-------------------------------------------------------------------------*/
+#ifdef BUILD_FLOAT
+LVM_FLOAT LVM_FO_HPF( LVM_FLOAT w,
+ FO_FLOAT_Coefs_t *pCoeffs)
+{
+ LVM_FLOAT Y,Coefficients[13] = {-0.999996f,
+ 0.999801f,
+ -0.497824f,
+ 0.322937f,
+ -0.180880f,
+ 0.087658f,
+ -0.032102f,
+ 0.008163f,
+ -0.001252f,
+ 0.000089f,
+ 0,
+ 0,
+ 0};
+ Y=LVM_Polynomial((LVM_UINT16)9, Coefficients, w);
+ pCoeffs->B1 = -Y; /* Store -B1 in filter structure instead of B1!*/
+ /* A0=(1-B1)/2= B1/2 - 0.5*/
+ Y = Y / 2.0f; /* A0=Y=B1/2*/
+ Y = Y - 0.5f; /* A0=Y=(B1/2 - 0.5)*/
+
+ pCoeffs->A0 = Y * FILTER_LOSS_FLOAT; /* Apply loss to avoid overflow*/
+ pCoeffs->A1 = -pCoeffs->A0; /* Store A1=-A0*/
+
+ return 1;
+}
+#else
LVM_INT32 LVM_FO_HPF( LVM_INT32 w,
FO_C32_Coefs_t *pCoeffs)
{
@@ -97,4 +126,4 @@
return 1;
}
-
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/LVM_FO_LPF.c b/media/libeffects/lvm/lib/Common/src/LVM_FO_LPF.c
index 86ec951..9fe67f8 100644
--- a/media/libeffects/lvm/lib/Common/src/LVM_FO_LPF.c
+++ b/media/libeffects/lvm/lib/Common/src/LVM_FO_LPF.c
@@ -53,7 +53,7 @@
/* A9 194669577 */
/* A10 8 */
/* */
-/* Y = (A0 + A1*X + A2*X2 + A3*X3 + Â….. + AN*xN) << AN+1 */
+/* Y = (A0 + A1*X + A2*X2 + A3*X3 + �.. + AN*xN) << AN+1 */
/* */
/* */
/* PARAMETERS: */
@@ -68,7 +68,33 @@
/* RETURNS: */
/* */
/*-------------------------------------------------------------------------*/
+#ifdef BUILD_FLOAT
+LVM_FLOAT LVM_FO_LPF( LVM_FLOAT w,
+ FO_FLOAT_Coefs_t *pCoeffs)
+{
+ LVM_FLOAT Y,Coefficients[13] = {-0.999996f,
+ 0.999801f,
+ -0.497824f,
+ 0.322937f,
+ -0.180880f,
+ 0.087658f,
+ -0.032102f,
+ 0.008163f,
+ -0.001252f,
+ 0.000089f,
+ 0};
+ Y=LVM_Polynomial((LVM_UINT16)9, Coefficients, w);
+ pCoeffs->B1 = -Y; // Store -B1 in filter structure instead of B1!
+ // A0=(1+B1)/2= B1/2 + 0.5
+ Y = Y / 2.0f; // A0=Y=B1/2
+ Y = Y + 0.5f; // A0=Y=(B1/2 + 0.5)
+ pCoeffs->A0 = Y * FILTER_LOSS_FLOAT;
+ pCoeffs->A1 = pCoeffs->A0;
+
+ return 1;
+}
+#else
LVM_INT32 LVM_FO_LPF( LVM_INT32 w,
FO_C32_Coefs_t *pCoeffs)
{
@@ -94,4 +120,4 @@
pCoeffs->A1=pCoeffs->A0;
return 1;
}
-
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/LVM_GetOmega.c b/media/libeffects/lvm/lib/Common/src/LVM_GetOmega.c
index f3b9b3c..7846ca0 100644
--- a/media/libeffects/lvm/lib/Common/src/LVM_GetOmega.c
+++ b/media/libeffects/lvm/lib/Common/src/LVM_GetOmega.c
@@ -32,16 +32,45 @@
#define LVVDL_2PiByFs_SHIFT1 12 /* Qformat shift for 8kHz, 11.025kHz and 12kHz i.e. 12=41-29 */
#define LVVDL_2PiByFs_SHIFT2 13 /* Qformat shift for 16kHz, 22.050kHz and 24kHz i.e. 13=42-29 */
#define LVVDL_2PiByFs_SHIFT3 14 /* Qformat shift for 32kHz, 44.1kHz and 48kHz i.e. 14=43-29 */
-
+#ifndef BUILD_FLOAT
const LVM_INT32 LVVDL_2PiOnFsTable[] = {LVVDL_2PiBy_8000 , /* 8kHz in Q41, 16kHz in Q42, 32kHz in Q43 */
LVVDL_2PiBy_11025, /* 11025 Hz in Q41, 22050Hz in Q42, 44100 Hz in Q43*/
LVVDL_2PiBy_12000}; /* 12kHz in Q41, 24kHz in Q42, 48kHz in Q43 */
-
+#endif
const LVM_INT32 LVVDL_2PiOnFsShiftTable[]={LVVDL_2PiByFs_SHIFT1 , /* 8kHz, 11025Hz, 12kHz */
LVVDL_2PiByFs_SHIFT2, /* 16kHz, 22050Hz, 24kHz*/
LVVDL_2PiByFs_SHIFT3}; /* 32kHz, 44100Hz, 48kHz */
+#ifdef BUILD_FLOAT
+#define LVVDL_2PiBy_8000_f 0.000785398f
+#define LVVDL_2PiBy_11025_f 0.000569903f
+#define LVVDL_2PiBy_12000_f 0.000523599f
+#define LVVDL_2PiBy_16000_f 0.000392700f
+#define LVVDL_2PiBy_22050_f 0.000284952f
+#define LVVDL_2PiBy_24000_f 0.000261800f
+#define LVVDL_2PiBy_32000_f 0.000196350f
+#define LVVDL_2PiBy_44100_f 0.000142476f
+#define LVVDL_2PiBy_48000_f 0.000130900f
+#ifdef HIGHER_FS
+#define LVVDL_2PiBy_96000_f 0.000065450f
+#define LVVDL_2PiBy_192000_f 0.000032725f
+#endif
+const LVM_FLOAT LVVDL_2PiOnFsTable[] = {LVVDL_2PiBy_8000_f,
+ LVVDL_2PiBy_11025_f,
+ LVVDL_2PiBy_12000_f,
+ LVVDL_2PiBy_16000_f,
+ LVVDL_2PiBy_22050_f,
+ LVVDL_2PiBy_24000_f,
+ LVVDL_2PiBy_32000_f,
+ LVVDL_2PiBy_44100_f,
+ LVVDL_2PiBy_48000_f
+#ifdef HIGHER_FS
+ ,LVVDL_2PiBy_96000_f
+ ,LVVDL_2PiBy_192000_f
+#endif
+ };
+#endif
/*-------------------------------------------------------------------------*/
/* FUNCTION: */
/* LVM_GetOmega */
@@ -59,7 +88,20 @@
/* RETURNS: */
/* w=2*pi*Fc/Fs in Q2.29 format */
/*-------------------------------------------------------------------------*/
-
+#ifdef BUILD_FLOAT
+#ifdef HIGHER_FS
+LVM_FLOAT LVM_GetOmega(LVM_UINT32 Fc,
+ LVM_Fs_en Fs)
+#else
+LVM_FLOAT LVM_GetOmega(LVM_UINT16 Fc,
+ LVM_Fs_en Fs)
+#endif
+{
+ LVM_FLOAT w;
+ w = (LVM_FLOAT)Fc * LVVDL_2PiOnFsTable[Fs];
+ return w;
+}
+#else
LVM_INT32 LVM_GetOmega(LVM_UINT16 Fc,
LVM_Fs_en Fs)
{
@@ -67,4 +109,4 @@
MUL32x32INTO32((LVM_INT32)Fc,LVVDL_2PiOnFsTable[Fs%3],w,LVVDL_2PiOnFsShiftTable[Fs/3])
return w;
}
-
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/LVM_Mixer_FilterCoeffs.h b/media/libeffects/lvm/lib/Common/src/LVM_Mixer_FilterCoeffs.h
index 6846d49..f1e45fa 100644
--- a/media/libeffects/lvm/lib/Common/src/LVM_Mixer_FilterCoeffs.h
+++ b/media/libeffects/lvm/lib/Common/src/LVM_Mixer_FilterCoeffs.h
@@ -87,5 +87,58 @@
#define ALPHA_49 0 /* Floating point Alpha = 0.000000 */
#define ALPHA_50 0 /* Floating point Alpha = 0.000000 */
+#ifdef BUILD_FLOAT /* BUILD_FLOAT */
+#define ALPHA_Float_0 0.999999f
+#define ALPHA_Float_1 0.999998f
+#define ALPHA_Float_2 0.999997f
+#define ALPHA_Float_3 0.999996f
+#define ALPHA_Float_4 0.999995f
+#define ALPHA_Float_5 0.999992f
+#define ALPHA_Float_6 0.999989f
+#define ALPHA_Float_7 0.999985f
+#define ALPHA_Float_8 0.999979f
+#define ALPHA_Float_9 0.999970f
+#define ALPHA_Float_10 0.999957f
+#define ALPHA_Float_11 0.999939f
+#define ALPHA_Float_12 0.999914f
+#define ALPHA_Float_13 0.999879f
+#define ALPHA_Float_14 0.999829f
+#define ALPHA_Float_15 0.999758f
+#define ALPHA_Float_16 0.999658f
+#define ALPHA_Float_17 0.999516f
+#define ALPHA_Float_18 0.999316f
+#define ALPHA_Float_19 0.999033f
+#define ALPHA_Float_20 0.998633f
+#define ALPHA_Float_21 0.998067f
+#define ALPHA_Float_22 0.997268f
+#define ALPHA_Float_23 0.996139f
+#define ALPHA_Float_24 0.994545f
+#define ALPHA_Float_25 0.992295f
+#define ALPHA_Float_26 0.989123f
+#define ALPHA_Float_27 0.984654f
+#define ALPHA_Float_28 0.978370f
+#define ALPHA_Float_29 0.969553f
+#define ALPHA_Float_30 0.957221f
+#define ALPHA_Float_31 0.940051f
+#define ALPHA_Float_32 0.916297f
+#define ALPHA_Float_33 0.883729f
+#define ALPHA_Float_34 0.839645f
+#define ALPHA_Float_35 0.781036f
+#define ALPHA_Float_36 0.705078f
+#define ALPHA_Float_37 0.610108f
+#define ALPHA_Float_38 0.497239f
+#define ALPHA_Float_39 0.372343f
+#define ALPHA_Float_40 0.247351f
+#define ALPHA_Float_41 0.138722f
+#define ALPHA_Float_42 0.061234f
+#define ALPHA_Float_43 0.019267f
+#define ALPHA_Float_44 0.003756f
+#define ALPHA_Float_45 0.000372f
+#define ALPHA_Float_46 0.000014f
+#define ALPHA_Float_47 0.000000f
+#define ALPHA_Float_48 0.000000f
+#define ALPHA_Float_49 0.000000f
+#define ALPHA_Float_50 0.000000f
+#endif
#endif
diff --git a/media/libeffects/lvm/lib/Common/src/LVM_Mixer_TimeConstant.c b/media/libeffects/lvm/lib/Common/src/LVM_Mixer_TimeConstant.c
index 809d904..18b2782 100644
--- a/media/libeffects/lvm/lib/Common/src/LVM_Mixer_TimeConstant.c
+++ b/media/libeffects/lvm/lib/Common/src/LVM_Mixer_TimeConstant.c
@@ -57,7 +57,110 @@
/* Alpha - the filter coefficient Q31 format */
/* */
/************************************************************************/
+#ifdef BUILD_FLOAT
+LVM_FLOAT LVM_Mixer_TimeConstant(LVM_UINT32 tc,
+#ifdef HIGHER_FS
+ LVM_UINT32 Fs,
+#else
+ LVM_UINT16 Fs,
+#endif
+ LVM_UINT16 NumChannels)
+{
+ LVM_UINT32 Product;
+ LVM_FLOAT ProductFloat;
+ LVM_INT16 InterpolateShort;
+ LVM_FLOAT Interpolate;
+ LVM_UINT16 Shift;
+ LVM_FLOAT Diff;
+ LVM_FLOAT Table[] = {ALPHA_Float_0, /* Log spaced look-up table */
+ ALPHA_Float_1,
+ ALPHA_Float_2,
+ ALPHA_Float_3,
+ ALPHA_Float_4,
+ ALPHA_Float_5,
+ ALPHA_Float_6,
+ ALPHA_Float_7,
+ ALPHA_Float_8,
+ ALPHA_Float_9,
+ ALPHA_Float_10,
+ ALPHA_Float_11,
+ ALPHA_Float_12,
+ ALPHA_Float_13,
+ ALPHA_Float_14,
+ ALPHA_Float_15,
+ ALPHA_Float_16,
+ ALPHA_Float_17,
+ ALPHA_Float_18,
+ ALPHA_Float_19,
+ ALPHA_Float_20,
+ ALPHA_Float_21,
+ ALPHA_Float_22,
+ ALPHA_Float_23,
+ ALPHA_Float_24,
+ ALPHA_Float_25,
+ ALPHA_Float_26,
+ ALPHA_Float_27,
+ ALPHA_Float_28,
+ ALPHA_Float_29,
+ ALPHA_Float_30,
+ ALPHA_Float_31,
+ ALPHA_Float_32,
+ ALPHA_Float_33,
+ ALPHA_Float_34,
+ ALPHA_Float_35,
+ ALPHA_Float_36,
+ ALPHA_Float_37,
+ ALPHA_Float_38,
+ ALPHA_Float_39,
+ ALPHA_Float_40,
+ ALPHA_Float_41,
+ ALPHA_Float_42,
+ ALPHA_Float_43,
+ ALPHA_Float_44,
+ ALPHA_Float_45,
+ ALPHA_Float_46,
+ ALPHA_Float_47,
+ ALPHA_Float_48,
+ ALPHA_Float_49,
+ ALPHA_Float_50};
+
+ /* Calculate the product of the time constant and the sample rate */
+ Product = ((tc >> 16) * (LVM_UINT32)Fs) << 13; /* Stereo value */
+ Product = Product + (((tc & 0x0000FFFF) * (LVM_UINT32)Fs) >> 3);
+
+ if (NumChannels == 1)
+ {
+ Product = Product >> 1; /* Mono value */
+ }
+
+ /* Normalize to get the table index and interpolation factor */
+ for (Shift = 0; Shift < ((Alpha_TableSize - 1) / 2); Shift++)
+ {
+ if ((Product & 0x80000000) != 0)
+ {
+ break;
+ }
+
+ Product = Product << 1;
+ }
+ Shift = (LVM_UINT16)((Shift << 1));
+
+ if ((Product & 0x40000000)==0)
+ {
+ Shift++;
+ }
+
+ InterpolateShort = (LVM_INT16)((Product >> 15) & 0x00007FFF);
+ Interpolate = (LVM_FLOAT)InterpolateShort / 32768.0f;
+
+ Diff = (Table[Shift] - Table[Shift + 1]);
+ Diff = Diff * Interpolate;
+ ProductFloat = Table[Shift + 1] + Diff;
+
+ return ProductFloat;
+}
+#else
LVM_UINT32 LVM_Mixer_TimeConstant(LVM_UINT32 tc,
LVM_UINT16 Fs,
LVM_UINT16 NumChannels)
@@ -154,3 +257,4 @@
return Product;
}
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/LVM_Polynomial.c b/media/libeffects/lvm/lib/Common/src/LVM_Polynomial.c
index a6d7db2..cd57767 100644
--- a/media/libeffects/lvm/lib/Common/src/LVM_Polynomial.c
+++ b/media/libeffects/lvm/lib/Common/src/LVM_Polynomial.c
@@ -25,7 +25,7 @@
/* */
/* DESCRIPTION: */
/* This function performs polynomial expansion */
-/* Y = (A0 + A1*X + A2*X2 + A3*X3 + Â….. + AN*xN) << AN+1 */
+/* Y = (A0 + A1*X + A2*X2 + A3*X3 + �.. + AN*xN) << AN+1 */
/* */
/* LVM_INT32 LVM_Polynomial(LVM_UINT16 N, */
/* LVM_INT32 *pCoefficients, */
@@ -40,7 +40,48 @@
/* RETURNS: */
/* The result of the polynomial expansion in Q1.31 format */
/*-------------------------------------------------------------------------*/
+#ifdef BUILD_FLOAT
+LVM_FLOAT LVM_Polynomial(LVM_UINT16 N,
+ LVM_FLOAT *pCoefficients,
+ LVM_FLOAT X)
+{
+ LVM_INT32 i;
+ LVM_FLOAT Y,A,XTemp,Temp,sign;
+ Y = *pCoefficients; /* Y=A0*/
+ pCoefficients++;
+
+ if(X == -1.0f)
+ {
+ Temp = -1;
+ sign = Temp;
+ for(i = 1; i <= N; i++)
+ {
+ Y += ((*pCoefficients) * sign);
+ pCoefficients++;
+ sign *= Temp;
+ }
+
+
+ }
+ else
+ {
+ XTemp = X;
+ for(i = N-1; i >= 0; i--)
+ {
+ A = *pCoefficients;
+ pCoefficients++;
+
+ Temp = A * XTemp;
+ Y += Temp;
+
+ Temp = XTemp * X;
+ XTemp = Temp;
+ }
+ }
+ return Y;
+}
+#else
LVM_INT32 LVM_Polynomial(LVM_UINT16 N,
LVM_INT32 *pCoefficients,
LVM_INT32 X)
@@ -93,4 +134,4 @@
}
return Y;
}
-
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/LVM_Power10.c b/media/libeffects/lvm/lib/Common/src/LVM_Power10.c
index 6ca1077..8785594 100644
--- a/media/libeffects/lvm/lib/Common/src/LVM_Power10.c
+++ b/media/libeffects/lvm/lib/Common/src/LVM_Power10.c
@@ -44,7 +44,7 @@
/* A11 50477244 */
/* A12 -2 */
/* */
-/* Y = (A0 + A1*X + A2*X2 + A3*X3 + Â….. + AN*xN) << AN+1 */
+/* Y = (A0 + A1*X + A2*X2 + A3*X3 + �.. + AN*xN) << AN+1 */
/* */
/* */
/* PARAMETERS: */
@@ -54,7 +54,28 @@
/* RETURNS: */
/* The result of the 10x expansion in Q8.24 format */
/*-------------------------------------------------------------------------*/
-
+#ifdef BUILD_FLOAT
+LVM_FLOAT LVM_Power10(LVM_FLOAT X)
+{
+ LVM_FLOAT Y,Coefficients[13]={0.999906f,
+ 2.302475f,
+ 2.652765f,
+ 2.035494f,
+ 1.165667f,
+ 0.537676f,
+ 0.213192f,
+ 0.069603f,
+ 0.016553f,
+ 0.004373f,
+ 0.001817f,
+ 0.000367f,
+ 0};
+ Y=LVM_Polynomial((LVM_UINT16)11,
+ Coefficients,
+ X);
+ return Y;
+}
+#else
LVM_INT32 LVM_Power10(LVM_INT32 X)
{
LVM_INT32 Y,Coefficients[13]={ 16775636,
@@ -75,4 +96,4 @@
X);
return Y;
}
-
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/LoadConst_32.c b/media/libeffects/lvm/lib/Common/src/LoadConst_32.c
index 2f1e591..9e14c3b 100644
--- a/media/libeffects/lvm/lib/Common/src/LoadConst_32.c
+++ b/media/libeffects/lvm/lib/Common/src/LoadConst_32.c
@@ -24,7 +24,22 @@
/**********************************************************************************
FUNCTION LoadConst_32
***********************************************************************************/
+#ifdef BUILD_FLOAT
+void LoadConst_Float(const LVM_FLOAT val,
+ LVM_FLOAT *dst,
+ LVM_INT16 n )
+{
+ LVM_INT16 ii;
+ for (ii = n; ii != 0; ii--)
+ {
+ *dst = val;
+ dst++;
+ }
+
+ return;
+}
+#else
void LoadConst_32(const LVM_INT32 val,
LVM_INT32 *dst,
LVM_INT16 n )
@@ -39,5 +54,6 @@
return;
}
+#endif
/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/MSTo2i_Sat_16x16.c b/media/libeffects/lvm/lib/Common/src/MSTo2i_Sat_16x16.c
index 26297e7..02c906a 100644
--- a/media/libeffects/lvm/lib/Common/src/MSTo2i_Sat_16x16.c
+++ b/media/libeffects/lvm/lib/Common/src/MSTo2i_Sat_16x16.c
@@ -77,4 +77,58 @@
return;
}
+#ifdef BUILD_FLOAT
+void MSTo2i_Sat_Float(const LVM_FLOAT *srcM,
+ const LVM_FLOAT *srcS,
+ LVM_FLOAT *dst,
+ LVM_INT16 n )
+{
+ LVM_FLOAT temp,mVal,sVal;
+ LVM_INT16 ii;
+
+
+ for (ii = n; ii != 0; ii--)
+ {
+ mVal = (LVM_FLOAT)*srcM;
+ srcM++;
+
+ sVal = (LVM_FLOAT)*srcS;
+ srcS++;
+
+ temp = mVal + sVal;
+
+ if (temp > 1.0f)
+ {
+ *dst = 1.0f;
+ }
+ else if (temp < -1.0f)
+ {
+ *dst = -1.0f;
+ }
+ else
+ {
+ *dst = (LVM_FLOAT)temp;
+ }
+ dst++;
+
+ temp = mVal - sVal;
+
+ if (temp > 1.0f)
+ {
+ *dst = 1.0f;
+ }
+ else if (temp < -1.0f)
+ {
+ *dst = - 1.0f;
+ }
+ else
+ {
+ *dst = (LVM_FLOAT)temp;
+ }
+ dst++;
+ }
+
+ return;
+}
+#endif
/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/Mac3s_Sat_32x16.c b/media/libeffects/lvm/lib/Common/src/Mac3s_Sat_32x16.c
index f28f366..e3fb40d 100644
--- a/media/libeffects/lvm/lib/Common/src/Mac3s_Sat_32x16.c
+++ b/media/libeffects/lvm/lib/Common/src/Mac3s_Sat_32x16.c
@@ -64,7 +64,44 @@
return;
}
+#ifdef BUILD_FLOAT
+void Mac3s_Sat_Float(const LVM_FLOAT *src,
+ const LVM_FLOAT val,
+ LVM_FLOAT *dst,
+ LVM_INT16 n)
+{
+ LVM_INT16 ii;
+ LVM_FLOAT srcval;
+ LVM_FLOAT Temp,dInVal;
+ for (ii = n; ii != 0; ii--)
+ {
+ srcval = *src;
+ src++;
+
+ Temp = srcval * val;
+
+ dInVal = (LVM_FLOAT)*dst;
+ Temp = Temp + dInVal;
+
+ if (Temp > 1.000000f)
+ {
+ *dst = 1.000000f;
+ }
+ else if (Temp < -1.000000f)
+ {
+ *dst = -1.000000f;
+ }
+ else
+ {
+ *dst = Temp;
+ }
+ dst++;
+ }
+
+ return;
+}
+#endif
/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/MixInSoft_D32C31_SAT.c b/media/libeffects/lvm/lib/Common/src/MixInSoft_D32C31_SAT.c
index 73c26ed..16e367b 100644
--- a/media/libeffects/lvm/lib/Common/src/MixInSoft_D32C31_SAT.c
+++ b/media/libeffects/lvm/lib/Common/src/MixInSoft_D32C31_SAT.c
@@ -32,7 +32,71 @@
/**********************************************************************************
FUNCTION MIXINSOFT_D32C31_SAT
***********************************************************************************/
+#ifdef BUILD_FLOAT
+void MixInSoft_D32C31_SAT( Mix_1St_Cll_FLOAT_t *pInstance,
+ const LVM_FLOAT *src,
+ LVM_FLOAT *dst,
+ LVM_INT16 n)
+{
+ char HardMixing = TRUE;
+ if(n <= 0) return;
+
+ /******************************************************************************
+ SOFT MIXING
+ *******************************************************************************/
+ if (pInstance->Current != pInstance->Target)
+ {
+ if(pInstance->Alpha == 0){
+ pInstance->Current = pInstance->Target;
+ }else if ((pInstance->Current-pInstance->Target < POINT_ZERO_ONE_DB_FLOAT) &&
+ (pInstance->Current-pInstance->Target > -POINT_ZERO_ONE_DB_FLOAT)){
+ pInstance->Current = pInstance->Target; /* Difference is not significant anymore. \
+ Make them equal. */
+ }else{
+ /* Soft mixing has to be applied */
+ HardMixing = FALSE;
+ Core_MixInSoft_D32C31_SAT(pInstance, src, dst, n);
+ }
+ }
+
+ /******************************************************************************
+ HARD MIXING
+ *******************************************************************************/
+
+ if (HardMixing){
+ if (pInstance->Target != 0){ /* Nothing to do in case Target = 0 */
+ if ((pInstance->Target) == 1.0f)
+ Add2_Sat_Float(src, dst, n);
+ else{
+ Core_MixInSoft_D32C31_SAT(pInstance, src, dst, n);
+ pInstance->Current = pInstance->Target; /* In case the core function would \
+ have changed the Current value */
+ }
+ }
+ }
+
+ /******************************************************************************
+ CALL BACK
+ *******************************************************************************/
+ /* Call back before the hard mixing, because in this case, hard mixing makes
+ use of the core soft mix function which can change the Current value! */
+
+ if (pInstance->CallbackSet){
+ if ((pInstance->Current - pInstance->Target < POINT_ZERO_ONE_DB_FLOAT) &&
+ (pInstance->Current - pInstance->Target > -POINT_ZERO_ONE_DB_FLOAT)){
+ pInstance->Current = pInstance->Target; /* Difference is not significant anymore. \
+ Make them equal. */
+ pInstance->CallbackSet = FALSE;
+ if (pInstance->pCallBack != 0){
+ (*pInstance->pCallBack) ( pInstance->pCallbackHandle,
+ pInstance->pGeneralPurpose,
+ pInstance->CallbackParam );
+ }
+ }
+ }
+}
+#else
void MixInSoft_D32C31_SAT( Mix_1St_Cll_t *pInstance,
const LVM_INT32 *src,
LVM_INT32 *dst,
@@ -91,5 +155,5 @@
}
}
}
-
+#endif
/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/MixSoft_1St_D32C31_WRA.c b/media/libeffects/lvm/lib/Common/src/MixSoft_1St_D32C31_WRA.c
index ca88b04..869293b 100644
--- a/media/libeffects/lvm/lib/Common/src/MixSoft_1St_D32C31_WRA.c
+++ b/media/libeffects/lvm/lib/Common/src/MixSoft_1St_D32C31_WRA.c
@@ -34,7 +34,68 @@
/**********************************************************************************
FUNCTION MIXSOFT_1ST_D32C31_WRA
***********************************************************************************/
+#ifdef BUILD_FLOAT
+void MixSoft_1St_D32C31_WRA( Mix_1St_Cll_FLOAT_t *pInstance,
+ const LVM_FLOAT *src,
+ LVM_FLOAT *dst,
+ LVM_INT16 n)
+{
+ char HardMixing = TRUE;
+ if(n <= 0) return;
+
+ /******************************************************************************
+ SOFT MIXING
+ *******************************************************************************/
+ if (pInstance->Current != pInstance->Target)
+ {
+ if(pInstance->Alpha == 0){
+ pInstance->Current = pInstance->Target;
+ }else if ((pInstance->Current - pInstance->Target < POINT_ZERO_ONE_DB_FLOAT) &&
+ (pInstance->Current - pInstance->Target > -POINT_ZERO_ONE_DB_FLOAT)){
+ pInstance->Current = pInstance->Target; /* Difference is not significant anymore. \
+ Make them equal. */
+ }else{
+ /* Soft mixing has to be applied */
+ HardMixing = FALSE;
+ Core_MixSoft_1St_D32C31_WRA(pInstance, src, dst, n);
+ }
+ }
+
+ /******************************************************************************
+ HARD MIXING
+ *******************************************************************************/
+
+ if (HardMixing){
+ if (pInstance->Target == 0)
+ LoadConst_Float(0, dst, n);
+ else if ((pInstance->Target) == 1.0f){
+ if (src != dst)
+ Copy_Float((LVM_FLOAT*)src, (LVM_FLOAT*)dst, (LVM_INT16)(n));
+ }
+ else
+ Mult3s_Float(src, pInstance->Current, dst, n);
+ }
+
+ /******************************************************************************
+ CALL BACK
+ *******************************************************************************/
+
+ if (pInstance->CallbackSet){
+ if ((pInstance->Current - pInstance->Target < POINT_ZERO_ONE_DB_FLOAT) &&
+ (pInstance->Current - pInstance->Target > -POINT_ZERO_ONE_DB_FLOAT)){
+ pInstance->Current = pInstance->Target; /* Difference is not significant anymore. \
+ Make them equal. */
+ pInstance->CallbackSet = FALSE;
+ if (pInstance->pCallBack != 0){
+ (*pInstance->pCallBack) ( pInstance->pCallbackHandle,
+ pInstance->pGeneralPurpose,
+ pInstance->CallbackParam );
+ }
+ }
+ }
+}
+#else
void MixSoft_1St_D32C31_WRA( Mix_1St_Cll_t *pInstance,
const LVM_INT32 *src,
LVM_INT32 *dst,
@@ -91,5 +152,5 @@
}
}
}
-
+#endif
/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/MixSoft_2St_D32C31_SAT.c b/media/libeffects/lvm/lib/Common/src/MixSoft_2St_D32C31_SAT.c
index 2e0a099..6fc1b92 100644
--- a/media/libeffects/lvm/lib/Common/src/MixSoft_2St_D32C31_SAT.c
+++ b/media/libeffects/lvm/lib/Common/src/MixSoft_2St_D32C31_SAT.c
@@ -26,7 +26,44 @@
/**********************************************************************************
FUNCTION MIXSOFT_2ST_D32C31_SAT
***********************************************************************************/
+#ifdef BUILD_FLOAT
+void MixSoft_2St_D32C31_SAT( Mix_2St_Cll_FLOAT_t *pInstance,
+ const LVM_FLOAT *src1,
+ const LVM_FLOAT *src2,
+ LVM_FLOAT *dst,
+ LVM_INT16 n)
+{
+ if(n <= 0) return;
+
+ /******************************************************************************
+ SOFT MIXING
+ *******************************************************************************/
+ if ((pInstance->Current1 != pInstance->Target1) || (pInstance->Current2 != pInstance->Target2))
+ {
+ MixSoft_1St_D32C31_WRA((Mix_1St_Cll_FLOAT_t*)pInstance, src1, dst, n);
+ MixInSoft_D32C31_SAT((void *)&pInstance->Alpha2, /* Cast to void: \
+ no dereferencing in function*/
+ src2, dst, n);
+ }
+
+ /******************************************************************************
+ HARD MIXING
+ *******************************************************************************/
+
+ else
+ {
+ if (pInstance->Current1 == 0)
+ MixSoft_1St_D32C31_WRA((void *) &pInstance->Alpha2, /* Cast to void: no \
+ dereferencing in function*/
+ src2, dst, n);
+ else if (pInstance->Current2 == 0)
+ MixSoft_1St_D32C31_WRA((Mix_1St_Cll_FLOAT_t*) pInstance, src1, dst, n);
+ else
+ Core_MixHard_2St_D32C31_SAT(pInstance, src1, src2, dst, n);
+ }
+}
+#else
void MixSoft_2St_D32C31_SAT( Mix_2St_Cll_t *pInstance,
const LVM_INT32 *src1,
const LVM_INT32 *src2,
@@ -61,5 +98,6 @@
Core_MixHard_2St_D32C31_SAT( pInstance, src1, src2, dst, n);
}
}
-
+#endif
/**********************************************************************************/
+
diff --git a/media/libeffects/lvm/lib/Common/src/Mixer_private.h b/media/libeffects/lvm/lib/Common/src/Mixer_private.h
index 607073c..00d55ed 100644
--- a/media/libeffects/lvm/lib/Common/src/Mixer_private.h
+++ b/media/libeffects/lvm/lib/Common/src/Mixer_private.h
@@ -26,6 +26,10 @@
#define POINT_ZERO_ONE_DB 2473805 /* 0.01 dB on a full scale signal = (10^(0.01/20) -1) * 2^31 */
+#ifdef BUILD_FLOAT
+#define POINT_ZERO_ONE_DB_FLOAT 0.001152 /* 0.01 dB on a full scale \
+ signal = (10^(0.01/20) -1) * 2^31 */
+#endif
/**********************************************************************************
DEFINITIONS
***********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/MonoTo2I_32.c b/media/libeffects/lvm/lib/Common/src/MonoTo2I_32.c
index c09ec0f..796a15c 100644
--- a/media/libeffects/lvm/lib/Common/src/MonoTo2I_32.c
+++ b/media/libeffects/lvm/lib/Common/src/MonoTo2I_32.c
@@ -45,5 +45,26 @@
return;
}
+#ifdef BUILD_FLOAT
+void MonoTo2I_Float( const LVM_FLOAT *src,
+ LVM_FLOAT *dst,
+ LVM_INT16 n)
+{
+ LVM_INT16 ii;
+ src += (n - 1);
+ dst += ((n * 2) - 1);
+ for (ii = n; ii != 0; ii--)
+ {
+ *dst = *src;
+ dst--;
+
+ *dst = *src;
+ dst--;
+ src--;
+ }
+
+ return;
+}
+#endif
/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/Mult3s_32x16.c b/media/libeffects/lvm/lib/Common/src/Mult3s_32x16.c
index a5dc50f..c758560 100644
--- a/media/libeffects/lvm/lib/Common/src/Mult3s_32x16.c
+++ b/media/libeffects/lvm/lib/Common/src/Mult3s_32x16.c
@@ -47,5 +47,23 @@
return;
}
+#ifdef BUILD_FLOAT
+void Mult3s_Float( const LVM_FLOAT *src,
+ const LVM_FLOAT val,
+ LVM_FLOAT *dst,
+ LVM_INT16 n)
+{
+ LVM_INT16 ii;
+ LVM_FLOAT temp;
+ for (ii = n; ii != 0; ii--)
+ {
+ temp = (*src) * val;
+ src++;
+ *dst = temp;
+ dst++;
+ }
+ return;
+}
+#endif
/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/NonLinComp_D16.c b/media/libeffects/lvm/lib/Common/src/NonLinComp_D16.c
index 73343cd..5156edc 100644
--- a/media/libeffects/lvm/lib/Common/src/NonLinComp_D16.c
+++ b/media/libeffects/lvm/lib/Common/src/NonLinComp_D16.c
@@ -114,4 +114,54 @@
}
}
+#ifdef BUILD_FLOAT
+void NonLinComp_Float(LVM_FLOAT Gain,
+ LVM_FLOAT *pDataIn,
+ LVM_FLOAT *pDataOut,
+ LVM_INT32 BlockLength)
+{
+ LVM_FLOAT Sample; /* Input samples */
+ LVM_INT32 SampleNo; /* Sample index */
+ LVM_FLOAT Temp;
+
+
+ /*
+ * Process a block of samples
+ */
+ for(SampleNo = 0; SampleNo < BlockLength; SampleNo++)
+ {
+ /*
+ * Read the input
+ */
+ Sample = *pDataIn;
+ pDataIn++;
+
+
+ /*
+ * Apply the compander, this compresses the signal at the expense of
+ * harmonic distortion. The amount of compression is control by the
+ * gain factor
+ */
+ if (Sample != -1.0f)
+ {
+ Temp = ((Sample * Sample));
+ if(Sample > 0)
+ {
+ Sample = (Sample + ((Gain * (Sample - Temp)) ));
+ }
+ else
+ {
+ Sample = (Sample + ((Gain * (Sample + Temp)) ));
+ }
+ }
+
+
+ /*
+ * Save the output
+ */
+ *pDataOut = Sample;
+ pDataOut++;
+ }
+}
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32C14G11_TRC_WRA_01.c b/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32C14G11_TRC_WRA_01.c
index c8c1527..9c17a05 100644
--- a/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32C14G11_TRC_WRA_01.c
+++ b/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32C14G11_TRC_WRA_01.c
@@ -38,6 +38,88 @@
pBiquadState->pDelays[6] is y(n-2)L in Q0 format
pBiquadState->pDelays[7] is y(n-2)R in Q0 format
***************************************************************************/
+#ifdef BUILD_FLOAT
+void PK_2I_D32F32C14G11_TRC_WRA_01 ( Biquad_FLOAT_Instance_t *pInstance,
+ LVM_FLOAT *pDataIn,
+ LVM_FLOAT *pDataOut,
+ LVM_INT16 NrSamples)
+ {
+ LVM_FLOAT ynL,ynR,ynLO,ynRO,templ;
+ LVM_INT16 ii;
+ PFilter_State_Float pBiquadState = (PFilter_State_Float) pInstance;
+
+ for (ii = NrSamples; ii != 0; ii--)
+ {
+
+
+ /**************************************************************************
+ PROCESSING OF THE LEFT CHANNEL
+ ***************************************************************************/
+ /* ynL= (A0 * (x(n)L - x(n-2)L ) )*/
+ templ = (*pDataIn) - pBiquadState->pDelays[2];
+ ynL = templ * pBiquadState->coefs[0];
+
+ /* ynL+= ((-B2 * y(n-2)L )) */
+ templ = pBiquadState->pDelays[6] * pBiquadState->coefs[1];
+ ynL += templ;
+
+ /* ynL+= ((-B1 * y(n-1)L ) ) */
+ templ = pBiquadState->pDelays[4] * pBiquadState->coefs[2];
+ ynL += templ;
+
+ /* ynLO= ((Gain * ynL )) */
+ ynLO = ynL * pBiquadState->coefs[3];
+
+ /* ynLO=( ynLO + x(n)L )*/
+ ynLO += (*pDataIn);
+
+ /**************************************************************************
+ PROCESSING OF THE RIGHT CHANNEL
+ ***************************************************************************/
+ /* ynR= (A0 * (x(n)R - x(n-2)R ) ) */
+ templ = (*(pDataIn + 1)) - pBiquadState->pDelays[3];
+ ynR = templ * pBiquadState->coefs[0];
+
+ /* ynR+= ((-B2 * y(n-2)R ) ) */
+ templ = pBiquadState->pDelays[7] * pBiquadState->coefs[1];
+ ynR += templ;
+
+ /* ynR+= ((-B1 * y(n-1)R ) ) */
+ templ = pBiquadState->pDelays[5] * pBiquadState->coefs[2];
+ ynR += templ;
+
+ /* ynRO= ((Gain * ynR )) */
+ ynRO = ynR * pBiquadState->coefs[3];
+
+ /* ynRO=( ynRO + x(n)R )*/
+ ynRO += (*(pDataIn+1));
+
+ /**************************************************************************
+ UPDATING THE DELAYS
+ ***************************************************************************/
+ pBiquadState->pDelays[7] = pBiquadState->pDelays[5]; /* y(n-2)R=y(n-1)R*/
+ pBiquadState->pDelays[6] = pBiquadState->pDelays[4]; /* y(n-2)L=y(n-1)L*/
+ pBiquadState->pDelays[3] = pBiquadState->pDelays[1]; /* x(n-2)R=x(n-1)R*/
+ pBiquadState->pDelays[2] = pBiquadState->pDelays[0]; /* x(n-2)L=x(n-1)L*/
+ pBiquadState->pDelays[5] = ynR; /* Update y(n-1)R */
+ pBiquadState->pDelays[4] = ynL; /* Update y(n-1)L */
+ pBiquadState->pDelays[0] = (*pDataIn); /* Update x(n-1)L */
+ pDataIn++;
+ pBiquadState->pDelays[1] = (*pDataIn); /* Update x(n-1)R */
+ pDataIn++;
+
+ /**************************************************************************
+ WRITING THE OUTPUT
+ ***************************************************************************/
+ *pDataOut = ynLO; /* Write Left output*/
+ pDataOut++;
+ *pDataOut = ynRO; /* Write Right ouput*/
+ pDataOut++;
+
+ }
+
+ }
+#else
void PK_2I_D32F32C14G11_TRC_WRA_01 ( Biquad_Instance_t *pInstance,
LVM_INT32 *pDataIn,
LVM_INT32 *pDataOut,
@@ -118,4 +200,4 @@
}
}
-
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32C30G11_TRC_WRA_01.c b/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32C30G11_TRC_WRA_01.c
index 67a570b..f705cbf 100644
--- a/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32C30G11_TRC_WRA_01.c
+++ b/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32C30G11_TRC_WRA_01.c
@@ -38,6 +38,7 @@
pBiquadState->pDelays[6] is y(n-2)L in Q0 format
pBiquadState->pDelays[7] is y(n-2)R in Q0 format
***************************************************************************/
+#ifndef BUILD_FLOAT
void PK_2I_D32F32C30G11_TRC_WRA_01 ( Biquad_Instance_t *pInstance,
LVM_INT32 *pDataIn,
LVM_INT32 *pDataOut,
@@ -116,4 +117,4 @@
}
}
-
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CllGss_TRC_WRA_01_Init.c b/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CllGss_TRC_WRA_01_Init.c
index 1d6142c..65475a3 100644
--- a/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CllGss_TRC_WRA_01_Init.c
+++ b/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CllGss_TRC_WRA_01_Init.c
@@ -18,7 +18,7 @@
#include "BIQUAD.h"
#include "PK_2I_D32F32CllGss_TRC_WRA_01_Private.h"
-
+#ifndef BUILD_FLOAT
void PK_2I_D32F32CllGss_TRC_WRA_01_Init(Biquad_Instance_t *pInstance,
Biquad_2I_Order2_Taps_t *pTaps,
PK_C32_Coefs_t *pCoef)
@@ -35,4 +35,4 @@
pBiquadState->coefs[3]=pCoef->G;
}
-
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CssGss_TRC_WRA_01_Init.c b/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CssGss_TRC_WRA_01_Init.c
index b9f64e6..a36330e 100644
--- a/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CssGss_TRC_WRA_01_Init.c
+++ b/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CssGss_TRC_WRA_01_Init.c
@@ -17,7 +17,23 @@
#include "BIQUAD.h"
#include "PK_2I_D32F32CssGss_TRC_WRA_01_Private.h"
+#ifdef BUILD_FLOAT
+void PK_2I_D32F32CssGss_TRC_WRA_01_Init(Biquad_FLOAT_Instance_t *pInstance,
+ Biquad_2I_Order2_FLOAT_Taps_t *pTaps,
+ PK_FLOAT_Coefs_t *pCoef)
+{
+ PFilter_State_Float pBiquadState = (PFilter_State_Float) pInstance;
+ pBiquadState->pDelays = (LVM_FLOAT *) pTaps;
+ pBiquadState->coefs[0] = pCoef->A0;
+
+ pBiquadState->coefs[1] = pCoef->B2;
+
+ pBiquadState->coefs[2] = pCoef->B1;
+
+ pBiquadState->coefs[3] = pCoef->G;
+}
+#else
void PK_2I_D32F32CssGss_TRC_WRA_01_Init(Biquad_Instance_t *pInstance,
Biquad_2I_Order2_Taps_t *pTaps,
PK_C16_Coefs_t *pCoef)
@@ -34,4 +50,4 @@
pBiquadState->coefs[3]=pCoef->G;
}
-
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CssGss_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CssGss_TRC_WRA_01_Private.h
index e2050e0..1e32062 100644
--- a/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CssGss_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CssGss_TRC_WRA_01_Private.h
@@ -21,6 +21,16 @@
/* The internal state variables are implemented in a (for the user) hidden structure */
/* In this (private) file, the internal structure is declared fro private use. */
+
+#ifdef BUILD_FLOAT
+typedef struct _Filter_State_Float_
+{
+ LVM_FLOAT * pDelays; /* pointer to the delayed samples (data of 32 bits) */
+ LVM_FLOAT coefs[5]; /* pointer to the filter coefficients */
+}Filter_State_Float;
+
+typedef Filter_State_Float * PFilter_State_Float ;
+#endif
typedef struct _Filter_State_
{
LVM_INT32 * pDelays; /* pointer to the delayed samples (data of 32 bits) */
diff --git a/media/libeffects/lvm/lib/Common/src/Shift_Sat_v16xv16.c b/media/libeffects/lvm/lib/Common/src/Shift_Sat_v16xv16.c
index 8363270..28fea65 100644
--- a/media/libeffects/lvm/lib/Common/src/Shift_Sat_v16xv16.c
+++ b/media/libeffects/lvm/lib/Common/src/Shift_Sat_v16xv16.c
@@ -24,7 +24,7 @@
/**********************************************************************************
FUNCTION Shift_Sat_v16xv16
***********************************************************************************/
-
+#ifndef BUILD_FLOAT
void Shift_Sat_v16xv16 (const LVM_INT16 val,
const LVM_INT16 *src,
LVM_INT16 *dst,
@@ -77,5 +77,5 @@
}
return;
}
-
+#endif
/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/Shift_Sat_v32xv32.c b/media/libeffects/lvm/lib/Common/src/Shift_Sat_v32xv32.c
index fbd132e..fac9de7 100644
--- a/media/libeffects/lvm/lib/Common/src/Shift_Sat_v32xv32.c
+++ b/media/libeffects/lvm/lib/Common/src/Shift_Sat_v32xv32.c
@@ -24,7 +24,62 @@
/**********************************************************************************
FUNCTION Shift_Sat_v32xv32
***********************************************************************************/
+#ifdef BUILD_FLOAT
+void Shift_Sat_Float (const LVM_INT16 val,
+ const LVM_FLOAT *src,
+ LVM_FLOAT *dst,
+ LVM_INT16 n)
+{
+ LVM_FLOAT temp;
+ LVM_INT32 ii,ij;
+ LVM_INT16 RShift;
+ if(val > 0)
+ {
+ for (ii = n; ii != 0; ii--)
+ {
+ temp = (LVM_FLOAT)*src;
+ src++;
+ for(ij = 0; ij < val; ij++)
+ {
+ temp = temp * 2;
+ }
+
+ if(temp > 1.0)
+ temp = 1.0;
+ if(temp < -1.0)
+ temp = -1.0;
+
+ *dst = (LVM_FLOAT)temp;
+ dst++;
+ }
+ }
+ else if(val < 0)
+ {
+ RShift=(LVM_INT16)(-val);
+
+ for (ii = n; ii != 0; ii--)
+ {
+ temp = (LVM_FLOAT)*src;
+ src++;
+ for(ij = 0; ij < RShift; ij++)
+ {
+ temp = temp / 2;
+ }
+ *dst = (LVM_FLOAT)temp;
+ dst++;
+ }
+ }
+ else
+ {
+ if(src != dst)
+ {
+ Copy_Float(src, dst, n);
+ }
+ }
+ return;
+}
+#else
void Shift_Sat_v32xv32 (const LVM_INT16 val,
const LVM_INT32 *src,
LVM_INT32 *dst,
@@ -79,5 +134,5 @@
}
return;
}
-
+#endif
/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/dB_to_Lin32.c b/media/libeffects/lvm/lib/Common/src/dB_to_Lin32.c
index ac0343f..9a726f2 100644
--- a/media/libeffects/lvm/lib/Common/src/dB_to_Lin32.c
+++ b/media/libeffects/lvm/lib/Common/src/dB_to_Lin32.c
@@ -29,6 +29,9 @@
/*######################################################################################*/
#include "ScalarArithmetic.h"
+#ifdef BUILD_FLOAT
+#include <math.h>
+#endif
/****************************************************************************************
@@ -64,6 +67,18 @@
#define SECOND_COEF 38836
#define MAX_VALUE 1536 /* 96 * 16 */
+#ifdef BUILD_FLOAT
+LVM_FLOAT dB_to_LinFloat(LVM_INT16 db_fix)
+{
+ LVM_FLOAT dB_Float;
+ LVM_FLOAT LinFloat;
+
+ dB_Float = (LVM_FLOAT)((LVM_FLOAT)db_fix / 16.0f);
+ LinFloat = pow(10, dB_Float / 20.0);
+
+ return LinFloat;
+}
+#else
LVM_INT32 dB_to_Lin32(LVM_INT16 db_fix)
{
LVM_INT32 Lin_val_32;
@@ -106,4 +121,4 @@
return Lin_val_32; /* format 1.16.15 */
}
-
+#endif
diff --git a/media/libeffects/lvm/lib/Eq/lib/LVEQNB.h b/media/libeffects/lvm/lib/Eq/lib/LVEQNB.h
index db6aabe..8e0b738 100644
--- a/media/libeffects/lvm/lib/Eq/lib/LVEQNB.h
+++ b/media/libeffects/lvm/lib/Eq/lib/LVEQNB.h
@@ -200,6 +200,10 @@
#define LVEQNB_CAP_FS_32000 64
#define LVEQNB_CAP_FS_44100 128
#define LVEQNB_CAP_FS_48000 256
+#if defined(BUILD_FLOAT) && defined(HIGHER_FS)
+#define LVEQNB_CAP_FS_96000 512
+#define LVEQNB_CAP_FS_192000 1024
+#endif
typedef enum
{
@@ -212,6 +216,10 @@
LVEQNB_FS_32000 = 6,
LVEQNB_FS_44100 = 7,
LVEQNB_FS_48000 = 8,
+#ifdef HIGHER_FS
+ LVEQNB_FS_96000 = 9,
+ LVEQNB_FS_192000 = 10,
+#endif
LVEQNB_FS_MAX = LVM_MAXINT_32
} LVEQNB_Fs_en;
@@ -268,6 +276,7 @@
{
/* General parameters */
LVM_UINT16 SampleRate;
+
LVM_UINT16 SourceFormat;
LVM_UINT16 MaxBlockSize;
LVM_UINT16 MaxBands;
@@ -460,11 +469,17 @@
/* NOTES: */
/* */
/****************************************************************************************/
-
+#ifdef BUILD_FLOAT
+LVEQNB_ReturnStatus_en LVEQNB_Process(LVEQNB_Handle_t hInstance,
+ const LVM_FLOAT *pInData,
+ LVM_FLOAT *pOutData,
+ LVM_UINT16 NumSamples);
+#else
LVEQNB_ReturnStatus_en LVEQNB_Process(LVEQNB_Handle_t hInstance,
const LVM_INT16 *pInData,
LVM_INT16 *pOutData,
LVM_UINT16 NumSamples);
+#endif
diff --git a/media/libeffects/lvm/lib/Eq/src/LVEQNB_CalcCoef.c b/media/libeffects/lvm/lib/Eq/src/LVEQNB_CalcCoef.c
index fddedb9..ff52b7f 100644
--- a/media/libeffects/lvm/lib/Eq/src/LVEQNB_CalcCoef.c
+++ b/media/libeffects/lvm/lib/Eq/src/LVEQNB_CalcCoef.c
@@ -22,7 +22,9 @@
/****************************************************************************************/
#include "LVEQNB_Private.h"
-
+#ifdef BUILD_FLOAT
+#include <math.h>
+#endif
/****************************************************************************************/
/* */
@@ -77,6 +79,7 @@
/****************************************************************************************/
+#ifndef BUILD_FLOAT
LVEQNB_ReturnStatus_en LVEQNB_DoublePrecCoefs(LVM_UINT16 Fs,
LVEQNB_BandDef_t *pFilterDefinition,
PK_C32_Coefs_t *pCoefficients)
@@ -168,7 +171,7 @@
return(LVEQNB_SUCCESS);
}
-
+#endif
/****************************************************************************************/
/* */
@@ -205,7 +208,67 @@
/* */
/****************************************************************************************/
+#ifdef BUILD_FLOAT
+LVEQNB_ReturnStatus_en LVEQNB_SinglePrecCoefs(LVM_UINT16 Fs,
+ LVEQNB_BandDef_t *pFilterDefinition,
+ PK_FLOAT_Coefs_t *pCoefficients)
+{
+ extern LVM_FLOAT LVEQNB_GainTable[];
+ extern LVM_FLOAT LVEQNB_TwoPiOnFsTable[];
+ extern LVM_FLOAT LVEQNB_DTable[];
+
+
+ /*
+ * Get the filter definition
+ */
+ LVM_INT16 Gain = pFilterDefinition->Gain;
+ LVM_UINT16 Frequency = pFilterDefinition->Frequency;
+ /* As mentioned in effectbundle.h */
+ LVM_FLOAT QFactor = (LVM_FLOAT)pFilterDefinition->QFactor / 100.0f;
+
+
+ /*
+ * Intermediate variables and temporary values
+ */
+ LVM_FLOAT T0;
+ LVM_FLOAT D;
+ LVM_FLOAT A0;
+ LVM_FLOAT B1;
+ LVM_FLOAT B2;
+
+ /*
+ * Calculating the intermediate values
+ */
+ T0 = Frequency * LVEQNB_TwoPiOnFsTable[Fs]; /* T0 = 2 * Pi * Fc / Fs */
+ if (Gain >= 0)
+ {
+ D = LVEQNB_DTable[15]; /* D = 1 if GaindB >= 0 */
+ }
+ else
+ {
+ D = LVEQNB_DTable[Gain + 15]; /* D = 1 / (1 + G) if GaindB < 0 */
+ }
+
+ /*
+ * Calculate the B2,B1,A0 coefficients
+ */
+ B2 = -0.5 * (2 * QFactor - D * T0) / (2 * QFactor + D * T0);
+ B1 = (0.5 - B2) * cos(T0);
+ A0 = (0.5 + B2) / 2.0;
+
+ /*
+ * Write coeff into the data structure
+ */
+ /* all the coefficients are multiplied with 2 to make them align with fixed point values*/
+ pCoefficients->A0 = 2 * A0;
+ pCoefficients->B1 = 2 * B1;
+ pCoefficients->B2 = 2 * B2;
+ pCoefficients->G = LVEQNB_GainTable[Gain + 15];
+
+ return(LVEQNB_SUCCESS);
+}
+#else
LVEQNB_ReturnStatus_en LVEQNB_SinglePrecCoefs(LVM_UINT16 Fs,
LVEQNB_BandDef_t *pFilterDefinition,
PK_C16_Coefs_t *pCoefficients)
@@ -296,3 +359,4 @@
return(LVEQNB_SUCCESS);
}
+#endif
\ No newline at end of file
diff --git a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Coeffs.h b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Coeffs.h
index 95212f2..f0deb6c 100644
--- a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Coeffs.h
+++ b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Coeffs.h
@@ -25,7 +25,39 @@
/* Gain table for (10^(Gain/20) - 1) */
/* */
/************************************************************************************/
-
+#ifdef BUILD_FLOAT
+#define LVEQNB_Gain_Neg15_dB -0.822172f
+#define LVEQNB_Gain_Neg14_dB -0.800474f
+#define LVEQNB_Gain_Neg13_dB -0.776128f
+#define LVEQNB_Gain_Neg12_dB -0.748811f
+#define LVEQNB_Gain_Neg11_dB -0.718162f
+#define LVEQNB_Gain_Neg10_dB -0.683772f
+#define LVEQNB_Gain_Neg9_dB -0.645187f
+#define LVEQNB_Gain_Neg8_dB -0.601893f
+#define LVEQNB_Gain_Neg7_dB -0.553316f
+#define LVEQNB_Gain_Neg6_dB -0.498813f
+#define LVEQNB_Gain_Neg5_dB -0.437659f
+#define LVEQNB_Gain_Neg4_dB -0.369043f
+#define LVEQNB_Gain_Neg3_dB -0.292054f
+#define LVEQNB_Gain_Neg2_dB -0.205672f
+#define LVEQNB_Gain_Neg1_dB -0.108749f
+#define LVEQNB_Gain_0_dB 0.000000f
+#define LVEQNB_Gain_1_dB 0.122018f
+#define LVEQNB_Gain_2_dB 0.258925f
+#define LVEQNB_Gain_3_dB 0.412538f
+#define LVEQNB_Gain_4_dB 0.584893f
+#define LVEQNB_Gain_5_dB 0.778279f
+#define LVEQNB_Gain_6_dB 0.995262f
+#define LVEQNB_Gain_7_dB 1.238721f
+#define LVEQNB_Gain_8_dB 1.511886f
+#define LVEQNB_Gain_9_dB 1.818383f
+#define LVEQNB_Gain_10_dB 2.162278f
+#define LVEQNB_Gain_11_dB 2.548134f
+#define LVEQNB_Gain_12_dB 2.981072f
+#define LVEQNB_Gain_13_dB 3.466836f
+#define LVEQNB_Gain_14_dB 4.011872f
+#define LVEQNB_Gain_15_dB 4.623413f
+#else
#define LVEQNB_GAINSHIFT 11 /* As a power of 2 */
#define LVEQNB_Gain_Neg15_dB (-1684) /* Floating point value -0.822172 */
#define LVEQNB_Gain_Neg14_dB (-1639) /* Floating point value -0.800474 */
@@ -58,14 +90,30 @@
#define LVEQNB_Gain_13_dB 7100 /* Floating point value 3.466836 */
#define LVEQNB_Gain_14_dB 8216 /* Floating point value 4.011872 */
#define LVEQNB_Gain_15_dB 9469 /* Floating point value 4.623413 */
-
+#endif
/************************************************************************************/
/* */
/* Frequency table for 2*Pi/Fs */
/* */
/************************************************************************************/
+#ifdef BUILD_FLOAT
+#define LVEQNB_2PiOn_8000 0.000785f
+#define LVEQNB_2PiOn_11025 0.000570f
+#define LVEQNB_2PiOn_12000 0.000524f
+#define LVEQNB_2PiOn_16000 0.000393f
+#define LVEQNB_2PiOn_22050 0.000285f
+#define LVEQNB_2PiOn_24000 0.000262f
+#define LVEQNB_2PiOn_32000 0.000196f
+#define LVEQNB_2PiOn_44100 0.000142f
+#define LVEQNB_2PiOn_48000 0.000131f
+#ifdef HIGHER_FS
+#define LVEQNB_2PiOn_96000 0.000065f
+#define LVEQNB_2PiOn_192000 0.000033f
+#endif
+
+#else
#define LVEQNB_FREQSHIFT 25 /* As a power of 2 */
#define LVEQNB_2PiOn_8000 26354 /* Floating point value 0.000785 */
#define LVEQNB_2PiOn_11025 19123 /* Floating point value 0.000570 */
@@ -76,14 +124,31 @@
#define LVEQNB_2PiOn_32000 6588 /* Floating point value 0.000196 */
#define LVEQNB_2PiOn_44100 4781 /* Floating point value 0.000142 */
#define LVEQNB_2PiOn_48000 4392 /* Floating point value 0.000131 */
-
+#endif
/************************************************************************************/
/* */
/* 50D table for 50 / ( 1 + Gain ) */
/* */
/************************************************************************************/
-
+#ifdef BUILD_FLOAT
+#define LVEQNB_100D_Neg15_dB 5.623413f
+#define LVEQNB_100D_Neg14_dB 5.011872f
+#define LVEQNB_100D_Neg13_dB 4.466836f
+#define LVEQNB_100D_Neg12_dB 3.981072f
+#define LVEQNB_100D_Neg11_dB 3.548134f
+#define LVEQNB_100D_Neg10_dB 3.162278f
+#define LVEQNB_100D_Neg9_dB 2.818383f
+#define LVEQNB_100D_Neg8_dB 2.511886f
+#define LVEQNB_100D_Neg7_dB 2.238721f
+#define LVEQNB_100D_Neg6_dB 1.995262f
+#define LVEQNB_100D_Neg5_dB 1.778279f
+#define LVEQNB_100D_Neg4_dB 1.584893f
+#define LVEQNB_100D_Neg3_dB 1.412538f
+#define LVEQNB_100D_Neg2_dB 1.258925f
+#define LVEQNB_100D_Neg1_dB 1.122018f
+#define LVEQNB_100D_0_dB 1.000000f
+#else
#define LVEQNB_100DSHIFT 5 /* As a power of 2 */
#define LVEQNB_100D_Neg15_dB 17995 /* Floating point value 5.623413 */
#define LVEQNB_100D_Neg14_dB 16038 /* Floating point value 5.011872 */
@@ -101,6 +166,6 @@
#define LVEQNB_100D_Neg2_dB 4029 /* Floating point value 1.258925 */
#define LVEQNB_100D_Neg1_dB 3590 /* Floating point value 1.122018 */
#define LVEQNB_100D_0_dB 3200 /* Floating point value 1.000000 */
-
+#endif
#endif
diff --git a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Control.c b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Control.c
index 10e7d74..c290aec 100644
--- a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Control.c
+++ b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Control.c
@@ -140,8 +140,12 @@
void LVEQNB_SetFilters(LVEQNB_Instance_t *pInstance,
LVEQNB_Params_t *pParams)
{
-
+#ifdef HIGHER_FS
+ extern const LVM_UINT32 LVEQNB_SampleRateTab[]; /* Sample rate table */
+#else
extern const LVM_UINT16 LVEQNB_SampleRateTab[]; /* Sample rate table */
+#endif
+
LVM_UINT16 i; /* Filter band index */
LVM_UINT32 fs = (LVM_UINT32)LVEQNB_SampleRateTab[(LVM_UINT16)pParams->SampleRate]; /* Sample rate */
LVM_UINT32 fc; /* Filter centre frequency */
@@ -158,11 +162,15 @@
fc = (LVM_UINT32)pParams->pBandDefinition[i].Frequency; /* Get the band centre frequency */
QFactor = (LVM_INT16)pParams->pBandDefinition[i].QFactor; /* Get the band Q factor */
-
+#ifdef BUILD_FLOAT
+ pInstance->pBiquadType[i] = LVEQNB_SinglePrecision_Float; /* Default to single precision */
+#else
/*
* For each filter set the type of biquad required
*/
pInstance->pBiquadType[i] = LVEQNB_SinglePrecision; /* Default to single precision */
+#endif
+#ifndef BUILD_FLOAT
if ((fc << 15) <= (LOW_FREQ * fs))
{
/*
@@ -177,7 +185,7 @@
*/
pInstance->pBiquadType[i] = LVEQNB_DoublePrecision;
}
-
+#endif
/*
* Check for out of range frequencies
@@ -230,6 +238,25 @@
BiquadType = pInstance->pBiquadType[i];
switch (BiquadType)
{
+#ifdef BUILD_FLOAT
+ case LVEQNB_SinglePrecision_Float:
+ {
+ PK_FLOAT_Coefs_t Coefficients;
+ /*
+ * Calculate the single precision coefficients
+ */
+ LVEQNB_SinglePrecCoefs((LVM_UINT16)pInstance->Params.SampleRate,
+ &pInstance->pBandDefinitions[i],
+ &Coefficients);
+ /*
+ * Set the coefficients
+ */
+ PK_2I_D32F32CssGss_TRC_WRA_01_Init(&pInstance->pEQNB_FilterState_Float[i],
+ &pInstance->pEQNB_Taps_Float[i],
+ &Coefficients);
+ break;
+ }
+#else
case LVEQNB_DoublePrecision:
{
PK_C32_Coefs_t Coefficients;
@@ -269,6 +296,7 @@
&Coefficients);
break;
}
+#endif
default:
break;
}
@@ -288,7 +316,7 @@
/* pInstance Pointer to the instance */
/* */
/************************************************************************************/
-
+#ifndef BUILD_FLOAT
void LVEQNB_ClearFilterHistory(LVEQNB_Instance_t *pInstance)
{
LVM_INT16 *pTapAddress;
@@ -305,8 +333,24 @@
NumTaps); /* Number of words */
}
}
+#else
+void LVEQNB_ClearFilterHistory(LVEQNB_Instance_t *pInstance)
+{
+ LVM_FLOAT *pTapAddress;
+ LVM_INT16 NumTaps;
+ pTapAddress = (LVM_FLOAT *)pInstance->pEQNB_Taps_Float;
+ NumTaps = (LVM_INT16)((pInstance->Capabilities.MaxBands * \
+ sizeof(Biquad_2I_Order2_FLOAT_Taps_t)) / sizeof(LVM_FLOAT));
+ if (NumTaps != 0)
+ {
+ LoadConst_Float(0, /* Clear the history, value 0 */
+ pTapAddress, /* Destination */
+ NumTaps); /* Number of words */
+ }
+}
+#endif
/****************************************************************************************/
/* */
/* FUNCTION: LVEQNB_Control */
@@ -422,9 +466,13 @@
{
if(pParams->OperatingMode == LVEQNB_ON)
{
+#ifdef BUILD_FLOAT
+ LVC_Mixer_SetTarget(&pInstance->BypassMixer.MixerStream[0], 1.0f);
+ LVC_Mixer_SetTarget(&pInstance->BypassMixer.MixerStream[1], 0.0f);
+#else
LVC_Mixer_SetTarget(&pInstance->BypassMixer.MixerStream[0],LVM_MAXINT_16);
LVC_Mixer_SetTarget(&pInstance->BypassMixer.MixerStream[1],0);
-
+#endif
pInstance->BypassMixer.MixerStream[0].CallbackSet = 1;
pInstance->BypassMixer.MixerStream[1].CallbackSet = 1;
}
@@ -432,15 +480,18 @@
{
/* Stay on the ON operating mode until the transition is done */
pInstance->Params.OperatingMode = LVEQNB_ON;
-
+#ifdef BUILD_FLOAT
+ LVC_Mixer_SetTarget(&pInstance->BypassMixer.MixerStream[0], 0.0f);
+ LVC_Mixer_SetTarget(&pInstance->BypassMixer.MixerStream[1], 1.0f);
+#else
LVC_Mixer_SetTarget(&pInstance->BypassMixer.MixerStream[0],0);
LVC_Mixer_SetTarget(&pInstance->BypassMixer.MixerStream[1],LVM_MAXINT_16);
+#endif
pInstance->BypassMixer.MixerStream[0].CallbackSet = 1;
pInstance->BypassMixer.MixerStream[1].CallbackSet = 1;
}
LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->BypassMixer.MixerStream[0],LVEQNB_BYPASS_MIXER_TC,(LVM_Fs_en)pParams->SampleRate,2);
LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->BypassMixer.MixerStream[1],LVEQNB_BYPASS_MIXER_TC,(LVM_Fs_en)pParams->SampleRate,2);
-
pInstance->bInOperatingModeTransition = LVM_TRUE;
}
@@ -470,8 +521,13 @@
/*
* Send an ALGOFF event if the ON->OFF switch transition is finished
*/
+#ifdef BUILD_FLOAT
+ if((LVC_Mixer_GetTarget(&pInstance->BypassMixer.MixerStream[0]) == 0) &&
+ (CallbackParam == 0)){
+#else
if((LVC_Mixer_GetTarget(&pInstance->BypassMixer.MixerStream[0]) == 0x00000000) &&
(CallbackParam == 0)){
+#endif
pInstance->Params.OperatingMode = LVEQNB_BYPASS;
if (CallBack != LVM_NULL){
CallBack(pInstance->Capabilities.pBundleInstance, LVM_NULL, ALGORITHM_EQNB_ID|LVEQNB_EVENT_ALGOFF);
@@ -485,9 +541,3 @@
return 1;
}
-
-
-
-
-
-
diff --git a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Init.c b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Init.c
index e01c1c5..de1bbb7 100644
--- a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Init.c
+++ b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Init.c
@@ -97,6 +97,21 @@
*/
InstAlloc_Init(&AllocMem,
LVM_NULL);
+#ifdef BUILD_FLOAT
+ InstAlloc_AddMember(&AllocMem, /* Low pass filter */
+ sizeof(Biquad_2I_Order2_FLOAT_Taps_t));
+ InstAlloc_AddMember(&AllocMem, /* High pass filter */
+ sizeof(Biquad_2I_Order2_FLOAT_Taps_t));
+ /* Equaliser Biquad Taps */
+ InstAlloc_AddMember(&AllocMem,
+ (pCapabilities->MaxBands * sizeof(Biquad_2I_Order2_FLOAT_Taps_t)));
+ /* Filter definitions */
+ InstAlloc_AddMember(&AllocMem,
+ (pCapabilities->MaxBands * sizeof(LVEQNB_BandDef_t)));
+ /* Biquad types */
+ InstAlloc_AddMember(&AllocMem,
+ (pCapabilities->MaxBands * sizeof(LVEQNB_BiquadType_en)));
+#else
InstAlloc_AddMember(&AllocMem, /* Low pass filter */
sizeof(Biquad_2I_Order2_Taps_t));
InstAlloc_AddMember(&AllocMem, /* High pass filter */
@@ -107,6 +122,7 @@
(pCapabilities->MaxBands * sizeof(LVEQNB_BandDef_t))); /* Filter definitions */
InstAlloc_AddMember(&AllocMem,
(pCapabilities->MaxBands * sizeof(LVEQNB_BiquadType_en))); /* Biquad types */
+#endif
pMemoryTable->Region[LVEQNB_MEMREGION_PERSISTENT_DATA].Size = InstAlloc_GetTotal(&AllocMem);
pMemoryTable->Region[LVEQNB_MEMREGION_PERSISTENT_DATA].Alignment = LVEQNB_DATA_ALIGN;
pMemoryTable->Region[LVEQNB_MEMREGION_PERSISTENT_DATA].Type = LVEQNB_PERSISTENT_DATA;
@@ -117,12 +133,22 @@
*/
InstAlloc_Init(&AllocMem,
LVM_NULL);
+#ifdef BUILD_FLOAT
+ InstAlloc_AddMember(&AllocMem, /* Low pass filter */
+ sizeof(Biquad_FLOAT_Instance_t));
+ InstAlloc_AddMember(&AllocMem, /* High pass filter */
+ sizeof(Biquad_FLOAT_Instance_t));
+ /* Equaliser Biquad Instance */
+ InstAlloc_AddMember(&AllocMem,
+ pCapabilities->MaxBands * sizeof(Biquad_FLOAT_Instance_t));
+#else
InstAlloc_AddMember(&AllocMem, /* Low pass filter */
sizeof(Biquad_Instance_t));
InstAlloc_AddMember(&AllocMem, /* High pass filter */
sizeof(Biquad_Instance_t));
InstAlloc_AddMember(&AllocMem,
pCapabilities->MaxBands * sizeof(Biquad_Instance_t)); /* Equaliser Biquad Instance */
+#endif
pMemoryTable->Region[LVEQNB_MEMREGION_PERSISTENT_COEF].Size = InstAlloc_GetTotal(&AllocMem);
pMemoryTable->Region[LVEQNB_MEMREGION_PERSISTENT_COEF].Alignment = LVEQNB_COEF_ALIGN;
pMemoryTable->Region[LVEQNB_MEMREGION_PERSISTENT_COEF].Type = LVEQNB_PERSISTENT_COEF;
@@ -133,8 +159,14 @@
*/
InstAlloc_Init(&AllocMem,
LVM_NULL);
+#ifdef BUILD_FLOAT
+ InstAlloc_AddMember(&AllocMem, /* Low pass filter */
+ LVEQNB_SCRATCHBUFFERS * sizeof(LVM_FLOAT) * \
+ pCapabilities->MaxBlockSize);
+#else
InstAlloc_AddMember(&AllocMem, /* Low pass filter */
LVEQNB_SCRATCHBUFFERS*sizeof(LVM_INT16)*pCapabilities->MaxBlockSize);
+#endif
pMemoryTable->Region[LVEQNB_MEMREGION_SCRATCH].Size = InstAlloc_GetTotal(&AllocMem);
pMemoryTable->Region[LVEQNB_MEMREGION_SCRATCH].Alignment = LVEQNB_SCRATCH_ALIGN;
pMemoryTable->Region[LVEQNB_MEMREGION_SCRATCH].Type = LVEQNB_SCRATCH;
@@ -248,8 +280,15 @@
InstAlloc_Init(&AllocMem,
pMemoryTable->Region[LVEQNB_MEMREGION_PERSISTENT_COEF].pBaseAddress);
+#ifdef BUILD_FLOAT
+ /* Equaliser Biquad Instance */
+ pInstance->pEQNB_FilterState_Float = InstAlloc_AddMember(&AllocMem,
+ pCapabilities->MaxBands * \
+ sizeof(Biquad_FLOAT_Instance_t));
+#else
pInstance->pEQNB_FilterState = InstAlloc_AddMember(&AllocMem,
pCapabilities->MaxBands * sizeof(Biquad_Instance_t)); /* Equaliser Biquad Instance */
+#endif
@@ -259,9 +298,15 @@
InstAlloc_Init(&AllocMem,
pMemoryTable->Region[LVEQNB_MEMREGION_PERSISTENT_DATA].pBaseAddress);
+#ifdef BUILD_FLOAT
+ MemSize = (pCapabilities->MaxBands * sizeof(Biquad_2I_Order2_FLOAT_Taps_t));
+ pInstance->pEQNB_Taps_Float = (Biquad_2I_Order2_FLOAT_Taps_t *)InstAlloc_AddMember(&AllocMem,
+ MemSize);
+#else
MemSize = (pCapabilities->MaxBands * sizeof(Biquad_2I_Order2_Taps_t));
pInstance->pEQNB_Taps = (Biquad_2I_Order2_Taps_t *)InstAlloc_AddMember(&AllocMem,
MemSize);
+#endif
MemSize = (pCapabilities->MaxBands * sizeof(LVEQNB_BandDef_t));
pInstance->pBandDefinitions = (LVEQNB_BandDef_t *)InstAlloc_AddMember(&AllocMem,
MemSize);
@@ -279,8 +324,13 @@
InstAlloc_Init(&AllocMem,
pMemoryTable->Region[LVEQNB_MEMREGION_SCRATCH].pBaseAddress);
+#ifdef BUILD_FLOAT
+ pInstance->pFastTemporary = (LVM_FLOAT *)InstAlloc_AddMember(&AllocMem,
+ sizeof(LVM_FLOAT));
+#else
pInstance->pFastTemporary = (LVM_INT16 *)InstAlloc_AddMember(&AllocMem,
sizeof(LVM_INT16));
+#endif
/*
* Update the instance parameters
@@ -308,15 +358,22 @@
pInstance->BypassMixer.MixerStream[0].CallbackParam = 0;
pInstance->BypassMixer.MixerStream[0].pCallbackHandle = (void*)pInstance;
pInstance->BypassMixer.MixerStream[0].pCallBack = LVEQNB_BypassMixerCallBack;
+
LVC_Mixer_Init(&pInstance->BypassMixer.MixerStream[0],0,0);
LVC_Mixer_SetTimeConstant(&pInstance->BypassMixer.MixerStream[0],0,LVM_FS_8000,2);
+
pInstance->BypassMixer.MixerStream[1].CallbackSet = 1;
pInstance->BypassMixer.MixerStream[1].CallbackParam = 0;
pInstance->BypassMixer.MixerStream[1].pCallbackHandle = LVM_NULL;
pInstance->BypassMixer.MixerStream[1].pCallBack = LVM_NULL;
+#ifdef BUILD_FLOAT
+ LVC_Mixer_Init(&pInstance->BypassMixer.MixerStream[1], 0, 1.0f);
+ LVC_Mixer_SetTimeConstant(&pInstance->BypassMixer.MixerStream[1], 0, LVM_FS_8000, 2);
+#else
LVC_Mixer_Init(&pInstance->BypassMixer.MixerStream[1],0,LVM_MAXINT_16);
LVC_Mixer_SetTimeConstant(&pInstance->BypassMixer.MixerStream[1],0,LVM_FS_8000,2);
+#endif
pInstance->bInOperatingModeTransition = LVM_FALSE;
diff --git a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Private.h b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Private.h
index 9df980c..56b02e0 100644
--- a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Private.h
+++ b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Private.h
@@ -60,6 +60,9 @@
/* Filter biquad types */
typedef enum
{
+#ifdef BUILD_FLOAT
+ LVEQNB_SinglePrecision_Float = -1,
+#endif
LVEQNB_SinglePrecision = 0,
LVEQNB_DoublePrecision = 1,
LVEQNB_OutOfRange = 2,
@@ -84,11 +87,20 @@
LVEQNB_Capabilities_t Capabilities; /* Instance capabilities */
/* Aligned memory pointers */
+#ifdef BUILD_FLOAT
+ LVM_FLOAT *pFastTemporary; /* Fast temporary data base address */
+#else
LVM_INT16 *pFastTemporary; /* Fast temporary data base address */
+#endif
+#ifdef BUILD_FLOAT
+ Biquad_2I_Order2_FLOAT_Taps_t *pEQNB_Taps_Float; /* Equaliser Taps */
+ Biquad_FLOAT_Instance_t *pEQNB_FilterState_Float; /* State for each filter band */
+#else
/* Process variables */
Biquad_2I_Order2_Taps_t *pEQNB_Taps; /* Equaliser Taps */
Biquad_Instance_t *pEQNB_FilterState; /* State for each filter band */
+#endif
/* Filter definitions and call back */
LVM_UINT16 NBands; /* Number of bands */
@@ -96,7 +108,12 @@
LVEQNB_BiquadType_en *pBiquadType; /* Filter biquad types */
/* Bypass variable */
+#ifdef BUILD_FLOAT
+ LVMixer3_2St_FLOAT_st BypassMixer;
+#else
LVMixer3_2St_st BypassMixer; /* Bypass mixer used in transitions */
+#endif
+
LVM_INT16 bInOperatingModeTransition; /* Operating mode transition flag */
} LVEQNB_Instance_t;
@@ -114,7 +131,11 @@
void LVEQNB_SetCoefficients(LVEQNB_Instance_t *pInstance);
void LVEQNB_ClearFilterHistory(LVEQNB_Instance_t *pInstance);
-
+#ifdef BUILD_FLOAT
+LVEQNB_ReturnStatus_en LVEQNB_SinglePrecCoefs(LVM_UINT16 Fs,
+ LVEQNB_BandDef_t *pFilterDefinition,
+ PK_FLOAT_Coefs_t *pCoefficients);
+#else
LVEQNB_ReturnStatus_en LVEQNB_SinglePrecCoefs(LVM_UINT16 Fs,
LVEQNB_BandDef_t *pFilterDefinition,
PK_C16_Coefs_t *pCoefficients);
@@ -122,6 +143,7 @@
LVEQNB_ReturnStatus_en LVEQNB_DoublePrecCoefs(LVM_UINT16 Fs,
LVEQNB_BandDef_t *pFilterDefinition,
PK_C32_Coefs_t *pCoefficients);
+#endif
LVM_INT32 LVEQNB_BypassMixerCallBack (void* hInstance, void *pGeneralPurpose, LVM_INT16 CallbackParam);
diff --git a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Process.c b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Process.c
index 58f58ed..6328181 100644
--- a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Process.c
+++ b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Process.c
@@ -57,7 +57,121 @@
/* NOTES: */
/* */
/****************************************************************************************/
+#ifdef BUILD_FLOAT
+LVEQNB_ReturnStatus_en LVEQNB_Process(LVEQNB_Handle_t hInstance,
+ const LVM_FLOAT *pInData,
+ LVM_FLOAT *pOutData,
+ LVM_UINT16 NumSamples)
+{
+ LVM_UINT16 i;
+ Biquad_FLOAT_Instance_t *pBiquad;
+ LVEQNB_Instance_t *pInstance = (LVEQNB_Instance_t *)hInstance;
+ LVM_FLOAT *pScratch;
+
+
+ /* Check for NULL pointers */
+ if((hInstance == LVM_NULL) || (pInData == LVM_NULL) || (pOutData == LVM_NULL))
+ {
+ return LVEQNB_NULLADDRESS;
+ }
+
+ /* Check if the input and output data buffers are 32-bit aligned */
+ if ((((uintptr_t)pInData % 4) != 0) || (((uintptr_t)pOutData % 4) != 0))
+ {
+ return LVEQNB_ALIGNMENTERROR;
+ }
+
+ pScratch = (LVM_FLOAT *)pInstance->pFastTemporary;
+
+ /*
+ * Check the number of samples is not too large
+ */
+ if (NumSamples > pInstance->Capabilities.MaxBlockSize)
+ {
+ return(LVEQNB_TOOMANYSAMPLES);
+ }
+
+ if (pInstance->Params.OperatingMode == LVEQNB_ON)
+ {
+ /*
+ * Copy input data in to scratch buffer
+ */
+
+ Copy_Float((LVM_FLOAT *)pInData, /* Source */
+ pScratch, /* Destination */
+ (LVM_INT16)(2 * NumSamples)); /* Left and Right */
+ /*
+ * For each section execte the filter unless the gain is 0dB
+ */
+ if (pInstance->NBands != 0)
+ {
+ for (i = 0; i < pInstance->NBands; i++)
+ {
+ /*
+ * Check if band is non-zero dB gain
+ */
+ if (pInstance->pBandDefinitions[i].Gain != 0)
+ {
+ /*
+ * Get the address of the biquad instance
+ */
+ pBiquad = &pInstance->pEQNB_FilterState_Float[i];
+
+
+ /*
+ * Select single or double precision as required
+ */
+ switch (pInstance->pBiquadType[i])
+ {
+ case LVEQNB_SinglePrecision_Float:
+ {
+ PK_2I_D32F32C14G11_TRC_WRA_01(pBiquad,
+ (LVM_FLOAT *)pScratch,
+ (LVM_FLOAT *)pScratch,
+ (LVM_INT16)NumSamples);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ }
+ }
+
+
+ if(pInstance->bInOperatingModeTransition == LVM_TRUE){
+ LVC_MixSoft_2St_D16C31_SAT(&pInstance->BypassMixer,
+ (LVM_FLOAT *)pScratch,
+ (LVM_FLOAT *)pInData,
+ (LVM_FLOAT *)pScratch,
+ (LVM_INT16)(2 * NumSamples));
+ Copy_Float((LVM_FLOAT*)pScratch, /* Source */
+ pOutData, /* Destination */
+ (LVM_INT16)(2 * NumSamples)); /* Left and Right samples */
+ }
+ else{
+ Copy_Float(pScratch, /* Source */
+ pOutData, /* Destination */
+ (LVM_INT16 )(2 * NumSamples)); /* Left and Right */
+ }
+ }
+ else
+ {
+ /*
+ * Mode is OFF so copy the data if necessary
+ */
+ if (pInData != pOutData)
+ {
+ Copy_Float(pInData, /* Source */
+ pOutData, /* Destination */
+ (LVM_INT16)(2 * NumSamples)); /* Left and Right samples */
+ }
+ }
+ return(LVEQNB_SUCCESS);
+
+}
+#else
LVEQNB_ReturnStatus_en LVEQNB_Process(LVEQNB_Handle_t hInstance,
const LVM_INT16 *pInData,
LVM_INT16 *pOutData,
@@ -198,3 +312,4 @@
return(LVEQNB_SUCCESS);
}
+#endif
\ No newline at end of file
diff --git a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Tables.c b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Tables.c
index 8e2e0e8..563181c 100644
--- a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Tables.c
+++ b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Tables.c
@@ -36,6 +36,20 @@
* Sample rate table for converting between the enumerated type and the actual
* frequency
*/
+#if defined(BUILD_FLOAT) && defined(HIGHER_FS)
+const LVM_UINT32 LVEQNB_SampleRateTab[] = {8000, /* 8kS/s */
+ 11025,
+ 12000,
+ 16000,
+ 22050,
+ 24000,
+ 32000,
+ 44100,
+ 48000,
+ 96000,
+ 192000
+};
+#else
const LVM_UINT16 LVEQNB_SampleRateTab[] = {8000, /* 8kS/s */
11025,
12000,
@@ -44,8 +58,9 @@
24000,
32000,
44100,
- 48000}; /* 48kS/s */
-
+ 48000
+};
+#endif
/************************************************************************************/
/* */
@@ -56,6 +71,22 @@
/*
* Table for 2 * Pi / Fs
*/
+#ifdef BUILD_FLOAT
+const LVM_FLOAT LVEQNB_TwoPiOnFsTable[] = {LVEQNB_2PiOn_8000, /* 8kS/s */
+ LVEQNB_2PiOn_11025,
+ LVEQNB_2PiOn_12000,
+ LVEQNB_2PiOn_16000,
+ LVEQNB_2PiOn_22050,
+ LVEQNB_2PiOn_24000,
+ LVEQNB_2PiOn_32000,
+ LVEQNB_2PiOn_44100,
+ LVEQNB_2PiOn_48000
+#ifdef HIGHER_FS
+ ,LVEQNB_2PiOn_96000
+ ,LVEQNB_2PiOn_192000
+#endif
+ };
+#else
const LVM_INT16 LVEQNB_TwoPiOnFsTable[] = {LVEQNB_2PiOn_8000, /* 8kS/s */
LVEQNB_2PiOn_11025,
LVEQNB_2PiOn_12000,
@@ -65,10 +96,44 @@
LVEQNB_2PiOn_32000,
LVEQNB_2PiOn_44100,
LVEQNB_2PiOn_48000}; /* 48kS/s */
+#endif
/*
* Gain table
*/
+#ifdef BUILD_FLOAT
+const LVM_FLOAT LVEQNB_GainTable[] = {LVEQNB_Gain_Neg15_dB, /* -15dB gain */
+ LVEQNB_Gain_Neg14_dB,
+ LVEQNB_Gain_Neg13_dB,
+ LVEQNB_Gain_Neg12_dB,
+ LVEQNB_Gain_Neg11_dB,
+ LVEQNB_Gain_Neg10_dB,
+ LVEQNB_Gain_Neg9_dB,
+ LVEQNB_Gain_Neg8_dB,
+ LVEQNB_Gain_Neg7_dB,
+ LVEQNB_Gain_Neg6_dB,
+ LVEQNB_Gain_Neg5_dB,
+ LVEQNB_Gain_Neg4_dB,
+ LVEQNB_Gain_Neg3_dB,
+ LVEQNB_Gain_Neg2_dB,
+ LVEQNB_Gain_Neg1_dB,
+ LVEQNB_Gain_0_dB, /* 0dB gain */
+ LVEQNB_Gain_1_dB,
+ LVEQNB_Gain_2_dB,
+ LVEQNB_Gain_3_dB,
+ LVEQNB_Gain_4_dB,
+ LVEQNB_Gain_5_dB,
+ LVEQNB_Gain_6_dB,
+ LVEQNB_Gain_7_dB,
+ LVEQNB_Gain_8_dB,
+ LVEQNB_Gain_9_dB,
+ LVEQNB_Gain_10_dB,
+ LVEQNB_Gain_11_dB,
+ LVEQNB_Gain_12_dB,
+ LVEQNB_Gain_13_dB,
+ LVEQNB_Gain_14_dB,
+ LVEQNB_Gain_15_dB}; /* +15dB gain */
+#else
const LVM_INT16 LVEQNB_GainTable[] = {LVEQNB_Gain_Neg15_dB, /* -15dB gain */
LVEQNB_Gain_Neg14_dB,
LVEQNB_Gain_Neg13_dB,
@@ -101,10 +166,28 @@
LVEQNB_Gain_14_dB,
LVEQNB_Gain_15_dB}; /* +15dB gain */
-
+#endif
/*
* D table for 100 / (Gain + 1)
*/
+#ifdef BUILD_FLOAT
+const LVM_FLOAT LVEQNB_DTable[] = {LVEQNB_100D_Neg15_dB, /* -15dB gain */
+ LVEQNB_100D_Neg14_dB,
+ LVEQNB_100D_Neg13_dB,
+ LVEQNB_100D_Neg12_dB,
+ LVEQNB_100D_Neg11_dB,
+ LVEQNB_100D_Neg10_dB,
+ LVEQNB_100D_Neg9_dB,
+ LVEQNB_100D_Neg8_dB,
+ LVEQNB_100D_Neg7_dB,
+ LVEQNB_100D_Neg6_dB,
+ LVEQNB_100D_Neg5_dB,
+ LVEQNB_100D_Neg4_dB,
+ LVEQNB_100D_Neg3_dB,
+ LVEQNB_100D_Neg2_dB,
+ LVEQNB_100D_Neg1_dB,
+ LVEQNB_100D_0_dB}; /* 0dB gain */
+#else
const LVM_INT16 LVEQNB_DTable[] = {LVEQNB_100D_Neg15_dB, /* -15dB gain */
LVEQNB_100D_Neg14_dB,
LVEQNB_100D_Neg13_dB,
@@ -122,7 +205,7 @@
LVEQNB_100D_Neg1_dB,
LVEQNB_100D_0_dB}; /* 0dB gain */
-
+#endif
/************************************************************************************/
/* */
/* Filter polynomial coefficients */
diff --git a/media/libeffects/lvm/lib/Reverb/lib/LVREV.h b/media/libeffects/lvm/lib/Reverb/lib/LVREV.h
index 28e3369..9c2e297 100644
--- a/media/libeffects/lvm/lib/Reverb/lib/LVREV.h
+++ b/media/libeffects/lvm/lib/Reverb/lib/LVREV.h
@@ -107,8 +107,14 @@
/* Parameters for REV */
LVM_UINT16 Level; /* Level, 0 to 100 representing percentage of reverb */
+#ifndef HIGHER_FS
LVM_UINT16 LPF; /* Low pass filter, in Hz */
LVM_UINT16 HPF; /* High pass filter, in Hz */
+#else
+ LVM_UINT32 LPF; /* Low pass filter, in Hz */
+ LVM_UINT32 HPF; /* High pass filter, in Hz */
+#endif
+
LVM_UINT16 T60; /* Decay time constant, in ms */
LVM_UINT16 Density; /* Echo density, 0 to 100 for minimum to maximum density */
LVM_UINT16 Damping; /* Damping */
@@ -297,11 +303,17 @@
/* 1. The input and output buffers must be 32-bit aligned */
/* */
/****************************************************************************************/
+#ifdef BUILD_FLOAT
+LVREV_ReturnStatus_en LVREV_Process(LVREV_Handle_t hInstance,
+ const LVM_FLOAT *pInData,
+ LVM_FLOAT *pOutData,
+ const LVM_UINT16 NumSamples);
+#else
LVREV_ReturnStatus_en LVREV_Process(LVREV_Handle_t hInstance,
const LVM_INT32 *pInData,
LVM_INT32 *pOutData,
const LVM_UINT16 NumSamples);
-
+#endif
#ifdef __cplusplus
}
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_ApplyNewSettings.c b/media/libeffects/lvm/lib/Reverb/src/LVREV_ApplyNewSettings.c
index ac2ef9d..e710844 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_ApplyNewSettings.c
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_ApplyNewSettings.c
@@ -41,6 +41,7 @@
/* */
/****************************************************************************************/
+#ifndef BUILD_FLOAT
LVREV_ReturnStatus_en LVREV_ApplyNewSettings (LVREV_Instance_st *pPrivate)
{
@@ -593,8 +594,589 @@
return LVREV_SUCCESS;
}
+#else /* BUILD_FLOAT*/
+LVREV_ReturnStatus_en LVREV_ApplyNewSettings (LVREV_Instance_st *pPrivate)
+{
+
+ LVM_Mode_en OperatingMode;
+ LVM_INT32 NumberOfDelayLines;
+ /* Check for NULL pointer */
+ if(pPrivate == LVM_NULL)
+ {
+ return LVREV_NULLADDRESS;
+ }
+
+ OperatingMode = pPrivate->NewParams.OperatingMode;
+
+ if(pPrivate->InstanceParams.NumDelays == LVREV_DELAYLINES_4)
+ {
+ NumberOfDelayLines = 4;
+ }
+ else if(pPrivate->InstanceParams.NumDelays == LVREV_DELAYLINES_2)
+ {
+ NumberOfDelayLines = 2;
+ }
+ else
+ {
+ NumberOfDelayLines = 1;
+ }
+
+ /*
+ * Update the high pass filter coefficients
+ */
+ if((pPrivate->NewParams.HPF != pPrivate->CurrentParams.HPF) ||
+ (pPrivate->NewParams.SampleRate != pPrivate->CurrentParams.SampleRate) ||
+ (pPrivate->bFirstControl == LVM_TRUE))
+ {
+ LVM_FLOAT Omega;
+ FO_FLOAT_Coefs_t Coeffs;
+
+ Omega = LVM_GetOmega(pPrivate->NewParams.HPF, pPrivate->NewParams.SampleRate);
+ LVM_FO_HPF(Omega, &Coeffs);
+ FO_1I_D32F32Cll_TRC_WRA_01_Init( &pPrivate->pFastCoef->HPCoefs,
+ &pPrivate->pFastData->HPTaps, &Coeffs);
+ LoadConst_Float(0,
+ (void *)&pPrivate->pFastData->HPTaps, /* Destination Cast to void: \
+ no dereferencing in function*/
+ sizeof(Biquad_1I_Order1_FLOAT_Taps_t) / sizeof(LVM_FLOAT));
+ }
+
+
+ /*
+ * Update the low pass filter coefficients
+ */
+ if((pPrivate->NewParams.LPF != pPrivate->CurrentParams.LPF) ||
+ (pPrivate->NewParams.SampleRate != pPrivate->CurrentParams.SampleRate) ||
+ (pPrivate->bFirstControl == LVM_TRUE))
+ {
+ LVM_FLOAT Omega;
+ FO_FLOAT_Coefs_t Coeffs;
+
+ Coeffs.A0 = 1;
+ Coeffs.A1 = 0;
+ Coeffs.B1 = 0;
+ if(pPrivate->NewParams.LPF <= (LVM_FsTable[pPrivate->NewParams.SampleRate] >> 1))
+ {
+ Omega = LVM_GetOmega(pPrivate->NewParams.LPF, pPrivate->NewParams.SampleRate);
+
+ /*
+ * Do not apply filter if w =2*pi*fc/fs >= 2.9
+ */
+ if(Omega <= (LVM_FLOAT)LVREV_2_9_INQ29)
+ {
+ LVM_FO_LPF(Omega, &Coeffs);
+ }
+ }
+ FO_1I_D32F32Cll_TRC_WRA_01_Init( &pPrivate->pFastCoef->LPCoefs,
+ &pPrivate->pFastData->LPTaps, &Coeffs);
+ LoadConst_Float(0,
+ (void *)&pPrivate->pFastData->LPTaps, /* Destination Cast to void: \
+ no dereferencing in function*/
+ sizeof(Biquad_1I_Order1_FLOAT_Taps_t) / sizeof(LVM_FLOAT));
+ }
+
+
+ /*
+ * Calculate the room size parameter
+ */
+ if( pPrivate->NewParams.RoomSize != pPrivate->CurrentParams.RoomSize)
+ {
+ /* Room size range is 10ms to 200ms
+ * 0% -- 10ms
+ * 50% -- 65ms
+ * 100% -- 120ms
+ */
+ pPrivate->RoomSizeInms = 10 + (((pPrivate->NewParams.RoomSize*11) + 5) / 10);
+ }
+
+
+ /*
+ * Update the T delay number of samples and the all pass delay number of samples
+ */
+ if( (pPrivate->NewParams.RoomSize != pPrivate->CurrentParams.RoomSize) ||
+ (pPrivate->NewParams.SampleRate != pPrivate->CurrentParams.SampleRate) ||
+ (pPrivate->bFirstControl == LVM_TRUE))
+ {
+
+ LVM_UINT32 Temp;
+ LVM_INT32 APDelaySize;
+ LVM_INT32 Fs = LVM_GetFsFromTable(pPrivate->NewParams.SampleRate);
+ LVM_UINT32 DelayLengthSamples = (LVM_UINT32)(Fs * pPrivate->RoomSizeInms);
+ LVM_INT16 i;
+ LVM_FLOAT ScaleTable[] = {LVREV_T_3_Power_minus0_on_4, LVREV_T_3_Power_minus1_on_4, \
+ LVREV_T_3_Power_minus2_on_4, LVREV_T_3_Power_minus3_on_4};
+ LVM_INT16 MaxT_Delay[] = {LVREV_MAX_T0_DELAY, LVREV_MAX_T1_DELAY, \
+ LVREV_MAX_T2_DELAY, LVREV_MAX_T3_DELAY};
+ LVM_INT16 MaxAP_Delay[] = {LVREV_MAX_AP0_DELAY, LVREV_MAX_AP1_DELAY, \
+ LVREV_MAX_AP2_DELAY, LVREV_MAX_AP3_DELAY};
+
+
+ /*
+ * For each delay line
+ */
+ for (i = 0; i < NumberOfDelayLines; i++)
+ {
+ if (i != 0)
+ {
+ LVM_FLOAT Temp1; /* to avoid QAC warning on type conversion */
+
+ Temp1=(LVM_FLOAT)DelayLengthSamples;
+ Temp = (LVM_UINT32)(Temp1 * ScaleTable[i]);
+ }
+ else
+ {
+ Temp = DelayLengthSamples;
+ }
+ APDelaySize = Temp / 1500;
+
+
+ /*
+ * Set the fixed delay
+ */
+
+#ifdef HIGHER_FS
+ Temp = (MaxT_Delay[i] - MaxAP_Delay[i]) * Fs / 192000;
+#else
+ Temp = (MaxT_Delay[i] - MaxAP_Delay[i]) * Fs / 48000;
+#endif
+ pPrivate->Delay_AP[i] = pPrivate->T[i] - Temp;
+
+
+ /*
+ * Set the tap selection
+ */
+ if (pPrivate->AB_Selection)
+ {
+ /* Smooth from tap A to tap B */
+ pPrivate->pOffsetB[i] = &pPrivate->pDelay_T[i][pPrivate->T[i] - \
+ Temp - APDelaySize];
+ pPrivate->B_DelaySize[i] = APDelaySize;
+ pPrivate->Mixer_APTaps[i].Target1 = 0;
+ pPrivate->Mixer_APTaps[i].Target2 = 1.0f;
+ }
+ else
+ {
+ /* Smooth from tap B to tap A */
+ pPrivate->pOffsetA[i] = &pPrivate->pDelay_T[i][pPrivate->T[i] - \
+ Temp - APDelaySize];
+ pPrivate->A_DelaySize[i] = APDelaySize;
+ pPrivate->Mixer_APTaps[i].Target2 = 0;
+ pPrivate->Mixer_APTaps[i].Target1 = 1.0f;
+ }
+
+ /*
+ * Set the maximum block size to the smallest delay size
+ */
+ pPrivate->MaxBlkLen = Temp;
+ if (pPrivate->MaxBlkLen > pPrivate->A_DelaySize[i])
+ {
+ pPrivate->MaxBlkLen = pPrivate->A_DelaySize[i];
+ }
+ if (pPrivate->MaxBlkLen > pPrivate->B_DelaySize[i])
+ {
+ pPrivate->MaxBlkLen = pPrivate->B_DelaySize[i];
+ }
+ }
+ if (pPrivate->AB_Selection)
+ {
+ pPrivate->AB_Selection = 0;
+ }
+ else
+ {
+ pPrivate->AB_Selection = 1;
+ }
+
+
+ /*
+ * Limit the maximum block length
+ */
+ /* Just as a precausion, but no problem if we remove this line */
+ pPrivate->MaxBlkLen = pPrivate->MaxBlkLen - 2;
+ if(pPrivate->MaxBlkLen > pPrivate->InstanceParams.MaxBlockSize)
+ {
+ pPrivate->MaxBlkLen = (LVM_INT32)pPrivate->InstanceParams.MaxBlockSize;
+ }
+ }
+
+
+
+ /*
+ * Update the low pass filter coefficient
+ */
+ if( (pPrivate->NewParams.Damping != pPrivate->CurrentParams.Damping) ||
+ (pPrivate->NewParams.SampleRate != pPrivate->CurrentParams.SampleRate) ||
+ (pPrivate->bFirstControl == LVM_TRUE))
+ {
+
+ LVM_INT32 Temp;
+ LVM_FLOAT Omega;
+ FO_FLOAT_Coefs_t Coeffs;
+ LVM_INT16 i;
+ LVM_INT16 Damping = (LVM_INT16)((pPrivate->NewParams.Damping * 100) + 1000);
+ LVM_FLOAT ScaleTable[] = {LVREV_T_3_Power_0_on_4, LVREV_T_3_Power_1_on_4,
+ LVREV_T_3_Power_2_on_4, LVREV_T_3_Power_3_on_4};
+
+
+ /*
+ * For each filter
+ */
+ for (i = 0; i < NumberOfDelayLines; i++)
+ {
+ if (i != 0)
+ {
+ Temp = (LVM_INT32)(ScaleTable[i] * Damping);
+ }
+ else
+ {
+ Temp = Damping;
+ }
+ if(Temp <= (LVM_INT32)(LVM_FsTable[pPrivate->NewParams.SampleRate] >> 1))
+ {
+ Omega = LVM_GetOmega(Temp, pPrivate->NewParams.SampleRate);
+ LVM_FO_LPF(Omega, &Coeffs);
+ }
+ else
+ {
+ Coeffs.A0 = 1;
+ Coeffs.A1 = 0;
+ Coeffs.B1 = 0;
+ }
+ FO_1I_D32F32Cll_TRC_WRA_01_Init(&pPrivate->pFastCoef->RevLPCoefs[i],
+ &pPrivate->pFastData->RevLPTaps[i], &Coeffs);
+ }
+ }
+
+
+ /*
+ * Update All-pass filter mixer time constants
+ */
+ if( (pPrivate->NewParams.RoomSize != pPrivate->CurrentParams.RoomSize) ||
+ (pPrivate->NewParams.SampleRate != pPrivate->CurrentParams.SampleRate) ||
+ (pPrivate->NewParams.Density != pPrivate->CurrentParams.Density))
+ {
+ LVM_INT16 i;
+ LVM_FLOAT Alpha;
+ LVM_FLOAT AlphaTap;
+
+ Alpha = LVM_Mixer_TimeConstant(LVREV_ALLPASS_TC,
+ LVM_GetFsFromTable(pPrivate->NewParams.SampleRate),
+ 1);
+
+ AlphaTap = LVM_Mixer_TimeConstant(LVREV_ALLPASS_TAP_TC,
+ LVM_GetFsFromTable(pPrivate->NewParams.SampleRate),
+ 1);
+
+ for (i = 0; i < 4; i++)
+ {
+ pPrivate->Mixer_APTaps[i].Alpha1 = AlphaTap;
+ pPrivate->Mixer_APTaps[i].Alpha2 = AlphaTap;
+ pPrivate->Mixer_SGFeedback[i].Alpha = Alpha;
+ pPrivate->Mixer_SGFeedforward[i].Alpha = Alpha;
+ }
+ }
+
+
+ /*
+ * Update the feed back gain
+ */
+ if( (pPrivate->NewParams.RoomSize != pPrivate->CurrentParams.RoomSize) ||
+ (pPrivate->NewParams.SampleRate != pPrivate->CurrentParams.SampleRate) ||
+ (pPrivate->NewParams.T60 != pPrivate->CurrentParams.T60) ||
+ (pPrivate->bFirstControl == LVM_TRUE))
+ {
+
+ LVM_FLOAT G[4]; /* Feedback gain (Q7.24) */
+
+ if(pPrivate->NewParams.T60 == 0)
+ {
+ G[3] = 0;
+ G[2] = 0;
+ G[1] = 0;
+ G[0] = 0;
+ }
+ else
+ {
+ LVM_FLOAT Temp1;
+ LVM_FLOAT Temp2;
+ LVM_INT16 i;
+ LVM_FLOAT ScaleTable[] = {LVREV_T_3_Power_minus0_on_4, LVREV_T_3_Power_minus1_on_4,
+ LVREV_T_3_Power_minus2_on_4, LVREV_T_3_Power_minus3_on_4};
+
+
+ /*
+ * For each delay line
+ */
+ for (i = 0; i < NumberOfDelayLines; i++)
+ {
+ Temp1 = (3 * pPrivate->RoomSizeInms * ScaleTable[i]) / pPrivate->NewParams.T60;
+ if(Temp1 >= (4))
+ {
+ G[i] = 0;
+ }
+ else if((Temp1 >= (2)))
+ {
+ Temp2 = LVM_Power10(-(Temp1 / 2.0f));
+ Temp1 = LVM_Power10(-(Temp1 / 2.0f));
+ Temp1 = Temp1 * Temp2;
+ }
+ else
+ {
+ Temp1 = LVM_Power10(-(Temp1));
+ }
+ if (NumberOfDelayLines == 1)
+ {
+ G[i] = Temp1;
+ }
+ else
+ {
+ LVM_FLOAT TempG;
+ TempG = Temp1 * ONE_OVER_SQRT_TWO;
+ G[i]=TempG;
+ }
+ }
+ }
+
+ /* Set up the feedback mixers for four delay lines */
+ pPrivate->FeedbackMixer[0].Target=G[0];
+ pPrivate->FeedbackMixer[1].Target=G[1];
+ pPrivate->FeedbackMixer[2].Target=G[2];
+ pPrivate->FeedbackMixer[3].Target=G[3];
+ }
+
+
+ /*
+ * Calculate the gain correction
+ */
+ if((pPrivate->NewParams.RoomSize != pPrivate->CurrentParams.RoomSize) ||
+ (pPrivate->NewParams.Level != pPrivate->CurrentParams.Level) ||
+ (pPrivate->NewParams.T60 != pPrivate->CurrentParams.T60) )
+ {
+ LVM_INT32 Index=0;
+ LVM_FLOAT Index_FLOAT;
+ LVM_INT32 i=0;
+ LVM_FLOAT Gain=0;
+ LVM_INT32 RoomSize=0;
+ LVM_FLOAT T60;
+ LVM_FLOAT Coefs[5];
+
+
+ if(pPrivate->NewParams.RoomSize == 0)
+ {
+ RoomSize = 1;
+ }
+ else
+ {
+ RoomSize = (LVM_INT32)pPrivate->NewParams.RoomSize;
+ }
+
+
+ if(pPrivate->NewParams.T60 < 100)
+ {
+ T60 = 100 * LVREV_T60_SCALE;
+ }
+ else
+ {
+ T60 = pPrivate->NewParams.T60 * LVREV_T60_SCALE;
+ }
+
+ /* Find the nearest room size in table */
+ for(i = 0; i < 24; i++)
+ {
+ if(RoomSize <= LVREV_GainPolyTable[i][0])
+ {
+ Index = i;
+ break;
+ }
+ }
+
+
+ if(RoomSize == LVREV_GainPolyTable[Index][0])
+ {
+ /* Take table values if the room size is in table */
+ for(i = 1; i < 5; i++)
+ {
+ Coefs[i-1] = LVREV_GainPolyTable[Index][i];
+ }
+ Coefs[4] = 0;
+ Gain = LVM_Polynomial(3, Coefs, T60); /* Q.24 result */
+ }
+ else
+ {
+ /* Interpolate the gain between nearest room sizes */
+
+ LVM_FLOAT Gain1,Gain2;
+ LVM_INT32 Tot_Dist,Dist;
+
+ Tot_Dist = (LVM_UINT32)LVREV_GainPolyTable[Index][0] - \
+ (LVM_UINT32)LVREV_GainPolyTable[Index-1][0];
+ Dist = RoomSize - (LVM_UINT32)LVREV_GainPolyTable[Index - 1][0];
+
+
+ /* Get gain for first */
+ for(i = 1; i < 5; i++)
+ {
+ Coefs[i-1] = LVREV_GainPolyTable[Index-1][i];
+ }
+ Coefs[4] = 0;
+
+ Gain1 = LVM_Polynomial(3, Coefs, T60); /* Q.24 result */
+
+ /* Get gain for second */
+ for(i = 1; i < 5; i++)
+ {
+ Coefs[i-1] = LVREV_GainPolyTable[Index][i];
+ }
+ Coefs[4] = 0;
+
+ Gain2 = LVM_Polynomial(3, Coefs, T60); /* Q.24 result */
+
+ /* Linear Interpolate the gain */
+ Gain = Gain1 + (((Gain2 - Gain1) * Dist) / (Tot_Dist));
+ }
+
+
+ /*
+ * Get the inverse of gain: Q.15
+ * Gain is mostly above one except few cases, take only gains above 1
+ */
+ if(Gain < 1)
+ {
+ pPrivate->Gain = 1;
+ }
+ else
+ {
+ pPrivate->Gain = 1 / Gain;
+ }
+
+ Index_FLOAT = 100.0f / (LVM_FLOAT)(100 + pPrivate->NewParams.Level);
+ pPrivate->Gain = pPrivate->Gain * Index_FLOAT;
+ pPrivate->GainMixer.Target = (pPrivate->Gain*Index_FLOAT) / 2;
+ }
+
+
+ /*
+ * Update the all pass comb filter coefficient
+ */
+ if( (pPrivate->NewParams.Density != pPrivate->CurrentParams.Density) ||
+ (pPrivate->bFirstControl == LVM_TRUE))
+ {
+ LVM_INT16 i;
+ LVM_FLOAT b = (LVM_FLOAT)pPrivate->NewParams.Density * LVREV_B_8_on_1000;
+
+ for (i = 0; i < 4; i++)
+ {
+ pPrivate->Mixer_SGFeedback[i].Target = b;
+ pPrivate->Mixer_SGFeedforward[i].Target = b;
+ }
+ }
+
+
+ /*
+ * Update the bypass mixer time constant
+ */
+ if((pPrivate->NewParams.SampleRate != pPrivate->CurrentParams.SampleRate) ||
+ (pPrivate->bFirstControl == LVM_TRUE))
+ {
+ LVM_UINT16 NumChannels = 1; /* Assume MONO format */
+ LVM_FLOAT Alpha;
+
+ Alpha = LVM_Mixer_TimeConstant(LVREV_FEEDBACKMIXER_TC,
+ LVM_GetFsFromTable(pPrivate->NewParams.SampleRate),
+ NumChannels);
+ pPrivate->FeedbackMixer[0].Alpha = Alpha;
+ pPrivate->FeedbackMixer[1].Alpha = Alpha;
+ pPrivate->FeedbackMixer[2].Alpha = Alpha;
+ pPrivate->FeedbackMixer[3].Alpha = Alpha;
+
+ NumChannels = 2; /* Always stereo output */
+ pPrivate->BypassMixer.Alpha1 = LVM_Mixer_TimeConstant(LVREV_BYPASSMIXER_TC,
+ LVM_GetFsFromTable(pPrivate->NewParams.SampleRate), NumChannels);
+ pPrivate->BypassMixer.Alpha2 = pPrivate->BypassMixer.Alpha1;
+ pPrivate->GainMixer.Alpha = pPrivate->BypassMixer.Alpha1;
+ }
+
+
+ /*
+ * Update the bypass mixer targets
+ */
+ if( (pPrivate->NewParams.Level != pPrivate->CurrentParams.Level) &&
+ (pPrivate->NewParams.OperatingMode == LVM_MODE_ON))
+ {
+ pPrivate->BypassMixer.Target2 = (LVM_FLOAT)(pPrivate->NewParams.Level ) / 100.0f;
+ pPrivate->BypassMixer.Target1 = 0x00000000;
+ if ((pPrivate->NewParams.Level == 0) && (pPrivate->bFirstControl == LVM_FALSE))
+ {
+ pPrivate->BypassMixer.CallbackSet2 = LVM_TRUE;
+ }
+ if (pPrivate->NewParams.Level != 0)
+ {
+ pPrivate->bDisableReverb = LVM_FALSE;
+ }
+ }
+
+ if(pPrivate->NewParams.OperatingMode != pPrivate->CurrentParams.OperatingMode)
+ {
+ if(pPrivate->NewParams.OperatingMode == LVM_MODE_ON)
+ {
+ pPrivate->BypassMixer.Target2 = (LVM_FLOAT)(pPrivate->NewParams.Level ) / 100.0f;
+ pPrivate->BypassMixer.Target1 = 0x00000000;
+
+ pPrivate->BypassMixer.CallbackSet2 = LVM_FALSE;
+ OperatingMode = LVM_MODE_ON;
+ if (pPrivate->NewParams.Level == 0)
+ {
+ pPrivate->bDisableReverb = LVM_TRUE;
+ }
+ else
+ {
+ pPrivate->bDisableReverb = LVM_FALSE;
+ }
+ }
+ else if (pPrivate->bFirstControl == LVM_FALSE)
+ {
+ pPrivate->BypassMixer.Target2 = 0x00000000;
+ pPrivate->BypassMixer.Target1 = 0x00000000;
+ pPrivate->BypassMixer.CallbackSet2 = LVM_TRUE;
+ pPrivate->GainMixer.Target = 0.03125f;
+ OperatingMode = LVM_MODE_ON;
+ }
+ else
+ {
+ OperatingMode = LVM_MODE_OFF;
+ }
+ }
+
+
+ /* If it is the first call to ApplyNew settings force the current to the target \
+ to begin immediate playback of the effect */
+ if(pPrivate->bFirstControl == LVM_TRUE)
+ {
+ pPrivate->BypassMixer.Current1 = pPrivate->BypassMixer.Target1;
+ pPrivate->BypassMixer.Current2 = pPrivate->BypassMixer.Target2;
+ }
+
+
+ /*
+ * Copy the new parameters
+ */
+ pPrivate->CurrentParams = pPrivate->NewParams;
+ pPrivate->CurrentParams.OperatingMode = OperatingMode;
+
+
+ /*
+ * Update flag
+ */
+ if(pPrivate->bFirstControl == LVM_TRUE)
+ {
+ pPrivate->bFirstControl = LVM_FALSE;
+ }
+
+
+ return LVREV_SUCCESS;
+}
+#endif /*BUILD_FLOAT*/
/****************************************************************************************/
/* */
/* FUNCTION: BypassMixer_Callback */
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_ClearAudioBuffers.c b/media/libeffects/lvm/lib/Reverb/src/LVREV_ClearAudioBuffers.c
index 6bb1e88..9491016 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_ClearAudioBuffers.c
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_ClearAudioBuffers.c
@@ -61,16 +61,26 @@
* Clear all filter tap data, delay-lines and other signal related data
*/
-
+#ifdef BUILD_FLOAT
+ LoadConst_Float(0,
+ (void *)&pLVREV_Private->pFastData->HPTaps, /* Destination Cast to void: \
+ no dereferencing in function*/
+ 2);
+ LoadConst_Float(0,
+ (void *)&pLVREV_Private->pFastData->LPTaps, /* Destination Cast to void: \
+ no dereferencing in function*/
+ 2);
+#else
LoadConst_32(0,
(void *)&pLVREV_Private->pFastData->HPTaps, /* Destination Cast to void: no dereferencing in function*/
2);
LoadConst_32(0,
(void *)&pLVREV_Private->pFastData->LPTaps, /* Destination Cast to void: no dereferencing in function*/
2);
-
+#endif
if((LVM_UINT16)pLVREV_Private->InstanceParams.NumDelays == LVREV_DELAYLINES_4)
{
+#ifndef BUILD_FLOAT
LoadConst_32(0, (LVM_INT32 *)&pLVREV_Private->pFastData->RevLPTaps[3], 2);
LoadConst_32(0, (LVM_INT32 *)&pLVREV_Private->pFastData->RevLPTaps[2], 2);
LoadConst_32(0, (LVM_INT32 *)&pLVREV_Private->pFastData->RevLPTaps[1], 2);
@@ -80,24 +90,46 @@
LoadConst_32(0,pLVREV_Private->pDelay_T[2], (LVM_INT16)LVREV_MAX_T2_DELAY);
LoadConst_32(0,pLVREV_Private->pDelay_T[1], (LVM_INT16)LVREV_MAX_T1_DELAY);
LoadConst_32(0,pLVREV_Private->pDelay_T[0], (LVM_INT16)LVREV_MAX_T0_DELAY);
+#else
+ LoadConst_Float(0, (LVM_FLOAT *)&pLVREV_Private->pFastData->RevLPTaps[3], 2);
+ LoadConst_Float(0, (LVM_FLOAT *)&pLVREV_Private->pFastData->RevLPTaps[2], 2);
+ LoadConst_Float(0, (LVM_FLOAT *)&pLVREV_Private->pFastData->RevLPTaps[1], 2);
+ LoadConst_Float(0, (LVM_FLOAT *)&pLVREV_Private->pFastData->RevLPTaps[0], 2);
+ LoadConst_Float(0, pLVREV_Private->pDelay_T[3], LVREV_MAX_T3_DELAY);
+ LoadConst_Float(0, pLVREV_Private->pDelay_T[2], LVREV_MAX_T2_DELAY);
+ LoadConst_Float(0, pLVREV_Private->pDelay_T[1], LVREV_MAX_T1_DELAY);
+ LoadConst_Float(0, pLVREV_Private->pDelay_T[0], LVREV_MAX_T0_DELAY);
+#endif
}
if((LVM_UINT16)pLVREV_Private->InstanceParams.NumDelays >= LVREV_DELAYLINES_2)
{
+#ifndef BUILD_FLOAT
LoadConst_32(0, (LVM_INT32 *)&pLVREV_Private->pFastData->RevLPTaps[1], 2);
LoadConst_32(0, (LVM_INT32 *)&pLVREV_Private->pFastData->RevLPTaps[0], 2);
LoadConst_32(0,pLVREV_Private->pDelay_T[1], (LVM_INT16)LVREV_MAX_T1_DELAY);
LoadConst_32(0,pLVREV_Private->pDelay_T[0], (LVM_INT16)LVREV_MAX_T0_DELAY);
+#else
+ LoadConst_Float(0, (LVM_FLOAT *)&pLVREV_Private->pFastData->RevLPTaps[1], 2);
+ LoadConst_Float(0, (LVM_FLOAT *)&pLVREV_Private->pFastData->RevLPTaps[0], 2);
+
+ LoadConst_Float(0, pLVREV_Private->pDelay_T[1], LVREV_MAX_T1_DELAY);
+ LoadConst_Float(0, pLVREV_Private->pDelay_T[0], LVREV_MAX_T0_DELAY);
+#endif
}
if((LVM_UINT16)pLVREV_Private->InstanceParams.NumDelays >= LVREV_DELAYLINES_1)
{
+#ifndef BUILD_FLOAT
LoadConst_32(0, (LVM_INT32 *)&pLVREV_Private->pFastData->RevLPTaps[0], 2);
LoadConst_32(0,pLVREV_Private->pDelay_T[0], (LVM_INT16)LVREV_MAX_T0_DELAY);
+#else
+ LoadConst_Float(0, (LVM_FLOAT *)&pLVREV_Private->pFastData->RevLPTaps[0], 2);
+ LoadConst_Float(0, pLVREV_Private->pDelay_T[0], LVREV_MAX_T0_DELAY);
+#endif
}
-
return LVREV_SUCCESS;
}
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_GetInstanceHandle.c b/media/libeffects/lvm/lib/Reverb/src/LVREV_GetInstanceHandle.c
index ffa5138..3366bcb 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_GetInstanceHandle.c
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_GetInstanceHandle.c
@@ -108,11 +108,29 @@
/*
* Zero all memory regions
*/
- LoadConst_16(0, (LVM_INT16 *)pMemoryTable->Region[LVM_PERSISTENT_SLOW_DATA].pBaseAddress, (LVM_INT16)((pMemoryTable->Region[LVM_PERSISTENT_SLOW_DATA].Size)/sizeof(LVM_INT16)));
- LoadConst_16(0, (LVM_INT16 *)pMemoryTable->Region[LVM_PERSISTENT_FAST_DATA].pBaseAddress, (LVM_INT16)((pMemoryTable->Region[LVM_PERSISTENT_FAST_DATA].Size)/sizeof(LVM_INT16)));
- LoadConst_16(0, (LVM_INT16 *)pMemoryTable->Region[LVM_PERSISTENT_FAST_COEF].pBaseAddress, (LVM_INT16)((pMemoryTable->Region[LVM_PERSISTENT_FAST_COEF].Size)/sizeof(LVM_INT16)));
- LoadConst_16(0, (LVM_INT16 *)pMemoryTable->Region[LVM_TEMPORARY_FAST].pBaseAddress, (LVM_INT16)((pMemoryTable->Region[LVM_TEMPORARY_FAST].Size)/sizeof(LVM_INT16)));
-
+#ifdef BUILD_FLOAT
+ LoadConst_Float(0,
+ (LVM_FLOAT *)pMemoryTable->Region[LVM_PERSISTENT_SLOW_DATA].pBaseAddress,
+ (LVM_INT16)((pMemoryTable->Region[LVM_PERSISTENT_SLOW_DATA].Size) / \
+ sizeof(LVM_FLOAT)));
+ LoadConst_Float(0,
+ (LVM_FLOAT *)pMemoryTable->Region[LVM_PERSISTENT_FAST_DATA].pBaseAddress,
+ (LVM_INT16)((pMemoryTable->Region[LVM_PERSISTENT_FAST_DATA].Size) / \
+ sizeof(LVM_FLOAT)));
+ LoadConst_Float(0,
+ (LVM_FLOAT *)pMemoryTable->Region[LVM_PERSISTENT_FAST_COEF].pBaseAddress,
+ (LVM_INT16)((pMemoryTable->Region[LVM_PERSISTENT_FAST_COEF].Size) / \
+ sizeof(LVM_FLOAT)));
+ LoadConst_Float(0,
+ (LVM_FLOAT *)pMemoryTable->Region[LVM_TEMPORARY_FAST].pBaseAddress,
+ (LVM_INT16)((pMemoryTable->Region[LVM_TEMPORARY_FAST].Size) / \
+ sizeof(LVM_FLOAT)));
+#else
+ LoadConst_16(0, (LVM_INT16 *)pMemoryTable->Region[LVM_PERSISTENT_SLOW_DATA].pBaseAddress, (LVM_INT16)((pMemoryTable->Region[LVM_PERSISTENT_SLOW_DATA].Size)/sizeof(LVM_INT16)));
+ LoadConst_16(0, (LVM_INT16 *)pMemoryTable->Region[LVM_PERSISTENT_FAST_DATA].pBaseAddress, (LVM_INT16)((pMemoryTable->Region[LVM_PERSISTENT_FAST_DATA].Size)/sizeof(LVM_INT16)));
+ LoadConst_16(0, (LVM_INT16 *)pMemoryTable->Region[LVM_PERSISTENT_FAST_COEF].pBaseAddress, (LVM_INT16)((pMemoryTable->Region[LVM_PERSISTENT_FAST_COEF].Size)/sizeof(LVM_INT16)));
+ LoadConst_16(0, (LVM_INT16 *)pMemoryTable->Region[LVM_TEMPORARY_FAST].pBaseAddress, (LVM_INT16)((pMemoryTable->Region[LVM_TEMPORARY_FAST].Size)/sizeof(LVM_INT16)));
+#endif
/*
* Set the instance handle if not already initialised
*/
@@ -146,7 +164,7 @@
* Set the data, coefficient and temporary memory pointers
*/
pLVREV_Private->pFastData = InstAlloc_AddMember(&FastData, sizeof(LVREV_FastData_st)); /* Fast data memory base address */
-
+#ifndef BUILD_FLOAT
if(pInstanceParams->NumDelays == LVREV_DELAYLINES_4)
{
pLVREV_Private->pDelay_T[3] = InstAlloc_AddMember(&FastData, LVREV_MAX_T3_DELAY * sizeof(LVM_INT32));
@@ -190,7 +208,67 @@
LoadConst_32(0,pLVREV_Private->pDelay_T[0] , (LVM_INT16)LVREV_MAX_T0_DELAY);
}
+#else
+ if(pInstanceParams->NumDelays == LVREV_DELAYLINES_4)
+ {
+ pLVREV_Private->pDelay_T[3] = InstAlloc_AddMember(&FastData, LVREV_MAX_T3_DELAY * \
+ sizeof(LVM_FLOAT));
+ pLVREV_Private->pDelay_T[2] = InstAlloc_AddMember(&FastData, LVREV_MAX_T2_DELAY * \
+ sizeof(LVM_FLOAT));
+ pLVREV_Private->pDelay_T[1] = InstAlloc_AddMember(&FastData, LVREV_MAX_T1_DELAY * \
+ sizeof(LVM_FLOAT));
+ pLVREV_Private->pDelay_T[0] = InstAlloc_AddMember(&FastData, LVREV_MAX_T0_DELAY * \
+ sizeof(LVM_FLOAT));
+ for(i = 0; i < 4; i++)
+ {
+ /* Scratch for each delay line output */
+ pLVREV_Private->pScratchDelayLine[i] = InstAlloc_AddMember(&Temporary,
+ sizeof(LVM_FLOAT) * \
+ MaxBlockSize);
+ }
+
+ LoadConst_Float(0, pLVREV_Private->pDelay_T[3], LVREV_MAX_T3_DELAY);
+ LoadConst_Float(0, pLVREV_Private->pDelay_T[2], LVREV_MAX_T2_DELAY);
+ LoadConst_Float(0, pLVREV_Private->pDelay_T[1], LVREV_MAX_T1_DELAY);
+ LoadConst_Float(0, pLVREV_Private->pDelay_T[0], LVREV_MAX_T0_DELAY);
+ }
+
+ if(pInstanceParams->NumDelays == LVREV_DELAYLINES_2)
+ {
+ pLVREV_Private->pDelay_T[1] = InstAlloc_AddMember(&FastData, LVREV_MAX_T1_DELAY * \
+ sizeof(LVM_FLOAT));
+ pLVREV_Private->pDelay_T[0] = InstAlloc_AddMember(&FastData, LVREV_MAX_T0_DELAY * \
+ sizeof(LVM_FLOAT));
+
+ for(i = 0; i < 2; i++)
+ {
+ /* Scratch for each delay line output */
+ pLVREV_Private->pScratchDelayLine[i] = InstAlloc_AddMember(&Temporary,
+ sizeof(LVM_FLOAT) * \
+ MaxBlockSize);
+ }
+
+ LoadConst_Float(0, pLVREV_Private->pDelay_T[1], (LVM_INT16)LVREV_MAX_T1_DELAY);
+ LoadConst_Float(0, pLVREV_Private->pDelay_T[0], (LVM_INT16)LVREV_MAX_T0_DELAY);
+ }
+
+ if(pInstanceParams->NumDelays == LVREV_DELAYLINES_1)
+ {
+ pLVREV_Private->pDelay_T[0] = InstAlloc_AddMember(&FastData,
+ LVREV_MAX_T0_DELAY * sizeof(LVM_FLOAT));
+
+ for(i = 0; i < 1; i++)
+ {
+ /* Scratch for each delay line output */
+ pLVREV_Private->pScratchDelayLine[i] = InstAlloc_AddMember(&Temporary,
+ sizeof(LVM_FLOAT) * \
+ MaxBlockSize);
+ }
+
+ LoadConst_Float(0, pLVREV_Private->pDelay_T[0], (LVM_INT16)LVREV_MAX_T0_DELAY);
+ }
+#endif
/* All-pass delay buffer addresses and sizes */
pLVREV_Private->T[0] = LVREV_MAX_T0_DELAY;
pLVREV_Private->T[1] = LVREV_MAX_T1_DELAY;
@@ -200,10 +278,19 @@
pLVREV_Private->pFastCoef = InstAlloc_AddMember(&FastCoef, sizeof(LVREV_FastCoef_st)); /* Fast coefficient memory base address */
+#ifndef BUILD_FLOAT
pLVREV_Private->pScratch = InstAlloc_AddMember(&Temporary, sizeof(LVM_INT32) * MaxBlockSize); /* General purpose scratch */
pLVREV_Private->pInputSave = InstAlloc_AddMember(&Temporary, 2 * sizeof(LVM_INT32) * MaxBlockSize); /* Mono->stereo input save for end mix */
LoadConst_32(0, pLVREV_Private->pInputSave, (LVM_INT16)(MaxBlockSize*2));
-
+#else
+ /* General purpose scratch */
+ pLVREV_Private->pScratch = InstAlloc_AddMember(&Temporary, sizeof(LVM_FLOAT) * \
+ MaxBlockSize);
+ /* Mono->stereo input save for end mix */
+ pLVREV_Private->pInputSave = InstAlloc_AddMember(&Temporary, 2 * sizeof(LVM_FLOAT) * \
+ MaxBlockSize);
+ LoadConst_Float(0, pLVREV_Private->pInputSave, (LVM_INT16)(MaxBlockSize * 2));
+#endif
/*
* Save the instance parameters in the instance structure
@@ -252,9 +339,13 @@
pLVREV_Private->GainMixer.pGeneralPurpose = LVM_NULL;
pLVREV_Private->GainMixer.pCallBack = LVM_NULL;
pLVREV_Private->GainMixer.CallbackSet = LVM_FALSE;
+#ifndef BUILD_FLOAT
pLVREV_Private->GainMixer.Current = 0x03ffffff;
pLVREV_Private->GainMixer.Target = 0x03ffffff;
-
+#else
+ pLVREV_Private->GainMixer.Current = 0.03125f;//0x03ffffff;
+ pLVREV_Private->GainMixer.Target = 0.03125f;//0x03ffffff;
+#endif
/*
* Set the All-Pass Filter mixers
@@ -277,7 +368,11 @@
pLVREV_Private->Mixer_APTaps[i].pCallBack1 = LVM_NULL;
pLVREV_Private->Mixer_APTaps[i].CallbackSet1 = LVM_FALSE;
pLVREV_Private->Mixer_APTaps[i].Current1 = 0;
+#ifndef BUILD_FLOAT
pLVREV_Private->Mixer_APTaps[i].Target1 = 0x7fffffff;
+#else
+ pLVREV_Private->Mixer_APTaps[i].Target1 = 1;
+#endif
/* Feedforward mixer */
pLVREV_Private->Mixer_SGFeedforward[i].CallbackParam = 0;
pLVREV_Private->Mixer_SGFeedforward[i].pCallbackHandle = LVM_NULL;
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_GetMemoryTable.c b/media/libeffects/lvm/lib/Reverb/src/LVREV_GetMemoryTable.c
index 2012432..f6d446b 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_GetMemoryTable.c
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_GetMemoryTable.c
@@ -161,21 +161,37 @@
InstAlloc_AddMember(&FastData, sizeof(LVREV_FastData_st));
if(pInstanceParams->NumDelays == LVREV_DELAYLINES_4)
{
+#ifndef BUILD_FLOAT
InstAlloc_AddMember(&FastData, LVREV_MAX_T3_DELAY * sizeof(LVM_INT32));
InstAlloc_AddMember(&FastData, LVREV_MAX_T2_DELAY * sizeof(LVM_INT32));
InstAlloc_AddMember(&FastData, LVREV_MAX_T1_DELAY * sizeof(LVM_INT32));
InstAlloc_AddMember(&FastData, LVREV_MAX_T0_DELAY * sizeof(LVM_INT32));
+#else
+ InstAlloc_AddMember(&FastData, LVREV_MAX_T3_DELAY * sizeof(LVM_FLOAT));
+ InstAlloc_AddMember(&FastData, LVREV_MAX_T2_DELAY * sizeof(LVM_FLOAT));
+ InstAlloc_AddMember(&FastData, LVREV_MAX_T1_DELAY * sizeof(LVM_FLOAT));
+ InstAlloc_AddMember(&FastData, LVREV_MAX_T0_DELAY * sizeof(LVM_FLOAT));
+#endif
}
if(pInstanceParams->NumDelays == LVREV_DELAYLINES_2)
{
+#ifndef BUILD_FLOAT
InstAlloc_AddMember(&FastData, LVREV_MAX_T1_DELAY * sizeof(LVM_INT32));
InstAlloc_AddMember(&FastData, LVREV_MAX_T0_DELAY * sizeof(LVM_INT32));
+#else
+ InstAlloc_AddMember(&FastData, LVREV_MAX_T1_DELAY * sizeof(LVM_FLOAT));
+ InstAlloc_AddMember(&FastData, LVREV_MAX_T0_DELAY * sizeof(LVM_FLOAT));
+#endif
}
if(pInstanceParams->NumDelays == LVREV_DELAYLINES_1)
{
+#ifndef BUILD_FLOAT
InstAlloc_AddMember(&FastData, LVREV_MAX_T0_DELAY * sizeof(LVM_INT32));
+#else
+ InstAlloc_AddMember(&FastData, LVREV_MAX_T0_DELAY * sizeof(LVM_FLOAT));
+#endif
}
pMemoryTable->Region[LVM_PERSISTENT_FAST_DATA].Size = InstAlloc_GetTotal(&FastData);
@@ -195,14 +211,25 @@
/*
* Temporary fast memory
*/
+#ifndef BUILD_FLOAT
InstAlloc_AddMember(&Temporary, sizeof(LVM_INT32) * MaxBlockSize); /* General purpose scratch memory */
InstAlloc_AddMember(&Temporary, 2*sizeof(LVM_INT32) * MaxBlockSize); /* Mono->stereo input saved for end mix */
-
+#else
+ /* General purpose scratch memory */
+ InstAlloc_AddMember(&Temporary, sizeof(LVM_FLOAT) * MaxBlockSize);
+ /* Mono->stereo input saved for end mix */
+ InstAlloc_AddMember(&Temporary, 2 * sizeof(LVM_FLOAT) * MaxBlockSize);
+#endif
if(pInstanceParams->NumDelays == LVREV_DELAYLINES_4)
{
for(i=0; i<4; i++)
{
+#ifndef BUILD_FLOAT
InstAlloc_AddMember(&Temporary, sizeof(LVM_INT32) * MaxBlockSize); /* A Scratch buffer for each delay line */
+#else
+ /* A Scratch buffer for each delay line */
+ InstAlloc_AddMember(&Temporary, sizeof(LVM_FLOAT) * MaxBlockSize);
+#endif
}
}
@@ -210,7 +237,12 @@
{
for(i=0; i<2; i++)
{
+#ifndef BUILD_FLOAT
InstAlloc_AddMember(&Temporary, sizeof(LVM_INT32) * MaxBlockSize); /* A Scratch buffer for each delay line */
+#else
+ /* A Scratch buffer for each delay line */
+ InstAlloc_AddMember(&Temporary, sizeof(LVM_FLOAT) * MaxBlockSize);
+#endif
}
}
@@ -218,7 +250,12 @@
{
for(i=0; i<1; i++)
{
+#ifndef BUILD_FLOAT
InstAlloc_AddMember(&Temporary, sizeof(LVM_INT32) * MaxBlockSize); /* A Scratch buffer for each delay line */
+#else
+ /* A Scratch buffer for each delay line */
+ InstAlloc_AddMember(&Temporary, sizeof(LVM_FLOAT) * MaxBlockSize);
+#endif
}
}
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_Private.h b/media/libeffects/lvm/lib/Reverb/src/LVREV_Private.h
index fbfa437..ff7475e 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_Private.h
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_Private.h
@@ -42,16 +42,27 @@
/* Defines */
/* */
/****************************************************************************************/
+#ifndef BUILD_FLOAT
/* General */
#define ONE_OVER_SQRT_TWO 23170 /* 1/sqrt(2) * 2^15 */
#define LVREV_B_8_on_1000 17179869 /* 0.8 * 2^31 */
#define LVREV_HEADROOM 8192 /* -12dB * 2^15 */
#define LVREV_2_9_INQ29 1583769190L /* 2.9 in Q29 format */
#define LVREV_MIN3DB 0x5A82 /* -3dB in Q15 format */
+#else
+/* General */
+#define ONE_OVER_SQRT_TWO 0.707107f /* 1/sqrt(2) * 2^15 */
+#define LVREV_B_8_on_1000 0.008f /* 0.8 * 2^31 */
+#define LVREV_HEADROOM 0.25f /* -12dB * 2^15 */
+#define LVREV_2_9_INQ29 2.9f /* 2.9 in Q29 format */
+#define LVREV_MIN3DB 0.7079457f /* -3dB in Q15 format */
+#endif
/* Intenal constants */
#define LVREV_LP_Poly_Order 4
#define LVREV_LP_Poly_Shift 5
+
+#ifndef BUILD_FLOAT
#define LVREV_T_3_Power_0_on_4 32768
#define LVREV_T_3_Power_1_on_4 43125
#define LVREV_T_3_Power_2_on_4 56755
@@ -61,14 +72,47 @@
#define LVREV_T_3_Power_minus1_on_4 24898 /* 3^(-1/4) * 2^15 */
#define LVREV_T_3_Power_minus2_on_4 18919 /* 3^(-2/4) * 2^15 */
#define LVREV_T_3_Power_minus3_on_4 14375 /* 3^(-3/4) * 2^15 */
-#define LVREV_MAX_T3_DELAY 2527 /* ((48000 * 120 * LVREV_T_3_Power_minus3_on_4) >> 15) / 1000 */
-#define LVREV_MAX_T2_DELAY 3326 /* ((48000 * 120 * LVREV_T_3_Power_minus2_on_4) >> 15) / 1000 */
-#define LVREV_MAX_T1_DELAY 4377 /* ((48000 * 120 * LVREV_T_3_Power_minus1_on_4) >> 15) / 1000 */
-#define LVREV_MAX_T0_DELAY 5760 /* ((48000 * 120 * LVREV_T_3_Power_minus0_on_4) >> 15) / 1000 */
-#define LVREV_MAX_AP3_DELAY 1685 /* ((48000 * 120 * LVREV_T_3_Power_minus3_on_4) >> 15) / 1500 */
-#define LVREV_MAX_AP2_DELAY 2218 /* ((48000 * 120 * LVREV_T_3_Power_minus2_on_4) >> 15) / 1500 */
-#define LVREV_MAX_AP1_DELAY 2918 /* ((48000 * 120 * LVREV_T_3_Power_minus1_on_4) >> 15) / 1500 */
-#define LVREV_MAX_AP0_DELAY 3840 /* ((48000 * 120 * LVREV_T_3_Power_minus0_on_4) >> 15) / 1500 */
+#else/*BUILD_FLOAT*/
+#define LVREV_T60_SCALE 0.000142f /*(1/7000) */
+
+#define LVREV_T_3_Power_0_on_4 1.0f
+#define LVREV_T_3_Power_1_on_4 1.316074f
+#define LVREV_T_3_Power_2_on_4 1.732051f
+#define LVREV_T_3_Power_3_on_4 2.279507f
+#define LVREV_T_3_Power_minus0_on_4 1.0f /* 3^(-0/4) * 2^15 */
+#define LVREV_T_3_Power_minus1_on_4 0.759836f /* 3^(-1/4) * 2^15 */
+#define LVREV_T_3_Power_minus2_on_4 0.577350f /* 3^(-2/4) * 2^15 */
+#define LVREV_T_3_Power_minus3_on_4 0.438691f /* 3^(-3/4) * 2^15 */
+#endif
+
+#ifndef HIGHER_FS
+#define LVREV_MAX_T3_DELAY 2527 /* ((48000 * 120 * LVREV_T_3_Power_minus3_on_4) >> 15) / 1000 */
+#define LVREV_MAX_T2_DELAY 3326 /* ((48000 * 120 * LVREV_T_3_Power_minus2_on_4) >> 15) / 1000 */
+#define LVREV_MAX_T1_DELAY 4377 /* ((48000 * 120 * LVREV_T_3_Power_minus1_on_4) >> 15) / 1000 */
+#define LVREV_MAX_T0_DELAY 5760 /* ((48000 * 120 * LVREV_T_3_Power_minus0_on_4) >> 15) / 1000 */
+#define LVREV_MAX_AP3_DELAY 1685 /* ((48000 * 120 * LVREV_T_3_Power_minus3_on_4) >> 15) / 1500 */
+#define LVREV_MAX_AP2_DELAY 2218 /* ((48000 * 120 * LVREV_T_3_Power_minus2_on_4) >> 15) / 1500 */
+#define LVREV_MAX_AP1_DELAY 2918 /* ((48000 * 120 * LVREV_T_3_Power_minus1_on_4) >> 15) / 1500 */
+#define LVREV_MAX_AP0_DELAY 3840 /* ((48000 * 120 * LVREV_T_3_Power_minus0_on_4) >> 15) / 1500 */
+#else
+ /* ((192000 * 120 * LVREV_T_3_Power_minus3_on_4) >> 15) / 1000 */
+#define LVREV_MAX_T3_DELAY 10108
+ /* ((192000 * 120 * LVREV_T_3_Power_minus2_on_4) >> 15) / 1000 */
+#define LVREV_MAX_T2_DELAY 13304
+ /* ((192000 * 120 * LVREV_T_3_Power_minus1_on_4) >> 15) / 1000 */
+#define LVREV_MAX_T1_DELAY 17508
+ /* ((192000 * 120 * LVREV_T_3_Power_minus0_on_4) >> 15) / 1000 */
+#define LVREV_MAX_T0_DELAY 23040
+ /* ((192000 * 120 * LVREV_T_3_Power_minus3_on_4) >> 15) / 1500 */
+#define LVREV_MAX_AP3_DELAY 6740
+ /* ((192000 * 120 * LVREV_T_3_Power_minus2_on_4) >> 15) / 1500 */
+#define LVREV_MAX_AP2_DELAY 8872
+ /* ((192000 * 120 * LVREV_T_3_Power_minus1_on_4) >> 15) / 1500 */
+#define LVREV_MAX_AP1_DELAY 11672
+ /* ((192000 * 120 * LVREV_T_3_Power_minus0_on_4) >> 15) / 1500 */
+#define LVREV_MAX_AP0_DELAY 15360
+#endif
+
#define LVREV_BYPASSMIXER_TC 1000 /* Bypass mixer time constant*/
#define LVREV_ALLPASS_TC 1000 /* All-pass filter time constant */
#define LVREV_ALLPASS_TAP_TC 10000 /* All-pass filter dely tap change */
@@ -76,7 +120,12 @@
#define LVREV_OUTPUTGAIN_SHIFT 5 /* Bits shift for output gain correction */
/* Parameter limits */
+#ifndef HIGHER_FS
#define LVREV_NUM_FS 9 /* Number of supported sample rates */
+#else
+#define LVREV_NUM_FS 11 /* Number of supported sample rates */
+#endif
+
#define LVREV_MAXBLKSIZE_LIMIT 64 /* Maximum block size low limit */
#define LVREV_MAX_LEVEL 100 /* Maximum level, 100% */
#define LVREV_MIN_LPF_CORNER 50 /* Low pass filter limits */
@@ -95,6 +144,7 @@
/* Structures */
/* */
/****************************************************************************************/
+#ifndef BUILD_FLOAT
/* Fast data structure */
typedef struct
{
@@ -161,7 +211,81 @@
} LVREV_Instance_st;
+#else /* BUILD_FLOAT */
+/* Fast data structure */
+typedef struct
+{
+ Biquad_1I_Order1_FLOAT_Taps_t HPTaps; /* High pass filter taps */
+ Biquad_1I_Order1_FLOAT_Taps_t LPTaps; /* Low pass filter taps */
+ Biquad_1I_Order1_FLOAT_Taps_t RevLPTaps[4]; /* Reverb low pass filters taps */
+
+} LVREV_FastData_st;
+
+
+/* Fast coefficient structure */
+typedef struct
+{
+
+ Biquad_FLOAT_Instance_t HPCoefs; /* High pass filter coefficients */
+ Biquad_FLOAT_Instance_t LPCoefs; /* Low pass filter coefficients */
+ Biquad_FLOAT_Instance_t RevLPCoefs[4]; /* Reverb low pass filters coefficients */
+
+} LVREV_FastCoef_st;
+typedef struct
+{
+ /* General */
+ LVREV_InstanceParams_st InstanceParams; /* Initialisation time instance parameters */
+ LVREV_MemoryTable_st MemoryTable; /* Memory table */
+ LVREV_ControlParams_st CurrentParams; /* Parameters being used */
+ LVREV_ControlParams_st NewParams; /* New parameters from the \
+ calling application */
+ LVM_CHAR bControlPending; /* Flag to indicate new parameters \
+ are available */
+ LVM_CHAR bFirstControl; /* Flag to indicate that the control \
+ function is called for the first time */
+ LVM_CHAR bDisableReverb; /* Flag to indicate that the mix level is
+ 0% and the reverb can be disabled */
+ LVM_INT32 RoomSizeInms; /* Room size in msec */
+ LVM_INT32 MaxBlkLen; /* Maximum block size for internal
+ processing */
+
+ /* Aligned memory pointers */
+ LVREV_FastData_st *pFastData; /* Fast data memory base address */
+ LVREV_FastCoef_st *pFastCoef; /* Fast coefficient memory base address */
+ LVM_FLOAT *pScratchDelayLine[4]; /* Delay line scratch memory */
+ LVM_FLOAT *pScratch; /* Multi ussge scratch */
+ LVM_FLOAT *pInputSave; /* Reverb block input save for dry/wet
+ mixing*/
+
+ /* Feedback matrix */
+ Mix_1St_Cll_FLOAT_t FeedbackMixer[4]; /* Mixer for Pop and Click Supression \
+ caused by feedback Gain */
+
+
+ /* All-Pass Filter */
+ LVM_INT32 T[4]; /* Maximum delay size of buffer */
+ LVM_FLOAT *pDelay_T[4]; /* Pointer to delay buffers */
+ LVM_INT32 Delay_AP[4]; /* Offset to AP delay buffer start */
+ LVM_INT16 AB_Selection; /* Smooth from tap A to B when 1 \
+ otherwise B to A */
+ LVM_INT32 A_DelaySize[4]; /* A delay length in samples */
+ LVM_INT32 B_DelaySize[4]; /* B delay length in samples */
+ LVM_FLOAT *pOffsetA[4]; /* Offset for the A delay tap */
+ LVM_FLOAT *pOffsetB[4]; /* Offset for the B delay tap */
+ Mix_2St_Cll_FLOAT_t Mixer_APTaps[4]; /* Smoothed AP delay mixer */
+ Mix_1St_Cll_FLOAT_t Mixer_SGFeedback[4]; /* Smoothed SAfeedback gain */
+ Mix_1St_Cll_FLOAT_t Mixer_SGFeedforward[4]; /* Smoothed AP feedforward gain */
+
+ /* Output gain */
+ Mix_2St_Cll_FLOAT_t BypassMixer; /* Dry/wet mixer */
+ LVM_FLOAT Gain; /* Gain applied to output to maintain
+ average signal power */
+ Mix_1St_Cll_FLOAT_t GainMixer; /* Gain smoothing */
+
+} LVREV_Instance_st;
+
+#endif
/****************************************************************************************/
/* */
/* Function prototypes */
@@ -169,12 +293,17 @@
/****************************************************************************************/
LVREV_ReturnStatus_en LVREV_ApplyNewSettings(LVREV_Instance_st *pPrivate);
-
+#ifdef BUILD_FLOAT
+void ReverbBlock(LVM_FLOAT *pInput,
+ LVM_FLOAT *pOutput,
+ LVREV_Instance_st *pPrivate,
+ LVM_UINT16 NumSamples);
+#else
void ReverbBlock(LVM_INT32 *pInput,
LVM_INT32 *pOutput,
LVREV_Instance_st *pPrivate,
LVM_UINT16 NumSamples);
-
+#endif
LVM_INT32 BypassMixer_Callback(void *pCallbackData,
void *pGeneralPurpose,
LVM_INT16 GeneralPurpose );
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_Process.c b/media/libeffects/lvm/lib/Reverb/src/LVREV_Process.c
index 5c7a8a0..566d84f 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_Process.c
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_Process.c
@@ -46,14 +46,26 @@
/* 1. The input and output buffers must be 32-bit aligned */
/* */
/****************************************************************************************/
+#ifdef BUILD_FLOAT
+LVREV_ReturnStatus_en LVREV_Process(LVREV_Handle_t hInstance,
+ const LVM_FLOAT *pInData,
+ LVM_FLOAT *pOutData,
+ const LVM_UINT16 NumSamples)
+#else
LVREV_ReturnStatus_en LVREV_Process(LVREV_Handle_t hInstance,
const LVM_INT32 *pInData,
LVM_INT32 *pOutData,
const LVM_UINT16 NumSamples)
+#endif
{
LVREV_Instance_st *pLVREV_Private = (LVREV_Instance_st *)hInstance;
+#ifdef BUILD_FLOAT
+ LVM_FLOAT *pInput = (LVM_FLOAT *)pInData;
+ LVM_FLOAT *pOutput = pOutData;
+#else
LVM_INT32 *pInput = (LVM_INT32 *)pInData;
LVM_INT32 *pOutput = pOutData;
+#endif
LVM_INT32 SamplesToProcess, RemainingSamples;
LVM_INT32 format = 1;
@@ -105,7 +117,7 @@
/*
* Copy the data to the output buffer, convert to stereo is required
*/
-
+#ifndef BUILD_FLOAT
if(pLVREV_Private->CurrentParams.SourceFormat == LVM_MONO){
MonoTo2I_32(pInput, pOutput, NumSamples);
} else {
@@ -113,6 +125,15 @@
(LVM_INT16 *)pOutput,
(LVM_INT16)(NumSamples << 2)); // 32 bit data, stereo
}
+#else
+ if(pLVREV_Private->CurrentParams.SourceFormat == LVM_MONO){
+ MonoTo2I_Float(pInput, pOutput, NumSamples);
+ } else {
+ Copy_Float(pInput,
+ pOutput,
+ (LVM_INT16)(NumSamples << 1)); // 32 bit data, stereo
+ }
+#endif
}
return LVREV_SUCCESS;
@@ -143,9 +164,13 @@
}
ReverbBlock(pInput, pOutput, pLVREV_Private, (LVM_UINT16)SamplesToProcess);
-
+#ifdef BUILD_FLOAT
+ pInput = (LVM_FLOAT *)(pInput + (SamplesToProcess * format));
+ pOutput = (LVM_FLOAT *)(pOutput + (SamplesToProcess * 2)); // Always stereo output
+#else
pInput = (LVM_INT32 *)(pInput +(SamplesToProcess*format));
- pOutput = (LVM_INT32 *)(pOutput+(SamplesToProcess*2)); // Always stereo output
+ pOutput = (LVM_INT32 *)(pOutput+(SamplesToProcess*2));
+#endif
}
return LVREV_SUCCESS;
@@ -175,7 +200,7 @@
/* 1. The input and output buffers must be 32-bit aligned */
/* */
/****************************************************************************************/
-
+#ifndef BUILD_FLOAT
void ReverbBlock(LVM_INT32 *pInput, LVM_INT32 *pOutput, LVREV_Instance_st *pPrivate, LVM_UINT16 NumSamples)
{
LVM_INT16 j, size;
@@ -479,7 +504,322 @@
return;
}
+#else
+void ReverbBlock(LVM_FLOAT *pInput, LVM_FLOAT *pOutput,
+ LVREV_Instance_st *pPrivate, LVM_UINT16 NumSamples)
+{
+ LVM_INT16 j, size;
+ LVM_FLOAT *pDelayLine;
+ LVM_FLOAT *pDelayLineInput = pPrivate->pScratch;
+ LVM_FLOAT *pScratch = pPrivate->pScratch;
+ LVM_FLOAT *pIn;
+ LVM_FLOAT *pTemp = pPrivate->pInputSave;
+ LVM_INT32 NumberOfDelayLines;
+
+ /******************************************************************************
+ * All calculations will go into the buffer pointed to by pTemp, this will *
+ * then be mixed with the original input to create the final output. *
+ * *
+ * When INPLACE processing is selected this must be a temporary buffer and *
+ * hence this is the worst case, so for simplicity this will ALWAYS be so *
+ * *
+ * The input buffer will remain untouched until the output of the mixer if *
+ * INPLACE processing is selected. *
+ * *
+ * The temp buffer will always be NumSamples in size regardless of MONO or *
+ * STEREO input. In the case of stereo input all processing is done in MONO *
+ * and the final output is converted to STEREO after the mixer *
+ ******************************************************************************/
+
+ if(pPrivate->InstanceParams.NumDelays == LVREV_DELAYLINES_4)
+ {
+ NumberOfDelayLines = 4;
+ }
+ else if(pPrivate->InstanceParams.NumDelays == LVREV_DELAYLINES_2)
+ {
+ NumberOfDelayLines = 2;
+ }
+ else
+ {
+ NumberOfDelayLines = 1;
+ }
+
+ if(pPrivate->CurrentParams.SourceFormat == LVM_MONO)
+ {
+ pIn = pInput;
+ }
+ else
+ {
+ /*
+ * Stereo to mono conversion
+ */
+
+ From2iToMono_Float(pInput,
+ pTemp,
+ (LVM_INT16)NumSamples);
+ pIn = pTemp;
+ }
+
+ Mult3s_Float(pIn,
+ (LVM_FLOAT)LVREV_HEADROOM,
+ pTemp,
+ (LVM_INT16)NumSamples);
+
+ /*
+ * High pass filter
+ */
+ FO_1I_D32F32C31_TRC_WRA_01(&pPrivate->pFastCoef->HPCoefs,
+ pTemp,
+ pTemp,
+ (LVM_INT16)NumSamples);
+ /*
+ * Low pass filter
+ */
+ FO_1I_D32F32C31_TRC_WRA_01(&pPrivate->pFastCoef->LPCoefs,
+ pTemp,
+ pTemp,
+ (LVM_INT16)NumSamples);
+
+ /*
+ * Process all delay lines
+ */
+
+ for(j = 0; j < NumberOfDelayLines; j++)
+ {
+ pDelayLine = pPrivate->pScratchDelayLine[j];
+
+ /*
+ * All-pass filter with pop and click suppression
+ */
+ /* Get the smoothed, delayed output. Put it in the output buffer */
+ MixSoft_2St_D32C31_SAT(&pPrivate->Mixer_APTaps[j],
+ pPrivate->pOffsetA[j],
+ pPrivate->pOffsetB[j],
+ pDelayLine,
+ (LVM_INT16)NumSamples);
+ /* Re-align the all pass filter delay buffer and copying the fixed delay data \
+ to the AP delay in the process */
+ Copy_Float(&pPrivate->pDelay_T[j][NumSamples],
+ pPrivate->pDelay_T[j],
+ (LVM_INT16)(pPrivate->T[j] - NumSamples)); /* 32-bit data */
+ /* Apply the smoothed feedback and save to fixed delay input (currently empty) */
+ MixSoft_1St_D32C31_WRA(&pPrivate->Mixer_SGFeedback[j],
+ pDelayLine,
+ &pPrivate->pDelay_T[j][pPrivate->T[j] - NumSamples],
+ (LVM_INT16)NumSamples);
+ /* Sum into the AP delay line */
+ Mac3s_Sat_Float(&pPrivate->pDelay_T[j][pPrivate->T[j] - NumSamples],
+ -1.0f, /* Invert since the feedback coefficient is negative */
+ &pPrivate->pDelay_T[j][pPrivate->Delay_AP[j] - NumSamples],
+ (LVM_INT16)NumSamples);
+ /* Apply smoothed feedforward sand save to fixed delay input (currently empty) */
+ MixSoft_1St_D32C31_WRA(&pPrivate->Mixer_SGFeedforward[j],
+ &pPrivate->pDelay_T[j][pPrivate->Delay_AP[j] - NumSamples],
+ &pPrivate->pDelay_T[j][pPrivate->T[j] - NumSamples],
+ (LVM_INT16)NumSamples);
+ /* Sum into the AP output */
+ Mac3s_Sat_Float(&pPrivate->pDelay_T[j][pPrivate->T[j] - NumSamples],
+ 1.0f,
+ pDelayLine,
+ (LVM_INT16)NumSamples);
+
+ /*
+ * Feedback gain
+ */
+ MixSoft_1St_D32C31_WRA(&pPrivate->FeedbackMixer[j], pDelayLine, pDelayLine, NumSamples);
+
+ /*
+ * Low pass filter
+ */
+ FO_1I_D32F32C31_TRC_WRA_01(&pPrivate->pFastCoef->RevLPCoefs[j],
+ pDelayLine,
+ pDelayLine,
+ (LVM_INT16)NumSamples);
+ }
+
+ /*
+ * Apply rotation matrix and delay samples
+ */
+ for(j = 0; j < NumberOfDelayLines; j++)
+ {
+
+ Copy_Float(pTemp,
+ pDelayLineInput,
+ (LVM_INT16)(NumSamples));
+ /*
+ * Rotation matrix mix
+ */
+ switch(j)
+ {
+ case 3:
+ /*
+ * Add delay line 1 and 2 contribution
+ */
+ Mac3s_Sat_Float(pPrivate->pScratchDelayLine[1], -1.0f,
+ pDelayLineInput, (LVM_INT16)NumSamples);
+ Mac3s_Sat_Float(pPrivate->pScratchDelayLine[2], -1.0f,
+ pDelayLineInput, (LVM_INT16)NumSamples);
+
+ break;
+ case 2:
+
+ /*
+ * Add delay line 0 and 3 contribution
+ */
+ Mac3s_Sat_Float(pPrivate->pScratchDelayLine[0], -1.0f,
+ pDelayLineInput, (LVM_INT16)NumSamples);
+ Mac3s_Sat_Float(pPrivate->pScratchDelayLine[3], -1.0f,
+ pDelayLineInput, (LVM_INT16)NumSamples);
+
+ break;
+ case 1:
+ if(pPrivate->InstanceParams.NumDelays == LVREV_DELAYLINES_4)
+ {
+ /*
+ * Add delay line 0 and 3 contribution
+ */
+ Mac3s_Sat_Float(pPrivate->pScratchDelayLine[0], -1.0f,
+ pDelayLineInput, (LVM_INT16)NumSamples);
+ Add2_Sat_Float(pPrivate->pScratchDelayLine[3], pDelayLineInput,
+ (LVM_INT16)NumSamples);
+
+ }
+ else
+ {
+ /*
+ * Add delay line 0 and 1 contribution
+ */
+ Mac3s_Sat_Float(pPrivate->pScratchDelayLine[0], -1.0f,
+ pDelayLineInput, (LVM_INT16)NumSamples);
+ Mac3s_Sat_Float(pPrivate->pScratchDelayLine[1], -1.0f,
+ pDelayLineInput, (LVM_INT16)NumSamples);
+
+ }
+ break;
+ case 0:
+ if(pPrivate->InstanceParams.NumDelays == LVREV_DELAYLINES_4)
+ {
+ /*
+ * Add delay line 1 and 2 contribution
+ */
+ Mac3s_Sat_Float(pPrivate->pScratchDelayLine[1], -1.0f,
+ pDelayLineInput, (LVM_INT16)NumSamples);
+ Add2_Sat_Float(pPrivate->pScratchDelayLine[2], pDelayLineInput,
+ (LVM_INT16)NumSamples);
+
+ }
+ else if(pPrivate->InstanceParams.NumDelays == LVREV_DELAYLINES_2)
+ {
+ /*
+ * Add delay line 0 and 1 contribution
+ */
+ Add2_Sat_Float(pPrivate->pScratchDelayLine[0], pDelayLineInput,
+ (LVM_INT16)NumSamples);
+ Mac3s_Sat_Float(pPrivate->pScratchDelayLine[1], -1.0f,
+ pDelayLineInput, (LVM_INT16)NumSamples);
+
+ }
+ else
+ {
+ /*
+ * Add delay line 0 contribution
+ */
+
+ /* SOURCE DESTINATION*/
+ Add2_Sat_Float(pPrivate->pScratchDelayLine[0], pDelayLineInput,
+ (LVM_INT16)NumSamples);
+ }
+ break;
+ default:
+ break;
+ }
+
+ /*
+ * Delay samples
+ */
+ Copy_Float(pDelayLineInput,
+ &pPrivate->pDelay_T[j][pPrivate->T[j] - NumSamples],
+ (LVM_INT16)(NumSamples)); /* 32-bit data */
+ }
+ /*
+ * Create stereo output
+ */
+ switch(pPrivate->InstanceParams.NumDelays)
+ {
+ case LVREV_DELAYLINES_4:
+ Add2_Sat_Float(pPrivate->pScratchDelayLine[3],
+ pPrivate->pScratchDelayLine[0],
+ (LVM_INT16)NumSamples);
+ Add2_Sat_Float(pPrivate->pScratchDelayLine[2],
+ pPrivate->pScratchDelayLine[1],
+ (LVM_INT16)NumSamples);
+
+
+ JoinTo2i_Float(pPrivate->pScratchDelayLine[0],
+ pPrivate->pScratchDelayLine[1],
+ pTemp,
+ (LVM_INT16)NumSamples);
+
+
+ break;
+ case LVREV_DELAYLINES_2:
+
+ Copy_Float(pPrivate->pScratchDelayLine[1],
+ pScratch,
+ (LVM_INT16)(NumSamples));
+
+ Mac3s_Sat_Float(pPrivate->pScratchDelayLine[0],
+ -1.0f,
+ pScratch,
+ (LVM_INT16)NumSamples);
+
+ Add2_Sat_Float(pPrivate->pScratchDelayLine[1],
+ pPrivate->pScratchDelayLine[0],
+ (LVM_INT16)NumSamples);
+
+
+ JoinTo2i_Float(pPrivate->pScratchDelayLine[0],
+ pScratch,
+ pTemp,
+ (LVM_INT16)NumSamples);
+ break;
+ case LVREV_DELAYLINES_1:
+ MonoTo2I_Float(pPrivate->pScratchDelayLine[0],
+ pTemp,
+ (LVM_INT16)NumSamples);
+ break;
+ default:
+ break;
+ }
+
+
+ /*
+ * Dry/wet mixer
+ */
+
+ size = (LVM_INT16)(NumSamples << 1);
+ MixSoft_2St_D32C31_SAT(&pPrivate->BypassMixer,
+ pTemp,
+ pTemp,
+ pOutput,
+ size);
+
+ /* Apply Gain*/
+
+ Shift_Sat_Float(LVREV_OUTPUTGAIN_SHIFT,
+ pOutput,
+ pOutput,
+ size);
+
+ MixSoft_1St_D32C31_WRA(&pPrivate->GainMixer,
+ pOutput,
+ pOutput,
+ size);
+
+ return;
+}
+#endif
/* End of file */
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_SetControlParameters.c b/media/libeffects/lvm/lib/Reverb/src/LVREV_SetControlParameters.c
index f5895a7..a719053 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_SetControlParameters.c
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_SetControlParameters.c
@@ -61,10 +61,15 @@
* Check all new control parameters are in range
*/
if( ((pNewParams->OperatingMode != LVM_MODE_OFF) && (pNewParams->OperatingMode != LVM_MODE_ON)) ||
- ((pNewParams->SampleRate != LVM_FS_8000) && (pNewParams->SampleRate != LVM_FS_11025) && (pNewParams->SampleRate != LVM_FS_12000) &&
+ (
+ (pNewParams->SampleRate != LVM_FS_8000) && (pNewParams->SampleRate != LVM_FS_11025) && (pNewParams->SampleRate != LVM_FS_12000) &&
(pNewParams->SampleRate != LVM_FS_16000) && (pNewParams->SampleRate != LVM_FS_22050) && (pNewParams->SampleRate != LVM_FS_24000) &&
- (pNewParams->SampleRate != LVM_FS_32000) && (pNewParams->SampleRate != LVM_FS_44100) && (pNewParams->SampleRate != LVM_FS_48000)) ||
- ((pNewParams->SourceFormat != LVM_STEREO) && (pNewParams->SourceFormat != LVM_MONOINSTEREO) && (pNewParams->SourceFormat != LVM_MONO)) )
+ (pNewParams->SampleRate != LVM_FS_32000) && (pNewParams->SampleRate != LVM_FS_44100) && (pNewParams->SampleRate != LVM_FS_48000)
+#ifdef HIGHER_FS
+ && (pNewParams->SampleRate != LVM_FS_96000) && (pNewParams->SampleRate != LVM_FS_192000)
+#endif
+ )
+ || ((pNewParams->SourceFormat != LVM_STEREO) && (pNewParams->SourceFormat != LVM_MONOINSTEREO) && (pNewParams->SourceFormat != LVM_MONO)) )
{
return (LVREV_OUTOFRANGE);
}
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_Tables.c b/media/libeffects/lvm/lib/Reverb/src/LVREV_Tables.c
index 5a6d43d..b3edc60 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_Tables.c
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_Tables.c
@@ -29,6 +29,7 @@
/****************************************************************************************/
/* Table with supported sampling rates. The table can be indexed using LVM_Fs_en */
+#ifndef HIGHER_FS
const LVM_UINT16 LVM_FsTable[] = {
8000 ,
11025,
@@ -40,14 +41,37 @@
44100,
48000
};
-
+#else
+const LVM_UINT32 LVM_FsTable[] = {
+ 8000 ,
+ 11025,
+ 12000,
+ 16000,
+ 22050,
+ 24000,
+ 32000,
+ 44100,
+ 48000,
+ 96000,
+ 192000
+};
+#endif
/* Table with supported sampling rates. The table can be indexed using LVM_Fs_en */
+#ifndef HIGHER_FS
LVM_UINT16 LVM_GetFsFromTable(LVM_Fs_en FsIndex){
if (FsIndex > LVM_FS_48000)
return 0;
return (LVM_FsTable[FsIndex]);
}
+#else
+LVM_UINT32 LVM_GetFsFromTable(LVM_Fs_en FsIndex){
+ if (FsIndex > LVM_FS_192000)
+ return 0;
+
+ return (LVM_FsTable[FsIndex]);
+}
+#endif
/* In order to maintain consistant input and out put signal strengths
output gain/attenuation is applied. This gain depends on T60 and Rooms
@@ -69,6 +93,7 @@
*/
/* Normalizing output including Reverb Level part (only shift up)*/
+#ifndef BUILD_FLOAT
const LVM_INT32 LVREV_GainPolyTable[24][5]={{1,17547434,128867434,-120988896,50761228,},
{2,18256869,172666902,-193169292,88345744,},
{3,16591311,139250151,-149667234,66770059,},
@@ -94,6 +119,32 @@
{90,16003322,48323661,-35607378,13153872,},
{100,15955223,48558201,-33706865,11715792,},
};
-
+#else
+const LVM_FLOAT LVREV_GainPolyTable[24][5]={{1,1.045909f,7.681098f,-7.211500f,3.025605f,},
+ {2,1.088194f,10.291749f,-11.513787f,5.265817f,},
+ {3,0.988919f,8.299956f,-8.920862f,3.979806f,},
+ {4,1.035927f,10.182567f,-10.346134f,4.546533f,},
+ {5,1.130313f,12.538727f,-13.627023f,6.165208f,},
+ {6,1.060743f,8.091713f,-8.588079f,3.834230f,},
+ {7,1.040381f,10.406566f,-11.176650f,5.075132f,},
+ {8,1.026944f,8.387302f,-8.689796f,3.895863f,},
+ {9,1.013312f,9.727236f,-10.534165f,4.742272f,},
+ {10,0.996095f,8.492249f,-7.947677f,3.478917f,},
+ {13,1.079346f,8.894425f,-9.641768f,4.434442f,},
+ {15,0.994327f,7.441335f,-8.003979f,3.581177f,},
+ {17,0.991067f,7.208373f,-7.257859f,3.167774f,},
+ {20,1.033445f,7.476371f,-7.546960f,3.369703f,},
+ {25,0.982830f,5.913867f,-5.638448f,2.420932f,},
+ {30,0.928782f,5.035343f,-4.492104f,1.844904f,},
+ {40,0.953714f,5.060232f,-4.472204f,1.829642f,},
+ {50,0.899258f,4.273357f,-3.537492f,1.387576f,},
+ {60,0.943584f,4.093228f,-3.469658f,1.410911f,},
+ {70,0.926021f,3.973125f,-3.331985f,1.344690f,},
+ {75,0.894853f,2.871747f,-1.438758f,0.311856f,},
+ {80,0.935122f,2.991857f,-2.038882f,0.686395f,},
+ {90,0.953872f,2.880315f,-2.122365f,0.784032f,},
+ {100,0.951005f,2.894294f,-2.009086f,0.698316f,},
+};
+#endif
/* End of file */
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_Tables.h b/media/libeffects/lvm/lib/Reverb/src/LVREV_Tables.h
index 5f993bd..0658186 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_Tables.h
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_Tables.h
@@ -37,10 +37,19 @@
/* */
/****************************************************************************************/
+#ifndef HIGHER_FS
extern const LVM_UINT16 LVM_FsTable[];
extern LVM_UINT16 LVM_GetFsFromTable(LVM_Fs_en FsIndex);
-extern LVM_INT32 LVREV_GainPolyTable[24][5];
+#else
+extern const LVM_UINT32 LVM_FsTable[];
+extern LVM_UINT32 LVM_GetFsFromTable(LVM_Fs_en FsIndex);
+#endif
+#ifndef BUILD_FLOAT
+extern LVM_INT32 LVREV_GainPolyTable[24][5];
+#else
+extern LVM_FLOAT LVREV_GainPolyTable[24][5];
+#endif
#ifdef __cplusplus
}
#endif
diff --git a/media/libeffects/lvm/lib/SpectrumAnalyzer/lib/LVPSA.h b/media/libeffects/lvm/lib/SpectrumAnalyzer/lib/LVPSA.h
index a675cb2..2038fbb 100644
--- a/media/libeffects/lvm/lib/SpectrumAnalyzer/lib/LVPSA.h
+++ b/media/libeffects/lvm/lib/SpectrumAnalyzer/lib/LVPSA.h
@@ -216,11 +216,17 @@
/* otherwise Error due to bad parameters */
/* */
/*********************************************************************************************************************************/
+#ifdef BUILD_FLOAT
+LVPSA_RETURN LVPSA_Process ( pLVPSA_Handle_t hInstance,
+ LVM_FLOAT *pLVPSA_InputSamples,
+ LVM_UINT16 InputBlockSize,
+ LVPSA_Time AudioTime );
+#else
LVPSA_RETURN LVPSA_Process ( pLVPSA_Handle_t hInstance,
LVM_INT16 *pLVPSA_InputSamples,
LVM_UINT16 InputBlockSize,
LVPSA_Time AudioTime );
-
+#endif
/*********************************************************************************************************************************/
/* */
/* FUNCTION: LVPSA_GetSpectrum */
diff --git a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Control.c b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Control.c
index cd5f69c..f6c4ea7 100644
--- a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Control.c
+++ b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Control.c
@@ -28,6 +28,15 @@
LVPSA_RETURN LVPSA_SetQPFCoefficients( LVPSA_InstancePr_t *pInst,
LVPSA_ControlParams_t *pParams );
+#ifdef BUILD_FLOAT
+LVPSA_RETURN LVPSA_BPSinglePrecCoefs( LVM_UINT16 Fs,
+ LVPSA_FilterParam_t *pFilterParams,
+ BP_FLOAT_Coefs_t *pCoefficients);
+
+LVPSA_RETURN LVPSA_BPDoublePrecCoefs( LVM_UINT16 Fs,
+ LVPSA_FilterParam_t *pFilterParams,
+ BP_FLOAT_Coefs_t *pCoefficients);
+#else
LVPSA_RETURN LVPSA_BPSinglePrecCoefs( LVM_UINT16 Fs,
LVPSA_FilterParam_t *pFilterParams,
BP_C16_Coefs_t *pCoefficients);
@@ -39,7 +48,7 @@
LVPSA_RETURN LVPSA_BPDoublePrecCoefs( LVM_UINT16 Fs,
LVPSA_FilterParam_t *pFilterParams,
BP_C32_Coefs_t *pCoefficients);
-
+#endif
LVPSA_RETURN LVPSA_SetBPFCoefficients( LVPSA_InstancePr_t *pInst,
LVPSA_ControlParams_t *pParams );
@@ -179,7 +188,11 @@
LVM_UINT16 Freq;
LVPSA_ControlParams_t Params;
extern LVM_INT16 LVPSA_nSamplesBufferUpdate[];
+#ifndef HIGHER_FS
extern LVM_UINT16 LVPSA_SampleRateTab[];
+#else
+ extern LVM_UINT32 LVPSA_SampleRateTab[];
+#endif
extern LVM_UINT16 LVPSA_DownSamplingFactor[];
@@ -267,8 +280,11 @@
LVPSA_RETURN LVPSA_SetBPFiltersType ( LVPSA_InstancePr_t *pInst,
LVPSA_ControlParams_t *pParams )
{
-
+#ifndef HIGHER_FS
extern LVM_UINT16 LVPSA_SampleRateTab[]; /* Sample rate table */
+#else
+ extern LVM_UINT32 LVPSA_SampleRateTab[]; /* Sample rate table */
+#endif
LVM_UINT16 ii; /* Filter band index */
LVM_UINT32 fs = (LVM_UINT32)LVPSA_SampleRateTab[(LVM_UINT16)pParams->Fs]; /* Sample rate */
LVM_UINT32 fc; /* Filter centre frequency */
@@ -342,26 +358,42 @@
{
case LVPSA_DoublePrecisionFilter:
{
+#ifndef BUILD_FLOAT
BP_C32_Coefs_t Coefficients;
/*
* Calculate the double precision coefficients
*/
LVPSA_BPDoublePrecCoefs((LVM_UINT16)pParams->Fs,
- &pInst->pFiltersParams[ii],
- &Coefficients);
-
+ &pInst->pFiltersParams[ii],
+ &Coefficients);
/*
* Set the coefficients
*/
BP_1I_D16F32Cll_TRC_WRA_01_Init ( &pInst->pBP_Instances[ii],
&pInst->pBP_Taps[ii],
&Coefficients);
+#else
+ BP_FLOAT_Coefs_t Coefficients;
+ /*
+ * Calculate the double precision coefficients
+ */
+ LVPSA_BPDoublePrecCoefs((LVM_UINT16)pParams->Fs,
+ &pInst->pFiltersParams[ii],
+ &Coefficients);
+ /*
+ * Set the coefficients
+ */
+ BP_1I_D16F32Cll_TRC_WRA_01_Init ( &pInst->pBP_Instances[ii],
+ &pInst->pBP_Taps[ii],
+ &Coefficients);
+#endif
break;
}
case LVPSA_SimplePrecisionFilter:
{
+#ifndef BUILD_FLOAT
BP_C16_Coefs_t Coefficients;
/*
@@ -374,9 +406,26 @@
/*
* Set the coefficients
*/
- BP_1I_D16F16Css_TRC_WRA_01_Init ( &pInst->pBP_Instances[ii],
+ BP_1I_D16F16Css_TRC_WRA_01_Init (&pInst->pBP_Instances[ii],
&pInst->pBP_Taps[ii],
&Coefficients);
+#else
+ BP_FLOAT_Coefs_t Coefficients;
+
+ /*
+ * Calculate the single precision coefficients
+ */
+ LVPSA_BPSinglePrecCoefs((LVM_UINT16)pParams->Fs,
+ &pInst->pFiltersParams[ii],
+ &Coefficients);
+
+ /*
+ * Set the coefficients
+ */
+ BP_1I_D16F16Css_TRC_WRA_01_Init (&pInst->pBP_Instances[ii],
+ &pInst->pBP_Taps[ii],
+ &Coefficients);
+#endif
break;
}
}
@@ -409,18 +458,31 @@
{
LVM_UINT16 ii;
LVM_Fs_en Fs = pParams->Fs;
+#ifndef BUILD_FLOAT
QPD_C32_Coefs *pCoefficients;
extern QPD_C32_Coefs LVPSA_QPD_Coefs[];
-
pCoefficients = &LVPSA_QPD_Coefs[(pParams->LevelDetectionSpeed * LVPSA_NR_SUPPORTED_RATE) + Fs];
+#else
+ QPD_FLOAT_Coefs *pCoefficients;
+ extern QPD_FLOAT_Coefs LVPSA_QPD_Float_Coefs[];
+
+ pCoefficients = &LVPSA_QPD_Float_Coefs[(pParams->LevelDetectionSpeed * \
+ LVPSA_NR_SUPPORTED_RATE) + Fs];
+#endif
for (ii = 0; ii < pInst->nRelevantFilters; ii++)
{
- LVPSA_QPD_Init (&pInst->pQPD_States[ii],
- &pInst->pQPD_Taps[ii],
- pCoefficients );
+#ifndef BUILD_FLOAT
+ LVPSA_QPD_Init (&pInst->pQPD_States[ii],
+ &pInst->pQPD_Taps[ii],
+ pCoefficients );
+#else
+ LVPSA_QPD_Init_Float (&pInst->pQPD_States[ii],
+ &pInst->pQPD_Taps[ii],
+ pCoefficients );
+#endif
}
return(LVPSA_OK);
@@ -460,6 +522,87 @@
/* of the n bands equalizer (LVEQNB */
/* */
/****************************************************************************************/
+#ifdef BUILD_FLOAT
+LVPSA_RETURN LVPSA_BPSinglePrecCoefs( LVM_UINT16 Fs,
+ LVPSA_FilterParam_t *pFilterParams,
+ BP_FLOAT_Coefs_t *pCoefficients)
+{
+
+ extern LVM_FLOAT LVPSA_Float_TwoPiOnFsTable[];
+ extern LVM_FLOAT LVPSA_Float_CosCoef[];
+
+
+ /*
+ * Intermediate variables and temporary values
+ */
+ LVM_FLOAT T0;
+ LVM_FLOAT D;
+ LVM_FLOAT A0;
+ LVM_FLOAT B1;
+ LVM_FLOAT B2;
+ LVM_FLOAT Dt0;
+ LVM_FLOAT B2_Den;
+ LVM_FLOAT B2_Num;
+ LVM_FLOAT COS_T0;
+ LVM_FLOAT coef;
+ LVM_FLOAT factor;
+ LVM_FLOAT t0;
+ LVM_INT16 i;
+
+
+ /*
+ * Get the filter definition
+ */
+ LVM_FLOAT Frequency = (LVM_FLOAT)(pFilterParams->CenterFrequency);
+ LVM_FLOAT QFactor = ((LVM_FLOAT)(pFilterParams->QFactor)) / 100;
+
+ /*
+ * Calculating the intermediate values
+ */
+ T0 = Frequency * LVPSA_Float_TwoPiOnFsTable[Fs]; /* T0 = 2 * Pi * Fc / Fs */
+ D = 3200; /* Floating point value 1.000000 (1*100*2^5) */
+ /* Force D = 1 : the function was originally used for a peaking filter.
+ The D parameter do not exist for a BandPass filter coefficients */
+
+ /*
+ * Calculate the B2 coefficient
+ */
+ Dt0 = T0 / 2048 ;
+ B2_Den = QFactor + Dt0;
+ B2_Num = Dt0 - QFactor;
+ B2 = B2_Num / (2 * B2_Den);
+
+ /*
+ * Calculate the cosine by a polynomial expansion using the equation:
+ *
+ * Cos += coef(n) * t0^n For n = 0 to 6
+ */
+ T0 = (T0 / 2048) * 0.63658558f; /* Scale to 1.0 in 16-bit for range 0 to fs/2 */
+ t0 = T0 ;
+ factor = 1.0f; /* Initialise to 1.0 for the a0 coefficient */
+ COS_T0 = 0.0f; /* Initialise the error to zero */
+ for (i = 1; i < 7; i++)
+ {
+ coef = LVPSA_Float_CosCoef[i]; /* Get the nth coefficient */
+ COS_T0 += (factor * coef); /* The nth partial sum */
+ factor = (factor * t0) ; /* Calculate t0^n */
+ }
+ COS_T0 = COS_T0 * 8; /*LVPSA_CosCoef_float[0]*/ /* Correct the scaling */
+
+
+ B1 = ((LVM_FLOAT)0.5 - B2) * (COS_T0); /* B1 = (0.5 - b2) * cos(t0) */
+ A0 = ((LVM_FLOAT)0.5 + B2) / 2; /* A0 = (0.5 + b2) / 2 */
+
+ /*
+ * Write coeff into the data structure
+ */
+ pCoefficients->A0 = A0 * 2;
+ pCoefficients->B1 = B1 * 2;
+ pCoefficients->B2 = B2 * 2;
+
+ return(LVPSA_OK);
+}
+#else
LVPSA_RETURN LVPSA_BPSinglePrecCoefs( LVM_UINT16 Fs,
LVPSA_FilterParam_t *pFilterParams,
BP_C16_Coefs_t *pCoefficients)
@@ -541,7 +684,7 @@
return(LVPSA_OK);
}
-
+#endif
/****************************************************************************************/
/* */
/* FUNCTION: LVPSA_BPDoublePrecCoefs */
@@ -584,6 +727,90 @@
/* of the n bands equalizer (LVEQNB */
/* */
/****************************************************************************************/
+#ifdef BUILD_FLOAT
+LVPSA_RETURN LVPSA_BPDoublePrecCoefs( LVM_UINT16 Fs,
+ LVPSA_FilterParam_t *pFilterParams,
+ BP_FLOAT_Coefs_t *pCoefficients)
+{
+
+ extern LVM_FLOAT LVPSA_Float_TwoPiOnFsTable[];
+ extern LVM_FLOAT LVPSA_Float_DPCosCoef[];
+
+ /*
+ * Intermediate variables and temporary values
+ */
+ LVM_FLOAT T0;
+ LVM_FLOAT D;
+ LVM_FLOAT A0;
+ LVM_FLOAT B1;
+ LVM_FLOAT B2;
+ LVM_FLOAT Dt0;
+ LVM_FLOAT B2_Den;
+ LVM_FLOAT B2_Num;
+ LVM_FLOAT CosErr;
+ LVM_FLOAT coef;
+ LVM_FLOAT factor;
+ LVM_FLOAT t0;
+ LVM_INT16 i;
+
+ /*
+ * Get the filter definition
+ */
+ LVM_FLOAT Frequency = (LVM_FLOAT)(pFilterParams->CenterFrequency);
+ LVM_FLOAT QFactor = ((LVM_FLOAT)(pFilterParams->QFactor)) / 100;
+
+
+ /*
+ * Calculating the intermediate values
+ */
+ T0 = Frequency * LVPSA_Float_TwoPiOnFsTable[Fs]; /* T0 = 2 * Pi * Fc / Fs */
+ D = 3200; /* Floating point value 1.000000 (1*100*2^5) */
+ /* Force D = 1 : the function was originally used for a peaking filter.
+ The D parameter do not exist for a BandPass filter coefficients */
+
+ /*
+ * Calculate the B2 coefficient
+ */
+ Dt0 = T0 / 2048 ;
+ B2_Den = QFactor + Dt0;
+ B2_Num = Dt0 - QFactor;
+ B2 = B2_Num / (2 * B2_Den);
+
+ /*
+ * Calculate the cosine error by a polynomial expansion using the equation:
+ *
+ * CosErr += coef(n) * t0^n For n = 0 to 4
+ */
+ T0 = T0 * 0.994750f; /* Scale to 1.0 in 16-bit for range 0 to fs/50 */
+ t0 = T0;
+ factor = 1.0f; /* Initialise to 1.0 for the a0 coefficient */
+ CosErr = 0.0f; /* Initialise the error to zero */
+ for (i = 1; i < 5; i++)
+ {
+ coef = LVPSA_Float_DPCosCoef[i]; /* Get the nth coefficient */
+ CosErr += factor * coef; /* The nth partial sum */
+ factor = factor * t0; /* Calculate t0^n */
+ }
+ CosErr = CosErr * 2; /* Correct the scaling */
+
+ /*
+ * Calculate the B1 and A0 coefficients
+ */
+ B1 = ((LVM_FLOAT)0.5 - B2); /* B1 = (0.5 - b2) */
+ A0 = B1 * CosErr ; /* Temporary storage for (0.5 - b2) * coserr(t0) */
+ B1 -= A0; /* B1 = (0.5 - b2) * (1 - coserr(t0)) */
+ A0 = ((LVM_FLOAT)0.5 + B2) / 2; /* A0 = (0.5 + b2) / 2 */
+
+ /*
+ * Write coeff into the data structure
+ */
+ pCoefficients->A0 = A0;
+ pCoefficients->B1 = B1;
+ pCoefficients->B2 = B2;
+
+ return(LVPSA_OK);
+}
+#else
LVPSA_RETURN LVPSA_BPDoublePrecCoefs( LVM_UINT16 Fs,
LVPSA_FilterParam_t *pFilterParams,
BP_C32_Coefs_t *pCoefficients)
@@ -666,7 +893,7 @@
return(LVPSA_OK);
}
-
+#endif
/************************************************************************************/
/* */
/* FUNCTION: LVPSA_ClearFilterHistory */
@@ -690,11 +917,17 @@
/* Band Pass filters taps */
pTapAddress = (LVM_INT8 *)pInst->pBP_Taps;
+#ifdef BUILD_FLOAT
+ for(i = 0; i < pInst->nBands * sizeof(Biquad_1I_Order2_FLOAT_Taps_t); i++)
+ {
+ pTapAddress[i] = 0;
+ }
+#else
for(i = 0; i < pInst->nBands * sizeof(Biquad_1I_Order2_Taps_t); i++)
{
pTapAddress[i] = 0;
}
-
+#endif
/* Quasi-peak filters taps */
pTapAddress = (LVM_INT8 *)pInst->pQPD_Taps;
for(i = 0; i < pInst->nBands * sizeof(QPD_Taps_t); i++)
diff --git a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Init.c b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Init.c
index 27a4bc3..1c26860 100644
--- a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Init.c
+++ b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Init.c
@@ -47,7 +47,11 @@
LVPSA_InstancePr_t *pLVPSA_Inst;
LVPSA_RETURN errorCode = LVPSA_OK;
LVM_UINT32 ii;
+#ifndef BUILD_FLOAT
extern LVM_INT16 LVPSA_GainTable[];
+#else
+ extern LVM_FLOAT LVPSA_Float_GainTable[];
+#endif
LVM_UINT32 BufferLength = 0;
/* Ints_Alloc instances, needed for memory alignment management */
@@ -141,19 +145,37 @@
/* Assign the pointers */
-
+#ifndef BUILD_FLOAT
pLVPSA_Inst->pPostGains = InstAlloc_AddMember( &Instance, pInitParams->nBands * sizeof(LVM_UINT16) );
+#else
+ pLVPSA_Inst->pPostGains = InstAlloc_AddMember( &Instance, pInitParams->nBands * \
+ sizeof(LVM_FLOAT) );
+#endif
pLVPSA_Inst->pFiltersParams = InstAlloc_AddMember( &Instance, pInitParams->nBands * sizeof(LVPSA_FilterParam_t) );
pLVPSA_Inst->pSpectralDataBufferStart = InstAlloc_AddMember( &Instance, pInitParams->nBands * pLVPSA_Inst->SpectralDataBufferLength * sizeof(LVM_UINT8) );
pLVPSA_Inst->pPreviousPeaks = InstAlloc_AddMember( &Instance, pInitParams->nBands * sizeof(LVM_UINT8) );
pLVPSA_Inst->pBPFiltersPrecision = InstAlloc_AddMember( &Instance, pInitParams->nBands * sizeof(LVPSA_BPFilterPrecision_en) );
-
+#ifndef BUILD_FLOAT
pLVPSA_Inst->pBP_Instances = InstAlloc_AddMember( &Coef, pInitParams->nBands * sizeof(Biquad_Instance_t) );
pLVPSA_Inst->pQPD_States = InstAlloc_AddMember( &Coef, pInitParams->nBands * sizeof(QPD_State_t) );
+#else
+ pLVPSA_Inst->pBP_Instances = InstAlloc_AddMember( &Coef, pInitParams->nBands * \
+ sizeof(Biquad_FLOAT_Instance_t) );
+ pLVPSA_Inst->pQPD_States = InstAlloc_AddMember( &Coef, pInitParams->nBands * \
+ sizeof(QPD_FLOAT_State_t) );
+#endif
+#ifndef BUILD_FLOAT
pLVPSA_Inst->pBP_Taps = InstAlloc_AddMember( &Data, pInitParams->nBands * sizeof(Biquad_1I_Order2_Taps_t) );
pLVPSA_Inst->pQPD_Taps = InstAlloc_AddMember( &Data, pInitParams->nBands * sizeof(QPD_Taps_t) );
+#else
+ pLVPSA_Inst->pBP_Taps = InstAlloc_AddMember( &Data,
+ pInitParams->nBands * \
+ sizeof(Biquad_1I_Order2_FLOAT_Taps_t));
+ pLVPSA_Inst->pQPD_Taps = InstAlloc_AddMember( &Data, pInitParams->nBands * \
+ sizeof(QPD_FLOAT_Taps_t) );
+#endif
/* Copy filters parameters in the private instance */
for(ii = 0; ii < pLVPSA_Inst->nBands; ii++)
@@ -164,7 +186,12 @@
/* Set Post filters gains*/
for(ii = 0; ii < pLVPSA_Inst->nBands; ii++)
{
+#ifndef BUILD_FLOAT
pLVPSA_Inst->pPostGains[ii] =(LVM_UINT16) LVPSA_GainTable[pInitParams->pFiltersParams[ii].PostGain + 15];
+#else
+ pLVPSA_Inst->pPostGains[ii] = LVPSA_Float_GainTable[15 + \
+ pInitParams->pFiltersParams[ii].PostGain];
+#endif
}
pLVPSA_Inst->pSpectralDataBufferWritePointer = pLVPSA_Inst->pSpectralDataBufferStart;
diff --git a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Memory.c b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Memory.c
index 0984b10..06a8f9d 100644
--- a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Memory.c
+++ b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Memory.c
@@ -106,7 +106,11 @@
*/
InstAlloc_AddMember( &Instance, sizeof(LVPSA_InstancePr_t) );
+#ifdef BUILD_FLOAT
+ InstAlloc_AddMember( &Instance, pInitParams->nBands * sizeof(LVM_FLOAT) );
+#else
InstAlloc_AddMember( &Instance, pInitParams->nBands * sizeof(LVM_UINT16) );
+#endif
InstAlloc_AddMember( &Instance, pInitParams->nBands * sizeof(LVPSA_FilterParam_t) );
{
@@ -134,7 +138,11 @@
/*
* Scratch memory
*/
+#ifndef BUILD_FLOAT
InstAlloc_AddMember( &Scratch, 2 * pInitParams->MaxInputBlockSize * sizeof(LVM_INT16) );
+#else
+ InstAlloc_AddMember( &Scratch, 2 * pInitParams->MaxInputBlockSize * sizeof(LVM_FLOAT) );
+#endif
pMemoryTable->Region[LVPSA_MEMREGION_SCRATCH].Size = InstAlloc_GetTotal(&Scratch);
pMemoryTable->Region[LVPSA_MEMREGION_SCRATCH].Type = LVPSA_SCRATCH;
pMemoryTable->Region[LVPSA_MEMREGION_SCRATCH].pBaseAddress = LVM_NULL;
@@ -142,8 +150,13 @@
/*
* Persistent coefficients memory
*/
+#ifndef BUILD_FLOAT
InstAlloc_AddMember( &Coef, pInitParams->nBands * sizeof(Biquad_Instance_t) );
InstAlloc_AddMember( &Coef, pInitParams->nBands * sizeof(QPD_State_t) );
+#else
+ InstAlloc_AddMember( &Coef, pInitParams->nBands * sizeof(Biquad_FLOAT_Instance_t) );
+ InstAlloc_AddMember( &Coef, pInitParams->nBands * sizeof(QPD_FLOAT_State_t) );
+#endif
pMemoryTable->Region[LVPSA_MEMREGION_PERSISTENT_COEF].Size = InstAlloc_GetTotal(&Coef);
pMemoryTable->Region[LVPSA_MEMREGION_PERSISTENT_COEF].Type = LVPSA_PERSISTENT_COEF;
pMemoryTable->Region[LVPSA_MEMREGION_PERSISTENT_COEF].pBaseAddress = LVM_NULL;
@@ -151,8 +164,13 @@
/*
* Persistent data memory
*/
+#ifndef BUILD_FLOAT
InstAlloc_AddMember( &Data, pInitParams->nBands * sizeof(Biquad_1I_Order2_Taps_t) );
InstAlloc_AddMember( &Data, pInitParams->nBands * sizeof(QPD_Taps_t) );
+#else
+ InstAlloc_AddMember( &Data, pInitParams->nBands * sizeof(Biquad_1I_Order2_FLOAT_Taps_t) );
+ InstAlloc_AddMember( &Data, pInitParams->nBands * sizeof(QPD_FLOAT_Taps_t) );
+#endif
pMemoryTable->Region[LVPSA_MEMREGION_PERSISTENT_DATA].Size = InstAlloc_GetTotal(&Data);
pMemoryTable->Region[LVPSA_MEMREGION_PERSISTENT_DATA].Type = LVPSA_PERSISTENT_DATA;
pMemoryTable->Region[LVPSA_MEMREGION_PERSISTENT_DATA].pBaseAddress = LVM_NULL;
diff --git a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Private.h b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Private.h
index 03522fb..a750bb0 100644
--- a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Private.h
+++ b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Private.h
@@ -43,8 +43,11 @@
#define LVPSA_MEMREGION_PERSISTENT_COEF 1 /* Offset to persistent coefficients memory region in memory table */
#define LVPSA_MEMREGION_PERSISTENT_DATA 2 /* Offset to persistent taps memory region in memory table */
#define LVPSA_MEMREGION_SCRATCH 3 /* Offset to scratch memory region in memory table */
-
-#define LVPSA_NR_SUPPORTED_RATE 9 /* From 8000Hz to 48000Hz */
+#ifndef HIGHER_FS
+#define LVPSA_NR_SUPPORTED_RATE 9 /* From 8000Hz to 48000Hz*/
+#else
+#define LVPSA_NR_SUPPORTED_RATE 11 /* From 8000Hz to 192000Hz*/
+#endif
#define LVPSA_NR_SUPPORTED_SPEED 3 /* LOW, MEDIUM, HIGH */
#define LVPSA_MAXBUFFERDURATION 4000 /* Maximum length in ms of the levels buffer */
@@ -93,12 +96,27 @@
LVPSA_MemTab_t MemoryTable;
LVPSA_BPFilterPrecision_en *pBPFiltersPrecision; /* Points a nBands elements array that contains the filter precision for each band */
+#ifndef BUILD_FLOAT
Biquad_Instance_t *pBP_Instances; /* Points a nBands elements array that contains the band pass filter instance for each band */
Biquad_1I_Order2_Taps_t *pBP_Taps; /* Points a nBands elements array that contains the band pass filter taps for each band */
QPD_State_t *pQPD_States; /* Points a nBands elements array that contains the QPD filter instance for each band */
QPD_Taps_t *pQPD_Taps; /* Points a nBands elements array that contains the QPD filter taps for each band */
- LVM_UINT16 *pPostGains; /* Points a nBands elements array that contains the post-filter gains for each band */
+#else
+ Biquad_FLOAT_Instance_t *pBP_Instances;
+ /* Points a nBands elements array that contains the band pass filter taps for each band */
+ Biquad_1I_Order2_FLOAT_Taps_t *pBP_Taps;
+ /* Points a nBands elements array that contains the QPD filter instance for each band */
+ QPD_FLOAT_State_t *pQPD_States;
+ /* Points a nBands elements array that contains the QPD filter taps for each band */
+ QPD_FLOAT_Taps_t *pQPD_Taps;
+#endif
+#ifndef BUILD_FLOAT
+ LVM_UINT16 *pPostGains; /* Points a nBands elements array that contains the post-filter gains for each band */
+#else
+ /* Points a nBands elements array that contains the post-filter gains for each band */
+ LVM_FLOAT *pPostGains;
+#endif
LVPSA_FilterParam_t *pFiltersParams; /* Copy of the filters parameters from the input parameters */
diff --git a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Process.c b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Process.c
index 9e29f68..ea5f74a 100644
--- a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Process.c
+++ b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Process.c
@@ -43,6 +43,96 @@
/* otherwise Error due to bad parameters */
/* */
/************************************************************************************/
+#ifdef BUILD_FLOAT
+LVPSA_RETURN LVPSA_Process ( pLVPSA_Handle_t hInstance,
+ LVM_FLOAT *pLVPSA_InputSamples,
+ LVM_UINT16 InputBlockSize,
+ LVPSA_Time AudioTime )
+
+{
+ LVPSA_InstancePr_t *pLVPSA_Inst = (LVPSA_InstancePr_t*)hInstance;
+ LVM_FLOAT *pScratch;
+ LVM_INT16 ii;
+ LVM_INT32 AudioTimeInc;
+ extern LVM_UINT32 LVPSA_SampleRateInvTab[];
+ LVM_UINT8 *pWrite_Save; /* Position of the write pointer
+ at the beginning of the process */
+
+ /******************************************************************************
+ CHECK PARAMETERS
+ *******************************************************************************/
+ if(hInstance == LVM_NULL || pLVPSA_InputSamples == LVM_NULL)
+ {
+ return(LVPSA_ERROR_NULLADDRESS);
+ }
+ if(InputBlockSize == 0 || InputBlockSize > pLVPSA_Inst->MaxInputBlockSize)
+ {
+ return(LVPSA_ERROR_INVALIDPARAM);
+ }
+
+ pScratch = (LVM_FLOAT*)pLVPSA_Inst->MemoryTable.Region[LVPSA_MEMREGION_SCRATCH].pBaseAddress;
+ pWrite_Save = pLVPSA_Inst->pSpectralDataBufferWritePointer;
+
+ /******************************************************************************
+ APPLY NEW SETTINGS IF NEEDED
+ *******************************************************************************/
+ if (pLVPSA_Inst->bControlPending == LVM_TRUE)
+ {
+ pLVPSA_Inst->bControlPending = 0;
+ LVPSA_ApplyNewSettings( pLVPSA_Inst);
+ }
+
+ /******************************************************************************
+ PROCESS SAMPLES
+ *******************************************************************************/
+ /* Put samples in range [-0.5;0.5[ for BP filters (see Biquads documentation) */
+ Copy_Float(pLVPSA_InputSamples, pScratch, (LVM_INT16)InputBlockSize);
+ Shift_Sat_Float(-1, pScratch, pScratch, (LVM_INT16)InputBlockSize);
+
+ for (ii = 0; ii < pLVPSA_Inst->nRelevantFilters; ii++)
+ {
+ switch(pLVPSA_Inst->pBPFiltersPrecision[ii])
+ {
+ case LVPSA_SimplePrecisionFilter:
+ BP_1I_D16F16C14_TRC_WRA_01 ( &pLVPSA_Inst->pBP_Instances[ii],
+ pScratch,
+ pScratch + InputBlockSize,
+ (LVM_INT16)InputBlockSize);
+ break;
+
+ case LVPSA_DoublePrecisionFilter:
+ BP_1I_D16F32C30_TRC_WRA_01 ( &pLVPSA_Inst->pBP_Instances[ii],
+ pScratch,
+ pScratch + InputBlockSize,
+ (LVM_INT16)InputBlockSize);
+ break;
+ default:
+ break;
+ }
+
+
+ LVPSA_QPD_Process_Float ( pLVPSA_Inst,
+ pScratch + InputBlockSize,
+ (LVM_INT16)InputBlockSize,
+ ii);
+ }
+
+ /******************************************************************************
+ UPDATE SpectralDataBufferAudioTime
+ *******************************************************************************/
+
+ if(pLVPSA_Inst->pSpectralDataBufferWritePointer != pWrite_Save)
+ {
+ MUL32x32INTO32((AudioTime + (LVM_INT32)((LVM_INT32)pLVPSA_Inst->LocalSamplesCount*1000)),
+ (LVM_INT32)LVPSA_SampleRateInvTab[pLVPSA_Inst->CurrentParams.Fs],
+ AudioTimeInc,
+ LVPSA_FsInvertShift)
+ pLVPSA_Inst->SpectralDataBufferAudioTime = AudioTime + AudioTimeInc;
+ }
+
+ return(LVPSA_OK);
+}
+#else
LVPSA_RETURN LVPSA_Process ( pLVPSA_Handle_t hInstance,
LVM_INT16 *pLVPSA_InputSamples,
LVM_UINT16 InputBlockSize,
@@ -130,7 +220,7 @@
return(LVPSA_OK);
}
-
+#endif
/************************************************************************************/
/* */
diff --git a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_QPD.h b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_QPD.h
index 836bfd7..99d844b 100644
--- a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_QPD.h
+++ b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_QPD.h
@@ -31,6 +31,15 @@
LVM_INT32 Coefs[2]; /* pointer to the filter coefficients */
}QPD_State_t, *pQPD_State_t;
+#ifdef BUILD_FLOAT
+typedef struct
+{
+ /* pointer to the delayed samples (data of 32 bits) */
+ LVM_FLOAT *pDelay;
+ LVM_FLOAT Coefs[2]; /* pointer to the filter coefficients */
+}QPD_FLOAT_State_t, *pQPD_FLOAT_State_t;
+#endif
+
typedef struct
{
LVM_INT32 KP; /*should store a0*/
@@ -38,12 +47,30 @@
} QPD_C32_Coefs, *PQPD_C32_Coefs;
+#ifdef BUILD_FLOAT
+typedef struct
+{
+ LVM_FLOAT KP; /*should store a0*/
+ LVM_FLOAT KM; /*should store b2*/
+
+} QPD_FLOAT_Coefs, *PQPD_FLOAT_Coefs;
+#endif
+
+
typedef struct
{
LVM_INT32 Storage[1];
} QPD_Taps_t, *pQPD_Taps_t;
+#ifdef BUILD_FLOAT
+typedef struct
+{
+ LVM_FLOAT Storage[1];
+
+} QPD_FLOAT_Taps_t, *pQPD_FLOAT_Taps_t;
+
+#endif
/************************************************************************************/
/* */
/* FUNCTION: LVPSA_QPD_Process */
@@ -62,6 +89,12 @@
LVM_INT16 numSamples,
LVM_INT16 BandIndex);
+#ifdef BUILD_FLOAT
+void LVPSA_QPD_Process_Float ( void *hInstance,
+ LVM_FLOAT *pInSamps,
+ LVM_INT16 numSamples,
+ LVM_INT16 BandIndex);
+#endif
/************************************************************************************/
/* */
/* FUNCTION: LVPSA_QPD_Init */
@@ -80,8 +113,12 @@
void LVPSA_QPD_Init ( QPD_State_t *pInstance,
QPD_Taps_t *pTaps,
QPD_C32_Coefs *pCoef );
+#ifdef BUILD_FLOAT
-
+void LVPSA_QPD_Init_Float ( QPD_FLOAT_State_t *pInstance,
+ QPD_FLOAT_Taps_t *pTaps,
+ QPD_FLOAT_Coefs *pCoef );
+#endif
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_QPD_Init.c b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_QPD_Init.c
index 50e0a80..2cc32ab 100644
--- a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_QPD_Init.c
+++ b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_QPD_Init.c
@@ -40,3 +40,14 @@
pQPD_State->Coefs[0] = pCoef->KP;
pQPD_State->Coefs[1] = pCoef->KM;
}
+
+#ifdef BUILD_FLOAT
+void LVPSA_QPD_Init_Float ( pQPD_FLOAT_State_t pQPD_State,
+ QPD_FLOAT_Taps_t *pTaps,
+ QPD_FLOAT_Coefs *pCoef )
+{
+ pQPD_State->pDelay = pTaps->Storage;
+ pQPD_State->Coefs[0] = ((LVM_FLOAT)pCoef->KP);
+ pQPD_State->Coefs[1] = ((LVM_FLOAT)pCoef->KM);
+}
+#endif
diff --git a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_QPD_Process.c b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_QPD_Process.c
index 67197c1..e233172 100644
--- a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_QPD_Process.c
+++ b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_QPD_Process.c
@@ -35,12 +35,16 @@
/* */
/************************************************************************************/
void LVPSA_QPD_WritePeak( pLVPSA_InstancePr_t pLVPSA_Inst,
- LVM_UINT8 **ppWrite,
- LVM_INT16 BandIndex,
- LVM_INT16 Value );
+ LVM_UINT8 **ppWrite,
+ LVM_INT16 BandIndex,
+ LVM_INT16 Value );
-
-
+#ifdef BUILD_FLOAT
+void LVPSA_QPD_WritePeak_Float( pLVPSA_InstancePr_t pLVPSA_Inst,
+ LVM_UINT8 **ppWrite,
+ LVM_INT16 BandIndex,
+ LVM_FLOAT Value );
+#endif
/************************************************************************************/
/* */
/* FUNCTION: LVPSA_QPD_Process */
@@ -54,6 +58,7 @@
/* RETURNS: void */
/* */
/************************************************************************************/
+#ifndef BUILD_FLOAT
void LVPSA_QPD_Process ( void *hInstance,
LVM_INT16 *pInSamps,
LVM_INT16 numSamples,
@@ -173,7 +178,131 @@
pLVPSA_Inst->DownSamplingCount = (LVM_UINT16)(-ii);
}
}
+#else
+void LVPSA_QPD_Process_Float ( void *hInstance,
+ LVM_FLOAT *pInSamps,
+ LVM_INT16 numSamples,
+ LVM_INT16 BandIndex)
+{
+ /******************************************************************************
+ PARAMETERS
+ *******************************************************************************/
+ LVPSA_InstancePr_t *pLVPSA_Inst = (LVPSA_InstancePr_t*)hInstance;
+ QPD_FLOAT_State_t *pQPDState = (QPD_FLOAT_State_t*)&pLVPSA_Inst->pQPD_States[BandIndex];
+
+ /* Pointer to taps */
+ LVM_FLOAT* pDelay = pQPDState->pDelay;
+
+ /* Parameters needed during quasi peak calculations */
+ LVM_FLOAT X0;
+ LVM_FLOAT temp,temp2;
+ LVM_FLOAT accu;
+ LVM_FLOAT Xg0;
+ LVM_FLOAT D0;
+ LVM_FLOAT V0 = (LVM_FLOAT)(*pDelay);
+
+ /* Filter's coef */
+ LVM_FLOAT Kp = ((LVM_FLOAT)(pQPDState->Coefs[0]));
+ LVM_FLOAT Km = ((LVM_FLOAT)(pQPDState->Coefs[1]));
+
+ LVM_INT16 ii = numSamples;
+
+ LVM_UINT8 *pWrite = pLVPSA_Inst->pSpectralDataBufferWritePointer;
+ LVM_INT32 BufferUpdateSamplesCount = pLVPSA_Inst->BufferUpdateSamplesCount;
+ LVM_UINT16 DownSamplingFactor = pLVPSA_Inst->DownSamplingFactor;
+
+ /******************************************************************************
+ INITIALIZATION
+ *******************************************************************************/
+ /* Correct the pointer to take the first down sampled signal sample */
+ pInSamps += pLVPSA_Inst->DownSamplingCount;
+ /* Correct also the number of samples */
+ ii = (LVM_INT16)(ii - (LVM_INT16)pLVPSA_Inst->DownSamplingCount);
+
+ while (ii > 0)
+ {
+ /* Apply post gain */
+ /* - 1 to compensate scaling in process function*/
+ X0 = (*pInSamps) * pLVPSA_Inst->pPostGains[BandIndex];
+ pInSamps = pInSamps + DownSamplingFactor;
+
+ /* Saturate and take absolute value */
+ if(X0 < 0.0f)
+ X0 = -X0;
+ if (X0 > 1.0f)
+ Xg0 = 1.0f;
+ else
+ Xg0 =X0;
+
+
+ /* Quasi peak filter calculation */
+ D0 = Xg0 - V0;
+
+ temp2 = D0;
+
+ accu = temp2 * Kp;
+ D0 = D0 / 2.0f;
+ if (D0 < 0.0f){
+ D0 = -D0;
+ }
+
+ temp2 = D0;
+
+ temp = D0 * Km;
+ accu += temp + Xg0;
+
+ if (accu > 1.0f)
+ accu = 1.0f;
+ else if(accu < 0.0f)
+ accu = 0.0f;
+
+ V0 = accu;
+
+ if(((pLVPSA_Inst->nSamplesBufferUpdate - BufferUpdateSamplesCount) < DownSamplingFactor))
+ {
+ LVPSA_QPD_WritePeak_Float( pLVPSA_Inst,
+ &pWrite,
+ BandIndex,
+ V0);
+
+ BufferUpdateSamplesCount -= pLVPSA_Inst->nSamplesBufferUpdate;
+ pLVPSA_Inst->LocalSamplesCount = (LVM_UINT16)(numSamples - ii);
+ }
+ BufferUpdateSamplesCount += DownSamplingFactor;
+
+ ii = (LVM_INT16)(ii - DownSamplingFactor);
+
+ }
+
+ /* Store last taps in memory */
+ *pDelay = V0;
+
+ /* If this is the last call to the function after last band processing,
+ update the parameters. */
+ if(BandIndex == (pLVPSA_Inst->nRelevantFilters - 1))
+ {
+ pLVPSA_Inst->pSpectralDataBufferWritePointer = pWrite;
+ /* Adjustment for 11025Hz input, 220,5 is normally
+ the exact number of samples for 20ms.*/
+ if((pLVPSA_Inst->pSpectralDataBufferWritePointer != pWrite)&&
+ (pLVPSA_Inst->CurrentParams.Fs == LVM_FS_11025))
+ {
+ if(pLVPSA_Inst->nSamplesBufferUpdate == 220)
+ {
+ pLVPSA_Inst->nSamplesBufferUpdate = 221;
+ }
+ else
+ {
+ pLVPSA_Inst->nSamplesBufferUpdate = 220;
+ }
+ }
+ pLVPSA_Inst->pSpectralDataBufferWritePointer = pWrite;
+ pLVPSA_Inst->BufferUpdateSamplesCount = BufferUpdateSamplesCount;
+ pLVPSA_Inst->DownSamplingCount = (LVM_UINT16)(-ii);
+ }
+}
+#endif
/************************************************************************************/
/* */
/* FUNCTION: LVPSA_QPD_WritePeak */
@@ -209,4 +338,23 @@
*ppWrite = pWrite;
}
+#ifdef BUILD_FLOAT
+void LVPSA_QPD_WritePeak_Float( pLVPSA_InstancePr_t pLVPSA_Inst,
+ LVM_UINT8 **ppWrite,
+ LVM_INT16 BandIndex,
+ LVM_FLOAT Value )
+{
+ LVM_UINT8 *pWrite = *ppWrite;
+ /* Write the value and update the write pointer */
+ *(pWrite + BandIndex) = (LVM_UINT8)(Value * 256);
+ pWrite += pLVPSA_Inst->nBands;
+ if (pWrite == (pLVPSA_Inst->pSpectralDataBufferStart + pLVPSA_Inst->nBands * \
+ pLVPSA_Inst->SpectralDataBufferLength))
+ {
+ pWrite = pLVPSA_Inst->pSpectralDataBufferStart;
+ }
+
+ *ppWrite = pWrite;
+}
+#endif
diff --git a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Tables.c b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Tables.c
index 21a5d8d..1287503 100644
--- a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Tables.c
+++ b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Tables.c
@@ -34,6 +34,7 @@
* Sample rate table for converting between the enumerated type and the actual
* frequency
*/
+#ifndef HIGHER_FS
const LVM_UINT16 LVPSA_SampleRateTab[] = { 8000, /* 8kS/s */
11025,
12000,
@@ -43,6 +44,19 @@
32000,
44100,
48000}; /* 48kS/s */
+#else
+const LVM_UINT32 LVPSA_SampleRateTab[] = { 8000, /* 8kS/s */
+ 11025,
+ 12000,
+ 16000,
+ 22050,
+ 24000,
+ 32000,
+ 44100,
+ 48000,
+ 96000,
+ 192000}; /* 192kS/s */
+#endif
/************************************************************************************/
/* */
@@ -62,7 +76,12 @@
89478,
67109,
48696,
- 44739}; /* 48kS/s */
+ 44739
+#ifdef HIGHER_FS
+ ,22369
+ ,11185 /* 192kS/s */
+#endif
+ };
@@ -84,7 +103,12 @@
480,
640,
882,
- 960}; /* 48kS/s */
+ 960
+#ifdef HIGHER_FS
+ ,1920
+ ,3840 /* 192kS/s */
+#endif
+ };
/************************************************************************************/
/* */
/* Down sampling factors */
@@ -102,7 +126,12 @@
16, /* 24000 S/s */
21, /* 32000 S/s */
30, /* 44100 S/s */
- 32}; /* 48000 S/s */
+ 32 /* 48000 S/s */
+#ifdef HIGHER_FS
+ ,64 /* 96000 S/s */
+ ,128 /*192000 S/s */
+#endif
+ };
/************************************************************************************/
@@ -122,8 +151,30 @@
8785,
6588,
4781,
- 4392}; /* 48kS/s */
+ 4392
+#ifdef HIGHER_FS
+ ,2196
+ ,1098 /* 192kS/s */
+#endif
+ };
+#ifdef BUILD_FLOAT
+const LVM_FLOAT LVPSA_Float_TwoPiOnFsTable[] = { 0.8042847f, /* 8kS/s */
+ 0.5836054f,
+ 0.5361796f,
+ 0.4021423f,
+ 0.2917874f,
+ 0.2681051f,
+ 0.2010559f,
+ 0.1459089f,
+ 0.1340372f
+#ifdef HIGHER_FS
+ ,0.0670186f
+ ,0.0335093f /* 192kS/s */
+#endif
+ };
+
+#endif
/*
* Gain table
*/
@@ -159,6 +210,39 @@
10264,
11576}; /* +15dB gain */
+#ifdef BUILD_FLOAT
+const LVM_FLOAT LVPSA_Float_GainTable[]={ 0.177734375f, /* -15dB gain */
+ 0.199218750f,
+ 0.223632812f,
+ 0.250976562f,
+ 0.281738281f,
+ 0.315917968f,
+ 0.354492187f,
+ 0.397949218f,
+ 0.446289062f,
+ 0.500976562f,
+ 0.562011718f,
+ 0.630859375f,
+ 0.707519531f,
+ 0.793945312f,
+ 0.891113281f,
+ 1.000000000f, /* 0dB gain */
+ 1.121582031f,
+ 1.258789062f,
+ 1.412109375f,
+ 1.584472656f,
+ 1.777832031f,
+ 2.000000000f,
+ 2.238281250f,
+ 2.511718750f,
+ 2.818359375f,
+ 3.162109375f,
+ 3.547851562f,
+ 3.980957031f,
+ 4.466796875f,
+ 5.011718750f,
+ 5.652343750f}; /* +15dB gain */
+#endif
/************************************************************************************/
/* */
/* Cosone polynomial coefficients */
@@ -181,7 +265,15 @@
-2671, /* a3 */
23730, /* a4 */
-9490}; /* a5 */
-
+#ifdef BUILD_FLOAT
+const LVM_FLOAT LVPSA_Float_CosCoef[] = { 3, /* Shifts */
+ 0.1250038f, /* a0 */
+ -0.0010986f, /* a1 */
+ -0.6019775f, /* a2 */
+ -0.0815149f, /* a3 */
+ 0.7242042f, /* a4 */
+ -0.2896206f}; /* a5 */
+#endif
/*
* Coefficients for calculating the cosine error with the equation:
*
@@ -201,7 +293,13 @@
-6, /* a1 */
16586, /* a2 */
-44}; /* a3 */
-
+#ifdef BUILD_FLOAT
+const LVM_FLOAT LVPSA_Float_DPCosCoef[] = {1.0f, /* Shifts */
+ 0.0f, /* a0 */
+ -0.00008311f, /* a1 */
+ 0.50617999f, /* a2 */
+ -0.00134281f}; /* a3 */
+#endif
/************************************************************************************/
/* */
/* Quasi peak filter coefficients table */
@@ -239,3 +337,54 @@
{0xA375B2C6,0x1E943BBC},
{0xA2E1E950,0x1E2A532E}}; /* 48kS/s */
+#ifdef BUILD_FLOAT
+const QPD_FLOAT_Coefs LVPSA_QPD_Float_Coefs[] = {
+
+ /* 8kS/s */ /* LVPSA_SPEED_LOW */
+ {-0.9936831989325583f,0.0062135565094650f},
+ {-0.9935833332128823f,0.0063115493394434f},
+ {-0.9932638457976282f,0.0066249934025109f},
+ {-0.9936831989325583f,0.0062135565094650f},
+ {-0.9931269618682563f,0.0067592649720609f},
+ {-0.9932638457976282f,0.0066249934025109f},
+ {-0.9933686633594334f,0.0065221670083702f},
+ {-0.9931269618682563f,0.0067592649720609f},
+ /* 48kS/s */
+ {-0.9932638457976282f,0.0066249934025109f},
+#ifdef HIGHER_FS
+ {-0.9932638457976282f,0.0066249934025109f},
+ {-0.9932638457976282f,0.0066249934025109f},
+#endif
+ /* 8kS/s */ /* LVPSA_SPEED_MEDIUM */
+ {-0.9568079425953329f,0.0418742666952312f},
+ {-0.9561413046903908f,0.0425090822391212f},
+ {-0.9540119562298059f,0.0445343819446862f},
+ {-0.9568079425953329f,0.0418742666952312f},
+ {-0.9531011912040412f,0.0453995238058269f},
+ {-0.9540119562298059f,0.0445343819446862f},
+ {-0.9547099955379963f,0.0438708555884659f},
+ //{0x8600C7B9,0x05CFA6CF},
+ {-0.9531011912040412f,0.0453995238058269f},
+ /* 48kS/s */
+ {-0.9540119562298059f,0.0445343819446862f},
+#ifdef HIGHER_FS
+ {-0.9540119562298059f,0.0445343819446862f},
+ {-0.9540119562298059f,0.0445343819446862f},
+#endif
+ /* 8kS/s */ /* LVPSA_SPEED_HIGH */
+ {-0.7415186790749431f,0.2254409026354551f},
+ {-0.7381451204419136f,0.2279209652915597f},
+ {-0.7274807319045067f,0.2356666540727019f},
+ {-0.7415186790749431f,0.2254409026354551f},
+ {-0.7229706319049001f,0.2388987224549055f},
+ {-0.7274807319045067f,0.2356666540727019f},
+ {-0.7309581353329122f,0.2331568226218224f},
+ {-0.7229706319049001f,0.2388987224549055f},
+ /* 48kS/s */
+ {-0.7274807319045067f,0.2356666540727019f}
+#ifdef HIGHER_FS
+ ,{-0.7274807319045067f,0.2356666540727019f}
+ ,{-0.7274807319045067f,0.2356666540727019f}
+#endif
+ };
+#endif
diff --git a/media/libeffects/lvm/lib/StereoWidening/lib/LVCS.h b/media/libeffects/lvm/lib/StereoWidening/lib/LVCS.h
index 0d62274..e75695e 100644
--- a/media/libeffects/lvm/lib/StereoWidening/lib/LVCS.h
+++ b/media/libeffects/lvm/lib/StereoWidening/lib/LVCS.h
@@ -374,12 +374,17 @@
/* NOTES: */
/* */
/****************************************************************************************/
-
+#ifdef BUILD_FLOAT
+LVCS_ReturnStatus_en LVCS_Process(LVCS_Handle_t hInstance,
+ const LVM_FLOAT *pInData,
+ LVM_FLOAT *pOutData,
+ LVM_UINT16 NumSamples);
+#else
LVCS_ReturnStatus_en LVCS_Process(LVCS_Handle_t hInstance,
const LVM_INT16 *pInData,
LVM_INT16 *pOutData,
LVM_UINT16 NumSamples);
-
+#endif
#ifdef __cplusplus
}
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_BypassMix.c b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_BypassMix.c
index 3e48c7e..29e3c9e 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_BypassMix.c
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_BypassMix.c
@@ -70,11 +70,17 @@
{
LVM_UINT16 Offset;
+#ifndef BUILD_FLOAT
LVM_UINT32 Gain;
+ LVM_INT32 Current;
+#else
+ LVM_FLOAT Gain;
+ LVM_FLOAT Current;
+#endif
LVCS_Instance_t *pInstance = (LVCS_Instance_t *)hInstance;
LVCS_BypassMix_t *pConfig = (LVCS_BypassMix_t *)&pInstance->BypassMix;
const Gain_t *pOutputGainTable;
- LVM_INT32 Current;
+
/*
@@ -85,7 +91,11 @@
&& (pInstance->MSTarget1 != 0x7FFF) /* this indicates an off->on transtion */
)
{
+#ifndef BUILD_FLOAT
pInstance->TransitionGain = pParams->EffectLevel;
+#else
+ pInstance->TransitionGain = ((LVM_FLOAT)pParams->EffectLevel / 32767);
+#endif
}
else
{
@@ -102,23 +112,46 @@
/*
* Setup the mixer gain for the processed path
*/
+#ifndef BUILD_FLOAT
Gain = (LVM_UINT32)(pOutputGainTable[Offset].Loss * pInstance->TransitionGain);
+#else
+ Gain = (LVM_FLOAT)(pOutputGainTable[Offset].Loss * pInstance->TransitionGain);
+#endif
pConfig->Mixer_Instance.MixerStream[0].CallbackParam = 0;
pConfig->Mixer_Instance.MixerStream[0].pCallbackHandle = LVM_NULL;
pConfig->Mixer_Instance.MixerStream[0].pCallBack = LVM_NULL;
pConfig->Mixer_Instance.MixerStream[0].CallbackSet=1;
+
+#ifndef BUILD_FLOAT
Current = LVC_Mixer_GetCurrent(&pConfig->Mixer_Instance.MixerStream[0]);
LVC_Mixer_Init(&pConfig->Mixer_Instance.MixerStream[0],(LVM_INT32)(Gain >> 15),Current);
LVC_Mixer_VarSlope_SetTimeConstant(&pConfig->Mixer_Instance.MixerStream[0],LVCS_BYPASS_MIXER_TC,pParams->SampleRate,2);
+#else
+ Current = LVC_Mixer_GetCurrent(&pConfig->Mixer_Instance.MixerStream[0]);
+ LVC_Mixer_Init(&pConfig->Mixer_Instance.MixerStream[0], (LVM_FLOAT)(Gain), Current);
+ LVC_Mixer_VarSlope_SetTimeConstant(&pConfig->Mixer_Instance.MixerStream[0],
+ LVCS_BYPASS_MIXER_TC, pParams->SampleRate, 2);
+#endif
+
/*
* Setup the mixer gain for the unprocessed path
*/
+#ifndef BUILD_FLOAT
Gain = (LVM_UINT32)(pOutputGainTable[Offset].Loss * (0x7FFF - pInstance->TransitionGain));
Gain = (LVM_UINT32)pOutputGainTable[Offset].UnprocLoss * (Gain >> 15);
Current = LVC_Mixer_GetCurrent(&pConfig->Mixer_Instance.MixerStream[1]);
LVC_Mixer_Init(&pConfig->Mixer_Instance.MixerStream[1],(LVM_INT32)(Gain >> 15),Current);
LVC_Mixer_VarSlope_SetTimeConstant(&pConfig->Mixer_Instance.MixerStream[1],LVCS_BYPASS_MIXER_TC,pParams->SampleRate,2);
+#else
+ Gain = (LVM_FLOAT)(pOutputGainTable[Offset].Loss * (1.0 - \
+ (LVM_FLOAT)pInstance->TransitionGain));
+ Gain = (LVM_FLOAT)pOutputGainTable[Offset].UnprocLoss * Gain;
+ Current = LVC_Mixer_GetCurrent(&pConfig->Mixer_Instance.MixerStream[1]);
+ LVC_Mixer_Init(&pConfig->Mixer_Instance.MixerStream[1], (LVM_FLOAT)(Gain), Current);
+ LVC_Mixer_VarSlope_SetTimeConstant(&pConfig->Mixer_Instance.MixerStream[1],
+ LVCS_BYPASS_MIXER_TC, pParams->SampleRate, 2);
+#endif
pConfig->Mixer_Instance.MixerStream[1].CallbackParam = 0;
pConfig->Mixer_Instance.MixerStream[1].pCallbackHandle = hInstance;
pConfig->Mixer_Instance.MixerStream[1].CallbackSet=1;
@@ -134,7 +167,7 @@
* Correct gain for the effect level
*/
{
-
+#ifndef BUILD_FLOAT
LVM_INT16 GainCorrect;
LVM_INT32 Gain1;
LVM_INT32 Gain2;
@@ -172,6 +205,43 @@
LVC_Mixer_VarSlope_SetTimeConstant(&pConfig->Mixer_Instance.MixerStream[0],LVCS_BYPASS_MIXER_TC,pParams->SampleRate,2);
LVC_Mixer_SetTarget(&pConfig->Mixer_Instance.MixerStream[1],Gain2>>16);
LVC_Mixer_VarSlope_SetTimeConstant(&pConfig->Mixer_Instance.MixerStream[1],LVCS_BYPASS_MIXER_TC,pParams->SampleRate,2);
+#else
+ LVM_FLOAT GainCorrect;
+ LVM_FLOAT Gain1;
+ LVM_FLOAT Gain2;
+
+ Gain1 = LVC_Mixer_GetTarget(&pConfig->Mixer_Instance.MixerStream[0]);
+ Gain2 = LVC_Mixer_GetTarget(&pConfig->Mixer_Instance.MixerStream[1]);
+ /*
+ * Calculate the gain correction
+ */
+ if (pInstance->Params.CompressorMode == LVM_MODE_ON)
+ {
+ GainCorrect = (LVM_FLOAT)( pInstance->VolCorrect.GainMin
+ - (((LVM_FLOAT)pInstance->VolCorrect.GainMin * \
+ ((LVM_FLOAT)pInstance->TransitionGain)))
+ + (((LVM_FLOAT)pInstance->VolCorrect.GainFull * \
+ ((LVM_FLOAT)pInstance->TransitionGain))));
+
+ /*
+ * Apply the gain correction
+ */
+ Gain1 = (Gain1 * GainCorrect);
+ Gain2 = (Gain2 * GainCorrect);
+
+ }
+
+ /*
+ * Set the gain values
+ */
+ pConfig->Output_Shift = pConfig->Output_Shift;
+ LVC_Mixer_SetTarget(&pConfig->Mixer_Instance.MixerStream[0],Gain1);
+ LVC_Mixer_VarSlope_SetTimeConstant(&pConfig->Mixer_Instance.MixerStream[0],
+ LVCS_BYPASS_MIXER_TC, pParams->SampleRate, 2);
+ LVC_Mixer_SetTarget(&pConfig->Mixer_Instance.MixerStream[1],Gain2);
+ LVC_Mixer_VarSlope_SetTimeConstant(&pConfig->Mixer_Instance.MixerStream[1],
+ LVCS_BYPASS_MIXER_TC, pParams->SampleRate, 2);
+#endif
}
return(LVCS_SUCCESS);
@@ -206,9 +276,15 @@
/************************************************************************************/
LVCS_ReturnStatus_en LVCS_BypassMixer(LVCS_Handle_t hInstance,
+#ifndef BUILD_FLOAT
const LVM_INT16 *pProcessed,
const LVM_INT16 *pUnprocessed,
LVM_INT16 *pOutData,
+#else
+ const LVM_FLOAT *pProcessed,
+ const LVM_FLOAT *pUnprocessed,
+ LVM_FLOAT *pOutData,
+#endif
LVM_UINT16 NumSamples)
{
@@ -223,6 +299,7 @@
/*
* Apply the bypass mix
*/
+#ifndef BUILD_FLOAT
LVC_MixSoft_2St_D16C31_SAT(&pConfig->Mixer_Instance,
pProcessed,
(LVM_INT16 *) pUnprocessed,
@@ -236,6 +313,20 @@
(LVM_INT16*)pOutData,
(LVM_INT16*)pOutData,
(LVM_INT16)(2*NumSamples)); /* Left and right*/
+#else
+ LVC_MixSoft_2St_D16C31_SAT(&pConfig->Mixer_Instance,
+ pProcessed,
+ (LVM_FLOAT *) pUnprocessed,
+ pOutData,
+ (LVM_INT16)(2 * NumSamples));
+ /*
+ * Apply output gain correction shift
+ */
+ Shift_Sat_Float((LVM_INT16)pConfig->Output_Shift,
+ (LVM_FLOAT*)pOutData,
+ (LVM_FLOAT*)pOutData,
+ (LVM_INT16)(2 * NumSamples)); /* Left and right*/
+#endif
}
return(LVCS_SUCCESS);
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_BypassMix.h b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_BypassMix.h
index d1ef70a..f69ba38 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_BypassMix.h
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_BypassMix.h
@@ -42,12 +42,16 @@
typedef struct
{
/* Mixer settings */
+#ifdef BUILD_FLOAT
+ LVMixer3_2St_FLOAT_st Mixer_Instance; /* Mixer instance */
+#else
LVMixer3_2St_st Mixer_Instance; /* Mixer instance */
+#endif
LVM_UINT16 Output_Shift; /* Correcting gain output shift */
} LVCS_BypassMix_t;
-
+#ifndef BUILD_FLOAT
/* Output gain type */
typedef struct
{
@@ -56,8 +60,15 @@
LVM_UINT16 Loss; /* Loss required */
LVM_UINT16 UnprocLoss; /* Unprocessed path loss */
} Gain_t;
-
-
+#else
+typedef struct
+{
+ /* Output gain settings, Gain = (Loss/32768) * 2^Shift */
+ LVM_UINT16 Shift; /* Left shifts required */
+ LVM_FLOAT Loss; /* Loss required */
+ LVM_FLOAT UnprocLoss; /* Unprocessed path loss */
+} Gain_t;
+#endif
/************************************************************************************/
/* */
/* Function prototypes */
@@ -67,13 +78,19 @@
LVCS_ReturnStatus_en LVCS_BypassMixInit(LVCS_Handle_t hInstance,
LVCS_Params_t *pParams);
-
+#ifndef BUILD_FLOAT
LVCS_ReturnStatus_en LVCS_BypassMixer(LVCS_Handle_t hInstance,
const LVM_INT16 *pProcessed,
const LVM_INT16 *unProcessed,
- LVM_INT16 *pOutData,
- LVM_UINT16 NumSamples);
-
+ LVM_INT16 *pOutData,
+ LVM_UINT16 NumSamples);
+#else
+LVCS_ReturnStatus_en LVCS_BypassMixer(LVCS_Handle_t hInstance,
+ const LVM_FLOAT *pProcessed,
+ const LVM_FLOAT *unProcessed,
+ LVM_FLOAT *pOutData,
+ LVM_UINT16 NumSamples);
+#endif
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Control.c b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Control.c
index ce6d410..3bf6ec6 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Control.c
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Control.c
@@ -120,11 +120,13 @@
pInstance->VolCorrect = pLVCS_VolCorrectTable[Offset];
pInstance->CompressGain = pInstance->VolCorrect.CompMin;
-
+#ifdef BUILD_FLOAT
+ LVC_Mixer_Init(&pInstance->BypassMix.Mixer_Instance.MixerStream[0], 0, 0);
+#else
LVC_Mixer_Init(&pInstance->BypassMix.Mixer_Instance.MixerStream[0],0,0);
-
-
+#endif
{
+#ifndef BUILD_FLOAT
LVM_UINT32 Gain;
const Gain_t *pOutputGainTable = (Gain_t*)&LVCS_OutputGainTable[0];
Gain = (LVM_UINT32)(pOutputGainTable[Offset].Loss * LVM_MAXINT_16);
@@ -140,7 +142,23 @@
LVCS_BYPASS_MIXER_TC,pParams->SampleRate,2);
LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->BypassMix.Mixer_Instance.MixerStream[1],
LVCS_BYPASS_MIXER_TC,pParams->SampleRate,2);
+#else
+ LVM_FLOAT Gain;
+ const Gain_t *pOutputGainTable = (Gain_t*)&LVCS_OutputGainTable[0];
+ Gain = (LVM_FLOAT)(pOutputGainTable[Offset].Loss);
+ Gain = (LVM_FLOAT)pOutputGainTable[Offset].UnprocLoss * (Gain);
+ /*
+ * Apply the gain correction
+ */
+ Gain = (Gain * pInstance->VolCorrect.GainMin);
+
+ LVC_Mixer_Init(&pInstance->BypassMix.Mixer_Instance.MixerStream[1], 0, Gain);
+ LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->BypassMix.Mixer_Instance.MixerStream[0],
+ LVCS_BYPASS_MIXER_TC, pParams->SampleRate, 2);
+ LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->BypassMix.Mixer_Instance.MixerStream[1],
+ LVCS_BYPASS_MIXER_TC, pParams->SampleRate, 2);
+#endif
}
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Equaliser.c b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Equaliser.c
index 25b0d86..ec5312e 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Equaliser.c
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Equaliser.c
@@ -53,7 +53,72 @@
/* NOTES: */
/* */
/************************************************************************************/
+#ifdef BUILD_FLOAT
+LVCS_ReturnStatus_en LVCS_EqualiserInit(LVCS_Handle_t hInstance,
+ LVCS_Params_t *pParams)
+{
+ LVM_UINT16 Offset;
+ LVCS_Instance_t *pInstance = (LVCS_Instance_t *)hInstance;
+ LVCS_Equaliser_t *pConfig = (LVCS_Equaliser_t *)&pInstance->Equaliser;
+ LVCS_Data_t *pData;
+ LVCS_Coefficient_t *pCoefficients;
+ BQ_FLOAT_Coefs_t Coeffs;
+ const BiquadA012B12CoefsSP_t *pEqualiserCoefTable;
+
+ pData = (LVCS_Data_t *) \
+ pInstance->MemoryTable.Region[LVCS_MEMREGION_PERSISTENT_FAST_DATA].pBaseAddress;
+
+ pCoefficients = (LVCS_Coefficient_t *) \
+ pInstance->MemoryTable.Region[LVCS_MEMREGION_PERSISTENT_FAST_COEF].pBaseAddress;
+ /*
+ * If the sample rate changes re-initialise the filters
+ */
+ if ((pInstance->Params.SampleRate != pParams->SampleRate) ||
+ (pInstance->Params.SpeakerType != pParams->SpeakerType))
+ {
+ /*
+ * Setup the filter coefficients and clear the history
+ */
+ Offset = (LVM_UINT16)(pParams->SampleRate + (pParams->SpeakerType * (1 + LVM_FS_48000)));
+ pEqualiserCoefTable = (BiquadA012B12CoefsSP_t*)&LVCS_EqualiserCoefTable[0];
+
+ /* Left and right filters */
+ /* Convert incoming coefficients to the required format/ordering */
+ Coeffs.A0 = (LVM_FLOAT) pEqualiserCoefTable[Offset].A0;
+ Coeffs.A1 = (LVM_FLOAT) pEqualiserCoefTable[Offset].A1;
+ Coeffs.A2 = (LVM_FLOAT) pEqualiserCoefTable[Offset].A2;
+ Coeffs.B1 = (LVM_FLOAT)-pEqualiserCoefTable[Offset].B1;
+ Coeffs.B2 = (LVM_FLOAT)-pEqualiserCoefTable[Offset].B2;
+
+ LoadConst_Float((LVM_INT16)0, /* Value */
+ (void *)&pData->EqualiserBiquadTaps, /* Destination Cast to void:\
+ no dereferencing in function*/
+ /* Number of words */
+ (LVM_UINT16)(sizeof(pData->EqualiserBiquadTaps) / sizeof(LVM_FLOAT)));
+
+ BQ_2I_D16F32Css_TRC_WRA_01_Init(&pCoefficients->EqualiserBiquadInstance,
+ &pData->EqualiserBiquadTaps,
+ &Coeffs);
+
+ /* Callbacks */
+ switch(pEqualiserCoefTable[Offset].Scale)
+ {
+ case 13:
+ pConfig->pBiquadCallBack = BQ_2I_D16F32C13_TRC_WRA_01;
+ break;
+ case 14:
+ pConfig->pBiquadCallBack = BQ_2I_D16F32C14_TRC_WRA_01;
+ break;
+ case 15:
+ pConfig->pBiquadCallBack = BQ_2I_D16F32C15_TRC_WRA_01;
+ break;
+ }
+ }
+
+ return(LVCS_SUCCESS);
+}
+#else
LVCS_ReturnStatus_en LVCS_EqualiserInit(LVCS_Handle_t hInstance,
LVCS_Params_t *pParams)
{
@@ -112,7 +177,7 @@
return(LVCS_SUCCESS);
}
-
+#endif
/************************************************************************************/
/* */
/* FUNCTION: LVCS_Equaliser */
@@ -132,7 +197,37 @@
/* 1. Always processes in place. */
/* */
/************************************************************************************/
+#ifdef BUILD_FLOAT
+LVCS_ReturnStatus_en LVCS_Equaliser(LVCS_Handle_t hInstance,
+ LVM_FLOAT *pInputOutput,
+ LVM_UINT16 NumSamples)
+{
+ LVCS_Instance_t *pInstance = (LVCS_Instance_t *)hInstance;
+ LVCS_Equaliser_t *pConfig = (LVCS_Equaliser_t *)&pInstance->Equaliser;
+ LVCS_Coefficient_t *pCoefficients;
+
+
+ pCoefficients = (LVCS_Coefficient_t *) \
+ pInstance->MemoryTable.Region[LVCS_MEMREGION_PERSISTENT_FAST_COEF].pBaseAddress;
+
+
+ /*
+ * Check if the equaliser is required
+ */
+ if ((pInstance->Params.OperatingMode & LVCS_EQUALISERSWITCH) != 0)
+ {
+ /* Apply filter to the left and right channels */
+ (pConfig->pBiquadCallBack)((Biquad_FLOAT_Instance_t*) \
+ &pCoefficients->EqualiserBiquadInstance,
+ (LVM_FLOAT *)pInputOutput,
+ (LVM_FLOAT *)pInputOutput,
+ (LVM_INT16)NumSamples);
+ }
+
+ return(LVCS_SUCCESS);
+}
+#else
LVCS_ReturnStatus_en LVCS_Equaliser(LVCS_Handle_t hInstance,
LVM_INT16 *pInputOutput,
LVM_UINT16 NumSamples)
@@ -157,4 +252,4 @@
return(LVCS_SUCCESS);
}
-
+#endif
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Equaliser.h b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Equaliser.h
index cf96f5b..0e756e7 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Equaliser.h
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Equaliser.h
@@ -32,8 +32,11 @@
/* Equaliser structure */
typedef struct
{
+#ifndef BUILD_FLOAT
void (*pBiquadCallBack) (Biquad_Instance_t*, LVM_INT16*, LVM_INT16*, LVM_INT16);
-
+#else
+ void (*pBiquadCallBack) (Biquad_FLOAT_Instance_t*, LVM_FLOAT*, LVM_FLOAT*, LVM_INT16);
+#endif
} LVCS_Equaliser_t;
@@ -45,12 +48,15 @@
LVCS_ReturnStatus_en LVCS_EqualiserInit(LVCS_Handle_t hInstance,
LVCS_Params_t *pParams);
-
+#ifndef BUILD_FLOAT
LVCS_ReturnStatus_en LVCS_Equaliser(LVCS_Handle_t hInstance,
LVM_INT16 *pInputOutput,
LVM_UINT16 NumSamples);
-
-
+#else
+LVCS_ReturnStatus_en LVCS_Equaliser(LVCS_Handle_t hInstance,
+ LVM_FLOAT *pInputOutput,
+ LVM_UINT16 NumSamples);
+#endif
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Headphone_Coeffs.h b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Headphone_Coeffs.h
index 3e640cb..4f5221a 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Headphone_Coeffs.h
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Headphone_Coeffs.h
@@ -24,7 +24,463 @@
/* The Stereo Enhancer */
/* */
/************************************************************************************/
+#ifdef BUILD_FLOAT
+/* Stereo Enhancer coefficients for 8000 Hz sample rate, scaled with 0.161258 */
+#define CS_MIDDLE_8000_A0 0.227720
+#define CS_MIDDLE_8000_A1 -0.215125
+#define CS_MIDDLE_8000_A2 0.000000
+#define CS_MIDDLE_8000_B1 -0.921899
+#define CS_MIDDLE_8000_B2 0.000000
+#define CS_MIDDLE_8000_SCALE 15
+#define CS_SIDE_8000_A0 0.611441
+#define CS_SIDE_8000_A1 -0.380344
+#define CS_SIDE_8000_A2 -0.231097
+#define CS_SIDE_8000_B1 -0.622470
+#define CS_SIDE_8000_B2 -0.130759
+#define CS_SIDE_8000_SCALE 15
+/* Stereo Enhancer coefficients for 11025Hz sample rate, scaled with 0.162943 */
+#define CS_MIDDLE_11025_A0 0.230838
+#define CS_MIDDLE_11025_A1 -0.221559
+#define CS_MIDDLE_11025_A2 0.000000
+#define CS_MIDDLE_11025_B1 -0.943056
+#define CS_MIDDLE_11025_B2 0.000000
+#define CS_MIDDLE_11025_SCALE 15
+#define CS_SIDE_11025_A0 0.557372
+#define CS_SIDE_11025_A1 -0.391490
+#define CS_SIDE_11025_A2 -0.165881
+#define CS_SIDE_11025_B1 -0.880608
+#define CS_SIDE_11025_B2 0.032397
+#define CS_SIDE_11025_SCALE 15
+
+/* Stereo Enhancer coefficients for 12000Hz sample rate, scaled with 0.162191 */
+#define CS_MIDDLE_12000_A0 0.229932
+#define CS_MIDDLE_12000_A1 -0.221436
+#define CS_MIDDLE_12000_A2 0.000000
+#define CS_MIDDLE_12000_B1 -0.947616
+#define CS_MIDDLE_12000_B2 0.000000
+#define CS_MIDDLE_12000_SCALE 15
+#define CS_SIDE_12000_A0 0.558398
+#define CS_SIDE_12000_A1 -0.392211
+#define CS_SIDE_12000_A2 -0.166187
+#define CS_SIDE_12000_B1 -0.892550
+#define CS_SIDE_12000_B2 0.032856
+#define CS_SIDE_12000_SCALE 15
+
+/* Stereo Enhancer coefficients for 16000Hz sample rate, scaled with 0.162371 */
+#define CS_MIDDLE_16000_A0 0.230638
+#define CS_MIDDLE_16000_A1 -0.224232
+#define CS_MIDDLE_16000_A2 0.000000
+#define CS_MIDDLE_16000_B1 -0.960550
+#define CS_MIDDLE_16000_B2 0.000000
+#define CS_MIDDLE_16000_SCALE 15
+#define CS_SIDE_16000_A0 0.499695
+#define CS_SIDE_16000_A1 -0.355543
+#define CS_SIDE_16000_A2 -0.144152
+#define CS_SIDE_16000_B1 -1.050788
+#define CS_SIDE_16000_B2 0.144104
+#define CS_SIDE_16000_SCALE 14
+
+/* Stereo Enhancer coefficients for 22050Hz sample rate, scaled with 0.160781 */
+#define CS_MIDDLE_22050_A0 0.228749
+#define CS_MIDDLE_22050_A1 -0.224128
+#define CS_MIDDLE_22050_A2 0.000000
+#define CS_MIDDLE_22050_B1 -0.971262
+#define CS_MIDDLE_22050_B2 0.000000
+#define CS_MIDDLE_22050_SCALE 15
+#define CS_SIDE_22050_A0 0.440112
+#define CS_SIDE_22050_A1 -0.261096
+#define CS_SIDE_22050_A2 -0.179016
+#define CS_SIDE_22050_B1 -1.116786
+#define CS_SIDE_22050_B2 0.182507
+#define CS_SIDE_22050_SCALE 14
+
+/* Stereo Enhancer coefficients for 24000Hz sample rate, scaled with 0.161882 */
+#define CS_MIDDLE_24000_A0 0.230395
+#define CS_MIDDLE_24000_A1 -0.226117
+#define CS_MIDDLE_24000_A2 0.000000
+#define CS_MIDDLE_24000_B1 -0.973573
+#define CS_MIDDLE_24000_B2 0.000000
+#define CS_MIDDLE_24000_SCALE 15
+#define CS_SIDE_24000_A0 0.414770
+#define CS_SIDE_24000_A1 -0.287182
+#define CS_SIDE_24000_A2 -0.127588
+#define CS_SIDE_24000_B1 -1.229648
+#define CS_SIDE_24000_B2 0.282177
+#define CS_SIDE_24000_SCALE 14
+
+/* Stereo Enhancer coefficients for 32000Hz sample rate, scaled with 0.160322 */
+#define CS_MIDDLE_32000_A0 0.228400
+#define CS_MIDDLE_32000_A1 -0.225214
+#define CS_MIDDLE_32000_A2 0.000000
+#define CS_MIDDLE_32000_B1 -0.980126
+#define CS_MIDDLE_32000_B2 0.000000
+#define CS_MIDDLE_32000_SCALE 15
+#define CS_SIDE_32000_A0 0.364579
+#define CS_SIDE_32000_A1 -0.207355
+#define CS_SIDE_32000_A2 -0.157224
+#define CS_SIDE_32000_B1 -1.274231
+#define CS_SIDE_32000_B2 0.312495
+#define CS_SIDE_32000_SCALE 14
+
+/* Stereo Enhancer coefficients for 44100Hz sample rate, scaled with 0.163834 */
+#define CS_MIDDLE_44100_A0 0.233593
+#define CS_MIDDLE_44100_A1 -0.231225
+#define CS_MIDDLE_44100_A2 0.000000
+#define CS_MIDDLE_44100_B1 -0.985545
+#define CS_MIDDLE_44100_B2 0.000000
+#define CS_MIDDLE_44100_SCALE 15
+#define CS_SIDE_44100_A0 0.284573
+#define CS_SIDE_44100_A1 -0.258910
+#define CS_SIDE_44100_A2 -0.025662
+#define CS_SIDE_44100_B1 -1.572248
+#define CS_SIDE_44100_B2 0.588399
+#define CS_SIDE_44100_SCALE 14
+
+/* Stereo Enhancer coefficients for 48000Hz sample rate, scaled with 0.164402 */
+#define CS_MIDDLE_48000_A0 0.234445
+#define CS_MIDDLE_48000_A1 -0.232261
+#define CS_MIDDLE_48000_A2 0.000000
+#define CS_MIDDLE_48000_B1 -0.986713
+#define CS_MIDDLE_48000_B2 0.000000
+#define CS_MIDDLE_48000_SCALE 15
+#define CS_SIDE_48000_A0 0.272606
+#define CS_SIDE_48000_A1 -0.266952
+#define CS_SIDE_48000_A2 -0.005654
+#define CS_SIDE_48000_B1 -1.617141
+#define CS_SIDE_48000_B2 0.630405
+#define CS_SIDE_48000_SCALE 14
+
+#ifdef HIGHER_FS
+/* Stereo Enhancer coefficients for 96000Hz sample rate, scaled with 0.165*/
+/* high pass filter with cutoff frequency 102.18 Hz*/
+#define CS_MIDDLE_96000_A0 0.235532
+#define CS_MIDDLE_96000_A1 -0.234432
+#define CS_MIDDLE_96000_A2 0.000000
+#define CS_MIDDLE_96000_B1 -0.993334
+#define CS_MIDDLE_96000_B2 0.000000
+#define CS_MIDDLE_96000_SCALE 15
+/* bandpass filter with fc1 270 and fc2 3703, designed using 2nd order butterworth */
+#define CS_SIDE_96000_A0 0.016727
+#define CS_SIDE_96000_A1 0.000000
+#define CS_SIDE_96000_A2 -0.016727
+#define CS_SIDE_96000_B1 -1.793372
+#define CS_SIDE_96000_B2 0.797236
+#define CS_SIDE_96000_SCALE 14
+
+/* Stereo Enhancer coefficients for 192000Hz sample rate, scaled with 0.1689*/
+#define CS_MIDDLE_192000_A0 0.241219
+#define CS_MIDDLE_192000_A1 -0.240656
+#define CS_MIDDLE_192000_A2 0.000000
+#define CS_MIDDLE_192000_B1 -0.996661
+#define CS_MIDDLE_192000_B2 0.000000
+#define CS_MIDDLE_192000_SCALE 15
+/* bandpass filter with fc1 270 and fc2 3703, designed using 2nd order butterworth */
+#define CS_SIDE_192000_A0 0.008991
+#define CS_SIDE_192000_A1 -0.000000
+#define CS_SIDE_192000_A2 -0.008991
+#define CS_SIDE_192000_B1 -1.892509
+#define CS_SIDE_192000_B2 0.893524
+#define CS_SIDE_192000_SCALE 14
+#endif
+
+/************************************************************************************/
+/* */
+/* The Reverb Unit */
+/* */
+/************************************************************************************/
+
+/* Reverb delay settings in samples */
+#define LVCS_STEREODELAY_CS_8KHZ 93 /* Sample rate 8kS/s */
+#define LVCS_STEREODELAY_CS_11KHZ 128 /* Sample rate 11kS/s */
+#define LVCS_STEREODELAY_CS_12KHZ 139 /* Sample rate 12kS/s */
+#define LVCS_STEREODELAY_CS_16KHZ 186 /* Sample rate 16kS/s */
+#define LVCS_STEREODELAY_CS_22KHZ 256 /* Sample rate 22kS/s */
+#define LVCS_STEREODELAY_CS_24KHZ 279 /* Sample rate 24kS/s */
+#define LVCS_STEREODELAY_CS_32KHZ 372 /* Sample rate 32kS/s */
+#define LVCS_STEREODELAY_CS_44KHZ 512 /* Sample rate 44kS/s */
+#define LVCS_STEREODELAY_CS_48KHZ 512 /* Sample rate 48kS/s */
+
+/* Reverb coefficients for 8000 Hz sample rate, scaled with 1.038030 */
+#define CS_REVERB_8000_A0 0.667271
+#define CS_REVERB_8000_A1 -0.667271
+#define CS_REVERB_8000_A2 0.000000
+#define CS_REVERB_8000_B1 -0.668179
+#define CS_REVERB_8000_B2 0.000000
+#define CS_REVERB_8000_SCALE 15
+
+/* Reverb coefficients for 11025Hz sample rate, scaled with 1.038030 */
+#define CS_REVERB_11025_A0 0.699638
+#define CS_REVERB_11025_A1 -0.699638
+#define CS_REVERB_11025_A2 0.000000
+#define CS_REVERB_11025_B1 -0.749096
+#define CS_REVERB_11025_B2 0.000000
+#define CS_REVERB_11025_SCALE 15
+
+/* Reverb coefficients for 12000Hz sample rate, scaled with 1.038030 */
+#define CS_REVERB_12000_A0 0.706931
+#define CS_REVERB_12000_A1 -0.706931
+#define CS_REVERB_12000_A2 0.000000
+#define CS_REVERB_12000_B1 -0.767327
+#define CS_REVERB_12000_B2 0.000000
+#define CS_REVERB_12000_SCALE 15
+
+/* Reverb coefficients for 16000Hz sample rate, scaled with 1.038030 */
+#define CS_REVERB_16000_A0 0.728272
+#define CS_REVERB_16000_A1 -0.728272
+#define CS_REVERB_16000_A2 0.000000
+#define CS_REVERB_16000_B1 -0.820679
+#define CS_REVERB_16000_B2 0.000000
+#define CS_REVERB_16000_SCALE 15
+
+/* Reverb coefficients for 22050Hz sample rate, scaled with 1.038030 */
+#define CS_REVERB_22050_A0 0.516396
+#define CS_REVERB_22050_A1 0.000000
+#define CS_REVERB_22050_A2 -0.516396
+#define CS_REVERB_22050_B1 -0.518512
+#define CS_REVERB_22050_B2 -0.290990
+#define CS_REVERB_22050_SCALE 15
+
+
+/* Reverb coefficients for 24000Hz sample rate, scaled with 1.038030 */
+#define CS_REVERB_24000_A0 0.479565
+#define CS_REVERB_24000_A1 0.000000
+#define CS_REVERB_24000_A2 -0.479565
+#define CS_REVERB_24000_B1 -0.637745
+#define CS_REVERB_24000_B2 -0.198912
+#define CS_REVERB_24000_SCALE 15
+
+/* Reverb coefficients for 32000Hz sample rate, scaled with 1.038030 */
+#define CS_REVERB_32000_A0 0.380349
+#define CS_REVERB_32000_A1 0.000000
+#define CS_REVERB_32000_A2 -0.380349
+#define CS_REVERB_32000_B1 -0.950873
+#define CS_REVERB_32000_B2 0.049127
+#define CS_REVERB_32000_SCALE 15
+
+/* Reverb coefficients for 44100Hz sample rate, scaled with 1.038030 */
+#define CS_REVERB_44100_A0 0.297389
+#define CS_REVERB_44100_A1 0.000000
+#define CS_REVERB_44100_A2 -0.297389
+#define CS_REVERB_44100_B1 -1.200423
+#define CS_REVERB_44100_B2 0.256529
+#define CS_REVERB_44100_SCALE 14
+
+/* Reverb coefficients for 48000Hz sample rate, scaled with 1.038030 */
+#define CS_REVERB_48000_A0 0.278661
+#define CS_REVERB_48000_A1 0.000000
+#define CS_REVERB_48000_A2 -0.278661
+#define CS_REVERB_48000_B1 -1.254993
+#define CS_REVERB_48000_B2 0.303347
+#define CS_REVERB_48000_SCALE 14
+
+#ifdef HIGHER_FS
+/* Reverb coefficients for 96000Hz sample rate, scaled with 0.8 */
+/* Band pass filter with fc1=500 and fc2=8000*/
+#define CS_REVERB_96000_A0 0.1602488
+#define CS_REVERB_96000_A1 0.000000
+#define CS_REVERB_96000_A2 -0.1602488
+#define CS_REVERB_96000_B1 -1.585413
+#define CS_REVERB_96000_B2 0.599377
+#define CS_REVERB_96000_SCALE 14
+
+/* Reverb coefficients for 192000Hz sample rate, scaled with 0.8 */
+/* Band pass filter with fc1=500 and fc2=8000*/
+#define CS_REVERB_192000_A0 0.0878369
+#define CS_REVERB_192000_A1 0.000000
+#define CS_REVERB_192000_A2 -0.0878369
+#define CS_REVERB_192000_B1 -1.7765764
+#define CS_REVERB_192000_B2 0.7804076
+#define CS_REVERB_192000_SCALE 14
+
+#endif
+
+
+/* Reverb Gain Settings */
+#define LVCS_HEADPHONE_DELAYGAIN 0.800000 /* Algorithm delay path gain */
+#define LVCS_HEADPHONE_OUTPUTGAIN 1.000000 /* Algorithm output gain */
+#define LVCS_HEADPHONE_PROCGAIN 18403 /* Processed path gain */
+#define LVCS_HEADPHONE_UNPROCGAIN 18403 /* Unprocessed path gain */
+#define LVCS_HEADPHONE_GAINCORRECT 1.009343 /* Delay mixer gain correction */
+
+/************************************************************************************/
+/* */
+/* The Equaliser */
+/* */
+/************************************************************************************/
+
+/* Equaliser coefficients for 8000 Hz sample rate, \
+ CS scaled with 1.038497 and CSEX scaled with 0.775480 */
+#define CS_EQUALISER_8000_A0 1.263312
+#define CS_EQUALISER_8000_A1 -0.601748
+#define CS_EQUALISER_8000_A2 -0.280681
+#define CS_EQUALISER_8000_B1 -0.475865
+#define CS_EQUALISER_8000_B2 -0.408154
+#define CS_EQUALISER_8000_SCALE 14
+#define CSEX_EQUALISER_8000_A0 0.943357
+#define CSEX_EQUALISER_8000_A1 -0.449345
+#define CSEX_EQUALISER_8000_A2 -0.209594
+#define CSEX_EQUALISER_8000_B1 -0.475865
+#define CSEX_EQUALISER_8000_B2 -0.408154
+#define CSEX_EQUALISER_8000_SCALE 15
+
+/* Equaliser coefficients for 11025Hz sample rate, \
+ CS scaled with 1.027761 and CSEX scaled with 0.767463 */
+#define CS_EQUALISER_11025_A0 1.101145
+#define CS_EQUALISER_11025_A1 0.139020
+#define CS_EQUALISER_11025_A2 -0.864423
+#define CS_EQUALISER_11025_B1 0.024541
+#define CS_EQUALISER_11025_B2 -0.908930
+#define CS_EQUALISER_11025_SCALE 14
+#define CSEX_EQUALISER_11025_A0 0.976058
+#define CSEX_EQUALISER_11025_A1 -0.695326
+#define CSEX_EQUALISER_11025_A2 -0.090809
+#define CSEX_EQUALISER_11025_B1 -0.610594
+#define CSEX_EQUALISER_11025_B2 -0.311149
+#define CSEX_EQUALISER_11025_SCALE 15
+
+/* Equaliser coefficients for 12000Hz sample rate, \
+ CS scaled with 1.032521 and CSEX scaled with 0.771017 */
+#define CS_EQUALISER_12000_A0 1.276661
+#define CS_EQUALISER_12000_A1 -1.017519
+#define CS_EQUALISER_12000_A2 -0.044128
+#define CS_EQUALISER_12000_B1 -0.729616
+#define CS_EQUALISER_12000_B2 -0.204532
+#define CS_EQUALISER_12000_SCALE 14
+#define CSEX_EQUALISER_12000_A0 1.007095
+#define CSEX_EQUALISER_12000_A1 -0.871912
+#define CSEX_EQUALISER_12000_A2 0.023232
+#define CSEX_EQUALISER_12000_B1 -0.745857
+#define CSEX_EQUALISER_12000_B2 -0.189171
+#define CSEX_EQUALISER_12000_SCALE 14
+
+/* Equaliser coefficients for 16000Hz sample rate, \
+ CS scaled with 1.031378 and CSEX scaled with 0.770164 */
+#define CS_EQUALISER_16000_A0 1.281629
+#define CS_EQUALISER_16000_A1 -1.075872
+#define CS_EQUALISER_16000_A2 -0.041365
+#define CS_EQUALISER_16000_B1 -0.725239
+#define CS_EQUALISER_16000_B2 -0.224358
+#define CS_EQUALISER_16000_SCALE 14
+#define CSEX_EQUALISER_16000_A0 1.081091
+#define CSEX_EQUALISER_16000_A1 -0.867183
+#define CSEX_EQUALISER_16000_A2 -0.070247
+#define CSEX_EQUALISER_16000_B1 -0.515121
+#define CSEX_EQUALISER_16000_B2 -0.425893
+#define CSEX_EQUALISER_16000_SCALE 14
+
+/* Equaliser coefficients for 22050Hz sample rate, \
+ CS scaled with 1.041576 and CSEX scaled with 0.777779 */
+#define CS_EQUALISER_22050_A0 1.388605
+#define CS_EQUALISER_22050_A1 -1.305799
+#define CS_EQUALISER_22050_A2 0.039922
+#define CS_EQUALISER_22050_B1 -0.719494
+#define CS_EQUALISER_22050_B2 -0.243245
+#define CS_EQUALISER_22050_SCALE 14
+#define CSEX_EQUALISER_22050_A0 1.272910
+#define CSEX_EQUALISER_22050_A1 -1.341014
+#define CSEX_EQUALISER_22050_A2 0.167462
+#define CSEX_EQUALISER_22050_B1 -0.614219
+#define CSEX_EQUALISER_22050_B2 -0.345384
+#define CSEX_EQUALISER_22050_SCALE 14
+
+/* Equaliser coefficients for 24000Hz sample rate, \
+ CS scaled with 1.034495 and CSEX scaled with 0.772491 */
+#define CS_EQUALISER_24000_A0 1.409832
+#define CS_EQUALISER_24000_A1 -1.456506
+#define CS_EQUALISER_24000_A2 0.151410
+#define CS_EQUALISER_24000_B1 -0.804201
+#define CS_EQUALISER_24000_B2 -0.163783
+#define CS_EQUALISER_24000_SCALE 14
+#define CSEX_EQUALISER_24000_A0 1.299198
+#define CSEX_EQUALISER_24000_A1 -1.452447
+#define CSEX_EQUALISER_24000_A2 0.240489
+#define CSEX_EQUALISER_24000_B1 -0.669303
+#define CSEX_EQUALISER_24000_B2 -0.294984
+#define CSEX_EQUALISER_24000_SCALE 14
+
+/* Equaliser coefficients for 32000Hz sample rate, \
+ CS scaled with 1.044559 and CSEX scaled with 0.780006 */
+#define CS_EQUALISER_32000_A0 1.560988
+#define CS_EQUALISER_32000_A1 -1.877724
+#define CS_EQUALISER_32000_A2 0.389741
+#define CS_EQUALISER_32000_B1 -0.907410
+#define CS_EQUALISER_32000_B2 -0.070489
+#define CS_EQUALISER_32000_SCALE 14
+#define CSEX_EQUALISER_32000_A0 1.785049
+#define CSEX_EQUALISER_32000_A1 -2.233497
+#define CSEX_EQUALISER_32000_A2 0.526431
+#define CSEX_EQUALISER_32000_B1 -0.445939
+#define CSEX_EQUALISER_32000_B2 -0.522446
+#define CSEX_EQUALISER_32000_SCALE 13
+
+/* Equaliser coefficients for 44100Hz sample rate, \
+ CS scaled with 1.022170 and CSEX scaled with 0.763288 */
+#define CS_EQUALISER_44100_A0 1.623993
+#define CS_EQUALISER_44100_A1 -2.270743
+#define CS_EQUALISER_44100_A2 0.688829
+#define CS_EQUALISER_44100_B1 -1.117190
+#define CS_EQUALISER_44100_B2 0.130208
+#define CS_EQUALISER_44100_SCALE 13
+#define CSEX_EQUALISER_44100_A0 2.028315
+#define CSEX_EQUALISER_44100_A1 -2.882459
+#define CSEX_EQUALISER_44100_A2 0.904535
+#define CSEX_EQUALISER_44100_B1 -0.593308
+#define CSEX_EQUALISER_44100_B2 -0.385816
+#define CSEX_EQUALISER_44100_SCALE 13
+
+/* Equaliser coefficients for 48000Hz sample rate, \
+ CS scaled with 1.018635 and CSEX scaled with 0.760648 */
+#define CS_EQUALISER_48000_A0 1.641177
+#define CS_EQUALISER_48000_A1 -2.364687
+#define CS_EQUALISER_48000_A2 0.759910
+#define CS_EQUALISER_48000_B1 -1.166774
+#define CS_EQUALISER_48000_B2 0.178074
+#define CS_EQUALISER_48000_SCALE 13
+#define CSEX_EQUALISER_48000_A0 2.099655
+#define CSEX_EQUALISER_48000_A1 -3.065220
+#define CSEX_EQUALISER_48000_A2 1.010417
+#define CSEX_EQUALISER_48000_B1 -0.634021
+#define CSEX_EQUALISER_48000_B2 -0.347332
+#define CSEX_EQUALISER_48000_SCALE 13
+
+
+#ifdef HIGHER_FS
+#define CS_EQUALISER_96000_A0 1.784497
+#define CS_EQUALISER_96000_A1 -3.001435
+#define CS_EQUALISER_96000_A2 1.228422
+#define CS_EQUALISER_96000_B1 -1.477804
+#define CS_EQUALISER_96000_B2 0.481369
+#define CS_EQUALISER_96000_SCALE 13
+#define CSEX_EQUALISER_96000_A0 2.7573
+#define CSEX_EQUALISER_96000_A1 -4.6721
+#define CSEX_EQUALISER_96000_A2 1.9317
+#define CSEX_EQUALISER_96000_B1 -0.971718
+#define CSEX_EQUALISER_96000_B2 -0.021216
+#define CSEX_EQUALISER_96000_SCALE 13
+
+#define CS_EQUALISER_192000_A0 1.889582
+#define CS_EQUALISER_192000_A1 -3.456140
+#define CS_EQUALISER_192000_A2 1.569864
+#define CS_EQUALISER_192000_B1 -1.700798
+#define CS_EQUALISER_192000_B2 0.701824
+#define CS_EQUALISER_192000_SCALE 13
+#define CSEX_EQUALISER_192000_A0 3.4273
+#define CSEX_EQUALISER_192000_A1 -6.2936
+#define CSEX_EQUALISER_192000_A2 2.8720
+#define CSEX_EQUALISER_192000_B1 -1.31074
+#define CSEX_EQUALISER_192000_B2 0.31312
+#define CSEX_EQUALISER_192000_SCALE 13
+#endif
+
+
+#define LVCS_HEADPHONE_SHIFT 2 /* Output Shift */
+#define LVCS_HEADPHONE_SHIFTLOSS 0.8477735 /* Output Shift loss */
+#define LVCS_HEADPHONE_GAIN 0.2087465 /* Unprocessed path gain */
+#define LVCS_EX_HEADPHONE_SHIFT 3 /* EX Output Shift */
+#define LVCS_EX_HEADPHONE_SHIFTLOSS 0.569225 /* EX Output Shift loss */
+#define LVCS_EX_HEADPHONE_GAIN 0.07794425 /* EX Unprocessed path gain */
+#else
/* Stereo Enhancer coefficients for 8000 Hz sample rate, scaled with 0.161258 */
#define CS_MIDDLE_8000_A0 7462 /* Floating point value 0.227720 */
#define CS_MIDDLE_8000_A1 (-7049) /* Floating point value -0.215125 */
@@ -394,5 +850,6 @@
#define LVCS_EX_HEADPHONE_SHIFT 3 /* EX Output Shift */
#define LVCS_EX_HEADPHONE_SHIFTLOSS 18600 /* EX Output Shift loss */
#define LVCS_EX_HEADPHONE_GAIN 5108 /* EX Unprocessed path gain */
-
#endif
+#endif
+
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Init.c b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Init.c
index 1904e46..d4c7627 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Init.c
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Init.c
@@ -98,7 +98,13 @@
/*
* Scratch memory
*/
+#ifdef BUILD_FLOAT
+ /* Inplace processing */
+ ScratchSize = (LVM_UINT32) \
+ (LVCS_SCRATCHBUFFERS * sizeof(LVM_FLOAT) * pCapabilities->MaxBlockSize);
+#else
ScratchSize = (LVM_UINT32)(LVCS_SCRATCHBUFFERS*sizeof(LVM_INT16)*pCapabilities->MaxBlockSize); /* Inplace processing */
+#endif
pMemoryTable->Region[LVCS_MEMREGION_TEMPORARY_FAST].Size = ScratchSize;
pMemoryTable->Region[LVCS_MEMREGION_TEMPORARY_FAST].Type = LVCS_SCRATCH;
pMemoryTable->Region[LVCS_MEMREGION_TEMPORARY_FAST].pBaseAddress = LVM_NULL;
@@ -190,6 +196,7 @@
pLVCS_VolCorrectTable = (LVCS_VolCorrect_t*)&LVCS_VolCorrectTable[0];
pInstance->VolCorrect = pLVCS_VolCorrectTable[0];
pInstance->TransitionGain = 0;
+
/* These current and target values are intialized again in LVCS_Control.c */
LVC_Mixer_Init(&pInstance->BypassMix.Mixer_Instance.MixerStream[0],0,0);
/* These current and target values are intialized again in LVCS_Control.c */
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Private.h b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Private.h
index f3adb8d..a97e4f0 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Private.h
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Private.h
@@ -95,10 +95,17 @@
/* Volume correction structure */
typedef struct
{
+#ifdef BUILD_FLOAT
+ LVM_FLOAT CompFull; /* Post CS compression 100% effect */
+ LVM_FLOAT CompMin; /* Post CS compression 0% effect */
+ LVM_FLOAT GainFull; /* CS gain correct 100% effect */
+ LVM_FLOAT GainMin; /* CS gain correct 0% effect */
+#else
LVM_INT16 CompFull; /* Post CS compression 100% effect */
LVM_INT16 CompMin; /* Post CS compression 0% effect */
LVM_INT16 GainFull; /* CS gain correct 100% effect */
LVM_INT16 GainMin; /* CS gain correct 0% effect */
+#endif
} LVCS_VolCorrect_t;
/* Instance structure */
@@ -112,8 +119,13 @@
/* Private parameters */
LVCS_OutputDevice_en OutputDevice; /* Selected output device type */
LVCS_VolCorrect_t VolCorrect; /* Volume correction settings */
+#ifndef BUILD_FLOAT
LVM_INT16 TransitionGain; /* Transition gain */
LVM_INT16 CompressGain; /* Last used compressor gain*/
+#else
+ LVM_FLOAT TransitionGain; /* Transition gain */
+ LVM_FLOAT CompressGain; /* Last used compressor gain*/
+#endif
/* Sub-block configurations */
LVCS_StereoEnhancer_t StereoEnhancer; /* Stereo enhancer configuration */
@@ -134,24 +146,35 @@
/* Coefficient Structure */
typedef struct
{
+#ifdef BUILD_FLOAT
+ Biquad_FLOAT_Instance_t EqualiserBiquadInstance;
+ Biquad_FLOAT_Instance_t ReverbBiquadInstance;
+ Biquad_FLOAT_Instance_t SEBiquadInstanceMid;
+ Biquad_FLOAT_Instance_t SEBiquadInstanceSide;
+#else
Biquad_Instance_t EqualiserBiquadInstance;
Biquad_Instance_t ReverbBiquadInstance;
Biquad_Instance_t SEBiquadInstanceMid;
Biquad_Instance_t SEBiquadInstanceSide;
-
+#endif
} LVCS_Coefficient_t;
/* Data Structure */
typedef struct
{
+#ifdef BUILD_FLOAT
+ Biquad_2I_Order2_FLOAT_Taps_t EqualiserBiquadTaps;
+ Biquad_2I_Order2_FLOAT_Taps_t ReverbBiquadTaps;
+ Biquad_1I_Order1_FLOAT_Taps_t SEBiquadTapsMid;
+ Biquad_1I_Order2_FLOAT_Taps_t SEBiquadTapsSide;
+#else
Biquad_2I_Order2_Taps_t EqualiserBiquadTaps;
Biquad_2I_Order2_Taps_t ReverbBiquadTaps;
Biquad_1I_Order1_Taps_t SEBiquadTapsMid;
Biquad_1I_Order2_Taps_t SEBiquadTapsSide;
-
+#endif
} LVCS_Data_t;
-
void LVCS_TimerCallBack ( void* hInstance,
void* pCallBackParams,
LVM_INT32 CallbackParam);
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Process.c b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Process.c
index 5d99461..3956d4d 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Process.c
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Process.c
@@ -66,7 +66,77 @@
/* NOTES: */
/* */
/************************************************************************************/
+#ifdef BUILD_FLOAT
+LVCS_ReturnStatus_en LVCS_Process_CS(LVCS_Handle_t hInstance,
+ const LVM_FLOAT *pInData,
+ LVM_FLOAT *pOutData,
+ LVM_UINT16 NumSamples)
+{
+ const LVM_FLOAT *pInput;
+ LVCS_Instance_t *pInstance = (LVCS_Instance_t *)hInstance;
+ LVM_FLOAT *pScratch;
+ LVCS_ReturnStatus_en err;
+ pScratch = (LVM_FLOAT *) \
+ pInstance->MemoryTable.Region[LVCS_MEMREGION_TEMPORARY_FAST].pBaseAddress;
+
+ /*
+ * Check if the processing is inplace
+ */
+ if (pInData == pOutData)
+ {
+ /* Processing inplace */
+ pInput = pScratch + (2 * NumSamples);
+ Copy_Float((LVM_FLOAT *)pInData, /* Source */
+ (LVM_FLOAT *)pInput, /* Destination */
+ (LVM_INT16)(2 * NumSamples)); /* Left and right */
+ }
+ else
+ {
+ /* Processing outplace */
+ pInput = pInData;
+ }
+
+ /*
+ * Call the stereo enhancer
+ */
+ err = LVCS_StereoEnhancer(hInstance, /* Instance handle */
+ pInData, /* Pointer to the input data */
+ pOutData, /* Pointer to the output data */
+ NumSamples); /* Number of samples to process */
+
+ /*
+ * Call the reverb generator
+ */
+ err = LVCS_ReverbGenerator(hInstance, /* Instance handle */
+ pOutData, /* Pointer to the input data */
+ pOutData, /* Pointer to the output data */
+ NumSamples); /* Number of samples to process */
+
+ /*
+ * Call the equaliser
+ */
+ err = LVCS_Equaliser(hInstance, /* Instance handle */
+ pOutData, /* Pointer to the input data */
+ NumSamples); /* Number of samples to process */
+
+ /*
+ * Call the bypass mixer
+ */
+ err = LVCS_BypassMixer(hInstance, /* Instance handle */
+ pOutData, /* Pointer to the processed data */
+ pInput, /* Pointer to the input (unprocessed) data */
+ pOutData, /* Pointer to the output data */
+ NumSamples); /* Number of samples to process */
+
+ if(err != LVCS_SUCCESS)
+ {
+ return err;
+ }
+
+ return(LVCS_SUCCESS);
+}
+#else
LVCS_ReturnStatus_en LVCS_Process_CS(LVCS_Handle_t hInstance,
const LVM_INT16 *pInData,
LVM_INT16 *pOutData,
@@ -133,7 +203,7 @@
return(LVCS_SUCCESS);
}
-
+#endif
/************************************************************************************/
/* */
/* FUNCTION: LVCS_Process */
@@ -160,7 +230,170 @@
/* NOTES: */
/* */
/************************************************************************************/
+#ifdef BUILD_FLOAT
+LVCS_ReturnStatus_en LVCS_Process(LVCS_Handle_t hInstance,
+ const LVM_FLOAT *pInData,
+ LVM_FLOAT *pOutData,
+ LVM_UINT16 NumSamples)
+{
+ LVCS_Instance_t *pInstance = (LVCS_Instance_t *)hInstance;
+ LVCS_ReturnStatus_en err;
+
+ /*
+ * Check the number of samples is not too large
+ */
+ if (NumSamples > pInstance->Capabilities.MaxBlockSize)
+ {
+ return(LVCS_TOOMANYSAMPLES);
+ }
+
+ /*
+ * Check if the algorithm is enabled
+ */
+ if (pInstance->Params.OperatingMode != LVCS_OFF)
+ {
+ /*
+ * Call CS process function
+ */
+ err = LVCS_Process_CS(hInstance,
+ pInData,
+ pOutData,
+ NumSamples);
+
+
+ /*
+ * Compress to reduce expansion effect of Concert Sound and correct volume
+ * differences for difference settings. Not applied in test modes
+ */
+ if ((pInstance->Params.OperatingMode == LVCS_ON)&& \
+ (pInstance->Params.CompressorMode == LVM_MODE_ON))
+ {
+ LVM_FLOAT Gain = pInstance->VolCorrect.CompMin;
+ LVM_FLOAT Current1;
+
+ Current1 = LVC_Mixer_GetCurrent(&pInstance->BypassMix.Mixer_Instance.MixerStream[0]);
+ Gain = (LVM_FLOAT)( pInstance->VolCorrect.CompMin
+ - (((LVM_FLOAT)pInstance->VolCorrect.CompMin * (Current1)))
+ + (((LVM_FLOAT)pInstance->VolCorrect.CompFull * (Current1))));
+
+ if(NumSamples < LVCS_COMPGAINFRAME)
+ {
+ NonLinComp_Float(Gain, /* Compressor gain setting */
+ pOutData,
+ pOutData,
+ (LVM_INT32)(2 * NumSamples));
+ }
+ else
+ {
+ LVM_FLOAT GainStep;
+ LVM_FLOAT FinalGain;
+ LVM_INT16 SampleToProcess = NumSamples;
+ LVM_FLOAT *pOutPtr;
+
+ /* Large changes in Gain can cause clicks in output
+ Split data into small blocks and use interpolated gain values */
+
+ GainStep = (LVM_FLOAT)(((Gain-pInstance->CompressGain) * \
+ LVCS_COMPGAINFRAME) / NumSamples);
+
+ if((GainStep == 0) && (pInstance->CompressGain < Gain))
+ {
+ GainStep = 1;
+ }
+ else
+ {
+ if((GainStep == 0) && (pInstance->CompressGain > Gain))
+ {
+ GainStep = -1;
+ }
+ }
+
+ FinalGain = Gain;
+ Gain = pInstance->CompressGain;
+ pOutPtr = pOutData;
+
+ while(SampleToProcess > 0)
+ {
+ Gain = (LVM_FLOAT)(Gain + GainStep);
+ if((GainStep > 0) && (FinalGain <= Gain))
+ {
+ Gain = FinalGain;
+ GainStep = 0;
+ }
+
+ if((GainStep < 0) && (FinalGain > Gain))
+ {
+ Gain = FinalGain;
+ GainStep = 0;
+ }
+
+ if(SampleToProcess > LVCS_COMPGAINFRAME)
+ {
+ NonLinComp_Float(Gain, /* Compressor gain setting */
+ pOutPtr,
+ pOutPtr,
+ (LVM_INT32)(2 * LVCS_COMPGAINFRAME));
+ pOutPtr += (2 * LVCS_COMPGAINFRAME);
+ SampleToProcess = (LVM_INT16)(SampleToProcess - LVCS_COMPGAINFRAME);
+ }
+ else
+ {
+ NonLinComp_Float(Gain, /* Compressor gain setting */
+ pOutPtr,
+ pOutPtr,
+ (LVM_INT32)(2 * SampleToProcess));
+ SampleToProcess = 0;
+ }
+
+ }
+ }
+
+ /* Store gain value*/
+ pInstance->CompressGain = Gain;
+ }
+
+
+ if(pInstance->bInOperatingModeTransition == LVM_TRUE){
+
+ /*
+ * Re-init bypass mix when timer has completed
+ */
+ if ((pInstance->bTimerDone == LVM_TRUE) &&
+ (pInstance->BypassMix.Mixer_Instance.MixerStream[1].CallbackSet == 0))
+ {
+ err = LVCS_BypassMixInit(hInstance,
+ &pInstance->Params);
+
+ if(err != LVCS_SUCCESS)
+ {
+ return err;
+ }
+
+ }
+ else{
+ LVM_Timer ( &pInstance->TimerInstance,
+ (LVM_INT16)NumSamples);
+ }
+ }
+ }
+ else
+ {
+ if (pInData != pOutData)
+ {
+ /*
+ * The algorithm is disabled so just copy the data
+ */
+ Copy_Float((LVM_FLOAT *)pInData, /* Source */
+ (LVM_FLOAT *)pOutData, /* Destination */
+ (LVM_INT16)(2 * NumSamples)); /* Left and right */
+ }
+ }
+
+
+ return(LVCS_SUCCESS);
+}
+#else
LVCS_ReturnStatus_en LVCS_Process(LVCS_Handle_t hInstance,
const LVM_INT16 *pInData,
LVM_INT16 *pOutData,
@@ -321,13 +554,4 @@
return(LVCS_SUCCESS);
}
-
-
-
-
-
-
-
-
-
-
+#endif
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_ReverbGenerator.c b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_ReverbGenerator.c
index ee257b8..1085101 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_ReverbGenerator.c
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_ReverbGenerator.c
@@ -57,7 +57,98 @@
/* 2. The numerator coefficients of the filter are negated to cause an inversion. */
/* */
/************************************************************************************/
+#ifdef BUILD_FLOAT
+LVCS_ReturnStatus_en LVCS_ReverbGeneratorInit(LVCS_Handle_t hInstance,
+ LVCS_Params_t *pParams)
+{
+ LVM_UINT16 Delay;
+ LVM_UINT16 Offset;
+ LVCS_Instance_t *pInstance = (LVCS_Instance_t *)hInstance;
+ LVCS_ReverbGenerator_t *pConfig = (LVCS_ReverbGenerator_t *)&pInstance->Reverberation;
+ LVCS_Data_t *pData;
+ LVCS_Coefficient_t *pCoefficients;
+ BQ_FLOAT_Coefs_t Coeffs;
+ const BiquadA012B12CoefsSP_t *pReverbCoefTable;
+
+
+ pData = (LVCS_Data_t *) \
+ pInstance->MemoryTable.Region[LVCS_MEMREGION_PERSISTENT_FAST_DATA].pBaseAddress;
+
+ pCoefficients = (LVCS_Coefficient_t *) \
+ pInstance->MemoryTable.Region[LVCS_MEMREGION_PERSISTENT_FAST_COEF].pBaseAddress;
+
+ /*
+ * Initialise the delay and filters if:
+ * - the sample rate has changed
+ * - the speaker type has changed to or from the mobile speaker
+ */
+ if(pInstance->Params.SampleRate != pParams->SampleRate ) /* Sample rate change test */
+
+ {
+ /*
+ * Setup the delay
+ */
+ Delay = (LVM_UINT16)LVCS_StereoDelayCS[(LVM_UINT16)pParams->SampleRate];
+
+
+ pConfig->DelaySize = (LVM_INT16)(2 * Delay);
+ pConfig->DelayOffset = 0;
+ LoadConst_Float(0, /* Value */
+ (LVM_FLOAT *)&pConfig->StereoSamples[0], /* Destination */
+ /* Number of words */
+ (LVM_UINT16)(sizeof(pConfig->StereoSamples) / sizeof(LVM_FLOAT)));
+ /*
+ * Setup the filters
+ */
+ Offset = (LVM_UINT16)pParams->SampleRate;
+ pReverbCoefTable = (BiquadA012B12CoefsSP_t*)&LVCS_ReverbCoefTable[0];
+
+ /* Convert incoming coefficients to the required format/ordering */
+ Coeffs.A0 = (LVM_FLOAT)pReverbCoefTable[Offset].A0;
+ Coeffs.A1 = (LVM_FLOAT)pReverbCoefTable[Offset].A1;
+ Coeffs.A2 = (LVM_FLOAT)pReverbCoefTable[Offset].A2;
+ Coeffs.B1 = (LVM_FLOAT)-pReverbCoefTable[Offset].B1;
+ Coeffs.B2 = (LVM_FLOAT)-pReverbCoefTable[Offset].B2;
+
+ LoadConst_Float(0, /* Value */
+ (void *)&pData->ReverbBiquadTaps, /* Destination Cast to void:
+ no dereferencing in function*/
+ /* Number of words */
+ (LVM_UINT16)(sizeof(pData->ReverbBiquadTaps) / sizeof(LVM_FLOAT)));
+
+ BQ_2I_D16F16Css_TRC_WRA_01_Init(&pCoefficients->ReverbBiquadInstance,
+ &pData->ReverbBiquadTaps,
+ &Coeffs);
+
+ /* Callbacks */
+ switch(pReverbCoefTable[Offset].Scale)
+ {
+ case 14:
+ pConfig->pBiquadCallBack = BQ_2I_D16F16C14_TRC_WRA_01;
+ break;
+ case 15:
+ pConfig->pBiquadCallBack = BQ_2I_D16F16C15_TRC_WRA_01;
+ break;
+ }
+
+
+ /*
+ * Setup the mixer
+ */
+ pConfig->ProcGain = (LVM_UINT16)(HEADPHONEGAINPROC);
+ pConfig->UnprocGain = (LVM_UINT16)(HEADPHONEGAINUNPROC);
+ }
+
+ if(pInstance->Params.ReverbLevel != pParams->ReverbLevel)
+ {
+ LVM_INT32 ReverbPercentage = 83886; // 1 Percent Reverb i.e 1/100 in Q 23 format
+ ReverbPercentage *= pParams->ReverbLevel; // Actual Reverb Level in Q 23 format
+ pConfig->ReverbLevel = ((LVM_FLOAT)(ReverbPercentage>>8)) / 32767.0f;
+ }
+ return(LVCS_SUCCESS);
+}
+#else
LVCS_ReturnStatus_en LVCS_ReverbGeneratorInit(LVCS_Handle_t hInstance,
LVCS_Params_t *pParams)
{
@@ -140,7 +231,7 @@
return(LVCS_SUCCESS);
}
-
+#endif
/************************************************************************************/
/* */
/* FUNCTION: LVCS_Reverb */
@@ -179,7 +270,91 @@
/* 2. The Gain is combined with the LPF and incorporated in to the coefficients */
/* */
/************************************************************************************/
+#ifdef BUILD_FLOAT
+LVCS_ReturnStatus_en LVCS_ReverbGenerator(LVCS_Handle_t hInstance,
+ const LVM_FLOAT *pInData,
+ LVM_FLOAT *pOutData,
+ LVM_UINT16 NumSamples)
+{
+ LVCS_Instance_t *pInstance = (LVCS_Instance_t *)hInstance;
+ LVCS_ReverbGenerator_t *pConfig = (LVCS_ReverbGenerator_t *)&pInstance->Reverberation;
+ LVCS_Coefficient_t *pCoefficients;
+ LVM_FLOAT *pScratch;
+
+ pCoefficients = (LVCS_Coefficient_t *)\
+ pInstance->MemoryTable.Region[LVCS_MEMREGION_PERSISTENT_FAST_COEF].pBaseAddress;
+
+ pScratch = (LVM_FLOAT *)\
+ pInstance->MemoryTable.Region[LVCS_MEMREGION_TEMPORARY_FAST].pBaseAddress;
+
+ /*
+ * Copy the data to the output in outplace processing
+ */
+ if (pInData != pOutData)
+ {
+ /*
+ * Reverb not required so just copy the data
+ */
+ Copy_Float((LVM_FLOAT *)pInData, /* Source */
+ (LVM_FLOAT *)pOutData, /* Destination */
+ (LVM_INT16)(2 * NumSamples)); /* Left and right */
+ }
+
+
+ /*
+ * Check if the reverb is required
+ */
+ /* Disable when CS4MS in stereo mode */
+ if (((pInstance->Params.SpeakerType == LVCS_HEADPHONE) || \
+ (pInstance->Params.SpeakerType == LVCS_EX_HEADPHONES) ||
+ (pInstance->Params.SourceFormat != LVCS_STEREO)) &&
+ /* For validation testing */
+ ((pInstance->Params.OperatingMode & LVCS_REVERBSWITCH) !=0))
+ {
+ /********************************************************************************/
+ /* */
+ /* Copy the input data to scratch memory and filter it */
+ /* */
+ /********************************************************************************/
+
+ /*
+ * Copy the input data to the scratch memory
+ */
+ Copy_Float((LVM_FLOAT *)pInData, /* Source */
+ (LVM_FLOAT *)pScratch, /* Destination */
+ (LVM_INT16)(2 * NumSamples)); /* Left and right */
+
+ /*
+ * Filter the data
+ */
+ (pConfig->pBiquadCallBack)((Biquad_FLOAT_Instance_t*)&pCoefficients->ReverbBiquadInstance,
+ (LVM_FLOAT *)pScratch,
+ (LVM_FLOAT *)pScratch,
+ (LVM_INT16)NumSamples);
+
+ Mult3s_Float( (LVM_FLOAT *)pScratch,
+ pConfig->ReverbLevel,
+ (LVM_FLOAT *)pScratch,
+ (LVM_INT16)(2 * NumSamples));
+
+
+ /*
+ * Apply the delay mix
+ */
+ DelayMix_Float((LVM_FLOAT *)pScratch,
+ &pConfig->StereoSamples[0],
+ pConfig->DelaySize,
+ pOutData,
+ &pConfig->DelayOffset,
+ (LVM_INT16)NumSamples);
+
+
+ }
+
+ return(LVCS_SUCCESS);
+}
+#else
LVCS_ReturnStatus_en LVCS_ReverbGenerator(LVCS_Handle_t hInstance,
const LVM_INT16 *pInData,
LVM_INT16 *pOutData,
@@ -257,8 +432,4 @@
return(LVCS_SUCCESS);
}
-
-
-
-
-
+#endif
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_ReverbGenerator.h b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_ReverbGenerator.h
index 6e026ff..69892b6 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_ReverbGenerator.h
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_ReverbGenerator.h
@@ -58,14 +58,20 @@
LVM_INT16 DelayOffset;
LVM_INT16 ProcGain;
LVM_INT16 UnprocGain;
+#ifndef BUILD_FLOAT
LVM_INT16 StereoSamples[2*LVCS_STEREODELAY_CS_48KHZ];
-
/* Reverb Level */
LVM_INT16 ReverbLevel;
-
/* Filter */
void (*pBiquadCallBack) (Biquad_Instance_t*, LVM_INT16*, LVM_INT16*, LVM_INT16);
-
+#else
+ LVM_FLOAT StereoSamples[2 * LVCS_STEREODELAY_CS_48KHZ];
+ /* Reverb Level */
+ LVM_FLOAT ReverbLevel;
+ /* Filter */
+ void (*pBiquadCallBack) (Biquad_FLOAT_Instance_t*,
+ LVM_FLOAT*, LVM_FLOAT*, LVM_INT16);
+#endif
} LVCS_ReverbGenerator_t;
@@ -77,12 +83,17 @@
LVCS_ReturnStatus_en LVCS_ReverbGeneratorInit(LVCS_Handle_t hInstance,
LVCS_Params_t *pParams);
-
+#ifdef BUILD_FLOAT
+LVCS_ReturnStatus_en LVCS_ReverbGenerator(LVCS_Handle_t hInstance,
+ const LVM_FLOAT *pInput,
+ LVM_FLOAT *pOutput,
+ LVM_UINT16 NumSamples);
+#else
LVCS_ReturnStatus_en LVCS_ReverbGenerator(LVCS_Handle_t hInstance,
const LVM_INT16 *pInput,
LVM_INT16 *pOutput,
LVM_UINT16 NumSamples);
-
+#endif
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_StereoEnhancer.c b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_StereoEnhancer.c
index b9b8b05..2992c35 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_StereoEnhancer.c
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_StereoEnhancer.c
@@ -49,7 +49,103 @@
/* NOTES: */
/* */
/************************************************************************************/
+#ifdef BUILD_FLOAT
+LVCS_ReturnStatus_en LVCS_SEnhancerInit(LVCS_Handle_t hInstance,
+ LVCS_Params_t *pParams)
+{
+ LVM_UINT16 Offset;
+ LVCS_Instance_t *pInstance = (LVCS_Instance_t *)hInstance;
+ LVCS_StereoEnhancer_t *pConfig = (LVCS_StereoEnhancer_t *)&pInstance->StereoEnhancer;
+ LVCS_Data_t *pData;
+ LVCS_Coefficient_t *pCoefficient;
+ FO_FLOAT_Coefs_t CoeffsMid;
+ BQ_FLOAT_Coefs_t CoeffsSide;
+ const BiquadA012B12CoefsSP_t *pSESideCoefs;
+
+
+ pData = (LVCS_Data_t *) \
+ pInstance->MemoryTable.Region[LVCS_MEMREGION_PERSISTENT_FAST_DATA].pBaseAddress;
+
+ pCoefficient = (LVCS_Coefficient_t *) \
+ pInstance->MemoryTable.Region[LVCS_MEMREGION_PERSISTENT_FAST_COEF].pBaseAddress;
+
+ /*
+ * If the sample rate or speaker type has changed update the filters
+ */
+ if ((pInstance->Params.SampleRate != pParams->SampleRate) ||
+ (pInstance->Params.SpeakerType != pParams->SpeakerType))
+ {
+ /*
+ * Set the filter coefficients based on the sample rate
+ */
+ /* Mid filter */
+ Offset = (LVM_UINT16)pParams->SampleRate;
+
+ /* Convert incoming coefficients to the required format/ordering */
+ CoeffsMid.A0 = (LVM_FLOAT) LVCS_SEMidCoefTable[Offset].A0;
+ CoeffsMid.A1 = (LVM_FLOAT) LVCS_SEMidCoefTable[Offset].A1;
+ CoeffsMid.B1 = (LVM_FLOAT)-LVCS_SEMidCoefTable[Offset].B1;
+
+ /* Clear the taps */
+ LoadConst_Float(0, /* Value */
+ (void *)&pData->SEBiquadTapsMid, /* Destination Cast to void:\
+ no dereferencing in function*/
+ /* Number of words */
+ (LVM_UINT16)(sizeof(pData->SEBiquadTapsMid) / sizeof(LVM_FLOAT)));
+
+ FO_1I_D16F16Css_TRC_WRA_01_Init(&pCoefficient->SEBiquadInstanceMid,
+ &pData->SEBiquadTapsMid,
+ &CoeffsMid);
+
+ /* Callbacks */
+ if(LVCS_SEMidCoefTable[Offset].Scale == 15)
+ {
+ pConfig->pBiquadCallBack_Mid = FO_1I_D16F16C15_TRC_WRA_01;
+ }
+
+ Offset = (LVM_UINT16)(pParams->SampleRate);
+ pSESideCoefs = (BiquadA012B12CoefsSP_t*)&LVCS_SESideCoefTable[0];
+
+ /* Side filter */
+ /* Convert incoming coefficients to the required format/ordering */
+ CoeffsSide.A0 = (LVM_FLOAT) pSESideCoefs[Offset].A0;
+ CoeffsSide.A1 = (LVM_FLOAT) pSESideCoefs[Offset].A1;
+ CoeffsSide.A2 = (LVM_FLOAT) pSESideCoefs[Offset].A2;
+ CoeffsSide.B1 = (LVM_FLOAT)-pSESideCoefs[Offset].B1;
+ CoeffsSide.B2 = (LVM_FLOAT)-pSESideCoefs[Offset].B2;
+
+ /* Clear the taps */
+ LoadConst_Float(0, /* Value */
+ (void *)&pData->SEBiquadTapsSide, /* Destination Cast to void:\
+ no dereferencing in function*/
+ /* Number of words */
+ (LVM_UINT16)(sizeof(pData->SEBiquadTapsSide) / sizeof(LVM_FLOAT)));
+ /* Callbacks */
+ switch(pSESideCoefs[Offset].Scale)
+ {
+ case 14:
+ BQ_1I_D16F32Css_TRC_WRA_01_Init(&pCoefficient->SEBiquadInstanceSide,
+ &pData->SEBiquadTapsSide,
+ &CoeffsSide);
+
+ pConfig->pBiquadCallBack_Side = BQ_1I_D16F32C14_TRC_WRA_01;
+ break;
+ case 15:
+ BQ_1I_D16F16Css_TRC_WRA_01_Init(&pCoefficient->SEBiquadInstanceSide,
+ &pData->SEBiquadTapsSide,
+ &CoeffsSide);
+
+ pConfig->pBiquadCallBack_Side = BQ_1I_D16F16C15_TRC_WRA_01;
+ break;
+ }
+
+ }
+
+
+ return(LVCS_SUCCESS);
+}
+#else
LVCS_ReturnStatus_en LVCS_SEnhancerInit(LVCS_Handle_t hInstance,
LVCS_Params_t *pParams)
{
@@ -138,7 +234,7 @@
return(LVCS_SUCCESS);
}
-
+#endif
/************************************************************************************/
/* */
/* FUNCTION: LVCS_StereoEnhance */
@@ -177,7 +273,90 @@
/* 1. The side filter is not used in Mobile Speaker mode */
/* */
/************************************************************************************/
+#ifdef BUILD_FLOAT
+LVCS_ReturnStatus_en LVCS_StereoEnhancer(LVCS_Handle_t hInstance,
+ const LVM_FLOAT *pInData,
+ LVM_FLOAT *pOutData,
+ LVM_UINT16 NumSamples)
+{
+ LVCS_Instance_t *pInstance = (LVCS_Instance_t *)hInstance;
+ LVCS_StereoEnhancer_t *pConfig = (LVCS_StereoEnhancer_t *)&pInstance->StereoEnhancer;
+ LVCS_Coefficient_t *pCoefficient;
+ LVM_FLOAT *pScratch;
+
+ pCoefficient = (LVCS_Coefficient_t *) \
+ pInstance->MemoryTable.Region[LVCS_MEMREGION_PERSISTENT_FAST_COEF].pBaseAddress;
+
+ pScratch = (LVM_FLOAT *) \
+ pInstance->MemoryTable.Region[LVCS_MEMREGION_TEMPORARY_FAST].pBaseAddress;
+ /*
+ * Check if the Stereo Enhancer is enabled
+ */
+ if ((pInstance->Params.OperatingMode & LVCS_STEREOENHANCESWITCH) != 0)
+ {
+ /*
+ * Convert from stereo to middle and side
+ */
+ From2iToMS_Float(pInData,
+ pScratch,
+ pScratch + NumSamples,
+ (LVM_INT16)NumSamples);
+
+ /*
+ * Apply filter to the middle signal
+ */
+ if (pInstance->OutputDevice == LVCS_HEADPHONE)
+ {
+ (pConfig->pBiquadCallBack_Mid)((Biquad_FLOAT_Instance_t*)\
+ &pCoefficient->SEBiquadInstanceMid,
+ (LVM_FLOAT *)pScratch,
+ (LVM_FLOAT *)pScratch,
+ (LVM_INT16)NumSamples);
+ }
+ else
+ {
+ Mult3s_Float(pScratch, /* Source */
+ (LVM_FLOAT)pConfig->MidGain, /* Gain */
+ pScratch, /* Destination */
+ (LVM_INT16)NumSamples); /* Number of samples */
+ }
+
+ /*
+ * Apply the filter the side signal only in stereo mode for headphones
+ * and in all modes for mobile speakers
+ */
+ if (pInstance->Params.SourceFormat == LVCS_STEREO)
+ {
+ (pConfig->pBiquadCallBack_Side)((Biquad_FLOAT_Instance_t*) \
+ &pCoefficient->SEBiquadInstanceSide,
+ (LVM_FLOAT *)(pScratch + NumSamples),
+ (LVM_FLOAT *)(pScratch + NumSamples),
+ (LVM_INT16)NumSamples);
+ }
+
+ /*
+ * Convert from middle and side to stereo
+ */
+ MSTo2i_Sat_Float(pScratch,
+ pScratch + NumSamples,
+ pOutData,
+ (LVM_INT16)NumSamples);
+
+ }
+ else
+ {
+ /*
+ * The stereo enhancer is disabled so just copy the data
+ */
+ Copy_Float((LVM_FLOAT *)pInData, /* Source */
+ (LVM_FLOAT *)pOutData, /* Destination */
+ (LVM_INT16)(2 * NumSamples)); /* Left and right */
+ }
+
+ return(LVCS_SUCCESS);
+}
+#else
LVCS_ReturnStatus_en LVCS_StereoEnhancer(LVCS_Handle_t hInstance,
const LVM_INT16 *pInData,
LVM_INT16 *pOutData,
@@ -254,7 +433,4 @@
return(LVCS_SUCCESS);
}
-
-
-
-
+#endif
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_StereoEnhancer.h b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_StereoEnhancer.h
index 15bc407..4125f24 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_StereoEnhancer.h
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_StereoEnhancer.h
@@ -43,18 +43,31 @@
/* Stereo enhancer structure */
typedef struct
{
+
+#ifndef BUILD_FLOAT
/*
* Middle filter
*/
void (*pBiquadCallBack_Mid)(Biquad_Instance_t*, LVM_INT16*, LVM_INT16*, LVM_INT16);
-
/*
* Side filter
*/
void (*pBiquadCallBack_Side)(Biquad_Instance_t*, LVM_INT16*, LVM_INT16*, LVM_INT16);
+ LVM_UINT16 MidGain; /* Middle gain in mobile speaker mode */
+#else
+ /*
+ * Middle filter
+ */
+ void (*pBiquadCallBack_Mid)(Biquad_FLOAT_Instance_t*,
+ LVM_FLOAT*, LVM_FLOAT*, LVM_INT16);
- LVM_UINT16 MidGain; /* Middle gain in mobile speaker mode */
-
+ /*
+ * Side filter
+ */
+ void (*pBiquadCallBack_Side)(Biquad_FLOAT_Instance_t*,
+ LVM_FLOAT*, LVM_FLOAT*, LVM_INT16);
+ LVM_FLOAT MidGain; /* Middle gain in mobile speaker mode */
+#endif
} LVCS_StereoEnhancer_t;
@@ -67,12 +80,17 @@
LVCS_ReturnStatus_en LVCS_SEnhancerInit(LVCS_Handle_t hInstance,
LVCS_Params_t *pParams);
+#ifndef BUILD_FLOAT
LVCS_ReturnStatus_en LVCS_StereoEnhancer(LVCS_Handle_t hInstance,
const LVM_INT16 *pInData,
LVM_INT16 *pOutData,
LVM_UINT16 NumSamples);
-
-
+#else
+LVCS_ReturnStatus_en LVCS_StereoEnhancer(LVCS_Handle_t hInstance,
+ const LVM_FLOAT *pInData,
+ LVM_FLOAT *pOutData,
+ LVM_UINT16 NumSamples);
+#endif
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Tables.c b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Tables.c
index 974de21..e154e29 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Tables.c
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Tables.c
@@ -71,7 +71,19 @@
{CS_MIDDLE_48000_A0, /* 48kS/s coefficients */
CS_MIDDLE_48000_A1,
CS_MIDDLE_48000_B1,
- (LVM_UINT16 )CS_MIDDLE_48000_SCALE}};
+ (LVM_UINT16 )CS_MIDDLE_48000_SCALE}
+#ifdef HIGHER_FS
+ ,
+ {CS_MIDDLE_96000_A0, /* 96kS/s coefficients */
+ CS_MIDDLE_96000_A1,
+ CS_MIDDLE_96000_B1,
+ (LVM_UINT16 )CS_MIDDLE_96000_SCALE},
+ {CS_MIDDLE_192000_A0, /* 192kS/s coefficients */
+ CS_MIDDLE_192000_A1,
+ CS_MIDDLE_192000_B1,
+ (LVM_UINT16 )CS_MIDDLE_192000_SCALE}
+#endif
+ };
/* Coefficient table for the side filter */
const BiquadA012B12CoefsSP_t LVCS_SESideCoefTable[] = {
@@ -130,6 +142,21 @@
CS_SIDE_48000_B1,
CS_SIDE_48000_B2,
(LVM_UINT16 )CS_SIDE_48000_SCALE}
+#ifdef HIGHER_FS
+ ,
+ {CS_SIDE_96000_A0, /* 96kS/s coefficients */
+ CS_SIDE_96000_A1,
+ CS_SIDE_96000_A2,
+ CS_SIDE_96000_B1,
+ CS_SIDE_96000_B2,
+ (LVM_UINT16 )CS_SIDE_96000_SCALE},
+ {CS_SIDE_192000_A0, /* 192kS/s coefficients */
+ CS_SIDE_192000_A1,
+ CS_SIDE_192000_A2,
+ CS_SIDE_192000_B1,
+ CS_SIDE_192000_B2,
+ (LVM_UINT16 )CS_SIDE_192000_SCALE}
+#endif
};
@@ -195,6 +222,20 @@
CS_EQUALISER_48000_B1,
CS_EQUALISER_48000_B2,
(LVM_UINT16 )CS_EQUALISER_48000_SCALE},
+#ifdef HIGHER_FS
+ {CS_EQUALISER_96000_A0, /* 96kS/s coefficients */
+ CS_EQUALISER_96000_A1,
+ CS_EQUALISER_96000_A2,
+ CS_EQUALISER_96000_B1,
+ CS_EQUALISER_96000_B2,
+ (LVM_UINT16 )CS_EQUALISER_96000_SCALE},
+ {CS_EQUALISER_192000_A0, /* 192kS/s coefficients */
+ CS_EQUALISER_192000_A1,
+ CS_EQUALISER_192000_A2,
+ CS_EQUALISER_192000_B1,
+ CS_EQUALISER_192000_B2,
+ (LVM_UINT16 )CS_EQUALISER_192000_SCALE},
+#endif
/* Concert Sound EX Headphone coefficients */
{CSEX_EQUALISER_8000_A0, /* 8kS/s coefficients */
@@ -251,6 +292,21 @@
CSEX_EQUALISER_48000_B1,
CSEX_EQUALISER_48000_B2,
(LVM_UINT16 )CSEX_EQUALISER_48000_SCALE}
+#ifdef HIGHER_FS
+ ,
+ {CSEX_EQUALISER_96000_A0, /* 96kS/s coefficients */
+ CSEX_EQUALISER_96000_A1,
+ CSEX_EQUALISER_96000_A2,
+ CSEX_EQUALISER_96000_B1,
+ CSEX_EQUALISER_96000_B2,
+ (LVM_UINT16 )CSEX_EQUALISER_96000_SCALE},
+ {CSEX_EQUALISER_192000_A0, /* 192kS/s coefficients */
+ CSEX_EQUALISER_192000_A1,
+ CSEX_EQUALISER_192000_A2,
+ CSEX_EQUALISER_192000_B1,
+ CSEX_EQUALISER_192000_B2,
+ (LVM_UINT16 )CSEX_EQUALISER_192000_SCALE}
+#endif
};
@@ -334,6 +390,21 @@
CS_REVERB_48000_B1,
CS_REVERB_48000_B2,
(LVM_UINT16 )CS_REVERB_48000_SCALE}
+#ifdef HIGHER_FS
+ ,
+ {CS_REVERB_96000_A0, /* 96kS/s coefficients */
+ CS_REVERB_96000_A1,
+ CS_REVERB_96000_A2,
+ CS_REVERB_96000_B1,
+ CS_REVERB_96000_B2,
+ (LVM_UINT16 )CS_REVERB_96000_SCALE},
+ {CS_REVERB_192000_A0, /* 192kS/s coefficients */
+ CS_REVERB_192000_A1,
+ CS_REVERB_192000_A2,
+ CS_REVERB_192000_B1,
+ CS_REVERB_192000_B2,
+ (LVM_UINT16 )CS_REVERB_192000_SCALE}
+#endif
};
@@ -385,6 +456,24 @@
/* */
/************************************************************************************/
const LVCS_VolCorrect_t LVCS_VolCorrectTable[] = {
+#ifdef BUILD_FLOAT
+ {0.433362f, /* Headphone, stereo mode */
+ 0.000000f,
+ 1.000024f,
+ 1.412640f},
+ {0.433362f, /* EX Headphone, stereo mode */
+ 0.000000f,
+ 1.000024f,
+ 1.412640f},
+ {1.000000f, /* Headphone, mono mode */
+ 0.000000f,
+ 1.000024f,
+ 1.412640f},
+ {1.000000f, /* EX Headphone, mono mode */
+ 0.000000f,
+ 1.000024f,
+ 1.412640f}
+#else
{14200, /* Headphone, stereo mode */
0,
4096,
@@ -401,6 +490,7 @@
0,
4096,
5786}
+#endif
};
/************************************************************************************/
@@ -418,8 +508,25 @@
#define LVCS_VOL_TC_Fs32000 32721 /* Floating point value 0.998565674 */
#define LVCS_VOL_TC_Fs44100 32734 /* Floating point value 0.998962402 */
#define LVCS_VOL_TC_Fs48000 32737 /* Floating point value 0.999053955 */
+#if defined(BUILD_FLOAT) && defined(HIGHER_FS)
+#define LVCS_VOL_TC_Fs96000 32751 /* Floating point value 0.999511703 */ /* Todo @ need to re check this value*/
+#define LVCS_VOL_TC_Fs192000 32763 /* Floating point value 0.999877925 */ /* Todo @ need to re check this value*/
+#endif
-
+#if defined(BUILD_FLOAT) && defined(HIGHER_FS)
+const LVM_INT16 LVCS_VolumeTCTable[11] = {LVCS_VOL_TC_Fs8000,
+ LVCS_VOL_TC_Fs11025,
+ LVCS_VOL_TC_Fs12000,
+ LVCS_VOL_TC_Fs16000,
+ LVCS_VOL_TC_Fs22050,
+ LVCS_VOL_TC_Fs24000,
+ LVCS_VOL_TC_Fs32000,
+ LVCS_VOL_TC_Fs44100,
+ LVCS_VOL_TC_Fs48000,
+ LVCS_VOL_TC_Fs96000,
+ LVCS_VOL_TC_Fs192000
+};
+#else
const LVM_INT16 LVCS_VolumeTCTable[9] = {LVCS_VOL_TC_Fs8000,
LVCS_VOL_TC_Fs11025,
LVCS_VOL_TC_Fs12000,
@@ -428,15 +535,30 @@
LVCS_VOL_TC_Fs24000,
LVCS_VOL_TC_Fs32000,
LVCS_VOL_TC_Fs44100,
- LVCS_VOL_TC_Fs48000};
+ LVCS_VOL_TC_Fs48000
+};
+#endif
/************************************************************************************/
/* */
/* Sample rate table */
/* */
/************************************************************************************/
-
-const LVM_INT32 LVCS_SampleRateTable[9] = {8000,
+#if defined(BUILD_FLOAT) && defined(HIGHER_FS)
+const LVM_INT32 LVCS_SampleRateTable[11] = {8000,
+ 11025,
+ 12000,
+ 16000,
+ 22050,
+ 24000,
+ 32000,
+ 44100,
+ 48000,
+ 96000,
+ 192000
+};
+#else
+const LVM_INT16 LVCS_SampleRateTable[9] = {8000,
11025,
12000,
16000,
@@ -444,5 +566,6 @@
24000,
32000,
44100,
- 48000};
-
+ 48000
+};
+#endif
diff --git a/media/libeffects/lvm/wrapper/Android.mk b/media/libeffects/lvm/wrapper/Android.mk
index efd30fb..f106aae 100644
--- a/media/libeffects/lvm/wrapper/Android.mk
+++ b/media/libeffects/lvm/wrapper/Android.mk
@@ -10,7 +10,7 @@
LOCAL_SRC_FILES:= \
Bundle/EffectBundle.cpp
-LOCAL_CFLAGS += -fvisibility=hidden
+LOCAL_CFLAGS += -fvisibility=hidden -DBUILD_FLOAT -DHIGHER_FS
LOCAL_CFLAGS += -Wall -Werror
LOCAL_MODULE:= libbundlewrapper
@@ -43,7 +43,7 @@
LOCAL_SRC_FILES:= \
Reverb/EffectReverb.cpp
-LOCAL_CFLAGS += -fvisibility=hidden
+LOCAL_CFLAGS += -fvisibility=hidden -DBUILD_FLOAT -DHIGHER_FS
LOCAL_CFLAGS += -Wall -Werror
LOCAL_MODULE:= libreverbwrapper
diff --git a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
index df6501b..4f1fed5 100644
--- a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
+++ b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
@@ -14,7 +14,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
+#ifndef LVM_FLOAT
+typedef float LVM_FLOAT;
+#endif
#define LOG_TAG "Bundle"
#define ARRAY_SIZE(array) (sizeof (array) / sizeof (array)[0])
//#define LOG_NDEBUG 0
@@ -271,7 +273,10 @@
pContext->pBundledContext->SamplesToExitCountVirt = 0;
pContext->pBundledContext->SamplesToExitCountBb = 0;
pContext->pBundledContext->SamplesToExitCountEq = 0;
-
+#ifdef BUILD_FLOAT
+ pContext->pBundledContext->pInputBuffer = NULL;
+ pContext->pBundledContext->pOutputBuffer = NULL;
+#endif
for (int i = 0; i < FIVEBAND_NUMBANDS; i++) {
pContext->pBundledContext->bandGaindB[i] = EQNB_5BandSoftPresets[i];
}
@@ -439,6 +444,14 @@
if (pContext->pBundledContext->workBuffer != NULL) {
free(pContext->pBundledContext->workBuffer);
}
+#ifdef BUILD_FLOAT
+ if (pContext->pBundledContext->pInputBuffer != NULL) {
+ free(pContext->pBundledContext->pInputBuffer);
+ }
+ if (pContext->pBundledContext->pOutputBuffer != NULL) {
+ free(pContext->pBundledContext->pOutputBuffer);
+ }
+#endif
delete pContext->pBundledContext;
pContext->pBundledContext = LVM_NULL;
}
@@ -695,7 +708,47 @@
return 0;
} /* end LvmBundle_init */
+#ifdef BUILD_FLOAT
+/**********************************************************************************
+ FUNCTION INT16LTOFLOAT
+***********************************************************************************/
+// Todo: need to write function descriptor
+static void Int16ToFloat(const LVM_INT16 *src, LVM_FLOAT *dst, size_t n) {
+ size_t ii;
+ src += n-1;
+ dst += n-1;
+ for (ii = n; ii != 0; ii--) {
+ *dst = ((LVM_FLOAT)((LVM_INT16)*src)) / 32768.0f;
+ src--;
+ dst--;
+ }
+ return;
+}
+/**********************************************************************************
+ FUNCTION FLOATTOINT16_SAT
+***********************************************************************************/
+// Todo : Need to write function descriptor
+static void FloatToInt16_SAT(const LVM_FLOAT *src, LVM_INT16 *dst, size_t n) {
+ size_t ii;
+ LVM_INT32 temp;
+ src += n-1;
+ dst += n-1;
+ for (ii = n; ii != 0; ii--) {
+ temp = (LVM_INT32)((*src) * 32768.0f);
+ if (temp >= 32767) {
+ *dst = 32767;
+ } else if (temp <= -32768) {
+ *dst = -32768;
+ } else {
+ *dst = (LVM_INT16)temp;
+ }
+ src--;
+ dst--;
+ }
+ return;
+}
+#endif
//----------------------------------------------------------------------------
// LvmBundle_process()
//----------------------------------------------------------------------------
@@ -713,7 +766,99 @@
// pOut: pointer to updated stereo 16 bit output data
//
//----------------------------------------------------------------------------
+#ifdef BUILD_FLOAT
+int LvmBundle_process(LVM_INT16 *pIn,
+ LVM_INT16 *pOut,
+ int frameCount,
+ EffectContext *pContext){
+
+ //LVM_ControlParams_t ActiveParams; /* Current control Parameters */
+ LVM_ReturnStatus_en LvmStatus = LVM_SUCCESS; /* Function call status */
+ LVM_INT16 *pOutTmp;
+ LVM_FLOAT *pInputBuff;
+ LVM_FLOAT *pOutputBuff;
+
+ if (pContext->pBundledContext->pInputBuffer == NULL ||
+ pContext->pBundledContext->frameCount < frameCount) {
+ if (pContext->pBundledContext->pInputBuffer != NULL) {
+ free(pContext->pBundledContext->pInputBuffer);
+ }
+ pContext->pBundledContext->pInputBuffer = (LVM_FLOAT *)malloc(frameCount * \
+ sizeof(LVM_FLOAT) * FCC_2);
+ }
+
+ if (pContext->pBundledContext->pOutputBuffer == NULL ||
+ pContext->pBundledContext->frameCount < frameCount) {
+ if (pContext->pBundledContext->pOutputBuffer != NULL) {
+ free(pContext->pBundledContext->pOutputBuffer);
+ }
+ pContext->pBundledContext->pOutputBuffer = (LVM_FLOAT *)malloc(frameCount * \
+ sizeof(LVM_FLOAT) * FCC_2);
+ }
+
+ if ((pContext->pBundledContext->pInputBuffer == NULL) ||
+ (pContext->pBundledContext->pOutputBuffer == NULL)) {
+ ALOGV("LVM_ERROR : LvmBundle_process memory allocation for float buffer's failed");
+ return -EINVAL;
+ }
+
+ pInputBuff = pContext->pBundledContext->pInputBuffer;
+ pOutputBuff = pContext->pBundledContext->pOutputBuffer;
+
+ if (pContext->config.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_WRITE){
+ pOutTmp = pOut;
+ } else if (pContext->config.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE){
+ if (pContext->pBundledContext->frameCount != frameCount) {
+ if (pContext->pBundledContext->workBuffer != NULL) {
+ free(pContext->pBundledContext->workBuffer);
+ }
+ pContext->pBundledContext->workBuffer =
+ (LVM_INT16 *)calloc(frameCount, sizeof(LVM_INT16) * FCC_2);
+ if (pContext->pBundledContext->workBuffer == NULL) {
+ return -ENOMEM;
+ }
+ pContext->pBundledContext->frameCount = frameCount;
+ }
+ pOutTmp = pContext->pBundledContext->workBuffer;
+ } else {
+ ALOGV("LVM_ERROR : LvmBundle_process invalid access mode");
+ return -EINVAL;
+ }
+
+ #ifdef LVM_PCM
+ fwrite(pIn, frameCount*sizeof(LVM_INT16) * FCC_2, 1, pContext->pBundledContext->PcmInPtr);
+ fflush(pContext->pBundledContext->PcmInPtr);
+ #endif
+
+ /* Converting input data from fixed point to float point */
+ Int16ToFloat(pIn, pInputBuff, frameCount * 2);
+
+ /* Process the samples */
+ LvmStatus = LVM_Process(pContext->pBundledContext->hInstance, /* Instance handle */
+ pInputBuff, /* Input buffer */
+ pOutputBuff, /* Output buffer */
+ (LVM_UINT16)frameCount, /* Number of samples to read */
+ 0); /* Audo Time */
+
+ LVM_ERROR_CHECK(LvmStatus, "LVM_Process", "LvmBundle_process")
+ if(LvmStatus != LVM_SUCCESS) return -EINVAL;
+
+ /* Converting output data from float point to fixed point */
+ FloatToInt16_SAT(pOutputBuff, pOutTmp, (LVM_UINT16)frameCount * 2);
+ #ifdef LVM_PCM
+ fwrite(pOutTmp, frameCount*sizeof(LVM_INT16) * FCC_2, 1, pContext->pBundledContext->PcmOutPtr);
+ fflush(pContext->pBundledContext->PcmOutPtr);
+ #endif
+
+ if (pContext->config.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE){
+ for (int i = 0; i < frameCount * 2; i++){
+ pOut[i] = clamp16((LVM_INT32)pOut[i] + (LVM_INT32)pOutTmp[i]);
+ }
+ }
+ return 0;
+} /* end LvmBundle_process */
+#else
int LvmBundle_process(LVM_INT16 *pIn,
LVM_INT16 *pOut,
int frameCount,
@@ -771,7 +916,7 @@
}
return 0;
} /* end LvmBundle_process */
-
+#endif
//----------------------------------------------------------------------------
// EqualizerUpdateActiveParams()
@@ -1126,6 +1271,16 @@
SampleRate = LVM_FS_48000;
pContext->pBundledContext->SamplesPerSecond = 48000*2; // 2 secs Stereo
break;
+#if defined(BUILD_FLOAT) && defined(HIGHER_FS)
+ case 96000:
+ SampleRate = LVM_FS_96000;
+ pContext->pBundledContext->SamplesPerSecond = 96000*2; // 2 secs Stereo
+ break;
+ case 192000:
+ SampleRate = LVM_FS_192000;
+ pContext->pBundledContext->SamplesPerSecond = 192000*2; // 2 secs Stereo
+ break;
+#endif
default:
ALOGV("\tEffect_setConfig invalid sampling rate %d", pConfig->inputCfg.samplingRate);
return -EINVAL;
diff --git a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.h b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.h
index ee604eb..cad89fd 100644
--- a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.h
+++ b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.h
@@ -103,6 +103,10 @@
FILE *PcmInPtr;
FILE *PcmOutPtr;
#endif
+ #ifdef BUILD_FLOAT
+ LVM_FLOAT *pInputBuffer;
+ LVM_FLOAT *pOutputBuffer;
+ #endif
};
/* SessionContext : One session */
diff --git a/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp b/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
index 12a038f..ab6b63c 100644
--- a/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
+++ b/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
@@ -14,7 +14,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
+#ifndef LVM_FLOAT
+typedef float LVM_FLOAT;
+#endif
#define LOG_TAG "Reverb"
#define ARRAY_SIZE(array) (sizeof (array) / sizeof (array)[0])
//#define LOG_NDEBUG 0
@@ -152,6 +154,8 @@
LVM_Fs_en SampleRate;
LVM_INT32 *InFrames32;
LVM_INT32 *OutFrames32;
+ size_t bufferSizeIn;
+ size_t bufferSizeOut;
bool auxiliary;
bool preset;
uint16_t curPreset;
@@ -172,8 +176,11 @@
#define REVERB_DEFAULT_PRESET REVERB_PRESET_NONE
-
+#ifdef BUILD_FLOAT
+#define REVERB_SEND_LEVEL 0.75f // 0.75 in 4.12 format
+#else
#define REVERB_SEND_LEVEL (0x0C00) // 0.75 in 4.12 format
+#endif
#define REVERB_UNIT_VOLUME (0x1000) // 1.0 in 4.12 format
//--- local function prototypes
@@ -269,8 +276,15 @@
// Allocate memory for reverb process (*2 is for STEREO)
- pContext->InFrames32 = (LVM_INT32 *)malloc(LVREV_MAX_FRAME_SIZE * sizeof(LVM_INT32) * 2);
- pContext->OutFrames32 = (LVM_INT32 *)malloc(LVREV_MAX_FRAME_SIZE * sizeof(LVM_INT32) * 2);
+#ifdef BUILD_FLOAT
+ pContext->bufferSizeIn = LVREV_MAX_FRAME_SIZE * sizeof(float) * 2;
+ pContext->bufferSizeOut = pContext->bufferSizeIn;
+#else
+ pContext->bufferSizeIn = LVREV_MAX_FRAME_SIZE * sizeof(LVM_INT32) * 2;
+ pContext->bufferSizeOut = pContext->bufferSizeIn;
+#endif
+ pContext->InFrames32 = (LVM_INT32 *)malloc(pContext->bufferSizeIn);
+ pContext->OutFrames32 = (LVM_INT32 *)malloc(pContext->bufferSizeOut);
ALOGV("\tEffectCreate %p, size %zu", pContext, sizeof(ReverbContext));
ALOGV("\tEffectCreate end\n");
@@ -292,6 +306,8 @@
#endif
free(pContext->InFrames32);
free(pContext->OutFrames32);
+ pContext->bufferSizeIn = 0;
+ pContext->bufferSizeOut = 0;
Reverb_free(pContext);
delete pContext;
return 0;
@@ -388,6 +404,48 @@
}
#endif
+#ifdef BUILD_FLOAT
+/**********************************************************************************
+ FUNCTION INT16LTOFLOAT
+***********************************************************************************/
+// Todo: need to write function descriptor
+static void Int16ToFloat(const LVM_INT16 *src, LVM_FLOAT *dst, size_t n) {
+ size_t ii;
+ src += n-1;
+ dst += n-1;
+ for (ii = n; ii != 0; ii--) {
+ *dst = ((LVM_FLOAT)((LVM_INT16)*src)) / 32768.0f;
+ src--;
+ dst--;
+ }
+ return;
+}
+/**********************************************************************************
+ FUNCTION FLOATTOINT16_SAT
+***********************************************************************************/
+// Todo : Need to write function descriptor
+static void FloatToInt16_SAT(const LVM_FLOAT *src, LVM_INT16 *dst, size_t n) {
+ size_t ii;
+ LVM_INT32 temp;
+
+ src += n-1;
+ dst += n-1;
+ for (ii = n; ii != 0; ii--) {
+ temp = (LVM_INT32)((*src) * 32768.0f);
+ if (temp >= 32767) {
+ *dst = 32767;
+ } else if (temp <= -32768) {
+ *dst = -32768;
+ } else {
+ *dst = (LVM_INT16)temp;
+ }
+ src--;
+ dst--;
+ }
+ return;
+}
+#endif
+
static inline int16_t clamp16(int32_t sample)
{
if ((sample>>15) ^ (sample>>31))
@@ -421,8 +479,31 @@
LVM_INT16 samplesPerFrame = 1;
LVREV_ReturnStatus_en LvmStatus = LVREV_SUCCESS; /* Function call status */
LVM_INT16 *OutFrames16;
+#ifdef BUILD_FLOAT
+ LVM_FLOAT *pInputBuff;
+ LVM_FLOAT *pOutputBuff;
+#endif
-
+#ifdef BUILD_FLOAT
+ if (pContext->InFrames32 == NULL ||
+ pContext->bufferSizeIn < frameCount * sizeof(float) * 2) {
+ if (pContext->InFrames32 != NULL) {
+ free(pContext->InFrames32);
+ }
+ pContext->bufferSizeIn = frameCount * sizeof(float) * 2;
+ pContext->InFrames32 = (LVM_INT32 *)malloc(pContext->bufferSizeIn);
+ }
+ if (pContext->OutFrames32 == NULL ||
+ pContext->bufferSizeOut < frameCount * sizeof(float) * 2) {
+ if (pContext->OutFrames32 != NULL) {
+ free(pContext->OutFrames32);
+ }
+ pContext->bufferSizeOut = frameCount * sizeof(float) * 2;
+ pContext->OutFrames32 = (LVM_INT32 *)malloc(pContext->bufferSizeOut);
+ }
+ pInputBuff = (float *)pContext->InFrames32;
+ pOutputBuff = (float *)pContext->OutFrames32;
+#endif
// Check that the input is either mono or stereo
if (pContext->config.inputCfg.channels == AUDIO_CHANNEL_OUT_STEREO) {
samplesPerFrame = 2;
@@ -448,49 +529,84 @@
Reverb_LoadPreset(pContext);
}
-
-
// Convert to Input 32 bits
if (pContext->auxiliary) {
+#ifdef BUILD_FLOAT
+ Int16ToFloat(pIn, pInputBuff, frameCount * samplesPerFrame);
+#else
for(int i=0; i<frameCount*samplesPerFrame; i++){
pContext->InFrames32[i] = (LVM_INT32)pIn[i]<<8;
}
- } else {
+#endif
+ } else {
// insert reverb input is always stereo
for (int i = 0; i < frameCount; i++) {
+#ifndef BUILD_FLOAT
pContext->InFrames32[2*i] = (pIn[2*i] * REVERB_SEND_LEVEL) >> 4; // <<8 + >>12
pContext->InFrames32[2*i+1] = (pIn[2*i+1] * REVERB_SEND_LEVEL) >> 4; // <<8 + >>12
+#else
+ pInputBuff[2 * i] = (LVM_FLOAT)pIn[2 * i] * REVERB_SEND_LEVEL / 32768.0f;
+ pInputBuff[2 * i + 1] = (LVM_FLOAT)pIn[2 * i + 1] * REVERB_SEND_LEVEL / 32768.0f;
+#endif
}
}
if (pContext->preset && pContext->curPreset == REVERB_PRESET_NONE) {
+#ifdef BUILD_FLOAT
+ memset(pOutputBuff, 0, frameCount * sizeof(LVM_FLOAT) * 2); //always stereo here
+#else
memset(pContext->OutFrames32, 0, frameCount * sizeof(LVM_INT32) * 2); //always stereo here
+#endif
} else {
if(pContext->bEnabled == LVM_FALSE && pContext->SamplesToExitCount > 0) {
+#ifdef BUILD_FLOAT
+ memset(pInputBuff, 0, frameCount * sizeof(LVM_FLOAT) * samplesPerFrame);
+#else
memset(pContext->InFrames32,0,frameCount * sizeof(LVM_INT32) * samplesPerFrame);
+#endif
ALOGV("\tZeroing %d samples per frame at the end of call", samplesPerFrame);
}
/* Process the samples, producing a stereo output */
+#ifdef BUILD_FLOAT
+ LvmStatus = LVREV_Process(pContext->hInstance, /* Instance handle */
+ pInputBuff, /* Input buffer */
+ pOutputBuff, /* Output buffer */
+ frameCount); /* Number of samples to read */
+#else
LvmStatus = LVREV_Process(pContext->hInstance, /* Instance handle */
pContext->InFrames32, /* Input buffer */
pContext->OutFrames32, /* Output buffer */
frameCount); /* Number of samples to read */
- }
+#endif
+ }
LVM_ERROR_CHECK(LvmStatus, "LVREV_Process", "process")
if(LvmStatus != LVREV_SUCCESS) return -EINVAL;
// Convert to 16 bits
if (pContext->auxiliary) {
+#ifdef BUILD_FLOAT
+ FloatToInt16_SAT(pOutputBuff, OutFrames16, (size_t)frameCount * 2);
+#else
for (int i=0; i < frameCount*2; i++) { //always stereo here
OutFrames16[i] = clamp16(pContext->OutFrames32[i]>>8);
}
- } else {
- for (int i=0; i < frameCount*2; i++) { //always stereo here
- OutFrames16[i] = clamp16((pContext->OutFrames32[i]>>8) + (LVM_INT32)pIn[i]);
- }
+#endif
+ } else {
+#ifdef BUILD_FLOAT
+ for (int i = 0; i < frameCount * 2; i++) {//always stereo here
+ //pOutputBuff and OutFrames16 point to the same buffer, so better to
+ //accumulate in pInputBuff, which is available
+ pInputBuff[i] = pOutputBuff[i] + (LVM_FLOAT)pIn[i] / 32768.0f;
+ }
+ FloatToInt16_SAT(pInputBuff, OutFrames16, (size_t)frameCount * 2);
+#else
+ for (int i=0; i < frameCount*2; i++) { //always stereo here
+ OutFrames16[i] = clamp16((pContext->OutFrames32[i]>>8) + (LVM_INT32)pIn[i]);
+ }
+#endif
// apply volume with ramp if needed
if ((pContext->leftVolume != pContext->prevLeftVolume ||
pContext->rightVolume != pContext->prevRightVolume) &&
@@ -643,6 +759,14 @@
case 48000:
SampleRate = LVM_FS_48000;
break;
+#if defined(BUILD_FLOAT) && defined(HIGHER_FS)
+ case 96000:
+ SampleRate = LVM_FS_96000;
+ break;
+ case 192000:
+ SampleRate = LVM_FS_192000;
+ break;
+#endif
default:
ALOGV("\rReverb_setConfig invalid sampling rate %d", pConfig->inputCfg.samplingRate);
return -EINVAL;
@@ -1010,7 +1134,7 @@
//ALOGV("\tReverbGetRoomHfLevel() ActiveParams.LPFL %d, pContext->SavedHfLevel: %d, "
// "converted level: %d\n", ActiveParams.LPF, pContext->SavedHfLevel, level);
- if(ActiveParams.LPF != level){
+ if((int16_t)ActiveParams.LPF != level){
ALOGV("\tLVM_ERROR : (ignore at start up) ReverbGetRoomHfLevel() has wrong level -> %d %d\n",
ActiveParams.Level, level);
}
diff --git a/media/libmedia/Android.bp b/media/libmedia/Android.bp
index bbe97ee..043c84a 100644
--- a/media/libmedia/Android.bp
+++ b/media/libmedia/Android.bp
@@ -1,7 +1,7 @@
cc_library_headers {
name: "libmedia_headers",
vendor_available: true,
- export_include_dirs: ["include"],
+ export_include_dirs: ["include", "omx/1.0/include"],
}
cc_library {
diff --git a/media/libmedia/IMediaExtractor.cpp b/media/libmedia/IMediaExtractor.cpp
index f08fabb..19b00f3 100644
--- a/media/libmedia/IMediaExtractor.cpp
+++ b/media/libmedia/IMediaExtractor.cpp
@@ -21,7 +21,6 @@
#include <stdint.h>
#include <sys/types.h>
-#include <android/media/ICas.h>
#include <binder/IPCThreadState.h>
#include <binder/Parcel.h>
#include <media/IMediaExtractor.h>
@@ -117,12 +116,12 @@
return NULL;
}
- virtual status_t setMediaCas(const sp<ICas> & cas) {
+ virtual status_t setMediaCas(const HInterfaceToken &casToken) {
ALOGV("setMediaCas");
Parcel data, reply;
data.writeInterfaceToken(BpMediaExtractor::getInterfaceDescriptor());
- data.writeStrongBinder(IInterface::asBinder(cas));
+ data.writeByteVector(casToken);
status_t err = remote()->transact(SETMEDIACAS, data, &reply);
if (err != NO_ERROR) {
@@ -206,15 +205,14 @@
ALOGV("setMediaCas");
CHECK_INTERFACE(IMediaExtractor, data, reply);
- sp<IBinder> casBinder;
- status_t err = data.readNullableStrongBinder(&casBinder);
+ HInterfaceToken casToken;
+ status_t err = data.readByteVector(&casToken);
if (err != NO_ERROR) {
- ALOGE("Error reading cas from parcel");
+ ALOGE("Error reading casToken from parcel");
return err;
}
- sp<ICas> cas = interface_cast<ICas>(casBinder);
- reply->writeInt32(setMediaCas(cas));
+ reply->writeInt32(setMediaCas(casToken));
return OK;
}
default:
diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp
index 43130eb..a073081 100644
--- a/media/libmedia/IOMX.cpp
+++ b/media/libmedia/IOMX.cpp
@@ -29,7 +29,7 @@
#include <utils/NativeHandle.h>
#include <gui/IGraphicBufferProducer.h>
-#include <omx/1.0/WOmxNode.h>
+#include <media/omx/1.0/WOmxNode.h>
#include <android/IGraphicBufferSource.h>
#include <android/IOMXBufferSource.h>
diff --git a/media/libmedia/include/media/IMediaExtractor.h b/media/libmedia/include/media/IMediaExtractor.h
index ab40f53..1e13b65 100644
--- a/media/libmedia/include/media/IMediaExtractor.h
+++ b/media/libmedia/include/media/IMediaExtractor.h
@@ -20,14 +20,12 @@
#include <media/IMediaSource.h>
#include <media/stagefright/DataSource.h>
+#include <vector>
namespace android {
class MetaData;
-namespace media {
-class ICas;
-};
-using namespace media;
+typedef std::vector<uint8_t> HInterfaceToken;
class IMediaExtractor : public IInterface {
public:
@@ -65,7 +63,7 @@
// for DRM
virtual char* getDrmTrackInfo(size_t trackID, int *len) = 0;
- virtual status_t setMediaCas(const sp<ICas> &cas) = 0;
+ virtual status_t setMediaCas(const HInterfaceToken &casToken) = 0;
virtual void setUID(uid_t uid) = 0;
diff --git a/include/media/omx/1.0/Conversion.h b/media/libmedia/omx/1.0/include/media/omx/1.0/Conversion.h
similarity index 100%
rename from include/media/omx/1.0/Conversion.h
rename to media/libmedia/omx/1.0/include/media/omx/1.0/Conversion.h
diff --git a/include/media/omx/1.0/WGraphicBufferSource.h b/media/libmedia/omx/1.0/include/media/omx/1.0/WGraphicBufferSource.h
similarity index 100%
rename from include/media/omx/1.0/WGraphicBufferSource.h
rename to media/libmedia/omx/1.0/include/media/omx/1.0/WGraphicBufferSource.h
diff --git a/include/media/omx/1.0/WOmx.h b/media/libmedia/omx/1.0/include/media/omx/1.0/WOmx.h
similarity index 100%
rename from include/media/omx/1.0/WOmx.h
rename to media/libmedia/omx/1.0/include/media/omx/1.0/WOmx.h
diff --git a/include/media/omx/1.0/WOmxBufferSource.h b/media/libmedia/omx/1.0/include/media/omx/1.0/WOmxBufferSource.h
similarity index 100%
rename from include/media/omx/1.0/WOmxBufferSource.h
rename to media/libmedia/omx/1.0/include/media/omx/1.0/WOmxBufferSource.h
diff --git a/include/media/omx/1.0/WOmxNode.h b/media/libmedia/omx/1.0/include/media/omx/1.0/WOmxNode.h
similarity index 100%
rename from include/media/omx/1.0/WOmxNode.h
rename to media/libmedia/omx/1.0/include/media/omx/1.0/WOmxNode.h
diff --git a/include/media/omx/1.0/WOmxObserver.h b/media/libmedia/omx/1.0/include/media/omx/1.0/WOmxObserver.h
similarity index 100%
rename from include/media/omx/1.0/WOmxObserver.h
rename to media/libmedia/omx/1.0/include/media/omx/1.0/WOmxObserver.h
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index 6a09227..df36046 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -1171,7 +1171,7 @@
if (mSource != nullptr) {
if (audio) {
if (mVideoDecoderError || mSource->getFormat(false /* audio */) == NULL
- || mSurface == NULL) {
+ || mSurface == NULL || mVideoDecoder == NULL) {
// When both audio and video have error, or this stream has only audio
// which has error, notify client of error.
notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
@@ -1182,7 +1182,7 @@
mAudioDecoderError = true;
} else {
if (mAudioDecoderError || mSource->getFormat(true /* audio */) == NULL
- || mAudioSink == NULL) {
+ || mAudioSink == NULL || mAudioDecoder == NULL) {
// When both audio and video have error, or this stream has only video
// which has error, notify client of error.
notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
index ad788f7..0fc1aa7 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
@@ -639,11 +639,6 @@
notifyListener_l(MEDIA_STOPPED);
}
- if (property_get_bool("persist.debug.sf.stats", false)) {
- Vector<String16> args;
- dump(-1, args);
- }
-
mState = STATE_RESET_IN_PROGRESS;
mPlayer->resetAsync();
@@ -935,7 +930,10 @@
// don't send completion event when looping
return;
}
-
+ if (property_get_bool("persist.debug.sf.stats", false)) {
+ Vector<String16> args;
+ dump(-1, args);
+ }
mPlayer->pause();
mState = STATE_PAUSED;
}
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index 758db1f..483a9ff 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -840,7 +840,7 @@
return;
}
- notifyEOS(true /* audio */, ERROR_END_OF_STREAM);
+ notifyEOS_l(true /* audio */, ERROR_END_OF_STREAM);
}
size_t NuPlayer::Renderer::fillAudioBuffer(void *buffer, size_t size) {
@@ -917,10 +917,10 @@
if (mAudioSink->needsTrailingPadding()) {
postEOSDelayUs = getPendingAudioPlayoutDurationUs(ALooper::GetNowUs());
}
- ALOGV("fillAudioBuffer: notifyEOS "
+ ALOGV("fillAudioBuffer: notifyEOS_l "
"mNumFramesWritten:%u finalResult:%d postEOSDelay:%lld",
mNumFramesWritten, entry->mFinalResult, (long long)postEOSDelayUs);
- notifyEOS(true /* audio */, entry->mFinalResult, postEOSDelayUs);
+ notifyEOS_l(true /* audio */, entry->mFinalResult, postEOSDelayUs);
}
}
return sizeCopied;
@@ -1408,6 +1408,11 @@
}
void NuPlayer::Renderer::notifyEOS(bool audio, status_t finalResult, int64_t delayUs) {
+ Mutex::Autolock autoLock(mLock);
+ notifyEOS_l(audio, finalResult, delayUs);
+}
+
+void NuPlayer::Renderer::notifyEOS_l(bool audio, status_t finalResult, int64_t delayUs) {
if (audio && delayUs > 0) {
sp<AMessage> msg = new AMessage(kWhatEOS, this);
msg->setInt32("audioEOSGeneration", mAudioEOSGeneration);
@@ -1420,6 +1425,11 @@
notify->setInt32("audio", static_cast<int32_t>(audio));
notify->setInt32("finalResult", finalResult);
notify->post(delayUs);
+
+ if (audio) {
+ // Video might outlive audio. Clear anchor to enable video only case.
+ mAnchorTimeMediaUs = -1;
+ }
}
void NuPlayer::Renderer::notifyAudioTearDown(AudioTearDownReason reason) {
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
index e6850b5..f58b79c 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
@@ -275,6 +275,7 @@
void onChangeAudioFormat(const sp<AMessage> &meta, const sp<AMessage> ¬ify);
void notifyEOS(bool audio, status_t finalResult, int64_t delayUs = 0);
+ void notifyEOS_l(bool audio, status_t finalResult, int64_t delayUs = 0);
void notifyFlushComplete(bool audio);
void notifyPosition();
void notifyVideoLateBy(int64_t lateByUs);
diff --git a/media/libnbaio/Android.bp b/media/libnbaio/Android.bp
index f511876..02f7529 100644
--- a/media/libnbaio/Android.bp
+++ b/media/libnbaio/Android.bp
@@ -1,13 +1,48 @@
+
+cc_defaults {
+ name: "libnbaio_mono_defaults",
+ srcs: [
+ "MonoPipe.cpp",
+ "MonoPipeReader.cpp",
+ "NBAIO.cpp",
+ ],
+ header_libs: [
+ "libaudioclient_headers",
+ "libaudio_system_headers",
+ "libmedia_headers",
+ ],
+ export_header_lib_headers: [
+ "libaudioclient_headers",
+ "libmedia_headers",
+ ],
+
+ shared_libs: [
+ "libaudioutils",
+ "liblog",
+ "libutils",
+ ],
+
+ export_include_dirs: ["include_mono"],
+}
+
+// libnbaio_mono is the part of libnbaio that is available for vendors to use. Vendor modules can't
+// link against libnbaio and system modules can't link against libnbaio_mono. The rest of libnbaio
+// pulls in too many other dependencies.
+cc_library_shared {
+ name: "libnbaio_mono",
+ vendor: true,
+ defaults: ["libnbaio_mono_defaults"],
+}
+
cc_library_shared {
name: "libnbaio",
+ defaults: ["libnbaio_mono_defaults"],
srcs: [
"AudioBufferProviderSource.cpp",
"AudioStreamInSource.cpp",
"AudioStreamOutSink.cpp",
- "MonoPipe.cpp",
- "MonoPipeReader.cpp",
- "NBAIO.cpp",
"NBLog.cpp",
+ "PerformanceAnalysis.cpp",
"Pipe.cpp",
"PipeReader.cpp",
"SourceAudioBufferProvider.cpp",
@@ -24,8 +59,8 @@
"libaudioutils",
"libbinder",
"libcutils",
- "libutils",
"liblog",
+ "libutils",
],
cflags: [
@@ -35,7 +70,5 @@
include_dirs: ["system/media/audio_utils/include"],
- local_include_dirs: ["include"],
-
export_include_dirs: ["include"],
}
diff --git a/media/libnbaio/AudioStreamOutSink.cpp b/media/libnbaio/AudioStreamOutSink.cpp
index cbff87d..8564899 100644
--- a/media/libnbaio/AudioStreamOutSink.cpp
+++ b/media/libnbaio/AudioStreamOutSink.cpp
@@ -18,6 +18,7 @@
//#define LOG_NDEBUG 0
#include <utils/Log.h>
+#include <audio_utils/clock.h>
#include <media/audiohal/StreamHalInterface.h>
#include <media/nbaio/AudioStreamOutSink.h>
@@ -82,8 +83,7 @@
return INVALID_OPERATION;
}
timestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL] = position64;
- timestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL] =
- time.tv_sec * 1000000000LL + time.tv_nsec;
+ timestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL] = audio_utils_ns_from_timespec(&time);
return OK;
}
diff --git a/media/libnbaio/NBLog.cpp b/media/libnbaio/NBLog.cpp
index ebb90c8..a352b15 100644
--- a/media/libnbaio/NBLog.cpp
+++ b/media/libnbaio/NBLog.cpp
@@ -18,14 +18,14 @@
* Documentation: Workflow summary for histogram data processing:
* For more details on FIFO, please see system/media/audio_utils; doxygen
* TODO: add this documentation to doxygen once it is further developed
-* 1) writing the data to a buffer
-* onWork
+* 1) Writing buffer period timestamp to the circular buffer
+* onWork()
* Called every period length (e.g., 4ms)
* Calls LOG_HIST_TS
* LOG_HIST_TS
-* Hashes file name and line number
-* calls NBLOG::Writer::logHistTS once
-* NBLOG::Writer::logHistTS
+* Hashes file name and line number, and writes single timestamp to buffer
+* calls NBLOG::Writer::logEventHistTS once
+* NBLOG::Writer::logEventHistTS
* calls NBLOG::Writer::log on hash and current timestamp
* time is in CLOCK_MONOTONIC converted to ns
* NBLOG::Writer::log(Event, const void*, size_t)
@@ -44,6 +44,8 @@
* ssize_t audio_utils_fifo_reader::obtain
* Determines readable buffer section via pointer arithmetic on reader
* and writer pointers
+* Similarly, LOG_AUDIO_STATE() is called by onStateChange whenever audio is
+* turned on or off, and writes this notification to the FIFO.
*
* 2) reading the data from shared memory
* Thread::threadloop()
@@ -51,6 +53,7 @@
* NBLog::MergeThread::threadLoop()
* calls NBLog::Merger::merge
* NBLog::Merger::merge
+* Merges snapshots sorted by timestamp
* for each reader in vector of class NamedReader,
* callsNamedReader::reader()->getSnapshot
* TODO: check whether the rest of this function is relevant
@@ -59,11 +62,12 @@
* calls mFifoReader->obtain to find readable data
* sets snapshot.begin() and .end() iterators to boundaries of valid entries
* moves the fifo reader index to after the last entry read
-* in this case, the buffer is in shared memory. in (3), the buffer is private
+* in this case, the buffer is in shared memory. in (4), the buffer is private
*
* 3) reading the data from private buffer
* MediaLogService::dump
-* calls NBLog::Reader::dump(int) on instance of subclass mergeReader
+* calls NBLog::Reader::dump(CONSOLE)
+* The private buffer contains all logs for all readers in shared memory
* NBLog::Reader::dump(int)
* calls getSnapshot on the current reader
* calls dump(int, size_t, Snapshot)
@@ -72,9 +76,10 @@
* (string, timestamp, etc...)
* In the case of EVENT_HISTOGRAM_ENTRY_TS, adds a list of timestamp sequences
* (histogram entry) to NBLog::mHists
-* In the case of EVENT_HISTOGRAM_FLUSH, calls drawHistogram on each element in
-* the list and erases it
-* TODO: when do these events occur?
+* TODO: add every HISTOGRAM_ENTRY_TS to two
+* circular buffers: one short-term and one long-term (can add even longer-term
+* structures in the future). When dump is called, print everything currently
+* in the buffer.
* NBLog::drawHistogram
* input: timestamp array
* buckets this to a histogram and prints
@@ -82,7 +87,7 @@
*/
#define LOG_TAG "NBLog"
-//#define LOG_NDEBUG 0
+// #define LOG_NDEBUG 0
#include <algorithm>
#include <climits>
@@ -102,6 +107,7 @@
#include <new>
#include <audio_utils/roundup.h>
#include <media/nbaio/NBLog.h>
+#include <media/nbaio/PerformanceAnalysis.h>
// #include <utils/CallStack.h> // used to print callstack
#include <utils/Log.h>
#include <utils/String8.h>
@@ -134,7 +140,7 @@
switch (type) {
case EVENT_START_FMT:
return std::make_unique<FormatEntry>(FormatEntry(ptr));
- case EVENT_HISTOGRAM_FLUSH:
+ case EVENT_AUDIO_STATE:
case EVENT_HISTOGRAM_ENTRY_TS:
return std::make_unique<HistogramEntry>(HistogramEntry(ptr));
default:
@@ -513,7 +519,7 @@
log(EVENT_HASH, &hash, sizeof(hash));
}
-void NBLog::Writer::logHistTS(log_hash_t hash)
+void NBLog::Writer::logEventHistTs(Event event, log_hash_t hash)
{
if (!mEnabled) {
return;
@@ -522,22 +528,7 @@
data.hash = hash;
data.ts = get_monotonic_ns();
if (data.ts > 0) {
- log(EVENT_HISTOGRAM_ENTRY_TS, &data, sizeof(data));
- } else {
- ALOGE("Failed to get timestamp");
- }
-}
-
-void NBLog::Writer::logHistFlush(log_hash_t hash)
-{
- if (!mEnabled) {
- return;
- }
- HistTsEntry data;
- data.hash = hash;
- data.ts = get_monotonic_ns();
- if (data.ts > 0) {
- log(EVENT_HISTOGRAM_FLUSH, &data, sizeof(data));
+ log(event, &data, sizeof(data));
} else {
ALOGE("Failed to get timestamp");
}
@@ -771,15 +762,15 @@
NBLog::Event::EVENT_HISTOGRAM_ENTRY_TS};
const std::set<NBLog::Event> NBLog::Reader::endingTypes {NBLog::Event::EVENT_END_FMT,
NBLog::Event::EVENT_HISTOGRAM_ENTRY_TS,
- NBLog::Event::EVENT_HISTOGRAM_FLUSH};
+ NBLog::Event::EVENT_AUDIO_STATE};
+
NBLog::Reader::Reader(const void *shared, size_t size)
: mShared((/*const*/ Shared *) shared), /*mIMemory*/
mFd(-1), mIndent(0),
mFifo(mShared != NULL ?
new audio_utils_fifo(size, sizeof(uint8_t),
mShared->mBuffer, mShared->mRear, NULL /*throttlesFront*/) : NULL),
- mFifoReader(mFifo != NULL ? new audio_utils_fifo_reader(*mFifo) : NULL),
- findGlitch(false)
+ mFifoReader(mFifo != NULL ? new audio_utils_fifo_reader(*mFifo) : NULL)
{
}
@@ -795,39 +786,6 @@
delete mFifo;
}
-inline static int deltaMs(int64_t ns1, int64_t ns2) {
- return (ns2 - ns1) / (1000 * 1000);
-}
-
-// Produces a log warning if the timing of recent buffer periods caused a glitch
-// Computes sum of running window of three buffer periods
-// Checks whether the buffer periods leave enough CPU time for the next one
-// e.g. if a buffer period is expected to be 4 ms and a buffer requires 3 ms of CPU time,
-// here are some glitch cases:
-// 4 + 4 + 6 ; 5 + 4 + 5; 2 + 2 + 10
-// TODO: develop this code to track changes in histogram distribution in addition
-// to / instead of glitches
-void NBLog::Reader::alertIfGlitch(const std::vector<int64_t> &samples) {
- //TODO: measure kPeriodLen and kRatio from the data as they may change.
- static const int kPeriodLen = 4; // current period length is ideally 4 ms
- static const double kRatio = 0.75; // estimate of CPU time as ratio of period length
- // DAC processing time for 4 ms buffer
- static const int kPeriodTime = static_cast<int>(round(kPeriodLen * kRatio));
- static const int kNumBuff = 3; // number of buffers considered in local history
- std::deque<int> periods(kNumBuff, kPeriodLen);
- for (size_t i = 2; i < samples.size(); ++i) { // skip first time entry
- periods.push_front(deltaMs(samples[i - 1], samples[i]));
- periods.pop_back();
- // TODO: check that all glitch cases are covered
- if (std::accumulate(periods.begin(), periods.end(), 0) > kNumBuff * kPeriodLen +
- kPeriodLen - kPeriodTime) {
- ALOGW("A glitch occurred");
- periods.assign(kNumBuff, kPeriodLen);
- }
- }
- return;
-}
-
const uint8_t *NBLog::Reader::findLastEntryOfTypes(const uint8_t *front, const uint8_t *back,
const std::set<Event> &types) {
while (back + Entry::kPreviousLengthOffset >= front) {
@@ -941,31 +899,12 @@
void NBLog::Reader::dump(int fd, size_t indent, NBLog::Reader::Snapshot &snapshot)
{
- // CallStack cs(LOG_TAG);
-#if 0
- struct timespec ts;
- time_t maxSec = -1;
- while (entry - start >= (int) Entry::kOverhead) {
- if (prevEntry - start < 0 || !prevEntry.hasConsistentLength()) {
- break;
- }
- if (prevEntry->type == EVENT_TIMESTAMP) {
- if (prevEntry->length != sizeof(struct timespec)) {
- // corrupt
- break;
- }
- prevEntry.copyData((uint8_t*) &ts);
- if (ts.tv_sec > maxSec) {
- maxSec = ts.tv_sec;
- }
- }
- --entry;
- --prevEntry;
- }
-#endif
+ // CallStack cs(LOG_TAG);
mFd = fd;
mIndent = indent;
String8 timestamp, body;
+ // FIXME: this is not thread safe
+ static PerformanceAnalysis performanceAnalysis; // used to store data and to call analysis functions
size_t lost = snapshot.lost() + (snapshot.begin() - EntryIterator(snapshot.data()));
if (lost > 0) {
body.appendFormat("warning: lost %zu bytes worth of events", lost);
@@ -973,85 +912,9 @@
// log to push it out. Consider keeping the timestamp/body between calls to copyEntryDataAt().
dumpLine(timestamp, body);
}
-#if 0
- size_t width = 1;
- while (maxSec >= 10) {
- ++width;
- maxSec /= 10;
- }
- if (maxSec >= 0) {
- timestamp.appendFormat("[%*s]", (int) width + 4, "");
- }
- bool deferredTimestamp = false;
-#endif
for (auto entry = snapshot.begin(); entry != snapshot.end();) {
switch (entry->type) {
-#if 0
- case EVENT_STRING:
- body.appendFormat("%.*s", (int) entry.length(), entry.data());
- break;
- case EVENT_TIMESTAMP: {
- // already checked that length == sizeof(struct timespec);
- entry.copyData((const uint8_t*) &ts);
- long prevNsec = ts.tv_nsec;
- long deltaMin = LONG_MAX;
- long deltaMax = -1;
- long deltaTotal = 0;
- auto aux(entry);
- for (;;) {
- ++aux;
- if (end - aux >= 0 || aux.type() != EVENT_TIMESTAMP) {
- break;
- }
- struct timespec tsNext;
- aux.copyData((const uint8_t*) &tsNext);
- if (tsNext.tv_sec != ts.tv_sec) {
- break;
- }
- long delta = tsNext.tv_nsec - prevNsec;
- if (delta < 0) {
- break;
- }
- if (delta < deltaMin) {
- deltaMin = delta;
- }
- if (delta > deltaMax) {
- deltaMax = delta;
- }
- deltaTotal += delta;
- prevNsec = tsNext.tv_nsec;
- }
- size_t n = (aux - entry) / (sizeof(struct timespec) + 3 /*Entry::kOverhead?*/);
- if (deferredTimestamp) {
- dumpLine(timestamp, body);
- deferredTimestamp = false;
- }
- timestamp.clear();
- if (n >= kSquashTimestamp) {
- timestamp.appendFormat("[%d.%03d to .%.03d by .%.03d to .%.03d]",
- (int) ts.tv_sec, (int) (ts.tv_nsec / 1000000),
- (int) ((ts.tv_nsec + deltaTotal) / 1000000),
- (int) (deltaMin / 1000000), (int) (deltaMax / 1000000));
- entry = aux;
- // advance = 0;
- break;
- }
- timestamp.appendFormat("[%d.%03d]", (int) ts.tv_sec,
- (int) (ts.tv_nsec / 1000000));
- deferredTimestamp = true;
- }
- break;
- case EVENT_INTEGER:
- appendInt(&body, entry.data());
- break;
- case EVENT_FLOAT:
- appendFloat(&body, entry.data());
- break;
- case EVENT_PID:
- appendPID(&body, entry.data(), entry.length());
- break;
-#endif
case EVENT_START_FMT:
entry = handleFormat(FormatEntry(entry), ×tamp, &body);
break;
@@ -1063,40 +926,15 @@
memcpy(&hash, &(data->hash), sizeof(hash));
int64_t ts;
memcpy(&ts, &data->ts, sizeof(ts));
- const std::pair<log_hash_t, int> key(hash, data->author);
- // TODO might want to filter excessively high outliers, which are usually caused
- // by the thread being inactive.
- mHists[key].push_back(ts);
+ performanceAnalysis.logTsEntry(data->author, ts);
++entry;
break;
}
- // draws histograms stored in global Reader::mHists and erases them
- case EVENT_HISTOGRAM_FLUSH: {
- HistogramEntry histEntry(entry);
- // Log timestamp
- // Timestamp of call to drawHistogram, not when audio was generated
- const int64_t ts = histEntry.timestamp();
- timestamp.clear();
- timestamp.appendFormat("[%d.%03d]", (int) (ts / (1000 * 1000 * 1000)),
- (int) ((ts / (1000 * 1000)) % 1000));
- // Log histograms
- setFindGlitch(true);
- body.appendFormat("Histogram flush - ");
- handleAuthor(histEntry, &body);
- for (auto hist = mHists.begin(); hist != mHists.end();) {
- if (hist->first.second == histEntry.author()) {
- body.appendFormat("%X", (int)hist->first.first);
- if (findGlitch) {
- alertIfGlitch(hist->second);
- }
- // set file to empty and write data for all histograms in this set
- writeHistToFile(hist->second, hist != mHists.begin());
- drawHistogram(&body, hist->second, true, indent);
- hist = mHists.erase(hist);
- } else {
- ++hist;
- }
- }
+ case EVENT_AUDIO_STATE: {
+ StateTsEntryWithAuthor *data = (StateTsEntryWithAuthor *) (entry->data);
+ // TODO This memcpies are here to avoid unaligned memory access crash.
+ // There's probably a more efficient way to do it
+ performanceAnalysis.handleStateChange(data->author);
++entry;
break;
}
@@ -1110,10 +948,10 @@
++entry;
break;
}
-
- if (!body.isEmpty()) {
- dumpLine(timestamp, body);
- }
+ }
+ performanceAnalysis.reportPerformance(&body);
+ if (!body.isEmpty()) {
+ dumpLine(timestamp, body);
}
}
@@ -1139,16 +977,6 @@
return iMemory != 0 && mIMemory != 0 && iMemory->pointer() == mIMemory->pointer();
}
-void NBLog::Reader::setFindGlitch(bool s)
-{
- findGlitch = s;
-}
-
-bool NBLog::Reader::isFindGlitch() const
-{
- return findGlitch;
-}
-
// ---------------------------------------------------------------------------
void NBLog::appendTimestamp(String8 *body, const void *data) {
@@ -1283,126 +1111,6 @@
return arg;
}
-static int widthOf(int x) {
- int width = 0;
- while (x > 0) {
- ++width;
- x /= 10;
- }
- return width;
-}
-
-static std::map<int, int> buildBuckets(const std::vector<int64_t> &samples) {
- // TODO allow buckets of variable resolution
- std::map<int, int> buckets;
- for (size_t i = 1; i < samples.size(); ++i) {
- ++buckets[deltaMs(samples[i - 1], samples[i])];
- }
- return buckets;
-}
-
-static inline uint32_t log2(uint32_t x) {
- // This works for x > 0
- return 31 - __builtin_clz(x);
-}
-
-// TODO put this function in separate file. Make it return a std::string instead of modifying body
-/*
-Example output:
-[54.234] Histogram flush - AudioOut_D:
-Histogram 33640BF1
- [ 1][ 1][ 1][ 3][54][69][ 1][ 2][ 1]
- 64| []
- 32| [] []
- 16| [] []
- 8| [] []
- 4| [] []
- 2|______________[]__[]__[]______[]____
- 4 5 6 8 9 10 11 13 15
-Notice that all values that fall in the same row have the same height (65 and 127 are displayed
-identically). That's why exact counts are added at the top.
-*/
-void NBLog::Reader::drawHistogram(String8 *body,
- const std::vector<int64_t> &samples,
- bool logScale,
- int indent,
- int maxHeight) {
- // this avoids some corner cases
- if (samples.size() <= 1) {
- return;
- }
- // temp code for debugging the outlier timestamp
- const int kMaxMs = 100;
- for (size_t i = 1; i < samples.size()-1; ++i) {
- const int currDelta = deltaMs(samples[i - 1], samples[i]);
- if (currDelta > kMaxMs) {
- body->appendFormat("\nlocation: %zu, size: %zu, pos from end: %zu, %d\t", i,
- samples.size(), samples.size() - i, currDelta);
- }
- }
- // FIXME: as can be seen when printing the values, the outlier timestamps typically occur
- // in the first histogram 35 to 38 indices from the end (most often 35).
- // TODO: build histogram buckets earlier and discard timestamps to save memory
- std::map<int, int> buckets = buildBuckets(samples);
- // TODO consider changing all ints to uint32_t or uint64_t
-
- // underscores and spaces length corresponds to maximum width of histogram
- static const int kLen = 40;
- std::string underscores(kLen, '-');
- std::string spaces(kLen, ' ');
-
- auto it = buckets.begin();
- int maxDelta = it->first;
- int maxCount = it->second;
- // Compute maximum values
- while (++it != buckets.end()) {
- if (it->first > maxDelta) {
- maxDelta = it->first;
- }
- if (it->second > maxCount) {
- maxCount = it->second;
- }
- }
- int height = logScale ? log2(maxCount) + 1 : maxCount; // maxCount > 0, safe to call log2
- const int leftPadding = widthOf(logScale ? pow(2, height) : maxCount);
- const int colWidth = std::max(std::max(widthOf(maxDelta) + 1, 3), leftPadding + 2);
- int scalingFactor = 1;
- // scale data if it exceeds maximum height
- if (height > maxHeight) {
- scalingFactor = (height + maxHeight) / maxHeight;
- height /= scalingFactor;
- }
- body->appendFormat("\n%*s", leftPadding + 11, "Occurrences");
- // write histogram label line with bucket values
- body->appendFormat("\n%*s", indent, " ");
- body->appendFormat("%*s", leftPadding, " ");
- for (auto const &x : buckets) {
- body->appendFormat("%*d", colWidth, x.second);
- }
- // write histogram ascii art
- body->appendFormat("\n%*s", indent, " ");
- for (int row = height * scalingFactor; row >= 0; row -= scalingFactor) {
- const int value = logScale ? (1 << row) : row;
- body->appendFormat("%.*s", leftPadding, spaces.c_str());
- for (auto const &x : buckets) {
- body->appendFormat("%.*s%s", colWidth - 1, spaces.c_str(), x.second < value ? " " : "|");
- }
- body->appendFormat("\n%*s", indent, " ");
- }
- // print x-axis
- const int columns = static_cast<int>(buckets.size());
- body->appendFormat("%*c", leftPadding, ' ');
- body->appendFormat("%.*s", (columns + 1) * colWidth, underscores.c_str());
- body->appendFormat("\n%*s", indent, " ");
-
- // write footer with bucket labels
- body->appendFormat("%*s", leftPadding, " ");
- for (auto const &x : buckets) {
- body->appendFormat("%*d", colWidth, x.first);
- }
- body->appendFormat("%.*s%s", colWidth, spaces.c_str(), "ms\n");
-}
-
NBLog::Merger::Merger(const void *shared, size_t size):
mShared((Shared *) shared),
mFifo(mShared != NULL ?
diff --git a/media/libnbaio/OWNERS b/media/libnbaio/OWNERS
new file mode 100644
index 0000000..f9cb567
--- /dev/null
+++ b/media/libnbaio/OWNERS
@@ -0,0 +1 @@
+gkasten@google.com
diff --git a/media/libnbaio/PerformanceAnalysis.cpp b/media/libnbaio/PerformanceAnalysis.cpp
new file mode 100644
index 0000000..7cba4c6
--- /dev/null
+++ b/media/libnbaio/PerformanceAnalysis.cpp
@@ -0,0 +1,345 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#define LOG_TAG "PerformanceAnalysis"
+// #define LOG_NDEBUG 0
+
+#include <algorithm>
+#include <climits>
+#include <deque>
+#include <fstream>
+#include <iostream>
+#include <math.h>
+#include <numeric>
+#include <vector>
+#include <stdarg.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/prctl.h>
+#include <time.h>
+#include <new>
+#include <audio_utils/roundup.h>
+#include <media/nbaio/NBLog.h>
+#include <media/nbaio/PerformanceAnalysis.h>
+// #include <utils/CallStack.h> // used to print callstack
+#include <utils/Log.h>
+#include <utils/String8.h>
+
+#include <queue>
+#include <utility>
+
+namespace android {
+
+PerformanceAnalysis::PerformanceAnalysis() {
+ // These variables will be (FIXME) learned from the data
+ kPeriodMs = 4; // typical buffer period (mode)
+ // average number of Ms spent processing buffer
+ kPeriodMsCPU = static_cast<int>(kPeriodMs * kRatio);
+}
+
+// converts a time series into a map. key: buffer period length. value: count
+static std::map<int, int> buildBuckets(const std::vector<int64_t> &samples) {
+ // TODO allow buckets of variable resolution
+ std::map<int, int> buckets;
+ for (size_t i = 1; i < samples.size(); ++i) {
+ ++buckets[deltaMs(samples[i - 1], samples[i])];
+ }
+ return buckets;
+}
+
+static int widthOf(int x) {
+ int width = 0;
+ while (x > 0) {
+ ++width;
+ x /= 10;
+ }
+ return width;
+}
+
+// Given a series of audio processing wakeup timestamps,
+// buckets the time intervals into a histogram, searches for
+// outliers, analyzes the outlier series for unexpectedly
+// small or large values and stores these as peaks, and flushes
+// the timestamp series from memory.
+void PerformanceAnalysis::processAndFlushTimeStampSeries(int author) {
+ // 1) analyze the series to store all outliers and their exact timestamps:
+ storeOutlierData(mTimeStampSeries[author]);
+
+ // 2) detect peaks in the outlier series
+ detectPeaks();
+
+ // 3) compute its histogram, append this to mRecentHists and erase the time series
+ // FIXME: need to store the timestamp of the beginning of each histogram
+ // FIXME: Restore LOG_HIST_FLUSH to separate histograms at every end-of-stream event
+ // A histogram should not span data between audio off/on timespans
+ mRecentHists.emplace_back(author, buildBuckets(mTimeStampSeries[author]));
+ // do not let mRecentHists exceed capacity
+ // ALOGD("mRecentHists size: %d", static_cast<int>(mRecentHists.size()));
+ if (mRecentHists.size() >= kRecentHistsCapacity) {
+ // ALOGD("popped back mRecentHists");
+ mRecentHists.pop_front();
+ }
+ mTimeStampSeries[author].clear();
+}
+
+// forces short-term histogram storage to avoid adding idle audio time interval
+// to buffer period data
+void PerformanceAnalysis::handleStateChange(int author) {
+ ALOGD("handleStateChange");
+ processAndFlushTimeStampSeries(author);
+ return;
+}
+
+// Takes a single buffer period timestamp entry with author information and stores it
+// in a temporary series of timestamps. Once the series is full, the data is analyzed,
+// stored, and emptied.
+// TODO: decide whether author or file location information is more important to store
+// for now, only stores author (thread)
+void PerformanceAnalysis::logTsEntry(int author, int64_t ts) {
+ // TODO might want to filter excessively high outliers, which are usually caused
+ // by the thread being inactive.
+ // Store time series data for each reader in order to bucket it once there
+ // is enough data. Then, write to recentHists as a histogram.
+ mTimeStampSeries[author].push_back(ts);
+ // if length of the time series has reached kShortHistSize samples,
+ // analyze the data and flush the timestamp series from memory
+ if (mTimeStampSeries[author].size() >= kShortHistSize) {
+ processAndFlushTimeStampSeries(author);
+ }
+}
+
+// Given a series of outlier intervals (mOutlier data),
+// looks for changes in distribution (peaks), which can be either positive or negative.
+// The function sets the mean to the starting value and sigma to 0, and updates
+// them as long as no peak is detected. When a value is more than 'threshold'
+// standard deviations from the mean, a peak is detected and the mean and sigma
+// are set to the peak value and 0.
+void PerformanceAnalysis::detectPeaks() {
+ if (mOutlierData.empty()) {
+ ALOGD("peak detector called on empty array");
+ return;
+ }
+
+ // compute mean of the distribution. Used to check whether a value is large
+ const double kTypicalDiff = std::accumulate(
+ mOutlierData.begin(), mOutlierData.end(), 0,
+ [](auto &a, auto &b){return a + b.first;}) / mOutlierData.size();
+ // ALOGD("typicalDiff %f", kTypicalDiff);
+
+ // iterator at the beginning of a sequence, or updated to the most recent peak
+ std::deque<std::pair<uint64_t, uint64_t>>::iterator start = mOutlierData.begin();
+ // the mean and standard deviation are updated every time a peak is detected
+ // initialize first time. The mean from the previous sequence is stored
+ // for the next sequence. Here, they are initialized for the first time.
+ if (mPeakDetectorMean < 0) {
+ mPeakDetectorMean = static_cast<double>(start->first);
+ mPeakDetectorSd = 0;
+ }
+ auto sqr = [](auto x){ return x * x; };
+ for (auto it = mOutlierData.begin(); it != mOutlierData.end(); ++it) {
+ // no surprise occurred:
+ // the new element is a small number of standard deviations from the mean
+ if ((fabs(it->first - mPeakDetectorMean) < kStddevThreshold * mPeakDetectorSd) ||
+ // or: right after peak has been detected, the delta is smaller than average
+ (mPeakDetectorSd == 0 && fabs(it->first - mPeakDetectorMean) < kTypicalDiff)) {
+ // update the mean and sd:
+ // count number of elements (distance between start interator and current)
+ const int kN = std::distance(start, it) + 1;
+ // usual formulas for mean and sd
+ mPeakDetectorMean = std::accumulate(start, it + 1, 0.0,
+ [](auto &a, auto &b){return a + b.first;}) / kN;
+ mPeakDetectorSd = sqrt(std::accumulate(start, it + 1, 0.0,
+ [=](auto &a, auto &b){ return a + sqr(b.first - mPeakDetectorMean);})) /
+ ((kN > 1)? kN - 1 : kN); // kN - 1: mean is correlated with variance
+ // ALOGD("value, mean, sd: %f, %f, %f", static_cast<double>(it->first), mean, sd);
+ }
+ // surprising value: store peak timestamp and reset mean, sd, and start iterator
+ else {
+ mPeakTimestamps.emplace_back(it->second);
+ // TODO: remove pop_front once a circular buffer is in place
+ if (mPeakTimestamps.size() >= kShortHistSize) {
+ ALOGD("popped back mPeakTimestamps");
+ mPeakTimestamps.pop_front();
+ }
+ mPeakDetectorMean = static_cast<double>(it->first);
+ mPeakDetectorSd = 0;
+ start = it;
+ }
+ }
+ //for (const auto &it : mPeakTimestamps) {
+ // ALOGE("mPeakTimestamps %f", static_cast<double>(it));
+ //}
+ return;
+}
+
+// Called by LogTsEntry. The input is a vector of timestamps.
+// Finds outliers and writes to mOutlierdata.
+// Each value in mOutlierdata consists of: <outlier timestamp, time elapsed since previous outlier>.
+// e.g. timestamps (ms) 1, 4, 5, 16, 18, 28 will produce pairs (4, 5), (13, 18).
+// This function is applied to the time series before it is converted into a histogram.
+void PerformanceAnalysis::storeOutlierData(const std::vector<int64_t> ×tamps) {
+ if (timestamps.size() < 1) {
+ ALOGE("storeOutlierData called on empty vector");
+ return;
+ }
+ // first pass: need to initialize
+ if (mElapsed == 0) {
+ mPrevNs = timestamps[0];
+ }
+ for (const auto &ts: timestamps) {
+ const uint64_t diffMs = static_cast<uint64_t>(deltaMs(mPrevNs, ts));
+ if (diffMs >= static_cast<uint64_t>(kOutlierMs)) {
+ mOutlierData.emplace_back(mElapsed, static_cast<uint64_t>(mPrevNs));
+ // Remove oldest value if the vector is full
+ // TODO: remove pop_front once circular buffer is in place
+ // FIXME: change kShortHistSize to some other constant. Make sure it is large
+ // enough that data will never be lost before being written to a long-term FIFO
+ if (mOutlierData.size() >= kShortHistSize) {
+ ALOGD("popped back mOutlierData");
+ mOutlierData.pop_front();
+ }
+ mElapsed = 0;
+ }
+ mElapsed += diffMs;
+ mPrevNs = ts;
+ }
+}
+
+
+// FIXME: delete this temporary test code, recycled for various new functions
+void PerformanceAnalysis::testFunction() {
+ // produces values (4: 5000000), (13: 18000000)
+ // ns timestamps of buffer periods
+ const std::vector<int64_t>kTempTestData = {1000000, 4000000, 5000000,
+ 16000000, 18000000, 28000000};
+ PerformanceAnalysis::storeOutlierData(kTempTestData);
+ for (const auto &outlier: mOutlierData) {
+ ALOGE("PerformanceAnalysis test %lld: %lld",
+ static_cast<long long>(outlier.first), static_cast<long long>(outlier.second));
+ }
+ detectPeaks();
+}
+
+// TODO Make it return a std::string instead of modifying body --> is this still relevant?
+// FIXME: as can be seen when printing the values, the outlier timestamps typically occur
+// in the first histogram 35 to 38 indices from the end (most often 35).
+// TODO consider changing all ints to uint32_t or uint64_t
+void PerformanceAnalysis::reportPerformance(String8 *body, int maxHeight) {
+ if (mRecentHists.size() < 1) {
+ ALOGD("reportPerformance: mRecentHists is empty");
+ return;
+ }
+ ALOGD("reportPerformance: hists size %d", static_cast<int>(mRecentHists.size()));
+ // TODO: more elaborate data analysis
+ std::map<int, int> buckets;
+ for (const auto &shortHist: mRecentHists) {
+ for (const auto &countPair : shortHist.second) {
+ buckets[countPair.first] += countPair.second;
+ }
+ }
+
+ // underscores and spaces length corresponds to maximum width of histogram
+ static const int kLen = 40;
+ std::string underscores(kLen, '_');
+ std::string spaces(kLen, ' ');
+
+ auto it = buckets.begin();
+ int maxDelta = it->first;
+ int maxCount = it->second;
+ // Compute maximum values
+ while (++it != buckets.end()) {
+ if (it->first > maxDelta) {
+ maxDelta = it->first;
+ }
+ if (it->second > maxCount) {
+ maxCount = it->second;
+ }
+ }
+ int height = log2(maxCount) + 1; // maxCount > 0, safe to call log2
+ const int leftPadding = widthOf(1 << height);
+ const int colWidth = std::max(std::max(widthOf(maxDelta) + 1, 3), leftPadding + 2);
+ int scalingFactor = 1;
+ // scale data if it exceeds maximum height
+ if (height > maxHeight) {
+ scalingFactor = (height + maxHeight) / maxHeight;
+ height /= scalingFactor;
+ }
+ body->appendFormat("\n%*s", leftPadding + 11, "Occurrences");
+ // write histogram label line with bucket values
+ body->appendFormat("\n%s", " ");
+ body->appendFormat("%*s", leftPadding, " ");
+ for (auto const &x : buckets) {
+ body->appendFormat("%*d", colWidth, x.second);
+ }
+ // write histogram ascii art
+ body->appendFormat("\n%s", " ");
+ for (int row = height * scalingFactor; row >= 0; row -= scalingFactor) {
+ const int value = 1 << row;
+ body->appendFormat("%.*s", leftPadding, spaces.c_str());
+ for (auto const &x : buckets) {
+ body->appendFormat("%.*s%s", colWidth - 1, spaces.c_str(), x.second < value ? " " : "|");
+ }
+ body->appendFormat("\n%s", " ");
+ }
+ // print x-axis
+ const int columns = static_cast<int>(buckets.size());
+ body->appendFormat("%*c", leftPadding, ' ');
+ body->appendFormat("%.*s", (columns + 1) * colWidth, underscores.c_str());
+ body->appendFormat("\n%s", " ");
+
+ // write footer with bucket labels
+ body->appendFormat("%*s", leftPadding, " ");
+ for (auto const &x : buckets) {
+ body->appendFormat("%*d", colWidth, x.first);
+ }
+ body->appendFormat("%.*s%s", colWidth, spaces.c_str(), "ms\n");
+
+ // Now report glitches
+ body->appendFormat("\ntime elapsed between glitches and glitch timestamps\n");
+ for (const auto &outlier: mOutlierData) {
+ body->appendFormat("%lld: %lld\n", static_cast<long long>(outlier.first),
+ static_cast<long long>(outlier.second));
+ }
+
+}
+
+
+// Produces a log warning if the timing of recent buffer periods caused a glitch
+// Computes sum of running window of three buffer periods
+// Checks whether the buffer periods leave enough CPU time for the next one
+// e.g. if a buffer period is expected to be 4 ms and a buffer requires 3 ms of CPU time,
+// here are some glitch cases:
+// 4 + 4 + 6 ; 5 + 4 + 5; 2 + 2 + 10
+// TODO: develop this code to track changes in histogram distribution in addition
+// to / instead of glitches.
+void PerformanceAnalysis::alertIfGlitch(const std::vector<int64_t> &samples) {
+ std::deque<int> periods(kNumBuff, kPeriodMs);
+ for (size_t i = 2; i < samples.size(); ++i) { // skip first time entry
+ periods.push_front(deltaMs(samples[i - 1], samples[i]));
+ periods.pop_back();
+ // TODO: check that all glitch cases are covered
+ if (std::accumulate(periods.begin(), periods.end(), 0) > kNumBuff * kPeriodMs +
+ kPeriodMs - kPeriodMsCPU) {
+ ALOGW("A glitch occurred");
+ periods.assign(kNumBuff, kPeriodMs);
+ }
+ }
+ return;
+}
+
+} // namespace android
diff --git a/media/libnbaio/include/AudioBufferProviderSource.h b/media/libnbaio/include/media/nbaio/AudioBufferProviderSource.h
similarity index 98%
rename from media/libnbaio/include/AudioBufferProviderSource.h
rename to media/libnbaio/include/media/nbaio/AudioBufferProviderSource.h
index 4747dcf..71182bb 100644
--- a/media/libnbaio/include/AudioBufferProviderSource.h
+++ b/media/libnbaio/include/media/nbaio/AudioBufferProviderSource.h
@@ -19,8 +19,8 @@
#ifndef ANDROID_AUDIO_BUFFER_PROVIDER_SOURCE_H
#define ANDROID_AUDIO_BUFFER_PROVIDER_SOURCE_H
-#include "NBAIO.h"
#include <media/AudioBufferProvider.h>
+#include <media/nbaio/NBAIO.h>
namespace android {
diff --git a/media/libnbaio/include/AudioStreamInSource.h b/media/libnbaio/include/media/nbaio/AudioStreamInSource.h
similarity index 98%
rename from media/libnbaio/include/AudioStreamInSource.h
rename to media/libnbaio/include/media/nbaio/AudioStreamInSource.h
index 508e0fe..8a3ffbe 100644
--- a/media/libnbaio/include/AudioStreamInSource.h
+++ b/media/libnbaio/include/media/nbaio/AudioStreamInSource.h
@@ -17,7 +17,7 @@
#ifndef ANDROID_AUDIO_STREAM_IN_SOURCE_H
#define ANDROID_AUDIO_STREAM_IN_SOURCE_H
-#include "NBAIO.h"
+#include <media/nbaio/NBAIO.h>
namespace android {
diff --git a/media/libnbaio/include/AudioStreamOutSink.h b/media/libnbaio/include/media/nbaio/AudioStreamOutSink.h
similarity index 98%
rename from media/libnbaio/include/AudioStreamOutSink.h
rename to media/libnbaio/include/media/nbaio/AudioStreamOutSink.h
index 56a2a38..348b4f8 100644
--- a/media/libnbaio/include/AudioStreamOutSink.h
+++ b/media/libnbaio/include/media/nbaio/AudioStreamOutSink.h
@@ -17,7 +17,7 @@
#ifndef ANDROID_AUDIO_STREAM_OUT_SINK_H
#define ANDROID_AUDIO_STREAM_OUT_SINK_H
-#include "NBAIO.h"
+#include <media/nbaio/NBAIO.h>
namespace android {
diff --git a/media/libnbaio/include/LibsndfileSink.h b/media/libnbaio/include/media/nbaio/LibsndfileSink.h
similarity index 97%
rename from media/libnbaio/include/LibsndfileSink.h
rename to media/libnbaio/include/media/nbaio/LibsndfileSink.h
index 97a57e0..535e3f5 100644
--- a/media/libnbaio/include/LibsndfileSink.h
+++ b/media/libnbaio/include/media/nbaio/LibsndfileSink.h
@@ -17,7 +17,8 @@
#ifndef ANDROID_AUDIO_LIBSNDFILE_SINK_H
#define ANDROID_AUDIO_LIBSNDFILE_SINK_H
-#include "NBAIO.h"
+#include <media/nbaio/NBAIO.h>
+
#include "sndfile.h"
// Implementation of NBAIO_Sink that wraps a libsndfile opened in SFM_WRITE mode
diff --git a/media/libnbaio/include/LibsndfileSource.h b/media/libnbaio/include/media/nbaio/LibsndfileSource.h
similarity index 97%
rename from media/libnbaio/include/LibsndfileSource.h
rename to media/libnbaio/include/media/nbaio/LibsndfileSource.h
index 4fbdb4b..bc6aa9d 100644
--- a/media/libnbaio/include/LibsndfileSource.h
+++ b/media/libnbaio/include/media/nbaio/LibsndfileSource.h
@@ -17,7 +17,8 @@
#ifndef ANDROID_AUDIO_LIBSNDFILE_SOURCE_H
#define ANDROID_AUDIO_LIBSNDFILE_SOURCE_H
-#include "NBAIO.h"
+#include <media/nbaio/NBAIO.h>
+
#include "sndfile.h"
// Implementation of NBAIO_Source that wraps a libsndfile opened in SFM_READ mode
diff --git a/media/libnbaio/include/NBLog.h b/media/libnbaio/include/media/nbaio/NBLog.h
similarity index 95%
rename from media/libnbaio/include/NBLog.h
rename to media/libnbaio/include/media/nbaio/NBLog.h
index 785b9c2..3e48ee1 100644
--- a/media/libnbaio/include/NBLog.h
+++ b/media/libnbaio/include/media/nbaio/NBLog.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 The Android Open Source Project
+ * Copyright (C) 2017 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.
@@ -25,6 +25,7 @@
#include <utils/threads.h>
#include <map>
+#include <deque>
#include <set>
#include <vector>
@@ -43,8 +44,6 @@
class Writer;
class Reader;
-private:
-
enum Event : uint8_t {
EVENT_RESERVED,
EVENT_STRING, // ASCII string, not NUL-terminated
@@ -59,12 +58,13 @@
EVENT_HASH, // unique HASH of log origin, originates from hash of file name
// and line number
EVENT_HISTOGRAM_ENTRY_TS, // single datum for timestamp histogram
- EVENT_HISTOGRAM_FLUSH, // show histogram on log
+ EVENT_AUDIO_STATE, // audio on/off event: logged upon FastMixer::onStateChange() call
EVENT_END_FMT, // end of logFormat argument list
EVENT_UPPER_BOUND, // to check for invalid events
};
+private:
// ---------------------------------------------------------------------------
// API for handling format entry operations
@@ -248,6 +248,8 @@
int author;
}; //TODO __attribute__((packed));
+using StateTsEntryWithAuthor = HistTsEntryWithAuthor;
+
struct HistIntEntry {
log_hash_t hash;
int value;
@@ -341,8 +343,7 @@
virtual void logStart(const char *fmt);
virtual void logEnd();
virtual void logHash(log_hash_t hash);
- virtual void logHistTS(log_hash_t hash);
- virtual void logHistFlush(log_hash_t hash);
+ virtual void logEventHistTs(Event event, log_hash_t hash);
virtual bool isEnabled() const;
@@ -407,6 +408,7 @@
public:
// A snapshot of a readers buffer
+ // This is raw data. No analysis has been done on it
class Snapshot {
public:
Snapshot() : mData(NULL), mLost(0) {}
@@ -443,20 +445,17 @@
virtual ~Reader();
- void alertIfGlitch(const std::vector<int64_t> &samples);
-
// get snapshot of readers fifo buffer, effectively consuming the buffer
std::unique_ptr<Snapshot> getSnapshot();
// dump a particular snapshot of the reader
+ // TODO: move dump to PerformanceAnalysis. Model/view/controller design
void dump(int fd, size_t indent, Snapshot & snap);
// dump the current content of the reader's buffer (call getSnapshot() and previous dump())
void dump(int fd, size_t indent = 0);
bool isIMemory(const sp<IMemory>& iMemory) const;
- // if findGlitch is true, log warning when buffer periods caused glitch
- void setFindGlitch(bool s);
- bool isFindGlitch() const;
private:
+
static const std::set<Event> startingTypes;
static const std::set<Event> endingTypes;
/*const*/ Shared* const mShared; // raw pointer to shared memory, actually const but not
@@ -469,10 +468,6 @@
audio_utils_fifo_reader * const mFifoReader; // used to read from FIFO,
// non-NULL unless constructor fails
- // each pair contains a sequence of timestamps (one histogram's worth)
- // pair's log_hash_t is the hash of the source code location where the timestamp was taken
- // pair's int points to the Reader that originated the entry
- std::map<std::pair<log_hash_t, int>, std::vector<int64_t>> mHists;
// TODO: it might be clearer, instead of a direct map from source location to vector of
// timestamps, if we instead first mapped from source location to an object that
// represented that location. And one_of its fields would be a vector of timestamps.
@@ -485,17 +480,12 @@
// dummy method for handling absent author entry
virtual void handleAuthor(const AbstractEntry& /*fmtEntry*/, String8* /*body*/) {}
- static void drawHistogram(String8 *body, const std::vector<int64_t> &samples,
- bool logScale, int indent = 0, int maxHeight = 10);
-
// Searches for the last entry of type <type> in the range [front, back)
// back has to be entry-aligned. Returns nullptr if none enconuntered.
static const uint8_t *findLastEntryOfTypes(const uint8_t *front, const uint8_t *back,
const std::set<Event> &types);
static const size_t kSquashTimestamp = 5; // squash this many or more adjacent timestamps
-
- bool findGlitch; // alert if a local buffer period sequence caused an audio glitch
};
// Wrapper for a reader with a name. Contains a pointer to the reader and a pointer to the name
diff --git a/media/libnbaio/include/media/nbaio/PerformanceAnalysis.h b/media/libnbaio/include/media/nbaio/PerformanceAnalysis.h
new file mode 100644
index 0000000..4be567f
--- /dev/null
+++ b/media/libnbaio/include/media/nbaio/PerformanceAnalysis.h
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+// Non-blocking event logger intended for safe communication between processes via shared memory
+
+#ifndef ANDROID_MEDIA_PERFORMANCEANALYSIS_H
+#define ANDROID_MEDIA_PERFORMANCEANALYSIS_H
+
+#include <map>
+#include <deque>
+#include <vector>
+#include "NBLog.h"
+
+namespace android {
+
+class String8;
+
+class PerformanceAnalysis {
+ // This class stores and analyzes audio processing wakeup timestamps from NBLog
+ // FIXME: currently, all performance data is stored in deques. Need to add a mutex.
+ // FIXME: continue this way until analysis is done in a separate thread. Then, use
+ // the fifo writer utilities.
+public:
+
+ PerformanceAnalysis();
+
+ // FIXME: decide whether to use 64 or 32 bits
+ typedef uint64_t log_hash_t;
+
+ // stores a short-term histogram of size determined by kShortHistSize
+ // key: observed buffer period. value: count
+ // TODO: unsigned, unsigned
+ // TODO: change this name to histogram
+ using short_histogram = std::map<int, int>;
+
+ using outlierInterval = uint64_t;
+ // int64_t timestamps are converted to uint64_t in PerformanceAnalysis::storeOutlierData,
+ // and all further analysis functions use uint64_t.
+ using timestamp = uint64_t;
+ using timestamp_raw = int64_t;
+
+ // Given a series of audio processing wakeup timestamps,
+ // compresses and and analyzes the data, and flushes
+ // the timestamp series from memory.
+ void processAndFlushTimeStampSeries(int author);
+
+ // Called when an audio on/off event is read from the buffer
+ // calls flushTimeStampSeries on the data up to the event,
+ // effectively skipping over the idle audio time interval
+ // when writing buffer period data to memory.
+ void handleStateChange(int author);
+
+ // Writes wakeup timestamp entry to log and runs analysis
+ // author is the thread ID
+ // TODO: check. if the thread has multiple histograms, is author info correct
+ // FIXME: remove author from arglist. Want to call these function separately on
+ // each thread’s data.
+ // FIXME: decide whether to store the hash (source file location) instead
+ // FIXME: If thread has multiple histograms, check that code works and correct
+ // author is stored (test with multiple threads). Need to check that the current
+ // code is not receiving data from multiple threads. This could cause odd values.
+ void logTsEntry(int author, timestamp_raw ts);
+
+ // FIXME: make peakdetector and storeOutlierData a single function
+ // Input: mOutlierData. Looks at time elapsed between outliers
+ // finds significant changes in the distribution
+ // writes timestamps of significant changes to mPeakTimestamps
+ void detectPeaks();
+
+ // runs analysis on timestamp series before it is converted to a histogram
+ // finds outliers
+ // writes to mOutlierData <time elapsed since previous outlier, outlier timestamp>
+ void storeOutlierData(const std::vector<timestamp_raw> ×tamps);
+
+ // input: series of short histograms. Generates a string of analysis of the buffer periods
+ // TODO: WIP write more detailed analysis
+ // FIXME: move this data visualization to a separate class. Model/view/controller
+ void reportPerformance(String8 *body, int maxHeight = 10);
+
+ // TODO: delete this. temp for testing
+ void testFunction();
+
+ // This function used to detect glitches in a time series
+ // TODO incorporate this into the analysis (currently unused)
+ void alertIfGlitch(const std::vector<timestamp_raw> &samples);
+
+ ~PerformanceAnalysis() {}
+
+private:
+
+ // stores outlier analysis: <elapsed time between outliers in ms, outlier timestamp>
+ std::deque<std::pair<outlierInterval, timestamp>> mOutlierData;
+
+ // stores each timestamp at which a peak was detected
+ // a peak is a moment at which the average outlier interval changed significantly
+ std::deque<timestamp> mPeakTimestamps;
+
+ // FIFO of small histograms
+ // stores fixed-size short buffer period histograms with hash and thread data
+ // TODO: Turn it into a circular buffer for better data flow
+ std::deque<std::pair<int, short_histogram>> mRecentHists;
+
+ // map from author to vector of timestamps, collected from NBLog
+ // when a vector reaches its maximum size, analysis is run and the data is deleted
+ std::map<int, std::vector<timestamp_raw>> mTimeStampSeries;
+
+ // TODO: measure these from the data (e.g., mode) as they may change.
+ // const int kGlitchThreshMs = 7;
+ // const int kMsPerSec = 1000;
+
+ // Parameters used when detecting outliers
+ // TODO: learn some of these from the data, delete unused ones
+ // FIXME: decide whether to make kPeriodMs static.
+ // The non-const values are (TODO: will be) learned from the data
+ static const int kNumBuff = 3; // number of buffers considered in local history
+ int kPeriodMs; // current period length is ideally 4 ms
+ static const int kOutlierMs = 7; // values greater or equal to this cause glitches
+ // DAC processing time for 4 ms buffer
+ static constexpr double kRatio = 0.75; // estimate of CPU time as ratio of period length
+ int kPeriodMsCPU; // compute based on kPeriodLen and kRatio
+
+ // Peak detection: number of standard deviations from mean considered a significant change
+ static const int kStddevThreshold = 5;
+
+ static const int kRecentHistsCapacity = 100; // number of short-term histograms stored in memory
+ static const int kShortHistSize = 50; // number of samples in a short-term histogram
+
+ // these variables are stored in-class to ensure continuity while analyzing the timestamp
+ // series one short sequence at a time: the variables are not re-initialized every time.
+ // FIXME: create inner class for these variables and decide which other ones to add to it
+ double mPeakDetectorMean = -1;
+ double mPeakDetectorSd = -1;
+ // variables for storeOutlierData
+ uint64_t mElapsed = 0;
+ int64_t mPrevNs = -1;
+
+};
+
+static inline int deltaMs(int64_t ns1, int64_t ns2) {
+ return (ns2 - ns1) / (1000 * 1000);
+}
+
+static inline uint32_t log2(uint32_t x) {
+ // This works for x > 0
+ return 31 - __builtin_clz(x);
+}
+
+} // namespace android
+
+#endif // ANDROID_MEDIA_PERFORMANCEANALYSIS_H
diff --git a/media/libnbaio/include/Pipe.h b/media/libnbaio/include/media/nbaio/Pipe.h
similarity index 98%
rename from media/libnbaio/include/Pipe.h
rename to media/libnbaio/include/media/nbaio/Pipe.h
index 58b9750..0431976 100644
--- a/media/libnbaio/include/Pipe.h
+++ b/media/libnbaio/include/media/nbaio/Pipe.h
@@ -18,7 +18,7 @@
#define ANDROID_AUDIO_PIPE_H
#include <audio_utils/fifo.h>
-#include "NBAIO.h"
+#include <media/nbaio/NBAIO.h>
namespace android {
diff --git a/media/libnbaio/include/PipeReader.h b/media/libnbaio/include/media/nbaio/PipeReader.h
similarity index 100%
rename from media/libnbaio/include/PipeReader.h
rename to media/libnbaio/include/media/nbaio/PipeReader.h
diff --git a/media/libnbaio/include/SourceAudioBufferProvider.h b/media/libnbaio/include/media/nbaio/SourceAudioBufferProvider.h
similarity index 98%
rename from media/libnbaio/include/SourceAudioBufferProvider.h
rename to media/libnbaio/include/media/nbaio/SourceAudioBufferProvider.h
index ae49903..cc2d019 100644
--- a/media/libnbaio/include/SourceAudioBufferProvider.h
+++ b/media/libnbaio/include/media/nbaio/SourceAudioBufferProvider.h
@@ -19,7 +19,7 @@
#ifndef ANDROID_SOURCE_AUDIO_BUFFER_PROVIDER_H
#define ANDROID_SOURCE_AUDIO_BUFFER_PROVIDER_H
-#include "NBAIO.h"
+#include <media/nbaio/NBAIO.h>
#include <media/ExtendedAudioBufferProvider.h>
namespace android {
diff --git a/media/libnbaio/include/MonoPipe.h b/media/libnbaio/include_mono/media/nbaio/MonoPipe.h
similarity index 98%
rename from media/libnbaio/include/MonoPipe.h
rename to media/libnbaio/include_mono/media/nbaio/MonoPipe.h
index 60ae92e..c51d0fe 100644
--- a/media/libnbaio/include/MonoPipe.h
+++ b/media/libnbaio/include_mono/media/nbaio/MonoPipe.h
@@ -20,7 +20,7 @@
#include <time.h>
#include <audio_utils/fifo.h>
#include <media/SingleStateQueue.h>
-#include "NBAIO.h"
+#include <media/nbaio/NBAIO.h>
namespace android {
diff --git a/media/libnbaio/include/MonoPipeReader.h b/media/libnbaio/include_mono/media/nbaio/MonoPipeReader.h
similarity index 100%
rename from media/libnbaio/include/MonoPipeReader.h
rename to media/libnbaio/include_mono/media/nbaio/MonoPipeReader.h
diff --git a/media/libnbaio/include/NBAIO.h b/media/libnbaio/include_mono/media/nbaio/NBAIO.h
similarity index 100%
rename from media/libnbaio/include/NBAIO.h
rename to media/libnbaio/include_mono/media/nbaio/NBAIO.h
diff --git a/media/libstagefright/ACodecBufferChannel.cpp b/media/libstagefright/ACodecBufferChannel.cpp
index 0d9696f..3c7ae3e 100644
--- a/media/libstagefright/ACodecBufferChannel.cpp
+++ b/media/libstagefright/ACodecBufferChannel.cpp
@@ -20,7 +20,7 @@
#include <numeric>
-#include <android/media/IDescrambler.h>
+#include <android/hardware/cas/native/1.0/IDescrambler.h>
#include <binder/MemoryDealer.h>
#include <media/openmax/OMX_Core.h>
#include <media/stagefright/foundation/AMessage.h>
@@ -34,8 +34,11 @@
#include "include/SharedMemoryBuffer.h"
namespace android {
-using binder::Status;
-using MediaDescrambler::DescrambleInfo;
+using hardware::hidl_handle;
+using hardware::hidl_string;
+using hardware::hidl_vec;
+using namespace hardware::cas::V1_0;
+using namespace hardware::cas::native::V1_0;
using BufferInfo = ACodecBufferChannel::BufferInfo;
using BufferInfoIterator = std::vector<const BufferInfo>::const_iterator;
@@ -114,74 +117,97 @@
return -ENOENT;
}
- ICrypto::DestinationBuffer destination;
+ native_handle_t *secureHandle = NULL;
if (secure) {
sp<SecureBuffer> secureData =
static_cast<SecureBuffer *>(it->mCodecBuffer.get());
- destination.mType = secureData->getDestinationType();
- if (destination.mType != ICrypto::kDestinationTypeNativeHandle) {
+ if (secureData->getDestinationType() != ICrypto::kDestinationTypeNativeHandle) {
return BAD_VALUE;
}
- destination.mHandle =
- static_cast<native_handle_t *>(secureData->getDestinationPointer());
- } else {
- destination.mType = ICrypto::kDestinationTypeSharedMemory;
- destination.mSharedMemory = mDecryptDestination;
+ secureHandle = static_cast<native_handle_t *>(secureData->getDestinationPointer());
}
-
- ICrypto::SourceBuffer source;
- source.mSharedMemory = it->mSharedEncryptedBuffer;
- source.mHeapSeqNum = mHeapSeqNum;
-
ssize_t result = -1;
if (mCrypto != NULL) {
+ ICrypto::DestinationBuffer destination;
+ if (secure) {
+ destination.mType = ICrypto::kDestinationTypeNativeHandle;
+ destination.mHandle = secureHandle;
+ } else {
+ destination.mType = ICrypto::kDestinationTypeSharedMemory;
+ destination.mSharedMemory = mDecryptDestination;
+ }
+
+ ICrypto::SourceBuffer source;
+ source.mSharedMemory = it->mSharedEncryptedBuffer;
+ source.mHeapSeqNum = mHeapSeqNum;
+
result = mCrypto->decrypt(key, iv, mode, pattern,
source, it->mClientBuffer->offset(),
subSamples, numSubSamples, destination, errorDetailMsg);
- } else {
- DescrambleInfo descrambleInfo;
- descrambleInfo.dstType = destination.mType ==
- ICrypto::kDestinationTypeSharedMemory ?
- DescrambleInfo::kDestinationTypeVmPointer :
- DescrambleInfo::kDestinationTypeNativeHandle;
- descrambleInfo.scramblingControl = key != NULL ?
- (DescramblerPlugin::ScramblingControl)key[0] :
- DescramblerPlugin::kScrambling_Unscrambled;
- descrambleInfo.numSubSamples = numSubSamples;
- descrambleInfo.subSamples = (DescramblerPlugin::SubSample *)subSamples;
- descrambleInfo.srcMem = it->mSharedEncryptedBuffer;
- descrambleInfo.srcOffset = 0;
- descrambleInfo.dstPtr = NULL;
- descrambleInfo.dstOffset = 0;
-
- int32_t descrambleResult = -1;
- Status status = mDescrambler->descramble(descrambleInfo, &descrambleResult);
-
- if (status.isOk()) {
- result = descrambleResult;
- }
if (result < 0) {
- ALOGE("descramble failed, exceptionCode=%d, err=%d, result=%zd",
- status.exceptionCode(), status.transactionError(), result);
- } else {
- ALOGV("descramble succeeded, result=%zd", result);
+ return result;
}
- if (result > 0 && destination.mType == ICrypto::kDestinationTypeSharedMemory) {
- memcpy(destination.mSharedMemory->pointer(),
+ if (destination.mType == ICrypto::kDestinationTypeSharedMemory) {
+ memcpy(it->mCodecBuffer->base(), destination.mSharedMemory->pointer(), result);
+ }
+ } else {
+ // Here we cast CryptoPlugin::SubSample to hardware::cas::native::V1_0::SubSample
+ // directly, the structure definitions should match as checked in DescramblerImpl.cpp.
+ hidl_vec<SubSample> hidlSubSamples;
+ hidlSubSamples.setToExternal((SubSample *)subSamples, numSubSamples, false /*own*/);
+
+ ssize_t offset;
+ size_t size;
+ it->mSharedEncryptedBuffer->getMemory(&offset, &size);
+ hardware::cas::native::V1_0::SharedBuffer srcBuffer = {
+ .heapBase = mHidlMemory,
+ .offset = (uint64_t) offset,
+ .size = size
+ };
+
+ DestinationBuffer dstBuffer;
+ if (secure) {
+ dstBuffer.type = BufferType::NATIVE_HANDLE;
+ dstBuffer.secureMemory = hidl_handle(secureHandle);
+ } else {
+ dstBuffer.type = BufferType::SHARED_MEMORY;
+ dstBuffer.nonsecureMemory = srcBuffer;
+ }
+
+ Status status = Status::OK;
+ hidl_string detailedError;
+
+ auto returnVoid = mDescrambler->descramble(
+ key != NULL ? (ScramblingControl)key[0] : ScramblingControl::UNSCRAMBLED,
+ hidlSubSamples,
+ srcBuffer,
+ 0,
+ dstBuffer,
+ 0,
+ [&status, &result, &detailedError] (
+ Status _status, uint32_t _bytesWritten,
+ const hidl_string& _detailedError) {
+ status = _status;
+ result = (ssize_t)_bytesWritten;
+ detailedError = _detailedError;
+ });
+
+ if (!returnVoid.isOk() || status != Status::OK || result < 0) {
+ ALOGE("descramble failed, trans=%s, status=%d, result=%zd",
+ returnVoid.description().c_str(), status, result);
+ return UNKNOWN_ERROR;
+ }
+
+ ALOGV("descramble succeeded, %zd bytes", result);
+
+ if (dstBuffer.type == BufferType::SHARED_MEMORY) {
+ memcpy(it->mCodecBuffer->base(),
(uint8_t*)it->mSharedEncryptedBuffer->pointer(), result);
}
}
- if (result < 0) {
- return result;
- }
-
- if (destination.mType == ICrypto::kDestinationTypeSharedMemory) {
- memcpy(it->mCodecBuffer->base(), destination.mSharedMemory->pointer(), result);
- }
-
it->mCodecBuffer->setRange(0, result);
// Copy metadata from client to codec buffer.
@@ -275,10 +301,21 @@
int32_t seqNum = mCrypto->setHeap(dealer->getMemoryHeap());
if (seqNum >= 0) {
mHeapSeqNum = seqNum;
- ALOGD("setHeap returned mHeapSeqNum=%d", mHeapSeqNum);
+ ALOGV("setHeap returned mHeapSeqNum=%d", mHeapSeqNum);
} else {
mHeapSeqNum = -1;
- ALOGD("setHeap failed, setting mHeapSeqNum=-1");
+ ALOGE("setHeap failed, setting mHeapSeqNum=-1");
+ }
+ } else if (mDescrambler != nullptr) {
+ sp<IMemoryHeap> heap = dealer->getMemoryHeap();
+ native_handle_t* nativeHandle = native_handle_create(1, 0);
+ if (nativeHandle != nullptr) {
+ int fd = heap->getHeapID();
+ nativeHandle->data[0] = fd;
+ mHidlMemory = hidl_memory("ashmem", hidl_handle(nativeHandle), heap->getSize());
+ ALOGV("created hidl_memory for descrambler");
+ } else {
+ ALOGE("failed to create hidl_memory for descrambler");
}
}
return dealer;
diff --git a/media/libstagefright/Android.bp b/media/libstagefright/Android.bp
index 6cc1ace..2041b89 100644
--- a/media/libstagefright/Android.bp
+++ b/media/libstagefright/Android.bp
@@ -17,6 +17,7 @@
"AudioPlayer.cpp",
"AudioSource.cpp",
"BufferImpl.cpp",
+ "CodecBase.cpp",
"CallbackDataSource.cpp",
"CameraSource.cpp",
"CameraSourceTimeLapse.cpp",
@@ -104,6 +105,9 @@
"libhidlmemory",
"android.hidl.allocator@1.0",
"android.hidl.memory@1.0",
+ "android.hidl.token@1.0-utils",
+ "android.hardware.cas@1.0",
+ "android.hardware.cas.native@1.0",
"android.hardware.media.omx@1.0",
"libstagefright_xmlparser@1.0",
],
diff --git a/media/libstagefright/CodecBase.cpp b/media/libstagefright/CodecBase.cpp
new file mode 100644
index 0000000..d0610b2
--- /dev/null
+++ b/media/libstagefright/CodecBase.cpp
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2017, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "CodecBase"
+
+#include <android/hardware/cas/native/1.0/IDescrambler.h>
+#include <media/ICrypto.h>
+#include <media/stagefright/CodecBase.h>
+#include <utils/Log.h>
+
+namespace android {
+
+void BufferChannelBase::setCrypto(const sp<ICrypto> &crypto) {
+ mCrypto = crypto;
+}
+
+void BufferChannelBase::setDescrambler(const sp<IDescrambler> &descrambler) {
+ mDescrambler = descrambler;
+}
+
+} // namespace android
diff --git a/media/libstagefright/FrameRenderTracker.cpp b/media/libstagefright/FrameRenderTracker.cpp
index 917870f..1aa3bad 100644
--- a/media/libstagefright/FrameRenderTracker.cpp
+++ b/media/libstagefright/FrameRenderTracker.cpp
@@ -88,7 +88,9 @@
status_t FrameRenderTracker::onFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano) {
// ensure monotonic timestamps
- if (mLastRenderTimeNs >= systemNano) {
+ if (mLastRenderTimeNs > systemNano ||
+ // EOS is normally marked on the last frame
+ (mLastRenderTimeNs == systemNano && mediaTimeUs != INT64_MAX)) {
ALOGW("[%s] Ignoring out of order/stale system nano %lld for media time %lld from codec.",
mComponentName.c_str(), (long long)systemNano, (long long)mediaTimeUs);
return BAD_VALUE;
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index bd71632..98d101a 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -23,7 +23,8 @@
#include "include/SharedMemoryBuffer.h"
#include "include/SoftwareRenderer.h"
-#include <android/media/IDescrambler.h>
+#include <android/hardware/cas/native/1.0/IDescrambler.h>
+
#include <binder/IMemory.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
diff --git a/media/libstagefright/NuMediaExtractor.cpp b/media/libstagefright/NuMediaExtractor.cpp
index 51f1ba3..640cb82 100644
--- a/media/libstagefright/NuMediaExtractor.cpp
+++ b/media/libstagefright/NuMediaExtractor.cpp
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-//#define LOG_NDEBUG 0
+#define LOG_NDEBUG 0
#define LOG_TAG "NuMediaExtractor"
#include <utils/Log.h>
@@ -35,7 +35,6 @@
#include <media/stagefright/MediaSource.h>
#include <media/stagefright/MetaData.h>
#include <media/stagefright/Utils.h>
-#include <android/media/ICas.h>
namespace android {
@@ -83,8 +82,8 @@
return ERROR_UNSUPPORTED;
}
- if (mCas != NULL) {
- mImpl->setMediaCas(mCas);
+ if (!mCasToken.empty()) {
+ mImpl->setMediaCas(mCasToken);
}
status_t err = updateDurationAndBitrate();
@@ -119,8 +118,8 @@
return ERROR_UNSUPPORTED;
}
- if (mCas != NULL) {
- mImpl->setMediaCas(mCas);
+ if (!mCasToken.empty()) {
+ mImpl->setMediaCas(mCasToken);
}
err = updateDurationAndBitrate();
@@ -149,8 +148,8 @@
return ERROR_UNSUPPORTED;
}
- if (mCas != NULL) {
- mImpl->setMediaCas(mCas);
+ if (!mCasToken.empty()) {
+ mImpl->setMediaCas(mCasToken);
}
err = updateDurationAndBitrate();
@@ -161,24 +160,36 @@
return err;
}
-status_t NuMediaExtractor::setMediaCas(const sp<ICas> &cas) {
- ALOGV("setMediaCas: cas=%p", cas.get());
+static String8 arrayToString(const std::vector<uint8_t> &array) {
+ String8 result;
+ for (size_t i = 0; i < array.size(); i++) {
+ result.appendFormat("%02x ", array[i]);
+ }
+ if (result.isEmpty()) {
+ result.append("(null)");
+ }
+ return result;
+}
+
+status_t NuMediaExtractor::setMediaCas(const HInterfaceToken &casToken) {
+ ALOGV("setMediaCas: casToken={%s}", arrayToString(casToken).c_str());
Mutex::Autolock autoLock(mLock);
- if (cas == NULL) {
+ if (casToken.empty()) {
return BAD_VALUE;
}
+ mCasToken = casToken;
+
if (mImpl != NULL) {
- mImpl->setMediaCas(cas);
+ mImpl->setMediaCas(casToken);
status_t err = updateDurationAndBitrate();
if (err != OK) {
return err;
}
}
- mCas = cas;
return OK;
}
diff --git a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
index 9fbdb72..e0c0c32 100644
--- a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
+++ b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
@@ -218,6 +218,30 @@
OMX_ERRORTYPE SoftAAC2::internalGetParameter(
OMX_INDEXTYPE index, OMX_PTR params) {
switch ((OMX_U32) index) {
+ case OMX_IndexParamAudioPortFormat:
+ {
+ OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams =
+ (OMX_AUDIO_PARAM_PORTFORMATTYPE *)params;
+
+ if (!isValidOMXParam(formatParams)) {
+ return OMX_ErrorBadParameter;
+ }
+
+ if (formatParams->nPortIndex > 1) {
+ return OMX_ErrorUndefined;
+ }
+
+ if (formatParams->nIndex > 0) {
+ return OMX_ErrorNoMore;
+ }
+
+ formatParams->eEncoding =
+ (formatParams->nPortIndex == 0)
+ ? OMX_AUDIO_CodingAAC : OMX_AUDIO_CodingPCM;
+
+ return OMX_ErrorNone;
+ }
+
case OMX_IndexParamAudioAac:
{
OMX_AUDIO_PARAM_AACPROFILETYPE *aacParams =
@@ -342,6 +366,29 @@
return OMX_ErrorNone;
}
+ case OMX_IndexParamAudioPortFormat:
+ {
+ const OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams =
+ (const OMX_AUDIO_PARAM_PORTFORMATTYPE *)params;
+
+ if (!isValidOMXParam(formatParams)) {
+ return OMX_ErrorBadParameter;
+ }
+
+ if (formatParams->nPortIndex > 1) {
+ return OMX_ErrorUndefined;
+ }
+
+ if ((formatParams->nPortIndex == 0
+ && formatParams->eEncoding != OMX_AUDIO_CodingAAC)
+ || (formatParams->nPortIndex == 1
+ && formatParams->eEncoding != OMX_AUDIO_CodingPCM)) {
+ return OMX_ErrorUndefined;
+ }
+
+ return OMX_ErrorNone;
+ }
+
case OMX_IndexParamAudioAac:
{
const OMX_AUDIO_PARAM_AACPROFILETYPE *aacParams =
diff --git a/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp b/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp
index 7553153..b7e84ec 100644
--- a/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp
+++ b/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp
@@ -143,6 +143,30 @@
OMX_ERRORTYPE SoftAMR::internalGetParameter(
OMX_INDEXTYPE index, OMX_PTR params) {
switch (index) {
+ case OMX_IndexParamAudioPortFormat:
+ {
+ OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams =
+ (OMX_AUDIO_PARAM_PORTFORMATTYPE *)params;
+
+ if (!isValidOMXParam(formatParams)) {
+ return OMX_ErrorBadParameter;
+ }
+
+ if (formatParams->nPortIndex > 1) {
+ return OMX_ErrorUndefined;
+ }
+
+ if (formatParams->nIndex > 0) {
+ return OMX_ErrorNoMore;
+ }
+
+ formatParams->eEncoding =
+ (formatParams->nPortIndex == 0)
+ ? OMX_AUDIO_CodingAMR : OMX_AUDIO_CodingPCM;
+
+ return OMX_ErrorNone;
+ }
+
case OMX_IndexParamAudioAmr:
{
OMX_AUDIO_PARAM_AMRTYPE *amrParams =
@@ -236,6 +260,29 @@
return OMX_ErrorNone;
}
+ case OMX_IndexParamAudioPortFormat:
+ {
+ const OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams =
+ (const OMX_AUDIO_PARAM_PORTFORMATTYPE *)params;
+
+ if (!isValidOMXParam(formatParams)) {
+ return OMX_ErrorBadParameter;
+ }
+
+ if (formatParams->nPortIndex > 1) {
+ return OMX_ErrorUndefined;
+ }
+
+ if ((formatParams->nPortIndex == 0
+ && formatParams->eEncoding != OMX_AUDIO_CodingAMR)
+ || (formatParams->nPortIndex == 1
+ && formatParams->eEncoding != OMX_AUDIO_CodingPCM)) {
+ return OMX_ErrorUndefined;
+ }
+
+ return OMX_ErrorNone;
+ }
+
case OMX_IndexParamAudioAmr:
{
const OMX_AUDIO_PARAM_AMRTYPE *aacParams =
diff --git a/media/libstagefright/codecs/flac/dec/SoftFlacDecoder.cpp b/media/libstagefright/codecs/flac/dec/SoftFlacDecoder.cpp
index f89688c..cff4a33 100644
--- a/media/libstagefright/codecs/flac/dec/SoftFlacDecoder.cpp
+++ b/media/libstagefright/codecs/flac/dec/SoftFlacDecoder.cpp
@@ -68,7 +68,7 @@
def.eDir = OMX_DirInput;
def.nBufferCountMin = kNumInputBuffers;
def.nBufferCountActual = def.nBufferCountMin;
- def.nBufferSize = 8192;
+ def.nBufferSize = 32768;
def.bEnabled = OMX_TRUE;
def.bPopulated = OMX_FALSE;
def.eDomain = OMX_PortDomainAudio;
diff --git a/media/libstagefright/codecs/g711/dec/SoftG711.cpp b/media/libstagefright/codecs/g711/dec/SoftG711.cpp
index f7c0429..7a4cca9 100644
--- a/media/libstagefright/codecs/g711/dec/SoftG711.cpp
+++ b/media/libstagefright/codecs/g711/dec/SoftG711.cpp
@@ -105,6 +105,30 @@
OMX_ERRORTYPE SoftG711::internalGetParameter(
OMX_INDEXTYPE index, OMX_PTR params) {
switch (index) {
+ case OMX_IndexParamAudioPortFormat:
+ {
+ OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams =
+ (OMX_AUDIO_PARAM_PORTFORMATTYPE *)params;
+
+ if (!isValidOMXParam(formatParams)) {
+ return OMX_ErrorBadParameter;
+ }
+
+ if (formatParams->nPortIndex > 1) {
+ return OMX_ErrorUndefined;
+ }
+
+ if (formatParams->nIndex > 0) {
+ return OMX_ErrorNoMore;
+ }
+
+ formatParams->eEncoding =
+ (formatParams->nPortIndex == 0)
+ ? OMX_AUDIO_CodingG711 : OMX_AUDIO_CodingPCM;
+
+ return OMX_ErrorNone;
+ }
+
case OMX_IndexParamAudioPcm:
{
OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
@@ -173,6 +197,29 @@
return OMX_ErrorNone;
}
+ case OMX_IndexParamAudioPortFormat:
+ {
+ const OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams =
+ (const OMX_AUDIO_PARAM_PORTFORMATTYPE *)params;
+
+ if (!isValidOMXParam(formatParams)) {
+ return OMX_ErrorBadParameter;
+ }
+
+ if (formatParams->nPortIndex > 1) {
+ return OMX_ErrorUndefined;
+ }
+
+ if ((formatParams->nPortIndex == 0
+ && formatParams->eEncoding != OMX_AUDIO_CodingG711)
+ || (formatParams->nPortIndex == 1
+ && formatParams->eEncoding != OMX_AUDIO_CodingPCM)) {
+ return OMX_ErrorUndefined;
+ }
+
+ return OMX_ErrorNone;
+ }
+
case OMX_IndexParamStandardComponentRole:
{
const OMX_PARAM_COMPONENTROLETYPE *roleParams =
diff --git a/media/libstagefright/codecs/gsm/dec/SoftGSM.cpp b/media/libstagefright/codecs/gsm/dec/SoftGSM.cpp
index 11999b4..d777229 100644
--- a/media/libstagefright/codecs/gsm/dec/SoftGSM.cpp
+++ b/media/libstagefright/codecs/gsm/dec/SoftGSM.cpp
@@ -105,6 +105,30 @@
OMX_ERRORTYPE SoftGSM::internalGetParameter(
OMX_INDEXTYPE index, OMX_PTR params) {
switch (index) {
+ case OMX_IndexParamAudioPortFormat:
+ {
+ OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams =
+ (OMX_AUDIO_PARAM_PORTFORMATTYPE *)params;
+
+ if (!isValidOMXParam(formatParams)) {
+ return OMX_ErrorBadParameter;
+ }
+
+ if (formatParams->nPortIndex > 1) {
+ return OMX_ErrorUndefined;
+ }
+
+ if (formatParams->nIndex > 0) {
+ return OMX_ErrorNoMore;
+ }
+
+ formatParams->eEncoding =
+ (formatParams->nPortIndex == 0)
+ ? OMX_AUDIO_CodingGSMFR : OMX_AUDIO_CodingPCM;
+
+ return OMX_ErrorNone;
+ }
+
case OMX_IndexParamAudioPcm:
{
OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
@@ -164,6 +188,29 @@
return OMX_ErrorNone;
}
+ case OMX_IndexParamAudioPortFormat:
+ {
+ const OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams =
+ (const OMX_AUDIO_PARAM_PORTFORMATTYPE *)params;
+
+ if (!isValidOMXParam(formatParams)) {
+ return OMX_ErrorBadParameter;
+ }
+
+ if (formatParams->nPortIndex > 1) {
+ return OMX_ErrorUndefined;
+ }
+
+ if ((formatParams->nPortIndex == 0
+ && formatParams->eEncoding != OMX_AUDIO_CodingGSMFR)
+ || (formatParams->nPortIndex == 1
+ && formatParams->eEncoding != OMX_AUDIO_CodingPCM)) {
+ return OMX_ErrorUndefined;
+ }
+
+ return OMX_ErrorNone;
+ }
+
case OMX_IndexParamStandardComponentRole:
{
const OMX_PARAM_COMPONENTROLETYPE *roleParams =
diff --git a/media/libstagefright/codecs/mp3dec/SoftMP3.cpp b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp
index 3def1f0..2364684 100644
--- a/media/libstagefright/codecs/mp3dec/SoftMP3.cpp
+++ b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp
@@ -134,6 +134,30 @@
OMX_ERRORTYPE SoftMP3::internalGetParameter(
OMX_INDEXTYPE index, OMX_PTR params) {
switch (index) {
+ case OMX_IndexParamAudioPortFormat:
+ {
+ OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams =
+ (OMX_AUDIO_PARAM_PORTFORMATTYPE *)params;
+
+ if (!isValidOMXParam(formatParams)) {
+ return OMX_ErrorBadParameter;
+ }
+
+ if (formatParams->nPortIndex > 1) {
+ return OMX_ErrorUndefined;
+ }
+
+ if (formatParams->nIndex > 0) {
+ return OMX_ErrorNoMore;
+ }
+
+ formatParams->eEncoding =
+ (formatParams->nPortIndex == 0)
+ ? OMX_AUDIO_CodingMP3 : OMX_AUDIO_CodingPCM;
+
+ return OMX_ErrorNone;
+ }
+
case OMX_IndexParamAudioPcm:
{
OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
@@ -208,6 +232,29 @@
return OMX_ErrorNone;
}
+ case OMX_IndexParamAudioPortFormat:
+ {
+ const OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams =
+ (const OMX_AUDIO_PARAM_PORTFORMATTYPE *)params;
+
+ if (!isValidOMXParam(formatParams)) {
+ return OMX_ErrorBadParameter;
+ }
+
+ if (formatParams->nPortIndex > 1) {
+ return OMX_ErrorUndefined;
+ }
+
+ if ((formatParams->nPortIndex == 0
+ && formatParams->eEncoding != OMX_AUDIO_CodingMP3)
+ || (formatParams->nPortIndex == 1
+ && formatParams->eEncoding != OMX_AUDIO_CodingPCM)) {
+ return OMX_ErrorUndefined;
+ }
+
+ return OMX_ErrorNone;
+ }
+
case OMX_IndexParamAudioPcm:
{
const OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
diff --git a/media/libstagefright/codecs/opus/dec/SoftOpus.cpp b/media/libstagefright/codecs/opus/dec/SoftOpus.cpp
index 2ac6ce0..d1f5e59 100644
--- a/media/libstagefright/codecs/opus/dec/SoftOpus.cpp
+++ b/media/libstagefright/codecs/opus/dec/SoftOpus.cpp
@@ -129,6 +129,31 @@
OMX_ERRORTYPE SoftOpus::internalGetParameter(
OMX_INDEXTYPE index, OMX_PTR params) {
switch ((int)index) {
+ case OMX_IndexParamAudioPortFormat:
+ {
+ OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams =
+ (OMX_AUDIO_PARAM_PORTFORMATTYPE *)params;
+
+ if (!isValidOMXParam(formatParams)) {
+ return OMX_ErrorBadParameter;
+ }
+
+ if (formatParams->nPortIndex > 1) {
+ return OMX_ErrorUndefined;
+ }
+
+ if (formatParams->nIndex > 0) {
+ return OMX_ErrorNoMore;
+ }
+
+ formatParams->eEncoding =
+ (formatParams->nPortIndex == 0)
+ ? (OMX_AUDIO_CODINGTYPE)OMX_AUDIO_CodingAndroidOPUS :
+ OMX_AUDIO_CodingPCM;
+
+ return OMX_ErrorNone;
+ }
+
case OMX_IndexParamAudioAndroidOpus:
{
OMX_AUDIO_PARAM_ANDROID_OPUSTYPE *opusParams =
@@ -212,6 +237,30 @@
return OMX_ErrorNone;
}
+ case OMX_IndexParamAudioPortFormat:
+ {
+ const OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams =
+ (const OMX_AUDIO_PARAM_PORTFORMATTYPE *)params;
+
+ if (!isValidOMXParam(formatParams)) {
+ return OMX_ErrorBadParameter;
+ }
+
+ if (formatParams->nPortIndex > 1) {
+ return OMX_ErrorUndefined;
+ }
+
+ if ((formatParams->nPortIndex == 0
+ && formatParams->eEncoding !=
+ (OMX_AUDIO_CODINGTYPE)OMX_AUDIO_CodingAndroidOPUS)
+ || (formatParams->nPortIndex == 1
+ && formatParams->eEncoding != OMX_AUDIO_CodingPCM)) {
+ return OMX_ErrorUndefined;
+ }
+
+ return OMX_ErrorNone;
+ }
+
case OMX_IndexParamAudioAndroidOpus:
{
const OMX_AUDIO_PARAM_ANDROID_OPUSTYPE *opusParams =
diff --git a/media/libstagefright/codecs/raw/SoftRaw.cpp b/media/libstagefright/codecs/raw/SoftRaw.cpp
index acb2b37..1a527b3 100644
--- a/media/libstagefright/codecs/raw/SoftRaw.cpp
+++ b/media/libstagefright/codecs/raw/SoftRaw.cpp
@@ -60,7 +60,7 @@
def.eDir = OMX_DirInput;
def.nBufferCountMin = kNumBuffers;
def.nBufferCountActual = def.nBufferCountMin;
- def.nBufferSize = 32 * 1024;
+ def.nBufferSize = 64 * 1024;
def.bEnabled = OMX_TRUE;
def.bPopulated = OMX_FALSE;
def.eDomain = OMX_PortDomainAudio;
@@ -78,7 +78,7 @@
def.eDir = OMX_DirOutput;
def.nBufferCountMin = kNumBuffers;
def.nBufferCountActual = def.nBufferCountMin;
- def.nBufferSize = 32 * 1024;
+ def.nBufferSize = 64 * 1024;
def.bEnabled = OMX_TRUE;
def.bPopulated = OMX_FALSE;
def.eDomain = OMX_PortDomainAudio;
@@ -100,6 +100,28 @@
OMX_ERRORTYPE SoftRaw::internalGetParameter(
OMX_INDEXTYPE index, OMX_PTR params) {
switch (index) {
+ case OMX_IndexParamAudioPortFormat:
+ {
+ OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams =
+ (OMX_AUDIO_PARAM_PORTFORMATTYPE *)params;
+
+ if (!isValidOMXParam(formatParams)) {
+ return OMX_ErrorBadParameter;
+ }
+
+ if (formatParams->nPortIndex > 1) {
+ return OMX_ErrorUndefined;
+ }
+
+ if (formatParams->nIndex > 0) {
+ return OMX_ErrorNoMore;
+ }
+
+ formatParams->eEncoding = OMX_AUDIO_CodingPCM;
+
+ return OMX_ErrorNone;
+ }
+
case OMX_IndexParamAudioPcm:
{
OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
@@ -153,6 +175,26 @@
return OMX_ErrorNone;
}
+ case OMX_IndexParamAudioPortFormat:
+ {
+ const OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams =
+ (const OMX_AUDIO_PARAM_PORTFORMATTYPE *)params;
+
+ if (!isValidOMXParam(formatParams)) {
+ return OMX_ErrorBadParameter;
+ }
+
+ if (formatParams->nPortIndex > 1) {
+ return OMX_ErrorUndefined;
+ }
+
+ if (formatParams->eEncoding != OMX_AUDIO_CodingPCM) {
+ return OMX_ErrorUndefined;
+ }
+
+ return OMX_ErrorNone;
+ }
+
case OMX_IndexParamAudioPcm:
{
const OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
diff --git a/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp b/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp
index 14dd250..96e01b6 100644
--- a/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp
+++ b/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp
@@ -129,6 +129,30 @@
OMX_ERRORTYPE SoftVorbis::internalGetParameter(
OMX_INDEXTYPE index, OMX_PTR params) {
switch (index) {
+ case OMX_IndexParamAudioPortFormat:
+ {
+ OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams =
+ (OMX_AUDIO_PARAM_PORTFORMATTYPE *)params;
+
+ if (!isValidOMXParam(formatParams)) {
+ return OMX_ErrorBadParameter;
+ }
+
+ if (formatParams->nPortIndex > 1) {
+ return OMX_ErrorUndefined;
+ }
+
+ if (formatParams->nIndex > 0) {
+ return OMX_ErrorNoMore;
+ }
+
+ formatParams->eEncoding =
+ (formatParams->nPortIndex == 0)
+ ? OMX_AUDIO_CodingVORBIS : OMX_AUDIO_CodingPCM;
+
+ return OMX_ErrorNone;
+ }
+
case OMX_IndexParamAudioVorbis:
{
OMX_AUDIO_PARAM_VORBISTYPE *vorbisParams =
@@ -221,6 +245,29 @@
return OMX_ErrorNone;
}
+ case OMX_IndexParamAudioPortFormat:
+ {
+ const OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams =
+ (const OMX_AUDIO_PARAM_PORTFORMATTYPE *)params;
+
+ if (!isValidOMXParam(formatParams)) {
+ return OMX_ErrorBadParameter;
+ }
+
+ if (formatParams->nPortIndex > 1) {
+ return OMX_ErrorUndefined;
+ }
+
+ if ((formatParams->nPortIndex == 0
+ && formatParams->eEncoding != OMX_AUDIO_CodingVORBIS)
+ || (formatParams->nPortIndex == 1
+ && formatParams->eEncoding != OMX_AUDIO_CodingPCM)) {
+ return OMX_ErrorUndefined;
+ }
+
+ return OMX_ErrorNone;
+ }
+
case OMX_IndexParamAudioVorbis:
{
const OMX_AUDIO_PARAM_VORBISTYPE *vorbisParams =
diff --git a/media/libstagefright/foundation/Android.bp b/media/libstagefright/foundation/Android.bp
index 91462c8..9108ce1 100644
--- a/media/libstagefright/foundation/Android.bp
+++ b/media/libstagefright/foundation/Android.bp
@@ -1,7 +1,12 @@
+cc_library_headers {
+ name: "libstagefright_foundation_headers",
+ export_include_dirs: ["include"],
+ vendor_available: true,
+}
+
cc_library_shared {
name: "libstagefright_foundation",
vendor_available: true,
-
include_dirs: [
"frameworks/av/include",
"frameworks/native/include",
@@ -11,12 +16,13 @@
"include/media/stagefright/foundation",
],
- export_include_dirs: [
- "include",
- ],
-
header_libs: [
"libhardware_headers",
+ "libstagefright_foundation_headers",
+ ],
+
+ export_header_lib_headers: [
+ "libstagefright_foundation_headers",
],
export_shared_lib_headers: [
diff --git a/media/libstagefright/include/ACodecBufferChannel.h b/media/libstagefright/include/ACodecBufferChannel.h
index 0da2e81..f253a52 100644
--- a/media/libstagefright/include/ACodecBufferChannel.h
+++ b/media/libstagefright/include/ACodecBufferChannel.h
@@ -30,6 +30,8 @@
namespace android {
+using hardware::hidl_memory;
+
/**
* BufferChannelBase implementation for ACodec.
*/
@@ -117,6 +119,7 @@
sp<MemoryDealer> mDealer;
sp<IMemory> mDecryptDestination;
int32_t mHeapSeqNum;
+ hidl_memory mHidlMemory;
// These should only be accessed via std::atomic_* functions.
//
diff --git a/media/libstagefright/include/MPEG2TSExtractor.h b/media/libstagefright/include/MPEG2TSExtractor.h
index 2a75298..ac93b5e 100644
--- a/media/libstagefright/include/MPEG2TSExtractor.h
+++ b/media/libstagefright/include/MPEG2TSExtractor.h
@@ -45,7 +45,7 @@
virtual sp<MetaData> getMetaData();
- virtual status_t setMediaCas(const sp<ICas> &cas) override;
+ virtual status_t setMediaCas(const HInterfaceToken &casToken) override;
virtual uint32_t flags() const;
virtual const char * name() { return "MPEG2TSExtractor"; }
diff --git a/media/libstagefright/include/media/stagefright/CodecBase.h b/media/libstagefright/include/media/stagefright/CodecBase.h
index 0dd77ba..6245ccb 100644
--- a/media/libstagefright/include/media/stagefright/CodecBase.h
+++ b/media/libstagefright/include/media/stagefright/CodecBase.h
@@ -24,27 +24,31 @@
#define STRINGIFY_ENUMS
-#include <media/ICrypto.h>
+#include <media/hardware/CryptoAPI.h>
+#include <media/hardware/HardwareAPI.h>
#include <media/IOMX.h>
#include <media/MediaCodecInfo.h>
-#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/foundation/AHandler.h>
#include <media/stagefright/foundation/ColorUtils.h>
-#include <media/hardware/HardwareAPI.h>
-
+#include <media/stagefright/MediaErrors.h>
+#include <system/graphics.h>
#include <utils/NativeHandle.h>
-#include <system/graphics.h>
-#include <android/media/IDescrambler.h>
-
namespace android {
-using namespace media;
class BufferChannelBase;
struct BufferProducerWrapper;
class MediaCodecBuffer;
struct PersistentSurface;
struct RenderedFrameInfo;
class Surface;
+struct ICrypto;
+namespace hardware {
+namespace cas {
+namespace native {
+namespace V1_0 {
+struct IDescrambler;
+}}}}
+using hardware::cas::native::V1_0::IDescrambler;
struct CodecBase : public AHandler, /* static */ ColorUtils {
/**
@@ -256,13 +260,9 @@
mCallback = std::move(callback);
}
- inline void setCrypto(const sp<ICrypto> &crypto) {
- mCrypto = crypto;
- }
+ void setCrypto(const sp<ICrypto> &crypto);
- inline void setDescrambler(const sp<IDescrambler> &descrambler) {
- mDescrambler = descrambler;
- }
+ void setDescrambler(const sp<IDescrambler> &descrambler);
/**
* Queue an input buffer into the buffer channel.
diff --git a/media/libstagefright/include/media/stagefright/MediaCodec.h b/media/libstagefright/include/media/stagefright/MediaCodec.h
index 4140266..209fe12 100644
--- a/media/libstagefright/include/media/stagefright/MediaCodec.h
+++ b/media/libstagefright/include/media/stagefright/MediaCodec.h
@@ -47,10 +47,13 @@
struct PersistentSurface;
class SoftwareRenderer;
class Surface;
-namespace media {
-class IDescrambler;
-};
-using namespace media;
+namespace hardware {
+namespace cas {
+namespace native {
+namespace V1_0 {
+struct IDescrambler;
+}}}}
+using hardware::cas::native::V1_0::IDescrambler;
struct MediaCodec : public AHandler {
enum ConfigureFlags {
diff --git a/media/libstagefright/include/media/stagefright/MediaErrors.h b/media/libstagefright/include/media/stagefright/MediaErrors.h
index 2e663ec..6a5c6b6 100644
--- a/media/libstagefright/include/media/stagefright/MediaErrors.h
+++ b/media/libstagefright/include/media/stagefright/MediaErrors.h
@@ -79,6 +79,26 @@
HEARTBEAT_ERROR_BASE = -3000,
ERROR_HEARTBEAT_TERMINATE_REQUESTED = HEARTBEAT_ERROR_BASE,
+ // CAS-related error codes
+ CAS_ERROR_BASE = -4000,
+
+ ERROR_CAS_UNKNOWN = CAS_ERROR_BASE,
+ ERROR_CAS_NO_LICENSE = CAS_ERROR_BASE - 1,
+ ERROR_CAS_LICENSE_EXPIRED = CAS_ERROR_BASE - 2,
+ ERROR_CAS_SESSION_NOT_OPENED = CAS_ERROR_BASE - 3,
+ ERROR_CAS_DECRYPT_UNIT_NOT_INITIALIZED = CAS_ERROR_BASE - 4,
+ ERROR_CAS_DECRYPT = CAS_ERROR_BASE - 5,
+ ERROR_CAS_CANNOT_HANDLE = CAS_ERROR_BASE - 6,
+ ERROR_CAS_TAMPER_DETECTED = CAS_ERROR_BASE - 7,
+ ERROR_CAS_NOT_PROVISIONED = CAS_ERROR_BASE - 8,
+ ERROR_CAS_DEVICE_REVOKED = CAS_ERROR_BASE - 9,
+ ERROR_CAS_RESOURCE_BUSY = CAS_ERROR_BASE - 10,
+ ERROR_CAS_INSUFFICIENT_OUTPUT_PROTECTION = CAS_ERROR_BASE - 11,
+ ERROR_CAS_LAST_USED_ERRORCODE = CAS_ERROR_BASE - 11,
+
+ ERROR_CAS_VENDOR_MAX = CAS_ERROR_BASE - 500,
+ ERROR_CAS_VENDOR_MIN = CAS_ERROR_BASE - 999,
+
// NDK Error codes
// frameworks/av/include/ndk/NdkMediaError.h
// from -10000 (0xFFFFD8F0 - 0xFFFFD8EC)
diff --git a/media/libstagefright/include/media/stagefright/MediaExtractor.h b/media/libstagefright/include/media/stagefright/MediaExtractor.h
index a856b2b..f12160b 100644
--- a/media/libstagefright/include/media/stagefright/MediaExtractor.h
+++ b/media/libstagefright/include/media/stagefright/MediaExtractor.h
@@ -23,10 +23,6 @@
#include <media/MediaAnalyticsItem.h>
namespace android {
-namespace media {
-class ICas;
-};
-using namespace media;
class DataSource;
struct MediaSource;
class MetaData;
@@ -70,7 +66,7 @@
}
virtual void setUID(uid_t /*uid*/) {
}
- virtual status_t setMediaCas(const sp<ICas>& /*cas*/) override {
+ virtual status_t setMediaCas(const HInterfaceToken &/*casToken*/) override {
return INVALID_OPERATION;
}
diff --git a/media/libstagefright/include/media/stagefright/NuMediaExtractor.h b/media/libstagefright/include/media/stagefright/NuMediaExtractor.h
index 3e3cc17..6a93bd5 100644
--- a/media/libstagefright/include/media/stagefright/NuMediaExtractor.h
+++ b/media/libstagefright/include/media/stagefright/NuMediaExtractor.h
@@ -28,10 +28,6 @@
#include <utils/Vector.h>
namespace android {
-namespace media {
-class ICas;
-}
-using namespace media;
struct ABuffer;
struct AMessage;
@@ -64,7 +60,7 @@
status_t setDataSource(const sp<DataSource> &datasource);
- status_t setMediaCas(const sp<ICas> &cas);
+ status_t setMediaCas(const HInterfaceToken &casToken);
size_t countTracks() const;
status_t getTrackFormat(size_t index, sp<AMessage> *format, uint32_t flags = 0) const;
@@ -115,7 +111,7 @@
sp<DataSource> mDataSource;
sp<IMediaExtractor> mImpl;
- sp<ICas> mCas;
+ HInterfaceToken mCasToken;
Vector<TrackInfo> mSelectedTracks;
int64_t mTotalBitrate; // in bits/sec
diff --git a/media/libstagefright/mpeg2ts/ATSParser.cpp b/media/libstagefright/mpeg2ts/ATSParser.cpp
index 31edb21..a256a4d 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.cpp
+++ b/media/libstagefright/mpeg2ts/ATSParser.cpp
@@ -23,8 +23,8 @@
#include "ESQueue.h"
#include "include/avc_utils.h"
-#include <android/media/IDescrambler.h>
-#include <binder/MemoryDealer.h>
+#include <android/hardware/cas/native/1.0/IDescrambler.h>
+#include <cutils/native_handle.h>
#include <media/stagefright/foundation/ABitReader.h>
#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/ADebug.h>
@@ -41,8 +41,12 @@
#include <inttypes.h>
namespace android {
-using binder::Status;
-using MediaDescrambler::DescrambleInfo;
+using hardware::hidl_handle;
+using hardware::hidl_memory;
+using hardware::hidl_string;
+using hardware::hidl_vec;
+using namespace hardware::cas::V1_0;
+using namespace hardware::cas::native::V1_0;
// I want the expression "y" evaluated even if verbose logging is off.
#define MY_LOGV(x, y) \
@@ -203,6 +207,7 @@
sp<AMessage> mSampleAesKeyItem;
sp<IMemory> mMem;
sp<MemoryDealer> mDealer;
+ hardware::cas::native::V1_0::SharedBuffer mDescramblerSrcBuffer;
sp<ABuffer> mDescrambledBuffer;
List<SubSampleInfo> mSubSamples;
sp<IDescrambler> mDescrambler;
@@ -235,7 +240,7 @@
// Ensure internal buffers can hold specified size, and will re-allocate
// as needed.
- void ensureBufferCapacity(size_t size);
+ bool ensureBufferCapacity(size_t size);
DISALLOW_EVIL_CONSTRUCTORS(Stream);
};
@@ -807,9 +812,9 @@
mQueue = NULL;
}
-void ATSParser::Stream::ensureBufferCapacity(size_t neededSize) {
+bool ATSParser::Stream::ensureBufferCapacity(size_t neededSize) {
if (mBuffer != NULL && mBuffer->capacity() >= neededSize) {
- return;
+ return true;
}
ALOGV("ensureBufferCapacity: current size %zu, new size %zu, scrambled %d",
@@ -837,6 +842,26 @@
mMem = newMem;
mDealer = newDealer;
mDescrambledBuffer = newScrambledBuffer;
+
+ ssize_t offset;
+ size_t size;
+ sp<IMemoryHeap> heap = newMem->getMemory(&offset, &size);
+ if (heap == NULL) {
+ return false;
+ }
+ native_handle_t* nativeHandle = native_handle_create(1, 0);
+ if (!nativeHandle) {
+ ALOGE("[stream %d] failed to create native handle", mElementaryPID);
+ return false;
+ }
+ nativeHandle->data[0] = heap->getHeapID();
+ mDescramblerSrcBuffer.heapBase = hidl_memory("ashmem",
+ hidl_handle(nativeHandle), heap->getSize());
+ mDescramblerSrcBuffer.offset = (uint64_t) offset;
+ mDescramblerSrcBuffer.size = (uint64_t) size;
+
+ ALOGD("[stream %d] created shared buffer for descrambling, offset %zd, size %zu",
+ mElementaryPID, offset, size);
} else {
// Align to multiples of 64K.
neededSize = (neededSize + 65535) & ~65535;
@@ -850,6 +875,7 @@
newBuffer->setRange(0, 0);
}
mBuffer = newBuffer;
+ return true;
}
status_t ATSParser::Stream::parse(
@@ -923,7 +949,9 @@
}
size_t neededSize = mBuffer->size() + payloadSizeBits / 8;
- ensureBufferCapacity(neededSize);
+ if (!ensureBufferCapacity(neededSize)) {
+ return NO_MEMORY;
+ }
memcpy(mBuffer->data() + mBuffer->size(), br->data(), payloadSizeBits / 8);
mBuffer->setRange(0, mBuffer->size() + payloadSizeBits / 8);
@@ -1365,47 +1393,59 @@
memcpy(mDescrambledBuffer->data(), mBuffer->data(), descrambleBytes);
mDescrambledBuffer->setRange(0, descrambleBytes);
- sp<ABuffer> subSamples = new ABuffer(
- sizeof(DescramblerPlugin::SubSample) * descrambleSubSamples);
-
- DescrambleInfo info;
- info.dstType = DescrambleInfo::kDestinationTypeVmPointer;
- info.scramblingControl = (DescramblerPlugin::ScramblingControl)sctrl;
- info.numSubSamples = descrambleSubSamples;
- info.subSamples = (DescramblerPlugin::SubSample *)subSamples->data();
- info.srcMem = mMem;
- info.srcOffset = 0;
- info.dstPtr = NULL; // in-place descrambling into srcMem
- info.dstOffset = 0;
+ hidl_vec<SubSample> subSamples;
+ subSamples.resize(descrambleSubSamples);
int32_t i = 0;
for (auto it = mSubSamples.begin();
it != mSubSamples.end() && i < descrambleSubSamples; it++, i++) {
if (it->transport_scrambling_mode != 0 || pesScramblingControl != 0) {
- info.subSamples[i].mNumBytesOfClearData = 0;
- info.subSamples[i].mNumBytesOfEncryptedData = it->subSampleSize;
+ subSamples[i].numBytesOfClearData = 0;
+ subSamples[i].numBytesOfEncryptedData = it->subSampleSize;
} else {
- info.subSamples[i].mNumBytesOfClearData = it->subSampleSize;
- info.subSamples[i].mNumBytesOfEncryptedData = 0;
+ subSamples[i].numBytesOfClearData = it->subSampleSize;
+ subSamples[i].numBytesOfEncryptedData = 0;
}
}
+
+ uint64_t srcOffset = 0, dstOffset = 0;
// If scrambled at PES-level, PES header should be skipped
if (pesScramblingControl != 0) {
- info.srcOffset = info.dstOffset = pesOffset;
- info.subSamples[0].mNumBytesOfEncryptedData -= pesOffset;
+ srcOffset = dstOffset = pesOffset;
+ subSamples[0].numBytesOfEncryptedData -= pesOffset;
}
- int32_t result;
- Status status = mDescrambler->descramble(info, &result);
+ Status status = Status::OK;
+ uint32_t bytesWritten = 0;
+ hidl_string detailedError;
- if (!status.isOk()) {
- ALOGE("[stream %d] descramble failed, exceptionCode=%d",
- mElementaryPID, status.exceptionCode());
+ DestinationBuffer dstBuffer;
+ dstBuffer.type = BufferType::SHARED_MEMORY;
+ dstBuffer.nonsecureMemory = mDescramblerSrcBuffer;
+
+ auto returnVoid = mDescrambler->descramble(
+ (ScramblingControl) sctrl,
+ subSamples,
+ mDescramblerSrcBuffer,
+ srcOffset,
+ dstBuffer,
+ dstOffset,
+ [&status, &bytesWritten, &detailedError] (
+ Status _status, uint32_t _bytesWritten,
+ const hidl_string& _detailedError) {
+ status = _status;
+ bytesWritten = _bytesWritten;
+ detailedError = _detailedError;
+ });
+
+ if (!returnVoid.isOk()) {
+ ALOGE("[stream %d] descramble failed, trans=%s",
+ mElementaryPID, returnVoid.description().c_str());
return UNKNOWN_ERROR;
}
ALOGV("[stream %d] descramble succeeded, %d bytes",
- mElementaryPID, result);
+ mElementaryPID, bytesWritten);
memcpy(mBuffer->data(), mDescrambledBuffer->data(), descrambleBytes);
}
diff --git a/media/libstagefright/mpeg2ts/ATSParser.h b/media/libstagefright/mpeg2ts/ATSParser.h
index 374e011..41c19cd 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.h
+++ b/media/libstagefright/mpeg2ts/ATSParser.h
@@ -29,11 +29,13 @@
#include <vector>
namespace android {
-namespace media {
-class ICas;
-class IDescrambler;
-};
-using namespace media;
+namespace hardware {
+namespace cas {
+namespace V1_0 {
+struct ICas;
+}}}
+using hardware::cas::V1_0::ICas;
+
class ABitReader;
struct ABuffer;
struct AnotherPacketSource;
diff --git a/media/libstagefright/mpeg2ts/Android.bp b/media/libstagefright/mpeg2ts/Android.bp
index 96eb5bf..21259c4 100644
--- a/media/libstagefright/mpeg2ts/Android.bp
+++ b/media/libstagefright/mpeg2ts/Android.bp
@@ -35,5 +35,8 @@
shared_libs: [
"libcrypto",
"libmedia",
+ "libhidlmemory",
+ "android.hardware.cas.native@1.0",
+ "android.hidl.memory@1.0",
],
}
diff --git a/media/libstagefright/mpeg2ts/CasManager.cpp b/media/libstagefright/mpeg2ts/CasManager.cpp
index 047b1b3..9ff4521 100644
--- a/media/libstagefright/mpeg2ts/CasManager.cpp
+++ b/media/libstagefright/mpeg2ts/CasManager.cpp
@@ -18,15 +18,19 @@
#define LOG_TAG "CasManager"
#include "CasManager.h"
-#include <android/media/ICas.h>
-#include <android/media/IDescrambler.h>
-#include <android/media/IMediaCasService.h>
-#include <binder/IServiceManager.h>
+#include <android/hardware/cas/1.0/ICas.h>
+#include <android/hardware/cas/1.0/IMediaCasService.h>
+#include <android/hardware/cas/native/1.0/IDescrambler.h>
+#include <hidl/HidlSupport.h>
#include <media/stagefright/foundation/ABitReader.h>
#include <utils/Log.h>
namespace android {
-using binder::Status;
+
+using hardware::hidl_vec;
+using hardware::Return;
+using namespace hardware::cas::V1_0;
+using namespace hardware::cas::native::V1_0;
struct ATSParser::CasManager::ProgramCasManager : public RefBase {
ProgramCasManager(unsigned programNumber, const CADescriptor &descriptor);
@@ -125,45 +129,60 @@
const sp<ICas>& cas,
PidToSessionMap &sessionMap,
CasSession *session) {
- sp<IServiceManager> sm = defaultServiceManager();
- sp<IBinder> casServiceBinder = sm->getService(String16("media.cas"));
- sp<IMediaCasService> casService =
- interface_cast<IMediaCasService>(casServiceBinder);
-
+ sp<IMediaCasService> casService = IMediaCasService::getService("default");
if (casService == NULL) {
ALOGE("Cannot obtain IMediaCasService");
return NO_INIT;
}
+ Status status;
sp<IDescrambler> descrambler;
+ sp<IDescramblerBase> descramblerBase;
+ Return<Status> returnStatus(Status::OK);
+ Return<sp<IDescramblerBase> > returnDescrambler(NULL);
std::vector<uint8_t> sessionId;
const CADescriptor &descriptor = session->mCADescriptor;
- Status status = cas->openSession(&sessionId);
- if (!status.isOk()) {
- ALOGE("Failed to open session: exception=%d, error=%d",
- status.exceptionCode(), status.serviceSpecificErrorCode());
+ auto returnVoid = cas->openSession(
+ [&status, &sessionId] (Status _status, const hidl_vec<uint8_t>& _sessionId) {
+ status = _status;
+ sessionId = _sessionId;
+ });
+ if (!returnVoid.isOk() || status != Status::OK) {
+ ALOGE("Failed to open session: trans=%s, status=%d",
+ returnVoid.description().c_str(), status);
goto l_fail;
}
- cas->setSessionPrivateData(sessionId, descriptor.mPrivateData);
- if (!status.isOk()) {
- ALOGE("Failed to set private data: exception=%d, error=%d",
- status.exceptionCode(), status.serviceSpecificErrorCode());
+ returnStatus = cas->setSessionPrivateData(sessionId, descriptor.mPrivateData);
+ if (!returnStatus.isOk() || returnStatus != Status::OK) {
+ ALOGE("Failed to set private data: trans=%s, status=%d",
+ returnStatus.description().c_str(), (Status)returnStatus);
goto l_fail;
}
- status = casService->createDescrambler(descriptor.mSystemID, &descrambler);
- if (!status.isOk() || descrambler == NULL) {
- ALOGE("Failed to create descrambler: : exception=%d, error=%d",
- status.exceptionCode(), status.serviceSpecificErrorCode());
+ returnDescrambler = casService->createDescrambler(descriptor.mSystemID);
+ if (!returnDescrambler.isOk()) {
+ ALOGE("Failed to create descrambler: trans=%s",
+ returnDescrambler.description().c_str());
+ goto l_fail;
+ }
+ descramblerBase = (sp<IDescramblerBase>) returnDescrambler;
+ if (descramblerBase == NULL) {
+ ALOGE("Failed to create descrambler: null ptr");
goto l_fail;
}
- status = descrambler->setMediaCasSession(sessionId);
- if (!status.isOk()) {
- ALOGE("Failed to init descrambler: : exception=%d, error=%d",
- status.exceptionCode(), status.serviceSpecificErrorCode());
+ returnStatus = descramblerBase->setMediaCasSession(sessionId);
+ if (!returnStatus.isOk() || (Status) returnStatus != Status::OK) {
+ ALOGE("Failed to init descrambler: : trans=%s, status=%d",
+ returnStatus.description().c_str(), (Status) returnStatus);
+ goto l_fail;
+ }
+
+ descrambler = IDescrambler::castFrom(descramblerBase);
+ if (descrambler == NULL) {
+ ALOGE("Failed to cast from IDescramblerBase to IDescrambler");
goto l_fail;
}
@@ -177,8 +196,8 @@
if (!sessionId.empty()) {
cas->closeSession(sessionId);
}
- if (descrambler != NULL) {
- descrambler->release();
+ if (descramblerBase != NULL) {
+ descramblerBase->release();
}
return NO_INIT;
}
@@ -316,11 +335,12 @@
if (index < 0) {
return false;
}
- MediaCas::ParcelableCasData ecm(br->data(), br->numBitsLeft() / 8);
- Status status = mICas->processEcm(mCAPidToSessionIdMap[index], ecm);
- if (!status.isOk()) {
- ALOGE("Failed to process ECM: exception=%d, error=%d",
- status.exceptionCode(), status.serviceSpecificErrorCode());
+ hidl_vec<uint8_t> ecm;
+ ecm.setToExternal((uint8_t*)br->data(), br->numBitsLeft() / 8);
+ auto returnStatus = mICas->processEcm(mCAPidToSessionIdMap[index], ecm);
+ if (!returnStatus.isOk() || (Status) returnStatus != Status::OK) {
+ ALOGE("Failed to process ECM: trans=%s, status=%d",
+ returnStatus.description().c_str(), (Status) returnStatus);
}
return true; // handled
}
diff --git a/media/libstagefright/mpeg2ts/CasManager.h b/media/libstagefright/mpeg2ts/CasManager.h
index 8088dec..81f6546 100644
--- a/media/libstagefright/mpeg2ts/CasManager.h
+++ b/media/libstagefright/mpeg2ts/CasManager.h
@@ -21,10 +21,13 @@
#include <set>
namespace android {
-namespace media {
-class ICas;
-class IDescrambler;
-}
+namespace hardware {
+namespace cas {
+namespace native {
+namespace V1_0 {
+struct IDescrambler;
+}}}}
+using hardware::cas::native::V1_0::IDescrambler;
struct ATSParser::CasManager : public RefBase {
CasManager();
diff --git a/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp b/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp
index c3f1274..9d684e0 100644
--- a/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp
+++ b/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp
@@ -38,8 +38,13 @@
#include "AnotherPacketSource.h"
#include "ATSParser.h"
+#include <hidl/HybridInterface.h>
+#include <android/hardware/cas/1.0/ICas.h>
+
namespace android {
+using hardware::cas::V1_0::ICas;
+
static const size_t kTSPacketSize = 188;
static const int kMaxDurationReadSize = 250000LL;
static const int kMaxDurationRetry = 6;
@@ -156,7 +161,10 @@
|| !strcasecmp(MEDIA_MIMETYPE_AUDIO_SCRAMBLED, mime));
}
-status_t MPEG2TSExtractor::setMediaCas(const sp<ICas> &cas) {
+status_t MPEG2TSExtractor::setMediaCas(const HInterfaceToken &casToken) {
+ HalToken halToken;
+ halToken.setToExternal((uint8_t*)casToken.data(), casToken.size());
+ sp<ICas> cas = ICas::castFrom(retrieveHalInterface(halToken));
ALOGD("setMediaCas: %p", cas.get());
status_t err = mParser->setMediaCas(cas);
diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp
index 22d7d27..c6fa4ae 100644
--- a/media/libstagefright/omx/OMXNodeInstance.cpp
+++ b/media/libstagefright/omx/OMXNodeInstance.cpp
@@ -246,6 +246,15 @@
virtual ~CallbackDispatcher();
private:
+ enum {
+ // This is used for frame_rendered message batching, which will eventually end up in a
+ // single AMessage in MediaCodec when it is signaled to the app. AMessage can contain
+ // up-to 64 key-value pairs, and each frame_rendered message uses 2 keys, so the max
+ // value for this would be 32. Nonetheless, limit this to 12 to which gives at least 10
+ // mseconds of batching at 120Hz.
+ kMaxQueueSize = 12,
+ };
+
Mutex mLock;
sp<OMXNodeInstance> const mOwner;
@@ -290,7 +299,7 @@
Mutex::Autolock autoLock(mLock);
mQueue.push_back(msg);
- if (realTime) {
+ if (realTime || mQueue.size() >= kMaxQueueSize) {
mQueueChanged.signal();
}
}
@@ -2168,8 +2177,8 @@
msg.fenceFd = -1;
msg.u.render_data.timestamp = renderData[i].nMediaTimeUs;
msg.u.render_data.nanoTime = renderData[i].nSystemTimeNs;
-
- instance->mDispatcher->post(msg, false /* realTime */);
+ bool realTime = msg.u.render_data.timestamp == INT64_MAX;
+ instance->mDispatcher->post(msg, realTime);
}
return OMX_ErrorNone;
}
diff --git a/media/libstagefright/omx/SoftOMXPlugin.cpp b/media/libstagefright/omx/SoftOMXPlugin.cpp
index fccb12b..0bc65e1 100644
--- a/media/libstagefright/omx/SoftOMXPlugin.cpp
+++ b/media/libstagefright/omx/SoftOMXPlugin.cpp
@@ -85,7 +85,21 @@
libName.append(kComponents[i].mLibNameSuffix);
libName.append(".so");
- void *libHandle = dlopen(libName.c_str(), RTLD_NOW);
+ // RTLD_NODELETE means we keep the shared library around forever.
+ // this eliminates thrashing during sequences like loading soundpools.
+ // It also leaves the rest of the logic around the dlopen()/dlclose()
+ // calls in this file unchanged.
+ //
+ // Implications of the change:
+ // -- the codec process (where this happens) will have a slightly larger
+ // long-term memory footprint as it accumulates the loaded shared libraries.
+ // This is expected to be a small amount of memory.
+ // -- plugin codecs can no longer (and never should have) depend on a
+ // free reset of any static data as the library would have crossed
+ // a dlclose/dlopen cycle.
+ //
+
+ void *libHandle = dlopen(libName.c_str(), RTLD_NOW|RTLD_NODELETE);
if (libHandle == NULL) {
ALOGE("unable to dlopen %s: %s", libName.c_str(), dlerror());
diff --git a/radio/Android.bp b/radio/Android.bp
deleted file mode 100644
index 8e614f2..0000000
--- a/radio/Android.bp
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2014 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.
-
-cc_library_shared {
- name: "libradio",
-
- srcs: [
- "Radio.cpp",
- "IRadio.cpp",
- "IRadioClient.cpp",
- "IRadioService.cpp",
- ],
-
- shared_libs: [
- "libcutils",
- "libutils",
- "liblog",
- "libbinder",
- "libradio_metadata",
- ],
-
- cflags: [
- "-Werror",
- "-Wall",
- ],
-}
diff --git a/radio/IRadio.cpp b/radio/IRadio.cpp
deleted file mode 100644
index 72f3b68..0000000
--- a/radio/IRadio.cpp
+++ /dev/null
@@ -1,337 +0,0 @@
-/*
-**
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-#define LOG_TAG "IRadio"
-//#define LOG_NDEBUG 0
-#include <utils/Log.h>
-#include <utils/Errors.h>
-#include <binder/IMemory.h>
-#include <radio/IRadio.h>
-#include <radio/IRadioService.h>
-#include <radio/IRadioClient.h>
-#include <system/radio.h>
-#include <system/RadioMetadataWrapper.h>
-
-namespace android {
-
-enum {
- DETACH = IBinder::FIRST_CALL_TRANSACTION,
- SET_CONFIGURATION,
- GET_CONFIGURATION,
- SET_MUTE,
- GET_MUTE,
- SCAN,
- STEP,
- TUNE,
- CANCEL,
- GET_PROGRAM_INFORMATION,
- HAS_CONTROL
-};
-
-class BpRadio: public BpInterface<IRadio>
-{
-public:
- explicit BpRadio(const sp<IBinder>& impl)
- : BpInterface<IRadio>(impl)
- {
- }
-
- void detach()
- {
- ALOGV("detach");
- Parcel data, reply;
- data.writeInterfaceToken(IRadio::getInterfaceDescriptor());
- remote()->transact(DETACH, data, &reply);
- }
-
- virtual status_t setConfiguration(const struct radio_band_config *config)
- {
- Parcel data, reply;
- if (config == NULL) {
- return BAD_VALUE;
- }
- data.writeInterfaceToken(IRadio::getInterfaceDescriptor());
- data.write(config, sizeof(struct radio_band_config));
- status_t status = remote()->transact(SET_CONFIGURATION, data, &reply);
- if (status == NO_ERROR) {
- status = (status_t)reply.readInt32();
- }
- return status;
- }
-
- virtual status_t getConfiguration(struct radio_band_config *config)
- {
- Parcel data, reply;
- if (config == NULL) {
- return BAD_VALUE;
- }
- data.writeInterfaceToken(IRadio::getInterfaceDescriptor());
- status_t status = remote()->transact(GET_CONFIGURATION, data, &reply);
- if (status == NO_ERROR) {
- status = (status_t)reply.readInt32();
- if (status == NO_ERROR) {
- reply.read(config, sizeof(struct radio_band_config));
- }
- }
- return status;
- }
-
- virtual status_t setMute(bool mute)
- {
- Parcel data, reply;
- data.writeInterfaceToken(IRadio::getInterfaceDescriptor());
- data.writeInt32(mute ? 1 : 0);
- status_t status = remote()->transact(SET_MUTE, data, &reply);
- if (status == NO_ERROR) {
- status = (status_t)reply.readInt32();
- }
- return status;
- }
-
- virtual status_t getMute(bool *mute)
- {
- Parcel data, reply;
- if (mute == NULL) {
- return BAD_VALUE;
- }
- data.writeInterfaceToken(IRadio::getInterfaceDescriptor());
- status_t status = remote()->transact(GET_MUTE, data, &reply);
- if (status == NO_ERROR) {
- status = (status_t)reply.readInt32();
- if (status == NO_ERROR) {
- int32_t muteread = reply.readInt32();
- *mute = muteread != 0;
- }
- }
- return status;
- }
-
- virtual status_t scan(radio_direction_t direction, bool skipSubChannel)
- {
- Parcel data, reply;
- data.writeInterfaceToken(IRadio::getInterfaceDescriptor());
- data.writeInt32(direction);
- data.writeInt32(skipSubChannel ? 1 : 0);
- status_t status = remote()->transact(SCAN, data, &reply);
- if (status == NO_ERROR) {
- status = (status_t)reply.readInt32();
- }
- return status;
- }
-
- virtual status_t step(radio_direction_t direction, bool skipSubChannel)
- {
- Parcel data, reply;
- data.writeInterfaceToken(IRadio::getInterfaceDescriptor());
- data.writeInt32(direction);
- data.writeInt32(skipSubChannel ? 1 : 0);
- status_t status = remote()->transact(STEP, data, &reply);
- if (status == NO_ERROR) {
- status = (status_t)reply.readInt32();
- }
- return status;
- }
-
- virtual status_t tune(uint32_t channel, uint32_t subChannel)
- {
- Parcel data, reply;
- data.writeInterfaceToken(IRadio::getInterfaceDescriptor());
- data.writeUint32(channel);
- data.writeUint32(subChannel);
- status_t status = remote()->transact(TUNE, data, &reply);
- if (status == NO_ERROR) {
- status = (status_t)reply.readInt32();
- }
- return status;
- }
-
- virtual status_t cancel()
- {
- Parcel data, reply;
- data.writeInterfaceToken(IRadio::getInterfaceDescriptor());
- status_t status = remote()->transact(CANCEL, data, &reply);
- if (status == NO_ERROR) {
- status = (status_t)reply.readInt32();
- }
- return status;
- }
-
- virtual status_t getProgramInformation(struct radio_program_info *info)
- {
- Parcel data, reply;
- if (info == nullptr || info->metadata == nullptr) {
- return BAD_VALUE;
- }
- radio_metadata_t *metadata = info->metadata;
- data.writeInterfaceToken(IRadio::getInterfaceDescriptor());
- status_t status = remote()->transact(GET_PROGRAM_INFORMATION, data, &reply);
- if (status == NO_ERROR) {
- status = (status_t)reply.readInt32();
- if (status == NO_ERROR) {
- reply.read(info, sizeof(struct radio_program_info));
- // restore local metadata pointer
- info->metadata = metadata;
-
- uint32_t metadataSize = reply.readUint32();
- if (metadataSize != 0) {
- radio_metadata_t *newMetadata = (radio_metadata_t *)malloc(metadataSize);
- if (newMetadata == NULL) {
- return NO_MEMORY;
- }
- reply.read(newMetadata, metadataSize);
- status = radio_metadata_add_metadata(&info->metadata, newMetadata);
- free(newMetadata);
- }
- }
- }
- return status;
- }
-
- virtual status_t hasControl(bool *hasControl)
- {
- Parcel data, reply;
- if (hasControl == NULL) {
- return BAD_VALUE;
- }
- data.writeInterfaceToken(IRadio::getInterfaceDescriptor());
- status_t status = remote()->transact(HAS_CONTROL, data, &reply);
- if (status == NO_ERROR) {
- status = (status_t)reply.readInt32();
- if (status == NO_ERROR) {
- *hasControl = reply.readInt32() != 0;
- }
- }
- return status;
- }
-};
-
-IMPLEMENT_META_INTERFACE(Radio, "android.hardware.IRadio");
-
-// ----------------------------------------------------------------------
-
-status_t BnRadio::onTransact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
- switch(code) {
- case DETACH: {
- ALOGV("DETACH");
- CHECK_INTERFACE(IRadio, data, reply);
- detach();
- return NO_ERROR;
- } break;
- case SET_CONFIGURATION: {
- CHECK_INTERFACE(IRadio, data, reply);
- struct radio_band_config config;
- data.read(&config, sizeof(struct radio_band_config));
- status_t status = setConfiguration(&config);
- reply->writeInt32(status);
- return NO_ERROR;
- }
- case GET_CONFIGURATION: {
- CHECK_INTERFACE(IRadio, data, reply);
- struct radio_band_config config;
- status_t status = getConfiguration(&config);
- reply->writeInt32(status);
- if (status == NO_ERROR) {
- reply->write(&config, sizeof(struct radio_band_config));
- }
- return NO_ERROR;
- }
- case SET_MUTE: {
- CHECK_INTERFACE(IRadio, data, reply);
- bool mute = data.readInt32() != 0;
- status_t status = setMute(mute);
- reply->writeInt32(status);
- return NO_ERROR;
- }
- case GET_MUTE: {
- CHECK_INTERFACE(IRadio, data, reply);
- bool mute;
- status_t status = getMute(&mute);
- reply->writeInt32(status);
- if (status == NO_ERROR) {
- reply->writeInt32(mute ? 1 : 0);
- }
- return NO_ERROR;
- }
- case SCAN: {
- CHECK_INTERFACE(IRadio, data, reply);
- radio_direction_t direction = (radio_direction_t)data.readInt32();
- bool skipSubChannel = data.readInt32() == 1;
- status_t status = scan(direction, skipSubChannel);
- reply->writeInt32(status);
- return NO_ERROR;
- }
- case STEP: {
- CHECK_INTERFACE(IRadio, data, reply);
- radio_direction_t direction = (radio_direction_t)data.readInt32();
- bool skipSubChannel = data.readInt32() == 1;
- status_t status = step(direction, skipSubChannel);
- reply->writeInt32(status);
- return NO_ERROR;
- }
- case TUNE: {
- CHECK_INTERFACE(IRadio, data, reply);
- uint32_t channel = data.readUint32();
- uint32_t subChannel = data.readUint32();
- status_t status = tune(channel, subChannel);
- reply->writeInt32(status);
- return NO_ERROR;
- }
- case CANCEL: {
- CHECK_INTERFACE(IRadio, data, reply);
- status_t status = cancel();
- reply->writeInt32(status);
- return NO_ERROR;
- }
- case GET_PROGRAM_INFORMATION: {
- CHECK_INTERFACE(IRadio, data, reply);
- struct radio_program_info info;
- RadioMetadataWrapper metadataWrapper(&info.metadata);
-
- status_t status = getProgramInformation(&info);
- reply->writeInt32(status);
- if (status == NO_ERROR) {
- reply->write(&info, sizeof(struct radio_program_info));
- if (radio_metadata_get_count(info.metadata) > 0) {
- size_t size = radio_metadata_get_size(info.metadata);
- reply->writeUint32((uint32_t)size);
- reply->write(info.metadata, size);
- } else {
- reply->writeUint32(0);
- }
- }
- return NO_ERROR;
- }
- case HAS_CONTROL: {
- CHECK_INTERFACE(IRadio, data, reply);
- bool control;
- status_t status = hasControl(&control);
- reply->writeInt32(status);
- if (status == NO_ERROR) {
- reply->writeInt32(control ? 1 : 0);
- }
- return NO_ERROR;
- }
- default:
- return BBinder::onTransact(code, data, reply, flags);
- }
-}
-
-// ----------------------------------------------------------------------------
-
-}; // namespace android
diff --git a/radio/IRadioClient.cpp b/radio/IRadioClient.cpp
deleted file mode 100644
index ca21949..0000000
--- a/radio/IRadioClient.cpp
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
-**
-** Copyright 2015, 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 <stdint.h>
-#include <sys/types.h>
-#include <binder/IMemory.h>
-#include <binder/Parcel.h>
-#include <binder/IPCThreadState.h>
-#include <binder/IServiceManager.h>
-#include <radio/IRadioClient.h>
-
-namespace android {
-
-enum {
- ON_EVENT = IBinder::FIRST_CALL_TRANSACTION,
-};
-
-class BpRadioClient: public BpInterface<IRadioClient>
-{
-
-public:
- explicit BpRadioClient(const sp<IBinder>& impl)
- : BpInterface<IRadioClient>(impl)
- {
- }
-
- virtual void onEvent(const sp<IMemory>& eventMemory)
- {
- Parcel data, reply;
- data.writeInterfaceToken(IRadioClient::getInterfaceDescriptor());
- data.writeStrongBinder(IInterface::asBinder(eventMemory));
- remote()->transact(ON_EVENT,
- data,
- &reply);
- }
-};
-
-IMPLEMENT_META_INTERFACE(RadioClient,
- "android.hardware.IRadioClient");
-
-// ----------------------------------------------------------------------
-
-status_t BnRadioClient::onTransact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
- switch(code) {
- case ON_EVENT: {
- CHECK_INTERFACE(IRadioClient, data, reply);
- sp<IMemory> eventMemory = interface_cast<IMemory>(
- data.readStrongBinder());
- onEvent(eventMemory);
- return NO_ERROR;
- } break;
- default:
- return BBinder::onTransact(code, data, reply, flags);
- } return NO_ERROR;
-}
-
-// ----------------------------------------------------------------------------
-
-}; // namespace android
diff --git a/radio/IRadioService.cpp b/radio/IRadioService.cpp
deleted file mode 100644
index 72e3a61..0000000
--- a/radio/IRadioService.cpp
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
-**
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-#define LOG_TAG "BpRadioService"
-//#define LOG_NDEBUG 0
-
-#include <utils/Log.h>
-#include <utils/Errors.h>
-
-#include <stdint.h>
-#include <sys/types.h>
-#include <binder/IMemory.h>
-#include <binder/Parcel.h>
-#include <binder/IPCThreadState.h>
-#include <binder/IServiceManager.h>
-
-#include <radio/IRadioService.h>
-#include <radio/IRadio.h>
-#include <radio/IRadioClient.h>
-
-namespace android {
-
-enum {
- LIST_MODULES = IBinder::FIRST_CALL_TRANSACTION,
- ATTACH,
-};
-
-#define MAX_ITEMS_PER_LIST 1024
-
-class BpRadioService: public BpInterface<IRadioService>
-{
-public:
- explicit BpRadioService(const sp<IBinder>& impl)
- : BpInterface<IRadioService>(impl)
- {
- }
-
- virtual status_t listModules(struct radio_properties *properties,
- uint32_t *numModules)
- {
- if (numModules == NULL || (*numModules != 0 && properties == NULL)) {
- return BAD_VALUE;
- }
- Parcel data, reply;
- data.writeInterfaceToken(IRadioService::getInterfaceDescriptor());
- uint32_t numModulesReq = (properties == NULL) ? 0 : *numModules;
- data.writeInt32(numModulesReq);
- status_t status = remote()->transact(LIST_MODULES, data, &reply);
- if (status == NO_ERROR) {
- status = (status_t)reply.readInt32();
- *numModules = (uint32_t)reply.readInt32();
- }
- ALOGV("listModules() status %d got *numModules %d", status, *numModules);
- if (status == NO_ERROR) {
- if (numModulesReq > *numModules) {
- numModulesReq = *numModules;
- }
- if (numModulesReq > 0) {
- reply.read(properties, numModulesReq * sizeof(struct radio_properties));
- }
- }
- return status;
- }
-
- virtual status_t attach(radio_handle_t handle,
- const sp<IRadioClient>& client,
- const struct radio_band_config *config,
- bool withAudio,
- sp<IRadio>& radio)
- {
- Parcel data, reply;
- data.writeInterfaceToken(IRadioService::getInterfaceDescriptor());
- data.writeInt32(handle);
- data.writeStrongBinder(IInterface::asBinder(client));
- ALOGV("attach() config %p withAudio %d region %d type %d",
- config == NULL ? 0 : config, withAudio,
- config == NULL ? 0 : config->region,
- config == NULL ? 0 : config->band.type);
- if (config == NULL) {
- data.writeInt32(0);
- } else {
- data.writeInt32(1);
- data.write(config, sizeof(struct radio_band_config));
- }
- data.writeInt32(withAudio ? 1 : 0);
- status_t status = remote()->transact(ATTACH, data, &reply);
- if (status != NO_ERROR) {
- return status;
- }
- status = reply.readInt32();
- if (reply.readInt32() != 0) {
- radio = interface_cast<IRadio>(reply.readStrongBinder());
- }
- return status;
- }
-};
-
-IMPLEMENT_META_INTERFACE(RadioService, "android.hardware.IRadioService");
-
-// ----------------------------------------------------------------------
-
-status_t BnRadioService::onTransact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
- switch(code) {
- case LIST_MODULES: {
- CHECK_INTERFACE(IRadioService, data, reply);
- uint32_t numModulesReq = data.readInt32();
- if (numModulesReq > MAX_ITEMS_PER_LIST) {
- numModulesReq = MAX_ITEMS_PER_LIST;
- }
- uint32_t numModules = numModulesReq;
- struct radio_properties *properties =
- (struct radio_properties *)calloc(numModulesReq,
- sizeof(struct radio_properties));
- if (properties == NULL) {
- reply->writeInt32(NO_MEMORY);
- reply->writeInt32(0);
- return NO_ERROR;
- }
-
- status_t status = listModules(properties, &numModules);
- reply->writeInt32(status);
- reply->writeInt32(numModules);
- ALOGV("LIST_MODULES status %d got numModules %d", status, numModules);
-
- if (status == NO_ERROR) {
- if (numModulesReq > numModules) {
- numModulesReq = numModules;
- }
- reply->write(properties,
- numModulesReq * sizeof(struct radio_properties));
- }
- free(properties);
- return NO_ERROR;
- } break;
-
- case ATTACH: {
- CHECK_INTERFACE(IRadioService, data, reply);
- radio_handle_t handle = data.readInt32();
- sp<IRadioClient> client =
- interface_cast<IRadioClient>(data.readStrongBinder());
- struct radio_band_config config;
- struct radio_band_config *configPtr = NULL;
- if (data.readInt32() != 0) {
- data.read(&config, sizeof(struct radio_band_config));
- configPtr = &config;
- }
- bool withAudio = data.readInt32() != 0;
- ALOGV("ATTACH configPtr %p withAudio %d", configPtr, withAudio);
- sp<IRadio> radio;
- status_t status = attach(handle, client, configPtr, withAudio, radio);
- reply->writeInt32(status);
- if (radio != 0) {
- reply->writeInt32(1);
- reply->writeStrongBinder(IInterface::asBinder(radio));
- } else {
- reply->writeInt32(0);
- }
- return NO_ERROR;
- } break;
- default:
- return BBinder::onTransact(code, data, reply, flags);
- }
-}
-
-// ----------------------------------------------------------------------------
-
-}; // namespace android
diff --git a/radio/OWNERS b/radio/OWNERS
deleted file mode 100644
index 4b38a35..0000000
--- a/radio/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-elaurent@google.com
-twasilczyk@google.com
diff --git a/radio/Radio.cpp b/radio/Radio.cpp
deleted file mode 100644
index 9ddd221..0000000
--- a/radio/Radio.cpp
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
-**
-** Copyright (C) 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-#define LOG_TAG "Radio"
-//#define LOG_NDEBUG 0
-
-#include <utils/Log.h>
-#include <utils/threads.h>
-#include <binder/IPCThreadState.h>
-#include <binder/IServiceManager.h>
-#include <binder/IMemory.h>
-
-#include <radio/Radio.h>
-#include <radio/IRadio.h>
-#include <radio/IRadioService.h>
-#include <radio/IRadioClient.h>
-#include <radio/RadioCallback.h>
-
-namespace android {
-
-namespace {
- sp<IRadioService> gRadioService;
- const int kRadioServicePollDelay = 500000; // 0.5s
- const char* kRadioServiceName = "media.radio";
- Mutex gLock;
-
- class DeathNotifier : public IBinder::DeathRecipient
- {
- public:
- DeathNotifier() {
- }
-
- virtual void binderDied(const wp<IBinder>& who __unused) {
- ALOGV("binderDied");
- Mutex::Autolock _l(gLock);
- gRadioService.clear();
- ALOGW("Radio service died!");
- }
- };
-
- sp<DeathNotifier> gDeathNotifier;
-}; // namespace anonymous
-
-const sp<IRadioService> Radio::getRadioService()
-{
- Mutex::Autolock _l(gLock);
- if (gRadioService.get() == 0) {
- sp<IServiceManager> sm = defaultServiceManager();
- sp<IBinder> binder;
- do {
- binder = sm->getService(String16(kRadioServiceName));
- if (binder != 0) {
- break;
- }
- ALOGW("RadioService not published, waiting...");
- usleep(kRadioServicePollDelay);
- } while(true);
- if (gDeathNotifier == NULL) {
- gDeathNotifier = new DeathNotifier();
- }
- binder->linkToDeath(gDeathNotifier);
- gRadioService = interface_cast<IRadioService>(binder);
- }
- ALOGE_IF(gRadioService == 0, "no RadioService!?");
- return gRadioService;
-}
-
-// Static methods
-status_t Radio::listModules(struct radio_properties *properties,
- uint32_t *numModules)
-{
- ALOGV("listModules()");
- const sp<IRadioService> service = getRadioService();
- if (service == 0) {
- return NO_INIT;
- }
- return service->listModules(properties, numModules);
-}
-
-sp<Radio> Radio::attach(radio_handle_t handle,
- const struct radio_band_config *config,
- bool withAudio,
- const sp<RadioCallback>& callback)
-{
- ALOGV("attach()");
- sp<Radio> radio;
- const sp<IRadioService> service = getRadioService();
- if (service == 0) {
- return radio;
- }
- radio = new Radio(handle, callback);
- status_t status = service->attach(handle, radio, config, withAudio, radio->mIRadio);
-
- if (status == NO_ERROR && radio->mIRadio != 0) {
- IInterface::asBinder(radio->mIRadio)->linkToDeath(radio);
- } else {
- ALOGW("Error %d connecting to radio service", status);
- radio.clear();
- }
- return radio;
-}
-
-
-
-// Radio
-Radio::Radio(radio_handle_t /*handle*/, const sp<RadioCallback>& callback)
- : mCallback(callback)
-{
-}
-
-Radio::~Radio()
-{
- if (mIRadio != 0) {
- mIRadio->detach();
- }
-}
-
-
-void Radio::detach() {
- ALOGV("detach()");
- Mutex::Autolock _l(mLock);
- mCallback.clear();
- if (mIRadio != 0) {
- mIRadio->detach();
- IInterface::asBinder(mIRadio)->unlinkToDeath(this);
- mIRadio = 0;
- }
-}
-
-status_t Radio::setConfiguration(const struct radio_band_config *config)
-{
- Mutex::Autolock _l(mLock);
- if (mIRadio == 0) {
- return NO_INIT;
- }
- return mIRadio->setConfiguration(config);
-}
-
-status_t Radio::getConfiguration(struct radio_band_config *config)
-{
- Mutex::Autolock _l(mLock);
- if (mIRadio == 0) {
- return NO_INIT;
- }
- return mIRadio->getConfiguration(config);
-}
-
-status_t Radio::setMute(bool mute)
-{
- Mutex::Autolock _l(mLock);
- if (mIRadio == 0) {
- return NO_INIT;
- }
- return mIRadio->setMute(mute);
-}
-
-status_t Radio::getMute(bool *mute)
-{
- Mutex::Autolock _l(mLock);
- if (mIRadio == 0) {
- return NO_INIT;
- }
- return mIRadio->getMute(mute);
-}
-
-status_t Radio::scan(radio_direction_t direction, bool skipSubchannel)
-{
- Mutex::Autolock _l(mLock);
- if (mIRadio == 0) {
- return NO_INIT;
- }
- return mIRadio->scan(direction, skipSubchannel);
-}
-
-status_t Radio::step(radio_direction_t direction, bool skipSubchannel)
-{
- Mutex::Autolock _l(mLock);
- if (mIRadio == 0) {
- return NO_INIT;
- }
- return mIRadio->step(direction, skipSubchannel);
-}
-
-status_t Radio::tune(unsigned int channel, unsigned int subChannel)
-{
- Mutex::Autolock _l(mLock);
- if (mIRadio == 0) {
- return NO_INIT;
- }
- return mIRadio->tune(channel, subChannel);
-}
-
-status_t Radio::cancel()
-{
- Mutex::Autolock _l(mLock);
- if (mIRadio == 0) {
- return NO_INIT;
- }
- return mIRadio->cancel();
-}
-
-status_t Radio::getProgramInformation(struct radio_program_info *info)
-{
- Mutex::Autolock _l(mLock);
- if (mIRadio == 0) {
- return NO_INIT;
- }
- return mIRadio->getProgramInformation(info);
-}
-
-status_t Radio::hasControl(bool *hasControl)
-{
- Mutex::Autolock _l(mLock);
- if (mIRadio == 0) {
- return NO_INIT;
- }
- return mIRadio->hasControl(hasControl);
-}
-
-
-// BpRadioClient
-void Radio::onEvent(const sp<IMemory>& eventMemory)
-{
- Mutex::Autolock _l(mLock);
- if (eventMemory == 0 || eventMemory->pointer() == NULL) {
- return;
- }
-
- // The event layout in shared memory is:
- // sizeof(struct radio_event) bytes : the event itself
- // 4 bytes : metadata size or 0
- // N bytes : metadata if present
- struct radio_event *event = (struct radio_event *)eventMemory->pointer();
- uint32_t metadataOffset = sizeof(struct radio_event) + sizeof(uint32_t);
- uint32_t metadataSize = *(uint32_t *)((uint8_t *)event + metadataOffset - sizeof(uint32_t));
-
- // restore local metadata pointer from offset
- switch (event->type) {
- case RADIO_EVENT_TUNED:
- case RADIO_EVENT_AF_SWITCH:
- if (metadataSize != 0) {
- event->info.metadata =
- (radio_metadata_t *)((uint8_t *)event + metadataOffset);
- } else {
- event->info.metadata = 0;
- }
- break;
- case RADIO_EVENT_METADATA:
- if (metadataSize != 0) {
- event->metadata =
- (radio_metadata_t *)((uint8_t *)event + metadataOffset);
- } else {
- event->metadata = 0;
- }
- break;
- default:
- break;
- }
-
- if (mCallback != 0) {
- mCallback->onEvent(event);
- }
-}
-
-
-//IBinder::DeathRecipient
-void Radio::binderDied(const wp<IBinder>& who __unused) {
- Mutex::Autolock _l(mLock);
- ALOGW("Radio server binder Died ");
- mIRadio = 0;
- struct radio_event event;
- memset(&event, 0, sizeof(struct radio_event));
- event.type = RADIO_EVENT_SERVER_DIED;
- event.status = DEAD_OBJECT;
- if (mCallback != 0) {
- mCallback->onEvent(&event);
- }
-}
-
-}; // namespace android
diff --git a/services/audioflinger/FastMixer.cpp b/services/audioflinger/FastMixer.cpp
index c4f1af3..c10fa05 100644
--- a/services/audioflinger/FastMixer.cpp
+++ b/services/audioflinger/FastMixer.cpp
@@ -138,7 +138,8 @@
void FastMixer::onStateChange()
{
- LOG_HIST_FLUSH();
+ // log that audio was turned on/off
+ LOG_AUDIO_STATE();
const FastMixerState * const current = (const FastMixerState *) mCurrent;
const FastMixerState * const previous = (const FastMixerState *) mPrevious;
FastMixerDumpState * const dumpState = (FastMixerDumpState *) mDumpState;
diff --git a/services/audioflinger/MmapTracks.h b/services/audioflinger/MmapTracks.h
index 2a27dfd..366a164 100644
--- a/services/audioflinger/MmapTracks.h
+++ b/services/audioflinger/MmapTracks.h
@@ -28,6 +28,7 @@
audio_channel_mask_t channelMask,
audio_session_t sessionId,
uid_t uid,
+ pid_t pid,
audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE);
virtual ~MmapTrack();
@@ -39,7 +40,7 @@
virtual bool isFastTrack() const { return false; }
static void appendDumpHeader(String8& result);
- void dump(char* buffer, size_t size);
+ void appendDump(String8& result, bool active);
private:
friend class MmapThread;
@@ -55,5 +56,6 @@
virtual int64_t framesReleased() const;
virtual void onTimestamp(const ExtendedTimestamp ×tamp);
+ pid_t mPid;
}; // end of Track
diff --git a/services/audioflinger/OWNERS b/services/audioflinger/OWNERS
new file mode 100644
index 0000000..703e4d2
--- /dev/null
+++ b/services/audioflinger/OWNERS
@@ -0,0 +1,3 @@
+hunga@google.com
+jmtrivi@google.com
+mnaganov@google.com
diff --git a/services/audioflinger/PatchPanel.cpp b/services/audioflinger/PatchPanel.cpp
index d7c0728..27c6d35 100644
--- a/services/audioflinger/PatchPanel.cpp
+++ b/services/audioflinger/PatchPanel.cpp
@@ -474,6 +474,7 @@
format,
frameCount,
NULL,
+ (size_t)0 /* bufferSize */,
AUDIO_INPUT_FLAG_NONE);
if (patch->mPatchRecord == 0) {
return NO_MEMORY;
@@ -494,6 +495,7 @@
format,
frameCount,
patch->mPatchRecord->buffer(),
+ patch->mPatchRecord->bufferSize(),
AUDIO_OUTPUT_FLAG_NONE);
if (patch->mPatchTrack == 0) {
return NO_MEMORY;
diff --git a/services/audioflinger/PlaybackTracks.h b/services/audioflinger/PlaybackTracks.h
index 3f1a0c0..1c1a989 100644
--- a/services/audioflinger/PlaybackTracks.h
+++ b/services/audioflinger/PlaybackTracks.h
@@ -30,6 +30,7 @@
audio_channel_mask_t channelMask,
size_t frameCount,
void *buffer,
+ size_t bufferSize,
const sp<IMemory>& sharedBuffer,
audio_session_t sessionId,
uid_t uid,
@@ -40,7 +41,7 @@
virtual status_t initCheck() const;
static void appendDumpHeader(String8& result);
- void dump(char* buffer, size_t size, bool active);
+ void appendDump(String8& result, bool active);
virtual status_t start(AudioSystem::sync_event_t event =
AudioSystem::SYNC_EVENT_NONE,
audio_session_t triggerSession = AUDIO_SESSION_NONE);
@@ -240,6 +241,7 @@
audio_format_t format,
size_t frameCount,
void *buffer,
+ size_t bufferSize,
audio_output_flags_t flags);
virtual ~PatchTrack();
diff --git a/services/audioflinger/RecordTracks.h b/services/audioflinger/RecordTracks.h
index 3f83ca8..f8da780 100644
--- a/services/audioflinger/RecordTracks.h
+++ b/services/audioflinger/RecordTracks.h
@@ -29,6 +29,7 @@
audio_channel_mask_t channelMask,
size_t frameCount,
void *buffer,
+ size_t bufferSize,
audio_session_t sessionId,
uid_t uid,
audio_input_flags_t flags,
@@ -50,7 +51,7 @@
return tmp; }
static void appendDumpHeader(String8& result);
- void dump(char* buffer, size_t size, bool active);
+ void appendDump(String8& result, bool active);
void handleSyncStartEvent(const sp<SyncEvent>& event);
void clearSyncStartEvent();
@@ -102,6 +103,7 @@
audio_format_t format,
size_t frameCount,
void *buffer,
+ size_t bufferSize,
audio_input_flags_t flags);
virtual ~PatchRecord();
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index a67acd6..2a877e3 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -1543,6 +1543,7 @@
ALOGW("ActiveTracks<T>::add track %p already there", track.get());
return index;
}
+ logTrack("add", track);
mActiveTracksGeneration++;
mLatestActiveTrack = track;
++mBatteryCounter[track->uid()].second;
@@ -1556,6 +1557,7 @@
ALOGW("ActiveTracks<T>::remove nonexistent track %p", track.get());
return index;
}
+ logTrack("remove", track);
mActiveTracksGeneration++;
--mBatteryCounter[track->uid()].second;
// mLatestActiveTrack is not cleared even if is the same as track.
@@ -1566,6 +1568,7 @@
void AudioFlinger::ThreadBase::ActiveTracks<T>::clear() {
for (const sp<T> &track : mActiveTracks) {
BatteryNotifier::getInstance().noteStopAudio(track->uid());
+ logTrack("clear", track);
}
mLastActiveTracksGeneration = mActiveTracksGeneration;
mActiveTracks.clear();
@@ -1604,6 +1607,16 @@
}
}
+template <typename T>
+void AudioFlinger::ThreadBase::ActiveTracks<T>::logTrack(
+ const char *funcName, const sp<T> &track) const {
+ if (mLocalLog != nullptr) {
+ String8 result;
+ track->appendDump(result, false /* active */);
+ mLocalLog->log("AT::%-10s(%p) %s", funcName, track.get(), result.string());
+ }
+}
+
void AudioFlinger::ThreadBase::broadcast_l()
{
// Thread could be blocked waiting for async
@@ -1639,6 +1652,7 @@
mSuspended(0), mBytesWritten(0),
mFramesWritten(0),
mSuspendedFrames(0),
+ mActiveTracks(&this->mLocalLog),
// mStreamTypes[] initialized in constructor body
mOutput(output),
mLastWriteTime(-1), mNumWrites(0), mNumDelayedWrites(0), mInWrite(false),
@@ -1706,8 +1720,6 @@
void AudioFlinger::PlaybackThread::dumpTracks(int fd, const Vector<String16>& args __unused)
{
- const size_t SIZE = 256;
- char buffer[SIZE];
String8 result;
result.appendFormat(" Stream volumes in dB: ");
@@ -1734,8 +1746,10 @@
size_t numactive = mActiveTracks.size();
dprintf(fd, " %zu Tracks", numtracks);
size_t numactiveseen = 0;
+ const char *prefix = " ";
if (numtracks) {
dprintf(fd, " of which %zu are active\n", numactive);
+ result.append(prefix);
Track::appendDumpHeader(result);
for (size_t i = 0; i < numtracks; ++i) {
sp<Track> track = mTracks[i];
@@ -1744,8 +1758,8 @@
if (active) {
numactiveseen++;
}
- track->dump(buffer, SIZE, active);
- result.append(buffer);
+ result.append(prefix);
+ track->appendDump(result, active);
}
}
} else {
@@ -1753,15 +1767,15 @@
}
if (numactiveseen != numactive) {
// some tracks in the active list were not in the tracks list
- snprintf(buffer, SIZE, " The following tracks are in the active list but"
+ result.append(" The following tracks are in the active list but"
" not in the track list\n");
- result.append(buffer);
+ result.append(prefix);
Track::appendDumpHeader(result);
for (size_t i = 0; i < numactive; ++i) {
sp<Track> track = mActiveTracks[i];
if (mTracks.indexOf(track) < 0) {
- track->dump(buffer, SIZE, true);
- result.append(buffer);
+ result.append(prefix);
+ track->appendDump(result, true /* active */);
}
}
}
@@ -2012,7 +2026,8 @@
}
track = new Track(this, client, streamType, sampleRate, format,
- channelMask, frameCount, NULL, sharedBuffer,
+ channelMask, frameCount,
+ nullptr /* buffer */, (size_t)0 /* bufferSize */, sharedBuffer,
sessionId, uid, *flags, TrackBase::TYPE_DEFAULT, portId);
lStatus = track != 0 ? track->initCheck() : (status_t) NO_MEMORY;
@@ -2171,10 +2186,6 @@
chain->incActiveTrackCnt();
}
- char buffer[256];
- track->dump(buffer, arraysize(buffer), false /* active */);
- mLocalLog.log("addTrack_l (%p) %s", track.get(), buffer + 4); // log for analysis
-
status = NO_ERROR;
}
@@ -2201,9 +2212,9 @@
{
track->triggerEvents(AudioSystem::SYNC_EVENT_PRESENTATION_COMPLETE);
- char buffer[256];
- track->dump(buffer, arraysize(buffer), false /* active */);
- mLocalLog.log("removeTrack_l (%p) %s", track.get(), buffer + 4); // log for analysis
+ String8 result;
+ track->appendDump(result, false /* active */);
+ mLocalLog.log("removeTrack_l (%p) %s", track.get(), result.string());
mTracks.remove(track);
deleteTrackName_l(track->name());
@@ -3403,10 +3414,6 @@
}
if (track->isTerminated()) {
removeTrack_l(track);
- } else { // inactive but not terminated
- char buffer[256];
- track->dump(buffer, arraysize(buffer), false /* active */);
- mLocalLog.log("removeTracks_l(%p) %s", track.get(), buffer + 4);
}
}
}
@@ -5924,7 +5931,9 @@
#endif
) :
ThreadBase(audioFlinger, id, outDevice, inDevice, RECORD, systemReady),
- mInput(input), mRsmpInBuffer(NULL),
+ mInput(input),
+ mActiveTracks(&this->mLocalLog),
+ mRsmpInBuffer(NULL),
// mRsmpInFrames, mRsmpInFramesP2, and mRsmpInFramesOA are set by readInputParameters_l()
mRsmpInRear(0)
#ifdef TEE_SINK
@@ -6695,7 +6704,8 @@
Mutex::Autolock _l(mLock);
track = new RecordTrack(this, client, sampleRate,
- format, channelMask, frameCount, NULL, sessionId, uid,
+ format, channelMask, frameCount,
+ nullptr /* buffer */, (size_t)0 /* bufferSize */, sessionId, uid,
*flags, TrackBase::TYPE_DEFAULT, portId);
lStatus = track->initCheck();
@@ -6887,6 +6897,10 @@
void AudioFlinger::RecordThread::removeTrack_l(const sp<RecordTrack>& track)
{
+ String8 result;
+ track->appendDump(result, false /* active */);
+ mLocalLog.log("removeTrack_l (%p) %s", track.get(), result.string());
+
mTracks.remove(track);
// need anything related to effects here?
if (track->isFastTrack()) {
@@ -6900,6 +6914,8 @@
dumpInternals(fd, args);
dumpTracks(fd, args);
dumpEffectChains(fd, args);
+ dprintf(fd, " Local log:\n");
+ mLocalLog.dump(fd, " " /* prefix */, 40 /* lines */);
}
void AudioFlinger::RecordThread::dumpInternals(int fd, const Vector<String16>& args)
@@ -6913,6 +6929,12 @@
if (mActiveTracks.size() == 0) {
dprintf(fd, " No active record clients\n");
}
+
+ if (input != nullptr) {
+ dprintf(fd, " Hal stream dump:\n");
+ (void)input->stream->dump(fd);
+ }
+
dprintf(fd, " Fast capture thread: %s\n", hasFastCapture() ? "yes" : "no");
dprintf(fd, " Fast track available: %s\n", mFastTrackAvail ? "yes" : "no");
@@ -6927,16 +6949,15 @@
void AudioFlinger::RecordThread::dumpTracks(int fd, const Vector<String16>& args __unused)
{
- const size_t SIZE = 256;
- char buffer[SIZE];
String8 result;
-
size_t numtracks = mTracks.size();
size_t numactive = mActiveTracks.size();
size_t numactiveseen = 0;
dprintf(fd, " %zu Tracks", numtracks);
+ const char *prefix = " ";
if (numtracks) {
dprintf(fd, " of which %zu are active\n", numactive);
+ result.append(prefix);
RecordTrack::appendDumpHeader(result);
for (size_t i = 0; i < numtracks ; ++i) {
sp<RecordTrack> track = mTracks[i];
@@ -6945,8 +6966,8 @@
if (active) {
numactiveseen++;
}
- track->dump(buffer, SIZE, active);
- result.append(buffer);
+ result.append(prefix);
+ track->appendDump(result, active);
}
}
} else {
@@ -6954,15 +6975,15 @@
}
if (numactiveseen != numactive) {
- snprintf(buffer, SIZE, " The following tracks are in the active list but"
+ result.append(" The following tracks are in the active list but"
" not in the track list\n");
- result.append(buffer);
+ result.append(prefix);
RecordTrack::appendDumpHeader(result);
for (size_t i = 0; i < numactive; ++i) {
sp<RecordTrack> track = mActiveTracks[i];
if (mTracks.indexOf(track) < 0) {
- track->dump(buffer, SIZE, true);
- result.append(buffer);
+ result.append(prefix);
+ track->appendDump(result, true /* active */);
}
}
@@ -7544,7 +7565,8 @@
AudioHwDevice *hwDev, sp<StreamHalInterface> stream,
audio_devices_t outDevice, audio_devices_t inDevice, bool systemReady)
: ThreadBase(audioFlinger, id, outDevice, inDevice, MMAP, systemReady),
- mHalStream(stream), mHalDevice(hwDev->hwDevice()), mAudioHwDev(hwDev)
+ mHalStream(stream), mHalDevice(hwDev->hwDevice()), mAudioHwDev(hwDev),
+ mActiveTracks(&this->mLocalLog)
{
mStandby = true;
readHalParameters_l();
@@ -7692,7 +7714,7 @@
}
sp<MmapTrack> track = new MmapTrack(this, mSampleRate, mFormat, mChannelMask, mSessionId,
- client.clientUid, portId);
+ client.clientUid, client.clientPid, portId);
mActiveTracks.add(track);
sp<EffectChain> chain = getEffectChain_l(mSessionId);
@@ -8160,6 +8182,8 @@
dumpInternals(fd, args);
dumpTracks(fd, args);
dumpEffectChains(fd, args);
+ dprintf(fd, " Local log:\n");
+ mLocalLog.dump(fd, " " /* prefix */, 40 /* lines */);
}
void AudioFlinger::MmapThread::dumpInternals(int fd, const Vector<String16>& args)
@@ -8176,18 +8200,17 @@
void AudioFlinger::MmapThread::dumpTracks(int fd, const Vector<String16>& args __unused)
{
- const size_t SIZE = 256;
- char buffer[SIZE];
String8 result;
-
size_t numtracks = mActiveTracks.size();
- dprintf(fd, " %zu Tracks", numtracks);
+ dprintf(fd, " %zu Tracks\n", numtracks);
+ const char *prefix = " ";
if (numtracks) {
+ result.append(prefix);
MmapTrack::appendDumpHeader(result);
for (size_t i = 0; i < numtracks ; ++i) {
sp<MmapTrack> track = mActiveTracks[i];
- track->dump(buffer, SIZE);
- result.append(buffer);
+ result.append(prefix);
+ track->appendDump(result, true /* active */);
}
} else {
dprintf(fd, "\n");
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index 062bad6..32f2bc4 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -508,9 +508,10 @@
template <typename T>
class ActiveTracks {
public:
- ActiveTracks()
+ explicit ActiveTracks(SimpleLog *localLog = nullptr)
: mActiveTracksGeneration(0)
, mLastActiveTracksGeneration(0)
+ , mLocalLog(localLog)
{ }
~ActiveTracks() {
@@ -562,6 +563,8 @@
void updatePowerState(sp<ThreadBase> thread, bool force = false);
private:
+ void logTrack(const char *funcName, const sp<T> &track) const;
+
SortedVector<uid_t> getWakeLockUids() {
SortedVector<uid_t> wakeLockUids;
for (const sp<T> &track : mActiveTracks) {
@@ -576,6 +579,7 @@
int mActiveTracksGeneration;
int mLastActiveTracksGeneration;
wp<T> mLatestActiveTrack; // latest track added to ActiveTracks
+ SimpleLog * const mLocalLog;
};
SimpleLog mLocalLog;
diff --git a/services/audioflinger/TrackBase.h b/services/audioflinger/TrackBase.h
index cb540ca..d4ce0b4 100644
--- a/services/audioflinger/TrackBase.h
+++ b/services/audioflinger/TrackBase.h
@@ -61,6 +61,7 @@
audio_channel_mask_t channelMask,
size_t frameCount,
void *buffer,
+ size_t bufferSize,
audio_session_t sessionId,
uid_t uid,
bool isOut,
@@ -82,6 +83,7 @@
sp<IMemory> getBuffers() const { return mBufferMemory; }
void* buffer() const { return mBuffer; }
+ size_t bufferSize() const { return mBufferSize; }
virtual bool isFastTrack() const = 0;
bool isOutputTrack() const { return (mType == TYPE_OUTPUT); }
bool isPatchTrack() const { return (mType == TYPE_PATCH); }
@@ -133,6 +135,40 @@
mTerminated = true;
}
+ // Upper case characters are final states.
+ // Lower case characters are transitory.
+ const char *getTrackStateString() const {
+ if (isTerminated()) {
+ return "T ";
+ }
+ switch (mState) {
+ case IDLE:
+ return "I ";
+ case STOPPING_1: // for Fast and Offload
+ return "s1";
+ case STOPPING_2: // for Fast and Offload
+ return "s2";
+ case STOPPED:
+ return "S ";
+ case RESUMING:
+ return "r ";
+ case ACTIVE:
+ return "A ";
+ case PAUSING:
+ return "p ";
+ case PAUSED:
+ return "P ";
+ case FLUSHED:
+ return "F ";
+ case STARTING_1: // for RecordTrack
+ return "r1";
+ case STARTING_2: // for RecordTrack
+ return "r2";
+ default:
+ return "? ";
+ }
+ }
+
bool isOut() const { return mIsOut; }
// true for Track, false for RecordTrack,
// this could be a track type if needed later
@@ -144,6 +180,7 @@
sp<IMemory> mBufferMemory; // currently non-0 for fast RecordTrack only
void* mBuffer; // start of track buffer, typically in shared memory
// except for OutputTrack when it is in local memory
+ size_t mBufferSize; // size of mBuffer in bytes
// we don't really need a lock for these
track_state mState;
const uint32_t mSampleRate; // initial sample rate only; for tracks which
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index 9763bf2..0f25153 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -50,10 +50,6 @@
#define ALOGVV(a...) do { } while(0)
#endif
-// TODO move to a common header (Also shared with AudioTrack.cpp)
-#define NANOS_PER_SECOND 1000000000
-#define TIME_TO_NANOS(time) ((uint64_t)(time).tv_sec * NANOS_PER_SECOND + (time).tv_nsec)
-
namespace android {
// ----------------------------------------------------------------------------
@@ -71,6 +67,7 @@
audio_channel_mask_t channelMask,
size_t frameCount,
void *buffer,
+ size_t bufferSize,
audio_session_t sessionId,
uid_t clientUid,
bool isOut,
@@ -81,7 +78,7 @@
mThread(thread),
mClient(client),
mCblk(NULL),
- // mBuffer
+ // mBuffer, mBufferSize
mState(IDLE),
mSampleRate(sampleRate),
mFormat(format),
@@ -113,15 +110,22 @@
// ALOGD("Creating track with %d buffers @ %d bytes", bufferCount, bufferSize);
- size_t bufferSize = buffer == NULL ? roundup(frameCount) : frameCount;
+ size_t minBufferSize = buffer == NULL ? roundup(frameCount) : frameCount;
// check overflow when computing bufferSize due to multiplication by mFrameSize.
- if (bufferSize < frameCount // roundup rounds down for values above UINT_MAX / 2
+ if (minBufferSize < frameCount // roundup rounds down for values above UINT_MAX / 2
|| mFrameSize == 0 // format needs to be correct
- || bufferSize > SIZE_MAX / mFrameSize) {
+ || minBufferSize > SIZE_MAX / mFrameSize) {
android_errorWriteLog(0x534e4554, "34749571");
return;
}
- bufferSize *= mFrameSize;
+ minBufferSize *= mFrameSize;
+
+ if (buffer == nullptr) {
+ bufferSize = minBufferSize; // allocated here.
+ } else if (minBufferSize > bufferSize) {
+ android_errorWriteLog(0x534e4554, "38340117");
+ return;
+ }
size_t size = sizeof(audio_track_cblk_t);
if (buffer == NULL && alloc == ALLOC_CBLK) {
@@ -177,6 +181,7 @@
// It should references the buffer via the pipe.
// Therefore, to detect incorrect usage of the buffer, we set mBuffer to NULL.
mBuffer = NULL;
+ bufferSize = 0;
break;
case ALLOC_CBLK:
// clear all buffers
@@ -196,7 +201,10 @@
case ALLOC_NONE:
mBuffer = buffer;
break;
+ default:
+ LOG_ALWAYS_FATAL("invalid allocation type: %d", (int)alloc);
}
+ mBufferSize = bufferSize;
#ifdef TEE_SINK
if (mTeeSinkTrackEnabled) {
@@ -368,6 +376,7 @@
audio_channel_mask_t channelMask,
size_t frameCount,
void *buffer,
+ size_t bufferSize,
const sp<IMemory>& sharedBuffer,
audio_session_t sessionId,
uid_t uid,
@@ -376,6 +385,7 @@
audio_port_handle_t portId)
: TrackBase(thread, client, sampleRate, format, channelMask, frameCount,
(sharedBuffer != 0) ? sharedBuffer->pointer() : buffer,
+ (sharedBuffer != 0) ? sharedBuffer->size() : bufferSize,
sessionId, uid, true /*isOut*/,
(type == TYPE_PATCH) ? ( buffer == NULL ? ALLOC_LOCAL : ALLOC_NONE) : ALLOC_CBLK,
type, portId),
@@ -411,21 +421,6 @@
mAudioTrackServerProxy = new AudioTrackServerProxy(mCblk, mBuffer, frameCount,
mFrameSize, !isExternalTrack(), sampleRate);
} else {
- // Is the shared buffer of sufficient size?
- // (frameCount * mFrameSize) is <= SIZE_MAX, checked in TrackBase.
- if (sharedBuffer->size() < frameCount * mFrameSize) {
- // Workaround: clear out mCblk to indicate track hasn't been properly created.
- mCblk->~audio_track_cblk_t(); // destroy our shared-structure.
- if (mClient == 0) {
- free(mCblk);
- }
- mCblk = NULL;
-
- mSharedBuffer.clear(); // release shared buffer early
- android_errorWriteLog(0x534e4554, "38340117");
- return;
- }
-
mAudioTrackServerProxy = new StaticAudioTrackServerProxy(mCblk, mBuffer, frameCount,
mFrameSize);
}
@@ -503,58 +498,40 @@
/*static*/ void AudioFlinger::PlaybackThread::Track::appendDumpHeader(String8& result)
{
- result.append(" Name Active Client Type Fmt Chn mask Session fCount S F SRate "
- "L dB R dB VS dB Server Main buf Aux buf Flags UndFrmCnt Flushed\n");
+ result.append("T Name Active Client Session S Flags "
+ " Format Chn mask SRate "
+ "ST L dB R dB VS dB "
+ " Server FrmCnt FrmRdy F Underruns Flushed "
+ "Main Buf Aux Buf\n");
}
-void AudioFlinger::PlaybackThread::Track::dump(char* buffer, size_t size, bool active)
+void AudioFlinger::PlaybackThread::Track::appendDump(String8& result, bool active)
{
- gain_minifloat_packed_t vlr = mAudioTrackServerProxy->getVolumeLR();
- if (isFastTrack()) {
- sprintf(buffer, " F %2d", mFastIndex);
- } else if (mName >= AudioMixer::TRACK0) {
- sprintf(buffer, " %4d", mName - AudioMixer::TRACK0);
- } else {
- sprintf(buffer, " none");
- }
- track_state state = mState;
- char stateChar;
- if (isTerminated()) {
- stateChar = 'T';
- } else {
- switch (state) {
- case IDLE:
- stateChar = 'I';
- break;
- case STOPPING_1:
- stateChar = 's';
- break;
- case STOPPING_2:
- stateChar = '5';
- break;
- case STOPPED:
- stateChar = 'S';
- break;
- case RESUMING:
- stateChar = 'R';
- break;
- case ACTIVE:
- stateChar = 'A';
- break;
- case PAUSING:
- stateChar = 'p';
- break;
- case PAUSED:
- stateChar = 'P';
- break;
- case FLUSHED:
- stateChar = 'F';
- break;
- default:
- stateChar = '?';
- break;
+ char trackType;
+ switch (mType) {
+ case TYPE_DEFAULT:
+ case TYPE_OUTPUT:
+ if (mSharedBuffer.get() != nullptr) {
+ trackType = 'S'; // static
+ } else {
+ trackType = ' '; // normal
}
+ break;
+ case TYPE_PATCH:
+ trackType = 'P';
+ break;
+ default:
+ trackType = '?';
}
+
+ if (isFastTrack()) {
+ result.appendFormat("F%c %3d", trackType, mFastIndex);
+ } else if (mName >= AudioMixer::TRACK0) {
+ result.appendFormat("%c %4d", trackType, mName - AudioMixer::TRACK0);
+ } else {
+ result.appendFormat("%c none", trackType);
+ }
+
char nowInUnderrun;
switch (mObservedUnderruns.mBitFields.mMostRecent) {
case UNDERRUN_FULL:
@@ -571,31 +548,75 @@
break;
}
- std::pair<float /* volume */, bool /* active */> vsVolume = mVolumeHandler->getLastVolume();
- snprintf(&buffer[8], size - 8, " %6s %6u %4u %08X %08X %7u %6zu %1c %1d %5u "
- "%5.2g %5.2g %5.2g%c "
- "%08X %08zX %08zX 0x%03X %9u%c %7u\n",
+ char fillingStatus;
+ switch (mFillingUpStatus) {
+ case FS_INVALID:
+ fillingStatus = 'I';
+ break;
+ case FS_FILLING:
+ fillingStatus = 'f';
+ break;
+ case FS_FILLED:
+ fillingStatus = 'F';
+ break;
+ case FS_ACTIVE:
+ fillingStatus = 'A';
+ break;
+ default:
+ fillingStatus = '?';
+ break;
+ }
+
+ // clip framesReadySafe to max representation in dump
+ const size_t framesReadySafe =
+ std::min(mAudioTrackServerProxy->framesReadySafe(), (size_t)99999999);
+
+ // obtain volumes
+ const gain_minifloat_packed_t vlr = mAudioTrackServerProxy->getVolumeLR();
+ const std::pair<float /* volume */, bool /* active */> vsVolume =
+ mVolumeHandler->getLastVolume();
+
+ // Our effective frame count is obtained by ServerProxy::getBufferSizeInFrames()
+ // as it may be reduced by the application.
+ const size_t bufferSizeInFrames = (size_t)mAudioTrackServerProxy->getBufferSizeInFrames();
+ // Check whether the buffer size has been modified by the app.
+ const char modifiedBufferChar = bufferSizeInFrames < mFrameCount
+ ? 'r' /* buffer reduced */: bufferSizeInFrames > mFrameCount
+ ? 'e' /* error */ : ' ' /* identical */;
+
+ result.appendFormat("%7s %6u %7u %2s 0x%03X "
+ "%08X %08X %6u "
+ "%2u %5.2g %5.2g %5.2g%c "
+ "%08X %6zu%c %6zu %c %9u%c %7u "
+ "%08zX %08zX\n",
active ? "yes" : "no",
(mClient == 0) ? getpid_cached : mClient->pid(),
- mStreamType,
+ mSessionId,
+ getTrackStateString(),
+ mCblk->mFlags,
+
mFormat,
mChannelMask,
- mSessionId,
- mFrameCount,
- stateChar,
- mFillingUpStatus,
mAudioTrackServerProxy->getSampleRate(),
+
+ mStreamType,
20.0 * log10(float_from_gain(gain_minifloat_unpack_left(vlr))),
20.0 * log10(float_from_gain(gain_minifloat_unpack_right(vlr))),
20.0 * log10(vsVolume.first), // VolumeShaper(s) total volume
vsVolume.second ? 'A' : ' ', // if any VolumeShapers active
+
mCblk->mServer,
- (size_t)mMainBuffer, // use %zX as %p appends 0x
- (size_t)mAuxBuffer, // use %zX as %p appends 0x
- mCblk->mFlags,
+ bufferSizeInFrames,
+ modifiedBufferChar,
+ framesReadySafe,
+ fillingStatus,
mAudioTrackServerProxy->getUnderrunFrames(),
nowInUnderrun,
- (unsigned)mAudioTrackServerProxy->framesFlushed() % 10000000); // 7 digits
+ (unsigned)mAudioTrackServerProxy->framesFlushed() % 10000000,
+
+ (size_t)mMainBuffer, // use %zX as %p appends 0x
+ (size_t)mAuxBuffer // use %zX as %p appends 0x
+ );
}
uint32_t AudioFlinger::PlaybackThread::Track::sampleRate() const {
@@ -1235,7 +1256,8 @@
uid_t uid)
: Track(playbackThread, NULL, AUDIO_STREAM_PATCH,
sampleRate, format, channelMask, frameCount,
- NULL, 0, AUDIO_SESSION_NONE, uid, AUDIO_OUTPUT_FLAG_NONE,
+ nullptr /* buffer */, (size_t)0 /* bufferSize */, nullptr /* sharedBuffer */,
+ AUDIO_SESSION_NONE, uid, AUDIO_OUTPUT_FLAG_NONE,
TYPE_OUTPUT),
mActive(false), mSourceThread(sourceThread)
{
@@ -1351,7 +1373,9 @@
if (mBufferQueue.size()) {
mBufferQueue.removeAt(0);
free(pInBuffer->mBuffer);
- delete pInBuffer;
+ if (pInBuffer != &inBuffer) {
+ delete pInBuffer;
+ }
ALOGV("OutputTrack::write() %p thread %p released overflow buffer %zu", this,
mThread.unsafe_get(), mBufferQueue.size());
} else {
@@ -1430,10 +1454,12 @@
audio_format_t format,
size_t frameCount,
void *buffer,
+ size_t bufferSize,
audio_output_flags_t flags)
: Track(playbackThread, NULL, streamType,
sampleRate, format, channelMask, frameCount,
- buffer, 0, AUDIO_SESSION_NONE, getuid(), flags, TYPE_PATCH),
+ buffer, bufferSize, nullptr /* sharedBuffer */,
+ AUDIO_SESSION_NONE, getuid(), flags, TYPE_PATCH),
mProxy(new ClientProxy(mCblk, mBuffer, frameCount, mFrameSize, true, true))
{
uint64_t mixBufferNs = ((uint64_t)2 * playbackThread->frameCount() * 1000000000) /
@@ -1567,13 +1593,14 @@
audio_channel_mask_t channelMask,
size_t frameCount,
void *buffer,
+ size_t bufferSize,
audio_session_t sessionId,
uid_t uid,
audio_input_flags_t flags,
track_type type,
audio_port_handle_t portId)
: TrackBase(thread, client, sampleRate, format,
- channelMask, frameCount, buffer, sessionId, uid, false /*isOut*/,
+ channelMask, frameCount, buffer, bufferSize, sessionId, uid, false /*isOut*/,
(type == TYPE_DEFAULT) ?
((flags & AUDIO_INPUT_FLAG_FAST) ? ALLOC_PIPE : ALLOC_CBLK) :
((buffer == NULL) ? ALLOC_LOCAL : ALLOC_NONE),
@@ -1701,22 +1728,28 @@
/*static*/ void AudioFlinger::RecordThread::RecordTrack::appendDumpHeader(String8& result)
{
- result.append(" Active Client Fmt Chn mask Session S Server fCount SRate\n");
+ result.append("Active Client Session S Flags Format Chn mask SRate Server FrmCnt\n");
}
-void AudioFlinger::RecordThread::RecordTrack::dump(char* buffer, size_t size, bool active)
+void AudioFlinger::RecordThread::RecordTrack::appendDump(String8& result, bool active)
{
- snprintf(buffer, size, " %6s %6u %3u %08X %7u %1d %08X %6zu %5u\n",
+ result.appendFormat("%c%5s %6u %7u %2s 0x%03X "
+ "%08X %08X %6u "
+ "%08X %6zu\n",
+ isFastTrack() ? 'F' : ' ',
active ? "yes" : "no",
(mClient == 0) ? getpid_cached : mClient->pid(),
+ mSessionId,
+ getTrackStateString(),
+ mCblk->mFlags,
+
mFormat,
mChannelMask,
- mSessionId,
- mState,
- mCblk->mServer,
- mFrameCount,
- mSampleRate);
+ mSampleRate,
+ mCblk->mServer,
+ mFrameCount
+ );
}
void AudioFlinger::RecordThread::RecordTrack::handleSyncStartEvent(const sp<SyncEvent>& event)
@@ -1767,9 +1800,10 @@
audio_format_t format,
size_t frameCount,
void *buffer,
+ size_t bufferSize,
audio_input_flags_t flags)
: RecordTrack(recordThread, NULL, sampleRate, format, channelMask, frameCount,
- buffer, AUDIO_SESSION_NONE, getuid(), flags, TYPE_PATCH),
+ buffer, bufferSize, AUDIO_SESSION_NONE, getuid(), flags, TYPE_PATCH),
mProxy(new ClientProxy(mCblk, mBuffer, frameCount, mFrameSize, false, true))
{
uint64_t mixBufferNs = ((uint64_t)2 * recordThread->frameCount() * 1000000000) /
@@ -1834,11 +1868,15 @@
audio_channel_mask_t channelMask,
audio_session_t sessionId,
uid_t uid,
+ pid_t pid,
audio_port_handle_t portId)
: TrackBase(thread, NULL, sampleRate, format,
- channelMask, 0, NULL, sessionId, uid, false,
+ channelMask, (size_t)0 /* frameCount */,
+ nullptr /* buffer */, (size_t)0 /* bufferSize */,
+ sessionId, uid, false /* isOut */,
ALLOC_NONE,
- TYPE_DEFAULT, portId)
+ TYPE_DEFAULT, portId),
+ mPid(pid)
{
}
@@ -1885,17 +1923,17 @@
/*static*/ void AudioFlinger::MmapThread::MmapTrack::appendDumpHeader(String8& result)
{
- result.append(" Client Fmt Chn mask SRate\n");
+ result.append("Client Session Format Chn mask SRate\n");
}
-void AudioFlinger::MmapThread::MmapTrack::dump(char* buffer, size_t size)
+void AudioFlinger::MmapThread::MmapTrack::appendDump(String8& result, bool active __unused)
{
- snprintf(buffer, size, " %6u %3u %08X %5u\n",
- mUid,
+ result.appendFormat("%6u %7u %08X %08X %6u\n",
+ mPid,
+ mSessionId,
mFormat,
mChannelMask,
mSampleRate);
-
}
} // namespace android
diff --git a/services/audioflinger/TypedLogger.h b/services/audioflinger/TypedLogger.h
index 2d84028..909af09 100644
--- a/services/audioflinger/TypedLogger.h
+++ b/services/audioflinger/TypedLogger.h
@@ -88,11 +88,11 @@
// Write histogram timestamp entry
#define LOG_HIST_TS() do { NBLog::Writer *x = tlNBLogWriter; if (x != nullptr) \
- x->logHistTS(hash(__FILE__, __LINE__)); } while(0)
+ x->logEventHistTs(NBLog::EVENT_HISTOGRAM_ENTRY_TS, hash(__FILE__, __LINE__)); } while(0)
-// flush all histogram
-#define LOG_HIST_FLUSH() do { NBLog::Writer *x = tlNBLogWriter; if (x != nullptr) \
- x->logHistFlush(hash(__FILE__, __LINE__)); } while(0)
+// Record that audio was turned on/off
+#define LOG_AUDIO_STATE() do { NBLog::Writer *x = tlNBLogWriter; if (x != nullptr) \
+ x->logEventHistTs(NBLog::EVENT_AUDIO_STATE, hash(__FILE__, __LINE__)); } while(0)
namespace android {
extern "C" {
diff --git a/services/audiopolicy/Android.mk b/services/audiopolicy/Android.mk
index ad340e5..65571f9 100644
--- a/services/audiopolicy/Android.mk
+++ b/services/audiopolicy/Android.mk
@@ -24,7 +24,8 @@
libhardware_legacy \
libserviceutility \
libaudiopolicymanager \
- libmedia_helper
+ libmedia_helper \
+ libeffectsconfig
LOCAL_STATIC_LIBRARIES := \
libaudiopolicycomponents
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index c868206..7b19f58 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -349,8 +349,8 @@
virtual void onDynamicPolicyMixStateUpdate(String8 regId, int32_t state) = 0;
- virtual void onRecordingConfigurationUpdate(int event, audio_session_t session,
- audio_source_t source,
+ virtual void onRecordingConfigurationUpdate(int event,
+ const record_client_info_t *clientInfo,
const struct audio_config_base *clientConfig,
const struct audio_config_base *deviceConfig,
audio_patch_handle_t patchHandle) = 0;
diff --git a/services/audiopolicy/OWNERS b/services/audiopolicy/OWNERS
new file mode 100644
index 0000000..a8483fa
--- /dev/null
+++ b/services/audiopolicy/OWNERS
@@ -0,0 +1,3 @@
+jmtrivi@google.com
+krocard@google.com
+mnaganov@google.com
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioSession.h b/services/audiopolicy/common/managerdefinitions/include/AudioSession.h
index ca070cf..cedf22d 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioSession.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioSession.h
@@ -22,6 +22,7 @@
#include <utils/Errors.h>
#include <utils/KeyedVector.h>
#include <media/AudioPolicy.h>
+#include <media/IAudioPolicyServiceClient.h>
#include "AudioSessionInfoProvider.h"
namespace android {
@@ -44,14 +45,14 @@
status_t dump(int fd, int spaces, int index) const;
- audio_session_t session() const { return mSession; }
- audio_source_t inputSource()const { return mInputSource; }
+ audio_session_t session() const { return mRecordClientInfo.session; }
+ audio_source_t inputSource()const { return mRecordClientInfo.source; }
audio_format_t format() const { return mConfig.format; }
uint32_t sampleRate() const { return mConfig.sample_rate; }
audio_channel_mask_t channelMask() const { return mConfig.channel_mask; }
audio_input_flags_t flags() const { return mFlags; }
- uid_t uid() const { return mUid; }
- void setUid(uid_t uid) { mUid = uid; }
+ uid_t uid() const { return mRecordClientInfo.uid; }
+ void setUid(uid_t uid) { mRecordClientInfo.uid = uid; }
bool matches(const sp<AudioSession> &other) const;
bool isSoundTrigger() const { return mIsSoundTrigger; }
uint32_t openCount() const { return mOpenCount; } ;
@@ -65,11 +66,9 @@
virtual void onSessionInfoUpdate() const;
private:
- const audio_session_t mSession;
- const audio_source_t mInputSource;
+ record_client_info_t mRecordClientInfo;
const struct audio_config_base mConfig;
const audio_input_flags_t mFlags;
- uid_t mUid;
bool mIsSoundTrigger;
uint32_t mOpenCount;
uint32_t mActiveCount;
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioSession.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioSession.cpp
index bea9f4f..5b57d3d 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioSession.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioSession.cpp
@@ -38,9 +38,9 @@
bool isSoundTrigger,
AudioMix* policyMix,
AudioPolicyClientInterface *clientInterface) :
- mSession(session), mInputSource(inputSource),
+ mRecordClientInfo({ .uid = uid, .session = session, .source = inputSource}),
mConfig({ .format = format, .sample_rate = sampleRate, .channel_mask = channelMask}),
- mFlags(flags), mUid(uid), mIsSoundTrigger(isSoundTrigger),
+ mFlags(flags), mIsSoundTrigger(isSoundTrigger),
mOpenCount(1), mActiveCount(0), mPolicyMix(policyMix), mClientInterface(clientInterface),
mInfoProvider(NULL)
{
@@ -92,7 +92,7 @@
const audio_patch_handle_t patchHandle = (provider != NULL) ? provider->getPatchHandle() :
AUDIO_PATCH_HANDLE_NONE;
if (patchHandle != AUDIO_PATCH_HANDLE_NONE) {
- mClientInterface->onRecordingConfigurationUpdate(event, mSession, mInputSource,
+ mClientInterface->onRecordingConfigurationUpdate(event, &mRecordClientInfo,
&mConfig, &deviceConfig, patchHandle);
}
}
@@ -102,13 +102,13 @@
bool AudioSession::matches(const sp<AudioSession> &other) const
{
- if (other->session() == mSession &&
- other->inputSource() == mInputSource &&
+ if (other->session() == mRecordClientInfo.session &&
+ other->inputSource() == mRecordClientInfo.source &&
other->format() == mConfig.format &&
other->sampleRate() == mConfig.sample_rate &&
other->channelMask() == mConfig.channel_mask &&
other->flags() == mFlags &&
- other->uid() == mUid) {
+ other->uid() == mRecordClientInfo.uid) {
return true;
}
return false;
@@ -130,8 +130,7 @@
AUDIO_PATCH_HANDLE_NONE;
if (patchHandle != AUDIO_PATCH_HANDLE_NONE) {
mClientInterface->onRecordingConfigurationUpdate(RECORD_CONFIG_EVENT_START,
- mSession, mInputSource,
- &mConfig, &deviceConfig, patchHandle);
+ &mRecordClientInfo, &mConfig, &deviceConfig, patchHandle);
}
}
}
@@ -144,11 +143,11 @@
snprintf(buffer, SIZE, "%*sAudio session %d:\n", spaces, "", index+1);
result.append(buffer);
- snprintf(buffer, SIZE, "%*s- session: %2d\n", spaces, "", mSession);
+ snprintf(buffer, SIZE, "%*s- session: %2d\n", spaces, "", mRecordClientInfo.session);
result.append(buffer);
- snprintf(buffer, SIZE, "%*s- owner uid: %2d\n", spaces, "", mUid);
+ snprintf(buffer, SIZE, "%*s- owner uid: %2d\n", spaces, "", mRecordClientInfo.uid);
result.append(buffer);
- snprintf(buffer, SIZE, "%*s- input source: %d\n", spaces, "", mInputSource);
+ snprintf(buffer, SIZE, "%*s- input source: %d\n", spaces, "", mRecordClientInfo.source);
result.append(buffer);
snprintf(buffer, SIZE, "%*s- format: %08x\n", spaces, "", mConfig.format);
result.append(buffer);
diff --git a/services/audiopolicy/service/AudioPolicyClientImpl.cpp b/services/audiopolicy/service/AudioPolicyClientImpl.cpp
index dbcc070..31c9575 100644
--- a/services/audiopolicy/service/AudioPolicyClientImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyClientImpl.cpp
@@ -220,11 +220,11 @@
}
void AudioPolicyService::AudioPolicyClient::onRecordingConfigurationUpdate(
- int event, audio_session_t session, audio_source_t source,
+ int event, const record_client_info_t *clientInfo,
const audio_config_base_t *clientConfig, const audio_config_base_t *deviceConfig,
audio_patch_handle_t patchHandle)
{
- mAudioPolicyService->onRecordingConfigurationUpdate(event, session, source,
+ mAudioPolicyService->onRecordingConfigurationUpdate(event, clientInfo,
clientConfig, deviceConfig, patchHandle);
}
diff --git a/services/audiopolicy/service/AudioPolicyEffects.cpp b/services/audiopolicy/service/AudioPolicyEffects.cpp
index 654465d..84b1073 100644
--- a/services/audiopolicy/service/AudioPolicyEffects.cpp
+++ b/services/audiopolicy/service/AudioPolicyEffects.cpp
@@ -20,8 +20,10 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <memory>
#include <cutils/misc.h>
#include <media/AudioEffect.h>
+#include <media/EffectsConfig.h>
#include <system/audio.h>
#include <system/audio_effects/audio_effects_conf.h>
#include <utils/Vector.h>
@@ -39,11 +41,17 @@
AudioPolicyEffects::AudioPolicyEffects()
{
- // load automatic audio effect modules
- if (access(AUDIO_EFFECT_VENDOR_CONFIG_FILE, R_OK) == 0) {
- loadAudioEffectConfig(AUDIO_EFFECT_VENDOR_CONFIG_FILE);
- } else if (access(AUDIO_EFFECT_DEFAULT_CONFIG_FILE, R_OK) == 0) {
- loadAudioEffectConfig(AUDIO_EFFECT_DEFAULT_CONFIG_FILE);
+ status_t loadResult = loadAudioEffectXmlConfig();
+ if (loadResult < 0) {
+ ALOGW("Failed to load XML effect configuration, fallback to .conf");
+ // load automatic audio effect modules
+ if (access(AUDIO_EFFECT_VENDOR_CONFIG_FILE, R_OK) == 0) {
+ loadAudioEffectConfig(AUDIO_EFFECT_VENDOR_CONFIG_FILE);
+ } else if (access(AUDIO_EFFECT_DEFAULT_CONFIG_FILE, R_OK) == 0) {
+ loadAudioEffectConfig(AUDIO_EFFECT_DEFAULT_CONFIG_FILE);
+ }
+ } else if (loadResult > 0) {
+ ALOGE("Effect config is partially invalid, skipped %d elements", loadResult);
}
}
@@ -685,6 +693,28 @@
return NO_ERROR;
}
+status_t AudioPolicyEffects::loadAudioEffectXmlConfig() {
+ auto result = effectsConfig::parse();
+ if (result.parsedConfig == nullptr) {
+ return -ENOENT;
+ }
+
+ auto loadProcessingChain = [](auto& processingChain, auto& streams) {
+ for (auto& stream : processingChain) {
+ auto effectDescs = std::make_unique<EffectDescVector>();
+ for (auto& effect : stream.effects) {
+ effectDescs->mEffects.add(
+ new EffectDesc{effect.get().name.c_str(), effect.get().uuid});
+ }
+ streams.add(stream.type, effectDescs.release());
+ }
+ };
+ loadProcessingChain(result.parsedConfig->preprocess, mInputSources);
+ loadProcessingChain(result.parsedConfig->postprocess, mOutputStreams);
+ // Casting from ssize_t to status_t is probably safe, there should not be more than 2^31 errors
+ return result.nbSkippedElement;
+}
+
status_t AudioPolicyEffects::loadAudioEffectConfig(const char *path)
{
cnode *root;
diff --git a/services/audiopolicy/service/AudioPolicyEffects.h b/services/audiopolicy/service/AudioPolicyEffects.h
index 0c74d87..59d5d14 100644
--- a/services/audiopolicy/service/AudioPolicyEffects.h
+++ b/services/audiopolicy/service/AudioPolicyEffects.h
@@ -155,7 +155,8 @@
audio_stream_type_t streamNameToEnum(const char *name);
// Parse audio_effects.conf
- status_t loadAudioEffectConfig(const char *path);
+ status_t loadAudioEffectConfig(const char *path); // TODO: add legacy in the name
+ status_t loadAudioEffectXmlConfig(); // TODO: remove "Xml" in the name
// Load all effects descriptors in configuration file
status_t loadEffects(cnode *root, Vector <EffectDesc *>& effects);
diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp
index c4f6367..b417631 100644
--- a/services/audiopolicy/service/AudioPolicyService.cpp
+++ b/services/audiopolicy/service/AudioPolicyService.cpp
@@ -185,21 +185,21 @@
}
}
-void AudioPolicyService::onRecordingConfigurationUpdate(int event, audio_session_t session,
- audio_source_t source, const audio_config_base_t *clientConfig,
+void AudioPolicyService::onRecordingConfigurationUpdate(int event,
+ const record_client_info_t *clientInfo, const audio_config_base_t *clientConfig,
const audio_config_base_t *deviceConfig, audio_patch_handle_t patchHandle)
{
- mOutputCommandThread->recordingConfigurationUpdateCommand(event, session, source,
+ mOutputCommandThread->recordingConfigurationUpdateCommand(event, clientInfo,
clientConfig, deviceConfig, patchHandle);
}
-void AudioPolicyService::doOnRecordingConfigurationUpdate(int event, audio_session_t session,
- audio_source_t source, const audio_config_base_t *clientConfig,
+void AudioPolicyService::doOnRecordingConfigurationUpdate(int event,
+ const record_client_info_t *clientInfo, const audio_config_base_t *clientConfig,
const audio_config_base_t *deviceConfig, audio_patch_handle_t patchHandle)
{
Mutex::Autolock _l(mNotificationClientsLock);
for (size_t i = 0; i < mNotificationClients.size(); i++) {
- mNotificationClients.valueAt(i)->onRecordingConfigurationUpdate(event, session, source,
+ mNotificationClients.valueAt(i)->onRecordingConfigurationUpdate(event, clientInfo,
clientConfig, deviceConfig, patchHandle);
}
}
@@ -267,12 +267,12 @@
}
void AudioPolicyService::NotificationClient::onRecordingConfigurationUpdate(
- int event, audio_session_t session, audio_source_t source,
+ int event, const record_client_info_t *clientInfo,
const audio_config_base_t *clientConfig, const audio_config_base_t *deviceConfig,
audio_patch_handle_t patchHandle)
{
if (mAudioPolicyServiceClient != 0) {
- mAudioPolicyServiceClient->onRecordingConfigurationUpdate(event, session, source,
+ mAudioPolicyServiceClient->onRecordingConfigurationUpdate(event, clientInfo,
clientConfig, deviceConfig, patchHandle);
}
}
@@ -544,8 +544,8 @@
break;
}
mLock.unlock();
- svc->doOnRecordingConfigurationUpdate(data->mEvent, data->mSession,
- data->mSource, &data->mClientConfig, &data->mDeviceConfig,
+ svc->doOnRecordingConfigurationUpdate(data->mEvent, &data->mClientInfo,
+ &data->mClientConfig, &data->mDeviceConfig,
data->mPatchHandle);
mLock.lock();
} break;
@@ -810,7 +810,7 @@
}
void AudioPolicyService::AudioCommandThread::recordingConfigurationUpdateCommand(
- int event, audio_session_t session, audio_source_t source,
+ int event, const record_client_info_t *clientInfo,
const audio_config_base_t *clientConfig, const audio_config_base_t *deviceConfig,
audio_patch_handle_t patchHandle)
{
@@ -818,14 +818,13 @@
command->mCommand = RECORDING_CONFIGURATION_UPDATE;
RecordingConfigurationUpdateData *data = new RecordingConfigurationUpdateData();
data->mEvent = event;
- data->mSession = session;
- data->mSource = source;
+ data->mClientInfo = *clientInfo;
data->mClientConfig = *clientConfig;
data->mDeviceConfig = *deviceConfig;
data->mPatchHandle = patchHandle;
command->mParam = data;
- ALOGV("AudioCommandThread() adding recording configuration update event %d, source %d",
- event, source);
+ ALOGV("AudioCommandThread() adding recording configuration update event %d, source %d uid %u",
+ event, clientInfo->source, clientInfo->uid);
sendCommand(command);
}
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index 35542f1..38d4b17 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -228,11 +228,11 @@
void onDynamicPolicyMixStateUpdate(const String8& regId, int32_t state);
void doOnDynamicPolicyMixStateUpdate(const String8& regId, int32_t state);
- void onRecordingConfigurationUpdate(int event, audio_session_t session,
- audio_source_t source, const audio_config_base_t *clientConfig,
+ void onRecordingConfigurationUpdate(int event, const record_client_info_t *clientInfo,
+ const audio_config_base_t *clientConfig,
const audio_config_base_t *deviceConfig, audio_patch_handle_t patchHandle);
- void doOnRecordingConfigurationUpdate(int event, audio_session_t session,
- audio_source_t source, const audio_config_base_t *clientConfig,
+ void doOnRecordingConfigurationUpdate(int event, const record_client_info_t *clientInfo,
+ const audio_config_base_t *clientConfig,
const audio_config_base_t *deviceConfig, audio_patch_handle_t patchHandle);
private:
@@ -306,8 +306,8 @@
int delayMs);
void dynamicPolicyMixStateUpdateCommand(const String8& regId, int32_t state);
void recordingConfigurationUpdateCommand(
- int event, audio_session_t session,
- audio_source_t source,
+ int event,
+ const record_client_info_t *clientInfo,
const audio_config_base_t *clientConfig,
const audio_config_base_t *deviceConfig,
audio_patch_handle_t patchHandle);
@@ -404,8 +404,7 @@
class RecordingConfigurationUpdateData : public AudioCommandData {
public:
int mEvent;
- audio_session_t mSession;
- audio_source_t mSource;
+ record_client_info_t mClientInfo;
struct audio_config_base mClientConfig;
struct audio_config_base mDeviceConfig;
audio_patch_handle_t mPatchHandle;
@@ -518,7 +517,7 @@
virtual void onAudioPatchListUpdate();
virtual void onDynamicPolicyMixStateUpdate(String8 regId, int32_t state);
virtual void onRecordingConfigurationUpdate(int event,
- audio_session_t session, audio_source_t source,
+ const record_client_info_t *clientInfo,
const audio_config_base_t *clientConfig,
const audio_config_base_t *deviceConfig, audio_patch_handle_t patchHandle);
@@ -540,8 +539,7 @@
void onAudioPatchListUpdate();
void onDynamicPolicyMixStateUpdate(const String8& regId, int32_t state);
void onRecordingConfigurationUpdate(
- int event, audio_session_t session,
- audio_source_t source,
+ int event, const record_client_info_t *clientInfo,
const audio_config_base_t *clientConfig,
const audio_config_base_t *deviceConfig,
audio_patch_handle_t patchHandle);
diff --git a/services/mediaanalytics/MediaAnalyticsService.cpp b/services/mediaanalytics/MediaAnalyticsService.cpp
index 876c685..f3bb35c 100644
--- a/services/mediaanalytics/MediaAnalyticsService.cpp
+++ b/services/mediaanalytics/MediaAnalyticsService.cpp
@@ -404,6 +404,8 @@
} else {
dumpRecent(result, ts_since, only);
}
+ free((void*)only);
+ only=NULL;
if (clear) {
diff --git a/services/mediadrm/Android.mk b/services/mediadrm/Android.mk
index 6b30db6..2daa829 100644
--- a/services/mediadrm/Android.mk
+++ b/services/mediadrm/Android.mk
@@ -17,7 +17,6 @@
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
- MediaCasService.cpp \
MediaDrmService.cpp \
main_mediadrmserver.cpp
diff --git a/services/mediadrm/FactoryLoader.h b/services/mediadrm/FactoryLoader.h
deleted file mode 100644
index d7f1118..0000000
--- a/services/mediadrm/FactoryLoader.h
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef MEDIA_CAS_LOADER_H_
-#define MEDIA_CAS_LOADER_H_
-
-#include <dirent.h>
-#include <dlfcn.h>
-#include <media/SharedLibrary.h>
-#include <utils/KeyedVector.h>
-#include <utils/Mutex.h>
-
-namespace android {
-using namespace std;
-using namespace media;
-using namespace MediaCas;
-
-template <class T>
-class FactoryLoader {
-public:
- FactoryLoader(const char *name) :
- mFactory(NULL), mCreateFactoryFuncName(name) {}
-
- virtual ~FactoryLoader() { closeFactory(); }
-
- bool findFactoryForScheme(
- int32_t CA_system_id,
- sp<SharedLibrary> *library = NULL,
- T** factory = NULL);
-
- bool enumeratePlugins(vector<ParcelableCasPluginDescriptor>* results);
-
-private:
- typedef T*(*CreateFactoryFunc)();
-
- Mutex mMapLock;
- T* mFactory;
- const char *mCreateFactoryFuncName;
- sp<SharedLibrary> mLibrary;
- KeyedVector<int32_t, String8> mCASystemIdToLibraryPathMap;
- KeyedVector<String8, wp<SharedLibrary> > mLibraryPathToOpenLibraryMap;
-
- bool loadFactoryForSchemeFromPath(
- const String8 &path,
- int32_t CA_system_id,
- sp<SharedLibrary> *library,
- T** factory);
-
- bool queryPluginsFromPath(
- const String8 &path,
- vector<ParcelableCasPluginDescriptor>* results);
-
- bool openFactory(const String8 &path);
- void closeFactory();
-};
-
-template <class T>
-bool FactoryLoader<T>::findFactoryForScheme(
- int32_t CA_system_id, sp<SharedLibrary> *library, T** factory) {
- if (library != NULL) {
- library->clear();
- }
- if (factory != NULL) {
- *factory = NULL;
- }
-
- Mutex::Autolock autoLock(mMapLock);
-
- // first check cache
- ssize_t index = mCASystemIdToLibraryPathMap.indexOfKey(CA_system_id);
- if (index >= 0) {
- return loadFactoryForSchemeFromPath(
- mCASystemIdToLibraryPathMap[index],
- CA_system_id, library, factory);
- }
-
- // no luck, have to search
- String8 dirPath("/system/lib/mediacas");
- DIR* pDir = opendir(dirPath.string());
-
- if (pDir == NULL) {
- ALOGE("Failed to open plugin directory %s", dirPath.string());
- return false;
- }
-
- struct dirent* pEntry;
- while ((pEntry = readdir(pDir))) {
- String8 pluginPath = dirPath + "/" + pEntry->d_name;
- if (pluginPath.getPathExtension() == ".so") {
- if (loadFactoryForSchemeFromPath(
- pluginPath, CA_system_id, library, factory)) {
- mCASystemIdToLibraryPathMap.add(CA_system_id, pluginPath);
- closedir(pDir);
-
- return true;
- }
- }
- }
-
- closedir(pDir);
-
- ALOGE("Failed to find plugin");
- return false;
-}
-
-template <class T>
-bool FactoryLoader<T>::enumeratePlugins(
- vector<ParcelableCasPluginDescriptor>* results) {
- ALOGI("enumeratePlugins");
-
- results->clear();
-
- String8 dirPath("/system/lib/mediacas");
- DIR* pDir = opendir(dirPath.string());
-
- if (pDir == NULL) {
- ALOGE("Failed to open plugin directory %s", dirPath.string());
- return false;
- }
-
- Mutex::Autolock autoLock(mMapLock);
-
- struct dirent* pEntry;
- while ((pEntry = readdir(pDir))) {
- String8 pluginPath = dirPath + "/" + pEntry->d_name;
- if (pluginPath.getPathExtension() == ".so") {
- queryPluginsFromPath(pluginPath, results);
- }
- }
- return true;
-}
-
-template <class T>
-bool FactoryLoader<T>::loadFactoryForSchemeFromPath(
- const String8 &path, int32_t CA_system_id,
- sp<SharedLibrary> *library, T** factory) {
- closeFactory();
-
- if (!openFactory(path) || !mFactory->isSystemIdSupported(CA_system_id)) {
- closeFactory();
- return false;
- }
-
- if (library != NULL) {
- *library = mLibrary;
- }
- if (factory != NULL) {
- *factory = mFactory;
- }
- return true;
-}
-
-template <class T>
-bool FactoryLoader<T>::queryPluginsFromPath(
- const String8 &path, vector<ParcelableCasPluginDescriptor>* results) {
- closeFactory();
-
- vector<CasPluginDescriptor> descriptors;
- if (!openFactory(path) || mFactory->queryPlugins(&descriptors) != OK) {
- closeFactory();
- return false;
- }
-
- for (auto it = descriptors.begin(); it != descriptors.end(); it++) {
- results->push_back(ParcelableCasPluginDescriptor(
- it->CA_system_id, it->name));
- }
- return true;
-}
-
-template <class T>
-bool FactoryLoader<T>::openFactory(const String8 &path) {
- // get strong pointer to open shared library
- ssize_t index = mLibraryPathToOpenLibraryMap.indexOfKey(path);
- if (index >= 0) {
- mLibrary = mLibraryPathToOpenLibraryMap[index].promote();
- } else {
- index = mLibraryPathToOpenLibraryMap.add(path, NULL);
- }
-
- if (!mLibrary.get()) {
- mLibrary = new SharedLibrary(path);
- if (!*mLibrary) {
- return false;
- }
-
- mLibraryPathToOpenLibraryMap.replaceValueAt(index, mLibrary);
- }
-
- CreateFactoryFunc createFactory =
- (CreateFactoryFunc)mLibrary->lookup(mCreateFactoryFuncName);
- if (createFactory == NULL || (mFactory = createFactory()) == NULL) {
- return false;
- }
- return true;
-}
-
-template <class T>
-void FactoryLoader<T>::closeFactory() {
- delete mFactory;
- mFactory = NULL;
- mLibrary.clear();
-}
-
-} // namespace android
-
-#endif // MEDIA_CAS_LOADER_H_
diff --git a/services/mediadrm/MediaCasService.cpp b/services/mediadrm/MediaCasService.cpp
deleted file mode 100644
index c111283..0000000
--- a/services/mediadrm/MediaCasService.cpp
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "MediaCasService"
-
-#include <binder/IServiceManager.h>
-#include <media/cas/CasAPI.h>
-#include <media/cas/DescramblerAPI.h>
-#include <media/CasImpl.h>
-#include <media/DescramblerImpl.h>
-#include <utils/Log.h>
-#include <utils/List.h>
-#include "MediaCasService.h"
-#include <android/media/ICasListener.h>
-
-namespace android {
-
-//static
-void MediaCasService::instantiate() {
- defaultServiceManager()->addService(
- String16("media.cas"), new MediaCasService());
-}
-
-MediaCasService::MediaCasService() :
- mCasLoader(new FactoryLoader<CasFactory>("createCasFactory")),
- mDescramblerLoader(new FactoryLoader<DescramblerFactory>(
- "createDescramblerFactory")) {
-}
-
-MediaCasService::~MediaCasService() {
- delete mCasLoader;
- delete mDescramblerLoader;
-}
-
-Status MediaCasService::enumeratePlugins(
- vector<ParcelableCasPluginDescriptor>* results) {
- ALOGV("enumeratePlugins");
-
- mCasLoader->enumeratePlugins(results);
-
- return Status::ok();
-}
-
-Status MediaCasService::isSystemIdSupported(
- int32_t CA_system_id, bool* result) {
- ALOGV("isSystemIdSupported: CA_system_id=%d", CA_system_id);
-
- *result = mCasLoader->findFactoryForScheme(CA_system_id);
-
- return Status::ok();
-}
-
-Status MediaCasService::createPlugin(
- int32_t CA_system_id,
- const sp<ICasListener> &listener,
- sp<ICas>* result) {
- ALOGV("createPlugin: CA_system_id=%d", CA_system_id);
-
- result->clear();
-
- CasFactory *factory;
- sp<SharedLibrary> library;
- if (mCasLoader->findFactoryForScheme(CA_system_id, &library, &factory)) {
- CasPlugin *plugin = NULL;
- sp<CasImpl> casImpl = new CasImpl(listener);
- if (factory->createPlugin(CA_system_id, (uint64_t)casImpl.get(),
- &CasImpl::OnEvent, &plugin) == OK && plugin != NULL) {
- casImpl->init(library, plugin);
- *result = casImpl;
- }
- }
-
- return Status::ok();
-}
-
-Status MediaCasService::isDescramblerSupported(
- int32_t CA_system_id, bool* result) {
- ALOGV("isDescramblerSupported: CA_system_id=%d", CA_system_id);
-
- *result = mDescramblerLoader->findFactoryForScheme(CA_system_id);
-
- return Status::ok();
-}
-
-Status MediaCasService::createDescrambler(
- int32_t CA_system_id, sp<IDescrambler>* result) {
- ALOGV("createDescrambler: CA_system_id=%d", CA_system_id);
-
- result->clear();
-
- DescramblerFactory *factory;
- sp<SharedLibrary> library;
- if (mDescramblerLoader->findFactoryForScheme(
- CA_system_id, &library, &factory)) {
- DescramblerPlugin *plugin = NULL;
- if (factory->createPlugin(CA_system_id, &plugin) == OK
- && plugin != NULL) {
- *result = new DescramblerImpl(library, plugin);
- }
- }
-
- return Status::ok();
-}
-
-} // namespace android
diff --git a/services/mediadrm/MediaCasService.h b/services/mediadrm/MediaCasService.h
deleted file mode 100644
index cb828f2..0000000
--- a/services/mediadrm/MediaCasService.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef MEDIA_CAS_SERVICE_H_
-#define MEDIA_CAS_SERVICE_H_
-
-#include <android/media/BnMediaCasService.h>
-
-#include "FactoryLoader.h"
-
-namespace android {
-using binder::Status;
-struct CasFactory;
-struct DescramblerFactory;
-
-class MediaCasService : public BnMediaCasService {
-public:
- static void instantiate();
-
- virtual Status enumeratePlugins(
- vector<ParcelableCasPluginDescriptor>* results) override;
-
- virtual Status isSystemIdSupported(
- int32_t CA_system_id, bool* result) override;
-
- virtual Status createPlugin(
- int32_t CA_system_id,
- const sp<ICasListener> &listener,
- sp<ICas>* result) override;
-
- virtual Status isDescramblerSupported(
- int32_t CA_system_id, bool* result) override;
-
- virtual Status createDescrambler(
- int32_t CA_system_id, sp<IDescrambler>* result) override;
-
-private:
- FactoryLoader<CasFactory> *mCasLoader;
- FactoryLoader<DescramblerFactory> *mDescramblerLoader;
-
- MediaCasService();
- virtual ~MediaCasService();
-};
-
-} // namespace android
-
-#endif // MEDIA_CAS_SERVICE_H_
diff --git a/services/mediadrm/main_mediadrmserver.cpp b/services/mediadrm/main_mediadrmserver.cpp
index b685ae0..b767b8c 100644
--- a/services/mediadrm/main_mediadrmserver.cpp
+++ b/services/mediadrm/main_mediadrmserver.cpp
@@ -27,7 +27,6 @@
#include <cutils/properties.h>
#include <utils/Log.h>
#include "MediaDrmService.h"
-#include "MediaCasService.h"
using namespace android;
@@ -39,7 +38,6 @@
sp<IServiceManager> sm = defaultServiceManager();
ALOGI("ServiceManager: %p", sm.get());
MediaDrmService::instantiate();
- MediaCasService::instantiate();
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
}
diff --git a/services/oboeservice/OWNERS b/services/oboeservice/OWNERS
new file mode 100644
index 0000000..f4d51f9
--- /dev/null
+++ b/services/oboeservice/OWNERS
@@ -0,0 +1 @@
+philburk@google.com
diff --git a/services/radio/Android.mk b/services/radio/Android.mk
deleted file mode 100644
index 1b50dc3..0000000
--- a/services/radio/Android.mk
+++ /dev/null
@@ -1,59 +0,0 @@
-# Copyright 2014 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.
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-
-LOCAL_SRC_FILES:= \
- RadioService.cpp
-
-LOCAL_SHARED_LIBRARIES:= \
- liblog \
- libutils \
- libbinder \
- libcutils \
- libaudioclient \
- libhardware \
- libradio \
- libradio_metadata
-
-ifeq ($(USE_LEGACY_LOCAL_AUDIO_HAL),true)
-# libhardware configuration
-LOCAL_SRC_FILES += \
- RadioHalLegacy.cpp
-else
-# Treble configuration
-
-LOCAL_SRC_FILES += \
- HidlUtils.cpp \
- RadioHalHidl.cpp
-
-LOCAL_SHARED_LIBRARIES += \
- libhwbinder \
- libhidlbase \
- libhidltransport \
- libbase \
- libaudiohal \
- android.hardware.broadcastradio@1.0
-endif
-
-LOCAL_CFLAGS += -Wall -Wextra -Werror
-
-LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
-
-LOCAL_MODULE:= libradioservice
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/services/radio/HidlUtils.cpp b/services/radio/HidlUtils.cpp
deleted file mode 100644
index 6895377..0000000
--- a/services/radio/HidlUtils.cpp
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#define LOG_TAG "HidlUtils"
-//#define LOG_NDEBUG 0
-
-#include <utils/Log.h>
-#include <utils/misc.h>
-#include <system/radio_metadata.h>
-
-#include "HidlUtils.h"
-
-namespace android {
-
-using android::hardware::broadcastradio::V1_0::MetadataType;
-using android::hardware::broadcastradio::V1_0::Band;
-using android::hardware::broadcastradio::V1_0::Deemphasis;
-using android::hardware::broadcastradio::V1_0::Rds;
-
-//static
-int HidlUtils::convertHalResult(Result result)
-{
- switch (result) {
- case Result::OK:
- return 0;
- case Result::INVALID_ARGUMENTS:
- return -EINVAL;
- case Result::INVALID_STATE:
- return -ENOSYS;
- case Result::TIMEOUT:
- return -ETIMEDOUT;
- case Result::NOT_INITIALIZED:
- default:
- return -ENODEV;
- }
-}
-
-
-//static
-void HidlUtils::convertBandConfigToHal(BandConfig *halConfig,
- const radio_hal_band_config_t *config)
-{
- halConfig->type = static_cast<Band>(config->type);
- halConfig->antennaConnected = config->antenna_connected;
- halConfig->lowerLimit = config->lower_limit;
- halConfig->upperLimit = config->upper_limit;
- halConfig->spacings.setToExternal(const_cast<unsigned int *>(&config->spacings[0]),
- config->num_spacings * sizeof(uint32_t));
- // FIXME: transfer buffer ownership. should have a method for that in hidl_vec
- halConfig->spacings.resize(config->num_spacings);
-
- if (halConfig->type == Band::FM) {
- halConfig->ext.fm.deemphasis = static_cast<Deemphasis>(config->fm.deemphasis);
- halConfig->ext.fm.stereo = config->fm.stereo;
- halConfig->ext.fm.rds = static_cast<Rds>(config->fm.rds);
- halConfig->ext.fm.ta = config->fm.ta;
- halConfig->ext.fm.af = config->fm.af;
- halConfig->ext.fm.ea = config->fm.ea;
- } else {
- halConfig->ext.am.stereo = config->am.stereo;
- }
-}
-
-//static
-void HidlUtils::convertPropertiesFromHal(radio_hal_properties_t *properties,
- const Properties *halProperties)
-{
- properties->class_id = static_cast<radio_class_t>(halProperties->classId);
- strlcpy(properties->implementor, halProperties->implementor.c_str(), RADIO_STRING_LEN_MAX);
- strlcpy(properties->product, halProperties->product.c_str(), RADIO_STRING_LEN_MAX);
- strlcpy(properties->version, halProperties->version.c_str(), RADIO_STRING_LEN_MAX);
- strlcpy(properties->serial, halProperties->serial.c_str(), RADIO_STRING_LEN_MAX);
- properties->num_tuners = halProperties->numTuners;
- properties->num_audio_sources = halProperties->numAudioSources;
- properties->supports_capture = halProperties->supportsCapture;
- properties->num_bands = halProperties->bands.size();
-
- for (size_t i = 0; i < halProperties->bands.size(); i++) {
- convertBandConfigFromHal(&properties->bands[i], &halProperties->bands[i]);
- }
-}
-
-//static
-void HidlUtils::convertBandConfigFromHal(radio_hal_band_config_t *config,
- const BandConfig *halConfig)
-{
- config->type = static_cast<radio_band_t>(halConfig->type);
- config->antenna_connected = halConfig->antennaConnected;
- config->lower_limit = halConfig->lowerLimit;
- config->upper_limit = halConfig->upperLimit;
- config->num_spacings = halConfig->spacings.size();
- if (config->num_spacings > RADIO_NUM_SPACINGS_MAX) {
- config->num_spacings = RADIO_NUM_SPACINGS_MAX;
- }
- memcpy(config->spacings, halConfig->spacings.data(),
- sizeof(uint32_t) * config->num_spacings);
-
- if (halConfig->type == Band::FM) {
- config->fm.deemphasis = static_cast<radio_deemphasis_t>(halConfig->ext.fm.deemphasis);
- config->fm.stereo = halConfig->ext.fm.stereo;
- config->fm.rds = static_cast<radio_rds_t>(halConfig->ext.fm.rds);
- config->fm.ta = halConfig->ext.fm.ta;
- config->fm.af = halConfig->ext.fm.af;
- config->fm.ea = halConfig->ext.fm.ea;
- } else {
- config->am.stereo = halConfig->ext.am.stereo;
- }
-}
-
-
-//static
-void HidlUtils::convertProgramInfoFromHal(radio_program_info_t *info,
- const ProgramInfo *halInfo)
-{
- info->channel = halInfo->channel;
- info->sub_channel = halInfo->subChannel;
- info->tuned = halInfo->tuned;
- info->stereo = halInfo->stereo;
- info->digital = halInfo->digital;
- info->signal_strength = halInfo->signalStrength;
- convertMetaDataFromHal(&info->metadata, halInfo->metadata,
- halInfo->channel, halInfo->subChannel);
-}
-
-// TODO(twasilczyk): drop unnecessary channel info
-//static
-void HidlUtils::convertMetaDataFromHal(radio_metadata_t **metadata,
- const hidl_vec<MetaData>& halMetadata,
- uint32_t channel __unused,
- uint32_t subChannel __unused)
-{
-
- if (metadata == nullptr || *metadata == nullptr) {
- ALOGE("destination metadata buffer is a nullptr");
- return;
- }
- for (size_t i = 0; i < halMetadata.size(); i++) {
- radio_metadata_key_t key = static_cast<radio_metadata_key_t>(halMetadata[i].key);
- radio_metadata_type_t type = static_cast<radio_metadata_key_t>(halMetadata[i].type);
- radio_metadata_clock_t clock;
-
- switch (type) {
- case RADIO_METADATA_TYPE_INT:
- radio_metadata_add_int(metadata, key, halMetadata[i].intValue);
- break;
- case RADIO_METADATA_TYPE_TEXT:
- radio_metadata_add_text(metadata, key, halMetadata[i].stringValue.c_str());
- break;
- case RADIO_METADATA_TYPE_RAW:
- radio_metadata_add_raw(metadata, key,
- halMetadata[i].rawValue.data(),
- halMetadata[i].rawValue.size());
- break;
- case RADIO_METADATA_TYPE_CLOCK:
- clock.utc_seconds_since_epoch =
- halMetadata[i].clockValue.utcSecondsSinceEpoch;
- clock.timezone_offset_in_minutes =
- halMetadata[i].clockValue.timezoneOffsetInMinutes;
- radio_metadata_add_clock(metadata, key, &clock);
- break;
- default:
- ALOGW("%s invalid metadata type %u",__FUNCTION__, halMetadata[i].type);
- break;
- }
- }
-}
-
-} // namespace android
diff --git a/services/radio/HidlUtils.h b/services/radio/HidlUtils.h
deleted file mode 100644
index c771060..0000000
--- a/services/radio/HidlUtils.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#ifndef ANDROID_HARDWARE_RADIO_HAL_HIDL_UTILS_H
-#define ANDROID_HARDWARE_RADIO_HAL_HIDL_UTILS_H
-
-#include <android/hardware/broadcastradio/1.0/types.h>
-#include <hardware/radio.h>
-
-namespace android {
-
-using android::hardware::hidl_vec;
-using android::hardware::broadcastradio::V1_0::Result;
-using android::hardware::broadcastradio::V1_0::Properties;
-using android::hardware::broadcastradio::V1_0::BandConfig;
-using android::hardware::broadcastradio::V1_0::ProgramInfo;
-using android::hardware::broadcastradio::V1_0::MetaData;
-
-class HidlUtils {
-public:
- static int convertHalResult(Result result);
- static void convertBandConfigFromHal(radio_hal_band_config_t *config,
- const BandConfig *halConfig);
- static void convertPropertiesFromHal(radio_hal_properties_t *properties,
- const Properties *halProperties);
- static void convertBandConfigToHal(BandConfig *halConfig,
- const radio_hal_band_config_t *config);
- static void convertProgramInfoFromHal(radio_program_info_t *info,
- const ProgramInfo *halInfo);
- static void convertMetaDataFromHal(radio_metadata_t **metadata,
- const hidl_vec<MetaData>& halMetadata,
- uint32_t channel,
- uint32_t subChannel);
-};
-
-} // namespace android
-
-#endif // ANDROID_HARDWARE_RADIO_HAL_HIDL_UTILS_H
diff --git a/services/radio/OWNERS b/services/radio/OWNERS
deleted file mode 100644
index eb9549a..0000000
--- a/services/radio/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-elaurent@google.com
-hunga@google.com
-twasilczyk@google.com
diff --git a/services/radio/RadioHalHidl.cpp b/services/radio/RadioHalHidl.cpp
deleted file mode 100644
index f637275..0000000
--- a/services/radio/RadioHalHidl.cpp
+++ /dev/null
@@ -1,382 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "RadioHalHidl"
-//#define LOG_NDEBUG 0
-
-#include <media/audiohal/hidl/HalDeathHandler.h>
-#include <utils/Log.h>
-#include <utils/misc.h>
-#include <system/RadioMetadataWrapper.h>
-#include <android/hardware/broadcastradio/1.0/IBroadcastRadioFactory.h>
-
-#include "RadioHalHidl.h"
-#include "HidlUtils.h"
-
-namespace android {
-
-using android::hardware::broadcastradio::V1_0::IBroadcastRadioFactory;
-using android::hardware::broadcastradio::V1_0::Class;
-using android::hardware::broadcastradio::V1_0::Direction;
-using android::hardware::broadcastradio::V1_0::Properties;
-
-
-/* static */
-sp<RadioInterface> RadioInterface::connectModule(radio_class_t classId)
-{
- return new RadioHalHidl(classId);
-}
-
-int RadioHalHidl::getProperties(radio_hal_properties_t *properties)
-{
- ALOGV("%s IN", __FUNCTION__);
- sp<IBroadcastRadio> module = getService();
- if (module == 0) {
- return -ENODEV;
- }
- Properties halProperties;
- Result halResult = Result::NOT_INITIALIZED;
- Return<void> hidlReturn =
- module->getProperties([&](Result result, const Properties& properties) {
- halResult = result;
- if (result == Result::OK) {
- halProperties = properties;
- }
- });
-
- if (halResult == Result::OK) {
- HidlUtils::convertPropertiesFromHal(properties, &halProperties);
- }
- return HidlUtils::convertHalResult(halResult);
-}
-
-int RadioHalHidl::openTuner(const radio_hal_band_config_t *config,
- bool audio,
- sp<TunerCallbackInterface> callback,
- sp<TunerInterface>& tuner)
-{
- sp<IBroadcastRadio> module = getService();
- if (module == 0) {
- return -ENODEV;
- }
- sp<Tuner> tunerImpl = new Tuner(callback, this);
-
- BandConfig halConfig;
- Result halResult = Result::NOT_INITIALIZED;
- sp<ITuner> halTuner;
-
- HidlUtils::convertBandConfigToHal(&halConfig, config);
- Return<void> hidlReturn =
- module->openTuner(halConfig, audio, tunerImpl,
- [&](Result result, const sp<ITuner>& tuner) {
- halResult = result;
- if (result == Result::OK) {
- halTuner = tuner;
- }
- });
-
- if (halResult == Result::OK) {
- tunerImpl->setHalTuner(halTuner);
- tuner = tunerImpl;
- }
-
- return HidlUtils::convertHalResult(halResult);
-}
-
-int RadioHalHidl::closeTuner(sp<TunerInterface>& tuner)
-{
- sp<Tuner> tunerImpl = static_cast<Tuner *>(tuner.get());
- sp<ITuner> clearTuner;
- tunerImpl->setHalTuner(clearTuner);
- return 0;
-}
-
-RadioHalHidl::RadioHalHidl(radio_class_t classId)
- : mClassId(classId)
-{
-}
-
-RadioHalHidl::~RadioHalHidl()
-{
-}
-
-sp<IBroadcastRadio> RadioHalHidl::getService()
-{
- if (mHalModule == 0) {
- sp<IBroadcastRadioFactory> factory = IBroadcastRadioFactory::getService();
- if (factory != 0) {
- factory->connectModule(static_cast<Class>(mClassId),
- [&](Result retval, const ::android::sp<IBroadcastRadio>& result) {
- if (retval == Result::OK) {
- mHalModule = result;
- }
- });
- }
- }
- ALOGV("%s OUT module %p", __FUNCTION__, mHalModule.get());
- return mHalModule;
-}
-
-void RadioHalHidl::clearService()
-{
- ALOGV("%s IN module %p", __FUNCTION__, mHalModule.get());
- mHalModule.clear();
-}
-
-
-int RadioHalHidl::Tuner::setConfiguration(const radio_hal_band_config_t *config)
-{
- ALOGV("%s IN mHalTuner %p", __FUNCTION__, mHalTuner.get());
-
- if (mHalTuner == 0) {
- return -ENODEV;
- }
- BandConfig halConfig;
- HidlUtils::convertBandConfigToHal(&halConfig, config);
-
- Return<Result> hidlResult = mHalTuner->setConfiguration(halConfig);
- return HidlUtils::convertHalResult(hidlResult);
-}
-
-int RadioHalHidl::Tuner::getConfiguration(radio_hal_band_config_t *config)
-{
- ALOGV("%s IN mHalTuner %p", __FUNCTION__, mHalTuner.get());
- if (mHalTuner == 0) {
- return -ENODEV;
- }
- BandConfig halConfig;
- Result halResult;
- Return<void> hidlReturn =
- mHalTuner->getConfiguration([&](Result result, const BandConfig& config) {
- halResult = result;
- if (result == Result::OK) {
- halConfig = config;
- }
- });
- if (hidlReturn.isOk() && halResult == Result::OK) {
- HidlUtils::convertBandConfigFromHal(config, &halConfig);
- }
- return HidlUtils::convertHalResult(halResult);
-}
-
-int RadioHalHidl::Tuner::scan(radio_direction_t direction, bool skip_sub_channel)
-{
- ALOGV("%s IN mHalTuner %p", __FUNCTION__, mHalTuner.get());
- if (mHalTuner == 0) {
- return -ENODEV;
- }
- Return<Result> hidlResult =
- mHalTuner->scan(static_cast<Direction>(direction), skip_sub_channel);
- return HidlUtils::convertHalResult(hidlResult);
-}
-
-int RadioHalHidl::Tuner::step(radio_direction_t direction, bool skip_sub_channel)
-{
- ALOGV("%s IN mHalTuner %p", __FUNCTION__, mHalTuner.get());
- if (mHalTuner == 0) {
- return -ENODEV;
- }
- Return<Result> hidlResult =
- mHalTuner->step(static_cast<Direction>(direction), skip_sub_channel);
- return HidlUtils::convertHalResult(hidlResult);
-}
-
-int RadioHalHidl::Tuner::tune(unsigned int channel, unsigned int sub_channel)
-{
- ALOGV("%s IN mHalTuner %p", __FUNCTION__, mHalTuner.get());
- if (mHalTuner == 0) {
- return -ENODEV;
- }
- Return<Result> hidlResult =
- mHalTuner->tune(channel, sub_channel);
- return HidlUtils::convertHalResult(hidlResult);
-}
-
-int RadioHalHidl::Tuner::cancel()
-{
- ALOGV("%s IN mHalTuner %p", __FUNCTION__, mHalTuner.get());
- if (mHalTuner == 0) {
- return -ENODEV;
- }
- Return<Result> hidlResult = mHalTuner->cancel();
- return HidlUtils::convertHalResult(hidlResult);
-}
-
-int RadioHalHidl::Tuner::getProgramInformation(radio_program_info_t *info)
-{
- ALOGV("%s IN mHalTuner %p", __FUNCTION__, mHalTuner.get());
- if (mHalTuner == 0) {
- return -ENODEV;
- }
- if (info == nullptr || info->metadata == nullptr) {
- return BAD_VALUE;
- }
- ProgramInfo halInfo;
- Result halResult;
- Return<void> hidlReturn = mHalTuner->getProgramInformation(
- [&](Result result, const ProgramInfo& info) {
- halResult = result;
- if (result == Result::OK) {
- halInfo = info;
- }
- });
- if (hidlReturn.isOk() && halResult == Result::OK) {
- HidlUtils::convertProgramInfoFromHal(info, &halInfo);
- }
- return HidlUtils::convertHalResult(halResult);
-}
-
-Return<void> RadioHalHidl::Tuner::hardwareFailure()
-{
- ALOGV("%s IN", __FUNCTION__);
- handleHwFailure();
- return Return<void>();
-}
-
-Return<void> RadioHalHidl::Tuner::configChange(Result result, const BandConfig& config)
-{
- ALOGV("%s IN", __FUNCTION__);
- radio_hal_event_t event;
- memset(&event, 0, sizeof(radio_hal_event_t));
- event.type = RADIO_EVENT_CONFIG;
- event.status = HidlUtils::convertHalResult(result);
- HidlUtils::convertBandConfigFromHal(&event.config, &config);
- onCallback(&event);
- return Return<void>();
-}
-
-Return<void> RadioHalHidl::Tuner::tuneComplete(Result result, const ProgramInfo& info)
-{
- ALOGV("%s IN", __FUNCTION__);
- radio_hal_event_t event = {};
- RadioMetadataWrapper metadataWrapper(&event.info.metadata);
-
- event.type = RADIO_EVENT_TUNED;
- event.status = HidlUtils::convertHalResult(result);
- HidlUtils::convertProgramInfoFromHal(&event.info, &info);
- onCallback(&event);
- return Return<void>();
-}
-
-Return<void> RadioHalHidl::Tuner::afSwitch(const ProgramInfo& info)
-{
- ALOGV("%s IN", __FUNCTION__);
- radio_hal_event_t event = {};
- RadioMetadataWrapper metadataWrapper(&event.info.metadata);
-
- event.type = RADIO_EVENT_AF_SWITCH;
- HidlUtils::convertProgramInfoFromHal(&event.info, &info);
- onCallback(&event);
- return Return<void>();
-}
-
-Return<void> RadioHalHidl::Tuner::antennaStateChange(bool connected)
-{
- ALOGV("%s IN", __FUNCTION__);
- radio_hal_event_t event;
- memset(&event, 0, sizeof(radio_hal_event_t));
- event.type = RADIO_EVENT_ANTENNA;
- event.on = connected;
- onCallback(&event);
- return Return<void>();
-}
-Return<void> RadioHalHidl::Tuner::trafficAnnouncement(bool active)
-{
- ALOGV("%s IN", __FUNCTION__);
- radio_hal_event_t event;
- memset(&event, 0, sizeof(radio_hal_event_t));
- event.type = RADIO_EVENT_TA;
- event.on = active;
- onCallback(&event);
- return Return<void>();
-}
-Return<void> RadioHalHidl::Tuner::emergencyAnnouncement(bool active)
-{
- ALOGV("%s IN", __FUNCTION__);
- radio_hal_event_t event;
- memset(&event, 0, sizeof(radio_hal_event_t));
- event.type = RADIO_EVENT_EA;
- event.on = active;
- onCallback(&event);
- return Return<void>();
-}
-Return<void> RadioHalHidl::Tuner::newMetadata(uint32_t channel, uint32_t subChannel,
- const ::android::hardware::hidl_vec<MetaData>& metadata)
-{
- ALOGV("%s IN", __FUNCTION__);
- radio_hal_event_t event = {};
- RadioMetadataWrapper metadataWrapper(&event.metadata);
-
- event.type = RADIO_EVENT_METADATA;
- HidlUtils::convertMetaDataFromHal(&event.metadata, metadata, channel, subChannel);
- onCallback(&event);
- return Return<void>();
-}
-
-
-RadioHalHidl::Tuner::Tuner(sp<TunerCallbackInterface> callback, sp<RadioHalHidl> module)
- : TunerInterface(), mHalTuner(NULL), mCallback(callback), mParentModule(module)
-{
- // Make sure the handler we are passing in only deals with const members,
- // as it can be called on an arbitrary thread.
- const auto& self = this;
- HalDeathHandler::getInstance()->registerAtExitHandler(
- this, [&self]() { self->sendHwFailureEvent(); });
-}
-
-
-RadioHalHidl::Tuner::~Tuner()
-{
- HalDeathHandler::getInstance()->unregisterAtExitHandler(this);
-}
-
-void RadioHalHidl::Tuner::setHalTuner(sp<ITuner>& halTuner) {
- if (mHalTuner != 0) {
- mHalTuner->unlinkToDeath(HalDeathHandler::getInstance());
- }
- mHalTuner = halTuner;
- if (mHalTuner != 0) {
- mHalTuner->linkToDeath(HalDeathHandler::getInstance(), 0 /*cookie*/);
- }
-}
-
-void RadioHalHidl::Tuner::handleHwFailure()
-{
- ALOGV("%s IN", __FUNCTION__);
- sp<RadioHalHidl> parentModule = mParentModule.promote();
- if (parentModule != 0) {
- parentModule->clearService();
- }
- sendHwFailureEvent();
- mHalTuner.clear();
-}
-
-void RadioHalHidl::Tuner::sendHwFailureEvent() const
-{
- radio_hal_event_t event;
- memset(&event, 0, sizeof(radio_hal_event_t));
- event.type = RADIO_EVENT_HW_FAILURE;
- onCallback(&event);
-}
-
-void RadioHalHidl::Tuner::onCallback(radio_hal_event_t *halEvent) const
-{
- if (mCallback != 0) {
- mCallback->onEvent(halEvent);
- }
-}
-
-} // namespace android
diff --git a/services/radio/RadioHalHidl.h b/services/radio/RadioHalHidl.h
deleted file mode 100644
index f98420d..0000000
--- a/services/radio/RadioHalHidl.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_RADIO_HAL_HIDL_H
-#define ANDROID_HARDWARE_RADIO_HAL_HIDL_H
-
-#include <utils/RefBase.h>
-#include <utils/threads.h>
-#include "RadioInterface.h"
-#include "TunerInterface.h"
-#include "TunerCallbackInterface.h"
-#include <android/hardware/broadcastradio/1.0/types.h>
-#include <android/hardware/broadcastradio/1.0/IBroadcastRadio.h>
-#include <android/hardware/broadcastradio/1.0/ITuner.h>
-#include <android/hardware/broadcastradio/1.0/ITunerCallback.h>
-
-namespace android {
-
-using android::hardware::Return;
-using android::hardware::broadcastradio::V1_0::Result;
-using android::hardware::broadcastradio::V1_0::IBroadcastRadio;
-using android::hardware::broadcastradio::V1_0::ITuner;
-using android::hardware::broadcastradio::V1_0::ITunerCallback;
-
-using android::hardware::broadcastradio::V1_0::BandConfig;
-using android::hardware::broadcastradio::V1_0::ProgramInfo;
-using android::hardware::broadcastradio::V1_0::MetaData;
-
-class RadioHalHidl : public RadioInterface
-{
-public:
- RadioHalHidl(radio_class_t classId);
-
- // RadioInterface
- virtual int getProperties(radio_hal_properties_t *properties);
- virtual int openTuner(const radio_hal_band_config_t *config,
- bool audio,
- sp<TunerCallbackInterface> callback,
- sp<TunerInterface>& tuner);
- virtual int closeTuner(sp<TunerInterface>& tuner);
-
- class Tuner : public TunerInterface, public virtual ITunerCallback
- {
- public:
- Tuner(sp<TunerCallbackInterface> callback, sp<RadioHalHidl> module);
-
- // TunerInterface
- virtual int setConfiguration(const radio_hal_band_config_t *config);
- virtual int getConfiguration(radio_hal_band_config_t *config);
- virtual int scan(radio_direction_t direction, bool skip_sub_channel);
- virtual int step(radio_direction_t direction, bool skip_sub_channel);
- virtual int tune(unsigned int channel, unsigned int sub_channel);
- virtual int cancel();
- virtual int getProgramInformation(radio_program_info_t *info);
-
- // ITunerCallback
- virtual Return<void> hardwareFailure();
- virtual Return<void> configChange(Result result, const BandConfig& config);
- virtual Return<void> tuneComplete(Result result, const ProgramInfo& info);
- virtual Return<void> afSwitch(const ProgramInfo& info);
- virtual Return<void> antennaStateChange(bool connected);
- virtual Return<void> trafficAnnouncement(bool active);
- virtual Return<void> emergencyAnnouncement(bool active);
- virtual Return<void> newMetadata(uint32_t channel, uint32_t subChannel,
- const ::android::hardware::hidl_vec<MetaData>& metadata);
-
- void setHalTuner(sp<ITuner>& halTuner);
- sp<ITuner> getHalTuner() { return mHalTuner; }
-
- private:
- virtual ~Tuner();
-
- void onCallback(radio_hal_event_t *halEvent) const;
- void handleHwFailure();
- void sendHwFailureEvent() const;
-
- sp<ITuner> mHalTuner;
- const sp<TunerCallbackInterface> mCallback;
- wp<RadioHalHidl> mParentModule;
- };
-
- sp<IBroadcastRadio> getService();
- void clearService();
-
-private:
- virtual ~RadioHalHidl();
-
- radio_class_t mClassId;
- sp<IBroadcastRadio> mHalModule;
-};
-
-} // namespace android
-
-#endif // ANDROID_HARDWARE_RADIO_HAL_HIDL_H
diff --git a/services/radio/RadioHalLegacy.cpp b/services/radio/RadioHalLegacy.cpp
deleted file mode 100644
index d50ccd4..0000000
--- a/services/radio/RadioHalLegacy.cpp
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "RadioHalLegacy"
-//#define LOG_NDEBUG 0
-
-#include <utils/Log.h>
-#include <utils/misc.h>
-#include "RadioHalLegacy.h"
-
-namespace android {
-
-const char *RadioHalLegacy::sClassModuleNames[] = {
- RADIO_HARDWARE_MODULE_ID_FM, /* corresponds to RADIO_CLASS_AM_FM */
- RADIO_HARDWARE_MODULE_ID_SAT, /* corresponds to RADIO_CLASS_SAT */
- RADIO_HARDWARE_MODULE_ID_DT, /* corresponds to RADIO_CLASS_DT */
-};
-
-/* static */
-sp<RadioInterface> RadioInterface::connectModule(radio_class_t classId)
-{
- return new RadioHalLegacy(classId);
-}
-
-RadioHalLegacy::RadioHalLegacy(radio_class_t classId)
- : RadioInterface(), mClassId(classId), mHwDevice(NULL)
-{
-}
-
-void RadioHalLegacy::onFirstRef()
-{
- const hw_module_t *mod;
- int rc;
- ALOGI("%s mClassId %d", __FUNCTION__, mClassId);
-
- mHwDevice = NULL;
-
- if ((mClassId < 0) ||
- (mClassId >= NELEM(sClassModuleNames))) {
- ALOGE("invalid class ID %d", mClassId);
- return;
- }
-
- ALOGI("%s RADIO_HARDWARE_MODULE_ID %s %s",
- __FUNCTION__, RADIO_HARDWARE_MODULE_ID, sClassModuleNames[mClassId]);
-
- rc = hw_get_module_by_class(RADIO_HARDWARE_MODULE_ID, sClassModuleNames[mClassId], &mod);
- if (rc != 0) {
- ALOGE("couldn't load radio module %s.%s (%s)",
- RADIO_HARDWARE_MODULE_ID, sClassModuleNames[mClassId], strerror(-rc));
- return;
- }
- rc = radio_hw_device_open(mod, &mHwDevice);
- if (rc != 0) {
- ALOGE("couldn't open radio hw device in %s.%s (%s)",
- RADIO_HARDWARE_MODULE_ID, "primary", strerror(-rc));
- mHwDevice = NULL;
- return;
- }
- if (mHwDevice->common.version != RADIO_DEVICE_API_VERSION_CURRENT) {
- ALOGE("wrong radio hw device version %04x", mHwDevice->common.version);
- radio_hw_device_close(mHwDevice);
- mHwDevice = NULL;
- }
-}
-
-RadioHalLegacy::~RadioHalLegacy()
-{
- if (mHwDevice != NULL) {
- radio_hw_device_close(mHwDevice);
- }
-}
-
-int RadioHalLegacy::getProperties(radio_hal_properties_t *properties)
-{
- if (mHwDevice == NULL) {
- return -ENODEV;
- }
-
- int rc = mHwDevice->get_properties(mHwDevice, properties);
- if (rc != 0) {
- ALOGE("could not read implementation properties");
- }
-
- return rc;
-}
-
-int RadioHalLegacy::openTuner(const radio_hal_band_config_t *config,
- bool audio,
- sp<TunerCallbackInterface> callback,
- sp<TunerInterface>& tuner)
-{
- if (mHwDevice == NULL) {
- return -ENODEV;
- }
- sp<Tuner> tunerImpl = new Tuner(callback);
-
- const struct radio_tuner *halTuner;
- int rc = mHwDevice->open_tuner(mHwDevice, config, audio,
- RadioHalLegacy::Tuner::callback, tunerImpl.get(),
- &halTuner);
- if (rc == 0) {
- tunerImpl->setHalTuner(halTuner);
- tuner = tunerImpl;
- }
- return rc;
-}
-
-int RadioHalLegacy::closeTuner(sp<TunerInterface>& tuner)
-{
- if (mHwDevice == NULL) {
- return -ENODEV;
- }
- if (tuner == 0) {
- return -EINVAL;
- }
- sp<Tuner> tunerImpl = (Tuner *)tuner.get();
- return mHwDevice->close_tuner(mHwDevice, tunerImpl->getHalTuner());
-}
-
-int RadioHalLegacy::Tuner::setConfiguration(const radio_hal_band_config_t *config)
-{
- if (mHalTuner == NULL) {
- return -ENODEV;
- }
- return mHalTuner->set_configuration(mHalTuner, config);
-}
-
-int RadioHalLegacy::Tuner::getConfiguration(radio_hal_band_config_t *config)
-{
- if (mHalTuner == NULL) {
- return -ENODEV;
- }
- return mHalTuner->get_configuration(mHalTuner, config);
-}
-
-int RadioHalLegacy::Tuner::scan(radio_direction_t direction, bool skip_sub_channel)
-{
- if (mHalTuner == NULL) {
- return -ENODEV;
- }
- return mHalTuner->scan(mHalTuner, direction, skip_sub_channel);
-}
-
-int RadioHalLegacy::Tuner::step(radio_direction_t direction, bool skip_sub_channel)
-{
- if (mHalTuner == NULL) {
- return -ENODEV;
- }
- return mHalTuner->step(mHalTuner, direction, skip_sub_channel);
-}
-
-int RadioHalLegacy::Tuner::tune(unsigned int channel, unsigned int sub_channel)
-{
- if (mHalTuner == NULL) {
- return -ENODEV;
- }
- return mHalTuner->tune(mHalTuner, channel, sub_channel);
-}
-
-int RadioHalLegacy::Tuner::cancel()
-{
- if (mHalTuner == NULL) {
- return -ENODEV;
- }
- return mHalTuner->cancel(mHalTuner);
-}
-
-int RadioHalLegacy::Tuner::getProgramInformation(radio_program_info_t *info)
-{
- if (mHalTuner == NULL) {
- return -ENODEV;
- }
- return mHalTuner->get_program_information(mHalTuner, info);
-}
-
-void RadioHalLegacy::Tuner::onCallback(radio_hal_event_t *halEvent)
-{
- if (mCallback != 0) {
- mCallback->onEvent(halEvent);
- }
-}
-
-//static
-void RadioHalLegacy::Tuner::callback(radio_hal_event_t *halEvent, void *cookie)
-{
- wp<RadioHalLegacy::Tuner> weak = wp<RadioHalLegacy::Tuner>((RadioHalLegacy::Tuner *)cookie);
- sp<RadioHalLegacy::Tuner> tuner = weak.promote();
- if (tuner != 0) {
- tuner->onCallback(halEvent);
- }
-}
-
-RadioHalLegacy::Tuner::Tuner(sp<TunerCallbackInterface> callback)
- : TunerInterface(), mHalTuner(NULL), mCallback(callback)
-{
-}
-
-
-RadioHalLegacy::Tuner::~Tuner()
-{
-}
-
-
-} // namespace android
diff --git a/services/radio/RadioHalLegacy.h b/services/radio/RadioHalLegacy.h
deleted file mode 100644
index 7d4831b..0000000
--- a/services/radio/RadioHalLegacy.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_RADIO_HAL_LEGACY_H
-#define ANDROID_HARDWARE_RADIO_HAL_LEGACY_H
-
-#include <utils/RefBase.h>
-#include <hardware/radio.h>
-#include "RadioInterface.h"
-#include "TunerInterface.h"
-#include "TunerCallbackInterface.h"
-
-namespace android {
-
-class RadioHalLegacy : public RadioInterface
-{
-public:
- RadioHalLegacy(radio_class_t classId);
-
- // RadioInterface
- virtual int getProperties(radio_hal_properties_t *properties);
- virtual int openTuner(const radio_hal_band_config_t *config,
- bool audio,
- sp<TunerCallbackInterface> callback,
- sp<TunerInterface>& tuner);
- virtual int closeTuner(sp<TunerInterface>& tuner);
-
- // RefBase
- virtual void onFirstRef();
-
- class Tuner : public TunerInterface
- {
- public:
- Tuner(sp<TunerCallbackInterface> callback);
-
- virtual int setConfiguration(const radio_hal_band_config_t *config);
- virtual int getConfiguration(radio_hal_band_config_t *config);
- virtual int scan(radio_direction_t direction, bool skip_sub_channel);
- virtual int step(radio_direction_t direction, bool skip_sub_channel);
- virtual int tune(unsigned int channel, unsigned int sub_channel);
- virtual int cancel();
- virtual int getProgramInformation(radio_program_info_t *info);
-
- static void callback(radio_hal_event_t *halEvent, void *cookie);
- void onCallback(radio_hal_event_t *halEvent);
-
- void setHalTuner(const struct radio_tuner *halTuner) { mHalTuner = halTuner; }
- const struct radio_tuner *getHalTuner() { return mHalTuner; }
-
- private:
- virtual ~Tuner();
-
- const struct radio_tuner *mHalTuner;
- sp<TunerCallbackInterface> mCallback;
- };
-
-protected:
- virtual ~RadioHalLegacy();
-
-private:
- static const char * sClassModuleNames[];
-
- radio_class_t mClassId;
- struct radio_hw_device *mHwDevice;
-};
-
-} // namespace android
-
-#endif // ANDROID_HARDWARE_RADIO_HAL_LEGACY_H
diff --git a/services/radio/RadioInterface.h b/services/radio/RadioInterface.h
deleted file mode 100644
index fcfb4d5..0000000
--- a/services/radio/RadioInterface.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_RADIO_INTERFACE_H
-#define ANDROID_HARDWARE_RADIO_INTERFACE_H
-
-#include <utils/RefBase.h>
-#include <system/radio.h>
-#include "TunerInterface.h"
-#include "TunerCallbackInterface.h"
-
-namespace android {
-
-class RadioInterface : public virtual RefBase
-{
-public:
- /* get a sound trigger HAL instance */
- static sp<RadioInterface> connectModule(radio_class_t classId);
-
- /*
- * Retrieve implementation properties.
- *
- * arguments:
- * - properties: where to return the module properties
- *
- * returns:
- * 0 if no error
- * -EINVAL if invalid arguments are passed
- */
- virtual int getProperties(radio_hal_properties_t *properties) = 0;
-
- /*
- * Open a tuner interface for the requested configuration.
- * If no other tuner is opened, this will activate the radio module.
- *
- * arguments:
- * - config: the band configuration to apply
- * - audio: this tuner will be used for live radio listening and should be connected to
- * the radio audio source.
- * - callback: the event callback
- * - cookie: the cookie to pass when calling the callback
- * - tuner: where to return the tuner interface
- *
- * returns:
- * 0 if HW was powered up and configuration could be applied
- * -EINVAL if configuration requested is invalid
- * -ENOSYS if called out of sequence
- *
- * Callback function with event RADIO_EVENT_CONFIG MUST be called once the
- * configuration is applied or a failure occurs or after a time out.
- */
- virtual int openTuner(const radio_hal_band_config_t *config,
- bool audio,
- sp<TunerCallbackInterface> callback,
- sp<TunerInterface>& tuner) = 0;
-
- /*
- * Close a tuner interface.
- * If the last tuner is closed, the radio module is deactivated.
- *
- * arguments:
- * - tuner: the tuner interface to close
- *
- * returns:
- * 0 if powered down successfully.
- * -EINVAL if an invalid argument is passed
- * -ENOSYS if called out of sequence
- */
- virtual int closeTuner(sp<TunerInterface>& tuner) = 0;
-
-protected:
- RadioInterface() {}
- virtual ~RadioInterface() {}
-};
-
-} // namespace android
-
-#endif // ANDROID_HARDWARE_RADIO_INTERFACE_H
diff --git a/services/radio/RadioRegions.h b/services/radio/RadioRegions.h
deleted file mode 100644
index d40ee83..0000000
--- a/services/radio/RadioRegions.h
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_RADIO_REGIONS_H
-#define ANDROID_HARDWARE_RADIO_REGIONS_H
-
-namespace android {
-
-#define RADIO_BAND_LOWER_FM_ITU1 87500
-#define RADIO_BAND_UPPER_FM_ITU1 108000
-#define RADIO_BAND_SPACING_FM_ITU1 100
-
-#define RADIO_BAND_LOWER_FM_ITU2 87900
-#define RADIO_BAND_UPPER_FM_ITU2 107900
-#define RADIO_BAND_SPACING_FM_ITU2 200
-
-#define RADIO_BAND_LOWER_FM_JAPAN 76000
-#define RADIO_BAND_UPPER_FM_JAPAN 90000
-#define RADIO_BAND_SPACING_FM_JAPAN 100
-
-#define RADIO_BAND_LOWER_FM_OIRT 65800
-#define RADIO_BAND_UPPER_FM_OIRT 74000
-#define RADIO_BAND_SPACING_FM_OIRT 10
-
-#define RADIO_BAND_LOWER_LW 153
-#define RADIO_BAND_UPPER_LW 279
-#define RADIO_BAND_SPACING_LW 9
-
-#define RADIO_BAND_LOWER_MW_IUT1 531
-#define RADIO_BAND_UPPER_MW_ITU1 1611
-#define RADIO_BAND_SPACING_MW_ITU1 9
-
-#define RADIO_BAND_LOWER_MW_IUT2 540
-#define RADIO_BAND_UPPER_MW_ITU2 1610
-#define RADIO_BAND_SPACING_MW_ITU2 10
-
-#define RADIO_BAND_LOWER_SW 2300
-#define RADIO_BAND_UPPER_SW 26100
-#define RADIO_BAND_SPACING_SW 5
-
-
-#ifndef ARRAY_SIZE
-#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
-#endif
-
-const radio_band_config_t sKnownRegionConfigs[] = {
- { // FM ITU 1
- RADIO_REGION_ITU_1,
- {
- RADIO_BAND_FM,
- false,
- RADIO_BAND_LOWER_FM_ITU1,
- RADIO_BAND_UPPER_FM_ITU1,
- 1,
- {RADIO_BAND_SPACING_FM_ITU1},
- {
- {
- RADIO_DEEMPHASIS_50,
- true,
- RADIO_RDS_WORLD,
- true,
- true,
- true,
- }
- }
- }
- },
- { // FM Americas
- RADIO_REGION_ITU_2,
- {
- RADIO_BAND_FM,
- false,
- RADIO_BAND_LOWER_FM_ITU2,
- RADIO_BAND_UPPER_FM_ITU2,
- 1,
- {RADIO_BAND_SPACING_FM_ITU2},
- {
- {
- RADIO_DEEMPHASIS_75,
- true,
- RADIO_RDS_US,
- true,
- true,
- true,
- }
- }
- }
- },
- { // FM Japan
- RADIO_REGION_JAPAN,
- {
- RADIO_BAND_FM,
- false,
- RADIO_BAND_LOWER_FM_JAPAN,
- RADIO_BAND_UPPER_FM_JAPAN,
- 1,
- {RADIO_BAND_SPACING_FM_JAPAN},
- {
- {
- RADIO_DEEMPHASIS_50,
- true,
- RADIO_RDS_WORLD,
- true,
- true,
- true,
- }
- }
- }
- },
- { // FM Korea
- RADIO_REGION_KOREA,
- {
- RADIO_BAND_FM,
- false,
- RADIO_BAND_LOWER_FM_ITU1,
- RADIO_BAND_UPPER_FM_ITU1,
- 1,
- {RADIO_BAND_SPACING_FM_ITU1},
- {
- {
- RADIO_DEEMPHASIS_75,
- true,
- RADIO_RDS_WORLD,
- true,
- true,
- true,
- }
- }
- }
- },
- { // FM OIRT
- RADIO_REGION_OIRT,
- {
- RADIO_BAND_FM,
- false,
- RADIO_BAND_LOWER_FM_OIRT,
- RADIO_BAND_UPPER_FM_OIRT,
- 1,
- {RADIO_BAND_SPACING_FM_OIRT},
- {
- {
- RADIO_DEEMPHASIS_50,
- true,
- RADIO_RDS_WORLD,
- true,
- true,
- true,
- }
- }
- }
- },
- { // FM US HD radio
- RADIO_REGION_ITU_2,
- {
- RADIO_BAND_FM_HD,
- false,
- RADIO_BAND_LOWER_FM_ITU2,
- RADIO_BAND_UPPER_FM_ITU2,
- 1,
- {RADIO_BAND_SPACING_FM_ITU2},
- {
- {
- RADIO_DEEMPHASIS_75,
- true,
- RADIO_RDS_US,
- true,
- true,
- true,
- }
- }
- }
- },
- { // AM LW
- RADIO_REGION_ITU_1,
- {
- RADIO_BAND_AM,
- false,
- RADIO_BAND_LOWER_LW,
- RADIO_BAND_UPPER_LW,
- 1,
- {RADIO_BAND_SPACING_LW},
- {
- }
- }
- },
- { // AM SW
- RADIO_REGION_ITU_1,
- {
- RADIO_BAND_AM,
- false,
- RADIO_BAND_LOWER_SW,
- RADIO_BAND_UPPER_SW,
- 1,
- {RADIO_BAND_SPACING_SW},
- {
- }
- }
- },
- { // AM MW ITU1
- RADIO_REGION_ITU_1,
- {
- RADIO_BAND_AM,
- false,
- RADIO_BAND_LOWER_MW_IUT1,
- RADIO_BAND_UPPER_MW_ITU1,
- 1,
- {RADIO_BAND_SPACING_MW_ITU1},
- {
- }
- }
- },
- { // AM MW ITU2
- RADIO_REGION_ITU_2,
- {
- RADIO_BAND_AM,
- false,
- RADIO_BAND_LOWER_MW_IUT2,
- RADIO_BAND_UPPER_MW_ITU2,
- 1,
- {RADIO_BAND_SPACING_MW_ITU2},
- {
- }
- }
- }
-};
-
-
-} // namespace android
-
-#endif // ANDROID_HARDWARE_RADIO_REGIONS_H
diff --git a/services/radio/RadioService.cpp b/services/radio/RadioService.cpp
deleted file mode 100644
index beb7c09..0000000
--- a/services/radio/RadioService.cpp
+++ /dev/null
@@ -1,936 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "RadioService"
-//#define LOG_NDEBUG 0
-
-#include <stdio.h>
-#include <string.h>
-#include <sys/types.h>
-#include <pthread.h>
-
-#include <system/audio.h>
-#include <system/audio_policy.h>
-#include <system/radio.h>
-#include <system/radio_metadata.h>
-#include <cutils/atomic.h>
-#include <cutils/properties.h>
-#include <hardware/hardware.h>
-#include <utils/Errors.h>
-#include <utils/Log.h>
-#include <binder/IServiceManager.h>
-#include <binder/MemoryBase.h>
-#include <binder/MemoryHeapBase.h>
-#include <binder/PermissionCache.h>
-#include <hardware/radio.h>
-#include <media/AudioSystem.h>
-#include "RadioService.h"
-#include "RadioRegions.h"
-
-namespace android {
-
-static const char kRadioTunerAudioDeviceName[] = "Radio tuner source";
-
-static const String16 RADIO_PERMISSION("android.permission.ACCESS_FM_RADIO");
-
-RadioService::RadioService()
- : BnRadioService(), mNextUniqueId(1)
-{
- ALOGI("%s", __FUNCTION__);
-}
-
-void RadioService::onFirstRef()
-{
- ALOGI("%s", __FUNCTION__);
-
- sp<RadioInterface> dev = RadioInterface::connectModule(RADIO_CLASS_AM_FM);
-
- if (dev == 0) {
- return;
- }
- struct radio_hal_properties halProperties;
- int rc = dev->getProperties(&halProperties);
- if (rc != 0) {
- ALOGE("could not read implementation properties");
- return;
- }
-
- radio_properties_t properties;
- properties.handle =
- (radio_handle_t)android_atomic_inc(&mNextUniqueId);
- convertProperties(&properties, &halProperties);
-
- ALOGI("loaded default module %s, ver %s, handle %d", properties.product,
- properties.version, properties.handle);
-
- sp<Module> module = new Module(dev, properties);
- mModules.add(properties.handle, module);
-}
-
-RadioService::~RadioService()
-{
-}
-
-status_t RadioService::listModules(struct radio_properties *properties,
- uint32_t *numModules)
-{
- if (!PermissionCache::checkCallingPermission(RADIO_PERMISSION)) {
- return PERMISSION_DENIED;
- }
- ALOGV("listModules");
-
- AutoMutex lock(mServiceLock);
- if (numModules == NULL || (*numModules != 0 && properties == NULL)) {
- return BAD_VALUE;
- }
- uint32_t maxModules = *numModules;
- *numModules = mModules.size();
- for (size_t i = 0; i < mModules.size() && i < maxModules; i++) {
- properties[i] = mModules.valueAt(i)->properties();
- }
- return NO_ERROR;
-}
-
-status_t RadioService::attach(radio_handle_t handle,
- const sp<IRadioClient>& client,
- const struct radio_band_config *config,
- bool withAudio,
- sp<IRadio>& radio)
-{
- if (!PermissionCache::checkCallingPermission(RADIO_PERMISSION)) {
- return PERMISSION_DENIED;
- }
- ALOGV("%s %d config %p withAudio %d", __FUNCTION__, handle, config, withAudio);
-
- AutoMutex lock(mServiceLock);
- radio.clear();
- if (client == 0) {
- return BAD_VALUE;
- }
- ssize_t index = mModules.indexOfKey(handle);
- if (index < 0) {
- return BAD_VALUE;
- }
- sp<Module> module = mModules.valueAt(index);
-
- if (config == NULL) {
- config = module->getDefaultConfig();
- if (config == NULL) {
- return INVALID_OPERATION;
- }
- }
- ALOGV("%s region %d type %d", __FUNCTION__, config->region, config->band.type);
-
- radio = module->addClient(client, config, withAudio);
-
- if (radio == 0) {
- return NO_INIT;
- }
- return NO_ERROR;
-}
-
-
-static const int kDumpLockRetries = 50;
-static const int kDumpLockSleep = 60000;
-
-static bool tryLock(Mutex& mutex)
-{
- bool locked = false;
- for (int i = 0; i < kDumpLockRetries; ++i) {
- if (mutex.tryLock() == NO_ERROR) {
- locked = true;
- break;
- }
- usleep(kDumpLockSleep);
- }
- return locked;
-}
-
-status_t RadioService::dump(int fd, const Vector<String16>& args __unused) {
- String8 result;
- if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
- result.appendFormat("Permission Denial: can't dump RadioService");
- write(fd, result.string(), result.size());
- } else {
- bool locked = tryLock(mServiceLock);
- // failed to lock - RadioService is probably deadlocked
- if (!locked) {
- result.append("RadioService may be deadlocked\n");
- write(fd, result.string(), result.size());
- }
-
- if (locked) mServiceLock.unlock();
- }
- return NO_ERROR;
-}
-
-status_t RadioService::onTransact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
- return BnRadioService::onTransact(code, data, reply, flags);
-}
-
-
-/* static */
-void RadioService::convertProperties(radio_properties_t *properties,
- const radio_hal_properties_t *halProperties)
-{
- memset(properties, 0, sizeof(struct radio_properties));
- properties->class_id = halProperties->class_id;
- strlcpy(properties->implementor, halProperties->implementor,
- RADIO_STRING_LEN_MAX);
- strlcpy(properties->product, halProperties->product,
- RADIO_STRING_LEN_MAX);
- strlcpy(properties->version, halProperties->version,
- RADIO_STRING_LEN_MAX);
- strlcpy(properties->serial, halProperties->serial,
- RADIO_STRING_LEN_MAX);
- properties->num_tuners = halProperties->num_tuners;
- properties->num_audio_sources = halProperties->num_audio_sources;
- properties->supports_capture = halProperties->supports_capture;
-
- for (size_t i = 0; i < ARRAY_SIZE(sKnownRegionConfigs); i++) {
- const radio_hal_band_config_t *band = &sKnownRegionConfigs[i].band;
- size_t j;
- for (j = 0; j < halProperties->num_bands; j++) {
- const radio_hal_band_config_t *halBand = &halProperties->bands[j];
- size_t k;
- if (band->type != halBand->type) continue;
- if (band->lower_limit < halBand->lower_limit) continue;
- if (band->upper_limit > halBand->upper_limit) continue;
- for (k = 0; k < halBand->num_spacings; k++) {
- if (band->spacings[0] == halBand->spacings[k]) break;
- }
- if (k == halBand->num_spacings) continue;
- if (band->type == RADIO_BAND_AM) break;
- if ((band->fm.deemphasis & halBand->fm.deemphasis) == 0) continue;
- if (halBand->fm.rds == 0) break;
- if ((band->fm.rds & halBand->fm.rds) != 0) break;
- }
- if (j == halProperties->num_bands) continue;
-
- ALOGI("convertProperties() Adding band type %d region %d",
- sKnownRegionConfigs[i].band.type , sKnownRegionConfigs[i].region);
-
- memcpy(&properties->bands[properties->num_bands++],
- &sKnownRegionConfigs[i],
- sizeof(radio_band_config_t));
- }
-}
-
-#undef LOG_TAG
-#define LOG_TAG "RadioService::CallbackThread"
-
-RadioService::CallbackThread::CallbackThread(const wp<ModuleClient>& moduleClient)
- : mModuleClient(moduleClient), mMemoryDealer(new MemoryDealer(1024 * 1024, "RadioService"))
-{
-}
-
-RadioService::CallbackThread::~CallbackThread()
-{
- mEventQueue.clear();
-}
-
-void RadioService::CallbackThread::onFirstRef()
-{
- run("RadioService cbk", ANDROID_PRIORITY_URGENT_AUDIO);
-}
-
-bool RadioService::CallbackThread::threadLoop()
-{
- while (!exitPending()) {
- sp<IMemory> eventMemory;
- sp<ModuleClient> moduleClient;
- {
- Mutex::Autolock _l(mCallbackLock);
- while (mEventQueue.isEmpty() && !exitPending()) {
- ALOGV("CallbackThread::threadLoop() sleep");
- mCallbackCond.wait(mCallbackLock);
- ALOGV("CallbackThread::threadLoop() wake up");
- }
- if (exitPending()) {
- break;
- }
- eventMemory = mEventQueue[0];
- mEventQueue.removeAt(0);
- moduleClient = mModuleClient.promote();
- }
- if (moduleClient != 0) {
- moduleClient->onCallbackEvent(eventMemory);
- eventMemory.clear();
- }
- }
- return false;
-}
-
-void RadioService::CallbackThread::exit()
-{
- Mutex::Autolock _l(mCallbackLock);
- requestExit();
- mCallbackCond.broadcast();
-}
-
-sp<IMemory> RadioService::CallbackThread::prepareEvent(radio_hal_event_t *halEvent)
-{
- sp<IMemory> eventMemory;
-
- // The event layout in shared memory is:
- // sizeof(struct radio_event) bytes : the event itself
- // 4 bytes : metadata size or 0
- // N bytes : metadata if present
- uint32_t metadataOffset = sizeof(struct radio_event) + sizeof(uint32_t);
- uint32_t metadataSize = 0;
-
- switch (halEvent->type) {
- case RADIO_EVENT_TUNED:
- case RADIO_EVENT_AF_SWITCH:
- if (radio_metadata_check(halEvent->info.metadata) == 0) {
- metadataSize = (uint32_t)radio_metadata_get_size(halEvent->info.metadata);
- }
- break;
- case RADIO_EVENT_METADATA:
- if (radio_metadata_check(halEvent->metadata) != 0) {
- return eventMemory;
- }
- metadataSize = (uint32_t)radio_metadata_get_size(halEvent->metadata);
- break;
- default:
- break;
- }
-
- eventMemory = mMemoryDealer->allocate(metadataOffset + metadataSize);
- if (eventMemory == 0 || eventMemory->pointer() == NULL) {
- eventMemory.clear();
- return eventMemory;
- }
-
- struct radio_event *event = (struct radio_event *)eventMemory->pointer();
-
- *(uint32_t *)((uint8_t *)event + metadataOffset - sizeof(uint32_t)) = metadataSize;
-
- event->type = halEvent->type;
- event->status = halEvent->status;
-
- switch (event->type) {
- case RADIO_EVENT_CONFIG:
- event->config.band = halEvent->config;
- break;
- case RADIO_EVENT_TUNED:
- case RADIO_EVENT_AF_SWITCH:
- event->info = halEvent->info;
- if (metadataSize != 0) {
- memcpy((uint8_t *)event + metadataOffset, halEvent->info.metadata, metadataSize);
- }
- break;
- case RADIO_EVENT_TA:
- case RADIO_EVENT_EA:
- case RADIO_EVENT_ANTENNA:
- case RADIO_EVENT_CONTROL:
- event->on = halEvent->on;
- break;
- case RADIO_EVENT_METADATA:
- if (metadataSize != 0) {
- memcpy((uint8_t *)event + metadataOffset, halEvent->metadata, metadataSize);
- }
- break;
- case RADIO_EVENT_HW_FAILURE:
- default:
- break;
- }
-
- return eventMemory;
-}
-
-void RadioService::CallbackThread::sendEvent(radio_hal_event_t *event)
- {
- sp<IMemory> eventMemory = prepareEvent(event);
- if (eventMemory == 0) {
- return;
- }
-
- AutoMutex lock(mCallbackLock);
- mEventQueue.add(eventMemory);
- mCallbackCond.signal();
- ALOGV("%s DONE", __FUNCTION__);
-}
-
-
-#undef LOG_TAG
-#define LOG_TAG "RadioService::Module"
-
-RadioService::Module::Module(sp<RadioInterface> hwDevice, radio_properties properties)
- : mHwDevice(hwDevice), mProperties(properties), mMute(true)
-{
-}
-
-RadioService::Module::~Module() {
- mHwDevice.clear();
- mModuleClients.clear();
-}
-
-status_t RadioService::Module::dump(int fd __unused, const Vector<String16>& args __unused) {
- String8 result;
- return NO_ERROR;
-}
-
-sp<RadioService::ModuleClient> RadioService::Module::addClient(const sp<IRadioClient>& client,
- const struct radio_band_config *config,
- bool audio)
-{
- ALOGV("addClient() %p config %p product %s", this, config, mProperties.product);
-
- AutoMutex lock(mLock);
- sp<ModuleClient> moduleClient;
- int ret;
-
- if (mHwDevice == 0) {
- return moduleClient;
- }
-
- for (size_t i = 0; i < mModuleClients.size(); i++) {
- if (mModuleClients[i]->client() == client) {
- // client already connected: reject
- return moduleClient;
- }
- }
- moduleClient = new ModuleClient(this, client, config, audio);
-
- struct radio_hal_band_config halConfig;
- halConfig = config->band;
-
- // Tuner preemption logic:
- // There is a limited amount of tuners and a limited amount of radio audio sources per module.
- // The minimum is one tuner and one audio source.
- // The numbers of tuners and sources are indicated in the module properties.
- // NOTE: current framework implementation only supports one radio audio source.
- // It is possible to open more than one tuner at a time but only one tuner can be connected
- // to the radio audio source (AUDIO_DEVICE_IN_FM_TUNER).
- // The base rule is that a newly connected tuner always wins, i.e. always gets a tuner
- // and can use the audio source if requested.
- // If another client is preempted, it is notified by a callback with RADIO_EVENT_CONTROL
- // indicating loss of control.
- // - If the newly connected client requests the audio source (audio == true):
- // - if an audio source is available
- // no problem
- // - if not:
- // the oldest client in the list using audio is preempted.
- // - If the newly connected client does not request the audio source (audio == false):
- // - if a tuner is available
- // no problem
- // - if not:
- // The oldest client not using audio is preempted first and if none is found the
- // the oldest client using audio is preempted.
- // Each time a tuner using the audio source is opened or closed, the audio policy manager is
- // notified of the connection or disconnection of AUDIO_DEVICE_IN_FM_TUNER.
-
- sp<ModuleClient> oldestTuner;
- sp<ModuleClient> oldestAudio;
- size_t allocatedTuners = 0;
- size_t allocatedAudio = 0;
- for (size_t i = 0; i < mModuleClients.size(); i++) {
- if (mModuleClients[i]->getTuner() != NULL) {
- if (mModuleClients[i]->audio()) {
- if (oldestAudio == 0) {
- oldestAudio = mModuleClients[i];
- }
- allocatedAudio++;
- } else {
- if (oldestTuner == 0) {
- oldestTuner = mModuleClients[i];
- }
- allocatedTuners++;
- }
- }
- }
-
- sp<TunerInterface> halTuner;
- sp<ModuleClient> preemtedClient;
- if (audio) {
- if (allocatedAudio >= mProperties.num_audio_sources) {
- ALOG_ASSERT(oldestAudio != 0, "addClient() allocatedAudio/oldestAudio mismatch");
- preemtedClient = oldestAudio;
- }
- } else {
- if (allocatedAudio + allocatedTuners >= mProperties.num_tuners) {
- if (allocatedTuners != 0) {
- ALOG_ASSERT(oldestTuner != 0, "addClient() allocatedTuners/oldestTuner mismatch");
- preemtedClient = oldestTuner;
- } else {
- ALOG_ASSERT(oldestAudio != 0, "addClient() allocatedAudio/oldestAudio mismatch");
- preemtedClient = oldestAudio;
- }
- }
- }
- if (preemtedClient != 0) {
- halTuner = preemtedClient->getTuner();
- sp<TunerInterface> clear;
- preemtedClient->setTuner(clear);
- mHwDevice->closeTuner(halTuner);
- if (preemtedClient->audio()) {
- notifyDeviceConnection(false, "");
- }
- }
-
- ret = mHwDevice->openTuner(&halConfig, audio,
- moduleClient,
- halTuner);
- if (ret == 0) {
- ALOGV("addClient() setTuner %p", halTuner.get());
- moduleClient->setTuner(halTuner);
- mModuleClients.add(moduleClient);
- if (audio) {
- notifyDeviceConnection(true, "");
- }
- ALOGV("addClient() DONE moduleClient %p", moduleClient.get());
- } else {
- ALOGW("%s open_tuner failed with error %d", __FUNCTION__, ret);
- moduleClient.clear();
- }
-
- return moduleClient;
-}
-
-void RadioService::Module::removeClient(const sp<ModuleClient>& moduleClient) {
- ALOGV("removeClient()");
- AutoMutex lock(mLock);
- int ret;
- ssize_t index = -1;
-
- for (size_t i = 0; i < mModuleClients.size(); i++) {
- if (mModuleClients[i] == moduleClient) {
- index = i;
- break;
- }
- }
- if (index == -1) {
- return;
- }
-
- mModuleClients.removeAt(index);
- sp<TunerInterface> halTuner = moduleClient->getTuner();
- if (halTuner == NULL) {
- return;
- }
-
- if (mHwDevice != 0) {
- mHwDevice->closeTuner(halTuner);
- }
-
- if (moduleClient->audio()) {
- notifyDeviceConnection(false, "");
- }
-
- mMute = true;
-
- if (mModuleClients.isEmpty()) {
- return;
- }
-
- if (mHwDevice == 0) {
- return;
- }
-
- // Tuner reallocation logic:
- // When a client is removed and was controlling a tuner, this tuner will be allocated to a
- // previously preempted client. This client will be notified by a callback with
- // RADIO_EVENT_CONTROL indicating gain of control.
- // - If a preempted client is waiting for an audio source and one becomes available:
- // Allocate the tuner to the most recently added client waiting for an audio source
- // - If not:
- // Allocate the tuner to the most recently added client.
- // Each time a tuner using the audio source is opened or closed, the audio policy manager is
- // notified of the connection or disconnection of AUDIO_DEVICE_IN_FM_TUNER.
-
- sp<ModuleClient> youngestClient;
- sp<ModuleClient> youngestClientAudio;
- size_t allocatedTuners = 0;
- size_t allocatedAudio = 0;
- for (ssize_t i = mModuleClients.size() - 1; i >= 0; i--) {
- if (mModuleClients[i]->getTuner() == NULL) {
- if (mModuleClients[i]->audio()) {
- if (youngestClientAudio == 0) {
- youngestClientAudio = mModuleClients[i];
- }
- } else {
- if (youngestClient == 0) {
- youngestClient = mModuleClients[i];
- }
- }
- } else {
- if (mModuleClients[i]->audio()) {
- allocatedAudio++;
- } else {
- allocatedTuners++;
- }
- }
- }
-
- ALOG_ASSERT(allocatedTuners + allocatedAudio < mProperties.num_tuners,
- "removeClient() removed client but no tuner available");
-
- ALOG_ASSERT(!moduleClient->audio() || allocatedAudio < mProperties.num_audio_sources,
- "removeClient() removed audio client but no tuner with audio available");
-
- if (allocatedAudio < mProperties.num_audio_sources && youngestClientAudio != 0) {
- youngestClient = youngestClientAudio;
- }
-
- ALOG_ASSERT(youngestClient != 0, "removeClient() removed client no candidate found for tuner");
-
- struct radio_hal_band_config halConfig = youngestClient->halConfig();
- ret = mHwDevice->openTuner(&halConfig, youngestClient->audio(),
- moduleClient,
- halTuner);
-
- if (ret == 0) {
- youngestClient->setTuner(halTuner);
- if (youngestClient->audio()) {
- notifyDeviceConnection(true, "");
- }
- }
-}
-
-status_t RadioService::Module::setMute(bool mute)
-{
- Mutex::Autolock _l(mLock);
- if (mute != mMute) {
- mMute = mute;
- //TODO notifify audio policy manager of media activity on radio audio device
- }
- return NO_ERROR;
-}
-
-status_t RadioService::Module::getMute(bool *mute)
-{
- Mutex::Autolock _l(mLock);
- *mute = mMute;
- return NO_ERROR;
-}
-
-
-const struct radio_band_config *RadioService::Module::getDefaultConfig() const
-{
- if (mProperties.num_bands == 0) {
- return NULL;
- }
- return &mProperties.bands[0];
-}
-
-void RadioService::Module::notifyDeviceConnection(bool connected,
- const char *address) {
- int64_t token = IPCThreadState::self()->clearCallingIdentity();
- AudioSystem::setDeviceConnectionState(AUDIO_DEVICE_IN_FM_TUNER,
- connected ? AUDIO_POLICY_DEVICE_STATE_AVAILABLE :
- AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
- address, kRadioTunerAudioDeviceName);
- IPCThreadState::self()->restoreCallingIdentity(token);
-}
-
-#undef LOG_TAG
-#define LOG_TAG "RadioService::ModuleClient"
-
-RadioService::ModuleClient::ModuleClient(const sp<Module>& module,
- const sp<IRadioClient>& client,
- const struct radio_band_config *config,
- bool audio)
- : mModule(module), mClient(client), mConfig(*config), mAudio(audio), mTuner(0)
-{
-}
-
-void RadioService::ModuleClient::onFirstRef()
-{
- mCallbackThread = new CallbackThread(this);
- IInterface::asBinder(mClient)->linkToDeath(this);
-}
-
-RadioService::ModuleClient::~ModuleClient() {
- if (mClient != 0) {
- IInterface::asBinder(mClient)->unlinkToDeath(this);
- mClient.clear();
- }
- if (mCallbackThread != 0) {
- mCallbackThread->exit();
- }
-}
-
-void RadioService::ModuleClient::onEvent(radio_hal_event_t *halEvent)
-{
- mCallbackThread->sendEvent(halEvent);
-}
-
-status_t RadioService::ModuleClient::dump(int fd __unused,
- const Vector<String16>& args __unused) {
- String8 result;
- return NO_ERROR;
-}
-
-void RadioService::ModuleClient::detach() {
- ALOGV("%s", __FUNCTION__);
- sp<ModuleClient> strongMe = this;
- {
- AutoMutex lock(mLock);
- if (mClient != 0) {
- IInterface::asBinder(mClient)->unlinkToDeath(this);
- mClient.clear();
- }
- }
- sp<Module> module = mModule.promote();
- if (module == 0) {
- return;
- }
- module->removeClient(this);
-}
-
-radio_hal_band_config_t RadioService::ModuleClient::halConfig() const
-{
- AutoMutex lock(mLock);
- ALOGV("%s locked", __FUNCTION__);
- return mConfig.band;
-}
-
-sp<TunerInterface>& RadioService::ModuleClient::getTuner()
-{
- AutoMutex lock(mLock);
- ALOGV("%s locked", __FUNCTION__);
- return mTuner;
-}
-
-void RadioService::ModuleClient::setTuner(sp<TunerInterface>& tuner)
-{
- ALOGV("%s %p", __FUNCTION__, this);
-
- AutoMutex lock(mLock);
- mTuner = tuner;
- ALOGV("%s locked", __FUNCTION__);
-
- radio_hal_event_t event;
- event.type = RADIO_EVENT_CONTROL;
- event.status = 0;
- event.on = mTuner != 0;
- mCallbackThread->sendEvent(&event);
- ALOGV("%s DONE", __FUNCTION__);
-
-}
-
-status_t RadioService::ModuleClient::setConfiguration(const struct radio_band_config *config)
-{
- if (!PermissionCache::checkCallingPermission(RADIO_PERMISSION)) {
- return PERMISSION_DENIED;
- }
- AutoMutex lock(mLock);
- status_t status = NO_ERROR;
- ALOGV("%s locked", __FUNCTION__);
-
- if (mTuner != 0) {
- struct radio_hal_band_config halConfig;
- halConfig = config->band;
- status = (status_t)mTuner->setConfiguration(&halConfig);
- if (status == NO_ERROR) {
- mConfig = *config;
- }
- } else {
- mConfig = *config;
- status = INVALID_OPERATION;
- }
-
- return status;
-}
-
-status_t RadioService::ModuleClient::getConfiguration(struct radio_band_config *config)
-{
- if (!PermissionCache::checkCallingPermission(RADIO_PERMISSION)) {
- return PERMISSION_DENIED;
- }
- AutoMutex lock(mLock);
- status_t status = NO_ERROR;
- ALOGV("%s locked", __FUNCTION__);
-
- if (mTuner != 0) {
- struct radio_hal_band_config halConfig;
- status = (status_t)mTuner->getConfiguration(&halConfig);
- if (status == NO_ERROR) {
- mConfig.band = halConfig;
- }
- }
- *config = mConfig;
-
- return status;
-}
-
-status_t RadioService::ModuleClient::setMute(bool mute)
-{
- if (!PermissionCache::checkCallingPermission(RADIO_PERMISSION)) {
- return PERMISSION_DENIED;
- }
- sp<Module> module;
- {
- Mutex::Autolock _l(mLock);
- ALOGV("%s locked", __FUNCTION__);
- if (mTuner == 0 || !mAudio) {
- return INVALID_OPERATION;
- }
- module = mModule.promote();
- if (module == 0) {
- return NO_INIT;
- }
- }
- module->setMute(mute);
- return NO_ERROR;
-}
-
-status_t RadioService::ModuleClient::getMute(bool *mute)
-{
- if (!PermissionCache::checkCallingPermission(RADIO_PERMISSION)) {
- return PERMISSION_DENIED;
- }
- sp<Module> module;
- {
- Mutex::Autolock _l(mLock);
- ALOGV("%s locked", __FUNCTION__);
- module = mModule.promote();
- if (module == 0) {
- return NO_INIT;
- }
- }
- return module->getMute(mute);
-}
-
-status_t RadioService::ModuleClient::scan(radio_direction_t direction, bool skipSubChannel)
-{
- if (!PermissionCache::checkCallingPermission(RADIO_PERMISSION)) {
- return PERMISSION_DENIED;
- }
- AutoMutex lock(mLock);
- ALOGV("%s locked", __FUNCTION__);
- status_t status;
- if (mTuner != 0) {
- status = (status_t)mTuner->scan(direction, skipSubChannel);
- } else {
- status = INVALID_OPERATION;
- }
- return status;
-}
-
-status_t RadioService::ModuleClient::step(radio_direction_t direction, bool skipSubChannel)
-{
- if (!PermissionCache::checkCallingPermission(RADIO_PERMISSION)) {
- return PERMISSION_DENIED;
- }
- AutoMutex lock(mLock);
- ALOGV("%s locked", __FUNCTION__);
- status_t status;
- if (mTuner != 0) {
- status = (status_t)mTuner->step(direction, skipSubChannel);
- } else {
- status = INVALID_OPERATION;
- }
- return status;
-}
-
-status_t RadioService::ModuleClient::tune(uint32_t channel, uint32_t subChannel)
-{
- if (!PermissionCache::checkCallingPermission(RADIO_PERMISSION)) {
- return PERMISSION_DENIED;
- }
- AutoMutex lock(mLock);
- ALOGV("%s locked", __FUNCTION__);
- status_t status;
- if (mTuner != 0) {
- status = (status_t)mTuner->tune(channel, subChannel);
- } else {
- status = INVALID_OPERATION;
- }
- return status;
-}
-
-status_t RadioService::ModuleClient::cancel()
-{
- if (!PermissionCache::checkCallingPermission(RADIO_PERMISSION)) {
- return PERMISSION_DENIED;
- }
- AutoMutex lock(mLock);
- ALOGV("%s locked", __FUNCTION__);
- status_t status;
- if (mTuner != 0) {
- status = (status_t)mTuner->cancel();
- } else {
- status = INVALID_OPERATION;
- }
- return status;
-}
-
-status_t RadioService::ModuleClient::getProgramInformation(struct radio_program_info *info)
-{
- if (!PermissionCache::checkCallingPermission(RADIO_PERMISSION)) {
- return PERMISSION_DENIED;
- }
- AutoMutex lock(mLock);
- ALOGV("%s locked", __FUNCTION__);
- status_t status;
- if (mTuner != NULL) {
- status = (status_t)mTuner->getProgramInformation(info);
- } else {
- status = INVALID_OPERATION;
- }
-
- return status;
-}
-
-status_t RadioService::ModuleClient::hasControl(bool *hasControl)
-{
- if (!PermissionCache::checkCallingPermission(RADIO_PERMISSION)) {
- return PERMISSION_DENIED;
- }
- Mutex::Autolock lock(mLock);
- ALOGV("%s locked", __FUNCTION__);
- *hasControl = mTuner != 0;
- return NO_ERROR;
-}
-
-void RadioService::ModuleClient::onCallbackEvent(const sp<IMemory>& eventMemory)
-{
- if (eventMemory == 0 || eventMemory->pointer() == NULL) {
- return;
- }
-
- sp<IRadioClient> client;
- {
- AutoMutex lock(mLock);
- ALOGV("%s locked", __FUNCTION__);
- radio_event_t *event = (radio_event_t *)eventMemory->pointer();
- switch (event->type) {
- case RADIO_EVENT_CONFIG:
- mConfig.band = event->config.band;
- event->config.region = mConfig.region;
- break;
- default:
- break;
- }
-
- client = mClient;
- }
- if (client != 0) {
- client->onEvent(eventMemory);
- }
-}
-
-
-void RadioService::ModuleClient::binderDied(
- const wp<IBinder> &who __unused) {
- ALOGW("client binder died for client %p", this);
- detach();
-}
-
-}; // namespace android
diff --git a/services/radio/RadioService.h b/services/radio/RadioService.h
deleted file mode 100644
index 444eb7a..0000000
--- a/services/radio/RadioService.h
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_RADIO_SERVICE_H
-#define ANDROID_HARDWARE_RADIO_SERVICE_H
-
-#include <utils/Vector.h>
-//#include <binder/AppOpsManager.h>
-#include <binder/MemoryDealer.h>
-#include <binder/BinderService.h>
-#include <binder/IAppOpsCallback.h>
-#include <radio/IRadioService.h>
-#include <radio/IRadio.h>
-#include <radio/IRadioClient.h>
-#include <system/radio.h>
-#include <hardware/radio.h>
-#include "RadioInterface.h"
-#include "TunerInterface.h"
-#include "TunerCallbackInterface.h"
-
-namespace android {
-
-class MemoryHeapBase;
-
-class RadioService :
- public BinderService<RadioService>,
- public BnRadioService
-{
- friend class BinderService<RadioService>;
-
-public:
- class ModuleClient;
- class Module;
-
- static char const* getServiceName() { return "media.radio"; }
-
- RadioService();
- virtual ~RadioService();
-
- // IRadioService
- virtual status_t listModules(struct radio_properties *properties,
- uint32_t *numModules);
-
- virtual status_t attach(radio_handle_t handle,
- const sp<IRadioClient>& client,
- const struct radio_band_config *config,
- bool withAudio,
- sp<IRadio>& radio);
-
- virtual status_t onTransact(uint32_t code, const Parcel& data,
- Parcel* reply, uint32_t flags);
-
- virtual status_t dump(int fd, const Vector<String16>& args);
-
-
- class Module : public virtual RefBase {
- public:
-
- Module(sp<RadioInterface> hwDevice,
- struct radio_properties properties);
-
- virtual ~Module();
-
- sp<ModuleClient> addClient(const sp<IRadioClient>& client,
- const struct radio_band_config *config,
- bool audio);
-
- void removeClient(const sp<ModuleClient>& moduleClient);
-
- status_t setMute(bool mute);
-
- status_t getMute(bool *mute);
-
- virtual status_t dump(int fd, const Vector<String16>& args);
-
- sp<RadioInterface> hwDevice() const { return mHwDevice; }
- const struct radio_properties properties() const { return mProperties; }
- const struct radio_band_config *getDefaultConfig() const ;
-
- private:
-
- void notifyDeviceConnection(bool connected, const char *address);
-
- Mutex mLock; // protects mModuleClients
- sp<RadioInterface> mHwDevice; // HAL hardware device
- const struct radio_properties mProperties; // cached hardware module properties
- Vector< sp<ModuleClient> > mModuleClients; // list of attached clients
- bool mMute; // radio audio source state
- // when unmuted, audio is routed to the
- // output device selected for media use case.
- }; // class Module
-
- class CallbackThread : public Thread {
- public:
-
- explicit CallbackThread(const wp<ModuleClient>& moduleClient);
-
- virtual ~CallbackThread();
-
-
- // Thread virtuals
- virtual bool threadLoop();
-
- // RefBase
- virtual void onFirstRef();
-
- void exit();
-
- void sendEvent(radio_hal_event_t *halEvent);
- sp<IMemory> prepareEvent(radio_hal_event_t *halEvent);
-
- private:
- wp<ModuleClient> mModuleClient; // client module the thread belongs to
- Condition mCallbackCond; // condition signaled when a new event is posted
- Mutex mCallbackLock; // protects mEventQueue
- Vector< sp<IMemory> > mEventQueue; // pending callback events
- sp<MemoryDealer> mMemoryDealer; // shared memory for callback event
- }; // class CallbackThread
-
- class ModuleClient : public BnRadio,
- public IBinder::DeathRecipient,
- public TunerCallbackInterface {
- public:
-
- ModuleClient(const sp<Module>& module,
- const sp<IRadioClient>& client,
- const struct radio_band_config *config,
- bool audio);
-
- virtual ~ModuleClient();
-
- // IRadio
- virtual void detach();
-
- virtual status_t setConfiguration(const struct radio_band_config *config);
-
- virtual status_t getConfiguration(struct radio_band_config *config);
-
- virtual status_t setMute(bool mute);
-
- virtual status_t getMute(bool *mute);
-
- virtual status_t scan(radio_direction_t direction, bool skipSubChannel);
-
- virtual status_t step(radio_direction_t direction, bool skipSubChannel);
-
- virtual status_t tune(unsigned int channel, unsigned int subChannel);
-
- virtual status_t cancel();
-
- virtual status_t getProgramInformation(struct radio_program_info *info);
-
- virtual status_t hasControl(bool *hasControl);
-
- virtual status_t dump(int fd, const Vector<String16>& args);
-
- sp<IRadioClient> client() const { return mClient; }
- wp<Module> module() const { return mModule; }
- radio_hal_band_config_t halConfig() const;
- sp<CallbackThread> callbackThread() const { return mCallbackThread; }
- void setTuner(sp<TunerInterface>& tuner);
- sp<TunerInterface>& getTuner();
- bool audio() const { return mAudio; }
-
- void onCallbackEvent(const sp<IMemory>& event);
-
- virtual void onFirstRef();
-
-
- // IBinder::DeathRecipient implementation
- virtual void binderDied(const wp<IBinder> &who);
-
- // TunerCallbackInterface
- virtual void onEvent(radio_hal_event_t *event);
-
- private:
-
- mutable Mutex mLock; // protects mClient, mConfig and mTuner
- wp<Module> mModule; // The module this client is attached to
- sp<IRadioClient> mClient; // event callback binder interface
- radio_band_config_t mConfig; // current band configuration
- sp<CallbackThread> mCallbackThread; // event callback thread
- const bool mAudio;
- sp<TunerInterface> mTuner; // HAL tuner interface. NULL indicates that
- // this client does not have control on any
- // tuner
- }; // class ModuleClient
-
-
- static void callback(radio_hal_event_t *halEvent, void *cookie);
-
-private:
-
- virtual void onFirstRef();
-
- static void convertProperties(radio_properties_t *properties,
- const radio_hal_properties_t *halProperties);
- Mutex mServiceLock; // protects mModules
- volatile int32_t mNextUniqueId; // for module ID allocation
- DefaultKeyedVector< radio_handle_t, sp<Module> > mModules;
-};
-
-} // namespace android
-
-#endif // ANDROID_HARDWARE_RADIO_SERVICE_H
diff --git a/services/radio/TunerCallbackInterface.h b/services/radio/TunerCallbackInterface.h
deleted file mode 100644
index 4973cce..0000000
--- a/services/radio/TunerCallbackInterface.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_TUNER_CALLBACK_INTERFACE_H
-#define ANDROID_HARDWARE_TUNER_CALLBACK_INTERFACE_H
-
-#include <utils/RefBase.h>
-#include <system/radio.h>
-
-namespace android {
-
-class TunerCallbackInterface : public virtual RefBase
-{
-public:
- virtual void onEvent(radio_hal_event_t *event) = 0;
-
-protected:
- TunerCallbackInterface() {}
- virtual ~TunerCallbackInterface() {}
-
-};
-
-} // namespace android
-
-#endif // ANDROID_HARDWARE_TUNER_CALLBACK_INTERFACE_H
diff --git a/services/radio/TunerInterface.h b/services/radio/TunerInterface.h
deleted file mode 100644
index 4e657d3..0000000
--- a/services/radio/TunerInterface.h
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_TUNER_INTERFACE_H
-#define ANDROID_HARDWARE_TUNER_INTERFACE_H
-
-#include <utils/RefBase.h>
-#include <system/radio.h>
-
-namespace android {
-
-class TunerInterface : public virtual RefBase
-{
-public:
- /*
- * Apply current radio band configuration (band, range, channel spacing ...).
- *
- * arguments:
- * - config: the band configuration to apply
- *
- * returns:
- * 0 if configuration could be applied
- * -EINVAL if configuration requested is invalid
- *
- * Automatically cancels pending scan, step or tune.
- *
- * Callback function with event RADIO_EVENT_CONFIG MUST be called once the
- * configuration is applied or a failure occurs or after a time out.
- */
- virtual int setConfiguration(const radio_hal_band_config_t *config) = 0;
-
- /*
- * Retrieve current radio band configuration.
- *
- * arguments:
- * - config: where to return the band configuration
- *
- * returns:
- * 0 if valid configuration is returned
- * -EINVAL if invalid arguments are passed
- */
- virtual int getConfiguration(radio_hal_band_config_t *config) = 0;
-
- /*
- * Start scanning up to next valid station.
- * Must be called when a valid configuration has been applied.
- *
- * arguments:
- * - direction: RADIO_DIRECTION_UP or RADIO_DIRECTION_DOWN
- * - skip_sub_channel: valid for HD radio or digital radios only: ignore sub channels
- * (e.g SPS for HD radio).
- *
- * returns:
- * 0 if scan successfully started
- * -ENOSYS if called out of sequence
- * -ENODEV if another error occurs
- *
- * Automatically cancels pending scan, step or tune.
- *
- * Callback function with event RADIO_EVENT_TUNED MUST be called once
- * locked on a station or after a time out or full frequency scan if
- * no station found. The event status should indicate if a valid station
- * is tuned or not.
- */
- virtual int scan(radio_direction_t direction, bool skip_sub_channel) = 0;
-
- /*
- * Move one channel spacing up or down.
- * Must be called when a valid configuration has been applied.
- *
- * arguments:
- * - direction: RADIO_DIRECTION_UP or RADIO_DIRECTION_DOWN
- * - skip_sub_channel: valid for HD radio or digital radios only: ignore sub channels
- * (e.g SPS for HD radio).
- *
- * returns:
- * 0 if step successfully started
- * -ENOSYS if called out of sequence
- * -ENODEV if another error occurs
- *
- * Automatically cancels pending scan, step or tune.
- *
- * Callback function with event RADIO_EVENT_TUNED MUST be called once
- * step completed or after a time out. The event status should indicate
- * if a valid station is tuned or not.
- */
- virtual int step(radio_direction_t direction, bool skip_sub_channel) = 0;
-
- /*
- * Tune to specified frequency.
- * Must be called when a valid configuration has been applied.
- *
- * arguments:
- * - channel: channel to tune to. A frequency in kHz for AM/FM/HD Radio bands.
- * - sub_channel: valid for HD radio or digital radios only: (e.g SPS number for HD radio).
- *
- * returns:
- * 0 if tune successfully started
- * -ENOSYS if called out of sequence
- * -EINVAL if invalid arguments are passed
- * -ENODEV if another error occurs
- *
- * Automatically cancels pending scan, step or tune.
- *
- * Callback function with event RADIO_EVENT_TUNED MUST be called once
- * tuned or after a time out. The event status should indicate
- * if a valid station is tuned or not.
- */
- virtual int tune(unsigned int channel, unsigned int sub_channel) = 0;
-
- /*
- * Cancel a scan, step or tune operation.
- * Must be called while a scan, step or tune operation is pending
- * (callback not yet sent).
- *
- * returns:
- * 0 if successful
- * -ENOSYS if called out of sequence
- * -ENODEV if another error occurs
- *
- * The callback is not sent.
- */
- virtual int cancel() = 0;
-
- /*
- * Retrieve current station information.
- *
- * arguments:
- * - info: where to return the program info.
- * If info->metadata is NULL. no meta data should be returned.
- * If meta data must be returned, they should be added to or cloned to
- * info->metadata, not passed from a newly created meta data buffer.
- *
- * returns:
- * 0 if tuned and information available
- * -EINVAL if invalid arguments are passed
- * -ENODEV if another error occurs
- */
- virtual int getProgramInformation(radio_program_info_t *info) = 0;
-
-protected:
- TunerInterface() {}
- virtual ~TunerInterface() {}
-
-};
-
-} // namespace android
-
-#endif // ANDROID_HARDWARE_TUNER_INTERFACE_H