示例#1
0
        /// \internal
        /// <summary>Creates the audio context using the specified device.</summary>
        /// <param name="device">The device descriptor obtained through AudioContext.AvailableDevices, or null for the default device.</param>
        /// <param name="freq">Frequency for mixing output buffer, in units of Hz. Pass 0 for driver default.</param>
        /// <param name="refresh">Refresh intervals, in units of Hz. Pass 0 for driver default.</param>
        /// <param name="sync">Flag, indicating a synchronous context.</param>
        /// <param name="enableEfx">Indicates whether the EFX extension should be initialized, if present.</param>
        /// <param name="efxAuxiliarySends">Requires EFX enabled. The number of desired Auxiliary Sends per source.</param>
        /// <exception cref="ArgumentOutOfRangeException">Occurs when a specified parameter is invalid.</exception>
        /// <exception cref="AudioDeviceException">
        /// Occurs when the specified device is not available, or is in use by another program.
        /// </exception>
        /// <exception cref="AudioContextException">
        /// Occurs when an audio context could not be created with the specified parameters.
        /// </exception>
        /// <exception cref="NotSupportedException">
        /// Occurs when an AudioContext already exists.</exception>
        /// <remarks>
        /// <para>For maximum compatibility, you are strongly recommended to use the default constructor.</para>
        /// <para>Multiple AudioContexts are not supported at this point.</para>
        /// <para>
        /// The number of auxilliary EFX sends depends on the audio hardware and drivers. Most Realtek devices, as well
        /// as the Creative SB Live!, support 1 auxilliary send. Creative's Audigy and X-Fi series support 4 sends.
        /// Values higher than supported will be clamped by the driver.
        /// </para>
        /// </remarks>
        void CreateContext(string device, int freq, int refresh, bool sync, bool enableEfx, MaxAuxiliarySends efxAuxiliarySends)
        {
            if (!AudioDeviceEnumerator.IsOpenALSupported)
            {
                throw new DllNotFoundException("openal32.dll");
            }

            if (AudioDeviceEnumerator.Version == AudioDeviceEnumerator.AlcVersion.Alc1_1 && AudioDeviceEnumerator.AvailablePlaybackDevices.Count == 0)    // Alc 1.0 does not support device enumeration.
            {
                throw new NotSupportedException("No audio hardware is available.");
            }
            if (context_exists)
            {
                throw new NotSupportedException("Multiple AudioContexts are not supported.");
            }
            if (freq < 0)
            {
                throw new ArgumentOutOfRangeException("freq", freq, "Should be greater than zero.");
            }
            if (refresh < 0)
            {
                throw new ArgumentOutOfRangeException("refresh", refresh, "Should be greater than zero.");
            }


            if (!String.IsNullOrEmpty(device))
            {
                device_name   = device;
                device_handle = Alc.OpenDevice(device); // try to open device by name
            }
            if (device_handle == IntPtr.Zero)
            {
                device_name   = "IntPtr.Zero (null string)";
                device_handle = Alc.OpenDevice(null); // try to open unnamed default device
            }
            if (device_handle == IntPtr.Zero)
            {
                device_name   = AudioContext.DefaultDevice;
                device_handle = Alc.OpenDevice(AudioContext.DefaultDevice); // try to open named default device
            }
            if (device_handle == IntPtr.Zero)
            {
                device_name = "None";
                throw new AudioDeviceException(String.Format("Audio device '{0}' does not exist or is tied up by another application.",
                                                             String.IsNullOrEmpty(device) ? "default" : device));
            }

            CheckErrors();

            // Build the attribute list
            List <int> attributes = new List <int>();

            if (freq != 0)
            {
                attributes.Add((int)AlcContextAttributes.Frequency);
                attributes.Add(freq);
            }

            if (refresh != 0)
            {
                attributes.Add((int)AlcContextAttributes.Refresh);
                attributes.Add(refresh);
            }

            attributes.Add((int)AlcContextAttributes.Sync);
            attributes.Add(sync ? 1 : 0);

            if (enableEfx && Alc.IsExtensionPresent(device_handle, "ALC_EXT_EFX"))
            {
                int num_slots;
                switch (efxAuxiliarySends)
                {
                case MaxAuxiliarySends.One:
                case MaxAuxiliarySends.Two:
                case MaxAuxiliarySends.Three:
                case MaxAuxiliarySends.Four:
                    num_slots = (int)efxAuxiliarySends;
                    break;

                default:
                case MaxAuxiliarySends.UseDriverDefault:
                    Alc.GetInteger(device_handle, AlcGetInteger.EfxMaxAuxiliarySends, 1, out num_slots);
                    break;
                }

                attributes.Add((int)AlcContextAttributes.EfxMaxAuxiliarySends);
                attributes.Add(num_slots);
            }
            attributes.Add(0);

            context_handle = Alc.CreateContext(device_handle, attributes.ToArray());

            if (context_handle == ContextHandle.Zero)
            {
                Alc.CloseDevice(device_handle);
                throw new AudioContextException("The audio context could not be created with the specified parameters.");
            }

            CheckErrors();

            // HACK: OpenAL SI on Linux/ALSA crashes on MakeCurrent. This hack avoids calling MakeCurrent when
            // an old OpenAL version is detect - it may affect outdated OpenAL versions different than OpenAL SI,
            // but it looks like a good compromise for now.
            if (AudioDeviceEnumerator.AvailablePlaybackDevices.Count > 0)
            {
                MakeCurrent();
            }

            CheckErrors();

            device_name = Alc.GetString(device_handle, AlcGetString.DeviceSpecifier);


            lock (audio_context_lock)
            {
                available_contexts.Add(this.context_handle, this);
                context_exists = true;
            }
        }
