Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
134 diamond 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