blob: 0b67ff595899c46a0dccee604ad78295fb0844b2 [file] [log] [blame]
rjw6c1fd8f2022-11-30 14:33:01 +08001/*****************************************************************************
2* Copyright Statement:
3* --------------------
4* This software is protected by Copyright and the information contained
5* herein is confidential. The software may not be copied and the information
6* contained herein may not be used or disclosed except with the written
7* permission of MediaTek Inc. (C) 2005
8*
9* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
10* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
11* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
12* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
13* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
14* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
15* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
16* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
17* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
18* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
19* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
20* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
21*
22* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
23* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
24* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
25* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
26* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
27*
28* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
29* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
30* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
31* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
32* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
33*
34*****************************************************************************/
35
36/*****************************************************************************
37 *
38 * Filename:
39 * ---------
40 * PcmMixer2.c
41 *
42 * Project:
43 * --------
44 *
45 *
46 * Description:
47 * ------------
48 *
49 *
50 * Author:
51 * -------
52 * -------
53 *============================================================================
54 * HISTORY
55 * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
56 *------------------------------------------------------------------------------
57 * removed!
58 * removed!
59 * removed!
60 *
61 *------------------------------------------------------------------------------
62 * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
63 *============================================================================
64 ****************************************************************************/
65
66#include "kal_public_api.h"
67#include "kal_general_types.h"
68#include "sync_data.h"
69
70#include "kal_trace.h"
71#include "l1sp_trc.h"
72#include "event_info_utility.h" // for MODEM_WARNING_MESSAGE
73
74
75#include "am.h"
76//#include "speech_def.h"
77#include "afe_def.h" // for output device setting
78#include "sp_drv.h"
79
80#include "pcmMixer.h"
81#include "sal_exp.h"
82
83/************************** Constants ***************************************/
84#define PCMMIXER_BUF_SIZE 960 // using in 16 bit, FB
85
86typedef enum {
87 PCMMIXER_STATE_IDLE = 0,
88 PCMMIXER_STATE_RUN,
89 PCMMIXER_STATE_CLOSING,
90}PCMMIXER_STATE_TYPE;
91
92/*********** Structure *******************************************************/
93
94typedef struct{
95
96 PCMMIXER_STATE_TYPE state;
97 kal_spinlockid lockId;
98
99 kal_bool ulmix;
100 kal_bool dlmix;
101
102 void (*hisrHandler)(void);
103
104 kal_uint16 aud_id;
105
106 kal_uint16 ULGain;
107 kal_uint16 DLGain;
108
109}PcmMixer_T;
110
111/*********** variable ********************************************************/
112
113static PcmMixer_T gPcmMixer;
114
115static kal_uint16 pcmMixerBuf[PCMMIXER_BUF_SIZE];
116
117/*********** internal fucntion **********************************************/
118
119
120
121void pcmMixerHisr( void *pram )
122{
123 volatile uint16* toBuf;
124 uint32 toBufLen;
125 uint16 i;
126
127 if (KAL_SPINLOCK_NOT_AVAILABLE == kal_take_spinlock(gPcmMixer.lockId, KAL_NO_WAIT)) {
128 MD_TRC_VM_HISR_LOCK_NOT_AVALIABLE(1);
129 goto leaveHisr;
130 }
131 // handle extra notify and closing state
132 if (PCMMIXER_STATE_RUN != gPcmMixer.state)
133 goto leaveProc;
134
135 if(!SAL_Mixer2_IsRunning())
136 goto leaveProc;;
137
138 // gain and setting update
139 SAL_Mixer2_Config(gPcmMixer.ULGain, gPcmMixer.DLGain, gPcmMixer.ulmix, gPcmMixer.dlmix);
140
141 // write data
142 toBuf = SAL_Mixer2_GetBuf_DL();
143 toBufLen = SAL_Mixer2_GetDataLen_DL();
144 for(i=0; i<toBufLen; i++) {
145 toBuf[i] = pcmMixerBuf[i];
146 }
147 Data_Sync_Barrier();
148
149
150leaveProc:
151 kal_give_spinlock(gPcmMixer.lockId);
152
153 if( gPcmMixer.hisrHandler != NULL) {
154 gPcmMixer.hisrHandler();
155 }
156
157leaveHisr:
158 return;
159}
160
161
162/*===========================================================================*/
163uint16 PcmMixer_QueryDlBufLen(void)
164{
165 return (uint16) (SAL_Mixer2_GetDataLen_DL());
166}
167
168/**
169 @srcBuf:
170 @len: length of sample
171*/
172void PcmMixer_writeDlBuf(uint16 *srcBuf, uint16 len)
173{
174 if(len <= PCMMIXER_BUF_SIZE) {
175 kal_take_spinlock(gPcmMixer.lockId, KAL_INFINITE_WAIT);
176 kal_mem_cpy(pcmMixerBuf, srcBuf, len*sizeof(int16));
177 kal_give_spinlock(gPcmMixer.lockId);
178 }
179}
180
181/**
182 @isMix: Mixer switch for uplink speech, 1 for SPH+Sound, 0 for sound only
183 @gain: Sound effect gain for uplink mixer, for 0 to 7
184*/
185void PcmMixer_ConfigUl(kal_bool isMix, kal_int8 gain )
186{
187 MD_TRC_MIXER2_CONFIG_UL(isMix, gain);
188
189 if(gain<0) {
190 gain=0;
191 } else if (gain >7) {
192 gain=7;
193 }
194
195 if( gain == 0 )
196 gPcmMixer.ULGain = 0;
197 else {
198 gPcmMixer.ULGain = (kal_int16)(32767 >> (7 - gain));
199 }
200 gPcmMixer.ulmix= isMix;
201}
202
203
204/**
205 @isMix: Mixer switch for uplink speech, 1 for SPH+Sound, 0 for sound only
206 @gain: Sound effect gain for uplink mixer, for 0 to 7
207*/
208void PcmMixer_ConfigDl(kal_bool isMix, kal_int8 gain )
209{
210 MD_TRC_MIXER2_CONFIG_DL(isMix, gain);
211
212 if(gain<0) {
213 gain=0;
214 } else if (gain >7) {
215 gain=7;
216 }
217
218 if( gain == 0 )
219 gPcmMixer.DLGain = 0;
220 else {
221 gPcmMixer.DLGain = (kal_int16)(32767 >> (7 - gain));
222 }
223 gPcmMixer.dlmix= isMix;
224}
225
226
227/**
228
229 The function starts the background sound playback of the media handle.
230
231 @bgSnd_hdlr: handler
232*/
233void PcmMixer_Start(void (*mixerHisrHandler)(void))
234{
235 if(PCMMIXER_STATE_RUN == gPcmMixer.state) {
236 return;
237 }
238
239 MD_TRC_MIXER2_START();
240
241 gPcmMixer.state = PCMMIXER_STATE_IDLE;
242 memset(pcmMixerBuf, 0, sizeof(kal_uint16)*PCMMIXER_BUF_SIZE);
243 gPcmMixer.hisrHandler = mixerHisrHandler;
244
245 L1Audio_SetFlag(gPcmMixer.aud_id);
246
247 // update config to dsp
248 SAL_Mixer2_Config(gPcmMixer.ULGain, gPcmMixer.DLGain, gPcmMixer.ulmix, gPcmMixer.dlmix);
249
250 // turn on.
251 // AM_SND_PlaybackOn(); TODO:
252 SAL_Mixer2_SetInit();
253 {
254 uint32 I;
255 for( I = 0; I < 20; I++ ) {
256 if(SAL_Mixer2_IsRunning()) {
257 gPcmMixer.state = PCMMIXER_STATE_RUN;
258 break;
259 }
260 kal_sleep_task( AUD_1TICK(2) );
261 }
262 MODEM_WARNING_MESSAGE(I < 20, "PcmMixer_Start: fail to wait DSP runing");
263 }
264
265
266}
267
268/*
269 * Description
270 * ---------
271 * The function stops the background sound playback of the media handle.
272 *
273 * Syntax
274 * ---------
275 * void PcmMixerStop();
276 *
277 * where
278 * hdl The media handle
279 *
280 * Return Value
281 * ---------
282 * None
283 */
284void PcmMixer_Stop(void)
285{
286 uint32 I;
287
288 if(PCMMIXER_STATE_RUN != gPcmMixer.state) {
289 L1Audio_ClearFlag(gPcmMixer.aud_id);
290 return;
291 }
292
293 // change the state before start closing
294 kal_take_spinlock(gPcmMixer.lockId, KAL_INFINITE_WAIT);
295 gPcmMixer.state= PCMMIXER_STATE_CLOSING;
296 kal_give_spinlock(gPcmMixer.lockId);
297
298 if(SAL_Mixer2_IsRunning())
299 SAL_Mixer2_SetFinal();
300 for ( I = 0; I < 20; I++ ) {
301 if ( SAL_Mixer2_IsIdle()) /* DSP returns to idle state */
302 break;
303
304 kal_sleep_task( AUD_1TICK(2) );
305 }
306 if(I>=20) {
307 DEBUG_ASSERT(0);
308 MODEM_WARNING_MESSAGE(0, "PcmMixer_Stop: fail to stop DSP mixer2 function");
309 }
310
311 // TODO:
312 // AM_SND_PlaybackOff( true );
313 gPcmMixer.state = PCMMIXER_STATE_IDLE;
314
315 L1Audio_ClearFlag(gPcmMixer.aud_id);
316}
317
318
319void PcmMixer_Init(void)
320{
321 gPcmMixer.lockId = kal_create_spinlock("pcmMixerLock");
322 gPcmMixer.aud_id = L1Audio_GetAudioID();
323 L1Audio_HookHisrHandler(DP_D2C_MIXER2_DL_ID, pcmMixerHisr, 0);
324}
325
326