【问题标题】:General additive synthesis program通用添加剂合成程序
【发布时间】:2012-10-22 14:45:55
【问题描述】:

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

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

【问题讨论】:

  • 您遇到了什么错误?
  • @AK4749 我将其视为No such file or directory gcc: no input files 但除此之外,我不完全确定我是否真的正确地解决了这个问题
  • 好吧,我们可以一次慢慢地解决这个问题,但在我看来,您的 gcc 设置不正确或使用错误的语法来调用它。你能编译一个简单的hello world程序吗?
  • +1 用于制作加法合成器。

标签: c audio synthesis


【解决方案1】:

随着我开始注意到越来越多的小细节,cmets 开始阅读变得烦人(但请确保您仍然回答我编译的 Hello World 问题),因此我已将它们合并到此答案中并将其更新为我看到了更多:

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

【讨论】:

  • 我的 gcc 出了点问题,但已修复,因此我能够运行 hello world 问题。我已经解决了一些问题,但我仍然遇到大量错误
  • 有没有我可以发邮件给你的邮箱,因为这个评论线程可能会来来回回一段时间
  • 当然,发送电子邮件至: 显然没有括号,我会通过那里为您提供更好的联系信息 - 这是一个高知名度的网站,不想发布我的真实电子邮件哈哈。它将 24 小时开放。
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 2015-04-16
    • 2015-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-22
    相关资源
    最近更新 更多