2

我正在尝试编写一个通用的加法合成 c 程序,该程序将生成一个复杂的正弦曲线,该正弦曲线由一系列任意频率的纯正弦波跟随单个包络创建。输入文件将具有这种性质

F0     P0                   // a list of up to 100 floats indicating frequencies and 
F1     P1                   // % contribution of this frequency to the sound
F2     P2
....
-1                          // sentinal value to indicate end of frequency list 
B0     A0                   //  first breakpoint
B1     A1
...                         // There can be an arbitary number of breakpoints

我希望我的程序生成一个 WAV 文件,直到最后一个断点,在该断点处,所有正弦波都将以给定的频率生成,缩放到列出的贡献百分比,并加在一起以产生最终的声音

我试图尝试一些 c 编程,但我不是天生的 C 编程,所以这是我到目前为止所做的:

#include <stdio.h>
#include <stdlib.h>
#include <portsf.h>
#include <math.h>
#ifndef M_PI
#define M_PI (3.141592654)
#endif

// Additive Synthesis

PSF_PROPS props;
props.srate = 44100;
props.chans = 2;
props.samptype = PSF_SAMP_IEEE_FLOAT;
props.format = PSF_STDWAVE;
props.chformat = STDWAVE;

float* frame;

int sampleNumber;
double angleIncrement;
double frequency;
double sampleRate;
int i;
int twopi = 2.0 * M_PI;

ofd = psf_sndCreate(argv[2],&props,0,0,PSF_CREATE_RDWR);

int main (int argc, char* argv[]) {

sampleNumber = 0;
angleIncrement = twopi * frequency/sampleRate;
while (i < sampleNumber) {
    frame[0] = frame[1] = sin(sampleNumber * angleIncrement);
    sampleNumber++;
    if (fwrite(&sampleout,sizeof(float),1,rawfile) !=1) {
        printf("Error writing to output file.\n");
        return 1;
    }
    if (i <=1000) 
        fprintf(bpfile, "%ld\t%f\n", i, frame);
    phase += angleIncrement;
    if (phase >= twopi)
        phase -= twopi;
}

phase_offset = -1 * PI / 2;
sample_buffer = (float*) malloc(samples * sizeof(float));
// sample_buffer set back to 0
memset(sample_buffer, 0, sizeof(float)*sampleNumber);

// go through the number of harmonics
for (i = 1; i <= NHARMS; i++) {
    amp = 1.0 / i;
    // go through number of sinusoid components
    for (n = 0; n < sampleNumber; n++) { 
        sample_buffer[n] += amp * cos(i * angleIncrement * n + phase_offset);
    }
}       
}

但是,我不确定我是否做对了。关于如何解决此问题并继续进行的任何想法?

4

2 回答 2

2

随着我开始注意到越来越多的小细节,这些评论开始读起来很烦人(但请确保你仍然回答我编译的 Hello World 问题),所以我将它们合并到这个答案中,并会在我看到更多时更新它:

  1. 截至目前,frequency仅使用一次,并且当时仅使用0.0一次。那是你要的吗?
  2. i初始化为0sampleNumber也开始于0。因此while条件(i < sampleNumber)永远不会执行
  3. i永远不会增加但您有一个if ( i <= 1000 )条件,因此将始终评估true
  4. sampleRate被初始化为0.0,对它的第一个操作就是除以它,这显然不是快乐时光
  5. 显然是迂腐的,但n最底层的for循环从未被声明过(int n; for (n = ....)例如。
  6. 在你的sample_buffer = (float*) malloc(samples * sizeof(float));行中,samples很可能应该是sampleNumber,对吧?samples从未定义
于 2012-10-22T19:36:02.940 回答
1

我同意 AKA4749,并且您还应该做一件事:在添加样本时剪辑样本,否则会出现失真:

if ( sample[i] > 1 ) sample[i] = 1;
else if ( sample[i] < -1 ) sample[i] = -1;
于 2012-10-22T19:48:19.823 回答