/// <summary>
        /// Retrieves information on a device and adds it to the static deviceinfo dictionary do it can be reused later.
        /// </summary>
        /// <param name="deviceNo">Device number to retrieve information on.</param>
        protected void CollectDeviceInfo(int deviceNo)
        {
            // Device info is saved in a dictionary so it can be reused lateron.
            if (!_deviceInfos.ContainsKey(deviceNo))
            {
                Log.Debug("Collecting device info");

                BASS_WASAPI_DEVICEINFO bassDeviceInfo = BassWasapi.BASS_WASAPI_GetDeviceInfo(deviceNo);
                if (bassDeviceInfo == null)
                {
                    throw new BassLibraryException("BASS_WASAPI_GetDeviceInfo");
                }

                BASS_WASAPI_INFO bassInfo = BassWasapi.BASS_WASAPI_GetInfo();
                if (bassInfo == null)
                {
                    throw new BassLibraryException("BASS_WASAPI_GetInfo");
                }

                DeviceInfo deviceInfo = new DeviceInfo
                {
                    Name     = bassDeviceInfo.name,
                    Driver   = "WASAPI",
                    Channels = bassInfo.chans,
                    MinRate  = bassInfo.freq,
                    MaxRate  = bassInfo.freq,
                };

                GetDeviceFormats(deviceNo, deviceInfo);
                lock (_deviceInfos)
                    _deviceInfos.Add(deviceNo, deviceInfo);
            }
            Log.Debug("WASAPI device info: {0}", _deviceInfos[_deviceNo].ToString());
        }
