一般添加剂合成程序

时间:2012-10-22 14:45:55

标签: c audio synthesis

我正在尝试编写一个通用的加法合成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);
    }
}       
}

但是,我不确定我是否正确行事。关于如何解决这个问题的任何想法并继续下去?

2 个答案:

答案 0 :(得分:2)

当我开始注意到越来越多的细节时,评论开始变得烦人的阅读(但确保你仍然回答我编译的Hello World问题),所以我将它们合并到这个答案中并将其更新为我看到更多:

  1. 截至目前,frequency仅使用一次,此时只有0.0。那是你想要的吗?
  2. i已初始化为0,而sampleNumber也已在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

答案 1 :(得分:1)

我同意AKA4749,还有一件事你应该做的事情:在添加样品时剪裁样品或者你会失真:

if ( sample[i] > 1 ) sample[i] = 1;
else if ( sample[i] < -1 ) sample[i] = -1;