18e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels/******************************************************************** 28e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels * * 38e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * 48e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * 58e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * 68e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * 78e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels * * 88e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2010 * 98e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels * by the Xiph.Org Foundation http://www.xiph.org/ * 108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels * * 118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels ******************************************************************** 128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels function: psychoacoustics not including preecho 148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels last mod: $Id: psy.c 17077 2010-03-26 06:22:19Z xiphmont $ 158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels ********************************************************************/ 178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include <stdlib.h> 198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include <math.h> 208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include <string.h> 218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "vorbis/codec.h" 228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "codec_internal.h" 238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "masking.h" 258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "psy.h" 268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "os.h" 278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "lpc.h" 288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "smallft.h" 298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "scales.h" 308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "misc.h" 318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#define NEGINF -9999.f 338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic const double stereo_threshholds[]={0.0, .5, 1.0, 1.5, 2.5, 4.5, 8.5, 16.5, 9e10}; 348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic const double stereo_threshholds_limited[]={0.0, .5, 1.0, 1.5, 2.0, 2.5, 4.5, 8.5, 9e10}; 358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsvorbis_look_psy_global *_vp_global_look(vorbis_info *vi){ 378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels codec_setup_info *ci=vi->codec_setup; 388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels vorbis_info_psy_global *gi=&ci->psy_g_param; 398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels vorbis_look_psy_global *look=_ogg_calloc(1,sizeof(*look)); 408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels look->channels=vi->channels; 428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels look->ampmax=-9999.; 448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels look->gi=gi; 458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels return(look); 468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels} 478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsvoid _vp_global_free(vorbis_look_psy_global *look){ 498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(look){ 508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels memset(look,0,sizeof(*look)); 518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels _ogg_free(look); 528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels} 548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsvoid _vi_gpsy_free(vorbis_info_psy_global *i){ 568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(i){ 578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels memset(i,0,sizeof(*i)); 588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels _ogg_free(i); 598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels} 618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsvoid _vi_psy_free(vorbis_info_psy *i){ 638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(i){ 648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels memset(i,0,sizeof(*i)); 658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels _ogg_free(i); 668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels} 688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic void min_curve(float *c, 708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float *c2){ 718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels int i; 728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(i=0;i<EHMER_MAX;i++)if(c2[i]<c[i])c[i]=c2[i]; 738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels} 748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic void max_curve(float *c, 758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float *c2){ 768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels int i; 778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(i=0;i<EHMER_MAX;i++)if(c2[i]>c[i])c[i]=c2[i]; 788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels} 798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic void attenuate_curve(float *c,float att){ 818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels int i; 828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(i=0;i<EHMER_MAX;i++) 838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels c[i]+=att; 848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels} 858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic float ***setup_tone_curves(float curveatt_dB[P_BANDS],float binHz,int n, 878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float center_boost, float center_decay_rate){ 888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels int i,j,k,m; 898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float ath[EHMER_MAX]; 908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float workc[P_BANDS][P_LEVELS][EHMER_MAX]; 918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float athc[P_LEVELS][EHMER_MAX]; 928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float *brute_buffer=alloca(n*sizeof(*brute_buffer)); 938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float ***ret=_ogg_malloc(sizeof(*ret)*P_BANDS); 958e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 968e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels memset(workc,0,sizeof(workc)); 978e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 988e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(i=0;i<P_BANDS;i++){ 998e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels /* we add back in the ATH to avoid low level curves falling off to 1008e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels -infinity and unnecessarily cutting off high level curves in the 1018e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels curve limiting (last step). */ 1028e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 1038e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels /* A half-band's settings must be valid over the whole band, and 1048e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels it's better to mask too little than too much */ 1058e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels int ath_offset=i*4; 1068e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(j=0;j<EHMER_MAX;j++){ 1078e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float min=999.; 1088e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(k=0;k<4;k++) 1098e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(j+k+ath_offset<MAX_ATH){ 1108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(min>ATH[j+k+ath_offset])min=ATH[j+k+ath_offset]; 1118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels }else{ 1128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(min>ATH[MAX_ATH-1])min=ATH[MAX_ATH-1]; 1138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 1148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels ath[j]=min; 1158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 1168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 1178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels /* copy curves into working space, replicate the 50dB curve to 30 1188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels and 40, replicate the 100dB curve to 110 */ 1198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(j=0;j<6;j++) 1208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels memcpy(workc[i][j+2],tonemasks[i][j],EHMER_MAX*sizeof(*tonemasks[i][j])); 1218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels memcpy(workc[i][0],tonemasks[i][0],EHMER_MAX*sizeof(*tonemasks[i][0])); 1228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels memcpy(workc[i][1],tonemasks[i][0],EHMER_MAX*sizeof(*tonemasks[i][0])); 1238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 1248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels /* apply centered curve boost/decay */ 1258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(j=0;j<P_LEVELS;j++){ 1268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(k=0;k<EHMER_MAX;k++){ 1278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float adj=center_boost+abs(EHMER_OFFSET-k)*center_decay_rate; 1288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(adj<0. && center_boost>0)adj=0.; 1298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(adj>0. && center_boost<0)adj=0.; 1308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels workc[i][j][k]+=adj; 1318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 1328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 1338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 1348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels /* normalize curves so the driving amplitude is 0dB */ 1358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels /* make temp curves with the ATH overlayed */ 1368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(j=0;j<P_LEVELS;j++){ 1378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels attenuate_curve(workc[i][j],curveatt_dB[i]+100.-(j<2?2:j)*10.-P_LEVEL_0); 1388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels memcpy(athc[j],ath,EHMER_MAX*sizeof(**athc)); 1398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels attenuate_curve(athc[j],+100.-j*10.f-P_LEVEL_0); 1408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels max_curve(athc[j],workc[i][j]); 1418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 1428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 1438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels /* Now limit the louder curves. 1448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 1458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels the idea is this: We don't know what the playback attenuation 1468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels will be; 0dB SL moves every time the user twiddles the volume 1478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels knob. So that means we have to use a single 'most pessimal' curve 1488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for all masking amplitudes, right? Wrong. The *loudest* sound 1498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels can be in (we assume) a range of ...+100dB] SL. However, sounds 1508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 20dB down will be in a range ...+80], 40dB down is from ...+60], 1518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels etc... */ 1528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 1538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(j=1;j<P_LEVELS;j++){ 1548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels min_curve(athc[j],athc[j-1]); 1558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels min_curve(workc[i][j],athc[j]); 1568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 1578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 1588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 1598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(i=0;i<P_BANDS;i++){ 1608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels int hi_curve,lo_curve,bin; 1618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels ret[i]=_ogg_malloc(sizeof(**ret)*P_LEVELS); 1628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 1638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels /* low frequency curves are measured with greater resolution than 1648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels the MDCT/FFT will actually give us; we want the curve applied 1658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels to the tone data to be pessimistic and thus apply the minimum 1668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels masking possible for a given bin. That means that a single bin 1678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels could span more than one octave and that the curve will be a 1688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels composite of multiple octaves. It also may mean that a single 1698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels bin may span > an eighth of an octave and that the eighth 1708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels octave values may also be composited. */ 1718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 1728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels /* which octave curves will we be compositing? */ 1738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels bin=floor(fromOC(i*.5)/binHz); 1748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels lo_curve= ceil(toOC(bin*binHz+1)*2); 1758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels hi_curve= floor(toOC((bin+1)*binHz)*2); 1768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(lo_curve>i)lo_curve=i; 1778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(lo_curve<0)lo_curve=0; 1788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(hi_curve>=P_BANDS)hi_curve=P_BANDS-1; 1798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 1808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(m=0;m<P_LEVELS;m++){ 1818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels ret[i][m]=_ogg_malloc(sizeof(***ret)*(EHMER_MAX+2)); 1828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 1838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(j=0;j<n;j++)brute_buffer[j]=999.; 1848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 1858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels /* render the curve into bins, then pull values back into curve. 1868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels The point is that any inherent subsampling aliasing results in 1878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels a safe minimum */ 1888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(k=lo_curve;k<=hi_curve;k++){ 1898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels int l=0; 1908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 1918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(j=0;j<EHMER_MAX;j++){ 1928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels int lo_bin= fromOC(j*.125+k*.5-2.0625)/binHz; 1938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels int hi_bin= fromOC(j*.125+k*.5-1.9375)/binHz+1; 1948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 1958e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(lo_bin<0)lo_bin=0; 1968e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(lo_bin>n)lo_bin=n; 1978e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(lo_bin<l)l=lo_bin; 1988e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(hi_bin<0)hi_bin=0; 1998e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(hi_bin>n)hi_bin=n; 2008e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 2018e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(;l<hi_bin && l<n;l++) 2028e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(brute_buffer[l]>workc[k][m][j]) 2038e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels brute_buffer[l]=workc[k][m][j]; 2048e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 2058e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 2068e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(;l<n;l++) 2078e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(brute_buffer[l]>workc[k][m][EHMER_MAX-1]) 2088e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels brute_buffer[l]=workc[k][m][EHMER_MAX-1]; 2098e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 2108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 2118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 2128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels /* be equally paranoid about being valid up to next half ocatve */ 2138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(i+1<P_BANDS){ 2148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels int l=0; 2158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels k=i+1; 2168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(j=0;j<EHMER_MAX;j++){ 2178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels int lo_bin= fromOC(j*.125+i*.5-2.0625)/binHz; 2188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels int hi_bin= fromOC(j*.125+i*.5-1.9375)/binHz+1; 2198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 2208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(lo_bin<0)lo_bin=0; 2218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(lo_bin>n)lo_bin=n; 2228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(lo_bin<l)l=lo_bin; 2238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(hi_bin<0)hi_bin=0; 2248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(hi_bin>n)hi_bin=n; 2258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 2268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(;l<hi_bin && l<n;l++) 2278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(brute_buffer[l]>workc[k][m][j]) 2288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels brute_buffer[l]=workc[k][m][j]; 2298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 2308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 2318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(;l<n;l++) 2328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(brute_buffer[l]>workc[k][m][EHMER_MAX-1]) 2338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels brute_buffer[l]=workc[k][m][EHMER_MAX-1]; 2348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 2358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 2368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 2378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 2388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(j=0;j<EHMER_MAX;j++){ 2398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels int bin=fromOC(j*.125+i*.5-2.)/binHz; 2408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(bin<0){ 2418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels ret[i][m][j+2]=-999.; 2428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels }else{ 2438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(bin>=n){ 2448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels ret[i][m][j+2]=-999.; 2458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels }else{ 2468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels ret[i][m][j+2]=brute_buffer[bin]; 2478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 2488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 2498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 2508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 2518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels /* add fenceposts */ 2528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(j=0;j<EHMER_OFFSET;j++) 2538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(ret[i][m][j+2]>-200.f)break; 2548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels ret[i][m][0]=j; 2558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 2568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(j=EHMER_MAX-1;j>EHMER_OFFSET+1;j--) 2578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(ret[i][m][j+2]>-200.f) 2588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels break; 2598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels ret[i][m][1]=j; 2608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 2618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 2628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 2638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 2648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels return(ret); 2658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels} 2668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 2678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsvoid _vp_psy_init(vorbis_look_psy *p,vorbis_info_psy *vi, 2688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels vorbis_info_psy_global *gi,int n,long rate){ 2698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels long i,j,lo=-99,hi=1; 2708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels long maxoc; 2718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels memset(p,0,sizeof(*p)); 2728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 2738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels p->eighth_octave_lines=gi->eighth_octave_lines; 2748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels p->shiftoc=rint(log(gi->eighth_octave_lines*8.f)/log(2.f))-1; 2758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 2768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels p->firstoc=toOC(.25f*rate*.5/n)*(1<<(p->shiftoc+1))-gi->eighth_octave_lines; 2778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels maxoc=toOC((n+.25f)*rate*.5/n)*(1<<(p->shiftoc+1))+.5f; 2788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels p->total_octave_lines=maxoc-p->firstoc+1; 2798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels p->ath=_ogg_malloc(n*sizeof(*p->ath)); 2808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 2818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels p->octave=_ogg_malloc(n*sizeof(*p->octave)); 2828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels p->bark=_ogg_malloc(n*sizeof(*p->bark)); 2838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels p->vi=vi; 2848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels p->n=n; 2858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels p->rate=rate; 2868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 2878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels /* AoTuV HF weighting */ 2888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels p->m_val = 1.; 2898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(rate < 26000) p->m_val = 0; 2908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels else if(rate < 38000) p->m_val = .94; /* 32kHz */ 2918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels else if(rate > 46000) p->m_val = 1.275; /* 48kHz */ 2928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 2938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels /* set up the lookups for a given blocksize and sample rate */ 2948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 2958e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(i=0,j=0;i<MAX_ATH-1;i++){ 2968e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels int endpos=rint(fromOC((i+1)*.125-2.)*2*n/rate); 2978e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float base=ATH[i]; 2988e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(j<endpos){ 2998e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float delta=(ATH[i+1]-base)/(endpos-j); 3008e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(;j<endpos && j<n;j++){ 3018e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels p->ath[j]=base+100.; 3028e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels base+=delta; 3038e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 3048e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 3058e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 3068e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 3078e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(;j<n;j++){ 3088e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels p->ath[j]=p->ath[j-1]; 3098e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 3108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 3118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(i=0;i<n;i++){ 3128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float bark=toBARK(rate/(2*n)*i); 3138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 3148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(;lo+vi->noisewindowlomin<i && 3158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels toBARK(rate/(2*n)*lo)<(bark-vi->noisewindowlo);lo++); 3168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 3178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(;hi<=n && (hi<i+vi->noisewindowhimin || 3188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels toBARK(rate/(2*n)*hi)<(bark+vi->noisewindowhi));hi++); 3198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 3208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels p->bark[i]=((lo-1)<<16)+(hi-1); 3218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 3228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 3238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 3248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(i=0;i<n;i++) 3258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels p->octave[i]=toOC((i+.25f)*.5*rate/n)*(1<<(p->shiftoc+1))+.5f; 3268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 3278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels p->tonecurves=setup_tone_curves(vi->toneatt,rate*.5/n,n, 3288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels vi->tone_centerboost,vi->tone_decay); 3298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 3308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels /* set up rolling noise median */ 3318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels p->noiseoffset=_ogg_malloc(P_NOISECURVES*sizeof(*p->noiseoffset)); 3328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(i=0;i<P_NOISECURVES;i++) 3338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels p->noiseoffset[i]=_ogg_malloc(n*sizeof(**p->noiseoffset)); 3348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 3358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(i=0;i<n;i++){ 3368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float halfoc=toOC((i+.5)*rate/(2.*n))*2.; 3378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels int inthalfoc; 3388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float del; 3398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 3408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(halfoc<0)halfoc=0; 3418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(halfoc>=P_BANDS-1)halfoc=P_BANDS-1; 3428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels inthalfoc=(int)halfoc; 3438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels del=halfoc-inthalfoc; 3448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 3458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(j=0;j<P_NOISECURVES;j++) 3468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels p->noiseoffset[j][i]= 3478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels p->vi->noiseoff[j][inthalfoc]*(1.-del) + 3488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels p->vi->noiseoff[j][inthalfoc+1]*del; 3498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 3508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 3518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#if 0 3528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels { 3538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels static int ls=0; 3548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels _analysis_output_always("noiseoff0",ls,p->noiseoffset[0],n,1,0,0); 3558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels _analysis_output_always("noiseoff1",ls,p->noiseoffset[1],n,1,0,0); 3568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels _analysis_output_always("noiseoff2",ls++,p->noiseoffset[2],n,1,0,0); 3578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 3588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#endif 3598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels} 3608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 3618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsvoid _vp_psy_clear(vorbis_look_psy *p){ 3628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels int i,j; 3638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(p){ 3648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(p->ath)_ogg_free(p->ath); 3658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(p->octave)_ogg_free(p->octave); 3668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(p->bark)_ogg_free(p->bark); 3678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(p->tonecurves){ 3688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(i=0;i<P_BANDS;i++){ 3698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(j=0;j<P_LEVELS;j++){ 3708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels _ogg_free(p->tonecurves[i][j]); 3718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 3728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels _ogg_free(p->tonecurves[i]); 3738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 3748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels _ogg_free(p->tonecurves); 3758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 3768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(p->noiseoffset){ 3778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(i=0;i<P_NOISECURVES;i++){ 3788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels _ogg_free(p->noiseoffset[i]); 3798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 3808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels _ogg_free(p->noiseoffset); 3818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 3828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels memset(p,0,sizeof(*p)); 3838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 3848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels} 3858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 3868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels/* octave/(8*eighth_octave_lines) x scale and dB y scale */ 3878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic void seed_curve(float *seed, 3888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels const float **curves, 3898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float amp, 3908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels int oc, int n, 3918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels int linesper,float dBoffset){ 3928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels int i,post1; 3938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels int seedptr; 3948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels const float *posts,*curve; 3958e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 3968e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels int choice=(int)((amp+dBoffset-P_LEVEL_0)*.1f); 3978e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels choice=max(choice,0); 3988e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels choice=min(choice,P_LEVELS-1); 3998e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels posts=curves[choice]; 4008e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels curve=posts+2; 4018e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels post1=(int)posts[1]; 4028e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels seedptr=oc+(posts[0]-EHMER_OFFSET)*linesper-(linesper>>1); 4038e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 4048e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(i=posts[0];i<post1;i++){ 4058e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(seedptr>0){ 4068e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float lin=amp+curve[i]; 4078e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(seed[seedptr]<lin)seed[seedptr]=lin; 4088e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 4098e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels seedptr+=linesper; 4108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(seedptr>=n)break; 4118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 4128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels} 4138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 4148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic void seed_loop(vorbis_look_psy *p, 4158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels const float ***curves, 4168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels const float *f, 4178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels const float *flr, 4188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float *seed, 4198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float specmax){ 4208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels vorbis_info_psy *vi=p->vi; 4218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels long n=p->n,i; 4228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float dBoffset=vi->max_curve_dB-specmax; 4238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 4248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels /* prime the working vector with peak values */ 4258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 4268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(i=0;i<n;i++){ 4278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float max=f[i]; 4288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels long oc=p->octave[i]; 4298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels while(i+1<n && p->octave[i+1]==oc){ 4308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels i++; 4318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(f[i]>max)max=f[i]; 4328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 4338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 4348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(max+6.f>flr[i]){ 4358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels oc=oc>>p->shiftoc; 4368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 4378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(oc>=P_BANDS)oc=P_BANDS-1; 4388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(oc<0)oc=0; 4398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 4408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels seed_curve(seed, 4418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels curves[oc], 4428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels max, 4438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels p->octave[i]-p->firstoc, 4448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels p->total_octave_lines, 4458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels p->eighth_octave_lines, 4468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels dBoffset); 4478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 4488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 4498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels} 4508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 4518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic void seed_chase(float *seeds, int linesper, long n){ 4528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels long *posstack=alloca(n*sizeof(*posstack)); 4538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float *ampstack=alloca(n*sizeof(*ampstack)); 4548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels long stack=0; 4558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels long pos=0; 4568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels long i; 4578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 4588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(i=0;i<n;i++){ 4598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(stack<2){ 4608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels posstack[stack]=i; 4618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels ampstack[stack++]=seeds[i]; 4628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels }else{ 4638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels while(1){ 4648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(seeds[i]<ampstack[stack-1]){ 4658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels posstack[stack]=i; 4668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels ampstack[stack++]=seeds[i]; 4678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels break; 4688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels }else{ 4698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(i<posstack[stack-1]+linesper){ 4708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(stack>1 && ampstack[stack-1]<=ampstack[stack-2] && 4718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels i<posstack[stack-2]+linesper){ 4728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels /* we completely overlap, making stack-1 irrelevant. pop it */ 4738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels stack--; 4748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels continue; 4758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 4768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 4778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels posstack[stack]=i; 4788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels ampstack[stack++]=seeds[i]; 4798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels break; 4808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 4818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 4828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 4838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 4848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 4858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 4868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels /* the stack now contains only the positions that are relevant. Scan 4878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 'em straight through */ 4888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 4898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(i=0;i<stack;i++){ 4908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels long endpos; 4918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(i<stack-1 && ampstack[i+1]>ampstack[i]){ 4928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels endpos=posstack[i+1]; 4938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels }else{ 4948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels endpos=posstack[i]+linesper+1; /* +1 is important, else bin 0 is 4958e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels discarded in short frames */ 4968e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 4978e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(endpos>n)endpos=n; 4988e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(;pos<endpos;pos++) 4998e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels seeds[pos]=ampstack[i]; 5008e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 5018e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 5028e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels /* there. Linear time. I now remember this was on a problem set I 5038e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels had in Grad Skool... I didn't solve it at the time ;-) */ 5048e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 5058e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels} 5068e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 5078e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels/* bleaugh, this is more complicated than it needs to be */ 5088e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include<stdio.h> 5098e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic void max_seeds(vorbis_look_psy *p, 5108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float *seed, 5118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float *flr){ 5128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels long n=p->total_octave_lines; 5138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels int linesper=p->eighth_octave_lines; 5148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels long linpos=0; 5158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels long pos; 5168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 5178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels seed_chase(seed,linesper,n); /* for masking */ 5188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 5198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels pos=p->octave[0]-p->firstoc-(linesper>>1); 5208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 5218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels while(linpos+1<p->n){ 5228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float minV=seed[pos]; 5238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels long end=((p->octave[linpos]+p->octave[linpos+1])>>1)-p->firstoc; 5248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(minV>p->vi->tone_abs_limit)minV=p->vi->tone_abs_limit; 5258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels while(pos+1<=end){ 5268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels pos++; 5278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if((seed[pos]>NEGINF && seed[pos]<minV) || minV==NEGINF) 5288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels minV=seed[pos]; 5298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 5308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 5318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels end=pos+p->firstoc; 5328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(;linpos<p->n && p->octave[linpos]<=end;linpos++) 5338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(flr[linpos]<minV)flr[linpos]=minV; 5348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 5358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 5368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels { 5378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float minV=seed[p->total_octave_lines-1]; 5388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(;linpos<p->n;linpos++) 5398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(flr[linpos]<minV)flr[linpos]=minV; 5408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 5418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 5428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels} 5438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 5448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic void bark_noise_hybridmp(int n,const long *b, 5458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels const float *f, 5468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float *noise, 5478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels const float offset, 5488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels const int fixed){ 5498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 5508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float *N=alloca(n*sizeof(*N)); 5518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float *X=alloca(n*sizeof(*N)); 5528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float *XX=alloca(n*sizeof(*N)); 5538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float *Y=alloca(n*sizeof(*N)); 5548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float *XY=alloca(n*sizeof(*N)); 5558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 5568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float tN, tX, tXX, tY, tXY; 5578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels int i; 5588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 5598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels int lo, hi; 5608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float R=0.f; 5618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float A=0.f; 5628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float B=0.f; 5638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float D=1.f; 5648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float w, x, y; 5658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 5668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels tN = tX = tXX = tY = tXY = 0.f; 5678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 5688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels y = f[0] + offset; 5698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if (y < 1.f) y = 1.f; 5708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 5718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels w = y * y * .5; 5728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 5738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels tN += w; 5748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels tX += w; 5758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels tY += w * y; 5768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 5778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels N[0] = tN; 5788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels X[0] = tX; 5798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels XX[0] = tXX; 5808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels Y[0] = tY; 5818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels XY[0] = tXY; 5828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 5838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for (i = 1, x = 1.f; i < n; i++, x += 1.f) { 5848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 5858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels y = f[i] + offset; 5868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if (y < 1.f) y = 1.f; 5878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 5888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels w = y * y; 5898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 5908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels tN += w; 5918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels tX += w * x; 5928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels tXX += w * x * x; 5938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels tY += w * y; 5948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels tXY += w * x * y; 5958e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 5968e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels N[i] = tN; 5978e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels X[i] = tX; 5988e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels XX[i] = tXX; 5998e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels Y[i] = tY; 6008e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels XY[i] = tXY; 6018e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 6028e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 6038e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for (i = 0, x = 0.f;; i++, x += 1.f) { 6048e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 6058e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels lo = b[i] >> 16; 6068e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if( lo>=0 ) break; 6078e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels hi = b[i] & 0xffff; 6088e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 6098e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels tN = N[hi] + N[-lo]; 6108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels tX = X[hi] - X[-lo]; 6118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels tXX = XX[hi] + XX[-lo]; 6128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels tY = Y[hi] + Y[-lo]; 6138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels tXY = XY[hi] - XY[-lo]; 6148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 6158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels A = tY * tXX - tX * tXY; 6168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels B = tN * tXY - tX * tY; 6178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels D = tN * tXX - tX * tX; 6188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels R = (A + x * B) / D; 6198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if (R < 0.f) 6208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels R = 0.f; 6218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 6228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels noise[i] = R - offset; 6238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 6248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 6258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for ( ;; i++, x += 1.f) { 6268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 6278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels lo = b[i] >> 16; 6288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels hi = b[i] & 0xffff; 6298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(hi>=n)break; 6308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 6318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels tN = N[hi] - N[lo]; 6328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels tX = X[hi] - X[lo]; 6338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels tXX = XX[hi] - XX[lo]; 6348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels tY = Y[hi] - Y[lo]; 6358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels tXY = XY[hi] - XY[lo]; 6368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 6378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels A = tY * tXX - tX * tXY; 6388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels B = tN * tXY - tX * tY; 6398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels D = tN * tXX - tX * tX; 6408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels R = (A + x * B) / D; 6418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if (R < 0.f) R = 0.f; 6428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 6438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels noise[i] = R - offset; 6448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 6458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for ( ; i < n; i++, x += 1.f) { 6468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 6478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels R = (A + x * B) / D; 6488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if (R < 0.f) R = 0.f; 6498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 6508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels noise[i] = R - offset; 6518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 6528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 6538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if (fixed <= 0) return; 6548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 6558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for (i = 0, x = 0.f;; i++, x += 1.f) { 6568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels hi = i + fixed / 2; 6578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels lo = hi - fixed; 6588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(lo>=0)break; 6598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 6608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels tN = N[hi] + N[-lo]; 6618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels tX = X[hi] - X[-lo]; 6628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels tXX = XX[hi] + XX[-lo]; 6638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels tY = Y[hi] + Y[-lo]; 6648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels tXY = XY[hi] - XY[-lo]; 6658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 6668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 6678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels A = tY * tXX - tX * tXY; 6688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels B = tN * tXY - tX * tY; 6698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels D = tN * tXX - tX * tX; 6708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels R = (A + x * B) / D; 6718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 6728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if (R - offset < noise[i]) noise[i] = R - offset; 6738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 6748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for ( ;; i++, x += 1.f) { 6758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 6768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels hi = i + fixed / 2; 6778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels lo = hi - fixed; 6788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(hi>=n)break; 6798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 6808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels tN = N[hi] - N[lo]; 6818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels tX = X[hi] - X[lo]; 6828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels tXX = XX[hi] - XX[lo]; 6838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels tY = Y[hi] - Y[lo]; 6848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels tXY = XY[hi] - XY[lo]; 6858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 6868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels A = tY * tXX - tX * tXY; 6878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels B = tN * tXY - tX * tY; 6888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels D = tN * tXX - tX * tX; 6898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels R = (A + x * B) / D; 6908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 6918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if (R - offset < noise[i]) noise[i] = R - offset; 6928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 6938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for ( ; i < n; i++, x += 1.f) { 6948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels R = (A + x * B) / D; 6958e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if (R - offset < noise[i]) noise[i] = R - offset; 6968e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 6978e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels} 6988e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 6998e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsvoid _vp_noisemask(vorbis_look_psy *p, 7008e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float *logmdct, 7018e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float *logmask){ 7028e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 7038e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels int i,n=p->n; 7048e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float *work=alloca(n*sizeof(*work)); 7058e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 7068e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels bark_noise_hybridmp(n,p->bark,logmdct,logmask, 7078e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 140.,-1); 7088e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 7098e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(i=0;i<n;i++)work[i]=logmdct[i]-logmask[i]; 7108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 7118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels bark_noise_hybridmp(n,p->bark,work,logmask,0., 7128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels p->vi->noisewindowfixed); 7138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 7148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(i=0;i<n;i++)work[i]=logmdct[i]-work[i]; 7158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 7168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#if 0 7178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels { 7188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels static int seq=0; 7198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 7208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float work2[n]; 7218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(i=0;i<n;i++){ 7228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels work2[i]=logmask[i]+work[i]; 7238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 7248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 7258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(seq&1) 7268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels _analysis_output("median2R",seq/2,work,n,1,0,0); 7278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels else 7288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels _analysis_output("median2L",seq/2,work,n,1,0,0); 7298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 7308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(seq&1) 7318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels _analysis_output("envelope2R",seq/2,work2,n,1,0,0); 7328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels else 7338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels _analysis_output("envelope2L",seq/2,work2,n,1,0,0); 7348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels seq++; 7358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 7368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#endif 7378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 7388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(i=0;i<n;i++){ 7398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels int dB=logmask[i]+.5; 7408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(dB>=NOISE_COMPAND_LEVELS)dB=NOISE_COMPAND_LEVELS-1; 7418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(dB<0)dB=0; 7428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels logmask[i]= work[i]+p->vi->noisecompand[dB]; 7438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 7448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 7458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels} 7468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 7478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsvoid _vp_tonemask(vorbis_look_psy *p, 7488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float *logfft, 7498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float *logmask, 7508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float global_specmax, 7518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float local_specmax){ 7528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 7538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels int i,n=p->n; 7548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 7558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float *seed=alloca(sizeof(*seed)*p->total_octave_lines); 7568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float att=local_specmax+p->vi->ath_adjatt; 7578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(i=0;i<p->total_octave_lines;i++)seed[i]=NEGINF; 7588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 7598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels /* set the ATH (floating below localmax, not global max by a 7608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels specified att) */ 7618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(att<p->vi->ath_maxatt)att=p->vi->ath_maxatt; 7628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 7638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(i=0;i<n;i++) 7648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels logmask[i]=p->ath[i]+att; 7658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 7668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels /* tone masking */ 7678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels seed_loop(p,(const float ***)p->tonecurves,logfft,logmask,seed,global_specmax); 7688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels max_seeds(p,seed,logmask); 7698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 7708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels} 7718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 7728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsvoid _vp_offset_and_mix(vorbis_look_psy *p, 7738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float *noise, 7748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float *tone, 7758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels int offset_select, 7768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float *logmask, 7778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float *mdct, 7788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float *logmdct){ 7798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels int i,n=p->n; 7808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float de, coeffi, cx;/* AoTuV */ 7818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float toneatt=p->vi->tone_masteratt[offset_select]; 7828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 7838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels cx = p->m_val; 7848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 7858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(i=0;i<n;i++){ 7868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float val= noise[i]+p->noiseoffset[offset_select][i]; 7878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(val>p->vi->noisemaxsupp)val=p->vi->noisemaxsupp; 7888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels logmask[i]=max(val,tone[i]+toneatt); 7898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 7908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 7918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels /* AoTuV */ 7928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels /** @ M1 ** 7938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels The following codes improve a noise problem. 7948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels A fundamental idea uses the value of masking and carries out 7958e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels the relative compensation of the MDCT. 7968e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels However, this code is not perfect and all noise problems cannot be solved. 7978e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels by Aoyumi @ 2004/04/18 7988e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels */ 7998e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 8008e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(offset_select == 1) { 8018e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels coeffi = -17.2; /* coeffi is a -17.2dB threshold */ 8028e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels val = val - logmdct[i]; /* val == mdct line value relative to floor in dB */ 8038e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 8048e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(val > coeffi){ 8058e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels /* mdct value is > -17.2 dB below floor */ 8068e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 8078e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels de = 1.0-((val-coeffi)*0.005*cx); 8088e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels /* pro-rated attenuation: 8098e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels -0.00 dB boost if mdct value is -17.2dB (relative to floor) 8108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels -0.77 dB boost if mdct value is 0dB (relative to floor) 8118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels -1.64 dB boost if mdct value is +17.2dB (relative to floor) 8128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels etc... */ 8138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 8148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(de < 0) de = 0.0001; 8158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels }else 8168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels /* mdct value is <= -17.2 dB below floor */ 8178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 8188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels de = 1.0-((val-coeffi)*0.0003*cx); 8198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels /* pro-rated attenuation: 8208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels +0.00 dB atten if mdct value is -17.2dB (relative to floor) 8218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels +0.45 dB atten if mdct value is -34.4dB (relative to floor) 8228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels etc... */ 8238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 8248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels mdct[i] *= de; 8258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 8268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 8278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 8288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels} 8298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 8308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsfloat _vp_ampmax_decay(float amp,vorbis_dsp_state *vd){ 8318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels vorbis_info *vi=vd->vi; 8328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels codec_setup_info *ci=vi->codec_setup; 8338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels vorbis_info_psy_global *gi=&ci->psy_g_param; 8348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 8358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels int n=ci->blocksizes[vd->W]/2; 8368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float secs=(float)n/vi->rate; 8378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 8388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels amp+=secs*gi->ampmax_att_per_sec; 8398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(amp<-9999)amp=-9999; 8408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels return(amp); 8418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels} 8428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 8438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic float FLOOR1_fromdB_LOOKUP[256]={ 8448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 1.0649863e-07F, 1.1341951e-07F, 1.2079015e-07F, 1.2863978e-07F, 8458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 1.3699951e-07F, 1.4590251e-07F, 1.5538408e-07F, 1.6548181e-07F, 8468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 1.7623575e-07F, 1.8768855e-07F, 1.9988561e-07F, 2.128753e-07F, 8478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 2.2670913e-07F, 2.4144197e-07F, 2.5713223e-07F, 2.7384213e-07F, 8488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 2.9163793e-07F, 3.1059021e-07F, 3.3077411e-07F, 3.5226968e-07F, 8498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 3.7516214e-07F, 3.9954229e-07F, 4.2550680e-07F, 4.5315863e-07F, 8508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 4.8260743e-07F, 5.1396998e-07F, 5.4737065e-07F, 5.8294187e-07F, 8518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 6.2082472e-07F, 6.6116941e-07F, 7.0413592e-07F, 7.4989464e-07F, 8528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 7.9862701e-07F, 8.5052630e-07F, 9.0579828e-07F, 9.6466216e-07F, 8538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 1.0273513e-06F, 1.0941144e-06F, 1.1652161e-06F, 1.2409384e-06F, 8548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 1.3215816e-06F, 1.4074654e-06F, 1.4989305e-06F, 1.5963394e-06F, 8558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 1.7000785e-06F, 1.8105592e-06F, 1.9282195e-06F, 2.0535261e-06F, 8568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 2.1869758e-06F, 2.3290978e-06F, 2.4804557e-06F, 2.6416497e-06F, 8578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 2.8133190e-06F, 2.9961443e-06F, 3.1908506e-06F, 3.3982101e-06F, 8588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 3.6190449e-06F, 3.8542308e-06F, 4.1047004e-06F, 4.3714470e-06F, 8598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 4.6555282e-06F, 4.9580707e-06F, 5.2802740e-06F, 5.6234160e-06F, 8608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 5.9888572e-06F, 6.3780469e-06F, 6.7925283e-06F, 7.2339451e-06F, 8618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 7.7040476e-06F, 8.2047000e-06F, 8.7378876e-06F, 9.3057248e-06F, 8628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 9.9104632e-06F, 1.0554501e-05F, 1.1240392e-05F, 1.1970856e-05F, 8638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 1.2748789e-05F, 1.3577278e-05F, 1.4459606e-05F, 1.5399272e-05F, 8648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 1.6400004e-05F, 1.7465768e-05F, 1.8600792e-05F, 1.9809576e-05F, 8658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 2.1096914e-05F, 2.2467911e-05F, 2.3928002e-05F, 2.5482978e-05F, 8668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 2.7139006e-05F, 2.8902651e-05F, 3.0780908e-05F, 3.2781225e-05F, 8678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 3.4911534e-05F, 3.7180282e-05F, 3.9596466e-05F, 4.2169667e-05F, 8688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 4.4910090e-05F, 4.7828601e-05F, 5.0936773e-05F, 5.4246931e-05F, 8698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 5.7772202e-05F, 6.1526565e-05F, 6.5524908e-05F, 6.9783085e-05F, 8708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 7.4317983e-05F, 7.9147585e-05F, 8.4291040e-05F, 8.9768747e-05F, 8718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 9.5602426e-05F, 0.00010181521F, 0.00010843174F, 0.00011547824F, 8728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 0.00012298267F, 0.00013097477F, 0.00013948625F, 0.00014855085F, 8738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 0.00015820453F, 0.00016848555F, 0.00017943469F, 0.00019109536F, 8748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 0.00020351382F, 0.00021673929F, 0.00023082423F, 0.00024582449F, 8758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 0.00026179955F, 0.00027881276F, 0.00029693158F, 0.00031622787F, 8768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 0.00033677814F, 0.00035866388F, 0.00038197188F, 0.00040679456F, 8778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 0.00043323036F, 0.00046138411F, 0.00049136745F, 0.00052329927F, 8788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 0.00055730621F, 0.00059352311F, 0.00063209358F, 0.00067317058F, 8798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 0.00071691700F, 0.00076350630F, 0.00081312324F, 0.00086596457F, 8808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 0.00092223983F, 0.00098217216F, 0.0010459992F, 0.0011139742F, 8818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 0.0011863665F, 0.0012634633F, 0.0013455702F, 0.0014330129F, 8828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 0.0015261382F, 0.0016253153F, 0.0017309374F, 0.0018434235F, 8838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 0.0019632195F, 0.0020908006F, 0.0022266726F, 0.0023713743F, 8848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 0.0025254795F, 0.0026895994F, 0.0028643847F, 0.0030505286F, 8858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 0.0032487691F, 0.0034598925F, 0.0036847358F, 0.0039241906F, 8868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 0.0041792066F, 0.0044507950F, 0.0047400328F, 0.0050480668F, 8878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 0.0053761186F, 0.0057254891F, 0.0060975636F, 0.0064938176F, 8888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 0.0069158225F, 0.0073652516F, 0.0078438871F, 0.0083536271F, 8898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 0.0088964928F, 0.009474637F, 0.010090352F, 0.010746080F, 8908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 0.011444421F, 0.012188144F, 0.012980198F, 0.013823725F, 8918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 0.014722068F, 0.015678791F, 0.016697687F, 0.017782797F, 8928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 0.018938423F, 0.020169149F, 0.021479854F, 0.022875735F, 8938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 0.024362330F, 0.025945531F, 0.027631618F, 0.029427276F, 8948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 0.031339626F, 0.033376252F, 0.035545228F, 0.037855157F, 8958e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 0.040315199F, 0.042935108F, 0.045725273F, 0.048696758F, 8968e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 0.051861348F, 0.055231591F, 0.058820850F, 0.062643361F, 8978e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 0.066714279F, 0.071049749F, 0.075666962F, 0.080584227F, 8988e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 0.085821044F, 0.091398179F, 0.097337747F, 0.10366330F, 8998e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 0.11039993F, 0.11757434F, 0.12521498F, 0.13335215F, 9008e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 0.14201813F, 0.15124727F, 0.16107617F, 0.17154380F, 9018e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 0.18269168F, 0.19456402F, 0.20720788F, 0.22067342F, 9028e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 0.23501402F, 0.25028656F, 0.26655159F, 0.28387361F, 9038e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 0.30232132F, 0.32196786F, 0.34289114F, 0.36517414F, 9048e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 0.38890521F, 0.41417847F, 0.44109412F, 0.46975890F, 9058e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 0.50028648F, 0.53279791F, 0.56742212F, 0.60429640F, 9068e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 0.64356699F, 0.68538959F, 0.72993007F, 0.77736504F, 9078e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 0.82788260F, 0.88168307F, 0.9389798F, 1.F, 9088e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}; 9098e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 9108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels/* this is for per-channel noise normalization */ 9118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic int apsort(const void *a, const void *b){ 9128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float f1=**(float**)a; 9138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float f2=**(float**)b; 9148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels return (f1<f2)-(f1>f2); 9158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels} 9168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 9178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic void flag_lossless(int limit, float prepoint, float postpoint, float *mdct, 9188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float *floor, int *flag, int i, int jn){ 9198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels int j; 9208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(j=0;j<jn;j++){ 9218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float point = j>=limit-i ? postpoint : prepoint; 9228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float r = fabs(mdct[j])/floor[j]; 9238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(r<point) 9248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels flag[j]=0; 9258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels else 9268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels flag[j]=1; 9278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 9288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels} 9298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 9308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels/* Overload/Side effect: On input, the *q vector holds either the 9318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels quantized energy (for elements with the flag set) or the absolute 9328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels values of the *r vector (for elements with flag unset). On output, 9338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels *q holds the quantized energy for all elements */ 9348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic float noise_normalize(vorbis_look_psy *p, int limit, float *r, float *q, float *f, int *flags, float acc, int i, int n, int *out){ 9358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 9368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels vorbis_info_psy *vi=p->vi; 9378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float **sort = alloca(n*sizeof(*sort)); 9388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels int j,count=0; 9398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels int start = (vi->normal_p ? vi->normal_start-i : n); 9408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(start>n)start=n; 9418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 9428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels /* force classic behavior where only energy in the current band is considered */ 9438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels acc=0.f; 9448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 9458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels /* still responsible for populating *out where noise norm not in 9468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels effect. There's no need to [re]populate *q in these areas */ 9478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(j=0;j<start;j++){ 9488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(!flags || !flags[j]){ /* lossless coupling already quantized. 9498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels Don't touch; requantizing based on 9508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels energy would be incorrect. */ 9518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float ve = q[j]/f[j]; 9528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(r[j]<0) 9538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels out[j] = -rint(sqrt(ve)); 9548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels else 9558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels out[j] = rint(sqrt(ve)); 9568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 9578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 9588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 9598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels /* sort magnitudes for noise norm portion of partition */ 9608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(;j<n;j++){ 9618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(!flags || !flags[j]){ /* can't noise norm elements that have 9628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels already been loslessly coupled; we can 9638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels only account for their energy error */ 9648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float ve = q[j]/f[j]; 9658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels /* Despite all the new, more capable coupling code, for now we 9668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels implement noise norm as it has been up to this point. Only 9678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels consider promotions to unit magnitude from 0. In addition 9688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels the only energy error counted is quantizations to zero. */ 9698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels /* also-- the original point code only applied noise norm at > pointlimit */ 9708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(ve<.25f && (!flags || j>=limit-i)){ 9718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels acc += ve; 9728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels sort[count++]=q+j; /* q is fabs(r) for unflagged element */ 9738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels }else{ 9748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels /* For now: no acc adjustment for nonzero quantization. populate *out and q as this value is final. */ 9758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(r[j]<0) 9768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels out[j] = -rint(sqrt(ve)); 9778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels else 9788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels out[j] = rint(sqrt(ve)); 9798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels q[j] = out[j]*out[j]*f[j]; 9808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 9818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels }/* else{ 9828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels again, no energy adjustment for error in nonzero quant-- for now 9838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels }*/ 9848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 9858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 9868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(count){ 9878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels /* noise norm to do */ 9888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels qsort(sort,count,sizeof(*sort),apsort); 9898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(j=0;j<count;j++){ 9908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels int k=sort[j]-q; 9918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(acc>=vi->normal_thresh){ 9928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels out[k]=unitnorm(r[k]); 9938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels acc-=1.f; 9948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels q[k]=f[k]; 9958e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels }else{ 9968e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels out[k]=0; 9978e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels q[k]=0.f; 9988e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 9998e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 10008e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 10018e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 10028e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels return acc; 10038e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels} 10048e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 10058e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels/* Noise normalization, quantization and coupling are not wholly 10068e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels seperable processes in depth>1 coupling. */ 10078e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsvoid _vp_couple_quantize_normalize(int blobno, 10088e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels vorbis_info_psy_global *g, 10098e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels vorbis_look_psy *p, 10108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels vorbis_info_mapping0 *vi, 10118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float **mdct, 10128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels int **iwork, 10138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels int *nonzero, 10148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels int sliding_lowpass, 10158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels int ch){ 10168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 10178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels int i; 10188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels int n = p->n; 10198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels int partition=(p->vi->normal_p ? p->vi->normal_partition : 16); 10208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels int limit = g->coupling_pointlimit[p->vi->blockflag][blobno]; 10218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float prepoint=stereo_threshholds[g->coupling_prepointamp[blobno]]; 10228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float postpoint=stereo_threshholds[g->coupling_postpointamp[blobno]]; 10238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float de=0.1*p->m_val; /* a blend of the AoTuV M2 and M3 code here and below */ 10248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 10258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels /* mdct is our raw mdct output, floor not removed. */ 10268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels /* inout passes in the ifloor, passes back quantized result */ 10278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 10288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels /* unquantized energy (negative indicates amplitude has negative sign) */ 10298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float **raw = alloca(ch*sizeof(*raw)); 10308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 10318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels /* dual pupose; quantized energy (if flag set), othersize fabs(raw) */ 10328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float **quant = alloca(ch*sizeof(*quant)); 10338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 10348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels /* floor energy */ 10358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float **floor = alloca(ch*sizeof(*floor)); 10368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 10378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels /* flags indicating raw/quantized status of elements in raw vector */ 10388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels int **flag = alloca(ch*sizeof(*flag)); 10398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 10408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels /* non-zero flag working vector */ 10418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels int *nz = alloca(ch*sizeof(*nz)); 10428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 10438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels /* energy surplus/defecit tracking */ 10448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float *acc = alloca((ch+vi->coupling_steps)*sizeof(*acc)); 10458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 10468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels /* The threshold of a stereo is changed with the size of n */ 10478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(n > 1000) 10488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels postpoint=stereo_threshholds_limited[g->coupling_postpointamp[blobno]]; 10498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 10508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels raw[0] = alloca(ch*partition*sizeof(**raw)); 10518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels quant[0] = alloca(ch*partition*sizeof(**quant)); 10528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels floor[0] = alloca(ch*partition*sizeof(**floor)); 10538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels flag[0] = alloca(ch*partition*sizeof(**flag)); 10548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 10558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(i=1;i<ch;i++){ 10568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels raw[i] = &raw[0][partition*i]; 10578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels quant[i] = &quant[0][partition*i]; 10588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels floor[i] = &floor[0][partition*i]; 10598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels flag[i] = &flag[0][partition*i]; 10608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 10618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(i=0;i<ch+vi->coupling_steps;i++) 10628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels acc[i]=0.f; 10638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 10648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(i=0;i<n;i+=partition){ 10658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels int k,j,jn = partition > n-i ? n-i : partition; 10668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels int step,track = 0; 10678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 10688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels memcpy(nz,nonzero,sizeof(*nz)*ch); 10698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 10708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels /* prefill */ 10718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels memset(flag[0],0,ch*partition*sizeof(**flag)); 10728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(k=0;k<ch;k++){ 10738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels int *iout = &iwork[k][i]; 10748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(nz[k]){ 10758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 10768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(j=0;j<jn;j++) 10778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels floor[k][j] = FLOOR1_fromdB_LOOKUP[iout[j]]; 10788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 10798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels flag_lossless(limit,prepoint,postpoint,&mdct[k][i],floor[k],flag[k],i,jn); 10808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 10818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(j=0;j<jn;j++){ 10828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels quant[k][j] = raw[k][j] = mdct[k][i+j]*mdct[k][i+j]; 10838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(mdct[k][i+j]<0.f) raw[k][j]*=-1.f; 10848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels floor[k][j]*=floor[k][j]; 10858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 10868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 10878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels acc[track]=noise_normalize(p,limit,raw[k],quant[k],floor[k],NULL,acc[track],i,jn,iout); 10888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 10898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels }else{ 10908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(j=0;j<jn;j++){ 10918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels floor[k][j] = 1e-10f; 10928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels raw[k][j] = 0.f; 10938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels quant[k][j] = 0.f; 10948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels flag[k][j] = 0; 10958e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels iout[j]=0; 10968e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 10978e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels acc[track]=0.f; 10988e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 10998e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels track++; 11008e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 11018e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 11028e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels /* coupling */ 11038e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(step=0;step<vi->coupling_steps;step++){ 11048e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels int Mi = vi->coupling_mag[step]; 11058e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels int Ai = vi->coupling_ang[step]; 11068e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels int *iM = &iwork[Mi][i]; 11078e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels int *iA = &iwork[Ai][i]; 11088e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float *reM = raw[Mi]; 11098e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float *reA = raw[Ai]; 11108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float *qeM = quant[Mi]; 11118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float *qeA = quant[Ai]; 11128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float *floorM = floor[Mi]; 11138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float *floorA = floor[Ai]; 11148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels int *fM = flag[Mi]; 11158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels int *fA = flag[Ai]; 11168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 11178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(nz[Mi] || nz[Ai]){ 11188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels nz[Mi] = nz[Ai] = 1; 11198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 11208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(j=0;j<jn;j++){ 11218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 11228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(j<sliding_lowpass-i){ 11238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(fM[j] || fA[j]){ 11248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels /* lossless coupling */ 11258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 11268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels reM[j] = fabs(reM[j])+fabs(reA[j]); 11278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels qeM[j] = qeM[j]+qeA[j]; 11288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels fM[j]=fA[j]=1; 11298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 11308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels /* couple iM/iA */ 11318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels { 11328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels int A = iM[j]; 11338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels int B = iA[j]; 11348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 11358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(abs(A)>abs(B)){ 11368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels iA[j]=(A>0?A-B:B-A); 11378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels }else{ 11388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels iA[j]=(B>0?A-B:B-A); 11398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels iM[j]=B; 11408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 11418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 11428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels /* collapse two equivalent tuples to one */ 11438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(iA[j]>=abs(iM[j])*2){ 11448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels iA[j]= -iA[j]; 11458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels iM[j]= -iM[j]; 11468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 11478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 11488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 11498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 11508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels }else{ 11518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels /* lossy (point) coupling */ 11528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(j<limit-i){ 11538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels /* dipole */ 11548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels reM[j] += reA[j]; 11558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels qeM[j] = fabs(reM[j]); 11568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels }else{ 11578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels /* AoTuV */ 11588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels /** @ M2 ** 11598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels The boost problem by the combination of noise normalization and point stereo is eased. 11608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels However, this is a temporary patch. 11618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels by Aoyumi @ 2004/04/18 11628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels */ 11638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels float derate = (1.0 - de*((float)(j-limit+i) / (float)(n-limit))); 11648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 11658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels /* elliptical */ 11668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(reM[j]+reA[j]<0){ 11678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels reM[j] = - (qeM[j] = (fabs(reM[j])+fabs(reA[j]))*derate*derate); 11688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels }else{ 11698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels reM[j] = (qeM[j] = (fabs(reM[j])+fabs(reA[j]))*derate*derate); 11708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 11718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 11728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels reA[j]=qeA[j]=0.f; 11738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels fA[j]=1; 11748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels iA[j]=0; 11758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 11768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 11778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels floorM[j]=floorA[j]=floorM[j]+floorA[j]; 11788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 11798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels /* normalize the resulting mag vector */ 11808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels acc[track]=noise_normalize(p,limit,raw[Mi],quant[Mi],floor[Mi],flag[Mi],acc[track],i,jn,iM); 11818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels track++; 11828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 11838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 11848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 11858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 11868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels for(i=0;i<vi->coupling_steps;i++){ 11878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels /* make sure coupling a zero and a nonzero channel results in two 11888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels nonzero channels. */ 11898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels if(nonzero[vi->coupling_mag[i]] || 11908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels nonzero[vi->coupling_ang[i]]){ 11918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels nonzero[vi->coupling_mag[i]]=1; 11928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels nonzero[vi->coupling_ang[i]]=1; 11938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 11948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 11958e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels} 1196