• R/O
  • HTTP
  • SSH
  • HTTPS

MIDIChordHelper: Commit

Javaアプリ MIDI Chord Helper のソースコード


Commit MetaInfo

Revision789637b9e9e5ca67609dab51344310d1c45f2fbd (tree)
Time2017-05-18 23:11:26
AuthorAkiyoshi Kamide <kamide@yk.r...>
CommiterAkiyoshi Kamide

Log Message

新シーケンス作成画面に文字コード選択プルダウンを追加

Change Summary

Incremental Difference

--- a/src/camidion/chordhelper/ChordHelperApplet.java
+++ b/src/camidion/chordhelper/ChordHelperApplet.java
@@ -13,6 +13,7 @@ import java.io.IOException;
1313 import java.net.URI;
1414 import java.net.URISyntaxException;
1515 import java.net.URL;
16+import java.nio.charset.Charset;
1617 import java.util.Arrays;
1718
1819 import javax.sound.midi.InvalidMidiDataException;
@@ -60,6 +61,7 @@ import camidion.chordhelper.midieditor.TempoSelecter;
6061 import camidion.chordhelper.midieditor.TimeSignatureSelecter;
6162 import camidion.chordhelper.music.Chord;
6263 import camidion.chordhelper.music.Key;
64+import camidion.chordhelper.music.MIDISpec;
6365 import camidion.chordhelper.music.Range;
6466 import camidion.chordhelper.pianokeyboard.MidiKeyboardPanel;
6567 import camidion.chordhelper.pianokeyboard.PianoKeyboardAdapter;
@@ -95,7 +97,7 @@ public class ChordHelperApplet extends JApplet {
9597 public int addRandomSongToPlaylist(int measureLength) throws InvalidMidiDataException {
9698 NewSequenceDialog d = midiEditor.newSequenceDialog;
9799 d.setRandomChordProgression(measureLength);
98- int index = playlistModel.play(d.getMidiSequence());
100+ int index = playlistModel.play(d.getMidiSequence(), d.getSelectedCharset());
99101 midiEditor.playlistTable.getSelectionModel().setSelectionInterval(index, index);
100102 return index;
101103 }
@@ -113,7 +115,9 @@ public class ChordHelperApplet extends JApplet {
113115 URL url = (new URI(midiFileUrl)).toURL();
114116 String filename = url.getFile().replaceFirst("^.*/","");
115117 Sequence sequence = MidiSystem.getSequence(url);
116- int index = playlistModel.add(sequence, filename);
118+ Charset charset = MIDISpec.getCharsetOf(sequence);
119+ if( charset == null ) charset = Charset.defaultCharset();
120+ int index = playlistModel.add(sequence, charset, filename);
117121 midiEditor.playlistTable.getSelectionModel().setSelectionInterval(index, index);
118122 return index;
119123 } catch( URISyntaxException|IOException|InvalidMidiDataException e ) {
@@ -270,7 +274,7 @@ public class ChordHelperApplet extends JApplet {
270274 */
271275 public static class VersionInfo {
272276 public static final String NAME = "MIDI Chord Helper";
273- public static final String VERSION = "Ver.20170517.1";
277+ public static final String VERSION = "Ver.20170518.1";
274278 public static final String COPYRIGHT = "Copyright (C) 2004-2017";
275279 public static final String AUTHER = "@きよし - Akiyoshi Kamide";
276280 public static final String URL = "http://www.yk.rim.or.jp/~kamide/music/chordhelper/";
@@ -407,7 +411,7 @@ public class ChordHelperApplet extends JApplet {
407411 break;
408412 }
409413 });
410- // シーケンサーの再生時間位置、またはシーケンサーにロード中のシーケンスが変更されたときに呼び出されるリスナーを登録
414+ // 再生時間位置の移動、シーケンス名の変更、またはシーケンスの入れ替えが発生したときに呼び出されるリスナーを登録
411415 JLabel songTitleLabel = new JLabel();
412416 sequencerModel.addChangeListener(e->{
413417 Sequencer sequencer = sequencerModel.getSequencer();
--- a/src/camidion/chordhelper/mididevice/MidiSequencerModel.java
+++ b/src/camidion/chordhelper/mididevice/MidiSequencerModel.java
@@ -249,11 +249,17 @@ public class MidiSequencerModel extends MidiDeviceModel implements BoundedRangeM
249249 listenerList.remove(ChangeListener.class, listener);
250250 }
251251 /**
252- * 秒位置が変わったことをリスナーに通知します。
253- * <p>登録中のすべての {@link ChangeListener} について
252+ * 登録中のすべての {@link ChangeListener} の
254253 * {@link ChangeListener#stateChanged(ChangeEvent)}
255- * を呼び出すことによって状態の変化を通知します。
254+ * を呼び出します。
256255 * </p>
256+ * <p>次のような状態変更を通知したいときに呼び出します。
257+ * </p>
258+ * <ul>
259+ * <li>秒位置の移動</li>
260+ * <li>ロードされているシーケンス名の変更</li>
261+ * <li>ロードされているシーケンスの入れ替え</li>
262+ * </ul>
257263 */
258264 public void fireStateChanged() {
259265 Object[] listeners = listenerList.getListenerList();
--- a/src/camidion/chordhelper/midieditor/Base64Dialog.java
+++ b/src/camidion/chordhelper/midieditor/Base64Dialog.java
@@ -4,11 +4,13 @@ import java.awt.event.ActionEvent;
44 import java.io.ByteArrayInputStream;
55 import java.io.IOException;
66 import java.io.InputStream;
7+import java.nio.charset.Charset;
78 import java.util.Base64;
89 import java.util.regex.Pattern;
910
1011 import javax.sound.midi.InvalidMidiDataException;
1112 import javax.sound.midi.MidiSystem;
13+import javax.sound.midi.Sequence;
1214 import javax.swing.AbstractAction;
1315 import javax.swing.Action;
1416 import javax.swing.Box;
@@ -24,6 +26,7 @@ import javax.swing.event.DocumentListener;
2426
2527 import camidion.chordhelper.ButtonIcon;
2628 import camidion.chordhelper.ChordHelperApplet;
29+import camidion.chordhelper.music.MIDISpec;
2730
2831 /**
2932 * Base64テキスト入力ダイアログ
@@ -54,7 +57,10 @@ public class Base64Dialog extends JDialog implements DocumentListener {
5457 return -1;
5558 }
5659 try (InputStream in = new ByteArrayInputStream(midiData)) {
57- int index = playlistTable.getModel().add(MidiSystem.getSequence(in), null);
60+ Sequence sequence = MidiSystem.getSequence(in);
61+ Charset charset = MIDISpec.getCharsetOf(sequence);
62+ if( charset == null ) charset = Charset.defaultCharset();
63+ int index = playlistTable.getModel().add(sequence, charset, null);
5864 playlistTable.getSelectionModel().setSelectionInterval(index, index);
5965 return index;
6066 } catch( IOException|InvalidMidiDataException e ) {
--- /dev/null
+++ b/src/camidion/chordhelper/midieditor/CharsetComboBox.java
@@ -0,0 +1,15 @@
1+package camidion.chordhelper.midieditor;
2+
3+import java.nio.charset.Charset;
4+
5+import javax.swing.JComboBox;
6+
7+public class CharsetComboBox extends JComboBox<Charset> {
8+ {
9+ Charset.availableCharsets().values().stream().forEach(v->addItem(v));
10+ setSelectedItem(Charset.defaultCharset());
11+ }
12+ public Charset getSelectedCharset() {
13+ return (Charset)getSelectedItem();
14+ }
15+}
--- a/src/camidion/chordhelper/midieditor/NewSequenceDialog.java
+++ b/src/camidion/chordhelper/midieditor/NewSequenceDialog.java
@@ -13,6 +13,7 @@ import java.awt.event.ComponentListener;
1313 import java.awt.event.InputEvent;
1414 import java.awt.event.MouseEvent;
1515 import java.awt.event.MouseListener;
16+import java.nio.charset.Charset;
1617 import java.util.ArrayList;
1718 import java.util.Vector;
1819
@@ -61,6 +62,7 @@ public class NewSequenceDialog extends JDialog {
6162 "Key: C\nC G/B | Am Em/G | F C/E | Dm7 G7 C % | F G7 | Csus4 C\n";
6263 private JTextArea chordText = new JTextArea(INITIAL_CHORD_STRING, 18, 30);
6364 private JTextField seqNameText = new JTextField();
65+ private CharsetComboBox charsetSelecter = new CharsetComboBox();
6466 private JComboBox<Integer> ppqComboBox = new JComboBox<Integer>(PPQList);
6567 private TimeSignatureSelecter timesigSelecter = new TimeSignatureSelecter();
6668 private TempoSelecter tempoSelecter = new TempoSelecter();
@@ -103,16 +105,20 @@ public class NewSequenceDialog extends JDialog {
103105 @Override
104106 public void actionPerformed(ActionEvent event) {
105107 try {
106- int index = playlistTable.play(getMidiSequence());
108+ int index = playlistTable.play(getMidiSequence(), getSelectedCharset());
107109 playlistTable.getModel().getSequenceModelList().get(index).setModified(true);
108110 } catch (Exception ex) {
109111 JOptionPane.showMessageDialog(
110112 NewSequenceDialog.this, ex,
111113 ChordHelperApplet.VersionInfo.NAME, JOptionPane.ERROR_MESSAGE);
114+ ex.printStackTrace();
112115 }
113116 setVisible(false);
114117 }
115118 };
119+ public Charset getSelectedCharset() {
120+ return charsetSelecter.getSelectedCharset();
121+ }
116122 /**
117123 * 新しいMIDIシーケンスを生成するダイアログを構築します。
118124 * @param playlist シーケンス追加先プレイリスト
@@ -129,6 +135,8 @@ public class NewSequenceDialog extends JDialog {
129135 setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
130136 add(new JLabel("Sequence name:"));
131137 add(seqNameText);
138+ add(new JLabel("Character set:"));
139+ add(charsetSelecter);
132140 }});
133141 add(new JPanel() {{
134142 setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
@@ -219,7 +227,8 @@ public class NewSequenceDialog extends JDialog {
219227 measureSelecter.getStartMeasurePosition(),
220228 measureSelecter.getEndMeasurePosition(),
221229 firstTrackSpec,
222- trackSpecPanel.getTrackSpecs()
230+ trackSpecPanel.getTrackSpecs(),
231+ charsetSelecter.getSelectedCharset()
223232 );
224233 }
225234 /**
--- a/src/camidion/chordhelper/midieditor/PlaylistTable.java
+++ b/src/camidion/chordhelper/midieditor/PlaylistTable.java
@@ -25,7 +25,6 @@ import javax.swing.Action;
2525 import javax.swing.DefaultCellEditor;
2626 import javax.swing.Icon;
2727 import javax.swing.JButton;
28-import javax.swing.JComboBox;
2928 import javax.swing.JComponent;
3029 import javax.swing.JFileChooser;
3130 import javax.swing.JOptionPane;
@@ -45,6 +44,7 @@ import javax.swing.table.TableColumnModel;
4544
4645 import camidion.chordhelper.ChordHelperApplet;
4746 import camidion.chordhelper.mididevice.MidiSequencerModel;
47+import camidion.chordhelper.music.MIDISpec;
4848
4949 /**
5050 * プレイリストビュー(シーケンスリスト)
@@ -117,9 +117,7 @@ public class PlaylistTable extends JTable {
117117 //
118118 // 文字コード選択をプルダウンにする
119119 getColumnModel().getColumn(PlaylistTableModel.Column.CHARSET.ordinal())
120- .setCellEditor(new DefaultCellEditor(new JComboBox<Charset>() {{
121- Charset.availableCharsets().values().stream().forEach(v->addItem(v));
122- }}));
120+ .setCellEditor(new DefaultCellEditor(new CharsetComboBox()));
123121 setAutoCreateColumnsFromModel(false);
124122 //
125123 // Base64画面を開くアクションの生成
@@ -328,7 +326,10 @@ public class PlaylistTable extends JTable {
328326 while(itr.hasNext()) {
329327 File file = itr.next();
330328 try (FileInputStream in = new FileInputStream(file)) {
331- int lastIndex = ((PlaylistTableModel)dataModel).add(MidiSystem.getSequence(in), file.getName());
329+ Sequence sequence = MidiSystem.getSequence(in);
330+ Charset charset = MIDISpec.getCharsetOf(sequence);
331+ if( charset == null ) charset = Charset.defaultCharset();
332+ int lastIndex = ((PlaylistTableModel)dataModel).add(sequence, charset, file.getName());
332333 if( firstIndex < 0 ) firstIndex = lastIndex;
333334 } catch(IOException|InvalidMidiDataException e) {
334335 String message = "Could not open as MIDI file "+file+"\n"+e;
@@ -358,12 +359,13 @@ public class PlaylistTable extends JTable {
358359 /**
359360 * 指定されたシーケンスを追加して再生します。
360361 * @param sequence 再生するシーケンス
362+ * @param charset 文字コード
361363 * @return 追加されたシーケンスのインデックス(先頭が 0)
362364 * @throws InvalidMidiDataException {@link Sequencer#setSequence(Sequence)} を参照
363365 * @throws IllegalStateException MIDIシーケンサデバイスが閉じている場合
364366 */
365- public int play(Sequence sequence) throws InvalidMidiDataException {
366- int index = getModel().play(sequence);
367+ public int play(Sequence sequence, Charset charset) throws InvalidMidiDataException {
368+ int index = getModel().play(sequence, charset);
367369 selectionModel.setSelectionInterval(index, index);
368370 return index;
369371 }
--- a/src/camidion/chordhelper/midieditor/PlaylistTableModel.java
+++ b/src/camidion/chordhelper/midieditor/PlaylistTableModel.java
@@ -35,7 +35,7 @@ public class PlaylistTableModel extends AbstractTableModel {
3535 /**
3636 * 空のトラックリストモデル
3737 */
38- public final SequenceTrackListTableModel emptyTrackListTableModel = new SequenceTrackListTableModel(this, null, null);
38+ public final SequenceTrackListTableModel emptyTrackListTableModel = new SequenceTrackListTableModel(this, null, null, null);
3939 /**
4040 * 空のイベントリストモデル
4141 */
@@ -344,12 +344,15 @@ public class PlaylistTableModel extends AbstractTableModel {
344344 /**
345345 * MIDIシーケンスを追加します。
346346 * @param sequence MIDIシーケンス(nullの場合、シーケンスを自動生成して追加)
347+ * @param charset MIDIシーケンス内のテキスト文字コード
347348 * @param filename ファイル名(nullの場合、ファイル名なし)
348349 * @return 追加されたシーケンスのインデックス(先頭が 0)
349350 */
350- public int add(Sequence sequence, String filename) {
351- if( sequence == null ) sequence = (new ChordProgression()).toMidiSequence();
352- sequenceModelList.add(new SequenceTrackListTableModel(this, sequence, filename));
351+ public int add(Sequence sequence, Charset charset, String filename) {
352+ if( sequence == null ) {
353+ sequence = (new ChordProgression()).toMidiSequence(charset);
354+ }
355+ sequenceModelList.add(new SequenceTrackListTableModel(this, sequence, charset, filename));
353356 int lastIndex = sequenceModelList.size() - 1;
354357 fireTableRowsInserted(lastIndex, lastIndex);
355358 return lastIndex;
@@ -405,12 +408,13 @@ public class PlaylistTableModel extends AbstractTableModel {
405408 /**
406409 * 指定されたMIDIシーケンスをこのプレイリストに追加し、再生されていなければ追加した曲から再生します。
407410 * @param sequence MIDIシーケンス
411+ * @param charset 文字コード
408412 * @return 追加されたシーケンスのインデックス(先頭が 0)
409413 * @throws InvalidMidiDataException {@link Sequencer#setSequence(Sequence)} を参照
410414 * @throws IllegalStateException MIDIシーケンサデバイスが閉じている場合
411415 */
412- public int play(Sequence sequence) throws InvalidMidiDataException {
413- int lastIndex = add(sequence,"");
416+ public int play(Sequence sequence, Charset charset) throws InvalidMidiDataException {
417+ int lastIndex = add(sequence, charset, "");
414418 if( ! sequencerModel.getSequencer().isRunning() ) play(lastIndex);
415419 return lastIndex;
416420 }
--- a/src/camidion/chordhelper/midieditor/SequenceTrackListTableModel.java
+++ b/src/camidion/chordhelper/midieditor/SequenceTrackListTableModel.java
@@ -85,14 +85,17 @@ public class SequenceTrackListTableModel extends AbstractTableModel {
8585 * MIDIシーケンスとファイル名から {@link SequenceTrackListTableModel} を構築します。
8686 * @param sequenceListTableModel 親のプレイリスト
8787 * @param sequence MIDIシーケンス
88+ * @param charset MIDIシーケンスのテキスト文字コード
8889 * @param filename ファイル名
8990 */
9091 public SequenceTrackListTableModel(
9192 PlaylistTableModel sequenceListTableModel,
9293 Sequence sequence,
94+ Charset charset,
9395 String filename
9496 ) {
9597 this.sequenceListTableModel = sequenceListTableModel;
98+ this.charset = charset;
9699 setSequence(sequence);
97100 setFilename(filename);
98101 }
@@ -244,12 +247,7 @@ public class SequenceTrackListTableModel extends AbstractTableModel {
244247 //
245248 // トラックリストを再構築
246249 Track tracks[] = sequence.getTracks();
247- for(Track track : tracks) {
248- trackModelList.add(new MidiEventTableModel(this, track));
249- }
250- // 文字コードの判定
251- Charset cs = MIDISpec.getCharsetOf(sequence);
252- charset = cs==null ? Charset.defaultCharset() : cs;
250+ for(Track track : tracks) trackModelList.add(new MidiEventTableModel(this, track));
253251 //
254252 // トラックが挿入されたことを通知
255253 fireTableRowsInserted(0, tracks.length-1);
@@ -280,6 +278,7 @@ public class SequenceTrackListTableModel extends AbstractTableModel {
280278 */
281279 @Override
282280 public String toString() {
281+ if( sequence == null ) return "";
283282 byte b[] = MIDISpec.getNameBytesOf(sequence);
284283 return b == null ? "" : new String(b, charset);
285284 }
@@ -290,10 +289,12 @@ public class SequenceTrackListTableModel extends AbstractTableModel {
290289 * @return 成功したらtrue
291290 */
292291 public boolean setName(String name) {
293- if( name.equals(toString()) ) return false;
292+ if( name.equals(toString()) || sequence == null ) return false;
294293 if( ! MIDISpec.setNameBytesOf(sequence, name.getBytes(charset)) ) return false;
295294 setModified(true);
296295 fireTableDataChanged();
296+ if( isOnSequencer() )
297+ sequenceListTableModel.getSequencerModel().fireStateChanged();
297298 return true;
298299 }
299300 /**
@@ -328,7 +329,7 @@ public class SequenceTrackListTableModel extends AbstractTableModel {
328329 * @return トラックモデル(見つからない場合null)
329330 */
330331 public MidiEventTableModel getSelectedTrackModel(ListSelectionModel selectionModel) {
331- if( selectionModel.isSelectionEmpty() ) return null;
332+ if( sequence == null || selectionModel.isSelectionEmpty() ) return null;
332333 Track tracks[] = sequence.getTracks();
333334 if( tracks.length == 0 ) return null;
334335 Track t = tracks[selectionModel.getMinSelectionIndex()];
@@ -340,8 +341,10 @@ public class SequenceTrackListTableModel extends AbstractTableModel {
340341 * @return トラックのインデックス(先頭 0、トラックが見つからない場合 -1)
341342 */
342343 public int indexOf(Track track) {
343- Track tracks[] = sequence.getTracks();
344- for( int i=0; i<tracks.length; i++ ) if( tracks[i] == track ) return i;
344+ if( sequence != null ) {
345+ Track tracks[] = sequence.getTracks();
346+ for( int i=0; i<tracks.length; i++ ) if( tracks[i] == track ) return i;
347+ }
345348 return -1;
346349 }
347350 /**
--- a/src/camidion/chordhelper/music/AbstractNoteTrackSpec.java
+++ b/src/camidion/chordhelper/music/AbstractNoteTrackSpec.java
@@ -1,5 +1,7 @@
11 package camidion.chordhelper.music;
22
3+import java.nio.charset.Charset;
4+
35 import javax.sound.midi.InvalidMidiDataException;
46 import javax.sound.midi.MidiEvent;
57 import javax.sound.midi.MidiMessage;
@@ -30,8 +32,8 @@ public abstract class AbstractNoteTrackSpec extends AbstractTrackSpec {
3032 this(ch,name,programNumber);
3133 this.velocity = velocity;
3234 }
33- public Track createTrack( Sequence seq, FirstTrackSpec firstTrackSpec ) {
34- Track track = super.createTrack( seq, firstTrackSpec );
35+ public Track createTrack( Sequence seq, FirstTrackSpec firstTrackSpec, Charset charset ) {
36+ Track track = super.createTrack( seq, firstTrackSpec, charset );
3537 if( programNumber >= 0 ) addProgram( programNumber, 0 );
3638 return track;
3739 }
--- a/src/camidion/chordhelper/music/AbstractTrackSpec.java
+++ b/src/camidion/chordhelper/music/AbstractTrackSpec.java
@@ -1,5 +1,7 @@
11 package camidion.chordhelper.music;
22
3+import java.nio.charset.Charset;
4+
35 import javax.sound.midi.InvalidMidiDataException;
46 import javax.sound.midi.MetaMessage;
57 import javax.sound.midi.MidiEvent;
@@ -43,10 +45,10 @@ public abstract class AbstractTrackSpec {
4345 * @param firstTrackSpec 最初のトラック仕様
4446 * @return 生成したトラック
4547 */
46- public Track createTrack( Sequence seq, FirstTrackSpec firstTrackSpec ) {
48+ public Track createTrack( Sequence seq, FirstTrackSpec firstTrackSpec, Charset charset ) {
4749 this.firstTrackSpec = firstTrackSpec;
4850 track = (sequence = seq).createTrack();
49- if( name != null ) addStringTo( 0x03, name, 0 );
51+ if( name != null ) addStringTo( 0x03, name, charset, 0 );
5052 minNoteTicks = (long)( seq.getResolution() >> 2 );
5153 return track;
5254 }
@@ -58,14 +60,14 @@ public abstract class AbstractTrackSpec {
5860 * @return {@link Track#add(MidiEvent)} と同じ
5961 */
6062 public boolean addMetaEventTo( int type, byte data[], long tickPos ) {
61- MetaMessage meta_msg = new MetaMessage();
63+ MetaMessage metaMessage = new MetaMessage();
6264 try {
63- meta_msg.setMessage( type, data, data.length );
65+ metaMessage.setMessage( type, data, data.length );
6466 } catch( InvalidMidiDataException ex ) {
6567 ex.printStackTrace();
6668 return false;
6769 }
68- return track.add(new MidiEvent(meta_msg, tickPos));
70+ return track.add(new MidiEvent(metaMessage, tickPos));
6971 }
7072 /**
7173 * 文字列をメタイベントとして追加します。
@@ -74,21 +76,21 @@ public abstract class AbstractTrackSpec {
7476 * @param tickPos tick位置
7577 * @return {@link #addMetaEventTo(int, byte[], long)} と同じ
7678 */
77- public boolean addStringTo( int type, String str, long tickPos ) {
79+ public boolean addStringTo( int type, String str, Charset charset, long tickPos ) {
7880 if( str == null ) str = "";
79- return addMetaEventTo( type, str.getBytes(), tickPos );
81+ return addMetaEventTo(type, str.getBytes(charset), tickPos);
8082 }
81- public boolean addStringTo( int type, ChordProgression.ChordStroke cs ) {
82- return addStringTo(type, cs.chord.toString(), cs.tickRange.startTickPos);
83+ public boolean addStringTo( int type, ChordProgression.ChordStroke cs, Charset charset ) {
84+ return addStringTo(type, cs.chord.toString(), charset, cs.tickRange.startTickPos);
8385 }
84- public boolean addStringTo( int type, ChordProgression.Lyrics lyrics ) {
85- return addStringTo(type, lyrics.text, lyrics.startTickPos);
86+ public boolean addStringTo( int type, ChordProgression.Lyrics lyrics, Charset charset ) {
87+ return addStringTo(type, lyrics.text, charset, lyrics.startTickPos);
8688 }
8789 public boolean addEOT( long tickPos ) {
8890 return addMetaEventTo( 0x2F, new byte[0], tickPos );
8991 }
90- public void setChordSymbolText( ChordProgression cp ) {
91- cp.setChordSymbolTextTo( this );
92+ public void setChordSymbolText(ChordProgression cp, Charset charset) {
93+ cp.setChordSymbolTextTo(this, charset);
9294 }
9395 public boolean addSysEx(byte[] data, long tickPos) {
9496 SysexMessage msg = new SysexMessage();
--- a/src/camidion/chordhelper/music/ChordProgression.java
+++ b/src/camidion/chordhelper/music/ChordProgression.java
@@ -1,5 +1,6 @@
11 package camidion.chordhelper.music;
22
3+import java.nio.charset.Charset;
34 import java.util.ArrayList;
45 import java.util.List;
56 import java.util.Vector;
@@ -435,26 +436,26 @@ public class ChordProgression {
435436 }
436437 }
437438 // コード文字列の書き込み
438- public void setChordSymbolTextTo( AbstractTrackSpec ts ) {
439+ public void setChordSymbolTextTo( AbstractTrackSpec ts, Charset charset ) {
439440 for( Line line : lines ) {
440441 for( Measure measure : line ) {
441442 if( measure.ticks_per_beat == null ) continue;
442443 for( Object element : measure ) {
443444 if( element instanceof ChordStroke ) {
444- ts.addStringTo( 0x01, (ChordStroke)element );
445+ ts.addStringTo( 0x01, (ChordStroke)element, charset );
445446 }
446447 }
447448 }
448449 }
449450 }
450451 // 歌詞の書き込み
451- public void setLyricsTo( AbstractTrackSpec ts ) {
452+ public void setLyricsTo( AbstractTrackSpec ts, Charset charset ) {
452453 for( Line line : lines ) {
453454 for( Measure measure : line ) {
454455 if( measure.ticks_per_beat == null ) continue;
455456 for( Object element : measure ) {
456457 if( element instanceof Lyrics ) {
457- ts.addStringTo( 0x05, (Lyrics)element );
458+ ts.addStringTo( 0x05, (Lyrics)element, charset );
458459 }
459460 }
460461 }
@@ -462,19 +463,23 @@ public class ChordProgression {
462463 }
463464 /**
464465 * コード進行をもとに MIDI シーケンスを生成します。
466+ * @param charset 文字コード
465467 * @return MIDIシーケンス
466468 */
467- public Sequence toMidiSequence() { return toMidiSequence(48); }
469+ public Sequence toMidiSequence(Charset charset) {
470+ return toMidiSequence(48, charset);
471+ }
468472 /**
469- * 指定のタイミング解像度で、
470- * コード進行をもとに MIDI シーケンスを生成します。
473+ * 指定のタイミング解像度、文字コードで、コード進行をもとに MIDI シーケンスを生成します。
474+ * @param ppq 分解能(pulse per quarter)
475+ * @param charset 文字コード
471476 * @return MIDIシーケンス
472477 */
473- public Sequence toMidiSequence(int ppq) {
478+ public Sequence toMidiSequence(int ppq, Charset charset) {
474479 //
475480 // PPQ = Pulse Per Quarter (TPQN = Tick Per Quearter Note)
476481 //
477- return toMidiSequence( ppq, 0, 0, null, null );
482+ return toMidiSequence( ppq, 0, 0, null, null, charset );
478483 }
479484 /**
480485 * 小節数、トラック仕様、コード進行をもとに MIDI シーケンスを生成します。
@@ -483,11 +488,14 @@ public class ChordProgression {
483488 * @param endMeasure 終了小節位置
484489 * @param firstTrack 最初のトラックの仕様
485490 * @param trackSpecs 残りのトラックの仕様
491+ * @param charset 文字コード
486492 * @return MIDIシーケンス
487493 */
488494 public Sequence toMidiSequence(
489495 int ppq, int startMeasure, int endMeasure,
490- FirstTrackSpec firstTrack, Vector<AbstractNoteTrackSpec> trackSpecs
496+ FirstTrackSpec firstTrack,
497+ Vector<AbstractNoteTrackSpec> trackSpecs,
498+ Charset charset
491499 ) {
492500 Sequence seq;
493501 try {
@@ -498,7 +506,7 @@ public class ChordProgression {
498506 // マスタートラックの生成
499507 if( firstTrack == null ) firstTrack = new FirstTrackSpec();
500508 firstTrack.key = this.key;
501- firstTrack.createTrack( seq, startMeasure, endMeasure );
509+ firstTrack.createTrack(seq, charset, startMeasure, endMeasure);
502510 //
503511 // 中身がなければここで終了
504512 if( lines == null || trackSpecs == null ) return seq;
@@ -507,17 +515,17 @@ public class ChordProgression {
507515 setTickPositions(firstTrack);
508516 //
509517 // コードのテキストと歌詞を書き込む
510- setChordSymbolTextTo(firstTrack);
511- setLyricsTo(firstTrack);
518+ setChordSymbolTextTo(firstTrack, charset);
519+ setLyricsTo(firstTrack, charset);
512520 //
513521 // 残りのトラックを生成
514522 for( AbstractNoteTrackSpec ts : trackSpecs ) {
515- ts.createTrack(seq, firstTrack);
523+ ts.createTrack(seq, firstTrack, charset);
516524 if( ts instanceof DrumTrackSpec ) {
517525 ((DrumTrackSpec)ts).addDrums(this);
518526 }
519527 else {
520- ((MelodyTrackSpec)ts).addChords(this);
528+ ((MelodyTrackSpec)ts).addChords(this, charset);
521529 }
522530 }
523531 return seq;
--- a/src/camidion/chordhelper/music/FirstTrackSpec.java
+++ b/src/camidion/chordhelper/music/FirstTrackSpec.java
@@ -1,5 +1,7 @@
11 package camidion.chordhelper.music;
22
3+import java.nio.charset.Charset;
4+
35 import javax.sound.midi.Sequence;
46 import javax.sound.midi.Track;
57
@@ -19,16 +21,12 @@ public class FirstTrackSpec extends AbstractTrackSpec {
1921 if( tempoData != null ) this.tempoData = tempoData;
2022 if( timesigData != null ) this.timesigData = timesigData;
2123 }
22- public FirstTrackSpec(String name, byte[] tempoData, byte[] timesigData, Key key) {
23- this(name,tempoData,timesigData);
24- this.key = key;
25- }
26- public Track createTrack(Sequence seq) {
27- return createTrack( seq, 0, 0 );
24+ public Track createTrack(Sequence seq, Charset charset) {
25+ return createTrack(seq, charset, 0, 0);
2826 }
29- public Track createTrack(Sequence seq, int startMeasurePos, int endMeasurePos) {
27+ public Track createTrack(Sequence seq, Charset charset, int startMeasurePos, int endMeasurePos) {
3028 preMeasures = startMeasurePos - 1;
31- Track track = super.createTrack( seq, this );
29+ Track track = super.createTrack(seq, this, charset);
3230 if( tempoData == null ) tempoData = DEFAULT_TEMPO_DATA;
3331 addTempo(tempoData, 0);
3432 if( timesigData == null ) timesigData = DEFAULT_TIMESIG_DATA;
--- a/src/camidion/chordhelper/music/MIDISpec.java
+++ b/src/camidion/chordhelper/music/MIDISpec.java
@@ -197,7 +197,7 @@ public class MIDISpec {
197197 return Arrays.stream(sequence.getTracks()).anyMatch(t->setNameBytesOf(t,name));
198198 }
199199 /**
200- * シーケンスの名前や歌詞など、メタイベントのテキストをもとに文字コードを判定します。
200+ * 指定されたMIDIシーケンスからメタイベントのテキスト(名前や歌詞など)を検索し、その文字コードを判定します。
201201 * 判定できなかった場合はnullを返します。
202202 * @param sequence MIDIシーケンス
203203 * @return 文字コード判定結果(またはnull)
--- a/src/camidion/chordhelper/music/MelodyTrackSpec.java
+++ b/src/camidion/chordhelper/music/MelodyTrackSpec.java
@@ -1,5 +1,7 @@
11 package camidion.chordhelper.music;
22
3+import java.nio.charset.Charset;
4+
35 /**
46 * メロディトラック仕様
57 */
@@ -55,8 +57,9 @@ public class MelodyTrackSpec extends AbstractNoteTrackSpec {
5557 /**
5658 * コードの追加
5759 * @param cp コード進行
60+ * @param charset 文字コード
5861 */
59- public void addChords( ChordProgression cp ) {
62+ public void addChords( ChordProgression cp, Charset charset ) {
6063 int mask;
6164 long tick;
6265 long startTickPos;
@@ -175,7 +178,7 @@ public class MelodyTrackSpec extends AbstractNoteTrackSpec {
175178 // 決定された音符を追加
176179 addNote(startTickPos, tick + minNoteTicks, noteNumber, velocity);
177180 // 歌詞をテキストとして追加
178- addStringTo(0x05, MIDISpec.nsx39LyricElements[index], startTickPos);
181+ addStringTo(0x05, MIDISpec.nsx39LyricElements[index], charset, startTickPos);
179182 }
180183 else {
181184 // 決定された音符を追加
Show on old repository browser