From 9847614871e861c216425b95a8300dba37b0f6e6 Mon Sep 17 00:00:00 2001 From: grm Date: Sun, 2 Mar 2025 13:53:54 +0200 Subject: Also improve midi and add tt for templating --- src/b.h | 35 ++++--- src/gui.h | 16 ++++ src/midi.c | 20 +--- src/sound.c | 3 +- src/synth_engine.h | 7 +- src/synth_engine_v2.c | 2 +- src/synth_gui.c | 40 ++++---- src/tt.c | 124 +++++++++++++++++++++++++ src/web.c | 248 +++++++++++++++++++++++++++----------------------- 9 files changed, 332 insertions(+), 163 deletions(-) create mode 100644 src/gui.h create mode 100644 src/tt.c (limited to 'src') diff --git a/src/b.h b/src/b.h index 0b3bf2e..a6dba68 100644 --- a/src/b.h +++ b/src/b.h @@ -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 */ diff --git a/src/midi.c b/src/midi.c index 429e9df..a015de4 100644 --- a/src/midi.c +++ b/src/midi.c @@ -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 +#include +#include +#include +#include +#include + +#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