Java使用MidiEvent组合乐器音效

很久前看到别人写的电子乐器软件,感觉很炫,一直以为音效是采用录制的音乐,然后事件触发音效播放,今天才知道理解错了,javax.sound.midi包下提供了一系列与音乐播放,音效组合相关的API.这里实现一个简单的乐器音效组合.来说明相关参数的作用.

/**
     * MidiEvent是组合乐曲的指令,一连串的MidiEvent就好像是乐谱一样.
     * MidiEvent用来指示在何时执行什么操作,每个指令都必须包括该指令的执行时机.也就是说,乐声应该在那一拍发响.
     * 
     * @param comd    
     *                 chmod代表信息类型 144类型的信息代表NOTE ON表示打开 128代表NOTE OFF 表示关闭
     * @param chan
     *                 chan表示频道,每个频道代表不同的演奏者.
     *                 例如:一号频道是吉他,二号频道是Bass.或者可以像IronMaiden用3把不同音色的吉他编制
     * @param one    
     *                 one表示音符,从0~127代表不同音高
     * @param two
     *                 two代表音道/音量,用多大的音道按下? 0几乎听不到,100算是差不多
     * @param tick
     * @return
     */
    public MidiEvent makeEvent(int comd, int chan, int one, int two, int tick){
        MidiEvent event = null;
        try {
            ShortMessage a = new ShortMessage();
            a.setMessage(comd,chan,one,two);
            //表示在tick拍启动a这个Message
            event = new MidiEvent(a, tick);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return event;
    }

实例应用代码

import javax.sound.midi.MidiEvent;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.Sequence;
import javax.sound.midi.Sequencer;
import javax.sound.midi.ShortMessage;
import javax.sound.midi.Track;


/**
 * 
 *    MiniMusic.java
 *
 *     功   能: TODO 
 *     类   名: MiniMusic.java
 *
 *  ver     変更日       角色    担当者     変更内容
 *     ──────────────────────────────────────────────
 *  V1.00   2013-3-19   模块    苏若年     初版
 *
 *     Copyright (c) 2013 dennisit corporation All Rights Reserved.
 *   
 *  Email:<a href="mailto:DennisIT@163.com">发送邮件</a>
 *
 */
public class MiniMusic {
    
    public void play(){
        try {
            Sequencer player = MidiSystem.getSequencer();
            player.open();
            //节拍器
            Sequence seq = new Sequence(Sequence.PPQ,4);
            Track track = seq.createTrack();
            
            int r=0;
            for(int i=0; i<60; i+=4){
                r = (int)((Math.random()*50)+1);    //随即音符
                track.add(makeEvent(144, 1, r, 100, i));
                track.add(makeEvent(128, 1, r, 100, i+2));
            }
            
            player.setSequence(seq);
            player.setLoopCount(player.LOOP_CONTINUOUSLY);    //指定无穷的重复次数
            player.setTempoInBPM(120);
            player.start();
        } catch (Exception e) {
            // TODO: handle exception
        }
    }
    
    /**
     * MidiEvent是组合乐曲的指令,一连串的MidiEvent就好像是乐谱一样.
     * MidiEvent用来指示在何时执行什么操作,每个指令都必须包括该指令的执行时机.也就是说,乐声应该在那一拍发响.
     * 
     * @param comd    
     *                 chmod代表信息类型 144类型的信息代表NOTE ON表示打开 128代表NOTE OFF 表示关闭
     * @param chan
     *                 chan表示频道,每个频道代表不同的演奏者.
     *                 例如:一号频道是吉他,二号频道是Bass.或者可以像IronMaiden用3把不同音色的吉他编制
     * @param one    
     *                 one表示音符,从0~127代表不同音高
     * @param two
     *                 two代表音道/音量,用多大的音道按下? 0几乎听不到,100算是差不多
     * @param tick
     * @return
     */
    public MidiEvent makeEvent(int comd, int chan, int one, int two, int tick){
        MidiEvent event = null;
        try {
            ShortMessage a = new ShortMessage();
            a.setMessage(comd,chan,one,two);
            //表示在tick拍启动a这个Message
            event = new MidiEvent(a, tick);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return event;
    }
    
    public static void main(String[] args) {
        MiniMusic mini = new MiniMusic();
        mini.play();
        
    }
}

运行即可听到,有一段循环播放的乐器音效,当然你有兴趣,可以做成更炫的Java版的电子乐器软件.如下.

 

 

转载请注明出处:[http://www.cnblogs.com/dennisit/archive/2013/03/19/2969745.html]

 

在线交谈

posted @ 2013-03-19 18:41  苏二  阅读(3897)  评论(1编辑  收藏  举报