/[svn]/jsampler/trunk/src/org/jsampler/view/classic/Channel.java
ViewVC logotype

Contents of /jsampler/trunk/src/org/jsampler/view/classic/Channel.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 787 - (show annotations) (download)
Mon Oct 10 16:03:12 2005 UTC (18 years, 6 months ago) by iliev
File size: 26625 byte(s)
* The first alpha-release of JSampler

1 /*
2 * JSampler - a java front-end for LinuxSampler
3 *
4 * Copyright (C) 2005 Grigor Kirilov Iliev
5 *
6 * This file is part of JSampler.
7 *
8 * JSampler is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2
10 * as published by the Free Software Foundation.
11 *
12 * JSampler is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with JSampler; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20 * MA 02111-1307 USA
21 */
22
23 package org.jsampler.view.classic;
24
25 import java.awt.Color;
26 import java.awt.Dimension;
27 import java.awt.GridBagConstraints;
28 import java.awt.GridBagLayout;
29 import java.awt.Insets;
30
31 import java.awt.event.ActionEvent;
32 import java.awt.event.ActionListener;
33
34 import java.net.URL;
35
36 import java.util.logging.Level;
37
38 import javax.swing.BorderFactory;
39 import javax.swing.Box;
40 import javax.swing.BoxLayout;
41 import javax.swing.ImageIcon;
42 import javax.swing.JButton;
43 import javax.swing.JComboBox;
44 import javax.swing.JLabel;
45 import javax.swing.JPanel;
46 import javax.swing.JSeparator;
47 import javax.swing.JSlider;
48 import javax.swing.JToggleButton;
49
50 import javax.swing.event.ChangeEvent;
51 import javax.swing.event.ChangeListener;
52
53 import net.sf.juife.JuifeUtils;
54
55 import org.jsampler.CC;
56 import org.jsampler.AudioDeviceModel;
57 import org.jsampler.MidiDeviceModel;
58 import org.jsampler.SamplerChannelModel;
59 import org.jsampler.SamplerModel;
60
61 import org.jsampler.event.AudioDeviceListEvent;
62 import org.jsampler.event.AudioDeviceListListener;
63 import org.jsampler.event.MidiDeviceListEvent;
64 import org.jsampler.event.MidiDeviceListListener;
65 import org.jsampler.event.SamplerChannelAdapter;
66 import org.jsampler.event.SamplerChannelEvent;
67 import org.jsampler.event.SamplerChannelListener;
68
69 import org.linuxsampler.lscp.AudioOutputDevice;
70 import org.linuxsampler.lscp.MidiInputDevice;
71 import org.linuxsampler.lscp.MidiPort;
72 import org.linuxsampler.lscp.SamplerChannel;
73 import org.linuxsampler.lscp.SamplerEngine;
74
75 import static org.jsampler.view.classic.ClassicI18n.i18n;
76
77
78 /**
79 *
80 * @author Grigor Iliev
81 */
82 public class Channel extends org.jsampler.view.JSChannel {
83 private final static ImageIcon iconMuteOn;
84 private final static ImageIcon iconMuteOff;
85 private final static ImageIcon iconMutedBySolo;
86
87 private final static ImageIcon iconSoloOn;
88 private final static ImageIcon iconSoloOff;
89
90 private final static ImageIcon iconShowProperties;
91 private final static ImageIcon iconHideProperties;
92
93 static {
94 String path = "org/jsampler/view/classic/res/icons/";
95 URL url = ClassLoader.getSystemClassLoader().getResource(path + "mute_on.png");
96 iconMuteOn = new ImageIcon(url);
97
98 url = ClassLoader.getSystemClassLoader().getResource(path + "mute_off.png");
99 iconMuteOff = new ImageIcon(url);
100
101 url = ClassLoader.getSystemClassLoader().getResource(path + "muted_by_solo.png");
102 iconMutedBySolo = new ImageIcon(url);
103
104 url = ClassLoader.getSystemClassLoader().getResource(path + "solo_on.png");
105 iconSoloOn = new ImageIcon(url);
106
107 url = ClassLoader.getSystemClassLoader().getResource(path + "solo_off.png");
108 iconSoloOff = new ImageIcon(url);
109
110 url = ClassLoader.getSystemClassLoader().getResource(path + "Back16.gif");
111 iconShowProperties = new ImageIcon(url);
112
113 url = ClassLoader.getSystemClassLoader().getResource(path + "Down16.gif");
114 iconHideProperties = new ImageIcon(url);
115 }
116
117
118 private final JPanel mainPane = new JPanel();
119 private final ChannelProperties propertiesPane;
120 private final JButton btnInstr = new JButton(i18n.getLabel("Channel.btnInstr"));
121 private final JButton btnMute = new JButton();
122 private final JButton btnSolo = new JButton();
123 private final JSlider slVolume = new JSlider(0, 100);
124 private final JLabel lVolume = new JLabel();
125 private final JLabel lStreams = new JLabel("--");
126 private final JLabel lVoices = new JLabel("--");
127 private final JToggleButton btnProperties = new JToggleButton();
128
129 private final EventHandler eventHandler = new EventHandler();
130
131 private static int count = 2;
132
133 private boolean selected = false;
134
135
136 /**
137 * Creates a new instance of <code>Channel</code> using the specified
138 * non-<code>null</code> channel model.
139 * @param model The model to be used by this channel.
140 * @throws IllegalArgumentException If the model is <code>null</code>.
141 */
142 public
143 Channel(SamplerChannelModel model) {
144 super(model);
145
146 setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1));
147
148 mainPane.setLayout(new BoxLayout(mainPane, BoxLayout.Y_AXIS));
149
150 JPanel p = new JPanel();
151 p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS));
152 p.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
153
154 //setToolTipText(" Channel: " + String.valueOf(getChannelID()) + " ");
155
156 Dimension d = btnInstr.getPreferredSize();
157 btnInstr.setMaximumSize(new Dimension(Short.MAX_VALUE, d.height));
158 p.add(btnInstr);
159 p.add(Box.createRigidArea(new Dimension(6, 0)));
160
161 lStreams.setHorizontalAlignment(JLabel.CENTER);
162 lVoices.setHorizontalAlignment(JLabel.CENTER);
163
164 JPanel statPane = new JPanel();
165 statPane.setBorder(BorderFactory.createLoweredBevelBorder());
166 statPane.setLayout(new BoxLayout(statPane, BoxLayout.X_AXIS));
167 statPane.add(Box.createRigidArea(new Dimension(6, 0)));
168 statPane.add(lStreams);
169 statPane.add(new JLabel("/"));
170 statPane.add(lVoices);
171 statPane.add(Box.createRigidArea(new Dimension(6, 0)));
172
173 p.add(statPane);
174
175 p.add(Box.createRigidArea(new Dimension(6, 0)));
176
177 btnMute.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
178 p.add(btnMute);
179 p.add(Box.createRigidArea(new Dimension(6, 0)));
180
181 btnSolo.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
182 p.add(btnSolo);
183 p.add(Box.createRigidArea(new Dimension(6, 0)));
184
185 JPanel volumePane = new JPanel();
186 volumePane.setBorder(BorderFactory.createLoweredBevelBorder());
187 volumePane.setLayout(new BoxLayout(volumePane, BoxLayout.X_AXIS));
188 volumePane.add(Box.createRigidArea(new Dimension(6, 0)));
189
190 d = slVolume.getPreferredSize();
191 slVolume.setMaximumSize(new Dimension(d.width > 300 ? d.width : 300, d.height));
192 volumePane.add(slVolume);
193
194 lVolume.setBorder(BorderFactory.createEmptyBorder(3, 6, 3, 6));
195 lVolume.setHorizontalAlignment(lVolume.RIGHT);
196
197 // We use this to set the size of the lVolume that will be used in setVolume()
198 // to prevent the frequent resizing of lVolume
199 lVolume.setText("100%");
200
201 volumePane.add(lVolume);
202
203 p.add(volumePane);
204 p.add(Box.createRigidArea(new Dimension(6, 0)));
205
206 btnProperties.setContentAreaFilled(false);
207 btnProperties.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
208 btnProperties.setIcon(iconShowProperties);
209 btnProperties.setSelectedIcon(iconHideProperties);
210 p.add(btnProperties);
211
212 mainPane.add(p);
213
214 propertiesPane = new ChannelProperties(model);
215 propertiesPane.setBorder(BorderFactory.createEmptyBorder(0, 3, 3, 3));
216 propertiesPane.setVisible(false);
217 mainPane.add(propertiesPane);
218 add(mainPane);
219
220 d = getPreferredSize();
221 setMaximumSize(new Dimension(getMaximumSize().width, d.height));
222
223 getModel().addSamplerChannelListener(eventHandler);
224
225 btnInstr.addActionListener(new ActionListener() {
226 public void
227 actionPerformed(ActionEvent e) { loadInstrument(); }
228 });
229
230 btnMute.addActionListener(new ActionListener() {
231 public void
232 actionPerformed(ActionEvent e) { changeMute(); }
233 });
234
235 btnSolo.addActionListener(new ActionListener() {
236 public void
237 actionPerformed(ActionEvent e) { changeSolo(); }
238 });
239
240 slVolume.addChangeListener(new ChangeListener() {
241 public void
242 stateChanged(ChangeEvent e) { setVolume(); }
243 });
244
245 btnProperties.addActionListener(new ActionListener() {
246 public void
247 actionPerformed(ActionEvent e) {
248 showProperties(btnProperties.isSelected());
249 }
250 });
251
252 updateChannelInfo();
253 }
254
255 private class EventHandler implements SamplerChannelListener {
256 /**
257 * Invoked when changes are made to a sampler channel.
258 * @param e A <code>SamplerChannelEvent</code> instance
259 * containing event information.
260 */
261 public void
262 channelChanged(SamplerChannelEvent e) { updateChannelInfo(); }
263
264 /**
265 * Invoked when the number of active disk streams has changed.
266 * @param e A <code>SamplerChannelEvent</code> instance
267 * containing event information.
268 */
269 public void
270 streamCountChanged(SamplerChannelEvent e) {
271 updateStreamCount(getModel().getStreamCount());
272 }
273
274 /**
275 * Invoked when the number of active voices has changed.
276 * @param e A <code>SamplerChannelEvent</code> instance
277 * containing event information.
278 */
279 public void
280 voiceCountChanged(SamplerChannelEvent e) {
281 updateVoiceCount(getModel().getVoiceCount());
282 }
283 }
284
285 /**
286 * Determines whether the channel is selected.
287 * @return <code>true</code> if the channel is selected, <code>false</code> otherwise.
288 */
289 public boolean isSelected() { return selected; }
290
291 /**
292 * Sets the selection state of this channel.
293 * This method is invoked when the selection state of the channel has changed.
294 * @param select Specifies the new selection state of this channel;
295 * <code>true</code> to select the channel, <code>false</code> otherwise.
296 */
297 public void
298 setSelected(boolean select) {
299 if(select)
300 mainPane.setBorder(BorderFactory.createLineBorder(java.awt.Color.WHITE, 3));
301 else mainPane.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
302
303 selected = select;
304 }
305
306 /** Hides the channel properties. */
307 public void
308 collapseChannel() { if(btnProperties.isSelected()) btnProperties.doClick(); }
309
310 /** Shows the channel properties. */
311 public void
312 expandChannel() { if(!btnProperties.isSelected()) btnProperties.doClick(); }
313
314 /**
315 * Updates the channel settings. This method is invoked when changes to the
316 * channel were made.
317 */
318 private void
319 updateChannelInfo() {
320 SamplerChannel sc = getChannelInfo();
321
322 int status = sc.getInstrumentStatus();
323 if(status >= 0 && status < 100) {
324 btnInstr.setText(i18n.getLabel("Channel.loadingInstrument", status));
325 } else {
326 if(sc.getInstrumentName() != null) btnInstr.setText(sc.getInstrumentName());
327 else btnInstr.setText(i18n.getLabel("Channel.btnInstr"));
328 }
329
330 updateMute(sc);
331
332 if(sc.isSoloChannel()) btnSolo.setIcon(iconSoloOn);
333 else btnSolo.setIcon(iconSoloOff);
334
335 slVolume.setValue((int)(sc.getVolume() * 100));
336
337 boolean b = sc.getEngine() != null;
338 slVolume.setEnabled(b);
339 btnSolo.setEnabled(b);
340 btnMute.setEnabled(b);
341 }
342
343 /** Invoked when the user clicks the mute button. */
344 private void
345 changeMute() {
346 SamplerChannel sc = getChannelInfo();
347 boolean b = true;
348
349 /*
350 * Changing the mute button icon now instead of
351 * leaving the work to the notification mechanism of the LinuxSampler.
352 */
353 if(sc.isMuted() && !sc.isMutedBySolo()) {
354 b = false;
355 boolean hasSolo = CC.getSamplerModel().hasSoloChannel();
356
357 if(sc.isSoloChannel() || !hasSolo) btnMute.setIcon(iconMuteOff);
358 else btnMute.setIcon(iconMutedBySolo);
359 } else btnMute.setIcon(iconMuteOn);
360
361 getModel().setMute(b);
362 }
363
364 /** Invoked when the user clicks the solo button. */
365 private void
366 changeSolo() {
367 SamplerChannel sc = getChannelInfo();
368 boolean b = !sc.isSoloChannel();
369
370 /*
371 * Changing the solo button icon (and related) now instead of
372 * leaving the work to the notification mechanism of the LinuxSampler.
373 */
374 if(b) {
375 btnSolo.setIcon(iconSoloOn);
376 if(sc.isMutedBySolo()) btnMute.setIcon(iconMuteOff);
377 } else {
378 btnSolo.setIcon(iconSoloOff);
379 if(!sc.isMuted() && CC.getSamplerModel().getSoloChannelCount() > 1)
380 btnMute.setIcon(iconMutedBySolo);
381 }
382
383 getModel().setSolo(b);
384 }
385
386 /** Invoked when the user changes the volume */
387 private void
388 setVolume() {
389 updateVolume();
390
391 if(slVolume.getValueIsAdjusting()) return;
392
393 int vol = (int)(getChannelInfo().getVolume() * 100);
394
395 if(vol == slVolume.getValue()) return;
396
397 /*
398 * If the model's volume is not equal to the slider
399 * value we assume that the change is due to user input.
400 * So we must update the volume at the backend too.
401 */
402 float volume = slVolume.getValue();
403 volume /= 100;
404 getModel().setVolume(volume);
405 }
406
407 private void
408 updateVolume() {
409 int volume = slVolume.getValue();
410 slVolume.setToolTipText(i18n.getLabel("Channel.volume", volume));
411
412 setVolumeLabel(volume);
413
414
415 }
416
417 private void
418 setVolumeLabel(int volume) {
419 Dimension d = lVolume.getPreferredSize();
420 lVolume.setText(String.valueOf(volume) + '%');
421 d = JuifeUtils.getUnionSize(d, lVolume.getPreferredSize());
422 lVolume.setMinimumSize(d);
423 lVolume.setPreferredSize(d);
424 lVolume.setMaximumSize(d);
425 }
426
427 /**
428 * Updates the mute button with the proper icon regarding to information obtained
429 * from <code>channel</code>.
430 * @param channel A <code>SamplerChannel</code> instance containing the new settings
431 * for this channel.
432 */
433 private void
434 updateMute(SamplerChannel channel) {
435 if(channel.isMutedBySolo()) btnMute.setIcon(iconMutedBySolo);
436 else if(channel.isMuted()) btnMute.setIcon(iconMuteOn);
437 else btnMute.setIcon(iconMuteOff);
438 }
439
440 /**
441 * Updates the number of active disk streams.
442 * @param count The new number of active disk streams.
443 */
444 private void
445 updateStreamCount(int count) {
446 Dimension d = lStreams.getPreferredSize();
447 lStreams.setText(count == 0 ? "--" : String.valueOf(count));
448 d = JuifeUtils.getUnionSize(d, lStreams.getPreferredSize());
449 lStreams.setMinimumSize(d);
450 lStreams.setPreferredSize(d);
451 lStreams.setMaximumSize(d);
452 }
453
454 /**
455 * Updates the number of active voices.
456 * @param count The new number of active voices.
457 */
458 private void
459 updateVoiceCount(int count) {
460 Dimension d = lVoices.getPreferredSize();
461 lVoices.setText(count == 0 ? "--" : String.valueOf(count));
462 d = JuifeUtils.getUnionSize(d, lVoices.getPreferredSize());
463 lVoices.setMinimumSize(d);
464 lVoices.setPreferredSize(d);
465 lVoices.setMaximumSize(d);
466 }
467
468 private void
469 showProperties(boolean show) {propertiesPane.setVisible(show); }
470
471 private void
472 loadInstrument() {
473 InstrumentChooser dlg = new InstrumentChooser(CC.getMainFrame());
474 dlg.setVisible(true);
475
476 if(!dlg.isCancelled()) {
477 getModel().loadInstrument(dlg.getFileName(), dlg.getInstrumentIndex());
478 }
479 }
480 }
481
482 class ChannelProperties extends JPanel {
483 private final static ImageIcon iconAudioProps;
484
485 static {
486 String path = "org/jsampler/view/classic/res/icons/";
487 URL url = ClassLoader.getSystemClassLoader().getResource(path + "Import16.gif");
488 iconAudioProps = new ImageIcon(url);
489 }
490
491 private final JLabel lMidiDevice =
492 new JLabel(i18n.getLabel("ChannelProperties.lMidiDevice"));
493 private final JLabel lMidiPort =
494 new JLabel(i18n.getLabel("ChannelProperties.lMidiPort"));
495 private final JLabel lMidiChannel =
496 new JLabel(i18n.getLabel("ChannelProperties.lMidiChannel"));
497
498 private final JLabel lAudioDevice =
499 new JLabel(i18n.getLabel("ChannelProperties.lAudioDevice"));
500
501 private final JComboBox cbEngines = new JComboBox();
502
503 private final JComboBox cbMidiDevice = new JComboBox();
504 private final JComboBox cbMidiPort = new JComboBox();
505 private final JComboBox cbMidiChannel = new JComboBox();
506 private final JComboBox cbAudioDevice = new JComboBox();
507
508 private final JButton btnAudioProps = new JButton(iconAudioProps);
509
510 private SamplerChannelModel channelModel = null;
511
512 private boolean update = false;
513
514 /**
515 * Creates a new instance of <code>ChannelProperties</code> using the specified non-null
516 * channel model.
517 * @param model The model to be used by this channel properties pane.
518 */
519 ChannelProperties(SamplerChannelModel model) {
520 channelModel = model;
521
522 setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
523
524 add(new JSeparator());
525
526 JPanel enginesPane = new JPanel();
527
528 for(SamplerEngine e : CC.getSamplerModel().getEngines()) cbEngines.addItem(e);
529
530 //cbEngines.setMaximumSize(cbEngines.getPreferredSize());
531
532 enginesPane.add(cbEngines);
533 String s = i18n.getLabel("ChannelProperties.enginesPane");
534 enginesPane.setBorder(BorderFactory.createTitledBorder(s));
535
536 JPanel devicesPane = new JPanel();
537 devicesPane.setLayout(new BoxLayout(devicesPane, BoxLayout.X_AXIS));
538
539 devicesPane.add(Box.createRigidArea(new Dimension(3, 0)));
540
541 devicesPane.add(createMidiPane());
542
543 devicesPane.add(Box.createRigidArea(new Dimension(3, 0)));
544
545 devicesPane.add(enginesPane);
546
547 devicesPane.add(Box.createRigidArea(new Dimension(3, 0)));
548
549 JPanel audioPane = createAudioPane();
550 Dimension d = audioPane.getPreferredSize();
551 d.height = Short.MAX_VALUE;
552
553 audioPane.setMaximumSize(d);
554 devicesPane.add(audioPane);
555
556 add(devicesPane);
557 add(Box.createRigidArea(new Dimension(0, 6)));
558
559 add(new JSeparator());
560
561 cbMidiChannel.addItem("All");
562 for(int i = 1; i <= 16; i++) cbMidiChannel.addItem(String.valueOf(i));
563
564 cbMidiDevice.addActionListener(new ActionListener() {
565 public void
566 actionPerformed(ActionEvent e) { setMidiDevice(); }
567 });
568
569 cbMidiPort.addActionListener(new ActionListener() {
570 public void
571 actionPerformed(ActionEvent e) { setMidiPort(); }
572 });
573
574 cbMidiChannel.addActionListener(new ActionListener() {
575 public void
576 actionPerformed(ActionEvent e) { setMidiChannel(); }
577 });
578
579 cbEngines.addActionListener(new ActionListener() {
580 public void
581 actionPerformed(ActionEvent e) { setEngineType(); }
582 });
583
584 cbAudioDevice.addActionListener(new ActionListener() {
585 public void
586 actionPerformed(ActionEvent e) { setAudioDevice(); }
587 });
588
589 getModel().addSamplerChannelListener(new SamplerChannelAdapter() {
590 public void
591 channelChanged(SamplerChannelEvent e) { updateChannelProperties(); }
592 });
593
594 CC.getSamplerModel().addMidiDeviceListListener(getHandler());
595 CC.getSamplerModel().addAudioDeviceListListener(getHandler());
596
597 btnAudioProps.setToolTipText(i18n.getLabel("ChannelProperties.routing"));
598 btnAudioProps.addActionListener(new ActionListener() {
599 public void
600 actionPerformed(ActionEvent e) {
601 SamplerChannel c = getModel().getChannelInfo();
602 new ChannelOutputRoutingDlg(CC.getMainFrame(), c).setVisible(true);
603
604 }
605 });
606
607
608
609 updateMidiDevices();
610 updateAudioDevices();
611 updateChannelProperties();
612 }
613
614 private JPanel
615 createMidiPane() {
616 JPanel midiPane = new JPanel();
617
618 GridBagLayout gridbag = new GridBagLayout();
619 GridBagConstraints c = new GridBagConstraints();
620
621 midiPane.setLayout(gridbag);
622
623 c.gridx = 0;
624 c.gridy = 0;
625 c.insets = new Insets(3, 3, 3, 3);
626 gridbag.setConstraints(lMidiDevice, c);
627 midiPane.add(lMidiDevice);
628
629 c.gridx = 1;
630 c.gridy = 0;
631 gridbag.setConstraints(cbMidiDevice, c);
632 midiPane.add(cbMidiDevice);
633
634 c.gridx = 2;
635 c.gridy = 0;
636 gridbag.setConstraints(lMidiPort, c);
637 midiPane.add(lMidiPort);
638
639 c.gridx = 4;
640 c.gridy = 0;
641 gridbag.setConstraints(lMidiChannel, c);
642 midiPane.add(lMidiChannel);
643
644 c.gridx = 5;
645 c.gridy = 0;
646 gridbag.setConstraints(cbMidiChannel, c);
647 midiPane.add(cbMidiChannel);
648
649 c.gridx = 3;
650 c.gridy = 0;
651 c.weightx = 1.0;
652 c.fill = GridBagConstraints.HORIZONTAL;
653 c.insets = new Insets(3, 3, 3, 3);
654 gridbag.setConstraints(cbMidiPort, c);
655 midiPane.add(cbMidiPort);
656
657 String s = i18n.getLabel("ChannelProperties.midiPane");
658 midiPane.setBorder(BorderFactory.createTitledBorder(s));
659
660 return midiPane;
661 }
662
663 private JPanel
664 createAudioPane() {
665 JPanel audioPane = new JPanel();
666
667 GridBagLayout gridbag = new GridBagLayout();
668 GridBagConstraints c = new GridBagConstraints();
669
670 audioPane.setLayout(gridbag);
671
672 c.gridx = 0;
673 c.gridy = 0;
674 c.insets = new Insets(3, 3, 3, 3);
675 gridbag.setConstraints(lAudioDevice, c);
676 audioPane.add(lAudioDevice);
677
678 c.gridx = 1;
679 c.gridy = 0;
680 gridbag.setConstraints(cbAudioDevice, c);
681 audioPane.add(cbAudioDevice);
682
683 btnAudioProps.setMargin(new Insets(0, 0, 0, 0));
684 c.gridx = 2;
685 c.gridy = 0;
686 c.insets = new Insets(3, 9, 3, 3);
687 gridbag.setConstraints(btnAudioProps, c);
688 audioPane.add(btnAudioProps);
689
690 String s = i18n.getLabel("ChannelProperties.audioPane");
691 audioPane.setBorder(BorderFactory.createTitledBorder(s));
692
693 return audioPane;
694 }
695
696 /**
697 * Gets the model that is currently used by this channel properties pane.
698 * @return model The <code>SamplerChannelModel</code> instance
699 * that provides information about the channel whose settings are
700 * represented by this channel properties pane.
701 */
702 public SamplerChannelModel
703 getModel() { return channelModel; }
704
705 /**
706 * Updates the channel settings. This method is invoked when changes to the
707 * channel were made.
708 */
709 private void
710 updateChannelProperties() {
711 SamplerModel sm = CC.getSamplerModel();
712 SamplerChannel sc = getModel().getChannelInfo();
713
714 MidiDeviceModel mm = sm.getMidiDeviceModel(sc.getMidiInputDevice());
715 AudioDeviceModel am = sm.getAudioDeviceModel(sc.getAudioOutputDevice());
716
717 if(isUpdate()) CC.getLogger().warning("Unexpected update state!");
718
719 setUpdate(true);
720
721 try {
722 cbMidiDevice.setSelectedItem(mm == null ? null : mm.getDeviceInfo());
723
724 cbEngines.setSelectedItem(sc.getEngine());
725
726 cbAudioDevice.setSelectedItem(am == null ? null : am.getDeviceInfo());
727 } catch(Exception x) {
728 CC.getLogger().log(Level.WARNING, "Unkown error", x);
729 }
730
731 setUpdate(false);
732 }
733
734 /**
735 * Updates the MIDI device list.
736 */
737 private void
738 updateMidiDevices() {
739 SamplerModel sm = CC.getSamplerModel();
740 SamplerChannel sc = getModel().getChannelInfo();
741
742 setUpdate(true);
743
744 try {
745 cbMidiDevice.removeAllItems();
746
747 for(MidiDeviceModel m : sm.getMidiDeviceModels())
748 cbMidiDevice.addItem(m.getDeviceInfo());
749
750 MidiDeviceModel mm = sm.getMidiDeviceModel(sc.getMidiInputDevice());
751 cbMidiDevice.setSelectedItem(mm == null ? null : mm.getDeviceInfo());
752 } catch(Exception x) {
753 CC.getLogger().log(Level.WARNING, "Unkown error", x);
754 }
755
756 setUpdate(false);
757 }
758
759 /**
760 * Updates the audio device list.
761 */
762 private void
763 updateAudioDevices() {
764 SamplerModel sm = CC.getSamplerModel();
765 SamplerChannel sc = getModel().getChannelInfo();
766
767 setUpdate(true);
768
769 try {
770 cbAudioDevice.removeAllItems();
771
772 for(AudioDeviceModel m : sm.getAudioDeviceModels())
773 cbAudioDevice.addItem(m.getDeviceInfo());
774
775 AudioDeviceModel am = sm.getAudioDeviceModel(sc.getAudioOutputDevice());
776 cbAudioDevice.setSelectedItem(am == null ? null : am.getDeviceInfo());
777 } catch(Exception x) {
778 CC.getLogger().log(Level.WARNING, "Unkown error", x);
779 }
780
781 setUpdate(false);
782 }
783
784 private void
785 setMidiDevice() {
786 MidiInputDevice mid = (MidiInputDevice)cbMidiDevice.getSelectedItem();
787
788 if(!isUpdate()) {
789 if(mid != null) getModel().setMidiInputDevice(mid.getDeviceID());
790 return;
791 }
792
793 cbMidiPort.removeAllItems();
794
795 if(mid == null) {
796 cbMidiPort.setEnabled(false);
797
798 cbMidiChannel.setSelectedItem(null);
799 cbMidiChannel.setEnabled(false);
800 } else {
801 cbMidiPort.setEnabled(true);
802
803 MidiPort[] ports = mid.getMidiPorts();
804 for(MidiPort port : ports) cbMidiPort.addItem(port);
805
806 int p = getModel().getChannelInfo().getMidiInputPort();
807 cbMidiPort.setSelectedItem(p >= 0 && p < ports.length ? ports[p] : null);
808
809 cbMidiChannel.setEnabled(true);
810 int c = getModel().getChannelInfo().getMidiInputChannel();
811 cbMidiChannel.setSelectedItem(c == -1 ? "All" : String.valueOf(c + 1));
812 }
813
814
815 }
816
817 private void
818 setMidiPort() {
819 if(isUpdate()) return;
820
821 getModel().setMidiInputPort(cbMidiPort.getSelectedIndex());
822 }
823
824 private void
825 setMidiChannel() {
826 if(isUpdate()) return;
827
828 Object o = cbMidiChannel.getSelectedItem();
829 if(o == null) return;
830
831 int c = o.toString().equals("All") ? -1 : Integer.parseInt(o.toString()) - 1;
832
833 getModel().setMidiInputChannel(c);
834 }
835
836 /** Invoked when the user selects an engine. */
837 private void
838 setEngineType() {
839 Object oldEngine = getModel().getChannelInfo().getEngine();
840 SamplerEngine newEngine = (SamplerEngine)cbEngines.getSelectedItem();
841
842 if(oldEngine != null) { if(oldEngine.equals(newEngine)) return; }
843 else if(newEngine == null) return;
844
845 getModel().setEngineType(newEngine.getName());
846
847 }
848
849 private void
850 setAudioDevice() {
851 if(isUpdate()) return;
852 AudioOutputDevice dev = (AudioOutputDevice)cbAudioDevice.getSelectedItem();
853 if(dev != null) getModel().setAudioOutputDevice(dev.getDeviceID());
854 }
855
856 /**
857 * Determines whether the currently processed changes are due to update.
858 * @return <code>true</code> if the currently processed changes are due to update and
859 * <code>false</code> if the currently processed changes are due to user input.
860 */
861 private boolean
862 isUpdate() { return update; }
863
864 /**
865 * Sets whether the currently processed changes are due to update.
866 * @param b Specify <code>true</code> to indicate that the currently
867 * processed changes are due to update; <code>false</code>
868 * indicates that the currently processed changes are due to user input.
869 */
870 private void
871 setUpdate(boolean b) { update = b; }
872
873 private final Handler handler = new Handler();
874
875 private Handler
876 getHandler() { return handler; }
877
878 private class Handler implements MidiDeviceListListener, AudioDeviceListListener {
879 /**
880 * Invoked when a new MIDI device is created.
881 * @param e A <code>MidiDeviceListEvent</code>
882 * instance providing the event information.
883 */
884 public void
885 deviceAdded(MidiDeviceListEvent e) {
886 cbMidiDevice.addItem(e.getMidiDeviceModel().getDeviceInfo());
887 }
888
889 /**
890 * Invoked when a MIDI device is removed.
891 * @param e A <code>MidiDeviceListEvent</code>
892 * instance providing the event information.
893 */
894 public void
895 deviceRemoved(MidiDeviceListEvent e) {
896 cbMidiDevice.removeItem(e.getMidiDeviceModel().getDeviceInfo());
897 }
898
899 /**
900 * Invoked when a new audio device is created.
901 * @param e An <code>AudioDeviceListEvent</code>
902 * instance providing the event information.
903 */
904 public void
905 deviceAdded(AudioDeviceListEvent e) {
906 cbAudioDevice.addItem(e.getAudioDeviceModel().getDeviceInfo());
907 }
908
909 /**
910 * Invoked when an audio device is removed.
911 * @param e An <code>AudioDeviceListEvent</code>
912 * instance providing the event information.
913 */
914 public void
915 deviceRemoved(AudioDeviceListEvent e) {
916 cbAudioDevice.removeItem(e.getAudioDeviceModel().getDeviceInfo());
917 }
918 }
919 }

  ViewVC Help
Powered by ViewVC