OSDN Git Service

新シーケンス作成画面に文字コード選択プルダウンを追加
authorAkiyoshi Kamide <kamide@yk.rim.or.jp>
Thu, 18 May 2017 14:11:26 +0000 (23:11 +0900)
committerAkiyoshi Kamide <kamide@yk.rim.or.jp>
Thu, 18 May 2017 14:11:26 +0000 (23:11 +0900)
14 files changed:
src/camidion/chordhelper/ChordHelperApplet.java
src/camidion/chordhelper/mididevice/MidiSequencerModel.java
src/camidion/chordhelper/midieditor/Base64Dialog.java
src/camidion/chordhelper/midieditor/CharsetComboBox.java [new file with mode: 0644]
src/camidion/chordhelper/midieditor/NewSequenceDialog.java
src/camidion/chordhelper/midieditor/PlaylistTable.java
src/camidion/chordhelper/midieditor/PlaylistTableModel.java
src/camidion/chordhelper/midieditor/SequenceTrackListTableModel.java
src/camidion/chordhelper/music/AbstractNoteTrackSpec.java
src/camidion/chordhelper/music/AbstractTrackSpec.java
src/camidion/chordhelper/music/ChordProgression.java
src/camidion/chordhelper/music/FirstTrackSpec.java
src/camidion/chordhelper/music/MIDISpec.java
src/camidion/chordhelper/music/MelodyTrackSpec.java

index 19a25e7..9b00641 100644 (file)
@@ -13,6 +13,7 @@ import java.io.IOException;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.URL;
+import java.nio.charset.Charset;
 import java.util.Arrays;
 
 import javax.sound.midi.InvalidMidiDataException;
@@ -60,6 +61,7 @@ import camidion.chordhelper.midieditor.TempoSelecter;
 import camidion.chordhelper.midieditor.TimeSignatureSelecter;
 import camidion.chordhelper.music.Chord;
 import camidion.chordhelper.music.Key;
+import camidion.chordhelper.music.MIDISpec;
 import camidion.chordhelper.music.Range;
 import camidion.chordhelper.pianokeyboard.MidiKeyboardPanel;
 import camidion.chordhelper.pianokeyboard.PianoKeyboardAdapter;
