;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; 64 bit Menuet audio example ; ; Compile with FASM 1.60 or above ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; use64 org 0x0 db 'MENUET64' ; Header identifier dq 0x01 ; Version dq START ; Start of code dq image_end ; Size of image dq 0x600000 ; Memory for app dq 0x0ffff0 ; Rsp dq 0x00 ; Prm dq 0x00 ; Icon ; All drivers support playback and record with 48khz,16bit,stereo,16kB/buff ; ; Latency: 85.33msec @ 48 khz, 16-bit stereo, 16384 bytes/buffer ; 0.67msec @ 48 khz, 16-bit stereo, 128 bytes/buffer ; 0.08msec @ 192 khz, 24-bit stereo, 96 bytes/buffer wavelocation equ 0x100000 wavelocation24 equ 0x200000 START: mov rax , 141 ; Enable system font mov rbx , 1 mov rcx , 1 mov rdx , 5 shl 32 + 5 mov r8 , 9 shl 32 + 12 int 0x60 mov rax , 117 ; Audio card available? mov rbx , 1 int 0x60 cmp rax , 0 jne noavail mov [available],byte 1 noavail: call draw_window ; At first, draw the window call calculate_audiowave still: mov rax , 23 ; Wait here for event mov rbx , 1 int 0x60 test rax , 0x1 ; Window redraw jnz window_event test rax , 0x2 ; Keyboard press jnz key_event test rax , 0x4 ; Button press jnz button_event call check_mouse ; Check mouse jmp still window_event: call draw_window jmp still key_event: mov rax , 0x2 ; Read the key and ignore int 0x60 jmp still playaudio: ; Device available cmp [available],dword 1 je device_available mov rax , 4 mov rbx , unsupported mov rcx , 48 mov rdx , 123 mov r9 , 1 mov rsi , 0x000000 int 0x60 mov rax , 23 mov rbx , 125 int 0x60 mov rax , 4 mov rbx , unsupported mov rcx , 48 mov rdx , 123 mov r9 , 1 mov rsi , 0xffffff int 0x60 ret device_available: ; Default setup 0 supported by all drivers ; (48000hz,16bit/ch,stereo,signed,16384bytes/buff) mov rax , 4 mov rbx , playing mov rcx , 72 mov rdx , 123 mov r9 , 1 mov rsi , 0x000000 int 0x60 ; Clear buffers mov rdi , 0x180000 mov rcx , 65536 mov rax , 0 cld rep stosb mov rax , 117 mov rbx , 2 mov rcx , 0x180000 mov rdx , 0 int 0x60 mov rax , 117 mov rbx , 2 mov rcx , 0x180000 mov rdx , 1 int 0x60 ; Start playback mov r14 , 0 ; current playbuffer mov r15 , [wavestart] ; 16bit/24bit wave ; Play command mov rax , 117 mov rbx , 3 int 0x60 waitmore: ; Get current playbuffer (0/1) mov rax , 117 mov rbx , 4 int 0x60 cmp rbx , r14 jne nowantedblock ; Give data for nonactive playbuffer (0/1) mov rax , 117 mov rbx , 2 mov rcx , r15 ; wave position mov rdx , r14 ; playbuffer add rdx , 1 and rdx , 1 int 0x60 add r15 , [buffersize] add r14 , 1 and r14 , 1 nowantedblock: cmp r15 , [waveend] ja audiodone cmp [buffertime],dword 1000 ; below ms buffer jb nodelay mov rax , 105 mov rbx , 1 int 0x60 nodelay: mov rax , 11 int 0x60 cmp rax , 0 je waitmore audiodone: ; Stop playing at button press mov rax , 117 mov rbx , 5 int 0x60 ; Clear playing text mov rax , 4 mov rbx , playing mov rcx , 72 mov rdx , 123 mov r9 , 1 mov rsi , 0xffffff int 0x60 ret calculate_audiowave: ; Get sine to memory mov rcx , 0 newsine: mov rax , 122 mov rbx , 6 int 0x60 mov [sine+rcx*8],rbx add rcx , 1 cmp rcx , 3600 jb newsine ; Calculate example audiowave mov r14 , 0 ; frequency location mov r15 , wavelocation ; wave location newwave: mov rcx , 0 mov rdi , 0 setwave: push rcx shr rcx , 16 mov rbx , [sine+rcx*8] pop rcx shr rbx , 2 mov [r15+rdi+0],bx mov [r15+rdi+2],bx mov rdx , ((3600*65536)/(16384/4)) movzx rax , byte [freq+r14] imul rdx , rax add rcx , rdx add rdi , 4 cmp rcx , 3600*65536 jb norcx sub rcx , 3600*65536 norcx: cmp rdi , 16384*2 jb setwave add r15 , 16384*2 add r14 , 1 cmp r14 , 11 jbe newwave ; 16bit -> 24bit mov rsi , wavelocation mov rdi , wavelocation24 new32: xor rax , rax mov ax , [rsi] shl rax , 8 mov [rdi],eax mov [rdi+3],eax mov [rdi+6],eax mov [rdi+9],eax add rsi , 2 add rdi , 12 cmp rsi , wavelocation + 16384*11*2 jb new32 ret check_mouse: ; Select audioformat from list mov rax , 37 mov rbx , 2 int 0x60 cmp rax , 0 je nomousedown mov rax , 37 mov rbx , 1 int 0x60 mov rbx , rax shr rax , 32 cmp rax , 22 jb nomousedown cmp rax , 155 ja nomousedown and rbx , 0xffff sub rbx , 109-42 mov rax , rbx mov rbx , 12 xor rdx , rdx div rbx cmp rax , 4 jae nomousedown add rax , [vscroll_value] sub rax , 300 cmp rax , [formats] jae nomousedown mov [selected],rax call draw_audio_info call set_audio_parameters waitmouseup: mov rax , 5 mov rbx , 1 int 0x60 mov rax , 37 mov rbx , 2 int 0x60 cmp rax , 0 jne waitmouseup nomousedown: ret set_audio_parameters: ; Get buffersize for selected setup mov rax , 117 mov rbx , 7 mov rcx , [selected] int 0x60 mov rax , rbx shr rax , 32+16 mov [buffersize],rax ; Calculate buffer time duration in microseconds mov r8 , rbx and r8 , 0xfffff ; freq mov r9 , rbx shr r9 , 32 and r9 , 0xff ; channels mov r10 , rbx shr r10 , 24 and r10 , 0xff ; bytes / sample shr r10 , 3 imul r8 , r9 imul r8 , r10 imul r8 , 10 mov rax , [buffersize] imul rax , 100000000 xor rdx , rdx mov rbx , r8 div rbx add rax , 5 ; roundup xor rdx , rdx mov rbx , 10 div rbx mov [buffertime],rax ; Use 16bit/24bit wave for playback mov [wavestart],dword wavelocation mov [waveend],dword wavelocation+20*16384*1 cmp r10 , 2 je wave16bit mov [wavestart],dword wavelocation24 mov [waveend],dword wavelocation24+20*16384*8 wave16bit: ; And select setup at card mov rax , 117 mov rbx , 8 mov rcx , [selected] int 0x60 ret button_event: mov rax , 0x11 int 0x60 ; rax = status ; rbx = button id cmp rbx , 1 ; Play audio jne no_play call playaudio jmp still no_play: cmp rbx , 300 ; Vertical scroll jb no_vertical_scroll cmp rbx , 399 ja no_vertical_scroll mov [vscroll_value], rbx call draw_audio_info jmp still no_vertical_scroll: cmp rbx , 0x10000001 ; Close button je terminate cmp rbx , 0x104 ; Close menu selection je terminate jmp noterm terminate: mov rax , 512 int 0x60 noterm: jmp still draw_window: mov rax , 0xC ; Beginning of window draw mov rbx , 0x1 int 0x60 mov rax , 0x0 ; Draw window mov rbx , 0x0000010000000000 + 193 ; x start & size mov rcx , 0x0000008000000000 + 180 ; y start & size mov rdx , 0x0000000000FFFFFF ; type & border color mov r8 , 0x0000000000000001 ; draw flags mov r9 , window_label ; 0 or label - asciiz mov r10 , menu_struct ; 0 or pointer to menu struct int 0x60 mov rax , 8 mov rbx , 20 * 0x100000000 + 70 mov rcx , 135* 0x100000000 + 20 mov rdx , 1 mov r8 , 0 mov r9 , button1 int 0x60 mov rax , 8 mov rbx , 100* 0x100000000 + 70 mov rcx , 135* 0x100000000 + 20 mov rdx , 2 mov r8 , 0 mov r9 , button2 int 0x60 call draw_audio_info mov rax , 0xC mov rbx , 0x2 int 0x60 ret draw_audio_info: ; Display audio-format list mov rax , 38 mov rbx , 21 mov rcx , 109-42 mov rdx , 169 mov r8 , 161-42 mov r9 , 0xa0a0a0 push r8 mov r8 , rcx int 0x60 pop r8 push rcx mov rcx , r8 int 0x60 pop rcx push rdx mov rdx , rbx int 0x60 pop rdx add rbx , 1 add rcx , 1 sub rdx , rbx sub r8 , rcx shl rbx , 32 add rbx , rdx sub rbx , 13 shl rcx , 32 add rcx , r8 mov rax , 13 mov rdx , 0xffffff int 0x60 mov rax , 4 mov rbx , string_info mov rcx , 23 mov rdx , 93-42 mov r9 , 1 mov rsi , 0x000000 int 0x60 mov r15 , [vscroll_value] sub r15 , 300 mov rax , 117 mov rbx , 7 mov rcx , r15 int 0x60 cmp rax , 0 jne done mov r13 , 0 mov [formats],r15 newsetup: ; mov rax , 117 mov rbx , 7 mov rcx , r15 int 0x60 cmp rax , 0 jne done ; add [formats],dword 1 ; cmp r13 , 4 jae nodisplay ; mov [curx],dword 0 mov rax , rbx and rax , 0xffffff call addtext mov rax , rbx shr rax , 24 and rax , 0xff call addtext mov rax , rbx shr rax , 32 and rax , 0xff call addtext ;mov rax , rbx ;shr rax , 40 ;and rax , 0xf ;call addtext mov rax , rbx shr rax , 44 and rax , 0x1f mov cl , al mov rax , 10b shl rax , cl call addtext mov rax , rbx shr rax , 48 call addtext mov rax , [curx] mov [text+rax-1],byte 0 ; mov rax , 13 mov rbx , 24 shl 32 + 6*22 mov rcx , r13 imul rcx , 12 add rcx , 110-42 shl rcx , 32 add rcx , 12 mov rdx , 0xd0d0d0 mov r10 , r13 add r10 , [vscroll_value] sub r10 , 300 cmp r10 , [selected] je yessel mov rdx , 0xffffff yessel: int 0x60 mov rax , 4 mov rbx , text mov rcx , 25 mov rdx , r13 imul rdx , 12 add rdx , 112-42 mov r9 , 1 mov rsi , 0x000000 int 0x60 ; nodisplay: ; add r15 , 1 add r13 , 1 ; jmp newsetup done: call draw_vertical_scroll ret addtext: ; Add parameters to audioformat line push rbx mov rdi , number+10 newaddt: mov rbx , 10 xor rdx , rdx div rbx add dl , 48 mov [rdi],dl sub rdi , 1 cmp rax , 0 jne newaddt mov rcx , number+10 sub rcx , rdi mov rsi , rdi add rsi , 1 mov rdi , [curx] add rdi , text add [curx],rcx cld rep movsb mov rax , [curx] mov [text+rax],byte ',' add [curx],dword 1 pop rbx ret draw_vertical_scroll: ; Vertical scroll mov rax , 113 mov rbx , 1 mov rcx , 300 mov rdx , [formats] mov r8 , [vscroll_value] mov r9 , 157 mov r10 , 110-42 mov r11 , 50 int 0x60 ret ; ; Data area ; window_label: db 'AUDIO EXAMPLE',0 button1: db 'PLAY',0 button2: db 'STOP',0 unsupported: db 'Card unavailable.',0 playing: db 'Playing..',0 cardhz: dq 0x0 multiplier: dq 0x0 blockwait: dq 0x0 available: dq 0x0 buffertime: dq 0x0 wavestart: dq wavelocation waveend: dq wavelocation+20*16384*1 freq: db 27,30,34,36,40,45,51,54,54,54,54,54,54,54 text: db ' ',0 number: db ' ',0 curx: dq 0x0 formats: dq 0x0 buffersize: dq 16384 ; for default setup 0 selected: dq 0x0 ; selected setup string_info: db 'Formats:',0 ; hz,bits,chs,bufs,bufsize vscroll_value: dq 300 menu_struct: ; Menu Struct dq 0 ; Version dq 0x100 ; Start value of ID to return ( ID + Line ) ; Returned when menu closes and ; user made no selections. db 0,'FILE',0 ; ID = 0x100 + 1 db 1,'Open..',0 db 1,'-',0 db 1,'Quit',0 ; ID = 0x100 + 2 db 255 ; End of Menu Struct sine: times 3600 dq ? image_end: