MDCT analysis-synthesis (untested)
authorJean-Marc Valin <jean-marc.valin@usherbrooke.ca>
Thu, 29 Nov 2007 14:10:42 +0000 (01:10 +1100)
committerJean-Marc Valin <jean-marc.valin@usherbrooke.ca>
Thu, 29 Nov 2007 14:10:42 +0000 (01:10 +1100)
celt.kdevelop
libcelt/celt.c
libcelt/mdct.c
libcelt/mdct.h
libcelt/os_support.h

index ab27c56..c4e9153 100644 (file)
@@ -8,12 +8,27 @@
     <primarylanguage>C</primarylanguage>
     <ignoreparts/>
     <projectname>celt</projectname>
+    <projectdirectory>.</projectdirectory>
+    <absoluteprojectpath>false</absoluteprojectpath>
+    <description/>
+    <defaultencoding/>
   </general>
   <kdevautoproject>
     <general>
-      <useconfiguration>debug</useconfiguration>
+      <useconfiguration>default</useconfiguration>
     </general>
-    <run/>
+    <run>
+      <mainprogram/>
+      <programargs/>
+      <globaldebugarguments/>
+      <globalcwd/>
+      <useglobalprogram>true</useglobalprogram>
+      <terminal>false</terminal>
+      <autocompile>false</autocompile>
+      <autoinstall>false</autoinstall>
+      <autokdesu>false</autokdesu>
+      <envvars/>
+    </run>
     <configurations>
       <optimized>
         <builddir>optimized</builddir>
         <cflags>-O0 -g3</cflags>
       </debug>
     </configurations>
+    <make>
+      <envvars>
+        <envvar value="1" name="WANT_AUTOCONF_2_5" />
+        <envvar value="1" name="WANT_AUTOMAKE_1_6" />
+      </envvars>
+    </make>
   </kdevautoproject>
   <kdevdebugger>
     <general>
       <dbgshell>libtool</dbgshell>
+      <gdbpath/>
+      <configGdbScript/>
+      <runShellScript/>
+      <runGdbScript/>
+      <breakonloadinglibs>true</breakonloadinglibs>
+      <separatetty>false</separatetty>
+      <floatingtoolbar>false</floatingtoolbar>
+      <raiseGDBOnStart>false</raiseGDBOnStart>
     </general>
+    <display>
+      <staticmembers>false</staticmembers>
+      <demanglenames>true</demanglenames>
+      <outputradix>10</outputradix>
+    </display>
   </kdevdebugger>
   <kdevdoctreeview>
     <ignoretocs>
       <type ext="h" />
     </useglobaltypes>
   </kdevfilecreate>
+  <kdevcppsupport>
+    <qt>
+      <used>false</used>
+      <version>3</version>
+      <includestyle>3</includestyle>
+      <root></root>
+      <designerintegration>EmbeddedKDevDesigner</designerintegration>
+      <qmake></qmake>
+      <designer></designer>
+      <designerpluginpaths/>
+    </qt>
+    <codecompletion>
+      <automaticCodeCompletion>false</automaticCodeCompletion>
+      <automaticArgumentsHint>true</automaticArgumentsHint>
+      <automaticHeaderCompletion>true</automaticHeaderCompletion>
+      <codeCompletionDelay>250</codeCompletionDelay>
+      <argumentsHintDelay>400</argumentsHintDelay>
+      <headerCompletionDelay>250</headerCompletionDelay>
+      <showOnlyAccessibleItems>false</showOnlyAccessibleItems>
+      <completionBoxItemOrder>0</completionBoxItemOrder>
+      <howEvaluationContextMenu>true</howEvaluationContextMenu>
+      <showCommentWithArgumentHint>true</showCommentWithArgumentHint>
+      <statusBarTypeEvaluation>false</statusBarTypeEvaluation>
+      <namespaceAliases>std=_GLIBCXX_STD;__gnu_cxx=std</namespaceAliases>
+      <processPrimaryTypes>true</processPrimaryTypes>
+      <processFunctionArguments>false</processFunctionArguments>
+      <preProcessAllHeaders>false</preProcessAllHeaders>
+      <parseMissingHeadersExperimental>false</parseMissingHeadersExperimental>
+      <resolveIncludePathsUsingMakeExperimental>false</resolveIncludePathsUsingMakeExperimental>
+      <alwaysParseInBackground>true</alwaysParseInBackground>
+      <usePermanentCaching>true</usePermanentCaching>
+      <alwaysIncludeNamespaces>false</alwaysIncludeNamespaces>
+      <includePaths>.;</includePaths>
+    </codecompletion>
+    <creategettersetter>
+      <prefixGet/>
+      <prefixSet>set</prefixSet>
+      <prefixVariable>m_,_</prefixVariable>
+      <parameterName>theValue</parameterName>
+      <inlineGet>true</inlineGet>
+      <inlineSet>true</inlineSet>
+    </creategettersetter>
+    <splitheadersource>
+      <enabled>false</enabled>
+      <synchronize>true</synchronize>
+      <orientation>Vertical</orientation>
+    </splitheadersource>
+    <references/>
+  </kdevcppsupport>
+  <cppsupportpart>
+    <filetemplates>
+      <interfacesuffix>.h</interfacesuffix>
+      <implementationsuffix>.cpp</implementationsuffix>
+    </filetemplates>
+  </cppsupportpart>
+  <kdevfileview>
+    <groups>
+      <hidenonprojectfiles>false</hidenonprojectfiles>
+      <hidenonlocation>false</hidenonlocation>
+    </groups>
+    <tree>
+      <hidepatterns>*.o,*.lo,CVS</hidepatterns>
+      <hidenonprojectfiles>false</hidenonprojectfiles>
+    </tree>
+  </kdevfileview>
 </kdevelop>