Exemplo n.º 2
0
        /// <summary>
        /// Create a mixer using the stream attributes
        /// </summary>
        /// <param name="stream"></param>
        /// <returns></returns>
        public bool CreateMixer(MusicStream stream)
        {
            Log.Debug("BASS: ---------------------------------------------");
            Log.Debug("BASS: Creating BASS mixer stream");

            bool result = false;

            BASSFlag mixerFlags = BASSFlag.BASS_MIXER_NONSTOP | BASSFlag.BASS_SAMPLE_FLOAT | BASSFlag.BASS_MIXER_NORAMPIN;

            if (Config.MusicPlayer == AudioPlayer.Asio || Config.MusicPlayer == AudioPlayer.WasApi)
            {
                mixerFlags |= BASSFlag.BASS_STREAM_DECODE;
            }

            int outputChannels = _bassPlayer.DeviceChannels;

            _mixingMatrix = null;

            // See, if we need Upmixing
            if (outputChannels > stream.ChannelInfo.chans)
            {
                Log.Debug("BASS: Found more output channels ({0}) than input channels ({1}). Check for upmixing.", outputChannels,
                          stream.ChannelInfo.chans);
                _mixingMatrix = CreateMixingMatrix(stream.ChannelInfo.chans);
                if (_mixingMatrix != null)
                {
                    outputChannels = Math.Min(_mixingMatrix.GetLength(0), outputChannels);
                    _upmixing      = true;
                }
                else
                {
                    outputChannels = stream.ChannelInfo.chans;
                }
            }
            else if (outputChannels < stream.ChannelInfo.chans)
            {
                // Downmix to Stereo
                Log.Debug("BASS: Found more input channels ({0}) than output channels ({1}). Downmix.", stream.ChannelInfo.chans,
                          outputChannels);
                outputChannels = Math.Min(outputChannels, 2);
            }

            Log.Debug("BASS: Creating {0} channel mixer with sample rate of {1}", outputChannels, stream.ChannelInfo.freq);
            _mixer = BassMix.BASS_Mixer_StreamCreate(stream.ChannelInfo.freq, outputChannels, mixerFlags);
            if (_mixer == 0)
            {
                Log.Error("BASS: Unable to create Mixer.  Reason: {0}.",
                          Enum.GetName(typeof(BASSError), Bass.BASS_ErrorGetCode()));
                return(false);
            }

            switch (Config.MusicPlayer)
            {
            case AudioPlayer.Bass:
            case AudioPlayer.DShow:

                if (!Bass.BASS_ChannelPlay(_mixer, false))
                {
                    Log.Error("BASS: Unable to start Mixer.  Reason: {0}.", Enum.GetName(typeof(BASSError), Bass.BASS_ErrorGetCode()));
                    return(false);
                }

                result = true;

                break;

            case AudioPlayer.Asio:

                Log.Info("BASS: Initialising ASIO device");

                if (BassAsio.BASS_ASIO_IsStarted() && !BassAsio.BASS_ASIO_Stop())
                {
                    Log.Error("BASS: Error stopping Asio Device: {0}", BassAsio.BASS_ASIO_ErrorGetCode());
                }

                // Disable and Unjoin all the channels
                if (!BassAsio.BASS_ASIO_ChannelReset(false, -1, BASSASIOReset.BASS_ASIO_RESET_ENABLE))
                {
                    Log.Error("BASS: Error disabling Asio Channels: {0}", BassAsio.BASS_ASIO_ErrorGetCode());
                }

                if (!BassAsio.BASS_ASIO_ChannelReset(false, -1, BASSASIOReset.BASS_ASIO_RESET_JOIN))
                {
                    Log.Error("BASS: Error unjoining Asio Channels: {0}", BassAsio.BASS_ASIO_ErrorGetCode());
                }

                _asioProc = new ASIOPROC(AsioCallback);

                BassAsio.BASS_ASIO_ChannelSetVolume(false, -1, (float)Config.StreamVolume / 100f);

                // enable 1st output channel...(0=first)
                Log.Debug("BASS: Joining Asio Channel #{0}", "0");
                BassAsio.BASS_ASIO_ChannelEnable(false, 0, _asioProc, new IntPtr(_mixer));

                // and join the next channels to it
                int numChannels = Math.Max(stream.ChannelInfo.chans, outputChannels);
                for (int i = 1; i < numChannels; i++)
                {
                    Log.Debug("BASS: Joining Asio Channel #{0}", i);
                    BassAsio.BASS_ASIO_ChannelJoin(false, i, 0);
                }

                // since we joined the channels, the next commands will apply to all channles joined
                // so setting the values to the first channels changes them all automatically
                // set the source format (float, as the decoding channel is)
                if (!BassAsio.BASS_ASIO_ChannelSetFormat(false, 0, BASSASIOFormat.BASS_ASIO_FORMAT_FLOAT))
                {
                    Log.Error("BASS: Error setting Asio Sample Format: {0}", BassAsio.BASS_ASIO_ErrorGetCode());
                }

                // set the source rate
                Log.Debug("BASS: Set sample rate to {0}", stream.ChannelInfo.freq);
                if (!BassAsio.BASS_ASIO_ChannelSetRate(false, 0, (double)stream.ChannelInfo.freq))
                {
                    Log.Error("BASS: Error setting Asio Channel Samplerate: {0}", BassAsio.BASS_ASIO_ErrorGetCode());
                }

                // try to set the device rate too (saves resampling)
                if (!BassAsio.BASS_ASIO_SetRate((double)stream.ChannelInfo.freq))
                {
                    Log.Error("BASS: Error setting Asio Samplerate: {0}", BassAsio.BASS_ASIO_ErrorGetCode());
                }

                // and start playing it...start output using default buffer/latency
                if (!BassAsio.BASS_ASIO_Start(0))
                {
                    Log.Error("BASS: Error starting Asio playback: {0}", BassAsio.BASS_ASIO_ErrorGetCode());
                }
                Log.Info("BASS: Finished initialising ASIO device");
                result = true;

                break;

            case AudioPlayer.WasApi:

                Log.Info("BASS: Initialising WASAPI device");

                try
                {
                    BassWasapi.BASS_WASAPI_Free();
                    Log.Debug("BASS: Freed WASAPI device");
                }
                catch (Exception ex)
                {
                    Log.Error("BASS: Exception freeing WASAPI. {0} {1}", ex.Message, ex.StackTrace);
                }

                BASSWASAPIInit initFlags = BASSWASAPIInit.BASS_WASAPI_AUTOFORMAT;

                _wasapiProc = new WASAPIPROC(WasApiCallback);

                bool wasApiExclusiveSupported = true;

                // Check if we have an uneven number of channels
                var chkChannels = outputChannels % 2;
                if (chkChannels == 1)
                {
                    Log.Warn("BASS: Found uneven number of channels {0}. increase output channels.", outputChannels);
                    outputChannels++;                 // increase the number of output channels
                    wasApiExclusiveSupported = false; // And indicate that we need a new mixer
                }

                // Handle the special cases of 3.0, 4.0 and 5.0 files being played on a 5.1 or 6.1 device
                if (outputChannels == 3) // a 3.0 file
                {
                    Log.Info("BASS: Found a 3 channel file. Set upmixing with LFE, LR, RR set to silent");
                    _mixingMatrix            = CreateThreeDotZeroUpMixMatrix();
                    outputChannels           = _bassPlayer.DeviceChannels; // WASAPI device should be initialised with all channels active
                    wasApiExclusiveSupported = false;                      // And indicate that we need a new mixer
                }
                else if (outputChannels == 4)                              // a 4.0 file
                {
                    Log.Info("BASS: Found a 4 channel file. Set upmixing with Center and LFE set to silent");
                    _mixingMatrix            = CreateFourDotZeroUpMixMatrix();
                    outputChannels           = _bassPlayer.DeviceChannels; // WASAPI device should be initialised with all channels active
                    wasApiExclusiveSupported = false;                      // And indicate that we need a new mixer
                }
                else if (outputChannels == 5)                              // a 5.0 file
                {
                    Log.Info("BASS: Found a 5 channel file. Set upmixing with LFE set to silent");
                    _mixingMatrix            = CreateFiveDotZeroUpMixMatrix();
                    outputChannels           = _bassPlayer.DeviceChannels; // WASAPI device should be initialised with all channels active
                    wasApiExclusiveSupported = false;                      // And indicate that we need a new mixer
                }

                // If Exclusive mode is used, check, if that would be supported, otherwise init in shared mode
                if (Config.WasApiExclusiveMode)
                {
                    initFlags        |= BASSWASAPIInit.BASS_WASAPI_EXCLUSIVE;
                    _wasapiShared     = false;
                    _wasapiMixedChans = 0;
                    _wasapiMixedFreq  = 0;

                    BASSWASAPIFormat wasapiFormat = BassWasapi.BASS_WASAPI_CheckFormat(_bassPlayer.DeviceNumber,
                                                                                       stream.ChannelInfo.freq,
                                                                                       outputChannels,
                                                                                       BASSWASAPIInit.BASS_WASAPI_EXCLUSIVE);
                    if (wasapiFormat == BASSWASAPIFormat.BASS_WASAPI_FORMAT_UNKNOWN)
                    {
                        Log.Warn("BASS: WASAPI exclusive mode not directly supported. Let BASS WASAPI choose better mode.");
                        wasApiExclusiveSupported = false;
                    }
                }
                else
                {
                    Log.Debug("BASS: Init WASAPI shared mode with Event driven system enabled.");
                    initFlags |= BASSWASAPIInit.BASS_WASAPI_SHARED | BASSWASAPIInit.BASS_WASAPI_EVENT;

                    // In case of WASAPI Shared mode we need to setup the mixer to use the same sample rate as set in
                    // the Windows Mixer, otherwise we wioll have increased playback speed
                    BASS_WASAPI_DEVICEINFO devInfo = BassWasapi.BASS_WASAPI_GetDeviceInfo(_bassPlayer.DeviceNumber);
                    Log.Debug("BASS: Creating {0} channel mixer for frequency {1}", devInfo.mixchans, devInfo.mixfreq);
                    _mixer = BassMix.BASS_Mixer_StreamCreate(devInfo.mixfreq, devInfo.mixchans, mixerFlags);
                    if (_mixer == 0)
                    {
                        Log.Error("BASS: Unable to create Mixer.  Reason: {0}.",
                                  Enum.GetName(typeof(BASSError), Bass.BASS_ErrorGetCode()));
                        return(false);
                    }
                    _wasapiShared = true;
                }

                Log.Debug("BASS: Try to init WASAPI with a Frequency of {0} and {1} channels", stream.ChannelInfo.freq, outputChannels);

                if (BassWasapi.BASS_WASAPI_Init(_bassPlayer.DeviceNumber, stream.ChannelInfo.freq, outputChannels,
                                                initFlags | BASSWASAPIInit.BASS_WASAPI_BUFFER, Convert.ToSingle(Config.BufferingMs / 1000.0), 0f, _wasapiProc, IntPtr.Zero))
                {
                    BASS_WASAPI_INFO wasapiInfo = BassWasapi.BASS_WASAPI_GetInfo();

                    Log.Debug("BASS: ---------------------------------------------");
                    Log.Debug("BASS: Buffer Length: {0}", wasapiInfo.buflen);
                    Log.Debug("BASS: Channels: {0}", wasapiInfo.chans);
                    Log.Debug("BASS: Frequency: {0}", wasapiInfo.freq);
                    Log.Debug("BASS: Format: {0}", wasapiInfo.format.ToString());
                    Log.Debug("BASS: InitFlags: {0}", wasapiInfo.initflags.ToString());
                    Log.Debug("BASS: Exclusive: {0}", wasapiInfo.IsExclusive.ToString());
                    Log.Debug("BASS: ---------------------------------------------");
                    Log.Info("BASS: WASAPI Device successfully initialised");

                    // Now we need to check, if WASAPI decided to switch to a different mode
                    if (Config.WasApiExclusiveMode && !wasApiExclusiveSupported)
                    {
                        // Recreate Mixer with new value
                        Log.Debug("BASS: Creating new {0} channel mixer for frequency {1}", wasapiInfo.chans, wasapiInfo.freq);
                        _mixer = BassMix.BASS_Mixer_StreamCreate(wasapiInfo.freq, wasapiInfo.chans, mixerFlags);
                        if (_mixer == 0)
                        {
                            Log.Error("BASS: Unable to create Mixer.  Reason: {0}.",
                                      Enum.GetName(typeof(BASSError), Bass.BASS_ErrorGetCode()));
                            return(false);
                        }
                    }

                    BassWasapi.BASS_WASAPI_SetVolume(BASSWASAPIVolume.BASS_WASAPI_CURVE_DB, (float)Config.StreamVolume / 100f);
                    BassWasapi.BASS_WASAPI_Start();
                    result = true;
                }
                else
                {
                    Log.Error("BASS: Couldn't init WASAPI device. Error: {0}", Enum.GetName(typeof(BASSError), Bass.BASS_ErrorGetCode()));
                }
                break;
            }

            if (result)
            {
                Log.Debug("BASS: Successfully created BASS Mixer stream");
            }
            return(result);
        }
