/******************************************************************** * * * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * * * * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2010 * * by the Xiph.Org Foundation https://xiph.org/ * * * ********************************************************************
/* simplistic, wasteful way of doing this (unique lookup for each mode/submapping); there should be a central repository for identical lookups. That will require minor work, so I'm putting it off as low priority.
Why a lookup for each backend in a given mode? Because the blocksize is set by the mode, and low backend lookups may require
parameters from other areas of the mode/mapping */
/* another 'we meant to do it this way' hack... up to beta 4, we packed 4 binary zeros here to signify one submapping in use. We now redefine that to mean four bitflags that indicate use of deeper features; bit0:submappings, bit1:coupling, bit2,3:reserved. This is backward compatable with all actual uses
of the beta code. */
/* we don't write the channel submappings if we only have one... */ if(info->submaps>1){ for(i=0;i<vi->channels;i++)
oggpack_write(opb,info->chmuxlist[i],4);
} for(i=0;i<info->submaps;i++){
oggpack_write(opb,0,8); /* time submap unused */
oggpack_write(opb,info->floorsubmap[i],8);
oggpack_write(opb,info->residuesubmap[i],8);
}
}
/* also responsible for range checking */ static vorbis_info_mapping *mapping0_unpack(vorbis_info *vi,oggpack_buffer *opb){ int i,b;
vorbis_info_mapping0 *info=_ogg_calloc(1,sizeof(*info));
codec_setup_info *ci=vi->codec_setup; if(vi->channels<=0)goto err_out;
b=oggpack_read(opb,1); if(b<0)goto err_out; if(b){
info->coupling_steps=oggpack_read(opb,8)+1; if(info->coupling_steps<=0)goto err_out; for(i=0;i<info->coupling_steps;i++){ /* vi->channels > 0 is enforced in the caller */ int testM=info->coupling_mag[i]=
oggpack_read(opb,ov_ilog(vi->channels-1)); int testA=info->coupling_ang[i]=
oggpack_read(opb,ov_ilog(vi->channels-1));
scale_dB=todB(&scale) + .345; /* + .345 is a hack; the original todB estimation used on IEEE 754 compliant machines had a bug that returned dB values about a third of a decibel too high. The bug was harmless because tunings implicitly took that into account. However, fixing the bug in the estimator requires changing all the tunings as well. For now, it's easier to sync things back up here, and recalibrate the tunings in the
next major model upgrade. */
/* transform the PCM data */ /* only MDCT right now.... */
mdct_forward(b->transform[vb->W][0],pcm,gmdct[i]);
/* FFT yields more accurate tonal estimation (not phase sensitive) */
drft_forward(&b->fft_look[vb->W],pcm);
logfft[0]=scale_dB+todB(pcm) + .345; /* + .345 is a hack; the original todB estimation used on IEEE 754 compliant machines had a bug that returned dB values about a third of a decibel too high. The bug was harmless because tunings implicitly took that into account. However, fixing the bug in the estimator requires changing all the tunings as well. For now, it's easier to sync things back up here, and recalibrate the tunings in the
next major model upgrade. */
local_ampmax[i]=logfft[0]; for(j=1;j<n-1;j+=2){ float temp=pcm[j]*pcm[j]+pcm[j+1]*pcm[j+1];
temp=logfft[(j+1)>>1]=scale_dB+.5f*todB(&temp) + .345; /* + .345 is a hack; the original todB estimation used on IEEE 754 compliant machines had a bug that returned dB values about a third of a decibel too high. The bug was harmless because tunings implicitly took that into account. However, fixing the bug in the estimator requires changing all the tunings as well. For now, it's easier to sync things back up here, and recalibrate the tunings in the
next major model upgrade. */ if(temp>local_ampmax[i])local_ampmax[i]=temp;
}
for(j=0;j<n/2;j++)
logmdct[j]=todB(mdct+j) + .345; /* + .345 is a hack; the original todB estimation used on IEEE 754 compliant machines had a bug that returned dB values about a third of a decibel too high. The bug was harmless because tunings implicitly took that into account. However, fixing the bug in the estimator requires changing all the tunings as well. For now, it's easier to sync things back up here, and recalibrate the tunings in the
next major model upgrade. */
/* first step; noise masking. Not only does 'noise masking' give us curves from which we can decide how much resolution to give noise parts of the spectrum, it also implicitly hands us a tonality estimate (the larger the value in the
'noise_depth' vector, the more tonal that area is) */
_vp_noisemask(psy_look,
logmdct,
noise); /* noise does not have by-frequency offset
bias applied yet */ #if0 if(vi->channels==2){ if(i==0)
_analysis_output("noiseL",seq,noise,n/2,1,0,0); else
_analysis_output("noiseR",seq,noise,n/2,1,0,0);
}else{
_analysis_output("noise",seq,noise,n/2,1,0,0);
} #endif
/* second step: 'all the other crap'; all the stuff that isn't computed/fit for bitrate management goes in the second psy
vector. This includes tone masking, peak limiting and ATH */
/* third step; we offset the noise vectors, overlay tone masking. We then do a floor1-specific line fit. If we're performing bitrate management, the line fit is performed
multiple times for up/down tweakage on demand. */
/* this algorithm is hardwired to floor 1 for now; abort out if we're *not* floor1. This won't happen unless someone has
broken the encode setup lib. Guard it anyway. */ if(ci->floor_type[info->floorsubmap[submap]]!=1)return(-1);
/* are we managing bitrate? If so, perform two more fits for
later rate tweaking (fits represent hi/lo) */ if(vorbis_bitrate_managed(vb) && floor_posts[i][PACKETBLOBS/2]){ /* higher rate by way of lower noise curve */
/* we also interpolate a range of intermediate curves for
intermediate rates */ for(k=1;k<PACKETBLOBS/2;k++)
floor_posts[i][k]=
floor1_interpolate_fit(vb,b->flr[info->floorsubmap[submap]],
floor_posts[i][0],
floor_posts[i][PACKETBLOBS/2],
k*65536/(PACKETBLOBS/2)); for(k=PACKETBLOBS/2+1;k<PACKETBLOBS-1;k++)
floor_posts[i][k]=
floor1_interpolate_fit(vb,b->flr[info->floorsubmap[submap]],
floor_posts[i][PACKETBLOBS/2],
floor_posts[i][PACKETBLOBS-1],
(k-PACKETBLOBS/2)*65536/(PACKETBLOBS/2));
}
}
}
vbi->ampmax=global_ampmax;
/* the next phases are performed once for vbr-only and PACKETBLOB times for bitrate managed modes.
1) encode actual mode being used 2) encode the floor for each channel, compute coded mask curve/res 3) normalize and couple. 4) encode residue 5) save packet bytes to the packetblob vector
*/
/* iterate over the many masking curve fits we've created */
{ int **couple_bundle=alloca(sizeof(*couple_bundle)*vi->channels); int *zerobundle=alloca(sizeof(*zerobundle)*vi->channels);
/* start out our new packet blob with packet type and mode */ /* Encode the packet type */
oggpack_write(opb,0,1); /* Encode the modenumber */ /* Encode frame mode, pre,post windowsize, then dispatch */
oggpack_write(opb,modenumber,b->modebits); if(vb->W){
oggpack_write(opb,vb->lW,1);
oggpack_write(opb,vb->nW,1);
}
/* encode floor, compute masking curve, sep out residue */ for(i=0;i<vi->channels;i++){ int submap=info->chmuxlist[i]; int *ilogmask=iwork[i];
/* our iteration is now based on masking curve, not prequant and
coupling. Only one prequant/coupling step */
/* quantize/couple */ /* incomplete implementation that assumes the tree is all depth
one, or no tree at all */
_vp_couple_quantize_normalize(k,
&ci->psy_g_param,
psy_look,
info,
gmdct,
iwork,
nonzero,
ci->psy_g_param.sliding_lowpass[vb->W][k],
vi->channels);
float **pcmbundle=alloca(sizeof(*pcmbundle)*vi->channels); int *zerobundle=alloca(sizeof(*zerobundle)*vi->channels);
int *nonzero =alloca(sizeof(*nonzero)*vi->channels); void **floormemo=alloca(sizeof(*floormemo)*vi->channels);
/* recover the spectral envelope; store it in the PCM vector for now */ for(i=0;i<vi->channels;i++){ int submap=info->chmuxlist[i];
floormemo[i]=_floor_P[ci->floor_type[info->floorsubmap[submap]]]->
inverse1(vb,b->flr[info->floorsubmap[submap]]); if(floormemo[i])
nonzero[i]=1; else
nonzero[i]=0;
memset(vb->pcm[i],0,sizeof(*vb->pcm[i])*n/2);
}
/* channel coupling can 'dirty' the nonzero listing */ for(i=0;i<info->coupling_steps;i++){ if(nonzero[info->coupling_mag[i]] ||
nonzero[info->coupling_ang[i]]){
nonzero[info->coupling_mag[i]]=1;
nonzero[info->coupling_ang[i]]=1;
}
}
/* recover the residue into our working vectors */ for(i=0;i<info->submaps;i++){ int ch_in_bundle=0; for(j=0;j<vi->channels;j++){ if(info->chmuxlist[j]==i){ if(nonzero[j])
zerobundle[ch_in_bundle]=1; else
zerobundle[ch_in_bundle]=0;
pcmbundle[ch_in_bundle++]=vb->pcm[j];
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.