1 package camidion.chordhelper.midieditor;
3 import java.awt.Dimension;
4 import java.awt.Graphics;
5 import java.awt.Graphics2D;
6 import java.awt.GridLayout;
7 import java.awt.Insets;
9 import java.awt.Rectangle;
10 import java.awt.event.ActionEvent;
11 import java.awt.event.ActionListener;
12 import java.awt.event.ComponentEvent;
13 import java.awt.event.ComponentListener;
14 import java.awt.event.InputEvent;
15 import java.awt.event.MouseEvent;
16 import java.awt.event.MouseListener;
17 import java.util.ArrayList;
18 import java.util.Vector;
20 import javax.sound.midi.InvalidMidiDataException;
21 import javax.sound.midi.MidiChannel;
22 import javax.sound.midi.Sequence;
23 import javax.swing.AbstractAction;
24 import javax.swing.Action;
25 import javax.swing.BoxLayout;
26 import javax.swing.JButton;
27 import javax.swing.JCheckBox;
28 import javax.swing.JComboBox;
29 import javax.swing.JComponent;
30 import javax.swing.JDialog;
31 import javax.swing.JLabel;
32 import javax.swing.JOptionPane;
33 import javax.swing.JPanel;
34 import javax.swing.JScrollPane;
35 import javax.swing.JSpinner;
36 import javax.swing.JTabbedPane;
37 import javax.swing.JTextArea;
38 import javax.swing.JTextField;
39 import javax.swing.SpinnerNumberModel;
40 import javax.swing.event.ChangeEvent;
41 import javax.swing.event.ChangeListener;
43 import camidion.chordhelper.ButtonIcon;
44 import camidion.chordhelper.ChordHelperApplet;
45 import camidion.chordhelper.mididevice.VirtualMidiDevice;
46 import camidion.chordhelper.music.AbstractNoteTrackSpec;
47 import camidion.chordhelper.music.ChordProgression;
48 import camidion.chordhelper.music.DrumTrackSpec;
49 import camidion.chordhelper.music.FirstTrackSpec;
50 import camidion.chordhelper.music.MelodyTrackSpec;
51 import camidion.chordhelper.music.Range;
52 import camidion.chordhelper.pianokeyboard.PianoKeyboardListener;
53 import camidion.chordhelper.pianokeyboard.PianoKeyboardPanel;
56 * 新しいMIDIシーケンスを生成するダイアログ
58 public class NewSequenceDialog extends JDialog {
59 private static final Insets ZERO_INSETS = new Insets(0,0,0,0);
60 private static final Integer[] PPQList = {
61 48,60,80,96,120,160,192,240,320,384,480,960
63 private static final String INITIAL_CHORD_STRING =
64 "Key: C\nC G/B | Am Em/G | F C/E | Dm7 G7 C % | F G7 | Csus4 C\n";
65 private JTextArea chordText = new JTextArea(INITIAL_CHORD_STRING, 18, 30);
66 private JTextField seqNameText = new JTextField();
67 private JComboBox<Integer> ppqComboBox = new JComboBox<Integer>(PPQList);
68 private TimeSignatureSelecter timesigSelecter = new TimeSignatureSelecter();
69 private TempoSelecter tempoSelecter = new TempoSelecter();
70 private MeasureSelecter measureSelecter = new MeasureSelecter();
71 private TrackSpecPanel trackSpecPanel = new TrackSpecPanel() {{
72 DrumTrackSpec dts = new DrumTrackSpec(9, "Percussion track");
76 mts = new MelodyTrackSpec(2, "Bass track", new Range(36,48));
80 mts = new MelodyTrackSpec(1, "Chord track", new Range(60,72));
82 mts = new MelodyTrackSpec(0, "Melody track", new Range(60,84));
83 mts.randomMelody = true;
84 mts.beatPattern = 0xFFFF;
85 mts.continuousBeatPattern = 0x820A;
91 public Action openAction = new AbstractAction("New") {
93 String tooltip = "Generate new song - 新しい曲を生成";
94 putValue(Action.SHORT_DESCRIPTION, tooltip);
97 public void actionPerformed(ActionEvent e) { setVisible(true); }
99 private PlaylistTableModel playlist;
103 public Action generateAction = new AbstractAction(
104 "Generate & Add to PlayList", new ButtonIcon(ButtonIcon.EJECT_ICON)
107 public void actionPerformed(ActionEvent event) {
109 playlist.addSequenceAndPlay(getMidiSequence());
110 } catch (InvalidMidiDataException ex) {
111 ex.printStackTrace();
112 JOptionPane.showMessageDialog(
113 NewSequenceDialog.this, ex.getMessage(),
114 ChordHelperApplet.VersionInfo.NAME, JOptionPane.ERROR_MESSAGE);
120 * 新しいMIDIシーケンスを生成するダイアログを構築します。
121 * @param playlist シーケンス追加先プレイリスト
122 * @param midiOutDevice 操作音を出力するMIDI出力デバイス
124 public NewSequenceDialog(PlaylistTableModel playlist, VirtualMidiDevice midiOutDevice) {
125 this.playlist = playlist;
126 trackSpecPanel.setChannels(midiOutDevice.getChannels());
127 setTitle("Generate new sequence - " + ChordHelperApplet.VersionInfo.NAME);
128 add(new JTabbedPane() {{
129 add("Sequence", new JPanel() {{
130 setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
132 setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
133 add(new JLabel("Sequence name:"));
137 setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
138 add(new JLabel("Resolution in PPQ ="));
140 add(measureSelecter);
142 add(new JButton("Randomize (Tempo, Time signature, Chord progression)") {{
143 setMargin(ZERO_INSETS);
144 addActionListener(new ActionListener() {
146 public void actionPerformed(ActionEvent e) {
147 setRandomChordProgression(
148 measureSelecter.getMeasureDuration()
154 setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
157 add(new JLabel("Time signature ="));
158 add(timesigSelecter);
162 setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
163 add(new JLabel("Chord progression :"));
164 add(new JLabel("Transpose"));
165 add(new JButton(" + Up ") {{
166 setMargin(ZERO_INSETS);
167 addActionListener(new ActionListener() {
169 public void actionPerformed(ActionEvent e) {
170 ChordProgression cp = createChordProgression();
172 setChordProgression(cp);
176 add(new JButton(" - Down ") {{
177 setMargin(ZERO_INSETS);
178 addActionListener(new ActionListener() {
180 public void actionPerformed(ActionEvent e) {
181 ChordProgression cp = createChordProgression();
183 setChordProgression(cp);
187 add(new JButton(" Enharmonic ") {{
188 setMargin(ZERO_INSETS);
189 addActionListener(new ActionListener() {
191 public void actionPerformed(ActionEvent e) {
192 ChordProgression cp = createChordProgression();
193 cp.toggleEnharmonically();
194 setChordProgression(cp);
198 add(new JButton("Relative key") {{
199 setMargin(ZERO_INSETS);
200 addActionListener(new ActionListener() {
202 public void actionPerformed(ActionEvent e) {
203 ChordProgression cp = createChordProgression();
204 cp.toggleKeyMajorMinor();
205 setChordProgression(cp);
210 add(new JScrollPane(chordText));
212 setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
213 add(new JButton(generateAction){{setMargin(ZERO_INSETS);}});
216 add("Track", trackSpecPanel);
218 setBounds( 250, 200, 600, 540 );
224 private ChordProgression createChordProgression() {
225 return new ChordProgression(chordText.getText());
228 * MIDIシーケンスを生成して返します。
231 public Sequence getMidiSequence() {
232 FirstTrackSpec firstTrackSpec = new FirstTrackSpec(
233 seqNameText.getText(),
234 tempoSelecter.getTempoByteArray(),
235 timesigSelecter.getByteArray()
237 return createChordProgression().toMidiSequence(
238 (int)ppqComboBox.getSelectedItem(),
239 measureSelecter.getStartMeasurePosition(),
240 measureSelecter.getEndMeasurePosition(),
242 trackSpecPanel.getTrackSpecs()
246 * コード進行を設定します。テキスト欄に反映されます。
249 public void setChordProgression(ChordProgression cp) {
250 chordText.setText(cp.toString());
253 * テンポ・拍子・コード進行をランダムに設定
254 * @param measureLength 小節数
256 public void setRandomChordProgression(int measureLength) {
257 tempoSelecter.setTempo( 80 + (int)(Math.random() * 100) );
258 int timesig_upper = 4;
259 int timesig_lower_index = 2;
260 switch( (int)(Math.random() * 10) ) {
261 case 0: timesig_upper = 3; break; // 3/4
263 timesigSelecter.setValue((byte)timesig_upper, (byte)timesig_lower_index);
264 setChordProgression(new ChordProgression(measureLength, timesig_upper));
269 private static class TrackSpecPanel extends JPanel
270 implements PianoKeyboardListener, ActionListener, ChangeListener
272 JComboBox<AbstractNoteTrackSpec> trackSelecter = new JComboBox<>();
273 JLabel trackTypeLabel = new JLabel();
274 JTextField nameTextField = new JTextField(20);
275 MidiChannelComboSelecter chSelecter =
276 new MidiChannelComboSelecter("MIDI Channel:");
277 MidiProgramSelecter pgSelecter = new MidiProgramSelecter();
278 MidiProgramFamilySelecter pgFamilySelecter =
279 new MidiProgramFamilySelecter(pgSelecter) {{
280 pgSelecter.setFamilySelecter(pgFamilySelecter);
282 PianoKeyboardPanel keyboardPanel = new PianoKeyboardPanel() {{
283 keyboard.octaveSizeModel.setValue(6);
284 keyboard.setPreferredSize(new Dimension(400,40));
285 keyboard.setMaxSelectable(2);
287 JPanel rangePanel = new JPanel() {{
288 add( new JLabel("Range:") );
291 JCheckBox randomMelodyCheckbox = new JCheckBox("Random melody");
292 JCheckBox bassCheckbox = new JCheckBox("Bass note");
293 JCheckBox randomLyricCheckbox = new JCheckBox("Random lyrics");
294 JCheckBox nsx39Checkbox = new JCheckBox("NSX-39");;
295 BeatPadPanel beatPadPanel = new BeatPadPanel(this);
296 private MidiChannel[] midiChannels;
298 public TrackSpecPanel() {
299 nameTextField.addActionListener(this);
300 keyboardPanel.keyboard.addPianoKeyboardListener(this);
302 add(new JLabel("Track select:"));
307 add(new JLabel("Track name (Press [Enter] key to change):"));
311 add(new VelocitySelecter(keyboardPanel.keyboard.velocityModel));
313 add(pgFamilySelecter);
317 bassCheckbox.addChangeListener(this);
319 randomMelodyCheckbox.addChangeListener(this);
320 add(randomMelodyCheckbox);
321 randomLyricCheckbox.addChangeListener(this);
322 add(randomLyricCheckbox);
323 nsx39Checkbox.addChangeListener(this);
326 trackSelecter.addActionListener(this);
327 chSelecter.comboBox.addActionListener(this);
328 keyboardPanel.keyboard.velocityModel.addChangeListener(
329 new ChangeListener() {
330 public void stateChanged(ChangeEvent e) {
331 AbstractNoteTrackSpec ants = getTrackSpec();
332 ants.velocity = keyboardPanel.keyboard.velocityModel.getValue();
336 pgSelecter.addActionListener(this);
339 public void stateChanged(ChangeEvent e) {
340 Object src = e.getSource();
341 if( src == bassCheckbox ) {
342 AbstractNoteTrackSpec ants = getTrackSpec();
343 if( ants instanceof MelodyTrackSpec ) {
344 MelodyTrackSpec mts = (MelodyTrackSpec)ants;
345 mts.isBass = bassCheckbox.isSelected();
348 else if( src == randomMelodyCheckbox ) {
349 AbstractNoteTrackSpec ants = getTrackSpec();
350 if( ants instanceof MelodyTrackSpec ) {
351 MelodyTrackSpec mts = (MelodyTrackSpec)ants;
352 mts.randomMelody = randomMelodyCheckbox.isSelected();
355 else if( src == randomLyricCheckbox ) {
356 AbstractNoteTrackSpec ants = getTrackSpec();
357 if( ants instanceof MelodyTrackSpec ) {
358 MelodyTrackSpec mts = (MelodyTrackSpec)ants;
359 mts.randomLyric = randomLyricCheckbox.isSelected();
362 else if( src == nsx39Checkbox ) {
363 AbstractNoteTrackSpec ants = getTrackSpec();
364 if( ants instanceof MelodyTrackSpec ) {
365 MelodyTrackSpec mts = (MelodyTrackSpec)ants;
366 mts.nsx39 = nsx39Checkbox.isSelected();
371 public void actionPerformed(ActionEvent e) {
372 Object src = e.getSource();
373 AbstractNoteTrackSpec ants;
374 if( src == nameTextField ) {
375 getTrackSpec().name = nameTextField.getText();
377 else if( src == trackSelecter ) {
378 ants = (AbstractNoteTrackSpec)(trackSelecter.getSelectedItem());
379 String trackTypeString = "Track type: " + (
380 ants instanceof DrumTrackSpec ? "Percussion" :
381 ants instanceof MelodyTrackSpec ? "Melody" : "(Unknown)"
383 trackTypeLabel.setText(trackTypeString);
384 nameTextField.setText(ants.name);
385 chSelecter.setSelectedChannel(ants.midiChannel);
386 keyboardPanel.keyboard.velocityModel.setValue(ants.velocity);
387 pgSelecter.setProgram(ants.programNumber);
388 keyboardPanel.keyboard.clear();
389 if( ants instanceof DrumTrackSpec ) {
390 rangePanel.setVisible(false);
391 randomMelodyCheckbox.setVisible(false);
392 randomLyricCheckbox.setVisible(false);
393 nsx39Checkbox.setVisible(false);
394 bassCheckbox.setVisible(false);
396 else if( ants instanceof MelodyTrackSpec ) {
397 MelodyTrackSpec ts = (MelodyTrackSpec)ants;
398 rangePanel.setVisible(true);
399 keyboardPanel.keyboard.setSelectedNote(ts.range.min_note);
400 keyboardPanel.keyboard.setSelectedNote(ts.range.max_note);
401 keyboardPanel.keyboard.autoScroll(ts.range.min_note);
402 randomMelodyCheckbox.setSelected(ts.randomMelody);
403 randomLyricCheckbox.setSelected(ts.randomLyric);
404 bassCheckbox.setSelected(ts.isBass);
405 randomMelodyCheckbox.setVisible(true);
406 randomLyricCheckbox.setVisible(true);
407 nsx39Checkbox.setVisible(true);
408 bassCheckbox.setVisible(true);
410 beatPadPanel.setTrackSpec(ants);
412 else if( src == chSelecter.comboBox ) {
413 getTrackSpec().midiChannel = chSelecter.getSelectedChannel();
415 else if( src == pgSelecter ) {
416 getTrackSpec().programNumber = pgSelecter.getProgram();
420 public void pianoKeyPressed(int n, InputEvent e) {
422 AbstractNoteTrackSpec ants = getTrackSpec();
423 if( ants instanceof MelodyTrackSpec ) {
424 MelodyTrackSpec ts = (MelodyTrackSpec)ants;
425 ts.range = new Range(keyboardPanel.keyboard.getSelectedNotes());
429 public void pianoKeyReleased(int n, InputEvent e) { noteOff(n); }
430 public void octaveMoved(ChangeEvent event) {}
431 public void octaveResized(ChangeEvent event) {}
432 public void noteOn(int n) {
433 if( midiChannels == null ) return;
434 MidiChannel mc = midiChannels[chSelecter.getSelectedChannel()];
435 mc.noteOn( n, keyboardPanel.keyboard.velocityModel.getValue() );
437 public void noteOff(int n) {
438 if( midiChannels == null ) return;
439 MidiChannel mc = midiChannels[chSelecter.getSelectedChannel()];
440 mc.noteOff( n, keyboardPanel.keyboard.velocityModel.getValue() );
442 public void setChannels( MidiChannel midiChannels[] ) {
443 this.midiChannels = midiChannels;
445 public AbstractNoteTrackSpec getTrackSpec() {
446 Object trackSpecObj = trackSelecter.getSelectedItem();
447 AbstractNoteTrackSpec ants = (AbstractNoteTrackSpec)trackSpecObj;
448 ants.name = nameTextField.getText();
451 public Vector<AbstractNoteTrackSpec> getTrackSpecs() {
452 Vector<AbstractNoteTrackSpec> trackSpecs = new Vector<>();
453 int i=0, n_items = trackSelecter.getItemCount();
454 while( i < n_items ) {
455 trackSpecs.add((AbstractNoteTrackSpec)trackSelecter.getItemAt(i++));
459 public void addTrackSpec(AbstractNoteTrackSpec trackSpec) {
460 trackSelecter.addItem(trackSpec);
463 private static class MeasureSelecter extends JPanel {
464 public MeasureSelecter() {
465 setLayout(new GridLayout(2,3));
467 add(new JLabel("Start",JLabel.CENTER));
468 add(new JLabel("End",JLabel.CENTER));
469 add(new JLabel("Measure",JLabel.RIGHT));
470 add(new JSpinner(startModel));
471 add(new JSpinner(endModel));
473 private SpinnerNumberModel startModel = new SpinnerNumberModel( 3, 1, 9999, 1 );
474 private SpinnerNumberModel endModel = new SpinnerNumberModel( 8, 1, 9999, 1 );
475 public int getStartMeasurePosition() {
476 return startModel.getNumber().intValue();
478 public int getEndMeasurePosition() {
479 return endModel.getNumber().intValue();
481 public int getMeasureDuration() {
482 return getEndMeasurePosition() - getStartMeasurePosition() + 1;
485 //////////////////////////////////////////////////////////////////
490 private static class BeatPadPanel extends JPanel implements ActionListener {
491 PianoKeyboardListener piano_keyboard_listener;
492 JPanel percussion_selecters_panel;
493 java.util.List<JComboBox<String>> percussionSelecters =
494 new ArrayList<JComboBox<String>>() {
496 for( int i=0; i < DrumTrackSpec.defaultPercussions.length; i++ ) {
497 add(new JComboBox<String>());
503 public BeatPadPanel(PianoKeyboardListener pkl) {
504 piano_keyboard_listener = pkl;
505 percussion_selecters_panel = new JPanel();
506 percussion_selecters_panel.setLayout(
507 new BoxLayout( percussion_selecters_panel, BoxLayout.Y_AXIS )
509 for( JComboBox<String> cb : percussionSelecters ) {
510 percussion_selecters_panel.add(cb);
511 cb.addActionListener(this);
513 add( percussion_selecters_panel );
514 add( beat_pad = new BeatPad(pkl) );
515 beat_pad.setPreferredSize( new Dimension(400,200) );
516 setLayout( new BoxLayout( this, BoxLayout.X_AXIS ) );
518 public void actionPerformed(ActionEvent e) {
519 Object src = e.getSource();
520 for( JComboBox<String> cb : percussionSelecters ) {
521 if( src != cb ) continue;
523 (DrumTrackSpec.PercussionComboBoxModel)cb.getModel()
524 ).getSelectedNoteNo();
525 piano_keyboard_listener.pianoKeyPressed(note_no,(InputEvent)null);
528 public void setTrackSpec( AbstractNoteTrackSpec ants ) {
529 beat_pad.setTrackSpec(ants);
530 if( ants instanceof DrumTrackSpec ) {
531 DrumTrackSpec dts = (DrumTrackSpec)ants;
533 for( JComboBox<String> cb : percussionSelecters ) {
534 cb.setModel(dts.models[i++]);
536 percussion_selecters_panel.setVisible(true);
538 else if( ants instanceof MelodyTrackSpec ) {
539 percussion_selecters_panel.setVisible(false);
543 private static class BeatPad extends JComponent implements MouseListener, ComponentListener {
544 PianoKeyboardListener piano_keyboard_listener;
545 private int on_note_no = -1;
546 AbstractNoteTrackSpec track_spec;
548 public static final int MAX_BEATS = 16;
549 Rectangle beat_buttons[][];
550 Rectangle continuous_beat_buttons[][];
552 public BeatPad(PianoKeyboardListener pkl) {
553 piano_keyboard_listener = pkl;
554 addMouseListener(this);
555 addComponentListener(this);
556 // addMouseMotionListener(this);
558 public void paint(Graphics g) {
560 Graphics2D g2 = (Graphics2D) g;
562 int note, beat, mask;
564 if( track_spec instanceof DrumTrackSpec ) {
565 DrumTrackSpec dts = (DrumTrackSpec)track_spec;
566 for( note=0; note<dts.beat_patterns.length; note++ ) {
567 for( beat=0, mask=0x8000; beat<MAX_BEATS; beat++, mask >>>= 1 ) {
568 r = beat_buttons[note][beat];
569 if( (dts.beat_patterns[note] & mask) != 0 )
570 g2.fillRect( r.x, r.y, r.width, r.height );
572 g2.drawRect( r.x, r.y, r.width, r.height );
576 else if( track_spec instanceof MelodyTrackSpec ) {
577 MelodyTrackSpec mts = (MelodyTrackSpec)track_spec;
578 for( beat=0, mask=0x8000; beat<MAX_BEATS; beat++, mask >>>= 1 ) {
579 r = beat_buttons[0][beat];
580 if( (mts.beatPattern & mask) != 0 )
581 g2.fillRect( r.x, r.y, r.width, r.height );
583 g2.drawRect( r.x, r.y, r.width, r.height );
584 r = continuous_beat_buttons[0][beat];
585 if( (mts.continuousBeatPattern & mask) != 0 )
586 g2.fillRect( r.x, r.y, r.width, r.height );
588 g2.drawRect( r.x, r.y, r.width, r.height );
593 public void componentShown(ComponentEvent e) { }
594 public void componentHidden(ComponentEvent e) { }
595 public void componentMoved(ComponentEvent e) { }
596 public void componentResized(ComponentEvent e) {
599 public void mousePressed(MouseEvent e) {
601 if( on_note_no >= 0 ) {
602 piano_keyboard_listener.pianoKeyPressed( on_note_no ,(InputEvent)e );
605 public void mouseReleased(MouseEvent e) {
606 if( on_note_no >= 0 ) {
607 piano_keyboard_listener.pianoKeyReleased( on_note_no ,(InputEvent)e );
611 public void mouseEntered(MouseEvent e) {
612 if((e.getModifiers() & InputEvent.BUTTON1_MASK) == InputEvent.BUTTON1_MASK) {
616 public void mouseExited(MouseEvent e) { }
617 public void mouseClicked(MouseEvent e) { }
618 private void sizeChanged() {
619 int beat, note, width, height;
620 Dimension d = getSize();
622 if( track_spec instanceof DrumTrackSpec ) {
623 DrumTrackSpec dts = (DrumTrackSpec)track_spec;
624 num_notes = dts.models.length;
626 beat_buttons = new Rectangle[num_notes][];
627 continuous_beat_buttons = new Rectangle[num_notes][];
628 for( note=0; note<beat_buttons.length; note++ ) {
629 beat_buttons[note] = new Rectangle[MAX_BEATS];
630 continuous_beat_buttons[note] = new Rectangle[MAX_BEATS];
631 for( beat=0; beat<MAX_BEATS; beat++ ) {
632 width = (d.width * 3) / (MAX_BEATS * 4);
633 height = d.height / num_notes - 1;
634 beat_buttons[note][beat] = new Rectangle(
635 beat * d.width / MAX_BEATS,
640 width = d.width / (MAX_BEATS * 3);
641 continuous_beat_buttons[note][beat] = new Rectangle(
642 (beat+1) * d.width / MAX_BEATS - width + 1,
643 note * height + height / 3,
650 private void catchEvent(MouseEvent e) {
651 Point point = e.getPoint();
652 int note, beat, mask;
655 if( track_spec instanceof DrumTrackSpec ) {
656 DrumTrackSpec dts = (DrumTrackSpec)track_spec;
657 for( note=0; note<dts.beat_patterns.length; note++ ) {
658 for( beat=0, mask=0x8000; beat<MAX_BEATS; beat++, mask >>>= 1 ) {
659 if( beat_buttons[note][beat].contains(point) ) {
660 dts.beat_patterns[note] ^= mask;
661 on_note_no = dts.models[note].getSelectedNoteNo();
667 else if( track_spec instanceof MelodyTrackSpec ) {
668 MelodyTrackSpec mts = (MelodyTrackSpec)track_spec;
669 for( beat=0, mask=0x8000; beat<MAX_BEATS; beat++, mask >>>= 1 ) {
670 if( beat_buttons[0][beat].contains(point) ) {
671 mts.beatPattern ^= mask;
674 if( continuous_beat_buttons[0][beat].contains(point) ) {
675 mts.continuousBeatPattern ^= mask;
681 public void setTrackSpec( AbstractNoteTrackSpec ants ) {