/// <summary>
        /// Init initializes the ouput controller.<br />
        /// This method is called after the
        /// objects haven been instanciated.
        ///
        /// Specifically, Init is prepping the "Soundbank" for the currently supported 'hardware'
        /// and setting the user preffered output style/profiles via the following options:
        /// - Speakers: a valid named Speaker target regonized by Bass, eg 'Rear' or RearCenter'
        /// - BassShaker1: Location of "primary" Bass Shaker if not controlled be amp crossover, as recognized by Bass
        /// - BassShaker2: See Previous
        /// - LowImpactMode: true or false value determines if alternate routing/less overall intesity is used
        /// - DeviceNumber: Bass recognized soundcard output if not using Default system device. Devices are listed in DirectOutput.log
        /// Levels/Fine Tuning options: These all have values from 0 (minimum) to 100 (maximum)
        /// - ImpactFactor: Global Modifier for relative "effect" overall
        /// - ShakerImapactFactor: Fine tuning of Shaker intensity.
        /// - FlipperLevel: Fine tuning of the effect applied to the flippers
        /// - BumperLevel: same as above, for Pop Bumpers
        /// - SlingsLevel: the Slingshots and everything else
        /// </summary>
        /// <param name="Cabinet">The cabinet object which is using the output controller instance.</param>
        public override void Init(Cabinet Cabinet)
        {
            if (bank == null)
            {
                Log.Exception("Could not Initialize SSFImpactor");
                return;
            }

            try
            {
                _FrontExciterPair = (uint)(BassFlags)Enum.Parse(typeof(BassFlags), "Speaker" + _FrontExciters);
                _RearExciterPair  = (uint)(BassFlags)Enum.Parse(typeof(BassFlags), "Speaker" + _RearExciters);
                if (_Shaker1 != "None")
                {
                    _ShakerChannel1 = (uint)(BassFlags)Enum.Parse(typeof(BassFlags), "Speaker" + _Shaker1);
                }
                if (_Shaker2 != "None")
                {
                    _ShakerChannel2 = (uint)(BassFlags)Enum.Parse(typeof(BassFlags), "Speaker" + _Shaker2);
                }
            }
            catch
            {
                Log.Write("Invalid value for a Speaker in Cabinet.xml, using defaults ");
                _FrontExciterPair = (uint)BassFlags.SpeakerRear;
                _RearExciterPair  = (uint)BassFlags.SpeakerRearCenter;
                _ShakerChannel1   = (uint)BassFlags.SpeakerRearCenter;
                _ShakerChannel2   = (uint)BassFlags.SpeakerRear;
            }


            if (SoundBank.Names.Count == 0 || true)  // This should always be run
            {
                DeviceInfo mydevice;

                try
                {
                    bank.PrepBox(_DeviceNumber);
                    var info = Bass.Info;
                    try
                    {
                        for (int dev = 1; ; dev++)
                        {
                            var bd = Bass.GetDeviceInfo(dev);
                            Log.Write("BASS device " + dev.ToString() + " is " + bd.Name);
                        }
                    }
                    catch (Exception)
                    {
                        // You have to wait until GetDeviceInfo fails.  Yuck.
                    }

                    Log.Write("SSFImpactor DeviceNumber = " + _DeviceNumber);

                    if (_DeviceNumber == -1)
                    {
                        Log.Write("BASS using default Windows sound device");
                    }

                    Log.Write("BASS current device number = " + Bass.CurrentDevice);
                    mydevice = Bass.GetDeviceInfo(Bass.CurrentDevice);
                    Log.Write("BASS currnet device name: " + mydevice.Name);
                    Log.Write("BASS detects " + info.SpeakerCount.ToString() + " speakers.");

                    SSF.CopyTo(ssfStream);

                    if (_LowImpactMode)
                    {
                        stream = Bass.CreateStream(ssfStream.ToArray(), 0, ssfStream.Length, (BassFlags)_FrontExciterPair);

                        if ((stream == 0) && (Bass.LastError == Errors.Speaker))
                        {
                            Log.Write("Unable to assign FrontExciters stream to speakers: " + _FrontExciters);
                        }
                    }
                    else
                    {
                        stream = Bass.CreateStream(ssfStream.ToArray(), 0, ssfStream.Length, (BassFlags)_FrontExciterPair);
                        if ((stream == 0) && (Bass.LastError == Errors.Speaker))
                        {
                            Log.Write("Unable to assign FrontExciters stream to speakers: " + _FrontExciters);
                        }

                        stream1 = Bass.CreateStream(ssfStream.ToArray(), 0, ssfStream.Length, (BassFlags)_RearExciterPair);
                        if ((stream1 == 0) && (Bass.LastError == Errors.Speaker))
                        {
                            Log.Write("Unable to assign RearExciters stream to speakers: " + _RearExciters);
                        }
                    }


                    useFaker   = true;
                    fakeShaker = new Faker
                    {
                        Shaker1      = _Shaker1,
                        Shaker2      = _Shaker2,
                        ImpactEffect = _ShakeAmount
                    };

                    fakeGear = new SSFGear()
                    {
                        Shaker1   = _Shaker1,
                        GearLevel = _GearLevel
                    };

                    Log.Write("SSFShaker activated");
                    Log.Write("SSFImpactor \"Hardware\" Initialized\n");
                    haveBass = true;
                    AddOutputs();
                }
                catch (Exception e)
                {
                    Log.Write("Could Not Initialze Bass - " + e.Message);
                }
            }
        }
        /// <summary>
        /// Init initializes the ouput controller.<br />
        /// This method is called after the
        /// objects haven been instanciated.
        ///
        /// Specifically, Init is prepping the "Soundbank" for the currently supported 'hardware'
        /// and setting the user preffered output style/profiles via the following options:
        /// - Speakers: a valid named Speaker target regonized by Bass, eg 'Rear' or RearCenter'
        /// - BassShaker1: Location of "primary" Bass Shaker if not controlled be amp crossover, as recognized by Bass
        /// - BassShaker2: See Previous
        /// - LowImpactMode: true or false value determines if alternate routing/less overall intesity is used
        /// - DeviceNumber: Bass recognized soundcard output if not using Default system device. Devices are listed in DirectOutput.log
        /// Levels/Fine Tuning options: These all have values from 0 (minimum) to 100 (maximum)
        /// - ImpactFactor: Global Modifier for relative "effect" overall
        /// - ShakerImapactFactor: Fine tuning of Shaker intensity.
        /// - FlipperLevel: Fine tuning of the effect applied to the flippers
        /// - BumperLevel: same as above, for Pop Bumpers
        /// - SlingsLevel: the Slingshots and everything else
        /// </summary>
        /// <param name="Cabinet">The cabinet object which is using the output controller instance.</param>
        public override void Init(Cabinet Cabinet)
        {
            if (bank == null)
            {
                Log.Exception("Could not Initialize SSFImpactor");
                return;
            }

            try
            {
                _FrontExciterPair = (uint)(BassFlags)Enum.Parse(typeof(BassFlags), "Speaker" + _FrontExciters);
                _RearExciterPair  = (uint)(BassFlags)Enum.Parse(typeof(BassFlags), "Speaker" + _RearExciters);
                if (_Shaker1 != "None")
                {
                    _ShakerChannel1 = (uint)(BassFlags)Enum.Parse(typeof(BassFlags), "Speaker" + _Shaker1);
                }
                if (_Shaker2 != "None")
                {
                    _ShakerChannel2 = (uint)(BassFlags)Enum.Parse(typeof(BassFlags), "Speaker" + _Shaker2);
                }
            }
            catch
            {
                Log.Write("Invalid value for a Speaker in Cabinet.xml, using defaults ");
                _FrontExciterPair = (uint)BassFlags.SpeakerRear;
                _RearExciterPair  = (uint)BassFlags.SpeakerRear;
                _ShakerChannel1   = (uint)BassFlags.SpeakerRearCenter;
                _ShakerChannel2   = (uint)BassFlags.SpeakerRear;
            }


            if (SoundBank.Names.Count == 0)
            {
                try
                {
                    bank.PrepBox(_DeviceNumber);
                    var info = Bass.Info;
                    try
                    {
                        for (int dev = 1; ; dev++)
                        {
                            var bd = Bass.GetDeviceInfo(dev);
                            Log.Write("BASS device " + dev.ToString() + " is " + bd.Name);
                        }
                    }
                    catch (Exception)
                    {
                        // You have to wait until GetDeviceInfo fails.  Yuck.
                    }

                    Log.Write("BASS detects " + info.SpeakerCount.ToString() + " speakers.");

                    SSF.CopyTo(ssfStream);

                    /*
                     * if(_LowImpactMode || File.Exists(@"C:\DirectOutput\SSFLI"))
                     * {
                     *  stream = Bass.CreateStream(ssfStream.ToArray(), 0, ssfStream.Length, BassFlags.SpeakerRearRight);
                     * }
                     * else
                     * {
                     */
                    stream  = Bass.CreateStream(ssfStream.ToArray(), 0, ssfStream.Length, (BassFlags)_FrontExciterPair);
                    stream1 = Bass.CreateStream(ssfStream.ToArray(), 0, ssfStream.Length, (BassFlags)_RearExciterPair);

                    //}


                    useFaker   = true;
                    fakeShaker = new Faker
                    {
                        Shaker1      = _Shaker1,
                        Shaker2      = _Shaker2,
                        ImpactEffect = _ShakeAmount
                    };

                    fakeGear = new SSFGear()
                    {
                        GearLevel = _GearLevel
                    };

                    Log.Write("SSFShaker activated");
                    Log.Write("SSFImpactor \"Hardware\" Initialized\n");
                    haveBass = true;
                    AddOutputs();
                }
                catch (Exception e)
                {
                    Log.Write("Could Not Initialze Bass - " + e.Message);
                }
            }
        }