mirror of
https://github.com/vsariola/sointu.git
synced 2026-06-09 23:39:09 -04:00
Rewrote most of the synth to better support stereo signals and polyphony. VSTi removed as there is no plan to update the VSTi to support the new features.
The stereo opcode variants have bit 1 of the command stream set. The polyphony is split into two parts: 1) polyphony, meaning that voices reuse the same opcodes; 2) multitrack voices, meaning that a track triggers more than voice. They both can be flexible defined in any combinations: for example voice 1 and 2 can be triggered by track 1 and use instrument 1, and voice 3 by track 2/instrument 2 and voice 4 by track 3/instrument 2. This is achieved through the use of bitmasks: in the aforementioned example, bit 1 of su_voicetrack_bitmask would be set, meaning "the voice after voice #1 will be triggered by the same track". On the other hand, bits 1 and 3 of su_polyphony_bitmask would be set to indicate that "the voices after #1 and #3 will reuse the same instruments".
This commit is contained in:
1491
src/4klang.asm
1491
src/4klang.asm
File diff suppressed because it is too large
Load Diff
586
src/4klang.inc
586
src/4klang.inc
@@ -1,586 +0,0 @@
|
||||
%ifndef _4KLANG_INC
|
||||
%define _4KLANG_INC
|
||||
|
||||
; Following defines have to be defined before this include:
|
||||
; MAX_INSTRUMENTS e.g. %define MAX_INSTRUMENTS 10
|
||||
; BPM e.g. %define BPM 100
|
||||
; MAX_PATTERNS e.g. %define MAX_PATTERNS 1
|
||||
;
|
||||
; Optionally:
|
||||
; PATTERN_SIZE_SHIFT e.g. %define PATTERN_SIZE_SHIFT 4 <- this is the default
|
||||
|
||||
%macro EXPORT 1
|
||||
global %1
|
||||
%1
|
||||
%endmacro
|
||||
|
||||
%ifidn __OUTPUT_FORMAT__,win32
|
||||
; on win32, function f with n parameters is mangled as "_f@n"
|
||||
%define MANGLE_FUNC(f,n) _ %+ f %+ @ %+ n
|
||||
%define WIN_OR_MAC
|
||||
%endif
|
||||
|
||||
%ifidn __OUTPUT_FORMAT__,elf32
|
||||
; on linux, function f with n parameters is mangled as "f"
|
||||
%define MANGLE_FUNC(f,n) f
|
||||
%endif
|
||||
|
||||
%ifidn __OUTPUT_FORMAT__,macho32
|
||||
; on mac, function f with x parameters is mangled as "_f"
|
||||
%define MANGLE_FUNC(f,n) _f
|
||||
%define WIN_OR_MAC
|
||||
%endif
|
||||
|
||||
%ifdef WIN_OR_MAC
|
||||
; Windows has crinkler so one may USE_SECTIONS to put everything in custom sections to aid crinkler.
|
||||
; Maybe mac users need it too
|
||||
%ifdef USE_SECTIONS
|
||||
%define SECT_BSS(n) section . %+ n bss align=1
|
||||
%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=1
|
||||
%define SECT_DATA(n) section .data align=1
|
||||
%define SECT_TEXT(n) section .code align=1
|
||||
%endif
|
||||
; On windows and mac, data label d is mangled as "_d"
|
||||
%define MANGLE_DATA(d) _ %+ d
|
||||
%else
|
||||
; Linux
|
||||
%ifdef USE_SECTIONS
|
||||
%define SECT_BSS(n) section .bss. %+ n nobits alloc noexec write align=1
|
||||
%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=1
|
||||
%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
|
||||
; On linux, data label d is mangled as "d"
|
||||
%define MANGLE_DATA(d) d
|
||||
%endif
|
||||
|
||||
%ifdef GO4K_USE_ALL
|
||||
; GO4K_USE_ALL is convenience way to enable almost all features of the synth, for vsti plugins and such which
|
||||
; do not have any size constraints. However, GO4K_USE_ALL should only enable features that absolutely do not
|
||||
; change the functioning of the synth in any way, just add features. Clipping, 16 bit output etc. should still
|
||||
; be enabled only whent they are actually needed
|
||||
|
||||
; Things that are NOT defined by GO4K_USE_ALL
|
||||
;%define GO4K_USE_16BIT_OUTPUT ; // removing this will output to 32bit floating point buffer
|
||||
;%define GO4K_USE_GROOVE_PATTERN ; // removing this skips groove pattern code
|
||||
;%define GO4K_USE_ENVELOPE_RECORDINGS ; // removing this skips envelope recording code
|
||||
;%define GO4K_USE_NOTE_RECORDINGS ; // removing this skips note recording code
|
||||
;%define GO4K_USE_UNDENORMALIZE ; // removing this skips denormalization code in the units
|
||||
;%define GO4K_CLIP_OUTPUT ; // removing this skips clipping code for the final output
|
||||
|
||||
%define GO4K_USE_DST ; // removing this will skip DST unit
|
||||
%define GO4K_USE_DLL ; // removing this will skip DLL unit
|
||||
%define GO4K_USE_PAN ; // removing this will skip PAN unit
|
||||
%define GO4K_USE_GLOBAL_DLL ; // removing this will skip global dll processing
|
||||
%define GO4K_USE_FSTG ; // removing this will skip global store unit
|
||||
%define GO4K_USE_FLD ; // removing this will skip float load unit
|
||||
%define GO4K_USE_GLITCH ; // removing this will skip GLITCH unit
|
||||
%define GO4K_USE_ENV_CHECK ; // removing this skips checks if processing is needed
|
||||
%define GO4K_USE_VCO_CHECK ; // removing this skips checks if processing is needed
|
||||
%define GO4K_USE_VCO_PHASE_OFFSET ; // removing this will skip initial phase offset code
|
||||
%define GO4K_USE_VCO_SHAPE ; // removing this skips waveshaping code
|
||||
%define GO4K_USE_VCO_GATE ; // removing this skips gate code
|
||||
%define GO4K_USE_VCO_MOD_FM ; // removing this skips frequency modulation code
|
||||
%define GO4K_USE_VCO_MOD_DM ; // removing this skips detune modulation code
|
||||
%define GO4K_USE_VCO_STEREO ; // removing this skips stereo code
|
||||
%define GO4K_USE_VCF_CHECK ; // removing this skips checks if processing is needed
|
||||
%define GO4K_USE_VCF_HIGH ; // removing this skips code for high output
|
||||
%define GO4K_USE_VCF_BAND ; // removing this skips code for band output
|
||||
%define GO4K_USE_VCF_PEAK ; // removing this skips code for peak output
|
||||
%define GO4K_USE_VCF_STEREO ; // removing this skips code for stereo filter output
|
||||
%define GO4K_USE_DST_CHECK ; // removing this skips checks if processing is needed
|
||||
%define GO4K_USE_DST_SH ; // removing this skips sample and hold code
|
||||
%define GO4K_USE_DST_STEREO ; // removing this skips stereo processing
|
||||
%define GO4K_USE_DLL_NOTE_SYNC ; // removing this will skip delay length adjusting code (karplus strong)
|
||||
%define GO4K_USE_DLL_CHORUS ; // removing this will skip delay chorus/flanger code
|
||||
%define GO4K_USE_DLL_CHORUS_CLAMP ; // removing this will skip chorus lfo phase clamping
|
||||
%define GO4K_USE_DLL_DAMP ; // removing this will skip dll damping code
|
||||
%define GO4K_USE_DLL_DC_FILTER ; // removing this will skip dll dc offset removal code
|
||||
%define GO4K_USE_FSTG_CHECK ; // removing this skips checks if processing is needed
|
||||
%define GO4K_USE_WAVESHAPER_CLIP ; // removing this will skip clipping code
|
||||
%endif
|
||||
|
||||
%ifdef GO4K_USE_VCO_SHAPE
|
||||
%define INCLUDE_WAVESHAPER
|
||||
%endif
|
||||
%ifdef GO4K_USE_DST
|
||||
%define INCLUDE_WAVESHAPER
|
||||
%endif
|
||||
|
||||
%ifdef GO4K_USE_ENVELOPE_RECORDINGS
|
||||
%define GO4K_USE_BUFFER_RECORDINGS
|
||||
%endif
|
||||
%ifdef GO4K_USE_NOTE_RECORDINGS
|
||||
%define GO4K_USE_BUFFER_RECORDINGS
|
||||
%endif
|
||||
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // synth defines
|
||||
; //----------------------------------------------------------------------------------------
|
||||
|
||||
%define MAX_DELAY 65536
|
||||
%define MAX_UNITS 64
|
||||
%define MAX_UNIT_SLOTS 16
|
||||
%define MAX_WORK_VARS 8
|
||||
|
||||
%ifndef SAMPLE_RATE
|
||||
%define SAMPLE_RATE 44100
|
||||
%endif
|
||||
|
||||
%ifndef MAX_VOICES
|
||||
%define MAX_VOICES 1
|
||||
%endif
|
||||
|
||||
%ifndef HLD
|
||||
%define HLD 1
|
||||
%endif
|
||||
|
||||
%ifndef PATTERN_SIZE_SHIFT
|
||||
%define PATTERN_SIZE_SHIFT 4
|
||||
%endif
|
||||
|
||||
%define PATTERN_SIZE (1 << PATTERN_SIZE_SHIFT)
|
||||
%define MAX_TICKS (MAX_PATTERNS*PATTERN_SIZE)
|
||||
%define SAMPLES_PER_TICK (SAMPLE_RATE*4*60/(BPM*16))
|
||||
%define DEF_LFO_NORMALIZE 0.000038
|
||||
%define MAX_SAMPLES (SAMPLES_PER_TICK*MAX_TICKS)
|
||||
|
||||
%define GO4K_BEGIN_CMDDEF(def_name)
|
||||
%define GO4K_END_CMDDEF db 0
|
||||
%define GO4K_BEGIN_PARAMDEF(def_name)
|
||||
%define GO4K_END_PARAMDEF
|
||||
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // ENV structs
|
||||
; //----------------------------------------------------------------------------------------
|
||||
GO4K_ENV_ID equ 1
|
||||
%macro GO4K_ENV 5
|
||||
db %1
|
||||
db %2
|
||||
db %3
|
||||
db %4
|
||||
db %5
|
||||
%endmacro
|
||||
%define ATTAC(val) val
|
||||
%define DECAY(val) val
|
||||
%define SUSTAIN(val) val
|
||||
%define RELEASE(val) val
|
||||
%define GAIN(val) val
|
||||
struc go4kENV_val
|
||||
;// unit paramters
|
||||
.attac resd 1
|
||||
.decay resd 1
|
||||
.sustain resd 1
|
||||
.release resd 1
|
||||
.gain resd 1
|
||||
.size
|
||||
endstruc
|
||||
struc go4kENV_wrk
|
||||
;// work variables
|
||||
.state resd 1
|
||||
.level resd 1
|
||||
.size
|
||||
endstruc
|
||||
%define ENV_STATE_ATTAC 0
|
||||
%define ENV_STATE_DECAY 1
|
||||
%define ENV_STATE_SUSTAIN 2
|
||||
%define ENV_STATE_RELEASE 3
|
||||
%define ENV_STATE_OFF 4
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // VCO structs
|
||||
; //----------------------------------------------------------------------------------------
|
||||
GO4K_VCO_ID equ 2
|
||||
|
||||
%macro GO4K_VCO 8
|
||||
db %1
|
||||
db %2
|
||||
%ifdef GO4K_USE_VCO_PHASE_OFFSET
|
||||
db %3
|
||||
%endif
|
||||
%ifdef GO4K_USE_VCO_GATE
|
||||
db %4
|
||||
%endif
|
||||
db %5
|
||||
%ifdef GO4K_USE_VCO_SHAPE
|
||||
db %6
|
||||
%endif
|
||||
db %7
|
||||
db %8
|
||||
%endmacro
|
||||
%define TRANSPOSE(val) val
|
||||
%define DETUNE(val) val
|
||||
%define PHASE(val) val
|
||||
%define GATES(val) val
|
||||
%define COLOR(val) val
|
||||
%define SHAPE(val) val
|
||||
%define FLAGS(val) val
|
||||
%define SINE 0x01
|
||||
%define TRISAW 0x02
|
||||
%define PULSE 0x04
|
||||
%define NOISE 0x08
|
||||
%define LFO 0x10
|
||||
%define GATE 0x20
|
||||
%define VCO_STEREO 0x40
|
||||
struc go4kVCO_val
|
||||
;// unit paramters
|
||||
.transpose resd 1
|
||||
.detune resd 1
|
||||
%ifdef GO4K_USE_VCO_PHASE_OFFSET
|
||||
.phaseofs resd 1
|
||||
%endif
|
||||
%ifdef GO4K_USE_VCO_GATE
|
||||
.gate resd 1
|
||||
%endif
|
||||
.color resd 1
|
||||
%ifdef GO4K_USE_VCO_SHAPE
|
||||
.shape resd 1
|
||||
%endif
|
||||
.gain resd 1
|
||||
.flags resd 1
|
||||
.size
|
||||
endstruc
|
||||
struc go4kVCO_wrk
|
||||
;// work variables
|
||||
.phase resd 1
|
||||
;// stero variables
|
||||
.phase2 resd 1
|
||||
.gatestate resd 1
|
||||
.detune_mod resd 1
|
||||
.freq_mod resd 1
|
||||
.size
|
||||
endstruc
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // VCF structs
|
||||
; //----------------------------------------------------------------------------------------
|
||||
GO4K_VCF_ID equ 3
|
||||
%macro GO4K_VCF 3
|
||||
db %1
|
||||
db %2
|
||||
db %3
|
||||
%endmacro
|
||||
%define LOWPASS 0x1
|
||||
%define HIGHPASS 0x2
|
||||
%define BANDPASS 0x4
|
||||
%define BANDSTOP 0x3
|
||||
%define ALLPASS 0x7
|
||||
%define PEAK 0x8
|
||||
%define STEREO 0x10
|
||||
%define FREQUENCY(val) val
|
||||
%define RESONANCE(val) val
|
||||
%define VCFTYPE(val) val
|
||||
struc go4kVCF_val
|
||||
;// unit paramters
|
||||
.freq resd 1
|
||||
.res resd 1
|
||||
.type resd 1
|
||||
.size
|
||||
endstruc
|
||||
struc go4kVCF_wrk
|
||||
;// work variables
|
||||
.low resd 1
|
||||
.high resd 1
|
||||
.band resd 1
|
||||
.freq_mod resd 1
|
||||
;// stereo variables
|
||||
.low2 resd 1
|
||||
.high2 resd 1
|
||||
.band2 resd 1
|
||||
.size
|
||||
endstruc
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // DST structs
|
||||
; //----------------------------------------------------------------------------------------
|
||||
GO4K_DST_ID equ 4
|
||||
%macro GO4K_DST 3
|
||||
db %1
|
||||
%ifdef GO4K_USE_DST_SH
|
||||
db %2
|
||||
%endif
|
||||
%ifdef GO4K_USE_DST_STEREO
|
||||
db %3
|
||||
%endif
|
||||
%endmacro
|
||||
%define DRIVE(val) val
|
||||
%define SNHFREQ(val) val
|
||||
%define FLAGS(val) val
|
||||
struc go4kDST_val
|
||||
;// unit paramters
|
||||
.drive resd 1
|
||||
%ifdef GO4K_USE_DST_SH
|
||||
.snhfreq resd 1
|
||||
%endif
|
||||
%ifdef GO4K_USE_DST_STEREO
|
||||
.flags resd 1
|
||||
%endif
|
||||
.size
|
||||
endstruc
|
||||
struc go4kDST_wrk
|
||||
;// work variables
|
||||
.out resd 1
|
||||
.snhphase resd 1
|
||||
;// stereo variables
|
||||
.out2 resd 1
|
||||
.size
|
||||
endstruc
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // DLL structs
|
||||
; //----------------------------------------------------------------------------------------
|
||||
GO4K_DLL_ID equ 5
|
||||
%macro GO4K_DLL 8
|
||||
db %1
|
||||
db %2
|
||||
db %3
|
||||
%ifdef GO4K_USE_DLL_DAMP
|
||||
db %4
|
||||
%endif
|
||||
%ifdef GO4K_USE_DLL_CHORUS
|
||||
db %5
|
||||
db %6
|
||||
%endif
|
||||
db %7
|
||||
db %8
|
||||
%endmacro
|
||||
%define PREGAIN(val) val
|
||||
%define DRY(val) val
|
||||
%define FEEDBACK(val) val
|
||||
%define DEPTH(val) val
|
||||
%define DAMP(val) val
|
||||
%define DELAY(val) val
|
||||
%define COUNT(val) val
|
||||
struc go4kDLL_val
|
||||
;// unit paramters
|
||||
.pregain resd 1
|
||||
.dry resd 1
|
||||
.feedback resd 1
|
||||
%ifdef GO4K_USE_DLL_DAMP
|
||||
.damp resd 1
|
||||
%endif
|
||||
%ifdef GO4K_USE_DLL_CHORUS
|
||||
.freq resd 1
|
||||
.depth resd 1
|
||||
%endif
|
||||
.delay resd 1
|
||||
.count resd 1
|
||||
.size
|
||||
endstruc
|
||||
struc go4kDLL_wrk
|
||||
;// work variables
|
||||
.index resd 1
|
||||
.store resd 1
|
||||
.dcin resd 1
|
||||
.dcout resd 1
|
||||
.phase resd 1
|
||||
;// the delay buffer
|
||||
.buffer resd MAX_DELAY
|
||||
.size
|
||||
endstruc
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // FOP structs
|
||||
; //----------------------------------------------------------------------------------------
|
||||
GO4K_FOP_ID equ 6
|
||||
%macro GO4K_FOP 1
|
||||
db %1
|
||||
%endmacro
|
||||
%define OP(val) val
|
||||
%define FOP_POP 0x1
|
||||
%define FOP_ADDP 0x2
|
||||
%define FOP_MULP 0x3
|
||||
%define FOP_PUSH 0x4
|
||||
%define FOP_XCH 0x5
|
||||
%define FOP_ADD 0x6
|
||||
%define FOP_MUL 0x7
|
||||
%define FOP_ADDP2 0x8
|
||||
%define FOP_LOADNOTE 0x9
|
||||
%define FOP_MULP2 0xa
|
||||
struc go4kFOP_val
|
||||
.flags resd 1
|
||||
.size
|
||||
endstruc
|
||||
struc go4kFOP_wrk
|
||||
.size
|
||||
endstruc
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // FST structs
|
||||
; //----------------------------------------------------------------------------------------
|
||||
GO4K_FST_ID equ 7
|
||||
%macro GO4K_FST 2
|
||||
db %1
|
||||
dw %2
|
||||
%endmacro
|
||||
%define AMOUNT(val) val
|
||||
%define VALUE_MOD(unit,unittype,slot,flags) unit*MAX_UNIT_SLOTS+go4k %+ unittype %+ _val. %+ slot /4+MAX_WORK_VARS+flags
|
||||
%define WRK_MOD(unit,unittype,slot,flags) unit*MAX_UNIT_SLOTS+go4k %+ unittype %+ _wrk. %+ slot /4+flags
|
||||
%define FST_SET 0x0000
|
||||
%define FST_ADD 0x4000
|
||||
%define FST_POP 0x8000
|
||||
struc go4kFST_val
|
||||
.amount resd 1
|
||||
.size
|
||||
endstruc
|
||||
struc go4kFST_wrk
|
||||
.size
|
||||
endstruc
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // PAN structs
|
||||
; //----------------------------------------------------------------------------------------
|
||||
GO4K_PAN_ID equ 8
|
||||
%macro GO4K_PAN 1
|
||||
%ifdef GO4K_USE_PAN
|
||||
db %1
|
||||
%endif
|
||||
%endmacro
|
||||
%define PANNING(val) val
|
||||
struc go4kPAN_val
|
||||
%ifdef GO4K_USE_PAN
|
||||
.panning resd 1
|
||||
%endif
|
||||
.size
|
||||
endstruc
|
||||
struc go4kPAN_wrk
|
||||
.size
|
||||
endstruc
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // OUT structs
|
||||
; //----------------------------------------------------------------------------------------
|
||||
GO4K_OUT_ID equ 9
|
||||
%macro GO4K_OUT 2
|
||||
db %1
|
||||
%ifdef GO4K_USE_GLOBAL_DLL
|
||||
db %2
|
||||
%endif
|
||||
%endmacro
|
||||
%define AUXSEND(val) val
|
||||
struc go4kOUT_val
|
||||
.gain resd 1
|
||||
%ifdef GO4K_USE_GLOBAL_DLL
|
||||
.auxsend resd 1
|
||||
%endif
|
||||
.size
|
||||
endstruc
|
||||
struc go4kOUT_wrk
|
||||
.size
|
||||
endstruc
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // ACC structs (this is for the synth def only)
|
||||
; //----------------------------------------------------------------------------------------
|
||||
GO4K_ACC_ID equ 10
|
||||
%macro GO4K_ACC 1
|
||||
db %1
|
||||
%endmacro
|
||||
%define OUTPUT 0
|
||||
%define AUX 8
|
||||
%define ACCTYPE(val) val
|
||||
struc go4kACC_val
|
||||
.acctype resd 1
|
||||
.size
|
||||
endstruc
|
||||
struc go4kACC_wrk
|
||||
.size
|
||||
endstruc
|
||||
%ifdef GO4K_USE_FLD
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // FLD structs
|
||||
; //----------------------------------------------------------------------------------------
|
||||
GO4K_FLD_ID equ 11
|
||||
%macro GO4K_FLD 1
|
||||
db %1
|
||||
%endmacro
|
||||
%define VALUE(val) val
|
||||
struc go4kFLD_val
|
||||
.value resd 1
|
||||
.size
|
||||
endstruc
|
||||
struc go4kFLD_wrk
|
||||
.size
|
||||
endstruc
|
||||
%endif
|
||||
%ifdef GO4K_USE_GLITCH
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // GLITCH structs
|
||||
; //----------------------------------------------------------------------------------------
|
||||
GO4K_GLITCH_ID equ 12
|
||||
%macro GO4K_GLITCH 5
|
||||
db %1
|
||||
db %2
|
||||
db %3
|
||||
db %4
|
||||
db %5
|
||||
%endmacro
|
||||
%define ACTIVE(val) val
|
||||
%define SLICEFACTOR(val)val
|
||||
%define PITCHFACTOR(val)val
|
||||
%define SLICESIZE(val) val
|
||||
struc go4kGLITCH_val
|
||||
;// unit paramters
|
||||
.active resd 1
|
||||
.dry resd 1
|
||||
.dsize resd 1
|
||||
.dpitch resd 1
|
||||
.slicesize resd 1
|
||||
.size
|
||||
endstruc
|
||||
struc go4kGLITCH_wrk
|
||||
;// work variables
|
||||
.index resd 1
|
||||
.store resd 1
|
||||
.slizesize resd 1
|
||||
.slicepitch resd 1
|
||||
.unused resd 1
|
||||
;// the delay buffer
|
||||
.buffer resd MAX_DELAY
|
||||
.size
|
||||
endstruc
|
||||
%endif
|
||||
%ifdef GO4K_USE_FSTG
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // FSTG structs
|
||||
; //----------------------------------------------------------------------------------------
|
||||
%ifdef GO4K_USE_GLITCH
|
||||
GO4K_FSTG_ID equ 13
|
||||
%else
|
||||
GO4K_FSTG_ID equ 12
|
||||
%endif
|
||||
%macro GO4K_FSTG 2
|
||||
db %1
|
||||
dw %2
|
||||
%endmacro
|
||||
|
||||
%define GLOBAL_VALUE_MOD(inst,unit,unittype,slot,flags) inst*go4k_instrument.size*MAX_VOICES/4 + unit*MAX_UNIT_SLOTS+go4k %+ unittype %+ _val. %+ slot /4+(go4k_instrument.workspace/4)+MAX_WORK_VARS+flags
|
||||
%define GLOBAL_WRK_MOD(inst,unit,unittype,slot,flags) inst*go4k_instrument.size*MAX_VOICES/4 + unit*MAX_UNIT_SLOTS+go4k %+ unittype %+ _wrk. %+ slot /4+(go4k_instrument.workspace/4)+flags
|
||||
struc go4kFSTG_val
|
||||
.amount resd 1
|
||||
.size
|
||||
endstruc
|
||||
struc go4kFSTG_wrk
|
||||
.size
|
||||
endstruc
|
||||
%endif
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // Voice struct
|
||||
; //----------------------------------------------------------------------------------------
|
||||
struc go4k_instrument
|
||||
.release resd 1
|
||||
.note resd 1
|
||||
.workspace resd MAX_UNITS*MAX_UNIT_SLOTS
|
||||
.dlloutl resd 1
|
||||
.dlloutr resd 1
|
||||
.outl resd 1
|
||||
.outr resd 1
|
||||
.size
|
||||
endstruc
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // Synth struct
|
||||
; //----------------------------------------------------------------------------------------
|
||||
struc go4k_synth
|
||||
.instruments resb go4k_instrument.size * MAX_INSTRUMENTS * MAX_VOICES
|
||||
.global resb go4k_instrument.size * MAX_VOICES
|
||||
.size
|
||||
endstruc
|
||||
|
||||
%endif ; _4KLANG_INC
|
||||
@@ -1 +0,0 @@
|
||||
add_subdirectory(vsti)
|
||||
12
src/introspection.asm
Normal file
12
src/introspection.asm
Normal file
@@ -0,0 +1,12 @@
|
||||
; Various compile time definitions exported
|
||||
SECT_DATA(introscn)
|
||||
|
||||
%ifdef SU_USE_16BIT_OUTPUT
|
||||
EXPORT MANGLE_DATA(su_use_16bit_output) dd 1
|
||||
%else
|
||||
EXPORT MANGLE_DATA(su_use_16bit_output) dd 0
|
||||
%endif
|
||||
|
||||
%ifdef MAX_SAMPLES
|
||||
EXPORT MANGLE_DATA(su_max_samples) dd MAX_SAMPLES
|
||||
%endif
|
||||
155
src/opcodes/arithmetic.asm
Normal file
155
src/opcodes/arithmetic.asm
Normal file
@@ -0,0 +1,155 @@
|
||||
SECT_TEXT(suarithm)
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; op_pop function: a -> (empty)
|
||||
; stereo: a b -> (empty)
|
||||
;-------------------------------------------------------------------------------
|
||||
%if POP_ID > -1
|
||||
|
||||
EXPORT MANGLE_FUNC(su_op_pop,0)
|
||||
%ifdef INCLUDE_STEREO_POP
|
||||
jnc su_op_pop_mono
|
||||
fstp st0
|
||||
su_op_pop_mono:
|
||||
%endif
|
||||
fstp st0
|
||||
ret
|
||||
|
||||
%endif
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; op_add function: a b -> a+b b
|
||||
; stereo: a b c d -> a+c b+d c d
|
||||
;-------------------------------------------------------------------------------
|
||||
%if ADD_ID > -1
|
||||
|
||||
EXPORT MANGLE_FUNC(su_op_add,0)
|
||||
%ifdef INCLUDE_STEREO_ADD
|
||||
jnc su_op_add_mono
|
||||
fadd st0, st2
|
||||
fxch
|
||||
fadd st0, st3
|
||||
fxch
|
||||
ret
|
||||
su_op_pop_mono:
|
||||
%endif
|
||||
fadd st1
|
||||
ret
|
||||
|
||||
%endif
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; op_addp function: a b -> a+b
|
||||
; stereo: a b c d -> a+c b+d
|
||||
;-------------------------------------------------------------------------------
|
||||
%if ADDP_ID > -1
|
||||
|
||||
EXPORT MANGLE_FUNC(su_op_addp,0)
|
||||
%ifdef INCLUDE_STEREO_ADDP
|
||||
jnc su_op_addp_mono
|
||||
faddp st2, st0
|
||||
faddp st2, st0
|
||||
ret
|
||||
su_op_addp_mono:
|
||||
%endif
|
||||
faddp st1, st0
|
||||
ret
|
||||
|
||||
%endif
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; op_loadnote function: (empty) -> n
|
||||
; stereo: (empty) -> n n
|
||||
; ecx should point to the workspace (slightly offset)
|
||||
;-------------------------------------------------------------------------------
|
||||
%if LOADNOTE_ID > -1
|
||||
|
||||
EXPORT MANGLE_FUNC(su_op_loadnote,0)
|
||||
%ifdef INCLUDE_STEREO_LOADNOTE
|
||||
jnc su_op_loadnote_mono
|
||||
call su_op_loadnote_mono
|
||||
su_op_loadnote_mono:
|
||||
%endif
|
||||
fild dword [ecx+su_unit.size-su_voice.workspace+su_voice.note]
|
||||
fmul dword [c_i128]
|
||||
ret
|
||||
|
||||
%endif
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; op_mul function: a b -> a*b a
|
||||
; stereo: a b c d -> a*c b*d c d
|
||||
;-------------------------------------------------------------------------------
|
||||
%if MUL_ID > -1
|
||||
|
||||
EXPORT MANGLE_FUNC(su_op_mul,0)
|
||||
%ifdef INCLUDE_STEREO_MUL
|
||||
jnc su_op_mul_mono
|
||||
fmul st0, st2
|
||||
fxch
|
||||
fadd st0, st3
|
||||
fxch
|
||||
ret
|
||||
su_op_mul_mono:
|
||||
%endif
|
||||
fmul st1
|
||||
ret
|
||||
|
||||
%endif
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; op_mulp function: a b -> a*b
|
||||
; stereo: a b c d -> a*c b*d
|
||||
;-------------------------------------------------------------------------------
|
||||
%if MULP_ID > -1
|
||||
|
||||
EXPORT MANGLE_FUNC(su_op_mulp,0)
|
||||
%ifdef INCLUDE_STEREO_MULP
|
||||
jnc su_op_mulp_mono
|
||||
fmulp st2, st0
|
||||
fmulp st2, st0
|
||||
ret
|
||||
su_op_mulp_mono:
|
||||
%endif
|
||||
fmulp st1
|
||||
ret
|
||||
|
||||
%endif
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; op_push function: a -> a a
|
||||
; stereo: a b -> a b a b
|
||||
;-------------------------------------------------------------------------------
|
||||
%if PUSH_ID > -1
|
||||
|
||||
EXPORT MANGLE_FUNC(su_op_push,0)
|
||||
%ifdef INCLUDE_STEREO_PUSH
|
||||
jnc su_op_push_mono
|
||||
fld st1
|
||||
fld st1
|
||||
ret
|
||||
su_op_push_mono:
|
||||
%endif
|
||||
fld st0
|
||||
ret
|
||||
|
||||
%endif
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; op_xch function: a b -> b a
|
||||
; stereo: a b c d -> c d a b
|
||||
;-------------------------------------------------------------------------------
|
||||
%if XCH_ID > -1
|
||||
|
||||
EXPORT MANGLE_FUNC(su_op_xch,0)
|
||||
%ifdef INCLUDE_STEREO_XCH
|
||||
jnc su_op_xch_mono
|
||||
fxch st0, st2 ; c b a d
|
||||
fxch st0, st1 ; b c a d
|
||||
fxch st0, st2 ; d c a b
|
||||
su_op_xch_mono:
|
||||
%endif
|
||||
fxch st0, st1
|
||||
ret
|
||||
|
||||
%endif
|
||||
168
src/opcodes/arithmetic.inc
Normal file
168
src/opcodes/arithmetic.inc
Normal file
@@ -0,0 +1,168 @@
|
||||
;-------------------------------------------------------------------------------
|
||||
; ADDP related defines
|
||||
;-------------------------------------------------------------------------------
|
||||
%assign ADDP_ID -1
|
||||
%macro USE_ADDP 0
|
||||
%if ADDP_ID == -1
|
||||
%assign ADDP_ID CUR_ID
|
||||
%assign CUR_ID CUR_ID + 2
|
||||
%xdefine OPCODES OPCODES MANGLE_FUNC(su_op_addp,0),
|
||||
%xdefine NUMPARAMS NUMPARAMS 0,
|
||||
%endif
|
||||
%endmacro
|
||||
|
||||
%macro SU_ADDP 1
|
||||
USE_ADDP
|
||||
%xdefine CMDS CMDS ADDP_ID + %1,
|
||||
%if %1 == STEREO
|
||||
%define INCLUDE_STEREO_ADDP
|
||||
%endif
|
||||
%endmacro
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; ADD related defines
|
||||
;-------------------------------------------------------------------------------
|
||||
%assign ADD_ID -1
|
||||
%macro USE_ADD 0
|
||||
%if ADD_ID == -1
|
||||
%assign ADD_ID CUR_ID
|
||||
%assign CUR_ID CUR_ID + 2
|
||||
%xdefine OPCODES OPCODES MANGLE_FUNC(su_op_add,0),
|
||||
%xdefine NUMPARAMS NUMPARAMS 0,
|
||||
%endif
|
||||
%endmacro
|
||||
|
||||
%assign ADD_ID -1
|
||||
%macro SU_ADD 1
|
||||
USE_ADD
|
||||
%xdefine CMDS CMDS ADD_ID + %1,
|
||||
%if %1 == STEREO
|
||||
%define INCLUDE_STEREO_ADD
|
||||
%endif
|
||||
%endmacro
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; POP related defines
|
||||
;-------------------------------------------------------------------------------
|
||||
%assign POP_ID -1
|
||||
%macro USE_POP 0
|
||||
%if POP_ID == -1
|
||||
%assign POP_ID CUR_ID
|
||||
%assign CUR_ID CUR_ID + 2
|
||||
%xdefine OPCODES OPCODES MANGLE_FUNC(su_op_pop,0),
|
||||
%xdefine NUMPARAMS NUMPARAMS 0,
|
||||
%endif
|
||||
%endmacro
|
||||
|
||||
%macro SU_POP 1
|
||||
USE_POP
|
||||
%xdefine CMDS CMDS POP_ID + %1,
|
||||
%if %1 == STEREO
|
||||
%define INCLUDE_STEREO_POP
|
||||
%endif
|
||||
%endmacro
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; LOADNOTE related defines
|
||||
;-------------------------------------------------------------------------------
|
||||
%assign LOADNOTE_ID -1
|
||||
%macro USE_LOADNOTE 0
|
||||
%if LOADNOTE_ID == -1
|
||||
%assign LOADNOTE_ID CUR_ID
|
||||
%assign CUR_ID CUR_ID + 2
|
||||
%xdefine OPCODES OPCODES MANGLE_FUNC(su_op_loadnote,0),
|
||||
%xdefine NUMPARAMS NUMPARAMS 0,
|
||||
%endif
|
||||
%endmacro
|
||||
|
||||
%macro SU_LOADNOTE 1
|
||||
USE_LOADNOTE
|
||||
%xdefine CMDS CMDS LOADNOTE_ID + %1,
|
||||
%if %1 == STEREO
|
||||
%define INCLUDE_STEREO_LOADNOTE
|
||||
%endif
|
||||
%endmacro
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; MUL related defines
|
||||
;-------------------------------------------------------------------------------
|
||||
%assign MUL_ID -1
|
||||
%macro USE_MUL 0
|
||||
%if MUL_ID == -1
|
||||
%assign MUL_ID CUR_ID
|
||||
%assign CUR_ID CUR_ID + 2
|
||||
%xdefine OPCODES OPCODES MANGLE_FUNC(su_op_mul,0),
|
||||
%xdefine NUMPARAMS NUMPARAMS 0,
|
||||
%endif
|
||||
%endmacro
|
||||
|
||||
%macro SU_MUL 1
|
||||
USE_MUL
|
||||
%xdefine CMDS CMDS MUL_ID + %1,
|
||||
%if %1 == STEREO
|
||||
%define INCLUDE_STEREO_MUL
|
||||
%endif
|
||||
%endmacro
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; MULP related defines
|
||||
;-------------------------------------------------------------------------------
|
||||
%assign MULP_ID -1
|
||||
%macro USE_MULP 0
|
||||
%if MULP_ID == -1
|
||||
%assign MULP_ID CUR_ID
|
||||
%assign CUR_ID CUR_ID + 2
|
||||
%xdefine OPCODES OPCODES MANGLE_FUNC(su_op_mulp,0),
|
||||
%xdefine NUMPARAMS NUMPARAMS 0,
|
||||
%endif
|
||||
%endmacro
|
||||
|
||||
%macro SU_MULP 1
|
||||
USE_MULP
|
||||
%xdefine CMDS CMDS MULP_ID + %1,
|
||||
%if %1 == STEREO
|
||||
%define INCLUDE_STEREO_MULP
|
||||
%endif
|
||||
%endmacro
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; PUSH related defines
|
||||
;-------------------------------------------------------------------------------
|
||||
%assign PUSH_ID -1
|
||||
%macro USE_PUSH 0
|
||||
%if PUSH_ID == -1
|
||||
%assign PUSH_ID CUR_ID
|
||||
%assign CUR_ID CUR_ID + 2
|
||||
%xdefine OPCODES OPCODES MANGLE_FUNC(su_op_push,0),
|
||||
%xdefine NUMPARAMS NUMPARAMS 0,
|
||||
%endif
|
||||
%endmacro
|
||||
|
||||
%macro SU_PUSH 1
|
||||
USE_PUSH
|
||||
%xdefine CMDS CMDS PUSH_ID + %1,
|
||||
%if %1 == STEREO
|
||||
%define INCLUDE_STEREO_PUSH
|
||||
%endif
|
||||
%endmacro
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; XCH related defines
|
||||
;-------------------------------------------------------------------------------
|
||||
%assign XCH_ID -1
|
||||
%macro USE_XCH 0
|
||||
%if XCH_ID == -1
|
||||
%assign XCH_ID CUR_ID
|
||||
%assign CUR_ID CUR_ID + 2
|
||||
%xdefine OPCODES OPCODES MANGLE_FUNC(su_op_xch,0),
|
||||
%xdefine NUMPARAMS NUMPARAMS 0,
|
||||
%endif
|
||||
%endmacro
|
||||
|
||||
%macro SU_XCH 1
|
||||
USE_XCH
|
||||
%xdefine CMDS CMDS XCH_ID + %1,
|
||||
%if %1 == STEREO
|
||||
%define INCLUDE_STEREO_XCH
|
||||
%endif
|
||||
%endmacro
|
||||
351
src/opcodes/effects.asm
Normal file
351
src/opcodes/effects.asm
Normal file
@@ -0,0 +1,351 @@
|
||||
;-------------------------------------------------------------------------------
|
||||
; DISTORT Tick
|
||||
;-------------------------------------------------------------------------------
|
||||
; Input: st0 : x - input value
|
||||
; Output: st0 : x*a/(1-a+(2*a-1)*abs(x))
|
||||
; where x is clamped first
|
||||
;-------------------------------------------------------------------------------
|
||||
%if DISTORT_ID > -1
|
||||
|
||||
SECT_TEXT(sudistrt)
|
||||
|
||||
EXPORT MANGLE_FUNC(su_op_distort,0)
|
||||
%ifdef INCLUDE_STEREO_DISTORT
|
||||
jnc su_op_distort_mono
|
||||
call su_stereo_filterhelper
|
||||
%define INCLUDE_STEREO_FILTERHELPER
|
||||
su_op_distort_mono:
|
||||
%endif
|
||||
fld dword [edx+su_distort_ports.drive]
|
||||
%define SU_INCLUDE_WAVESHAPER
|
||||
; flow into waveshaper
|
||||
%endif
|
||||
|
||||
%ifdef SU_INCLUDE_WAVESHAPER
|
||||
su_waveshaper:
|
||||
fxch ; x a
|
||||
call MANGLE_FUNC(su_clip_op,0)
|
||||
fxch ; a x' (from now on just called x)
|
||||
fld st0 ; a a x
|
||||
fsub dword [c_0_5] ; a-.5 a x
|
||||
fadd st0 ; 2*a-1 a x
|
||||
fld st2 ; x 2*a-1 a x
|
||||
fabs ; abs(x) 2*a-1 a x
|
||||
fmulp st1 ; (2*a-1)*abs(x) a x
|
||||
fld1 ; 1 (2*a-1)*abs(x) a x
|
||||
faddp st1 ; 1+(2*a-1)*abs(x) a x
|
||||
fsub st1 ; 1-a+(2*a-1)*abs(x) a x
|
||||
fdivp st1, st0 ; a/(1-a+(2*a-1)*abs(x)) x
|
||||
fmulp st1 ; x*a/(1-a+(2*a-1)*abs(x))
|
||||
ret
|
||||
|
||||
%define SU_INCLUDE_CLIP
|
||||
|
||||
%endif ; SU_USE_DST
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; HOLD Tick
|
||||
;-------------------------------------------------------------------------------
|
||||
%if HOLD_ID > -1
|
||||
|
||||
SECT_TEXT(suhold)
|
||||
|
||||
EXPORT MANGLE_FUNC(su_op_hold,0)
|
||||
%ifdef INCLUDE_STEREO_HOLD
|
||||
jnc su_op_hold_mono
|
||||
call su_stereo_filterhelper
|
||||
%define INCLUDE_STEREO_FILTERHELPER
|
||||
su_op_hold_mono:
|
||||
%endif
|
||||
fld dword [edx+su_hold_ports.freq] ; f x
|
||||
fmul st0, st0 ; f^2 x
|
||||
fchs ; -f^2 x
|
||||
fadd dword [WRK+su_hold_wrk.phase] ; p-f^2 x
|
||||
fst dword [WRK+su_hold_wrk.phase] ; p <- p-f^2
|
||||
fldz ; 0 p x
|
||||
fucomip st1 ; p x
|
||||
fstp dword [esp-4] ; t=p, x
|
||||
jc short su_op_hold_holding ; if (0 < p) goto holding
|
||||
fld1 ; 1 x
|
||||
fadd dword [esp-4] ; 1+t x
|
||||
fstp dword [WRK+su_hold_wrk.phase] ; x
|
||||
fst dword [WRK+su_hold_wrk.holdval] ; save holded value
|
||||
ret ; x
|
||||
su_op_hold_holding:
|
||||
fstp st0 ;
|
||||
fld dword [WRK+su_hold_wrk.holdval] ; x
|
||||
ret
|
||||
|
||||
%endif ; HOLD_ID > -1
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; su_op_filter: perform low/high/band-pass filtering on the signal
|
||||
;-------------------------------------------------------------------------------
|
||||
; Input: WRK : pointer to unit workspace
|
||||
; VAL : pointer to unit values as bytes
|
||||
; ecx : pointer to global workspace
|
||||
; st0 : signal
|
||||
; Output: st0 : filtered signal
|
||||
; Dirty: eax, edx
|
||||
;-------------------------------------------------------------------------------
|
||||
%if FILTER_ID > -1
|
||||
SECT_TEXT(sufilter)
|
||||
|
||||
EXPORT MANGLE_FUNC(su_op_filter,0)
|
||||
lodsb ; load the flags to al
|
||||
%ifdef INCLUDE_STEREO_FILTER
|
||||
jnc su_op_filter_mono
|
||||
call su_stereo_filterhelper
|
||||
%define INCLUDE_STEREO_FILTERHELPER
|
||||
su_op_filter_mono:
|
||||
%endif
|
||||
fld dword [edx+su_filter_ports.res] ; r x
|
||||
fld dword [edx+su_filter_ports.freq]; f r x
|
||||
fmul st0, st0 ; f2 x (square the input so we never get negative and also have a smoother behaviour in the lower frequencies)
|
||||
fst dword [esp-4] ; f2 r x
|
||||
fmul dword [WRK+su_filter_wrk.band] ; f2*b r x
|
||||
fadd dword [WRK+su_filter_wrk.low] ; f2*b+l r x
|
||||
fst dword [WRK+su_filter_wrk.low] ; l'=f2*b+l r x
|
||||
fsubp st2, st0 ; r x-l'
|
||||
fmul dword [WRK+su_filter_wrk.band] ; r*b x-l'
|
||||
fsubp st1, st0 ; x-l'-r*b
|
||||
fst dword [WRK+su_filter_wrk.high] ; h'=x-l'-r*b
|
||||
fmul dword [esp-4] ; f2*h'
|
||||
fadd dword [WRK+su_filter_wrk.band] ; f2*h'+b
|
||||
fstp dword [WRK+su_filter_wrk.band] ; b'=f2*h'+b
|
||||
fldz ; 0
|
||||
%ifdef INCLUDE_LOWPASS
|
||||
test al, byte LOWPASS
|
||||
jz short su_op_filter_skiplowpass
|
||||
fadd dword [WRK+su_filter_wrk.low]
|
||||
su_op_filter_skiplowpass:
|
||||
%endif
|
||||
%ifdef INCLUDE_BANDPASS
|
||||
test al, byte BANDPASS
|
||||
jz short su_op_filter_skipbandpass
|
||||
fadd dword [WRK+su_filter_wrk.band]
|
||||
su_op_filter_skipbandpass:
|
||||
%endif
|
||||
%ifdef INCLUDE_HIGHPASS
|
||||
test al, byte HIGHPASS
|
||||
jz short su_op_filter_skiphighpass
|
||||
fadd dword [WRK+su_filter_wrk.high]
|
||||
su_op_filter_skiphighpass:
|
||||
%endif
|
||||
%ifdef INCLUDE_NEGBANDPASS
|
||||
test al, byte NEGBANDPASS
|
||||
jz short su_op_filter_skipnegbandpass
|
||||
fsub dword [WRK+su_filter_wrk.band]
|
||||
su_op_filter_skipnegbandpass:
|
||||
%endif
|
||||
%ifdef INCLUDE_NEGHIGHPASS
|
||||
test al, byte NEGHIGHPASS
|
||||
jz short su_op_filter_skipneghighpass
|
||||
fsub dword [WRK+su_filter_wrk.high]
|
||||
su_op_filter_skipneghighpass:
|
||||
%endif
|
||||
ret
|
||||
%endif ; SU_INCLUDE_FILTER
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; su_clip function
|
||||
;-------------------------------------------------------------------------------
|
||||
; Input: st0 : x
|
||||
; Output: st0 : min(max(x,-1),1)
|
||||
;-------------------------------------------------------------------------------
|
||||
%if CLIP_ID > -1
|
||||
%define SU_INCLUDE_CLIP
|
||||
%endif
|
||||
|
||||
%ifdef SU_INCLUDE_CLIP
|
||||
|
||||
SECT_TEXT(suclip)
|
||||
|
||||
EXPORT MANGLE_FUNC(su_clip_op,0)
|
||||
fld1 ; 1 x a
|
||||
fucomi st1 ; if (1 <= x)
|
||||
jbe short su_clip_do ; goto Clip_Do
|
||||
fchs ; -1 x a
|
||||
fucomi st1 ; if (-1 < x)
|
||||
fcmovb st0, st1 ; x x a
|
||||
su_clip_do:
|
||||
fstp st1 ; x' a, where x' = clamp(x)
|
||||
ret
|
||||
|
||||
%endif ; SU_INCLUDE_CLIP
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; PAN Tick
|
||||
;-------------------------------------------------------------------------------
|
||||
; Input: WRK : pointer to unit workspace
|
||||
; VAL : pointer to unit values as bytes
|
||||
; ecx : pointer to global workspace
|
||||
; st0 : s, the signal
|
||||
; Output: st0 : s*(1-p), where p is the panning in [0,1] range
|
||||
; st1 : s*p
|
||||
; Dirty: eax, edx
|
||||
;-------------------------------------------------------------------------------
|
||||
%if PAN_ID > -1
|
||||
|
||||
SECT_TEXT(supan)
|
||||
|
||||
%ifdef INCLUDE_STEREO_PAN
|
||||
|
||||
EXPORT MANGLE_FUNC(su_op_pan,0)
|
||||
jc su_op_pan_do ; this time, if this is mono op...
|
||||
fld st0 ; ...we duplicate the mono into stereo first
|
||||
su_op_pan_do:
|
||||
fld dword [edx+su_pan_ports.panning] ; p l r
|
||||
fld1 ; 1 p l r
|
||||
fsub st1 ; 1-p p l r
|
||||
fmulp st2 ; p (1-p)*l r
|
||||
fmulp st2 ; (1-p)*l p*r
|
||||
ret
|
||||
|
||||
%else ; ifndef INCLUDE_STEREO_PAN
|
||||
|
||||
EXPORT MANGLE_FUNC(su_op_pan,0)
|
||||
fld dword [edx+su_pan_ports.panning] ; p s
|
||||
fmul st1 ; p*s s
|
||||
fsub st1, st0 ; p*s s-p*s
|
||||
; Equal to
|
||||
; s*p s*(1-p)
|
||||
fxch ; s*(1-p) s*p SHOULD PROBABLY DELETE, WHY BOTHER
|
||||
ret
|
||||
|
||||
%endif ; INCLUDE_STEREO_PAN
|
||||
|
||||
%endif ; SU_USE_PAN
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; su_stereo_filterhelper: moves the workspace to next, does the filtering for
|
||||
; right channel (pulling the calling address from stack), rewinds the
|
||||
; workspace and returns
|
||||
;-------------------------------------------------------------------------------
|
||||
%ifdef INCLUDE_STEREO_FILTERHELPER
|
||||
|
||||
su_stereo_filterhelper:
|
||||
add WRK, 16
|
||||
fxch ; r l
|
||||
call dword [esp] ; call whoever called me...
|
||||
fxch ; l r
|
||||
sub WRK, 16 ; move WRK back to where it was
|
||||
ret
|
||||
|
||||
%endif
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; Delay Tick
|
||||
;-------------------------------------------------------------------------------
|
||||
; Pseudocode:
|
||||
; q = dr*x
|
||||
; for (i = 0;i < count;i++)
|
||||
; s = b[(t-delaytime[i+offset])&65535]
|
||||
; q += s
|
||||
; o[i] = o[i]*da+s*(1-da)
|
||||
; b[t] = f*o[i] +p^2*x
|
||||
; Perform dc-filtering q and output
|
||||
;-------------------------------------------------------------------------------
|
||||
%if DELAY_ID > -1
|
||||
|
||||
SECT_TEXT(sudelay)
|
||||
|
||||
EXPORT MANGLE_FUNC(su_op_delay,0)
|
||||
lodsb ; eax = delay index
|
||||
mov edi, eax
|
||||
lodsb ; eax = delay count
|
||||
%ifdef INCLUDE_STEREO_DELAY
|
||||
jnc su_op_delay_mono
|
||||
fxch
|
||||
call su_op_delay_mono ; do right delay
|
||||
fxch
|
||||
add edi, eax ; the second delay is done with the delay time index added by count
|
||||
su_op_delay_mono:
|
||||
%endif
|
||||
pushad
|
||||
mov ebx, edi; ugly register juggling, refactor
|
||||
%ifdef DELAY_NOTE_SYNC
|
||||
test ebx, ebx ; note s
|
||||
jne su_op_delay_skipnotesync
|
||||
fld1
|
||||
fild dword [ecx+su_unit.size-su_voice.workspace+su_voice.note]
|
||||
fmul dword [c_i12]
|
||||
call MANGLE_FUNC(su_power,0)
|
||||
fmul dword [c_freq_normalize] ; // normalize
|
||||
fdivp st1, st0 ; // invert to get numer of samples
|
||||
fistp word [MANGLE_DATA(su_delay_times)] ; store current comb size
|
||||
su_op_delay_skipnotesync:
|
||||
%endif
|
||||
kmDLL_func_process:
|
||||
mov ecx, eax ;// ecx is the number of parallel delays
|
||||
mov WRK, dword [MANGLE_DATA(su_delay_buffer_ofs)] ;// ebp is current delay
|
||||
fld st0 ; x x
|
||||
fmul dword [edx+su_delay_ports.dry] ; dr*x x
|
||||
fxch ; x dr*x
|
||||
fmul dword [edx+su_delay_ports.pregain] ; p*x dr*x
|
||||
fmul dword [edx+su_delay_ports.pregain] ; p^2*x dr*x
|
||||
|
||||
kmDLL_func_loop:
|
||||
mov edi, dword [WRK + su_delayline_wrk.time]
|
||||
inc edi
|
||||
and edi, MAX_DELAY-1
|
||||
mov dword [WRK + su_delayline_wrk.time],edi
|
||||
movzx esi, word [MANGLE_DATA(su_delay_times)+ebx*2] ; esi = comb size from the delay times table
|
||||
mov eax, edi
|
||||
sub eax, esi
|
||||
and eax, MAX_DELAY-1
|
||||
fld dword [WRK+eax*4+su_delayline_wrk.buffer] ; s p^2*x dr*x, where s is the sample from delay buffer
|
||||
;// add comb output to current output
|
||||
fadd st2, st0 ; s p^2*x dr*x+s
|
||||
fld1 ; 1 s p^2*x dr*x+s
|
||||
fsub dword [edx+su_delay_ports.damp] ; 1-da s p^2*x dr*x+s
|
||||
fmulp st1, st0 ; s*(1-da) p^2*x dr*x+s
|
||||
fld dword [edx+su_delay_ports.damp] ; da s*(1-da) p^2*x dr*x+s
|
||||
fmul dword [WRK+su_delayline_wrk.filtstate] ; o*da s*(1-da) p^2*x dr*x+s, where o is stored
|
||||
faddp st1, st0 ; o*da+s*(1-da) p^2*x dr*x+s
|
||||
fst dword [WRK+su_delayline_wrk.filtstate] ; o'=o*da+s*(1-da), o' p^2*x dr*x+s
|
||||
fmul dword [edx+su_delay_ports.feedback] ; f*o' p^2*x dr*x+s
|
||||
fadd st0, st1 ; f*o'+p^2*x p^2*x dr*x+s
|
||||
fstp dword [WRK+edi*4+su_delayline_wrk.buffer]; save f*o'+p^2*x to delay buffer
|
||||
inc ebx ;// go to next delay lenkmh index
|
||||
add WRK, su_delayline_wrk.size ;// go to next delay
|
||||
mov dword [MANGLE_DATA(su_delay_buffer_ofs)], WRK ;// store next delay offset
|
||||
loopne kmDLL_func_loop
|
||||
fstp st0 ; dr*x+s1+s2+s3+...
|
||||
; DC-filtering
|
||||
sub WRK, su_delayline_wrk.size ; the reason to use the last su_delayline_wrk instead of su_delay_wrk is that su_delay_wrk is wiped by retriggering
|
||||
fld dword [WRK+su_delayline_wrk.dcout] ; o s
|
||||
fmul dword [c_dc_const] ; c*o s
|
||||
fsub dword [WRK+su_delayline_wrk.dcin] ; c*o-i s
|
||||
fxch ; s c*o-i
|
||||
fst dword [WRK+su_delayline_wrk.dcin] ; i'=s, s c*o-i
|
||||
faddp st1 ; s+c*o-i
|
||||
fadd dword [c_0_5] ;// add and sub small offset to prevent denormalization
|
||||
fsub dword [c_0_5]
|
||||
fst dword [WRK+su_delayline_wrk.dcout] ; o'=s+c*o-i
|
||||
popad
|
||||
ret
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; Delay data
|
||||
;-------------------------------------------------------------------------------
|
||||
SECT_BSS(sudelbuf)
|
||||
|
||||
EXPORT MANGLE_DATA(su_delay_buffer_ofs)
|
||||
resd 1
|
||||
EXPORT MANGLE_DATA(su_delay_buffer)
|
||||
resb NUM_DELAY_LINES*su_delayline_wrk.size
|
||||
|
||||
SECT_DATA(suconst)
|
||||
|
||||
%ifndef C_DC_CONST
|
||||
c_dc_const dd 0.99609375 ; R = 1 - (pi*2 * frequency /samplerate)
|
||||
%define C_DC_CONST
|
||||
%endif
|
||||
|
||||
%ifndef C_FREQ_NORMALIZE
|
||||
c_freq_normalize dd 0.000092696138 ; // 220.0/(2^(69/12)) / 44100.0
|
||||
%define C_FREQ_NORMALIZE
|
||||
%endif
|
||||
|
||||
%endif ; DELAY_ID > -1
|
||||
256
src/opcodes/effects.inc
Normal file
256
src/opcodes/effects.inc
Normal file
@@ -0,0 +1,256 @@
|
||||
;-------------------------------------------------------------------------------
|
||||
; Filter (LOWPASS, BANDPASS...) effect related defines
|
||||
;-------------------------------------------------------------------------------
|
||||
%assign FILTER_ID -1
|
||||
|
||||
%macro USE_FILTER 0
|
||||
%if FILTER_ID == -1
|
||||
%assign FILTER_ID CUR_ID
|
||||
%assign CUR_ID CUR_ID + 2
|
||||
%xdefine OPCODES OPCODES MANGLE_FUNC(su_op_filter,0),
|
||||
%xdefine NUMPARAMS NUMPARAMS 2,
|
||||
%endif
|
||||
%endmacro
|
||||
|
||||
%define LOWPASS 0x40
|
||||
%define BANDPASS 0x20
|
||||
%define HIGHPASS 0x10
|
||||
%define NEGBANDPASS 0x08
|
||||
%define NEGHIGHPASS 0x04
|
||||
|
||||
%macro SU_FILTER 4
|
||||
db %2
|
||||
db %3
|
||||
db %4
|
||||
USE_FILTER
|
||||
%xdefine CMDS CMDS FILTER_ID + %1,
|
||||
%if %1 == STEREO
|
||||
%define INCLUDE_STEREO_FILTER
|
||||
%endif
|
||||
%if (%4) & LOWPASS == LOWPASS
|
||||
%define INCLUDE_LOWPASS
|
||||
%endif
|
||||
%if (%4) & BANDPASS == BANDPASS
|
||||
%define INCLUDE_BANDPASS
|
||||
%endif
|
||||
%if (%4) & HIGHPASS == HIGHPASS
|
||||
%define INCLUDE_HIGHPASS
|
||||
%endif
|
||||
%if (%4) & NEGBANDPASS == NEGBANDPASS
|
||||
%define INCLUDE_NEGBANDPASS
|
||||
%endif
|
||||
%if (%4) & NEGHIGHPASS == NEGHIGHPASS
|
||||
%define INCLUDE_NEGHIGHPASS
|
||||
%endif
|
||||
%endmacro
|
||||
|
||||
%define FREQUENCY(val) val
|
||||
%define RESONANCE(val) val
|
||||
%define FLAGS(val) val
|
||||
|
||||
struc su_filter_ports
|
||||
.freq resd 1
|
||||
.res resd 1
|
||||
.params
|
||||
endstruc
|
||||
|
||||
struc su_filter_wrk
|
||||
.low resd 1
|
||||
.high resd 1
|
||||
.band resd 1
|
||||
.size
|
||||
endstruc
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; PAN effect related defines
|
||||
;-------------------------------------------------------------------------------
|
||||
%assign PAN_ID -1
|
||||
|
||||
%macro USE_PAN 0
|
||||
%if PAN_ID == -1
|
||||
%assign PAN_ID CUR_ID
|
||||
%assign CUR_ID CUR_ID + 2
|
||||
%xdefine OPCODES OPCODES MANGLE_FUNC(su_op_pan,0),
|
||||
%xdefine NUMPARAMS NUMPARAMS 1,
|
||||
%endif
|
||||
%endmacro
|
||||
|
||||
%macro SU_PAN 2
|
||||
db %2
|
||||
USE_PAN
|
||||
%xdefine CMDS CMDS PAN_ID + %1,
|
||||
%if %1 == STEREO
|
||||
%define INCLUDE_STEREO_PAN
|
||||
%endif
|
||||
%endmacro
|
||||
|
||||
%define PANNING(val) val
|
||||
|
||||
struc su_pan_ports
|
||||
.panning resd 1
|
||||
.params
|
||||
endstruc
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; DISTORT effect related defines
|
||||
;-------------------------------------------------------------------------------
|
||||
%assign DISTORT_ID -1
|
||||
|
||||
%macro USE_DISTORT 0
|
||||
%if DISTORT_ID == -1
|
||||
%assign DISTORT_ID CUR_ID
|
||||
%assign CUR_ID CUR_ID + 2
|
||||
%xdefine OPCODES OPCODES MANGLE_FUNC(su_op_distort,0),
|
||||
%xdefine NUMPARAMS NUMPARAMS 1,
|
||||
%endif
|
||||
%endmacro
|
||||
|
||||
%macro SU_DISTORT 2
|
||||
db %2
|
||||
USE_DISTORT
|
||||
%xdefine CMDS CMDS DISTORT_ID + %1,
|
||||
%if %1 == STEREO
|
||||
%define INCLUDE_STEREO_DISTORT
|
||||
%endif
|
||||
%endmacro
|
||||
|
||||
%define DRIVE(val) val
|
||||
|
||||
struc su_distort_ports
|
||||
.drive resd 1
|
||||
.params
|
||||
endstruc
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; HOLD effect related defines
|
||||
;-------------------------------------------------------------------------------
|
||||
%assign HOLD_ID -1
|
||||
|
||||
%macro USE_HOLD 0
|
||||
%if HOLD_ID == -1
|
||||
%assign HOLD_ID CUR_ID
|
||||
%assign CUR_ID CUR_ID + 2
|
||||
%xdefine OPCODES OPCODES MANGLE_FUNC(su_op_hold,0),
|
||||
%xdefine NUMPARAMS NUMPARAMS 1,
|
||||
%endif
|
||||
%endmacro
|
||||
|
||||
%macro SU_HOLD 2
|
||||
db %2
|
||||
USE_HOLD
|
||||
%xdefine CMDS CMDS HOLD_ID + %1,
|
||||
%if %1 == STEREO
|
||||
%define INCLUDE_STEREO_DISTORT
|
||||
%endif
|
||||
%endmacro
|
||||
|
||||
%define HOLDFREQ(val) val
|
||||
|
||||
struc su_hold_ports
|
||||
.freq resd 1
|
||||
.params
|
||||
endstruc
|
||||
|
||||
struc su_hold_wrk
|
||||
.phase resd 1
|
||||
.holdval resd 1
|
||||
endstruc
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; CLIP effect related defines
|
||||
;-------------------------------------------------------------------------------
|
||||
%assign CLIP_ID -1
|
||||
|
||||
%macro USE_CLIP 0
|
||||
%if CLIP_ID == -1
|
||||
%assign CLIP_ID CUR_ID
|
||||
%assign CUR_ID CUR_ID + 2
|
||||
%xdefine OPCODES OPCODES MANGLE_FUNC(su_op_clip,0),
|
||||
%xdefine NUMPARAMS NUMPARAMS 0,
|
||||
%endif
|
||||
%endmacro
|
||||
|
||||
%macro SU_CLIP 1
|
||||
USE_CLIP
|
||||
%xdefine CMDS CMDS CLIP_ID + %1,
|
||||
%if %1 == STEREO
|
||||
%define INCLUDE_STEREO_CLIP
|
||||
%endif
|
||||
%endmacro
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; Delay effect related defines
|
||||
;-------------------------------------------------------------------------------
|
||||
%assign DELAY_ID -1
|
||||
%macro USE_DELAY 0
|
||||
%if DELAY_ID == -1
|
||||
%assign DELAY_ID CUR_ID
|
||||
%assign CUR_ID CUR_ID + 2
|
||||
%xdefine OPCODES OPCODES MANGLE_FUNC(su_op_delay,0),
|
||||
%xdefine NUMPARAMS NUMPARAMS 4,
|
||||
%endif
|
||||
%endmacro
|
||||
|
||||
%define MAX_DELAY 65536
|
||||
%assign NUM_DELAY_LINES 0
|
||||
|
||||
%macro SU_DELAY 7
|
||||
db %2
|
||||
db %3
|
||||
db %4
|
||||
db %5
|
||||
db %6
|
||||
db %7
|
||||
USE_DELAY
|
||||
%xdefine CMDS CMDS DELAY_ID + %1,
|
||||
%assign NUM_DELAY_LINES NUM_DELAY_LINES + %7 * (1+%1)
|
||||
%if %1 == STEREO
|
||||
%define INCLUDE_STEREO_DELAY
|
||||
%endif
|
||||
%if %6 == 0
|
||||
%define DELAY_NOTE_SYNC
|
||||
%endif
|
||||
%endmacro
|
||||
|
||||
%macro SU_BEGIN_DELTIMES 0
|
||||
SECT_DATA(sudeltim)
|
||||
|
||||
EXPORT MANGLE_DATA(su_delay_times)
|
||||
dw 0
|
||||
%endmacro
|
||||
|
||||
%define SU_END_DELTIMES
|
||||
|
||||
%macro DELTIME 1-*
|
||||
%rep %0
|
||||
dw %1
|
||||
%rotate 1
|
||||
%endrep
|
||||
%endmacro
|
||||
|
||||
|
||||
%define PREGAIN(val) val
|
||||
%define DRY(val) val
|
||||
%define FEEDBACK(val) val
|
||||
%define DEPTH(val) val
|
||||
%define DAMP(val) val
|
||||
%define DELAY(val) val
|
||||
%define COUNT(val) val
|
||||
|
||||
struc su_delay_ports
|
||||
.pregain resd 1
|
||||
.dry resd 1
|
||||
.feedback resd 1
|
||||
.damp resd 1
|
||||
.freq resd 1
|
||||
.ports
|
||||
endstruc
|
||||
|
||||
struc su_delayline_wrk
|
||||
.time resd 1
|
||||
.filtstate resd 1
|
||||
.dcin resd 1
|
||||
.dcout resd 1
|
||||
.buffer resd MAX_DELAY
|
||||
.size
|
||||
endstruc
|
||||
63
src/opcodes/flowcontrol.asm
Normal file
63
src/opcodes/flowcontrol.asm
Normal file
@@ -0,0 +1,63 @@
|
||||
;-------------------------------------------------------------------------------
|
||||
; su_op_advance function: opcode to advance from one instrument to next
|
||||
;-------------------------------------------------------------------------------
|
||||
; Stack: voice wrkptr valptr comptr
|
||||
; voice : the number of voice we are currently processing
|
||||
; wrkptr : pointer to the first unit of current voice - su_unit.size
|
||||
; valptr : pointer to the first unit's value of current voice
|
||||
; comptr : pointer to the first command of current voice
|
||||
; COM : pointer to the command after current command
|
||||
; Output: WRK : pointer to the next unit to be processed
|
||||
; VAL : pointer to the values of the next to be processed
|
||||
; COM : pointer to the next command to be executed
|
||||
;
|
||||
; Checks if this was the last voice of current instrument. If so, moves to
|
||||
; next opcodes and updates the stack to reflect the instrument change.
|
||||
; If this instrument has more voices to process, rolls back the COM and VAL
|
||||
; pointers to where they were when this instrument started.
|
||||
;-------------------------------------------------------------------------------
|
||||
SECT_TEXT(suopadvn)
|
||||
|
||||
%ifdef INCLUDE_POLYPHONY
|
||||
|
||||
EXPORT MANGLE_FUNC(su_op_advance,0) ; Stack: addr voice wrkptr valptr comptr
|
||||
mov WRK, dword [esp+8] ; WRK = wrkptr
|
||||
add WRK, su_voice.size ; move to next voice
|
||||
mov dword [esp+8], WRK ; update stack
|
||||
mov ecx, dword [esp+4] ; ecx = voice
|
||||
bt dword [su_polyphony_bitmask],ecx ; if voice bit of su_polyphonism not set
|
||||
jnc su_op_advance_next_instrument ; goto next_instrument
|
||||
mov VAL, dword [esp+12] ; rollback to where we were earlier
|
||||
mov COM, dword [esp+16]
|
||||
jmp short su_op_advance_finish
|
||||
su_op_advance_next_instrument:
|
||||
mov dword [esp+12], VAL ; save current VAL as a checkpoint
|
||||
mov dword [esp+16], COM ; save current COM as a checkpoint
|
||||
su_op_advance_finish:
|
||||
inc ecx ; voice++
|
||||
mov dword [esp+4], ecx
|
||||
ret
|
||||
|
||||
%else
|
||||
|
||||
EXPORT MANGLE_FUNC(su_op_advance,0) ; Stack: addr voice wrkptr valptr comptr
|
||||
mov WRK, dword [esp+8] ; WRK = wrkptr
|
||||
add WRK, su_voice.size ; move to next voice
|
||||
mov dword [esp+8], WRK ; update stack
|
||||
inc dword [esp+4] ; voice++
|
||||
ret
|
||||
|
||||
%endif
|
||||
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; Constants
|
||||
;-------------------------------------------------------------------------------
|
||||
%ifdef SU_USE_DLL_DC_FILTER
|
||||
%ifndef C_DC_CONST
|
||||
SECT_DATA(suconst)
|
||||
c_dc_const dd 0.99609375 ; R = 1 - (pi*2 * frequency /samplerate)
|
||||
%define C_DC_CONST
|
||||
%endif
|
||||
|
||||
%endif
|
||||
0
src/opcodes/flowcontrol.inc
Normal file
0
src/opcodes/flowcontrol.inc
Normal file
70
src/opcodes/sinks.asm
Normal file
70
src/opcodes/sinks.asm
Normal file
@@ -0,0 +1,70 @@
|
||||
;-------------------------------------------------------------------------------
|
||||
; OUT Tick
|
||||
;-------------------------------------------------------------------------------
|
||||
%if OUT_ID > -1
|
||||
|
||||
SECT_TEXT(suopout)
|
||||
|
||||
EXPORT MANGLE_FUNC(su_op_out,0) ; l r
|
||||
mov eax, su_synth_obj + su_synth.left
|
||||
%ifdef INCLUDE_STEREO_OUT
|
||||
jnc su_op_out_mono
|
||||
call su_op_out_mono
|
||||
add eax, 4
|
||||
su_op_out_mono:
|
||||
%endif
|
||||
fmul dword [edx+su_out_ports.gain] ; g*l
|
||||
fadd dword [eax] ; g*l+o
|
||||
fstp dword [eax] ; o'=g*l+o
|
||||
ret
|
||||
|
||||
%endif ; SU_OUT_ID > -1
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; Send Tick
|
||||
;-------------------------------------------------------------------------------
|
||||
; Input: WRK : pointer to unit workspace
|
||||
; VAL : pointer to unit values as bytes
|
||||
; ecx : pointer to global workspace
|
||||
; st0 : signal
|
||||
; Output: (st0) : signal, unless popped
|
||||
; Dirty: eax, edx
|
||||
;-------------------------------------------------------------------------------
|
||||
%if SEND_ID > -1
|
||||
|
||||
SECT_TEXT(susend)
|
||||
|
||||
EXPORT MANGLE_FUNC(su_op_send,0)
|
||||
lodsw
|
||||
%ifdef INCLUDE_STEREO_SEND
|
||||
jnc su_op_send_mono
|
||||
mov edi, eax
|
||||
inc eax ; send the right channel first
|
||||
fxch ; r l
|
||||
call su_op_send_mono ; (r) l
|
||||
mov eax, edi ; move back to original address
|
||||
test edx, SEND_POP ; if r was not popped and is still in the stack
|
||||
jnz su_op_send_mono
|
||||
fxch ; swap them back: l r
|
||||
su_op_send_mono:
|
||||
%endif
|
||||
%ifdef INCLUDE_GLOBAL_SEND
|
||||
test eax, SEND_GLOBAL
|
||||
jz su_op_send_skipglobal
|
||||
mov ecx, su_synth_obj - su_unit.size
|
||||
su_op_send_skipglobal:
|
||||
%endif
|
||||
test eax, SEND_POP ; if the SEND_POP bit is not set
|
||||
jnz su_op_send_skippush
|
||||
fld st0 ; duplicate the signal on stack: s s
|
||||
su_op_send_skippush: ; there is signal s, but maybe also another: s (s)
|
||||
fld dword [edx+su_send_ports.amount] ; a l (l)
|
||||
fsub dword [c_0_5] ; a-.5 l (l)
|
||||
fadd st0 ; g=2*a-1 l (l)
|
||||
and eax, 0x0000ffff - SEND_POP - SEND_GLOBAL ; eax = send address
|
||||
fmulp st1, st0 ; g*l (l)
|
||||
fadd dword [ecx+su_unit.size+eax*4] ; g*l+L (l),where L is the current value
|
||||
fstp dword [ecx+su_unit.size+eax*4] ; (l)
|
||||
ret
|
||||
|
||||
%endif ; SU_USE_SEND > -1
|
||||
66
src/opcodes/sinks.inc
Normal file
66
src/opcodes/sinks.inc
Normal file
@@ -0,0 +1,66 @@
|
||||
;-------------------------------------------------------------------------------
|
||||
; OUT structs
|
||||
;-------------------------------------------------------------------------------
|
||||
%assign OUT_ID -1
|
||||
%macro USE_OUT 0
|
||||
%if OUT_ID == -1
|
||||
%assign OUT_ID CUR_ID
|
||||
%assign CUR_ID CUR_ID + 2
|
||||
%xdefine OPCODES OPCODES MANGLE_FUNC(su_op_out,0),
|
||||
%xdefine NUMPARAMS NUMPARAMS 1,
|
||||
%endif
|
||||
%endmacro
|
||||
|
||||
%macro SU_OUT 2
|
||||
db %2
|
||||
USE_OUT
|
||||
%xdefine CMDS CMDS OUT_ID+%1,
|
||||
%if %1 == STEREO
|
||||
%define INCLUDE_STEREO_OUT
|
||||
%endif
|
||||
%endmacro
|
||||
|
||||
%define GAIN(val) val
|
||||
|
||||
struc su_out_ports
|
||||
.gain resd 1
|
||||
.params
|
||||
endstruc
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; SEND structs
|
||||
;-------------------------------------------------------------------------------
|
||||
%assign SEND_ID -1
|
||||
%macro USE_SEND 0
|
||||
%if SEND_ID == -1
|
||||
%assign SEND_ID CUR_ID
|
||||
%assign CUR_ID CUR_ID + 2
|
||||
%xdefine OPCODES OPCODES MANGLE_FUNC(su_op_send,0),
|
||||
%xdefine NUMPARAMS NUMPARAMS 1,
|
||||
%endif
|
||||
%endmacro
|
||||
|
||||
%macro SU_SEND 3
|
||||
db %2
|
||||
dw %3
|
||||
USE_SEND
|
||||
%xdefine CMDS CMDS SEND_ID + %1,
|
||||
%if %1 == STEREO
|
||||
%define INCLUDE_STEREO_SEND
|
||||
%endif
|
||||
%if (%3) & SEND_GLOBAL == SEND_GLOBAL
|
||||
%define INCLUDE_GLOBAL_SEND
|
||||
%endif
|
||||
%endmacro
|
||||
|
||||
%define AMOUNT(val) val
|
||||
%define PORT(unit,unittype,port) (unit*su_unit.size + su_ %+ unittype %+ _ports. %+ port + su_unit.ports)/4
|
||||
%define GLOBALPORT(voice,unit,unittype,port) SEND_GLOBAL + (su_synth.voices+voice*su_voice.size+su_voice.workspace+unit*su_unit.size + su_ %+ unittype %+ _ports. %+ port + su_unit.ports)/4
|
||||
%define OUTPORT 0
|
||||
%define SEND_POP 0x8000
|
||||
%define SEND_GLOBAL 0x4000
|
||||
|
||||
struc su_send_ports
|
||||
.amount resd 1
|
||||
.params
|
||||
endstruc
|
||||
312
src/opcodes/sources.asm
Normal file
312
src/opcodes/sources.asm
Normal file
@@ -0,0 +1,312 @@
|
||||
;-------------------------------------------------------------------------------
|
||||
; ENV Tick
|
||||
;-------------------------------------------------------------------------------
|
||||
; Input: WRK : pointer to unit workspace
|
||||
; VAL : pointer to unit values as bytes
|
||||
; ecx : pointer to global workspace
|
||||
; Output: st0 : envelope value, [gain]*level. The slopes of
|
||||
; level is 2^(-24*p) per sample, where p is either
|
||||
; attack, decay or release in [0,1] range
|
||||
; Dirty: eax, edx
|
||||
;-------------------------------------------------------------------------------
|
||||
%if ENVELOPE_ID > -1
|
||||
|
||||
SECT_TEXT(suenvelo)
|
||||
|
||||
EXPORT MANGLE_FUNC(su_op_envelope,0)
|
||||
%ifdef INCLUDE_STEREO_ENVELOPE
|
||||
jnc su_op_envelope_mono
|
||||
call su_op_envelope_mono
|
||||
fld st0
|
||||
ret
|
||||
su_op_envelope_mono:
|
||||
%endif
|
||||
kmENV_func_do:
|
||||
mov eax, dword [ecx+su_unit.size-su_voice.workspace+su_voice.release] ; eax = su_instrument.release
|
||||
test eax, eax ; if (eax == 0)
|
||||
je kmENV_func_process ; goto process
|
||||
mov dword [WRK+su_env_work.state], ENV_STATE_RELEASE ; [state]=RELEASE
|
||||
kmENV_func_process:
|
||||
mov eax, dword [WRK+su_env_work.state] ; al=[state]
|
||||
fld dword [WRK+su_env_work.level] ; x=[level]
|
||||
cmp al, ENV_STATE_SUSTAIN ; if (al==SUSTAIN)
|
||||
je short kmENV_func_leave2 ; goto leave2
|
||||
kmENV_func_attac:
|
||||
cmp al, ENV_STATE_ATTAC ; if (al!=ATTAC)
|
||||
jne short kmENV_func_decay ; goto decay
|
||||
call su_env_map ; a x, where a=attack
|
||||
faddp st1, st0 ; a+x
|
||||
fld1 ; 1 a+x
|
||||
fucomi st1 ; if (a+x<=1) // is attack complete?
|
||||
fcmovnb st0, st1 ; a+x a+x
|
||||
jbe short kmENV_func_statechange ; else goto statechange
|
||||
kmENV_func_decay:
|
||||
cmp al, ENV_STATE_DECAY ; if (al!=DECAY)
|
||||
jne short kmENV_func_release ; goto release
|
||||
call su_env_map ; d x, where d=decay
|
||||
fsubp st1, st0 ; x-d
|
||||
fld dword [edx+su_env_ports.sustain] ; s x-d, where s=sustain
|
||||
fucomi st1 ; if (x-d>s) // is decay complete?
|
||||
fcmovb st0, st1 ; x-d x-d
|
||||
jnc short kmENV_func_statechange ; else goto statechange
|
||||
kmENV_func_release:
|
||||
cmp al, ENV_STATE_RELEASE ; if (al!=RELEASE)
|
||||
jne short kmENV_func_leave ; goto leave
|
||||
call su_env_map ; r x, where r=release
|
||||
fsubp st1, st0 ; x-r
|
||||
fldz ; 0 x-r
|
||||
fucomi st1 ; if (x-r>0) // is release complete?
|
||||
fcmovb st0, st1 ; x-r x-r, then goto leave
|
||||
jc short kmENV_func_leave
|
||||
kmENV_func_statechange:
|
||||
inc dword [WRK+su_env_work.state] ; [state]++
|
||||
kmENV_func_leave:
|
||||
fstp st1 ; x', where x' is the new value
|
||||
fst dword [WRK+su_env_work.level] ; [level]=x'
|
||||
kmENV_func_leave2:
|
||||
fmul dword [edx+su_env_ports.gain] ; [gain]*x'
|
||||
ret
|
||||
|
||||
%endif ; SU_USE_ENVELOPE
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; su_noise function: noise oscillators
|
||||
;-------------------------------------------------------------------------------
|
||||
%if NOISE_ID > -1
|
||||
|
||||
SECT_TEXT(sunoise)
|
||||
|
||||
EXPORT MANGLE_FUNC(su_op_noise,0)
|
||||
%ifdef INCLUDE_STEREO_NOISE
|
||||
jnc su_op_noise_mono
|
||||
clc
|
||||
call dword [esp]
|
||||
su_op_noise_mono:
|
||||
%endif
|
||||
call MANGLE_FUNC(FloatRandomNumber,0)
|
||||
fld dword [edx+su_noise_ports.shape]
|
||||
call su_waveshaper
|
||||
fld dword [edx+su_noise_ports.gain]
|
||||
fmulp st1, st0
|
||||
ret
|
||||
|
||||
%define SU_INCLUDE_WAVESHAPER
|
||||
|
||||
%endif
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; su_op_oscillat function: oscillator, the heart of the synth
|
||||
;-------------------------------------------------------------------------------
|
||||
%if OSCILLAT_ID > -1
|
||||
|
||||
SECT_TEXT(suoscill)
|
||||
|
||||
EXPORT MANGLE_FUNC(su_op_oscillat,0)
|
||||
lodsb ; load the flags
|
||||
%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:
|
||||
%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
|
||||
fiadd dword [ecx+su_unit.size-su_voice.workspace+su_voice.note] ; // st0 is note, st1 is t+d offset
|
||||
su_op_oscillat_skipnote:
|
||||
fmul dword [c_i12]
|
||||
call MANGLE_FUNC(su_power,0)
|
||||
test al, byte LFO
|
||||
jz short su_op_oscillat_normalize_note
|
||||
fmul dword [c_lfo_normalize] ; // st0 is now frequency for lfo
|
||||
jmp short su_op_oscillat_normalized
|
||||
su_op_oscillat_normalize_note:
|
||||
fmul dword [c_freq_normalize] ; // st0 is now frequency
|
||||
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]
|
||||
fld1
|
||||
fadd st1, st0
|
||||
fxch
|
||||
fprem
|
||||
fstp st1
|
||||
fld dword [edx+su_osc_ports.color] ; // c p
|
||||
; every oscillator test included if needed
|
||||
%ifdef INCLUDE_SINE
|
||||
test al, byte SINE
|
||||
jz short su_op_oscillat_notsine
|
||||
call su_oscillat_sine
|
||||
su_op_oscillat_notsine:
|
||||
%endif
|
||||
%ifdef INCLUDE_TRISAW
|
||||
test al, byte TRISAW
|
||||
jz short su_op_oscillat_not_trisaw
|
||||
call su_oscillat_trisaw
|
||||
su_op_oscillat_not_trisaw:
|
||||
%endif
|
||||
%ifdef INCLUDE_PULSE
|
||||
test al, byte PULSE
|
||||
jz short su_op_oscillat_not_pulse
|
||||
call su_oscillat_pulse
|
||||
su_op_oscillat_not_pulse:
|
||||
%endif
|
||||
%ifdef INCLUDE_GATE
|
||||
test al, byte GATE
|
||||
jz short su_op_oscillat_not_gate
|
||||
call su_oscillat_gate
|
||||
jmp su_op_oscillat_gain ; skip waveshaping as the shape parameter is reused for gateshigh
|
||||
su_op_oscillat_not_gate:
|
||||
%endif
|
||||
; finally, shape the oscillator and apply gain
|
||||
fld dword [edx+su_osc_ports.shape]
|
||||
call su_waveshaper
|
||||
su_op_oscillat_gain:
|
||||
fld dword [edx+su_osc_ports.gain]
|
||||
fmulp st1, st0
|
||||
ret
|
||||
%define SU_INCLUDE_WAVESHAPER
|
||||
|
||||
SECT_DATA(suconst)
|
||||
|
||||
%ifndef C_FREQ_NORMALIZE
|
||||
c_freq_normalize dd 0.000092696138 ; // 220.0/(2^(69/12)) / 44100.0
|
||||
%define C_FREQ_NORMALIZE
|
||||
%endif
|
||||
c_lfo_normalize dd 0.000038
|
||||
|
||||
%endif
|
||||
|
||||
; PULSE
|
||||
%ifdef INCLUDE_PULSE
|
||||
|
||||
SECT_TEXT(supulse)
|
||||
|
||||
su_oscillat_pulse:
|
||||
fucomi st1 ; // c p
|
||||
fld1
|
||||
jnc short su_oscillat_pulse_up ; // +1 c p
|
||||
fchs ; // -1 c p
|
||||
su_oscillat_pulse_up:
|
||||
fstp st1 ; // +-1 p
|
||||
fstp st1 ; // +-1
|
||||
ret
|
||||
|
||||
%endif
|
||||
|
||||
; TRISAW
|
||||
%ifdef INCLUDE_TRISAW
|
||||
|
||||
SECT_TEXT(sutrisaw)
|
||||
|
||||
su_oscillat_trisaw:
|
||||
fucomi st1 ; // c p
|
||||
jnc short su_oscillat_trisaw_up
|
||||
fld1 ; // 1 c p
|
||||
fsubr st2, st0 ; // 1 c 1-p
|
||||
fsubrp st1, st0 ; // 1-c 1-p
|
||||
su_oscillat_trisaw_up:
|
||||
fdivp st1, st0 ; // tp'/tc
|
||||
fadd st0 ; // 2*''
|
||||
fld1 ; // 1 2*''
|
||||
fsubp st1, st0 ; // 2*''-1
|
||||
ret
|
||||
%endif
|
||||
|
||||
; SINE
|
||||
%ifdef INCLUDE_SINE
|
||||
|
||||
SECT_TEXT(susine)
|
||||
|
||||
su_oscillat_sine:
|
||||
fucomi st1 ; // c p
|
||||
jnc short su_oscillat_sine_do
|
||||
fstp st1
|
||||
fsub st0, st0 ; // 0
|
||||
ret
|
||||
su_oscillat_sine_do
|
||||
fdivp st1, st0 ; // p/c
|
||||
fldpi ; // pi p
|
||||
fadd st0 ; // 2*pi p
|
||||
fmulp st1, st0 ; // 2*pi*p
|
||||
fsin ; // sin(2*pi*p)
|
||||
ret
|
||||
|
||||
%endif
|
||||
|
||||
%ifdef INCLUDE_GATE
|
||||
|
||||
SECT_TEXT(sugate)
|
||||
|
||||
su_oscillat_gate:
|
||||
fxch ; p c
|
||||
fstp st1 ; p
|
||||
fmul dword [c_16] ; 16*p
|
||||
push eax
|
||||
push eax
|
||||
fistp dword [esp] ; s=int(16*p), stack empty
|
||||
fld1 ; 1
|
||||
pop eax
|
||||
and al, 0xf ; ax=int(16*p) & 15, stack: 1
|
||||
bt word [VAL-4],ax ; if bit ax of the gate word is set
|
||||
jc go4kVCO_gate_bit ; goto gate_bit
|
||||
fsub st0, st0 ; stack: 0
|
||||
go4kVCO_gate_bit: ; stack: 0/1, let's call it x
|
||||
fld dword [WRK+su_osc_wrk.gatestate] ; g x, g is gatestate, x is the input to this filter 0/1
|
||||
fsub st1 ; g-x x
|
||||
fmul dword [c_dc_const] ; c(g-x) x
|
||||
faddp st1, st0 ; x+c(g-x)
|
||||
fst dword [WRK+su_osc_wrk.gatestate] ; g'=x+c(g-x)
|
||||
pop eax ; Another way to see this (c~0.996)
|
||||
ret ; g'=cg+(1-c)x
|
||||
; This is a low-pass to smooth the gate transitions
|
||||
|
||||
SECT_DATA(suconst)
|
||||
|
||||
%ifndef C_16
|
||||
c_16 dd 16.0
|
||||
%define C_16
|
||||
%endif
|
||||
|
||||
%ifndef C_DC_CONST
|
||||
c_dc_const dd 0.99609375 ; R = 1 - (pi*2 * frequency /samplerate)
|
||||
%define C_DC_CONST
|
||||
%endif
|
||||
|
||||
%endif
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; LOAD_VAL opcode
|
||||
;-------------------------------------------------------------------------------
|
||||
; Input: WRK : pointer to unit workspace
|
||||
; VAL : pointer to unit values as bytes
|
||||
; Output: st0 : 2*v-1, where v is the loaded value
|
||||
; Dirty: eax, edx
|
||||
;-------------------------------------------------------------------------------
|
||||
%if LOAD_VAL_ID > -1
|
||||
|
||||
SECT_TEXT(suloadvl)
|
||||
|
||||
EXPORT MANGLE_FUNC(su_op_load_val,0)
|
||||
%ifdef INCLUDE_STEREO_LOAD_VAL
|
||||
jnc su_op_load_val_mono
|
||||
call su_load_val_mono
|
||||
su_load_val_mono:
|
||||
%endif
|
||||
fld dword [edx+su_load_val_ports.value] ; v
|
||||
fsub dword [c_0_5] ; v-.5
|
||||
fadd st0 ; 2*v-1
|
||||
ret
|
||||
|
||||
%endif ; SU_USE_LOAD_VAL
|
||||
185
src/opcodes/sources.inc
Normal file
185
src/opcodes/sources.inc
Normal file
@@ -0,0 +1,185 @@
|
||||
;-------------------------------------------------------------------------------
|
||||
; ENVELOPE structs
|
||||
;-------------------------------------------------------------------------------
|
||||
%assign ENVELOPE_ID -1
|
||||
%macro USE_ENVELOPE 0
|
||||
%if ENVELOPE_ID == -1
|
||||
%assign ENVELOPE_ID CUR_ID
|
||||
%assign CUR_ID CUR_ID + 2
|
||||
%xdefine OPCODES OPCODES MANGLE_FUNC(su_op_envelope,0),
|
||||
%xdefine NUMPARAMS NUMPARAMS 5,
|
||||
%endif
|
||||
%endmacro
|
||||
|
||||
%macro SU_ENVELOPE 6
|
||||
db %2
|
||||
db %3
|
||||
db %4
|
||||
db %5
|
||||
db %6
|
||||
USE_ENVELOPE
|
||||
%xdefine CMDS CMDS ENVELOPE_ID+%1,
|
||||
%if %1 == STEREO
|
||||
%define INCLUDE_STEREO_ENVELOPE
|
||||
%endif
|
||||
%endmacro
|
||||
|
||||
%define ATTAC(val) val
|
||||
%define DECAY(val) val
|
||||
%define SUSTAIN(val) val
|
||||
%define RELEASE(val) val
|
||||
%define GAIN(val) val
|
||||
|
||||
struc su_env_ports
|
||||
.attac resd 1
|
||||
.decay resd 1
|
||||
.sustain resd 1
|
||||
.release resd 1
|
||||
.gain resd 1
|
||||
.params
|
||||
endstruc
|
||||
|
||||
struc su_env_work
|
||||
.state resd 1
|
||||
.level resd 1
|
||||
.size
|
||||
endstruc
|
||||
|
||||
%define ENV_STATE_ATTAC 0
|
||||
%define ENV_STATE_DECAY 1
|
||||
%define ENV_STATE_SUSTAIN 2
|
||||
%define ENV_STATE_RELEASE 3
|
||||
%define ENV_STATE_OFF 4
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; OSCILLAT structs
|
||||
;-------------------------------------------------------------------------------
|
||||
%assign OSCILLAT_ID -1
|
||||
%macro USE_OSCILLAT 0
|
||||
%if OSCILLAT_ID == -1
|
||||
%assign OSCILLAT_ID CUR_ID
|
||||
%assign CUR_ID CUR_ID + 2
|
||||
%xdefine OPCODES OPCODES MANGLE_FUNC(su_op_oscillat,0),
|
||||
%xdefine NUMPARAMS NUMPARAMS 6,
|
||||
%endif
|
||||
%endmacro
|
||||
|
||||
%define SINE 0x40
|
||||
%define TRISAW 0x20
|
||||
%define PULSE 0x10
|
||||
%define LFO 0x08
|
||||
%define GATE 0x04
|
||||
|
||||
%macro SU_OSCILLAT 8
|
||||
db %2
|
||||
db %3
|
||||
db %4
|
||||
db %5
|
||||
db %6
|
||||
db %7
|
||||
db %8
|
||||
USE_OSCILLAT
|
||||
%xdefine CMDS CMDS OSCILLAT_ID + %1,
|
||||
%if %1 == STEREO
|
||||
%define INCLUDE_STEREO_OSCILLAT
|
||||
%endif
|
||||
%if (%8) & SINE == SINE
|
||||
%define INCLUDE_SINE
|
||||
%endif
|
||||
%if (%8) & TRISAW == TRISAW
|
||||
%define INCLUDE_TRISAW
|
||||
%endif
|
||||
%if (%8) & PULSE == PULSE
|
||||
%define INCLUDE_PULSE
|
||||
%endif
|
||||
%if (%8) & GATE == GATE
|
||||
%define INCLUDE_GATE
|
||||
%endif
|
||||
%endmacro
|
||||
|
||||
struc su_osc_ports
|
||||
.transpose resd 1
|
||||
.detune resd 1
|
||||
.phaseofs resd 1
|
||||
.color resd 1
|
||||
.shape resd 1
|
||||
.gain resd 1
|
||||
.params
|
||||
endstruc
|
||||
|
||||
struc su_osc_wrk
|
||||
.phase resd 1
|
||||
.gatestate resd 1
|
||||
.size
|
||||
endstruc
|
||||
|
||||
%define TRANSPOSE(val) val
|
||||
%define DETUNE(val) val
|
||||
%define PHASE(val) val
|
||||
%define GATESLOW(val) val
|
||||
%define GATESHIGH(val) val
|
||||
%define COLOR(val) val
|
||||
%define SHAPE(val) val
|
||||
%define FLAGS(val) val
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; NOISE structs
|
||||
;-------------------------------------------------------------------------------
|
||||
%assign NOISE_ID -1
|
||||
%macro USE_NOISE 0
|
||||
%if NOISE_ID == -1
|
||||
%assign NOISE_ID CUR_ID
|
||||
%assign CUR_ID CUR_ID + 2
|
||||
%xdefine OPCODES OPCODES MANGLE_FUNC(su_op_noise,0),
|
||||
%xdefine NUMPARAMS NUMPARAMS 2,
|
||||
%endif
|
||||
%endmacro
|
||||
|
||||
%macro SU_NOISE 3
|
||||
db %2
|
||||
db %3
|
||||
USE_NOISE
|
||||
%xdefine CMDS CMDS NOISE_ID + %1,
|
||||
%if %1 == STEREO
|
||||
%define INCLUDE_STEREO_NOISE
|
||||
%endif
|
||||
%endmacro
|
||||
|
||||
struc su_noise_ports
|
||||
.shape resd 1
|
||||
.gain resd 1
|
||||
.params
|
||||
endstruc
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; LOAD_VAL structs
|
||||
;-------------------------------------------------------------------------------
|
||||
%assign LOAD_VAL_ID -1
|
||||
%macro USE_LOAD_VAL 0
|
||||
%if LOAD_VAL_ID == -1
|
||||
%assign LOAD_VAL_ID CUR_ID
|
||||
%assign CUR_ID CUR_ID + 2
|
||||
%xdefine OPCODES OPCODES MANGLE_FUNC(su_op_load_val,0),
|
||||
%xdefine NUMPARAMS NUMPARAMS 1,
|
||||
%endif
|
||||
%endmacro
|
||||
|
||||
%macro SU_LOAD_VAL 2
|
||||
db %2
|
||||
USE_LOAD_VAL
|
||||
%xdefine CMDS CMDS LOAD_VAL_ID+%1,
|
||||
%if %1 == STEREO
|
||||
%define INCLUDE_STEREO_LOAD_VAL
|
||||
%endif
|
||||
%endmacro
|
||||
|
||||
%define VALUE(val) val
|
||||
|
||||
struc su_load_val_ports
|
||||
.value resd 1
|
||||
.params
|
||||
endstruc
|
||||
|
||||
struc su_load_val_wrk
|
||||
.size
|
||||
endstruc
|
||||
202
src/player.asm
Normal file
202
src/player.asm
Normal file
@@ -0,0 +1,202 @@
|
||||
;-------------------------------------------------------------------------------
|
||||
; Uninitialized data
|
||||
;-------------------------------------------------------------------------------
|
||||
%ifdef INCLUDE_MULTIVOICE_TRACKS
|
||||
|
||||
SECT_BSS(subss)
|
||||
|
||||
su_current_voiceno resd MAX_TRACKS ; number of the last voice used for each track
|
||||
|
||||
SECT_DATA(suconst)
|
||||
|
||||
su_voicetrack_bitmask dd VOICETRACK_BITMASK; does the following voice belong to the same track
|
||||
|
||||
%endif
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; Constants
|
||||
;-------------------------------------------------------------------------------
|
||||
SECT_DATA(suconst)
|
||||
|
||||
%ifdef SU_USE_16BIT_OUTPUT
|
||||
c_32767 dd 32767.0
|
||||
%endif
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; output_sound macro: used by the render function to write sound to buffer
|
||||
;-------------------------------------------------------------------------------
|
||||
; The macro contains the ifdef hell to handle 16bit output and clipping cases
|
||||
; to keep the main function more readable
|
||||
; Stack : sample row pushad output_ptr
|
||||
;-------------------------------------------------------------------------------
|
||||
%macro output_sound 0
|
||||
%ifndef SU_USE_16BIT_OUTPUT
|
||||
%ifndef SU_CLIP_OUTPUT ; The modern way. No need to clip; OS can do it.
|
||||
mov edi, dword [esp+44] ; edi containts ptr
|
||||
mov esi, su_synth_obj+su_synth.left
|
||||
movsd ; copy left channel to output buffer
|
||||
movsd ; copy right channel to output buffer
|
||||
mov dword [esp+44], edi ; save back the updated ptr
|
||||
lea edi, [esi-8]
|
||||
xor eax,eax
|
||||
stosd ; clear left channel so the VM is ready to write them again
|
||||
stosd ; clear right channel so the VM is ready to write them again
|
||||
%else
|
||||
mov esi, dword [esp+44] ; esi points to the output buffer
|
||||
xor ecx,ecx
|
||||
xor eax,eax
|
||||
%%loop: ; loop over two channels, left & right
|
||||
fld dword [su_synth_obj+su_synth.left+ecx*4]
|
||||
call su_clip
|
||||
fstp dword [esi]
|
||||
mov dword [su_synth_obj+su_synth.left+ecx*4],eax ; clear the sample so the VM is ready to write it
|
||||
add esi,4
|
||||
cmp ecx,2
|
||||
jl %%loop
|
||||
mov dword [esp+44], esi ; save esi back to stack
|
||||
%endif
|
||||
%else ; 16-bit output, always clipped. This is a bit legacy method.
|
||||
mov esi, dword [esp+44] ; esi points to the output buffer
|
||||
mov edi, su_synth_obj+su_synth.left
|
||||
mov ecx, 2
|
||||
%%loop: ; loop over two channels, left & right
|
||||
fld dword [edi]
|
||||
call MANGLE_FUNC(su_clip_op,0)
|
||||
fmul dword [c_32767]
|
||||
push eax
|
||||
fistp dword [esp]
|
||||
pop eax
|
||||
mov word [esi],ax ; // store integer converted right sample
|
||||
xor eax,eax
|
||||
stosd
|
||||
add esi,2
|
||||
loop %%loop
|
||||
mov dword [esp+44], esi ; save esi back to stack
|
||||
%endif
|
||||
%endmacro
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; su_render function: the entry point for the synth
|
||||
;-------------------------------------------------------------------------------
|
||||
; Has the signature su_render(void *ptr), where ptr is a pointer to
|
||||
; the output buffer
|
||||
; Stack: output_ptr
|
||||
;-------------------------------------------------------------------------------
|
||||
SECT_TEXT(surender)
|
||||
|
||||
EXPORT MANGLE_FUNC(su_render,4) ; Stack: ptr
|
||||
pushad ; Stack: pushad ptr
|
||||
xor eax, eax ; ecx is the current row
|
||||
su_render_rowloop: ; loop through every row in the song
|
||||
push eax ; Stack: row pushad ptr
|
||||
call su_update_voices ; update instruments for the new row
|
||||
xor eax, eax ; ecx is the current sample within row
|
||||
su_render_sampleloop: ; loop through every sample in the row
|
||||
push eax ; Stack: sample row pushad ptr
|
||||
call MANGLE_FUNC(su_run_vm,0) ; run through the VM code
|
||||
output_sound ; *ptr++ = left, *ptr++ = right
|
||||
pop eax ; Stack: row pushad ptr
|
||||
inc eax
|
||||
cmp eax, SAMPLES_PER_ROW
|
||||
jl su_render_sampleloop
|
||||
pop eax ; Stack: pushad ptr
|
||||
inc eax
|
||||
cmp eax, TOTAL_ROWS
|
||||
jl su_render_rowloop
|
||||
popad ; Stack: ptr
|
||||
ret 4 ; Stack emptied by ret
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; su_update_voices function: polyphonic & chord implementation
|
||||
;-------------------------------------------------------------------------------
|
||||
; Input: eax : current row within song
|
||||
; Dirty: pretty much everything
|
||||
;-------------------------------------------------------------------------------
|
||||
SECT_TEXT(suupdvce)
|
||||
|
||||
%ifdef INCLUDE_MULTIVOICE_TRACKS
|
||||
|
||||
su_update_voices: ; Stack: retaddr row
|
||||
xor edx, edx
|
||||
mov ebx, PATTERN_SIZE
|
||||
div ebx ; eax = current pattern, edx = current row in pattern
|
||||
lea esi, [MANGLE_DATA(su_tracks)+eax] ; esi points to the pattern data for current track
|
||||
xor eax, eax ; eax is the first voice of next track
|
||||
xor ebx, ebx ; ebx is the first voice of current track
|
||||
xor ebp, ebp ; ebp is the current track being processed
|
||||
su_update_voices_trackloop:
|
||||
movzx eax, byte [esi] ; eax = current pattern
|
||||
imul eax, PATTERN_SIZE ; eax = offset to current pattern data
|
||||
movzx eax, byte [MANGLE_DATA(su_patterns)+eax+edx] ; eax = note
|
||||
push edx ; Stack: ptrnrow
|
||||
xor edx, edx ; edx=0
|
||||
mov ecx, ebx ; ecx=first voice of the track to be done
|
||||
su_calculate_voices_loop: ; do {
|
||||
bt dword [su_voicetrack_bitmask],ecx ; // notice that the incs don't set carry
|
||||
inc edx ; edx++ // edx=numvoices
|
||||
inc ecx ; ecx++ // ecx=the first voice of next track
|
||||
jc su_calculate_voices_loop ; } while bit ecx-1 of bitmask is on
|
||||
push ecx ; Stack: next_instr ptrnrow
|
||||
cmp al, HLD ; anything but hold causes action
|
||||
je short su_update_voices_nexttrack
|
||||
mov ecx, dword [su_current_voiceno+ebp*4]
|
||||
mov edi, ecx
|
||||
add edi, ebx
|
||||
imul edi, edi, su_voice.size
|
||||
mov dword [su_synth_obj+su_synth.voices+edi+su_voice.release],1 ; set the voice currently active to release
|
||||
cmp al, HLD ; if cl < HLD (no new note triggered)
|
||||
jl su_update_voices_nexttrack ; goto nexttrack
|
||||
inc ecx ; curvoice++
|
||||
cmp ecx, edx ; if (curvoice >= num_voices)
|
||||
jl su_update_voices_skipreset
|
||||
xor ecx,ecx ; curvoice = 0
|
||||
su_update_voices_skipreset:
|
||||
mov dword [su_current_voiceno+ebp*4],ecx
|
||||
add ecx, ebx
|
||||
imul ecx, ecx, su_voice.size
|
||||
lea edi, [su_synth_obj+su_synth.voices+ecx]
|
||||
stosd ; save note
|
||||
mov ecx, (su_voice.size - su_voice.release)/4
|
||||
xor eax, eax
|
||||
rep stosd ; clear the workspace of the new voice, retriggering oscillators
|
||||
su_update_voices_nexttrack:
|
||||
pop ebx ; ebx=first voice of next instrument, Stack: ptrnrow
|
||||
pop edx ; edx=patrnrow
|
||||
add esi, MAX_PATTERNS
|
||||
inc ebp
|
||||
cmp ebp, MAX_TRACKS
|
||||
jl short su_update_voices_trackloop
|
||||
ret
|
||||
|
||||
%else ; INCLUDE_MULTIVOICE_TRACKS not defined -> one voice per track version
|
||||
|
||||
su_update_voices: ; Stack: retaddr row
|
||||
xor edx, edx
|
||||
mov ebx, PATTERN_SIZE
|
||||
div ebx ; eax = current pattern, edx = current row in pattern
|
||||
lea esi, [MANGLE_DATA(su_tracks)+eax] ; esi points to the pattern data for current track
|
||||
lea edi, [su_synth_obj+su_synth.voices]
|
||||
mov ebp, MAX_TRACKS
|
||||
su_update_voices_trackloop:
|
||||
movzx eax, byte [esi] ; eax = current pattern
|
||||
imul eax, PATTERN_SIZE ; eax = offset to current pattern data
|
||||
movzx eax, byte [MANGLE_DATA(su_patterns)+eax+edx] ; ecx = note
|
||||
cmp al, HLD ; anything but hold causes action
|
||||
je short su_update_voices_nexttrack
|
||||
mov dword [edi+su_voice.release],1 ; set the voice currently active to release
|
||||
jl su_update_voices_nexttrack ; if cl < HLD (no new note triggered) goto nexttrack
|
||||
su_update_voices_retrigger:
|
||||
stosd ; save note
|
||||
mov ecx, (su_voice.size - su_voice.release)/4
|
||||
xor eax, eax
|
||||
rep stosd ; clear the workspace of the new voice, retriggering oscillators
|
||||
jmp short su_update_voices_skipadd
|
||||
su_update_voices_nexttrack:
|
||||
add edi, su_voice.size
|
||||
su_update_voices_skipadd:
|
||||
add esi, MAX_PATTERNS
|
||||
dec ebp
|
||||
jnz short su_update_voices_trackloop
|
||||
ret
|
||||
|
||||
%endif ;INCLUDE_MULTIVOICE_TRACKS
|
||||
4
src/playerosx/.gitignore
vendored
4
src/playerosx/.gitignore
vendored
@@ -1,4 +0,0 @@
|
||||
4klangrender
|
||||
4klang.asm
|
||||
4klang.inc
|
||||
4klang.o
|
||||
@@ -1,33 +0,0 @@
|
||||
#include <stdio.h>
|
||||
|
||||
extern void _4klang_render(void*) __attribute__ ((stdcall));
|
||||
extern int _4klang_current_tick;
|
||||
|
||||
#define SAMPLE_RATE 44100
|
||||
#define MAX_INSTRUMENTS 9
|
||||
#define MAX_VOICES 1
|
||||
#define HLD 1 ; // can be adjusted to give crinkler some other possibilities
|
||||
#define BPM 100
|
||||
#define MAX_PATTERNS 62
|
||||
#define PATTERN_SIZE_SHIFT 4
|
||||
#define PATTERN_SIZE (1 << PATTERN_SIZE_SHIFT)
|
||||
#define MAX_TICKS (MAX_PATTERNS*PATTERN_SIZE)
|
||||
#define SAMPLES_PER_TICK (SAMPLE_RATE*4*60/(BPM*16))
|
||||
#define DEF_LFO_NORMALIZE 0.000038
|
||||
#define MAX_SAMPLES (SAMPLES_PER_TICK*MAX_TICKS)
|
||||
|
||||
float buf[SAMPLES_PER_TICK * 2];
|
||||
|
||||
int main() {
|
||||
FILE *fp;
|
||||
|
||||
_4klang_current_tick = 0;
|
||||
|
||||
fp = fdopen(fileno(stdout), "wb");
|
||||
for(int n=0;n<MAX_TICKS;n++) {
|
||||
fprintf(stderr,"\nRender %d %d\n",n,_4klang_current_tick);
|
||||
_4klang_render(buf);
|
||||
fwrite(buf, sizeof(buf), 1, fp);
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
# 4klang rendering example for Mac OSX
|
||||
|
||||
In here you'll find `4klangrender.c` which will call the `4klang.asm` library and render one tick
|
||||
at the time (using the `AUTHORING` flag in `4klang.inc`).
|
||||
|
||||
The `runosx.sh` shell script contains the commands to compile the asm and link with the c example code, and create
|
||||
an executable that will ouput a stream of 32 bit floating point samples. By piping into [SOX](http://sox.sourceforge.net/) we'll get sound output.
|
||||
|
||||
You also need [YASM](http://yasm.tortall.net/) and gcc (XCode) installed, and if everything is right you should get sound output by simply typing in your terminal (from this folder):
|
||||
|
||||
`sh runosx.sh`
|
||||
@@ -1,9 +0,0 @@
|
||||
echo "Copying 4klang.asm and 4klang.inc from parent dir"
|
||||
echo "Enabling SINGLE_TICK_RENDERING (and AUTHORING) flag for rendering example"
|
||||
echo "You need sox installed to get audio output"
|
||||
sed -e 's/\;\%define SINGLE_TICK_RENDERING/\%define SINGLE_TICK_RENDERING/' ../4klang.inc | \
|
||||
sed -e 's/\;\%define AUTHORING/\%define AUTHORING/' > 4klang.inc
|
||||
cp ../4klang.asm .
|
||||
yasm -f macho 4klang.asm
|
||||
gcc -Wl,-no_pie -m32 4klang.o 4klangrender.c -o 4klangrender
|
||||
./4klangrender | sox -t raw -b 32 -e float -r 44100 -c 2 - -d
|
||||
194
src/sointu.asm
Normal file
194
src/sointu.asm
Normal file
@@ -0,0 +1,194 @@
|
||||
%define WRK ebp ; // alias for unit workspace
|
||||
%define VAL esi ; // alias for unit values (transformed/untransformed)
|
||||
%define COM ebx ; // alias for instrument opcodes
|
||||
|
||||
;===============================================================================
|
||||
; Uninitialized data: The one and only synth object
|
||||
;===============================================================================
|
||||
SECT_BSS(susynth)
|
||||
|
||||
su_synth_obj resb su_synth.size
|
||||
su_transformed_values resd 16
|
||||
|
||||
;===============================================================================
|
||||
; The opcode table jump table. This is constructed to only include the opcodes
|
||||
; that are used so that the jump table is as small as possible.
|
||||
;===============================================================================
|
||||
SECT_DATA(suoptabl)
|
||||
|
||||
su_synth_commands
|
||||
dd OPCODES
|
||||
|
||||
;===============================================================================
|
||||
; The number of transformed parameters each opcode takes
|
||||
;===============================================================================
|
||||
SECT_DATA(suparcnt)
|
||||
|
||||
su_opcode_numparams
|
||||
db NUMPARAMS
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; Constants used by the common functions
|
||||
;-------------------------------------------------------------------------------
|
||||
SECT_DATA(suconst)
|
||||
|
||||
c_i128 dd 0.0078125
|
||||
c_RandDiv dd 65536*32768
|
||||
c_0_5 dd 0.5
|
||||
EXPORT MANGLE_DATA(RandSeed)
|
||||
dd 1
|
||||
c_24 dd 24
|
||||
c_i12 dd 0x3DAAAAAA
|
||||
EXPORT MANGLE_DATA(LFO_NORMALIZE)
|
||||
dd DEF_LFO_NORMALIZE
|
||||
|
||||
%ifdef INCLUDE_POLYPHONY
|
||||
su_polyphony_bitmask dd POLYPHONY_BITMASK ; does the next voice reuse the current opcodes?
|
||||
%endif
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; su_run_vm function: runs the entire virtual machine once, creating 1 sample
|
||||
;-------------------------------------------------------------------------------
|
||||
; Input: su_synth_obj.left : Set to 0 before calling
|
||||
; su_synth_obj.right : Set to 0 before calling
|
||||
; Output: su_synth_obj.left : left sample
|
||||
; su_synth_obj.right : right sample
|
||||
; Dirty: everything
|
||||
;-------------------------------------------------------------------------------
|
||||
SECT_TEXT(surunvm)
|
||||
|
||||
EXPORT MANGLE_FUNC(su_run_vm,0)
|
||||
mov COM, MANGLE_DATA(su_commands) ; COM points to vm code
|
||||
mov VAL, MANGLE_DATA(su_params) ; VAL points to unit params
|
||||
; su_unit.size will be added back before WRK is used
|
||||
mov WRK, su_synth_obj + su_synth.voices + su_voice.workspace - su_unit.size
|
||||
push COM ; Stack: COM
|
||||
push VAL ; Stack: VAL COM
|
||||
push WRK ; Stack: WRK VAL COM
|
||||
%if DELAY_ID > -1
|
||||
mov ecx, MANGLE_DATA(su_delay_buffer) ; reset delaywrk to first delayline
|
||||
mov dword [MANGLE_DATA(su_delay_buffer_ofs)], ecx
|
||||
%endif
|
||||
xor ecx, ecx ; voice = 0
|
||||
push ecx ; Stack: voice WRK VAL COM
|
||||
su_run_vm_loop: ; loop until all voices done
|
||||
movzx eax, byte [COM] ; eax = command byte
|
||||
inc COM ; move to next instruction
|
||||
add WRK, su_unit.size ; move WRK to next unit
|
||||
push eax
|
||||
shr eax,1
|
||||
mov al,byte [eax+su_opcode_numparams]
|
||||
push eax
|
||||
call su_transform_values
|
||||
mov ecx, dword [esp+8]
|
||||
pop eax
|
||||
shr eax,1
|
||||
call dword [eax*4+su_synth_commands] ; call the function corresponding to the instruction
|
||||
cmp dword [esp],MAX_VOICES ; if (voice < MAX_VOICES)
|
||||
jl su_run_vm_loop ; goto vm_loop
|
||||
add esp, 16 ; Stack cleared
|
||||
ret
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; FloatRandomNumber function
|
||||
;-------------------------------------------------------------------------------
|
||||
; Output: st0 : result
|
||||
;-------------------------------------------------------------------------------
|
||||
SECT_TEXT(surandom)
|
||||
|
||||
EXPORT MANGLE_FUNC(FloatRandomNumber,0)
|
||||
push eax
|
||||
imul eax,dword [MANGLE_DATA(RandSeed)],16007
|
||||
mov dword [MANGLE_DATA(RandSeed)], eax
|
||||
fild dword [MANGLE_DATA(RandSeed)]
|
||||
fidiv dword [c_RandDiv]
|
||||
pop eax
|
||||
ret
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; su_transform_values function: transforms values and adds modulations
|
||||
;-------------------------------------------------------------------------------
|
||||
; Input: [esp] : number of bytes to transform
|
||||
; VAL : pointer to byte stream
|
||||
; Output: eax : last transformed byte (zero extended)
|
||||
; edx : pointer to su_transformed_values, containing
|
||||
; each byte transformed as x/128.0f+modulations
|
||||
; VAL : updated to point after the transformed bytes
|
||||
;-------------------------------------------------------------------------------
|
||||
SECT_TEXT(sutransf)
|
||||
|
||||
su_transform_values:
|
||||
push ecx
|
||||
xor ecx, ecx
|
||||
xor eax, eax
|
||||
mov edx, su_transformed_values
|
||||
su_transform_values_loop:
|
||||
cmp ecx, dword [esp+8]
|
||||
jge su_transform_values_out
|
||||
lodsb
|
||||
push eax
|
||||
fild dword [esp]
|
||||
fmul dword [c_i128]
|
||||
fadd dword [WRK+su_unit.ports+ecx*4]
|
||||
fstp dword [edx+ecx*4]
|
||||
mov dword [WRK+su_unit.ports+ecx*4], 0
|
||||
pop eax
|
||||
inc ecx
|
||||
jmp su_transform_values_loop
|
||||
su_transform_values_out:
|
||||
pop ecx
|
||||
ret 4
|
||||
|
||||
%macro TRANSFORM_VALUES 1
|
||||
push %1 %+ .params/4
|
||||
call su_transform_values
|
||||
%endmacro
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; su_env_map function: computes 2^(-24*x) of the envelope parameter
|
||||
;-------------------------------------------------------------------------------
|
||||
; Input: eax : envelope parameter (0 = attac, 1 = decay...)
|
||||
; edx : pointer to su_transformed_values
|
||||
; Output: st0 : 2^(-24*x), where x is the parameter in the range 0-1
|
||||
;-------------------------------------------------------------------------------
|
||||
SECT_TEXT(supower)
|
||||
|
||||
%if ENVELOPE_ID > -1
|
||||
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
|
||||
fchs ; -24*x
|
||||
; flow into Power function, which outputs 2^(-24*x)
|
||||
%endif
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; su_power function: computes 2^x
|
||||
;-------------------------------------------------------------------------------
|
||||
; Input: st0 : x
|
||||
; Output: st0 : 2^x
|
||||
;-------------------------------------------------------------------------------
|
||||
EXPORT MANGLE_FUNC(su_power,0)
|
||||
fld1 ; 1 x
|
||||
fld st1 ; x 1 x
|
||||
fprem ; mod(x,1) 1 x
|
||||
f2xm1 ; 2^mod(x,1)-1 1 x
|
||||
faddp st1,st0 ; 2^mod(x,1) x
|
||||
fscale ; 2^mod(x,1)*2^trunc(x) x
|
||||
; Equal to:
|
||||
; 2^x x
|
||||
fstp st1 ; 2^x
|
||||
ret
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; Include the rest of the code
|
||||
;-------------------------------------------------------------------------------
|
||||
%include "opcodes/arithmetic.asm"
|
||||
%include "opcodes/flowcontrol.asm"
|
||||
%include "opcodes/sources.asm"
|
||||
%include "opcodes/sinks.asm"
|
||||
; warning: at the moment effects has to be assembled after
|
||||
; sources, as sources.asm defines SU_USE_WAVESHAPER
|
||||
; if needed.
|
||||
%include "opcodes/effects.asm"
|
||||
%include "player.asm"
|
||||
%include "introspection.asm"
|
||||
296
src/sointu.inc
Normal file
296
src/sointu.inc
Normal file
@@ -0,0 +1,296 @@
|
||||
%ifndef SOINTU_INC
|
||||
%define SOINTU_INC
|
||||
|
||||
; Following defines have to be defined before this include:
|
||||
; MAX_TRACKS e.g. %define MAX_TRACKS 10
|
||||
; BPM e.g. %define BPM 100
|
||||
; MAX_PATTERNS e.g. %define MAX_PATTERNS 1
|
||||
; MAX_VOICES e.g. %define MAX_VOICES 4 <- e.g. 4 instruments or 1 polyphonic instrument with 4 voices
|
||||
;
|
||||
; Optionally:
|
||||
; PATTERN_SIZE e.g. %define PATTERN_SIZE 16 <- this is the default
|
||||
|
||||
%macro EXPORT 1
|
||||
global %1
|
||||
%1
|
||||
%endmacro
|
||||
|
||||
%ifidn __OUTPUT_FORMAT__,win32
|
||||
; on win32, function f with n parameters is mangled as "_f@n"
|
||||
%define MANGLE_FUNC(f,n) _ %+ f %+ @ %+ n
|
||||
%define WIN_OR_MAC
|
||||
%endif
|
||||
|
||||
%ifidn __OUTPUT_FORMAT__,elf32
|
||||
; on linux, function f with n parameters is mangled as "f"
|
||||
%define MANGLE_FUNC(f,n) f
|
||||
%endif
|
||||
|
||||
%ifidn __OUTPUT_FORMAT__,macho32
|
||||
; on mac, function f with x parameters is mangled as "_f"
|
||||
%define MANGLE_FUNC(f,n) _f
|
||||
%define WIN_OR_MAC
|
||||
%endif
|
||||
|
||||
%ifdef WIN_OR_MAC
|
||||
; Windows has crinkler so one may USE_SECTIONS to put everything in custom sections to aid crinkler.
|
||||
; Maybe mac users need it too
|
||||
%ifdef USE_SECTIONS
|
||||
%define SECT_BSS(n) section . %+ n bss align=1
|
||||
%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=1
|
||||
%define SECT_DATA(n) section .data align=1
|
||||
%define SECT_TEXT(n) section .code align=1
|
||||
%endif
|
||||
; On windows and mac, data label d is mangled as "_d"
|
||||
%define MANGLE_DATA(d) _ %+ d
|
||||
%else
|
||||
; Linux
|
||||
%ifdef USE_SECTIONS
|
||||
%define SECT_BSS(n) section .bss. %+ n nobits alloc noexec write align=1
|
||||
%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=1
|
||||
%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
|
||||
; On linux, data label d is mangled as "d"
|
||||
%define MANGLE_DATA(d) d
|
||||
%endif
|
||||
|
||||
%ifdef SU_USE_ALL
|
||||
; SU_USE_ALL is convenience way to enable almost all features of the synth, for vsti plugins and such which
|
||||
; do not have any size constraints. However, SU_USE_ALL should only enable features that absolutely do not
|
||||
; change the functioning of the synth in any way, just add features. Clipping, 16 bit output etc. should still
|
||||
; be enabled only whent they are actually needed
|
||||
|
||||
; Things that are NOT defined by SU_USE_ALL
|
||||
;%define SU_USE_16BIT_OUTPUT ; // removing this will output to 32bit floating point buffer
|
||||
;%define SU_USE_GROOVE_PATTERN ; // removing this skips groove pattern code
|
||||
;%define SU_USE_ENVELOPE_RECORDINGS ; // removing this skips envelope recording code
|
||||
;%define SU_USE_NOTE_RECORDINGS ; // removing this skips note recording code
|
||||
;%define SU_USE_UNDENORMALIZE ; // removing this skips denormalization code in the units
|
||||
;%define SU_CLIP_OUTPUT ; // removing this skips clipping code for the final output
|
||||
|
||||
%define SU_USE_DST ; // removing this will skip DST unit
|
||||
%define SU_USE_DLL ; // removing this will skip DLL unit
|
||||
%define SU_USE_PAN ; // removing this will skip PAN unit
|
||||
%define SU_USE_GLOBAL_DLL ; // removing this will skip global dll processing
|
||||
%define SU_USE_FSTG ; // removing this will skip global store unit
|
||||
%define SU_USE_FLD ; // removing this will skip float load unit
|
||||
%define SU_USE_GLITCH ; // removing this will skip GLITCH unit
|
||||
%define SU_USE_ENV_CHECK ; // removing this skips checks if processing is needed
|
||||
%define SU_USE_VCO_CHECK ; // removing this skips checks if processing is needed
|
||||
%define SU_USE_VCO_PHASE_OFFSET ; // removing this will skip initial phase offset code
|
||||
%define SU_USE_VCO_SHAPE ; // removing this skips waveshaping code
|
||||
%define SU_USE_VCO_GATE ; // removing this skips gate code
|
||||
%define SU_USE_VCO_MOD_FM ; // removing this skips frequency modulation code
|
||||
%define SU_USE_VCO_MOD_DM ; // removing this skips detune modulation code
|
||||
%define SU_USE_VCO_STEREO ; // removing this skips stereo code
|
||||
%define SU_USE_VCF_CHECK ; // removing this skips checks if processing is needed
|
||||
%define SU_USE_VCF_HIGH ; // removing this skips code for high output
|
||||
%define SU_USE_VCF_BAND ; // removing this skips code for band output
|
||||
%define SU_USE_VCF_PEAK ; // removing this skips code for peak output
|
||||
%define SU_USE_VCF_STEREO ; // removing this skips code for stereo filter output
|
||||
%define SU_USE_DST_CHECK ; // removing this skips checks if processing is needed
|
||||
%define SU_USE_DST_SH ; // removing this skips sample and hold code
|
||||
%define SU_USE_DST_STEREO ; // removing this skips stereo processing
|
||||
%define SU_USE_DLL_NOTE_SYNC ; // removing this will skip delay length adjusting code (karplus strong)
|
||||
%define SU_USE_DLL_CHORUS ; // removing this will skip delay chorus/flanger code
|
||||
%define SU_USE_DLL_CHORUS_CLAMP ; // removing this will skip chorus lfo phase clamping
|
||||
%define SU_USE_DLL_DAMP ; // removing this will skip dll damping code
|
||||
%define SU_USE_DLL_DC_FILTER ; // removing this will skip dll dc offset removal code
|
||||
%define SU_USE_FSTG_CHECK ; // removing this skips checks if processing is needed
|
||||
%define SU_USE_WAVESHAPER_CLIP ; // removing this will skip clipping code
|
||||
%endif
|
||||
|
||||
%ifdef SU_USE_VCO_SHAPE
|
||||
%define INCLUDE_WAVESHAPER
|
||||
%endif
|
||||
%ifdef SU_USE_DST
|
||||
%define INCLUDE_WAVESHAPER
|
||||
%endif
|
||||
%ifdef SU_USE_16BIT_OUTPUT
|
||||
%define SU_INCLUDE_CLIP
|
||||
%endif
|
||||
|
||||
;%include "opcodes/flowcontrol.inc"
|
||||
|
||||
%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 MONO 0
|
||||
%define STEREO 1
|
||||
|
||||
%include "opcodes/arithmetic.inc"
|
||||
%include "opcodes/effects.inc"
|
||||
%include "opcodes/sources.inc"
|
||||
%include "opcodes/sinks.inc"
|
||||
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // synth defines
|
||||
; //----------------------------------------------------------------------------------------
|
||||
|
||||
%define MAX_DELAY 65536
|
||||
%define MAX_UNITS 64
|
||||
%define ABSOLUTE_MAX_VOICES 32
|
||||
|
||||
%ifndef SAMPLE_RATE
|
||||
%define SAMPLE_RATE 44100
|
||||
%endif
|
||||
|
||||
%ifndef HLD
|
||||
%define HLD 1
|
||||
%endif
|
||||
|
||||
%define TOTAL_ROWS (MAX_PATTERNS*PATTERN_SIZE)
|
||||
%define SAMPLES_PER_ROW (SAMPLE_RATE*4*60/(BPM*16))
|
||||
%define DEF_LFO_NORMALIZE 0.000038
|
||||
%define MAX_SAMPLES (SAMPLES_PER_ROW*TOTAL_ROWS)
|
||||
|
||||
%macro SU_BEGIN_PATCH 0
|
||||
SECT_DATA(params)
|
||||
|
||||
EXPORT MANGLE_DATA(su_params)
|
||||
%endmacro
|
||||
|
||||
%macro SU_END_PATCH 0 ; After the patch is finished, saves the accumulated commands
|
||||
SECT_DATA(sucomnds)
|
||||
|
||||
EXPORT MANGLE_DATA(su_commands)
|
||||
db CMDS
|
||||
%endmacro
|
||||
|
||||
%define CONCATENATE(x,y) x %+ y
|
||||
%define POLYPHONY_BITMASK 0
|
||||
%assign MAX_VOICES 0
|
||||
%assign MAX_TRACKS 0
|
||||
%macro SU_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 << MAX_VOICES)
|
||||
%assign MAX_VOICES MAX_VOICES + 1
|
||||
%endrep
|
||||
%assign MAX_VOICES MAX_VOICES + 1 ; the last voice increment, without adding bit 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 SU_END_INSTRUMENT 0
|
||||
%xdefine CMDS CMDS SU_ADVANCE_ID,
|
||||
%endmacro
|
||||
|
||||
%assign PATTERN_LENGTH -1
|
||||
%macro SU_BEGIN_PATTERNS 0
|
||||
SECT_DATA(supatrns)
|
||||
|
||||
EXPORT MANGLE_DATA(su_patterns)
|
||||
%define USE_PLAYER
|
||||
%endmacro
|
||||
|
||||
%define SU_END_PATTERNS
|
||||
|
||||
%assign PATTERN_SIZE -1
|
||||
%macro PATTERN 1-*
|
||||
%rep %0
|
||||
db %1
|
||||
%rotate 1
|
||||
%endrep
|
||||
%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 SU_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 SU_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
|
||||
.track resd 1
|
||||
.workspace resb MAX_UNITS * su_unit.size
|
||||
.size
|
||||
endstruc
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // Synth struct
|
||||
; //----------------------------------------------------------------------------------------
|
||||
struc su_synth
|
||||
.left resd 1
|
||||
.right resd 1
|
||||
.voices resb ABSOLUTE_MAX_VOICES * su_voice.size
|
||||
.size
|
||||
endstruc
|
||||
|
||||
%endif ; SOINTU_INC
|
||||
@@ -1,457 +0,0 @@
|
||||
%define MAX_INSTRUMENTS 9
|
||||
%define MAX_VOICES 1
|
||||
%define HLD 1 ; // can be adjusted to give crinkler some other possibilities
|
||||
%define BPM 100
|
||||
%define MAX_PATTERNS 62
|
||||
%define SINGLE_FILE
|
||||
%define USE_SECTIONS
|
||||
%define GO4K_USE_UNDENORMALIZE ; // removing this skips denormalization code in the units
|
||||
%define GO4K_CLIP_OUTPUT ; // removing this skips clipping code for the final output
|
||||
%define GO4K_USE_DST ; // removing this will skip DST unit
|
||||
%define GO4K_USE_DLL ; // removing this will skip DLL unit
|
||||
%define GO4K_USE_PAN ; // removing this will skip PAN unit
|
||||
%define GO4K_USE_GLOBAL_DLL ; // removing this will skip global dll processing
|
||||
%define GO4K_USE_FSTG ; // removing this will skip global store unit
|
||||
%define GO4K_USE_FLD ; // removing this will skip float load unit
|
||||
%define GO4K_USE_GLITCH ; // removing this will skip GLITCH unit
|
||||
%define GO4K_USE_ENV_CHECK ; // removing this skips checks if processing is needed
|
||||
%define GO4K_USE_ENV_MOD_GM ; // removing this will skip env gain modulation code
|
||||
%define GO4K_USE_ENV_MOD_ADR ; // removing this will skip env attack/decay/release modulation code
|
||||
%define GO4K_USE_VCO_CHECK ; // removing this skips checks if processing is needed
|
||||
%define GO4K_USE_VCO_PHASE_OFFSET ; // removing this will skip initial phase offset code
|
||||
%define GO4K_USE_VCO_SHAPE ; // removing this skips waveshaping code
|
||||
%define GO4K_USE_VCO_GATE ; // removing this skips gate code
|
||||
%define GO4K_USE_VCO_MOD_FM ; // removing this skips frequency modulation code
|
||||
%define GO4K_USE_VCO_MOD_PM ; // removing this skips phase modulation code
|
||||
%define GO4K_USE_VCO_MOD_TM ; // removing this skips transpose modulation code
|
||||
%define GO4K_USE_VCO_MOD_DM ; // removing this skips detune modulation code
|
||||
%define GO4K_USE_VCO_MOD_CM ; // removing this skips color modulation code
|
||||
%define GO4K_USE_VCO_MOD_GM ; // removing this skips gain modulation code
|
||||
%define GO4K_USE_VCO_MOD_SM ; // removing this skips shaping modulation code
|
||||
%define GO4K_USE_VCO_STEREO ; // removing this skips stereo code
|
||||
%define GO4K_USE_VCF_CHECK ; // removing this skips checks if processing is needed
|
||||
%define GO4K_USE_VCF_MOD_FM ; // removing this skips frequency modulation code
|
||||
%define GO4K_USE_VCF_MOD_RM ; // removing this skips resonance modulation code
|
||||
%define GO4K_USE_VCF_HIGH ; // removing this skips code for high output
|
||||
%define GO4K_USE_VCF_BAND ; // removing this skips code for band output
|
||||
%define GO4K_USE_VCF_PEAK ; // removing this skips code for peak output
|
||||
%define GO4K_USE_VCF_STEREO ; // removing this skips code for stereo filter output
|
||||
%define GO4K_USE_DST_CHECK ; // removing this skips checks if processing is needed
|
||||
%define GO4K_USE_DST_SH ; // removing this skips sample and hold code
|
||||
%define GO4K_USE_DST_MOD_DM ; // removing this skips distortion modulation code
|
||||
%define GO4K_USE_DST_MOD_SH ; // removing this skips sample and hold modulation code
|
||||
%define GO4K_USE_DST_STEREO ; // removing this skips stereo processing
|
||||
%define GO4K_USE_DLL_NOTE_SYNC ; // removing this will skip delay length adjusting code (karplus strong)
|
||||
%define GO4K_USE_DLL_CHORUS ; // removing this will skip delay chorus/flanger code
|
||||
%define GO4K_USE_DLL_CHORUS_CLAMP ; // removing this will skip chorus lfo phase clamping
|
||||
%define GO4K_USE_DLL_DAMP ; // removing this will skip dll damping code
|
||||
%define GO4K_USE_DLL_DC_FILTER ; // removing this will skip dll dc offset removal code
|
||||
%define GO4K_USE_FSTG_CHECK ; // removing this skips checks if processing is needed
|
||||
%define GO4K_USE_PAN_MOD ; // removing this will skip panning modulation code
|
||||
%define GO4K_USE_OUT_MOD_AM ; // removing this skips output aux send modulation code
|
||||
%define GO4K_USE_OUT_MOD_GM ; // removing this skips output gain modulation code
|
||||
%define GO4K_USE_WAVESHAPER_CLIP ; // removing this will skip clipping code
|
||||
%define GO4K_USE_FLD_MOD_VM ; // removing this will skip float load modulation code
|
||||
%define GO4K_USE_DLL_MOD ; // define this to enable modulations for delay line
|
||||
%define GO4K_USE_DLL_MOD_PM ; // define this to enable pregain modulation for delay line
|
||||
%define GO4K_USE_DLL_MOD_FM ; // define this to enable feebback modulation for delay line
|
||||
%define GO4K_USE_DLL_MOD_IM ; // define this to enable dry modulation for delay line
|
||||
%define GO4K_USE_DLL_MOD_DM ; // define this to enable damping modulation for delay line
|
||||
%define GO4K_USE_DLL_MOD_SM ; // define this to enable lfo freq modulation for delay line
|
||||
%define GO4K_USE_DLL_MOD_AM ; // define this to enable lfo depth modulation for delay line
|
||||
|
||||
%include "../4klang.asm"
|
||||
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // Pattern Data, reduced by 967 patterns
|
||||
; //----------------------------------------------------------------------------------------
|
||||
SECT_DATA(g4kmuc1)
|
||||
|
||||
EXPORT MANGLE_DATA(go4k_patterns)
|
||||
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
db 76, HLD, HLD, HLD, 0, 0, 0, 0, 79, HLD, HLD, HLD, 0, 0, 0, 0,
|
||||
db 69, HLD, HLD, HLD, HLD, HLD, HLD, HLD, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
db 76, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD,
|
||||
db 81, HLD, HLD, HLD, 0, 0, 0, 0, 79, HLD, HLD, HLD, 0, 0, 0, 0,
|
||||
db 84, HLD, HLD, HLD, HLD, HLD, HLD, HLD, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
db 76, HLD, HLD, HLD, 0, 0, 0, 0, 88, HLD, HLD, HLD, HLD, HLD, HLD, HLD,
|
||||
db HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, 0, 0, 0, 0,
|
||||
db 76, HLD, HLD, HLD, HLD, HLD, HLD, HLD, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
db 52, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD,
|
||||
db 57, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD,
|
||||
db 60, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD,
|
||||
db 64, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD,
|
||||
db 69, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD,
|
||||
db 72, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD,
|
||||
db 40, 52, HLD, 64, HLD, 40, 52, 64, 52, HLD, HLD, HLD, 0, 0, 0, 0,
|
||||
db 57, 0, 0, 57, 0, 0, 69, 0, 0, 69, 0, 0, 57, HLD, HLD, HLD,
|
||||
db 52, 64, 0, 57, 0, 69, 48, 0, 48, HLD, HLD, HLD, 0, 0, 0, 0,
|
||||
db 40, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD,
|
||||
db 40, 52, HLD, 40, HLD, 40, 40, 40, 52, HLD, HLD, HLD, 0, 0, 0, 0,
|
||||
db 40, 0, 0, 52, 0, 0, 40, 0, 52, 40, 0, 52, 0, 40, 0, 0,
|
||||
db 45, 0, 0, 57, 0, 0, 45, 0, 57, 45, 0, 57, 0, 45, 0, 0,
|
||||
db 48, 0, 0, 60, 0, 0, 48, 0, 60, 48, 0, 60, 0, 48, 0, 0,
|
||||
db 40, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, 0, 0, 0, 0,
|
||||
db 45, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, 0, 0, 0, 0,
|
||||
db 36, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, 0, 0, 0, 0,
|
||||
db 0, 0, 0, 0, 60, HLD, 0, 0, 0, 0, 0, 0, 60, HLD, 0, 0,
|
||||
db 60, HLD, 0, 0, 0, 0, 60, HLD, 0, 0, 60, HLD, 60, HLD, 0, 0,
|
||||
db 0, 0, 0, 0, 60, HLD, 0, 0, 0, 0, 0, 0, 60, HLD, 60, HLD,
|
||||
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, HLD, 0, 0,
|
||||
db 60, HLD, 60, HLD, 0, 0, 60, HLD, 0, 0, 0, 0, 60, HLD, 0, 0,
|
||||
db 0, 0, 60, HLD, 0, 0, 0, 0, 60, HLD, 0, 0, 0, 0, 0, 0,
|
||||
db 0, 0, 60, HLD, 0, 0, 0, 0, 60, HLD, 0, 0, 60, HLD, 0, 0,
|
||||
db 0, 0, 0, 60, HLD, 0, 0, 0, 0, 0, 0, 0, 60, HLD, 0, 0,
|
||||
db 0, 0, 0, 60, HLD, 0, 0, 0, 0, 60, HLD, 60, 60, HLD, 0, 0,
|
||||
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 0, 0, 0,
|
||||
db 91, 0, 0, 88, 0, 0, 76, 0, 81, 0, 0, 0, 0, 0, 0, 0,
|
||||
db 81, 0, 0, 84, 0, 0, 86, 0, 88, 0, 0, 0, 0, 0, 0, 0,
|
||||
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 93, 0, 0, 0,
|
||||
db 81, 0, 0, 84, 0, 0, 86, 0, 81, 0, 0, 0, 0, 0, 0, 0,
|
||||
db 84, 0, 0, 86, 0, 0, 88, 0, 0, 91, 0, 0, 84, 0, 0, 0,
|
||||
db HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD,
|
||||
go4k_patterns_end
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // Pattern Index List
|
||||
; //----------------------------------------------------------------------------------------
|
||||
SECT_DATA(g4kmuc2)
|
||||
|
||||
EXPORT MANGLE_DATA(go4k_pattern_lists)
|
||||
Instrument0List db 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 4, 5, 6, 7, 1, 2, 3, 0, 4, 5, 6, 7, 8, 2, 9, 0, 0, 0,
|
||||
Instrument1List db 9, 7, 10, 7, 11, 7, 12, 7, 9, 7, 10, 7, 11, 7, 12, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 7, 13, 7, 14, 7, 3, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 7, 0, 0,
|
||||
Instrument2List db 15, 0, 16, 0, 17, 0, 18, 0, 19, 0, 16, 0, 17, 0, 18, 0, 20, 20, 21, 21, 22, 22, 20, 20, 20, 20, 21, 21, 22, 22, 20, 20, 23, 15, 24, 16, 25, 17, 18, 0, 20, 20, 21, 21, 22, 22, 20, 20, 20, 20, 21, 21, 22, 22, 20, 20, 20, 20, 0, 0, 0, 0,
|
||||
Instrument3List db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0,
|
||||
Instrument4List db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 26, 27, 26, 27, 26, 27, 28, 27, 26, 27, 26, 27, 26, 27, 28, 27, 29, 27, 29, 27, 29, 27, 29, 27, 26, 27, 26, 27, 26, 27, 28, 27, 26, 27, 26, 27, 26, 27, 28, 27, 26, 27, 0, 0, 0,
|
||||
Instrument5List db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 31, 30, 32, 30, 31, 30, 32, 30, 31, 30, 32, 30, 31, 30, 32, 30, 31, 30, 32, 30, 31, 30, 0, 30, 31, 30, 32, 30, 31, 30, 32, 30, 31, 30, 32, 30, 31, 30, 32, 30, 31, 30, 32, 0, 0,
|
||||
Instrument6List db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 33, 33, 34, 33, 33, 33, 34, 33, 33, 33, 34, 33, 33, 33, 34, 33, 33, 33, 34, 33, 33, 33, 34, 33, 33, 33, 34, 33, 33, 33, 34, 33, 33, 33, 34, 33, 33, 33, 34, 33, 33, 0, 0, 0, 0,
|
||||
Instrument7List db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 36, 0, 37, 38, 36, 0, 39, 35, 36, 0, 37, 38, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
Instrument8List db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 41, 41, 41, 11, 41, 41, 41, 11, 41, 41, 41, 11, 41, 41, 41, 11, 41, 41, 41, 11, 41, 41, 41, 11, 41, 41, 41, 11, 41, 41, 41, 11, 41, 41, 41, 11, 41, 41, 41, 11, 41, 41, 41, 41, 0,
|
||||
go4k_pattern_lists_end
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // Instrument Commands
|
||||
; //----------------------------------------------------------------------------------------
|
||||
SECT_DATA(g4kmuc3)
|
||||
|
||||
EXPORT MANGLE_DATA(go4k_synth_instructions)
|
||||
GO4K_BEGIN_CMDDEF(Instrument0)
|
||||
db GO4K_ENV_ID
|
||||
db GO4K_FST_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_FST_ID
|
||||
db GO4K_FST_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_VCF_ID
|
||||
db GO4K_VCF_ID
|
||||
db GO4K_DST_ID
|
||||
db GO4K_PAN_ID
|
||||
db GO4K_DLL_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_DLL_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_OUT_ID
|
||||
GO4K_END_CMDDEF
|
||||
GO4K_BEGIN_CMDDEF(Instrument1)
|
||||
db GO4K_ENV_ID
|
||||
db GO4K_FST_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_FST_ID
|
||||
db GO4K_FST_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_VCF_ID
|
||||
db GO4K_VCF_ID
|
||||
db GO4K_DST_ID
|
||||
db GO4K_PAN_ID
|
||||
db GO4K_DLL_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_DLL_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_OUT_ID
|
||||
GO4K_END_CMDDEF
|
||||
GO4K_BEGIN_CMDDEF(Instrument2)
|
||||
db GO4K_ENV_ID
|
||||
db GO4K_FST_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_FST_ID
|
||||
db GO4K_FST_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_VCF_ID
|
||||
db GO4K_VCF_ID
|
||||
db GO4K_DST_ID
|
||||
db GO4K_PAN_ID
|
||||
db GO4K_DLL_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_DLL_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_OUT_ID
|
||||
GO4K_END_CMDDEF
|
||||
GO4K_BEGIN_CMDDEF(Instrument3)
|
||||
db GO4K_ENV_ID
|
||||
db GO4K_FST_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_VCF_ID
|
||||
db GO4K_PAN_ID
|
||||
db GO4K_OUT_ID
|
||||
GO4K_END_CMDDEF
|
||||
GO4K_BEGIN_CMDDEF(Instrument4)
|
||||
db GO4K_ENV_ID
|
||||
db GO4K_FST_ID
|
||||
db GO4K_ENV_ID
|
||||
db GO4K_DST_ID
|
||||
db GO4K_FST_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_PAN_ID
|
||||
db GO4K_OUT_ID
|
||||
GO4K_END_CMDDEF
|
||||
GO4K_BEGIN_CMDDEF(Instrument5)
|
||||
db GO4K_ENV_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_VCF_ID
|
||||
db GO4K_PAN_ID
|
||||
db GO4K_DLL_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_DLL_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_OUT_ID
|
||||
GO4K_END_CMDDEF
|
||||
GO4K_BEGIN_CMDDEF(Instrument6)
|
||||
db GO4K_ENV_ID
|
||||
db GO4K_FST_ID
|
||||
db GO4K_ENV_ID
|
||||
db GO4K_FST_ID
|
||||
db GO4K_FST_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_VCF_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_VCF_ID
|
||||
db GO4K_PAN_ID
|
||||
db GO4K_OUT_ID
|
||||
GO4K_END_CMDDEF
|
||||
GO4K_BEGIN_CMDDEF(Instrument7)
|
||||
db GO4K_ENV_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_PAN_ID
|
||||
db GO4K_DLL_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_DLL_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_OUT_ID
|
||||
GO4K_END_CMDDEF
|
||||
GO4K_BEGIN_CMDDEF(Instrument8)
|
||||
db GO4K_ENV_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_FSTG_ID
|
||||
db GO4K_FSTG_ID
|
||||
db GO4K_FOP_ID
|
||||
GO4K_END_CMDDEF
|
||||
;// global commands
|
||||
GO4K_BEGIN_CMDDEF(Global)
|
||||
db GO4K_ACC_ID
|
||||
db GO4K_DLL_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_DLL_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_ACC_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_OUT_ID
|
||||
GO4K_END_CMDDEF
|
||||
go4k_synth_instructions_end
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // Intrument Data
|
||||
; //----------------------------------------------------------------------------------------
|
||||
SECT_DATA(g4kmuc4)
|
||||
|
||||
EXPORT MANGLE_DATA(go4k_synth_parameter_values)
|
||||
GO4K_BEGIN_PARAMDEF(Instrument0)
|
||||
GO4K_ENV ATTAC(72),DECAY(96),SUSTAIN(96),RELEASE(88),GAIN(128)
|
||||
; GO4K_FST AMOUNT(64),DEST(0*MAX_UNIT_SLOTS+2) ; TODO: convert into new DEST format
|
||||
GO4K_VCO TRANSPOSE(64),DETUNE(60),PHASE(32),GATES(0),COLOR(80),SHAPE(64),GAIN(128),FLAGS(PULSE)
|
||||
GO4K_VCO TRANSPOSE(64),DETUNE(72),PHASE(32),GATES(0),COLOR(96),SHAPE(64),GAIN(128),FLAGS(TRISAW)
|
||||
GO4K_VCO TRANSPOSE(32),DETUNE(64),PHASE(0),GATES(0),COLOR(64),SHAPE(96),GAIN(128),FLAGS(SINE|LFO)
|
||||
; GO4K_FST AMOUNT(68),DEST(2*MAX_UNIT_SLOTS+2) ; TODO: convert into new DEST format
|
||||
; GO4K_FST AMOUNT(61),DEST(3*MAX_UNIT_SLOTS+2); TODO: convert into new DEST format
|
||||
GO4K_FOP OP(FOP_POP)
|
||||
GO4K_FOP OP(FOP_ADDP)
|
||||
GO4K_FOP OP(FOP_MULP)
|
||||
GO4K_VCF FREQUENCY(26),RESONANCE(128),VCFTYPE(PEAK)
|
||||
GO4K_VCF FREQUENCY(64),RESONANCE(64),VCFTYPE(LOWPASS)
|
||||
GO4K_DST DRIVE(104), SNHFREQ(128), FLAGS(0)
|
||||
GO4K_PAN PANNING(64)
|
||||
GO4K_DLL PREGAIN(96),DRY(128),FEEDBACK(96),DAMP(64),FREQUENCY(0),DEPTH(0),DELAY(16),COUNT(1)
|
||||
GO4K_FOP OP(FOP_XCH)
|
||||
GO4K_DLL PREGAIN(96),DRY(128),FEEDBACK(64),DAMP(64),FREQUENCY(0),DEPTH(0),DELAY(17),COUNT(1)
|
||||
GO4K_FOP OP(FOP_XCH)
|
||||
GO4K_OUT GAIN(0), AUXSEND(32)
|
||||
GO4K_END_PARAMDEF
|
||||
GO4K_BEGIN_PARAMDEF(Instrument1)
|
||||
GO4K_ENV ATTAC(72),DECAY(96),SUSTAIN(96),RELEASE(88),GAIN(128)
|
||||
; GO4K_FST AMOUNT(64),DEST(0*MAX_UNIT_SLOTS+2) ; TODO: convert into new DEST format
|
||||
GO4K_VCO TRANSPOSE(64),DETUNE(60),PHASE(32),GATES(0),COLOR(80),SHAPE(64),GAIN(128),FLAGS(TRISAW)
|
||||
GO4K_VCO TRANSPOSE(64),DETUNE(72),PHASE(32),GATES(0),COLOR(96),SHAPE(112),GAIN(64),FLAGS(SINE)
|
||||
GO4K_VCO TRANSPOSE(80),DETUNE(112),PHASE(0),GATES(0),COLOR(64),SHAPE(16),GAIN(128),FLAGS(PULSE|LFO)
|
||||
; GO4K_FST AMOUNT(68),DEST(2*MAX_UNIT_SLOTS+2) ; TODO: convert into new DEST format
|
||||
; GO4K_FST AMOUNT(60),DEST(3*MAX_UNIT_SLOTS+2) ; TODO: convert into new DEST format
|
||||
GO4K_FOP OP(FOP_POP)
|
||||
GO4K_FOP OP(FOP_ADDP)
|
||||
GO4K_FOP OP(FOP_MULP)
|
||||
GO4K_VCF FREQUENCY(80),RESONANCE(24),VCFTYPE(LOWPASS)
|
||||
GO4K_VCF FREQUENCY(48),RESONANCE(24),VCFTYPE(HIGHPASS)
|
||||
GO4K_DST DRIVE(64), SNHFREQ(128), FLAGS(0)
|
||||
GO4K_PAN PANNING(64)
|
||||
GO4K_DLL PREGAIN(96),DRY(128),FEEDBACK(96),DAMP(64),FREQUENCY(0),DEPTH(0),DELAY(16),COUNT(1)
|
||||
GO4K_FOP OP(FOP_XCH)
|
||||
GO4K_DLL PREGAIN(96),DRY(128),FEEDBACK(64),DAMP(64),FREQUENCY(0),DEPTH(0),DELAY(17),COUNT(1)
|
||||
GO4K_FOP OP(FOP_XCH)
|
||||
GO4K_OUT GAIN(0), AUXSEND(32)
|
||||
GO4K_END_PARAMDEF
|
||||
GO4K_BEGIN_PARAMDEF(Instrument2)
|
||||
GO4K_ENV ATTAC(32),DECAY(64),SUSTAIN(64),RELEASE(64),GAIN(64)
|
||||
; GO4K_FST AMOUNT(120),DEST(0*MAX_UNIT_SLOTS+2) ; TODO: convert into new DEST format
|
||||
GO4K_VCO TRANSPOSE(64),DETUNE(64),PHASE(32),GATES(0),COLOR(80),SHAPE(64),GAIN(128),FLAGS(PULSE)
|
||||
GO4K_VCO TRANSPOSE(64),DETUNE(72),PHASE(32),GATES(0),COLOR(96),SHAPE(64),GAIN(128),FLAGS(TRISAW)
|
||||
GO4K_VCO TRANSPOSE(32),DETUNE(64),PHASE(0),GATES(0),COLOR(64),SHAPE(96),GAIN(128),FLAGS(SINE|LFO)
|
||||
; GO4K_FST AMOUNT(68),DEST(2*MAX_UNIT_SLOTS+2) ; TODO: convert into new DEST format
|
||||
; GO4K_FST AMOUNT(60),DEST(3*MAX_UNIT_SLOTS+2); TODO: convert into new DEST format
|
||||
GO4K_FOP OP(FOP_POP)
|
||||
GO4K_FOP OP(FOP_ADDP)
|
||||
GO4K_FOP OP(FOP_MULP)
|
||||
GO4K_VCF FREQUENCY(18),RESONANCE(64),VCFTYPE(PEAK)
|
||||
GO4K_VCF FREQUENCY(32),RESONANCE(48),VCFTYPE(LOWPASS)
|
||||
GO4K_DST DRIVE(88), SNHFREQ(128), FLAGS(0)
|
||||
GO4K_PAN PANNING(64)
|
||||
GO4K_DLL PREGAIN(64),DRY(128),FEEDBACK(96),DAMP(64),FREQUENCY(0),DEPTH(0),DELAY(16),COUNT(1)
|
||||
GO4K_FOP OP(FOP_XCH)
|
||||
GO4K_DLL PREGAIN(64),DRY(128),FEEDBACK(64),DAMP(64),FREQUENCY(0),DEPTH(0),DELAY(17),COUNT(1)
|
||||
GO4K_FOP OP(FOP_XCH)
|
||||
GO4K_OUT GAIN(64), AUXSEND(64)
|
||||
GO4K_END_PARAMDEF
|
||||
GO4K_BEGIN_PARAMDEF(Instrument3)
|
||||
GO4K_ENV ATTAC(0),DECAY(76),SUSTAIN(0),RELEASE(0),GAIN(32)
|
||||
; GO4K_FST AMOUNT(128),DEST(0*MAX_UNIT_SLOTS+2) ; TODO: convert into new DEST format
|
||||
GO4K_VCO TRANSPOSE(64),DETUNE(64),PHASE(64),GATES(0),COLOR(64),SHAPE(64),GAIN(128),FLAGS(NOISE)
|
||||
GO4K_FOP OP(FOP_MULP)
|
||||
GO4K_VCF FREQUENCY(80),RESONANCE(128),VCFTYPE(LOWPASS)
|
||||
GO4K_PAN PANNING(64)
|
||||
GO4K_OUT GAIN(64), AUXSEND(0)
|
||||
GO4K_END_PARAMDEF
|
||||
GO4K_BEGIN_PARAMDEF(Instrument4)
|
||||
GO4K_ENV ATTAC(0),DECAY(64),SUSTAIN(96),RELEASE(64),GAIN(128)
|
||||
; GO4K_FST AMOUNT(128),DEST(0*MAX_UNIT_SLOTS+2) ; TODO: convert into new DEST format
|
||||
GO4K_ENV ATTAC(0),DECAY(70),SUSTAIN(0),RELEASE(0),GAIN(128)
|
||||
GO4K_DST DRIVE(32), SNHFREQ(128), FLAGS(0)
|
||||
; GO4K_FST AMOUNT(80),DEST(6*MAX_UNIT_SLOTS+1) ; TODO: convert into new DEST format
|
||||
GO4K_FOP OP(FOP_POP)
|
||||
GO4K_VCO TRANSPOSE(46),DETUNE(64),PHASE(0),GATES(0),COLOR(64),SHAPE(64),GAIN(128),FLAGS(TRISAW)
|
||||
GO4K_FOP OP(FOP_MULP)
|
||||
GO4K_PAN PANNING(64)
|
||||
GO4K_OUT GAIN(128), AUXSEND(0)
|
||||
GO4K_END_PARAMDEF
|
||||
GO4K_BEGIN_PARAMDEF(Instrument5)
|
||||
GO4K_ENV ATTAC(0),DECAY(64),SUSTAIN(0),RELEASE(0),GAIN(128)
|
||||
GO4K_VCO TRANSPOSE(64),DETUNE(64),PHASE(64),GATES(0),COLOR(64),SHAPE(64),GAIN(128),FLAGS(NOISE)
|
||||
GO4K_FOP OP(FOP_MULP)
|
||||
GO4K_VCF FREQUENCY(128),RESONANCE(128),VCFTYPE(BANDPASS)
|
||||
GO4K_PAN PANNING(64)
|
||||
GO4K_DLL PREGAIN(64),DRY(128),FEEDBACK(96),DAMP(64),FREQUENCY(0),DEPTH(0),DELAY(16),COUNT(1)
|
||||
GO4K_FOP OP(FOP_XCH)
|
||||
GO4K_DLL PREGAIN(64),DRY(128),FEEDBACK(64),DAMP(64),FREQUENCY(0),DEPTH(0),DELAY(17),COUNT(1)
|
||||
GO4K_FOP OP(FOP_XCH)
|
||||
GO4K_OUT GAIN(64), AUXSEND(0)
|
||||
GO4K_END_PARAMDEF
|
||||
GO4K_BEGIN_PARAMDEF(Instrument6)
|
||||
GO4K_ENV ATTAC(0),DECAY(72),SUSTAIN(0),RELEASE(72),GAIN(128)
|
||||
; GO4K_FST AMOUNT(128),DEST(0*MAX_UNIT_SLOTS+2) ; TODO: convert into new DEST format
|
||||
GO4K_ENV ATTAC(0),DECAY(56),SUSTAIN(0),RELEASE(0),GAIN(128)
|
||||
; GO4K_FST AMOUNT(108),DEST(6*MAX_UNIT_SLOTS+1) ; TODO: convert into new DEST format
|
||||
; GO4K_FST AMOUNT(72),DEST(7*MAX_UNIT_SLOTS+1) ; TODO: convert into new DEST format
|
||||
GO4K_FOP OP(FOP_POP)
|
||||
GO4K_VCO TRANSPOSE(32),DETUNE(64),PHASE(0),GATES(0),COLOR(64),SHAPE(32),GAIN(64),FLAGS(SINE)
|
||||
GO4K_VCO TRANSPOSE(64),DETUNE(64),PHASE(0),GATES(0),COLOR(64),SHAPE(80),GAIN(64),FLAGS(SINE)
|
||||
GO4K_VCO TRANSPOSE(64),DETUNE(64),PHASE(0),GATES(0),COLOR(64),SHAPE(64),GAIN(64),FLAGS(NOISE)
|
||||
GO4K_VCF FREQUENCY(104),RESONANCE(128),VCFTYPE(LOWPASS)
|
||||
GO4K_FOP OP(FOP_ADDP)
|
||||
GO4K_FOP OP(FOP_ADDP)
|
||||
GO4K_FOP OP(FOP_MULP)
|
||||
GO4K_VCF FREQUENCY(22),RESONANCE(32),VCFTYPE(HIGHPASS)
|
||||
GO4K_PAN PANNING(64)
|
||||
GO4K_OUT GAIN(64), AUXSEND(0)
|
||||
GO4K_END_PARAMDEF
|
||||
GO4K_BEGIN_PARAMDEF(Instrument7)
|
||||
GO4K_ENV ATTAC(0),DECAY(0),SUSTAIN(96),RELEASE(32),GAIN(128)
|
||||
GO4K_VCO TRANSPOSE(64),DETUNE(64),PHASE(0),GATES(0),COLOR(80),SHAPE(64),GAIN(128),FLAGS(PULSE)
|
||||
GO4K_FOP OP(FOP_MULP)
|
||||
GO4K_PAN PANNING(64)
|
||||
GO4K_DLL PREGAIN(96),DRY(128),FEEDBACK(96),DAMP(64),FREQUENCY(0),DEPTH(0),DELAY(16),COUNT(1)
|
||||
GO4K_FOP OP(FOP_XCH)
|
||||
GO4K_DLL PREGAIN(96),DRY(128),FEEDBACK(64),DAMP(64),FREQUENCY(0),DEPTH(0),DELAY(17),COUNT(1)
|
||||
GO4K_FOP OP(FOP_XCH)
|
||||
GO4K_OUT GAIN(0), AUXSEND(64)
|
||||
GO4K_END_PARAMDEF
|
||||
GO4K_BEGIN_PARAMDEF(Instrument8)
|
||||
GO4K_ENV ATTAC(0),DECAY(0),SUSTAIN(128),RELEASE(0),GAIN(128)
|
||||
GO4K_VCO TRANSPOSE(48),DETUNE(64),PHASE(0),GATES(0),COLOR(64),SHAPE(64),GAIN(128),FLAGS(TRISAW|LFO)
|
||||
GO4K_FOP OP(FOP_MULP)
|
||||
; GO4K_FSTG AMOUNT(72),DEST(2*go4k_instrument.size*MAX_VOICES+10*MAX_UNIT_SLOTS*4+4*4+go4k_instrument.workspace) ; TODO: convert into new DEST format
|
||||
; GO4K_FSTG AMOUNT(66),DEST(1*go4k_instrument.size*MAX_VOICES+10*MAX_UNIT_SLOTS*4+4*4+go4k_instrument.workspace) ; TODO: convert into new DEST format
|
||||
GO4K_FOP OP(FOP_POP)
|
||||
GO4K_END_PARAMDEF
|
||||
;// global parameters
|
||||
GO4K_BEGIN_PARAMDEF(Global)
|
||||
GO4K_ACC ACCTYPE(AUX)
|
||||
GO4K_DLL PREGAIN(40),DRY(128),FEEDBACK(125),DAMP(64),FREQUENCY(0),DEPTH(0),DELAY(0),COUNT(8)
|
||||
GO4K_FOP OP(FOP_XCH)
|
||||
GO4K_DLL PREGAIN(40),DRY(128),FEEDBACK(125),DAMP(64),FREQUENCY(0),DEPTH(0),DELAY(8),COUNT(8)
|
||||
GO4K_FOP OP(FOP_XCH)
|
||||
GO4K_ACC ACCTYPE(OUTPUT)
|
||||
GO4K_FOP OP(FOP_ADDP2)
|
||||
GO4K_OUT GAIN(64), AUXSEND(0)
|
||||
GO4K_END_PARAMDEF
|
||||
go4k_synth_parameter_values_end
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // Delay/Reverb Times
|
||||
; //----------------------------------------------------------------------------------------
|
||||
SECT_DATA(g4kmuc5)
|
||||
|
||||
EXPORT MANGLE_DATA(go4k_delay_times)
|
||||
dw 0
|
||||
dw 1116
|
||||
dw 1188
|
||||
dw 1276
|
||||
dw 1356
|
||||
dw 1422
|
||||
dw 1492
|
||||
dw 1556
|
||||
dw 1618
|
||||
dw 1140
|
||||
dw 1212
|
||||
dw 1300
|
||||
dw 1380
|
||||
dw 1446
|
||||
dw 1516
|
||||
dw 1580
|
||||
dw 1642
|
||||
dw 22050 ; Originally times 100 dw 0, but crashes for me (Peter) - so reverted to this found in an older version
|
||||
dw 16537
|
||||
dw 11025
|
||||
Binary file not shown.
@@ -1,28 +0,0 @@
|
||||
file(GLOB SOURCE_LIST CONFIGURE_DEPENDS "*.cpp" "*.hpp" "*.asm" "*.bin")
|
||||
file(GLOB AEFFECT_SOURCE_LIST CONFIGURE_DEPENDS "audioeffect/*")
|
||||
|
||||
# Make a dynamic library of 4klang
|
||||
add_library(4klang SHARED ${SOURCE_LIST} ${AEFFECT_SOURCE_LIST} Go4kVSTi.rc Go4kVSTi.def)
|
||||
|
||||
# Make a dynamic library of 8klang
|
||||
add_library(8klang SHARED ${SOURCE_LIST} ${AEFFECT_SOURCE_LIST} Go4kVSTi2.rc Go4kVSTi2.def)
|
||||
|
||||
target_compile_definitions(8klang PUBLIC _8KLANG)
|
||||
|
||||
set_target_properties(4klang 8klang PROPERTIES
|
||||
MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
|
||||
|
||||
# The private headers
|
||||
target_include_directories(4klang PRIVATE "audioeffect/")
|
||||
|
||||
# The private headers
|
||||
target_include_directories(8klang PRIVATE "audioeffect/")
|
||||
|
||||
add_library(vstgui STATIC IMPORTED)
|
||||
set_target_properties(vstgui
|
||||
PROPERTIES IMPORTED_LOCATION
|
||||
"${CMAKE_SOURCE_DIR}/extern/vstgui.lib")
|
||||
|
||||
target_link_libraries(4klang PRIVATE comctl32 vstgui)
|
||||
|
||||
target_link_libraries(8klang PRIVATE comctl32 vstgui)
|
||||
@@ -1,204 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#ifndef __Go4kVSTi__
|
||||
#include "Go4kVSTi.h"
|
||||
#endif
|
||||
#include "Go4kVSTiCore.h"
|
||||
//-----------------------------------------------------------------------------------------
|
||||
// Go4kVSTi
|
||||
//-----------------------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
Go4kVSTi::Go4kVSTi (audioMasterCallback audioMaster) : AudioEffectX (audioMaster, 0, 0)
|
||||
{
|
||||
m_chunkBuffer = 0;
|
||||
if (audioMaster)
|
||||
{
|
||||
setNumInputs (0); // no inputs
|
||||
setNumOutputs (2); // 2 outputs, stereo
|
||||
canProcessReplacing ();
|
||||
hasVu (false);
|
||||
hasClip (false);
|
||||
isSynth ();
|
||||
programsAreChunks (true);
|
||||
#ifdef _8KLANG
|
||||
setUniqueID ('8klg');
|
||||
#else
|
||||
setUniqueID ('4klg');
|
||||
#endif
|
||||
}
|
||||
initProcess ();
|
||||
suspend ();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
Go4kVSTi::~Go4kVSTi ()
|
||||
{
|
||||
delete[] m_chunkBuffer;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
void Go4kVSTi::setProgram (long program)
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
void Go4kVSTi::setProgramName (char *name)
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
void Go4kVSTi::getProgramName (char *name)
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
void Go4kVSTi::getParameterLabel (long index, char *label)
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
void Go4kVSTi::getParameterDisplay (long index, char *text)
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
void Go4kVSTi::getParameterName (long index, char *label)
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
void Go4kVSTi::setParameter (long index, float value)
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
float Go4kVSTi::getParameter (long index)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
bool Go4kVSTi::getOutputProperties (long index, VstPinProperties* properties)
|
||||
{
|
||||
if (index < 2)
|
||||
{
|
||||
sprintf (properties->label, "Vstx %1d", index + 1);
|
||||
properties->flags = kVstPinIsActive;
|
||||
properties->flags |= kVstPinIsStereo; // test, make channel 1+2 stereo
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
bool Go4kVSTi::getProgramNameIndexed (long category, long index, char* text)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
bool Go4kVSTi::copyProgram (long destination)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
bool Go4kVSTi::getEffectName (char* name)
|
||||
{
|
||||
#ifdef _8KLANG
|
||||
strcpy (name, "8klang");
|
||||
#else
|
||||
strcpy (name, "4klang");
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
bool Go4kVSTi::getVendorString (char* text)
|
||||
{
|
||||
strcpy (text, "Alcatraz");
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
bool Go4kVSTi::getProductString (char* text)
|
||||
{
|
||||
#ifdef _8KLANG
|
||||
strcpy (text, "8klang");
|
||||
#else
|
||||
strcpy (text, "4klang");
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
long Go4kVSTi::canDo (char* text)
|
||||
{
|
||||
if (!strcmp (text, "receiveVstEvents"))
|
||||
return 1;
|
||||
if (!strcmp (text, "receiveVstMidiEvent"))
|
||||
return 1;
|
||||
if (!strcmp (text, "receiveVstTimeInfo"))
|
||||
return 1;
|
||||
return -1; // explicitly can't do; 0 => don't know
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
long Go4kVSTi::getChunk(void** data, bool isPreset)
|
||||
{
|
||||
// serialize patch data into file, then load it back
|
||||
char path[MAX_PATH];
|
||||
char filename[MAX_PATH];
|
||||
GetTempPath(MAX_PATH, path);
|
||||
GetTempFileName(path, "4klang_", 0, filename);
|
||||
Go4kVSTi_SavePatch(filename);
|
||||
|
||||
HANDLE h = CreateFile(filename, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0);
|
||||
if (h == INVALID_HANDLE_VALUE)
|
||||
return 0;
|
||||
|
||||
DWORD dummy;
|
||||
DWORD size = GetFileSize(h, &dummy);
|
||||
delete[] m_chunkBuffer;
|
||||
m_chunkBuffer = new unsigned char[size];
|
||||
ReadFile(h, m_chunkBuffer, size, &dummy, 0);
|
||||
CloseHandle(h);
|
||||
DeleteFile(filename);
|
||||
|
||||
if (dummy == size)
|
||||
{
|
||||
*data = m_chunkBuffer;
|
||||
return size;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
long Go4kVSTi::setChunk(void* data, long byteSize, bool isPreset)
|
||||
{
|
||||
if (!data || !byteSize) return 0;
|
||||
|
||||
// write chunk into file, then deserialize as patch data
|
||||
char path[MAX_PATH];
|
||||
char filename[MAX_PATH];
|
||||
GetTempPath(MAX_PATH, path);
|
||||
GetTempFileName(path, "4klang_", 0, filename);
|
||||
|
||||
HANDLE h = CreateFile(filename, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
|
||||
if (h == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
DWORD err = GetLastError();
|
||||
return 0;
|
||||
}
|
||||
DWORD dummy;
|
||||
WriteFile(h, data, byteSize, &dummy, 0);
|
||||
CloseHandle(h);
|
||||
|
||||
if (dummy == byteSize)
|
||||
{
|
||||
Go4kVSTi_LoadPatch(filename);
|
||||
}
|
||||
DeleteFile(filename);
|
||||
return 0;
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
LIBRARY 4klang
|
||||
EXPORTS main
|
||||
@@ -1,55 +0,0 @@
|
||||
#ifndef __Go4kVSTi__
|
||||
#define __Go4kVSTi__
|
||||
|
||||
#include <string.h>
|
||||
#include <vector>
|
||||
|
||||
#ifndef __AudioEffectX__
|
||||
#include "audioeffectx.h"
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------------------
|
||||
class Go4kVSTi : public AudioEffectX
|
||||
{
|
||||
public:
|
||||
Go4kVSTi(audioMasterCallback audioMaster);
|
||||
~Go4kVSTi();
|
||||
|
||||
virtual void process(float **inputs, float **outputs, long sampleframes);
|
||||
virtual void processReplacing(float **inputs, float **outputs, long sampleframes);
|
||||
void processAnyhow(float **inputs, float **outputs, long sampleFrames);
|
||||
virtual long processEvents(VstEvents* events);
|
||||
|
||||
virtual void setProgram(long program);
|
||||
virtual void setProgramName(char *name);
|
||||
virtual void getProgramName(char *name);
|
||||
virtual void setParameter(long index, float value);
|
||||
virtual float getParameter(long index);
|
||||
virtual void getParameterLabel(long index, char *label);
|
||||
virtual void getParameterDisplay(long index, char *text);
|
||||
virtual void getParameterName(long index, char *text);
|
||||
virtual void setSampleRate(float sampleRate);
|
||||
virtual void setBlockSize(long blockSize);
|
||||
virtual void suspend();
|
||||
virtual void resume();
|
||||
virtual bool getOutputProperties (long index, VstPinProperties* properties);
|
||||
virtual bool getProgramNameIndexed (long category, long index, char* text);
|
||||
virtual bool copyProgram (long destination);
|
||||
virtual bool getEffectName (char* name);
|
||||
virtual bool getVendorString (char* text);
|
||||
virtual bool getProductString (char* text);
|
||||
virtual long getVendorVersion () {return 1;}
|
||||
virtual long canDo (char* text);
|
||||
virtual long getChunk(void** data, bool isPreset = false) override;
|
||||
virtual long setChunk(void* data, long byteSize, bool isPreset = false) override;
|
||||
|
||||
private:
|
||||
void initProcess();
|
||||
void ApplyEvent(VstMidiEvent *event);
|
||||
|
||||
std::vector<VstMidiEvent*> m_currentEvents;
|
||||
|
||||
unsigned char *m_chunkBuffer;
|
||||
};
|
||||
|
||||
#endif
|
||||
1433
src/vsti/Go4kVSTi.rc
1433
src/vsti/Go4kVSTi.rc
File diff suppressed because it is too large
Load Diff
@@ -1,2 +0,0 @@
|
||||
LIBRARY 8klang
|
||||
EXPORTS main
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,315 +0,0 @@
|
||||
#include "windows.h"
|
||||
|
||||
// init synth
|
||||
void Go4kVSTi_Init();
|
||||
|
||||
// clear instrument slot
|
||||
void Go4kVSTi_ClearInstrumentSlot(char channel, int slot);
|
||||
// clear instrument workspace
|
||||
void Go4kVSTi_ClearInstrumentWorkspace(char channel);
|
||||
// clear global slot
|
||||
void Go4kVSTi_ClearGlobalSlot(int slot);
|
||||
// clear global workspace
|
||||
void Go4kVSTi_ClearGlobalWorkspace();
|
||||
|
||||
// reset instrument to default values
|
||||
void Go4kVSTi_ResetInstrument(char channel);
|
||||
// reset global to default values
|
||||
void Go4kVSTi_ResetGlobal();
|
||||
// reset the synth to default values
|
||||
void Go4kVSTi_ResetPatch();
|
||||
|
||||
// flip 2 neighbour instrument slots
|
||||
void Go4kVSTi_FlipInstrumentSlots(char channel, int a, int b);
|
||||
// flip 2 neighbour global slots
|
||||
void Go4kVSTi_FlipGlobalSlots(int a, int b);
|
||||
|
||||
// init a slot with given type with default values
|
||||
void Go4kVSTi_InitSlot(BYTE* slot, int channel, int type);
|
||||
// init a instrument slot
|
||||
void Go4kVSTi_InitInstrumentSlot(char channel, int s, int type);
|
||||
// init a global slot
|
||||
void Go4kVSTi_InitGlobalSlot(int s, int type);
|
||||
|
||||
// set global bpm
|
||||
void Go4kVSTi_SetBPM(float bpm);
|
||||
float Go4kVSTi_GetBPM();
|
||||
|
||||
// activate solo mode
|
||||
void Go4kVSTi_Solo(int channel, int solo);
|
||||
// stream recording activation/deactivation
|
||||
void Go4kVSTi_Record(bool record, bool recordingNoise, int patternsize, float patternquant);
|
||||
// panic
|
||||
void Go4kVSTi_Panic();
|
||||
// update dll times (e.g. sync to current bpm)
|
||||
void Go4kVSTi_UpdateDelayTimes();
|
||||
// clear delay lines
|
||||
void Go4kVSTi_ClearDelayLines();
|
||||
|
||||
// one tick the whole synth pipeline. results are left and right output sample
|
||||
void Go4kVSTi_Tick(float *oleft, float *oright, int samples);
|
||||
// add a voice with given parameters to synth
|
||||
void Go4kVSTi_AddVoice(int channel, int note);
|
||||
// stop a voice with given parameters in synth
|
||||
void Go4kVSTi_StopVoice(int channel, int note);
|
||||
|
||||
// load binary patch data
|
||||
void Go4kVSTi_LoadPatch(char *filename);
|
||||
// save binary patch data
|
||||
void Go4kVSTi_SavePatch(char *filename);
|
||||
// load instrumen data to specified channel
|
||||
void Go4kVSTi_LoadInstrument(char* filename, char channel);
|
||||
// save instrument data from current channel
|
||||
void Go4kVSTi_SaveInstrument(char* filename, char channel);
|
||||
// load unit data into specified slot
|
||||
void Go4kVSTi_LoadUnit(char* filename, BYTE* slot);
|
||||
// save unit date from specified slot
|
||||
void Go4kVSTi_SaveUnit(char* filename, BYTE* slot);
|
||||
|
||||
void Go4kVSTi_SaveByteStream(HINSTANCE hInst, char* filename, int useenvlevels, int useenotevalues, int clipoutput, int undenormalize, int objformat, int output16);
|
||||
|
||||
#define MAX_POLYPHONY 2
|
||||
#define MAX_INSTRUMENTS 16
|
||||
#define MAX_UNITS 64
|
||||
#define MAX_UNIT_SLOTS 16
|
||||
|
||||
enum UnitID
|
||||
{
|
||||
M_NONE = 0,
|
||||
M_ENV,
|
||||
M_VCO,
|
||||
M_VCF,
|
||||
M_DST,
|
||||
M_DLL,
|
||||
M_FOP,
|
||||
M_FST,
|
||||
M_PAN,
|
||||
M_OUT,
|
||||
M_ACC,
|
||||
M_FLD,
|
||||
M_GLITCH,
|
||||
NUM_MODULES
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// value definitions
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#define ENV_STATE_ATTAC 0
|
||||
#define ENV_STATE_DECAY 1
|
||||
#define ENV_STATE_SUSTAIN 2
|
||||
#define ENV_STATE_RELEASE 3
|
||||
#define ENV_STATE_OFF 4
|
||||
|
||||
typedef struct ENV_val
|
||||
{
|
||||
BYTE id;
|
||||
BYTE attac;
|
||||
BYTE decay;
|
||||
BYTE sustain;
|
||||
BYTE release;
|
||||
BYTE gain;
|
||||
// GUI STUFF
|
||||
} *ENV_valP;
|
||||
|
||||
#define VCO_SINE 0x01
|
||||
#define VCO_TRISAW 0x02
|
||||
#define VCO_PULSE 0x04
|
||||
#define VCO_NOISE 0x08
|
||||
#define VCO_LFO 0x10
|
||||
#define VCO_GATE 0x20
|
||||
#define VCO_STEREO 0x40
|
||||
typedef struct VCO_val
|
||||
{
|
||||
BYTE id;
|
||||
BYTE transpose;
|
||||
BYTE detune;
|
||||
BYTE phaseofs;
|
||||
BYTE gate;
|
||||
BYTE color;
|
||||
BYTE shape;
|
||||
BYTE gain;
|
||||
BYTE flags;
|
||||
// GUI STUFF
|
||||
} *VCO_valP;
|
||||
|
||||
typedef struct VCO11_val
|
||||
{
|
||||
BYTE id;
|
||||
BYTE transpose;
|
||||
BYTE detune;
|
||||
BYTE phaseofs;
|
||||
BYTE color;
|
||||
BYTE shape;
|
||||
BYTE gain;
|
||||
BYTE flags;
|
||||
// GUI STUFF
|
||||
} *VCO11_valP;
|
||||
|
||||
#define VCF_LOWPASS 0x1
|
||||
#define VCF_HIGHPASS 0x2
|
||||
#define VCF_BANDPASS 0x4
|
||||
#define VCF_BANDSTOP 0x3
|
||||
#define VCF_ALLPASS 0x7
|
||||
#define VCF_PEAK 0x8
|
||||
#define VCF_STEREO 0x10
|
||||
typedef struct VCF_val
|
||||
{
|
||||
BYTE id;
|
||||
BYTE freq;
|
||||
BYTE res;
|
||||
BYTE type;
|
||||
// GUI STUFF
|
||||
} *VCF_valP;
|
||||
|
||||
typedef struct DST_val
|
||||
{
|
||||
BYTE id;
|
||||
BYTE drive;
|
||||
BYTE snhfreq;
|
||||
BYTE stereo;
|
||||
// GUI STUFF
|
||||
} *DST_valP;
|
||||
|
||||
typedef struct DLL_val
|
||||
{
|
||||
BYTE id;
|
||||
BYTE pregain;
|
||||
BYTE dry;
|
||||
BYTE feedback;
|
||||
BYTE damp;
|
||||
BYTE freq;
|
||||
BYTE depth;
|
||||
BYTE delay;
|
||||
BYTE count;
|
||||
// GUI STUFF
|
||||
BYTE guidelay;
|
||||
BYTE synctype;
|
||||
BYTE leftreverb;
|
||||
BYTE reverb;
|
||||
} *DLL_valP;
|
||||
|
||||
typedef struct DLL10_val
|
||||
{
|
||||
BYTE id;
|
||||
BYTE pregain;
|
||||
BYTE dry;
|
||||
BYTE feedback;
|
||||
BYTE damp;
|
||||
BYTE delay;
|
||||
BYTE count;
|
||||
// GUI STUFF
|
||||
BYTE guidelay;
|
||||
BYTE synctype;
|
||||
BYTE leftreverb;
|
||||
BYTE reverb;
|
||||
} *DLL10_valP;
|
||||
|
||||
#define FOP_POP 0x1
|
||||
#define FOP_ADDP 0x2
|
||||
#define FOP_MULP 0x3
|
||||
#define FOP_PUSH 0x4
|
||||
#define FOP_XCH 0x5
|
||||
#define FOP_ADD 0x6
|
||||
#define FOP_MUL 0x7
|
||||
#define FOP_ADDP2 0x8
|
||||
#define FOP_LOADNOTE 0x9
|
||||
#define FOP_MULP2 0xa
|
||||
typedef struct FOP_val
|
||||
{
|
||||
BYTE id;
|
||||
BYTE flags;
|
||||
} *FOP_valP;
|
||||
|
||||
#define FST_SET 0x00
|
||||
#define FST_ADD 0x10
|
||||
#define FST_MUL 0x20
|
||||
#define FST_POP 0x40
|
||||
typedef struct FST_val
|
||||
{
|
||||
BYTE id;
|
||||
BYTE amount;
|
||||
BYTE type;
|
||||
// GUI STUFF
|
||||
char dest_stack;
|
||||
char dest_unit;
|
||||
char dest_slot;
|
||||
char dest_id;
|
||||
} *FST_valP;
|
||||
|
||||
typedef struct PAN_val
|
||||
{
|
||||
BYTE id;
|
||||
BYTE panning;
|
||||
// GUI STUFF
|
||||
} *PAN_valP;
|
||||
|
||||
typedef struct OUT_val
|
||||
{
|
||||
BYTE id;
|
||||
BYTE gain;
|
||||
BYTE auxsend;
|
||||
// GUI STUFF
|
||||
} *OUT_valP;
|
||||
|
||||
#define ACC_OUT 0
|
||||
#define ACC_AUX 8
|
||||
typedef struct ACC_val
|
||||
{
|
||||
BYTE id;
|
||||
BYTE flags;
|
||||
} *ACC_valP;
|
||||
|
||||
typedef struct FLD_val
|
||||
{
|
||||
BYTE id;
|
||||
BYTE value;
|
||||
// GUI STUFF
|
||||
} *FLD_valP;
|
||||
|
||||
typedef struct GLITCH_val
|
||||
{
|
||||
BYTE id;
|
||||
BYTE active;
|
||||
BYTE dry;
|
||||
BYTE dsize;
|
||||
BYTE dpitch;
|
||||
BYTE delay;
|
||||
// GUI STUFF
|
||||
BYTE guidelay;
|
||||
} *GLITCH_valP;
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// workspace definitions
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct InstrumentWorkspace
|
||||
{
|
||||
DWORD release;
|
||||
DWORD note;
|
||||
float workspace[MAX_UNITS*MAX_UNIT_SLOTS];
|
||||
float dlloutl;
|
||||
float dlloutr;
|
||||
float outl;
|
||||
float outr;
|
||||
} *InstrumentWorkspaceP;
|
||||
|
||||
typedef struct SynthObject
|
||||
{
|
||||
DWORD Polyphony;
|
||||
char InstrumentNames[MAX_INSTRUMENTS][64];
|
||||
BYTE InstrumentValues[MAX_INSTRUMENTS][MAX_UNITS][MAX_UNIT_SLOTS]; // 16 instruments a 32 slots a 32 dowrds
|
||||
BYTE GlobalValues[MAX_UNITS][MAX_UNIT_SLOTS]; // 32 slots a 32 dwords
|
||||
InstrumentWorkspace InstrumentWork[MAX_INSTRUMENTS*MAX_POLYPHONY];
|
||||
InstrumentWorkspace GlobalWork;
|
||||
DWORD InstrumentSignalValid[MAX_INSTRUMENTS];
|
||||
DWORD GlobalSignalValid;
|
||||
float SignalTrace[MAX_INSTRUMENTS];
|
||||
int ControlInstrument[MAX_INSTRUMENTS];
|
||||
int VoiceIndex[MAX_INSTRUMENTS];
|
||||
int HighestSlotIndex[17];
|
||||
} *SynthObjectP;
|
||||
|
||||
SynthObjectP Go4kVSTi_GetSynthObject();
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,182 +0,0 @@
|
||||
#include <windows.h>
|
||||
|
||||
#define ButtonGroupChanged(btn_firstid, btn_lastid, test_id, seltab, result_index) \
|
||||
{ \
|
||||
result_index = 0; \
|
||||
if (LOWORD(test_id) >= btn_firstid && \
|
||||
LOWORD(test_id) <= btn_lastid) \
|
||||
{ \
|
||||
for (WORD bgci = btn_firstid; bgci <= btn_lastid; bgci++) \
|
||||
{ \
|
||||
if (LOWORD(test_id) == bgci) \
|
||||
{ \
|
||||
EnableWindow(GetDlgItem(ModuleWnd[seltab], bgci), false); \
|
||||
result_index = bgci; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
EnableWindow(GetDlgItem(ModuleWnd[seltab], bgci), true); \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
#define EnableButtonGroup(btn_firstid, btn_lastid, seltab, btn_show) \
|
||||
{ \
|
||||
for (WORD bgci = btn_firstid; bgci <= btn_lastid; bgci++) \
|
||||
{ \
|
||||
EnableWindow(GetDlgItem(ModuleWnd[seltab], bgci), btn_show); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define SetCheckboxGroupBitmask(btn_firstid, btn_lastid, seltab, input_bits) \
|
||||
{ \
|
||||
WORD curbitsel = 0x0001; \
|
||||
for (WORD bgci = btn_firstid; bgci <= btn_lastid; bgci++,curbitsel*=2) \
|
||||
{ \
|
||||
SendDlgItemMessage(ModuleWnd[seltab], bgci, BM_SETCHECK, input_bits & curbitsel, 0); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define GetCheckboxGroupBitmask(btn_firstid, btn_lastid, test_id, seltab, result_bits, result_index) \
|
||||
{ \
|
||||
result_index = 0; \
|
||||
result_bits = 0; \
|
||||
WORD curbitsel = 0x0001; \
|
||||
if (LOWORD(test_id) >= btn_firstid && \
|
||||
LOWORD(test_id) <= btn_lastid) \
|
||||
{ \
|
||||
for (WORD bgci = btn_firstid; bgci <= btn_lastid; bgci++,curbitsel*=2) \
|
||||
{ \
|
||||
if (LOWORD(test_id) == bgci) \
|
||||
{ \
|
||||
result_index = bgci; \
|
||||
} \
|
||||
if (SendDlgItemMessage(ModuleWnd[seltab], bgci, BM_GETCHECK, 0, 0)==BST_CHECKED) \
|
||||
{ \
|
||||
result_bits |= curbitsel; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
result_bits &= ~curbitsel; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
#define InitSlider(tab_id, slider_id, slider_low, slider_hi, slider_pos) \
|
||||
{ \
|
||||
SendDlgItemMessage(tab_id, slider_id, TBM_SETRANGE, true, MAKELONG(slider_low, slider_hi)); \
|
||||
SendDlgItemMessage(tab_id, slider_id, TBM_SETPOS, true, slider_pos); \
|
||||
SendDlgItemMessage(tab_id, slider_id, TBM_SETLINESIZE, 0, 1); \
|
||||
SendDlgItemMessage(tab_id, slider_id, TBM_SETPAGESIZE, 0, 1); \
|
||||
sprintf(SliderValTxt, "%d", slider_pos); \
|
||||
SetWindowText(GetDlgItem(tab_id, slider_id ## _VAL), SliderValTxt); \
|
||||
}
|
||||
|
||||
#define InitSliderCenter(tab_id, slider_id, slider_low, slider_hi, slider_pos) \
|
||||
{ \
|
||||
SendDlgItemMessage(tab_id, slider_id, TBM_SETRANGE, true, MAKELONG(slider_low, slider_hi)); \
|
||||
SendDlgItemMessage(tab_id, slider_id, TBM_SETPOS, true, slider_pos); \
|
||||
SendDlgItemMessage(tab_id, slider_id, TBM_SETLINESIZE, 0, 1); \
|
||||
SendDlgItemMessage(tab_id, slider_id, TBM_SETPAGESIZE, 0, 1); \
|
||||
sprintf(SliderValTxt, "%d", slider_pos-64); \
|
||||
SetWindowText(GetDlgItem(tab_id, slider_id ## _VAL), SliderValTxt); \
|
||||
}
|
||||
|
||||
#define InitSliderCenter2(tab_id, slider_id, slider_low, slider_hi, slider_pos) \
|
||||
{ \
|
||||
SendDlgItemMessage(tab_id, slider_id, TBM_SETRANGE, true, MAKELONG(slider_low, slider_hi)); \
|
||||
SendDlgItemMessage(tab_id, slider_id, TBM_SETPOS, true, slider_pos); \
|
||||
SendDlgItemMessage(tab_id, slider_id, TBM_SETLINESIZE, 0, 1); \
|
||||
SendDlgItemMessage(tab_id, slider_id, TBM_SETPAGESIZE, 0, 1); \
|
||||
sprintf(SliderValTxt, "%d", (slider_pos-64)*2); \
|
||||
SetWindowText(GetDlgItem(tab_id, slider_id ## _VAL), SliderValTxt); \
|
||||
}
|
||||
|
||||
#define InitSliderNoGUI(tab_id, slider_id, slider_low, slider_hi, slider_pos) \
|
||||
{ \
|
||||
SendDlgItemMessage(tab_id, slider_id, TBM_SETRANGE, true, MAKELONG(slider_low, slider_hi)); \
|
||||
SendDlgItemMessage(tab_id, slider_id, TBM_SETPOS, true, slider_pos); \
|
||||
SendDlgItemMessage(tab_id, slider_id, TBM_SETLINESIZE, 0, 1); \
|
||||
SendDlgItemMessage(tab_id, slider_id, TBM_SETPAGESIZE, 0, 1); \
|
||||
}
|
||||
|
||||
#define DisableButtonGroup(btn_firstid, btn_lastid, seltab) \
|
||||
{ \
|
||||
for (WORD bgci = btn_firstid; bgci <= btn_lastid; bgci++) \
|
||||
{ \
|
||||
EnableWindow(GetDlgItem(ModuleWnd[seltab], bgci), true); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define InterleavedButtonGroupChanged(btn_firstid, btn_count, test_id, result_index)\
|
||||
{ \
|
||||
result_index = -1; \
|
||||
if (((LOWORD(test_id)-btn_firstid) % 6) == 0) \
|
||||
{ \
|
||||
for (WORD bgci = 0; bgci < btn_count; bgci++) \
|
||||
{ \
|
||||
WORD ibtn = btn_firstid+bgci*6; \
|
||||
if (LOWORD(test_id) == ibtn) \
|
||||
{ \
|
||||
EnableWindow(GetDlgItem(TabWnd[SelectedTab], ibtn), false); \
|
||||
result_index = bgci; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
EnableWindow(GetDlgItem(TabWnd[SelectedTab], ibtn), true); \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
#define DisableInterleavedButtonGroup(btn_firstid, btn_count, seltab) \
|
||||
{ \
|
||||
for (WORD bgci = 0; bgci < btn_count; bgci++) \
|
||||
{ \
|
||||
EnableWindow(GetDlgItem(TabWnd[seltab], btn_firstid+bgci*6), true); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define UpdateSliderValue(usv_id, usv_v) \
|
||||
{ \
|
||||
usv_v = SendMessage(GetDlgItem(ModuleWnd[uid], usv_id), TBM_GETPOS, 0, 0); \
|
||||
sprintf(SliderValTxt, "%d", usv_v); \
|
||||
SetWindowText(GetDlgItem(ModuleWnd[uid], usv_id ## _VAL), SliderValTxt); \
|
||||
}
|
||||
|
||||
#define UpdateSliderValueCenter(usv_id, usv_v) \
|
||||
{ \
|
||||
usv_v = SendMessage(GetDlgItem(ModuleWnd[uid], usv_id), TBM_GETPOS, 0, 0); \
|
||||
sprintf(SliderValTxt, "%d", usv_v-64); \
|
||||
SetWindowText(GetDlgItem(ModuleWnd[uid], usv_id ## _VAL), SliderValTxt); \
|
||||
}
|
||||
|
||||
#define UpdateSliderValueCenter2(usv_id, usv_v) \
|
||||
{ \
|
||||
usv_v = SendMessage(GetDlgItem(ModuleWnd[uid], usv_id), TBM_GETPOS, 0, 0); \
|
||||
sprintf(SliderValTxt, "%d", (usv_v-64)*2); \
|
||||
SetWindowText(GetDlgItem(ModuleWnd[uid], usv_id ## _VAL), SliderValTxt); \
|
||||
}
|
||||
|
||||
void Go4kVSTiGUI_Create(HINSTANCE hInst);
|
||||
void Go4kVSTiGUI_Show(int showCommand);
|
||||
void Go4kVSTiGUI_Destroy();
|
||||
|
||||
bool InitTabDlg();
|
||||
|
||||
bool ButtonPressed(WPARAM id, LPARAM lParam);
|
||||
bool ScrollbarChanged(HWND hwndDlg, WPARAM wParam, LPARAM lParam);
|
||||
bool StackButtonPressed(WPARAM id);
|
||||
void TabChanged(int index);
|
||||
|
||||
void UpdateSignalCount(int channel);
|
||||
void UpdateControls(int channel);
|
||||
void UpdateModuleParamWindow(int tab, int unit);
|
||||
void UpdateVoiceDisplay(int i);
|
||||
|
||||
void GetStreamFileName();
|
||||
|
||||
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
#include <windows.h>
|
||||
#include <stddef.h>
|
||||
#include "Go4kVSTi.h"
|
||||
#include "Go4kVSTiGUI.h"
|
||||
|
||||
static AudioEffect *effect = 0;
|
||||
bool oome = false;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// prototype of the export function main
|
||||
int main (audioMasterCallback audioMaster);
|
||||
|
||||
int main (audioMasterCallback audioMaster)
|
||||
{
|
||||
// get vst version
|
||||
if(!audioMaster (0, audioMasterVersion, 0, 0, 0, 0))
|
||||
return 0; // old version
|
||||
|
||||
effect = new Go4kVSTi (audioMaster);
|
||||
if (!effect)
|
||||
return 0;
|
||||
if (oome)
|
||||
{
|
||||
delete effect;
|
||||
return 0;
|
||||
}
|
||||
return (int)effect->getAeffect();
|
||||
}
|
||||
|
||||
void* hInstance;
|
||||
BOOL WINAPI DllMain (HINSTANCE hInst, DWORD dwReason, LPVOID lpvReserved)
|
||||
{
|
||||
switch (dwReason)
|
||||
{
|
||||
// wird aufgerufen, wenn zum ersten mal das plugin aktiviert wird
|
||||
// also hier init für den synth
|
||||
case DLL_PROCESS_ATTACH:
|
||||
//MessageBox(NULL, "DLL_PROCESS_ATTACH", "DllMain", MB_OK);
|
||||
Go4kVSTiGUI_Create(hInst);
|
||||
Go4kVSTiGUI_Show(SW_SHOW);
|
||||
break;
|
||||
// wird aufgerufen, wenn das plugin nicht mehr verwendet wird
|
||||
// entweder bei entfernen des letzten, schliessen des songs oder
|
||||
// des programms. Also hier Deinit und zerstörung des Synths
|
||||
case DLL_PROCESS_DETACH:
|
||||
//MessageBox(NULL, "DLL_PROCESS_DETACH", "DllMain", MB_OK);
|
||||
Go4kVSTiGUI_Destroy();
|
||||
effect = 0;
|
||||
break;
|
||||
// die beiden brauchts wohl nicht
|
||||
case DLL_THREAD_ATTACH:
|
||||
//MessageBox(NULL, "DLL_THREAD_ATTACH", "DllMain", MB_OK);
|
||||
break;
|
||||
case DLL_THREAD_DETACH:
|
||||
//MessageBox(NULL, "DLL_THREAD_DETACH", "DllMain", MB_OK);
|
||||
break;
|
||||
}
|
||||
hInstance = hInst;
|
||||
return 1;
|
||||
}
|
||||
@@ -1,158 +0,0 @@
|
||||
#ifndef __Go4kVSTi__
|
||||
#include "Go4kVSTi.h"
|
||||
#include "Go4kVSTiCore.h"
|
||||
#include "stdio.h"
|
||||
#endif
|
||||
|
||||
#include "math.h"
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
void Go4kVSTi::setSampleRate (float sampleRate)
|
||||
{
|
||||
AudioEffectX::setSampleRate (sampleRate);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
void Go4kVSTi::setBlockSize (long blockSize)
|
||||
{
|
||||
AudioEffectX::setBlockSize (blockSize);
|
||||
// you may need to have to do something here...
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
void Go4kVSTi::suspend ()
|
||||
{
|
||||
m_currentEvents.clear();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
void Go4kVSTi::resume ()
|
||||
{
|
||||
wantEvents ();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
void Go4kVSTi::initProcess ()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
void Go4kVSTi::process (float **inputs, float **outputs, long sampleFrames)
|
||||
{
|
||||
processAnyhow(inputs, outputs, sampleFrames);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
void Go4kVSTi::processReplacing (float **inputs, float **outputs, long sampleFrames)
|
||||
{
|
||||
processAnyhow(inputs, outputs, sampleFrames);
|
||||
}
|
||||
|
||||
void Go4kVSTi::processAnyhow(float **inputs, float **outputs, long sampleFrames)
|
||||
{
|
||||
float* outl = outputs[0];
|
||||
float* outr = outputs[1];
|
||||
static int bpmCheck = 0;
|
||||
if ( bpmCheck <= 0 )
|
||||
{
|
||||
VstTimeInfo* myTime = getTimeInfo ( kVstTempoValid );
|
||||
Go4kVSTi_SetBPM(myTime->tempo);
|
||||
bpmCheck = 20; // only check every 20th call of this function (bpm shouldnt change that often)
|
||||
}
|
||||
bpmCheck--;
|
||||
|
||||
int start = 0;
|
||||
// midi events will occur this frame, so render partially
|
||||
if (m_currentEvents.size() > 0)
|
||||
{
|
||||
// for all events
|
||||
for (unsigned int i = 0; i < m_currentEvents.size(); i++)
|
||||
{
|
||||
// process samples until next event
|
||||
int todo = m_currentEvents[i]->deltaFrames - start;
|
||||
Go4kVSTi_Tick(outl+start, outr+start, todo);
|
||||
start = m_currentEvents[i]->deltaFrames;
|
||||
// apply changes due to event
|
||||
ApplyEvent(m_currentEvents[i]);
|
||||
}
|
||||
}
|
||||
Go4kVSTi_Tick(outl+start, outr+start, sampleFrames - start);
|
||||
|
||||
// clear event list (old event pointer wont be valid next frame anyway)
|
||||
m_currentEvents.clear();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
long Go4kVSTi::processEvents(VstEvents* ev)
|
||||
{
|
||||
for (long i = 0; i < ev->numEvents; i++)
|
||||
{
|
||||
if ((ev->events[i])->type != kVstMidiType)
|
||||
continue;
|
||||
VstMidiEvent* event = (VstMidiEvent*)ev->events[i];
|
||||
m_currentEvents.push_back(event);
|
||||
}
|
||||
return 1; // want more
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
void Go4kVSTi::ApplyEvent(VstMidiEvent *event)
|
||||
{
|
||||
char* midiData = event->midiData;
|
||||
byte status = midiData[0] & 0xf0; // status
|
||||
byte channel = midiData[0] & 0x0f; // channel
|
||||
|
||||
// note on/off events
|
||||
if (status == 0x90 || status == 0x80)
|
||||
{
|
||||
byte note = midiData[1] & 0x7f;
|
||||
byte velocity = midiData[2] & 0x7f;
|
||||
if (status == 0x80)
|
||||
velocity = 0;
|
||||
// note off
|
||||
if (!velocity)
|
||||
{
|
||||
Go4kVSTi_StopVoice(channel, note);
|
||||
}
|
||||
// note on
|
||||
else
|
||||
{
|
||||
Go4kVSTi_AddVoice(channel, note);
|
||||
}
|
||||
}
|
||||
/* // polyphonic aftertouch
|
||||
else if (status == 0xA)
|
||||
{
|
||||
byte note = midiData[1] & 0x7f;
|
||||
byte pressure = midiData[2] & 0x7f;
|
||||
Go4kVSTi_PolyAftertouch(channel, note, pressure);
|
||||
}
|
||||
// channel aftertouch
|
||||
else if (status == 0xD)
|
||||
{
|
||||
byte pressure = midiData[1] & 0x7f;
|
||||
Go4kVSTi_ChannelAftertouch(channel, pressure);
|
||||
}
|
||||
// Controller Change
|
||||
else if (status == 0xB0)
|
||||
{
|
||||
byte number = midiData[1] & 0x7f;
|
||||
byte value = midiData[2] & 0x7f;
|
||||
// Go4kVSTi_ControllerChange(channel, number, value, event->deltaFrames);
|
||||
}
|
||||
// Pitch Bend
|
||||
else if (status == 0xE0)
|
||||
{
|
||||
byte lsb = midiData[1] & 0x7f;
|
||||
byte msb = midiData[2] & 0x7f;
|
||||
int value = (((int)(msb)) << 7) + lsb;
|
||||
// Go4kVSTi_PitchBend(channel, value); // 0 - 16383, center 8192
|
||||
// dont use full precision for the sake of equally sized streams
|
||||
// Go4kVSTi_PitchBend(channel, value >> 7, event->deltaFrames); // 0 - 127, center 64
|
||||
}*/
|
||||
// all notes off (dont seem to come anyway
|
||||
else if (status == 0xb0 && midiData[1] == 0x7e) // all notes off
|
||||
{
|
||||
Go4kVSTi_StopVoice(channel, 0);
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
#ifndef __AEffEditor__
|
||||
#define __AEffEditor__
|
||||
|
||||
class AudioEffect;
|
||||
|
||||
struct ERect
|
||||
{
|
||||
short top;
|
||||
short left;
|
||||
short bottom;
|
||||
short right;
|
||||
};
|
||||
|
||||
class AEffEditor
|
||||
{
|
||||
public:
|
||||
AEffEditor (AudioEffect *effect) {this->effect = effect; updateFlag = 0; }
|
||||
virtual ~AEffEditor() {}
|
||||
|
||||
virtual long getRect(ERect **rect) {*rect = 0; return 0;}
|
||||
virtual long open(void *ptr) {systemWindow = ptr; return 0;}
|
||||
virtual void close() {}
|
||||
virtual void idle() { if(updateFlag) {updateFlag = 0; update();} }
|
||||
|
||||
#if MAC
|
||||
virtual void draw(ERect *rect) {rect = rect;}
|
||||
virtual long mouse(long x, long y) {x = x; y = y; return 0;}
|
||||
virtual long key(long keyCode) {keyCode = keyCode; return 0;}
|
||||
virtual void top() {}
|
||||
virtual void sleep() {}
|
||||
#endif
|
||||
virtual void update() {}
|
||||
virtual void postUpdate() {updateFlag = 1;}
|
||||
|
||||
protected:
|
||||
AEffEditor () {};
|
||||
|
||||
AudioEffect *effect;
|
||||
void *systemWindow;
|
||||
long updateFlag;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,172 +0,0 @@
|
||||
#ifndef __AEffect__
|
||||
#define __AEffect__
|
||||
|
||||
/*
|
||||
to create an Audio Effect for power pc's, create a
|
||||
code resource
|
||||
file type: 'aPcs'
|
||||
resource type: 'aEff'
|
||||
ppc header: none (raw pef)
|
||||
|
||||
for windows, it's a .dll
|
||||
|
||||
the only symbol searched for is:
|
||||
AEffect *main(float (*audioMaster)(AEffect *effect, long opcode, long index,
|
||||
long value, void *ptr, float opt));
|
||||
*/
|
||||
|
||||
#if PRAGMA_ALIGN_SUPPORTED || __MWERKS__
|
||||
#pragma options align=mac68k
|
||||
#elif defined CBUILDER
|
||||
#pragma -a8
|
||||
#elif defined(WIN32) || defined(__FLAT__)
|
||||
#pragma pack(push)
|
||||
#pragma pack(8)
|
||||
#endif
|
||||
|
||||
#if defined(WIN32) || defined(__FLAT__) || defined CBUILDER
|
||||
#define VSTCALLBACK __cdecl
|
||||
#else
|
||||
#define VSTCALLBACK
|
||||
#endif
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
// misc def's
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
typedef struct AEffect AEffect;
|
||||
typedef long (VSTCALLBACK *audioMasterCallback)(AEffect *effect, long opcode, long index,
|
||||
long value, void *ptr, float opt);
|
||||
|
||||
// prototype for plug-in main
|
||||
// AEffect *main(audioMasterCallback audioMaster);
|
||||
|
||||
#ifdef CBUILDER
|
||||
#define kEffectMagic 'PtsV'
|
||||
#else
|
||||
#define kEffectMagic 'VstP'
|
||||
#endif
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
struct AEffect
|
||||
{
|
||||
long magic; // must be kEffectMagic ('VstP')
|
||||
long (VSTCALLBACK *dispatcher)(AEffect *effect, long opCode, long index, long value,
|
||||
void *ptr, float opt);
|
||||
void (VSTCALLBACK *process)(AEffect *effect, float **inputs, float **outputs, long sampleframes);
|
||||
void (VSTCALLBACK *setParameter)(AEffect *effect, long index, float parameter);
|
||||
float (VSTCALLBACK *getParameter)(AEffect *effect, long index);
|
||||
|
||||
long numPrograms;
|
||||
long numParams; // all programs are assumed to have numParams parameters
|
||||
long numInputs; //
|
||||
long numOutputs; //
|
||||
long flags; // see constants
|
||||
long resvd1; // reserved, must be 0
|
||||
long resvd2; // reserved, must be 0
|
||||
long initialDelay; // for algorithms which need input in the first place
|
||||
long realQualities; // number of realtime qualities (0: realtime)
|
||||
long offQualities; // number of offline qualities (0: realtime only)
|
||||
float ioRatio; // input samplerate to output samplerate ratio, not used yet
|
||||
void *object; // for class access (see AudioEffect.hpp), MUST be 0 else!
|
||||
void *user; // user access
|
||||
long uniqueID; // pls choose 4 character as unique as possible.
|
||||
// this is used to identify an effect for save+load
|
||||
long version; //
|
||||
void (VSTCALLBACK *processReplacing)(AEffect *effect, float **inputs, float **outputs, long sampleframes);
|
||||
char future[60]; // pls zero
|
||||
};
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
// flags bits
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
#define effFlagsHasEditor 1 // if set, is expected to react to editor messages
|
||||
#define effFlagsHasClip 2 // return > 1. in getVu() if clipped
|
||||
#define effFlagsHasVu 4 // return vu value in getVu(); > 1. means clipped
|
||||
#define effFlagsCanMono 8 // if numInputs == 2, makes sense to be used for mono in
|
||||
#define effFlagsCanReplacing 16 // supports in place output (processReplacing() exsists)
|
||||
#define effFlagsProgramChunks 32 // program data are handled in formatless chunks
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
// dispatcher opCodes
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
enum
|
||||
{
|
||||
effOpen = 0, // initialise
|
||||
effClose, // exit, release all memory and other resources!
|
||||
|
||||
effSetProgram, // program no in <value>
|
||||
effGetProgram, // return current program no.
|
||||
effSetProgramName, // user changed program name (max 24 char + 0) to as passed in string
|
||||
effGetProgramName, // stuff program name (max 24 char + 0) into string
|
||||
|
||||
effGetParamLabel, // stuff parameter <index> label (max 8 char + 0) into string
|
||||
// (examples: sec, dB, type)
|
||||
effGetParamDisplay, // stuff parameter <index> textual representation into string
|
||||
// (examples: 0.5, -3, PLATE)
|
||||
effGetParamName, // stuff parameter <index> label (max 8 char + 0) into string
|
||||
// (examples: Time, Gain, RoomType)
|
||||
effGetVu, // called if (flags & (effFlagsHasClip | effFlagsHasVu))
|
||||
|
||||
// system
|
||||
|
||||
effSetSampleRate, // in opt (float)
|
||||
effSetBlockSize, // in value
|
||||
effMainsChanged, // the user has switched the 'power on' button to
|
||||
// value (0 off, else on). This only switches audio
|
||||
// processing; you should flush delay buffers etc.
|
||||
// editor
|
||||
|
||||
effEditGetRect, // stuff rect (top, left, bottom, right) into ptr
|
||||
effEditOpen, // system dependant Window pointer in ptr
|
||||
effEditClose, // no arguments
|
||||
effEditDraw, // draw method, ptr points to rect
|
||||
effEditMouse, // index: x, value: y
|
||||
effEditKey, // system keycode in value
|
||||
effEditIdle, // no arguments. Be gentle!
|
||||
effEditTop, // window has topped, no arguments
|
||||
effEditSleep, // window goes to background
|
||||
|
||||
// new
|
||||
|
||||
effIdentify, // returns 'NvEf'
|
||||
effGetChunk, // host requests pointer to chunk into (void**)ptr, byteSize returned
|
||||
effSetChunk, // plug-in receives saved chunk, byteSize passed
|
||||
|
||||
effNumOpcodes
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
// audioMaster opCodes
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
enum
|
||||
{
|
||||
audioMasterAutomate = 0, // index, value, returns 0
|
||||
audioMasterVersion, // vst version, currently 2 (0 for older)
|
||||
audioMasterCurrentId, // returns the unique id of a plug that's currently
|
||||
// loading
|
||||
audioMasterIdle, // call application idle routine (this will
|
||||
// call effEditIdle for all open editors too)
|
||||
audioMasterPinConnected // inquire if an input or output is beeing connected;
|
||||
// index enumerates input or output counting from zero,
|
||||
// value is 0 for input and != 0 otherwise. note: the
|
||||
// return value is 0 for <true> such that older versions
|
||||
// will always return true.
|
||||
|
||||
};
|
||||
|
||||
#if PRAGMA_ALIGN_SUPPORTED || __MWERKS__
|
||||
#pragma options align=reset
|
||||
#elif defined(WIN32) || defined(__FLAT__)
|
||||
#pragma pack(pop)
|
||||
#elif defined CBUILDER
|
||||
#pragma -a-
|
||||
#endif
|
||||
|
||||
#endif // __AEffect__
|
||||
@@ -1,382 +0,0 @@
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "AudioEffect.hpp"
|
||||
#include "AEffEditor.hpp"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
long dispatchEffectClass (AEffect *e, long opCode,
|
||||
long index, long value, void *ptr, float opt)
|
||||
{
|
||||
AudioEffect *ae = (AudioEffect *)(e->object);
|
||||
|
||||
if(opCode == effClose)
|
||||
{
|
||||
ae->dispatcher(opCode, index, value, ptr, opt);
|
||||
delete ae;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return ae->dispatcher(opCode, index, value, ptr, opt);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
float getParameterClass(AEffect *e, long index)
|
||||
{
|
||||
AudioEffect *ae = (AudioEffect *)(e->object);
|
||||
return ae->getParameter(index);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void setParameterClass(AEffect *e, long index, float value)
|
||||
{
|
||||
AudioEffect *ae = (AudioEffect *)(e->object);
|
||||
ae->setParameter(index, value);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void processClass(AEffect *e, float **inputs, float **outputs, long sampleFrames)
|
||||
{
|
||||
AudioEffect *ae = (AudioEffect *)(e->object);
|
||||
ae->process(inputs, outputs, sampleFrames);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void processClassReplacing(AEffect *e, float **inputs, float **outputs, long sampleFrames)
|
||||
{
|
||||
AudioEffect *ae = (AudioEffect *)(e->object);
|
||||
ae->processReplacing(inputs, outputs, sampleFrames);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
AudioEffect::AudioEffect(audioMasterCallback audioMaster, long numPrograms, long numParams)
|
||||
{
|
||||
this->audioMaster = audioMaster;
|
||||
editor = 0;
|
||||
this->numPrograms = numPrograms;
|
||||
this->numParams = numParams;
|
||||
curProgram = 0;
|
||||
|
||||
memset(&cEffect, 0, sizeof(cEffect));
|
||||
cEffect.magic = kEffectMagic;
|
||||
cEffect.dispatcher = dispatchEffectClass;
|
||||
cEffect.process = processClass;
|
||||
cEffect.setParameter = setParameterClass;
|
||||
cEffect.getParameter = getParameterClass;
|
||||
cEffect.numPrograms = numPrograms;
|
||||
cEffect.numParams = numParams;
|
||||
cEffect.numInputs = 1;
|
||||
cEffect.numOutputs = 2;
|
||||
cEffect.flags = 0;
|
||||
cEffect.resvd1 = 0;
|
||||
cEffect.resvd2 = 0;
|
||||
cEffect.initialDelay = 0;
|
||||
cEffect.realQualities = 0;
|
||||
cEffect.offQualities = 0;
|
||||
cEffect.ioRatio = 1.f;
|
||||
cEffect.object = this;
|
||||
cEffect.user = 0;
|
||||
cEffect.uniqueID = 'NoEf'; // you must set this!
|
||||
cEffect.version = 1;
|
||||
cEffect.processReplacing = processClassReplacing;
|
||||
|
||||
sampleRate = 44100.f;
|
||||
blockSize = 1024L;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
AudioEffect::~AudioEffect()
|
||||
{
|
||||
if(editor)
|
||||
delete editor;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
long AudioEffect::dispatcher(long opCode, long index, long value, void *ptr, float opt)
|
||||
{
|
||||
long v = 0;
|
||||
|
||||
switch(opCode)
|
||||
{
|
||||
case effOpen: open(); break;
|
||||
case effClose: close(); break;
|
||||
case effSetProgram: if(value < numPrograms) setProgram(value); break;
|
||||
case effGetProgram: v = getProgram(); break;
|
||||
case effSetProgramName: setProgramName((char *)ptr); break;
|
||||
case effGetProgramName: getProgramName((char *)ptr); break;
|
||||
case effGetParamLabel: getParameterLabel(index, (char *)ptr); break;
|
||||
case effGetParamDisplay: getParameterDisplay(index, (char *)ptr); break;
|
||||
case effGetParamName: getParameterName(index, (char *)ptr); break;
|
||||
|
||||
case effSetSampleRate: setSampleRate(opt); break;
|
||||
case effSetBlockSize: setBlockSize(value); break;
|
||||
case effMainsChanged: if(!value) suspend(); else resume(); break;
|
||||
case effGetVu: v = (long)(getVu() * 32767.); break;
|
||||
|
||||
// editor
|
||||
|
||||
case effEditGetRect: if(editor) v = editor->getRect((ERect **)ptr); break;
|
||||
case effEditOpen: if(editor) v = editor->open(ptr); break;
|
||||
case effEditClose: if(editor) editor->close(); break;
|
||||
case effEditIdle: if(editor) editor->idle(); break;
|
||||
|
||||
#if MAC
|
||||
case effEditDraw: if(editor) editor->draw((ERect *)ptr); break;
|
||||
case effEditMouse: if(editor) v = editor->mouse(index, value); break;
|
||||
case effEditKey: if(editor) v = editor->key(value); break;
|
||||
case effEditTop: if(editor) editor->top(); break;
|
||||
case effEditSleep: if(editor) editor->sleep(); break;
|
||||
#endif
|
||||
|
||||
// new
|
||||
|
||||
case effIdentify: v = 'NvEf'; break;
|
||||
case effGetChunk: v = getChunk((void**)ptr, index ? true : false); break;
|
||||
case effSetChunk: v = setChunk(ptr, value, index ? true : false); break;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
long AudioEffect::getMasterVersion()
|
||||
{
|
||||
long version = 1;
|
||||
if(audioMaster)
|
||||
{
|
||||
version = audioMaster(&cEffect, audioMasterVersion, 0, 0, 0, 0);
|
||||
if(!version) // old
|
||||
version = 1;
|
||||
}
|
||||
return version;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
long AudioEffect::getCurrentUniqueId()
|
||||
{
|
||||
long id = 0;
|
||||
if(audioMaster)
|
||||
id = audioMaster(&cEffect, audioMasterCurrentId, 0, 0, 0, 0);
|
||||
return id;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void AudioEffect::masterIdle()
|
||||
{
|
||||
if(audioMaster)
|
||||
audioMaster(&cEffect, audioMasterIdle, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
bool AudioEffect::isInputConnected(long input)
|
||||
{
|
||||
long ret = 0;
|
||||
if(audioMaster)
|
||||
ret = audioMaster(&cEffect, audioMasterPinConnected, input, 0, 0, 0);
|
||||
return ret ? false : true; // return value is 0 for true
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
bool AudioEffect::isOutputConnected(long output)
|
||||
{
|
||||
long ret = 0;
|
||||
if(audioMaster)
|
||||
ret = audioMaster(&cEffect, audioMasterPinConnected, output, 1, 0, 0);
|
||||
return ret ? false : true; // return value is 0 for true
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// flags
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void AudioEffect::hasVu(bool state)
|
||||
{
|
||||
if(state)
|
||||
cEffect.flags |= effFlagsHasVu;
|
||||
else
|
||||
cEffect.flags &= ~effFlagsHasVu;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void AudioEffect::hasClip(bool state)
|
||||
{
|
||||
if(state)
|
||||
cEffect.flags |= effFlagsHasClip;
|
||||
else
|
||||
cEffect.flags &= ~effFlagsHasClip;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void AudioEffect::canMono(bool state)
|
||||
{
|
||||
if(state)
|
||||
cEffect.flags |= effFlagsCanMono;
|
||||
else
|
||||
cEffect.flags &= ~effFlagsCanMono;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void AudioEffect::canProcessReplacing(bool state)
|
||||
{
|
||||
if(state)
|
||||
cEffect.flags |= effFlagsCanReplacing;
|
||||
else
|
||||
cEffect.flags &= ~effFlagsCanReplacing;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void AudioEffect::programsAreChunks(bool state)
|
||||
{
|
||||
if(state)
|
||||
cEffect.flags |= effFlagsProgramChunks;
|
||||
else
|
||||
cEffect.flags &= ~effFlagsProgramChunks;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void AudioEffect::setRealtimeQualities(long qualities)
|
||||
{
|
||||
cEffect.realQualities = qualities;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void AudioEffect::setOfflineQualities(long qualities)
|
||||
{
|
||||
cEffect.offQualities = qualities;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void AudioEffect::setInitialDelay(long delay)
|
||||
{
|
||||
cEffect.initialDelay = delay;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// string
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void AudioEffect::dB2string(float value, char *text)
|
||||
{
|
||||
if(value <= 0)
|
||||
#if MAC
|
||||
strcpy(text, " -° ");
|
||||
#else
|
||||
strcpy(text, " -oo ");
|
||||
#endif
|
||||
else
|
||||
float2string((float)(20. * log10(value)), text);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void AudioEffect::Hz2string(float samples, char *text)
|
||||
{
|
||||
float sampleRate = getSampleRate();
|
||||
if(!samples)
|
||||
float2string(0, text);
|
||||
else
|
||||
float2string(sampleRate / samples, text);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void AudioEffect::ms2string(float samples, char *text)
|
||||
{
|
||||
float2string((float)(samples * 1000. / getSampleRate()), text);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void AudioEffect::float2string(float value, char *text)
|
||||
{
|
||||
long c = 0, neg = 0;
|
||||
char string[32];
|
||||
char *s;
|
||||
double v, integ, i10, mantissa, m10, ten = 10.;
|
||||
|
||||
v = (double)value;
|
||||
if(v < 0)
|
||||
{
|
||||
neg = 1;
|
||||
value = -value;
|
||||
v = -v;
|
||||
c++;
|
||||
if(v > 9999999.)
|
||||
{
|
||||
strcpy(string, " Huge! ");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if(v > 99999999.)
|
||||
{
|
||||
strcpy(string, " Huge! ");
|
||||
return;
|
||||
}
|
||||
|
||||
s = string + 31;
|
||||
*s-- = 0;
|
||||
*s-- = '.';
|
||||
c++;
|
||||
|
||||
integ = floor(v);
|
||||
i10 = fmod(integ, ten);
|
||||
*s-- = (long)i10 + '0';
|
||||
integ /= ten;
|
||||
c++;
|
||||
while(integ >= 1. && c < 8)
|
||||
{
|
||||
i10 = fmod(integ, ten);
|
||||
*s-- = (long)i10 + '0';
|
||||
integ /= ten;
|
||||
c++;
|
||||
}
|
||||
if(neg)
|
||||
*s-- = '-';
|
||||
strcpy(text, s + 1);
|
||||
if(c >= 8)
|
||||
return;
|
||||
|
||||
s = string + 31;
|
||||
*s-- = 0;
|
||||
mantissa = fmod(v, 1.);
|
||||
mantissa *= pow(ten, (double)(8 - c));
|
||||
while(c < 8)
|
||||
{
|
||||
if(mantissa <= 0)
|
||||
*s-- = '0';
|
||||
else
|
||||
{
|
||||
m10 = fmod(mantissa, ten);
|
||||
*s-- = (long)m10 + '0';
|
||||
mantissa /= 10.;
|
||||
}
|
||||
c++;
|
||||
}
|
||||
strcat(text, s + 1);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void AudioEffect::long2string(long value, char *text)
|
||||
{
|
||||
char string[32];
|
||||
|
||||
if(value >= 100000000)
|
||||
{
|
||||
strcpy(text, " Huge! ");
|
||||
return;
|
||||
}
|
||||
sprintf(string, "%7d", value);
|
||||
string[8] = 0;
|
||||
strcpy(text, (char *)string);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void AudioEffect::setParameterAutomated(long index, float value)
|
||||
{
|
||||
setParameter(index, value);
|
||||
if(audioMaster)
|
||||
audioMaster(&cEffect, audioMasterAutomate, index, 0, 0, value); // value is in opt
|
||||
}
|
||||
|
||||
@@ -1,109 +0,0 @@
|
||||
#ifndef __AudioEffect__
|
||||
#define __AudioEffect__
|
||||
|
||||
#include "AEffect.h" // "c" interface
|
||||
#include <string.h>
|
||||
|
||||
class AEffEditor;
|
||||
class AudioEffect;
|
||||
|
||||
// Needs to be defined by the audio effect and is
|
||||
// called to create the audio effect object instance.
|
||||
AudioEffect* createEffectInstance (audioMasterCallback audioMaster);
|
||||
|
||||
long dispatchEffectClass(AEffect *e,
|
||||
long opCode, long index, long value, void *ptr, float opt);
|
||||
float getParameterClass(long index);
|
||||
void setParameterClass(long index, float value);
|
||||
void processClass(AEffect *e, float **inputs, float **outputs, long sampleFrames);
|
||||
void processClassReplacing(AEffect *e, float **inputs, float **outputs, long sampleFrames);
|
||||
|
||||
class AudioEffect
|
||||
{
|
||||
friend class AEffEditor;
|
||||
friend long dispatchEffectClass(AEffect *e, long opCode, long index, long value, void *ptr, float opt);
|
||||
friend float getParameterClass(AEffect *e, long index);
|
||||
friend void setParameterClass(AEffect *e, long index, float value);
|
||||
friend void processClass(AEffect *e, float **inputs, float **outputs, long sampleFrames);
|
||||
friend void processClassReplacing(AEffect *e, float **inputs, float **outputs, long sampleFrames);
|
||||
|
||||
public:
|
||||
AudioEffect(audioMasterCallback audioMaster, long numPrograms, long numParams);
|
||||
virtual ~AudioEffect();
|
||||
|
||||
virtual void setParameter(long index, float value) {index = index; value = value;}
|
||||
virtual float getParameter(long index) {index = index; return 0;}
|
||||
virtual void setParameterAutomated(long index, float value);
|
||||
|
||||
AEffect *getAeffect() {return &cEffect;}
|
||||
void setEditor(AEffEditor *editor)
|
||||
{ this->editor = editor;
|
||||
if(editor) cEffect.flags |= effFlagsHasEditor;
|
||||
else cEffect.flags &= ~effFlagsHasEditor;}
|
||||
|
||||
// called from audio master
|
||||
virtual void process(float **inputs, float **outputs, long sampleFrames) = 0;
|
||||
virtual void processReplacing(float **inputs, float **outputs, long sampleFrames)
|
||||
{inputs = inputs; outputs = outputs; sampleFrames = sampleFrames;}
|
||||
virtual long dispatcher(long opCode, long index, long value, void *ptr, float opt);
|
||||
virtual void open() {}
|
||||
virtual void close() {}
|
||||
virtual long getProgram() {return curProgram;}
|
||||
virtual void setProgram(long program) {curProgram = program;} // don't forget to set curProgram
|
||||
virtual void setProgramName(char *name) {*name = 0;} // all following refer to curProgram
|
||||
virtual void getProgramName(char *name) {*name = 0;}
|
||||
virtual void getParameterLabel(long index, char *label) {index = index; *label = 0;}
|
||||
virtual void getParameterDisplay(long index, char *text) {index = index; *text = 0;}
|
||||
virtual void getParameterName(long index, char *text) {index = index; *text = 0;}
|
||||
virtual float getVu() {return 0;}
|
||||
virtual long getChunk(void** data, bool isPreset = false) {return 0;} // returns byteSize
|
||||
virtual long setChunk(void* data, long byteSize, bool isPreset = false) {return 0;}
|
||||
virtual void setSampleRate(float sampleRate) {this->sampleRate = sampleRate;}
|
||||
virtual void setBlockSize(long blockSize) {this->blockSize = blockSize;}
|
||||
virtual void suspend() {}
|
||||
virtual void resume() {}
|
||||
|
||||
// setup
|
||||
virtual void setUniqueID(long iD) {cEffect.uniqueID = iD;} // must call this!
|
||||
virtual void setNumInputs(long inputs) {cEffect.numInputs = inputs;}
|
||||
virtual void setNumOutputs(long outputs) {cEffect.numOutputs = outputs;}
|
||||
virtual void hasVu(bool state = true);
|
||||
virtual void hasClip(bool state = true);
|
||||
virtual void canMono(bool state = true);
|
||||
virtual void canProcessReplacing(bool state = true);
|
||||
virtual void programsAreChunks(bool state = true);
|
||||
virtual void setRealtimeQualities(long qualities);
|
||||
virtual void setOfflineQualities(long qualities);
|
||||
virtual void setInitialDelay(long delay);
|
||||
|
||||
// inquiry
|
||||
virtual float getSampleRate() {return sampleRate;}
|
||||
virtual long getBlockSize() {return blockSize;}
|
||||
|
||||
// host communication
|
||||
virtual long getMasterVersion();
|
||||
virtual long getCurrentUniqueId();
|
||||
virtual void masterIdle();
|
||||
virtual bool isInputConnected(long input);
|
||||
virtual bool isOutputConnected(long output);
|
||||
|
||||
// tools
|
||||
virtual void dB2string(float value, char *text);
|
||||
virtual void Hz2string(float samples, char *text);
|
||||
virtual void ms2string(float samples, char *text);
|
||||
virtual void float2string(float value, char *string);
|
||||
virtual void long2string(long value, char *text);
|
||||
|
||||
protected:
|
||||
// members
|
||||
float sampleRate;
|
||||
AEffEditor *editor;
|
||||
audioMasterCallback audioMaster;
|
||||
long numPrograms;
|
||||
long numParams;
|
||||
long curProgram;
|
||||
long blockSize;
|
||||
AEffect cEffect;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,534 +0,0 @@
|
||||
#ifndef __aeffectx__
|
||||
#define __aeffectx__
|
||||
|
||||
#ifndef __AEffect__
|
||||
#include "AEffect.h"
|
||||
#endif
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
// VST Plug-Ins SDK
|
||||
// version 2.0 extension
|
||||
// (c)1999 Steinberg Soft+Hardware GmbH
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
// VstEvent
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
|
||||
typedef struct VstEvent VstEvent;
|
||||
typedef struct VstMidiEvent VstMidiEvent;
|
||||
typedef struct VstEvents VstEvents;
|
||||
|
||||
struct VstEvent // a generic timestamped event
|
||||
{
|
||||
long type; // see enum below
|
||||
long byteSize; // of this event, excl. type and byteSize
|
||||
long deltaFrames; // sample frames related to the current block start sample position
|
||||
long flags; // generic flags, none defined yet (0)
|
||||
|
||||
char data[16]; // size may vary but is usually 16
|
||||
};
|
||||
|
||||
enum // VstEvent types
|
||||
{
|
||||
kVstMidiType = 1, // midi event, can be cast as VstMidiEvent (see below)
|
||||
kVstAudioType, // audio
|
||||
kVstVideoType, // video
|
||||
kVstParameterType, // parameter
|
||||
kVstTriggerType // trigger
|
||||
// ...etc
|
||||
};
|
||||
|
||||
struct VstMidiEvent // to be casted from a VstEvent
|
||||
{
|
||||
long type; // kVstMidiType
|
||||
long byteSize; // 24
|
||||
long deltaFrames; // sample frames related to the current block start sample position
|
||||
long flags; // none defined yet
|
||||
|
||||
long noteLength; // (in sample frames) of entire note, if available, else 0
|
||||
long noteOffset; // offset into note from note start if available, else 0
|
||||
|
||||
char midiData[4]; // 1 thru 3 midi bytes; midiData[3] is reserved (zero)
|
||||
char detune; // -64 to +63 cents; for scales other than 'well-tempered' ('microtuning')
|
||||
char noteOffVelocity;
|
||||
char reserved1; // zero
|
||||
char reserved2; // zero
|
||||
};
|
||||
|
||||
struct VstEvents // a block of events for the current audio block
|
||||
{
|
||||
long numEvents;
|
||||
long reserved; // zero
|
||||
VstEvent* events[2]; // variable
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
// VstTimeInfo
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
|
||||
typedef struct VstTimeInfo VstTimeInfo;
|
||||
|
||||
// VstTimeInfo as requested via audioMasterGetTime (getTimeInfo())
|
||||
// refers to the current time slice. note the new slice is
|
||||
// already started when processEvents() is called
|
||||
|
||||
struct VstTimeInfo
|
||||
{
|
||||
double samplePos; // current location
|
||||
double sampleRate;
|
||||
double nanoSeconds; // system time
|
||||
double ppqPos; // 1 ppq
|
||||
double tempo; // in bpm
|
||||
double barStartPos; // last bar start, in 1 ppq
|
||||
double cycleStartPos; // 1 ppq
|
||||
double cycleEndPos; // 1 ppq
|
||||
long timeSigNumerator; // time signature
|
||||
long timeSigDenominator;
|
||||
long smpteOffset;
|
||||
long smpteFrameRate; // 0:24, 1:25, 2:29.97, 3:30, 4:29.97 df, 5:30 df
|
||||
long samplesToNextClock; // midi clock resolution (24 ppq), can be negative
|
||||
long flags; // see below
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
kVstTransportChanged = 1,
|
||||
kVstTransportPlaying = 1 << 1,
|
||||
kVstTransportCycleActive = 1 << 2,
|
||||
|
||||
kVstAutomationWriting = 1 << 6,
|
||||
kVstAutomationReading = 1 << 7,
|
||||
|
||||
// flags which indicate which of the fields in this VstTimeInfo
|
||||
// are valid; samplePos and sampleRate are always valid
|
||||
kVstNanosValid = 1 << 8,
|
||||
kVstPpqPosValid = 1 << 9,
|
||||
kVstTempoValid = 1 << 10,
|
||||
kVstBarsValid = 1 << 11,
|
||||
kVstCyclePosValid = 1 << 12, // start and end
|
||||
kVstTimeSigValid = 1 << 13,
|
||||
kVstSmpteValid = 1 << 14,
|
||||
kVstClockValid = 1 << 15
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
// VarIo
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
|
||||
typedef struct VstVariableIo VstVariableIo;
|
||||
|
||||
struct VstVariableIo
|
||||
{
|
||||
float **inputs;
|
||||
float **outputs;
|
||||
long numSamplesInput;
|
||||
long numSamplesOutput;
|
||||
long *numSamplesInputProcessed;
|
||||
long *numSamplesOutputProcessed;
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
// new audioMaster opCodes
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
enum
|
||||
{
|
||||
// VstEvents + VstTimeInfo
|
||||
audioMasterWantMidi = audioMasterPinConnected + 2, // <value> is a filter which is currently ignored
|
||||
audioMasterGetTime, // returns const VstTimeInfo* (or 0 if not supported)
|
||||
// <value> should contain a mask indicating which fields are required
|
||||
// (see valid masks above), as some items may require extensive
|
||||
// conversions
|
||||
audioMasterProcessEvents, // VstEvents* in <ptr>
|
||||
audioMasterSetTime, // VstTimenfo* in <ptr>, filter in <value>, not supported
|
||||
audioMasterTempoAt, // returns tempo (in bpm * 10000) at sample frame location passed in <value>
|
||||
|
||||
// parameters
|
||||
audioMasterGetNumAutomatableParameters,
|
||||
audioMasterGetParameterQuantization, // returns the integer value for +1.0 representation,
|
||||
// or 1 if full single float precision is maintained
|
||||
// in automation. parameter index in <value> (-1: all, any)
|
||||
// connections, configuration
|
||||
audioMasterIOChanged, // numInputs and/or numOutputs has changed
|
||||
audioMasterNeedIdle, // plug needs idle calls (outside its editor window)
|
||||
audioMasterSizeWindow, // index: width, value: height
|
||||
audioMasterGetSampleRate,
|
||||
audioMasterGetBlockSize,
|
||||
audioMasterGetInputLatency,
|
||||
audioMasterGetOutputLatency,
|
||||
audioMasterGetPreviousPlug, // input pin in <value> (-1: first to come), returns cEffect*
|
||||
audioMasterGetNextPlug, // output pin in <value> (-1: first to come), returns cEffect*
|
||||
|
||||
// realtime info
|
||||
audioMasterWillReplaceOrAccumulate, // returns: 0: not supported, 1: replace, 2: accumulate
|
||||
audioMasterGetCurrentProcessLevel, // returns: 0: not supported,
|
||||
// 1: currently in user thread (gui)
|
||||
// 2: currently in audio thread (where process is called)
|
||||
// 3: currently in 'sequencer' thread (midi, timer etc)
|
||||
// 4: currently offline processing and thus in user thread
|
||||
// other: not defined, but probably pre-empting user thread.
|
||||
audioMasterGetAutomationState, // returns 0: not supported, 1: off, 2:read, 3:write, 4:read/write
|
||||
|
||||
// offline
|
||||
audioMasterOfflineStart,
|
||||
audioMasterOfflineRead, // ptr points to offline structure, see below. return 0: error, 1 ok
|
||||
audioMasterOfflineWrite, // same as read
|
||||
audioMasterOfflineGetCurrentPass,
|
||||
audioMasterOfflineGetCurrentMetaPass,
|
||||
|
||||
// other
|
||||
audioMasterSetOutputSampleRate, // for variable i/o, sample rate in <opt>
|
||||
audioMasterGetSpeakerArrangement, // (long)input in <value>, output in <ptr>
|
||||
audioMasterGetVendorString, // fills <ptr> with a string identifying the vendor (max 64 char)
|
||||
audioMasterGetProductString, // fills <ptr> with a string with product name (max 64 char)
|
||||
audioMasterGetVendorVersion, // returns vendor-specific version
|
||||
audioMasterVendorSpecific, // no definition, vendor specific handling
|
||||
audioMasterSetIcon, // void* in <ptr>, format not defined yet
|
||||
audioMasterCanDo, // string in ptr, see below
|
||||
audioMasterGetLanguage, // see enum
|
||||
audioMasterOpenWindow, // returns platform specific ptr
|
||||
audioMasterCloseWindow, // close window, platform specific handle in <ptr>
|
||||
audioMasterGetDirectory, // get plug directory, FSSpec on MAC, else char*
|
||||
audioMasterUpdateDisplay // something has changed, update 'multi-fx' display
|
||||
};
|
||||
|
||||
enum VstHostLanguage
|
||||
{
|
||||
kVstLangEnglish = 1,
|
||||
kVstLangGerman,
|
||||
kVstLangFrench,
|
||||
kVstLangItalian,
|
||||
kVstLangSpanish,
|
||||
kVstLangJapanese
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
// dispatcher opCodes
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
enum
|
||||
{
|
||||
// VstEvents
|
||||
effProcessEvents = effSetChunk + 1, // VstEvents* in <ptr>
|
||||
|
||||
// parameters and programs
|
||||
effCanBeAutomated, // parameter index in <index>
|
||||
effString2Parameter, // parameter index in <index>, string in <ptr>
|
||||
effGetNumProgramCategories, // no arguments. this is for dividing programs into groups (like GM)
|
||||
effGetProgramNameIndexed, // get program name of category <value>, program <index> into <ptr>.
|
||||
// category (that is, <value>) may be -1, in which case program indices
|
||||
// are enumerated linearily (as usual); otherwise, each category starts
|
||||
// over with index 0.
|
||||
effCopyProgram, // copy current program to destination <index>
|
||||
// note: implies setParameter
|
||||
// connections, configuration
|
||||
effConnectInput, // input at <index> has been (dis-)connected;
|
||||
// <value> == 0: disconnected, else connected
|
||||
effConnectOutput, // same as input
|
||||
effGetInputProperties, // <index>, VstPinProperties* in ptr, return != 0 => true
|
||||
effGetOutputProperties, // dto
|
||||
effGetPlugCategory, // no parameter, return value is category
|
||||
|
||||
// realtime
|
||||
effGetCurrentPosition, // for external dsp, see flag bits below
|
||||
effGetDestinationBuffer, // for external dsp, see flag bits below. returns float*
|
||||
|
||||
// offline
|
||||
effOfflineNotify, // ptr = VstAudioFile array, value = count, index = start flag
|
||||
effOfflinePrepare, // ptr = VstOfflineTask array, value = count
|
||||
effOfflineRun, // dto
|
||||
|
||||
// other
|
||||
effProcessVarIo, // VstVariableIo* in <ptr>
|
||||
effSetSpeakerArrangement, // VstSpeakerArrangement* pluginInput in <value>
|
||||
// VstSpeakerArrangement* pluginOutput in <ptr>
|
||||
effSetBlockSizeAndSampleRate, // block size in <value>, sampleRate in <opt>
|
||||
effSetBypass, // onOff in <value> (0 = off)
|
||||
effGetEffectName, // char* name (max 32 bytes) in <ptr>
|
||||
effGetErrorText, // char* text (max 256 bytes) in <ptr>
|
||||
effGetVendorString, // fills <ptr> with a string identifying the vendor (max 64 char)
|
||||
effGetProductString, // fills <ptr> with a string with product name (max 64 char)
|
||||
effGetVendorVersion, // returns vendor-specific version
|
||||
effVendorSpecific, // no definition, vendor specific handling
|
||||
effCanDo, // <ptr>
|
||||
effGetTailSize, // returns tail size; 0 is default (return 1 for 'no tail')
|
||||
effIdle, // idle call in response to audioMasterneedIdle. must
|
||||
// return 1 to keep idle calls beeing issued
|
||||
|
||||
// gui
|
||||
effGetIcon, // void* in <ptr>, not yet defined
|
||||
effSetViewPosition, // set view position (in window) to x <index> y <value>
|
||||
|
||||
// and...
|
||||
effGetParameterProperties, // of param <index>, VstParameterProperties* in <ptr>
|
||||
effKeysRequired, // returns 0: needs keys (default for 1.0 plugs), 1: don't need
|
||||
effGetVstVersion, // returns 2; older versions return 0
|
||||
|
||||
effNumV2Opcodes
|
||||
// note that effNumOpcodes doesn't apply anymore
|
||||
};
|
||||
|
||||
typedef struct VstParameterProperties VstParameterProperties;
|
||||
typedef struct VstPinProperties VstPinProperties;
|
||||
|
||||
struct VstParameterProperties
|
||||
{
|
||||
float stepFloat;
|
||||
float smallStepFloat;
|
||||
float largeStepFloat;
|
||||
char label[64];
|
||||
long flags;
|
||||
long minInteger;
|
||||
long maxInteger;
|
||||
long stepInteger;
|
||||
long largeStepInteger;
|
||||
char shortLabel[8]; // recommended: 6 + delimiter
|
||||
char future[48];
|
||||
};
|
||||
|
||||
// parameter properties flags
|
||||
enum
|
||||
{
|
||||
kVstParameterIsSwitch = 1 << 0,
|
||||
kVstParameterUsesIntegerMinMax = 1 << 1,
|
||||
kVstParameterUsesFloatStep = 1 << 2,
|
||||
kVstParameterUsesIntStep = 1 << 3
|
||||
};
|
||||
|
||||
struct VstPinProperties
|
||||
{
|
||||
char label[64];
|
||||
long flags;
|
||||
long reserved;
|
||||
char shortLabel[8]; // recommended: 6 + delimiter
|
||||
char future[48];
|
||||
};
|
||||
|
||||
// pin properties flags
|
||||
enum
|
||||
{
|
||||
kVstPinIsActive = 1 << 0,
|
||||
kVstPinIsStereo = 1 << 1
|
||||
};
|
||||
|
||||
// category
|
||||
enum VstPlugCategory
|
||||
{
|
||||
kPlugCategUnknown = 0,
|
||||
kPlugCategEffect,
|
||||
kPlugCategSynth,
|
||||
kPlugCategAnalysis,
|
||||
kPlugCategMastering,
|
||||
kPlugCategSpacializer, // 'panners'
|
||||
kPlugCategRoomFx, // delays and reverbs
|
||||
kPlugSurroundFx // dedicated surround processor
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
// flags bits
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
enum
|
||||
{
|
||||
effFlagsIsSynth = 1 << 8, // host may assign mixer channels for its outputs
|
||||
effFlagsNoSoundInStop = 1 << 9, // does not produce sound when input is all silence
|
||||
effFlagsExtIsAsync = 1 << 10, // for external dsp; plug returns immedeately from process()
|
||||
// host polls plug position (current block) via effGetCurrentPosition
|
||||
effFlagsExtHasBuffer = 1 << 11 // external dsp, may have their own output buffe (32 bit float)
|
||||
// host then requests this via effGetDestinationBuffer
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
// surround setup
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
typedef struct VstSpeakerProperties VstSpeakerProperties;
|
||||
typedef struct VstSpeakerArrangement VstSpeakerArrangement;
|
||||
|
||||
struct VstSpeakerProperties
|
||||
{ // units: range: except:
|
||||
float azimuth; // rad -PI...PI 10.f for LFE channel
|
||||
float elevation; // rad -PI/2...PI/2 10.f for LFE channel
|
||||
float radius; // meter 0.f for LFE channel
|
||||
float reserved; // 0.
|
||||
char name[64]; // for new setups, new names should be given (L/R/C... won't do)
|
||||
char future[32];
|
||||
};
|
||||
|
||||
// note: the origin for azimuth is right (as by math conventions dealing with radians);
|
||||
// the elevation origin is also right, visualizing a rotation of a circle across the
|
||||
// -pi/pi axis of the horizontal circle. thus, an elevation of -pi/2 corresponds
|
||||
// to bottom, and a speaker standing on the left, and 'beaming' upwards would have
|
||||
// an azimuth of -pi, and an elevation of pi/2.
|
||||
// for user interface representation, grads are more likely to be used, and the
|
||||
// origins will obviously 'shift' accordingly.
|
||||
|
||||
struct VstSpeakerArrangement
|
||||
{
|
||||
float lfeGain; // LFE channel gain is adjusted [dB] higher than other channels
|
||||
long numChannels; // number of channels in this speaker arrangement
|
||||
VstSpeakerProperties speakers[8]; // variable
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
// offline
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
typedef struct VstOfflineTask VstOfflineTask;
|
||||
typedef struct VstAudioFile VstAudioFile;
|
||||
typedef struct VstAudioFileMarker VstAudioFileMarker;
|
||||
|
||||
struct VstOfflineTask
|
||||
{
|
||||
char processName[96]; // set by plug
|
||||
|
||||
// audio access
|
||||
double readPosition; // set by plug/host
|
||||
double writePosition; // set by plug/host
|
||||
long readCount; // set by plug/host
|
||||
long writeCount; // set by plug
|
||||
long sizeInputBuffer; // set by host
|
||||
long sizeOutputBuffer; // set by host
|
||||
void* inputBuffer; // set by host
|
||||
void* outputBuffer; // set by host
|
||||
double positionToProcessFrom; // set by host
|
||||
double numFramesToProcess; // set by host
|
||||
double maxFramesToWrite; // set by plug
|
||||
|
||||
// other data access
|
||||
void* extraBuffer; // set by plug
|
||||
long value; // set by host or plug
|
||||
long index; // set by host or plug
|
||||
|
||||
// file attributes
|
||||
double numFramesInSourceFile; // set by host
|
||||
double sourceSampleRate; // set by host or plug
|
||||
double destinationSampleRate; // set by host or plug
|
||||
long numSourceChannels; // set by host or plug
|
||||
long numDestinationChannels; // set by host or plug
|
||||
long sourceFormat; // set by host
|
||||
long destinationFormat; // set by plug
|
||||
char outputText[512]; // set by plug or host
|
||||
|
||||
// progress notification
|
||||
double progress; // set by plug
|
||||
long progressMode; // reserved for future
|
||||
char progressText[100]; // set by plug
|
||||
|
||||
long flags; // set by host and plug; see VstOfflineTaskFlags
|
||||
long returnValue; // reserved for future
|
||||
void* hostOwned; // set by host
|
||||
void* plugOwned; // set by plug
|
||||
|
||||
char future[1024];
|
||||
};
|
||||
|
||||
enum VstOfflineTaskFlags
|
||||
{
|
||||
// set by host
|
||||
kVstOfflineUnvalidParameter = 1 << 0,
|
||||
kVstOfflineNewFile = 1 << 1,
|
||||
|
||||
// set by plug
|
||||
kVstOfflinePlugError = 1 << 10,
|
||||
kVstOfflineInterleavedAudio = 1 << 11,
|
||||
kVstOfflineTempOutputFile = 1 << 12,
|
||||
kVstOfflineFloatOutputFile = 1 << 13,
|
||||
kVstOfflineRandomWrite = 1 << 14,
|
||||
kVstOfflineStretch = 1 << 15,
|
||||
kVstOfflineNoThread = 1 << 16
|
||||
};
|
||||
|
||||
// option passed to offlineRead/offlineWrite
|
||||
|
||||
enum VstOfflineOption
|
||||
{
|
||||
kVstOfflineAudio, // reading/writing audio samples
|
||||
kVstOfflinePeaks, // reading graphic representation
|
||||
kVstOfflineParameter, // reading/writing parameters
|
||||
kVstOfflineMarker, // reading/writing marker
|
||||
kVstOfflineCursor, // reading/moving edit cursor
|
||||
kVstOfflineSelection, // reading/changing selection
|
||||
kVstOfflineQueryFiles // to request the host to call asynchronously offlineNotify
|
||||
};
|
||||
|
||||
// structure passed to offlineNotify and offlineStart
|
||||
|
||||
struct VstAudioFile
|
||||
{
|
||||
long flags; // see enum VstAudioFileFlags
|
||||
void* hostOwned; // any data private to host
|
||||
void* plugOwned; // any data private to plugin
|
||||
char name[100]; // file title
|
||||
long uniqueId; // uniquely identify a file during a session
|
||||
double sampleRate; // file sample rate
|
||||
long numChannels; // number of channels (1 for mono, 2 for stereo...)
|
||||
double numFrames; // number of frames in the audio file
|
||||
long format; // reserved for future
|
||||
double editCursorPosition; // -1 if no such cursor
|
||||
double selectionStart; // frame index of first selected frame, or -1
|
||||
double selectionSize; // number of frames in selection, or 0
|
||||
long selectedChannelsMask; // 1 bit per channel
|
||||
long numMarkers; // number of markers in the file
|
||||
long timeRulerUnit; // see doc for possible values
|
||||
double timeRulerOffset; // offset in time ruler (positive or negative)
|
||||
double tempo; // as bpm
|
||||
long timeSigNumerator; // time signature numerator
|
||||
long timeSigDenominator; // time signature denominator
|
||||
long ticksPerBlackNote; // resolution
|
||||
long smpteFrameRate; // smpte rate (set as in VstTimeInfo)
|
||||
|
||||
char future[64];
|
||||
};
|
||||
|
||||
enum VstAudioFileFlags
|
||||
{
|
||||
// set by host (in call offlineNotify)
|
||||
kVstOfflineReadOnly = 1 << 0,
|
||||
kVstOfflineNoRateConversion = 1 << 1,
|
||||
kVstOfflineNoChannelChange = 1 << 2,
|
||||
|
||||
// Set by plug (in function offlineStart)
|
||||
kVstOfflineCanProcessSelection = 1 << 10,
|
||||
kVstOfflineNoCrossfade = 1 << 11,
|
||||
kVstOfflineWantRead = 1 << 12,
|
||||
kVstOfflineWantWrite = 1 << 13,
|
||||
kVstOfflineWantWriteMarker = 1 << 14,
|
||||
kVstOfflineWantMoveCursor = 1 << 15,
|
||||
kVstOfflineWantSelect = 1 << 16
|
||||
};
|
||||
|
||||
struct VstAudioFileMarker
|
||||
{
|
||||
double position;
|
||||
char name[32];
|
||||
long type;
|
||||
long id;
|
||||
long reserved;
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
// others
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
// structure passed to openWindow and closeWindow
|
||||
|
||||
struct VstWindow
|
||||
{
|
||||
char title[128]; // title
|
||||
short xPos; // position and size
|
||||
short yPos;
|
||||
short width;
|
||||
short height;
|
||||
long style; // 0: with title, 1: without title
|
||||
|
||||
void *parent; // parent of this window
|
||||
void *userHandle; // reserved
|
||||
void *winHandle; // reserved
|
||||
|
||||
char future[104];
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,558 +0,0 @@
|
||||
#ifndef __audioeffectx__
|
||||
#include "audioeffectx.h"
|
||||
#endif
|
||||
|
||||
// *** steinberg developers: this is a public file, *do not edit!*
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
// VST Plug-Ins SDK
|
||||
// version 2.0 extension
|
||||
// (c)1999 Steinberg Soft+Hardware GmbH
|
||||
//
|
||||
// you should not have to edit this file
|
||||
// use override methods instead, as suggested in the class declaration (audioeffectx.h)
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
// 'canDo' strings. note other 'canDos' can be evaluated by calling the according
|
||||
// function, for instance if getSampleRate returns 0, you
|
||||
// will certainly want to assume that this selector is not supported.
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
const char* hostCanDos [] =
|
||||
{
|
||||
"sendVstEvents",
|
||||
"sendVstMidiEvent",
|
||||
"sendVstTimeInfo",
|
||||
"receiveVstEvents",
|
||||
"receiveVstMidiEvent",
|
||||
"receiveVstTimeInfo",
|
||||
|
||||
"reportConnectionChanges",
|
||||
"acceptIOChanges",
|
||||
"sizeWindow",
|
||||
|
||||
"asyncProcessing",
|
||||
"offline",
|
||||
"supplyIdle",
|
||||
"supportShell" // 'shell' handling via uniqueID as suggested by Waves
|
||||
};
|
||||
|
||||
const char* plugCanDos [] =
|
||||
{
|
||||
"sendVstEvents",
|
||||
"sendVstMidiEvent",
|
||||
"sendVstTimeInfo",
|
||||
"receiveVstEvents",
|
||||
"receiveVstMidiEvent",
|
||||
"receiveVstTimeInfo",
|
||||
"offline",
|
||||
"plugAsChannelInsert",
|
||||
"plugAsSend",
|
||||
"mixDryWet",
|
||||
"noRealTime",
|
||||
"multipass",
|
||||
"metapass",
|
||||
"1in1out",
|
||||
"1in2out",
|
||||
"2in1out",
|
||||
"2in2out",
|
||||
"2in4out",
|
||||
"4in2out",
|
||||
"4in4out",
|
||||
"4in8out", // 4:2 matrix to surround bus
|
||||
"8in4out", // surround bus to 4:2 matrix
|
||||
"8in8out"
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
// AudioEffectX extends AudioEffect with the new features. so you should derive
|
||||
// your plug from AudioEffectX
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
// VstEvents + VstTimeInfo
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
AudioEffectX::AudioEffectX (audioMasterCallback audioMaster, long numPrograms, long numParams)
|
||||
: AudioEffect (audioMaster, numPrograms, numParams)
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
AudioEffectX::~AudioEffectX ()
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
long AudioEffectX::dispatcher (long opCode, long index, long value, void *ptr, float opt)
|
||||
{
|
||||
long v = 0;
|
||||
switch(opCode)
|
||||
{
|
||||
// VstEvents
|
||||
case effProcessEvents:
|
||||
v = processEvents ((VstEvents*)ptr);
|
||||
break;
|
||||
|
||||
// parameters and programs
|
||||
case effCanBeAutomated:
|
||||
v = canParameterBeAutomated (index) ? 1 : 0;
|
||||
break;
|
||||
case effString2Parameter:
|
||||
v = string2parameter (index, (char*)ptr) ? 1 : 0;
|
||||
break;
|
||||
|
||||
case effGetNumProgramCategories:
|
||||
v = getNumCategories ();
|
||||
break;
|
||||
case effGetProgramNameIndexed:
|
||||
v = getProgramNameIndexed (value, index, (char*)ptr) ? 1 : 0;
|
||||
break;
|
||||
case effCopyProgram:
|
||||
v = copyProgram (index) ? 1 : 0;
|
||||
break;
|
||||
|
||||
// connections, configuration
|
||||
case effConnectInput:
|
||||
inputConnected (index, value ? true : false);
|
||||
v = 1;
|
||||
break;
|
||||
case effConnectOutput:
|
||||
outputConnected (index, value ? true : false);
|
||||
v = 1;
|
||||
break;
|
||||
case effGetInputProperties:
|
||||
v = getInputProperties (index, (VstPinProperties*)ptr) ? 1 : 0;
|
||||
break;
|
||||
case effGetOutputProperties:
|
||||
v = getOutputProperties (index, (VstPinProperties*)ptr) ? 1 : 0;
|
||||
break;
|
||||
case effGetPlugCategory:
|
||||
v = (long)getPlugCategory ();
|
||||
break;
|
||||
|
||||
// realtime
|
||||
case effGetCurrentPosition:
|
||||
v = reportCurrentPosition ();
|
||||
break;
|
||||
|
||||
case effGetDestinationBuffer:
|
||||
v = (long)reportDestinationBuffer ();
|
||||
break;
|
||||
|
||||
// offline
|
||||
case effOfflineNotify:
|
||||
v = offlineNotify ((VstAudioFile*)ptr, value, index != 0);
|
||||
break;
|
||||
case effOfflinePrepare:
|
||||
v = offlinePrepare ((VstOfflineTask*)ptr, value);
|
||||
break;
|
||||
case effOfflineRun:
|
||||
v = offlineRun ((VstOfflineTask*)ptr, value);
|
||||
break;
|
||||
|
||||
// other
|
||||
case effSetSpeakerArrangement:
|
||||
v = setSpeakerArrangement ((VstSpeakerArrangement*)value, (VstSpeakerArrangement*)ptr) ? 1 : 0;
|
||||
break;
|
||||
case effProcessVarIo:
|
||||
v = processVariableIo ((VstVariableIo*)ptr) ? 1 : 0;
|
||||
break;
|
||||
case effSetBlockSizeAndSampleRate:
|
||||
setBlockSizeAndSampleRate (value, opt);
|
||||
v = 1;
|
||||
break;
|
||||
case effSetBypass:
|
||||
v = setBypass (value ? true : false) ? 1 : 0;
|
||||
break;
|
||||
case effGetEffectName:
|
||||
v = getEffectName ((char *)ptr) ? 1 : 0;
|
||||
break;
|
||||
case effGetErrorText:
|
||||
v = getErrorText ((char *)ptr) ? 1 : 0;
|
||||
break;
|
||||
case effGetVendorString:
|
||||
v = getVendorString ((char *)ptr) ? 1 : 0;
|
||||
break;
|
||||
case effGetProductString:
|
||||
v = getProductString ((char *)ptr) ? 1 : 0;
|
||||
break;
|
||||
case effGetVendorVersion:
|
||||
v = getVendorVersion ();
|
||||
break;
|
||||
case effVendorSpecific:
|
||||
v = vendorSpecific (index, value, ptr, opt);
|
||||
break;
|
||||
case effCanDo:
|
||||
v = canDo ((char*)ptr);
|
||||
break;
|
||||
case effGetIcon:
|
||||
v = (long)getIcon ();
|
||||
break;
|
||||
case effSetViewPosition:
|
||||
v = setViewPosition (index, value) ? 1 : 0;
|
||||
break;
|
||||
case effGetTailSize:
|
||||
v = getGetTailSize ();
|
||||
break;
|
||||
case effIdle:
|
||||
v = fxIdle ();
|
||||
break;
|
||||
|
||||
case effGetParameterProperties:
|
||||
v = getParameterProperties (index, (VstParameterProperties*)ptr) ? 1 : 0;
|
||||
break;
|
||||
|
||||
case effKeysRequired:
|
||||
v = (keysRequired () ? 0 : 1); // reversed to keep v1 compatibility
|
||||
break;
|
||||
case effGetVstVersion:
|
||||
v = getVstVersion ();
|
||||
break;
|
||||
|
||||
// version 1.0 or unknown
|
||||
default:
|
||||
v = AudioEffect::dispatcher (opCode, index, value, ptr, opt);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
void AudioEffectX::wantEvents (long filter)
|
||||
{
|
||||
if (audioMaster)
|
||||
audioMaster (&cEffect, audioMasterWantMidi, 0, filter, 0, 0);
|
||||
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
VstTimeInfo* AudioEffectX::getTimeInfo (long filter)
|
||||
{
|
||||
if (audioMaster)
|
||||
return (VstTimeInfo*) audioMaster (&cEffect, audioMasterGetTime, 0, filter, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
long AudioEffectX::tempoAt (long pos)
|
||||
{
|
||||
if (audioMaster)
|
||||
return audioMaster (&cEffect, audioMasterTempoAt, 0, pos, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
bool AudioEffectX::sendVstEventsToHost (VstEvents* events)
|
||||
{
|
||||
if (audioMaster)
|
||||
return audioMaster (&cEffect, audioMasterProcessEvents, 0, 0, events, 0) == 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
// parameters
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
long AudioEffectX::getNumAutomatableParameters ()
|
||||
{
|
||||
if (audioMaster)
|
||||
return audioMaster (&cEffect, audioMasterGetNumAutomatableParameters, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
long AudioEffectX::getParameterQuantization ()
|
||||
{
|
||||
if (audioMaster)
|
||||
return audioMaster (&cEffect, audioMasterGetParameterQuantization, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
// configuration
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
bool AudioEffectX::ioChanged ()
|
||||
{
|
||||
if (audioMaster)
|
||||
return (audioMaster (&cEffect, audioMasterIOChanged, 0, 0, 0, 0) != 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
bool AudioEffectX::needIdle ()
|
||||
{
|
||||
if (audioMaster)
|
||||
return (audioMaster (&cEffect, audioMasterNeedIdle, 0, 0, 0, 0) != 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
bool AudioEffectX::sizeWindow (long width, long height)
|
||||
{
|
||||
if (audioMaster)
|
||||
return (audioMaster (&cEffect, audioMasterSizeWindow, width, height, 0, 0) != 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
double AudioEffectX::updateSampleRate ()
|
||||
{
|
||||
if (audioMaster)
|
||||
audioMaster (&cEffect, audioMasterGetSampleRate, 0, 0, 0, 0); // calls setSampleRate if implemented
|
||||
return sampleRate;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
long AudioEffectX::updateBlockSize ()
|
||||
{
|
||||
if (audioMaster)
|
||||
audioMaster (&cEffect, audioMasterGetBlockSize, 0, 0, 0, 0); // calls setBlockSize if implemented
|
||||
return blockSize;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
long AudioEffectX::getInputLatency ()
|
||||
{
|
||||
if (audioMaster)
|
||||
return audioMaster (&cEffect, audioMasterGetInputLatency, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
long AudioEffectX::getOutputLatency ()
|
||||
{
|
||||
if (audioMaster)
|
||||
return audioMaster (&cEffect, audioMasterGetOutputLatency, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
AEffect* AudioEffectX::getPreviousPlug (long input)
|
||||
{
|
||||
if (audioMaster)
|
||||
return (AEffect*) audioMaster (&cEffect, audioMasterGetPreviousPlug, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
AEffect* AudioEffectX::getNextPlug (long output)
|
||||
{
|
||||
if (audioMaster)
|
||||
return (AEffect*) audioMaster (&cEffect, audioMasterGetNextPlug, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
// configuration
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
long AudioEffectX::willProcessReplacing ()
|
||||
{
|
||||
if (audioMaster)
|
||||
return audioMaster (&cEffect, audioMasterWillReplaceOrAccumulate, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
long AudioEffectX::getCurrentProcessLevel ()
|
||||
{
|
||||
if (audioMaster)
|
||||
return audioMaster (&cEffect, audioMasterGetCurrentProcessLevel, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
long AudioEffectX::getAutomationState ()
|
||||
{
|
||||
if (audioMaster)
|
||||
return audioMaster (&cEffect, audioMasterGetAutomationState, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
void AudioEffectX::wantAsyncOperation (bool state)
|
||||
{
|
||||
if (state)
|
||||
cEffect.flags |= effFlagsExtIsAsync;
|
||||
else
|
||||
cEffect.flags &= ~effFlagsExtIsAsync;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
void AudioEffectX::hasExternalBuffer (bool state)
|
||||
{
|
||||
if (state)
|
||||
cEffect.flags |= effFlagsExtHasBuffer;
|
||||
else
|
||||
cEffect.flags &= ~effFlagsExtHasBuffer;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
// offline
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
bool AudioEffectX::offlineRead (VstOfflineTask* offline, VstOfflineOption option, bool readSource)
|
||||
{
|
||||
if (audioMaster)
|
||||
return (audioMaster (&cEffect, audioMasterOfflineRead, readSource, option, offline, 0) != 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
bool AudioEffectX::offlineWrite (VstOfflineTask* offline, VstOfflineOption option)
|
||||
{
|
||||
if (audioMaster)
|
||||
return (audioMaster (&cEffect, audioMasterOfflineWrite, 0, option, offline, 0) != 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
bool AudioEffectX::offlineStart (VstAudioFile* audioFiles, long numAudioFiles, long numNewAudioFiles)
|
||||
{
|
||||
if (audioMaster)
|
||||
return (audioMaster (&cEffect, audioMasterOfflineStart, numNewAudioFiles, numAudioFiles, audioFiles, 0) != 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
long AudioEffectX::offlineGetCurrentPass ()
|
||||
{
|
||||
if (audioMaster)
|
||||
return (audioMaster (&cEffect, audioMasterOfflineGetCurrentPass, 0, 0, 0, 0) != 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
long AudioEffectX::offlineGetCurrentMetaPass ()
|
||||
{
|
||||
if (audioMaster)
|
||||
return (audioMaster (&cEffect, audioMasterOfflineGetCurrentMetaPass, 0, 0, 0, 0) != 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
// other
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
void AudioEffectX::setOutputSamplerate (float sampleRate)
|
||||
{
|
||||
if (audioMaster)
|
||||
audioMaster (&cEffect, audioMasterSetOutputSampleRate, 0, 0, 0, sampleRate);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
bool AudioEffectX::getSpeakerArrangement (VstSpeakerArrangement* pluginInput, VstSpeakerArrangement* pluginOutput)
|
||||
{
|
||||
if (audioMaster)
|
||||
return (audioMaster (&cEffect, audioMasterGetSpeakerArrangement, 0, (long)pluginInput, pluginOutput, 0) != 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
bool AudioEffectX::getHostVendorString (char* text)
|
||||
{
|
||||
if (audioMaster)
|
||||
return (audioMaster (&cEffect, audioMasterGetVendorString, 0, 0, text, 0) != 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
bool AudioEffectX::getHostProductString (char* text)
|
||||
{
|
||||
if (audioMaster)
|
||||
return (audioMaster (&cEffect, audioMasterGetProductString, 0, 0, text, 0) != 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
long AudioEffectX::getHostVendorVersion ()
|
||||
{
|
||||
if (audioMaster)
|
||||
return audioMaster (&cEffect, audioMasterGetVendorVersion, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
long AudioEffectX::hostVendorSpecific (long lArg1, long lArg2, void* ptrArg, float floatArg)
|
||||
{
|
||||
if (audioMaster)
|
||||
return audioMaster (&cEffect, audioMasterVendorSpecific, lArg1, lArg2, ptrArg, floatArg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
long AudioEffectX::canHostDo (char* text)
|
||||
{
|
||||
if (audioMaster)
|
||||
return (audioMaster (&cEffect, audioMasterCanDo, 0, 0, text, 0) != 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
void AudioEffectX::isSynth (bool state)
|
||||
{
|
||||
if (state)
|
||||
cEffect.flags |= effFlagsIsSynth;
|
||||
else
|
||||
cEffect.flags &= ~effFlagsIsSynth;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
void AudioEffectX::noTail (bool state)
|
||||
{
|
||||
if (state)
|
||||
cEffect.flags |= effFlagsNoSoundInStop;
|
||||
else
|
||||
cEffect.flags &= ~effFlagsNoSoundInStop;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
long AudioEffectX::getHostLanguage ()
|
||||
{
|
||||
if (audioMaster)
|
||||
return audioMaster (&cEffect, audioMasterGetLanguage, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
void* AudioEffectX::openWindow (VstWindow* window)
|
||||
{
|
||||
if (audioMaster)
|
||||
return (void*)audioMaster (&cEffect, audioMasterOpenWindow, 0, 0, window, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
bool AudioEffectX::closeWindow (VstWindow* window)
|
||||
{
|
||||
if (audioMaster)
|
||||
return (audioMaster (&cEffect, audioMasterCloseWindow, 0, 0, window, 0) != 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
void* AudioEffectX::getDirectory ()
|
||||
{
|
||||
if (audioMaster)
|
||||
return (void*)(audioMaster (&cEffect, audioMasterGetDirectory, 0, 0, 0, 0));
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
bool AudioEffectX::updateDisplay()
|
||||
{
|
||||
if (audioMaster)
|
||||
return (audioMaster (&cEffect, audioMasterUpdateDisplay, 0, 0, 0, 0)) ? true : false;
|
||||
return 0;
|
||||
}
|
||||
@@ -1,185 +0,0 @@
|
||||
#ifndef __audioeffectx__
|
||||
#define __audioeffectx__
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------------
|
||||
// VST Plug-Ins SDK
|
||||
// version 2.0 extension
|
||||
// (c)1999 Steinberg Soft+Hardware GmbH
|
||||
//----------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#ifndef __AudioEffect__
|
||||
#include "AudioEffect.hpp" // version 1.0 base class AudioEffect
|
||||
#endif
|
||||
|
||||
#ifndef __aeffectx__
|
||||
#include "aeffectx.h" // version 2.0 'C' extensions and structures
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------------
|
||||
// AudioEffectX extends AudioEffect with the new features. so you should derive
|
||||
// your plug from AudioEffectX
|
||||
//----------------------------------------------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
class AudioEffectX : public AudioEffect
|
||||
{
|
||||
public:
|
||||
AudioEffectX (audioMasterCallback audioMaster, long numPrograms, long numParams);
|
||||
virtual ~AudioEffectX ();
|
||||
|
||||
virtual long dispatcher (long opCode, long index, long value, void *ptr, float opt);
|
||||
|
||||
// 'host' are methods which go from plug to host, and are usually not overridden
|
||||
// 'plug' are methods which you may override to implement the according functionality (to host)
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------------
|
||||
// events + time
|
||||
//----------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
// host
|
||||
virtual void wantEvents (long filter = 1); // filter is currently ignored, midi channel data only (default)
|
||||
virtual VstTimeInfo* getTimeInfo (long filter);
|
||||
// returns const VstTimeInfo* (or 0 if not supported)
|
||||
// filter should contain a mask indicating which fields are requested
|
||||
// (see valid masks in aeffectx.h), as some items may require extensive
|
||||
// conversions
|
||||
virtual long tempoAt (long pos); // returns tempo (in bpm * 10000) at sample frame location <pos>
|
||||
bool sendVstEventsToHost (VstEvents* events); // true:success
|
||||
|
||||
// plug
|
||||
virtual long processEvents (VstEvents* events) {return 0;} // wants no more...else return 1!
|
||||
// VstEvents and VstMidiEvents are declared in aeffectx.h
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------------
|
||||
// parameters and programs
|
||||
//----------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
// host
|
||||
virtual long getNumAutomatableParameters ();
|
||||
virtual long getParameterQuantization (); // returns the integer value for +1.0 representation,
|
||||
// or 1 if full single float precision is maintained
|
||||
// in automation. parameter index in <value> (-1: all, any)
|
||||
// plug
|
||||
virtual bool canParameterBeAutomated (long index) { return true; }
|
||||
virtual bool string2parameter (long index, char* text) {return false;} // note: implies setParameter. text==0 is to be
|
||||
// expected to check the capability (returns true).
|
||||
virtual float getChannelParameter (long channel, long index) {return 0;}
|
||||
virtual long getNumCategories () {return 1L;}
|
||||
virtual bool getProgramNameIndexed (long category, long index, char* text) {return false;}
|
||||
virtual bool copyProgram (long destination) {return false;}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------------
|
||||
// connections, configuration
|
||||
//----------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
// host
|
||||
virtual bool ioChanged (); // tell host numInputs and/or numOutputs and/or numParameters has changed
|
||||
virtual bool needIdle (); // plug needs idle calls (outside its editor window)
|
||||
virtual bool sizeWindow (long width, long height);
|
||||
virtual double updateSampleRate (); // gets and returns sample rate from host (may issue setSampleRate() )
|
||||
virtual long updateBlockSize (); // same for block size
|
||||
virtual long getInputLatency ();
|
||||
virtual long getOutputLatency ();
|
||||
virtual AEffect* getPreviousPlug (long input); // input can be -1 in which case the first found is returned
|
||||
virtual AEffect* getNextPlug (long output); // output can be -1 in which case the first found is returned
|
||||
|
||||
// plug
|
||||
virtual void inputConnected (long index, bool state) {} // input at <index> has been (dis-)connected,
|
||||
virtual void outputConnected (long index, bool state) {} // same as input; state == true: connected
|
||||
virtual bool getInputProperties (long index, VstPinProperties* properties) {return false;}
|
||||
virtual bool getOutputProperties (long index, VstPinProperties* properties) {return false;}
|
||||
virtual VstPlugCategory getPlugCategory()
|
||||
{ if (cEffect.flags & effFlagsIsSynth) return kPlugCategSynth; return kPlugCategUnknown; }
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------------
|
||||
// realtime
|
||||
//----------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
// host
|
||||
virtual long willProcessReplacing (); // returns 0: not implemented, 1: replacing, 2: accumulating
|
||||
virtual long getCurrentProcessLevel (); // returns: 0: not supported,
|
||||
// 1: currently in user thread (gui)
|
||||
// 2: currently in audio thread or irq (where process is called)
|
||||
// 3: currently in 'sequencer' thread or irq (midi, timer etc)
|
||||
// 4: currently offline processing and thus in user thread
|
||||
// other: not defined, but probably pre-empting user thread.
|
||||
virtual long getAutomationState (); // returns 0: not supported, 1: off, 2:read, 3:write, 4:read/write
|
||||
virtual void wantAsyncOperation (bool state = true); // notify host that we want to operate asynchronously.
|
||||
// process() will return immedeately; host will poll getCurrentPosition
|
||||
// to see if data are available in time.
|
||||
virtual void hasExternalBuffer (bool state = true); // external dsp, may have their own output buffe (32 bit float)
|
||||
// host then requests this via effGetDestinationBuffer
|
||||
|
||||
// plug
|
||||
virtual long reportCurrentPosition () {return 0;} // for external dsp, see wantAsyncOperation ()
|
||||
virtual float* reportDestinationBuffer () {return 0;} // for external dsp (dma option)
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------------
|
||||
// offline
|
||||
//----------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
// host
|
||||
virtual bool offlineRead (VstOfflineTask* offline, VstOfflineOption option, bool readSource = true);
|
||||
virtual bool offlineWrite (VstOfflineTask* offline, VstOfflineOption option);
|
||||
virtual bool offlineStart (VstAudioFile* ptr, long numAudioFiles, long numNewAudioFiles);
|
||||
virtual long offlineGetCurrentPass ();
|
||||
virtual long offlineGetCurrentMetaPass ();
|
||||
|
||||
// plug
|
||||
virtual bool offlineNotify (VstAudioFile* ptr, long numAudioFiles, bool start) { return false; }
|
||||
virtual bool offlinePrepare (VstOfflineTask* offline, long count) {return false;}
|
||||
virtual bool offlineRun (VstOfflineTask* offline, long count) {return false;}
|
||||
|
||||
virtual long offlineGetNumPasses () {return 0;}
|
||||
virtual long offlineGetNumMetaPasses () {return 0;}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------------
|
||||
// other
|
||||
//----------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
// host
|
||||
virtual void setOutputSamplerate (float samplerate);
|
||||
virtual bool getSpeakerArrangement (VstSpeakerArrangement* pluginInput, VstSpeakerArrangement* pluginOutput);
|
||||
virtual bool getHostVendorString (char* text); // fills <text> with a string identifying the vendor (max 64 char)
|
||||
virtual bool getHostProductString (char* text); // fills <text> with a string with product name (max 64 char)
|
||||
virtual long getHostVendorVersion (); // returns vendor-specific version
|
||||
virtual long hostVendorSpecific (long lArg1, long lArg2, void* ptrArg, float floatArg); // no definition
|
||||
virtual long canHostDo (char* text); // see 'hostCanDos' in audioeffectx.cpp
|
||||
// returns 0: don't know (default), 1: yes, -1: no
|
||||
virtual void isSynth (bool state = true); // will call wantEvents if true
|
||||
virtual void noTail (bool state = true); // true: tells host we produce no output when silence comes in
|
||||
// enables host to omit process() when no data are present
|
||||
// on any one input.
|
||||
virtual long getHostLanguage (); // returns VstHostLanguage
|
||||
virtual void* openWindow (VstWindow*); // create new window
|
||||
virtual bool closeWindow (VstWindow*); // close a newly created window
|
||||
virtual void* getDirectory (); // get the plug's directory, FSSpec on mac, else char*
|
||||
virtual bool updateDisplay(); // something has changed, update 'multi-fx' display
|
||||
// returns true if supported
|
||||
|
||||
// plug
|
||||
virtual bool processVariableIo (VstVariableIo* varIo) {return false;}
|
||||
virtual bool setSpeakerArrangement (VstSpeakerArrangement* pluginInput, VstSpeakerArrangement* pluginOutput) {return false;}
|
||||
virtual void setBlockSizeAndSampleRate (long blockSize, float sampleRate)
|
||||
{this->blockSize = blockSize; this->sampleRate = sampleRate;}
|
||||
virtual bool setBypass(bool onOff) {return false;} // for 'soft-bypass; process() still called
|
||||
virtual bool getEffectName (char* name) {return false;} // name max 32 char
|
||||
virtual bool getErrorText (char* text) {return false;} // max 256 char
|
||||
virtual bool getVendorString (char* text) {return false;} // fill text with a string identifying the vendor (max 64 char)
|
||||
virtual bool getProductString (char* text) {return false;} // fill text with a string identifying the product name (max 64 char) // fills <ptr> with a string with product name (max 64 char)
|
||||
virtual long getVendorVersion () {return 0;} // return vendor-specific version
|
||||
virtual long vendorSpecific (long lArg, long lArg2, void* ptrArg, float floatArg) {return 0;}
|
||||
// no definition, vendor specific handling
|
||||
virtual long canDo (char* text) {return 0;} // see 'plugCanDos' in audioeffectx.cpp. return values:
|
||||
// 0: don't know (default), 1: yes, -1: no
|
||||
virtual void* getIcon () {return 0;} // not yet defined
|
||||
virtual bool setViewPosition (long x, long y) {return false;}
|
||||
virtual long getGetTailSize () {return 0; }
|
||||
virtual long fxIdle () {return 0;}
|
||||
virtual bool getParameterProperties (long index, VstParameterProperties* p) {return false;}
|
||||
virtual bool keysRequired () {return false;} // version 1 plugs will return true
|
||||
virtual long getVstVersion () {return 2;}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,628 +0,0 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// VST Plug-Ins SDK
|
||||
// Simple user interface framework for VST plugins
|
||||
// Standard control objects
|
||||
//
|
||||
// Version 1.0
|
||||
//
|
||||
// First version : Wolfgang Kundrus
|
||||
// Added new objects : Michael Schmidt 08.97
|
||||
// Added new objects : Yvan Grabit 01.98
|
||||
//
|
||||
// (c)1999 Steinberg Soft+Hardware GmbH
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef __vstcontrols__
|
||||
#define __vstcontrols__
|
||||
|
||||
#ifndef __vstgui__
|
||||
#include "vstgui.h"
|
||||
#endif
|
||||
|
||||
//------------------
|
||||
// defines
|
||||
//------------------
|
||||
#ifndef kPI
|
||||
#define kPI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
#ifndef k2PI
|
||||
#define k2PI 6.28318530717958647692
|
||||
#endif
|
||||
|
||||
#ifndef kPI_2
|
||||
#define kPI_2 1.57079632679489661923f
|
||||
#endif
|
||||
#ifndef kPI_4
|
||||
#define kPI_4 0.78539816339744830962
|
||||
#endif
|
||||
|
||||
#ifndef kE
|
||||
#define kE 2.7182818284590452354
|
||||
#endif
|
||||
|
||||
#ifndef kLN2
|
||||
#define kLN2 0.69314718055994530942
|
||||
#endif
|
||||
|
||||
|
||||
//------------------
|
||||
// CControlEnum type
|
||||
//------------------
|
||||
enum CControlEnum
|
||||
{
|
||||
kHorizontal = 1 << 0,
|
||||
kVertical = 1 << 1,
|
||||
kShadowText = 1 << 2,
|
||||
kLeft = 1 << 3,
|
||||
kRight = 1 << 4,
|
||||
kTop = 1 << 5,
|
||||
kBottom = 1 << 6,
|
||||
k3DIn = 1 << 7,
|
||||
k3DOut = 1 << 8,
|
||||
kPopupStyle = 1 << 9,
|
||||
kCheckStyle = 1 << 10
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
class CControlListener
|
||||
{
|
||||
public:
|
||||
virtual void valueChanged (CDrawContext *context, CControl *control) = 0;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
class CControl : public CView
|
||||
{
|
||||
public:
|
||||
CControl (CRect &size, CControlListener *listener, int tag);
|
||||
virtual ~CControl ();
|
||||
|
||||
virtual void draw (CDrawContext *context) = 0;
|
||||
virtual void update (CDrawContext *context);
|
||||
virtual void doIdleStuff () { if (parent) parent->doIdleStuff (); }
|
||||
|
||||
virtual void setValue (float val) { value = val; }
|
||||
virtual float getValue () { return value; };
|
||||
|
||||
virtual void setMin (float val) { vmin = val; }
|
||||
virtual float getMin () { return vmin; }
|
||||
virtual void setMax (float val) { vmax = val; }
|
||||
virtual float getMax () { return vmax; }
|
||||
|
||||
virtual void setOldValue (float val) { oldValue = val; }
|
||||
virtual float getOldValue (void) { return oldValue; }
|
||||
virtual void setDefaultValue (float val) { defaultValue = val; }
|
||||
virtual float getDefaultValue (void) { return defaultValue; }
|
||||
|
||||
inline int getTag () { return tag; }
|
||||
|
||||
virtual void setMouseEnabled (bool bEnable = true) { bMouseEnabled = bEnable; }
|
||||
virtual bool getMouseEnabled () { return bMouseEnabled; }
|
||||
|
||||
protected:
|
||||
CControlListener *listener;
|
||||
long tag;
|
||||
bool dirty;
|
||||
bool bMouseEnabled;
|
||||
float oldValue;
|
||||
float defaultValue;
|
||||
float value;
|
||||
float vmin;
|
||||
float vmax;
|
||||
float step;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
class COnOffButton : public CControl
|
||||
{
|
||||
public:
|
||||
COnOffButton (CRect &size, CControlListener *listener, int tag,
|
||||
CBitmap *handle);
|
||||
virtual ~COnOffButton ();
|
||||
|
||||
virtual void draw (CDrawContext*);
|
||||
virtual void mouse (CDrawContext *context, CPoint &where);
|
||||
|
||||
protected:
|
||||
CBitmap *handle;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
class CParamDisplay : public CControl
|
||||
{
|
||||
public:
|
||||
CParamDisplay (CRect &size, CBitmap *background = 0, int style = 0);
|
||||
virtual ~CParamDisplay ();
|
||||
|
||||
virtual void setFont (CFont fontID);
|
||||
virtual void setFontColor (CColor color);
|
||||
virtual void setBackColor (CColor color);
|
||||
virtual void setFrameColor (CColor color);
|
||||
virtual void setShadowColor (CColor color);
|
||||
|
||||
virtual void setHoriAlign (CHoriTxtAlign hAlign);
|
||||
virtual void setBackOffset (CPoint &offset);
|
||||
virtual void setStringConvert (void (*stringConvert) (float value, char *string));
|
||||
|
||||
virtual void draw (CDrawContext *context);
|
||||
|
||||
protected:
|
||||
void drawText (CDrawContext *context, char *string, CBitmap *newBack = 0);
|
||||
|
||||
CHoriTxtAlign horiTxtAlign;
|
||||
int style;
|
||||
|
||||
CFont fontID;
|
||||
CColor fontColor;
|
||||
CColor backColor;
|
||||
CColor frameColor;
|
||||
CColor shadowColor;
|
||||
CPoint offset;
|
||||
|
||||
CBitmap *background;
|
||||
|
||||
private:
|
||||
void (*stringConvert) (float value, char *string);
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
class CTextEdit : public CParamDisplay
|
||||
{
|
||||
public:
|
||||
CTextEdit (CRect &size, CControlListener *listener, int tag, const char *txt = 0,
|
||||
CBitmap *background = 0,
|
||||
int style = 0);
|
||||
~CTextEdit ();
|
||||
|
||||
virtual void setText (char *txt);
|
||||
virtual void getText (char *txt);
|
||||
|
||||
virtual void draw (CDrawContext *context);
|
||||
virtual void mouse (CDrawContext *context, CPoint &where);
|
||||
|
||||
virtual void setTextEditConvert (void (*stringConvert) (char *input, char *string));
|
||||
|
||||
virtual void takeFocus ();
|
||||
virtual void looseFocus ();
|
||||
|
||||
protected:
|
||||
void *platformControl;
|
||||
void *platformFont;
|
||||
char text[256];
|
||||
|
||||
private:
|
||||
void (*stringConvert) (char *input, char *string);
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
#define MAX_ENTRY 128
|
||||
class COptionMenu : public CParamDisplay
|
||||
{
|
||||
public:
|
||||
COptionMenu (CRect &size, CControlListener *listener, int tag,
|
||||
CBitmap *background = 0, CBitmap *bgWhenClick = 0,
|
||||
int style = 0);
|
||||
~COptionMenu ();
|
||||
|
||||
virtual bool addEntry (char *txt, int index = -1);
|
||||
virtual int getCurrent (char *txt = 0);
|
||||
virtual bool setCurrent (int index);
|
||||
virtual bool getEntry (int index, char *txt);
|
||||
virtual bool removeEntry (int index);
|
||||
virtual bool removeAllEntry ();
|
||||
virtual int getNbEntries () { return nbEntries; }
|
||||
|
||||
virtual void draw (CDrawContext *context);
|
||||
virtual void mouse (CDrawContext *context, CPoint &where);
|
||||
|
||||
virtual void takeFocus ();
|
||||
virtual void looseFocus ();
|
||||
|
||||
#if MOTIF
|
||||
void setCurrentSelected (void *itemSelected);
|
||||
#endif
|
||||
|
||||
protected:
|
||||
void *platformControl;
|
||||
char *entry[MAX_ENTRY];
|
||||
|
||||
#if MOTIF
|
||||
void *itemWidget[MAX_ENTRY];
|
||||
#endif
|
||||
|
||||
int nbEntries;
|
||||
int currentIndex;
|
||||
CBitmap *bgWhenClick;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
class CKnob : public CControl
|
||||
{
|
||||
public:
|
||||
CKnob (CRect &size, CControlListener *listener, int tag,
|
||||
CBitmap *background,
|
||||
CBitmap *handle, CPoint &offset);
|
||||
virtual ~CKnob ();
|
||||
|
||||
virtual void draw (CDrawContext*);
|
||||
virtual void mouse (CDrawContext *context, CPoint &where);
|
||||
|
||||
virtual void valueToPoint (CPoint &point);
|
||||
virtual float valueFromPoint (CPoint &point);
|
||||
|
||||
virtual void setBackground (CBitmap* background);
|
||||
virtual CBitmap *getBackground () { return background; }
|
||||
|
||||
protected:
|
||||
int inset;
|
||||
CBitmap *background;
|
||||
CBitmap *handle;
|
||||
CPoint offset;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
class CAnimKnob : public CKnob
|
||||
{
|
||||
public:
|
||||
CAnimKnob (CRect &size, CControlListener *listener, int tag,
|
||||
int subPixmaps, // number of subPixmaps
|
||||
int heightOfOneImage, // pixel
|
||||
CBitmap *handle, CPoint &offset);
|
||||
virtual ~CAnimKnob ();
|
||||
|
||||
virtual void draw (CDrawContext*);
|
||||
|
||||
protected:
|
||||
int subPixmaps; // number of subPixmaps
|
||||
int heightOfOneImage;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
class CVerticalSwitch : public CControl
|
||||
{
|
||||
public:
|
||||
CVerticalSwitch (CRect &size, CControlListener *listener, int tag,
|
||||
int subPixmaps, // number of subPixmaps
|
||||
int heightOfOneImage, // pixel
|
||||
int iMaxPositions,
|
||||
CBitmap *handle, CPoint &offset);
|
||||
virtual ~CVerticalSwitch ();
|
||||
|
||||
virtual void draw (CDrawContext*);
|
||||
virtual void mouse (CDrawContext *context, CPoint &where);
|
||||
|
||||
protected:
|
||||
CBitmap *handle;
|
||||
CPoint offset;
|
||||
int subPixmaps; // number of subPixmaps
|
||||
int heightOfOneImage;
|
||||
int iMaxPositions;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
class CHorizontalSwitch : public CControl
|
||||
{
|
||||
public:
|
||||
CHorizontalSwitch (CRect &size, CControlListener *listener, int tag,
|
||||
int subPixmaps, // number of subPixmaps
|
||||
int heightOfOneImage, // pixel
|
||||
int iMaxPositions,
|
||||
CBitmap *handle,
|
||||
CPoint &offset);
|
||||
virtual ~CHorizontalSwitch ();
|
||||
|
||||
virtual void draw (CDrawContext*);
|
||||
virtual void mouse (CDrawContext *context, CPoint &where);
|
||||
|
||||
protected:
|
||||
CBitmap *handle;
|
||||
CPoint offset;
|
||||
int subPixmaps; // number of subPixmaps
|
||||
int heightOfOneImage;
|
||||
int iMaxPositions;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
class CRockerSwitch : public CControl
|
||||
{
|
||||
public:
|
||||
CRockerSwitch (CRect &size, CControlListener *listener, int tag,
|
||||
int heightOfOneImage, // pixel
|
||||
CBitmap *handle, CPoint &offset);
|
||||
virtual ~CRockerSwitch ();
|
||||
|
||||
virtual void draw (CDrawContext*);
|
||||
virtual void mouse (CDrawContext *context, CPoint &where);
|
||||
|
||||
protected:
|
||||
CBitmap *handle;
|
||||
CPoint offset;
|
||||
int heightOfOneImage;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
class CMovieBitmap : public CControl
|
||||
{
|
||||
public:
|
||||
CMovieBitmap (CRect &size, CControlListener *listener, int tag,
|
||||
int subPixmaps, // number of subPixmaps
|
||||
int heightOfOneImage, // pixel
|
||||
CBitmap *handle, CPoint &offset);
|
||||
virtual ~CMovieBitmap ();
|
||||
|
||||
virtual void draw (CDrawContext*);
|
||||
|
||||
protected:
|
||||
CBitmap *handle;
|
||||
CPoint offset;
|
||||
int subPixmaps; // number of subPixmaps
|
||||
int heightOfOneImage;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
class CMovieButton : public CControl
|
||||
{
|
||||
public:
|
||||
CMovieButton (CRect &size, CControlListener *listener, int tag,
|
||||
int heightOfOneImage, // pixel
|
||||
CBitmap *handle, CPoint &offset);
|
||||
virtual ~CMovieButton ();
|
||||
|
||||
virtual void draw (CDrawContext*);
|
||||
virtual void mouse (CDrawContext *context, CPoint &where);
|
||||
|
||||
protected:
|
||||
CBitmap *handle;
|
||||
CPoint offset;
|
||||
int heightOfOneImage;
|
||||
float buttonState;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
// displays bitmaps within a (child-) window
|
||||
class CAutoAnimation : public CControl
|
||||
{
|
||||
public:
|
||||
CAutoAnimation (CRect &size, CControlListener *listener, int tag,
|
||||
int subPixmaps, // number of subPixmaps...
|
||||
int heightOfOneImage, // pixel
|
||||
CBitmap *handle, CPoint &offset);
|
||||
virtual ~CAutoAnimation ();
|
||||
|
||||
virtual void draw (CDrawContext*);
|
||||
virtual void mouse (CDrawContext *context, CPoint &where);
|
||||
|
||||
virtual void openWindow (void);
|
||||
virtual void closeWindow (void);
|
||||
|
||||
virtual void nextPixmap (void);
|
||||
virtual void previousPixmap (void);
|
||||
|
||||
bool isWindowOpened () { return windowOpened; }
|
||||
|
||||
protected:
|
||||
CBitmap *handle;
|
||||
CPoint offset;
|
||||
|
||||
int subPixmaps;
|
||||
int heightOfOneImage;
|
||||
|
||||
bool windowOpened;
|
||||
int totalHeightOfBitmap;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
// Vertical Slider
|
||||
class CVerticalSlider : public CControl
|
||||
{
|
||||
public:
|
||||
CVerticalSlider (CRect &size, CControlListener *listener, int tag,
|
||||
int iMinYPos, // min Y position in pixel
|
||||
int iMaxYPos, // max Y position in pixel
|
||||
CBitmap *handle, // bitmap slider
|
||||
CBitmap *background, // bitmap background
|
||||
CPoint &offset,
|
||||
int style = kBottom); // style (kBottom, kTop))
|
||||
|
||||
virtual ~CVerticalSlider ();
|
||||
|
||||
virtual void draw (CDrawContext*);
|
||||
virtual void mouse (CDrawContext *context, CPoint &where);
|
||||
|
||||
virtual void setDrawTransparentHandle (bool val) { drawTransparentEnabled = val; }
|
||||
virtual void setOffsetHandle (CPoint &val) { offsetHandle = val; }
|
||||
|
||||
protected:
|
||||
CBitmap *handle;
|
||||
CBitmap *background;
|
||||
|
||||
int widthOfSlider; // size of the handle-slider
|
||||
int heightOfSlider;
|
||||
|
||||
CPoint offset;
|
||||
CPoint offsetHandle;
|
||||
|
||||
int iMinYPos; // min Y position in pixel
|
||||
int iMaxYPos; // max Y position in pixel
|
||||
int style;
|
||||
|
||||
int actualYPos;
|
||||
bool drawTransparentEnabled;
|
||||
|
||||
int minTmp;
|
||||
int maxTmp;
|
||||
int widthControl;
|
||||
int heightControl;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
// Horizontal Slider
|
||||
class CHorizontalSlider : public CControl
|
||||
{
|
||||
public:
|
||||
CHorizontalSlider (CRect &size, CControlListener *listener, int tag,
|
||||
int iMinXPos, // min X position in pixel
|
||||
int iMaxXPos, // max X position in pixel
|
||||
CBitmap *handle, // bitmap slider
|
||||
CBitmap *background, // bitmap background
|
||||
CPoint &offset,
|
||||
int style = kRight); // style (kRight, kLeft));
|
||||
|
||||
virtual ~CHorizontalSlider ();
|
||||
|
||||
virtual void draw (CDrawContext*);
|
||||
virtual void mouse (CDrawContext *context, CPoint &where);
|
||||
|
||||
virtual void setDrawTransparentHandle (bool val) { drawTransparentEnabled = val; }
|
||||
virtual void setOffsetHandle (CPoint &val) { offsetHandle = val; }
|
||||
|
||||
protected:
|
||||
CBitmap *handle;
|
||||
CBitmap *background;
|
||||
|
||||
int widthOfSlider; // size of the handle-slider
|
||||
int heightOfSlider;
|
||||
|
||||
CPoint offset;
|
||||
CPoint offsetHandle;
|
||||
|
||||
int iMinXPos; // min X position in pixel
|
||||
int iMaxXPos; // max X position in pixel
|
||||
int style;
|
||||
|
||||
int actualXPos;
|
||||
bool drawTransparentEnabled;
|
||||
|
||||
int minTmp;
|
||||
int maxTmp;
|
||||
int widthControl;
|
||||
int heightControl;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
// special display with custom numbers (0...9)
|
||||
class CSpecialDigit : public CControl
|
||||
{
|
||||
public:
|
||||
CSpecialDigit (CRect &size, CControlListener *listener, int tag, // tag identifier
|
||||
long dwPos, // actual value
|
||||
int iNumbers, // amount of numbers (max 7)
|
||||
int *xpos, // array of all XPOS
|
||||
int *ypos, // array of all YPOS
|
||||
int width, // width of ONE number
|
||||
int height, // height of ONE number
|
||||
CBitmap *handle); // bitmap numbers
|
||||
virtual ~CSpecialDigit ();
|
||||
|
||||
virtual void draw (CDrawContext*);
|
||||
|
||||
virtual float getNormValue (void);
|
||||
|
||||
protected:
|
||||
CBitmap *handle;
|
||||
int iNumbers; // amount of numbers
|
||||
int xpos[7]; // array of all XPOS, max 7 possible
|
||||
int ypos[7]; // array of all YPOS, max 7 possible
|
||||
int width; // width of ONE number
|
||||
int height; // height of ONE number
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
class CKickButton : public CControl
|
||||
{
|
||||
public:
|
||||
CKickButton (CRect &size, CControlListener *listener, int tag,
|
||||
int heightOfOneImage, // pixel
|
||||
CBitmap *handle, CPoint &offset);
|
||||
virtual ~CKickButton ();
|
||||
|
||||
virtual void draw (CDrawContext*);
|
||||
virtual void mouse (CDrawContext *context, CPoint &where);
|
||||
|
||||
protected:
|
||||
CBitmap *handle;
|
||||
CPoint offset;
|
||||
int heightOfOneImage;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
class CSplashScreen : public CControl
|
||||
{
|
||||
public:
|
||||
CSplashScreen (CRect &size, CControlListener *listener, int tag,
|
||||
CBitmap *handle,
|
||||
CRect &toDisplay,
|
||||
CPoint &offset);
|
||||
virtual ~CSplashScreen ();
|
||||
|
||||
virtual void draw (CDrawContext*);
|
||||
virtual void mouse (CDrawContext *context, CPoint &where);
|
||||
|
||||
protected:
|
||||
CRect toDisplay;
|
||||
CRect keepSize;
|
||||
CBitmap *handle;
|
||||
CPoint offset;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
class CVuMeter : public CControl
|
||||
{
|
||||
public:
|
||||
CVuMeter (CRect& size, CBitmap *onBitmap, CBitmap *offBitmap,
|
||||
int nbLed, const int style = kVertical);
|
||||
virtual ~CVuMeter ();
|
||||
|
||||
virtual void setDecreaseStepValue (float value) { decreaseValue = value; }
|
||||
|
||||
virtual void draw (CDrawContext *context);
|
||||
|
||||
protected:
|
||||
CBitmap *onBitmap;
|
||||
CBitmap *offBitmap;
|
||||
int nbLed;
|
||||
int style;
|
||||
float decreaseValue;
|
||||
|
||||
CRect rectOn;
|
||||
CRect rectOff;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,621 +0,0 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// VST Plug-Ins SDK
|
||||
// User interface framework for VST plugins
|
||||
//
|
||||
// Version 1.0
|
||||
//
|
||||
// First version : Wolfgang Kundrus
|
||||
// Added Motif/Windows version : Yvan Grabit 01.98
|
||||
// Added Mac version : Charlie Steinberg 02.98
|
||||
// Added BeOS version : Georges-Edouard Berenger 05.99
|
||||
//
|
||||
// (c)1999 Steinberg Soft+Hardware GmbH
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef __vstgui__
|
||||
#define __vstgui__
|
||||
|
||||
// define global defines
|
||||
#if WIN32
|
||||
#define WINDOWS 1
|
||||
#elif SGI | SUN
|
||||
#define MOTIF 1
|
||||
#elif __MWERKS__
|
||||
#define MAC 1
|
||||
#endif
|
||||
|
||||
#ifndef __AEffEditor__
|
||||
#include "AEffEditor.hpp"
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------
|
||||
#if WINDOWS
|
||||
#include <windows.h>
|
||||
|
||||
//----------------------------------------------------
|
||||
#elif MOTIF
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Intrinsic.h>
|
||||
#ifdef NOBOOL
|
||||
#ifndef bool
|
||||
typedef short bool;
|
||||
#endif
|
||||
#ifndef false
|
||||
static const bool false = 0;
|
||||
#endif
|
||||
#ifndef true
|
||||
static const bool true = 1;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// definition of struct for XPixmap resources
|
||||
struct CResTableEntry {
|
||||
int id;
|
||||
char **xpm;
|
||||
};
|
||||
|
||||
typedef CResTableEntry CResTable[];
|
||||
extern CResTable xpmResources;
|
||||
|
||||
//----------------------------------------------------
|
||||
#elif MAC
|
||||
#include <Quickdraw.h>
|
||||
class CCashedPict;
|
||||
|
||||
//----------------------------------------------------
|
||||
#elif BEOS
|
||||
#include <View.h>
|
||||
class PlugView;
|
||||
class BBitmap;
|
||||
class BResources;
|
||||
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------
|
||||
//----------------------------------------------------
|
||||
class CFrame;
|
||||
class CDrawContext;
|
||||
class COffscreenContext;
|
||||
class CControl;
|
||||
class CBitmap;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// AEffGUIEditor Declaration
|
||||
//-----------------------------------------------------------------------------
|
||||
class AEffGUIEditor : public AEffEditor
|
||||
{
|
||||
public :
|
||||
|
||||
AEffGUIEditor (AudioEffect *effect);
|
||||
|
||||
virtual ~AEffGUIEditor ();
|
||||
|
||||
virtual void setParameter (long index, float value) { postUpdate (); }
|
||||
virtual long getRect (ERect **rect);
|
||||
virtual long open (void *ptr);
|
||||
virtual void idle ();
|
||||
virtual void draw (ERect *rect);
|
||||
#if MAC
|
||||
virtual long mouse (long x, long y);
|
||||
#endif
|
||||
|
||||
// get the current time (in ms)
|
||||
long getTicks ();
|
||||
|
||||
// feedback to appli.
|
||||
void doIdleStuff ();
|
||||
|
||||
// get the effect attached to this editor
|
||||
AudioEffect *getEffect () { return effect; }
|
||||
|
||||
//---------------------------------------
|
||||
protected:
|
||||
ERect rect;
|
||||
CFrame *frame;
|
||||
|
||||
unsigned long lLastTicks;
|
||||
|
||||
private:
|
||||
short sInControlLoop;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Structure CRect
|
||||
//-----------------------------------------------------------------------------
|
||||
struct CRect
|
||||
{
|
||||
CRect (long left = 0, long top = 0, long right = 0, long bottom = 0)
|
||||
: left (left), top (top), right (right), bottom (bottom) {}
|
||||
CRect (const CRect& r)
|
||||
: left (r.left), top (r.top), right (r.right), bottom (r.bottom) {}
|
||||
CRect& operator () (long left, long top, long right, long bottom)
|
||||
{
|
||||
if (left < right)
|
||||
this->left = left, this->right = right;
|
||||
else
|
||||
this->left = right, this->right = left;
|
||||
if (top < bottom)
|
||||
this->top = top, this->bottom = bottom;
|
||||
else
|
||||
this->top = bottom, this->bottom = top;
|
||||
return *this;
|
||||
}
|
||||
|
||||
long left;
|
||||
long top;
|
||||
long right;
|
||||
long bottom;
|
||||
inline long width () { return right - left; }
|
||||
inline long height () { return bottom - top; }
|
||||
|
||||
void offset (long x, long y) { left += x; right += x;
|
||||
top += y; bottom += y; }
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Structure CPoint
|
||||
//-----------------------------------------------------------------------------
|
||||
struct CPoint
|
||||
{
|
||||
CPoint (long h = 0, long v = 0) : h (h), v (v) {}
|
||||
CPoint& operator () (long h, long v)
|
||||
{ this->h = h; this->v = v;
|
||||
return *this; }
|
||||
|
||||
bool isInside (CRect& r)
|
||||
{ return h >= r.left && h <= r.right && v >= r.top && v <= r.bottom; }
|
||||
|
||||
long h;
|
||||
long v;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Structure CColor
|
||||
//-----------------------------------------------------------------------------
|
||||
struct CColor
|
||||
{
|
||||
CColor& operator () (unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue,
|
||||
unsigned char unused)
|
||||
{
|
||||
this->red = red;
|
||||
this->green = green;
|
||||
this->blue = blue;
|
||||
this->unused = unused;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CColor& operator = (CColor newColor)
|
||||
{
|
||||
red = newColor.red;
|
||||
green = newColor.green;
|
||||
blue = newColor.blue;
|
||||
unused = newColor.unused;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator != (CColor newColor)
|
||||
{
|
||||
return (red != newColor.red ||
|
||||
green != newColor.green ||
|
||||
blue != newColor.blue);
|
||||
}
|
||||
|
||||
bool operator == (CColor newColor)
|
||||
{
|
||||
return (red == newColor.red &&
|
||||
green == newColor.green &&
|
||||
blue == newColor.blue);
|
||||
}
|
||||
|
||||
unsigned char red;
|
||||
unsigned char green;
|
||||
unsigned char blue;
|
||||
unsigned char unused;
|
||||
};
|
||||
|
||||
// define some basic colors
|
||||
static CColor kTransparentCColor = {255, 255, 255, 0};
|
||||
static CColor kBlackCColor = {0, 0, 0, 0};
|
||||
static CColor kWhiteCColor = {255, 255, 255, 0};
|
||||
static CColor kGreyCColor = {127, 127, 127, 0};
|
||||
static CColor kRedCColor = {255, 0, 0, 0};
|
||||
static CColor kGreenCColor = {0 , 255, 0, 0};
|
||||
static CColor kBlueCColor = {0 , 0, 255, 0};
|
||||
static CColor kYellowCColor = {255, 255, 0, 0};
|
||||
static CColor kCyanCColor = {255, 0, 255, 0};
|
||||
static CColor kMagentaCColor= {0 , 255, 255, 0};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------
|
||||
// Font type
|
||||
//-----------
|
||||
enum CFont
|
||||
{
|
||||
kSystemFont = 0,
|
||||
kNormalFontVeryBig,
|
||||
kNormalFontBig,
|
||||
kNormalFont,
|
||||
kNormalFontSmall,
|
||||
kNormalFontVerySmall,
|
||||
kSymbolFont,
|
||||
|
||||
kNumStandardFonts
|
||||
};
|
||||
|
||||
//-----------
|
||||
// Line style
|
||||
//-----------
|
||||
enum CLineStyle
|
||||
{
|
||||
kLineSolid = 0,
|
||||
kLineOnOffDash
|
||||
};
|
||||
|
||||
//----------------------------
|
||||
// Text alignment (Horizontal)
|
||||
//----------------------------
|
||||
enum CHoriTxtAlign
|
||||
{
|
||||
kLeftText = 0,
|
||||
kCenterText,
|
||||
kRightText
|
||||
};
|
||||
|
||||
//----------------------------
|
||||
// Buttons Type (+modifiers)
|
||||
//----------------------------
|
||||
enum CButton
|
||||
{
|
||||
kLButton = 1,
|
||||
kMButton = 2,
|
||||
kRButton = 4,
|
||||
kShift = 8,
|
||||
kControl = 16,
|
||||
kAlt = 32,
|
||||
kApple = 64
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// CDrawContext Declaration
|
||||
//-----------------------------------------------------------------------------
|
||||
class CDrawContext
|
||||
{
|
||||
public:
|
||||
CDrawContext (CFrame *frame, void *systemContext, void *window = 0);
|
||||
virtual ~CDrawContext ();
|
||||
|
||||
void moveTo (CPoint &point);
|
||||
void lineTo (CPoint &point);
|
||||
|
||||
void polyLine (CPoint *point, int numberOfPoints);
|
||||
void fillPolygon (CPoint *point, int numberOfPoints);
|
||||
|
||||
void drawRect (CRect &rect);
|
||||
void fillRect (CRect &rect);
|
||||
|
||||
void drawArc (CRect &rect, CPoint &point1, CPoint &point2);
|
||||
void fillArc (CRect &rect, CPoint &point1, CPoint &point2);
|
||||
|
||||
void drawEllipse (CRect &rect);
|
||||
void fillEllipse (CRect &rect);
|
||||
|
||||
void drawPoint (CPoint &point, CColor color);
|
||||
|
||||
void setLineStyle (CLineStyle style);
|
||||
CLineStyle getLineStyle () { return lineStyle; }
|
||||
|
||||
void setLineWidth (int width);
|
||||
int getLineWidth () { return frameWidth; }
|
||||
|
||||
void setFillColor (CColor color);
|
||||
CColor getFillColor () { return fillColor; }
|
||||
|
||||
void setFrameColor (CColor color);
|
||||
CColor getFrameColor () { return frameColor; }
|
||||
|
||||
void setFontColor (CColor color);
|
||||
CColor getFontColor () { return fontColor; }
|
||||
void setFont (CFont fontID, const int size = 0);
|
||||
|
||||
void drawString (const char *string, CRect &rect, const short opaque = false,
|
||||
const CHoriTxtAlign hAlign = kCenterText);
|
||||
|
||||
int getMouseButtons ();
|
||||
void getMouseLocation (CPoint &point);
|
||||
|
||||
#if MOTIF
|
||||
int getIndexColor (CColor color);
|
||||
Colormap getColormap ();
|
||||
Visual *getVisual ();
|
||||
unsigned int getDepth ();
|
||||
|
||||
static int nbNewColor;
|
||||
#endif
|
||||
|
||||
void *getWindow () { return window; }
|
||||
void setWindow (void *ptr) { window = ptr; }
|
||||
void getLoc (CPoint &where) { where = penLoc; }
|
||||
|
||||
//-------------------------------------------
|
||||
protected:
|
||||
|
||||
friend class CBitmap;
|
||||
friend class COffscreenContext;
|
||||
|
||||
void *getSystemContext () { return systemContext; }
|
||||
|
||||
void *systemContext;
|
||||
void *window;
|
||||
CFrame *frame;
|
||||
|
||||
int fontSize;
|
||||
CColor fontColor;
|
||||
CPoint penLoc;
|
||||
|
||||
int frameWidth;
|
||||
CColor frameColor;
|
||||
CColor fillColor;
|
||||
CLineStyle lineStyle;
|
||||
|
||||
#if WINDOWS
|
||||
void *brush;
|
||||
void *pen;
|
||||
void *font;
|
||||
void *oldbrush;
|
||||
void *oldpen;
|
||||
void *oldfont;
|
||||
int iPenStyle;
|
||||
|
||||
#elif MAC
|
||||
FontInfo fontInfoStruct;
|
||||
Pattern fillPattern;
|
||||
|
||||
#elif MOTIF
|
||||
Display *display;
|
||||
|
||||
XFontStruct *fontInfoStruct;
|
||||
CFont fontInfoId;
|
||||
|
||||
#elif BEOS
|
||||
BView* plugView;
|
||||
BFont font;
|
||||
void lineFromTo (CPoint& cstart, CPoint& cend);
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// COffscreenContext Declaration
|
||||
//-----------------------------------------------------------------------------
|
||||
class COffscreenContext : public CDrawContext
|
||||
{
|
||||
public:
|
||||
COffscreenContext (CDrawContext *context, CBitmap *bitmap);
|
||||
COffscreenContext (CFrame *frame, long width, long height, const CColor backgroundColor = kBlackCColor);
|
||||
|
||||
virtual ~COffscreenContext ();
|
||||
|
||||
void transfert (CDrawContext *context, CRect destRect, CPoint srcOffset = CPoint (0, 0));
|
||||
inline int getWidth () { return width; }
|
||||
inline int getHeight () { return height; }
|
||||
|
||||
//-------------------------------------------
|
||||
protected:
|
||||
bool destroyPixmap;
|
||||
CBitmap *bitmap;
|
||||
|
||||
long height;
|
||||
long width;
|
||||
|
||||
CColor backgroundColor;
|
||||
|
||||
#if MOTIF
|
||||
Display *xdisplay;
|
||||
|
||||
#elif BEOS
|
||||
BBitmap *offscreenBitmap;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// CBitmap Declaration
|
||||
//-----------------------------------------------------------------------------
|
||||
class CBitmap
|
||||
{
|
||||
public:
|
||||
CBitmap (int resourceID);
|
||||
CBitmap (CFrame &frame, int width, int height);
|
||||
~CBitmap ();
|
||||
|
||||
void draw (CDrawContext*, CRect &rect, const CPoint &offset = CPoint (0, 0));
|
||||
void drawTransparent (CDrawContext *context, CRect &rect, const CPoint &offset = CPoint (0, 0));
|
||||
|
||||
inline int getWidth () { return width; }
|
||||
inline int getHeight () { return height; }
|
||||
|
||||
void forget ();
|
||||
void remember ();
|
||||
|
||||
void *getHandle () { return handle; }
|
||||
|
||||
#if BEOS
|
||||
static void closeResource ();
|
||||
#endif
|
||||
|
||||
//-------------------------------------------
|
||||
protected:
|
||||
int resourceID;
|
||||
void *handle;
|
||||
void *mask;
|
||||
int width;
|
||||
int height;
|
||||
|
||||
int nbReference;
|
||||
|
||||
#if MOTIF
|
||||
void *createPixmapFromXpm (CDrawContext *context);
|
||||
|
||||
char **dataXpm;
|
||||
Display *xdisplay;
|
||||
|
||||
#elif MAC
|
||||
CCashedPict *pPict;
|
||||
|
||||
#elif BEOS
|
||||
static BResources *resourceFile;
|
||||
BBitmap *bbitmap;
|
||||
bool transparencySet;
|
||||
#endif
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// CView Declaration
|
||||
//-----------------------------------------------------------------------------
|
||||
class CView
|
||||
{
|
||||
public:
|
||||
CView (CRect &size);
|
||||
virtual ~CView ();
|
||||
|
||||
void redraw ();
|
||||
virtual void draw (CDrawContext *context);
|
||||
virtual void mouse (CDrawContext *context, CPoint &where);
|
||||
virtual void update (CDrawContext *context);
|
||||
|
||||
virtual void looseFocus ();
|
||||
virtual void takeFocus ();
|
||||
|
||||
virtual void setTempOffscreen (COffscreenContext *tempOffscr);
|
||||
|
||||
int getHeight () { return size.height (); }
|
||||
int getWidth () { return size.width (); }
|
||||
|
||||
CFrame *getParent () { return parent; }
|
||||
|
||||
//-------------------------------------------
|
||||
protected:
|
||||
friend class CControl;
|
||||
friend class CFrame;
|
||||
CRect size;
|
||||
CFrame *parent;
|
||||
COffscreenContext *tempOffscreen;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// CFrame Declaration
|
||||
//-----------------------------------------------------------------------------
|
||||
class CFrame : public CView
|
||||
{
|
||||
public:
|
||||
CFrame (CRect &size, void *systemWindow, AEffGUIEditor *editor);
|
||||
CFrame (CRect &size, char *title, AEffGUIEditor *editor, const int style = 0);
|
||||
|
||||
~CFrame ();
|
||||
|
||||
bool open (CPoint *point = 0);
|
||||
bool close ();
|
||||
bool isOpen () { return openFlag; }
|
||||
|
||||
void draw (CDrawContext *context);
|
||||
void draw (CView *view = 0);
|
||||
void mouse (CDrawContext *context, CPoint &where);
|
||||
|
||||
void update (CDrawContext *context);
|
||||
void idle ();
|
||||
void doIdleStuff () { if (editor) editor->doIdleStuff (); }
|
||||
|
||||
bool getPosition (int &x, int &y);
|
||||
bool setSize (int width, int height);
|
||||
bool getSize (CRect *size);
|
||||
|
||||
void setBackground (CBitmap *background);
|
||||
CBitmap *getBackground () { return background; }
|
||||
|
||||
virtual bool addView (CView *view);
|
||||
virtual bool removeView (CView *view);
|
||||
|
||||
int setModalView (CView *view);
|
||||
|
||||
#if WINDOWS
|
||||
void *getSystemWindow () { return hwnd;}
|
||||
#elif BEOS
|
||||
void *getSystemWindow () { return plugView;}
|
||||
#else
|
||||
void *getSystemWindow () { return systemWindow;}
|
||||
#endif
|
||||
|
||||
AEffGUIEditor *getEditor () { return editor; }
|
||||
|
||||
void setEditView (CView *view) { editView = view; }
|
||||
CView *getEditView () { return editView; }
|
||||
|
||||
#if MOTIF
|
||||
Colormap getColormap () { return colormap; }
|
||||
Visual *getVisual () { return visual; }
|
||||
unsigned int getDepth () { return depth; }
|
||||
Display *getDisplay () { return display; }
|
||||
Window getWindow () { return window; }
|
||||
void freeGc ();
|
||||
|
||||
Region region;
|
||||
|
||||
GC gc;
|
||||
GC getGC () { return gc; }
|
||||
#else
|
||||
void *getGC () { return 0; }
|
||||
#endif
|
||||
|
||||
//-------------------------------------------
|
||||
protected:
|
||||
bool initFrame (void *systemWin);
|
||||
|
||||
AEffGUIEditor *editor;
|
||||
|
||||
void *systemWindow;
|
||||
CBitmap *background;
|
||||
int viewCount;
|
||||
int maxViews;
|
||||
CView **views;
|
||||
CView *modalView;
|
||||
CView *editView;
|
||||
|
||||
bool firstDraw;
|
||||
bool openFlag;
|
||||
|
||||
#if WINDOWS
|
||||
void *hwnd;
|
||||
friend LONG WINAPI WindowProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
#elif MOTIF
|
||||
Colormap colormap;
|
||||
Display *display;
|
||||
Visual *visual;
|
||||
Window window;
|
||||
unsigned int depth;
|
||||
|
||||
friend void _destroyCallback (Widget, XtPointer, XtPointer);
|
||||
|
||||
#elif BEOS
|
||||
PlugView *plugView;
|
||||
#endif
|
||||
|
||||
//-------------------------------------------
|
||||
private:
|
||||
bool addedWindow;
|
||||
void *vstWindow;
|
||||
};
|
||||
|
||||
|
||||
// include the control object
|
||||
#ifndef __vstcontrols__
|
||||
#include "vstcontrols.h"
|
||||
#endif
|
||||
|
||||
|
||||
//-End--------------------------------------
|
||||
#endif
|
||||
Binary file not shown.
1000
src/vsti/resource.h
1000
src/vsti/resource.h
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user