【问题标题】:Java playing wrong sound frequencyJava播放错误的声音频率
【发布时间】:2013-01-09 04:35:11
【问题描述】:

我正在编写一个从一个频率线性转换到另一个频率的 java 声音应用程序。

当我输入一个恒定的频率(也就是第一个和最后一个频率相同)时,播放正确的频率。

但是,只要两个频率之间的差异大于零,播放的频率就会以正确的值开始,但以两倍的速率递增,并以两倍的差异结束。(例如我输入500和1000;频率从500开始,到1500结束)。

我最初认为我只是错误地增加了频率,但是当我打印频率值时,它会打印出我想要的值(例如,我输入 500 和 1000;打印输出从 500 开始到 1000 结束)。

我通过记录输出声音并在频谱图上查看其频率来检查可听频率的值。这是我的代码的相关简化部分:

import java.lang.Math;
import javax.sound.sampled.*;

public class MainSpeech {

    public static void main(String[] args) throws LineUnavailableException {

        double freq; //  frequency in Hz
        int volume = 30;
        int time = 1; // in seconds
        float sampleRate = 8000.0f; // in Hz
        int numSamples = (int)(sampleRate * time); // # of samples within given time
        byte stream[] = new byte[(int)(sampleRate*1)]; // waveform values

        freq = 700;
        for (int i = 0; i < numSamples; i++) {
            freq += 0.1;
            stream[i] = (byte) (Math.sin(2*Math.PI*i*freq/sampleRate)*volume);
        }

        AudioFormat af = new AudioFormat(sampleRate, 8, 1, true, false);
        SourceDataLine sdl = AudioSystem.getSourceDataLine(af);
        sdl.open(af);
        sdl.start();
        sdl.write(stream, 0, stream.length); // play sound
        sdl.drain();
        sdl.close();
    }
}

在这个简化的 sn-p 中,频率应该从 700 开始,增加 8000 倍 0.1,以 1500 的频率结束,打印输出正确显示。然而,可听频率实际上在 2300 处结束。

【问题讨论】:

  • 如需尽快获得更好的帮助,请发帖SSCCE
  • 好的,如果您复制并粘贴代码现在应该可以工作了。
  • 好的,它确实有效。我制作了声音的 WAV,并打算将其上传到我的站点以便于分析(希望其他人已经安装了频谱分析软件)。但目前我无法访问我的网站! ..OK here it is 在 eSnips 上,但它不允许热链接。
  • 这不是重复问题,因为它是“在代码中查找错误”的问题类型。而且代码肯定不一样。
  • 好吧,我想通了!我的代码中的错误是创建正弦波的数学。要创建平滑的正弦波,相位必须是连续的,因此方程需要是相位的函数,而不是频率的函数(另请注意:相位是频率的积分)。对于任何有类似问题的人,Wikipedia 有一个非常简短的数学解释。

标签: java audio frequency javasound waveform


【解决方案1】:

这里有一个错误:

2*Math.PI*i*freq/sampleRate

在此处使用 i 或 freq,但不能同时使用。你所拥有的不是频率的线性变化,而是二次的。如果您希望它的行为如下所述,请使用

2*Math.PI*freq/sampleRate

【讨论】:

  • 干得好。我同意,这不是重复的。有没有办法让我投票删除“重复”状态?
  • @PhilFreihofner 谢谢。您还不能投票支持打开/关闭。仅从 3k 起 :-(。但是您可以通过标志将问题提交给版主。从而赢得“有用的标志”
  • 谢谢 Gangnus -- 我按照你的建议做了。显然,OP 决定在他的解决方案中使用 i 而不是 freq ,尽管两者都应该可以工作,而且两者都不比另一个更连续。
  • 谢谢,但我解决了问题(在上面的评论中说明)并且您所说的不正确。 “freq”是一个常数,“i”是变量。如果“i”不存在,则等式的值将永远不会改变。如果“freq”不存在,则方程与频率无关。
  • '频率 += 0.1;'多少频率可以是一个常数?你必须学会​​看到你的错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-23
  • 1970-01-01
  • 2010-11-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多