index 4ba3887..20c6e17 100644 (file)
 */
 
 #include "os_support.h"
+#include "mdct.h"
+#include <math.h>
+
+#define MAX_PERIOD 2048
 
 struct CELTState_ {
    int frame_size;
@@ -39,6 +43,8 @@ struct CELTState_ {
    float preemph;
    float preemph_mem;
    
+   mdct_lookup mdct_lookup;
+   
    float *window;
    float *in_mem;
    float *mdct_overlap;
@@ -49,24 +55,53 @@ typedef struct CELTState_ CELTState;
 
 CELTState *celt_init(int blockSize, int blocksPerFrame)
 {
+   int i, N;
+   N = blockSize;
+   CELTState *st = celt_alloc(sizeof(CELTState));
+   
+   st->frame_size = blockSize * blocksPerFrame;
+   st->block_size = blockSize;
+   st->nb_blocks  = blocksPerFrame;
+   
+   mdct_init(&st->mdct_lookup, 2*N);
    
+   st->window = celt_alloc(2*N*sizeof(float));
+   st->in_mem = celt_alloc(N*sizeof(float));
+   st->mdct_overlap = celt_alloc(N*sizeof(float));
+   st->out_mem = celt_alloc(MAX_PERIOD*sizeof(float));
+
+   for (i=0;i<N;i++)
+      st->window[i] = st->window[2*N-i-1] = sin(.5*M_PI* sin(.5*M_PI*(i+.5)/N) * sin(.5*M_PI*(i+.5)/N));
+   return st;
 }
 
 void celt_encode(CELTState *st, short *pcm)
 {
-   int i;
-   int N = st->block_size;
-   float in[(st->nb_blocks+1)*N];
-   float X[st->nb_blocks*N];
+   int i, N, B;
+   N = st->block_size;
+   B = st->nb_blocks;
+   float in[(B+1)*N];
+   float X[B*N];
    
    /* FIXME: Add preemphasis */
    for (i=0;i<N;i++)
       in[i] = st->in_mem[i];
-   for (;i<st->nb_blocks*N;i++)
+   for (;i<(B+1)*N;i++)
       in[i] = pcm[i-N];
    
-   /* Compute MDCTs */
+   for (i=0;i<N;i++)
+      st->in_mem[i] = pcm[(B-1)*N+i];
 
+   /* Compute MDCTs */
+   for (i=0;i<B;i++)
+   {
+      int j;
+      float x[2*N];
+      for (j=0;j<2*N;j++)
+         x[j] = st->window[j]*in[i*N+j];
+      mdct_forward(&st->mdct_lookup, x, X+N*i);
+   }
+   
    /* Pitch analysis */
 
    /* Band normalisation */
@@ -76,5 +111,24 @@ void celt_encode(CELTState *st, short *pcm)
    /* Residual quantisation */
    
    /* Synthesis */
+
+   CELT_MOVE(st->out_mem, st->out_mem+B*N, MAX_PERIOD-B*N);
+   /* Compute inverse MDCTs */
+   for (i=0;i<B;i++)
+   {
+      int j;
+      float x[2*N];
+      mdct_backward(&st->mdct_lookup, X+N*i, x);
+      for (j=0;j<2*N;j++)
+         x[j] = st->window[j]*x[j];
+      for (j=0;j<N;j++)
+         st->out_mem[MAX_PERIOD+(i-B)*N+j] = x[j]+st->mdct_overlap[j];
+      for (j=0;j<N;j++)
+         st->mdct_overlap[j] = x[N+j];
+      
+      for (j=0;j<N;j++)
+         pcm[i*N+j] = st->out_mem[MAX_PERIOD+(i-B)*N+j];
+   }
+
 }
 
index ae83ed4..12e9a0f 100644 (file)
@@ -41,9 +41,9 @@
 #include <stdlib.h>
 #include <string.h>
 #include <math.h>
-#include "vorbis/codec.h"
+/*#include "vorbis/codec.h"*/
 #include "mdct.h"
-/*#include "os.h"*/
+#include "os_support.h"
 /*#include "misc.h"*/
 
 #define STIN static inline
@@ -52,8 +52,8 @@
    some window function algebra. */
 
 void mdct_init(mdct_lookup *lookup,int n){
-  int   *bitrev=_ogg_malloc(sizeof(*bitrev)*(n/4));
-  DATA_TYPE *T=_ogg_malloc(sizeof(*T)*(n+n/4));
+  int   *bitrev=celt_alloc(sizeof(*bitrev)*(n/4));
+  DATA_TYPE *T=celt_alloc(sizeof(*T)*(n+n/4));
   
   int i;
   int n2=n>>1;
@@ -340,8 +340,8 @@ STIN void mdct_butterflies(mdct_lookup *init,
 
 void mdct_clear(mdct_lookup *l){
   if(l){
-    if(l->trig)_ogg_free(l->trig);
-    if(l->bitrev)_ogg_free(l->bitrev);
+    if(l->trig)celt_free(l->trig);
+    if(l->bitrev)celt_free(l->bitrev);
     memset(l,0,sizeof(*l));
   }
 }
index 176daad..b91dc43 100644 (file)
@@ -18,7 +18,7 @@
 #ifndef _OGG_mdct_H_
 #define _OGG_mdct_H_
 
-#include "vorbis/codec.h"
+/*#include "vorbis/codec.h"*/
 
 
 
index d2f9eb8..ad06b95 100644 (file)
 #include <stdio.h>
 #include <stdlib.h>
 
-/** Speex wrapper for calloc. To do your own dynamic allocation, all you need to do is replace this function, speex_realloc and speex_free 
-    NOTE: speex_alloc needs to CLEAR THE MEMORY */
-#ifndef OVERRIDE_SPEEX_ALLOC
-static inline void *speex_alloc (int size)
+/** Speex wrapper for calloc. To do your own dynamic allocation, all you need to do is replace this function, celt_realloc and celt_free 
+    NOTE: celt_alloc needs to CLEAR THE MEMORY */
+#ifndef OVERRIDE_CELT_ALLOC
+static inline void *celt_alloc (int size)
 {
    /* WARNING: this is not equivalent to malloc(). If you want to use malloc() 
       or your own allocator, YOU NEED TO CLEAR THE MEMORY ALLOCATED. Otherwise
@@ -50,66 +50,66 @@ static inline void *speex_alloc (int size)
 }
 #endif
 
-/** Same as speex_alloc, except that the area is only needed inside a Speex call (might cause problem with wideband though) */
-#ifndef OVERRIDE_SPEEX_ALLOC_SCRATCH
-static inline void *speex_alloc_scratch (int size)
+/** Same as celt_alloc, except that the area is only needed inside a Speex call (might cause problem with wideband though) */
+#ifndef OVERRIDE_CELT_ALLOC_SCRATCH
+static inline void *celt_alloc_scratch (int size)
 {
    /* Scratch space doesn't need to be cleared */
    return calloc(size,1);
 }
 #endif
 
-/** Speex wrapper for realloc. To do your own dynamic allocation, all you need to do is replace this function, speex_alloc and speex_free */
-#ifndef OVERRIDE_SPEEX_REALLOC
-static inline void *speex_realloc (void *ptr, int size)
+/** Speex wrapper for realloc. To do your own dynamic allocation, all you need to do is replace this function, celt_alloc and celt_free */
+#ifndef OVERRIDE_CELT_REALLOC
+static inline void *celt_realloc (void *ptr, int size)
 {
    return realloc(ptr, size);
 }
 #endif
 
-/** Speex wrapper for calloc. To do your own dynamic allocation, all you need to do is replace this function, speex_realloc and speex_alloc */
-#ifndef OVERRIDE_SPEEX_FREE
-static inline void speex_free (void *ptr)
+/** Speex wrapper for calloc. To do your own dynamic allocation, all you need to do is replace this function, celt_realloc and celt_alloc */
+#ifndef OVERRIDE_CELT_FREE
+static inline void celt_free (void *ptr)
 {
    free(ptr);
 }
 #endif
 
-/** Same as speex_free, except that the area is only needed inside a Speex call (might cause problem with wideband though) */
-#ifndef OVERRIDE_SPEEX_FREE_SCRATCH
-static inline void speex_free_scratch (void *ptr)
+/** Same as celt_free, except that the area is only needed inside a Speex call (might cause problem with wideband though) */
+#ifndef OVERRIDE_CELT_FREE_SCRATCH
+static inline void celt_free_scratch (void *ptr)
 {
    free(ptr);
 }
 #endif
 
 /** Copy n bytes of memory from src to dst. The 0* term provides compile-time type checking  */
-#ifndef OVERRIDE_SPEEX_COPY
-#define SPEEX_COPY(dst, src, n) (memcpy((dst), (src), (n)*sizeof(*(dst)) + 0*((dst)-(src)) ))
+#ifndef OVERRIDE_CELT_COPY
+#define CELT_COPY(dst, src, n) (memcpy((dst), (src), (n)*sizeof(*(dst)) + 0*((dst)-(src)) ))
 #endif
 
 /** Copy n bytes of memory from src to dst, allowing overlapping regions. The 0* term 
     provides compile-time type checking */
-#ifndef OVERRIDE_SPEEX_MOVE
-#define SPEEX_MOVE(dst, src, n) (memmove((dst), (src), (n)*sizeof(*(dst)) + 0*((dst)-(src)) ))
+#ifndef OVERRIDE_CELT_MOVE
+#define CELT_MOVE(dst, src, n) (memmove((dst), (src), (n)*sizeof(*(dst)) + 0*((dst)-(src)) ))
 #endif
 
 /** Set n bytes of memory to value of c, starting at address s */
-#ifndef OVERRIDE_SPEEX_MEMSET
-#define SPEEX_MEMSET(dst, c, n) (memset((dst), (c), (n)*sizeof(*(dst))))
+#ifndef OVERRIDE_CELT_MEMSET
+#define CELT_MEMSET(dst, c, n) (memset((dst), (c), (n)*sizeof(*(dst))))
 #endif
 
 
-#ifndef OVERRIDE_SPEEX_FATAL
-static inline void _speex_fatal(const char *str, const char *file, int line)
+#ifndef OVERRIDE_CELT_FATAL
+static inline void _celt_fatal(const char *str, const char *file, int line)
 {
    fprintf (stderr, "Fatal (internal) error in %s, line %d: %s\n", file, line, str);
    exit(1);
 }
 #endif
 
-#ifndef OVERRIDE_SPEEX_WARNING
-static inline void speex_warning(const char *str)
+#ifndef OVERRIDE_CELT_WARNING
+static inline void celt_warning(const char *str)
 {
 #ifndef DISABLE_WARNINGS
    fprintf (stderr, "warning: %s\n", str);
@@ -117,8 +117,8 @@ static inline void speex_warning(const char *str)
 }
 #endif
 
-#ifndef OVERRIDE_SPEEX_WARNING_INT
-static inline void speex_warning_int(const char *str, int val)
+#ifndef OVERRIDE_CELT_WARNING_INT
+static inline void celt_warning_int(const char *str, int val)
 {
 #ifndef DISABLE_WARNINGS
    fprintf (stderr, "warning: %s %d\n", str, val);
@@ -126,8 +126,8 @@ static inline void speex_warning_int(const char *str, int val)
 }
 #endif
 
-#ifndef OVERRIDE_SPEEX_NOTIFY
-static inline void speex_notify(const char *str)
+#ifndef OVERRIDE_CELT_NOTIFY
+static inline void celt_notify(const char *str)
 {
 #ifndef DISABLE_NOTIFICATIONS
    fprintf (stderr, "notification: %s\n", str);
@@ -135,17 +135,17 @@ static inline void speex_notify(const char *str)
 }
 #endif
 
-#ifndef OVERRIDE_SPEEX_PUTC
+#ifndef OVERRIDE_CELT_PUTC
 /** Speex wrapper for putc */
-static inline void _speex_putc(int ch, void *file)
+static inline void _celt_putc(int ch, void *file)
 {
    FILE *f = (FILE *)file;
    fprintf(f, "%c", ch);
 }
 #endif
 
-#define speex_fatal(str) _speex_fatal(str, __FILE__, __LINE__);
-#define speex_assert(cond) {if (!(cond)) {speex_fatal("assertion failed: " #cond);}}
+#define celt_fatal(str) _celt_fatal(str, __FILE__, __LINE__);
+#define celt_assert(cond) {if (!(cond)) {celt_fatal("assertion failed: " #cond);}}
 
 #ifndef RELEASE
 static inline void print_vec(float *vec, int len, char *name)