Example #1
0
        /// <summary>
        /// Initializes a device for playback.
        /// </summary>
        /// <param name="device">Device to use for playback</param>
        /// <param name="frequency">Mixer sample rate/frequency</param>
        private void InitializeDevice(Device device, int frequency)
        {
            // Set properties
            this.device = device;

            // Check driver type
            if (device.DriverType == DriverType.DirectSound)
            {
                // Initialize sound system
                Base.Init(device.Id, frequency, BASSInit.BASS_DEVICE_DEFAULT);
            }
#if !IOS && !ANDROID
            else if (device.DriverType == DriverType.ASIO)
            {
                // Initialize sound system
                BaseASIO.Init(device.Id, frequency, BASSInit.BASS_DEVICE_DEFAULT, BASSASIOInit.BASS_ASIO_THREAD);              
            }
            else if (device.DriverType == DriverType.WASAPI)
            {
                // Create callback
                wasapiProc = new WASAPIPROC(WASAPICallback);

                // Initialize sound system
                BaseWASAPI.Init(device.Id, frequency, 2, BASSInit.BASS_DEVICE_DEFAULT, BASSWASAPIInit.BASS_WASAPI_SHARED, 0, 0, wasapiProc);
            }
#endif
        }
Example #2
0
        /// <summary>
        /// Detects the standard/DirectSound output devices present in the system.
        /// </summary>
        /// <returns>List of standard/DirectSound output devices</returns>
        public static IEnumerable<Device> DetectOutputDevices()
        {
            var devices = new List<Device>();
            var devicesDirectSound = Bass.BASS_GetDeviceInfos().ToList();
            for(int a = 0; a < devicesDirectSound.Count; a++)
            {
                // Make sure the device is usable
                if (devicesDirectSound[a].IsEnabled)
                {
                    Device device = new Device();
                    device.IsDefault = devicesDirectSound[a].IsDefault;
                    device.Id = a;
                    device.DriverType = DriverType.DirectSound;
                    device.Name = devicesDirectSound[a].name;
                    device.Driver = devicesDirectSound[a].driver;

                    // If the driver name is No Sound, don't add it to the list of devices
                    if (device.Name.ToUpper() != "NO SOUND")
                    {
                        devices.Add(device);
                    }                    
                }
            }

            return devices;
        }
Example #3
0
 public AudioAppConfig()
 {
     // Set defaults
     AudioDevice = new Device();
     SampleRate = 44100;
     Volume = 1;
     BufferSize = 1000;
     UpdatePeriod = 100;
 }        
Example #4
0
        /// <summary>
        /// Detects the ASIO output devices present in the system.
        /// </summary>
        /// <returns>List of ASIO output devices</returns>
        public static IEnumerable<Device> DetectASIOOutputDevices()
        {
            var devices = new List<Device>();

#if !IOS && !ANDROID

            var devicesASIO = BassAsio.BASS_ASIO_GetDeviceInfos().ToList();
            for (int a = 0; a < devicesASIO.Count; a++)
            {
                Device device = new Device();
                device.IsDefault = false;
                device.Id = a;
                device.DriverType = DriverType.ASIO;
                device.Name = devicesASIO[a].name;
                device.Driver = devicesASIO[a].driver;
                devices.Add(device);
            }
#endif

            return devices;
        }
Example #5
0
        /// <summary>
        /// Frees the device currently used for playback.
        /// </summary>
        public void FreeDevice()
        {
            if (!_isDeviceInitialized)
                return;

#if !IOS && !ANDROID

            // Check driver type
            if (_device.DriverType == DriverType.ASIO)
            {
                // Free ASIO device
                if (!BassAsio.BASS_ASIO_Free())
                {
                    // Get error
                    BASSError error = Bass.BASS_ErrorGetCode();
                    throw new Exception("Error freeing ASIO device: " + error.ToString());
                }
            }
            else if (_device.DriverType == DriverType.WASAPI)
            {
                // Free WASAPI device
                if (!BassWasapi.BASS_WASAPI_Free())
                {
                    // Get error
                    BASSError error = Bass.BASS_ErrorGetCode();
                    throw new Exception("Error freeing WASAPI device: " + error.ToString());
                }
            }
#endif

            Base.Free();
            _mixerChannel = null;
            _device = null;
            _isDeviceInitialized = false;
        }
