diff --git a/README.md b/README.md index fdd9d76..a6e1e5a 100644 --- a/README.md +++ b/README.md @@ -167,7 +167,10 @@ wat2wasm --enable-bulk-memory test_chords.wat #### Examples -The folder `examples/code` contains usage examples for Sointu with winmm und dsound playback under Windows and asound playback under Unix. Source code is available in C and x86 assembly (win32, elf32 and elf64 versions). +The folder `examples/code` contains usage examples for Sointu with winmm +and dsound playback under Windows and asound playback under Unix. Source +code is available in C and x86 assembly (win32, elf32 and elf64 +versions). To build the examples, use `ninja examples`. diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 897896d..fa5c928 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -5,8 +5,8 @@ function(regression_test testname) add_executable(${testname} ${source} test_renderer.c) else() if(ARGV3) - set(source ${ARGV3}.yml) - else() + set(source ${ARGV3}.yml) + else() set(source ${testname}.yml) endif() @@ -31,14 +31,14 @@ function(regression_test testname) COMMAND ${compilecmd} ${ARGV4} -arch=wasm -o ${watfile} ${CMAKE_CURRENT_SOURCE_DIR}/${source} && ${WAT2WASM} -o ${wasmfile} ${watfile} DEPENDS ${source} ${wasmtemplates} ${compilecmd} ) - + add_custom_target(${wasmtarget} ALL SOURCES "${source}" "${wasmtemplates}" DEPENDS ${wasmfile} ) add_test(${wasmtarget} ${NODE} ${CMAKE_CURRENT_SOURCE_DIR}/wasm_test_renderer.es6 ${wasmfile} ${CMAKE_CURRENT_SOURCE_DIR}/expected_output/${testname}.raw) - endif() + endif() endif() if (${testname} MATCHES "sync") @@ -50,12 +50,12 @@ function(regression_test testname) target_include_directories(${testname} PUBLIC ${CMAKE_CURRENT_BINARY_DIR}) target_compile_definitions(${testname} PUBLIC TEST_NAME="${testname}") - + if (ARGV1) message("${testname} requires ${ARGV1}") set_tests_properties(${testname} PROPERTIES FIXTURES_REQUIRED "${ARGV1}") endif() - + if (ARGV2) message("${testname} setups ${ARGV2}") set_tests_properties(${testname} PROPERTIES FIXTURES_SETUP "${ARGV2}") diff --git a/tests/test_render_samples.c b/tests/test_render_samples.c index 562e761..165a605 100644 --- a/tests/test_render_samples.c +++ b/tests/test_render_samples.c @@ -4,27 +4,28 @@ #include #include "test_render_samples.h" -void SU_CALLCONV su_render_song(float* buffer) { - Synth* synth; - const unsigned char commands[] = { SU_ENVELOPE_ID, // MONO - SU_ENVELOPE_ID, // MONO - SU_OUT_ID + 1, // STEREO - SU_ADVANCE_ID };// MONO - const unsigned char values[] = { 64, 64, 64, 80, 128, // envelope 1 - 95, 64, 64, 80, 128, // envelope 2 - 128}; +void SU_CALLCONV su_render_song(float *buffer) +{ + Synth *synth; + const unsigned char commands[] = {SU_ENVELOPE_ID, // MONO + SU_ENVELOPE_ID, // MONO + SU_OUT_ID + 1, // STEREO + SU_ADVANCE_ID}; // MONO + const unsigned char values[] = {64, 64, 64, 80, 128, // envelope 1 + 95, 64, 64, 80, 128, // envelope 2 + 128}; int retval; int samples; int time; // initialize Synth - synth = (Synth*)malloc(sizeof(Synth)); + synth = (Synth *)malloc(sizeof(Synth)); memset(synth, 0, sizeof(Synth)); memcpy(synth->Commands, commands, sizeof(commands)); memcpy(synth->Values, values, sizeof(values)); synth->NumVoices = 1; synth->Polyphony = 0; synth->RandSeed = 1; - // triger first voice + // triger first voice synth->SynthWrk.Voices[0].Note = 64; synth->SynthWrk.Voices[0].Sustain = 1; samples = SU_LENGTH_IN_SAMPLES / 2; diff --git a/tests/test_render_samples_api.c b/tests/test_render_samples_api.c index 135862f..393f792 100644 --- a/tests/test_render_samples_api.c +++ b/tests/test_render_samples_api.c @@ -10,23 +10,24 @@ #define SAMPLES_PER_ROW SAMPLE_RATE * 4 * 60 / (BPM * 16) const int su_max_samples = SAMPLES_PER_ROW * LENGTH_IN_ROWS; -int main(int argc, char* argv[]) { - Synth* synth; - float* buffer; - const unsigned char commands[] = { SU_ENVELOPE_ID, // MONO - SU_ENVELOPE_ID, // MONO - SU_OUT_ID + 1, // STEREO - SU_ADVANCE_ID };// MONO - const unsigned char values[] = { 64, 64, 64, 80, 128, // envelope 1 - 95, 64, 64, 80, 128, // envelope 2 - 128 }; +int main(int argc, char *argv[]) +{ + Synth *synth; + float *buffer; + const unsigned char commands[] = {SU_ENVELOPE_ID, // MONO + SU_ENVELOPE_ID, // MONO + SU_OUT_ID + 1, // STEREO + SU_ADVANCE_ID}; // MONO + const unsigned char values[] = {64, 64, 64, 80, 128, // envelope 1 + 95, 64, 64, 80, 128, // envelope 2 + 128}; int errcode; int time; int samples; int totalrendered; - int retval; + int retval; // initialize Synth - synth = (Synth*)malloc(sizeof(Synth)); + synth = (Synth *)malloc(sizeof(Synth)); memset(synth, 0, sizeof(Synth)); memcpy(synth->Commands, commands, sizeof(commands)); memcpy(synth->Values, values, sizeof(values)); @@ -34,13 +35,13 @@ int main(int argc, char* argv[]) { synth->Polyphony = 0; synth->RandSeed = 1; // initialize Buffer - buffer = (float*)malloc(2 * sizeof(float) * su_max_samples); - // triger first voice + buffer = (float *)malloc(2 * sizeof(float) * su_max_samples); + // triger first voice synth->SynthWrk.Voices[0].Note = 64; synth->SynthWrk.Voices[0].Sustain = 1; totalrendered = 0; // First check that when we render using su_render with 0 time - // we get nothing done + // we get nothing done samples = su_max_samples; time = 0; errcode = su_render(synth, buffer, &samples, &time); @@ -50,18 +51,18 @@ int main(int argc, char* argv[]) { { printf("su_render rendered samples, despite it should not\n"); goto fail; - } + } if (time > 0) { printf("su_render advanced time, despite it should not\n"); goto fail; } // Then check that when we render using su_render with 0 samples, - // we get nothing done + // we get nothing done samples = 0; time = INT32_MAX; errcode = su_render(synth, buffer, &samples, &time); - if (errcode != 0) + if (errcode != 0) goto fail; if (samples > 0) { @@ -75,12 +76,13 @@ int main(int argc, char* argv[]) { } // Then check that each time we call render, only SAMPLES_PER_ROW // number of samples are rendered - for (int i = 0; i < 16; i++) { + for (int i = 0; i < 16; i++) + { // Simulate "small buffers" i.e. render a buffer with 1 sample // check that buffer full samples = 1; time = INT32_MAX; - errcode = su_render(synth, &buffer[totalrendered*2], &samples, &time); + errcode = su_render(synth, &buffer[totalrendered * 2], &samples, &time); if (errcode != 0) goto fail; totalrendered += samples; @@ -93,7 +95,7 @@ int main(int argc, char* argv[]) { { printf("su_render should have advanced the time also by one"); goto fail; - } + } samples = SAMPLES_PER_ROW - 1; time = INT32_MAX; errcode = su_render(synth, &buffer[totalrendered * 2], &samples, &time); @@ -117,14 +119,15 @@ int main(int argc, char* argv[]) { { printf("su_render should have rendered a total of su_max_samples"); goto fail; - } + } retval = 0; finish: free(synth); free(buffer); return retval; fail: - if (errcode > 0) { + if (errcode > 0) + { if ((errcode & 0xFF00) != 0) printf("FPU stack was not empty on exit\n"); if ((errcode & 0x04) != 0) diff --git a/tests/test_renderer.c b/tests/test_renderer.c index 6c01eba..d538989 100644 --- a/tests/test_renderer.c +++ b/tests/test_renderer.c @@ -1,4 +1,4 @@ -#if defined (_WIN32) +#if defined(_WIN32) #define _CRT_SECURE_NO_DEPRECATE #include #else @@ -21,9 +21,9 @@ float syncBuf[SU_SYNCBUFFER_LENGTH]; float fileSyncBuf[SU_BUFFER_LENGTH]; #endif - -int main(int argc, char* argv[]) { - FILE* f; +int main(int argc, char *argv[]) +{ + FILE *f; char filename[256]; int n; char test_name[] = TEST_NAME; @@ -33,18 +33,19 @@ int main(int argc, char* argv[]) { float max_diff; float diff; - if (argc < 2) { + if (argc < 2) + { fprintf(stderr, "usage: [test] path/to/expected_wave.raw"); return 1; } - #ifdef SU_LOAD_GMDLS +#ifdef SU_LOAD_GMDLS su_load_gmdls(); - #endif +#endif su_render_song(buf); -#if defined (_WIN32) +#if defined(_WIN32) CreateDirectory(actual_output_folder, NULL); #else mkdir(actual_output_folder, 0777); @@ -52,19 +53,20 @@ int main(int argc, char* argv[]) { snprintf(filename, sizeof filename, "%s%s%s", actual_output_folder, test_name, ".raw"); f = fopen(filename, "wb"); - fwrite((void*)buf, sizeof(SUsample), SU_BUFFER_LENGTH, f); + fwrite((void *)buf, sizeof(SUsample), SU_BUFFER_LENGTH, f); fclose(f); - #ifdef SU_SYNC +#ifdef SU_SYNC snprintf(filename, sizeof filename, "%s%s%s", actual_output_folder, test_name, "_syncbuf.raw"); f = fopen(filename, "wb"); - fwrite((void*)syncBuf, sizeof(float), SU_SYNCBUFFER_LENGTH, f); + fwrite((void *)syncBuf, sizeof(float), SU_SYNCBUFFER_LENGTH, f); fclose(f); - #endif +#endif f = fopen(argv[1], "rb"); - if (f == NULL) { + if (f == NULL) + { fprintf(stderr, "No expected waveform found!\n"); goto fail; } @@ -73,42 +75,49 @@ int main(int argc, char* argv[]) { fsize = ftell(f); fseek(f, 0, SEEK_SET); - if (SU_BUFFER_LENGTH * sizeof(SUsample) < fsize) { + if (SU_BUFFER_LENGTH * sizeof(SUsample) < fsize) + { fprintf(stderr, "Sointu rendered shorter wave than expected\n"); goto fail; } - if (SU_BUFFER_LENGTH * sizeof(SUsample) > fsize) { + if (SU_BUFFER_LENGTH * sizeof(SUsample) > fsize) + { fprintf(stderr, "Sointu rendered longer wave than expected\n"); goto fail; } - fread((void*)filebuf, fsize, 1, f); + fread((void *)filebuf, fsize, 1, f); fclose(f); f = NULL; max_diff = 0.0f; - for (n = 0; n < SU_BUFFER_LENGTH; n++) { - diff = (float)fabs((float)(buf[n] - filebuf[n])/SU_SAMPLE_RANGE); - if (diff > 1e-3f || isnan(diff)) { + for (n = 0; n < SU_BUFFER_LENGTH; n++) + { + diff = (float)fabs((float)(buf[n] - filebuf[n]) / SU_SAMPLE_RANGE); + if (diff > 1e-3f || isnan(diff)) + { fprintf(stderr, "Sointu rendered different wave than expected\n"); goto fail; } - if (diff > max_diff) { + if (diff > max_diff) + { max_diff = diff; } } - if (max_diff > 1e-6) { - fprintf(stderr, "Warning: Sointu rendered almost correct wave, but a small maximum error of %f\n",max_diff); + if (max_diff > 1e-6) + { + fprintf(stderr, "Warning: Sointu rendered almost correct wave, but a small maximum error of %f\n", max_diff); } #ifdef SU_SYNC f = fopen(argv[2], "rb"); - if (f == NULL) { + if (f == NULL) + { fprintf(stderr, "No expected sync waveform found!\n"); goto fail; } @@ -117,25 +126,29 @@ int main(int argc, char* argv[]) { fsize = ftell(f); fseek(f, 0, SEEK_SET); - if (SU_SYNCBUFFER_LENGTH * sizeof(float) < fsize) { + if (SU_SYNCBUFFER_LENGTH * sizeof(float) < fsize) + { fprintf(stderr, "Sointu rendered shorter sync wave than expected\n"); goto fail; } - if (SU_SYNCBUFFER_LENGTH * sizeof(float) > fsize) { + if (SU_SYNCBUFFER_LENGTH * sizeof(float) > fsize) + { fprintf(stderr, "Sointu rendered longer sync wave than expected\n"); goto fail; } - fread((void*)fileSyncBuf, fsize, 1, f); + fread((void *)fileSyncBuf, fsize, 1, f); fclose(f); f = NULL; max_diff = 0.0f; - for (n = 0; n < SU_SYNCBUFFER_LENGTH; n++) { + for (n = 0; n < SU_SYNCBUFFER_LENGTH; n++) + { diff = (float)fabs(syncBuf[n] - fileSyncBuf[n]); - if (diff > 1e-3f || isnan(diff)) { + if (diff > 1e-3f || isnan(diff)) + { fprintf(stderr, "Sointu rendered different sync wave than expected\n"); goto fail; } @@ -144,7 +157,8 @@ int main(int argc, char* argv[]) { return 0; fail: - if (f != NULL) { + if (f != NULL) + { fclose(f); f = NULL; } diff --git a/tracker/generate/main.go b/tracker/generate/main.go index b377cf8..5a506fe 100644 --- a/tracker/generate/main.go +++ b/tracker/generate/main.go @@ -1,4 +1,6 @@ +//go:build ignore // +build ignore + package main import ( diff --git a/vm/compiler/templates/wasm/sources.wat b/vm/compiler/templates/wasm/sources.wat index cd7d10a..597bf52 100644 --- a/vm/compiler/templates/wasm/sources.wat +++ b/vm/compiler/templates/wasm/sources.wat @@ -206,7 +206,7 @@ {{- end}} {{- if .Stereo "oscillator"}} (local.set $detune (f32.neg (local.get $detune))) ;; flip the detune for secon round - (global.set $WRK (i32.add (global.get $WRK) (i32.const 4))) + (global.set $WRK (i32.add (global.get $WRK) (i32.const 4))) (br_if $stereoLoop (i32.eqz (local.tee $stereo (i32.eqz (local.get $stereo))))) end (global.set $WRK (local.get $WRK_stereostash)) diff --git a/vm/generate/generate.go b/vm/generate/generate.go index ac3c42b..3bc177c 100644 --- a/vm/generate/generate.go +++ b/vm/generate/generate.go @@ -1,4 +1,6 @@ +//go:build ignore // +build ignore + package main import (