psy_main.c revision b676a05348e4c516fa8b57e33b10548e6142c3f8
1e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/* 2e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** Copyright 2003-2010, VisualOn, Inc. 3e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** 4e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** Licensed under the Apache License, Version 2.0 (the "License"); 5e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** you may not use this file except in compliance with the License. 6e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** You may obtain a copy of the License at 7e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** 8e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** http://www.apache.org/licenses/LICENSE-2.0 9e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** 10e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** Unless required by applicable law or agreed to in writing, software 11e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** distributed under the License is distributed on an "AS IS" BASIS, 12e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** See the License for the specific language governing permissions and 14e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** limitations under the License. 15e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard */ 16e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/******************************************************************************* 17e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard File: psy_main.c 18e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 19e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Content: Psychoacoustic major functions 20e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 21956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*******************************************************************************/ 22956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 23e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "typedef.h" 24e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "basic_op.h" 25956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "oper_32b.h" 26956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "psy_const.h" 27956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "block_switch.h" 28956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "transform.h" 29956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "spreading.h" 30956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "pre_echo_control.h" 31956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "band_nrg.h" 32956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "psy_configuration.h" 33956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "psy_data.h" 34956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "ms_stereo.h" 35956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "interface.h" 36956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "psy_main.h" 37956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "grp_data.h" 38956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "tns_func.h" 39956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "memalign.h" 40956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 41956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/* long start short stop */ 42956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word16 blockType2windowShape[] = {KBD_WINDOW,SINE_WINDOW,SINE_WINDOW,KBD_WINDOW}; 43956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 44956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/* 45956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong forward definitions 46956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*/ 47956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word16 advancePsychLong(PSY_DATA* psyData, 48956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong TNS_DATA* tnsData, 49956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong PSY_CONFIGURATION_LONG *hPsyConfLong, 50956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong PSY_OUT_CHANNEL* psyOutChannel, 51956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 *pScratchTns, 52956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong const TNS_DATA *tnsData2, 53956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong const Word16 ch); 54956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 55956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word16 advancePsychLongMS (PSY_DATA psyData[MAX_CHANNELS], 56956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong const PSY_CONFIGURATION_LONG *hPsyConfLong); 57956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 58956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word16 advancePsychShort(PSY_DATA* psyData, 59956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong TNS_DATA* tnsData, 60956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong const PSY_CONFIGURATION_SHORT *hPsyConfShort, 61956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong PSY_OUT_CHANNEL* psyOutChannel, 62956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 *pScratchTns, 63956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong const TNS_DATA *tnsData2, 64956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong const Word16 ch); 65956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 66956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word16 advancePsychShortMS (PSY_DATA psyData[MAX_CHANNELS], 67956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong const PSY_CONFIGURATION_SHORT *hPsyConfShort); 68956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 69956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 70956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/***************************************************************************** 71956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 72956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: PsyNew 73956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: allocates memory for psychoacoustic 74956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns: an error code 75956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* input: pointer to a psych handle 76956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 77956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/ 78956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongWord16 PsyNew(PSY_KERNEL *hPsy, Word32 nChan, VO_MEM_OPERATOR *pMemOP) 79956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 80e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 i; 81e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 *mdctSpectrum; 82e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 *scratchTNS; 83e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 *mdctDelayBuffer; 84b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 85e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard mdctSpectrum = (Word32 *)mem_malloc(pMemOP, nChan * FRAME_LEN_LONG * sizeof(Word32), 32, VO_INDEX_ENC_AAC); 86e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if(NULL == mdctSpectrum) 87e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard return 1; 88e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 89e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard scratchTNS = (Word32 *)mem_malloc(pMemOP, nChan * FRAME_LEN_LONG * sizeof(Word32), 32, VO_INDEX_ENC_AAC); 90e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if(NULL == scratchTNS) 91e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 92956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return 1; 93e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 94e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 95e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard mdctDelayBuffer = (Word16 *)mem_malloc(pMemOP, nChan * BLOCK_SWITCHING_OFFSET * sizeof(Word16), 32, VO_INDEX_ENC_AAC); 96e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if(NULL == mdctDelayBuffer) 97e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 98e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard return 1; 99e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 100e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 101956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (i=0; i<nChan; i++){ 102b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard hPsy->psyData[i].mdctDelayBuffer = mdctDelayBuffer + i*BLOCK_SWITCHING_OFFSET; 103956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsy->psyData[i].mdctSpectrum = mdctSpectrum + i*FRAME_LEN_LONG; 104956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 105956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 106956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsy->pScratchTns = scratchTNS; 107956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 108956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return 0; 109956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 110956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 111956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 112956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/***************************************************************************** 113956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 114956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: PsyDelete 115956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: allocates memory for psychoacoustic 116956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns: an error code 117956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 118956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/ 119956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongWord16 PsyDelete(PSY_KERNEL *hPsy, VO_MEM_OPERATOR *pMemOP) 120956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 121e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 nch; 122e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 123e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if(hPsy) 124e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 125e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if(hPsy->psyData[0].mdctDelayBuffer) 126e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard mem_free(pMemOP, hPsy->psyData[0].mdctDelayBuffer, VO_INDEX_ENC_AAC); 127b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 128e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if(hPsy->psyData[0].mdctSpectrum) 129e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard mem_free(pMemOP, hPsy->psyData[0].mdctSpectrum, VO_INDEX_ENC_AAC); 130e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 131e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (nch=0; nch<MAX_CHANNELS; nch++){ 132b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard hPsy->psyData[nch].mdctDelayBuffer = NULL; 133e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard hPsy->psyData[nch].mdctSpectrum = NULL; 134e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 135e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 136e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if(hPsy->pScratchTns) 137e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 138e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard mem_free(pMemOP, hPsy->pScratchTns, VO_INDEX_ENC_AAC); 139e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard hPsy->pScratchTns = NULL; 140e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 141e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 142956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 143956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return 0; 144956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 145956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 146956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 147956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/***************************************************************************** 148956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 149956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: PsyOutNew 150956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: allocates memory for psyOut struc 151956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns: an error code 152956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* input: pointer to a psych handle 153956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 154956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/ 155956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongWord16 PsyOutNew(PSY_OUT *hPsyOut, VO_MEM_OPERATOR *pMemOP) 156956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 157956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong pMemOP->Set(VO_INDEX_ENC_AAC, hPsyOut, 0, sizeof(PSY_OUT)); 158956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* 159956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong alloc some more stuff, tbd 160956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong */ 161956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return 0; 162956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 163956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 164956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/***************************************************************************** 165956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 166956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: PsyOutDelete 167956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: allocates memory for psychoacoustic 168956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns: an error code 169956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 170956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/ 171956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongWord16 PsyOutDelete(PSY_OUT *hPsyOut, VO_MEM_OPERATOR *pMemOP) 172956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 173956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyOut=NULL; 174956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return 0; 175956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 176956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 177956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 178956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/***************************************************************************** 179956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 180956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: psyMainInit 181956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: initializes psychoacoustic 182956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns: an error code 183956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 184956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/ 185956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 186956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongWord16 psyMainInit(PSY_KERNEL *hPsy, 187956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 sampleRate, 188956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 bitRate, 189956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 channels, 190956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 tnsMask, 191956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 bandwidth) 192956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 193956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 ch, err; 194956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 channelBitRate = bitRate/channels; 195956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 196956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong err = InitPsyConfigurationLong(channelBitRate, 197956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong sampleRate, 198956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong bandwidth, 199e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard &(hPsy->psyConfLong)); 200e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 201956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (!err) { 202e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard hPsy->sampleRateIdx = hPsy->psyConfLong.sampRateIdx; 203956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong err = InitTnsConfigurationLong(bitRate, sampleRate, channels, 204956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &hPsy->psyConfLong.tnsConf, &hPsy->psyConfLong, tnsMask&2); 205956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 206956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 207956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (!err) 208956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong err = InitPsyConfigurationShort(channelBitRate, 209956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong sampleRate, 210956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong bandwidth, 211956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &hPsy->psyConfShort); 212956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (!err) { 213956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong err = InitTnsConfigurationShort(bitRate, sampleRate, channels, 214956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &hPsy->psyConfShort.tnsConf, &hPsy->psyConfShort, tnsMask&1); 215956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 216956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 217956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (!err) 218956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for(ch=0;ch < channels;ch++){ 219b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 220956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong InitBlockSwitching(&hPsy->psyData[ch].blockSwitchingControl, 221956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong bitRate, channels); 222956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 223956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong InitPreEchoControl(hPsy->psyData[ch].sfbThresholdnm1, 224956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsy->psyConfLong.sfbCnt, 225956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsy->psyConfLong.sfbThresholdQuiet); 226b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard hPsy->psyData[ch].mdctScalenm1 = 0; 227956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 228956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 229956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return(err); 230956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 231956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 232956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/***************************************************************************** 233956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 234956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: psyMain 235956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: psychoacoustic main function 236956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns: an error code 237956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 238956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* This function assumes that enough input data is in the modulo buffer. 239956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 240956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/ 241956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 242956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongWord16 psyMain(Word16 nChannels, 243956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong ELEMENT_INFO *elemInfo, 244b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard Word16 *timeSignal, 245956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong PSY_DATA psyData[MAX_CHANNELS], 246956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong TNS_DATA tnsData[MAX_CHANNELS], 247956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong PSY_CONFIGURATION_LONG *hPsyConfLong, 248956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong PSY_CONFIGURATION_SHORT *hPsyConfShort, 249956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS], 250956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong PSY_OUT_ELEMENT *psyOutElement, 251956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 *pScratchTns, 252956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 sampleRate) 253956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 254956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 maxSfbPerGroup[MAX_CHANNELS]; 255956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 mdctScalingArray[MAX_CHANNELS]; 256956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 257956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 ch; /* counts through channels */ 258956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 sfb; /* counts through scalefactor bands */ 259956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 line; /* counts through lines */ 260956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 channels; 261956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 maxScale; 262956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 263b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard channels = elemInfo->nChannelsInEl; 264b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard maxScale = 0; 265956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 266e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* block switching */ 267956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for(ch = 0; ch < channels; ch++) { 268956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong BlockSwitching(&psyData[ch].blockSwitchingControl, 269956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong timeSignal+elemInfo->ChannelIndex[ch], 270956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong sampleRate, 271956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong nChannels); 272956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 273956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 274956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* synch left and right block type */ 275956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong SyncBlockSwitching(&psyData[0].blockSwitchingControl, 276956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &psyData[1].blockSwitchingControl, 277956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong channels); 278956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 279956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* transform 280956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong and get maxScale (max mdctScaling) for all channels */ 281956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for(ch=0; ch<channels; ch++) { 282956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Transform_Real(psyData[ch].mdctDelayBuffer, 283956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong timeSignal+elemInfo->ChannelIndex[ch], 284956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong nChannels, 285956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[ch].mdctSpectrum, 286956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &(mdctScalingArray[ch]), 287956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[ch].blockSwitchingControl.windowSequence); 288956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong maxScale = max(maxScale, mdctScalingArray[ch]); 289956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 290956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 291956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* common scaling for all channels */ 292956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (ch=0; ch<channels; ch++) { 293956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 scaleDiff = maxScale - mdctScalingArray[ch]; 294b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 295956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (scaleDiff > 0) { 296956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 *Spectrum = psyData[ch].mdctSpectrum; 297956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for(line=0; line<FRAME_LEN_LONG; line++) { 298956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong *Spectrum = (*Spectrum) >> scaleDiff; 299956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Spectrum++; 300956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 301956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 302b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard psyData[ch].mdctScale = maxScale; 303956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 304956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 305956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (ch=0; ch<channels; ch++) { 306b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 307956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if(psyData[ch].blockSwitchingControl.windowSequence != SHORT_WINDOW) { 308956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* update long block parameter */ 309956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong advancePsychLong(&psyData[ch], 310956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &tnsData[ch], 311956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfLong, 312956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &psyOutChannel[ch], 313956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong pScratchTns, 314956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &tnsData[1 - ch], 315956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong ch); 316956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 317956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* determine maxSfb */ 318956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (sfb=hPsyConfLong->sfbCnt-1; sfb>=0; sfb--) { 319956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (line=hPsyConfLong->sfbOffset[sfb+1] - 1; line>=hPsyConfLong->sfbOffset[sfb]; line--) { 320b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 321956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (psyData[ch].mdctSpectrum[line] != 0) break; 322956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 323956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (line >= hPsyConfLong->sfbOffset[sfb]) break; 324956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 325956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong maxSfbPerGroup[ch] = sfb + 1; 326956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 327956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* Calc bandwise energies for mid and side channel 328956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Do it only if 2 channels exist */ 329b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 330956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (ch == 1) 331956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong advancePsychLongMS(psyData, hPsyConfLong); 332956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 333956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong else { 334956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong advancePsychShort(&psyData[ch], 335956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &tnsData[ch], 336956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfShort, 337956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &psyOutChannel[ch], 338956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong pScratchTns, 339956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &tnsData[1 - ch], 340956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong ch); 341956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 342956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* Calc bandwise energies for mid and side channel 343956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Do it only if 2 channels exist */ 344b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 345956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (ch == 1) 346956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong advancePsychShortMS (psyData, hPsyConfShort); 347956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 348956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 349956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 350956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* group short data */ 351956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for(ch=0; ch<channels; ch++) { 352b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 353956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (psyData[ch].blockSwitchingControl.windowSequence == SHORT_WINDOW) { 354956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong groupShortData(psyData[ch].mdctSpectrum, 355956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong pScratchTns, 356956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &psyData[ch].sfbThreshold, 357956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &psyData[ch].sfbEnergy, 358956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &psyData[ch].sfbEnergyMS, 359956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &psyData[ch].sfbSpreadedEnergy, 360956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfShort->sfbCnt, 361956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfShort->sfbOffset, 362956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfShort->sfbMinSnr, 363956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyOutElement->groupedSfbOffset[ch], 364956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &maxSfbPerGroup[ch], 365956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyOutElement->groupedSfbMinSnr[ch], 366956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[ch].blockSwitchingControl.noOfGroups, 367956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[ch].blockSwitchingControl.groupLen); 368956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 369956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 370956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 371956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 372956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#if (MAX_CHANNELS>1) 373956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* 374956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong stereo Processing 375956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong */ 376956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (channels == 2) { 377b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard psyOutElement->toolsInfo.msDigest = MS_NONE; 378956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong maxSfbPerGroup[0] = maxSfbPerGroup[1] = max(maxSfbPerGroup[0], maxSfbPerGroup[1]); 379956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 380b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 381956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (psyData[0].blockSwitchingControl.windowSequence != SHORT_WINDOW) 382956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong MsStereoProcessing(psyData[0].sfbEnergy.sfbLong, 383956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[1].sfbEnergy.sfbLong, 384956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[0].sfbEnergyMS.sfbLong, 385956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[1].sfbEnergyMS.sfbLong, 386956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[0].mdctSpectrum, 387956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[1].mdctSpectrum, 388956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[0].sfbThreshold.sfbLong, 389956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[1].sfbThreshold.sfbLong, 390956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[0].sfbSpreadedEnergy.sfbLong, 391956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[1].sfbSpreadedEnergy.sfbLong, 392956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong (Word16*)&psyOutElement->toolsInfo.msDigest, 393956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong (Word16*)psyOutElement->toolsInfo.msMask, 394956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfLong->sfbCnt, 395956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfLong->sfbCnt, 396956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong maxSfbPerGroup[0], 397956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong (const Word16*)hPsyConfLong->sfbOffset); 398956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong else 399956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong MsStereoProcessing(psyData[0].sfbEnergy.sfbLong, 400956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[1].sfbEnergy.sfbLong, 401956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[0].sfbEnergyMS.sfbLong, 402956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[1].sfbEnergyMS.sfbLong, 403956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[0].mdctSpectrum, 404956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[1].mdctSpectrum, 405956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[0].sfbThreshold.sfbLong, 406956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[1].sfbThreshold.sfbLong, 407956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[0].sfbSpreadedEnergy.sfbLong, 408956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[1].sfbSpreadedEnergy.sfbLong, 409956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong (Word16*)&psyOutElement->toolsInfo.msDigest, 410956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong (Word16*)psyOutElement->toolsInfo.msMask, 411956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[0].blockSwitchingControl.noOfGroups*hPsyConfShort->sfbCnt, 412956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfShort->sfbCnt, 413956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong maxSfbPerGroup[0], 414956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong (const Word16*)psyOutElement->groupedSfbOffset[0]); 415956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 416956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 417956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#endif /* (MAX_CHANNELS>1) */ 418956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 419956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* 420956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong build output 421956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong */ 422956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for(ch=0;ch<channels;ch++) { 423b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 424956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (psyData[ch].blockSwitchingControl.windowSequence != SHORT_WINDOW) 425956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong BuildInterface(psyData[ch].mdctSpectrum, 426956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[ch].mdctScale, 427956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &psyData[ch].sfbThreshold, 428956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &psyData[ch].sfbEnergy, 429956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &psyData[ch].sfbSpreadedEnergy, 430956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[ch].sfbEnergySum, 431956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[ch].sfbEnergySumMS, 432956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[ch].blockSwitchingControl.windowSequence, 433956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong blockType2windowShape[psyData[ch].blockSwitchingControl.windowSequence], 434956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfLong->sfbCnt, 435956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfLong->sfbOffset, 436956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong maxSfbPerGroup[ch], 437956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfLong->sfbMinSnr, 438956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[ch].blockSwitchingControl.noOfGroups, 439956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[ch].blockSwitchingControl.groupLen, 440956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &psyOutChannel[ch]); 441956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong else 442956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong BuildInterface(psyData[ch].mdctSpectrum, 443956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[ch].mdctScale, 444956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &psyData[ch].sfbThreshold, 445956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &psyData[ch].sfbEnergy, 446956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &psyData[ch].sfbSpreadedEnergy, 447956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[ch].sfbEnergySum, 448956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[ch].sfbEnergySumMS, 449956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong SHORT_WINDOW, 450956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong SINE_WINDOW, 451956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[0].blockSwitchingControl.noOfGroups*hPsyConfShort->sfbCnt, 452956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyOutElement->groupedSfbOffset[ch], 453956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong maxSfbPerGroup[ch], 454956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyOutElement->groupedSfbMinSnr[ch], 455956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[ch].blockSwitchingControl.noOfGroups, 456956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[ch].blockSwitchingControl.groupLen, 457956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &psyOutChannel[ch]); 458956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 459956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 460956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return(0); /* no error */ 461956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 462956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 463956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/***************************************************************************** 464956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 465956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: advancePsychLong 466956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: psychoacoustic for long blocks 467956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 468956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/ 469956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 470956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word16 advancePsychLong(PSY_DATA* psyData, 471956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong TNS_DATA* tnsData, 472956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong PSY_CONFIGURATION_LONG *hPsyConfLong, 473956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong PSY_OUT_CHANNEL* psyOutChannel, 474956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 *pScratchTns, 475956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong const TNS_DATA* tnsData2, 476956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong const Word16 ch) 477956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 478956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 i; 479956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 normEnergyShift = (psyData->mdctScale + 1) << 1; /* in reference code, mdct spectrum must be multipied with 2, so +1 */ 480e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 clipEnergy = hPsyConfLong->clipEnergy >> normEnergyShift; 481956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 *data0, *data1, tdata; 482956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 483956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* low pass */ 484e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard data0 = psyData->mdctSpectrum + hPsyConfLong->lowpassLine; 485956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for(i=hPsyConfLong->lowpassLine; i<FRAME_LEN_LONG; i++) { 486b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard *data0++ = 0; 487956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 488956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 489956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* Calc sfb-bandwise mdct-energies for left and right channel */ 490956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong CalcBandEnergy( psyData->mdctSpectrum, 491956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfLong->sfbOffset, 492956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfLong->sfbActive, 493956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData->sfbEnergy.sfbLong, 494956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &psyData->sfbEnergySum.sfbLong); 495956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 496956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* 497956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong TNS detect 498956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong */ 499956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong TnsDetect(tnsData, 500956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfLong->tnsConf, 501956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong pScratchTns, 502956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong (const Word16*)hPsyConfLong->sfbOffset, 503956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData->mdctSpectrum, 504956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 0, 505956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData->blockSwitchingControl.windowSequence, 506956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData->sfbEnergy.sfbLong); 507956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 508b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard /* TnsSync */ 509956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (ch == 1) { 510956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong TnsSync(tnsData, 511956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tnsData2, 512956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfLong->tnsConf, 513956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 0, 514956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData->blockSwitchingControl.windowSequence); 515956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 516956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 517b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard /* Tns Encoder */ 518956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong TnsEncode(&psyOutChannel->tnsInfo, 519956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tnsData, 520956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfLong->sfbCnt, 521956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfLong->tnsConf, 522956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfLong->lowpassLine, 523956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData->mdctSpectrum, 524956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 0, 525956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData->blockSwitchingControl.windowSequence); 526956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 527956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* first part of threshold calculation */ 528e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard data0 = psyData->sfbEnergy.sfbLong; 529e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard data1 = psyData->sfbThreshold.sfbLong; 530956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (i=hPsyConfLong->sfbCnt; i; i--) { 531956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tdata = L_mpy_ls(*data0++, hPsyConfLong->ratio); 532e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard *data1++ = min(tdata, clipEnergy); 533956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 534956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 535b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard /* Calc sfb-bandwise mdct-energies for left and right channel again */ 536956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (tnsData->dataRaw.tnsLong.subBlockInfo.tnsActive!=0) { 537b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard Word16 tnsStartBand = hPsyConfLong->tnsConf.tnsStartBand; 538956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong CalcBandEnergy( psyData->mdctSpectrum, 539956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfLong->sfbOffset+tnsStartBand, 540956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfLong->sfbActive - tnsStartBand, 541956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData->sfbEnergy.sfbLong+tnsStartBand, 542956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &psyData->sfbEnergySum.sfbLong); 543b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 544e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard data0 = psyData->sfbEnergy.sfbLong; 545e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard tdata = psyData->sfbEnergySum.sfbLong; 546956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (i=0; i<tnsStartBand; i++) 547e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard tdata += *data0++; 548e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 549956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData->sfbEnergySum.sfbLong = tdata; 550956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 551956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 552956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 553956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* spreading energy */ 554956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong SpreadingMax(hPsyConfLong->sfbCnt, 555956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfLong->sfbMaskLowFactor, 556956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfLong->sfbMaskHighFactor, 557956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData->sfbThreshold.sfbLong); 558956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 559956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* threshold in quiet */ 560e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard data0 = psyData->sfbThreshold.sfbLong; 561e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard data1 = hPsyConfLong->sfbThresholdQuiet; 562956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (i=hPsyConfLong->sfbCnt; i; i--) 563e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 564e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard *data0 = max(*data0, (*data1 >> normEnergyShift)); 565e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard data0++; data1++; 566956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 567956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 568b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard /* preecho control */ 569956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (psyData->blockSwitchingControl.windowSequence == STOP_WINDOW) { 570e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard data0 = psyData->sfbThresholdnm1; 571e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (i=hPsyConfLong->sfbCnt; i; i--) { 572b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard *data0++ = MAX_32; 573e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 574b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard psyData->mdctScalenm1 = 0; 575956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 576956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 577956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong PreEchoControl( psyData->sfbThresholdnm1, 578956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfLong->sfbCnt, 579956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfLong->maxAllowedIncreaseFactor, 580956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfLong->minRemainingThresholdFactor, 581956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData->sfbThreshold.sfbLong, 582956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData->mdctScale, 583956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData->mdctScalenm1); 584b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard psyData->mdctScalenm1 = psyData->mdctScale; 585b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 586956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 587956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (psyData->blockSwitchingControl.windowSequence== START_WINDOW) { 588e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard data0 = psyData->sfbThresholdnm1; 589956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (i=hPsyConfLong->sfbCnt; i; i--) { 590b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard *data0++ = MAX_32; 591956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 592b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard psyData->mdctScalenm1 = 0; 593956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 594956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 595956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* apply tns mult table on cb thresholds */ 596956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong ApplyTnsMultTableToRatios(hPsyConfLong->tnsConf.tnsRatioPatchLowestCb, 597956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfLong->tnsConf.tnsStartBand, 598956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tnsData->dataRaw.tnsLong.subBlockInfo, 599956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData->sfbThreshold.sfbLong); 600956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 601956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 602956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* spreaded energy */ 603e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard data0 = psyData->sfbSpreadedEnergy.sfbLong; 604e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard data1 = psyData->sfbEnergy.sfbLong; 605956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (i=hPsyConfLong->sfbCnt; i; i--) { 606b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard //psyData->sfbSpreadedEnergy.sfbLong[i] = psyData->sfbEnergy.sfbLong[i]; 607956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong *data0++ = *data1++; 608956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 609956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 610956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* spreading energy */ 611956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong SpreadingMax(hPsyConfLong->sfbCnt, 612b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard hPsyConfLong->sfbMaskLowFactorSprEn, 613956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfLong->sfbMaskHighFactorSprEn, 614956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData->sfbSpreadedEnergy.sfbLong); 615956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 616956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return 0; 617956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 618956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 619956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/***************************************************************************** 620956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 621956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: advancePsychLongMS 622b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard* description: update mdct-energies for left add or minus right channel 623956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* for long block 624956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 625956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/ 626956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word16 advancePsychLongMS (PSY_DATA psyData[MAX_CHANNELS], 627956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong const PSY_CONFIGURATION_LONG *hPsyConfLong) 628956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 629956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong CalcBandEnergyMS(psyData[0].mdctSpectrum, 630956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[1].mdctSpectrum, 631956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfLong->sfbOffset, 632956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfLong->sfbActive, 633956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[0].sfbEnergyMS.sfbLong, 634956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &psyData[0].sfbEnergySumMS.sfbLong, 635956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[1].sfbEnergyMS.sfbLong, 636956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &psyData[1].sfbEnergySumMS.sfbLong); 637956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 638956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return 0; 639956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 640956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 641956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 642956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/***************************************************************************** 643956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 644956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: advancePsychShort 645956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: psychoacoustic for short blocks 646956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 647956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/ 648956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 649956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word16 advancePsychShort(PSY_DATA* psyData, 650956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong TNS_DATA* tnsData, 651956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong const PSY_CONFIGURATION_SHORT *hPsyConfShort, 652956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong PSY_OUT_CHANNEL* psyOutChannel, 653956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 *pScratchTns, 654956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong const TNS_DATA *tnsData2, 655956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong const Word16 ch) 656956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 657956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 w; 658956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 normEnergyShift = (psyData->mdctScale + 1) << 1; /* in reference code, mdct spectrum must be multipied with 2, so +1 */ 659956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 clipEnergy = hPsyConfShort->clipEnergy >> normEnergyShift; 660b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard Word32 wOffset = 0; 661956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 *data0, *data1; 662956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 663956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for(w = 0; w < TRANS_FAC; w++) { 664956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 i, tdata; 665956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 666956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* low pass */ 667e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard data0 = psyData->mdctSpectrum + wOffset + hPsyConfShort->lowpassLine; 668956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for(i=hPsyConfShort->lowpassLine; i<FRAME_LEN_SHORT; i++){ 669b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard *data0++ = 0; 670956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 671956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 672956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* Calc sfb-bandwise mdct-energies for left and right channel */ 673956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong CalcBandEnergy( psyData->mdctSpectrum+wOffset, 674956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfShort->sfbOffset, 675956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfShort->sfbActive, 676956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData->sfbEnergy.sfbShort[w], 677956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &psyData->sfbEnergySum.sfbShort[w]); 678956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* 679956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong TNS 680956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong */ 681956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong TnsDetect(tnsData, 682956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfShort->tnsConf, 683956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong pScratchTns, 684956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong (const Word16*)hPsyConfShort->sfbOffset, 685956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData->mdctSpectrum+wOffset, 686956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong w, 687956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData->blockSwitchingControl.windowSequence, 688956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData->sfbEnergy.sfbShort[w]); 689956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 690956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* TnsSync */ 691956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (ch == 1) { 692956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong TnsSync(tnsData, 693956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tnsData2, 694956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfShort->tnsConf, 695956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong w, 696956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData->blockSwitchingControl.windowSequence); 697956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 698956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 699956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong TnsEncode(&psyOutChannel->tnsInfo, 700956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tnsData, 701956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfShort->sfbCnt, 702956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfShort->tnsConf, 703956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfShort->lowpassLine, 704956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData->mdctSpectrum+wOffset, 705956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong w, 706956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData->blockSwitchingControl.windowSequence); 707956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 708956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* first part of threshold calculation */ 709e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard data0 = psyData->sfbThreshold.sfbShort[w]; 710e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard data1 = psyData->sfbEnergy.sfbShort[w]; 711956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (i=hPsyConfShort->sfbCnt; i; i--) { 712956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tdata = L_mpy_ls(*data1++, hPsyConfShort->ratio); 713e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard *data0++ = min(tdata, clipEnergy); 714956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 715956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 716b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard /* Calc sfb-bandwise mdct-energies for left and right channel again */ 717956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (tnsData->dataRaw.tnsShort.subBlockInfo[w].tnsActive != 0) { 718b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard Word16 tnsStartBand = hPsyConfShort->tnsConf.tnsStartBand; 719956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong CalcBandEnergy( psyData->mdctSpectrum+wOffset, 720956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfShort->sfbOffset+tnsStartBand, 721956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong (hPsyConfShort->sfbActive - tnsStartBand), 722956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData->sfbEnergy.sfbShort[w]+tnsStartBand, 723e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard &psyData->sfbEnergySum.sfbShort[w]); 724956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 725e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard tdata = psyData->sfbEnergySum.sfbShort[w]; 726e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard data0 = psyData->sfbEnergy.sfbShort[w]; 727956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (i=tnsStartBand; i; i--) 728e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard tdata += *data0++; 729e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 730956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData->sfbEnergySum.sfbShort[w] = tdata; 731956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 732956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 733956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* spreading */ 734956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong SpreadingMax(hPsyConfShort->sfbCnt, 735956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfShort->sfbMaskLowFactor, 736956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfShort->sfbMaskHighFactor, 737956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData->sfbThreshold.sfbShort[w]); 738956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 739956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 740956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* threshold in quiet */ 741e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard data0 = psyData->sfbThreshold.sfbShort[w]; 742e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard data1 = hPsyConfShort->sfbThresholdQuiet; 743956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (i=hPsyConfShort->sfbCnt; i; i--) 744e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 745e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard *data0 = max(*data0, (*data1 >> normEnergyShift)); 746e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 747e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard data0++; data1++; 748e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 749956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 750956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 751b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard /* preecho */ 752956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong PreEchoControl( psyData->sfbThresholdnm1, 753956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfShort->sfbCnt, 754956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfShort->maxAllowedIncreaseFactor, 755956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfShort->minRemainingThresholdFactor, 756956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData->sfbThreshold.sfbShort[w], 757956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData->mdctScale, 758956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong w==0 ? psyData->mdctScalenm1 : psyData->mdctScale); 759956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 760956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* apply tns mult table on cb thresholds */ 761956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong ApplyTnsMultTableToRatios( hPsyConfShort->tnsConf.tnsRatioPatchLowestCb, 762956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfShort->tnsConf.tnsStartBand, 763956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tnsData->dataRaw.tnsShort.subBlockInfo[w], 764956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData->sfbThreshold.sfbShort[w]); 765956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 766956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* spreaded energy */ 767e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard data0 = psyData->sfbSpreadedEnergy.sfbShort[w]; 768e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard data1 = psyData->sfbEnergy.sfbShort[w]; 769956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (i=hPsyConfShort->sfbCnt; i; i--) { 770956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong *data0++ = *data1++; 771956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 772956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong SpreadingMax(hPsyConfShort->sfbCnt, 773b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard hPsyConfShort->sfbMaskLowFactorSprEn, 774956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfShort->sfbMaskHighFactorSprEn, 775956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData->sfbSpreadedEnergy.sfbShort[w]); 776956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 777956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong wOffset += FRAME_LEN_SHORT; 778956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } /* for TRANS_FAC */ 779956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 780b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard psyData->mdctScalenm1 = psyData->mdctScale; 781956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 782956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return 0; 783956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 784956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 785956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/***************************************************************************** 786956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 787956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: advancePsychShortMS 788b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard* description: update mdct-energies for left add or minus right channel 789956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* for short block 790956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 791956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/ 792956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word16 advancePsychShortMS (PSY_DATA psyData[MAX_CHANNELS], 793956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong const PSY_CONFIGURATION_SHORT *hPsyConfShort) 794956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 795956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 w, wOffset; 796b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard wOffset = 0; 797956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for(w=0; w<TRANS_FAC; w++) { 798956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong CalcBandEnergyMS(psyData[0].mdctSpectrum+wOffset, 799956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[1].mdctSpectrum+wOffset, 800956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfShort->sfbOffset, 801956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfShort->sfbActive, 802956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[0].sfbEnergyMS.sfbShort[w], 803956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &psyData[0].sfbEnergySumMS.sfbShort[w], 804956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[1].sfbEnergyMS.sfbShort[w], 805956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &psyData[1].sfbEnergySumMS.sfbShort[w]); 806956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong wOffset += FRAME_LEN_SHORT; 807956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 808956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 809956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return 0; 810956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 811