示例#2
0
        /// \internal
        /// <summary>Creates the audio context using the specified device.</summary>
        /// <param name="device">The device descriptor obtained through AudioContext.AvailableDevices, or null for the default device.</param>
        /// <param name="freq">Frequency for mixing output buffer, in units of Hz. Pass 0 for driver default.</param>
        /// <param name="refresh">Refresh intervals, in units of Hz. Pass 0 for driver default.</param>
        /// <param name="sync">Flag, indicating a synchronous context.</param>
        /// <param name="enableEfx">Indicates whether the EFX extension should be initialized, if present.</param>
        /// <param name="efxAuxiliarySends">Requires EFX enabled. The number of desired Auxiliary Sends per source.</param>
        /// <exception cref="ArgumentOutOfRangeException">Occurs when a specified parameter is invalid.</exception>
        /// <exception cref="AudioDeviceException">
        /// Occurs when the specified device is not available, or is in use by another program.
        /// </exception>
        /// <exception cref="AudioContextException">
        /// Occurs when an audio context could not be created with the specified parameters.
        /// </exception>
        /// <exception cref="NotSupportedException">
        /// Occurs when an AudioContext already exists.</exception>
        /// <remarks>
        /// <para>For maximum compatibility, you are strongly recommended to use the default constructor.</para>
        /// <para>Multiple AudioContexts are not supported at this point.</para>
        /// <para>
        /// The number of auxilliary EFX sends depends on the audio hardware and drivers. Most Realtek devices, as well
        /// as the Creative SB Live!, support 1 auxilliary send. Creative's Audigy and X-Fi series support 4 sends.
        /// Values higher than supported will be clamped by the driver.
        /// </para>
        /// </remarks>
        void CreateContext(string device, int freq, int refresh, bool sync, bool enableEfx, MaxAuxiliarySends efxAuxiliarySends)
        {
            if (!AudioDeviceEnumerator.IsOpenALSupported)
                throw new DllNotFoundException("soft_oal.dll");

            if (AudioDeviceEnumerator.Version == AudioDeviceEnumerator.AlcVersion.Alc1_1 && AudioDeviceEnumerator.AvailablePlaybackDevices.Count == 0)    // Alc 1.0 does not support device enumeration.
                throw new NotSupportedException("No audio hardware is available.");
            if (context_exists) throw new NotSupportedException("Multiple AudioContexts are not supported.");
            if (freq < 0) throw new ArgumentOutOfRangeException("freq", freq, "Should be greater than zero.");
            if (refresh < 0) throw new ArgumentOutOfRangeException("refresh", refresh, "Should be greater than zero.");


            if (!String.IsNullOrEmpty(device))
            {
                device_name = device;
                device_handle = Alc.OpenDevice(device); // try to open device by name
            }
            if (device_handle == IntPtr.Zero)
            {
                device_name = "IntPtr.Zero (null string)";
                device_handle = Alc.OpenDevice(null); // try to open unnamed default device
            }
            if (device_handle == IntPtr.Zero)
            {
                device_name = AudioContext.DefaultDevice;
                device_handle = Alc.OpenDevice(AudioContext.DefaultDevice); // try to open named default device
            }
            if (device_handle == IntPtr.Zero)
            {
                device_name = "None";
                throw new AudioDeviceException(String.Format("Audio device '{0}' does not exist or is tied up by another application.",
                    String.IsNullOrEmpty(device) ? "default" : device));
            }

            CheckErrors();

            // Build the attribute list
            List<int> attributes = new List<int>();

            if (freq != 0)
            {
                attributes.Add((int)AlcContextAttributes.Frequency);
                attributes.Add(freq);
            }

            if (refresh != 0)
            {
                attributes.Add((int)AlcContextAttributes.Refresh);
                attributes.Add(refresh);
            }

            attributes.Add((int)AlcContextAttributes.Sync);
            attributes.Add(sync ? 1 : 0);

            if (enableEfx && Alc.IsExtensionPresent(device_handle, "ALC_EXT_EFX"))
            {
                int num_slots;
                switch (efxAuxiliarySends)
                {
                    case MaxAuxiliarySends.One:
                    case MaxAuxiliarySends.Two:
                    case MaxAuxiliarySends.Three:
                    case MaxAuxiliarySends.Four:
                        num_slots = (int)efxAuxiliarySends;
                        break;
                    default:
                    case MaxAuxiliarySends.UseDriverDefault:
                        Alc.GetInteger(device_handle, AlcGetInteger.EfxMaxAuxiliarySends, 1, out num_slots);
                        break;
                }
              
                attributes.Add((int)AlcContextAttributes.EfxMaxAuxiliarySends);
                attributes.Add(num_slots);
            }
            attributes.Add(0);

            context_handle = Alc.CreateContext(device_handle, attributes.ToArray());

            if (context_handle == ContextHandle.Zero)
            {
                Alc.CloseDevice(device_handle);
                throw new AudioContextException("The audio context could not be created with the specified parameters.");
            }

            CheckErrors();

            // HACK: OpenAL SI on Linux/ALSA crashes on MakeCurrent. This hack avoids calling MakeCurrent when
            // an old OpenAL version is detect - it may affect outdated OpenAL versions different than OpenAL SI,
            // but it looks like a good compromise for now.
            if (AudioDeviceEnumerator.AvailablePlaybackDevices.Count > 0)
                MakeCurrent();

            CheckErrors();

            device_name = Alc.GetString(device_handle, AlcGetString.DeviceSpecifier);
 

            lock (audio_context_lock)
            {
                available_contexts.Add(this.context_handle, this);
                context_exists = true;
            }
        }
