如何更改剪辑的分贝

How do I change the decibels of a clip

我遇到的问题是音频文件的分贝仅从 programVolume(变量)的初始值开始变化,但我有一个 JSlider 可以改变变量的值;但是,它不会改变分贝的文件。我如何add/change 确保基于从 JSlider 中为变量设置的值更改小数。

  File fileSong = new File (filePath); 
  AudioInputStream input = AudioSystem.getAudioInputStream(fileSong); 
  clip = AudioSystem.getClip(); 
  clip.open(input); 
  FloatControl gainControl = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);
  gainControl.setValue(programVolume);
  clip.start();

编辑:

我添加了以下代码:

  File fileSong = new File (filePath); 
  AudioInputStream input = AudioSystem.getAudioInputStream(fileSong);
  clip = AudioSystem.getClip(); 
  clip.open(input); 

  FloatControl gainControl = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);
  float range = gainControl.getMaximum() - gainControl.getMinimum();
  float gain = (range * programVolume) + gainControl.getMinimum();
  gainControl.setValue(gain);

对于我的 JSlider(在方法 ChangeEvent e 中)

    programVolume =  (float)volume.getValue() / 100; 

我仍然面临同样的问题。从 JSlider 收到的新值不会更改音量。只有 programVolume 的初始值会改变声音。

我想通了!每当使用 JSlider 更改变量时,剪辑都必须停止,并且它停止的点将存储到变量中。我选择了一个很长的剪辑,然后必须重新启动剪辑,当它重新启动时,它使用用户选择的新音量,并且它在它停止的同时开始,给用户一种错觉,即音量在音频时被改变了-文件停止时正在播放,改变音量,然后恢复。 Math.Log 东西用于 calculate/convert 我们知道的音量系统的分贝 (0%-100%) 左右我认为。

  File fileSong = new File (filePath);
  AudioInputStream input = AudioSystem.getAudioInputStream(fileSong); 
  clip = AudioSystem.getClip(); 
  clip.open(input); 
  clip.setMicrosecondPosition(position); 

  FloatControl gainControl = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN); 
  float range = (float) (Math.log(userInput) / Math.log(10) * 20); 
  gainControl.setValue(range); 
  clip.start(); 

@gthanop 对 ShaleeQureshi 回答的第一个建议非常重要。重新加载 Clip 是非常低效的。必须重新加载整个 Clip 才能重新启动。

控件通常会出现问题,因为它们依赖于与不同系统交互的本机代码。在一台 PC 上实现的控件可能无法在另一台 PC 上实现,因为该 PC 上缺少功能。

出现的另一个问题是控件引起的更改与缓冲区边界相关联。例如,如果缓冲区的长度为半秒,则新值生效最多需要半秒。

音频文件本身没有 "decibel" 控件。相反,音量来自形成信号的数据值的动态范围。一个安静的文件可能只在 -0.05 到 0.05 之间,而一个响亮的文件可能更像是 -0.5 到 0.5。音频文件可能有响亮的部分和柔和的部分,但整体仍直接编码为信号值。 .wav 文件上没有 "volume" 控件。

由于无法依赖 Java 提供的控件,您可能需要查看 github 资源 AudioCue。它基本上是一个增强的 Clip,具有实时音量控制。该代码具有许可,可以免费使用或检查想法。基本原则是将数据存储在 float[] 而不是 Clip 中,并通过 SourceDataLine 播放它,同时不断参考与信号相乘的体积因子流式传输的值。