Applied patch #957544 to make output sample rate configurable at runtime.

svn-id: r14225
This commit is contained in:
Torbjörn Andersson 2004-07-16 10:24:29 +00:00
parent 078dc6220f
commit 70f8f689a1
8 changed files with 79 additions and 10 deletions

33
README
View File

@ -34,6 +34,7 @@ Table of Contents:
* 7.3 Native MIDI support * 7.3 Native MIDI support
* 7.4 UNIX native & ALSA sequencer support * 7.4 UNIX native & ALSA sequencer support
* 7.5 Using compressed audiofiles (MP3, Ogg Vorbis, Flac) * 7.5 Using compressed audiofiles (MP3, Ogg Vorbis, Flac)
* 7.6 Output sample rate
8.0) Configuration Files 8.0) Configuration Files
9.0) Compiling 9.0) Compiling
X.X) Credits X.X) Credits
@ -330,6 +331,7 @@ arguments - see the next section.
atari, fmtowns, mac, pc) atari, fmtowns, mac, pc)
--multi-midi Enable combination of Adlib and native MIDI --multi-midi Enable combination of Adlib and native MIDI
--native-mt32 True Roland MT-32 (disable GM emulation) --native-mt32 True Roland MT-32 (disable GM emulation)
--output-rate=RATE Select output sample rate in Hz (e.g. 22050)
--aspect-ratio Enable aspect ratio correction --aspect-ratio Enable aspect ratio correction
--alt-intro Use alternative intro for CD versions of Beneath a --alt-intro Use alternative intro for CD versions of Beneath a
@ -863,6 +865,35 @@ For Flac add --flac and optional parameters, i.e.
Eventually you will have a much smaller *.mp3, *.ogg or *.fla file, copy this Eventually you will have a much smaller *.mp3, *.ogg or *.fla file, copy this
file to your game dir. You can safely remove the old file. file to your game dir. You can safely remove the old file.
7.6) Output sample rate:
---- -------------------
The output sample rate tells ScummVM how many sound samples to play per channel
per second. There is much that could be said on this subject, but most of it
would be irrelevant here. The short version is that for most games 22050 Hz is
fine, but in some cases 44100 Hz is preferable. On extremely low-end systems
you may want to use 11025 Hz, but it's unlikely that you have to worry about
that.
To elaborate, most of the sounds ScummVM has to play were sampled at either
22050 Hz or 11025 Hz. Using a higher sample rate will not magically improve the
quality of these sounds. Hence, 22050 Hz is fine.
Some games use CD audio. If you use compressed files for this, they are
probably sampled at 44100 Hz, so for these games that may be a better choice of
sample rate.
When using the Adlib, FM Towns, PC Speaker or IBM PCjr music drivers, ScummVM
is responsible for generating the samples. Usually 22050 Hz will be plenty for
these, but there is at least one piece of Adlib music in Beneath a Steeel Sky
that will sound a lot better at 44100 Hz.
Using frequencies in between is not recommended. For one thing, your sound card
may not support it. In theory, ScummVM should fall back on a sensible frequency
in that case, but don't count on it. More importantly, ScummVM has to resample
all sounds to its output frequency. This is much easier to do well if the
output frequency is a multiple of the original frequency.
8.0) Configuration file: 8.0) Configuration file:
---- ------------------- ---- -------------------
@ -946,6 +977,8 @@ The following keywords are recognized:
joystick_num number Number of joystick device to use for input joystick_num number Number of joystick device to use for input
master_volume number The master volume setting (0-255) master_volume number The master volume setting (0-255)
music_driver string The music engine to use. music_driver string The music engine to use.
output_rate number The output sample rate to use, in Hz. Sensible
values are 11025, 22050 and 44100.
alsa_port string Port to use for output when using the alsa_port string Port to use for output when using the
ALSA music driver. ALSA music driver.
music_volume number The music volume setting (0-255) music_volume number The music volume setting (0-255)

View File

