documentation + fix some edge cases
parent
0500d94930
commit
9a854506f3
|
@ -3,6 +3,10 @@ using System.Runtime.InteropServices;
|
|||
|
||||
namespace MoonWorks.Audio
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains raw audio data in the format specified by Format.
|
||||
/// Submit this to a SourceVoice to play audio.
|
||||
/// </summary>
|
||||
public class AudioBuffer : AudioResource
|
||||
{
|
||||
IntPtr BufferDataPtr;
|
||||
|
@ -24,11 +28,22 @@ namespace MoonWorks.Audio
|
|||
OwnsBufferData = ownsBufferData;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create another AudioBuffer from this audio buffer.
|
||||
/// It will not own the buffer data.
|
||||
/// </summary>
|
||||
/// <param name="offset">Offset in bytes from the top of the original buffer.</param>
|
||||
/// <param name="length">Length in bytes of the new buffer.</param>
|
||||
/// <returns></returns>
|
||||
public AudioBuffer CreateSubBuffer(int offset, uint length)
|
||||
{
|
||||
return new AudioBuffer(Device, Format, BufferDataPtr + offset, length, false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create an FAudioBuffer struct from this AudioBuffer.
|
||||
/// </summary>
|
||||
/// <param name="loop">Whether we should set the FAudioBuffer to loop.</param>
|
||||
public FAudio.FAudioBuffer ToFAudioBuffer(bool loop = false)
|
||||
{
|
||||
return new FAudio.FAudioBuffer
|
||||
|
|
|
@ -4,6 +4,9 @@ using System.Runtime.InteropServices;
|
|||
|
||||
namespace MoonWorks.Audio
|
||||
{
|
||||
/// <summary>
|
||||
/// Streamable audio in Ogg format.
|
||||
/// </summary>
|
||||
public class AudioDataOgg : AudioDataStreamable
|
||||
{
|
||||
private IntPtr FileDataPtr = IntPtr.Zero;
|
||||
|
|
|
@ -4,6 +4,9 @@ using System.Runtime.InteropServices;
|
|||
|
||||
namespace MoonWorks.Audio
|
||||
{
|
||||
/// <summary>
|
||||
/// Streamable audio in QOA format.
|
||||
/// </summary>
|
||||
public class AudioDataQoa : AudioDataStreamable
|
||||
{
|
||||
private IntPtr QoaHandle = IntPtr.Zero;
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
namespace MoonWorks.Audio
|
||||
{
|
||||
/// <summary>
|
||||
/// Use this in conjunction with a StreamingVoice to play back streaming audio data.
|
||||
/// </summary>
|
||||
public abstract class AudioDataStreamable : AudioResource
|
||||
{
|
||||
public Format Format { get; protected set; }
|
||||
|
|
|
@ -6,9 +6,14 @@ namespace MoonWorks.Audio
|
|||
{
|
||||
public static class AudioDataWav
|
||||
{
|
||||
// mostly borrowed from https://github.com/FNA-XNA/FNA/blob/b71b4a35ae59970ff0070dea6f8620856d8d4fec/src/Audio/SoundEffect.cs#L385
|
||||
/// <summary>
|
||||
/// Create an AudioBuffer containing all the WAV audio data in a file.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public unsafe static AudioBuffer CreateBuffer(AudioDevice device, string filePath)
|
||||
{
|
||||
// mostly borrowed from https://github.com/FNA-XNA/FNA/blob/b71b4a35ae59970ff0070dea6f8620856d8d4fec/src/Audio/SoundEffect.cs#L385
|
||||
|
||||
// WaveFormatEx data
|
||||
ushort wFormatTag;
|
||||
ushort nChannels;
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
using System.IO;
|
||||
|
||||
namespace MoonWorks.Audio
|
||||
{
|
||||
public static class AudioUtils
|
||||
{
|
||||
public static Format ReadWaveFormat(string filePath, out int dataLength)
|
||||
{
|
||||
var fileInfo = new FileInfo(filePath);
|
||||
using FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
|
||||
using BinaryReader br = new BinaryReader(fs);
|
||||
|
||||
fs.Position = 20;
|
||||
var formatTag = br.ReadInt16();
|
||||
fs.Position = 22;
|
||||
var channels = br.ReadInt16();
|
||||
fs.Position = 24;
|
||||
var sampleRate = br.ReadInt32();
|
||||
fs.Position = 34;
|
||||
var bitsPerSample = br.ReadInt16();
|
||||
fs.Position = 40;
|
||||
dataLength = br.ReadInt32();
|
||||
|
||||
return new Format
|
||||
{
|
||||
Tag = (FormatTag) formatTag,
|
||||
Channels = (ushort) channels,
|
||||
SampleRate = (uint) sampleRate,
|
||||
BitsPerSample = (ushort) bitsPerSample
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,8 @@
|
|||
namespace MoonWorks.Audio
|
||||
{
|
||||
/// <summary>
|
||||
/// PersistentVoice should be used when you need to maintain a long-term reference to a source voice.
|
||||
/// </summary>
|
||||
public class PersistentVoice : SourceVoice, IPoolable<PersistentVoice>
|
||||
{
|
||||
public PersistentVoice(AudioDevice device, Format format) : base(device, format)
|
||||
|
|
|
@ -3,7 +3,9 @@ using System.Runtime.InteropServices;
|
|||
|
||||
namespace MoonWorks.Audio
|
||||
{
|
||||
// sound instances can send their audio to this voice to add reverb
|
||||
/// <summary>
|
||||
/// Use this in conjunction with SourceVoice.SetReverbEffectChain to add reverb to a voice.
|
||||
/// </summary>
|
||||
public unsafe class ReverbEffect : SubmixVoice
|
||||
{
|
||||
public ReverbEffect(AudioDevice audioDevice) : base(audioDevice, 1, audioDevice.DeviceDetails.OutputFormat.Format.nSamplesPerSec)
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
namespace MoonWorks.Audio
|
||||
{
|
||||
// NOTE: all sounds played with a SoundSequence must have the same audio format!
|
||||
/// <summary>
|
||||
/// Plays back a series of AudioBuffers in sequence. Set the OnSoundNeeded callback to add AudioBuffers dynamically.
|
||||
/// </summary>
|
||||
public class SoundSequence : SourceVoice
|
||||
{
|
||||
public int NeedSoundThreshold = 0;
|
||||
|
|
|
@ -10,6 +10,8 @@ namespace MoonWorks.Audio
|
|||
private Format format;
|
||||
public Format Format => format;
|
||||
|
||||
protected bool PlaybackInitiated;
|
||||
|
||||
/// <summary>
|
||||
/// The number of buffers queued in the voice.
|
||||
/// This includes the currently playing voice!
|
||||
|
@ -170,6 +172,13 @@ namespace MoonWorks.Audio
|
|||
}
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
Stop();
|
||||
PlaybackInitiated = false;
|
||||
base.Reset();
|
||||
}
|
||||
|
||||
protected override unsafe void Destroy()
|
||||
{
|
||||
Stop();
|
||||
|
|
|
@ -3,6 +3,9 @@ using System.Runtime.InteropServices;
|
|||
|
||||
namespace MoonWorks.Audio
|
||||
{
|
||||
/// <summary>
|
||||
/// Use in conjunction with an AudioDataStreamable object to play back streaming audio data.
|
||||
/// </summary>
|
||||
public class StreamingVoice : SourceVoice, IPoolable<StreamingVoice>
|
||||
{
|
||||
private const int BUFFER_COUNT = 3;
|
||||
|
@ -54,6 +57,12 @@ namespace MoonWorks.Audio
|
|||
}
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
Unload();
|
||||
base.Reset();
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
lock (StateLock)
|
||||
|
@ -67,7 +76,7 @@ namespace MoonWorks.Audio
|
|||
}
|
||||
}
|
||||
|
||||
protected void QueueBuffers()
|
||||
private void QueueBuffers()
|
||||
{
|
||||
int buffersNeeded = BUFFER_COUNT - (int) BuffersQueued; // don't get got by uint underflow!
|
||||
for (int i = 0; i < buffersNeeded; i += 1)
|
||||
|
@ -76,7 +85,7 @@ namespace MoonWorks.Audio
|
|||
}
|
||||
}
|
||||
|
||||
protected unsafe void AddBuffer()
|
||||
private unsafe void AddBuffer()
|
||||
{
|
||||
var buffer = buffers[nextBufferIndex];
|
||||
nextBufferIndex = (nextBufferIndex + 1) % BUFFER_COUNT;
|
||||
|
|
|
@ -2,6 +2,9 @@ using System;
|
|||
|
||||
namespace MoonWorks.Audio
|
||||
{
|
||||
/// <summary>
|
||||
/// SourceVoices can send audio to a SubmixVoice for convenient effects processing.
|
||||
/// </summary>
|
||||
public class SubmixVoice : Voice
|
||||
{
|
||||
public SubmixVoice(
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
namespace MoonWorks.Audio
|
||||
{
|
||||
/// <summary>
|
||||
/// These voices are intended for playing one-off sound effects that don't have a long term reference.
|
||||
/// TransientVoice is intended for playing one-off sound effects that don't have a long term reference.
|
||||
/// It will be automatically returned to the source voice pool once it is done playing back.
|
||||
/// </summary>
|
||||
public class TransientVoice : SourceVoice, IPoolable<TransientVoice>
|
||||
{
|
||||
|
@ -18,7 +19,7 @@ namespace MoonWorks.Audio
|
|||
{
|
||||
lock (StateLock)
|
||||
{
|
||||
if (BuffersQueued == 0)
|
||||
if (PlaybackInitiated && BuffersQueued == 0)
|
||||
{
|
||||
Return();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue