SCI: Turned sfx_player_t into a class SfxPlayer, and converted the existing players to subclasses of that
svn-id: r40912
This commit is contained in:
parent
c5539b4e4e
commit
1d00cc5df0
10 changed files with 138 additions and 192 deletions
|
@ -64,7 +64,6 @@ MODULE_OBJS = \
|
||||||
sfx/songlib.o \
|
sfx/songlib.o \
|
||||||
sfx/device/devices.o \
|
sfx/device/devices.o \
|
||||||
sfx/player/new_player.o \
|
sfx/player/new_player.o \
|
||||||
sfx/player/players.o \
|
|
||||||
sfx/player/polled.o \
|
sfx/player/polled.o \
|
||||||
sfx/player/realtime.o \
|
sfx/player/realtime.o \
|
||||||
sfx/seq/gm.o \
|
sfx/seq/gm.o \
|
||||||
|
|
|
@ -27,7 +27,9 @@
|
||||||
|
|
||||||
#include "sci/tools.h"
|
#include "sci/tools.h"
|
||||||
#include "sci/sfx/core.h"
|
#include "sci/sfx/core.h"
|
||||||
#include "sci/sfx/player.h"
|
#include "sci/sfx/player/new_player.h"
|
||||||
|
#include "sci/sfx/player/polled.h"
|
||||||
|
#include "sci/sfx/player/realtime.h"
|
||||||
#include "sci/sfx/sci_midi.h"
|
#include "sci/sfx/sci_midi.h"
|
||||||
|
|
||||||
#include "common/system.h"
|
#include "common/system.h"
|
||||||
|
@ -44,7 +46,7 @@ namespace Sci {
|
||||||
int sciprintf(char *msg, ...);
|
int sciprintf(char *msg, ...);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static sfx_player_t *player = NULL;
|
SfxPlayer *player = NULL; // FIXME: Avoid static vars
|
||||||
|
|
||||||
|
|
||||||
int sfx_pcm_available() {
|
int sfx_pcm_available() {
|
||||||
|
@ -56,13 +58,6 @@ void sfx_reset_player() {
|
||||||
player->stop();
|
player->stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
tell_synth_func *sfx_get_player_tell_func() {
|
|
||||||
if (player)
|
|
||||||
return player->tell_synth;
|
|
||||||
else
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sfx_get_player_polyphony() {
|
int sfx_get_player_polyphony() {
|
||||||
if (player)
|
if (player)
|
||||||
return player->polyphony;
|
return player->polyphony;
|
||||||
|
@ -306,8 +301,7 @@ static void _update_multi_song(sfx_state_t *self) {
|
||||||
sciprintf("[SFX] Stopping song %lx\n", oldseeker->handle);
|
sciprintf("[SFX] Stopping song %lx\n", oldseeker->handle);
|
||||||
}
|
}
|
||||||
if (player && oldseeker->it)
|
if (player && oldseeker->it)
|
||||||
player->iterator_message
|
player->iterator_message(SongIterator::Message(oldseeker->it->ID, SIMSG_STOP));
|
||||||
(SongIterator::Message(oldseeker->it->ID, SIMSG_STOP));
|
|
||||||
oldseeker->next_playing = NULL; /* Clear this pointer; we don't need the tag anymore */
|
oldseeker->next_playing = NULL; /* Clear this pointer; we don't need the tag anymore */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -352,7 +346,6 @@ int sfx_play_iterator_pcm(SongIterator *it, song_handle_t handle) {
|
||||||
|
|
||||||
#define DELAY (1000000 / SFX_TICKS_PER_SEC)
|
#define DELAY (1000000 / SFX_TICKS_PER_SEC)
|
||||||
|
|
||||||
|
|
||||||
static void _sfx_timer_callback(void *data) {
|
static void _sfx_timer_callback(void *data) {
|
||||||
/* First run the player, to give it a chance to fill
|
/* First run the player, to give it a chance to fill
|
||||||
** the audio buffer */
|
** the audio buffer */
|
||||||
|
@ -375,7 +368,10 @@ void sfx_init(sfx_state_t *self, ResourceManager *resmgr, int flags) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
player = sfx_find_player(NULL);
|
// TODO: Implement platform policy here?
|
||||||
|
player = new NewPlayer();
|
||||||
|
//player = new PolledPlayer();
|
||||||
|
//player = new RealtimePlayer();
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG_SONG_API
|
#ifdef DEBUG_SONG_API
|
||||||
|
@ -391,6 +387,7 @@ void sfx_init(sfx_state_t *self, ResourceManager *resmgr, int flags) {
|
||||||
player = NULL;
|
player = NULL;
|
||||||
} else if (player->init(resmgr, DELAY / 1000)) {
|
} else if (player->init(resmgr, DELAY / 1000)) {
|
||||||
sciprintf("[SFX] Song player '%s' reported error, disabled\n", player->name);
|
sciprintf("[SFX] Song player '%s' reported error, disabled\n", player->name);
|
||||||
|
delete player;
|
||||||
player = NULL;
|
player = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -406,16 +403,15 @@ void sfx_init(sfx_state_t *self, ResourceManager *resmgr, int flags) {
|
||||||
// We initialise the timer last, so there is no possibility of the
|
// We initialise the timer last, so there is no possibility of the
|
||||||
// timer callback being triggered while the mixer or player are
|
// timer callback being triggered while the mixer or player are
|
||||||
// still being initialized.
|
// still being initialized.
|
||||||
|
if (strcmp(player->name, "realtime") == 0) {
|
||||||
if (g_system->getMixer()->isReady() || (player && player->maintenance)) {
|
// FIXME: Merge this timer code into RealtimePlayer itself
|
||||||
if (!g_system->getTimerManager()->installTimerProc(&_sfx_timer_callback, DELAY, NULL)) {
|
if (!g_system->getTimerManager()->installTimerProc(&_sfx_timer_callback, DELAY, NULL)) {
|
||||||
warning("[SFX] " __FILE__": Timer failed to initialize");
|
warning("[SFX] " __FILE__": Timer failed to initialize");
|
||||||
warning("[SFX] Disabled sound support");
|
warning("[SFX] Disabled sound support");
|
||||||
|
delete player;
|
||||||
player = NULL;
|
player = NULL;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
} /* With no PCM device and no player, we don't need a timer */
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfx_exit(sfx_state_t *self) {
|
void sfx_exit(sfx_state_t *self) {
|
||||||
|
@ -429,8 +425,6 @@ void sfx_exit(sfx_state_t *self) {
|
||||||
fprintf(stderr, "[sfx-core] Uninitialising\n");
|
fprintf(stderr, "[sfx-core] Uninitialising\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
song_lib_free(self->songlib);
|
|
||||||
|
|
||||||
// WARNING: The mixer may hold feeds from the player, so we must
|
// WARNING: The mixer may hold feeds from the player, so we must
|
||||||
// stop the mixer BEFORE stopping the player.
|
// stop the mixer BEFORE stopping the player.
|
||||||
// FIXME Player "new" frees its own feeds, so we only need to stop any
|
// FIXME Player "new" frees its own feeds, so we only need to stop any
|
||||||
|
@ -438,13 +432,19 @@ void sfx_exit(sfx_state_t *self) {
|
||||||
if (strcmp(player->name, "new") != 0)
|
if (strcmp(player->name, "new") != 0)
|
||||||
g_system->getMixer()->stopAll();
|
g_system->getMixer()->stopAll();
|
||||||
|
|
||||||
if (player)
|
// FIXME: change players to stop their own audio streams
|
||||||
|
if (player) {
|
||||||
// See above: This must happen AFTER stopping the mixer
|
// See above: This must happen AFTER stopping the mixer
|
||||||
player->exit();
|
player->exit();
|
||||||
|
delete player;
|
||||||
|
player = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (strcmp(player->name, "new") == 0)
|
if (strcmp(player->name, "new") == 0)
|
||||||
g_system->getMixer()->stopAll();
|
g_system->getMixer()->stopAll();
|
||||||
|
|
||||||
|
song_lib_free(self->songlib);
|
||||||
|
|
||||||
// Delete audio resources for CD talkie games
|
// Delete audio resources for CD talkie games
|
||||||
if (self->audioResource) {
|
if (self->audioResource) {
|
||||||
delete self->audioResource;
|
delete self->audioResource;
|
||||||
|
@ -715,7 +715,6 @@ static const song_handle_t midi_send_base = 0xffff0000;
|
||||||
Common::Error sfx_send_midi(sfx_state_t *self, song_handle_t handle, int channel,
|
Common::Error sfx_send_midi(sfx_state_t *self, song_handle_t handle, int channel,
|
||||||
int command, int arg1, int arg2) {
|
int command, int arg1, int arg2) {
|
||||||
byte buffer[5];
|
byte buffer[5];
|
||||||
tell_synth_func *tell = sfx_get_player_tell_func();
|
|
||||||
|
|
||||||
/* Yes, in that order. SCI channel mutes are actually done via
|
/* Yes, in that order. SCI channel mutes are actually done via
|
||||||
a counting semaphore. 0 means to decrement the counter, 1
|
a counting semaphore. 0 means to decrement the counter, 1
|
||||||
|
@ -753,8 +752,8 @@ Common::Error sfx_send_midi(sfx_state_t *self, song_handle_t handle, int channel
|
||||||
return Common::kUnknownError;
|
return Common::kUnknownError;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tell)
|
if (player)
|
||||||
tell(MIDI_cmdlen[command >> 4], buffer);
|
player->tell_synth(MIDI_cmdlen[command >> 4], buffer);
|
||||||
return Common::kNoError;
|
return Common::kNoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -127,22 +127,22 @@ void SongIteratorChannel::init(int id_, int offset_, int end_) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SongIteratorChannel::resetSynthChannels() {
|
void SongIteratorChannel::resetSynthChannels() {
|
||||||
|
extern SfxPlayer *player; // FIXME
|
||||||
byte buf[5];
|
byte buf[5];
|
||||||
tell_synth_func *tell = sfx_get_player_tell_func();
|
|
||||||
|
|
||||||
for (int i = 0; i < MIDI_CHANNELS; i++) {
|
for (int i = 0; i < MIDI_CHANNELS; i++) {
|
||||||
if (playmask & (1 << i)) {
|
if (playmask & (1 << i)) {
|
||||||
buf[0] = 0xe0 | i; /* Pitch bend */
|
buf[0] = 0xe0 | i; /* Pitch bend */
|
||||||
buf[1] = 0x80; /* Wheel center */
|
buf[1] = 0x80; /* Wheel center */
|
||||||
buf[2] = 0x40;
|
buf[2] = 0x40;
|
||||||
if (tell)
|
if (player)
|
||||||
tell(3, buf);
|
player->tell_synth(3, buf);
|
||||||
|
|
||||||
buf[0] = 0xb0 | i; // Set control
|
buf[0] = 0xb0 | i; // Set control
|
||||||
buf[1] = 0x40; // Hold pedal
|
buf[1] = 0x40; // Hold pedal
|
||||||
buf[2] = 0x00; // Off
|
buf[2] = 0x00; // Off
|
||||||
if (tell)
|
if (player)
|
||||||
tell(3, buf);
|
player->tell_synth(3, buf);
|
||||||
/* TODO: Reset other controls? */
|
/* TODO: Reset other controls? */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,20 +35,19 @@
|
||||||
|
|
||||||
namespace Sci {
|
namespace Sci {
|
||||||
|
|
||||||
typedef void tell_synth_func(int buf_nr, byte *buf);
|
class SfxPlayer {
|
||||||
|
public:
|
||||||
struct sfx_player_t {
|
|
||||||
const char *name;
|
const char *name;
|
||||||
const char *version;
|
const char *version;
|
||||||
|
|
||||||
Common::Error (*set_option)(char *name, char *value);
|
/** Number of voices that can play simultaneously */
|
||||||
/* Sets an option for player timing mechanism
|
int polyphony;
|
||||||
** Parameters: (char *) name: The name describing what to set
|
|
||||||
** (char *) value: The value to set
|
|
||||||
** Returns : (int) Common::kNoError, or Common::kUnknownError if the name wasn't understood
|
|
||||||
*/
|
|
||||||
|
|
||||||
Common::Error (*init)(ResourceManager *resmgr, int expected_latency);
|
public:
|
||||||
|
SfxPlayer() : name(0), version(0), polyphony(0) {}
|
||||||
|
virtual ~SfxPlayer() {}
|
||||||
|
|
||||||
|
virtual Common::Error init(ResourceManager *resmgr, int expected_latency) = 0;
|
||||||
/* Initializes the player
|
/* Initializes the player
|
||||||
** Parameters: (ResourceManager *) resmgr: A resource manager for driver initialization
|
** Parameters: (ResourceManager *) resmgr: A resource manager for driver initialization
|
||||||
** (int) expected_latency: Expected delay in between calls to 'maintenance'
|
** (int) expected_latency: Expected delay in between calls to 'maintenance'
|
||||||
|
@ -56,7 +55,7 @@ struct sfx_player_t {
|
||||||
** Returns : (int) Common::kNoError on success, Common::kUnknownError on failure
|
** Returns : (int) Common::kNoError on success, Common::kUnknownError on failure
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Common::Error (*add_iterator)(SongIterator *it, uint32 start_time);
|
virtual Common::Error add_iterator(SongIterator *it, uint32 start_time) = 0;
|
||||||
/* Adds an iterator to the song player
|
/* Adds an iterator to the song player
|
||||||
** Parameters: (songx_iterator_t *) it: The iterator to play
|
** Parameters: (songx_iterator_t *) it: The iterator to play
|
||||||
** (uint32) start_time: The time to assume as the
|
** (uint32) start_time: The time to assume as the
|
||||||
|
@ -68,17 +67,12 @@ struct sfx_player_t {
|
||||||
** to add iterators onto their already existing iterators
|
** to add iterators onto their already existing iterators
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Common::Error (*fade_out)();
|
virtual Common::Error stop() = 0;
|
||||||
/* Fades out the currently playing song (within two seconds
|
|
||||||
** Returns : (int) Common::kNoError on success, Common::kUnknownError on failure
|
|
||||||
*/
|
|
||||||
|
|
||||||
Common::Error (*stop)();
|
|
||||||
/* Stops the currently playing song and deletes the associated iterator
|
/* Stops the currently playing song and deletes the associated iterator
|
||||||
** Returns : (int) Common::kNoError on success, Common::kUnknownError on failure
|
** Returns : (int) Common::kNoError on success, Common::kUnknownError on failure
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Common::Error (*iterator_message)(const SongIterator::Message &msg);
|
virtual Common::Error iterator_message(const SongIterator::Message &msg) = 0;
|
||||||
/* Transmits a song iterator message to the active song
|
/* Transmits a song iterator message to the active song
|
||||||
** Parameters: (SongIterator::Message) msg: The message to transmit
|
** Parameters: (SongIterator::Message) msg: The message to transmit
|
||||||
** Returns : (int) Common::kNoError on success, Common::kUnknownError on failure
|
** Returns : (int) Common::kNoError on success, Common::kUnknownError on failure
|
||||||
|
@ -87,48 +81,34 @@ struct sfx_player_t {
|
||||||
** and re-start playing, so it is preferred that it is present
|
** and re-start playing, so it is preferred that it is present
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Common::Error (*pause)(); /* OPTIONAL -- may be NULL */
|
virtual Common::Error pause() = 0;
|
||||||
/* Pauses song playing
|
/* Pauses song playing
|
||||||
** Returns : (int) Common::kNoError on success, Common::kUnknownError on failure
|
** Returns : (int) Common::kNoError on success, Common::kUnknownError on failure
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Common::Error (*resume)(); /* OPTIONAL -- may be NULL */
|
virtual Common::Error resume() = 0;
|
||||||
/* Resumes song playing after a pause
|
/* Resumes song playing after a pause
|
||||||
** Returns : (int) Common::kNoError on success, Common::kUnknownError on failure
|
** Returns : (int) Common::kNoError on success, Common::kUnknownError on failure
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Common::Error (*exit)();
|
virtual Common::Error exit() = 0;
|
||||||
/* Stops the player
|
/* Stops the player
|
||||||
** Returns : (int) Common::kNoError on success, Common::kUnknownError on failure
|
** Returns : (int) Common::kNoError on success, Common::kUnknownError on failure
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void (*maintenance)(); /* OPTIONAL -- may be NULL */
|
virtual void maintenance() {}
|
||||||
/* Regularly called maintenance function
|
/* Regularly called maintenance function
|
||||||
** This function is called frequently and regularly (if present), it can be
|
** This function is called frequently and regularly (if present), it can be
|
||||||
** used to emit sound.
|
** used to emit sound.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
tell_synth_func *tell_synth;
|
virtual void tell_synth(int buf_nr, byte *buf) = 0;
|
||||||
/* Pass a raw MIDI event to the synth
|
/* Pass a raw MIDI event to the synth
|
||||||
Parameters: (int) argc: Length of buffer holding the midi event
|
Parameters: (int) argc: Length of buffer holding the midi event
|
||||||
(byte *) argv: The buffer itself
|
(byte *) argv: The buffer itself
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int polyphony; /* Number of voices that can play simultaneously */
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
sfx_player_t *sfx_find_player(char *name);
|
|
||||||
/* Looks up a player by name or finds the default player
|
|
||||||
** Parameters: (char *) name: Name of the player to look up, or NULL for dedault
|
|
||||||
** Returns : (sfx_player_t *) The player requested, or NULL if none was found
|
|
||||||
*/
|
|
||||||
|
|
||||||
tell_synth_func *sfx_get_player_tell_func();
|
|
||||||
/* Gets the callback function of the player in use.
|
|
||||||
** Returns: (tell_synth_func *) The callback function.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int sfx_get_player_polyphony();
|
int sfx_get_player_polyphony();
|
||||||
/* Determines the polyphony of the player in use
|
/* Determines the polyphony of the player in use
|
||||||
** Returns : (int) Number of voices the active player can emit
|
** Returns : (int) Number of voices the active player can emit
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
|
|
||||||
namespace Sci {
|
namespace Sci {
|
||||||
|
|
||||||
|
// TODO: Turn the following static vars into member vars
|
||||||
static MidiPlayer *mididrv;
|
static MidiPlayer *mididrv;
|
||||||
|
|
||||||
static SongIterator *play_it = NULL;
|
static SongIterator *play_it = NULL;
|
||||||
|
@ -89,7 +90,7 @@ static void play_song(SongIterator *it) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void player_tell_synth(int buf_nr, byte *buf) {
|
void NewPlayer::tell_synth(int buf_nr, byte *buf) {
|
||||||
byte op1 = (buf_nr < 2 ? 0 : buf[1]);
|
byte op1 = (buf_nr < 2 ? 0 : buf[1]);
|
||||||
byte op2 = (buf_nr < 3 ? 0 : buf[2]);
|
byte op2 = (buf_nr < 3 ? 0 : buf[2]);
|
||||||
|
|
||||||
|
@ -97,25 +98,18 @@ static void player_tell_synth(int buf_nr, byte *buf) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void player_timer_callback(void *refCon) {
|
static void player_timer_callback(void *refCon) {
|
||||||
mutex->lock();
|
Common::StackLock lock(*mutex);
|
||||||
|
|
||||||
if (play_it && !play_it_done && !play_paused) {
|
if (play_it && !play_it_done && !play_paused) {
|
||||||
play_song(play_it);
|
play_song(play_it);
|
||||||
}
|
}
|
||||||
|
|
||||||
current_time = current_time.addFrames(1);
|
current_time = current_time.addFrames(1);
|
||||||
mutex->unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void player_void_callback(void) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* API implementation */
|
/* API implementation */
|
||||||
|
|
||||||
static Common::Error player_set_option(char *name, char *value) {
|
Common::Error NewPlayer::init(ResourceManager *resmgr, int expected_latency) {
|
||||||
return Common::kUnknownError;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Common::Error player_init(ResourceManager *resmgr, int expected_latency) {
|
|
||||||
MidiDriverType musicDriver = MidiDriver::detectMusicDriver(MDT_PCSPK | MDT_ADLIB);
|
MidiDriverType musicDriver = MidiDriver::detectMusicDriver(MDT_PCSPK | MDT_ADLIB);
|
||||||
|
|
||||||
switch(musicDriver) {
|
switch(musicDriver) {
|
||||||
|
@ -134,7 +128,7 @@ static Common::Error player_init(ResourceManager *resmgr, int expected_latency)
|
||||||
|
|
||||||
assert(mididrv);
|
assert(mididrv);
|
||||||
|
|
||||||
sfx_new_player.polyphony = mididrv->getPolyphony();
|
this->polyphony = mididrv->getPolyphony();
|
||||||
|
|
||||||
tempo = mididrv->getBaseTempo();
|
tempo = mididrv->getBaseTempo();
|
||||||
uint32 time = g_system->getMillis();
|
uint32 time = g_system->getMillis();
|
||||||
|
@ -150,7 +144,7 @@ static Common::Error player_init(ResourceManager *resmgr, int expected_latency)
|
||||||
return Common::kNoError;
|
return Common::kNoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Common::Error player_add_iterator(SongIterator *it, uint32 start_time) {
|
Common::Error NewPlayer::add_iterator(SongIterator *it, uint32 start_time) {
|
||||||
mutex->lock();
|
mutex->lock();
|
||||||
SIMSG_SEND(it, SIMSG_SET_PLAYMASK(mididrv->getPlayMask()));
|
SIMSG_SEND(it, SIMSG_SET_PLAYMASK(mididrv->getPlayMask()));
|
||||||
SIMSG_SEND(it, SIMSG_SET_RHYTHM(mididrv->hasRhythmChannel()));
|
SIMSG_SEND(it, SIMSG_SET_RHYTHM(mididrv->hasRhythmChannel()));
|
||||||
|
@ -168,12 +162,7 @@ static Common::Error player_add_iterator(SongIterator *it, uint32 start_time) {
|
||||||
return Common::kNoError;
|
return Common::kNoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Common::Error player_fade_out(void) {
|
Common::Error NewPlayer::stop(void) {
|
||||||
warning("Attempt to fade out - not implemented yet");
|
|
||||||
return Common::kUnknownError;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Common::Error player_stop(void) {
|
|
||||||
debug(3, "Player: Stopping song iterator %p", (void *)play_it);
|
debug(3, "Player: Stopping song iterator %p", (void *)play_it);
|
||||||
mutex->lock();
|
mutex->lock();
|
||||||
delete play_it;
|
delete play_it;
|
||||||
|
@ -185,41 +174,39 @@ static Common::Error player_stop(void) {
|
||||||
return Common::kNoError;
|
return Common::kNoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Common::Error player_send_iterator_message(const SongIterator::Message &msg) {
|
Common::Error NewPlayer::iterator_message(const SongIterator::Message &msg) {
|
||||||
mutex->lock();
|
Common::StackLock lock(*mutex);
|
||||||
if (!play_it) {
|
if (!play_it) {
|
||||||
mutex->unlock();
|
|
||||||
return Common::kUnknownError;
|
return Common::kUnknownError;
|
||||||
}
|
}
|
||||||
|
|
||||||
songit_handle_message(&play_it, msg);
|
songit_handle_message(&play_it, msg);
|
||||||
mutex->unlock();
|
|
||||||
|
|
||||||
return Common::kNoError;
|
return Common::kNoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Common::Error player_pause(void) {
|
Common::Error NewPlayer::pause(void) {
|
||||||
mutex->lock();
|
Common::StackLock lock(*mutex);
|
||||||
|
|
||||||
play_paused = 1;
|
play_paused = 1;
|
||||||
play_pause_diff = wakeup_time.msecsDiff(current_time);
|
play_pause_diff = wakeup_time.msecsDiff(current_time);
|
||||||
|
|
||||||
mididrv->playSwitch(false);
|
mididrv->playSwitch(false);
|
||||||
mutex->unlock();
|
|
||||||
|
|
||||||
return Common::kNoError;
|
return Common::kNoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Common::Error player_resume(void) {
|
Common::Error NewPlayer::resume(void) {
|
||||||
mutex->lock();
|
Common::StackLock lock(*mutex);
|
||||||
|
|
||||||
wakeup_time = Audio::Timestamp(current_time.msecs() + play_pause_diff, SFX_TICKS_PER_SEC);
|
wakeup_time = Audio::Timestamp(current_time.msecs() + play_pause_diff, SFX_TICKS_PER_SEC);
|
||||||
mididrv->playSwitch(true);
|
mididrv->playSwitch(true);
|
||||||
play_paused = 0;
|
play_paused = 0;
|
||||||
mutex->unlock();
|
|
||||||
|
|
||||||
return Common::kNoError;
|
return Common::kNoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Common::Error player_exit(void) {
|
Common::Error NewPlayer::exit(void) {
|
||||||
mididrv->close();
|
mididrv->close();
|
||||||
delete mididrv;
|
delete mididrv;
|
||||||
delete mutex;
|
delete mutex;
|
||||||
|
@ -229,22 +216,9 @@ static Common::Error player_exit(void) {
|
||||||
return Common::kNoError;
|
return Common::kNoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
sfx_player_t sfx_new_player = {
|
NewPlayer::NewPlayer() {
|
||||||
"new",
|
name = "new";
|
||||||
"0.1",
|
version = "0.1";
|
||||||
&player_set_option,
|
}
|
||||||
&player_init,
|
|
||||||
&player_add_iterator,
|
|
||||||
&player_fade_out,
|
|
||||||
&player_stop,
|
|
||||||
&player_send_iterator_message,
|
|
||||||
&player_pause,
|
|
||||||
&player_resume,
|
|
||||||
&player_exit,
|
|
||||||
&player_void_callback,
|
|
||||||
&player_tell_synth,
|
|
||||||
0 /* polyphony */
|
|
||||||
};
|
|
||||||
|
|
||||||
} // End of namespace Sci
|
} // End of namespace Sci
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,19 @@
|
||||||
|
|
||||||
namespace Sci {
|
namespace Sci {
|
||||||
|
|
||||||
extern sfx_player_t sfx_new_player;
|
class NewPlayer : public SfxPlayer {
|
||||||
|
public:
|
||||||
|
NewPlayer();
|
||||||
|
|
||||||
|
virtual Common::Error init(ResourceManager *resmgr, int expected_latency);
|
||||||
|
virtual Common::Error add_iterator(SongIterator *it, uint32 start_time);
|
||||||
|
virtual Common::Error stop();
|
||||||
|
virtual Common::Error iterator_message(const SongIterator::Message &msg);
|
||||||
|
virtual Common::Error pause();
|
||||||
|
virtual Common::Error resume();
|
||||||
|
virtual Common::Error exit();
|
||||||
|
virtual void tell_synth(int buf_nr, byte *buf);
|
||||||
|
};
|
||||||
|
|
||||||
} // End of namespace Sci
|
} // End of namespace Sci
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
|
|
||||||
namespace Sci {
|
namespace Sci {
|
||||||
|
|
||||||
|
// TODO: Turn the following static vars into member vars
|
||||||
static SongIterator *play_it;
|
static SongIterator *play_it;
|
||||||
static int play_paused = 0;
|
static int play_paused = 0;
|
||||||
static sfx_softseq_t *seq;
|
static sfx_softseq_t *seq;
|
||||||
|
@ -48,7 +49,7 @@ static int new_song = 0;
|
||||||
#define TIME_INC 60
|
#define TIME_INC 60
|
||||||
static int time_counter = 0;
|
static int time_counter = 0;
|
||||||
|
|
||||||
static void pp_tell_synth(int buf_nr, byte *buf) {
|
void PolledPlayer::tell_synth(int buf_nr, byte *buf) {
|
||||||
seq->handle_command(seq, buf[0], buf_nr - 1, buf + 1);
|
seq->handle_command(seq, buf[0], buf_nr - 1, buf + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,15 +263,7 @@ static int ppf_poll(int frame_size, byte *dest, int size) {
|
||||||
/* API implementation */
|
/* API implementation */
|
||||||
/*--------------------*/
|
/*--------------------*/
|
||||||
|
|
||||||
static void pp_timer_callback() {
|
Common::Error PolledPlayer::init(ResourceManager *resmgr, int expected_latency) {
|
||||||
/* Hey, we're polled anyway ;-) */
|
|
||||||
}
|
|
||||||
|
|
||||||
static Common::Error pp_set_option(char *name, char *value) {
|
|
||||||
return Common::kUnknownError;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Common::Error pp_init(ResourceManager *resmgr, int expected_latency) {
|
|
||||||
if (!g_system->getMixer()->isReady())
|
if (!g_system->getMixer()->isReady())
|
||||||
return Common::kUnknownError;
|
return Common::kUnknownError;
|
||||||
|
|
||||||
|
@ -307,15 +300,16 @@ static Common::Error pp_init(ResourceManager *resmgr, int expected_latency) {
|
||||||
|
|
||||||
seq->set_volume(seq, volume);
|
seq->set_volume(seq, volume);
|
||||||
|
|
||||||
|
// FIXME: Keep a SoundHandle and use that to stop the feed in the exit method
|
||||||
PolledPlayerAudioStream *newStream = new PolledPlayerAudioStream(seq->pcm_conf);
|
PolledPlayerAudioStream *newStream = new PolledPlayerAudioStream(seq->pcm_conf);
|
||||||
// FIXME: Is this sound type appropriate?
|
// FIXME: Is this sound type appropriate?
|
||||||
g_system->getMixer()->playInputStream(Audio::Mixer::kSFXSoundType, 0, newStream);
|
g_system->getMixer()->playInputStream(Audio::Mixer::kSFXSoundType, 0, newStream);
|
||||||
|
|
||||||
sfx_player_polled.polyphony = seq->polyphony;
|
this->polyphony = seq->polyphony;
|
||||||
return Common::kNoError;
|
return Common::kNoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Common::Error pp_add_iterator(SongIterator *it, uint32 start_time) {
|
Common::Error PolledPlayer::add_iterator(SongIterator *it, uint32 start_time) {
|
||||||
SongIterator *old = play_it;
|
SongIterator *old = play_it;
|
||||||
|
|
||||||
SIMSG_SEND(it, SIMSG_SET_PLAYMASK(seq->playmask));
|
SIMSG_SEND(it, SIMSG_SET_PLAYMASK(seq->playmask));
|
||||||
|
@ -340,12 +334,7 @@ static Common::Error pp_add_iterator(SongIterator *it, uint32 start_time) {
|
||||||
return Common::kNoError;
|
return Common::kNoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Common::Error pp_fade_out() {
|
Common::Error PolledPlayer::stop() {
|
||||||
warning(__FILE__": Attempt to fade out- not implemented yet");
|
|
||||||
return Common::kUnknownError;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Common::Error pp_stop() {
|
|
||||||
SongIterator *it = play_it;
|
SongIterator *it = play_it;
|
||||||
|
|
||||||
play_it = NULL;
|
play_it = NULL;
|
||||||
|
@ -357,7 +346,7 @@ static Common::Error pp_stop() {
|
||||||
return Common::kNoError;
|
return Common::kNoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Common::Error pp_send_iterator_message(const SongIterator::Message &msg) {
|
Common::Error PolledPlayer::iterator_message(const SongIterator::Message &msg) {
|
||||||
if (!play_it)
|
if (!play_it)
|
||||||
return Common::kUnknownError;
|
return Common::kUnknownError;
|
||||||
|
|
||||||
|
@ -365,14 +354,14 @@ static Common::Error pp_send_iterator_message(const SongIterator::Message &msg)
|
||||||
return Common::kNoError;
|
return Common::kNoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Common::Error pp_pause() {
|
Common::Error PolledPlayer::pause() {
|
||||||
play_paused = 1;
|
play_paused = 1;
|
||||||
seq->set_volume(seq, 0);
|
seq->set_volume(seq, 0);
|
||||||
|
|
||||||
return Common::kNoError;
|
return Common::kNoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Common::Error pp_resume() {
|
Common::Error PolledPlayer::resume() {
|
||||||
if (!play_it) {
|
if (!play_it) {
|
||||||
play_paused = 0;
|
play_paused = 0;
|
||||||
return Common::kNoError; /* Nothing to resume */
|
return Common::kNoError; /* Nothing to resume */
|
||||||
|
@ -388,7 +377,7 @@ static Common::Error pp_resume() {
|
||||||
return Common::kNoError;
|
return Common::kNoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Common::Error pp_exit() {
|
Common::Error PolledPlayer::exit() {
|
||||||
seq->exit(seq);
|
seq->exit(seq);
|
||||||
delete play_it;
|
delete play_it;
|
||||||
play_it = NULL;
|
play_it = NULL;
|
||||||
|
@ -396,21 +385,9 @@ static Common::Error pp_exit() {
|
||||||
return Common::kNoError;
|
return Common::kNoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
sfx_player_t sfx_player_polled = {
|
PolledPlayer::PolledPlayer() {
|
||||||
"polled",
|
name = "polled";
|
||||||
"0.1",
|
version = "0.1";
|
||||||
&pp_set_option,
|
}
|
||||||
&pp_init,
|
|
||||||
&pp_add_iterator,
|
|
||||||
&pp_fade_out,
|
|
||||||
&pp_stop,
|
|
||||||
&pp_send_iterator_message,
|
|
||||||
&pp_pause,
|
|
||||||
&pp_resume,
|
|
||||||
&pp_exit,
|
|
||||||
&pp_timer_callback,
|
|
||||||
&pp_tell_synth,
|
|
||||||
0 /* polyphony */
|
|
||||||
};
|
|
||||||
|
|
||||||
} // End of namespace Sci
|
} // End of namespace Sci
|
||||||
|
|
|
@ -30,7 +30,19 @@
|
||||||
|
|
||||||
namespace Sci {
|
namespace Sci {
|
||||||
|
|
||||||
extern sfx_player_t sfx_player_polled;
|
class PolledPlayer : public SfxPlayer {
|
||||||
|
public:
|
||||||
|
PolledPlayer();
|
||||||
|
|
||||||
|
virtual Common::Error init(ResourceManager *resmgr, int expected_latency);
|
||||||
|
virtual Common::Error add_iterator(SongIterator *it, uint32 start_time);
|
||||||
|
virtual Common::Error stop();
|
||||||
|
virtual Common::Error iterator_message(const SongIterator::Message &msg);
|
||||||
|
virtual Common::Error pause();
|
||||||
|
virtual Common::Error resume();
|
||||||
|
virtual Common::Error exit();
|
||||||
|
virtual void tell_synth(int buf_nr, byte *buf);
|
||||||
|
};
|
||||||
|
|
||||||
} // End of namespace Sci
|
} // End of namespace Sci
|
||||||
|
|
||||||
|
|
|
@ -37,14 +37,15 @@
|
||||||
|
|
||||||
namespace Sci {
|
namespace Sci {
|
||||||
|
|
||||||
static sfx_sequencer_t *seq;
|
|
||||||
|
|
||||||
/* Playing mechanism */
|
/* Playing mechanism */
|
||||||
|
|
||||||
static inline int delta_time(const uint32 comp, const uint32 base) {
|
static inline int delta_time(const uint32 comp, const uint32 base) {
|
||||||
return long(comp) - long(base);
|
return long(comp) - long(base);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Turn the following static vars into member vars
|
||||||
|
static sfx_sequencer_t *seq;
|
||||||
|
|
||||||
static SongIterator *play_it = NULL;
|
static SongIterator *play_it = NULL;
|
||||||
static uint32 play_last_time;
|
static uint32 play_last_time;
|
||||||
static uint32 play_pause_started; /* Beginning of the last pause */
|
static uint32 play_pause_started; /* Beginning of the last pause */
|
||||||
|
@ -105,11 +106,11 @@ static void play_song(SongIterator *it, uint32 *wakeup_time, int writeahead_time
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rt_tell_synth(int buf_nr, byte *buf) {
|
void RealtimePlayer::tell_synth(int buf_nr, byte *buf) {
|
||||||
seq->event(buf[0], buf_nr - 1, buf + 1);
|
seq->event(buf[0], buf_nr - 1, buf + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rt_timer_callback(void) {
|
void RealtimePlayer::maintenance() {
|
||||||
if (play_it && !play_it_done) {
|
if (play_it && !play_it_done) {
|
||||||
if (!play_moredelay) {
|
if (!play_moredelay) {
|
||||||
int delta = delta_time(play_last_time, g_system->getMillis());
|
int delta = delta_time(play_last_time, g_system->getMillis());
|
||||||
|
@ -145,11 +146,7 @@ static Resource *find_patch(ResourceManager *resmgr, const char *seq_name, int p
|
||||||
|
|
||||||
/* API implementation */
|
/* API implementation */
|
||||||
|
|
||||||
static Common::Error rt_set_option(char *name, char *value) {
|
Common::Error RealtimePlayer::init(ResourceManager *resmgr, int expected_latency) {
|
||||||
return Common::kUnknownError;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Common::Error rt_init(ResourceManager *resmgr, int expected_latency) {
|
|
||||||
Resource *res = NULL, *res2 = NULL;
|
Resource *res = NULL, *res2 = NULL;
|
||||||
void *seq_dev = NULL;
|
void *seq_dev = NULL;
|
||||||
|
|
||||||
|
@ -160,7 +157,7 @@ static Common::Error rt_init(ResourceManager *resmgr, int expected_latency) {
|
||||||
return Common::kUnknownError;
|
return Common::kUnknownError;
|
||||||
}
|
}
|
||||||
|
|
||||||
sfx_player_realtime.polyphony = seq->polyphony;
|
this->polyphony = seq->polyphony;
|
||||||
|
|
||||||
res = find_patch(resmgr, seq->name, seq->patchfile);
|
res = find_patch(resmgr, seq->name, seq->patchfile);
|
||||||
res2 = find_patch(resmgr, seq->name, seq->patchfile2);
|
res2 = find_patch(resmgr, seq->name, seq->patchfile2);
|
||||||
|
@ -189,7 +186,7 @@ static Common::Error rt_init(ResourceManager *resmgr, int expected_latency) {
|
||||||
return Common::kNoError;
|
return Common::kNoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Common::Error rt_add_iterator(SongIterator *it, uint32 start_time) {
|
Common::Error RealtimePlayer::add_iterator(SongIterator *it, uint32 start_time) {
|
||||||
if (seq->reset_timer) /* Restart timer counting if possible */
|
if (seq->reset_timer) /* Restart timer counting if possible */
|
||||||
seq->reset_timer(start_time);
|
seq->reset_timer(start_time);
|
||||||
|
|
||||||
|
@ -204,12 +201,7 @@ static Common::Error rt_add_iterator(SongIterator *it, uint32 start_time) {
|
||||||
return Common::kNoError;
|
return Common::kNoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Common::Error rt_fade_out(void) {
|
Common::Error RealtimePlayer::stop(void) {
|
||||||
warning(__FILE__": Attempt to fade out- not implemented yet");
|
|
||||||
return Common::kUnknownError;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Common::Error rt_stop(void) {
|
|
||||||
SongIterator *it = play_it;
|
SongIterator *it = play_it;
|
||||||
|
|
||||||
play_it = NULL;
|
play_it = NULL;
|
||||||
|
@ -221,7 +213,7 @@ static Common::Error rt_stop(void) {
|
||||||
return Common::kNoError;
|
return Common::kNoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Common::Error rt_send_iterator_message(const SongIterator::Message &msg) {
|
Common::Error RealtimePlayer::iterator_message(const SongIterator::Message &msg) {
|
||||||
if (!play_it)
|
if (!play_it)
|
||||||
return Common::kUnknownError;
|
return Common::kUnknownError;
|
||||||
|
|
||||||
|
@ -229,7 +221,7 @@ static Common::Error rt_send_iterator_message(const SongIterator::Message &msg)
|
||||||
return Common::kNoError;
|
return Common::kNoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Common::Error rt_pause(void) {
|
Common::Error RealtimePlayer::pause(void) {
|
||||||
play_pause_started = g_system->getMillis();
|
play_pause_started = g_system->getMillis();
|
||||||
// Also, indicate that we haven't modified the time counter yet
|
// Also, indicate that we haven't modified the time counter yet
|
||||||
play_pause_counter = play_pause_started;
|
play_pause_counter = play_pause_started;
|
||||||
|
@ -242,12 +234,12 @@ static Common::Error rt_pause(void) {
|
||||||
return seq->allstop();
|
return seq->allstop();
|
||||||
}
|
}
|
||||||
|
|
||||||
static Common::Error rt_resume(void) {
|
Common::Error RealtimePlayer::resume(void) {
|
||||||
play_paused = 0;
|
play_paused = 0;
|
||||||
return Common::kNoError;
|
return Common::kNoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Common::Error rt_exit(void) {
|
Common::Error RealtimePlayer::exit(void) {
|
||||||
if (seq->close()) {
|
if (seq->close()) {
|
||||||
warning("[SFX] Sequencer reported error on close");
|
warning("[SFX] Sequencer reported error on close");
|
||||||
return Common::kUnknownError;
|
return Common::kUnknownError;
|
||||||
|
@ -256,21 +248,9 @@ static Common::Error rt_exit(void) {
|
||||||
return Common::kNoError;
|
return Common::kNoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
sfx_player_t sfx_player_realtime = {
|
RealtimePlayer::RealtimePlayer() {
|
||||||
"realtime",
|
name = "realtime";
|
||||||
"0.1",
|
version = "0.1";
|
||||||
&rt_set_option,
|
}
|
||||||
&rt_init,
|
|
||||||
&rt_add_iterator,
|
|
||||||
&rt_fade_out,
|
|
||||||
&rt_stop,
|
|
||||||
&rt_send_iterator_message,
|
|
||||||
&rt_pause,
|
|
||||||
&rt_resume,
|
|
||||||
&rt_exit,
|
|
||||||
&rt_timer_callback,
|
|
||||||
&rt_tell_synth,
|
|
||||||
0 /* polyphony */
|
|
||||||
};
|
|
||||||
|
|
||||||
} // End of namespace Sci
|
} // End of namespace Sci
|
||||||
|
|
|
@ -30,7 +30,20 @@
|
||||||
|
|
||||||
namespace Sci {
|
namespace Sci {
|
||||||
|
|
||||||
extern sfx_player_t sfx_player_realtime;
|
class RealtimePlayer : public SfxPlayer {
|
||||||
|
public:
|
||||||
|
RealtimePlayer();
|
||||||
|
|
||||||
|
virtual Common::Error init(ResourceManager *resmgr, int expected_latency);
|
||||||
|
virtual Common::Error add_iterator(SongIterator *it, uint32 start_time);
|
||||||
|
virtual Common::Error stop();
|
||||||
|
virtual Common::Error iterator_message(const SongIterator::Message &msg);
|
||||||
|
virtual Common::Error pause();
|
||||||
|
virtual Common::Error resume();
|
||||||
|
virtual Common::Error exit();
|
||||||
|
virtual void maintenance();
|
||||||
|
virtual void tell_synth(int buf_nr, byte *buf);
|
||||||
|
};
|
||||||
|
|
||||||
} // End of namespace Sci
|
} // End of namespace Sci
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue