diff --git a/guru.py b/guru.py
index 509aab2961f9e2536443f6496f2b85b5406cd9d7..b5343a335cf0de0876f1ee6fa04742b4be0f037c 100755
--- a/guru.py
+++ b/guru.py
@@ -110,8 +110,8 @@ class Guru():
 
         # getter
         self.parser.add_argument("-pcs", "--print-connection-status", action="store_true", dest="get_connection_status",  default=False, help="Prints the status of the connection to liquidsoap, pv and tank")
-        self.parser.add_argument("-gam", "--get-active-mixer",        action="store_true", dest="get_active_mixer",       default=False, help="Which mixer is activated?")
-        self.parser.add_argument("-pms", "--print-mixer-status",      action="store_true", dest="get_mixer_status",       default=False, help="Prints all mixer sources and their states")
+        self.parser.add_argument("-gam", "--get-active-mixer",        action="store_true", dest="mixer_channels_selected",default=False, help="Which mixer channels are selected?")
+        self.parser.add_argument("-pms", "--print-mixer-status",      action="store_true", dest="mixer_status",           default=False, help="Prints all mixer sources and their states")
         self.parser.add_argument("-pap", "--print-act-programme",     action="store_true", dest="get_act_programme",      default=False, help="Prints the actual Programme, the controller holds")
         self.parser.add_argument("-s",   "--status",                  action="store_true", dest="get_status",             default=False, help="Returns the Engine Status as JSON")
 
diff --git a/modules/cli_tool/padavan.py b/modules/cli_tool/padavan.py
index 56c3c8eb0b2f6f4dd5391d47de2a38d3b39f0ebe..a368f465e713725c594328f356256e2d041d9747 100644
--- a/modules/cli_tool/padavan.py
+++ b/modules/cli_tool/padavan.py
@@ -50,11 +50,11 @@ class Padavan:
         if self.args.fetch_new_programme:
             self.fetch_new_programme()
 
-        elif self.args.get_active_mixer:
-            self.get_active_mixer()
+        elif self.args.mixer_channels_selected:
+            self.mixer_channels_selected()
 
-        elif self.args.get_mixer_status:
-            self.get_mixer_status()
+        elif self.args.mixer_status:
+            self.mixer_status()
 
         elif self.args.get_act_programme:
             self.get_act_programme()
@@ -275,9 +275,9 @@ class Padavan:
         self.destroy_liquidsoap_communication()
 
     # ------------------------------------------------------------------------------------------ #
-    def get_active_mixer(self):
+    def mixer_channels_selected(self):
         self.init_liquidsoap_communication()
-        am = self.ss.get_active_mixer()
+        am = self.ss.mixer_channels_selected()
 
         if len(am) == 0:
             self.destroy_liquidsoap_communication()
@@ -289,10 +289,10 @@ class Padavan:
         self.destroy_liquidsoap_communication()
 
     # ------------------------------------------------------------------------------------------ #
-    def get_mixer_status(self):
+    def mixer_status(self):
         self.init_liquidsoap_communication()
 
-        status = self.ss.get_mixer_status()
+        status = self.ss.mixer_status()
 
         for k, v in status.items():
             self.stringreply += "source: " + k + "\t status: " + v + "\n"
diff --git a/modules/core/engine.py b/modules/core/engine.py
index 3819a3c3b36e0549151bdcbd2836f33291f3481b..8bd210fe9790588b1484f6d40c7a7a15e840e350 100644
--- a/modules/core/engine.py
+++ b/modules/core/engine.py
@@ -26,7 +26,9 @@ import time
 import logging
 import json
 
-from urllib.parse import urlparse, ParseResult
+from urllib.parse               import urlparse, ParseResult
+from contextlib                 import suppress
+from threading                  import Thread
 
 from modules.base.enum          import ChannelType, Channel, TransitionType, LiquidsoapResponse, EntryPlayState
 from modules.base.utils         import TerminalColors, SimpleUtil, EngineUtil
@@ -66,7 +68,7 @@ class SoundSystem():
 
     def __init__(self, config):
         """
-        Initializes the communicator by establishing a Socket connection
+        Initializes the sound-system by establishing a Socket connection
         to Liquidsoap.
 
         Args:
@@ -96,19 +98,22 @@ class SoundSystem():
 
     def start(self):
         """
