aboutsummaryrefslogtreecommitdiff
path: root/sound.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sound.cpp')
-rw-r--r--sound.cpp392
1 files changed, 15 insertions, 377 deletions
diff --git a/sound.cpp b/sound.cpp
index 22c14dbad2..1085088abf 100644
--- a/sound.cpp
+++ b/sound.cpp
@@ -22,6 +22,8 @@
#include "stdafx.h"
#include "scumm.h"
+#include "mididrv.h"
+#include "imuse.h"
#include "cdmusic.h"
#ifdef _WIN32_WCE
@@ -54,7 +56,7 @@ void Scumm::processSoundQues()
int i, j;
int num;
int16 data[16];
- SoundEngine *se;
+ IMuse *se;
processSfxQueues();
@@ -77,7 +79,7 @@ void Scumm::processSoundQues()
data[j] = _soundQue[i + j];
i += num;
- se = (SoundEngine *)_soundEngine;
+ se = _imuse;
#if 0
debug(1, "processSoundQues(%d,%d,%d,%d,%d,%d,%d,%d,%d)",
data[0] >> 8,
@@ -100,7 +102,7 @@ void Scumm::processSoundQues()
void Scumm::playSound(int sound)
{
byte *ptr;
- SoundEngine *se = (SoundEngine *)_soundEngine;
+ IMuse *se = _imuse;
ptr = getResourceAddress(rtSound, sound);
if (ptr != NULL && READ_UINT32_UNALIGNED(ptr) == MKID('SOUN')) {
@@ -253,7 +255,7 @@ bool Scumm::isMouthSyncOff(uint pos)
int Scumm::isSoundRunning(int sound)
{
- SoundEngine *se;
+ IMuse *se;
int i;
if (sound == current_cd_sound)
@@ -271,7 +273,7 @@ int Scumm::isSoundRunning(int sound)
if (!isResourceLoaded(rtSound, sound))
return 0;
- se = (SoundEngine *)_soundEngine;
+ se = _imuse;
if (!se)
return 0;
return se->get_sound_status(sound);
@@ -300,7 +302,7 @@ bool Scumm::isSoundInQueue(int sound)
void Scumm::stopSound(int a)
{
- SoundEngine *se;
+ IMuse *se;
int i;
if (a == current_cd_sound) {
@@ -308,7 +310,7 @@ void Scumm::stopSound(int a)
cd_stop();
}
- se = (SoundEngine *)_soundEngine;
+ se = _imuse;
if (se)
se->stop_sound(a);
@@ -319,7 +321,7 @@ void Scumm::stopSound(int a)
void Scumm::stopAllSounds()
{
- SoundEngine *se = (SoundEngine *)_soundEngine;
+ IMuse *se = _imuse;
if (current_cd_sound != 0) {
current_cd_sound = 0;
@@ -376,7 +378,7 @@ void Scumm::talkSound(uint32 a, uint32 b, int mode)
void Scumm::setupSound()
{
- SoundEngine *se = (SoundEngine *)_soundEngine;
+ IMuse *se = _imuse;
if (se) {
se->setBase(res.address[rtSound]);
if (se->get_music_volume() == 0)
@@ -392,7 +394,7 @@ void Scumm::setupSound()
void Scumm::pauseSounds(bool pause)
{
- SoundEngine *se = (SoundEngine *)_soundEngine;
+ IMuse *se = _imuse;
if (se)
se->pause(pause);
_soundsPaused = pause;
@@ -562,84 +564,16 @@ void *Scumm::openSfxFile()
return file;
}
-MixerChannel *Scumm::allocateMixer()
-{
- int i;
- MixerChannel *mc = _mixer_channel;
- for (i = 0; i < NUM_MIXER; i++, mc++) {
- if (!mc->_sfx_sound)
- return mc;
- }
- return NULL;
-}
-
void Scumm::stopSfxSound()
{
- MixerChannel *mc = _mixer_channel;
- int i;
- for (i = 0; i < NUM_MIXER; i++, mc++) {
- if (mc->_sfx_sound)
- mc->clear();
- }
+ _mixer->stop_all();
}
bool Scumm::isSfxFinished()
{
- int i;
- for (i = 0; i < NUM_MIXER; i++)
- if (_mixer_channel[i]._sfx_sound)
- return false;
- return true;
-}
-
-#ifdef COMPRESSED_SOUND_FILE
-void Scumm::playSfxSound_MP3(void *sound, uint32 size)
-{
- MixerChannel *mc = allocateMixer();
-
- if (!mc) {
- warning("No mixer channel available");
- return;
- }
-
- mc->type = MIXER_MP3;
- mc->_sfx_sound = sound;
-
- mad_stream_init(&mc->sound_data.mp3.stream);
-
-
-
-#ifdef _WIN32_WCE
-
- // 11 kHz on WinCE
-
- mad_stream_options((mad_stream *) & mc->sound_data.mp3.stream,
- MAD_OPTION_HALFSAMPLERATE);
-
-#endif
-
-
- mad_frame_init(&mc->sound_data.mp3.frame);
- mad_synth_init(&mc->sound_data.mp3.synth);
- mc->sound_data.mp3.position = 0;
- mc->sound_data.mp3.pos_in_frame = 0xFFFFFFFF;
- mc->sound_data.mp3.size = size;
- /* This variable is the number of samples to cut at the start of the MP3
- file. This is needed to have lip-sync as the MP3 file have some miliseconds
- of blank at the start (as, I suppose, the MP3 compression algorithm need to
- have some silence at the start to really be efficient and to not distort
- too much the start of the sample).
-
- This value was found by experimenting out. If you recompress differently your
- .SO3 file, you may have to change this value.
-
- When using Lame, it seems that the sound starts to have some volume about 50 ms
- from the start of the sound => we skip about 1024 samples.
- */
- mc->sound_data.mp3.silence_cut = 1024;
+ return !_mixer->has_active_channel();
}
-#endif
void Scumm::playBundleSound(char *sound)
{
@@ -648,304 +582,8 @@ void Scumm::playBundleSound(char *sound)
void Scumm::playSfxSound(void *sound, uint32 size, uint rate)
{
- MixerChannel *mc = allocateMixer();
-
- if (!mc) {
- warning("No mixer channel available");
- return;
- }
-
- mc->type = MIXER_STANDARD;
- mc->_sfx_sound = sound;
- mc->sound_data.standard._sfx_pos = 0;
- mc->sound_data.standard._sfx_fp_pos = 0;
-
-#ifdef _WIN32_WCE
- mc->sound_data.standard._sfx_fp_speed = (1 << 16) * rate / 11025;
-#else
- mc->sound_data.standard._sfx_fp_speed = (1 << 16) * rate / 22050;
-#endif
- while (size & 0xFFFF0000)
- size >>= 1, rate >>= 1;
-
-
-#ifdef _WIN32_WCE
- mc->sound_data.standard._sfx_size = size * 11025 / rate;
-#else
- mc->sound_data.standard._sfx_size = size * 22050 / rate;
-#endif
+ _mixer->play_raw(NULL, sound, size, rate, SoundMixer::FLAG_AUTOFREE);
}
-#ifdef COMPRESSED_SOUND_FILE
-static inline int scale_sample(mad_fixed_t sample)
-{
- /* round */
- sample += (1L << (MAD_F_FRACBITS - 16));
- /* clip */
- if (sample >= MAD_F_ONE)
- sample = MAD_F_ONE - 1;
- else if (sample < -MAD_F_ONE)
- sample = -MAD_F_ONE;
- /* quantize and scale to not saturate when mixing a lot of channels */
- return sample >> (MAD_F_FRACBITS + 2 - 16);
-}
-#endif
-
-void MixerChannel::mix(int16 * data, uint32 len)
-{
- if (!_sfx_sound)
- return;
-
-#ifdef COMPRESSED_SOUND_FILE
- if (type == MIXER_STANDARD) {
-#endif
- int8 *s;
- uint32 fp_pos, fp_speed;
-
- if (len > sound_data.standard._sfx_size)
- len = sound_data.standard._sfx_size;
- sound_data.standard._sfx_size -= len;
-
- s = (int8 *) _sfx_sound + sound_data.standard._sfx_pos;
- fp_pos = sound_data.standard._sfx_fp_pos;
- fp_speed = sound_data.standard._sfx_fp_speed;
-
- do {
- fp_pos += fp_speed;
- *data++ += (*s << 6);
- s += fp_pos >> 16;
- fp_pos &= 0x0000FFFF;
- } while (--len);
-
- sound_data.standard._sfx_pos = s - (int8 *) _sfx_sound;
- sound_data.standard._sfx_fp_speed = fp_speed;
- sound_data.standard._sfx_fp_pos = fp_pos;
-
- if (!sound_data.standard._sfx_size)
- clear();
-#ifdef COMPRESSED_SOUND_FILE
- } else {
- if (type == MIXER_MP3) {
- mad_fixed_t const *ch;
- while (1) {
- ch =
- sound_data.mp3.synth.pcm.samples[0] + sound_data.mp3.pos_in_frame;
- while ((sound_data.mp3.pos_in_frame < sound_data.mp3.synth.pcm.length)
- && (len > 0)) {
- if (sound_data.mp3.silence_cut > 0) {
- sound_data.mp3.silence_cut--;
- } else {
- *data++ += scale_sample(*ch++);
- len--;
- }
- sound_data.mp3.pos_in_frame++;
- }
- if (len == 0)
- return;
-
- if (sound_data.mp3.position >= sound_data.mp3.size) {
- clear();
- return;
- }
-
- mad_stream_buffer(&sound_data.mp3.stream,
- ((unsigned char *)_sfx_sound) +
- sound_data.mp3.position,
- sound_data.mp3.size + MAD_BUFFER_GUARD -
- sound_data.mp3.position);
-
- if (mad_frame_decode(&sound_data.mp3.frame, &sound_data.mp3.stream) ==
- -1) {
- /* End of audio... */
- if (sound_data.mp3.stream.error == MAD_ERROR_BUFLEN) {
- clear();
- return;
- } else if (!MAD_RECOVERABLE(sound_data.mp3.stream.error)) {
- error("MAD frame decode error !");
- }
- }
- mad_synth_frame(&sound_data.mp3.synth, &sound_data.mp3.frame);
- sound_data.mp3.pos_in_frame = 0;
- sound_data.mp3.position =
- (unsigned char *)sound_data.mp3.stream.next_frame -
- (unsigned char *)_sfx_sound;
- }
- } else if (type == MIXER_MP3_CDMUSIC) {
- mad_fixed_t const *ch;
- mad_timer_t frame_duration;
- static long last_pos = 0;
-
- if (!sound_data.mp3_cdmusic.playing)
- return;
-
- while (1) {
-
- // See if we just skipped
- if (ftell(sound_data.mp3_cdmusic.file) != last_pos) {
- int skip_loop;
-
- // Read the new data
- memset(_sfx_sound, 0,
- sound_data.mp3_cdmusic.buffer_size + MAD_BUFFER_GUARD);
- sound_data.mp3_cdmusic.size =
- fread(_sfx_sound, 1, sound_data.mp3_cdmusic.buffer_size,
- sound_data.mp3_cdmusic.file);
- if (!sound_data.mp3_cdmusic.size) {
- sound_data.mp3_cdmusic.playing = false;
- return;
- }
- last_pos = ftell(sound_data.mp3_cdmusic.file);
- // Resync
- mad_stream_buffer(&sound_data.mp3_cdmusic.stream,
- (unsigned char *)_sfx_sound,
- sound_data.mp3_cdmusic.size);
- skip_loop = 2;
- while (skip_loop != 0) {
- if (mad_frame_decode(&sound_data.mp3_cdmusic.frame,
- &sound_data.mp3_cdmusic.stream) == 0) {
- /* Do not decrease duration - see if it's a problem */
- skip_loop--;
- if (skip_loop == 0) {
- mad_synth_frame(&sound_data.mp3_cdmusic.synth,
- &sound_data.mp3_cdmusic.frame);
- }
- } else {
- if (!MAD_RECOVERABLE(sound_data.mp3_cdmusic.stream.error)) {
- debug(1, "Unrecoverable error while skipping !");
- sound_data.mp3_cdmusic.playing = false;
- return;
- }
- }
- }
- // We are supposed to be in synch
- mad_frame_mute(&sound_data.mp3_cdmusic.frame);
- mad_synth_mute(&sound_data.mp3_cdmusic.synth);
- // Resume decoding
- if (mad_frame_decode(&sound_data.mp3_cdmusic.frame,
- &sound_data.mp3_cdmusic.stream) == 0) {
- sound_data.mp3_cdmusic.position =
- (unsigned char *)sound_data.mp3_cdmusic.stream.next_frame -
- (unsigned char *)_sfx_sound;
- sound_data.mp3_cdmusic.pos_in_frame = 0;
- } else {
- sound_data.mp3_cdmusic.playing = false;
- return;
- }
- }
- // Get samples, play samples ...
-
- ch = sound_data.mp3_cdmusic.synth.pcm.samples[0] +
- sound_data.mp3_cdmusic.pos_in_frame;
- while ((sound_data.mp3_cdmusic.pos_in_frame <
- sound_data.mp3_cdmusic.synth.pcm.length) && (len > 0)) {
- *data++ += scale_sample(*ch++);
- len--;
- sound_data.mp3_cdmusic.pos_in_frame++;
- }
- if (len == 0) {
- return;
- }
- // See if we have finished
- // May be incorrect to check the size at the end of a frame but I suppose
- // they are short enough :)
-
- frame_duration = sound_data.mp3_cdmusic.frame.header.duration;
-
- mad_timer_negate(&frame_duration);
- mad_timer_add(&sound_data.mp3_cdmusic.duration, frame_duration);
- if (mad_timer_compare(sound_data.mp3_cdmusic.duration, mad_timer_zero)
- < 0) {
- sound_data.mp3_cdmusic.playing = false;
- }
-
- if (mad_frame_decode(&sound_data.mp3_cdmusic.frame,
- &sound_data.mp3_cdmusic.stream) == -1) {
-
- if (sound_data.mp3_cdmusic.stream.error == MAD_ERROR_BUFLEN) {
- int not_decoded;
-
- if (!sound_data.mp3_cdmusic.stream.next_frame) {
- memset(_sfx_sound, 0,
- sound_data.mp3_cdmusic.buffer_size + MAD_BUFFER_GUARD);
- sound_data.mp3_cdmusic.size =
- fread(_sfx_sound, 1, sound_data.mp3_cdmusic.buffer_size,
- sound_data.mp3_cdmusic.file);
- sound_data.mp3_cdmusic.position = 0;
- not_decoded = 0;
- } else {
- not_decoded = sound_data.mp3_cdmusic.stream.bufend -
- sound_data.mp3_cdmusic.stream.next_frame;
- memcpy(_sfx_sound, sound_data.mp3_cdmusic.stream.next_frame,
- not_decoded);
-
- sound_data.mp3_cdmusic.size =
- fread((unsigned char *)_sfx_sound + not_decoded, 1,
- sound_data.mp3_cdmusic.buffer_size - not_decoded,
- sound_data.mp3_cdmusic.file);
- }
- last_pos = ftell(sound_data.mp3_cdmusic.file);
- sound_data.mp3_cdmusic.stream.error = MAD_ERROR_NONE;
- // Restream
- mad_stream_buffer(&sound_data.mp3_cdmusic.stream,
- (unsigned char *)_sfx_sound,
- sound_data.mp3_cdmusic.size + not_decoded);
- if (mad_frame_decode
- (&sound_data.mp3_cdmusic.frame,
- &sound_data.mp3_cdmusic.stream) == -1) {
- debug(1, "Error decoding after restream %d !",
- sound_data.mp3.stream.error);
- }
- } else if (!MAD_RECOVERABLE(sound_data.mp3.stream.error)) {
- error("MAD frame decode error in MP3 CDMUSIC !");
- }
- }
-
- mad_synth_frame(&sound_data.mp3_cdmusic.synth,
- &sound_data.mp3_cdmusic.frame);
- sound_data.mp3_cdmusic.pos_in_frame = 0;
- sound_data.mp3_cdmusic.position =
- (unsigned char *)sound_data.mp3_cdmusic.stream.next_frame -
- (unsigned char *)_sfx_sound;
- }
- }
- }
-#endif
-}
-
-void MixerChannel::clear()
-{
- free(_sfx_sound);
- _sfx_sound = NULL;
-
-#ifdef COMPRESSED_SOUND_FILE
- if (type == MIXER_MP3) {
- mad_synth_finish(&sound_data.mp3.synth);
- mad_frame_finish(&sound_data.mp3.frame);
- mad_stream_finish(&sound_data.mp3.stream);
- }
-#endif
-}
-
-void Scumm::mixWaves(int16 * sounds, int len)
-{
- int i;
-
- memset(sounds, 0, len * sizeof(int16));
-
- if (_soundsPaused)
- return;
-
- SoundEngine *se = (SoundEngine *)_soundEngine;
- if (se) {
- se->driver()->generate_samples(sounds, len);
- }
-
- for (i = NUM_MIXER - 1; i >= 0; i--) {
- _mixer_channel[i].mix(sounds, len);
- }
-
- if (_soundsPaused2)
- memset(sounds, 0x0, len * sizeof(int16));
-}