#!/usr/bin/liquidsoap

# No loggin for now
set("log.stdout",false)
set("log.file",false)

# Audio streamer implemented in liquidsoap
version = "08.11"

# Detect available outputs
outputs = [
%ifdef output.icecast.mp3
"shoutcast",
"icecast.mp3",
%endif
%ifdef output.icecast.vorbis
"icecast.vorbis",
%endif
"dummy"
]
outs = string.concat(separator=", ", outputs)

# Detect available inputs
inputs = [
%ifdef input.alsa
"alsa",
%endif
%ifdef input.jack
"jack",
%endif
"playlist",
"http",
"directory",
"file"
]
ins = string.concat(separator=", ", inputs)

transitions = [
"crossfade",
"smart_crossfade"
]
trs = string.concat(separator=", ", transitions)

failed = string.ref("false")
def is_failed() = 
  f = fst(failed)
  bool_of_string(f())
end
def shutdown() = 
  set = snd(failed)
  set(string_of(true))
  shutdown()
end

usage = "Usage: simpleliq [ -h ] [ -i input ] [ -o output ] [ -e effect] [ -t transition] [ -script ] [ -local ]
* -h displays this message
* Input can be: #{ins}
* Output can be: #{outs}
* Effect can be: none, compress, normalize, nrj (normalize+compress)
* Transition can be: #{trs}
* -script outputs the corresponding script
* -local plays the stream on the local soundcard
* -h, --help: print this message

Optional settings:

Settings for alsa input (if enabled):
* -alsa-device: set alsa input device (default: default)

Settings for jack input (if enabled):
* -jack-device: set jack input port name (default: simpleliq)

