From c8a3a05a5d83758582e0b89c4646476c535f84b0 Mon Sep 17 00:00:00 2001 From: Jordi Vilalta Prat Date: Mon, 16 Feb 2009 16:23:48 +0000 Subject: SCI: Changed pcm_device and timer "driver" functionality to use directly the ScummVM modules svn-id: r38373 --- engines/sci/include/gfx_driver.h | 42 ---- engines/sci/include/sfx_pcm.h | 9 - engines/sci/include/sfx_timer.h | 10 - engines/sci/module.mk | 8 +- engines/sci/sfx/core.cpp | 6 +- engines/sci/sfx/pcm_device.cpp | 60 +++++ engines/sci/sfx/pcm_device/alsa.cpp | 375 ----------------------------- engines/sci/sfx/pcm_device/audbuf_test.cpp | 186 -------------- engines/sci/sfx/pcm_device/audiobuf.cpp | 339 -------------------------- engines/sci/sfx/pcm_device/audiobuf.h | 140 ----------- engines/sci/sfx/pcm_device/pcm_devices.cpp | 48 ---- engines/sci/sfx/pcm_device/scummvm.cpp | 60 ----- engines/sci/sfx/pcm_device/sdl.cpp | 261 -------------------- engines/sci/sfx/timer.cpp | 54 +++++ engines/sci/sfx/timer/pthread.cpp | 100 -------- engines/sci/sfx/timer/sigalrm.cpp | 150 ------------ engines/sci/sfx/timer/timer_scummvm.cpp | 54 ----- engines/sci/sfx/timer/timers.cpp | 52 ---- 18 files changed, 121 insertions(+), 1833 deletions(-) create mode 100644 engines/sci/sfx/pcm_device.cpp delete mode 100644 engines/sci/sfx/pcm_device/alsa.cpp delete mode 100644 engines/sci/sfx/pcm_device/audbuf_test.cpp delete mode 100644 engines/sci/sfx/pcm_device/audiobuf.cpp delete mode 100644 engines/sci/sfx/pcm_device/audiobuf.h delete mode 100644 engines/sci/sfx/pcm_device/pcm_devices.cpp delete mode 100644 engines/sci/sfx/pcm_device/scummvm.cpp delete mode 100644 engines/sci/sfx/pcm_device/sdl.cpp create mode 100644 engines/sci/sfx/timer.cpp delete mode 100644 engines/sci/sfx/timer/pthread.cpp delete mode 100644 engines/sci/sfx/timer/sigalrm.cpp delete mode 100644 engines/sci/sfx/timer/timer_scummvm.cpp delete mode 100644 engines/sci/sfx/timer/timers.cpp (limited to 'engines') diff --git a/engines/sci/include/gfx_driver.h b/engines/sci/include/gfx_driver.h index 850674fcc5..76ff498e68 100644 --- a/engines/sci/include/gfx_driver.h +++ b/engines/sci/include/gfx_driver.h @@ -393,46 +393,4 @@ typedef struct _gfx_driver { /* Graphics driver */ } gfx_driver_t; - - -gfx_driver_t * -gfx_find_driver(char *, char *name); -/* Attempts to match a graphics driver to a name -** Parameters: (char *) path: The path to search in -** (char *) name: The name of the graphics driver to look for -** or NULL for the default driver -** Returns : (gfx_driver_t *) The resulting driver, or NULL if none -** was found -*/ - -const char * -gfx_get_driver_name(int nr); -/* Retreives the name of the driver with the specified number -** Parameters: (int) nr: Number of the driver -** (char *) The driver's name -** Note that this function only makes sense within a loop or if nr=0, since -** the result value is valid iff nr >= 0 AND there does not exist an nr' -** with 0 <= nr' < nr so that gfx_get_driver_name(nr') == NULL. -*/ - -/*** Utility functions for set_parameter implementations */ - -int -string_truep(char *value); -/* Tests whether a string expresses truth -** Parameters: (char *) value: The value to test -** Returns : non-zero iff 'value' contans a string expressing something -** along the lines of "yes" -*/ - -int -string_falsep(char *value); -/* Tests whether a string expresses falsehood -** Parameters: (char *) value: The value to test -** Returns : non-zero iff 'value' contans a string expressing something -** along the lines of "no" -*/ - - - #endif /* !_SCI_GFX_DRIVER_H_ */ diff --git a/engines/sci/include/sfx_pcm.h b/engines/sci/include/sfx_pcm.h index fe6a0ad4fe..f05e96d331 100644 --- a/engines/sci/include/sfx_pcm.h +++ b/engines/sci/include/sfx_pcm.h @@ -223,13 +223,4 @@ sfx_pcm_available(void); ** Returns : (int) zero iff no PCM device is available */ -sfx_pcm_device_t * -sfx_pcm_find_device(char *name); -/* Finds a PCM device by name -** Parameters: (char *) name: Name of the PCM device to look for, or NULL to -** use the system default -** Returns : (sfx_pcm_device_t *) The requested device, or NULL if no matching -** device could be found -*/ - #endif /* !defined(_SFX_PCM_H_) */ diff --git a/engines/sci/include/sfx_timer.h b/engines/sci/include/sfx_timer.h index 919203d120..8b17067a20 100644 --- a/engines/sci/include/sfx_timer.h +++ b/engines/sci/include/sfx_timer.h @@ -83,14 +83,4 @@ typedef struct { */ } sfx_timer_t; -extern sfx_timer_t * - sfx_find_timer(char *name); -/* Finds a timer by name -** Parameters: (char *) name: Name of the timer to look up, or NULL for default -** Returns : (sfx_timer_t *) The timer of matching name, or NULL -** if not found -** This does not consider timers provided by PCM devices; there must be -** retrieved externally. -*/ - #endif /* !_FREESCI_SFX_TIMER_H_ */ diff --git a/engines/sci/module.mk b/engines/sci/module.mk index 63f9bdc879..42063d8d49 100644 --- a/engines/sci/module.mk +++ b/engines/sci/module.mk @@ -70,14 +70,14 @@ MODULE_OBJS = \ sfx/adlib.o \ sfx/core.o \ sfx/iterator.o \ + sfx/pcm_device.o \ sfx/pcm-iterator.o \ sfx/songlib.o \ sfx/time.o \ + sfx/timer.o \ sfx/device/devices.o \ sfx/mixer/mixers.o \ sfx/mixer/soft.o \ - sfx/pcm_device/pcm_devices.o \ - sfx/pcm_device/scummvm.o \ sfx/player/players.o \ sfx/player/polled.o \ sfx/player/realtime.o \ @@ -86,9 +86,7 @@ MODULE_OBJS = \ sfx/softseq/opl2.o \ sfx/softseq/pcspeaker.o \ sfx/softseq/SN76496.o \ - sfx/softseq/softsequencers.o \ - sfx/timer/timer_scummvm.o \ - sfx/timer/timers.o + sfx/softseq/softsequencers.o # FIXME: The following is supposed to be a set of *temporary* hacks CXXFLAGS += -Wno-variadic-macros diff --git a/engines/sci/sfx/core.cpp b/engines/sci/sfx/core.cpp index 902872742d..ff8e7dc01e 100644 --- a/engines/sci/sfx/core.cpp +++ b/engines/sci/sfx/core.cpp @@ -45,6 +45,8 @@ static sfx_player_t *player = NULL; sfx_pcm_mixer_t *mixer = NULL; static sfx_pcm_device_t *pcm_device = NULL; static sfx_timer_t *timer = NULL; +extern sfx_timer_t sfx_timer_scummvm; +extern sfx_pcm_device_t sfx_pcm_driver_scummvm; Common::Mutex* callbackMutex; @@ -445,7 +447,7 @@ sfx_init(sfx_state_t *self, resource_mgr_t *resmgr, int flags) { } mixer = sfx_pcm_find_mixer(NULL); - pcm_device = sfx_pcm_find_device(NULL); + pcm_device = &sfx_pcm_driver_scummvm; player = sfx_find_player(NULL); @@ -461,7 +463,7 @@ sfx_init(sfx_state_t *self, resource_mgr_t *resmgr, int flags) { if (pcm_device && pcm_device->timer) timer = pcm_device->timer; else - timer = sfx_find_timer(NULL); + timer = &sfx_timer_scummvm; if (!timer) { fprintf(stderr, "[SFX] " __FILE__": Could not find timing mechanism\n"); diff --git a/engines/sci/sfx/pcm_device.cpp b/engines/sci/sfx/pcm_device.cpp new file mode 100644 index 0000000000..e6bb5f9c25 --- /dev/null +++ b/engines/sci/sfx/pcm_device.cpp @@ -0,0 +1,60 @@ +#include "sci/include/sfx_time.h" +#include "sci/include/sfx_pcm.h" +#include "engines/engine.h" +#include "sound/audiostream.h" +#include "sound/mixer.h" + + +static int pcmout_scummvm_framesize; +static Audio::AppendableAudioStream * pcmout_scummvm_audiostream; +static Audio::SoundHandle pcmout_scummvm_sound_handle; + + +static int pcmout_scummvm_init(sfx_pcm_device_t *self) { + int pcmout_scummvm_audiostream_flags = Audio::Mixer::FLAG_16BITS | Audio::Mixer::FLAG_STEREO; + +#ifdef SCUMM_LITTLE_ENDIAN + pcmout_scummvm_audiostream_flags |= Audio::Mixer::FLAG_LITTLE_ENDIAN; +#endif + + self->buf_size = 2048 << 1; + self->conf.rate = g_engine->_mixer->getOutputRate(); + self->conf.stereo = SFX_PCM_STEREO_LR; + self->conf.format = SFX_PCM_FORMAT_S16_NATIVE; + pcmout_scummvm_framesize = SFX_PCM_FRAME_SIZE(self->conf); + + pcmout_scummvm_audiostream = Audio::makeAppendableAudioStream(self->conf.rate, pcmout_scummvm_audiostream_flags); + ::g_engine->_mixer->playInputStream(Audio::Mixer::kSFXSoundType, &pcmout_scummvm_sound_handle, pcmout_scummvm_audiostream); + + return SFX_OK; +} + +static void pcmout_scummvm_exit(sfx_pcm_device_t *self) { +} + +static int pcmout_scummvm_output(sfx_pcm_device_t *self, byte *buf, int count, + sfx_timestamp_t *timestamp) { + + byte *__buf = new byte[count * pcmout_scummvm_framesize]; + + memcpy(__buf, buf, count * pcmout_scummvm_framesize); + + pcmout_scummvm_audiostream->queueBuffer(__buf, count * pcmout_scummvm_framesize); + + return SFX_OK; +} + + +sfx_pcm_device_t sfx_pcm_driver_scummvm = { + "ScummVM", + "0.1", + &pcmout_scummvm_init, + &pcmout_scummvm_exit, + NULL, + &pcmout_scummvm_output, + NULL, + {0, 0, 0}, + 0, + NULL, + NULL +}; diff --git a/engines/sci/sfx/pcm_device/alsa.cpp b/engines/sci/sfx/pcm_device/alsa.cpp deleted file mode 100644 index 4698d66478..0000000000 --- a/engines/sci/sfx/pcm_device/alsa.cpp +++ /dev/null @@ -1,375 +0,0 @@ -/*************************************************************************** - alsa.c Copyright (C) 2004 Walter van Niftrik - - - This program may be modified and copied freely according to the terms of - the GNU general public license (GPL), as long as the above copyright - notice and the licensing information contained herein are preserved. - - Please refer to www.gnu.org for licensing details. - - This work is provided AS IS, without warranty of any kind, expressed or - implied, including but not limited to the warranties of merchantibility, - noninfringement, and fitness for a specific purpose. The author will not - be held liable for any damage caused by this work or derivatives of it. - - By using this source code, you agree to the licensing terms as stated - above. - - - Please contact the maintainer for bug reports or inquiries. - - Current Maintainer: - - Walter van Niftrik - -***************************************************************************/ - -/* Based on ALSA's pcm.c example. */ - -#include -#include "audiobuf.h" - -#ifdef HAVE_ALSA -#ifdef HAVE_PTHREAD - -#define ALSA_PCM_NEW_HW_PARAMS_API -#define ALSA_PCM_NEW_SW_PARAMS_API - -#include -#include - -static const char *device = "default"; /* FIXME */ -static snd_pcm_format_t format = SND_PCM_FORMAT_S16; -static unsigned int rate = 44100; /* FIXME */ -static unsigned int channels = 2; /* FIXME */ -static unsigned int buffer_time = 100000; /* FIXME */ -static unsigned int period_time = 1000000 / 60; /* 60Hz */ /* FIXME */ - -static snd_pcm_sframes_t buffer_size; -static snd_pcm_sframes_t period_size; - -static int frame_size; -static long last_callback_secs, last_callback_usecs; - -static sfx_audio_buf_t audio_buffer; -static void (*alsa_sfx_timer_callback)(void *data); -static void *alsa_sfx_timer_data; - -static snd_pcm_t *handle; - -static pthread_t thread; -static volatile byte run_thread; - -static pthread_mutex_t mutex; - -static int -xrun_recovery(snd_pcm_t *handle, int err) { - if (err == -EPIPE) { /* under-run */ - err = snd_pcm_prepare(handle); - if (err < 0) - fprintf(stderr, "Can't recovery from underrun, prepare failed: %s\n", snd_strerror(err)); - return 0; - } else if (err == -ESTRPIPE) { - while ((err = snd_pcm_resume(handle)) == -EAGAIN) - sleep(1); /* wait until the suspend flag is released */ - if (err < 0) { - err = snd_pcm_prepare(handle); - if (err < 0) - fprintf(stderr, "Can't recovery from suspend, prepare failed: %s\n", snd_strerror(err)); - } - return 0; - } - return err; -} - -static void * -alsa_thread(void *arg) { - gint16 *ptr; - int err, cptr; - guint8 *buf; - sfx_pcm_device_t *self = (sfx_pcm_device_t *) arg; - - buf = (guint8 *) malloc(period_size * frame_size); - - while (run_thread) { - ptr = (gint16 *) buf; - cptr = period_size; - - sci_gettime(&last_callback_secs, &last_callback_usecs); - - self->timer->block(); - - if (alsa_sfx_timer_callback) - alsa_sfx_timer_callback(alsa_sfx_timer_data); - - self->timer->unblock(); - - sfx_audbuf_read(&audio_buffer, buf, period_size); - - while (cptr > 0) { - err = snd_pcm_writei(handle, ptr, cptr); - if (err == -EAGAIN) - continue; - if (err < 0) { - if (xrun_recovery(handle, err) < 0) { - fprintf(stderr, "[SND:ALSA] Write error: %s\n", snd_strerror(err)); - run_thread = 0; - } - break; /* skip one period */ - } - ptr += err * channels; - cptr -= err; - } - } - - free(buf); - return NULL; -} - -static sfx_timestamp_t -pcmout_alsa_output_timestamp(sfx_pcm_device_t *self) { - /* Number of frames enqueued in the output device: */ - int delta = (buffer_size - period_size) / frame_size - /* Number of frames enqueued in the internal audio buffer: */ - + audio_buffer.frames_nr; - - return sfx_timestamp_add(sfx_new_timestamp(last_callback_secs, - last_callback_usecs, - rate), - delta); -} - -static int -pcmout_alsa_init(sfx_pcm_device_t *self) { - unsigned int rrate; - int err, dir; - snd_pcm_hw_params_t *hwparams; - snd_pcm_sw_params_t *swparams; - pthread_attr_t attr; - - snd_pcm_hw_params_alloca(&hwparams); - snd_pcm_sw_params_alloca(&swparams); - - err = snd_pcm_open(&handle, device, SND_PCM_STREAM_PLAYBACK, 0); - if (err < 0) { - sciprintf("[SND:ALSA] Playback open error: %s\n", snd_strerror(err)); - return SFX_ERROR; - } - err = snd_pcm_hw_params_any(handle, hwparams); - if (err < 0) { - sciprintf("[SND:ALSA] Broken configuration for playback: no configurations available: %s\n", snd_strerror(err)); - return SFX_ERROR; - } - err = snd_pcm_hw_params_set_access(handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED); - if (err < 0) { - sciprintf("[SND:ALSA] Access type not available for playback: %s\n", snd_strerror(err)); - return SFX_ERROR; - } - err = snd_pcm_hw_params_set_format(handle, hwparams, format); - if (err < 0) { - sciprintf("[SND:ALSA] Sample format not available for playback: %s\n", snd_strerror(err)); - return SFX_ERROR; - } - err = snd_pcm_hw_params_set_channels(handle, hwparams, channels); - if (err < 0) { - sciprintf("[SND:ALSA] Channels count (%i) not available for playback: %s\n", channels, snd_strerror(err)); - return SFX_ERROR; - } - rrate = rate; - err = snd_pcm_hw_params_set_rate_near(handle, hwparams, &rrate, 0); - if (err < 0) { - sciprintf("[SND:ALSA] Rate %iHz not available for playback: %s\n", rate, snd_strerror(err)); - return SFX_ERROR; - } - if (rrate != rate) { - sciprintf("[SND:ALSA] Rate doesn't match (requested %iHz, get %iHz)\n", rate, err); - return SFX_ERROR; - } - err = snd_pcm_hw_params_set_buffer_time_near(handle, hwparams, &buffer_time, &dir); - if (err < 0) { - sciprintf("[SND:ALSA] Unable to set buffer time %i for playback: %s\n", buffer_time, snd_strerror(err)); - return SFX_ERROR; - } - err = snd_pcm_hw_params_get_buffer_size(hwparams, (snd_pcm_uframes_t*) & buffer_size); - if (err < 0) { - sciprintf("[SND:ALSA] Unable to get buffer size for playback: %s\n", snd_strerror(err)); - return SFX_ERROR; - } - err = snd_pcm_hw_params_set_period_time_near(handle, hwparams, &period_time, &dir); - if (err < 0) { - sciprintf("[SND:ALSA] Unable to set period time %i for playback: %s\n", period_time, snd_strerror(err)); - return SFX_ERROR; - } - err = snd_pcm_hw_params_get_period_size(hwparams, (snd_pcm_uframes_t*) & period_size, &dir); - if (err < 0) { - sciprintf("[SND:ALSA] Unable to get period size for playback: %s\n", snd_strerror(err)); - return SFX_ERROR; - } - if (period_size >= buffer_size) { - sciprintf("[SND:ALSA] Period size %i matches or exceeds buffer size %i\n", period_size, buffer_size); - return SFX_ERROR; - } - err = snd_pcm_hw_params(handle, hwparams); - if (err < 0) { - sciprintf("[SND:ALSA] Unable to set hw params for playback: %s\n", snd_strerror(err)); - return SFX_ERROR; - } - err = snd_pcm_sw_params_current(handle, swparams); - if (err < 0) { - sciprintf("[SND:ALSA] Unable to determine current swparams for playback: %s\n", snd_strerror(err)); - return SFX_ERROR; - } - err = snd_pcm_sw_params_set_start_threshold(handle, swparams, buffer_size); - if (err < 0) { - sciprintf("[SND:ALSA] Unable to set start threshold mode for playback: %s\n", snd_strerror(err)); - return SFX_ERROR; - } - err = snd_pcm_sw_params_set_avail_min(handle, swparams, period_size); - if (err < 0) { - sciprintf("[SND:ALSA] Unable to set avail min for playback: %s\n", snd_strerror(err)); - return SFX_ERROR; - } - err = snd_pcm_sw_params_set_xfer_align(handle, swparams, 1); - if (err < 0) { - sciprintf("[SND:ALSA] Unable to set transfer align for playback: %s\n", snd_strerror(err)); - return SFX_ERROR; - } - err = snd_pcm_sw_params(handle, swparams); - if (err < 0) { - sciprintf("[SND:ALSA] Unable to set sw params for playback: %s\n", snd_strerror(err)); - return SFX_ERROR; - } - - self->buf_size = buffer_size; - self->conf.rate = rate; - self->conf.stereo = channels > 1; - self->conf.format = SFX_PCM_FORMAT_S16_NATIVE; - - frame_size = SFX_PCM_FRAME_SIZE(self->conf); - - sfx_audbuf_init(&audio_buffer, self->conf); - - if (pthread_mutex_init(&mutex, NULL) != 0) { - sciprintf("[SND:ALSA] Failed to create mutex\n"); - return SFX_ERROR; - } - - run_thread = 1; - if (pthread_create(&thread, NULL, alsa_thread, self) != 0) { - sciprintf("[SND:ALSA] Failed to create thread\n"); - return SFX_ERROR; - } - - return SFX_OK; -} - -static int -pcmout_alsa_output(sfx_pcm_device_t *self, byte *buf, - int count, sfx_timestamp_t *ts) { - if (ts) - sfx_audbuf_write_timestamp(&audio_buffer, *ts); - - sfx_audbuf_write(&audio_buffer, buf, count); - return SFX_OK; -} - -static int -pcmout_alsa_set_option(sfx_pcm_device_t *self, char *name, char *value) { - return SFX_ERROR; -} - -static void -pcmout_alsa_exit(sfx_pcm_device_t *self) { - int err; - - run_thread = 0; - sciprintf("[SND:ALSA] Waiting for PCM thread to exit... "); - if (!pthread_join(thread, NULL)) - sciprintf("OK\n"); - else - sciprintf("Failed\n"); - - pthread_mutex_destroy(&mutex); - - if ((err = snd_pcm_drop(handle)) < 0) { - sciprintf("[SND:ALSA] Can't stop PCM device: %s\n", snd_strerror(err)); - } - if ((err = snd_pcm_close(handle)) < 0) { - sciprintf("[SND:ALSA] Can't close PCM device: %s\n", snd_strerror(err)); - } - - sfx_audbuf_free(&audio_buffer); -} - -static int -timer_alsa_set_option(char *name, char *value) { - return SFX_ERROR; -} - - -static int -timer_alsa_init(void (*callback)(void *data), void *data) { - alsa_sfx_timer_callback = callback; - alsa_sfx_timer_data = data; - - return SFX_OK; -} - -static int -timer_alsa_stop(void) { - alsa_sfx_timer_callback = NULL; - - return SFX_OK; -} - -static int -timer_alsa_block(void) { - if (pthread_mutex_lock(&mutex) != 0) { - fprintf(stderr, "[SND:ALSA] Failed to lock mutex\n"); - return SFX_ERROR; - } - - return SFX_OK; -} - -static int -timer_alsa_unblock(void) { - if (pthread_mutex_unlock(&mutex) != 0) { - fprintf(stderr, "[SND:ALSA] Failed to unlock mutex\n"); - return SFX_ERROR; - } - - return SFX_OK; -} - -#define ALSA_PCM_VERSION "0.2" - -sfx_timer_t pcmout_alsa_timer = { - "alsa-pcm-timer", - ALSA_PCM_VERSION, - 0, - 0, - timer_alsa_set_option, - timer_alsa_init, - timer_alsa_stop, - timer_alsa_block, - timer_alsa_unblock -}; - -sfx_pcm_device_t sfx_pcm_driver_alsa = { - "alsa", - ALSA_PCM_VERSION, - pcmout_alsa_init, - pcmout_alsa_exit, - pcmout_alsa_set_option, - pcmout_alsa_output, - pcmout_alsa_output_timestamp, - {0, 0, 0}, - 0, - &pcmout_alsa_timer, - NULL -}; - -#endif /* HAVE_PTHREAD */ -#endif /* HAVE_ALSA */ diff --git a/engines/sci/sfx/pcm_device/audbuf_test.cpp b/engines/sci/sfx/pcm_device/audbuf_test.cpp deleted file mode 100644 index 08e8b2ad5e..0000000000 --- a/engines/sci/sfx/pcm_device/audbuf_test.cpp +++ /dev/null @@ -1,186 +0,0 @@ -/*************************************************************************** - audbuf_test.c Copyright (C) 2002 Christoph Reichenbach - - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public Licence as - published by the Free Software Foundaton; either version 2 of the - Licence, or (at your option) any later version. - - It is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - merchantibility or fitness for a particular purpose. See the - GNU General Public Licence for more details. - - You should have received a copy of the GNU General Public Licence - along with this program; see the file COPYING. If not, write to - the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. - - - Please contact the maintainer for any program-related bug reports or - inquiries. - - Current Maintainer: - - Christoph Reichenbach (CR) - -***************************************************************************/ - -#include "audiobuf.h" -#if 0 -sfx_audio_buf_t buf; - -#define MIN_FRAMESIZE 1 -#define MAX_FRAMESIZE 8 - - -void -tester_write(unsigned char *data, int datalen, int framesize, int gran) { - int i; - - for (i = 0; i < datalen; i += gran) { - int size = (i + gran < datalen) ? gran : datalen - i; - - sfx_audbuf_write(&buf, data + (i * framesize), framesize, size); - } -} - - -void -tester_read(unsigned char *data, int datalen, int framesize, int gran) { - unsigned char *readdata = malloc(datalen * framesize); - int i; - - for (i = 0; i < datalen; i += gran) { - int size = (i + gran < datalen) ? gran : datalen - i; - int j; - - sfx_audbuf_read(&buf, readdata + (i * framesize), framesize, size); - for (j = 0; j < gran * framesize; j++) { - int offset = i * framesize + j; - - if (data[i] != readdata[i]) { - fprintf(stderr, "[ERROR] Mismatch at offset %08x (sample #%d): Expected %02x, got %02x\n", - offset, i, readdata[i], data[i]); - } - } - } - - free(readdata); -} - - -void -test1(unsigned char *data, int len) -/* Test the 'regular' case */ -{ - int framesize; - int stepsize; - - fprintf(stderr, "[Test-1] Commenced; len=%d.\n", len); - - for (framesize = MAX_FRAMESIZE; framesize >= MIN_FRAMESIZE; framesize >>= 1) { - fprintf(stderr, "[Test-1] Writing frame size %d\n", framesize); - for (stepsize = 1; stepsize <= len; stepsize++) - tester_write(data, len / framesize, framesize, stepsize); - } - - for (framesize = MAX_FRAMESIZE; framesize >= MIN_FRAMESIZE; framesize >>= 1) { - fprintf(stderr, "[Test-1] Reading frame size %d\n", framesize); - for (stepsize = len; stepsize >= 1; stepsize--) - tester_read(data, len / framesize, framesize, stepsize); - } - - fprintf(stderr, "[Test-1] Completed.\n"); -} - -#define TEST2_COUNT 10 -#define TEST2_LEN 3 - -void -test2(unsigned char *data, int framesize) -/* Test whether buffer underrun repeats are handled correctly */ -{ - int i; - unsigned char *src; - - fprintf(stderr, "[Test-2] Commenced; framesize=%d.\n", framesize); - - sfx_audbuf_write(&buf, data, framesize, 1); - src = malloc(framesize * TEST2_LEN); - - for (i = 0; i < TEST2_COUNT + 1; i++) { - int inst; - sfx_audbuf_read(&buf, src, framesize, TEST2_LEN); - - for (inst = 0; inst < TEST2_LEN; inst++) { - int offset = inst * framesize; - int j; - - for (j = 0; j < framesize; j++) - if (src[j + offset] != data[j]) { - fprintf(stderr, "[ERROR] At copy sample %d, frame %d, offset %d: Expected %02x, got %02x\n", - i, inst, j, data[j], src[j+offset]); - } - } - memset(src, 0xbf, framesize * TEST2_LEN); - } - - free(src); - fprintf(stderr, "[Test-1] Completed.\n"); -} - - -#define CHUNKS_NR 4 - -#define CHUNK_LEN_0 8 -#define CHUNK_LEN_1 20 -#define CHUNK_LEN_2 16 -#define CHUNK_LEN_3 40 - -unsigned char test_data_0[CHUNK_LEN_0] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; -unsigned char test_data_1[CHUNK_LEN_1] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, - 0xff, 0x00, 0xff, 0x00 - }; -unsigned char test_data_2[CHUNK_LEN_2] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; -unsigned char test_data_3[CHUNK_LEN_3] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, - 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, - 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, - 0x8f, 0x8e, 0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88 - }; - -struct { - int len; - unsigned char *data; -} test_chunks[CHUNKS_NR] = { - { CHUNK_LEN_0, test_data_0 }, - { CHUNK_LEN_1, test_data_1 }, - { CHUNK_LEN_2, test_data_2 }, - { CHUNK_LEN_3, test_data_3 } -}; - -int -main(int argc, char **argv) { - int i; - - sfx_audbuf_init(&buf); - for (i = 0; i < CHUNKS_NR; i++) { - int k; - - /* for (k = MAX_FRAMESIZE; k >= MIN_FRAMESIZE; k >>= 1) - test2(test_chunks[i].data, k);*/ - - test1(test_chunks[i].data, test_chunks[i].len); - } - sfx_audbuf_exit(&buf); - - return 0; -} -#else -int main() {} -#endif diff --git a/engines/sci/sfx/pcm_device/audiobuf.cpp b/engines/sci/sfx/pcm_device/audiobuf.cpp deleted file mode 100644 index 15c5bb765b..0000000000 --- a/engines/sci/sfx/pcm_device/audiobuf.cpp +++ /dev/null @@ -1,339 +0,0 @@ -/*************************************************************************** - audiobuf.c Copyright (C) 2003 Christoph Reichenbach - - - This program may be modified and copied freely according to the terms of - the GNU general public license (GPL), as long as the above copyright - notice and the licensing information contained herein are preserved. - - Please refer to www.gnu.org for licensing details. - - This work is provided AS IS, without warranty of any kind, expressed or - implied, including but not limited to the warranties of merchantibility, - noninfringement, and fitness for a specific purpose. The author will not - be held liable for any damage caused by this work or derivatives of it. - - By using this source code, you agree to the licensing terms as stated - above. - - - Please contact the maintainer for bug reports or inquiries. - - Current Maintainer: - - Christoph Reichenbach (CR) - -***************************************************************************/ - -#include "audiobuf.h" - -#define NO_BUFFER_UNDERRUN 0 -#define SAW_BUFFER_UNDERRUN 1 -#define REPORTED_BUFFER_UNDERRUN 2 - -static int -buffer_underrun_status = NO_BUFFER_UNDERRUN; - - -static sfx_audio_buf_chunk_t * -sfx_audbuf_alloc_chunk(void) { - sfx_audio_buf_chunk_t *ch = (sfx_audio_buf_chunk_t*)sci_malloc(sizeof(sfx_audio_buf_chunk_t)); - ch->used = 0; - ch->next = NULL; - ch->prev = NULL; - - return ch; -} - -void -sfx_audbuf_init(sfx_audio_buf_t *buf, sfx_pcm_config_t pcm_conf) { - int framesize = SFX_PCM_FRAME_SIZE(pcm_conf); - byte silence[16]; - int silencew = pcm_conf.format & ~SFX_PCM_FORMAT_LMASK; - - /* Determine the correct 'silence' for the channel and install it */ - /* Conservatively assume stereo */ - if (pcm_conf.format & SFX_PCM_FORMAT_16) { - if (pcm_conf.format & SFX_PCM_FORMAT_LE) { - silence[0] = silencew & 0xff; - silence[1] = (silencew >> 8) & 0xff; - } else { - silence[0] = (silencew >> 8) & 0xff; - silence[1] = silencew & 0xff; - } - memcpy(silence + 2, silence, 2); - } else { - silence[0] = silencew; - silence[1] = silencew; - } - - buf->last = buf->first = sfx_audbuf_alloc_chunk(); - buf->unused = NULL; - memcpy(buf->last_frame, silence, framesize); /* Initialise, in case we - ** underrun before the - ** first write */ - buf->read_offset = 0; - buf->framesize = framesize; - buf->read_timestamp.secs = -1; /* Mark as inactive */ - buf->frames_nr = 0; -} - -static void -sfx_audbuf_free_chain(sfx_audio_buf_chunk_t *b) { - while (b) { - sfx_audio_buf_chunk_t *n = b->next; - sci_free(b); - b = n; - } -} - -void -sfx_audbuf_free(sfx_audio_buf_t *buf) { - sfx_audbuf_free_chain(buf->first); - sfx_audbuf_free_chain(buf->unused); - buf->first = buf->last = buf->unused = NULL; - buf->read_offset = (int) 0xdeadbeef; -} - -void -sfx_audbuf_write(sfx_audio_buf_t *buf, unsigned char *src, int frames) { - /* In here, we compute PER BYTE */ - int data_left = buf->framesize * frames; - - if (!buf->last) { - fprintf(stderr, "FATAL: Violation of audiobuf.h usage protocol: Must use 'init' before 'write'\n"); - exit(1); - } - - if (buffer_underrun_status == SAW_BUFFER_UNDERRUN) { - /* Print here to avoid threadsafeness issues */ - sciprintf("[audiobuf] Buffer underrun\n"); - buffer_underrun_status = REPORTED_BUFFER_UNDERRUN; - } - - buf->frames_nr += frames; - - while (data_left) { - int cpsize; - int buf_free; - buf_free = SFX_AUDIO_BUF_SIZE - buf->last->used; - - - if (buf_free >= data_left) - cpsize = data_left; - else - cpsize = buf_free; - - /* Copy and advance pointers */ - memcpy(buf->last->data + buf->last->used, src, cpsize); - data_left -= cpsize; - buf->last->used += cpsize; - src += cpsize; - - if (buf->last->used == SFX_AUDIO_BUF_SIZE) { - if (!buf->last->next) { - sfx_audio_buf_chunk_t *old = buf->last; - if (buf->unused) { /* Re-use old chunks */ - sfx_audio_buf_chunk_t *buf_next_unused = buf->unused->next; - buf->unused->next = NULL; - buf->unused->used = 0; - - buf->last->next = buf->unused; - buf->unused = buf_next_unused; - } else /* Allocate */ - buf->last->next = - sfx_audbuf_alloc_chunk(); - - buf->last->prev = old; - } - - buf->last = buf->last->next; - } - } - -#ifdef TRACE_BUFFER - { - sfx_audio_buf_chunk_t *c = buf->first; - int t = buf->read_offset; - - while (c) { - fprintf(stderr, "-> ["); - for (; t < c->used; t++) - fprintf(stderr, " %02x", c->data[t]); - t = 0; - fprintf(stderr, " ] "); - c = c->next; - } - fprintf(stderr, "\n"); - } -#endif - - if (frames && (src - buf->framesize) != buf->last_frame) - /* Backup last frame, unless we're already filling from it */ - memcpy(buf->last_frame, src - buf->framesize, buf->framesize); -} - -int -sfx_audbuf_read(sfx_audio_buf_t *buf, unsigned char *dest, int frames) { - int written = 0; - - if (frames <= 0) - return 0; - - if (buf->read_timestamp.secs >= 0) { - /* Have a timestamp? Must update it! */ - buf->read_timestamp = - sfx_timestamp_add(buf->read_timestamp, - frames); - - } - - buf->frames_nr -= frames; - if (buf->frames_nr < 0) - buf->frames_nr = 0; - -#ifdef TRACE_BUFFER - { - sfx_audio_buf_chunk_t *c = buf->first; - int t = buf->read_offset; - - while (c) { - fprintf(stderr, "-> ["); - for (; t < c->used; t++) - fprintf(stderr, " %02x", c->data[t]); - t = 0; - fprintf(stderr, " ] "); - c = c->next; - } - fprintf(stderr, "\n"); - } -#endif - - while (frames) { - int data_needed = frames * buf->framesize; - int rdbytes = data_needed; - int rdframes; - - if (rdbytes > buf->first->used - buf->read_offset) - rdbytes = buf->first->used - buf->read_offset; - - memcpy(dest, buf->first->data + buf->read_offset, rdbytes); - - buf->read_offset += rdbytes; - dest += rdbytes; - - if (buf->read_offset == SFX_AUDIO_BUF_SIZE) { - /* Continue to next, enqueue the current chunk as - ** being unused */ - sfx_audio_buf_chunk_t *lastfirst = buf->first; - - buf->first = buf->first->next; - lastfirst->next = buf->unused; - buf->unused = lastfirst; - - buf->read_offset = 0; - } - - rdframes = (rdbytes / buf->framesize); - frames -= rdframes; - written += rdframes; - - if (frames && - (!buf->first || buf->read_offset == buf->first->used)) { - fprintf(stderr, "Underrun by %d frames at %d\n", frames, - buf->read_timestamp.frame_rate); - /* Buffer underrun! */ - if (!buffer_underrun_status == NO_BUFFER_UNDERRUN) { - buffer_underrun_status = SAW_BUFFER_UNDERRUN; - } - do { - memcpy(dest, buf->last_frame, buf->framesize); - dest += buf->framesize; - } while (--frames); - } - - } - - return written; -} - -#if 0 -static void -_sfx_audbuf_rewind_stream(sfx_audio_buf_t *buf, int delta) { - if (delta > buf->frames_nr) - delta = buf->frames_nr; - - - fprintf(stderr, "Rewinding %d\n", delta); - buf->frames_nr -= delta; - - /* From here on, 'delta' means the number of BYTES to remove */ - delta *= buf->framesize; - - while (delta) { - if (buf->last->used >= delta) { - fprintf(stderr, "Subtracting from %d %d\n", buf->last->used, delta); - buf->last->used -= delta; - delta = 0; - } else { - fprintf(stderr, "Must do block-unuse\n"); - delta -= buf->last->used; - buf->last->used = 0; - buf->last->next = buf->unused; - buf->unused = buf->last; - buf->last = buf->unused->prev; - buf->unused->prev = NULL; - } - } -} -#endif - -void -sfx_audbuf_write_timestamp(sfx_audio_buf_t *buf, sfx_timestamp_t ts) { - sfx_timestamp_t newstamp; - - newstamp = sfx_timestamp_add(ts, -buf->frames_nr); - - - if (buf->read_timestamp.secs <= 0) - /* Initial stamp */ - buf->read_timestamp = newstamp; - else { - int delta = sfx_timestamp_frame_diff(newstamp, buf->read_timestamp); - long s1, s2, s3, u1, u2, u3; - sfx_timestamp_gettime(&(buf->read_timestamp), &s1, &u1); - sfx_timestamp_gettime(&(newstamp), &s2, &u2); - sfx_timestamp_gettime(&(ts), &s3, &u3); - - if (delta < 0) { -#if 0 - /* fprintf(stderr, "[SFX-BUF] audiobuf.c: Timestamp delta %d at %d: Must rewind (not implemented yet)\n", - delta, buf->read_timestamp.frame_rate);*/ - _sfx_audbuf_rewind_stream(buf, -delta); - buf->read_timestamp = newstamp; -#endif - } else if (delta > 0) { - fprintf(stderr, "[SFX-BUF] audiobuf.c: Timestamp delta %d at %d: Filling in as silence frames\n", - delta, buf->read_timestamp.frame_rate); - /* Fill up with silence */ - while (delta--) { - sfx_audbuf_write(buf, buf->last_frame, 1); - } - buf->read_timestamp = newstamp; - } - } -} - -int -sfx_audbuf_read_timestamp(sfx_audio_buf_t *buf, sfx_timestamp_t *ts) { - if (buf->read_timestamp.secs > 0) { - *ts = buf->read_timestamp; - return 0; - } else { - ts->secs = -1; - ts->usecs = -1; - ts->frame_offset = -1; - ts->frame_rate = -1; - return 1; /* No timestamp */ - } -} diff --git a/engines/sci/sfx/pcm_device/audiobuf.h b/engines/sci/sfx/pcm_device/audiobuf.h deleted file mode 100644 index b2019aec17..0000000000 --- a/engines/sci/sfx/pcm_device/audiobuf.h +++ /dev/null @@ -1,140 +0,0 @@ -/*************************************************************************** - audiobuf.h Copyright (C) 2003 Christoph Reichenbach - - - This program may be modified and copied freely according to the terms of - the GNU general public license (GPL), as long as the above copyright - notice and the licensing information contained herein are preserved. - - Please refer to www.gnu.org for licensing details. - - This work is provided AS IS, without warranty of any kind, expressed or - implied, including but not limited to the warranties of merchantibility, - noninfringement, and fitness for a specific purpose. The author will not - be held liable for any damage caused by this work or derivatives of it. - - By using this source code, you agree to the licensing terms as stated - above. - - - Please contact the maintainer for bug reports or inquiries. - - Current Maintainer: - - Christoph Reichenbach (CR) - -***************************************************************************/ - -/* Auxiliary audio buffer for PCM devices -** Polled PCM devices must store data written to them until it is explicitly -** requiested. This is facilitated by the structures and functions defined -** here. -** This is generic for all PCM devices; it implies no specific requirements. -** -** Usage: Introduce an sfx_audio_buf_t into your state and make sure to use -** each of the functions provided here at least once in the appropriate -** places. -*/ - - -#ifndef _AUDIOBUF_H_ -#define _AUDIOBUF_H_ - -#include -#include -#include -#include - - -#define SFX_AUDIO_BUF_SIZE 8192 /* Must be multiple of framesize */ -#define SFX_AUDIO_MAX_FRAME 8 /* Max. individual frame size */ - -typedef struct _sfx_audio_buf_chunk { - unsigned char data[SFX_AUDIO_BUF_SIZE]; - int used; - struct _sfx_audio_buf_chunk *prev; - struct _sfx_audio_buf_chunk *next; -} sfx_audio_buf_chunk_t; - -typedef struct { - int read_offset; - sfx_audio_buf_chunk_t *first; /* Next to read-- can be = last */ - sfx_audio_buf_chunk_t *last; /* Next to write-- can be = first */ - sfx_audio_buf_chunk_t *unused; /* Unused chunk list, can be NULL */ - unsigned char last_frame[SFX_AUDIO_MAX_FRAME]; - /* Contains the last frame successfully read; used for buffer - ** underruns to avoid crack before silance */ - sfx_timestamp_t read_timestamp; /* Timestamp for reading */ - int frames_nr; /* Total number of frames currently in between reading and writing */ - int framesize; -} sfx_audio_buf_t; - - -void -sfx_audbuf_init(sfx_audio_buf_t *buf, sfx_pcm_config_t conf); -/* Initialises an audio buffer -** Parameters: (sfx_audio_buf_t *) buf: The buffer to initialise -** (sfx_pcm_config_t) conf: The configuration for which the buffer should -** be set up -** Modifies : (sfx_audio_buf_t) *buf -*/ - -void -sfx_audbuf_free(sfx_audio_buf_t *buf); -/* Frees all memory associated with an audio buffer -** Parameters: (sfx_audio_buf_t *) buf: The buffer whose associated memory -** should be freed -** Modifies : (sfx_audio_buf_t) *buf -*/ - -void -sfx_audbuf_write(sfx_audio_buf_t *buf, unsigned char *src, int frames); -/* Store data in an audion buffer -** Parameters: (sfx_audio_buf_t *) buf: The buffer to write to -** (unsigned char *) src: Pointer to the data that should be -** written -** (int) frames: Number of frames to write -** Modifies : (sfx_audio_buf_t) *buf -*/ - - -void -sfx_audbuf_write_timestamp(sfx_audio_buf_t *buf, sfx_timestamp_t ts); -/* Sets the most recently written timestamp for the buffer -** Parameters: (sfx_audio_buf_t *) buf: The buffer to operate on -** (sfx_timestamp_t) ts: The timestamp to set -** If a timestamp is already set, 'ts' is checked for consistency and -** 'silent' frames are introduced as padding for future writes. -*/ - - -int -sfx_audbuf_read_timestamp(sfx_audio_buf_t *buf, sfx_timestamp_t *ts); -/* Reads the timestamp describing the time right before the next frame being read -** Parameters: (sfx_audio_buf_t *) buf: The buffer to read from -** Returns : (sfx_timestamp_t) *ts: The requested timestamp, or nothing -** (int) zero on success, nonzero if no timestamp is known -*/ - - -int -sfx_audbuf_read(sfx_audio_buf_t *buf, unsigned char *dest, int frames); -/* Read data from audio buffer -** Parameters: (sfx_audio_buf_t *) buf: The buffer to write to -** (unsigned char *) dest: Pointer to the place the read data -** should be written to -** (int) frames: Number of frames to write -** Returns : (int) Number of frames actually read -** Affects : (sfx_audio_buf_t) *buf -** (unsigned char ) *dest -** global error stream -** If the returned number of frames is smaller than the number of frames -** requested to be written, this function will issue a buffer underrun -** warning and fill up the remaining space with the last frame it en-- -** countered, or a block of '0' if no such frame is known. -*/ - - - - -#endif /* !_AUDIOBUF_H_ */ diff --git a/engines/sci/sfx/pcm_device/pcm_devices.cpp b/engines/sci/sfx/pcm_device/pcm_devices.cpp deleted file mode 100644 index 866372a670..0000000000 --- a/engines/sci/sfx/pcm_device/pcm_devices.cpp +++ /dev/null @@ -1,48 +0,0 @@ -/*************************************************************************** - pcmout.c Copyright (C) 2002 Solomon Peachy - - This program may be modified and copied freely according to the terms of - the GNU general public license (GPL), as long as the above copyright - notice and the licensing information contained herein are preserved. - - Please refer to www.gnu.org for licensing details. - - This work is provided AS IS, without warranty of any kind, expressed or - implied, including but not limited to the warranties of merchantibility, - noninfringement, and fitness for a specific purpose. The author will not - be held liable for any damage caused by this work or derivatives of it. - - By using this source code, you agree to the licensing terms as stated - above. - -***************************************************************************/ - -#include "sci/include/sfx_pcm.h" -#include "sci/include/resource.h" - -#ifndef NO_PCMOUT -extern sfx_pcm_device_t sfx_pcm_driver_scummvm; -#endif - -sfx_pcm_device_t *pcmout_drivers[] = { -#ifndef NO_PCMOUT - &sfx_pcm_driver_scummvm, -#endif - NULL -}; - -sfx_pcm_device_t * -sfx_pcm_find_device(char *name) { - int retval = 0; - - if (!name) { /* Find default driver */ - return pcmout_drivers[0]; - } - - while (pcmout_drivers[retval] && - scumm_stricmp(name, pcmout_drivers[retval]->name)) - retval++; - - return pcmout_drivers[retval]; -} - diff --git a/engines/sci/sfx/pcm_device/scummvm.cpp b/engines/sci/sfx/pcm_device/scummvm.cpp deleted file mode 100644 index e6bb5f9c25..0000000000 --- a/engines/sci/sfx/pcm_device/scummvm.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include "sci/include/sfx_time.h" -#include "sci/include/sfx_pcm.h" -#include "engines/engine.h" -#include "sound/audiostream.h" -#include "sound/mixer.h" - - -static int pcmout_scummvm_framesize; -static Audio::AppendableAudioStream * pcmout_scummvm_audiostream; -static Audio::SoundHandle pcmout_scummvm_sound_handle; - - -static int pcmout_scummvm_init(sfx_pcm_device_t *self) { - int pcmout_scummvm_audiostream_flags = Audio::Mixer::FLAG_16BITS | Audio::Mixer::FLAG_STEREO; - -#ifdef SCUMM_LITTLE_ENDIAN - pcmout_scummvm_audiostream_flags |= Audio::Mixer::FLAG_LITTLE_ENDIAN; -#endif - - self->buf_size = 2048 << 1; - self->conf.rate = g_engine->_mixer->getOutputRate(); - self->conf.stereo = SFX_PCM_STEREO_LR; - self->conf.format = SFX_PCM_FORMAT_S16_NATIVE; - pcmout_scummvm_framesize = SFX_PCM_FRAME_SIZE(self->conf); - - pcmout_scummvm_audiostream = Audio::makeAppendableAudioStream(self->conf.rate, pcmout_scummvm_audiostream_flags); - ::g_engine->_mixer->playInputStream(Audio::Mixer::kSFXSoundType, &pcmout_scummvm_sound_handle, pcmout_scummvm_audiostream); - - return SFX_OK; -} - -static void pcmout_scummvm_exit(sfx_pcm_device_t *self) { -} - -static int pcmout_scummvm_output(sfx_pcm_device_t *self, byte *buf, int count, - sfx_timestamp_t *timestamp) { - - byte *__buf = new byte[count * pcmout_scummvm_framesize]; - - memcpy(__buf, buf, count * pcmout_scummvm_framesize); - - pcmout_scummvm_audiostream->queueBuffer(__buf, count * pcmout_scummvm_framesize); - - return SFX_OK; -} - - -sfx_pcm_device_t sfx_pcm_driver_scummvm = { - "ScummVM", - "0.1", - &pcmout_scummvm_init, - &pcmout_scummvm_exit, - NULL, - &pcmout_scummvm_output, - NULL, - {0, 0, 0}, - 0, - NULL, - NULL -}; diff --git a/engines/sci/sfx/pcm_device/sdl.cpp b/engines/sci/sfx/pcm_device/sdl.cpp deleted file mode 100644 index c4c47ed2a1..0000000000 --- a/engines/sci/sfx/pcm_device/sdl.cpp +++ /dev/null @@ -1,261 +0,0 @@ -/*************************************************************************** - sdl.c Copyright (C) 2002 Solomon Peachy, Claudio Matsuoka, - 2003,04 Christoph Reichenbach - - This program may be modified and copied freely according to the terms of - the GNU general public license (GPL), as long as the above copyright - notice and the licensing information contained herein are preserved. - - Please refer to www.gnu.org for licensing details. - - This work is provided AS IS, without warranty of any kind, expressed or - implied, including but not limited to the warranties of merchantibility, - noninfringement, and fitness for a specific purpose. The author will not - be held liable for any damage caused by this work or derivatives of it. - - By using this source code, you agree to the licensing terms as stated - above. - -***************************************************************************/ - -#include -#include "audiobuf.h" - -#ifdef HAVE_SDL - -#if !defined(_MSC_VER) -# include -#endif - -#include -#undef HAVE_ICONV -#undef HAVE_ICONV_H -#undef HAVE_ALLOCA_H - -#include - -#define DELTA_TIME_LIMIT 10000 /* Report errors above this delta time */ - -static sfx_audio_buf_t audio_buffer; -static void (*sdl_sfx_timer_callback)(void *data); -static void *sdl_sfx_timer_data; -static int frame_size; -static int buf_size; -static int rate; -static long last_callback_secs, last_callback_usecs; -static int last_callback_len; - -static sfx_timestamp_t -pcmout_sdl_output_timestamp(sfx_pcm_device_t *self) { - /* Number of frames enqueued in the output device: */ - int delta = (buf_size - last_callback_len) / frame_size - /* Number of frames enqueued in the internal audio buffer: */ - + audio_buffer.frames_nr; - - return sfx_timestamp_add(sfx_new_timestamp(last_callback_secs, - last_callback_usecs, - rate), - delta); -} - -FILE *fil = NULL; - -static void -timer_sdl_internal_callback(void *userdata, byte *dest, int len) { - sci_gettime(&last_callback_secs, &last_callback_usecs); - last_callback_len = len; - - if (sdl_sfx_timer_callback) - sdl_sfx_timer_callback(sdl_sfx_timer_data); - -#if 0 - if (!sfx_audbuf_read_timestamp(&audio_buffer, &ts)) { - int delta = (buf_size - len) / frame_size; - sfx_timestamp_t real_ts; - long deltatime; - long sec2, usec2; - sci_gettime(&sec2, &usec2); - - real_ts = sfx_timestamp_add(sfx_new_timestamp(sec, usec, rate), delta); - - deltatime = sfx_timestamp_usecs_diff(ts, real_ts); - - fprintf(stderr, "[SDL] Frames requested: %d Playing %ld too late. Needed %ldus for computations.\n", - len / frame_size, deltatime, - (usec2 - usec) + (sec2 - sec)*1000000); - - if (abs(deltatime) > DELTA_TIME_LIMIT) - sciprintf("[SND:SDL] Very high delta time for PCM playback: %ld too late (%d frames in the future)\n", - deltatime, sfx_timestamp_frame_diff(sfx_new_timestamp(sec, usec, rate), ts)); - -#if 0 - if (deltatime < 0) { - /* Read and discard frames, explicitly underrunning */ - int max_read = len / frame_size; - int frames_to_kill = sfx_timestamp_frame_diff(real_ts, ts); - - while (frames_to_kill) { - int d = frames_to_kill > max_read ? max_read : frames_to_kill; - sfx_audbuf_read(&audio_buffer, dest, d); - frames_to_kill -= d; - } - } -#endif - } -#endif - sfx_audbuf_read(&audio_buffer, dest, len / frame_size); - -#if 0 - if (!fil) { - fil = fopen("/tmp/sdl.log", "w"); - } - { - int i; - int end = len / frame_size; - gint16 *d = dest; - fprintf(fil, "Writing %d/%d\n", len, frame_size); - for (i = 0; i < end; i++) { - fprintf(fil, "\t%d\t%d\n", d[0], d[1]); - d += 2; - } - } -#endif -} - - -static int -pcmout_sdl_init(sfx_pcm_device_t *self) { - SDL_AudioSpec a; - - if (SDL_Init(SDL_INIT_AUDIO | SDL_INIT_NOPARACHUTE) != 0) { - fprintf(stderr, "[SND:SDL] Error while initialising: %s\n", SDL_GetError()); - return -1; - } - - a.freq = 44100; /* FIXME */ -#ifdef WORDS_BIGENDIAN - a.format = AUDIO_S16MSB; /* FIXME */ -#else - a.format = AUDIO_S16LSB; /* FIXME */ -#endif - a.channels = 2; /* FIXME */ - a.samples = 2048; /* FIXME */ - a.callback = timer_sdl_internal_callback; - a.userdata = NULL; - - if (SDL_OpenAudio(&a, NULL) < 0) { - fprintf(stderr, "[SND:SDL] Error while opening audio: %s\n", SDL_GetError()); - return SFX_ERROR; - } - - buf_size = a.samples; - rate = a.freq; - - self->buf_size = a.samples << 1; /* Looks like they're using double size */ - self->conf.rate = a.freq; - self->conf.stereo = a.channels > 1; - self->conf.format = SFX_PCM_FORMAT_S16_NATIVE; - - frame_size = SFX_PCM_FRAME_SIZE(self->conf); - - sfx_audbuf_init(&audio_buffer, self->conf); - SDL_PauseAudio(0); - - return SFX_OK; -} - -int -pcmout_sdl_output(sfx_pcm_device_t *self, byte *buf, - int count, sfx_timestamp_t *ts) { - if (ts) - sfx_audbuf_write_timestamp(&audio_buffer, *ts); - sfx_audbuf_write(&audio_buffer, buf, count); - return SFX_OK; -} - - -static int -pcmout_sdl_set_option(sfx_pcm_device_t *self, char *name, char *value) { - return SFX_ERROR; /* Option not supported */ -} - -static void -pcmout_sdl_exit(sfx_pcm_device_t *self) { - SDL_PauseAudio(1); - SDL_CloseAudio(); - sfx_audbuf_free(&audio_buffer); - - SDL_QuitSubSystem(SDL_INIT_AUDIO); - - if (!SDL_WasInit(SDL_INIT_EVERYTHING)) { - sciprintf("[SND:SDL] No active SDL subsystems found.. shutting down SDL\n"); - SDL_Quit(); - } -} - - -static int -timer_sdl_set_option(char *name, char *value) { - return SFX_ERROR; -} - - -static int -timer_sdl_init(void (*callback)(void *data), void *data) { - sdl_sfx_timer_callback = callback; - sdl_sfx_timer_data = data; - - - return SFX_OK; -} - -static int -timer_sdl_stop(void) { - sdl_sfx_timer_callback = NULL; - - return SFX_OK; -} - -static int -timer_sdl_block(void) { - SDL_LockAudio(); - - return SFX_OK; -} - -static int -timer_sdl_unblock(void) { - SDL_UnlockAudio(); - - return SFX_OK; -} - -#define SDL_PCM_VERSION "0.1" - -sfx_timer_t pcmout_sdl_timer = { - "sdl-pcm-timer", - SDL_PCM_VERSION, - 0, - 0, - timer_sdl_set_option, - timer_sdl_init, - timer_sdl_stop, - timer_sdl_block, - timer_sdl_unblock -}; - -sfx_pcm_device_t sfx_pcm_driver_sdl = { - "sdl", - SDL_PCM_VERSION, - pcmout_sdl_init, - pcmout_sdl_exit, - pcmout_sdl_set_option, - pcmout_sdl_output, - pcmout_sdl_output_timestamp, - {0, 0, 0}, - 0, - &pcmout_sdl_timer, - NULL -}; - -#endif diff --git a/engines/sci/sfx/timer.cpp b/engines/sci/sfx/timer.cpp new file mode 100644 index 0000000000..beb57aef6b --- /dev/null +++ b/engines/sci/sfx/timer.cpp @@ -0,0 +1,54 @@ +#include "common/timer.h" +#include "engines/engine.h" +#include "sci/include/sfx_timer.h" + + +#define FREQ 60 +#define DELAY (1000000 / FREQ) + +typedef void (*scummvm_timer_callback_t)(void *); +static scummvm_timer_callback_t scummvm_timer_callback = NULL; +static void *scummvm_timer_callback_data = NULL; +extern ::Engine *g_engine; + +void scummvm_timer_update_internal(void *ptr) { + if (scummvm_timer_callback) + scummvm_timer_callback(scummvm_timer_callback_data); +} + +int scummvm_timer_start(void (*func)(void *), void *data) { + if (scummvm_timer_callback) { + fprintf(stderr, + "Error: Attempt to initialize gametick timer more than once\n"); + return SFX_ERROR; + } + + if (!func) { + fprintf(stderr, + "Error: Attempt to initialize gametick timer w/o callback\n"); + return SFX_ERROR; + } + + scummvm_timer_callback = func; + scummvm_timer_callback_data = data; + + ::g_engine->getTimerManager()->installTimerProc(&scummvm_timer_update_internal, DELAY, NULL); + return SFX_OK; +} + +int scummvm_timer_stop() { + scummvm_timer_callback = NULL; + return SFX_OK; +} + + +sfx_timer_t sfx_timer_scummvm = { + "ScummVM", + "0.1", + DELAY / 1000, 0, + NULL, + &scummvm_timer_start, + &scummvm_timer_stop, + 0, + 0 +}; diff --git a/engines/sci/sfx/timer/pthread.cpp b/engines/sci/sfx/timer/pthread.cpp deleted file mode 100644 index bcef9639c4..0000000000 --- a/engines/sci/sfx/timer/pthread.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/*************************************************************************** - pthread.c Copyright (C) 2005 Walter van Niftrik - - - This program may be modified and copied freely according to the terms of - the GNU general public license (GPL), as long as the above copyright - notice and the licensing information contained herein are preserved. - - Please refer to www.gnu.org for licensing details. - - This work is provided AS IS, without warranty of any kind, expressed or - implied, including but not limited to the warranties of merchantibility, - noninfringement, and fitness for a specific purpose. The author will not - be held liable for any damage caused by this work or derivatives of it. - - By using this source code, you agree to the licensing terms as stated - above. - - - Please contact the maintainer for bug reports or inquiries. - - Current Maintainer: - - Walter van Niftrik - -***************************************************************************/ - -#include -#include -#include - -/* Timer frequency in hertz */ -#define FREQ 60 - -/* Delay in ms */ -#define DELAY (1000 / FREQ) - -static void (*callback)(void *) = NULL; -static void *callback_data = NULL; -pthread_t thread; -volatile static int thread_run; - -static void * -timer_thread(void *arg) { - while (thread_run) { - if (callback) - callback(callback_data); - - usleep(DELAY * 1000); - } - - return NULL; -} - -static int -set_option(char *name, char *value) { - return SFX_ERROR; -} - -static int -init(void (*func)(void *), void *data) { - if (callback) { - fprintf(stderr, "Error: Attempt to initialize pthread timer more than once\n"); - return SFX_ERROR; - } - - if (!func) { - fprintf(stderr, "Error: Attempt to initialize pthread timer w/o callback\n"); - return SFX_ERROR; - } - - callback = func; - callback_data = data; - - thread_run = 1; - if (pthread_create(&thread, NULL, timer_thread, NULL)) { - fprintf(stderr, "Error: Could not create thread.\n"); - return SFX_ERROR; - } - - return SFX_OK; -} - -static int -stop(void) { - thread_run = 0; - pthread_join(thread, NULL); - - return SFX_OK; -} - -sfx_timer_t sfx_timer_pthread = { - "pthread", - "0.1", - DELAY, - 0, - &set_option, - &init, - &stop -}; diff --git a/engines/sci/sfx/timer/sigalrm.cpp b/engines/sci/sfx/timer/sigalrm.cpp deleted file mode 100644 index 2bab402d14..0000000000 --- a/engines/sci/sfx/timer/sigalrm.cpp +++ /dev/null @@ -1,150 +0,0 @@ -/*************************************************************************** - sigalrm.c Copyright (C) 2002 Christoph Reichenbach - - - This program may be modified and copied freely according to the terms of - the GNU general public license (GPL), as long as the above copyright - notice and the licensing information contained herein are preserved. - - Please refer to www.gnu.org for licensing details. - - This work is provided AS IS, without warranty of any kind, expressed or - implied, including but not limited to the warranties of merchantibility, - noninfringement, and fitness for a specific purpose. The author will not - be held liable for any damage caused by this work or derivatives of it. - - By using this source code, you agree to the licensing terms as stated - above. - - - Please contact the maintainer for bug reports or inquiries. - - Current Maintainer: - - Christoph Reichenbach (CR) - -***************************************************************************/ - -#include - -#ifdef HAVE_SETITIMER - -#include -#include -#include - -#ifdef HAVE_PTHREAD -#include -#define sigprocmask pthread_sigmask -#endif - -static void (*sig_callback)(void *) = NULL; -static void *sig_callback_data = NULL; -static sigset_t current_sigset; - -static void -timer_handler(int i) { - if (sig_callback) - sig_callback(sig_callback_data); -} - -static int -sigalrm_set_option(char *name, char *value) { - return SFX_ERROR; -} - - -static int -sigalrm_start(void) { - struct itimerval itimer; - - itimer.it_value.tv_sec = 0; - itimer.it_value.tv_usec = 1000000 / 60; - itimer.it_interval = itimer.it_value; - - signal(SIGALRM, timer_handler); /* Re-instate timer handler, to make sure */ - setitimer(ITIMER_REAL, &itimer, NULL); - - return SFX_OK; -} - - -static int -sigalrm_init(void (*callback)(void *), void *data) { - if (sig_callback) { - fprintf(stderr, "Error: Attempt to initialize sigalrm timer more than once\n"); - return SFX_ERROR; - } - - if (!callback) { - fprintf(stderr, "Error: Attempt to initialize sigalrm timer w/o callback\n"); - return SFX_ERROR; - } - - sig_callback = callback; - sig_callback_data = data; - - sigalrm_start(); - - sigemptyset(¤t_sigset); - sigaddset(¤t_sigset, SIGALRM); - - return SFX_OK; -} - - -static int -sigalrm_stop(void) { - struct itimerval itimer; - - if (!sig_callback) { - fprintf(stderr, "Error: Attempt to stop sigalrm timer when not running\n"); - return SFX_ERROR; - } - - itimer.it_value.tv_sec = 0; - itimer.it_value.tv_usec = 0; - itimer.it_interval = itimer.it_value; - - setitimer(ITIMER_REAL, &itimer, NULL); /* Stop timer */ - signal(SIGALRM, SIG_DFL); - - return SFX_OK; -} - - -static int -sigalrm_block(void) { - if (sigprocmask(SIG_BLOCK, ¤t_sigset, NULL) != 0) { - fprintf(stderr, "Error: Failed to block sigalrm\n"); - return SFX_ERROR; - } - - return SFX_OK; -} - - -static int -sigalrm_unblock(void) { - if (sigprocmask(SIG_UNBLOCK, ¤t_sigset, NULL) != 0) { - fprintf(stderr, "Error: Failed to unblock sigalrm\n"); - return SFX_ERROR; - } - - return SFX_OK; -} - - -sfx_timer_t sfx_timer_sigalrm = { - "sigalrm", - "0.1", - 17, /* 1000 / 60 */ - 0, - &sigalrm_set_option, - &sigalrm_init, - &sigalrm_stop, - &sigalrm_block, - &sigalrm_unblock -}; - -#endif /* HAVE_SETITIMER */ diff --git a/engines/sci/sfx/timer/timer_scummvm.cpp b/engines/sci/sfx/timer/timer_scummvm.cpp deleted file mode 100644 index beb57aef6b..0000000000 --- a/engines/sci/sfx/timer/timer_scummvm.cpp +++ /dev/null @@ -1,54 +0,0 @@ -#include "common/timer.h" -#include "engines/engine.h" -#include "sci/include/sfx_timer.h" - - -#define FREQ 60 -#define DELAY (1000000 / FREQ) - -typedef void (*scummvm_timer_callback_t)(void *); -static scummvm_timer_callback_t scummvm_timer_callback = NULL; -static void *scummvm_timer_callback_data = NULL; -extern ::Engine *g_engine; - -void scummvm_timer_update_internal(void *ptr) { - if (scummvm_timer_callback) - scummvm_timer_callback(scummvm_timer_callback_data); -} - -int scummvm_timer_start(void (*func)(void *), void *data) { - if (scummvm_timer_callback) { - fprintf(stderr, - "Error: Attempt to initialize gametick timer more than once\n"); - return SFX_ERROR; - } - - if (!func) { - fprintf(stderr, - "Error: Attempt to initialize gametick timer w/o callback\n"); - return SFX_ERROR; - } - - scummvm_timer_callback = func; - scummvm_timer_callback_data = data; - - ::g_engine->getTimerManager()->installTimerProc(&scummvm_timer_update_internal, DELAY, NULL); - return SFX_OK; -} - -int scummvm_timer_stop() { - scummvm_timer_callback = NULL; - return SFX_OK; -} - - -sfx_timer_t sfx_timer_scummvm = { - "ScummVM", - "0.1", - DELAY / 1000, 0, - NULL, - &scummvm_timer_start, - &scummvm_timer_stop, - 0, - 0 -}; diff --git a/engines/sci/sfx/timer/timers.cpp b/engines/sci/sfx/timer/timers.cpp deleted file mode 100644 index 82a1d11d6c..0000000000 --- a/engines/sci/sfx/timer/timers.cpp +++ /dev/null @@ -1,52 +0,0 @@ -/*************************************************************************** - timers.c Copyright (C) 2002 Christoph Reichenbach - - - This program may be modified and copied freely according to the terms of - the GNU general public license (GPL), as long as the above copyright - notice and the licensing information contained herein are preserved. - - Please refer to www.gnu.org for licensing details. - - This work is provided AS IS, without warranty of any kind, expressed or - implied, including but not limited to the warranties of merchantibility, - noninfringement, and fitness for a specific purpose. The author will not - be held liable for any damage caused by this work or derivatives of it. - - By using this source code, you agree to the licensing terms as stated - above. - - - Please contact the maintainer for bug reports or inquiries. - - Current Maintainer: - - Christoph Reichenbach (CR) - -***************************************************************************/ - -#include "sci/include/sfx_timer.h" -#include "sci/include/resource.h" - -extern sfx_timer_t sfx_timer_scummvm; - -sfx_timer_t *sfx_timers[] = { - &sfx_timer_scummvm, - NULL -}; - - -sfx_timer_t * -sfx_find_timer(char *name) { - if (!name) { - /* Policies go here */ - return sfx_timers[0]; - } else { - int n = 0; - while (sfx_timers[n] - && scumm_stricmp(sfx_timers[n]->name, name)) - ++n; - - return sfx_timers[n]; - } -} -- cgit v1.2.3