我試圖找到任何有關這方面的信息,但我一直沒有找到任何幫助。Java的midi程序選擇奇怪的行爲
我試圖製作一個程序,用於生成一個midi文件,其中包含兩個使用不同樂器(程序)一起播放的樂器。我一直在使用一個示例程序: http://www.cs.cornell.edu/courses/cs211/2008sp/examples/MidiSynth.java.txt 作爲模板,但是當我試圖人爲地製造了MIDI事件(而不是生成它們與示例程序的合成器飛),所產生的MIDI文件不似乎在意我已經切換了節目,對於文件中的每個音符使用最後一個改變後的節目,由兩個midi音軌組成,儘管我已經將節目改變數據保存到兩個音軌中。我已經貼了代碼爲我的程序beneith:
import java.io.File;
import java.io.IOException;
import javax.sound.midi.Sequence;
import javax.sound.midi.Soundbank;
import javax.sound.midi.Sequencer;
import javax.sound.midi.Synthesizer;
import javax.sound.midi.Instrument;
import javax.sound.midi.MidiChannel;
import javax.sound.midi.MidiEvent;
import javax.sound.midi.MidiMessage;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.ShortMessage;
import javax.sound.midi.Track;
import javax.sound.midi.InvalidMidiDataException;
public class MidiTest2
{
/* This velocity is used for all notes.
*/
private static final int VELOCITY = 64;
final int PROGRAM = 192;
final int NOTEON = 144;
final int NOTEOFF = 128;
long startTime;
Sequence sequence;
Synthesizer synthesizer;
Sequencer sequencer;
Instrument instruments[];
ChannelData channels[];
ChannelData cc;
//int instrumentCounter = 0;
Track track;
MidiTest2(){
try{
if(synthesizer == null){
if((synthesizer = MidiSystem.getSynthesizer()) == null){
System.out.println("getSynthesizer() failed");
return;
}
}
synthesizer.open();
sequencer = MidiSystem.getSequencer();
sequence = new Sequence(Sequence.PPQ, 10);
}catch(Exception e){
e.printStackTrace();
return;
}
Soundbank sb = synthesizer.getDefaultSoundbank();
if(sb != null){
instruments = synthesizer.getDefaultSoundbank().getInstruments();
synthesizer.loadInstrument(instruments[0]);
}
MidiChannel midiChannels[] = synthesizer.getChannels();
channels = new ChannelData[midiChannels.length];
for(int i = 0; i < channels.length;++i){
channels[i] = new ChannelData(midiChannels[i], i);
}
cc = channels[0];
}
public void createShortEvent(int type, int num){
ShortMessage message = new ShortMessage();
try{
long millis = System.currentTimeMillis() - startTime;
long tick = millis * sequence.getResolution()/500;
message.setMessage(type+cc.num, num, cc.velocity);
System.out.println("Type: " + message.getCommand() + ", Data1: " + message.getData1() + ", Data2: " + message.getData2() + ", Tick: " + tick);
MidiEvent event = new MidiEvent(message, tick);
track.add(event);
}catch (Exception e){
e.printStackTrace();
}
}
public void createShortEvent(int type, int num, int eventTime){
ShortMessage message = new ShortMessage();
try{
//long millis = System.currentTimeMillis() - startTime;
long tick = eventTime * sequence.getResolution();
message.setMessage(type+cc.num, num, cc.velocity);
System.out.println("Type: " + message.getCommand() + ", Data1: " + message.getData1() + ", Data2: " + message.getData2() + ", Tick: " + tick);
MidiEvent event = new MidiEvent(message, tick);
track.add(event);
}catch (Exception e){
e.printStackTrace();
}
}
public void saveMidiFile(){
try {
int[] fileTypes = MidiSystem.getMidiFileTypes(sequence);
if (fileTypes.length == 0) {
System.out.println("Can't save sequence");
} else {
if (MidiSystem.write(sequence, fileTypes[0], new File("testmidi.mid")) == -1) {
throw new IOException("Problems writing to file");
}
}
} catch (SecurityException ex) {
} catch (Exception ex) {
ex.printStackTrace();
}
}
void run(){
//System.out.println("sequence: " + sequence.getTracks().length);
createNewTrack(0);
createShortEvent(NOTEON, 60, 2);
createShortEvent(NOTEOFF, 60, 3);
createShortEvent(NOTEON, 61, 3);
createShortEvent(NOTEOFF, 61, 4);
createShortEvent(NOTEON, 62, 4);
createShortEvent(NOTEOFF, 62, 5);
createShortEvent(NOTEON, 63, 5);
createShortEvent(NOTEOFF, 63, 6);
createNewTrack(5);
createShortEvent(NOTEON, 50, 1);
createShortEvent(NOTEOFF, 50, 5);
playMidiFile();
saveMidiFile();
}
void printTrack(int num){
Track tempTrack = sequence.getTracks()[num];
System.out.println(tempTrack.get(0).getTick());
}
void playMidiFile(){
try{
sequencer.open();
sequencer.setSequence(sequence);
}catch (Exception e){
e.printStackTrace();
}
sequencer.start();
}
void createNewTrack(int program){
track = sequence.createTrack();
programChange(program);
}
void programChange(int program){
cc.channel.programChange(program);
System.out.println("program: " + program);
startTime = System.currentTimeMillis();
createShortEvent(PROGRAM, program);
}
public static void main(String[] args)
{
MidiTest2 mt = new MidiTest2();
mt.run();
}
}
的ChannelData級(即沒有做任何事情,但我想我會發布它的完整性起見):
public class ChannelData {
MidiChannel channel;
boolean solo, mono, mute, sustain;
int velocity, pressure, bend, reverb;
int row, col, num;
public ChannelData(MidiChannel channel, int num) {
this.channel = channel;
this.num = num;
velocity = pressure = bend = reverb = 64;
}
public void setComponentStates() {
}
}
在我試着用原聲鋼琴音色創作5個音符,用電鋼琴音色創作1個音符。但是,即使我在切換樂器之前創建了一個新的軌道,所有音符都會用電子鋼琴的聲音播放。
我一直試圖弄清楚現在5個小時或什麼,我都沒有想法。
「我以爲我會爲了完整而張貼它」如果它不相關,請不要發佈它。同樣,這隻會發生在5個音符,還是隻發生在1? http://www.stackoverflow.com/help/mcve我並不想固執,只是在這裏有很多代碼需要通過。 –
是的,我明白你的觀點。我的意思是,以使它更容易爲任何人試圖剛剛獲得運行代碼在這種情況下,我認爲這將是更好的,如果它是完整的。儘管我知道它的工作原理,但事實證明,我認爲這些代碼實際上並不重要。不管怎麼說,還是要謝謝你! – dipetriantonio