/// <summary> /// Initializes a new instance of the <see cref="AudioDeviceErrorChecker" /> struct. /// </summary> /// <param name="device">The device to monitor.</param> public AudioDeviceErrorChecker(IntPtr device) { if (device == IntPtr.Zero) { throw new AudioDeviceException(); } unsafe { _device = (Device *)device.ToPointer(); } }
/// <summary> /// Loads the API for the given extension, using the base API. /// </summary> /// <param name="device">The device of the context.</param> /// <param name="baseAPI">The base API instance.</param> /// <typeparam name="TContextExtension">The extension type.</typeparam> /// <returns>The extension.</returns> /// <exception cref="ExtensionNotSupportedException">Thrown if the API doesn't support the extension.</exception> internal static unsafe TContextExtension LoadContextExtension <TContextExtension> (Device *device, IContextExtensions baseAPI) where TContextExtension : ContextExtensionBase { var extensionMetadata = ExtensionLoader.GetAPIExtensionMetadata <TContextExtension>(); if (!baseAPI.IsExtensionPresent(device, extensionMetadata.ExtensionName)) { throw new ExtensionNotSupportedException(extensionMetadata.ExtensionName); } return(APILoader.Load <TContextExtension>(new OpenALLibraryNameContainer())); }
/// <summary> /// Initializes a new instance of the <see cref="AudioCapture{TBufferFormat}"/> class that opens a device for audio recording. /// </summary> /// <param name="captureAPI">The capture API instance to use.</param> /// <param name="deviceName">The device name.</param> /// <param name="frequency">The frequency that the data should be captured at.</param> /// <param name="sampleFormat">The requested capture buffer format.</param> /// <param name="bufferSize"> /// The size of OpenAL's capture internal ring-buffer. This value expects number of samples, not /// bytes. /// </param> public unsafe AudioCapture ( Capture captureAPI, string deviceName = null, uint frequency = 22050, TBufferFormat?sampleFormat = null, int bufferSize = 4096 ) { if (frequency <= 0) { throw new ArgumentOutOfRangeException(nameof(frequency)); } if (bufferSize <= 0) { throw new ArgumentOutOfRangeException(nameof(bufferSize)); } var actualSampleFormat = sampleFormat ?? (TBufferFormat)(object)BufferFormat.Mono16; _captureAPI = captureAPI; // Try to open specified device. If it fails, try to open default device. CurrentDevice = deviceName; _handle = _captureAPI.CaptureOpenDevice(deviceName, frequency, actualSampleFormat, bufferSize); if (_handle == null) { CurrentDevice = "IntPtr.Zero"; _handle = _captureAPI.CaptureOpenDevice(null, frequency, actualSampleFormat, bufferSize); } if (_handle == null) { // Everything we tried failed. Capture may not be supported, bail out. CurrentDevice = "None"; throw new AudioDeviceException ( "All attempts to open capture devices returned IntPtr.Zero. See debug log for verbose list." ); } // handle is not null, check for some Alc Error CheckErrors(); SampleFormat = actualSampleFormat; SampleFrequency = frequency; }
public AudioOutput(int channels = 1, int sampleRate = 44100) { if (channels < 1 || channels > 2) { throw new ArgumentOutOfRangeException(nameof(channels)); } if (sampleRate < 2000 || sampleRate > 200000) { throw new ArgumentOutOfRangeException(nameof(sampleRate)); } try { al = AL.GetApi(true); alContext = ALContext.GetApi(true); } catch { al = AL.GetApi(false); alContext = ALContext.GetApi(false); } device = alContext.OpenDevice(""); Available = device != null; if (Available) { context = alContext.CreateContext(device, null); alContext.MakeContextCurrent(context); if (al.GetError() != AudioError.NoError) { Available = false; if (context != null) { alContext.DestroyContext(context); } alContext.CloseDevice(device); al.Dispose(); alContext.Dispose(); disposed = true; return; } source = al.GenSource(); al.SetSourceProperty(source, SourceBoolean.Looping, true); al.SetSourceProperty(source, SourceFloat.Gain, 1.0f); } }
/// <summary> /// Completes a capture operation. This call does not block. /// </summary> /// <typeparam name="TManagedFormat">The managed format of the buffer.</typeparam> /// <typeparam name="TBufferFormat">The format of the native buffer.</typeparam> /// <param name="device">The device.</param> /// <param name="bufferFormat">The data format of the buffer.</param> /// <param name="sampleCount">The number of samples to retrieve.</param> /// <returns>The captured samples.</returns> public unsafe TManagedFormat[] CaptureSamples <TManagedFormat, TBufferFormat> ( Device *device, TBufferFormat bufferFormat, int sampleCount ) where TBufferFormat : struct, Enum where TManagedFormat : unmanaged { var formatSize = FormatHelpers.GetFormatSize(bufferFormat); var managedFormatSize = sizeof(TManagedFormat); var internalBufferSize = sampleCount * formatSize; var managedBufferElementCount = internalBufferSize / managedFormatSize; var resizeBuffer = new TManagedFormat[managedBufferElementCount]; CaptureSamples(device, bufferFormat, sampleCount, in resizeBuffer); return(resizeBuffer); }
protected override unsafe void OnStop() { // Cleanup: nuke our context if we have it. This is hacky and bad - we should really destroy // our buffers and sources. I have _no_ idea if OpenAL will leak memory. if (_context != null) { XPlane.Trace.WriteLine($"[OpenAL Sample] Deleting my context 0x{((ulong)_context):X8}"); _alc.DestroyContext(_context); _context = null; } if (_device != null) { _alc.CloseDevice(_device); _device = null; } _flightLoop.Dispose(); _flightLoop = null; Menu.PluginsMenu.Dispose(); }
/// <inheritdoc /> public abstract unsafe bool CaptureCloseDevice(Device *device);
/// <inheritdoc /> public unsafe partial void CaptureSamples(Device *device, void *buffer, int sampleCount);
public unsafe partial void GetContextProperty(Device *device, GetCaptureContextInteger param, int count, int *data);
/// <inheritdoc /> public unsafe partial bool IsExtensionPresent(Device *device, string name);
/// <inheritdoc /> public unsafe partial void CaptureStop(Device *device);
/// <inheritdoc /> public abstract unsafe int GetEnumValue(Device *device, [CallerFree] string name);
/// <inheritdoc /> public abstract unsafe string GetString(Device *device, GetEnumerationContextString param);
/// <inheritdoc /> public abstract unsafe char *GetStringList(Device *device, GetCaptureContextStringList param);
/// <inheritdoc /> public unsafe partial string GetString(Device *device, GetEnumerationContextString param);
public unsafe partial byte *GetStringList(Device *device, GetCaptureContextStringList param);
/// <inheritdoc /> public abstract unsafe void GetContextProperty(Device *device, GetCaptureContextInteger param, int count, void *data);
public unsafe partial string GetContextProperty(Device *device, GetContextString param);
/// <inheritdoc /> public unsafe partial int GetEnumValue(Device *device, string name);
/// <inheritdoc /> public unsafe partial void *GetProcAddress(Device *device, string name);
/// <inheritdoc /> public abstract unsafe void CaptureStop(Device *device);
/// <inheritdoc /> public unsafe partial Context *CreateContext(Device *device, int *attributeList);
/// <inheritdoc /> public abstract unsafe void CaptureSamples(Device *device, void *buffer, int sampleCount);
public abstract unsafe void GetContextProperty(Device *device, EFXContextInteger param, int size, int *data);
/// <summary> /// Completes a capture operation. This call does not block. /// </summary> /// <typeparam name="TManagedFormat">The managed format of the buffer.</typeparam> /// <typeparam name="TBufferFormat">The format of the native buffer.</typeparam> /// <param name="device">The device.</param> /// <param name="bufferFormat">The data format of the buffer.</param> /// <param name="sampleCount">The number of samples to retrieve.</param> /// <param name="buffer">The buffer to fill. </param> public unsafe void CaptureSamples <TManagedFormat, TBufferFormat> ( Device *device, TBufferFormat bufferFormat, int sampleCount, in TManagedFormat[] buffer
/// <inheritdoc /> public unsafe partial bool CaptureCloseDevice(Device *device);
/// <inheritdoc /> public abstract unsafe char *GetStringList(Device *device, GetEnumerationContextStringList param);
/// <inheritdoc /> public unsafe partial ContextError GetError(Device *device);
/// <inheritdoc /> public unsafe partial byte *GetStringList(Device *device, GetEnumerationContextStringList param);
public unsafe partial void GetContextProperty(Device *device, EFXContextInteger param, int size, int *data);