Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. SYS equ meos
  2. midi_parse:
  3.     and  [max_note],0
  4.     and  [cur_track],0
  5.     mov  [min_note],0xff
  6.     mov  edi,[midi_limit]
  7.     cmp  dword[workarea],'MThd'
  8.     je   .head_ok
  9.     mov  edx,sHeadInv
  10.     call debug_outstr
  11.     jmp  clearpath
  12.   .head_ok:
  13.     cmp  dword[workarea+4],0x6000000
  14.     je   .heads_ok
  15.     mov  edx,sHSizeInv
  16.     call debug_outstr
  17.     jmp  clearpath
  18.   .heads_ok:
  19.     cmp  dword[workarea+8],0x1000000
  20.     jmp   .headt_ok
  21.     mov  edx,sTypeUnsup
  22.     call debug_outstr
  23.     jmp  clearpath
  24.   .headt_ok:
  25.     movzx eax,word[workarea+12]
  26.     rol  ax,8
  27.     mov  [quarter],eax
  28.     mov  [tempo],50
  29.     mov  esi,workarea+0xe
  30. skip_sections:
  31.     lodsd
  32.     cmp  eax,'MTrk'
  33.     je   track_found
  34. if SYS eq meos
  35. ;    dps  <'What?',13,10>
  36. end if
  37.     lodsd
  38.     add  esi,eax
  39.     cmp  esi,[midi_limit]
  40.     jbe  skip_sections
  41.  if NONCRITICAL_MSG eq 1
  42.     dps  'No more tracks'
  43.  end if
  44.     and  word[edi],0
  45. ;    ud2
  46.     jmp  decode_end
  47. track_found:
  48. if SYS eq meos1
  49.     dps  <13,10,'Track '>
  50.     push esi
  51.     sub  esi,workarea
  52. ;    dpd  esi
  53.     pop  esi
  54. end if
  55.     lodsd
  56.     bswap eax
  57.     mov  bl,[cur_track]
  58.     cmp  bl,[sel_track]
  59.     je   .trk_fnd
  60.     add  esi,eax
  61.     jmp  next_event.eot
  62.   .trk_fnd:
  63.     mov  [track_len],eax
  64.     dps  'TRK'
  65. next_event:
  66.     call readvar
  67. ;    dpd  eax
  68.     add  [delta],eax
  69.     lodsw             ; al -event, ah - next byte
  70. if SYS eq meos1
  71.     dph  eax
  72.     dps  <' ',13,10>
  73.     newline
  74. end if
  75.     test al,0x80      ; check if a valid event
  76.     jnz  .valid_evt2
  77.     dec  esi
  78.     shl  ax,8
  79.     mov  al,[prev_cmd]
  80.     jmp  .valid_evt
  81.   .valid_evt2:
  82.     mov  [prev_cmd],al
  83.   .valid_evt:
  84.     cmp  al,0xf0
  85.     jne  .nosysex
  86.     dec  esi
  87.     call readvar
  88.     add  esi,eax
  89.     jmp  next_event
  90.   .nosysex:
  91.     cmp  al,0xff
  92.     jne  .no_meta
  93.  
  94.   ; meta events
  95.     cmp  ah,0x51
  96.     jne  .notempo
  97.     push eax edx
  98.     mov  eax,[esi]
  99.     xor  al,al
  100.     bswap eax
  101.     xor  edx,edx
  102.     mov  ebx,10000
  103.     div  ebx
  104.     pop  edx eax
  105.     jmp  .no_eot
  106.   .notempo:
  107.     cmp  ah,0x2f      ; end of track
  108.     jne  .no_eot
  109.     inc  esi
  110. if SYS eq meos1
  111.     dps  <13,10,'EOT'>
  112.     push esi
  113.     sub  esi,workarea
  114.     dpd  esi
  115.     pop  esi
  116. ;    mcall 5,200
  117. ;    dph  eax
  118. ;    ud2
  119. end if
  120.   .eot:
  121. ;    dps  'EOT '
  122.     inc  [cur_track]
  123.     jmp  skip_sections;decode_end
  124.   .no_eot:
  125.     lodsb
  126.     movzx ecx,al    ; ecx - length of metadata
  127.     add  esi,ecx
  128.     jmp  next_event
  129.   .no_meta:
  130.     cmp  al,0xfa    ; system ctl events
  131.     jb   .no_sys
  132.   .dec_esi:
  133.     dec  esi
  134.     jmp  next_event
  135.   .no_sys:
  136.     cmp  al,0xf8
  137.     je   .dec_esi
  138.     movzx ecx,al    ; ecx - MIDI Event Command
  139.     and  ecx,0xf    ; cl - channel
  140.     and  al,0xf0    ; al - event code
  141.  
  142.     cmp  al,0xe0    ; Pitch wheel change
  143.     je   .inc_esi
  144.     cmp  al,0xb0
  145.     ja   .no_inc
  146.   .inc_esi:
  147.     inc  esi
  148.   .no_inc:
  149.     cmp  ecx,[channel]     ; Channel must be 0 !!!
  150.     jz   .chan_ok
  151.  if NONCRITICAL_MSG eq 1
  152.     dps  'C'         ; Reference to unsupported channel !!!
  153.     dpd  ecx
  154.     mov  ecx,esi
  155.     dps  '-'
  156.     sub  ecx,workarea+1
  157.     dpd  ecx
  158.  end if
  159.     jmp  next_event
  160.   .chan_ok:
  161.     cmp  al,0x90     ; Note On
  162.     jne  .no_noon
  163.     add  al,[octave]
  164.     cmp  [curnote],0x80
  165.     je   .note_ok
  166.  if NONCRITICAL_MSG eq 1
  167.     dps  'N!'        ; Note On without Off !!!
  168.  end if
  169.   .note_ok:
  170. ;    dps  'N+'
  171. ;    movzx  ecx,ah
  172. ;    dpd  ecx
  173.     call insert_pause
  174.     mov  [curnote],ah ; [curnote]=note number
  175.     jmp  next_event
  176.   .no_noon:
  177.     cmp  al,0x80     ; Note Off
  178.     jne  .no_nooff
  179.     add  ah,[octave]
  180.     cmp  ah,[curnote]
  181.     je   .off_ok
  182.  if NONCRITICAL_MSG eq 1
  183.     dps  'n!'        ; Note Off mismatch !!!
  184.  end if
  185.   .off_ok:
  186. ;    dps  'N-'
  187.     cmp  ah,[max_note]
  188.     jbe  .nomax
  189.     mov  [max_note],ah
  190.   .nomax:
  191.     cmp  ah,[min_note]
  192.     jae  .ins
  193.     mov  [min_note],ah
  194.   .ins:
  195.     call insert_note
  196.     mov  [curnote],al
  197.  
  198.   .no_nooff:         ; No more supported events
  199.     jmp  next_event
  200. prev_cmd db ?
  201. max_note db ?
  202. min_note db ?
  203. ;   *********************************************
  204. ;   *******  READ VARIABLE BYTES ****************
  205. ;   *********************************************
  206.  
  207. readvar:
  208. ; in:  esi - pointer;
  209. ; out: esi - new pointer; eax - value;
  210.     push ebx ecx
  211.     movzx ebx,byte[esi]
  212.     inc  esi
  213.     btr  ebx,7
  214.     jnc  .exit
  215.   .next:
  216.     shl  ebx,7
  217.     lodsb
  218.     mov  ecx,eax
  219.     and  eax,0x7f
  220.     add  ebx,eax
  221.     cmp  cl,0x7f
  222.     ja   .next
  223.   .exit:
  224.     mov  eax,ebx
  225.     pop  ecx ebx
  226.     ret
  227.  
  228. ;   *********************************************
  229. ;   *******  INSERT PAUSE ***********************
  230. ;   *********************************************
  231.  
  232. insert_pause:
  233.     cmp  [delta],0
  234.     jz  return
  235.     push eax ebx ecx
  236.     mov  ah,0xff
  237.     jmp  write_note
  238.  
  239. ;   *********************************************
  240. ;   *******  INSERT NOTE ************************
  241. ;   *********************************************
  242.  
  243. insert_note:    ; ah - note code
  244.     push eax ebx ecx
  245.     movzx eax,ah
  246.     mov  ebx,12
  247.     div  bl
  248.     shl  al,4
  249.     add  ah,al
  250.     sub  ah,0x1f
  251. write_note:
  252.     push eax
  253.     mov  eax,[delta]
  254.     mov  edx,[tempo]
  255.     mul  edx
  256.     mov  ecx,[quarter]
  257.     div  ecx    ; ax - note delay
  258.     cmp  eax,0x7f
  259.     jb   .ok
  260.     mov  eax,0x7f
  261.   .ok:
  262.     movzx ecx,al
  263.     or   ecx,0x80
  264.     pop  eax
  265.     mov  al,cl
  266.     stosw
  267.     xor  eax,eax
  268.     mov  [delta],eax
  269.     pop ecx ebx eax
  270. return:
  271.     ret
  272.  
  273. sHeadInv:
  274. if lang eq ru
  275.   db "Неверный заголовок",0
  276. else
  277.   db "Header invalid",0
  278. end if
  279.  
  280. sHSizeInv:
  281. if lang eq ru
  282.   db 'Неверный размер заголовка',0
  283. else
  284.   db 'Header size invalid',0
  285. end if
  286.  
  287. sTypeUnsup:
  288. if lang eq ru
  289.   db 'Тип MIDI не поддерживается',0
  290. else
  291.   db 'MIDI type not supported',0
  292. end if
  293.