changeset 3842:5f8cfa1a6fdb libavcodec

Original Commit: r39 | ods15 | 2006-09-23 09:36:11 +0300 (Sat, 23 Sep 2006) | 2 lines add window function
author ods15
date Mon, 02 Oct 2006 05:56:25 +0000
parents 6591b55f6482
children 2fa04cd17b7e
files vorbis_enc.c
diffstat 1 files changed, 51 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/vorbis_enc.c	Mon Oct 02 05:56:23 2006 +0000
+++ b/vorbis_enc.c	Mon Oct 02 05:56:25 2006 +0000
@@ -98,6 +98,7 @@
     int blocksize[2]; // in (1<<n) format
     MDCTContext mdct[2];
     const float * win[2];
+    int have_saved;
     float * saved;
     float * samples;
     float * floor; // also used for tmp values for mdct
@@ -339,6 +340,7 @@
     venc->modes[0].blockflag = 0;
     venc->modes[0].mapping = 0;
 
+    venc->have_saved = 0;
     venc->saved = av_malloc(sizeof(float) * venc->channels * (1 << venc->blocksize[1]) / 2);
     venc->samples = av_malloc(sizeof(float) * venc->channels * (1 << venc->blocksize[1]));
     venc->floor = av_malloc(sizeof(float) * venc->channels * (1 << venc->blocksize[1]) / 2);
@@ -611,6 +613,53 @@
     return 0;
 }
 
+static int window(venc_context_t * venc, signed short * audio, int samples) {
+    int i, j, channel;
+    const float * win = venc->win[0];
+    int window_len = 1 << (venc->blocksize[0] - 1);
+    // FIXME use dsp
+
+    if (!venc->have_saved && !samples) return 0;
+
+    if (venc->have_saved) {
+        for (channel = 0; channel < venc->channels; channel++) {
+            memcpy(venc->samples + channel*window_len*2, venc->saved + channel*window_len, sizeof(float)*window_len);
+        }
+    } else {
+        for (channel = 0; channel < venc->channels; channel++) {
+            memset(venc->samples + channel*window_len*2, 0, sizeof(float)*window_len);
+        }
+    }
+
+    if (samples) {
+        for (channel = 0; channel < venc->channels; channel++) {
+            float * offset = venc->saved + channel*window_len*2 + window_len;
+            j = channel;
+            for (i = 0; i < samples; i++, j += venc->channels)
+                offset[i] = audio[j] / 32768. * win[window_len - i];
+        }
+    } else {
+        for (channel = 0; channel < venc->channels; channel++) {
+            memset(venc->samples + channel*window_len*2 + window_len, 0, sizeof(float)*window_len);
+        }
+    }
+
+    for (channel = 0; channel < venc->channels; channel++) {
+        ff_mdct_calc(&venc->mdct[0], venc->coeffs + channel*window_len, venc->samples + channel*window_len*2, venc->floor/*tmp*/);
+    }
+
+    if (samples) {
+        for (channel = 0; channel < venc->channels; channel++) {
+            j = channel;
+            for (i = 0; i < samples; i++, j += venc->channels)
+                venc->saved[i] = audio[j] / 32768. * win[i];
+        }
+        venc->have_saved = 1;
+    } else {
+        venc->have_saved = 0;
+    }
+    return 1;
+}
 
 static int vorbis_encode_frame(AVCodecContext * avccontext, unsigned char * packets, int buf_size, void *data)
 {
@@ -622,6 +671,8 @@
     PutBitContext pb;
     int i;
 
+    if (!window(venc, audio, samples)) return 0;
+
     init_put_bits(&pb, packets, buf_size);
 
     put_bits(&pb, 1, 0); // magic bit