From 878e57b057b500bc3c8477b65bd6d1b33e1a76c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petri=20J=C3=A4rvisalo?= Date: Tue, 4 Jun 2024 17:07:01 +0300 Subject: [PATCH] sample testailuja --- 4klang.asm | 395 +++++++++++++++-------------- 4klang.h | 8 +- 4klang.inc | 8 +- 4klang.yml | 533 +++++++++++++++++----------------------- 4klang_st.yml | 301 +++++++++++++++++++++++ song.yml => _4klang.yml | 128 ++++------ base.config | 10 +- debug_audio.asm | 5 +- exemain.asm | 2 + minified.config | 6 +- music/4k_house.xrns | Bin 0 -> 9927 bytes music/4k_sointu.xrns | Bin 16458 -> 16482 bytes music/sointu_house.yml | 286 +++++++++++++++++++++ shader.glsl | 37 ++- shader_minified.h | 226 ++++++++++++++++- texture_0.png | Bin 0 -> 19118 bytes 16 files changed, 1346 insertions(+), 599 deletions(-) create mode 100644 4klang_st.yml rename song.yml => _4klang.yml (85%) create mode 100644 music/4k_house.xrns create mode 100644 music/sointu_house.yml create mode 100644 texture_0.png diff --git a/4klang.asm b/4klang.asm index ff1c707..c5bd449 100644 --- a/4klang.asm +++ b/4klang.asm @@ -1,6 +1,6 @@ -%define SU_LENGTH_IN_SAMPLES 3335488 +%define SU_LENGTH_IN_SAMPLES 1550944 %define SU_SAMPLE_RATE 44100 -%define SU_BPM 165. +%define SU_BPM 116. ;------------------------------------------------------------------------------- ; unit struct @@ -61,7 +61,7 @@ endstruc section .synth_object bss align=256 su_synth_obj: resb su_synthworkspace.size - resb 34*su_delayline_wrk.size + resb 20*su_delayline_wrk.size ;------------------------------------------------------------------------------- @@ -76,23 +76,26 @@ global _su_render_song@4 _su_render_song@4: pushad ; Stack: edi, esi, ebp, esp, ebx, edx, ecx, eax, retaddr_su_render_song, OutputBufPtr xor eax, eax - push 1 ; Stack: RandSeed, edi, esi, ebp, esp, ebx, edx, ecx, eax, retaddr_su_render_song, OutputBufPtr - push eax ; Stack: GlobalTick, RandSeed, edi, esi, ebp, esp, ebx, edx, ecx, eax, retaddr_su_render_song, OutputBufPtr + push 16 ; Stack: VoiceTrackBitmask, edi, esi, ebp, esp, ebx, edx, ecx, eax, retaddr_su_render_song, OutputBufPtr + push 1 ; Stack: RandSeed, VoiceTrackBitmask, edi, esi, ebp, esp, ebx, edx, ecx, eax, retaddr_su_render_song, OutputBufPtr + push eax ; Stack: GlobalTick, RandSeed, VoiceTrackBitmask, edi, esi, ebp, esp, ebx, edx, ecx, eax, retaddr_su_render_song, OutputBufPtr su_render_rowloop: ; loop through every row in the song - push eax ; Stack: Row, GlobalTick, RandSeed, edi, esi, ebp, esp, ebx, edx, ecx, eax, retaddr_su_render_song, OutputBufPtr + push eax ; Stack: Row, GlobalTick, RandSeed, VoiceTrackBitmask, edi, esi, ebp, esp, ebx, edx, ecx, eax, retaddr_su_render_song, OutputBufPtr 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, GlobalTick, RandSeed, edi, esi, ebp, esp, ebx, edx, ecx, eax, retaddr_su_render_song, OutputBufPtr - push 7 ; Stack: VoicesRemain, Sample, Row, GlobalTick, RandSeed, edi, esi, ebp, esp, ebx, edx, ecx, eax, retaddr_su_render_song, OutputBufPtr + push eax ; Stack: Sample, Row, GlobalTick, RandSeed, VoiceTrackBitmask, edi, esi, ebp, esp, ebx, edx, ecx, eax, retaddr_su_render_song, OutputBufPtr + push 8 ; Stack: PolyphonyBitmask, Sample, Row, GlobalTick, RandSeed, VoiceTrackBitmask, edi, esi, ebp, esp, ebx, edx, ecx, eax, retaddr_su_render_song, OutputBufPtr ; does the next voice reuse the current opcodes? + push 8 ; Stack: VoicesRemain, PolyphonyBitmask, Sample, Row, GlobalTick, RandSeed, VoiceTrackBitmask, edi, esi, ebp, esp, ebx, edx, ecx, eax, retaddr_su_render_song, OutputBufPtr mov edx, dword su_synth_obj ; edx points to the synth object mov ebx, dword su_patch_opcodes ; COM points to vm code mov esi, dword su_patch_operands ; VAL points to unit params mov ecx, dword su_synth_obj + su_synthworkspace.size - su_delayline_wrk.filtstate lea ebp, [edx + su_synthworkspace.voices] ; WRK points to the first voice call su_run_vm ; run through the VM code - pop eax ; eax = VoicesRemain, Stack: Sample, Row, GlobalTick, RandSeed, edi, esi, ebp, esp, ebx, edx, ecx, eax, retaddr_su_render_song, OutputBufPtr - mov esi, [esp + 52] ; esi points to the output buffer + pop eax ; eax = VoicesRemain, Stack: PolyphonyBitmask, Sample, Row, GlobalTick, RandSeed, VoiceTrackBitmask, edi, esi, ebp, esp, ebx, edx, ecx, eax, retaddr_su_render_song, OutputBufPtr + pop eax ; eax = PolyphonyBitmask, Stack: Sample, Row, GlobalTick, RandSeed, VoiceTrackBitmask, edi, esi, ebp, esp, ebx, edx, ecx, eax, retaddr_su_render_song, OutputBufPtr + mov esi, [esp + 56] ; esi points to the output buffer mov edi, dword su_synth_obj+su_synthworkspace.left mov ecx, 2 output_sound16bit_loop: ; loop over two channels, left & right @@ -107,19 +110,20 @@ su_render_sampleloop: ; loop through every sample in the row stosd add esi,2 loop output_sound16bit_loop - mov [esp + 52], esi ; save esi back to stack ; *ptr++ = left, *ptr++ = right - pop eax ; eax = Sample, Stack: Row, GlobalTick, RandSeed, edi, esi, ebp, esp, ebx, edx, ecx, eax, retaddr_su_render_song, OutputBufPtr + mov [esp + 56], esi ; save esi back to stack ; *ptr++ = left, *ptr++ = right + pop eax ; eax = Sample, Stack: Row, GlobalTick, RandSeed, VoiceTrackBitmask, edi, esi, ebp, esp, ebx, edx, ecx, eax, retaddr_su_render_song, OutputBufPtr inc dword [esp + 4] ; increment global time, used by delays inc eax - cmp eax, 4009 + cmp eax, 5702 jl su_render_sampleloop - pop eax ; eax = Row, Stack: GlobalTick, RandSeed, edi, esi, ebp, esp, ebx, edx, ecx, eax, retaddr_su_render_song, OutputBufPtr ; Stack: pushad ptr + pop eax ; eax = Row, Stack: GlobalTick, RandSeed, VoiceTrackBitmask, edi, esi, ebp, esp, ebx, edx, ecx, eax, retaddr_su_render_song, OutputBufPtr ; Stack: pushad ptr inc eax - cmp eax, 832 + cmp eax, 272 jl su_render_rowloop ; rewind the stack the entropy of multiple pop eax is probably lower than add - pop eax ; eax = GlobalTick, Stack: RandSeed, edi, esi, ebp, esp, ebx, edx, ecx, eax, retaddr_su_render_song, OutputBufPtr - pop eax ; eax = RandSeed, Stack: edi, esi, ebp, esp, ebx, edx, ecx, eax, retaddr_su_render_song, OutputBufPtr + pop eax ; eax = GlobalTick, Stack: RandSeed, VoiceTrackBitmask, edi, esi, ebp, esp, ebx, edx, ecx, eax, retaddr_su_render_song, OutputBufPtr + pop eax ; eax = RandSeed, Stack: VoiceTrackBitmask, edi, esi, ebp, esp, ebx, edx, ecx, eax, retaddr_su_render_song, OutputBufPtr + pop eax ; eax = VoiceTrackBitmask, Stack: edi, esi, ebp, esp, ebx, edx, ecx, eax, retaddr_su_render_song, OutputBufPtr popad ; Popped: eax, ecx, edx, ebx, esp, ebp, esi, edi. Stack: retaddr_su_render_song, OutputBufPtr ret 4 @@ -131,35 +135,58 @@ su_render_sampleloop: ; loop through every sample in the row ;------------------------------------------------------------------------------- section .su_update_voices code align=1 su_update_voices: -; The simple implementation: each track triggers always the same voice +; The more complicated implementation: one track can trigger multiple voices xor edx, edx - xor ebx, ebx - mov bl, 16 ; rows per pattern - div ebx ; eax = current pattern, edx = current row in pattern - lea esi, [su_tracks+eax]; esi points to the pattern data for current track - mov edi, dword su_synth_obj+su_synthworkspace.voices - mov bl, 6 ; MAX_TRACKS is always <= 32 so this is ok + mov ebx, 16 ; we could do xor ebx,ebx; mov bl,PATTERN_SIZE, but that would limit patternsize to 256... + div ebx ; eax = current pattern, edx = current row in pattern + + lea esi, [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 + mov ebp, dword su_synth_obj ; ebp points to the current_voiceno array su_update_voices_trackloop: movzx eax, byte [esi] ; eax = current pattern - imul eax, 16 ; multiply by rows per pattern, eax = offset to current pattern data - movzx eax, byte [su_patterns + eax + edx] ; ecx = note - cmp al, 1 ; anything but hold causes action + imul eax, 16 ; eax = offset to current pattern data + movzx eax,byte [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 [esp + 16 + 4],ecx ; test voicetrack_bitmask// 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, 1 ; anything but hold causes action je short su_update_voices_nexttrack - mov dword [edi+su_voice.sustain], eax ; set the voice currently active to release - jb su_update_voices_nexttrack ; if cl < HLD (no new note triggered) goto nexttrack -su_update_voices_retrigger: + mov cl, byte [ebp] + mov edi, ecx + add edi, ebx + shl edi, 12 ; each unit = 64 bytes and there are 1<= num_voices) + jl su_update_voices_skipreset + xor ecx,ecx ; curvoice = 0 +su_update_voices_skipreset: + mov byte [ebp],cl + add ecx, ebx + shl ecx, 12 ; each unit = 64 bytes and there are 1<<6 units + small header + lea edi,[su_synth_obj + su_synthworkspace.voices + ecx] stosd ; save note - stosd ; save sustain - mov ecx, (su_voice.size - su_voice.inputs)/4 ; could be xor ecx, ecx; mov ch,...>>8, but will it actually be smaller after compression? + stosd ; save release + mov ecx, (su_voice.size - su_voice.inputs)/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, 52 - dec ebx - jnz short su_update_voices_trackloop + pop ebx ; ebx=first voice of next instrument, Stack: ptrnrow + pop edx ; edx=patrnrow + add esi, 17 + inc ebp + cmp ebp,su_synth_obj + 6 + jl su_update_voices_trackloop ret ;------------------------------------------------------------------------------- @@ -178,7 +205,7 @@ su_update_voices_skipadd: ;------------------------------------------------------------------------------- section .su_run_vm code align=1 su_run_vm: - pushad ; Stack: edi, OperandStream, Voice, esp, OpcodeStream, Synth, DelayWorkSpace, eax, retaddr_su_run_vm, VoicesRemain, Sample, Row, GlobalTick, RandSeed, edi, esi, ebp, esp, ebx, edx, ecx, eax, retaddr_su_render_song, OutputBufPtr + pushad ; Stack: edi, OperandStream, Voice, esp, OpcodeStream, Synth, DelayWorkSpace, eax, retaddr_su_run_vm, VoicesRemain, PolyphonyBitmask, Sample, Row, GlobalTick, RandSeed, VoiceTrackBitmask, edi, esi, ebp, esp, ebx, edx, ecx, eax, retaddr_su_render_song, OutputBufPtr su_run_vm_loop: ; loop until all voices done movzx edi, byte [ebx] ; edi = command byte inc ebx ; move to next instruction @@ -209,12 +236,22 @@ su_transform_operands_out: call [su_vm_jumptable-4+edi*4] ; call the function corresponding to the instruction jmp su_run_vm_loop su_run_vm_advance: - mov ebp, dword [esp + 8] ; load pointer to voice to register - add ebp, su_voice.size ; shift it to point to following voice - mov dword [esp + 8], ebp ; save back to stack - dec dword [esp + 36] ; voices-- - jne su_run_vm_loop ; if there's more voices to process, goto vm_loop - popad ; Popped: eax, ecx = DelayWorkSpace, edx = Synth, ebx = OpcodeStream, esp, ebp = Voice, esi = OperandStream, edi. Stack: retaddr_su_run_vm, VoicesRemain, Sample, Row, GlobalTick, RandSeed, edi, esi, ebp, esp, ebx, edx, ecx, eax, retaddr_su_render_song, OutputBufPtr + mov ebp, [esp + 8] ; WRK points to start of current voice + add ebp, su_voice.size ; move to next voice + mov [esp + 8], ebp ; update the pointer in the stack to point to the new voice + mov ecx, [esp + 36] ; ecx = how many voices remain to process + dec ecx ; decrement number of voices to process + bt dword [esp + 40], ecx ; if voice bit of su_polyphonism not set + jnc su_op_advance_next_instrument ; goto next_instrument + mov esi, [esp + 4] ; if it was set, then repeat the opcodes for the current voice + mov ebx, [esp + 16] +su_op_advance_next_instrument: + mov [esp + 4], esi ; save current VAL as a checkpoint + mov [esp + 16], ebx ; save current COM as a checkpoint +su_op_advance_finish: + mov [esp + 36], ecx + jne su_run_vm_loop ; ZF was set by dec ecx + popad ; Popped: eax, ecx = DelayWorkSpace, edx = Synth, ebx = OpcodeStream, esp, ebp = Voice, esi = OperandStream, edi. Stack: retaddr_su_run_vm, VoicesRemain, PolyphonyBitmask, Sample, Row, GlobalTick, RandSeed, VoiceTrackBitmask, edi, esi, ebp, esp, ebx, edx, ecx, eax, retaddr_su_render_song, OutputBufPtr ret ;------------------------------------------------------------------------------- ; ADDP opcode: add the two top most signals on the stack and pop @@ -224,11 +261,6 @@ su_run_vm_advance: ;------------------------------------------------------------------------------- section .su_op_addp code align=1 su_op_addp: - jnc su_op_addp_mono - faddp st2, st0 - faddp st2, st0 - ret -su_op_addp_mono: faddp st1, st0 ret @@ -248,44 +280,6 @@ su_op_mulp_mono: fmulp st1 ret -;------------------------------------------------------------------------------- -; XCH opcode: exchange the signals on the stack -;------------------------------------------------------------------------------- -; Mono: a b -> b a -; stereo: a b c d -> c d a b -;------------------------------------------------------------------------------- -section .su_op_xch code align=1 -su_op_xch: - fxch st0, st1 - ret - - -;------------------------------------------------------------------------------- -; HOLD opcode: sample and hold the signal, reducing sample rate -;------------------------------------------------------------------------------- -; Mono version: holds the signal at a rate defined by the freq parameter -; Stereo version: holds both channels -;------------------------------------------------------------------------------- -section .su_op_hold code align=1 -su_op_hold: - fld dword [edx] ; f x - fmul st0, st0 ; f^2 x - fchs ; -f^2 x - fadd dword [ebp] ; p-f^2 x - fst dword [ebp] ; 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 [ebp] ; x - fst dword [ebp+4] ; save holded value - ret ; x -su_op_hold_holding: - fstp st0 ; - fld dword [ebp+4] ; x - ret ;------------------------------------------------------------------------------- ; FILTER opcode: perform low/high/band-pass/notch etc. filtering on the signal @@ -316,10 +310,6 @@ su_op_filter: jz short su_op_filter_skiplowpass fadd dword [ebp] su_op_filter_skiplowpass: - test al, byte 0x20 - jz short su_op_filter_skipbandpass - fadd dword [ebp+8] -su_op_filter_skipbandpass: test al, byte 0x10 jz short su_op_filter_skiphighpass fadd dword [ebp+4] @@ -343,12 +333,14 @@ su_op_filter_skipneghighpass: ;------------------------------------------------------------------------------- section .su_op_pan code align=1 su_op_pan: - fld dword [edx] ; 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 + 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] ; 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 ;------------------------------------------------------------------------------- @@ -363,10 +355,10 @@ su_op_pan: section .su_op_delay code align=1 su_op_delay: lodsw ; al = delay index, ah = delay count - pushad ; Stack: edi, DelayVal, ebp, esp, DelayCom, edx, ecx, eax, retaddr_su_op_delay, edi, OperandStream, Voice, esp, OpcodeStream, Synth, DelayWorkSpace, eax, retaddr_su_run_vm, VoicesRemain, Sample, Row, GlobalTick, RandSeed, edi, esi, ebp, esp, ebx, edx, ecx, eax, retaddr_su_render_song, OutputBufPtr + pushad ; Stack: edi, DelayVal, ebp, esp, DelayCom, edx, ecx, eax, retaddr_su_op_delay, edi, OperandStream, Voice, esp, OpcodeStream, Synth, DelayWorkSpace, eax, retaddr_su_run_vm, VoicesRemain, PolyphonyBitmask, Sample, Row, GlobalTick, RandSeed, VoiceTrackBitmask, edi, esi, ebp, esp, ebx, edx, ecx, eax, retaddr_su_render_song, OutputBufPtr movzx ebx, al lea ebx,[su_delay_times + ebx*2] ; BX now points to the right position within delay time table - movzx esi, word [esp + 84] ; notice that we load word, so we wrap at 65536 + movzx esi, word [esp + 88] ; notice that we load word, so we wrap at 65536 mov ecx, dword [esp + 60] ; ebp is now the separate delay workspace, as they require a lot more space jnc su_op_delay_mono push eax ; save _ah (delay count) @@ -377,7 +369,7 @@ su_op_delay: su_op_delay_mono: ; flow into mono delay call su_op_delay_do ; when stereo delay is not enabled, we could inline this to save 5 bytes, but I expect stereo delay to be farely popular so maybe not worth the hassle mov dword [esp + 60],ecx ; move delay workspace pointer back to stack. - popad ; Popped: eax, ecx, edx, ebx = DelayCom, esp, ebp, esi = DelayVal, edi. Stack: retaddr_su_op_delay, edi, OperandStream, Voice, esp, OpcodeStream, Synth, DelayWorkSpace, eax, retaddr_su_run_vm, VoicesRemain, Sample, Row, GlobalTick, RandSeed, edi, esi, ebp, esp, ebx, edx, ecx, eax, retaddr_su_render_song, OutputBufPtr + popad ; Popped: eax, ecx, edx, ebx = DelayCom, esp, ebp, esi = DelayVal, edi. Stack: retaddr_su_op_delay, edi, OperandStream, Voice, esp, OpcodeStream, Synth, DelayWorkSpace, eax, retaddr_su_run_vm, VoicesRemain, PolyphonyBitmask, Sample, Row, GlobalTick, RandSeed, VoiceTrackBitmask, edi, esi, ebp, esp, ebx, edx, ecx, eax, retaddr_su_render_song, OutputBufPtr ret ;------------------------------------------------------------------------------- @@ -445,10 +437,6 @@ section .su_op_compressor code align=1 su_op_compressor: fld st0 ; x x fmul st0, st0 ; x^2 x - fld st2 ; r x^2 l r - fst st3 ; y x^2 l r - fmul st0, st0 ; y^2 x^2 l r - faddp st1, st0 ; y^2+x^2 l r fld dword [ebp] ; l x^2 x fucomi st0, st1 setnb al ; if (st0 >= st1) al = 1; else al = 0; @@ -477,7 +465,6 @@ su_op_compressor: ; if ratio is at minimum => p=0 => 1 x ; if ratio is at maximum => p=0.5 => t/x => t/x*x=t fdiv dword [edx + 8]; this used to be pregain but that ran into problems with getting back up to 0 dB so postgain should be better at that - fld st0 ; and return the computed gain two times, ready for MULP STEREO ret @@ -528,12 +515,6 @@ section .su_op_send code align=1 su_op_send: lodsw mov ecx, [esp + 12] ; load pointer to voice - pushf ; uh ugly: we save the flags just for the stereo carry bit. Doing the .CX loading later crashed the synth for stereo sends as loading the synth address from stack was f'd up by the "call su_op_send_mono" - test ah, 0x80 - jz su_op_send_skipglobal - mov ecx, [esp + 24 + 4] -su_op_send_skipglobal: - popf test al, 0x8 ; if the SEND_POP bit is not set jnz su_op_send_skippush fld st0 ; duplicate the signal on stack: s s @@ -615,7 +596,7 @@ su_op_envelope_leave2: ;------------------------------------------------------------------------------- section .su_op_noise code align=1 su_op_noise: - lea ecx,[esp + 56] + lea ecx,[esp + 60] imul eax, [ecx],16007 mov [ecx],eax fild dword [ecx] @@ -646,7 +627,7 @@ su_op_oscillator: fchs ; -d r, negate the detune for second round su_op_oscillat_mono: -pushad ; Stack: edi, esi, OscWRK, esp, ebx, edx, ecx, , retaddr_su_op_oscillator, edi, OperandStream, Voice, esp, OpcodeStream, Synth, DelayWorkSpace, eax, retaddr_su_run_vm, VoicesRemain, Sample, Row, GlobalTick, RandSeed, edi, esi, ebp, esp, ebx, edx, ecx, eax, retaddr_su_render_song, OutputBufPtr +pushad ; Stack: edi, esi, OscWRK, esp, ebx, edx, ecx, , retaddr_su_op_oscillator, edi, OperandStream, Voice, esp, OpcodeStream, Synth, DelayWorkSpace, eax, retaddr_su_run_vm, VoicesRemain, PolyphonyBitmask, Sample, Row, GlobalTick, RandSeed, VoiceTrackBitmask, edi, esi, ebp, esp, ebx, edx, ecx, eax, retaddr_su_render_song, OutputBufPtr fldz ; 0 d fxch ; d a=0, "accumulated signal" su_op_oscillat_unison_loop: @@ -668,39 +649,31 @@ su_op_oscillat_unison_loop: jmp short su_op_oscillat_unison_loop su_op_oscillat_unison_out: -popad ; Popped: eax = , ecx, edx, ebx, esp, ebp = OscWRK, esi, edi. Stack: retaddr_su_op_oscillator, edi, OperandStream, Voice, esp, OpcodeStream, Synth, DelayWorkSpace, eax, retaddr_su_run_vm, VoicesRemain, Sample, Row, GlobalTick, RandSeed, edi, esi, ebp, esp, ebx, edx, ecx, eax, retaddr_su_render_song, OutputBufPtr +popad ; Popped: eax = , ecx, edx, ebx, esp, ebp = OscWRK, esi, edi. Stack: retaddr_su_op_oscillator, edi, OperandStream, Voice, esp, OpcodeStream, Synth, DelayWorkSpace, eax, retaddr_su_run_vm, VoicesRemain, PolyphonyBitmask, Sample, Row, GlobalTick, RandSeed, VoiceTrackBitmask, edi, esi, ebp, esp, ebx, edx, ecx, eax, retaddr_su_render_song, OutputBufPtr ret su_op_oscillat_single: fld dword [edx] fsub dword [FCONST_0_500000] fdiv dword [FCONST_0_00781250] faddp st1 - test al, byte 0x08 - jnz su_op_oscillat_skipnote fiadd dword [edx-su_voice.inputs+su_voice.note] ; // st0 is note, st1 is t+d offset -su_op_oscillat_skipnote: fmul dword [ICONST_1034594986] call su_power - test al, byte 0x08 - jz short su_op_oscillat_normalize_note - fmul dword [FCONST_3_80000em05] ; // st0 is now frequency for lfo - jmp short su_op_oscillat_normalized -su_op_oscillat_normalize_note: fmul dword [FCONST_9_269614em05] ; // st0 is now frequency su_op_oscillat_normalized: fadd dword [ebp] + test al, byte 0x80 + jz short su_op_oscillat_not_sample + fst dword [ebp] ; for samples, we store the phase without mod(p,1) + call su_oscillat_sample + jmp su_op_oscillat_shaping ; skip the rest to avoid color phase normalization and colorloading +su_op_oscillat_not_sample: fld1 ; we need to take mod(p,1) so the frequency does not drift as the float fadd st1, st0 ; make no mistake: without this, there is audible drifts in oscillator pitch fxch ; as the actual period changes once the phase becomes too big fprem ; we actually computed mod(p+1,1) instead of mod(p,1) as the fprem takes mod fstp st1 ; towards zero fst dword [ebp] ; store back the updated phase - fadd dword [edx + 8] - fld1 ; this is a bit stupid, but we need to take mod(x,1) again after phase modulations - fadd st1, st0 ; as the actual oscillator functions expect x in [0,1] - fxch - fprem - fstp st1 fld dword [edx + 12] ; // c p ; every oscillator test included if needed test al, byte 0x40 @@ -711,6 +684,10 @@ su_op_oscillat_notsine: jz short su_op_oscillat_not_trisaw call su_oscillat_trisaw su_op_oscillat_not_trisaw: + test al, byte 0x10 + jz short su_op_oscillat_not_pulse + call su_oscillat_pulse +su_op_oscillat_not_pulse: su_op_oscillat_shaping: ; finally, shape the oscillator and apply gain fld dword [edx + 16] @@ -719,6 +696,17 @@ su_op_oscillat_gain: fmul dword [edx + 20] ret +section .su_oscillat_pulse code align=1 +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 + section .su_oscillat_trisaw code align=1 su_oscillat_trisaw: fucomi st1 ; // c p @@ -748,6 +736,30 @@ su_oscillat_sine_do: fsin ; // sin(2*pi*p) ret +section .su_oscillat_sample code align=1 +su_oscillat_sample: + pushad ; Stack: SampleDi, esi, ebp, esp, SampleBx, SampleDx, SampleCx, SampleAx, retaddr_su_oscillat_sample, retaddr_su_op_oscillator, edi, OperandStream, Voice, esp, OpcodeStream, Synth, DelayWorkSpace, eax, retaddr_su_run_vm, VoicesRemain, PolyphonyBitmask, Sample, Row, GlobalTick, RandSeed, VoiceTrackBitmask, edi, esi, ebp, esp, ebx, edx, ecx, eax, retaddr_su_render_song, OutputBufPtr ; edx must be saved, eax & ecx if this is stereo osc + push eax + mov al, byte [esi-4] ; reuse "color" as the sample number + lea edi, [su_sample_offsets + eax*8]; edi points now to the sample table entry + fmul dword [FCONST_84_28075] ; p*r + fistp dword [esp] + pop edx ; edx is now the sample number + movzx ebx, word [edi + 4] ; ecx = loopstart + sub edx, ebx ; if sample number < loop start + jl su_oscillat_sample_not_looping ; then we're not looping yet + mov eax, edx ; eax = sample number + movzx ecx, word [edi + 6] ; edi is now the loop length + xor edx, edx ; div wants edx to be empty + div ecx ; edx is now the remainder +su_oscillat_sample_not_looping: + add edx, ebx ; sampleno += loopstart + add edx, dword [edi] + fild word [su_sample_table + edx*2] + fdiv dword [FCONST_32767_0] + popad ; Popped: eax = SampleAx, ecx = SampleCx, edx = SampleDx, ebx = SampleBx, esp, ebp, esi, edi = SampleDi. Stack: retaddr_su_oscillat_sample, retaddr_su_op_oscillator, edi, OperandStream, Voice, esp, OpcodeStream, Synth, DelayWorkSpace, eax, retaddr_su_run_vm, VoicesRemain, PolyphonyBitmask, Sample, Row, GlobalTick, RandSeed, VoiceTrackBitmask, edi, esi, ebp, esp, ebx, edx, ecx, eax, retaddr_su_render_song, OutputBufPtr + ret + ;------------------------------------------------------------------------------- ; IN opcode: inputs and clears a global port ;------------------------------------------------------------------------------- @@ -766,6 +778,37 @@ su_op_in: ret +section .su_load_gmdls code align=1 +global _su_load_gmdls@0 +_su_load_gmdls@0: + mov eax, su_sample_table + ; these are the arguments for ReadFile + push 0 ; NULL + push eax ; &bytes_read, reusing sample table again; it does not matter that the first four bytes are trashed + push 3440660 ; number of bytes to read + push eax ; here we actually pass the sample table to readfile + ; these are for OpenFile + push 0 ; OF_READ + push eax ; &ofstruct, blatantly reuse the sample table + push su_gmdls_path1 ; path + call dword [__imp__OpenFile@12]; eax = OpenFile(path,&ofstruct,OF_READ) + push eax ; handle to file + call dword [__imp__ReadFile@20] ; Readfile(handle,&su_sample_table,SAMPLE_TABLE_SIZE,&bytes_read,NULL) + ret +extern __imp__OpenFile@12 ; requires windows +extern __imp__ReadFile@20 + ; requires windows + + +section .su_gmdls_path1 data align=1 +su_gmdls_path1: + db 'drivers/gm.dls',0 + + +section .susamtable bss align=256 +su_sample_table: + resb 3440660 ; size of gmdls. + ;------------------------------------------------------------------------------- ; su_nonlinear_map function: returns 2^(-24*x) of parameter number _AX @@ -813,7 +856,7 @@ su_power: ; best way to do this ;------------------------------------------------------------------------------- section .su_op_distort code align=1 -su_op_distort:call su_effects_stereohelper +su_op_distort: fld dword [edx] su_waveshaper: @@ -869,17 +912,15 @@ section .su_vm_jumptable data align=1 su_vm_jumptable: dd su_op_envelope dd su_op_oscillator - dd su_op_distort - dd su_op_hold dd su_op_mulp dd su_op_noise dd su_op_filter dd su_op_addp dd su_op_pan - dd su_op_delay - dd su_op_xch dd su_op_outaux dd su_op_send + dd su_op_distort + dd su_op_delay dd su_op_compressor dd su_op_in dd su_op_out @@ -891,17 +932,15 @@ section .su_vm_transformcounts data align=1 su_vm_transformcounts: db 5 db 6 - db 1 - db 1 db 0 db 2 db 2 db 0 db 1 + db 2 + db 1 + db 1 db 4 - db 0 - db 2 - db 1 db 5 db 0 db 1 @@ -913,55 +952,53 @@ su_vm_transformcounts: section .su_patterns data align=1 su_patterns: db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - db 0,0,0,0,0,0,0,0,57,1,1,1,57,1,1,1 - db 1,1,1,1,57,1,1,1,1,1,1,1,57,1,1,1 - db 1,1,1,1,57,1,1,1,1,1,1,57,57,1,1,1 - db 1,1,1,1,57,57,57,57,1,1,1,1,57,1,1,1 - db 1,1,1,1,57,1,1,1,57,57,1,1,57,1,1,1 + db 48,1,1,1,48,1,1,1,48,1,1,1,48,1,1,1 + db 48,1,1,1,48,1,1,1,48,1,1,1,48,1,48,1 db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 - db 1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0 - db 0,0,0,0,0,0,0,0,0,0,46,1,1,1,46,1 - db 46,1,1,1,1,1,1,1,1,1,46,1,1,1,1,1 - db 46,1,1,1,1,1,1,1,46,1,46,1,1,1,1,1 - db 46,1,1,1,1,1,1,1,46,46,46,46,1,1,1,1 - db 46,1,1,1,1,1,1,1,1,1,46,46,1,1,1,1 - db 48,1,48,1,1,1,48,1,48,1,48,1,1,1,48,1 - db 50,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 - db 48,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 - db 46,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 - db 1,1,1,1,1,1,1,1,1,1,48,1,50,1,53,1 - db 43,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 - db 1,1,1,1,1,1,1,1,43,1,45,1,46,1,48,1 - db 1,1,1,1,1,1,1,1,1,1,1,1,48,1,50,1 - db 52,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 - db 45,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 - db 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0 - db 62,0,64,0,65,0,69,0,65,0,64,0,62,0,64,0 - db 65,0,72,0,65,0,64,0,62,0,64,0,65,0,71,0 - db 65,0,69,0,65,0,64,0,62,0,64,0,65,0,72,0 - db 50,0,50,1,50,0,50,1,50,0,50,1,50,0,50,1 - db 48,0,48,1,48,0,48,1,48,0,48,1,48,0,48,1 - db 46,0,46,1,46,0,46,1,46,0,46,1,46,0,46,1 - db 43,0,43,1,43,0,43,1,43,0,43,1,43,0,43,1 - db 43,0,43,1,43,0,43,1,43,0,43,1,43,0,43,0 + db 1,1,1,1,58,1,1,1,1,1,1,1,58,1,1,1 + db 1,1,1,1,72,1,1,1,1,1,1,1,72,1,1,1 + db 74,1,0,0,74,1,77,70,1,0,70,1,0,70,1,0 + db 74,1,0,0,74,1,77,70,1,0,70,1,0,0,72,1 + db 74,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + db 60,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 + db 1,1,53,1,1,1,53,1,1,1,53,1,1,1,53,1 + db 1,1,53,1,1,1,53,1,1,1,53,1,1,1,53,53 ;------------------------------------------------------------------------------- ; Tracks ;------------------------------------------------------------------------------- section .su_tracks data align=1 su_tracks: - db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,2,2,3,2,2,2,4,2,2,2,2,2,2,2,5,2,2,2,3,2,2,2,4,2,2,2,2,2,2,2,5,6,6,7,0 - db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,9,9,9,10,9,9,9,11,9,9,9,10,9,9,9,12,9,9,9,10,9,9,9,11,9,9,9,10,9,9,9,12,6,6,7,0 - db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,6,6,7,0 - db 14,6,15,6,16,17,18,19,16,20,21,22,14,6,6,23,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 - db 24,25,24,26,24,25,24,26,24,25,24,26,24,25,24,26,24,25,24,26,24,25,24,26,24,25,24,26,24,25,24,26,24,25,24,26,24,25,24,26,24,25,24,26,24,25,24,26,0,0,0,0 - db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27,27,28,28,29,29,30,30,27,27,28,28,29,29,30,30,27,27,28,28,29,29,30,30,27,27,28,28,29,29,30,31,0,0,0,0 + db 0,0,0,0,1,2,1,2,1,2,1,2,1,2,1,2,3 + db 0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,3 + db 0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,3 + db 6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,8 + db 0,0,0,0,9,3,3,3,9,3,3,3,3,3,3,3,3 + db 0,0,0,0,10,11,10,10,10,10,10,10,10,10,10,10,3 +;------------------------------------------------------------------------------- +; Sample offsets +;------------------------------------------------------------------------------- +section .su_sample_offsets data align=1 +su_sample_offsets: + dd 560606 + dw 4276 + dw 1 + dd 641780 + dw 2423 + dw 1 + dd 433554 + dw 2615 + dw 5676 + dd 367477 + dw 1343 + dw 1 + ;------------------------------------------------------------------------------- ; Delay times ;------------------------------------------------------------------------------- section .su_delay_times data align=1 su_delay_times: - dw 1116,1188,1276,1356,1422,1492,1556,1618,1140,1212,1300,1380,1446,1516,1580,1642,21381,12027 + dw 1395,350,1744,1744,1116,1188,1276,1356,1422,1492,1556,1618,1140,1212,1300,1380,1446,1516,1580,1642 ;------------------------------------------------------------------------------- @@ -969,14 +1006,14 @@ su_delay_times: ;------------------------------------------------------------------------------- section .su_patch_opcodes data align=1 su_patch_opcodes: - db 2,4,6,8,10,2,12,10,14,14,16,14,14,14,14,14,6,8,18,20,22,20,22,25,2,26,2,26,2,26,0,2,26,4,6,8,10,2,12,14,14,10,16,14,14,14,14,18,25,2,2,10,26,0,2,12,10,14,14,14,18,25,0,5,5,17,5,17,15,14,22,14,7,15,3,11,25,4,26,4,26,26,4,26,4,26,4,26,0,2,4,4,16,10,18,20,22,20,25,0,2,26,26,2,4,4,16,10,14,14,18,7,29,11,25,0,31,21,33,0 + db 2,4,6,2,8,10,10,6,12,10,10,10,10,14,17,2,2,6,18,0,2,4,20,6,2,8,6,10,10,12,14,17,2,18,2,18,0,2,22,8,6,2,22,8,6,12,2,4,6,12,10,20,14,17,0,2,4,4,12,6,10,10,20,2,8,6,10,12,24,6,20,14,17,2,18,0,3,3,7,5,7,15,17,0,3,5,7,11,11,15,17,0,27,23,29,0 ;------------------------------------------------------------------------------- ; The parameters / inputs to each opcode ;------------------------------------------------------------------------------- section .su_patch_operands data align=1 su_patch_operands: - db 22,64,0,0,38,77,64,19,128,66,70,64,78,128,0,68,0,0,70,2,128,97,128,68,108,128,68,100,128,68,19,98,16,15,128,80,40,74,80,23,42,16,97,128,59,27,128,112,0,0,15,27,128,112,0,8,15,128,0,38,49,0,0,128,70,40,0,47,54,0,0,128,19,152,0,54,68,70,0,128,26,200,0,39,71,0,0,128,7,0,149,88,64,42,115,114,54,33,58,100,28,45,0,0,128,84,102,93,63,68,75,87,64,11,66,68,53,128,80,7,76,16,13,54,16,64,128,0,71,128,74,0,128,49,71,121,0,128,0,56,0,4,53,0,0,128,102,128,87,128,16,95,128,80,89,71,32,61,45,0,64,87,64,128,65,128,34,64,60,87,128,64,128,35,64,69,0,128,106,128,66,62,91,64,103,26,88,85,31,88,96,12,128,88,25,59,106,60,64,29,21,64,64,4,128,64,128,40,52,25,0,41,42,55,54,63,128,72,75,33,0,59,43,0,74,64,0,128,64,128,72,69,73,0,40,64,0,128,64,128,72,71,120,0,40,64,0,128,64,128,72,86,152,0,39,62,0,30,71,88,62,14,53,27,72,64,88,66,64,113,64,128,64,64,71,128,86,0,16,1,73,128,90,0,17,1,84,52,39,81,0,0,128,87,144,0,90,107,0,33,57,67,57,128,76,64,0,98,64,101,64,64,48,85,78,97,64,35,39,82,64,15,128,68,64,80,48,56,87,46,54,85,35,2,50,128,114,77,0,15,128 + db 18,65,0,0,60,94,57,0,128,63,79,66,0,43,0,0,128,67,81,87,35,68,100,62,64,9,75,68,53,128,80,10,85,16,10,49,16,64,57,0,62,128,0,0,128,39,61,34,0,128,0,40,0,0,76,0,0,96,86,116,0,0,114,37,130,95,0,68,0,0,83,3,107,57,67,68,128,78,64,71,84,10,47,54,0,0,128,19,136,0,54,68,70,0,128,26,255,255,0,53,0,0,128,64,128,0,0,0,3,97,0,0,54,0,0,128,64,6,0,0,2,3,79,128,0,62,0,0,42,64,64,0,1,64,125,128,39,76,68,114,70,50,12,46,74,36,39,77,40,48,0,84,50,128,35,71,64,0,64,64,64,16,3,128,64,94,128,64,83,32,53,0,0,64,52,59,91,102,72,37,65,87,47,102,59,64,98,23,0,72,47,45,76,128,104,0,8,90,0,0,128,21,78,0,85,64,77,64,0,2,64,111,128,73,49,78,50,60,0,0,128,82,64,0,3,64,127,128,78,128,76,109,128,64,57,84,0,2,40,128,120,42,4,15,128 ;------------------------------------------------------------------------------- ; Constants @@ -986,8 +1023,8 @@ FCONST_32767_0 dd 0x46fffe00 FCONST_0_00781250 dd 0x3c000000 FCONST_0_500000 dd 0x3f000000 FCONST_0_99609375 dd 0x3f7f0000 -FCONST_3_80000em05 dd 0x381f6230 FCONST_9_269614em05 dd 0x38c265dc +FCONST_84_28075 dd 0x42a88fbe ICONST_2147483648 dd 0x80000000 ICONST_1034594986 dd 0x3daaaaaa ICONST_24 dd 0x18 diff --git a/4klang.h b/4klang.h index 57fca4a..a766528 100644 --- a/4klang.h +++ b/4klang.h @@ -3,14 +3,14 @@ #define SU_RENDER_H #define SU_CHANNEL_COUNT 2 -#define SU_LENGTH_IN_SAMPLES 3335488 +#define SU_LENGTH_IN_SAMPLES 1550944 #define SU_BUFFER_LENGTH (SU_LENGTH_IN_SAMPLES*SU_CHANNEL_COUNT) #define SU_SAMPLE_RATE 44100 -#define SU_BPM 165 +#define SU_BPM 116 #define SU_ROWS_PER_BEAT 4 #define SU_ROWS_PER_PATTERN 16 -#define SU_LENGTH_IN_PATTERNS 52 +#define SU_LENGTH_IN_PATTERNS 17 #define SU_LENGTH_IN_ROWS (SU_LENGTH_IN_PATTERNS*SU_PATTERN_SIZE) #define SU_SAMPLES_PER_ROW (SU_SAMPLE_RATE*60/(SU_BPM*SU_ROWS_PER_BEAT)) @@ -34,6 +34,8 @@ typedef short SUsample; extern "C" { #endif void SU_CALLCONV su_render_song(SUsample *buffer); +void SU_CALLCONV su_load_gmdls(); +#define SU_LOAD_GMDLS #ifdef __cplusplus diff --git a/4klang.inc b/4klang.inc index c1c0054..26ab3d0 100644 --- a/4klang.inc +++ b/4klang.inc @@ -3,14 +3,14 @@ %define PLAYER_INC %define SU_CHANNEL_COUNT 2 -%define SU_LENGTH_IN_SAMPLES 3335488 +%define SU_LENGTH_IN_SAMPLES 1550944 %define SU_BUFFER_LENGTH (SU_LENGTH_IN_SAMPLES*SU_CHANNEL_COUNT) %define SU_SAMPLE_RATE 44100 -%define SU_BPM 165 +%define SU_BPM 116 %define SU_ROWS_PER_BEAT 4 %define SU_ROWS_PER_PATTERN 16 -%define SU_LENGTH_IN_PATTERNS 52 +%define SU_LENGTH_IN_PATTERNS 17 %define SU_LENGTH_IN_ROWS (SU_LENGTH_IN_PATTERNS*SU_PATTERN_SIZE) %define SU_SAMPLES_PER_ROW (SU_SAMPLE_RATE*60/(SU_BPM*SU_ROWS_PER_BEAT)) %define SU_SAMPLE_SIZE 2 @@ -23,5 +23,7 @@ _su_symbols: %else ; MANGLED extern su_render_song %endif ; MANGLED + extern _su_load_gmdls +%define SU_LOAD_GMDLS %endif ; PLAYER_INC diff --git a/4klang.yml b/4klang.yml index 26e270f..ccedb85 100644 --- a/4klang.yml +++ b/4klang.yml @@ -1,156 +1,53 @@ -bpm: 165 +bpm: 116 rowsperbeat: 4 score: tracks: - numvoices: 1 - order: [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 1, 2, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 4, 1, 1, 1, 2, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 4, -1, -1, 5, -1] - patterns: [[1, 1, 1, 1, 1, 1, 1, 1, 57, 1, 1, 1, 57, 1, 1, 1], [1, 1, 1, 1, 57, 1, 1, 1, 1, 1, 1, 1, 57, 1, 1, 1], [1, 1, 1, 1, 57, 1, 1, 1, 1, 1, 1, 57, 57, 1, 1, 1], [1, 1, 1, 1, 57, 57, 57, 57, 1, 1, 1, 1, 57, 1, 1, 1], [1, 1, 1, 1, 57, 1, 1, 1, 57, 57, 1, 1, 57, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1]] + order: [-1, -1, -1, -1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, -1] + patterns: [[48, 1, 1, 1, 48, 1, 1, 1, 48, 1, 1, 1, 48, 1, 1, 1], [48, 1, 1, 1, 48, 1, 1, 1, 48, 1, 1, 1, 48, 1, 48, 1]] - numvoices: 1 - order: [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 1, 2, 1, 1, 1, 3, 1, 1, 1, 2, 1, 1, 1, 4, 1, 1, 1, 2, 1, 1, 1, 3, 1, 1, 1, 2, 1, 1, 1, 4, -1, -1, 5, -1] - patterns: [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 46, 1, 1, 1, 46, 1], [46, 1, 1, 1, 1, 1, 1, 1, 1, 1, 46, 1, 1, 1, 1, 1], [46, 1, 1, 1, 1, 1, 1, 1, 46, 1, 46, 1, 1, 1, 1, 1], [46, 1, 1, 1, 1, 1, 1, 1, 46, 46, 46, 46, 1, 1, 1, 1], [46, 1, 1, 1, 1, 1, 1, 1, 1, 1, 46, 46, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1]] + order: [-1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, -1] + patterns: [[1, 1, 1, 1, 58, 1, 1, 1, 1, 1, 1, 1, 58, 1, 1, 1]] - numvoices: 1 - order: [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 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, -1, -1, 1, -1] - patterns: [[48, 1, 48, 1, 1, 1, 48, 1, 48, 1, 48, 1, 1, 1, 48, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1]] + order: [-1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1] + patterns: [[1, 1, 1, 1, 72, 1, 1, 1, 1, 1, 1, 1, 72, 1, 1, 1]] - numvoices: 1 - order: [0, -1, 1, -1, 2, 3, 4, 5, 2, 6, 7, 8, 0, -1, -1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1] - patterns: [[50, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [48, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [46, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 48, 1, 50, 1, 53, 1], [43, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 43, 1, 45, 1, 46, 1, 48, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 48, 1, 50, 1], [52, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [45, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1]] + order: [0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 2] + patterns: [[74, 1, 0, 1, 74, 1, 77, 70, 1, 0, 70, 1, 0, 70, 1, 0], [74, 1, 0, 1, 74, 1, 77, 70, 1, 0, 70, 1, 0, 1, 72, 1], [74, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]] + - numvoices: 2 + order: [-1, -1, -1, -1, 0, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, -1] + patterns: [[60, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]] - numvoices: 1 - order: [0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, -1, -1, -1, -1] - patterns: [[62, 0, 64, 0, 65, 0, 69, 0, 65, 0, 64, 0, 62, 0, 64, 0], [65, 0, 72, 0, 65, 0, 64, 0, 62, 0, 64, 0, 65, 0, 71, 0], [65, 0, 69, 0, 65, 0, 64, 0, 62, 0, 64, 0, 65, 0, 72, 0]] - - numvoices: 1 - order: [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 1, 1, 2, 2, 3, 3, 0, 0, 1, 1, 2, 2, 3, 3, 0, 0, 1, 1, 2, 2, 3, 3, 0, 0, 1, 1, 2, 2, 3, 4, -1, -1, -1, -1] - patterns: [[50, 0, 50, 1, 50, 0, 50, 1, 50, 0, 50, 1, 50, 0, 50, 1], [48, 0, 48, 1, 48, 0, 48, 1, 48, 0, 48, 1, 48, 0, 48, 1], [46, 0, 46, 1, 46, 0, 46, 1, 46, 0, 46, 1, 46, 0, 46, 1], [43, 0, 43, 1, 43, 0, 43, 1, 43, 0, 43, 1, 43, 0, 43, 1], [43, 0, 43, 1, 43, 0, 43, 1, 43, 0, 43, 1, 43, 0, 43, 0]] + order: [-1, -1, -1, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1] + patterns: [[1, 1, 53, 1, 1, 1, 53, 1, 1, 1, 53, 1, 1, 1, 53, 1], [1, 1, 53, 1, 1, 1, 53, 1, 1, 1, 53, 1, 1, 1, 53, 53]] rowsperpattern: 16 - length: 52 + length: 17 patch: - - name: snare - numvoices: 1 - units: - - type: envelope - id: 1 - parameters: {attack: 22, decay: 64, gain: 38, release: 0, stereo: 0, sustain: 0} - - type: oscillator - id: 2 - parameters: {color: 128, detune: 64, gain: 70, lfo: 0, phase: 19, shape: 66, stereo: 0, transpose: 77, type: 0} - - type: distort - id: 3 - parameters: {drive: 78, stereo: 0} - - type: hold - id: 4 - parameters: {damp: 0, dry: 128, feedback: 96, holdfreq: 128, notetracking: 2, pregain: 40, stereo: 0} - - type: mulp - id: 5 - parameters: {panning: 64, stereo: 0} - - type: envelope - id: 6 - parameters: {attack: 0, auxgain: 64, decay: 68, gain: 70, outgain: 64, release: 0, stereo: 0, sustain: 0} - - type: noise - id: 81 - parameters: {gain: 128, shape: 2, stereo: 0} - - type: mulp - id: 82 - parameters: {stereo: 0} - - type: filter - id: 83 - parameters: {bandpass: 0, frequency: 97, highpass: 0, lowpass: 1, negbandpass: 0, neghighpass: 1, resonance: 128, stereo: 0} - - type: filter - id: 84 - parameters: {bandpass: 0, frequency: 108, highpass: 0, lowpass: 1, negbandpass: 0, neghighpass: 1, resonance: 128, stereo: 0} - - type: addp - id: 85 - parameters: {stereo: 0} - - type: filter - id: 86 - parameters: {bandpass: 0, frequency: 100, highpass: 0, lowpass: 1, negbandpass: 0, neghighpass: 1, resonance: 128, stereo: 0} - - type: filter - id: 87 - parameters: {bandpass: 0, frequency: 19, highpass: 1, lowpass: 0, negbandpass: 0, neghighpass: 0, resonance: 98, stereo: 0} - - type: filter - id: 88 - parameters: {bandpass: 0, frequency: 15, highpass: 1, lowpass: 1, negbandpass: 0, neghighpass: 0, resonance: 128, stereo: 0} - - type: filter - id: 89 - parameters: {bandpass: 0, frequency: 40, highpass: 1, lowpass: 1, negbandpass: 0, neghighpass: 0, resonance: 74, stereo: 0} - - type: filter - id: 90 - parameters: {bandpass: 0, frequency: 23, highpass: 1, lowpass: 0, negbandpass: 0, neghighpass: 0, resonance: 42, stereo: 0} - - type: distort - id: 91 - parameters: {drive: 97, stereo: 0} - - type: hold - id: 92 - parameters: {holdfreq: 128, stereo: 0} - - type: pan - id: 93 - parameters: {panning: 59, stereo: 0} - - type: delay - id: 94 - parameters: {damp: 0, dry: 128, feedback: 112, notetracking: 0, pregain: 27, stereo: 0} - varargs: [1116, 1188, 1276, 1356, 1422, 1492, 1556, 1618] - - type: xch - id: 95 - parameters: {stereo: 0} - - type: delay - id: 96 - parameters: {damp: 0, dry: 128, feedback: 112, notetracking: 0, pregain: 27, stereo: 0} - varargs: [1140, 1212, 1300, 1380, 1446, 1516, 1580, 1642] - - type: xch - id: 97 - parameters: {stereo: 0} - - type: outaux - id: 98 - parameters: {auxgain: 0, outgain: 128, stereo: 1} - - type: envelope - id: 99 - parameters: {attack: 38, decay: 49, gain: 128, release: 0, stereo: 0, sustain: 0} - - type: send - id: 100 - parameters: {amount: 70, port: 0, sendpop: 1, target: 2} - - type: envelope - id: 101 - parameters: {attack: 47, decay: 54, gain: 128, release: 0, stereo: 0, sustain: 0} - - type: send - id: 102 - parameters: {amount: 19, port: 0, sendpop: 1, target: 83} - - type: envelope - id: 103 - parameters: {attack: 54, decay: 68, gain: 128, release: 0, stereo: 0, sustain: 70} - - type: send - id: 104 - parameters: {amount: 26, port: 0, sendpop: 1, target: 86} - - name: kick + - name: kick edm 2 + comment: Suggested note to play G-2 to C-3 numvoices: 1 units: - type: envelope id: 105 - parameters: {attack: 39, channel: 2, decay: 71, gain: 128, release: 0, stereo: 0, sustain: 0} - - type: send - id: 205 - parameters: {amount: 7, damp: 64, dry: 128, feedback: 125, notetracking: 0, port: 0, pregain: 40, sendpop: 0, stereo: 0, target: 184, unit: 0, voice: 0} + parameters: {attack: 18, channel: 2, decay: 65, gain: 60, release: 0, stereo: 0, sustain: 0} - type: oscillator id: 106 - parameters: {color: 115, detune: 64, gain: 54, lfo: 0, phase: 42, shape: 114, stereo: 0, transpose: 88, type: 1, unison: 1} - - type: distort - id: 107 - parameters: {drive: 58, stereo: 0} - - type: hold - id: 108 - parameters: {holdfreq: 100, stereo: 0} + parameters: {color: 128, detune: 57, gain: 79, lfo: 0, phase: 0, shape: 63, stereo: 0, transpose: 94, type: 0, unison: 2} - type: mulp id: 126 parameters: {stereo: 0} - type: envelope id: 110 - parameters: {attack: 28, decay: 45, gain: 128, release: 0, stereo: 0, sustain: 0} + parameters: {attack: 0, decay: 43, gain: 128, release: 0, stereo: 0, sustain: 0} - type: noise id: 111 - parameters: {gain: 102, shape: 84, stereo: 0} + parameters: {gain: 81, shape: 67, stereo: 0} - type: filter id: 112 - parameters: {bandpass: 0, frequency: 93, highpass: 0, lowpass: 1, negbandpass: 0, neghighpass: 1, resonance: 63, stereo: 0} + parameters: {bandpass: 0, frequency: 87, highpass: 0, lowpass: 1, negbandpass: 0, neghighpass: 1, resonance: 35, stereo: 0} - type: filter id: 113 - parameters: {bandpass: 0, frequency: 75, highpass: 0, lowpass: 1, negbandpass: 0, neghighpass: 0, resonance: 87, stereo: 0} + parameters: {bandpass: 0, frequency: 100, highpass: 0, lowpass: 1, negbandpass: 0, neghighpass: 0, resonance: 62, stereo: 0} - type: mulp id: 10 parameters: {stereo: 0} @@ -159,222 +56,236 @@ patch: parameters: {stereo: 0} - type: filter id: 12 - parameters: {bandpass: 0, frequency: 11, highpass: 0, lowpass: 1, negbandpass: 0, neghighpass: 1, resonance: 66, stereo: 0} + parameters: {bandpass: 0, frequency: 9, highpass: 0, lowpass: 1, negbandpass: 0, neghighpass: 1, resonance: 75, stereo: 0} - type: filter id: 13 parameters: {bandpass: 0, frequency: 53, highpass: 1, lowpass: 1, negbandpass: 0, neghighpass: 0, resonance: 128, stereo: 0} - type: filter id: 14 - parameters: {bandpass: 0, frequency: 7, highpass: 1, lowpass: 0, negbandpass: 0, neghighpass: 0, resonance: 76, stereo: 0} + parameters: {bandpass: 0, frequency: 10, highpass: 1, lowpass: 0, negbandpass: 0, neghighpass: 0, resonance: 85, stereo: 0} - type: filter id: 15 - parameters: {bandpass: 0, frequency: 13, highpass: 1, lowpass: 0, negbandpass: 0, neghighpass: 0, resonance: 54, stereo: 0} + parameters: {bandpass: 0, frequency: 10, highpass: 1, lowpass: 0, negbandpass: 0, neghighpass: 0, resonance: 49, stereo: 0} - type: pan id: 114 parameters: {panning: 64, stereo: 0} - type: outaux id: 118 - parameters: {auxgain: 0, outgain: 128, stereo: 1} + parameters: {auxgain: 0, outgain: 57, stereo: 1} - type: envelope id: 119 - parameters: {attack: 71, decay: 128, gain: 128, release: 0, stereo: 0, sustain: 74} + parameters: {attack: 62, decay: 128, gain: 128, release: 0, stereo: 0, sustain: 0} - type: envelope id: 120 - parameters: {attack: 49, decay: 71, gain: 128, release: 0, stereo: 0, sustain: 121} + parameters: {attack: 39, decay: 61, gain: 128, release: 0, stereo: 0, sustain: 34} - type: mulp id: 121 parameters: {stereo: 0} - type: send id: 122 parameters: {amount: 0, port: 0, sendpop: 1, target: 106} + - name: snare edm 2 (sample) + comment: 'Suggested range: E-2 to C-3' + numvoices: 1 + units: + - type: envelope + parameters: {attack: 0, decay: 76, gain: 96, release: 0, stereo: 0, sustain: 0} + - type: oscillator + id: 200 + parameters: {color: 64, detune: 116, gain: 37, lfo: 0, looplength: 1, loopstart: 4276, phase: 0, samplestart: 560606, shape: 114, stereo: 0, transpose: 86, type: 4, unison: 2} + - type: distort + parameters: {drive: 95, stereo: 0} + - type: mulp + parameters: {panning: 64, stereo: 0} + - type: envelope + parameters: {attack: 0, auxgain: 64, decay: 68, gain: 83, outgain: 64, release: 0, stereo: 0, sustain: 0} + - type: noise + parameters: {gain: 107, shape: 3, stereo: 0} + - type: mulp + parameters: {stereo: 0} + - type: filter + id: 201 + parameters: {bandpass: 0, frequency: 57, highpass: 0, lowpass: 1, negbandpass: 0, neghighpass: 1, resonance: 67, stereo: 0} + - type: filter + parameters: {bandpass: 0, frequency: 128, highpass: 0, lowpass: 1, negbandpass: 0, neghighpass: 0, resonance: 78, stereo: 0} + - type: addp + parameters: {stereo: 0} + - type: pan + parameters: {panning: 71, stereo: 0} + - type: outaux + parameters: {auxgain: 10, outgain: 84, stereo: 1} + - type: envelope + parameters: {attack: 47, decay: 54, gain: 128, release: 0, stereo: 0, sustain: 0} + - type: send + parameters: {amount: 19, port: 0, sendpop: 1, target: 201} + - type: envelope + parameters: {attack: 54, decay: 68, gain: 128, release: 0, stereo: 0, sustain: 70} + - type: send + parameters: {amount: 26, port: 0, sendpop: 1, target: 202} + - name: clap + numvoices: 1 + units: + - type: envelope + id: 1 + parameters: {attack: 0, decay: 53, gain: 128, release: 0, stereo: 0, sustain: 0} + - type: delay + id: 162 + parameters: {damp: 0, dry: 128, feedback: 0, notetracking: 0, pregain: 64, stereo: 0} + varargs: [1395, 350] + - type: noise + id: 3 + parameters: {gain: 0, shape: 97, stereo: 0} + - type: mulp + id: 4 + parameters: {stereo: 0} + - type: envelope + id: 163 + parameters: {attack: 0, decay: 54, gain: 128, release: 0, stereo: 0, sustain: 0} + - type: delay + id: 164 + parameters: {damp: 0, dry: 6, feedback: 0, notetracking: 0, pregain: 64, stereo: 0} + varargs: [1744, 1744] + - type: noise + id: 165 + parameters: {gain: 128, shape: 79, stereo: 0} + - type: mulp + id: 171 + parameters: {stereo: 0} + - type: addp + id: 235 + parameters: {stereo: 0} + - type: envelope + id: 233 + parameters: {attack: 0, decay: 62, gain: 42, release: 0, stereo: 0, sustain: 0} + - type: oscillator + id: 234 + parameters: {color: 64, detune: 64, gain: 125, looplength: 1, loopstart: 2423, phase: 0, samplestart: 641780, shape: 64, stereo: 0, transpose: 64, type: 4} + - type: mulp + id: 236 + parameters: {stereo: 0} + - type: addp + id: 173 + parameters: {stereo: 0} + - type: filter + id: 5 + parameters: {bandpass: 0, frequency: 39, highpass: 0, lowpass: 1, negbandpass: 0, neghighpass: 1, resonance: 76, stereo: 0} + - type: distort + parameters: {drive: 114, stereo: 0} + - type: pan + id: 174 + parameters: {panning: 70, stereo: 0} + - type: outaux + id: 161 + parameters: {auxgain: 12, outgain: 50, stereo: 1} + - name: House Bass Organ + numvoices: 1 + units: + - type: envelope + id: 207 + parameters: {attack: 46, decay: 74, gain: 77, release: 39, stereo: 0, sustain: 36} + - type: oscillator + id: 208 + parameters: {color: 84, detune: 48, gain: 128, phase: 0, shape: 50, stereo: 0, transpose: 40, type: 1, unison: 3} + - type: oscillator + id: 213 + parameters: {color: 64, detune: 64, gain: 64, phase: 0, shape: 64, stereo: 0, transpose: 71, type: 2, unison: 0} + - type: addp + id: 214 + parameters: {stereo: 0} + - type: mulp + id: 209 + parameters: {stereo: 0} + - type: filter + id: 218 + parameters: {bandpass: 0, frequency: 3, highpass: 0, lowpass: 1, negbandpass: 0, neghighpass: 0, resonance: 128, stereo: 0} + - type: filter + id: 219 + parameters: {bandpass: 0, frequency: 94, highpass: 0, lowpass: 1, negbandpass: 0, neghighpass: 0, resonance: 128, stereo: 0} + - type: distort + id: 215 + parameters: {drive: 83, stereo: 0} + - type: envelope + id: 221 + parameters: {attack: 32, decay: 53, gain: 64, release: 0, stereo: 0, sustain: 0} + - type: noise + id: 222 + parameters: {gain: 59, shape: 52, stereo: 0} + - type: mulp + id: 223 + parameters: {stereo: 0} + - type: filter + id: 225 + parameters: {bandpass: 0, frequency: 91, highpass: 0, lowpass: 1, negbandpass: 1, neghighpass: 0, resonance: 102, stereo: 0} + - type: addp + id: 224 + parameters: {stereo: 0} + - type: compressor + id: 229 + parameters: {attack: 37, invgain: 87, ratio: 102, release: 65, stereo: 0, threshold: 47} + - type: mulp + id: 230 + parameters: {stereo: 0} + - type: distort + id: 228 + parameters: {drive: 59, stereo: 0} + - type: pan + id: 211 + parameters: {panning: 64, stereo: 0} + - type: outaux + id: 212 + parameters: {auxgain: 23, outgain: 98, stereo: 1} + - type: envelope + id: 220 + parameters: {attack: 0, decay: 72, gain: 76, release: 45, stereo: 0, sustain: 47} + - type: send + id: 217 + parameters: {amount: 128, port: 0, sendpop: 1, stereo: 0, target: 218, unit: 0, voice: 0} + - name: Crash909 + numvoices: 2 + units: + - type: envelope + id: 1 + parameters: {attack: 8, decay: 90, gain: 128, release: 0, stereo: 1, sustain: 0} + - type: envelope + id: 231 + parameters: {attack: 21, decay: 78, gain: 64, release: 85, stereo: 1, sustain: 0} + - type: mulp + id: 232 + parameters: {stereo: 1} + - type: oscillator + id: 2 + parameters: {color: 64, detune: 64, gain: 111, looplength: 5676, loopstart: 2615, phase: 0, samplestart: 433554, shape: 64, stereo: 1, transpose: 77, type: 4, unison: 0} + - type: mulp + id: 3 + parameters: {stereo: 1} + - type: pan + id: 5 + parameters: {damp: 0, dry: 128, feedback: 96, notetracking: 2, panning: 73, pregain: 40, stereo: 1} + - type: outaux + id: 6 + parameters: {auxgain: 78, outgain: 49, panning: 64, stereo: 1} - name: hihat numvoices: 1 units: - type: envelope - id: 128 - parameters: {attack: 4, decay: 53, gain: 128, release: 0, stereo: 0, sustain: 0} - - type: noise - id: 129 - parameters: {gain: 128, shape: 102, stereo: 0} + id: 1 + parameters: {attack: 50, decay: 60, gain: 128, release: 0, stereo: 1, sustain: 0} + - type: oscillator + parameters: {color: 64, detune: 64, gain: 127, looplength: 1, loopstart: 1343, phase: 0, samplestart: 367477, shape: 64, stereo: 1, transpose: 82, type: 4} - type: mulp - id: 130 - parameters: {stereo: 0} + id: 239 + parameters: {stereo: 1} - type: filter - id: 131 - parameters: {bandpass: 0, frequency: 87, highpass: 1, lowpass: 0, negbandpass: 0, neghighpass: 0, resonance: 128, stereo: 0} + parameters: {bandpass: 0, frequency: 78, highpass: 0, lowpass: 1, negbandpass: 1, neghighpass: 1, resonance: 128, stereo: 1} - type: filter - id: 132 - parameters: {bandpass: 0, frequency: 95, highpass: 1, lowpass: 1, negbandpass: 0, neghighpass: 0, resonance: 128, stereo: 0} - - type: filter - id: 133 - parameters: {bandpass: 1, frequency: 89, highpass: 0, lowpass: 0, negbandpass: 0, neghighpass: 0, resonance: 71, stereo: 0} + id: 240 + parameters: {bandpass: 0, frequency: 109, highpass: 0, lowpass: 1, negbandpass: 0, neghighpass: 0, resonance: 128, stereo: 1} - type: pan - id: 134 - parameters: {panning: 61, stereo: 0} + id: 7 + parameters: {panning: 57, stereo: 1} - type: outaux id: 11 - parameters: {auxgain: 0, outgain: 45, stereo: 1} - - name: ba_reese - numvoices: 1 - units: - - type: oscillator - id: 159 - parameters: {color: 128, detune: 87, gain: 128, lfo: 0, phase: 64, shape: 65, stereo: 1, transpose: 64, type: 1, unison: 2} - - type: oscillator - id: 160 - parameters: {color: 128, detune: 60, gain: 128, lfo: 0, phase: 87, shape: 64, stereo: 1, transpose: 64, type: 1, unison: 3} - - type: addp - id: 162 - parameters: {stereo: 1} - - type: oscillator - id: 161 - parameters: {color: 128, detune: 69, gain: 128, lfo: 0, phase: 0, shape: 106, stereo: 1, transpose: 64, type: 0, unison: 2} - - type: addp - id: 16 - parameters: {stereo: 1} - - type: filter - id: 17 - parameters: {bandpass: 0, frequency: 62, highpass: 0, lowpass: 1, negbandpass: 0, neghighpass: 0, resonance: 91, stereo: 1} - - type: filter - id: 190 - parameters: {bandpass: 0, frequency: 103, highpass: 1, lowpass: 1, negbandpass: 1, neghighpass: 0, resonance: 26, stereo: 0} - - type: xch - id: 195 - parameters: {stereo: 0} - - type: filter - id: 196 - parameters: {bandpass: 0, frequency: 85, highpass: 1, lowpass: 1, negbandpass: 1, neghighpass: 0, resonance: 31, stereo: 0} - - type: distort - id: 193 - parameters: {drive: 96, stereo: 1} - - type: filter - id: 194 - parameters: {bandpass: 0, frequency: 12, highpass: 1, lowpass: 1, negbandpass: 1, neghighpass: 0, resonance: 128, stereo: 1} - - type: envelope - id: 189 - parameters: {attack: 25, decay: 59, gain: 64, release: 60, stereo: 1, sustain: 106} - - type: mulp - id: 206 - parameters: {stereo: 1} - - type: outaux - id: 21 - parameters: {auxgain: 21, outgain: 29, stereo: 1} - - type: oscillator - id: 149 - parameters: {color: 128, detune: 64, gain: 128, lfo: 1, phase: 4, shape: 64, stereo: 0, transpose: 64, type: 1} - - type: send - id: 150 - parameters: {amount: 52, port: 1, sendpop: 1, stereo: 0, target: 159} - - type: oscillator - id: 152 - parameters: {color: 54, detune: 42, gain: 128, lfo: 1, phase: 55, shape: 63, stereo: 0, transpose: 41, type: 0} - - type: send - id: 153 - parameters: {amount: 75, port: 1, sendpop: 0, stereo: 0, target: 160} - - type: send - id: 154 - parameters: {amount: 59, port: 3, sendpop: 1, stereo: 0, target: 160} - - type: oscillator - id: 156 - parameters: {color: 128, detune: 64, gain: 128, lfo: 1, phase: 0, shape: 64, stereo: 0, transpose: 74, type: 0} - - type: send - id: 157 - parameters: {amount: 69, port: 1, sendpop: 1, stereo: 0, target: 161} - - type: oscillator - id: 191 - parameters: {color: 128, detune: 64, gain: 128, lfo: 1, phase: 0, shape: 64, stereo: 0, transpose: 40, type: 0, unison: 0} - - type: send - id: 192 - parameters: {amount: 71, port: 0, sendpop: 1, stereo: 0, target: 190, unit: 0, voice: 0} - - type: oscillator - id: 197 - parameters: {color: 128, detune: 64, gain: 128, lfo: 1, phase: 0, shape: 64, stereo: 0, transpose: 40, type: 0} - - type: send - id: 198 - parameters: {amount: 86, port: 0, sendpop: 1, stereo: 0, target: 196, unit: 0, voice: 0} - - name: ky_sine - numvoices: 1 - units: - - type: envelope - id: 163 - parameters: {attack: 39, decay: 62, gain: 71, release: 30, stereo: 0, sustain: 0} - - type: oscillator - id: 164 - parameters: {color: 53, detune: 62, gain: 72, lfo: 0, phase: 14, shape: 27, stereo: 0, transpose: 88, type: 0} - - type: oscillator - id: 165 - parameters: {color: 113, detune: 66, gain: 128, lfo: 0, phase: 64, shape: 64, stereo: 0, transpose: 88, type: 0} - - type: addp - id: 166 - parameters: {stereo: 0} - - type: mulp - id: 167 - parameters: {stereo: 0} - - type: pan - id: 168 - parameters: {panning: 64, stereo: 0} - - type: delay - id: 169 - parameters: {damp: 0, dry: 128, feedback: 86, notetracking: 2, pregain: 71, stereo: 0} - varargs: [64] - - type: xch - id: 170 - parameters: {stereo: 0} - - type: delay - id: 171 - parameters: {damp: 0, dry: 128, feedback: 90, notetracking: 2, pregain: 73, stereo: 0} - varargs: [36] - - type: outaux - id: 172 - parameters: {auxgain: 52, outgain: 84, stereo: 1} - - name: ba_trana - numvoices: 1 - units: - - type: envelope - id: 173 - parameters: {attack: 39, decay: 81, gain: 128, release: 0, stereo: 0, sustain: 0} - - type: send - id: 174 - parameters: {amount: 87, port: 0, sendpop: 0, target: 181} - - type: send - id: 175 - parameters: {amount: 90, port: 3, sendpop: 1, target: 179} - - type: envelope - id: 176 - parameters: {attack: 33, decay: 57, gain: 128, release: 57, stereo: 0, sustain: 67} - - type: oscillator - id: 177 - parameters: {color: 98, detune: 64, gain: 101, lfo: 0, phase: 0, shape: 64, stereo: 0, transpose: 76, type: 0, unison: 0} - - type: oscillator - id: 179 - parameters: {color: 78, detune: 48, gain: 64, lfo: 0, phase: 85, shape: 97, stereo: 0, transpose: 64, type: 1, unison: 3} - - type: addp - id: 178 - parameters: {stereo: 0} - - type: mulp - id: 185 - parameters: {stereo: 0} - - type: filter - id: 181 - parameters: {bandpass: 0, frequency: 39, highpass: 0, lowpass: 1, negbandpass: 0, neghighpass: 0, resonance: 82, stereo: 0} - - type: filter - id: 182 - parameters: {bandpass: 0, frequency: 15, highpass: 0, lowpass: 1, negbandpass: 0, neghighpass: 1, resonance: 128, stereo: 0} - - type: pan - id: 183 - parameters: {panning: 64, stereo: 0} - - type: distort - id: 200 - parameters: {drive: 80, stereo: 1} - - type: compressor - id: 186 - parameters: {attack: 48, invgain: 87, ratio: 54, release: 56, stereo: 1, threshold: 46} - - type: mulp - id: 187 - parameters: {stereo: 1} - - type: outaux - id: 184 - parameters: {auxgain: 35, outgain: 85, stereo: 1} + parameters: {auxgain: 0, outgain: 84, stereo: 1} - name: Global numvoices: 1 units: @@ -383,7 +294,7 @@ patch: parameters: {channel: 2, stereo: 1} - type: delay id: 8 - parameters: {damp: 77, dry: 128, feedback: 114, notetracking: 0, pregain: 50, stereo: 1} + parameters: {damp: 42, dry: 128, feedback: 120, notetracking: 0, pregain: 40, stereo: 1} varargs: [1116, 1188, 1276, 1356, 1422, 1492, 1556, 1618, 1140, 1212, 1300, 1380, 1446, 1516, 1580, 1642] - type: out id: 9 diff --git a/4klang_st.yml b/4klang_st.yml new file mode 100644 index 0000000..f459de8 --- /dev/null +++ b/4klang_st.yml @@ -0,0 +1,301 @@ +bpm: 116 +rowsperbeat: 4 +score: + tracks: + - numvoices: 1 + order: [-1, -1, -1, -1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, -1] + patterns: [[48, 1, 1, 1, 48, 1, 1, 1, 48, 1, 1, 1, 48, 1, 1, 1], [48, 1, 1, 1, 48, 1, 1, 1, 48, 1, 1, 1, 48, 1, 48, 1]] + - numvoices: 1 + order: [-1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, -1] + patterns: [[1, 1, 1, 1, 58, 1, 1, 1, 1, 1, 1, 1, 58, 1, 1, 1]] + - numvoices: 1 + order: [-1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1] + patterns: [[1, 1, 1, 1, 72, 1, 1, 1, 1, 1, 1, 1, 72, 1, 1, 1]] + - numvoices: 1 + order: [0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 2] + patterns: [[74, 1, 0, 1, 74, 1, 77, 70, 1, 0, 70, 1, 0, 70, 1, 0], [74, 1, 0, 1, 74, 1, 77, 70, 1, 0, 70, 1, 0, 1, 72, 1], [74, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]] + - numvoices: 2 + order: [-1, -1, -1, -1, 0, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, -1] + patterns: [[60, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]] + - numvoices: 1 + order: [-1, -1, -1, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1] + patterns: [[1, 1, 53, 1, 1, 1, 53, 1, 1, 1, 53, 1, 1, 1, 53, 1], [1, 1, 53, 1, 1, 1, 53, 1, 1, 1, 53, 1, 1, 1, 53, 53]] + rowsperpattern: 16 + length: 17 +patch: + - name: kick edm 2 + comment: Suggested note to play G-2 to C-3 + numvoices: 1 + units: + - type: envelope + id: 105 + parameters: {attack: 18, channel: 2, decay: 65, gain: 60, release: 0, stereo: 0, sustain: 0} + - type: oscillator + id: 106 + parameters: {color: 128, detune: 57, gain: 79, lfo: 0, phase: 0, shape: 63, stereo: 0, transpose: 94, type: 0, unison: 2} + - type: mulp + id: 126 + parameters: {stereo: 0} + - type: envelope + id: 110 + parameters: {attack: 0, decay: 43, gain: 128, release: 0, stereo: 0, sustain: 0} + - type: noise + id: 111 + parameters: {gain: 81, shape: 67, stereo: 0} + - type: filter + id: 112 + parameters: {bandpass: 0, frequency: 87, highpass: 0, lowpass: 1, negbandpass: 0, neghighpass: 1, resonance: 35, stereo: 0} + - type: filter + id: 113 + parameters: {bandpass: 0, frequency: 100, highpass: 0, lowpass: 1, negbandpass: 0, neghighpass: 0, resonance: 62, stereo: 0} + - type: mulp + id: 10 + parameters: {stereo: 0} + - type: addp + id: 127 + parameters: {stereo: 0} + - type: filter + id: 12 + parameters: {bandpass: 0, frequency: 9, highpass: 0, lowpass: 1, negbandpass: 0, neghighpass: 1, resonance: 75, stereo: 0} + - type: filter + id: 13 + parameters: {bandpass: 0, frequency: 53, highpass: 1, lowpass: 1, negbandpass: 0, neghighpass: 0, resonance: 128, stereo: 0} + - type: filter + id: 14 + parameters: {bandpass: 0, frequency: 10, highpass: 1, lowpass: 0, negbandpass: 0, neghighpass: 0, resonance: 85, stereo: 0} + - type: filter + id: 15 + parameters: {bandpass: 0, frequency: 10, highpass: 1, lowpass: 0, negbandpass: 0, neghighpass: 0, resonance: 49, stereo: 0} + - type: pan + id: 114 + parameters: {panning: 64, stereo: 0} + - type: outaux + id: 118 + parameters: {auxgain: 0, outgain: 57, stereo: 1} + - type: envelope + id: 119 + parameters: {attack: 62, decay: 128, gain: 128, release: 0, stereo: 0, sustain: 0} + - type: envelope + id: 120 + parameters: {attack: 39, decay: 61, gain: 128, release: 0, stereo: 0, sustain: 34} + - type: mulp + id: 121 + parameters: {stereo: 0} + - type: send + id: 122 + parameters: {amount: 0, port: 0, sendpop: 1, target: 106} + - name: snare edm 2 (sample) + comment: 'Suggested range: E-2 to C-3' + numvoices: 1 + units: + - type: envelope + parameters: {attack: 0, decay: 76, gain: 96, release: 0, stereo: 1, sustain: 0} + - type: oscillator + id: 200 + parameters: {color: 64, detune: 116, gain: 37, lfo: 0, looplength: 1, loopstart: 4276, phase: 0, samplestart: 560606, shape: 114, stereo: 1, transpose: 86, type: 4, unison: 2} + - type: distort + parameters: {drive: 95, stereo: 1} + - type: mulp + parameters: {panning: 64, stereo: 1} + - type: envelope + parameters: {attack: 0, auxgain: 64, decay: 68, gain: 83, outgain: 64, release: 0, stereo: 1, sustain: 0} + - type: noise + parameters: {gain: 107, shape: 3, stereo: 1} + - type: mulp + parameters: {stereo: 1} + - type: filter + id: 201 + parameters: {bandpass: 0, frequency: 57, highpass: 0, lowpass: 1, negbandpass: 0, neghighpass: 1, resonance: 67, stereo: 1} + - type: filter + parameters: {bandpass: 0, frequency: 128, highpass: 0, lowpass: 1, negbandpass: 0, neghighpass: 0, resonance: 78, stereo: 1} + - type: addp + parameters: {stereo: 1} + - type: pan + parameters: {panning: 64, stereo: 1} + - type: outaux + parameters: {auxgain: 0, outgain: 78, stereo: 1} + - type: envelope + parameters: {attack: 47, decay: 54, gain: 128, release: 0, stereo: 0, sustain: 0} + - type: send + parameters: {amount: 19, port: 0, sendpop: 1, target: 201} + - type: envelope + parameters: {attack: 54, decay: 68, gain: 128, release: 0, stereo: 0, sustain: 70} + - type: send + parameters: {amount: 26, port: 0, sendpop: 1, target: 202} + - name: clap + numvoices: 1 + units: + - type: envelope + id: 1 + parameters: {attack: 0, decay: 53, gain: 128, release: 0, stereo: 0, sustain: 0} + - type: delay + id: 162 + parameters: {damp: 0, dry: 128, feedback: 0, notetracking: 0, pregain: 64, stereo: 0} + varargs: [1395, 350] + - type: noise + id: 3 + parameters: {gain: 0, shape: 97, stereo: 0} + - type: mulp + id: 4 + parameters: {stereo: 0} + - type: envelope + id: 163 + parameters: {attack: 0, decay: 54, gain: 128, release: 0, stereo: 0, sustain: 0} + - type: delay + id: 164 + parameters: {damp: 0, dry: 6, feedback: 0, notetracking: 0, pregain: 64, stereo: 0} + varargs: [1744, 1744] + - type: noise + id: 165 + parameters: {gain: 128, shape: 79, stereo: 0} + - type: mulp + id: 171 + parameters: {stereo: 0} + - type: addp + id: 235 + parameters: {stereo: 0} + - type: envelope + id: 233 + parameters: {attack: 0, decay: 62, gain: 42, release: 0, stereo: 0, sustain: 0} + - type: oscillator + id: 234 + parameters: {color: 64, detune: 64, gain: 125, looplength: 1, loopstart: 2423, phase: 0, samplestart: 641780, shape: 64, stereo: 0, transpose: 64, type: 4} + - type: mulp + id: 236 + parameters: {stereo: 0} + - type: addp + id: 173 + parameters: {stereo: 0} + - type: filter + id: 5 + parameters: {bandpass: 0, frequency: 39, highpass: 0, lowpass: 1, negbandpass: 0, neghighpass: 1, resonance: 76, stereo: 0} + - type: distort + parameters: {drive: 114, stereo: 0} + - type: pan + id: 174 + parameters: {panning: 70, stereo: 0} + - type: outaux + id: 161 + parameters: {auxgain: 12, outgain: 50, stereo: 1} + - name: House Bass Organ + numvoices: 1 + units: + - type: envelope + id: 207 + parameters: {attack: 46, decay: 74, gain: 77, release: 39, stereo: 0, sustain: 36} + - type: oscillator + id: 208 + parameters: {color: 84, detune: 48, gain: 128, phase: 0, shape: 50, stereo: 0, transpose: 40, type: 1, unison: 3} + - type: oscillator + id: 213 + parameters: {color: 64, detune: 64, gain: 64, phase: 0, shape: 64, stereo: 0, transpose: 71, type: 2, unison: 0} + - type: addp + id: 214 + parameters: {stereo: 0} + - type: mulp + id: 209 + parameters: {stereo: 0} + - type: filter + id: 218 + parameters: {bandpass: 0, frequency: 3, highpass: 0, lowpass: 1, negbandpass: 0, neghighpass: 0, resonance: 128, stereo: 0} + - type: filter + id: 219 + parameters: {bandpass: 0, frequency: 94, highpass: 0, lowpass: 1, negbandpass: 0, neghighpass: 0, resonance: 128, stereo: 0} + - type: distort + id: 215 + parameters: {drive: 83, stereo: 0} + - type: envelope + id: 221 + parameters: {attack: 32, decay: 53, gain: 64, release: 0, stereo: 0, sustain: 0} + - type: noise + id: 222 + parameters: {gain: 59, shape: 52, stereo: 0} + - type: mulp + id: 223 + parameters: {stereo: 0} + - type: filter + id: 225 + parameters: {bandpass: 0, frequency: 91, highpass: 0, lowpass: 1, negbandpass: 1, neghighpass: 0, resonance: 102, stereo: 0} + - type: addp + id: 224 + parameters: {stereo: 0} + - type: compressor + id: 229 + parameters: {attack: 37, invgain: 87, ratio: 102, release: 65, stereo: 0, threshold: 47} + - type: mulp + id: 230 + parameters: {stereo: 0} + - type: distort + id: 228 + parameters: {drive: 59, stereo: 0} + - type: pan + id: 211 + parameters: {panning: 64, stereo: 0} + - type: outaux + id: 212 + parameters: {auxgain: 23, outgain: 98, stereo: 1} + - type: envelope + id: 220 + parameters: {attack: 0, decay: 72, gain: 76, release: 45, stereo: 0, sustain: 47} + - type: send + id: 217 + parameters: {amount: 128, port: 0, sendpop: 1, stereo: 0, target: 218, unit: 0, voice: 0} + - name: Crash909 + numvoices: 2 + units: + - type: envelope + id: 1 + parameters: {attack: 8, decay: 90, gain: 128, release: 0, stereo: 1, sustain: 0} + - type: envelope + id: 231 + parameters: {attack: 21, decay: 78, gain: 64, release: 85, stereo: 1, sustain: 0} + - type: mulp + id: 232 + parameters: {stereo: 1} + - type: oscillator + id: 2 + parameters: {color: 64, detune: 64, gain: 111, looplength: 5676, loopstart: 2615, phase: 0, samplestart: 433554, shape: 64, stereo: 1, transpose: 77, type: 4, unison: 0} + - type: mulp + id: 3 + parameters: {stereo: 1} + - type: pan + id: 5 + parameters: {damp: 0, dry: 128, feedback: 96, notetracking: 2, panning: 73, pregain: 40, stereo: 1} + - type: outaux + id: 6 + parameters: {auxgain: 78, outgain: 49, panning: 64, stereo: 1} + - name: hihat + numvoices: 1 + units: + - type: envelope + id: 1 + parameters: {attack: 50, decay: 60, gain: 128, release: 0, stereo: 1, sustain: 0} + - type: oscillator + parameters: {color: 64, detune: 64, gain: 127, looplength: 1, loopstart: 1343, phase: 0, samplestart: 367477, shape: 64, stereo: 1, transpose: 82, type: 4} + - type: mulp + id: 239 + parameters: {stereo: 1} + - type: filter + parameters: {bandpass: 0, frequency: 78, highpass: 0, lowpass: 1, negbandpass: 1, neghighpass: 1, resonance: 128, stereo: 1} + - type: filter + id: 240 + parameters: {bandpass: 0, frequency: 109, highpass: 0, lowpass: 1, negbandpass: 0, neghighpass: 0, resonance: 128, stereo: 1} + - type: pan + id: 7 + parameters: {panning: 57, stereo: 1} + - type: outaux + id: 11 + parameters: {auxgain: 0, outgain: 84, stereo: 1} + - name: Global + numvoices: 1 + units: + - type: in + id: 7 + parameters: {channel: 2, stereo: 1} + - type: delay + id: 8 + parameters: {damp: 42, dry: 128, feedback: 120, notetracking: 0, pregain: 40, stereo: 1} + varargs: [1116, 1188, 1276, 1356, 1422, 1492, 1556, 1618, 1140, 1212, 1300, 1380, 1446, 1516, 1580, 1642] + - type: out + id: 9 + parameters: {gain: 128, stereo: 1} diff --git a/song.yml b/_4klang.yml similarity index 85% rename from song.yml rename to _4klang.yml index 4ed31b1..26e270f 100644 --- a/song.yml +++ b/_4klang.yml @@ -3,23 +3,23 @@ rowsperbeat: 4 score: tracks: - numvoices: 1 - order: [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 1, 2, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 4, 1, 1, 1, 2, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 4, -1, -1, 5] - patterns: [[1, 1, 1, 1, 1, 1, 1, 1, 57, 1, 1, 1, 57], [1, 1, 1, 1, 57, 1, 1, 1, 1, 1, 1, 1, 57], [1, 1, 1, 1, 57, 1, 1, 1, 1, 1, 1, 57, 57], [1, 1, 1, 1, 57, 57, 57, 57, 1, 1, 1, 1, 57], [1, 1, 1, 1, 57, 1, 1, 1, 57, 57, 1, 1, 57], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0]] + order: [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 1, 2, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 4, 1, 1, 1, 2, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 4, -1, -1, 5, -1] + patterns: [[1, 1, 1, 1, 1, 1, 1, 1, 57, 1, 1, 1, 57, 1, 1, 1], [1, 1, 1, 1, 57, 1, 1, 1, 1, 1, 1, 1, 57, 1, 1, 1], [1, 1, 1, 1, 57, 1, 1, 1, 1, 1, 1, 57, 57, 1, 1, 1], [1, 1, 1, 1, 57, 57, 57, 57, 1, 1, 1, 1, 57, 1, 1, 1], [1, 1, 1, 1, 57, 1, 1, 1, 57, 57, 1, 1, 57, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1]] - numvoices: 1 - order: [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 1, 2, 1, 1, 1, 3, 1, 1, 1, 2, 1, 1, 1, 4, 1, 1, 1, 2, 1, 1, 1, 3, 1, 1, 1, 2, 1, 1, 1, 4, -1, -1, 5] - patterns: [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 46, 1, 1, 1, 46], [46, 1, 1, 1, 1, 1, 1, 1, 1, 1, 46], [46, 1, 1, 1, 1, 1, 1, 1, 46, 1, 46], [46, 1, 1, 1, 1, 1, 1, 1, 46, 46, 46, 46], [46, 1, 1, 1, 1, 1, 1, 1, 1, 1, 46, 46], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0]] + order: [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 1, 2, 1, 1, 1, 3, 1, 1, 1, 2, 1, 1, 1, 4, 1, 1, 1, 2, 1, 1, 1, 3, 1, 1, 1, 2, 1, 1, 1, 4, -1, -1, 5, -1] + patterns: [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 46, 1, 1, 1, 46, 1], [46, 1, 1, 1, 1, 1, 1, 1, 1, 1, 46, 1, 1, 1, 1, 1], [46, 1, 1, 1, 1, 1, 1, 1, 46, 1, 46, 1, 1, 1, 1, 1], [46, 1, 1, 1, 1, 1, 1, 1, 46, 46, 46, 46, 1, 1, 1, 1], [46, 1, 1, 1, 1, 1, 1, 1, 1, 1, 46, 46, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1]] - numvoices: 1 - order: [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 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, -1, -1, 1] - patterns: [[48, 1, 48, 1, 1, 1, 48, 1, 48, 1, 48, 1, 1, 1, 48], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0]] + order: [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 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, -1, -1, 1, -1] + patterns: [[48, 1, 48, 1, 1, 1, 48, 1, 48, 1, 48, 1, 1, 1, 48, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1]] - numvoices: 1 - order: [0, -1, 1, -1, 2, 3, 4, 5, 2, 6, 7, 8, 0, -1, -1, 9] - patterns: [[50], [48], [46], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 48, 1, 50, 1, 53], [43], [1, 1, 1, 1, 1, 1, 1, 1, 43, 1, 45, 1, 46, 1, 48], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 48, 1, 50], [52], [45], [1, 1, 1, 1, 1, 1, 1, 1, 0]] + order: [0, -1, 1, -1, 2, 3, 4, 5, 2, 6, 7, 8, 0, -1, -1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1] + patterns: [[50, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [48, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [46, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 48, 1, 50, 1, 53, 1], [43, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 43, 1, 45, 1, 46, 1, 48, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 48, 1, 50, 1], [52, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [45, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1]] - numvoices: 1 - order: [0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2] + order: [0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, -1, -1, -1, -1] patterns: [[62, 0, 64, 0, 65, 0, 69, 0, 65, 0, 64, 0, 62, 0, 64, 0], [65, 0, 72, 0, 65, 0, 64, 0, 62, 0, 64, 0, 65, 0, 71, 0], [65, 0, 69, 0, 65, 0, 64, 0, 62, 0, 64, 0, 65, 0, 72, 0]] - numvoices: 1 - order: [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 1, 1, 2, 2, 3, 3, 0, 0, 1, 1, 2, 2, 3, 3, 0, 0, 1, 1, 2, 2, 3, 3, 0, 0, 1, 1, 2, 2, 3, 4] - patterns: [[50, 0, 50, 1, 50, 0, 50, 1, 50, 0, 50, 1, 50, 0, 50], [48, 0, 48, 1, 48, 0, 48, 1, 48, 0, 48, 1, 48, 0, 48], [46, 0, 46, 1, 46, 0, 46, 1, 46, 0, 46, 1, 46, 0, 46], [43, 0, 43, 1, 43, 0, 43, 1, 43, 0, 43, 1, 43, 0, 43], [43, 0, 43, 1, 43, 0, 43, 1, 43, 0, 43, 1, 43, 0, 43, 0]] + order: [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 1, 1, 2, 2, 3, 3, 0, 0, 1, 1, 2, 2, 3, 3, 0, 0, 1, 1, 2, 2, 3, 3, 0, 0, 1, 1, 2, 2, 3, 4, -1, -1, -1, -1] + patterns: [[50, 0, 50, 1, 50, 0, 50, 1, 50, 0, 50, 1, 50, 0, 50, 1], [48, 0, 48, 1, 48, 0, 48, 1, 48, 0, 48, 1, 48, 0, 48, 1], [46, 0, 46, 1, 46, 0, 46, 1, 46, 0, 46, 1, 46, 0, 46, 1], [43, 0, 43, 1, 43, 0, 43, 1, 43, 0, 43, 1, 43, 0, 43, 1], [43, 0, 43, 1, 43, 0, 43, 1, 43, 0, 43, 1, 43, 0, 43, 0]] rowsperpattern: 16 length: 52 patch: @@ -172,17 +172,6 @@ patch: - type: pan id: 114 parameters: {panning: 64, stereo: 0} - - type: delay - id: 115 - parameters: {damp: 128, dry: 128, feedback: 20, notetracking: 0, pregain: 21, stereo: 0} - varargs: [1140, 1212, 1300, 1380, 1446, 1516, 1580, 1642] - - type: xch - id: 116 - parameters: {stereo: 0} - - type: delay - id: 117 - parameters: {damp: 128, dry: 128, feedback: 20, notetracking: 0, pregain: 20, stereo: 0} - varargs: [1116, 1188, 1276, 1356, 1422, 1492, 1556, 1618] - type: outaux id: 118 parameters: {auxgain: 0, outgain: 128, stereo: 1} @@ -222,23 +211,54 @@ patch: - type: pan id: 134 parameters: {panning: 61, stereo: 0} - - type: delay - id: 135 - parameters: {damp: 29, dry: 128, feedback: 50, notetracking: 0, pregain: 28, stereo: 0} - varargs: [1116, 1188, 1276, 1356, 1422, 1492, 1556, 1618] - - type: xch - id: 136 - parameters: {stereo: 0} - - type: delay - id: 137 - parameters: {damp: 0, dry: 128, feedback: 40, notetracking: 0, pregain: 32, stereo: 0} - varargs: [1140, 1212, 1300, 1380, 1446, 1516, 1580, 1642] - type: outaux id: 11 parameters: {auxgain: 0, outgain: 45, stereo: 1} - name: ba_reese numvoices: 1 units: + - type: oscillator + id: 159 + parameters: {color: 128, detune: 87, gain: 128, lfo: 0, phase: 64, shape: 65, stereo: 1, transpose: 64, type: 1, unison: 2} + - type: oscillator + id: 160 + parameters: {color: 128, detune: 60, gain: 128, lfo: 0, phase: 87, shape: 64, stereo: 1, transpose: 64, type: 1, unison: 3} + - type: addp + id: 162 + parameters: {stereo: 1} + - type: oscillator + id: 161 + parameters: {color: 128, detune: 69, gain: 128, lfo: 0, phase: 0, shape: 106, stereo: 1, transpose: 64, type: 0, unison: 2} + - type: addp + id: 16 + parameters: {stereo: 1} + - type: filter + id: 17 + parameters: {bandpass: 0, frequency: 62, highpass: 0, lowpass: 1, negbandpass: 0, neghighpass: 0, resonance: 91, stereo: 1} + - type: filter + id: 190 + parameters: {bandpass: 0, frequency: 103, highpass: 1, lowpass: 1, negbandpass: 1, neghighpass: 0, resonance: 26, stereo: 0} + - type: xch + id: 195 + parameters: {stereo: 0} + - type: filter + id: 196 + parameters: {bandpass: 0, frequency: 85, highpass: 1, lowpass: 1, negbandpass: 1, neghighpass: 0, resonance: 31, stereo: 0} + - type: distort + id: 193 + parameters: {drive: 96, stereo: 1} + - type: filter + id: 194 + parameters: {bandpass: 0, frequency: 12, highpass: 1, lowpass: 1, negbandpass: 1, neghighpass: 0, resonance: 128, stereo: 1} + - type: envelope + id: 189 + parameters: {attack: 25, decay: 59, gain: 64, release: 60, stereo: 1, sustain: 106} + - type: mulp + id: 206 + parameters: {stereo: 1} + - type: outaux + id: 21 + parameters: {auxgain: 21, outgain: 29, stereo: 1} - type: oscillator id: 149 parameters: {color: 128, detune: 64, gain: 128, lfo: 1, phase: 4, shape: 64, stereo: 0, transpose: 64, type: 1} @@ -260,48 +280,6 @@ patch: - type: send id: 157 parameters: {amount: 69, port: 1, sendpop: 1, stereo: 0, target: 161} - - type: envelope - id: 189 - parameters: {attack: 22, decay: 54, gain: 64, release: 64, stereo: 1, sustain: 64} - - type: oscillator - id: 159 - parameters: {color: 128, detune: 87, gain: 128, lfo: 0, phase: 64, shape: 65, stereo: 1, transpose: 64, type: 1, unison: 3} - - type: oscillator - id: 160 - parameters: {color: 128, detune: 60, gain: 128, lfo: 0, phase: 87, shape: 64, stereo: 1, transpose: 64, type: 1, unison: 2} - - type: oscillator - id: 161 - parameters: {color: 128, detune: 69, gain: 128, lfo: 0, phase: 0, shape: 106, stereo: 1, transpose: 64, type: 0, unison: 2} - - type: addp - id: 162 - parameters: {stereo: 1} - - type: addp - id: 16 - parameters: {stereo: 1} - - type: filter - id: 17 - parameters: {bandpass: 0, frequency: 62, highpass: 0, lowpass: 1, negbandpass: 0, neghighpass: 0, resonance: 91, stereo: 1} - - type: filter - id: 190 - parameters: {bandpass: 0, frequency: 93, highpass: 1, lowpass: 1, negbandpass: 0, neghighpass: 1, resonance: 74, stereo: 1} - - type: xch - id: 195 - parameters: {stereo: 1} - - type: filter - id: 196 - parameters: {bandpass: 0, frequency: 94, highpass: 1, lowpass: 1, negbandpass: 0, neghighpass: 1, resonance: 78, stereo: 1} - - type: mulp - id: 19 - parameters: {stereo: 1} - - type: distort - id: 193 - parameters: {drive: 96, stereo: 1} - - type: filter - id: 194 - parameters: {bandpass: 0, frequency: 10, highpass: 1, lowpass: 1, negbandpass: 1, neghighpass: 0, resonance: 128, stereo: 1} - - type: outaux - id: 21 - parameters: {auxgain: 21, outgain: 29, stereo: 1} - type: oscillator id: 191 parameters: {color: 128, detune: 64, gain: 128, lfo: 1, phase: 0, shape: 64, stereo: 0, transpose: 40, type: 0, unison: 0} diff --git a/base.config b/base.config index afc39f3..6292e35 100644 --- a/base.config +++ b/base.config @@ -43,11 +43,11 @@ USE_WIDECHAR_TEXTS=1 ########### Time base ########### USE_TIME_DIVIDER_IN_X86_CODE=1 -TIME_DIVIDER=64145.453 +TIME_DIVIDER=91241.383 TIME_BASE=bars AUDIO_DELAY=2048 -PROD_END_TIME=3337536 +PROD_END_TIME=1552992 ########### Final product ########### @@ -59,11 +59,11 @@ EXE_LINKER_PROGRAM=GNU ld QUOTE=\" -CRINKLER_ORDERTRIES=400 +CRINKLER_ORDERTRIES=4000 -AUDIO_BUFFER_ALLOCATED_LENGTH=3337536 +AUDIO_BUFFER_ALLOCATED_LENGTH=1552992 AUDIO_SAMPLING_RATE=44100 LOOP_END=5.0 LOOP_START=3.0 LOOP_ENABLED=0 -TIME_DIVIDER_INT=64145 +TIME_DIVIDER_INT=91241 diff --git a/debug_audio.asm b/debug_audio.asm index 5848f84..24a2831 100644 --- a/debug_audio.asm +++ b/debug_audio.asm @@ -132,6 +132,7 @@ section .text ; the __imp__ versions refer to the corresponding import address table entries ; 4klang + extern _su_render_song@4 ; General Windows stuff @@ -179,10 +180,12 @@ SetRenderedAudioBufferPtr: export StartAudioRendererThread global _StartAudioRendererThread _StartAudioRendererThread -StartAudioRendererThread: +StartAudioRendererThread: push 0 push 0 push dword [rendered_audio_buffer_ptr] + extern _su_load_gmdls@0 + call _su_load_gmdls@0 push _su_render_song@4 push 0 push 0 diff --git a/exemain.asm b/exemain.asm index bcc17ad..0d366c3 100644 --- a/exemain.asm +++ b/exemain.asm @@ -389,6 +389,8 @@ main: push 0 push 0 push rendered_audio_data + (AUDIO_DELAY * 4) + extern _su_load_gmdls@0 + call _su_load_gmdls@0 push _su_render_song@4 push 0 push 0 diff --git a/minified.config b/minified.config index 10eeafa..517e10c 100644 --- a/minified.config +++ b/minified.config @@ -7,11 +7,11 @@ include $(PARENT_CONFIG) # Visuals -EXE_LINKER_PROGRAM=GNU ld +EXE_LINKER_PROGRAM=Crinkler CRINKLER_ORDERTRIES=4000 SHADER_FILE=shader_minified.h -TIME_UNIFORM_NAME='n' -RESOLUTION_UNIFORM_NAME='r' +TIME_UNIFORM_NAME='f' +RESOLUTION_UNIFORM_NAME='v' TEXTS_UNIFORM_NAME='k' USE_WIDECHAR_TEXTS=1 TIME_DIVIDER=44100.000 diff --git a/music/4k_house.xrns b/music/4k_house.xrns new file mode 100644 index 0000000000000000000000000000000000000000..c4fbeec7bddfe1b092f1e66241dfaf4d6c6a7d30 GIT binary patch literal 9927 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 Z|M`^wC0RtIrzTk7FBfoqCGvFl{{S`KC1U^p literal 16458 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 diff --git a/music/sointu_house.yml b/music/sointu_house.yml new file mode 100644 index 0000000..e3752bc --- /dev/null +++ b/music/sointu_house.yml @@ -0,0 +1,286 @@ +bpm: 100 +rowsperbeat: 4 +score: + tracks: + - numvoices: 1 + order: [0] + patterns: [[72, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 72]] + rowsperpattern: 16 + length: 1 +patch: + - name: kick edm 2 + comment: Suggested note to play G-2 to C-3 + numvoices: 1 + units: + - type: envelope + id: 105 + parameters: {attack: 18, channel: 2, decay: 65, gain: 60, release: 0, stereo: 0, sustain: 0} + - type: oscillator + id: 106 + parameters: {color: 128, detune: 57, gain: 79, lfo: 0, phase: 0, shape: 63, stereo: 0, transpose: 94, type: 0, unison: 2} + - type: mulp + id: 126 + parameters: {stereo: 0} + - type: envelope + id: 110 + parameters: {attack: 0, decay: 43, gain: 128, release: 0, stereo: 0, sustain: 0} + - type: noise + id: 111 + parameters: {gain: 81, shape: 67, stereo: 0} + - type: filter + id: 112 + parameters: {bandpass: 0, frequency: 87, highpass: 0, lowpass: 1, negbandpass: 0, neghighpass: 1, resonance: 35, stereo: 0} + - type: filter + id: 113 + parameters: {bandpass: 0, frequency: 100, highpass: 0, lowpass: 1, negbandpass: 0, neghighpass: 0, resonance: 62, stereo: 0} + - type: mulp + id: 10 + parameters: {stereo: 0} + - type: addp + id: 127 + parameters: {stereo: 0} + - type: filter + id: 12 + parameters: {bandpass: 0, frequency: 9, highpass: 0, lowpass: 1, negbandpass: 0, neghighpass: 1, resonance: 75, stereo: 0} + - type: filter + id: 13 + parameters: {bandpass: 0, frequency: 53, highpass: 1, lowpass: 1, negbandpass: 0, neghighpass: 0, resonance: 128, stereo: 0} + - type: filter + id: 14 + parameters: {bandpass: 0, frequency: 10, highpass: 1, lowpass: 0, negbandpass: 0, neghighpass: 0, resonance: 85, stereo: 0} + - type: filter + id: 15 + parameters: {bandpass: 0, frequency: 10, highpass: 1, lowpass: 0, negbandpass: 0, neghighpass: 0, resonance: 49, stereo: 0} + - type: pan + id: 114 + parameters: {panning: 64, stereo: 0} + - type: outaux + id: 118 + parameters: {auxgain: 0, outgain: 57, stereo: 1} + - type: envelope + id: 119 + parameters: {attack: 62, decay: 128, gain: 128, release: 0, stereo: 0, sustain: 0} + - type: envelope + id: 120 + parameters: {attack: 39, decay: 61, gain: 128, release: 0, stereo: 0, sustain: 34} + - type: mulp + id: 121 + parameters: {stereo: 0} + - type: send + id: 122 + parameters: {amount: 0, port: 0, sendpop: 1, target: 106} + - name: snare edm 2 (sample) + comment: 'Suggested range: E-2 to C-3' + numvoices: 1 + units: + - type: envelope + parameters: {attack: 0, decay: 76, gain: 96, release: 0, stereo: 1, sustain: 0} + - type: oscillator + id: 200 + parameters: {color: 64, detune: 116, gain: 37, lfo: 0, looplength: 1, loopstart: 4276, phase: 0, samplestart: 560606, shape: 114, stereo: 1, transpose: 86, type: 4, unison: 2} + - type: distort + parameters: {drive: 95, stereo: 1} + - type: mulp + parameters: {panning: 64, stereo: 1} + - type: envelope + parameters: {attack: 0, auxgain: 64, decay: 68, gain: 83, outgain: 64, release: 0, stereo: 1, sustain: 0} + - type: noise + parameters: {gain: 107, shape: 3, stereo: 1} + - type: mulp + parameters: {stereo: 1} + - type: filter + id: 201 + parameters: {bandpass: 0, frequency: 57, highpass: 0, lowpass: 1, negbandpass: 0, neghighpass: 1, resonance: 67, stereo: 1} + - type: filter + parameters: {bandpass: 0, frequency: 128, highpass: 0, lowpass: 1, negbandpass: 0, neghighpass: 0, resonance: 78, stereo: 1} + - type: addp + parameters: {stereo: 1} + - type: pan + parameters: {panning: 64, stereo: 1} + - type: outaux + parameters: {auxgain: 0, outgain: 78, stereo: 1} + - type: envelope + parameters: {attack: 47, decay: 54, gain: 128, release: 0, stereo: 0, sustain: 0} + - type: send + parameters: {amount: 19, port: 0, sendpop: 1, target: 201} + - type: envelope + parameters: {attack: 54, decay: 68, gain: 128, release: 0, stereo: 0, sustain: 70} + - type: send + parameters: {amount: 26, port: 0, sendpop: 1, target: 202} + - name: clap + numvoices: 1 + units: + - type: envelope + id: 1 + parameters: {attack: 0, decay: 53, gain: 128, release: 0, stereo: 1, sustain: 0} + - type: delay + id: 162 + parameters: {damp: 0, dry: 128, feedback: 0, notetracking: 0, pregain: 64, stereo: 1} + varargs: [1395, 350] + - type: noise + id: 3 + parameters: {gain: 0, shape: 97, stereo: 1} + - type: mulp + id: 4 + parameters: {stereo: 1} + - type: envelope + id: 163 + parameters: {attack: 0, decay: 54, gain: 128, release: 0, stereo: 1, sustain: 0} + - type: delay + id: 164 + parameters: {damp: 0, dry: 6, feedback: 0, notetracking: 0, pregain: 64, stereo: 1} + varargs: [1744, 1744] + - type: noise + id: 165 + parameters: {gain: 128, shape: 79, stereo: 1} + - type: mulp + id: 171 + parameters: {stereo: 1} + - type: addp + id: 235 + parameters: {stereo: 1} + - type: envelope + id: 233 + parameters: {attack: 0, decay: 62, gain: 42, release: 0, stereo: 1, sustain: 0} + - type: oscillator + id: 234 + parameters: {color: 64, detune: 64, gain: 125, looplength: 1, loopstart: 2423, phase: 0, samplestart: 641780, shape: 64, stereo: 1, transpose: 64, type: 4} + - type: mulp + id: 236 + parameters: {stereo: 1} + - type: addp + id: 173 + parameters: {stereo: 1} + - type: filter + id: 5 + parameters: {bandpass: 0, frequency: 39, highpass: 0, lowpass: 1, negbandpass: 0, neghighpass: 1, resonance: 76, stereo: 1} + - type: distort + parameters: {drive: 114, stereo: 1} + - type: pan + id: 174 + parameters: {panning: 80, stereo: 1} + - type: outaux + id: 161 + parameters: {auxgain: 12, outgain: 50, stereo: 1} + - name: House Bass Organ + numvoices: 1 + units: + - type: envelope + id: 207 + parameters: {attack: 46, decay: 74, gain: 77, release: 39, stereo: 0, sustain: 36} + - type: oscillator + id: 208 + parameters: {color: 84, detune: 48, gain: 128, phase: 0, shape: 50, stereo: 0, transpose: 40, type: 1, unison: 3} + - type: oscillator + id: 213 + parameters: {color: 64, detune: 64, gain: 64, phase: 0, shape: 64, stereo: 0, transpose: 71, type: 2, unison: 0} + - type: addp + id: 214 + parameters: {stereo: 0} + - type: mulp + id: 209 + parameters: {stereo: 0} + - type: filter + id: 218 + parameters: {bandpass: 0, frequency: 3, highpass: 0, lowpass: 1, negbandpass: 0, neghighpass: 0, resonance: 128, stereo: 0} + - type: filter + id: 219 + parameters: {bandpass: 0, frequency: 94, highpass: 0, lowpass: 1, negbandpass: 0, neghighpass: 0, resonance: 128, stereo: 0} + - type: distort + id: 215 + parameters: {drive: 83, stereo: 0} + - type: envelope + id: 221 + parameters: {attack: 32, decay: 53, gain: 64, release: 0, stereo: 0, sustain: 0} + - type: noise + id: 222 + parameters: {gain: 59, shape: 52, stereo: 0} + - type: mulp + id: 223 + parameters: {stereo: 0} + - type: filter + id: 225 + parameters: {bandpass: 0, frequency: 91, highpass: 0, lowpass: 1, negbandpass: 1, neghighpass: 0, resonance: 102, stereo: 0} + - type: addp + id: 224 + parameters: {stereo: 0} + - type: compressor + id: 229 + parameters: {attack: 37, invgain: 87, ratio: 102, release: 65, stereo: 0, threshold: 47} + - type: mulp + id: 230 + parameters: {stereo: 0} + - type: distort + id: 228 + parameters: {drive: 59, stereo: 0} + - type: pan + id: 211 + parameters: {panning: 64, stereo: 0} + - type: outaux + id: 212 + parameters: {auxgain: 23, outgain: 98, stereo: 1} + - type: envelope + id: 220 + parameters: {attack: 0, decay: 72, gain: 76, release: 45, stereo: 0, sustain: 47} + - type: send + id: 217 + parameters: {amount: 128, port: 0, sendpop: 1, stereo: 0, target: 218, unit: 0, voice: 0} + - name: Crash909 + numvoices: 2 + units: + - type: envelope + id: 1 + parameters: {attack: 8, decay: 90, gain: 128, release: 0, stereo: 1, sustain: 0} + - type: envelope + id: 231 + parameters: {attack: 21, decay: 78, gain: 64, release: 85, stereo: 1, sustain: 0} + - type: mulp + id: 232 + parameters: {stereo: 1} + - type: oscillator + id: 2 + parameters: {color: 64, detune: 64, gain: 111, looplength: 5676, loopstart: 2615, phase: 0, samplestart: 433554, shape: 64, stereo: 1, transpose: 77, type: 4, unison: 0} + - type: mulp + id: 3 + parameters: {stereo: 1} + - type: pan + id: 5 + parameters: {damp: 0, dry: 128, feedback: 96, notetracking: 2, panning: 73, pregain: 40, stereo: 1} + - type: outaux + id: 6 + parameters: {auxgain: 78, outgain: 49, panning: 64, stereo: 1} + - name: hihat + numvoices: 1 + units: + - type: envelope + id: 1 + parameters: {attack: 50, decay: 60, gain: 128, release: 0, stereo: 1, sustain: 0} + - type: oscillator + parameters: {color: 64, detune: 64, gain: 127, looplength: 1, loopstart: 1343, phase: 0, samplestart: 367477, shape: 64, stereo: 1, transpose: 82, type: 4} + - type: mulp + id: 239 + parameters: {stereo: 1} + - type: filter + parameters: {bandpass: 0, frequency: 78, highpass: 0, lowpass: 1, negbandpass: 1, neghighpass: 1, resonance: 128, stereo: 1} + - type: filter + id: 240 + parameters: {bandpass: 0, frequency: 109, highpass: 0, lowpass: 1, negbandpass: 0, neghighpass: 0, resonance: 128, stereo: 1} + - type: pan + id: 7 + parameters: {panning: 57, stereo: 1} + - type: outaux + id: 11 + parameters: {auxgain: 0, outgain: 84, stereo: 1} + - name: Global + numvoices: 1 + units: + - type: in + id: 7 + parameters: {channel: 2, stereo: 1} + - type: delay + id: 8 + parameters: {damp: 42, dry: 128, feedback: 120, notetracking: 0, pregain: 40, stereo: 1} + varargs: [1116, 1188, 1276, 1356, 1422, 1492, 1556, 1618, 1140, 1212, 1300, 1380, 1446, 1516, 1580, 1642] + - type: out + id: 9 + parameters: {gain: 128, stereo: 1} diff --git a/shader.glsl b/shader.glsl index 05fc5cc..c7d804d 100644 --- a/shader.glsl +++ b/shader.glsl @@ -9,6 +9,12 @@ struct Ray { vec3 dir; }; +vec2 getUV(vec2 offset) { + vec2 uv = 2.0 *((gl_FragCoord.xy + offset*0.5)/u_resolution.xy - 0.5); + uv.x *= u_resolution.x/u_resolution.y; // Correct for aspect ratio + return uv; +} + mat2 scale(vec2 scale){ return mat2(1. / scale.x, 0.0, 0.0, 1./scale.y); } @@ -617,8 +623,20 @@ float sdCog2d(vec2 pos) { float sdCog(vec3 pos, float angle) { pos.xy *= Rot(angle); float d1 = opExtrusion(pos, sdCog2d(pos.xy), 0.05); - float d2 = fCapsule(pos, vec3(0., 0.0, 0.), vec3(0., 0., 1.), 0.2); - return 0.8 * fOpDifferenceRound(d1,d2,0.05)-0.003;} + float d2 = fCapsule(pos, vec3(0., 0.0, 0.), vec3(0., 0., 1.), 0.2); + return 0.8 * fOpDifferenceRound(d1,d2,0.05)-0.003; +} + +float sdText(vec3 pos, float angle) { + //pos.xy *= Rot(angle); + vec3 color = texture2D(texts, getUV(vec2( 0.,0.))).rgb; + + //gl_FragColor = vec4(vec3(color), 1.); + + //float d1 = opExtrusion(pos, , 0.1); + return 0.; +// return d1; +} float sdHex(vec3 pos, float i, float angle) { @@ -655,10 +673,11 @@ vec2 mapScene(in vec3 p) { if (d == a) mat = 1. + mod(i,3.); } - /*float c2 = sdCog(p, u_time); - d = min(d, c2); - if ( d == c2) mat = 4.; -*/ + + //float c2 = sdText(p, u_time); + //d = min(d, c2); + //if ( d == c2) mat = 4.; + // float c3 = fBox(p+vec3(0.5, .87, 0.), vec3(1., 1.,1.)); // d = min(d, c3); @@ -963,11 +982,7 @@ vec3 render(vec2 uv) { return col; } -vec2 getUV(vec2 offset) { - vec2 uv = 2.0 *((gl_FragCoord.xy + offset*0.5)/u_resolution.xy - 0.5); - uv.x *= u_resolution.x/u_resolution.y; // Correct for aspect ratio - return uv; -} + void main() { diff --git a/shader_minified.h b/shader_minified.h index dd1daff..c127e4b 100644 --- a/shader_minified.h +++ b/shader_minified.h @@ -1,18 +1,228 @@ // Generated with Shader Minifier 1.3.6 (https://github.com/laurentlb/Shader_Minifier/) #ifndef SHADER_MINIFIED_H_ # define SHADER_MINIFIED_H_ -# define VAR_my_fragColor "v" -# define VAR_u_resolution "r" -# define VAR_u_time "n" +# define VAR_texts "k" +# define VAR_texture_sampler "m" +# define VAR_u_resolution "v" +# define VAR_u_time "f" const char *__temp_cleaned_shader_glsl = - "#version 330\n" - "uniform float n;" - "uniform vec2 r;" - "layout(location=1) out vec4 v;struct Light{vec3 position;float intensity;vec3 color;};struct Surface{float dist;vec3 position;vec3 baseColor;vec3 normal;vec3 emissiveColor;};struct Hit{Surface surface;Surface near;};" + "uniform vec2 v;" + "uniform float f;" + "uniform sampler2D m,k;struct Ray{vec3 rd;vec3 dir;};" + "mat2 n()" + "{" + "vec2 v=vec2(1.3);" + "return mat2(1./v.x,0.,0.,1./v.y);" + "}" + "const float i=2.*acos(-1.),s=sqrt(5.)*.5+.5;" + "float n(vec3 v,vec2 x)" + "{" + "vec3 f=abs(v);" + "return max(f.y-x.y,max(f.x*sqrt(3.)*.5+f.z*.5,f.z)-x.x);" + "}" + "void n(inout vec2 v)" + "{" + "float f=acos(-1.)/2.;" + "v=cos(f)*v+sin(f)*vec2(v.y,-v.x);" + "}" + "float x(float v,float f)" + "{" + "return min(-.1,max(v,f))+length(max(vec2(.1+v,.1+f),vec2(0)));" + "}" + "float t(vec2 v,float f)" + "{" + "return fract(tan(distance(v*s,v)*f)*v.x);" + "}" + "mat2 t(float v)" + "{" + "float f=sin(v),x=cos(v);" + "return mat2(x,-f,f,x);" + "}" + "float n(vec3 v,float f,float i)" + "{" + "vec3 r=v;" + "r.xz*=t(i);" + "r.yz*=t(i);" + "n(r.yz);" + "float m=n(r,vec2(.5+f,.1)),y=n(r,vec2(.2+f,.1));" + "return x(m,-y);" + "}" + "vec2 x(vec3 v)" + "{" + "float x=0.,r=1e10;" + "vec3 i=v;" + "i.xy*=n();" + "for(float m=1.;m<=6.;m++)" + "{" + "float y=n(i,m*.35,f+abs(2.+.4*sin(f))*m*3.1415/6.);" + "r=min(r,y);" + "if(r==y)" + "x=1.+mod(m,3.);" + "}" + "return vec2(r,x);" + "}" + "vec3 t(vec3 v,vec3 f,inout vec3 i)" + "{" + "float r=0.,m=0.,y=0.;" + "for(int e=0;e<150;e++)" + "{" + "i=v+f*r;" + "vec2 n=x(i);" + "r+=n.x;" + "m=n.y;" + "if(r>80.)" + "break;" + "if(n.x80.)" + "r=-1.;" + "return vec3(r,m,y);" + "}" + "vec3 x(vec3 v,vec3 f,vec3 i)" + "{" + "float r=0.,m=0.,y=0.;" + "for(int e=0;e<50;e++)" + "{" + "i=v+f*r;" + "vec2 n=x(i);" + "r+=n.x;" + "m=n.y;" + "if(r>40.)" + "break;" + "if(n.x40.)" + "r=-1.;" + "return vec3(r,m,y);" + "}" + "float e(vec3 v,vec3 f)" + "{" + "float r=1.,m=.01;" + "for(int i=0;i<40;i++)" + "{" + "if(m>30.)" + "break;" + "float y=x(v+m*f).x;" + "r=min(r,y/(18.*m));" + "m+=clamp(y,.005,.5);" + "if(r<-1.||m>30.)" + "break;" + "}" + "r=max(r,-1.);" + "return.25*(1.+r)*(1.+r)*(2.-r);" + "}" + "vec3 e(vec3 v)" + "{" + "vec2 f=vec2(.001,0);" + "vec3 r=vec3(x(v+f.xyy).x-x(v-f.xyy).x,x(v+f.yxy).x-x(v-f.yxy).x,x(v+f.yyx).x-x(v-f.yyx).x);" + "return normalize(r);" + "}" + "vec3 p(vec3 v,vec3 f)" + "{" + "vec3 r=vec3(.5454);" + "return r+(1.-r)*pow(clamp(1.-dot(v,f),0.,1.),5.);" + "}" + "vec3 e(vec3 v,vec3 f,float r,vec3 i,vec3 x,vec3 y,float m)" + "{" + "vec3 n=normalize(i),d=vec3(max(0.,dot(n,reflect(x,y)))),s=p(normalize(n-x),n)*m;" + "float k=e(i+y*.01,v);" + "d=pow(d,vec3(r))*m;" + "return f*mix(vec3(1)*vec3(max(0.,dot(n,y))),d,s)*k;" + "}" + "float r(vec3 v,vec3 f)" + "{" + "float r=0.,m=1.;" + "for(int i=0;i<8;i++)" + "{" + "float y=.01+.02*float(i*i),d=x(v+f*y).x;" + "r+=(y-d)*m;" + "m*=.85;" + "}" + "return 1.-clamp(.6*r,0.,1.);" + "}" + "vec3 e(vec3 v,vec3 f,vec3 m,float i)" + "{" + "float y=1.,x=r(v,f);" + "vec3 n=vec3(.1529);" + "if(i==0.)" + "n=vec3(.2863,.1059,.2431),y=1.5;" + "else if(i==1.)" + "n=vec3(.3294,.0941,.6),y=.6;" + "else if(i==2.)" + "n=vec3(.5804,.9647,1),y=1.;" + "else if(i==3.)" + "n=vec3(0),y=1e2;" + "else if(i==4.)" + "n=vec3(.9961,1,.9922),y=.3;" + "vec3 d=vec3(0);" + "d+=e(vec3(0,-40,-1),vec3(.56,.44,.18)*2.,y,v,m,f,x);" + "d+=e(vec3(-20,4,10),vec3(.04,.2,.71)*2.,y,v,m,f,x);" + "vec3 s=vec3(0,4,2);" + "float c=e(v+f*.01,s);" + "d+=vec3(.6627,.7098,.8863)*clamp(dot(f,s),0.,1.)*c*x;" + "d+=vec3(.1333,.1333,.1216)*clamp(dot(f,normalize(s*vec3(-1,0,-1))),0.,1.)*x;" + "return n*max(vec3(0),d);" + "}" + "vec3 p(vec3 f)" + "{" + "vec2 r=gl_FragCoord.xy/v.xy;" + "f=mix(f,f*smoothstep(.8,.4,length(r-vec2(.5))),.9);" + "f=mix(f,smoothstep(0.,1.,f),.5);" + "f*=vec3(1);" + "return pow(f,vec3(1./2.2));" + "}" + "vec3 e(vec2 f,vec3 v,vec3 i)" + "{" + "vec3 r=normalize(i-v),y=cross(vec3(0,1,0),r);" + "return normalize(v+r+f.x*y+f.y*cross(r,y)-v);" + "}" + "vec3 p(vec2 v,vec3 f,vec3 i)" + "{" + "vec3 r=normalize(i-f),y=normalize(cross(vec3(0,1,0),r)),m=normalize(cross(r,y));" + "vec2 n=vec2(t(gl_FragCoord.xy,.13),t(gl_FragCoord.xy,.4));" + "return normalize(v.x*y+v.y*m+1.7*r+sqrt(n.x)*(y*sin(n.y*6.283)+m*cos(n.y*6.283))*.25*1.7/150.2);" + "}" + "vec3 r(vec2 v)" + "{" + "bool r=!true;" + "vec3 f=vec3(0,5,-3),y=vec3(0),m;" + "m=r?" + "p(v,f,y):" + "e(v,f,y);" + "vec3 i=vec3(.051,.0667,.1529),n=vec3(0),d=t(f,m,n),s=m;" + "if(d.z>0.)" + "{" + "vec3 k=e(n);" + "i=e(n,k,m,d.y);" + "i=i*exp(-d.x*.04)+mix(i,mix(vec3(.3686,.2431,.4392),vec3(.4,.7294,.9216),pow(max(dot(s,vec3(0,.3,-1)),0.),8.)),1.-exp(-d.x*.04))*(1.-exp(-d.x*.04));" + "m=normalize(reflect(m,k));" + "vec3 c=n+m*.01,g=x(c,m,n);" + "if(g.z>0.)" + "n=c+m*g.x,k=e(n),i+=.1*e(n,k,m,g.y);" + "}" + "return i;" + "}" + "vec2 e()" + "{" + "vec2 r=2.*((gl_FragCoord.xy+vec2(0)*.5)/v.xy-.5);" + "r.x*=v.x/v.y;" + "return r;" + "}" "void main()" "{" - "v=vec4(vec3(0,1,0),1);" + "vec3 v=vec3(0);" + "v+=r(e());" + "v=p(v);" + "gl_FragColor=vec4(v,1);" "}"; #endif // SHADER_MINIFIED_H_ diff --git a/texture_0.png b/texture_0.png new file mode 100644 index 0000000000000000000000000000000000000000..d676179a672006598d949a56cdcefe1750b5e748 GIT binary patch literal 19118 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 S)lJfEC@ZQfWSzP4;Qs(J8SFp+ literal 0 HcmV?d00001