From 8d984cbc38aa06429b5603308a17f79764e98971 Mon Sep 17 00:00:00 2001 From: Veikko Sariola Date: Sun, 12 Apr 2020 21:55:28 +0300 Subject: [PATCH] Implement ctest unit test, first test simply testing that envelope works as it used to. --- CMakeLists.txt | 6 + tests/CMakeLists.txt | 7 + tests/test_env.asm | 652 ++++++++++++++++++++++++++++++++++++ tests/test_env_expected.raw | Bin 0 -> 846720 bytes tests/test_renderer.c | 77 +++++ 5 files changed, 742 insertions(+) create mode 100644 tests/CMakeLists.txt create mode 100644 tests/test_env.asm create mode 100644 tests/test_env_expected.raw create mode 100644 tests/test_renderer.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 128e472..b409c31 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,3 +35,9 @@ add_subdirectory(src) # We should put examples here # add_subdirectory(examples) + +# Testing only available if this is the main app +# Emergency override 4KLANG_CMAKE_BUILD_TESTING provided as well +if((CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME OR 4KLANG_CMAKE_BUILD_TESTING) AND BUILD_TESTING) + add_subdirectory(tests) +endif() \ No newline at end of file diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 0000000..919613b --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,7 @@ +add_executable(test_env test_env.asm test_renderer.c test_env_expected.raw) +add_custom_command( + TARGET test_env POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy + ${CMAKE_SOURCE_DIR}/tests/test_env_expected.raw + ${CMAKE_CURRENT_BINARY_DIR}/test_env_expected.raw) +add_test(test_env test_env) \ No newline at end of file diff --git a/tests/test_env.asm b/tests/test_env.asm new file mode 100644 index 0000000..71ab3ba --- /dev/null +++ b/tests/test_env.asm @@ -0,0 +1,652 @@ +bits 32 + +; //---------------------------------------------------------------------------------------- +; // useful macros +; //---------------------------------------------------------------------------------------- +; // export function (make it accessable from main.cpp) +; //---------------------------------------------------------------------------------------- +%macro export_func 1 + global _%1 + _%1: +%endmacro +%define USE_SECTIONS +; //---------------------------------------------------------------------------------------- +; // basic defines for the song/synth +; //---------------------------------------------------------------------------------------- +;%define AUTHORING ; Use to export the current tick being rendered +;%define SINGLE_TICK_RENDERING ; Use to render single tick on _4klang_render invocation ( requires AUTHORING enabled ) +%define SAMPLE_RATE 44100 +%define MAX_INSTRUMENTS 1 +%define MAX_VOICES 1 +%define HLD 1 ; // can be adjusted to give crinkler some other possibilities +%define BPM 100 +%define MAX_PATTERNS 1 +%define PATTERN_SIZE_SHIFT 4 +%define PATTERN_SIZE (1 << PATTERN_SIZE_SHIFT) +%define MAX_TICKS (MAX_PATTERNS*PATTERN_SIZE) +%define SAMPLES_PER_TICK (SAMPLE_RATE*4*60/(BPM*16)) +%define DEF_LFO_NORMALIZE 0.000038 +%define MAX_SAMPLES (SAMPLES_PER_TICK*MAX_TICKS) +; //---------------------------------------------------------------------------------------- +; // some defines for unit usage, which reduce synth code size +; //---------------------------------------------------------------------------------------- +;%define GO4K_USE_16BIT_OUTPUT ; // removing this will output to 32bit floating point buffer +;%define GO4K_USE_GROOVE_PATTERN ; // removing this skips groove pattern code +;%define GO4K_USE_ENVELOPE_RECORDINGS ; // removing this skips envelope recording code +;%define GO4K_USE_NOTE_RECORDINGS ; // removing this skips note recording code +%define GO4K_USE_UNDENORMALIZE ; // removing this skips denormalization code in the units +%define GO4K_CLIP_OUTPUT ; // removing this skips clipping code for the final output +%define GO4K_USE_DST ; // removing this will skip DST unit +%define GO4K_USE_DLL ; // removing this will skip DLL unit +%define GO4K_USE_PAN ; // removing this will skip PAN unit +%define GO4K_USE_GLOBAL_DLL ; // removing this will skip global dll processing +%define GO4K_USE_FSTG ; // removing this will skip global store unit +%define GO4K_USE_FLD ; // removing this will skip float load unit +%define GO4K_USE_GLITCH ; // removing this will skip GLITCH unit +%define GO4K_USE_ENV_CHECK ; // removing this skips checks if processing is needed +%define GO4K_USE_ENV_MOD_GM ; // removing this will skip env gain modulation code +%define GO4K_USE_ENV_MOD_ADR ; // removing this will skip env attack/decay/release modulation code +%define GO4K_USE_VCO_CHECK ; // removing this skips checks if processing is needed +%define GO4K_USE_VCO_PHASE_OFFSET ; // removing this will skip initial phase offset code +%define GO4K_USE_VCO_SHAPE ; // removing this skips waveshaping code +%define GO4K_USE_VCO_GATE ; // removing this skips gate code +%define GO4K_USE_VCO_MOD_FM ; // removing this skips frequency modulation code +%define GO4K_USE_VCO_MOD_PM ; // removing this skips phase modulation code +%define GO4K_USE_VCO_MOD_TM ; // removing this skips transpose modulation code +%define GO4K_USE_VCO_MOD_DM ; // removing this skips detune modulation code +%define GO4K_USE_VCO_MOD_CM ; // removing this skips color modulation code +%define GO4K_USE_VCO_MOD_GM ; // removing this skips gain modulation code +%define GO4K_USE_VCO_MOD_SM ; // removing this skips shaping modulation code +%define GO4K_USE_VCO_STEREO ; // removing this skips stereo code +%define GO4K_USE_VCF_CHECK ; // removing this skips checks if processing is needed +%define GO4K_USE_VCF_MOD_FM ; // removing this skips frequency modulation code +%define GO4K_USE_VCF_MOD_RM ; // removing this skips resonance modulation code +%define GO4K_USE_VCF_HIGH ; // removing this skips code for high output +%define GO4K_USE_VCF_BAND ; // removing this skips code for band output +%define GO4K_USE_VCF_PEAK ; // removing this skips code for peak output +%define GO4K_USE_VCF_STEREO ; // removing this skips code for stereo filter output +%define GO4K_USE_DST_CHECK ; // removing this skips checks if processing is needed +%define GO4K_USE_DST_SH ; // removing this skips sample and hold code +%define GO4K_USE_DST_MOD_DM ; // removing this skips distortion modulation code +%define GO4K_USE_DST_MOD_SH ; // removing this skips sample and hold modulation code +%define GO4K_USE_DST_STEREO ; // removing this skips stereo processing +%define GO4K_USE_DLL_NOTE_SYNC ; // removing this will skip delay length adjusting code (karplus strong) +%define GO4K_USE_DLL_CHORUS ; // removing this will skip delay chorus/flanger code +%define GO4K_USE_DLL_CHORUS_CLAMP ; // removing this will skip chorus lfo phase clamping +%define GO4K_USE_DLL_DAMP ; // removing this will skip dll damping code +%define GO4K_USE_DLL_DC_FILTER ; // removing this will skip dll dc offset removal code +%define GO4K_USE_FSTG_CHECK ; // removing this skips checks if processing is needed +%define GO4K_USE_PAN_MOD ; // removing this will skip panning modulation code +%define GO4K_USE_OUT_MOD_AM ; // removing this skips output aux send modulation code +%define GO4K_USE_OUT_MOD_GM ; // removing this skips output gain modulation code +%define GO4K_USE_WAVESHAPER_CLIP ; // removing this will skip clipping code +%define GO4K_USE_FLD_MOD_VM ; // removing this will skip float load modulation code +%define GO4K_USE_DLL_MOD ; // define this to enable modulations for delay line +%define GO4K_USE_DLL_MOD_PM ; // define this to enable pregain modulation for delay line +%define GO4K_USE_DLL_MOD_FM ; // define this to enable feebback modulation for delay line +%define GO4K_USE_DLL_MOD_IM ; // define this to enable dry modulation for delay line +%define GO4K_USE_DLL_MOD_DM ; // define this to enable damping modulation for delay line +%define GO4K_USE_DLL_MOD_SM ; // define this to enable lfo freq modulation for delay line +%define GO4K_USE_DLL_MOD_AM ; // define this to enable lfo depth modulation for delay line + +; //---------------------------------------------------------------------------------------- +; // synth defines +; //---------------------------------------------------------------------------------------- +%define MAX_DELAY 65536 +%define MAX_UNITS 64 +%define MAX_UNIT_SLOTS 16 +%define GO4K_BEGIN_CMDDEF(def_name) +%define GO4K_END_CMDDEF db 0 +%define GO4K_BEGIN_PARAMDEF(def_name) +%define GO4K_END_PARAMDEF +; //---------------------------------------------------------------------------------------- +; // ENV structs +; //---------------------------------------------------------------------------------------- +GO4K_ENV_ID equ 1 +%macro GO4K_ENV 5 + db %1 + db %2 + db %3 + db %4 + db %5 +%endmacro +%define ATTAC(val) val +%define DECAY(val) val +%define SUSTAIN(val) val +%define RELEASE(val) val +%define GAIN(val) val +struc go4kENV_val +;// unit paramters + .attac resd 1 + .decay resd 1 + .sustain resd 1 + .release resd 1 + .gain resd 1 + .size +endstruc +struc go4kENV_wrk +;// work variables + .state resd 1 + .level resd 1 +;// modulation targets + .gm resd 1 + .am resd 1 + .dm resd 1 + .sm resd 1 + .rm resd 1 + .size +endstruc +%define ENV_STATE_ATTAC 0 +%define ENV_STATE_DECAY 1 +%define ENV_STATE_SUSTAIN 2 +%define ENV_STATE_RELEASE 3 +%define ENV_STATE_OFF 4 +; //---------------------------------------------------------------------------------------- +; // VCO structs +; //---------------------------------------------------------------------------------------- +GO4K_VCO_ID equ 2 + +%macro GO4K_VCO 8 + db %1 + db %2 +%ifdef GO4K_USE_VCO_PHASE_OFFSET + db %3 +%endif +%ifdef GO4K_USE_VCO_GATE + db %4 +%endif + db %5 +%ifdef GO4K_USE_VCO_SHAPE + db %6 +%else +%endif + db %7 + db %8 +%endmacro +%define TRANSPOSE(val) val +%define DETUNE(val) val +%define PHASE(val) val +%define GATES(val) val +%define COLOR(val) val +%define SHAPE(val) val +%define FLAGS(val) val +%define SINE 0x01 +%define TRISAW 0x02 +%define PULSE 0x04 +%define NOISE 0x08 +%define LFO 0x10 +%define GATE 0x20 +%define VCO_STEREO 0x40 +struc go4kVCO_val +;// unit paramters + .transpose resd 1 + .detune resd 1 +%ifdef GO4K_USE_VCO_PHASE_OFFSET + .phaseofs resd 1 +%endif +%ifdef GO4K_USE_VCO_GATE + .gate resd 1 +%endif + .color resd 1 +%ifdef GO4K_USE_VCO_SHAPE + .shape resd 1 +%endif + .gain resd 1 + .flags resd 1 + .size +endstruc +struc go4kVCO_wrk +;// work variables + .phase resd 1 +;// modulation targets + .tm resd 1 + .dm resd 1 + .fm resd 1 + .pm resd 1 + .cm resd 1 + .sm resd 1 + .gm resd 1 +;// stero variables + .phase2 resd 1 + .size +endstruc +; //---------------------------------------------------------------------------------------- +; // VCF structs +; //---------------------------------------------------------------------------------------- +GO4K_VCF_ID equ 3 +%macro GO4K_VCF 3 + db %1 + db %2 + db %3 +%endmacro +%define LOWPASS 0x1 +%define HIGHPASS 0x2 +%define BANDPASS 0x4 +%define BANDSTOP 0x3 +%define ALLPASS 0x7 +%define PEAK 0x8 +%define STEREO 0x10 +%define FREQUENCY(val) val +%define RESONANCE(val) val +%define VCFTYPE(val) val +struc go4kVCF_val +;// unit paramters + .freq resd 1 + .res resd 1 + .type resd 1 + .size +endstruc +struc go4kVCF_wrk +;// work variables + .low resd 1 + .high resd 1 + .band resd 1 + .freq resd 1 ;// unused but kept so modulation target offsets stay same +;// modulation targets + .fm resd 1 + .rm resd 1 +;// stereo variables + .low2 resd 1 + .high2 resd 1 + .band2 resd 1 + .size +endstruc +; //---------------------------------------------------------------------------------------- +; // DST structs +; //---------------------------------------------------------------------------------------- +GO4K_DST_ID equ 4 +%macro GO4K_DST 3 + db %1 +%ifdef GO4K_USE_DST_SH + db %2 + %ifdef GO4K_USE_DST_STEREO + db %3 + %endif +%else + %ifdef GO4K_USE_DST_STEREO + db %3 + %endif +%endif +%endmacro +%define DRIVE(val) val +%define SNHFREQ(val) val +%define FLAGS(val) val +struc go4kDST_val +;// unit paramters + .drive resd 1 +%ifdef GO4K_USE_DST_SH + .snhfreq resd 1 +%endif + .flags resd 1 + .size +endstruc +struc go4kDST_wrk +;// work variables + .out resd 1 + .snhphase resd 1 +;// modulation targets + .dm resd 1 + .sm resd 1 +;// stereo variables + .out2 resd 1 + .size +endstruc +; //---------------------------------------------------------------------------------------- +; // DLL structs +; //---------------------------------------------------------------------------------------- +GO4K_DLL_ID equ 5 +%macro GO4K_DLL 8 + db %1 + db %2 + db %3 +%ifdef GO4K_USE_DLL_DAMP + db %4 +%endif +%ifdef GO4K_USE_DLL_CHORUS + db %5 + db %6 +%endif + db %7 + db %8 +%endmacro +%define PREGAIN(val) val +%define DRY(val) val +%define FEEDBACK(val) val +%define DEPTH(val) val +%define DAMP(val) val +%define DELAY(val) val +%define COUNT(val) val +struc go4kDLL_val +;// unit paramters + .pregain resd 1 + .dry resd 1 + .feedback resd 1 +%ifdef GO4K_USE_DLL_DAMP + .damp resd 1 +%endif +%ifdef GO4K_USE_DLL_CHORUS + .freq resd 1 + .depth +%endif + .delay resd 1 + .count resd 1 + .size +endstruc +struc go4kDLL_wrk +;// work variables + .index resd 1 + .store resd 1 + .dcin resd 1 + .dcout resd 1 + .phase resd 1 +;// the delay buffer + .buffer resd MAX_DELAY + .size +endstruc +struc go4kDLL_wrk2 +;// modulation targets + .pm resd 1 + .fm resd 1 + .im resd 1 + .dm resd 1 + .sm resd 1 + .am resd 1 + .size +endstruc +; //---------------------------------------------------------------------------------------- +; // FOP structs +; //---------------------------------------------------------------------------------------- +GO4K_FOP_ID equ 6 +%macro GO4K_FOP 1 + db %1 +%endmacro +%define OP(val) val +%define FOP_POP 0x1 +%define FOP_ADDP 0x2 +%define FOP_MULP 0x3 +%define FOP_PUSH 0x4 +%define FOP_XCH 0x5 +%define FOP_ADD 0x6 +%define FOP_MUL 0x7 +%define FOP_ADDP2 0x8 +%define FOP_LOADNOTE 0x9 +%define FOP_MULP2 0xa +struc go4kFOP_val + .flags resd 1 + .size +endstruc +struc go4kFOP_wrk + .size +endstruc +; //---------------------------------------------------------------------------------------- +; // FST structs +; //---------------------------------------------------------------------------------------- +GO4K_FST_ID equ 7 +%macro GO4K_FST 2 + db %1 + dw %2 +%endmacro +%define AMOUNT(val) val +%define DEST(val) val +%define FST_SET 0x0000 +%define FST_ADD 0x4000 +%define FST_POP 0x8000 +struc go4kFST_val + .amount resd 1 + .op1 resd 1 + .size +endstruc +struc go4kFST_wrk + .size +endstruc +; //---------------------------------------------------------------------------------------- +; // PAN structs +; //---------------------------------------------------------------------------------------- +GO4K_PAN_ID equ 8 +%macro GO4K_PAN 1 +%ifdef GO4K_USE_PAN + db %1 +%endif +%endmacro +%define PANNING(val) val +struc go4kPAN_val +%ifdef GO4K_USE_PAN + .panning resd 1 +%endif + .size +endstruc +struc go4kPAN_wrk +;// modulation targets + .pm resd 1 + .size +endstruc +; //---------------------------------------------------------------------------------------- +; // OUT structs +; //---------------------------------------------------------------------------------------- +GO4K_OUT_ID equ 9 +%macro GO4K_OUT 2 + db %1 +%ifdef GO4K_USE_GLOBAL_DLL + db %2 +%endif +%endmacro +%define AUXSEND(val) val +struc go4kOUT_val + .gain resd 1 +%ifdef GO4K_USE_GLOBAL_DLL + .auxsend resd 1 +%endif + .size +endstruc +struc go4kOUT_wrk +;// modulation targets + .am resd 1 + .gm resd 1 + .size +endstruc +; //---------------------------------------------------------------------------------------- +; // ACC structs (this is for the synth def only) +; //---------------------------------------------------------------------------------------- +GO4K_ACC_ID equ 10 +%macro GO4K_ACC 1 + db %1 +%endmacro +%define OUTPUT 0 +%define AUX 8 +%define ACCTYPE(val) val +struc go4kACC_val + .acctype resd 1 + .size +endstruc +struc go4kACC_wrk + .size +endstruc +%ifdef GO4K_USE_FLD +; //---------------------------------------------------------------------------------------- +; // FLD structs +; //---------------------------------------------------------------------------------------- +GO4K_FLD_ID equ 11 +%macro GO4K_FLD 1 + db %1 +%endmacro +%define VALUE(val) val +struc go4kFLD_val + .value resd 1 + .size +endstruc +struc go4kFLD_wrk +;// modulation targets + .vm resd 1 + .size +endstruc +%endif +%ifdef GO4K_USE_GLITCH +; //---------------------------------------------------------------------------------------- +; // GLITCH structs +; //---------------------------------------------------------------------------------------- +GO4K_GLITCH_ID equ 12 +%macro GO4K_GLITCH 5 + db %1 + db %2 + db %3 + db %4 + db %5 +%endmacro +%define ACTIVE(val) val +%define SLICEFACTOR(val)val +%define PITCHFACTOR(val)val +%define SLICESIZE(val) val +struc go4kGLITCH_val +;// unit paramters + .active resd 1 + .dry resd 1 + .dsize resd 1 + .dpitch resd 1 + .slicesize resd 1 + .size +endstruc +struc go4kGLITCH_wrk +;// work variables + .index resd 1 + .store resd 1 + .slizesize resd 1 + .slicepitch resd 1 + .unused resd 1 +;// the delay buffer + .buffer resd MAX_DELAY + .size +endstruc +struc go4kGLITCH_wrk2 +;// modulation targets + .am resd 1 + .dm resd 1 + .sm resd 1 + .pm resd 1 + .size +endstruc +%endif +%ifdef GO4K_USE_FSTG +; //---------------------------------------------------------------------------------------- +; // FSTG structs +; //---------------------------------------------------------------------------------------- +GO4K_FSTG_ID equ 13 +%macro GO4K_FSTG 2 + db %1 + dw %2 +%endmacro +struc go4kFSTG_val + .amount resd 1 + .op1 resd 1 + .size +endstruc +struc go4kFSTG_wrk + .size +endstruc +%endif +; //---------------------------------------------------------------------------------------- +; // Voice struct +; //---------------------------------------------------------------------------------------- +struc go4k_instrument + .release resd 1 + .note resd 1 + .workspace resd MAX_UNITS*MAX_UNIT_SLOTS + .dlloutl resd 1 + .dlloutr resd 1 + .outl resd 1 + .outr resd 1 + .size +endstruc +; //---------------------------------------------------------------------------------------- +; // Synth struct +; //---------------------------------------------------------------------------------------- +struc go4k_synth + .instruments resb go4k_instrument.size * MAX_INSTRUMENTS * MAX_VOICES + .global resb go4k_instrument.size * MAX_VOICES + .size +endstruc +; //---------------------------------------------------------------------------------------- +; // Pattern Data, reduced by 967 patterns +; //---------------------------------------------------------------------------------------- +%ifdef USE_SECTIONS +section .g4kmuc1 data align=1 +%else +section .data align=1 +%endif +go4k_patterns + db 64, HLD, HLD, HLD, HLD, HLD, HLD, HLD, 0, 0, 0, 0, 0, 0, 0, 0, +go4k_patterns_end +; //---------------------------------------------------------------------------------------- +; // Pattern Index List +; //---------------------------------------------------------------------------------------- +%ifdef USE_SECTIONS +section .g4kmuc2 data align=1 +%else +section .data +%endif +go4k_pattern_lists +Instrument0List db 0, +go4k_pattern_lists_end +; //---------------------------------------------------------------------------------------- +; // Instrument Commands +; //---------------------------------------------------------------------------------------- +%ifdef USE_SECTIONS +section .g4kmuc3 data align=1 +%else +section .data +%endif +go4k_synth_instructions +GO4K_BEGIN_CMDDEF(Instrument0) + db GO4K_ENV_ID + db GO4K_PAN_ID + db GO4K_OUT_ID +GO4K_END_CMDDEF +;// global commands +GO4K_BEGIN_CMDDEF(Global) + db GO4K_ACC_ID + db GO4K_OUT_ID +GO4K_END_CMDDEF +go4k_synth_instructions_end +; //---------------------------------------------------------------------------------------- +; // Intrument Data +; //---------------------------------------------------------------------------------------- +%ifdef USE_SECTIONS +section .g4kmuc4 data align=1 +%else +section .data +%endif +go4k_synth_parameter_values +GO4K_BEGIN_PARAMDEF(Instrument0) + GO4K_ENV ATTAC(64),DECAY(64),SUSTAIN(64),RELEASE(80),GAIN(128) + GO4K_PAN PANNING(64) + GO4K_OUT GAIN(128), AUXSEND(0) +GO4K_END_PARAMDEF +;// global parameters +GO4K_BEGIN_PARAMDEF(Global) + GO4K_ACC ACCTYPE(OUTPUT) + GO4K_OUT GAIN(128), AUXSEND(0) +GO4K_END_PARAMDEF +go4k_synth_parameter_values_end +; //---------------------------------------------------------------------------------------- +; // Delay/Reverb Times +; //---------------------------------------------------------------------------------------- +%ifdef USE_SECTIONS +section .g4kmuc5 data align=1 +%else +section .data +%endif +%ifdef GO4K_USE_DLL +global _go4k_delay_times +_go4k_delay_times + dw 0 +%endif + +section .data + +global _test_name +_test_name db 'test_env', 0 ; null terminated string + +global _test_max_samples +_test_max_samples + dd MAX_SAMPLES + +%include "../src/4klang.inc" diff --git a/tests/test_env_expected.raw b/tests/test_env_expected.raw new file mode 100644 index 0000000000000000000000000000000000000000..105929a6b91e72bbd52738a6ff3fecdb904ed045 GIT binary patch literal 846720 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 z24VxTf!IK7AT|&ihz-OBVgs>(*g$L`HV_+#4a5dw1F?bFKx`m35F3aM#0Fvmv4Pk? zY#=re8;A|W24VxTf!IK7AT|&ihz-OBVgs>(*g$L`HV_+#4a5dw1F?bFKx`m35F3aM z#0Fvmv4Pk?Y#=re8;A|W24VxTf!IK7AT|&ihz-OBVgs>(*g$L`HV_+#4a5dw1F?bF zKx`m35F3aM#0Fvmv4Pk?Y#=re8;A|W24VxTf!IK7AT|&ihz-OBVgs>(*g$L`HV_+# z4a5dw1F?bFKx`m35F3aM#0Fvmv4Pk?Y#=re8;A|W24VxTf!IK7AT|&ihz-OBVgs>( z*g$L`HV_+#4a5dw1F?bFKx`m35F3aM#0Fvmv4Pk?Y#=re8;A|W24VxTf!IK7AT|&i zhz-OBVgs>(*g$L`HV_+#4a5dw1F?bFKx`m35F3aM#0Fvmv4Pk?Y#=re8;A|W24VxT zf!IK7AT|&ihz-OBVgs>(*g$L`HV_+#4a5dw1F?bFKx`m35F3aM#0Fvmv4Pk?Y#=re z8;A|W24VxTf!IK7AT|&ihz-OBVgs>(*g$L`HV_+#4a5dw1F?bFKx`m35F3aM#0Fvm zv4Pk?Y#=re8;A|W24VxTf!IK7AT|&ihz-OBVgs>(*g$L`HV_+#4a5dw1F?bFKx`m3 z5F3aM#0Fvmv4Pk?Y#=re8;A|W24VxTf!IK7AT|&ihz-OBVgs>(*g$L`HV_+#4a5dw z1F?bFKx`m35F3aM#0Fvmv4Pk?Y#=re8;A|W24VxTf!IK7AT|&ihz-OBVgs>(*g$L` zHV_+#4a5dw1F?bFKx`m35F3aM#0Fvmv4Pk?Y#=re8;A|W24VxTf!IK7AT|&ihz-OB zVgs>(*g$L`HV_+#4a5dw1F?bFKx`m35F3aM#0Fvmv4Pk?Y#=re8;A|W24VxTf!IK7 zAT|&ihz-OBVgs>(*g$L`HV_+#4a5dw1F?bFKx`m35F3aM#0Fvmv4Pk?Y#=re8;A|W z24VxTf!IK7AT|&ihz-OBVgs>(*g$L`HV_+#4a5dw1F?bFKx`m35F3aM#0Fvmv4Pk? zY#=re8;A|W24VxTf!IK7AT|&ihz-OBVgs>(*g$L`HV_+#4a5dw1F?bFKx`m35F3aM z#0Fvmv4Pk?Y#=re8;A|W24VxTf!IK7AT|&ihz-OBVgs>(*g$L`HV_+#4a5dw1F?bF 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 z$O2g)3uJ*TkOi_p7RUlwAPZ!HERY4VKo-aXSs)8!fh>>(vOpHd0$CsnWPvP@1+qXE z$O2g)3uJ*TkOi_p7RUlwAPZ!HERY4VKo-aXSs)8!fh>>(vOpHd0$CsnWPvP@1+qXE z$O2g)3uJ*TkOi_p7RUlwAPZ!HERY4VKo-aXSs)8!fh>>(vOpHd0$CsnWPvP@1+qXE z$O2g)3uJ*TkOi_p7RUlwAPZ!HERY4VKo-aXSs)8!fh>>(vOpHd0$CsnWPvP@1+qXE z$O2g)3uJ*TkOi_p7RUlwAPZ!HERY4VKo-aXSs)8!fh>>(vOpHd0$CsnWPvP@1+qXE z$O2g)3uJ*TkOi_p7RUlwAPZ!HERY4VKo-aXSs)8!fh>>(vOpHd0$CsnWPvP@1+qXE z$O2g)3uJ*TkOi_p7RUlwAPZ!HERY4VKo-aXSs)8!fh>>(vOpHd0$CsnWPvP@1+qXE z$O2g)3uJ*TkOi_p7RUlwAPZ!HERY4VKo-aXSs)8!fh>>(vOpHd0$CsnWPvP@1+qXE z$O2g)3uJ*TkOi_p7RUlwAPZ!HERY4VKo-aXSs)8!fh>>(vOpHd0$CsnWPvP@1+qXE z$O2g)3uJ*TkOi_p7RUlwAPZ!HERY4VKo-aXSs)8!fh>>(vOpHd0$CsnWPvP@1+qXE z$O2g)3uJ*TkOi_p7RUlwAPZ!HERY4VKo-aXSs)8!fh>>(vOpHd0$CsnWPvP@1+qXE z$O2g)3uJ*TkOi_p7RUlwAPZ!HERY4VKo-aXSs)8!fh>>(vOpHd0$CsnWPvP@1+qXE z$O2g)3uJ*TkOi_p7RUlwAPZ!HERY4VKo-aXSs)8!fh>>(vOpHd0$CsnWPvP@1+qXE z$O2g)3uJ*TkOi_p7RUlwAPZ!HERY4VKo-aXSs)8!fh>>(vOpHd0$CsnWPvP@1+qXE z$O2g)3uJ*TkOi_p7RUlwAPZ!HERY4VKo-aXSs)8!fh>>(vOpHd0$CsnWPvP@1+qXE z$O2g)3uJ*TkOi_p7RUlwAPZ!HERY4VKo-aXSs)8!fh>>(vOpHd0$CsnWPvP@1+qXE z$O2g)3uJ*TkOi_p7RUlwAPZ!HERY4VKo-aXSs)8!fh>>(vOpHd0$CsnWPvP@1+qXE z$O2g)3uJ*TkOi_p7RUlwAPZ!HERY4VKo-aXSs)8!fh>>(vOpHd0$CsnWPvP@1+qXE z$O2g)3uJ*TkOi_p7RUlwAPZ!HERY4VKo-aXSs)8!fh>>(vOpHd0$CsnWPvP@1+qXE z$O2g)3uJ*TkOi_p7RUlwAPZ!HERY4VKo-aXSs)8!fh>>(vOpHd0$CsnWPvP@1+qXE z$O2g)3uJ*TkOi_p7RUlwAPZ!HERY4VKo-aXSs)8!fh>>(vOpHd0$CsnWPvP@1+qXE z$O2g)3uJ*TkOi_p7RUlwAPZ!HERY4VKo-aXSs)8!fh>>(vOpHd0$CsnWPvP@1+qXE z$O2g)3uJ*TkOi_p7RUlwAPZ!HERY4VKo-aXSs)8!fh>>(vOpHd0$CsnWPvP@1+qXE z$O2g)3uJ*TkOi_p7RUlwAPZ!HERY4VKo-aXSs)8!fh>>(vOpHd0$CsnWPvP@1+qXE M$O2j5|E~r9A9zf(wg3PC literal 0 HcmV?d00001 diff --git a/tests/test_renderer.c b/tests/test_renderer.c new file mode 100644 index 0000000..97a78c6 --- /dev/null +++ b/tests/test_renderer.c @@ -0,0 +1,77 @@ +#include +#include + +extern void __stdcall _4klang_render(); +extern int test_max_samples; +extern char test_name[]; + +int main(int argc, char* argv[]) { + FILE* f; + float* buf; + char filename[256]; + int n; + float v; + int retval; + + buf = (float*)malloc(test_max_samples * 2 * sizeof(float)); + + if (buf == NULL) { + printf("Could not allocate buffer\n"); + return 1; + } + + _4klang_render(buf); + + snprintf(filename, sizeof filename, "%s%s", test_name, "_expected.raw"); + + f = fopen(filename, "rb"); + + if (f == NULL) { + printf("No expected waveform found!\n"); + retval = 1; + goto end; + } + + n = 0; + while (1) { + fread((void*)(&v), sizeof(v), 1, f); + if (feof(f)) { + if (n == test_max_samples * 2) { + retval = 0; + } + else { + printf("4klang rendered longer wave than expected\n"); + retval = 1; + } + break; + } + if (n >= test_max_samples * 2) { + printf("4klang rendered shorter wave than expected\n"); + retval = 1; + break; + } + if (buf[n] != v) { + printf("4klang rendered different wave than expected\n"); + retval = 1; + break; + } + ++n; + } +end: + + if (f != 0) { + fclose(f); + f = 0; + } + + snprintf(filename, sizeof filename, "%s%s", test_name, "_got.raw"); + f = fopen(filename, "wb"); + fwrite((void*)buf, sizeof(*buf), 2 * test_max_samples, f); + fclose(f); + + if (buf != 0) { + free(buf); + buf = 0; + } + return retval; +} \ No newline at end of file