blob: f3c41f1aa017f9a43630c5203183249252340d6b (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
#include <stdio.h>
#include <math.h>
#include "common.h"
#include "ath.h"
#include "encoder.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 */
void psycho_0(double SMR[2][SBLIMIT], int nch, unsigned int scalar[2][3][SBLIMIT], FLOAT sfreq) {
int ch, sb, gr;
int minscaleindex[2][SBLIMIT]; /* Smaller scale indexes mean bigger scalefactors */
static FLOAT ath_min[SBLIMIT];
int i;
static int init=0;
if (!init) {
FLOAT freqperline = sfreq/1024.0;
for (sb=0;sb<SBLIMIT;sb++) {
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 < ath_min[i>>4])
ath_min[i>>4] = ath_val;
}
init++;
}
/* 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]) - ath_min[sb];
}
|