diff options
-rw-r--r-- | TODO | 8 | ||||
-rw-r--r-- | build_and_test.sh | 10 | ||||
-rw-r--r-- | refetch_deps.sh | 52 | ||||
-rw-r--r-- | source/saw/_impl.c | 32 | ||||
-rw-r--r-- | source/saw/main.c | 66 |
5 files changed, 117 insertions, 51 deletions
@@ -3,14 +3,14 @@ To-Do list - UI: Piano roll - UI: Volume control - UI: Playback control -- Simple tonal synth +- Sound: Buffering. +- Sound: Simple tonal synth - Build: WebAssembly -- Drum synth: kick, snare, cymbal +- Sound: Kick, snare, cymbal - UI: Track composing -- Build: Faster recompilation - Done - Script for fetching dependencies. - nanovg and miniaudio setup. +- Build: Faster recompilation diff --git a/build_and_test.sh b/build_and_test.sh index 46f8661..0b40374 100644 --- a/build_and_test.sh +++ b/build_and_test.sh @@ -111,8 +111,18 @@ fi echo "" echo "Build saw" +if [ ! -f "build/saw_impl${OBJ_POSTFIX}" ] || \ + [ "source/saw/_impl.c" -nt "build/saw_impl${OBJ_POSTFIX}" ]; then + $COMPILE ${FLAGS} \ + ${FLAG_OBJ}"build/saw_impl${OBJ_POSTFIX}" \ + "source/saw/_impl.c" + if [ $? -ne 0 ]; then + exit 1 + fi +fi $COMPILE ${FLAGS} \ ${FLAG_EXE}"build/saw${EXE_POSTFIX}" \ + "build/saw_impl${OBJ_POSTFIX}" \ "source/saw/_exe.c" \ ${LINK_FLAGS} if [ $? -ne 0 ]; then diff --git a/refetch_deps.sh b/refetch_deps.sh index 19be044..d3081b2 100644 --- a/refetch_deps.sh +++ b/refetch_deps.sh @@ -1,44 +1,38 @@ -if [ -d "./source/kit" ]; then - rm -rf "./source/kit" +if [ -d "source/kit" ]; then + rm -rf "source/kit" fi - -if [ -d "./source/stb" ]; then - rm -rf "./source/stb" +if [ -d "source/stb" ]; then + rm -rf "source/stb" fi - -if [ -f "./source/thirdparty/miniaudio.h" ]; then - rm -rf "./source/thirdparty/miniaudio.h" +if [ -f "source/thirdparty/miniaudio.h" ]; then + rm -rf "source/thirdparty/miniaudio.h" fi - -if [ -d "./_tmp_kit" ]; then - rm -rf "./_tmp_kit" +if [ -d "_tmp_kit" ]; then + rm -rf "_tmp_kit" fi - -if [ -d "./_tmp_stb" ]; then - rm -rf "./_tmp_stb" +if [ -d "_tmp_stb" ]; then + rm -rf "_tmp_stb" fi - -if [ -d "./_tmp_miniaudio" ]; then - rm -rf "./_tmp_miniaudio" +if [ -d "_tmp_miniaudio" ]; then + rm -rf "_tmp_miniaudio" fi git clone --quiet --depth 1 https://guattari.tech/kit.git _tmp_kit git clone --quiet --depth 1 https://github.com/nothings/stb.git _tmp_stb git clone --quiet --depth 1 https://github.com/mackron/miniaudio.git _tmp_miniaudio -if [ ! -d "./source/stb" ]; then - mkdir "./source/stb" +if [ ! -d "source/stb" ]; then + mkdir "source/stb" fi - -if [ ! -d "./source/thirdparty" ]; then - mkdir "./source/thirdparty" +if [ ! -d "source/thirdparty" ]; then + mkdir "source/thirdparty" fi -mv "./_tmp_kit/source/kit" "./source/kit" -mv "./_tmp_stb/stb_image.h" "./source/stb/stb_image.h" -mv "./_tmp_stb/stb_truetype.h" "./source/stb/stb_truetype.h" -mv "./_tmp_miniaudio/miniaudio.h" "./source/thirdparty/miniaudio.h" +mv "_tmp_kit/source/kit" "source/kit" +mv "_tmp_stb/stb_image.h" "source/stb/stb_image.h" +mv "_tmp_stb/stb_truetype.h" "source/stb/stb_truetype.h" +mv "_tmp_miniaudio/miniaudio.h" "source/thirdparty/miniaudio.h" -rm -rf "./_tmp_kit" -rm -rf "./_tmp_stb" -rm -rf "./_tmp_miniaudio" +rm -rf "_tmp_kit" +rm -rf "_tmp_stb" +rm -rf "_tmp_miniaudio" diff --git a/source/saw/_impl.c b/source/saw/_impl.c new file mode 100644 index 0000000..f405a6b --- /dev/null +++ b/source/saw/_impl.c @@ -0,0 +1,32 @@ +#ifdef __EMSCRIPTEN__ +# define SOKOL_GLES3 +# define NANOVG_GLES3 1 +#else +# define SOKOL_GLCORE33 +# define NANOVG_GL3 1 +#endif + +// sokol +// +#define SOKOL_APP_IMPL +#include "../kit/time.h" // for timespec_get +#include "../thirdparty/sokol_app.h" + +// miniaudio +// +#ifdef __GNUC__ +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wunused-result" +#endif +#define MINIAUDIO_IMPLEMENTATION +#include "../thirdparty/miniaudio.h" +#ifdef __GNUC__ +# pragma GCC diagnostic pop +#endif + +// nanovg +// +#include "../thirdparty/nanovg.c" +#include "../thirdparty/nanovg_gl.c" +#include "../thirdparty/android.c" + diff --git a/source/saw/main.c b/source/saw/main.c index ff2a34c..89e899e 100644 --- a/source/saw/main.c +++ b/source/saw/main.c @@ -3,30 +3,25 @@ // - Custom OpenGL loader. // +#include "../kit/math.h" +#include "../kit/time.h" + #ifdef __EMSCRIPTEN__ +# include <GLES3/gl3.h> # define SOKOL_GLES3 # define NANOVG_GLES3 1 #else +# include <GL/gl.h> # define SOKOL_GLCORE33 # define NANOVG_GL3 1 #endif -#include "../kit/time.h" // for timespec_get - -// sokol -#define SOKOL_APP_IMPL #include "../thirdparty/sokol_app.h" - -// nanovg -#include "../thirdparty/nanovg.c" -#include "../thirdparty/nanovg_gl.c" -#include "../thirdparty/android.c" - -// miniaudio -#define MINIAUDIO_IMPLEMENTATION #include "../thirdparty/miniaudio.h" +#include "../thirdparty/nanovg.h" +#include "../thirdparty/nanovg_gl.h" -#include "../kit/math.h" +#include <stdio.h> enum { SAW_CHANNEL_COUNT = 2, @@ -39,6 +34,8 @@ enum { static struct NVGcontext *saw_nvg; static ma_device saw_ma; +static i64 saw_time = 0; + static i32 saw_mouse_x = 0; static i32 saw_mouse_y = 0; static i8 saw_lbutton_click = 0; @@ -60,6 +57,21 @@ static i8 saw_pianoroll_turned_off[PIANOROLL_SIZE] = { 0 }; # pragma GCC optimize("O3") #endif +static i64 time_(void) { + struct timespec t; + timespec_get(&t, TIME_UTC); + return ((i64) t.tv_sec) * 1000 + ((i64) t.tv_nsec) / 1000000; +} + +static void time_frame_(char const *s) { + i64 t = time_(); + if (saw_time == 0) + printf("%-20s %lld\n", s, t); + else + printf("%-20s+%lld\n", s, t - saw_time); + saw_time = t; +} + static f64 saw_envelope(f64 t, f64 attack, f64 decay, f64 sustain, f64 duration, f64 release) { // FIXME @@ -117,6 +129,8 @@ static void saw_audio(ma_device *device, void *void_out_, #endif static void saw_init(void) { + time_frame_("saw_init"); + sapp_set_window_title("saw"); #ifdef SOKOL_GLCORE33 @@ -125,6 +139,8 @@ static void saw_init(void) { saw_nvg = nvgCreateGLES3(NVG_ANTIALIAS | NVG_STENCIL_STROKES); #endif + time_frame_(" ma device config"); + ma_device_config config = ma_device_config_init( ma_device_type_playback); @@ -134,12 +150,17 @@ static void saw_init(void) { config.dataCallback = saw_audio; config.pUserData = NULL; + time_frame_(" ma device init"); + if (ma_device_init(NULL, &config, &saw_ma) != MA_SUCCESS) { printf("ma_device_init failed.\n"); return; } + time_frame_(" ma start"); ma_device_start(&saw_ma); + + time_frame_(" done"); } static void saw_frame(void) { @@ -148,7 +169,7 @@ static void saw_frame(void) { glViewport(0, 0, width, height); glClearColor(.23f, .19f, .16f, 1.f); - glClearDepthf(1.f); + glClearDepth(1.); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); @@ -164,6 +185,8 @@ static void saw_frame(void) { i32 pianokey_width = 100; i32 pianokey_border = 2; + i8 hover_any = 0; + for (i32 i = 0; i < PIANOROLL_SIZE; i++) { i32 x = x0 + pianokey_border; i32 y = height - y0 - (i + 1) * pianokey_height; @@ -188,6 +211,8 @@ static void saw_frame(void) { nvgFill(saw_nvg); if (has_cursor) { + hover_any = 1; + if (!saw_pianoroll_turned_off[i] && (saw_lbutton_click || (saw_lbutton_down && saw_pianoroll_last_index != i)) && @@ -198,17 +223,21 @@ static void saw_frame(void) { saw_voice_time[n] = saw_voice_time[n - 1]; } - saw_voice_on[0] = 1; - saw_voice_pitch[0] = i; - saw_voice_time[0] = 0; - saw_pianoroll_last_index = i; + saw_voice_on[0] = 1; + saw_voice_pitch[0] = i; + saw_voice_time[0] = 0; } if (saw_rbutton_click) saw_pianoroll_turned_off[i] = !saw_pianoroll_turned_off[i]; + + saw_pianoroll_last_index = i; } } + if (!hover_any) + saw_pianoroll_last_index = -1; + nvgEndFrame(saw_nvg); // Cleanup input state. @@ -264,6 +293,7 @@ char const *__lsan_default_suppressions() { } sapp_desc sokol_main(int argc, char **argv) { + time_frame_("sokol_main"); return (sapp_desc) { .width = 1280, .height = 720, |