1 /**
2  * Defines audio related classes, such as the listener and emitter
3  */
4 module dash.components.audio;
5 import dash.core.properties, dash.components, dash.utility, dash.utility.bindings.soloud;
6 import std..string;
7 
8 /**
9  * Listener object that hears sounds and sends them to the audio output device
10  * (usually attaced to the camera)
11  */
12 class Listener : ComponentReg!Listener
13 {
14 private:
15 
16 public:
17     /**
18      * Create a listener object 
19      */
20     this()
21     {
22         // Constructor code
23     }
24 
25     override void update()
26     {
27         Audio.soloud.update3dAudio();
28         Audio.soloud.set3dListenerAt(owner.transform.position.x,
29                                      owner.transform.position.y,
30                                      owner.transform.position.z);
31     }
32 }
33 
34 /**
35  * Emitter object that plays sounds that listeners can hear
36  */
37 class Emitter : ComponentReg!Emitter
38 {
39 private:
40     Modplug toPlay;
41     uint[] handles;
42 public:
43     /**
44      * Create an emmiter object
45      */
46     this()
47     {
48         // Constructor Code
49     }
50 
51     override void initialize() {
52         super.initialize;
53         toPlay = Modplug.create();
54     }
55 
56     // call:
57     // emmiter.play( filename );
58     void play( string soundName )
59     {
60         // Load in the sound
61         toPlay.load( Audio.sounds[soundName].toStringz() );
62 
63         // play the sound from the location of the parent object
64         Audio.soloud.play3d(toPlay,
65                             owner.transform.position.x,
66                             owner.transform.position.y,
67                             owner.transform.position.z);
68     }
69 
70 
71     /**
72      * Plays a sound that will follow the emitter for however long you set the length to be.
73      */
74     void playFollow( string soundName ) {
75         // Load in the sound
76         toPlay.load( Audio.sounds[soundName].toStringz() );
77 
78         // play the sound from the location of the parent object
79         // and set the sound to move with the emitter
80         handles ~= Audio.soloud.play3d( toPlay,
81                                         owner.transform.position.x,
82                                         owner.transform.position.y,
83                                         owner.transform.position.z );
84 
85     }
86 
87     override void update()
88     {
89         foreach_reverse( i, handle; handles )
90         {
91             if( !Audio.soloud.isValidVoiceHandle( handle ) )
92             {
93                 auto end = handles[i+1..$];
94                 handles = handles[0..i];
95                 handles ~= end;
96             } else {
97                 Audio.soloud.set3dSourcePosition( handle,
98                                                   owner.transform.position.x,
99                                                   owner.transform.position.y,
100                                                   owner.transform.position.z );
101             }
102         }
103     }
104 
105 
106     
107     void playFollow( string soundName, float soundLength )
108     {
109 
110     }
111 }
112 
113 /**
114  * TODO
115  * implement sound struct
116 struct Sound
117 {
118     Wav soundfile;
119 }
120  */
121  
122 final abstract class Audio
123 {
124 static:
125 //private:
126     Soloud soloud;
127 
128 public:
129     string[string] sounds;
130 
131     void initialize()
132     {
133         soloud = Soloud.create();
134         soloud.init();
135 
136         foreach( file; scanDirectory( Resources.Audio ) )
137         {
138             sounds[file.baseFileName] = file.relativePath;
139         }
140     }
141 
142     void shutdown()
143     {
144         soloud.deinit();
145         soloud.destroy();
146     }
147 }