15 #include "globalMilesManager.h"
17 #ifdef HAVE_RAD_MSS //[
19 #include "lightMutexHolder.h"
20 #include "milesAudioManager.h"
21 #include "milesAudioSample.h"
22 #include "milesAudioSequence.h"
30 GlobalMilesManager *GlobalMilesManager::_global_ptr;
38 GlobalMilesManager() :
39 _managers_lock(
"GlobalMilesManager::_managers_lock"),
40 _samples_lock(
"GlobalMilesManager::_samples_lock"),
41 _sequences_lock(
"GlobalMilesManager::_sequences_lock")
57 void GlobalMilesManager::
58 add_manager(MilesAudioManager *manager) {
60 _managers.insert(manager);
73 void GlobalMilesManager::
74 remove_manager(MilesAudioManager *manager) {
76 _managers.erase(manager);
77 if (_managers.empty() && _is_open) {
88 void GlobalMilesManager::
91 Managers::iterator mi;
92 for (mi = _managers.begin(); mi != _managers.end(); ++mi) {
112 bool GlobalMilesManager::
113 get_sample(HSAMPLE &sample,
size_t &index, MilesAudioSample *sound) {
116 for (
size_t i = 0; i < _samples.size(); ++i) {
117 SampleData &smp = _samples[i];
118 if (AIL_sample_status(smp._sample) == SMP_DONE) {
119 if (smp._sound != NULL) {
122 smp._sound->internal_stop();
125 sample = smp._sample;
132 sample = AIL_allocate_sample_handle(_digital_driver);
137 AIL_init_sample(sample, DIG_F_STEREO_16, 0);
138 index = _samples.size();
142 smp._sample = sample;
143 _samples.push_back(smp);
153 void GlobalMilesManager::
154 release_sample(
size_t index, MilesAudioSample *sound) {
156 nassertv(index < _samples.size());
158 SampleData &smp = _samples[index];
159 if (smp._sound == sound) {
179 bool GlobalMilesManager::
180 get_sequence(HSEQUENCE &sequence,
size_t &index, MilesAudioSequence *sound) {
183 for (
size_t i = 0; i < _sequences.size(); ++i) {
184 SequenceData &seq = _sequences[i];
185 if (AIL_sequence_status(seq._sequence) == SEQ_DONE) {
186 if (seq._sound != NULL) {
189 seq._sound->internal_stop();
192 sequence = seq._sequence;
199 sequence = AIL_allocate_sequence_handle(_midi_driver);
204 index = _sequences.size();
208 seq._sequence = sequence;
209 _sequences.push_back(seq);
219 void GlobalMilesManager::
220 release_sequence(
size_t index, MilesAudioSequence *sound) {
222 nassertv(index < _sequences.size());
224 SequenceData &seq = _sequences[index];
225 if (seq._sound == sound) {
238 void GlobalMilesManager::
240 if (!miles_audio_force_midi_reset) {
241 audio_debug(
"MilesAudioManager::skipping force_midi_reset");
244 audio_debug(
"MilesAudioManager::force_midi_reset");
247 if ((_midi_driver!=NULL) && (_midi_driver->deviceid != MIDI_NULL_DRIVER) && (_midi_driver->hMidiOut != NULL)) {
248 audio_debug(
"MilesAudioManager::calling midiOutReset");
249 midiOutReset(_midi_driver->hMidiOut);
260 GlobalMilesManager *GlobalMilesManager::
262 if (_global_ptr == NULL) {
263 _global_ptr =
new GlobalMilesManager;
273 void GlobalMilesManager::
275 audio_debug(
"GlobalMilesManager::open_api()")
278 bool use_digital = (audio_play_wave || audio_play_mp3);
279 if (audio_play_midi && audio_software_midi) {
284 audio_software_midi =
true;
287 audio_debug(
" use_digital="<<use_digital);
288 audio_debug(
" audio_play_midi="<<audio_play_midi);
289 audio_debug(
" audio_software_midi="<<audio_software_midi);
290 audio_debug(
" audio_output_rate="<<audio_output_rate);
291 audio_debug(
" audio_output_bits="<<audio_output_bits);
292 audio_debug(
" audio_output_channels="<<audio_output_channels);
293 audio_debug(
" audio_software_midi="<<audio_software_midi);
295 #if !defined(NDEBUG) && defined(AIL_MSS_version) //[
297 AIL_MSS_version(version, 8);
298 audio_debug(
" Mss32.dll Version: "<<version);
301 if (!AIL_startup()) {
302 milesAudio_cat.warning()
303 <<
"Miles Sound System already initialized!\n";
306 AIL_set_file_callbacks(open_callback, close_callback,
307 seek_callback, read_callback);
311 AIL_open_digital_driver(audio_output_rate, audio_output_bits,
312 audio_output_channels, 0);
315 if (audio_play_midi) {
316 if (audio_software_midi) {
317 _midi_driver = AIL_open_XMIDI_driver(AIL_OPEN_XMIDI_NULL_DRIVER);
320 _dls_device = AIL_DLS_open(_midi_driver, _digital_driver, NULL, 0,
321 audio_output_rate, audio_output_bits,
322 audio_output_channels);
330 PT(
VirtualFile) file = vfs->get_file(dls_pathname);
332 milesAudio_cat.warning()
333 <<
"DLS file does not exist: " << dls_pathname <<
"\n";
335 }
else if (!file->read_file(_dls_data,
true)) {
336 milesAudio_cat.warning()
337 <<
"Could not read DLS file: " << dls_pathname <<
"\n";
339 }
else if (_dls_data.empty()) {
340 milesAudio_cat.warning()
341 <<
"DLS file is empty: " << dls_pathname <<
"\n";
344 _dls_file = AIL_DLS_load_memory(_dls_device, &_dls_data[0], 0);
347 if (_dls_file == 0) {
348 audio_error(
" Could not get DLS file, switching to hardware MIDI.");
349 AIL_DLS_close(_dls_device, 0);
351 AIL_close_XMIDI_driver(_midi_driver);
352 _midi_driver = AIL_open_XMIDI_driver(0);
355 audio_info(
" using Miles software midi");
358 _midi_driver = AIL_open_XMIDI_driver(0);
359 audio_info(
" using Miles hardware midi");
371 void GlobalMilesManager::
373 audio_debug(
"GlobalMilesManager::close_api()")
376 Samples::iterator si;
377 for (si = _samples.begin(); si != _samples.end(); ++si) {
378 SampleData &smp = (*si);
379 AIL_release_sample_handle(smp._sample);
383 Sequences::iterator qi;
384 for (qi = _sequences.begin(); qi != _sequences.end(); ++qi) {
385 SequenceData &smp = (*qi);
386 AIL_release_sequence_handle(smp._sequence);
390 if (_dls_file != 0) {
391 AIL_DLS_unload(_dls_device, _dls_file);
395 if (_dls_device != 0) {
396 AIL_DLS_close(_dls_device, 0);
400 if (_midi_driver != 0) {
401 AIL_close_XMIDI_driver(_midi_driver);
405 if (_digital_driver != 0) {
406 AIL_close_digital_driver(_digital_driver);
423 U32 AILCALLBACK GlobalMilesManager::
424 open_callback(
char const *filename, UINTa *file_handle) {
426 istream *strm = vfs->
open_read_file(Filename::binary_filename(
string(filename)),
true);
432 (*file_handle) = (UINTa)strm;
442 void AILCALLBACK GlobalMilesManager::
443 close_callback(UINTa file_handle) {
444 istream *strm = (istream *)file_handle;
455 S32 AILCALLBACK GlobalMilesManager::
456 seek_callback(UINTa file_handle, S32 offset, U32 type) {
457 istream *strm = (istream *)file_handle;
460 case AIL_FILE_SEEK_BEGIN:
461 strm->seekg(offset, ios::beg);
464 case AIL_FILE_SEEK_CURRENT:
465 strm->seekg(offset, ios::cur);
468 case AIL_FILE_SEEK_END:
469 strm->seekg(offset, ios::end);
473 return strm->tellg();
482 U32 AILCALLBACK GlobalMilesManager::
483 read_callback(UINTa file_handle,
void *buffer, U32 bytes) {
484 istream *strm = (istream *)file_handle;
485 strm->read((
char *)buffer, bytes);
486 return strm->gcount();
A hierarchy of directories and files that appears to be one continuous file system, even though the files may originate from several different sources that may not be related to the actual OS's file system.
static Filename get_dls_pathname()
Returns the full pathname to the DLS file, as specified by the Config.prc file, or the default for th...
The abstract base class for a file or directory within the VirtualFileSystem.
static void close_read_file(istream *stream)
Closes a file opened by a previous call to open_read_file().
The name of a file, such as a texture file or an Egg file.
Similar to MutexHolder, but for a light mutex.
static VirtualFileSystem * get_global_ptr()
Returns the default global VirtualFileSystem.
bool resolve_filename(Filename &filename, const DSearchPath &searchpath, const string &default_extension=string()) const
Searches the given search path for the filename.
istream * open_read_file(const Filename &filename, bool auto_unwrap) const
Convenience function; returns a newly allocated istream if the file exists and can be read...