@ -169,6 +169,9 @@ protected:
SDL_Surface *_tmpscreen; SDL_Surface *_tmpscreen;
bool _overlayVisible; bool _overlayVisible;
// Audio
int _samplesPerSec;
// CD Audio // CD Audio
SDL_CD *_cdrom; SDL_CD *_cdrom;
int cd_track, cd_num_loops, cd_start_frame, cd_duration; int cd_track, cd_num_loops, cd_start_frame, cd_duration;

View File

@ -95,6 +95,7 @@ OSystem_SDL::OSystem_SDL()
#endif #endif
_hwscreen(0), _screen(0), _screenWidth(0), _screenHeight(0), _hwscreen(0), _screen(0), _screenWidth(0), _screenHeight(0),
_tmpscreen(0), _overlayVisible(false), _tmpscreen(0), _overlayVisible(false),
_samplesPerSec(0),
_cdrom(0), _scaler_proc(0), _modeChanged(false), _dirty_checksums(0), _cdrom(0), _scaler_proc(0), _modeChanged(false), _dirty_checksums(0),
_mouseVisible(false), _mouseDrawn(false), _mouseData(0), _mouseVisible(false), _mouseDrawn(false), _mouseData(0),
_mouseHotspotX(0), _mouseHotspotY(0), _mouseHotspotX(0), _mouseHotspotY(0),
@ -274,18 +275,40 @@ void OSystem_SDL::deleteMutex(MutexRef mutex) {
bool OSystem_SDL::setSoundCallback(SoundProc proc, void *param) { bool OSystem_SDL::setSoundCallback(SoundProc proc, void *param) {
SDL_AudioSpec desired; SDL_AudioSpec desired;
SDL_AudioSpec obtained;
memset(&desired, 0, sizeof(desired)); memset(&desired, 0, sizeof(desired));
desired.freq = SAMPLES_PER_SEC; if (ConfMan.hasKey("output_rate"))
_samplesPerSec = ConfMan.getInt("output_rate");
else
_samplesPerSec = SAMPLES_PER_SEC;
// Originally, we always used 2048 samples. This loop will produce the
// same result at 22050 Hz, and should hopefully produce something
// sensible for other frequencies. Note that it must be a power of two.
uint16 samples = 0x8000;
for (;;) {
if (samples / (_samplesPerSec / 1000) < 100)
break;
samples >>= 1;
}
desired.freq = _samplesPerSec;
desired.format = AUDIO_S16SYS; desired.format = AUDIO_S16SYS;
desired.channels = 2; desired.channels = 2;
desired.samples = 2048; desired.samples = samples;
desired.callback = proc; desired.callback = proc;
desired.userdata = param; desired.userdata = param;
if (SDL_OpenAudio(&desired, NULL) != 0) { if (SDL_OpenAudio(&desired, &obtained) != 0) {
return false; return false;
} }
// Note: This should be the obtained output rate, but it seems that at
// least on some platforms SDL will lie and claim it did get the rate
// even if it didn't. Probably only happens for "weird" rates, though.
_samplesPerSec = obtained.freq;
SDL_PauseAudio(0); SDL_PauseAudio(0);
return true; return true;
} }
@ -295,7 +318,7 @@ void OSystem_SDL::clearSoundCallback() {
} }
int OSystem_SDL::getOutputSampleRate() const { int OSystem_SDL::getOutputSampleRate() const {
return SAMPLES_PER_SEC; return _samplesPerSec;
} }
#pragma mark - #pragma mark -

View File

