[FFmpeg-soc] [soc]: r2847 - aacenc/aacpsy.c

kostya subversion at mplayerhq.hu
Fri Jul 25 14:52:51 CEST 2008


Author: kostya
Date: Fri Jul 25 14:52:50 2008
New Revision: 2847

Log:
Make 3GPP-inspired psy model handle eight short windows case

Modified:
   aacenc/aacpsy.c

Modified: aacenc/aacpsy.c
==============================================================================
--- aacenc/aacpsy.c	(original)
+++ aacenc/aacpsy.c	Fri Jul 25 14:52:50 2008
@@ -322,8 +322,10 @@ typedef struct Psy3gppContext{
     float       barks [1024];
     float       bark_l[64];
     float       bark_s[16];
-    float       s_low [1024];
-    float       s_hi  [1024];
+    float       s_low_s[64];
+    float       s_low_l[16];
+    float       s_hi_s [64];
+    float       s_hi_l [16];
     Psy3gppBand band[2][128];
     Psy3gppBand prev_band[2][128];
     int         reservoir;
@@ -332,7 +334,8 @@ typedef struct Psy3gppContext{
     float       b[2];
     float       pe[2];
     float       thr[2];
-    float       ath[64];
+    float       ath_l[64];
+    float       ath_s[16];
 }Psy3gppContext;
 
 /**
@@ -375,8 +378,18 @@ static av_cold int psy_3gpp_init(AACPsyC
         prev = pctx->barks[i - 1];
     }
     for(g = 0; g < apc->num_bands1024 - 1; g++){
-        pctx->s_low[g] = pow(10.0, -(pctx->bark_l[g+1] - pctx->bark_l[g]) * PSY_3GPP_SPREAD_LOW);
-        pctx->s_hi [g] = pow(10.0, -(pctx->bark_l[g+1] - pctx->bark_l[g]) * PSY_3GPP_SPREAD_HI);
+        pctx->s_low_l[g] = pow(10.0, -(pctx->bark_l[g+1] - pctx->bark_l[g]) * PSY_3GPP_SPREAD_LOW);
+        pctx->s_hi_l [g] = pow(10.0, -(pctx->bark_l[g+1] - pctx->bark_l[g]) * PSY_3GPP_SPREAD_HI);
+    }
+    prev = 0.0;
+    for(g = 0; g < apc->num_bands128; g++){
+        i += apc->bands128[g];
+        pctx->bark_s[g] = (pctx->barks[i - 1] + prev) / 2.0;
+        prev = pctx->barks[i - 1];
+    }
+    for(g = 0; g < apc->num_bands128 - 1; g++){
+        pctx->s_low_s[g] = pow(10.0, -(pctx->bark_s[g+1] - pctx->bark_s[g]) * PSY_3GPP_SPREAD_LOW);
+        pctx->s_hi_s [g] = pow(10.0, -(pctx->bark_s[g+1] - pctx->bark_s[g]) * PSY_3GPP_SPREAD_HI);
     }
     start = 0;
     minath = ath(3410, ATH_ADD);
@@ -385,9 +398,18 @@ static av_cold int psy_3gpp_init(AACPsyC
         for(i = 1; i < apc->bands1024[g]; i++){
             minscale = fminf(minscale, ath(apc->avctx->sample_rate * (start + i) / 1024.0 / 2.0, ATH_ADD));
         }
-        pctx->ath[g] = minscale - minath;
+        pctx->ath_l[g] = minscale - minath;
         start += apc->bands1024[g];
     }
+    start = 0;
+    for(g = 0; g < apc->num_bands128; g++){
+        minscale = ath(apc->avctx->sample_rate * start / 1024.0, ATH_ADD);
+        for(i = 1; i < apc->bands128[g]; i++){
+            minscale = fminf(minscale, ath(apc->avctx->sample_rate * (start + i) / 1024.0 / 2.0, ATH_ADD));
+        }
+        pctx->ath_s[g] = minscale - minath;
+        start += apc->bands128[g];
+    }
 
     pctx->avg_bits = apc->avctx->bit_rate * 1024 / apc->avctx->sample_rate;
     return 0;
@@ -452,7 +474,7 @@ static void calc_pe(Psy3gppBand *band, i
 static void psy_3gpp_process(AACPsyContext *apc, int channel, ChannelElement *cpe)
 {
     int start;
-    int ch, g, i;
+    int ch, w, g, g2, i;
     int prev_scale;
     Psy3gppContext *pctx = (Psy3gppContext*) apc->model_priv_data;
     float stereo_att, pe_target;
@@ -475,44 +497,59 @@ static void psy_3gpp_process(AACPsyConte
     for(ch = 0; ch < apc->avctx->channels; ch++){
         start = 0;
         cpe->ch[ch].gain = 0;
+        for(w = 0; w < cpe->ch[ch].ics.num_windows; w++){
         for(g = 0; g < cpe->ch[ch].ics.num_swb; g++){
+            g2 = w*16 + g;
             for(i = 0; i < cpe->ch[ch].ics.swb_sizes[g]; i++)
-                pctx->band[ch][g].energy +=  cpe->ch[ch].coeffs[start+i] *  cpe->ch[ch].coeffs[start+i];
-            pctx->band[ch][g].thr = pctx->band[ch][g].energy * 0.001258925f;
+                pctx->band[ch][g2].energy +=  cpe->ch[ch].coeffs[start+i] *  cpe->ch[ch].coeffs[start+i];
+            pctx->band[ch][g2].thr = pctx->band[ch][g2].energy * 0.001258925f;
             start += cpe->ch[ch].ics.swb_sizes[g];
-            if(pctx->band[ch][g].energy != 0.0){
+            if(pctx->band[ch][g2].energy != 0.0){
                 float ffac = 0.0;
 
                 for(i = 0; i < cpe->ch[ch].ics.swb_sizes[g]; i++)
                     ffac += sqrt(FFABS(cpe->ch[ch].coeffs[start+i]));
-                pctx->band[ch][g].ffac = ffac;
-                calc_pe(&pctx->band[ch][g], cpe->ch[ch].ics.swb_sizes[g]);
+                pctx->band[ch][g2].ffac = ffac;
+                calc_pe(&pctx->band[ch][g2], cpe->ch[ch].ics.swb_sizes[g]);
             }
         }
+        }
     }
 
     //modify thresholds - spread, threshold in quiet - 5.4.3
     for(ch = 0; ch < apc->avctx->channels; ch++){
-        for(g = 1; g < cpe->ch[ch].ics.num_swb; g++)
-            pctx->band[ch][g].thr = FFMAX(pctx->band[ch][g].thr, pctx->band[ch][g-1].thr * pctx->s_low[g-1]);
-        for(g = cpe->ch[ch].ics.num_swb - 2; g >= 0; g--)
-            pctx->band[ch][g].thr = FFMAX(pctx->band[ch][g].thr, pctx->band[ch][g+1].thr * pctx->s_hi[g+1]);
+        for(w = 0; w < cpe->ch[ch].ics.num_windows; w++){
+        for(g = 1; g < cpe->ch[ch].ics.num_swb; g++){
+            g2 = w*16 + g;
+            pctx->band[ch][g2].thr = FFMAX(pctx->band[ch][g2].thr, pctx->band[ch][g2-1].thr * pctx->s_low_l[g-1]);
+        }
+        for(g = cpe->ch[ch].ics.num_swb - 2; g >= 0; g--){
+            g2 = w*16 + g;
+            pctx->band[ch][g2].thr = FFMAX(pctx->band[ch][g2].thr, pctx->band[ch][g2+1].thr * pctx->s_hi_l[g+1]);
+        }
         for(g = 0; g < cpe->ch[ch].ics.num_swb; g++){
-            pctx->band[ch][g].thr_quiet = FFMAX(pctx->band[ch][g].thr, pctx->ath[g]);
-            pctx->band[ch][g].thr_quiet = fmaxf(PSY_3GPP_RPEMIN*pctx->band[ch][g].thr_quiet, fminf(pctx->band[ch][g].thr_quiet, PSY_3GPP_RPELEV*pctx->prev_band[ch][g].thr_quiet));
-            pctx->band[ch][g].thr = FFMAX(pctx->band[ch][g].thr, pctx->band[ch][g].thr_quiet * 0.25);
+            g2 = w*16 + g;
+            if(cpe->ch[ch].ics.num_swb == apc->num_bands1024)
+                pctx->band[ch][g2].thr_quiet = FFMAX(pctx->band[ch][g2].thr, pctx->ath_l[g]);
+            else
+                pctx->band[ch][g2].thr_quiet = FFMAX(pctx->band[ch][g2].thr, pctx->ath_s[g]);
+            pctx->band[ch][g2].thr_quiet = fmaxf(PSY_3GPP_RPEMIN*pctx->band[ch][g2].thr_quiet, fminf(pctx->band[ch][g2].thr_quiet, PSY_3GPP_RPELEV*pctx->prev_band[ch][g2].thr_quiet));
+            pctx->band[ch][g2].thr = FFMAX(pctx->band[ch][g2].thr, pctx->band[ch][g2].thr_quiet * 0.25);
+        }
         }
     }
 
     // M/S detection - 5.5.2
     if(apc->avctx->channels > 1 && cpe->common_window){
         start = 0;
+        for(w = 0; w < cpe->ch[ch].ics.num_windows; w++){
         for(g = 0; g < cpe->ch[0].ics.num_swb; g++){
             double en_m = 0.0, en_s = 0.0, l1;
             float m, s;
 
-            cpe->ms.mask[0][g] = 0;
-            if(pctx->band[0][g].energy == 0.0 || pctx->band[1][g].energy == 0.0)
+            g2 = w*16 + g;
+            cpe->ms.mask[w][g] = 0;
+            if(pctx->band[0][g2].energy == 0.0 || pctx->band[1][g2].energy == 0.0)
                 continue;
             for(i = 0; i < cpe->ch[0].ics.swb_sizes[g]; i++){
                 m = (cpe->ch[0].coeffs[start+i] + cpe->ch[1].coeffs[start+i]) / 2.0;
@@ -520,30 +557,34 @@ static void psy_3gpp_process(AACPsyConte
                 en_m += m*m;
                 en_s += s*s;
             }
-            l1 = FFMIN(pctx->band[0][g].thr, pctx->band[1][g].thr);
-            if(en_m == 0.0 || en_s == 0.0 || l1*l1 / (en_m * en_s) >= (pctx->band[0][g].thr * pctx->band[1][g].thr / (pctx->band[0][g].energy * pctx->band[1][g].energy))){
-                cpe->ms.mask[0][g] = 1;
-                pctx->band[0][g].energy = en_m;
-                pctx->band[1][g].energy = en_s;
-                pctx->band[0][g].thr = en_m * 0.001258925f;
-                pctx->band[1][g].thr = en_s * 0.001258925f;
+            l1 = FFMIN(pctx->band[0][g2].thr, pctx->band[1][g2].thr);
+            if(en_m == 0.0 || en_s == 0.0 || l1*l1 / (en_m * en_s) >= (pctx->band[0][g2].thr * pctx->band[1][g2].thr / (pctx->band[0][g2].energy * pctx->band[1][g2].energy))){
+                cpe->ms.mask[w][g] = 1;
+                pctx->band[0][g2].energy = en_m;
+                pctx->band[1][g2].energy = en_s;
+                pctx->band[0][g2].thr = en_m * 0.001258925f;
+                pctx->band[1][g2].thr = en_s * 0.001258925f;
                 //TODO: minSnr update
             }
         }
+        }
     }
 
     for(ch = 0; ch < apc->avctx->channels; ch++){
         pctx->a[ch] = pctx->b[ch] = pctx->pe[ch] = pctx->thr[ch] = 0.0f;
+        for(w = 0; w < cpe->ch[ch].ics.num_windows; w++){
         for(g = 0; g < cpe->ch[ch].ics.num_swb; g++){
-            if(pctx->band[ch][g].energy != 0.0)
-                calc_pe(&pctx->band[ch][g], cpe->ch[ch].ics.swb_sizes[g]);
-            if(pctx->band[ch][g].thr < pctx->band[ch][g].energy){
-                pctx->a[ch]   += pctx->band[ch][g].a;
-                pctx->b[ch]   += pctx->band[ch][g].b;
-                pctx->pe[ch]  += pctx->band[ch][g].pe;
-                pctx->thr[ch] += pctx->band[ch][g].thr;
+            g2 = w*16 + g;
+            if(pctx->band[ch][g2].energy != 0.0)
+                calc_pe(&pctx->band[ch][g2], cpe->ch[ch].ics.swb_sizes[g]);
+            if(pctx->band[ch][g2].thr < pctx->band[ch][g2].energy){
+                pctx->a[ch]   += pctx->band[ch][g2].a;
+                pctx->b[ch]   += pctx->band[ch][g2].b;
+                pctx->pe[ch]  += pctx->band[ch][g2].pe;
+                pctx->thr[ch] += pctx->band[ch][g2].thr;
             }
         }
+        }
     }
 
     //bitrate reduction - 5.6.1
@@ -562,16 +603,19 @@ static void psy_3gpp_process(AACPsyConte
             //add correction factor to thresholds and recalculate perceptual entropy
             pctx->a[ch] = pctx->b[ch] = pctx->pe[ch] = pctx->thr[ch] = 0.0;
             pe = 0.0f;
+            for(w = 0; w < cpe->ch[ch].ics.num_windows; w++){
             for(g = 0; g < cpe->ch[ch].ics.num_swb; g++){
-                pctx->band[ch][g].thr = modify_thr(pctx->band[ch][g].thr, r);
-                calc_pe(&pctx->band[ch][g], cpe->ch[ch].ics.swb_sizes[g]);
-                if(pctx->band[ch][g].thr < pctx->band[ch][g].energy){
-                    pctx->a[ch]   += pctx->band[ch][g].a;
-                    pctx->b[ch]   += pctx->band[ch][g].b;
-                    pctx->pe[ch]  += pctx->band[ch][g].pe;
-                    pctx->thr[ch] += pctx->band[ch][g].thr;
+                g2 = w*16 + g;
+                pctx->band[ch][g2].thr = modify_thr(pctx->band[ch][g2].thr, r);
+                calc_pe(&pctx->band[ch][g2], cpe->ch[ch].ics.swb_sizes[g]);
+                if(pctx->band[ch][g2].thr < pctx->band[ch][g2].energy){
+                    pctx->a[ch]   += pctx->band[ch][g2].a;
+                    pctx->b[ch]   += pctx->band[ch][g2].b;
+                    pctx->pe[ch]  += pctx->band[ch][g2].pe;
+                    pctx->thr[ch] += pctx->band[ch][g2].thr;
                 }
             }
+            }
         }
         //TODO: linearization
     }
@@ -581,28 +625,31 @@ static void psy_3gpp_process(AACPsyConte
         int min_scale = 256;
         prev_scale = -1;
         cpe->ch[ch].gain = 0;
+        for(w = 0; w < cpe->ch[ch].ics.num_windows; w++){
         for(g = 0; g < cpe->ch[ch].ics.num_swb; g++){
-            cpe->ch[ch].zeroes[0][g] = pctx->band[ch][g].thr >= pctx->band[ch][g].energy;
-            if(cpe->ch[ch].zeroes[0][g]) continue;
+            g2 = w*16 + g;
+            cpe->ch[ch].zeroes[w][g] = pctx->band[ch][g2].thr >= pctx->band[ch][g2].energy;
+            if(cpe->ch[ch].zeroes[w][g]) continue;
             //spec gives constant for lg() but we scaled it for log2()
-            cpe->ch[ch].sf_idx[0][g] = (int)(2.66667 * (log2(6.75*pctx->band[ch][g].thr) - log2(pctx->band[ch][g].ffac)));
+            cpe->ch[ch].sf_idx[w][g] = (int)(2.66667 * (log2(6.75*pctx->band[ch][g2].thr) - log2(pctx->band[ch][g2].ffac)));
             if(prev_scale != -1)
-                cpe->ch[ch].sf_idx[0][g] = av_clip(cpe->ch[ch].sf_idx[0][g], prev_scale - SCALE_MAX_DIFF, prev_scale + SCALE_MAX_DIFF);
-            prev_scale = cpe->ch[ch].sf_idx[0][g];
+                cpe->ch[ch].sf_idx[w][g] = av_clip(cpe->ch[ch].sf_idx[w][g], prev_scale - SCALE_MAX_DIFF, prev_scale + SCALE_MAX_DIFF);
+            prev_scale = cpe->ch[ch].sf_idx[w][g];
         }
         //limit scalefactors
         for(g = 0; g < cpe->ch[ch].ics.num_swb; g++){
-            if(cpe->ch[ch].zeroes[0][g]) continue;
-            min_scale = FFMIN(min_scale, cpe->ch[ch].sf_idx[0][g]);
+            if(cpe->ch[ch].zeroes[w][g]) continue;
+            min_scale = FFMIN(min_scale, cpe->ch[ch].sf_idx[w][g]);
         }
         for(g = 0; g < cpe->ch[ch].ics.num_swb; g++){
-            if(cpe->ch[ch].zeroes[0][g]) continue;
-            cpe->ch[ch].sf_idx[0][g] = FFMIN(cpe->ch[ch].sf_idx[0][g], min_scale + SCALE_MAX_DIFF);
+            if(cpe->ch[ch].zeroes[w][g]) continue;
+            cpe->ch[ch].sf_idx[w][g] = FFMIN(cpe->ch[ch].sf_idx[w][g], min_scale + SCALE_MAX_DIFF);
         }
         for(g = 0; g < cpe->ch[ch].ics.num_swb; g++){
-            if(cpe->ch[ch].zeroes[0][g]) continue;
-            cpe->ch[ch].sf_idx[0][g] = av_clip(SCALE_ONE_POS + cpe->ch[ch].sf_idx[0][g], 0, SCALE_MAX_POS);
-            if(!cpe->ch[ch].gain) cpe->ch[ch].gain = cpe->ch[ch].sf_idx[0][g];
+            if(cpe->ch[ch].zeroes[w][g]) continue;
+            cpe->ch[ch].sf_idx[w][g] = av_clip(SCALE_ONE_POS + cpe->ch[ch].sf_idx[w][g], 0, SCALE_MAX_POS);
+            if(!cpe->ch[ch].gain) cpe->ch[ch].gain = cpe->ch[ch].sf_idx[w][g];
+        }
         }
     }
 



More information about the FFmpeg-soc mailing list