[xiph-commits] r10725 - trunk/ghost/libghost

jm at svn.xiph.org jm at svn.xiph.org
Mon Jan 9 19:55:56 PST 2006


Author: jm
Date: 2006-01-09 19:55:51 -0800 (Mon, 09 Jan 2006)
New Revision: 10725

Modified:
   trunk/ghost/libghost/Makefile.am
   trunk/ghost/libghost/ghost.c
   trunk/ghost/libghost/ghost.h
   trunk/ghost/libghost/sinusoids.c
   trunk/ghost/libghost/sinusoids.h
   trunk/ghost/libghost/testghost.c
Log:
sinusoid picking using a high-res FFT (instead of just using pitch).


Modified: trunk/ghost/libghost/Makefile.am
===================================================================
--- trunk/ghost/libghost/Makefile.am	2006-01-10 02:27:16 UTC (rev 10724)
+++ trunk/ghost/libghost/Makefile.am	2006-01-10 03:55:51 UTC (rev 10725)
@@ -9,7 +9,8 @@
 lib_LTLIBRARIES = libghost.la
 
 # Sources for compilation in the library
-libghost_la_SOURCES = ghost.c sinusoids.c pitch.c lifting.c smallft.c fftwrap.c
+libghost_la_SOURCES = ghost.c sinusoids.c pitch.c lifting.c \
+	smallft.c fftwrap.c misc.c
 
 #noinst_HEADERS =
 

Modified: trunk/ghost/libghost/ghost.c
===================================================================
--- trunk/ghost/libghost/ghost.c	2006-01-10 02:27:16 UTC (rev 10724)
+++ trunk/ghost/libghost/ghost.c	2006-01-10 03:55:51 UTC (rev 10725)
@@ -28,9 +28,12 @@
 #include "ghost.h"
 #include "pitch.h"
 #include "sinusoids.h"
+#include "fftwrap.h"
 
 #define PCM_BUF_SIZE 2048
 
+#define SINUSOIDS 15
+
 GhostEncState *ghost_encoder_state_new(int sampling_rate)
 {
    int i;
@@ -40,6 +43,7 @@
    st->overlap = 64;
    st->pcm_buf = calloc(PCM_BUF_SIZE,sizeof(float));
    st->window = calloc(st->length,sizeof(float));
+   st->big_window = calloc(PCM_BUF_SIZE,sizeof(float));
    st->syn_memory = calloc(st->overlap,sizeof(float));
    st->current_pcm = st->pcm_buf + PCM_BUF_SIZE - st->length;
    for (i=0;i<st->length;i++)
@@ -47,8 +51,11 @@
    for (i=0;i<st->overlap;i++)
    {
       st->window[i] = .5-.5*cos(M_PI*i/st->overlap);
-      st->window[st->length-i] = .5-.5*cos(M_PI*(i+1)/st->overlap);
+      st->window[st->length-i-1] = .5-.5*cos(M_PI*(i+1)/st->overlap);
    }
+   st->big_fft = spx_fft_init(PCM_BUF_SIZE);
+   for (i=0;i<PCM_BUF_SIZE;i++)
+      st->big_window[i] = .5-.5*cos(2*M_PI*(i+1)/PCM_BUF_SIZE);
    return st;
 }
 
@@ -69,28 +76,45 @@
       st->current_pcm[i+st->overlap]=pcm[i];
    find_pitch(st->current_pcm, &gain, &pitch, 100, 1024, st->length);
    //fprintf (stderr,"%f %f\n", pitch, gain);
-   pitch = 256;
+   //pitch = 256;
    w = 2*M_PI/pitch;
    {
-      float wi[45];
+      float wi[SINUSOIDS];
       float x[st->length];
       float y[st->length];
-      float ai[45], bi[45];
-      for (i=0;i<45;i++)
+      float ai[SINUSOIDS], bi[SINUSOIDS];
+      float psd[PCM_BUF_SIZE];
+      
+      for (i=0;i<SINUSOIDS;i++)
          wi[i] = w*(i+1);
+
+      spx_fft_float(st->big_fft, st->pcm_buf, psd);
+      for (i=1;i<(PCM_BUF_SIZE>>1);i++)
+      {
+         psd[i] = 10*log10(psd[2*i-1]*psd[2*i-1] + psd[2*i]*psd[2*i]);
+      }
+      psd[0] = 10*log10(psd[0]*psd[0]);
+      psd[(PCM_BUF_SIZE>>1)-1] = 10*log10(psd[PCM_BUF_SIZE-1]*psd[PCM_BUF_SIZE-1]);
+      find_sinusoids(psd, wi, SINUSOIDS, (PCM_BUF_SIZE>>1)+1);
+      /*for (i=0;i<SINUSOIDS;i++)
+      {
+         fprintf (stderr, "%f ", wi[i]);
+      }
+      fprintf (stderr, "\n");*/
       for (i=0;i<st->length;i++)
          x[i] = st->window[i]*st->current_pcm[i];
-      extract_sinusoids(x, wi, st->window, ai, bi, y, 20, st->length);
+      extract_sinusoids(x, wi, st->window, ai, bi, y, SINUSOIDS, st->length);
       /*for (i=0;i<st->length;i++)
       y[i] = x[i];*/
       short out[st->advance];
       for (i=0;i<st->overlap;i++)
-         out[i] = st->syn_memory[i]+y[i];
+         pcm[i] = st->syn_memory[i]+y[i];
       for (i=st->overlap;i<st->advance;i++)
-         out[i] = y[i];
+         pcm[i] = y[i];
       for (i=st->advance;i<st->length;i++)
          st->syn_memory[i-st->advance]=y[i];
-      fwrite(out, sizeof(short), st->advance, stdout);
+      //fwrite(out, sizeof(short), st->advance, stdout);
+      
    }
    
 }

