sointu/include/sointu/header.inc

280 lines
7.9 KiB
PHP

%ifndef SOINTU_INC
%define SOINTU_INC
%macro EXPORT 1
global %1
%1:
%endmacro
%ifidn __OUTPUT_FORMAT__,win32
%define WINDOWS
%assign BITS 32
%define MANGLE_FUNC(f,n) _ %+ f %+ @ %+ n
%define MANGLE_DATA(d) _ %+ d
%endif
%ifidn __OUTPUT_FORMAT__,win64
%define WINDOWS
%assign BITS 64
%define MANGLE_FUNC(f,n) f
%define MANGLE_DATA(d) d
%endif
%ifidn __OUTPUT_FORMAT__,macho32
%define MACOS
%assign BITS 32
%endif
%ifidn __OUTPUT_FORMAT__,macho64
%define MACOS
%assign BITS 64
%endif
%ifidn __OUTPUT_FORMAT__,elf
%define LINUX
%assign BITS 32
%endif
%ifidn __OUTPUT_FORMAT__,elf64
%define LINUX
%assign BITS 64
%endif
%ifdef WINDOWS
; Windows has crinkler so one may put everything in custom sections to aid crinkler.
; Maybe mac users need it too
%ifndef DISABLE_SECTIONS
%define SECT_BSS(n) section . %+ n bss align=256 ; a high alignment on the uninitialized sections should compress better
%define SECT_DATA(n) section . %+ n data align=1
%define SECT_TEXT(n) section . %+ n code align=1
%else
%define SECT_BSS(n) section .bss align=256
%define SECT_DATA(n) section .data align=1
%define SECT_TEXT(n) section .code align=1
%endif
%elifdef MACOS
%define MANGLE_FUNC(f,n) _ %+ f
%define MANGLE_DATA(d) _ %+ d
; macho does not seem to support named sections, so DISABLE_SECTIONS
; is "always on" / ignored
%define SECT_BSS(n) section .bss align=256
%define SECT_DATA(n) section .data align=1
%define SECT_TEXT(n) section .text align=1
%else ; Linux, or hopefully something similar
%define MANGLE_FUNC(f,n) f
%define MANGLE_DATA(d) d
%ifndef DISABLE_SECTIONS
%define SECT_BSS(n) section .bss. %+ n nobits alloc noexec write align=256
%define SECT_DATA(n) section .data. %+ n progbits alloc noexec write align=1
%define SECT_TEXT(n) section .text. %+ n progbits alloc exec nowrite align=1
%else
%define SECT_BSS(n) section .bss. nobits alloc noexec write align=256
%define SECT_DATA(n) section .data. progbits alloc noexec write align=1
%define SECT_TEXT(n) section .text. progbits alloc exec nowrite align=1
%endif
%endif
%assign CUR_ID 2
%define CMDS ; CMDS is empty at first, no commands defined
%define OPCODES MANGLE_FUNC(su_op_advance,0),
%define NUMPARAMS 0,
%define SU_ADVANCE_ID 0
%define STEREO(val) val
section .text ; yasm throws section redeclaration warnings if strucs are defined without a plain .text section
%include "sointu/flowcontrol_header.inc"
%include "sointu/arithmetic_header.inc"
%include "sointu/effects_header.inc"
%include "sointu/sources_header.inc"
%include "sointu/sinks_header.inc"
;-------------------------------------------------------------------------------
; synth defines
;-------------------------------------------------------------------------------
%define MAX_DELAY 65536
%assign MAX_UNITS_SHIFT 6
%assign MAX_UNITS ((1 << MAX_UNITS_SHIFT)-1) ; this is carefully chosen to align su_unit to 2^n boundary
%define ABSOLUTE_MAX_VOICES 32
%ifndef SAMPLE_RATE
%define SAMPLE_RATE 44100
%endif
%define TOTAL_ROWS (MAX_PATTERNS*PATTERN_SIZE)
%define SAMPLES_PER_ROW (SAMPLE_RATE*4*60/(SU_BPM*16))
%macro BEGIN_SONG 5
%xdefine SU_BPM %1
%if %2 == 1
%define SU_OUTPUT_16BIT
%endif
%if %3 == 1
%define SU_CLIP_OUTPUT
%endif
%if %4 == 1
%define INCLUDE_DELAY_MODULATION
%endif
%xdefine SU_HOLDVALUE %5
%endmacro
%macro END_SONG 0
%include "sointu/footer.inc"
%endmacro
%define BPM(val) val
%define OUTPUT_16BIT(val) val
%define CLIP_OUTPUT(val) val
%define DELAY_MODULATION(val) val
%define HOLD(val) val
%macro BEGIN_PATCH 0
SECT_DATA(params)
EXPORT MANGLE_DATA(su_params)
%endmacro
%macro END_PATCH 0 ; After the patch is finished, saves the accumulated commands
SECT_DATA(sucomnds)
EXPORT MANGLE_DATA(su_commands)
db CMDS
%endmacro
%define POLYPHONY_BITMASK 0
%assign MAX_VOICES 0
%assign MAX_TRACKS 0
%macro BEGIN_INSTRUMENT 1
; increment MAX_VOICES equal to %1 and construct the POLYPHONY_BITMASK so that
; for every except the last, the bit is on
%rep %1-1
%assign POLYPHONY_BITMASK (POLYPHONY_BITMASK << 1) + 1
%assign MAX_VOICES MAX_VOICES + 1
%endrep
%assign POLYPHONY_BITMASK (POLYPHONY_BITMASK << 1)
%assign MAX_VOICES MAX_VOICES + 1 ; the last voice increment, without adding one bit to the mask
%if MAX_VOICES > 32
%error Error: cannot have more than 32 voices!
%endif
%if %1 > 1
%define INCLUDE_POLYPHONY
%endif
%endmacro
%define VOICES(val) val
%define TRACKS(val) val
%macro END_INSTRUMENT 0
%xdefine CMDS CMDS SU_ADVANCE_ID,
%endmacro
%assign PATTERN_LENGTH -1
%macro BEGIN_PATTERNS 0
SECT_DATA(supatrns)
EXPORT MANGLE_DATA(su_patterns)
%define USE_PLAYER
%endmacro
%define END_PATTERNS
%assign PATTERN_SIZE -1
%macro PATTERN 1-*
%rep %0
db %1
%rotate 1
%endrep
%if %0 >= 256
%error 'Pattern size should be < 256'
%endif
%if PATTERN_SIZE == -1
%assign PATTERN_SIZE %0
%else
%if %0 != PATTERN_SIZE
%error 'All patterns should have the same length!'
%endif
%endif
%endmacro
%macro BEGIN_TRACKS 0
SECT_DATA(sutracks)
EXPORT MANGLE_DATA(su_tracks)
%define USE_PLAYER
%endmacro
%assign MAX_PATTERNS -1
%assign MAX_TRACKS 0
%assign VOICETRACK_BITMASK 0
%assign VOICETRACK_COUNT 0
%macro TRACK 2-* ; first param number of voices, rest are the patterns
%rep %0-1
db %2
%rotate 1
%endrep
%rotate 1
%if MAX_PATTERNS == -1
%assign MAX_PATTERNS %0-1
%else
%if %0-1 != MAX_PATTERNS
%error 'All tracks should have same number of patterns!'
%endif
%endif
%assign MAX_TRACKS MAX_TRACKS + 1
%if MAX_TRACKS > 32
%error Error: cannot have more than 32 tracks!
%endif
; increment MAX_TRACKS equal to %2 and construct the CHORD_BITMASK so that
; for every track except the last track of an instrument, the bit is on
%rep %1-1
%assign VOICETRACK_BITMASK VOICETRACK_BITMASK + (1 << VOICETRACK_COUNT)
%assign VOICETRACK_COUNT VOICETRACK_COUNT + 1
%endrep
%assign VOICETRACK_COUNT VOICETRACK_COUNT + 1 ; the last voice increment, without adding bit mask
%if VOICETRACK_COUNT > 32
%error Error: cannot have more than a total of 32 voices assigned to tracks.
%endif
%if %1 > 1
%define INCLUDE_MULTIVOICE_TRACKS
%endif
%endmacro
%define END_TRACKS
;-------------------------------------------------------------------------------
; unit struct
;-------------------------------------------------------------------------------
struc su_unit
.state resd 8
.ports resd 8
.size:
endstruc
;-------------------------------------------------------------------------------
; voice struct
;-------------------------------------------------------------------------------
struc su_voice
.note resd 1
.release resd 1
.inputs resd 8
.reserved resd 6 ; this is done to so the whole voice is 2^n long, see polyphonic player
.workspace resb MAX_UNITS * su_unit.size
.size:
endstruc
;-------------------------------------------------------------------------------
; synthworkspace struct
;-------------------------------------------------------------------------------
struc su_synthworkspace
.curvoices resb 32 ; these are used by the multitrack player to store which voice is playing on which track
.left resd 1
.right resd 1
.aux resd 6 ; 3 auxiliary signals
.voices resb ABSOLUTE_MAX_VOICES * su_voice.size
.size:
endstruc
%endif ; SOINTU_INC