00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "pandabase.h"
00020 #include "dcast.h"
00021
00022 #ifdef HAVE_FMODEX //[
00023
00024
00025 #include "config_audio.h"
00026 #include "fmodAudioSound.h"
00027 #include "string_utils.h"
00028 #include "subfileInfo.h"
00029 #include "reMutexHolder.h"
00030
00031 TypeHandle FmodAudioSound::_type_handle;
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 FmodAudioSound::
00042 FmodAudioSound(AudioManager *manager, Filename file_name, bool positional) {
00043 ReMutexHolder holder(FmodAudioManager::_lock);
00044 audio_debug("FmodAudioSound::FmodAudioSound() Creating new sound, filename: " << file_name );
00045
00046 _active = manager->get_active();
00047 _paused = false;
00048 _start_time = 0.0;
00049
00050
00051 FMOD_RESULT result;
00052
00053
00054 _location.x = 0;
00055 _location.y = 0;
00056 _location.z = 0;
00057
00058 _velocity.x = 0;
00059 _velocity.y = 0;
00060 _velocity.z = 0;
00061
00062
00063 _playrate = 1;
00064
00065
00066 for (int i=0; i<AudioManager::SPK_COUNT; i++) {
00067 _mix[i] = 1.0;
00068 }
00069
00070
00071 FmodAudioManager *fmanager;
00072 DCAST_INTO_V(fmanager, manager);
00073 _manager = fmanager;
00074
00075 _channel = 0;
00076 _file_name = file_name;
00077 _file_name.set_binary();
00078
00079
00080 result = _manager->_system->getSpeakerMode( &_speakermode );
00081 fmod_audio_errcheck("_system->getSpeakerMode()", result);
00082
00083 VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
00084 PT(VirtualFile) file = vfs->get_file(_file_name);
00085 if (file == (VirtualFile *)NULL) {
00086
00087
00088 result = FMOD_ERR_FILE_NOTFOUND;
00089
00090 } else {
00091 bool preload = (fmod_audio_preload_threshold < 0) || (file->get_file_size() < fmod_audio_preload_threshold);
00092 int flags = FMOD_SOFTWARE;
00093 flags |= positional ? FMOD_3D : FMOD_2D;
00094
00095 FMOD_CREATESOUNDEXINFO sound_info;
00096 memset(&sound_info, 0, sizeof(sound_info));
00097 sound_info.cbsize = sizeof(sound_info);
00098
00099 string ext = downcase(_file_name.get_extension());
00100 if (ext == "mid") {
00101
00102 memcpy(&sound_info, &_manager->_midi_info, sizeof(sound_info));
00103 if (sound_info.dlsname != NULL) {
00104 audio_debug("Using DLS file " << sound_info.dlsname);
00105 }
00106 }
00107
00108 const char *name_or_data = _file_name.c_str();
00109 string os_filename;
00110
00111 pvector<unsigned char> mem_buffer;
00112 SubfileInfo info;
00113 if (preload) {
00114
00115
00116
00117 file->read_file(mem_buffer, true);
00118 sound_info.length = mem_buffer.size();
00119 if (mem_buffer.size() != 0) {
00120 name_or_data = (const char *)&mem_buffer[0];
00121 }
00122 flags |= FMOD_OPENMEMORY;
00123 if (fmodAudio_cat.is_debug()) {
00124 fmodAudio_cat.debug()
00125 << "Reading " << _file_name << " into memory (" << sound_info.length
00126 << " bytes)\n";
00127 }
00128
00129 } else if (file->get_system_info(info)) {
00130
00131
00132
00133
00134
00135 os_filename = info.get_filename().to_os_specific();
00136 name_or_data = os_filename.c_str();
00137 sound_info.fileoffset = (unsigned int)info.get_start();
00138 sound_info.length = (unsigned int)info.get_size();
00139 flags |= FMOD_CREATESTREAM;
00140 if (fmodAudio_cat.is_debug()) {
00141 fmodAudio_cat.debug()
00142 << "Streaming " << _file_name << " from disk (" << name_or_data
00143 << ", " << sound_info.fileoffset << ", " << sound_info.length << ")\n";
00144 }
00145
00146 } else {
00147 #if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS)
00148
00149
00150 name_or_data = (const char *)file.p();
00151 sound_info.length = (unsigned int)info.get_size();
00152 sound_info.useropen = open_callback;
00153 sound_info.userclose = close_callback;
00154 sound_info.userread = read_callback;
00155 sound_info.userseek = seek_callback;
00156 flags |= FMOD_CREATESTREAM;
00157 if (fmodAudio_cat.is_debug()) {
00158 fmodAudio_cat.debug()
00159 << "Streaming " << _file_name << " from disk using callbacks\n";
00160 }
00161
00162 #else // HAVE_THREADS && !SIMPLE_THREADS
00163
00164 name_or_data = "";
00165
00166 fmodAudio_cat.warning()
00167 << "Cannot stream " << _file_name << "; file is not literally on disk.\n";
00168 #endif
00169 }
00170
00171 result =
00172 _manager->_system->createSound(name_or_data, flags, &sound_info, &_sound);
00173 }
00174
00175 if (result != FMOD_OK) {
00176 audio_error("createSound(" << _file_name << "): " << FMOD_ErrorString(result));
00177
00178
00179
00180 FMOD_CREATESOUNDEXINFO sound_info;
00181 memset(&sound_info, 0, sizeof(sound_info));
00182 char blank_data[100];
00183 memset(blank_data, 0, sizeof(blank_data));
00184 sound_info.cbsize = sizeof(sound_info);
00185 sound_info.length = sizeof(blank_data);
00186 sound_info.numchannels = 1;
00187 sound_info.defaultfrequency = 8000;
00188 sound_info.format = FMOD_SOUND_FORMAT_PCM16;
00189 int flags = FMOD_SOFTWARE | FMOD_OPENMEMORY | FMOD_OPENRAW;
00190
00191 result = _manager->_system->createSound( blank_data, flags, &sound_info, &_sound);
00192 fmod_audio_errcheck("createSound (blank)", result);
00193 }
00194
00195
00196
00197 _sound->setLoopCount(1);
00198 _sound->setMode(FMOD_LOOP_OFF);
00199
00200
00201
00202
00203
00204
00205 result = _sound->getDefaults( &_sampleFrequency, &_volume , &_balance, &_priority);
00206 fmod_audio_errcheck("_sound->getDefaults()", result);
00207 }
00208
00209
00210
00211
00212
00213
00214
00215 FmodAudioSound::
00216 ~FmodAudioSound() {
00217 ReMutexHolder holder(FmodAudioManager::_lock);
00218 FMOD_RESULT result;
00219
00220
00221 _manager->_all_sounds.erase(this);
00222
00223
00224 result = _sound->release();
00225 fmod_audio_errcheck("_sound->release()", result);
00226 }
00227
00228
00229
00230
00231
00232
00233
00234 void FmodAudioSound::
00235 play() {
00236 start_playing();
00237 }
00238
00239
00240
00241
00242
00243
00244 void FmodAudioSound::
00245 stop() {
00246 ReMutexHolder holder(FmodAudioManager::_lock);
00247 FMOD_RESULT result;
00248
00249 if (_channel != 0) {
00250 result =_channel->stop();
00251 if (result == FMOD_ERR_INVALID_HANDLE || result == FMOD_ERR_CHANNEL_STOLEN) {
00252 _channel = 0;
00253 } else if (result == FMOD_OK) {
00254 _self_ref.clear();
00255 } else {
00256 fmod_audio_errcheck("_channel->stop()", result);
00257 }
00258 }
00259 _start_time = 0.0;
00260 }
00261
00262
00263
00264
00265
00266
00267
00268 void FmodAudioSound::
00269 set_loop(bool loop) {
00270 if (loop) {
00271 set_loop_count(0);
00272 } else {
00273 set_loop_count(1);
00274 }
00275 }
00276
00277
00278
00279
00280
00281
00282 bool FmodAudioSound::
00283 get_loop() const {
00284 if (get_loop_count() == 1) {
00285 return false;
00286 } else {
00287 return true;
00288 }
00289 }
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300 void FmodAudioSound::
00301 set_loop_count(unsigned long loop_count) {
00302 ReMutexHolder holder(FmodAudioManager::_lock);
00303 audio_debug("FmodAudioSound::set_loop_count() Setting the sound's loop count to: " << loop_count);
00304
00305
00306 FMOD_RESULT result;
00307
00308 if (loop_count == 0) {
00309 result = _sound->setLoopCount( -1 );
00310 fmod_audio_errcheck("_sound->setLoopCount()", result);
00311 result =_sound->setMode(FMOD_LOOP_NORMAL);
00312 fmod_audio_errcheck("_sound->setMode()", result);
00313 } else if (loop_count == 1) {
00314 result = _sound->setLoopCount( 1 );
00315 fmod_audio_errcheck("_sound->setLoopCount()", result);
00316 result =_sound->setMode(FMOD_LOOP_OFF);
00317 fmod_audio_errcheck("_sound->setMode()", result);
00318 } else {
00319 result = _sound->setLoopCount( loop_count );
00320 fmod_audio_errcheck("_sound->setLoopCount()", result);
00321 result =_sound->setMode(FMOD_LOOP_NORMAL);
00322 fmod_audio_errcheck("_sound->setMode()", result);
00323 }
00324
00325 audio_debug("FmodAudioSound::set_loop_count() Sound's loop count should be set to: " << loop_count);
00326 }
00327
00328
00329
00330
00331
00332
00333 unsigned long FmodAudioSound::
00334 get_loop_count() const {
00335 ReMutexHolder holder(FmodAudioManager::_lock);
00336 FMOD_RESULT result;
00337 int loop_count;
00338
00339 result = _sound->getLoopCount( &loop_count );
00340 fmod_audio_errcheck("_sound->getLoopCount()", result);
00341
00342 if (loop_count <= 0) {
00343 return 0;
00344 } else {
00345 return (unsigned long)loop_count;
00346 }
00347 }
00348
00349
00350
00351
00352
00353
00354
00355
00356 void FmodAudioSound::
00357 set_time(PN_stdfloat start_time) {
00358 ReMutexHolder holder(FmodAudioManager::_lock);
00359 _start_time = start_time;
00360
00361 if (status() == PLAYING) {
00362
00363 start_playing();
00364 }
00365 }
00366
00367
00368
00369
00370
00371
00372 PN_stdfloat FmodAudioSound::
00373 get_time() const {
00374 ReMutexHolder holder(FmodAudioManager::_lock);
00375 FMOD_RESULT result;
00376 unsigned int current_time;
00377
00378 if (_channel == 0) {
00379 return 0.0f;
00380 }
00381
00382 result = _channel->getPosition( ¤t_time , FMOD_TIMEUNIT_MS );
00383 if (result == FMOD_ERR_INVALID_HANDLE || result == FMOD_ERR_CHANNEL_STOLEN) {
00384 return 0.0f;
00385 }
00386 fmod_audio_errcheck("_channel->getPosition()", result);
00387
00388 return ((double)current_time) / 1000.0;
00389 }
00390
00391
00392
00393
00394
00395
00396
00397 void FmodAudioSound::
00398 set_volume(PN_stdfloat vol) {
00399 ReMutexHolder holder(FmodAudioManager::_lock);
00400 _volume = vol;
00401 set_volume_on_channel();
00402 }
00403
00404
00405
00406
00407
00408
00409 PN_stdfloat FmodAudioSound::
00410 get_volume() const {
00411 return _volume;
00412 }
00413
00414
00415
00416
00417
00418
00419 void FmodAudioSound::
00420 start_playing() {
00421 ReMutexHolder holder(FmodAudioManager::_lock);
00422 FMOD_RESULT result;
00423
00424 if (!_active) {
00425 _paused = true;
00426 return;
00427 }
00428
00429 int startTime = (int)(_start_time * 1000);
00430
00431 if (_channel != 0) {
00432
00433 result = _channel->setPosition( startTime , FMOD_TIMEUNIT_MS );
00434 if (result == FMOD_ERR_INVALID_HANDLE || result == FMOD_ERR_CHANNEL_STOLEN) {
00435 _channel = 0;
00436
00437 } else {
00438 fmod_audio_errcheck("_channel->setPosition()", result);
00439
00440 bool playing;
00441 result = _channel->isPlaying(&playing);
00442 fmod_audio_errcheck("_channel->isPlaying()", result);
00443 if (result != FMOD_OK || !playing) {
00444 _channel = 0;
00445 }
00446 }
00447 }
00448
00449 if (_channel == 0) {
00450 result = _manager->_system->playSound(FMOD_CHANNEL_FREE, _sound, true, &_channel);
00451 fmod_audio_errcheck("_system->playSound()", result);
00452 result = _channel->setChannelGroup(_manager->_channelgroup);
00453 fmod_audio_errcheck("_channel->setChannelGroup()", result);
00454 result = _channel->setUserData(this);
00455 fmod_audio_errcheck("_channel->setUserData()", result);
00456 result = _channel->setCallback(sound_end_callback);
00457 fmod_audio_errcheck("_channel->setCallback()", result);
00458 result = _channel->setPosition( startTime , FMOD_TIMEUNIT_MS );
00459 fmod_audio_errcheck("_channel->setPosition()", result);
00460
00461 set_volume_on_channel();
00462 set_play_rate_on_channel();
00463 set_speaker_mix_or_balance_on_channel();
00464
00465 set_3d_attributes_on_channel();
00466
00467 result = _channel->setPaused(false);
00468 fmod_audio_errcheck("_channel->setPaused()", result);
00469
00470 _self_ref = this;
00471 }
00472 }
00473
00474
00475
00476
00477
00478
00479 void FmodAudioSound::
00480 set_volume_on_channel() {
00481 ReMutexHolder holder(FmodAudioManager::_lock);
00482 FMOD_RESULT result;
00483
00484 if (_channel != 0) {
00485 result = _channel->setVolume( _volume );
00486 if (result == FMOD_ERR_INVALID_HANDLE || result == FMOD_ERR_CHANNEL_STOLEN) {
00487 _channel = 0;
00488 } else {
00489 fmod_audio_errcheck("_channel->setVolume()", result);
00490 }
00491 }
00492 }
00493
00494
00495
00496
00497
00498
00499 void FmodAudioSound::
00500 set_balance(PN_stdfloat bal) {
00501 ReMutexHolder holder(FmodAudioManager::_lock);
00502 _balance = bal;
00503 set_speaker_mix_or_balance_on_channel();
00504 }
00505
00506
00507
00508
00509
00510
00511
00512
00513 PN_stdfloat FmodAudioSound::
00514 get_balance() const {
00515 return _balance;
00516 }
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528 void FmodAudioSound::
00529 set_play_rate(PN_stdfloat rate) {
00530 ReMutexHolder holder(FmodAudioManager::_lock);
00531 _playrate = rate;
00532 set_play_rate_on_channel();
00533 }
00534
00535
00536
00537
00538
00539
00540 PN_stdfloat FmodAudioSound::
00541 get_play_rate() const {
00542 return _playrate;
00543 }
00544
00545
00546
00547
00548
00549
00550 void FmodAudioSound::
00551 set_play_rate_on_channel() {
00552 ReMutexHolder holder(FmodAudioManager::_lock);
00553 FMOD_RESULT result;
00554 PN_stdfloat frequency = _sampleFrequency * _playrate;
00555
00556 if (_channel != 0) {
00557 result = _channel->setFrequency( frequency );
00558 if (result == FMOD_ERR_INVALID_HANDLE || result == FMOD_ERR_CHANNEL_STOLEN) {
00559 _channel = 0;
00560 } else {
00561 fmod_audio_errcheck("_channel->setFrequency()", result);
00562 }
00563 }
00564 }
00565
00566
00567
00568
00569
00570
00571 const string& FmodAudioSound::
00572 get_name() const {
00573 return _file_name;
00574 }
00575
00576
00577
00578
00579
00580
00581
00582 PN_stdfloat FmodAudioSound::
00583 length() const {
00584 ReMutexHolder holder(FmodAudioManager::_lock);
00585 FMOD_RESULT result;
00586 unsigned int length;
00587
00588 result = _sound->getLength( &length, FMOD_TIMEUNIT_MS );
00589 fmod_audio_errcheck("_sound->getLength()", result);
00590
00591 return ((double)length) / 1000.0;
00592 }
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609 void FmodAudioSound::
00610 set_3d_attributes(PN_stdfloat px, PN_stdfloat py, PN_stdfloat pz, PN_stdfloat vx, PN_stdfloat vy, PN_stdfloat vz) {
00611 ReMutexHolder holder(FmodAudioManager::_lock);
00612 _location.x = px;
00613 _location.y = pz;
00614 _location.z = py;
00615
00616 _velocity.x = vx;
00617 _velocity.y = vz;
00618 _velocity.z = vy;
00619
00620 set_3d_attributes_on_channel();
00621 }
00622
00623
00624
00625
00626
00627
00628 void FmodAudioSound::
00629 set_3d_attributes_on_channel() {
00630 ReMutexHolder holder(FmodAudioManager::_lock);
00631 FMOD_RESULT result;
00632 FMOD_MODE soundMode;
00633
00634 result = _sound->getMode(&soundMode);
00635 fmod_audio_errcheck("_sound->getMode()", result);
00636
00637 if ((_channel != 0) && (soundMode & FMOD_3D)) {
00638 result = _channel->set3DAttributes( &_location, &_velocity );
00639 if (result == FMOD_ERR_INVALID_HANDLE || result == FMOD_ERR_CHANNEL_STOLEN) {
00640 _channel = 0;
00641 } else {
00642 fmod_audio_errcheck("_channel->set3DAttributes()", result);
00643 }
00644 }
00645 }
00646
00647
00648
00649
00650
00651
00652
00653 void FmodAudioSound::
00654 get_3d_attributes(PN_stdfloat *px, PN_stdfloat *py, PN_stdfloat *pz, PN_stdfloat *vx, PN_stdfloat *vy, PN_stdfloat *vz) {
00655 audio_error("get3dAttributes: Currently unimplemented. Get the attributes of the attached object.");
00656 }
00657
00658
00659
00660
00661
00662
00663
00664 void FmodAudioSound::
00665 set_3d_min_distance(PN_stdfloat dist) {
00666 ReMutexHolder holder(FmodAudioManager::_lock);
00667 FMOD_RESULT result;
00668
00669 _min_dist = dist;
00670
00671 result = _sound->set3DMinMaxDistance( dist, _max_dist );
00672 fmod_audio_errcheck("_sound->set3DMinMaxDistance()", result);
00673 }
00674
00675
00676
00677
00678
00679
00680 PN_stdfloat FmodAudioSound::
00681 get_3d_min_distance() const {
00682 return _min_dist;
00683 }
00684
00685
00686
00687
00688
00689
00690 void FmodAudioSound::
00691 set_3d_max_distance(PN_stdfloat dist) {
00692 ReMutexHolder holder(FmodAudioManager::_lock);
00693 FMOD_RESULT result;
00694
00695 _max_dist = dist;
00696
00697 result = _sound->set3DMinMaxDistance( _min_dist, dist );
00698 fmod_audio_errcheck("_sound->set3DMinMaxDistance()", result);
00699 }
00700
00701
00702
00703
00704
00705
00706 PN_stdfloat FmodAudioSound::
00707 get_3d_max_distance() const {
00708 return _max_dist;
00709 }
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722 PN_stdfloat FmodAudioSound::
00723 get_speaker_mix(AudioManager::SpeakerId speaker) {
00724 ReMutexHolder holder(FmodAudioManager::_lock);
00725 if (_channel == 0) {
00726 return 0.0;
00727 }
00728
00729 FMOD_RESULT result;
00730 float frontleft;
00731 float frontright;
00732 float center;
00733 float sub;
00734 float backleft;
00735 float backright;
00736 float sideleft;
00737 float sideright;
00738
00739 result = _channel->getSpeakerMix( &frontleft, &frontright, ¢er, &sub, &backleft, &backright, &sideleft, &sideright );
00740 fmod_audio_errcheck("_channel->getSpeakerMix()", result);
00741
00742 switch(speaker) {
00743 case AudioManager::SPK_frontleft: return frontleft;
00744 case AudioManager::SPK_frontright: return frontright;
00745 case AudioManager::SPK_center: return center;
00746 case AudioManager::SPK_sub: return sub;
00747 case AudioManager::SPK_backleft: return backleft;
00748 case AudioManager::SPK_backright: return backright;
00749 case AudioManager::SPK_sideleft: return sideleft;
00750 case AudioManager::SPK_sideright: return sideright;
00751 default: return 0.0;
00752 }
00753 }
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771 void FmodAudioSound::
00772 set_speaker_mix(PN_stdfloat frontleft, PN_stdfloat frontright, PN_stdfloat center, PN_stdfloat sub, PN_stdfloat backleft, PN_stdfloat backright, PN_stdfloat sideleft, PN_stdfloat sideright) {
00773 ReMutexHolder holder(FmodAudioManager::_lock);
00774 _mix[AudioManager::SPK_frontleft] = frontleft;
00775 _mix[AudioManager::SPK_frontright] = frontright;
00776 _mix[AudioManager::SPK_center] = center;
00777 _mix[AudioManager::SPK_sub] = sub;
00778 _mix[AudioManager::SPK_backleft] = backleft;
00779 _mix[AudioManager::SPK_backright] = backright;
00780 _mix[AudioManager::SPK_sideleft] = sideleft;
00781 _mix[AudioManager::SPK_sideright] = sideright;
00782
00783 set_speaker_mix_or_balance_on_channel();
00784 }
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797 void FmodAudioSound::
00798 set_speaker_mix_or_balance_on_channel() {
00799 ReMutexHolder holder(FmodAudioManager::_lock);
00800 FMOD_RESULT result;
00801 FMOD_MODE soundMode;
00802
00803 result = _sound->getMode(&soundMode);
00804 fmod_audio_errcheck("_sound->getMode()", result);
00805
00806 if ((_channel != 0) && (( soundMode & FMOD_3D ) == 0)) {
00807 if ( _speakermode == FMOD_SPEAKERMODE_STEREO ) {
00808 result = _channel->setPan( _balance );
00809 } else {
00810 result = _channel->setSpeakerMix( _mix[AudioManager::SPK_frontleft],
00811 _mix[AudioManager::SPK_frontright],
00812 _mix[AudioManager::SPK_center],
00813 _mix[AudioManager::SPK_sub],
00814 _mix[AudioManager::SPK_backleft],
00815 _mix[AudioManager::SPK_backright],
00816 _mix[AudioManager::SPK_sideleft],
00817 _mix[AudioManager::SPK_sideright]
00818 );
00819 }
00820 if (result == FMOD_ERR_INVALID_HANDLE || result == FMOD_ERR_CHANNEL_STOLEN) {
00821 _channel = 0;
00822 } else {
00823 fmod_audio_errcheck("_channel->setSpeakerMix()/setPan()", result);
00824 }
00825 }
00826 }
00827
00828
00829
00830
00831
00832
00833
00834
00835 int FmodAudioSound::
00836 get_priority() {
00837 audio_debug("FmodAudioSound::get_priority()");
00838 return _priority;
00839 }
00840
00841
00842
00843
00844
00845
00846
00847 void FmodAudioSound::
00848 set_priority(int priority) {
00849 ReMutexHolder holder(FmodAudioManager::_lock);
00850
00851 audio_debug("FmodAudioSound::set_priority()");
00852
00853 FMOD_RESULT result;
00854
00855 _priority = priority;
00856
00857 result = _sound->setDefaults( _sampleFrequency, _volume , _balance, _priority);
00858 fmod_audio_errcheck("_sound->setDefaults()", result);
00859 }
00860
00861
00862
00863
00864
00865
00866 AudioSound::SoundStatus FmodAudioSound::
00867 status() const {
00868 ReMutexHolder holder(FmodAudioManager::_lock);
00869 FMOD_RESULT result;
00870 bool playingState;
00871
00872 if ( _channel == 0 ) {
00873 return READY;
00874 }
00875
00876 result = _channel->isPlaying( &playingState );
00877 if ((result == FMOD_OK) && (playingState == true)) {
00878 return PLAYING;
00879 } else {
00880 return READY;
00881 }
00882 }
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892 void FmodAudioSound::
00893 set_active(bool active) {
00894 ReMutexHolder holder(FmodAudioManager::_lock);
00895 if (_active != active) {
00896 _active = active;
00897 if (_active) {
00898
00899 if (_paused && get_loop_count()==0) {
00900
00901 _paused = false;
00902 play();
00903 }
00904
00905 } else {
00906
00907 if (status() == PLAYING) {
00908 if (get_loop_count() == 0) {
00909
00910 _paused = true;
00911 _start_time = get_time();
00912 }
00913 stop();
00914 }
00915 }
00916 }
00917 }
00918
00919
00920
00921
00922
00923
00924
00925 bool FmodAudioSound::
00926 get_active() const {
00927 return _active;
00928 }
00929
00930
00931
00932
00933
00934
00935 void FmodAudioSound::
00936 finished() {
00937 audio_error("finished: not implemented under FMOD-EX");
00938 }
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948 void FmodAudioSound::
00949 set_finished_event(const string& event) {
00950 audio_error("set_finished_event: not implemented under FMOD-EX");
00951 }
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961 const string& FmodAudioSound::
00962 get_finished_event() const {
00963 audio_error("get_finished_event: not implemented under FMOD-EX");
00964 return _finished_event;
00965 }
00966
00967
00968
00969
00970
00971
00972
00973 FMOD_RESULT F_CALLBACK FmodAudioSound::
00974 sound_end_callback(FMOD_CHANNEL * channel,
00975 FMOD_CHANNEL_CALLBACKTYPE type,
00976 void *commanddata1,
00977 void *commanddata2) {
00978
00979
00980
00981 if (type == FMOD_CHANNEL_CALLBACKTYPE_END) {
00982 FMOD::Channel *fc = (FMOD::Channel *)channel;
00983 void *userdata = NULL;
00984 FMOD_RESULT result = fc->getUserData(&userdata);
00985 fmod_audio_errcheck("channel->getUserData()", result);
00986 FmodAudioSound *fsound = (FmodAudioSound*)userdata;
00987 fsound->_self_ref = fsound;
00988 }
00989 return FMOD_OK;
00990 }
00991
00992
00993
00994
00995
00996
00997 FMOD_RESULT F_CALLBACK FmodAudioSound::
00998 open_callback(const char *name, int, unsigned int *file_size,
00999 void **handle, void **user_data) {
01000
01001 VirtualFile *file = (VirtualFile *)name;
01002 if (file == (VirtualFile *)NULL) {
01003 return FMOD_ERR_FILE_NOTFOUND;
01004 }
01005 if (fmodAudio_cat.is_spam()) {
01006 fmodAudio_cat.spam()
01007 << "open_callback(" << *file << ")\n";
01008 }
01009
01010 istream *str = file->open_read_file(true);
01011
01012 (*file_size) = file->get_file_size(str);
01013 (*handle) = (void *)str;
01014 (*user_data) = (void *)file;
01015
01016
01017
01018 file->ref();
01019
01020 return FMOD_OK;
01021 }
01022
01023
01024
01025
01026
01027
01028 FMOD_RESULT F_CALLBACK FmodAudioSound::
01029 close_callback(void *handle, void *user_data) {
01030 VirtualFile *file = (VirtualFile *)user_data;
01031 if (fmodAudio_cat.is_spam()) {
01032 fmodAudio_cat.spam()
01033 << "close_callback(" << *file << ")\n";
01034 }
01035
01036 VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
01037
01038 istream *str = (istream *)handle;
01039 vfs->close_read_file(str);
01040
01041
01042 unref_delete(file);
01043
01044 return FMOD_OK;
01045 }
01046
01047
01048
01049
01050
01051
01052 FMOD_RESULT F_CALLBACK FmodAudioSound::
01053 read_callback(void *handle, void *buffer, unsigned int size_bytes,
01054 unsigned int *bytes_read, void *user_data) {
01055 VirtualFile *file = (VirtualFile *)user_data;
01056 if (fmodAudio_cat.is_spam()) {
01057 fmodAudio_cat.spam()
01058 << "read_callback(" << *file << ", " << size_bytes << ")\n";
01059 }
01060
01061 istream *str = (istream *)handle;
01062 str->read((char *)buffer, size_bytes);
01063 (*bytes_read) = str->gcount();
01064
01065
01066
01067
01068
01069
01070
01071 if (str->eof()) {
01072 if ((*bytes_read) == 0) {
01073 return FMOD_ERR_FILE_EOF;
01074 } else {
01075
01076 return FMOD_OK;
01077 }
01078 } if (str->fail()) {
01079 return FMOD_ERR_FILE_BAD;
01080 } else {
01081 return FMOD_OK;
01082 }
01083 }
01084
01085
01086
01087
01088
01089
01090 FMOD_RESULT F_CALLBACK FmodAudioSound::
01091 seek_callback(void *handle, unsigned int pos, void *user_data) {
01092 VirtualFile *file = (VirtualFile *)user_data;
01093 if (fmodAudio_cat.is_spam()) {
01094 fmodAudio_cat.spam()
01095 << "seek_callback(" << *file << ", " << pos << ")\n";
01096 }
01097
01098 istream *str = (istream *)handle;
01099 str->clear();
01100 str->seekg(pos);
01101
01102 if (str->fail() && !str->eof()) {
01103 return FMOD_ERR_FILE_COULDNOTSEEK;
01104 } else {
01105 return FMOD_OK;
01106 }
01107 }
01108
01109
01110 #endif //]