使用 sin() 生成的声音中的金属声音

Posted

技术标签:

【中文标题】使用 sin() 生成的声音中的金属声音【英文标题】:Metalic sound from generated sound with sin() 【发布时间】:2014-01-19 16:45:20 【问题描述】:

我有以下代码,混合了different sources,因为我是从 C 和 php 背景学习 C++:

int main() 
  const unsigned int sampleRate = 48000;
  // prepare a 6 seconds buffer and write it
  const unsigned long int size = sampleRate*6;
  float sample[size];
  unsigned long int i = 0;
  unsigned long insin, insinb, factor;

  // Multiply for 2*pi and divide by sampleRate to make the default period of 1s
  // So the freq can be stated in Hz
  factor = 2*3.141592;

  for (i; i<size; i++) 
    // Store the value of the sin wave
    insin = 440*float(i)*factor/float(sampleRate);
    insinb = 880*float(i)*factor/float(sampleRate);

    if (i > size/8)
      // Attempt to make it sound more instrument-like
      sample[i] = 0.7 * sin(insin) + 0.3 * sin(insinb);
    else
      sample[i] = 0.7 * sin(insinb) + 0.3 * sin(insin);

    // DEBUG
    if (i < 1000)
      printf("%f\n", sample[i]);
    

  writeWAVData("sin.mp3", sample, size, sampleRate, 1);
  return 1;
  

它会创建 .mp3 文件。但是,它总是 1 秒长,并且具有非常金属的声音。从// DEBUG 中,我检索了并非真正类似于正弦的值。一小部分:

0.637161
0.637161
0.637161
0.070853
0.070853
0.070853
0.070853
0.070853
0.070853
0.070853
0.070853
0.070853
-0.383386
-0.383386
-0.383386
-0.383386
-0.383386

我认为金属声音可能来自于 sin() 返回值过于方形的事实。为什么会这样? 我可以让 sin() 返回一个“质量更好”的函数,还是我做错了什么?如果您有任何兴趣,这里是代码的开头和其余部分: p>

#include <fstream>
#include <cmath>
#include <sndfile.hh>

template <typename T>
void write(std::ofstream& stream, const T& t) 
  stream.write((const char*)&t, sizeof(T));
  

template <typename SampleType>
void writeWAVData(const char* outFile, SampleType* buf, size_t bufSize,
                  int sampleRate, short channels)
  
  std::ofstream stream(outFile, std::ios::binary);
  stream.write("RIFF", 4);
  write<int>(stream, 36 + bufSize);
  stream.write("WAVE", 4);
  stream.write("fmt ", 4);
  write<int>(stream, 16);
  write<short>(stream, 1);                                        // Format (1 = PCM)
  write<short>(stream, channels);                                 // Channels
  write<int>(stream, sampleRate);                                 // Sample Rate
  write<int>(stream, sampleRate * channels * sizeof(SampleType)); // Byterate
  write<short>(stream, channels * sizeof(SampleType));            // Frame size
  write<short>(stream, 8 * sizeof(SampleType));                   // Bits per sample
  stream.write("data", 4);
  stream.write((const char*)&bufSize, 4);
  stream.write((const char*)buf, bufSize);
  

我只是通过在 Linux (Ubuntu 13.10) 中执行此操作来编译它:

 g++ audio.cpp -o audio && ./audio

【问题讨论】:

【参考方案1】:

我认为问题可能是:

unsigned long insin, insinb, factor;

这些是整数类型。

尝试将其更改为

float insin, insinb, factor;

【讨论】:

确实是这样。非常感谢。

以上是关于使用 sin() 生成的声音中的金属声音的主要内容,如果未能解决你的问题,请参考以下文章

生成的正弦波 pcm 声音中的静态噪声

增加 dB 值的 MATLAB 声音生成

Android:通知不会生成默认声音

使用 JavaScript 生成声音

Flash:为上传的声音生成/显示声音波形

使用 C++ 在运行时生成声音