Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OpenAL Implementation #93

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CSCore.Test/CSCore.Test.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@
<Compile Include="SoundIn\WasapiCaptureBehaviourTests.cs" />
<Compile Include="SoundIn\WasapiLoopbackCaptureBehaviourTests.cs" />
<Compile Include="SoundIn\WaveInCaptureBehaviourTests.cs" />
<Compile Include="SoundOut\ALSoundOutBehaviourTests.cs" />
<Compile Include="SoundOut\DirectSoundOutBehaviourTests.cs" />
<Compile Include="SoundOut\SoundOutBehaviourTests.cs" />
<Compile Include="SoundOut\WasapiOutBehaviourTests.cs" />
Expand Down
14 changes: 14 additions & 0 deletions CSCore.Test/SoundOut/ALSoundOutBehaviourTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using CSCore.SoundOut;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace CSCore.Test.SoundOut
{
[TestClass]
public class ALSoundOutBehaviourTests : SoundOutBehaviourTests
{
protected override ISoundOut CreateSoundOut()
{
return new ALSoundOut();
}
}
}
10 changes: 10 additions & 0 deletions CSCore/CSCore.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -327,12 +327,22 @@
<Compile Include="SoundIn\WaveIn.cs" />
<Compile Include="SoundIn\WaveInBuffer.cs" />
<Compile Include="SoundIn\WaveInDevice.cs" />
<Compile Include="SoundOut\ALSoundOut.cs" />
<Compile Include="SoundOut\AL\ALErrorCodes.cs" />
<Compile Include="SoundOut\DirectSoundOut.cs" />
<Compile Include="SoundOut\MMInterop\Utils.cs" />
<Compile Include="SoundOut\MMInterop\WaveCallback.cs" />
<Compile Include="SoundOut\MmDeviceFormats.cs" />
<Compile Include="SoundOut\MmDeviceSupported.cs" />
<Compile Include="SoundOut\MMInterop\WaveHeaderFlags.cs" />
<Compile Include="SoundOut\AL\ALContext.cs" />
<Compile Include="SoundOut\AL\ALDevice.cs" />
<Compile Include="SoundOut\AL\ALFormat.cs" />
<Compile Include="SoundOut\AL\ALInterops.cs" />
<Compile Include="SoundOut\AL\ALPlayback.cs" />
<Compile Include="SoundOut\AL\ALSource.cs" />
<Compile Include="SoundOut\AL\ALSourceParameters.cs" />
<Compile Include="SoundOut\AL\ALSourceState.cs" />
<Compile Include="SoundOut\PlaybackStoppedEventArgs.cs" />
<Compile Include="SoundOut\WasapiOut.cs" />
<Compile Include="SoundOut\WaveOut.cs" />
Expand Down
69 changes: 69 additions & 0 deletions CSCore/SoundOut/AL/ALContext.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
using System;

namespace CSCore.SoundOut.AL
{
internal class ALContext : IDisposable
{
/// <summary>
/// Gets the handle
/// </summary>
public IntPtr Handle { private set; get; }

/// <summary>
/// Initializes a new ALContext class
/// </summary>
/// <param name="contextHandle">The handle</param>
private ALContext(IntPtr contextHandle)
{
Handle = contextHandle;
}

/// <summary>
/// Makes the context the current context
/// </summary>
public void MakeCurrent()
{
ALInterops.alcMakeContextCurrent(Handle);
}

/// <summary>
/// Deconstructs the ALContext class
/// </summary>
~ALContext()
{
Dispose(false);
}

/// <summary>
/// Disposes the openal context
/// </summary>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}

/// <summary>
/// Disposes the openal context
/// </summary>
/// <param name="disposing">The disposing state</param>
protected void Dispose(bool disposing)
{
if (Handle != IntPtr.Zero)
{
ALInterops.alcDestroyContext(Handle);
Handle = IntPtr.Zero;
}
}

/// <summary>
/// Creates a new openal context
/// </summary>
/// <param name="deviceHandle">The device handle</param>
/// <returns>OpenALContext</returns>
public static ALContext CreateContext(IntPtr deviceHandle)
{
return new ALContext(ALInterops.alcCreateContext(deviceHandle, IntPtr.Zero));
}
}
}
137 changes: 137 additions & 0 deletions CSCore/SoundOut/AL/ALDevice.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
using System;
using System.Collections.Generic;
using System.Linq;

namespace CSCore.SoundOut.AL
{
public class ALDevice : IDisposable
{
private static ALDevice[] _devices;

/// <summary>
/// Gets the name
/// </summary>
public string Name { private set; get; }

/// <summary>
/// Gets the openal context
/// </summary>
internal ALContext Context { get; private set; }

private IntPtr _deviceHandle;
private readonly List<ALSource> _sources;
private bool _isInitialized;

/// <summary>
/// Initializes a new ALDevice class
/// </summary>
internal ALDevice(string deviceName)
{
Name = deviceName;
_sources = new List<ALSource>();
}

/// <summary>
/// Initializes the openal device
/// </summary>
public void Initialize()
{
if (!_isInitialized)
{
_deviceHandle = ALInterops.alcOpenDevice(Name);
Context = ALContext.CreateContext(_deviceHandle);
_isInitialized = true;
}
}

internal ALErrorCode GetLastError()
{
return ALInterops.alGetError();
}

/// <summary>
/// Generates a new openal source
/// </summary>
/// <returns></returns>
internal ALSource GenerateALSource()
{
Context.MakeCurrent();

var sources = new uint[1];
ALInterops.alGenSources(1, sources);

return new ALSource(this, sources[0]);
}

/// <summary>
/// Deletes the specified openal source
/// </summary>
/// <param name="source">The source</param>
internal void DeleteALSource(ALSource source)
{
Context.MakeCurrent();

var sources = new uint[1];
sources[0] = source.Id;

ALInterops.alDeleteSources(1, sources);
}

/// <summary>
/// Enumerates the openal devices
/// </summary>
/// <returns></returns>
public static ALDevice[] EnumerateALDevices()
{
if (_devices == null)
{
var deviceNames = ALInterops.GetALDeviceNames();
var devices = new ALDevice[deviceNames.Length];

for (int i = 0; i < devices.Length; i++)
{
devices[i] = new ALDevice(deviceNames[i]);
}

_devices = devices;
}

return _devices;
}

/// <summary>
/// Gets the default playback device
/// </summary>
public static ALDevice DefaultDevice
{
get { return EnumerateALDevices().FirstOrDefault(); }
}

/// <summary>
/// Disposes the openal device
/// </summary>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}

/// <summary>
/// Disposes the openal device
/// </summary>
/// <param name="disposing">The disposing state</param>
protected void Dispose(bool disposing)
{
if (disposing)
{
Context.Dispose();
}

if (_deviceHandle != IntPtr.Zero)
{
ALInterops.alcCloseDevice(_deviceHandle);
_deviceHandle = IntPtr.Zero;
}
}
}
}
74 changes: 74 additions & 0 deletions CSCore/SoundOut/AL/ALErrorCodes.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CSCore.SoundOut.AL
{
public enum ALErrorCode
{
/// <summary>
/// No Error
/// </summary>
NoError = 0x0,

/// <summary>
/// Invalid Name
/// </summary>
InvalidName = 0xA001,

/// <summary>
/// Invalid Enum
/// </summary>
InvalidEnum = 0xA002,

/// <summary>
/// Invalid Value
/// </summary>
InvalidValue = 0xA003,

/// <summary>
/// Invalid Operation
/// </summary>
InvalidOperation = 0xA004,

/// <summary>
/// Out of Memory
/// </summary>
OutOfMemory = 0xA005
}

public enum ALCErrorCode
{
/// <summary>
/// No Error
/// </summary>
NoError = 0x0,

/// <summary>
/// Invalid Device
/// </summary>
InvalidDevice = 0xA001,


/// <summary>
/// Invalid Context
/// </summary>
InvalidContext = 0xA002,

/// <summary>
/// Invalid Enum
/// </summary>
InvalidEnum = 0xA003,

/// <summary>
/// Invalid Value
/// </summary>
InvalidValue = 0xA004,

/// <summary>
/// Out of Memory
/// </summary>
OutOfMemory = 0xA005
}
}
42 changes: 42 additions & 0 deletions CSCore/SoundOut/AL/ALFormat.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
namespace CSCore.SoundOut.AL
{
internal enum ALFormat
{
/// <summary>
/// Unknown.
/// </summary>
Unknown = 0,

/// <summary>
/// Mono, 8Bit.
/// </summary>
Mono8Bit = 0x1100,

/// <summary>
/// Mono, 16Bit.
/// </summary>
Mono16Bit = 0x1101,

/// <summary>
/// Stereo, 8Bit.
/// </summary>
Stereo8Bit = 0x1102,

/// <summary>
/// Stereo, 16Bit.
/// </summary>
Stereo16Bit = 0x1103,

/// <summary>
/// Mono, float 32Bit.
/// This is not required to be supported on all implementations
/// </summary>
MonoFloat32Bit = 0x10010,

/// <summary>
/// Stereo, float 32bit
/// This is not required to be supported on all implementations
/// </summary>
StereoFloat32Bit = 0x10011
}
}
Loading