1 /*
2  * Sweep, a sound wave editor.
3  *
4  * Copyright (C) 2000 Conrad Parker
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19  */
20 
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <gdk/gdkkeysyms.h>
25 
26 #include <sweep/sweep.h>
27 
28 #include "../src/sweep_app.h" /* XXX */
29 
30 #if 0
31 static void
32 region_reverse (gpointer data, sw_format * format, int nr_frames,
33 		sw_param_set pset, gpointer custom_data)
34 {
35   glong i, sw;
36   gpointer d, e, t;
37 
38   sw = frames_to_bytes (format, 1);
39   t = g_malloc (sw);
40 
41   d = data;
42   e = d + frames_to_bytes (format, nr_frames);
43 
44   for (i = 0; i <= nr_frames/2; i++) {
45     memcpy (t, d, sw);
46     memcpy (d, e, sw);
47     memcpy (e, t, sw);
48 
49     d += sw;
50     e -= sw;
51   }
52 
53   g_free (t);
54 }
55 #endif
56 
57 static sw_sample *
sounddata_reverse(sw_sample * sample,sw_param_set pset,gpointer custom_data)58 sounddata_reverse (sw_sample * sample, sw_param_set pset,
59 		   gpointer custom_data)
60 {
61   GList * gl;
62   sw_sel * sel;
63   glong i, sw;
64   sw_sounddata * sounddata;
65   sw_format * format;
66   sw_framecount_t nr_frames;
67   gpointer d, e, t;
68 
69   sw_framecount_t op_total, run_total;
70   sw_framecount_t remaining, n;
71 
72   gboolean active = TRUE;
73 
74   sounddata = sample_get_sounddata (sample);
75   format = sounddata->format;
76 
77   op_total = sounddata_selection_nr_frames (sounddata) / 200;
78   if (op_total == 0) op_total = 1;
79   run_total = 0;
80 
81   sw = frames_to_bytes (format, 1);
82   t = alloca (sw);
83 
84   for (gl = sounddata->sels; active && gl; gl = gl->next) {
85     sel = (sw_sel *)gl->data;
86 
87     d = sounddata->data + frames_to_bytes (format, sel->sel_start);
88     nr_frames = sel->sel_end - sel->sel_start;
89 
90     e = d + frames_to_bytes (format, nr_frames);
91 
92     remaining = nr_frames/2;
93 
94     while (active && remaining > 0) {
95       g_mutex_lock (sample->ops_mutex);
96 
97       if (sample->edit_state == SWEEP_EDIT_STATE_CANCEL) {
98 	active = FALSE;
99       } else {
100 	n = MIN (remaining, 1024);
101 
102 	for (i = 0; i <= n; i++) {
103 	  memcpy (t, d, sw);
104 	  memcpy (d, e, sw);
105 	  memcpy (e, t, sw);
106 
107 	  d += sw;
108 	  e -= sw;
109 	}
110 
111 	remaining -= n;
112 
113 	run_total += n;
114 	sample_set_progress_percent (sample, run_total / op_total);
115       }
116 
117       g_mutex_unlock (sample->ops_mutex);
118     }
119   }
120 
121   return sample;
122 }
123 
124 static sw_op_instance *
apply_reverse(sw_sample * sample,sw_param_set pset,gpointer custom_data)125 apply_reverse (sw_sample * sample, sw_param_set pset, gpointer custom_data)
126 {
127 #if 0
128   return
129     perform_filter_region_op (sample, _("Reverse"),
130 			       (SweepFilterRegion)region_reverse, pset, NULL);
131 #endif
132 
133   return
134     perform_filter_op (sample, _("Reverse"),
135 		       (SweepFilter)sounddata_reverse, pset, NULL);
136 }
137 
138 
139 static sw_procedure proc_reverse = {
140   N_("Reverse"),
141   N_("Reverse selected regions of a sample"),
142   "Conrad Parker",
143   "Copyright (C) 2000",
144   "http://sweep.sourceforge.net/plugins/reverse",
145   "Filters/Reverse", /* identifier */
146   GDK_f, /* accel_key */
147   GDK_SHIFT_MASK, /* accel_mods */
148   0, /* nr_params */
149   NULL, /* param_specs */
150   NULL, /* suggests() */
151   apply_reverse,
152   NULL, /* custom_data */
153 };
154 
155 static GList *
reverse_init(void)156 reverse_init (void)
157 {
158   return g_list_append ((GList *)NULL, &proc_reverse);
159 }
160 
161 
162 sw_plugin plugin = {
163   reverse_init, /* plugin_init */
164   NULL, /* plugin_cleanup */
165 };
166