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 }