更改 Java 中的 MIDI 音量

huangapple go评论74阅读模式
英文:

changing midi volume in java

问题

首先,更改音量是有效的,但在更改音量时遇到了一些问题,所以: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, i, 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();
    }
}

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) {
        e.printStackTrace();
    }
    music.setLoopCount(Sequencer.LOOP_CONTINUOUSLY);
    music.start();
}
英文:

first of all changing volume is working but i got some problems while changing the volume so 1) after changing the volume like setting it to 0 (no volume) you still hearing parts of the song in the default value of the volume 2)after song changed the volume getting back to the default value of the volume

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 &lt; 16; i++) {
volumeMessage.setMessage(ShortMessage.CONTROL_CHANGE, i, CHANGE_VOLUME,(int)(value * 127.0));
volumeMessage.setMessage(ShortMessage.CONTROL_CHANGE, i, 39, (int)(value * 127.0));
MidiSystem.getReceiver().send(volumeMessage, -1);
}
} else {  
MidiChannel[] channels = synthesizer.getChannels();
for( int c = 0; c &lt; channels.length; c++ ) {
if(channels[c] != null)   channels[c].controlChange( 7, (int)( value*127.0) );
}
}
music.setSequence(sequence);
} catch (Exception e) {
e.printStackTrace();
}
}

playing 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(&quot;Problem loading MIDI file.&quot;);
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 &lt; 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();
}

答案1

得分: 0

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

这段代码发送*一条*消息该消息的内容是第二个`setMessage`调用设置的值因此音量 MSB 不会改变
而这是计算 LSB 的错误方法。)

控制器 7 的确用于音量但并没有确切的标准来解释这些值显然您的合成器在接收到零音量时不会静音

许多 MIDI 文件会对控制器 7 进行自己的更改如果您的合成器支持[主音量](https://stackoverflow.com/q/26394515/11654),您应该发送该值。
英文:
volumeMessage.setMessage(ShortMessage.CONTROL_CHANGE, i, CHANGE_VOLUME,(int)(value * 127.0));
volumeMessage.setMessage(ShortMessage.CONTROL_CHANGE, i, 39, (int)(value * 127.0));
MidiSystem.getReceiver().send(volumeMessage, -1);

This code sends one message. The contents of that message are the values set by the second setMessage call, so the volume MSB is not changed at all.
(And this is the wrong way of computing the LSB.)

Controller 7 is indeed for volume, but there is no exact standard for how the values are to be interpreted. Apparently, your synthesizer does not mute itself when it receives a volume of zero.

Many MIDI files do their own changes to controller 7. If your synthesizer supports Master Volume, you should send that instead.

huangapple
  • 本文由 发表于 2020年8月22日 07:12:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/63531085.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定