156 lines
3.5 KiB
C
156 lines
3.5 KiB
C
/*
|
|
* Filename: synththing.c
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
* Version:
|
|
* Created: Wed Oct 30 17:52:12 2019
|
|
* Revision: None
|
|
* Author: Rachel Fae Fox (foxiepaws),fox@foxiepa.ws
|
|
*
|
|
*/
|
|
|
|
|
|
#include <math.h>
|
|
#include <assert.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <portaudio.h>
|
|
#include <stdbool.h>
|
|
#include <unistd.h>
|
|
#include "common.h"
|
|
#include "synths/basic.h"
|
|
#include "synths/fm_2op.h"
|
|
#include "filters/svf.h"
|
|
#include "utils/envelope.h"
|
|
#include "utils/lfo.h"
|
|
#include "utils/seq.h"
|
|
#include <string.h>
|
|
|
|
|
|
#define SAMPLE_RATE (44100)
|
|
|
|
|
|
|
|
Basic saw;
|
|
SVF filt;
|
|
LFO lfo;
|
|
static EngineState data;
|
|
FM2 fm2;
|
|
Seq s;
|
|
|
|
int mycallback( const void *input,
|
|
void *output,
|
|
unsigned long frameCount,
|
|
const PaStreamCallbackTimeInfo* timeInfo,
|
|
PaStreamCallbackFlags statusFlags,
|
|
void *userData ) {
|
|
|
|
EngineState *data = (EngineState*)userData;
|
|
float *out = (float*) output;
|
|
unsigned int i;
|
|
|
|
for( i=0; i<frameCount; i++ )
|
|
{
|
|
//filt.process(&filt, (saw.process(&saw,data)));
|
|
//float a = filt.low;
|
|
fm2.freq = s.out;
|
|
s.run(&s);
|
|
float a = 0.5 * fm2.process(&fm2,data);
|
|
//filt.process(&filt,a);
|
|
//a = filt.low;
|
|
*out++ = a;
|
|
*out++ = a;
|
|
data->t++;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int main(int argc, char**argv) {
|
|
|
|
/* portaudio boilerplate crap */
|
|
PaError err;
|
|
err = Pa_Initialize();
|
|
const PaDeviceInfo *deviceInfo;
|
|
int numDevices;
|
|
numDevices = Pa_GetDeviceCount();
|
|
if( numDevices < 0 )
|
|
{
|
|
printf( "ERROR: Pa_CountDevices returned 0x%x\n", numDevices );
|
|
err = numDevices;
|
|
goto error;
|
|
}
|
|
|
|
for(int i=0; i<numDevices; i++ )
|
|
{
|
|
deviceInfo = Pa_GetDeviceInfo( i );
|
|
|
|
printf("name: %s\n"
|
|
"max channels\tin: %d\tout: %d\n"
|
|
"samplerate: %f",deviceInfo->name,deviceInfo->maxInputChannels,deviceInfo->maxOutputChannels,deviceInfo->defaultSampleRate);
|
|
}
|
|
s = *seq_new();
|
|
s.steps = 3;
|
|
midinote m[] = {60, 64, 67};
|
|
s.notes = malloc(sizeof(char) * 3);
|
|
memcpy(s.notes,m,3);
|
|
s.wait = 22050;
|
|
Envelope c = *envelope_new();
|
|
c.sustain = true;
|
|
c.ar = true;
|
|
c.release = 44100*3;
|
|
Envelope b = *envelope_new();
|
|
b.attack = 44100;
|
|
b.release = 44100/2;
|
|
b.ar = true;
|
|
b.sustain = true;
|
|
fm2 = *fm2_new();
|
|
fm2.Carrier.level = 1.0;
|
|
fm2.Carrier.mul = 1.0;
|
|
fm2.Carrier.e = c;
|
|
fm2.Modulator.level = 1.0;
|
|
fm2.Modulator.mul = 0.5;
|
|
fm2.Modulator.e = b;
|
|
fm2.freq = 440;
|
|
|
|
/*
|
|
saw = *basic_new(_waveform_sine, b);
|
|
saw.amp = 1.0f;
|
|
saw.pwm = 0.5;
|
|
saw.freq = 440;
|
|
saw.gate = false;
|
|
filt = *svf_new(7000.0f, 0.5f); */
|
|
//data.sample_rate=SAMPLE_RATE;
|
|
PaStream *stream;
|
|
/* Open an audio I/O stream. */
|
|
err = Pa_OpenDefaultStream( &stream,
|
|
0,
|
|
2,
|
|
paFloat32,
|
|
SAMPLE_RATE,
|
|
256,
|
|
mycallback,
|
|
&data );
|
|
|
|
if( err != paNoError ) goto error;
|
|
err = Pa_StartStream( stream );
|
|
if( err != paNoError ) goto error;
|
|
/* start anything intersting */
|
|
/* saw.gate = true;
|
|
sleep(5);
|
|
saw.gate = false;
|
|
sleep(5);*/
|
|
fm2.gate = true;
|
|
sleep(6);
|
|
fm2.gate=false;
|
|
sleep(5);
|
|
/* more crap */
|
|
error:
|
|
printf( "PortAudio error: %s\n", Pa_GetErrorText( err ) );
|
|
err = Pa_Terminate();
|
|
if( err != paNoError )
|
|
printf( "PortAudio error: %s\n", Pa_GetErrorText( err ) );
|
|
|
|
}
|