Example #6
0
        /// <summary>
        /// Initializes a specific audio device for playback.
        /// </summary>
        /// <param name="device">Audio device</param>
        /// <param name="mixerSampleRate">Mixer sample rate (in Hz)</param>
        public void InitializeDevice(Device device, int mixerSampleRate)
        {
            _device = device;
            _mixerSampleRate = mixerSampleRate;

            Tracing.Log("Player -- Initializing device (SampleRate: " + mixerSampleRate.ToString() + " Hz, DriverType: " + device.DriverType.ToString() + ", Id: " + device.Id.ToString() + ", Name: " + device.Name + ", BufferSize: " + _bufferSize.ToString() + ", UpdatePeriod: " + _updatePeriod.ToString() + ")");

            // Check driver type
            if (device.DriverType == DriverType.DirectSound)
            {
                // Initialize sound system                
                Base.Init(device.Id, mixerSampleRate, BASSInit.BASS_DEVICE_DEFAULT | BASSInit.BASS_DEVICE_LATENCY);
            }
#if !IOS && !ANDROID
            else if (device.DriverType == DriverType.ASIO)
            {
                // Initialize sound system
                BaseASIO.Init(device.Id, mixerSampleRate, BASSInit.BASS_DEVICE_DEFAULT, BASSASIOInit.BASS_ASIO_THREAD);
            }
            else if (device.DriverType == DriverType.WASAPI)
            {
                // Create callback
                wasapiProc = new WASAPIPROC(WASAPICallback);

                // Initialize sound system                
                //Base.InitWASAPI(device.Id, mixerSampleRate, 2, BASSInit.BASS_DEVICE_DEFAULT, BASSWASAPIInit.BASS_WASAPI_SHARED, 10.0f, 0, wasapiProc);
                BaseWASAPI.Init(device.Id, mixerSampleRate, 2, BASSInit.BASS_DEVICE_DEFAULT, BASSWASAPIInit.BASS_WASAPI_SHARED, 0.5f, 0, wasapiProc);
                //Base.InitWASAPI(device.Id, mixerSampleRate, 2, BASSInit.BASS_DEVICE_DEFAULT, BASSWASAPIInit.BASS_WASAPI_EXCLUSIVE, 1, 0, wasapiProc);

                //BASS_WASAPI_INFO info = BassWasapi.BASS_WASAPI_GetInfo();
            }
#endif

            // Default BASS.NET configuration values for Windows *AND* Linux:
            //
            // BASS_CONFIG_BUFFER: 500
            // BASS_CONFIG_UPDATEPERIOD: 100
            // BASS_CONFIG_UPDATETHREADS: 1
			
			if(OS.Type == OSType.Windows)
			{
	            // Set configuration for buffer and update period
            	// This only works for the default BASS output (http://www.un4seen.com/forum/?topic=13429.msg93740#msg93740)
            	Base.SetConfig(BASSConfig.BASS_CONFIG_BUFFER, _bufferSize); 
            	Base.SetConfig(BASSConfig.BASS_CONFIG_UPDATEPERIOD, _updatePeriod);	
			}
            else if (OS.Type == OSType.Linux)
            {				
				// 10ms update period does not work under Linux. Major stuttering
                Base.SetConfig(BASSConfig.BASS_CONFIG_BUFFER, _bufferSize);
                Base.SetConfig(BASSConfig.BASS_CONFIG_UPDATEPERIOD, 100);

#if ANDROID
                Base.SetConfig(BASSConfig.BASS_CONFIG_DEV_BUFFER, 500); // Default on Android: 30ms
#endif                
            }
            else if (OS.Type == OSType.MacOSX)
            {
                Base.SetConfig(BASSConfig.BASS_CONFIG_BUFFER, _bufferSize);
                Base.SetConfig(BASSConfig.BASS_CONFIG_UPDATEPERIOD, _updatePeriod);					
            }		

            _isDeviceInitialized = true;
        }
