mirror of
https://github.com/vsariola/sointu.git
synced 2025-06-04 01:28:45 -04:00
Implement compressor.
This commit is contained in:
parent
71a5a18257
commit
fc0ad4c011
11
README.md
11
README.md
@ -57,8 +57,8 @@ New features since fork
|
||||
the first thing actually implemented was a set of regression tests to avoid
|
||||
breaking everything beyond any hope of repair. Done, using CTest.
|
||||
- **New units**. Bit-crusher, gain, inverse gain, clip, modulate bpm
|
||||
(proper triplets!)... As always, if you don't use them, they won't be
|
||||
compiled into the code.
|
||||
(proper triplets!), compressor (can be used for side-chaining)... As
|
||||
always, if you don't use them, they won't be compiled into the code.
|
||||
- **Pattern length does not have to be a power of 2**.
|
||||
|
||||
Future goals
|
||||
@ -68,8 +68,11 @@ Future goals
|
||||
on CMake and compiles on Windows. Cross-platform NASM/YASM macros have been
|
||||
drafted and remain to be tested. Once the project is more mature, I will
|
||||
try compiling on other platforms.
|
||||
- **Even more opcodes**. At least: compressor (with side-chaining). Maybe
|
||||
also equalizer.
|
||||
- **Find a more general solution for skipping opcodes / early outs**. It's
|
||||
probably a new opcode "skip" that skips from the opcode to the next out in
|
||||
case the signal entering skip and the signal leaving out are both close to
|
||||
zero.
|
||||
- **Even more opcodes**. Maybe an equalizer? DC-offset removal?
|
||||
- **Support for 64-bit targets**.
|
||||
- **Browser-based GUI and MIDI instrument**. Modern browsers support WebMIDI,
|
||||
WebAudio and, most importantly, they are cross-platform and come installed
|
||||
|
@ -419,3 +419,56 @@ SECT_DATA(suconst)
|
||||
%endif
|
||||
|
||||
%endif ; DELAY_ID > -1
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; Compressor Tick
|
||||
;-------------------------------------------------------------------------------
|
||||
%if COMPRES_ID > -1
|
||||
|
||||
SECT_TEXT(sucompr)
|
||||
|
||||
EXPORT MANGLE_FUNC(su_op_compressor,0)
|
||||
fld st0 ; x x
|
||||
fmul st0, st0 ; x^2 x
|
||||
%ifdef INCLUDE_STEREO_COMPRES
|
||||
jnc su_op_compressor_mono
|
||||
fld st2 ; r l^2 l r
|
||||
fmul st0, st0 ; r^2 l^2 l r
|
||||
faddp st1, st0 ; r^2+l^2 l r
|
||||
call su_op_compressor_mono ; So, for stereo, we square both left & right and add them up
|
||||
fld st0 ; and return the computed gain two times, ready for MULP STEREO
|
||||
ret
|
||||
su_op_compressor_mono:
|
||||
%endif
|
||||
fld dword [WRK+su_compres_wrk.level] ; l x^2 x
|
||||
mov al,1 ; high bits are zero so this is ok. eax = 1 => release
|
||||
fucomi st0, st1 ; if l > x^2 // we're releasing
|
||||
jnb su_op_compressor_releasing
|
||||
xor eax, eax ; eax = 0 => attacking
|
||||
su_op_compressor_releasing:
|
||||
fsub st1, st0 ; l x^2-l x
|
||||
call su_env_map ; c l x^2-l x, c is either attack or release parameter mapped in a nonlinear way
|
||||
fmulp st2, st0 ; l c*(x^2-l) x
|
||||
faddp st1, st0 ; l+c*(x^2-l) x
|
||||
fst dword [WRK+su_compres_wrk.level] ; l'=l+c*(x^2-l), l' x
|
||||
fld dword [edx+su_compres_ports.threshold] ; t l' x
|
||||
fmul st0, st0 ; t*t
|
||||
fucomi st0, st1 ; if threshold < l'
|
||||
jb su_op_compressor_compress ; then we actually do compression
|
||||
fstp st0 ; l' x
|
||||
fstp st0 ; x
|
||||
fld1 ; 1 x
|
||||
ret ; return unity gain when we are below threshold
|
||||
su_op_compressor_compress: ; l' x
|
||||
fdivrp st1, st0 ; t*t/l' x
|
||||
fld dword [edx+su_compres_ports.ratio] ; r t*t/l' x
|
||||
fmul dword [c_0_5] ; p=r/2 t*t/l' x
|
||||
fxch ; t*t/l' p x
|
||||
fyl2x ; p*log2(t*t/l') x
|
||||
jmp MANGLE_FUNC(su_power,0) ; 2^(p*log2(t*t/l')) x
|
||||
; tail call ; Equal to:
|
||||
; (t*t/l')^p x
|
||||
; if ratio is at minimum => p=0 => 1 x
|
||||
; if ratio is at maximum => p=0.5 => t/x => t/x*x=t
|
||||
|
||||
%endif ; COMPRES_ID > -1
|
@ -344,3 +344,47 @@ struc su_delayline_wrk
|
||||
.buffer resd MAX_DELAY
|
||||
.size
|
||||
endstruc
|
||||
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; COMPRES effect related defines
|
||||
;-------------------------------------------------------------------------------
|
||||
%assign COMPRES_ID -1
|
||||
|
||||
%macro USE_COMPRES 0
|
||||
%if COMPRES_ID == -1
|
||||
%assign COMPRES_ID CUR_ID
|
||||
%assign CUR_ID CUR_ID + 2
|
||||
%xdefine OPCODES OPCODES MANGLE_FUNC(su_op_compressor,0),
|
||||
%xdefine NUMPARAMS NUMPARAMS 4,
|
||||
%endif
|
||||
%endmacro
|
||||
|
||||
%macro SU_COMPRES 5
|
||||
db %2
|
||||
db %3
|
||||
db %4
|
||||
db %5
|
||||
USE_COMPRES
|
||||
%xdefine CMDS CMDS COMPRES_ID + %1,
|
||||
%if %1 == STEREO
|
||||
%define INCLUDE_STEREO_COMPRES
|
||||
%endif
|
||||
%endmacro
|
||||
|
||||
%define ATTAC(val) val
|
||||
%define RELEASE(val) val
|
||||
%define THRESHOLD(val) val
|
||||
%define RATIO(val) val
|
||||
|
||||
struc su_compres_ports
|
||||
.attack resd 1
|
||||
.release resd 1
|
||||
.threshold resd 1
|
||||
.ratio resd 1
|
||||
.ports
|
||||
endstruc
|
||||
|
||||
struc su_compres_wrk
|
||||
.level resd 1
|
||||
endstruc
|
@ -152,7 +152,7 @@ su_transform_values_out:
|
||||
;-------------------------------------------------------------------------------
|
||||
SECT_TEXT(supower)
|
||||
|
||||
%if ENVELOPE_ID > -1
|
||||
%if ENVELOPE_ID > -1 ; TODO: compressor also uses this, so should be compiled if either
|
||||
su_env_map:
|
||||
fld dword [edx+eax*4] ; x, where x is the parameter in the range 0-1
|
||||
fimul dword [c_24] ; 24*x
|
||||
|
@ -100,6 +100,9 @@ regression_test(test_clip_stereo CLIP)
|
||||
regression_test(test_crush "VCO_SINE;ENVELOPE;FOP_MULP;INVGAIN" CRUSH)
|
||||
regression_test(test_crush_stereo CRUSH)
|
||||
|
||||
regression_test(test_compressor "" COMPRESSOR)
|
||||
regression_test(test_compressor_stereo COMPRESSOR)
|
||||
|
||||
regression_test(test_filter_band "VCO_SINE;ENVELOPE;FOP_MULP")
|
||||
regression_test(test_filter_low "VCO_SINE;ENVELOPE;FOP_MULP")
|
||||
regression_test(test_filter_high "VCO_SINE;ENVELOPE;FOP_MULP")
|
||||
|
BIN
tests/expected_output/test_compressor.raw
Normal file
BIN
tests/expected_output/test_compressor.raw
Normal file
Binary file not shown.
BIN
tests/expected_output/test_compressor_stereo.raw
Normal file
BIN
tests/expected_output/test_compressor_stereo.raw
Normal file
Binary file not shown.
43
tests/test_compressor.asm
Normal file
43
tests/test_compressor.asm
Normal file
@ -0,0 +1,43 @@
|
||||
%define BPM 100
|
||||
%define USE_SECTIONS
|
||||
|
||||
%include "../src/sointu.inc"
|
||||
|
||||
SU_BEGIN_PATTERNS
|
||||
PATTERN 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 65, 65, 65, 65,
|
||||
PATTERN 76, 0, 0, 0, 0, 0, 0, 0, 76, 0, 0, 0, 0, 0, 0, 0,
|
||||
SU_END_PATTERNS
|
||||
|
||||
SU_BEGIN_TRACKS
|
||||
TRACK VOICES(1),0 ; a very silent voice
|
||||
TRACK VOICES(1),1 ; a loud one
|
||||
SU_END_TRACKS
|
||||
|
||||
SU_BEGIN_PATCH
|
||||
SU_BEGIN_INSTRUMENT VOICES(1) ; Instrument0
|
||||
SU_ENVELOPE MONO,ATTAC(64),DECAY(64),SUSTAIN(64),RELEASE(64),GAIN(16)
|
||||
SU_ENVELOPE MONO,ATTAC(64),DECAY(64),SUSTAIN(64),RELEASE(64),GAIN(16)
|
||||
SU_OSCILLAT MONO,TRANSPOSE(88),DETUNE(64),PHASE(0),COLOR(128),SHAPE(64),GAIN(128),FLAGS(TRISAW)
|
||||
SU_OSCILLAT MONO,TRANSPOSE(88),DETUNE(64),PHASE(0),COLOR(128),SHAPE(64),GAIN(128),FLAGS(TRISAW)
|
||||
SU_MULP STEREO
|
||||
SU_SEND MONO,AMOUNT(128),GLOBALPORT(2,0,receive,left) + SEND_POP
|
||||
SU_SEND MONO,AMOUNT(128),GLOBALPORT(2,0,receive,right) + SEND_POP
|
||||
SU_END_INSTRUMENT
|
||||
SU_BEGIN_INSTRUMENT VOICES(1) ; Instrument0
|
||||
SU_ENVELOPE MONO,ATTAC(64),DECAY(64),SUSTAIN(64),RELEASE(64),GAIN(128)
|
||||
SU_ENVELOPE MONO,ATTAC(64),DECAY(64),SUSTAIN(64),RELEASE(64),GAIN(128)
|
||||
SU_OSCILLAT MONO,TRANSPOSE(88),DETUNE(64),PHASE(0),COLOR(128),SHAPE(64),GAIN(128),FLAGS(SINE)
|
||||
SU_OSCILLAT MONO,TRANSPOSE(88),DETUNE(64),PHASE(0),COLOR(128),SHAPE(64),GAIN(128),FLAGS(SINE)
|
||||
SU_MULP STEREO
|
||||
SU_SEND MONO,AMOUNT(128),GLOBALPORT(2,0,receive,left) + SEND_POP
|
||||
SU_SEND MONO,AMOUNT(128),GLOBALPORT(2,0,receive,right) + SEND_POP
|
||||
SU_END_INSTRUMENT
|
||||
SU_BEGIN_INSTRUMENT VOICES(1) ; Global compressor effect
|
||||
SU_RECEIVE STEREO
|
||||
SU_COMPRES MONO,ATTAC(32),RELEASE(80),THRESHOLD(32),RATIO(64)
|
||||
SU_MULP MONO
|
||||
SU_OUT STEREO, GAIN(128)
|
||||
SU_END_INSTRUMENT
|
||||
SU_END_PATCH
|
||||
|
||||
%include "../src/sointu.asm"
|
43
tests/test_compressor_stereo.asm
Normal file
43
tests/test_compressor_stereo.asm
Normal file
@ -0,0 +1,43 @@
|
||||
%define BPM 100
|
||||
%define USE_SECTIONS
|
||||
|
||||
%include "../src/sointu.inc"
|
||||
|
||||
SU_BEGIN_PATTERNS
|
||||
PATTERN 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 65, 65, 65, 65,
|
||||
PATTERN 76, 0, 0, 0, 0, 0, 0, 0, 76, 0, 0, 0, 0, 0, 0, 0,
|
||||
SU_END_PATTERNS
|
||||
|
||||
SU_BEGIN_TRACKS
|
||||
TRACK VOICES(1),0 ; a very silent voice
|
||||
TRACK VOICES(1),1 ; a loud one
|
||||
SU_END_TRACKS
|
||||
|
||||
SU_BEGIN_PATCH
|
||||
SU_BEGIN_INSTRUMENT VOICES(1) ; Instrument0
|
||||
SU_ENVELOPE MONO,ATTAC(64),DECAY(64),SUSTAIN(64),RELEASE(64),GAIN(16)
|
||||
SU_ENVELOPE MONO,ATTAC(64),DECAY(64),SUSTAIN(64),RELEASE(64),GAIN(16)
|
||||
SU_OSCILLAT MONO,TRANSPOSE(88),DETUNE(64),PHASE(0),COLOR(128),SHAPE(64),GAIN(128),FLAGS(TRISAW)
|
||||
SU_OSCILLAT MONO,TRANSPOSE(88),DETUNE(64),PHASE(0),COLOR(128),SHAPE(64),GAIN(128),FLAGS(TRISAW)
|
||||
SU_MULP STEREO
|
||||
SU_SEND MONO,AMOUNT(128),GLOBALPORT(2,0,receive,left) + SEND_POP
|
||||
SU_SEND MONO,AMOUNT(128),GLOBALPORT(2,0,receive,right) + SEND_POP
|
||||
SU_END_INSTRUMENT
|
||||
SU_BEGIN_INSTRUMENT VOICES(1) ; Instrument0
|
||||
SU_ENVELOPE MONO,ATTAC(64),DECAY(64),SUSTAIN(64),RELEASE(64),GAIN(128)
|
||||
SU_ENVELOPE MONO,ATTAC(64),DECAY(64),SUSTAIN(64),RELEASE(64),GAIN(128)
|
||||
SU_OSCILLAT MONO,TRANSPOSE(88),DETUNE(64),PHASE(0),COLOR(128),SHAPE(64),GAIN(128),FLAGS(SINE)
|
||||
SU_OSCILLAT MONO,TRANSPOSE(88),DETUNE(64),PHASE(0),COLOR(128),SHAPE(64),GAIN(128),FLAGS(SINE)
|
||||
SU_MULP STEREO
|
||||
SU_SEND MONO,AMOUNT(128),GLOBALPORT(2,0,receive,left) + SEND_POP
|
||||
SU_SEND MONO,AMOUNT(128),GLOBALPORT(2,0,receive,right) + SEND_POP
|
||||
SU_END_INSTRUMENT
|
||||
SU_BEGIN_INSTRUMENT VOICES(1) ; Global compressor effect
|
||||
SU_RECEIVE STEREO
|
||||
SU_COMPRES STEREO,ATTAC(32),RELEASE(80),THRESHOLD(32),RATIO(64)
|
||||
SU_MULP STEREO
|
||||
SU_OUT STEREO, GAIN(128)
|
||||
SU_END_INSTRUMENT
|
||||
SU_END_PATCH
|
||||
|
||||
%include "../src/sointu.asm"
|
Loading…
x
Reference in New Issue
Block a user