-        Starts the soundsystem.
+        Starts the sound-system.
         """
         # Sleep needed, because the socket is created too slowly by Liquidsoap
         time.sleep(1)
         self.enable_transaction()
         time.sleep(1)
 
-        self.mixer_start()
+        # Initialize all channels
+        channels = self.mixer_channels_reload()
+        for c in channels:
+            self.channel_volume(c, "0")
 
         # Setting init params like a blank file
-        install_dir = self.config.get("install_dir")
-        channel = self.active_channel[ChannelType.FILESYSTEM]
-        self.playlist_push(channel, install_dir + "/configuration/blank.flac")
+        # install_dir = self.config.get("install_dir")
+        # channel = self.active_channel[ChannelType.FILESYSTEM]
+        # self.playlist_push(channel, install_dir + "/configuration/blank.flac")
 
         self.disable_transaction()
         self.is_liquidsoap_running = True
@@ -133,104 +138,124 @@ class SoundSystem():
         return self.is_liquidsoap_running
 
 
+
     #
     #   MIXER : GENERAL
     # 
 
 
-    def mixer_start(self):
-        # Reset channels and reload them
-        channels = self.reload_channels()
+    def mixer_status(self):
+        """
+        Returns the state of all mixer channels
+        """
+        cnt = 0
+        inputstate = {}
 
-        # For all available channels
-        for c in channels:
-            # Set volume to zero
-            self.channel_volume(c, "0")
-            # And activate this channel
-            self.channel_activate(c, True)
+        self.enable_transaction()
+        inputs = self.mixer_channels()
 
+        for input in inputs:
+            inputstate[input] = self.channel_status(cnt)
+            cnt = cnt + 1
 
-    # ------------------------------------------------------------------------------------------ #
-    # def set_volume(self, mixernumber, volume):
-    #     #return self.client.command("mixer", 'volume', mixernumber, str(volume))
-    #     return self.__send_lqc_command__(self.client, "mixer", "volume", mixernumber, volume)
+        self.disable_transaction()
+        return inputstate
 
-    # ------------------------------------------------------------------------------------------ #
-    def get_active_mixer(self):
+
+    def mixer_channels(self):
         """
-        get active mixer in liquidsoap server
-        :return:
+        Retrieves all mixer channels
         """
-        activeinputs = []
+        if self.channels is None or len(self.channels) == 0:
+            self.channels = self.__send_lqc_command__(self.client, "mixer", "inputs")
 
-        # enable more control over the connection
-        self.enable_transaction()
+        return self.channels
 
-        inputs = self.get_all_channels()
 
+    def mixer_channels_selected(self):
+        """
+        Retrieves all selected channels of the mixer.
+        """
         cnt = 0
-        for input in inputs:
-            status = self.__get_mixer_status__(cnt)
+        activeinputs = []
 
+        self.enable_transaction()
+        inputs = self.mixer_channels()
+
+        for input in inputs:
+            status = self.channel_status(cnt)
             if "selected=true" in status:
                 activeinputs.append(input)
-
             cnt = cnt + 1
 
         self.disable_transaction()
 
         return activeinputs
 
-    # ------------------------------------------------------------------------------------------ #
-    def get_mixer_status(self):
-        inputstate = {}
 
-        self.enable_transaction()
+    def mixer_channels_except(self, input_type):
+        """
+        Retrieves all mixer channels except the ones of the given type.
+        """
+        try:
+            activemixer_copy = self.mixer_channels().copy()
+            activemixer_copy.remove(input_type)
+        except ValueError as e:
+            self.logger.error("Requested channel (" + input_type + ") not in channellist. Reason: " + str(e))
+        except AttributeError:
+            self.logger.critical("Channellist is None")
 
-        inputs = self.get_all_channels()
+        return activemixer_copy
 
-        cnt = 0
-        for input in inputs:
-            inputstate[input] = self.__get_mixer_status__(cnt)
-            cnt = cnt + 1
 
-        self.disable_transaction()
+    def mixer_channels_reload(self):
+        """
+        Reloads all mixer channels. 
+        """
+        self.channels = None
+        return self.mixer_channels()
 
-        return inputstate
 
 
     # ------------------------------------------------------------------------------------------ #
     def get_mixer_volume(self, channel):
+        # FIXME Is this needed; even possible?
         return False
 
-    # ------------------------------------------------------------------------------------------ #
-    def __get_mixer_status__(self, mixernumber):
-        return self.__send_lqc_command__(self.client, "mixer", "status", mixernumber)
+
 
 
     #
-    #   MIXER : CHANNELS
+    #   MIXER : CONTROL SECTION
     #
 
 
-    def load(self, entry):
+    def preroll(self, entry):
         """
