Compare commits
2 changed files with 188 additions and 260 deletions
297
cimp.bas
297
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"
|
||||
Select Case command$(1)
|
||||
Case "--soundbank"
|
||||
cmd_msg = "SOUNDBANK:" + _cwd$ + slash + command$(2)
|
||||
Case "--next"
|
||||
cmd_msg = "NEXT"
|
||||
|
||||
case "--prev"
|
||||
cmd_msg="PREV"
|
||||
Case "--prev"
|
||||
cmd_msg = "PREV"
|
||||
|
||||
case "-v","--volume"
|
||||
cmd_msg="VOL:"+command$(2)
|
||||
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
|
||||
Next i
|
||||
System
|
||||
|
||||
case "--playlist"
|
||||
cmd_msg="GET_PLAYLIST"
|
||||
Case "--playlist"
|
||||
cmd_msg = "GET_PLAYLIST"
|
||||
|
||||
case else
|
||||
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
|
||||
start_wait = timer
|
||||
|
||||
do while timer-start_wait<2
|
||||
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
|
||||
|
|
@ -121,7 +117,7 @@ if ipc_status=0 then
|
|||
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"
|
||||
|
|
@ -240,7 +200,7 @@ for i=1 to _commandcount
|
|||
redim _preserve file(ubound(file)+1)
|
||||
end if
|
||||
end if
|
||||
end select
|
||||
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,42 +219,38 @@ 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)
|
||||
msg_len = ipc_check_message(_offset(incoming_buf), 512)
|
||||
|
||||
if msg_len>0 then
|
||||
if msg_len > 0 then
|
||||
dim client_cmd as string
|
||||
client_cmd=left$(incoming_buf,msg_len)
|
||||
client_cmd = left$(incoming_buf, msg_len)
|
||||
|
||||
if client_cmd="NEXT" then
|
||||
playnext=1
|
||||
elseif client_cmd="PLAY" then
|
||||
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
|
||||
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
|
||||
|
|
@ -312,44 +268,44 @@ while keyin<>27
|
|||
_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
|
||||
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
|
||||
|
||||
|
|
@ -358,7 +314,7 @@ while keyin<>27
|
|||
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 ---
|
||||
|
|
@ -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
|
||||
|
|
@ -541,11 +497,11 @@ sub parsem3u (filename$,array$())
|
|||
basepath$=left$(filename$,i)
|
||||
exit for
|
||||
end if
|
||||
next
|
||||
f=freefile
|
||||
open filename$ for input as #f
|
||||
count=0
|
||||
do until eof(f)
|
||||
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
|
||||
|
|
@ -557,23 +513,23 @@ do until eof(f)
|
|||
array$(ubound(array$))=resolvedpath$
|
||||
redim _preserve array$(ubound(array$)+1)
|
||||
end if
|
||||
end if
|
||||
loop
|
||||
close #f
|
||||
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
|
||||
|
|
@ -751,35 +710,3 @@ end function
|
|||
sub loadsoundbank (filename as string)
|
||||
_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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue