mirror of
https://github.com/vsariola/sointu.git
synced 2025-09-17 10:44:37 -04:00
Implement sample-based oscillators, with sample import from gm.dls.
This commit is contained in:
42
src/gmdls.asm
Normal file
42
src/gmdls.asm
Normal file
@ -0,0 +1,42 @@
|
||||
%ifdef INCLUDE_GMDLS
|
||||
|
||||
%define SAMPLE_TABLE_SIZE 3440660 ; size of gmdls
|
||||
|
||||
extern _OpenFile@12 ; requires windows
|
||||
extern _ReadFile@20 ; requires windows
|
||||
|
||||
SECT_TEXT(sugmdls)
|
||||
|
||||
su_gmdls_load:
|
||||
mov edi, MANGLE_DATA(su_sample_table)
|
||||
mov esi, su_gmdls_path1
|
||||
su_gmdls_pathloop:
|
||||
push 0 ; OF_READ
|
||||
push edi ; &ofstruct, blatantly reuse the sample table
|
||||
push esi ; path
|
||||
call _OpenFile@12 ; eax = OpenFile(path,&ofstruct,OF_READ)
|
||||
add esi, su_gmdls_path2 - su_gmdls_path1 ; if we ever get to third, then crash
|
||||
cmp eax, -1 ; eax == INVALID?
|
||||
je su_gmdls_pathloop
|
||||
push 0 ; NULL
|
||||
push edi ; &bytes_read, reusing sample table again; it does not matter that the first four bytes are trashed
|
||||
push SAMPLE_TABLE_SIZE ; number of bytes to read
|
||||
push edi ; here we actually pass the sample table to readfile
|
||||
push eax ; handle to file
|
||||
call _ReadFile@20 ; Readfile(handle,&su_sample_table,SAMPLE_TABLE_SIZE,&bytes_read,NULL)
|
||||
ret
|
||||
|
||||
SECT_DATA(sugmpath)
|
||||
|
||||
su_gmdls_path1:
|
||||
db 'drivers/gm.dls',0
|
||||
su_gmdls_path2:
|
||||
db 'drivers/etc/gm.dls',0
|
||||
|
||||
SECT_DATA(suconst)
|
||||
c_samplefreq_scaling dd 84.28074964676522 ; o = 0.000092696138, n = 72, f = 44100*o*2**(n/12), scaling = 22050/f <- so note 72 plays at the "normal rate"
|
||||
|
||||
SECT_BSS(susamtbl)
|
||||
EXPORT MANGLE_DATA(su_sample_table) resb SAMPLE_TABLE_SIZE ; size of gmdls.
|
||||
|
||||
%endif
|
@ -136,6 +136,13 @@ su_op_oscillat_normalized:
|
||||
fadd dword [WRK+su_osc_wrk.phase]
|
||||
fst dword [WRK+su_osc_wrk.phase]
|
||||
fadd dword [edx+su_osc_ports.phaseofs]
|
||||
%ifdef INCLUDE_SAMPLES
|
||||
test al, byte SAMPLE
|
||||
jz short su_op_oscillat_not_sample
|
||||
call su_oscillat_sample
|
||||
jmp su_op_oscillat_shaping ; skip the rest to avoid color phase normalization and colorloading
|
||||
su_op_oscillat_not_sample:
|
||||
%endif
|
||||
fld1
|
||||
fadd st1, st0
|
||||
fxch
|
||||
@ -168,6 +175,7 @@ su_op_oscillat_not_pulse:
|
||||
jmp su_op_oscillat_gain ; skip waveshaping as the shape parameter is reused for gateshigh
|
||||
su_op_oscillat_not_gate:
|
||||
%endif
|
||||
su_op_oscillat_shaping:
|
||||
; finally, shape the oscillator and apply gain
|
||||
fld dword [edx+su_osc_ports.shape]
|
||||
call su_waveshaper
|
||||
@ -285,6 +293,42 @@ SECT_DATA(suconst)
|
||||
|
||||
%endif
|
||||
|
||||
; SAMPLES
|
||||
%ifdef INCLUDE_SAMPLES
|
||||
|
||||
SECT_TEXT(suoscsam)
|
||||
|
||||
su_oscillat_sample: ; p
|
||||
pushad ; edx must be saved, eax & ecx if this is stereo osc
|
||||
push edx
|
||||
mov al, byte [VAL-4] ; reuse "color" as the sample number
|
||||
lea edi, [MANGLE_DATA(su_sample_offsets) + eax*8] ; edi points now to the sample table entry
|
||||
fmul dword [c_samplefreq_scaling] ; p*r
|
||||
fistp dword [esp]
|
||||
pop edx ; edx is now the sample number
|
||||
movzx ebx, word [edi + su_sample_offset.loopstart] ; ecx = loopstart
|
||||
sub edx, ebx ; if sample number < loop start
|
||||
jl su_oscillat_sample_not_looping ; then we're not looping yet
|
||||
mov eax, edx ; eax = sample number
|
||||
movzx ecx, word [edi + su_sample_offset.looplength] ; edi is now the loop length
|
||||
xor edx, edx ; div wants edx to be empty
|
||||
div ecx ; edx is now the remainder
|
||||
su_oscillat_sample_not_looping:
|
||||
add edx, ebx ; sampleno += loopstart
|
||||
add edx, dword [edi + su_sample_offset.start]
|
||||
fild word [MANGLE_DATA(su_sample_table) + edx*2]
|
||||
fdiv dword [c_32767]
|
||||
popad
|
||||
ret
|
||||
|
||||
SECT_DATA(suconst)
|
||||
%ifndef C_32767
|
||||
c_32767 dd 32767.0
|
||||
%define C_32767
|
||||
%endif
|
||||
|
||||
%endif
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; LOADVAL opcode
|
||||
;-------------------------------------------------------------------------------
|
||||
|
@ -64,6 +64,7 @@ endstruc
|
||||
%endif
|
||||
%endmacro
|
||||
|
||||
%define SAMPLE 0x80 ; in this case, all the rest of the bits is the sample index
|
||||
%define SINE 0x40
|
||||
%define TRISAW 0x20
|
||||
%define PULSE 0x10
|
||||
@ -95,6 +96,9 @@ endstruc
|
||||
%if (%8) & GATE == GATE
|
||||
%define INCLUDE_GATE
|
||||
%endif
|
||||
%if (%8) & SAMPLE == SAMPLE
|
||||
%define INCLUDE_SAMPLES
|
||||
%endif
|
||||
%endmacro
|
||||
|
||||
struc su_osc_ports
|
||||
@ -119,9 +123,39 @@ endstruc
|
||||
%define GATESLOW(val) val
|
||||
%define GATESHIGH(val) val
|
||||
%define COLOR(val) val
|
||||
%define SAMPLENO(val) val
|
||||
%define SHAPE(val) val
|
||||
%define FLAGS(val) val
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; Sample related defines
|
||||
;-------------------------------------------------------------------------------
|
||||
|
||||
%macro SU_BEGIN_SAMPLE_OFFSETS 0
|
||||
SECT_DATA(susamoff)
|
||||
|
||||
EXPORT MANGLE_DATA(su_sample_offsets)
|
||||
%endmacro
|
||||
|
||||
%macro SAMPLE_OFFSET 3
|
||||
dd %1
|
||||
dw %2
|
||||
dw %3
|
||||
%endmacro
|
||||
|
||||
%define START(val) val
|
||||
%define LOOPSTART(val) val
|
||||
%define LOOPLENGTH(val) val
|
||||
|
||||
%define SU_END_SAMPLE_OFFSETS
|
||||
|
||||
struc su_sample_offset ; length conveniently 8, so easy to index
|
||||
.start resd 1
|
||||
.loopstart resw 1
|
||||
.looplength resw 1
|
||||
.size
|
||||
endstruc
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; NOISE structs
|
||||
;-------------------------------------------------------------------------------
|
||||
|
@ -19,7 +19,10 @@ su_voicetrack_bitmask dd VOICETRACK_BITMASK; does the following voice bel
|
||||
SECT_DATA(suconst)
|
||||
|
||||
%ifdef SU_USE_16BIT_OUTPUT
|
||||
c_32767 dd 32767.0
|
||||
%ifndef C_32767
|
||||
c_32767 dd 32767.0
|
||||
%define C_32767
|
||||
%endif
|
||||
%endif
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
@ -86,6 +89,9 @@ SECT_TEXT(surender)
|
||||
|
||||
EXPORT MANGLE_FUNC(su_render,4) ; Stack: ptr
|
||||
pushad ; Stack: pushad ptr
|
||||
%ifdef INCLUDE_GMDLS
|
||||
call su_gmdls_load
|
||||
%endif
|
||||
xor eax, eax ; ecx is the current row
|
||||
su_render_rowloop: ; loop through every row in the song
|
||||
push eax ; Stack: row pushad ptr
|
||||
|
@ -191,3 +191,4 @@ EXPORT MANGLE_FUNC(su_power,0)
|
||||
%include "opcodes/effects.asm"
|
||||
%include "player.asm"
|
||||
%include "introspection.asm"
|
||||
%include "gmdls.asm"
|
||||
|
Reference in New Issue
Block a user