-        Preloads the entry. This is required before the actual `play(..)` can happen.
+        Pre-Rolls/Pre-Loads the entry. This is required before the actual `play(..)` can happen.
+
+        Be aware when using this method to queue a very short entry (shorter than ``) this may
+        result in sitations with incorrect timing. In this case bundle multiple short entries as
+        one queue using `preroll_playlist(self, entries)`.
 
-        Note his method is blocking until loading has finished. If this method is called 
-        asynchroniously, the progress on the preloading state can be looked up in `entry.state`.
+        It's important to note, that his method is blocking until loading has finished. If this 
+        method is called asynchronously, the progress on the preloading state can be looked up in 
+        `entry.state`.
+
+        Args:
+            entries ([Entry]):    An array holding filesystem entries
         """
         entry.status = EntryPlayState.LOADING
         self.logger.info("Loading entry '%s'" % entry)
         is_ready = False
 
-        # Choose and save the input channel
+        # LIVE
         if entry.type == ChannelType.LIVE:
             entry.channel = "linein_" + entry.source.split("line://")[1]
             is_ready = True
         else:
-            self.player_state.set_active_entry(entry)
-            entry.channel = self.channel_swap(entry.type)
+            # Choose and save the input channel
+            entry.previous_channel, entry.channel = self.channel_swap(entry.type)
 
         # PLAYLIST
         if entry.type == ChannelType.FILESYSTEM:
@@ -243,45 +268,99 @@ class SoundSystem():
         if is_ready == True:
             entry.status = EntryPlayState.READY
 
+        # Store in play-log cache for later reference
+        self.player_state.add_to_history([entry])
+
+
+
+    def preroll_group(self, entries):
+        """
+        Pre-Rolls/Pre-Loads multiple filesystem entries at once. This call is required before the 
+        actual `play(..)` can happen. Due to their nature, non-filesystem entries cannot be queued
+        using this method. In this case use `preroll(self, entry)` instead. This method also allows
+        queuing of very short files, such as jingles.
+
+        It's important to note, that his method is blocking until loading has finished. If this 
+        method is called asynchronously, the progress on the preloading state can be looked up in 
+        `entry.state`.
+
+        Args:
+            entries ([Entry]):    An array holding filesystem entries
+        """
+        channel = None
+
+        # Validate entry type
+        for entry in entries:
+            if entry.type != ChannelType.FILESYSTEM:
+                raise InvalidChannelException
+        
+        # Determine channel
+        channel = self.channel_swap(entry.type)
+
+        # Queue entries
+        for entry in entries:
+            entry.status = EntryPlayState.LOADING
+            self.logger.info("Loading entry '%s'" % entry)
+
+            # Choose and save the input channel
+            entry.previous_channel, entry.channel = channel
+
+            if self.playlist_push(entry.channel, entry.source) == True:
+                entry.status = EntryPlayState.READY
+        
+        # Store in play-log cache for later reference
+        self.player_state.add_to_history(entries)
+
+
 
     def play(self, entry, transition):
         """
         Plays a new `Entry`. In case of a new schedule (or some intented, immediate transition),
         a clean channel is selected and transitions between old and new channel is performed.
 
-        This method expects that the entry is pre-loaded using `load(..)` before being played.
+        This method expects that the entry is pre-loaded using `preroll(..)` or `preroll_group(self, entries)`
+        before being played. In case the pre-roll has happened for a group of entries, only the 
+        first entry of the group needs to be passed.
 
         Args:
             entry (PlaylistEntry):          The audio source to be played
