mirror of
https://github.com/vsariola/sointu.git
synced 2025-07-23 07:24:47 -04:00
feat: add the ability to use Sointu as a sync-tracker
There is a new "sync" opcode that saves the top-most signal every 256 samples to the new "syncBuffer" output. Additionally, you can enable saving the current fractional row as sync[0], avoiding calculating the beat in the shader, but also calculating the beat correctly when the beat is modulated.
This commit is contained in:
@ -21,3 +21,24 @@
|
||||
fstp dword [{{.WRK}}] ; save the remainder for future
|
||||
ret
|
||||
{{end}}
|
||||
|
||||
|
||||
{{- if or .RowSync (.HasOp "sync")}}
|
||||
;-------------------------------------------------------------------------------
|
||||
; SYNC opcode: save the stack top to sync buffer
|
||||
;-------------------------------------------------------------------------------
|
||||
{{.Func "su_op_sync" "Opcode"}}
|
||||
{{- if not .Library}}
|
||||
; TODO: syncs are NOPs when compiling as library, should figure out a way to
|
||||
; make them work when compiling to use the native track also
|
||||
mov {{.AX}}, [{{.Stack "GlobalTick"}}]
|
||||
test al, al
|
||||
jne su_op_sync_skip
|
||||
xchg {{.AX}}, [{{.Stack "SyncBufPtr"}}]
|
||||
fst dword [{{.AX}}]
|
||||
add {{.AX}}, 4
|
||||
xchg {{.AX}}, [{{.Stack "SyncBufPtr"}}]
|
||||
su_op_sync_skip:
|
||||
{{- end}}
|
||||
ret
|
||||
{{end}}
|
||||
|
@ -14,6 +14,14 @@
|
||||
;-------------------------------------------------------------------------------
|
||||
{{.Func "su_run_vm"}}
|
||||
{{- .PushRegs .CX "DelayWorkSpace" .DX "Synth" .COM "CommandStream" .WRK "Voice" .VAL "ValueStream" | indent 4}}
|
||||
{{- if .RowSync}}
|
||||
fild dword [{{.Stack "Sample"}}]
|
||||
{{.Int .Song.SamplesPerRow | .Prepare | indent 8}}
|
||||
fidiv dword [{{.Int .Song.SamplesPerRow | .Use}}]
|
||||
fiadd dword [{{.Stack "Row"}}]
|
||||
{{.Call "su_op_sync"}}
|
||||
fstp st0
|
||||
{{- end}}
|
||||
su_run_vm_loop: ; loop until all voices done
|
||||
movzx edi, byte [{{.COM}}] ; edi = command byte
|
||||
inc {{.COM}} ; move to next instruction
|
||||
|
@ -14,12 +14,22 @@ su_synth_obj:
|
||||
; the output buffer. Renders the compile time hard-coded song to the buffer.
|
||||
; Stack: output_ptr
|
||||
;-------------------------------------------------------------------------------
|
||||
{{- if or .RowSync (.HasOp "sync")}}
|
||||
{{.ExportFunc "su_render_song" "OutputBufPtr" "SyncBufPtr"}}
|
||||
{{- else}}
|
||||
{{.ExportFunc "su_render_song" "OutputBufPtr"}}
|
||||
{{- end}}
|
||||
{{- if .Amd64}}
|
||||
{{- if eq .OS "windows"}}
|
||||
{{- .PushRegs "rcx" "OutputBufPtr" "rdi" "NonVolatileRsi" "rsi" "NonVolatile" "rbx" "NonVolatileRbx" "rbp" "NonVolatileRbp" | indent 4}} ; rcx = ptr to buf. rdi,rsi,rbx,rbp nonvolatile
|
||||
{{- if or .RowSync (.HasOp "sync")}}
|
||||
{{- .PushRegs "rdx" "SyncBufPtr" | indent 4}}
|
||||
{{- end}}
|
||||
{{- else}} ; SystemV amd64 ABI, linux mac or hopefully something similar
|
||||
{{- .PushRegs "rdi" "OutputBufPtr" "rbx" "NonVolatileRbx" "rbp" "NonVolatileRbp" | indent 4}}
|
||||
{{- if or .RowSync (.HasOp "sync")}}
|
||||
{{- .PushRegs "rsi" "SyncBufPtr" | indent 4}}
|
||||
{{- end}}
|
||||
{{- end}}
|
||||
{{- else}}
|
||||
{{- .PushRegs | indent 4}}
|
||||
@ -68,6 +78,9 @@ su_render_sampleloop: ; loop through every sample in the row
|
||||
{{$.Pop $.AX}}
|
||||
{{- end}}
|
||||
{{- if .Amd64}}
|
||||
{{- if or .RowSync (.HasOp "sync")}}
|
||||
{{.Pop .AX}} ; pop the sync buf ptr away
|
||||
{{- end}}
|
||||
{{- if eq .OS "windows"}}
|
||||
; Windows64 ABI, rdi rsi rbx rbp non-volatile
|
||||
{{- .PopRegs "rcx" "rdi" "rsi" "rbx" "rbp" | indent 4}}
|
||||
@ -78,8 +91,12 @@ su_render_sampleloop: ; loop through every sample in the row
|
||||
ret
|
||||
{{- else}}
|
||||
{{- .PopRegs | indent 4}}
|
||||
{{- if or .RowSync (.HasOp "sync")}}
|
||||
ret 8
|
||||
{{- else}}
|
||||
ret 4
|
||||
{{- end}}
|
||||
{{- end}}
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; su_update_voices function: polyphonic & chord implementation
|
||||
|
@ -13,6 +13,15 @@
|
||||
#define SU_LENGTH_IN_ROWS (SU_LENGTH_IN_PATTERNS*SU_PATTERN_SIZE)
|
||||
#define SU_SAMPLES_PER_ROW (SU_SAMPLE_RATE*60/(SU_BPM*SU_ROWS_PER_BEAT))
|
||||
|
||||
{{- if or .RowSync (.HasOp "sync")}}
|
||||
{{- if .RowSync}}
|
||||
#define SU_NUMSYNCS {{add1 .Song.Patch.NumSyncs}}
|
||||
{{- else}}
|
||||
#define SU_NUMSYNCS {{.Song.Patch.NumSyncs}}
|
||||
{{- end}}
|
||||
#define SU_SYNCBUFFER_LENGTH ((SU_LENGTH_IN_SAMPLES+255)>>8)*SU_NUMSYNCS
|
||||
{{- end}}
|
||||
|
||||
#include <stdint.h>
|
||||
#if UINTPTR_MAX == 0xffffffff
|
||||
#if defined(__clang__) || defined(__GNUC__)
|
||||
@ -39,7 +48,12 @@ typedef float SUsample;
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
{{- if or .RowSync (.HasOp "sync")}}
|
||||
void SU_CALLCONV su_render_song(SUsample *buffer,float *syncBuffer);
|
||||
#define SU_SYNC
|
||||
{{- else}}
|
||||
void SU_CALLCONV su_render_song(SUsample *buffer);
|
||||
{{- end}}
|
||||
{{- if gt (.SampleOffsets | len) 0}}
|
||||
void SU_CALLCONV su_load_gmdls();
|
||||
#define SU_LOAD_GMDLS
|
||||
|
Reference in New Issue
Block a user