| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336 |
- /*************************************************************************/
- /* */
- /* 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 "cst_wave.h"
- #include "cst_track.h"
- #include "cst_sigpr.h"
- void inv_lpc_filterd(short *sig, float *a, int order, double *res, int size)
- {
- int i, j;
- double r;
- for (i = 0; i < order; i++)
- {
- r = sig[i];
- for (j = 1; j < order; j++)
- /* if (i-j >= 0) */
- r -= a[j] * (double)sig[i - j];
- res[i] = r;
- }
- for (i = order; i < size; i++)
- {
- r = sig[i];
- for (j = 1; j < order; j++)
- r -= a[j] * (double)sig[i - j];
- res[i] = r;
- }
- }
- cst_wave *find_residual(cst_wave *sig, cst_track *lpc)
- {
- cst_wave *res;
- int i;
- double *resd;
- int size,start,end;
- res = new_wave();
- cst_wave_resize(res,sig->num_samples,1);
- res->sample_rate = sig->sample_rate;
- resd = cst_alloc(double,sig->num_samples);
- start = lpc->num_channels;
- for (i=0; i<lpc->num_frames; i++)
- {
- end = (int)((float)sig->sample_rate * lpc->times[i]);
- size = end - start;
-
- inv_lpc_filterd(&sig->samples[start],lpc->frames[i],lpc->num_channels,
- &resd[start],size);
-
- start = end;
- }
- for (i=0; i<res->num_samples; i++)
- res->samples[i] = resd[i];
- cst_free(resd);
- return res;
- }
- void lpc_filterd(short *res, float *a, int order, double *sig, int size)
- {
- int i, j;
- double r;
- for (i = 0; i < order; i++)
- {
- r = res[i];
- for (j = 1; j < order; j++)
- /* if (i-j >= 0) */
- r += a[j] * (double)sig[i - j];
- sig[i] = r;
- }
- for (i = order; i < size; i++)
- {
- r = res[i];
- for (j = 1; j < order; j++)
- r += a[j] * (double)sig[i - j];
- sig[i] = r;
- }
- }
- cst_wave *reconstruct_wave(cst_wave *res, cst_track *lpc)
- {
- cst_wave *sig;
- int i;
- double *sigd;
- int start, end, size;
- sig = new_wave();
- cst_wave_resize(sig,res->num_samples,1);
- sig->sample_rate = res->sample_rate;
- sigd = cst_alloc(double,sig->num_samples);
- start = 0;
- for (i=0; i<lpc->num_frames; i++)
- {
- end = (int)((float)sig->sample_rate * lpc->times[i]);
- size = end - start;
-
- lpc_filterd(&res->samples[start],
- lpc->frames[i],lpc->num_channels,
- &sigd[start],size);
-
- start = end;
- }
- for (i=0; i<sig->num_samples; i++)
- sig->samples[i] = sigd[i];
- cst_free(sigd);
- return sig;
- }
- float lpc_min = -2.709040;
- float lpc_range = 2.328840+2.709040;
- void lpc_filterde(unsigned char *resulaw,
- unsigned short *as, int order,
- short *sig,
- int size)
- {
- int i, j;
- float r;
- float *a;
- float *sigf;
-
- a = cst_alloc(float,order);
- for (i=1; i<order; i++)
- a[i] = (((float)as[i]/65535.0)*lpc_range)+lpc_min;
- sigf = cst_alloc(float,size);
- for (i=0; i<size; i++)
- sigf[i] = sig[i];
- for (i = 0; i < order; i++)
- {
- r = cst_ulaw_to_short(resulaw[i]);
- for (j = 1; j < order; j++)
- /* if (i-j >= 0) */
- r += a[j] * (float)sigf[i - j];
- sigf[i] = r;
- }
- for (i = order; i < size; i++)
- {
- r = cst_ulaw_to_short(resulaw[i]);
- for (j = 1; j < order; j++)
- r += a[j] * (float)sigf[i - j];
- sigf[i] = r;
- }
- for (i=0; i<size; i++)
- sig[i] = sigf[i];
-
- cst_free(sigf);
- /* cst_free(a); */
- }
- cst_wave *reconstruct_wavee(cst_wave *res, cst_track *lpc)
- {
- cst_wave *sig;
- int i,j;
- short *sigd;
- int start, end, size;
- unsigned short *as;
- unsigned char *resulaw;
- sig = new_wave();
- cst_wave_resize(sig,res->num_samples,1);
- sig->sample_rate = res->sample_rate;
- sigd = cst_alloc(short,sig->num_samples);
- as = cst_alloc(unsigned short,lpc->num_channels);
- resulaw = cst_alloc(unsigned char, res->num_samples);
- for (i=0; i<res->num_samples; i++)
- resulaw[i] = cst_short_to_ulaw(res->samples[i]);
-
- start = 0;
- for (i=0; i<lpc->num_frames; i++)
- {
- end = (int)((float)sig->sample_rate * lpc->times[i]);
- size = end - start;
- for (j=1; j<lpc->num_channels; j++)
- as[j] = (((lpc->frames[i][j]-lpc_min)/lpc_range)*65535.0);
-
- lpc_filterde(&resulaw[start],
- as,lpc->num_channels,
- &sigd[start],size);
-
- start = end;
- }
- for (i=0; i<sig->num_samples; i++)
- sig->samples[i] = sigd[i];
- cst_free(sigd);
- return sig;
- }
- cst_wave *dumdum(cst_wave *res,cst_track *lpc)
- {
- cst_lpcres *lpcres;
- int i,j,s;
- unsigned short *bbb;
- int start,end,size;
- FILE *ofd;
- lpcres = new_lpcres();
- lpcres_resize_frames(lpcres,lpc->num_frames);
- lpcres->num_channels = lpc->num_channels-1;
- start = 0;
- for (i=0; i<lpc->num_frames; i++)
- {
- bbb = cst_alloc(unsigned short,lpc->num_channels-1);
- for (j=1; j<lpc->num_channels; j++)
- bbb[j-1] = (unsigned short)
- (((lpc->frames[i][j]-lpc_min)/lpc_range)*65535);
- lpcres->frames[i] = bbb;
- end = lpc->times[i]*res->sample_rate;
- lpcres->times[i] = lpc->times[i];
- size = end - start;
- lpcres->sizes[i] = size;
- start = end;
- }
- lpcres_resize_samples(lpcres,res->num_samples);
- lpcres->lpc_min = lpc_min;
- lpcres->lpc_range = lpc_range;
- lpcres->sample_rate = res->sample_rate;
- for (i=0; i<res->num_samples; i++)
- lpcres->residual[i] = cst_short_to_ulaw(res->samples[i]);
- ofd = fopen("lpc1.lpc","w");
- for (s=0,i=0; i<lpcres->num_frames; i++)
- {
- fprintf(ofd,"%d %d %d\n",i,lpcres->times[i],lpcres->sizes[i]);
- for (j=0; j < lpcres->num_channels; j++)
- fprintf(ofd,"%d ",lpcres->frames[i][j]);
- fprintf(ofd,"\n");
- for (j=0; j < lpcres->sizes[i]; j++,s++)
- fprintf(ofd,"%d ",lpcres->residual[s]);
- fprintf(ofd,"\n");
- }
- fclose(ofd);
-
- return lpc_resynth(lpcres);
- }
- int main(int argc, char **argv)
- {
- /* need that cool argument parser */
- cst_wave *w,*res,*sig,*w2, *w3;
- cst_track *lpc;
- int i;
- double r;
- if (argc != 3)
- {
- fprintf(stderr,"usage: lpc_test2 LPC WAVEFILE\n");
- return 1;
- }
- lpc = new_track();
- cst_track_load_est(lpc,argv[1]);
- sig = new_wave();
- cst_wave_load_riff(sig,argv[2]);
- res = find_residual(sig,lpc);
-
- w = reconstruct_wave(res,lpc);
- cst_wave_save_riff(res,"res.wav");
- cst_wave_save_riff(w,"new.wav");
- w2 = reconstruct_wavee(res,lpc);
- cst_wave_save_riff(w2,"newe.wav");
- w3 = dumdum(res,lpc);
- cst_wave_save_riff(w3,"newr.wav");
- for (r=0.0,i=0; i<sig->num_samples; i++)
- r += ((float)sig->samples[i]-(float)w->samples[i]) *
- ((float)sig->samples[i]-(float)w->samples[i]);
- r /= sig->num_samples;
- printf("orig/new %f\n",sqrt(r));
- for (r=0.0,i=0; i<sig->num_samples; i++)
- r += ((float)sig->samples[i]-(float)w2->samples[i]) *
- ((float)sig->samples[i]-(float)w2->samples[i]);
- r /= sig->num_samples;
- printf("orig/newe %f\n",sqrt(r));
- for (r=0.0,i=0; i<sig->num_samples; i++)
- r += ((float)sig->samples[i]-(float)w3->samples[i]) *
- ((float)sig->samples[i]-(float)w3->samples[i]);
- r /= sig->num_samples;
- printf("orig/newr %f\n",sqrt(r));
- return 0;
- }
|