diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..877a99f --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,27 @@ +name: test JSFX + +on: [push, pull_request] + +jobs: + test: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + name: Check out repository code + with: + # Fetches all submodules recursively + submodules: 'recursive' + + - name: Compile EEL2 with NO_GFX + run: | + make -C WDL/WDL/eel2 NO_GFX=1 + + - name: Compile JSFX Plugins + run: | + # Add commands to compile your JSFX scripts + # Example: eel2compiler my_plugin.jsfx + + - name: Run Tests + run: | + test_eel.sh diff --git a/.gitignore b/.gitignore index 1ee5385..43d5d8a 100644 --- a/.gitignore +++ b/.gitignore @@ -360,3 +360,5 @@ MigrationBackup/ # Fody - auto-generated XML schema FodyWeavers.xsd + +*.test.eel2 \ No newline at end of file diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..d64636c --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "WDL"] + path = WDL + url = https://github.com/justinfrankel/WDL.git + ignore = all \ No newline at end of file diff --git a/test_eel.sh b/test_eel.sh new file mode 100755 index 0000000..37d5fbb --- /dev/null +++ b/test_eel.sh @@ -0,0 +1,29 @@ +cat testing_defines.eel2 > vocalrediso.test.eel2 +sed -r -e 's/^(desc|slider[0-9]+):.*|^@(init|slider|block|serialize|sample)//' \ + -e 's/\/\/DEBUGPRINT/printf/' \ + -e 's/\/\/IFTEST|\/\*IFTEST\{\*|\*\}IFTEST\*\///' \ + -e 's/\*IFNTEST\*|IFNTEST\{\*|\*\}IFNTEST//' \ + vocalrediso-jamesdsp.eel >> vocalrediso.test.eel2 +./WDL/WDL/eel2/loose_eel ./vocalrediso.test.eel2 + +##//DEBUGPRINT("HI"); +##//IFTEST code_here(); +##/*IFTEST{* +## more_code(); +##*}IFTEST*/ +##/*IFNTEST*/called_when_not_testing(); +##/*IFNTEST{*/ +## also_called_when_not_testing(); +##/*}IFNTEST*/ + +# will transform to + +##printf("HI"); +## code_here(); +## +## more_code(); +## +##//called_when_not_testing(); +##/*IFNTEST{*/ +## also_called_when_not_testing(); +##/*IFNTEST}*/ \ No newline at end of file diff --git a/testing_defines.eel2 b/testing_defines.eel2 new file mode 100644 index 0000000..7ca4fb6 --- /dev/null +++ b/testing_defines.eel2 @@ -0,0 +1,15 @@ +function assert_equal_exact(expected, actual, message) global() ( + (expected !== actual) ? printf("expected: %d, was: %d. %s\n", expected, actual, message) +); + +function assert_equal_exact(expected, actual) global() ( + assert_equal_exact(expected, actual, "values differ!") +); + +function assert_true(boolean, message) global() ( + (!boolean) ? printf("expected true, was false. %s\n", message) +); + +function assert_false(boolean, message) global() ( + boolean ? printf("expected false, was true. %s\n", message) +); diff --git a/vocalrediso-jamesdsp.eel b/vocalrediso-jamesdsp.eel index 2655a26..75ce5b5 100644 --- a/vocalrediso-jamesdsp.eel +++ b/vocalrediso-jamesdsp.eel @@ -37,6 +37,8 @@ slider10=1; slider11=1; slider12=0; +//IFTEST srate = 24000; + _free_memory = 0; function simple_alloc(amount) local(_free_memory_old) @@ -52,8 +54,9 @@ prev_fft_size = 0; function setup_stft_state(fft_size, first_time) ( //////////////////////// Setup block // This is called when playback starts, or when the FFT size is changed - memset(fft_buffer, 0.0, MAX_FFT_SIZE*2); - memset(output_buffer, 0.0, buffer_length*2); + memset(fft_buffer, 0, MAX_FFT_SIZE*2); + memset(output_buffer, 0, buffer_length*2); + memset(input_buffer, 0, buffer_length*2); //////////////////////// ); @@ -84,6 +87,7 @@ function process_stft_segment(fft_buffer, fft_size) local(fft_bin, left_real, le //////////////////////// Main STFT block // The 'meat' of the algorithm, the code in this block will most resemble the code from vocalrediso.ny + // first, apply vocal reduction algorithm only in the right bands fft_bin >= low_bin && fft_bin <= high_bin ? ( // get constants for this bin @@ -99,8 +103,8 @@ function process_stft_segment(fft_buffer, fft_size) local(fft_bin, left_real, le // calculate weight: truncate w1 to [0, 1] and apply strength, then take 1 - the result, and multiply // by 1 - the square of the difference between the two norm values divided by the sum of the two, moderated by strength * slider10 weight = (1 - min(1, max(0, w1)) ^ strength) * ( - 1 - (sqr(norm_left - norm_right)/sqr(norm_left + norm_right)) - ) ^ (slider10 / strength) / 2; + 1 - sqr(norm_left - norm_right)/sqr(norm_left + norm_right) + ) ^ (slider10 / strength) * 0.5; // find the c channel, the sum of the two complex numbers c_real = l_real_rotated + r_real_rotated; @@ -168,7 +172,7 @@ buffer_index = 0; input_buffer = simple_alloc(buffer_length*2); output_buffer = simple_alloc(buffer_length*2); -function window(r) local(s, s2, gaussian_width, x) ( +function window(r) ( // When squared, the Hann window adds up perfectly for overlap >= 4, so it's suitable for perfect reconstruction //(0.5 - 0.5*cos(r*2*$pi))/sqrt(0.375); // the MLT sine window also appears to add up correctly, with sigma = sqrt(2). @@ -199,6 +203,7 @@ freembuf(freemem); @slider +//IFTEST function slider_code() ( // convert low cut and high cut to bins every time a slider is changed low_bin = min(slider5, slider6) / srate * fft_size; high_bin = max(slider6, slider5) / srate * fft_size; @@ -236,10 +241,11 @@ loop(fft_size, band_index += 1; // next index ); +//IFTEST ); // slider_code() ( @sample - +//IFTEST function sample_code() ( input_buffer[buffer_index*2] = spl0; input_buffer[buffer_index*2 + 1] = spl1; @@ -287,7 +293,84 @@ output_index = buffer_index - fft_size; output_index < 0 ? output_index += buffer_length; spl0 = output_buffer[output_index*2]; spl1 = output_buffer[output_index*2 + 1]; + output_buffer[output_index*2] = 0; // clear the sample we just read output_buffer[output_index*2 + 1] = 0; buffer_index = (buffer_index + 1)%buffer_length; + +//IFTEST ); // function sample_code() ( + + +/*IFTEST{* // main test block +//DEBUGPRINT("SETUP: dry=100 wet=100\n"); +slider1 = slider2 = 100; +slider_code(); + +//DEBUGPRINT("Test 1:SAMPLE_0_0_TEST\n"); +// spl0=0 spl1=1 for buffer_length*2 samples +setup_stft_state(fft_size, 1); +spl0sum = 0; +spl1sum = 0; +loop(10, + spl0=0; + spl1=0; + sample_code(); + spl0sum += abs(spl0); + spl1sum += abs(spl1); +); +//DEBUGPRINT("spl0sum=%g, spl1sum=%g\n", spl0sum, spl1sum); + +//DEBUGPRINT("SAMPLE_0_0_TEST\n"); +// spl0=1 spl1=0 for buffer_length*2 samples +setup_stft_state(fft_size, 1); +spl0sum = 0; +spl1sum = 0; +loop(10, + spl0=1; + spl1=0; + sample_code(); + spl0sum += 1000000*abs(spl1); + spl1sum += 1000000*abs(spl0); +); +//DEBUGPRINT("spl0sum=%g, spl1sum=%g\n", spl0sum, spl1sum); + + +//DEBUGPRINT("SAMPLE_0_1_TEST\n"); +// spl0=0 spl1=1 for buffer_length*2 samples +setup_stft_state(fft_size, 1); +spl0sum = 0; +spl1sum = 0; +loop(buffer_length*8, + spl0=0; + spl1=1; + sample_code(); + spl0sum += 1000000*abs(spl0); + spl1sum += 1000000*abs(spl1); +); +//DEBUGPRINT("spl0sum=%g, spl1sum=%g\n", spl0sum, spl1sum); + +//DEBUGPRINT("SAMPLE_1_1_TEST\n"); +// spl0=1 spl1=0 for buffer_length*2 samples +setup_stft_state(fft_size, 1); +/*IFTEST{* +spl0sum = 0; +spl1sum = 0; +loop(buffer_length*8, + spl0=0; + spl1=1; + sample_code(); + spl0sum += 1000000*abs(spl1); + spl1sum += 1000000*abs(spl0); +); +//DEBUGPRINT("spl0sum=%g, spl1sum=%g\n", spl0sum, spl1sum); + +//DEBUGPRINT("Testing Completed Without Crashing!\n"); + +function exit(code) ( + code|0; +); + +atexit("exit(-1)"); + +*}IFTEST*/ // main test block diff --git a/vocalrediso.jsfx b/vocalrediso.jsfx index 79799f3..5d63e4b 100644 --- a/vocalrediso.jsfx +++ b/vocalrediso.jsfx @@ -44,8 +44,9 @@ prev_fft_size = 0; function setup_stft_state(fft_size, first_time) ( //////////////////////// Setup block // This is called when playback starts, or when the FFT size is changed - memset(fft_buffer, 0.0, MAX_FFT_SIZE*2); - memset(output_buffer, 0.0, buffer_length*2); + memset(fft_buffer, 0, MAX_FFT_SIZE*2); + memset(output_buffer, 0, buffer_length*2); + memset(input_buffer, 0, buffer_length*2); //////////////////////// ); @@ -76,7 +77,7 @@ function process_stft_segment(fft_buffer, fft_size) local(fft_bin, left_real, le //////////////////////// Main STFT block // The 'meat' of the algorithm, the code in this block will most resemble the code from vocalrediso.ny - // first, apply vocal reduction algorithm only in the right bands + // first, apply vocal reduction algorithm only in the right bands fft_bin >= low_bin && fft_bin <= high_bin ? ( // get constants for this bin strength = strength_buffer[fft_bin];