首页 文章

Java midi程序选择奇怪的行为

提问于
浏览
0

我试图找到有关这方面的任何信息,但我找不到任何有用的信息 .

我正在尝试制作一个程序来生成一个midi文件,其中包含两个乐器,它们使用不同的乐器(程序)同时播放 . 我一直在使用一个示例程序:http://www.cs.cornell.edu/courses/cs211/2008sp/examples/MidiSynth.java.txt作为模板但是当我尝试人工创建midi事件时(而不是在示例程序中使用合成器动态生成它们),得到的midi文件似乎没有尽管我已经将程序更改数据保存到两个轨道,但是我已经切换了程序,使用文件中每个音符的最后一个改变程序,包括两个midi-tracks . 我已经粘贴了我的程序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个音符,使用电子钢琴声音创建一个音符 . 然而,即使我在切换乐器之前创建了新的音轨,所有音符都会以电钢琴音色播放 .

我一直在努力解决这个问题,现在已经有5个小时或者其他什么了,我完全没有想法 .

1 回答

  • 0

    曲目可以帮助您自己的程序组织事件,但它们不会以任何方式影响合成器 .

    要能够进行不同的设置,您必须使用不同的 Channels .

相关问题