Peace & Protection 4.00 — File Browser

PeaceProtection4.00v4.0 / PeaceProtection4.00v4.0 / ADDONS / SOUND.MRC

SOUND.MRC — 28.22 KB — Download this file

; #= ppsound -rs
; ########################################
; Peace & Protection
; Sound (standard addon) part 1
; ########################################

;;; test info reading for messed headers and add vbr support

; /loc [-switches] type [soundfile|stop] [window] [action]
; switches specify list or play random, etc.
; soundfile may include an extension (else type is used to get extension(s))
; soundfile may include a directory, wildcards, spaces, quotes
; if soundfile is just a directory or missing, you pick a file
; wildcards finds indexed matches; wilds with directory finds nonindexed matches
; exact filename only matches exact file (although dirs are searched)
; window defaults to TARGET
; action defaults to DEFAULT
; type must be specified (mp, not mp2/mp3, for example)
; type may be * if -s for playlist, or to use current type
; finds and plays to window (unless error or playlisting)
; mostly used internally
; adds all matches to queue if open

; Switches-
; -l = Always list
; -r = Always random
; -a[n] = Add to list [number]
; -p = Playlist all matches
; -c = Confirm random selections
; -s = Searching for a playlist (with l to edit list)
; (by default, lists if >1, plays if =1)

