周期性功能发生器,千周后波长误差

发布于 2025-02-01 09:35:15 字数 3527 浏览 1 评论 0原文

我正在使用C ++代码生成各种形式的PCM声波使用正弦函数的谐波,然后在Audacity中导入文件以查看结果后,以最大的样本速率大胆进行导入可以支持原始数据文件(签名16位, ,384000Hz)只是为了发现采样谐波中可能的错误。我发现的问题是,在5000个样品后,锯齿波的长度与原始的罪基底座和正方形的一号(这2个在最终宽度中对齐)。我真的不明白的锯齿波的长度错误出现了。

代码:

#include <iostream>
#include <fstream>
#include <cmath>

typedef char               sint8;
typedef unsigned char      uint8;
typedef signed short int   sint16;
typedef unsigned short int uint16;
typedef unsigned int       uint32;

using namespace std;

#define PI 3.14159265F

#define DEG2RAD(value) ((float)(value) * (PI/180.F))

// Just for debugging LSB and MSB
void dec2bin(signed long int number, unsigned short size)
{
    int c, k;
    for (c = (size*8)-1; c >= 0; c--)
    {
        k = number >> c;
        if (k & 1)
            printf("1");
        else
            printf("0");
        if (c % 4 == 0)
            printf(" ");
    }
    printf("\n");
}

float generateSquareWave(uint32 degreeValue, uint32 harmonics, uint32 frequency)
{
  float resultSinSum = 0.F;

  for(uint32 degreeIndex = 0x00000001U; degreeIndex <= 0x00000002U*harmonics; degreeIndex += 0x00000002U)
  {
      resultSinSum += ((1.F/(float)(degreeIndex))*sin(((float)(frequency))*((float)(degreeIndex))*DEG2RAD(degreeValue)));
  }

  return resultSinSum;
}

float generateSawTooth(uint32 degreeValue, uint32 harmonics, uint32 frequency)
{
  float resultSinSum = 0.F;

  for(uint32 degreeIndex = 0x00000001U; degreeIndex <= 0x00000002U*harmonics; degreeIndex += 0x00000001U)
  {
      resultSinSum += ((1.F/(float)(degreeIndex))*sin(((float)(frequency))*((float)(degreeIndex))*DEG2RAD(degreeValue)));
  }

  return -(0.615F * resultSinSum);
}

int main()
{
  const uint32 WAVE_CYCLES = 5000U;
  const uint32 DEGREE_PER_CYCLE = 360U;
  const uint32 NUMBER_OF_SAMPLES = WAVE_CYCLES * DEGREE_PER_CYCLE;

  sint8 functionSamples[NUMBER_OF_SAMPLES] = {};

  ofstream myfile;

  myfile.open("sound.raw");

  for(uint32 degreeIndex = 0x00000000; degreeIndex <= NUMBER_OF_SAMPLES; degreeIndex += 0x00000001U)
  {
      // ORIGINAL: float soundFunction = sin(DEG2RAD(degreeIndex));
      //float soundFunction = cos(DEG2RAD(degreeIndex));
      //float soundFunction = sqrt(DEG2RAD(degreeIndex));

      //float soundFunction = generateSquareWave(degreeIndex, 16U, 1U);

      float soundFunction = generateSawTooth(degreeIndex, 16U, 1U);

      soundFunction = soundFunction * 32768;

      if( soundFunction > 32767 ) soundFunction = 32767;
      if( soundFunction < -32768 ) soundFunction = -32768;

      // Write LSB 16b int PCM from float32
      functionSamples[degreeIndex] = static_cast<sint8>(static_cast<sint16>(soundFunction) >> 8);
      functionSamples[degreeIndex+1] = static_cast<sint8>(soundFunction);
  }

  myfile.write(&functionSamples[0], NUMBER_OF_SAMPLES);

  myfile.close();

  return 0;
}

前5个周期的宽度对齐:

5000循环后: 似乎锯齿波具有更大的周期,但与其他2个初始波相同,只是循环宽度中的长度不同,我没有解释。

