Happy Birthday!用Java来一首生日快乐歌!

        作为同时热爱编程与midi编曲的人,我决定自己动手,送给自己一份融合编程与编曲的小礼物!这个小程序利用了Java提供的midi包,在程序中创建音序器以及一个音轨,然后硬编码地写入了生日快乐歌的音符(乐谱),再调用虚拟乐器播放出生日快乐歌,最后还在控制台输出了一行生日祝福。

        这篇的代码我借助了CSDN提供的AI创作助手,功能很强大!其中部分代码我有改动,还加了一些注释。正好我也借着这个机会初步了解了Java的midi包。其实把乐谱硬编码在程序中,这样扩展性不好,更好的方式是用Java加载本地的midi文件。

        以下是程序代码。

import javax.sound.midi.*;	//导入midi包

public class HappyBirthday {	/*功能:在程序中硬编码生日快乐歌的音符,并利用midi接口播放这首歌。*/
    public static void main(String[] args) {
        try {
        	/*使用MidiSystem类获取一个MIDI音序器Sequencer对象,
        	 * 并打开它,以便准备播放MIDI音乐
        	 */
            Sequencer sequencer = MidiSystem.getSequencer();
            sequencer.open();
            
            /*创建一个Sequence对象,它将作为MIDI音乐的容器,使用默认的节拍类型
             * (PPQ,即“每拍的脉冲数”)和一个缩放因子4(即一个四分音符的长度为4个单位)。
             */
            Sequence sequence = new Sequence(Sequence.PPQ, 4);
            
            /*在Sequence对象中创建一个Track对象,作为MIDI音乐的轨道,
             * 音符和控制信息可以添加到这个轨道上。
             */
            Track track = sequence.createTrack();
            
            /*//设置MIDI音乐的“乐器”,以便为之后的音符指定正确的声音。
             * ShortMessage类是MIDI消息的一种类型,可以使用它来构建
             * 不同类型的MIDI消息,MidiEvent类则用于将MIDI消息插入到轨道中。
             */
            ShortMessage first = new ShortMessage();
            first.setMessage(ShortMessage.PROGRAM_CHANGE, 0, 1, 0);
            MidiEvent firstEvent = new MidiEvent(first, 0);
            track.add(firstEvent);
            
            /*指定生日快乐歌曲的音符和时长。数组notes存储的是每个音符的MIDI值,
             * 数组durations则存储每个音符的持续时间。
             */
            int[] notes = {60, 60, 62, 60, 65, 64, 60, 60, 62, 60, 67, 65, 60, 60, 72, 69, 65, 64, 62, 70, 70, 69, 65, 67, 65 };
            int[] durations = {4, 4, 4, 4, 4, 2, 4, 4, 4, 4, 4, 4, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4};

            /*在轨道上依次添加每个音符和其对应的持续时间。
             * MidiMessage类的静态方法NOTE_ON和NOTE_OFF分别表示开启和停止一个音符,
             * 这个方法的参数是MIDI信道(音色)、音符的音高(即notes数组中的元素)、以及音符的强度
             */
            for (int i = 0; i < notes.length; i++) {
                ShortMessage a = new ShortMessage();
                a.setMessage(ShortMessage.NOTE_ON, 5, notes[i], 100);	//第二个参数是选乐器 9是打击乐,其它都是钢琴
                MidiEvent noteOn = new MidiEvent(a,i * 4 );				//第二个参数是每拍的时间戳,实际上可用于改变播放速度
                track.add(noteOn);

                ShortMessage b = new ShortMessage();
                b.setMessage(ShortMessage.NOTE_OFF, 0, notes[i], 100);
                MidiEvent noteOff = new MidiEvent(b, (i * 4) + durations[i]);
                track.add(noteOff);
            }

            /*将创建好的Sequence对象设置到Sequencer对象中,并启动播放。
             * 此时程序将以MIDI格式播放生日快乐曲目。
             */
            sequencer.setSequence(sequence);
            sequencer.setTempoInBPM(120);
            sequencer.start();
        } catch (Exception ex) {	//异常处理
            ex.printStackTrace();
        }
        System.out.println("HAPPY BIRTHDAY!!!");	//在控制台输出文本
    }
}

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值