/* * parrot.c * Program to illustrate /dev/dsp device * Records several seconds of sound, then echoes it back. * Runs until Control-C is pressed. */ #include #include #include #include #include #include #include #include #include #include #include #include // Files must be 44100, 16bit wav files #define LENGTH 1 /* how many seconds of speech to store */ #define CUTOFF 441 /* how many seconds of speech to store */ #define RATE 44100 /* the sampling rate */ #define SIZE 16 /* sample size: 8 or 16 bits */ #define CHANNELS 1 /* 1 = mono 2 = stereo */ //#define RT_SAMPLE_LENGTH 1000 #define RT_SAMPLE_LENGTH (LENGTH*RATE*SIZE*CHANNELS/(8*CUTOFF)) #define NHALF RT_SAMPLE_LENGTH/2 #define ERR_THRESHOLD 10000 // Min power freq to accept a freq as local maximum #define FREQ_MAXDEV 0.20 //Percentage of freq desviaion to be recognized #define FREQ_ZERO 2000 #define FREQ_ZERO_MIN FREQ_ZERO-(FREQ_ZERO*FREQ_MAXDEV) #define FREQ_ZERO_MAX FREQ_ZERO+(FREQ_ZERO*FREQ_MAXDEV) #define FREQ_ONE 5000 #define FREQ_ONE_MIN FREQ_ONE-(FREQ_ONE*FREQ_MAXDEV) #define FREQ_ONE_MAX FREQ_ONE+(FREQ_ONE*FREQ_MAXDEV) #define FREQ_SEPARATION 7000 #define FREQ_SEPARATION_MIN FREQ_SEPARATION-(FREQ_SEPARATION*FREQ_MAXDEV) #define FREQ_SEPARATION_MAX FREQ_SEPARATION+(FREQ_SEPARATION*FREQ_MAXDEV) #define FREQ_NEWFILE 12000 #define FREQ_NEWFILE_MIN FREQ_NEWFILE-(FREQ_NEWFILE*FREQ_MAXDEV) #define FREQ_NEWFILE_MAX FREQ_NEWFILE+(FREQ_NEWFILE*FREQ_MAXDEV) #define ORIG_SAMPLERATE 44100 #define BANDWIDTH ORIG_SAMPLERATE/2 #define SCALE_PONDERATION (double)ORIG_SAMPLERATE/ (double)RT_SAMPLE_LENGTH #define MIN_COUNT_ACCEPT 2 /* this buffer holds the digitized audio */ unsigned char buf[LENGTH*RATE*SIZE*CHANNELS/(8*CUTOFF)]; int main(int argc, char *argv[]) { int fd; /* sound device file descriptor */ int arg; /* argument for ioctl calls */ int status; /* return status of system calls */ int v,m,i; double maxval,maxpos; double curpos,absval; double last_freq=0; int count_repeat=MIN_COUNT_ACCEPT; int in_value,in_value_2b; static double *in_data = NULL, *out_data = NULL; static fftw_plan plan; char tmp[50]; char aux_num[50]; int position=0; int final_value; //in_data input real data from wavfile in_data = (double *)fftw_malloc(RT_SAMPLE_LENGTH * sizeof(double)); //out_data where the output will reside out_data = (double *)fftw_malloc(RT_SAMPLE_LENGTH * sizeof(double)); // r to r fft plan = fftw_plan_r2r_1d(RT_SAMPLE_LENGTH, in_data, out_data, FFTW_R2HC, FFTW_FORWARD); //Vector that will hold the final binary number position =0; for (i = 0; i < 50 ; i++) tmp[i]=0; int stop=0; long double power_org=0; long double power_fft=0; int newtone=1; int file_out; file_out = open(argv[1], O_WRONLY|O_CREAT|O_TRUNC,00666); /* open sound device */ fd = open("/dev/dsp", O_RDONLY); if (fd < 0) { perror("open of /dev/dsp failed"); exit(1); } /* set sampling parameters */ arg = SIZE; /* sample size */ status = ioctl(fd, SOUND_PCM_WRITE_BITS, &arg); if (status == -1) perror("SOUND_PCM_WRITE_BITS ioctl failed"); if (arg != SIZE) perror("unable to set sample size"); arg = CHANNELS; /* mono or stereo */ status = ioctl(fd, SOUND_PCM_WRITE_CHANNELS, &arg); if (status == -1) perror("SOUND_PCM_WRITE_CHANNELS ioctl failed"); if (arg != CHANNELS) perror("unable to set number of channels"); arg = RATE; /* sampling rate */ status = ioctl(fd, SOUND_PCM_WRITE_RATE, &arg); if (status == -1) perror("SOUND_PCM_WRITE_WRITE ioctl failed"); int point=0; while (1) { /* loop until Control-C */ status = read(fd, buf, sizeof(buf)); /* record some sound */ if (status != sizeof(buf)) perror("read wrong number of bytes"); point=0; for (v=0;v 127) { // printf ("invalue_2b:%d, neu:%d\n",in_value_2b,in_value_2b - 255); in_value_2b = (int)in_value_2b - 255; } int vo=256*in_value_2b +in_value; in_data[v] =(double)( 256*(int)in_value_2b + (int)in_value); // printf ("v: %d %g %d\n",256*in_value_2b + in_value,in_data[v],vo); // printf ("in: %d",in_data[v]); //power_org=power_org+pow(in_data[v],2); } //printf ("POWER ORIG: %d \n",power_org); fftw_execute(plan); m = 0; maxval=0; maxpos=0; for (i = 0; i < (RT_SAMPLE_LENGTH-2); i++) { //absval = sqrt(pow(in_data[i],2) + pow(out_data[i],2)); //absval = sqrt(pow(out_data[i],2) + pow(out_data[i],2)); absval = sqrt(out_data[i] * out_data[i]); //power_fft = power_fft + pow ( absval, 2); curpos = (double)m * SCALE_PONDERATION; if (absval>maxval && curpos < BANDWIDTH){ maxval=absval; maxpos=curpos; } m++; } //printf ("POWERFFT: %d \n",maxval); if (maxval>ERR_THRESHOLD) { //printf ("Maximum at freq:%f, %f\n",maxpos,maxval); if (newtone==0) { if ( maxpos > FREQ_ONE_MIN && maxpos < FREQ_ONE_MAX ) { if (last_freq != FREQ_ONE ) { count_repeat--; if (count_repeat == 0 ) { count_repeat = MIN_COUNT_ACCEPT; last_freq = FREQ_ONE; tmp[position]=1; position++; // printf ("ONE\n"); } } } if ( maxpos > FREQ_ZERO_MIN && maxpos < FREQ_ZERO_MAX ) { if (last_freq != FREQ_ZERO ) { count_repeat--; if (count_repeat == 0 ) { count_repeat = MIN_COUNT_ACCEPT; last_freq = FREQ_ZERO; //printf ("ZERO\n"); tmp[position]=0; position++; } } } if ( maxpos > FREQ_SEPARATION_MIN && maxpos < FREQ_SEPARATION_MAX ) { if (last_freq != FREQ_SEPARATION ){ count_repeat--; if (count_repeat == 0 ) { count_repeat = MIN_COUNT_ACCEPT; last_freq = FREQ_SEPARATION; //printf ("SEPARATION\n"); } } } } if ( maxpos > FREQ_NEWFILE_MIN && maxpos < FREQ_NEWFILE_MAX ) { if (last_freq != FREQ_NEWFILE ){ count_repeat--; if (count_repeat == 0 ) { //Final nou fitxer if (newtone==0) { stop=1; newtone=1; } count_repeat = MIN_COUNT_ACCEPT; last_freq = FREQ_NEWFILE; newtone--; printf ("NEWFILE\n"); } } } if (stop==1) { final_value=0; for (i=0;i