switched to openal sound support

This commit is contained in:
Chris Forbes
2010-01-08 15:22:19 +13:00
parent 49774e022d
commit da28d226ac
4 changed files with 116 additions and 38 deletions

View File

@@ -63,10 +63,6 @@
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\Ijw.DirectX\Ijw.Framework\IjwFramework\bin\Debug\IjwFramework.dll</HintPath> <HintPath>..\Ijw.DirectX\Ijw.Framework\IjwFramework\bin\Debug\IjwFramework.dll</HintPath>
</Reference> </Reference>
<Reference Include="irrKlang.NET2.0, Version=1.1.3.0, Culture=neutral, PublicKeyToken=a854741bd80517c7, processorArchitecture=x86">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\thirdparty\irrKlang.NET2.0.dll</HintPath>
</Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Core"> <Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework> <RequiredTargetFramework>3.5</RequiredTargetFramework>
@@ -75,6 +71,7 @@
<Reference Include="System.Drawing" /> <Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" /> <Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
<Reference Include="Tao.OpenAl, Version=1.1.0.1, Culture=neutral, PublicKeyToken=a7579dda88828311, processorArchitecture=MSIL" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Chat.cs" /> <Compile Include="Chat.cs" />

View File

@@ -1,7 +1,8 @@
using IjwFramework.Collections; using IjwFramework.Collections;
using IrrKlang;
using OpenRa.FileFormats; using OpenRa.FileFormats;
using OpenRa.Game.GameRules; using OpenRa.Game.GameRules;
using Tao.OpenAl;
using System;
namespace OpenRa.Game namespace OpenRa.Game
{ {
@@ -14,49 +15,42 @@ namespace OpenRa.Game
//TODO: read these from somewhere? //TODO: read these from somewhere?
static float soundVolume; static float soundVolume;
static float musicVolume; static float musicVolume;
static bool paused; // static bool paused;
static ISoundSource LoadSound(string filename) static ISoundSource LoadSound(string filename)
{ {
var data = AudLoader.LoadSound(FileSystem.Open(filename)); var data = AudLoader.LoadSound(FileSystem.Open(filename));
return soundEngine.AddSoundSourceFromPCMData(data, filename, return soundEngine.AddSoundSourceFromMemory(data, 1, 16, 22050);
new AudioFormat()
{
ChannelCount = 1,
FrameCount = data.Length / 2,
Format = SampleFormat.Signed16Bit,
SampleRate = 22050
});
} }
public static void Initialize() public static void Initialize()
{ {
soundEngine = new ISoundEngine(); soundEngine = new OpenAlSoundEngine();
sounds = new Cache<string, ISoundSource>(LoadSound); sounds = new Cache<string, ISoundSource>(LoadSound);
music = null; music = null;
soundVolume = soundEngine.SoundVolume; soundVolume = soundEngine.Volume;
musicVolume = soundEngine.SoundVolume; musicVolume = soundEngine.Volume;
} }
public static void Play(string name) public static void Play(string name)
{ {
var sound = sounds[name]; var sound = sounds[name];
// todo: positioning // todo: positioning
soundEngine.Play2D(sound, false /* loop */, false, false); soundEngine.Play2D(sound, false);
} }
public static void PlayMusic(string name) public static void PlayMusic(string name)
{ {
var sound = sounds[name]; var sound = sounds[name];
music = soundEngine.Play2D(sound, true /* loop */, false, false); music = soundEngine.Play2D(sound, true);
music.Volume = musicVolume; music.Volume = musicVolume;
} }
public static bool Paused //public static bool Paused
{ //{
get { return paused; } // get { return paused; }
set { paused = value; soundEngine.SetAllSoundsPaused(paused); } // set { paused = value; soundEngine.SetAllSoundsPaused(paused); }
} //}
public static float Volume public static float Volume
{ {
@@ -64,29 +58,30 @@ namespace OpenRa.Game
set set
{ {
soundVolume = value; soundVolume = value;
soundEngine.SoundVolume = value; soundEngine.Volume = value;
} }
} }
public static float MusicVolume public static float MusicVolume
{ {
get { return musicVolume; } get { return musicVolume; }
set { set
{
musicVolume = value; musicVolume = value;
if (music != null) if (music != null)
music.Volume = value; music.Volume = value;
} }
} }
public static void SeekMusic(uint delta) //public static void SeekMusic(uint delta)
{ //{
if (music != null) // if (music != null)
{ // {
music.PlayPosition += delta; // music.PlayPosition += delta;
if (music.PlayPosition < 0 || music.PlayPosition > music.PlayLength) // if (music.PlayPosition < 0 || music.PlayPosition > music.PlayLength)
music.PlayPosition = 0; // music.PlayPosition = 0;
} // }
} //}
public static void PlayVoice(string phrase, Actor voicedUnit) public static void PlayVoice(string phrase, Actor voicedUnit)
{ {
@@ -115,4 +110,91 @@ namespace OpenRa.Game
Play(clip + variant); Play(clip + variant);
} }
} }
interface ISoundEngine
{
ISoundSource AddSoundSourceFromMemory(byte[] data, int channels, int sampleBits, int sampleRate);
ISound Play2D(ISoundSource sound, bool loop);
float Volume { get; set; }
}
interface ISoundSource {}
interface ISound
{
float Volume { get; set; }
}
class OpenAlSoundEngine : ISoundEngine
{
float volume = 1f;
public OpenAlSoundEngine()
{
var str = Alc.alcGetString(IntPtr.Zero, Alc.ALC_DEFAULT_DEVICE_SPECIFIER);
var dev = Alc.alcOpenDevice(str);
if (dev == IntPtr.Zero)
throw new InvalidOperationException("Can't create OpenAL device");
var ctx = Alc.alcCreateContext(dev, (int[]) null);
Alc.alcMakeContextCurrent(ctx);
}
public ISoundSource AddSoundSourceFromMemory(byte[] data, int channels, int sampleBits, int sampleRate)
{
return new OpenAlSoundSource(data, channels, sampleBits, sampleRate);
}
public ISound Play2D(ISoundSource sound, bool loop)
{
return new OpenAlSound((sound as OpenAlSoundSource).buffer, loop);
}
public float Volume
{
get { return volume; }
set { Al.alListenerf(Al.AL_GAIN, volume = value); }
}
}
class OpenAlSoundSource : ISoundSource
{
public readonly int buffer;
static int MakeALFormat(int channels, int bits)
{
if (channels == 1)
return bits == 16 ? Al.AL_FORMAT_MONO16 : Al.AL_FORMAT_MONO8;
else
return bits == 16 ? Al.AL_FORMAT_STEREO16 : Al.AL_FORMAT_STEREO8;
}
public OpenAlSoundSource(byte[] data, int channels, int sampleBits, int sampleRate)
{
Al.alGenBuffers(1, out buffer);
Al.alBufferData(buffer, MakeALFormat(channels, sampleBits), data, data.Length, sampleRate);
}
}
class OpenAlSound : ISound
{
public readonly int source;
float volume = 1f;
public OpenAlSound(int buffer, bool looping)
{
Al.alGenSources(1, out source);
Al.alSourcef(source, Al.AL_PITCH, 1f);
Al.alSourcef(source, Al.AL_GAIN, 1f);
Al.alSource3f(source, Al.AL_POSITION, 0f, 0f, 0f);
Al.alSource3f(source, Al.AL_VELOCITY, 0f, 0f, 0f);
Al.alSourcei(source, Al.AL_BUFFER, buffer);
Al.alSourcei(source, Al.AL_LOOPING, looping ? Al.AL_TRUE : Al.AL_FALSE);
Al.alSourcePlay(source);
}
public float Volume
{
get { return volume; }
set { Al.alSourcef(source, Al.AL_GAIN, volume = value); }
}
}
} }

Binary file not shown.

View File

@@ -1 +0,0 @@
irrKlang library is from http://www.ambiera.com/irrklang/