1 module prova.attachables.audio.audiosource; 2 3 import derelict.openal.al; 4 import prova.assets; 5 import prova.audio; 6 import prova.core; 7 import prova.entities; 8 import prova.math; 9 10 /// 11 class AudioSource 12 { 13 private uint sourceId; 14 private AudioClip audioClip; 15 private Entity _entity; 16 private bool _looping = false; 17 private float _volume = 1; 18 private float _pitch = 1; 19 20 /// Limited to Ogg files for now 21 this(AudioClip audioClip) 22 { 23 this.audioClip = audioClip; 24 25 alGenSources(1, &sourceId); 26 alSourcei(sourceId, AL_BUFFER, audioClip.bufferId); 27 } 28 29 /// 30 @property Entity entity() 31 { 32 return _entity; 33 } 34 35 /// 36 @property void entity(Entity entity) 37 { 38 _entity = entity; 39 } 40 41 /// 42 @property uint channels() 43 { 44 return audioClip.channels; 45 } 46 47 /// 48 @property float volume() 49 { 50 return _volume; 51 } 52 53 /// 54 @property void volume(float value) 55 { 56 _volume = value; 57 alSourcef(sourceId, AL_GAIN, value); 58 } 59 60 /// 61 @property float pitch() 62 { 63 return _pitch; 64 } 65 66 /// 67 @property void pitch(float value) 68 { 69 _pitch = value; 70 alSourcef(sourceId, AL_PITCH, value); 71 } 72 73 /// 74 @property bool isPlaying() 75 { 76 ALenum status; 77 alGetSourcei(sourceId, AL_SOURCE_STATE, &status); 78 79 return status == AL_PLAYING; 80 } 81 82 /// 83 @property bool looping() 84 { 85 return _looping; 86 } 87 88 /// 89 void play(bool loop = false) 90 { 91 if(isPlaying()) 92 stop(); 93 94 _looping = loop; 95 alSourcei(sourceId, AL_LOOPING, loop); 96 97 alSourceRewind(sourceId); 98 alSourcePlay(sourceId); 99 } 100 101 /// 102 void stop() 103 { 104 alSourceStop(sourceId); 105 } 106 107 /// 108 void pause() 109 { 110 alSourcePause(sourceId); 111 } 112 113 /// 114 void resume() 115 { 116 alSourcePlay(sourceId); 117 } 118 119 package(prova) void update() 120 { 121 if(!entity) 122 return; 123 124 Vector3 position = entity.getWorldPosition(); 125 Vector3 velocity = entity.getWorldRotation() * entity.velocity; 126 127 position /= Audio.scale; 128 velocity /= Audio.scale; 129 130 alSource3f(sourceId, AL_POSITION, position.x, position.y, position.z); 131 alSource3f(sourceId, AL_VELOCITY, velocity.x, velocity.y, velocity.z); 132 } 133 134 ~this() 135 { 136 if(isPlaying) 137 stop(); 138 139 alDeleteSources(1, &sourceId); 140 } 141 }