[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