0,0 → 1,292 |
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 |
db "¥¢¥àë© § £®«®¢®ª",0 |
else |
db "Header invalid",0 |
end if |
|
sHSizeInv: |
if lang eq ru |
db '¥¢¥àë© à §¬¥à § £®«®¢ª ',0 |
else |
db 'Header size invalid',0 |
end if |
|
sTypeUnsup: |
if lang eq ru |
db '¨¯ MIDI ¥ ¯®¤¤¥à¦¨¢ ¥âáï',0 |
else |
db 'MIDI type not supported',0 |
end if |