int frame_and_filter(short sample, float *data) { int signal; signal = detect_envelope(block_dc(sample)); if (signal_on) { if (row_index < row_len) { data[row_index] = filter_signal(sample); row_index++; } } else if (signal > threshold) { signal_on = 1; } return row_index; }
void* thr_bandpass(void *p_data) { std::list<t_audioOutCmd>::iterator cmditer; t_audioOutCmd cut; t_shared* pshared_data = (t_shared*)p_data; bool bquit; int samplerate; float *wrkbuffer; float *outbuffer; float *samplesbuffers[3]; unsigned long time; unsigned long total_time; int samplestart; int samplestop; int samplenum; bool bcompleted; t_ret_samples r; float *psamples; t_audio_strip strip; std::list<t_audio_strip> tmp_filtered_sound_list; std::list<t_audio_strip>::iterator f_sound_iter; double start_timecode; g_thrbandpassretval = 0; #ifdef _DEBUG printf("Initialising the bandpass thread\n"); #endif LOCK; bquit = pshared_data->bquit; samplerate = pshared_data->samplerate; UNLOCK; wrkbuffer = new float[MAX_VIEW_TIME * samplerate]; outbuffer = new float[MAX_VIEW_TIME * samplerate]; samplesbuffers[1] = wrkbuffer; samplesbuffers[2] = outbuffer; while (!bquit) { SLOCK; if (pshared_data->filter_cmd_list.size() > 0) { tmp_filtered_sound_list.clear(); total_time = 0; // Frankenstein design in order to be able to add new commands and unlock the mutex during the filtering and hence not lock the interface bcompleted = false; while (!bcompleted) { // Find the next command to be filtered cmditer = pshared_data->filter_cmd_list.begin(); while (cmditer != pshared_data->filter_cmd_list.end() && (*cmditer).notestate != state_wait_filtering) { cmditer++; } // Check if finished bcompleted = (cmditer == pshared_data->filter_cmd_list.end()); if (!bcompleted) { // Get the data assert((*cmditer).notestate == state_wait_filtering); (*cmditer).notestate = state_filtered; cut = (*cmditer); // Copy it because it could be delete in between unlocks SUNLOCK; samplestart = cut.start * samplerate - (samplerate / HANN_FCUT) / 2; samplestop = cut.stop * samplerate + (samplerate / HANN_FCUT) / 2; samplenum = samplestop - samplestart; if (samplestart < samplestop) { psamples = new float[samplenum]; LOCK; r = pshared_data->pad->get_data(samplestart, psamples, samplenum); UNLOCK; samplenum = r.obtained; // Parallel filtering of bands samplesbuffers[0] = psamples; // Filtering output filter_signal(&cut, samplesbuffers, samplenum, samplerate, &time); total_time += time; apply_hann_on_begin_and_end(psamples, samplenum, samplerate); //printf("playdelay is %f\n", cut.playdelay); strip.playtimecode = cut.playdelay; strip.samples = psamples; strip.samplenum = samplenum; strip.current_sample = 0; tmp_filtered_sound_list.push_front(strip); //printf("listsize ==%d\n", (int)pshared_data->filter_cmd_list.size()); } SLOCK; } // The command are erased in the rendering function } //--------------------------------------------------------------------------------- // All the notes must start at the same time otherwise it will mess the rythm up. // Therefore update the srtips only when they are filtered, filtering takes // a noticeable time. //--------------------------------------------------------------------------------- start_timecode = 0.001 * SDL_GetTicks(); // Playing the notes start here FLOCK; f_sound_iter = tmp_filtered_sound_list.begin(); while (f_sound_iter != tmp_filtered_sound_list.end()) { // Update the first -1 element (*f_sound_iter).playtimecode += start_timecode; pshared_data->filtered_sound_list.push_front((*f_sound_iter)); f_sound_iter++; } FUNLOCK; cmditer = pshared_data->filter_cmd_list.begin(); while (cmditer != pshared_data->filter_cmd_list.end()) { if ((*cmditer).notestate == state_filtered) { (*cmditer).playstart = start_timecode + (*cmditer).playdelay; (*cmditer).notestate = state_ready_2play; } cmditer++; } } SUNLOCK; #ifdef SHOW_FILTERING_TIME printf("Bandpass filtering took %lums.\n", total_time); #endif // Wait for something wait_filter_event(pshared_data); LOCK; bquit = pshared_data->bquit; UNLOCK; } delete[] wrkbuffer; delete[] outbuffer; #ifdef _DEBUG printf("Bandpass thread closing\n"); #endif return &g_thrbandpassretval; }