#include #include #include #include #include #include #include #include "guttersynth.h" int samples_per_second = 44100; int bits_per_sample = 16; char* output_name = "guttersynth-example1.wav"; int written_samples = 0; struct wavfile_header { char riff_tag[4]; int riff_length; char wave_tag[4]; char fmt_tag[4]; int fmt_length; short audio_format; short num_channels; int sample_rate; int byte_rate; short block_align; short bits_per_sample; char data_tag[4]; int data_length; }; FILE* target; /* * open wavfile and set the riff header */ FILE* wavfile_open() { // populate the header struct wavfile_header header; strncpy(header.riff_tag, "RIFF",4); strncpy(header.wave_tag, "WAVE",4); strncpy(header.fmt_tag, "fmt ",4); strncpy(header.data_tag, "data",4); header.riff_length = 0; header.fmt_length = 16; header.audio_format = 1; header.num_channels = 1; header.sample_rate = samples_per_second; header.byte_rate = samples_per_second * (bits_per_sample / 8); header.block_align = bits_per_sample / 8; header.bits_per_sample = bits_per_sample; header.data_length = 0; FILE *file = fopen(output_name, "w+"); if(!file) return 0; fwrite(&header, sizeof(header), 1, file); fflush(file); return file; } /* * write to wavfile */ void wavfile_write(double* data, int length) { short* shortdata = (short*) malloc(sizeof(short) * length); int i; double sample; for (i = 0; i < length; i++) { sample = data[i] * 0.5; /// (DBL_MAX*0.01); shortdata[i] = (short) (sample * SHRT_MAX * 0.5); } fwrite(shortdata, sizeof(short), length, target); fflush(target); written_samples += length; free(shortdata); } /* * close the open wavfile */ void wavfile_close() { int file_length = ftell(target); int data_length = file_length - sizeof(struct wavfile_header); fseek(target, sizeof(struct wavfile_header) - sizeof(int), SEEK_SET); fwrite(&data_length, sizeof(data_length), 1, target); int riff_length = file_length - 8; fseek(target, 4, SEEK_SET); fwrite(&riff_length, sizeof(riff_length), 1, target); fclose(target); } /* * Returns a random float within a range * * min: bottom end of range * max: top end of range * * returns: random float */ double rangerandom(double min, double max) { double random = ((double) rand()) / (double) RAND_MAX; double diff = max - min; double r = random * diff; return min + r; } int boolrandom() { return (rand() > (RAND_MAX / 2)); } double interpolate(double items[], int points, int point) { return (((items[1] - items[0]) / points) * point) + items[0]; } void create() { target = wavfile_open(); int seconds = 20; int total_samples = samples_per_second * seconds; int sample = 0; int buffer_pos = 0; int buffer_size = 4410; double *buffer = (double*) malloc(sizeof(double) * buffer_size); gutter_state *gs = gutter_init(4, 24, samples_per_second); //gutter_randomisefilters(gs); double* filterAutomation = malloc(sizeof(double) * gs->bankCount * gs->filterCount * 3 * 2); int b, f, i, ai; double val; for (b = 0, ai=0; b < gs->bankCount; b++) { for (f = 0; f < gs->filterCount; f++) { i = b * gs->bankCount + f; val = rangerandom(100, 2000); filterAutomation[ai++] = val; filterAutomation[ai++] = (boolrandom()) ? val : rangerandom(100, 2000); val = rangerandom(0.3, 1); filterAutomation[ai++] = val; filterAutomation[ai++] = (boolrandom()) ? val : rangerandom(0.3, 1); val = rangerandom(20, 200); filterAutomation[ai++] = val; filterAutomation[ai++] = (boolrandom()) ? val : rangerandom(20, 200); } } double gamma[2] = { rangerandom(2, 10), rangerandom(2, 10) }; double omega[2] = { rangerandom(0.2, 1), rangerandom(0.2, 1) }; double c[2] = { rangerandom(0.2, 2), rangerandom(0.2, 2) }; double dt[2] = { rangerandom(100, 10000), rangerandom(100, 10000) }; double singleGain[2] = { rangerandom(0.2, 0.7), rangerandom(0.2, 0.7) }; gs->filtersOn = 1; gs->smoothing = 1; gs->distortionMethod = 2; gs->omega = rangerandom(0.3, 0.9); gs->c = rangerandom(0.5, 0.9); gs->dt = rangerandom(100, 500); gutter_randomisefilters(gs); for (sample = 0; sample <= total_samples; sample ++) { gs->gamma = interpolate(gamma, total_samples, sample); //gs->omega = 0.8; //interpolate(omega, total_samples, sample); //gs->c = 0.8; //interpolate(c, total_samples, sample); //gs->dt = 300; //interpolate(dt, total_samples, sample); gs->singleGain = 0.8; //interpolate(singleGain, total_samples, sample); for (b = 0, ai = 0; b < gs->bankCount; b++) { for (f = 0; f < gs->filterCount; f++, ai=ai+6) { i = b * gs->bankCount + f; gs->filterFreqs[i] = interpolate(filterAutomation + ai, total_samples, sample); gs->gains[i] = interpolate(filterAutomation + ai + 2, total_samples, sample); gs->Q[i] = interpolate(filterAutomation + ai + 4, total_samples, sample); } } gutter_calccoeffs(gs); buffer[buffer_pos] = gutter_process(gs); if (buffer_pos == buffer_size - 1) { buffer_pos = 0; wavfile_write(buffer, buffer_size); } else { buffer_pos ++; } // randomise filters every second if (sample % samples_per_second == 0) { //gutter_randomisefilters(gs); } } free(buffer); free(filterAutomation); gutter_cleanup(gs); wavfile_close(); } int main() { // random seed from time srand((unsigned int) time(NULL)); // generate the file create(); return 0; }