-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
/
OALSoundBuffer.cs
99 lines (85 loc) · 3.11 KB
/
OALSoundBuffer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
using MonoGame.OpenAL;
namespace Microsoft.Xna.Framework.Audio
{
internal class OALSoundBuffer : IDisposable
{
int openALDataBuffer;
ALFormat openALFormat;
int dataSize;
bool _isDisposed;
public OALSoundBuffer()
{
AL.GenBuffers(1, out openALDataBuffer);
ALHelper.CheckError("Failed to generate OpenAL data buffer.");
}
~OALSoundBuffer()
{
Dispose(false);
}
public int OpenALDataBuffer
{
get
{
return openALDataBuffer;
}
}
public double Duration
{
get;
set;
}
public void BindDataBuffer(byte[] dataBuffer, ALFormat format, int size, int sampleRate, int sampleAlignment = 0)
{
if ((format == ALFormat.MonoMSAdpcm || format == ALFormat.StereoMSAdpcm) && !OpenALSoundController.Instance.SupportsAdpcm)
throw new InvalidOperationException("MS-ADPCM is not supported by this OpenAL driver");
if ((format == ALFormat.MonoIma4 || format == ALFormat.StereoIma4) && !OpenALSoundController.Instance.SupportsIma4)
throw new InvalidOperationException("IMA/ADPCM is not supported by this OpenAL driver");
openALFormat = format;
dataSize = size;
int unpackedSize = 0;
if (sampleAlignment > 0)
{
AL.Bufferi(openALDataBuffer, ALBufferi.UnpackBlockAlignmentSoft, sampleAlignment);
ALHelper.CheckError("Failed to fill buffer.");
}
AL.BufferData(openALDataBuffer, openALFormat, dataBuffer, size, sampleRate);
ALHelper.CheckError("Failed to fill buffer.");
int bits, channels;
Duration = -1;
AL.GetBuffer(openALDataBuffer, ALGetBufferi.Bits, out bits);
ALHelper.CheckError("Failed to get buffer bits");
AL.GetBuffer(openALDataBuffer, ALGetBufferi.Channels, out channels);
ALHelper.CheckError("Failed to get buffer channels");
AL.GetBuffer(openALDataBuffer, ALGetBufferi.Size, out unpackedSize);
ALHelper.CheckError("Failed to get buffer size");
Duration = (float)(unpackedSize / ((bits / 8) * channels)) / (float)sampleRate;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!_isDisposed)
{
if (disposing)
{
// Clean up managed objects
}
// Release unmanaged resources
if (AL.IsBuffer(openALDataBuffer))
{
ALHelper.CheckError("Failed to fetch buffer state.");
AL.DeleteBuffers(1, ref openALDataBuffer);
ALHelper.CheckError("Failed to delete buffer.");
}
_isDisposed = true;
}
}
}
}