1 /*
2 * Copyright (C) 2004-2010 NXP Software
3 * Copyright (C) 2010 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 /**********************************************************************************
19 INCLUDE FILES
20 ***********************************************************************************/
21
22 #include "LVC_Mixer_Private.h"
23 #include "VectorArithmetic.h"
24 #include "ScalarArithmetic.h"
25
26 /**********************************************************************************
27 DEFINITIONS
28 ***********************************************************************************/
29
30 #define TRUE 1
31 #define FALSE 0
32
33 /**********************************************************************************
34 FUNCTION MIXINSOFT_D16C31_SAT
35 ***********************************************************************************/
LVC_MixInSoft_D16C31_SAT(LVMixer3_1St_FLOAT_st * ptrInstance,const LVM_FLOAT * src,LVM_FLOAT * dst,LVM_INT16 n)36 void LVC_MixInSoft_D16C31_SAT(LVMixer3_1St_FLOAT_st* ptrInstance, const LVM_FLOAT* src,
37 LVM_FLOAT* dst, LVM_INT16 n) {
38 char HardMixing = TRUE;
39 LVM_FLOAT TargetGain;
40 Mix_Private_FLOAT_st* pInstance =
41 (Mix_Private_FLOAT_st*)(ptrInstance->MixerStream[0].PrivateParams);
42
43 if (n <= 0) return;
44
45 /******************************************************************************
46 SOFT MIXING
47 *******************************************************************************/
48 if (pInstance->Current != pInstance->Target) {
49 if (pInstance->Delta == 1.0f) {
50 pInstance->Current = pInstance->Target;
51 TargetGain = pInstance->Target;
52 LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[0]), TargetGain);
53 } else if (Abs_Float(pInstance->Current - pInstance->Target) < pInstance->Delta) {
54 pInstance->Current = pInstance->Target; /* Difference is not significant anymore. \
55 Make them equal. */
56 TargetGain = pInstance->Target;
57 LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[0]), TargetGain);
58 } else {
59 /* Soft mixing has to be applied */
60 HardMixing = FALSE;
61 LVC_Core_MixInSoft_D16C31_SAT(&(ptrInstance->MixerStream[0]), src, dst, n);
62 }
63 }
64
65 /******************************************************************************
66 HARD MIXING
67 *******************************************************************************/
68
69 if (HardMixing) {
70 if (pInstance->Target != 0) { /* Nothing to do in case Target = 0 */
71 if ((pInstance->Target) == 1.0f) {
72 Add2_Sat_Float(src, dst, n);
73 } else {
74 Mac3s_Sat_Float(src, (pInstance->Target), dst, n);
75 /* In case the LVCore function would have changed the Current value */
76 pInstance->Current = pInstance->Target;
77 }
78 }
79 }
80
81 /******************************************************************************
82 CALL BACK
83 *******************************************************************************/
84
85 if (ptrInstance->MixerStream[0].CallbackSet) {
86 if (Abs_Float(pInstance->Current - pInstance->Target) < pInstance->Delta) {
87 pInstance->Current = pInstance->Target; /* Difference is not significant anymore. \
88 Make them equal. */
89 TargetGain = pInstance->Target;
90 LVC_Mixer_SetTarget(ptrInstance->MixerStream, TargetGain);
91 ptrInstance->MixerStream[0].CallbackSet = FALSE;
92 if (ptrInstance->MixerStream[0].pCallBack != 0) {
93 (*ptrInstance->MixerStream[0].pCallBack)(
94 ptrInstance->MixerStream[0].pCallbackHandle,
95 ptrInstance->MixerStream[0].pGeneralPurpose,
96 ptrInstance->MixerStream[0].CallbackParam);
97 }
98 }
99 }
100 }
101
102 /*
103 * FUNCTION: LVC_MixInSoft_Mc_D16C31_SAT
104 *
105 * DESCRIPTION:
106 * Mixer function with support for processing multichannel input
107 *
108 * PARAMETERS:
109 * ptrInstance Instance pointer
110 * src Source
111 * dst Destination
112 * NrFrames Number of frames
113 * NrChannels Number of channels
114 *
115 * RETURNS:
116 * void
117 *
118 */
LVC_MixInSoft_Mc_D16C31_SAT(LVMixer3_1St_FLOAT_st * ptrInstance,const LVM_FLOAT * src,LVM_FLOAT * dst,LVM_INT16 NrFrames,LVM_INT16 NrChannels)119 void LVC_MixInSoft_Mc_D16C31_SAT(LVMixer3_1St_FLOAT_st* ptrInstance, const LVM_FLOAT* src,
120 LVM_FLOAT* dst, LVM_INT16 NrFrames, LVM_INT16 NrChannels) {
121 char HardMixing = TRUE;
122 LVM_FLOAT TargetGain;
123 Mix_Private_FLOAT_st* pInstance =
124 (Mix_Private_FLOAT_st*)(ptrInstance->MixerStream[0].PrivateParams);
125
126 if (NrFrames <= 0) return;
127
128 /******************************************************************************
129 SOFT MIXING
130 *******************************************************************************/
131 if (pInstance->Current != pInstance->Target) {
132 if (pInstance->Delta == 1.0f) {
133 pInstance->Current = pInstance->Target;
134 TargetGain = pInstance->Target;
135 LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[0]), TargetGain);
136 } else if (Abs_Float(pInstance->Current - pInstance->Target) < pInstance->Delta) {
137 pInstance->Current = pInstance->Target; /* Difference is not significant anymore. \
138 Make them equal. */
139 TargetGain = pInstance->Target;
140 LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[0]), TargetGain);
141 } else {
142 /* Soft mixing has to be applied */
143 HardMixing = FALSE;
144 LVC_Core_MixInSoft_Mc_D16C31_SAT(&(ptrInstance->MixerStream[0]), src, dst, NrFrames,
145 NrChannels);
146 }
147 }
148
149 /******************************************************************************
150 HARD MIXING
151 *******************************************************************************/
152
153 if (HardMixing) {
154 if (pInstance->Target != 0) { /* Nothing to do in case Target = 0 */
155 if ((pInstance->Target) == 1.0f) {
156 Add2_Sat_Float(src, dst, NrFrames * NrChannels);
157 } else {
158 Mac3s_Sat_Float(src, (pInstance->Target), dst, NrFrames * NrChannels);
159 /* In case the LVCore function would have changed the Current value */
160 pInstance->Current = pInstance->Target;
161 }
162 }
163 }
164
165 /******************************************************************************
166 CALL BACK
167 *******************************************************************************/
168
169 if (ptrInstance->MixerStream[0].CallbackSet) {
170 if (Abs_Float(pInstance->Current - pInstance->Target) < pInstance->Delta) {
171 pInstance->Current = pInstance->Target; /* Difference is not significant anymore. \
172 Make them equal. */
173 TargetGain = pInstance->Target;
174 LVC_Mixer_SetTarget(ptrInstance->MixerStream, TargetGain);
175 ptrInstance->MixerStream[0].CallbackSet = FALSE;
176 if (ptrInstance->MixerStream[0].pCallBack != 0) {
177 (*ptrInstance->MixerStream[0].pCallBack)(
178 ptrInstance->MixerStream[0].pCallbackHandle,
179 ptrInstance->MixerStream[0].pGeneralPurpose,
180 ptrInstance->MixerStream[0].CallbackParam);
181 }
182 }
183 }
184 }
185
186 /**********************************************************************************/
187