在java中改变midi音量
Posted
技术标签:
【中文标题】在java中改变midi音量【英文标题】:changing midi volume in java 【发布时间】:2020-08-21 23:12:01 【问题描述】:首先,改变音量是有效的,但我在改变音量时遇到了一些问题,所以 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();
播放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】: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 的错误方法。)
Controller 7 确实适用于音量,但对于如何解释这些值没有确切的标准。显然,当您的合成器接收到零音量时,它不会自行静音。
许多 MIDI 文件对控制器 7 进行自己的更改。如果您的合成器支持 Master Volume,您应该发送它。
【讨论】:
所有时间 synthesizer.getDefaultSoundbank() 不是空的,所以它转到这里 MidiChannel[] channels = synthesizer.getChannels(); for( int c = 0; c以上是关于在java中改变midi音量的主要内容,如果未能解决你的问题,请参考以下文章
Windows Vista/7 上的 SDL_Mixer MIDI 音量问题