/* Simple Zero-Crossing-based vowel/consonant detection program by Perry R. Cook, Princeton U, 2004 Takes a wavefile, and determines vowel/consonant. Also synthesizes two files, vowels.wav and conson.wav, which contain the respective blocks. This version is integer, no-multiply version. */ #include #include #include #include #include /* These thresholds are set up for 8K sample rate, 400 sample buffers */ #define POWERTHRESH 20000 #define VOWELTHRESH 100 int zerocrossings(long size,short *data); int getfakepower(long size,short *data); #include "waveio.h" // return true if numbers are within 3% of each other int zbout(float num1, float num2) { if (fabs(num1-num2)/num1 < 0.05) return 1; else return 0; } int main(int argc,char *argv[]) { struct soundhdr hdr; short *short_data,vout,cout; FILE *fd,*fdvout,*fdcout; long i,n_read,time=0,block=0; long block_size,hop_size; float zeroes = 0; int vowel; float pitch,power=0,blocktime=0.05,hoptime=-1,sgain; float pitch1=0,pitch2=0; if (argc>1) { fd = opensoundin(argv[1],&hdr); if (fd) { #ifdef LITTLENDIAN fdvout = opensoundout("vowels.wav",&hdr); fdcout = opensoundout("conson.wav",&hdr); #else fdvout = opensoundout("vowels.snd",&hdr); fdcout = opensoundout("conson.snd",&hdr); #endif if (argc>2) { i = 2; while (i < argc) { if (argv[i][0]=='-') { if (argv[i][1]=='b') { blocktime = atof(argv[i+1]); printf("setting blocktime to: %f\n",blocktime); // i += 1; } else if (argv[i][1]=='h') { hoptime = atof(argv[i+1]); printf("setting hoptime to: %f\n",hoptime); // i += 1; } else printf("I don't understand this switch: %s\n",argv[i+1]); } i += 1; } } block_size = blocktime * hdr.srate; if (hoptime < 0) hop_size = block_size / 2; else hop_size = hoptime * hdr.srate; if (hop_size >= block_size) { hop_size = block_size; printf("Setting hop_size = block_size\n"); } short_data = (short *) malloc(block_size*2); n_read = fread(short_data,2,block_size,fd); while (n_read>0) { zeroes = zerocrossings(block_size,short_data); power = getfakepower(block_size,short_data); printf("%.3f ",time / (float) hdr.srate); if (power > POWERTHRESH) { if (zeroes < VOWELTHRESH) { printf("Voiced "); vowel = 1; } else { printf("Unvoiced "); vowel = 0; } } else { vowel = -1; printf("Silence "); pitch = 0.0; } printf("%.3f %.3f\n",power, zeroes); for (i=0;i <-h hopTime> \n"); printf(" blockTime default is 0.05 seconds\n"); printf(" hopTime default is blockTime/2 (must be <= blockTime)\n"); exit(0); } return 1; } int zerocrossings(long size,short *data) { long i; float numzeroes = 0.0; for (i=0;i 0) numzeroes += 1; if (data[i] > 0) if ( data[i+1] < 0) numzeroes += 1; } return numzeroes; } int getfakepower(long size,short *data) { long i; float power = 0.0; for (i=0;i