1 module polyplex.core.audio.buffer;
2 import polyplex.core.audio;
3 import ppc.audio;
4 import derelict.openal;
5 
6 import std.stdio;
7 
8 public enum AudioRenderFormats : int {
9 	/**
10 		Auto detect (only available for PPC Audio streams)
11 	*/
12 	Auto = 0,
13 	Mono8 = AL_FORMAT_MONO8,
14 	Mono16 = AL_FORMAT_MONO16,
15 	MonoFloat = AL_FORMAT_MONO_FLOAT32,
16 
17 	Stereo8 = AL_FORMAT_STEREO8,
18 	Stereo16 = AL_FORMAT_STEREO16,
19 	StereoFloat = AL_FORMAT_STEREO_FLOAT32,
20 }
21 
22 public struct RawBuffer {
23 	public ubyte[] Data;
24 	public int SampleRate;
25 	public int Length() { return cast(int)Data.length; }
26 }
27 
28 public class ALBuffer {
29 	private ALuint buff;
30 
31 	/// The audio device hosting this buffer.
32 	public AudioDevice HostDevice;
33 	public ALuint ALBuff() { return buff; }
34 
35 	this(Audio aud, AudioRenderFormats format = AudioRenderFormats.Auto) {
36 		//Clear any present errors.
37 		alGetError();
38 		
39 		// Generate buffer.
40 		alGenBuffers(1, &buff);
41 
42 		AudioRenderFormats f_format = format;
43 
44 		// Buffer data from audio source.
45 		if (format == AudioRenderFormats.Auto) {
46 			if (aud.Channels == 1) f_format = AudioRenderFormats.Mono16;
47 			else if (aud.Channels == 2) f_format = AudioRenderFormats.Stereo16;
48 			else throw new Exception("Unsupported amount of channels!");
49 		}
50 
51 		alBufferData(this.buff, f_format, aud.Samples.ptr, cast(int)aud.Length, cast(int)aud.SampleRate);
52 	}
53 
54 	this(RawBuffer buff, AudioRenderFormats format) {
55 		if (format == AudioRenderFormats.Auto) throw new Exception("Auto detection not available for RawBuffers.");
56 
57 		//Clear any present errors.
58 		alGetError();
59 		
60 		// Generate buffer.
61 		alGenBuffers(1, &this.buff);
62 		alBufferData(this.buff, format, buff.Data.ptr, buff.Length, buff.SampleRate);
63 	}
64 
65 	~this() {
66 		alDeleteBuffers(1, &this.buff);
67 	}
68 }