Java-调整WAV文件的播放速度
我可能很笨,但我似乎找不到解决问题的办法 (注意:我可以找到很多人报告这个问题,似乎这是由于较新的Java(可能是1.5?)造成的。也许不再支持采样率?我找不到任何解决方案) 我正在尝试调整采样率以加快/减慢歌曲。我可以成功地播放.wav文件而不会出现问题,因此我研究了用于调整音量的FloatControl:Java-调整WAV文件的播放速度,java,audio,javasound,pcm,audio-processing,Java,Audio,Javasound,Pcm,Audio Processing,我可能很笨,但我似乎找不到解决问题的办法 (注意:我可以找到很多人报告这个问题,似乎这是由于较新的Java(可能是1.5?)造成的。也许不再支持采样率?我找不到任何解决方案) 我正在尝试调整采样率以加快/减慢歌曲。我可以成功地播放.wav文件而不会出现问题,因此我研究了用于调整音量的FloatControl: public void adjustVolume(String audioType, float gain) { FloatControl gainControl = nu
public void adjustVolume(String audioType, float gain) {
FloatControl gainControl = null;
gainControl = (FloatControl) clipSFX.getControl(FloatControl.Type.MASTER_GAIN);
if(gain > MAX_VOLUME)
gain = MAX_VOLUME;
if(gain < MIN_VOLUME)
gain = MIN_VOLUME;
//set volume
gainControl.setValue(gain);
}
我在网上找到的所有东西似乎都与从麦克风或外线获取输入有关,而且似乎无法转化为使用音频文件,所以我不确定我缺少了什么。任何帮助都将不胜感激!谢谢 这里我们有一种改变速度的方法-通过加倍采样率。基本步骤如下:
- 打开文件的音频流
- 获取格式
- 在更改采样率的情况下创建新格式
- 打开具有该格式的数据行
- 读取文件/音频流并在线播放
public void play() {
try {
File fileIn = new File(" ....);
AudioInputStream audioInputStream=AudioSystem.getAudioInputStream(fileIn);
AudioFormat formatIn=audioInputStream.getFormat();
AudioFormat format=new AudioFormat(formatIn.getSampleRate()*2, formatIn.getSampleSizeInBits(), formatIn.getChannels(), true, formatIn.isBigEndian());
System.out.println(formatIn.toString());
System.out.println(format.toString());
byte[] data=new byte[1024];
DataLine.Info dinfo=new DataLine.Info(SourceDataLine.class, format);
SourceDataLine line=(SourceDataLine)AudioSystem.getLine(dinfo);
if(line!=null) {
line.open(format);
line.start();
while(true) {
int k=audioInputStream.read(data, 0, data.length);
if(k<0) break;
line.write(data, 0, k);
}
line.stop();
line.close();
}
}
catch(Exception ex) { ex.printStackTrace(); }
}
public void play(){
试一试{
File fileIn=新文件(“..”);
AudioInputStream AudioInputStream=AudioSystem.getAudioInputStream(fileIn);
AudioFormat formatIn=audioInputStream.getFormat();
AudioFormat format=新的AudioFormat(formatIn.getSampleRate()*2,formatIn.getSampleSizeInBits(),formatIn.GetChannel(),true,formatIn.isBigEndian());
System.out.println(formatIn.toString());
System.out.println(format.toString());
字节[]数据=新字节[1024];
DataLine.Info dinfo=新的DataLine.Info(SourceDataLine.class,格式);
SourceDataLine=(SourceDataLine)AudioSystem.getLine(dinfo);
如果(行!=null){
行。打开(格式);
line.start();
while(true){
int k=audioInputStream.read(数据,0,数据.长度);
如果(k这里我们有一种改变速度的方法-通过加倍采样率。基本步骤如下:
- 打开文件的音频流
- 获取格式
- 在更改采样率的情况下创建新格式
- 打开具有该格式的数据行
- 读取文件/音频流并在线播放
这里的概念是SourceDataLine、AudioFormat和AudioInputStream。如果您查看javax.sound教程,您会发现它们,甚至可以找到类的页面。您现在可以创建自己的方法(如adjust(factor)),该方法只获取新格式,其他方法保持不变
public void play() {
try {
File fileIn = new File(" ....);
AudioInputStream audioInputStream=AudioSystem.getAudioInputStream(fileIn);
AudioFormat formatIn=audioInputStream.getFormat();
AudioFormat format=new AudioFormat(formatIn.getSampleRate()*2, formatIn.getSampleSizeInBits(), formatIn.getChannels(), true, formatIn.isBigEndian());
System.out.println(formatIn.toString());
System.out.println(format.toString());
byte[] data=new byte[1024];
DataLine.Info dinfo=new DataLine.Info(SourceDataLine.class, format);
SourceDataLine line=(SourceDataLine)AudioSystem.getLine(dinfo);
if(line!=null) {
line.open(format);
line.start();
while(true) {
int k=audioInputStream.read(data, 0, data.length);
if(k<0) break;
line.write(data, 0, k);
}
line.stop();
line.close();
}
}
catch(Exception ex) { ex.printStackTrace(); }
}
public void play(){
试一试{
File fileIn=新文件(“..”);
AudioInputStream AudioInputStream=AudioSystem.getAudioInputStream(fileIn);
AudioFormat formatIn=audioInputStream.getFormat();
AudioFormat format=新的AudioFormat(formatIn.getSampleRate()*2,formatIn.getSampleSizeInBits(),formatIn.GetChannel(),true,formatIn.isBigEndian());
System.out.println(formatIn.toString());
System.out.println(format.toString());
字节[]数据=新字节[1024];
DataLine.Info dinfo=新的DataLine.Info(SourceDataLine.class,格式);
SourceDataLine=(SourceDataLine)AudioSystem.getLine(dinfo);
如果(行!=null){
行。打开(格式);
line.start();
while(true){
int k=audioInputStream.read(数据,0,数据.长度);
如果(k),也可以在音频数据中前进时使用线性插值来改变速度
音频值以数组形式排列,光标通常从一个值移动到另一个值。但您可以设置进度为任意数量,例如1.5帧,并在需要时创建加权值
假设数据如下所示:
0.5
0.8
0.2
-0.1
-0.5
-0.7
您的播放数据(速率为1.5)将为
0.5
(0.8+0.2)/2
-0.1
(-0.5+-0.7)/2
我知道在堆栈溢出之前,有一些帖子更全面地解释了这个算法。请原谅我没有跟踪他们
我使用此方法允许在以下开源库中实时更改.wav播放速度:。请随意查看代码并利用其中的思想
以下是从位于两个音频帧之间的点创建立体声音频值对的方法(数据是有符号浮动的,范围从-1到1)。它来自AudioCue.java
中的内部类AudioCue播放器
。可能不是最容易读取的。正在读取的声音数据位于数组cue
中,idx
是当前的“播放头”正在通过此数组的位置。“intIndex”是音频帧,“flatIndex”是帧在数组中的实际位置。我使用帧跟踪播放头的位置并计算插值权重,然后使用flatIndex从数组中获取相应的值
private float[] readFractionalFrame(float[] audioVals, float idx)
{
final int intIndex = (int) idx;
final int flatIndex = intIndex * 2;
audioVals[0] = cue[flatIndex + 2] * (idx - intIndex)
+ cue[flatIndex] * ((intIndex + 1) - idx);
audioVals[1] = cue[flatIndex + 3] * (idx - intIndex)
+ cue[flatIndex + 1] * ((intIndex + 1) - idx);
return audioVals;
}
如果有问题,我很乐意澄清。在处理音频数据时,也可以使用线性插值来改变速度
音频值以数组形式排列,光标通常从一个值移动到另一个值。但您可以设置进度为任意数量,例如1.5帧,并在需要时创建加权值
假设数据如下所示:
0.5
0.8
0.2
-0.1
-0.5
-0.7
您的播放数据(速率为1.5)将为
0.5
(0.8+0.2)/2
-0.1
(-0.5+-0.7)/2
我知道有一些帖子更全面地解释了这一点