Settings for playlist, directory and file input:
* -uri: set default media source uri (default: false://)

Settings for Icecast output (if enabled):
* -host: set host (default: localhost)
* -port: set source destination port (default: 8080)
* -password: set source password (default: hackme)
* -genre: set source genre (default: savonet)
* -url: set source URL (default: http://savonet.sf.net)
* -description: set source description (default: Powered by liquidsoap)
* -stereo: stream stereo audio data (default: true)
* -bitrate: set bitrate for mp3 output (default: 128)
* -samplerate: set samplerate (default: 44100)
* -restart: try to restart the output after a failure (default: false)
* -quality: set quality, for vorbis output (default: 2.)
* -mount: set mountpoint (default: none)"


# Initial message
print("Starting simpleliq version #{version}")

# Get parameters
input = getopt(default="blank","-i")
output = getopt(default="dummy","-o")
effect = getopt(default="none","-e")
transition = getopt(default="none","-t")

# Get help option
help =
 if getopt("-h") == "1" or getopt("--help") == "1" then
  true
 else
  false
 end

# Initial script:
script = string.ref("")
script.get = fst(script)
script.set = snd(script)
script.set(
"#!/usr/bin/env liquidsoap
# Script generated by simpleliq

# Enable logging to stdout, disable logging to file
set('log.stdout',true)
set('log.file',false)

")

s = blank(id="none")
%ifdef input.alsa
s = 
  if input == "alsa" then
    device = getopt(default="default","-alsa-device")
    script.set(script.get() ^ 
"# Input alsa
s = input.alsa(device='#{device}')

")
    input.alsa(id="alsa",device=device)
  else
    s
  end
%endif
%ifdef input.jack
s = 
  if input == "jack" then
    device = getopt(default="simpleliq","-jack-device")
    script.set(script.get() ^
"#Input jack
s = input.jack(id='#{device}')

")
    input.jack(id=device)
  else
    s
  end
%endif
s = 
  if input != "input.jack" and input != "input.alsa" then
    uri = getopt(default="false://","-uri")
    if uri == "false://" then
      shutdown ()
    end
    if input == "playlist" then
      script.set(script.get() ^
"# Playlist input
s = playlist('#{uri}')

")
      playlist(id="playlist",uri)
    elsif input == "directory" then
      script.set(script.get() ^
"# Directory input
s = playlist('#{uri}')

")
      playlist(id="directory",uri)
    elsif input == "http" then
      script.set(script.get() ^
"# Http input
s = input.http('#{uri}')

")
      input.http(id="http",uri)
    elsif input == "file" then
      script.set(script.get() ^
"# File input
s = single('#{uri}')

")
      single(id="file",uri)
    else
      s
    end
  else
    s
  end

if source.id(s) == "dummy" then
  print("No valid input..")
  shutdown ()
end

# Getting effet
e = 
  if effect == "normalize" then
script.set(script.get() ^
"# Adding normalization
s = normalize(s)

")
    (effect,normalize)
  elsif effect == "compress" then
script.set(script.get() ^
"# Adding compression
s = compress(s)

")
    (effect,compress)
  elsif effect == "nrj" then
script.set(script.get() ^
"# Adding normalization and compression
s = nrj(s)

")
    (effect,nrj)
  else
    def id(s) = s end
    ("none",id)
  end

# Getting transition
t = 
  if transition == "crossfade" then
    start_next = float_of_string(getopt(default="7.","-start-next"))
    fade_in = float_of_string(getopt(default="5.","-fade-in"))
    fade_out = float_of_string(getopt(default="5.","-fade-out"))
    script.set(script.get() ^
"# Adding crossfade transitions
s = crossfade(start_next=#{start_next},fade_in=#{fade_in},
              fade_out=#{fade_out},s)

")
    (transition,crossfade(start_next=start_next,fade_in=fade_in,
                          fade_out=fade_out))
  elsif transition == "smart_crossfade" then
    script.set(script.get() ^
"# Adding smart_crossfade transitions
s = smart_crossfade(s)

")
    (transition,smart_crossfade)
  else
    def id(s) = s end
    ("none",id)
  end

# Getting output
script.set(script.get() ^
"# Making source infaillible
s = mksafe(s)

")
o = ("dummy",output.dummy(id="dummy"))
host = getopt(default="localhost","-host")
port = int_of_string(getopt(default="8000","-port"))
password = getopt(default="hackme","-password")
genre = getopt(default="savonet","-genre")
url = getopt(default="http://savonet.sf.net/","-url")
description = getopt(default="Powered by liquidsoap","-description")
stereo = bool_of_string(getopt(default="true","-stereo"))
bitrate = int_of_string(getopt(default="128","-bitrate"))
samplerate = int_of_string(getopt(default="44100","-samplerate"))
restart = bool_of_string(getopt(default="false","-restart"))
quality = float_of_string(getopt(default="2.","-quality"))
mount = getopt(default="none","-mount")
if mount == "none" and (output == "icecast.mp3" or output == "icecast.vorbis") then
  print("No mount point given for icecast output !")
  shutdown ()
end
%ifdef output.icecast.mp3
o = 
  if output == "shoutcast" then
    script.set(script.get() ^
"# Shoutcast output
output.shoutcast.mp3(bitrate=#{bitrate}, host='#{host}',
                     password='#{password}', genre='#{genre}',
                     url='#{url}', description='#{description}',
                     stereo=#{stereo}, bitrate=#{bitrate},
                     samplerate=#{samplerate},
                     restart=#{restart}, s)

")
    (output,
    output.shoutcast.mp3(id="shoutcast",bitrate=bitrate,
                         host=host,password=password,
                         genre=genre,url=url,description=description,
                         stereo=stereo,samplerate=samplerate,
                         restart=restart))
  elsif output == "icecast.mp3" then
    script.set(script.get() ^
"# MP3 icecast output
o = output.icecast.mp3(bitrate=#{bitrate}, host='#{host}',
                       password='#{password}', genre='#{genre}',
                       url='#{url}', 
		       description='#{description}',
                       stereo=#{stereo}, bitrate=#{bitrate},
                       samplerate=#{samplerate}, restart=#{restart}, 
                       mount='#{mount}', s)

")
    (output,
    output.icecast.mp3(id="icecast-mp3",bitrate=bitrate,
                       host=host,password=password,
                       genre=genre,url=url,description=description,
                       stereo=stereo,samplerate=samplerate,
                       restart=restart,mount=mount))
  else
    o
  end
%endif
%ifdef output.icecast.vorbis
o = 
  if output == "icecast.vorbis" then
    script.set(script.get() ^
"# Vorbis icecast output
o = output.icecast.vorbis(host='#{host}', password='#{password}',
                          genre='#{genre}', url='#{url}',
			  description='#{description}',
                          stereo=#{stereo}, quality=#{quality},
                          restart=#{restart}, mount='#{mount}',
			  s)

")
   (output,
    output.icecast.vorbis(id="icecast-vorbis",
                          host=host,password=password,
                          genre=genre,url=url,description=description,
                          stereo=stereo,quality=quality,
                          restart=restart,mount=mount))
  else
    o
  end
%endif
o = 
  if getopt("-local") == "1" then
    # Special case for local: added on top..
    print("Enabling local output..")
    script.set(script.get() ^
"# Adding local output
out(s)

")
    def f(s) = 
      ignore(out(s))
      f = snd(o)
      f(s)
    end
    (fst(o),f)
  else
    o
  end

# Add dummy output to script
if fst(o) == "dummy" then
  script.set(script.get() ^
"# Dummy output
output.dummy(s)

")
end

script.set(script.get() ^ "# That's all folks !")

# Print config
if not help then
  if not is_failed() then
    print("Streaming config:")
    print("Input:       #{source.id(s)}")
    print("Output:      #{fst(o)}")
    print("Effect:      #{fst(e)}")
    print("Transitions: #{fst(t)}")
    if getopt("-script") == "1" then
      print("Generated script:")
      print("8<--------------------------------->8")
      print(script.get())
      print("8<--------------------------------->8")
      shutdown ()
      blank()
    else
      print("Starting streaming...")
      set("log.stdout",true)
      e = snd(e)
      t = snd(t)
      o = snd(o)
      o(mksafe(t(e(s))))
    end
  else
    print("Something went wrong...")
    print("Start with --help to get some help.")
    shutdown ()
    blank ()
  end
else
  print(usage)
  shutdown()
  blank()
end
