2012-02-12 11:28:59 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using ANX.Framework.Audio;
|
2012-10-04 07:07:18 +00:00
|
|
|
|
using ANX.Framework.NonXNA.Development;
|
2012-02-12 11:28:59 +00:00
|
|
|
|
using ANX.Framework.NonXNA.SoundSystem;
|
2012-08-30 12:05:40 +00:00
|
|
|
|
using OpenTK.Audio.OpenAL;
|
2012-08-29 18:07:54 +00:00
|
|
|
|
using WaveUtils;
|
2012-08-30 12:05:40 +00:00
|
|
|
|
using ALFormat = OpenTK.Audio.OpenAL.ALFormat;
|
2012-08-26 12:53:00 +00:00
|
|
|
|
|
|
|
|
|
// This file is part of the ANX.Framework created by the
|
|
|
|
|
// "ANX.Framework developer group" and released under the Ms-PL license.
|
|
|
|
|
// For details see: http://anxframework.codeplex.com/license
|
2012-02-12 11:28:59 +00:00
|
|
|
|
|
|
|
|
|
namespace ANX.SoundSystem.OpenAL
|
|
|
|
|
{
|
2012-10-04 07:07:18 +00:00
|
|
|
|
[Developer("AstrorEnales")]
|
2012-02-12 11:28:59 +00:00
|
|
|
|
public class OpenALSoundEffect : ISoundEffect
|
|
|
|
|
{
|
|
|
|
|
#region Private
|
2012-08-26 12:53:00 +00:00
|
|
|
|
private WaveInfo waveInfo;
|
|
|
|
|
private TimeSpan duration;
|
2012-10-04 07:07:18 +00:00
|
|
|
|
internal int BufferHandle { get; private set; }
|
2012-02-12 11:28:59 +00:00
|
|
|
|
#endregion
|
|
|
|
|
|
2012-08-26 12:53:00 +00:00
|
|
|
|
#region Public
|
2012-10-04 07:07:18 +00:00
|
|
|
|
public TimeSpan Duration
|
|
|
|
|
{
|
|
|
|
|
get { return duration; }
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
2012-02-12 11:28:59 +00:00
|
|
|
|
|
|
|
|
|
#region Constructor
|
2012-10-04 07:07:18 +00:00
|
|
|
|
internal OpenALSoundEffect(Stream stream)
|
2012-02-12 11:28:59 +00:00
|
|
|
|
{
|
2012-08-29 18:07:54 +00:00
|
|
|
|
CreateFromStream(stream);
|
2012-02-12 11:28:59 +00:00
|
|
|
|
}
|
2012-08-29 13:04:22 +00:00
|
|
|
|
|
2012-10-04 07:07:18 +00:00
|
|
|
|
internal OpenALSoundEffect(byte[] buffer, int offset, int count, int sampleRate, AudioChannels channels,
|
|
|
|
|
int loopStart, int loopLength)
|
2012-08-29 13:04:22 +00:00
|
|
|
|
{
|
2012-10-04 07:07:18 +00:00
|
|
|
|
// TODO: loopStart and loopLength
|
2012-08-29 13:04:22 +00:00
|
|
|
|
|
2012-10-04 07:07:18 +00:00
|
|
|
|
byte[] subBuffer = new byte[count];
|
|
|
|
|
Array.Copy(buffer, offset, subBuffer, 0, count);
|
|
|
|
|
BufferHandle = AL.GenBuffer();
|
2012-08-29 18:07:54 +00:00
|
|
|
|
|
2012-10-04 07:07:18 +00:00
|
|
|
|
// TODO: evaluate if 8bit or 16bit!!
|
|
|
|
|
ALFormat format = channels == AudioChannels.Mono ? ALFormat.Mono8 : ALFormat.Stereo8;
|
|
|
|
|
AL.BufferData(BufferHandle, format, subBuffer, count, sampleRate);
|
|
|
|
|
|
|
|
|
|
float sizeMulBlockAlign = count / ((int)channels * 2f);
|
|
|
|
|
duration = TimeSpan.FromMilliseconds(sizeMulBlockAlign * 1000f / sampleRate);
|
|
|
|
|
|
|
|
|
|
ALError error = AL.GetError();
|
|
|
|
|
if (error != ALError.NoError)
|
|
|
|
|
throw new Exception("OpenAL error " + error + ": " + AL.GetErrorString(error));
|
2012-08-29 18:07:54 +00:00
|
|
|
|
}
|
|
|
|
|
#endregion
|
2012-08-29 13:04:22 +00:00
|
|
|
|
|
2012-08-29 18:07:54 +00:00
|
|
|
|
#region CreateFromStream
|
|
|
|
|
private void CreateFromStream(Stream stream)
|
|
|
|
|
{
|
2012-08-29 13:04:22 +00:00
|
|
|
|
waveInfo = WaveFile.LoadData(stream);
|
2012-08-29 18:07:54 +00:00
|
|
|
|
if (waveInfo.WaveFormat != WaveFormat.PCM)
|
|
|
|
|
{
|
2012-10-04 07:07:18 +00:00
|
|
|
|
var converter = new WaveConverter(waveInfo);
|
2012-08-29 18:07:54 +00:00
|
|
|
|
converter.ConvertToPcm();
|
|
|
|
|
}
|
2012-08-29 13:04:22 +00:00
|
|
|
|
|
2012-08-29 18:07:54 +00:00
|
|
|
|
duration = waveInfo.CalculateDuration();
|
2012-08-29 13:04:22 +00:00
|
|
|
|
|
2012-10-04 07:07:18 +00:00
|
|
|
|
BufferHandle = AL.GenBuffer();
|
|
|
|
|
AL.BufferData(BufferHandle, (ALFormat)waveInfo.ALFormat, waveInfo.Data, waveInfo.Data.Length, waveInfo.SampleRate);
|
2012-08-29 13:04:22 +00:00
|
|
|
|
|
|
|
|
|
ALError error = AL.GetError();
|
|
|
|
|
if (error != ALError.NoError)
|
|
|
|
|
throw new Exception("OpenAL error " + error + ": " + AL.GetErrorString(error));
|
|
|
|
|
}
|
2012-02-12 11:28:59 +00:00
|
|
|
|
#endregion
|
|
|
|
|
|
2012-08-26 12:53:00 +00:00
|
|
|
|
#region Dispose
|
2012-02-12 11:28:59 +00:00
|
|
|
|
public void Dispose()
|
|
|
|
|
{
|
2012-08-26 12:53:00 +00:00
|
|
|
|
waveInfo = null;
|
2012-10-04 07:07:18 +00:00
|
|
|
|
AL.DeleteBuffer(BufferHandle);
|
2012-02-12 11:28:59 +00:00
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
}
|
|
|
|
|
}
|