// file: calculate_snr.cc // // this is the driver program that calculates the signal-to-noise ratio // of a raw speech file // // system include files // #include #include #include // local include files // #include "global_constants.h" #include "calculate_snr_constants.h" #include "calculate_snr.h" // main program // main (int argc, char** argv) { // declare various parameters for snr calculation // char* datafile = new char [MAX_STRING_LENGTH]; float frame_size = CSNR_DEFAULT_FRAME_SIZE; float window_size = CSNR_DEFAULT_WINDOW_SIZE; float sample_freq = CSNR_DEFAULT_SAMPLE_FREQ; int num_chans = CSNR_DEFAULT_NUM_CHANS; float noise_threshold = CSNR_DEFAULT_NOISE_THRESHOLD; float signal_threshold = CSNR_DEFAULT_SIGNAL_THRESHOLD; int debug_mode = CSNR_DEFAULT_DEBUG_MODE; // get the command line arguments // if (get_parameters_cc(datafile, frame_size, window_size, sample_freq, num_chans, noise_threshold, signal_threshold, debug_mode, argv, argc) != TRUE) { fprintf(stdout, "Error in command line arguments\n"); return ERROR; } if (check_parameters_cc(datafile, frame_size, window_size, sample_freq, num_chans, noise_threshold, signal_threshold, debug_mode) != TRUE) { fprintf(stdout, "Invalid parameter value\n"); return ERROR; } // calculate the number of samples per window and per frame // int samples_per_frame = calculate_num_samples_cc (frame_size, sample_freq); int samples_per_win = calculate_num_samples_cc (window_size, sample_freq); // calculate the number of frames in a file // int total_frames = calculate_num_frames_cc(datafile, samples_per_frame, num_chans); if (total_frames == 0) { fprintf(stdout, "total_frames is 0\n"); return ERROR; } // start and end sample of a window // int offset_samples = int( rint((samples_per_win - samples_per_frame) / 2) ); int start_sample = -offset_samples * num_chans; int end_sample = (samples_per_frame + offset_samples) * num_chans; // end sample in a file // int end_file_sample = calculate_end_sample_cc(datafile, sample_freq, num_chans); if (debug_mode > DEBUG_FULL) { fprintf(stdout, "number of samples per frame: %d\n", samples_per_frame); fprintf(stdout, "number of samples per window: %d\n", samples_per_win); fprintf(stdout, "total number of frames in the signal file: %d\n", total_frames); fprintf(stdout, "end file sample: %d\n", end_file_sample); fprintf(stdout, "\n"); } // declare and initialize buffer to hold a window of the signal // int num_samples = num_chans * samples_per_win; float* signal_window = new float[num_samples]; float* pre_emphasized_window = new float[num_samples]; float* hamming_window = new float[num_samples]; memset(signal_window, 0, sizeof(float) * num_samples); memset(pre_emphasized_window, 0, sizeof(float) * num_samples); memset(hamming_window, 0, sizeof(float) * num_samples); // declare and initialize buffer to hold the energy of a windowed signal // float* energy_window = new float[num_chans]; memset(energy_window, 0, sizeof(float) * num_chans); // declare a buffer to hold the energy of the entire signal // float** energy_buffer = new float* [num_chans]; for (int j = 0; j < num_chans; j++) { energy_buffer[j] = new float[total_frames + CSNR_NUM_PADS]; memset(energy_buffer[j], 0, sizeof(float) * total_frames); } int num_energy = 0; // previous value of a frame // float* signal_prev_frame = new float[num_chans]; memset(signal_prev_frame, 0, sizeof(float) * num_chans); // read in the signal frame by frame until end of file // while (read_signal_cc(signal_window, num_chans, start_sample, end_sample, end_file_sample, datafile, debug_mode) == TRUE) { pre_emphasize_signal_cc(pre_emphasized_window, signal_window, samples_per_win, num_chans, signal_prev_frame, debug_mode); hamming_window_signal_cc(hamming_window, pre_emphasized_window, samples_per_win, num_chans, debug_mode); calculate_energy_cc(energy_window, hamming_window, samples_per_win, num_chans, debug_mode); add_energy_cc(energy_buffer, num_energy, energy_window, num_chans, debug_mode); // increment to next frame // start_sample += samples_per_frame * num_chans; end_sample += samples_per_frame * num_chans; } if (num_energy*num_chans != total_frames) { fprintf (stdout, "number of energy [%d] does not equal total number of frames [%d]\n", num_energy*num_chans, total_frames); } if (debug_mode > DEBUG_BRIEF) { for (int i = 0; i < num_chans; i++) { for (int j = 0; j < num_energy; j++) { fprintf(stdout, "chan %d :: energy for frame %d = %.2f\n", i, j, energy_buffer[i][j]); } } fprintf(stdout, "\n"); } // allocate space for pdf and cdf computation // float** bin_avgs = new float*[num_chans]; int** bin_freqs = new int*[num_chans]; float** pdf = new float*[num_chans]; float** cdf = new float*[num_chans]; for (int i = 0; i < num_chans; i++) { bin_avgs[i] = new float[CSNR_NUM_BINS]; bin_freqs[i] = new int[CSNR_NUM_BINS]; pdf[i] = new float[CSNR_NUM_BINS]; cdf[i] = new float[CSNR_NUM_BINS]; memset(bin_avgs[i], 0, sizeof(float) * CSNR_NUM_BINS); memset(bin_freqs[i], 0, sizeof(int) * CSNR_NUM_BINS); memset(pdf[i], 0, sizeof(float) * CSNR_NUM_BINS); memset(cdf[i], 0, sizeof(float) * CSNR_NUM_BINS); } // compute the histogram of the energy of the signal of each channel // calculate_hist_cc(bin_avgs, bin_freqs, energy_buffer, num_energy, num_chans, debug_mode); // compute the pdf of each channel // calculate_pdf_cc (pdf, bin_freqs, num_energy, num_chans, debug_mode); // compute the cdf of each channel // calculate_cdf_cc (cdf, pdf, num_chans, debug_mode); // compute the snr value for each channel // float* snr_values = new float[num_chans]; // compute the snr for each channel // calculate_snr_cc(snr_values, cdf, bin_avgs, num_chans, noise_threshold, signal_threshold, debug_mode); // output the snr values for each channel // print_buffer_cc(snr_values, num_chans); // free up space // if (datafile != (char*)NULL) { delete [] datafile; datafile = (char*)NULL; } if (signal_window != (float*)NULL) { delete [] signal_window; signal_window = (float*)NULL; } if (pre_emphasized_window != (float*)NULL) { delete [] pre_emphasized_window; pre_emphasized_window = (float*)NULL; } if (hamming_window != (float*)NULL) { delete [] hamming_window; hamming_window = (float*)NULL; } if (energy_window != (float*)NULL) { delete [] energy_window; energy_window = (float*)NULL; } if (energy_buffer != (float**)NULL) { for (int i = 0; i < num_chans; i++) { if (energy_buffer[i] != (float*)NULL) { delete [] energy_buffer[i]; energy_buffer[i] = (float*)NULL; } } delete [] energy_buffer; energy_buffer = (float**)NULL; } if (signal_prev_frame != (float*)NULL) { delete [] signal_prev_frame; signal_prev_frame = (float*)NULL; } if (bin_avgs != (float**)NULL) { for (int i = 0; i < num_chans; i++) { if (bin_avgs[i] != (float*)NULL) { delete [] bin_avgs[i]; bin_avgs[i] = (float*)NULL; } } delete [] bin_avgs; } if (bin_freqs != (int**)NULL) { for (int i = 0; i < num_chans; i++) { if (bin_freqs[i] != (int*)NULL) { delete [] bin_freqs[i]; bin_freqs[i] = (int*)NULL; } } delete [] bin_freqs; } if (pdf != (float**)NULL) { for (int i = 0; i < num_chans; i++) { if (pdf[i] != (float*)NULL) { delete [] pdf[i]; pdf[i] = (float*)NULL; } } delete [] pdf; } if (cdf != (float**)NULL) { for (int i = 0; i < num_chans; i++) { if (cdf[i] != (float*)NULL) { delete [] cdf[i]; cdf[i] = (float*)NULL; } } delete [] cdf; } if (snr_values != (float*)NULL) { delete [] snr_values; } // exit gracefully // return NO_ERROR; }