/[svn]/jsampler/trunk/src/org/jsampler/view/std/JSFxSendsPane.java
ViewVC logotype

Annotation of /jsampler/trunk/src/org/jsampler/view/std/JSFxSendsPane.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1540 - (hide annotations) (download)
Mon Dec 3 23:22:02 2007 UTC (16 years, 4 months ago) by iliev
File size: 12952 byte(s)
* Fantasia: by default the volume values are now shown in decibels
* Implemented support for retrieving instrument information
  from instrument files
* Some bugfixes and enhancements

1 iliev 1286 /*
2     * JSampler - a java front-end for LinuxSampler
3     *
4     * Copyright (C) 2005-2007 Grigor Iliev <grigor@grigoriliev.com>
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.std;
24    
25     import java.awt.BorderLayout;
26     import java.awt.Dimension;
27    
28     import java.awt.event.ActionEvent;
29     import java.awt.event.ActionListener;
30    
31     import javax.swing.AbstractAction;
32     import javax.swing.Action;
33     import javax.swing.BorderFactory;
34     import javax.swing.Box;
35     import javax.swing.BoxLayout;
36     import javax.swing.DefaultCellEditor;
37     import javax.swing.JButton;
38     import javax.swing.JComboBox;
39     import javax.swing.JLabel;
40     import javax.swing.JPanel;
41     import javax.swing.JScrollPane;
42     import javax.swing.JSlider;
43     import javax.swing.JSplitPane;
44     import javax.swing.JTable;
45     import javax.swing.JToolBar;
46    
47     import javax.swing.event.ChangeEvent;
48     import javax.swing.event.ChangeListener;
49     import javax.swing.event.ListSelectionEvent;
50     import javax.swing.event.ListSelectionListener;
51    
52     import javax.swing.table.AbstractTableModel;
53     import javax.swing.table.TableColumn;
54     import javax.swing.table.JTableHeader;
55    
56     import net.sf.juife.event.TaskEvent;
57     import net.sf.juife.event.TaskListener;
58    
59     import org.jsampler.AudioDeviceModel;
60     import org.jsampler.CC;
61 iliev 1540 import org.jsampler.HF;
62     import org.jsampler.JSPrefs;
63 iliev 1286 import org.jsampler.SamplerChannelModel;
64    
65     import org.jsampler.event.EffectSendsAdapter;
66     import org.jsampler.event.EffectSendsEvent;
67     import org.jsampler.event.EffectSendsListener;
68    
69    
70     import org.jsampler.task.Channel;
71    
72     import org.jsampler.view.FxSendTable;
73    
74     import org.linuxsampler.lscp.FxSend;
75    
76     import static org.jsampler.view.std.StdI18n.i18n;
77    
78    
79     /**
80     *
81     * @author Grigor Iliev
82     */
83     public class JSFxSendsPane extends JPanel implements ListSelectionListener {
84     private SamplerChannelModel channelModel;
85     private final FxSendTable fxSendsTable;
86    
87     protected final Action actionAddFxSend = new AddFxSendAction();
88     protected final Action actionRemoveFxSend = new RemoveFxSendAction();
89    
90     private final JComboBox cbMidiCtrls = new JComboBox();
91 iliev 1540 private final JSlider slVolume = StdUtils.createVolumeSlider();
92 iliev 1286
93     private final JLabel lMidiCtrl = new JLabel(i18n.getLabel("JSFxSendsPane.lMidiCtrl"));
94     private final JLabel lVolume = new JLabel(i18n.getLabel("JSFxSendsPane.lVolume"));
95    
96     private final ChannelRoutingTable channelRoutingTable;
97    
98     private FxSend fxSend = null;
99    
100     /**
101     * Creates a new instance of <code>JSFxSendsPane</code>.
102     *
103     * @throws IllegalArgumentException If <code>model</code> is <code>null</code>.
104     */
105     public
106     JSFxSendsPane(SamplerChannelModel model) {
107     if(model == null)
108     throw new IllegalArgumentException("model should be non-null!");
109    
110     channelModel = model;
111     fxSendsTable = new FxSendTable(channelModel);
112     channelRoutingTable = new ChannelRoutingTable();
113    
114     setLayout(new BorderLayout());
115    
116    
117    
118     JPanel rightPane = createRightPane();
119    
120    
121     JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
122     splitPane.setLeftComponent(createLeftPane());
123     splitPane.setRightComponent(rightPane);
124     splitPane.setContinuousLayout(true);
125     add(splitPane);
126    
127     channelModel.addEffectSendsListener(getHandler());
128    
129     fxSendsTable.getSelectionModel().addListSelectionListener(this);
130    
131     if(channelModel.getChannelInfo().getEngine() == null) {
132     actionAddFxSend.setEnabled(false);
133     }
134     if(channelModel.getFxSendCount() == 0) {
135     actionRemoveFxSend.setEnabled(false);
136     } else {
137     fxSendsTable.setSelectedFxSend(channelModel.getFxSend(0));
138     }
139     updateFxSend();
140    
141     Dimension d = getMinimumSize();
142     int w = d.width > 500 ? d.width : 500;
143     int h = d.height > 300 ? d.height : 300;
144     setPreferredSize(new Dimension(w, h));
145     splitPane.setDividerLocation(200);
146     }
147    
148 iliev 1540 protected JSPrefs
149     preferences() { return CC.getViewConfig().preferences(); }
150    
151 iliev 1286 protected JToolBar
152     createToolBar() {
153     JToolBar tb = new JToolBar();
154     tb.setMaximumSize(new Dimension(Short.MAX_VALUE, tb.getPreferredSize().height));
155     tb.setFloatable(false);
156     tb.setAlignmentX(JPanel.RIGHT_ALIGNMENT);
157    
158     tb.add(new JButton(actionAddFxSend));
159     tb.add(new JButton(actionRemoveFxSend));
160    
161     return tb;
162     }
163    
164     protected JPanel
165     createLeftPane() {
166     JPanel leftPane = new JPanel();
167     leftPane.setLayout(new BorderLayout());
168    
169     leftPane.add(createToolBar(), BorderLayout.NORTH);
170     leftPane.add(new JScrollPane(fxSendsTable));
171    
172     return leftPane;
173     }
174    
175     protected JPanel
176     createRightPane() {
177     for(int i = 0; i < 128; i++) cbMidiCtrls.addItem(new Integer(i));
178    
179     cbMidiCtrls.addActionListener(new ActionListener() {
180     public void
181     actionPerformed(ActionEvent e) {
182     if(fxSend == null) return;
183    
184     int fxs = fxSend.getFxSendId();
185     int ctrl = cbMidiCtrls.getSelectedIndex();
186    
187     if(ctrl == fxSend.getMidiController()) {
188     return;
189     }
190    
191     channelModel.setBackendFxSendMidiController(fxs, ctrl);
192     }
193     });
194    
195     slVolume.addChangeListener(new ChangeListener() {
196     public void
197 iliev 1445 stateChanged(ChangeEvent e) { setVolume(); }
198 iliev 1286 });
199    
200     JPanel rightPane = new JPanel();
201     rightPane.setLayout(new BorderLayout());
202    
203     JPanel p = new JPanel();
204     p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS));
205    
206     JPanel p2 = new JPanel();
207     p2.setLayout(new BoxLayout(p2, BoxLayout.X_AXIS));
208    
209     p2.add(lVolume);
210     p2.add(Box.createRigidArea(new Dimension(6, 0)));
211     slVolume.setMinimumSize(slVolume.getPreferredSize());
212     p2.add(slVolume);
213     p2.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
214     p.add(p2);
215    
216     p2 = new JPanel();
217    
218     p2.setLayout(new BoxLayout(p2, BoxLayout.X_AXIS));
219     p2.add(lMidiCtrl);
220     p2.add(Box.createRigidArea(new Dimension(6, 0)));
221     p2.add(cbMidiCtrls);
222     p2.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
223     //p2.setAlignmentX(LEFT_ALIGNMENT);
224     p.add(p2);
225    
226     rightPane.add(p, BorderLayout.NORTH);
227     rightPane.add(new JScrollPane(channelRoutingTable));
228    
229     return rightPane;
230     }
231    
232 iliev 1445 private void
233     setVolume() {
234     if(fxSend == null || slVolume.getValueIsAdjusting()) return;
235    
236     int i = (int)(fxSend.getLevel() * 100);
237     if(slVolume.getValue() == i) return;
238    
239     float vol = slVolume.getValue();
240     vol /= 100;
241     channelModel.setBackendFxSendLevel(fxSend.getFxSendId(), vol);
242     }
243    
244 iliev 1286 public void
245     valueChanged(ListSelectionEvent e) {
246     if(e.getValueIsAdjusting()) return;
247    
248     fxSend = fxSendsTable.getSelectedFxSend();
249     actionRemoveFxSend.setEnabled(fxSend != null);
250     updateFxSend();
251     }
252    
253     private void
254     updateFxSend() {
255     boolean b = (fxSend != null);
256     cbMidiCtrls.setEnabled(b);
257     slVolume.setEnabled(b);
258     channelRoutingTable.setEnabled(b);
259     if(!b) {
260     slVolume.setValue(0);
261     cbMidiCtrls.setSelectedIndex(0);
262     return;
263     }
264    
265     cbMidiCtrls.setSelectedIndex(fxSend.getMidiController());
266     slVolume.setValue((int)(fxSend.getLevel() * 100));
267     }
268    
269     class AddFxSendAction extends AbstractAction {
270     private int fxSendId = -1;
271    
272     AddFxSendAction() {
273     super(i18n.getLabel("JSFxSendsPane.AddFxSendAction"));
274    
275     String s = i18n.getLabel("JSFxSendsPane.AddFxSendAction.tt");
276     putValue(SHORT_DESCRIPTION, s);
277     }
278    
279     public void
280     actionPerformed(ActionEvent e) {
281     int id = channelModel.getChannelId();
282     final Channel.AddFxSend t = new Channel.AddFxSend(id, 0, "New effect send");
283    
284     t.addTaskListener(new TaskListener() {
285     public void
286     taskPerformed(TaskEvent e) {
287     if(t.doneWithErrors()) {
288     fxSendId = -1;
289     return;
290     }
291     setFxSendId(t.getResult());
292     }
293     });
294     CC.getTaskQueue().add(t);
295     }
296    
297     public int
298     getFxSendId() { return fxSendId; }
299    
300     public void
301     setFxSendId(int id) { fxSendId = id; }
302     }
303    
304     class RemoveFxSendAction extends AbstractAction {
305     RemoveFxSendAction() {
306     super(i18n.getLabel("JSFxSendsPane.RemoveFxSendAction"));
307    
308     String s = i18n.getLabel("JSFxSendsPane.RemoveFxSendAction.tt");
309     putValue(SHORT_DESCRIPTION, s);
310     }
311    
312     public void
313     actionPerformed(ActionEvent e) {
314     FxSend fxs = fxSendsTable.getSelectedFxSend();
315     if(fxs == null) return;
316     channelModel.removeBackendFxSend(fxs.getFxSendId());
317     }
318     }
319    
320     class ChannelRoutingTable extends JTable {
321     private String[] columnToolTips = {
322     i18n.getLabel("JSFxSendsPane.ttAudioSrc"),
323     i18n.getLabel("JSFxSendsPane.ttAudioDst"),
324     };
325    
326     ChannelRoutingTable() {
327     super(new ChannelRoutingTableModel());
328    
329     JComboBox cb = new JComboBox();
330     int devId = channelModel.getChannelInfo().getAudioOutputDevice();
331     AudioDeviceModel adm = CC.getSamplerModel().getAudioDeviceById(devId);
332    
333     int chns;
334     if(adm == null) {
335     chns = channelModel.getChannelInfo().getAudioOutputChannels();
336     } else {
337     chns = adm.getDeviceInfo().getAudioChannelCount();
338     }
339    
340     for(Integer i = 0; i < chns; i++) cb.addItem(i);
341    
342     TableColumn column = getColumnModel().getColumn(1);
343     column.setCellEditor(new DefaultCellEditor(cb));
344     }
345    
346     protected JTableHeader
347     createDefaultTableHeader() {
348     return new JTableHeader(columnModel) {
349     public String getToolTipText(java.awt.event.MouseEvent e) {
350     java.awt.Point p = e.getPoint();
351     int i = columnModel.getColumnIndexAtX(p.x);
352     i = columnModel.getColumn(i).getModelIndex();
353     return columnToolTips[i];
354     }
355     };
356     }
357     }
358    
359     class ChannelRoutingTableModel extends AbstractTableModel implements ListSelectionListener {
360     private String[] columnNames = {
361     i18n.getLabel("JSFxSendsPane.audioSrc"),
362     i18n.getLabel("JSFxSendsPane.audioDst")
363     };
364    
365     ChannelRoutingTableModel() {
366     channelModel.addEffectSendsListener(new EffectSendsAdapter() {
367     /** Invoked when an effect send's setting are changed. */
368     public void
369     effectSendChanged(EffectSendsEvent e) {
370     if(fxSend == null) {
371     fireTableDataChanged();
372     return;
373     }
374    
375     if(fxSend.equals(e.getFxSend())) {
376     int l;
377     l = e.getFxSend().getAudioOutputRouting().length;
378     fireTableRowsUpdated(0, l - 1);
379     }
380     }
381     });
382    
383     fxSendsTable.getSelectionModel().addListSelectionListener(this);
384     }
385    
386     public int
387     getColumnCount() { return columnNames.length; }
388    
389     public String
390     getColumnName(int column) { return columnNames[column]; }
391    
392     public int
393     getRowCount() {
394     if(fxSend == null) return 0;
395     return fxSend.getAudioOutputRouting().length;
396     }
397    
398     public Object
399     getValueAt(int row, int column) {
400     switch(column) {
401     case 0:
402     return row;
403     case 1:
404     return fxSend.getAudioOutputRouting()[row];
405     default: return null;
406     }
407    
408     }
409    
410     public boolean
411     isCellEditable(int row, int column) {
412     switch(column) {
413     case 0:
414     return false;
415     case 1:
416     return true;
417     default: return false;
418     }
419     }
420    
421     public void
422     setValueAt(Object value, int row, int column) {
423     if(column == 0) return;
424     int id = fxSend.getFxSendId();
425     int src = (Integer)getValueAt(row, 0);
426     int dst = (Integer)value;
427     channelModel.setBackendFxSendAudioOutputChannel(id, src, dst);
428     fxSend.getAudioOutputRouting()[row] = dst;
429    
430     fireTableCellUpdated(row, column);
431     }
432    
433     public void
434     valueChanged(ListSelectionEvent e) {
435     if(e.getValueIsAdjusting()) return;
436    
437     fireTableDataChanged();
438     }
439     }
440    
441     private final Handler eventHandler = new Handler();
442    
443     private Handler
444     getHandler() { return eventHandler; }
445    
446     private class Handler implements EffectSendsListener {
447     /** Invoked when a new effect send is added to a sampler channel. */
448     public void
449     effectSendAdded(EffectSendsEvent e) {
450     FxSend fxs = fxSendsTable.getSelectedFxSend();
451     if(fxs == null) return;
452     AddFxSendAction a = (AddFxSendAction)actionAddFxSend;
453     if(fxs.getFxSendId() != a.getFxSendId()) return;
454    
455     fxSendsTable.requestFocus();
456     fxSendsTable.editSelectedFxSend();
457     a.setFxSendId(-1);
458     }
459    
460     /** Invoked when an effect send is removed from a sampler channel. */
461     public void
462     effectSendRemoved(EffectSendsEvent e) {
463     if(channelModel.getFxSendCount() == 0) return;
464     int id = e.getFxSend().getFxSendId();
465     for(FxSend fxs : channelModel.getFxSends()) {
466     if(fxs.getFxSendId() > id) {
467     fxSendsTable.setSelectedFxSend(fxs);
468     return;
469     }
470     }
471     FxSend fxs = channelModel.getFxSend(channelModel.getFxSendCount() - 1);
472     fxSendsTable.setSelectedFxSend(fxs);
473     }
474    
475     /** Invoked when an effect send's setting are changed. */
476     public void
477     effectSendChanged(EffectSendsEvent e) {
478     if(fxSend == null) return;
479     if(fxSend.equals(e.getFxSend())) {
480     fxSend = e.getFxSend();
481     updateFxSend();
482     }
483     }
484     }
485     }

  ViewVC Help
Powered by ViewVC