Example #7
0
        /// <summary>
        /// Initializes the player.
        /// </summary>        
        /// <param name="device">Device output</param>
        /// <param name="mixerSampleRate">Mixer sample rate (default: 44100 Hz)</param>
        /// <param name="bufferSize">Buffer size (default: 500 ms)</param>
        /// <param name="updatePeriod">Update period (default: 10 ms)</param>
        /// <param name="initializeDevice">Indicates if the device should be initialized</param>
        private void Initialize(Device device, int mixerSampleRate, int bufferSize, int updatePeriod, bool initializeDevice)
        {
            OnPlaylistEnded += () => { };

            Player.CurrentPlayer = this;            
            _device = device;
            _mixerSampleRate = mixerSampleRate;
            _bufferSize = bufferSize;
            _updatePeriod = updatePeriod;
            //_decodingService = new DecodingService(100000, UseFloatingPoint);
            _playlist = new ShufflePlaylist();
            _syncProcs = new List<PlayerSyncProc>();

#if !ANDROID
            _useFloatingPoint = true;
#endif

            _timerPlayer = new System.Timers.Timer();
            _timerPlayer.Elapsed += new System.Timers.ElapsedEventHandler(timerPlayer_Elapsed);
            _timerPlayer.Interval = 1000;
            _timerPlayer.Enabled = false;

            // Initialize BASS library by OS type
            if (OS.Type == OSType.Windows)
            {
                // Load decoding plugins
                //plugins = Base.LoadPluginDirectory(Path.GetDirectoryName((new Uri(Assembly.GetExecutingAssembly().CodeBase)).AbsolutePath));
                Tracing.Log("Player init -- Loading plugins...");
                //aacPluginHandle = Base.LoadPlugin("bass_aac.dll");
                _apePluginHandle = Base.LoadPlugin("bass_ape.dll");
                _flacPluginHandle = Base.LoadPlugin("bassflac.dll");
                _mpcPluginHandle = Base.LoadPlugin("bass_mpc.dll");
                //ofrPluginHandle = Base.LoadPlugin("bass_ofr.dll"); // Requires OptimFrog.DLL
                //ttaPluginHandle = Base.LoadPlugin("bass_tta.dll");
                _wmaPluginHandle = Base.LoadPlugin("basswma.dll");
                _wvPluginHandle = Base.LoadPlugin("basswv.dll");

                int bassFxVersion = Base.GetFxPluginVersion();
                int bassEncVersion = BaseEnc.GetVersion();
            	//Base.LoadFxPlugin();
            }
			else // Linux or Mac OS X
			{				
				// Load BASS library
				Tracing.Log("Player init -- Checking BASS library and plugin versions...");
				int bassVersion = Base.GetBASSVersion();				
				int bassFxVersion = Base.GetFxPluginVersion();
				int bassMixVersion = Base.GetMixPluginVersion();
                int bassEncVersion = BaseEnc.GetVersion();
				Tracing.Log("Player init -- BASS Version: " + bassVersion);
				Tracing.Log("Player init -- BASS FX Version: " + bassFxVersion);
				Tracing.Log("Player init -- BASS Mix Version: " + bassMixVersion);
                Tracing.Log("Player init -- BASS Enc Version: " + bassEncVersion);

				// Check OS type
                Console.WriteLine("Player init -- OS is " + OS.Type.ToString());
	            if (OS.Type == OSType.Linux)
	            {
                    string pluginPath = string.Empty;

#if ANDROID
                    pluginPath = PluginDirectoryPath;
                    _aacPluginHandle = Base.LoadPlugin(Path.Combine(pluginPath, "libbass_aac.so"));
                    _alacPluginHandle = Base.LoadPlugin(Path.Combine(pluginPath, "libbass_alac.so"));
                    _apePluginHandle = Base.LoadPlugin(Path.Combine(pluginPath, "libbass_ape.so"));
                    _mpcPluginHandle = Base.LoadPlugin(Path.Combine(pluginPath, "libbass_mpc.so"));
                    _flacPluginHandle = Base.LoadPlugin(Path.Combine(pluginPath, "libbassflac.so"));
                    _wvPluginHandle = Base.LoadPlugin(Path.Combine(pluginPath, "libbasswv.so"));
#else

                    // Find plugins either in current directory (i.e. development) or in a system directory (ex: /usr/lib/Sessions or /opt/lib/Sessions)
                    string exePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);               
                    
                    // Check in the current directory first
                    if(!File.Exists(exePath + "/libbassflac.so"))
                    {
                        // Check in /usr/lib/Sessions
                        if(!File.Exists("/usr/lib/Sessions/libbassflac.so"))
                        {
                            // Check in /opt/lib/Sessions
                            if(!File.Exists("/opt/lib/Sessions/libbassflac.so"))
                            {
                                // The plugins could not be found!
                                throw new Exception("The BASS plugins could not be found either in the current directory, in /usr/lib/Sessions or in /opt/lib/Sessions!");
                            }
                            else
                            {
                                pluginPath = "/opt/lib/Sessions";
                            }                       
                        }
                        else
                        {
                            pluginPath = "/usr/lib/Sessions";
                        }
                    }
                    else
                    {                   
                        pluginPath = exePath;
                    }

                    // Load decoding plugins
                    _flacPluginHandle = Base.LoadPlugin(Path.Combine(pluginPath, "libbassflac.so"));
                    _wvPluginHandle = Base.LoadPlugin(Path.Combine(pluginPath, "libbasswv.so"));
                    _mpcPluginHandle = Base.LoadPlugin(Path.Combine(pluginPath, "libbass_mpc.so"));
#endif					
	            }
	            else if (OS.Type == OSType.MacOSX)
	            {
#if IOS
                    // Load decoding plugins (http://www.un4seen.com/forum/?topic=13851.msg96559#msg96559)
                    _flacPluginHandle = Base.LoadPlugin("BASSFLAC");
                    _wvPluginHandle = Base.LoadPlugin("BASSWV");
                    _apePluginHandle = Base.LoadPlugin("BASS_APE");
                    _mpcPluginHandle = Base.LoadPlugin("BASS_MPC");

					int bassEncVersionOSX = BaseEnc.GetVersion();

					Console.WriteLine("Player init -- Configuring IOSNOTIFY delegate...");
                    _iosNotifyProc = new IOSNOTIFYPROC(IOSNotifyProc);
                    IntPtr ptr = Marshal.GetFunctionPointerForDelegate(_iosNotifyProc);
                    Bass.BASS_SetConfigPtr((BASSConfig)46, ptr);
                    //Bass.BASS_SetConfigPtr(BASSIOSConfig.BASS_CONFIG_IOS_NOTIFY, ptr);

					Console.WriteLine("Player init -- Configuring AirPlay and remote control...");
                    Bass.BASS_SetConfig(BASSConfig.BASS_CONFIG_IOS_MIXAUDIO, 0); // 0 = AirPlay
#else

                    // Try to get the plugins in the current path
                    Console.WriteLine("Loading OS X plugins...");
                    string exePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
                    string pluginPath = exePath.Replace("MonoBundle", "Resources");

                    // Check in the current directory first
                    if(!File.Exists(pluginPath + "/libbassflac.dylib"))
                    {
                        // The plugins could not be found!
                        throw new Exception("The BASS plugins could not be found in the current directory!");
                    }

                    // Load decoding plugins
					_flacPluginHandle = Base.LoadPlugin(pluginPath + "/libbassflac.dylib");
                    _wvPluginHandle = Base.LoadPlugin(pluginPath + "/libbasswv.dylib");
                    _mpcPluginHandle = Base.LoadPlugin(pluginPath + "/libbass_mpc.dylib");
                    _apePluginHandle = Base.LoadPlugin(pluginPath + "/libbass_ape.dylib");
                    _ttaPluginHandle = Base.LoadPlugin(pluginPath + "/libbass_tta.dylib");

                    int bassEncVersion2 = BaseEnc.GetVersion();
                    //Console.WriteLine("OSX Bassenc.dylib version: {0}", bassEncVersion);
#endif
	            }
			}

