【问题标题】:Slow down audio speed降低音频速度
【发布时间】:2017-08-05 15:58:28
【问题描述】:

所以在下面的程序中,它会加快音频文件的速度,让它听起来好像这个人有一个“氦气声音”。这是通过更改索引值来完成的,当您增加它时,文件会变得更高音调和更快。我想知道是否有办法做相反的事情,让音频播放得更慢,声音更深。

public void helium(String sourceFile, String targetFile)
{
    Sound sourceObj = new Sound(sourceFile);                               
    Sound target = new Sound(targetFile);   
    int sampleValue = 0;                                              
    int targetIndex = 0;                                                

    for(int index = 0; index < sourceObj.getLength(); index+=2)
    {
        sampleValue = sourceObj.getSampleValueAt(index);                    
        target.setSampleValueAt(targetIndex,sampleValue);                   
        targetIndex++;                                                      
    }
    target.play();  

}

【问题讨论】:

  • 使用负值?
  • 如果给索引放负值,只会报错
  • 如果你加1并使用index / 2会怎样?
  • 我刚试过,但它只是让音频听起来正常,只播放一半的音频。

标签: java audio


【解决方案1】:

与其将样本大小减半,不如将样本大小翻倍,并使用每个值两次。我敢肯定还有更高级的方法,但这会使波形的前进速度减慢两倍,从而产生更低音调的声音。

我必须做出一些假设,因为您使用了一些我不熟悉的非标准声音 API。为了确保您的声音对于目标样本不会太长,我现在将源中的索引限制为目标样本最大大小的一半 (index &lt; target.getLength()/2)

int sampleValue = 0;                                              
int targetIndex = 0;                                                

for(int index = 0; index < target.getLength()/2; index++)
{
    sampleValue = sourceObj.getSampleValueAt(index);                    
    target.setSampleValueAt(targetIndex, sampleValue);
    target.setSampleValueAt(targetIndex + 1, sampleValue);                   
    targetIndex += 2;                                                      
}

【讨论】:

  • 抱歉,我是 Java 新手,但是当我将代码更改为您编写的代码时,它会产生一个错误,提示“该索引 443904,不存在。最后一个有效索引是 443903 ”。很抱歉,如果您可以更改代码或为我解释代码,我真的不知道这意味着什么。
  • @DannyM 更新了答案。请参阅“为确保您的声音对于目标样本来说不会太长,我现在将源中的索引限制为目标样本最大大小的一半 (index &lt; target.getLength()/2)”
  • 谢谢你成功了。如果你不介意我问,你知道我上面说的那个错误为什么会发生吗? (对不起,我对编程很陌生)
  • 看起来您的目标Sound 样本是根据磁盘上文件的长度创建的,您不能简单地通过将样本值设置为更高的索引来扩展样本的长度。您可能希望以不同的方式创建您的目标声音:Sound target = new Sound(sourceObject.getLength() * 2);,然后您可以循环到 index &lt; target.getLength(),基于此 Javadoc(但我无法验证,因为我没有您的库)@987654321 @
【解决方案2】:

天真的方法是将每个样本加倍。

一种不那么天真的方法是分割样本之间的差异(线性插值)。

正确的方法是在每个样本之间插入一个零,然后应用一个低通滤波器来拒绝任何高于一半采样率的信号。见https://en.wikipedia.org/wiki/Upsampling

【讨论】:

    猜你喜欢
    • 2022-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-25
    • 2022-09-25
    相关资源
    最近更新 更多