source: svn/newcon3bcm2_21bu/magnum/portinginterface/ape/7552/bape_echo_canceller.c

Last change on this file was 76, checked in by megakiss, 10 years ago

1W 대기전력을 만족시키기 위하여 POWEROFF시 튜너를 Standby 상태로 함

  • Property svn:executable set to *
File size: 28.5 KB
Line 
1/***************************************************************************
2 *     Copyright (c) 2006-2012, Broadcom Corporation
3 *     All Rights Reserved
4 *     Confidential Property of Broadcom Corporation
5 *
6 *  THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED SOFTWARE LICENSE
7 *  AGREEMENT  BETWEEN THE USER AND BROADCOM.  YOU HAVE NO RIGHT TO USE OR
8 *  EXPLOIT THIS MATERIAL EXCEPT SUBJECT TO THE TERMS OF SUCH AN AGREEMENT.
9 *
10 * $brcm_Workfile: bape_echo_canceller.c $
11 * $brcm_Revision: Hydra_Software_Devel/3 $
12 * $brcm_Date: 2/3/12 4:30p $
13 *
14 * Module Description: Audio Decoder Interface
15 *
16 * Revision History:
17 *
18 * $brcm_Log: /magnum/portinginterface/ape/7422/bape_echo_canceller.c $
19 *
20 * Hydra_Software_Devel/3   2/3/12 4:30p jgarrett
21 * SW7425-2268: Initial bringup of voice conferencing support
22 *
23 * Hydra_Software_Devel/2   2/2/12 4:49p jgarrett
24 * SW7425-2268: Adding EchoCanceller
25 *
26 * Hydra_Software_Devel/1   1/31/12 6:17p jgarrett
27 * SW7425-2268: Adding initial voice conferencing support
28 *
29 ***************************************************************************/
30
31#include "bape.h"
32#include "bape_priv.h"
33#include "bdsp_raaga.h"
34
35BDBG_MODULE(bape_echo_canceller);
36BDBG_OBJECT_ID(BAPE_EchoCanceller);
37
38static BDSP_AudioProcessing BAPE_EchoCanceller_P_GetType(BAPE_EchoCancellerAlgorithm algorithm);
39static BERR_Code BAPE_EchoCanceller_P_ApplyDspSettings(BAPE_EchoCancellerHandle handle, BDSP_TaskHandle task, unsigned branchId, unsigned stageId);
40static void BAPE_EchoCanceller_P_GetDefaultAlgorithmSettings(BAPE_EchoCancellerHandle handle);
41static BERR_Code BAPE_EchoCanceller_P_ConnectorSupported(struct BAPE_PathNode *pNode, BAPE_PathConnector *pConnector);
42static bool BAPE_EchoCanceller_P_IsRunning(BAPE_EchoCancellerHandle handle);
43static void BAPE_EchoCanceller_P_InitInterTaskDescriptors(BAPE_EchoCancellerHandle handle);
44
45static BERR_Code BAPE_EchoCanceller_P_Local_AllocatePathFromInput(struct BAPE_PathNode *pNode, struct BAPE_PathConnection *pConnection);
46static BERR_Code BAPE_EchoCanceller_P_Local_ConfigPathFromInput(struct BAPE_PathNode *pNode, struct BAPE_PathConnection *pConnection);
47static BERR_Code BAPE_EchoCanceller_P_Local_StartPathFromInput(struct BAPE_PathNode *pNode, struct BAPE_PathConnection *pConnection);
48static void BAPE_EchoCanceller_P_Local_StopPathFromInput(struct BAPE_PathNode *pNode, struct BAPE_PathConnection *pConnection);
49static void BAPE_EchoCanceller_P_Local_RemoveInputCallback(struct BAPE_PathNode *pNode, BAPE_PathConnector *pConnector);
50
51static BERR_Code BAPE_EchoCanceller_P_Remote_AllocatePathFromInput(struct BAPE_PathNode *pNode, struct BAPE_PathConnection *pConnection);
52static BERR_Code BAPE_EchoCanceller_P_Remote_StartPathFromInput(struct BAPE_PathNode *pNode, struct BAPE_PathConnection *pConnection);
53static void BAPE_EchoCanceller_P_Remote_StopPathFromInput(struct BAPE_PathNode *pNode, struct BAPE_PathConnection *pConnection);
54static void BAPE_EchoCanceller_P_Remote_RemoveInputCallback(struct BAPE_PathNode *pNode, BAPE_PathConnector *pConnector);
55
56void BAPE_EchoCanceller_GetDefaultSettings(
57    BAPE_EchoCancellerSettings *pSettings   /* [out] */
58    )
59{
60    BKNI_Memset(pSettings, 0, sizeof(*pSettings));
61    pSettings->algorithm = BAPE_EchoCancellerAlgorithm_eSpeex;
62}
63
64BERR_Code BAPE_EchoCanceller_Create(
65    BAPE_Handle deviceHandle,
66    const BAPE_EchoCancellerSettings *pSettings,
67    BAPE_EchoCancellerHandle *pHandle               /* [out] */
68    )
69{
70    BERR_Code errCode = BERR_SUCCESS;
71    BAPE_EchoCancellerHandle handle;
72    BAPE_EchoCancellerSettings defaults;
73
74    BDBG_OBJECT_ASSERT(deviceHandle, BAPE_Device);
75    BDBG_ASSERT(NULL != pHandle);
76
77    if ( NULL == pSettings )
78    {
79        BAPE_EchoCanceller_GetDefaultSettings(&defaults);
80        pSettings = &defaults;
81    }
82
83    handle = BKNI_Malloc(sizeof(BAPE_EchoCanceller));
84    if ( NULL == handle )
85    {
86        errCode = BERR_TRACE(BERR_OUT_OF_SYSTEM_MEMORY);
87        goto err_handle;
88    }
89
90    BKNI_Memset(handle, 0, sizeof(BAPE_EchoCanceller));
91    BDBG_OBJECT_SET(handle, BAPE_EchoCanceller);
92    handle->deviceHandle = deviceHandle;
93
94    /* Initialize node for local connections.  This is the primary node that can attach to outputs. */
95    BAPE_P_InitPathNode(&handle->localNode, BAPE_PathNodeType_eEchoCanceller, pSettings->algorithm, 1, deviceHandle, handle);   
96    handle->localNode.pName = "Echo Canceller (local)";
97    handle->localNode.paths[0].connector.numChannelPairs = 1;
98    handle->localNode.paths[0].connector.useBufferPool = true;   
99    handle->localNode.paths[0].connector.mono = true;   
100    handle->localNode.paths[0].connector.dataSource = BAPE_DataSource_eDspBuffer;   
101
102    /* Generic Routines */
103    handle->localNode.allocatePathToOutput = BAPE_DSP_P_AllocatePathToOutput;
104    handle->localNode.configPathToOutput = BAPE_DSP_P_ConfigPathToOutput;
105    handle->localNode.stopPathToOutput = BAPE_DSP_P_StopPathToOutput;
106    handle->localNode.startPathToOutput = BAPE_DSP_P_StartPathToOutput;
107    handle->localNode.stopPathToOutput = BAPE_DSP_P_StopPathToOutput;
108
109    /* Echo Canceller Specifics */
110    handle->localNode.connectorSupported = BAPE_EchoCanceller_P_ConnectorSupported;
111    handle->localNode.allocatePathFromInput = BAPE_EchoCanceller_P_Local_AllocatePathFromInput;
112    handle->localNode.configPathFromInput = BAPE_EchoCanceller_P_Local_ConfigPathFromInput;
113    handle->localNode.startPathFromInput = BAPE_EchoCanceller_P_Local_StartPathFromInput;
114    handle->localNode.stopPathFromInput = BAPE_EchoCanceller_P_Local_StopPathFromInput;
115    handle->localNode.removeInput = BAPE_EchoCanceller_P_Local_RemoveInputCallback;
116    handle->localNode.monoInputValid = true;                         /* EchoCancellers can handle mono input */
117
118    /* Initialize node for remote inputs.  This node can not connect downstream, and is an inter-task link between a decoder and the ecno-canceller. */
119    BAPE_P_InitPathNode(&handle->remoteNode, BAPE_PathNodeType_eEchoCanceller, pSettings->algorithm, 1, deviceHandle, handle);
120    handle->localNode.pName = "Echo Canceller (remote)";
121    handle->remoteNode.paths[0].connector.numChannelPairs = 1;
122    handle->remoteNode.paths[0].connector.useBufferPool = true;   
123    handle->remoteNode.paths[0].connector.mono = true;   
124    handle->remoteNode.paths[0].connector.dataSource = BAPE_DataSource_eDspBuffer;   
125
126    /* No generic routines, we can not connect to outputs */
127
128    /* Echo Canceller Specifics */
129    handle->remoteNode.connectorSupported = BAPE_EchoCanceller_P_ConnectorSupported;
130    handle->remoteNode.allocatePathFromInput = BAPE_EchoCanceller_P_Remote_AllocatePathFromInput;
131    handle->remoteNode.startPathFromInput = BAPE_EchoCanceller_P_Remote_StartPathFromInput;
132    handle->remoteNode.stopPathFromInput = BAPE_EchoCanceller_P_Remote_StopPathFromInput;
133    handle->remoteNode.removeInput = BAPE_EchoCanceller_P_Remote_RemoveInputCallback;
134    handle->remoteNode.monoInputValid = true;                         /* EchoCancellers can handle mono input */
135
136    /* Init algorithm settings */
137    BKNI_Memcpy(&handle->settings, pSettings, sizeof(BAPE_EchoCancellerSettings));
138    BAPE_EchoCanceller_P_GetDefaultAlgorithmSettings(handle);
139
140
141    /* Allocate required buffers */
142    handle->pInterTaskGenericBuffer = BMEM_Heap_Alloc(deviceHandle->memHandle, BDSP_AF_P_INTERTASK_IOGENBUFFER_SIZE);
143    if ( NULL == handle->pInterTaskGenericBuffer )
144    {
145        errCode = BERR_TRACE(BERR_OUT_OF_DEVICE_MEMORY);
146        goto err_generic_buffer;
147    }
148
149    handle->pInterTaskIoBuffer = BMEM_Heap_Alloc(deviceHandle->memHandle, BAPE_P_INTER_TASK_BUFFER_SIZE);
150    if ( NULL == handle->pInterTaskIoBuffer )
151    {
152        errCode = BERR_TRACE(BERR_OUT_OF_DEVICE_MEMORY);
153        goto err_io_buffer;
154    }
155
156    handle->pInterTaskIoDescriptor = BMEM_Heap_Alloc(deviceHandle->memHandle, sizeof(BDSP_AF_P_sIO_BUFFER));
157    if ( NULL == handle->pInterTaskIoDescriptor )
158    {
159        errCode = BERR_TRACE(BERR_OUT_OF_DEVICE_MEMORY);
160        goto err_io_descriptor;
161    }
162
163    handle->pInterTaskGenericDescriptor = BMEM_Heap_Alloc(deviceHandle->memHandle, sizeof(BDSP_AF_P_sIO_GENERIC_BUFFER));
164    if ( NULL == handle->pInterTaskGenericDescriptor )
165    {
166        errCode = BERR_TRACE(BERR_OUT_OF_DEVICE_MEMORY);
167        goto err_generic_descriptor;
168    }
169
170    BAPE_EchoCanceller_P_InitInterTaskDescriptors(handle);
171
172    *pHandle = handle;
173    return BERR_SUCCESS;
174
175err_generic_descriptor:
176    BMEM_Heap_Free(deviceHandle->memHandle, handle->pInterTaskIoDescriptor);
177err_io_descriptor:
178    BMEM_Heap_Free(deviceHandle->memHandle, handle->pInterTaskIoBuffer);
179err_io_buffer:
180    BMEM_Heap_Free(deviceHandle->memHandle, handle->pInterTaskGenericBuffer);
181err_generic_buffer:
182    BDBG_OBJECT_DESTROY(handle, BAPE_EchoCanceller);
183    BKNI_Free(handle);
184err_handle:
185    return errCode;
186}
187
188void BAPE_EchoCanceller_Destroy(
189    BAPE_EchoCancellerHandle handle
190    )
191{
192    bool running;
193    BDBG_OBJECT_ASSERT(handle, BAPE_EchoCanceller);
194
195    running = handle->localStarted || handle->remoteStarted;
196    BDBG_ASSERT(false == running);
197    BDBG_ASSERT(NULL == handle->localInput);
198    BDBG_ASSERT(NULL == handle->remoteInput);
199
200    BMEM_Heap_Free(handle->deviceHandle->memHandle, handle->pInterTaskGenericDescriptor);
201    BMEM_Heap_Free(handle->deviceHandle->memHandle, handle->pInterTaskIoDescriptor);
202    BMEM_Heap_Free(handle->deviceHandle->memHandle, handle->pInterTaskIoBuffer);
203    BMEM_Heap_Free(handle->deviceHandle->memHandle, handle->pInterTaskGenericBuffer);
204    BDBG_OBJECT_DESTROY(handle, BAPE_EchoCanceller);
205    BKNI_Free(handle);
206}
207
208void BAPE_EchoCanceller_GetSettings(
209    BAPE_EchoCancellerHandle handle,
210    BAPE_EchoCancellerSettings *pSettings    /* [out] Settings */
211    )
212{
213    BDBG_OBJECT_ASSERT(handle, BAPE_EchoCanceller);
214    BDBG_ASSERT(NULL != pSettings);
215    *pSettings = handle->settings;
216}
217
218BERR_Code BAPE_EchoCanceller_SetSettings(
219    BAPE_EchoCancellerHandle handle,
220    const BAPE_EchoCancellerSettings *pSettings
221    )
222{
223    bool running;
224
225    BDBG_OBJECT_ASSERT(handle, BAPE_EchoCanceller);
226    BDBG_ASSERT(NULL != pSettings);
227
228    running = BAPE_EchoCanceller_P_IsRunning(handle);
229    if ( running && pSettings->algorithm != handle->settings.algorithm )
230    {
231        BDBG_ERR(("Can not change algorithm while running."));
232        return BERR_TRACE(BERR_NOT_SUPPORTED);
233    }
234
235    handle->settings = *pSettings;
236
237    return BERR_SUCCESS;
238}
239
240void BAPE_EchoCanceller_GetAlgorithmSettings(
241    BAPE_EchoCancellerHandle handle,
242    BAPE_EchoCancellerAlgorithm algorithm,
243    BAPE_EchoCancellerAlgorithmSettings *pSettings  /* [out] */
244    )
245{
246    BDBG_OBJECT_ASSERT(handle, BAPE_EchoCanceller);
247    BDBG_ASSERT(NULL != pSettings);
248
249    pSettings->algorithm = algorithm;
250    switch ( algorithm )
251    {
252    case BAPE_EchoCancellerAlgorithm_eSpeex:
253        pSettings->algorithmSettings.speex = handle->speexSettings;
254        break;
255    default:
256        break;
257    }
258}
259
260BERR_Code BAPE_EchoCanceller_SetAlgorithmSettings(
261    BAPE_EchoCancellerHandle handle,
262    const BAPE_EchoCancellerAlgorithmSettings *pSettings
263    )
264{
265    bool running, updateDsp=false;
266    BERR_Code errCode;
267
268    BDBG_OBJECT_ASSERT(handle, BAPE_EchoCanceller);
269    BDBG_ASSERT(NULL != pSettings);
270
271    running = BAPE_EchoCanceller_P_IsRunning(handle);
272    if ( handle->settings.algorithm == pSettings->algorithm )
273    {
274        updateDsp = true;
275    }
276
277    switch ( pSettings->algorithm )
278    {
279    case BAPE_EchoCancellerAlgorithm_eSpeex:
280        handle->speexSettings = pSettings->algorithmSettings.speex;
281        break;
282    default:
283        updateDsp = false;
284        break;
285    }
286
287    if ( running && updateDsp )
288    {
289        errCode = BAPE_EchoCanceller_P_ApplyDspSettings(handle,
290                                                        handle->localNode.paths[0].connector.task, 
291                                                        handle->localNode.paths[0].connector.branchId, 
292                                                        handle->localNode.paths[0].connector.stageId);
293        if ( errCode )
294        {
295            return BERR_TRACE(errCode);
296        }
297    }
298
299    return BERR_SUCCESS;
300}
301
302void BAPE_EchoCanceller_GetConnector(
303    BAPE_EchoCancellerHandle handle,
304    BAPE_Connector *pConnector   /* [out] */
305    )
306{
307    BDBG_OBJECT_ASSERT(handle, BAPE_EchoCanceller);
308    BDBG_ASSERT(NULL != pConnector);
309    *pConnector = &handle->localNode.paths[0].connector;
310}
311
312BERR_Code BAPE_EchoCanceller_AddLocalInput(
313    BAPE_EchoCancellerHandle handle,
314    BAPE_Connector input
315    )
316{
317    BERR_Code errCode;
318    BDBG_OBJECT_ASSERT(handle, BAPE_EchoCanceller);
319    BDBG_OBJECT_ASSERT(input, BAPE_PathConnector);
320    if ( NULL != handle->localInput )
321    {
322        BDBG_ERR(("Can not have more than one local input"));
323        return BERR_TRACE(BERR_NOT_SUPPORTED);
324    }
325    errCode = BAPE_PathNode_P_AddInput(&handle->localNode, input);
326    if ( errCode )
327    {
328        return BERR_TRACE(errCode);
329    }
330    handle->localInput = input;
331    return BERR_SUCCESS;
332}
333
334BERR_Code BAPE_EchoCanceller_RemoveLocalInput(
335    BAPE_EchoCancellerHandle handle,
336    BAPE_Connector input
337    )
338{
339    BERR_Code errCode;
340    BDBG_OBJECT_ASSERT(handle, BAPE_EchoCanceller);
341    BDBG_OBJECT_ASSERT(input, BAPE_PathConnector);
342    if ( input != handle->localInput )
343    {
344        BDBG_ERR(("Input %s %s (%#x) is not connected as the local input", input->pParent->pName, input->pName, input));
345        return BERR_TRACE(BERR_INVALID_PARAMETER);
346    }
347    errCode = BAPE_PathNode_P_RemoveInput(&handle->localNode, input);
348    if ( errCode )
349    {
350        return BERR_TRACE(errCode);
351    }
352    handle->localInput = NULL;
353    return BERR_SUCCESS;
354}
355
356/***************************************************************************
357Summary:
358Add a remote (far-end) input to the echo canceller
359***************************************************************************/
360BERR_Code BAPE_EchoCanceller_AddRemoteInput(
361    BAPE_EchoCancellerHandle handle,
362    BAPE_Connector input
363    )
364{
365    BERR_Code errCode;
366    BDBG_OBJECT_ASSERT(handle, BAPE_EchoCanceller);
367    BDBG_OBJECT_ASSERT(input, BAPE_PathConnector);
368    if ( NULL != handle->remoteInput )
369    {
370        BDBG_ERR(("Can not have more than one remote input"));
371        return BERR_TRACE(BERR_NOT_SUPPORTED);
372    }
373    errCode = BAPE_PathNode_P_AddInput(&handle->remoteNode, input);
374    if ( errCode )
375    {
376        return BERR_TRACE(errCode);
377    }
378    handle->remoteInput = input;
379    return BERR_SUCCESS;
380}
381
382/***************************************************************************
383Summary:
384Remove a remote (far-end) input from this processing stage
385***************************************************************************/
386BERR_Code BAPE_EchoCanceller_RemoveRemoteInput(
387    BAPE_EchoCancellerHandle handle,
388    BAPE_Connector input
389    )
390{
391    BERR_Code errCode;
392    BDBG_OBJECT_ASSERT(handle, BAPE_EchoCanceller);
393    BDBG_OBJECT_ASSERT(input, BAPE_PathConnector);
394    if ( input != handle->remoteInput )
395    {
396        BDBG_ERR(("Input %s %s (%#x) is not connected as the remote input", input->pParent->pName, input->pName, input));
397        return BERR_TRACE(BERR_INVALID_PARAMETER);
398    }
399    errCode = BAPE_PathNode_P_RemoveInput(&handle->remoteNode, input);
400    if ( errCode )
401    {
402        return BERR_TRACE(errCode);
403    }
404    handle->remoteInput = NULL;
405    return BERR_SUCCESS;
406}
407
408/***************************************************************************
409Summary:
410Remove all inputs from this processing stage
411***************************************************************************/
412BERR_Code BAPE_EchoCanceller_RemoveAllInputs(
413    BAPE_EchoCancellerHandle handle
414    )
415{
416    BDBG_OBJECT_ASSERT(handle, BAPE_EchoCanceller);
417    if ( handle->localInput )
418    {
419        (void)BAPE_EchoCanceller_RemoveLocalInput(handle, handle->localInput);
420    }
421    if ( handle->remoteInput )
422    {
423        (void)BAPE_EchoCanceller_RemoveRemoteInput(handle, handle->remoteInput);
424    }
425    return BERR_SUCCESS;
426}
427
428static BDSP_AudioProcessing BAPE_EchoCanceller_P_GetType(BAPE_EchoCancellerAlgorithm algorithm)
429{
430    switch ( algorithm )
431    {
432    case BAPE_EchoCancellerAlgorithm_eSpeex:
433        return BDSP_AudioProcessing_eSpeexAec;
434    default:
435        return BDSP_AudioProcessing_eMax;
436    }   
437}
438
439static BERR_Code BAPE_EchoCanceller_P_ApplySpeexSettings(BAPE_EchoCancellerHandle handle, BDSP_TaskHandle task, unsigned branchId, unsigned stageId)
440{
441    BERR_Code errCode;
442    BDSP_Raaga_Audio_SpeexAECConfigParams userConfig;
443
444    errCode = BDSP_Task_GetStageSettings(task, branchId, stageId, &userConfig, sizeof(userConfig));
445    if ( errCode )
446    {
447        return BERR_TRACE(errCode);
448    }
449
450    userConfig.ui32GainResolution = handle->speexSettings.gainMode == BAPE_SpeexEchoCancellerGainMode_eBark?0:1;
451
452    errCode = BDSP_Task_SetStageSettings(task, branchId, stageId, &userConfig, sizeof(userConfig));
453    if ( errCode )
454    {
455        return BERR_TRACE(errCode);
456    }
457
458    return BERR_SUCCESS;
459}
460
461static BERR_Code BAPE_EchoCanceller_P_ApplyDspSettings(BAPE_EchoCancellerHandle handle, BDSP_TaskHandle task, unsigned branchId, unsigned stageId)
462{
463    BDBG_OBJECT_ASSERT(handle, BAPE_EchoCanceller);
464
465    BDBG_ASSERT(NULL != task);
466   
467    switch ( handle->settings.algorithm )
468    {
469    case BAPE_EchoCancellerAlgorithm_eSpeex:
470        return BAPE_EchoCanceller_P_ApplySpeexSettings(handle, task, branchId, stageId);
471    default:
472        return BERR_SUCCESS;
473    }
474}
475
476static BERR_Code BAPE_EchoCanceller_P_ConnectorSupported(struct BAPE_PathNode *pNode, BAPE_PathConnector *pConnector)
477{
478    /* We only support mono input to the echo canceller */
479    BDBG_OBJECT_ASSERT(pNode, BAPE_PathNode);
480    BDBG_OBJECT_ASSERT(pConnector, BAPE_PathConnector);
481    if ( pConnector->dataSource == BAPE_DataSource_eDspBuffer &&
482         !pConnector->compressed &&
483         pConnector->numChannelPairs == 1 &&
484         pConnector->mono )
485    {
486        return BERR_SUCCESS;
487    }
488    else
489    {
490        BDBG_ERR(("Only Mono PCM DSP input is supported"));
491        return BERR_TRACE(BERR_INVALID_PARAMETER);
492    }
493}
494
495static BERR_Code BAPE_EchoCanceller_P_Local_AllocatePathFromInput(struct BAPE_PathNode *pNode, struct BAPE_PathConnection *pConnection)
496{
497    BAPE_EchoCancellerHandle handle;
498    BERR_Code errCode;
499    unsigned sourceIndex;
500    BDSP_CIT_P_FwStageInfo *pStageInfo;
501    BDSP_CIT_P_FwStgSrcDstDetails *pDetails; 
502
503    BDBG_OBJECT_ASSERT(pNode, BAPE_PathNode);
504    BDBG_OBJECT_ASSERT(pConnection, BAPE_PathConnection);
505
506    handle = pNode->pHandle;
507
508    /* More Sanity */
509    BDBG_ASSERT(pNode == &handle->localNode);
510    BDBG_ASSERT(pConnection->pSource == handle->localInput);
511
512    /* First, make sure we have both inputs known before attempting to start. */
513    if ( NULL == handle->remoteInput )
514    {
515        BDBG_ERR(("Both the local and remote inputs must be connected to the DSP in order to start an echo canceller."));
516        return BERR_TRACE(BERR_NOT_SUPPORTED);
517    }
518
519    /* Local (microphone) inputs connect in a standard fashion as a post-processing stage.  The local task drives the process. */
520    /* Add stage to CIT and propagate task settings */
521    errCode = BAPE_DSP_P_AddProcessingStage(pConnection->pSource->pTaskCreateSettings, pConnection->pSource->branchId, pConnection->pSource->stageId, 
522                                            BDSP_AF_P_DistinctOpType_eMono_PCM,
523                                            BAPE_EchoCanceller_P_GetType(handle->settings.algorithm),
524                                            false,
525                                            &pNode->paths[0].connector.branchId, &pNode->paths[0].connector.stageId);
526    if ( errCode )
527    {
528        return BERR_TRACE(errCode);
529    }
530    pNode->paths[0].connector.pTaskCreateSettings = pConnection->pSource->pTaskCreateSettings;       
531
532    /* Also add the inter-task buffer as input for this stage */
533    pStageInfo = &pConnection->pSource->pTaskCreateSettings->pBranchInfo[pNode->paths[0].connector.branchId]->sFwStgInfo[pNode->paths[0].connector.stageId];
534    sourceIndex = pStageInfo->sStgConnectivity.ui32NumSrc;
535    BDBG_ASSERT(sourceIndex < BDSP_P_MAX_FW_STG_INPUTS);
536    pDetails = &pStageInfo->sStgConnectivity.sSrcDetails[sourceIndex];
537    pDetails->eType = BDSP_CIT_P_FwStgSrcDstType_eInterTaskDRAMBuf;
538    BMEM_Heap_ConvertAddressToOffset(handle->deviceHandle->memHandle, 
539                                     handle->pInterTaskIoDescriptor,
540                                     &pDetails->uDetails.sInterTaskDramBuffCfg.ui32IoBuffCfgAddr);
541    BMEM_Heap_ConvertAddressToOffset(handle->deviceHandle->memHandle, 
542                                     handle->pInterTaskGenericDescriptor,
543                                     &pDetails->uDetails.sInterTaskDramBuffCfg.ui32IoGenericBuffCfgAddr);
544    pStageInfo->sStgConnectivity.ui32NumSrc = sourceIndex+1;
545
546    return BERR_SUCCESS;
547}
548
549static BERR_Code BAPE_EchoCanceller_P_Remote_AllocatePathFromInput(struct BAPE_PathNode *pNode, struct BAPE_PathConnection *pConnection)
550{
551    BAPE_EchoCancellerHandle handle;
552    BDBG_OBJECT_ASSERT(pNode, BAPE_PathNode);
553    BDBG_OBJECT_ASSERT(pConnection, BAPE_PathConnection);
554
555    handle = pNode->pHandle;
556
557    /* More Sanity */
558    BDBG_ASSERT(pNode == &handle->remoteNode);
559    BDBG_ASSERT(pConnection->pSource == handle->remoteInput);
560
561    /* First, make sure we have both inputs known before attempting to start. */
562    if ( NULL == handle->localInput )
563    {
564        BDBG_ERR(("Both the local and remote inputs must be connected to the DSP in order to start an echo canceller."));
565        return BERR_TRACE(BERR_NOT_SUPPORTED);
566    }
567
568    /* Remote inputs connect as an inter-task connection.  The local task will drive the processing. */
569    pConnection->pInterTaskIoDescriptor = handle->pInterTaskIoDescriptor;
570    pConnection->pInterTaskIoBuffer = handle->pInterTaskIoBuffer;
571    pConnection->pInterTaskGenericDescriptor = handle->pInterTaskGenericDescriptor;
572    pConnection->pInterTaskGenericBuffer = handle->pInterTaskGenericBuffer;
573
574    return BERR_SUCCESS;
575}
576
577static BERR_Code BAPE_EchoCanceller_P_Local_ConfigPathFromInput(struct BAPE_PathNode *pNode, struct BAPE_PathConnection *pConnection)
578{
579    BERR_Code errCode;
580    BAPE_EchoCancellerHandle handle;
581
582    BDBG_OBJECT_ASSERT(pNode, BAPE_PathNode);
583    BDBG_OBJECT_ASSERT(pConnection, BAPE_PathConnection);
584
585    handle = pNode->pHandle;
586    BDBG_OBJECT_ASSERT(handle, BAPE_EchoCanceller);
587   
588    BDBG_ASSERT(pNode == &handle->localNode);
589    BDBG_ASSERT(pConnection->pSource == handle->localInput);
590       
591    BDBG_ASSERT(NULL != pConnection->pSource->task);
592    pNode->paths[0].connector.task = pConnection->pSource->task;
593    errCode = BAPE_EchoCanceller_P_ApplyDspSettings(handle, 
594                                                    handle->localNode.paths[0].connector.task, 
595                                                    handle->localNode.paths[0].connector.branchId, 
596                                                    handle->localNode.paths[0].connector.stageId);
597    if ( errCode )
598    {
599        return BERR_TRACE(errCode);
600    }
601
602    return BERR_SUCCESS;
603}
604
605static BERR_Code BAPE_EchoCanceller_P_Local_StartPathFromInput(struct BAPE_PathNode *pNode, struct BAPE_PathConnection *pConnection)
606{
607    BAPE_EchoCancellerHandle handle;
608    BDBG_OBJECT_ASSERT(pNode, BAPE_PathNode);
609    BDBG_OBJECT_ASSERT(pConnection, BAPE_PathConnection);
610
611    handle = pNode->pHandle;
612    BDBG_OBJECT_ASSERT(handle, BAPE_EchoCanceller);
613
614    BDBG_ASSERT(pNode == &handle->localNode);
615    BDBG_ASSERT(pConnection->pSource == handle->localInput);
616
617    BDBG_ASSERT(false == handle->localStarted);
618
619    /* When the first input starts, initialize the IO Generic Buffer RD/WR pointers to defaults. */
620    if ( false == handle->remoteStarted )
621    {
622        BAPE_EchoCanceller_P_InitInterTaskDescriptors(handle);
623    }
624
625    handle->localStarted = true;
626
627    return BERR_SUCCESS;
628}
629
630static BERR_Code BAPE_EchoCanceller_P_Remote_StartPathFromInput(struct BAPE_PathNode *pNode, struct BAPE_PathConnection *pConnection)
631{
632    BAPE_EchoCancellerHandle handle;
633    BDBG_OBJECT_ASSERT(pNode, BAPE_PathNode);
634    BDBG_OBJECT_ASSERT(pConnection, BAPE_PathConnection);
635
636    handle = pNode->pHandle;
637    BDBG_OBJECT_ASSERT(handle, BAPE_EchoCanceller);
638
639    BDBG_ASSERT(pNode == &handle->remoteNode);
640    BDBG_ASSERT(pConnection->pSource == handle->remoteInput);
641
642    /* When the first input starts, initialize the IO Generic Buffer RD/WR pointers to defaults. */
643    if ( false == handle->localStarted )
644    {
645        BAPE_EchoCanceller_P_InitInterTaskDescriptors(handle);
646    }
647
648    BDBG_ASSERT(false == handle->remoteStarted);
649    handle->remoteStarted = true;
650
651    return BERR_SUCCESS;
652}
653
654static void BAPE_EchoCanceller_P_Local_StopPathFromInput(struct BAPE_PathNode *pNode, struct BAPE_PathConnection *pConnection)
655{
656    BAPE_EchoCancellerHandle handle;
657    BDBG_OBJECT_ASSERT(pNode, BAPE_PathNode);
658    BDBG_OBJECT_ASSERT(pConnection, BAPE_PathConnection);
659
660    handle = pNode->pHandle;
661    BDBG_OBJECT_ASSERT(handle, BAPE_EchoCanceller);
662
663    BDBG_ASSERT(pNode == &handle->localNode);
664    BDBG_ASSERT(pConnection->pSource == handle->localInput);
665
666    BDBG_ASSERT(handle->localStarted);
667    handle->localStarted = false;
668}
669
670static void BAPE_EchoCanceller_P_Remote_StopPathFromInput(struct BAPE_PathNode *pNode, struct BAPE_PathConnection *pConnection)
671{
672    BAPE_EchoCancellerHandle handle;
673    BDBG_OBJECT_ASSERT(pNode, BAPE_PathNode);
674    BDBG_OBJECT_ASSERT(pConnection, BAPE_PathConnection);
675
676    handle = pNode->pHandle;
677    BDBG_OBJECT_ASSERT(handle, BAPE_EchoCanceller);
678
679    BDBG_ASSERT(pNode == &handle->remoteNode);
680    BDBG_ASSERT(pConnection->pSource == handle->remoteInput);
681
682    BDBG_ASSERT(handle->remoteStarted);
683    handle->remoteStarted = false;
684}
685
686static void BAPE_EchoCanceller_P_GetDefaultSpeexSettings(BAPE_EchoCancellerHandle handle)
687{
688    BDSP_Raaga_Audio_SpeexAECConfigParams userConfig;
689
690    BERR_TRACE(BDSP_Raaga_GetDefaultAudioProcessingSettings(BDSP_AudioProcessing_eSpeexAec, &userConfig, sizeof(userConfig)));
691
692    handle->speexSettings.gainMode = (userConfig.ui32GainResolution == 0)?BAPE_SpeexEchoCancellerGainMode_eBark:BAPE_SpeexEchoCancellerGainMode_eLinear;
693}
694
695static void BAPE_EchoCanceller_P_GetDefaultAlgorithmSettings(BAPE_EchoCancellerHandle handle)
696{
697    BAPE_EchoCanceller_P_GetDefaultSpeexSettings(handle);
698}
699
700static void BAPE_EchoCanceller_P_Local_RemoveInputCallback(struct BAPE_PathNode *pNode, BAPE_PathConnector *pConnector)
701{
702    (void)BAPE_EchoCanceller_RemoveLocalInput(pNode->pHandle, pConnector);
703}
704
705static void BAPE_EchoCanceller_P_Remote_RemoveInputCallback(struct BAPE_PathNode *pNode, BAPE_PathConnector *pConnector)
706{
707    (void)BAPE_EchoCanceller_RemoveRemoteInput(pNode->pHandle, pConnector);
708}
709
710static bool BAPE_EchoCanceller_P_IsRunning(BAPE_EchoCancellerHandle handle)
711{
712    return handle->localStarted;
713}
714
715static void BAPE_EchoCanceller_P_InitInterTaskDescriptors(BAPE_EchoCancellerHandle handle)
716{
717    BDSP_AF_P_sIO_GENERIC_BUFFER *pGenericDescriptor;
718    BDSP_AF_P_sIO_BUFFER *pIoDescriptor;
719    void *pCached;
720    uint32_t base, end;
721    unsigned i;
722
723    /* Initialize IO Buffer Descriptor */
724    (void)BMEM_Heap_ConvertAddressToCached(handle->deviceHandle->memHandle, handle->pInterTaskIoDescriptor, &pCached);
725    pIoDescriptor = pCached;
726    pIoDescriptor->eBufferType = BDSP_AF_P_BufferType_eDRAM;
727    pIoDescriptor->ui32NumBuffers = 1;  /* Mono data */
728    BMEM_ConvertAddressToOffset(handle->deviceHandle->memHandle, handle->pInterTaskIoBuffer, &base);
729    end = base+(BAPE_P_INTER_TASK_BUFFER_SIZE);
730    pIoDescriptor->sCircBuffer[0].ui32BaseAddr = base;
731    pIoDescriptor->sCircBuffer[0].ui32ReadAddr = base;
732    pIoDescriptor->sCircBuffer[0].ui32WriteAddr = base;
733    pIoDescriptor->sCircBuffer[0].ui32EndAddr = end;
734    pIoDescriptor->sCircBuffer[0].ui32WrapAddr = end;
735
736    for ( i = 1; i < BDSP_AF_P_MAX_CHANNELS; i++ )
737    {
738        BKNI_Memset(&pIoDescriptor->sCircBuffer[i], 0, sizeof(pIoDescriptor->sCircBuffer[i]));
739    }
740    BMEM_Heap_FlushCache(handle->deviceHandle->memHandle, pIoDescriptor, sizeof(BDSP_AF_P_sIO_BUFFER));
741
742    /* Initialize IO Generic Buffer Descriptor */
743    (void)BMEM_Heap_ConvertAddressToCached(handle->deviceHandle->memHandle, handle->pInterTaskGenericDescriptor, &pCached);
744    pGenericDescriptor = pCached;
745    BKNI_Memset(pGenericDescriptor, 0, sizeof(BDSP_AF_P_sIO_GENERIC_BUFFER));
746    pGenericDescriptor->eBufferType = BDSP_AF_P_BufferType_eDRAM;
747    pGenericDescriptor->ui32NumBuffers = 1;
748    BMEM_ConvertAddressToOffset(handle->deviceHandle->memHandle, handle->pInterTaskGenericBuffer, &base);
749    end = base+BDSP_AF_P_INTERTASK_IOGENBUFFER_SIZE;
750    pGenericDescriptor->sCircBuffer.ui32BaseAddr = base;
751    pGenericDescriptor->sCircBuffer.ui32ReadAddr = base;
752    pGenericDescriptor->sCircBuffer.ui32WriteAddr = base;
753    pGenericDescriptor->sCircBuffer.ui32EndAddr = end;
754    pGenericDescriptor->sCircBuffer.ui32WrapAddr = end;
755    BMEM_Heap_FlushCache(handle->deviceHandle->memHandle, pGenericDescriptor, sizeof(BDSP_AF_P_sIO_GENERIC_BUFFER));
756}
757
Note: See TracBrowser for help on using the repository browser.