46d9482bb0
git-svn-id: svn://kolibrios.org@9587 a494cfbc-eb01-0410-851d-a64ba20cac60
702 lines
16 KiB
NASM
702 lines
16 KiB
NASM
; AUTHORS:
|
|
; S. Kuzmin, A. Ershov, Madis Kalme 2005
|
|
; Sergey Efremenkov, Leency 2018
|
|
|
|
; CHECK OUT README.TXT!
|
|
|
|
format binary as ""
|
|
|
|
use32
|
|
org 0x0
|
|
db 'MENUET01' ; 8 byte id
|
|
dd 0x01 ; header version
|
|
dd START ; start of code
|
|
dd I_END ; size of image
|
|
dd 0x9000 ; memory for app
|
|
dd 0x9000 ; esp
|
|
dd fileinfo2.path ; I_Param , I_Icon
|
|
dd 0x0
|
|
|
|
include "mos_uzit.inc"
|
|
|
|
TAG1_X = 250 ; coordinates of ID3v1 block
|
|
TAG1_Y = 40
|
|
|
|
BLOCKS_TO_READ equ 2 ; must be greater than 1
|
|
BLOCK_SIZE equ 512 ;ñêîëüêî áàéò â áëîêå
|
|
|
|
START:
|
|
|
|
xor eax, eax
|
|
mov [last_err], eax
|
|
mov [fileinfo2+4], eax ; start block = 0
|
|
mov dword [fileinfo2+12], BLOCKS_TO_READ*BLOCK_SIZE
|
|
mcall 70, fileinfo2
|
|
|
|
result:
|
|
push eax ebx ;ïîëó÷àåì ðàçìåð ôàéëà â áàéòàõ
|
|
mcall 70, fileSizeInfo
|
|
|
|
cmp eax, 0
|
|
je @f
|
|
mov dword[size], 16384; ebx
|
|
jmp result.sizeEnd
|
|
@@:
|
|
mov eax, dword[fileBuf+32] ; íà ñàìîì äåëå òàì ðàçìåð 8 áàéò, à íå 4
|
|
mov dword[size], eax
|
|
.sizeEnd:
|
|
pop ebx eax
|
|
;mov dword [size], 16384; ebx
|
|
|
|
; checking ID3v2 tag
|
|
xor eax, eax
|
|
mov [tagv2], eax
|
|
mov eax, [mp3_file]
|
|
and eax, 0x00ffffff
|
|
cmp eax, 'ID3'
|
|
jnz .no_id3v2
|
|
mov eax, [mp3_file+3]
|
|
mov [tagv2], eax
|
|
|
|
mov ecx, 4
|
|
mov esi, mp3_file+6
|
|
xor eax, eax
|
|
xor ebx, ebx
|
|
cld
|
|
.size_read:
|
|
lodsb
|
|
shl ebx, 7
|
|
or ebx, eax
|
|
loop .size_read
|
|
add ebx, 10
|
|
mov eax, ebx
|
|
shr eax, 9
|
|
|
|
push eax edx
|
|
mov edx, BLOCK_SIZE
|
|
mul edx
|
|
mov dword[fileinfo2+4], eax ; start block
|
|
pop edx eax
|
|
|
|
shl eax, 9
|
|
|
|
mov ecx, ebx
|
|
add ecx, 3
|
|
|
|
sub ebx, eax
|
|
mov edi, ebx
|
|
add edi, mp3_file
|
|
dec edi
|
|
|
|
mcall 70, fileinfo2
|
|
|
|
jmp .loop
|
|
.no_id3v2:
|
|
|
|
mov ecx, 3
|
|
mov edi, mp3_file-1
|
|
.loop:
|
|
inc edi
|
|
inc ecx
|
|
cmp ecx, dword[size]
|
|
ja .no_frames
|
|
mov eax, [edi]
|
|
call Header_Check
|
|
test eax, eax
|
|
jz .header_found
|
|
cmp edi, mp3_file+BLOCKS_TO_READ*512-4
|
|
jb .loop
|
|
|
|
add dword [fileinfo2+4], (BLOCKS_TO_READ-1)*BLOCK_SIZE
|
|
|
|
mcall 70, fileinfo2
|
|
|
|
sub edi, (BLOCKS_TO_READ-1)*512
|
|
jmp .loop
|
|
|
|
.no_frames:
|
|
mov [last_err], err_bad_file
|
|
mov [last_err_l], err_bad_file_e - err_bad_file
|
|
jmp reading_end
|
|
|
|
.header_found:
|
|
mov eax, dword [edi]
|
|
sub ecx, 4
|
|
mov [header_at], ecx
|
|
|
|
|
|
call extract_bits
|
|
|
|
call decode_standard
|
|
|
|
call decode_layer
|
|
|
|
call decode_channels
|
|
|
|
call decode_samplerate
|
|
|
|
call decode_bitrate
|
|
|
|
call calculate_time_frame_count
|
|
|
|
;--------------------------------------------
|
|
|
|
mov eax, [b1s]
|
|
and eax, 1
|
|
shl eax, 1 ; eax = eax * 2
|
|
cmp byte [shan], 11b ; if mono
|
|
jz @f
|
|
inc eax
|
|
@@:
|
|
mov ebx, xing_offset
|
|
xlatb
|
|
|
|
add edi, eax
|
|
mov eax, [edi]
|
|
|
|
xor ebx, ebx
|
|
mov [xing_tag], ebx
|
|
cmp eax, 'Xing'
|
|
jnz .no_xing_tag
|
|
mov esi, edi
|
|
add esi, 15
|
|
std
|
|
mov edi, xing_bytes
|
|
mov ecx, 3*4
|
|
xor eax, eax
|
|
|
|
.xing_read:
|
|
lodsb
|
|
mov [edi], al
|
|
inc edi
|
|
loop .xing_read
|
|
cld
|
|
mov ebx, [xing_tag]
|
|
test ebx, 1
|
|
jz .frames_end
|
|
mov eax, [xing_frames]
|
|
mov [framecount], eax
|
|
test [b1s], 1 ; if MPEG 1 eax = eax*2
|
|
jz @f
|
|
shl eax, 1
|
|
@@:
|
|
mov ebx, 575
|
|
mul ebx ; edx:eax = eax*575
|
|
mov ebx, [SR]
|
|
div ebx ; eax = edx:eax / sample rate
|
|
|
|
mov [time], eax
|
|
|
|
; calculating bitrate
|
|
xor edx, edx
|
|
mov ebx, 1000 / 8
|
|
mul ebx ; edx:eax = time * 1000
|
|
mov ebx, eax
|
|
mov eax, [xing_bytes]
|
|
div ebx ; eax = size / time*1000
|
|
mov [BR], eax
|
|
|
|
|
|
.frames_end:
|
|
|
|
|
|
.no_xing_tag:
|
|
|
|
xor eax, eax
|
|
xor ebx, ebx
|
|
xor ecx, ecx
|
|
xor edx, edx
|
|
; ID3v1 tag reading
|
|
mov eax, [size] ; reading 2 last 512-byte blocks where our
|
|
mov ebx, eax ; tag may be
|
|
shr eax, 9 ; eax = size of file in full 512-byte blocks
|
|
test eax, eax ; if file's length is less then 512 we'll
|
|
jz @f ; read the whole file
|
|
dec eax
|
|
@@:
|
|
push eax edx
|
|
mov edx, BLOCK_SIZE
|
|
mul edx
|
|
mov dword [fileinfo2+4], eax ; start block
|
|
pop edx eax
|
|
mov dword [fileinfo2+12], 2*BLOCK_SIZE ; blocks to read
|
|
|
|
shl eax, 9
|
|
sub ebx, eax
|
|
add ebx, mp3_file - 128 ; if tag is present, ebx points to it
|
|
mov esi, ebx
|
|
|
|
xor eax, eax
|
|
mov [tag], eax
|
|
|
|
|
|
mcall 70, fileinfo2
|
|
|
|
mov eax, [esi] ; checking if tag is present
|
|
and eax, 0x00ffffff
|
|
cmp eax, 'TAG'
|
|
jnz @f
|
|
inc [tag]
|
|
cld
|
|
mov ecx, 128 / 4
|
|
mov edi, tag.data
|
|
rep movsd
|
|
mov esi, tag.data
|
|
mov ecx, 126
|
|
call Win2Dos
|
|
@@:
|
|
reading_end:
|
|
call draw_window ; 14.08.05 [
|
|
|
|
|
|
; Öèêë ïîëó÷åíèÿ è îáðàáîòêè ñîîáùåíèé
|
|
get_event:
|
|
mov eax,10
|
|
int 0x40
|
|
dec eax
|
|
jnz @f
|
|
call draw_window
|
|
jmp get_event
|
|
@@:
|
|
dec eax
|
|
jz key_on_keyboard
|
|
dec eax
|
|
jz click_on_button
|
|
jmp get_event
|
|
|
|
key_on_keyboard:
|
|
mcall 2
|
|
jmp get_event
|
|
|
|
click_on_button:
|
|
exit:
|
|
mcall 17
|
|
;cmp ah, 10
|
|
;jz other_file
|
|
|
|
mov eax,-1
|
|
int 0x40
|
|
|
|
jmp get_event ; ] 14.08.05
|
|
|
|
; Ðèñîâàíèå îêíà
|
|
draw_window:
|
|
mcall 12,1
|
|
mov eax,0 ; function 0 : define and draw window
|
|
mov ebx,250 shl 16 + 500
|
|
mov ecx,250 shl 16 + 300
|
|
mov edx,0x34aabbcc ; color of work area RRGGBB,8->color gl
|
|
mov edi, header
|
|
int 0x40
|
|
|
|
Text 20,12,0x00000000,choice, choicelen-choice
|
|
Text 110,12,0x00000000,fileinfo2.path, 60
|
|
|
|
mov edx, dword [last_err]
|
|
test edx, edx
|
|
jz .no_err
|
|
mov eax, 4
|
|
mov ebx, 50*65536+50
|
|
xor ecx, ecx
|
|
mov esi, [last_err_l]
|
|
int 0x40
|
|
jmp draw_end
|
|
.no_err:
|
|
|
|
Text 20,40,0x00000000,S, Slen-S
|
|
Number 110,40,1*256,1,dword [S1],0x000000;
|
|
Number 122,40,1*256,1,dword [S2],0x000000;
|
|
|
|
Text 20,60,0x00000000,L, Llen-L
|
|
Number 110,60,1*256,1,dword [La],0x000000
|
|
|
|
Text 20,100,0x00000000,SamR, SamRlen-SamR
|
|
Number 110,100,0*256,5,dword [SR],0x000000
|
|
|
|
Text 20,120,0x00000000,BitR, BitRlen-BitR
|
|
Number 110,120,0*256,3,dword [BR],0x000000
|
|
|
|
mov eax, [xing_tag]
|
|
test eax, eax
|
|
jz @f
|
|
Text 170,120,0x00000000,vbr, vbr_e - vbr
|
|
@@:
|
|
|
|
Text 20,140,0x00000000,Sizebyte, Sizebytelen-Sizebyte
|
|
Number 110,140,0*256,8,dword [size],0x000000
|
|
|
|
Text 20,160,0x00000000,Timese, Timeselen-Timese
|
|
Number 110,160,0*256,4,dword [time],0x000000
|
|
|
|
Text 20,180,0x00000000,frame, framelen-frame
|
|
Number 110,180,0*256,4,dword [frames],0x000000
|
|
|
|
Text 20,200,0x00000000,framcount, framcountlen-framcount
|
|
|
|
Text 20,220,0x00000000,padding, paddinglen-padding
|
|
|
|
cmp [pad], 1
|
|
je res1
|
|
jne res2
|
|
|
|
res1:
|
|
Text 75,220,0x00000000,da, dalen-da
|
|
jmp nex
|
|
res2:
|
|
Text 75,220,0x00000000,net, netlen-net
|
|
jmp nex
|
|
|
|
nex:
|
|
|
|
; ------------------
|
|
|
|
|
|
Text 110,220,0x00000000,crci, crcilen-crci
|
|
|
|
cmp [crc], 0
|
|
je res3
|
|
jne res4
|
|
|
|
res3:
|
|
Text 160,220,0x00000000,da, dalen-da
|
|
jmp ne
|
|
res4:
|
|
Text 160,220,0x00000000,net, netlen-net
|
|
jmp ne
|
|
|
|
ne:
|
|
|
|
;--------------------------
|
|
|
|
Number 110,200,0*256,6,dword [framecount],0x000000
|
|
|
|
|
|
Text 20,80,0x00000000,Ka, Kalen-Ka
|
|
|
|
cmp [K], 1
|
|
je rez1
|
|
cmp [K], 2
|
|
je rez2
|
|
cmp [K], 3
|
|
je rez3
|
|
cmp [K], 4
|
|
je rez4
|
|
|
|
rez1:
|
|
Text 110,80,0x00000000,SC, SClen-SC
|
|
jmp next
|
|
rez2:
|
|
Text 110,80,0x00000000,DC, DClen-DC
|
|
jmp next
|
|
rez3:
|
|
Text 110,80,0x00000000,JOS, JOSlen-JOS
|
|
jmp next
|
|
rez4:
|
|
Text 110,80,0x00000000,Su, Sulen-Su
|
|
|
|
next:
|
|
Text 20,240,0,header_found, header_found_e - header_found
|
|
Number 160,240,0*256,6,dword [header_at],0x000000 ;;;;;;; HEADER AT
|
|
|
|
|
|
|
|
; ID3v2
|
|
|
|
mcall 4, 250*65536+220, 0,id3v2, id3v2_e - id3v2
|
|
mov edi, tagv2
|
|
mov eax, [edi]
|
|
test eax, eax
|
|
jz .no_v2
|
|
mcall 4, 281*65536+220, ,dots, dots_e - dots
|
|
xor ecx, ecx
|
|
mov cl, byte [edi]
|
|
mcall 47, 65536*2, , 286*65536+220, 0
|
|
mov cl, byte [edi+1]
|
|
mcall , , , 304*65536+220,
|
|
|
|
jmp .v2_end
|
|
.no_v2:
|
|
Text 300,220,0,net, netlen- net
|
|
.v2_end:
|
|
|
|
|
|
|
|
; ID3v1 info
|
|
; Writing all field names
|
|
mov eax, 4 ; function 4
|
|
words2reg ebx, TAG1_X, TAG1_Y
|
|
xor ecx, ecx ; color
|
|
mov edx, id3v1
|
|
mov esi, id3v1_e - id3v1
|
|
int 0x40
|
|
|
|
add ebx, 40
|
|
mov edx, title ; length is the same, so we don't write it in esi
|
|
int 0x40
|
|
|
|
add ebx, 20
|
|
mov edx, artist
|
|
inc esi
|
|
int 0x40
|
|
|
|
add ebx, 20
|
|
mov edx, album
|
|
dec esi
|
|
int 0x40
|
|
|
|
add ebx, 20
|
|
mov edx, year
|
|
dec esi
|
|
int 0x40
|
|
|
|
add ebx, 20
|
|
mov edx, genre
|
|
inc esi
|
|
int 0x40
|
|
|
|
add ebx, 20
|
|
mov edx, comment
|
|
inc esi
|
|
inc esi
|
|
int 0x40
|
|
|
|
sub ebx, 120
|
|
mov edx, track
|
|
int 0x40
|
|
|
|
; checking if tag is
|
|
mov eax, dword [tag]
|
|
test eax, eax
|
|
jz .no_tag1
|
|
|
|
mov edi, tag.data
|
|
|
|
; writing walues
|
|
words2reg edx, (TAG1_X+50), (TAG1_Y+20)
|
|
|
|
; track number uses the 30-th byte of comment field
|
|
; it may be the last char in comment field
|
|
; so we check if this byte presents a track number
|
|
mov eax, [edi+125]
|
|
test al, al
|
|
jnz .no_track
|
|
test ah, ah
|
|
jz .no_track
|
|
|
|
mov ebx, 3*65536
|
|
xor ecx, ecx
|
|
mov cl, ah
|
|
xor esi, esi
|
|
mov eax, 47
|
|
int 0x40
|
|
|
|
.no_track:
|
|
mov ebx, edx
|
|
mov edx, edi
|
|
mov eax, 4 ; function 4
|
|
xor ecx, ecx ; color
|
|
|
|
add ebx, 20
|
|
add edx, 3
|
|
mov esi, 30
|
|
int 0x40 ; title
|
|
|
|
add ebx, 20
|
|
add edx, esi
|
|
int 0x40 ; artist
|
|
|
|
add ebx, 20
|
|
add edx, esi
|
|
int 0x40 ; album
|
|
|
|
add ebx, 60
|
|
add edx, 34
|
|
dec esi
|
|
int 0x40 ; comment
|
|
|
|
sub ebx, 40
|
|
mov esi, 4
|
|
sub edx, esi
|
|
int 0x40 ; year
|
|
|
|
.no_tag1:
|
|
draw_end:
|
|
mcall 12, 2
|
|
ret ; (!) 14.08.05
|
|
|
|
freq dd 11025, 12000, 8000
|
|
Bitrate db 0,1,2, 3, 4, 5, 6, 7, 8,10,12,14,16,18,20,0,\ ; v2 l2 l3
|
|
0,1,2, 3, 4, 5, 6, 7, 8,10,12,14,16,18,20,0,\ ; v2 l2 l3
|
|
0,4,6, 7, 8,10,12,14,16,18,20,22,24,28,32,0,\ ; v2 l1
|
|
0,4,5, 6, 7, 8,10,12,14,16,20,24,28,32,40,0,\ ; v1 l3
|
|
0,4,6, 7, 8,10,12,14,16,20,24,28,32,40,48,0,\ ; v1 l2
|
|
0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,0 ; v1 l1
|
|
xing_offset db 13, 21, 21, 36
|
|
header:
|
|
db 'MP3 Info 0.7',0
|
|
|
|
S:
|
|
db 'MPEG Version: . '
|
|
Slen:
|
|
|
|
L:
|
|
db 'Layer: '
|
|
Llen:
|
|
|
|
Ka:
|
|
db 'Channels Mode: '
|
|
Kalen:
|
|
|
|
Su:
|
|
db 'Stereo'
|
|
Sulen:
|
|
|
|
JOS:
|
|
db 'Joint stereo '
|
|
JOSlen:
|
|
|
|
DC:
|
|
db 'Dual channel'
|
|
DClen:
|
|
|
|
SC:
|
|
db 'Single Channel (Mono)'
|
|
SClen:
|
|
|
|
SamR:
|
|
db 'Sample Rate: Hz'
|
|
SamRlen:
|
|
|
|
BitR:
|
|
db 'BitRate: Kbps'
|
|
BitRlen:
|
|
|
|
Sizebyte:
|
|
db 'Size: bytes'
|
|
Sizebytelen:
|
|
|
|
Timese:
|
|
db 'Time: seconds'
|
|
Timeselen:
|
|
|
|
frame:
|
|
db 'Frame size: bytes'
|
|
framelen:
|
|
|
|
framcount:
|
|
db 'Quantity: frames'
|
|
framcountlen:
|
|
|
|
padding:
|
|
db 'Padding:'
|
|
paddinglen:
|
|
|
|
crci:
|
|
db 'CRC:'
|
|
crcilen:
|
|
|
|
da:
|
|
db 'yes'
|
|
dalen:
|
|
|
|
net:
|
|
db 'no'
|
|
netlen:
|
|
dots db '. .'
|
|
dots_e:
|
|
|
|
header_found db 'Header found at:'
|
|
header_found_e:
|
|
|
|
choice:
|
|
db 'File path: '
|
|
choicelen:
|
|
id3v2 db 'ID3v2'
|
|
id3v2_e:
|
|
vbr db '(VBR)'
|
|
vbr_e:
|
|
id3v1 db 'ID3v1'
|
|
id3v1_e:
|
|
track db 'Track #'
|
|
track_e:
|
|
title db 'Title'
|
|
title_e:
|
|
artist db 'Artist'
|
|
artist_e:
|
|
album db 'Album'
|
|
album_e:
|
|
year db 'Year'
|
|
year_e:
|
|
genre db 'Genre'
|
|
genre_e:
|
|
comment db 'Comment'
|
|
comment_e:
|
|
|
|
err_bad_file db 'Bad file'
|
|
err_bad_file_e:
|
|
|
|
fileinfo2:
|
|
.func dd 0 ;íîìåð ïîäôóíêöèè
|
|
.start dd 0*BLOCK_SIZE ;ïîçèöèÿ â ôàéëå (â áàéòàõ) *512
|
|
dd 0 ;(çàðåçåðâèðîâàíî ïîä ñòàðøèé dword ïîçèöèè)
|
|
.size dd 1*BLOCK_SIZE ;ñêîëüêî áàéò ÷èòàòü
|
|
.buf dd mp3_file ;óêàçàòåëü íà áóôåð, êóäà áóäóò çàïèñàíû äàííûå
|
|
.path:
|
|
db "TEST.MP3",0 ;"/SYS/TEST.MP3",0
|
|
rb 256-($-.path)
|
|
|
|
|
|
;äëÿ ïîëó÷åíèÿ êîððåêòíîãî ðàçìåðà ôàéëà
|
|
fileSizeInfo:
|
|
dd 5 ; íîìåð ïîäôóíêöèè
|
|
dd 0,0,0 ;(çàðåçåðâèðîâàíî)
|
|
dd fileBuf ;óêàçàòåëü íà áóôåð, êóäà áóäóò çàïèñàíû äàííûå(40 áàéò)
|
|
db 0
|
|
dd fileinfo2.path
|
|
|
|
fileBuf: db 40 dup(0)
|
|
|
|
|
|
;=================================================
|
|
b1s dd ? ; standard
|
|
b1l dd ? ; layer
|
|
S1 dd ?
|
|
S2 dd ?
|
|
La dd ?
|
|
shan dd ?
|
|
K dd ?
|
|
sam dd ?
|
|
id dd ?
|
|
SR dd ?
|
|
Bita dd ?
|
|
BR dd ?
|
|
size dd ?
|
|
time dd ?
|
|
frames dd ?
|
|
|
|
xing_bytes dd ?
|
|
xing_frames dd ?
|
|
xing_tag dd ?
|
|
|
|
tagv2 dd ?
|
|
tag dd ?
|
|
.data rb 128
|
|
framecount dd ?
|
|
pad dd ?
|
|
priv dd ?
|
|
modx dd ?
|
|
copy dd ?
|
|
orig dd ?
|
|
emph dd ?
|
|
crc dd ?
|
|
header_at dd ?
|
|
last_err dd ?
|
|
last_err_l dd ?
|
|
|
|
|
|
I_END:
|
|
|
|
;label pre_file dword at 0x3000-4
|
|
label mp3_file dword at 0x3000
|
|
|