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 4184333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber#define UNUSED(x) (void)(x) 4284333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber 43956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/* long start short stop */ 44956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word16 blockType2windowShape[] = {KBD_WINDOW,SINE_WINDOW,SINE_WINDOW,KBD_WINDOW}; 45956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 46956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/* 47956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong forward definitions 48956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*/ 49956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word16 advancePsychLong(PSY_DATA* psyData, 50956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong TNS_DATA* tnsData, 51956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong PSY_CONFIGURATION_LONG *hPsyConfLong, 52956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong PSY_OUT_CHANNEL* psyOutChannel, 53956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 *pScratchTns, 54956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong const TNS_DATA *tnsData2, 55956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong const Word16 ch); 56956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 57956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word16 advancePsychLongMS (PSY_DATA psyData[MAX_CHANNELS], 58956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong const PSY_CONFIGURATION_LONG *hPsyConfLong); 59956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 60956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word16 advancePsychShort(PSY_DATA* psyData, 61956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong TNS_DATA* tnsData, 62956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong const PSY_CONFIGURATION_SHORT *hPsyConfShort, 63956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong PSY_OUT_CHANNEL* psyOutChannel, 64956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 *pScratchTns, 65956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong const TNS_DATA *tnsData2, 66956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong const Word16 ch); 67956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 68956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word16 advancePsychShortMS (PSY_DATA psyData[MAX_CHANNELS], 69956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong const PSY_CONFIGURATION_SHORT *hPsyConfShort); 70956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 71956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 72956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/***************************************************************************** 73956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 74956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: PsyNew 75956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: allocates memory for psychoacoustic 76956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns: an error code 77956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* input: pointer to a psych handle 78956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 79956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/ 80956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongWord16 PsyNew(PSY_KERNEL *hPsy, Word32 nChan, VO_MEM_OPERATOR *pMemOP) 81956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 82e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 i; 83e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 *mdctSpectrum; 84e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 *scratchTNS; 85e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 *mdctDelayBuffer; 86b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 87e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard mdctSpectrum = (Word32 *)mem_malloc(pMemOP, nChan * FRAME_LEN_LONG * sizeof(Word32), 32, VO_INDEX_ENC_AAC); 88e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if(NULL == mdctSpectrum) 89e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard return 1; 90e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 91e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard scratchTNS = (Word32 *)mem_malloc(pMemOP, nChan * FRAME_LEN_LONG * sizeof(Word32), 32, VO_INDEX_ENC_AAC); 92e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if(NULL == scratchTNS) 93e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 94956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return 1; 95e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 96e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 97e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard mdctDelayBuffer = (Word16 *)mem_malloc(pMemOP, nChan * BLOCK_SWITCHING_OFFSET * sizeof(Word16), 32, VO_INDEX_ENC_AAC); 98e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if(NULL == mdctDelayBuffer) 99e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 100e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard return 1; 101e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 102e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 103956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (i=0; i<nChan; i++){ 104b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard hPsy->psyData[i].mdctDelayBuffer = mdctDelayBuffer + i*BLOCK_SWITCHING_OFFSET; 105956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsy->psyData[i].mdctSpectrum = mdctSpectrum + i*FRAME_LEN_LONG; 106956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 107956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 108956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsy->pScratchTns = scratchTNS; 109956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 110956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return 0; 111956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 112956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 113956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 114956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/***************************************************************************** 115956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 116956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: PsyDelete 117956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: allocates memory for psychoacoustic 118956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns: an error code 119956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 120956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/ 121956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongWord16 PsyDelete(PSY_KERNEL *hPsy, VO_MEM_OPERATOR *pMemOP) 122956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 123e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 nch; 124e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 125e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if(hPsy) 126e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 127e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if(hPsy->psyData[0].mdctDelayBuffer) 128e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard mem_free(pMemOP, hPsy->psyData[0].mdctDelayBuffer, VO_INDEX_ENC_AAC); 129b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 130e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if(hPsy->psyData[0].mdctSpectrum) 131e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard mem_free(pMemOP, hPsy->psyData[0].mdctSpectrum, VO_INDEX_ENC_AAC); 132e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 133e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (nch=0; nch<MAX_CHANNELS; nch++){ 134b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard hPsy->psyData[nch].mdctDelayBuffer = NULL; 135e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard hPsy->psyData[nch].mdctSpectrum = NULL; 136e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 137e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 138e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if(hPsy->pScratchTns) 139e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 140e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard mem_free(pMemOP, hPsy->pScratchTns, VO_INDEX_ENC_AAC); 141e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard hPsy->pScratchTns = NULL; 142e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 143e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 144956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 145956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return 0; 146956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 147956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 148956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 149956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/***************************************************************************** 150956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 151956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: PsyOutNew 152956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: allocates memory for psyOut struc 153956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns: an error code 154956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* input: pointer to a psych handle 155956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 156956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/ 157956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongWord16 PsyOutNew(PSY_OUT *hPsyOut, VO_MEM_OPERATOR *pMemOP) 158956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 159956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong pMemOP->Set(VO_INDEX_ENC_AAC, hPsyOut, 0, sizeof(PSY_OUT)); 160956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* 161956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong alloc some more stuff, tbd 162956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong */ 163956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return 0; 164956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 165956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 166956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/***************************************************************************** 167956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 168956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: PsyOutDelete 169956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: allocates memory for psychoacoustic 170956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns: an error code 171956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 172956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/ 173956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongWord16 PsyOutDelete(PSY_OUT *hPsyOut, VO_MEM_OPERATOR *pMemOP) 174956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 17584333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber UNUSED(hPsyOut); 17684333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber UNUSED(pMemOP); 17784333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber 178956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return 0; 179956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 180956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 181956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 182956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/***************************************************************************** 183956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 184956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: psyMainInit 185956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: initializes psychoacoustic 186956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns: an error code 187956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 188956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/ 189956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 190956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongWord16 psyMainInit(PSY_KERNEL *hPsy, 191956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 sampleRate, 192956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 bitRate, 193956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 channels, 194956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 tnsMask, 195956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 bandwidth) 196956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 197956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 ch, err; 198956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 channelBitRate = bitRate/channels; 199956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 200956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong err = InitPsyConfigurationLong(channelBitRate, 201956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong sampleRate, 202956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong bandwidth, 203e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard &(hPsy->psyConfLong)); 204e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 205956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (!err) { 206e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard hPsy->sampleRateIdx = hPsy->psyConfLong.sampRateIdx; 207956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong err = InitTnsConfigurationLong(bitRate, sampleRate, channels, 208956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &hPsy->psyConfLong.tnsConf, &hPsy->psyConfLong, tnsMask&2); 209956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 210956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 211956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (!err) 212956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong err = InitPsyConfigurationShort(channelBitRate, 213956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong sampleRate, 214956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong bandwidth, 215956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &hPsy->psyConfShort); 216956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (!err) { 217956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong err = InitTnsConfigurationShort(bitRate, sampleRate, channels, 218956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &hPsy->psyConfShort.tnsConf, &hPsy->psyConfShort, tnsMask&1); 219956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 220956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 221956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (!err) 222956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for(ch=0;ch < channels;ch++){ 223b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 224956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong InitBlockSwitching(&hPsy->psyData[ch].blockSwitchingControl, 225956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong bitRate, channels); 226956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 227956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong InitPreEchoControl(hPsy->psyData[ch].sfbThresholdnm1, 228956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsy->psyConfLong.sfbCnt, 229956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsy->psyConfLong.sfbThresholdQuiet); 230b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard hPsy->psyData[ch].mdctScalenm1 = 0; 231956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 232956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 233956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return(err); 234956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 235956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 236956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/***************************************************************************** 237956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 238956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: psyMain 239956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: psychoacoustic main function 240956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns: an error code 241956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 242956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* This function assumes that enough input data is in the modulo buffer. 243956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 244956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/ 245956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 246956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongWord16 psyMain(Word16 nChannels, 247956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong ELEMENT_INFO *elemInfo, 248b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard Word16 *timeSignal, 249956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong PSY_DATA psyData[MAX_CHANNELS], 250956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong TNS_DATA tnsData[MAX_CHANNELS], 251956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong PSY_CONFIGURATION_LONG *hPsyConfLong, 252956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong PSY_CONFIGURATION_SHORT *hPsyConfShort, 253956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS], 254956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong PSY_OUT_ELEMENT *psyOutElement, 255956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 *pScratchTns, 256956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 sampleRate) 257956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 258956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 maxSfbPerGroup[MAX_CHANNELS]; 259956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 mdctScalingArray[MAX_CHANNELS]; 260956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 261956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 ch; /* counts through channels */ 262956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 sfb; /* counts through scalefactor bands */ 263956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 line; /* counts through lines */ 264956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 channels; 265956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 maxScale; 266956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 267b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard channels = elemInfo->nChannelsInEl; 268b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard maxScale = 0; 269956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 270e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* block switching */ 271956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for(ch = 0; ch < channels; ch++) { 272956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong BlockSwitching(&psyData[ch].blockSwitchingControl, 273956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong timeSignal+elemInfo->ChannelIndex[ch], 274956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong sampleRate, 275956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong nChannels); 276956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 277956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 278956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* synch left and right block type */ 279956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong SyncBlockSwitching(&psyData[0].blockSwitchingControl, 280956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &psyData[1].blockSwitchingControl, 281956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong channels); 282956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 283956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* transform 284956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong and get maxScale (max mdctScaling) for all channels */ 285956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for(ch=0; ch<channels; ch++) { 286956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Transform_Real(psyData[ch].mdctDelayBuffer, 287956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong timeSignal+elemInfo->ChannelIndex[ch], 288956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong nChannels, 289956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[ch].mdctSpectrum, 290956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &(mdctScalingArray[ch]), 291956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[ch].blockSwitchingControl.windowSequence); 292956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong maxScale = max(maxScale, mdctScalingArray[ch]); 293956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 294956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 295956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* common scaling for all channels */ 296956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (ch=0; ch<channels; ch++) { 297956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 scaleDiff = maxScale - mdctScalingArray[ch]; 298b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 299956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (scaleDiff > 0) { 300956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 *Spectrum = psyData[ch].mdctSpectrum; 301956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for(line=0; line<FRAME_LEN_LONG; line++) { 302956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong *Spectrum = (*Spectrum) >> scaleDiff; 303956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Spectrum++; 304956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 305956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 306b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard psyData[ch].mdctScale = maxScale; 307956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 308956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 309956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (ch=0; ch<channels; ch++) { 310b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 311956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if(psyData[ch].blockSwitchingControl.windowSequence != SHORT_WINDOW) { 312956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* update long block parameter */ 313956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong advancePsychLong(&psyData[ch], 314956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &tnsData[ch], 315956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfLong, 316956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &psyOutChannel[ch], 317956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong pScratchTns, 318956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &tnsData[1 - ch], 319956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong ch); 320956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 321956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* determine maxSfb */ 322956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (sfb=hPsyConfLong->sfbCnt-1; sfb>=0; sfb--) { 323956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (line=hPsyConfLong->sfbOffset[sfb+1] - 1; line>=hPsyConfLong->sfbOffset[sfb]; line--) { 324b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 325956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (psyData[ch].mdctSpectrum[line] != 0) break; 326956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 327956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (line >= hPsyConfLong->sfbOffset[sfb]) break; 328956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 329956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong maxSfbPerGroup[ch] = sfb + 1; 330956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 331956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* Calc bandwise energies for mid and side channel 332956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Do it only if 2 channels exist */ 333b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 334956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (ch == 1) 335956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong advancePsychLongMS(psyData, hPsyConfLong); 336956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 337956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong else { 338956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong advancePsychShort(&psyData[ch], 339956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &tnsData[ch], 340956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfShort, 341956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &psyOutChannel[ch], 342956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong pScratchTns, 343956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &tnsData[1 - ch], 344956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong ch); 345956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 346956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* Calc bandwise energies for mid and side channel 347956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Do it only if 2 channels exist */ 348b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 349956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (ch == 1) 350956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong advancePsychShortMS (psyData, hPsyConfShort); 351956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 352956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 353956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 354956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* group short data */ 355956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for(ch=0; ch<channels; ch++) { 356b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 357956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (psyData[ch].blockSwitchingControl.windowSequence == SHORT_WINDOW) { 358956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong groupShortData(psyData[ch].mdctSpectrum, 359956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong pScratchTns, 360956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &psyData[ch].sfbThreshold, 361956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &psyData[ch].sfbEnergy, 362956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &psyData[ch].sfbEnergyMS, 363956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &psyData[ch].sfbSpreadedEnergy, 364956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfShort->sfbCnt, 365956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfShort->sfbOffset, 366956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfShort->sfbMinSnr, 367956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyOutElement->groupedSfbOffset[ch], 368956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &maxSfbPerGroup[ch], 369956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyOutElement->groupedSfbMinSnr[ch], 370956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[ch].blockSwitchingControl.noOfGroups, 371956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[ch].blockSwitchingControl.groupLen); 372956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 373956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 374956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 375956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 376956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#if (MAX_CHANNELS>1) 377956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* 378956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong stereo Processing 379956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong */ 380956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (channels == 2) { 381b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard psyOutElement->toolsInfo.msDigest = MS_NONE; 382956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong maxSfbPerGroup[0] = maxSfbPerGroup[1] = max(maxSfbPerGroup[0], maxSfbPerGroup[1]); 383956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 384b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 385956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (psyData[0].blockSwitchingControl.windowSequence != SHORT_WINDOW) 386956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong MsStereoProcessing(psyData[0].sfbEnergy.sfbLong, 387956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[1].sfbEnergy.sfbLong, 388956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[0].sfbEnergyMS.sfbLong, 389956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[1].sfbEnergyMS.sfbLong, 390956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[0].mdctSpectrum, 391956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[1].mdctSpectrum, 392956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[0].sfbThreshold.sfbLong, 393956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[1].sfbThreshold.sfbLong, 394956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[0].sfbSpreadedEnergy.sfbLong, 395956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[1].sfbSpreadedEnergy.sfbLong, 396956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong (Word16*)&psyOutElement->toolsInfo.msDigest, 397956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong (Word16*)psyOutElement->toolsInfo.msMask, 398956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfLong->sfbCnt, 399956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfLong->sfbCnt, 400956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong maxSfbPerGroup[0], 401956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong (const Word16*)hPsyConfLong->sfbOffset); 402956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong else 403956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong MsStereoProcessing(psyData[0].sfbEnergy.sfbLong, 404956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[1].sfbEnergy.sfbLong, 405956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[0].sfbEnergyMS.sfbLong, 406956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[1].sfbEnergyMS.sfbLong, 407956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[0].mdctSpectrum, 408956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[1].mdctSpectrum, 409956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[0].sfbThreshold.sfbLong, 410956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[1].sfbThreshold.sfbLong, 411956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[0].sfbSpreadedEnergy.sfbLong, 412956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[1].sfbSpreadedEnergy.sfbLong, 413956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong (Word16*)&psyOutElement->toolsInfo.msDigest, 414956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong (Word16*)psyOutElement->toolsInfo.msMask, 415956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[0].blockSwitchingControl.noOfGroups*hPsyConfShort->sfbCnt, 416956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfShort->sfbCnt, 417956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong maxSfbPerGroup[0], 418956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong (const Word16*)psyOutElement->groupedSfbOffset[0]); 419956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 420956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 421956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#endif /* (MAX_CHANNELS>1) */ 422956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 423956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* 424956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong build output 425956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong */ 426956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for(ch=0;ch<channels;ch++) { 427b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 428956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (psyData[ch].blockSwitchingControl.windowSequence != SHORT_WINDOW) 429956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong BuildInterface(psyData[ch].mdctSpectrum, 430956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[ch].mdctScale, 431956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &psyData[ch].sfbThreshold, 432956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &psyData[ch].sfbEnergy, 433956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &psyData[ch].sfbSpreadedEnergy, 434956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[ch].sfbEnergySum, 435956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[ch].sfbEnergySumMS, 436956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[ch].blockSwitchingControl.windowSequence, 437956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong blockType2windowShape[psyData[ch].blockSwitchingControl.windowSequence], 438956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfLong->sfbCnt, 439956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfLong->sfbOffset, 440956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong maxSfbPerGroup[ch], 441956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfLong->sfbMinSnr, 442956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[ch].blockSwitchingControl.noOfGroups, 443956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[ch].blockSwitchingControl.groupLen, 444956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &psyOutChannel[ch]); 445956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong else 446956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong BuildInterface(psyData[ch].mdctSpectrum, 447956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[ch].mdctScale, 448956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &psyData[ch].sfbThreshold, 449956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &psyData[ch].sfbEnergy, 450956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &psyData[ch].sfbSpreadedEnergy, 451956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[ch].sfbEnergySum, 452956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[ch].sfbEnergySumMS, 453956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong SHORT_WINDOW, 454956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong SINE_WINDOW, 455956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[0].blockSwitchingControl.noOfGroups*hPsyConfShort->sfbCnt, 456956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyOutElement->groupedSfbOffset[ch], 457956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong maxSfbPerGroup[ch], 458956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyOutElement->groupedSfbMinSnr[ch], 459956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[ch].blockSwitchingControl.noOfGroups, 460956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[ch].blockSwitchingControl.groupLen, 461956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &psyOutChannel[ch]); 462956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 463956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 464956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return(0); /* no error */ 465956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 466956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 467956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/***************************************************************************** 468956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 469956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: advancePsychLong 470956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: psychoacoustic for long blocks 471956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 472956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/ 473956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 474956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word16 advancePsychLong(PSY_DATA* psyData, 475956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong TNS_DATA* tnsData, 476956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong PSY_CONFIGURATION_LONG *hPsyConfLong, 477956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong PSY_OUT_CHANNEL* psyOutChannel, 478956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 *pScratchTns, 479956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong const TNS_DATA* tnsData2, 480956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong const Word16 ch) 481956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 482956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 i; 483956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 normEnergyShift = (psyData->mdctScale + 1) << 1; /* in reference code, mdct spectrum must be multipied with 2, so +1 */ 484e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 clipEnergy = hPsyConfLong->clipEnergy >> normEnergyShift; 485956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 *data0, *data1, tdata; 486956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 487956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* low pass */ 488e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard data0 = psyData->mdctSpectrum + hPsyConfLong->lowpassLine; 489956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for(i=hPsyConfLong->lowpassLine; i<FRAME_LEN_LONG; i++) { 490b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard *data0++ = 0; 491956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 492956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 493956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* Calc sfb-bandwise mdct-energies for left and right channel */ 494956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong CalcBandEnergy( psyData->mdctSpectrum, 495956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfLong->sfbOffset, 496956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfLong->sfbActive, 497956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData->sfbEnergy.sfbLong, 498956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &psyData->sfbEnergySum.sfbLong); 499956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 500956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* 501956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong TNS detect 502956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong */ 503956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong TnsDetect(tnsData, 504956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfLong->tnsConf, 505956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong pScratchTns, 506956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong (const Word16*)hPsyConfLong->sfbOffset, 507956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData->mdctSpectrum, 508956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 0, 509956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData->blockSwitchingControl.windowSequence, 510956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData->sfbEnergy.sfbLong); 511956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 512b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard /* TnsSync */ 513956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (ch == 1) { 514956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong TnsSync(tnsData, 515956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tnsData2, 516956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfLong->tnsConf, 517956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 0, 518956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData->blockSwitchingControl.windowSequence); 519956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 520956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 521b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard /* Tns Encoder */ 522956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong TnsEncode(&psyOutChannel->tnsInfo, 523956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tnsData, 524956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfLong->sfbCnt, 525956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfLong->tnsConf, 526956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfLong->lowpassLine, 527956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData->mdctSpectrum, 528956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 0, 529956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData->blockSwitchingControl.windowSequence); 530956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 531956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* first part of threshold calculation */ 532e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard data0 = psyData->sfbEnergy.sfbLong; 533e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard data1 = psyData->sfbThreshold.sfbLong; 534956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (i=hPsyConfLong->sfbCnt; i; i--) { 535956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tdata = L_mpy_ls(*data0++, hPsyConfLong->ratio); 536e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard *data1++ = min(tdata, clipEnergy); 537956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 538956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 539b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard /* Calc sfb-bandwise mdct-energies for left and right channel again */ 540956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (tnsData->dataRaw.tnsLong.subBlockInfo.tnsActive!=0) { 541b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard Word16 tnsStartBand = hPsyConfLong->tnsConf.tnsStartBand; 542956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong CalcBandEnergy( psyData->mdctSpectrum, 543956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfLong->sfbOffset+tnsStartBand, 544956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfLong->sfbActive - tnsStartBand, 545956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData->sfbEnergy.sfbLong+tnsStartBand, 546956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &psyData->sfbEnergySum.sfbLong); 547b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 548e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard data0 = psyData->sfbEnergy.sfbLong; 549e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard tdata = psyData->sfbEnergySum.sfbLong; 550956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (i=0; i<tnsStartBand; i++) 551e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard tdata += *data0++; 552e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 553956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData->sfbEnergySum.sfbLong = tdata; 554956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 555956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 556956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 557956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* spreading energy */ 558956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong SpreadingMax(hPsyConfLong->sfbCnt, 559956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfLong->sfbMaskLowFactor, 560956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfLong->sfbMaskHighFactor, 561956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData->sfbThreshold.sfbLong); 562956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 563956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* threshold in quiet */ 564e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard data0 = psyData->sfbThreshold.sfbLong; 565e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard data1 = hPsyConfLong->sfbThresholdQuiet; 566956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (i=hPsyConfLong->sfbCnt; i; i--) 567e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 568e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard *data0 = max(*data0, (*data1 >> normEnergyShift)); 569e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard data0++; data1++; 570956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 571956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 572b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard /* preecho control */ 573956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (psyData->blockSwitchingControl.windowSequence == STOP_WINDOW) { 574e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard data0 = psyData->sfbThresholdnm1; 575e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (i=hPsyConfLong->sfbCnt; i; i--) { 576b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard *data0++ = MAX_32; 577e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 578b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard psyData->mdctScalenm1 = 0; 579956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 580956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 581956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong PreEchoControl( psyData->sfbThresholdnm1, 582956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfLong->sfbCnt, 583956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfLong->maxAllowedIncreaseFactor, 584956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfLong->minRemainingThresholdFactor, 585956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData->sfbThreshold.sfbLong, 586956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData->mdctScale, 587956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData->mdctScalenm1); 588b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard psyData->mdctScalenm1 = psyData->mdctScale; 589b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 590956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 591956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (psyData->blockSwitchingControl.windowSequence== START_WINDOW) { 592e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard data0 = psyData->sfbThresholdnm1; 593956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (i=hPsyConfLong->sfbCnt; i; i--) { 594b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard *data0++ = MAX_32; 595956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 596b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard psyData->mdctScalenm1 = 0; 597956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 598956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 599956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* apply tns mult table on cb thresholds */ 600956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong ApplyTnsMultTableToRatios(hPsyConfLong->tnsConf.tnsRatioPatchLowestCb, 601956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfLong->tnsConf.tnsStartBand, 602956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tnsData->dataRaw.tnsLong.subBlockInfo, 603956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData->sfbThreshold.sfbLong); 604956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 605956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 606956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* spreaded energy */ 607e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard data0 = psyData->sfbSpreadedEnergy.sfbLong; 608e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard data1 = psyData->sfbEnergy.sfbLong; 609956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (i=hPsyConfLong->sfbCnt; i; i--) { 610b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard //psyData->sfbSpreadedEnergy.sfbLong[i] = psyData->sfbEnergy.sfbLong[i]; 611956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong *data0++ = *data1++; 612956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 613956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 614956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* spreading energy */ 615956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong SpreadingMax(hPsyConfLong->sfbCnt, 616b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard hPsyConfLong->sfbMaskLowFactorSprEn, 617956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfLong->sfbMaskHighFactorSprEn, 618956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData->sfbSpreadedEnergy.sfbLong); 619956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 620956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return 0; 621956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 622956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 623956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/***************************************************************************** 624956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 625956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: advancePsychLongMS 626b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard* description: update mdct-energies for left add or minus right channel 627956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* for long block 628956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 629956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/ 630956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word16 advancePsychLongMS (PSY_DATA psyData[MAX_CHANNELS], 631956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong const PSY_CONFIGURATION_LONG *hPsyConfLong) 632956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 633956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong CalcBandEnergyMS(psyData[0].mdctSpectrum, 634956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[1].mdctSpectrum, 635956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfLong->sfbOffset, 636956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfLong->sfbActive, 637956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[0].sfbEnergyMS.sfbLong, 638956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &psyData[0].sfbEnergySumMS.sfbLong, 639956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[1].sfbEnergyMS.sfbLong, 640956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &psyData[1].sfbEnergySumMS.sfbLong); 641956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 642956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return 0; 643956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 644956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 645956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 646956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/***************************************************************************** 647956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 648956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: advancePsychShort 649956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: psychoacoustic for short blocks 650956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 651956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/ 652956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 653956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word16 advancePsychShort(PSY_DATA* psyData, 654956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong TNS_DATA* tnsData, 655956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong const PSY_CONFIGURATION_SHORT *hPsyConfShort, 656956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong PSY_OUT_CHANNEL* psyOutChannel, 657956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 *pScratchTns, 658956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong const TNS_DATA *tnsData2, 659956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong const Word16 ch) 660956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 661956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 w; 662956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 normEnergyShift = (psyData->mdctScale + 1) << 1; /* in reference code, mdct spectrum must be multipied with 2, so +1 */ 663956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 clipEnergy = hPsyConfShort->clipEnergy >> normEnergyShift; 664b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard Word32 wOffset = 0; 6659fc4dfb69df0b5a13b7a1904272eb1dcf8113d0cMartin Storsjo Word32 *data0; 6669fc4dfb69df0b5a13b7a1904272eb1dcf8113d0cMartin Storsjo const Word32 *data1; 667956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 668956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for(w = 0; w < TRANS_FAC; w++) { 669956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 i, tdata; 670956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 671956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* low pass */ 672e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard data0 = psyData->mdctSpectrum + wOffset + hPsyConfShort->lowpassLine; 673956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for(i=hPsyConfShort->lowpassLine; i<FRAME_LEN_SHORT; i++){ 674b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard *data0++ = 0; 675956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 676956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 677956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* Calc sfb-bandwise mdct-energies for left and right channel */ 678956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong CalcBandEnergy( psyData->mdctSpectrum+wOffset, 679956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfShort->sfbOffset, 680956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfShort->sfbActive, 681956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData->sfbEnergy.sfbShort[w], 682956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &psyData->sfbEnergySum.sfbShort[w]); 683956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* 684956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong TNS 685956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong */ 686956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong TnsDetect(tnsData, 687956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfShort->tnsConf, 688956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong pScratchTns, 689956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong (const Word16*)hPsyConfShort->sfbOffset, 690956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData->mdctSpectrum+wOffset, 691956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong w, 692956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData->blockSwitchingControl.windowSequence, 693956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData->sfbEnergy.sfbShort[w]); 694956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 695956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* TnsSync */ 696956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (ch == 1) { 697956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong TnsSync(tnsData, 698956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tnsData2, 699956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfShort->tnsConf, 700956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong w, 701956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData->blockSwitchingControl.windowSequence); 702956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 703956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 704956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong TnsEncode(&psyOutChannel->tnsInfo, 705956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tnsData, 706956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfShort->sfbCnt, 707956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfShort->tnsConf, 708956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfShort->lowpassLine, 709956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData->mdctSpectrum+wOffset, 710956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong w, 711956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData->blockSwitchingControl.windowSequence); 712956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 713956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* first part of threshold calculation */ 714e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard data0 = psyData->sfbThreshold.sfbShort[w]; 715e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard data1 = psyData->sfbEnergy.sfbShort[w]; 716956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (i=hPsyConfShort->sfbCnt; i; i--) { 717956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tdata = L_mpy_ls(*data1++, hPsyConfShort->ratio); 718e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard *data0++ = min(tdata, clipEnergy); 719956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 720956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 721b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard /* Calc sfb-bandwise mdct-energies for left and right channel again */ 722956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (tnsData->dataRaw.tnsShort.subBlockInfo[w].tnsActive != 0) { 723b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard Word16 tnsStartBand = hPsyConfShort->tnsConf.tnsStartBand; 724956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong CalcBandEnergy( psyData->mdctSpectrum+wOffset, 725956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfShort->sfbOffset+tnsStartBand, 726956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong (hPsyConfShort->sfbActive - tnsStartBand), 727956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData->sfbEnergy.sfbShort[w]+tnsStartBand, 728e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard &psyData->sfbEnergySum.sfbShort[w]); 729956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 730e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard tdata = psyData->sfbEnergySum.sfbShort[w]; 731e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard data0 = psyData->sfbEnergy.sfbShort[w]; 732956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (i=tnsStartBand; i; i--) 733e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard tdata += *data0++; 734e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 735956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData->sfbEnergySum.sfbShort[w] = tdata; 736956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 737956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 738956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* spreading */ 739956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong SpreadingMax(hPsyConfShort->sfbCnt, 740956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfShort->sfbMaskLowFactor, 741956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfShort->sfbMaskHighFactor, 742956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData->sfbThreshold.sfbShort[w]); 743956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 744956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 745956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* threshold in quiet */ 746e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard data0 = psyData->sfbThreshold.sfbShort[w]; 747e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard data1 = hPsyConfShort->sfbThresholdQuiet; 748956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (i=hPsyConfShort->sfbCnt; i; i--) 749e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 750e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard *data0 = max(*data0, (*data1 >> normEnergyShift)); 751e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 752e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard data0++; data1++; 753e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 754956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 755956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 756b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard /* preecho */ 757956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong PreEchoControl( psyData->sfbThresholdnm1, 758956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfShort->sfbCnt, 759956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfShort->maxAllowedIncreaseFactor, 760956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfShort->minRemainingThresholdFactor, 761956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData->sfbThreshold.sfbShort[w], 762956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData->mdctScale, 763956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong w==0 ? psyData->mdctScalenm1 : psyData->mdctScale); 764956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 765956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* apply tns mult table on cb thresholds */ 766956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong ApplyTnsMultTableToRatios( hPsyConfShort->tnsConf.tnsRatioPatchLowestCb, 767956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfShort->tnsConf.tnsStartBand, 768956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tnsData->dataRaw.tnsShort.subBlockInfo[w], 769956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData->sfbThreshold.sfbShort[w]); 770956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 771956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* spreaded energy */ 772e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard data0 = psyData->sfbSpreadedEnergy.sfbShort[w]; 773e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard data1 = psyData->sfbEnergy.sfbShort[w]; 774956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (i=hPsyConfShort->sfbCnt; i; i--) { 775956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong *data0++ = *data1++; 776956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 777956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong SpreadingMax(hPsyConfShort->sfbCnt, 778b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard hPsyConfShort->sfbMaskLowFactorSprEn, 779956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfShort->sfbMaskHighFactorSprEn, 780956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData->sfbSpreadedEnergy.sfbShort[w]); 781956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 782956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong wOffset += FRAME_LEN_SHORT; 783956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } /* for TRANS_FAC */ 784956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 785b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard psyData->mdctScalenm1 = psyData->mdctScale; 786956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 787956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return 0; 788956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 789956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 790956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/***************************************************************************** 791956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 792956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: advancePsychShortMS 793b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard* description: update mdct-energies for left add or minus right channel 794956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* for short block 795956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 796956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/ 797956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word16 advancePsychShortMS (PSY_DATA psyData[MAX_CHANNELS], 798956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong const PSY_CONFIGURATION_SHORT *hPsyConfShort) 799956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 800956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 w, wOffset; 801b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard wOffset = 0; 802956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for(w=0; w<TRANS_FAC; w++) { 803956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong CalcBandEnergyMS(psyData[0].mdctSpectrum+wOffset, 804956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[1].mdctSpectrum+wOffset, 805956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfShort->sfbOffset, 806956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hPsyConfShort->sfbActive, 807956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[0].sfbEnergyMS.sfbShort[w], 808956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &psyData[0].sfbEnergySumMS.sfbShort[w], 809956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyData[1].sfbEnergyMS.sfbShort[w], 810956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &psyData[1].sfbEnergySumMS.sfbShort[w]); 811956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong wOffset += FRAME_LEN_SHORT; 812956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 813956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 814956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return 0; 815956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 816