示例#3
0
 /// <summary>Creates the audio context using the specified device and device parameters.</summary>
 /// <param name="device">The device descriptor obtained through AudioContext.AvailableDevices.</param>
 /// <param name="freq">Frequency for mixing output buffer, in units of Hz. Pass 0 for driver default.</param>
 /// <param name="refresh">Refresh intervals, in units of Hz. Pass 0 for driver default.</param>
 /// <param name="sync">Flag, indicating a synchronous context.</param>
 /// <param name="enableEfx">Indicates whether the EFX extension should be initialized, if present.</param>
 /// <param name="efxMaxAuxSends">Requires EFX enabled. The number of desired Auxiliary Sends per source.</param>
 /// <exception cref="ArgumentNullException">Occurs when the device string is invalid.</exception>
 /// <exception cref="ArgumentOutOfRangeException">Occurs when a specified parameter is invalid.</exception>
 /// <exception cref="AudioDeviceException">
 /// Occurs when the specified device is not available, or is in use by another program.
 /// </exception>
 /// <exception cref="AudioContextException">
 /// Occurs when an audio context could not be created with the specified parameters.
 /// </exception>
 /// <exception cref="NotSupportedException">
 /// Occurs when an AudioContext already exists.</exception>
 /// <remarks>
 /// <para>For maximum compatibility, you are strongly recommended to use the default constructor.</para>
 /// <para>Multiple AudioContexts are not supported at this point.</para>
 /// <para>
 /// The number of auxilliary EFX sends depends on the audio hardware and drivers. Most Realtek devices, as well
 /// as the Creative SB Live!, support 1 auxilliary send. Creative's Audigy and X-Fi series support 4 sends.
 /// Values higher than supported will be clamped by the driver.
 /// </para>
 /// </remarks>
 public AudioContext(string device, int freq, int refresh, bool sync, bool enableEfx, MaxAuxiliarySends efxMaxAuxSends)
 {
     CreateContext(device, freq, refresh, sync, enableEfx, efxMaxAuxSends);
 }
示例#4
0
 /// <summary>Creates the audio context using the specified device and device parameters.</summary>
 /// <param name="device">The device descriptor obtained through AudioContext.AvailableDevices.</param>
 /// <param name="freq">Frequency for mixing output buffer, in units of Hz. Pass 0 for driver default.</param>
 /// <param name="refresh">Refresh intervals, in units of Hz. Pass 0 for driver default.</param>
 /// <param name="sync">Flag, indicating a synchronous context.</param>
 /// <param name="enableEfx">Indicates whether the EFX extension should be initialized, if present.</param>
 /// <param name="efxMaxAuxSends">Requires EFX enabled. The number of desired Auxiliary Sends per source.</param>
 /// <exception cref="ArgumentNullException">Occurs when the device string is invalid.</exception>
 /// <exception cref="ArgumentOutOfRangeException">Occurs when a specified parameter is invalid.</exception>
 /// <exception cref="AudioDeviceException">
 /// Occurs when the specified device is not available, or is in use by another program.
 /// </exception>
 /// <exception cref="AudioContextException">
 /// Occurs when an audio context could not be created with the specified parameters.
 /// </exception>
 /// <exception cref="NotSupportedException">
 /// Occurs when an AudioContext already exists.</exception>
 /// <remarks>
 /// <para>For maximum compatibility, you are strongly recommended to use the default constructor.</para>
 /// <para>Multiple AudioContexts are not supported at this point.</para>
 /// <para>
 /// The number of auxilliary EFX sends depends on the audio hardware and drivers. Most Realtek devices, as well
 /// as the Creative SB Live!, support 1 auxilliary send. Creative's Audigy and X-Fi series support 4 sends.
 /// Values higher than supported will be clamped by the driver.
 /// </para>
 /// </remarks>
 public AudioContext(string device, int freq, int refresh, bool sync, bool enableEfx, MaxAuxiliarySends efxMaxAuxSends)
 {
     CreateContext(device, freq, refresh, sync, enableEfx, efxMaxAuxSends);
 }