2009-02-17 15:07:44 +00:00
|
|
|
/* ScummVM - Graphic Adventure Engine
|
|
|
|
*
|
|
|
|
* ScummVM is the legal property of its developers, whose names
|
|
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
|
|
* file distributed with this source distribution.
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
*
|
|
|
|
* $URL$
|
|
|
|
* $Id$
|
|
|
|
*
|
|
|
|
*/
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-02-21 22:06:42 +00:00
|
|
|
#include "sci/tools.h"
|
|
|
|
#include "sci/sfx/sequencer.h"
|
|
|
|
#include "sci/sfx/device.h"
|
|
|
|
#include "sci/sfx/seq/instrument-map.h"
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-02-21 10:23:36 +00:00
|
|
|
namespace Sci {
|
|
|
|
|
2009-02-15 06:10:59 +00:00
|
|
|
static midi_writer_t *writer = NULL;
|
|
|
|
|
2009-02-27 12:59:02 +00:00
|
|
|
static int midi_gm_open(int patch_len, byte *data, int patch2_len, byte *data2, void *device) {
|
2009-02-15 06:10:59 +00:00
|
|
|
sfx_instrument_map_t *instrument_map = sfx_instrument_map_load_sci(data, patch_len);
|
|
|
|
|
|
|
|
if (!instrument_map) {
|
|
|
|
fprintf(stderr, "[GM] No GM instrument map found, trying MT-32 instrument map..\n");
|
|
|
|
instrument_map = sfx_instrument_map_mt32_to_gm(data2, patch2_len);
|
|
|
|
}
|
|
|
|
|
|
|
|
writer = sfx_mapped_writer((midi_writer_t *) device, instrument_map);
|
|
|
|
|
|
|
|
if (!writer)
|
|
|
|
return SFX_ERROR;
|
|
|
|
|
|
|
|
if (writer->reset_timer)
|
|
|
|
writer->reset_timer(writer);
|
|
|
|
|
|
|
|
return SFX_OK;
|
|
|
|
}
|
|
|
|
|
2009-02-27 12:59:02 +00:00
|
|
|
static int midi_gm_close(void) {
|
2009-02-15 06:10:59 +00:00
|
|
|
return SFX_OK;
|
|
|
|
}
|
|
|
|
|
2009-02-27 12:59:02 +00:00
|
|
|
static int midi_gm_event(byte command, int argc, byte *argv) {
|
2009-02-15 06:10:59 +00:00
|
|
|
byte data[4];
|
|
|
|
|
2009-02-15 22:34:41 +00:00
|
|
|
assert(argc < 4);
|
2009-02-15 06:10:59 +00:00
|
|
|
data[0] = command;
|
|
|
|
memcpy(data + 1, argv, argc);
|
|
|
|
|
|
|
|
writer->write(writer, data, argc + 1);
|
|
|
|
|
|
|
|
return SFX_OK;
|
|
|
|
}
|
|
|
|
|
2009-02-27 12:59:02 +00:00
|
|
|
static int midi_gm_delay(int ticks) {
|
2009-02-15 06:10:59 +00:00
|
|
|
writer->delay(writer, ticks);
|
|
|
|
|
|
|
|
return SFX_OK;
|
|
|
|
}
|
|
|
|
|
2009-02-27 12:59:02 +00:00
|
|
|
static int midi_gm_reset_timer(uint32 ts) {
|
2009-02-15 06:10:59 +00:00
|
|
|
writer->reset_timer(writer);
|
|
|
|
|
|
|
|
return SFX_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
#define MIDI_MASTER_VOLUME_LEN 8
|
|
|
|
|
2009-02-27 12:59:02 +00:00
|
|
|
static int midi_gm_volume(uint8 volume) {
|
2009-02-15 06:10:59 +00:00
|
|
|
byte data[MIDI_MASTER_VOLUME_LEN] = {
|
|
|
|
0xf0,
|
|
|
|
0x7f,
|
|
|
|
0x7f,
|
|
|
|
0x04,
|
|
|
|
0x01,
|
|
|
|
volume,
|
|
|
|
volume,
|
2009-02-15 22:34:41 +00:00
|
|
|
0xf7
|
|
|
|
};
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
writer->write(writer, data, MIDI_MASTER_VOLUME_LEN);
|
|
|
|
if (writer->flush)
|
|
|
|
writer->flush(writer);
|
|
|
|
|
|
|
|
return SFX_OK;
|
|
|
|
}
|
|
|
|
|
2009-02-27 12:59:02 +00:00
|
|
|
static int midi_gm_allstop(void) {
|
2009-02-15 06:10:59 +00:00
|
|
|
byte data[3] = { 0xb0,
|
2009-02-15 22:34:41 +00:00
|
|
|
0x78, /* all sound off */
|
|
|
|
0
|
|
|
|
};
|
2009-02-15 06:10:59 +00:00
|
|
|
int i;
|
|
|
|
|
|
|
|
/* All sound off on all channels */
|
|
|
|
for (i = 0; i < 16; i++) {
|
|
|
|
data[0] = 0xb0 | i;
|
|
|
|
writer->write(writer, data, 3);
|
|
|
|
}
|
|
|
|
if (writer->flush)
|
|
|
|
writer->flush(writer);
|
|
|
|
|
|
|
|
return SFX_OK;
|
|
|
|
}
|
|
|
|
|
2009-02-27 12:59:02 +00:00
|
|
|
static int midi_gm_reverb(int reverb) {
|
2009-02-15 06:10:59 +00:00
|
|
|
byte data[3] = { 0xb0,
|
2009-02-15 22:34:41 +00:00
|
|
|
91, /* set reverb */
|
|
|
|
reverb
|
|
|
|
};
|
2009-02-15 06:10:59 +00:00
|
|
|
int i;
|
|
|
|
|
|
|
|
/* Set reverb on all channels */
|
|
|
|
for (i = 0; i < 16; i++)
|
|
|
|
if (i != 9) {
|
|
|
|
data[0] = 0xb0 | i;
|
|
|
|
writer->write(writer, data, 3);
|
|
|
|
}
|
|
|
|
if (writer->flush)
|
|
|
|
writer->flush(writer);
|
|
|
|
|
|
|
|
return SFX_OK;
|
|
|
|
}
|
|
|
|
|
2009-02-27 12:59:02 +00:00
|
|
|
static int midi_gm_set_option(char *x, char *y) {
|
2009-02-15 06:10:59 +00:00
|
|
|
return SFX_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
sfx_sequencer_t sfx_sequencer_gm = {
|
|
|
|
"General MIDI",
|
|
|
|
"0.1",
|
|
|
|
SFX_DEVICE_MIDI,
|
|
|
|
&midi_gm_set_option,
|
|
|
|
&midi_gm_open,
|
|
|
|
&midi_gm_close,
|
|
|
|
&midi_gm_event,
|
|
|
|
&midi_gm_delay,
|
|
|
|
&midi_gm_reset_timer,
|
|
|
|
&midi_gm_allstop,
|
|
|
|
&midi_gm_volume,
|
|
|
|
&midi_gm_reverb,
|
|
|
|
004, /* patch.004 */
|
|
|
|
001, /* patch.001 */
|
|
|
|
0x01, /* playflag */
|
|
|
|
1, /* do play rhythm */
|
|
|
|
64, /* max polyphony */
|
|
|
|
0 /* no write-ahead needed inherently */
|
|
|
|
};
|
2009-02-21 10:23:36 +00:00
|
|
|
|
|
|
|
} // End of namespace Sci
|