diff options
Diffstat (limited to 'backends/mixer')
-rw-r--r-- | backends/mixer/wincesdl/wincesdl-mixer.cpp | 183 | ||||
-rw-r--r-- | backends/mixer/wincesdl/wincesdl-mixer.h | 53 |
2 files changed, 236 insertions, 0 deletions
diff --git a/backends/mixer/wincesdl/wincesdl-mixer.cpp b/backends/mixer/wincesdl/wincesdl-mixer.cpp new file mode 100644 index 0000000000..fb8a7d10c7 --- /dev/null +++ b/backends/mixer/wincesdl/wincesdl-mixer.cpp @@ -0,0 +1,183 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#ifdef _WIN32_WCE + +// Disable symbol overrides so that we can use system headers. +#define FORBIDDEN_SYMBOL_ALLOW_ALL + +#include "common/config-manager.h" +#include "backends/platform/wince/wince-sdl.h" +#include "backends/mixer/wincesdl/wincesdl-mixer.h" +#include "common/system.h" + +#ifdef USE_VORBIS +#ifndef USE_TREMOR +#include <vorbis/vorbisfile.h> +#else +#include <tremor/ivorbisfile.h> +#endif +#endif + +#define SAMPLES_PER_SEC_OLD 11025 +#define SAMPLES_PER_SEC_NEW 22050 + +WINCESdlMixerManager::WINCESdlMixerManager() { + +} + +WINCESdlMixerManager::~WINCESdlMixerManager() { + +} + +void WINCESdlMixerManager::init() { + SDL_AudioSpec desired; + int thread_priority; + + uint32 sampleRate = compute_sample_rate(); + if (sampleRate == 0) + warning("OSystem_WINCE3::setupMixer called with sample rate 0 - audio will not work"); + else if (_mixer && _mixer->getOutputRate() == sampleRate) { + debug(1, "Skipping sound mixer re-init: samplerate is good"); + return; + } + + memset(&desired, 0, sizeof(desired)); + desired.freq = sampleRate; + desired.format = AUDIO_S16SYS; + desired.channels = 2; + desired.samples = 128; + desired.callback = private_sound_proc; + desired.userdata = this; + + // Create the mixer instance + if (_mixer == 0) + _mixer = new Audio::MixerImpl(g_system, sampleRate); + + // Add sound thread priority + if (!ConfMan.hasKey("sound_thread_priority")) + thread_priority = THREAD_PRIORITY_NORMAL; + else + thread_priority = ConfMan.getInt("sound_thread_priority"); + + desired.thread_priority = thread_priority; + + SDL_CloseAudio(); + if (SDL_OpenAudio(&desired, NULL) != 0) { + warning("Could not open audio device: %s", SDL_GetError()); + _mixer->setReady(false); + + } else { + debug(1, "Sound opened OK, mixing at %d Hz", sampleRate); + + // Re-create mixer to match the output rate + int vol1 = _mixer->getVolumeForSoundType(Audio::Mixer::kPlainSoundType); + int vol2 = _mixer->getVolumeForSoundType(Audio::Mixer::kMusicSoundType); + int vol3 = _mixer->getVolumeForSoundType(Audio::Mixer::kSFXSoundType); + int vol4 = _mixer->getVolumeForSoundType(Audio::Mixer::kSpeechSoundType); + delete _mixer; + _mixer = new Audio::MixerImpl(g_system, sampleRate); + _mixer->setVolumeForSoundType(Audio::Mixer::kPlainSoundType, vol1); + _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, vol2); + _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, vol3); + _mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, vol4); + _mixer->setReady(true); + SDL_PauseAudio(0); + } +} + +void WINCESdlMixerManager::private_sound_proc(void *param, byte *buf, int len) { + WINCESdlMixerManager *this_ = (WINCESdlMixerManager *)param; + assert(this_); + + if (this_->_mixer) + this_->_mixer->mixCallback(buf, len); + if (!OSystem_WINCE3::_soundMaster) + memset(buf, 0, len); +} + +uint32 WINCESdlMixerManager::compute_sample_rate() { + uint32 sampleRate; + + // Force at least medium quality FM synthesis for FOTAQ + Common::String gameid(ConfMan.get("gameid")); + if (gameid == "queen") { + if (!((ConfMan.hasKey("FM_high_quality") && ConfMan.getBool("FM_high_quality")) || + (ConfMan.hasKey("FM_medium_quality") && ConfMan.getBool("FM_medium_quality")))) { + ConfMan.setBool("FM_medium_quality", true); + ConfMan.flushToDisk(); + } + } + // See if the output frequency is forced by the game + if (gameid == "ft" || gameid == "dig" || gameid == "comi" || gameid == "queen" || gameid == "sword" || gameid == "agi") + sampleRate = SAMPLES_PER_SEC_NEW; + else { + if (ConfMan.hasKey("high_sample_rate") && ConfMan.getBool("high_sample_rate")) + sampleRate = SAMPLES_PER_SEC_NEW; + else + sampleRate = SAMPLES_PER_SEC_OLD; + } + +#ifdef USE_VORBIS + // Modify the sample rate on the fly if OGG is involved + if (sampleRate == SAMPLES_PER_SEC_OLD) + if (checkOggHighSampleRate()) + sampleRate = SAMPLES_PER_SEC_NEW; +#endif + + return sampleRate; +} + +#ifdef USE_VORBIS +bool WINCESdlMixerManager::checkOggHighSampleRate() { + char trackFile[255]; + FILE *testFile; + OggVorbis_File *test_ov_file = new OggVorbis_File; + + // FIXME: The following sprintf assumes that "path" is always + // terminated by a path separator. This is *not* true in general. + // This code really should check for the path separator, or even + // better, use the FSNode API. + sprintf(trackFile, "%sTrack1.ogg", ConfMan.get("path").c_str()); + // Check if we have an OGG audio track + testFile = fopen(trackFile, "rb"); + if (testFile) { + if (!ov_open(testFile, test_ov_file, NULL, 0)) { + bool highSampleRate = (ov_info(test_ov_file, -1)->rate == 22050); + ov_clear(test_ov_file); + delete test_ov_file; + return highSampleRate; + } + } + + // Do not test for OGG samples - too big and too slow anyway :) + + delete test_ov_file; + return false; +} +#endif + +#endif + diff --git a/backends/mixer/wincesdl/wincesdl-mixer.h b/backends/mixer/wincesdl/wincesdl-mixer.h new file mode 100644 index 0000000000..6c2f1efeee --- /dev/null +++ b/backends/mixer/wincesdl/wincesdl-mixer.h @@ -0,0 +1,53 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#ifndef BACKENDS_MIXER_WINCE_SDL_H +#define BACKENDS_MIXER_WINCE_SDL_H + +#include "backends/mixer/sdl/sdl-mixer.h" + +/** + * SDL mixer manager for WinCE + */ +class WINCESdlMixerManager : public SdlMixerManager { +public: + WINCESdlMixerManager(); + virtual ~WINCESdlMixerManager(); + + virtual void init(); + +private: + +#ifdef USE_VORBIS + bool checkOggHighSampleRate(); +#endif + + static void private_sound_proc(void *param, byte *buf, int len); + uint32 compute_sample_rate(); + +}; + +#endif + |