Inheritance: NVorbis.OpenTKSupport.LoggerBase
        static void Main()
        {
#if TRACE
            Trace.Listeners.Add(new ConsoleTraceListener());
#endif
            Console.WindowHeight = StreamFiles.Length + 12;

            Console.WriteLine("Pr[e]pare, [P]lay, [S]top, Pa[u]se, [R]esume, [L]oop toggle, [Q]uit");
            Console.WriteLine("Faders (in/out) : Low-pass filter [F]/[G], Volume [V]/[B]");
            Console.WriteLine("[Up], [Down] : Change current sample");
            Console.WriteLine("[Shift] + Action : Do for all " + StreamFiles.Length + " streams");

            var logger = new ConsoleLogger();
            logger.Write(" #  FX Buffering", 0, 8);

            using (new AudioContext())
                using (var streamer = new OggStreamer(65536))
                {
                    streamer.Logger = logger;
                    ALHelper.CheckCapabilities(logger);

                    bool quit = false;

                    var streams = new OggStream[StreamFiles.Length];

                    for (int i = 0; i < StreamFiles.Length; i++)
                    {
                        streams[i] = new OggStream(StreamFiles[i])
                        {
                            Logger = logger
                        };
                        logger.SetStreamIndex(streams[i], i);
                        logger.Write((i + 1).ToString(), 1, 10 + i);
                    }
                    logger.Write(">", 0, 10);
                    foreach (var s in streams)
                    {
                        s.Prepare();
                    }

                    int sIdx      = 0;
                    var activeSet = new List <OggStream>();

                    while (!quit)
                    {
                        var input = Console.ReadKey(true);

                        activeSet.Clear();
                        if ((input.Modifiers & ConsoleModifiers.Shift) == ConsoleModifiers.Shift)
                        {
                            activeSet.AddRange(streams);
                        }
                        else
                        {
                            activeSet.Add(streams[sIdx]);
                        }

                        var lower = char.ToLower(input.KeyChar);
                        if (input.Key == ConsoleKey.UpArrow)
                        {
                            lower = '-';
                        }
                        if (input.Key == ConsoleKey.DownArrow)
                        {
                            lower = '+';
                        }

                        switch (lower)
                        {
                        case 'e': activeSet.ForEach(x => x.Prepare()); break;

                        case 'p': activeSet.ForEach(x => x.Play()); break;

                        case 'u': activeSet.ForEach(x => x.Pause()); break;

                        case 's': activeSet.ForEach(x => x.Stop()); break;

                        case 'r': activeSet.ForEach(x => x.Resume()); break;

                        case 'l':
                            int index = 0;
                            activeSet.ForEach(s =>
                            {
                                s.IsLooped = !s.IsLooped;
                                logger.Write(s.IsLooped ? "L" : " ", 3, 10 + sIdx + index++);
                            });
                            break;

                        case 'v': FadeVolume(activeSet, true, 1, logger); break;

                        case 'b': FadeVolume(activeSet, false, 1, logger); break;

                        case 'f': FadeFilter(activeSet, true, 1, logger); break;

                        case 'g': FadeFilter(activeSet, false, 1, logger); break;

                        case '+':
                            logger.Write(" ", 0, 10 + sIdx);
                            sIdx++;
                            if (sIdx > streams.Length - 1)
                            {
                                sIdx = 0;
                            }
                            logger.Write(">", 0, 10 + sIdx);
                            break;

                        case '-':
                            logger.Write(" ", 0, 10 + sIdx);
                            sIdx--;
                            if (sIdx < 0)
                            {
                                sIdx = streams.Length - 1;
                            }
                            logger.Write(">", 0, 10 + sIdx);
                            break;

                        case 'q':
                            quit = true;
                            foreach (var cts in filterFades.Values)
                            {
                                cts.Cancel();
                            }
                            foreach (var cts in volumeFades.Values)
                            {
                                cts.Cancel();
                            }
                            foreach (var s in streams)
                            {
                                s.Stop();                        // nicer and more effective
                            }
                            foreach (var s in streams)
                            {
                                s.Dispose();
                            }
                            break;
                        }
                    }
                }
        }