我还在Google绘图视图中重叠波浪,以发现错误,但没有错误:

I am generating from C++ code various forms of a PCM sound wave using composed harmonics of sine functions, then after importing file in Audacity to see the result, import is done at a maximum sample rate Audacity can support for raw data files (signed 16 bits, 384000Hz) just to spot possible errors in sampled harmonics. The problem what I have spotted is that after 5000 samples the sawtooth wave differ in length than the original sin base and the square one (these 2 are aligned in the final width). Where the length error is coming for the sawtooth wave I really do not understand.

Code:

#include <iostream>
#include <fstream>
#include <cmath>

typedef char               sint8;
typedef unsigned char      uint8;
typedef signed short int   sint16;
typedef unsigned short int uint16;
typedef unsigned int       uint32;

using namespace std;

#define PI 3.14159265F

#define DEG2RAD(value) ((float)(value) * (PI/180.F))

// Just for debugging LSB and MSB
void dec2bin(signed long int number, unsigned short size)
{
    int c, k;
    for (c = (size*8)-1; c >= 0; c--)
    {
        k = number >> c;
        if (k & 1)
            printf("1");
        else
            printf("0");
        if (c % 4 == 0)
            printf(" ");
    }
    printf("\n");
}

float generateSquareWave(uint32 degreeValue, uint32 harmonics, uint32 frequency)
{
  float resultSinSum = 0.F;

  for(uint32 degreeIndex = 0x00000001U; degreeIndex <= 0x00000002U*harmonics; degreeIndex += 0x00000002U)
  {
      resultSinSum += ((1.F/(float)(degreeIndex))*sin(((float)(frequency))*((float)(degreeIndex))*DEG2RAD(degreeValue)));
  }

  return resultSinSum;
}

float generateSawTooth(uint32 degreeValue, uint32 harmonics, uint32 frequency)
{
  float resultSinSum = 0.F;

  for(uint32 degreeIndex = 0x00000001U; degreeIndex <= 0x00000002U*harmonics; degreeIndex += 0x00000001U)
  {
      resultSinSum += ((1.F/(float)(degreeIndex))*sin(((float)(frequency))*((float)(degreeIndex))*DEG2RAD(degreeValue)));
  }

  return -(0.615F * resultSinSum);
}

int main()
{
  const uint32 WAVE_CYCLES = 5000U;
  const uint32 DEGREE_PER_CYCLE = 360U;
  const uint32 NUMBER_OF_SAMPLES = WAVE_CYCLES * DEGREE_PER_CYCLE;

  sint8 functionSamples[NUMBER_OF_SAMPLES] = {};

  ofstream myfile;

  myfile.open("sound.raw");

  for(uint32 degreeIndex = 0x00000000; degreeIndex <= NUMBER_OF_SAMPLES; degreeIndex += 0x00000001U)
  {
      // ORIGINAL: float soundFunction = sin(DEG2RAD(degreeIndex));
      //float soundFunction = cos(DEG2RAD(degreeIndex));
      //float soundFunction = sqrt(DEG2RAD(degreeIndex));

      //float soundFunction = generateSquareWave(degreeIndex, 16U, 1U);

      float soundFunction = generateSawTooth(degreeIndex, 16U, 1U);

      soundFunction = soundFunction * 32768;

      if( soundFunction > 32767 ) soundFunction = 32767;
      if( soundFunction < -32768 ) soundFunction = -32768;

      // Write LSB 16b int PCM from float32
      functionSamples[degreeIndex] = static_cast<sint8>(static_cast<sint16>(soundFunction) >> 8);
      functionSamples[degreeIndex+1] = static_cast<sint8>(soundFunction);
  }

  myfile.write(&functionSamples[0], NUMBER_OF_SAMPLES);

  myfile.close();

  return 0;
}

First 5 cycles are aligned in width:
enter image description here

After 5000 cycles:
Seems that sawtooth wave have a bigger number of periods, but is same as the other 2 initial waves just the length in the cycle width differ for which I don't have a explanation.
enter image description here

I also overlap waves in the Google plot view to spot the error but no error:
enter image description here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文