aboutsummaryrefslogtreecommitdiff
path: root/audio
diff options
context:
space:
mode:
authorMatthew Hoops2011-05-31 14:16:29 -0400
committerMatthew Hoops2011-05-31 14:16:29 -0400
commitaa49b38c5a8032586cb94fc4ca07149eecabe64a (patch)
treeea5c7617f8c482c8cf4141b728b3ccff5a7f84c7 /audio
parentd3ea9ab2a9334747eb445c1b45aa30cb17ffdf1b (diff)
parentc86a6c466fabe31fbf36363aa8d0ac8ea6001b9f (diff)
downloadscummvm-rg350-aa49b38c5a8032586cb94fc4ca07149eecabe64a.tar.gz
scummvm-rg350-aa49b38c5a8032586cb94fc4ca07149eecabe64a.tar.bz2
scummvm-rg350-aa49b38c5a8032586cb94fc4ca07149eecabe64a.zip
Merge remote branch 'upstream/master' into t7g-ios
Conflicts: engines/groovie/script.cpp
Diffstat (limited to 'audio')
-rw-r--r--audio/audiostream.cpp3
-rw-r--r--audio/audiostream.h3
-rw-r--r--audio/decoders/adpcm.cpp3
-rw-r--r--audio/decoders/adpcm.h3
-rw-r--r--audio/decoders/adpcm_intern.h3
-rw-r--r--audio/decoders/aiff.cpp3
-rw-r--r--audio/decoders/aiff.h3
-rw-r--r--audio/decoders/flac.cpp5
-rw-r--r--audio/decoders/flac.h3
-rw-r--r--audio/decoders/iff_sound.cpp3
-rw-r--r--audio/decoders/iff_sound.h3
-rw-r--r--audio/decoders/mac_snd.cpp3
-rw-r--r--audio/decoders/mac_snd.h3
-rw-r--r--audio/decoders/mp3.cpp3
-rw-r--r--audio/decoders/mp3.h3
-rw-r--r--audio/decoders/qdm2.cpp3
-rw-r--r--audio/decoders/qdm2.h3
-rw-r--r--audio/decoders/qdm2data.h3
-rw-r--r--audio/decoders/raw.cpp3
-rw-r--r--audio/decoders/raw.h3
-rw-r--r--audio/decoders/vag.cpp3
-rw-r--r--audio/decoders/vag.h3
-rw-r--r--audio/decoders/voc.cpp3
-rw-r--r--audio/decoders/voc.h3
-rw-r--r--audio/decoders/vorbis.cpp3
-rw-r--r--audio/decoders/vorbis.h4
-rw-r--r--audio/decoders/wave.cpp3
-rw-r--r--audio/decoders/wave.h3
-rw-r--r--audio/fmopl.cpp3
-rw-r--r--audio/fmopl.h8
-rw-r--r--audio/mididrv.cpp3
-rw-r--r--audio/mididrv.h3
-rw-r--r--audio/midiparser.cpp3
-rw-r--r--audio/midiparser.h3
-rw-r--r--audio/midiparser_smf.cpp3
-rw-r--r--audio/midiparser_xmidi.cpp5
-rw-r--r--audio/midiplayer.cpp3
-rw-r--r--audio/midiplayer.h3
-rw-r--r--audio/mixer.cpp5
-rw-r--r--audio/mixer.h3
-rw-r--r--audio/mixer_intern.h5
-rw-r--r--audio/mods/infogrames.cpp3
-rw-r--r--audio/mods/infogrames.h3
-rw-r--r--audio/mods/maxtrax.cpp3
-rw-r--r--audio/mods/maxtrax.h3
-rw-r--r--audio/mods/module.cpp3
-rw-r--r--audio/mods/module.h3
-rw-r--r--audio/mods/paula.cpp3
-rw-r--r--audio/mods/paula.h3
-rw-r--r--audio/mods/protracker.cpp3
-rw-r--r--audio/mods/protracker.h3
-rw-r--r--audio/mods/rjp1.cpp3
-rw-r--r--audio/mods/rjp1.h3
-rw-r--r--audio/mods/soundfx.cpp3
-rw-r--r--audio/mods/soundfx.h3
-rw-r--r--audio/mods/tfmx.cpp7
-rw-r--r--audio/mods/tfmx.h3
-rw-r--r--audio/module.mk3
-rw-r--r--audio/mpu401.cpp3
-rw-r--r--audio/mpu401.h3
-rw-r--r--audio/musicplugin.cpp3
-rw-r--r--audio/musicplugin.h3
-rw-r--r--audio/null.cpp3
-rw-r--r--audio/null.h3
-rw-r--r--audio/rate.cpp3
-rw-r--r--audio/rate.h3
-rw-r--r--audio/rate_arm.cpp3
-rw-r--r--audio/rate_arm_asm.s3
-rw-r--r--audio/softsynth/adlib.cpp3
-rw-r--r--audio/softsynth/appleiigs.cpp3
-rw-r--r--audio/softsynth/cms.cpp3
-rw-r--r--audio/softsynth/cms.h3
-rw-r--r--audio/softsynth/eas.cpp3
-rw-r--r--audio/softsynth/emumidi.h3
-rw-r--r--audio/softsynth/fluidsynth.cpp3
-rw-r--r--audio/softsynth/fmtowns_pc98/towns_audio.cpp524
-rw-r--r--audio/softsynth/fmtowns_pc98/towns_audio.h135
-rw-r--r--audio/softsynth/fmtowns_pc98/towns_euphony.cpp28
-rw-r--r--audio/softsynth/fmtowns_pc98/towns_euphony.h17
-rw-r--r--audio/softsynth/fmtowns_pc98/towns_midi.cpp1043
-rw-r--r--audio/softsynth/fmtowns_pc98/towns_midi.h83
-rw-r--r--audio/softsynth/fmtowns_pc98/towns_pc98_driver.cpp101
-rw-r--r--audio/softsynth/fmtowns_pc98/towns_pc98_driver.h37
-rw-r--r--audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp255
-rw-r--r--audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h30
-rw-r--r--audio/softsynth/fmtowns_pc98/towns_pc98_plugins.cpp86
-rw-r--r--audio/softsynth/mt32.cpp17
-rw-r--r--audio/softsynth/mt32/freeverb.cpp3
-rw-r--r--audio/softsynth/mt32/freeverb.h3
-rw-r--r--audio/softsynth/mt32/partial.cpp4
-rw-r--r--audio/softsynth/mt32/synth.cpp24
-rw-r--r--audio/softsynth/mt32/synth.h2
-rw-r--r--audio/softsynth/mt32/tables.cpp26
-rw-r--r--audio/softsynth/mt32/tables.h4
-rw-r--r--audio/softsynth/opl/dosbox.cpp3
-rw-r--r--audio/softsynth/opl/dosbox.h3
-rw-r--r--audio/softsynth/opl/mame.cpp17
-rw-r--r--audio/softsynth/opl/mame.h5
-rw-r--r--audio/softsynth/pcspk.cpp3
-rw-r--r--audio/softsynth/pcspk.h3
-rw-r--r--audio/softsynth/sid.cpp3
-rw-r--r--audio/softsynth/sid.h3
-rw-r--r--audio/softsynth/wave6581.cpp3
-rw-r--r--audio/softsynth/ym2612.cpp793
-rw-r--r--audio/softsynth/ym2612.h179
-rw-r--r--audio/timestamp.cpp3
-rw-r--r--audio/timestamp.h3
107 files changed, 1970 insertions, 1716 deletions
diff --git a/audio/audiostream.cpp b/audio/audiostream.cpp
index 0cfbabf53b..547aa77526 100644
--- a/audio/audiostream.cpp
+++ b/audio/audiostream.cpp
@@ -18,9 +18,6 @@
* 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$
- *
*/
#include "common/debug.h"
diff --git a/audio/audiostream.h b/audio/audiostream.h
index 22de21cb34..0ffaa241ce 100644
--- a/audio/audiostream.h
+++ b/audio/audiostream.h
@@ -18,9 +18,6 @@
* 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$
- *
*/
#ifndef SOUND_AUDIOSTREAM_H
diff --git a/audio/decoders/adpcm.cpp b/audio/decoders/adpcm.cpp
index a9284973d5..d28ed222a5 100644
--- a/audio/decoders/adpcm.cpp
+++ b/audio/decoders/adpcm.cpp
@@ -18,9 +18,6 @@
* 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$
- *
*/
#include "common/stream.h"
diff --git a/audio/decoders/adpcm.h b/audio/decoders/adpcm.h
index 10344101e2..1dd4d510df 100644
--- a/audio/decoders/adpcm.h
+++ b/audio/decoders/adpcm.h
@@ -18,9 +18,6 @@
* 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$
- *
*/
/**
diff --git a/audio/decoders/adpcm_intern.h b/audio/decoders/adpcm_intern.h
index f875bd88c7..c9f894fb84 100644
--- a/audio/decoders/adpcm_intern.h
+++ b/audio/decoders/adpcm_intern.h
@@ -18,9 +18,6 @@
* 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$
- *
*/
/**
diff --git a/audio/decoders/aiff.cpp b/audio/decoders/aiff.cpp
index 957fb13638..f3b0dfb559 100644
--- a/audio/decoders/aiff.cpp
+++ b/audio/decoders/aiff.cpp
@@ -18,9 +18,6 @@
* 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$
- *
*/
/*
diff --git a/audio/decoders/aiff.h b/audio/decoders/aiff.h
index dddbffb520..558a018f57 100644
--- a/audio/decoders/aiff.h
+++ b/audio/decoders/aiff.h
@@ -18,9 +18,6 @@
* 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$
- *
*/
/**
diff --git a/audio/decoders/flac.cpp b/audio/decoders/flac.cpp
index fe15877ac6..d06a7b9c0e 100644
--- a/audio/decoders/flac.cpp
+++ b/audio/decoders/flac.cpp
@@ -18,9 +18,6 @@
* 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$
- *
*/
// Disable symbol overrides for FILE as that is used in FLAC headers
@@ -306,7 +303,7 @@ int FLACStream::readBuffer(int16 *buffer, const int numSamples) {
const uint numChannels = getChannels();
if (numChannels == 0) {
- warning("FLACStream: Stream not successfully initialised, cant playback");
+ warning("FLACStream: Stream not successfully initialized, cant playback");
return -1; // streaminfo wasnt read!
}
diff --git a/audio/decoders/flac.h b/audio/decoders/flac.h
index 69222f22a1..3182b26425 100644
--- a/audio/decoders/flac.h
+++ b/audio/decoders/flac.h
@@ -18,9 +18,6 @@
* 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$
- *
*/
/**
diff --git a/audio/decoders/iff_sound.cpp b/audio/decoders/iff_sound.cpp
index 8efe017e75..4efdce0338 100644
--- a/audio/decoders/iff_sound.cpp
+++ b/audio/decoders/iff_sound.cpp
@@ -18,9 +18,6 @@
* 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$
- *
*/
#include "audio/decoders/iff_sound.h"
diff --git a/audio/decoders/iff_sound.h b/audio/decoders/iff_sound.h
index 4d26b32e71..b266e629a1 100644
--- a/audio/decoders/iff_sound.h
+++ b/audio/decoders/iff_sound.h
@@ -18,9 +18,6 @@
* 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$
- *
*/
/**
diff --git a/audio/decoders/mac_snd.cpp b/audio/decoders/mac_snd.cpp
index fc69988860..43253a9ddf 100644
--- a/audio/decoders/mac_snd.cpp
+++ b/audio/decoders/mac_snd.cpp
@@ -18,9 +18,6 @@
* 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$
- *
*/
/*
diff --git a/audio/decoders/mac_snd.h b/audio/decoders/mac_snd.h
index bf6331a265..cbbd82bbe0 100644
--- a/audio/decoders/mac_snd.h
+++ b/audio/decoders/mac_snd.h
@@ -18,9 +18,6 @@
* 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$
- *
*/
/**
diff --git a/audio/decoders/mp3.cpp b/audio/decoders/mp3.cpp
index 91bd49873a..8d7f006ec7 100644
--- a/audio/decoders/mp3.cpp
+++ b/audio/decoders/mp3.cpp
@@ -18,9 +18,6 @@
* 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$
- *
*/
#include "audio/decoders/mp3.h"
diff --git a/audio/decoders/mp3.h b/audio/decoders/mp3.h
index d3a5b70d45..86ddc599ea 100644
--- a/audio/decoders/mp3.h
+++ b/audio/decoders/mp3.h
@@ -18,9 +18,6 @@
* 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$
- *
*/
/**
diff --git a/audio/decoders/qdm2.cpp b/audio/decoders/qdm2.cpp
index dbce8d2447..a178c363b5 100644
--- a/audio/decoders/qdm2.cpp
+++ b/audio/decoders/qdm2.cpp
@@ -18,9 +18,6 @@
* 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$
- *
*/
// Based off ffmpeg's QDM2 decoder
diff --git a/audio/decoders/qdm2.h b/audio/decoders/qdm2.h
index 6988623dcb..c0ec647bfd 100644
--- a/audio/decoders/qdm2.h
+++ b/audio/decoders/qdm2.h
@@ -18,9 +18,6 @@
* 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$
- *
*/
// Only compile if Mohawk is enabled or if we're building dynamic modules
diff --git a/audio/decoders/qdm2data.h b/audio/decoders/qdm2data.h
index cfe1a3d10e..d92bc0ff80 100644
--- a/audio/decoders/qdm2data.h
+++ b/audio/decoders/qdm2data.h
@@ -18,9 +18,6 @@
* 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$
- *
*/
#ifndef AUDIO_QDM2DATA_H
diff --git a/audio/decoders/raw.cpp b/audio/decoders/raw.cpp
index cf787f9b12..4789fd0f36 100644
--- a/audio/decoders/raw.cpp
+++ b/audio/decoders/raw.cpp
@@ -18,9 +18,6 @@
* 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$
- *
*/
#include "common/endian.h"
diff --git a/audio/decoders/raw.h b/audio/decoders/raw.h
index 23ed02182d..5a7897b688 100644
--- a/audio/decoders/raw.h
+++ b/audio/decoders/raw.h
@@ -18,9 +18,6 @@
* 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$
- *
*/
#ifndef SOUND_RAW_H
diff --git a/audio/decoders/vag.cpp b/audio/decoders/vag.cpp
index 2c3a36202a..10ef69708c 100644
--- a/audio/decoders/vag.cpp
+++ b/audio/decoders/vag.cpp
@@ -18,9 +18,6 @@
* 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$
- *
*/
#include "audio/decoders/vag.h"
diff --git a/audio/decoders/vag.h b/audio/decoders/vag.h
index 4adc1d3dde..b80fbdb98f 100644
--- a/audio/decoders/vag.h
+++ b/audio/decoders/vag.h
@@ -18,9 +18,6 @@
* 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$
- *
*/
/**
diff --git a/audio/decoders/voc.cpp b/audio/decoders/voc.cpp
index 9c2dc4f337..74ea4440a1 100644
--- a/audio/decoders/voc.cpp
+++ b/audio/decoders/voc.cpp
@@ -18,9 +18,6 @@
* 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$
- *
*/
#include "common/debug.h"
diff --git a/audio/decoders/voc.h b/audio/decoders/voc.h
index 38250dcf7a..8bc6dcf46f 100644
--- a/audio/decoders/voc.h
+++ b/audio/decoders/voc.h
@@ -18,9 +18,6 @@
* 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$
- *
*/
/**
diff --git a/audio/decoders/vorbis.cpp b/audio/decoders/vorbis.cpp
index 63f7ba8207..2724dd1f02 100644
--- a/audio/decoders/vorbis.cpp
+++ b/audio/decoders/vorbis.cpp
@@ -18,9 +18,6 @@
* 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$
- *
*/
// Disable symbol overrides for FILE and fseek as those are used in the
diff --git a/audio/decoders/vorbis.h b/audio/decoders/vorbis.h
index 51d0b82d5f..e3d989e9b8 100644
--- a/audio/decoders/vorbis.h
+++ b/audio/decoders/vorbis.h
@@ -18,9 +18,6 @@
* 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$
- *
*/
/**
@@ -36,6 +33,7 @@
* - scumm
* - sword1
* - sword2
+ * - sword25
* - touche
* - tucker
*/
diff --git a/audio/decoders/wave.cpp b/audio/decoders/wave.cpp
index a64874887a..3cf4566d0c 100644
--- a/audio/decoders/wave.cpp
+++ b/audio/decoders/wave.cpp
@@ -18,9 +18,6 @@
* 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$
- *
*/
#include "common/debug.h"
diff --git a/audio/decoders/wave.h b/audio/decoders/wave.h
index 33c3e798a0..6a34bc175a 100644
--- a/audio/decoders/wave.h
+++ b/audio/decoders/wave.h
@@ -18,9 +18,6 @@
* 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$
- *
*/
/**
diff --git a/audio/fmopl.cpp b/audio/fmopl.cpp
index 5952a987a7..a24c2a533c 100644
--- a/audio/fmopl.cpp
+++ b/audio/fmopl.cpp
@@ -17,9 +17,6 @@
* 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$
*/
#include "audio/fmopl.h"
diff --git a/audio/fmopl.h b/audio/fmopl.h
index 33235f3545..b88325a52e 100644
--- a/audio/fmopl.h
+++ b/audio/fmopl.h
@@ -17,16 +17,16 @@
* 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$
*/
#ifndef SOUND_FMOPL_H
#define SOUND_FMOPL_H
#include "common/scummsys.h"
-#include "common/str.h"
+
+namespace Common {
+class String;
+}
namespace OPL {
diff --git a/audio/mididrv.cpp b/audio/mididrv.cpp
index 6cc3366847..7beb76352c 100644
--- a/audio/mididrv.cpp
+++ b/audio/mididrv.cpp
@@ -18,9 +18,6 @@
* 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$
- *
*/
#include "common/config-manager.h"
diff --git a/audio/mididrv.h b/audio/mididrv.h
index c6c5179051..7369cab26b 100644
--- a/audio/mididrv.h
+++ b/audio/mididrv.h
@@ -18,9 +18,6 @@
* 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$
- *
*/
#ifndef SOUND_MIDIDRV_H
diff --git a/audio/midiparser.cpp b/audio/midiparser.cpp
index a1399d0c30..943a6067a4 100644
--- a/audio/midiparser.cpp
+++ b/audio/midiparser.cpp
@@ -18,9 +18,6 @@
* 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$
- *
*/
#include "audio/midiparser.h"
diff --git a/audio/midiparser.h b/audio/midiparser.h
index 24f2ba7963..9dff4b54ba 100644
--- a/audio/midiparser.h
+++ b/audio/midiparser.h
@@ -18,9 +18,6 @@
* 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$
- *
*/
/// \brief Declarations related to the MidiParser class
diff --git a/audio/midiparser_smf.cpp b/audio/midiparser_smf.cpp
index 8ead95de4c..e883471b54 100644
--- a/audio/midiparser_smf.cpp
+++ b/audio/midiparser_smf.cpp
@@ -18,9 +18,6 @@
* 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$
- *
*/
#include "audio/midiparser.h"
diff --git a/audio/midiparser_xmidi.cpp b/audio/midiparser_xmidi.cpp
index 1146084cde..7c3cf102d1 100644
--- a/audio/midiparser_xmidi.cpp
+++ b/audio/midiparser_xmidi.cpp
@@ -18,9 +18,6 @@
* 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$
- *
*/
#include "audio/midiparser.h"
@@ -240,7 +237,7 @@ bool MidiParser_XMIDI::loadMusic(byte *data, uint32 size) {
pos += 4;
_num_tracks = 1;
} else if (memcmp(pos, "XDIR", 4)) {
- // Not an XMIDI that we recognise
+ // Not an XMIDI that we recognize
warning("Expected 'XDIR' but found '%c%c%c%c'", pos[0], pos[1], pos[2], pos[3]);
return false;
} else {
diff --git a/audio/midiplayer.cpp b/audio/midiplayer.cpp
index f4a13a0438..7fab02a5be 100644
--- a/audio/midiplayer.cpp
+++ b/audio/midiplayer.cpp
@@ -18,9 +18,6 @@
* 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$
- *
*/
#include "audio/midiplayer.h"
diff --git a/audio/midiplayer.h b/audio/midiplayer.h
index 0cf373d646..e1da0bfb79 100644
--- a/audio/midiplayer.h
+++ b/audio/midiplayer.h
@@ -18,9 +18,6 @@
* 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$
- *
*/
#ifndef SOUND_MIDIPLAYER_H
diff --git a/audio/mixer.cpp b/audio/mixer.cpp
index 4d23487e71..fb4fffb8d8 100644
--- a/audio/mixer.cpp
+++ b/audio/mixer.cpp
@@ -18,9 +18,6 @@
* 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$
- *
*/
#include "common/util.h"
@@ -260,6 +257,8 @@ int MixerImpl::mixCallback(byte *samples, uint len) {
Common::StackLock lock(_mutex);
int16 *buf = (int16 *)samples;
+ // we store stereo, 16-bit samples
+ assert(len % 4 == 0);
len >>= 2;
// Since the mixer callback has been called, the mixer must be ready...
diff --git a/audio/mixer.h b/audio/mixer.h
index 5802abdd6b..1fbe265488 100644
--- a/audio/mixer.h
+++ b/audio/mixer.h
@@ -18,9 +18,6 @@
* 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$
- *
*/
#ifndef SOUND_MIXER_H
diff --git a/audio/mixer_intern.h b/audio/mixer_intern.h
index d7764e50d9..a04eb55c5b 100644
--- a/audio/mixer_intern.h
+++ b/audio/mixer_intern.h
@@ -18,9 +18,6 @@
* 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$
- *
*/
#ifndef SOUND_MIXER_INTERN_H
@@ -129,6 +126,8 @@ public:
* the backend (e.g. from an audio mixing thread). All the actual mixing
* work is done from here.
*
+ * @param samples Sample buffer, in which stereo 16-bit samples will be stored.
+ * @param len Length of the provided buffer to fill (in bytes, should be divisible by 4).
* @return number of sample pairs processed (which can still be silence!)
*/
int mixCallback(byte *samples, uint len);
diff --git a/audio/mods/infogrames.cpp b/audio/mods/infogrames.cpp
index 8bfffeacb6..5b4d39fe49 100644
--- a/audio/mods/infogrames.cpp
+++ b/audio/mods/infogrames.cpp
@@ -18,9 +18,6 @@
* 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$
- *
*/
#include "audio/mods/infogrames.h"
diff --git a/audio/mods/infogrames.h b/audio/mods/infogrames.h
index 9787210e82..307a26d4e1 100644
--- a/audio/mods/infogrames.h
+++ b/audio/mods/infogrames.h
@@ -18,9 +18,6 @@
* 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$
- *
*/
/**
diff --git a/audio/mods/maxtrax.cpp b/audio/mods/maxtrax.cpp
index 0738966dab..953bb8f8d2 100644
--- a/audio/mods/maxtrax.cpp
+++ b/audio/mods/maxtrax.cpp
@@ -18,9 +18,6 @@
* 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$
- *
*/
#include "common/scummsys.h"
diff --git a/audio/mods/maxtrax.h b/audio/mods/maxtrax.h
index 2f890afe2d..bef6669d2a 100644
--- a/audio/mods/maxtrax.h
+++ b/audio/mods/maxtrax.h
@@ -18,9 +18,6 @@
* 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$
- *
*/
// see if all engines using this class are DISABLED
diff --git a/audio/mods/module.cpp b/audio/mods/module.cpp
index 987b17bc8d..8d09671d26 100644
--- a/audio/mods/module.cpp
+++ b/audio/mods/module.cpp
@@ -18,9 +18,6 @@
* 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$
- *
*/
#include "audio/mods/module.h"
diff --git a/audio/mods/module.h b/audio/mods/module.h
index c9b72bd2d6..a57a89225e 100644
--- a/audio/mods/module.h
+++ b/audio/mods/module.h
@@ -18,9 +18,6 @@
* 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$
- *
*/
#ifndef SOUND_MODS_MODULE_H
diff --git a/audio/mods/paula.cpp b/audio/mods/paula.cpp
index ef841ac9bf..4b49d6e750 100644
--- a/audio/mods/paula.cpp
+++ b/audio/mods/paula.cpp
@@ -18,9 +18,6 @@
* 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$
- *
*/
#include "audio/mods/paula.h"
diff --git a/audio/mods/paula.h b/audio/mods/paula.h
index f6f159d5a6..cd797f51cb 100644
--- a/audio/mods/paula.h
+++ b/audio/mods/paula.h
@@ -18,9 +18,6 @@
* 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$
- *
*/
#ifndef SOUND_MODS_PAULA_H
diff --git a/audio/mods/protracker.cpp b/audio/mods/protracker.cpp
index f781920505..084b0edf9a 100644
--- a/audio/mods/protracker.cpp
+++ b/audio/mods/protracker.cpp
@@ -18,9 +18,6 @@
* 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$
- *
*/
#include "audio/mods/protracker.h"
diff --git a/audio/mods/protracker.h b/audio/mods/protracker.h
index fa9895b81f..15f708d801 100644
--- a/audio/mods/protracker.h
+++ b/audio/mods/protracker.h
@@ -18,9 +18,6 @@
* 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$
- *
*/
/**
diff --git a/audio/mods/rjp1.cpp b/audio/mods/rjp1.cpp
index eaa99e6928..45c6caa106 100644
--- a/audio/mods/rjp1.cpp
+++ b/audio/mods/rjp1.cpp
@@ -18,9 +18,6 @@
* 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$
- *
*/
#include "common/debug.h"
diff --git a/audio/mods/rjp1.h b/audio/mods/rjp1.h
index e3cb0b853d..232b1926e9 100644
--- a/audio/mods/rjp1.h
+++ b/audio/mods/rjp1.h
@@ -18,9 +18,6 @@
* 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$
- *
*/
/**
diff --git a/audio/mods/soundfx.cpp b/audio/mods/soundfx.cpp
index 44fdd65986..767d1ce9c8 100644
--- a/audio/mods/soundfx.cpp
+++ b/audio/mods/soundfx.cpp
@@ -18,9 +18,6 @@
* 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$
- *
*/
#include "common/endian.h"
diff --git a/audio/mods/soundfx.h b/audio/mods/soundfx.h
index 9dd5240160..48ccff2da6 100644
--- a/audio/mods/soundfx.h
+++ b/audio/mods/soundfx.h
@@ -18,9 +18,6 @@
* 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$
- *
*/
/**
diff --git a/audio/mods/tfmx.cpp b/audio/mods/tfmx.cpp
index f7cfc50c10..a89da78af1 100644
--- a/audio/mods/tfmx.cpp
+++ b/audio/mods/tfmx.cpp
@@ -18,9 +18,6 @@
* 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$
- *
*/
#include "common/scummsys.h"
@@ -335,7 +332,7 @@ void Tfmx::macroRun(ChannelContext &channel) {
channel.vibLength = macroPtr[1];
channel.vibCount = macroPtr[1] / 2;
channel.vibDelta = macroPtr[3];
- // TODO: Perhaps a bug, vibValue could be left uninitialised
+ // TODO: Perhaps a bug, vibValue could be left uninitialized
if (!channel.portaDelta) {
channel.period = channel.refPeriod;
channel.vibValue = 0;
@@ -703,7 +700,7 @@ void Tfmx::noteCommand(const uint8 note, const uint8 param1, const uint8 param2,
channel.relVol = param2 >> 4;
channel.fineTune = (int8)param3;
- // TODO: the point where the channel gets initialised varies with the games, needs more research.
+ // TODO: the point where the channel gets initialized varies with the games, needs more research.
initMacroProgramm(channel);
channel.keyUp = false; // key down = playing a Note
diff --git a/audio/mods/tfmx.h b/audio/mods/tfmx.h
index 1930487eb8..2b07e2e660 100644
--- a/audio/mods/tfmx.h
+++ b/audio/mods/tfmx.h
@@ -18,9 +18,6 @@
* 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$
- *
*/
// see if all engines using this class are DISABLED
diff --git a/audio/module.mk b/audio/module.mk
index 545a55c23b..46cb9944e1 100644
--- a/audio/module.mk
+++ b/audio/module.mk
@@ -42,10 +42,11 @@ MODULE_OBJS := \
softsynth/opl/mame.o \
softsynth/fmtowns_pc98/towns_audio.o \
softsynth/fmtowns_pc98/towns_euphony.o \
+ softsynth/fmtowns_pc98/towns_midi.o \
softsynth/fmtowns_pc98/towns_pc98_driver.o \
softsynth/fmtowns_pc98/towns_pc98_fmsynth.o \
+ softsynth/fmtowns_pc98/towns_pc98_plugins.o \
softsynth/appleiigs.o \
- softsynth/ym2612.o \
softsynth/fluidsynth.o \
softsynth/mt32.o \
softsynth/eas.o \
diff --git a/audio/mpu401.cpp b/audio/mpu401.cpp
index 4834772c07..caad945258 100644
--- a/audio/mpu401.cpp
+++ b/audio/mpu401.cpp
@@ -17,9 +17,6 @@
* 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$
*/
#include "audio/mpu401.h"
diff --git a/audio/mpu401.h b/audio/mpu401.h
index 5f1a5108ac..15728a6d97 100644
--- a/audio/mpu401.h
+++ b/audio/mpu401.h
@@ -18,9 +18,6 @@
* 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$
- *
*/
#ifndef SOUND_MPU401_H
diff --git a/audio/musicplugin.cpp b/audio/musicplugin.cpp
index eb28d2f4c9..7c77c3455c 100644
--- a/audio/musicplugin.cpp
+++ b/audio/musicplugin.cpp
@@ -18,9 +18,6 @@
* 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$
- *
*/
#include "audio/musicplugin.h"
diff --git a/audio/musicplugin.h b/audio/musicplugin.h
index 53a2ae426d..2a25962b87 100644
--- a/audio/musicplugin.h
+++ b/audio/musicplugin.h
@@ -17,9 +17,6 @@
* 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$
*/
#ifndef SOUND_MUSICPLUGIN_H
diff --git a/audio/null.cpp b/audio/null.cpp
index 2066a6d048..36c894aa7c 100644
--- a/audio/null.cpp
+++ b/audio/null.cpp
@@ -17,9 +17,6 @@
* 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$
*/
#include "common/error.h"
diff --git a/audio/null.h b/audio/null.h
index 8570d4d293..97c7c8cc93 100644
--- a/audio/null.h
+++ b/audio/null.h
@@ -17,9 +17,6 @@
* 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$
*/
#ifndef SOUND_NULL_H
diff --git a/audio/rate.cpp b/audio/rate.cpp
index fd52503b8c..83abd6150b 100644
--- a/audio/rate.cpp
+++ b/audio/rate.cpp
@@ -18,9 +18,6 @@
* 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$
- *
*/
/*
diff --git a/audio/rate.h b/audio/rate.h
index af37994d02..72bcbf48c5 100644
--- a/audio/rate.h
+++ b/audio/rate.h
@@ -18,9 +18,6 @@
* 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$
- *
*/
#ifndef SOUND_RATE_H
diff --git a/audio/rate_arm.cpp b/audio/rate_arm.cpp
index 1eb55d0dc3..433a7d3423 100644
--- a/audio/rate_arm.cpp
+++ b/audio/rate_arm.cpp
@@ -18,9 +18,6 @@
* 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$
- *
*/
/*
diff --git a/audio/rate_arm_asm.s b/audio/rate_arm_asm.s
index 9431ae0649..d86d96267e 100644
--- a/audio/rate_arm_asm.s
+++ b/audio/rate_arm_asm.s
@@ -18,9 +18,6 @@
@ 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$
-@
@ @author Robin Watts (robin@wss.co.uk)
@
@ This file, together with rate_arm.cpp, provides an ARM optimised version
diff --git a/audio/softsynth/adlib.cpp b/audio/softsynth/adlib.cpp
index 9fec74c9d6..60de8fad60 100644
--- a/audio/softsynth/adlib.cpp
+++ b/audio/softsynth/adlib.cpp
@@ -17,9 +17,6 @@
* 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$
*/
#include "audio/softsynth/emumidi.h"
diff --git a/audio/softsynth/appleiigs.cpp b/audio/softsynth/appleiigs.cpp
index 80159c79ce..6ee70d1202 100644
--- a/audio/softsynth/appleiigs.cpp
+++ b/audio/softsynth/appleiigs.cpp
@@ -18,9 +18,6 @@
* 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$
-*
*/
#include "audio/null.h"
diff --git a/audio/softsynth/cms.cpp b/audio/softsynth/cms.cpp
index fcc15f127e..67eacd1a41 100644
--- a/audio/softsynth/cms.cpp
+++ b/audio/softsynth/cms.cpp
@@ -17,9 +17,6 @@
* 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$
*/
#include "audio/softsynth/cms.h"
diff --git a/audio/softsynth/cms.h b/audio/softsynth/cms.h
index d5bb7f0a42..48064746a8 100644
--- a/audio/softsynth/cms.h
+++ b/audio/softsynth/cms.h
@@ -17,9 +17,6 @@
* 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$
*/
#ifndef SOUND_SOFTSYNTH_CMS_H
diff --git a/audio/softsynth/eas.cpp b/audio/softsynth/eas.cpp
index 7d17655d20..d829e3b39a 100644
--- a/audio/softsynth/eas.cpp
+++ b/audio/softsynth/eas.cpp
@@ -17,9 +17,6 @@
* 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$
*/
#include "common/scummsys.h"
diff --git a/audio/softsynth/emumidi.h b/audio/softsynth/emumidi.h
index 190b70c392..f3d7645f87 100644
--- a/audio/softsynth/emumidi.h
+++ b/audio/softsynth/emumidi.h
@@ -17,9 +17,6 @@
* 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$
*/
#ifndef SOUND_SOFTSYNTH_EMUMIDI_H
diff --git a/audio/softsynth/fluidsynth.cpp b/audio/softsynth/fluidsynth.cpp
index a4877a4ec1..2451336784 100644
--- a/audio/softsynth/fluidsynth.cpp
+++ b/audio/softsynth/fluidsynth.cpp
@@ -17,9 +17,6 @@
* 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$
*/
#include "common/scummsys.h"
diff --git a/audio/softsynth/fmtowns_pc98/towns_audio.cpp b/audio/softsynth/fmtowns_pc98/towns_audio.cpp
index 7b6658ab3a..786e3ee1d2 100644
--- a/audio/softsynth/fmtowns_pc98/towns_audio.cpp
+++ b/audio/softsynth/fmtowns_pc98/towns_audio.cpp
@@ -18,19 +18,19 @@
* 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$
- *
*/
#include "audio/softsynth/fmtowns_pc98/towns_audio.h"
+#include "audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h"
+
#include "common/endian.h"
#include "common/util.h"
+#include "common/textconsole.h"
#include "backends/audiocd/audiocd.h"
class TownsAudio_PcmChannel {
-friend class TownsAudioInterface;
+friend class TownsAudioInterfaceInternal;
public:
TownsAudio_PcmChannel();
~TownsAudio_PcmChannel();
@@ -80,7 +80,7 @@ private:
};
class TownsAudio_WaveTable {
-friend class TownsAudioInterface;
+friend class TownsAudioInterfaceInternal;
public:
TownsAudio_WaveTable();
~TownsAudio_WaveTable();
@@ -101,14 +101,170 @@ private:
int8 *data;
};
-TownsAudioInterface::TownsAudioInterface(Audio::Mixer *mixer, TownsAudioInterfacePluginDriver *driver) : TownsPC98_FmSynth(mixer, kTypeTowns),
+class TownsAudioInterfaceInternal : public TownsPC98_FmSynth {
+public:
+ TownsAudioInterfaceInternal(Audio::Mixer *mixer, TownsAudioInterface *owner, TownsAudioInterfacePluginDriver *driver, bool externalMutexHandling = false);
+ ~TownsAudioInterfaceInternal();
+
+ static TownsAudioInterfaceInternal *addNewRef(Audio::Mixer *mixer, TownsAudioInterface *owner, TownsAudioInterfacePluginDriver *driver, bool externalMutexHandling = false);
+ static void releaseRef(TownsAudioInterface *owner);
+
+ bool init();
+
+ int callback(int command, ...);
+ int processCommand(int command, va_list &args);
+
+ void setMusicVolume(int volume);
+ void setSoundEffectVolume(int volume);
+ // Defines the channels used as sound effect channels for the purpose of ScummVM GUI volume control.
+ // The first 6 bits are the 6 fm channels. The next 8 bits are pcm channels.
+ void setSoundEffectChanMask(int mask);
+
+private:
+ bool assignPluginDriver(TownsAudioInterface *owner, TownsAudioInterfacePluginDriver *driver, bool externalMutexHandling = false);
+ void removePluginDriver(TownsAudioInterface *owner);
+
+ void nextTickEx(int32 *buffer, uint32 bufferSize);
+
+ void timerCallbackA();
+ void timerCallbackB();
+
+ typedef int (TownsAudioInterfaceInternal::*TownsAudioIntfCallback)(va_list &);
+ const TownsAudioIntfCallback *_intfOpcodes;
+
+ int intf_reset(va_list &args);
+ int intf_keyOn(va_list &args);
+ int intf_keyOff(va_list &args);
+ int intf_setPanPos(va_list &args);
+ int intf_setInstrument(va_list &args);
+ int intf_loadInstrument(va_list &args);
+ int intf_setPitch(va_list &args);
+ int intf_setLevel(va_list &args);
+ int intf_chanOff(va_list &args);
+ int intf_writeReg(va_list &args);
+ int intf_writeRegBuffer(va_list &args);
+ int intf_readRegBuffer(va_list &args);
+ int intf_setTimerA(va_list &args);
+ int intf_setTimerB(va_list &args);
+ int intf_enableTimerA(va_list &args);
+ int intf_enableTimerB(va_list &args);
+ int intf_loadSamples(va_list &args);
+ int intf_reserveEffectChannels(va_list &args);
+ int intf_loadWaveTable(va_list &args);
+ int intf_unloadWaveTable(va_list &args);
+ int intf_pcmPlayEffect(va_list &args);
+ int intf_pcmChanOff(va_list &args);
+ int intf_pcmEffectPlaying(va_list &args);
+ int intf_fmKeyOn(va_list &args);
+ int intf_fmKeyOff(va_list &args);
+ int intf_fmSetPanPos(va_list &args);
+ int intf_fmSetInstrument(va_list &args);
+ int intf_fmLoadInstrument(va_list &args);
+ int intf_fmSetPitch(va_list &args);
+ int intf_fmSetLevel(va_list &args);
+ int intf_fmReset(va_list &args);
+ int intf_setOutputVolume(va_list &args);
+ int intf_resetOutputVolume(va_list &args);
+ int intf_getOutputVolume(va_list &args);
+ int intf_setOutputMute(va_list &args);
+ int intf_cdaToggle(va_list &args);
+ int intf_getOutputVolume2(va_list &args);
+ int intf_getOutputMute(va_list &args);
+ int intf_pcmUpdateEnvelopeGenerator(va_list &args);
+
+ int intf_notImpl(va_list &args);
+
+ void fmReset();
+ int fmKeyOn(int chan, int note, int velo);
+ int fmKeyOff(int chan);
+ int fmChanOff(int chan);
+ int fmSetPanPos(int chan, int mode);
+ int fmSetInstrument(int chan, int instrId);
+ int fmLoadInstrument(int instrId, const uint8 *data);
+ int fmSetPitch(int chan, int pitch);
+ int fmSetLevel(int chan, int lvl);
+
+ void bufferedWriteReg(uint8 part, uint8 regAddress, uint8 value);
+
+ uint8 _fmChanPlaying;
+ uint8 _fmChanNote[6];
+ int16 _fmChanPitch[6];
+
+ uint8 *_fmSaveReg[2];
+ uint8 *_fmInstruments;
+
+ void pcmReset();
+ int pcmKeyOn(int chan, int note, int velo);
+ int pcmKeyOff(int chan);
+ int pcmChanOff(int chan);
+ int pcmSetPanPos(int chan, int mode);
+ int pcmSetInstrument(int chan, int instrId);
+ int pcmLoadInstrument(int instrId, const uint8 *data);
+ int pcmSetPitch(int chan, int pitch);
+ int pcmSetLevel(int chan, int lvl);
+ void pcmUpdateEnvelopeGenerator(int chan);
+
+ TownsAudio_PcmChannel *_pcmChan;
+ uint8 _pcmChanOut;
+ uint8 _pcmChanReserved;
+ uint8 _pcmChanKeyPressed;
+ uint8 _pcmChanEffectPlaying;
+ uint8 _pcmChanKeyPlaying;
+
+ uint8 _pcmChanNote[8];
+ uint8 _pcmChanVelo[8];
+ uint8 _pcmChanLevel[8];
+
+ uint8 _numReservedChannels;
+ uint8 *_pcmInstruments;
+
+ TownsAudio_WaveTable *_waveTables;
+ uint8 _numWaveTables;
+ uint32 _waveTablesTotalDataSize;
+
+ void pcmCalcPhaseStep(TownsAudio_PcmChannel *p, TownsAudio_WaveTable *w);
+
+ void updateOutputVolume();
+ void updateOutputVolumeInternal();
+ uint8 _outputVolumeFlags;
+ uint8 _outputLevel[16];
+ uint8 _outputMute[16];
+ bool _updateOutputVol;
+
+ const float _baserate;
+ uint32 _timerBase;
+ uint32 _tickLength;
+ uint32 _timer;
+
+ uint16 _musicVolume;
+ uint16 _sfxVolume;
+ int _pcmSfxChanMask;
+
+ TownsAudioInterfacePluginDriver *_drv;
+ void *_drvOwner;
+ bool _ready;
+
+ static TownsAudioInterfaceInternal *_refInstance;
+ static int _refCount;
+
+ static const uint8 _chanFlags[];
+ static const uint16 _frequency[];
+ static const uint8 _carrier[];
+ static const uint8 _fmDefaultInstrument[];
+ static const uint16 _pcmPhase1[];
+ static const uint16 _pcmPhase2[];
+};
+
+TownsAudioInterfaceInternal::TownsAudioInterfaceInternal(Audio::Mixer *mixer, TownsAudioInterface *owner, TownsAudioInterfacePluginDriver *driver, bool externalMutexHandling) :
+ TownsPC98_FmSynth(mixer, kTypeTowns, externalMutexHandling),
_fmInstruments(0), _pcmInstruments(0), _pcmChan(0), _waveTables(0), _waveTablesTotalDataSize(0),
- _baserate(55125.0f / (float)mixer->getOutputRate()), _tickLength(0), _timer(0), _drv(driver),
+ _baserate(55125.0f / (float)mixer->getOutputRate()), _tickLength(0), _timer(0), _drv(driver), _drvOwner(owner),
_pcmSfxChanMask(0), _musicVolume(Audio::Mixer::kMaxMixerVolume), _sfxVolume(Audio::Mixer::kMaxMixerVolume),
- _outputVolumeFlags(0), _outputMuteFlags(0), _pcmChanOut(0), _pcmChanReserved(0), _pcmChanKeyPressed(0),
- _pcmChanEffectPlaying(0), _pcmChanKeyPlaying(0), _ready(false) {
+ _outputVolumeFlags(0), _pcmChanOut(0), _pcmChanReserved(0), _pcmChanKeyPressed(0),
+ _pcmChanEffectPlaying(0), _pcmChanKeyPlaying(0), _fmChanPlaying(0),
+ _numReservedChannels(0), _numWaveTables(0), _updateOutputVol(false), _ready(false) {
-#define INTCB(x) &TownsAudioInterface::intf_##x
+#define INTCB(x) &TownsAudioInterfaceInternal::intf_##x
static const TownsAudioIntfCallback intfCb[] = {
// 0
INTCB(reset),
@@ -197,14 +353,14 @@ TownsAudioInterface::TownsAudioInterface(Audio::Mixer *mixer, TownsAudioInterfac
INTCB(setOutputVolume),
// 68
INTCB(resetOutputVolume),
- INTCB(notImpl),
- INTCB(updateOutputVolume),
+ INTCB(getOutputVolume),
+ INTCB(setOutputMute),
INTCB(notImpl),
// 72
INTCB(notImpl),
INTCB(cdaToggle),
- INTCB(notImpl),
- INTCB(notImpl),
+ INTCB(getOutputVolume2),
+ INTCB(getOutputMute),
// 76
INTCB(notImpl),
INTCB(notImpl),
@@ -219,16 +375,24 @@ TownsAudioInterface::TownsAudioInterface(Audio::Mixer *mixer, TownsAudioInterfac
_intfOpcodes = intfCb;
memset(_fmSaveReg, 0, sizeof(_fmSaveReg));
+ memset(_fmChanNote, 0, sizeof(_fmChanNote));
+ memset(_fmChanPitch, 0, sizeof(_fmChanPitch));
+ memset(_pcmChanNote, 0, sizeof(_pcmChanNote));
+ memset(_pcmChanVelo, 0, sizeof(_pcmChanVelo));
+ memset(_pcmChanLevel, 0, sizeof(_pcmChanLevel));
memset(_outputLevel, 0, sizeof(_outputLevel));
+ memset(_outputMute, 0, sizeof(_outputMute));
_timerBase = (uint32)(_baserate * 1000000.0f);
_tickLength = 2 * _timerBase;
}
-TownsAudioInterface::~TownsAudioInterface() {
+TownsAudioInterfaceInternal::~TownsAudioInterfaceInternal() {
_ready = false;
deinit();
+ Common::StackLock lock(_mutex);
+
delete[] _fmSaveReg[0];
delete[] _fmSaveReg[1];
delete[] _fmInstruments;
@@ -237,7 +401,34 @@ TownsAudioInterface::~TownsAudioInterface() {
delete[] _pcmChan;
}
-bool TownsAudioInterface::init() {
+TownsAudioInterfaceInternal *TownsAudioInterfaceInternal::addNewRef(Audio::Mixer *mixer, TownsAudioInterface *owner, TownsAudioInterfacePluginDriver *driver, bool externalMutexHandling) {
+ _refCount++;
+ if (_refCount == 1 && _refInstance == 0)
+ _refInstance = new TownsAudioInterfaceInternal(mixer, owner, driver, externalMutexHandling);
+ else if (_refCount < 2 || _refInstance == 0)
+ error("TownsAudioInterfaceInternal::addNewRef(): Internal reference management failure");
+ else if (!_refInstance->assignPluginDriver(owner, driver, externalMutexHandling))
+ error("TownsAudioInterfaceInternal::addNewRef(): Plugin driver conflict");
+
+ return _refInstance;
+}
+
+void TownsAudioInterfaceInternal::releaseRef(TownsAudioInterface *owner) {
+ if (!_refCount)
+ return;
+
+ _refCount--;
+
+ if (_refCount) {
+ if (_refInstance)
+ _refInstance->removePluginDriver(owner);
+ } else {
+ delete _refInstance;
+ _refInstance = 0;
+ }
+}
+
+bool TownsAudioInterfaceInternal::init() {
if (_ready)
return true;
@@ -261,44 +452,79 @@ bool TownsAudioInterface::init() {
return true;
}
-int TownsAudioInterface::callback(int command, ...) {
+int TownsAudioInterfaceInternal::callback(int command, ...) {
if (!_ready)
return 1;
va_list args;
va_start(args, command);
- if (command > 81) {
- va_end(args);
- return 4;
- }
+ int res = processCommand(command, args);
+
+ va_end(args);
+ return res;
+}
+
+int TownsAudioInterfaceInternal::processCommand(int command, va_list &args) {
+ if (!_ready)
+ return 1;
+ if (command < 0 || command > 81)
+ return 4;
+
+ Common::StackLock lock(_mutex);
int res = (this->*_intfOpcodes[command])(args);
- va_end(args);
return res;
}
-void TownsAudioInterface::setMusicVolume(int volume) {
+void TownsAudioInterfaceInternal::setMusicVolume(int volume) {
_musicVolume = CLIP<uint16>(volume, 0, Audio::Mixer::kMaxMixerVolume);
setVolumeIntern(_musicVolume, _sfxVolume);
}
-void TownsAudioInterface::setSoundEffectVolume(int volume) {
+void TownsAudioInterfaceInternal::setSoundEffectVolume(int volume) {
_sfxVolume = CLIP<uint16>(volume, 0, Audio::Mixer::kMaxMixerVolume);
setVolumeIntern(_musicVolume, _sfxVolume);
}
-void TownsAudioInterface::setSoundEffectChanMask(int mask) {
+void TownsAudioInterfaceInternal::setSoundEffectChanMask(int mask) {
_pcmSfxChanMask = mask >> 6;
mask &= 0x3f;
setVolumeChannelMasks(~mask, mask);
}
-void TownsAudioInterface::nextTickEx(int32 *buffer, uint32 bufferSize) {
+bool TownsAudioInterfaceInternal::assignPluginDriver(TownsAudioInterface *owner, TownsAudioInterfacePluginDriver *driver, bool externalMutexHandling) {
+ if (_refCount <= 1)
+ return true;
+
+ if (_drv) {
+ if (driver && driver != _drv)
+ return false;
+ } else {
+ Common::StackLock lock(_mutex);
+ _drv = driver;
+ _drvOwner = owner;
+ _externalMutex = externalMutexHandling;
+ }
+
+ return true;
+}
+
+void TownsAudioInterfaceInternal::removePluginDriver(TownsAudioInterface *owner) {
+ if (_drvOwner == owner) {
+ Common::StackLock lock(_mutex);
+ _drv = 0;
+ }
+}
+
+void TownsAudioInterfaceInternal::nextTickEx(int32 *buffer, uint32 bufferSize) {
if (!_ready)
return;
+ if (_updateOutputVol)
+ updateOutputVolumeInternal();
+
for (uint32 i = 0; i < bufferSize; i++) {
_timer += _tickLength;
while (_timer > 0x514767) {
@@ -346,14 +572,12 @@ void TownsAudioInterface::nextTickEx(int32 *buffer, uint32 bufferSize) {
}
}
-void TownsAudioInterface::timerCallbackA() {
- Common::StackLock lock(_mutex);
+void TownsAudioInterfaceInternal::timerCallbackA() {
if (_drv && _ready)
_drv->timerCallback(0);
}
-void TownsAudioInterface::timerCallbackB() {
- Common::StackLock lock(_mutex);
+void TownsAudioInterfaceInternal::timerCallbackB() {
if (_ready) {
if (_drv)
_drv->timerCallback(1);
@@ -361,62 +585,62 @@ void TownsAudioInterface::timerCallbackB() {
}
}
-int TownsAudioInterface::intf_reset(va_list &args) {
+int TownsAudioInterfaceInternal::intf_reset(va_list &args) {
fmReset();
pcmReset();
callback(68);
return 0;
}
-int TownsAudioInterface::intf_keyOn(va_list &args) {
+int TownsAudioInterfaceInternal::intf_keyOn(va_list &args) {
int chan = va_arg(args, int);
int note = va_arg(args, int);
int velo = va_arg(args, int);
return (chan & 0x40) ? pcmKeyOn(chan, note, velo) : fmKeyOn(chan, note, velo);
}
-int TownsAudioInterface::intf_keyOff(va_list &args) {
+int TownsAudioInterfaceInternal::intf_keyOff(va_list &args) {
int chan = va_arg(args, int);
return (chan & 0x40) ? pcmKeyOff(chan) : fmKeyOff(chan);
}
-int TownsAudioInterface::intf_setPanPos(va_list &args) {
+int TownsAudioInterfaceInternal::intf_setPanPos(va_list &args) {
int chan = va_arg(args, int);
int mode = va_arg(args, int);
return (chan & 0x40) ? pcmSetPanPos(chan, mode) : fmSetPanPos(chan, mode);
}
-int TownsAudioInterface::intf_setInstrument(va_list &args) {
+int TownsAudioInterfaceInternal::intf_setInstrument(va_list &args) {
int chan = va_arg(args, int);
int instrId = va_arg(args, int);
return (chan & 0x40) ? pcmSetInstrument(chan, instrId) : fmSetInstrument(chan, instrId);
}
-int TownsAudioInterface::intf_loadInstrument(va_list &args) {
+int TownsAudioInterfaceInternal::intf_loadInstrument(va_list &args) {
int chanType = va_arg(args, int);
int instrId = va_arg(args, int);
uint8 *instrData = va_arg(args, uint8 *);
return (chanType & 0x40) ? pcmLoadInstrument(instrId, instrData) : fmLoadInstrument(instrId, instrData);
}
-int TownsAudioInterface::intf_setPitch(va_list &args) {
+int TownsAudioInterfaceInternal::intf_setPitch(va_list &args) {
int chan = va_arg(args, int);
int16 pitch = (int16)(va_arg(args, int) & 0xffff);
return (chan & 0x40) ? pcmSetPitch(chan, pitch) : fmSetPitch(chan, pitch);
}
-int TownsAudioInterface::intf_setLevel(va_list &args) {
+int TownsAudioInterfaceInternal::intf_setLevel(va_list &args) {
int chan = va_arg(args, int);
int lvl = va_arg(args, int);
return (chan & 0x40) ? pcmSetLevel(chan, lvl) : fmSetLevel(chan, lvl);
}
-int TownsAudioInterface::intf_chanOff(va_list &args) {
+int TownsAudioInterfaceInternal::intf_chanOff(va_list &args) {
int chan = va_arg(args, int);
return (chan & 0x40) ? pcmChanOff(chan) : fmChanOff(chan);
}
-int TownsAudioInterface::intf_writeReg(va_list &args) {
+int TownsAudioInterfaceInternal::intf_writeReg(va_list &args) {
int part = va_arg(args, int) ? 1 : 0;
int reg = va_arg(args, int);
int val = va_arg(args, int);
@@ -427,7 +651,7 @@ int TownsAudioInterface::intf_writeReg(va_list &args) {
return 0;
}
-int TownsAudioInterface::intf_writeRegBuffer(va_list &args) {
+int TownsAudioInterfaceInternal::intf_writeRegBuffer(va_list &args) {
int part = va_arg(args, int) ? 1 : 0;
int reg = va_arg(args, int);
int val = va_arg(args, int);
@@ -439,7 +663,7 @@ int TownsAudioInterface::intf_writeRegBuffer(va_list &args) {
return 0;
}
-int TownsAudioInterface::intf_readRegBuffer(va_list &args) {
+int TownsAudioInterfaceInternal::intf_readRegBuffer(va_list &args) {
int part = va_arg(args, int) ? 1 : 0;
int reg = va_arg(args, int);
uint8 *dst = va_arg(args, uint8 *);
@@ -452,7 +676,7 @@ int TownsAudioInterface::intf_readRegBuffer(va_list &args) {
return 0;
}
-int TownsAudioInterface::intf_setTimerA(va_list &args) {
+int TownsAudioInterfaceInternal::intf_setTimerA(va_list &args) {
int enable = va_arg(args, int);
int tempo = va_arg(args, int);
@@ -467,7 +691,7 @@ int TownsAudioInterface::intf_setTimerA(va_list &args) {
return 0;
}
-int TownsAudioInterface::intf_setTimerB(va_list &args) {
+int TownsAudioInterfaceInternal::intf_setTimerB(va_list &args) {
int enable = va_arg(args, int);
int tempo = va_arg(args, int);
@@ -481,17 +705,17 @@ int TownsAudioInterface::intf_setTimerB(va_list &args) {
return 0;
}
-int TownsAudioInterface::intf_enableTimerA(va_list &args) {
+int TownsAudioInterfaceInternal::intf_enableTimerA(va_list &args) {
bufferedWriteReg(0, 0x27, _fmSaveReg[0][0x27] | 0x15);
return 0;
}
-int TownsAudioInterface::intf_enableTimerB(va_list &args) {
+int TownsAudioInterfaceInternal::intf_enableTimerB(va_list &args) {
bufferedWriteReg(0, 0x27, _fmSaveReg[0][0x27] | 0x2a);
return 0;
}
-int TownsAudioInterface::intf_loadSamples(va_list &args) {
+int TownsAudioInterfaceInternal::intf_loadSamples(va_list &args) {
uint32 dest = va_arg(args, uint32);
int size = va_arg(args, int);
uint8 *src = va_arg(args, uint8*);
@@ -514,7 +738,7 @@ int TownsAudioInterface::intf_loadSamples(va_list &args) {
return 0;
}
-int TownsAudioInterface::intf_reserveEffectChannels(va_list &args) {
+int TownsAudioInterfaceInternal::intf_reserveEffectChannels(va_list &args) {
int numChan = va_arg(args, int);
if (numChan > 8)
return 3;
@@ -546,7 +770,7 @@ int TownsAudioInterface::intf_reserveEffectChannels(va_list &args) {
return 0;
}
-int TownsAudioInterface::intf_loadWaveTable(va_list &args) {
+int TownsAudioInterfaceInternal::intf_loadWaveTable(va_list &args) {
uint8 *data = va_arg(args, uint8 *);
if (_numWaveTables > 127)
return 3;
@@ -573,7 +797,7 @@ int TownsAudioInterface::intf_loadWaveTable(va_list &args) {
return 0;
}
-int TownsAudioInterface::intf_unloadWaveTable(va_list &args) {
+int TownsAudioInterfaceInternal::intf_unloadWaveTable(va_list &args) {
int id = va_arg(args, int);
if (id == -1) {
@@ -600,7 +824,7 @@ int TownsAudioInterface::intf_unloadWaveTable(va_list &args) {
return 0;
}
-int TownsAudioInterface::intf_pcmPlayEffect(va_list &args) {
+int TownsAudioInterfaceInternal::intf_pcmPlayEffect(va_list &args) {
int chan = va_arg(args, int);
int note = va_arg(args, int);
int velo = va_arg(args, int);
@@ -650,13 +874,13 @@ int TownsAudioInterface::intf_pcmPlayEffect(va_list &args) {
return 0;
}
-int TownsAudioInterface::intf_pcmChanOff(va_list &args) {
+int TownsAudioInterfaceInternal::intf_pcmChanOff(va_list &args) {
int chan = va_arg(args, int);
pcmChanOff(chan);
return 0;
}
-int TownsAudioInterface::intf_pcmEffectPlaying(va_list &args) {
+int TownsAudioInterfaceInternal::intf_pcmEffectPlaying(va_list &args) {
int chan = va_arg(args, int);
if (chan < 0x40 || chan > 0x47)
return 1;
@@ -664,54 +888,54 @@ int TownsAudioInterface::intf_pcmEffectPlaying(va_list &args) {
return (_pcmChanEffectPlaying & _chanFlags[chan]) ? 1 : 0;
}
-int TownsAudioInterface::intf_fmKeyOn(va_list &args) {
+int TownsAudioInterfaceInternal::intf_fmKeyOn(va_list &args) {
int chan = va_arg(args, int);
int note = va_arg(args, int);
int velo = va_arg(args, int);
return fmKeyOn(chan, note, velo);
}
-int TownsAudioInterface::intf_fmKeyOff(va_list &args) {
+int TownsAudioInterfaceInternal::intf_fmKeyOff(va_list &args) {
int chan = va_arg(args, int);
return fmKeyOff(chan);
}
-int TownsAudioInterface::intf_fmSetPanPos(va_list &args) {
+int TownsAudioInterfaceInternal::intf_fmSetPanPos(va_list &args) {
int chan = va_arg(args, int);
int mode = va_arg(args, int);
return fmSetPanPos(chan, mode);
}
-int TownsAudioInterface::intf_fmSetInstrument(va_list &args) {
+int TownsAudioInterfaceInternal::intf_fmSetInstrument(va_list &args) {
int chan = va_arg(args, int);
int instrId = va_arg(args, int);
return fmSetInstrument(chan, instrId);
}
-int TownsAudioInterface::intf_fmLoadInstrument(va_list &args) {
+int TownsAudioInterfaceInternal::intf_fmLoadInstrument(va_list &args) {
int instrId = va_arg(args, int);
uint8 *instrData = va_arg(args, uint8 *);
return fmLoadInstrument(instrId, instrData);
}
-int TownsAudioInterface::intf_fmSetPitch(va_list &args) {
+int TownsAudioInterfaceInternal::intf_fmSetPitch(va_list &args) {
int chan = va_arg(args, int);
uint16 freq = va_arg(args, int) & 0xffff;
return fmSetPitch(chan, freq);
}
-int TownsAudioInterface::intf_fmSetLevel(va_list &args) {
+int TownsAudioInterfaceInternal::intf_fmSetLevel(va_list &args) {
int chan = va_arg(args, int);
int lvl = va_arg(args, int);
return fmSetLevel(chan, lvl);
}
-int TownsAudioInterface::intf_fmReset(va_list &args) {
+int TownsAudioInterfaceInternal::intf_fmReset(va_list &args) {
fmReset();
return 0;
}
-int TownsAudioInterface::intf_setOutputVolume(va_list &args) {
+int TownsAudioInterfaceInternal::intf_setOutputVolume(va_list &args) {
int chanType = va_arg(args, int);
int left = va_arg(args, int);
int right = va_arg(args, int);
@@ -727,18 +951,20 @@ int TownsAudioInterface::intf_setOutputVolume(va_list &args) {
left = (left & 0x7e) >> 1;
right = (right & 0x7e) >> 1;
- if (chan)
+ if (chan == 12)
_outputVolumeFlags |= flags[chanType];
else
_outputVolumeFlags &= ~flags[chanType];
if (chanType > 1) {
_outputLevel[chan + chanType] = left;
+ _outputMute[chan + chanType] = 0;
} else {
if (chanType == 0)
chan -= 8;
_outputLevel[chan] = left;
_outputLevel[chan + 1] = right;
+ _outputMute[chan] = _outputMute[chan + 1] = 0;
}
updateOutputVolume();
@@ -746,38 +972,87 @@ int TownsAudioInterface::intf_setOutputVolume(va_list &args) {
return 0;
}
-int TownsAudioInterface::intf_resetOutputVolume(va_list &args) {
+int TownsAudioInterfaceInternal::intf_resetOutputVolume(va_list &args) {
memset(_outputLevel, 0, sizeof(_outputLevel));
- _outputMuteFlags = 0;
_outputVolumeFlags = 0;
updateOutputVolume();
return 0;
}
-int TownsAudioInterface::intf_updateOutputVolume(va_list &args) {
+int TownsAudioInterfaceInternal::intf_getOutputVolume(va_list &args) {
+ int chanType = va_arg(args, int);
+ int *left = va_arg(args, int*);
+ int *right = va_arg(args, int*);
+
+ uint8 chan = (chanType & 0x40) ? 8 : 12;
+ chanType &= 3;
+
+ if (chanType > 1) {
+ *left = _outputLevel[chan + chanType] & 0x3f;
+ } else {
+ if (chanType == 0)
+ chan -= 8;
+ *left = _outputLevel[chan] & 0x3f;
+ *right = _outputLevel[chan + 1] & 0x3f;
+ }
+
+ return 0;
+}
+
+int TownsAudioInterfaceInternal::intf_setOutputMute(va_list &args) {
int flags = va_arg(args, int);
- _outputMuteFlags = flags & 3;
+ _outputVolumeFlags = flags;
+ uint8 mute = flags & 3;
+ uint8 f = flags & 0xff;
+
+ memset(_outputMute, 1, 8);
+ if (mute & 2)
+ memset(&_outputMute[12], 1, 4);
+ if (mute & 1)
+ memset(&_outputMute[8], 1, 4);
+
+ _outputMute[(f < 0x80) ? 11 : 15] = 0;
+ f += f;
+ _outputMute[(f < 0x80) ? 10 : 14] = 0;
+ f += f;
+ _outputMute[(f < 0x80) ? 8 : 12] = 0;
+ f += f;
+ _outputMute[(f < 0x80) ? 9 : 13] = 0;
+ f += f;
+ _outputMute[(f < 0x80) ? 0 : 4] = 0;
+ f += f;
+ _outputMute[(f < 0x80) ? 1 : 5] = 0;
+ f += f;
+
updateOutputVolume();
return 0;
}
-int TownsAudioInterface::intf_cdaToggle(va_list &args) {
+int TownsAudioInterfaceInternal::intf_cdaToggle(va_list &args) {
//int mode = va_arg(args, int);
//_unkMask = mode ? 0x7f : 0x3f;
return 0;
}
-int TownsAudioInterface::intf_pcmUpdateEnvelopeGenerator(va_list &args) {
+int TownsAudioInterfaceInternal::intf_getOutputVolume2(va_list &args) {
+ return 0;
+}
+
+int TownsAudioInterfaceInternal::intf_getOutputMute (va_list &args) {
+ return 0;
+}
+
+int TownsAudioInterfaceInternal::intf_pcmUpdateEnvelopeGenerator(va_list &args) {
for (int i = 0; i < 8; i++)
pcmUpdateEnvelopeGenerator(i);
return 0;
}
-int TownsAudioInterface::intf_notImpl(va_list &args) {
+int TownsAudioInterfaceInternal::intf_notImpl(va_list &args) {
return 4;
}
-void TownsAudioInterface::fmReset() {
+void TownsAudioInterfaceInternal::fmReset() {
TownsPC98_FmSynth::reset();
_fmChanPlaying = 0;
@@ -805,7 +1080,7 @@ void TownsAudioInterface::fmReset() {
}
}
-int TownsAudioInterface::fmKeyOn(int chan, int note, int velo) {
+int TownsAudioInterfaceInternal::fmKeyOn(int chan, int note, int velo) {
if (chan > 5)
return 1;
if (note < 12 || note > 107 || (velo & 0x80))
@@ -885,7 +1160,7 @@ int TownsAudioInterface::fmKeyOn(int chan, int note, int velo) {
return 0;
}
-int TownsAudioInterface::fmKeyOff(int chan) {
+int TownsAudioInterfaceInternal::fmKeyOff(int chan) {
if (chan > 5)
return 1;
_fmChanPlaying &= ~_chanFlags[chan];
@@ -895,7 +1170,7 @@ int TownsAudioInterface::fmKeyOff(int chan) {
return 0;
}
-int TownsAudioInterface::fmChanOff(int chan) {
+int TownsAudioInterfaceInternal::fmChanOff(int chan) {
if (chan > 5)
return 1;
_fmChanPlaying &= ~_chanFlags[chan];
@@ -913,7 +1188,7 @@ int TownsAudioInterface::fmChanOff(int chan) {
return 0;
}
-int TownsAudioInterface::fmSetPanPos(int chan, int value) {
+int TownsAudioInterfaceInternal::fmSetPanPos(int chan, int value) {
if (chan > 5)
return 1;
@@ -932,7 +1207,7 @@ int TownsAudioInterface::fmSetPanPos(int chan, int value) {
return 0;
}
-int TownsAudioInterface::fmSetInstrument(int chan, int instrId) {
+int TownsAudioInterfaceInternal::fmSetInstrument(int chan, int instrId) {
if (chan > 5)
return 1;
if (instrId > 127)
@@ -976,7 +1251,7 @@ int TownsAudioInterface::fmSetInstrument(int chan, int instrId) {
return 0;
}
-int TownsAudioInterface::fmLoadInstrument(int instrId, const uint8 *data) {
+int TownsAudioInterfaceInternal::fmLoadInstrument(int instrId, const uint8 *data) {
if (instrId > 127)
return 3;
assert(data);
@@ -984,7 +1259,7 @@ int TownsAudioInterface::fmLoadInstrument(int instrId, const uint8 *data) {
return 0;
}
-int TownsAudioInterface::fmSetPitch(int chan, int pitch) {
+int TownsAudioInterfaceInternal::fmSetPitch(int chan, int pitch) {
if (chan > 5)
return 1;
@@ -1071,7 +1346,7 @@ int TownsAudioInterface::fmSetPitch(int chan, int pitch) {
return 0;
}
-int TownsAudioInterface::fmSetLevel(int chan, int lvl) {
+int TownsAudioInterfaceInternal::fmSetLevel(int chan, int lvl) {
if (chan > 5)
return 1;
if (lvl > 127)
@@ -1094,12 +1369,12 @@ int TownsAudioInterface::fmSetLevel(int chan, int lvl) {
return 0;
}
-void TownsAudioInterface::bufferedWriteReg(uint8 part, uint8 regAddress, uint8 value) {
+void TownsAudioInterfaceInternal::bufferedWriteReg(uint8 part, uint8 regAddress, uint8 value) {
_fmSaveReg[part][regAddress] = value;
writeReg(part, regAddress, value);
}
-void TownsAudioInterface::pcmReset() {
+void TownsAudioInterfaceInternal::pcmReset() {
_pcmChanOut = 0;
_pcmChanReserved = _pcmChanKeyPressed = _pcmChanEffectPlaying = _pcmChanKeyPlaying = 0;
_numReservedChannels = 0;
@@ -1127,7 +1402,7 @@ void TownsAudioInterface::pcmReset() {
}
}
-int TownsAudioInterface::pcmKeyOn(int chan, int note, int velo) {
+int TownsAudioInterfaceInternal::pcmKeyOn(int chan, int note, int velo) {
if (chan < 0x40 || chan > 0x47)
return 1;
@@ -1198,7 +1473,7 @@ int TownsAudioInterface::pcmKeyOn(int chan, int note, int velo) {
return 0;
}
-int TownsAudioInterface::pcmKeyOff(int chan) {
+int TownsAudioInterfaceInternal::pcmKeyOff(int chan) {
if (chan < 0x40 || chan > 0x47)
return 1;
@@ -1208,7 +1483,7 @@ int TownsAudioInterface::pcmKeyOff(int chan) {
return 0;
}
-int TownsAudioInterface::pcmChanOff(int chan) {
+int TownsAudioInterfaceInternal::pcmChanOff(int chan) {
if (chan < 0x40 || chan > 0x47)
return 1;
@@ -1222,7 +1497,7 @@ int TownsAudioInterface::pcmChanOff(int chan) {
return 0;
}
-int TownsAudioInterface::pcmSetPanPos(int chan, int mode) {
+int TownsAudioInterfaceInternal::pcmSetPanPos(int chan, int mode) {
if (chan > 0x47)
return 1;
if (mode & 0x80)
@@ -1245,7 +1520,7 @@ int TownsAudioInterface::pcmSetPanPos(int chan, int mode) {
return 0;
}
-int TownsAudioInterface::pcmSetInstrument(int chan, int instrId) {
+int TownsAudioInterfaceInternal::pcmSetInstrument(int chan, int instrId) {
if (chan > 0x47)
return 1;
if (instrId > 31)
@@ -1255,7 +1530,7 @@ int TownsAudioInterface::pcmSetInstrument(int chan, int instrId) {
return 0;
}
-int TownsAudioInterface::pcmLoadInstrument(int instrId, const uint8 *data) {
+int TownsAudioInterfaceInternal::pcmLoadInstrument(int instrId, const uint8 *data) {
if (instrId > 31)
return 3;
assert(data);
@@ -1263,7 +1538,7 @@ int TownsAudioInterface::pcmLoadInstrument(int instrId, const uint8 *data) {
return 0;
}
-int TownsAudioInterface::pcmSetPitch(int chan, int pitch) {
+int TownsAudioInterfaceInternal::pcmSetPitch(int chan, int pitch) {
if (chan > 0x47)
return 1;
@@ -1293,7 +1568,7 @@ int TownsAudioInterface::pcmSetPitch(int chan, int pitch) {
return 0;
}
-int TownsAudioInterface::pcmSetLevel(int chan, int lvl) {
+int TownsAudioInterfaceInternal::pcmSetLevel(int chan, int lvl) {
if (chan > 0x47)
return 1;
@@ -1322,7 +1597,7 @@ int TownsAudioInterface::pcmSetLevel(int chan, int lvl) {
return 0;
}
-void TownsAudioInterface::pcmUpdateEnvelopeGenerator(int chan) {
+void TownsAudioInterfaceInternal::pcmUpdateEnvelopeGenerator(int chan) {
TownsAudio_PcmChannel *p = &_pcmChan[chan];
if (!p->envCurrentLevel) {
_pcmChanKeyPlaying &= ~_chanFlags[chan];
@@ -1364,7 +1639,7 @@ void TownsAudioInterface::pcmUpdateEnvelopeGenerator(int chan) {
p->velo = (p->envCurrentLevel >> 8) << 1;
}
-void TownsAudioInterface::pcmCalcPhaseStep(TownsAudio_PcmChannel *p, TownsAudio_WaveTable *w) {
+void TownsAudioInterfaceInternal::pcmCalcPhaseStep(TownsAudio_PcmChannel *p, TownsAudio_WaveTable *w) {
int8 diff = p->note - w->baseNote;
uint16 r = w->rate + w->rateOffs;
uint16 bl = 0;
@@ -1393,45 +1668,60 @@ void TownsAudioInterface::pcmCalcPhaseStep(TownsAudio_PcmChannel *p, TownsAudio_
p->step = (s * p->stepPitch) >> 14;
}
-void TownsAudioInterface::updateOutputVolume() {
+void TownsAudioInterfaceInternal::updateOutputVolume() {
+ // Avoid calls to g_system->getAudioCDManager() functions from the main thread
+ // since this can cause mutex lockups.
+ _updateOutputVol = true;
+}
+
+void TownsAudioInterfaceInternal::updateOutputVolumeInternal() {
+ if (!_ready)
+ return;
+
// FM Towns seems to support volumes of 0 - 63 for each channel.
// We recalculate sane values for our 0 to 255 volume range and
// balance values for our -128 to 127 volume range
// CD-AUDIO
- uint32 maxVol = MAX(_outputLevel[12], _outputLevel[13]);
+ uint32 maxVol = MAX(_outputLevel[12] * (_outputMute[12] ^ 1), _outputLevel[13] * (_outputMute[13] ^ 1));
int volume = (int)(((float)(maxVol * 255) / 63.0f));
- int balance = maxVol ? (int)( ( ((int)_outputLevel[13] - _outputLevel[12]) * 127) / (float)maxVol) : 0;
+ int balance = maxVol ? (int)( ( ((int)_outputLevel[13] * (_outputMute[13] ^ 1) - _outputLevel[12] * (_outputMute[12] ^ 1)) * 127) / (float)maxVol) : 0;
g_system->getAudioCDManager()->setVolume(volume);
g_system->getAudioCDManager()->setBalance(balance);
+
+ _updateOutputVol = false;
}
-const uint8 TownsAudioInterface::_chanFlags[] = {
+TownsAudioInterfaceInternal *TownsAudioInterfaceInternal::_refInstance = 0;
+
+int TownsAudioInterfaceInternal::_refCount = 0;
+
+const uint8 TownsAudioInterfaceInternal::_chanFlags[] = {
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80
};
-const uint16 TownsAudioInterface::_frequency[] = {
+const uint16 TownsAudioInterfaceInternal::_frequency[] = {
0x028C, 0x02B4, 0x02DC, 0x030A, 0x0338, 0x0368, 0x039C, 0x03D4, 0x040E, 0x044A, 0x048C, 0x04D0
};
-const uint8 TownsAudioInterface::_carrier[] = {
+const uint8 TownsAudioInterfaceInternal::_carrier[] = {
0x10, 0x10, 0x10, 0x10, 0x30, 0x70, 0x70, 0xF0
};
-const uint8 TownsAudioInterface::_fmDefaultInstrument[] = {
+const uint8 TownsAudioInterfaceInternal::_fmDefaultInstrument[] = {
0x45, 0x4C, 0x45, 0x50, 0x49, 0x41, 0x4E, 0x4F, 0x01, 0x0A, 0x02, 0x01,
0x1E, 0x32, 0x05, 0x00, 0x9C, 0xDC, 0x9C, 0xDC, 0x07, 0x03, 0x14, 0x08,
0x00, 0x03, 0x05, 0x05, 0x55, 0x45, 0x27, 0xA7, 0x04, 0xC0, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
-const uint16 TownsAudioInterface::_pcmPhase1[] = {
+const uint16 TownsAudioInterfaceInternal::_pcmPhase1[] = {
0x879B, 0x0F37, 0x1F58, 0x306E, 0x4288, 0x55B6, 0x6A08, 0x7F8F, 0x965E, 0xAE88, 0xC882, 0xE341
};
-const uint16 TownsAudioInterface::_pcmPhase2[] = {
+const uint16 TownsAudioInterfaceInternal::_pcmPhase2[] = {
0xFEFE, 0xF1A0, 0xE411, 0xD744, 0xCB2F, 0xBFC7, 0xB504, 0xAAE2, 0xA144, 0x9827, 0x8FAC
};
@@ -1582,3 +1872,37 @@ void TownsAudio_WaveTable::clear() {
data = 0;
}
+TownsAudioInterface::TownsAudioInterface(Audio::Mixer *mixer, TownsAudioInterfacePluginDriver *driver, bool externalMutexHandling) {
+ _intf = TownsAudioInterfaceInternal::addNewRef(mixer, this, driver, externalMutexHandling);
+}
+
+TownsAudioInterface::~TownsAudioInterface() {
+ TownsAudioInterfaceInternal::releaseRef(this);
+ _intf = 0;
+}
+
+bool TownsAudioInterface::init() {
+ return _intf->init();
+}
+
+int TownsAudioInterface::callback(int command, ...) {
+ va_list args;
+ va_start(args, command);
+
+ int res = _intf->processCommand(command, args);
+
+ va_end(args);
+ return res;
+}
+
+void TownsAudioInterface::setMusicVolume(int volume) {
+ _intf->setMusicVolume(volume);
+}
+
+void TownsAudioInterface::setSoundEffectVolume(int volume) {
+ _intf->setSoundEffectVolume(volume);
+}
+
+void TownsAudioInterface::setSoundEffectChanMask(int mask) {
+ _intf->setSoundEffectChanMask(mask);
+}
diff --git a/audio/softsynth/fmtowns_pc98/towns_audio.h b/audio/softsynth/fmtowns_pc98/towns_audio.h
index 2819ab2d57..4af888f009 100644
--- a/audio/softsynth/fmtowns_pc98/towns_audio.h
+++ b/audio/softsynth/fmtowns_pc98/towns_audio.h
@@ -18,15 +18,14 @@
* 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$
- *
*/
#ifndef TOWNS_AUDIO_H
#define TOWNS_AUDIO_H
-#include "audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h"
+#include "audio/mixer.h"
+
+class TownsAudioInterfaceInternal;
class TownsAudioInterfacePluginDriver {
public:
@@ -34,12 +33,9 @@ public:
virtual void timerCallback(int timerId) = 0;
};
-class TownsAudio_PcmChannel;
-class TownsAudio_WaveTable;
-
-class TownsAudioInterface : public TownsPC98_FmSynth {
+class TownsAudioInterface {
public:
- TownsAudioInterface(Audio::Mixer *mixer, TownsAudioInterfacePluginDriver *driver);
+ TownsAudioInterface(Audio::Mixer *mixer, TownsAudioInterfacePluginDriver *driver, bool externalMutexHandling = false);
~TownsAudioInterface();
bool init();
@@ -53,126 +49,7 @@ public:
void setSoundEffectChanMask(int mask);
private:
- void nextTickEx(int32 *buffer, uint32 bufferSize);
-
- void timerCallbackA();
- void timerCallbackB();
-
- typedef int (TownsAudioInterface::*TownsAudioIntfCallback)(va_list &);
- const TownsAudioIntfCallback *_intfOpcodes;
-
- int intf_reset(va_list &args);
- int intf_keyOn(va_list &args);
- int intf_keyOff(va_list &args);
- int intf_setPanPos(va_list &args);
- int intf_setInstrument(va_list &args);
- int intf_loadInstrument(va_list &args);
- int intf_setPitch(va_list &args);
- int intf_setLevel(va_list &args);
- int intf_chanOff(va_list &args);
- int intf_writeReg(va_list &args);
- int intf_writeRegBuffer(va_list &args);
- int intf_readRegBuffer(va_list &args);
- int intf_setTimerA(va_list &args);
- int intf_setTimerB(va_list &args);
- int intf_enableTimerA(va_list &args);
- int intf_enableTimerB(va_list &args);
- int intf_loadSamples(va_list &args);
- int intf_reserveEffectChannels(va_list &args);
- int intf_loadWaveTable(va_list &args);
- int intf_unloadWaveTable(va_list &args);
- int intf_pcmPlayEffect(va_list &args);
- int intf_pcmChanOff(va_list &args);
- int intf_pcmEffectPlaying(va_list &args);
- int intf_fmKeyOn(va_list &args);
- int intf_fmKeyOff(va_list &args);
- int intf_fmSetPanPos(va_list &args);
- int intf_fmSetInstrument(va_list &args);
- int intf_fmLoadInstrument(va_list &args);
- int intf_fmSetPitch(va_list &args);
- int intf_fmSetLevel(va_list &args);
- int intf_fmReset(va_list &args);
- int intf_setOutputVolume(va_list &args);
- int intf_resetOutputVolume(va_list &args);
- int intf_updateOutputVolume(va_list &args);
- int intf_cdaToggle(va_list &args);
- int intf_pcmUpdateEnvelopeGenerator(va_list &args);
-
- int intf_notImpl(va_list &args);
-
- void fmReset();
- int fmKeyOn(int chan, int note, int velo);
- int fmKeyOff(int chan);
- int fmChanOff(int chan);
- int fmSetPanPos(int chan, int mode);
- int fmSetInstrument(int chan, int instrId);
- int fmLoadInstrument(int instrId, const uint8 *data);
- int fmSetPitch(int chan, int pitch);
- int fmSetLevel(int chan, int lvl);
-
- void bufferedWriteReg(uint8 part, uint8 regAddress, uint8 value);
-
- uint8 _fmChanPlaying;
- uint8 _fmChanNote[6];
- int16 _fmChanPitch[6];
-
- uint8 *_fmSaveReg[2];
- uint8 *_fmInstruments;
-
- void pcmReset();
- int pcmKeyOn(int chan, int note, int velo);
- int pcmKeyOff(int chan);
- int pcmChanOff(int chan);
- int pcmSetPanPos(int chan, int mode);
- int pcmSetInstrument(int chan, int instrId);
- int pcmLoadInstrument(int instrId, const uint8 *data);
- int pcmSetPitch(int chan, int pitch);
- int pcmSetLevel(int chan, int lvl);
- void pcmUpdateEnvelopeGenerator(int chan);
-
- TownsAudio_PcmChannel *_pcmChan;
- uint8 _pcmChanOut;
- uint8 _pcmChanReserved;
- uint8 _pcmChanKeyPressed;
- uint8 _pcmChanEffectPlaying;
- uint8 _pcmChanKeyPlaying;
-
- uint8 _pcmChanNote[8];
- uint8 _pcmChanVelo[8];
- uint8 _pcmChanLevel[8];
-
- uint8 _numReservedChannels;
- uint8 *_pcmInstruments;
-
- TownsAudio_WaveTable *_waveTables;
- uint8 _numWaveTables;
- uint32 _waveTablesTotalDataSize;
-
- void pcmCalcPhaseStep(TownsAudio_PcmChannel *p, TownsAudio_WaveTable *w);
-
- void updateOutputVolume();
- uint8 _outputVolumeFlags;
- uint8 _outputLevel[16];
- uint8 _outputMuteFlags;
-
- const float _baserate;
- uint32 _timerBase;
- uint32 _tickLength;
- uint32 _timer;
-
- uint16 _musicVolume;
- uint16 _sfxVolume;
- int _pcmSfxChanMask;
-
- TownsAudioInterfacePluginDriver *_drv;
- bool _ready;
-
- static const uint8 _chanFlags[];
- static const uint16 _frequency[];
- static const uint8 _carrier[];
- static const uint8 _fmDefaultInstrument[];
- static const uint16 _pcmPhase1[];
- static const uint16 _pcmPhase2[];
+ TownsAudioInterfaceInternal *_intf;
};
#endif
diff --git a/audio/softsynth/fmtowns_pc98/towns_euphony.cpp b/audio/softsynth/fmtowns_pc98/towns_euphony.cpp
index cd3a348b85..bc2c88b236 100644
--- a/audio/softsynth/fmtowns_pc98/towns_euphony.cpp
+++ b/audio/softsynth/fmtowns_pc98/towns_euphony.cpp
@@ -18,9 +18,6 @@
* 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$
- *
*/
#include "audio/softsynth/fmtowns_pc98/towns_euphony.h"
@@ -31,7 +28,8 @@
TownsEuphonyDriver::TownsEuphonyDriver(Audio::Mixer *mixer) : _activeChannels(0), _sustainChannels(0),
_assignedChannels(0), _paraCount(0), _command(0), _tEnable(0), _tMode(0), _tOrdr(0), _tLevel(0),
_tTranspose(0), _musicPos(0), _musicStart(0), _playing(false), _eventBuffer(0), _bufferedEventsCount(0),
- _tempoControlMode(0) {
+ _tempoControlMode(0), _timerSetting(0), _tempoDiff(0), _timeStampBase(0), _elapsedEvents(0), _loop(false),
+ _endOfTrack(false), _suspendParsing(false), _musicTrackSize(0) {
_para[0] = _para[1] = 0;
_intf = new TownsAudioInterface(mixer, this);
resetTempo();
@@ -84,7 +82,7 @@ void TownsEuphonyDriver::reset() {
_intf->callback(0);
_intf->callback(74);
- _intf->callback(70);
+ _intf->callback(70, 0);
_intf->callback(75, 3);
setTimerA(true, 1);
@@ -223,21 +221,21 @@ void TownsEuphonyDriver::setOutputVolume(int mode, int volLeft, int volRight) {
_intf->callback(67, mode, volLeft, volRight);
}
-int TownsEuphonyDriver::chanEnable(int tableEntry, int val) {
+int TownsEuphonyDriver::configChan_enable(int tableEntry, int val) {
if (tableEntry > 31)
return 3;
_tEnable[tableEntry] = val;
return 0;
}
-int TownsEuphonyDriver::chanMode(int tableEntry, int val) {
+int TownsEuphonyDriver::configChan_setMode(int tableEntry, int val) {
if (tableEntry > 31)
return 3;
_tMode[tableEntry] = val;
return 0;
}
-int TownsEuphonyDriver::chanOrdr(int tableEntry, int val) {
+int TownsEuphonyDriver::configChan_remap(int tableEntry, int val) {
if (tableEntry > 31)
return 3;
if (val < 16)
@@ -245,7 +243,7 @@ int TownsEuphonyDriver::chanOrdr(int tableEntry, int val) {
return 0;
}
-int TownsEuphonyDriver::chanVolumeShift(int tableEntry, int val) {
+int TownsEuphonyDriver::configChan_adjustVolume(int tableEntry, int val) {
if (tableEntry > 31)
return 3;
if (val <= 40)
@@ -253,7 +251,7 @@ int TownsEuphonyDriver::chanVolumeShift(int tableEntry, int val) {
return 0;
}
-int TownsEuphonyDriver::chanNoteShift(int tableEntry, int val) {
+int TownsEuphonyDriver::configChan_setTranspose(int tableEntry, int val) {
if (tableEntry > 31)
return 3;
if (val <= 40)
@@ -675,8 +673,8 @@ bool TownsEuphonyDriver::evtSetupNote() {
uint8 velo = _musicPos[5];
sendEvent(mode, evt);
- sendEvent(mode, applyNoteShift(note));
- sendEvent(mode, applyVolumeShift(velo));
+ sendEvent(mode, applyTranspose(note));
+ sendEvent(mode, applyVolumeAdjust(velo));
jumpNextLoop();
if (_musicPos[0] == 0xfe || _musicPos[0] == 0xfd)
@@ -715,7 +713,7 @@ bool TownsEuphonyDriver::evtPolyphonicAftertouch() {
uint8 mode = _tMode[_musicPos[1]];
sendEvent(mode, evt);
- sendEvent(mode, applyNoteShift(_musicPos[4]));
+ sendEvent(mode, applyTranspose(_musicPos[4]));
sendEvent(mode, _musicPos[5]);
return false;
@@ -783,7 +781,7 @@ bool TownsEuphonyDriver::evtModeOrdrChange() {
return false;
}
-uint8 TownsEuphonyDriver::applyNoteShift(uint8 in) {
+uint8 TownsEuphonyDriver::applyTranspose(uint8 in) {
int out = _tTranspose[_musicPos[1]];
if (!out)
return in;
@@ -798,7 +796,7 @@ uint8 TownsEuphonyDriver::applyNoteShift(uint8 in) {
return out & 0xff;
}
-uint8 TownsEuphonyDriver::applyVolumeShift(uint8 in) {
+uint8 TownsEuphonyDriver::applyVolumeAdjust(uint8 in) {
int out = _tLevel[_musicPos[1]];
out += (in & 0x7f);
out = CLIP(out, 1, 127);
diff --git a/audio/softsynth/fmtowns_pc98/towns_euphony.h b/audio/softsynth/fmtowns_pc98/towns_euphony.h
index dc40373913..6b30bfb7f5 100644
--- a/audio/softsynth/fmtowns_pc98/towns_euphony.h
+++ b/audio/softsynth/fmtowns_pc98/towns_euphony.h
@@ -18,9 +18,6 @@
* 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$
- *
*/
#ifndef TOWNS_EUP_H
@@ -58,11 +55,11 @@ public:
void setOutputVolume(int chanType, int volLeft, int volRight);
- int chanEnable(int tableEntry, int val);
- int chanMode(int tableEntry, int val);
- int chanOrdr(int tableEntry, int val);
- int chanVolumeShift(int tableEntry, int val);
- int chanNoteShift(int tableEntry, int val);
+ int configChan_enable(int tableEntry, int val);
+ int configChan_setMode(int tableEntry, int val);
+ int configChan_remap(int tableEntry, int val);
+ int configChan_adjustVolume(int tableEntry, int val);
+ int configChan_setTranspose(int tableEntry, int val);
int assignChannel(int chan, int tableEntry);
@@ -114,8 +111,8 @@ private:
return false;
}
- uint8 applyNoteShift(uint8 in);
- uint8 applyVolumeShift(uint8 in);
+ uint8 applyTranspose(uint8 in);
+ uint8 applyVolumeAdjust(uint8 in);
void sendNoteOff();
void sendNoteOn();
diff --git a/audio/softsynth/fmtowns_pc98/towns_midi.cpp b/audio/softsynth/fmtowns_pc98/towns_midi.cpp
new file mode 100644
index 0000000000..4617b0555c
--- /dev/null
+++ b/audio/softsynth/fmtowns_pc98/towns_midi.cpp
@@ -0,0 +1,1043 @@
+/* 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.
+ *
+ */
+
+#include "audio/softsynth/fmtowns_pc98/towns_midi.h"
+#include "audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h"
+#include "common/textconsole.h"
+#include "common/system.h"
+
+class TownsMidiOutputChannel {
+friend class TownsMidiInputChannel;
+public:
+ TownsMidiOutputChannel(MidiDriver_TOWNS *driver, int chanId);
+ ~TownsMidiOutputChannel();
+
+ void noteOn(uint8 msb, uint16 lsb);
+ void noteOnPitchBend(uint8 msb, uint16 lsb);
+ void setupProgram(const uint8 *data, uint8 mLevelPara, uint8 tLevelPara);
+ void setupEffects(int index, uint8 flags, const uint8 *effectData);
+ void setModWheel(uint8 value);
+
+ void connect(TownsMidiInputChannel *chan);
+ void disconnect();
+
+ bool update();
+
+ enum CheckPriorityStatus {
+ kDisconnected = -2,
+ kHighPriority = -1
+ };
+
+ int checkPriority(int pri);
+
+private:
+ struct EffectEnvelope {
+ uint8 state;
+ int32 currentLevel;
+ int32 duration;
+ int32 maxLevel;
+ int32 startLevel;
+ uint8 loop;
+ uint8 stateTargetLevels[4];
+ uint8 stateModWheelLevels[4];
+ int8 modWheelSensitivity;
+ int8 modWheelState;
+ int8 modWheelLast;
+ uint16 numSteps;
+ uint32 stepCounter;
+ int32 incrPerStep;
+ int8 dir;
+ uint32 incrPerStepRem;
+ uint32 incrCountRem;
+ } *_effectEnvelopes;
+
+ struct EffectDef {
+ int32 phase;
+ uint8 type;
+ uint8 useModWheel;
+ uint8 loopRefresh;
+ EffectEnvelope *s;
+ } *_effectDefs;
+
+ void startEffect(EffectEnvelope *s, const uint8 *effectData);
+ void updateEffectGenerator(EffectEnvelope *s, EffectDef *d);
+ int advanceEffectEnvelope(EffectEnvelope *s, EffectDef *d);
+ void initNextEnvelopeState(EffectEnvelope *s);
+ int16 getEffectStartLevel(uint8 type);
+ int getEffectModLevel(int lvl, int mod);
+
+ void keyOn();
+ void keyOff();
+ void keyOnSetFreq(uint16 frq);
+ void out(uint8 reg, uint8 val);
+
+ TownsMidiInputChannel *_in;
+ TownsMidiOutputChannel *_prev;
+ TownsMidiOutputChannel *_next;
+ uint8 _adjustModTl;
+ uint8 _chan;
+ uint8 _note;
+ uint8 _operator2Tl;
+ uint8 _operator1Tl;
+ uint8 _sustainNoteOff;
+ int16 _duration;
+
+ uint16 _freq;
+ int16 _freqAdjust;
+
+ MidiDriver_TOWNS *_driver;
+
+ static const uint8 _chanMap[];
+ static const uint8 _chanMap2[];
+ static const uint8 _effectDefaults[];
+ static const uint16 _effectEnvStepTable[];
+ static const uint8 _freqMSB[];
+ static const uint16 _freqLSB[];
+};
+
+class TownsMidiInputChannel : public MidiChannel {
+friend class TownsMidiOutputChannel;
+public:
+ TownsMidiInputChannel(MidiDriver_TOWNS *driver, int chanIndex);
+ ~TownsMidiInputChannel();
+
+ MidiDriver *device() { return _driver; }
+ byte getNumber() { return _chanIndex; }
+ bool allocate();
+ void release();
+
+ void send(uint32 b);
+
+ void noteOff(byte note);
+ void noteOn(byte note, byte velocity);
+ void programChange(byte program);
+ void pitchBend(int16 bend);
+ void controlChange(byte control, byte value);
+ void pitchBendFactor(byte value);
+ void priority(byte value);
+ void sysEx_customInstrument(uint32 type, const byte *instr);
+
+private:
+ void controlModulationWheel(byte value);
+ void controlVolume(byte value);
+ void controlPanPos(byte value);
+ void controlSustain(byte value);
+
+ void releasePedal();
+
+ TownsMidiOutputChannel *_out;
+
+ uint8 *_instrument;
+ uint8 _prg;
+ uint8 _chanIndex;
+ uint8 _effectLevel;
+ uint8 _priority;
+ uint8 _ctrlVolume;
+ uint8 _tl;
+ uint8 _pan;
+ uint8 _panEff;
+ uint8 _percS;
+ int8 _transpose;
+ uint8 _fld_1f;
+ int8 _detune;
+ int8 _modWheel;
+ uint8 _sustain;
+ uint8 _pitchBendFactor;
+ int16 _pitchBend;
+ uint16 _freqLSB;
+
+ bool _allocated;
+
+ MidiDriver_TOWNS *_driver;
+
+ static const uint8 _programAdjustLevel[];
+};
+
+class TownsMidiChanState {
+public:
+ TownsMidiChanState();
+ ~TownsMidiChanState() {}
+ uint8 get(uint8 type);
+
+ uint8 unk1;
+ uint8 mulAmsFms;
+ uint8 tl;
+ uint8 attDec;
+ uint8 sus;
+ uint8 fgAlg;
+ uint8 unk2;
+};
+
+TownsMidiChanState::TownsMidiChanState() {
+ unk1 = mulAmsFms = tl = attDec = sus = fgAlg = unk2 = 0;
+}
+
+uint8 TownsMidiChanState::get(uint8 type) {
+ switch (type) {
+ case 0:
+ return unk1;
+ case 1:
+ return mulAmsFms;
+ case 2:
+ return tl;
+ case 3:
+ return attDec;
+ case 4:
+ return sus;
+ case 5:
+ return fgAlg;
+ case 6:
+ return unk2;
+ default:
+ break;
+ }
+ return 0;
+}
+
+TownsMidiOutputChannel::TownsMidiOutputChannel(MidiDriver_TOWNS *driver, int chanIndex) : _driver(driver), _chan(chanIndex),
+ _in(0), _prev(0), _next(0), _adjustModTl(0), _operator2Tl(0), _note(0), _operator1Tl(0), _sustainNoteOff(0), _duration(0), _freq(0), _freqAdjust(0) {
+ _effectEnvelopes = new EffectEnvelope[2];
+ _effectDefs = new EffectDef[2];
+
+ memset(_effectEnvelopes, 0, 2 * sizeof(EffectEnvelope));
+ memset(_effectDefs, 0, 2 * sizeof(EffectDef));
+ _effectDefs[0].s = &_effectEnvelopes[1];
+ _effectDefs[1].s = &_effectEnvelopes[0];
+}
+
+TownsMidiOutputChannel::~TownsMidiOutputChannel() {
+ delete[] _effectEnvelopes;
+ delete[] _effectDefs;
+}
+
+void TownsMidiOutputChannel::noteOn(uint8 msb, uint16 lsb) {
+ _freq = (msb << 7) + lsb;
+ _freqAdjust = 0;
+ keyOnSetFreq(_freq);
+}
+
+void TownsMidiOutputChannel::noteOnPitchBend(uint8 msb, uint16 lsb) {
+ _freq = (msb << 7) + lsb;
+ keyOnSetFreq(_freq + _freqAdjust);
+}
+
+void TownsMidiOutputChannel::setupProgram(const uint8 *data, uint8 mLevelPara, uint8 tLevelPara) {
+ // This driver uses only 2 operators and 2 algorithms (algorithm 5 and 7),
+ // since it is just a modified AdLib driver. It also uses AdLib programs.
+ // There are no FM-TOWNS specific programs. This is the reason for the low quality of the FM-TOWNS
+ // music (unsuitable data is just forced into the wrong audio device).
+
+ static const uint8 mul[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 12, 12, 15, 15 };
+ uint8 chan = _chanMap[_chan];
+
+ uint8 mulAmsFms1 = _driver->_chanState[chan].mulAmsFms = data[0];
+ uint8 tl1 = _driver->_chanState[chan].tl = (data[1] | 0x3f) - mLevelPara;
+ uint8 attDec1 = _driver->_chanState[chan].attDec = ~data[2];
+ uint8 sus1 = _driver->_chanState[chan].sus = ~data[3];
+ _driver->_chanState[chan].unk2 = data[4];
+ chan += 3;
+
+ out(0x30, mul[mulAmsFms1 & 0x0f]);
+ out(0x40, (tl1 & 0x3f) + 15);
+ out(0x50, ((attDec1 >> 4) << 1) | ((attDec1 >> 4) & 1));
+ out(0x60, ((attDec1 << 1) | (attDec1 & 1)) & 0x1f);
+ out(0x70, (mulAmsFms1 & 0x20) ^ 0x20 ? (((sus1 & 0x0f) << 1) | 1) : 0);
+ out(0x80, sus1);
+
+ uint8 mulAmsFms2 = _driver->_chanState[chan].mulAmsFms = data[5];
+ uint8 tl2 = _driver->_chanState[chan].tl = (data[6] | 0x3f) - tLevelPara;
+ uint8 attDec2 = _driver->_chanState[chan].attDec = ~data[7];
+ uint8 sus2 = _driver->_chanState[chan].sus = ~data[8];
+ _driver->_chanState[chan].unk2 = data[9];
+
+ uint8 mul2 = mul[mulAmsFms2 & 0x0f];
+ tl2 = (tl2 & 0x3f) + 15;
+ uint8 ar2 = ((attDec2 >> 4) << 1) | ((attDec2 >> 4) & 1);
+ uint8 dec2 = ((attDec2 << 1) | (attDec2 & 1)) & 0x1f;
+ uint8 sus2r = (mulAmsFms2 & 0x20) ^ 0x20 ? (((sus2 & 0x0f) << 1) | 1) : 0;
+
+ for (int i = 4; i < 16; i += 4) {
+ out(0x30 + i, mul2);
+ out(0x40 + i, tl2);
+ out(0x50 + i, ar2);
+ out(0x60 + i, dec2);
+ out(0x70 + i, sus2r);
+ out(0x80 + i, sus2);
+ }
+
+ _driver->_chanState[chan].fgAlg = data[10];
+
+ uint8 alg = 5 + 2 * (data[10] & 1);
+ uint8 fb = 4 * (data[10] & 0x0e);
+ out(0xb0, fb | alg);
+ uint8 t = mulAmsFms1 | mulAmsFms2;
+ out(0xb4, (0xc0 | ((t & 0x80) >> 3) | ((t & 0x40) >> 5)));
+}
+
+void TownsMidiOutputChannel::setupEffects(int index, uint8 flags, const uint8 *effectData) {
+ uint16 effectMaxLevel[] = { 0x2FF, 0x1F, 0x07, 0x3F, 0x0F, 0x0F, 0x0F, 0x03, 0x3F, 0x0F, 0x0F, 0x0F, 0x03, 0x3E, 0x1F };
+ uint8 effectType[] = { 0x1D, 0x1C, 0x1B, 0x00, 0x03, 0x04, 0x07, 0x08, 0x0D, 0x10, 0x11, 0x14, 0x15, 0x1e, 0x1f, 0x00 };
+
+ EffectEnvelope *s = &_effectEnvelopes[index];
+ EffectDef *d = &_effectDefs[index];
+
+ d->phase = 0;
+ d->useModWheel = flags & 0x40;
+ s->loop = flags & 0x20;
+ d->loopRefresh = flags & 0x10;
+ d->type = effectType[flags & 0x0f];
+ s->maxLevel = effectMaxLevel[flags & 0x0f];
+ s->modWheelSensitivity = 31;
+ s->modWheelState = d->useModWheel ? _in->_modWheel >> 2 : 31;
+
+ switch (d->type) {
+ case 0:
+ s->startLevel = _operator2Tl;
+ break;
+ case 13:
+ s->startLevel = _operator1Tl;
+ break;
+ case 30:
+ s->startLevel = 31;
+ d->s->modWheelState = 0;
+ break;
+ case 31:
+ s->startLevel = 0;
+ d->s->modWheelSensitivity = 0;
+ break;
+ default:
+ s->startLevel = getEffectStartLevel(d->type);
+ break;
+ }
+
+ startEffect(s, effectData);
+}
+
+void TownsMidiOutputChannel::setModWheel(uint8 value) {
+ if (_effectEnvelopes[0].state != kEnvReady && _effectDefs[0].type)
+ _effectEnvelopes[0].modWheelState = value >> 2;
+
+ if (_effectEnvelopes[1].state != kEnvReady && _effectDefs[1].type)
+ _effectEnvelopes[1].modWheelState = value >> 2;
+}
+
+void TownsMidiOutputChannel::connect(TownsMidiInputChannel *chan) {
+ if (!chan)
+ return;
+
+ _in = chan;
+ _next = chan->_out;
+ _prev = 0;
+ chan->_out = this;
+ if (_next)
+ _next->_prev = this;
+}
+
+void TownsMidiOutputChannel::disconnect() {
+ keyOff();
+
+ TownsMidiOutputChannel *p = _prev;
+ TownsMidiOutputChannel *n = _next;
+
+ if (n)
+ n->_prev = p;
+ if (p)
+ p->_next = n;
+ else
+ _in->_out = n;
+ _in = 0;
+}
+
+bool TownsMidiOutputChannel::update() {
+ if (!_in)
+ return false;
+
+ if (_duration) {
+ _duration -= 17;
+ if (_duration <= 0) {
+ disconnect();
+ return true;
+ }
+ }
+
+ for (int i = 0; i < 2; i++) {
+ if (_effectEnvelopes[i].state != kEnvReady)
+ updateEffectGenerator(&_effectEnvelopes[i], &_effectDefs[i]);
+ }
+
+ return false;
+}
+
+int TownsMidiOutputChannel::checkPriority(int pri) {
+ if (!_in)
+ return kDisconnected;
+
+ if (!_next && pri >= _in->_priority)
+ return _in->_priority;
+
+ return kHighPriority;
+}
+
+void TownsMidiOutputChannel::startEffect(EffectEnvelope *s, const uint8 *effectData) {
+ s->state = kEnvAttacking;
+ s->currentLevel = 0;
+ s->modWheelLast = 31;
+ s->duration = effectData[0] * 63;
+ s->stateTargetLevels[0] = effectData[1];
+ s->stateTargetLevels[1] = effectData[3];
+ s->stateTargetLevels[2] = effectData[5];
+ s->stateTargetLevels[3] = effectData[6];
+ s->stateModWheelLevels[0] = effectData[2];
+ s->stateModWheelLevels[1] = effectData[4];
+ s->stateModWheelLevels[2] = 0;
+ s->stateModWheelLevels[3] = effectData[7];
+ initNextEnvelopeState(s);
+}
+
+void TownsMidiOutputChannel::updateEffectGenerator(EffectEnvelope *s, EffectDef *d) {
+ uint8 f = advanceEffectEnvelope(s, d);
+
+ if (f & 1) {
+ switch (d->type) {
+ case 0:
+ _operator2Tl = s->startLevel + d->phase;
+ break;
+ case 13:
+ _operator1Tl = s->startLevel + d->phase;
+ break;
+ case 30:
+ d->s->modWheelState = d->phase;
+ break;
+ case 31:
+ d->s->modWheelSensitivity = d->phase;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (f & 2) {
+ if (d->loopRefresh)
+ keyOn();
+ }
+}
+
+int TownsMidiOutputChannel::advanceEffectEnvelope(EffectEnvelope *s, EffectDef *d) {
+ if (s->duration) {
+ s->duration -= 17;
+ if (s->duration <= 0) {
+ s->state = kEnvReady;
+ return 0;
+ }
+ }
+
+ int32 t = s->currentLevel + s->incrPerStep;
+
+ s->incrCountRem += s->incrPerStepRem;
+ if (s->incrCountRem >= s->numSteps) {
+ s->incrCountRem -= s->numSteps;
+ t += s->dir;
+ }
+
+ int retFlags = 0;
+
+ if (t != s->currentLevel || (s->modWheelState != s->modWheelLast)) {
+ s->currentLevel = t;
+ s->modWheelLast = s->modWheelState;
+ t = getEffectModLevel(t, s->modWheelState);
+ if (t != d->phase)
+ d->phase = t;
+ retFlags |= 1;
+ }
+
+ if (--s->stepCounter)
+ return retFlags;
+
+ if (++s->state > kEnvReleasing) {
+ if (!s->loop) {
+ s->state = kEnvReady;
+ return retFlags;
+ }
+ s->state = kEnvAttacking;
+ retFlags |= 2;
+ }
+
+ initNextEnvelopeState(s);
+
+ return retFlags;
+}
+
+void TownsMidiOutputChannel::initNextEnvelopeState(EffectEnvelope *s) {
+ uint8 v = s->stateTargetLevels[s->state - 1];
+ int32 e = _effectEnvStepTable[_driver->_operatorLevelTable[((v & 0x7f) << 5) + s->modWheelSensitivity]];
+
+ if (v & 0x80)
+ e = _driver->randomValue(e);
+
+ if (!e)
+ e = 1;
+
+ s->numSteps = s->stepCounter = e;
+ int32 d = 0;
+
+ if (s->state != kEnvSustaining) {
+ v = s->stateModWheelLevels[s->state - 1];
+ e = getEffectModLevel(s->maxLevel, (v & 0x7f) - 31);
+
+ if (v & 0x80)
+ e = _driver->randomValue(e);
+
+ if (e + s->startLevel > s->maxLevel) {
+ e = s->maxLevel - s->startLevel;
+ } else {
+ if (e + s->startLevel < 0)
+ e = -s->startLevel;
+ }
+
+ d = e - s->currentLevel;
+ }
+
+ s->incrPerStep = d / s->numSteps;
+ s->dir = (d < 0) ? -1 : 1;
+ d *= s->dir;
+ s->incrPerStepRem = d % s->numSteps;
+ s->incrCountRem = 0;
+}
+
+int16 TownsMidiOutputChannel::getEffectStartLevel(uint8 type) {
+ uint8 chan = (type < 13) ? _chanMap2[_chan] : ((type < 26) ? _chanMap[_chan] : _chan);
+
+ if (type == 28)
+ return 15;
+ else if (type == 29)
+ return 383;
+ else if (type > 29)
+ return 0;
+ else if (type > 12)
+ type -= 13;
+
+ const uint8 *def = &_effectDefaults[type << 2];
+ uint8 res = (_driver->_chanState[chan].get(def[0] >> 5) & def[2]) >> def[1];
+ if (def[3])
+ res = def[3] - res;
+
+ return res;
+}
+
+int TownsMidiOutputChannel::getEffectModLevel(int lvl, int mod) {
+ if (mod == 0)
+ return 0;
+
+ if (mod == 31)
+ return lvl;
+
+ if (lvl > 63 || lvl < -63)
+ return ((lvl + 1) * mod) >> 5;
+
+ if (mod < 0) {
+ if (lvl < 0)
+ return _driver->_operatorLevelTable[((-lvl) << 5) - mod];
+ else
+ return -_driver->_operatorLevelTable[(lvl << 5) - mod];
+ } else {
+ if (lvl < 0)
+ return -_driver->_operatorLevelTable[((-lvl) << 5) + mod];
+ else
+ return _driver->_operatorLevelTable[((-lvl) << 5) + mod];
+ }
+
+ return 0;
+}
+
+void TownsMidiOutputChannel::keyOn() {
+ out(0x28, 0x30);
+}
+
+void TownsMidiOutputChannel::keyOff() {
+ out(0x28, 0);
+}
+
+void TownsMidiOutputChannel::keyOnSetFreq(uint16 frq) {
+ uint16 note = (frq << 1) >> 8;
+ frq = (_freqMSB[note] << 11) | _freqLSB[note] ;
+ out(0xa4, frq >> 8);
+ out(0xa0, frq & 0xff);
+ //out(0x28, 0x00);
+ out(0x28, 0x30);
+}
+
+void TownsMidiOutputChannel::out(uint8 reg, uint8 val) {
+ static const uint8 chanRegOffs[] = { 0, 1, 2, 0, 1, 2 };
+ static const uint8 keyValOffs[] = { 0, 1, 2, 4, 5, 6 };
+
+ if (reg == 0x28)
+ val = (val & 0xf0) | keyValOffs[_chan];
+ if (reg < 0x30)
+ _driver->_intf->callback(17, 0, reg, val);
+ else
+ _driver->_intf->callback(17, _chan / 3, (reg & ~3) | chanRegOffs[_chan], val);
+}
+
+const uint8 TownsMidiOutputChannel::_chanMap[] = {
+ 0, 1, 2, 8, 9, 10
+};
+
+const uint8 TownsMidiOutputChannel::_chanMap2[] = {
+ 3, 4, 5, 11, 12, 13
+};
+
+const uint8 TownsMidiOutputChannel::_effectDefaults[] = {
+ 0x40, 0x00, 0x3F, 0x3F, 0xE0, 0x02, 0x00, 0x00, 0x40, 0x06, 0xC0, 0x00,
+ 0x20, 0x00, 0x0F, 0x00, 0x60, 0x04, 0xF0, 0x0F, 0x60, 0x00, 0x0F, 0x0F,
+ 0x80, 0x04, 0xF0, 0x0F, 0x80, 0x00, 0x0F, 0x0F, 0xE0, 0x00, 0x03, 0x00,
+ 0x20, 0x07, 0x80, 0x00, 0x20, 0x06, 0x40, 0x00, 0x20, 0x05, 0x20, 0x00,
+ 0x20, 0x04, 0x10, 0x00, 0xC0, 0x00, 0x01, 0x00, 0xC0, 0x01, 0x0E, 0x00
+};
+
+const uint16 TownsMidiOutputChannel::_effectEnvStepTable[] = {
+ 0x0001, 0x0002, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009,
+ 0x000A, 0x000C, 0x000E, 0x0010, 0x0012, 0x0015, 0x0018, 0x001E,
+ 0x0024, 0x0032, 0x0040, 0x0052, 0x0064, 0x0088, 0x00A0, 0x00C0,
+ 0x00F0, 0x0114, 0x0154, 0x01CC, 0x0258, 0x035C, 0x04B0, 0x0640
+};
+
+const uint8 TownsMidiOutputChannel::_freqMSB[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+ 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
+ 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
+ 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+ 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x80, 0x81, 0x83, 0x85,
+ 0x87, 0x88, 0x8A, 0x8C, 0x8E, 0x8F, 0x91, 0x93, 0x95, 0x96, 0x98, 0x9A,
+ 0x9C, 0x9E, 0x9F, 0xA1, 0xA3, 0xA5, 0xA6, 0xA8, 0xAA, 0xAC, 0xAD, 0xAF,
+ 0xB1, 0xB3, 0xB4, 0xB6, 0xB8, 0xBA, 0xBC, 0xBD, 0xBF, 0xC1, 0xC3, 0xC4,
+ 0xC6, 0xC8, 0xCA, 0xCB, 0xCD, 0xCF, 0xD1, 0xD2, 0xD4, 0xD6, 0xD8, 0xDA,
+ 0xDB, 0xDD, 0xDF, 0xE1, 0xE2, 0xE4, 0xE6, 0xE8, 0xE9, 0xEB, 0xED, 0xEF
+};
+
+const uint16 TownsMidiOutputChannel::_freqLSB[] = {
+ 0x02D6, 0x02D6, 0x02D6, 0x02D6, 0x02D6, 0x02D6, 0x02D6, 0x02D6,
+ 0x02D6, 0x02D6, 0x02D6, 0x02D6, 0x02D6, 0x02D6, 0x0301, 0x032F,
+ 0x0360, 0x0393, 0x03C9, 0x0403, 0x0440, 0x0481, 0x04C6, 0x050E,
+ 0x055B, 0x02D6, 0x0301, 0x032F, 0x0360, 0x0393, 0x03C9, 0x0403,
+ 0x0440, 0x0481, 0x04C6, 0x050E, 0x055B, 0x02D6, 0x0301, 0x032F,
+ 0x0360, 0x0393, 0x03C9, 0x0403, 0x0440, 0x0481, 0x04C6, 0x050E,
+ 0x055B, 0x02D6, 0x0301, 0x032F, 0x0360, 0x0393, 0x03C9, 0x0403,
+ 0x0440, 0x0481, 0x04C6, 0x050E, 0x055B, 0x02D6, 0x0301, 0x032F,
+ 0x0360, 0x0393, 0x03C9, 0x0403, 0x0440, 0x0481, 0x04C6, 0x050E,
+ 0x055B, 0x02D6, 0x0301, 0x032F, 0x0360, 0x0393, 0x03C9, 0x0403,
+ 0x0440, 0x0481, 0x04C6, 0x050E, 0x055B, 0x02D6, 0x0301, 0x032F,
+ 0x0360, 0x0393, 0x03C9, 0x0403, 0x0440, 0x0481, 0x04C6, 0x050E,
+ 0x055B, 0x055B, 0x055B, 0x055B, 0x055B, 0x055B, 0x055B, 0x055B,
+ 0x055B, 0x055B, 0x055B, 0x055B, 0x055B, 0x055B, 0x055B, 0x055B,
+ 0x055B, 0x055B, 0x055B, 0x055B, 0x055B, 0x055B, 0x055B, 0x055B,
+ 0x055B, 0x055B, 0x055B, 0x055B, 0x055B, 0x055B, 0x055B, 0x055B
+};
+
+TownsMidiInputChannel::TownsMidiInputChannel(MidiDriver_TOWNS *driver, int chanIndex) : MidiChannel(), _driver(driver), _out(0), _prg(0), _chanIndex(chanIndex),
+ _effectLevel(0), _priority(0), _ctrlVolume(0), _tl(0), _pan(0), _panEff(0), _transpose(0), _percS(0), _pitchBendFactor(0), _pitchBend(0), _sustain(0), _freqLSB(0),
+ _fld_1f(0), _detune(0), _modWheel(0), _allocated(false) {
+ _instrument = new uint8[30];
+ memset(_instrument, 0, 30);
+}
+
+TownsMidiInputChannel::~TownsMidiInputChannel() {
+ delete[] _instrument;
+}
+
+bool TownsMidiInputChannel::allocate() {
+ if (_allocated)
+ return false;
+ _allocated = true;
+ return true;
+}
+
+void TownsMidiInputChannel::release() {
+ _allocated = false;
+}
+
+void TownsMidiInputChannel::send(uint32 b) {
+ _driver->send(b | _chanIndex);
+}
+
+void TownsMidiInputChannel::noteOff(byte note) {
+ if (!_out)
+ return;
+
+ for (TownsMidiOutputChannel *oc = _out; oc; oc = oc->_next) {
+ if (oc->_note != note)
+ continue;
+
+ if (_sustain)
+ oc->_sustainNoteOff = 1;
+ else
+ oc->disconnect();
+ }
+}
+
+void TownsMidiInputChannel::noteOn(byte note, byte velocity) {
+ TownsMidiOutputChannel *oc = _driver->allocateOutputChannel(_priority);
+
+ if (!oc)
+ return;
+
+ oc->connect(this);
+
+ oc->_adjustModTl = _instrument[10] & 1;
+ oc->_note = note;
+ oc->_sustainNoteOff = 0;
+ oc->_duration = _instrument[29] * 63;
+
+ oc->_operator1Tl = (_instrument[1] & 0x3f) + _driver->_operatorLevelTable[((velocity >> 1) << 5) + (_instrument[4] >> 2)];
+ if (oc->_operator1Tl > 63)
+ oc->_operator1Tl = 63;
+
+ oc->_operator2Tl = (_instrument[6] & 0x3f) + _driver->_operatorLevelTable[((velocity >> 1) << 5) + (_instrument[9] >> 2)];
+ if (oc->_operator2Tl > 63)
+ oc->_operator2Tl = 63;
+
+ oc->setupProgram(_instrument, oc->_adjustModTl == 1 ? _programAdjustLevel[_driver->_operatorLevelTable[(_tl >> 2) + (oc->_operator1Tl << 5)]] : oc->_operator1Tl, _programAdjustLevel[_driver->_operatorLevelTable[(_tl >> 2) + (oc->_operator2Tl << 5)]]);
+ oc->noteOn(note + _transpose, _freqLSB);
+
+ if (_instrument[11] & 0x80)
+ oc->setupEffects(0, _instrument[11], &_instrument[12]);
+ else
+ oc->_effectEnvelopes[0].state = kEnvReady;
+
+ if (_instrument[20] & 0x80)
+ oc->setupEffects(1, _instrument[20], &_instrument[21]);
+ else
+ oc->_effectEnvelopes[1].state = kEnvReady;
+}
+
+void TownsMidiInputChannel::programChange(byte program) {
+ // Not implemented (The loading and assignment of programs
+ // is handled externally by the SCUMM engine. The programs
+ // get sent via sysEx_customInstrument.)
+}
+
+void TownsMidiInputChannel::pitchBend(int16 bend) {
+ _pitchBend = bend;
+ _freqLSB = ((_pitchBend * _pitchBendFactor) >> 6) + _detune;
+ for (TownsMidiOutputChannel *oc = _out; oc; oc = oc->_next)
+ oc->noteOnPitchBend(oc->_note + oc->_in->_transpose, _freqLSB);
+}
+
+void TownsMidiInputChannel::controlChange(byte control, byte value) {
+ switch (control) {
+ case 1:
+ controlModulationWheel(value);
+ break;
+ case 7:
+ controlVolume(value);
+ break;
+ case 10:
+ controlPanPos(value);
+ break;
+ case 64:
+ controlSustain(value);
+ break;
+ case 123:
+ while (_out)
+ _out->disconnect();
+ break;
+ default:
+ break;
+ }
+}
+
+void TownsMidiInputChannel::pitchBendFactor(byte value) {
+ _pitchBendFactor = value;
+ _freqLSB = ((_pitchBend * _pitchBendFactor) >> 6) + _detune;
+ for (TownsMidiOutputChannel *oc = _out; oc; oc = oc->_next)
+ oc->noteOnPitchBend(oc->_note + oc->_in->_transpose, _freqLSB);
+}
+
+void TownsMidiInputChannel::priority(byte value) {
+ _priority = value;
+}
+
+void TownsMidiInputChannel::sysEx_customInstrument(uint32 type, const byte *instr) {
+ memcpy(_instrument, instr, 30);
+}
+
+void TownsMidiInputChannel::controlModulationWheel(byte value) {
+ _modWheel = value;
+ for (TownsMidiOutputChannel *oc = _out; oc; oc = oc->_next)
+ oc->setModWheel(value);
+}
+
+void TownsMidiInputChannel::controlVolume(byte value) {
+ /* This is all done inside the imuse code
+ uint16 v1 = _ctrlVolume + 1;
+ uint16 v2 = value;
+ if (_chanIndex != 16) {
+ _ctrlVolume = value;
+ v2 = _player->getEffectiveVolume();
+ }
+ _tl = (v1 * v2) >> 7;*/
+
+ _tl = value;
+}
+
+void TownsMidiInputChannel::controlPanPos(byte value) {
+ // not implemented
+}
+
+void TownsMidiInputChannel::controlSustain(byte value) {
+ _sustain = value;
+ if (!value)
+ releasePedal();
+}
+
+void TownsMidiInputChannel::releasePedal() {
+ for (TownsMidiOutputChannel *oc = _out; oc; oc = oc->_next) {
+ if (oc->_sustainNoteOff)
+ oc->disconnect();
+ }
+}
+
+const uint8 TownsMidiInputChannel::_programAdjustLevel[] = {
+ 0x00, 0x04, 0x07, 0x0B, 0x0D, 0x10, 0x12, 0x14,
+ 0x16, 0x18, 0x1A, 0x1B, 0x1D, 0x1E, 0x1F, 0x21,
+ 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29,
+ 0x2A, 0x2B, 0x2C, 0x2C, 0x2D, 0x2E, 0x2F, 0x2F,
+ 0x30, 0x31, 0x31, 0x32, 0x33, 0x33, 0x34, 0x35,
+ 0x35, 0x36, 0x36, 0x37, 0x37, 0x38, 0x38, 0x39,
+ 0x39, 0x3A, 0x3A, 0x3B, 0x3B, 0x3C, 0x3C, 0x3C,
+ 0x3D, 0x3D, 0x3E, 0x3E, 0x3E, 0x3F, 0x3F, 0x3F
+};
+
+MidiDriver_TOWNS::MidiDriver_TOWNS(Audio::Mixer *mixer) : _timerProc(0), _timerProcPara(0), _channels(0), _out(0),
+ _chanState(0), _operatorLevelTable(0), _tickCounter1(0), _tickCounter2(0), _rand(1), _allocCurPos(0), _isOpen(false) {
+ // We set exteral mutex handling to true, since this driver is only suitable for use with the SCUMM engine
+ // which has its own mutex. This causes lockups which cannot always be avoided.
+ _intf = new TownsAudioInterface(mixer, this, true);
+
+ _channels = new TownsMidiInputChannel*[32];
+ for (int i = 0; i < 32; i++)
+ _channels[i] = new TownsMidiInputChannel(this, i > 8 ? (i + 1) : i);
+
+ _out = new TownsMidiOutputChannel*[6];
+ for (int i = 0; i < 6; i++)
+ _out[i] = new TownsMidiOutputChannel(this, i);
+
+ _chanState = new TownsMidiChanState[32];
+
+ _operatorLevelTable = new uint8[2048];
+ for (int i = 0; i < 64; i++) {
+ for (int ii = 0; ii < 32; ii++)
+ _operatorLevelTable[(i << 5) + ii] = ((i * (ii + 1)) >> 5) & 0xff;
+ }
+ for (int i = 0; i < 64; i++)
+ _operatorLevelTable[i << 5] = 0;
+}
+
+MidiDriver_TOWNS::~MidiDriver_TOWNS() {
+ close();
+ delete _intf;
+
+ if (_channels) {
+ for (int i = 0; i < 32; i++)
+ delete _channels[i];
+ delete[] _channels;
+ }
+ _channels = 0;
+
+ if (_out) {
+ for (int i = 0; i < 6; i++)
+ delete _out[i];
+ delete[] _out;
+ }
+ _out = 0;
+
+ delete[] _chanState;
+ _chanState = 0;
+ delete[] _operatorLevelTable;
+ _operatorLevelTable = 0;
+}
+
+int MidiDriver_TOWNS::open() {
+ if (_isOpen)
+ return MERR_ALREADY_OPEN;
+
+ if (!_intf->init())
+ return MERR_CANNOT_CONNECT;
+
+ _intf->callback(0);
+
+ _intf->callback(21, 255, 1);
+ _intf->callback(21, 0, 1);
+ _intf->callback(22, 255, 221);
+
+ _intf->callback(33, 8);
+ _intf->setSoundEffectChanMask(~0x3f);
+
+ _allocCurPos = 0;
+
+ _isOpen = true;
+
+ return 0;
+}
+
+void MidiDriver_TOWNS::close() {
+ if (!_isOpen)
+ return;
+
+ _isOpen = false;
+
+ setTimerCallback(0, 0);
+ g_system->delayMillis(20);
+}
+
+void MidiDriver_TOWNS::send(uint32 b) {
+ if (!_isOpen)
+ return;
+
+ byte param2 = (b >> 16) & 0xFF;
+ byte param1 = (b >> 8) & 0xFF;
+ byte cmd = b & 0xF0;
+
+ TownsMidiInputChannel *c = _channels[b & 0x0F];
+
+ switch (cmd) {
+ case 0x80:
+ c->noteOff(param1);
+ break;
+ case 0x90:
+ if (param2)
+ c->noteOn(param1, param2);
+ else
+ c->noteOff(param1);
+ break;
+ case 0xB0:
+ c->controlChange(param1, param2);
+ break;
+ case 0xC0:
+ c->programChange(param1);
+ break;
+ case 0xE0:
+ c->pitchBend((param1 | (param2 << 7)) - 0x2000);
+ break;
+ case 0xF0:
+ warning("MidiDriver_TOWNS: Receiving SysEx command on a send() call");
+ break;
+
+ default:
+ break;
+ }
+}
+
+void MidiDriver_TOWNS::setTimerCallback(void *timer_param, Common::TimerManager::TimerProc timer_proc) {
+ _timerProc = timer_proc;
+ _timerProcPara = timer_param;
+}
+
+uint32 MidiDriver_TOWNS::getBaseTempo() {
+ return 10080;
+}
+
+MidiChannel *MidiDriver_TOWNS::allocateChannel() {
+ if (!_isOpen)
+ return 0;
+
+ for (int i = 0; i < 32; ++i) {
+ TownsMidiInputChannel *chan = _channels[i];
+ if (chan->allocate())
+ return chan;
+ }
+
+ return 0;
+}
+
+MidiChannel *MidiDriver_TOWNS::getPercussionChannel() {
+ return 0;
+}
+
+void MidiDriver_TOWNS::timerCallback(int timerId) {
+ if (!_isOpen)
+ return;
+
+ switch (timerId) {
+ case 1:
+ updateParser();
+ updateOutputChannels();
+
+ /*_tickCounter1 += 10000;
+ while (_tickCounter1 >= 4167) {
+ _tickCounter1 -= 4167;
+ unkUpdate();
+ }*/
+ break;
+ default:
+ break;
+ }
+}
+
+void MidiDriver_TOWNS::updateParser() {
+ if (_timerProc)
+ _timerProc(_timerProcPara);
+}
+
+void MidiDriver_TOWNS::updateOutputChannels() {
+ _tickCounter2 += 10000;
+ while (_tickCounter2 >= 16667) {
+ _tickCounter2 -= 16667;
+ for (int i = 0; i < 6; i++) {
+ if (_out[i]->update())
+ return;
+ }
+ }
+}
+
+TownsMidiOutputChannel *MidiDriver_TOWNS::allocateOutputChannel(uint8 pri) {
+ TownsMidiOutputChannel *res = 0;
+
+ for (int i = 0; i < 6; i++) {
+ if (++_allocCurPos == 6)
+ _allocCurPos = 0;
+
+ int s = _out[_allocCurPos]->checkPriority(pri);
+ if (s == TownsMidiOutputChannel::kDisconnected)
+ return _out[_allocCurPos];
+
+ if (s != TownsMidiOutputChannel::kHighPriority) {
+ pri = s;
+ res = _out[_allocCurPos];
+ }
+ }
+
+ if (res)
+ res->disconnect();
+
+ return res;
+}
+
+int MidiDriver_TOWNS::randomValue(int para) {
+ _rand = (_rand & 1) ? (_rand >> 1) ^ 0xb8 : (_rand >> 1);
+ return (_rand * para) >> 8;
+}
diff --git a/audio/softsynth/fmtowns_pc98/towns_midi.h b/audio/softsynth/fmtowns_pc98/towns_midi.h
new file mode 100644
index 0000000000..a98bb1b59c
--- /dev/null
+++ b/audio/softsynth/fmtowns_pc98/towns_midi.h
@@ -0,0 +1,83 @@
+/* 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.
+ *
+ */
+
+#ifndef TOWNS_MIDI_H
+#define TOWNS_MIDI_H
+
+#include "audio/softsynth/fmtowns_pc98/towns_audio.h"
+#include "audio/mididrv.h"
+
+
+class TownsMidiOutputChannel;
+class TownsMidiInputChannel;
+class TownsMidiChanState;
+
+class MidiDriver_TOWNS : public MidiDriver, public TownsAudioInterfacePluginDriver {
+friend class TownsMidiInputChannel;
+friend class TownsMidiOutputChannel;
+public:
+ MidiDriver_TOWNS(Audio::Mixer *mixer);
+ ~MidiDriver_TOWNS();
+
+ int open();
+ bool isOpen() const { return _isOpen; }
+ void close();
+
+ void send(uint32 b);
+
+ void setTimerCallback(void *timer_param, Common::TimerManager::TimerProc timer_proc);
+
+ uint32 getBaseTempo();
+ MidiChannel *allocateChannel();
+ MidiChannel *getPercussionChannel();
+
+ void timerCallback(int timerId);
+
+private:
+ void updateParser();
+ void updateOutputChannels();
+
+ TownsMidiOutputChannel *allocateOutputChannel(uint8 pri);
+
+ int randomValue(int para);
+
+ TownsMidiInputChannel **_channels;
+ TownsMidiOutputChannel **_out;
+ TownsMidiChanState *_chanState;
+
+ Common::TimerManager::TimerProc _timerProc;
+ void *_timerProcPara;
+
+ TownsAudioInterface *_intf;
+
+ uint32 _tickCounter1;
+ uint32 _tickCounter2;
+ uint8 _allocCurPos;
+ uint8 _rand;
+
+ bool _isOpen;
+
+ uint8 *_operatorLevelTable;
+};
+
+#endif
+
diff --git a/audio/softsynth/fmtowns_pc98/towns_pc98_driver.cpp b/audio/softsynth/fmtowns_pc98/towns_pc98_driver.cpp
index a551276ab1..49fe97caf1 100644
--- a/audio/softsynth/fmtowns_pc98/towns_pc98_driver.cpp
+++ b/audio/softsynth/fmtowns_pc98/towns_pc98_driver.cpp
@@ -18,9 +18,6 @@
* 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$
- *
*/
#include "audio/softsynth/fmtowns_pc98/towns_pc98_driver.h"
@@ -1057,6 +1054,8 @@ TownsPC98_AudioDriver::~TownsPC98_AudioDriver() {
_ready = false;
deinit();
+ Common::StackLock lock(_mutex);
+
if (_channels) {
for (int i = 0; i < _numChan; i++)
delete _channels[i];
@@ -1239,7 +1238,6 @@ void TownsPC98_AudioDriver::fadeStep() {
if (!_musicPlaying)
return;
- Common::StackLock lock(_mutex);
for (int j = 0; j < _numChan; j++) {
if (_updateChannelsFlag & _channels[j]->_idFlag)
_channels[j]->fadeStep();
@@ -1264,37 +1262,30 @@ void TownsPC98_AudioDriver::fadeStep() {
}
}
-void TownsPC98_AudioDriver::timerCallbackB() {
- _sfxOffs = 0;
-
- if (_musicPlaying) {
- _musicTickCounter++;
-
- for (int i = 0; i < _numChan; i++) {
- if (_updateChannelsFlag & _channels[i]->_idFlag) {
- _channels[i]->processEvents();
- _channels[i]->processFrequency();
- }
- }
+void TownsPC98_AudioDriver::pause() {
+ _musicPlaying = false;
+}
+
+void TownsPC98_AudioDriver::cont() {
+ _musicPlaying = true;
+}
- for (int i = 0; i < _numSSG; i++) {
- if (_updateSSGFlag & _ssgChannels[i]->_idFlag) {
- _ssgChannels[i]->processEvents();
- _ssgChannels[i]->processFrequency();
- }
- }
+bool TownsPC98_AudioDriver::looping() {
+ return _looping == _updateChannelsFlag ? true : false;
+}
-#ifndef DISABLE_PC98_RHYTHM_CHANNEL
- if (_hasPercussion)
- if (_updateRhythmFlag & _rhythmChannel->_idFlag)
- _rhythmChannel->processEvents();
-#endif
- }
+bool TownsPC98_AudioDriver::musicPlaying() {
+ return _musicPlaying;
+}
- toggleRegProtection(false);
+void TownsPC98_AudioDriver::setMusicVolume(int volume) {
+ _musicVolume = volume;
+ setVolumeIntern(_musicVolume, _sfxVolume);
+}
- if (_finishedChannelsFlag == _updateChannelsFlag && _finishedSSGFlag == _updateSSGFlag && _finishedRhythmFlag == _updateRhythmFlag)
- _musicPlaying = false;
+void TownsPC98_AudioDriver::setSoundEffectVolume(int volume) {
+ _sfxVolume = volume;
+ setVolumeIntern(_musicVolume, _sfxVolume);
}
void TownsPC98_AudioDriver::timerCallbackA() {
@@ -1322,15 +1313,37 @@ void TownsPC98_AudioDriver::timerCallbackA() {
}
}
-void TownsPC98_AudioDriver::setMusicTempo(uint8 tempo) {
- writeReg(0, 0x26, tempo);
- writeReg(0, 0x27, 0x33);
-}
+void TownsPC98_AudioDriver::timerCallbackB() {
+ _sfxOffs = 0;
-void TownsPC98_AudioDriver::setSfxTempo(uint16 tempo) {
- writeReg(0, 0x24, tempo & 0xff);
- writeReg(0, 0x25, tempo >> 8);
- writeReg(0, 0x27, 0x33);
+ if (_musicPlaying) {
+ _musicTickCounter++;
+
+ for (int i = 0; i < _numChan; i++) {
+ if (_updateChannelsFlag & _channels[i]->_idFlag) {
+ _channels[i]->processEvents();
+ _channels[i]->processFrequency();
+ }
+ }
+
+ for (int i = 0; i < _numSSG; i++) {
+ if (_updateSSGFlag & _ssgChannels[i]->_idFlag) {
+ _ssgChannels[i]->processEvents();
+ _ssgChannels[i]->processFrequency();
+ }
+ }
+
+#ifndef DISABLE_PC98_RHYTHM_CHANNEL
+ if (_hasPercussion)
+ if (_updateRhythmFlag & _rhythmChannel->_idFlag)
+ _rhythmChannel->processEvents();
+#endif
+ }
+
+ toggleRegProtection(false);
+
+ if (_finishedChannelsFlag == _updateChannelsFlag && _finishedSSGFlag == _updateSSGFlag && _finishedRhythmFlag == _updateRhythmFlag)
+ _musicPlaying = false;
}
void TownsPC98_AudioDriver::startSoundEffect() {
@@ -1353,6 +1366,16 @@ void TownsPC98_AudioDriver::startSoundEffect() {
_sfxData = 0;
}
+void TownsPC98_AudioDriver::setMusicTempo(uint8 tempo) {
+ writeReg(0, 0x26, tempo);
+ writeReg(0, 0x27, 0x33);
+}
+
+void TownsPC98_AudioDriver::setSfxTempo(uint16 tempo) {
+ writeReg(0, 0x24, tempo & 0xff);
+ writeReg(0, 0x25, tempo >> 8);
+ writeReg(0, 0x27, 0x33);
+}
const uint8 TownsPC98_AudioDriver::_drvTables[] = {
// channel presets
0x00, 0x80, 0x00, 0x00, 0x00, 0x01,
diff --git a/audio/softsynth/fmtowns_pc98/towns_pc98_driver.h b/audio/softsynth/fmtowns_pc98/towns_pc98_driver.h
index 1227e2626a..ff58482227 100644
--- a/audio/softsynth/fmtowns_pc98/towns_pc98_driver.h
+++ b/audio/softsynth/fmtowns_pc98/towns_pc98_driver.h
@@ -18,9 +18,6 @@
* 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$
- *
*/
#ifndef TOWNS_PC98_AUDIODRIVER_H
@@ -53,33 +50,19 @@ public:
void fadeStep();
- void pause() {
- _musicPlaying = false;
- }
- void cont() {
- _musicPlaying = true;
- }
+ void pause();
+ void cont();
- void timerCallbackB();
+ bool looping();
+ bool musicPlaying();
+
+ void setMusicVolume(int volume);
+ void setSoundEffectVolume(int volume);
+
+private:
void timerCallbackA();
+ void timerCallbackB();
- bool looping() {
- return _looping == _updateChannelsFlag ? true : false;
- }
- bool musicPlaying() {
- return _musicPlaying;
- }
-
- void setMusicVolume(int volume) {
- _musicVolume = volume;
- setVolumeIntern(_musicVolume, _sfxVolume);
- }
- void setSoundEffectVolume(int volume) {
- _sfxVolume = volume;
- setVolumeIntern(_musicVolume, _sfxVolume);
- }
-
-protected:
void startSoundEffect();
void setMusicTempo(uint8 tempo);
diff --git a/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp b/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp
index 9d3751a0cc..63007ba93c 100644
--- a/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp
+++ b/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp
@@ -18,9 +18,6 @@
* 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$
- *
*/
#include "audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h"
@@ -42,45 +39,22 @@ public:
void recalculateRates();
void generateOutput(int32 phasebuf, int32 *feedbuf, int32 &out);
- void feedbackLevel(int32 level) {
- _feedbackLevel = level ? level + 6 : 0;
- }
- void detune(int value) {
- _detn = &_detnTbl[value << 5];
- }
- void multiple(uint32 value) {
- _multiple = value ? (value << 1) : 1;
- }
- void attackRate(uint32 value) {
- _specifiedAttackRate = value;
- }
+ void feedbackLevel(int32 level);
+ void detune(int value);
+ void multiple(uint32 value);
+ void attackRate(uint32 value);
bool scaleRate(uint8 value);
- void decayRate(uint32 value) {
- _specifiedDecayRate = value;
- recalculateRates();
- }
- void sustainRate(uint32 value) {
- _specifiedSustainRate = value;
- recalculateRates();
- }
- void sustainLevel(uint32 value) {
- _sustainLevel = (value == 0x0f) ? 0x3e0 : value << 5;
- }
- void releaseRate(uint32 value) {
- _specifiedReleaseRate = value;
- recalculateRates();
- }
- void totalLevel(uint32 value) {
- _totalLevel = value << 3;
- }
- void ampModulation(bool enable) {
- _ampMod = enable;
- }
+ void decayRate(uint32 value);
+ void sustainRate(uint32 value);
+ void sustainLevel(uint32 value);
+ void releaseRate(uint32 value);
+ void totalLevel(uint32 value);
+ void ampModulation(bool enable);
void reset();
protected:
EnvelopeState _state;
- bool _playing;
+ bool _holdKey;
uint32 _feedbackLevel;
uint32 _multiple;
uint32 _totalLevel;
@@ -125,7 +99,7 @@ TownsPC98_FmSynthOperator::TownsPC98_FmSynthOperator(const uint32 timerbase, con
_rtt(rtt), _rateTbl(rateTable), _rshiftTbl(shiftTable), _adTbl(attackDecayTable), _fTbl(frqTable),
_sinTbl(sineTable), _tLvlTbl(tlevelOut), _detnTbl(detuneTable), _tickLength(timerbase * 2),
_specifiedAttackRate(0), _specifiedDecayRate(0), _specifiedReleaseRate(0), _specifiedSustainRate(0),
- _phase(0), _state(kEnvReady), _playing(false), _timer(0), _keyScale1(0),
+ _sustainLevel(0), _phase(0), _state(kEnvReady), _holdKey(false), _timer(0), _keyScale1(0),
_keyScale2(0), _currentLevel(1023), _ampMod(false), _tickCount(0) {
fs_a.rate = fs_a.shift = fs_d.rate = fs_d.shift = fs_s.rate = fs_s.shift = fs_r.rate = fs_r.shift = 0;
@@ -134,19 +108,19 @@ TownsPC98_FmSynthOperator::TownsPC98_FmSynthOperator(const uint32 timerbase, con
}
void TownsPC98_FmSynthOperator::keyOn() {
- if (_playing)
+ if (_holdKey)
return;
- _playing = true;
+ _holdKey = true;
_state = kEnvAttacking;
_phase = 0;
}
void TownsPC98_FmSynthOperator::keyOff() {
- if (!_playing)
+ if (!_holdKey)
return;
- _playing = false;
+ _holdKey = false;
if (_state != kEnvReady)
_state = kEnvReleasing;
}
@@ -202,39 +176,42 @@ void TownsPC98_FmSynthOperator::generateOutput(int32 phasebuf, int32 *feed, int3
int32 targetLevel = 0;
EnvelopeState nextState = kEnvReady;
- switch (_state) {
- case kEnvReady:
- return;
- case kEnvAttacking:
- targetLevel = 0;
- nextState = kEnvDecaying;
- if ((_specifiedAttackRate << 1) + _keyScale2 < 64) {
- targetTime = (1 << fs_a.shift) - 1;
- levelIncrement = (~_currentLevel * _adTbl[fs_a.rate + ((_tickCount >> fs_a.shift) & 7)]) >> 4;
+ for (bool loop = true; loop;) {
+ switch (_state) {
+ case kEnvReady:
+ return;
+ case kEnvAttacking:
+ targetLevel = 0;
+ nextState = _sustainLevel ? kEnvDecaying : kEnvSustaining;
+ if ((_specifiedAttackRate << 1) + _keyScale2 < 62) {
+ targetTime = (1 << fs_a.shift) - 1;
+ levelIncrement = (~_currentLevel * _adTbl[fs_a.rate + ((_tickCount >> fs_a.shift) & 7)]) >> 4;
+ } else {
+ _currentLevel = targetLevel;
+ _state = nextState;
+ continue;
+ }
+ break;
+ case kEnvDecaying:
+ targetTime = (1 << fs_d.shift) - 1;
+ nextState = kEnvSustaining;
+ targetLevel = _sustainLevel;
+ levelIncrement = _adTbl[fs_d.rate + ((_tickCount >> fs_d.shift) & 7)];
+ break;
+ case kEnvSustaining:
+ targetTime = (1 << fs_s.shift) - 1;
+ nextState = kEnvSustaining;
+ targetLevel = 1023;
+ levelIncrement = _adTbl[fs_s.rate + ((_tickCount >> fs_s.shift) & 7)];
+ break;
+ case kEnvReleasing:
+ targetTime = (1 << fs_r.shift) - 1;
+ nextState = kEnvReady;
+ targetLevel = 1023;
+ levelIncrement = _adTbl[fs_r.rate + ((_tickCount >> fs_r.shift) & 7)];
break;
- } else {
- _currentLevel = targetLevel;
- _state = nextState;
}
- // Fall through
- case kEnvDecaying:
- targetTime = (1 << fs_d.shift) - 1;
- nextState = kEnvSustaining;
- targetLevel = _sustainLevel;
- levelIncrement = _adTbl[fs_d.rate + ((_tickCount >> fs_d.shift) & 7)];
- break;
- case kEnvSustaining:
- targetTime = (1 << fs_s.shift) - 1;
- nextState = kEnvSustaining;
- targetLevel = 1023;
- levelIncrement = _adTbl[fs_s.rate + ((_tickCount >> fs_s.shift) & 7)];
- break;
- case kEnvReleasing:
- targetTime = (1 << fs_r.shift) - 1;
- nextState = kEnvReady;
- targetLevel = 1023;
- levelIncrement = _adTbl[fs_r.rate + ((_tickCount >> fs_r.shift) & 7)];
- break;
+ loop = false;
}
if (!(_tickCount & targetTime)) {
@@ -275,6 +252,63 @@ void TownsPC98_FmSynthOperator::generateOutput(int32 phasebuf, int32 *feed, int3
out += *o;
}
+void TownsPC98_FmSynthOperator::feedbackLevel(int32 level) {
+ _feedbackLevel = level ? level + 6 : 0;
+}
+
+void TownsPC98_FmSynthOperator::detune(int value) {
+ _detn = &_detnTbl[value << 5];
+}
+
+void TownsPC98_FmSynthOperator::multiple(uint32 value) {
+ _multiple = value ? (value << 1) : 1;
+}
+
+void TownsPC98_FmSynthOperator::attackRate(uint32 value) {
+ _specifiedAttackRate = value;
+}
+
+bool TownsPC98_FmSynthOperator::scaleRate(uint8 value) {
+ value = 3 - value;
+ if (_keyScale1 != value) {
+ _keyScale1 = value;
+ return true;
+ }
+
+ int k = _keyScale2;
+ int r = _specifiedAttackRate ? (_specifiedAttackRate << 1) + 0x20 : 0;
+ fs_a.rate = ((r + k) < 94) ? _rateTbl[r + k] : 136;
+ fs_a.shift = ((r + k) < 94) ? _rshiftTbl[r + k] : 0;
+ return false;
+}
+
+void TownsPC98_FmSynthOperator::decayRate(uint32 value) {
+ _specifiedDecayRate = value;
+ recalculateRates();
+}
+
+void TownsPC98_FmSynthOperator::sustainRate(uint32 value) {
+ _specifiedSustainRate = value;
+ recalculateRates();
+ }
+
+void TownsPC98_FmSynthOperator::sustainLevel(uint32 value) {
+ _sustainLevel = (value == 0x0f) ? 0x3e0 : value << 5;
+}
+
+void TownsPC98_FmSynthOperator::releaseRate(uint32 value) {
+ _specifiedReleaseRate = value;
+ recalculateRates();
+}
+
+void TownsPC98_FmSynthOperator::totalLevel(uint32 value) {
+ _totalLevel = value << 3;
+}
+
+void TownsPC98_FmSynthOperator::ampModulation(bool enable) {
+ _ampMod = enable;
+}
+
void TownsPC98_FmSynthOperator::reset() {
keyOff();
_timer = 0;
@@ -295,20 +329,6 @@ void TownsPC98_FmSynthOperator::reset() {
ampModulation(false);
}
-bool TownsPC98_FmSynthOperator::scaleRate(uint8 value) {
- value = 3 - value;
- if (_keyScale1 != value) {
- _keyScale1 = value;
- return true;
- }
-
- int k = _keyScale2;
- int r = _specifiedAttackRate ? (_specifiedAttackRate << 1) + 0x20 : 0;
- fs_a.rate = ((r + k) < 94) ? _rateTbl[r + k] : 136;
- fs_a.shift = ((r + k) < 94) ? _rshiftTbl[r + k] : 0;
- return false;
-}
-
class TownsPC98_FmSynthSquareSineSource {
public:
TownsPC98_FmSynthSquareSineSource(const uint32 timerbase, const uint32 rtt);
@@ -633,7 +653,8 @@ void TownsPC98_FmSynthSquareSineSource::updateRegs() {
#ifndef DISABLE_PC98_RHYTHM_CHANNEL
TownsPC98_FmSynthPercussionSource::TownsPC98_FmSynthPercussionSource(const uint32 timerbase, const uint32 rtt) :
- _rtt(rtt), _tickLength(timerbase * 2), _timer(0), _ready(false), _volMaskA(0), _volMaskB(0), _volumeA(Audio::Mixer::kMaxMixerVolume), _volumeB(Audio::Mixer::kMaxMixerVolume) {
+ _rtt(rtt), _tickLength(timerbase * 2), _timer(0), _totalLevel(0), _volMaskA(0), _volMaskB(0),
+ _volumeA(Audio::Mixer::kMaxMixerVolume), _volumeB(Audio::Mixer::kMaxMixerVolume), _ready(false) {
memset(_rhChan, 0, sizeof(RhtChannel) * 6);
_reg = new uint8 *[40];
@@ -830,7 +851,7 @@ void TownsPC98_FmSynthPercussionSource::advanceInput(RhtChannel *ins) {
}
#endif // DISABLE_PC98_RHYTHM_CHANNEL
-TownsPC98_FmSynth::TownsPC98_FmSynth(Audio::Mixer *mixer, EmuType type) :
+TownsPC98_FmSynth::TownsPC98_FmSynth(Audio::Mixer *mixer, EmuType type, bool externalMutexHandling) :
_mixer(mixer),
_chanInternal(0), _ssg(0),
#ifndef DISABLE_PC98_RHYTHM_CHANNEL
@@ -841,7 +862,7 @@ TownsPC98_FmSynth::TownsPC98_FmSynth(Audio::Mixer *mixer, EmuType type) :
_oprRates(0), _oprRateshift(0), _oprAttackDecay(0), _oprFrq(0), _oprSinTbl(0), _oprLevelOut(0), _oprDetune(0),
_rtt(type == kTypeTowns ? 0x514767 : 0x5B8D80), _baserate(55125.0f / (float)mixer->getOutputRate()),
_volMaskA(0), _volMaskB(0), _volumeA(255), _volumeB(255),
- _regProtectionFlag(false), _ready(false) {
+ _regProtectionFlag(false), _externalMutex(externalMutexHandling), _ready(false) {
memset(&_timers[0], 0, sizeof(ChipTimer));
memset(&_timers[1], 0, sizeof(ChipTimer));
@@ -854,6 +875,8 @@ TownsPC98_FmSynth::~TownsPC98_FmSynth() {
if (_ready)
deinit();
+ Common::StackLock lock(_mutex);
+
delete _ssg;
#ifndef DISABLE_PC98_RHYTHM_CHANNEL
delete _prc;
@@ -934,10 +957,10 @@ void TownsPC98_FmSynth::writeReg(uint8 part, uint8 regAddress, uint8 value) {
if (_regProtectionFlag || !_ready)
return;
- static const uint8 oprOrdr[] = { 0, 2, 1, 3 };
-
Common::StackLock lock(_mutex);
+ static const uint8 oprOrdr[] = { 0, 2, 1, 3 };
+
uint8 h = regAddress & 0xf0;
uint8 l = (regAddress & 0x0f);
@@ -1084,6 +1107,7 @@ void TownsPC98_FmSynth::writeReg(uint8 part, uint8 regAddress, uint8 value) {
if (l == 0) {
c->frqTemp = (c->frqTemp & 0xff00) | value;
c->updateEnvelopeParameters = true;
+ c->fmIndex = (c->frqTemp >> 4 & 0x7f);
for (int i = 0; i < 4; i++)
co[i]->frequency(c->frqTemp);
} else if (l == 4) {
@@ -1118,21 +1142,37 @@ void TownsPC98_FmSynth::writeReg(uint8 part, uint8 regAddress, uint8 value) {
}
int TownsPC98_FmSynth::readBuffer(int16 *buffer, const int numSamples) {
- Common::StackLock lock(_mutex);
-
memset(buffer, 0, sizeof(int16) * numSamples);
int32 *tmp = new int32[numSamples];
int32 *tmpStart = tmp;
memset(tmp, 0, sizeof(int32) * numSamples);
int32 samplesLeft = numSamples >> 1;
+ bool locked = false;
+ if (_ready) {
+ _mutex.lock();
+ locked = true;
+ }
+
while (_ready && samplesLeft) {
int32 render = samplesLeft;
for (int i = 0; i < 2; i++) {
if (_timers[i].enabled && _timers[i].cb) {
if (!_timers[i].smpTillCb) {
+
+ if (locked && _externalMutex) {
+ _mutex.unlock();
+ locked = false;
+ }
+
(this->*_timers[i].cb)();
+
+ if (!locked && _externalMutex) {
+ _mutex.lock();
+ locked = true;
+ }
+
_timers[i].smpTillCb = _timers[i].smpPerCb;
_timers[i].smpTillCbRem += _timers[i].smpPerCbRem;
@@ -1175,16 +1215,37 @@ int TownsPC98_FmSynth::readBuffer(int16 *buffer, const int numSamples) {
tmp += (render << 1);
}
+ if (locked)
+ _mutex.unlock();
+
delete[] tmpStart;
+
return numSamples;
}
+bool TownsPC98_FmSynth::isStereo() const {
+ return true;
+}
+
+bool TownsPC98_FmSynth::endOfData() const {
+ return false;
+}
+
+int TownsPC98_FmSynth::getRate() const {
+ return _mixer->getOutputRate();
+}
+
void TownsPC98_FmSynth::deinit() {
_ready = false;
_mixer->stopHandle(_soundHandle);
+ Common::StackLock lock(_mutex);
_timers[0].cb = _timers[1].cb = &TownsPC98_FmSynth::idleTimerCallback;
}
+void TownsPC98_FmSynth::toggleRegProtection(bool prot) {
+ _regProtectionFlag = prot;
+}
+
uint8 TownsPC98_FmSynth::readSSGStatus() {
return _ssg->chanEnable();
}
@@ -1220,7 +1281,7 @@ void TownsPC98_FmSynth::generateTables() {
WRITE_BE_UINT32(_oprRates + 32, _numChan == 6 ? 0x90900000 : 0x00081018);
WRITE_BE_UINT32(_oprRates + 36, _numChan == 6 ? 0x00001010 : 0x00081018);
memset(_oprRates, 0x90, 32);
- memset(_oprRates + 96, 0x80, 32);
+ memset(&_oprRates[96], 0x80, 32);
uint8 *dst = (uint8 *)_oprRates + 40;
for (int i = 0; i < 40; i += 4)
WRITE_BE_UINT32(dst + i, 0x00081018);
@@ -1277,8 +1338,8 @@ void TownsPC98_FmSynth::generateTables() {
uint8 *dtt = new uint8[128];
memset(dtt, 0, 36);
- memset(dtt + 36, 1, 8);
- memcpy(dtt + 44, _detSrc, 84);
+ memset(&dtt[36], 1, 8);
+ memcpy(&dtt[44], _detSrc, 84);
delete[] _oprDetune;
_oprDetune = new int32[256];
diff --git a/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h b/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h
index 2b916b2cdc..4f81fa9a5c 100644
--- a/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h
+++ b/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h
@@ -18,9 +18,6 @@
* 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$
- *
*/
#ifndef TOWNS_PC98_FMSYNTH_H
@@ -47,7 +44,7 @@ class TownsPC98_FmSynthPercussionSource;
#endif
enum EnvelopeState {
- kEnvReady,
+ kEnvReady = 0,
kEnvAttacking,
kEnvDecaying,
kEnvSustaining,
@@ -62,7 +59,7 @@ public:
kType86
};
- TownsPC98_FmSynth(Audio::Mixer *mixer, EmuType type);
+ TownsPC98_FmSynth(Audio::Mixer *mixer, EmuType type, bool externalMutexHandling = false);
virtual ~TownsPC98_FmSynth();
virtual bool init();
@@ -72,15 +69,9 @@ public:
// AudioStream interface
int readBuffer(int16 *buffer, const int numSamples);
- bool isStereo() const {
- return true;
- }
- bool endOfData() const {
- return false;
- }
- int getRate() const {
- return _mixer->getOutputRate();
- }
+ bool isStereo() const;
+ bool endOfData() const;
+ int getRate() const;
protected:
void deinit();
@@ -89,17 +80,15 @@ protected:
// additional output that has to be inserted into the buffer.
virtual void nextTickEx(int32 *buffer, uint32 bufferSize) {}
- void toggleRegProtection(bool prot) {
- _regProtectionFlag = prot;
- }
+ void toggleRegProtection(bool prot);
uint8 readSSGStatus();
virtual void timerCallbackA() = 0;
virtual void timerCallbackB() = 0;
- // The audio driver can store and apply two different audio settings
+ // The audio driver can store and apply two different volume settings
// (usually for music and sound effects). The channel mask will determine
- // which channels get effected by the setting. The first bits will be
+ // which channels get effected by which setting. The first bits will be
// the normal fm channels, the next bits the ssg channels and the final
// bit the rhythm channel.
void setVolumeIntern(int volA, int volB);
@@ -110,6 +99,8 @@ protected:
const bool _hasPercussion;
Common::Mutex _mutex;
+ bool _externalMutex;
+
private:
void generateTables();
void nextTick(int32 *buffer, uint32 bufferSize);
@@ -127,6 +118,7 @@ private:
}
uint16 frqTemp;
+ uint8 fmIndex;
bool enableLeft;
bool enableRight;
bool updateEnvelopeParameters;
diff --git a/audio/softsynth/fmtowns_pc98/towns_pc98_plugins.cpp b/audio/softsynth/fmtowns_pc98/towns_pc98_plugins.cpp
new file mode 100644
index 0000000000..194bfc41f9
--- /dev/null
+++ b/audio/softsynth/fmtowns_pc98/towns_pc98_plugins.cpp
@@ -0,0 +1,86 @@
+/* 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.
+ *
+ */
+
+#include "audio/softsynth/fmtowns_pc98/towns_midi.h"
+#include "audio/musicplugin.h"
+#include "common/translation.h"
+#include "common/error.h"
+#include "common/system.h"
+
+
+class TownsEmuMusicPlugin : public MusicPluginObject {
+public:
+ const char *getName() const {
+ return _s("FM-Towns Audio");
+ }
+
+ const char *getId() const {
+ return "towns";
+ }
+
+ MusicDevices getDevices() const;
+ Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const;
+};
+
+MusicDevices TownsEmuMusicPlugin::getDevices() const {
+ MusicDevices devices;
+ devices.push_back(MusicDevice(this, "", MT_TOWNS));
+ return devices;
+}
+
+Common::Error TownsEmuMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle) const {
+ *mididriver = new MidiDriver_TOWNS(g_system->getMixer());
+ return Common::kNoError;
+}
+
+class PC98EmuMusicPlugin : public MusicPluginObject {
+public:
+ const char *getName() const {
+ return _s("PC-98 Audio");
+ }
+
+ const char *getId() const {
+ return "pc98";
+ }
+
+ MusicDevices getDevices() const;
+ Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const;
+};
+
+MusicDevices PC98EmuMusicPlugin::getDevices() const {
+ MusicDevices devices;
+ devices.push_back(MusicDevice(this, "", MT_PC98));
+ return devices;
+}
+
+Common::Error PC98EmuMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle) const {
+ //*mididriver = /**/
+ return Common::kNoError;
+}
+
+//#if PLUGIN_ENABLED_DYNAMIC(TOWNS)
+ //REGISTER_PLUGIN_DYNAMIC(TOWNS, PLUGIN_TYPE_MUSIC, TownsEmuMusicPlugin);
+ //REGISTER_PLUGIN_DYNAMIC(TOWNS, PLUGIN_TYPE_MUSIC, TownsEmuMusicPlugin);
+//#else
+ REGISTER_PLUGIN_STATIC(TOWNS, PLUGIN_TYPE_MUSIC, TownsEmuMusicPlugin);
+ REGISTER_PLUGIN_STATIC(PC98, PLUGIN_TYPE_MUSIC, PC98EmuMusicPlugin);
+//#endif
diff --git a/audio/softsynth/mt32.cpp b/audio/softsynth/mt32.cpp
index 5371be60b3..27a5a629c4 100644
--- a/audio/softsynth/mt32.cpp
+++ b/audio/softsynth/mt32.cpp
@@ -17,9 +17,6 @@
* 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$
*/
#include "common/scummsys.h"
@@ -66,7 +63,7 @@ protected:
void generateSamples(int16 *buf, int len);
public:
- bool _initialising;
+ bool _initializing;
MidiDriver_MT32(Audio::Mixer *mixer);
virtual ~MidiDriver_MT32();
@@ -218,7 +215,7 @@ static MT32Emu::File *MT32_OpenFile(void *userData, const char *filename, MT32Em
}
static void MT32_PrintDebug(void *userData, const char *fmt, va_list list) {
- if (((MidiDriver_MT32 *)userData)->_initialising) {
+ if (((MidiDriver_MT32 *)userData)->_initializing) {
char buf[512];
vsnprintf(buf, 512, fmt, list);
@@ -242,7 +239,7 @@ static int MT32_Report(void *userData, MT32Emu::ReportType type, const void *rep
error("Failed to load MT32_PCM.ROM");
break;
case MT32Emu::ReportType_progressInit:
- if (((MidiDriver_MT32 *)userData)->_initialising) {
+ if (((MidiDriver_MT32 *)userData)->_initializing) {
drawProgress(*((const float *)reportData));
return eatSystemEvents();
}
@@ -286,7 +283,7 @@ MidiDriver_MT32::MidiDriver_MT32(Audio::Mixer *mixer) : MidiDriver_Emulated(mixe
// at rates other than 32KHz, thus we produce data at 32KHz and
// rely on Mixer to convert.
_outputRate = 32000; //_mixer->getOutputRate();
- _initialising = false;
+ _initializing = false;
}
MidiDriver_MT32::~MidiDriver_MT32() {
@@ -327,11 +324,11 @@ int MidiDriver_MT32::open() {
g_system->getPaletteManager()->setPalette(dummy_palette, 0, 3);
}
- _initialising = true;
- drawMessage(-1, _s("Initialising MT-32 Emulator"));
+ _initializing = true;
+ drawMessage(-1, _s("Initializing MT-32 Emulator"));
if (!_synth->open(prop))
return MERR_DEVICE_NOT_AVAILABLE;
- _initialising = false;
+ _initializing = false;
if (screenFormat.bytesPerPixel > 1)
g_system->fillScreen(screenFormat.RGBToColor(0, 0, 0));
diff --git a/audio/softsynth/mt32/freeverb.cpp b/audio/softsynth/mt32/freeverb.cpp
index c62d4f2cf3..67f065c20e 100644
--- a/audio/softsynth/mt32/freeverb.cpp
+++ b/audio/softsynth/mt32/freeverb.cpp
@@ -18,9 +18,6 @@
* 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$
- *
*/
// Comb filter implementation
diff --git a/audio/softsynth/mt32/freeverb.h b/audio/softsynth/mt32/freeverb.h
index 8310aca3e3..39ae463970 100644
--- a/audio/softsynth/mt32/freeverb.h
+++ b/audio/softsynth/mt32/freeverb.h
@@ -18,9 +18,6 @@
* 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$
- *
*/
// Macro for killing denormalled numbers
diff --git a/audio/softsynth/mt32/partial.cpp b/audio/softsynth/mt32/partial.cpp
index 5ba9ef6145..c4f2e94ebe 100644
--- a/audio/softsynth/mt32/partial.cpp
+++ b/audio/softsynth/mt32/partial.cpp
@@ -28,7 +28,7 @@
#if defined(MACOSX) || defined(SOLARIS) || defined(__MINGW32__)
// Older versions of Mac OS X didn't supply a powf function, so using it
// will cause a binary incompatibility when trying to run a binary built
-// on a newer OS X release on an olderr one. And Solaris 8 doesn't provide
+// on a newer OS X release on an older one. And Solaris 8 doesn't provide
// powf, floorf, fabsf etc. at all.
// Cross-compiled MinGW32 toolchains suffer from a cross-compile bug in
// libstdc++. math/stubs.o should be empty, but it comes with a symbol for
@@ -164,7 +164,7 @@ void Partial::startPartial(dpoly *usePoly, const PatchCache *useCache, Partial *
structurePosition = patchCache->structurePosition;
play = true;
- initKeyFollow(poly->freqnum); // Initialises noteVal, filtVal and realVal
+ initKeyFollow(poly->freqnum); // Initializes noteVal, filtVal and realVal
#if MT32EMU_ACCURATENOTES == 0
noteLookup = &synth->tables.noteLookups[noteVal - LOWEST_NOTE];
#else
diff --git a/audio/softsynth/mt32/synth.cpp b/audio/softsynth/mt32/synth.cpp
index 112527cc71..322b864b6e 100644
--- a/audio/softsynth/mt32/synth.cpp
+++ b/audio/softsynth/mt32/synth.cpp
@@ -34,7 +34,7 @@
#if defined(MACOSX) || defined(SOLARIS) || defined(__MINGW32__)
// Older versions of Mac OS X didn't supply a powf function, so using it
// will cause a binary incompatibility when trying to run a binary built
-// on a newer OS X release on an olderr one. And Solaris 8 doesn't provide
+// on a newer OS X release on an older one. And Solaris 8 doesn't provide
// powf, floorf, fabsf etc. at all.
// Cross-compiled MinGW32 toolchains suffer from a cross-compile bug in
// libstdc++. math/stubs.o should be empty, but it comes with a symbol for
@@ -426,36 +426,36 @@ bool Synth::open(SynthProperties &useProp) {
}
}
- printDebug("Initialising Timbre Bank A");
+ printDebug("Initializing Timbre Bank A");
if (!initTimbres(controlROMMap->timbreAMap, controlROMMap->timbreAOffset, 0)) {
return false;
}
- printDebug("Initialising Timbre Bank B");
+ printDebug("Initializing Timbre Bank B");
if (!initTimbres(controlROMMap->timbreBMap, controlROMMap->timbreBOffset, 64)) {
return false;
}
- printDebug("Initialising Timbre Bank R");
+ printDebug("Initializing Timbre Bank R");
if (!initRhythmTimbres(controlROMMap->timbreRMap, controlROMMap->timbreRCount)) {
return false;
}
- printDebug("Initialising Timbre Bank M");
- // CM-64 seems to initialise all bytes in this bank to 0.
+ printDebug("Initializing Timbre Bank M");
+ // CM-64 seems to initialize all bytes in this bank to 0.
memset(&mt32ram.timbres[128], 0, sizeof (mt32ram.timbres[128]) * 64);
partialManager = new PartialManager(this);
pcmWaves = new PCMWaveEntry[controlROMMap->pcmCount];
- printDebug("Initialising PCM List");
+ printDebug("Initializing PCM List");
initPCMList(controlROMMap->pcmTable, controlROMMap->pcmCount);
- printDebug("Initialising Rhythm Temp");
+ printDebug("Initializing Rhythm Temp");
memcpy(mt32ram.rhythmSettings, &controlROMData[controlROMMap->rhythmSettings], controlROMMap->rhythmSettingsCount * 4);
- printDebug("Initialising Patches");
+ printDebug("Initializing Patches");
for (Bit8u i = 0; i < 128; i++) {
PatchParam *patch = &mt32ram.patches[i];
patch->timbreGroup = i / 64;
@@ -468,9 +468,9 @@ bool Synth::open(SynthProperties &useProp) {
patch->dummy = 0;
}
- printDebug("Initialising System");
+ printDebug("Initializing System");
// The MT-32 manual claims that "Standard pitch" is 442Hz.
- mt32ram.system.masterTune = 0x40; // Confirmed on CM-64 as 0x4A, but SCUMM games use 0x40 and we don't want to initialise twice
+ mt32ram.system.masterTune = 0x40; // Confirmed on CM-64 as 0x4A, but SCUMM games use 0x40 and we don't want to initialize twice
mt32ram.system.reverbMode = 0; // Confirmed
mt32ram.system.reverbTime = 5; // Confirmed
mt32ram.system.reverbLevel = 3; // Confirmed
@@ -792,7 +792,7 @@ void Synth::writeSysex(unsigned char device, const Bit8u *sysex, Bit32u len) {
for (;;) {
// Find the appropriate memory region
int regionNum;
- const MemoryRegion *region = NULL; // Initialised to please compiler
+ const MemoryRegion *region = NULL; // Initialized to please compiler
for (regionNum = 0; regionNum < NUM_REGIONS; regionNum++) {
region = &memoryRegions[regionNum];
if (region->contains(addr)) {
diff --git a/audio/softsynth/mt32/synth.h b/audio/softsynth/mt32/synth.h
index edda446287..0ef2c9d135 100644
--- a/audio/softsynth/mt32/synth.h
+++ b/audio/softsynth/mt32/synth.h
@@ -263,7 +263,7 @@ public:
Synth();
~Synth();
- // Used to initialise the MT-32. Must be called before any other function.
+ // Used to initialize the MT-32. Must be called before any other function.
// Returns true if initialization was sucessful, otherwise returns false.
bool open(SynthProperties &useProp);
diff --git a/audio/softsynth/mt32/tables.cpp b/audio/softsynth/mt32/tables.cpp
index eba4d2a520..9fdb595467 100644
--- a/audio/softsynth/mt32/tables.cpp
+++ b/audio/softsynth/mt32/tables.cpp
@@ -19,6 +19,10 @@
* IN THE SOFTWARE.
*/
+
+// FIXME: Avoid using rand
+#define FORBIDDEN_SYMBOL_EXCEPTION_rand
+
#include <stdlib.h>
#include <string.h>
#include <math.h>
@@ -28,7 +32,7 @@
#if defined(MACOSX) || defined(SOLARIS) || defined(__MINGW32__)
// Older versions of Mac OS X didn't supply a powf function, so using it
// will cause a binary incompatibility when trying to run a binary built
-// on a newer OS X release on an olderr one. And Solaris 8 doesn't provide
+// on a newer OS X release on an older one. And Solaris 8 doesn't provide
// powf, floorf, fabsf etc. at all.
// Cross-compiled MinGW32 toolchains suffer from a cross-compile bug in
// libstdc++. math/stubs.o should be empty, but it comes with a symbol for
@@ -199,7 +203,7 @@ void Tables::initEnvelopes(float samplerate) {
void Tables::initMT32ConstantTables(Synth *synth) {
int lf;
- synth->printDebug("Initialising Pitch Tables");
+ synth->printDebug("Initializing Pitch Tables");
for (lf = -108; lf <= 108; lf++) {
tvfKeyfollowMult[lf + 108] = (int)(256 * powf(2.0f, (float)(lf / 24.0f)));
//synth->printDebug("KT %d = %d", f, keytable[f+108]);
@@ -664,7 +668,7 @@ bool Tables::initNotes(Synth *synth, PCMWaveEntry *pcmWaves, float rate, float m
bool abort = false;
synth->report(ReportType_progressInit, &progress);
for (int f = LOWEST_NOTE; f <= HIGHEST_NOTE; f++) {
- synth->printDebug("Initialising note %s%d", NoteNames[f % 12], (f / 12) - 2);
+ synth->printDebug("Initializing note %s%d", NoteNames[f % 12], (f / 12) - 2);
NoteLookup *noteLookup = &noteLookups[f - LOWEST_NOTE];
file = initNote(synth, noteLookup, (float)f, rate, masterTune, pcmWaves, file);
progress = (f - LOWEST_NOTE + 1) / (float)NUM_NOTES;
@@ -719,12 +723,12 @@ void Tables::freeNotes() {
}
}
}
- initialisedMasterTune = 0.0f;
+ initializedMasterTune = 0.0f;
}
Tables::Tables() {
- initialisedSampleRate = 0.0f;
- initialisedMasterTune = 0.0f;
+ initializedSampleRate = 0.0f;
+ initializedMasterTune = 0.0f;
memset(&noteLookups, 0, sizeof(noteLookups));
}
@@ -733,23 +737,23 @@ bool Tables::init(Synth *synth, PCMWaveEntry *pcmWaves, float sampleRate, float
synth->printDebug("Bad sampleRate (%f <= 0.0f)", (double)sampleRate);
return false;
}
- if (initialisedSampleRate == 0.0f) {
+ if (initializedSampleRate == 0.0f) {
initMT32ConstantTables(synth);
}
- if (initialisedSampleRate != sampleRate) {
+ if (initializedSampleRate != sampleRate) {
initFiltCoeff(sampleRate);
initEnvelopes(sampleRate);
for (int key = 12; key <= 108; key++) {
initDep(&keyLookups[key - 12], (float)key);
}
}
- if (initialisedSampleRate != sampleRate || initialisedMasterTune != masterTune) {
+ if (initializedSampleRate != sampleRate || initializedMasterTune != masterTune) {
freeNotes();
if (!initNotes(synth, pcmWaves, sampleRate, masterTune)) {
return false;
}
- initialisedSampleRate = sampleRate;
- initialisedMasterTune = masterTune;
+ initializedSampleRate = sampleRate;
+ initializedMasterTune = masterTune;
}
return true;
}
diff --git a/audio/softsynth/mt32/tables.h b/audio/softsynth/mt32/tables.h
index d9af5114b2..9950323e7b 100644
--- a/audio/softsynth/mt32/tables.h
+++ b/audio/softsynth/mt32/tables.h
@@ -69,8 +69,8 @@ struct KeyLookup {
};
class Tables {
- float initialisedSampleRate;
- float initialisedMasterTune;
+ float initializedSampleRate;
+ float initializedMasterTune;
void initMT32ConstantTables(Synth *synth);
static Bit16s clampWF(Synth *synth, const char *n, float ampVal, double input);
static File *initWave(Synth *synth, NoteLookup *noteLookup, float ampsize, float div2, File *file);
diff --git a/audio/softsynth/opl/dosbox.cpp b/audio/softsynth/opl/dosbox.cpp
index 7a494d70ec..e039845b8f 100644
--- a/audio/softsynth/opl/dosbox.cpp
+++ b/audio/softsynth/opl/dosbox.cpp
@@ -17,9 +17,6 @@
* 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$
*/
/*
diff --git a/audio/softsynth/opl/dosbox.h b/audio/softsynth/opl/dosbox.h
index 1e92c7f7c9..125dde8aec 100644
--- a/audio/softsynth/opl/dosbox.h
+++ b/audio/softsynth/opl/dosbox.h
@@ -17,9 +17,6 @@
* 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$
*/
/*
diff --git a/audio/softsynth/opl/mame.cpp b/audio/softsynth/opl/mame.cpp
index 5d790f924f..9cc35971eb 100644
--- a/audio/softsynth/opl/mame.cpp
+++ b/audio/softsynth/opl/mame.cpp
@@ -18,9 +18,6 @@
* 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$
- *
* LGPL licensed version of MAMEs fmopl (V0.37a modified) by
* Tatsuyuki Satoh. Included from LGPL'ed AdPlug.
*/
@@ -549,7 +546,7 @@ inline void OPL_CALC_RH(FM_OPL *OPL, OPL_CH *CH) {
// but EG_STEP = 96.0/EG_ENT, and WHITE_NOISE_db=6.0. So, that's equivalent to
// int(OPL->rnd.getRandomBit() * EG_ENT/16). We know that EG_ENT is 4096, or 1024,
// or 128, so we can safely avoid any FP ops.
- int whitenoise = OPL->rnd.getRandomBit() * (EG_ENT>>4);
+ int whitenoise = OPL->rnd->getRandomBit() * (EG_ENT>>4);
int tone8;
@@ -1129,6 +1126,15 @@ FM_OPL *OPLCreate(int type, int clock, int rate) {
OPL->rate = rate;
OPL->max_ch = max_ch;
+ // Init the random source. Note: We use a fixed name for it here.
+ // So if multiple FM_OPL objects exist in parallel, then their
+ // random sources will have an equal name. At least in the
+ // current EventRecorder implementation, this causes no problems;
+ // but this is probably not guaranteed.
+ // Alas, it does not seem worthwhile to bother much with this
+ // at the time, so I am leaving it as it is.
+ OPL->rnd = new Common::RandomSource("mame");
+
/* init grobal tables */
OPL_initalize(OPL);
@@ -1137,9 +1143,10 @@ FM_OPL *OPLCreate(int type, int clock, int rate) {
return OPL;
}
-/* ---------- Destroy one of vietual YM3812 ---------- */
+/* ---------- Destroy one of virtual YM3812 ---------- */
void OPLDestroy(FM_OPL *OPL) {
OPL_UnLockTable();
+ delete OPL->rnd;
free(OPL);
}
diff --git a/audio/softsynth/opl/mame.h b/audio/softsynth/opl/mame.h
index 4314aa6dba..803ca897e7 100644
--- a/audio/softsynth/opl/mame.h
+++ b/audio/softsynth/opl/mame.h
@@ -18,9 +18,6 @@
* 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$
- *
* LGPL licensed version of MAMEs fmopl (V0.37a modified) by
* Tatsuyuki Satoh. Included from LGPL'ed AdPlug.
*/
@@ -150,7 +147,7 @@ typedef struct fm_opl_f {
OPL_UPDATEHANDLER UpdateHandler; /* stream update handler */
int UpdateParam; /* stream update parameter */
- Common::RandomSource rnd;
+ Common::RandomSource *rnd;
} FM_OPL;
/* ---------- Generic interface section ---------- */
diff --git a/audio/softsynth/pcspk.cpp b/audio/softsynth/pcspk.cpp
index 947c142b73..66af968463 100644
--- a/audio/softsynth/pcspk.cpp
+++ b/audio/softsynth/pcspk.cpp
@@ -18,9 +18,6 @@
* 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$
-*
*/
#include "audio/softsynth/pcspk.h"
diff --git a/audio/softsynth/pcspk.h b/audio/softsynth/pcspk.h
index 8f01fa852b..3641400b1f 100644
--- a/audio/softsynth/pcspk.h
+++ b/audio/softsynth/pcspk.h
@@ -17,9 +17,6 @@
* 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$
*/
#ifndef SOUND_SOFTSYNTH_PCSPK_H
diff --git a/audio/softsynth/sid.cpp b/audio/softsynth/sid.cpp
index 40dc50e972..4b8f783ef4 100644
--- a/audio/softsynth/sid.cpp
+++ b/audio/softsynth/sid.cpp
@@ -18,9 +18,6 @@
* 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$
- *
*/
/*
diff --git a/audio/softsynth/sid.h b/audio/softsynth/sid.h
index d6e402dc3b..a015242844 100644
--- a/audio/softsynth/sid.h
+++ b/audio/softsynth/sid.h
@@ -18,9 +18,6 @@
* 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$
- *
*/
/*
diff --git a/audio/softsynth/wave6581.cpp b/audio/softsynth/wave6581.cpp
index d1ddad1623..63e08fb113 100644
--- a/audio/softsynth/wave6581.cpp
+++ b/audio/softsynth/wave6581.cpp
@@ -18,9 +18,6 @@
* 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$
- *
*/
/*
diff --git a/audio/softsynth/ym2612.cpp b/audio/softsynth/ym2612.cpp
deleted file mode 100644
index 162c92f05a..0000000000
--- a/audio/softsynth/ym2612.cpp
+++ /dev/null
@@ -1,793 +0,0 @@
-/* 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$
- */
-
-#include <math.h>
-
-#include "audio/softsynth/ym2612.h"
-#include "common/util.h"
-#include "audio/musicplugin.h"
-#include "common/error.h"
-#include "common/system.h"
-#include "common/textconsole.h"
-#include "common/translation.h"
-#include "common/types.h"
-
-////////////////////////////////////////
-//
-// Miscellaneous
-//
-////////////////////////////////////////
-
-static int *sintbl = 0;
-static int *powtbl = 0;
-static int *frequencyTable = 0;
-static int *keycodeTable = 0;
-static int *keyscaleTable = 0;
-static int *attackOut = 0;
-
-
-////////////////////////////////////////
-//
-// Operator2612 implementation
-//
-////////////////////////////////////////
-
-Operator2612::Operator2612 (Voice2612 *owner) :
- _owner (owner),
- _state (_s_ready),
- _currentLevel ((int32)0x7f << 15),
- _phase (0),
- _lastOutput (0),
- _feedbackLevel (0),
- _detune (0),
- _multiple (1),
- _keyScale (0),
- _specifiedTotalLevel (127),
- _specifiedAttackRate (0),
- _specifiedDecayRate (0),
- _specifiedSustainRate (0),
- _specifiedReleaseRate (15) {
- velocity(0);
-}
-
-Operator2612::~Operator2612()
-{ }
-
-void Operator2612::velocity(int velo) {
- _velocity = velo;
- _totalLevel = ((int32)_specifiedTotalLevel << 15) +
- ((int32)(127-_velocity) << 13);
- _sustainLevel = ((int32)_specifiedSustainLevel << 17);
-}
-
-void Operator2612::feedbackLevel(int level) {
- _feedbackLevel = level;
-}
-
-void Operator2612::setInstrument(byte const *instrument) {
- _detune = (instrument[8] >> 4) & 7;
- _multiple = instrument[8] & 15;
- _specifiedTotalLevel = instrument[12] & 127;
- _keyScale = (instrument[16] >> 6) & 3;
- _specifiedAttackRate = instrument[16] & 31;
- _specifiedDecayRate = instrument[20] & 31;
- _specifiedSustainRate = instrument[24] & 31;
- _specifiedSustainLevel = (instrument[28] >> 4) & 15;
- _specifiedReleaseRate = instrument[28] & 15;
- _state = _s_ready;
- velocity(_velocity);
-}
-
-void Operator2612::keyOn() {
- _state = _s_attacking;
- _tickCount = 0;
- _phase = 0;
- _currentLevel = ((int32)0x7f << 15);
-}
-
-void Operator2612::keyOff() {
- if (_state != _s_ready)
- _state = _s_releasing;
-}
-
-void Operator2612::frequency(int freq) {
- double value; // Use for intermediate computations to avoid int64 arithmetic
- int r;
-
- _frequency = freq / _owner->_rate;
-
- r = _specifiedAttackRate;
- if (r != 0) {
- r = r * 2 + (keyscaleTable[freq/262205] >> (3-_keyScale));
- if (r >= 64)
- r = 63;
- }
-
- r = 63 - r;
- if (_specifiedTotalLevel >= 128)
- value = 0;
- else {
- value = powtbl[(r&3) << 7];
- value *= 1 << (r >> 2);
- value *= 41;
- value /= 1 << (15 + 5);
- value *= 127 - _specifiedTotalLevel;
- value /= 127;
- }
- _attackTime = (int32) value; // 1 ?? == (1 << 12)
- if (_attackTime > 0)
- _attackTime = (1 << (12+10)) / (_owner->_rate * _attackTime);
-
- r = _specifiedDecayRate;
- if (r != 0) {
- r = r * 2 + (keyscaleTable[freq/262205] >> (3-_keyScale));
- if (r >= 64)
- r = 63;
- }
- value = (double) powtbl[(r&3) << 7] * (0x10 << (r>>2)) / 31;
- _decayRate = (int32) value / _owner->_rate;
-
- r = _specifiedSustainRate;
- if (r != 0) {
- r = r * 2 + (keyscaleTable[freq/262205] >> (3-_keyScale));
- if (r >= 64)
- r = 63;
- }
- value = (double) powtbl[(r&3) << 7] * (0x10 << (r>>2)) / 31;
- _sustainRate = (int32) value / _owner->_rate;
-
- r = _specifiedReleaseRate;
- if (r != 0) {
- r = r * 2 + 1; // (Translated) I cannot know whether the timing is a good choice or not
- r = r * 2 + (keyscaleTable[freq/262205] >> (3-_keyScale));
- // KS
- if (r >= 64)
- r = 63;
- }
- value = (double) powtbl[(r&3) << 7] * (0x10 << (r>>2)) / 31;
- _releaseRate = (int32) value / _owner->_rate;
-}
-
-void Operator2612::nextTick(const int *phasebuf, int *outbuf, int buflen) {
- if (_state == _s_ready)
- return;
- if (_state == _s_attacking && _attackTime <= 0) {
- _currentLevel = 0;
- _state = _s_decaying;
- }
-
- int32 levelIncrement = 0;
- int32 target = 0;
- State next_state = _s_ready;
- const int32 zero_level = ((int32)0x7f << 15);
- const int phaseIncrement = (_multiple > 0) ? (_frequency * _multiple) : (_frequency / 2);
-
- int32 output = _lastOutput;
- int32 level = _currentLevel + _totalLevel;
-
- while (buflen) {
- switch (_state) {
- case _s_ready:
- return;
- case _s_attacking:
- next_state = _s_attacking;
- break;
- case _s_decaying:
- levelIncrement = _decayRate;
- target = _sustainLevel + _totalLevel;
- next_state = _s_sustaining;
- break;
- case _s_sustaining:
- levelIncrement = _sustainRate;
- target = zero_level + _totalLevel;
- next_state = _s_ready;
- break;
- case _s_releasing:
- levelIncrement = _releaseRate;
- target = zero_level + _totalLevel;
- next_state = _s_ready;
- break;
- }
-
- bool switching = false;
- do {
- if (next_state == _s_attacking) {
- // Attack phase
- ++_tickCount;
- int i = (int) (_tickCount * _attackTime);
- if (i >= 1024) {
- level = _totalLevel;
- _state = _s_decaying;
- switching = true;
- } else {
- level = (attackOut[i] << (31 - 8 - 16)) + _totalLevel;
- }
- } else {
- // Decay, Sustain and Release phases
- level += levelIncrement;
- if (level >= target) {
- level = target;
- _state = next_state;
- switching = true;
- }
- }
-
- if (level < zero_level) {
- int phaseShift = *phasebuf >> 2;
- if (_feedbackLevel)
- phaseShift += (output << (_feedbackLevel - 1)) / 1024;
- output = sintbl[((_phase >> 7) + phaseShift) & 0x7ff];
- output >>= (level >> 18);
- // Here is the original code, which requires 64-bit ints
-// output *= powtbl[511 - ((level>>25)&511)];
-// output >>= 16;
-// output >>= 1;
- // And here's our 32-bit trick for doing it. (Props to Fingolfin!)
- // Result varies from original code by max of 1.
-// int powVal = powtbl[511 - ((level>>9)&511)];
-// int outputHI = output / 256;
-// int powHI = powVal / 256;
-// output = (outputHI * powHI) / 2 + (outputHI * (powVal % 256) + powHI * (output % 256)) / 512;
- // And here's the even faster code.
- // Result varies from original code by max of 8.
- output = ((output >> 4) * (powtbl[511-((level>>9)&511)] >> 3)) / 1024;
-
- _phase += phaseIncrement;
- _phase &= 0x3ffff;
- } else
- output = 0;
-
- *outbuf += output;
- --buflen;
- ++phasebuf;
- ++outbuf;
- } while (buflen && !switching);
- }
- _lastOutput = output;
- _currentLevel = level - _totalLevel;
-}
-
-////////////////////////////////////////
-//
-// Voice2612 implementation
-//
-////////////////////////////////////////
-
-Voice2612::Voice2612() {
- next = 0;
- _control7 = 127;
- _note = 40;
- _frequency = 440;
- _frequencyOffs = 0x2000;
- _algorithm = 7;
-
- _buffer = 0;
- _buflen = 0;
-
- int i;
- for (i = 0; i < ARRAYSIZE(_opr); ++i)
- _opr[i] = new Operator2612 (this);
- velocity(0);
-}
-
-Voice2612::~Voice2612() {
- int i;
- for (i = 0; i < ARRAYSIZE(_opr); ++i)
- delete _opr[i];
- free(_buffer);
-}
-
-void Voice2612::velocity(int velo) {
- _velocity = velo;
-#if 0
- int v = (velo * _control7) >> 7;
-#else
- int v = velo + (_control7 - 127) * 4;
-#endif
- bool iscarrier[8][4] = {
- { false, false, false, true, }, //0
- { false, false, false, true, }, //1
- { false, false, false, true, }, //2
- { false, false, false, true, }, //3
- { false, true, false, true, }, //4
- { false, true, true, true, }, //5
- { false, true, true, true, }, //6
- { true, true, true, true, }, //7
- };
- int opr;
- for (opr = 0; opr < 4; opr++)
- if (iscarrier[_algorithm][opr])
- _opr[opr]->velocity(v);
- else
- _opr[opr]->velocity(127);
-}
-
-void Voice2612::setControlParameter(int control, int value) {
- switch (control) {
- case 7:
- _control7 = value;
- velocity(_velocity);
- break;
- case 123:
- // All notes off
- noteOff(_note);
- };
-}
-
-void Voice2612::setInstrument(byte const *instrument) {
- if (instrument == NULL)
- return;
-
- _algorithm = instrument[32] & 7;
- _opr[0]->feedbackLevel((instrument[32] >> 3) & 7);
- _opr[1]->feedbackLevel(0);
- _opr[2]->feedbackLevel(0);
- _opr[3]->feedbackLevel(0);
- _opr[0]->setInstrument(instrument + 0);
- _opr[1]->setInstrument(instrument + 2);
- _opr[2]->setInstrument(instrument + 1);
- _opr[3]->setInstrument(instrument + 3);
-}
-
-void Voice2612::nextTick(int *outbuf, int buflen) {
- if (_velocity == 0)
- return;
-
- if (_buflen < buflen) {
- free(_buffer);
- _buflen = buflen;
- _buffer = (int *) malloc(sizeof(int) * buflen * 2);
- }
-
- int *buf1 = _buffer;
- int *buf2 = _buffer + buflen;
- memset(_buffer, 0, sizeof(int) * buflen * 2);
-
- switch (_algorithm) {
- case 0:
- _opr[0]->nextTick(buf1, buf2, buflen);
- _opr[1]->nextTick(buf2, buf1, buflen);
- memset (buf2, 0, sizeof (int) * buflen);
- _opr[2]->nextTick(buf1, buf2, buflen);
- _opr[3]->nextTick(buf2, outbuf, buflen);
- break;
- case 1:
- _opr[0]->nextTick(buf1, buf2, buflen);
- _opr[1]->nextTick(buf1, buf2, buflen);
- _opr[2]->nextTick(buf2, buf1, buflen);
- _opr[3]->nextTick(buf1, outbuf, buflen);
- break;
- case 2:
- _opr[1]->nextTick(buf1, buf2, buflen);
- _opr[2]->nextTick(buf2, buf1, buflen);
- memset(buf2, 0, sizeof(int) * buflen);
- _opr[0]->nextTick(buf2, buf1, buflen);
- _opr[3]->nextTick(buf1, outbuf, buflen);
- break;
- case 3:
- _opr[0]->nextTick(buf1, buf2, buflen);
- _opr[1]->nextTick(buf2, buf1, buflen);
- memset(buf2, 0, sizeof(int) * buflen);
- _opr[2]->nextTick(buf2, buf1, buflen);
- _opr[3]->nextTick(buf1, outbuf, buflen);
- break;
- case 4:
- _opr[0]->nextTick(buf1, buf2, buflen);
- _opr[1]->nextTick(buf2, outbuf, buflen);
- _opr[2]->nextTick(buf1, buf1, buflen);
- _opr[3]->nextTick(buf1, outbuf, buflen);
- break;
- case 5:
- _opr[0]->nextTick(buf1, buf2, buflen);
- _opr[1]->nextTick(buf2, outbuf, buflen);
- _opr[2]->nextTick(buf2, outbuf, buflen);
- _opr[3]->nextTick(buf2, outbuf, buflen);
- break;
- case 6:
- _opr[0]->nextTick(buf1, buf2, buflen);
- _opr[1]->nextTick(buf2, outbuf, buflen);
- _opr[2]->nextTick(buf1, outbuf, buflen);
- _opr[3]->nextTick(buf1, outbuf, buflen);
- break;
- case 7:
- _opr[0]->nextTick(buf1, outbuf, buflen);
- _opr[1]->nextTick(buf1, outbuf, buflen);
- _opr[2]->nextTick(buf1, outbuf, buflen);
- _opr[3]->nextTick(buf1, outbuf, buflen);
- break;
- };
-}
-
-void Voice2612::noteOn(int n, int onVelo) {
- _note = n;
- velocity(onVelo);
- recalculateFrequency();
- int i;
- for (i = 0; i < ARRAYSIZE(_opr); i++)
- _opr[i]->keyOn();
-}
-
-bool Voice2612::noteOff(int note) {
- if (_note != note)
- return false;
- int i;
- for (i = 0; i < ARRAYSIZE(_opr); i++)
- _opr[i]->keyOff();
- return true;
-}
-
-void Voice2612::pitchBend(int value) {
- _frequencyOffs = value;
- recalculateFrequency();
-}
-
-void Voice2612::recalculateFrequency() {
- //
- //
- //
- int32 basefreq = frequencyTable[_note];
- int cfreq = frequencyTable[_note - (_note % 12)];
- int oct = _note / 12;
- int fnum = (int) (((double)basefreq * (1 << 13)) / cfreq);
- fnum += _frequencyOffs - 0x2000;
- if (fnum < 0x2000) {
- fnum += 0x2000;
- oct--;
- }
- if (fnum >= 0x4000) {
- fnum -= 0x2000;
- oct++;
- }
-
- //
- _frequency = (int) ((frequencyTable[oct*12] * (double)fnum) / 8);
-
- int i;
- for (i = 0; i < ARRAYSIZE(_opr); i++)
- _opr[i]->frequency(_frequency);
-}
-
-////////////////////////////////////////
-//
-// MidiChannel_YM2612
-//
-////////////////////////////////////////
-
-MidiChannel_YM2612::MidiChannel_YM2612() {
- _voices = 0;
- _next_voice = 0;
-}
-
-MidiChannel_YM2612::~MidiChannel_YM2612() {
- removeAllVoices();
-}
-
-void MidiChannel_YM2612::removeAllVoices() {
- if (!_voices)
- return;
- Voice2612 *last, *voice = _voices;
- for (; voice; voice = last) {
- last = voice->next;
- delete voice;
- }
- _voices = _next_voice = 0;
-}
-
-void MidiChannel_YM2612::noteOn(byte note, byte onVelo) {
- if (!_voices)
- return;
- _next_voice = _next_voice ? _next_voice : _voices;
- _next_voice->noteOn(note, onVelo);
- _next_voice = _next_voice->next;
-}
-
-void MidiChannel_YM2612::noteOff(byte note) {
- if (!_voices)
- return;
- if (_next_voice == _voices)
- _next_voice = 0;
- Voice2612 *voice = _next_voice;
- do {
- if (!voice)
- voice = _voices;
- if (voice->noteOff(note)) {
- _next_voice = voice;
- break;
- }
- voice = voice->next;
- } while (voice != _next_voice);
-}
-
-void MidiChannel_YM2612::controlChange(byte control, byte value) {
- //
- if (control == 121) {
- // Reset controller
- removeAllVoices();
- } else {
- Voice2612 *voice = _voices;
- for (; voice; voice = voice->next)
- voice->setControlParameter(control, value);
- }
-}
-
-void MidiChannel_YM2612::sysEx_customInstrument(uint32 type, const byte *fmInst) {
- if (type != 'EUP ')
- return;
- Voice2612 *voice = new Voice2612;
- voice->next = _voices;
- _voices = voice;
- voice->_rate = _rate;
- voice->setInstrument(fmInst);
-}
-
-void MidiChannel_YM2612::pitchBend(int16 value) {
- //
- Voice2612 *voice = _voices;
- for (; voice; voice = voice->next)
- voice->pitchBend(value);
-}
-
-void MidiChannel_YM2612::nextTick(int *outbuf, int buflen) {
- Voice2612 *voice = _voices;
- for (; voice; voice = voice->next)
- voice->nextTick(outbuf, buflen);
-}
-
-void MidiChannel_YM2612::rate(uint16 r) {
- _rate = r;
- Voice2612 *voice = _voices;
- for (; voice; voice = voice->next)
- voice->_rate = r;
-}
-
-////////////////////////////////////////
-//
-// MidiDriver_YM2612
-//
-////////////////////////////////////////
-
-MidiDriver_YM2612::MidiDriver_YM2612(Audio::Mixer *mixer)
- : MidiDriver_Emulated(mixer) {
- _next_voice = 0;
-
- createLookupTables();
- _volume = 256;
- int i;
- for (i = 0; i < ARRAYSIZE(_channel); i++)
- _channel[i] = new MidiChannel_YM2612;
- rate(getRate());
-}
-
-MidiDriver_YM2612::~MidiDriver_YM2612() {
- int i;
- for (i = 0; i < ARRAYSIZE(_channel); i++)
- delete _channel[i];
- removeLookupTables();
-}
-
-int MidiDriver_YM2612::open() {
- if (_isOpen)
- return MERR_ALREADY_OPEN;
-
- MidiDriver_Emulated::open();
-
- _mixer->playStream(Audio::Mixer::kPlainSoundType, &_mixerSoundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
- return 0;
-}
-
-void MidiDriver_YM2612::close() {
- if (!_isOpen)
- return;
- _isOpen = false;
-
- _mixer->stopHandle(_mixerSoundHandle);
-}
-
-void MidiDriver_YM2612::send(uint32 b) {
- send(b & 0xF, b & 0xFFFFFFF0);
-}
-
-void MidiDriver_YM2612::send(byte chan, uint32 b) {
- //byte param3 = (byte) ((b >> 24) & 0xFF);
- byte param2 = (byte) ((b >> 16) & 0xFF);
- byte param1 = (byte) ((b >> 8) & 0xFF);
- byte cmd = (byte) (b & 0xF0);
- if (chan > ARRAYSIZE(_channel))
- return;
-
- switch (cmd) {
- case 0x80:// Note Off
- _channel[chan]->noteOff(param1);
- break;
- case 0x90: // Note On
- _channel[chan]->noteOn(param1, param2);
- break;
- case 0xA0: // Aftertouch
- break; // Not supported.
- case 0xB0: // Control Change
- _channel[chan]->controlChange(param1, param2);
- break;
- case 0xC0: // Program Change
- _channel[chan]->programChange(param1);
- break;
- case 0xD0: // Channel Pressure
- break; // Not supported.
- case 0xE0: // Pitch Bend
- _channel[chan]->pitchBend((param1 | (param2 << 7)) - 0x2000);
- break;
- case 0xF0: // SysEx
- // We should never get here! SysEx information has to be
- // sent via high-level semantic methods.
- warning("MidiDriver_YM2612: Receiving SysEx command on a send() call");
- break;
-
- default:
- warning("MidiDriver_YM2612: Unknown send() command 0x%02X", cmd);
- }
-}
-
-void MidiDriver_YM2612::sysEx(const byte *msg, uint16 length) {
- if (msg[0] != 0x7C || msg[1] >= ARRAYSIZE(_channel))
- return;
- _channel[msg[1]]->sysEx_customInstrument('EUP ', &msg[2]);
-}
-
-void MidiDriver_YM2612::generateSamples(int16 *data, int len) {
- memset(data, 0, 2 * sizeof(int16) * len);
- nextTick(data, len);
-}
-
-void MidiDriver_YM2612::nextTick(int16 *buf1, int buflen) {
- int *buf0 = (int *)buf1;
-
- int i;
- for (i = 0; i < ARRAYSIZE(_channel); i++)
- _channel[i]->nextTick(buf0, buflen);
-
- for (i = 0; i < buflen; ++i)
- buf1[i*2+1] = buf1[i*2] = ((buf0[i] * volume()) >> 10) & 0xffff;
-}
-
-void MidiDriver_YM2612::rate(uint16 r)
-{
- int i;
- for (i = 0; i < ARRAYSIZE(_channel); i++)
- _channel[i]->rate(r);
-}
-
-void MidiDriver_YM2612::createLookupTables() {
- {
- int i;
- sintbl = new int [2048];
- for (i = 0; i < 2048; i++)
- sintbl[i] = (int)(0xffff * sin(i/2048.0 * 2.0 * M_PI));
- }
-
- {
- int i;
- powtbl = new int [1025];
- for (i = 0; i <= 1024; i++)
- powtbl[i] = (int)(0x10000 * pow(2.0, (i - 512) / 512.0));
- }
-
- {
- int i;
- int block;
-
- static int fnum[] = {
- 0x026a, 0x028f, 0x02b6, 0x02df,
- 0x030b, 0x0339, 0x036a, 0x039e,
- 0x03d5, 0x0410, 0x044e, 0x048f,
- };
-
- // (int)(880.0 * 256.0 * pow(2.0, (note-0x51)/12.0))
- //
- frequencyTable = new int [120];
- for (block = -1; block < 9; block++) {
- for (i = 0; i < 12; i++) {
- double freq = fnum[i] * (166400.0 / 3) * pow(2.0, block-21);
- frequencyTable[(block+1)*12+i] = (int)(256.0 * freq);
- }
- }
-
- keycodeTable = new int [120];
- // detune
- for (block = -1; block < 9; block++) {
- for (i = 0; i < 12; i++) {
- // see p.204
- int f8 = (fnum[i] >> 7) & 1;
- int f9 = (fnum[i] >> 8) & 1;
- int f10 = (fnum[i] >> 9) & 1;
- int f11 = (fnum[i] >> 10) & 1;
- int n4 = f11;
- int n3 = (f11&(f10|f9|f8)) | (~f11&f10&f9&f8);
- int note = n4*2 + n3;
- // see p.207
- keycodeTable[(block+1)*12+i] = block*4 + note;
- }
- }
- }
-
- {
- int freq;
- keyscaleTable = new int [8192];
- keyscaleTable[0] = 0;
- for (freq = 1; freq < 8192; freq++) {
- keyscaleTable[freq] = (int)(log((double)freq) / 9.03 * 32.0) - 1;
- // 8368[Hz] (o9c)
- }
- }
-
- {
- int i;
- attackOut = new int [1024];
- for (i = 0; i < 1024; i++)
- attackOut[i] = (int)(((0x7fff+0x03a5)*30.0) / (30.0+i)) - 0x03a5;
- }
-}
-
-void MidiDriver_YM2612::removeLookupTables() {
- delete[] sintbl;
- delete[] powtbl;
- delete[] frequencyTable;
- delete[] keycodeTable;
- delete[] keyscaleTable;
- delete[] attackOut;
- sintbl = powtbl = frequencyTable = keycodeTable = keyscaleTable = attackOut = 0;
-}
-
-
-// Plugin interface
-
-class TownsEmuMusicPlugin : public MusicPluginObject {
-public:
- const char *getName() const {
- return _s("FM Towns Emulator");
- }
-
- const char *getId() const {
- return "towns";
- }
-
- MusicDevices getDevices() const;
- Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const;
-};
-
-MusicDevices TownsEmuMusicPlugin::getDevices() const {
- MusicDevices devices;
- devices.push_back(MusicDevice(this, "", MT_TOWNS));
- return devices;
-}
-
-Common::Error TownsEmuMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle) const {
- *mididriver = new MidiDriver_YM2612(g_system->getMixer());
-
- return Common::kNoError;
-}
-
-//#if PLUGIN_ENABLED_DYNAMIC(TOWNS)
- //REGISTER_PLUGIN_DYNAMIC(TOWNS, PLUGIN_TYPE_MUSIC, TownsEmuMusicPlugin);
-//#else
- REGISTER_PLUGIN_STATIC(TOWNS, PLUGIN_TYPE_MUSIC, TownsEmuMusicPlugin);
-//#endif
diff --git a/audio/softsynth/ym2612.h b/audio/softsynth/ym2612.h
deleted file mode 100644
index f652b2d9e4..0000000000
--- a/audio/softsynth/ym2612.h
+++ /dev/null
@@ -1,179 +0,0 @@
-/* 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$
- */
-
-#ifndef SOUND_SOFTSYNTH_Y2612_H
-#define SOUND_SOFTSYNTH_Y2612_H
-
-#include "common/scummsys.h"
-
-#include "audio/softsynth/emumidi.h"
-
-////////////////////////////////////////
-//
-// Class declarations
-//
-////////////////////////////////////////
-
-class Voice2612;
-class Operator2612 {
-protected:
- Voice2612 *_owner;
- enum State { _s_ready, _s_attacking, _s_decaying, _s_sustaining, _s_releasing };
- State _state;
- int32 _currentLevel;
- int _frequency;
- uint32 _phase;
- int _lastOutput;
- int _feedbackLevel;
- int _detune;
- int _multiple;
- int32 _totalLevel;
- int _keyScale;
- int _velocity;
- int _specifiedTotalLevel;
- int _specifiedAttackRate;
- int _specifiedDecayRate;
- int _specifiedSustainLevel;
- int _specifiedSustainRate;
- int _specifiedReleaseRate;
- int _tickCount;
- int _attackTime;
- int32 _decayRate;
- int32 _sustainLevel;
- int32 _sustainRate;
- int32 _releaseRate;
-
-public:
- Operator2612 (Voice2612 *owner);
- ~Operator2612();
- void feedbackLevel(int level);
- void setInstrument(byte const *instrument);
- void velocity(int velo);
- void keyOn();
- void keyOff();
- void frequency(int freq);
- void nextTick(const int *phaseShift, int *outbuf, int buflen);
- bool inUse() { return (_state != _s_ready); }
-};
-
-class Voice2612 {
-public:
- Voice2612 *next;
- uint16 _rate;
-
-protected:
- Operator2612 *_opr[4];
- int _velocity;
- int _control7;
- int _note;
- int _frequencyOffs;
- int _frequency;
- int _algorithm;
-
- int *_buffer;
- int _buflen;
-
-public:
- Voice2612();
- ~Voice2612();
- void setControlParameter(int control, int value);
- void setInstrument(byte const *instrument);
- void velocity(int velo);
- void nextTick(int *outbuf, int buflen);
- void noteOn(int n, int onVelo);
- bool noteOff(int note);
- void pitchBend(int value);
- void recalculateFrequency();
-};
-
-class MidiChannel_YM2612 : public MidiChannel {
-protected:
- uint16 _rate;
- Voice2612 *_voices;
- Voice2612 *_next_voice;
-
-public:
- void removeAllVoices();
- void nextTick(int *outbuf, int buflen);
- void rate(uint16 r);
-
-public:
- MidiChannel_YM2612();
- virtual ~MidiChannel_YM2612();
-
- // MidiChannel interface
- MidiDriver *device() { return 0; }
- byte getNumber() { return 0; }
- void release() { }
- void send(uint32 b) { }
- void noteOff(byte note);
- void noteOn(byte note, byte onVelo);
- void programChange(byte program) { }
- void pitchBend(int16 value);
- void controlChange(byte control, byte value);
- void pitchBendFactor(byte value) { }
- void sysEx_customInstrument(uint32 type, const byte *instr);
-};
-
-class MidiDriver_YM2612 : public MidiDriver_Emulated {
-protected:
- MidiChannel_YM2612 *_channel[16];
-
- int _next_voice;
- int _volume;
-
-protected:
- void nextTick(int16 *buf1, int buflen);
- int volume(int val = -1) { if (val >= 0) _volume = val; return _volume; }
- void rate(uint16 r);
-
- void generateSamples(int16 *buf, int len);
-
-public:
- MidiDriver_YM2612(Audio::Mixer *mixer);
- virtual ~MidiDriver_YM2612();
-
- static void createLookupTables();
- static void removeLookupTables();
-
- int open();
- void close();
- void send(uint32 b);
- void send(byte channel, uint32 b); // Supports higher than channel 15
- uint32 property(int prop, uint32 param) { return 0; }
-
- void setPitchBendRange(byte channel, uint range) { }
- void sysEx(const byte *msg, uint16 length);
-
- MidiChannel *allocateChannel() { return 0; }
- MidiChannel *getPercussionChannel() { return 0; }
-
-
- // AudioStream API
- bool isStereo() const { return true; }
- int getRate() const { return _mixer->getOutputRate(); }
-};
-
-#endif
-
diff --git a/audio/timestamp.cpp b/audio/timestamp.cpp
index cdc5bc3a02..69b47d1628 100644
--- a/audio/timestamp.cpp
+++ b/audio/timestamp.cpp
@@ -18,9 +18,6 @@
* 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$
- *
*/
#include "audio/timestamp.h"
diff --git a/audio/timestamp.h b/audio/timestamp.h
index 4130793fc8..ef095a2106 100644
--- a/audio/timestamp.h
+++ b/audio/timestamp.h
@@ -18,9 +18,6 @@
* 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$
- *
*/
#ifndef SOUND_TIMESTAMP_H