@@ -95,7 +97,7 @@ public class ChordHelperApplet extends JApplet {
        public int addRandomSongToPlaylist(int measureLength) throws InvalidMidiDataException {
                NewSequenceDialog d = midiEditor.newSequenceDialog;
                d.setRandomChordProgression(measureLength);
-               int index = playlistModel.play(d.getMidiSequence());
+               int index = playlistModel.play(d.getMidiSequence(), d.getSelectedCharset());
                midiEditor.playlistTable.getSelectionModel().setSelectionInterval(index, index);
                return index;
        }
@@ -113,7 +115,9 @@ public class ChordHelperApplet extends JApplet {
                        URL url = (new URI(midiFileUrl)).toURL();
                        String filename = url.getFile().replaceFirst("^.*/","");
                        Sequence sequence = MidiSystem.getSequence(url);
-                       int index = playlistModel.add(sequence, filename);
+                       Charset charset = MIDISpec.getCharsetOf(sequence);
+                       if( charset == null ) charset = Charset.defaultCharset();
+                       int index = playlistModel.add(sequence, charset, filename);
                        midiEditor.playlistTable.getSelectionModel().setSelectionInterval(index, index);
                        return index;
                } catch( URISyntaxException|IOException|InvalidMidiDataException e ) {
@@ -270,7 +274,7 @@ public class ChordHelperApplet extends JApplet {
         */
        public static class VersionInfo {
                public static final String NAME = "MIDI Chord Helper";
-               public static final String VERSION = "Ver.20170517.1";
+               public static final String VERSION = "Ver.20170518.1";
                public static final String COPYRIGHT = "Copyright (C) 2004-2017";
                public static final String AUTHER = "@きよし - Akiyoshi Kamide";
                public static final String URL = "http://www.yk.rim.or.jp/~kamide/music/chordhelper/";
@@ -407,7 +411,7 @@ public class ChordHelperApplet extends JApplet {
                                break;
                        }
                });
-               // シーケンサーの再生時間位置、またはシーケンサーにロード中のシーケンスが変更されたときに呼び出されるリスナーを登録
+               // 再生時間位置の移動、シーケンス名の変更、またはシーケンスの入れ替えが発生したときに呼び出されるリスナーを登録
                JLabel songTitleLabel = new JLabel();
                sequencerModel.addChangeListener(e->{
                        Sequencer sequencer = sequencerModel.getSequencer();
index 059ba25..f14c806 100644 (file)
@@ -249,11 +249,17 @@ public class MidiSequencerModel extends MidiDeviceModel implements BoundedRangeM
                listenerList.remove(ChangeListener.class, listener);
        }
        /**
-        * 秒位置が変わったことをリスナーに通知します。
-        * <p>登録中のすべての {@link ChangeListener} について
+        * 登録中のすべての {@link ChangeListener} の
         * {@link ChangeListener#stateChanged(ChangeEvent)}
-        * ã\82\92å\91¼ã\81³å\87ºã\81\99ã\81\93ã\81¨ã\81«ã\82\88ã\81£ã\81¦ç\8a¶æ\85\8bã\81®å¤\89å\8c\96ã\82\92é\80\9aç\9f¥ã\81\97ã\81¾ã\81\99ã\80\82
+        * を呼び出します。
         * </p>
+        * <p>次のような状態変更を通知したいときに呼び出します。
+        * </p>
+        * <ul>
+        * <li>秒位置の移動</li>
+        * <li>ロードされているシーケンス名の変更</li>
+        * <li>ロードされているシーケンスの入れ替え</li>
+        * </ul>
         */
        public void fireStateChanged() {
                Object[] listeners = listenerList.getListenerList();
index 2e17dc0..63c9181 100644 (file)
@@ -4,11 +4,13 @@ import java.awt.event.ActionEvent;
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.nio.charset.Charset;
 import java.util.Base64;
 import java.util.regex.Pattern;
 
 import javax.sound.midi.InvalidMidiDataException;
 import javax.sound.midi.MidiSystem;
+import javax.sound.midi.Sequence;
 import javax.swing.AbstractAction;
 import javax.swing.Action;
 import javax.swing.Box;
@@ -24,6 +26,7 @@ import javax.swing.event.DocumentListener;
 
 import camidion.chordhelper.ButtonIcon;
 import camidion.chordhelper.ChordHelperApplet;
+import camidion.chordhelper.music.MIDISpec;
 
 /**
  * Base64テキスト入力ダイアログ
@@ -54,7 +57,10 @@ public class Base64Dialog extends JDialog implements DocumentListener {
                        return -1;
                }
                try (InputStream in = new ByteArrayInputStream(midiData)) {
-                       int index = playlistTable.getModel().add(MidiSystem.getSequence(in), null);
+                       Sequence sequence = MidiSystem.getSequence(in);
+                       Charset charset = MIDISpec.getCharsetOf(sequence);
+                       if( charset == null ) charset = Charset.defaultCharset();
+                       int index = playlistTable.getModel().add(sequence, charset, null);
                        playlistTable.getSelectionModel().setSelectionInterval(index, index);
                        return index;
                } catch( IOException|InvalidMidiDataException e ) {
diff --git a/src/camidion/chordhelper/midieditor/CharsetComboBox.java b/src/camidion/chordhelper/midieditor/CharsetComboBox.java
new file mode 100644 (file)
index 0000000..9f7adbf
--- /dev/null
@@ -0,0 +1,15 @@
+package camidion.chordhelper.midieditor;
+
+import java.nio.charset.Charset;
+
+import javax.swing.JComboBox;
+
+public class CharsetComboBox extends JComboBox<Charset> {
+       {
+               Charset.availableCharsets().values().stream().forEach(v->addItem(v));
+               setSelectedItem(Charset.defaultCharset());
+       }
+       public Charset getSelectedCharset() {
+               return (Charset)getSelectedItem();
+       }
+}
index fb28bd5..fa1878b 100644 (file)
@@ -13,6 +13,7 @@ import java.awt.event.ComponentListener;
 import java.awt.event.InputEvent;
 import java.awt.event.MouseEvent;
 import java.awt.event.MouseListener;
+import java.nio.charset.Charset;
 import java.util.ArrayList;
 import java.util.Vector;
 
@@ -61,6 +62,7 @@ public class NewSequenceDialog extends JDialog {
                "Key: C\nC G/B | Am Em/G | F C/E | Dm7 G7 C % | F G7 | Csus4 C\n";
        private JTextArea chordText = new JTextArea(INITIAL_CHORD_STRING, 18, 30);
        private JTextField seqNameText = new JTextField();
+       private CharsetComboBox charsetSelecter = new CharsetComboBox();
        private JComboBox<Integer> ppqComboBox = new JComboBox<Integer>(PPQList);
        private TimeSignatureSelecter timesigSelecter = new TimeSignatureSelecter();
        private TempoSelecter tempoSelecter = new TempoSelecter();
@@ -103,16 +105,20 @@ public class NewSequenceDialog extends JDialog {
                @Override
                public void actionPerformed(ActionEvent event) {
                        try {
-                               int index = playlistTable.play(getMidiSequence());
+                               int index = playlistTable.play(getMidiSequence(), getSelectedCharset());
                                playlistTable.getModel().getSequenceModelList().get(index).setModified(true);
                        } catch (Exception ex) {
                                JOptionPane.showMessageDialog(
                                        NewSequenceDialog.this, ex,
                                        ChordHelperApplet.VersionInfo.NAME, JOptionPane.ERROR_MESSAGE);
+                               ex.printStackTrace();
                        }
                        setVisible(false);
                }
        };
+       public Charset getSelectedCharset() {
+               return charsetSelecter.getSelectedCharset();
+       }
        /**
         * 新しいMIDIシーケンスを生成するダイアログを構築します。
         * @param playlist シーケンス追加先プレイリスト
@@ -129,6 +135,8 @@ public class NewSequenceDialog extends JDialog {
                                        setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
                                        add(new JLabel("Sequence name:"));
                                        add(seqNameText);
+                                       add(new JLabel("Character set:"));
+                                       add(charsetSelecter);
                                }});
                                add(new JPanel() {{
                                        setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
@@ -219,7 +227,8 @@ public class NewSequenceDialog extends JDialog {
                        measureSelecter.getStartMeasurePosition(),
                        measureSelecter.getEndMeasurePosition(),
                        firstTrackSpec,
-                       trackSpecPanel.getTrackSpecs()
+                       trackSpecPanel.getTrackSpecs(),
+                       charsetSelecter.getSelectedCharset()
                );
        }
        /**
index 0e38400..b8e5004 100644 (file)
@@ -25,7 +25,6 @@ import javax.swing.Action;
 import javax.swing.DefaultCellEditor;
 import javax.swing.Icon;
 import javax.swing.JButton;
-import javax.swing.JComboBox;
 import javax.swing.JComponent;
 import javax.swing.JFileChooser;
 import javax.swing.JOptionPane;
@@ -45,6 +44,7 @@ import javax.swing.table.TableColumnModel;
 
 import camidion.chordhelper.ChordHelperApplet;
 import camidion.chordhelper.mididevice.MidiSequencerModel;
+import camidion.chordhelper.music.MIDISpec;
 
 /**
  * プレイリストビュー(シーケンスリスト)
@@ -117,9 +117,7 @@ public class PlaylistTable extends JTable {
                //
                // 文字コード選択をプルダウンにする
                getColumnModel().getColumn(PlaylistTableModel.Column.CHARSET.ordinal())
-                       .setCellEditor(new DefaultCellEditor(new JComboBox<Charset>() {{
-                               Charset.availableCharsets().values().stream().forEach(v->addItem(v));
-                       }}));
+                       .setCellEditor(new DefaultCellEditor(new CharsetComboBox()));
                setAutoCreateColumnsFromModel(false);
                //
                // Base64画面を開くアクションの生成
@@ -328,7 +326,10 @@ public class PlaylistTable extends JTable {
                while(itr.hasNext()) {
                        File file = itr.next();
                        try (FileInputStream in = new FileInputStream(file)) {
-                               int lastIndex = ((PlaylistTableModel)dataModel).add(MidiSystem.getSequence(in), file.getName());
+                               Sequence sequence = MidiSystem.getSequence(in);
+                               Charset charset = MIDISpec.getCharsetOf(sequence);
+                               if( charset == null ) charset = Charset.defaultCharset();
+                               int lastIndex = ((PlaylistTableModel)dataModel).add(sequence, charset, file.getName());
                                if( firstIndex < 0 ) firstIndex = lastIndex;
                        } catch(IOException|InvalidMidiDataException e) {
                                String message = "Could not open as MIDI file "+file+"\n"+e;
@@ -358,12 +359,13 @@ public class PlaylistTable extends JTable {
        /**
         * 指定されたシーケンスを追加して再生します。
         * @param sequence 再生するシーケンス
+        * @param charset 文字コード
         * @return 追加されたシーケンスのインデックス(先頭が 0)
         * @throws InvalidMidiDataException {@link Sequencer#setSequence(Sequence)} を参照
         * @throws IllegalStateException MIDIシーケンサデバイスが閉じている場合
         */
-       public int play(Sequence sequence) throws InvalidMidiDataException {
-               int index = getModel().play(sequence);
+       public int play(Sequence sequence, Charset charset) throws InvalidMidiDataException {
+               int index = getModel().play(sequence, charset);
                selectionModel.setSelectionInterval(index, index);
                return index;
        }
index 2917876..d3bc6fe 100644 (file)
@@ -35,7 +35,7 @@ public class PlaylistTableModel extends AbstractTableModel {
        /**
         * 空のトラックリストモデル
         */
-       public final SequenceTrackListTableModel emptyTrackListTableModel = new SequenceTrackListTableModel(this, null, null);
+       public final SequenceTrackListTableModel emptyTrackListTableModel = new SequenceTrackListTableModel(this, null, null, null);
        /**
         * 空のイベントリストモデル
         */
@@ -344,12 +344,15 @@ public class PlaylistTableModel extends AbstractTableModel {
        /**
         * MIDIシーケンスを追加します。
         * @param sequence MIDIシーケンス(nullの場合、シーケンスを自動生成して追加)
+        * @param charset MIDIシーケンス内のテキスト文字コード
         * @param filename ファイル名(nullの場合、ファイル名なし)
         * @return 追加されたシーケンスのインデックス(先頭が 0)
         */
-       public int add(Sequence sequence, String filename) {
-               if( sequence == null ) sequence = (new ChordProgression()).toMidiSequence();
-               sequenceModelList.add(new SequenceTrackListTableModel(this, sequence, filename));
+       public int add(Sequence sequence, Charset charset, String filename) {
+               if( sequence == null ) {
+                       sequence = (new ChordProgression()).toMidiSequence(charset);
+               }
+               sequenceModelList.add(new SequenceTrackListTableModel(this, sequence, charset, filename));
                int lastIndex = sequenceModelList.size() - 1;
                fireTableRowsInserted(lastIndex, lastIndex);
                return lastIndex;
@@ -405,12 +408,13 @@ public class PlaylistTableModel extends AbstractTableModel {
        /**
         * 指定されたMIDIシーケンスをこのプレイリストに追加し、再生されていなければ追加した曲から再生します。
         * @param sequence MIDIシーケンス
+        * @param charset 文字コード
         * @return 追加されたシーケンスのインデックス(先頭が 0)
         * @throws InvalidMidiDataException {@link Sequencer#setSequence(Sequence)} を参照
         * @throws IllegalStateException MIDIシーケンサデバイスが閉じている場合
         */
-       public int play(Sequence sequence) throws InvalidMidiDataException {
-               int lastIndex = add(sequence,"");
+       public int play(Sequence sequence, Charset charset) throws InvalidMidiDataException {
+               int lastIndex = add(sequence, charset, "");
                if( ! sequencerModel.getSequencer().isRunning() ) play(lastIndex);
                return lastIndex;
        }
index 8a9fe9b..91fa6d0 100644 (file)
@@ -85,14 +85,17 @@ public class SequenceTrackListTableModel extends AbstractTableModel {
         * MIDIシーケンスとファイル名から {@link SequenceTrackListTableModel} を構築します。
         * @param sequenceListTableModel 親のプレイリスト
         * @param sequence MIDIシーケンス
+        * @param charset MIDIシーケンスのテキスト文字コード
         * @param filename ファイル名
         */
        public SequenceTrackListTableModel(
                PlaylistTableModel sequenceListTableModel,
                Sequence sequence,
+               Charset charset,
                String filename
        ) {
                this.sequenceListTableModel = sequenceListTableModel;
+               this.charset = charset;
                setSequence(sequence);
                setFilename(filename);
        }
@@ -244,12 +247,7 @@ public class SequenceTrackListTableModel extends AbstractTableModel {
                //
                // トラックリストを再構築
                Track tracks[] = sequence.getTracks();
-               for(Track track : tracks) {
-                       trackModelList.add(new MidiEventTableModel(this, track));
-               }
-               // 文字コードの判定
-               Charset cs = MIDISpec.getCharsetOf(sequence);
-               charset = cs==null ? Charset.defaultCharset() : cs;
+               for(Track track : tracks) trackModelList.add(new MidiEventTableModel(this, track));
                //
                // トラックが挿入されたことを通知
                fireTableRowsInserted(0, tracks.length-1);
@@ -280,6 +278,7 @@ public class SequenceTrackListTableModel extends AbstractTableModel {
         */
        @Override
        public String toString() {
+               if( sequence == null ) return "";
                byte b[] = MIDISpec.getNameBytesOf(sequence);
                return b == null ? "" : new String(b, charset);
        }
@@ -290,10 +289,12 @@ public class SequenceTrackListTableModel extends AbstractTableModel {
         * @return 成功したらtrue
         */
        public boolean setName(String name) {
-               if( name.equals(toString()) ) return false;
+               if( name.equals(toString()) || sequence == null ) return false;
                if( ! MIDISpec.setNameBytesOf(sequence, name.getBytes(charset)) ) return false;
                setModified(true);
                fireTableDataChanged();
+               if( isOnSequencer() )
+                       sequenceListTableModel.getSequencerModel().fireStateChanged();
                return true;
        }
        /**
@@ -328,7 +329,7 @@ public class SequenceTrackListTableModel extends AbstractTableModel {
         * @return トラックモデル(見つからない場合null)
         */
        public MidiEventTableModel getSelectedTrackModel(ListSelectionModel selectionModel) {
-               if( selectionModel.isSelectionEmpty() ) return null;
+               if( sequence == null || selectionModel.isSelectionEmpty() ) return null;
                Track tracks[] = sequence.getTracks();
                if( tracks.length == 0 ) return null;
                Track t = tracks[selectionModel.getMinSelectionIndex()];
@@ -340,8 +341,10 @@ public class SequenceTrackListTableModel extends AbstractTableModel {
         * @return トラックのインデックス(先頭 0、トラックが見つからない場合 -1)
         */
        public int indexOf(Track track) {
-               Track tracks[] = sequence.getTracks();
-               for( int i=0; i<tracks.length; i++ ) if( tracks[i] == track ) return i;
+               if( sequence != null ) {
+                       Track tracks[] = sequence.getTracks();
+                       for( int i=0; i<tracks.length; i++ ) if( tracks[i] == track ) return i;
+               }
                return -1;
        }
        /**
index ba4b3b1..78164e9 100644 (file)
@@ -1,5 +1,7 @@
 package camidion.chordhelper.music;
 
+import java.nio.charset.Charset;
+
 import javax.sound.midi.InvalidMidiDataException;
 import javax.sound.midi.MidiEvent;
 import javax.sound.midi.MidiMessage;
@@ -30,8 +32,8 @@ public abstract class AbstractNoteTrackSpec extends AbstractTrackSpec {
                this(ch,name,programNumber);
                this.velocity = velocity;
        }
-       public Track createTrack( Sequence seq, FirstTrackSpec firstTrackSpec ) {
-               Track track = super.createTrack( seq, firstTrackSpec );
+       public Track createTrack( Sequence seq, FirstTrackSpec firstTrackSpec, Charset charset ) {
+               Track track = super.createTrack( seq, firstTrackSpec, charset );
                if( programNumber >= 0 ) addProgram( programNumber, 0 );
                return track;
        }
index 7447b1a..685e664 100644 (file)
@@ -1,5 +1,7 @@
 package camidion.chordhelper.music;
 
+import java.nio.charset.Charset;
+
 import javax.sound.midi.InvalidMidiDataException;
 import javax.sound.midi.MetaMessage;
 import javax.sound.midi.MidiEvent;
@@ -43,10 +45,10 @@ public abstract class AbstractTrackSpec {
         * @param firstTrackSpec 最初のトラック仕様
         * @return 生成したトラック
         */
-       public Track createTrack( Sequence seq, FirstTrackSpec firstTrackSpec ) {
+       public Track createTrack( Sequence seq, FirstTrackSpec firstTrackSpec, Charset charset ) {
                this.firstTrackSpec = firstTrackSpec;
                track = (sequence = seq).createTrack();
-               if( name != null ) addStringTo( 0x03, name, 0 );
+               if( name != null ) addStringTo( 0x03, name, charset, 0 );
                minNoteTicks = (long)( seq.getResolution() >> 2 );
                return track;
        }
@@ -58,14 +60,14 @@ public abstract class AbstractTrackSpec {
         * @return {@link Track#add(MidiEvent)} と同じ
         */
        public boolean addMetaEventTo( int type, byte data[], long tickPos  ) {
-               MetaMessage meta_msg = new MetaMessage();
+               MetaMessage metaMessage = new MetaMessage();
                try {
-                       meta_msg.setMessage( type, data, data.length );
+                       metaMessage.setMessage( type, data, data.length );
                } catch( InvalidMidiDataException ex ) {
                        ex.printStackTrace();
                        return false;
                }
-               return track.add(new MidiEvent(meta_msg, tickPos));
+               return track.add(new MidiEvent(metaMessage, tickPos));
        }
        /**
         * 文字列をメタイベントとして追加します。
@@ -74,21 +76,21 @@ public abstract class AbstractTrackSpec {
         * @param tickPos tick位置
         * @return {@link #addMetaEventTo(int, byte[], long)} と同じ
         */
-       public boolean addStringTo( int type, String str, long tickPos ) {
+       public boolean addStringTo( int type, String str, Charset charset, long tickPos ) {
                if( str == null ) str = "";
-               return addMetaEventTo( type, str.getBytes(), tickPos );
+               return addMetaEventTo(type, str.getBytes(charset), tickPos);
        }
-       public boolean addStringTo( int type, ChordProgression.ChordStroke cs ) {
-               return addStringTo(type, cs.chord.toString(), cs.tickRange.startTickPos);
+       public boolean addStringTo( int type, ChordProgression.ChordStroke cs, Charset charset ) {
+               return addStringTo(type, cs.chord.toString(), charset, cs.tickRange.startTickPos);
        }
-       public boolean addStringTo( int type, ChordProgression.Lyrics lyrics ) {
-               return addStringTo(type, lyrics.text, lyrics.startTickPos);
+       public boolean addStringTo( int type, ChordProgression.Lyrics lyrics, Charset charset ) {
+               return addStringTo(type, lyrics.text, charset, lyrics.startTickPos);
        }
        public boolean addEOT( long tickPos ) {
                return addMetaEventTo( 0x2F, new byte[0], tickPos );
        }
-       public void setChordSymbolText( ChordProgression cp ) {
-               cp.setChordSymbolTextTo( this );
+       public void setChordSymbolText(ChordProgression cp, Charset charset) {
+               cp.setChordSymbolTextTo(this, charset);
        }
        public boolean addSysEx(byte[] data, long tickPos) {
                SysexMessage msg = new SysexMessage();
index 5866895..38cdc04 100644 (file)
@@ -1,5 +1,6 @@
 package camidion.chordhelper.music;
 
+import java.nio.charset.Charset;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Vector;
@@ -435,26 +436,26 @@ public class ChordProgression {
                }
        }
        // コード文字列の書き込み
-       public void setChordSymbolTextTo( AbstractTrackSpec ts ) {
+       public void setChordSymbolTextTo( AbstractTrackSpec ts, Charset charset ) {
                for( Line line : lines ) {
                        for( Measure measure : line ) {
                                if( measure.ticks_per_beat == null ) continue;
                                for( Object element : measure ) {
                                        if( element instanceof ChordStroke ) {
-                                               ts.addStringTo( 0x01, (ChordStroke)element );
+                                               ts.addStringTo( 0x01, (ChordStroke)element, charset );
                                        }
                                }
                        }
                }
        }
        // 歌詞の書き込み
-       public void setLyricsTo( AbstractTrackSpec ts ) {
+       public void setLyricsTo( AbstractTrackSpec ts, Charset charset ) {
                for( Line line : lines ) {
                        for( Measure measure : line ) {
                                if( measure.ticks_per_beat == null ) continue;
                                for( Object element : measure ) {
                                        if( element instanceof Lyrics ) {
-                                               ts.addStringTo( 0x05, (Lyrics)element );
+                                               ts.addStringTo( 0x05, (Lyrics)element, charset );
                                        }
                                }
                        }
@@ -462,19 +463,23 @@ public class ChordProgression {
        }
        /**
         * コード進行をもとに MIDI シーケンスを生成します。
+        * @param charset 文字コード
         * @return MIDIシーケンス
         */
-       public Sequence toMidiSequence() { return toMidiSequence(48); }
+       public Sequence toMidiSequence(Charset charset) {
+               return toMidiSequence(48, charset);
+       }
        /**
-        * 指定のタイミング解像度で、
-        * コード進行をもとに MIDI シーケンスを生成します。
+        * 指定のタイミング解像度、文字コードで、コード進行をもとに MIDI シーケンスを生成します。
+        * @param ppq 分解能(pulse per quarter)
+        * @param charset 文字コード
         * @return MIDIシーケンス
         */
-       public Sequence toMidiSequence(int ppq) {
+       public Sequence toMidiSequence(int ppq, Charset charset) {
                //
                // PPQ = Pulse Per Quarter (TPQN = Tick Per Quearter Note)
                //
-               return toMidiSequence( ppq, 0, 0, null, null );
+               return toMidiSequence( ppq, 0, 0, null, null, charset );
        }
        /**
         * 小節数、トラック仕様、コード進行をもとに MIDI シーケンスを生成します。
@@ -483,11 +488,14 @@ public class ChordProgression {
         * @param endMeasure 終了小節位置
         * @param firstTrack 最初のトラックの仕様
         * @param trackSpecs 残りのトラックの仕様
+        * @param charset 文字コード
         * @return MIDIシーケンス
         */
        public Sequence toMidiSequence(
                int ppq, int startMeasure, int endMeasure,
-               FirstTrackSpec firstTrack, Vector<AbstractNoteTrackSpec> trackSpecs
+               FirstTrackSpec firstTrack,
+               Vector<AbstractNoteTrackSpec> trackSpecs,
+               Charset charset
        ) {
                Sequence seq;
                try {
@@ -498,7 +506,7 @@ public class ChordProgression {
                // マスタートラックの生成
                if( firstTrack == null ) firstTrack = new FirstTrackSpec();
                firstTrack.key = this.key;
-               firstTrack.createTrack( seq, startMeasure, endMeasure );
+               firstTrack.createTrack(seq, charset, startMeasure, endMeasure);
                //
                // 中身がなければここで終了
                if( lines == null || trackSpecs == null ) return seq;
@@ -507,17 +515,17 @@ public class ChordProgression {
                setTickPositions(firstTrack);
                //
                // コードのテキストと歌詞を書き込む
-               setChordSymbolTextTo(firstTrack);
-               setLyricsTo(firstTrack);
+               setChordSymbolTextTo(firstTrack, charset);
+               setLyricsTo(firstTrack, charset);
                //
                // 残りのトラックを生成
                for( AbstractNoteTrackSpec ts : trackSpecs ) {
-                       ts.createTrack(seq, firstTrack);
+                       ts.createTrack(seq, firstTrack, charset);
                        if( ts instanceof DrumTrackSpec ) {
                                ((DrumTrackSpec)ts).addDrums(this);
                        }
                        else {
-                               ((MelodyTrackSpec)ts).addChords(this);
+                               ((MelodyTrackSpec)ts).addChords(this, charset);
                        }
                }
                return seq;
index 1c7006f..75f9c2d 100644 (file)
@@ -1,5 +1,7 @@
 package camidion.chordhelper.music;
 
+import java.nio.charset.Charset;
+
 import javax.sound.midi.Sequence;
 import javax.sound.midi.Track;
 
@@ -19,16 +21,12 @@ public class FirstTrackSpec extends AbstractTrackSpec {
                if( tempoData != null ) this.tempoData = tempoData;
                if( timesigData != null ) this.timesigData = timesigData;
        }
-       public FirstTrackSpec(String name, byte[] tempoData, byte[] timesigData, Key key) {
-               this(name,tempoData,timesigData);
-               this.key = key;
-       }
-       public Track createTrack(Sequence seq) {
-               return createTrack( seq, 0, 0 );
+       public Track createTrack(Sequence seq, Charset charset) {
+               return createTrack(seq, charset, 0, 0);
        }
-       public Track createTrack(Sequence seq, int startMeasurePos, int endMeasurePos) {
+       public Track createTrack(Sequence seq, Charset charset, int startMeasurePos, int endMeasurePos) {
                preMeasures = startMeasurePos - 1;
-               Track track = super.createTrack( seq, this );
+               Track track = super.createTrack(seq, this, charset);
                if( tempoData == null ) tempoData = DEFAULT_TEMPO_DATA;
                addTempo(tempoData, 0);
                if( timesigData == null ) timesigData = DEFAULT_TIMESIG_DATA;
index 592100c..502980a 100644 (file)
@@ -197,7 +197,7 @@ public class MIDISpec {
                return Arrays.stream(sequence.getTracks()).anyMatch(t->setNameBytesOf(t,name));
        }
        /**
-        * シーケンスの名前や歌詞など、メタイベントのテキストをもとに文字コードを判定します。
+        * 指定されたMIDIシーケンスからメタイベントのテキスト(名前や歌詞など)を検索し、その文字コードを判定します。
         * 判定できなかった場合はnullを返します。
         * @param sequence MIDIシーケンス
         * @return 文字コード判定結果(またはnull)
index 4adcb6f..bfd9567 100644 (file)
@@ -1,5 +1,7 @@
 package camidion.chordhelper.music;
 
+import java.nio.charset.Charset;
+
 /**
  * メロディトラック仕様
  */
@@ -55,8 +57,9 @@ public class MelodyTrackSpec extends AbstractNoteTrackSpec {
        /**
         * コードの追加
         * @param cp コード進行
+        * @param charset 文字コード
         */
-       public void addChords( ChordProgression cp ) {
+       public void addChords( ChordProgression cp, Charset charset ) {
                int mask;
                long tick;
                long startTickPos;
@@ -175,7 +178,7 @@ public class MelodyTrackSpec extends AbstractNoteTrackSpec {
                                                        // 決定された音符を追加
                                                        addNote(startTickPos, tick + minNoteTicks, noteNumber, velocity);
                                                        // 歌詞をテキストとして追加
-                                                       addStringTo(0x05, MIDISpec.nsx39LyricElements[index], startTickPos);
+                                                       addStringTo(0x05, MIDISpec.nsx39LyricElements[index], charset, startTickPos);
                                                }
                                                else {
                                                        // 決定された音符を追加