Alan W Blackfix warnings641b9686 years agoHistory
484 lines · 16.2 KB · C
RawDownload
/*************************************************************************//*                                                                       *//*                  Language Technologies Institute                      *//*                     Carnegie Mellon University                        *//*                        Copyright (c) 2001                             *//*                        All Rights Reserved.                           *//*                                                                       *//*  Permission is hereby granted, free of charge, to use and distribute  *//*  this software and its documentation without restriction, including   *//*  without limitation the rights to use, copy, modify, merge, publish,  *//*  distribute, sublicense, and/or sell copies of this work, and to      *//*  permit persons to whom this work is furnished to do so, subject to   *//*  the following conditions:                                            *//*   1. The code must retain the above copyright notice, this list of    *//*      conditions and the following disclaimer.                         *//*   2. Any modifications must be clearly marked as such.                *//*   3. Original authors' names are not deleted.                         *//*   4. The authors' names are not used to endorse or promote products   *//*      derived from this software without specific prior written        *//*      permission.                                                      *//*                                                                       *//*  CARNEGIE MELLON UNIVERSITY AND THE CONTRIBUTORS TO THIS WORK         *//*  DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING      *//*  ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT   *//*  SHALL CARNEGIE MELLON UNIVERSITY NOR THE CONTRIBUTORS BE LIABLE      *//*  FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES    *//*  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN   *//*  AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,          *//*  ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF       *//*  THIS SOFTWARE.                                                       *//*                                                                       *//*************************************************************************//*             Author:  Alan W Black (awb@cs.cmu.edu)                    *//*               Date:  June 2001                                        *//*************************************************************************//*                                                                       *//*  residuals etc                                                        *//*                                                                       *//*************************************************************************/#include <stdio.h>#include <math.h>#include <string.h> /* To allow some normally const fields to manipulated during building */#define const #include "cst_args.h"#include "cst_wave.h"#include "cst_track.h"#include "cst_sigpr.h" float lpc_min;float lpc_range;const char *residual_codec = "ulaw";cst_track *vuv; void inv_lpc_filterd(short *sig, float *a, int order, double *res, int size){    /* Note this address bytes before sig, up to order shorts back */    int i, j;    double r;     for (i = 0; i < size; i++)    {	r = sig[i];	for (j = 1; j < order; j++)	    r -= a[j] * (double)sig[i - j];	res[i] = r;    }} static int voiced_frame(cst_track *lpc,int i,cst_track *vuv){    int p;     p = lpc->times[i]/(vuv->times[1]-vuv->times[0]);        if (p < 2)  /* some reasonable edge conditions */        return 0; /* unvoiced */    else if (p+2 >= vuv->num_frames)        return 0; /* unvoiced */    else if (vuv->frames[p][0] == 1)        return 1; /* voiced */    else if ((vuv->frames[p-2][0] == 0) &&             (vuv->frames[p-1][0] == 0) &&             (vuv->frames[p+1][0] == 0) &&             (vuv->frames[p+2][0] == 0)             )        return 0; /* unvoiced */    else         return 1;} cst_sts *find_sts(cst_wave *sig, cst_track *lpc){    cst_sts *sts;    int i,j;    double *resd;    int size,start,end;    short *sigplus;    unsigned char *ulaw_res, *power;    int ipower;    float sump;    int packed_size;#if 0    unsigned char *residual_unpacked;    int frame_size;#endif     sts = cst_alloc(cst_sts,lpc->num_frames);    sigplus = cst_alloc(short,sig->num_samples+lpc->num_channels);    memset(sigplus,0,sizeof(short)*lpc->num_channels);    memmove(&sigplus[lpc->num_channels],	    sig->samples,	    sizeof(short)*sig->num_samples);    /* EST LPC Windows are centered around the point */    /* so offset things by a half period */    start = (int)((float)sig->sample_rate * lpc->times[0]/2);    for (i=0; i<lpc->num_frames; i++)    {	if (i+1 == lpc->num_frames)	    end = (int)((float)sig->sample_rate * lpc->times[i]);	else	    end = (int)((float)sig->sample_rate *			(lpc->times[i]+lpc->times[i+1]))/2;	size = end - start;	if (size == 0)	    printf("frame size at %f is 0\n",lpc->times[i]);	resd = cst_alloc(double,size);		inv_lpc_filterd(&sigplus[start+lpc->num_channels],			lpc->frames[i],lpc->num_channels,			resd,			size);	sts[i].size = size;	sts[i].frame = cst_alloc(unsigned short,lpc->num_channels-1);	for (j=1; j < lpc->num_channels; j++)	    sts[i].frame[j-1] = (unsigned short)		(((lpc->frames[i][j]-lpc_min)/lpc_range)*65535);        if (cst_streq(residual_codec,"ulaw"))        {            sts[i].residual = cst_alloc(unsigned char,size);            for (j=0; j < size; j++)                sts[i].residual[j] = cst_short_to_ulaw((short)resd[j]);        }        else if (cst_streq(residual_codec,"g721"))        {            ulaw_res = cst_alloc(unsigned char,size+CST_G721_LEADIN);            for (j=0; j < size+CST_G721_LEADIN; j++)                ulaw_res[j] = cst_short_to_ulaw((short)resd[j-CST_G721_LEADIN]);            sts[i].residual = cst_g721_encode(&packed_size,size+CST_G721_LEADIN,ulaw_res);            cst_free(ulaw_res);        }        else if (cst_streq(residual_codec,"g721vuv"))        {            sump = 0.0;            for (j=0; j < size; j++)                sump+=resd[j]*resd[j];            ipower = (int)sqrt(sump/size);            if (voiced_frame(lpc,i,vuv) || (ipower > 250))            {                ulaw_res = cst_alloc(unsigned char,size+CST_G721_LEADIN);                for (j=0; j < size+CST_G721_LEADIN; j++)                    ulaw_res[j] = cst_short_to_ulaw((short)resd[j-CST_G721_LEADIN]);                sts[i].residual = cst_g721_encode(&packed_size,size+CST_G721_LEADIN,ulaw_res);                cst_free(ulaw_res);            }             else /* Unvoiced frame */            {                power = cst_alloc(unsigned char,6);                power[0] = 0;                power[1] = (unsigned char)ipower%256;                ipower = ipower >> 8;                power[2] = (unsigned char)ipower%256;                ipower = ipower >> 8;                power[3] = (unsigned char)ipower%256;                ipower = ipower >> 8;                power[4] = (unsigned char)ipower%256;                sts[i].residual = power;            }        }        else if (cst_streq(residual_codec,"vuv"))        {            sump = 0.0;            for (j=0; j < size; j++)                sump+=resd[j]*resd[j];            ipower = (int)sqrt(sump/size);            if (voiced_frame(lpc,i,vuv) || ipower > 250)            {                sts[i].residual = cst_alloc(unsigned char,size);                for (j=0; j < size; j++)                    sts[i].residual[j] = cst_short_to_ulaw((short)resd[j]);            }             else /* Unvoiced frame */            {                sump = 0.0;                for (j=0; j < size; j++)                    sump+=resd[j]*resd[j];                power = cst_alloc(unsigned char,6);                power[0] = 0;                power[1] = (unsigned char)ipower%256;                ipower = ipower >> 8;                power[2] = (unsigned char)ipower%256;                ipower = ipower >> 8;                power[3] = (unsigned char)ipower%256;                ipower = ipower >> 8;                power[4] = (unsigned char)ipower%256;                sts[i].residual = power;            }        }        else        {            fprintf(stderr,"unknown codec \'%s\"\n",residual_codec);            exit(-1);        }	start = end;    }     cst_free(sigplus);    return sts;} static double plus_or_minus_one(){    /* Randomly return 1 or -1 */    /* not sure rand() is portable */    if (rand() > RAND_MAX/2.0)        return 1.0;    else        return -1.0;} static double rand_zero_to_one(){    /* Return number between 0.0 and 1.0 */    return rand()/(float)RAND_MAX;} cst_wave *reconstruct_wave(cst_wave *sig, cst_sts *sts, cst_track *lpc){    cst_lpcres *lpcres;    int i,j,r;    int start;    int num_samples;    unsigned char *residual_unpacked;    int frame_size;    int p;    float m, q;     FILE *ofd; int s;     for (num_samples = 0, i=0; i < lpc->num_frames; i++)        num_samples += sts[i].size;     lpcres = new_lpcres();    lpcres_resize_frames(lpcres,lpc->num_frames);    lpcres->num_channels = lpc->num_channels-1;    start = (int)((float)sig->sample_rate * lpc->times[0]/2);    num_samples += start;    for (i=0; i<lpc->num_frames; i++)    {	lpcres->frames[i] = sts[i].frame;        lpcres->sizes[i] = sts[i].size;    }    lpcres_resize_samples(lpcres,num_samples);    lpcres->lpc_min = lpc_min;    lpcres->lpc_range = lpc_range;    lpcres->sample_rate = sig->sample_rate;    for (r=start,i=0; i<lpc->num_frames; i++)    {        if (cst_streq(residual_codec,"g721"))        {            residual_unpacked =                 cst_g721_decode(&frame_size, (sts[i].size+CST_G721_LEADIN+1)/2, sts[i].residual);            for (j=0; j<sts[i].size; j++,r++)                lpcres->residual[r] = residual_unpacked[j+CST_G721_LEADIN];            cst_free(residual_unpacked);        }        else if (cst_streq(residual_codec,"g721vuv"))        {            if (sts[i].residual[0] == 0)            {                p = sts[i].residual[4]; p = p << 8;                p += sts[i].residual[3]; p = p << 8;                p += sts[i].residual[2]; p = p << 8;                p += sts[i].residual[1];                m = ((float)p);                for (j=0; j<sts[i].size; j++,r++)                {                    q = m*2*rand_zero_to_one()*plus_or_minus_one();                    lpcres->residual[r] = cst_short_to_ulaw((short)q);                }            }            else            {                residual_unpacked =                     cst_g721_decode(&frame_size, (sts[i].size+CST_G721_LEADIN+1)/2, sts[i].residual);                for (j=0; j<sts[i].size; j++,r++)                    lpcres->residual[r] = residual_unpacked[j+CST_G721_LEADIN];                cst_free(residual_unpacked);            }        }        else if (cst_streq(residual_codec,"vuv"))        {            if (sts[i].residual[0] == 0)            {                p = sts[i].residual[4]; p = p << 8;                p += sts[i].residual[3]; p = p << 8;                p += sts[i].residual[2]; p = p << 8;                p += sts[i].residual[1];                m = ((float)p);                for (j=0; j<sts[i].size; j++,r++)                {                    q = m*2*rand_zero_to_one()*plus_or_minus_one();                    lpcres->residual[r] = cst_short_to_ulaw((short)q);                }            }            else            {                for (j=0; j<sts[i].size; j++,r++)                    lpcres->residual[r] = sts[i].residual[j];            }        }        else /* ulaw */        {            for (j=0; j<sts[i].size; j++,r++)                lpcres->residual[r] = sts[i].residual[j];        }    } #if 1    /* Debug dump */    ofd = fopen("lpc_resid.lpc","w");    for (s=0,i=0; i<lpcres->num_frames; i++)    {	fprintf(ofd,"%d %d %d\n",i,0,lpcres->sizes[i]);	for (j=0; j < lpcres->num_channels; j++)	    fprintf(ofd,"%d ",lpcres->frames[i][j]);	fprintf(ofd,"\n");        fprintf(ofd,"%d ",32000); s++;	for (j=1; j < lpcres->sizes[i]; j++,s++)	    fprintf(ofd,"%d ",cst_ulaw_to_short(lpcres->residual[s]));	fprintf(ofd,"\n");    }    fclose(ofd);    ofd = fopen("lpc_resid.res","w");    for (i=0; i < r; i++)	fprintf(ofd,"%d\n",cst_ulaw_to_short(lpcres->residual[i]));    fclose(ofd);#endif     return lpc_resynth_fixedpoint(lpcres);} void compare_waves(cst_wave *a, cst_wave *b){    int i;    double r;     if (a->num_samples != b->num_samples)    {	if (a->num_samples > b->num_samples)	{	    compare_waves(b,a);	    return;	}    }        for (r=0.0,i=0; i<a->num_samples; i++)	r += ((float)a->samples[i]-(float)b->samples[i]) *	    ((float)a->samples[i]-(float)b->samples[i]);    r /= a->num_samples;    printf("a/b diff %f\n",sqrt(r));} void save_sts(cst_sts *sts, cst_track *lpc, cst_wave *sig, const char *fn){    FILE *fd;    int i,j;     if ((fd=fopen(fn,"w"))== NULL)    {	fprintf(stderr,"can't open for writing file: %s\n", fn);	exit(-1);    }     fprintf(fd,"( %d %d %d %f %f)\n", lpc->num_frames, 	    lpc->num_channels-1, sig->sample_rate,	    lpc_min, lpc_range);    for (i=0; i<lpc->num_frames; i++)    {	fprintf(fd,"( %f (",lpc->times[i]);	for (j=1; j < lpc->num_channels; j++)	    fprintf(fd," %d",sts[i].frame[j-1]);	fprintf(fd," ) %d ( ", sts[i].size);        if (cst_streq(residual_codec,"ulaw"))        {            for (j=0; j < sts[i].size; j++)                fprintf(fd," %d",sts[i].residual[j]);        }        else if (cst_streq(residual_codec,"g721"))        {            for (j=0; j < (sts[i].size+CST_G721_LEADIN+1)/2; j++)                fprintf(fd," %d",sts[i].residual[j]);        }        else if (cst_streq(residual_codec,"g721vuv"))        {            if (sts[i].residual[0] == 0)                for (j=0; j < 5; j++)                    fprintf(fd," %d",sts[i].residual[j]);            else                for (j=0; j < (sts[i].size+CST_G721_LEADIN+1)/2; j++)                    fprintf(fd," %d",sts[i].residual[j]);        }        else if (cst_streq(residual_codec,"vuv"))        {            if (sts[i].residual[0] == 0)                for (j=0; j < 5; j++)                    fprintf(fd," %d",sts[i].residual[j]);            else                for (j=0; j < sts[i].size; j++)                    fprintf(fd," %d",sts[i].residual[j]);        }	fprintf(fd," ))\n");    }        fclose(fd);} int main(int argc, char **argv){    cst_track *lpc;    cst_wave *sig, *sig2;    cst_sts *sts;    cst_features *args;     args = new_features();    cst_args(argv,argc,             "usage: find_sts OPTIONS\n"             "Find sts from lpc and waveform\n"             "-codec <string>    ulaw (default), g721, g721vuv, vuv\n"             "-vuv <string>      v/uv track (for some codecs)\n"             "-lpcmin <float>    minimum LPC value\n"             "-lpcrange <float>  range of LPC values\n"             "-lpc <string>      LPC track file\n"             "-wave <string>     WAVE file\n"             "-o <string>        STS output file\n",             args);     lpc_min = get_param_float(args,"-lpcmin",-10.0);    lpc_range = get_param_float(args,"-lpcrange",20.0);    residual_codec = get_param_string(args,"-codec","ulaw");     if (feat_present(args,"-vuv"))    {        /* Fixed frame track of voiced (1) unvoived (0) information */        vuv = new_track();        cst_track_load_est(vuv,get_param_string(args,"-vuv","file.vuv"));    }     lpc = new_track();    cst_track_load_est(lpc,get_param_string(args,"-lpc","file.lpc"));    sig = new_wave();    if (cst_wave_load_riff(sig,get_param_string(args,"-wave","file.wav"))         == CST_WRONG_FORMAT)    {	fprintf(stderr,		"cannot load waveform, format unrecognized, from \"%s\"\n",                get_param_string(args,"-wave","file.wav"));	exit(-1);    }     sts = find_sts(sig,lpc);     /* See if it worked */    sig2 = reconstruct_wave(sig,sts,lpc);     compare_waves(sig,sig2);    cst_wave_save_riff(sig2,"sig2.wav");     save_sts(sts,lpc,sig,get_param_string(args,"-o","file.sts"));     return 0;}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t