Last active
October 14, 2024 08:36
-
-
Save harieamjari/cb29c167c28ae750403d7b2761d61808 to your computer and use it in GitHub Desktop.
An implementation of Karplus-Strong Algorithm in C. Using /dev/urandom in linux.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdint.h> | |
#include <stdlib.h> | |
#include <time.h> | |
#define SECONDS 6 /* you can change this to suit for your preferences */ | |
#define LENGTH 300 /* you can experiment with different string length */ | |
char wav_struct[] = { | |
'R', 'I', 'F', 'F', | |
0, 0, 0, 0, /* chunksize */ | |
'W', 'A', 'V', 'E', | |
'f', 'm', 't', ' ', /* subchunk1id */ | |
16, 0, 0, 0, /* subchunk1size */ | |
1, 0, /* audioformat */ | |
1, 0, /* numchannels */ | |
68, 172, 0, 0, /* samplerate 44100 */ | |
136, 88, 1, 0, /* byterare 88200 */ | |
2, 0, /* blockalign */ | |
16, 0, /* bitspersample */ | |
'd', 'a', 't', 'a', /* subchunk2id */ | |
0, 0, 0, 0 /* subchunk2size */ | |
}; | |
int main(){ | |
int16_t wavetable[LENGTH]; | |
srand(time(NULL)); | |
for (int i = 0; i < LENGTH; i++) wavetable[i] = rand(); | |
int16_t *raw_pcm = malloc(sizeof(int16_t)*44100*SECONDS); | |
if (raw_pcm == NULL){ | |
fprintf(stderr, "Failed to allocated raw_pcm\n"); | |
return 1; | |
} | |
int previous = 0; | |
int current = 0; | |
for (int i = 0; i < 44100*SECONDS; i++){ | |
wavetable[current] = ((wavetable[current]/2)+(previous/2)); | |
raw_pcm[i] = wavetable[current]; | |
previous = raw_pcm[i]; | |
current += 1; | |
current %= LENGTH; | |
} | |
FILE *fpout = fopen("kpa.wav", "wb"); | |
if (fpout == NULL) { | |
fprintf(stderr, "Couldn't write kpa.wav\n"); | |
free(raw_pcm); | |
return 1; | |
} | |
fwrite(wav_struct, sizeof(wav_struct), 1, fpout); | |
fwrite(raw_pcm, sizeof(int16_t), 44100*SECONDS, fpout); | |
uint32_t length = 32+((44100*SECONDS)<<1); | |
fseek(fpout, 4, SEEK_SET); | |
fwrite(&length, sizeof(uint32_t), 1, fpout); | |
uint32_t subchunk2size = (44100*SECONDS)<<1; | |
fseek(fpout, 40, SEEK_SET); | |
fwrite(&subchunk2size, sizeof(uint32_t), 1, fpout); | |
fclose(fpout); | |
free(raw_pcm); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment