1 module fmod.fmod; 2 3 public import derelict.fmod.fmod; 4 5 // Wraps SoftwareFormat calls 6 struct SoftwareFormat { 7 int samplerate; 8 int numrawspeakers; 9 FMOD_SPEAKERMODE speakermode; 10 } 11 12 struct SpeakerPosition { 13 FMOD_SPEAKER speaker; 14 float x, y; 15 bool active; 16 } 17 18 struct StreamBufferSize { 19 uint filebuffersize, filebuffersizetype; 20 } 21 22 struct Settings3D { 23 float dopplerscale, distancefactor, rolloffscale; 24 } 25 26 struct SoundDefaults { 27 float frequency; 28 int priority; 29 } 30 31 struct Sound3DDistance { 32 float min, max; 33 } 34 35 struct Sound3DConeSettings { 36 float insideangle, outsideangle, outsidevolume; 37 } 38 39 struct SoundFormat { 40 FMOD_SOUND_TYPE *type; 41 FMOD_SOUND_FORMAT *format; 42 int channels, bits; 43 } 44 45 struct ReverbProperties { 46 int instance; 47 float wet; 48 } 49 50 class FMODException : Exception { 51 FMOD_RESULT result; 52 53 this(FMOD_RESULT result, string msg = null, Throwable next = null) { 54 this.result = result; 55 super(msg, next); 56 } 57 58 this(FMOD_RESULT result, string msg, string file, size_t line, Throwable next = null) { 59 this.result = result; 60 super(msg, file, line, next); 61 } 62 } 63 64 void valid(FMOD_RESULT result, string msg = null) { 65 if (result != FMOD_RESULT.FMOD_OK) { 66 throw new FMODException(result, msg); 67 } 68 } 69 70 void loadFMOD() { 71 DerelictFmod.load(); 72 } 73 74 /* 75 Wraps the FMOD_System C struct 76 */ 77 class System { 78 FMOD_SYSTEM *sys; 79 80 this() { 81 this.sys = new FMOD_SYSTEM; 82 auto res = FMOD_System_Create(&this.sys); 83 valid(res); 84 } 85 86 ~this() { 87 valid(FMOD_System_Release(this.sys)); 88 } 89 90 void setOutput(FMOD_OUTPUTTYPE output) { 91 valid(FMOD_System_SetOutput(this.sys, output)); 92 } 93 94 FMOD_OUTPUTTYPE getOutput() { 95 FMOD_OUTPUTTYPE output; 96 valid(FMOD_System_GetOutput(this.sys, &output)); 97 return output; 98 } 99 100 int getNumDrivers() { 101 int num; 102 valid(FMOD_System_GetNumDrivers(this.sys, &num)); 103 return num; 104 } 105 106 void setDriver(int driver) { 107 valid(FMOD_System_SetDriver(this.sys, driver)); 108 } 109 110 int getDriver() { 111 int driver; 112 valid(FMOD_System_GetDriver(this.sys, &driver)); 113 return driver; 114 } 115 116 void setSoftwareChannels(int num) { 117 valid(FMOD_System_SetSoftwareChannels(this.sys, num)); 118 } 119 120 int getSoftwareChannels() { 121 int num; 122 valid(FMOD_System_GetSoftwareChannels(this.sys, &num)); 123 return num; 124 } 125 126 void setSoftwareFormat(SoftwareFormat *fmt) { 127 valid(FMOD_System_SetSoftwareFormat(this.sys, fmt.samplerate, fmt.speakermode, fmt.numrawspeakers)); 128 } 129 130 SoftwareFormat getSoftwareFormat() { 131 SoftwareFormat fmt; 132 valid(FMOD_System_GetSoftwareFormat(this.sys, &fmt.samplerate, &fmt.speakermode, &fmt.numrawspeakers)); 133 return fmt; 134 } 135 136 void setAdvancedSettings(FMOD_ADVANCEDSETTINGS *settings) { 137 valid(FMOD_System_SetAdvancedSettings(this.sys, settings)); 138 } 139 140 FMOD_ADVANCEDSETTINGS getAdvancedSettings() { 141 FMOD_ADVANCEDSETTINGS settings; 142 valid(FMOD_System_GetAdvancedSettings(this.sys, &settings)); 143 return settings; 144 } 145 146 void init(int maxchannels, uint flags=FMOD_INIT_NORMAL, void *extradriverdata=null) { 147 auto res = FMOD_System_Init(this.sys, maxchannels, flags, extradriverdata); 148 valid(res); 149 } 150 151 void close() { 152 valid(FMOD_System_Close(this.sys)); 153 } 154 155 void update() { 156 valid(FMOD_System_Update(this.sys)); 157 } 158 159 void setSpeakerPosition(SpeakerPosition *pos) { 160 valid(FMOD_System_SetSpeakerPosition(this.sys, pos.speaker, pos.x, pos.y, cast(int)pos.active)); 161 } 162 163 SpeakerPosition getSpeakerPosition() { 164 SpeakerPosition pos; 165 int active; 166 167 valid(FMOD_System_GetSpeakerPosition(this.sys, pos.speaker, &pos.x, &pos.y, &active)); 168 pos.active = cast(bool)active; 169 return pos; 170 } 171 172 void setStreamBufferSize(StreamBufferSize *size) { 173 valid(FMOD_System_SetStreamBufferSize(this.sys, size.filebuffersize, size.filebuffersizetype)); 174 } 175 176 StreamBufferSize getStreamBufferSize() { 177 StreamBufferSize size; 178 valid(FMOD_System_GetStreamBufferSize(this.sys, &size.filebuffersize, &size.filebuffersizetype)); 179 return size; 180 } 181 182 void set3DSettings(Settings3D *settings) { 183 valid(FMOD_System_Set3DSettings(this.sys, settings.dopplerscale, settings.distancefactor, settings.rolloffscale)); 184 } 185 186 Settings3D get3DSettings() { 187 Settings3D settings; 188 valid(FMOD_System_Get3DSettings(this.sys, &settings.dopplerscale, &settings.distancefactor, &settings.rolloffscale)); 189 return settings; 190 } 191 192 void set3DNumListeners(int num) { 193 valid(FMOD_System_Set3DNumListeners(this.sys, num)); 194 } 195 196 int get3DNumListeners() { 197 int num; 198 valid(FMOD_System_Get3DNumListeners(this.sys, &num)); 199 return num; 200 } 201 202 Sound createSound(string name_or_data, uint mode=0, FMOD_CREATESOUNDEXINFO *exinfo=null) { 203 return new Sound(this, name_or_data, mode, exinfo); 204 } 205 } 206 207 class Sound { 208 Channel channel; 209 FMOD_SOUND *sound; 210 211 this(System sys, string name, uint mode, FMOD_CREATESOUNDEXINFO *exinfo) { 212 this.sound = new FMOD_SOUND; 213 auto res1 = FMOD_System_CreateSound(sys.sys, name.ptr, mode, exinfo, &this.sound); 214 valid(res1); 215 auto res2 = FMOD_Sound_SetUserData(this.sound, cast(void*)sys); 216 valid(res2); 217 } 218 219 ~this() { 220 valid(FMOD_Sound_Release(this.sound)); 221 } 222 223 System parent() { 224 System sys; 225 valid(FMOD_Sound_GetUserData(this.sound, cast(void**)sys)); 226 return sys; 227 } 228 229 // Get the system object for this sound 230 FMOD_SYSTEM *system() { 231 FMOD_SYSTEM *sys; 232 valid(FMOD_Sound_GetSystemObject(this.sound, &sys)); 233 return sys; 234 } 235 236 void play(FMOD_CHANNELGROUP *group=null, bool paused=false) { 237 FMOD_CHANNEL *chan; 238 auto res = FMOD_System_PlaySound(this.system, this.sound, group, cast(int)paused, &chan); 239 valid(res); 240 this.channel = new Channel(chan); 241 } 242 243 void setDefaults(SoundDefaults *def) { 244 valid(FMOD_Sound_SetDefaults(this.sound, def.frequency, def.priority)); 245 } 246 247 SoundDefaults getDefaults() { 248 SoundDefaults def; 249 valid(FMOD_Sound_GetDefaults(this.sound, &def.frequency, &def.priority)); 250 return def; 251 } 252 253 void set3DDistance(Sound3DDistance *dist) { 254 valid(FMOD_Sound_Set3DMinMaxDistance(this.sound, dist.min, dist.max)); 255 } 256 257 Sound3DDistance get3DDistance() { 258 Sound3DDistance dist; 259 valid(FMOD_Sound_Get3DMinMaxDistance(this.sound, &dist.min, &dist.max)); 260 return dist; 261 } 262 263 void set3DConeSettings(Sound3DConeSettings *set) { 264 valid(FMOD_Sound_Set3DConeSettings(this.sound, set.insideangle, set.outsideangle, set.outsidevolume)); 265 } 266 267 Sound3DConeSettings get3DConeSettings() { 268 Sound3DConeSettings set; 269 valid(FMOD_Sound_Get3DConeSettings(this.sound, &set.insideangle, &set.outsideangle, &set.outsidevolume)); 270 return set; 271 } 272 273 void set3DCustomRolloff(FMOD_VECTOR[] points) { 274 valid(FMOD_Sound_Set3DCustomRolloff(this.sound, &points[0], cast(int)points.length)); 275 } 276 277 string getName(int length = 64) { 278 char[] str = new char[length]; 279 valid(FMOD_Sound_GetName(this.sound, &str[0], length)); 280 return cast(string)str; 281 } 282 283 // Returns the length in milliseconds 284 uint getLength() { 285 uint length; 286 valid(FMOD_Sound_GetLength(this.sound, &length, FMOD_TIMEUNIT_MS)); 287 return length; 288 } 289 290 SoundFormat getFormat() { 291 SoundFormat fmt; 292 valid(FMOD_Sound_GetFormat(this.sound, fmt.type, fmt.format, &fmt.channels, &fmt.bits)); 293 return fmt; 294 } 295 296 float getMusicSpeed() { 297 float speed; 298 valid(FMOD_Sound_GetMusicSpeed(this.sound, &speed)); 299 return speed; 300 } 301 302 void setMusicSpeed(float speed) { 303 valid(FMOD_Sound_SetMusicSpeed(this.sound, speed)); 304 } 305 306 void setMode(uint mode) { 307 valid(FMOD_Sound_SetMode(this.sound, mode)); 308 } 309 310 uint getMode() { 311 uint mode; 312 valid(FMOD_Sound_GetMode(this.sound, &mode)); 313 return mode; 314 } 315 316 int getLoopCount() { 317 int count; 318 valid(FMOD_Sound_GetLoopCount(this.sound, &count)); 319 return count; 320 } 321 322 void setLoopCount(int count) { 323 valid(FMOD_Sound_SetLoopCount(this.sound, count)); 324 } 325 } 326 327 class Channel { 328 FMOD_CHANNEL *channel; 329 330 this(FMOD_CHANNEL *chan) { 331 this.channel = chan; 332 } 333 334 FMOD_SYSTEM *system() { 335 FMOD_SYSTEM *sys; 336 valid(FMOD_Channel_GetSystemObject(this.channel, &sys)); 337 return sys; 338 } 339 340 void stop() { 341 valid(FMOD_Channel_Stop(this.channel)); 342 } 343 344 void setPaused(bool paused) { 345 valid(FMOD_Channel_SetPaused(this.channel, cast(int)paused)); 346 } 347 348 bool getPaused() { 349 int paused; 350 valid(FMOD_Channel_GetPaused(this.channel, &paused)); 351 return cast(bool)paused; 352 } 353 354 void setVolume(float volume) { 355 valid(FMOD_Channel_SetVolume(this.channel, volume)); 356 } 357 358 float getVolume() { 359 float volume; 360 valid(FMOD_Channel_GetVolume(this.channel, &volume)); 361 return volume; 362 } 363 364 void setVolumeRamp(int ramp) { 365 valid(FMOD_Channel_SetVolumeRamp(this.channel, ramp)); 366 } 367 368 int getVolumeRamp() { 369 int ramp; 370 valid(FMOD_Channel_GetVolumeRamp(this.channel, &ramp)); 371 return ramp; 372 } 373 374 float getAudibility() { 375 float aud; 376 valid(FMOD_Channel_GetAudibility(this.channel, &aud)); 377 return aud; 378 } 379 380 void setPitch(float pitch) { 381 valid(FMOD_Channel_SetPitch(this.channel, pitch)); 382 } 383 384 float getPitch() { 385 float pitch; 386 valid(FMOD_Channel_GetPitch(this.channel, &pitch)); 387 return pitch; 388 } 389 390 void setMute(bool mute) { 391 valid(FMOD_Channel_SetMute(this.channel, cast(int)mute)); 392 } 393 394 bool getMute() { 395 int mute; 396 valid(FMOD_Channel_GetMute(this.channel, &mute)); 397 return cast(bool)mute; 398 } 399 400 float getReverbProperties(int instance) { 401 float wet; 402 valid(FMOD_Channel_GetReverbProperties(this.channel, instance, &wet)); 403 return wet; 404 } 405 406 void setReverbProperties(int instance, float wet) { 407 valid(FMOD_Channel_SetReverbProperties(this.channel, instance, wet)); 408 } 409 410 void setLowPassGain(float gain) { 411 valid(FMOD_Channel_SetLowPassGain(this.channel, gain)); 412 } 413 414 float getLowPassGain() { 415 float gain; 416 valid(FMOD_Channel_GetLowPassGain(this.channel, &gain)); 417 return gain; 418 } 419 } 420 421 unittest { 422 loadFMOD(); 423 System sys = new System(); 424 sys.init(10); 425 delete(sys); 426 } 427