diff --git a/cimp.bas b/cimp.bas index 067ba3f..2a7a6e8 100644 --- a/cimp.bas +++ b/cimp.bas @@ -4,7 +4,7 @@ declare library"terminkey" sub echoon() function termwidth() function ipc_init&() - function ipc_check_message%(byval buf as _offset,byval max_len as long) + function ipc_check_message%(byval buf as _offset, byval max_len as long) sub ipc_send_message(buf as string) sub ipc_cleanup() end declare @@ -25,93 +25,89 @@ $end if redim file(0) as string chdir _startdir$ if command$=""then -print"please specify file to play." -goto quit + print"please specify file to play." + goto quit end if dim ipc_status as long -ipc_status=ipc_init +ipc_status = ipc_init -if ipc_status=0 then +if ipc_status = 0 then ' --- CLIENT MODE --- dim cmd_msg as string - - select case command$(1) - case "--soundbank" - cmd_msg="SOUNDBANK:"+_cwd$ +slash+command$(2) - case "--next" - cmd_msg="NEXT" - - case "--prev" - cmd_msg="PREV" - - case "-v","--volume" - cmd_msg="VOL:"+command$(2) + + Select Case command$(1) + Case "--soundbank" + cmd_msg = "SOUNDBANK:" + _cwd$ + slash + command$(2) + Case "--next" + cmd_msg = "NEXT" + + Case "--prev" + cmd_msg = "PREV" + + Case "-v", "--volume" + cmd_msg = "VOL:" + command$(2) case "--pause" - cmd_msg="PAUSE" + cmd_msg = "PAUSE" case "--stop" - cmd_msg="STOP" + cmd_msg = "STOP" case "--play" - cmd_msg="PLAY" + cmd_msg = "PLAY" case "--quit" - cmd_msg="QUIT" + cmd_msg = "QUIT" case "--shuffle" - cmd_msg="SHUFFLE" + cmd_msg = "SHUFFLE" case "--repeat" - cmd_msg="REPEAT" + cmd_msg = "REPEAT" case "--repeat-1" - cmd_msg="REPEAT1" - case "--repeat-off" - cmd_msg="REPEATOFF" + cmd_msg = "REPEAT1" case "--nyan" - cmd_msg="NYAN" - case "--nyan-off" - cmd_msg="NYANOFF" - case "--add" - for i=2 to _commandcount - cmd_msg="ADD:"+_cwd$ +slash+command$(i) + cmd_msg = "NYAN" + Case "--add" + For i = 2 To _commandcount + cmd_msg = "ADD:" + _cwd$ + slash + command$(i) ipc_send_message cmd_msg - next i - system - - case "--playlist" - cmd_msg="GET_PLAYLIST" - - case else + Next i + System + + Case "--playlist" + cmd_msg = "GET_PLAYLIST" + + Case Else ' Default behavior: Resolve target file/playlist and replace active queue - cmd_msg="PLAY:"+_cwd$ +slash+command$(1) + cmd_msg = "PLAY:" + _cwd$ + slash + command$(1) ipc_send_message cmd_msg - if _commandcount>1 then - for i=2 to _commandcount - cmd_msg="ADD:"+_cwd$ +slash+command$(i) + If _commandcount > 1 Then + For i = 2 To _commandcount + cmd_msg = "ADD:" + _cwd$ + slash + command$(i) ipc_send_message cmd_msg - next i - system - end if - end select - + Next i + System + End If + End Select + ' Send instruction to the main player instance ipc_send_message cmd_msg - + ' --- Two-way Client feedback for --playlist --- - if cmd_msg="GET_PLAYLIST" then + if cmd_msg = "GET_PLAYLIST" then ipc_cleanup _delay 0.1 - + dim client_listen as long - client_listen=ipc_init - if client_listen=1 then + client_listen = ipc_init + if client_listen = 1 then dim reply_buf as string - reply_buf=space$(4096)+chr$(0) + reply_buf = space$(4096) + chr$(0) dim start_wait as double - start_wait=timer - - do while timer-start_wait<2 + start_wait = timer + + do while timer - start_wait < 2 dim reply_len as long - reply_len=ipc_check_message(_offset(reply_buf),4096) - if reply_len>0 then - print left$(reply_buf,reply_len) + reply_len = ipc_check_message(_offset(reply_buf), 4096) + if reply_len > 0 then + print left$(reply_buf, reply_len) exit do end if _limit 30 @@ -119,9 +115,9 @@ if ipc_status=0 then ipc_cleanup end if end if - + system ' Exit client instance completely -elseif ipc_status=-1 then +elseif ipc_status = -1 then print "Error initializing Inter-Process Communication." goto quit end if @@ -137,8 +133,6 @@ dim shuffle as integer dim nooutput as integer dim timevis as integer dim nyan as integer -dim server as integer - dim marqueeoffset as integer dim i as integer @@ -173,40 +167,6 @@ timevis=1 nyan=0 marqueeoffset=0 - -dim config as string -config=GetConfig("cimp.conf") -if _fileexists(config) then - dim li as string - dim fh as integer - fh=freefile - open config for input as fh - while not eof(fh) - line input #fh,li - if left$(li,1)="#" then _continue - select case _trim$(left$(li,instr(li,"=")-1)) - case "volume" - volume=val(_trim$(mid$(li,instr(li,"=")+1)))/100 - case "shuffle" - if _trim$(mid$(li,instr(li,"=")+1))="true" then shuffle=-1 else shuffle=0 - case "repeat" - if _trim$(mid$(li,instr(li,"=")+1))="true" then repeat=-1 else repeat=0 - if _trim$(mid$(li,instr(li,"=")+1))="1" then repeat=1 - case "server" - if _trim$(mid$(li,instr(li,"=")+1))="true" then server=-1 else server=0 - case "nyan" - if _trim$(mid$(li,instr(li,"=")+1))="true" then nyan=-1 else nyan=0 - case "nooutput" - if _trim$(mid$(li,instr(li,"=")+1))="true" then nooutput=-1 else nooutput=0 - case "" - case else - print "Config not understood:" - print li - end select - wend - close fh -end if - for i=1 to _commandcount select case command$(i) case "-v","--volume" @@ -216,31 +176,31 @@ for i=1 to _commandcount shuffle=-1 case "-r","--repeat" if command$(i+1)="1"then - repeat=1 - else - repeat=-1 - end if - case "-n","--nooutput" - nooutput=-1 - case "-N","--nyan" - nyan=-1 - case "-b","--soundbank" - if _commandcount>i and _fileexists(command$(i+1)) then - loadsoundbank command$(i+1) - else - print "error loading soundbank" - system - end if - case else - if _fileexists(command$(i)) then - if lcase$(right$(command$(i),4))=".m3u"then - parsem3u command$(i),file() - else - file(ubound(file))=command$(i) - redim _preserve file(ubound(file)+1) - end if - end if -end select + repeat=1 + else + repeat=-1 + end if + case "-n","--nooutput" + nooutput=-1 + case "-N","--nyan" + nyan=-1 + case "-b","--soundbank" + if _commandcount>i and _fileexists(command$(i+1)) then + loadsoundbank command$(i+1) + else + print "error loading soundbank" + system + end if + case else + if _fileexists(command$(i)) then + if lcase$(right$(command$(i),4))=".m3u"then + parsem3u command$(i),file() + else + file(ubound(file))=command$(i) + redim _preserve file(ubound(file)+1) + end if + end if + end select next redim _preserve file(ubound(file)-1) @@ -249,7 +209,7 @@ if shuffle=-1 then shufflearray file() i=0 musichandle=_sndopen(file(i)) if musichandle=0 then - print"Error: could not open file ";file(i) + print"Error: could not open file "; file(i) goto quit end if _sndvol musichandle,volume @@ -259,110 +219,106 @@ songname=beforelast(".",afterlast("/",file(i))) while keyin<>27 keyin=terminkey - ' ---Poll Client Messages--- +' ---Poll Client Messages--- dim incoming_buf as string - incoming_buf=space$(512)+chr$(0) + incoming_buf = space$(512) + chr$(0) dim msg_len as long - msg_len=ipc_check_message(_offset(incoming_buf),512) - - if msg_len>0 then + msg_len = ipc_check_message(_offset(incoming_buf), 512) + + if msg_len > 0 then dim client_cmd as string - client_cmd=left$(incoming_buf,msg_len) - - if client_cmd="NEXT" then - playnext=1 - elseif client_cmd="PLAY" then + client_cmd = left$(incoming_buf, msg_len) + + if client_cmd = "NEXT" then + playnext = 1 + elseif client_cmd = "PLAY" then keyin=asc("x") - elseif client_cmd="PAUSE" then + elseif client_cmd = "PAUSE" then keyin=asc("c") - elseif client_cmd="STOP" then + elseif client_cmd = "STOP" then keyin=asc("v") - elseif client_cmd="QUIT" then + elseif client_cmd = "QUIT" then keyin=27 - elseif client_cmd="REPEAT" then + elseif client_cmd = "REPEAT" then repeat=-1 - elseif client_cmd="REPEAT1" then + elseif client_cmd = "REPEAT1" then repeat=1 - elseif client_cmd="REPEATOFF" then - repeat=0 - elseif client_cmd="SHUFFLE" then + elseif client_cmd = "SHUFFLE" then keyin=asc("s") - elseif client_cmd="NYAN" then - nyan=not nyan - elseif client_cmd="NYANOFF" then - nyan=0 - elseif left$(client_cmd,10)="SOUNDBANK:" then - if client_cmd="default" then loadsoundbank "" else loadsoundbank mid$(client_cmd,11) + elseif client_cmd = "NYAN" then + nyan = not nyan + elseif left$(client_cmd, 10) = "SOUNDBANK:" then + if client_cmd="default" then loadsoundbank "" else loadsoundbank mid$(client_cmd,11) - if _sndplaying(musichandle) then + if _SNDPLAYING(musichandle) then - ' a hack to make qb64pe load the midi file that is already loaded. - ' qb64 can't open the same file again with a new sound bank for some reason - ' so it has to be closed, freed and given a short delay before reloading - ' which gives a short break in the playing of music, very annoying. - ' this should be reverted if qb64pe ever gets the ability to reload the same - ' file more than once. - - tmppos=_sndgetpos(musichandle) - _sndstop musichandle - _sndclose musichandle - _delay .1 - musichandle=_sndopen(file(i)) - _sndvol musichandle,volume - _sndsetpos musichandle,tmppos - _sndplay musichandle - end if - elseif left$(client_cmd,4)="VOL:" then - volume=val(mid$(client_cmd,5))/100 - if volume>1 then volume=1 - if volume<0 then volume=0 - _sndvol musichandle,volume - elseif left$(client_cmd,4)="ADD:" then + ' a hack to make qb64pe load the midi file that is already loaded. + ' qb64 can't open the same file again with a new sound bank for some reason + ' so it has to be closed, freed and given a short delay before reloading + ' which gives a short break in the playing of music, very annoying. + ' this should be reverted if qb64pe ever gets the ability to reload the same + ' file more than once. + + tmppos=_sndgetpos(musichandle) + _sndstop musichandle + _sndclose musichandle + _delay .1 + musichandle=_sndopen(file(i)) + _sndvol musichandle,volume + _sndsetpos musichandle,tmppos + _sndplay musichandle + end if + elseif left$(client_cmd, 4) = "VOL:" then + volume = val(mid$(client_cmd, 5)) / 100 + if volume > 1 then volume = 1 + if volume < 0 then volume = 0 + _sndvol musichandle, volume + elseif left$(client_cmd, 4) = "ADD:" then dim new_file as string - new_file=_trim$(mid$(client_cmd,5)) + new_file = _trim$(mid$(client_cmd, 5)) if _fileexists(new_file) then - if lcase$(right$(new_file,4))=".m3u" then - parsem3u new_file,file() + if lcase$(right$(new_file, 4)) = ".m3u" then + parsem3u new_file, file() else - redim _preserve file(ubound(file)+1) as string - file(ubound(file))=new_file + redim _preserve file(ubound(file) + 1) as string + file(ubound(file)) = new_file end if end if - elseif left$(client_cmd,5)="PLAY:" then + elseif left$(client_cmd, 5) = "PLAY:" then dim replace_file as string - replace_file=_trim$(mid$(client_cmd,6)) + replace_file = _trim$(mid$(client_cmd, 6)) if _fileexists(replace_file) then redim file(0) as string - if lcase$(right$(replace_file,4))=".m3u" then - parsem3u replace_file,file() + if lcase$(right$(replace_file, 4)) = ".m3u" then + parsem3u replace_file, file() else - file(0)=replace_file + file(0) = replace_file end if - i=-1 - playnext=1 + i = -1 + playnext = 1 end if - elseif client_cmd="GET_PLAYLIST" then + elseif client_cmd = "GET_PLAYLIST" then dim p_idx as long dim playlist_payload as string - playlist_payload="=== Current Playlist ==="+chr$(10) - for p_idx=lbound(file) to ubound(file) - if p_idx=i then - playlist_payload=playlist_payload+"-> "+file(p_idx)+chr$(10) + playlist_payload = "=== Current Playlist ===" + chr$(10) + for p_idx = lbound(file) to ubound(file) + if p_idx = i then + playlist_payload = playlist_payload + "-> " + file(p_idx) + chr$(10) else - playlist_payload=playlist_payload+" "+file(p_idx)+chr$(10) + playlist_payload = playlist_payload + " " + file(p_idx) + chr$(10) end if next p_idx - + ipc_cleanup _delay 0.1 ipc_send_message playlist_payload _delay 0.1 dim reinit as long - reinit=ipc_init + reinit = ipc_init end if end if ' --- End Poll Client Messages --- - + select case keyin case key_up volume=volume+(0.01+(volume/10)) @@ -460,7 +416,7 @@ while keyin<>27 if nooutput=0 then tw=termwidth fixedwidth=uwidth(state)+uwidth(progress) - maxtitlewidth=tw-fixedwidth + maxtitlewidth=tw-fixedwidth-2 currentsongwidth=uwidth(songname) if currentsongwidth>maxtitlewidth and maxtitlewidth>4 then @@ -498,20 +454,20 @@ while keyin<>27 ' Print the text line if nyan=-1 then - print termcolor(7);state;animatedrainbowtext(visibletitle);termcolor(7);progress;clearrest + print termcolor(7); state; animatedrainbowtext(visibletitle); termcolor(7); progress; clearrest else - print termcolor(7);state;termcolor(3);visibletitle;termcolor(7);progress;clearrest + print termcolor(7); state; termcolor(3); visibletitle; termcolor(7); progress; clearrest end if ' Generate and print progress bar matching the layout width progressbar=bar(uwidth(state)+uwidth(visibletitle)+uwidth(progress),(_sndgetpos(musichandle)/_sndlen(musichandle))*100,11,7) - print progressbar;clearrest;cursorback; + print progressbar; clearrest; cursorback; end if _limit 30 if _exit then goto quit -wend + wend quit: _sndclose musichandle @@ -538,42 +494,42 @@ sub parsem3u (filename$,array$()) dim basepath$,l$,resolvedpath$ for i=len(filename$) to 1 step -1 if mid$(filename$,i,1)="/"or mid$(filename$,i,1)="\"then - basepath$=left$(filename$,i) - exit for - end if -next -f=freefile -open filename$ for input as #f -count=0 -do until eof(f) - line input #f,l$ - l$=_trim$(l$) - if len(l$)>0 and left$(l$,1)<>"#"then - resolvedpath$=l$ - if not _fileexists(resolvedpath$) then - resolvedpath$=basepath$+l$ - end if - if _fileexists(resolvedpath$) then - array$(ubound(array$))=resolvedpath$ - redim _preserve array$(ubound(array$)+1) - end if -end if -loop -close #f + basepath$=left$(filename$,i) + exit for + end if + next + f=freefile + open filename$ for input as #f + count=0 + do until eof(f) + line input #f,l$ + l$=_trim$(l$) + if len(l$)>0 and left$(l$,1)<>"#"then + resolvedpath$=l$ + if not _fileexists(resolvedpath$) then + resolvedpath$=basepath$+l$ + end if + if _fileexists(resolvedpath$) then + array$(ubound(array$))=resolvedpath$ + redim _preserve array$(ubound(array$)+1) + end if + end if + loop + close #f end sub function timeleft$ (handle&) dim seconds as integer seconds=_sndlen(handle&)-_sndgetpos(handle&) if seconds<0 then seconds=0 - timeleft$=right$("0"+ltrim$(str$(seconds\60)),2)+":"+right$("0"+ltrim$(str$(seconds mod 60)),2) + timeleft$=right$("0"+ltrim$(str$(seconds \ 60)),2)+":"+right$("0"+ltrim$(str$(seconds mod 60)),2) end function function timeelapsed$ (handle&) dim seconds as integer seconds=_sndgetpos(handle&) if seconds<0 then seconds=0 - timeelapsed$=right$("0"+ltrim$(str$(seconds\60)),2)+":"+right$("0"+ltrim$(str$(seconds mod 60)),2) + timeelapsed$=right$("0"+ltrim$(str$(seconds \ 60)),2)+":"+right$("0"+ltrim$(str$(seconds mod 60)),2) end function function termcolor$ (colorvalue as _unsigned long) @@ -669,9 +625,12 @@ end function function ulen% (txt$) dim count%,i%,b% + count%=0 for i%=1 to len(txt$) b%=asc(txt$,i%) - if (b% and &h80)=0 or (b% and &hc0)=&hc0 then count%=count%+1 + if (b% and &h80)=0 or (b% and &hc0)=&hc0 then + count%=count%+1 + end if next ulen%=count% end function @@ -749,37 +708,5 @@ function getcodepoint& (utf8char$) end function sub loadsoundbank (filename as string) - _midisoundbank filename + _midisoundbank filename end sub - - -function GetConfig$ (FileName as string) - select case left$(_os$,instr(_os$,"]")) - case "[WINDOWS]" - dim appdata as string - appdata=environ$("APPDATA") - if appdata="" then appdata=environ$("USERPROFILE")+"\AppData\Roaming" - if right$(appdata,1)<>"\" then appdata=appdata+"\" - GetConfig=appdata+FileName - - case "[MACOSX]" - dim homemac as string - homemac=environ$("HOME") - if homemac="" then homemac="/tmp" - if right$(homemac,1)="/" then homemac=left$(homemac,len(homemac)-1) - GetConfig=homemac+"/Library/Application Support/"+FileName - - case else ' Linux and other Unix-like systems - dim xdg as string,baseDir as string,homelinux as string - xdg=environ$("XDG_CONFIG_HOME") - if xdg<>"" then - baseDir=xdg - else - homelinux=environ$("HOME") - if homelinux="" then homelinux="/tmp" - baseDir=homelinux+"/.config" - end if - if right$(baseDir,1)="/" then baseDir=left$(baseDir,len(baseDir)-1) - GetConfig=baseDir+"/"+FileName - end select -end function diff --git a/readme.md b/readme.md index d20cef3..f7971b9 100644 --- a/readme.md +++ b/readme.md @@ -129,8 +129,9 @@ When interacting directly with the player interface terminal, use these keys: ## Supported Audio Formats -All formats supported by QB64PE are supported by cimp, as it handles the -decoding. The following formats are supported by the most recent version: +All formats supported by QB64/QB64PE are supported by cimp, as QB64 handles the +decoding. The following formats are supported by the most recent versions of +both compilers: Audio files: `mod`, `xm`, `s3m`, `it`, `mid`, `mp3`, `ogg`, and `flac` @@ -142,7 +143,7 @@ Sound banks: | File | Description | | ------------- | --------------------------------------------------------------------------------------- | -| `cimp.bas` | Main player - QB64 source handling client/server states and UI | +| `cimp.bas` | Main player — QB64-PE source handling client/server states and UI | | `terminkey.h` | C library for cross-platform raw keyboard input, IPC pipes/sockets, and terminal sizing | ## Notes