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