diff options
author | grm <grm@eyesin.space> | 2025-03-02 13:53:54 +0200 |
---|---|---|
committer | grm <grm@eyesin.space> | 2025-03-02 13:53:54 +0200 |
commit | 9847614871e861c216425b95a8300dba37b0f6e6 (patch) | |
tree | f319cc5ebd58d2247d546a3c2149ce85559be6d8 /src | |
parent | d5e9beaf5cc38c0e57bbc555a6e3054f3bf000d8 (diff) | |
download | synth-project-9847614871e861c216425b95a8300dba37b0f6e6.tar.gz synth-project-9847614871e861c216425b95a8300dba37b0f6e6.tar.bz2 synth-project-9847614871e861c216425b95a8300dba37b0f6e6.zip |
Also improve midi and add tt for templating
Diffstat (limited to 'src')
-rw-r--r-- | src/b.h | 35 | ||||
-rw-r--r-- | src/gui.h | 16 | ||||
-rw-r--r-- | src/midi.c | 20 | ||||
-rw-r--r-- | src/sound.c | 3 | ||||
-rw-r--r-- | src/synth_engine.h | 7 | ||||
-rw-r--r-- | src/synth_engine_v2.c | 2 | ||||
-rw-r--r-- | src/synth_gui.c | 40 | ||||
-rw-r--r-- | src/tt.c | 124 | ||||
-rw-r--r-- | src/web.c | 248 |
9 files changed, 332 insertions, 163 deletions
@@ -50,7 +50,8 @@ typedef enum { B_INFO, B_CMD, - B_BUILDING, + B_COMPILE, + B_TEMPLATE, B_CHANGE, B_WARNING, B_ERROR, @@ -195,8 +196,8 @@ void b_temp_rewind(size_t checkpoint); int is_path1_modified_after_path2(const char *path1, const char *path2); bool b_rename(const char *old_path, const char *new_path); -int b_needs_rebuild(const char *output_path, const char **input_paths, size_t input_paths_count); -int b_needs_rebuild1(const char *output_path, const char *input_path); +int b_needs_rebuild(B_Log_Level log, const char *output_path, const char **input_paths, size_t input_paths_count); +int b_needs_rebuild1(B_Log_Level log, const char *output_path, const char *input_path); int b_file_exists(const char *file_path); // TODO: add MinGW support for Go Rebuild Urself™ Technology @@ -246,7 +247,7 @@ int b_file_exists(const char *file_path); assert(argc >= 1); \ const char *binary_path = argv[0]; \ \ - int rebuild_is_needed = b_needs_rebuild(binary_path, &source_path, 1); \ + int rebuild_is_needed = b_needs_rebuild(B_COMPILE, binary_path, &source_path, 1); \ if (rebuild_is_needed < 0) exit(1); \ if (rebuild_is_needed) { \ B_String_Builder sb = {0}; \ @@ -506,22 +507,25 @@ void b_log(B_Log_Level level, const char *fmt, ...) { switch (level) { case B_INFO: - fprintf(stderr, "[INFO] "); + fprintf(stderr, " [INFO] "); break; case B_CMD: - fprintf(stderr, "[CMD] "); + fprintf(stderr, " [CMD] "); break; - case B_BUILDING: - fprintf(stderr, "[BUILDING] "); + case B_COMPILE: + fprintf(stderr, " [COMPILE] "); + break; + case B_TEMPLATE: + fprintf(stderr, "[TEMPLATE] "); break; case B_CHANGE: - fprintf(stderr, "[CHANGE] "); + fprintf(stderr, " [CHANGE] "); break; case B_WARNING: - fprintf(stderr, "[WARNING] "); + fprintf(stderr, " [WARNING] "); break; case B_ERROR: - fprintf(stderr, "[ERROR] "); + fprintf(stderr, " [ERROR] "); break; default: B_ASSERT(0 && "unreachable"); @@ -734,14 +738,14 @@ const char *b_temp_sv_to_cstr(B_String_View sv) return result; } -int b_needs_rebuild(const char *output_path, const char **input_paths, size_t input_paths_count) +int b_needs_rebuild(B_Log_Level log, const char *output_path, const char **input_paths, size_t input_paths_count) { struct stat statbuf = {0}; if (stat(output_path, &statbuf) < 0) { // NOTE: if output does not exist it 100% must be rebuilt if (errno == ENOENT) { - b_log(B_BUILDING, "%s", output_path); + b_log(log, "%s", output_path); return 1; } b_log(B_ERROR, "could not stat %s: %s", output_path, strerror(errno)); @@ -760,6 +764,7 @@ int b_needs_rebuild(const char *output_path, const char **input_paths, size_t in // NOTE: if even a single input_path is fresher than output_path that's 100% rebuild if (input_path_time > output_path_time) { b_log(B_CHANGE, "%s", input_path); + b_log(log, "%s", output_path); return 1; } } @@ -767,9 +772,9 @@ int b_needs_rebuild(const char *output_path, const char **input_paths, size_t in return 0; } -int b_needs_rebuild1(const char *output_path, const char *input_path) +int b_needs_rebuild1(B_Log_Level log, const char *output_path, const char *input_path) { - return b_needs_rebuild(output_path, &input_path, 1); + return b_needs_rebuild(log, output_path, &input_path, 1); } bool b_rename(const char *old_path, const char *new_path) diff --git a/src/gui.h b/src/gui.h new file mode 100644 index 0000000..f151e35 --- /dev/null +++ b/src/gui.h @@ -0,0 +1,16 @@ +#ifndef GUI_H +#define GUI_H + +typedef enum screen_e { + SCREEN_MAIN = 0, + SCREEN_AUDIOMIDISETUP, + SCREEN_ERR +} screen_e; + +typedef struct synth_gui { + screen_e screen; + int audiomidi_initialized; +} synth_gui; + + +#endif /* GUI_H */ @@ -161,22 +161,14 @@ init_midi(midi_t *m, synth_t *synth) printf("midi devs: %d\n", Pm_CountDevices()); const PmDeviceInfo *info; - int i, c=0; + int i=0; for (i = 0; i < Pm_CountDevices(); i++) { info = Pm_GetDeviceInfo(i); if (!info->input) { continue; } printf("%d: %s [input: %d output: %d opened: %d is_virt:%d] (interf: %s) -- %d\n", i, info->name, info->input, info->output, info->opened, info->is_virtual, info->interf, Pm_GetDefaultInputDeviceID()); - if (synth->midi_device_id == c) { - break; - } - c++; - //if (!strcmp("MPK225 MIDI", info->name) && !info->input) break; - //if (!strcmp("MPK225 Port A", info->name) && info->input == 1) break; - //if (!strcmp("CH345 MIDI 1", info->name) && info->input == 1) break; - //if (!strcmp("Midi Through Port-0", info->name) && info->input == 1) break; - //if (!strcmp("DigitalKBD MIDI 1", info->name) && info->input == 1) break; + if (!strcmp(synth->midi_device.name, info->name) && !info->input) break; } Pt_Start(1, midiCallback, m); @@ -190,6 +182,7 @@ init_midi(midi_t *m, synth_t *synth) enable = 1; } +// unused int get_midi_device_id(const char * name) { @@ -211,23 +204,20 @@ get_midi_device_id(const char * name) char * get_midi_devices() { - //Pm_Initialize(); int i; char *ret = (char *)malloc(sizeof(char) * 4096); - strcpy(ret, ""); + strcpy(ret, "Select Midi Device;"); const PmDeviceInfo *info; for (i = 0; i < Pm_CountDevices(); i++) { info = Pm_GetDeviceInfo(i); if (!info->input) { continue; } - printf("!!!!!!!!!!!!!!!!!!!!!!!!! ==> %s ========\n", info->name); strcat(ret, info->name); strcat(ret, ";"); } ret[strlen(ret) - 1] = '\0'; - //Pm_Terminate(); - + return ret; } diff --git a/src/sound.c b/src/sound.c index 2b2ca12..d4b0242 100644 --- a/src/sound.c +++ b/src/sound.c @@ -101,7 +101,8 @@ init_sound(synth_t * synth, PaStreamCallback *streamCallback, const char* device deviceInfo->name); if (strcmp(device_name, "default")) { printf("Trying to use default device\n"); - init_sound(synth, streamCallback, "default"); + strcpy(synth->soundcard.name, "default"); + init_sound(synth, streamCallback, synth->soundcard.name); } return; } diff --git a/src/synth_engine.h b/src/synth_engine.h index 21e427c..f771073 100644 --- a/src/synth_engine.h +++ b/src/synth_engine.h @@ -22,6 +22,11 @@ typedef struct soundcard_t { int id; } soundcard_t; +typedef struct midi_device_t { + char name[2048]; + int id; +} midi_device_t; + typedef struct lfo_t { float freq; float amp; @@ -136,7 +141,7 @@ typedef struct { int sound_active; soundcard_t soundcard; - int midi_device_id; + midi_device_t midi_device; synth_viz viz; diff --git a/src/synth_engine_v2.c b/src/synth_engine_v2.c index d4b7509..4d9721c 100644 --- a/src/synth_engine_v2.c +++ b/src/synth_engine_v2.c @@ -569,8 +569,8 @@ init_synth(void) strcpy(synth->soundcard.name, "default"); init_sound(synth, sound_gen, synth->soundcard.name); + strcpy(synth->midi_device.name, "Midi Through Port-0"); synth->midi = (midi_t *)malloc(sizeof(midi_t)); - synth->midi_device_id = get_midi_device_id("Midi Through Port-0"); init_midi(synth->midi, synth); synth->gui.screen = SCREEN_MAIN; diff --git a/src/synth_gui.c b/src/synth_gui.c index 43cfda1..d1dc78e 100644 --- a/src/synth_gui.c +++ b/src/synth_gui.c @@ -708,17 +708,21 @@ void get_nth_entry(const char *str, int n, char *result) { } char *soundcards = NULL; +char *midi_devices = NULL; void draw_audiomidisetup(synth_t *synth, const char *midi_devices) { static int edit_midi = 0; static int edit_sound = 0; - static int pick = 0; + static int midi_pick = 0; + static int soundcard_pick = 0; if (synth->gui.audiomidi_initialized == 0) { soundcards = get_soundcards(); - pick = 0; + midi_devices = get_midi_devices(); + soundcard_pick = 0; + midi_pick = 0; synth->gui.audiomidi_initialized = 1; printf("================ AUDIOMIDISETUP GUI INITIALIZED!\n"); } @@ -734,38 +738,38 @@ draw_audiomidisetup(synth_t *synth, const char *midi_devices) if (GuiButton((Rectangle){WIDTH - 100 - 50, 50 + 24 + 6 + 24 + 6 + 24 + 6 + 24 + 6, 100, 24}, "apply")) { - if (pick != 0) { - get_nth_entry(soundcards, pick, synth->soundcard.name); - printf("CHANGING TO %s\n", synth->soundcard.name); + if (soundcard_pick != 0) { + get_nth_entry(soundcards, soundcard_pick, synth->soundcard.name); + printf("[AUDIO] CHANGING TO %s\n", synth->soundcard.name); change_soundcard(synth); } + if (midi_pick != 0) { + get_nth_entry(midi_devices, midi_pick, synth->midi_device.name); + printf("[MIDI] CHANGING TO %s\n", synth->midi_device.name); + change_midi_device(synth); + } synth->gui.screen = SCREEN_MAIN; } - // audio dev + // midi dev if (GuiDropdownBox((Rectangle){WIDTH - 300 - 50, 12 + 24 + 6, 300, 24}, - soundcards, &pick, edit_sound)) { - edit_sound = !edit_sound; + midi_devices, &midi_pick, edit_midi)) { + edit_midi = !edit_midi; } - /* if (old_soundcard_id != synth->soundcard_id) { */ - /* old_soundcard_id = synth->soundcard_id; */ - /* get_nth_entry(soundcards, pick, synth->soundcard_name); */ - /* } */ - // midi dev + // audio dev if (GuiDropdownBox((Rectangle){WIDTH - 300 - 50, - 12, 200, + 12, 300, 24}, - midi_devices, &synth->midi_device_id, edit_midi)) { - edit_midi = !edit_midi; + soundcards, &soundcard_pick, edit_sound)) { + edit_sound = !edit_sound; } /* if (old_midi_device_id != synth->midi_device_id) { */ /* old_midi_device_id = synth->midi_device_id; */ - /* change_midi_device(synth); */ /* } */ @@ -778,6 +782,7 @@ draw_main(synth_t *synth) { if (synth->gui.audiomidi_initialized != 0) { if (soundcards) free(soundcards); + if (midi_devices) free(midi_devices); synth->gui.audiomidi_initialized = 0; } BeginDrawing(); @@ -891,7 +896,6 @@ rayrun(synth_t *synth){ draw_audiomidisetup(synth, midi_devices); //---------------------------------------------------------------------------------- - current_time = Pa_GetStreamTime(synth->stream); //printf("%f :: %ld\n", current_time - prev_time, phase); diff --git a/src/tt.c b/src/tt.c new file mode 100644 index 0000000..01c9614 --- /dev/null +++ b/src/tt.c @@ -0,0 +1,124 @@ +#include <stdio.h> +#include <stdlib.h> +#include <assert.h> +#include <stdint.h> +#include <string.h> +#include <unistd.h> + +#define DEFAULT_DELIMITER "$" + +void compile_c_code(char * s) { + printf("%.*s\n", (int) strlen(s), s); +} + +void compile_byte_array(char * s) { + printf("write(OUT, \""); + uint64_t slen = strlen(s); + for (uint64_t i = 0; i < slen; ++i) { + printf("\\x%02x", s[i]); + } + printf("\", %lu);\n", strlen(s)); +} + +char *read_file_to_string(const char *filename) { + FILE *file = fopen(filename, "rb"); + if (!file) { + perror("Error opening file"); + return NULL; + } + + fseek(file, 0, SEEK_END); + long file_size = ftell(file); + rewind(file); + + char *buffer = (char *)malloc(file_size + 1); + if (!buffer) { + perror("Memory allocation failed"); + fclose(file); + return NULL; + } + + fread(buffer, 1, file_size, file); + buffer[file_size] = '\0'; + + fclose(file); + return buffer; +} + +#define CHARSET_SIZE 128 // Covering standard ASCII characters + +int print_good_delimiters(const char * s) { + int seen[CHARSET_SIZE] = {0}; // Array to track seen characters + + size_t len = strlen(s); + for (size_t i = 0; i < len; i++) { + if (s[i] >= 0 && (int)s[i] < CHARSET_SIZE) { + seen[(int)s[i]] = 1; + } + } + + // Define the characters to check: A-Za-z0-9 and common symbols + char *valid_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()-_=+[{]}\\|;:'\",<.>/?`~"; + + int flag = 0; + printf("Good options for delimiters:\n"); + for (int i = 0; valid_chars[i] != '\0'; i++) { + if (!seen[(unsigned char)valid_chars[i]]) { + putchar(valid_chars[i]); + flag++; + } + } + if (!flag) { + printf(" :( none found, compromises shall be made"); + } + putchar('\n'); + + return 0; +} + + +int main(int argc, char *argv[]) +{ + if (argc < 2) { + fprintf(stderr, "Usage: %s <template> [delim|-d] [> OUTPUT]\n", argv[0]); + return 1; + } + + const char *filepath = argv[1]; + char *template = read_file_to_string(filepath); + if (!template) return 1; + + if (argc > 2 && 0 == strcmp(argv[2], "-d")) { + print_good_delimiters(template); + exit(0); + } + + char delim[1024] = DEFAULT_DELIMITER; + if (argc > 2) { + strcpy(delim, argv[2]); + } + + + int c_code_mode = 1; + for (int i = 0; delim[i] != '\0'; i++) { + if (template[i] != delim[i]) { + c_code_mode = 0; + break; + } + } + + char *token = strtok(template, delim); + while (token) { + if (c_code_mode) { + compile_c_code(token); + } else { + compile_byte_array(token); + } + c_code_mode = !c_code_mode; + + token = strtok(NULL, delim); + } + + free(template); + return 0; +} @@ -1,11 +1,10 @@ #include "web.h" +#define _GNU_SOURCE #include <libwebsockets.h> #include <pthread.h> -#include <microhttpd.h> #include <unistd.h> - #define HTTP_PORT 9966 #define WS_PORT 9967 @@ -15,6 +14,7 @@ struct MHD_Daemon *server; pthread_t server_thread; #define BUFFER_SIZE 1024 * 4 char message_buffer[BUFFER_SIZE]; +static char *html_content; // Function to handle slider changes void handle_slider_change(void *cls, int value) { @@ -23,41 +23,6 @@ void handle_slider_change(void *cls, int value) { cc_set(&synth->cc_cutoff, value); } -void handle_button_click(void *cls) { - printf("Button clicked!!!"); - synth_t *synth = (synth_t*)cls; - - int i = 5; - //printf("Note On : %s[%d] %fHz\n", int_to_note(i % 12), (synth->octave + (i / 12)) % 8, note); - synth->midi_note[i].freq = 16.35160 * pow(2, (synth->octave + i / 12.0)); - //synth->midi_note[i].freq = notes[i % 12][(synth->octave + (i / 12)) % 8]; - synth->midi_note[i].channel = -1; - synth->midi_note[i].noteOn = Pa_GetStreamTime(synth->stream); - synth->midi_note[i].noteOff = 0; - synth->midi_note[i].velocity = 1.0; - synth->midi_note[i].elapsed = 0; - synth->midi_note[i].active = 1; - int flag = 1; - for (int j = 0; j < synth->midi_active_n; j++) { - if (synth->midi_active[j] == &synth->midi_note[i]) { - flag = 0; - } - } - if (flag) { - synth->midi_active[synth->midi_active_n++] = &synth->midi_note[i]; - } - - //synth->adsr.elapsed = 0; - synth->active = 1; - - usleep(500000); - - synth->midi_note[i].noteOff = Pa_GetStreamTime(synth->stream); - synth->midi_note[i].noteOffSample = synth->midi_note[i].elapsed; - -} - - const char *html_header = "HTTP/1.1 200 OK\r\n" "Connection: close\r\n" @@ -65,76 +30,75 @@ const char *html_header = "\r\n" "\r\n"; -// HTML page with a slider -const char *html_content = - "<!DOCTYPE html>\n" - "<html>\n" - "<head>\n" - "<title>C SYNTH WEB!</title>\n" - "</head>\n" - "<body>\n" - "<input id='slider' style='width: 100%; height: 200px;' type='range' min='1' max='22000' />\n" - "<button onclick='onButtonClick()'>Trigger</button>\n" - "<button id='but'>ws</button>\n" - "<script>\n" - "const ws = new WebSocket('ws://10.0.0.10:9967');\n" - "const slider = document.getElementById('slider');\n" - "const but = document.getElementById('but');\n" - "\n" - "slider.oninput = function() { ws.send(slider.value); };\n" - "\n" - "but.onclick = function() { ws.send('THIS IS A TEST DONT KILL ME'); };\n" - "\n" - "ws.onmessage = function(event) {\n" - " console.log('Message from server: ' + event.data);\n" - " slider.value = parseInt(event.data);" - "};\n" - "ws.onopen = function() {\n" - " console.log('Connected to WebSocket server');\n" - "};\n" - "ws.onerror = function(error) {\n" - " console.error('WebSocket error: ' + error);\n" - "};\n" - "</script>\n" - "</body>\n" - "</html>\n"; +char *read_file_to_string(const char *filename) { + FILE *file = fopen(filename, "rb"); // Open file in binary mode + if (!file) { + perror("Error opening file"); + return NULL; + } -// HTTP request handler -enum MHD_Result handle_request(void *cls, struct MHD_Connection *connection, - const char *url, const char *method, - const char *version, const char *upload_data, - size_t *upload_data_size, void **con_cls) { - (void)version; - (void)upload_data; - (void)upload_data_size; - (void)con_cls; - struct MHD_Response *response; - enum MHD_Result ret; + // Seek to the end to determine file size + fseek(file, 0, SEEK_END); + long file_size = ftell(file); + rewind(file); // Go back to the beginning - if (strcmp(url, "/slider") == 0 && strcmp(method, "GET") == 0) { - const char *value_str = MHD_lookup_connection_value(connection, MHD_GET_ARGUMENT_KIND, "value"); - if (value_str) { - int value = atoi(value_str); - handle_slider_change(cls, value); + // Allocate memory for the file content (+1 for null terminator) + char *buffer = (char *)malloc(file_size + 1); + if (!buffer) { + perror("Memory allocation failed"); + fclose(file); + return NULL; } - response = MHD_create_response_from_buffer(0, "", MHD_RESPMEM_PERSISTENT); - ret = MHD_queue_response(connection, MHD_HTTP_OK, response); - MHD_destroy_response(response); - return ret; - } - if (strcmp(url, "/button") == 0 && strcmp(method, "GET") == 0) { - handle_button_click(cls); - response = MHD_create_response_from_buffer(0, "", MHD_RESPMEM_PERSISTENT); - ret = MHD_queue_response(connection, MHD_HTTP_OK, response); - MHD_destroy_response(response); - return ret; - } + // Read file into buffer + fread(buffer, 1, file_size, file); + buffer[file_size] = '\0'; // Null-terminate the string - response = MHD_create_response_from_buffer(strlen(html_content), (void *)html_content, MHD_RESPMEM_PERSISTENT); - ret = MHD_queue_response(connection, MHD_HTTP_OK, response); - MHD_destroy_response(response); - return ret; + fclose(file); + return buffer; +} + + + +int +key_to_number(char key) { + switch (key) { + case 'q': + return 0; + case '2': + return 1; + case 'w': + return 2; + case '3': + return 3; + case 'e': + return 4; + case 'r': + return 5; + case '5': + return 6; + case 't': + return 7; + case '6': + return 8; + case 'y': + return 9; + case '7': + return 10; + case 'u': + return 11; + case 'i': + return 12; + case '9': + return 13; + case 'o': + return 14; + case '0': + return 15; + case 'p': + return 16; + } + return 0; } // Callback to handle WebSocket events @@ -158,7 +122,44 @@ static int callback_ws(struct lws *wsi, enum lws_callback_reasons reason, case LWS_CALLBACK_RECEIVE: { // When a message is received char buffer[128]; snprintf(buffer, sizeof(buffer), "%.*s", (int)len, (char *)in); - printf("Received slider value: %s\n", buffer); + printf("Got ws message: [%s]\n", buffer); + if (!strcmp("note_on", buffer)) { + break; + } + if (!strcmp("note_off", buffer)) { + break; + } + if (buffer[0] == '+') { + char key = buffer[1]; + int i = key_to_number(key); + synthx->midi_note[i].freq = 16.35160 * pow(2, (synthx->octave + i / 12.0)); + synthx->midi_note[i].channel = -1; + synthx->midi_note[i].noteOn = Pa_GetStreamTime(synthx->stream); + synthx->midi_note[i].noteOff = 0; + synthx->midi_note[i].velocity = 1.0; + synthx->midi_note[i].elapsed = 0; + synthx->midi_note[i].active = 1; + int flag = 1; + for (int j = 0; j < synthx->midi_active_n; j++) { + if (synthx->midi_active[j] == &synthx->midi_note[i]) { + flag = 0; + } + } + if (flag) { + synthx->midi_active[synthx->midi_active_n++] = &synthx->midi_note[i]; + } + + //synth->adsr.elapsed = 0; + synthx->active = 1; + break; + } + if (buffer[0] == '-') { + char key = buffer[1]; + int i = key_to_number(key); + synthx->midi_note[i].noteOff = Pa_GetStreamTime(synthx->stream); + synthx->midi_note[i].noteOffSample = synthx->midi_note[i].elapsed; + break; + } //lws_write(wsi, (unsigned char *)in, len, LWS_WRITE_TEXT); int value = atoi(buffer); handle_slider_change(synthx, value); @@ -175,10 +176,8 @@ static int callback_ws(struct lws *wsi, enum lws_callback_reasons reason, case LWS_CALLBACK_HTTP: { snprintf(tmp, sizeof(tmp), html_header, strlen(html_content)); strcpy(buf, tmp); - printf("\nHTTP?!\n\n%s\n", tmp); strcat(buf, html_content); lws_write(wsi, (unsigned char *)buf, strlen(buf), LWS_WRITE_HTTP); - return -1; break; } case LWS_CALLBACK_CLOSED: { @@ -224,16 +223,41 @@ void *websocket_server_thread(void *arg) { return NULL; } +char *get_from_template() { + int size = 1024^3 * 1000; + char * ret = (char *)malloc(sizeof(char) * size); + + int pipefd[2]; + if (pipe(pipefd) == -1) { + perror("pipe"); + return NULL; + } + + #define OUT pipefd[1] + #define INT(x) dprintf(OUT, "%d", x); + #define PERCENT dprintf(OUT, "%s", "%"); + #include "index.html.h" + close(pipefd[1]); + + // Read from the pipe into a buffer + ssize_t bytes_read = read(pipefd[0], ret, size - 1); + if (bytes_read == -1) { + perror("read"); + return NULL; + } + + // Null-terminate the ret + ret[bytes_read] = '\0'; + close(pipefd[0]); + return ret; +} + void init_web(synth_t * synth) { + //html_content = read_file_to_string("src/index.html"); + html_content = get_from_template(); synthx = synth; - // Start the HTTP server - server = MHD_start_daemon(MHD_USE_THREAD_PER_CONNECTION, HTTP_PORT, NULL, NULL, &handle_request, (void *)synth, MHD_OPTION_END); - if (server == NULL) { - fprintf(stderr, "Failed to start server\n"); - return; - } // Create a new thread for the WebSocket server if (pthread_create(&server_thread, NULL, websocket_server_thread, NULL) != 0) { @@ -245,7 +269,7 @@ init_web(synth_t * synth) void free_web() { - MHD_stop_daemon(server); + free(html_content); } void ws_send_message(const char *message) { |