mirror of
https://github.com/cookiengineer/audacity
synced 2025-11-26 07:10:09 +01:00
Move library tree where it belongs
This commit is contained in:
134
lib-src/twolame/libtwolame/psycho_0.c
Normal file
134
lib-src/twolame/libtwolame/psycho_0.c
Normal file
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* TwoLAME: an optimized MPEG Audio Layer Two encoder
|
||||
*
|
||||
* Copyright (C) 2001-2004 Michael Cheng
|
||||
* Copyright (C) 2004-2006 The TwoLAME Project
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* 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_0.c,v 1.3 2008-02-01 19:44:33 richardash1981 Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "twolame.h"
|
||||
#include "common.h"
|
||||
#include "ath.h"
|
||||
#include "mem.h"
|
||||
#include "psycho_0.h"
|
||||
|
||||
/* MFC Mar 03
|
||||
It's almost obscene how well this psycho model works for the amount of
|
||||
computational effort that's put in.
|
||||
|
||||
I got the idea from:
|
||||
Hyen-O Oh et al "Low power mpeg audio encoders using simplified psychoacoustic model
|
||||
and fast bit allocation"
|
||||
IEEE Trans on Consumer Electronics v47 n3 August 2001. p613
|
||||
|
||||
All this model does is look at the lowest ATH value within the subband, and then looks
|
||||
at the scalefactors. It combines the two in a real dodgy way to get the SMRs.
|
||||
|
||||
Although the output values aren't really close to any of the other psycho models,
|
||||
the spread of values and the relative sizes of the values for the different subbands
|
||||
is about right
|
||||
|
||||
Feel free to make any sort of generic change you want. Add or subtract numbers, take
|
||||
logs, whatever. Fiddle with the numbers until we get a good SMR output */
|
||||
|
||||
|
||||
static psycho_0_mem *psycho_0_init (twolame_options *glopts, int sfreq)
|
||||
{
|
||||
FLOAT freqperline = (FLOAT)sfreq/1024.0;
|
||||
psycho_0_mem *mem = (psycho_0_mem *)TWOLAME_MALLOC(sizeof(psycho_0_mem));
|
||||
int sb, i;
|
||||
|
||||
for (sb=0;sb<SBLIMIT;sb++) {
|
||||
mem->ath_min[sb] = 1000; /* set it huge */
|
||||
}
|
||||
|
||||
/* Find the minimum ATH in each subband */
|
||||
for (i=0;i<512;i++) {
|
||||
FLOAT thisfreq = i * freqperline;
|
||||
FLOAT ath_val = ath_db(thisfreq, 0);
|
||||
if (ath_val < mem->ath_min[i>>4])
|
||||
mem->ath_min[i>>4] = ath_val;
|
||||
}
|
||||
|
||||
return mem;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void psycho_0(twolame_options *glopts, FLOAT SMR[2][SBLIMIT], unsigned int scalar[2][3][SBLIMIT])
|
||||
{
|
||||
psycho_0_mem *mem;
|
||||
int nch = glopts->num_channels_out;
|
||||
int sfreq = glopts->samplerate_out;
|
||||
int ch, sb, gr;
|
||||
unsigned int minscaleindex[2][SBLIMIT]; /* Smaller scale indexes mean bigger scalefactors */
|
||||
|
||||
if (!glopts->p0mem) {
|
||||
glopts->p0mem = psycho_0_init(glopts, sfreq);
|
||||
}
|
||||
mem = glopts->p0mem;
|
||||
|
||||
|
||||
/* call functions for critical boundaries, freq. */
|
||||
if (!glopts->p0mem) { /* bands, bark values, and mapping */
|
||||
|
||||
} else {
|
||||
|
||||
mem = glopts->p0mem;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Find the minimum scalefactor index for each ch/sb */
|
||||
for (ch=0;ch<nch;ch++)
|
||||
for (sb=0;sb<SBLIMIT;sb++)
|
||||
minscaleindex[ch][sb] = scalar[ch][0][sb];
|
||||
|
||||
for (ch=0;ch<nch;ch++)
|
||||
for (gr=1;gr<3;gr++)
|
||||
for (sb=0;sb<SBLIMIT;sb++)
|
||||
if (minscaleindex[ch][sb] > scalar[ch][gr][sb])
|
||||
minscaleindex[ch][sb] = scalar[ch][gr][sb];
|
||||
|
||||
/* Oh yeah. Fudge the hell out of the SMR calculations
|
||||
by combining the scalefactor table index and the min ATH in that subband
|
||||
There are probably more elegant/correct ways of combining these values,
|
||||
but who cares? It works pretty well
|
||||
MFC Mar 03 */
|
||||
for (ch=0;ch<nch;ch++)
|
||||
for (sb=0;sb<SBLIMIT;sb++)
|
||||
SMR[ch][sb] = 2.0 * (30.0 - minscaleindex[ch][sb]) - mem->ath_min[sb];
|
||||
}
|
||||
|
||||
|
||||
void psycho_0_deinit(psycho_0_mem **mem)
|
||||
{
|
||||
|
||||
if (mem==NULL||*mem==NULL) return;
|
||||
|
||||
TWOLAME_FREE( *mem );
|
||||
}
|
||||
|
||||
|
||||
|
||||
// vim:ts=4:sw=4:nowrap:
|
||||
Reference in New Issue
Block a user