#if IOS
            _bpmProc = new BPMPROC(BPMDetectionProcIOS);
            //bpmBeatProc = new BPMBEATPROC(BPMDetectionBeatProcIOS);
#else
            _bpmProc = new BPMPROC(BPMDetectionProc);
            //bpmBeatProc = new BPMBEATPROC(BPMDetectionBeatProc);
#endif
					
            // Create default EQ
            Tracing.Log("Player init -- Creating default EQ preset...");
            _currentEQPreset = new EQPreset();

            if (initializeDevice)
            {
                Tracing.Log("Player init -- Initializing device...");
                InitializeDevice(device, mixerSampleRate);
            }
        }
Example #8
0
 /// <summary>
 /// Constructor for the Player class which requires the mixer sample rate value to be passed
 /// in parameter.
 /// </summary>
 /// <param name="device">Device output</param>
 /// <param name="mixerSampleRate">Mixer sample rate (default: 44100 Hz)</param>
 /// <param name="bufferSize">Buffer size (default: 500 ms)</param>
 /// <param name="updatePeriod">Update period (default: 10 ms)</param>
 /// <param name="initializeDevice">Indicates if the device should be initialized</param>
 public Player(Device device, int mixerSampleRate, int bufferSize, int updatePeriod, bool initializeDevice)
 {
     Initialize(device, mixerSampleRate, bufferSize, updatePeriod, initializeDevice);
 }