Modified: trunk/ghost/libghost/ghost.h
===================================================================
--- trunk/ghost/libghost/ghost.h	2006-01-10 02:27:16 UTC (rev 10724)
+++ trunk/ghost/libghost/ghost.h	2006-01-10 03:55:51 UTC (rev 10725)
@@ -27,10 +27,12 @@
    float *pcm_buf;
    float *current_pcm;
    float *window;
+   float *big_window;
    float *syn_memory;
    int length;
    int advance;
    int overlap;
+   void *big_fft;
 } GhostEncState;
 
 GhostEncState *ghost_encoder_state_new(int sampling_rate);

Modified: trunk/ghost/libghost/sinusoids.c
===================================================================
--- trunk/ghost/libghost/sinusoids.c	2006-01-10 02:27:16 UTC (rev 10724)
+++ trunk/ghost/libghost/sinusoids.c	2006-01-10 03:55:51 UTC (rev 10725)
@@ -23,7 +23,52 @@
 
 #include <math.h>
 #include "sinusoids.h"
+#include <stdio.h>
 
+#define MIN(a,b) ((a)<(b) ? (a):(b))
+#define MAX(a,b) ((a)>(b) ? (a):(b))
+
+void find_sinusoids(float *psd, float *w, int N, int length)
+{
+   int i,j;
+   float sinusoidism[length];
+   float tmp_max;
+   int tmp_id;
+   sinusoidism[0] = sinusoidism[length-1] = -1;
+   sinusoidism[1] = sinusoidism[length-2] = -1;
+   for (i=2;i<length-2;i++)
+   {
+      if (psd[i] > psd[i-1] && psd[i] > psd[i+1])
+      {
+         float highlobe, lowlobe;
+         highlobe = psd[i]-MIN(psd[i+1], psd[i+2]);
+         lowlobe = psd[i]-MIN(psd[i-1], psd[i-2]);
+         sinusoidism[i] = psd[i] + .5*(highlobe + lowlobe - .5*MAX(lowlobe, highlobe));
+      } else {
+         sinusoidism[i] = -1;
+      }
+   }
+   /*for (i=0;i<=length;i++)
+   {
+      fprintf (stderr, "%f ", sinusoidism[i]);
+   }
+   fprintf (stderr, "\n");*/
+   for (i=0;i<N;i++)
+   {
+      tmp_max = -2;
+      for (j=0;j<length;j++)
+      {
+         if (sinusoidism[j]>tmp_max)
+         {
+            tmp_max = sinusoidism[j];
+            tmp_id = j;
+         }
+      }
+      sinusoidism[tmp_id] = -3;
+      w[i] = M_PI*tmp_id/(length-1);
+   }
+}
+
 void extract_sinusoids(float *x, float *w, float *window, float *ai, float *bi, float *y, int N, int len)
 {
    float cos_table[N][len];

Modified: trunk/ghost/libghost/sinusoids.h
===================================================================
--- trunk/ghost/libghost/sinusoids.h	2006-01-10 02:27:16 UTC (rev 10724)
+++ trunk/ghost/libghost/sinusoids.h	2006-01-10 03:55:51 UTC (rev 10725)
@@ -23,6 +23,8 @@
 #ifndef _SINUSOIDS_H
 #define _SINUSOIDS_H
 
+void find_sinusoids(float *psd, float *w, int N, int length);
+
 void extract_sinusoids(float *x, float *w, float *window, float *ai, float *bi, float *y, int N, int len);
 
 #endif

Modified: trunk/ghost/libghost/testghost.c
===================================================================
--- trunk/ghost/libghost/testghost.c	2006-01-10 02:27:16 UTC (rev 10724)
+++ trunk/ghost/libghost/testghost.c	2006-01-10 03:55:51 UTC (rev 10725)
@@ -37,10 +37,16 @@
 int main(int argc, char **argv)
 {
    GhostEncState *state;
-   FILE *fin;
+   FILE *fin, *fout;
    struct LiftingBasis bas;
    float x[1200];
    int i;
+   
+   if (argc != 3)
+   {
+      fprintf (stderr, "usage: testghost input_file output_file\nWhere the input and output are raw mono files sampled at 44.1 kHz or 48 kHz\n");
+      exit(1);
+   }
    /*float x[256];
    float y[256];
    float w[2] = {.05, .2};
@@ -79,7 +85,8 @@
    printf ("\n");
    return 0;
 #endif
-   fin = fopen("test.sw", "r");
+   fin = fopen(argv[1], "r");
+   fout = fopen(argv[2], "w");
    state = ghost_encoder_state_new(48000);
    while (1)
    {
@@ -94,7 +101,9 @@
       for (i=0;i<BLOCK_SIZE;i++)
          float_in[i] = short_in[i];
       ghost_encode(state, float_in);
-      
+      for (i=0;i<BLOCK_SIZE;i++)
+         short_in[i] = float_in[i];
+      fwrite(short_in, sizeof(short), BLOCK_SIZE, fout);
    }
    ghost_encoder_state_destroy(state);
    



More information about the commits mailing list