【问题标题】:How to Add Harmonics to Sine Waves如何向正弦波添加谐波
【发布时间】:2025-11-27 22:15:01
【问题描述】:

在没有发布整个头文件和 cpp 文件的情况下,我在这里有一些代码可以生成正弦波:

void CAudioGenerate::GenereateSinewave() 
{
   if(!GenerateBegin())
      return;

   short audio[2];

   for(double time=0.;  time < m_duration;  time += 1. / m_sampleRate)
   {                 
      audio[0] = short(m_amplitude * sin(time * 2 * M_PI * m_freq1));
      audio[1] = short(m_amplitude * sin(time * 2 * M_PI * m_freq1));

      GenerateWriteFrame(audio);

// Progress
      if(!GenerateProgress(time / m_duration))
         break;
   }


   // Close generator
   GenerateEnd();
}

我想添加一些谐波,将幅度降低 1/2、1/3 和 1/4。我认为我必须改变 m_amplitude 但我不完全确定哪种方法是正确的。

我考虑过添加m_amplitude = m_amplitude*(1/time),但没有奏效。

【问题讨论】:

  • 这似乎是一道数学题而不是编程题。
  • 我对信号处理几乎一无所知,但你不能通过生成两个波并添加(或减去)它们来做到这一点吗?参见例如this image(关于如何生成方波,但我猜可以用来生成任何形状)。
  • 我做了一点信号处理,但我不知道谐波(不同频率的声音)会如何持续影响您的幅度。不同的频率在不同的点上会相加和相减。
  • 我制作了一个 2f 谐波的图像,并展示了幅度如何同时变大和变小:i.imgur.com/Sc89xMo.jpg
  • 现在..如果你和两个声音在相同频率下反向同步......第二个反向声音的幅度较小,你会有效地降低幅度......但在代码中 -为什么不让你的 m_amplitude 更小呢?

标签: c++ signal-processing


【解决方案1】:

谐波在幅度中是不相关的。相反,谐波是具有N=2,3,4...频率 的波。混合不同的波只是添加组件的问题。

因此,对于两个谐波,代码为:

audio[0] = short(m_amplitude[0] * sin(time * 2 * M_PI * m_freq1))
         + short(m_amplitude[1] * sin(time * 4 * M_PI * m_freq1))
         + short(m_amplitude[2] * sin(time * 6 * M_PI * m_freq1));

【讨论】:

  • 随着距离 2*pi 越来越远,三角函数不会开始失去准确性吗?随着时间的推移,您可能会发现相位误差逐渐出现。
  • 是的。在 sin(2^55) 附近,您根本没有任何准确性。如果您仍在为基本触发而苦苦挣扎,我怀疑这不是一个主要问题。如果我需要想出一种方法来解决这个问题,我可能会选择核心数学:sin(x+dx)=sin x cos dx + cos x sin dx; cos(x+dx)=cos x cos dx - sin x sin dx。您可以通过跟踪sin(x)cos(x) 来增量计算sin(x+dx)。你仍然有一些舍入错误,所以你可能需要标准化为sin(x)^2 + cos(x)^2 = 1。但您只需要在这里准确的sin(dx),它通常非常准确。
  • 是的,我认为你是对的。您使用 4 和 6 的任何原因?
  • @ratman2050:第一个谐波是双频,所以2 * (2 * M_PI * m_freq1) = 4 * ...,第二个是3 * ( 2 * M_PI * ...