Panda3D
Loading...
Searching...
No Matches
fmodAudioManager.cxx
Go to the documentation of this file.
1/**
2 * PANDA 3D SOFTWARE
3 * Copyright (c) Carnegie Mellon University. All rights reserved.
4 *
5 * All use of this software is subject to the terms of the revised BSD
6 * license. You should have received a copy of this license along
7 * with this source code in a file named "LICENSE."
8 *
9 * @file fmodAudioManager.cxx
10 * @author cort
11 * @date 2003-01-22
12 * Prior system by: cary
13 * @author Stan Rosenbaum "Staque" - Spring 2006
14 */
15
16#include "pandabase.h"
17#include "config_audio.h"
18#include "config_fmodAudio.h"
19#include "dcast.h"
20
21// Panda headers.
22#include "config_audio.h"
23#include "config_putil.h"
24#include "fmodAudioManager.h"
25#include "fmodAudioSound.h"
26#include "filename.h"
27#include "virtualFileSystem.h"
28#include "reMutexHolder.h"
29
30// FMOD Headers.
31#include <fmod.hpp>
32#include <fmod_errors.h>
33
34#define USER_DSP_MAGIC ((void*)0x7012AB35)
35
36TypeHandle FmodAudioManager::_type_handle;
37
38ReMutex FmodAudioManager::_lock;
39FMOD::System *FmodAudioManager::_system;
40
41pset<FmodAudioManager *> FmodAudioManager::_all_managers;
42
43bool FmodAudioManager::_system_is_valid = false;
44
45PN_stdfloat FmodAudioManager::_doppler_factor = 1;
46PN_stdfloat FmodAudioManager::_distance_factor = 1;
47PN_stdfloat FmodAudioManager::_drop_off_factor = 1;
48
49
50// Central dispatcher for audio errors.
51
52void fmod_audio_errcheck(const char *context, FMOD_RESULT result) {
53 if (result != 0) {
54 audio_error(context << ": " << FMOD_ErrorString(result) );
55 }
56}
57
58/**
59 * Factory Function
60 */
62 audio_debug("Create_FmodAudioManager()");
63 return new FmodAudioManager;
64}
65
66
67/**
68 *
69 */
70FmodAudioManager::
71FmodAudioManager() {
72 ReMutexHolder holder(_lock);
73 FMOD_RESULT result;
74
75 // We need a varible temporary to check the FMOD Version.
76 unsigned int version;
77
78 _all_managers.insert(this);
79
80 // Init 3D attributes
81 _position.x = 0;
82 _position.y = 0;
83 _position.z = 0;
84
85 _velocity.x = 0;
86 _velocity.y = 0;
87 _velocity.z = 0;
88
89 _forward.x = 0;
90 _forward.y = 0;
91 _forward.z = 0;
92
93 _up.x = 0;
94 _up.y = 0;
95 _up.z = 0;
96
97 _active = true;
98
99 _saved_outputtype = FMOD_OUTPUTTYPE_AUTODETECT;
100
101 if (_system == nullptr) {
102 // Create the global FMOD System object. This one object must be shared
103 // by all FmodAudioManagers (this is particularly true on OSX, but the
104 // FMOD documentation is unclear as to whether this is the intended design
105 // on all systems).
106
107 result = FMOD::System_Create(&_system);
108 fmod_audio_errcheck("FMOD::System_Create()", result);
109
110 // Let check the Version of FMOD to make sure the Headers and Libraries
111 // are correct.
112 result = _system->getVersion(&version);
113 fmod_audio_errcheck("_system->getVersion()", result);
114
115 if (version < FMOD_VERSION){
116 audio_error("You are using an old version of FMOD. This program requires:" << FMOD_VERSION);
117 }
118
119 // Set speaker mode.
120 if (fmod_speaker_mode.get_value() == FSM_unspecified) {
121 if (fmod_use_surround_sound) {
122 // fmod-use-surround-sound is the old variable, now replaced by fmod-
123 // speaker-mode. This is for backward compatibility.
124 result = _system->setSpeakerMode(FMOD_SPEAKERMODE_5POINT1);
125 fmod_audio_errcheck("_system->setSpeakerMode()", result);
126 }
127 } else {
128 FMOD_SPEAKERMODE speakerMode;
129 speakerMode = (FMOD_SPEAKERMODE) fmod_speaker_mode.get_value();
130 result = _system->setSpeakerMode(speakerMode);
131 fmod_audio_errcheck("_system->setSpeakerMode()", result);
132 }
133
134 // Now we Initialize the System.
135 int nchan = fmod_number_of_sound_channels;
136 int flags = FMOD_INIT_NORMAL;
137
138 result = _system->init(nchan, flags, 0);
139 if (result == FMOD_ERR_TOOMANYCHANNELS) {
140 fmodAudio_cat.error()
141 << "Value too large for fmod-number-of-sound-channels: " << nchan
142 << "\n";
143 } else {
144 fmod_audio_errcheck("_system->init()", result);
145 }
146
147 _system_is_valid = (result == FMOD_OK);
148
149 if (_system_is_valid) {
150 result = _system->set3DSettings( _doppler_factor, _distance_factor, _drop_off_factor);
151 fmod_audio_errcheck("_system->set3DSettings()", result);
152 }
153 }
154
155 _is_valid = _system_is_valid;
156
157 memset(&_midi_info, 0, sizeof(_midi_info));
158 _midi_info.cbsize = sizeof(_midi_info);
159
160 Filename dls_pathname = get_dls_pathname();
161
162#ifdef IS_OSX
163 // Here's a big kludge. Don't ever let FMOD try to load this OSX-provided
164 // file; it crashes messily if you do.
165 if (dls_pathname == "/System/Library/Components/CoreAudio.component/Contents/Resources/gs_instruments.dls") {
166 dls_pathname = "";
167 }
168#endif // IS_OSX
169
170 if (!dls_pathname.empty()) {
171 _dlsname = dls_pathname.to_os_specific();
172 _midi_info.dlsname = _dlsname.c_str();
173 }
174
175 if (_is_valid) {
176 result = _system->createChannelGroup("UserGroup", &_channelgroup);
177 fmod_audio_errcheck("_system->createChannelGroup()", result);
178 }
179}
180
181/**
182 *
183 */
184FmodAudioManager::
185~FmodAudioManager() {
186 ReMutexHolder holder(_lock);
187 // Be sure to delete associated sounds before deleting the manager!
188 FMOD_RESULT result;
189
190 // Release Sounds Next
191 _all_sounds.clear();
192
193 // Remove me from the managers list.
194 _all_managers.erase(this);
195
196 if (_all_managers.empty()) {
197 result = _system->release();
198 fmod_audio_errcheck("_system->release()", result);
199 _system = nullptr;
200 _system_is_valid = false;
201 }
202}
203
204/**
205 * This just check to make sure the FMOD System is up and running correctly.
206 */
208is_valid() {
209 return _is_valid;
210}
211
212/**
213 * Converts a FilterConfig to an FMOD_DSP
214 */
215FMOD::DSP *FmodAudioManager::
216make_dsp(const FilterProperties::FilterConfig &conf) {
217 ReMutexHolder holder(_lock);
218 FMOD_DSP_TYPE dsptype;
219 FMOD_RESULT result;
220 FMOD::DSP *dsp;
221 switch (conf._type) {
222 case FilterProperties::FT_lowpass: dsptype = FMOD_DSP_TYPE_LOWPASS; break;
223 case FilterProperties::FT_highpass: dsptype = FMOD_DSP_TYPE_HIGHPASS; break;
224 case FilterProperties::FT_echo: dsptype = FMOD_DSP_TYPE_ECHO; break;
225 case FilterProperties::FT_flange: dsptype = FMOD_DSP_TYPE_FLANGE; break;
226 case FilterProperties::FT_distort: dsptype = FMOD_DSP_TYPE_DISTORTION; break;
227 case FilterProperties::FT_normalize: dsptype = FMOD_DSP_TYPE_NORMALIZE; break;
228 case FilterProperties::FT_parameq: dsptype = FMOD_DSP_TYPE_PARAMEQ; break;
229 case FilterProperties::FT_pitchshift: dsptype = FMOD_DSP_TYPE_PITCHSHIFT; break;
230 case FilterProperties::FT_chorus: dsptype = FMOD_DSP_TYPE_CHORUS; break;
231 case FilterProperties::FT_sfxreverb: dsptype = FMOD_DSP_TYPE_SFXREVERB; break;
232 case FilterProperties::FT_compress: dsptype = FMOD_DSP_TYPE_COMPRESSOR; break;
233 default:
234 audio_error("Garbage in DSP configuration data");
235 return nullptr;
236 }
237
238 result = _system->createDSPByType( dsptype, &dsp);
239 if (result != 0) {
240 audio_error("Could not create DSP object");
241 return nullptr;
242 }
243
244 FMOD_RESULT res1 = FMOD_OK;
245 FMOD_RESULT res2 = FMOD_OK;
246 FMOD_RESULT res3 = FMOD_OK;
247 FMOD_RESULT res4 = FMOD_OK;
248 FMOD_RESULT res5 = FMOD_OK;
249 FMOD_RESULT res6 = FMOD_OK;
250 FMOD_RESULT res7 = FMOD_OK;
251 FMOD_RESULT res8 = FMOD_OK;
252 FMOD_RESULT res9 = FMOD_OK;
253 FMOD_RESULT res10 = FMOD_OK;
254 FMOD_RESULT res11 = FMOD_OK;
255 FMOD_RESULT res12 = FMOD_OK;
256 FMOD_RESULT res13 = FMOD_OK;
257 FMOD_RESULT res14 = FMOD_OK;
258
259 switch (conf._type) {
260 case FilterProperties::FT_lowpass:
261 res1 = dsp->setParameter(FMOD_DSP_LOWPASS_CUTOFF, conf._a);
262 res2 = dsp->setParameter(FMOD_DSP_LOWPASS_RESONANCE, conf._b);
263 break;
264 case FilterProperties::FT_highpass:
265 res1 = dsp->setParameter(FMOD_DSP_HIGHPASS_CUTOFF, conf._a);
266 res2 = dsp->setParameter(FMOD_DSP_HIGHPASS_RESONANCE, conf._b);
267 break;
268 case FilterProperties::FT_echo:
269 res1 = dsp->setParameter(FMOD_DSP_ECHO_DRYMIX, conf._a);
270 res2 = dsp->setParameter(FMOD_DSP_ECHO_WETMIX, conf._b);
271 res3 = dsp->setParameter(FMOD_DSP_ECHO_DELAY, conf._c);
272 res4 = dsp->setParameter(FMOD_DSP_ECHO_DECAYRATIO, conf._d);
273 break;
274 case FilterProperties::FT_flange:
275 res1 = dsp->setParameter(FMOD_DSP_FLANGE_DRYMIX, conf._a);
276 res2 = dsp->setParameter(FMOD_DSP_FLANGE_WETMIX, conf._b);
277 res3 = dsp->setParameter(FMOD_DSP_FLANGE_DEPTH, conf._c);
278 res4 = dsp->setParameter(FMOD_DSP_FLANGE_RATE, conf._d);
279 break;
280 case FilterProperties::FT_distort:
281 res1 = dsp->setParameter(FMOD_DSP_DISTORTION_LEVEL, conf._a);
282 break;
283 case FilterProperties::FT_normalize:
284 res1 = dsp->setParameter(FMOD_DSP_NORMALIZE_FADETIME, conf._a);
285 res2 = dsp->setParameter(FMOD_DSP_NORMALIZE_THRESHHOLD,conf._b);
286 res3 = dsp->setParameter(FMOD_DSP_NORMALIZE_MAXAMP, conf._c);
287 break;
288 case FilterProperties::FT_parameq:
289 res1 = dsp->setParameter(FMOD_DSP_PARAMEQ_CENTER, conf._a);
290 res2 = dsp->setParameter(FMOD_DSP_PARAMEQ_BANDWIDTH, conf._b);
291 res3 = dsp->setParameter(FMOD_DSP_PARAMEQ_GAIN, conf._c);
292 break;
293 case FilterProperties::FT_pitchshift:
294 res1 = dsp->setParameter(FMOD_DSP_PITCHSHIFT_PITCH, conf._a);
295 res2 = dsp->setParameter(FMOD_DSP_PITCHSHIFT_FFTSIZE, conf._b);
296 res3 = dsp->setParameter(FMOD_DSP_PITCHSHIFT_OVERLAP, conf._c);
297 break;
298 case FilterProperties::FT_chorus:
299 res1 = dsp->setParameter(FMOD_DSP_CHORUS_DRYMIX, conf._a);
300 res2 = dsp->setParameter(FMOD_DSP_CHORUS_WETMIX1, conf._b);
301 res3 = dsp->setParameter(FMOD_DSP_CHORUS_WETMIX2, conf._c);
302 res4 = dsp->setParameter(FMOD_DSP_CHORUS_WETMIX3, conf._d);
303 res5 = dsp->setParameter(FMOD_DSP_CHORUS_DELAY, conf._e);
304 res6 = dsp->setParameter(FMOD_DSP_CHORUS_RATE, conf._f);
305 res7 = dsp->setParameter(FMOD_DSP_CHORUS_DEPTH, conf._g);
306 break;
307 case FilterProperties::FT_sfxreverb:
308 res1 = dsp->setParameter(FMOD_DSP_SFXREVERB_DRYLEVEL, conf._a);
309 res2 = dsp->setParameter(FMOD_DSP_SFXREVERB_ROOM, conf._b);
310 res3 = dsp->setParameter(FMOD_DSP_SFXREVERB_ROOMHF, conf._c);
311 res4 = dsp->setParameter(FMOD_DSP_SFXREVERB_DECAYTIME,conf._d);
312 res5 = dsp->setParameter(FMOD_DSP_SFXREVERB_DECAYHFRATIO, conf._e);
313 res6 = dsp->setParameter(FMOD_DSP_SFXREVERB_REFLECTIONSLEVEL,conf._f);
314 res7 = dsp->setParameter(FMOD_DSP_SFXREVERB_REFLECTIONSDELAY,conf._g);
315 res8 = dsp->setParameter(FMOD_DSP_SFXREVERB_REVERBLEVEL, conf._h);
316 res9 = dsp->setParameter(FMOD_DSP_SFXREVERB_REVERBDELAY, conf._i);
317 res10 = dsp->setParameter(FMOD_DSP_SFXREVERB_DIFFUSION, conf._j);
318 res11 = dsp->setParameter(FMOD_DSP_SFXREVERB_DENSITY, conf._k);
319 res12 = dsp->setParameter(FMOD_DSP_SFXREVERB_HFREFERENCE, conf._l);
320 res13 = dsp->setParameter(FMOD_DSP_SFXREVERB_ROOMLF, conf._m);
321 res14 = dsp->setParameter(FMOD_DSP_SFXREVERB_LFREFERENCE, conf._n);
322 break;
323 case FilterProperties::FT_compress:
324 res1 = dsp->setParameter(FMOD_DSP_COMPRESSOR_THRESHOLD, conf._a);
325 res2 = dsp->setParameter(FMOD_DSP_COMPRESSOR_ATTACK, conf._b);
326 res3 = dsp->setParameter(FMOD_DSP_COMPRESSOR_RELEASE, conf._c);
327 res4 = dsp->setParameter(FMOD_DSP_COMPRESSOR_GAINMAKEUP,conf._d);
328 break;
329 }
330
331 if ((res1!=FMOD_OK)||(res2!=FMOD_OK)||(res3!=FMOD_OK)||(res4!=FMOD_OK)||
332 (res5!=FMOD_OK)||(res6!=FMOD_OK)||(res7!=FMOD_OK)||(res8!=FMOD_OK)||
333 (res9!=FMOD_OK)||(res10!=FMOD_OK)||(res11!=FMOD_OK)||(res12!=FMOD_OK)||
334 (res13!=FMOD_OK)||(res14!=FMOD_OK)) {
335 audio_error("Could not configure DSP");
336 dsp->release();
337 return nullptr;
338 }
339
340 dsp->setUserData(USER_DSP_MAGIC);
341
342 return dsp;
343}
344
345/**
346 * Alters a DSP chain to make it match the specified configuration.
347 *
348 * This is an inadequate implementation - it just clears the whole DSP chain
349 * and rebuilds it from scratch. A better implementation would compare the
350 * existing DSP chain to the desired one, and make incremental changes. This
351 * would prevent a "pop" sound when the changes are made.
352 */
353void FmodAudioManager::
354update_dsp_chain(FMOD::DSP *head, FilterProperties *config) {
355 ReMutexHolder holder(_lock);
356 const FilterProperties::ConfigVector &conf = config->get_config();
357 FMOD_RESULT result;
358
359 while (1) {
360 int numinputs;
361 result = head->getNumInputs(&numinputs);
362 fmod_audio_errcheck("head->getNumInputs()", result);
363 if (numinputs != 1) {
364 break;
365 }
366 FMOD::DSP *prev;
367 result = head->getInput(0, &prev, nullptr);
368 fmod_audio_errcheck("head->getInput()", result);
369 void *userdata;
370 result = prev->getUserData(&userdata);
371 fmod_audio_errcheck("prev->getUserData()", result);
372 if (userdata != USER_DSP_MAGIC) {
373 break;
374 }
375 result = prev->remove();
376 fmod_audio_errcheck("prev->remove()", result);
377 result = prev->release();
378 fmod_audio_errcheck("prev->release()", result);
379 }
380
381 for (int i=0; i<(int)(conf.size()); i++) {
382 FMOD::DSP *dsp = make_dsp(conf[i]);
383 result = _channelgroup->addDSP(dsp, nullptr);
384 fmod_audio_errcheck("_channelgroup->addDSP()", result);
385 }
386}
387
388/**
389 * Configure the global DSP filter chain.
390 *
391 * FMOD has a relatively powerful DSP implementation. It is likely that most
392 * configurations will be supported.
393 */
394bool FmodAudioManager::
395configure_filters(FilterProperties *config) {
396 ReMutexHolder holder(_lock);
397 FMOD_RESULT result;
398 FMOD::DSP *head;
399 result = _channelgroup->getDSPHead(&head);
400 if (result != 0) {
401 audio_error("Getting DSP head: " << FMOD_ErrorString(result) );
402 return false;
403 }
404 update_dsp_chain(head, config);
405 return true;
406}
407
408/**
409 * This is what creates a sound instance.
410 */
411PT(AudioSound) FmodAudioManager::
412get_sound(const Filename &file_name, bool positional, int) {
413 ReMutexHolder holder(_lock);
414 // Needed so People use Panda's Generic UNIX Style Paths for Filename.
415 // path.to_os_specific() converts it back to the proper OS version later on.
416
417 Filename path = file_name;
418
420 vfs->resolve_filename(path, get_model_path());
421
422 // Locate the file on disk.
423 path.set_binary();
424 PT(VirtualFile) file = vfs->get_file(path);
425 if (file != nullptr) {
426 // Build a new AudioSound from the audio data.
427 PT(FmodAudioSound) sound = new FmodAudioSound(this, file, positional);
428
429 _all_sounds.insert(sound);
430 return sound;
431 } else {
432 audio_error("createSound(" << path << "): File not found.");
433 return get_null_sound();
434 }
435}
436
437/**
438 * This is what creates a sound instance.
439 */
440PT(AudioSound) FmodAudioManager::
441get_sound(MovieAudio *source, bool positional, int) {
442 nassert_raise("FMOD audio manager does not support MovieAudio sources");
443 return nullptr;
444}
445
446/**
447 * This is to query if you are using a MultiChannel Setup.
448 */
451 ReMutexHolder holder(_lock);
452 FMOD_RESULT result;
453 FMOD_SPEAKERMODE speakerMode;
454 int returnMode;
455
456 result = _system->getSpeakerMode( &speakerMode );
457 fmod_audio_errcheck("_system->getSpeakerMode()", result);
458
459 switch (speakerMode) {
460 case FMOD_SPEAKERMODE_RAW:
461 returnMode = 0;
462 break;
463 case FMOD_SPEAKERMODE_MONO:
464 returnMode = 1;
465 break;
466 case FMOD_SPEAKERMODE_STEREO:
467 returnMode = 2;
468 break;
469 case FMOD_SPEAKERMODE_QUAD:
470 returnMode = 3;
471 break;
472 case FMOD_SPEAKERMODE_SURROUND:
473 returnMode = 4;
474 break;
475 case FMOD_SPEAKERMODE_5POINT1:
476 returnMode = 5;
477 break;
478 case FMOD_SPEAKERMODE_7POINT1:
479 returnMode = 6;
480 break;
481 case FMOD_SPEAKERMODE_MAX:
482 returnMode = 7;
483 break;
484 default:
485 returnMode = -1;
486 }
487
488 return returnMode;
489}
490
491/**
492 * This is to set up FMOD to use a MultiChannel Setup. This method is pretty
493 * much useless. To set a speaker setup in FMOD for Surround Sound, stereo,
494 * or whatever you have to set the SpeakerMode BEFORE you Initialize FMOD.
495 * Since Panda Inits the FmodAudioManager right when you Start it up, you are
496 * never given an oppertunity to call this function. That is why I stuck a
497 * BOOL in the CONFIG.PRC file, whichs lets you flag if you want to use a
498 * Multichannel or not. That will set the speaker setup when an instance of
499 * this class is constructed. Still I put this here as a measure of good
500 * faith, since you can query the speaker setup after everything in Init.
501 * Also, maybe someone will completely hack Panda someday, in which one can
502 * init or re-init the AudioManagers after Panda is running.
503 */
505set_speaker_setup(AudioManager::SpeakerModeCategory cat) {
506 ReMutexHolder holder(_lock);
507 FMOD_RESULT result;
508 FMOD_SPEAKERMODE speakerModeType = (FMOD_SPEAKERMODE)cat;
509 result = _system->setSpeakerMode( speakerModeType);
510 fmod_audio_errcheck("_system->setSpeakerMode()", result);
511}
512
513/**
514 * Sets the volume of the AudioManager. It is not an override, but a
515 * multiplier.
516 */
518set_volume(PN_stdfloat volume) {
519 ReMutexHolder holder(_lock);
520 FMOD_RESULT result;
521 result = _channelgroup->setVolume(volume);
522 fmod_audio_errcheck("_channelgroup->setVolume()", result);
523}
524
525/**
526 * Returns the AudioManager's volume.
527 */
529get_volume() const {
530 ReMutexHolder holder(_lock);
531 float volume;
532 FMOD_RESULT result;
533 result = _channelgroup->getVolume(&volume);
534 fmod_audio_errcheck("_channelgroup->getVolume()", result);
535 return (PN_stdfloat)volume;
536}
537
538/**
539 * Changes output mode to write all audio to a wav file.
540 */
542set_wavwriter(bool outputwav) {
543 ReMutexHolder holder(_lock);
544 if (outputwav) {
545 _system->getOutput(&_saved_outputtype);
546 _system->setOutput(FMOD_OUTPUTTYPE_WAVWRITER);
547 }
548 else {
549 _system->setOutput(_saved_outputtype);
550 }
551}
552
553
554/**
555 * Turn on/off Warning: not implemented.
556 */
558set_active(bool active) {
559 ReMutexHolder holder(_lock);
560 if (_active != active) {
561 _active = active;
562
563 // Tell our AudioSounds to adjust:
564 for (SoundSet::iterator i = _all_sounds.begin();
565 i != _all_sounds.end();
566 ++i) {
567 (*i)->set_active(_active);
568 }
569 }
570}
571
572/**
573 *
574 */
575bool FmodAudioManager::
576get_active() const {
577 return _active;
578}
579
580/**
581 * Stop playback on all sounds managed by this manager.
582 */
585 ReMutexHolder holder(_lock);
586 // We have to walk through this list with some care, since stopping a sound
587 // may also remove it from the set (if there are no other references to the
588 // sound).
589 SoundSet::iterator i;
590 i = _all_sounds.begin();
591 while (i != _all_sounds.end()) {
592 SoundSet::iterator next = i;
593 ++next;
594
595 (*i)->stop();
596 i = next;
597 }
598}
599
600/**
601 * Perform all per-frame update functions.
602 */
604update() {
605 ReMutexHolder holder(_lock);
606 _system->update();
607}
608
609/**
610 * Set position of the "ear" that picks up 3d sounds NOW LISTEN UP!!! THIS IS
611 * IMPORTANT! Both Panda3D and FMOD use a left handed coordinate system. But
612 * there is a major difference! In Panda3D the Y-Axis is going into the
613 * Screen and the Z-Axis is going up. In FMOD the Y-Axis is going up and the
614 * Z-Axis is going into the screen. The solution is simple, we just flip the
615 * Y and Z axis, as we move coordinates from Panda to FMOD and back. What
616 * does did mean to average Panda user? Nothing, they shouldn't notice
617 * anyway. But if you decide to do any 3D audio work in here you have to keep
618 * it in mind. I told you, so you can't say I didn't.
619 */
621audio_3d_set_listener_attributes(PN_stdfloat px, PN_stdfloat py, PN_stdfloat pz, PN_stdfloat vx, PN_stdfloat vy, PN_stdfloat vz, PN_stdfloat fx, PN_stdfloat fy, PN_stdfloat fz, PN_stdfloat ux, PN_stdfloat uy, PN_stdfloat uz) {
622 ReMutexHolder holder(_lock);
623 audio_debug("FmodAudioManager::audio_3d_set_listener_attributes()");
624
625 FMOD_RESULT result;
626
627 _position.x = px;
628 _position.y = pz;
629 _position.z = py;
630
631 _velocity.x = vx;
632 _velocity.y = vz;
633 _velocity.z = vy;
634
635 _forward.x = fx;
636 _forward.y = fz;
637 _forward.z = fy;
638
639 _up.x = ux;
640 _up.y = uz;
641 _up.z = uy;
642
643 result = _system->set3DListenerAttributes( 0, &_position, &_velocity, &_forward, &_up);
644 fmod_audio_errcheck("_system->set3DListenerAttributes()", result);
645
646}
647
648/**
649 * Get position of the "ear" that picks up 3d sounds
650 */
652audio_3d_get_listener_attributes(PN_stdfloat *px, PN_stdfloat *py, PN_stdfloat *pz, PN_stdfloat *vx, PN_stdfloat *vy, PN_stdfloat *vz, PN_stdfloat *fx, PN_stdfloat *fy, PN_stdfloat *fz, PN_stdfloat *ux, PN_stdfloat *uy, PN_stdfloat *uz) {
653 audio_error("audio3dGetListenerAttributes: currently unimplemented. Get the attributes of the attached object");
654
655}
656
657
658/**
659 * Set units per meter (Fmod uses meters internally for its sound-
660 * spacialization calculations)
661 */
663audio_3d_set_distance_factor(PN_stdfloat factor) {
664 ReMutexHolder holder(_lock);
665 audio_debug( "FmodAudioManager::audio_3d_set_distance_factor( factor= " << factor << ")" );
666
667 FMOD_RESULT result;
668
669 _distance_factor = factor;
670
671 result = _system->set3DSettings( _doppler_factor, _distance_factor, _drop_off_factor);
672 fmod_audio_errcheck("_system->set3DSettings()", result);
673
674
675}
676
677/**
678 * Gets units per meter (Fmod uses meters internally for its sound-
679 * spacialization calculations)
680 */
683 audio_debug("FmodAudioManager::audio_3d_get_distance_factor()");
684
685 return _distance_factor;
686}
687
688/**
689 * Exaggerates or diminishes the Doppler effect. Defaults to 1.0
690 */
692audio_3d_set_doppler_factor(PN_stdfloat factor) {
693 ReMutexHolder holder(_lock);
694 audio_debug("FmodAudioManager::audio_3d_set_doppler_factor(factor="<<factor<<")");
695
696 FMOD_RESULT result;
697
698 _doppler_factor = factor;
699
700 result = _system->set3DSettings( _doppler_factor, _distance_factor, _drop_off_factor);
701 fmod_audio_errcheck("_system->set3DSettings()", result);
702
703}
704
705/**
706 *
707 */
708PN_stdfloat FmodAudioManager::
709audio_3d_get_doppler_factor() const {
710 audio_debug("FmodAudioManager::audio_3d_get_doppler_factor()");
711
712 return _doppler_factor;
713}
714
715/**
716 * Control the effect distance has on audability. Defaults to 1.0
717 */
719audio_3d_set_drop_off_factor(PN_stdfloat factor) {
720 ReMutexHolder holder(_lock);
721 audio_debug("FmodAudioManager::audio_3d_set_drop_off_factor("<<factor<<")");
722
723 FMOD_RESULT result;
724
725 _drop_off_factor = factor;
726
727 result = _system->set3DSettings( _doppler_factor, _distance_factor, _drop_off_factor);
728 fmod_audio_errcheck("_system->set3DSettings()", result);
729
730}
731
732/**
733 *
734 */
735PN_stdfloat FmodAudioManager::
736audio_3d_get_drop_off_factor() const {
737 ReMutexHolder holder(_lock);
738 audio_debug("FmodAudioManager::audio_3d_get_drop_off_factor()");
739
740 return _drop_off_factor;
741
742}
743
744
745
746/**
747 * NOT USED FOR FMOD-EX!!!
748 */
750set_concurrent_sound_limit(unsigned int limit) {
751
752}
753
754/**
755 * NOT USED FOR FMOD-EX!!!
756 */
759 return 1000000;
760}
761
762/**
763 * NOT USED FOR FMOD-EX!!!
764 */
766reduce_sounds_playing_to(unsigned int count) {
767
768}
769
770
771/**
772 * NOT USED FOR FMOD-EX!!! Clears a sound out of the sound cache.
773 */
775uncache_sound(const Filename &file_name) {
776 audio_debug("FmodAudioManager::uncache_sound(\""<<file_name<<"\")");
777
778}
779
780
781/**
782 * NOT USED FOR FMOD-EX!!! Clear out the sound cache.
783 */
785clear_cache() {
786 audio_debug("FmodAudioManager::clear_cache()");
787
788}
789
790/**
791 * NOT USED FOR FMOD-EX!!! Set the number of sounds that the cache can hold.
792 */
794set_cache_limit(unsigned int count) {
795 audio_debug("FmodAudioManager::set_cache_limit(count="<<count<<")");
796
797}
798
799/**
800 * NOT USED FOR FMOD-EX!!! Gets the number of sounds that the cache can hold.
801 */
803get_cache_limit() const {
804 audio_debug("FmodAudioManager::get_cache_limit() returning ");
805 // return _cache_limit;
806 return 0;
807}
get_dls_pathname
Returns the full pathname to the DLS file, as specified by the Config.prc file, or the default for th...
The name of a file, such as a texture file or an Egg file.
Definition filename.h:44
std::string to_os_specific() const
Converts the filename from our generic Unix-like convention (forward slashes starting with the root a...
void set_binary()
Indicates that the filename represents a binary file.
Definition filename.I:414
Stores a configuration for a set of audio DSP filters.
const ConfigVector & get_config()
Intended for use by AudioManager and AudioSound implementations: allows access to the config vector.
virtual void set_active(bool)
Turn on/off Warning: not implemented.
virtual void audio_3d_set_distance_factor(PN_stdfloat factor)
Set units per meter (Fmod uses meters internally for its sound- spacialization calculations)
virtual int get_speaker_setup()
This is to query if you are using a MultiChannel Setup.
virtual void audio_3d_set_drop_off_factor(PN_stdfloat factor)
Control the effect distance has on audability.
virtual void clear_cache()
NOT USED FOR FMOD-EX!!! Clear out the sound cache.
virtual void reduce_sounds_playing_to(unsigned int count)
NOT USED FOR FMOD-EX!!!
virtual void update()
Perform all per-frame update functions.
virtual unsigned int get_cache_limit() const
NOT USED FOR FMOD-EX!!! Gets the number of sounds that the cache can hold.
virtual void set_cache_limit(unsigned int count)
NOT USED FOR FMOD-EX!!! Set the number of sounds that the cache can hold.
virtual PN_stdfloat audio_3d_get_distance_factor() const
Gets units per meter (Fmod uses meters internally for its sound- spacialization calculations)
virtual bool is_valid()
This just check to make sure the FMOD System is up and running correctly.
virtual void audio_3d_set_listener_attributes(PN_stdfloat px, PN_stdfloat py, PN_stdfloat pz, PN_stdfloat vx, PN_stdfloat xy, PN_stdfloat xz, PN_stdfloat fx, PN_stdfloat fy, PN_stdfloat fz, PN_stdfloat ux, PN_stdfloat uy, PN_stdfloat uz)
Set position of the "ear" that picks up 3d sounds NOW LISTEN UP!!! THIS IS IMPORTANT!...
virtual void set_volume(PN_stdfloat)
Sets the volume of the AudioManager.
virtual unsigned int get_concurrent_sound_limit() const
NOT USED FOR FMOD-EX!!!
virtual void set_speaker_setup(SpeakerModeCategory cat)
This is to set up FMOD to use a MultiChannel Setup.
virtual void audio_3d_set_doppler_factor(PN_stdfloat factor)
Exaggerates or diminishes the Doppler effect.
virtual void stop_all_sounds()
Stop playback on all sounds managed by this manager.
virtual void set_wavwriter(bool)
Changes output mode to write all audio to a wav file.
virtual void set_concurrent_sound_limit(unsigned int limit=0)
NOT USED FOR FMOD-EX!!!
virtual void uncache_sound(const Filename &)
NOT USED FOR FMOD-EX!!! Clears a sound out of the sound cache.
virtual PN_stdfloat get_volume() const
Returns the AudioManager's volume.
virtual void audio_3d_get_listener_attributes(PN_stdfloat *px, PN_stdfloat *py, PN_stdfloat *pz, PN_stdfloat *vx, PN_stdfloat *vy, PN_stdfloat *vz, PN_stdfloat *fx, PN_stdfloat *fy, PN_stdfloat *fz, PN_stdfloat *ux, PN_stdfloat *uy, PN_stdfloat *uz)
Get position of the "ear" that picks up 3d sounds.
A MovieAudio is actually any source that provides a sequence of audio samples.
Definition movieAudio.h:44
Similar to MutexHolder, but for a reentrant mutex.
A reentrant mutex.
Definition reMutex.h:34
TypeHandle is the identifier used to differentiate C++ class types.
Definition typeHandle.h:81
A hierarchy of directories and files that appears to be one continuous file system,...
bool resolve_filename(Filename &filename, const DSearchPath &searchpath, const std::string &default_extension=std::string()) const
Searches the given search path for the filename.
PointerTo< VirtualFile > get_file(const Filename &filename, bool status_only=false) const
Looks up the file by the indicated name in the file system.
static VirtualFileSystem * get_global_ptr()
Returns the default global VirtualFileSystem.
The abstract base class for a file or directory within the VirtualFileSystem.
Definition virtualFile.h:35
This is our own Panda specialization on the default STL set.
Definition pset.h:49
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
AudioManager * Create_FmodAudioManager()
Factory Function.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.