Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java播放错误的声音频率_Java_Audio_Frequency_Javasound_Waveform - Fatal编程技术网

Java播放错误的声音频率

Java播放错误的声音频率,java,audio,frequency,javasound,waveform,Java,Audio,Frequency,Javasound,Waveform,我正在编写一个java声音应用程序,它可以从一个频率线性过渡到另一个频率 当我输入一个恒定的频率(即第一个和最后一个频率相同)时,将播放正确的频率 但是,每当两个频率之间的差值大于零时,播放的频率从正确的值开始,但以两倍的速率递增,最后以两倍的差值结束。(例如,输入500和1000;频率从500开始到1500结束) 我原本以为我只是错误地增加了频率,但当我打印频率值时,它会打印我想要的值(例如,我输入500和1000;打印输出从500开始,到1000结束) 我通过记录输出声音并查看频谱图上的频率

我正在编写一个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();
    }
}
import java.lang.Math;
导入javax.sound.sampled.*;
公开课主讲{
公共静态void main(字符串[]args)引发LineUnavailableException{
倍频;//频率单位为Hz
int体积=30;
int time=1;//以秒为单位
浮子采样器=8000.0f;//单位为Hz
int numSamples=(int)(采样器*时间);/#给定时间内的样本数
字节流[]=新字节[(int)(sampleRate*1)];//波形值
频率=700;
对于(int i=0;i

在这个简化的代码段中,频率应该从700开始,增加8000倍,增加0.1,以1500频率结束,打印输出正确显示。但是,音频实际上在2300处结束。

这里有一个错误:

2*Math.PI*i*freq/sampleRate
在此处使用i或freq,但不要同时使用它们。你得到的不是频率的线性变化,而是平方变化。如果您希望它按照下面描述的方式运行,请使用

2*Math.PI*freq/sampleRate

为了更快地获得更好的帮助,请发布一个。好的。如果您复制并粘贴代码,代码现在应该可以工作了。好的,它确实可以工作。我做了一个WAV的声音,并打算上传到我的网站,以便于分析(希望其他人已经安装了频谱分析软件)。但目前我无法访问我的网站。。在eSnips上可以,但不允许热链接。这不是重复的问题,因为它是“在代码中查找错误”的问题类型。代码完全不同。好吧,我想出来了!我的代码中的错误是创建正弦波的数学。要创建平滑的正弦波,相位必须是连续的,因此方程需要是相位的函数,而不是频率的函数(另请注意:相位是频率的积分)。对于任何有类似问题的人,有一个非常简短和简单的数学解释。干得好。我同意,这不是复制品。有没有办法让我投票删除“重复”状态?@Philfreihoff谢谢。你还不能投票支持“打开/关闭”。仅从3k开始:-(.但是你可以通过一个标志将问题提交给版主。因此,为了赢得一个“有用的标志”,感谢Gangnus——我按照你的建议做了。显然,OP决定在他的解决方案中使用I而不是freq,尽管两者都应该有效,并且都比另一个更连续。谢谢,但我解决了问题(在上面的评论中陈述)你所说的是不正确的。“freq”是一个常数,“i”是变量。如果“i”不存在,那么方程的值永远不会改变。如果“freq”不存在,方程将与频率毫无关系。“freq+=0.1;”freq怎么可能是常数?你必须学会看到你的错误。