forked from MoonsideGames/MoonWorks
fix static sound loading + window title
parent
adf047955e
commit
ec28d17a75
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace MoonWorks.Audio
|
||||
|
@ -17,6 +18,8 @@ namespace MoonWorks.Audio
|
|||
|
||||
private FAudio.FAudioVoiceSends reverbSends;
|
||||
|
||||
private readonly List<WeakReference<DynamicSoundInstance>> dynamicSoundInstances = new List<WeakReference<DynamicSoundInstance>>();
|
||||
|
||||
public unsafe AudioDevice()
|
||||
{
|
||||
FAudio.FAudioCreate(out var handle, 0, 0);
|
||||
|
@ -177,16 +180,39 @@ namespace MoonWorks.Audio
|
|||
|
||||
/* Init reverb sends */
|
||||
|
||||
reverbSends = new FAudio.FAudioVoiceSends();
|
||||
reverbSends.SendCount = 2;
|
||||
reverbSends.pSends = Marshal.AllocHGlobal(
|
||||
2 * Marshal.SizeOf<FAudio.FAudioSendDescriptor>()
|
||||
);
|
||||
reverbSends = new FAudio.FAudioVoiceSends
|
||||
{
|
||||
SendCount = 2,
|
||||
pSends = Marshal.AllocHGlobal(
|
||||
2 * Marshal.SizeOf<FAudio.FAudioSendDescriptor>()
|
||||
)
|
||||
};
|
||||
FAudio.FAudioSendDescriptor* sendDesc = (FAudio.FAudioSendDescriptor*) reverbSends.pSends;
|
||||
sendDesc[0].Flags = 0;
|
||||
sendDesc[0].pOutputVoice = MasteringVoice;
|
||||
sendDesc[1].Flags = 0;
|
||||
sendDesc[1].pOutputVoice = ReverbVoice;
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
for (var i = dynamicSoundInstances.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var weakReference = dynamicSoundInstances[i];
|
||||
if (weakReference.TryGetTarget(out var dynamicSoundInstance))
|
||||
{
|
||||
dynamicSoundInstance.Update();
|
||||
}
|
||||
else
|
||||
{
|
||||
dynamicSoundInstances.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void AddDynamicSoundInstance(DynamicSoundInstance instance)
|
||||
{
|
||||
dynamicSoundInstances.Add(new WeakReference<DynamicSoundInstance>(instance));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,10 +4,13 @@ using System.IO;
|
|||
namespace MoonWorks.Audio
|
||||
{
|
||||
/// <summary>
|
||||
/// For streaming long playback.
|
||||
/// For streaming long playback. Reads an OGG file.
|
||||
/// </summary>
|
||||
public class DynamicSound : Sound, IDisposable
|
||||
{
|
||||
internal override FAudio.FAudioWaveFormatEx Format { get; }
|
||||
|
||||
// FIXME: what should this value be?
|
||||
public const int BUFFER_SIZE = 1024 * 128;
|
||||
|
||||
internal IntPtr FileHandle { get; }
|
||||
|
@ -15,9 +18,7 @@ namespace MoonWorks.Audio
|
|||
|
||||
private bool IsDisposed;
|
||||
|
||||
// FIXME: what should this value be?
|
||||
|
||||
public DynamicSound(FileInfo fileInfo, ushort channels, uint samplesPerSecond) : base(channels, samplesPerSecond)
|
||||
public DynamicSound(AudioDevice device, FileInfo fileInfo) : base(device)
|
||||
{
|
||||
FileHandle = FAudio.stb_vorbis_open_filename(fileInfo.FullName, out var error, IntPtr.Zero);
|
||||
|
||||
|
@ -28,6 +29,26 @@ namespace MoonWorks.Audio
|
|||
}
|
||||
|
||||
Info = FAudio.stb_vorbis_get_info(FileHandle);
|
||||
|
||||
var blockAlign = (ushort)(4 * Info.channels);
|
||||
|
||||
Format = new FAudio.FAudioWaveFormatEx
|
||||
{
|
||||
wFormatTag = 3,
|
||||
wBitsPerSample = 32,
|
||||
nChannels = (ushort) Info.channels,
|
||||
nBlockAlign = blockAlign,
|
||||
nSamplesPerSec = Info.sample_rate,
|
||||
nAvgBytesPerSec = blockAlign * Info.sample_rate,
|
||||
cbSize = 0
|
||||
};
|
||||
}
|
||||
|
||||
public DynamicSoundInstance CreateInstance()
|
||||
{
|
||||
var instance = new DynamicSoundInstance(Device, this, false);
|
||||
Device.AddDynamicSoundInstance(instance);
|
||||
return instance;
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
|
|
|
@ -16,7 +16,7 @@ namespace MoonWorks.Audio
|
|||
|
||||
public override SoundState State { get; protected set; }
|
||||
|
||||
public DynamicSoundInstance(
|
||||
internal DynamicSoundInstance(
|
||||
AudioDevice device,
|
||||
DynamicSound parent,
|
||||
bool is3D
|
||||
|
@ -26,6 +26,8 @@ namespace MoonWorks.Audio
|
|||
queuedSizes = new List<uint>();
|
||||
|
||||
buffer = new float[DynamicSound.BUFFER_SIZE];
|
||||
|
||||
State = SoundState.Stopped;
|
||||
}
|
||||
|
||||
public void Play()
|
||||
|
@ -60,7 +62,7 @@ namespace MoonWorks.Audio
|
|||
ClearBuffers();
|
||||
}
|
||||
|
||||
private void Update()
|
||||
internal void Update()
|
||||
{
|
||||
if (State != SoundState.Playing)
|
||||
{
|
||||
|
@ -117,7 +119,7 @@ namespace MoonWorks.Audio
|
|||
buffer.Length
|
||||
);
|
||||
|
||||
IntPtr next = Marshal.AllocHGlobal(buffer.Length);
|
||||
IntPtr next = Marshal.AllocHGlobal(buffer.Length * sizeof(float));
|
||||
Marshal.Copy(buffer, 0, next, buffer.Length);
|
||||
|
||||
lock (queuedBuffers)
|
||||
|
|
|
@ -2,25 +2,12 @@ namespace MoonWorks.Audio
|
|||
{
|
||||
public abstract class Sound
|
||||
{
|
||||
internal FAudio.FAudioWaveFormatEx Format { get; }
|
||||
internal AudioDevice Device { get; }
|
||||
internal abstract FAudio.FAudioWaveFormatEx Format { get; }
|
||||
|
||||
/* NOTE: we only support float decoding! WAV sucks! */
|
||||
public Sound(
|
||||
ushort channels,
|
||||
uint samplesPerSecond
|
||||
) {
|
||||
var blockAlign = (ushort) (4 * channels);
|
||||
|
||||
Format = new FAudio.FAudioWaveFormatEx
|
||||
{
|
||||
wFormatTag = 3,
|
||||
wBitsPerSample = 32,
|
||||
nChannels = channels,
|
||||
nBlockAlign = blockAlign,
|
||||
nSamplesPerSec = samplesPerSecond,
|
||||
nAvgBytesPerSec = blockAlign * samplesPerSecond,
|
||||
cbSize = 0
|
||||
};
|
||||
public Sound(AudioDevice device)
|
||||
{
|
||||
Device = device;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,13 +6,15 @@ namespace MoonWorks.Audio
|
|||
{
|
||||
public class StaticSound : Sound, IDisposable
|
||||
{
|
||||
internal override FAudio.FAudioWaveFormatEx Format { get; }
|
||||
internal FAudio.FAudioBuffer Handle;
|
||||
private bool IsDisposed;
|
||||
|
||||
public uint LoopStart { get; set; } = 0;
|
||||
public uint LoopLength { get; set; } = 0;
|
||||
|
||||
public static StaticSound FromOgg(FileInfo fileInfo)
|
||||
private bool IsDisposed;
|
||||
|
||||
public static StaticSound LoadOgg(AudioDevice device, FileInfo fileInfo)
|
||||
{
|
||||
var filePointer = FAudio.stb_vorbis_open_filename(fileInfo.FullName, out var error, IntPtr.Zero);
|
||||
|
||||
|
@ -21,12 +23,20 @@ namespace MoonWorks.Audio
|
|||
throw new AudioLoadException("Error loading file!");
|
||||
}
|
||||
var info = FAudio.stb_vorbis_get_info(filePointer);
|
||||
var bufferSize = (uint)(info.sample_rate * info.channels);
|
||||
var bufferSize = FAudio.stb_vorbis_stream_length_in_samples(filePointer);
|
||||
var buffer = new float[bufferSize];
|
||||
|
||||
FAudio.stb_vorbis_get_samples_float_interleaved(
|
||||
filePointer,
|
||||
info.channels,
|
||||
buffer,
|
||||
(int) bufferSize
|
||||
);
|
||||
|
||||
FAudio.stb_vorbis_close(filePointer);
|
||||
|
||||
return new StaticSound(
|
||||
device,
|
||||
buffer,
|
||||
0,
|
||||
(ushort) info.channels,
|
||||
|
@ -35,25 +45,42 @@ namespace MoonWorks.Audio
|
|||
}
|
||||
|
||||
public StaticSound(
|
||||
AudioDevice device,
|
||||
float[] buffer,
|
||||
uint bufferOffset,
|
||||
ushort channels,
|
||||
uint samplesPerSecond
|
||||
) : base(channels, samplesPerSecond) {
|
||||
var bufferLength = 4 * buffer.Length;
|
||||
) : base(device) {
|
||||
var blockAlign = (ushort)(4 * channels);
|
||||
|
||||
Format = new FAudio.FAudioWaveFormatEx
|
||||
{
|
||||
wFormatTag = 3,
|
||||
wBitsPerSample = 32,
|
||||
nChannels = channels,
|
||||
nBlockAlign = blockAlign,
|
||||
nSamplesPerSec = samplesPerSecond,
|
||||
nAvgBytesPerSec = blockAlign * samplesPerSecond
|
||||
};
|
||||
|
||||
var bufferLengthInBytes = sizeof(float) * buffer.Length;
|
||||
|
||||
Handle = new FAudio.FAudioBuffer();
|
||||
Handle.Flags = FAudio.FAUDIO_END_OF_STREAM;
|
||||
Handle.pContext = IntPtr.Zero;
|
||||
Handle.AudioBytes = (uint) bufferLength;
|
||||
Handle.pAudioData = Marshal.AllocHGlobal((int) bufferLength);
|
||||
Marshal.Copy(buffer, (int) bufferOffset, Handle.pAudioData, (int) bufferLength);
|
||||
Handle.AudioBytes = (uint) bufferLengthInBytes;
|
||||
Handle.pAudioData = Marshal.AllocHGlobal(bufferLengthInBytes);
|
||||
Marshal.Copy(buffer, (int) bufferOffset, Handle.pAudioData, buffer.Length);
|
||||
Handle.PlayBegin = 0;
|
||||
Handle.PlayLength = (
|
||||
Handle.AudioBytes /
|
||||
(uint) Format.nChannels /
|
||||
(uint) (Format.wBitsPerSample / 8)
|
||||
);
|
||||
Handle.PlayLength = 0;
|
||||
|
||||
LoopStart = 0;
|
||||
LoopLength = 0;
|
||||
}
|
||||
|
||||
public StaticSoundInstance CreateInstance()
|
||||
{
|
||||
return new StaticSoundInstance(Device, this, false, true);
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
|
|
|
@ -38,6 +38,7 @@ namespace MoonWorks.Audio
|
|||
) : base(device, parent, is3D)
|
||||
{
|
||||
Loop = loop;
|
||||
State = SoundState.Stopped;
|
||||
}
|
||||
|
||||
public void Play()
|
||||
|
|
|
@ -82,6 +82,7 @@ namespace MoonWorks
|
|||
HandleSDLEvents();
|
||||
|
||||
Input.Update();
|
||||
AudioDevice.Update();
|
||||
|
||||
Update(timestep);
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ namespace MoonWorks
|
|||
ScreenMode = windowCreateInfo.ScreenMode;
|
||||
|
||||
Handle = SDL.SDL_CreateWindow(
|
||||
"MoonWorks.GraphicsTest",
|
||||
windowCreateInfo.WindowTitle,
|
||||
SDL.SDL_WINDOWPOS_UNDEFINED,
|
||||
SDL.SDL_WINDOWPOS_UNDEFINED,
|
||||
(int)windowCreateInfo.WindowWidth,
|
||||
|
|
|
@ -2,6 +2,7 @@ namespace MoonWorks
|
|||
{
|
||||
public struct WindowCreateInfo
|
||||
{
|
||||
public string WindowTitle;
|
||||
public uint WindowWidth;
|
||||
public uint WindowHeight;
|
||||
public ScreenMode ScreenMode;
|
||||
|
|
Loading…
Reference in New Issue