The Easiest Way to Save and Share Code Snippets on the web

libxtract example

c | by: jamiebullock

posted: Aug, 28th 2009 | jump to bottom

/*
 * Basic illustration of using libxtract to obtain fundamental frequency and 
 * spectral centroid from a WAV file
 *
 * Path to a soundfile is given as a first argument to the program
 *
 * To compile with gcc use something like:
 *
 *      gcc libxtract_example.c -o libxtract_example -l sndfile -l xtract
 *
 * Copyright Jamie Bullock (August 2009)
 * License: GPL v2
 *
 * 
 */
 
#include <stdio.h>
#include <sndfile.h>
#include <math.h>
 
#include "xtract/libxtract.h"
 
#define BUFFSIZE 1024
 
/* hanning window function. in future versions of libxtract, this will be in the library */
void apply_hann(float *data, const int N);
 
int main(int argc, char **argv){
 
    SNDFILE *sndfile;
    SF_INFO sf_info;
    sf_count_t count;
    char *filename;
    float data[BUFFSIZE],
          result[BUFFSIZE],
          argf[4],
          f0 = 0.f;
    int rv,
        samplerate,
        i = 0;
 
    /* get input arg */
    if(argc > 1){
        filename = argv[1];
    }
    else {
        printf("No arguments given please supply a path to a soundfile\n");
        return 0;
    }
 
    /* try to open the soundfile */
    if(!(sndfile = sf_open(filename, SFM_READ, &sf_info))){
        printf("Error opening input file %s.\n", filename);
        sf_perror(NULL);
        return 1;
    }
 
    /* blockwise iteration over our soundfile data */
    while((count = sf_read_float(sndfile, data, BUFFSIZE))){
 
        /* get the samplerate for later */
        samplerate = sf_info.samplerate;
 
        /* get F0 from time domain signal */
        argf[0] = (float)samplerate;
        xtract[XTRACT_FAILSAFE_F0](data, BUFFSIZE, argf, &f0);
 
        /* apply a hann window*/
        apply_hann(data, BUFFSIZE);
 
        /* get the magnitude spectrum */
        argf[0] = (float)samplerate / (float)BUFFSIZE;
        argf[1] = (float)XTRACT_MAGNITUDE_SPECTRUM;
        argf[0] = 0.f; /* no DC component in the result */
 
        xtract[XTRACT_SPECTRUM](data, BUFFSIZE, argf, result);
 
        /* get the centroid: result from xtract_spectrum() becomes the
         * input data for xtract_spectral_centroid() */
        xtract[XTRACT_SPECTRAL_CENTROID](result, BUFFSIZE, argf, &data[0]); 
 
        /* print the results */
        printf("frame %d: centroid=%f\tf0=%f\n",i, data[0], f0);
 
        i++;
    }
 
    sf_close(sndfile);
 
    return 0;
 
}
 
void apply_hann(float *data, const int N){
 
    int n;
    const float M = N - 1;
 
    /* normally we would pre-compute this, but we don't need efficiency here */
    for (n = 0; n < N; n++)
        data[n] *= 0.5 * (1.0 - cosf(2.0 * M_PI * (float)n / M));
 
    return;
 
}
 
54 views