int quick_sort_partition(int a[], int start, int end) { int p = random_selector(a, start, end); int temp; temp = a[p]; a[p] = a[end]; a[end] = temp; p = end; int j = start; // all elements whose index < j are < a[p] while(a[j] < a[p] && j <= end) j++; int i; for(i = end - 1; i >= j; i--) { if(a[i] < a[p]) { // put a[i] at a[j] temp = a[j]; a[j] = a[i]; a[i] = temp; j++; while(a[j] < a[p] && j <= i) j++; } } temp = a[j]; a[j] = a[end]; a[end] = temp; return j; }
int main (int argc, const char * argv[]) { // choose which zero of autocorrelation should be set as delay parameter int delay_choice =2; int embed_dimension =3; int num_neighbours = 15; long num_of_points_retained=500; int percentile =70; long output_len=2*(((float)percentile)/100)*num_of_points_retained; printf("%ld output_len =",output_len); float *output = malloc(output_len* sizeof(float)); printf("Density based subsampling running \n"); if (argc != 2) { fprintf(stderr, "Expecting wav file as argument\n"); return 1; } // Open sound file that comes in as a command line argument SF_INFO sndInfo; SNDFILE *sndFile = sf_open(argv[1], SFM_READ, &sndInfo); if (sndFile == NULL) { fprintf(stderr, "Error reading source file '%s': %s\n", argv[1], sf_strerror(sndFile)); return 1; } // Check format - 16bit PCM if (sndInfo.format != (SF_FORMAT_WAV | SF_FORMAT_PCM_16)) { fprintf(stderr, "Input should be 16bit Wav\n"); sf_close(sndFile); return 1; } // Now we know the length of the wav file, we can create a buffer for it, in this case, we are creating a double array. // Allocate memory float *buffer = malloc(sndInfo.frames * sizeof(float)* sndInfo.channels); if (buffer == NULL) { fprintf(stderr, "Could not allocate memory for data\n"); sf_close(sndFile); return 1; } // This next step, actually reads in the wav file data. This function automatically converts the whichever format the audio file data is in to doubles. The library can convert to a number of different formats. // Load data long numFrames = sf_readf_float(sndFile, buffer, sndInfo.frames); // Check correct number of samples loaded if (numFrames != sndInfo.frames) { fprintf(stderr, "Did not read enough samples for source\n"); sf_close(sndFile); free(buffer); return 1; } // Now just output some info about the wav file printf("Read %ld samples from %s, Sample rate: %d, Length: %fs\n", numFrames, argv[1], sndInfo.samplerate, (float)numFrames/sndInfo.samplerate); // extract a single channel out float *buffer_singlechannel = malloc(sndInfo.frames * sizeof(float)); long i=0; for (long f=0 ; f<numFrames ; f++) { buffer_singlechannel[f]= buffer[i]; // Channel 1 i+=sndInfo.channels; } // free the buffer with multiple channel input free(buffer); // array to store the autocorrelation function double *buffer_autocorrelation = malloc((2*sndInfo.frames +1)* sizeof(double)); // calculate autocorrelation xcorr( buffer_singlechannel, buffer_singlechannel, buffer_autocorrelation, sndInfo.frames, 0,sndInfo.frames, 1, 1, sndInfo.frames,sndInfo.frames, sndInfo.frames, sndInfo.frames); // choose delay to be second zero of auto correlation long long delay = zeroCrossing(buffer_autocorrelation, 2*sndInfo.frames +1, delay_choice); printf("Delay chosen = %lld\n",delay); long long delay_embd_length= (sndInfo.frames -(delay*embed_dimension)+2)* embed_dimension; //create delay embedding and store in a linear array in row major form float *buffer_delayembedding =malloc(delay_embd_length*sizeof(float)); long long k1=0; for (long long l=(delay*embed_dimension)-2; l<sndInfo.frames; l=l+1) { buffer_delayembedding[k1]=buffer_singlechannel[l]; buffer_delayembedding[k1+1]=buffer_singlechannel[l-delay]; buffer_delayembedding[k1+2]=buffer_singlechannel[l-2*delay]; // printf("%f %f %f\n", buffer_delayembedding[k1],buffer_delayembedding[k1+1],buffer_delayembedding[k1+2]); k1=k1+embed_dimension; } int *array =malloc(num_of_points_retained *sizeof(int)); random_selector( delay_embd_length/ embed_dimension ,num_of_points_retained , array); for (int i=0; i<num_of_points_retained; i++) { // printf("%d\n",array[i]); } float *buffer_delayembedding_selec =malloc(num_of_points_retained*embed_dimension*sizeof(float)); float * density_vals =malloc(num_of_points_retained* sizeof(float)); printf("total len = %lld\n ", delay_embd_length/3 ); printf("buffer len = %ld\n", num_of_points_retained*embed_dimension); printf("num_of_points_retained = %ld\n", num_of_points_retained); for (int i=0; i<num_of_points_retained; i=i+1) { int loc=(array[i]-1)*embed_dimension; // printf("i :%d loc=%d array[i]: %d \n",i, loc, array[i]); buffer_delayembedding_selec[3*i]=buffer_delayembedding[loc]; buffer_delayembedding_selec[3*i+1]=buffer_delayembedding[loc+1]; buffer_delayembedding_selec[3*i+2]=buffer_delayembedding[loc+2]; // printf("buffer selec [%d] = %f ", 3*i, buffer_delayembedding_selec[3*i]); // printf("[%d] = %f ", 3*i+1, buffer_delayembedding_selec[3*i+1]); // printf("[%d] = %f \n", 3*i+2, buffer_delayembedding_selec[3*i+2]); } // for (int i=0; i<delay_embd_length/ embed_dimension ; i++) // { // printf("% d th original :%f %f %f\n",i, buffer_delayembedding [3*i],buffer_delayembedding [3*i+1],buffer_delayembedding [3*i+2]); // } knn (buffer_delayembedding_selec, density_vals , (num_of_points_retained), num_neighbours); // free all arrays used till now except the single channel wave file and close the sndFile object sf_close(sndFile); //desnity based subsampling float * density_vals_temp =malloc(num_of_points_retained* sizeof(float)); memcpy(density_vals_temp,density_vals,num_of_points_retained* sizeof(float)); qsort(density_vals_temp, num_of_points_retained, sizeof(float), cmpfunc); float key=findNumber(100-percentile,density_vals_temp,500); // Function call and the print statement // printf(" \n %d percentile: %.4lf \n", percentile, key); printf(" \n the linear array output contains the subsampled point cloud \n"); //for (int kk=0; kk<num_of_points_retained; kk++) { // printf("%d index %f \n", kk,density_vals_temp[kk]); //} free(density_vals_temp); int counter2=0; for( int counter = 0 ; counter < num_of_points_retained; counter++) { if (density_vals[counter]>=key && counter2<output_len/2) { output[2*counter2]=buffer_delayembedding_selec[3*counter]; output[2*counter2+1]=buffer_delayembedding_selec[3*counter+1]; //printf("%d output %.4lf , %.4lf\n", counter2,output[2*counter2],output[2*counter2+1]); //printf("%d output %.4lf , %.4lf\n", counter,buffer_delayembedding_selec[3*counter],buffer_delayembedding_selec[3*counter+1]); counter2++; } } free(buffer_singlechannel); free(buffer_autocorrelation); free(buffer_delayembedding); free(array); free(buffer_delayembedding_selec); free(density_vals); printf("Density based subsampling End\n"); free(output); return 0; }