-            transition (TransitionType):    The type of transition to use e.g. fade-out.
+            transition (TransitionType):    The type of transition to use e.g. fade-in or instant volume level.
             queue (Boolean):                If `True` the entry is queued if the `ChannelType` does allow so; 
                 otherwise a new channel of the same type is activated
         
         """
-        try:
-            
-            # Move channel volume all the way up
+        with suppress(LQConnectionError):
+
+            # Instant activation or fade-in
             self.enable_transaction()
             if transition == TransitionType.FADE:
+                self.channel_select(entry.channel.value, True)
                 self.fade_in(entry)
             else:
-                self.channel_volume(entry.channel, entry.volume)
+                self.channel_activate(entry.channel.value, True)
             self.disable_transaction()
 
             # Update active channel and type
             self.active_channel[entry.type] = entry.channel     
-            
-            
-        except LQConnectionError:
-            # we already caught and handled this error in __send_lqc_command__, 
-            # but we do not want to execute this function further and pass the exception
-            pass
+
+            # Dear filesystem channels, please leave the room as you would like to find it!
+            if entry.previous_channel and entry.previous_channel in ChannelType.FILESYSTEM.channels:
+                def clean_up():
+                    # Wait a little, if there is some long fade-out. Note, this also means,
+                    # this channel should not be used for at least some seconds (including clearing time).
+                    time.sleep(2)
+                    self.enable_transaction()
+                    self.channel_activate(entry.previous_channel.value, False)
+                    res = self.playlist_clear(entry.previous_channel)
+                    self.logger.info("Clear Queue Response: "+res)
+                    self.disable_transaction()
+                Thread(target=clean_up).start()
 
 
 
     def on_play(self, source):
         """
-        Event Handler which is called by soundsystem implementation (i.e. Liquidsoap) 
+        Event Handler which is called by the soundsystem implementation (i.e. Liquidsoap) 
         when some entry is actually playing.
 
         Args:
@@ -304,8 +383,7 @@ class SoundSystem():
             entry (Entry):                  The entry to stop playing
             transition (TransitionType):    The type of transition to use e.g. fade-out.
         """
-
-        try:
+        with suppress(LQConnectionError):
             self.enable_transaction()
 
             if not entry.channel:
@@ -317,18 +395,17 @@ class SoundSystem():
             else:
                 self.channel_volume(entry.channel, 0)
 
-            # self.playlist_clear(entry.channel)
             self.logger.info(SimpleUtil.pink("Stopped channel '%s' for entry %s" % (entry.channel, entry)))
-
             self.disable_transaction()
 
-        except LQConnectionError:
-            # we already caught and handled this error in __send_lqc_command__, 
-            # but we do not want to execute this function further and pass the exception
-            pass
 
 
 
+    #
+    #   MIXER : CHANNEL
+    #
+
+
     def channel_swap(self, channel_type):
         """
         Returns the currently in-active channel for a given type. For example if the currently some
@@ -338,87 +415,99 @@ class SoundSystem():
         Args:
             channel_type (ChannelType): The channel type such es filesystem, stream or live channel
         """
-        active_channel = self.active_channel[channel_type]
-        channel = None
+        previous_channel = self.active_channel[channel_type]
+        new_channel = None
         msg = None
 
         if channel_type == ChannelType.FILESYSTEM:
-            if active_channel == Channel.FILESYSTEM_A:
-                channel = Channel.FILESYSTEM_B
+            if previous_channel == Channel.FILESYSTEM_A:
+                new_channel = Channel.FILESYSTEM_B
                 msg = "Swapped filesystem channel from A > B"
             else:
-                channel = Channel.FILESYSTEM_A
+                new_channel = Channel.FILESYSTEM_A
                 msg = "Swapped filesystem channel from B > A"
             
-            # TODO Clear old channel
-            
         elif channel_type == ChannelType.HTTP:
-            if active_channel == Channel.HTTP_A:
-                channel = Channel.HTTP_B
+            if previous_channel == Channel.HTTP_A:
+                new_channel = Channel.HTTP_B
                 msg = "Swapped HTTP Stream channel from A > B"
-
             else:
-                channel = Channel.HTTP_A
+                new_channel = Channel.HTTP_A
                 msg = "Swapped HTTP Stream channel from B > A"
 
-
         elif channel_type == ChannelType.HTTPS:
-            if active_channel == Channel.HTTPS_A:
-                channel = Channel.HTTPS_B
+            if previous_channel == Channel.HTTPS_A:
+                new_channel = Channel.HTTPS_B
                 msg = "Swapped HTTPS Stream channel from A > B"
-
             else:
-                channel = Channel.HTTPS_A
+                new_channel = Channel.HTTPS_A
                 msg = "Swapped HTTPS Stream channel from B > A"
             
+        if msg: self.logger.info(SimpleUtil.pink(msg))
+        return (previous_channel, new_channel)
 
 
-        if msg: self.logger.info(SimpleUtil.pink(msg))
-        return channel
 
+    def channel_status(self, channel_number):
+        """
+        Retrieves the status of a channel identified by the channel number.
+        """
+        return self.__send_lqc_command__(self.client, "mixer", "status", channel_number)
 
 
-    # ------------------------------------------------------------------------------------------ #
-    def all_inputs_but(self, input_type):
-        try:
-            activemixer_copy = self.get_all_channels().copy()
-            activemixer_copy.remove(input_type)
-        except ValueError as e:
-            self.logger.error("Requested channel (" + input_type + ") not in channellist. Reason: " + str(e))
-        except AttributeError:
-            self.logger.critical("Channellist is None")
 
-        return activemixer_copy
+    def channel_select(self, channel, select):
+        """
+        Selects/deselects some mixer channel
 
