Skip to content

Instantly share code, notes, and snippets.

@harieamjari
Last active October 2, 2023 03:10
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save harieamjari/cb29c167c28ae750403d7b2761d61808 to your computer and use it in GitHub Desktop.
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.
#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