Exemplo n.º 3
0
 public static extern bool BASS_WASAPI_GetInfo(BASS_WASAPI_INFO info);
        public override void SetInputStream(BassStream stream, bool passThrough)
        {
            if (_deviceState != DeviceState.Stopped)
            {
                throw new BassPlayerException("Device state is not 'DeviceState.Stopped'");
            }

            _inputStream = stream;
            _flags       = BASSWASAPIInit.BASS_WASAPI_AUTOFORMAT | BASSWASAPIInit.BASS_WASAPI_BUFFER;

            // If Exclusive mode is used, check, if that would be supported, otherwise init in shared mode
            bool isExclusive = Controller.GetSettings().WASAPIExclusiveMode;

            if (isExclusive)
            {
                _flags |= BASSWASAPIInit.BASS_WASAPI_EXCLUSIVE;

                BASSWASAPIFormat wasapiFormat = BassWasapi.BASS_WASAPI_CheckFormat(_deviceNo,
                                                                                   _inputStream.SampleRate,
                                                                                   _inputStream.Channels,
                                                                                   BASSWASAPIInit.BASS_WASAPI_EXCLUSIVE);
                if (wasapiFormat == BASSWASAPIFormat.BASS_WASAPI_FORMAT_UNKNOWN)
                {
                    Log.Info("BASS: WASAPI exclusive mode not directly supported for samplerate of {0} and {1} channels", _inputStream.SampleRate, _inputStream.Channels);
                    isExclusive = false;
                }
            }

retry:
            if (!isExclusive)
            {
                Log.Debug("BASS: Init WASAPI shared mode with Event driven system enabled.");
                _flags &= ~BASSWASAPIInit.BASS_WASAPI_EXCLUSIVE;
                _flags |= BASSWASAPIInit.BASS_WASAPI_SHARED | BASSWASAPIInit.BASS_WASAPI_EVENT;
            }

            Log.Debug("BASS: Try to init WASAPI with a samplerate of {0} and {1} channels", _inputStream.SampleRate, _inputStream.Channels);

            bool result = BassWasapi.BASS_WASAPI_Init(_deviceNo, _inputStream.SampleRate, _inputStream.Channels, _flags, 0.5f, 0f, _streamWriteProcDelegate, IntPtr.Zero);

            BASSError?bassInitErrorCode = result ? null : new BASSError?(Bass.BASS_ErrorGetCode());

            if (bassInitErrorCode.HasValue)
            {
                if (bassInitErrorCode.Value == BASSError.BASS_ERROR_ALREADY)
                {
                    if (!BassWasapi.BASS_WASAPI_SetDevice(_deviceNo))
                    {
                        throw new BassLibraryException("BASS_WASAPI_SetDevice");
                    }
                }
                else if (isExclusive)
                {
                    // Allow one retry in shared mode
                    Log.Warn("BASS: Failed to initialize WASAPI exclusive mode for samplerate of {0} and {1} channels. Trying fallback to shared mode.", _inputStream.SampleRate, _inputStream.Channels);
                    isExclusive = false;
                    goto retry;
                }
                else
                {
                    throw new BassLibraryException("BASS_WASAPI_Init");
                }
            }

            // If the GetDeviceNo() method returned BassConstants.BassDefaultDevice, we must request the actual device number
            // of the choosen default device
            _deviceNo = BassWasapi.BASS_WASAPI_GetDevice();

            CollectDeviceInfo(_deviceNo);
            BASS_WASAPI_INFO wasapiInfo = BassWasapi.BASS_WASAPI_GetInfo();

            Log.Debug("BASS: ---------------------------------------------");
            Log.Debug("BASS: Buffer Length: {0}", wasapiInfo.buflen);
            Log.Debug("BASS: Channels: {0}", wasapiInfo.chans);
            Log.Debug("BASS: Frequency: {0}", wasapiInfo.freq);
            Log.Debug("BASS: Format: {0}", wasapiInfo.format.ToString());
            Log.Debug("BASS: InitFlags: {0}", wasapiInfo.initflags.ToString());
            Log.Debug("BASS: Exclusive: {0}", wasapiInfo.IsExclusive.ToString());
            Log.Debug("BASS: ---------------------------------------------");
            Log.Info("BASS: WASAPI Device successfully initialised");

            // For shared mode we require a mixer to change the sampling rates of input stream to device output stream.
            if (!wasapiInfo.IsExclusive)
            {
                // Recreate Mixer with new value
                Log.Debug("BASS: Creating new {0} channel mixer for frequency {1}", wasapiInfo.chans, wasapiInfo.freq);
                _mixerHandle = BassMix.BASS_Mixer_StreamCreate(wasapiInfo.freq, wasapiInfo.chans, MIXER_FLAGS);
                if (_mixerHandle == BassConstants.BassInvalidHandle)
                {
                    throw new BassLibraryException("BASS_Mixer_StreamCreate");
                }
                _mixer = BassStream.Create(_mixerHandle);
                AttachStream();
            }

            int ms = Convert.ToInt32(Controller.GetSettings().DirectSoundBufferSize.TotalMilliseconds);

            if (!Bass.BASS_SetConfig(BASSConfig.BASS_CONFIG_BUFFER, ms))
            {
                throw new BassLibraryException("BASS_SetConfig");
            }

            // Enable update thread while the output device is active
            if (!Bass.BASS_SetConfig(BASSConfig.BASS_CONFIG_UPDATEPERIOD, ms / 4))
            {
                throw new BassLibraryException("BASS_SetConfig");
            }

            if (passThrough)
            {
                _fader = new BassStreamFader(_inputStream, Controller.GetSettings().FadeDuration);
            }

            ResetState();
        }
Exemplo n.º 5
0
        public static void SetDevice(int inputDevice, int outputDevice)
        {
            thisControl = PlayerControl.MainFormControl;

            //Get some info about their selected input device
            var inputdeviceinfo = BassWasapi.BASS_WASAPI_GetDeviceInfo(inputDevice);

            InputDevice     = inputDevice;
            InputDeviceInfo = inputdeviceinfo;

            //Get some info about their selected ouput device
            var outputdeviceinfo = BassWasapi.BASS_WASAPI_GetDeviceInfo(outputDevice);

            OutputDevice     = outputDevice;
            OutputDeviceInfo = outputdeviceinfo;


            if (!m_isWasapiInit)
            {
                Bass.BASS_SetConfig(BASSConfig.BASS_CONFIG_UPDATEPERIOD, 0);
                Bass.BASS_SetConfig(BASSConfig.BASS_CONFIG_FLOATDSP, true);
                Bass.BASS_Init(0, 44100, BASSInit.BASS_DEVICE_DEFAULT, PlayerControl.MainFormControl.Handle);

                Player.Mixer = MixerStreamCreate(outputdeviceinfo.mixfreq);

                if (Player.Mixer == 0)
                {
                    var error = Bass.BASS_ErrorGetCode();
                    MessageBox.Show(error.ToString(), "Could not create mixer!");
                    Bass.BASS_Free();
                    return;
                }

                _outstream = Player.Mixer;

                _instream = Bass.BASS_StreamCreatePush(inputdeviceinfo.mixfreq, inputdeviceinfo.mixchans, BASSFlag.BASS_SAMPLE_FLOAT | BASSFlag.BASS_STREAM_DECODE, IntPtr.Zero);
                // create a stream to receive the data
                // string fn = @"D:\tanie\karaokeNow Resources\LdVocal_01.wav";
                // _instream = Bass.BASS_StreamCreateFile(fn, 0L, 0L, BASSFlag.BASS_SAMPLE_FLOAT | BASSFlag.BASS_STREAM_DECODE | BASSFlag.BASS_SAMPLE_LOOP);

                //_stream[0] = BassMix.BASS_Split_StreamCreate(_instream, BASSFlag.BASS_SAMPLE_FLOAT | BASSFlag.BASS_STREAM_DECODE, null);//_instream;
                //_stream[1] = BassMix.BASS_Split_StreamCreate(_instream, BASSFlag.BASS_SAMPLE_FLOAT | BASSFlag.BASS_STREAM_DECODE, null);// _instream;
                //_stream[2] = BassMix.BASS_Split_StreamCreate(_instream, BASSFlag.BASS_SAMPLE_FLOAT | BASSFlag.BASS_STREAM_DECODE, null);//_instream;
                //_stream[3] = BassMix.BASS_Split_StreamCreate(_instream, BASSFlag.BASS_SAMPLE_FLOAT | BASSFlag.BASS_STREAM_DECODE, null);//_instream;


                //  _outstream = BassMix.BASS_Mixer_StreamCreate(outputdeviceinfo.mixfreq, outputdeviceinfo.mixchans, BASSFlag.BASS_SAMPLE_FLOAT | BASSFlag.BASS_STREAM_DECODE);
                //  Player.Mixer = _outstream;

                //Group 1 VST Effects ============================================================
                Channel1Fx.SetEffects(_instream);


                //Group 2 VST Effects ============================================================
                // Channel2Fx.SetEffects(_stream[1]);


                //Group 3 VST Effects ============================================================
                //Channel3Fx.SetEffects(_stream[2]);


                //Group 4 VST Effects ============================================================
                //Channel4Fx.SetEffects(_stream[3]);

                BassMix.BASS_Mixer_StreamAddChannel(_outstream, _instream, 0);
                // BassMix.BASS_Mixer_StreamAddChannel(_outstream, _stream[1], 0);
                //BassMix.BASS_Mixer_StreamAddChannel(_outstream, _stream[2], 0);
                // BassMix.BASS_Mixer_StreamAddChannel(_outstream, _stream[3], 0);

                m_isWasapiInit = true;
            }

            _wasapiInProc = new WASAPIPROC(InputProc);
            GC.KeepAlive(_wasapiInProc);


            _wasapiOutProc = new WASAPIPROC(OutputProc);
            GC.KeepAlive(_wasapiOutProc);

            //Set the input device so subsequent calls are on it
            BassWasapi.BASS_WASAPI_SetDevice(InputDevice);
            // Initialize BASS WASAPI input
            BASS_WASAPI_INFO input = new BASS_WASAPI_INFO();

            BassWasapi.BASS_WASAPI_GetInfo(input);

            BassWasapi.BASS_WASAPI_Init(inputDevice, inputdeviceinfo.mixfreq, inputdeviceinfo.mixchans,
                                        BASSWASAPIInit.BASS_WASAPI_EVENT | BASSWASAPIInit.BASS_WASAPI_BUFFER | BASSWASAPIInit.BASS_WASAPI_SHARED, input.buflen, 0, _wasapiInProc, IntPtr.Zero);

            //Set the output device so subsequent calls are on it
            BassWasapi.BASS_WASAPI_SetDevice(OutputDevice);
            BASS_WASAPI_INFO output = new BASS_WASAPI_INFO();

            BassWasapi.BASS_WASAPI_GetInfo(output);

            // Initialize BASS WASAPI output
            BassWasapi.BASS_WASAPI_Init(outputDevice, outputdeviceinfo.mixfreq, outputdeviceinfo.mixchans,
                                        BASSWASAPIInit.BASS_WASAPI_EVENT | BASSWASAPIInit.BASS_WASAPI_SHARED, output.buflen, 0, _wasapiOutProc, IntPtr.Zero);
        }