mirror of
https://github.com/vsariola/sointu.git
synced 2025-05-28 03:10:24 -04:00
Implement unison oscillators: multiple versions of slightly detuned oscillators that are added up to make a signal.
This commit is contained in:
parent
adc4a6e45f
commit
dc99157fbb
@ -73,6 +73,10 @@ New features since fork
|
||||
spare. See [this example](tests/test_oscillat_sample.asm), and this Python
|
||||
[script](scripts/parse_gmdls.py) parses the gm.dls file and dumps the
|
||||
sample offsets from it.
|
||||
- **Unison oscillators**. Multiple copies of the oscillator running sligthly
|
||||
detuned and added up to together. Great for trance leads (supersaw). Unison
|
||||
of up to 4, or 8 if you make stereo unison oscillator and add up both left
|
||||
and right channels. See [this example](tests/test_oscillat_unison.asm).
|
||||
|
||||
Future goals
|
||||
------------
|
||||
|
@ -101,24 +101,46 @@ su_op_noise_mono:
|
||||
SECT_TEXT(suoscill)
|
||||
|
||||
EXPORT MANGLE_FUNC(su_op_oscillat,0)
|
||||
lodsb ; load the flags
|
||||
lodsb ; load the flags
|
||||
fld dword [edx+su_osc_ports.detune] ; e, where e is the detune [0,1]
|
||||
fsub dword [c_0_5] ; e-.5
|
||||
fadd st0, st0 ; d=2*e-.5, where d is the detune [-1,1]
|
||||
%ifdef INCLUDE_STEREO_OSCILLAT
|
||||
jnc su_op_oscillat_mono
|
||||
add WRK, 4
|
||||
call su_op_oscillat_mono
|
||||
fld1 ; invert the detune for second run for some stereo separation
|
||||
fld dword [edx+su_osc_ports.detune]
|
||||
fsubp st1
|
||||
fstp dword [edx+su_osc_ports.detune]
|
||||
sub WRK, 4
|
||||
su_op_oscillat_mono:
|
||||
fld st0 ; d d
|
||||
call su_op_oscillat_mono ; r d
|
||||
add WRK, 4 ; state vars: r1 l1 r2 l2 r3 l3 r4 l4, for the unison osc phases
|
||||
fxch ; d r
|
||||
fchs ; -d r, negate the detune for second round
|
||||
su_op_oscillat_mono:
|
||||
%endif
|
||||
%ifdef INCLUDE_UNISONS
|
||||
pushad ; push eax, WRK, WRK would suffice but this is shorter
|
||||
fldz ; 0 d
|
||||
fxch ; d a=0, "accumulated signal"
|
||||
su_op_oscillat_unison_loop:
|
||||
fst dword [esp] ; save the current detune, d. We could keep it in fpu stack but it was getting big.
|
||||
call su_op_oscillat_single ; s a
|
||||
faddp st1, st0 ; a+=s
|
||||
test al, UNISON4
|
||||
je su_op_oscillat_unison_out
|
||||
add WRK, 8
|
||||
fld dword [edx+su_osc_ports.phaseofs] ; p s
|
||||
fadd dword [c_i12] ; p s, add some little phase offset to unison oscillators so they don't start in sync
|
||||
fstp dword [edx+su_osc_ports.phaseofs] ; s note that this changes the phase for second, possible stereo run. That's probably ok
|
||||
fld dword [esp] ; d s
|
||||
fmul dword [c_0_5] ; .5*d s // negate and halve the detune of each oscillator
|
||||
fchs ; -.5*d s // negate and halve the detune of each oscillator
|
||||
dec eax
|
||||
jmp short su_op_oscillat_unison_loop
|
||||
su_op_oscillat_unison_out:
|
||||
popad ; similarly, pop WRK, WRK, eax would suffice
|
||||
ret
|
||||
su_op_oscillat_single:
|
||||
%endif
|
||||
fld dword [edx+su_osc_ports.transpose]
|
||||
fsub dword [c_0_5]
|
||||
fdiv dword [c_i128]
|
||||
fld dword [edx+su_osc_ports.detune]
|
||||
fsub dword [c_0_5]
|
||||
fadd st0
|
||||
faddp st1
|
||||
test al, byte LFO
|
||||
jnz su_op_oscillat_skipnote
|
||||
|
@ -64,12 +64,15 @@ endstruc
|
||||
%endif
|
||||
%endmacro
|
||||
|
||||
%define SAMPLE 0x80 ; in this case, all the rest of the bits is the sample index
|
||||
%define SAMPLE 0x80
|
||||
%define SINE 0x40
|
||||
%define TRISAW 0x20
|
||||
%define PULSE 0x10
|
||||
%define LFO 0x08
|
||||
%define GATE 0x04
|
||||
%define UNISON2 0x01
|
||||
%define UNISON3 0x02 ; Warning, UNISON3 and UNISON4 do not work with gate at the moment, as they use the same state variable
|
||||
%define UNISON4 0x03
|
||||
|
||||
%macro SU_OSCILLAT 8
|
||||
db %2
|
||||
@ -99,6 +102,9 @@ endstruc
|
||||
%if (%8) & SAMPLE == SAMPLE
|
||||
%define INCLUDE_SAMPLES
|
||||
%endif
|
||||
%if (%8) & UNISON4 > 0
|
||||
%define INCLUDE_UNISONS
|
||||
%endif
|
||||
%endmacro
|
||||
|
||||
struc su_osc_ports
|
||||
@ -113,7 +119,7 @@ endstruc
|
||||
|
||||
struc su_osc_wrk
|
||||
.phase resd 1
|
||||
.gatestate resd 1
|
||||
.gatestate equ 16 ; we put is late so only UNISON3 and UNISON4 are unusable with gate
|
||||
.size
|
||||
endstruc
|
||||
|
||||
|
@ -80,6 +80,8 @@ regression_test(test_oscillat_gate ENVELOPE)
|
||||
regression_test(test_oscillat_stereo ENVELOPE)
|
||||
regression_test(test_oscillat_sample ENVELOPE)
|
||||
regression_test(test_oscillat_sample_stereo ENVELOPE)
|
||||
regression_test(test_oscillat_unison ENVELOPE)
|
||||
regression_test(test_oscillat_unison_stereo ENVELOPE)
|
||||
regression_test(test_oscillat_lfo "ENVELOPE;VCO_SINE;VCO_PULSE;FOP_MULP2")
|
||||
regression_test(test_oscillat_transposemod "VCO_SINE;ENVELOPE;FOP_MULP;FOP_PUSH;SEND")
|
||||
regression_test(test_oscillat_detunemod "VCO_SINE;ENVELOPE;FOP_MULP;FOP_PUSH;SEND")
|
||||
|
BIN
tests/expected_output/test_oscillat_unison.raw
Normal file
BIN
tests/expected_output/test_oscillat_unison.raw
Normal file
Binary file not shown.
BIN
tests/expected_output/test_oscillat_unison_stereo.raw
Normal file
BIN
tests/expected_output/test_oscillat_unison_stereo.raw
Normal file
Binary file not shown.
24
tests/test_oscillat_unison.asm
Normal file
24
tests/test_oscillat_unison.asm
Normal file
@ -0,0 +1,24 @@
|
||||
%define BPM 100
|
||||
%define USE_SECTIONS
|
||||
|
||||
%include "../src/sointu.inc"
|
||||
|
||||
SU_BEGIN_PATTERNS
|
||||
PATTERN 64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0,
|
||||
SU_END_PATTERNS
|
||||
|
||||
SU_BEGIN_TRACKS
|
||||
TRACK VOICES(1),0
|
||||
SU_END_TRACKS
|
||||
|
||||
SU_BEGIN_PATCH
|
||||
SU_BEGIN_INSTRUMENT VOICES(1) ; Instrument0
|
||||
SU_ENVELOPE MONO, ATTAC(32),DECAY(32),SUSTAIN(64),RELEASE(64),GAIN(128)
|
||||
SU_OSCILLAT MONO, TRANSPOSE(64),DETUNE(0),PHASE(64),COLOR(128),SHAPE(64),GAIN(32), FLAGS(TRISAW + UNISON4)
|
||||
SU_MULP MONO
|
||||
SU_PUSH MONO
|
||||
SU_OUT STEREO, GAIN(128)
|
||||
SU_END_INSTRUMENT
|
||||
SU_END_PATCH
|
||||
|
||||
%include "../src/sointu.asm"
|
23
tests/test_oscillat_unison_stereo.asm
Normal file
23
tests/test_oscillat_unison_stereo.asm
Normal file
@ -0,0 +1,23 @@
|
||||
%define BPM 100
|
||||
%define USE_SECTIONS
|
||||
|
||||
%include "../src/sointu.inc"
|
||||
|
||||
SU_BEGIN_PATTERNS
|
||||
PATTERN 64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0,
|
||||
SU_END_PATTERNS
|
||||
|
||||
SU_BEGIN_TRACKS
|
||||
TRACK VOICES(1),0
|
||||
SU_END_TRACKS
|
||||
|
||||
SU_BEGIN_PATCH
|
||||
SU_BEGIN_INSTRUMENT VOICES(1) ; Instrument0
|
||||
SU_ENVELOPE STEREO, ATTAC(32),DECAY(32),SUSTAIN(64),RELEASE(64),GAIN(128)
|
||||
SU_OSCILLAT STEREO, TRANSPOSE(64),DETUNE(0),PHASE(64),COLOR(128),SHAPE(64),GAIN(32), FLAGS(TRISAW + UNISON4)
|
||||
SU_MULP STEREO
|
||||
SU_OUT STEREO, GAIN(128)
|
||||
SU_END_INSTRUMENT
|
||||
SU_END_PATCH
|
||||
|
||||
%include "../src/sointu.asm"
|
Loading…
Reference in New Issue
Block a user