LVM_Control.c revision 09d5ca3766d4bab91cdaad7206716a5747ebad77
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 20 $Author: nxp007753 $ 21 $Revision: 1316 $ 22 $Date: 2010-07-23 11:53:24 +0200 (Fri, 23 Jul 2010) $ 23 24*****************************************************************************************/ 25 26 27/****************************************************************************************/ 28/* */ 29/* Includes */ 30/* */ 31/****************************************************************************************/ 32 33#include "VectorArithmetic.h" 34#include "ScalarArithmetic.h" 35#include "LVM_Coeffs.h" 36#include "LVM_Tables.h" 37#include "LVM_Private.h" 38 39/****************************************************************************************/ 40/* */ 41/* FUNCTION: LVM_SetControlParameters */ 42/* */ 43/* DESCRIPTION: */ 44/* Sets or changes the LifeVibes module parameters. */ 45/* */ 46/* PARAMETERS: */ 47/* hInstance Instance handle */ 48/* pParams Pointer to a parameter structure */ 49/* */ 50/* RETURNS: */ 51/* LVM_SUCCESS Succeeded */ 52/* LVM_NULLADDRESS When hInstance, pParams or any control pointers are NULL */ 53/* LVM_OUTOFRANGE When any of the control parameters are out of range */ 54/* */ 55/* NOTES: */ 56/* 1. This function may be interrupted by the LVM_Process function */ 57/* */ 58/****************************************************************************************/ 59 60LVM_ReturnStatus_en LVM_SetControlParameters(LVM_Handle_t hInstance, 61 LVM_ControlParams_t *pParams) 62{ 63 LVM_Instance_t *pInstance =(LVM_Instance_t *)hInstance; 64 65 66 if ((pParams == LVM_NULL) || (hInstance == LVM_NULL)) 67 { 68 return (LVM_NULLADDRESS); 69 } 70 71 pInstance->NewParams = *pParams; 72 73 if( 74 /* General parameters */ 75 ((pParams->OperatingMode != LVM_MODE_OFF) && (pParams->OperatingMode != LVM_MODE_ON)) || 76 ((pParams->SampleRate != LVM_FS_8000) && (pParams->SampleRate != LVM_FS_11025) && (pParams->SampleRate != LVM_FS_12000) && 77 (pParams->SampleRate != LVM_FS_16000) && (pParams->SampleRate != LVM_FS_22050) && (pParams->SampleRate != LVM_FS_24000) && 78 (pParams->SampleRate != LVM_FS_32000) && (pParams->SampleRate != LVM_FS_44100) && (pParams->SampleRate != LVM_FS_48000)) || 79 ((pParams->SourceFormat != LVM_STEREO) && (pParams->SourceFormat != LVM_MONOINSTEREO) && (pParams->SourceFormat != LVM_MONO)) || 80 (pParams->SpeakerType > LVM_EX_HEADPHONES)) 81 { 82 return (LVM_OUTOFRANGE); 83 } 84 85 /* 86 * Cinema Sound parameters 87 */ 88 if((pParams->VirtualizerOperatingMode != LVM_MODE_OFF) && (pParams->VirtualizerOperatingMode != LVM_MODE_ON)) 89 { 90 return (LVM_OUTOFRANGE); 91 } 92 93 if(pParams->VirtualizerType != LVM_CONCERTSOUND) 94 { 95 return (LVM_OUTOFRANGE); 96 } 97 98 if(pParams->VirtualizerReverbLevel > LVM_VIRTUALIZER_MAX_REVERB_LEVEL) 99 { 100 return (LVM_OUTOFRANGE); 101 } 102 103 if(pParams->CS_EffectLevel < LVM_CS_MIN_EFFECT_LEVEL) 104 { 105 return (LVM_OUTOFRANGE); 106 } 107 108 /* 109 * N-Band Equalizer 110 */ 111 if(pParams->EQNB_NBands > pInstance->InstParams.EQNB_NumBands) 112 { 113 return (LVM_OUTOFRANGE); 114 } 115 116 /* Definition pointer */ 117 if ((pParams->pEQNB_BandDefinition == LVM_NULL) && 118 (pParams->EQNB_NBands != 0)) 119 { 120 return (LVM_NULLADDRESS); 121 } 122 123 /* 124 * Copy the filter definitions for the Equaliser 125 */ 126 { 127 LVM_INT16 i; 128 129 if (pParams->EQNB_NBands != 0) 130 { 131 for (i=0; i<pParams->EQNB_NBands; i++) 132 { 133 pInstance->pEQNB_BandDefs[i] = pParams->pEQNB_BandDefinition[i]; 134 } 135 pInstance->NewParams.pEQNB_BandDefinition = pInstance->pEQNB_BandDefs; 136 } 137 } 138 if( /* N-Band Equaliser parameters */ 139 ((pParams->EQNB_OperatingMode != LVM_EQNB_OFF) && (pParams->EQNB_OperatingMode != LVM_EQNB_ON)) || 140 (pParams->EQNB_NBands > pInstance->InstParams.EQNB_NumBands)) 141 { 142 return (LVM_OUTOFRANGE); 143 } 144 /* Band parameters*/ 145 { 146 LVM_INT16 i; 147 for(i = 0; i < pParams->EQNB_NBands; i++) 148 { 149 if(((pParams->pEQNB_BandDefinition[i].Frequency < LVM_EQNB_MIN_BAND_FREQ) || 150 (pParams->pEQNB_BandDefinition[i].Frequency > LVM_EQNB_MAX_BAND_FREQ)) || 151 ((pParams->pEQNB_BandDefinition[i].Gain < LVM_EQNB_MIN_BAND_GAIN) || 152 (pParams->pEQNB_BandDefinition[i].Gain > LVM_EQNB_MAX_BAND_GAIN)) || 153 ((pParams->pEQNB_BandDefinition[i].QFactor < LVM_EQNB_MIN_QFACTOR) || 154 (pParams->pEQNB_BandDefinition[i].QFactor > LVM_EQNB_MAX_QFACTOR))) 155 { 156 return (LVM_OUTOFRANGE); 157 } 158 } 159 } 160 161 /* 162 * Bass Enhancement parameters 163 */ 164 if(((pParams->BE_OperatingMode != LVM_BE_OFF) && (pParams->BE_OperatingMode != LVM_BE_ON)) || 165 ((pParams->BE_EffectLevel < LVM_BE_MIN_EFFECTLEVEL ) || (pParams->BE_EffectLevel > LVM_BE_MAX_EFFECTLEVEL ))|| 166 ((pParams->BE_CentreFreq != LVM_BE_CENTRE_55Hz) && (pParams->BE_CentreFreq != LVM_BE_CENTRE_66Hz) && 167 (pParams->BE_CentreFreq != LVM_BE_CENTRE_78Hz) && (pParams->BE_CentreFreq != LVM_BE_CENTRE_90Hz)) || 168 ((pParams->BE_HPF != LVM_BE_HPF_OFF) && (pParams->BE_HPF != LVM_BE_HPF_ON))) 169 { 170 return (LVM_OUTOFRANGE); 171 } 172 173 /* 174 * Volume Control parameters 175 */ 176 if((pParams->VC_EffectLevel < LVM_VC_MIN_EFFECTLEVEL ) || (pParams->VC_EffectLevel > LVM_VC_MAX_EFFECTLEVEL )) 177 { 178 return (LVM_OUTOFRANGE); 179 } 180 if((pParams->VC_Balance < LVM_VC_BALANCE_MIN ) || (pParams->VC_Balance > LVM_VC_BALANCE_MAX )) 181 { 182 return (LVM_OUTOFRANGE); 183 } 184 185 /* 186 * PSA parameters 187 */ 188 if( (pParams->PSA_PeakDecayRate > LVPSA_SPEED_HIGH) || 189 (pParams->PSA_Enable > LVM_PSA_ON)) 190 { 191 return (LVM_OUTOFRANGE); 192 } 193 194 195 /* 196 * Set the flag to indicate there are new parameters to use 197 * 198 * Protect the copy of the new parameters from interrupts to avoid possible problems 199 * with loss control parameters. This problem can occur if this control function is called more 200 * than once before a call to the process function. If the process function interrupts 201 * the copy to NewParams then one frame may have mixed parameters, some old and some new. 202 */ 203 pInstance->ControlPending = LVM_TRUE; 204 pInstance->NoSmoothVolume = LVM_FALSE; 205 206 return(LVM_SUCCESS); 207} 208 209 210/****************************************************************************************/ 211/* */ 212/* FUNCTION: LVM_GetControlParameters */ 213/* */ 214/* DESCRIPTION: */ 215/* Request the LifeVibes module parameters. The current parameter set is returned */ 216/* via the parameter pointer. */ 217/* */ 218/* PARAMETERS: */ 219/* hInstance Instance handle */ 220/* pParams Pointer to an empty parameter structure */ 221/* */ 222/* RETURNS: */ 223/* LVM_SUCCESS Succeeded */ 224/* LVM_NULLADDRESS when any of hInstance or pParams is NULL */ 225/* */ 226/* NOTES: */ 227/* 1. This function may be interrupted by the LVM_Process function */ 228/* */ 229/****************************************************************************************/ 230 231LVM_ReturnStatus_en LVM_GetControlParameters(LVM_Handle_t hInstance, 232 LVM_ControlParams_t *pParams) 233{ 234 LVM_Instance_t *pInstance =(LVM_Instance_t *)hInstance; 235 236 237 /* 238 * Check pointer 239 */ 240 if ((pParams == LVM_NULL) || (hInstance == LVM_NULL)) 241 { 242 return (LVM_NULLADDRESS); 243 } 244 *pParams = pInstance->NewParams; 245 246 /* 247 * Copy the filter definitions for the Equaliser 248 */ 249 { 250 LVM_INT16 i; 251 252 if (pInstance->NewParams.EQNB_NBands != 0) 253 for (i=0; i<pInstance->NewParams.EQNB_NBands; i++) 254 { 255 pInstance->pEQNB_UserDefs[i] = pInstance->pEQNB_BandDefs[i]; 256 } 257 pParams->pEQNB_BandDefinition = pInstance->pEQNB_UserDefs; 258 } 259 260 return(LVM_SUCCESS); 261} 262 263 264/****************************************************************************************/ 265/* */ 266/* FUNCTION: LVM_SetTrebleBoost */ 267/* */ 268/* DESCRIPTION: */ 269/* Enable the treble boost when the settings are appropriate, i.e. non-zero gain */ 270/* and the sample rate is high enough for the effect to be heard. */ 271/* */ 272/* PARAMETERS: */ 273/* pInstance Pointer to the instance structure */ 274/* pParams Pointer to the parameters to use */ 275/* */ 276/****************************************************************************************/ 277void LVM_SetTrebleBoost(LVM_Instance_t *pInstance, 278 LVM_ControlParams_t *pParams) 279{ 280 extern FO_C16_LShx_Coefs_t LVM_TrebleBoostCoefs[]; 281 LVM_INT16 Offset; 282 LVM_INT16 EffectLevel = 0; 283 284 /* 285 * Load the coefficients 286 */ 287 if ((pParams->TE_OperatingMode == LVM_TE_ON) && 288 (pParams->SampleRate >= TrebleBoostMinRate) && 289 (pParams->OperatingMode == LVM_MODE_ON) && 290 (pParams->TE_EffectLevel > 0)) 291 { 292 if((pParams->TE_EffectLevel == LVM_TE_LOW_MIPS) && 293 ((pParams->SpeakerType == LVM_HEADPHONES)|| 294 (pParams->SpeakerType == LVM_EX_HEADPHONES))) 295 { 296 pInstance->TE_Active = LVM_FALSE; 297 } 298 else 299 { 300 EffectLevel = pParams->TE_EffectLevel; 301 pInstance->TE_Active = LVM_TRUE; 302 } 303 304 if(pInstance->TE_Active == LVM_TRUE) 305 { 306 /* 307 * Load the coefficients and enabled the treble boost 308 */ 309 Offset = (LVM_INT16)(EffectLevel - 1 + TrebleBoostSteps * (pParams->SampleRate - TrebleBoostMinRate)); 310 FO_2I_D16F32Css_LShx_TRC_WRA_01_Init(&pInstance->pTE_State->TrebleBoost_State, 311 &pInstance->pTE_Taps->TrebleBoost_Taps, 312 &LVM_TrebleBoostCoefs[Offset]); 313 314 /* 315 * Clear the taps 316 */ 317 LoadConst_16((LVM_INT16)0, /* Value */ 318 (void *)&pInstance->pTE_Taps->TrebleBoost_Taps, /* Destination.\ 319 Cast to void: no dereferencing in function */ 320 (LVM_UINT16)(sizeof(pInstance->pTE_Taps->TrebleBoost_Taps)/sizeof(LVM_INT16))); /* Number of words */ 321 } 322 } 323 else 324 { 325 /* 326 * Disable the treble boost 327 */ 328 pInstance->TE_Active = LVM_FALSE; 329 } 330 331 return; 332} 333 334 335/************************************************************************************/ 336/* */ 337/* FUNCTION: LVM_SetVolume */ 338/* */ 339/* DESCRIPTION: */ 340/* Converts the input volume demand from dBs to linear. */ 341/* */ 342/* PARAMETERS: */ 343/* pInstance Pointer to the instance */ 344/* pParams Initialisation parameters */ 345/* */ 346/************************************************************************************/ 347void LVM_SetVolume(LVM_Instance_t *pInstance, 348 LVM_ControlParams_t *pParams) 349{ 350 351 LVM_UINT16 dBShifts; /* 6dB shifts */ 352 LVM_UINT16 dBOffset; /* Table offset */ 353 LVM_INT16 Volume = 0; /* Required volume in dBs */ 354 355 /* 356 * Limit the gain to the maximum allowed 357 */ 358 if (pParams->VC_EffectLevel > 0) 359 { 360 Volume = 0; 361 } 362 else 363 { 364 Volume = pParams->VC_EffectLevel; 365 } 366 367 /* Compensate this volume in PSA plot */ 368 if(Volume > -60) /* Limit volume loss to PSA Limits*/ 369 pInstance->PSA_GainOffset=(LVM_INT16)(-Volume);/* Loss is compensated by Gain*/ 370 else 371 pInstance->PSA_GainOffset=(LVM_INT16)60;/* Loss is compensated by Gain*/ 372 373 pInstance->VC_AVLFixedVolume = 0; 374 375 /* 376 * Set volume control and AVL volumes according to headroom and volume user setting 377 */ 378 if(pParams->OperatingMode == LVM_MODE_ON) 379 { 380 /* Default Situation with no AVL and no RS */ 381 if(pParams->EQNB_OperatingMode == LVM_EQNB_ON) 382 { 383 if(Volume > -pInstance->Headroom) 384 Volume = (LVM_INT16)-pInstance->Headroom; 385 } 386 } 387 388 /* 389 * Activate volume control if necessary 390 */ 391 pInstance->VC_Active = LVM_TRUE; 392 if (Volume != 0) 393 { 394 pInstance->VC_VolumedB = Volume; 395 } 396 else 397 { 398 pInstance->VC_VolumedB = 0; 399 } 400 401 /* 402 * Calculate the required gain and shifts 403 */ 404 dBOffset = (LVM_UINT16)((-Volume) % 6); /* Get the dBs 0-5 */ 405 dBShifts = (LVM_UINT16)(Volume / -6); /* Get the 6dB shifts */ 406 407 408 /* 409 * Set the parameters 410 */ 411 if(dBShifts == 0) 412 { 413 LVC_Mixer_SetTarget(&pInstance->VC_Volume.MixerStream[0], 414 (LVM_INT32)LVM_VolumeTable[dBOffset]); 415 } 416 else 417 { 418 LVC_Mixer_SetTarget(&pInstance->VC_Volume.MixerStream[0], 419 (((LVM_INT32)LVM_VolumeTable[dBOffset])>>dBShifts)); 420 } 421 pInstance->VC_Volume.MixerStream[0].CallbackSet = 1; 422 if(pInstance->NoSmoothVolume == LVM_TRUE) 423 { 424 LVC_Mixer_SetTimeConstant(&pInstance->VC_Volume.MixerStream[0],0,pInstance->Params.SampleRate,2); 425 } 426 else 427 { 428 LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_Volume.MixerStream[0],LVM_VC_MIXER_TIME,pInstance->Params.SampleRate,2); 429 } 430} 431 432 433/************************************************************************************/ 434/* */ 435/* FUNCTION: LVM_SetHeadroom */ 436/* */ 437/* DESCRIPTION: */ 438/* Find suitable headroom based on EQ settings. */ 439/* */ 440/* PARAMETERS: */ 441/* pInstance Pointer to the instance */ 442/* pParams Initialisation parameters */ 443/* */ 444/* RETURNS: */ 445/* void Nothing */ 446/* */ 447/* NOTES: */ 448/* */ 449/************************************************************************************/ 450void LVM_SetHeadroom(LVM_Instance_t *pInstance, 451 LVM_ControlParams_t *pParams) 452{ 453 LVM_INT16 ii, jj; 454 LVM_INT16 Headroom = 0; 455 LVM_INT16 MaxGain = 0; 456 457 458 if ((pParams->EQNB_OperatingMode == LVEQNB_ON) && (pInstance->HeadroomParams.Headroom_OperatingMode == LVM_HEADROOM_ON)) 459 { 460 /* Find typical headroom value */ 461 for(jj = 0; jj < pInstance->HeadroomParams.NHeadroomBands; jj++) 462 { 463 MaxGain = 0; 464 for( ii = 0; ii < pParams->EQNB_NBands; ii++) 465 { 466 if((pParams->pEQNB_BandDefinition[ii].Frequency >= pInstance->HeadroomParams.pHeadroomDefinition[jj].Limit_Low) && 467 (pParams->pEQNB_BandDefinition[ii].Frequency <= pInstance->HeadroomParams.pHeadroomDefinition[jj].Limit_High)) 468 { 469 if(pParams->pEQNB_BandDefinition[ii].Gain > MaxGain) 470 { 471 MaxGain = pParams->pEQNB_BandDefinition[ii].Gain; 472 } 473 } 474 } 475 476 if((MaxGain - pInstance->HeadroomParams.pHeadroomDefinition[jj].Headroom_Offset) > Headroom){ 477 Headroom = (LVM_INT16)(MaxGain - pInstance->HeadroomParams.pHeadroomDefinition[jj].Headroom_Offset); 478 } 479 } 480 481 /* Saturate */ 482 if(Headroom < 0) 483 Headroom = 0; 484 } 485 pInstance->Headroom = (LVM_UINT16)Headroom ; 486 487} 488 489 490/****************************************************************************************/ 491/* */ 492/* FUNCTION: LVM_ApplyNewSettings */ 493/* */ 494/* DESCRIPTION: */ 495/* Applies changes to parametres. This function makes no assumptions about what */ 496/* each module needs for initialisation and hence passes all parameters to all the */ 497/* the modules in turn. */ 498/* */ 499/* */ 500/* PARAMETERS: */ 501/* hInstance Instance handle */ 502/* */ 503/* RETURNS: */ 504/* LVM_Success Succeeded */ 505/* */ 506/****************************************************************************************/ 507 508LVM_ReturnStatus_en LVM_ApplyNewSettings(LVM_Handle_t hInstance) 509{ 510 LVM_Instance_t *pInstance =(LVM_Instance_t *)hInstance; 511 LVM_ControlParams_t LocalParams; 512 LVM_INT16 Count = 5; 513 514 515 /* 516 * Copy the new parameters but make sure they didn't change while copying 517 */ 518 do 519 { 520 pInstance->ControlPending = LVM_FALSE; 521 LocalParams = pInstance->NewParams; 522 pInstance->HeadroomParams = pInstance->NewHeadroomParams; 523 Count--; 524 } while ((pInstance->ControlPending != LVM_FALSE) && 525 (Count > 0)); 526 527 /* Clear all internal data if format change*/ 528 if(LocalParams.SourceFormat != pInstance->Params.SourceFormat) 529 { 530 LVM_ClearAudioBuffers(pInstance); 531 pInstance->ControlPending = LVM_FALSE; 532 } 533 534 /* 535 * Update the treble boost if required 536 */ 537 if ((pInstance->Params.SampleRate != LocalParams.SampleRate) || 538 (pInstance->Params.TE_EffectLevel != LocalParams.TE_EffectLevel) || 539 (pInstance->Params.TE_OperatingMode != LocalParams.TE_OperatingMode) || 540 (pInstance->Params.OperatingMode != LocalParams.OperatingMode) || 541 (pInstance->Params.SpeakerType != LocalParams.SpeakerType)) 542 { 543 LVM_SetTrebleBoost(pInstance, 544 &LocalParams); 545 } 546 547 /* 548 * Update the headroom if required 549 */ 550 LVM_SetHeadroom(pInstance, /* Instance pointer */ 551 &LocalParams); /* New parameters */ 552 553 /* 554 * Update the volume if required 555 */ 556 { 557 LVM_SetVolume(pInstance, /* Instance pointer */ 558 &LocalParams); /* New parameters */ 559 } 560 /* Apply balance changes*/ 561 if(pInstance->Params.VC_Balance != LocalParams.VC_Balance) 562 { 563 /* Configure Mixer module for gradual changes to volume*/ 564 if(LocalParams.VC_Balance < 0) 565 { 566 LVM_INT32 Target; 567 /* Drop in right channel volume*/ 568 Target = LVM_MAXINT_16; 569 LVC_Mixer_SetTarget(&pInstance->VC_BalanceMix.MixerStream[0],Target); 570 LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_BalanceMix.MixerStream[0],LVM_VC_MIXER_TIME,LocalParams.SampleRate,1); 571 572 Target = dB_to_Lin32((LVM_INT16)(LocalParams.VC_Balance<<4)); 573 LVC_Mixer_SetTarget(&pInstance->VC_BalanceMix.MixerStream[1],Target); 574 LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_BalanceMix.MixerStream[1],LVM_VC_MIXER_TIME,LocalParams.SampleRate,1); 575 } 576 else if(LocalParams.VC_Balance >0) 577 { 578 LVM_INT32 Target; 579 /* Drop in left channel volume*/ 580 Target = dB_to_Lin32((LVM_INT16)((-LocalParams.VC_Balance)<<4)); 581 LVC_Mixer_SetTarget(&pInstance->VC_BalanceMix.MixerStream[0],Target); 582 LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_BalanceMix.MixerStream[0],LVM_VC_MIXER_TIME,LocalParams.SampleRate,1); 583 584 Target = LVM_MAXINT_16; 585 LVC_Mixer_SetTarget(&pInstance->VC_BalanceMix.MixerStream[1],Target); 586 LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_BalanceMix.MixerStream[1],LVM_VC_MIXER_TIME,LocalParams.SampleRate,1); 587 } 588 else 589 { 590 LVM_INT32 Target; 591 /* No drop*/ 592 Target = LVM_MAXINT_16; 593 LVC_Mixer_SetTarget(&pInstance->VC_BalanceMix.MixerStream[0],Target); 594 LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_BalanceMix.MixerStream[0],LVM_VC_MIXER_TIME,LocalParams.SampleRate,1); 595 596 LVC_Mixer_SetTarget(&pInstance->VC_BalanceMix.MixerStream[1],Target); 597 LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_BalanceMix.MixerStream[1],LVM_VC_MIXER_TIME,LocalParams.SampleRate,1); 598 } 599 } 600 /* 601 * Update the bass enhancement 602 */ 603 { 604 LVDBE_ReturnStatus_en DBE_Status; 605 LVDBE_Params_t DBE_Params; 606 LVDBE_Handle_t *hDBEInstance = pInstance->hDBEInstance; 607 608 609 /* 610 * Set the new parameters 611 */ 612 if(LocalParams.OperatingMode == LVM_MODE_OFF) 613 { 614 DBE_Params.OperatingMode = LVDBE_OFF; 615 } 616 else 617 { 618 DBE_Params.OperatingMode = (LVDBE_Mode_en)LocalParams.BE_OperatingMode; 619 } 620 DBE_Params.SampleRate = (LVDBE_Fs_en)LocalParams.SampleRate; 621 DBE_Params.EffectLevel = LocalParams.BE_EffectLevel; 622 DBE_Params.CentreFrequency = (LVDBE_CentreFreq_en)LocalParams.BE_CentreFreq; 623 DBE_Params.HPFSelect = (LVDBE_FilterSelect_en)LocalParams.BE_HPF; 624 DBE_Params.HeadroomdB = 0; 625 DBE_Params.VolumeControl = LVDBE_VOLUME_OFF; 626 DBE_Params.VolumedB = 0; 627 628 /* 629 * Make the changes 630 */ 631 DBE_Status = LVDBE_Control(hDBEInstance, 632 &DBE_Params); 633 634 635 /* 636 * Quit if the changes were not accepted 637 */ 638 if (DBE_Status != LVDBE_SUCCESS) 639 { 640 return((LVM_ReturnStatus_en)DBE_Status); 641 } 642 643 644 /* 645 * Set the control flag 646 */ 647 pInstance->DBE_Active = LVM_TRUE; 648 } 649 650 /* 651 * Update the N-Band Equaliser 652 */ 653 { 654 LVEQNB_ReturnStatus_en EQNB_Status; 655 LVEQNB_Params_t EQNB_Params; 656 LVEQNB_Handle_t *hEQNBInstance = pInstance->hEQNBInstance; 657 658 659 /* 660 * Set the new parameters 661 */ 662 663 if(LocalParams.OperatingMode == LVM_MODE_OFF) 664 { 665 EQNB_Params.OperatingMode = LVEQNB_BYPASS; 666 } 667 else 668 { 669 EQNB_Params.OperatingMode = (LVEQNB_Mode_en)LocalParams.EQNB_OperatingMode; 670 } 671 672 EQNB_Params.SampleRate = (LVEQNB_Fs_en)LocalParams.SampleRate; 673 EQNB_Params.NBands = LocalParams.EQNB_NBands; 674 EQNB_Params.pBandDefinition = (LVEQNB_BandDef_t *)LocalParams.pEQNB_BandDefinition; 675 if (LocalParams.SourceFormat == LVM_STEREO) /* Mono format not supported */ 676 { 677 EQNB_Params.SourceFormat = LVEQNB_STEREO; 678 } 679 else 680 { 681 EQNB_Params.SourceFormat = LVEQNB_MONOINSTEREO; /* Force to Mono-in-Stereo mode */ 682 } 683 684 685 /* 686 * Set the control flag 687 */ 688 if ((LocalParams.OperatingMode == LVM_MODE_ON) && 689 (LocalParams.EQNB_OperatingMode == LVM_EQNB_ON)) 690 { 691 pInstance->EQNB_Active = LVM_TRUE; 692 } 693 else 694 { 695 EQNB_Params.OperatingMode = LVEQNB_BYPASS; 696 } 697 698 /* 699 * Make the changes 700 */ 701 EQNB_Status = LVEQNB_Control(hEQNBInstance, 702 &EQNB_Params); 703 704 705 /* 706 * Quit if the changes were not accepted 707 */ 708 if (EQNB_Status != LVEQNB_SUCCESS) 709 { 710 return((LVM_ReturnStatus_en)EQNB_Status); 711 } 712 713 } 714 715 716 /* 717 * Update concert sound 718 */ 719 { 720 LVCS_ReturnStatus_en CS_Status; 721 LVCS_Params_t CS_Params; 722 LVCS_Handle_t *hCSInstance = pInstance->hCSInstance; 723 LVM_Mode_en CompressorMode=LVM_MODE_ON; 724 725 /* 726 * Set the new parameters 727 */ 728 if(LocalParams.VirtualizerOperatingMode == LVM_MODE_ON) 729 { 730 CS_Params.OperatingMode = LVCS_ON; 731 } 732 else 733 { 734 CS_Params.OperatingMode = LVCS_OFF; 735 } 736 737 if((LocalParams.TE_OperatingMode == LVM_TE_ON) && (LocalParams.TE_EffectLevel == LVM_TE_LOW_MIPS)) 738 { 739 CS_Params.SpeakerType = LVCS_EX_HEADPHONES; 740 } 741 else 742 { 743 CS_Params.SpeakerType = LVCS_HEADPHONES; 744 } 745 746 if (LocalParams.SourceFormat == LVM_STEREO) /* Mono format not supported */ 747 { 748 CS_Params.SourceFormat = LVCS_STEREO; 749 } 750 else 751 { 752 CS_Params.SourceFormat = LVCS_MONOINSTEREO; /* Force to Mono-in-Stereo mode */ 753 } 754 CS_Params.SampleRate = LocalParams.SampleRate; 755 CS_Params.ReverbLevel = LocalParams.VirtualizerReverbLevel; 756 CS_Params.EffectLevel = LocalParams.CS_EffectLevel; 757 758 759 /* 760 * Set the control flag 761 */ 762 if ((LocalParams.OperatingMode == LVM_MODE_ON) && 763 (LocalParams.VirtualizerOperatingMode != LVCS_OFF)) 764 { 765 pInstance->CS_Active = LVM_TRUE; 766 } 767 else 768 { 769 CS_Params.OperatingMode = LVCS_OFF; 770 } 771 772 CS_Params.CompressorMode=CompressorMode; 773 774 /* 775 * Make the changes 776 */ 777 CS_Status = LVCS_Control(hCSInstance, 778 &CS_Params); 779 780 781 /* 782 * Quit if the changes were not accepted 783 */ 784 if (CS_Status != LVCS_SUCCESS) 785 { 786 return((LVM_ReturnStatus_en)CS_Status); 787 } 788 789 } 790 791 /* 792 * Update the Power Spectrum Analyser 793 */ 794 { 795 LVPSA_RETURN PSA_Status; 796 LVPSA_ControlParams_t PSA_Params; 797 pLVPSA_Handle_t *hPSAInstance = pInstance->hPSAInstance; 798 799 800 /* 801 * Set the new parameters 802 */ 803 PSA_Params.Fs = LocalParams.SampleRate; 804 PSA_Params.LevelDetectionSpeed = (LVPSA_LevelDetectSpeed_en)LocalParams.PSA_PeakDecayRate; 805 806 /* 807 * Make the changes 808 */ 809 if(pInstance->InstParams.PSA_Included==LVM_PSA_ON) 810 { 811 PSA_Status = LVPSA_Control(hPSAInstance, 812 &PSA_Params); 813 814 if (PSA_Status != LVPSA_OK) 815 { 816 return((LVM_ReturnStatus_en)PSA_Status); 817 } 818 819 /* 820 * Apply new settings 821 */ 822 PSA_Status = LVPSA_ApplyNewSettings ((LVPSA_InstancePr_t*)hPSAInstance); 823 if(PSA_Status != LVPSA_OK) 824 { 825 return((LVM_ReturnStatus_en)PSA_Status); 826 } 827 } 828 } 829 830 /* 831 * Update the parameters and clear the flag 832 */ 833 pInstance->Params = LocalParams; 834 835 836 return(LVM_SUCCESS); 837} 838 839 840/****************************************************************************************/ 841/* */ 842/* FUNCTION: LVM_SetHeadroomParams */ 843/* */ 844/* DESCRIPTION: */ 845/* This function is used to set the automatiuc headroom management parameters. */ 846/* */ 847/* PARAMETERS: */ 848/* hInstance Instance Handle */ 849/* pHeadroomParams Pointer to headroom parameter structure */ 850/* */ 851/* RETURNS: */ 852/* LVM_Success Succeeded */ 853/* */ 854/* NOTES: */ 855/* 1. This function may be interrupted by the LVM_Process function */ 856/* */ 857/****************************************************************************************/ 858 859LVM_ReturnStatus_en LVM_SetHeadroomParams(LVM_Handle_t hInstance, 860 LVM_HeadroomParams_t *pHeadroomParams) 861{ 862 LVM_Instance_t *pInstance =(LVM_Instance_t *)hInstance; 863 LVM_UINT16 ii, NBands; 864 865 /* Check for NULL pointers */ 866 if ((hInstance == LVM_NULL) || (pHeadroomParams == LVM_NULL)) 867 { 868 return (LVM_NULLADDRESS); 869 } 870 if ((pHeadroomParams->NHeadroomBands != 0) && (pHeadroomParams->pHeadroomDefinition == LVM_NULL)) 871 { 872 return (LVM_NULLADDRESS); 873 } 874 875 /* Consider only the LVM_HEADROOM_MAX_NBANDS first bands*/ 876 if (pHeadroomParams->NHeadroomBands > LVM_HEADROOM_MAX_NBANDS) 877 { 878 NBands = LVM_HEADROOM_MAX_NBANDS; 879 } 880 else 881 { 882 NBands = pHeadroomParams->NHeadroomBands; 883 } 884 pInstance->NewHeadroomParams.NHeadroomBands = NBands; 885 886 /* Copy settings in memory */ 887 for(ii = 0; ii < NBands; ii++) 888 { 889 pInstance->pHeadroom_BandDefs[ii] = pHeadroomParams->pHeadroomDefinition[ii]; 890 } 891 892 pInstance->NewHeadroomParams.pHeadroomDefinition = pInstance->pHeadroom_BandDefs; 893 pInstance->NewHeadroomParams.Headroom_OperatingMode = pHeadroomParams->Headroom_OperatingMode; 894 pInstance->ControlPending = LVM_TRUE; 895 896 return(LVM_SUCCESS); 897} 898 899/****************************************************************************************/ 900/* */ 901/* FUNCTION: LVM_GetHeadroomParams */ 902/* */ 903/* DESCRIPTION: */ 904/* This function is used to get the automatic headroom management parameters. */ 905/* */ 906/* PARAMETERS: */ 907/* hInstance Instance Handle */ 908/* pHeadroomParams Pointer to headroom parameter structure (output) */ 909/* */ 910/* RETURNS: */ 911/* LVM_SUCCESS Succeeded */ 912/* LVM_NULLADDRESS When hInstance or pHeadroomParams are NULL */ 913/* */ 914/* NOTES: */ 915/* 1. This function may be interrupted by the LVM_Process function */ 916/* */ 917/****************************************************************************************/ 918 919LVM_ReturnStatus_en LVM_GetHeadroomParams(LVM_Handle_t hInstance, 920 LVM_HeadroomParams_t *pHeadroomParams) 921{ 922 LVM_Instance_t *pInstance =(LVM_Instance_t *)hInstance; 923 LVM_UINT16 ii; 924 925 /* Check for NULL pointers */ 926 if ((hInstance == LVM_NULL) || (pHeadroomParams == LVM_NULL)) 927 { 928 return (LVM_NULLADDRESS); 929 } 930 931 pHeadroomParams->NHeadroomBands = pInstance->NewHeadroomParams.NHeadroomBands; 932 933 934 /* Copy settings in memory */ 935 for(ii = 0; ii < pInstance->NewHeadroomParams.NHeadroomBands; ii++) 936 { 937 pInstance->pHeadroom_UserDefs[ii] = pInstance->pHeadroom_BandDefs[ii]; 938 } 939 940 941 pHeadroomParams->pHeadroomDefinition = pInstance->pHeadroom_UserDefs; 942 pHeadroomParams->Headroom_OperatingMode = pInstance->NewHeadroomParams.Headroom_OperatingMode; 943 return(LVM_SUCCESS); 944} 945 946/****************************************************************************************/ 947/* */ 948/* FUNCTION: LVM_AlgoCallBack */ 949/* */ 950/* DESCRIPTION: */ 951/* This is the callback function of the algorithm. */ 952/* */ 953/* PARAMETERS: */ 954/* pBundleHandle Pointer to the Instance Handle */ 955/* pData Pointer to the data */ 956/* callbackId ID of the callback */ 957/* */ 958/* NOTES: */ 959/* 1. This function may be interrupted by the LVM_Process function */ 960/* */ 961/****************************************************************************************/ 962LVM_INT32 LVM_AlgoCallBack( void *pBundleHandle, 963 void *pData, 964 LVM_INT16 callbackId) 965{ 966 LVM_Instance_t *pInstance =(LVM_Instance_t *)pBundleHandle; 967 968 (void) pData; 969 970 switch(callbackId & 0xFF00){ 971 case ALGORITHM_CS_ID: 972 switch(callbackId & 0x00FF) 973 { 974 case LVCS_EVENT_ALGOFF: 975 pInstance->CS_Active = LVM_FALSE; 976 break; 977 default: 978 break; 979 } 980 break; 981 case ALGORITHM_EQNB_ID: 982 switch(callbackId & 0x00FF) 983 { 984 case LVEQNB_EVENT_ALGOFF: 985 pInstance->EQNB_Active = LVM_FALSE; 986 break; 987 default: 988 break; 989 } 990 break; 991 default: 992 break; 993 } 994 995 return 0; 996} 997 998/****************************************************************************************/ 999/* */ 1000/* FUNCTION: LVM_VCCallBack */ 1001/* */ 1002/* DESCRIPTION: */ 1003/* This is the callback function of the Volume control. */ 1004/* */ 1005/* PARAMETERS: */ 1006/* pBundleHandle Pointer to the Instance Handle */ 1007/* pGeneralPurpose Pointer to the data */ 1008/* CallBackParam ID of the callback */ 1009/* */ 1010/* NOTES: */ 1011/* 1. This function may be interrupted by the LVM_Process function */ 1012/* */ 1013/****************************************************************************************/ 1014LVM_INT32 LVM_VCCallBack(void* pBundleHandle, 1015 void* pGeneralPurpose, 1016 short CallBackParam) 1017{ 1018 LVM_Instance_t *pInstance =(LVM_Instance_t *)pBundleHandle; 1019 LVM_INT32 Target; 1020 1021 (void) pGeneralPurpose; 1022 (void) CallBackParam; 1023 1024 /* When volume mixer has reached 0 dB target then stop it to avoid 1025 unnecessary processing. */ 1026 Target = LVC_Mixer_GetTarget(&pInstance->VC_Volume.MixerStream[0]); 1027 1028 if(Target == 0x7FFF) 1029 { 1030 pInstance->VC_Active = LVM_FALSE; 1031 } 1032 return 1; 1033} 1034