【问题标题】:Generating sin wave creates noise产生正弦波会产生噪音
【发布时间】:2019-03-23 11:48:22
【问题描述】:

我有一个用 C 语言编写的简单程序,可以生成具有特定频率、采样率和幅度的方波,效果很好。但是,如果我注释掉相关行并取消注释新的正弦波行,它会生成我的正弦波,但是当我将输出处理为 Audacity 或SoX 时也会产生很多噪音。

但是,包含我生成的缓冲区中的数据的日志文件按预期读取,带符号的值在幅度内,相对于指定频率在时间(样本)上振荡,没有意外值或噪声...

这可能会让我认为采样率或其他设置(字节序、单声道/立体声、数据类型等)有问题,但正如我之前所说,方波没有这样的问题。此外,我确保所有计算都是使用双精度浮点类型完成的,所以我知道整数强制不是我的问题。我难住了。欢迎任何帮助或见解。

这是我所拥有的:

#define pi 3.1415926

int main()
{
    FILE *fer=fopen("log.txt","w");
    double f=440; //freq
    double a=1000; //amplitude
    double p=44100/f; //period

    int16_t *b=malloc(sizeof(int16_t)*44100);
    if(!b)return 1;

    for(int i=0;i<44100;i++)
    {
        double ll=sin( (2.0L*pi/p)*i ) * a;   //SINE WAVE
        // double ll=fmod(i,p)<p/2?a:-a;   //SQUARE WAVE
        b[i]= ll;
        fprintf(fer,"%i\n",b[i]);
    }

    fwrite(b,sizeof(int16_t),44100,stdout);

    free(b);
    fclose(fer);
}

【问题讨论】:

  • 例如,Audacity 中的噪音是什么样的?
  • 以前有人问过这个问题,但我找不到。问题在于以文本模式打开文件(默认情况下),数据0x0D 被转换,当它是一个字节时,比如0x140D 16 位值。以二进制模式打开文件。我不明白你为什么要向stdout 发送二进制数据。大概你重定向输出。看看生成的文件大小,是不是比预期的大?
  • 另外,数据中没有零偏移。 Audacity会介意吗?还是希望 16 位数据以 0x8000 为中心?
  • @WeatherVane 是的,你完全正确,在所有方面。使用标准输出只是替代实际文件管理的 CLI 简写。我从未想过stdout 不是二进制流。现在我觉得很笨。我想您可以根据需要创建一个答案,或者我可以删除该问题,因为它是重复的。另外,我不确定我是否理解第二个问题。也许 Audacity 从编码中收集偏移值(带符号的 16 位、32 位浮点数等)——对于 SoX 也是如此

标签: c audio trigonometry synthesizer sample-rate


【解决方案1】:

您已将二进制输出发送到stdout,这是一个文本流,您可能会将其重定向到一个文件。在某些操作系统上,文本流中的换行符会被转换。因此,当看到字节值0x0A0x0D 时,它会转换为另一个值,或者可能转换为两个值。它可能是 16 位值的一部分,例如 0x0D00 并且系统不知道这些是 16 位值。一个线索是生成的文件大小比预期的要大。

解决方案是以二进制模式打开一个文件并将数据写入该文件。

关于另一条评论:基值。有时数据的中心(零值)应位于0x8000,并且数据被视为无符号并由玩家调整。我注意到您的数据被视为没有零偏移的签名数据。

这意味着对于1000 的幅度,数据要么在-1000+1000 的范围内,要么在3176833768 的范围内。

【讨论】:

  • 再次感谢。所以对于这个问题,我相信 SoX 和 Audacity 的行为是不同的,如果仅仅是因为 UI 的不同。 SoX 更加灵活,因为它允许输入 16 位无符号或有符号的原始音频数据,而 Audacity(从 v 2.3.0 开始)只允许 有符号 16 位原始音频数据(它确实允许无符号 8 位)。在这种情况下,SoX 会将 0x8000 解释为基值(无符号),如果有符号,两者都将使用 0x0000。我实际上检查了两者,SoX 会反转有符号输入的每一半(在无符号模式下)。希望这有点清楚
  • 嗯,是的,我想编码系统可以通过极端区域的数据缺失来检测(如果不饱和/未裁剪)。
猜你喜欢
  • 1970-01-01
  • 2020-05-03
  • 1970-01-01
  • 1970-01-01
  • 2011-07-25
  • 1970-01-01
  • 2016-08-17
  • 2018-10-17
  • 2021-05-13
相关资源
最近更新 更多