Domanda

I'm attempting to write a general additive synthesis c program that will generate a complex sinusoid created from a sequence of pure sine waves of arbitrary frequency following a single envelope. The input file will be something of this nature

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

I want my program to generate a WAV file up to the last breakpoint where all the sine waves will be generated at the given frequencies, scaled to the % contribution as listed, and added together to make the final sound

I've attempted to try some of the c programming out but I'm not naturally a C programming so this is what I've done so far:

#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);
    }
}       
}

However, I'm not really sure if I'm doing this right at all. Any ideas on how I can fix this and proceed?

È stato utile?

Soluzione

As I've started noticing more and more little details, the comments start getting annoying to read (but make sure you still answer my compiling Hello World question), so I've coalesced them into this answer and will update it as I see more:

  1. as of right now, frequency is used only once, and at that time is only 0.0 ever. is that what you want?
  2. i is initalized to 0, and sampleNumber is also started at 0. Thus the while condition (i < sampleNumber) will never execute
  3. i is never incremented yet you have a if ( i <= 1000 ) condition, which will thus always evaluate true
  4. sampleRate is initialized to 0.0, and the first operation on it is to divide by it, which, obviously, is not happy times
  5. Obviously pedantic, but the n in the bottom most for loop is never declared ( int n; for (n = ....) as an example.
  6. in your sample_buffer = (float*) malloc(samples * sizeof(float)); line, samples should most probably be sampleNumber, right? samples is never defined

Altri suggerimenti

I agree with AKA4749, and have one more thing you should do: clip the samples when you add them or you get distortion:

if ( sample[i] > 1 ) sample[i] = 1;
else if ( sample[i] < -1 ) sample[i] = -1;
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top