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