-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMenuBar.java
More file actions
324 lines (234 loc) · 12.1 KB
/
Copy pathMenuBar.java
File metadata and controls
324 lines (234 loc) · 12.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
package daw;
import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.*;
import javax.swing.*;
/**
*
* @author opdada01 Daniel Opdahl
* @author mantno01 Noah Manternach
* @author nteste01 Teboho Nteso
*
*/
//The MenuBar class provides the user with various track options via a drop-down menu, and allows
//the application to handle user selections.
public class MenuBar extends JMenuBar implements ActionListener {
/* FIELDS */
public MainDisplayWindow main_display_window;
public ArrayList<File> tracks_list;
/* CONSTRUCTOR */
public MenuBar(MainDisplayWindow main_display_window, ArrayList<File> tracks_list) {
//Here we set the main_display_window and tracks_list as well as locally declare all the
//menu drop-downs (e.g., edit_menu) and all the menu buttons (e.g., resample_item).
setMainDisplayWindow(main_display_window);
setTracksList(tracks_list);
JMenu edit_menu, track_menu, effect_menu;
JMenuItem cut_item, paste_item, erase_item;
JMenuItem merge_item, resample_item;
JMenuItem amplitude_item, normalize_item, clip_item, reverse_item;
setLayout(new FlowLayout(FlowLayout.LEFT));
//Here we create the drop-downs and the menu buttons, add the menu buttons to the
//drop-downs, and add ActionListeners to each menu button.
edit_menu = new JMenu("Edit");
erase_item = new JMenuItem("Erase");
track_menu = new JMenu("Track");
merge_item = new JMenuItem("Merge");
effect_menu = new JMenu("Effect");
amplitude_item = new JMenuItem("Adjust Amplitude");
reverse_item = new JMenuItem("Reverse");
add(edit_menu);
edit_menu.add(erase_item);
add(track_menu);
track_menu.add(merge_item);
add(effect_menu);
effect_menu.add(amplitude_item);
effect_menu.add(reverse_item);
erase_item.addActionListener(this);
merge_item.addActionListener(this);
amplitude_item.addActionListener(this);
reverse_item.addActionListener(this);
}
//All actions utilize a "checker" to ensure that the tracks_list is not empty, and therefore
//the user has a track to interact with. This is the first thing done with every action.
@Override
public void actionPerformed(ActionEvent e) {
//Selection "Erase" allows the user to remove audio from the selected file.
//The function goes through each byte and sets it to zero, essentially silencing it.
if (e.getActionCommand().equals("Erase")) {
if (getTracksList().isEmpty()) {
JOptionPane no_tracks_notification = new JOptionPane();
no_tracks_notification.showMessageDialog(this, "No Tracks to Edit!");
}
else {
getMainDisplayWindow().erase();
}
}
//Selection "Merge" allows the user to combine two file waveforms
//First we check to see if tracks_list has two or more tracks. If there is not, we notify
//the user with a pop-up window, do nothing, and return to the main display. Otherwise, we
//prompt the user to select a track to merge the current track with. If the user cancels
//or selects the current track, a pop-up window appears notifying them of their error, we
//do nothing, and return to the main display.
if (e.getActionCommand().equals("Merge")) {
if (getTracksList().isEmpty() || getTracksList().size() == 1) {
JOptionPane need_two_or_more_tracks_notification = new JOptionPane();
need_two_or_more_tracks_notification.showMessageDialog(this, "Need two or more tracks in order to Merge!");
}
else {
//merge_possible_values works as the options for the drop-down menu from which the user can
//select a track to merge with the current track
File merge_selected_file = null;
Object[] merge_possible_values = new Object[getTracksList().size()];
int i;
//Here we go through tracks_list and add the name of each to possibleVales except for
//the name of the current track
for (i=0; i<getTracksList().size(); i++) {
if (getTracksList().indexOf(getTracksList().get(i)) != getMainDisplayWindow().getCurrentTrack()) {
merge_possible_values[i] = getTracksList().get(i).getName();
}
}
String merge_selected_file_string = (String) JOptionPane.showInputDialog(null, "Select a Track to Merge With", "Merge Tracks", JOptionPane.INFORMATION_MESSAGE, null, merge_possible_values, merge_possible_values[0]);
System.out.println(merge_selected_file_string);
for (i=0; i<getTracksList().size(); i++) {
if (merge_selected_file_string.equals(getTracksList().get(i).getName())) {
merge_selected_file = getTracksList().get(i);
}
}
if (merge_selected_file_string == null) {
JOptionPane can_not_merge_with_null = new JOptionPane();
can_not_merge_with_null.showMessageDialog(this, "Select a valid Track to merge with");
}
else {
File current_file = getTracksList().get(getMainDisplayWindow().getCurrentTrack());
FileInputStream in1 = null;
try {
in1 = new FileInputStream(current_file);
} catch (Exception file_not_found) {}
int current_file_rate = 0;
try {
for (int i1 = 0; i1<32; i1++) {
while(i1 < 44 ) {
byte b1 = (byte) (in1.read() & 0xff);
byte b2 = (byte) (in1.read() & 0xff);
byte b3 = (byte) (in1.read() & 0xff);
byte b4 = (byte) (in1.read() & 0xff);
i1++;
if (i1 == 7) {
current_file_rate = b4 << 24 | b3 << 16 & 0xff0000 | b2 << 8 & 0xff00 | ((int) b1) & 0xff;
}
}
}
}
catch (Exception could_not_read_from_file_input_stream) {}
FileInputStream in2 = null;
try {
in2 = new FileInputStream(current_file);
} catch (FileNotFoundException could_not_open_file_input_stream) {}
int merge_selected_file_rate = 0;
try {
for (int i1 = 0; i1<32; i1++) {
while(i1 < 44 ) {
byte b1 = (byte) (in2.read() & 0xff);
byte b2 = (byte) (in2.read() & 0xff);
byte b3 = (byte) (in2.read() & 0xff);
byte b4 = (byte) (in2.read() & 0xff);
i1++;
if (i1 == 7) {
merge_selected_file_rate = b4 << 24 | b3 << 16 & 0xff0000 | b2 << 8 & 0xff00 | ((int) b1) & 0xff;
}
}
}
}
catch (Exception could_not_read_from_file_input_stream) {}
if (merge_selected_file_rate != current_file_rate) {
JOptionPane can_not_merge_different_samplerates = new JOptionPane();
can_not_merge_different_samplerates.showMessageDialog(this, "Cannot merge tracks with different sample rates");
}
else {
getMainDisplayWindow().merge(merge_selected_file);
}
}
}
}
//Selection "Adjust Amplitude" allows the user to adjust the amplitude of the current track using a percentage multiplier of their designation
//Here we prompt the user for input, specifically a percentage by which to scale the amplitude. If the user
//enters an in valid input (i.e., a number not between 0-1000, nothing at all, a character, etc.), a pop-up
//message is shown and nothing is done. The user can cancel the operation by pressing the cancel button.
if (e.getActionCommand().equals("Adjust Amplitude")) {
if (getTracksList().isEmpty()) {
JOptionPane no_tracks_notification = new JOptionPane();
no_tracks_notification.showMessageDialog(this, "No Tracks to Edit!");
}
else {
String percentage_input_string = JOptionPane.showInputDialog("Please input a percentage value to scale by:");
try {
if (percentage_input_string.equals("")) {
JOptionPane invalid_input_val_notification = new JOptionPane();
invalid_input_val_notification.showMessageDialog(this, "Percentage input necessary to adjust amplitude");
}
else {
try {
//We take the user input, convert it to a number, and divide by 100.0 to convert from
//percentage and get a double.
double scaling_ratio = Double.parseDouble(percentage_input_string);
scaling_ratio = scaling_ratio / 100.0;
if (scaling_ratio > 10.0 || scaling_ratio < 0) {
JOptionPane invalid_input_val_notification = new JOptionPane();
invalid_input_val_notification.showMessageDialog(this, "\"" + percentage_input_string + "\"" + " is not a valid percentage. Please enter a percentage in the range 0% - 1000%");
}
else {
Object[] amp_adj_possible_values = {"Clip", "Normalize"};
Object amp_adj_selected_value = JOptionPane.showInputDialog(null, "How would you like to scale?\n(See manual for details on scaling methods)", "Scaling Method", JOptionPane.INFORMATION_MESSAGE, null, amp_adj_possible_values, amp_adj_possible_values[0]);
System.out.println(amp_adj_selected_value);
if(amp_adj_selected_value == "Clip") {
System.out.println("beginning to Clip");
getMainDisplayWindow().adjustAmplitudeClip(scaling_ratio);
}
if (amp_adj_selected_value == "Normalize") {
getMainDisplayWindow().adjustAmplitudeNormalize(scaling_ratio);
}
if (amp_adj_selected_value != "Normalize" && amp_adj_selected_value != "Clip") {
JOptionPane null_input_amp_adj_method_notification = new JOptionPane();
null_input_amp_adj_method_notification.showMessageDialog(this, "Must select a method of scaling.");
}
}
}
catch (Exception invalid_percentage) {
JOptionPane invalid_input_str_notification = new JOptionPane();
invalid_input_str_notification.showMessageDialog(this, "\"" + percentage_input_string + "\"" + " is not a valid percentage");
}
}
}
//If the percentage_input_string is null, that means the user cancelled the operation. We do nothing in this case.
catch (Exception null_percentage_input_string) {}
}
}
//Selection "Reverse" allows the user to make a new track that essentially plays the original track backwards
if (e.getActionCommand().equals("Reverse")) {
if (getTracksList().isEmpty()) {
JOptionPane no_tracks_notification = new JOptionPane();
no_tracks_notification.showMessageDialog(this, "No Tracks to Edit!");
}
else {
getMainDisplayWindow().reverse();
}
}
}
/* ACCESSORS */
MainDisplayWindow getMainDisplayWindow() {
return main_display_window;
}
ArrayList<File> getTracksList() {
return tracks_list;
}
/* MUTATORS */
void setMainDisplayWindow(MainDisplayWindow other) {
main_display_window = other;
}
void setTracksList(ArrayList<File> other) {
tracks_list = other;
}
}