Post by Kyle Gagner on Jun 6, 2012 19:56:07 GMT -5
This is a quickie program I made for randomly generated music. It turned out surprisingly well. I want to make more stuff like this soon.
uses PortAudio
Source:
KyleSound.h:
uses PortAudio
Source:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include "KyleSound.h"
int mm;
double fr;
double freq[4];
double t;
long seed;
double osc[4];
double wub;
double decay;
double beatd;
double beatvol;
double attack;
double vol;
double tgt;
double hld;
double scale[6];
int nseq[6];
int c;
int o;
int e=0;
int el;
float *ep;
int random(void)
{
seed = (seed * 32719 + 3) % 32749; // Random generator stolen from teh interwebs http://www.daniweb.com/software-development/c/code/216329/construct-your-own-random-number-generator
return abs(seed);
}
double randdouble(void)
{
seed = (seed * 32719 + 3) % 32749;
return ((double)((seed%2001)-1000))/1000.0;
}
void sound(float *in,float *out,int frames)
{
int n;
int i;
int a;
int b;
float *op;
double add;
double add2;
double add3;
t+=frames/fr;
if(t>.2)
{
if(c==0)
{
if(random()%2==0)
{
a=0;
b=0;
while(a==b)
{
a=random()%6;
b=random()%6;
}
n=nseq[a];
nseq[a]=nseq[b];
nseq[b]=n;
printf("Note order change\n");
}
if(random()%5==0)
{
o=(random()%12)-6;
osc[0]=0;
printf("Chord change\n");
}
if(random()%100==0)
{
scale[1]=pow(2,(4.0/12.0));
scale[4]=pow(2,(16.0/12.0));
printf("Major Chords\n");
mm=1;
}
if(random()%100==0)
{
scale[1]=pow(2,(3.0/12.0));
scale[4]=pow(2,(15.0/12.0));
printf("Minor Chords\n");
mm=0;
}
}
for(n=0;n<3;n++)
{
freq[n]=110.0*scale[n]*pow(2,((double)o)/12.0);
}
freq[3]=440.0*scale[nseq[c]]*pow(2,((double)o)/12.0);
tgt=1;
osc[3]=0;
t=0;
c=(c+1)%6;
}
op=out;
add=6.283185307179586476925286766559*freq[3]/fr;
add2=6.283185307179586476925286766559/fr;
add3=2*6.283185307179586476925286766559/fr;
for(n=0;n<frames;n++)
{
wub+=add3;
beatvol*=beatd;
if(vol<tgt)
{
vol+=attack;
}
else
{
vol=tgt;
tgt*=decay;
}
e=(e+1)%el;
for(i=0;i<3;i++)
{
*op+=sin(freq[i]*osc[0])*(2-((double)i*cos(wub)));
}
*op/=60;
ep[e]=(ep[e]+sin(osc[3])*vol)/2.0;
*op+=ep[e];
*op/=2.1;
//*op=(((sin(freq[3]*osc1)+0)*vol)+(ep[e]))/4.0;//+sin(osc*5.0/4.0)+sin(osc*6.0/4.0))*vol/3.0;
ep[e]=*op;
op++;
osc[3]+=add;
osc[0]+=add2;
}
wub=fmod(wub,6.283185307179586476925286766559);
}
int main(int argc,char **argv)
{
mm=1;
int n;
char flags[12];
seed=time(NULL);
fr=Medium;
scale[0]=pow(2,(0.0/12.0));
scale[1]=pow(2,(4.0/12.0));
scale[2]=pow(2,(7.0/12.0));
scale[3]=pow(2,(12.0/12.0));
scale[4]=pow(2,(16.0/12.0));
scale[5]=pow(2,(19.0/12.0));
for(n=0;n<6;n++)
{
flags[n]=0;
}
n=random()%6;
flags[n]=1;
nseq[0]=n;
for(c=1;c<6;c++)
{
while(flags[n])
{
n=random()%6;
}
flags[n]=1;
nseq[c]=n;
}
c=0;
el=(int)(fr*.15);
ep=malloc(el*sizeof(float));
decay=pow(.5,1.0/(fr*.07*.2));
beatd=pow(.5,1.0/(fr*.03));
attack=100.0*.1/fr;
painit(0,1,fr,128);
while(1)
{
}
pafinish();
return 0;
}
KyleSound.h:
#include <portaudio.h>
#define High 44100
#define Medium 22050
#define Low 11025
#define Crap 8000;
PaStream *stream;
void sound(float *in,float *out,int frames);
int pacallback(const void *inbuffer,void *outbuffer,unsigned long frames,const PaStreamCallbackTimeInfo* timeinfo,PaStreamCallbackFlags status,void *data)
{
float *in = (float*)inbuffer;
float *out = (float*)outbuffer;
sound(in,out,(int)frames);
return 0;
}
void pacheck(PaError err)
{
if( err != paNoError )
{
printf( "PortAudio error: %s\n",Pa_GetErrorText(err));
}
}
void painit(int inports,int outports,int samplerate,int chunksize)
{
pacheck(Pa_Initialize());
pacheck(Pa_OpenDefaultStream(&stream,inports,outports,paFloat32,samplerate,chunksize,pacallback,NULL));
pacheck(Pa_StartStream(stream));
}
void pafinish(void)
{
pacheck(Pa_StopStream(stream));
pacheck(Pa_CloseStream(stream));
pacheck(Pa_Terminate());
}