/* audioreader.cpp -- reads sequence of overlapping windows * * 14-Jul-08 RBD */ #include "assert.h" #include "stdio.h" #include "math.h" #include "sautils.h" #include "string.h" #include #include "allegro.h" #include "audioreader.h" #include "scorealign.h" using namespace std; long Audio_reader::read_window(float *data) // reads the next window of samples // the first time, fill half the window with zeros and the second half // with data from the file // after that, shift the window by hop_size and fill the end of the window // with hop_size new samples // the window is actually constructed in temp_data, then copied to data. // That way, the caller can apply a smoothing function to data and we'll // still have a copy. // the function returns false on the next call when detecting that there // is no more samples, // data -- the window to be returned // temp_data -- since we destroy data by windowing, temp_data saves // overlapping samples so we don't have to read them again // samples_per_frame -- must be even, note that first window is padded // half-full with zeros // hop_samples -- additional samples read each time after the first window { int frames_read; // how many frames did we read? int hop = hop_samples; if (reading_first_window) { hop = samples_per_frame / 2; // first time we read more data // zero end of temp_data, which will shift to beginning memset(temp_data + hop, 0, sizeof(float) * (samples_per_frame - hop)); reading_first_window = false; } // before reading in new sounds, shift temp_data by hop_size memmove(temp_data, temp_data + hop, (samples_per_frame - hop) * sizeof(float)); frames_read = read(temp_data + samples_per_frame - hop, hop); // zero any leftovers (happens at last frame): //printf("check fr %i hs %i ws %i ",frames_read,hop_size,window_size); memset(temp_data + samples_per_frame - hop + frames_read, 0, sizeof(float) * (hop - frames_read)); assert(samples_per_frame - frames_read >= 0); // now copy temp_data to data memcpy(data, temp_data, sizeof(float) * samples_per_frame); if (frames_read != hop && reading_last_window == false) { reading_last_window = true; return true; } else if (reading_last_window == true) { return false; } else { return true; } } void Audio_reader::calculate_parameters(Scorealign &sa, bool verbose) { double sample_rate = get_sample_rate(); long pcm_frames = get_frames(); // we want to make sure samples_per_frame is even, to keep things // consistent we'll change hopsize_samples the same way samples_per_frame = (int) (sa.window_size * sample_rate + 0.5); if (samples_per_frame % 2 == 1) samples_per_frame = samples_per_frame + 1; /*=============================================================*/ hop_samples = (int)(sa.frame_period * sample_rate + 0.5); if (hop_samples % 2 == 1) hop_samples = hop_samples + 1; actual_frame_period = (hop_samples / sample_rate); // this is stored back in a field in sa as well as here in the reader frame_count= (int) ceil(((float) pcm_frames / hop_samples + 1)); this->frame_count = frame_count; temp_data = ALLOC(float, samples_per_frame); memset(temp_data, 0, samples_per_frame * sizeof(temp_data[0])); assert(temp_data); }