kolibrios-gitea/programs/media/midamp/trunk/midilite.inc

293 lines
5.7 KiB
PHP
Raw Permalink Blame History

SYS equ meos
midi_parse:
and [max_note],0
and [cur_track],0
mov [min_note],0xff
mov edi,[midi_limit]
cmp dword[workarea],'MThd'
je .head_ok
mov edx,sHeadInv
call debug_outstr
jmp clearpath
.head_ok:
cmp dword[workarea+4],0x6000000
je .heads_ok
mov edx,sHSizeInv
call debug_outstr
jmp clearpath
.heads_ok:
cmp dword[workarea+8],0x1000000
jmp .headt_ok
mov edx,sTypeUnsup
call debug_outstr
jmp clearpath
.headt_ok:
movzx eax,word[workarea+12]
rol ax,8
mov [quarter],eax
mov [tempo],50
mov esi,workarea+0xe
skip_sections:
lodsd
cmp eax,'MTrk'
je track_found
if SYS eq meos
; dps <'What?',13,10>
end if
lodsd
add esi,eax
cmp esi,[midi_limit]
jbe skip_sections
if NONCRITICAL_MSG eq 1
dps 'No more tracks'
end if
and word[edi],0
; ud2
jmp decode_end
track_found:
if SYS eq meos1
dps <13,10,'Track '>
push esi
sub esi,workarea
; dpd esi
pop esi
end if
lodsd
bswap eax
mov bl,[cur_track]
cmp bl,[sel_track]
je .trk_fnd
add esi,eax
jmp next_event.eot
.trk_fnd:
mov [track_len],eax
dps 'TRK'
next_event:
call readvar
; dpd eax
add [delta],eax
lodsw ; al -event, ah - next byte
if SYS eq meos1
dph eax
dps <' ',13,10>
newline
end if
test al,0x80 ; check if a valid event
jnz .valid_evt2
dec esi
shl ax,8
mov al,[prev_cmd]
jmp .valid_evt
.valid_evt2:
mov [prev_cmd],al
.valid_evt:
cmp al,0xf0
jne .nosysex
dec esi
call readvar
add esi,eax
jmp next_event
.nosysex:
cmp al,0xff
jne .no_meta
; meta events
cmp ah,0x51
jne .notempo
push eax edx
mov eax,[esi]
xor al,al
bswap eax
xor edx,edx
mov ebx,10000
div ebx
pop edx eax
jmp .no_eot
.notempo:
cmp ah,0x2f ; end of track
jne .no_eot
inc esi
if SYS eq meos1
dps <13,10,'EOT'>
push esi
sub esi,workarea
dpd esi
pop esi
; mcall 5,200
; dph eax
; ud2
end if
.eot:
; dps 'EOT '
inc [cur_track]
jmp skip_sections;decode_end
.no_eot:
lodsb
movzx ecx,al ; ecx - length of metadata
add esi,ecx
jmp next_event
.no_meta:
cmp al,0xfa ; system ctl events
jb .no_sys
.dec_esi:
dec esi
jmp next_event
.no_sys:
cmp al,0xf8
je .dec_esi
movzx ecx,al ; ecx - MIDI Event Command
and ecx,0xf ; cl - channel
and al,0xf0 ; al - event code
cmp al,0xe0 ; Pitch wheel change
je .inc_esi
cmp al,0xb0
ja .no_inc
.inc_esi:
inc esi
.no_inc:
cmp ecx,[channel] ; Channel must be 0 !!!
jz .chan_ok
if NONCRITICAL_MSG eq 1
dps 'C' ; Reference to unsupported channel !!!
dpd ecx
mov ecx,esi
dps '-'
sub ecx,workarea+1
dpd ecx
end if
jmp next_event
.chan_ok:
cmp al,0x90 ; Note On
jne .no_noon
add al,[octave]
cmp [curnote],0x80
je .note_ok
if NONCRITICAL_MSG eq 1
dps 'N!' ; Note On without Off !!!
end if
.note_ok:
; dps 'N+'
; movzx ecx,ah
; dpd ecx
call insert_pause
mov [curnote],ah ; [curnote]=note number
jmp next_event
.no_noon:
cmp al,0x80 ; Note Off
jne .no_nooff
add ah,[octave]
cmp ah,[curnote]
je .off_ok
if NONCRITICAL_MSG eq 1
dps 'n!' ; Note Off mismatch !!!
end if
.off_ok:
; dps 'N-'
cmp ah,[max_note]
jbe .nomax
mov [max_note],ah
.nomax:
cmp ah,[min_note]
jae .ins
mov [min_note],ah
.ins:
call insert_note
mov [curnote],al
.no_nooff: ; No more supported events
jmp next_event
prev_cmd db ?
max_note db ?
min_note db ?
; *********************************************
; ******* READ VARIABLE BYTES ****************
; *********************************************
readvar:
; in: esi - pointer;
; out: esi - new pointer; eax - value;
push ebx ecx
movzx ebx,byte[esi]
inc esi
btr ebx,7
jnc .exit
.next:
shl ebx,7
lodsb
mov ecx,eax
and eax,0x7f
add ebx,eax
cmp cl,0x7f
ja .next
.exit:
mov eax,ebx
pop ecx ebx
ret
; *********************************************
; ******* INSERT PAUSE ***********************
; *********************************************
insert_pause:
cmp [delta],0
jz return
push eax ebx ecx
mov ah,0xff
jmp write_note
; *********************************************
; ******* INSERT NOTE ************************
; *********************************************
insert_note: ; ah - note code
push eax ebx ecx
movzx eax,ah
mov ebx,12
div bl
shl al,4
add ah,al
sub ah,0x1f
write_note:
push eax
mov eax,[delta]
mov edx,[tempo]
mul edx
mov ecx,[quarter]
div ecx ; ax - note delay
cmp eax,0x7f
jb .ok
mov eax,0x7f
.ok:
movzx ecx,al
or ecx,0x80
pop eax
mov al,cl
stosw
xor eax,eax
mov [delta],eax
pop ecx ebx eax
return:
ret
sHeadInv:
if lang eq ru_RU
db "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>",0
else
db "Header invalid",0
end if
sHSizeInv:
if lang eq ru_RU
db '<27><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><><E0A0A7><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>',0
else
db 'Header size invalid',0
end if
sTypeUnsup:
if lang eq ru_RU
db '<27><><EFBFBD> MIDI <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E0A6A8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>',0
else
db 'MIDI type not supported',0
end if