-    # ------------------------------------------------------------------------------------------ #
-    def get_all_channels(self):
-        if self.channels is None or len(self.channels) == 0:
-            self.channels = self.__send_lqc_command__(self.client, "mixer", "inputs")
+        Args:
+            pos (Integer): The channel number
+            select (Boolean): Select or deselect
 
-        return self.channels
+        Returns:
+            (String):   Liquidsoap server response
+        """
+        channels = self.mixer_channels()
 
-    # ------------------------------------------------------------------------------------------ #
-    def reload_channels(self):
-        self.channels = None
-        return self.get_all_channels()
+        try:
+            index = channels.index(channel)
+            if len(channel) < 1:
+                self.logger.critical("Cannot select channel. There are no channels!")
+            else:
+                message = self.__send_lqc_command__(self.client, "mixer", "select", index, select)
+                return message
+        except Exception as e:
+            self.logger.critical("Ran into exception when selecting channel. Reason: " + str(e))
 
 
 
-    # ------------------------------------------------------------------------------------------ #
     def channel_activate(self, channel, activate):
-        channels = self.get_all_channels()
+        """
+        Combined call of following to save execution time:
+          - Select some mixer channel
+          - Increase the volume to 100, 
+
+        Args:
+            pos (Integer):  The channel number
+            activate (Boolean): Activate or deactivate
+
+        Returns:
+            (String):   Liquidsoap server response
+        """
+        channels = self.mixer_channels()
 
         try:
             index = channels.index(channel)
             if len(channel) < 1:
                 self.logger.critical("Cannot activate channel. There are no channels!")
             else:
-                message = self.__send_lqc_command__(self.client, "mixer", "select", index, activate)
+                message = self.__send_lqc_command__(self.client, "mixer", "activate", index, activate)
                 return message
         except Exception as e:
             self.logger.critical("Ran into exception when activating channel. Reason: " + str(e))
 
-    # ------------------------------------------------------------------------------------------ #
+
+
     def channel_volume(self, channel, volume):
         """
         Set volume of a channel
@@ -427,14 +516,13 @@ class SoundSystem():
             channel (Channel):      The channel
             volume  (Integer)       Volume between 0 and 100
         """
-
         channel = str(channel)
         try:
             if str(volume) == "100":
-                channels = self.get_all_channels()
+                channels = self.mixer_channels()
                 index = channels.index(channel)
             else:
-                channels = self.get_all_channels()
+                channels = self.mixer_channels()
                 index = channels.index(channel)
         except ValueError as e:
             msg = SimpleUtil.red("Cannot set volume of channel " + channel + " to " + str(volume) + "!. Reason: " + str(e))
@@ -572,7 +660,7 @@ class SoundSystem():
 
 
     #
-    #   Channel Type - Playlist 
+    #   Channel Type - Filesystem 
     #
 
     # FIXME
@@ -613,7 +701,7 @@ class SoundSystem():
 
 
     #         self.enable_transaction()
-    #         self.reload_channels()
+    #         self.mixer_channels_reload()
     #         # self.fade_in(playlist.entries[0])
     #         # FIXME rework
     #         for new_entry in playlist.entries:
@@ -654,7 +742,8 @@ class SoundSystem():
         self.logger.info("%s.playlist_push result: %s" % (channel, result))
         self.disable_transaction()
 
-        return result == "1"
+        # If successful, Liquidsoap returns a resource ID of the queued track
+        return int(result) >= 0
 
 
 
@@ -680,6 +769,7 @@ class SoundSystem():
         return result
 
 
+
     def playlist_clear(self, channel):
         """
         Removes all tracks currently queued in the given `ChannelType.FILESYSTEM` channel.
