在Java中更改MIDI音量

问题描述

首先更改音量是有效的,但更改音量时遇到了一些问题,因此1)更改音量后,例如将其设置为0(无音量),您仍会以默认音量2收听歌曲的一部分。 )将歌曲更改为音量后,恢复为音量的默认值

public static void setVolume(double value) {
    System.out.println();
    int CHANGE_VOLUME = 7;
    midivol =(value);
    try {
        if (synthesizer.getDefaultSoundbank() == null) {
            System.out.println(444);
                ShortMessage volumeMessage = new ShortMessage();
                for (int i = 0; i < 16; i++) {
                    volumeMessage.setMessage(ShortMessage.CONTROL_CHANGE,i,CHANGE_VOLUME,(int)(value * 127.0));
                    volumeMessage.setMessage(ShortMessage.CONTROL_CHANGE,39,(int)(value * 127.0));
                    MidiSystem.getReceiver().send(volumeMessage,-1);
                }
        } else {  
             MidiChannel[] channels = synthesizer.getChannels();

              for( int c = 0; c < channels.length; c++ ) {
                 if(channels[c] != null)   channels[c].controlChange( 7,(int)( value*127.0) );
              }
        }
        music.setSequence(sequence);
    } catch (Exception e) {
            e.printStackTrace();
        }
}

演奏midi:

 private void playMidi(String location) {
    double gain =Slider.musicvolume;
    music = null;
    //synthesizer = null;
    sequence = null;
    File midiFile = new File(location);
    try {
    sequence = MidiSystem.getSequence(midiFile);
        music = MidiSystem.getSequencer(false);
        music.open();
        music.setSequence(sequence);
    } catch (Exception e) {
        System.err.println("Problem loading MIDI file.");
        e.printStackTrace();
        return;
    }
    if (music instanceof Synthesizer) {
        synthesizer = (Synthesizer) music;
    } else {
        try {
            synthesizer = MidiSystem.getSynthesizer();
            synthesizer.open();
            if (synthesizer.getDefaultSoundbank() == null) {
                music.getTransmitter().setReceiver(MidiSystem.getReceiver());
            } else {
                music.getTransmitter().setReceiver(synthesizer.getReceiver());
            }
        } catch (Exception e) {
            e.printStackTrace();
            return;
        }
    }
      MidiChannel[] channels = synthesizer.getChannels();
     for (int i = 0; i < channels.length; i++) {
        channels[i].controlChange(7,(int) (gain * 127.0));
      }
     try {
        music.setSequence(sequence);
    } catch (InvalidMidiDataException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    music.setLoopCount(Sequencer.LOOP_CONTINUOUSLY);
    music.start();

}

解决方法

volumeMessage.setMessage(ShortMessage.CONTROL_CHANGE,i,CHANGE_VOLUME,(int)(value * 127.0));
volumeMessage.setMessage(ShortMessage.CONTROL_CHANGE,39,(int)(value * 127.0));
MidiSystem.getReceiver().send(volumeMessage,-1);

此代码发送一个消息。该消息的内容是第二个setMessage调用所设置的值,因此卷MSB完全没有更改。 (这是计算LSB的错误方法。)

控制器7确实是用于音量的,但是对于如何解释值没有确切的标准。显然,合成器收到零音量时不会自动静音。

许多MIDI文件对控制器7进行了自己的更改。如果您的合成器支持Master Volume,则应该发送该文件。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...