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); float buffer = (float)Controller.GetSettings().PlaybackBufferSizeMilliSecs / 1000; bool result = BassWasapi.BASS_WASAPI_Init(_deviceNo, _inputStream.SampleRate, _inputStream.Channels, _flags, buffer, 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().DirectSoundBufferSizeMilliSecs); 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, TimeSpan.FromMilliseconds(Controller.GetSettings().FadeDurationMilliSecs)); } // Init volume/mute mode _bassWASAPIVolScope = isExclusive? BASSWASAPIVolume.BASS_WASAPI_VOL_DEVICE : BASSWASAPIVolume.BASS_WASAPI_VOL_SESSION; ResetState(); }
public static extern bool BASS_WASAPI_GetMute(BASSWASAPIVolume mode);
public static extern float BASS_WASAPI_GetVolume(BASSWASAPIVolume curve);
public static extern bool BASS_WASAPI_SetMute(BASSWASAPIVolume mode, [MarshalAs(UnmanagedType.Bool)] bool mute);
public static extern bool BASS_WASAPI_SetVolume(BASSWASAPIVolume curve, float volume);