@@ -702,6 +792,8 @@ class SoundSystem():
 
         return result
 
+
+
     #
     #   Fading 
     #
diff --git a/modules/core/monitor.py b/modules/core/monitor.py
index f4bbce0d11e38aa502bdb828f7e2bde05e303407..9c7b99666cfed39864fe129ac7cba2125cbce940 100644
--- a/modules/core/monitor.py
+++ b/modules/core/monitor.py
@@ -159,7 +159,7 @@ class Monitoring:
         self.status["soundsystem"]["version"]   = self.soundsystem.version()
         self.status["soundsystem"]["uptime"]    = self.soundsystem.uptime()
         self.status["soundsystem"]["io"]        = self.get_io_state()
-        self.status["soundsystem"]["mixer"]     = self.soundsystem.get_mixer_status()
+        self.status["soundsystem"]["mixer"]     = self.soundsystem.mixer_status()
         #self.status["soundsystem"]["recorder"] = self.soundsystem.get_recorder_status()
         self.soundsystem.disable_transaction(self.soundsystem.client)
     
diff --git a/modules/core/state.py b/modules/core/state.py
index 726c2ad212f096a73ca4a8af4f344ccb3b96d321..a0f7fa0dd2b802d9d07909481f8b07b0a6355af3 100644
--- a/modules/core/state.py
+++ b/modules/core/state.py
@@ -59,32 +59,24 @@ class PlayerStateService:
     #
 
 
-    def set_active_entry(self, entry):
+    def add_to_history(self, entries):
         """
-        Saves the currently playing entry to the local cache.
+        Saves the currently pre-rolled [`Entry`] to the local cache.
         """
         self.entry_history.pop() 
-        self.entry_history.appendleft(entry) 
-
-        msg = "Active entry history:\n"
-        msg += "\n" + str(self.entry_history[0])
-        msg += "\n" + str(self.entry_history[1])
-        msg += "\n" + str(self.entry_history[2])
-        self.logger.info(msg)
+        self.entry_history.appendleft(entries) 
 
 
-
-    def get_active_entry(self):
+    def get_recent_entries(self):
         """
-        Retrieves the currently playing `Entry` from the local cache.
+        Retrieves the currently playing [`Entry`] from the local cache.
         """
         return self.entry_history[0]
 
 
-
     def store_trackservice_entry(self, source):
         """
-        Stores the given entry in the Track Service.
+        Stores the entry identified by the given source in the Track Service.
 
         Args:
             source (String):    The URI of the currently playing source
@@ -92,25 +84,42 @@ class PlayerStateService:
         Raises:
             (NoActiveEntryException):    In case currently nothing is playing
         """
-        active_entry = self.get_active_entry()
+        found = False
+        entries = self.get_recent_entries()
 
-        if not active_entry:
+        if not entries:
             raise NoActiveEntryException
 
-        if active_entry.source == source:
-            trackservice = TrackService(active_entry)
-            trackservice.store(add=True, commit=True)
+        for active_entry in entries:
+            if active_entry.source == source:
+                trackservice = TrackService(active_entry)
+                trackservice.store(add=True, commit=True)
+
+                active_entry.trackservice_id = trackservice.id
+                active_entry.store(add=False, commit=True)
 
-            active_entry.trackservice_id = trackservice.id
-            active_entry.store(add=False, commit=True)
+                self.logger.info("Stored active entry '%s' to TrackService as '%s'" % (active_entry, trackservice))
+                found = True
 
-            self.logger.info("Stored active entry '%s' to TrackService as '%s'" % (active_entry, trackservice))
-        else:
-            msg = "Active entry source '%s' != '%s' activated source." % (active_entry.source, source)
+        if not found:
+            msg = "Found no entry in the recent history which matches the given source '%s'" % (source)
             self.logger.critical(SimpleUtil.red(msg))
 
 
 
+    def print_entry_history(self):
+        """
+        Prints all recents entries of the history.
+        """
+        msg = "Active entry history:\n"
+        for entries in self.entry_history:
+            msg += "["
+            for e in entries:
+                msg += "\n" + str(e)
+            msg += "]"
+        self.logger.info(msg)
+
+
 
     # def adapt_trackservice_title(self, source):
     #     """
