; ********************************************************* ; * ; * 303 routine ; * ; * ESI = 16-note melody buffer ; * EDI = target buffer ; * ; ********************************************************* ;%define K303_PHASE 0*4 %define K303_ATTACK 0*4 %define K303_RELEASE 1*4 %define K303_NOTESIZE 2*4 %define K303_DETUNE 3*4 %define K303_BASEOCT 4*4 %define K303_CUTOFF 5*4 %define K303_DECAY 6*4 %define K303_RESO 7*4 section .text bits 32 ;_KZG_303_sawtooth: ; fld st0 ; frndint ; fsubrp st1 ; ret global _KZG_303@0 _KZG_303@0: %ifdef DEBUG mov ebp,_KZG_303_paramstart %endif fldz ;mov ecx,16 push byte 16 pop ecx _KZG_303_onenote: xor eax,eax lodsb test al, al jz near _KZG_303_deadnote xor ebx, ebx xchg edx, eax pushad _KZG_303_onesample: xor eax,eax ; filter type ; OSC1 fld st0 ; call _KZG_303_sawtooth fld st0 frndint fsubrp st1 ; OSC2 fld st1 fmul dword [ebp+K303_DETUNE] ; call _KZG_303_sawtooth fld st0 frndint fsubrp st1 ; MIX faddp st1 ; FILTER push ebx fild dword [esp] pop ebx fidiv dword [ebp+K303_NOTESIZE] ;st0 = percentage ;st1 = sample value ;st2 = phase fld1 fsubrp st1 fmul dword [ebp+K303_DECAY] fadd dword [ebp+K303_CUTOFF] fstp dword [_KZG_filter_cutoff] fld dword [ebp+K303_RESO] fstp dword [_KZG_filter_reso] fstp dword [_KZG_filter_sample] call _KZG_filter@0 ; Volume envelope (click/pop removal) - start cmp ebx,[ebp+K303_ATTACK] jg _KZG_303_dontfadestart push ebx fild dword [esp] pop ebx fidiv dword [ebp+K303_ATTACK] fmulp st1,st0 _KZG_303_dontfadestart: ; Volume envelope (click/pop removal) - end mov eax,[ebp+K303_NOTESIZE] sub eax,ebx cmp eax,[ebp+K303_RELEASE] jg _KZG_303_dontfadeend push eax fild dword [esp] pop eax fidiv dword [ebp+K303_RELEASE] fmulp st1,st0 _KZG_303_dontfadeend: ; Write to buffer fadd dword [edi] fstp dword [edi] add edi,byte 4 ; Phase increment fld dword [_KZG_303_basefreq] mov ecx, edx _KZG_303_note: fmul dword [_KZG_halfnote] loop _KZG_303_note fmul dword [ebp+K303_BASEOCT] faddp st1 inc ebx cmp ebx, [ebp+K303_NOTESIZE] jnz near _KZG_303_onesample popad _KZG_303_deadnote: %ifndef NOTE ; mov eax,[_KZG_303_buffersize] ; lea edi, [edi + eax*4] mov eax,[_KZG_303_buffersize] shr eax,2 add edi,eax %else add edi,NOTE*4 %endif dec ecx jnz near _KZG_303_onenote fstp st0 ret ; ; %ifdef DEBUG section .data bits 32 _KZG_303_paramstart: global _KZG_303_attack _KZG_303_attack dd 100 global _KZG_303_release _KZG_303_release dd 0/4 global _KZG_303_notesize _KZG_303_notesize dd 02 global _KZG_303_detune _KZG_303_detune dd 0.98 global _KZG_303_baseoct _KZG_303_baseoct dd 0.25 global _KZG_303_cutoff _KZG_303_cutoff dd 2100.0 global _KZG_303_decay _KZG_303_decay dd 4000.0 global _KZG_303_reso _KZG_303_reso dd 0.1 %endif %ifndef NOTE section .data global _KZG_303_buffersize _KZG_303_buffersize dd 0 %endif