产生正弦波会产生噪音
Generating sin wave creates noise
我有一个简单的 C 程序,可以生成特定频率、采样率和振幅的方波,效果很好。但是,如果我注释掉相关行并取消注释新的正弦波线,它会生成我的正弦波,但当我将输出处理为 Audacity 或 SoX.
时也会产生很多噪音
但是,包含我生成的缓冲区中数据的日志文件按预期读取,幅度内有符号值,相对于指定频率随时间(样本)振荡,没有意外值或噪音...
这可能会让我认为采样率或其他设置(字节顺序、mono/stereo、数据类型等)有问题,但正如我之前所说,方波没有这样的烦恼。我还确保所有计算都是使用双精度浮点类型完成的,这样我就知道整数强制转换不是我的问题。我很难过。欢迎任何帮助或见解。
这是我的:
#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);
}
您已将二进制输出发送到 stdout
,这是一个文本流,您可能将其重定向到一个文件。在某些操作系统上,文本流中的换行符会被转换。因此,当看到字节值 0x0A
或 0x0D
时,它会转换为另一个值,或者可能转换为两个值。它可能是 16 位值的一部分,例如 0x0D00
并且系统不知道这些是 16 位值。一个线索是生成的文件大小比预期的要大。
解决方法是以二进制模式打开一个文件,然后将数据写入其中。
关于其他评论:基值。有时数据的中心(零值)应该在 0x8000
并且数据被视为无符号并由玩家调整。我注意到您的数据被视为没有零偏移量的签名数据。
这意味着对于 1000
的振幅,数据要么在 -1000
到 +1000
范围内,要么在 31768
到 [=19= 范围内].
我有一个简单的 C 程序,可以生成特定频率、采样率和振幅的方波,效果很好。但是,如果我注释掉相关行并取消注释新的正弦波线,它会生成我的正弦波,但当我将输出处理为 Audacity 或 SoX.
时也会产生很多噪音但是,包含我生成的缓冲区中数据的日志文件按预期读取,幅度内有符号值,相对于指定频率随时间(样本)振荡,没有意外值或噪音...
这可能会让我认为采样率或其他设置(字节顺序、mono/stereo、数据类型等)有问题,但正如我之前所说,方波没有这样的烦恼。我还确保所有计算都是使用双精度浮点类型完成的,这样我就知道整数强制转换不是我的问题。我很难过。欢迎任何帮助或见解。
这是我的:
#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);
}
您已将二进制输出发送到 stdout
,这是一个文本流,您可能将其重定向到一个文件。在某些操作系统上,文本流中的换行符会被转换。因此,当看到字节值 0x0A
或 0x0D
时,它会转换为另一个值,或者可能转换为两个值。它可能是 16 位值的一部分,例如 0x0D00
并且系统不知道这些是 16 位值。一个线索是生成的文件大小比预期的要大。
解决方法是以二进制模式打开一个文件,然后将数据写入其中。
关于其他评论:基值。有时数据的中心(零值)应该在 0x8000
并且数据被视为无符号并由玩家调整。我注意到您的数据被视为没有零偏移量的签名数据。
这意味着对于 1000
的振幅,数据要么在 -1000
到 +1000
范围内,要么在 31768
到 [=19= 范围内].