diff --git a/modules/database/model.py b/modules/database/model.py
index dd01882be80f48707d30b3d5b7fb7d57a0ec42c6..20d2d6c7d9904fa27f570371ce28beed781532ff 100644
--- a/modules/database/model.py
+++ b/modules/database/model.py
@@ -423,7 +423,7 @@ class PlaylistEntry(DB.Model, AuraDatabaseModel):
     entry_start = Column(DateTime)
     queue_state = None # Assigned when entry is about to be queued
     channel = None # Assigned when entry is actually played
-    state = None # Assigned when state changes
+    status = None # Assigned when state changes
 
     # relationships
     playlist = relationship("Playlist", uselist=False, back_populates="entries")
@@ -720,7 +720,7 @@ class SingleEntry(DB.Model, AuraDatabaseModel):
 
     queue_state = None # Assigned when entry is about to be queued
     channel = None # Assigned when entry is actually played
-    state = None # Assigned when state changes
+    status = None # Assigned when state changes
 
 
     @hybrid_property
diff --git a/modules/scheduling/scheduler.py b/modules/scheduling/scheduler.py
index 4b2e5ab404647e71cde47c3131e673a8ed16054d..98d075f29f96bc640c6dc04acd6b297483a65765 100644
--- a/modules/scheduling/scheduler.py
+++ b/modules/scheduling/scheduler.py
@@ -196,8 +196,8 @@ class AuraScheduler(threading.Thread):
             if (seconds_to_seek + sleep_offset) > active_entry.duration:
                 self.logger.info("The FFWD [>>] range exceeds the length of the entry. Drink some tea and wait for the sound of the next entry.")
             else:
-                # Load and play active entry
-                self.soundsystem.load(active_entry)
+                # Pre-roll and play active entry
+                self.soundsystem.preroll(active_entry)
                 self.soundsystem.play(active_entry, TransitionType.FADE)
 
                 # Check if this is the last item of the schedule
@@ -219,8 +219,8 @@ class AuraScheduler(threading.Thread):
             or active_entry.type == ChannelType.HTTPS \
             or active_entry.type == ChannelType.LIVE:
 
-                # Load and play active entry
-                self.soundsystem.load(active_entry)
+                # Pre-roll and play active entry
+                self.soundsystem.preroll(active_entry)
                 self.soundsystem.play(active_entry, TransitionType.FADE)
 
                 self.queue_end_of_schedule(active_entry, True)
@@ -558,7 +558,6 @@ class AuraScheduler(threading.Thread):
 
 
 
-
     def queue_playlist_entries(self, entries, fade_in, fade_out):
         """
         Creates Liquidsoap player commands for all playlist items to be executed at the scheduled time.
@@ -571,58 +570,81 @@ class AuraScheduler(threading.Thread):
         Returns:
             (String):                   Formatted string to display playlist entries in log
         """       
+        entry_groups = []
+        entry_groups.append([])
+        previous_entry = None
+        index = 0
 
         # Mark entries which start after the end of their schedule or are cut
         clean_entries = self.preprocess_entries(entries, True)
 
-        # Schedule function calls
+        # Group all filesystem entries, allowing them to be queued at once
         for entry in clean_entries:
+            if previous_entry == None or \
+                (previous_entry != None and \
+                 previous_entry.type == entry.type and \
+                 entry.type == ChannelType.FILESYSTEM):
+                
+                entry_groups[index].append(entry)
+            else:
+                index += 1
+                entry_groups.append([])
+                entry_groups[index].append(entry)
 
-            self.set_entry_timer(entry, fade_in, fade_out)
+            previous_entry = entry
+        self.logger.info("Built %s entry group(s)" % len(entry_groups))
+         
+        # Schedule function calls
+        for entries in entry_groups:
+
+            self.set_entry_timer(entries, fade_in, fade_out)
 
             # Check if it's the last item, which needs special handling
-            if entry == clean_entries[-1]:
+            if entries[-1] == clean_entries[-1]:
                 # The end of schedule is the actual end of the track
-                self.queue_end_of_schedule(entry, fade_out)
+                self.queue_end_of_schedule(entries[-1], fade_out)
 
 
 
-    def set_entry_timer(self, entry, fade_in, fade_out):
+    def set_entry_timer(self, entries, fade_in, fade_out):
         """
-        Creates timer for loading and playing an entry. Existing timers are 
+        Creates timer for loading and playing one or multiple entries. Existing timers are 
         updated.
+
+        Args:
+            entries ([]): List of multiple filesystem entries, or a single entry of other types
         """
