Skip to content
Snippets Groups Projects
Commit 769716f8 authored by David Trattnig's avatar David Trattnig
Browse files

Merge branch 'lqs2-migration' into 'master'

Liquidsoap 2 migration

See merge request !3
parents 1da529ed ac51e20e
No related branches found
No related tags found
1 merge request!3Liquidsoap 2 migration
Pipeline #2183 passed
Showing
with 582 additions and 793 deletions
HDA
hda
occuring
fro
\ No newline at end of file
Gottfried Gaisbauer <gogo@servus.at> Gottfried <gogo@servus.at> Gottfried Gaisbauer <gogo@servus.at> Gottfried <gogo@servus.at>
Ingo Leindecker <ingo.leindecker@fro.at> ingo <ingo.leindecker@fro.at> Ingo Leindecker <ingo.leindecker@fro.at> ingo <ingo.leindecker@fro.at>
David Trattnig <david.trattnig@gmail.com> <david@subsquare.at> David Trattnig <david.trattnig@o94.at> <david@subsquare.at>
David Trattnig <david.trattnig@gmail.com> <david.trattnig@o94.at> David Trattnig <david.trattnig@o94.at> <david.trattnig@gmail.com>
David Trattnig <david.trattnig@gmail.com> david
Christian Pointner <equinox@helsinki.at> Christian Pointner <equinox@spreadspace.org> Christian Pointner <equinox@helsinki.at> Christian Pointner <equinox@spreadspace.org>
Ernesto Rico Schmidt <ernesto@helsinki.at> Ernesto Rico Schmidt <e.rico.schmidt@gmail.com> Ernesto Rico Schmidt <ernesto@helsinki.at> Ernesto Rico Schmidt <e.rico.schmidt@gmail.com>
Ernesto Rico Schmidt <ernesto@helsinki.at> nnrcschmdt <e.rico.schmidt@gmail.com> Ernesto Rico Schmidt <ernesto@helsinki.at> nnrcschmdt <e.rico.schmidt@gmail.com>
......
{ {
"search.exclude": { "search.exclude": {
"**/.git": true, "**/.git": true,
"**/tmp": true "**/tmp": true,
} "logs/**": true,
}
} }
\ No newline at end of file
FROM savonet/liquidsoap:v1.4.4 FROM savonet/liquidsoap:v2.1.0
LABEL maintainer="David Trattnig <david.trattnig@subsquare.at>" LABEL maintainer="David Trattnig <david.trattnig@subsquare.at>"
USER root USER root
# Dependencies & Utils # Dependencies & Utils
RUN apt update --allow-releaseinfo-change && apt -y install \ RUN apt update --allow-releaseinfo-change && \
apt -y --no-install-recommends install \
build-essential \
alsa-utils \ alsa-utils \
libssl-dev libssl-dev
# libgstreamer-ocaml-dev
# Setup Engine # Setup Engine
ENV TZ=Europe/Vienna
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN mkdir -p /srv/src RUN mkdir -p /srv/src
RUN mkdir -p /srv/tests RUN mkdir -p /srv/tests
RUN mkdir -p /srv/config RUN mkdir -p /srv/config
COPY src /srv/src COPY src /srv/src
COPY tests /srv/tests COPY tests /srv/tests
COPY run.sh /srv COPY config/sample.engine-core.docker.ini /srv/config/engine-core.ini
VOLUME ["/srv/socket", "/srv/logs", "/srv/audio/source", "/srv/audio/playlist", "/srv/audio/station"] COPY Makefile /srv/Makefile
COPY VERSION /srv/VERSION
VOLUME ["/srv/socket", "/srv/logs", "/srv/audio/source", "/srv/audio/playlist", "/srv/audio/fallback"]
#RUN chown -R liquidsoap:liquidsoap /srv #RUN chown -R liquidsoap:liquidsoap /srv
WORKDIR /srv WORKDIR /srv
# User liquodsoap has uid 10000 and gid 10001 # User Liquidsoap has UID 10000 and GID 10001
#USER liquidsoap #USER liquidsoap
# Start the Engine # Start the Engine
EXPOSE 1234/tcp EXPOSE 1234/tcp
ENTRYPOINT ["./run.sh", "prod"] ENTRYPOINT ["make"]
CMD ["core"] CMD ["run"]
\ No newline at end of file
Makefile 0 → 100644
-include build/base.Makefile
-include build/docker.Makefile
.PHONY: help
help:
@echo "$(APP_NAME) targets:"
@echo " init.dev - init development environment"
@echo " lint - verify code style"
@echo " spell - check spelling of text"
@echo " test - run test suite"
@echo " log - tail log file"
@echo " syslog - tail syslog file"
@echo " run - start app"
@echo " run.debug - start app in debug mode"
$(call docker_help)
# Settings
AURA_ENGINE_CORE_CONFIG := ${CURDIR}/config/engine-core.docker.ini
AURA_ENGINE_CORE_SOCKET := ${CURDIR}/socket
AURA_AUDIO_STORE := ${CURDIR}/audio
AURA_AUDIO_STORE_SOURCE := ${AURA_AUDIO_STORE}/source
AURA_AUDIO_STORE_FALLBACK := ${AURA_AUDIO_STORE}/fallback
AURA_AUDIO_STORE_PLAYLIST := ${AURA_AUDIO_STORE}/playlist
DOCKER_RUN = @docker run \
--name $(APP_NAME) \
--network="host" \
--mount type=tmpfs,destination=/tmp \
--device /dev/snd \
--group-add audio \
-v "$(AURA_ENGINE_CORE_CONFIG)":"/srv/config/engine-core.ini":ro \
-v "$(AURA_ENGINE_CORE_SOCKET)":"/srv/socket" \
-v "$(AURA_AUDIO_STORE_SOURCE)":"/var/audio/source":ro \
-v "$(AURA_AUDIO_STORE_PLAYLIST)":"/var/audio/playlist":ro \
-v "$(AURA_AUDIO_STORE_FALLBACK)":"/var/audio/fallback":ro \
-u $(UID):$(GID) \
$(DOCKER_ENTRY_POINT) \
autoradio/$(APP_NAME)
# Targets
.PHONY: lint
lint:
liquidsoap --check src/engine.liq
.PHONY: spell
spell: SPELL_PATHS := $(wildcard *.md) docs src tests config contrib
spell: SPELL_PATHS_SKIP := src/archive
spell: SPELL_IGNORE_FILE := .codespellignore
spell:
codespell --ignore-words "$(SPELL_IGNORE_FILE)" --skip "$(SPELL_PATHS_SKIP)" $(SPELL_PATHS)
.PHONY: init.dev
init.dev:
sudo apt install -y
codespell
.PHONY: test
test:
(cd tests && liquidsoap engine_test_suite.liq)
.PHONY: log
log:
tail -f logs/$(APP_NAME).log
.PHONY: run
run:
(cd src && liquidsoap ./engine.liq)
.PHONY: run.debug
run.debug:
(cd src && liquidsoap --verbose --debug ./engine.liq)
# AURA Engine Core # AURA Engine Core
<img src="https://gitlab.servus.at/autoradio/meta/-/raw/master/assets/images/aura-engine.png" width="250" align="right" /> <img src="https://gitlab.servus.at/autoradio/meta/-/raw/main/assets/images/aura-engine.png" width="250" align="right" />
AURA Engine Core is a play-out server for radio stations based on [Liquidsoap](https://www.liquidsoap.info/).
For full utilization Engine Core might be combined with [Engine](https://gitlab.servus.at/aura/engine) providing a managment, monitoring and scheduling layer atop. Engine Core provides following features out of the box:
- **Play audio from various sources** including files, streams and analog live audio
- **Analog audio or digital stream output** which is able to connect to an Icecast Server. It allows to stream to multiple Icecast Servers simultaniousely including sending of meta information using the *Icy* protocol.
- **Auto DJ** triggered by a silence detector to avoid [Dead Air](https://en.wikipedia.org/wiki/Dead_air). Play randomized music from a folder or M3U playlist.
- **ReplayGain** normalization done using passed [ReplayGain](https://en.wikipedia.org/wiki/ReplayGain) meta data.
- **Track Service** notifications when used in conjunction with [Engine API](https://gitlab.servus.at/aura/engine-api)
This project is part of [Aura Radio Software Suite](https://gitlab.servus.at/aura/meta), specifically build for the requirements of community radio stations. AURA Engine Core is a multi-channel playout server for radio stations based on [Liquidsoap](https://www.liquidsoap.info/).
<!-- TOC --> This documentation is meant for developers. For using the AURA Community Radio Suite check out the [aura.radio](https://docs.aura.radio/)
1. [AURA Engine Core](#aura-engine-core) ## Prerequisites
1. [Prerequisites](#prerequisites)
2. [Quickstart](#quickstart)
3. [Audio Store](#audio-store)
4. [Advanced Configuration](#advanced-configuration)
5. [Logging](#logging)
6. [Other AURA Components](#other-aura-components)
7. [Read more](#read-more)
8. [About](#about)
<!-- /TOC --> Before you begin, ensure you have met the following requirements:
## Prerequisites - Operating system: Debian 11, Ubuntu 20.04 or newer
- [Liquidsoap 2.1.x](https://www.liquidsoap.info/) installed using [OPAM (OCaml Package Manager)](https://opam.ocaml.org/)
- git
- make
To [install the AURA Suite](https://gitlab.servus.at/aura/meta) we recommend using [Docker](https://www.docker.com/) and [Docker Compose](https://docs.docker.com/compose/). ## Installation
> IMPORTANT: For live audio input inside Docker there are currently buffer and latency issues. After the [move the Liquidsoap 2.0](https://gitlab.servus.at/aura/engine-core/-/issues/4) it should be somewhat better. Also looking for tips on how to solve these issues. Therefore we right now recommend to do a bare-metal installation for *Engine Core*. If you don't require analog audio input you can safely use Docker. All other AURA components can be deployed using Docker though. Install system dependencies:
You'll need to have following installed before proceeding: ```bash
apt install curl alsa-utils libasound2-dev libavcodec-dev libavdevice-dev libavformat-dev libavutil-dev libflac-dev libjack-dev libpulse-dev libswresample-dev libswscale-dev libssl-dev ffmpeg opam
```
- [git](https://git-scm.com/) Build Liquidsoap with additional libraries:
- `apt-get install curl alsa-utils libasound2-dev libavcodec-dev libavdevice-dev libavformat-dev libavutil-dev libflac-dev libjack-dev libpulse-dev libswresample-dev libswscale-dev libssl-dev ffmpeg opam`
- [Liquidsoap 1.4.4](https://www.liquidsoap.info/doc-1.4.4/install.html) installed using [OPAM (OCaml Package Manager)](https://opam.ocaml.org/) and these additional dependencies:
- `opam depext alsa pulseaudio bjack ssl ffmpeg samplerate flac taglib mad lame vorbis flac opus cry liquidsoap.1.4.4 -y`
- `opam install alsa pulseaudio bjack ssl ffmpeg samplerate flac taglib mad lame vorbis flac opus cry liquidsoap.1.4.4 -y`
Download a zipped version from the [*Engine Core* repository](https://gitlab.servus.at/aura/engine-core) page or clone some specific branch or tag using `git` to a local `aura/engine-core` directory. In order to allow easy updating we recommend the git approach. ```bash
opam depext alsa pulseaudio bjack ffmpeg samplerate flac taglib mad lame vorbis flac opus cry ocurl liquidsoap -y
opam install alsa pulseaudio bjack ffmpeg samplerate flac taglib mad lame vorbis flac opus cry ocurl liquidsoap -y
```
## Quickstart ## Quickstart
Perform following commands inside the `engine-core` directory: After cloning the project perform following commands inside the project directory:
1. Create an initial configuration file based on an sample config: `cp config/sample-production.engine-core.ini config/engine-core.ini` 1. Create an initial configuration file based on an sample config: `cp config/sample.engine-core.ini config/engine-core.ini`
2. Create the folder structure `./audio/fallback/` in the project root and populate `fallback` with some music files. This folder is picked up as a so-called *Station Fallback* in case no other music is scheduled or if silence is detected. 2. Create the folder structure `./audio/fallback/` in the project root and populate `fallback` with some music files. This folder is picked up as a so-called _Station Fallback_ in case no other music is scheduled or if silence is detected.
3. Execute `./run.sh` to get the *Engine Core* server running. Voilá, you should hear some music! 3. Execute `make run` to get the _Engine Core_ server running. Voilá, you should hear some music!
If the audio device desired for playback is set as `default`, the Engine now should be ready to play sound. If you are not hearing any sound set a working output device for `output_device_0` in `engine-core.ini` and carefully review the logs. If the audio device desired for playback is set as `default`, the Engine now should be ready to play sound. If you are not hearing any sound set a working output device for `output_device_0` in `engine-core.ini` and carefully review the logs.
...@@ -62,26 +46,38 @@ After this is working you might be ready for a more sophisticated setup of the e ...@@ -62,26 +46,38 @@ After this is working you might be ready for a more sophisticated setup of the e
## Audio Store ## Audio Store
The aformentioned `audio` folder is the base for retrieving audio files. Engine Core is referencing three folders from this so-called *Audio Store*: The aforementioned `audio` folder is the base for retrieving audio files. Engine Core is referencing three folders from this so-called _Audio Store_:
- **`audio/fallback/`**: A local folder for any emergency playback, also called *Station Fallback*. All audio files inside are played in a randomized order, if no actually scheduled music is played by the engine. The folder is being watched for changes. So you can add/remove audio on the fly. This fallback feature is enabled by default. - **`audio/fallback/`**: A local folder for any emergency playback, also called _Station Fallback_. All audio files inside are played in a randomized order, if no actually scheduled music is played by the engine. The folder is being watched for changes. So you can add/remove audio on the fly. This fallback feature is enabled by default.
- **`audio/playlist/`**: Put a file `station-fallback-playlist.m3u` in here and it has the same effect as the fallback folder. - **`audio/playlist/`**: Put a file `station-fallback-playlist.m3u` in here and it has the same effect as the fallback folder.
he playlist is being watched for changes. Set `fallback_type="playlist"` to enable this instead of the fallback folder. he playlist is being watched for changes. Set `fallback_type="playlist"` to enable this instead of the fallback folder.
- **`audio/source/`**: This is the location for audio files provided by [Tank](https://gitlab.servus.at/aura/tank). Usually any audio files which are part of the scheduled programme are read for their broadcast from here. If you are running all AURA components on a single machine you should be fine with just creating a symbolic link to the relevant Tank folder (`ln -s ../engine/audio ./audio`). But in some [distributed and redundant production scenario](https://gitlab.servus.at/aura/meta/-/blob/master/docs/administration/installation-guide.md) you might think about more advanced options on how to sync your audio files between machines. You can find some ideas in the doc " [Setting up the Audio Store](https://gitlab.servus.at/aura/meta/-/blob/master/docs/administration/setup-audio-store.md)". - **`audio/source/`**: This is the location for audio files provided by [Tank](https://gitlab.servus.at/aura/tank). Usually any audio files which are part of the scheduled programme are read from here to perform broadcasts. If you are running all AURA components on a single machine you should be fine with just creating a symbolic link to the relevant Tank folder (`ln -s ../engine/audio ./audio`). But in some [distributed and redundant production scenario](https://docs.aura.radio/en/latest/administration/deployment-scenarios.html) you might think about more advanced options on how to sync your audio files between machines. You can find some ideas in the doc " [Setting up the Audio Store](https://docs.aura.radio/en/latest/administration/setup-audio-store.html)".
## Advanced Configuration ## Configuration
By default only audio output is enabled using the systems default device. If you want to use another audio interface or enable live audio, check the [Audio Device Configuration](docs/audio-device-configuration.md) document. By default only audio output is enabled using the systems default device. If you want to use another audio interface or enable live audio, check the [Audio Device Configuration](docs/audio-device-configuration.md) document.
Also review the other settings in your `engine-core.ini` to fine-tune the heart of your engine. If you are experiencing issues also check out the [Frequently Asked Questions (FAQ)](docs/frequently-asked-questions.md). Also review the other settings in your `engine-core.ini` to fine-tune the heart of your engine. If you are experiencing issues also check out the [Frequently Asked Questions (FAQ)](docs/frequently-asked-questions.md).
## Logging ## Channel Routing
The Engine Core logs can be found under `./logs`. Following diagram shows existing channels and their routing.
## Other AURA Components ```mermaid
graph TD
After successfully running Engine Core you might look into getting started with [the other Engine Components](https://gitlab.servus.at/aura/engine) and [AURA Web](https://gitlab.servus.at/aura/meta). iq0[Queue A] -->|in_queue_0| mix
iq1[Queue B] -->|in_queue_1| mix
is0[Stream A] -->|in_stream_0| mix
is1[Stream B] -->|in_stream_1| mix
il0[Line In 1-5] -->|in_line_0..4| mix
ff[Fallback Folder] -->|fallback_folder| which_fallback
fpls[Fallback Playlist] -->|fallback_playlist| which_fallback
mix[" Mixer "] --> silence_detector
which_fallback{or} -->| | silence_detector{Silence Detector}
silence_detector -->| | output[Output]
output --> |output.alsa| C[fa:fa-play Audio Interface]
output --> |output.icecast| D[fa:fa-play Icecast]
```
## Read more ## Read more
...@@ -90,10 +86,8 @@ After successfully running Engine Core you might look into getting started with ...@@ -90,10 +86,8 @@ After successfully running Engine Core you might look into getting started with
## About ## About
[<img src="https://gitlab.servus.at/autoradio/meta/-/raw/master/assets/images/aura-logo.png" width="150" />](https://gitlab.servus.at/aura/meta) [<img src="https://gitlab.servus.at/autoradio/meta/-/raw/main/assets/images/aura-logo.png" width="150" />](https://aura.radio)
AURA stands for Automated Radio and is a swiss army knife for community radio stations. Beside the Engine it provides Steering (Admin Interface for the radio station), Dashboard (Collaborative scheduling and programme coordination), Tank (Audio uploading, pre-processing and delivery). Read more in the [Aura Meta](https://gitlab.servus.at/aura/meta) repository or on the specific project pages. ```
| [<img src="https://gitlab.servus.at/aura/meta/-/raw/master/assets/images/aura-steering.png" width="150" align="left" />](https://gitlab.servus.at/aura/steering) | [<img src="https://gitlab.servus.at/aura/meta/-/raw/master/assets/images/aura-dashboard.png" width="150" align="left" />](https://gitlab.servus.at/aura/dashboard) | [<img src="https://gitlab.servus.at/aura/meta/-/raw/master/assets/images/aura-tank.png" width="150" align="left" />](https://gitlab.servus.at/aura/tank) | [<img src="https://gitlab.servus.at/aura/meta/-/raw/master/assets/images/aura-engine.png" width="150" align="left" />](https://gitlab.servus.at/aura/engine) | ```
|---|---|---|---|
| [Steering](https://gitlab.servus.at/aura/steering) | [Dashboard](https://gitlab.servus.at/aura/dashboard)<br/>[Dashboard Clock](https://gitlab.servus.at/aura/dashboard-clock) | [Tank](https://gitlab.servus.at/aura/tank) | [Engine](https://gitlab.servus.at/aura/engine)<br/>[Engine Core](https://gitlab.servus.at/aura/engine-core)<br/>[Engine API](https://gitlab.servus.at/aura/engine-api) |
1.0.0-alpha1-dev
\ No newline at end of file
# Base config for AURA Makefiles
# Include this at the top of other Makesfiles
.DEFAULT_GOAL := help
APP_NAME := $(shell basename $(dir $(abspath $(dir $$PWD/Makefile))))
\ No newline at end of file
# Docker targets for AURA Makefiles
# Help
define docker_help
@echo " docker.build - build docker image"
@echo " docker.push - push docker image"
@echo " docker.run - start app in container"
@echo " docker.run.i - start app in container (interactive mode)"
@echo " docker.run.bash - start bash in container"
@echo " docker.restart - restart container"
@echo " docker.stop - stop container"
@echo " docker.rm - stop and remove container"
@echo " docker.log - container logs for app"
@echo " docker.bash - enter bash in running container"
endef
# Dependencies
docker.deps:
@which docker
# Targets
.PHONY: docker.build
docker.build: docker.deps
@docker build -t autoradio/$(APP_NAME) .
.PHONY: docker.push
docker/push: docker.deps
@docker push autoradio/$(APP_NAME)
.PHONY: docker.run
docker.run: DOCKER_ENTRY_POINT := -d
docker.run: docker.deps
$(DOCKER_RUN)
.PHONY: docker.run.i
docker.run.i: DOCKER_ENTRY_POINT := -it
docker.run.i: docker.deps
$(DOCKER_RUN)
.PHONY: docker.run.bash
docker.run.bash: DOCKER_ENTRY_POINT := -v "$(CURDIR)":"/srv" --entrypoint bash -it
docker.run.bash: docker.deps
$(DOCKER_RUN)
.PHONY: docker.restart
docker.restart: docker.deps
@docker restart $(APP_NAME)
.PHONY: docker.stop
docker.stop: docker.deps
@docker stop $(APP_NAME)
.PHONY: docker.rm
docker.rm: docker.stop
@docker rm $(APP_NAME)
.PHONY: docker.log
docker.log: docker.deps
@docker logs $(APP_NAME) -f
.PHONY: docker.bash
docker.bash: docker.deps
@docker exec -it $(APP_NAME) bash
##############################################
# Engine-Core Configuration #
##############################################
# Note: Paths are relative to the 'src' folder
[general]
# File Socket to control engine-core externally (e.g. by 'engine')
socketdir="../socket"
# Host and port of the engine backchannel (Network Socket for e.g. sending track service updates)
engine_control_host="localhost:1337"
# Log directory absolute or relative from the "src" dir
logdir="../logs"
# Possible values are from "1" (INFO) to "5" (DEBUG)
log_level="3"
# Allow Liquidsoap to run as root (required for Docker)
liquidsoap_as_root="false"
[audio]
# This is the folder where fallback playlists are read from (optional)
audio_playlist_folder="../audio/playlist"
# Sets the time how long we have to fade in and out, when we select another mixer input values are in seconds
fade_in_time="1.5"
fade_out_time="1.5"
# Fallback type: "folder", "playlist" or "none"
fallback_type="folder"
# A playlist holding music for Station Fallbacks (optional)
fallback_music_playlist= "station-fallback-playlist.m3u"
# A folder holding music for Station Fallbacks (optional)
fallback_music_folder="../audio/fallback"
# The time in seconds how often the folder should be re-scanned
# Do not reload too often when using large folders
fallback_music_folder_reload="300"
# Maximum time of blank from source (defaults to 20., seconds, float)
fallback_max_blank="15."
# Minimum duration of noise on source to switch back over (defaults to 0, seconds, float)
fallback_min_noise="0."
# Power in dB under which the stream is considered silent (defaults to -40., float)
fallback_threshold="-80."
[soundcard]
# Choose your weapon: "alsa" (1 input/output), "pulseaudio" (multi input/output) or "jack" (multi input/output)
soundsystem="alsa"
# With 'alsa' you have to write the devicenames like 'default' to use the system default or 'hw:0' to use the 1st audio device directly.
# With Pulse Audio and Jack => an non empty value means it is used
# Devices with empty string are ignored and not used
input_device_0=""
input_device_1=""
input_device_2=""
input_device_3=""
input_device_4=""
# Same same, but different
output_device_0="default"
output_device_1=""
output_device_2=""
output_device_3=""
output_device_4=""
# ADVANCED ALSA SETTINGS - Defaults are recommended; you might need to tweak these values if you're hearing jitter, cracklings or other artifacts or having generally bad latency
#
# Buffered audio is quite simple to setup but has some latency; Unbuffered provides low latency but requires a valid frame size.
alsa_use_buffer="true"
# Usually provided by your device
alsa_sample_rate=""
# Set to 0 to use the ALSA default. If using hardware directly (hw:0) start with 8192. Higher values give higher latency and lower CPU usage.
alsa_buffer="8192"
# Only used for buffered ALSA I/O, and affects latency. Probably not wanted for live audio. Defaults to "1".
alsa_buffer_length="10"
# Set to 0 or leave empty to use the ALSA default.
alsa_periods=""
# Frame Size ("frame.audio.size") is provided by ALSA and is specific to your Audio Device. Needs to manually obtained and set correctly.
alsa_frame_size="2048"
# Tentative frame duration in seconds, defaults to "0.04" (Float). This setting is used as a hint for the duration,
# when ‘frame_size’ is not provided. It's required for getting things in sync, but it's actually tricky to set correctly.
alsa_frame_duration=""
[stream]
# defines enabled or not
stream_0="n"
# possible values: flac, mp3, ogg, opus (depending on which liquidsoap plugins you've installed)
stream_0_encoding="ogg"
# bitrate (with encoding types without bitrate like flac or ogg it is substituted. 32 => very poor quality. 320 => very high quality)
stream_0_bitrate="128"
# how many channels? everything else than 2 is considered as mono
stream_0_channels="2"
# to where we are streaming..?
stream_0_host="localhost"
# and which port?
stream_0_port="8888"
# the name of the mountpoint
stream_0_mountpoint="aura-test-0.ogg"
# username
stream_0_user="source"
# and the password
stream_0_password="source"
# stream url
stream_0_url="http://www.fro.at"
# the name of the stream
stream_0_name="AURA Test Stream 0"
# the genre of the stream
stream_0_genre="mixed"
# description of the stream
stream_0_description="Test Stream 0"
stream_1="n"
stream_1_encoding="flac"
stream_1_bitrate="128"
stream_1_channels="2"
stream_1_host="localhost"
stream_1_port="8888"
stream_1_mountpoint="aura-test-1.flac"
stream_1_user="source"
stream_1_password="source"
stream_1_url="http://www.fro.at"
stream_1_name="AURA Test Stream 1"
stream_1_genre="mixed"
stream_1_description="Test Stream 1"
stream_2="n"
stream_2_encoding="mp3"
stream_2_bitrate="64"
stream_2_channels="2"
stream_2_host="localhost"
stream_2_port="8888"
stream_2_mountpoint="aura-test-2.mp3"
stream_2_user="source"
stream_2_password="source"
stream_2_url="http://www.fro.at"
stream_2_name="AURA Test Stream 2"
stream_2_genre="mixed"
stream_2_description="Test Stream 2"
stream_3="n"
stream_3_encoding="ogg"
stream_3_bitrate="64"
stream_3_channels="2"
stream_3_host="localhost"
stream_3_port="8888"
stream_3_mountpoint="aura-test-3.ogg"
stream_3_user="source"
stream_3_password="source"
stream_3_url="http://www.fro.at"
stream_3_name="AURA Test Stream 3"
stream_3_genre="mixed"
stream_3_description="Test Stream 3"
stream_4="n"
stream_4_encoding="opus"
stream_4_bitrate="64"
stream_4_channels="2"
stream_4_host="localhost"
stream_4_port="8888"
stream_4_mountpoint="aura-test-4.opus"
stream_4_user="source"
stream_4_password="source"
stream_4_url="http://www.fro.at"
stream_4_name="AURA Test Stream 3"
stream_4_genre="mixed"
stream_4_description="Test Stream 3"
##############################################
# Engine-Core Configuration #
##############################################
# Note: Paths are relative to the 'src' folder
[general]
# File Socket to control engine-core externally (e.g. by 'engine')
socketdir="../socket"
# Host and port of the engine backchannel (Network Socket for e.g. sending track service updates)
engine_control_host="0.0.0.0:1337"
# Log directory absolute or relative from the "src" dir
logdir="../logs"
# Possible values are from "1" (INFO) to "5" (DEBUG)
log_level="3"
# Allow Liquidsoap to run as root (required for Docker)
liquidsoap_as_root="true"
[audio]
# This is the folder where fallback playlists are read from (optional)
audio_playlist_folder="../audio/playlist"
# Sets the time how long we have to fade in and out, when we select another mixer input values are in seconds
fade_in_time="1.5"
fade_out_time="1.5"
# Fallback type: "folder", "playlist" or "none"
fallback_type="folder"
# A playlist holding music for Station Fallbacks (optional)
fallback_music_playlist= "station-fallback-playlist.m3u"
# A folder holding music for Station Fallbacks (optional)
fallback_music_folder="../audio/fallback"
# The time in seconds how often the folder should be re-scanned
# Do not reload too often when using large folders
fallback_music_folder_reload="300"
# Maximum time of blank from source (defaults to 20., seconds, float)
fallback_max_blank="15."
# Minimum duration of noise on source to switch back over (defaults to 0, seconds, float)
fallback_min_noise="0."
# Power in dB under which the stream is considered silent (defaults to -40., float)
fallback_threshold="-80."
[soundcard]
# Choose your weapon: "alsa" (1 input/output), "pulseaudio" (multi input/output) or "jack" (multi input/output)
soundsystem="alsa"
# With 'alsa' you have to write the devicenames like 'default' to use the system default or 'hw:0' to use the 1st audio device directly.
# With Pulse Audio and Jack => an non empty value means it is used
# Devices with empty string are ignored and not used
input_device_0=""
input_device_1=""
input_device_2=""
input_device_3=""
input_device_4=""
# Same same, but different
output_device_0="default"
output_device_1=""
output_device_2=""
output_device_3=""
output_device_4=""
# ADVANCED ALSA SETTINGS - Defaults are recommended; you might need to tweak these values if you're hearing jitter, cracklings or other artifacts or having generally bad latency
#
# Buffered audio is quite simple to setup but has some latency; Unbuffered provides low latency but requires a valid frame size.
alsa_use_buffer="true"
# Usually provided by your device
alsa_sample_rate=""
# Set to 0 to use the ALSA default. If using hardware directly (hw:0) start with 8192. Higher values give higher latency and lower CPU usage.
alsa_buffer="8192"
# Only used for buffered ALSA I/O, and affects latency. Probably not wanted for live audio. Defaults to "1".
alsa_buffer_length="10"
# Set to 0 or leave empty to use the ALSA default.
alsa_periods=""
# Frame Size ("frame.audio.size") is provided by ALSA and is specific to your Audio Device. Needs to manually obtained and set correctly.
alsa_frame_size="2048"
# Tentative frame duration in seconds, defaults to "0.04" (Float). This setting is used as a hint for the duration,
# when ‘frame_size’ is not provided. It's required for getting things in sync, but it's actually tricky to set correctly.
alsa_frame_duration=""
[stream]
# defines enabled or not
stream_0="n"
# possible values: flac, mp3, ogg, opus (depending on which liquidsoap plugins you've installed)
stream_0_encoding="ogg"
# bitrate (with encoding types without bitrate like flac or ogg it is substituted. 32 => very poor quality. 320 => very high quality)
stream_0_bitrate="128"
# how many channels? everything else than 2 is considered as mono
stream_0_channels="2"
# to where we are streaming..?
stream_0_host="localhost"
# and which port?
stream_0_port="8888"
# the name of the mountpoint
stream_0_mountpoint="aura-test-0.ogg"
# username
stream_0_user="source"
# and the password
stream_0_password="source"
# stream url
stream_0_url="http://www.fro.at"
# the name of the stream
stream_0_name="AURA Test Stream 0"
# the genre of the stream
stream_0_genre="mixed"
# description of the stream
stream_0_description="Test Stream 0"
stream_1="n"
stream_1_encoding="flac"
stream_1_bitrate="128"
stream_1_channels="2"
stream_1_host="localhost"
stream_1_port="8888"
stream_1_mountpoint="aura-test-1.flac"
stream_1_user="source"
stream_1_password="source"
stream_1_url="http://www.fro.at"
stream_1_name="AURA Test Stream 1"
stream_1_genre="mixed"
stream_1_description="Test Stream 1"
stream_2="n"
stream_2_encoding="mp3"
stream_2_bitrate="64"
stream_2_channels="2"
stream_2_host="localhost"
stream_2_port="8888"
stream_2_mountpoint="aura-test-2.mp3"
stream_2_user="source"
stream_2_password="source"
stream_2_url="http://www.fro.at"
stream_2_name="AURA Test Stream 2"
stream_2_genre="mixed"
stream_2_description="Test Stream 2"
stream_3="n"
stream_3_encoding="ogg"
stream_3_bitrate="64"
stream_3_channels="2"
stream_3_host="localhost"
stream_3_port="8888"
stream_3_mountpoint="aura-test-3.ogg"
stream_3_user="source"
stream_3_password="source"
stream_3_url="http://www.fro.at"
stream_3_name="AURA Test Stream 3"
stream_3_genre="mixed"
stream_3_description="Test Stream 3"
stream_4="n"
stream_4_encoding="opus"
stream_4_bitrate="64"
stream_4_channels="2"
stream_4_host="localhost"
stream_4_port="8888"
stream_4_mountpoint="aura-test-4.opus"
stream_4_user="source"
stream_4_password="source"
stream_4_url="http://www.fro.at"
stream_4_name="AURA Test Stream 3"
stream_4_genre="mixed"
stream_4_description="Test Stream 3"
##############################################
# Engine-Core Configuration #
##############################################
# Note: Paths are relative to the 'src' folder
[general]
# File Socket to control engine-core externally (e.g. by 'engine')
socketdir="../socket"
# Host and port of the engine backchannel (Network Socket for e.g. sending track service updates)
engine_control_host="localhost:1337"
# Log directory absolute or relative from the "src" dir
logdir="../logs"
# Possible values are from "1" (INFO) to "5" (DEBUG)
log_level="3"
# Allow Liquidsoap to run as root (required for Docker)
liquidsoap_as_root="false"
[audio]
# This is the folder where fallback playlists are read from (optional)
audio_playlist_folder="../audio/playlist"
# Sets the time how long we have to fade in and out, when we select another mixer input values are in seconds
fade_in_time="1.5"
fade_out_time="1.5"
# Fallback type: "folder", "playlist" or "none"
fallback_type="folder"
# A playlist holding music for Station Fallbacks (optional)
fallback_music_playlist= "station-fallback-playlist.m3u"
# A folder holding music for Station Fallbacks (optional)
fallback_music_folder="../audio/fallback"
# The time in seconds how often the folder should be re-scanned
# Do not reload too often when using large folders
fallback_music_folder_reload="300"
# Maximum time of blank from source (defaults to 20., seconds, float)
fallback_max_blank="15."
# Minimum duration of noise on source to switch back over (defaults to 0, seconds, float)
fallback_min_noise="0."
# Power in dB under which the stream is considered silent (defaults to -40., float)
fallback_threshold="-80."
[soundcard]
# Choose your weapon: "alsa" (1 input/output), "pulseaudio" (multi input/output) or "jack" (multi input/output)
soundsystem="alsa"
# With 'alsa' you have to write the devicenames like 'default' to use the system default or 'hw:0' to use the 1st audio device directly.
# With Pulse Audio and Jack => an non empty value means it is used
# Devices with empty string are ignored and not used
input_device_0=""
input_device_1=""
input_device_2=""
input_device_3=""
input_device_4=""
# Same same, but different
output_device_0="default"
output_device_1=""
output_device_2=""
output_device_3=""
output_device_4=""
# ADVANCED ALSA SETTINGS - Defaults are recommended; you might need to tweak these values if you're hearing jitter, cracklings or other artifacts or having generally bad latency
#
# Buffered audio is quite simple to setup but has some latency; Unbuffered provides low latency but requires a valid frame size.
alsa_use_buffer="true"
# Usually provided by your device
alsa_sample_rate=""
# Set to 0 to use the ALSA default. If using hardware directly (hw:0) start with 8192. Higher values give higher latency and lower CPU usage.
alsa_buffer="8192"
# Only used for buffered ALSA I/O, and affects latency. Probably not wanted for live audio. Defaults to "1".
alsa_buffer_length="10"
# Set to 0 or leave empty to use the ALSA default.
alsa_periods=""
# Frame Size ("frame.audio.size") is provided by ALSA and is specific to your Audio Device. Needs to manually obtained and set correctly.
alsa_frame_size="2048"
# Tentative frame duration in seconds, defaults to "0.04" (Float). This setting is used as a hint for the duration,
# when ‘frame_size’ is not provided. It's required for getting things in sync, but it's actually tricky to set correctly.
alsa_frame_duration=""
[stream]
# defines enabled or not
stream_0="n"
# possible values: flac, mp3, ogg, opus (depending on which liquidsoap plugins you've installed)
stream_0_encoding="ogg"
# bitrate (with encoding types without bitrate like flac or ogg it is substituted. 32 => very poor quality. 320 => very high quality)
stream_0_bitrate="128"
# how many channels? everything else than 2 is considered as mono
stream_0_channels="2"
# to where we are streaming..?
stream_0_host="localhost"
# and which port?
stream_0_port="8888"
# the name of the mountpoint
stream_0_mountpoint="aura-test-0.ogg"
# username
stream_0_user="source"
# and the password
stream_0_password="source"
# stream url
stream_0_url="http://www.fro.at"
# the name of the stream
stream_0_name="AURA Test Stream 0"
# the genre of the stream
stream_0_genre="mixed"
# description of the stream
stream_0_description="Test Stream 0"
stream_1="n"
stream_1_encoding="flac"
stream_1_bitrate="128"
stream_1_channels="2"
stream_1_host="localhost"
stream_1_port="8888"
stream_1_mountpoint="aura-test-1.flac"
stream_1_user="source"
stream_1_password="source"
stream_1_url="http://www.fro.at"
stream_1_name="AURA Test Stream 1"
stream_1_genre="mixed"
stream_1_description="Test Stream 1"
stream_2="n"
stream_2_encoding="mp3"
stream_2_bitrate="64"
stream_2_channels="2"
stream_2_host="localhost"
stream_2_port="8888"
stream_2_mountpoint="aura-test-2.mp3"
stream_2_user="source"
stream_2_password="source"
stream_2_url="http://www.fro.at"
stream_2_name="AURA Test Stream 2"
stream_2_genre="mixed"
stream_2_description="Test Stream 2"
stream_3="n"
stream_3_encoding="ogg"
stream_3_bitrate="64"
stream_3_channels="2"
stream_3_host="localhost"
stream_3_port="8888"
stream_3_mountpoint="aura-test-3.ogg"
stream_3_user="source"
stream_3_password="source"
stream_3_url="http://www.fro.at"
stream_3_name="AURA Test Stream 3"
stream_3_genre="mixed"
stream_3_description="Test Stream 3"
stream_4="n"
stream_4_encoding="opus"
stream_4_bitrate="64"
stream_4_channels="2"
stream_4_host="localhost"
stream_4_port="8888"
stream_4_mountpoint="aura-test-4.opus"
stream_4_user="source"
stream_4_password="source"
stream_4_url="http://www.fro.at"
stream_4_name="AURA Test Stream 3"
stream_4_genre="mixed"
stream_4_description="Test Stream 3"
##################################################################################################
# Engine Core Configuration #
##################################################################################################
[general]
##################################################################################################
# Engine ID
; engine_id="1"
# File Socket to control engine-core by engine
; socket_dir="../socket"
# Log directory absolute or relative from the "src" dir
; log_dir="../logs"
# Possible values are from "1" (INFO) to "5" (DEBUG)
; log_level="3"
# Allow Liquidsoap to run as root (required for Docker)
liquidsoap_as_root="true"
# API endpoint to POST playlogs to
api_url_playlog="http://0.0.0.0:8008/api/v1/playlog"
# This is the folder where fallback playlists are read from (optional)
audio_playlist_folder="/var/audio/playlist"
[fallback]
##################################################################################################
# Fallback audio played in scenarios where all other channels are silent. Fallback channels are
# activated using a silence detector. You can use a fallback folder or playlist to feed audio
# into the fallback player.
#
# A folder holding music for Station Fallbacks (optional)
fallback_music_folder="/var/audio/fallback"
# Fallback Show Settings
; fallback_show_name="Station Fallback"
; fallback_show_id="-1"
# Fallback type: "folder", "playlist" or "none"
; fallback_type="folder"
# A playlist holding music for Station Fallbacks (optional)
; fallback_music_playlist= "station-fallback-playlist.m3u"
# The time in seconds how often the folder should be re-scanned
# Do not reload too often when using large folders
; fallback_music_folder_reload="300"
# Maximum time of blank from source (defaults to 20., seconds, float)
; fallback_max_blank="15."
# Minimum duration of noise on source to switch back over (defaults to 0, seconds, float)
; fallback_min_noise="0."
# Power in dB under which the stream is considered silent (defaults to -40., float)
; fallback_threshold="-80."
[audio]
##################################################################################################
# Sound Server
#
# Choose your weapon: "alsa" (1 input/output), "pulseaudio" (multi input/output)
# or "jack" (multi input/output)
soundsystem="alsa"
##################################################################################################
# Input / Output
#
# With 'alsa' you have to write the device names like 'default' to use the system default
# or 'hw:0' to use the 1st audio device directly. With Pulse Audio and Jack => an non empty value
# means it is used. Devices with empty string are ignored and not used
#
output_device_0="default"
; output_device_1=""
; input_device_0=""
; input_device_1=""
##################################################################################################
# Frame Settings
#
# Sample rate in Hz
; frame_audio_sample_rate="44100"
# Frame Size ("frame.audio.size") is provided by ALSA and is specific to your Audio Device. Needs
# to be manually obtained and set correctly.
; frame_audio_size="1764"
; frame_audio_size="7056"
# Tentative frame duration in seconds, defaults to "0.04" (Float). This setting is used as a hint
# for the duration, when frame_audio_size is not provided. It's required for getting things in
# sync, but it's actually tricky to set correctly.
; frame_duration=""
##################################################################################################
# Advanced ALSA Settings
#
# Defaults are recommended, but you might need to tweak these values if you're
# hearing jitter, cracklings or other artifacts or having generally bad latency
#
# Buffered audio is quite simple to setup but has some latency; Unbuffered provides low latency but
# requires a valid frame size.
; alsa_buffered_input="true"
; alsa_buffered_output="true"
#
# Set to 0 to use the ALSA default. If using hardware directly (hw:0) start with 8192. Higher values
# give higher latency and lower CPU usage.
; alsa_buffer="8192"
#
# Only used for buffered ALSA I/O, and affects latency. Probably not wanted for live audio.
# Defaults to "1".
; alsa_buffer_length="10"
#
# Set to 0 or leave empty to use the ALSA default.
; alsa_periods=""
##################################################################################################
# ReplayGain Track Gain Normalization
#
# Audio files are automatically normalized as soon ReplayGain metadata is provided. If your audio
# files do not provide such metadata, it's possible to compute it on the fly for all files
# automatically. Keep in mind this is a computation costly task.
;enable_replaygain_resolver=true
[stream]
##################################################################################################
# Icecast output
#
# Repeat this section for additional outgoing streams, like "stream_1", "stream_2" and so on.
# Enabled: (y)es or (n)o
; stream_0="n"
# Possible values: flac, mp3, ogg, opus
# (depending on the installed Liquidsoap)
; stream_0_encoding="ogg"
; stream_0_bitrate="128"
# Stereo (2) or Mono (any other value)
; stream_0_channels="2"
# Icecast host details
; stream_0_host="localhost"
; stream_0_port="8888"
; stream_0_mountpoint="aura-radio.ogg"
; stream_0_user="source"
; stream_0_password="source"
; stream_0_url="https://aura.radio"
# Stream Metadata
; stream_0_name="AURA Radio"
; stream_0_genre="music"
; stream_0_description="Music from the community radio software suite"
##################################################################################################
# Engine Core Configuration #
##################################################################################################
[general]
##################################################################################################
# Engine ID
; engine_id="1"
# File Socket to control engine-core by engine
; socket_dir="../socket"
# Log directory absolute or relative from the "src" dir
; log_dir="../logs"
# Possible values are from "1" (INFO) to "5" (DEBUG)
; log_level="3"
# Allow Liquidsoap to run as root (required for Docker)
; liquidsoap_as_root="false"
# API endpoint to POST playlogs to
api_url_playlog="http://127.0.0.1:8008/api/v1/playlog"
# This is the folder where fallback playlists are read from (optional)
; audio_playlist_folder="../audio/playlist"
[fallback]
##################################################################################################
# Fallback audio played in scenarios where all other channels are silent. Fallback channels are
# activated using a silence detector. You can use a fallback folder or playlist to feed audio
# into the fallback player.
#
# A folder holding music for Station Fallbacks (optional)
; fallback_music_folder="../audio/fallback"
# Fallback Show Settings
; fallback_show_name="Station Fallback"
; fallback_show_id="-1"
# Fallback type: "folder", "playlist" or "none"
; fallback_type="folder"
# A playlist holding music for Station Fallbacks (optional)
; fallback_music_playlist= "station-fallback-playlist.m3u"
# The time in seconds how often the folder should be re-scanned
# Do not reload too often when using large folders
; fallback_music_folder_reload="300"
# Maximum time of blank from source (defaults to 20., seconds, float)
; fallback_max_blank="15."
# Minimum duration of noise on source to switch back over (defaults to 0, seconds, float)
; fallback_min_noise="0."
# Power in dB under which the stream is considered silent (defaults to -40., float)
; fallback_threshold="-80."
[audio]
##################################################################################################
# Sound Server
#
# Choose your weapon: "alsa" (1 input/output), "pulseaudio" (multi input/output)
# or "jack" (multi input/output)
soundsystem="alsa"
##################################################################################################
# Input / Output
#
# With 'alsa' you have to write the device names like 'default' to use the system default
# or 'hw:0' to use the 1st audio device directly. With Pulse Audio and Jack => an non empty value
# means it is used. Devices with empty string are ignored and not used
#
output_device_0="default"
; output_device_1=""
; input_device_0=""
; input_device_1=""
##################################################################################################
# Frame Settings
#
# Sample rate in Hz
; frame_audio_sample_rate="44100"
# Frame Size ("frame.audio.size") is provided by ALSA and is specific to your Audio Device. Needs
# to be manually obtained and set correctly.
; frame_audio_size="1764"
; frame_audio_size="7056"
# Tentative frame duration in seconds, defaults to "0.04" (Float). This setting is used as a hint
# for the duration, when frame_audio_size is not provided. It's required for getting things in
# sync, but it's actually tricky to set correctly.
; frame_duration=""
##################################################################################################
# Advanced ALSA Settings
#
# Defaults are recommended, but you might need to tweak these values if you're
# hearing jitter, cracklings or other artifacts or having generally bad latency
#
# Buffered audio is quite simple to setup but has some latency; Unbuffered provides low latency but
# requires a valid frame size.
; alsa_buffered_input="true"
; alsa_buffered_output="true"
#
# Set to 0 to use the ALSA default. If using hardware directly (hw:0) start with 8192. Higher values
# give higher latency and lower CPU usage.
; alsa_buffer="8192"
#
# Only used for buffered ALSA I/O, and affects latency. Probably not wanted for live audio.
# Defaults to "1".
; alsa_buffer_length="10"
#
# Set to 0 or leave empty to use the ALSA default.
; alsa_periods=""
##################################################################################################
# ReplayGain Track Gain Normalization
#
# Audio files are automatically normalized as soon ReplayGain metadata is provided. If your audio
# files do not provide such metadata, it's possible to compute it on the fly for all files
# automatically. Keep in mind this is a computation costly task.
;enable_replaygain_resolver=true
[stream]
##################################################################################################
# Icecast output
#
# Repeat this section for additional outgoing streams, like "stream_1", "stream_2" and so on.
# Enabled: (y)es or (n)o
; stream_0="n"
# Possible values: flac, mp3, ogg, opus
# (depending on the installed Liquidsoap)
; stream_0_encoding="ogg"
; stream_0_bitrate="128"
# Stereo (2) or Mono (any other value)
; stream_0_channels="2"
# Icecast host details
; stream_0_host="localhost"
; stream_0_port="8888"
; stream_0_mountpoint="aura-radio.ogg"
; stream_0_user="source"
; stream_0_password="source"
; stream_0_url="https://aura.radio"
# Stream Metadata
; stream_0_name="AURA Radio"
; stream_0_genre="music"
; stream_0_description="Music from the community radio software suite"
# Audio Device Configuration # Audio Device Configuration
This document outlines the steps on how to configure an audio interface with Engine Core. This document outlines the steps on how to configure an audio interface with Engine Core.
...@@ -7,20 +6,19 @@ This document outlines the steps on how to configure an audio interface with Eng ...@@ -7,20 +6,19 @@ This document outlines the steps on how to configure an audio interface with Eng
<!-- TOC --> <!-- TOC -->
- [Audio Device Configuration](#audio-device-configuration) 1. [Audio Device Configuration](#audio-device-configuration)
- [ALSA](#alsa) 1. [ALSA](#alsa)
- [Disabe an existing Pulse Audio Server](#disabe-an-existing-pulse-audio-server) 1. [Disable an existing Pulse Audio Server](#disabe-an-existing-pulse-audio-server)
- [Defining the default audio device](#defining-the-default-audio-device) 2. [Setting the output device using a device ID](#setting-the-output-device-using-a-device-id)
- [Setting the output device using a device ID](#setting-the-output-device-using-a-device-id) 3. [Setting the input device](#setting-the-input-device)
- [Setting the input device](#setting-the-input-device) 1. [(A) Buffered audio](#a-buffered-audio)
- [(A) Buffered audio](#a-buffered-audio) 2. [(B) Unbuffered audio](#b-unbuffered-audio)
- [(B) Unbuffered audio](#b-unbuffered-audio) 2. [Pulse Audio](#pulse-audio)
- [Pulse Audio](#pulse-audio) 3. [JACK](#jack)
- [JACK](#jack)
<!-- /TOC --> <!-- /TOC -->
Following three audio drivers & servers are supported by *Engine Core*: Following three audio drivers & servers are supported by _Engine Core_:
1. ALSA: Recommended for native hardware access. Only one input and output per channel pair is available. 1. ALSA: Recommended for native hardware access. Only one input and output per channel pair is available.
2. PulseAudio: This provides the most simple setup, but is not recommended for live audio input due to latencies. 2. PulseAudio: This provides the most simple setup, but is not recommended for live audio input due to latencies.
...@@ -32,8 +30,9 @@ Out of the box Engine Core is configured to use ALSA `default` output. The input ...@@ -32,8 +30,9 @@ Out of the box Engine Core is configured to use ALSA `default` output. The input
When using your audio device with ALSA you are pretty close to the actual hardware. It can be relatively hard to find some good settings though. When using your audio device with ALSA you are pretty close to the actual hardware. It can be relatively hard to find some good settings though.
**Documentation:** While the [*Official ALSA*](https://www.alsa-project.org/wiki/Documentation) documentation is not an easy read, there is a superb [*ALSA, exposed!*](https://rendaw.gitlab.io/blog/2125f09a85f2.html#alsa-exposed) documentation available too. **Documentation:** While the [_Official ALSA_](https://www.alsa-project.org/wiki/Documentation) documentation is not an easy read, there is a superb [_ALSA, exposed!_](https://rendaw.gitlab.io/blog/2125f09a85f2.html#alsa-exposed) documentation available too.
### Disabe an existing Pulse Audio Server
### Disable an existing Pulse Audio Server
Before starting, you need to ensure not having a Pulse Audio server running on your system. On Linux distributions like Ubuntu, PulseAudio is pre-installed and it can be tricky turning it off. Before starting, you need to ensure not having a Pulse Audio server running on your system. On Linux distributions like Ubuntu, PulseAudio is pre-installed and it can be tricky turning it off.
...@@ -43,7 +42,7 @@ Having PulseAudio running in the background while thinking running native ALSA c ...@@ -43,7 +42,7 @@ Having PulseAudio running in the background while thinking running native ALSA c
First stop PulseAudio from restarting automatically First stop PulseAudio from restarting automatically
```conf ````conf
nano ~/.pulse/client.conf nano ~/.pulse/client.conf
(autospawn = no) (autospawn = no)
```conf ```conf
...@@ -51,7 +50,7 @@ nano ~/.pulse/client.conf ...@@ -51,7 +50,7 @@ nano ~/.pulse/client.conf
```bash ```bash
systemctl --user stop pulseaudio.socket systemctl --user stop pulseaudio.socket
systemctl --user stop pulseaudio.service systemctl --user stop pulseaudio.service
``` ````
You might even think about uninstalling PulseAudio altogether, as there are scenarios where the driver gets restarted upon ALSA device requests. Yes, even with having the PulseAudio service disabled and `autospawn = no` set in your PulseAudio configuration. You might even think about uninstalling PulseAudio altogether, as there are scenarios where the driver gets restarted upon ALSA device requests. Yes, even with having the PulseAudio service disabled and `autospawn = no` set in your PulseAudio configuration.
...@@ -61,7 +60,7 @@ If you only want to do a quick ALSA test, without removing your nicely working P ...@@ -61,7 +60,7 @@ If you only want to do a quick ALSA test, without removing your nicely working P
Audio output can be set by defining the default audio device or some specific device ID. If you prefer the latter you can skip this chapter. Audio output can be set by defining the default audio device or some specific device ID. If you prefer the latter you can skip this chapter.
After first installation, Engine Core is configured to use the audio device set as `default`. You can set the default device in `/etc/asound.conf` or in a per user configuration in `~/asoundrc`. A simple defintion can look like this: After first installation, Engine Core is configured to use the audio device set as `default`. You can set the default device in `/etc/asound.conf` or in a per user configuration in `~/asoundrc`. A simple definition can look like this:
```ini ```ini
defaults.pcm.card 2 defaults.pcm.card 2
...@@ -83,7 +82,7 @@ cat /proc/asound/cards ...@@ -83,7 +82,7 @@ cat /proc/asound/cards
Native Instruments Komplete Audio 6 at usb-0000:00:14.0-5.2.1, high speed Native Instruments Komplete Audio 6 at usb-0000:00:14.0-5.2.1, high speed
``` ```
The `asoundrc` configuration format allows the defintion of not only hardware devices but also complex virtual cards. For example it's possible to do live conversion using ALSA plugins or combine multiple devices into one. The `asoundrc` configuration format allows the definition of not only hardware devices but also complex virtual cards. For example it's possible to do live conversion using ALSA plugins or combine multiple devices into one.
> This file allows you to have more advanced control over your card/device. The .asoundrc file consists of definitions of the various cards available in your system. It also gives you access to the pcm plugins in alsa-lib. These allow you to do tricky things like combine your cards into one or access multiple I/Os on your multichannel card. > This file allows you to have more advanced control over your card/device. The .asoundrc file consists of definitions of the various cards available in your system. It also gives you access to the pcm plugins in alsa-lib. These allow you to do tricky things like combine your cards into one or access multiple I/Os on your multichannel card.
> >
...@@ -127,14 +126,14 @@ output_device_0="default:PCH" ...@@ -127,14 +126,14 @@ output_device_0="default:PCH"
Disadvantages can be: Disadvantages can be:
- Modern distributions configure the ALSA devices with *dmix*, so that several devices can use the sound card at the same time. This can lead to unintentional audio being played independently of engine-core, e.g. if a desktop is running on the same computer. - Modern distributions configure the ALSA devices with _dmix_, so that several devices can use the sound card at the same time. This can lead to unintentional audio being played independently of engine-core, e.g. if a desktop is running on the same computer.
- The default configuration might have higher latencies than would be possible. However, the latency of the default devices is like using PulseAudio and quite sufficient. - The default configuration might have higher latencies than would be possible. However, the latency of the default devices is like using PulseAudio and quite sufficient.
This can be avoided by directly addressing the hardware and setting the parameters buffer size and periods in `engine-ini`. However, this requires a deep understanding of ALSA and experimentally finding the right parameters, so it is not recommended. A good starting point is to set only the parameter for the buffer size. Liquidsoap will adjust the remaining parameters automatically: This can be avoided by directly addressing the hardware and setting the parameters buffer size and frame size in `engine-ini`. However, this requires a deep understanding of ALSA and experimentally finding the right parameters, so it is not recommended. A good starting point is to set only the parameter for the buffer size. Liquidsoap will adjust the remaining parameters automatically:
```ini ```ini
output_device_0="hw:2" output_device_0="hw:2"
alsa_buffer="8192" alsa_buffer="7056"
``` ```
> #TODO Check if we should remove the alsa buffer recommendation here? According to my experience the frame-size is enough, as it also sets the buffer indirectly. > #TODO Check if we should remove the alsa buffer recommendation here? According to my experience the frame-size is enough, as it also sets the buffer indirectly.
...@@ -145,7 +144,7 @@ See [alsa-project.org/wiki/FramesPeriods](https://www.alsa-project.org/wiki/Fram ...@@ -145,7 +144,7 @@ See [alsa-project.org/wiki/FramesPeriods](https://www.alsa-project.org/wiki/Fram
Live analog audio input is disabled by default in Engine Core. Configuring live audio with low latencies can be tricky and depends on your system, Liquidsoap version, ALSA version and last but not least your audio interface. Live analog audio input is disabled by default in Engine Core. Configuring live audio with low latencies can be tricky and depends on your system, Liquidsoap version, ALSA version and last but not least your audio interface.
First you'll need to set the input device ID. You can either set the `default` device or one specific device ID. The approach to get the correct device ID is similar to the one for the output device as outlined above. Here, all three example defintions are valid settings for the same card: First you'll need to set the input device ID. You can either set the `default` device or one specific device ID. The approach to get the correct device ID is similar to the one for the output device as outlined above. Here, all three example definitions are valid settings for the same card:
```ini ```ini
input_device_0="default" input_device_0="default"
...@@ -157,7 +156,6 @@ input_device_0="sysdefault:CARD=K6" ...@@ -157,7 +156,6 @@ input_device_0="sysdefault:CARD=K6"
Next you need to connect some external audio to the analog inputs of your audio interface. Double check if there is enough amplitude to avoid unnecessary searches for an error. Now you can try starting the engine with `run.sh`. Do you hear some sound? It might work, but probably you hear some audio glitches and see plenty buffer underruns in the logs. That's because you need to specific the proper frame-size, individual to you soundcard and ALSA driver. Next you need to connect some external audio to the analog inputs of your audio interface. Double check if there is enough amplitude to avoid unnecessary searches for an error. Now you can try starting the engine with `run.sh`. Do you hear some sound? It might work, but probably you hear some audio glitches and see plenty buffer underruns in the logs. That's because you need to specific the proper frame-size, individual to you soundcard and ALSA driver.
Next you need to decide if you want: Next you need to decide if you want:
- **(A) Buffered audio**: There's some latency involved, but it is relatively easy to configure. - **(A) Buffered audio**: There's some latency involved, but it is relatively easy to configure.
...@@ -170,33 +168,34 @@ Buffered audio is relatively easy to configure, but introduce some latency. By t ...@@ -170,33 +168,34 @@ Buffered audio is relatively easy to configure, but introduce some latency. By t
First check if buffered audio is enabled. But it's the default anyway. First check if buffered audio is enabled. But it's the default anyway.
```ini ```ini
alsa_use_buffer="true" alsa_buffered_input="true"
alsa_buffered_output="true"
``` ```
In that case you might need to tweak following settings, where the defaults are a good start. Maybe you are lucky and it works out of the box? :-) In that case you might need to tweak following settings, where the defaults are a good start. Maybe you are lucky and it works out of the box? :-)
```ini ```ini
alsa_buffer="8192" alsa_buffer="7056"
alsa_buffer_length="10" alsa_buffer_length="10"
alsa_frame_size="2048" frame_audio_size="1764"
``` ```
If you don't experience any buffer underruns in the logs you can try to decrease the buffer size to for example `4096` or `2048`. If you don't experience any buffer underruns in the logs you can try to decrease the buffer size to for example `3528` or `1764`.
In case you get plenty of buffer unterruns then try to increase the buffer size and possibly the frame size to twice the given value. In case you get plenty of buffer unterruns then try to increase the buffer size and possibly the frame size to twice the given value.
#### (B) Unbuffered audio #### (B) Unbuffered audio
When enabling unbuffered audio you can access the (almost ;) real-time capabilities of ALSA. When enabling unbuffered audio you can access the (almost) real-time capabilities of ALSA.
```ini ```ini
alsa_use_buffer="false" alsa_buffered_input="false"
``` ```
In that case you need to tweak at least following setting, but it's one with some huge impact. In that case you need to tweak at least following setting, but it's one with some huge impact.
```ini ```ini
alsa_frame_size="2048" frame_audio_size="1764"
``` ```
**Detecting the correct frame-size** **Detecting the correct frame-size**
...@@ -209,23 +208,23 @@ Now perform following steps to find the correct frame-size: ...@@ -209,23 +208,23 @@ Now perform following steps to find the correct frame-size:
1. Run the script with the initial `frame.audio.size` of zero: `engine-core/tests$ liquidsoap -v test_alsa_framesize.liq` 1. Run the script with the initial `frame.audio.size` of zero: `engine-core/tests$ liquidsoap -v test_alsa_framesize.liq`
2. This causes plenty buffer underruns. 2. This causes plenty buffer underruns.
3. Liquidsoap reports the "correct" frame-size of e.g. 1881 in the logs: `[analog_input:3] Could not set buffer size to 'frame.size' (1764 samples), got 1881.`. 3. Liquidsoap reports the "correct" frame-size of e.g. 1764 in the logs: `[analog_input:3] Could not set buffer size to 'frame.size' (1764 samples), got 1881.`.
4. Now adapt the `frame.audio.size` in the script to `1881`. 4. Now adapt the `frame.audio.size` in the script to `1764`.
5. This may have caused buffer underruns too 5. This may have caused buffer underruns too
6. Now try to set the frame size to a multiple of "1881". For example frame size to 2 x 1881 = 3762. Run the script again. 6. Now try to set the frame size to a multiple of "1764". For example frame size to 2 x 1764 = 3528. Run the script again.
7. Liquidsoap logs another mismatch in the logs: `[analog_input:3] Could not set buffer size to 'frame.size' (3762 samples), got 3763.` 7. Liquidsoap logs another mismatch in the logs: `[analog_input:3] Could not set buffer size to 'frame.size' (3528 samples), got 3529.`
8. Now the value is only off by 1. This might be because of a resolution problem. So now try to set the frame size to 3762 + 1 = 3763 8. Now the value is only off by 1. This might be because of a resolution problem. So now try to set the frame size to 3528 + 1 = 3529
9. Run the script again. Now the logs don't report an error like "Could not not set buffer size" anymore. 9. Run the script again. Now the logs don't report an error like "Could not not set buffer size" anymore.
10. Watch the logs for a while. If there are still some buffer underruns try a higher number. Try another multiple by setting frame size to 2 x 3763 = 7526. 10. Watch the logs for a while. If there are still some buffer underruns try a higher number. Try another multiple by setting frame size to 2 x 3528 = 7056.
11. Run the script again. If there are no buffer underruns anymore and you hear clean sound without any glitches you have found an optimal value. Also watchout for any "Could not set buffer size" logs, they should be gone too. 11. Run the script again. If there are no buffer underruns anymore and you hear clean sound without any glitches you have found an optimal value. Also watchout for any "Could not set buffer size" logs, they should be gone too.
The total steps needed and resulting values might be different based on your system and audio interface. The total steps needed and resulting values might be different based on your system and audio interface.
After you have found your own personal frame-size, use the value for the `alsa_frame_size` in the `engine-core.ini` config. Then start the engine and double-check the logs there. After you have found your own personal frame-size, use the value for the `frame_audio_size` in the `engine-core.ini` config. Then start the engine and double-check the logs there.
## Pulse Audio ## Pulse Audio
> *More testing and documentation on PulseAudio usage to be provided at a later stage. Feedback and tips are welcome.* > _More testing and documentation on PulseAudio usage to be provided at a later stage. Feedback and tips are welcome._
A system which is already configured for PulseAudio needs no further configuration. The `default` ALSA device is emulated automatically using a PulseAudio ALSA plugin. The signal flow looks like following: A system which is already configured for PulseAudio needs no further configuration. The `default` ALSA device is emulated automatically using a PulseAudio ALSA plugin. The signal flow looks like following:
...@@ -235,12 +234,10 @@ Obviously this is the reason for increased latencies. This should not be an issu ...@@ -235,12 +234,10 @@ Obviously this is the reason for increased latencies. This should not be an issu
Audio Interface <--> ALSA <--> Pulse Audio <--> Audio Stream Audio Interface <--> ALSA <--> Pulse Audio <--> Audio Stream
**Documentation:** Find more information in the [*PulseAudio*](https://www.freedesktop.org/wiki/Software/PulseAudio/Documentation/) documentation. **Documentation:** Find more information in the [_PulseAudio_](https://www.freedesktop.org/wiki/Software/PulseAudio/Documentation/) documentation.
## JACK ## JACK
> *Supported, but not yet tested. Documentation will be updated as soon we have more information on the actual usage. We are happy for contributions on configuration and best practices.* > _Supported, but not yet tested. Documentation will be updated as soon we have more information on the actual usage. We are happy for contributions on configuration and best practices._
**Documentation:** Find more information in the [*JACK Audio Connection Kit*](https://jackaudio.org/) documentation. **Documentation:** Find more information in the [_JACK Audio Connection Kit_](https://jackaudio.org/) documentation.
# Frequently Asked Questions # Frequently Asked Questions
<!-- TOC --> <!-- TOC -->
...@@ -8,7 +7,7 @@ ...@@ -8,7 +7,7 @@
2. [How can I find the audio output device IDs, required for settings in engine-core.ini?](#how-can-i-find-the-audio-output-device-ids-required-for-settings-in-engine-coreini) 2. [How can I find the audio output device IDs, required for settings in engine-core.ini?](#how-can-i-find-the-audio-output-device-ids-required-for-settings-in-engine-coreini)
3. [I have configured an audio device in my `engine-core.ini` but still hear no sound](#i-have-configured-an-audio-device-in-my-engine-coreini-but-still-hear-no-sound) 3. [I have configured an audio device in my `engine-core.ini` but still hear no sound](#i-have-configured-an-audio-device-in-my-engine-coreini-but-still-hear-no-sound)
4. [I have configured an audio device in my `docker.engine-core.ini` but still hear no sound](#i-have-configured-an-audio-device-in-my-dockerengine-coreini-but-still-hear-no-sound) 4. [I have configured an audio device in my `docker.engine-core.ini` but still hear no sound](#i-have-configured-an-audio-device-in-my-dockerengine-coreini-but-still-hear-no-sound)
5. [I'm getting [clock.wallclock_alsa:2] Error when starting output lineout: Failure("Error while setting open_pcm: No such file or directory")!**](#im-getting-clockwallclock_alsa2-error-when-starting-output-lineout-failureerror-while-setting-open_pcm-no-such-file-or-directory) 5. [I'm getting [clock.wallclock_alsa:2] Error when starting output lineout: Failure("Error while setting open_pcm: No such file or directory")!\*\*](#im-getting-clockwallclock_alsa2-error-when-starting-output-lineout-failureerror-while-setting-open_pcm-no-such-file-or-directory)
6. [How to solve 'Error when starting output output_lineout_0: Failure("Error while setting open_pcm: Device or resource busy")!'?](#how-to-solve-error-when-starting-output-output_lineout_0-failureerror-while-setting-open_pcm-device-or-resource-busy) 6. [How to solve 'Error when starting output output_lineout_0: Failure("Error while setting open_pcm: Device or resource busy")!'?](#how-to-solve-error-when-starting-output-output_lineout_0-failureerror-while-setting-open_pcm-device-or-resource-busy)
7. [How to avoid stutter, hangs, artifacts or in general glitchy sound?](#how-to-avoid-stutter-hangs-artifacts-or-in-general-glitchy-sound) 7. [How to avoid stutter, hangs, artifacts or in general glitchy sound?](#how-to-avoid-stutter-hangs-artifacts-or-in-general-glitchy-sound)
8. [Are there any commands to directly control the playout-server for development, debugging or testing?](#are-there-any-commands-to-directly-control-the-playout-server-for-development-debugging-or-testing) 8. [Are there any commands to directly control the playout-server for development, debugging or testing?](#are-there-any-commands-to-directly-control-the-playout-server-for-development-debugging-or-testing)
...@@ -32,6 +31,7 @@ Check out the [Audio Device Configuration](docs/audio-device-configuration.md) p ...@@ -32,6 +31,7 @@ Check out the [Audio Device Configuration](docs/audio-device-configuration.md) p
## I have configured an audio device in my `engine-core.ini` but still hear no sound ## I have configured an audio device in my `engine-core.ini` but still hear no sound
To test if you device is able to output audio at all, independently from Engine Core, try executing `speaker-test`. Also checkout out the `-D` argument to test specific devices. If you system doesn't provided `speaker-test` you have to install or use your preferred way of testing also audio. To test if you device is able to output audio at all, independently from Engine Core, try executing `speaker-test`. Also checkout out the `-D` argument to test specific devices. If you system doesn't provided `speaker-test` you have to install or use your preferred way of testing also audio.
## I have configured an audio device in my `docker.engine-core.ini` but still hear no sound ## I have configured an audio device in my `docker.engine-core.ini` but still hear no sound
If you are running Engine Core using Docker, run the aforementioned `speaker-test` from within your docker container by perform following: If you are running Engine Core using Docker, run the aforementioned `speaker-test` from within your docker container by perform following:
...@@ -41,12 +41,11 @@ If you are running Engine Core using Docker, run the aforementioned `speaker-tes ...@@ -41,12 +41,11 @@ If you are running Engine Core using Docker, run the aforementioned `speaker-tes
3. Now run `speaker-test`. It that's working, you now know that your audio device is at least available from within Docker and you'll need to further check your Liquidsoap device configuration. 3. Now run `speaker-test`. It that's working, you now know that your audio device is at least available from within Docker and you'll need to further check your Liquidsoap device configuration.
4. Next you can run `liquidsoap tests/test_alsa_default.liq`. This is a basic script which tries to play the supplied MP3 using the default ALSA device. 4. Next you can run `liquidsoap tests/test_alsa_default.liq`. This is a basic script which tries to play the supplied MP3 using the default ALSA device.
## I'm getting [clock.wallclock_alsa:2] Error when starting output lineout: Failure("Error while setting open_pcm: No such file or directory")!\*\*
## I'm getting [clock.wallclock_alsa:2] Error when starting output lineout: Failure("Error while setting open_pcm: No such file or directory")!** Assure you have set the correct device ID. To do so check the aforementioned question. Check the audio interface configuration section in `engine-core.ini`. Verify if the default settings `input_device_0` and `output_device_0` are valid device IDs.
Assure you have set the correct device ID. To do so check the aformentioned question. Check the audio interface configuration section in `engine-core.ini`. Verify if the default settings `input_device_0` and `output_device_0` are valid device IDs. In case your are _not_ running Engine Core within Docker, also check if your executing user (è.g. `engineuser`) belongs to the group `audio`.
In case your are *not* running Engine Core within Docker, also check if your executing user (è.g. `engineuser`) belongs to the group `audio`.
## How to solve 'Error when starting output output_lineout_0: Failure("Error while setting open_pcm: Device or resource busy")!'? ## How to solve 'Error when starting output output_lineout_0: Failure("Error while setting open_pcm: Device or resource busy")!'?
...@@ -58,7 +57,7 @@ This can have various reasons, but first of all it's good to check the `engine-c ...@@ -58,7 +57,7 @@ This can have various reasons, but first of all it's good to check the `engine-c
**Incorrect ALSA buffer settings**: If the ALSA settings provided by your system are not working cleanly the `engine-core.ini` settings provide to option to override parameters such as `alsa_buffer`. The correct settings are individual to the used soundcard but in general this is a tricky topic. In our case we had more success using PulseAudio or JACK instead. Recommendations are welcome. **Incorrect ALSA buffer settings**: If the ALSA settings provided by your system are not working cleanly the `engine-core.ini` settings provide to option to override parameters such as `alsa_buffer`. The correct settings are individual to the used soundcard but in general this is a tricky topic. In our case we had more success using PulseAudio or JACK instead. Recommendations are welcome.
**These problems occurr while having Icecast streaming enabled**: Try to reduce the quality of the stream, especially when you are experiencing hangs on the stream. Check your Icecast connection. Is it up and running? Maybe there is some authentication issue or an [Icecast limitation for max clients](ttps://github.com/savonet/liquidsoap/issues/524). **These problems occur while having Icecast streaming enabled**: Try to reduce the quality of the stream, especially when you are experiencing hangs on the stream. Check your Icecast connection. Is it up and running? Maybe there is some authentication issue or an [Icecast limitation for max clients](ttps://github.com/savonet/liquidsoap/issues/524).
**The hardware is hitting its limits**: Also check the relevant logs and the system utilization. Are there other processes using up the machines resources? You might even be hitting the performance limit of your hardware. Maybe using a realtime linux kernel could help too. **The hardware is hitting its limits**: Also check the relevant logs and the system utilization. Are there other processes using up the machines resources? You might even be hitting the performance limit of your hardware. Maybe using a realtime linux kernel could help too.
...@@ -78,7 +77,7 @@ List all available channels ...@@ -78,7 +77,7 @@ List all available channels
List all input channels connected to the mixer List all input channels connected to the mixer
`mixer.input` `mixer.inputs`
Set the volume of mixer `input 0` to `100%` Set the volume of mixer `input 0` to `100%`
...@@ -88,8 +87,7 @@ Push some audio file to the filesystem `in_filesystem_0` ...@@ -88,8 +87,7 @@ Push some audio file to the filesystem `in_filesystem_0`
`in_filesystem_0.push /path/to/your/file.mp3` `in_filesystem_0.push /path/to/your/file.mp3`
## Read More ## Read More
- [Overview](/README.md) - [Overview](/README.md)
- [Frequently Asked Questions (FAQ)](docs/frequently-asked-questions.md) - [Frequently Asked Questions (FAQ)](docs/frequently-asked-questions.md)
\ No newline at end of file
# Meta
__author__ = "David Trattnig and Gottfried Gaisbauer"
__copyright__ = "Copyright 2017-2020, Aura Engine Team"
__credits__ = ["Steffen Müller", "Michael Liebler"]
__license__ = "GNU Affero General Public License (AGPL) Version 3"
__version__ = "0.9.9"
__version_info__ = (0, 9, 9)
__maintainer__ = "David Trattnig"
__email__ = "david.trattnig@subsquare.at"
__status__ = "Development"
\ No newline at end of file
#!/bin/bash
mode="dev"
docker="false"
#
# Run Script for AURA Engine
#
# Call with one of these parameters:
#
# - dev
# - prod
# - debug
# - log
# - docker:dev
# - docker:debug
# - docker:build
# - docker:push
#
if [[ $* =~ ^(dev|prod|debug|log)$ ]]; then
mode=$1
fi
if [[ "$1" == *"docker:"* ]]; then
docker="true"
mode=${1#*:}
fi
echo "[ Run mode=$mode ]"
echo "[ Docker=$docker ]"
# +++ DEFAULT COMMANDS +++ #
if [[ $docker == "false" ]]; then
### Runs Engine Core in Development (Liquidsoap) ###
if [[ $mode == "dev" ]]; then
(cd src && liquidsoap ./engine.liq)
fi
### Runs Engine Core in Production (Liquidsoap) ###
if [[ $mode == "prod" ]]; then
(cd src && liquidsoap ./engine.liq)
fi
### Runs Engine Core (Verbose & debug output) ###
if [[ $mode == "debug" ]]; then
(cd src && liquidsoap --verbose --debug ./engine.liq)
fi
### Tails the log file only (Used for Docker debugging) ###
if [[ $mode == "log" ]]; then
tail -f logs/engine-core.log
fi
fi
# +++ DOCKER COMMANDS +++ #
if [[ $docker == "true" ]]; then
BASE_DIR=$(readlink -f .)
AUDIO_DIR=$(readlink -f ./audio)
echo "Absolute base dir: " $BASE_DIR
echo "Absolute audio dir: " $AUDIO_DIR
### Runs Engine Core ###
if [[ $mode == "dev" ]]; then
exec sudo docker run \
--network="host" \
--name aura-engine-core \
--rm \
-u $UID:$GID \
-v "$BASE_DIR/config/engine-core.docker.ini":"/srv/config/engine-core.ini":ro \
-v "$BASE_DIR/socket":"/srv/socket" \
-v "$AUDIO_DIR/source":"/var/audio/source":ro \
-v "$AUDIO_DIR/playlist":"/var/audio/playlist":ro \
-v "$AUDIO_DIR/station":"/var/audio/station":ro \
-v "$BASE_DIR/logs":"/srv/logs" \
-v "/etc/asound.conf":"/etc/asound.conf" \
--mount type=tmpfs,destination=/tmp \
--device /dev/snd \
--group-add audio \
autoradio/engine-core
fi
### Debugging mode: only tails the log file and enter the container manually ###
if [[ $mode == "debug" ]]; then
exec sudo docker run \
--network="host" \
--name aura-engine-core \
--rm \
-u $UID:$GID \
-v "$BASE_DIR/config/engine-core.docker.ini":"/srv/config/engine-core.ini":ro \
-v "$BASE_DIR/socket":"/srv/socket" \
-v "$AUDIO_DIR/source":"/var/audio/source":ro \
-v "$AUDIO_DIR/playlist":"/var/audio/playlist":ro \
-v "$AUDIO_DIR/station":"/var/audio/station":ro \
-v "$BASE_DIR/contrib":"/srv/contrib" \
-v "$BASE_DIR/tests":"/srv/tests" \
-v "$BASE_DIR/logs":"/srv/logs" \
-v "$BASE_DIR/contrib":"/srv/contrib" \
-v "$BASE_DIR/tests":"/srv/tests" \
-v "/etc/asound.conf":"/etc/asound.conf" \
--privileged \
--memory=8g --memory-reservation=4g \
--cpus=4.0 --cpu-shares=3000 \
--mount type=tmpfs,destination=/tmp \
--device /dev/snd \
--group-add audio \
autoradio/engine-core log
fi
### Create Docker Image from local project ###
if [[ $mode == "build" ]]; then
docker build -t autoradio/engine-core .
fi
### Pushes the latest Docker Image to Docker Hub ###
if [[ $mode == "push" ]]; then
docker push autoradio/engine-core
fi
fi
\ No newline at end of file
...@@ -25,16 +25,16 @@ fallback_inputs = ref [] ...@@ -25,16 +25,16 @@ fallback_inputs = ref []
# Create Sources # Create Sources
input_fallback_scheduled_0 = request.equeue(id="in_fallback_scheduled_0") input_fallback_scheduled_0 = request.queue(id="in_fallback_scheduled_0")
input_fallback_scheduled_1 = request.equeue(id="in_fallback_scheduled_1") input_fallback_scheduled_1 = request.queue(id="in_fallback_scheduled_1")
# Apply ReplayGain Normalization # Apply ReplayGain Normalization
input_fallback_scheduled_0 = amplify(id="in_fallback_scheduled_0", 1., override="replay_gain", input_fallback_scheduled_0) input_fallback_scheduled_0 = amplify(id="in_fallback_scheduled_0", 1., override="replay_gain", input_fallback_scheduled_0)
input_fallback_scheduled_1 = amplify(id="in_fallback_scheduled_1", 1., override="replay_gain", input_fallback_scheduled_1) input_fallback_scheduled_1 = amplify(id="in_fallback_scheduled_1", 1., override="replay_gain", input_fallback_scheduled_1)
# Add Event Handlers # Add Event Handlers
input_fallback_scheduled_0 = on_metadata(id="in_fallback_scheduled_0", on_metadata_notification, input_fallback_scheduled_0) input_fallback_scheduled_0.on_metadata(on_metadata_notification)
input_fallback_scheduled_1 = on_metadata(id="in_fallback_scheduled_1", on_metadata_notification, input_fallback_scheduled_1) input_fallback_scheduled_1.on_metadata(on_metadata_notification)
# Mixer for more control of scheduled fallbacks # Mixer for more control of scheduled fallbacks
fallback_mixer = mix(id="mixer_fallback", fallback_mixer = mix(id="mixer_fallback",
...@@ -47,8 +47,8 @@ fallback_mixer = mix(id="mixer_fallback", ...@@ -47,8 +47,8 @@ fallback_mixer = mix(id="mixer_fallback",
) )
) )
stripped_fallback_mixer = strip_blank( stripped_fallback_mixer = blank.strip(
id="fallback_strip_blank", id="fallback_stripped",
track_sensitive=false, track_sensitive=false,
max_blank=fallback_max_blank, max_blank=fallback_max_blank,
min_noise=fallback_min_noise, min_noise=fallback_min_noise,
......
...@@ -20,9 +20,9 @@ ...@@ -20,9 +20,9 @@
# Crossfade between tracks, # Crossfade between tracks,
# taking the respective volume levels # taking the respective volume levels
# into account in the choice of the # into account in the choice of the
# transition. # transition.
# @category Source / Track Processing # @category Source / Track Processing
# @param ~start_next Crossing duration, if any. # @param ~start_next Crossing duration, if any.
...@@ -45,25 +45,25 @@ def crossfade (~start_next=5.,~fade_in=3., ...@@ -45,25 +45,25 @@ def crossfade (~start_next=5.,~fade_in=3.,
def transition(a,b,ma,mb,sa,sb) def transition(a,b,ma,mb,sa,sb)
list.iter(fun(x)-> list.iter(fun(x)->
log(level=4,"Before: #{x}"),ma) log(level=4,"Before: #{x}"),ma)
list.iter(fun(x)-> list.iter(fun(x)->
log(level=4,"After : #{x}"),mb) log(level=4,"After : #{x}"),mb)
if if
# If A and B and not too loud and close, # If A and B and not too loud and close,
# fully cross-fade them. # fully cross-fade them.
a <= medium and a <= medium and
b <= medium and b <= medium and
abs(a - b) <= margin abs(a - b) <= margin
then then
log("Transition: crossed, fade-in, fade-out.") log("Transition: crossed, fade-in, fade-out.")
add(fade.out(sa),fade.in(sb)) add(fade.out(sa),fade.in(sb))
elsif elsif
# If B is significantly louder than A, # If B is significantly louder than A,
# only fade-out A. # only fade-out A.
# We don't want to fade almost silent things, # We don't want to fade almost silent things,
# ask for >medium. # ask for >medium.
b >= a + margin and a >= medium and b <= high b >= a + margin and a >= medium and b <= high
then then
...@@ -84,23 +84,23 @@ def crossfade (~start_next=5.,~fade_in=3., ...@@ -84,23 +84,23 @@ def crossfade (~start_next=5.,~fade_in=3.,
log("Transition: crossed, fade-in.") log("Transition: crossed, fade-in.")
add(sa,fade.in(sb)) add(sa,fade.in(sb))
# What to do with a loud end and # What to do with a loud end and
# a quiet beginning ? # a quiet beginning ?
# A good idea is to use a jingle to separate # A good idea is to use a jingle to separate
# the two tracks, but that's another story. # the two tracks, but that's another story.
else else
# Otherwise, A and B are just too loud # Otherwise, A and B are just too loud
# to overlap nicely, or the difference # to overlap nicely, or the difference
# between them is too large and # between them is too large and
# overlapping would completely mask one # overlapping would completely mask one
# of them. # of them.
log("No transition: just sequencing.") log("No transition: just sequencing.")
sequence([sa, sb]) sequence([sa, sb])
end end
end end
cross(width=width, duration=start_next, cross(width=width, duration=start_next,
conservative=conservative, conservative=conservative,
transition,s) transition,s)
end end
...@@ -205,7 +205,7 @@ def fallback_create(~skip=true, name, requestor) ...@@ -205,7 +205,7 @@ def fallback_create(~skip=true, name, requestor)
system('#{list.assoc(default="", "install_dir", ini)}/guru.py --on_play "#{filename}"') system('#{list.assoc(default="", "install_dir", ini)}/guru.py --on_play "#{filename}"')
end end
source = on_metadata(do_meta, source) source = on_metadata(do_meta, source)
log("channel created") log("channel created")
...@@ -220,24 +220,24 @@ end ...@@ -220,24 +220,24 @@ end
def create_playlist() = def create_playlist() =
log("requesting next song for PLAYLIST") log("requesting next song for PLAYLIST")
result = get_process_lines('#{list.assoc(default="", "install_dir", ini)}/guru.py --get-next-file-for "playlist" --quiet') result = process.read.lines('#{list.assoc(default="", "install_dir", ini)}/guru.py --get-next-file-for "playlist" --quiet')
create_dynamic_playlist(result) create_dynamic_playlist(result)
end end
def create_station_fallback() = def create_station_fallback() =
result = get_process_lines('#{list.assoc(default="", "install_dir", ini)}/guru.py --get-next-file-for station --quiet') result = process.read.lines('#{list.assoc(default="", "install_dir", ini)}/guru.py --get-next-file-for station --quiet')
log("next song for STATION fallback is: #{result}") log("next song for STATION fallback is: #{result}")
create_dynamic_playlist(result) create_dynamic_playlist(result)
end end
def create_show_fallback() = def create_show_fallback() =
result = get_process_lines('#{list.assoc(default="", "install_dir", ini)}/guru.py --get-next-file-for show --quiet') result = process.read.lines('#{list.assoc(default="", "install_dir", ini)}/guru.py --get-next-file-for show --quiet')
log("next song for SHOW fallback is: #{result}") log("next song for SHOW fallback is: #{result}")
create_dynamic_playlist(result) create_dynamic_playlist(result)
end end
def create_timeslot_fallback() = def create_timeslot_fallback() =
result = get_process_lines('#{list.assoc(default="", "install_dir", ini)}/guru.py --get-next-file-for timeslot --quiet') result = process.read.lines('#{list.assoc(default="", "install_dir", ini)}/guru.py --get-next-file-for timeslot --quiet')
log("next song for TIMESLOT fallback is: #{result}") log("next song for TIMESLOT fallback is: #{result}")
create_dynamic_playlist(result) create_dynamic_playlist(result)
end end
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment