-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #25 from Tornado-Technology/audio-management
Audio management
- Loading branch information
Showing
23 changed files
with
753 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
namespace Hypercube.Client.Audio; | ||
|
||
public enum AudioFormat | ||
{ | ||
Mono8 = 0x1100, | ||
Mono16 = 0x1101, | ||
Stereo8 = 0x1102, | ||
Stereo16 = 0x1103 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
namespace Hypercube.Client.Audio; | ||
|
||
public readonly struct AudioId(int value) : IEquatable<AudioId> | ||
{ | ||
public static readonly AudioId Invalid = new(-1); | ||
public static readonly AudioId Zero = new(0); | ||
|
||
public readonly int Value = value; | ||
|
||
public bool Equals(AudioId other) | ||
{ | ||
return Value == other.Value; | ||
} | ||
|
||
public override bool Equals(object? obj) | ||
{ | ||
return obj is AudioId id && Equals(id); | ||
} | ||
|
||
public static bool operator ==(AudioId a, AudioId b) | ||
{ | ||
return a.Equals(b); | ||
} | ||
|
||
public static bool operator !=(AudioId a, AudioId b) | ||
{ | ||
return !a.Equals(b); | ||
} | ||
|
||
public static implicit operator int(AudioId id) | ||
{ | ||
return id.Value; | ||
} | ||
|
||
public override int GetHashCode() | ||
{ | ||
return Value; | ||
} | ||
|
||
public override string ToString() | ||
{ | ||
return $"audio({Value})"; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
namespace Hypercube.Client.Audio; | ||
|
||
public readonly struct AudioSettings; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
namespace Hypercube.Client.Audio; | ||
|
||
public sealed class AudioStream | ||
{ | ||
public readonly AudioId Id; | ||
public readonly TimeSpan Length; | ||
|
||
public AudioStream(AudioId id, TimeSpan length) | ||
{ | ||
Id = id; | ||
Length = length; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
namespace Hypercube.Client.Audio; | ||
|
||
/// <remarks> | ||
/// Taken from <a href="https://en.wikipedia.org/wiki/Audio_file_format">Wikipedia</a>. | ||
/// </remarks> | ||
public enum AudioType | ||
{ | ||
_3gp, | ||
Aa, | ||
Aac, | ||
Aax, | ||
Act, | ||
Aiff, | ||
Alac, | ||
Amr, | ||
Ape, | ||
Au, | ||
Awb, | ||
Dss, | ||
Dvf, | ||
Flac, | ||
Gsm, | ||
Iklax, | ||
Ivs, | ||
M4A, | ||
M4B, | ||
M4P, | ||
Mmf, | ||
Movpkg, | ||
Mp3, | ||
Mpc, | ||
Msv, | ||
Nmf, | ||
Ogg, | ||
Oga, | ||
Mogg, | ||
Opus, | ||
Ra, | ||
Rm, | ||
Raw, | ||
Rf64, | ||
Sln, | ||
Tta, | ||
Voc, | ||
Vox, | ||
Wav, | ||
Wma, | ||
Wv, | ||
Webm, | ||
_8svx, | ||
Cda, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
namespace Hypercube.Client.Audio; | ||
|
||
public interface IAudioData | ||
{ | ||
AudioFormat Format { get; } | ||
ReadOnlyMemory<byte> Data { get; } | ||
int SampleRate { get; } | ||
TimeSpan Length { get; } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
namespace Hypercube.Client.Audio; | ||
|
||
public interface IAudioGroup | ||
{ | ||
float Gain { get; } | ||
|
||
void SetGain(float gain); | ||
|
||
void PauseAll(); | ||
void StopAll(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
using Hypercube.Shared.Resources; | ||
|
||
namespace Hypercube.Client.Audio; | ||
|
||
public interface IAudioManager | ||
{ | ||
IAudioSource CreateSource(ResourcePath path, AudioSettings settings); | ||
IAudioSource CreateSource(AudioStream stream); | ||
AudioStream GetAudio(ResourcePath path, AudioSettings settings); | ||
|
||
void Initialize(); | ||
|
||
/// <summary> | ||
/// Pause all audio sources. | ||
/// </summary> | ||
void PauseAll(); | ||
|
||
/// <summary> | ||
/// Stops all audio sources. | ||
/// </summary> | ||
void StopAll(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
namespace Hypercube.Client.Audio; | ||
|
||
public interface IAudioSource : IDisposable | ||
{ | ||
IAudioGroup? Group { get; } | ||
bool Playing { get; } | ||
|
||
bool Looping { get; set; } | ||
float Pitch { get; set; } | ||
float Gain { get; set; } | ||
|
||
void Start(); | ||
void Stop(); | ||
void Restart(); | ||
void Pause(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
using System.Collections.Frozen; | ||
using Hypercube.Client.Audio.Loading.Type; | ||
|
||
namespace Hypercube.Client.Audio.Loading; | ||
|
||
public sealed class AudioLoader : IAudioLoader | ||
{ | ||
private readonly FrozenDictionary<AudioType, IAudioTypeLoader> _loaders = new Dictionary<AudioType, IAudioTypeLoader> | ||
{ | ||
{ AudioType.Wav, new AudioWavLoader() } | ||
}.ToFrozenDictionary(); | ||
|
||
|
||
public IAudioData LoadAudioData(Stream stream, AudioType type) | ||
{ | ||
return _loaders[type].LoadAudioData(stream); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
namespace Hypercube.Client.Audio.Loading; | ||
|
||
public interface IAudioLoader | ||
{ | ||
IAudioData LoadAudioData(Stream stream, AudioType type); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
using Hypercube.Client.Audio.Reader.Wav; | ||
|
||
namespace Hypercube.Client.Audio.Loading.Type; | ||
|
||
public sealed class AudioWavLoader : IAudioTypeLoader | ||
{ | ||
public IAudioData LoadAudioData(Stream stream) | ||
{ | ||
var reader = new AudioWavReader(stream); | ||
return reader.Read(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
namespace Hypercube.Client.Audio.Loading.Type; | ||
|
||
public interface IAudioTypeLoader | ||
{ | ||
IAudioData LoadAudioData(Stream stream); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
namespace Hypercube.Client.Audio.Reader.Wav; | ||
|
||
/// <summary> | ||
/// Read the <a href="http://soundfile.sapp.org/doc/WaveFormat/">specification</a> for more information | ||
/// </summary> | ||
/// <remarks> | ||
/// 8-bit samples are stored as unsigned bytes, ranging from 0 to 255. | ||
/// 16-bit samples are stored as 2's-complement signed integers, ranging from -32768 to 32767. | ||
/// </remarks> | ||
public readonly struct AudioWavData : IAudioData | ||
{ | ||
public AudioFormat Format { get; } | ||
public ReadOnlyMemory<byte> Data { get; } | ||
public int SampleRate { get; } | ||
public TimeSpan Length { get; } | ||
|
||
public readonly short FormatType; | ||
public readonly short Channels; | ||
public readonly int ByteRate; | ||
public readonly short BlockAlign; | ||
public readonly short BitsPerSample; | ||
|
||
public AudioWavData(short formatType, short channels, int sampleRate, int byteRate, short blockAlign, short bitsPerSample, ReadOnlyMemory<byte> data) | ||
{ | ||
Format = GetFormat(channels, bitsPerSample); | ||
Data = data; | ||
SampleRate = sampleRate; | ||
Length = TimeSpan.FromSeconds(data.Length / (double) blockAlign / sampleRate); | ||
|
||
FormatType = formatType; | ||
Channels = channels; | ||
ByteRate = byteRate; | ||
BlockAlign = blockAlign; | ||
BitsPerSample = bitsPerSample; | ||
} | ||
|
||
public override string ToString() | ||
{ | ||
return $"format type {FormatType}, channels {Channels}, sample rate {SampleRate}, byte rate {ByteRate}, block align {BlockAlign}, bits per sample {BitsPerSample}, data length {Data.Length}"; | ||
} | ||
|
||
private static AudioFormat GetFormat(int channels, int bits) | ||
{ | ||
return bits switch | ||
{ | ||
8 => channels switch | ||
{ | ||
1 => AudioFormat.Mono8, | ||
2 => AudioFormat.Stereo8, | ||
_ => throw new InvalidOperationException() | ||
}, | ||
16 => channels switch | ||
{ | ||
1 => AudioFormat.Mono16, | ||
2 => AudioFormat.Stereo16, | ||
_ => throw new InvalidOperationException() | ||
}, | ||
_ => throw new InvalidOperationException() | ||
}; | ||
} | ||
} |
Oops, something went wrong.