英文:
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 < 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();
}
}
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("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();
}
答案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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论