C++数学函数生成
C++ mathematical function generation
在一个项目中,我遇到了准确生成各种波浪的需求。我原以为简单的正弦波是最容易开始的,但似乎我错了。我制作了一个简单的程序,生成样本的vector
,然后播放这些样本,以便用户听到波形,作为测试。以下是相关代码:
vector<short> genSineWaveSample(int nsamples, float freq, float amp) {
vector<short> samples;
for(float i = 0; i <= nsamples; i++) {
samples.push_back(amp * sinx15(freq*i));
}
return samples;
}
我不确定这是什么问题。我知道short
的矢量可能会有一些问题,但这正是我的音频框架想要的,而且我对这种库缺乏经验,所以不知道会发生什么。
症状如下:
- 频率不正确
- 即:给定freq=440,A4不是播放的音符
- 奇怪的失真
- 大多数频率不会产生干净的波。220、440、880都是干净的,其他大部分都变形了
- 大多数频率都显著向上移动
有人能就我可能做错了什么给出建议吗?
以下是我迄今为止所尝试的:
- 制作我自己的正弦函数,以获得更高的精度。
- 我对sin(x)使用了15次泰勒级数展开
- 改变了采样率,从256到44100,在给定上述误差的情况下,听不到任何变化,波只是更加失真
谢谢。如果有任何信息可以帮助你,我有义务提供。
我怀疑您向sin15x函数传递了不正确的值。如果你熟悉信号处理的基本原理,奈奎斯特频率是你可以忠实地重建(或在你的情况下构建)采样信号的最小频率。定义为信号中存在的最高频率分量的2x。
这对你的程序意味着,你需要在每个周期的最高频率的最后2个值,你想复制。在20Khz时,每秒需要40000个样本。看起来你只是在用值包装一个向量,并让播放程序对时间进行排序。
我们将假设您使用44.1Khz作为播放采样频率。这意味着一个产生1秒1kHz波的代码狙击看起来像
DataStructure wave = new DataStructure(44100) // creates some data structure of 44100 in length
for(int i = 0; i < 44100; i++)
{
wave[i] = sin(2*pi * i * (frequency / 44100) + pi / 2) // sin is in radians, frequency in Hz
}
你需要除以频率,而不是相乘。为了看到这一点,以通过22050 Hz频率值的情况为例。对于i=0,你得到sin(0)=1。对于i=1,sin(3pi/2)=-1等等。这会给你一个1,-1,1,-1的重复序列…这是以44.1Khz采样的22050Hz波的正确表示。这在频率下降时有效,但每个周期会得到越来越多的样本。有趣的是,这并没有什么区别。以每个周期2个样本采样的正弦波与每秒采样1000次的正弦波一样精确地重新创建。这没有考虑噪音,但对于大多数目的来说,效果足够好。
我建议研究数字信号处理的基础知识,因为这是一个非常有趣的领域,理解起来非常有用。
编辑:这假设所有这些参数都被计算为浮点数。
从根本上说,您缺少了一条信息。您没有指定要采集样本的时间。这也可以被认为是您的系统播放样本的速率。不过,就目前而言,大致朝着这个方向走会让你离得更近。
samples.push_back(amp * std::sin(M_PI / freq *i));
- "error: no matching function for call to"构造函数错误
- 什么时候调用组成单元对象的析构函数
- 继承函数的重载解析
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- C++模板来检查友元函数的存在
- 递归函数计算序列中的平方和(并输出过程)
- 对RValue对象调用的LValue ref限定成员函数
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 在C++STL中是否有Polyval(Matlab函数)等价物?
- 为什么使用 "this" 指针调用派生成员函数?
- 将对象数组的引用传递给函数
- 函数调用中参数的顺序重要吗
- 函数向量_指针有不同的原型,我可以构建一个吗
- 使用不带参数的函数访问结构元素
- 代码在main()中运行,但在函数中出现错误
- 内置函数可查看CPP中的成员变量
- 如何获取std::result_of函数的返回类型
- 如何在c++中为模板函数实例创建快捷方式
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