diff --git a/.vscode/tasks.json b/.vscode/tasks.json index e43101c..f40e7f1 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -13,6 +13,7 @@ "${fileDirname}/ring_buffer.c", "${fileDirname}/oscillator.c", "${fileDirname}/parser.c", + "${fileDirname}/export.c", "-lm", "-lraylib", "-o", diff --git a/build.sh b/build.sh index 80fa68b..a9c9dfe 100644 --- a/build.sh +++ b/build.sh @@ -1,3 +1,3 @@ #!/bin/bash CC="${CXX:-cc}" -$CC -Wall -std=c11 ./main.c ./utils.c ./ring_buffer.c ./oscillator.c ./parser.c -lm -lraylib -o ./bin/main +$CC -Wall -std=c11 ./main.c ./utils.c ./ring_buffer.c ./oscillator.c ./parser.c ./export.c -lm -lraylib -o ./bin/main diff --git a/export.c b/export.c new file mode 100644 index 0000000..8a231de --- /dev/null +++ b/export.c @@ -0,0 +1,74 @@ +#include "export.h" + +#include "stdio.h" +#include "string.h" +#include "settings.h" + +uint16_t toInt16Sample(float sample) { + return (uint16_t)(sample * 32767.f); +} + +static void write_file(char* filename, void* data, int size) { + FILE* fp = fopen(filename, "wb"); // open file for writing in binary mode + if (fp == NULL) { + fprintf(stderr, "Cannot open file: %s\n", filename); + exit(1); + } + + fwrite(data, size, 1, fp); // write data to file + + fclose(fp); // close file +} + +void pack(uint16_t* d, size_t length) { + size_t dataLength = length * 2; + + int bytesPerSample = 2; + int byteRate = SAMPLE_RATE * bytesPerSample; + + size_t fileSize = 36 + dataLength; + + uint8_t* buffer = (uint8_t*)malloc(fileSize); + + int i = 0; + + // RIFF header + memcpy(buffer + i, "RIFF", 4); + i += 4; + memcpy(buffer + i, &fileSize, 4); + i += 4; + memcpy(buffer + i, "WAVE", 4); + i += 4; + + // fmt subchunk + memcpy(buffer + i, "fmt ", 4); + i += 4; + int fmtSize = 16; + memcpy(buffer + i, &fmtSize, 4); + i += 4; + uint16_t audioFormat = 1; + memcpy(buffer + i, &audioFormat, 2); + i += 2; + uint16_t numChannels = 1; + memcpy(buffer + i, &numChannels, 2); + i += 2; + int sampleRate = (int)SAMPLE_RATE; + memcpy(buffer + i, &sampleRate, 4); + i += 4; + memcpy(buffer + i, &byteRate, 4); + i += 4; + memcpy(buffer + i, &bytesPerSample, 2); + i += 2; + int bitsPerSample = bytesPerSample * 8; + memcpy(buffer + i, &bitsPerSample, 2); + i += 2; + + // data subchunk + memcpy(buffer + i, "data", 4); + i += 4; + memcpy(buffer + i, &dataLength, 4); + i += 4; + memcpy(buffer + i, d, dataLength); + + write_file("output.wav", buffer, fileSize); +} \ No newline at end of file diff --git a/export.h b/export.h new file mode 100644 index 0000000..0cb1aaa --- /dev/null +++ b/export.h @@ -0,0 +1,9 @@ +#ifndef EXPORT_H +#define EXPORT_H + +#include "stdlib.h" + +uint16_t toInt16Sample(float sample); +void pack(uint16_t* d, size_t length); + +#endif \ No newline at end of file diff --git a/main.c b/main.c index 476f130..9dc1de1 100644 --- a/main.c +++ b/main.c @@ -8,6 +8,7 @@ #include "ring_buffer.h" #include "settings.h" #include "oscillator.h" +#include "export.h" #include "raylib.h" @@ -100,80 +101,7 @@ SynthSound get_note_sound(Note input) { int semitone_shift = get_semitone_shift(input.name); return note(semitone_shift, length); } - - -//------------------------------------------------------------------------------------ -// Wav File -//------------------------------------------------------------------------------------ - -static uint16_t toInt16Sample(float sample) { - return (uint16_t)(sample * 32767.f); -} - -static void write_file(char* filename, void* data, int size) { - FILE* fp = fopen(filename, "wb"); // open file for writing in binary mode - if (fp == NULL) { - fprintf(stderr, "Cannot open file: %s\n", filename); - exit(1); - } - - fwrite(data, size, 1, fp); // write data to file - - fclose(fp); // close file -} - -void pack(uint16_t* d, size_t length) { - size_t dataLength = length * 2; - - int bytesPerSample = 2; - int byteRate = SAMPLE_RATE * bytesPerSample; - - size_t fileSize = 36 + dataLength; - - uint8_t* buffer = (uint8_t*)malloc(fileSize); - - int i = 0; - - // RIFF header - memcpy(buffer + i, "RIFF", 4); - i += 4; - memcpy(buffer + i, &fileSize, 4); - i += 4; - memcpy(buffer + i, "WAVE", 4); - i += 4; - - // fmt subchunk - memcpy(buffer + i, "fmt ", 4); - i += 4; - int fmtSize = 16; - memcpy(buffer + i, &fmtSize, 4); - i += 4; - uint16_t audioFormat = 1; - memcpy(buffer + i, &audioFormat, 2); - i += 2; - uint16_t numChannels = 1; - memcpy(buffer + i, &numChannels, 2); - i += 2; - int sampleRate = (int)SAMPLE_RATE; - memcpy(buffer + i, &sampleRate, 4); - i += 4; - memcpy(buffer + i, &byteRate, 4); - i += 4; - memcpy(buffer + i, &bytesPerSample, 2); - i += 2; - int bitsPerSample = bytesPerSample * 8; - memcpy(buffer + i, &bitsPerSample, 2); - i += 2; - - // data subchunk - memcpy(buffer + i, "data", 4); - i += 4; - memcpy(buffer + i, &dataLength, 4); - i += 4; - memcpy(buffer + i, d, dataLength); - - write_file("output.wav", buffer, fileSize); -} +//------------------------------------------------------- size_t detect_note_pressed(Note* note) { size_t is_pressed = 0;