繁体   English   中英

Java Midi程序选择异常行为

[英]Java midi program selection strange behaviour

我试图找到有关此的任何信息,但找不到任何有帮助的信息。

我正在尝试制作一个程序,该程序生成一个MIDI文件,该文件由使用不同乐器(程序)同时演奏的两个乐器组成。 我一直在使用示例程序: http : //www.cs.cornell.edu/courses/cs211/2008sp/examples/MidiSynth.java.txt作为模板,但是当我尝试人工创建midi事件时(相对于使用示例程序中的合成器即时生成它们),生成的midi文件似乎并不关心我是否切换了程序,对文件中的每个音符使用最后更改为的程序,包括两个midi-轨道,即使我已将程序更改数据保存到两个轨道中。 我已经为我的程序粘贴了代码,因为:

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个小时左右来解决这个问题,但我全都没主意。

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

要具有不同的设置,必须使用不同的通道。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM