mirror of
https://github.com/cookiengineer/audacity
synced 2025-12-03 07:10:10 +01:00
Update twolame to 0.3.13.
This commit is contained in:
@@ -18,7 +18,7 @@
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* $Id: psycho_4.c,v 1.3 2008-02-01 19:44:35 richardash1981 Exp $
|
||||
* $Id$
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -72,19 +72,19 @@ static const FLOAT NMT = 5.5;
|
||||
/* The index into this array is a bark value
|
||||
This array gives the 'minval' values from ISO11172 Tables D.3.x */
|
||||
static const FLOAT minval[27] = {
|
||||
0.0, /* bark = 0 */
|
||||
20.0, /* 1 */
|
||||
20.0, /* 2 */
|
||||
20.0, /* 3 */
|
||||
20.0, /* 4 */
|
||||
20.0, /* 5 */
|
||||
17.0, /* 6 */
|
||||
15.0, /* 7 */
|
||||
10.0, /* 8 */
|
||||
7.0, /* 9 */
|
||||
4.4, /* 10 */
|
||||
4.5, 4.5, 4.5,4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, /* 11 - 25 */
|
||||
3.5 /* 26 */
|
||||
0.0, /* bark = 0 */
|
||||
20.0, /* 1 */
|
||||
20.0, /* 2 */
|
||||
20.0, /* 3 */
|
||||
20.0, /* 4 */
|
||||
20.0, /* 5 */
|
||||
17.0, /* 6 */
|
||||
15.0, /* 7 */
|
||||
10.0, /* 8 */
|
||||
7.0, /* 9 */
|
||||
4.4, /* 10 */
|
||||
4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, /* 11 - 25 */
|
||||
3.5 /* 26 */
|
||||
};
|
||||
|
||||
|
||||
@@ -94,484 +94,471 @@ static const FLOAT minval[27] = {
|
||||
Only create a table for cos, and then use trig to work out sin.
|
||||
sin(theta) = cos(PI/2 - theta)
|
||||
MFC March 2003 */
|
||||
static void psycho_4_trigtable_init(psycho_4_mem *p4mem) {
|
||||
static void psycho_4_trigtable_init(psycho_4_mem * p4mem)
|
||||
{
|
||||
|
||||
int i;
|
||||
for (i=0;i<TRIGTABLESIZE;i++) {
|
||||
p4mem->cos_table[i] = cos((FLOAT)i/TRIGTABLESCALE);
|
||||
}
|
||||
int i;
|
||||
for (i = 0; i < TRIGTABLESIZE; i++) {
|
||||
p4mem->cos_table[i] = cos((FLOAT) i / TRIGTABLESCALE);
|
||||
}
|
||||
}
|
||||
|
||||
static inline FLOAT psycho_4_cos(psycho_4_mem *p4mem, FLOAT phi) {
|
||||
int index;
|
||||
int sign=1;
|
||||
#ifdef NEWTAN
|
||||
static inline FLOAT psycho_4_cos(psycho_4_mem * p4mem, FLOAT phi)
|
||||
{
|
||||
int index;
|
||||
int sign = 1;
|
||||
|
||||
index = (int)(fabs(phi) * TRIGTABLESCALE);
|
||||
while (index>=TRIGTABLESIZE) {
|
||||
/* If we're larger than PI, then subtract PI until we aren't
|
||||
each time the sign will flip - Year 11 trig again. MFC March 2003 */
|
||||
index -= TRIGTABLESIZE;
|
||||
sign*=-1;
|
||||
}
|
||||
return(sign * p4mem->cos_table[index]);
|
||||
index = (int) (fabs(phi) * TRIGTABLESCALE);
|
||||
while (index >= TRIGTABLESIZE) {
|
||||
/* If we're larger than PI, then subtract PI until we aren't each time the sign will flip -
|
||||
Year 11 trig again. MFC March 2003 */
|
||||
index -= TRIGTABLESIZE;
|
||||
sign *= -1;
|
||||
}
|
||||
return (sign * p4mem->cos_table[index]);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* The spreading function. Values returned in units of energy
|
||||
Argument 'bark' is the difference in bark values between the
|
||||
centre of two partitions.
|
||||
This has been taken from LAME. MFC Feb 2003 */
|
||||
static FLOAT psycho_4_spreading_function(FLOAT bark) {
|
||||
static FLOAT psycho_4_spreading_function(FLOAT bark)
|
||||
{
|
||||
|
||||
FLOAT tempx,x,tempy,temp;
|
||||
tempx = bark;
|
||||
FLOAT tempx, x, tempy, temp;
|
||||
tempx = bark;
|
||||
#ifdef LAME
|
||||
/* MP3 standard actually spreads these values a little more */
|
||||
if (tempx>=0) tempx *= 3;
|
||||
else tempx *=1.5;
|
||||
/* MP3 standard actually spreads these values a little more */
|
||||
if (tempx >= 0)
|
||||
tempx *= 3;
|
||||
else
|
||||
tempx *= 1.5;
|
||||
#endif
|
||||
|
||||
if(tempx>=0.5 && tempx<=2.5)
|
||||
{
|
||||
temp = tempx - 0.5;
|
||||
x = 8.0 * (temp*temp - 2.0 * temp);
|
||||
}
|
||||
else x = 0.0;
|
||||
tempx += 0.474;
|
||||
tempy = 15.811389 + 7.5*tempx - 17.5*sqrt(1.0+tempx*tempx);
|
||||
if (tempx >= 0.5 && tempx <= 2.5) {
|
||||
temp = tempx - 0.5;
|
||||
x = 8.0 * (temp * temp - 2.0 * temp);
|
||||
} else
|
||||
x = 0.0;
|
||||
tempx += 0.474;
|
||||
tempy = 15.811389 + 7.5 * tempx - 17.5 * sqrt(1.0 + tempx * tempx);
|
||||
|
||||
if (tempy <= -60.0) return 0.0;
|
||||
if (tempy <= -60.0)
|
||||
return 0.0;
|
||||
|
||||
tempx = exp( (x + tempy)*LN_TO_LOG10 );
|
||||
tempx = exp((x + tempy) * LN_TO_LOG10);
|
||||
|
||||
#ifdef LAME
|
||||
/* I'm not sure where the magic value of 0.6609193 comes from.
|
||||
twolame will just keep using the rnorm to normalise the spreading function
|
||||
MFC Feb 2003 */
|
||||
/* Normalization. The spreading function should be normalized so that:
|
||||
+inf
|
||||
/
|
||||
| s3 [ bark ] d(bark) = 1
|
||||
/
|
||||
-inf
|
||||
*/
|
||||
tempx /= .6609193;
|
||||
/* I'm not sure where the magic value of 0.6609193 comes from. twolame will just keep using the
|
||||
rnorm to normalise the spreading function MFC Feb 2003 */
|
||||
/* Normalization. The spreading function should be normalized so that: +inf / | s3 [ bark ]
|
||||
d(bark) = 1 / -inf */
|
||||
tempx /= .6609193;
|
||||
#endif
|
||||
return tempx;
|
||||
return tempx;
|
||||
|
||||
}
|
||||
|
||||
/********************************
|
||||
* init psycho model 2
|
||||
********************************/
|
||||
static psycho_4_mem *psycho_4_init (twolame_options *glopts, int sfreq)
|
||||
static psycho_4_mem *psycho_4_init(twolame_options * glopts, int sfreq)
|
||||
{
|
||||
psycho_4_mem *mem;
|
||||
FLOAT *cbval, *rnorm;
|
||||
FLOAT *window;
|
||||
FLOAT bark[HBLKSIZE], *ath;
|
||||
int *numlines;
|
||||
int *partition;
|
||||
FCB *s;
|
||||
FLOAT *tmn;
|
||||
int i, j;
|
||||
psycho_4_mem *mem;
|
||||
FLOAT *cbval, *rnorm;
|
||||
FLOAT *window;
|
||||
FLOAT bark[HBLKSIZE], *ath;
|
||||
int *numlines;
|
||||
int *partition;
|
||||
FCB *s;
|
||||
FLOAT *tmn;
|
||||
int i, j;
|
||||
|
||||
{
|
||||
mem = (psycho_4_mem *)TWOLAME_MALLOC(sizeof(psycho_4_mem));
|
||||
{
|
||||
mem = (psycho_4_mem *) TWOLAME_MALLOC(sizeof(psycho_4_mem));
|
||||
|
||||
mem->tmn = (FLOAT *) TWOLAME_MALLOC (sizeof (DCB));
|
||||
mem->s = (FCB *) TWOLAME_MALLOC (sizeof (FCBCB));
|
||||
mem->lthr = (FHBLK *) TWOLAME_MALLOC (sizeof (F2HBLK));
|
||||
mem->r = (F2HBLK *) TWOLAME_MALLOC (sizeof (F22HBLK));
|
||||
mem->phi_sav = (F2HBLK *) TWOLAME_MALLOC (sizeof (F22HBLK));
|
||||
mem->tmn = (FLOAT *) TWOLAME_MALLOC(sizeof(DCB));
|
||||
mem->s = (FCB *) TWOLAME_MALLOC(sizeof(FCBCB));
|
||||
mem->lthr = (FHBLK *) TWOLAME_MALLOC(sizeof(F2HBLK));
|
||||
mem->r = (F2HBLK *) TWOLAME_MALLOC(sizeof(F22HBLK));
|
||||
mem->phi_sav = (F2HBLK *) TWOLAME_MALLOC(sizeof(F22HBLK));
|
||||
|
||||
mem->new=0;
|
||||
mem->old=1;
|
||||
mem->oldest=0;
|
||||
}
|
||||
mem->new = 0;
|
||||
mem->old = 1;
|
||||
mem->oldest = 0;
|
||||
}
|
||||
|
||||
{
|
||||
cbval = mem->cbval;
|
||||
rnorm = mem->rnorm;
|
||||
window = mem->window;
|
||||
//bark = mem->bark;
|
||||
ath = mem->ath;
|
||||
numlines = mem->numlines;
|
||||
partition = mem->numlines;
|
||||
s = mem->s;
|
||||
tmn = mem->tmn;
|
||||
}
|
||||
{
|
||||
cbval = mem->cbval;
|
||||
rnorm = mem->rnorm;
|
||||
window = mem->window;
|
||||
// bark = mem->bark;
|
||||
ath = mem->ath;
|
||||
numlines = mem->numlines;
|
||||
partition = mem->partition;
|
||||
s = mem->s;
|
||||
tmn = mem->tmn;
|
||||
}
|
||||
|
||||
|
||||
/* Set up the SIN/COS tables */
|
||||
psycho_4_trigtable_init(mem);
|
||||
/* Set up the SIN/COS tables */
|
||||
psycho_4_trigtable_init(mem);
|
||||
|
||||
/* calculate HANN window coefficients */
|
||||
for (i = 0; i < BLKSIZE; i++)
|
||||
window[i] = 0.5 * (1 - cos (2.0 * PI * (i - 0.5) / BLKSIZE));
|
||||
/* calculate HANN window coefficients */
|
||||
for (i = 0; i < BLKSIZE; i++)
|
||||
window[i] = 0.5 * (1 - cos(2.0 * PI * (i - 0.5) / BLKSIZE));
|
||||
|
||||
/* For each FFT line from 0(DC) to 512(Nyquist) calculate
|
||||
- bark : the bark value of this fft line
|
||||
- ath : the absolute threshold of hearing for this line [ATH]
|
||||
/* For each FFT line from 0(DC) to 512(Nyquist) calculate - bark : the bark value of this fft
|
||||
line - ath : the absolute threshold of hearing for this line [ATH]
|
||||
|
||||
Since it is a 1024 point FFT, each line in the fft corresponds
|
||||
to 1/1024 of the total frequency.
|
||||
Line 0 should correspond to DC - which doesn't really have a ATH afaik
|
||||
Line 1 should be 1/1024th of the Sampling Freq
|
||||
Line 512 should be the nyquist freq */
|
||||
for (i=0; i<HBLKSIZE; i++) {
|
||||
FLOAT freq = i * (FLOAT)sfreq/(FLOAT)BLKSIZE;
|
||||
bark[i] = ath_freq2bark(freq);
|
||||
/* The ath tables in the dist10 code seem to be a little out of kilter.
|
||||
they seem to start with index 0 corresponding to (sampling freq)/1024.
|
||||
When in doubt, i'm going to assume that the dist10 code is wrong. MFC Feb2003 */
|
||||
ath[i] = ath_energy(freq,glopts->athlevel);
|
||||
//fprintf(stderr,"%.2f ",ath[i]);
|
||||
}
|
||||
|
||||
|
||||
/* Work out the partitions
|
||||
Starting from line 0, all lines within 0.33 of the starting
|
||||
bark are added to the same partition. When a line is greater
|
||||
by 0.33 of a bark, start a new partition. */
|
||||
{
|
||||
int partition_count = 0; /* keep a count of the partitions */
|
||||
int cbase = 0; /* current base index for the bark range calculation */
|
||||
for (i=0;i<HBLKSIZE;i++) {
|
||||
if ((bark[i] - bark[cbase]) > 0.33) { /* 1/3 critical band? */
|
||||
/* this frequency line is too different from the starting line,
|
||||
(in terms of the bark distance)
|
||||
so close that previous partition, and make this line the first
|
||||
member of the next partition */
|
||||
cbase = i; /* Start the new partition from this frequency */
|
||||
partition_count++;
|
||||
}
|
||||
/* partition[i] tells us which partition the i'th frequency line is in */
|
||||
partition[i] = partition_count;
|
||||
/* keep a count of how many frequency lines are in each partition */
|
||||
numlines[partition_count]++;
|
||||
}
|
||||
}
|
||||
|
||||
/* For each partition within the frequency space,
|
||||
calculate the average bark value - cbval [central bark value] */
|
||||
for (i=0;i<HBLKSIZE;i++)
|
||||
cbval[partition[i]] += bark[i]; /* sum up all the bark values */
|
||||
for (i=0;i<CBANDS;i++) {
|
||||
if (numlines[i] != 0)
|
||||
cbval[i] /= numlines[i]; /* divide by the number of values */
|
||||
else {
|
||||
cbval[i]=0; /* this isn't a partition */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Calculate the spreading function. ISO 11172 Section D.2.3 */
|
||||
for (i=0;i<CBANDS;i++) {
|
||||
for (j=0;j<CBANDS;j++) {
|
||||
s[i][j] = psycho_4_spreading_function( 1.05 * (cbval[i] - cbval[j]) );
|
||||
rnorm[i] += s[i][j]; /* sum the spreading function values for each partition so that
|
||||
they can be normalised later on */
|
||||
}
|
||||
}
|
||||
|
||||
/* Calculate Tone Masking Noise values. ISO 11172 Tables D.3.x */
|
||||
for (j = 0; j < CBANDS; j++)
|
||||
tmn[j] = MAX(15.5+cbval[j], 24.5);
|
||||
Since it is a 1024 point FFT, each line in the fft corresponds to 1/1024 of the total
|
||||
frequency. Line 0 should correspond to DC - which doesn't really have a ATH afaik Line 1
|
||||
should be 1/1024th of the Sampling Freq Line 512 should be the nyquist freq */
|
||||
for (i = 0; i < HBLKSIZE; i++) {
|
||||
FLOAT freq = i * (FLOAT) sfreq / (FLOAT) BLKSIZE;
|
||||
bark[i] = ath_freq2bark(freq);
|
||||
/* The ath tables in the dist10 code seem to be a little out of kilter. they seem to start
|
||||
with index 0 corresponding to (sampling freq)/1024. When in doubt, i'm going to assume
|
||||
that the dist10 code is wrong. MFC Feb2003 */
|
||||
ath[i] = ath_energy(freq, glopts->athlevel);
|
||||
// fprintf(stderr,"%.2f ",ath[i]);
|
||||
}
|
||||
|
||||
|
||||
if (glopts->verbosity > 6) {
|
||||
/* Dump All the Values to STDOUT */
|
||||
int wlow, whigh=0;
|
||||
int ntot=0;
|
||||
fprintf(stdout,"psy model 4 init\n");
|
||||
fprintf(stdout,"index \tnlines \twlow \twhigh \tbval \tminval \ttmn\n");
|
||||
for (i=0;i<CBANDS;i++)
|
||||
if (numlines[i] != 0) {
|
||||
wlow = whigh+1;
|
||||
whigh = wlow + numlines[i] - 1;
|
||||
fprintf(stdout,"%i \t%i \t%i \t%i \t%5.2f \t%4.2f \t%4.2f\n",i+1, numlines[i],wlow, whigh, cbval[i],minval[(int)cbval[i]],tmn[i]);
|
||||
ntot += numlines[i];
|
||||
}
|
||||
fprintf(stdout,"total lines %i\n",ntot);
|
||||
exit(0);
|
||||
}
|
||||
/* Work out the partitions Starting from line 0, all lines within 0.33 of the starting bark are
|
||||
added to the same partition. When a line is greater by 0.33 of a bark, start a new
|
||||
partition. */
|
||||
{
|
||||
int partition_count = 0; /* keep a count of the partitions */
|
||||
int cbase = 0; /* current base index for the bark range calculation */
|
||||
for (i = 0; i < HBLKSIZE; i++) {
|
||||
if ((bark[i] - bark[cbase]) > 0.33) { /* 1/3 critical band? */
|
||||
/* this frequency line is too different from the starting line, (in terms of the
|
||||
bark distance) so close that previous partition, and make this line the first
|
||||
member of the next partition */
|
||||
cbase = i; /* Start the new partition from this frequency */
|
||||
partition_count++;
|
||||
}
|
||||
/* partition[i] tells us which partition the i'th frequency line is in */
|
||||
partition[i] = partition_count;
|
||||
/* keep a count of how many frequency lines are in each partition */
|
||||
numlines[partition_count]++;
|
||||
}
|
||||
}
|
||||
|
||||
return(mem);
|
||||
/* For each partition within the frequency space, calculate the average bark value - cbval
|
||||
[central bark value] */
|
||||
for (i = 0; i < HBLKSIZE; i++)
|
||||
cbval[partition[i]] += bark[i]; /* sum up all the bark values */
|
||||
for (i = 0; i < CBANDS; i++) {
|
||||
if (numlines[i] != 0)
|
||||
cbval[i] /= numlines[i]; /* divide by the number of values */
|
||||
else {
|
||||
cbval[i] = 0; /* this isn't a partition */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Calculate the spreading function. ISO 11172 Section D.2.3 */
|
||||
for (i = 0; i < CBANDS; i++) {
|
||||
for (j = 0; j < CBANDS; j++) {
|
||||
s[i][j] = psycho_4_spreading_function(1.05 * (cbval[i] - cbval[j]));
|
||||
rnorm[i] += s[i][j]; /* sum the spreading function values for each partition so that
|
||||
they can be normalised later on */
|
||||
}
|
||||
}
|
||||
|
||||
/* Calculate Tone Masking Noise values. ISO 11172 Tables D.3.x */
|
||||
for (j = 0; j < CBANDS; j++)
|
||||
tmn[j] = MAX(15.5 + cbval[j], 24.5);
|
||||
|
||||
|
||||
if (glopts->verbosity > 6) {
|
||||
/* Dump All the Values to STDERR */
|
||||
int wlow, whigh = 0;
|
||||
int ntot = 0;
|
||||
fprintf(stderr, "psy model 4 init\n");
|
||||
fprintf(stderr, "index \tnlines \twlow \twhigh \tbval \tminval \ttmn\n");
|
||||
for (i = 0; i < CBANDS; i++)
|
||||
if (numlines[i] != 0) {
|
||||
wlow = whigh + 1;
|
||||
whigh = wlow + numlines[i] - 1;
|
||||
fprintf(stderr, "%i \t%i \t%i \t%i \t%5.2f \t%4.2f \t%4.2f\n", i + 1, numlines[i],
|
||||
wlow, whigh, cbval[i], minval[(int) cbval[i]], tmn[i]);
|
||||
ntot += numlines[i];
|
||||
}
|
||||
fprintf(stderr, "total lines %i\n", ntot);
|
||||
}
|
||||
|
||||
return (mem);
|
||||
}
|
||||
|
||||
|
||||
void psycho_4 (twolame_options *glopts,
|
||||
short int buffer[2][1152],
|
||||
short int savebuf[2][1056],
|
||||
FLOAT smr[2][32])
|
||||
void psycho_4(twolame_options * glopts,
|
||||
short int buffer[2][1152], short int savebuf[2][1056], FLOAT smr[2][32])
|
||||
/* to match prototype : FLOAT args are always FLOAT */
|
||||
{
|
||||
psycho_4_mem *mem;
|
||||
unsigned int run, i, j, k, ch;
|
||||
FLOAT r_prime, phi_prime;
|
||||
FLOAT npart, epart;
|
||||
int new, old, oldest;
|
||||
FLOAT *grouped_c, *grouped_e;
|
||||
FLOAT *nb, *cb, *tb, *ecb, *bc;
|
||||
FLOAT *cbval, *rnorm;
|
||||
FLOAT *wsamp_r, *phi, *energy, *window;
|
||||
FLOAT *ath, *thr, *c;
|
||||
psycho_4_mem *mem;
|
||||
unsigned int run, i, j, k, ch;
|
||||
FLOAT r_prime, phi_prime;
|
||||
FLOAT npart, epart;
|
||||
int new, old, oldest;
|
||||
FLOAT *grouped_c, *grouped_e;
|
||||
FLOAT *nb, *cb, *tb, *ecb, *bc;
|
||||
FLOAT *cbval, *rnorm;
|
||||
FLOAT *wsamp_r, *phi, *energy, *window;
|
||||
FLOAT *ath, *thr, *c;
|
||||
|
||||
FLOAT *snrtmp[2];
|
||||
int *numlines;
|
||||
int *partition;
|
||||
FLOAT *tmn;
|
||||
FCB *s;
|
||||
FHBLK *lthr;
|
||||
F2HBLK *r, *phi_sav;
|
||||
|
||||
int nch = glopts->num_channels_out;
|
||||
int sfreq = glopts->samplerate_out;
|
||||
FLOAT *snrtmp[2];
|
||||
int *numlines;
|
||||
int *partition;
|
||||
FLOAT *tmn;
|
||||
FCB *s;
|
||||
FHBLK *lthr;
|
||||
F2HBLK *r, *phi_sav;
|
||||
|
||||
if (!glopts->p4mem) {
|
||||
glopts->p4mem = psycho_4_init (glopts,sfreq);
|
||||
}
|
||||
int nch = glopts->num_channels_out;
|
||||
int sfreq = glopts->samplerate_out;
|
||||
|
||||
mem = glopts->p4mem;
|
||||
{
|
||||
grouped_c = mem->grouped_c;
|
||||
grouped_e = mem->grouped_e;
|
||||
nb = mem->nb;
|
||||
cb = mem->cb;
|
||||
tb = mem->tb;
|
||||
ecb = mem->ecb;
|
||||
bc = mem->bc;
|
||||
rnorm = mem->rnorm;
|
||||
cbval = mem->cbval;
|
||||
wsamp_r = mem->wsamp_r;
|
||||
phi = mem->phi;
|
||||
energy = mem->energy;
|
||||
window = mem->window;
|
||||
ath = mem->ath;
|
||||
thr = mem->thr;
|
||||
c = mem->c;
|
||||
if (!glopts->p4mem) {
|
||||
glopts->p4mem = psycho_4_init(glopts, sfreq);
|
||||
}
|
||||
|
||||
snrtmp[0] = mem->snrtmp[0];
|
||||
snrtmp[1] = mem->snrtmp[1];
|
||||
mem = glopts->p4mem;
|
||||
{
|
||||
grouped_c = mem->grouped_c;
|
||||
grouped_e = mem->grouped_e;
|
||||
nb = mem->nb;
|
||||
cb = mem->cb;
|
||||
tb = mem->tb;
|
||||
ecb = mem->ecb;
|
||||
bc = mem->bc;
|
||||
rnorm = mem->rnorm;
|
||||
cbval = mem->cbval;
|
||||
wsamp_r = mem->wsamp_r;
|
||||
phi = mem->phi;
|
||||
energy = mem->energy;
|
||||
window = mem->window;
|
||||
ath = mem->ath;
|
||||
thr = mem->thr;
|
||||
c = mem->c;
|
||||
|
||||
numlines = mem->numlines;
|
||||
partition = mem->partition;
|
||||
tmn = mem->tmn;
|
||||
s = mem->s;
|
||||
lthr = mem->lthr;
|
||||
r = mem->r;
|
||||
phi_sav = mem->phi_sav;
|
||||
}
|
||||
snrtmp[0] = mem->snrtmp[0];
|
||||
snrtmp[1] = mem->snrtmp[1];
|
||||
|
||||
for (ch = 0; ch < nch; ch++) {
|
||||
for (run = 0; run < 2; run++) {
|
||||
/* Net offset is 480 samples (1056-576) for layer 2; this is because one must
|
||||
stagger input data by 256 samples to synchronize psychoacoustic model with
|
||||
filter bank outputs, then stagger so that center of 1024 FFT window lines
|
||||
up with center of 576 "new" audio samples.
|
||||
|
||||
flush = 384*3.0/2.0; = 576
|
||||
syncsize = 1056;
|
||||
sync_flush = syncsize - flush; 480
|
||||
BLKSIZE = 1024 */
|
||||
{
|
||||
short int *bufferp = buffer[ch];
|
||||
for (j = 0; j < 480; j++) {
|
||||
savebuf[ch][j] = savebuf[ch][j + 576];
|
||||
wsamp_r[j] = window[j] * ((FLOAT) savebuf[ch][j]);
|
||||
}
|
||||
for (; j < 1024; j++) {
|
||||
savebuf[ch][j] = *bufferp++;
|
||||
wsamp_r[j] = window[j] * ((FLOAT) savebuf[ch][j]);
|
||||
}
|
||||
for (; j < 1056; j++)
|
||||
savebuf[ch][j] = *bufferp++;
|
||||
}
|
||||
numlines = mem->numlines;
|
||||
partition = mem->partition;
|
||||
tmn = mem->tmn;
|
||||
s = mem->s;
|
||||
lthr = mem->lthr;
|
||||
r = mem->r;
|
||||
phi_sav = mem->phi_sav;
|
||||
}
|
||||
|
||||
/* Compute FFT */
|
||||
psycho_2_fft (wsamp_r, energy, phi);
|
||||
for (ch = 0; ch < nch; ch++) {
|
||||
for (run = 0; run < 2; run++) {
|
||||
/* Net offset is 480 samples (1056-576) for layer 2; this is because one must stagger
|
||||
input data by 256 samples to synchronize psychoacoustic model with filter bank
|
||||
outputs, then stagger so that center of 1024 FFT window lines up with center of 576
|
||||
"new" audio samples.
|
||||
|
||||
/* calculate the unpredictability measure, given energy[f] and phi[f]
|
||||
(the age pointers [new/old/oldest] are reset automatically on the second pass */
|
||||
{
|
||||
if (mem->new == 0) {
|
||||
mem->new = 1;
|
||||
mem->oldest = 1;
|
||||
} else {
|
||||
mem->new = 0;
|
||||
mem->oldest = 0;
|
||||
}
|
||||
if (mem->old == 0)
|
||||
mem->old = 1;
|
||||
else
|
||||
mem->old = 0;
|
||||
}
|
||||
old = mem->old;
|
||||
new = mem->new;
|
||||
oldest = mem->oldest;
|
||||
flush = 384*3.0/2.0; = 576 syncsize = 1056; sync_flush = syncsize - flush; 480
|
||||
BLKSIZE = 1024 */
|
||||
{
|
||||
short int *bufferp = buffer[ch];
|
||||
for (j = 0; j < 480; j++) {
|
||||
savebuf[ch][j] = savebuf[ch][j + 576];
|
||||
wsamp_r[j] = window[j] * ((FLOAT) savebuf[ch][j]);
|
||||
}
|
||||
for (; j < 1024; j++) {
|
||||
savebuf[ch][j] = *bufferp++;
|
||||
wsamp_r[j] = window[j] * ((FLOAT) savebuf[ch][j]);
|
||||
}
|
||||
for (; j < 1056; j++)
|
||||
savebuf[ch][j] = *bufferp++;
|
||||
}
|
||||
|
||||
/* Compute FFT */
|
||||
psycho_2_fft(wsamp_r, energy, phi);
|
||||
|
||||
/* calculate the unpredictability measure, given energy[f] and phi[f] (the age pointers
|
||||
[new/old/oldest] are reset automatically on the second pass */
|
||||
{
|
||||
if (mem->new == 0) {
|
||||
mem->new = 1;
|
||||
mem->oldest = 1;
|
||||
} else {
|
||||
mem->new = 0;
|
||||
mem->oldest = 0;
|
||||
}
|
||||
if (mem->old == 0)
|
||||
mem->old = 1;
|
||||
else
|
||||
mem->old = 0;
|
||||
}
|
||||
old = mem->old;
|
||||
new = mem->new;
|
||||
oldest = mem->oldest;
|
||||
|
||||
|
||||
for (j = 0; j < HBLKSIZE; j++) {
|
||||
for (j = 0; j < HBLKSIZE; j++) {
|
||||
#ifdef NEWATAN
|
||||
FLOAT temp1, temp2, temp3;
|
||||
r_prime = 2.0 * r[ch][old][j] - r[ch][oldest][j];
|
||||
phi_prime = 2.0 * phi_sav[ch][old][j] - phi_sav[ch][oldest][j];
|
||||
FLOAT temp1, temp2, temp3;
|
||||
r_prime = 2.0 * r[ch][old][j] - r[ch][oldest][j];
|
||||
phi_prime = 2.0 * phi_sav[ch][old][j] - phi_sav[ch][oldest][j];
|
||||
|
||||
r[ch][new][j] = sqrt ((FLOAT) energy[j]);
|
||||
phi_sav[ch][new][j] = phi[j];
|
||||
|
||||
{
|
||||
temp1 =
|
||||
r[ch][new][j] * psycho_4_cos(mem, phi[j]) -
|
||||
r_prime * psycho_4_cos(mem, phi_prime);
|
||||
/* Remember your grade 11 trig? sin(theta) = cos(PI/2 - theta) */
|
||||
temp2 =
|
||||
r[ch][new][j] * psycho_4_cos(mem, PI2 - phi[j]) -
|
||||
r_prime * psycho_4_cos(mem, PI2 - phi_prime);
|
||||
}
|
||||
r[ch][new][j] = sqrt((FLOAT) energy[j]);
|
||||
phi_sav[ch][new][j] = phi[j];
|
||||
|
||||
{
|
||||
temp1 =
|
||||
r[ch][new][j] * psycho_4_cos(mem, phi[j]) -
|
||||
r_prime * psycho_4_cos(mem, phi_prime);
|
||||
/* Remember your grade 11 trig? sin(theta) = cos(PI/2 - theta) */
|
||||
temp2 =
|
||||
r[ch][new][j] * psycho_4_cos(mem, PI2 - phi[j]) -
|
||||
r_prime * psycho_4_cos(mem, PI2 - phi_prime);
|
||||
}
|
||||
|
||||
|
||||
temp3 = r[ch][new][j] + fabs ((FLOAT) r_prime);
|
||||
if (temp3 != 0)
|
||||
c[j] = sqrt (temp1 * temp1 + temp2 * temp2) / temp3;
|
||||
else
|
||||
c[j] = 0;
|
||||
temp3 = r[ch][new][j] + fabs((FLOAT) r_prime);
|
||||
if (temp3 != 0)
|
||||
c[j] = sqrt(temp1 * temp1 + temp2 * temp2) / temp3;
|
||||
else
|
||||
c[j] = 0;
|
||||
#else
|
||||
FLOAT temp1, temp2, temp3;
|
||||
r_prime = 2.0 * r[ch][old][j] - r[ch][oldest][j];
|
||||
phi_prime = 2.0 * phi_sav[ch][old][j] - phi_sav[ch][oldest][j];
|
||||
FLOAT temp1, temp2, temp3;
|
||||
r_prime = 2.0 * r[ch][old][j] - r[ch][oldest][j];
|
||||
phi_prime = 2.0 * phi_sav[ch][old][j] - phi_sav[ch][oldest][j];
|
||||
|
||||
r[ch][new][j] = sqrt ((FLOAT) energy[j]);
|
||||
phi_sav[ch][new][j] = phi[j];
|
||||
r[ch][new][j] = sqrt((FLOAT) energy[j]);
|
||||
phi_sav[ch][new][j] = phi[j];
|
||||
|
||||
|
||||
temp1 =
|
||||
r[ch][new][j] * cos ((FLOAT) phi[j]) -
|
||||
r_prime * cos ((FLOAT) phi_prime);
|
||||
temp2 =
|
||||
r[ch][new][j] * sin ((FLOAT) phi[j]) -
|
||||
r_prime * sin ((FLOAT) phi_prime);
|
||||
temp1 = r[ch][new][j] * cos((FLOAT) phi[j]) - r_prime * cos((FLOAT) phi_prime);
|
||||
temp2 = r[ch][new][j] * sin((FLOAT) phi[j]) - r_prime * sin((FLOAT) phi_prime);
|
||||
|
||||
temp3 = r[ch][new][j] + fabs ((FLOAT) r_prime);
|
||||
if (temp3 != 0)
|
||||
c[j] = sqrt (temp1 * temp1 + temp2 * temp2) / temp3;
|
||||
else
|
||||
c[j] = 0;
|
||||
temp3 = r[ch][new][j] + fabs((FLOAT) r_prime);
|
||||
if (temp3 != 0)
|
||||
c[j] = sqrt(temp1 * temp1 + temp2 * temp2) / temp3;
|
||||
else
|
||||
c[j] = 0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* For each partition, sum all the energy in that partition - grouped_e
|
||||
and calculated the energy-weighted unpredictability measure - grouped_c
|
||||
ISO 11172 Section D.2.4.e */
|
||||
for (j = 1; j < CBANDS; j++) {
|
||||
grouped_e[j] = 0;
|
||||
grouped_c[j] = 0;
|
||||
}
|
||||
grouped_e[0] = energy[0];
|
||||
grouped_c[0] = energy[0] * c[0];
|
||||
for (j = 1; j < HBLKSIZE; j++) {
|
||||
grouped_e[partition[j]] += energy[j];
|
||||
grouped_c[partition[j]] += energy[j] * c[j];
|
||||
}
|
||||
/* For each partition, sum all the energy in that partition - grouped_e and calculated
|
||||
the energy-weighted unpredictability measure - grouped_c ISO 11172 Section D.2.4.e */
|
||||
for (j = 1; j < CBANDS; j++) {
|
||||
grouped_e[j] = 0;
|
||||
grouped_c[j] = 0;
|
||||
}
|
||||
grouped_e[0] = energy[0];
|
||||
grouped_c[0] = energy[0] * c[0];
|
||||
for (j = 1; j < HBLKSIZE; j++) {
|
||||
grouped_e[partition[j]] += energy[j];
|
||||
grouped_c[partition[j]] += energy[j] * c[j];
|
||||
}
|
||||
|
||||
/* convolve the grouped energy-weighted unpredictability measure
|
||||
and the grouped energy with the spreading function
|
||||
ISO 11172 D.2.4.f */
|
||||
for (j = 0; j < CBANDS; j++) {
|
||||
ecb[j] = 0;
|
||||
cb[j] = 0;
|
||||
for (k = 0; k < CBANDS; k++) {
|
||||
if (s[j][k] != 0.0) {
|
||||
ecb[j] += s[j][k] * grouped_e[k];
|
||||
cb[j] += s[j][k] * grouped_c[k];
|
||||
}
|
||||
}
|
||||
if (ecb[j] != 0)
|
||||
cb[j] = cb[j] / ecb[j];
|
||||
else
|
||||
cb[j] = 0;
|
||||
}
|
||||
/* convolve the grouped energy-weighted unpredictability measure and the grouped energy
|
||||
with the spreading function ISO 11172 D.2.4.f */
|
||||
for (j = 0; j < CBANDS; j++) {
|
||||
ecb[j] = 0;
|
||||
cb[j] = 0;
|
||||
for (k = 0; k < CBANDS; k++) {
|
||||
if (s[j][k] != 0.0) {
|
||||
ecb[j] += s[j][k] * grouped_e[k];
|
||||
cb[j] += s[j][k] * grouped_c[k];
|
||||
}
|
||||
}
|
||||
if (ecb[j] != 0)
|
||||
cb[j] = cb[j] / ecb[j];
|
||||
else
|
||||
cb[j] = 0;
|
||||
}
|
||||
|
||||
/* Convert cb to tb (the tonality index)
|
||||
ISO11172 SecD.2.4.g */
|
||||
for (i=0;i<CBANDS;i++) {
|
||||
if (cb[i] < 0.05)
|
||||
cb[i] = 0.05;
|
||||
else if (cb[i] > 0.5)
|
||||
cb[i] = 0.5;
|
||||
tb[i] = -0.301029996 - 0.434294482 * log((FLOAT) cb[i]);
|
||||
}
|
||||
|
||||
/* Convert cb to tb (the tonality index) ISO11172 SecD.2.4.g */
|
||||
for (i = 0; i < CBANDS; i++) {
|
||||
if (cb[i] < 0.05)
|
||||
cb[i] = 0.05;
|
||||
else if (cb[i] > 0.5)
|
||||
cb[i] = 0.5;
|
||||
tb[i] = -0.301029996 - 0.434294482 * log((FLOAT) cb[i]);
|
||||
}
|
||||
|
||||
/* Calculate the required SNR for each of the frequency partitions
|
||||
ISO 11172 Sect D.2.4.h */
|
||||
for (j = 0; j < CBANDS; j++) {
|
||||
FLOAT SNR, SNRtemp;
|
||||
SNRtemp = tmn[j] * tb[j] + NMT * (1.0 - tb[j]);
|
||||
SNR = MAX(SNRtemp, minval[(int)cbval[j]]);
|
||||
bc[j] = exp ((FLOAT) -SNR * LN_TO_LOG10);
|
||||
}
|
||||
|
||||
/* Calculate the permissible noise energy level in each of the frequency
|
||||
partitions.
|
||||
This section used to have pre-echo control but only for LayerI
|
||||
ISO 11172 Sec D.2.4.k - Spread the threshold energy over FFT lines */
|
||||
for (j = 0; j < CBANDS; j++) {
|
||||
if (rnorm[j] && numlines[j])
|
||||
nb[j] = ecb[j] * bc[j] / (rnorm[j] * numlines[j]);
|
||||
else
|
||||
nb[j] = 0;
|
||||
}
|
||||
/* Calculate the required SNR for each of the frequency partitions ISO 11172 Sect
|
||||
D.2.4.h */
|
||||
for (j = 0; j < CBANDS; j++) {
|
||||
FLOAT SNR, SNRtemp;
|
||||
SNRtemp = tmn[j] * tb[j] + NMT * (1.0 - tb[j]);
|
||||
SNR = MAX(SNRtemp, minval[(int) cbval[j]]);
|
||||
bc[j] = exp((FLOAT) - SNR * LN_TO_LOG10);
|
||||
}
|
||||
|
||||
/* ISO11172 Sec D.2.4.l - thr[] the final energy threshold of audibility */
|
||||
for (j = 0; j < HBLKSIZE; j++)
|
||||
thr[j] = MAX(nb[partition[j]], ath[j]);
|
||||
/* Calculate the permissible noise energy level in each of the frequency partitions.
|
||||
This section used to have pre-echo control but only for LayerI ISO 11172 Sec D.2.4.k
|
||||
- Spread the threshold energy over FFT lines */
|
||||
for (j = 0; j < CBANDS; j++) {
|
||||
if (rnorm[j] && numlines[j])
|
||||
nb[j] = ecb[j] * bc[j] / (rnorm[j] * numlines[j]);
|
||||
else
|
||||
nb[j] = 0;
|
||||
}
|
||||
|
||||
/* Translate the 512 threshold values to the 32 filter bands of the coder
|
||||
Using ISO 11172 Table D.5 and Section D.2.4.n */
|
||||
for (j = 0; j < 193; j += 16) {
|
||||
/* WIDTH = 0 */
|
||||
npart = 60802371420160.0;
|
||||
epart = 0.0;
|
||||
for (k = 0; k < 17; k++) {
|
||||
if (thr[j + k] < npart)
|
||||
npart = thr[j + k]; /* For WIDTH==0, find the minimum noise, and
|
||||
later multiply by the number of indexes i.e. 17 */
|
||||
epart += energy[j + k];
|
||||
}
|
||||
snrtmp[run][j / 16] = 4.342944819 * log((FLOAT)(epart/(npart*17.0)));
|
||||
}
|
||||
for (j = 208; j < (HBLKSIZE - 1); j += 16) {
|
||||
/* WIDTH = 1 */
|
||||
npart = 0.0;
|
||||
epart = 0.0;
|
||||
for (k = 0; k < 17; k++) {
|
||||
npart += thr[j + k]; /* For WIDTH==1, sum the noise */
|
||||
epart += energy[j + k];
|
||||
}
|
||||
snrtmp[run][j / 16] = 4.342944819 * log ((FLOAT) (epart/npart));
|
||||
}
|
||||
}
|
||||
/* ISO11172 Sec D.2.4.l - thr[] the final energy threshold of audibility */
|
||||
for (j = 0; j < HBLKSIZE; j++)
|
||||
thr[j] = MAX(nb[partition[j]], ath[j]);
|
||||
|
||||
/* Pick the maximum value of the two runs ISO 11172 Sect D.2.1 */
|
||||
for (i = 0; i < 32; i++)
|
||||
smr[ch][i] = MAX(snrtmp[0][i], snrtmp[1][i]);
|
||||
/* Translate the 512 threshold values to the 32 filter bands of the coder Using ISO
|
||||
11172 Table D.5 and Section D.2.4.n */
|
||||
for (j = 0; j < 193; j += 16) {
|
||||
/* WIDTH = 0 */
|
||||
npart = 60802371420160.0;
|
||||
epart = 0.0;
|
||||
for (k = 0; k < 17; k++) {
|
||||
if (thr[j + k] < npart)
|
||||
npart = thr[j + k]; /* For WIDTH==0, find the minimum noise, and later
|
||||
multiply by the number of indexes i.e. 17 */
|
||||
epart += energy[j + k];
|
||||
}
|
||||
snrtmp[run][j / 16] = 4.342944819 * log((FLOAT) (epart / (npart * 17.0)));
|
||||
}
|
||||
for (j = 208; j < (HBLKSIZE - 1); j += 16) {
|
||||
/* WIDTH = 1 */
|
||||
npart = 0.0;
|
||||
epart = 0.0;
|
||||
for (k = 0; k < 17; k++) {
|
||||
npart += thr[j + k]; /* For WIDTH==1, sum the noise */
|
||||
epart += energy[j + k];
|
||||
}
|
||||
snrtmp[run][j / 16] = 4.342944819 * log((FLOAT) (epart / npart));
|
||||
}
|
||||
}
|
||||
|
||||
/* Pick the maximum value of the two runs ISO 11172 Sect D.2.1 */
|
||||
for (i = 0; i < 32; i++)
|
||||
smr[ch][i] = MAX(snrtmp[0][i], snrtmp[1][i]);
|
||||
|
||||
} // now do other channel
|
||||
|
||||
} // now do other channel
|
||||
|
||||
}
|
||||
|
||||
|
||||
void psycho_4_deinit(psycho_4_mem **mem) {
|
||||
void psycho_4_deinit(psycho_4_mem ** mem)
|
||||
{
|
||||
|
||||
if (mem==NULL||*mem==NULL) return;
|
||||
if (mem == NULL || *mem == NULL)
|
||||
return;
|
||||
|
||||
TWOLAME_FREE( (*mem)->tmn );
|
||||
TWOLAME_FREE( (*mem)->s );
|
||||
TWOLAME_FREE( (*mem)->lthr );
|
||||
TWOLAME_FREE( (*mem)->r );
|
||||
TWOLAME_FREE( (*mem)->phi_sav );
|
||||
TWOLAME_FREE((*mem)->tmn);
|
||||
TWOLAME_FREE((*mem)->s);
|
||||
TWOLAME_FREE((*mem)->lthr);
|
||||
TWOLAME_FREE((*mem)->r);
|
||||
TWOLAME_FREE((*mem)->phi_sav);
|
||||
|
||||
TWOLAME_FREE( (*mem) );
|
||||
TWOLAME_FREE((*mem));
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user