-        play_timer = self.is_something_planned_at_time(entry.start_unix)
+        play_timer = self.is_something_planned_at_time(entries[0].start_unix)
         now_unix = self.get_virtual_now()
-        diff = entry.start_unix - now_unix
+        diff = entries[0].start_unix - now_unix
 
         # Play function to be called by timer
-        def do_play(entry):
-            self.logger.info(SimpleUtil.cyan("=== play('%s') ===" % entry))
+        def do_play(entries):
+            self.logger.info(SimpleUtil.cyan("=== play('%s') ===" % EngineUtil.get_entries_string(entries)))
             transition_type = TransitionType.INSTANT
             if fade_in:
                 transition_type = TransitionType.FADE
 
-            if entry.status != EntryPlayState.READY:
-                self.logger.critical(SimpleUtil.red("PLAY: For some reason the entry is not yet ready or could not be loaded (Entry: %s)" % str(entry)))
+            if entries[-1].status != EntryPlayState.READY:
+                self.logger.critical(SimpleUtil.red("PLAY: For some reason the entry/entries is not yet ready or could not be loaded (Entries: %s)" % str(entries)))
                 # TODO Pro-active fallback handling here
 
-            self.soundsystem.play(entry, transition_type)
+            self.soundsystem.play(entries[0], transition_type)
             self.logger.info(self.get_ascii_programme())
 
 
         if play_timer:
             # Check if the Playlist IDs are different
-            if play_timer.entry.entry_id != entry.entry_id:
+            if play_timer.entries[0].entry_id != entries[0].entry_id:
                 # If not, stop and remove the old timer, create a new one
                 self.stop_timer(play_timer)                
             else:
                 # If the playlists do not differ => reuse the old timer and do nothing
-                self.logger.info("Playlist Entry %s is already scheduled - no new timer created!" % entry)
+                self.logger.info("Playlist Entry %s is already scheduled - no new timer created!" % str(entries))
                 return
         
         # If nothing is planned at given time, create a new timer
-        (entry.switchtimer, entry.loadtimer) = self.create_timer(diff, do_play, [entry], switcher=True)
+        (entries[0].switchtimer, entries[0].loadtimer) = self.create_timer(diff, do_play, [entries], switcher=True)
 
 
 
@@ -750,7 +772,7 @@ class AuraScheduler(threading.Thread):
         Checks for existing timers at the given time.
         """
         for t in self.message_timer:
-            if t.entry.start_unix == given_time and (t.fade_in or t.switcher):
+            if t.entry[0].start_unix == given_time and (t.fade_in or t.switcher):
                 return t
         return False
 
@@ -775,12 +797,16 @@ class AuraScheduler(threading.Thread):
 
         if switcher:
             # Load function to be called by timer
-            def do_load(entry):
-                self.logger.info(SimpleUtil.cyan("=== load('%s') ===" % entry))
+            def do_load(entries):
                 try:
-                    self.soundsystem.load(entry)
+                    if entries[0].type == ChannelType.FILESYSTEM:
+                        self.logger.info(SimpleUtil.cyan("=== preroll_group('%s') ===" % EngineUtil.get_entries_string(entries)))
+                        self.soundsystem.preroll_group(entries)
+                    else:
+                        self.logger.info(SimpleUtil.cyan("=== preroll('%s') ===" % EngineUtil.get_entries_string(entries)))
+                        self.soundsystem.preroll(entries[0])
                 except LoadSourceException as e:
-                    self.logger("Could not load entry %s:" % str(entry), e)
+                    self.logger("Could not load entries %s:" % EngineUtil.get_entries_string(entries), e)
                     # TODO Fallback logic here
 
             loader_diff = diff - self.config.get("preload_offset")
diff --git a/testing/connection_tester.py b/testing/connection_tester.py
index 4ab6c17190647d40be4fe31c5178066cd491680a..513e40d7012c10d6f0ac764df819d07f8dba28b9 100644
--- a/testing/connection_tester.py
+++ b/testing/connection_tester.py
@@ -63,7 +63,7 @@ class ConnectionTester(AuraConfig):
     def test_lqs_conn(self):
         try:
             lsc = soundsystem(self.config)
-            lsc.get_mixer_status()
+            lsc.mixer_status()
             return True
 
         except Exception as e: