Skip to content
This repository was archived by the owner on Sep 8, 2023. It is now read-only.
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
21 changes: 14 additions & 7 deletions Framework/Audio/Audio.cs
Original file line number Diff line number Diff line change
@@ -1,23 +1,30 @@
using System;
using System.IO;

namespace Foster.Framework
{
/// <summary>
/// The Core Audio Module, used for playing sounds
/// </summary>
public abstract class Audio : Module
public abstract class Audio : AppModule
{
public string ApiName { get; protected set; } = "Unknown";
public Version ApiVersion { get; protected set; } = new Version(0, 0, 0);

protected Audio() : base(400)
{
internal readonly AudioSourcePool AudioSourcePool = new AudioSourcePool();

}
protected internal abstract AudioSource.Platform CreateAudioSource();

protected Audio() : base(400) { }

/// <summary>
/// The Renderer this Audio Module implements
/// </summary>
public abstract Renderer Renderer { get; }

protected internal override void Startup()
protected internal sealed override void Update()
{
Console.WriteLine($" - Audio {ApiName} {ApiVersion}");
AudioSourcePool.Update();
}
}
}
}
9 changes: 9 additions & 0 deletions Framework/Audio/AudioChannel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace Foster.Framework
{
public enum AudioChannel
{
None = 0,
Mono = 1,
Stereo = 2
}
}
13 changes: 13 additions & 0 deletions Framework/Audio/AudioException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System;

namespace Foster.Framework
{
public class AudioException : Exception
{
public AudioException() { }

public AudioException(string message) : base(message) { }

public AudioException(string message, Exception innerException) : base(message, innerException) { }
}
}
102 changes: 102 additions & 0 deletions Framework/Audio/AudioSource.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
using System;
using System.IO;

namespace Foster.Framework
{
public class AudioSource : IDisposable
{
public abstract class Platform
{
protected internal abstract void Init(AudioSource source, Stream stream);

protected internal abstract float Volume { get; set; }
protected internal abstract float Pitch { get; set; }
protected internal abstract bool Loop { get; set; }

protected internal abstract AudioState GetState();

protected internal abstract void Pause();
protected internal abstract void Play();
protected internal abstract void Resume();

protected internal abstract void Rewind();

protected internal abstract void Stop();


protected internal abstract void Dispose();
}

private readonly Platform implementation;

private readonly Audio audio;

internal bool IsPooled = false;

public float Volume
{
get => implementation.Volume;
set => implementation.Volume = value;
}

public float Pitch
{
get => implementation.Pitch;
set => implementation.Pitch = value;
}

public bool Loop
{
get => implementation.Loop;
set => implementation.Loop = value;
}

public AudioSource(Audio audio, Stream stream)
{
this.audio = audio;
implementation = audio.CreateAudioSource();
implementation.Init(this, stream);
}

public AudioSource(Stream stream)
: this(App.Audio, stream)
{
}

public AudioSource(string fileName)
: this(App.Audio, File.Open(fileName, FileMode.Open))
{
}

public AudioState GetState()
{
return implementation.GetState();
}

public void Pause()
{
implementation.Pause();
}

public void Play()
{

implementation.Play();
}

public void Resume()
{
implementation.Resume();
}

public void Stop()
{
implementation.Stop();
}

public void Dispose()
{
implementation.Dispose();
}
}
}
73 changes: 73 additions & 0 deletions Framework/Audio/AudioSourcePool.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
using System;
using System.Collections.Concurrent;
using System.IO;

namespace Foster.Framework
{
internal class AudioSourcePool : IDisposable
{
private readonly ConcurrentStack<AudioSource> availableSources;
private readonly ConcurrentHashSet<AudioSource> playingSources;

public int Count => availableSources.Count + playingSources.Count;

public AudioSourcePool()
{
availableSources = new ConcurrentStack<AudioSource>();
playingSources = new ConcurrentHashSet<AudioSource>();
}

public AudioSource Reserve(Audio audio, Stream stream)
{
if (!availableSources.TryPop(out var source))
{
source = new AudioSource(audio, stream)
{
IsPooled = true
};
}

playingSources.Add(source);
return source;
}

public void Free(AudioSource source)
{
if (!playingSources.TryRemove(source))
{
Log.Error("Audio source is not pooled");
}
}

public void Update()
{
foreach (var source in playingSources)
{
if (source.GetState() == AudioState.Stopped)
{
if (playingSources.TryRemove(source))
{
availableSources.Push(source);
}
else
{
Log.Message("Failed to remove source; possible race condition");
}
}
}
}

public void Dispose()
{
foreach (var source in playingSources)
{
source.Dispose();
}

foreach (var source in availableSources)
{
source.Dispose();
}
}
}
}
10 changes: 10 additions & 0 deletions Framework/Audio/AudioState.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace Foster.Framework
{
public enum AudioState
{
Unknown,
Playing,
Paused,
Stopped
}
}
10 changes: 10 additions & 0 deletions Framework/Audio/IAudioOpenAL.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace Foster.Framework
{
/// <summary>
/// An Implementation of the Audio Module that supports the OpenAL API
/// </summary>
public interface IAudioOpenAL
{

}
}
Loading