Example #9
0
 /// <summary>
 /// Constructor for the TestDevice class which requires a Device class.
 /// </summary>
 /// <param name="device">Device to use for playback</param>
 /// <param name="frequency">Mixer sample rate/frequency</param>
 public TestDevice(Device device, int frequency)
 {
     // Initialize the audio device
     InitializeDevice(device, frequency);
 }
Example #10
0
        /// <summary>
        /// Detects the WASAPI output devices present in the system. For Windows only.
        /// </summary>
        /// <returns>List of WASAPI output devices</returns>
        public static IEnumerable<Device> DetectWASAPIOutputDevices()
        {
            var devices = new List<Device>();

#if !IOS && !ANDROID

            var devicesWASAPI = BassWasapi.BASS_WASAPI_GetDeviceInfos().ToList();
            for (int a = 0; a < devicesWASAPI.Count; a++)
            {
                // Make sure the device is usable, and an output device
                if (devicesWASAPI[a].IsEnabled && !devicesWASAPI[a].IsInput)
                {
                    Device device = new Device();
                    device.IsDefault = devicesWASAPI[a].IsDefault;
                    device.Id = a;
                    device.DriverType = DriverType.WASAPI;
                    device.Name = devicesWASAPI[a].name;
                    device.Driver = devicesWASAPI[a].id;
                    devices.Add(device);
                }
            }
#endif

            return devices;
        }
Example #11
0
        /// <summary>
        /// Returns the default WASAPI device.
        /// If no device was no found, the value is null.
        /// </summary>
        /// <returns>Default WASAPI device</returns>
        public static Device GetDefaultWASAPIOutputDevice()
        {
            // Detect WASAPI devices
            List<BASS_WASAPI_DEVICEINFO> devicesWASAPI = BassWasapi.BASS_WASAPI_GetDeviceInfos().ToList();
            for (int a = 0; a < devicesWASAPI.Count; a++)
            {
                // Check if the device is the default one
                if (devicesWASAPI[a].IsEnabled && devicesWASAPI[a].IsDefault && !devicesWASAPI[a].IsInput)
                {
                    // Create device and add to list
                    Device device = new Device();
                    device.IsDefault = devicesWASAPI[a].IsDefault;
                    device.Id = a;
                    device.DriverType = DriverType.WASAPI;
                    device.Name = devicesWASAPI[a].name;
                    device.Driver = devicesWASAPI[a].id;
                    return device;
                }
            }

            return null;
        }
