/* * Sweep, a sound wave editor. * * Copyright (C) 2000 Conrad Parker * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include #include #include #include "sweep_app.h" #include "edit.h" static void do_filter_regions (sw_sample * sample, SweepFilterRegion func, sw_param_set pset, gpointer custom_data) { sw_sounddata * sounddata = sample->sounddata; sw_format * f = sounddata->format; GList * gl; sw_sel * sel; sw_framecount_t sel_total, run_total; sw_framecount_t offset, remaining, n; gpointer d; gint percent; gboolean active = TRUE; sel_total = sounddata_selection_nr_frames (sounddata) / 100; if (sel_total == 0) sel_total = 1; run_total = 0; for (gl = sounddata->sels; active && gl; gl = gl->next) { sel = (sw_sel *)gl->data; offset = 0; remaining = sel->sel_end - sel->sel_start; while (active && remaining > 0) { g_mutex_lock (sample->ops_mutex); if (sample->edit_state == SWEEP_EDIT_STATE_CANCEL) { active = FALSE; } else { d = sounddata->data + (int)frames_to_bytes (f, sel->sel_start + offset); n = MIN(remaining, 1024); func (d, sounddata->format, n, pset, custom_data); remaining -= n; offset += n; run_total += n; percent = run_total / sel_total; sample_set_progress_percent (sample, percent); #ifdef DEBUG g_print ("completed %d / %d frames, %d%%\n", run_total, sel_total, percent); #endif } g_mutex_unlock (sample->ops_mutex); } } } static void do_filter_regions_thread (sw_op_instance * inst) { sw_sample * sample = inst->sample; sw_perform_data * pd = (sw_perform_data *)inst->do_data; sw_edit_buffer * old_eb; paste_over_data * p; if (sample == NULL || sample->sounddata == NULL || sample->sounddata->sels == NULL) goto noop; old_eb = edit_buffer_from_sample (sample); p = paste_over_data_new (old_eb, old_eb); inst->redo_data = inst->undo_data = p; set_active_op (sample, inst); do_filter_regions (sample, (SweepFilterRegion)pd->func, pd->pset, pd->custom_data); if (sample->edit_state == SWEEP_EDIT_STATE_BUSY) { p->new_eb = edit_buffer_from_sample (sample); register_operation (sample, inst); } return; noop: sample_set_tmp_message (sample, _("No selection to process")); } static sw_operation filter_regions_op = { SWEEP_EDIT_MODE_FILTER, (SweepCallback)do_filter_regions_thread, (SweepFunction)g_free, (SweepCallback)undo_by_paste_over, (SweepFunction)paste_over_data_destroy, (SweepCallback)redo_by_paste_over, (SweepFunction)paste_over_data_destroy }; sw_op_instance * perform_filter_region_op (sw_sample * sample, char * desc, SweepFilterRegion func, sw_param_set pset, gpointer custom_data) { sw_perform_data * pd = (sw_perform_data *)g_malloc (sizeof(*pd)); pd->func = (SweepFunction)func; pd->pset = pset; pd->custom_data = custom_data; schedule_operation (sample, desc, &filter_regions_op, pd); return NULL; } static void do_filter_thread (sw_op_instance * inst) { sw_sample * sample = inst->sample; sw_perform_data * pd = (sw_perform_data *)inst->do_data; SweepFilter func = (SweepFilter)pd->func; sw_param_set pset = pd->pset; void * custom_data = pd->custom_data; sw_edit_buffer * old_eb; paste_over_data * p; sw_sample * out; old_eb = edit_buffer_from_sample (sample); p = paste_over_data_new (old_eb, old_eb); inst->redo_data = inst->undo_data = p; set_active_op (sample, inst); out = func (sample, pset, custom_data); /* XXX: this is all kinda assuming out == sample if out != NULL */ if (out != NULL && sample->edit_state == SWEEP_EDIT_STATE_BUSY) { p->new_eb = edit_buffer_from_sample (sample); register_operation (sample, inst); } } static sw_operation filter_op = { SWEEP_EDIT_MODE_FILTER, (SweepCallback)do_filter_thread, (SweepFunction)g_free, (SweepCallback)undo_by_paste_over, (SweepFunction)paste_over_data_destroy, (SweepCallback)redo_by_paste_over, (SweepFunction)paste_over_data_destroy }; sw_op_instance * perform_filter_op (sw_sample * sample, char * desc, SweepFilter func, sw_param_set pset, gpointer custom_data) { sw_perform_data * pd = (sw_perform_data *)g_malloc (sizeof(*pd)); pd->func = (SweepFunction)func; pd->pset = pset; pd->custom_data = custom_data; schedule_operation (sample, desc, &filter_op, pd); return NULL; }