| 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 | |
|---|
| 35 | BDBG_MODULE(bape_echo_canceller); |
|---|
| 36 | BDBG_OBJECT_ID(BAPE_EchoCanceller); |
|---|
| 37 | |
|---|
| 38 | static BDSP_AudioProcessing BAPE_EchoCanceller_P_GetType(BAPE_EchoCancellerAlgorithm algorithm); |
|---|
| 39 | static BERR_Code BAPE_EchoCanceller_P_ApplyDspSettings(BAPE_EchoCancellerHandle handle, BDSP_TaskHandle task, unsigned branchId, unsigned stageId); |
|---|
| 40 | static void BAPE_EchoCanceller_P_GetDefaultAlgorithmSettings(BAPE_EchoCancellerHandle handle); |
|---|
| 41 | static BERR_Code BAPE_EchoCanceller_P_ConnectorSupported(struct BAPE_PathNode *pNode, BAPE_PathConnector *pConnector); |
|---|
| 42 | static bool BAPE_EchoCanceller_P_IsRunning(BAPE_EchoCancellerHandle handle); |
|---|
| 43 | static void BAPE_EchoCanceller_P_InitInterTaskDescriptors(BAPE_EchoCancellerHandle handle); |
|---|
| 44 | |
|---|
| 45 | static BERR_Code BAPE_EchoCanceller_P_Local_AllocatePathFromInput(struct BAPE_PathNode *pNode, struct BAPE_PathConnection *pConnection); |
|---|
| 46 | static BERR_Code BAPE_EchoCanceller_P_Local_ConfigPathFromInput(struct BAPE_PathNode *pNode, struct BAPE_PathConnection *pConnection); |
|---|
| 47 | static BERR_Code BAPE_EchoCanceller_P_Local_StartPathFromInput(struct BAPE_PathNode *pNode, struct BAPE_PathConnection *pConnection); |
|---|
| 48 | static void BAPE_EchoCanceller_P_Local_StopPathFromInput(struct BAPE_PathNode *pNode, struct BAPE_PathConnection *pConnection); |
|---|
| 49 | static void BAPE_EchoCanceller_P_Local_RemoveInputCallback(struct BAPE_PathNode *pNode, BAPE_PathConnector *pConnector); |
|---|
| 50 | |
|---|
| 51 | static BERR_Code BAPE_EchoCanceller_P_Remote_AllocatePathFromInput(struct BAPE_PathNode *pNode, struct BAPE_PathConnection *pConnection); |
|---|
| 52 | static BERR_Code BAPE_EchoCanceller_P_Remote_StartPathFromInput(struct BAPE_PathNode *pNode, struct BAPE_PathConnection *pConnection); |
|---|
| 53 | static void BAPE_EchoCanceller_P_Remote_StopPathFromInput(struct BAPE_PathNode *pNode, struct BAPE_PathConnection *pConnection); |
|---|
| 54 | static void BAPE_EchoCanceller_P_Remote_RemoveInputCallback(struct BAPE_PathNode *pNode, BAPE_PathConnector *pConnector); |
|---|
| 55 | |
|---|
| 56 | void 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 | |
|---|
| 64 | BERR_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 | |
|---|
| 175 | err_generic_descriptor: |
|---|
| 176 | BMEM_Heap_Free(deviceHandle->memHandle, handle->pInterTaskIoDescriptor); |
|---|
| 177 | err_io_descriptor: |
|---|
| 178 | BMEM_Heap_Free(deviceHandle->memHandle, handle->pInterTaskIoBuffer); |
|---|
| 179 | err_io_buffer: |
|---|
| 180 | BMEM_Heap_Free(deviceHandle->memHandle, handle->pInterTaskGenericBuffer); |
|---|
| 181 | err_generic_buffer: |
|---|
| 182 | BDBG_OBJECT_DESTROY(handle, BAPE_EchoCanceller); |
|---|
| 183 | BKNI_Free(handle); |
|---|
| 184 | err_handle: |
|---|
| 185 | return errCode; |
|---|
| 186 | } |
|---|
| 187 | |
|---|
| 188 | void 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 | |
|---|
| 208 | void 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 | |
|---|
| 218 | BERR_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 | |
|---|
| 240 | void 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 | |
|---|
| 260 | BERR_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 | |
|---|
| 302 | void 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 | |
|---|
| 312 | BERR_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 | |
|---|
| 334 | BERR_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 | /*************************************************************************** |
|---|
| 357 | Summary: |
|---|
| 358 | Add a remote (far-end) input to the echo canceller |
|---|
| 359 | ***************************************************************************/ |
|---|
| 360 | BERR_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 | /*************************************************************************** |
|---|
| 383 | Summary: |
|---|
| 384 | Remove a remote (far-end) input from this processing stage |
|---|
| 385 | ***************************************************************************/ |
|---|
| 386 | BERR_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 | /*************************************************************************** |
|---|
| 409 | Summary: |
|---|
| 410 | Remove all inputs from this processing stage |
|---|
| 411 | ***************************************************************************/ |
|---|
| 412 | BERR_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 | |
|---|
| 428 | static 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 | |
|---|
| 439 | static 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 | |
|---|
| 461 | static 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 | |
|---|
| 476 | static 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 | |
|---|
| 495 | static 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 | |
|---|
| 549 | static 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 | |
|---|
| 577 | static 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 | |
|---|
| 605 | static 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 | |
|---|
| 630 | static 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 | |
|---|
| 654 | static 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 | |
|---|
| 670 | static 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 | |
|---|
| 686 | static 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 | |
|---|
| 695 | static void BAPE_EchoCanceller_P_GetDefaultAlgorithmSettings(BAPE_EchoCancellerHandle handle) |
|---|
| 696 | { |
|---|
| 697 | BAPE_EchoCanceller_P_GetDefaultSpeexSettings(handle); |
|---|
| 698 | } |
|---|
| 699 | |
|---|
| 700 | static void BAPE_EchoCanceller_P_Local_RemoveInputCallback(struct BAPE_PathNode *pNode, BAPE_PathConnector *pConnector) |
|---|
| 701 | { |
|---|
| 702 | (void)BAPE_EchoCanceller_RemoveLocalInput(pNode->pHandle, pConnector); |
|---|
| 703 | } |
|---|
| 704 | |
|---|
| 705 | static void BAPE_EchoCanceller_P_Remote_RemoveInputCallback(struct BAPE_PathNode *pNode, BAPE_PathConnector *pConnector) |
|---|
| 706 | { |
|---|
| 707 | (void)BAPE_EchoCanceller_RemoveRemoteInput(pNode->pHandle, pConnector); |
|---|
| 708 | } |
|---|
| 709 | |
|---|
| 710 | static bool BAPE_EchoCanceller_P_IsRunning(BAPE_EchoCancellerHandle handle) |
|---|
| 711 | { |
|---|
| 712 | return handle->localStarted; |
|---|
| 713 | } |
|---|
| 714 | |
|---|
| 715 | static 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 | |
|---|