00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <math.h>
00004 #include <string.h>
00005 #include "common.h"
00006 #include "encoder.h"
00007 #include "mem.h"
00008 #include "fft.h"
00009 #include "psycho_2.h"
00010
00011
00012
00013
00014
00015
00016 static int new = 0, old = 1, oldest = 0;
00017 static int init = 0, flush, sync_flush, syncsize, sfreq_idx;
00018
00019
00020
00021 static double nmt = 5.5;
00022
00023 static FLOAT crit_band[27] = { 0, 100, 200, 300, 400, 510, 630, 770,
00024 920, 1080, 1270, 1480, 1720, 2000, 2320, 2700,
00025 3150, 3700, 4400, 5300, 6400, 7700, 9500, 12000,
00026 15500, 25000, 30000
00027 };
00028
00029 static FLOAT bmax[27] = { 20.0, 20.0, 20.0, 20.0, 20.0, 17.0, 15.0,
00030 10.0, 7.0, 4.4, 4.5, 4.5, 4.5, 4.5,
00031 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5,
00032 4.5, 4.5, 4.5, 3.5, 3.5, 3.5
00033 };
00034
00035 static FLOAT *grouped_c, *grouped_e, *nb, *cb, *ecb, *bc;
00036 static FLOAT *wsamp_r, *phi, *energy;
00037 static FLOAT *c, *fthr;
00038 static F32 *snrtmp;
00039
00040 static int *numlines;
00041 static int *partition;
00042 static FLOAT *cbval, *rnorm;
00043 static FLOAT *window;
00044 static FLOAT *absthr;
00045 static double *tmn;
00046 static FCB *s;
00047 static FHBLK *lthr;
00048 static F2HBLK *r, *phi_sav;
00049
00050 void psycho_2_init (double sfreq);
00051
00052 void psycho_2 (short int *buffer, short int savebuf[1056], int chn,
00053 double *smr, double sfreq, options *glopts)
00054
00055 {
00056 unsigned int i, j, k;
00057 FLOAT r_prime, phi_prime;
00058 FLOAT minthres, sum_energy;
00059 double tb, temp1, temp2, temp3;
00060
00061 if (init == 0) {
00062 psycho_2_init (sfreq);
00063 init++;
00064 }
00065
00066 for (i = 0; i < 2; i++) {
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079 for (j = 0; j < 480; j++) {
00080 savebuf[j] = savebuf[j + flush];
00081 wsamp_r[j] = window[j] * ((FLOAT) savebuf[j]);
00082 }
00083 for (; j < 1024; j++) {
00084 savebuf[j] = *buffer++;
00085 wsamp_r[j] = window[j] * ((FLOAT) savebuf[j]);
00086 }
00087 for (; j < 1056; j++)
00088 savebuf[j] = *buffer++;
00089
00091 psycho_2_fft (wsamp_r, energy, phi);
00092
00093
00094
00095
00096
00097
00098 {
00099 if (new == 0) {
00100 new = 1;
00101 oldest = 1;
00102 } else {
00103 new = 0;
00104 oldest = 0;
00105 }
00106 if (old == 0)
00107 old = 1;
00108 else
00109 old = 0;
00110 }
00111 for (j = 0; j < HBLKSIZE; j++) {
00112 r_prime = 2.0 * r[chn][old][j] - r[chn][oldest][j];
00113 phi_prime = 2.0 * phi_sav[chn][old][j] - phi_sav[chn][oldest][j];
00114 r[chn][new][j] = sqrt ((double) energy[j]);
00115 phi_sav[chn][new][j] = phi[j];
00116 #ifdef SINCOS
00117 {
00118
00119
00120 double sphi, cphi, sprime, cprime;
00121 __sincos ((double) phi[j], &sphi, &cphi);
00122 __sincos ((double) phi_prime, &sprime, &cprime);
00123 temp1 = r[chn][new][j] * cphi - r_prime * cprime;
00124 temp2 = r[chn][new][j] * sphi - r_prime * sprime;
00125 }
00126 #else
00127 temp1 =
00128 r[chn][new][j] * cos ((double) phi[j]) -
00129 r_prime * cos ((double) phi_prime);
00130 temp2 =
00131 r[chn][new][j] * sin ((double) phi[j]) -
00132 r_prime * sin ((double) phi_prime);
00133 #endif
00134
00135 temp3 = r[chn][new][j] + fabs ((double) r_prime);
00136 if (temp3 != 0)
00137 c[j] = sqrt (temp1 * temp1 + temp2 * temp2) / temp3;
00138 else
00139 c[j] = 0;
00140 }
00141
00142
00143
00144
00145
00146 for (j = 1; j < CBANDS; j++) {
00147 grouped_e[j] = 0;
00148 grouped_c[j] = 0;
00149 }
00150 grouped_e[0] = energy[0];
00151 grouped_c[0] = energy[0] * c[0];
00152 for (j = 1; j < HBLKSIZE; j++) {
00153 grouped_e[partition[j]] += energy[j];
00154 grouped_c[partition[j]] += energy[j] * c[j];
00155 }
00156
00157
00158
00159
00160
00161 for (j = 0; j < CBANDS; j++) {
00162 ecb[j] = 0;
00163 cb[j] = 0;
00164 for (k = 0; k < CBANDS; k++) {
00165 if (s[j][k] != 0.0) {
00166 ecb[j] += s[j][k] * grouped_e[k];
00167 cb[j] += s[j][k] * grouped_c[k];
00168 }
00169 }
00170 if (ecb[j] != 0)
00171 cb[j] = cb[j] / ecb[j];
00172 else
00173 cb[j] = 0;
00174 }
00175
00176
00177
00178
00179
00180 for (j = 0; j < CBANDS; j++) {
00181 if (cb[j] < .05)
00182 cb[j] = 0.05;
00183 else if (cb[j] > .5)
00184 cb[j] = 0.5;
00185 tb = -0.434294482 * log ((double) cb[j]) - 0.301029996;
00186 cb[j] = tb;
00187 bc[j] = tmn[j] * tb + nmt * (1.0 - tb);
00188 k = cbval[j] + 0.5;
00189 bc[j] = (bc[j] > bmax[k]) ? bc[j] : bmax[k];
00190 bc[j] = exp ((double) -bc[j] * LN_TO_LOG10);
00191 }
00192
00193
00194
00195
00196
00197
00198 for (j = 0; j < CBANDS; j++)
00199 if (rnorm[j] && numlines[j])
00200 nb[j] = ecb[j] * bc[j] / (rnorm[j] * numlines[j]);
00201 else
00202 nb[j] = 0;
00203 for (j = 0; j < HBLKSIZE; j++) {
00204
00205 temp1 = nb[partition[j]];
00206 temp1 = (temp1 > absthr[j]) ? temp1 : absthr[j];
00207 #ifdef LAYERI
00208
00209
00210 if (lay == 1) {
00211 fthr[j] = (temp1 < lthr[chn][j]) ? temp1 : lthr[chn][j];
00212 temp2 = temp1 * 0.00316;
00213 fthr[j] = (temp2 > fthr[j]) ? temp2 : fthr[j];
00214 } else
00215 fthr[j] = temp1;
00216 lthr[chn][j] = LXMIN * temp1;
00217 #else
00218 fthr[j] = temp1;
00219 lthr[chn][j] = LXMIN * temp1;
00220 #endif
00221 }
00222
00223
00224
00225
00226 for (j = 0; j < 193; j += 16) {
00227 minthres = 60802371420160.0;
00228 sum_energy = 0.0;
00229 for (k = 0; k < 17; k++) {
00230 if (minthres > fthr[j + k])
00231 minthres = fthr[j + k];
00232 sum_energy += energy[j + k];
00233 }
00234 snrtmp[i][j / 16] = sum_energy / (minthres * 17.0);
00235 snrtmp[i][j / 16] = 4.342944819 * log ((double) snrtmp[i][j / 16]);
00236 }
00237 for (j = 208; j < (HBLKSIZE - 1); j += 16) {
00238 minthres = 0.0;
00239 sum_energy = 0.0;
00240 for (k = 0; k < 17; k++) {
00241 minthres += fthr[j + k];
00242 sum_energy += energy[j + k];
00243 }
00244 snrtmp[i][j / 16] = sum_energy / minthres;
00245 snrtmp[i][j / 16] = 4.342944819 * log ((double) snrtmp[i][j / 16]);
00246 }
00247
00248
00249
00250 }
00251 for (i = 0; i < 32; i++) {
00252 smr[i] = (snrtmp[0][i] > snrtmp[1][i]) ? snrtmp[0][i] : snrtmp[1][i];
00253 }
00254 }
00255
00256
00257
00258
00259 void psycho_2_init (double sfreq)
00260 {
00261 int i, j;
00262 FLOAT freq_mult;
00263 double temp1, temp2, temp3;
00264 FLOAT bval_lo;
00265
00266 grouped_c = (FLOAT *) mem_alloc (sizeof (FCB), "grouped_c");
00267 grouped_e = (FLOAT *) mem_alloc (sizeof (FCB), "grouped_e");
00268 nb = (FLOAT *) mem_alloc (sizeof (FCB), "nb");
00269 cb = (FLOAT *) mem_alloc (sizeof (FCB), "cb");
00270 ecb = (FLOAT *) mem_alloc (sizeof (FCB), "ecb");
00271 bc = (FLOAT *) mem_alloc (sizeof (FCB), "bc");
00272 wsamp_r = (FLOAT *) mem_alloc (sizeof (FBLK), "wsamp_r");
00273 phi = (FLOAT *) mem_alloc (sizeof (FBLK), "phi");
00274 energy = (FLOAT *) mem_alloc (sizeof (FBLK), "energy");
00275 c = (FLOAT *) mem_alloc (sizeof (FHBLK), "c");
00276 fthr = (FLOAT *) mem_alloc (sizeof (FHBLK), "fthr");
00277 snrtmp = (F32 *) mem_alloc (sizeof (F2_32), "snrtmp");
00278
00279 numlines = (int *) mem_alloc (sizeof (ICB), "numlines");
00280 partition = (int *) mem_alloc (sizeof (IHBLK), "partition");
00281 cbval = (FLOAT *) mem_alloc (sizeof (FCB), "cbval");
00282 rnorm = (FLOAT *) mem_alloc (sizeof (FCB), "rnorm");
00283 window = (FLOAT *) mem_alloc (sizeof (FBLK), "window");
00284 absthr = (FLOAT *) mem_alloc (sizeof (FHBLK), "absthr");
00285 tmn = (double *) mem_alloc (sizeof (DCB), "tmn");
00286 s = (FCB *) mem_alloc (sizeof (FCBCB), "s");
00287 lthr = (FHBLK *) mem_alloc (sizeof (F2HBLK), "lthr");
00288 r = (F2HBLK *) mem_alloc (sizeof (F22HBLK), "r");
00289 phi_sav = (F2HBLK *) mem_alloc (sizeof (F22HBLK), "phi_sav");
00290
00291 i = sfreq + 0.5;
00292 switch (i) {
00293 case 32000:
00294 case 16000:
00295 sfreq_idx = 0;
00296 break;
00297 case 44100:
00298 case 22050:
00299 sfreq_idx = 1;
00300 break;
00301 case 48000:
00302 case 24000:
00303 sfreq_idx = 2;
00304 break;
00305 default:
00306 fprintf (stderr, "error, invalid sampling frequency: %d Hz\n", i);
00307 exit (-1);
00308 }
00309 fprintf (stderr, "absthr[][] sampling frequency index: %d\n", sfreq_idx);
00310 psycho_2_read_absthr (absthr, sfreq_idx);
00311
00312 flush = 384 * 3.0 / 2.0;
00313 syncsize = 1056;
00314 sync_flush = syncsize - flush;
00315
00316
00317
00318 for (i = 0; i < BLKSIZE; i++)
00319 window[i] = 0.5 * (1 - cos (2.0 * PI * (i - 0.5) / BLKSIZE));
00320
00321 for (i = 0; i < HBLKSIZE; i++) {
00322 r[0][0][i] = r[1][0][i] = r[0][1][i] = r[1][1][i] = 0;
00323 phi_sav[0][0][i] = phi_sav[1][0][i] = 0;
00324 phi_sav[0][1][i] = phi_sav[1][1][i] = 0;
00325 lthr[0][i] = 60802371420160.0;
00326 lthr[1][i] = 60802371420160.0;
00327 }
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338 freq_mult = sfreq / BLKSIZE;
00339
00340
00341 for (i = 0; i < HBLKSIZE; i++) {
00342 temp1 = i * freq_mult;
00343 j = 1;
00344 while (temp1 > crit_band[j])
00345 j++;
00346 fthr[i] =
00347 j - 1 + (temp1 - crit_band[j - 1]) / (crit_band[j] - crit_band[j - 1]);
00348 }
00349 partition[0] = 0;
00350
00351 temp2 = 1;
00352 cbval[0] = fthr[0];
00353 bval_lo = fthr[0];
00354 for (i = 1; i < HBLKSIZE; i++) {
00355 if ((fthr[i] - bval_lo) > 0.33) {
00356 partition[i] = partition[i - 1] + 1;
00357 cbval[partition[i - 1]] = cbval[partition[i - 1]] / temp2;
00358 cbval[partition[i]] = fthr[i];
00359 bval_lo = fthr[i];
00360 numlines[partition[i - 1]] = temp2;
00361 temp2 = 1;
00362 } else {
00363 partition[i] = partition[i - 1];
00364 cbval[partition[i]] += fthr[i];
00365 temp2++;
00366 }
00367 }
00368 numlines[partition[i - 1]] = temp2;
00369 cbval[partition[i - 1]] = cbval[partition[i - 1]] / temp2;
00370
00371
00372
00373
00374
00375 for (j = 0; j < CBANDS; j++) {
00376 for (i = 0; i < CBANDS; i++) {
00377 temp1 = (cbval[i] - cbval[j]) * 1.05;
00378 if (temp1 >= 0.5 && temp1 <= 2.5) {
00379 temp2 = temp1 - 0.5;
00380 temp2 = 8.0 * (temp2 * temp2 - 2.0 * temp2);
00381 } else
00382 temp2 = 0;
00383 temp1 += 0.474;
00384 temp3 =
00385 15.811389 + 7.5 * temp1 -
00386 17.5 * sqrt ((double) (1.0 + temp1 * temp1));
00387 if (temp3 <= -100)
00388 s[i][j] = 0;
00389 else {
00390 temp3 = (temp2 + temp3) * LN_TO_LOG10;
00391 s[i][j] = exp (temp3);
00392 }
00393 }
00394 }
00395
00396
00397 for (j = 0; j < CBANDS; j++) {
00398 temp1 = 15.5 + cbval[j];
00399 tmn[j] = (temp1 > 24.5) ? temp1 : 24.5;
00400
00401 rnorm[j] = 0;
00402 for (i = 0; i < CBANDS; i++) {
00403 rnorm[j] += s[j][i];
00404 }
00405 }
00406
00407 if (glopts.verbosity > 10){
00408
00409 int wlow, whigh=0;
00410 fprintf(stdout,"psy model 2 init\n");
00411 fprintf(stdout,"index \tnlines \twlow \twhigh \tbval \tminval \ttmn\n");
00412 for (i=0;i<CBANDS;i++) {
00413 wlow = whigh+1;
00414 whigh = wlow + numlines[i] - 1;
00415 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],bmax[(int)(cbval[i]+0.5)],tmn[i]);
00416 }
00417 exit(0);
00418 }
00419
00420 }
00421
00422 void psycho_2_read_absthr (absthr, table)
00423 FLOAT *absthr;
00424 int table;
00425 {
00426 int j;
00427 #include "absthr.h"
00428
00429 if ((table < 0) || (table > 3)) {
00430 printf ("internal error: wrong table number");
00431 return;
00432 }
00433
00434 for (j = 0; j < HBLKSIZE; j++) {
00435 absthr[j] = absthr_table[table][j];
00436 }
00437 return;
00438 }