Example #12
0
        /// <summary>
        /// Returns the default DirectSound device.
        /// If no device was no found, the value is null.
        /// </summary>
        /// <returns>Default DirectSound device</returns>
        public static Device GetDefaultDirectSoundOutputDevice()
        {
            // Detect DirectSound devices
            List<BASS_DEVICEINFO> devicesDirectSound = Bass.BASS_GetDeviceInfos().ToList();
            for (int a = 0; a < devicesDirectSound.Count; a++)
            {
                // Check if the device is the default one
                if (devicesDirectSound[a].IsEnabled && devicesDirectSound[a].IsDefault)
                {
                    // Create device and add to list
                    Device device = new Device();
                    device.IsDefault = devicesDirectSound[a].IsDefault;
                    device.Id = a;
                    device.DriverType = DriverType.DirectSound;
                    device.Name = devicesDirectSound[a].name;
                    device.Driver = devicesDirectSound[a].driver;
                    return device;
                }
            }

            return null;
        }
Example #13
0
        /// <summary>
        /// Find an output device by its driver type and its device name.
        /// This is useful to get the actual deviceId because it can change if the
        /// user plugs/unplugs a sound card.
        /// </summary>
        /// <param name="driverType">Driver type</param>
        /// <param name="deviceName">Device name</param>
        /// <returns>Device (null if none found)</returns>
        public static Device FindOutputDevice(DriverType driverType, string deviceName)
        {
            // Check driver type
            if (driverType == DriverType.DirectSound)
            {
                // Detect DirectSound devices
                List<BASS_DEVICEINFO> devicesDirectSound = Bass.BASS_GetDeviceInfos().ToList();
                for (int a = 0; a < devicesDirectSound.Count; a++)
                {
                    // Check if the driver name is the same, and make sure the device is also enabled (i.e. available)
                    if (devicesDirectSound[a].name.ToUpper() == deviceName.ToUpper() &&
                        devicesDirectSound[a].IsEnabled)
                    {                        
                        // Create device and add to list
                        Device device = new Device();
                        device.IsDefault = devicesDirectSound[a].IsDefault;
                        device.Id = a;
                        device.DriverType = DriverType.DirectSound;
                        device.Name = devicesDirectSound[a].name;
                        device.Driver = devicesDirectSound[a].driver;
                        return device;
                    }
                }
            }
#if !IOS && !ANDROID
            else if (driverType == DriverType.ASIO)
            {
                // Detect ASIO devices
                List<BASS_ASIO_DEVICEINFO> devicesASIO = BassAsio.BASS_ASIO_GetDeviceInfos().ToList();
                for (int a = 0; a < devicesASIO.Count; a++)
                {
                    // Check if the driver name is the same
                    if (devicesASIO[a].name.ToUpper() == deviceName.ToUpper())
                    {
                        // Create device and add to list
                        Device device = new Device();
                        device.IsDefault = false;
                        device.Id = a;
                        device.DriverType = DriverType.ASIO;
                        device.Name = devicesASIO[a].name;
                        device.Driver = devicesASIO[a].driver;
                        return device;
                    }
                }
            } 
            else if (driverType == DriverType.WASAPI)
            {
                // Detect WASAPI devices
                List<BASS_WASAPI_DEVICEINFO> devicesWASAPI = BassWasapi.BASS_WASAPI_GetDeviceInfos().ToList();
                for (int a = 0; a < devicesWASAPI.Count; a++)
                {
                    // Check if the driver name is the same, that the device is an output device, and make sure that it is enabled
                    if (devicesWASAPI[a].name.ToUpper() == deviceName.ToUpper() &&
                        devicesWASAPI[a].IsEnabled && !devicesWASAPI[a].IsInput)
                    {
                        // Create device and add to list
                        Device device = new Device();
                        device.IsDefault = devicesWASAPI[a].IsDefault;
                        device.Id = a;
                        device.DriverType = DriverType.WASAPI;
                        device.Name = devicesWASAPI[a].name;
                        device.Driver = devicesWASAPI[a].id;
                        return device;
                    }
                }
            }
#endif

            return null;
        }