alias loc {
  ; Sort parameters
  if (-* iswm $1) { var %num,%opt = $1,%type = $2,%file = $3- }
  else { var %num,%opt = -,%type = $1,%file = $2- }
  if ("* iswm %file) { var %action = $gettok(%file,2-,34) | %file = $gettok(%file,1,34) }
  else { var %action = $gettok(%file,2-,32) | %file = $gettok(%file,1,32) }
  var %window = $gettok(%action,1,32)
  %action = $gettok(%action,2-,32)
  if (%action == $null) %action = -
  if ((%window == $null) || (%window == -)) {
    _validst -a
    %window = %`soundtarg
  }

  if (s isin %opt) %type = *
  else {
    if (%type == *) %type = %`soundtype
    if (%type == $null) {
      _validstp
      %type = %`soundtype
    }
    if ($_scfg(%type,ext) == $null) _error Unrecognized sound file type- %type See sound configuration for details.
  }

  ; Stop?
  if (%file == stop) {
    if (/* iswm $_scfg(%type,player)) $_scfg(%type,player) stop
    else {
      if ($istok($_scfg(%type,ext),%type,32)) %file = $_temp(%type)
      else %file = $_temp($gettok($_scfg(%type,ext),1,32))
      write -c %file | _plsound %type %file
    }
    .timer.squeue off
    return
  }

  ; Playlists?
  if (s isin %opt) var %kind = list
  else var %kind = file

  ; Find or select file
  if ($nopath(%file)) {
    if ((* !isin %file) && (. !isin %file) && (\ !isin %file)) %file = * $+ %file $+ *
    if (. !isin %file) %file = %file $+ . $+ $_glurp($iif(%kind == list,$_splext,$_scfg(%type,ext)))
    if (\ isin %file) %file = $_truename.fn(%file)
    if (%kind == list) {
      %num = $findfile($nofile(%file),$nopath(%file),0)
      if (%num == 0) _error No matching playlist files found.Mask- %file
      %file = $findfile($nofile(%file),$nopath(%file),$_pprand(%num))
    }
    else {
      %num = $_sfind(%type,1,%file)
      if (%num == 0) {
        window -c @.soundfind
        _error No matching $_desc(%type) files found.Mask- %file
      }
    }
  }
  else {
    if (%file == $null) {
      %file = $iif(%kind == list,$_scfg(opt,lastpdir),$_scfg(%type,lastdir))
      if (%file == $null) %file = $_scfg(%type,dir1)
    }
    if (*\ !iswm %file) %file = %file $+ \
    if (. !isin %file) %file = %file $+ *. $+ $_glurp($iif(%kind == list,$_splext,$_scfg(%type,ext)))
    if (%kind == list) var %kshow = playlist | else var %kshow = $_desc(%type) file
    %file = $$dir="Select a %kshow " %file
    writeini $_cfg(sound.ini) $iif(%kind == list,opt,%type) $iif(%kind == list,lastpdir,lastdir) $nofile(%file)
    ; grab any description and store in window
    if (%kind == file) %num = $_sfind(%type,1,%file)
  }

  ;  if (($window(@Queue) == $null) && ($window(@Playlist*,0) == 0)) .starg %window

  ; Special actions- queue?
  if (($window(@queue)) && (c !isin %opt) && (r !isin %opt) && (a !isin %opt) && (l !isin %opt)) {
    if (%kind == list) {
      window -hl @.soundfind
      loadbuf @.soundfind " $+ %file $+ "
      %kind = 1
    }
    else %kind = 2
    %num = 1
    :loopq
    if ($line(@.soundfind,%num)) { squeue $gettok($ifmatch,%kind,9) | inc %num | goto loopq }
    window -c @.soundfind
    squeue start
    return
  }

  ; List in window?
  if ((l isin %opt) || (a isin %opt) || ((%num > 1) && (r !isin %opt) && (c !isin %opt) && (p !isin %opt))) {
    if (a isin %opt) {
      %window = @Playlist $+ $calc($right(%opt,$calc(- $pos(%opt,a,1))))
      if (%window == @Playlist0) %window = @Playlist
    }
    else %window = @Playlist
    if ($window(%window) == $null) { _window 2.4 -l + %window $_winpos(8,12,10,10) @Playlist | _plban %window }
    elseif (a !isin %opt) { clear %window | _plban %window }
    if (%kind == list) {
      loadbuf %window " $+ %file $+ "
      titlebar %window (x files) %file
    }
    else {
      %num = 1
      :loopp
      if ($line(@.soundfind,%num)) { aline %window $gettok($ifmatch,2,9) | inc %num | goto loopp }
      window -c @.soundfind
    }
    _plupdt %window
    window -a %window
    return
  }

  if (%kind == list) {
    _plplpl %file
    return
  }

  ; Playlist?
  if (p isin %opt) {
    %file = $_temp($gettok($_splext,1,32))
    %num = 1
    window -ln @.soundfind2
    :looppp
    if ($line(@.soundfind,%num)) { aline @.soundfind2 $gettok($ifmatch,2,9) | inc %num | goto looppp }
    savebuf @.soundfind2 %file
    close -@ @.soundfind @.soundfind2
    _plplpl $mircdir $+ %file
    return
  }

  ; Else, random pick
  %num = $line(@.soundfind,0)
  :retry
  %file = $line(@.soundfind,$_pprand(%num))
  if ($_pprand($calc(2 + $gettok($gettok(%file,1,9),1,3))) > 2) goto retry
  window -c @.soundfind

  ; Confirm random pick?
  if ((c isin %opt) && (%num > 1)) {
    _dialog -am randsound randsound
    did -a randsound 2 $replace($nopath($gettok(%file,2,9)),&,&&)
    did -o randsound 10 1 %file
    did -o randsound 11 1 $1-
    did -o randsound 12 1 %window
    did -o randsound 13 1 %action
    did -o randsound 14 1 %type
    halt
  }

  ; sound / desc selected- now play
  if ($window(@queue)) { squeue $gettok(%file,2,9) | squeue start }
  else return $_sound($gettok(%file,2,9),%file,%window,%action,%type,$iif(%num > 1,randomly plays,plays))
}
alias _plban {
  aline $1 Double-click here to play one random, or on a file to play it
  aline -s $1 Double-click here to playlist all, or right-click for other options
  aline $1  
}

; Random pick dialog
dialog randsound {
  title "Random Sound"
  size -1 -1 400 68
  text "Playing:", 1, 5 3 395 15
  text "", 2, 8 20 395 15
  button "Pla&y", 3, 13 40 80 25, OK default
  button "Cancel", 4, 113 40 80 25, cancel
  button "&Pick again", 5, 213 40 80 25
  check "&Continuous", 20, 313 42 100 22
  edit "", 10, 1 1 1 1, hide result
  edit "", 11, 1 1 1 1, hide
  edit "", 12, 1 1 1 1, hide
  edit "", 13, 1 1 1 1, hide
  edit "", 14, 1 1 1 1, hide
}
on *:DIALOG:randsound:init:*:if (%_s.cont) did -c $dname 20
on *:DIALOG:randsound:sclick:3:{
  if ($_scfg($did(14),index)) {
    ; modify rating of old one
    var %file = $did(14) $+ _indx.dat
    %file = $_cfg(%file)
    var %get = "* $+ $did(10) $+ *"
    var %line = $read -nw [ $+ [ %get ] ] %file
    %line = $puttok(%line,0 ,1,9)
    if ($count(%line,	) < 2) %line = %line $+ 	
    write -l $+ $readn %file %line
  }
  if (($did(20).state) && ($_not(%_s.cont))) scont on | elseif ($did(20).state == 0) .scont off
  if ($window(@queue)) { squeue $gettok($did(10),2,9) | squeue start }
  else return $_sound($gettok($did(10),2,9),$did(10),$did(12),$did(13),$did(14),randomly plays)
}
on *:DIALOG:randsound:sclick:5:{
  if ($_scfg($did(14),index)) {
    ; modify rating of old one
    var %file = $did(14) $+ _indx.dat
    %file = $_cfg(%file)
    var %get = "* $+ $did(10) $+ *"
    var %line = $read -nw [ $+ [ %get ] ] %file
    var %new =  $+ $calc($gettok($gettok(%line,1,9),1,3) + 1) 
    %line = $puttok(%line,%new,1,9)
    if ($count(%line,	) < 2) %line = %line $+ 	
    write -l $+ $readn %file %line
  }
  loc $did(11)
}

; /sound [window] soundfile [action]
; soundfile must include an extension (defaults to wav otherwise)
; soundfile may include a directory
; soundfile may include wildcards, spaces, quotes
; window defaults to CURRENT; can be -s (status) -c (all chan) -q (quiet) -a (active)
; action defaults to NONE; use - for a 'default' action
; plays to window (unless error)

alias _tsound {
  _validst -a
  sound %`soundtarg $1-
}
alias sound {
  if (($1 == $null) || ($1 == on) || ($1 == off)) { sound $1 | unset %_opt.n3 | return }

  ; Sort parameters
  if (($_isopen($1)) || (-? iswm $1)) { var %window = $1,%file = $2- }
  else { var %window = -a,%file = $1- }
  if ("* iswm %file) { var %action = $gettok($gettok(%file,2-,34),1-,32) | %file = $gettok(%file,1,34) }
  else { var %action = $gettok(%file,2-,32) | %file = $gettok(%file,1,32) }

  if (%file == $null) _error No sound file given.You must specify a sound file or wildcard mask.
  if (. !isin %file) %file = %file $+ .wav

  ; Determine filetype
  var %type = $_sext(%file)
  if (%type == $null) _error Unrecognized sound file extension- %ext See sound configuration for details.

  ; Find the file
  var %found = $_sfind(%type,0,%file)
  if (%found == $null) _error Sound not found- %file This file may have moved, you may need to reindex sounds.

  ; sound / desc selected- now play
  return $_sound($gettok(%found,2,9),%found,%window,%action,%type,plays)
}

; determine filetype by extension
; $_sext(file)
alias _sext return $_scfg(reverse,$gettok($1-,$numtok($1-,46),46))

; This does the actual playing of a sound (with display)
; $_sound(file,fileline,window,action,type,howplayed)
; 'fileline' should contain the file/rating/desc
; 'action' should contain the action (- for default; blank ok)
; 'howplayed' should be some form of 'plays'
alias _sound {
  ; Correct window if needed
  var %window = $3,%action = $4,%20 = % $+ 20
  if (%window == -a) %window = $active
  if ((@Playlist* iswm %window) || (@Queue == %window)) {
    %window = %_soundtarg2
    if (%window == $null) %window = -s
  }
  elseif ((* * iswm %window) || (@* iswm %window)) %window = -s

  ;;; DEBUG
  %-last-sound-param = $1-
  %-last-sound-window = %window

  ; Play the sound itself
  _plsound $5 $1

  ; Format the action
  var %desc = $gettok($2,3,9)

  if ($5 == mp3) {
    mp3.prep $1
    var %secs = $mp3.time($1)
    if ((%secs < 1) || (%secs == $null)) %secs = 0

    if ((%desc == $null) && ($_scfg($5,autodesc))) %desc = $mp3.desc
    if ($4 == -) %action = $readini $_cfg(sound.ini) $5 $iif(%desc == $null,msg,msgdesc)
    %action = $_premsg($_readprep(%action))
    %action = $replace(%action,&desc&,%desc,&file&,$replace($nopath($1),%20,_,_,$chr(32)),&secs&,%secs,&dur&,$_dur(%secs),&time&,$_stime(%secs),&size&,$_size($lof($1)),&play&,$6)

    var %sect,%amp,%num = 9
    :loopr
    %sect = $gettok(stereo bitrate khz song artist album year genre comment,%num,32)
    %amp = & $+ %sect $+ &
    if (%amp isin %action) %action = $replace(%action,%amp,$mp3. [ $+ [ %sect ] ] )
    if (%num > 1) { dec %num | goto loopr }
  }
  else {
    if ($4 == -) %action = $readini $_cfg(sound.ini) $5 $iif(%desc == $null,msg,msgdesc)
    %action = $_premsg($_readprep(%action))
    %action = $replace(%action,&desc&,%desc,&file&,$replace($nopath($1),%20,_,_,$chr(32)),&size&,$_size($lof($1)),&play&,$6)
  }

  %action = $_finalmsg(%action)

  ; Say it
  set -u %.file $nopath($1)
  if (%window == -c) {
    if ($chan(0)) {
      if ($_scfg(opt,useme)) var %tosend = ACTION %action
      else var %tosend = SOUND $replace($nopath($1),$chr(32),?) %action
      var %chans
      %num = 1
      :loopa
      %sect = $chan(%num)
      if (%sect) {
        %chans = $addtok(%chans,%sect,44)
        if (($numtok(%chans,44) >= %!target) || ($calc($len(%chans) + $len(%tosend)) > 450)) { .ctcp %chans %tosend | var %chans }
        <show.sound> %sect $me 0 %action
        inc %num
        goto loopa
      }
      if (%chans) .ctcp %chans %tosend
      %!lastsound = $1
    }
    else <show.sound> -s $me 0 %action
  }
  elseif (%window != -q) {
    if (%window != -s) {
      if ($_scfg(opt,useme)) .describe %window %action
      else .ctcp %window SOUND $replace($nopath($1),$chr(32),?) %action
      %!lastsound = $1
    }
    if ($_isopen(%window)) <show.sound> %window $me 0 %action
    else <show.sound.send> %window $me %action
  }

  _scontchk $5 $1
}

; Here we handle the action of playing a sound (no display)
; $1 should be the file type
; $2- should be the file
alias _plsound {
  ; Get the player
  var %sound = $2-,%player = $_scfg($1,player)

  ; Play
  if ($_scfg($1,shortfn)) %sound = $shortfn($2-)
  if ($left(%player,1) == /) %player " $+ %sound $+ "
  else {
    if ($exists(%sound) == $false) { if ($show) _error File not found- $2- $+ This sound may have moved, you may need to reindex. | return }
    if ($_scfg($1,listone)) {
      var %file = $_scfg($1,list)
      if (%file == $null) %file = lst

      ; Filename
      %file = $_temp(%file)
      write -c %file %sound
      %sound = $mircdir $+ %file
      %sound = $shortfn(%sound)
      if ($_scfg($1,listformat)) $ifmatch %sound
    }
    run $iif($_scfg($1,minimize),-n) %player $iif(%player,") $+ %sound $+ $iif(%player,")
    if ($_scfg($1,grabfocus)) .timer.grabfocus 4 1 if ($appactive == $!false) $chr(123) showmirc -s $chr(124) .timer.grabfocus off $chr(125)
  }

  ; Store recents- both in an 8-item list and a 30-item playlist, and panel if open
  _recent sound 8 $2-
  var %file = $_cfg(recent.pls)
  window -hl @.reclist
  if ($exists(%file)) loadbuf @.reclist %file
  if ($fline(@.reclist,$2-,1)) dline @.reclist $ifmatch
  iline @.reclist 1 $2-
  savebuf 1-30 @.reclist %file
  if ($dialog(sndpanel)) {
    var %del = $line(@.reclist,31),%num = $did(sndpanel,7).lines,%found
    :droop
    if (%num) {
      if ($did(sndpanel,7,%num) == $2-) { %found = 1 | did -c sndpanel 7 %num }
      elseif ($did(sndpanel,7,%num) == %del) did -d sndpanel 7 %num
      dec %num | goto droop
    }
    if (%found != 1) did -ac sndpanel 7 $2-
  }
  window -c @.reclist
}

; $_sfind(type,x,filename)
; Finds sound file(s)
; wildcards finds indexed matches; wilds with directory finds nonindexed matches
; exact filename only matches exact file (although dirs are searched)
; x = 0 to return one (possibly random) match, 1 to return num of results and stick in @.soundfind
; remember that index is 'presorted'; results contain with tabs with descriptions etc.
; no errors except for index-missing errors
alias _sfind {
  window -hls @.soundfind
  clear @.soundfind
  ; wildcard search
  if ($nofile($3-)) {
    if ($exists($3-)) {
      if ($_scfg($1,index)) {
        var %file = $_cfg($1_indx.dat)
        if ($exists(%file) == $false) { if ($show) _error $_desc($1) files have not been indexed properly.Press $_Q.fkey(1,$calc($ctime + 120),reindex,$1) to index them. | return }
        filter -fw %file @.soundfind *	 $+ $3- $+ 	*
      }
      if ($line(@.soundfind,0) == 0) aline @.soundfind 0 	 $+ $3- $+ $chr(9)
    }
    else {
      ; ...within a directory
      var %num = $findfile($nofile($3-),$nopath($3-),0,aline @.soundfind 0 	 $+ $1- $+ $chr(9))
    }
  }
  else {
    ; ...within index
    ; (if index isn't in use, default to manual scan)
    if ($_scfg($1,index)) {
      var %file = $_cfg($1_indx.dat)
      if ($exists(%file) == $false) { if ($show) _error $_desc($1) files have not been indexed properly.Press $_Q.fkey(1,$calc($ctime + 120),reindex,$1) to index them. | return }
      filter -fw %file @.soundfind *	*\ $+ $3- $+ 	*
    }
    else {
      ; find exact matches within sound dirs
      var %file,%num = 1
      :loopf
      %file = $_scfg($1,dir [ $+ [ %num ] ] )
      if (%file) {
        %file = $findfile(%file,$3-,0,aline @.soundfind 0 	 $+ $1- $+ $chr(9))
        inc %num | goto loopf
      }
    }
  }
  ; All matches are in window
  if ($2) return $line(@.soundfind,0)
  ; random...
  if ($line(@.soundfind,0) == 0) { window -c @.soundfind | return }
  if ($line(@.soundfind,0) == 1) var %num = $line(@.soundfind,1)
  else {
    :retry
    var %num = $line(@.soundfind,$_pprand($line(@.soundfind,0)))
    if ($_pprand($calc(2 + $gettok($gettok(%num,1,9),1,3))) > 2) goto retry
  }
  window -c @.soundfind
  return %num
}

; $_scfg(type,bit)
alias _scfg return $readini -n $_cfg(sound.ini) $1 $2

; $_splext
alias _splext if ($_scfg(opt,playlist)) return $ifmatch | return m3u pls

; $_desc(type)
alias _desc return $readini -n $_cfg(sound.ini) $1 desc

; $_stime(secs)
alias _stime if ($1) return $int($calc($1 / 60)) $+ : $+ $right($calc($1 % 60 + 100),2) | return ?:??

; MP3/etc info identifiers (time must return seconds or 0/null; all others are free-form)
alias mp3.prep {
  bread " $+ $1- $+ " $calc($lof($1-) - 128) 128 &tag
  bread " $+ $1- $+ " 0 4 &riff
  if ($bvar(&riff,1-4).text === RIFF) var %try = 72
  elseif ($bvar(&riff,1-3) == 0 0 0) var %try = 36
  else var %try = 0
  bread " $+ $1- $+ " %try 2 &try
  if (($bvar(&try,1) == 255) && ($bvar(&try,2) & 224)) goto ok
  bread " $+ $1- $+ " 0 4096 &try
  %try = 1
  :loop
  if (($bvar(&try,%try) == 255) && ($bvar(&try,$calc(%try + 1)) & 224)) goto ok
  if (%try < 4094) { inc %try | goto loop }
  ;;; use a default header
  bread " $+ $1- $+ " 1 3 &mpeg
  return
  :ok
  bread " $+ $1- $+ " $calc(%try + 1) 3 &mpeg
  return
}
alias mp3.time return $round($calc($lof($1-) / $mp3.bitrate / 125),0)
alias mp3.tag if ($bvar(&tag,1-3).text === TAG) return 1 | return 0
alias mp3.layer return $calc(4 - $int($calc($bvar(&mpeg,1) / 2 % 4)))
alias mp3.ver return $gettok(2.5 0 2.0 1.0,$calc(1 + $int($calc($bvar(&mpeg,1) / 8 % 4))),32)
alias mp3.stereo if ($bvar(&mpeg,3) & 128) { if ($bvar(&mpeg,3) & 64) return Mono | return Dual Channel } | return Stereo
alias mp3.bitrate {
  var %ver = $mp3.ver
  if (%ver == 1.0) {
    mp3.layer
    if ($result == 1) var %info = 0 32 64 96 128 160 192 224 256 288 320 352 384 416 448 0
    elseif ($result == 2) var %info = 0 32 48 56 64 80 96 112 128 160 192 224 256 320 384 0
    else var %info = 0 32 40 48 56 64 80 96 112 128 160 192 224 256 320 0
  }
  elseif (%ver == 2.0) {
    mp3.layer
    if ($result == 1) var %info = 0 32 48 56 64 80 96 112 128 144 160 176 192 224 256 0
    else var %info = 0 8 16 24 32 40 48 56 64 80 96 112 128 144 160 0
  }
  else %info = 0 8 16 0 0 0 0 0 0 0 0 0 0 0 0 0
  return $gettok(%info,$int($calc($bvar(&mpeg,2) / 16 + 1)),32)
}
alias mp3.khz {
  mp3.ver
  if ($result == 1.0) var %info = 44.1 48 32 0
  elseif ($result == 2.0) var %info = 22.05 24 16 0
  else var %info = 11.025 12 8 0
  return $gettok(%info,$int($calc($bvar(&mpeg,2) / 4 % 4 + 1)),32)
}
alias mp3.desc {
  if ($mp3.tag) {
    var %album = $mp3.id3(64-93)
    if (%album) %album = ( $+ %album $+ )
    var %artist = $mp3.id3(34-63) %album
    if (%artist) %artist = %artist -
    return %artist $mp3.id3(4-33)
  }
}
alias mp3.song if ($mp3.tag) return $mp3.id3(4-33)
alias mp3.artist if ($mp3.tag) return $mp3.id3(34-63)
alias mp3.album if ($mp3.tag) return $mp3.id3(64-93)
alias mp3.year if ($mp3.tag) return $mp3.id3(94-97)
alias mp3.comment if ($mp3.tag) return $mp3.id3(98-127)
alias mp3.genre if ($mp3.genre2) return $read -tnl [ $+ [ $calc($ifmatch + 1) ] ] $scriptdirgenre.txt
alias mp3.genre2 if ($mp3.tag) return $bvar(&tag,128)
alias mp3.id3 {
  var %pos = 1,%info = $bvar(&tag,$1).text
  :loop
  if ($asc($mid(%info,%pos,1)) < 32) %info = $replace(%info,$mid(%info,%pos,1),$chr(32))
  if (%pos < $len(%info)) { inc %pos | goto loop }
  return $gettok(%info,1-,32)
}

alias -l _plwin if ($window(@Playlist*,$1) != $active) if ($ifmatch) return $ifmatch | return
alias _pldo {
  var %num = 1
  :loop
  if ($sline($1,%num).ln) {
    if ($2 == -r) dline $1 $sline($1,%num).ln
    elseif ($2 == -c) {
      aline $3 $sline($1,%num)
      inc %num
    }
    elseif ($2 == -m) {
      aline $3 $sline($1,%num)
      dline $1 $sline($1,%num).ln
    }
    goto loop
  }
  if (@Playlist* iswm $1) _plupdt $1
  if (@Playlist* iswm $3) _plupdt $3
}
alias _plupdt titlebar $1 ( $+ $calc($line($1,0) - 3) files) $gettok($window($1).title,3-,32) | window -b $1
alias -l _plpl {
  if ($line($1,0) < 4) return
  var %num = 1,%file = $_temp($gettok($_splext,1,32))
  if ($2 == $null) savebuf $calc($line($1,0) - 3) $1 %file
  elseif ($2- == -) {
    write -c %file
    :loop
    if ($sline($1,%num)) {
      write %file $ifmatch
      inc %num | goto loop
    }
  }
  else write -c %file $2-
  _plplpl $mircdir $+ %file
}
alias -l _plplpl {
  var %file = $read -nl1 $1-,%type = $_sext(%file)
  if (%type == $null) _error Unrecognized sound file type in playlist- %ext See sound configuration for details.
  if (/* iswm $_scfg(%type,player)) _error Cannot playlist $_desc(%type) filesYou aren't using an external player
  .timer.squeue off
  if ($_scfg(%type,shortfn)) var %sound = $shortfn($1-)
  else var %sound = $1-
  var %player = $_scfg(%type,player)
  run $iif($_scfg(%type,minimize),-n) %player $iif(%player,") $+ %sound $+ $iif(%player,")
  if ($_scfg(%type,grabfocus)) .timer.grabfocus 4 1 if ($appactive == $!false) $chr(123) showmirc -s $chr(124) .timer.grabfocus off $chr(125)
}
alias -l _plpopdo {
  if ($window(@queue)) {
    if ($1 == 0) {
      var %num = 1
      :loopq1
      if ($sline($active,%num)) { squeue $ifmatch | inc %num | goto loopq1 }
      squeue start
    }
    elseif ($1 == 2) {
      var %num = 4
      :loopq2
      if ($line($active,%num)) { squeue $ifmatch | inc %num | goto loopq2 }
      squeue start
    }
    elseif ($1 == 1) { if ($line($active,0) > 3) { squeue $line($active,$calc($_pprand($calc($line($active,0) - 3)) + 3)) | squeue start } }
    elseif ($1 > 3) { squeue $line($active,$1) | squeue start }
  }
  else {
    if ($1 == 0) _plpl $active -
    elseif ($1 == 1) { if ($line($active,0) > 3) { _validst | sound %`soundtarg " $+ $line($active,$calc($_pprand($calc($line($active,0) - 3)) + 3)) $+ " - } }
    elseif ($1 == 2) _plpl $active
    elseif ($1 > 3) { _validst | sound %`soundtarg " $+ $line($active,$1) $+ " - }
  }
}
menu @Playlist {
  dclick:_plpopdo $1
  $_isstarg:{ }
  $_isstype:{ }
  $iif($window(@Queue),Queue,Playlist)
  .$iif($sline($active,1).ln > 3,Selected files):_plpopdo 0
  .Entire list:_plpopdo 2
  .One at random:_plpopdo 1
  .-
  .$iif($window(@Queue),Stop and close queue,Activate queue):if ($window(@Queue)) squeue close | else squeue -n
  Options
  .$_dynpop(%_s.cont) Continuous play:scont *
  .$_dynpopf Playing to... %.isstarg:starg
  .-
  .%.isstype1:_isstype 1
  .%.isstype2:_isstype 2
  .%.isstype3:_isstype 3
  .%.isstype4:_isstype 4
  .%.isstype5:_isstype 5
  .%.isstype6:stype
  -
  Edit
  .Add file...:loc -a $+ $remove($active,@Playlist) *
  .Add list...:loc -sa $+ $remove($active,@Playlist) *
  .Find files...:loc -a $+ $remove($active,@Playlist) * " $+ $_entry(0,$null,Find filenames containing or matching...?Enter words or a wildcard string) $+ "
  .-
  .$iif($sline($active,1).ln > 3,Remove):_pldo $active -r
  .-
  .$iif($sline($active,1).ln > 3,Copy to)
  ..$_plwin(1):_pldo $active -c $window(@Playlist*,1)
  ..$_plwin(2):_pldo $active -c $window(@Playlist*,2)
  ..$_plwin(3):_pldo $active -c $window(@Playlist*,3)
  ..-
  ..New list:var %old = $active,%win = $_newwin(@Playlist) | _window 2.4 -l -t1,46 %win $_winpos(8,12,10,10) @Playlist | _plban %win | _pldo %old -c %win
  .$iif($sline($active,1).ln > 3,Move to)
  ..$_plwin(1):_pldo $active -m $window(@Playlist*,1)
  ..$_plwin(2):_pldo $active -m $window(@Playlist*,2)
  ..$_plwin(3):_pldo $active -m $window(@Playlist*,3)
  ..-
  ..New list:var %old = $active,%win = $_newwin(@Playlist) | _window 2.4 -l -t1,46 %win $_winpos(8,12,10,10) @Playlist | _plban %win | _pldo %old -m %win
  .-
  .$iif($sline($active,1).ln > 3,Up):_doslideup $active 4
  .$iif($sline($active,1).ln > 3,Down):_doslidedn $active
  .$iif(($sline($active,0).ln > 1) && ($sline($active,1).ln > 3),Shuffle selected):_doshuffle $active 4
  .$iif($sline($active,0).ln < 2,Shuffle all):_doshufflea $active 4
  -
  $iif(($numtok($window($active).title,32) > 2) && ($line($active,0) > 3),Save list):savebuf $calc($line($active,0) - 3) $active " $+ $gettok($window($active).title,3-,32) $+ "
  $iif($line($active,0) > 3,Save as...):{
    var %file = $_sext($line($active,4)),%dir = $_scfg(%file,lastpdir)
    if (%dir == $null) %dir = $_scfg(%file,dir1)
    %file = %dir $+ *. $+ $gettok($_splext,1,32)
    %file = $dir="Save playlist to what file?" %file
    if (%file == $null) return
    ;;; insert overwrite/append check
    if (. !isin %file) %file = %file $+ . $+ $gettok($_splext,1,32)
    savebuf $calc($line($active,0) - 3) $active " $+ %file $+ "
    titlebar $active $gettok($window($active).title,1-2,32) %file
  }
}
dialog starg {
  title "Sound Target"
  size -1 -1 140 155
  text "Play sounds to:", 1, 3 3 130 20
  list 2, 0 24 140 110
  button "Select", 3, 21 131 97 21, default OK
  edit "", 4, 1 1 1 1, hide result autohs
}
on *:DIALOG:starg:init:*:{
  did -a $dname 2 (all channels)
  did -a $dname 2 (current window)
  did -a $dname 2 (self)
  did -a $dname 2 (quietly)
  var %num = $chan(0) | :loop1 | if (%num) { did -a $dname 2 $chan(%num) | dec %num | goto loop1 }
  %num = $chat(0) | :loop2 | if (%num) { did -a $dname 2 = $+ $chat(%num) | dec %num | goto loop2 }
  %num = $query(0) | :loop3 | if (%num) { did -a $dname 2 $query(%num) | dec %num | goto loop3 }
  if ($findtok(-c -a -s -q,%`soundtarg,1,32)) did -c $dname 2 $ifmatch
  elseif ($_finddid($dname,2,%`soundtarg)) did -c $dname 2 $ifmatch
}
on *:DIALOG:starg:dclick:2:dialog -k $dname
on *:DIALOG:starg:sclick:3:did -o $dname 4 1 $did(2,$did(2).sel)
alias starg {
  if ($1- == Status Window) `set soundtarg -s
  elseif ((* * iswm $1-) || (@* iswm $1)) return
  elseif ($1) `set soundtarg $1
  else `set soundtarg $$dialog(starg,starg,-4)
  if ($left(%`soundtarg,1) == $chr(40)) `set soundtarg - $+ $mid(casq,$pos(acsq,$mid(%`soundtarg,2,1),1),1)
  if (-? iswm %`soundtarg) disps Now playing sounds $gettok(to all channels.to active (current) window.to status window (yourself).quietly,$findtok(-c -a -s -q,%`soundtarg,1,32),46)
  else disprs %`soundtarg Now playing sounds to $:t(%`soundtarg)
}
; checks if %`soundtarg is still valid
; if $1 is null then we ask, otherwise we default to that
alias _validst {
  if (-? iswm %`soundtarg) return
  if (%`soundtarg ischan) return
  if ($query(%`soundtarg) != $null) return
  if ((=* iswm %`soundtarg) && ($chat($right(%`soundtarg,-1)) != $null)) return
  if ($1 == 0) `set soundtarg
  else starg $1
}
; save active in case we use -a as a target from a playlist/queue
alias _validsta if (($active ischan) || ($query($active)) || (=* iswm $active)) %_soundtarg2 = $active | elseif (Status Window == $acitve) %_soundtarg2 = -s

; Continuous
alias scont {
  if ($1 == *) %_s.cont = $_not(%_s.cont)
  elseif ($1) %_s.cont = $_o2tf($1)
  if (%_s.cont) {
    dispa Continuous sound playing is enabled.
    if ($dialog(sndpanel)) did -c sndpanel 10
  }
  else {
    dispa Continuous sound playing disabled.
    if ($window(@Queue) == $null) .timer.squeue off
    if ($dialog(sndpanel)) did -u sndpanel 10
  }
}
alias _scontchk {
  if ((%_s.cont) && ($window(@Queue) == $null)) {
    if ($1 == mp3) { mp3.prep $2- | .timer.squeue -o 1 $mp3.time($2-) _scontnext $1 }
    elseif ((($1 == wav) || ($1 == mid)) && ($_scfg($1,player) == /splay)) .timer.squeue -o 0 3 if (($inmidi == $!false) && ($inwave == $!false)) _scontnext $1
  }
  elseif ($window(@Queue) == $null) .timer.squeue off
}
alias -l _scontnext {
  if ((%_s.cont) && ($window(@Queue) == $null)) {
    _validst -a
    if ($line(@Playlist,0) > 3) sound %`soundtarg " $+ $line(@Playlist,$calc($_pprand($calc($line(@Playlist,0) - 3)) + 3)) $+ " -
    else loc -r $1 * %`soundtarg
  }
}

on *:LOAD:.sound on

;;; samples
alias f5 loc -c mp3 *
alias mp if ($1 == $null) loc mp3 | else if ((. isin $1-) || (: isin $1-) || (\ isin $1-)) loc mp3 " $+ $1-" | else loc mp3 "* $+ $replace($1-,$chr(32),*) $+ *"

;;; beta fix
on *:START:if ($exists($_cfg(sound.ini))) remini $_cfg(sound.ini) *