@ -78,6 +78,7 @@ static const char USAGE_STRING[] =
" atari, fmtowns, mac, pc)\n" " atari, fmtowns, mac, pc)\n"
" --multi-midi Enable combination Adlib and native MIDI\n" " --multi-midi Enable combination Adlib and native MIDI\n"
" --native-mt32 True Roland MT-32 (disable GM emulation)\n" " --native-mt32 True Roland MT-32 (disable GM emulation)\n"
" --output-rate=RATE Select output sample rate in Hz (e.g. 22050)\n"
" --aspect-ratio Enable aspect ratio correction\n" " --aspect-ratio Enable aspect ratio correction\n"
"\n" "\n"
#if !defined(DISABLE_SKY) || !defined(DISABLE_QUEEN) #if !defined(DISABLE_SKY) || !defined(DISABLE_QUEEN)
@ -312,6 +313,10 @@ void GameDetector::parseCommandLine(int argc, char **argv) {
ConfMan.set("music_driver", option, kTransientDomain); ConfMan.set("music_driver", option, kTransientDomain);
END_OPTION END_OPTION
DO_LONG_OPTION("output-rate")
ConfMan.set("output_rate", (int)strtol(option, 0, 10), kTransientDomain);
END_OPTION
DO_OPTION_BOOL('f', "fullscreen") DO_OPTION_BOOL('f', "fullscreen")
ConfMan.set("fullscreen", cmdValue, kTransientDomain); ConfMan.set("fullscreen", cmdValue, kTransientDomain);
END_OPTION END_OPTION

View File

@ -37,6 +37,7 @@ Usage: scummvm [OPTIONS]... [GAME]\\
&atari, fmtowns, mac, pc)\\ &atari, fmtowns, mac, pc)\\
--multi-midi &Enable combination of Adlib and native MIDI\\ --multi-midi &Enable combination of Adlib and native MIDI\\
--native-mt32 &True Roland MT-32 (disable GM emulation)\\ --native-mt32 &True Roland MT-32 (disable GM emulation)\\
--output-rate=RATE &Select output sample rate in Hz (e.g. 22050)\\
--aspect-ratio &Enable aspect ratio correction\\ --aspect-ratio &Enable aspect ratio correction\\
\\ \\
--alt-intro &Use alternative intro for CD versions of Beneath a\\ --alt-intro &Use alternative intro for CD versions of Beneath a\\

View File

@ -34,4 +34,5 @@ for example:
\input {07_02.tex} \input {07_02.tex}
\input {07_03.tex} \input {07_03.tex}
\input {07_04.tex} \input {07_04.tex}
\input {07_05.tex} \input {07_05.tex}
\input {07_06.tex}

View File

@ -92,6 +92,8 @@ The following keywords are recognized:
joystick\_num &number Number of joystick device to use for input\\ joystick\_num &number Number of joystick device to use for input\\
master\_volume &number The master volume setting (0-255)\\ master\_volume &number The master volume setting (0-255)\\
music\_driver &string The music engine to use.\\ music\_driver &string The music engine to use.\\
output\_rate &number The output sample rate to use, in Hz. Sensible\\
& values are 11025, 22050 and 44100.\\
alsa\_port &string Port to use for output when using the\\ alsa\_port &string Port to use for output when using the\\
& ALSA music driver.\\ & ALSA music driver.\\
music\_volume &number The music volume setting (0-255)\\ music\_volume &number The music volume setting (0-255)\\

View File

@ -111,11 +111,6 @@ SoundMixer::SoundMixer() {
_premixProc = 0; _premixProc = 0;
int i = 0; int i = 0;
_outputRate = (uint) _syst->getOutputSampleRate();
if (_outputRate == 0)
error("OSystem returned invalid sample rate");
_globalVolume = 0; _globalVolume = 0;
_musicVolume = 0; _musicVolume = 0;
@ -125,6 +120,12 @@ SoundMixer::SoundMixer() {
_channels[i] = 0; _channels[i] = 0;
_mixerReady = _syst->setSoundCallback(mixCallback, this); _mixerReady = _syst->setSoundCallback(mixCallback, this);
_outputRate = (uint) _syst->getOutputSampleRate();
if (_outputRate == 0)
error("OSystem returned invalid sample rate");
debug(1, "Output sample rate: %d Hz", _outputRate);
} }
SoundMixer::~SoundMixer() { SoundMixer::~SoundMixer() {