From bee525560e251ba5fb3b6bca03216cf83eea3f10 Mon Sep 17 00:00:00 2001 From: Michael Schwendt Date: Jan 25 2018 13:43:58 +0000 Subject: Merge post-3.9 unbundling of adplug plugin and make it build without touching more than the plugin directory. Use %autosetup. Avoid harmless macro in comment, which is an rpmbuild error now. --- diff --git a/audacious-plugins-3.9-adplug-makefile.patch b/audacious-plugins-3.9-adplug-makefile.patch new file mode 100644 index 0000000..6970638 --- /dev/null +++ b/audacious-plugins-3.9-adplug-makefile.patch @@ -0,0 +1,11 @@ +diff -Naur audacious-plugins-3.9-unbundled-adplug/src/adplug/Makefile audacious-plugins-3.9-unbundled-adplug-makefile/src/adplug/Makefile +--- audacious-plugins-3.9-unbundled-adplug/src/adplug/Makefile 2018-01-25 13:49:54.505875596 +0100 ++++ audacious-plugins-3.9-unbundled-adplug-makefile/src/adplug/Makefile 2018-01-25 14:36:23.593354921 +0100 +@@ -11,5 +11,5 @@ + CFLAGS += ${PLUGIN_CFLAGS} + # FIXME: Turning off warnings for now; this code is awful + CXXFLAGS += ${PLUGIN_CFLAGS} -Wno-sign-compare -Wno-shift-negative-value +-CPPFLAGS += ${PLUGIN_CPPFLAGS} ${ADLIB_CFLAGS} -I../.. +-LIBS += ${ADLIB_LIBS} ++CPPFLAGS += ${PLUGIN_CPPFLAGS} ${ADLIB_CFLAGS} -I../.. `pkg-config --cflags adplug` ++LIBS += ${ADLIB_LIBS} `pkg-config --libs adplug` diff --git a/audacious-plugins-3.9-unbundle-adplug.patch b/audacious-plugins-3.9-unbundle-adplug.patch new file mode 100644 index 0000000..b87ba56 --- /dev/null +++ b/audacious-plugins-3.9-unbundle-adplug.patch @@ -0,0 +1,25845 @@ +diff -Naur audacious-plugins-3.9-orig/src/adplug/adplug-xmms.cc audacious-plugins-3.9/src/adplug/adplug-xmms.cc +--- audacious-plugins-3.9-orig/src/adplug/adplug-xmms.cc 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/adplug-xmms.cc 2018-01-25 13:49:54.559874361 +0100 +@@ -23,24 +23,34 @@ + #include + #include + +-#include "adplug.h" +-#include "emuopl.h" +-#include "silentopl.h" +-#include "players.h" ++#include ++#include ++#include ++#include + + #include + #include + #include + #include ++#include ++ ++#include "adplug-xmms.h" ++ ++#define CFG_ID "AdPlug" + + class AdPlugXMMS : public InputPlugin + { + public: + static const char * const exts[]; ++ static const char * const defaults[]; ++ static const PreferencesWidget widgets[]; ++ static const PluginPreferences prefs; + + static constexpr PluginInfo info = { + N_("AdPlug (AdLib Player)"), +- PACKAGE ++ PACKAGE, ++ nullptr, ++ & prefs + }; + + constexpr AdPlugXMMS () : InputPlugin (info, InputInfo () +@@ -80,12 +90,6 @@ + + /***** Global variables *****/ + +-// Configuration (and defaults) +-static struct { +- int freq = 44100l; +- bool bit16 = true, stereo = false, endless = false; +-} conf; +- + // Player variables + static struct { + CPlayer *p = nullptr; +@@ -126,8 +130,8 @@ + { + CSilentopl tmpopl; + +- CFileProvider fp (file); +- CPlayer *p = CAdPlug::factory (filename, &tmpopl, fp); ++ CFileVFSProvider fp (file); ++ CPlayer *p = CAdPlug::factory (filename, &tmpopl, CAdPlug::players, fp); + + if (! p) + return false; +@@ -153,24 +157,29 @@ + { + dbg_printf ("adplug_play(\"%s\"): ", filename); + ++ bool bit16 = aud_get_bool (CFG_ID, "16bit"); ++ bool stereo = aud_get_bool (CFG_ID, "Stereo"); ++ int freq = aud_get_int (CFG_ID, "Frequency"); ++ bool endless = aud_get_bool (CFG_ID, "Endless"); ++ + // Set XMMS main window information + dbg_printf ("xmms, "); +- int sampsize = (conf.bit16 ? 2 : 1) * (conf.stereo ? 2 : 1); +- set_stream_bitrate (conf.freq * sampsize * 8); ++ int sampsize = (bit16 ? 2 : 1) * (stereo ? 2 : 1); ++ set_stream_bitrate (freq * sampsize * 8); + + // open output plugin + dbg_printf ("open, "); +- open_audio (conf.bit16 ? FORMAT_16 : FORMAT_8, conf.freq, conf.stereo ? 2 : 1); ++ open_audio (bit16 ? FORMAT_16 : FORMAT_8, freq, stereo ? 2 : 1); + +- CEmuopl opl (conf.freq, conf.bit16, conf.stereo); ++ CEmuopl opl (freq, bit16, stereo); + long toadd = 0, i, towrite; + char *sndbuf, *sndbufpos; + bool playing = true; // Song self-end indicator. + + // Try to load module + dbg_printf ("factory, "); +- CFileProvider fp (fd); +- if (!(plr.p = CAdPlug::factory (filename, &opl, fp))) ++ CFileVFSProvider fp (fd); ++ if (!(plr.p = CAdPlug::factory (filename, &opl, CAdPlug::players, fp))) + { + dbg_printf ("error!\n"); + // MessageBox("AdPlug :: Error", "File could not be opened!", "Ok"); +@@ -197,7 +206,7 @@ + + // main playback loop + dbg_printf ("loop.\n"); +- while ((playing || conf.endless)) ++ while ((playing || endless)) + { + if (check_stop ()) + break; +@@ -226,7 +235,7 @@ + { + while (toadd < 0) + { +- toadd += conf.freq; ++ toadd += freq; + playing = plr.p->update (); + if (playing) + time += (int) (1000 / plr.p->getrefresh ()); +@@ -259,8 +268,8 @@ + { + CSilentopl tmpopl; + +- CFileProvider fp (fd); +- CPlayer *p = CAdPlug::factory (filename, &tmpopl, fp); ++ CFileVFSProvider fp (fd); ++ CPlayer *p = CAdPlug::factory (filename, &tmpopl, CAdPlug::players, fp); + + dbg_printf ("adplug_is_our_file(\"%s\"): returned ", filename); + +@@ -277,23 +286,31 @@ + + /***** Configuration file handling *****/ + +-#define CFG_VERSION "AdPlug" +- +-static const char * const adplug_defaults[] = { ++const char * const AdPlugXMMS::defaults[] = { + "16bit", "TRUE", + "Stereo", "FALSE", + "Frequency", "44100", + "Endless", "FALSE", + nullptr}; + ++const PreferencesWidget AdPlugXMMS::widgets[] = { ++ WidgetLabel (N_("Output")), ++ WidgetCheck (N_("16-bit output (if unchecked, output is 8-bit)"), ++ WidgetBool (CFG_ID, "16bit")), ++ WidgetCheck (N_("Duplicate mono output to two channels"), ++ WidgetBool (CFG_ID, "Stereo")), ++ WidgetSpin (N_("Sample rate"), ++ WidgetInt (CFG_ID, "Frequency"), {8000, 192000, 50, N_("Hz")}), ++ WidgetLabel (N_("Miscellaneous")), ++ WidgetCheck (N_("Repeat song in endless loop"), ++ WidgetBool (CFG_ID, "Endless")) ++}; ++ ++const PluginPreferences AdPlugXMMS::prefs = {{widgets}}; ++ + bool AdPlugXMMS::init () + { +- aud_config_set_defaults (CFG_VERSION, adplug_defaults); +- +- conf.bit16 = aud_get_bool (CFG_VERSION, "16bit"); +- conf.stereo = aud_get_bool (CFG_VERSION, "Stereo"); +- conf.freq = aud_get_int (CFG_VERSION, "Frequency"); +- conf.endless = aud_get_bool (CFG_VERSION, "Endless"); ++ aud_config_set_defaults (CFG_ID, defaults); + + // Load database from disk and hand it to AdPlug + dbg_printf ("database"); +@@ -327,9 +344,4 @@ + delete plr.db; + + plr.filename = String (); +- +- aud_set_bool (CFG_VERSION, "16bit", conf.bit16); +- aud_set_bool (CFG_VERSION, "Stereo", conf.stereo); +- aud_set_int (CFG_VERSION, "Frequency", conf.freq); +- aud_set_bool (CFG_VERSION, "Endless", conf.endless); + } +diff -Naur audacious-plugins-3.9-orig/src/adplug/adplug-xmms.h audacious-plugins-3.9/src/adplug/adplug-xmms.h +--- audacious-plugins-3.9-orig/src/adplug/adplug-xmms.h 1970-01-01 01:00:00.000000000 +0100 ++++ audacious-plugins-3.9/src/adplug/adplug-xmms.h 2018-01-25 13:49:54.612873149 +0100 +@@ -0,0 +1,104 @@ ++/* ++ AdPlug/XMMS - AdPlug XMMS Plugin ++ Copyright (C) 2002, 2003 Simon Peter ++ ++ AdPlug/XMMS is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ This plugin 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 ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with this plugin; if not, write to the Free Software ++ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++*/ ++ ++#ifndef ADPLUG_XMMS_H ++#define ADPLUG_XMMS_H ++ ++#include ++#include ++ ++#include ++ ++class vfsistream : public binistream ++{ ++public: ++ vfsistream(VFSFile *fd = nullptr) : ++ fd(fd) {} ++ ++ vfsistream(std::string &file) ++ { ++ if ((own = VFSFile(file.c_str(), "r"))) ++ fd = &own; ++ else ++ err |= NotFound; ++ } ++ ++ Byte getByte() ++ { ++ Byte b = (Byte)-1; ++ if (fd->fread(&b, 1, 1) != 1) ++ err |= Eof; ++ return b; ++ } ++ ++ void seek(long pos, Offset offs = Set) ++ { ++ VFSSeekType wh = (offs == Add) ? VFS_SEEK_CUR : (offs == End) ? VFS_SEEK_END : VFS_SEEK_SET; ++ if (fd->fseek (pos, wh)) ++ err |= Eof; ++ } ++ ++ long pos() ++ { ++ return fd->ftell (); ++ } ++ ++ unsigned long size() ++ { ++ return aud::max(fd->fsize(), (int64_t)0); ++ } ++ ++private: ++ VFSFile *fd = nullptr; ++ VFSFile own; ++}; ++ ++class CFileVFSProvider : public CFileProvider ++{ ++public: ++ CFileVFSProvider(VFSFile &file) : ++ m_file(file) {} ++ ++ binistream *open(std::string filename) const ++ { ++ binistream *f; ++ ++ if (!strcmp(filename.c_str(), m_file.filename()) && !m_file.fseek(0, VFS_SEEK_SET)) ++ f = new vfsistream(&m_file); ++ else ++ f = new vfsistream(filename); ++ ++ if(f->error()) { delete f; return 0; } ++ ++ // Open all files as little endian with IEEE floats by default ++ f->setFlag(binio::BigEndian, false); f->setFlag(binio::FloatIEEE); ++ ++ return f; ++ } ++ ++ void close(binistream *f) const ++ { ++ delete f; ++ } ++ ++private: ++ VFSFile &m_file; ++}; ++ ++#endif +diff -Naur audacious-plugins-3.9-orig/src/adplug/binio/binfile.cc audacious-plugins-3.9/src/adplug/binio/binfile.cc +--- audacious-plugins-3.9-orig/src/adplug/binio/binfile.cc 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/binio/binfile.cc 1970-01-01 01:00:00.000000000 +0100 +@@ -1,247 +0,0 @@ +-/* +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * binfile.h - Binary file I/O +- * Copyright (C) 2002, 2003 Simon Peter +- */ +- +-#include +-#include +- +-#include "binfile.h" +- +-/***** binfbase *****/ +- +-binfbase::binfbase() +- : f(NULL) +-{ +-} +- +-binfbase::~binfbase() +-{ +- if(f != NULL) close(); +-} +- +-void binfbase::close() +-{ +- if(f != NULL) { +- if(fclose(f) == EOF) err |= Fatal; else f = NULL; +- } else +- err |= NotOpen; +-} +- +-void binfbase::seek(long pos, Offset offs) +-{ +- int error = 0; +- +- if(f == NULL) { err |= NotOpen; return; } +- +- switch(offs) { +- case Set: error = fseek(f, pos, SEEK_SET); break; +- case Add: error = fseek(f, pos, SEEK_CUR); break; +- case End: error = fseek(f, pos, SEEK_END); break; +- } +- +- if(error == -1) err |= Fatal; +-} +- +-long binfbase::pos() +-{ +- long pos; +- +- if(f == NULL) { err |= NotOpen; return 0; } +- +- pos = ftell(f); +- +- if(pos == -1) { +- err |= Fatal; +- return 0; +- } else +- return pos; +-} +- +-/***** binifstream *****/ +- +-binifstream::binifstream() +-{ +-} +- +-binifstream::binifstream(const char *filename, const Mode mode) +-{ +- open(filename, mode); +-} +- +-#if BINIO_ENABLE_STRING +-binifstream::binifstream(const std::string &filename, const Mode mode) +-{ +- open(filename, mode); +-} +-#endif +- +-binifstream::~binifstream() +-{ +-} +- +-void binifstream::open(const char *filename, const Mode mode) +-{ +- f = fopen(filename, "rb"); +- +- if(f == NULL) +- switch(errno) { +- case ENOENT: err |= NotFound; break; +- case EACCES: err |= Denied; break; +- default: err |= NotOpen; break; +- } +-} +- +-#if BINIO_ENABLE_STRING +-void binifstream::open(const std::string &filename, const Mode mode) +-{ +- open(filename.c_str(), mode); +-} +-#endif +- +-binifstream::Byte binifstream::getByte() +-{ +- int read; +- +- if(f != NULL) { +- read = fgetc(f); +- if(read == EOF) err |= Eof; +- return (Byte)read; +- } else { +- err |= NotOpen; +- return 0; +- } +-} +- +-/***** binofstream *****/ +- +-binofstream::binofstream() +-{ +-} +- +-binofstream::binofstream(const char *filename, const Mode mode) +-{ +- open(filename, mode); +-} +- +-#if BINIO_ENABLE_STRING +-binofstream::binofstream(const std::string &filename, const Mode mode) +-{ +- open(filename, mode); +-} +-#endif +- +-binofstream::~binofstream() +-{ +-} +- +-void binofstream::open(const char *filename, const Mode mode) +-{ +- const char *modestr = "wb"; +- +- // Check if append mode is desired +- if(mode & Append) modestr = "ab"; +- +- f = fopen(filename, modestr); +- +- if(f == NULL) +- switch(errno) { +- case EEXIST: +- case EACCES: +- case EROFS: +- err |= Denied; +- break; +- case ENOENT: err |= NotFound; break; +- default: err |= NotOpen; break; +- } +-} +- +-#if BINIO_ENABLE_STRING +-void binofstream::open(const std::string &filename, const Mode mode) +-{ +- open(filename.c_str(), mode); +-} +-#endif +- +-void binofstream::putByte(Byte b) +-{ +- if(f == NULL) { err |= NotOpen; return; } +- +- if(fputc(b, f) == EOF) +- err |= Fatal; +-} +- +-/***** binfstream *****/ +- +-binfstream::binfstream() +-{ +-} +- +-binfstream::binfstream(const char *filename, const Mode mode) +-{ +- open(filename, mode); +-} +- +-#if BINIO_ENABLE_STRING +-binfstream::binfstream(const std::string &filename, const Mode mode) +-{ +- open(filename, mode); +-} +-#endif +- +-binfstream::~binfstream() +-{ +-} +- +-void binfstream::open(const char *filename, const Mode mode) +-{ +- char modestr[] = "w+b"; // Create & at beginning +- int ferror = 0; +- +- // Apply desired mode +- if(mode & NoCreate) { +- if(!(mode & Append)) +- modestr[0] = 'r'; // NoCreate & at beginning +- } else +- if(mode & Append) // Create & append +- modestr[0] = 'a'; +- +- f = fopen(filename, modestr); +- +- // NoCreate & append (emulated -- not possible with standard C fopen()) +- if(f != NULL && (mode & Append) && (mode & NoCreate)) +- ferror = fseek(f, 0, SEEK_END); +- +- if(f == NULL || ferror == -1) { +- switch(errno) { +- case EEXIST: +- case EACCES: +- case EROFS: +- err |= Denied; +- break; +- case ENOENT: err |= NotFound; break; +- default: err |= NotOpen; break; +- } +- } +-} +- +-#if BINIO_ENABLE_STRING +-void binfstream::open(const std::string &filename, const Mode mode) +-{ +- open(filename.c_str(), mode); +-} +-#endif +diff -Naur audacious-plugins-3.9-orig/src/adplug/binio/binfile.h audacious-plugins-3.9/src/adplug/binio/binfile.h +--- audacious-plugins-3.9-orig/src/adplug/binio/binfile.h 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/binio/binfile.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,110 +0,0 @@ +-/* +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * binfile.h - Binary file I/O +- * Copyright (C) 2002, 2003 Simon Peter +- */ +- +-#ifndef H_BINIO_BINFILE +-#define H_BINIO_BINFILE +- +-#include +- +-#include "binio.h" +- +-class binfbase: virtual public binio +-{ +-public: +- typedef enum { +- Append = 1 << 0, +- NoCreate = 1 << 1 +- } ModeFlags; +- +- typedef int Mode; +- +- binfbase(); +- virtual ~binfbase(); +- +- virtual void open(const char *filename, const Mode mode) = 0; +-#if BINIO_ENABLE_STRING +- virtual void open(const std::string &filename, const Mode mode) = 0; +-#endif +- void close(); +- +- virtual void seek(long pos, Offset offs = Set); +- virtual long pos(); +- +-protected: +- FILE *f; +-}; +- +-class binifstream: public binistream, virtual public binfbase +-{ +-public: +- binifstream(); +- binifstream(const char *filename, const Mode mode = NoCreate); +-#if BINIO_ENABLE_STRING +- binifstream(const std::string &filename, const Mode mode = NoCreate); +-#endif +- +- virtual ~binifstream(); +- +- virtual void open(const char *filename, const Mode mode = NoCreate); +-#if BINIO_ENABLE_STRING +- virtual void open(const std::string &filename, const Mode mode = NoCreate); +-#endif +- +-protected: +- virtual Byte getByte(); +-}; +- +-class binofstream: public binostream, virtual public binfbase +-{ +-public: +- binofstream(); +- binofstream(const char *filename, const Mode mode = 0); +-#if BINIO_ENABLE_STRING +- binofstream(const std::string &filename, const Mode mode = 0); +-#endif +- +- virtual ~binofstream(); +- +- virtual void open(const char *filename, const Mode mode = 0); +-#if BINIO_ENABLE_STRING +- virtual void open(const std::string &filename, const Mode mode = 0); +-#endif +- +-protected: +- virtual void putByte(Byte b); +-}; +- +-class binfstream: public binifstream, public binofstream +-{ +-public: +- binfstream(); +- binfstream(const char *filename, const Mode mode = 0); +-#if BINIO_ENABLE_STRING +- binfstream(const std::string &filename, const Mode mode = 0); +-#endif +- +- virtual ~binfstream(); +- +- virtual void open(const char *filename, const Mode mode = 0); +-#if BINIO_ENABLE_STRING +- virtual void open(const std::string &filename, const Mode mode = 0); +-#endif +-}; +- +-#endif +diff -Naur audacious-plugins-3.9-orig/src/adplug/binio/binio.cc audacious-plugins-3.9/src/adplug/binio/binio.cc +--- audacious-plugins-3.9-orig/src/adplug/binio/binio.cc 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/binio/binio.cc 1970-01-01 01:00:00.000000000 +0100 +@@ -1,298 +0,0 @@ +-/* +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * binio.cpp - Binary stream I/O classes +- * Copyright (C) 2002, 2003 Simon Peter +- */ +- +-#include +- +-#include "binio.h" +- +-/***** Defines *****/ +- +-#if BINIO_ENABLE_STRING +-// String buffer size for std::string readString() method +-#define STRINGBUFSIZE 256 +-#endif +- +-/***** binio *****/ +- +-#ifdef WORDS_BIGENDIAN +-const binio::Flags binio::system_flags = BigEndian | FloatIEEE; +-#else +-const binio::Flags binio::system_flags = FloatIEEE; +-#endif +- +-binio::binio() +- : my_flags(system_flags), err(NoError) +-{ +-} +- +-binio::~binio() +-{ +-} +- +-void binio::setFlag(Flag f, bool set) +-{ +- if(set) +- my_flags |= f; +- else +- my_flags &= !f; +-} +- +-bool binio::getFlag(Flag f) +-{ +- return (my_flags & f ? true : false); +-} +- +-binio::Error binio::error() +-{ +- Error e = err; +- +- err = NoError; +- return e; +-} +- +-bool binio::eof() +-{ +- return (err & Eof ? true : false); +-} +- +-/***** binistream *****/ +- +-binistream::binistream() +-{ +-} +- +-binistream::~binistream() +-{ +-} +- +-binistream::Int binistream::readInt(unsigned int size) +-{ +- unsigned int i; +- Int val = 0, in; +- +- // Check if 'size' doesn't exceed our system's biggest type. +- if(size > sizeof(Int)) { +- err |= Unsupported; +- return 0; +- } +- +- for(i = 0; i < size; i++) { +- in = getByte(); +- if(getFlag(BigEndian)) +- val <<= 8; +- else +- in <<= i * 8; +- val |= in; +- } +- +- return val; +-} +- +-binistream::Float binistream::readFloat(FType ft) +-{ +- if(getFlag(FloatIEEE)) { // Read IEEE-754 floating-point value +- unsigned int i, size = 0; +- FloatData in; +- bool swap; +- +- // Determine appropriate size for given type. +- switch(ft) { +- case Single: size = 4; break; // 32 bits +- case Double: size = 8; break; // 64 bits +- } +- +- // Determine byte ordering +- swap = getFlag(BigEndian) ^ (system_flags & BigEndian); +- +- // Read the float byte by byte, converting endianess +- for(i = 0; i < size; i++) +- if(swap) +- in.b[size - i - 1] = getByte(); +- else +- in.b[i] = getByte(); +- +- // Let the hardware do the conversion +- switch(ft) { +- case Single: return in.f; +- case Double: return in.d; +- } +- } +- +- // User tried to read a (yet) unsupported floating-point type. Bail out. +- err |= Unsupported; return 0.0; +-} +- +-unsigned long binistream::readString(char *str, unsigned long maxlen) +-{ +- unsigned long i; +- +- for(i = 0; i < maxlen; i++) { +- str[i] = (char)getByte(); +- if(err) { str[i] = '\0'; return i; } +- } +- +- return maxlen; +-} +- +-unsigned long binistream::readString(char *str, unsigned long maxlen, +- const char delim) +-{ +- unsigned long i; +- +- for(i = 0; i < maxlen; i++) { +- str[i] = (char)getByte(); +- if(str[i] == delim || err) { str[i] = '\0'; return i; } +- } +- +- str[maxlen] = '\0'; +- return maxlen; +-} +- +-#if BINIO_ENABLE_STRING +-std::string binistream::readString(const char delim) +-{ +- char buf[STRINGBUFSIZE + 1]; +- std::string tempstr; +- unsigned long read; +- +- do { +- read = readString(buf, STRINGBUFSIZE, delim); +- tempstr.append(buf, read); +- } while(read == STRINGBUFSIZE); +- +- return tempstr; +-} +-#endif +- +-binistream::Int binistream::peekInt(unsigned int size) +-{ +- Int val = readInt(size); +- if(!err) seek(-(long)size, Add); +- return val; +-} +- +-binistream::Float binistream::peekFloat(FType ft) +-{ +- Float val = readFloat(ft); +- +- if(!err) +- switch(ft) { +- case Single: seek(-4, Add); break; +- case Double: seek(-8, Add); break; +- } +- +- return val; +-} +- +-bool binistream::ateof() +-{ +- Error olderr = err; // Save current error state +- bool eof_then; +- +- peekInt(1); +- eof_then = eof(); // Get error state of next byte +- err = olderr; // Restore original error state +- return eof_then; +-} +- +-void binistream::ignore(unsigned long amount) +-{ +- unsigned long i; +- +- for(i = 0; i < amount; i++) +- getByte(); +-} +- +-/***** binostream *****/ +- +-binostream::binostream() +-{ +-} +- +-binostream::~binostream() +-{ +-} +- +-void binostream::writeInt(Int val, unsigned int size) +-{ +- unsigned int i; +- +- // Check if 'size' doesn't exceed our system's biggest type. +- if(size > sizeof(Int)) { err |= Unsupported; return; } +- +- for(i = 0; i < size; i++) { +- if(getFlag(BigEndian)) +- putByte((val >> (size - i - 1) * 8) & 0xff); +- else { +- putByte(val & 0xff); +- val >>= 8; +- } +- } +-} +- +-void binostream::writeFloat(Float f, FType ft) +-{ +- if(getFlag(FloatIEEE)) { // Write IEEE-754 floating-point value +- unsigned int i, size = 0; +- FloatData out; +- bool swap; +- +- // Hardware could be big or little endian, convert appropriately +- swap = getFlag(BigEndian) ^ (system_flags & BigEndian); +- +- // Determine appropriate size for given type and convert by hardware +- switch(ft) { +- case Single: size = 4; out.f = f; break; // 32 bits +- case Double: size = 8; out.d = f; break; // 64 bits +- } +- +- // Write the float byte by byte, converting endianess +- for(i = 0; i < size; i++) +- if(swap) +- putByte(out.b[size - i - 1]); +- else +- putByte(out.b[i]); +- +- return; // We're done. +- } +- +- // User tried to write an unsupported floating-point type. Bail out. +- err |= Unsupported; +-} +- +-unsigned long binostream::writeString(const char *str, unsigned long amount) +-{ +- unsigned int i; +- +- if(!amount) amount = strlen(str); +- +- for(i = 0; i < amount; i++) { +- putByte(str[i]); +- if(err) return i; +- } +- +- return amount; +-} +- +-#if BINIO_ENABLE_STRING +-unsigned long binostream::writeString(const std::string &str) +-{ +- return writeString(str.c_str()); +-} +-#endif +diff -Naur audacious-plugins-3.9-orig/src/adplug/binio/binio.h audacious-plugins-3.9/src/adplug/binio/binio.h +--- audacious-plugins-3.9-orig/src/adplug/binio/binio.h 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/binio/binio.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,137 +0,0 @@ +-/* -*-C++-*- +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * binio.h - Binary stream I/O classes +- * Copyright (C) 2002, 2003 Simon Peter +- */ +- +-#ifndef H_BINIO_BINIO +-#define H_BINIO_BINIO +- +-/***** Configuration *****/ +- +-// BINIO_ENABLE_STRING - Build std::string supporting methods +-// +-// Set to 1 to build std::string supporting methods. You need the STL to +-// do this. +-#define BINIO_ENABLE_STRING 1 +- +-/***** Implementation *****/ +- +-#if BINIO_ENABLE_STRING +-#include +-#endif +- +-class binio +-{ +-public: +- typedef enum { +- BigEndian = 1 << 0, +- FloatIEEE = 1 << 1 +- } Flag; +- +- typedef enum { +- NoError = 0, +- Fatal = 1 << 0, +- Unsupported = 1 << 1, +- NotOpen = 1 << 2, +- Denied = 1 << 3, +- NotFound = 1 << 4, +- Eof = 1 << 5 +- } ErrorCode; +- +- typedef enum { Set, Add, End } Offset; +- typedef enum { Single, Double } FType; +- typedef int Error; +- +- binio(); +- virtual ~binio(); +- +- void setFlag(Flag f, bool set = true); +- bool getFlag(Flag f); +- +- Error error(); +- bool eof(); +- +- virtual void seek(long, Offset = Set) = 0; +- virtual long pos() = 0; +- +-protected: +- typedef long long Int; +- typedef long double Float; +- typedef unsigned char Byte; // has to be unsigned! +- +- typedef int Flags; +- +- Flags my_flags; +- static const Flags system_flags; +- Error err; +- +- union FloatData { +- Byte b[8]; +- double d; +- float f; +- }; +-}; +- +-class binistream: virtual public binio +-{ +-public: +- binistream(); +- virtual ~binistream(); +- +- Int readInt(unsigned int size); +- Float readFloat(FType ft); +- unsigned long readString(char *str, unsigned long amount); +- unsigned long readString(char *str, unsigned long maxlen, const char delim); +-#if BINIO_ENABLE_STRING +- std::string readString(const char delim = '\0'); +-#endif +- +- Int peekInt(unsigned int size); +- Float peekFloat(FType ft); +- +- bool ateof(); +- void ignore(unsigned long amount = 1); +- +-protected: +- virtual Byte getByte() = 0; +-}; +- +-class binostream: virtual public binio +-{ +-public: +- binostream(); +- virtual ~binostream(); +- +- void writeInt(Int val, unsigned int size); +- void writeFloat(Float f, FType ft); +- unsigned long writeString(const char *str, unsigned long amount = 0); +-#if BINIO_ENABLE_STRING +- unsigned long writeString(const std::string &str); +-#endif +- +-protected: +- virtual void putByte(Byte) = 0; +-}; +- +-class binstream: public binistream, public binostream +-{ +-public: +- binstream(); +- virtual ~binstream(); +-}; +- +-#endif +diff -Naur audacious-plugins-3.9-orig/src/adplug/binio/binio_virtual.h audacious-plugins-3.9/src/adplug/binio/binio_virtual.h +--- audacious-plugins-3.9-orig/src/adplug/binio/binio_virtual.h 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/binio/binio_virtual.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,51 +0,0 @@ +-/* +- * Copyright (c) 2006 William Pitcock +- * This code is in the public domain. +- */ +- +-#ifndef __BINIO_VIRTUAL__ +-#define __BINIO_VIRTUAL__ +- +-#include "binio.h" +- +-#include +- +-class vfsistream : public binistream { +-private: +- VFSFile *fd = nullptr; +- VFSFile own; +- +-public: +- vfsistream(VFSFile *fd = nullptr) : +- fd(fd) {} +- +- vfsistream(std::string &file) { +- if ((own = VFSFile(file.c_str(), "r"))) +- fd = &own; +- else +- err |= NotFound; +- } +- +- Byte getByte() { +- Byte b = (Byte)-1; +- if (fd->fread(&b, 1, 1) != 1) +- err |= Eof; +- return b; +- } +- +- void seek(long pos, Offset offs = Set) { +- VFSSeekType wh = (offs == Add) ? VFS_SEEK_CUR : (offs == End) ? VFS_SEEK_END : VFS_SEEK_SET; +- if (fd->fseek (pos, wh)) +- err |= Eof; +- } +- +- long pos() { +- return fd->ftell (); +- } +- +- unsigned long size() { +- return aud::max(fd->fsize(), (int64_t)0); +- } +-}; +- +-#endif +diff -Naur audacious-plugins-3.9-orig/src/adplug/binio/binstr.cc audacious-plugins-3.9/src/adplug/binio/binstr.cc +--- audacious-plugins-3.9-orig/src/adplug/binio/binstr.cc 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/binio/binstr.cc 1970-01-01 01:00:00.000000000 +0100 +@@ -1,114 +0,0 @@ +-/* +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * binstr.cpp - Binary I/O on standard C strings in memory +- * Copyright (C) 2003 Simon Peter +- */ +- +-#include "binstr.h" +- +-/***** binsbase *****/ +- +-binsbase::binsbase(void *str, unsigned long len) +- : data((Byte *)str), spos((Byte *)str), length(len) +-{ +-} +- +-binsbase::~binsbase() +-{ +-} +- +-void binsbase::seek(long p, Offset offs) +-{ +- switch(offs) { +- case Set: spos = data + p; break; +- case Add: spos += p; break; +- case End: spos = data + length - 1 + p; break; +- } +- +- // Seek before start of data +- if(spos < data) { +- err |= Eof; +- spos = data; +- return; +- } +- +- // Seek after end of data +- if(spos - data >= length) { +- err |= Eof; +- spos = data + length - 1; +- } +-} +- +-long binsbase::pos() +-{ +- return (long)(spos - data); +-} +- +-/***** binisstream *****/ +- +-binisstream::binisstream(void *str, unsigned long len) +- : binsbase(str, len) +-{ +-} +- +-binisstream::~binisstream() +-{ +-} +- +-binisstream::Byte binisstream::getByte() +-{ +- Byte in = 0; +- +- if(spos - data >= length) +- err |= Eof; +- else { +- in = *spos; +- spos++; +- } +- +- return in; +-} +- +-/***** binosstream *****/ +- +-binosstream::binosstream(void *str, unsigned long len) +- : binsbase(str, len) +-{ +-} +- +-binosstream::~binosstream() +-{ +-} +- +-void binosstream::putByte(Byte b) +-{ +- *spos = b; +- spos++; +- +- if(spos - data >= length) +- spos = data + length - 1; +-} +- +-/***** binsstream *****/ +- +-binsstream::binsstream(void *str, unsigned long len) +- : binsbase(str, len), binisstream(str, len), binosstream(str, len) +-{ +-} +- +-binsstream::~binsstream() +-{ +-} +diff -Naur audacious-plugins-3.9-orig/src/adplug/binio/binstr.h audacious-plugins-3.9/src/adplug/binio/binstr.h +--- audacious-plugins-3.9-orig/src/adplug/binio/binstr.h 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/binio/binstr.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,66 +0,0 @@ +-/* +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * binstr.h - Binary I/O on standard C strings in memory +- * Copyright (C) 2003 Simon Peter +- */ +- +-#ifndef H_BINIO_BINSTR +-#define H_BINIO_BINSTR +- +-#include "binio.h" +- +-class binsbase: virtual public binio +-{ +-public: +- binsbase(void *str, unsigned long len); +- virtual ~binsbase(); +- +- virtual void seek(long p, Offset offs = Set); +- virtual long pos(); +- +-protected: +- Byte *data, *spos; +- long length; +-}; +- +-class binisstream: public binistream, virtual public binsbase +-{ +-public: +- binisstream(void *str, unsigned long len); +- virtual ~binisstream(); +- +-protected: +- virtual Byte getByte(); +-}; +- +-class binosstream: public binostream, virtual public binsbase +-{ +-public: +- binosstream(void *str, unsigned long len); +- virtual ~binosstream(); +- +-protected: +- virtual void putByte(Byte b); +-}; +- +-class binsstream: public binisstream, public binosstream +-{ +-public: +- binsstream(void *str, unsigned long len); +- virtual ~binsstream(); +-}; +- +-#endif +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/a2m.cc audacious-plugins-3.9/src/adplug/core/a2m.cc +--- audacious-plugins-3.9-orig/src/adplug/core/a2m.cc 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/a2m.cc 1970-01-01 01:00:00.000000000 +0100 +@@ -1,484 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2007 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * a2m.cpp - A2M Loader by Simon Peter +- * +- * NOTES: +- * This loader detects and loads version 1, 4, 5 & 8 files. +- * +- * version 1-4 files: +- * Following commands are ignored: FF1 - FF9, FAx - FEx +- * +- * version 5-8 files: +- * Instrument panning is ignored. Flags byte is ignored. +- * Following commands are ignored: Gxy, Hxy, Kxy - &xy +- */ +- +-#include +-#include "a2m.h" +- +-const unsigned int Ca2mLoader::MAXFREQ = 2000, +-Ca2mLoader::MINCOPY = ADPLUG_A2M_MINCOPY, +-Ca2mLoader::MAXCOPY = ADPLUG_A2M_MAXCOPY, +-Ca2mLoader::COPYRANGES = ADPLUG_A2M_COPYRANGES, +-Ca2mLoader::CODESPERRANGE = ADPLUG_A2M_CODESPERRANGE, +-Ca2mLoader::TERMINATE = 256, +-Ca2mLoader::FIRSTCODE = ADPLUG_A2M_FIRSTCODE, +-Ca2mLoader::MAXCHAR = FIRSTCODE + COPYRANGES * CODESPERRANGE - 1, +-Ca2mLoader::SUCCMAX = MAXCHAR + 1, +-Ca2mLoader::TWICEMAX = ADPLUG_A2M_TWICEMAX, +-Ca2mLoader::ROOT = 1, Ca2mLoader::MAXBUF = 42 * 1024, +-Ca2mLoader::MAXDISTANCE = 21389, Ca2mLoader::MAXSIZE = 21389 + MAXCOPY; +- +-const unsigned short Ca2mLoader::bitvalue[14] = +- {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192}; +- +-const signed short Ca2mLoader::copybits[COPYRANGES] = +- {4, 6, 8, 10, 12, 14}; +- +-const signed short Ca2mLoader::copymin[COPYRANGES] = +- {0, 16, 80, 336, 1360, 5456}; +- +-CPlayer *Ca2mLoader::factory(Copl *newopl) +-{ +- return new Ca2mLoader(newopl); +-} +- +-bool Ca2mLoader::load(const std::string &filename, const CFileProvider &fp) +-{ +- binistream *f = fp.open(filename); if(!f) return false; +- char id[10]; +- int i,j,k,t; +- unsigned int l; +- unsigned char *org = nullptr, *orgptr, flags = 0, numpats, version; +- unsigned long alength; +- unsigned short len[9], *secdata, *secptr; +- const unsigned char convfx[16] = {0,1,2,23,24,3,5,4,6,9,17,13,11,19,7,14}; +- const unsigned char convinf1[16] = {0,1,2,6,7,8,9,4,5,3,10,11,12,13,14,15}; +- const unsigned char newconvfx[] = {0,1,2,3,4,5,6,23,24,21,10,11,17,13,7,19, +- 255,255,22,25,255,15,255,255,255,255,255, +- 255,255,255,255,255,255,255,255,14,255}; +- +- // read header +- f->readString(id, 10); (void)f->readInt(4); +- version = f->readInt(1); numpats = f->readInt(1); +- +- // file validation section +- if(strncmp(id,"_A2module_",10) || (version != 1 && version != 5 && +- version != 4 && version != 8)) { +- fp.close(f); +- return false; +- } +- +- // load, depack & convert section +- nop = numpats; length = 128; restartpos = 0; +- if(version < 5) { +- for(i=0;i<5;i++) len[i] = f->readInt(2); +- t = 9; +- } else { // version >= 5 +- for(i=0;i<9;i++) len[i] = f->readInt(2); +- t = 18; +- } +- +- // block 0 +- secdata = new unsigned short [len[0] / 2]; +- if(version == 1 || version == 5) { +- for(i=0;ireadInt(2); +- org = new unsigned char [MAXBUF]; orgptr = org; +- sixdepak(secdata,org,len[0]); +- } else { +- orgptr = (unsigned char *)secdata; +- for(i=0;ireadInt(1); +- } +- memcpy(songname,orgptr,43); orgptr += 43; +- memcpy(author,orgptr,43); orgptr += 43; +- memcpy(instname,orgptr,250*33); orgptr += 250*33; +- +- for(i=0;i<250;i++) { // instruments +- inst[i].data[0] = *(orgptr+i*13+10); +- inst[i].data[1] = *(orgptr+i*13); +- inst[i].data[2] = *(orgptr+i*13+1); +- inst[i].data[3] = *(orgptr+i*13+4); +- inst[i].data[4] = *(orgptr+i*13+5); +- inst[i].data[5] = *(orgptr+i*13+6); +- inst[i].data[6] = *(orgptr+i*13+7); +- inst[i].data[7] = *(orgptr+i*13+8); +- inst[i].data[8] = *(orgptr+i*13+9); +- inst[i].data[9] = *(orgptr+i*13+2); +- inst[i].data[10] = *(orgptr+i*13+3); +- +- if(version < 5) +- inst[i].misc = *(orgptr+i*13+11); +- else { // version >= 5 -> OPL3 format +- int pan = *(orgptr+i*13+11); +- +- if(pan) +- inst[i].data[0] |= (pan & 3) << 4; // set pan +- else +- inst[i].data[0] |= 48; // enable both speakers +- } +- +- inst[i].slide = *(orgptr+i*13+12); +- } +- +- orgptr += 250*13; +- memcpy(order,orgptr,128); orgptr += 128; +- bpm = *orgptr; orgptr++; +- initspeed = *orgptr; orgptr++; +- if(version >= 5) flags = *orgptr; +- if(version == 1 || version == 5) delete [] org; +- delete [] secdata; +- +- // blocks 1-4 or 1-8 +- alength = len[1]; +- for(i = 0; i < (version < 5 ? numpats / 16 : numpats / 8); i++) +- alength += len[i+2]; +- +- secdata = new unsigned short [alength / 2]; +- if(version == 1 || version == 5) { +- for(l=0;lreadInt(2); +- org = new unsigned char [MAXBUF * (numpats / (version == 1 ? 16 : 8) + 1)]; +- orgptr = org; secptr = secdata; +- orgptr += sixdepak(secptr,orgptr,len[1]); secptr += len[1] / 2; +- if(version == 1) { +- if(numpats > 16) +- { orgptr += sixdepak(secptr,orgptr,len[2]); secptr += len[2] / 2; } +- if(numpats > 32) +- { orgptr += sixdepak(secptr,orgptr,len[3]); secptr += len[3] / 2; } +- if(numpats > 48) +- sixdepak(secptr,orgptr,len[4]); +- } else { +- if(numpats > 8) +- { orgptr += sixdepak(secptr,orgptr,len[2]); secptr += len[2] / 2; } +- if(numpats > 16) +- { orgptr += sixdepak(secptr,orgptr,len[3]); secptr += len[3] / 2; } +- if(numpats > 24) +- { orgptr += sixdepak(secptr,orgptr,len[4]); secptr += len[4] / 2; } +- if(numpats > 32) +- { orgptr += sixdepak(secptr,orgptr,len[5]); secptr += len[5] / 2; } +- if(numpats > 40) +- { orgptr += sixdepak(secptr,orgptr,len[6]); secptr += len[6] / 2; } +- if(numpats > 48) +- { orgptr += sixdepak(secptr,orgptr,len[7]); secptr += len[7] / 2; } +- if(numpats > 56) +- sixdepak(secptr,orgptr,len[8]); +- } +- delete [] secdata; +- } else { +- org = (unsigned char *)secdata; +- for(l=0;lreadInt(1); +- } +- +- if(version < 5) { +- for(i=0;inote = o[0] == 255 ? 127 : o[0]; +- track->inst = o[1]; +- track->command = convfx[o[2]]; +- track->param2 = o[3] & 0x0f; +- if(track->command != 14) +- track->param1 = o[3] >> 4; +- else { +- track->param1 = convinf1[o[3] >> 4]; +- if(track->param1 == 15 && !track->param2) { // convert key-off +- track->command = 8; +- track->param1 = 0; +- track->param2 = 0; +- } +- } +- if(track->command == 14) { +- switch(track->param1) { +- case 2: // convert define waveform +- track->command = 25; +- track->param1 = track->param2; +- track->param2 = 0xf; +- break; +- case 8: // convert volume slide up +- track->command = 26; +- track->param1 = track->param2; +- track->param2 = 0; +- break; +- case 9: // convert volume slide down +- track->command = 26; +- track->param1 = 0; +- break; +- } +- } +- } +- } else { // version >= 5 +- realloc_patterns(64, 64, 18); +- +- for(i=0;inote = o[0] == 255 ? 127 : o[0]; +- track->inst = o[1]; +- track->command = newconvfx[o[2]]; +- track->param1 = o[3] >> 4; +- track->param2 = o[3] & 0x0f; +- +- // Convert '&' command +- if(o[2] == 36) +- switch(track->param1) { +- case 0: // pattern delay (frames) +- track->command = 29; +- track->param1 = 0; +- // param2 already set correctly +- break; +- +- case 1: // pattern delay (rows) +- track->command = 14; +- track->param1 = 8; +- // param2 already set correctly +- break; +- } +- } +- } +- +- init_trackord(); +- +- if(version == 1 || version == 5) +- delete [] org; +- else +- delete [] secdata; +- +- // Process flags +- if(version >= 5) { +- CmodPlayer::flags |= Opl3; // All versions >= 5 are OPL3 +- if(flags & 8) CmodPlayer::flags |= Tremolo; // Tremolo depth +- if(flags & 16) CmodPlayer::flags |= Vibrato; // Vibrato depth +- } +- +- fp.close(f); +- rewind(0); +- return true; +-} +- +-float Ca2mLoader::getrefresh() +-{ +- if(tempo != 18) +- return (float) (tempo); +- else +- return 18.2f; +-} +- +-/*** private methods *************************************/ +- +-void Ca2mLoader::inittree() +-{ +- unsigned short i; +- +- for(i=2;i<=TWICEMAX;i++) { +- dad[i] = i / 2; +- freq[i] = 1; +- } +- +- for(i=1;i<=MAXCHAR;i++) { +- leftc[i] = 2 * i; +- rghtc[i] = 2 * i + 1; +- } +-} +- +-void Ca2mLoader::updatefreq(unsigned short a,unsigned short b) +-{ +- do { +- freq[dad[a]] = freq[a] + freq[b]; +- a = dad[a]; +- if(a != ROOT) { +- if(leftc[dad[a]] == a) +- b = rghtc[dad[a]]; +- else +- b = leftc[dad[a]]; +- } +- } while(a != ROOT); +- +- if(freq[ROOT] == MAXFREQ) +- for(a=1;a<=TWICEMAX;a++) +- freq[a] >>= 1; +-} +- +-void Ca2mLoader::updatemodel(unsigned short code) +-{ +- unsigned short a=code+SUCCMAX,b,c,code1,code2; +- +- freq[a]++; +- if(dad[a] != ROOT) { +- code1 = dad[a]; +- if(leftc[code1] == a) +- updatefreq(a,rghtc[code1]); +- else +- updatefreq(a,leftc[code1]); +- +- do { +- code2 = dad[code1]; +- if(leftc[code2] == code1) +- b = rghtc[code2]; +- else +- b = leftc[code2]; +- +- if(freq[a] > freq[b]) { +- if(leftc[code2] == code1) +- rghtc[code2] = a; +- else +- leftc[code2] = a; +- +- if(leftc[code1] == a) { +- leftc[code1] = b; +- c = rghtc[code1]; +- } else { +- rghtc[code1] = b; +- c = leftc[code1]; +- } +- +- dad[b] = code1; +- dad[a] = code2; +- updatefreq(b,c); +- a = b; +- } +- +- a = dad[a]; +- code1 = dad[a]; +- } while(code1 != ROOT); +- } +-} +- +-unsigned short Ca2mLoader::inputcode(unsigned short bits) +-{ +- unsigned short i,code=0; +- +- for(i=1;i<=bits;i++) { +- if(!ibitcount) { +- if(ibitcount == MAXBUF) +- ibufcount = 0; +- ibitbuffer = wdbuf[ibufcount]; +- ibufcount++; +- ibitcount = 15; +- } else +- ibitcount--; +- +- if(ibitbuffer > 0x7fff) +- code |= bitvalue[i-1]; +- ibitbuffer <<= 1; +- } +- +- return code; +-} +- +-unsigned short Ca2mLoader::uncompress() +-{ +- unsigned short a=1; +- +- do { +- if(!ibitcount) { +- if(ibufcount == MAXBUF) +- ibufcount = 0; +- ibitbuffer = wdbuf[ibufcount]; +- ibufcount++; +- ibitcount = 15; +- } else +- ibitcount--; +- +- if(ibitbuffer > 0x7fff) +- a = rghtc[a]; +- else +- a = leftc[a]; +- ibitbuffer <<= 1; +- } while(a <= MAXCHAR); +- +- a -= SUCCMAX; +- updatemodel(a); +- return a; +-} +- +-void Ca2mLoader::decode() +-{ +- unsigned short i,j,k,t,c,count=0,dist,len,index; +- +- inittree(); +- c = uncompress(); +- +- while(c != TERMINATE) { +- if(c < 256) { +- obuf[obufcount] = (unsigned char)c; +- obufcount++; +- if(obufcount == MAXBUF) { +- output_size = MAXBUF; +- obufcount = 0; +- } +- +- buf[count] = (unsigned char)c; +- count++; +- if(count == MAXSIZE) +- count = 0; +- } else { +- t = c - FIRSTCODE; +- index = t / CODESPERRANGE; +- len = t + MINCOPY - index * CODESPERRANGE; +- dist = inputcode(copybits[index]) + len + copymin[index]; +- +- j = count; +- k = count - dist; +- if(count < dist) +- k += MAXSIZE; +- +- for(i=0;i<=len-1;i++) { +- obuf[obufcount] = buf[k]; +- obufcount++; +- if(obufcount == MAXBUF) { +- output_size = MAXBUF; +- obufcount = 0; +- } +- +- buf[j] = buf[k]; +- j++; k++; +- if(j == MAXSIZE) j = 0; +- if(k == MAXSIZE) k = 0; +- } +- +- count += len; +- if(count >= MAXSIZE) +- count -= MAXSIZE; +- } +- c = uncompress(); +- } +- output_size = obufcount; +-} +- +-unsigned short Ca2mLoader::sixdepak(unsigned short *source, unsigned char *dest, +- unsigned short size) +-{ +- if((unsigned int)size + 4096 > MAXBUF) +- return 0; +- +- buf = new unsigned char [MAXSIZE]; +- input_size = size; +- ibitcount = 0; ibitbuffer = 0; +- obufcount = 0; ibufcount = 0; +- wdbuf = source; obuf = dest; +- +- decode(); +- delete [] buf; +- return output_size; +-} +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/a2m.h audacious-plugins-3.9/src/adplug/core/a2m.h +--- audacious-plugins-3.9-orig/src/adplug/core/a2m.h 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/a2m.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,83 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2007 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * a2m.h - A2M Loader by Simon Peter +- */ +- +-#ifndef H_ADPLUG_A2MLOADER +-#define H_ADPLUG_A2MLOADER +- +-#include "protrack.h" +- +-class Ca2mLoader: public CmodPlayer +-{ +-public: +- static CPlayer *factory(Copl *newopl); +- +- Ca2mLoader(Copl *newopl): CmodPlayer(newopl) +- { } +- +- bool load(const std::string &filename, const CFileProvider &fp); +- float getrefresh(); +- +- std::string gettype() +- { return std::string("AdLib Tracker 2"); } +- std::string gettitle() +- { if(*songname) return std::string(songname,1,*songname); else return std::string(); } +- std::string getauthor() +- { if(*author) return std::string(author,1,*author); else return std::string(); } +- unsigned int getinstruments() +- { return 250; } +- std::string getinstrument(unsigned int n) +- { return std::string(instname[n],1,*instname[n]); } +- +-private: +- +-#define ADPLUG_A2M_COPYRANGES 6 +-#define ADPLUG_A2M_FIRSTCODE 257 +-#define ADPLUG_A2M_MINCOPY 3 +-#define ADPLUG_A2M_MAXCOPY 255 +-#define ADPLUG_A2M_CODESPERRANGE (ADPLUG_A2M_MAXCOPY - ADPLUG_A2M_MINCOPY + 1) +-#define ADPLUG_A2M_MAXCHAR (ADPLUG_A2M_FIRSTCODE + ADPLUG_A2M_COPYRANGES * ADPLUG_A2M_CODESPERRANGE - 1) +-#define ADPLUG_A2M_TWICEMAX (2 * ADPLUG_A2M_MAXCHAR + 1) +- +- static const unsigned int MAXFREQ, MINCOPY, MAXCOPY, COPYRANGES, +- CODESPERRANGE, TERMINATE, FIRSTCODE, MAXCHAR, SUCCMAX, TWICEMAX, ROOT, +- MAXBUF, MAXDISTANCE, MAXSIZE; +- +- static const unsigned short bitvalue[14]; +- static const signed short copybits[ADPLUG_A2M_COPYRANGES], +- copymin[ADPLUG_A2M_COPYRANGES]; +- +- void inittree(); +- void updatefreq(unsigned short a,unsigned short b); +- void updatemodel(unsigned short code); +- unsigned short inputcode(unsigned short bits); +- unsigned short uncompress(); +- void decode(); +- unsigned short sixdepak(unsigned short *source,unsigned char *dest,unsigned short size); +- +- char songname[43], author[43], instname[250][33]; +- +- unsigned short ibitcount, ibitbuffer, ibufcount, obufcount, input_size, +- output_size, leftc[ADPLUG_A2M_MAXCHAR+1], rghtc[ADPLUG_A2M_MAXCHAR+1], +- dad[ADPLUG_A2M_TWICEMAX+1], freq[ADPLUG_A2M_TWICEMAX+1], *wdbuf; +- unsigned char *obuf, *buf; +-}; +- +-#endif +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/adl.cc audacious-plugins-3.9/src/adplug/core/adl.cc +--- audacious-plugins-3.9-orig/src/adplug/core/adl.cc 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/adl.cc 1970-01-01 01:00:00.000000000 +0100 +@@ -1,2439 +0,0 @@ +-/* +- * adl.cpp - ADL player adaption by Simon Peter +- * +- * Original ADL player by Torbjorn Andersson and Johannes Schickel +- * 'lordhoto' of the ScummVM project. +- */ +- +-/* ScummVM - Scumm Interpreter +- * +- * This file is licensed under both GPL and LGPL +- * Copyright (C) 2006 The ScummVM project +- * Copyright (C) 2006 Torbjorn Andersson and Johannes Schickel +- * +- * GPL License +- * +- * 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. +- * +- * LPGL License +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- +- * This library 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 +- * Lesser General Public License for more details. +- +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * $URL: https://svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/engines/kyra/sound_adlib.cpp $ +- * $Id: adl.cpp,v 1.11 2008/02/11 20:18:27 dynamite Exp $ +- * +- */ +- +-#include +-#include +-#include +-#include +- +-#include "adl.h" +-#include "debug.h" +- +-#ifdef ADL_DEBUG +-# define warning(...) AdPlug_LogWrite(__VA_ARGS__); \ +-AdPlug_LogWrite("\n") +- +-# define debugC(i1, i2, ...) AdPlug_LogWrite(__VA_ARGS__); \ +-AdPlug_LogWrite("\n") +-#else +-# define kDebugLevelSound 1 +- +-static inline void warning(const char *str, ...) +-{ +-} +- +-static inline void debugC(int i1, int i2, const char *str, ...) +-{ +-} +-#endif +- +-// #define warning(...) +-// #define debugC(i1, i2, ...) +- +-#define ARRAYSIZE(x) ((int)(sizeof(x) / sizeof(x[0]))) +- +-// Basic Adlib Programming: +-// http://www.gamedev.net/reference/articles/article446.asp +- +-#define CALLBACKS_PER_SECOND 72 +- +-typedef uint8_t uint8; +-typedef int8_t int8; +-typedef uint16_t uint16; +-typedef int16_t int16; +-typedef uint32_t uint32; +-typedef int32_t int32; +-typedef uint8_t byte; +- +-static inline uint16 READ_LE_UINT16(const void *ptr) { +- const byte *b = (const byte *)ptr; +- return (b[1] << 8) + b[0]; +-} +- +-static inline uint16 READ_BE_UINT16(const void *ptr) { +- const byte *b = (const byte *)ptr; +- return (b[0] << 8) + b[1]; +-} +- +-class AdlibDriver { +-public: +- AdlibDriver(Copl *opl); +- ~AdlibDriver(); +- +- int callback(int opcode, ...); +- void callback(); +- +- // AudioStream API +- // int readBuffer(int16 *buffer, const int numSamples) { +- // int32 samplesLeft = numSamples; +- // memset(buffer, 0, sizeof(int16) * numSamples); +- // while (samplesLeft) { +- // if (!_samplesTillCallback) { +- // callback(); +- // _samplesTillCallback = _samplesPerCallback; +- // _samplesTillCallbackRemainder += _samplesPerCallbackRemainder; +- // if (_samplesTillCallbackRemainder >= CALLBACKS_PER_SECOND) { +- // _samplesTillCallback++; +- // _samplesTillCallbackRemainder -= CALLBACKS_PER_SECOND; +- // } +- // } +- +- // int32 render = MIN(samplesLeft, _samplesTillCallback); +- // samplesLeft -= render; +- // _samplesTillCallback -= render; +- // YM3812UpdateOne(_adlib, buffer, render); +- // buffer += render; +- // } +- // return numSamples; +- // } +- +- bool isStereo() const { return false; } +- bool endOfData() const { return false; } +- // int getRate() const { return _mixer->getOutputRate(); } +- +- struct OpcodeEntry { +- typedef int (AdlibDriver::*DriverOpcode)(va_list &list); +- DriverOpcode function; +- const char *name; +- }; +- +- void setupOpcodeList(); +- const OpcodeEntry *_opcodeList; +- int _opcodesEntries; +- +- int snd_ret0x100(va_list &list); +- int snd_ret0x1983(va_list &list); +- int snd_initDriver(va_list &list); +- int snd_deinitDriver(va_list &list); +- int snd_setSoundData(va_list &list); +- int snd_unkOpcode1(va_list &list); +- int snd_startSong(va_list &list); +- int snd_unkOpcode2(va_list &list); +- int snd_unkOpcode3(va_list &list); +- int snd_readByte(va_list &list); +- int snd_writeByte(va_list &list); +- int snd_getSoundTrigger(va_list &list); +- int snd_unkOpcode4(va_list &list); +- int snd_dummy(va_list &list); +- int snd_getNullvar4(va_list &list); +- int snd_setNullvar3(va_list &list); +- int snd_setFlag(va_list &list); +- int snd_clearFlag(va_list &list); +- +- // These variables have not yet been named, but some of them are partly +- // known nevertheless: +- // +- // unk16 - Sound-related. Possibly some sort of pitch bend. +- // unk18 - Sound-effect. Used for secondaryEffect1() +- // unk19 - Sound-effect. Used for secondaryEffect1() +- // unk20 - Sound-effect. Used for secondaryEffect1() +- // unk21 - Sound-effect. Used for secondaryEffect1() +- // unk22 - Sound-effect. Used for secondaryEffect1() +- // unk29 - Sound-effect. Used for primaryEffect1() +- // unk30 - Sound-effect. Used for primaryEffect1() +- // unk31 - Sound-effect. Used for primaryEffect1() +- // unk32 - Sound-effect. Used for primaryEffect2() +- // unk33 - Sound-effect. Used for primaryEffect2() +- // unk34 - Sound-effect. Used for primaryEffect2() +- // unk35 - Sound-effect. Used for primaryEffect2() +- // unk36 - Sound-effect. Used for primaryEffect2() +- // unk37 - Sound-effect. Used for primaryEffect2() +- // unk38 - Sound-effect. Used for primaryEffect2() +- // unk39 - Currently unused, except for updateCallback56() +- // unk40 - Currently unused, except for updateCallback56() +- // unk41 - Sound-effect. Used for primaryEffect2() +- +- struct Channel { +- uint8 opExtraLevel2; +- uint8 *dataptr; +- uint8 duration; +- uint8 repeatCounter; +- int8 baseOctave; +- uint8 priority; +- uint8 dataptrStackPos; +- uint8 *dataptrStack[4]; +- int8 baseNote; +- uint8 unk29; +- uint8 unk31; +- uint16 unk30; +- uint16 unk37; +- uint8 unk33; +- uint8 unk34; +- uint8 unk35; +- uint8 unk36; +- uint8 unk32; +- uint8 unk41; +- uint8 unk38; +- uint8 opExtraLevel1; +- uint8 spacing2; +- uint8 baseFreq; +- uint8 tempo; +- uint8 position; +- uint8 regAx; +- uint8 regBx; +- typedef void (AdlibDriver::*Callback)(Channel&); +- Callback primaryEffect; +- Callback secondaryEffect; +- uint8 fractionalSpacing; +- uint8 opLevel1; +- uint8 opLevel2; +- uint8 opExtraLevel3; +- uint8 twoChan; +- uint8 unk39; +- uint8 unk40; +- uint8 spacing1; +- uint8 durationRandomness; +- uint8 unk19; +- uint8 unk18; +- int8 unk20; +- int8 unk21; +- uint8 unk22; +- uint16 offset; +- uint8 tempoReset; +- uint8 rawNote; +- int8 unk16; +- }; +- +- void primaryEffect1(Channel &channel); +- void primaryEffect2(Channel &channel); +- void secondaryEffect1(Channel &channel); +- +- void resetAdlibState(); +- void writeOPL(byte reg, byte val); +- void initChannel(Channel &channel); +- void noteOff(Channel &channel); +- void unkOutput2(uint8 num); +- +- uint16 getRandomNr(); +- void setupDuration(uint8 duration, Channel &channel); +- +- void setupNote(uint8 rawNote, Channel &channel, bool flag = false); +- void setupInstrument(uint8 regOffset, uint8 *dataptr, Channel &channel); +- void noteOn(Channel &channel); +- +- void adjustVolume(Channel &channel); +- +- uint8 calculateOpLevel1(Channel &channel); +- uint8 calculateOpLevel2(Channel &channel); +- +- uint16 checkValue(int16 val) { +- if (val < 0) +- val = 0; +- else if (val > 0x3F) +- val = 0x3F; +- return val; +- } +- +- // The sound data has at least two lookup tables: +- // +- // * One for programs, starting at offset 0. +- // * One for instruments, starting at offset 500. +- +- uint8 *getProgram(int progId) { +- return _soundData + READ_LE_UINT16(_soundData + 2 * progId); +- } +- +- uint8 *getInstrument(int instrumentId) { +- return _soundData + READ_LE_UINT16(_soundData + 500 + 2 * instrumentId); +- } +- +- void setupPrograms(); +- void executePrograms(); +- +- struct ParserOpcode { +- typedef int (AdlibDriver::*POpcode)(uint8 *&dataptr, Channel &channel, uint8 value); +- POpcode function; +- const char *name; +- }; +- +- void setupParserOpcodeTable(); +- const ParserOpcode *_parserOpcodeTable; +- int _parserOpcodeTableSize; +- +- int update_setRepeat(uint8 *&dataptr, Channel &channel, uint8 value); +- int update_checkRepeat(uint8 *&dataptr, Channel &channel, uint8 value); +- int update_setupProgram(uint8 *&dataptr, Channel &channel, uint8 value); +- int update_setNoteSpacing(uint8 *&dataptr, Channel &channel, uint8 value); +- int update_jump(uint8 *&dataptr, Channel &channel, uint8 value); +- int update_jumpToSubroutine(uint8 *&dataptr, Channel &channel, uint8 value); +- int update_returnFromSubroutine(uint8 *&dataptr, Channel &channel, uint8 value); +- int update_setBaseOctave(uint8 *&dataptr, Channel &channel, uint8 value); +- int update_stopChannel(uint8 *&dataptr, Channel &channel, uint8 value); +- int update_playRest(uint8 *&dataptr, Channel &channel, uint8 value); +- int update_writeAdlib(uint8 *&dataptr, Channel &channel, uint8 value); +- int update_setupNoteAndDuration(uint8 *&dataptr, Channel &channel, uint8 value); +- int update_setBaseNote(uint8 *&dataptr, Channel &channel, uint8 value); +- int update_setupSecondaryEffect1(uint8 *&dataptr, Channel &channel, uint8 value); +- int update_stopOtherChannel(uint8 *&dataptr, Channel &channel, uint8 value); +- int update_waitForEndOfProgram(uint8 *&dataptr, Channel &channel, uint8 value); +- int update_setupInstrument(uint8 *&dataptr, Channel &channel, uint8 value); +- int update_setupPrimaryEffect1(uint8 *&dataptr, Channel &channel, uint8 value); +- int update_removePrimaryEffect1(uint8 *&dataptr, Channel &channel, uint8 value); +- int update_setBaseFreq(uint8 *&dataptr, Channel &channel, uint8 value); +- int update_setupPrimaryEffect2(uint8 *&dataptr, Channel &channel, uint8 value); +- int update_setPriority(uint8 *&dataptr, Channel &channel, uint8 value); +- int updateCallback23(uint8 *&dataptr, Channel &channel, uint8 value); +- int updateCallback24(uint8 *&dataptr, Channel &channel, uint8 value); +- int update_setExtraLevel1(uint8 *&dataptr, Channel &channel, uint8 value); +- int update_setupDuration(uint8 *&dataptr, Channel &channel, uint8 value); +- int update_playNote(uint8 *&dataptr, Channel &channel, uint8 value); +- int update_setFractionalNoteSpacing(uint8 *&dataptr, Channel &channel, uint8 value); +- int update_setTempo(uint8 *&dataptr, Channel &channel, uint8 value); +- int update_removeSecondaryEffect1(uint8 *&dataptr, Channel &channel, uint8 value); +- int update_setChannelTempo(uint8 *&dataptr, Channel &channel, uint8 value); +- int update_setExtraLevel3(uint8 *&dataptr, Channel &channel, uint8 value); +- int update_setExtraLevel2(uint8 *&dataptr, Channel &channel, uint8 value); +- int update_changeExtraLevel2(uint8 *&dataptr, Channel &channel, uint8 value); +- int update_setAMDepth(uint8 *&dataptr, Channel &channel, uint8 value); +- int update_setVibratoDepth(uint8 *&dataptr, Channel &channel, uint8 value); +- int update_changeExtraLevel1(uint8 *&dataptr, Channel &channel, uint8 value); +- int updateCallback38(uint8 *&dataptr, Channel &channel, uint8 value); +- int updateCallback39(uint8 *&dataptr, Channel &channel, uint8 value); +- int update_removePrimaryEffect2(uint8 *&dataptr, Channel &channel, uint8 value); +- int updateCallback41(uint8 *&dataptr, Channel &channel, uint8 value); +- int update_resetToGlobalTempo(uint8 *&dataptr, Channel &channel, uint8 value); +- int update_nop1(uint8 *&dataptr, Channel &channel, uint8 value); +- int update_setDurationRandomness(uint8 *&dataptr, Channel &channel, uint8 value); +- int update_changeChannelTempo(uint8 *&dataptr, Channel &channel, uint8 value); +- int updateCallback46(uint8 *&dataptr, Channel &channel, uint8 value); +- int update_nop2(uint8 *&dataptr, Channel &channel, uint8 value); +- int update_setupRhythmSection(uint8 *&dataptr, Channel &channel, uint8 value); +- int update_playRhythmSection(uint8 *&dataptr, Channel &channel, uint8 value); +- int update_removeRhythmSection(uint8 *&dataptr, Channel &channel, uint8 value); +- int updateCallback51(uint8 *&dataptr, Channel &channel, uint8 value); +- int updateCallback52(uint8 *&dataptr, Channel &channel, uint8 value); +- int updateCallback53(uint8 *&dataptr, Channel &channel, uint8 value); +- int update_setSoundTrigger(uint8 *&dataptr, Channel &channel, uint8 value); +- int update_setTempoReset(uint8 *&dataptr, Channel &channel, uint8 value); +- int updateCallback56(uint8 *&dataptr, Channel &channel, uint8 value); +- +- // These variables have not yet been named, but some of them are partly +- // known nevertheless: +- // +- // _unkValue1 - Unknown. Used for updating _unkValue2 +- // _unkValue2 - Unknown. Used for updating _unkValue4 +- // _unkValue3 - Unknown. Used for updating _unkValue2 +- // _unkValue4 - Unknown. Used for updating _unkValue5 +- // _unkValue5 - Unknown. Used for controlling updateCallback24(). +- // _unkValue6 - Unknown. Rhythm section volume? +- // _unkValue7 - Unknown. Rhythm section volume? +- // _unkValue8 - Unknown. Rhythm section volume? +- // _unkValue9 - Unknown. Rhythm section volume? +- // _unkValue10 - Unknown. Rhythm section volume? +- // _unkValue11 - Unknown. Rhythm section volume? +- // _unkValue12 - Unknown. Rhythm section volume? +- // _unkValue13 - Unknown. Rhythm section volume? +- // _unkValue14 - Unknown. Rhythm section volume? +- // _unkValue15 - Unknown. Rhythm section volume? +- // _unkValue16 - Unknown. Rhythm section volume? +- // _unkValue17 - Unknown. Rhythm section volume? +- // _unkValue18 - Unknown. Rhythm section volume? +- // _unkValue19 - Unknown. Rhythm section volume? +- // _unkValue20 - Unknown. Rhythm section volume? +- // _unkTable[] - Probably frequences for the 12-tone scale. +- // _unkTable2[] - Unknown. Currently only used by updateCallback46() +- // _unkTable2_1[] - One of the tables in _unkTable2[] +- // _unkTable2_2[] - One of the tables in _unkTable2[] +- // _unkTable2_3[] - One of the tables in _unkTable2[] +- +- int32 _samplesPerCallback; +- int32 _samplesPerCallbackRemainder; +- int32 _samplesTillCallback; +- int32 _samplesTillCallbackRemainder; +- +- int _lastProcessed; +- int8 _flagTrigger; +- int _curChannel; +- uint8 _soundTrigger; +- int _soundsPlaying; +- +- uint16 _rnd; +- +- uint8 _unkValue1; +- uint8 _unkValue2; +- uint8 _unkValue3; +- uint8 _unkValue4; +- uint8 _unkValue5; +- uint8 _unkValue6; +- uint8 _unkValue7; +- uint8 _unkValue8; +- uint8 _unkValue9; +- uint8 _unkValue10; +- uint8 _unkValue11; +- uint8 _unkValue12; +- uint8 _unkValue13; +- uint8 _unkValue14; +- uint8 _unkValue15; +- uint8 _unkValue16; +- uint8 _unkValue17; +- uint8 _unkValue18; +- uint8 _unkValue19; +- uint8 _unkValue20; +- +- int _flags; +- +- uint8 *_soundData; +- +- uint8 _soundIdTable[0x10]; +- Channel _channels[10]; +- +- uint8 _vibratoAndAMDepthBits; +- uint8 _rhythmSectionBits; +- +- uint8 _curRegOffset; +- uint8 _tempo; +- +- const uint8 *_tablePtr1; +- const uint8 *_tablePtr2; +- +- static const uint8 _regOffset[]; +- static const uint16 _unkTable[]; +- static const uint8 *_unkTable2[]; +- static const uint8 _unkTable2_1[]; +- static const uint8 _unkTable2_2[]; +- static const uint8 _unkTable2_3[]; +- static const uint8 _unkTables[][32]; +- +- Copl *opl; +-}; +- +-AdlibDriver::AdlibDriver(Copl *newopl) +- : opl(newopl) +-{ +- setupOpcodeList(); +- setupParserOpcodeTable(); +- +- // _mixer = mixer; +- +- _flags = 0; +- // _adlib = makeAdlibOPL(getRate()); +- // assert(_adlib); +- +- memset(_channels, 0, sizeof(_channels)); +- _soundData = 0; +- +- _vibratoAndAMDepthBits = _curRegOffset = 0; +- +- _lastProcessed = _flagTrigger = _curChannel = _rhythmSectionBits = 0; +- _soundsPlaying = 0; +- _rnd = 0x1234; +- +- _tempo = 0; +- _soundTrigger = 0; +- +- _unkValue3 = 0xFF; +- _unkValue1 = _unkValue2 = _unkValue4 = _unkValue5 = 0; +- _unkValue6 = _unkValue7 = _unkValue8 = _unkValue9 = _unkValue10 = 0; +- _unkValue11 = _unkValue12 = _unkValue13 = _unkValue14 = _unkValue15 = +- _unkValue16 = _unkValue17 = _unkValue18 = _unkValue19 = _unkValue20 = 0; +- +- _tablePtr1 = _tablePtr2 = 0; +- +- // _mixer->setupPremix(this); +- +- // _samplesPerCallback = getRate() / CALLBACKS_PER_SECOND; +- // _samplesPerCallbackRemainder = getRate() % CALLBACKS_PER_SECOND; +- _samplesTillCallback = 0; +- _samplesTillCallbackRemainder = 0; +-} +- +-AdlibDriver::~AdlibDriver() { +- // _mixer->setupPremix(0); +- // OPLDestroy(_adlib); +- // _adlib = 0; +-} +- +-int AdlibDriver::callback(int opcode, ...) { +- // lock(); +- if (opcode >= _opcodesEntries || opcode < 0) { +- warning("AdlibDriver: calling unknown opcode '%d'", opcode); +- return 0; +- } +- +- debugC(9, kDebugLevelSound, "Calling opcode '%s' (%d)", _opcodeList[opcode].name, opcode); +- +- va_list args; +- va_start(args, opcode); +- int returnValue = (this->*(_opcodeList[opcode].function))(args); +- va_end(args); +- // unlock(); +- return returnValue; +-} +- +-// Opcodes +- +-int AdlibDriver::snd_ret0x100(va_list &list) { +- return 0x100; +-} +- +-int AdlibDriver::snd_ret0x1983(va_list &list) { +- return 0x1983; +-} +- +-int AdlibDriver::snd_initDriver(va_list &list) { +- _lastProcessed = _soundsPlaying = 0; +- resetAdlibState(); +- return 0; +-} +- +-int AdlibDriver::snd_deinitDriver(va_list &list) { +- resetAdlibState(); +- return 0; +-} +- +-int AdlibDriver::snd_setSoundData(va_list &list) { +- if (_soundData) { +- delete [] _soundData; +- _soundData = 0; +- } +- _soundData = va_arg(list, uint8*); +- return 0; +-} +- +-int AdlibDriver::snd_unkOpcode1(va_list &list) { +- warning("unimplemented snd_unkOpcode1"); +- return 0; +-} +- +-int AdlibDriver::snd_startSong(va_list &list) { +- int songId = va_arg(list, int); +- _flags |= 8; +- _flagTrigger = 1; +- +- uint8 *ptr = getProgram(songId); +- uint8 chan = *ptr; +- +- if ((songId << 1) != 0) { +- if (chan == 9) { +- if (_flags & 2) +- return 0; +- } else { +- if (_flags & 1) +- return 0; +- } +- } +- +- _soundIdTable[_soundsPlaying++] = songId; +- _soundsPlaying &= 0x0F; +- +- return 0; +-} +- +-int AdlibDriver::snd_unkOpcode2(va_list &list) { +- warning("unimplemented snd_unkOpcode2"); +- return 0; +-} +- +-int AdlibDriver::snd_unkOpcode3(va_list &list) { +- int value = va_arg(list, int); +- int loop = value; +- if (value < 0) { +- value = 0; +- loop = 9; +- } +- loop -= value; +- ++loop; +- +- while (loop--) { +- _curChannel = value; +- Channel &channel = _channels[_curChannel]; +- channel.priority = 0; +- channel.dataptr = 0; +- if (value != 9) { +- noteOff(channel); +- } +- ++value; +- } +- +- return 0; +-} +- +-int AdlibDriver::snd_readByte(va_list &list) { +- int a = va_arg(list, int); +- int b = va_arg(list, int); +- uint8 *ptr = getProgram(a) + b; +- return *ptr; +-} +- +-int AdlibDriver::snd_writeByte(va_list &list) { +- int a = va_arg(list, int); +- int b = va_arg(list, int); +- int c = va_arg(list, int); +- uint8 *ptr = getProgram(a) + b; +- uint8 oldValue = *ptr; +- *ptr = (uint8)c; +- return oldValue; +-} +- +-int AdlibDriver::snd_getSoundTrigger(va_list &list) { +- return _soundTrigger; +-} +- +-int AdlibDriver::snd_unkOpcode4(va_list &list) { +- warning("unimplemented snd_unkOpcode4"); +- return 0; +-} +- +-int AdlibDriver::snd_dummy(va_list &list) { +- return 0; +-} +- +-int AdlibDriver::snd_getNullvar4(va_list &list) { +- warning("unimplemented snd_getNullvar4"); +- return 0; +-} +- +-int AdlibDriver::snd_setNullvar3(va_list &list) { +- warning("unimplemented snd_setNullvar3"); +- return 0; +-} +- +-int AdlibDriver::snd_setFlag(va_list &list) { +- int oldFlags = _flags; +- _flags |= va_arg(list, int); +- return oldFlags; +-} +- +-int AdlibDriver::snd_clearFlag(va_list &list) { +- int oldFlags = _flags; +- _flags &= ~(va_arg(list, int)); +- return oldFlags; +-} +- +-// timer callback +- +-void AdlibDriver::callback() { +- // lock(); +- --_flagTrigger; +- if (_flagTrigger < 0) +- _flags &= ~8; +- setupPrograms(); +- executePrograms(); +- +- uint8 temp = _unkValue3; +- _unkValue3 += _tempo; +- if (_unkValue3 < temp) { +- if (!(--_unkValue2)) { +- _unkValue2 = _unkValue1; +- ++_unkValue4; +- } +- } +- // unlock(); +-} +- +-void AdlibDriver::setupPrograms() { +- while (_lastProcessed != _soundsPlaying) { +- uint8 *ptr = getProgram(_soundIdTable[_lastProcessed]); +- uint8 chan = *ptr++; +- uint8 priority = *ptr++; +- +- // Only start this sound if its priority is higher than the one +- // already playing. +- +- Channel &channel = _channels[chan]; +- +- if (priority >= channel.priority) { +- initChannel(channel); +- channel.priority = priority; +- channel.dataptr = ptr; +- channel.tempo = 0xFF; +- channel.position = 0xFF; +- channel.duration = 1; +- unkOutput2(chan); +- } +- +- ++_lastProcessed; +- _lastProcessed &= 0x0F; +- } +-} +- +-// A few words on opcode parsing and timing: +-// +-// First of all, We simulate a timer callback 72 times per second. Each timeout +-// we update each channel that has something to play. +-// +-// Each channel has its own individual tempo, which is added to its position. +-// This will frequently cause the position to "wrap around" but that is +-// intentional. In fact, it's the signal to go ahead and do more stuff with +-// that channel. +-// +-// Each channel also has a duration, indicating how much time is left on the +-// its current task. This duration is decreased by one. As long as it still has +-// not reached zero, the only thing that can happen is that the note is turned +-// off depending on manual or automatic note spacing. Once the duration reaches +-// zero, a new set of musical opcodes are executed. +-// +-// An opcode is one byte, followed by a variable number of parameters. Since +-// most opcodes have at least one one-byte parameter, we read that as well. Any +-// opcode that doesn't have that one parameter is responsible for moving the +-// data pointer back again. +-// +-// If the most significant bit of the opcode is 1, it's a function; call it. +-// The opcode functions return either 0 (continue), 1 (stop) or 2 (stop, and do +-// not run the effects callbacks). +-// +-// If the most significant bit of the opcode is 0, it's a note, and the first +-// parameter is its duration. (There are cases where the duration is modified +-// but that's an exception.) The note opcode is assumed to return 1, and is the +-// last opcode unless its duration is zero. +-// +-// Finally, most of the times that the callback is called, it will invoke the +-// effects callbacks. The final opcode in a set can prevent this, if it's a +-// function and it returns anything other than 1. +- +-void AdlibDriver::executePrograms() { +- // Each channel runs its own program. There are ten channels: One for +- // each Adlib channel (0-8), plus one "control channel" (9) which is +- // the one that tells the other channels what to do. +- +- for (_curChannel = 9; _curChannel >= 0; --_curChannel) { +- int result = 1; +- +- if (!_channels[_curChannel].dataptr) { +- continue; +- } +- +- Channel &channel = _channels[_curChannel]; +- if (_curChannel != 9) { +- _curRegOffset = _regOffset[_curChannel]; +- } +- +- if (channel.tempoReset) { +- channel.tempo = _tempo; +- } +- +- uint8 backup = channel.position; +- channel.position += channel.tempo; +- if (channel.position < backup) { +- if (--channel.duration) { +- if (channel.duration == channel.spacing2) +- noteOff(channel); +- if (channel.duration == channel.spacing1 && _curChannel != 9) +- noteOff(channel); +- } else { +- // An opcode is not allowed to modify its own +- // data pointer except through the 'dataptr' +- // parameter. To enforce that, we have to work +- // on a copy of the data pointer. +- // +- // This fixes a subtle music bug where the +- // wrong music would play when getting the +- // quill in Kyra 1. +- uint8 *dataptr = channel.dataptr; +- while (dataptr) { +- uint8 opcode = *dataptr++; +- uint8 param = *dataptr++; +- +- if (opcode & 0x80) { +- opcode &= 0x7F; +- if (opcode >= _parserOpcodeTableSize) +- opcode = _parserOpcodeTableSize - 1; +- debugC(9, kDebugLevelSound, "Calling opcode '%s' (%d) (channel: %d)", _parserOpcodeTable[opcode].name, opcode, _curChannel); +- result = (this->*(_parserOpcodeTable[opcode].function))(dataptr, channel, param); +- channel.dataptr = dataptr; +- if (result) +- break; +- } else { +- debugC(9, kDebugLevelSound, "Note on opcode 0x%02X (duration: %d) (channel: %d)", opcode, param, _curChannel); +- setupNote(opcode, channel); +- noteOn(channel); +- setupDuration(param, channel); +- if (param) { +- channel.dataptr = dataptr; +- break; +- } +- } +- } +- } +- } +- +- if (result == 1) { +- if (channel.primaryEffect) +- (this->*(channel.primaryEffect))(channel); +- if (channel.secondaryEffect) +- (this->*(channel.secondaryEffect))(channel); +- } +- } +-} +- +-// +- +-void AdlibDriver::resetAdlibState() { +- debugC(9, kDebugLevelSound, "resetAdlibState()"); +- _rnd = 0x1234; +- +- // Authorize the control of the waveforms +- writeOPL(0x01, 0x20); +- +- // Select FM music mode +- writeOPL(0x08, 0x00); +- +- // I would guess the main purpose of this is to turn off the rhythm, +- // thus allowing us to use 9 melodic voices instead of 6. +- writeOPL(0xBD, 0x00); +- +- int loop = 10; +- while (loop--) { +- if (loop != 9) { +- // Silence the channel +- writeOPL(0x40 + _regOffset[loop], 0x3F); +- writeOPL(0x43 + _regOffset[loop], 0x3F); +- } +- initChannel(_channels[loop]); +- } +-} +- +-// Old calling style: output0x388(0xABCD) +-// New calling style: writeOPL(0xAB, 0xCD) +- +-void AdlibDriver::writeOPL(byte reg, byte val) { +- opl->write(reg, val); +-} +- +-void AdlibDriver::initChannel(Channel &channel) { +- debugC(9, kDebugLevelSound, "initChannel(%lu)", (long)(&channel - _channels)); +- memset(&channel.dataptr, 0, sizeof(Channel) - ((char*)&channel.dataptr - (char*)&channel)); +- +- channel.tempo = 0xFF; +- channel.priority = 0; +- // normally here are nullfuncs but we set 0 for now +- channel.primaryEffect = 0; +- channel.secondaryEffect = 0; +- channel.spacing1 = 1; +-} +- +-void AdlibDriver::noteOff(Channel &channel) { +- debugC(9, kDebugLevelSound, "noteOff(%lu)", (long)(&channel - _channels)); +- +- // The control channel has no corresponding Adlib channel +- +- if (_curChannel >= 9) +- return; +- +- // When the rhythm section is enabled, channels 6, 7 and 8 are special. +- +- if (_rhythmSectionBits && _curChannel >= 6) +- return; +- +- // This means the "Key On" bit will always be 0 +- channel.regBx &= 0xDF; +- +- // Octave / F-Number / Key-On +- writeOPL(0xB0 + _curChannel, channel.regBx); +-} +- +-void AdlibDriver::unkOutput2(uint8 chan) { +- debugC(9, kDebugLevelSound, "unkOutput2(%d)", chan); +- +- // The control channel has no corresponding Adlib channel +- +- if (chan >= 9) +- return; +- +- // I believe this has to do with channels 6, 7, and 8 being special +- // when Adlib's rhythm section is enabled. +- +- if (_rhythmSectionBits && chan >= 6) +- return; +- +- uint8 offset = _regOffset[chan]; +- +- // The channel is cleared: First the attack/delay rate, then the +- // sustain level/release rate, and finally the note is turned off. +- +- writeOPL(0x60 + offset, 0xFF); +- writeOPL(0x63 + offset, 0xFF); +- +- writeOPL(0x80 + offset, 0xFF); +- writeOPL(0x83 + offset, 0xFF); +- +- writeOPL(0xB0 + chan, 0x00); +- +- // ...and then the note is turned on again, with whatever value is +- // still lurking in the A0 + chan register, but everything else - +- // including the two most significant frequency bit, and the octave - +- // set to zero. +- // +- // This is very strange behaviour, and causes problems with the ancient +- // FMOPL code we borrowed from AdPlug. I've added a workaround. See +- // fmopl.cpp for more details. +- // +- // More recent versions of the MAME FMOPL don't seem to have this +- // problem, but cannot currently be used because of licensing and +- // performance issues. +- // +- // Ken Silverman's Adlib emulator (which can be found on his Web page - +- // http://www.advsys.net/ken - and as part of AdPlug) also seems to be +- // immune, but is apparently not as feature complete as MAME's. +- +- writeOPL(0xB0 + chan, 0x20); +-} +- +-// I believe this is a random number generator. It actually does seem to +-// generate an even distribution of almost all numbers from 0 through 65535, +-// though in my tests some numbers were never generated. +- +-uint16 AdlibDriver::getRandomNr() { +- _rnd += 0x9248; +- uint16 lowBits = _rnd & 7; +- _rnd >>= 3; +- _rnd |= (lowBits << 13); +- return _rnd; +-} +- +-void AdlibDriver::setupDuration(uint8 duration, Channel &channel) { +- debugC(9, kDebugLevelSound, "setupDuration(%d, %lu)", duration, (long)(&channel - _channels)); +- if (channel.durationRandomness) { +- channel.duration = duration + (getRandomNr() & channel.durationRandomness); +- return; +- } +- if (channel.fractionalSpacing) { +- channel.spacing2 = (duration >> 3) * channel.fractionalSpacing; +- } +- channel.duration = duration; +-} +- +-// This function may or may not play the note. It's usually followed by a call +-// to noteOn(), which will always play the current note. +- +-void AdlibDriver::setupNote(uint8 rawNote, Channel &channel, bool flag) { +- debugC(9, kDebugLevelSound, "setupNote(%d, %lu)", rawNote, (long)(&channel - _channels)); +- +- channel.rawNote = rawNote; +- +- int8 note = (rawNote & 0x0F) + channel.baseNote; +- int8 octave = ((rawNote + channel.baseOctave) >> 4) & 0x0F; +- +- // There are only twelve notes. If we go outside that, we have to +- // adjust the note and octave. +- +- if (note >= 12) { +- note -= 12; +- octave++; +- } else if (note < 0) { +- note += 12; +- octave--; +- } +- +- // The calculation of frequency looks quite different from the original +- // disassembly at a first glance, but when you consider that the +- // largest possible value would be 0x0246 + 0xFF + 0x47 (and that's if +- // baseFreq is unsigned), freq is still a 10-bit value, just as it +- // should be to fit in the Ax and Bx registers. +- // +- // If it were larger than that, it could have overflowed into the +- // octave bits, and that could possibly have been used in some sound. +- // But as it is now, I can't see any way it would happen. +- +- uint16 freq = _unkTable[note] + channel.baseFreq; +- +- // When called from callback 41, the behaviour is slightly different: +- // We adjust the frequency, even when channel.unk16 is 0. +- +- if (channel.unk16 || flag) { +- const uint8 *table; +- +- if (channel.unk16 >= 0) { +- table = _unkTables[(channel.rawNote & 0x0F) + 2]; +- freq += table[channel.unk16]; +- } else { +- table = _unkTables[channel.rawNote & 0x0F]; +- freq -= table[-channel.unk16]; +- } +- } +- +- channel.regAx = freq & 0xFF; +- channel.regBx = (channel.regBx & 0x20) | (octave << 2) | ((freq >> 8) & 0x03); +- +- // Keep the note on or off +- writeOPL(0xA0 + _curChannel, channel.regAx); +- writeOPL(0xB0 + _curChannel, channel.regBx); +-} +- +-void AdlibDriver::setupInstrument(uint8 regOffset, uint8 *dataptr, Channel &channel) { +- debugC(9, kDebugLevelSound, "setupInstrument(%d, %p, %lu)", regOffset, (const void *)dataptr, (long)(&channel - _channels)); +- // Amplitude Modulation / Vibrato / Envelope Generator Type / +- // Keyboard Scaling Rate / Modulator Frequency Multiple +- writeOPL(0x20 + regOffset, *dataptr++); +- writeOPL(0x23 + regOffset, *dataptr++); +- +- uint8 temp = *dataptr++; +- +- // Feedback / Algorithm +- +- // It is very likely that _curChannel really does refer to the same +- // channel as regOffset, but there's only one Cx register per channel. +- +- writeOPL(0xC0 + _curChannel, temp); +- +- // The algorithm bit. I don't pretend to understand this fully, but +- // "If set to 0, operator 1 modulates operator 2. In this case, +- // operator 2 is the only one producing sound. If set to 1, both +- // operators produce sound directly. Complex sounds are more easily +- // created if the algorithm is set to 0." +- +- channel.twoChan = temp & 1; +- +- // Waveform Select +- writeOPL(0xE0 + regOffset, *dataptr++); +- writeOPL(0xE3 + regOffset, *dataptr++); +- +- channel.opLevel1 = *dataptr++; +- channel.opLevel2 = *dataptr++; +- +- // Level Key Scaling / Total Level +- writeOPL(0x40 + regOffset, calculateOpLevel1(channel)); +- writeOPL(0x43 + regOffset, calculateOpLevel2(channel)); +- +- // Attack Rate / Decay Rate +- writeOPL(0x60 + regOffset, *dataptr++); +- writeOPL(0x63 + regOffset, *dataptr++); +- +- // Sustain Level / Release Rate +- writeOPL(0x80 + regOffset, *dataptr++); +- writeOPL(0x83 + regOffset, *dataptr++); +-} +- +-// Apart from playing the note, this function also updates the variables for +-// primary effect 2. +- +-void AdlibDriver::noteOn(Channel &channel) { +- debugC(9, kDebugLevelSound, "noteOn(%lu)", (long)(&channel - _channels)); +- +- // The "note on" bit is set, and the current note is played. +- +- channel.regBx |= 0x20; +- writeOPL(0xB0 + _curChannel, channel.regBx); +- +- int8 shift = 9 - channel.unk33; +- uint16 temp = channel.regAx | (channel.regBx << 8); +- channel.unk37 = ((temp & 0x3FF) >> shift) & 0xFF; +- channel.unk38 = channel.unk36; +-} +- +-void AdlibDriver::adjustVolume(Channel &channel) { +- debugC(9, kDebugLevelSound, "adjustVolume(%lu)", (long)(&channel - _channels)); +- // Level Key Scaling / Total Level +- +- writeOPL(0x43 + _regOffset[_curChannel], calculateOpLevel2(channel)); +- if (channel.twoChan) +- writeOPL(0x40 + _regOffset[_curChannel], calculateOpLevel1(channel)); +-} +- +-// This is presumably only used for some sound effects, e.g. Malcolm blowing up +-// the trees in the intro (but not the effect where he "booby-traps" the big +-// tree) and turning Kallak to stone. Related functions and variables: +-// +-// update_setupPrimaryEffect1() +-// - Initialises unk29, unk30 and unk31 +-// - unk29 is not further modified +-// - unk30 is not further modified, except by update_removePrimaryEffect1() +-// +-// update_removePrimaryEffect1() +-// - Deinitialises unk30 +-// +-// unk29 - determines how often the notes are played +-// unk30 - modifies the frequency +-// unk31 - determines how often the notes are played +- +-void AdlibDriver::primaryEffect1(Channel &channel) { +- debugC(9, kDebugLevelSound, "Calling primaryEffect1 (channel: %d)", _curChannel); +- uint8 temp = channel.unk31; +- channel.unk31 += channel.unk29; +- if (channel.unk31 >= temp) +- return; +- +- // Initialise unk1 to the current frequency +- uint16 unk1 = ((channel.regBx & 3) << 8) | channel.regAx; +- +- // This is presumably to shift the "note on" bit so far to the left +- // that it won't be affected by any of the calculations below. +- uint16 unk2 = ((channel.regBx & 0x20) << 8) | (channel.regBx & 0x1C); +- +- int16 unk3 = (int16)channel.unk30; +- +- if (unk3 >= 0) { +- unk1 += unk3; +- if (unk1 >= 734) { +- // The new frequency is too high. Shift it down and go +- // up one octave. +- unk1 >>= 1; +- if (!(unk1 & 0x3FF)) +- ++unk1; +- unk2 = (unk2 & 0xFF00) | ((unk2 + 4) & 0xFF); +- unk2 &= 0xFF1C; +- } +- } else { +- unk1 += unk3; +- if (unk1 < 388) { +- // The new frequency is too low. Shift it up and go +- // down one octave. +- unk1 <<= 1; +- if (!(unk1 & 0x3FF)) +- --unk1; +- unk2 = (unk2 & 0xFF00) | ((unk2 - 4) & 0xFF); +- unk2 &= 0xFF1C; +- } +- } +- +- // Make sure that the new frequency is still a 10-bit value. +- unk1 &= 0x3FF; +- +- writeOPL(0xA0 + _curChannel, unk1 & 0xFF); +- channel.regAx = unk1 & 0xFF; +- +- // Shift down the "note on" bit again. +- uint8 value = unk1 >> 8; +- value |= (unk2 >> 8) & 0xFF; +- value |= unk2 & 0xFF; +- +- writeOPL(0xB0 + _curChannel, value); +- channel.regBx = value; +-} +- +-// This is presumably only used for some sound effects, e.g. Malcolm entering +-// and leaving Kallak's hut. Related functions and variables: +-// +-// update_setupPrimaryEffect2() +-// - Initialises unk32, unk33, unk34, unk35 and unk36 +-// - unk32 is not further modified +-// - unk33 is not further modified +-// - unk34 is a countdown that gets reinitialised to unk35 on zero +-// - unk35 is based on unk34 and not further modified +-// - unk36 is not further modified +-// +-// noteOn() +-// - Plays the current note +-// - Updates unk37 with a new (lower?) frequency +-// - Copies unk36 to unk38. The unk38 variable is a countdown. +-// +-// unk32 - determines how often the notes are played +-// unk33 - modifies the frequency +-// unk34 - countdown, updates frequency on zero +-// unk35 - initialiser for unk34 countdown +-// unk36 - initialiser for unk38 countdown +-// unk37 - frequency +-// unk38 - countdown, begins playing on zero +-// unk41 - determines how often the notes are played +-// +-// Note that unk41 is never initialised. Not that it should matter much, but it +-// is a bit sloppy. +- +-void AdlibDriver::primaryEffect2(Channel &channel) { +- debugC(9, kDebugLevelSound, "Calling primaryEffect2 (channel: %d)", _curChannel); +- if (channel.unk38) { +- --channel.unk38; +- return; +- } +- +- uint8 temp = channel.unk41; +- channel.unk41 += channel.unk32; +- if (channel.unk41 < temp) { +- uint16 unk1 = channel.unk37; +- if (!(--channel.unk34)) { +- unk1 ^= 0xFFFF; +- ++unk1; +- channel.unk37 = unk1; +- channel.unk34 = channel.unk35; +- } +- +- uint16 unk2 = (channel.regAx | (channel.regBx << 8)) & 0x3FF; +- unk2 += unk1; +- +- channel.regAx = unk2 & 0xFF; +- channel.regBx = (channel.regBx & 0xFC) | (unk2 >> 8); +- +- // Octave / F-Number / Key-On +- writeOPL(0xA0 + _curChannel, channel.regAx); +- writeOPL(0xB0 + _curChannel, channel.regBx); +- } +-} +- +-// I don't know where this is used. The same operation is performed several +-// times on the current channel, using a chunk of the _soundData[] buffer for +-// parameters. The parameters are used starting at the end of the chunk. +-// +-// Since we use _curRegOffset to specify the final register, it's quite +-// unlikely that this function is ever used to play notes. It's probably only +-// used to modify the sound. Another thing that supports this idea is that it +-// can be combined with any of the effects callbacks above. +-// +-// Related functions and variables: +-// +-// update_setupSecondaryEffect1() +-// - Initialies unk18, unk19, unk20, unk21, unk22 and offset +-// - unk19 is not further modified +-// - unk20 is not further modified +-// - unk22 is not further modified +-// - offset is not further modified +-// +-// unk18 - determines how often the operation is performed +-// unk19 - determines how often the operation is performed +-// unk20 - the start index into the data chunk +-// unk21 - the current index into the data chunk +-// unk22 - the operation to perform +-// offset - the offset to the data chunk +- +-void AdlibDriver::secondaryEffect1(Channel &channel) { +- debugC(9, kDebugLevelSound, "Calling secondaryEffect1 (channel: %d)", _curChannel); +- uint8 temp = channel.unk18; +- channel.unk18 += channel.unk19; +- if (channel.unk18 < temp) { +- if (--channel.unk21 < 0) { +- channel.unk21 = channel.unk20; +- } +- writeOPL(channel.unk22 + _curRegOffset, _soundData[channel.offset + channel.unk21]); +- } +-} +- +-uint8 AdlibDriver::calculateOpLevel1(Channel &channel) { +- int8 value = channel.opLevel1 & 0x3F; +- +- if (channel.twoChan) { +- value += channel.opExtraLevel1; +- value += channel.opExtraLevel2; +- value += channel.opExtraLevel3; +- } +- +- // Preserve the scaling level bits from opLevel1 +- +- return checkValue(value) | (channel.opLevel1 & 0xC0); +-} +- +-uint8 AdlibDriver::calculateOpLevel2(Channel &channel) { +- int8 value = channel.opLevel2 & 0x3F; +- +- value += channel.opExtraLevel1; +- value += channel.opExtraLevel2; +- value += channel.opExtraLevel3; +- +- // Preserve the scaling level bits from opLevel2 +- +- return checkValue(value) | (channel.opLevel2 & 0xC0); +-} +- +-// parser opcodes +- +-int AdlibDriver::update_setRepeat(uint8 *&dataptr, Channel &channel, uint8 value) { +- channel.repeatCounter = value; +- return 0; +-} +- +-int AdlibDriver::update_checkRepeat(uint8 *&dataptr, Channel &channel, uint8 value) { +- ++dataptr; +- if (--channel.repeatCounter) { +- int16 add = READ_LE_UINT16(dataptr - 2); +- dataptr += add; +- } +- return 0; +-} +- +-int AdlibDriver::update_setupProgram(uint8 *&dataptr, Channel &channel, uint8 value) { +- if (value == 0xFF) +- return 0; +- +- uint8 *ptr = getProgram(value); +- uint8 chan = *ptr++; +- uint8 priority = *ptr++; +- +- Channel &channel2 = _channels[chan]; +- +- if (priority >= channel2.priority) { +- _flagTrigger = 1; +- _flags |= 8; +- initChannel(channel2); +- channel2.priority = priority; +- channel2.dataptr = ptr; +- channel2.tempo = 0xFF; +- channel2.position = 0xFF; +- channel2.duration = 1; +- unkOutput2(chan); +- } +- +- return 0; +-} +- +-int AdlibDriver::update_setNoteSpacing(uint8 *&dataptr, Channel &channel, uint8 value) { +- channel.spacing1 = value; +- return 0; +-} +- +-int AdlibDriver::update_jump(uint8 *&dataptr, Channel &channel, uint8 value) { +- --dataptr; +- int16 add = READ_LE_UINT16(dataptr); dataptr += 2; +- dataptr += add; +- return 0; +-} +- +-int AdlibDriver::update_jumpToSubroutine(uint8 *&dataptr, Channel &channel, uint8 value) { +- --dataptr; +- int16 add = READ_LE_UINT16(dataptr); dataptr += 2; +- channel.dataptrStack[channel.dataptrStackPos++] = dataptr; +- dataptr += add; +- return 0; +-} +- +-int AdlibDriver::update_returnFromSubroutine(uint8 *&dataptr, Channel &channel, uint8 value) { +- dataptr = channel.dataptrStack[--channel.dataptrStackPos]; +- return 0; +-} +- +-int AdlibDriver::update_setBaseOctave(uint8 *&dataptr, Channel &channel, uint8 value) { +- channel.baseOctave = value; +- return 0; +-} +- +-int AdlibDriver::update_stopChannel(uint8 *&dataptr, Channel &channel, uint8 value) { +- channel.priority = 0; +- if (_curChannel != 9) { +- noteOff(channel); +- } +- dataptr = 0; +- return 2; +-} +- +-int AdlibDriver::update_playRest(uint8 *&dataptr, Channel &channel, uint8 value) { +- setupDuration(value, channel); +- noteOff(channel); +- return (value != 0); +-} +- +-int AdlibDriver::update_writeAdlib(uint8 *&dataptr, Channel &channel, uint8 value) { +- writeOPL(value, *dataptr++); +- return 0; +-} +- +-int AdlibDriver::update_setupNoteAndDuration(uint8 *&dataptr, Channel &channel, uint8 value) { +- setupNote(value, channel); +- value = *dataptr++; +- setupDuration(value, channel); +- return (value != 0); +-} +- +-int AdlibDriver::update_setBaseNote(uint8 *&dataptr, Channel &channel, uint8 value) { +- channel.baseNote = value; +- return 0; +-} +- +-int AdlibDriver::update_setupSecondaryEffect1(uint8 *&dataptr, Channel &channel, uint8 value) { +- channel.unk18 = value; +- channel.unk19 = value; +- channel.unk20 = channel.unk21 = *dataptr++; +- channel.unk22 = *dataptr++; +- channel.offset = READ_LE_UINT16(dataptr); dataptr += 2; +- channel.secondaryEffect = &AdlibDriver::secondaryEffect1; +- return 0; +-} +- +-int AdlibDriver::update_stopOtherChannel(uint8 *&dataptr, Channel &channel, uint8 value) { +- Channel &channel2 = _channels[value]; +- channel2.duration = 0; +- channel2.priority = 0; +- channel2.dataptr = 0; +- return 0; +-} +- +-int AdlibDriver::update_waitForEndOfProgram(uint8 *&dataptr, Channel &channel, uint8 value) { +- uint8 *ptr = getProgram(value); +- uint8 chan = *ptr; +- +- if (!_channels[chan].dataptr) { +- return 0; +- } +- +- dataptr -= 2; +- return 2; +-} +- +-int AdlibDriver::update_setupInstrument(uint8 *&dataptr, Channel &channel, uint8 value) { +- setupInstrument(_curRegOffset, getInstrument(value), channel); +- return 0; +-} +- +-int AdlibDriver::update_setupPrimaryEffect1(uint8 *&dataptr, Channel &channel, uint8 value) { +- channel.unk29 = value; +- channel.unk30 = READ_BE_UINT16(dataptr); +- dataptr += 2; +- channel.primaryEffect = &AdlibDriver::primaryEffect1; +- channel.unk31 = 0xFF; +- return 0; +-} +- +-int AdlibDriver::update_removePrimaryEffect1(uint8 *&dataptr, Channel &channel, uint8 value) { +- --dataptr; +- channel.primaryEffect = 0; +- channel.unk30 = 0; +- return 0; +-} +- +-int AdlibDriver::update_setBaseFreq(uint8 *&dataptr, Channel &channel, uint8 value) { +- channel.baseFreq = value; +- return 0; +-} +- +-int AdlibDriver::update_setupPrimaryEffect2(uint8 *&dataptr, Channel &channel, uint8 value) { +- channel.unk32 = value; +- channel.unk33 = *dataptr++; +- uint8 temp = *dataptr++; +- channel.unk34 = temp + 1; +- channel.unk35 = temp << 1; +- channel.unk36 = *dataptr++; +- channel.primaryEffect = &AdlibDriver::primaryEffect2; +- return 0; +-} +- +-int AdlibDriver::update_setPriority(uint8 *&dataptr, Channel &channel, uint8 value) { +- channel.priority = value; +- return 0; +-} +- +-int AdlibDriver::updateCallback23(uint8 *&dataptr, Channel &channel, uint8 value) { +- value >>= 1; +- _unkValue1 = _unkValue2 = value; +- _unkValue3 = 0xFF; +- _unkValue4 = _unkValue5 = 0; +- return 0; +-} +- +-int AdlibDriver::updateCallback24(uint8 *&dataptr, Channel &channel, uint8 value) { +- if (_unkValue5) { +- if (_unkValue4 & value) { +- _unkValue5 = 0; +- return 0; +- } +- } +- +- if (!(value & _unkValue4)) { +- ++_unkValue5; +- } +- +- dataptr -= 2; +- channel.duration = 1; +- return 2; +-} +- +-int AdlibDriver::update_setExtraLevel1(uint8 *&dataptr, Channel &channel, uint8 value) { +- channel.opExtraLevel1 = value; +- adjustVolume(channel); +- return 0; +-} +- +-int AdlibDriver::update_setupDuration(uint8 *&dataptr, Channel &channel, uint8 value) { +- setupDuration(value, channel); +- return (value != 0); +-} +- +-int AdlibDriver::update_playNote(uint8 *&dataptr, Channel &channel, uint8 value) { +- setupDuration(value, channel); +- noteOn(channel); +- return (value != 0); +-} +- +-int AdlibDriver::update_setFractionalNoteSpacing(uint8 *&dataptr, Channel &channel, uint8 value) { +- channel.fractionalSpacing = value & 7; +- return 0; +-} +- +-int AdlibDriver::update_setTempo(uint8 *&dataptr, Channel &channel, uint8 value) { +- _tempo = value; +- return 0; +-} +- +-int AdlibDriver::update_removeSecondaryEffect1(uint8 *&dataptr, Channel &channel, uint8 value) { +- --dataptr; +- channel.secondaryEffect = 0; +- return 0; +-} +- +-int AdlibDriver::update_setChannelTempo(uint8 *&dataptr, Channel &channel, uint8 value) { +- channel.tempo = value; +- return 0; +-} +- +-int AdlibDriver::update_setExtraLevel3(uint8 *&dataptr, Channel &channel, uint8 value) { +- channel.opExtraLevel3 = value; +- return 0; +-} +- +-int AdlibDriver::update_setExtraLevel2(uint8 *&dataptr, Channel &channel, uint8 value) { +- int channelBackUp = _curChannel; +- +- _curChannel = value; +- Channel &channel2 = _channels[value]; +- channel2.opExtraLevel2 = *dataptr++; +- adjustVolume(channel2); +- +- _curChannel = channelBackUp; +- return 0; +-} +- +-int AdlibDriver::update_changeExtraLevel2(uint8 *&dataptr, Channel &channel, uint8 value) { +- int channelBackUp = _curChannel; +- +- _curChannel = value; +- Channel &channel2 = _channels[value]; +- channel2.opExtraLevel2 += *dataptr++; +- adjustVolume(channel2); +- +- _curChannel = channelBackUp; +- return 0; +-} +- +-// Apart from initialising to zero, these two functions are the only ones that +-// modify _vibratoAndAMDepthBits. +- +-int AdlibDriver::update_setAMDepth(uint8 *&dataptr, Channel &channel, uint8 value) { +- if (value & 1) +- _vibratoAndAMDepthBits |= 0x80; +- else +- _vibratoAndAMDepthBits &= 0x7F; +- +- writeOPL(0xBD, _vibratoAndAMDepthBits); +- return 0; +-} +- +-int AdlibDriver::update_setVibratoDepth(uint8 *&dataptr, Channel &channel, uint8 value) { +- if (value & 1) +- _vibratoAndAMDepthBits |= 0x40; +- else +- _vibratoAndAMDepthBits &= 0xBF; +- +- writeOPL(0xBD, _vibratoAndAMDepthBits); +- return 0; +-} +- +-int AdlibDriver::update_changeExtraLevel1(uint8 *&dataptr, Channel &channel, uint8 value) { +- channel.opExtraLevel1 += value; +- adjustVolume(channel); +- return 0; +-} +- +-int AdlibDriver::updateCallback38(uint8 *&dataptr, Channel &channel, uint8 value) { +- int channelBackUp = _curChannel; +- +- _curChannel = value; +- Channel &channel2 = _channels[value]; +- channel2.duration = channel2.priority = 0; +- channel2.dataptr = 0; +- channel2.opExtraLevel2 = 0; +- +- if (value != 9) { +- uint8 outValue = _regOffset[value]; +- +- // Feedback strength / Connection type +- writeOPL(0xC0 + _curChannel, 0x00); +- +- // Key scaling level / Operator output level +- writeOPL(0x43 + outValue, 0x3F); +- +- // Sustain Level / Release Rate +- writeOPL(0x83 + outValue, 0xFF); +- +- // Key On / Octave / Frequency +- writeOPL(0xB0 + _curChannel, 0x00); +- } +- +- _curChannel = channelBackUp; +- return 0; +-} +- +-int AdlibDriver::updateCallback39(uint8 *&dataptr, Channel &channel, uint8 value) { +- uint16 unk = *dataptr++; +- unk |= value << 8; +- unk &= getRandomNr(); +- +- uint16 unk2 = ((channel.regBx & 0x1F) << 8) | channel.regAx; +- unk2 += unk; +- unk2 |= ((channel.regBx & 0x20) << 8); +- +- // Frequency +- writeOPL(0xA0 + _curChannel, unk2 & 0xFF); +- +- // Key On / Octave / Frequency +- writeOPL(0xB0 + _curChannel, (unk2 & 0xFF00) >> 8); +- +- return 0; +-} +- +-int AdlibDriver::update_removePrimaryEffect2(uint8 *&dataptr, Channel &channel, uint8 value) { +- --dataptr; +- channel.primaryEffect = 0; +- return 0; +-} +- +-int AdlibDriver::updateCallback41(uint8 *&dataptr, Channel &channel, uint8 value) { +- channel.unk16 = value; +- setupNote(channel.rawNote, channel, true); +- return 0; +-} +- +-int AdlibDriver::update_resetToGlobalTempo(uint8 *&dataptr, Channel &channel, uint8 value) { +- --dataptr; +- channel.tempo = _tempo; +- return 0; +-} +- +-int AdlibDriver::update_nop1(uint8 *&dataptr, Channel &channel, uint8 value) { +- --dataptr; +- return 0; +-} +- +-int AdlibDriver::update_setDurationRandomness(uint8 *&dataptr, Channel &channel, uint8 value) { +- channel.durationRandomness = value; +- return 0; +-} +- +-int AdlibDriver::update_changeChannelTempo(uint8 *&dataptr, Channel &channel, uint8 value) { +- int tempo = channel.tempo + (int8)value; +- +- if (tempo <= 0) +- tempo = 1; +- else if (tempo > 255) +- tempo = 255; +- +- channel.tempo = tempo; +- return 0; +-} +- +-int AdlibDriver::updateCallback46(uint8 *&dataptr, Channel &channel, uint8 value) { +- uint8 entry = *dataptr++; +- _tablePtr1 = _unkTable2[entry++]; +- _tablePtr2 = _unkTable2[entry]; +- if (value == 2) { +- // Frequency +- writeOPL(0xA0, _tablePtr2[0]); +- } +- return 0; +-} +- +-// TODO: This is really the same as update_nop1(), so they should be combined +-// into one single update_nop(). +- +-int AdlibDriver::update_nop2(uint8 *&dataptr, Channel &channel, uint8 value) { +- --dataptr; +- return 0; +-} +- +-int AdlibDriver::update_setupRhythmSection(uint8 *&dataptr, Channel &channel, uint8 value) { +- int channelBackUp = _curChannel; +- int regOffsetBackUp = _curRegOffset; +- +- _curChannel = 6; +- _curRegOffset = _regOffset[6]; +- +- setupInstrument(_curRegOffset, getInstrument(value), channel); +- _unkValue6 = channel.opLevel2; +- +- _curChannel = 7; +- _curRegOffset = _regOffset[7]; +- +- setupInstrument(_curRegOffset, getInstrument(*dataptr++), channel); +- _unkValue7 = channel.opLevel1; +- _unkValue8 = channel.opLevel2; +- +- _curChannel = 8; +- _curRegOffset = _regOffset[8]; +- +- setupInstrument(_curRegOffset, getInstrument(*dataptr++), channel); +- _unkValue9 = channel.opLevel1; +- _unkValue10 = channel.opLevel2; +- +- // Octave / F-Number / Key-On for channels 6, 7 and 8 +- +- _channels[6].regBx = *dataptr++ & 0x2F; +- writeOPL(0xB6, _channels[6].regBx); +- writeOPL(0xA6, *dataptr++); +- +- _channels[7].regBx = *dataptr++ & 0x2F; +- writeOPL(0xB7, _channels[7].regBx); +- writeOPL(0xA7, *dataptr++); +- +- _channels[8].regBx = *dataptr++ & 0x2F; +- writeOPL(0xB8, _channels[8].regBx); +- writeOPL(0xA8, *dataptr++); +- +- _rhythmSectionBits = 0x20; +- +- _curRegOffset = regOffsetBackUp; +- _curChannel = channelBackUp; +- return 0; +-} +- +-int AdlibDriver::update_playRhythmSection(uint8 *&dataptr, Channel &channel, uint8 value) { +- // Any instrument that we want to play, and which was already playing, +- // is temporarily keyed off. Instruments that were off already, or +- // which we don't want to play, retain their old on/off status. This is +- // probably so that the instrument's envelope is played from its +- // beginning again... +- +- writeOPL(0xBD, (_rhythmSectionBits & ~(value & 0x1F)) | 0x20); +- +- // ...but since we only set the rhythm instrument bits, and never clear +- // them (until the entire rhythm section is disabled), I'm not sure how +- // useful the cleverness above is. We could perhaps simply turn off all +- // the rhythm instruments instead. +- +- _rhythmSectionBits |= value; +- +- writeOPL(0xBD, _vibratoAndAMDepthBits | 0x20 | _rhythmSectionBits); +- return 0; +-} +- +-int AdlibDriver::update_removeRhythmSection(uint8 *&dataptr, Channel &channel, uint8 value) { +- --dataptr; +- _rhythmSectionBits = 0; +- +- // All the rhythm bits are cleared. The AM and Vibrato depth bits +- // remain unchanged. +- +- writeOPL(0xBD, _vibratoAndAMDepthBits); +- return 0; +-} +- +-int AdlibDriver::updateCallback51(uint8 *&dataptr, Channel &channel, uint8 value) { +- uint8 value2 = *dataptr++; +- +- if (value & 1) { +- _unkValue12 = value2; +- +- // Channel 7, op1: Level Key Scaling / Total Level +- writeOPL(0x51, checkValue(value2 + _unkValue7 + _unkValue11 + _unkValue12)); +- } +- +- if (value & 2) { +- _unkValue14 = value2; +- +- // Channel 8, op2: Level Key Scaling / Total Level +- writeOPL(0x55, checkValue(value2 + _unkValue10 + _unkValue13 + _unkValue14)); +- } +- +- if (value & 4) { +- _unkValue15 = value2; +- +- // Channel 8, op1: Level Key Scaling / Total Level +- writeOPL(0x52, checkValue(value2 + _unkValue9 + _unkValue16 + _unkValue15)); +- } +- +- if (value & 8) { +- _unkValue18 = value2; +- +- // Channel 7, op2: Level Key Scaling / Total Level +- writeOPL(0x54, checkValue(value2 + _unkValue8 + _unkValue17 + _unkValue18)); +- } +- +- if (value & 16) { +- _unkValue20 = value2; +- +- // Channel 6, op2: Level Key Scaling / Total Level +- writeOPL(0x53, checkValue(value2 + _unkValue6 + _unkValue19 + _unkValue20)); +- } +- +- return 0; +-} +- +-int AdlibDriver::updateCallback52(uint8 *&dataptr, Channel &channel, uint8 value) { +- uint8 value2 = *dataptr++; +- +- if (value & 1) { +- _unkValue11 = checkValue(value2 + _unkValue7 + _unkValue11 + _unkValue12); +- +- // Channel 7, op1: Level Key Scaling / Total Level +- writeOPL(0x51, _unkValue11); +- } +- +- if (value & 2) { +- _unkValue13 = checkValue(value2 + _unkValue10 + _unkValue13 + _unkValue14); +- +- // Channel 8, op2: Level Key Scaling / Total Level +- writeOPL(0x55, _unkValue13); +- } +- +- if (value & 4) { +- _unkValue16 = checkValue(value2 + _unkValue9 + _unkValue16 + _unkValue15); +- +- // Channel 8, op1: Level Key Scaling / Total Level +- writeOPL(0x52, _unkValue16); +- } +- +- if (value & 8) { +- _unkValue17 = checkValue(value2 + _unkValue8 + _unkValue17 + _unkValue18); +- +- // Channel 7, op2: Level Key Scaling / Total Level +- writeOPL(0x54, _unkValue17); +- } +- +- if (value & 16) { +- _unkValue19 = checkValue(value2 + _unkValue6 + _unkValue19 + _unkValue20); +- +- // Channel 6, op2: Level Key Scaling / Total Level +- writeOPL(0x53, _unkValue19); +- } +- +- return 0; +-} +- +-int AdlibDriver::updateCallback53(uint8 *&dataptr, Channel &channel, uint8 value) { +- uint8 value2 = *dataptr++; +- +- if (value & 1) { +- _unkValue11 = value2; +- +- // Channel 7, op1: Level Key Scaling / Total Level +- writeOPL(0x51, checkValue(value2 + _unkValue7 + _unkValue12)); +- } +- +- if (value & 2) { +- _unkValue13 = value2; +- +- // Channel 8, op2: Level Key Scaling / Total Level +- writeOPL(0x55, checkValue(value2 + _unkValue10 + _unkValue14)); +- } +- +- if (value & 4) { +- _unkValue16 = value2; +- +- // Channel 8, op1: Level Key Scaling / Total Level +- writeOPL(0x52, checkValue(value2 + _unkValue9 + _unkValue15)); +- } +- +- if (value & 8) { +- _unkValue17 = value2; +- +- // Channel 7, op2: Level Key Scaling / Total Level +- writeOPL(0x54, checkValue(value2 + _unkValue8 + _unkValue18)); +- } +- +- if (value & 16) { +- _unkValue19 = value2; +- +- // Channel 6, op2: Level Key Scaling / Total Level +- writeOPL(0x53, checkValue(value2 + _unkValue6 + _unkValue20)); +- } +- +- return 0; +-} +- +-int AdlibDriver::update_setSoundTrigger(uint8 *&dataptr, Channel &channel, uint8 value) { +- _soundTrigger = value; +- return 0; +-} +- +-int AdlibDriver::update_setTempoReset(uint8 *&dataptr, Channel &channel, uint8 value) { +- channel.tempoReset = value; +- return 0; +-} +- +-int AdlibDriver::updateCallback56(uint8 *&dataptr, Channel &channel, uint8 value) { +- channel.unk39 = value; +- channel.unk40 = *dataptr++; +- return 0; +-} +- +-// static res +- +-#define COMMAND(x) { &AdlibDriver::x, #x } +- +-void AdlibDriver::setupOpcodeList() { +- static const OpcodeEntry opcodeList[] = { +- COMMAND(snd_ret0x100), +- COMMAND(snd_ret0x1983), +- COMMAND(snd_initDriver), +- COMMAND(snd_deinitDriver), +- COMMAND(snd_setSoundData), +- COMMAND(snd_unkOpcode1), +- COMMAND(snd_startSong), +- COMMAND(snd_unkOpcode2), +- COMMAND(snd_unkOpcode3), +- COMMAND(snd_readByte), +- COMMAND(snd_writeByte), +- COMMAND(snd_getSoundTrigger), +- COMMAND(snd_unkOpcode4), +- COMMAND(snd_dummy), +- COMMAND(snd_getNullvar4), +- COMMAND(snd_setNullvar3), +- COMMAND(snd_setFlag), +- COMMAND(snd_clearFlag) +- }; +- +- _opcodeList = opcodeList; +- _opcodesEntries = ARRAYSIZE(opcodeList); +-} +- +-void AdlibDriver::setupParserOpcodeTable() { +- static const ParserOpcode parserOpcodeTable[] = { +- // 0 +- COMMAND(update_setRepeat), +- COMMAND(update_checkRepeat), +- COMMAND(update_setupProgram), +- COMMAND(update_setNoteSpacing), +- +- // 4 +- COMMAND(update_jump), +- COMMAND(update_jumpToSubroutine), +- COMMAND(update_returnFromSubroutine), +- COMMAND(update_setBaseOctave), +- +- // 8 +- COMMAND(update_stopChannel), +- COMMAND(update_playRest), +- COMMAND(update_writeAdlib), +- COMMAND(update_setupNoteAndDuration), +- +- // 12 +- COMMAND(update_setBaseNote), +- COMMAND(update_setupSecondaryEffect1), +- COMMAND(update_stopOtherChannel), +- COMMAND(update_waitForEndOfProgram), +- +- // 16 +- COMMAND(update_setupInstrument), +- COMMAND(update_setupPrimaryEffect1), +- COMMAND(update_removePrimaryEffect1), +- COMMAND(update_setBaseFreq), +- +- // 20 +- COMMAND(update_stopChannel), +- COMMAND(update_setupPrimaryEffect2), +- COMMAND(update_stopChannel), +- COMMAND(update_stopChannel), +- +- // 24 +- COMMAND(update_stopChannel), +- COMMAND(update_stopChannel), +- COMMAND(update_setPriority), +- COMMAND(update_stopChannel), +- +- // 28 +- COMMAND(updateCallback23), +- COMMAND(updateCallback24), +- COMMAND(update_setExtraLevel1), +- COMMAND(update_stopChannel), +- +- // 32 +- COMMAND(update_setupDuration), +- COMMAND(update_playNote), +- COMMAND(update_stopChannel), +- COMMAND(update_stopChannel), +- +- // 36 +- COMMAND(update_setFractionalNoteSpacing), +- COMMAND(update_stopChannel), +- COMMAND(update_setTempo), +- COMMAND(update_removeSecondaryEffect1), +- +- // 40 +- COMMAND(update_stopChannel), +- COMMAND(update_setChannelTempo), +- COMMAND(update_stopChannel), +- COMMAND(update_setExtraLevel3), +- +- // 44 +- COMMAND(update_setExtraLevel2), +- COMMAND(update_changeExtraLevel2), +- COMMAND(update_setAMDepth), +- COMMAND(update_setVibratoDepth), +- +- // 48 +- COMMAND(update_changeExtraLevel1), +- COMMAND(update_stopChannel), +- COMMAND(update_stopChannel), +- COMMAND(updateCallback38), +- +- // 52 +- COMMAND(update_stopChannel), +- COMMAND(updateCallback39), +- COMMAND(update_removePrimaryEffect2), +- COMMAND(update_stopChannel), +- +- // 56 +- COMMAND(update_stopChannel), +- COMMAND(updateCallback41), +- COMMAND(update_resetToGlobalTempo), +- COMMAND(update_nop1), +- +- // 60 +- COMMAND(update_setDurationRandomness), +- COMMAND(update_changeChannelTempo), +- COMMAND(update_stopChannel), +- COMMAND(updateCallback46), +- +- // 64 +- COMMAND(update_nop2), +- COMMAND(update_setupRhythmSection), +- COMMAND(update_playRhythmSection), +- COMMAND(update_removeRhythmSection), +- +- // 68 +- COMMAND(updateCallback51), +- COMMAND(updateCallback52), +- COMMAND(updateCallback53), +- COMMAND(update_setSoundTrigger), +- +- // 72 +- COMMAND(update_setTempoReset), +- COMMAND(updateCallback56), +- COMMAND(update_stopChannel) +- }; +- +- _parserOpcodeTable = parserOpcodeTable; +- _parserOpcodeTableSize = ARRAYSIZE(parserOpcodeTable); +-} +-#undef COMMAND +- +-// This table holds the register offset for operator 1 for each of the nine +-// channels. To get the register offset for operator 2, simply add 3. +- +-const uint8 AdlibDriver::_regOffset[] = { +- 0x00, 0x01, 0x02, 0x08, 0x09, 0x0A, 0x10, 0x11, +- 0x12 +-}; +- +-// Given the size of this table, and the range of its values, it's probably the +-// F-Numbers (10 bits) for the notes of the 12-tone scale. However, it does not +-// match the table in the Adlib documentation I've seen. +- +-const uint16 AdlibDriver::_unkTable[] = { +- 0x0134, 0x0147, 0x015A, 0x016F, 0x0184, 0x019C, 0x01B4, 0x01CE, 0x01E9, +- 0x0207, 0x0225, 0x0246 +-}; +- +-// These tables are currently only used by updateCallback46(), which only ever +-// uses the first element of one of the sub-tables. +- +-const uint8 *AdlibDriver::_unkTable2[] = { +- AdlibDriver::_unkTable2_1, +- AdlibDriver::_unkTable2_2, +- AdlibDriver::_unkTable2_1, +- AdlibDriver::_unkTable2_2, +- AdlibDriver::_unkTable2_3, +- AdlibDriver::_unkTable2_2 +-}; +- +-const uint8 AdlibDriver::_unkTable2_1[] = { +- 0x50, 0x50, 0x4F, 0x4F, 0x4E, 0x4E, 0x4D, 0x4D, +- 0x4C, 0x4C, 0x4B, 0x4B, 0x4A, 0x4A, 0x49, 0x49, +- 0x48, 0x48, 0x47, 0x47, 0x46, 0x46, 0x45, 0x45, +- 0x44, 0x44, 0x43, 0x43, 0x42, 0x42, 0x41, 0x41, +- 0x40, 0x40, 0x3F, 0x3F, 0x3E, 0x3E, 0x3D, 0x3D, +- 0x3C, 0x3C, 0x3B, 0x3B, 0x3A, 0x3A, 0x39, 0x39, +- 0x38, 0x38, 0x37, 0x37, 0x36, 0x36, 0x35, 0x35, +- 0x34, 0x34, 0x33, 0x33, 0x32, 0x32, 0x31, 0x31, +- 0x30, 0x30, 0x2F, 0x2F, 0x2E, 0x2E, 0x2D, 0x2D, +- 0x2C, 0x2C, 0x2B, 0x2B, 0x2A, 0x2A, 0x29, 0x29, +- 0x28, 0x28, 0x27, 0x27, 0x26, 0x26, 0x25, 0x25, +- 0x24, 0x24, 0x23, 0x23, 0x22, 0x22, 0x21, 0x21, +- 0x20, 0x20, 0x1F, 0x1F, 0x1E, 0x1E, 0x1D, 0x1D, +- 0x1C, 0x1C, 0x1B, 0x1B, 0x1A, 0x1A, 0x19, 0x19, +- 0x18, 0x18, 0x17, 0x17, 0x16, 0x16, 0x15, 0x15, +- 0x14, 0x14, 0x13, 0x13, 0x12, 0x12, 0x11, 0x11, +- 0x10, 0x10 +-}; +- +-// no don't ask me WHY this table exsits! +-const uint8 AdlibDriver::_unkTable2_2[] = { +- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, +- 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, +- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, +- 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, +- 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, +- 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, +- 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, +- 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, +- 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, +- 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, +- 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, +- 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x6F, +- 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, +- 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, +- 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, +- 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F +-}; +- +-const uint8 AdlibDriver::_unkTable2_3[] = { +- 0x40, 0x40, 0x40, 0x3F, 0x3F, 0x3F, 0x3E, 0x3E, +- 0x3E, 0x3D, 0x3D, 0x3D, 0x3C, 0x3C, 0x3C, 0x3B, +- 0x3B, 0x3B, 0x3A, 0x3A, 0x3A, 0x39, 0x39, 0x39, +- 0x38, 0x38, 0x38, 0x37, 0x37, 0x37, 0x36, 0x36, +- 0x36, 0x35, 0x35, 0x35, 0x34, 0x34, 0x34, 0x33, +- 0x33, 0x33, 0x32, 0x32, 0x32, 0x31, 0x31, 0x31, +- 0x30, 0x30, 0x30, 0x2F, 0x2F, 0x2F, 0x2E, 0x2E, +- 0x2E, 0x2D, 0x2D, 0x2D, 0x2C, 0x2C, 0x2C, 0x2B, +- 0x2B, 0x2B, 0x2A, 0x2A, 0x2A, 0x29, 0x29, 0x29, +- 0x28, 0x28, 0x28, 0x27, 0x27, 0x27, 0x26, 0x26, +- 0x26, 0x25, 0x25, 0x25, 0x24, 0x24, 0x24, 0x23, +- 0x23, 0x23, 0x22, 0x22, 0x22, 0x21, 0x21, 0x21, +- 0x20, 0x20, 0x20, 0x1F, 0x1F, 0x1F, 0x1E, 0x1E, +- 0x1E, 0x1D, 0x1D, 0x1D, 0x1C, 0x1C, 0x1C, 0x1B, +- 0x1B, 0x1B, 0x1A, 0x1A, 0x1A, 0x19, 0x19, 0x19, +- 0x18, 0x18, 0x18, 0x17, 0x17, 0x17, 0x16, 0x16, +- 0x16, 0x15 +-}; +- +-// This table is used to modify the frequency of the notes, depending on the +-// note value and unk16. In theory, we could very well try to access memory +-// outside this table, but in reality that probably won't happen. +-// +-// This could be some sort of pitch bend, but I have yet to see it used for +-// anything so it's hard to say. +- +-const uint8 AdlibDriver::_unkTables[][32] = { +- // 0 +- { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x08, +- 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, +- 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x19, +- 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21 }, +- // 1 +- { 0x00, 0x01, 0x02, 0x03, 0x04, 0x06, 0x07, 0x09, +- 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, +- 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x1A, +- 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x22, 0x24 }, +- // 2 +- { 0x00, 0x01, 0x02, 0x03, 0x04, 0x06, 0x08, 0x09, +- 0x0A, 0x0C, 0x0D, 0x0E, 0x0F, 0x11, 0x12, 0x13, +- 0x14, 0x15, 0x16, 0x17, 0x19, 0x1A, 0x1C, 0x1D, +- 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x24, 0x25, 0x26 }, +- // 3 +- { 0x00, 0x01, 0x02, 0x03, 0x04, 0x06, 0x08, 0x0A, +- 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x11, 0x12, 0x13, +- 0x14, 0x15, 0x16, 0x17, 0x18, 0x1A, 0x1C, 0x1D, +- 0x1E, 0x1F, 0x20, 0x21, 0x23, 0x25, 0x27, 0x28 }, +- // 4 +- { 0x00, 0x01, 0x02, 0x03, 0x04, 0x06, 0x08, 0x0A, +- 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x11, 0x13, 0x15, +- 0x16, 0x17, 0x18, 0x19, 0x1B, 0x1D, 0x1F, 0x20, +- 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x28, 0x2A }, +- // 5 +- { 0x00, 0x01, 0x02, 0x03, 0x05, 0x07, 0x09, 0x0B, +- 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x13, 0x15, +- 0x16, 0x17, 0x18, 0x19, 0x1B, 0x1D, 0x1F, 0x20, +- 0x21, 0x22, 0x23, 0x25, 0x27, 0x29, 0x2B, 0x2D }, +- // 6 +- { 0x00, 0x01, 0x02, 0x03, 0x05, 0x07, 0x09, 0x0B, +- 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x13, 0x15, +- 0x16, 0x17, 0x18, 0x1A, 0x1C, 0x1E, 0x21, 0x24, +- 0x25, 0x26, 0x27, 0x29, 0x2B, 0x2D, 0x2F, 0x30 }, +- // 7 +- { 0x00, 0x01, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, +- 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x13, 0x15, 0x18, +- 0x19, 0x1A, 0x1C, 0x1D, 0x1F, 0x21, 0x23, 0x25, +- 0x26, 0x27, 0x29, 0x2B, 0x2D, 0x2F, 0x30, 0x32 }, +- // 8 +- { 0x00, 0x01, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0D, +- 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x14, 0x17, 0x1A, +- 0x19, 0x1A, 0x1C, 0x1E, 0x20, 0x22, 0x25, 0x28, +- 0x29, 0x2A, 0x2B, 0x2D, 0x2F, 0x31, 0x33, 0x35 }, +- // 9 +- { 0x00, 0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0E, +- 0x0F, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1B, +- 0x1C, 0x1D, 0x1E, 0x20, 0x22, 0x24, 0x26, 0x29, +- 0x2A, 0x2C, 0x2E, 0x30, 0x32, 0x34, 0x36, 0x39 }, +- // 10 +- { 0x00, 0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0E, +- 0x0F, 0x10, 0x12, 0x14, 0x16, 0x19, 0x1B, 0x1E, +- 0x1F, 0x21, 0x23, 0x25, 0x27, 0x29, 0x2B, 0x2D, +- 0x2E, 0x2F, 0x31, 0x32, 0x34, 0x36, 0x39, 0x3C }, +- // 11 +- { 0x00, 0x01, 0x03, 0x05, 0x07, 0x0A, 0x0C, 0x0F, +- 0x10, 0x11, 0x13, 0x15, 0x17, 0x19, 0x1B, 0x1E, +- 0x1F, 0x20, 0x22, 0x24, 0x26, 0x28, 0x2B, 0x2E, +- 0x2F, 0x30, 0x32, 0x34, 0x36, 0x39, 0x3C, 0x3F }, +- // 12 +- { 0x00, 0x02, 0x04, 0x06, 0x08, 0x0B, 0x0D, 0x10, +- 0x11, 0x12, 0x14, 0x16, 0x18, 0x1B, 0x1E, 0x21, +- 0x22, 0x23, 0x25, 0x27, 0x29, 0x2C, 0x2F, 0x32, +- 0x33, 0x34, 0x36, 0x38, 0x3B, 0x34, 0x41, 0x44 }, +- // 13 +- { 0x00, 0x02, 0x04, 0x06, 0x08, 0x0B, 0x0D, 0x11, +- 0x12, 0x13, 0x15, 0x17, 0x1A, 0x1D, 0x20, 0x23, +- 0x24, 0x25, 0x27, 0x29, 0x2C, 0x2F, 0x32, 0x35, +- 0x36, 0x37, 0x39, 0x3B, 0x3E, 0x41, 0x44, 0x47 } +-}; +- +-// #pragma mark - +- +-// At the time of writing, the only known case where Kyra 1 uses sound triggers +-// is in the castle, to cycle between three different songs. +- +-const int CadlPlayer::_kyra1SoundTriggers[] = { +- 0, 4, 5, 3 +-}; +- +-const int CadlPlayer::_kyra1NumSoundTriggers = ARRAYSIZE(CadlPlayer::_kyra1SoundTriggers); +- +-CadlPlayer::CadlPlayer(Copl *newopl) +- : CPlayer(newopl), numsubsongs(0), _trackEntries(), _soundDataPtr(0) +-{ +- memset(_trackEntries, 0, sizeof(_trackEntries)); +- _driver = new AdlibDriver(newopl); +- assert(_driver); +- +- _sfxPlayingSound = -1; +- // _soundFileLoaded = ""; +- +- _soundTriggers = _kyra1SoundTriggers; +- _numSoundTriggers = _kyra1NumSoundTriggers; +- +- init(); +-} +- +-CadlPlayer::~CadlPlayer() { +- delete [] _soundDataPtr; +- delete _driver; +-} +- +-bool CadlPlayer::init() { +- _driver->callback(2); +- _driver->callback(16, int(4)); +- return true; +-} +- +-void CadlPlayer::process() { +- uint8 trigger = _driver->callback(11); +- +- if (trigger < _numSoundTriggers) { +- int soundId = _soundTriggers[trigger]; +- +- if (soundId) { +- playTrack(soundId); +- } +- } else { +- warning("Unknown sound trigger %d", trigger); +- // TODO: At this point, we really want to clear the trigger... +- } +-} +- +-// void CadlPlayer::setVolume(int volume) { +-// } +- +-// int CadlPlayer::getVolume() { +-// return 0; +-// } +- +-// void CadlPlayer::loadMusicFile(const char *file) { +-// loadSoundFile(file); +-// } +- +-void CadlPlayer::playTrack(uint8 track) { +- play(track); +-} +- +-// void CadlPlayer::haltTrack() { +-// unk1(); +-// unk2(); +-// //_engine->_system->delayMillis(3 * 60); +-// } +- +-void CadlPlayer::playSoundEffect(uint8_t track) { +- play(track); +-} +- +-void CadlPlayer::play(uint8_t track) { +- uint8 soundId = _trackEntries[track]; +- if ((int8)soundId == -1 || !_soundDataPtr) +- return; +- soundId &= 0xFF; +- _driver->callback(16, 0); +- // while ((_driver->callback(16, 0) & 8)) { +- // We call the system delay and not the game delay to avoid concurrency issues. +- // _engine->_system->delayMillis(10); +- // } +- if (_sfxPlayingSound != -1) { +- // Restore the sounds's normal values. +- _driver->callback(10, _sfxPlayingSound, int(1), int(_sfxPriority)); +- _driver->callback(10, _sfxPlayingSound, int(3), int(_sfxFourthByteOfSong)); +- _sfxPlayingSound = -1; +- } +- +- int chan = _driver->callback(9, soundId, int(0)); +- +- if (chan != 9) { +- _sfxPlayingSound = soundId; +- _sfxPriority = _driver->callback(9, soundId, int(1)); +- _sfxFourthByteOfSong = _driver->callback(9, soundId, int(3)); +- +- // In the cases I've seen, the mysterious fourth byte has been +- // the parameter for the update_setExtraLevel3() callback. +- // +- // The extra level is part of the channels "total level", which +- // is a six-bit value where larger values means softer volume. +- // +- // So what seems to be happening here is that sounds which are +- // started by this function are given a slightly lower priority +- // and a slightly higher (i.e. softer) extra level 3 than they +- // would have if they were started from anywhere else. Strange. +- +- int newVal = ((((-_sfxFourthByteOfSong) + 63) * 0xFF) >> 8) & 0xFF; +- newVal = -newVal + 63; +- _driver->callback(10, soundId, int(3), newVal); +- newVal = ((_sfxPriority * 0xFF) >> 8) & 0xFF; +- _driver->callback(10, soundId, int(1), newVal); +- } +- +- _driver->callback(6, soundId); +-} +- +-// void CadlPlayer::beginFadeOut() { +-// playSoundEffect(1); +-// } +- +-bool CadlPlayer::load(const std::string &filename, const CFileProvider &fp) +-{ +- binistream *f = fp.open(filename); +- +- // file validation section +- if(!f || !fp.extension(filename, ".adl")) { +- fp.close(f); +- return false; +- } +- +- // if (_soundFileLoaded == file) +- // return; +- +- // if (_soundDataPtr) { +- // haltTrack(); +- // } +- +- uint8 *file_data = 0; uint32 file_size = 0; +- +- // char filename[25]; +- // sprintf(filename, "%s.ADL", file); +- +- // file_data = _engine->resource()->fileData(filename, &file_size); +- // if (!file_data) { +- // warning("Couldn't find music file: '%s'", filename); +- // return; +- // } +- +- unk2(); +- unk1(); +- +- file_size = fp.filesize(f); +- file_data = new uint8 [file_size]; +- f->readString((char *)file_data, file_size); +- +- _driver->callback(8, int(-1)); +- _soundDataPtr = 0; +- +- uint8 *p = file_data; +- memcpy(_trackEntries, p, 120*sizeof(uint8)); +- p += 120; +- +- int soundDataSize = file_size - 120; +- +- _soundDataPtr = new uint8[soundDataSize]; +- assert(_soundDataPtr); +- +- memcpy(_soundDataPtr, p, soundDataSize*sizeof(uint8)); +- +- delete [] file_data; +- file_data = p = 0; +- file_size = 0; +- +- _driver->callback(4, _soundDataPtr); +- +- // _soundFileLoaded = file; +- +- // find last subsong +- for(int i = 119; i >= 0; i--) +- if(_trackEntries[i] != 0xff) { +- numsubsongs = i + 1; +- break; +- } +- +- fp.close(f); +- cursubsong = 2; +- rewind(); +- return true; +-} +- +-void CadlPlayer::rewind(int subsong) +-{ +- if(subsong == -1) subsong = cursubsong; +- opl->init(); +- opl->write(1,32); +- playSoundEffect(subsong); +- cursubsong = subsong; +- update(); +-} +- +-unsigned int CadlPlayer::getsubsongs() +-{ +- return numsubsongs; +-} +- +-bool CadlPlayer::update() +-{ +- bool songend = true; +- +-// if(_trackEntries[cursubsong] == 0xff) +-// return false; +- +- _driver->callback(); +- +- for(int i = 0; i < 10; i++) +- if(_driver->_channels[i].dataptr != NULL) +- songend = false; +- +- return !songend; +-} +- +-void CadlPlayer::unk1() { +- playSoundEffect(0); +- //_engine->_system->delayMillis(5 * 60); +-} +- +-void CadlPlayer::unk2() { +- playSoundEffect(0); +-} +- +-CPlayer *CadlPlayer::factory(Copl *newopl) +-{ +- return new CadlPlayer(newopl); +-} +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/adl.h audacious-plugins-3.9/src/adplug/core/adl.h +--- audacious-plugins-3.9-orig/src/adplug/core/adl.h 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/adl.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,80 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2007 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * adl.h - ADL player adaption by Simon Peter +- */ +- +-#ifndef H_ADPLUG_ADLPLAYER +-#define H_ADPLUG_ADLPLAYER +- +-#include +- +-#include "player.h" +- +-class AdlibDriver; +- +-class CadlPlayer: public CPlayer +-{ +- public: +- static CPlayer *factory(Copl *newopl); +- +- CadlPlayer(Copl *newopl); +- ~CadlPlayer(); +- +- bool load(const std::string &filename, const CFileProvider &fp); +- bool update(); +- void rewind(int subsong = -1); +- +- // refresh rate is fixed at 72Hz +- float getrefresh() +- { +- return 72.0f; +- } +- +- unsigned int getsubsongs(); +- unsigned int getsubsong() { return cursubsong; } +- std::string gettype() { return std::string("Westwood ADL"); } +- +- private: +- int numsubsongs, cursubsong; +- +- AdlibDriver *_driver; +- +- uint8_t _trackEntries[120]; +- uint8_t *_soundDataPtr; +- int _sfxPlayingSound; +- +- uint8_t _sfxPriority; +- uint8_t _sfxFourthByteOfSong; +- +- int _numSoundTriggers; +- const int *_soundTriggers; +- +- static const int _kyra1NumSoundTriggers; +- static const int _kyra1SoundTriggers[]; +- +- bool init(); +- void process(); +- void playTrack(uint8_t track); +- void playSoundEffect(uint8_t track); +- void play(uint8_t track); +- void unk1(); +- void unk2(); +-}; +- +-#endif +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/adlibemu.cc audacious-plugins-3.9/src/adplug/core/adlibemu.cc +--- audacious-plugins-3.9-orig/src/adplug/core/adlibemu.cc 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/adlibemu.cc 1970-01-01 01:00:00.000000000 +0100 +@@ -1,544 +0,0 @@ +-/* +- * ADLIBEMU.C +- * Copyright (C) 1998-2001 Ken Silverman +- * Ken Silverman's official web site: "http://www.advsys.net/ken" +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- */ +- +-/* +-This file is a digital Adlib emulator for OPL2 and possibly OPL3 +- +-Features that could be added in a future version: +-- Amplitude and Frequency Vibrato Bits (not hard, but a big speed hit) +-- Global Keyboard Split Number Bit (need to research this one some more) +-- 2nd Adlib chip for OPL3 (simply need to make my cell array bigger) +-- Advanced connection modes of OPL3 (Just need to add more "docell" cases) +-- L/R Stereo bits of OPL3 (Need adlibgetsample to return stereo) +- +-Features that aren't worth supporting: +-- Anything related to adlib timers&interrupts (Sorry - I always used IRQ0) +-- Composite sine wave mode (CSM) (Supported only on ancient cards) +- +-I'm not sure about a few things in my code: +-- Attack curve. What function is this anyway? I chose to use an order-3 +- polynomial to approximate but this doesn't seem right. +-- Attack/Decay/Release constants - my constants may not be exact +-- What should ADJUSTSPEED be? +-- Haven't verified that Global Keyboard Split Number Bit works yet +-- Some of the drums don't always sound right. It's pretty hard to guess +- the exact waveform of drums when you look at random data which is +- slightly randomized due to digital ADC recording. +-- Adlib seems to have a lot more treble than my emulator does. I'm not +- sure if this is simply unfixable due to the sound blaster's different +- filtering on FM and digital playback or if it's a serious bug in my +- code. +-*/ +- +-#include +-#include +-#include +- +-using std::max; +-using std::min; +- +-#define PI 3.141592653589793 +-#define MAXCELLS 18 +-#define WAVPREC 2048 +- +-static float AMPSCALE=(8192.0); +-#define FRQSCALE (49716/512.0) +- +-//Constants for Ken's Awe32, on a PII-266 (Ken says: Use these for KSM's!) +-#define MODFACTOR 4.0 //How much of modulator cell goes into carrier +-#define MFBFACTOR 1.0 //How much feedback goes back into modulator +-#define ADJUSTSPEED 0.75 //0<=x<=1 Simulate finite rate of change of state +- +-//Constants for Ken's Awe64G, on a P-133 +-//#define MODFACTOR 4.25 //How much of modulator cell goes into carrier +-//#define MFBFACTOR 0.5 //How much feedback goes back into modulator +-//#define ADJUSTSPEED 0.85 //0<=x<=1 Simulate finite rate of change of state +- +-typedef struct +-{ +- float val, t, tinc, vol, sustain, amp, mfb; +- float a0, a1, a2, a3, decaymul, releasemul; +- short *waveform; +- long wavemask; +- void (*cellfunc)(void *, float); +- unsigned char flags, dum0, dum1, dum2; +-} celltype; +- +-static long numspeakers, bytespersample; +-static float recipsamp; +-static celltype cell[MAXCELLS]; +-static signed short wavtable[WAVPREC*3]; +-static float kslmul[4] = {0.0,0.5,0.25,1.0}; +-static float frqmul[16] = {.5,1,2,3,4,5,6,7,8,9,10,10,12,12,15,15}, nfrqmul[16]; +-static unsigned char adlibreg[256], ksl[8][16]; +-static unsigned char modulatorbase[9] = {0,1,2,8,9,10,16,17,18}; +-static unsigned char odrumstat = 0; +-static unsigned char base2cell[22] = {0,1,2,0,1,2,0,0,3,4,5,3,4,5,0,0,6,7,8,6,7,8}; +- +-float lvol[9] = {1,1,1,1,1,1,1,1,1}; //Volume multiplier on left speaker +-float rvol[9] = {1,1,1,1,1,1,1,1,1}; //Volume multiplier on right speaker +-long lplc[9] = {0,0,0,0,0,0,0,0,0}; //Samples to delay on left speaker +-long rplc[9] = {0,0,0,0,0,0,0,0,0}; //Samples to delay on right speaker +- +-long nlvol[9], nrvol[9]; +-long nlplc[9], nrplc[9]; +-long rend = 0; +-#define FIFOSIZ 256L +-static float *rptr[9], *nrptr[9]; +-static float rbuf[9][FIFOSIZ*2]; +-static float snd[FIFOSIZ*2]; +- +-static void ftol(float f, long *a) { +- *a=f; +-} +- +-#define ctc ((celltype *)c) //A rare attempt to make code easier to read! +-void docell4 (void *c, float modulator) { } +-void docell3 (void *c, float modulator) +-{ +- long i; +- +- ftol(ctc->t+modulator,&i); +- ctc->t += ctc->tinc; +- ctc->val += (ctc->amp*ctc->vol*((float)ctc->waveform[i&ctc->wavemask])-ctc->val)*ADJUSTSPEED; +-} +-void docell2 (void *c, float modulator) +-{ +- long i; +- +- ftol(ctc->t+modulator,&i); +- +- if ((long)ctc->amp <= 0x37800000) +- { +- ctc->amp = 0; +- ctc->cellfunc = docell4; +- } +- ctc->amp *= ctc->releasemul; +- +- ctc->t += ctc->tinc; +- ctc->val += (ctc->amp*ctc->vol*((float)ctc->waveform[i&ctc->wavemask])-ctc->val)*ADJUSTSPEED; +-} +-void docell1 (void *c, float modulator) +-{ +- long i; +- +- ftol(ctc->t+modulator,&i); +- +- if ((long)ctc->amp <= (long)ctc->sustain) +- { +- if (ctc->flags&32) +- { +- ctc->amp = ctc->sustain; +- ctc->cellfunc = docell3; +- } +- else +- ctc->cellfunc = docell2; +- } +- else +- ctc->amp *= ctc->decaymul; +- +- ctc->t += ctc->tinc; +- ctc->val += (ctc->amp*ctc->vol*((float)ctc->waveform[i&ctc->wavemask])-ctc->val)*ADJUSTSPEED; +-} +-void docell0 (void *c, float modulator) +-{ +- long i; +- +- ftol(ctc->t+modulator,&i); +- +- ctc->amp = ((ctc->a3*ctc->amp + ctc->a2)*ctc->amp + ctc->a1)*ctc->amp + ctc->a0; +- if ((long)ctc->amp > 0x3f800000) +- { +- ctc->amp = 1; +- ctc->cellfunc = docell1; +- } +- +- ctc->t += ctc->tinc; +- ctc->val += (ctc->amp*ctc->vol*((float)ctc->waveform[i&ctc->wavemask])-ctc->val)*ADJUSTSPEED; +-} +- +- +-static long waveform[8] = {WAVPREC,WAVPREC>>1,WAVPREC,(WAVPREC*3)>>2,0,0,(WAVPREC*5)>>2,WAVPREC<<1}; +-static long wavemask[8] = {WAVPREC-1,WAVPREC-1,(WAVPREC>>1)-1,(WAVPREC>>1)-1,WAVPREC-1,((WAVPREC*3)>>2)-1,WAVPREC>>1,WAVPREC-1}; +-static long wavestart[8] = {0,WAVPREC>>1,0,WAVPREC>>2,0,0,0,WAVPREC>>3}; +-static float attackconst[4] = {1/2.82624,1/2.25280,1/1.88416,1/1.59744}; +-static float decrelconst[4] = {1/39.28064,1/31.41608,1/26.17344,1/22.44608}; +-void cellon (long i, long j, celltype *c, unsigned char iscarrier) +-{ +- long frn, oct, toff; +- float f; +- +- frn = ((((long)adlibreg[i+0xb0])&3)<<8) + (long)adlibreg[i+0xa0]; +- oct = ((((long)adlibreg[i+0xb0])>>2)&7); +- toff = (oct<<1) + ((frn>>9)&((frn>>8)|(((adlibreg[8]>>6)&1)^1))); +- if (!(adlibreg[j+0x20]&16)) toff >>= 2; +- +- f = pow(2.0,(adlibreg[j+0x60]>>4)+(toff>>2)-1)*attackconst[toff&3]*recipsamp; +- c->a0 = .0377*f; c->a1 = 10.73*f+1; c->a2 = -17.57*f; c->a3 = 7.42*f; +- f = -7.4493*decrelconst[toff&3]*recipsamp; +- c->decaymul = pow(2.0,f*pow(2.0,(adlibreg[j+0x60]&15)+(toff>>2))); +- c->releasemul = pow(2.0,f*pow(2.0,(adlibreg[j+0x80]&15)+(toff>>2))); +- c->wavemask = wavemask[adlibreg[j+0xe0]&7]; +- c->waveform = &wavtable[waveform[adlibreg[j+0xe0]&7]]; +- if (!(adlibreg[1]&0x20)) c->waveform = &wavtable[WAVPREC]; +- c->t = wavestart[adlibreg[j+0xe0]&7]; +- c->flags = adlibreg[j+0x20]; +- c->cellfunc = docell0; +- c->tinc = (float)(frn<vol = pow(2.0,((float)(adlibreg[j+0x40]&63) + +- (float)kslmul[adlibreg[j+0x40]>>6]*ksl[oct][frn>>6]) * -.125 - 14); +- c->sustain = pow(2.0,(float)(adlibreg[j+0x80]>>4) * -.5); +- if (!iscarrier) c->amp = 0; +- c->mfb = pow(2.0,((adlibreg[i+0xc0]>>1)&7)+5)*(WAVPREC/2048.0)*MFBFACTOR; +- if (!(adlibreg[i+0xc0]&14)) c->mfb = 0; +- c->val = 0; +-} +- +-//This function (and bug fix) written by Chris Moeller +-void cellfreq (signed long i, signed long j, celltype *c) +-{ +- long frn, oct; +- +- frn = ((((long)adlibreg[i+0xb0])&3)<<8) + (long)adlibreg[i+0xa0]; +- oct = ((((long)adlibreg[i+0xb0])>>2)&7); +- +- c->tinc = (float)(frn<vol = pow(2.0,((float)(adlibreg[j+0x40]&63) + +- (float)kslmul[adlibreg[j+0x40]>>6]*ksl[oct][frn>>6]) * -.125 - 14); +-} +- +-static long initfirstime = 0; +-void adlibinit (long dasamplerate, long danumspeakers, long dabytespersample) +-{ +- long i, j, frn, oct; +- +- memset((void *)adlibreg,0,sizeof(adlibreg)); +- memset((void *)cell,0,sizeof(celltype)*MAXCELLS); +- memset((void *)rbuf,0,sizeof(rbuf)); +- rend = 0; odrumstat = 0; +- +- for(i=0;i=0;i--) nfrqmul[i] = frqmul[i]*recipsamp*FRQSCALE*(WAVPREC/2048.0); +- +- if (!initfirstime) +- { +- initfirstime = 1; +- +- for(i=0;i<(WAVPREC>>1);i++) +- { +- wavtable[i] = +- wavtable[(i<<1) +WAVPREC] = (signed short)(16384*sin((float)((i<<1) )*PI*2/WAVPREC)); +- wavtable[(i<<1)+1+WAVPREC] = (signed short)(16384*sin((float)((i<<1)+1)*PI*2/WAVPREC)); +- } +- for(i=0;i<(WAVPREC>>3);i++) +- { +- wavtable[i+(WAVPREC<<1)] = wavtable[i+(WAVPREC>>3)]-16384; +- wavtable[i+((WAVPREC*17)>>3)] = wavtable[i+(WAVPREC>>2)]+16384; +- } +- +- //[table in book]*8/3 +- ksl[7][0] = 0; ksl[7][1] = 24; ksl[7][2] = 32; ksl[7][3] = 37; +- ksl[7][4] = 40; ksl[7][5] = 43; ksl[7][6] = 45; ksl[7][7] = 47; +- ksl[7][8] = 48; for(i=9;i<16;i++) ksl[7][i] = i+41; +- for(j=6;j>=0;j--) +- for(i=0;i<16;i++) +- { +- oct = (long)ksl[j+1][i]-8; if (oct < 0) oct = 0; +- ksl[j][i] = (unsigned char)oct; +- } +- } +- else +- { +- for(i=0;i<9;i++) +- { +- frn = ((((long)adlibreg[i+0xb0])&3)<<8) + (long)adlibreg[i+0xa0]; +- oct = ((((long)adlibreg[i+0xb0])>>2)&7); +- cell[i].tinc = (float)(frn< (odrumstat&16)) //BassDrum +- { +- cellon(6,16,&cell[6],0); +- cellon(6,19,&cell[15],1); +- cell[15].vol *= 2; +- } +- if ((v&8) > (odrumstat&8)) //Snare +- { +- cellon(16,20,&cell[16],0); +- cell[16].tinc *= 2*(nfrqmul[adlibreg[17+0x20]&15] / nfrqmul[adlibreg[20+0x20]&15]); +- if (((adlibreg[20+0xe0]&7) >= 3) && ((adlibreg[20+0xe0]&7) <= 5)) cell[16].vol = 0; +- cell[16].vol *= 2; +- } +- if ((v&4) > (odrumstat&4)) //TomTom +- { +- cellon(8,18,&cell[8],0); +- cell[8].vol *= 2; +- } +- if ((v&2) > (odrumstat&2)) //Cymbal +- { +- cellon(17,21,&cell[17],0); +- +- cell[17].wavemask = wavemask[5]; +- cell[17].waveform = &wavtable[waveform[5]]; +- cell[17].tinc *= 16; cell[17].vol *= 2; +- +- //cell[17].waveform = &wavtable[WAVPREC]; cell[17].wavemask = 0; +- //if (((adlibreg[21+0xe0]&7) == 0) || ((adlibreg[21+0xe0]&7) == 6)) +- // cell[17].waveform = &wavtable[(WAVPREC*7)>>2]; +- //if (((adlibreg[21+0xe0]&7) == 2) || ((adlibreg[21+0xe0]&7) == 3)) +- // cell[17].waveform = &wavtable[(WAVPREC*5)>>2]; +- } +- if ((v&1) > (odrumstat&1)) //Hihat +- { +- cellon(7,17,&cell[7],0); +- if (((adlibreg[17+0xe0]&7) == 1) || ((adlibreg[17+0xe0]&7) == 4) || +- ((adlibreg[17+0xe0]&7) == 5) || ((adlibreg[17+0xe0]&7) == 7)) cell[7].vol = 0; +- if ((adlibreg[17+0xe0]&7) == 6) { cell[7].wavemask = 0; cell[7].waveform = &wavtable[(WAVPREC*7)>>2]; } +- } +- +- odrumstat = v; +- } +- else if (((unsigned)(i-0x40) < (unsigned)22) && ((i&7) < 6)) +- { +- if ((i&7) < 3) // Modulator +- cellfreq(base2cell[i-0x40],i-0x40,&cell[base2cell[i-0x40]]); +- else // Carrier +- cellfreq(base2cell[i-0x40],i-0x40,&cell[base2cell[i-0x40]+9]); +- } +- else if ((unsigned)(i-0xa0) < (unsigned)9) +- { +- cellfreq(i-0xa0,modulatorbase[i-0xa0],&cell[i-0xa0]); +- cellfreq(i-0xa0,modulatorbase[i-0xa0]+3,&cell[i-0xa0+9]); +- } +- else if ((unsigned)(i-0xb0) < (unsigned)9) +- { +- if ((v&32) > (tmp&32)) +- { +- cellon(i-0xb0,modulatorbase[i-0xb0],&cell[i-0xb0],0); +- cellon(i-0xb0,modulatorbase[i-0xb0]+3,&cell[i-0xb0+9],1); +- } +- else if ((v&32) < (tmp&32)) +- cell[i-0xb0].cellfunc = cell[i-0xb0+9].cellfunc = docell2; +- cellfreq(i-0xb0,modulatorbase[i-0xb0],&cell[i-0xb0]); +- cellfreq(i-0xb0,modulatorbase[i-0xb0]+3,&cell[i-0xb0+9]); +- } +- +- //outdata(i,v); +-} +- +-static void clipit8(float f,unsigned char *a) { +- f/=256.0; +- f+=128.0; +- if (f>254.5) *a=255; +- else if (f<0.5) *a=0; +- else *a=f; +-} +- +-static void clipit16(float f,short *a) { +- if (f>32766.5) *a=32767; +- else if (f<-32767.5) *a=-32768; +- else *a=f; +-} +- +-void adlibsetvolume(int i) { +- AMPSCALE=i; +-} +- +-void adlibgetsample (unsigned char *sndptr, long numbytes) +-{ +- long i, j, k=0, ns, endsamples, rptrs, numsamples; +- celltype *cptr; +- float f; +- short *sndptr2=(short *)sndptr; +- +- numsamples = (numbytes>>(numspeakers+bytespersample-2)); +- +- if (bytespersample == 1) f = AMPSCALE/256.0; else f = AMPSCALE; +- if (numspeakers == 1) +- { +- nlvol[0] = lvol[0]*f; +- for(i=0;i<9;i++) rptr[i] = &rbuf[0][0]; +- rptrs = 1; +- } +- else +- { +- rptrs = 0; +- for(i=0;i<9;i++) +- { +- if ((!i) || (lvol[i] != lvol[i-1]) || (rvol[i] != rvol[i-1]) || +- (lplc[i] != lplc[i-1]) || (rplc[i] != rplc[i-1])) +- { +- nlvol[rptrs] = lvol[i]*f; +- nrvol[rptrs] = rvol[i]*f; +- nlplc[rptrs] = rend-min(max(lplc[i],0L),FIFOSIZ); +- nrplc[rptrs] = rend-min(max(rplc[i],0L),FIFOSIZ); +- rptrs++; +- } +- rptr[i] = &rbuf[rptrs-1][0]; +- } +- } +- +- +- //CPU time used to be somewhat less when emulator was only mono! +- // Because of no delay fifos! +- +- for(ns=0;ns>1)-1)); //Snare +- (cell[7].cellfunc)((void *)&cell[7],k&(WAVPREC-1)); //Hihat +- (cell[17].cellfunc)((void *)&cell[17],k&((WAVPREC>>3)-1)); //Cymbal +- (cell[8].cellfunc)((void *)&cell[8],0.0); //TomTom +- nrptr[7][i] += cell[7].val + cell[16].val; +- nrptr[8][i] += cell[8].val + cell[17].val; +- } +- } +- } +- for(j=9-1;j>=0;j--) +- { +- if ((adlibreg[0xbd]&0x20) && (j >= 6) && (j < 9)) continue; +- +- cptr = &cell[j]; k = j; +- if (adlibreg[0xc0+k]&1) +- { +- if ((cptr[9].cellfunc == docell4) && (cptr->cellfunc == docell4)) continue; +- for(i=0;icellfunc)((void *)cptr,cptr->val*cptr->mfb); +- (cptr->cellfunc)((void *)&cptr[9],0); +- nrptr[j][i] += cptr[9].val + cptr->val; +- } +- } +- else +- { +- if (cptr[9].cellfunc == docell4) continue; +- for(i=0;icellfunc)((void *)cptr,cptr->val*cptr->mfb); +- (cptr[9].cellfunc)((void *)&cptr[9],cptr->val*WAVPREC*MODFACTOR); +- nrptr[j][i] += cptr[9].val; +- } +- } +- } +- +- if (numspeakers == 1) +- { +- if (bytespersample == 1) +- { +- for(i=endsamples-1;i>=0;i--) +- clipit8(nrptr[0][i]*nlvol[0],sndptr+1); +- } +- else +- { +- for(i=endsamples-1;i>=0;i--) +- clipit16(nrptr[0][i]*nlvol[0],sndptr2+i); +- } +- } +- else +- { +- memset((void *)snd,0,endsamples*sizeof(float)*2); +- for(j=0;j=0;i--) +- clipit8(snd[i],sndptr+i); +- } +- else +- { +- for(i=(endsamples<<1)-1;i>=0;i--) +- clipit16(snd[i],sndptr2+i); +- } +- } +- +- sndptr = sndptr+(numspeakers*endsamples); +- sndptr2 = sndptr2+(numspeakers*endsamples); +- rend = ((rend+endsamples)&(FIFOSIZ*2-1)); +- } +-} +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/adlibemu.h audacious-plugins-3.9/src/adplug/core/adlibemu.h +--- audacious-plugins-3.9-orig/src/adplug/core/adlibemu.h 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/adlibemu.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,26 +0,0 @@ +-/* +- * ADLIBEMU.H +- * Copyright (C) 1998-2001 Ken Silverman +- * Ken Silverman's official web site: "http://www.advsys.net/ken" +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- */ +- +-void adlibinit(long dasamplerate,long danumspeakers,long dabytespersample); +-void adlib0(long i,long v); +-void adlibgetsample(void *sndptr,long numbytes); +-void adlibsetvolume(int i); +-void randoinsts(); +-extern float lvol[9],rvol[9],lplc[9],rplc[9]; +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/adplug.cc audacious-plugins-3.9/src/adplug/core/adplug.cc +--- audacious-plugins-3.9-orig/src/adplug/core/adplug.cc 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/adplug.cc 1970-01-01 01:00:00.000000000 +0100 +@@ -1,184 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2008 Simon Peter , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * adplug.cpp - CAdPlug utility class, by Simon Peter +- */ +- +-#include +-#include +-#include "binfile.h" +- +-#include "adplug.h" +-#include "debug.h" +- +-/***** Replayer includes *****/ +- +-#include "hsc.h" +-#include "amd.h" +-#include "a2m.h" +-#include "imf.h" +-#include "sng.h" +-#include "adtrack.h" +-#include "bam.h" +-#include "cmf.h" +-#include "d00.h" +-#include "dfm.h" +-#include "hsp.h" +-#include "ksm.h" +-#include "mad.h" +-#include "mid.h" +-#include "mkj.h" +-#include "cff.h" +-#include "dmo.h" +-#include "s3m.h" +-#include "dtm.h" +-#include "fmc.h" +-#include "mtk.h" +-#include "rad.h" +-#include "raw.h" +-#include "sa2.h" +-#include "bmf.h" +-#include "flash.h" +-#include "hybrid.h" +-#include "hyp.h" +-#include "psi.h" +-#include "rat.h" +-#include "lds.h" +-#include "u6m.h" +-#include "rol.h" +-#include "xsm.h" +-#include "dro.h" +-#include "dro2.h" +-#include "msc.h" +-#include "rix.h" +-#include "adl.h" +-#include "jbm.h" +- +-/***** CAdPlug *****/ +- +-// List of all players that come with the standard AdPlug distribution +-const CPlayerDesc CAdPlug::allplayers[] = { +- CPlayerDesc(ChscPlayer::factory, "HSC-Tracker", ".hsc\0"), +- CPlayerDesc(CsngPlayer::factory, "SNGPlay", ".sng\0"), +- CPlayerDesc(CimfPlayer::factory, "Apogee IMF", ".imf\0.wlf\0.adlib\0"), +- CPlayerDesc(Ca2mLoader::factory, "Adlib Tracker 2", ".a2m\0"), +- CPlayerDesc(CadtrackLoader::factory, "Adlib Tracker", ".sng\0"), +- CPlayerDesc(CamdLoader::factory, "AMUSIC", ".amd\0"), +- CPlayerDesc(CbamPlayer::factory, "Bob's Adlib Music", ".bam\0"), +- CPlayerDesc(CcmfPlayer::factory, "Creative Music File", ".cmf\0"), +- CPlayerDesc(Cd00Player::factory, "Packed EdLib", ".d00\0"), +- CPlayerDesc(CdfmLoader::factory, "Digital-FM", ".dfm\0"), +- CPlayerDesc(ChspLoader::factory, "HSC Packed", ".hsp\0"), +- CPlayerDesc(CksmPlayer::factory, "Ken Silverman Music", ".ksm\0"), +- CPlayerDesc(CmadLoader::factory, "Mlat Adlib Tracker", ".mad\0"), +- CPlayerDesc(CmidPlayer::factory, "MIDI", ".mid\0.sci\0.laa\0"), +- CPlayerDesc(CmkjPlayer::factory, "MKJamz", ".mkj\0"), +- CPlayerDesc(CcffLoader::factory, "Boomtracker", ".cff\0"), +- CPlayerDesc(CdmoLoader::factory, "TwinTeam", ".dmo\0"), +- CPlayerDesc(Cs3mPlayer::factory, "Scream Tracker 3", ".s3m\0"), +- CPlayerDesc(CdtmLoader::factory, "DeFy Adlib Tracker", ".dtm\0"), +- CPlayerDesc(CfmcLoader::factory, "Faust Music Creator", ".sng\0"), +- CPlayerDesc(CmtkLoader::factory, "MPU-401 Trakker", ".mtk\0"), +- CPlayerDesc(CradLoader::factory, "Reality Adlib Tracker", ".rad\0"), +- CPlayerDesc(CrawPlayer::factory, "RdosPlay RAW", ".raw\0"), +- CPlayerDesc(Csa2Loader::factory, "Surprise! Adlib Tracker", ".sat\0.sa2\0"), +- CPlayerDesc(CxadbmfPlayer::factory, "BMF Adlib Tracker", ".xad\0"), +- CPlayerDesc(CxadflashPlayer::factory, "Flash", ".xad\0"), +- CPlayerDesc(CxadhybridPlayer::factory, "Hybrid", ".xad\0"), +- CPlayerDesc(CxadhypPlayer::factory, "Hypnosis", ".xad\0"), +- CPlayerDesc(CxadpsiPlayer::factory, "PSI", ".xad\0"), +- CPlayerDesc(CxadratPlayer::factory, "rat", ".xad\0"), +- CPlayerDesc(CldsPlayer::factory, "LOUDNESS Sound System", ".lds\0"), +- CPlayerDesc(Cu6mPlayer::factory, "Ultima 6 Music", ".m\0"), +- CPlayerDesc(CrolPlayer::factory, "Adlib Visual Composer", ".rol\0"), +- CPlayerDesc(CxsmPlayer::factory, "eXtra Simple Music", ".xsm\0"), +- CPlayerDesc(CdroPlayer::factory, "DOSBox Raw OPL v0.1", ".dro\0"), +- CPlayerDesc(Cdro2Player::factory, "DOSBox Raw OPL v2.0", ".dro\0"), +- CPlayerDesc(CmscPlayer::factory, "Adlib MSC Player", ".msc\0"), +- CPlayerDesc(CrixPlayer::factory, "Softstar RIX OPL Music", ".rix\0"), +- CPlayerDesc(CadlPlayer::factory, "Westwood ADL", ".adl\0"), +- CPlayerDesc(CjbmPlayer::factory, "JBM Adlib Music", ".jbm\0"), +- CPlayerDesc() +-}; +- +-const CPlayers &CAdPlug::init_players(const CPlayerDesc pd[]) +-{ +- static CPlayers initplayers; +- unsigned int i; +- +- for(i = 0; pd[i].factory; i++) +- initplayers.push_back(&pd[i]); +- +- return initplayers; +-} +- +-const CPlayers CAdPlug::players = CAdPlug::init_players(CAdPlug::allplayers); +-CAdPlugDatabase *CAdPlug::database = 0; +- +-CPlayer *CAdPlug::factory(const std::string &fn, Copl *opl, +- const CFileProvider &fp, const CPlayers &pl) +-{ +- CPlayer *p; +- CPlayers::const_iterator i; +- unsigned int j; +- +- AdPlug_LogWrite("*** CAdPlug::factory(\"%s\",opl,fp) ***\n", fn.c_str()); +- +- // Try a direct hit by file extension +- for(i = pl.begin(); i != pl.end(); i++) +- for(j = 0; (*i)->get_extension(j); j++) +- if(fp.extension(fn, (*i)->get_extension(j))) { +- AdPlug_LogWrite("Trying direct hit: %s\n", (*i)->filetype.c_str()); +- if((p = (*i)->factory(opl))) { +- if(p->load(fn, fp)) { +- AdPlug_LogWrite("got it!\n"); +- AdPlug_LogWrite("--- CAdPlug::factory ---\n"); +- return p; +- } else +- delete p; +- } +- } +- +- // Try all players, one by one +- for(i = pl.begin(); i != pl.end(); i++) { +- AdPlug_LogWrite("Trying: %s\n", (*i)->filetype.c_str()); +- if((p = (*i)->factory(opl))) { +- if(p->load(fn, fp)) { +- AdPlug_LogWrite("got it!\n"); +- AdPlug_LogWrite("--- CAdPlug::factory ---\n"); +- return p; +- } else +- delete p; +- } +- } +- +- // Unknown file +- AdPlug_LogWrite("End of list!\n"); +- AdPlug_LogWrite("--- CAdPlug::factory ---\n"); +- return 0; +-} +- +-void CAdPlug::set_database(CAdPlugDatabase *db) +-{ +- database = db; +-} +- +-std::string CAdPlug::get_version() +-{ +- return std::string(VERSION); +-} +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/adplug.h audacious-plugins-3.9/src/adplug/core/adplug.h +--- audacious-plugins-3.9-orig/src/adplug/core/adplug.h 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/adplug.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,54 +0,0 @@ +-/* +- * AdPlug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2003 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * adplug.h - AdPlug main header file, by Simon Peter +- */ +- +-#ifndef H_ADPLUG_ADPLUG +-#define H_ADPLUG_ADPLUG +- +-#include +- +-#include "player.h" +-#include "opl.h" +-#include "fprovide.h" +-#include "players.h" +-#include "database.h" +- +-class CAdPlug +-{ +- friend CPlayer::CPlayer(Copl *newopl); +- +-public: +- static const CPlayers players; +- +- static CPlayer *factory(const std::string &fn, Copl *opl, +- const CFileProvider &fp, +- const CPlayers &pl = players); +- +- static void set_database(CAdPlugDatabase *db); +- static std::string get_version(); +- +-private: +- static CAdPlugDatabase *database; +- static const CPlayerDesc allplayers[]; +- +- static const CPlayers &init_players(const CPlayerDesc pd[]); +-}; +- +-#endif +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/adtrack.cc audacious-plugins-3.9/src/adplug/core/adtrack.cc +--- audacious-plugins-3.9-orig/src/adplug/core/adtrack.cc 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/adtrack.cc 1970-01-01 01:00:00.000000000 +0100 +@@ -1,176 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2003 Simon Peter , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * adtrack.cpp - Adlib Tracker 1.0 Loader by Simon Peter +- * +- * NOTES: +- * The original Adlib Tracker 1.0 is behaving a little different from the +- * official spec: The 'octave' integer from the instrument file is stored +- * "minus 1" from the actual value, underflowing from 0 to 0xffff. +- * +- * I also noticed that my player is playing everything transposed a few tones +- * higher than the original tracker. As far as i can see, my player perfectly +- * follows the official spec, so it "must" be the tracker that does something +- * wrong here... +- */ +- +-#include +-#include +- +-#include "adtrack.h" +-#include "debug.h" +- +-/*** Public methods ***/ +- +-CPlayer *CadtrackLoader::factory(Copl *newopl) +-{ +- return new CadtrackLoader(newopl); +-} +- +-bool CadtrackLoader::load(const std::string &filename, const CFileProvider &fp) +-{ +- binistream *f = fp.open(filename); if(!f) return false; +- binistream *instf; +- char note[2]; +- unsigned short rwp; +- unsigned char chp, octave, pnote = 0; +- int i,j; +- AdTrackInst myinst; +- +- // file validation +- if(!fp.extension(filename, ".sng") || fp.filesize(f) != 36000) +- { fp.close(f); return false; } +- +- // check for instruments file +- std::string instfilename(filename, 0, filename.find_last_of('.')); +- instfilename += ".ins"; +- AdPlug_LogWrite("CadtrackLoader::load(,\"%s\"): Checking for \"%s\"...\n", +- filename.c_str(), instfilename.c_str()); +- instf = fp.open(instfilename); +- if(!instf || fp.filesize(instf) != 468) { if(instf) { fp.close(instf); } fp.close(f); return false; } +- +- // give CmodPlayer a hint on what we're up to +- realloc_patterns(1,1000,9); realloc_instruments(9); realloc_order(1); +- init_trackord(); flags = NoKeyOn; +- (*order) = 0; length = 1; restartpos = 0; bpm = 120; initspeed = 3; +- +- // load instruments from instruments file +- for(i=0;i<9;i++) { +- for(j=0;j<2;j++) { +- myinst.op[j].appampmod = instf->readInt(2); +- myinst.op[j].appvib = instf->readInt(2); +- myinst.op[j].maintsuslvl = instf->readInt(2); +- myinst.op[j].keybscale = instf->readInt(2); +- myinst.op[j].octave = instf->readInt(2); +- myinst.op[j].freqrisevollvldn = instf->readInt(2); +- myinst.op[j].softness = instf->readInt(2); +- myinst.op[j].attack = instf->readInt(2); +- myinst.op[j].decay = instf->readInt(2); +- myinst.op[j].release = instf->readInt(2); +- myinst.op[j].sustain = instf->readInt(2); +- myinst.op[j].feedback = instf->readInt(2); +- myinst.op[j].waveform = instf->readInt(2); +- } +- convert_instrument(i, &myinst); +- } +- fp.close(instf); +- +- // load file +- for(rwp=0;rwp<1000;rwp++) +- for(chp=0;chp<9;chp++) { +- // read next record +- f->readString(note, 2); octave = f->readInt(1); f->ignore(); +- switch(*note) { +- case 'C': if(note[1] == '#') pnote = 2; else pnote = 1; break; +- case 'D': if(note[1] == '#') pnote = 4; else pnote = 3; break; +- case 'E': pnote = 5; break; +- case 'F': if(note[1] == '#') pnote = 7; else pnote = 6; break; +- case 'G': if(note[1] == '#') pnote = 9; else pnote = 8; break; +- case 'A': if(note[1] == '#') pnote = 11; else pnote = 10; break; +- case 'B': pnote = 12; break; +- case '\0': +- if(note[1] == '\0') +- tracks[chp][rwp].note = 127; +- else { +- fp.close(f); +- return false; +- } +- break; +- default: fp.close(f); return false; +- } +- if((*note) != '\0') { +- tracks[chp][rwp].note = pnote + (octave * 12); +- tracks[chp][rwp].inst = chp + 1; +- } +- } +- +- fp.close(f); +- rewind(0); +- return true; +-} +- +-float CadtrackLoader::getrefresh() +-{ +- return 18.2f; +-} +- +-/*** Private methods ***/ +- +-void CadtrackLoader::convert_instrument(unsigned int n, AdTrackInst *i) +-{ +- // Carrier "Amp Mod / Vib / Env Type / KSR / Multiple" register +- inst[n].data[2] = i->op[Carrier].appampmod ? 1 << 7 : 0; +- inst[n].data[2] += i->op[Carrier].appvib ? 1 << 6 : 0; +- inst[n].data[2] += i->op[Carrier].maintsuslvl ? 1 << 5 : 0; +- inst[n].data[2] += i->op[Carrier].keybscale ? 1 << 4 : 0; +- inst[n].data[2] += (i->op[Carrier].octave + 1) & 0xffff; // Bug in original tracker +- // Modulator... +- inst[n].data[1] = i->op[Modulator].appampmod ? 1 << 7 : 0; +- inst[n].data[1] += i->op[Modulator].appvib ? 1 << 6 : 0; +- inst[n].data[1] += i->op[Modulator].maintsuslvl ? 1 << 5 : 0; +- inst[n].data[1] += i->op[Modulator].keybscale ? 1 << 4 : 0; +- inst[n].data[1] += (i->op[Modulator].octave + 1) & 0xffff; // Bug in original tracker +- +- // Carrier "Key Scaling / Level" register +- inst[n].data[10] = (i->op[Carrier].freqrisevollvldn & 3) << 6; +- inst[n].data[10] += i->op[Carrier].softness & 63; +- // Modulator... +- inst[n].data[9] = (i->op[Modulator].freqrisevollvldn & 3) << 6; +- inst[n].data[9] += i->op[Modulator].softness & 63; +- +- // Carrier "Attack / Decay" register +- inst[n].data[4] = (i->op[Carrier].attack & 0x0f) << 4; +- inst[n].data[4] += i->op[Carrier].decay & 0x0f; +- // Modulator... +- inst[n].data[3] = (i->op[Modulator].attack & 0x0f) << 4; +- inst[n].data[3] += i->op[Modulator].decay & 0x0f; +- +- // Carrier "Release / Sustain" register +- inst[n].data[6] = (i->op[Carrier].release & 0x0f) << 4; +- inst[n].data[6] += i->op[Carrier].sustain & 0x0f; +- // Modulator... +- inst[n].data[5] = (i->op[Modulator].release & 0x0f) << 4; +- inst[n].data[5] += i->op[Modulator].sustain & 0x0f; +- +- // Channel "Feedback / Connection" register +- inst[n].data[0] = (i->op[Carrier].feedback & 7) << 1; +- +- // Carrier/Modulator "Wave Select" registers +- inst[n].data[8] = i->op[Carrier].waveform & 3; +- inst[n].data[7] = i->op[Modulator].waveform & 3; +-} +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/adtrack.h audacious-plugins-3.9/src/adplug/core/adtrack.h +--- audacious-plugins-3.9-orig/src/adplug/core/adtrack.h 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/adtrack.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,53 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2003 Simon Peter , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * adtrack.h - Adlib Tracker 1.0 Loader by Simon Peter +- */ +- +-#include "protrack.h" +- +-class CadtrackLoader: public CmodPlayer +-{ +-public: +- static CPlayer *factory(Copl *newopl); +- +- CadtrackLoader(Copl *newopl) +- : CmodPlayer(newopl) +- { }; +- +- bool load(const std::string &filename, const CFileProvider &fp); +- float getrefresh(); +- +- std::string gettype() +- { return std::string("Adlib Tracker 1.0"); }; +- unsigned int getinstruments() +- { return 9; }; +- +-private: +- enum Operators {Carrier = 1, Modulator = 0}; +- +- typedef struct { +- struct { +- unsigned short appampmod, appvib, maintsuslvl, keybscale, octave, +- freqrisevollvldn, softness, attack, decay, release, sustain, +- feedback, waveform; +- } op[2]; +- } AdTrackInst; +- +- void convert_instrument(unsigned int n, AdTrackInst *i); +-}; +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/amd.cc audacious-plugins-3.9/src/adplug/core/amd.cc +--- audacious-plugins-3.9-orig/src/adplug/core/amd.cc 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/amd.cc 1970-01-01 01:00:00.000000000 +0100 +@@ -1,193 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2007 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * amd.cpp - AMD Loader by Simon Peter +- */ +- +-#include +- +-#include "amd.h" +-#include "debug.h" +- +-CPlayer *CamdLoader::factory(Copl *newopl) +-{ +- return new CamdLoader(newopl); +-} +- +-bool CamdLoader::load(const std::string &filename, const CFileProvider &fp) +-{ +- binistream *f = fp.open(filename); if(!f) return false; +- struct { +- char id[9]; +- unsigned char version; +- } header; +- int i, j, k, t, numtrax, maxi = 0; +- unsigned char buf, buf2, buf3; +- const unsigned char convfx[10] = {0,1,2,9,17,11,13,18,3,14}; +- const unsigned char convvol[64] = { +- 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 9, 9, 0xa, 0xa, 0xb, +- 0xc, 0xc, 0xd, 0xe, 0xe, 0xf, 0x10, 0x10, 0x11, 0x12, 0x13, 0x14, 0x14, +- 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x21, +- 0x22, 0x23, 0x25, 0x26, 0x28, 0x29, 0x2b, 0x2d, 0x2e, 0x30, 0x32, 0x35, +- 0x37, 0x3a, 0x3c, 0x3f +- }; +- +- // file validation section +- if(fp.filesize(f) < 1072) { fp.close(f); return false; } +- f->seek(1062); f->readString(header.id, 9); +- header.version = f->readInt(1); +- if(strncmp(header.id, "seek(0); +- f->readString(songname, sizeof(songname)); +- f->readString(author, sizeof(author)); +- for(i = 0; i < 26; i++) { +- f->readString(instname[i], 23); +- for(j = 0; j < 11; j++) inst[i].data[j] = f->readInt(1); +- } +- length = f->readInt(1); nop = f->readInt(1) + 1; +- for(i=0;i<128;i++) order[i] = f->readInt(1); +- f->seek(10, binio::Add); +- if(header.version == 0x10) { // unpacked module +- maxi = nop * 9; +- for(i=0;i<64*9;i++) +- trackord[i/9][i%9] = i+1; +- t = 0; +- while(!f->ateof()) { +- for(j=0;j<64;j++) +- for(i=t;ireadInt(1); +- tracks[i][j].param2 = (buf&127) % 10; +- tracks[i][j].param1 = (buf&127) / 10; +- buf = f->readInt(1); +- tracks[i][j].inst = buf >> 4; +- tracks[i][j].command = buf & 0x0f; +- buf = f->readInt(1); +- if(buf >> 4) // fix bug in AMD save routine +- tracks[i][j].note = ((buf & 14) >> 1) * 12 + (buf >> 4); +- else +- tracks[i][j].note = 0; +- tracks[i][j].inst += (buf & 1) << 4; +- } +- t += 9; +- } +- } else { // packed module +- for(i=0;ireadInt(2) + 1; +- numtrax = f->readInt(2); +- for(k=0;kreadInt(2); +- if(i > 575) i = 575; // fix corrupted modules +- maxi = (i + 1 > maxi ? i + 1 : maxi); +- j = 0; +- do { +- buf = f->readInt(1); +- if(buf & 128) { +- for(t = j; t < j + (buf & 127) && t < 64; t++) { +- tracks[i][t].command = 0; +- tracks[i][t].inst = 0; +- tracks[i][t].note = 0; +- tracks[i][t].param1 = 0; +- tracks[i][t].param2 = 0; +- } +- j += buf & 127; +- continue; +- } +- tracks[i][j].param2 = buf % 10; +- tracks[i][j].param1 = buf / 10; +- buf = f->readInt(1); +- tracks[i][j].inst = buf >> 4; +- tracks[i][j].command = buf & 0x0f; +- buf = f->readInt(1); +- if(buf >> 4) // fix bug in AMD save routine +- tracks[i][j].note = ((buf & 14) >> 1) * 12 + (buf >> 4); +- else +- tracks[i][j].note = 0; +- tracks[i][j].inst += (buf & 1) << 4; +- j++; +- } while(j<64); +- } +- } +- fp.close(f); +- +- // convert to protracker replay data +- bpm = 50; restartpos = 0; flags = Decimal; +- for(i=0;i<26;i++) { // convert instruments +- buf = inst[i].data[0]; +- buf2 = inst[i].data[1]; +- inst[i].data[0] = inst[i].data[10]; +- inst[i].data[1] = buf; +- buf = inst[i].data[2]; +- inst[i].data[2] = inst[i].data[5]; +- buf3 = inst[i].data[3]; +- inst[i].data[3] = buf; +- buf = inst[i].data[4]; +- inst[i].data[4] = inst[i].data[7]; +- inst[i].data[5] = buf3; +- buf3 = inst[i].data[6]; +- inst[i].data[6] = inst[i].data[8]; +- inst[i].data[7] = buf; +- inst[i].data[8] = inst[i].data[9]; +- inst[i].data[9] = buf2; +- inst[i].data[10] = buf3; +- for(j=0;j<23;j++) // convert names +- if(instname[i][j] == '\xff') +- instname[i][j] = '\x20'; +- } +- for(i=0;i 63) vol = 63; +- tracks[i][j].param1 = vol / 10; +- tracks[i][j].param2 = vol % 10; +- } +- } +- +- rewind(0); +- return true; +-} +- +-float CamdLoader::getrefresh() +-{ +- if(tempo) +- return (float) (tempo); +- else +- return 18.2f; +-} +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/amd.h audacious-plugins-3.9/src/adplug/core/amd.h +--- audacious-plugins-3.9-orig/src/adplug/core/amd.h 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/amd.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,49 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2003 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * amd.h - AMD Loader by Simon Peter +- */ +- +-#include "protrack.h" +- +-class CamdLoader: public CmodPlayer +-{ +-public: +- static CPlayer *factory(Copl *newopl); +- +- CamdLoader(Copl *newopl) +- : CmodPlayer(newopl) +- { }; +- +- bool load(const std::string &filename, const CFileProvider &fp); +- float getrefresh(); +- +- std::string gettype() +- { return std::string("AMUSIC Adlib Tracker"); }; +- std::string gettitle() +- { return std::string(songname,0,24); }; +- std::string getauthor() +- { return std::string(author,0,24); }; +- unsigned int getinstruments() +- { return 26; }; +- std::string getinstrument(unsigned int n) +- { return std::string(instname[n],0,23); }; +- +-private: +- char songname[24],author[24],instname[26][23]; +-}; +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/bam.cc audacious-plugins-3.9/src/adplug/core/bam.cc +--- audacious-plugins-3.9-orig/src/adplug/core/bam.cc 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/bam.cc 1970-01-01 01:00:00.000000000 +0100 +@@ -1,203 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2003 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * bam.cpp - Bob's Adlib Music Player, by Simon Peter +- * +- * NOTES: +- * In my player, the loop counter is stored with the label. This can be +- * dangerous for some situations (see below), but there shouldn't be any BAM +- * files triggering this situation. +- * +- * From SourceForge Bug #476088: +- * ----------------------------- +- * Using just one loop counter for each label, my player can't +- * handle files that loop twice to the same label (if that's at +- * all possible with BAM). Imagine the following situation: +- * +- * ... [*] ---- [<- *] ---- [<- *] ... +- * ^ ^ ^ ^ ^ ^ ^ +- * | | | | | | | +- * +---|----+-----|-----+-----|----+--- normal song data +- * +----------|-----------|-------- label 1 +- * +-----------+-------- loop points to label 1 +- * +- * both loop points loop to the same label. Storing the loop +- * count with the label would cause chaos with the counter, +- * when the player executes the inner jump. +- * ------------------ +- * Not to worry. my reference implementation of BAM does not +- * support the multiple loop situation you describe, and +- * neither do any BAM-creation programs. Then both loops point +- * to the same label, the inner loop's counter is just allowed +- * to clobber the outer loop's counter. No stack is neccisary. +- */ +- +-#include +-#include "bam.h" +- +-const unsigned short CbamPlayer::freq[] = {172,182,193,205,217,230,243,258,274, +-290,307,326,345,365,387,410,435,460,489,517,547,580,614,651,1369,1389,1411, +-1434,1459,1484,1513,1541,1571,1604,1638,1675,2393,2413,2435,2458,2483,2508, +-2537,2565,2595,2628,2662,2699,3417,3437,3459,3482,3507,3532,3561,3589,3619, +-3652,3686,3723,4441,4461,4483,4506,4531,4556,4585,4613,4643,4676,4710,4747, +-5465,5485,5507,5530,5555,5580,5609,5637,5667,5700,5734,5771,6489,6509,6531, +-6554,6579,6604,6633,6661,6691,6724,6758,6795,7513,7533,7555,7578,7603,7628, +-7657,7685,7715,7748,7782,7819,7858,7898,7942,7988,8037,8089,8143,8191,8191, +-8191,8191,8191,8191,8191,8191,8191,8191,8191,8191}; +- +-CPlayer *CbamPlayer::factory(Copl *newopl) +-{ +- return new CbamPlayer(newopl); +-} +- +-bool CbamPlayer::load(const std::string &filename, const CFileProvider &fp) +-{ +- binistream *f = fp.open(filename); if(!f) return false; +- char id[4]; +- unsigned int i; +- +- size = fp.filesize(f) - 4; // filesize minus header +- f->readString(id, 4); +- if(strncmp(id,"CBMF",4)) { fp.close(f); return false; } +- +- song = new unsigned char [size]; +- for(i = 0; i < size; i++) song[i] = f->readInt(1); +- +- fp.close(f); +- rewind(0); +- return true; +-} +- +-bool CbamPlayer::update() +-{ +- unsigned char cmd,c; +- +- if(del) { +- del--; +- return !songend; +- } +- +- if(pos >= size) { // EOF detection +- pos = 0; +- songend = true; +- } +- +- while(song[pos] < 128) { +- cmd = song[pos] & 240; +- c = song[pos] & 15; +- switch(cmd) { +- case 0: // stop song +- pos = 0; +- songend = true; +- break; +- case 16: // start note +- if(c < 9) { +- opl->write(0xa0 + c, freq[song[++pos]] & 255); +- opl->write(0xb0 + c, (freq[song[pos]] >> 8) + 32); +- } else +- pos++; +- pos++; +- break; +- case 32: // stop note +- if(c < 9) +- opl->write(0xb0 + c, 0); +- pos++; +- break; +- case 48: // define instrument +- if(c < 9) { +- opl->write(0x20 + op_table[c],song[pos+1]); +- opl->write(0x23 + op_table[c],song[pos+2]); +- opl->write(0x40 + op_table[c],song[pos+3]); +- opl->write(0x43 + op_table[c],song[pos+4]); +- opl->write(0x60 + op_table[c],song[pos+5]); +- opl->write(0x63 + op_table[c],song[pos+6]); +- opl->write(0x80 + op_table[c],song[pos+7]); +- opl->write(0x83 + op_table[c],song[pos+8]); +- opl->write(0xe0 + op_table[c],song[pos+9]); +- opl->write(0xe3 + op_table[c],song[pos+10]); +- opl->write(0xc0 + c,song[pos+11]); +- } +- pos += 12; +- break; +- case 80: // set label +- label[c].target = ++pos; +- label[c].defined = true; +- break; +- case 96: // jump +- if(label[c].defined) +- switch(song[pos+1]) { +- case 254: // infinite loop +- if(label[c].defined) { +- pos = label[c].target; +- songend = true; +- break; +- } +- // fall through... +- case 255: // chorus +- if(!chorus && label[c].defined) { +- chorus = true; +- gosub = pos + 2; +- pos = label[c].target; +- break; +- } +- // fall through... +- case 0: // end of loop +- pos += 2; +- break; +- default: // finite loop +- if(!label[c].count) { // loop elapsed +- label[c].count = 255; +- pos += 2; +- break; +- } +- if(label[c].count < 255) // loop defined +- label[c].count--; +- else // loop undefined +- label[c].count = song[pos+1] - 1; +- pos = label[c].target; +- break; +- } +- break; +- case 112: // end of chorus +- if(chorus) { +- pos = gosub; +- chorus = false; +- } else +- pos++; +- break; +- default: // reserved command (skip) +- pos++; +- break; +- } +- } +- if(song[pos] >= 128) { // wait +- del = song[pos] - 127; +- pos++; +- } +- return !songend; +-} +- +-void CbamPlayer::rewind(int subsong) +-{ +- int i; +- +- pos = 0; songend = false; del = 0; gosub = 0; chorus = false; +- memset(label, 0, sizeof(label)); label[0].defined = true; +- for(i = 0; i < 16; i++) label[i].count = 255; // 255 = undefined +- opl->init(); opl->write(1,32); +-} +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/bam.h audacious-plugins-3.9/src/adplug/core/bam.h +--- audacious-plugins-3.9-orig/src/adplug/core/bam.h 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/bam.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,56 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2003 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * bam.h - Bob's Adlib Music Player, by Simon Peter +- */ +- +-#include "player.h" +- +-class CbamPlayer: public CPlayer +-{ +-public: +- static CPlayer *factory(Copl *newopl); +- +- CbamPlayer(Copl *newopl) +- : CPlayer(newopl), song(0) +- { }; +- ~CbamPlayer() +- { if(song) delete [] song; }; +- +- bool load(const std::string &filename, const CFileProvider &fp); +- bool update(); +- void rewind(int subsong); +- float getrefresh() +- { return 25.0f; }; +- +- std::string gettype() +- { return std::string("Bob's Adlib Music"); }; +- +-private: +- static const unsigned short freq[]; +- +- unsigned char *song, del; +- unsigned long pos, size, gosub; +- bool songend, chorus; +- +- struct { +- unsigned long target; +- bool defined; +- unsigned char count; +- } label[16]; +-}; +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/bmf.cc audacious-plugins-3.9/src/adplug/core/bmf.cc +--- audacious-plugins-3.9-orig/src/adplug/core/bmf.cc 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/bmf.cc 1970-01-01 01:00:00.000000000 +0100 +@@ -1,603 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2003, 2006 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * [xad] BMF player, by Riven the Mage +- */ +- +-/* +- - discovery - +- +- file(s) : GAMESNET.COM +- type : GamesNet advertising intro +- tune : by (?)The Brain [Razor 1911] +- player : ver.0.9b by Hammer +- +- file(s) : 2FAST4U.COM +- type : Ford Knox BBStro +- tune : by The Brain [Razor 1911] +- player : ver.1.1 by ? +- comment : in original player at 9th channel the feedback adlib register is not C8 but C6. +- +- file(s) : DATURA.COM +- type : Datura BBStro +- tune : by The Brain [Razor 1911] +- player : ver.1.2 by ? +- comment : inaccurate replaying, because constant outport; in original player it can be 380 or 382. +-*/ +- +-#include +-#include "bmf.h" +-#include "debug.h" +- +-const unsigned char CxadbmfPlayer::bmf_adlib_registers[117] = +-{ +- 0x20, 0x23, 0x40, 0x43, 0x60, 0x63, 0x80, 0x83, 0xA0, 0xB0, 0xC0, 0xE0, 0xE3, +- 0x21, 0x24, 0x41, 0x44, 0x61, 0x64, 0x81, 0x84, 0xA1, 0xB1, 0xC1, 0xE1, 0xE4, +- 0x22, 0x25, 0x42, 0x45, 0x62, 0x65, 0x82, 0x85, 0xA2, 0xB2, 0xC2, 0xE2, 0xE5, +- 0x28, 0x2B, 0x48, 0x4B, 0x68, 0x6B, 0x88, 0x8B, 0xA3, 0xB3, 0xC3, 0xE8, 0xEB, +- 0x29, 0x2C, 0x49, 0x4C, 0x69, 0x6C, 0x89, 0x8C, 0xA4, 0xB4, 0xC4, 0xE9, 0xEC, +- 0x2A, 0x2D, 0x4A, 0x4D, 0x6A, 0x6D, 0x8A, 0x8D, 0xA5, 0xB5, 0xC5, 0xEA, 0xED, +- 0x30, 0x33, 0x50, 0x53, 0x70, 0x73, 0x90, 0x93, 0xA6, 0xB6, 0xC6, 0xF0, 0xF3, +- 0x31, 0x34, 0x51, 0x54, 0x71, 0x74, 0x91, 0x94, 0xA7, 0xB7, 0xC7, 0xF1, 0xF4, +- 0x32, 0x35, 0x52, 0x55, 0x72, 0x75, 0x92, 0x95, 0xA8, 0xB8, 0xC8, 0xF2, 0xF5 +-}; +- +-const unsigned short CxadbmfPlayer::bmf_notes[12] = +-{ +- 0x157, 0x16B, 0x181, 0x198, 0x1B0, 0x1CA, 0x1E5, 0x202, 0x220, 0x241, 0x263, 0x287 +-}; +- +-/* for 1.1 */ +-const unsigned short CxadbmfPlayer::bmf_notes_2[12] = +-{ +- 0x159, 0x16D, 0x183, 0x19A, 0x1B2, 0x1CC, 0x1E8, 0x205, 0x223, 0x244, 0x267, 0x28B +-}; +- +-const unsigned char CxadbmfPlayer::bmf_default_instrument[13] = +-{ +- 0x01, 0x01, 0x3F, 0x3F, 0x00, 0x00, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00 +-}; +- +-CPlayer *CxadbmfPlayer::factory(Copl *newopl) +-{ +- return new CxadbmfPlayer(newopl); +-} +- +-bool CxadbmfPlayer::xadplayer_load() +-{ +- unsigned short ptr = 0; +- int i; +- +- if(xad.fmt != BMF) +- return false; +- +-#ifdef DEBUG +- AdPlug_LogWrite("\nbmf_load():\n\n"); +-#endif +- if (!strncmp((char *)&tune[0],"BMF1.2",6)) +- { +- bmf.version = BMF1_2; +- bmf.timer = 70.0f; +- } +- else if (!strncmp((char *)&tune[0],"BMF1.1",6)) +- { +- bmf.version = BMF1_1; +- bmf.timer = 60.0f; +- } +- else +- { +- bmf.version = BMF0_9B; +- bmf.timer = 18.2f; +- } +- +- // copy title & author +- if (bmf.version > BMF0_9B) +- { +- ptr = 6; +- +- strncpy(bmf.title,(char *)&tune[ptr],36); +- bmf.title[35] = 0; +- +- while (tune[ptr]) { ptr++; } +- ptr++; +- +- strncpy(bmf.author,(char *)&tune[ptr],36); +- bmf.author[35] = 0; +- +- while (tune[ptr]) { ptr++; } +- ptr++; +- } +- else +- { +- strncpy(bmf.title,xad.title,36); +- strncpy(bmf.author,xad.author,36); +- } +- +- // speed +- if (bmf.version > BMF0_9B) +- bmf.speed = tune[ptr++]; +- else +- bmf.speed = ((tune[ptr++] << 8) / 3) >> 8; // strange, yeh ? +- +- // load instruments +- if (bmf.version > BMF0_9B) +- { +- unsigned long iflags = (tune[ptr] << 24) | (tune[ptr+1] << 16) | (tune[ptr+2] << 8) | tune[ptr+3]; +- ptr+=4; +- +- for(i=0;i<32;i++) +- if (iflags & (1 << (31-i))) +- { +- strcpy(bmf.instruments[i].name, (char *)&tune[ptr]); +- memcpy(bmf.instruments[i].data, &tune[ptr+11], 13); +- ptr += 24; +- } +- else +- { +- bmf.instruments[i].name[0] = 0; +- +- if (bmf.version == BMF1_1) +- for(int j=0;j<13;j++) +- bmf.instruments[i].data[j] = bmf_default_instrument[j]; +- else +- for(int j=0;j<13;j++) +- bmf.instruments[i].data[j] = 0; +- } +- } +- else +- { +- ptr = 6; +- +- for(i=0;i<32;i++) +- { +- bmf.instruments[i].name[0] = 0; +- memcpy(bmf.instruments[tune[ptr]].data, &tune[ptr+2],13); // bug no.1 (no instrument-table-end detection) +- ptr+=15; +- } +- } +- +- // load streams +- if (bmf.version > BMF0_9B) +- { +- unsigned long sflags = (tune[ptr] << 24) | (tune[ptr+1] << 16) | (tune[ptr+2] << 8) | tune[ptr+3]; +- ptr+=4; +- +- for(i=0;i<9;i++) +- if (sflags & (1 << (31-i))) +- ptr+=__bmf_convert_stream(&tune[ptr],i); +- else +- bmf.streams[i][0].cmd = 0xFF; +- } +- else +- { +- for(i=0;i BMF0_9B) +- { +- opl_write(0x01, 0x20); +- +- /* 1.1 */ +- if (bmf.version == BMF1_1) +- for(i=0;i<9;i++) +- for(j=0;j<13;j++) +- opl_write(bmf_adlib_registers[13*i+j], bmf_default_instrument[j]); +- /* 1.2 */ +- else if (bmf.version == BMF1_2) +- for(i=0x20; i<0x100; i++) +- opl_write(i,0xFF); // very interesting, really! +- } +- +- /* ALL */ +- +- opl_write(0x08, 0x00); +- opl_write(0xBD, 0xC0); +-} +- +-void CxadbmfPlayer::xadplayer_update() +-{ +- for(int i=0;i<9;i++) +- if (bmf.channel[i].stream_position != 0xFFFF) +- { +- if (bmf.channel[i].delay) +- bmf.channel[i].delay--; +- else +- { +-#ifdef DEBUG +- AdPlug_LogWrite("channel %02X:\n", i); +-#endif +- bmf_event event; +- +- // process so-called cross-events +- while (true) +- { +- memcpy(&event, &bmf.streams[i][bmf.channel[i].stream_position], sizeof(bmf_event)); +-#ifdef DEBUG +- AdPlug_LogWrite("%02X %02X %02X %02X %02X %02X\n", +- event.note,event.delay,event.volume,event.instrument, +- event.cmd,event.cmd_data); +-#endif +- +- if (event.cmd == 0xFF) +- { +- bmf.channel[i].stream_position = 0xFFFF; +- bmf.active_streams--; +- break; +- } +- else if (event.cmd == 0xFE) +- { +- bmf.channel[i].loop_position = bmf.channel[i].stream_position+1; +- bmf.channel[i].loop_counter = event.cmd_data; +- } +- else if (event.cmd == 0xFD) +- { +- if (bmf.channel[i].loop_counter) +- { +- bmf.channel[i].stream_position = bmf.channel[i].loop_position-1; +- bmf.channel[i].loop_counter--; +- } +- } +- else +- break; +- +- bmf.channel[i].stream_position++; +- } // while (true) +- +- // process normal event +- unsigned short pos = bmf.channel[i].stream_position; +- +- if (pos != 0xFFFF) +- { +- bmf.channel[i].delay = bmf.streams[i][pos].delay; +- +- // command ? +- if (bmf.streams[i][pos].cmd) +- { +- unsigned char cmd = bmf.streams[i][pos].cmd; +- +- // 0x01: Set Modulator Volume +- if (cmd == 0x01) +- { +- unsigned char reg = bmf_adlib_registers[13*i+2]; +- +- opl_write(reg, (adlib[reg] | 0x3F) - bmf.streams[i][pos].cmd_data); +- } +- // 0x10: Set Speed +- else if (cmd == 0x10) +- { +- plr.speed = bmf.streams[i][pos].cmd_data; +- plr.speed_counter = plr.speed; +- } +- } // if (bmf.streams[i][pos].cmd) +- +- // instrument ? +- if (bmf.streams[i][pos].instrument) +- { +- unsigned char ins = bmf.streams[i][pos].instrument-1; +- +- if (bmf.version != BMF1_1) +- opl_write(0xB0+i, adlib[0xB0+i] & 0xDF); +- +- for(int j=0;j<13;j++) +- opl_write(bmf_adlib_registers[i*13+j], bmf.instruments[ins].data[j]); +- } // if (bmf.streams[i][pos].instrument) +- +- // volume ? +- if (bmf.streams[i][pos].volume) +- { +- unsigned char vol = bmf.streams[i][pos].volume-1; +- unsigned char reg = bmf_adlib_registers[13*i+3]; +- +- opl_write(reg, (adlib[reg] | 0x3F) - vol); +- } // if (bmf.streams[i][pos].volume) +- +- // note ? +- if (bmf.streams[i][pos].note) +- { +- unsigned short note = bmf.streams[i][pos].note; +- unsigned short freq = 0; +- +- // mute channel +- opl_write(0xB0+i, adlib[0xB0+i] & 0xDF); +- +- // get frequency +- if (bmf.version == BMF1_1) +- { +- if (note <= 0x60) +- freq = bmf_notes_2[--note % 12]; +- } +- else +- { +- if (note != 0x7F) +- freq = bmf_notes[--note % 12]; +- } +- +- // play note +- if (freq) +- { +- opl_write(0xB0+i, (freq >> 8) | ((note / 12) << 2) | 0x20); +- opl_write(0xA0+i, freq & 0xFF); +- } +- } // if (bmf.streams[i][pos].note) +- +- bmf.channel[i].stream_position++; +- } // if (pos != 0xFFFF) +- +- } // if (!bmf.channel[i].delay) +- } // if (bmf.channel[i].stream_position != 0xFFFF) +- +- // is module loop ? +- if (!bmf.active_streams) +- { +- for(int j=0;j<9;j++) +- bmf.channel[j].stream_position = 0; +- +- bmf.active_streams = 9; +- +- plr.looping = 1; +- } +-} +- +-float CxadbmfPlayer::xadplayer_getrefresh() +-{ +- return bmf.timer; +-} +- +-std::string CxadbmfPlayer::xadplayer_gettype() +-{ +- return std::string("xad: BMF Adlib Tracker"); +-} +- +-std::string CxadbmfPlayer::xadplayer_gettitle() +-{ +- return std::string(bmf.title); +-} +- +-std::string CxadbmfPlayer::xadplayer_getauthor() +-{ +- return std::string(bmf.author); +-} +- +-unsigned int CxadbmfPlayer::xadplayer_getinstruments() +-{ +- return 32; +-} +- +-std::string CxadbmfPlayer::xadplayer_getinstrument(unsigned int i) +-{ +- return std::string(bmf.instruments[i].name); +-} +- +-/* -------- Internal Functions ---------------------------- */ +- +-int CxadbmfPlayer::__bmf_convert_stream(unsigned char *stream, int channel) +-{ +-#ifdef DEBUG +- AdPlug_LogWrite("channel %02X (note,delay,volume,instrument,command,command_data):\n",channel); +- unsigned char *last = stream; +-#endif +- unsigned char *stream_start = stream; +- +- int pos = 0; +- +- while (true) +- { +- memset(&bmf.streams[channel][pos], 0, sizeof(bmf_event)); +- +- bool is_cmd = false; +- +- if (*stream == 0xFE) +- { +- // 0xFE -> 0xFF: End of Stream +- bmf.streams[channel][pos].cmd = 0xFF; +- +- stream++; +- +- break; +- } +- else if (*stream == 0xFC) +- { +- // 0xFC -> 0xFE xx: Save Loop Position +- bmf.streams[channel][pos].cmd = 0xFE; +- bmf.streams[channel][pos].cmd_data = (*(stream+1) & ((bmf.version == BMF0_9B) ? 0x7F : 0x3F)) - 1; +- +- stream+=2; +- } +- else if (*stream == 0x7D) +- { +- // 0x7D -> 0xFD: Loop Saved Position +- bmf.streams[channel][pos].cmd = 0xFD; +- +- stream++; +- } +- else +- { +- if (*stream & 0x80) +- { +- if (*(stream+1) & 0x80) +- { +- if (*(stream+1) & 0x40) +- { +- // byte0: 1aaaaaaa = NOTE +- bmf.streams[channel][pos].note = *stream & 0x7F; +- // byte1: 11bbbbbb = DELAY +- bmf.streams[channel][pos].delay = *(stream+1) & 0x3F; +- // byte2: cccccccc = COMMAND +- +- stream+=2; +- +- is_cmd = true; +- } +- else +- { +- // byte0: 1aaaaaaa = NOTE +- bmf.streams[channel][pos].note = *stream & 0x7F; +- // byte1: 11bbbbbb = DELAY +- bmf.streams[channel][pos].delay = *(stream+1) & 0x3F; +- +- stream+=2; +- } // if (*(stream+1) & 0x40) +- } +- else +- { +- // byte0: 1aaaaaaa = NOTE +- bmf.streams[channel][pos].note = *stream & 0x7F; +- // byte1: 0bbbbbbb = COMMAND +- +- stream++; +- +- is_cmd = true; +- } // if (*(stream+1) & 0x80) +- } +- else +- { +- // byte0: 0aaaaaaa = NOTE +- bmf.streams[channel][pos].note = *stream & 0x7F; +- +- stream++; +- } // if (*stream & 0x80) +- } // if (*stream == 0xFE) +- +- // is command ? +- if (is_cmd) +- { +- +- /* ALL */ +- +- if ((0x20 <= *stream) && (*stream <= 0x3F)) +- { +- // 0x20 or higher; 0x3F or lower: Set Instrument +- bmf.streams[channel][pos].instrument = *stream - 0x20 + 1; +- +- stream++; +- } +- else if (0x40 <= *stream) +- { +- // 0x40 or higher: Set Volume +- bmf.streams[channel][pos].volume = *stream - 0x40 + 1; +- +- stream++; +- } +- else +- { +- +- /* 0.9b */ +- +- if (bmf.version == BMF0_9B) +- if (*stream < 0x20) +- { +- // 0x1F or lower: ? +- stream++; +- } +- +- /* 1.2 */ +- +- if (bmf.version == BMF1_2) +- { +- if (*stream == 0x01) +- { +- // 0x01: Set Modulator Volume -> 0x01 +- bmf.streams[channel][pos].cmd = 0x01; +- bmf.streams[channel][pos].cmd_data = *(stream+1); +- +- stream+=2; +- } +- else if (*stream == 0x02) +- { +- // 0x02: ? +- stream+=2; +- } +- else if (*stream == 0x03) +- { +- // 0x03: ? +- stream+=2; +- } +- else if (*stream == 0x04) +- { +- // 0x04: Set Speed -> 0x10 +- bmf.streams[channel][pos].cmd = 0x10; +- bmf.streams[channel][pos].cmd_data = *(stream+1); +- +- stream+=2; +- } +- else if (*stream == 0x05) +- { +- // 0x05: Set Carrier Volume (port 380) +- bmf.streams[channel][pos].volume = *(stream+1) + 1; +- +- stream+=2; +- } +- else if (*stream == 0x06) +- { +- // 0x06: Set Carrier Volume (port 382) +- bmf.streams[channel][pos].volume = *(stream+1) + 1; +- +- stream+=2; +- } +- } // if (bmf.version == BMF1_2) +- +- } // if ((0x20 <= *stream) && (*stream <= 0x3F)) +- +- } // if (is_cmd) +- +-#ifdef DEBUG +- AdPlug_LogWrite("%02X %02X %02X %02X %02X %02X <---- ", +- bmf.streams[channel][pos].note, +- bmf.streams[channel][pos].delay, +- bmf.streams[channel][pos].volume, +- bmf.streams[channel][pos].instrument, +- bmf.streams[channel][pos].cmd, +- bmf.streams[channel][pos].cmd_data +- ); +- for(int zz=0;zz<(stream-last);zz++) +- AdPlug_LogWrite("%02X ",last[zz]); +- AdPlug_LogWrite("\n"); +- last=stream; +-#endif +- pos++; +- } // while (true) +- +- return (stream - stream_start); +-} +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/bmf.h audacious-plugins-3.9/src/adplug/core/bmf.h +--- audacious-plugins-3.9-orig/src/adplug/core/bmf.h 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/bmf.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,91 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2003 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * [xad] BMF player, by Riven the Mage +- */ +- +-#include "xad.h" +- +-class CxadbmfPlayer: public CxadPlayer +-{ +-public: +- static CPlayer *factory(Copl *newopl); +- +- CxadbmfPlayer(Copl *newopl): CxadPlayer(newopl) +- { }; +- ~CxadbmfPlayer() +- { }; +- +-protected: +- enum { BMF0_9B, BMF1_1, BMF1_2 }; +- // +- struct bmf_event +- { +- unsigned char note; +- unsigned char delay; +- unsigned char volume; +- unsigned char instrument; +- unsigned char cmd; +- unsigned char cmd_data; +- }; +- +- struct +- { +- unsigned char version; +- char title[36]; +- char author[36]; +- float timer; +- unsigned char speed; +- +- struct +- { +- char name[11]; +- unsigned char data[13]; +- } instruments[32]; +- +- bmf_event streams[9][1024]; +- +- int active_streams; +- +- struct +- { +- unsigned short stream_position; +- unsigned char delay; +- unsigned short loop_position; +- unsigned char loop_counter; +- } channel[9]; +- } bmf; +- // +- bool xadplayer_load(); +- void xadplayer_rewind(int subsong); +- void xadplayer_update(); +- float xadplayer_getrefresh(); +- std::string xadplayer_gettype(); +- std::string xadplayer_gettitle(); +- std::string xadplayer_getauthor(); +- std::string xadplayer_getinstrument(unsigned int i); +- unsigned int xadplayer_getinstruments(); +- // +-private: +- static const unsigned char bmf_adlib_registers[117]; +- static const unsigned short bmf_notes[12]; +- static const unsigned short bmf_notes_2[12]; +- static const unsigned char bmf_default_instrument[13]; +- +- int __bmf_convert_stream(unsigned char *stream, int channel); +-}; +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/cff.cc audacious-plugins-3.9/src/adplug/core/cff.cc +--- audacious-plugins-3.9-orig/src/adplug/core/cff.cc 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/cff.cc 1970-01-01 01:00:00.000000000 +0100 +@@ -1,501 +0,0 @@ +-/* +- AdPlug - Replayer for many OPL2/OPL3 audio file formats. +- Copyright (C) 1999 - 2008 Simon Peter , et al. +- +- This library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- This library 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 +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with this library; if not, write to the Free Software +- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- +- cff.cpp - BoomTracker loader by Riven the Mage +-*/ +-/* +- NOTE: Conversion of slides is not 100% accurate. Original volume slides +- have effect on carrier volume only. Also, original arpeggio, frequency & volume +- slides use previous effect data instead of current. +-*/ +- +-#include +-#include +-#include +- +-#include "cff.h" +- +-/* -------- Public Methods -------------------------------- */ +- +-CPlayer *CcffLoader::factory(Copl *newopl) +-{ +- return new CcffLoader(newopl); +-} +- +-bool CcffLoader::load(const std::string &filename, const CFileProvider &fp) +-{ +- binistream *f = fp.open(filename); if(!f) return false; +- const unsigned char conv_inst[11] = { 2,1,10,9,4,3,6,5,0,8,7 }; +- const unsigned short conv_note[12] = { 0x16B, 0x181, 0x198, 0x1B0, 0x1CA, 0x1E5, 0x202, 0x220, 0x241, 0x263, 0x287, 0x2AE }; +- +- int i,j,k,t=0; +- +- // '' - signed ? +- f->readString(header.id, 16); +- header.version = f->readInt(1); header.size = f->readInt(2); +- header.packed = f->readInt(1); f->readString((char *)header.reserved, 12); +- if (memcmp(header.id,"""\x1A\xDE\xE0",16)) +- { fp.close(f); return false; } +- +- unsigned char *module = new unsigned char [0x10000]; +- +- // packed ? +- if (header.packed) +- { +- cff_unpacker *unpacker = new cff_unpacker; +- +- unsigned char *packed_module = new unsigned char [header.size + 4]; +- +- memset(packed_module,0,header.size + 4); +- +- f->readString((char *)packed_module, header.size); +- fp.close(f); +- +- if (!unpacker->unpack(packed_module,module)) +- { +- delete unpacker; +- delete [] packed_module; +- delete [] module; +- return false; +- } +- +- delete unpacker; +- delete [] packed_module; +- +- if (memcmp(&module[0x5E1],"CUD-FM-File - SEND A POSTCARD -",31)) +- { +- delete [] module; +- return false; +- } +- } +- else +- { +- f->readString((char *)module, header.size); +- fp.close(f); +- } +- +- // init CmodPlayer +- realloc_instruments(47); +- realloc_order(64); +- realloc_patterns(36,64,9); +- init_notetable(conv_note); +- init_trackord(); +- +- // load instruments +- for (i=0;i<47;i++) +- { +- memcpy(&instruments[i],&module[i*32],sizeof(cff_instrument)); +- +- for (j=0;j<11;j++) +- inst[i].data[conv_inst[j]] = instruments[i].data[j]; +- +- instruments[i].name[20] = 0; +- } +- +- // number of patterns +- nop = module[0x5E0]; +- +- // load title & author +- memcpy(song_title,&module[0x614],20); +- memcpy(song_author,&module[0x600],20); +- +- // load order +- memcpy(order,&module[0x628],64); +- +- // load tracks +- for (i=0;ibyte0 == 0x6D) +- tracks[t][k].note = 127; +- else +- if (event->byte0) +- tracks[t][k].note = event->byte0; +- +- if (event->byte2) +- old_event_byte2[j] = event->byte2; +- +- // convert effect +- switch (event->byte1) +- { +- case 'I': // set instrument +- tracks[t][k].inst = event->byte2 + 1; +- tracks[t][k].param1 = tracks[t][k].param2 = 0; +- break; +- +- case 'H': // set tempo +- tracks[t][k].command = 7; +- if (event->byte2 < 16) +- { +- tracks[t][k].param1 = 0x07; +- tracks[t][k].param2 = 0x0D; +- } +- break; +- +- case 'A': // set speed +- tracks[t][k].command = 19; +- tracks[t][k].param1 = event->byte2 >> 4; +- tracks[t][k].param2 = event->byte2 & 15; +- break; +- +- case 'L': // pattern break +- tracks[t][k].command = 13; +- tracks[t][k].param1 = event->byte2 >> 4; +- tracks[t][k].param2 = event->byte2 & 15; +- break; +- +- case 'K': // order jump +- tracks[t][k].command = 11; +- tracks[t][k].param1 = event->byte2 >> 4; +- tracks[t][k].param2 = event->byte2 & 15; +- break; +- +- case 'M': // set vibrato/tremolo +- tracks[t][k].command = 27; +- tracks[t][k].param1 = event->byte2 >> 4; +- tracks[t][k].param2 = event->byte2 & 15; +- break; +- +- case 'C': // set modulator volume +- tracks[t][k].command = 21; +- tracks[t][k].param1 = (0x3F - event->byte2) >> 4; +- tracks[t][k].param2 = (0x3F - event->byte2) & 15; +- break; +- +- case 'G': // set carrier volume +- tracks[t][k].command = 22; +- tracks[t][k].param1 = (0x3F - event->byte2) >> 4; +- tracks[t][k].param2 = (0x3F - event->byte2) & 15; +- break; +- +- case 'B': // set carrier waveform +- tracks[t][k].command = 25; +- tracks[t][k].param1 = event->byte2; +- tracks[t][k].param2 = 0x0F; +- break; +- +- case 'E': // fine frequency slide down +- tracks[t][k].command = 24; +- tracks[t][k].param1 = old_event_byte2[j] >> 4; +- tracks[t][k].param2 = old_event_byte2[j] & 15; +- break; +- +- case 'F': // fine frequency slide up +- tracks[t][k].command = 23; +- tracks[t][k].param1 = old_event_byte2[j] >> 4; +- tracks[t][k].param2 = old_event_byte2[j] & 15; +- break; +- +- case 'D': // fine volume slide +- tracks[t][k].command = 14; +- if (old_event_byte2[j] & 15) +- { +- // slide down +- tracks[t][k].param1 = 5; +- tracks[t][k].param2 = old_event_byte2[j] & 15; +- } +- else +- { +- // slide up +- tracks[t][k].param1 = 4; +- tracks[t][k].param2 = old_event_byte2[j] >> 4; +- } +- break; +- +- case 'J': // arpeggio +- tracks[t][k].param1 = old_event_byte2[j] >> 4; +- tracks[t][k].param2 = old_event_byte2[j] & 15; +- break; +- } +- } +- +- t++; +- } +- } +- +- delete [] module; +- +- // order loop +- restartpos = 0; +- +- // order length +- for (i=0;i<64;i++) +- { +- if (order[i] >= 0x80) +- { +- length = i; +- break; +- } +- } +- +- // default tempo +- bpm = 0x7D; +- +- rewind(0); +- +- return true; +-} +- +-void CcffLoader::rewind(int subsong) +-{ +- CmodPlayer::rewind(subsong); +- +- // default instruments +- for (int i=0;i<9;i++) +- { +- channel[i].inst = i; +- +- channel[i].vol1 = 63 - (inst[i].data[10] & 63); +- channel[i].vol2 = 63 - (inst[i].data[9] & 63); +- } +-} +- +-std::string CcffLoader::gettype() +-{ +- if (header.packed) +- return std::string("BoomTracker 4, packed"); +- else +- return std::string("BoomTracker 4"); +-} +- +-std::string CcffLoader::gettitle() +-{ +- return std::string(song_title,20); +-} +- +-std::string CcffLoader::getauthor() +-{ +- return std::string(song_author,20); +-} +- +-std::string CcffLoader::getinstrument(unsigned int n) +-{ +- return std::string(instruments[n].name); +-} +- +-unsigned int CcffLoader::getinstruments() +-{ +- return 47; +-} +- +-/* -------- Private Methods ------------------------------- */ +- +-/* +- Lempel-Ziv-Tyr ;-) +-*/ +-long CcffLoader::cff_unpacker::unpack(unsigned char *ibuf, unsigned char *obuf) +-{ +- if (memcmp(ibuf,"YsComp""\x07""CUD1997""\x1A\x04",16)) +- return 0; +- +- input = ibuf + 16; +- output = obuf; +- +- output_length = 0; +- +- heap = (unsigned char *)malloc(0x10000); +- dictionary = (unsigned char **)malloc(sizeof(unsigned char *)*0x8000); +- +- memset(heap,0,0x10000); +- memset(dictionary,0,0x8000); +- +- cleanup(); +- if(!startup()) +- goto out; +- +- // LZW +- while (1) +- { +- new_code = get_code(); +- +- // 0x00: end of data +- if (new_code == 0) +- break; +- +- // 0x01: end of block +- if (new_code == 1) +- { +- cleanup(); +- if(!startup()) +- goto out; +- +- continue; +- } +- +- // 0x02: expand code length +- if (new_code == 2) +- { +- code_length++; +- +- continue; +- } +- +- // 0x03: RLE +- if (new_code == 3) +- { +- unsigned char old_code_length = code_length; +- +- code_length = 2; +- +- unsigned char repeat_length = get_code() + 1; +- +- code_length = 4 << get_code(); +- +- unsigned long repeat_counter = get_code(); +- +- if(output_length + repeat_counter * repeat_length > 0x10000) { +- output_length = 0; +- goto out; +- } +- +- for (unsigned int i=0;i= (0x104 + dictionary_length)) +- { +- // dictionary <- old.code.string + old.code.char +- the_string[++the_string[0]] = the_string[1]; +- } +- else +- { +- // dictionary <- old.code.string + new.code.char +- unsigned char temp_string[256]; +- +- translate_code(new_code,temp_string); +- +- the_string[++the_string[0]] = temp_string[1]; +- } +- +- expand_dictionary(the_string); +- +- // output <- new.code.string +- translate_code(new_code,the_string); +- +- if(output_length + the_string[0] > 0x10000) { +- output_length = 0; +- goto out; +- } +- +- for (int i=0;i>= code_length; +- bits_left -= code_length; +- +- return code; +-} +- +-void CcffLoader::cff_unpacker::translate_code(unsigned long code, unsigned char *string) +-{ +- unsigned char translated_string[256]; +- +- if (code >= 0x104) +- { +- memcpy(translated_string,dictionary[code - 0x104],(*(dictionary[code - 0x104])) + 1); +- } +- else +- { +- translated_string[0] = 1; +- translated_string[1] = (code - 4) & 0xFF; +- } +- +- memcpy(string,translated_string,256); +-} +- +-void CcffLoader::cff_unpacker::cleanup() +-{ +- code_length = 9; +- +- bits_buffer = 0; +- bits_left = 0; +- +- heap_length = 0; +- dictionary_length = 0; +-} +- +-int CcffLoader::cff_unpacker::startup() +-{ +- old_code = get_code(); +- +- translate_code(old_code,the_string); +- +- if(output_length + the_string[0] > 0x10000) { +- output_length = 0; +- return 0; +- } +- +- for (int i=0;i= 0xF0) +- return; +- +- memcpy(&heap[heap_length],string,string[0] + 1); +- +- dictionary[dictionary_length] = &heap[heap_length]; +- +- dictionary_length++; +- +- heap_length += (string[0] + 1); +-} +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/cff.h audacious-plugins-3.9/src/adplug/core/cff.h +--- audacious-plugins-3.9-orig/src/adplug/core/cff.h 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/cff.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,103 +0,0 @@ +-/* +- AdPlug - Replayer for many OPL2/OPL3 audio file formats. +- Copyright (C) 1999 - 2006 Simon Peter , et al. +- +- This library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- This library 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 +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with this library; if not, write to the Free Software +- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- +- cff.h - BoomTracker loader by Riven the Mage +-*/ +- +-#include "protrack.h" +- +-class CcffLoader: public CmodPlayer +-{ +- public: +- static CPlayer *factory(Copl *newopl); +- +- CcffLoader(Copl *newopl) : CmodPlayer(newopl) { }; +- +- bool load(const std::string &filename, const CFileProvider &fp); +- void rewind(int subsong); +- +- std::string gettype(); +- std::string gettitle(); +- std::string getauthor(); +- std::string getinstrument(unsigned int n); +- unsigned int getinstruments(); +- +- private: +- +- class cff_unpacker +- { +- public: +- +- long unpack(unsigned char *ibuf, unsigned char *obuf); +- +- private: +- +- unsigned long get_code(); +- void translate_code(unsigned long code, unsigned char *string); +- +- void cleanup(); +- int startup(); +- +- void expand_dictionary(unsigned char *string); +- +- unsigned char *input; +- unsigned char *output; +- +- long output_length; +- +- unsigned char code_length; +- +- unsigned long bits_buffer; +- unsigned int bits_left; +- +- unsigned char *heap; +- unsigned char **dictionary; +- +- unsigned int heap_length; +- unsigned int dictionary_length; +- +- unsigned long old_code,new_code; +- +- unsigned char the_string[256]; +- }; +- +- struct cff_header +- { +- char id[16]; +- unsigned char version; +- unsigned short size; +- unsigned char packed; +- unsigned char reserved[12]; +- } header; +- +- struct cff_instrument +- { +- unsigned char data[12]; +- char name[21]; +- } instruments[47]; +- +- char song_title[20]; +- char song_author[20]; +- +- struct cff_event +- { +- unsigned char byte0; +- unsigned char byte1; +- unsigned char byte2; +- }; +-}; +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/cmf.cc audacious-plugins-3.9/src/adplug/core/cmf.cc +--- audacious-plugins-3.9-orig/src/adplug/core/cmf.cc 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/cmf.cc 1970-01-01 01:00:00.000000000 +0100 +@@ -1,787 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2009 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * cmf.cpp - CMF player by Adam Nielsen +- * Subset of CMF reader in MOPL code (Malvineous' OPL player), no seeking etc. +- */ +- +-#include // for uintxx_t +-#include +-#include // for pow() etc. +-#include // for memset +-#include "debug.h" +-#include "cmf.h" +- +-// ------------------------------ +-// OPTIONS +-// ------------------------------ +- +-// The official Creative Labs CMF player seems to ignore the note velocity +-// (playing every note at the same volume), but you can uncomment this to +-// allow the note velocity to affect the volume (as presumably the composer +-// originally intended.) +-// +-//#define USE_VELOCITY +-// +-// The Xargon demo song is a good example of a song that uses note velocity. +- +-// OPL register offsets +-#define BASE_CHAR_MULT 0x20 +-#define BASE_SCAL_LEVL 0x40 +-#define BASE_ATCK_DCAY 0x60 +-#define BASE_SUST_RLSE 0x80 +-#define BASE_FNUM_L 0xA0 +-#define BASE_KEYON_FREQ 0xB0 +-#define BASE_RHYTHM 0xBD +-#define BASE_WAVE 0xE0 +-#define BASE_FEED_CONN 0xC0 +- +-#define OPLBIT_KEYON 0x20 // Bit in BASE_KEYON_FREQ register for turning a note on +- +-// Supplied with a channel, return the offset from a base OPL register for the +-// Modulator cell (e.g. channel 4's modulator is at offset 0x09. Since 0x60 is +-// the attack/decay function, register 0x69 will thus set the attack/decay for +-// channel 4's modulator.) (channels go from 0 to 8 inclusive) +-#define OPLOFFSET(channel) (((channel) / 3) * 8 + ((channel) % 3)) +- +-// These 16 instruments are repeated to fill up the 128 available slots. A CMF +-// file can override none/some/all of the 128 slots with custom instruments, +-// so any that aren't overridden are still available for use with these default +-// patches. The Word Rescue CMFs are good examples of songs that rely on these +-// default patches. +-uint8_t cDefaultPatches[] = +-"\x01\x11\x4F\x00\xF1\xD2\x53\x74\x00\x00\x06" +-"\x07\x12\x4F\x00\xF2\xF2\x60\x72\x00\x00\x08" +-"\x31\xA1\x1C\x80\x51\x54\x03\x67\x00\x00\x0E" +-"\x31\xA1\x1C\x80\x41\x92\x0B\x3B\x00\x00\x0E" +-"\x31\x16\x87\x80\xA1\x7D\x11\x43\x00\x00\x08" +-"\x30\xB1\xC8\x80\xD5\x61\x19\x1B\x00\x00\x0C" +-"\xF1\x21\x01\x00\x97\xF1\x17\x18\x00\x00\x08" +-"\x32\x16\x87\x80\xA1\x7D\x10\x33\x00\x00\x08" +-"\x01\x12\x4F\x00\x71\x52\x53\x7C\x00\x00\x0A" +-"\x02\x03\x8D\x00\xD7\xF5\x37\x18\x00\x00\x04" +-"\x21\x21\xD1\x00\xA3\xA4\x46\x25\x00\x00\x0A" +-"\x22\x22\x0F\x00\xF6\xF6\x95\x36\x00\x00\x0A" +-"\xE1\xE1\x00\x00\x44\x54\x24\x34\x02\x02\x07" +-"\xA5\xB1\xD2\x80\x81\xF1\x03\x05\x00\x00\x02" +-"\x71\x22\xC5\x00\x6E\x8B\x17\x0E\x00\x00\x02" +-"\x32\x21\x16\x80\x73\x75\x24\x57\x00\x00\x0E"; +- +- +-CPlayer *CcmfPlayer::factory(Copl *newopl) +-{ +- return new CcmfPlayer(newopl); +-} +- +-CcmfPlayer::CcmfPlayer(Copl *newopl) : +- CPlayer(newopl), +- data(NULL), +- pInstruments(NULL), +- bPercussive(false), +- iTranspose(0), +- iPrevCommand(0) +-{ +- assert(OPLOFFSET(1-1) == 0x00); +- assert(OPLOFFSET(5-1) == 0x09); +- assert(OPLOFFSET(9-1) == 0x12); +-} +- +-CcmfPlayer::~CcmfPlayer() +-{ +- if (this->data) delete[] data; +- if (this->pInstruments) delete[] pInstruments; +-} +- +-bool CcmfPlayer::load(const std::string &filename, const CFileProvider &fp) +-{ +- binistream *f = fp.open(filename); if(!f) return false; +- +- char cSig[4]; +- f->readString(cSig, 4); +- if ( +- (cSig[0] != 'C') || +- (cSig[1] != 'T') || +- (cSig[2] != 'M') || +- (cSig[3] != 'F') +- ) { +- // Not a CMF file +- fp.close(f); +- return false; +- } +- uint16_t iVer = f->readInt(2); +- if ((iVer != 0x0101) && (iVer != 0x0100)) { +- AdPlug_LogWrite("CMF file is not v1.0 or v1.1 (reports %d.%d)\n", iVer >> 8 , iVer & 0xFF); +- fp.close(f); +- return false; +- } +- +- this->cmfHeader.iInstrumentBlockOffset = f->readInt(2); +- this->cmfHeader.iMusicOffset = f->readInt(2); +- this->cmfHeader.iTicksPerQuarterNote = f->readInt(2); +- this->cmfHeader.iTicksPerSecond = f->readInt(2); +- this->cmfHeader.iTagOffsetTitle = f->readInt(2); +- this->cmfHeader.iTagOffsetComposer = f->readInt(2); +- this->cmfHeader.iTagOffsetRemarks = f->readInt(2); +- f->readString((char *)this->cmfHeader.iChannelsInUse, 16); +- if (iVer == 0x0100) { +- this->cmfHeader.iNumInstruments = f->readInt(1); +- this->cmfHeader.iTempo = 0; +- } else { // 0x0101 +- this->cmfHeader.iNumInstruments = f->readInt(2); +- this->cmfHeader.iTempo = f->readInt(2); +- } +- +- // Load the instruments +- +- f->seek(this->cmfHeader.iInstrumentBlockOffset); +- this->pInstruments = new SBI[ +- (this->cmfHeader.iNumInstruments < 128) ? 128 : this->cmfHeader.iNumInstruments +- ]; // Always at least 128 available for use +- +- for (int i = 0; i < this->cmfHeader.iNumInstruments; i++) { +- this->pInstruments[i].op[0].iCharMult = f->readInt(1); +- this->pInstruments[i].op[1].iCharMult = f->readInt(1); +- this->pInstruments[i].op[0].iScalingOutput = f->readInt(1); +- this->pInstruments[i].op[1].iScalingOutput = f->readInt(1); +- this->pInstruments[i].op[0].iAttackDecay = f->readInt(1); +- this->pInstruments[i].op[1].iAttackDecay = f->readInt(1); +- this->pInstruments[i].op[0].iSustainRelease = f->readInt(1); +- this->pInstruments[i].op[1].iSustainRelease = f->readInt(1); +- this->pInstruments[i].op[0].iWaveSel = f->readInt(1); +- this->pInstruments[i].op[1].iWaveSel = f->readInt(1); +- this->pInstruments[i].iConnection = f->readInt(1); +- f->seek(5, binio::Add); // skip over the padding bytes +- } +- +- // Set the rest of the instruments to the CMF defaults +- for (int i = this->cmfHeader.iNumInstruments; i < 128; i++) { +- this->pInstruments[i].op[0].iCharMult = cDefaultPatches[(i % 16) * 11 + 0]; +- this->pInstruments[i].op[1].iCharMult = cDefaultPatches[(i % 16) * 11 + 1]; +- this->pInstruments[i].op[0].iScalingOutput = cDefaultPatches[(i % 16) * 11 + 2]; +- this->pInstruments[i].op[1].iScalingOutput = cDefaultPatches[(i % 16) * 11 + 3]; +- this->pInstruments[i].op[0].iAttackDecay = cDefaultPatches[(i % 16) * 11 + 4]; +- this->pInstruments[i].op[1].iAttackDecay = cDefaultPatches[(i % 16) * 11 + 5]; +- this->pInstruments[i].op[0].iSustainRelease = cDefaultPatches[(i % 16) * 11 + 6]; +- this->pInstruments[i].op[1].iSustainRelease = cDefaultPatches[(i % 16) * 11 + 7]; +- this->pInstruments[i].op[0].iWaveSel = cDefaultPatches[(i % 16) * 11 + 8]; +- this->pInstruments[i].op[1].iWaveSel = cDefaultPatches[(i % 16) * 11 + 9]; +- this->pInstruments[i].iConnection = cDefaultPatches[(i % 16) * 11 + 10]; +- } +- +- if (this->cmfHeader.iTagOffsetTitle) { +- f->seek(this->cmfHeader.iTagOffsetTitle); +- this->strTitle = f->readString('\0'); +- } +- if (this->cmfHeader.iTagOffsetComposer) { +- f->seek(this->cmfHeader.iTagOffsetComposer); +- this->strComposer = f->readString('\0'); +- } +- if (this->cmfHeader.iTagOffsetRemarks) { +- f->seek(this->cmfHeader.iTagOffsetRemarks); +- this->strRemarks = f->readString('\0'); +- } +- +- // Load the MIDI data into memory +- f->seek(this->cmfHeader.iMusicOffset); +- this->iSongLen = fp.filesize(f) - this->cmfHeader.iMusicOffset; +- this->data = new unsigned char[this->iSongLen]; +- f->readString((char *)data, this->iSongLen); +- +- fp.close(f); +- rewind(0); +- +- return true; +-} +- +-bool CcmfPlayer::update() +-{ +- // This has to be here and not in getrefresh() for some reason. +- this->iDelayRemaining = 0; +- +- // Read in the next event +- while (!this->iDelayRemaining) { +- uint8_t iCommand = this->data[this->iPlayPointer++]; +- if ((iCommand & 0x80) == 0) { +- // Running status, use previous command +- this->iPlayPointer--; +- iCommand = this->iPrevCommand; +- } else { +- this->iPrevCommand = iCommand; +- } +- uint8_t iChannel = iCommand & 0x0F; +- switch (iCommand & 0xF0) { +- case 0x80: { // Note off (two data bytes) +- uint8_t iNote = this->data[this->iPlayPointer++]; +- uint8_t iVelocity = this->data[this->iPlayPointer++]; // release velocity +- this->cmfNoteOff(iChannel, iNote, iVelocity); +- break; +- } +- case 0x90: { // Note on (two data bytes) +- uint8_t iNote = this->data[this->iPlayPointer++]; +- uint8_t iVelocity = this->data[this->iPlayPointer++]; // attack velocity +- if (iVelocity) { +- this->cmfNoteOn(iChannel, iNote, iVelocity); +- } else { +- // This is a note-off instead (velocity == 0) +- this->cmfNoteOff(iChannel, iNote, iVelocity); // 64 is the MIDI default note-off velocity +- break; +- } +- break; +- } +- case 0xA0: { // Polyphonic key pressure (two data bytes) +- uint8_t iNote = this->data[this->iPlayPointer++]; +- uint8_t iPressure = this->data[this->iPlayPointer++]; +- AdPlug_LogWrite("CMF: Key pressure not yet implemented! (wanted ch%d/note %d set to %d)\n", iChannel, iNote, iPressure); +- break; +- } +- case 0xB0: { // Controller (two data bytes) +- uint8_t iController = this->data[this->iPlayPointer++]; +- uint8_t iValue = this->data[this->iPlayPointer++]; +- this->MIDIcontroller(iChannel, iController, iValue); +- break; +- } +- case 0xC0: { // Instrument change (one data byte) +- uint8_t iNewInstrument = this->data[this->iPlayPointer++]; +- this->chMIDI[iChannel].iPatch = iNewInstrument; +- AdPlug_LogWrite("CMF: Remembering MIDI channel %d now uses patch %d\n", iChannel, iNewInstrument); +- break; +- } +- case 0xD0: { // Channel pressure (one data byte) +- uint8_t iPressure = this->data[this->iPlayPointer++]; +- AdPlug_LogWrite("CMF: Channel pressure not yet implemented! (wanted ch%d set to %d)\n", iChannel, iPressure); +- break; +- } +- case 0xE0: { // Pitch bend (two data bytes) +- uint8_t iLSB = this->data[this->iPlayPointer++]; +- uint8_t iMSB = this->data[this->iPlayPointer++]; +- uint16_t iValue = (iMSB << 7) | iLSB; +- // 8192 is middle/off, 0 is -2 semitones, 16384 is +2 semitones +- this->chMIDI[iChannel].iPitchbend = iValue; +- AdPlug_LogWrite("CMF: Channel %d pitchbent to %d (%+.2f)\n", iChannel + 1, iValue, (float)(iValue - 8192) / 8192); +- break; +- } +- case 0xF0: // System message (arbitrary data bytes) +- switch (iCommand) { +- case 0xF0: { // Sysex +- uint8_t iNextByte; +- AdPlug_LogWrite("Sysex message: "); +- do { +- iNextByte = this->data[this->iPlayPointer++]; +- AdPlug_LogWrite("%02X", iNextByte); +- } while ((iNextByte & 0x80) == 0); +- AdPlug_LogWrite("\n"); +- // This will have read in the terminating EOX (0xF7) message too +- break; +- } +- case 0xF1: // MIDI Time Code Quarter Frame +- this->iPlayPointer++; // message data (ignored) +- break; +- case 0xF2: // Song position pointer +- this->iPlayPointer++; // message data (ignored) +- this->iPlayPointer++; +- break; +- case 0xF3: // Song select +- this->iPlayPointer++; // message data (ignored) +- AdPlug_LogWrite("CMF: MIDI Song Select is not implemented.\n"); +- break; +- case 0xF6: // Tune request +- break; +- case 0xF7: // End of System Exclusive (EOX) - should never be read, should be absorbed by Sysex handling code +- break; +- +- // These messages are "real time", meaning they can be sent between +- // the bytes of other messages - but we're lazy and don't handle these +- // here (hopefully they're not necessary in a MIDI file, and even less +- // likely to occur in a CMF.) +- case 0xF8: // Timing clock (sent 24 times per quarter note, only when playing) +- case 0xFA: // Start +- case 0xFB: // Continue +- case 0xFE: // Active sensing (sent every 300ms or MIDI connection assumed lost) +- break; +- case 0xFC: // Stop +- AdPlug_LogWrite("CMF: Received Real Time Stop message (0xFC)\n"); +- this->bSongEnd = true; +- this->iPlayPointer = 0; // for repeat in endless-play mode +- break; +- case 0xFF: { // System reset, used as meta-events in a MIDI file +- uint8_t iEvent = this->data[this->iPlayPointer++]; +- switch (iEvent) { +- case 0x2F: // end of track +- AdPlug_LogWrite("CMF: End-of-track, stopping playback\n"); +- this->bSongEnd = true; +- this->iPlayPointer = 0; // for repeat in endless-play mode +- break; +- default: +- AdPlug_LogWrite("CMF: Unknown MIDI meta-event 0xFF 0x%02X\n", iEvent); +- break; +- } +- break; +- } +- default: +- AdPlug_LogWrite("CMF: Unknown MIDI system command 0x%02X\n", iCommand); +- break; +- } +- break; +- default: +- AdPlug_LogWrite("CMF: Unknown MIDI command 0x%02X\n", iCommand); +- break; +- } +- +- if (this->iPlayPointer >= this->iSongLen) { +- this->bSongEnd = true; +- this->iPlayPointer = 0; // for repeat in endless-play mode +- } +- +- // Read in the number of ticks until the next event +- this->iDelayRemaining = this->readMIDINumber(); +- } +- +- return !this->bSongEnd; +-} +- +-void CcmfPlayer::rewind(int subsong) +-{ +- this->opl->init(); +- +- // Initialise +- +- // Enable use of WaveSel register on OPL3 (even though we're only an OPL2!) +- // Apparently this enables nine-channel mode? +- this->writeOPL(0x01, 0x20); +- +- // Disable OPL3 mode (can be left enabled by a previous non-CMF song) +- this->writeOPL(0x05, 0x00); +- +- // Really make sure CSM+SEL are off (again, Creative's player...) +- this->writeOPL(0x08, 0x00); +- +- // This freq setting is required for the hihat to sound correct at the start +- // of funky.cmf, even though it's for an unrelated channel. +- // If it's here however, it makes the hihat in Word Rescue's theme.cmf +- // sound really bad. +- // TODO: How do we figure out whether we need it or not??? +- this->writeOPL(BASE_FNUM_L + 8, 514 & 0xFF); +- this->writeOPL(BASE_KEYON_FREQ + 8, (1 << 2) | (514 >> 8)); +- +- // default freqs? +- this->writeOPL(BASE_FNUM_L + 7, 509 & 0xFF); +- this->writeOPL(BASE_KEYON_FREQ + 7, (2 << 2) | (509 >> 8)); +- this->writeOPL(BASE_FNUM_L + 6, 432 & 0xFF); +- this->writeOPL(BASE_KEYON_FREQ + 6, (2 << 2) | (432 >> 8)); +- +- // Amplify AM + VIB depth. Creative's CMF player does this, and there +- // doesn't seem to be any way to stop it from doing so - except for the +- // non-standard controller 0x63 I added :-) +- this->writeOPL(0xBD, 0xC0); +- +- this->bSongEnd = false; +- this->iPlayPointer = 0; +- this->iPrevCommand = 0; // just in case +- +- // Read in the number of ticks until the first event +- this->iDelayRemaining = this->readMIDINumber(); +- +- // Reset song state. This used to be in the constructor, but the XMMS2 +- // plugin sets the song length before starting playback. AdPlug plays the +- // song in its entirety (with no synth) to determine the song length, which +- // results in the state variables below matching the end of the song. When +- // the real OPL synth is activated for playback, it no longer matches the +- // state variables and the instruments are not set correctly! +- for (int i = 0; i < 9; i++) { +- this->chOPL[i].iNoteStart = 0; // no note playing atm +- this->chOPL[i].iMIDINote = -1; +- this->chOPL[i].iMIDIChannel = -1; +- this->chOPL[i].iMIDIPatch = -1; +- +- this->chMIDI[i].iPatch = -2; +- this->chMIDI[i].iPitchbend = 8192; +- } +- for (int i = 9; i < 16; i++) { +- this->chMIDI[i].iPatch = -2; +- this->chMIDI[i].iPitchbend = 8192; +- } +- +- memset(this->iCurrentRegs, 0, 256); +- +- return; +-} +- +-// Return value: 1 == 1 second, 2 == 0.5 seconds +-float CcmfPlayer::getrefresh() +-{ +- if (this->iDelayRemaining) { +- return (float)this->cmfHeader.iTicksPerSecond / (float)this->iDelayRemaining; +- } else { +- // Delay-remaining is zero (e.g. start of song) so use a tiny delay +- return this->cmfHeader.iTicksPerSecond; // wait for one tick +- } +-} +- +-std::string CcmfPlayer::gettitle() +-{ +- return this->strTitle; +-} +-std::string CcmfPlayer::getauthor() +-{ +- return this->strComposer; +-} +-std::string CcmfPlayer::getdesc() +-{ +- return this->strRemarks; +-} +- +- +-// +-// PROTECTED +-// +- +-// Read a variable-length integer from MIDI data +-uint32_t CcmfPlayer::readMIDINumber() +-{ +- uint32_t iValue = 0; +- for (int i = 0; i < 4; i++) { +- uint8_t iNext = this->data[this->iPlayPointer++]; +- iValue <<= 7; +- iValue |= (iNext & 0x7F); // ignore the MSB +- if ((iNext & 0x80) == 0) break; // last byte has the MSB unset +- } +- return iValue; +-} +- +-// iChannel: OPL channel (0-8) +-// iOperator: 0 == Modulator, 1 == Carrier +-// Source - source operator to read from instrument definition +-// Dest - destination operator on OPL chip +-// iInstrument: Index into this->pInstruments array of CMF instruments +-void CcmfPlayer::writeInstrumentSettings(uint8_t iChannel, uint8_t iOperatorSource, uint8_t iOperatorDest, uint8_t iInstrument) +-{ +- assert(iChannel <= 8); +- +- uint8_t iOPLOffset = OPLOFFSET(iChannel); +- if (iOperatorDest) iOPLOffset += 3; // Carrier if iOperator == 1 (else Modulator) +- +- this->writeOPL(BASE_CHAR_MULT + iOPLOffset, this->pInstruments[iInstrument].op[iOperatorSource].iCharMult); +- this->writeOPL(BASE_SCAL_LEVL + iOPLOffset, this->pInstruments[iInstrument].op[iOperatorSource].iScalingOutput); +- this->writeOPL(BASE_ATCK_DCAY + iOPLOffset, this->pInstruments[iInstrument].op[iOperatorSource].iAttackDecay); +- this->writeOPL(BASE_SUST_RLSE + iOPLOffset, this->pInstruments[iInstrument].op[iOperatorSource].iSustainRelease); +- this->writeOPL(BASE_WAVE + iOPLOffset, this->pInstruments[iInstrument].op[iOperatorSource].iWaveSel); +- +- // TODO: Check to see whether we should only be loading this for one or both operators +- this->writeOPL(BASE_FEED_CONN + iChannel, this->pInstruments[iInstrument].iConnection); +- return; +-} +- +-// Write a byte to the OPL "chip" and update the current record of register states +-void CcmfPlayer::writeOPL(uint8_t iRegister, uint8_t iValue) +-{ +- this->opl->write(iRegister, iValue); +- this->iCurrentRegs[iRegister] = iValue; +- return; +-} +- +-void CcmfPlayer::cmfNoteOn(uint8_t iChannel, uint8_t iNote, uint8_t iVelocity) +-{ +- uint8_t iBlock = iNote / 12; +- if (iBlock > 1) iBlock--; // keep in the same range as the Creative player +- //if (iBlock > 7) iBlock = 7; // don't want to go out of range +- +- double d = pow(2, ( +- (double)iNote + ( +- (this->chMIDI[iChannel].iPitchbend - 8192) / 8192.0 +- ) + ( +- this->iTranspose / 128 +- ) - 9) / 12.0 - (iBlock - 20)) +- * 440.0 / 32.0 / 50000.0; +- uint16_t iOPLFNum = (uint16_t)(d+0.5); +- if (iOPLFNum > 1023) AdPlug_LogWrite("CMF: This note is out of range! (send this song to malvineous@shikadi.net!)\n"); +- +- // See if we're playing a rhythm mode percussive instrument +- if ((iChannel > 10) && (this->bPercussive)) { +- uint8_t iPercChannel = this->getPercChannel(iChannel); +- +- // Will have to set every time (easier) than figuring out whether the mod +- // or car needs to be changed. +- //if (this->chOPL[iPercChannel].iMIDIPatch != this->chMIDI[iChannel].iPatch) { +- this->MIDIchangeInstrument(iPercChannel, iChannel, this->chMIDI[iChannel].iPatch); +- //} +- +- /* Velocity calculations - TODO: Work out the proper formula +- +- iVelocity -> iLevel (values generated by Creative's player) +- 7f -> 00 +- 7c -> 00 +- +- 7b -> 09 +- 73 -> 0a +- 6b -> 0b +- 63 -> 0c +- 5b -> 0d +- 53 -> 0e +- 4b -> 0f +- 43 -> 10 +- 3b -> 11 +- 33 -> 13 +- 2b -> 15 +- 23 -> 19 +- 1b -> 1b +- 13 -> 1d +- 0b -> 1f +- 03 -> 21 +- +- 02 -> 21 +- 00 -> N/A (note off) +- */ +- // Approximate formula, need to figure out more accurate one (my maths isn't so good...) +- int iLevel = 0x25 - sqrt(iVelocity * 16/*6*/);//(127 - iVelocity) * 0x20 / 127; +- if (iVelocity > 0x7b) iLevel = 0; // full volume +- if (iLevel < 0) iLevel = 0; +- if (iLevel > 0x3F) iLevel = 0x3F; +- //if (iVelocity < 0x40) iLevel = 0x10; +- +- int iOPLOffset = BASE_SCAL_LEVL + OPLOFFSET(iPercChannel); +- //if ((iChannel == 11) || (iChannel == 12) || (iChannel == 14)) { +- if (iChannel == 11) iOPLOffset += 3; // only do bassdrum carrier for volume control +- //iOPLOffset += 3; // carrier +- this->writeOPL(iOPLOffset, (this->iCurrentRegs[iOPLOffset] & ~0x3F) | iLevel);//(iVelocity * 0x3F / 127)); +- //} +- // Bass drum (ch11) uses both operators +- //if (iChannel == 11) this->writeOPL(iOPLOffset + 3, (this->iCurrentRegs[iOPLOffset + 3] & ~0x3F) | iLevel); +- +-/* #ifdef USE_VELOCITY // Official CMF player seems to ignore velocity levels +- uint16_t iLevel = 0x2F - (iVelocity * 0x2F / 127); // 0x2F should be 0x3F but it's too quiet then +- AdPlug_LogWrite("%02X + vel %d (lev %02X) == %02X\n", this->iCurrentRegs[iOPLOffset], iVelocity, iLevel, (this->iCurrentRegs[iOPLOffset] & ~0x3F) | iLevel); +- //this->writeOPL(iOPLOffset, (this->iCurrentRegs[iOPLOffset] & ~0x3F) | (0x3F - (iVelocity >> 1)));//(iVelocity * 0x3F / 127)); +- this->writeOPL(iOPLOffset, (this->iCurrentRegs[iOPLOffset] & ~0x3F) | iLevel);//(iVelocity * 0x3F / 127)); +- #endif*/ +- +- // Apparently you can't set the frequency for the cymbal or hihat? +- // Vinyl requires you don't set it, Kiloblaster requires you do! +- this->writeOPL(BASE_FNUM_L + iPercChannel, iOPLFNum & 0xFF); +- this->writeOPL(BASE_KEYON_FREQ + iPercChannel, (iBlock << 2) | ((iOPLFNum >> 8) & 0x03)); +- +- uint8_t iBit = 1 << (15 - iChannel); +- +- // Turn the perc instrument off if it's already playing (OPL can't do +- // polyphonic notes w/ percussion) +- if (this->iCurrentRegs[BASE_RHYTHM] & iBit) this->writeOPL(BASE_RHYTHM, this->iCurrentRegs[BASE_RHYTHM] & ~iBit); +- +- // I wonder whether we need to delay or anything here? +- +- // Turn the note on +- //if (iChannel == 15) { +- this->writeOPL(BASE_RHYTHM, this->iCurrentRegs[BASE_RHYTHM] | iBit); +- //AdPlug_LogWrite("CMF: Note %d on MIDI channel %d (mapped to OPL channel %d-1) - vel %02X, fnum %d/%d\n", iNote, iChannel, iPercChannel+1, iVelocity, iOPLFNum, iBlock); +- //} +- +- this->chOPL[iPercChannel].iNoteStart = ++this->iNoteCount; +- this->chOPL[iPercChannel].iMIDIChannel = iChannel; +- this->chOPL[iPercChannel].iMIDINote = iNote; +- +- } else { // Non rhythm-mode or a normal instrument channel +- +- // Figure out which OPL channel to play this note on +- int iOPLChannel = -1; +- int iNumChannels = this->bPercussive ? 6 : 9; +- for (int i = iNumChannels - 1; i >= 0; i--) { +- // If there's no note playing on this OPL channel, use that +- if (this->chOPL[i].iNoteStart == 0) { +- iOPLChannel = i; +- // See if this channel is already set to the instrument we want. +- if (this->chOPL[i].iMIDIPatch == this->chMIDI[iChannel].iPatch) { +- // It is, so stop searching +- break; +- } // else keep searching just in case there's a better match +- } +- } +- if (iOPLChannel == -1) { +- // All channels were in use, find the one with the longest note +- iOPLChannel = 0; +- int iEarliest = this->chOPL[0].iNoteStart; +- for (int i = 1; i < iNumChannels; i++) { +- if (this->chOPL[i].iNoteStart < iEarliest) { +- // Found a channel with a note being played for longer +- iOPLChannel = i; +- iEarliest = this->chOPL[i].iNoteStart; +- } +- } +- AdPlug_LogWrite("CMF: Too many polyphonic notes, cutting note on channel %d\n", iOPLChannel); +- } +- +- // Run through all the channels with negative notestart values - these +- // channels have had notes recently stop - and increment the counter +- // to slowly move the channel closer to being reused for a future note. +- //for (int i = 0; i < iNumChannels; i++) { +- // if (this->chOPL[i].iNoteStart < 0) this->chOPL[i].iNoteStart++; +- //} +- +- // Now the new note should be played on iOPLChannel, but see if the instrument +- // is right first. +- if (this->chOPL[iOPLChannel].iMIDIPatch != this->chMIDI[iChannel].iPatch) { +- this->MIDIchangeInstrument(iOPLChannel, iChannel, this->chMIDI[iChannel].iPatch); +- } +- +- this->chOPL[iOPLChannel].iNoteStart = ++this->iNoteCount; +- this->chOPL[iOPLChannel].iMIDIChannel = iChannel; +- this->chOPL[iOPLChannel].iMIDINote = iNote; +- +- #ifdef USE_VELOCITY // Official CMF player seems to ignore velocity levels +- // Adjust the channel volume to match the note velocity +- uint8_t iOPLOffset = BASE_SCAL_LEVL + OPLOFFSET(iChannel) + 3; // +3 == Carrier +- uint16_t iLevel = 0x2F - (iVelocity * 0x2F / 127); // 0x2F should be 0x3F but it's too quiet then +- this->writeOPL(iOPLOffset, (this->iCurrentRegs[iOPLOffset] & ~0x3F) | iLevel); +- #endif +- +- // Set the frequency and play the note +- this->writeOPL(BASE_FNUM_L + iOPLChannel, iOPLFNum & 0xFF); +- this->writeOPL(BASE_KEYON_FREQ + iOPLChannel, OPLBIT_KEYON | (iBlock << 2) | ((iOPLFNum & 0x300) >> 8)); +- } +- return; +-} +- +-void CcmfPlayer::cmfNoteOff(uint8_t iChannel, uint8_t iNote, uint8_t iVelocity) +-{ +- if ((iChannel > 10) && (this->bPercussive)) { +- int iOPLChannel = this->getPercChannel(iChannel); +- if (this->chOPL[iOPLChannel].iMIDINote != iNote) return; // there's a different note playing now +- this->writeOPL(BASE_RHYTHM, this->iCurrentRegs[BASE_RHYTHM] & ~(1 << (15 - iChannel))); +- this->chOPL[iOPLChannel].iNoteStart = 0; // channel free +- } else { // Non rhythm-mode or a normal instrument channel +- int iOPLChannel = -1; +- int iNumChannels = this->bPercussive ? 6 : 9; +- for (int i = 0; i < iNumChannels; i++) { +- if ( +- (this->chOPL[i].iMIDIChannel == iChannel) && +- (this->chOPL[i].iMIDINote == iNote) && +- (this->chOPL[i].iNoteStart != 0) +- ) { +- // Found the note, switch it off +- this->chOPL[i].iNoteStart = 0; +- iOPLChannel = i; +- break; +- } +- } +- if (iOPLChannel == -1) return; +- +- this->writeOPL(BASE_KEYON_FREQ + iOPLChannel, this->iCurrentRegs[BASE_KEYON_FREQ + iOPLChannel] & ~OPLBIT_KEYON); +- } +- return; +-} +- +-uint8_t CcmfPlayer::getPercChannel(uint8_t iChannel) +-{ +- switch (iChannel) { +- case 11: return 7-1; // Bass drum +- case 12: return 8-1; // Snare drum +- case 13: return 9-1; // Tom tom +- case 14: return 9-1; // Top cymbal +- case 15: return 8-1; // Hihat +- } +- AdPlug_LogWrite("CMF ERR: Tried to get the percussion channel from MIDI channel %d - this shouldn't happen!\n", iChannel); +- return 0; +-} +- +- +-void CcmfPlayer::MIDIchangeInstrument(uint8_t iOPLChannel, uint8_t iMIDIChannel, uint8_t iNewInstrument) +-{ +- if ((iMIDIChannel > 10) && (this->bPercussive)) { +- switch (iMIDIChannel) { +- case 11: // Bass drum (operator 13+16 == channel 7 modulator+carrier) +- this->writeInstrumentSettings(7-1, 0, 0, iNewInstrument); +- this->writeInstrumentSettings(7-1, 1, 1, iNewInstrument); +- break; +- case 12: // Snare drum (operator 17 == channel 8 carrier) +- //case 15: +- this->writeInstrumentSettings(8-1, 0, 1, iNewInstrument); +- +- // +- //this->writeInstrumentSettings(8-1, 0, 0, iNewInstrument); +- break; +- case 13: // Tom tom (operator 15 == channel 9 modulator) +- //case 14: +- this->writeInstrumentSettings(9-1, 0, 0, iNewInstrument); +- +- // +- //this->writeInstrumentSettings(9-1, 0, 1, iNewInstrument); +- break; +- case 14: // Top cymbal (operator 18 == channel 9 carrier) +- this->writeInstrumentSettings(9-1, 0, 1, iNewInstrument); +- break; +- case 15: // Hi-hat (operator 14 == channel 8 modulator) +- this->writeInstrumentSettings(8-1, 0, 0, iNewInstrument); +- break; +- default: +- AdPlug_LogWrite("CMF: Invalid MIDI channel %d (not melodic and not percussive!)\n", iMIDIChannel + 1); +- break; +- } +- this->chOPL[iOPLChannel].iMIDIPatch = iNewInstrument; +- } else { +- // Standard nine OPL channels +- this->writeInstrumentSettings(iOPLChannel, 0, 0, iNewInstrument); +- this->writeInstrumentSettings(iOPLChannel, 1, 1, iNewInstrument); +- this->chOPL[iOPLChannel].iMIDIPatch = iNewInstrument; +- } +- return; +-} +- +-void CcmfPlayer::MIDIcontroller(uint8_t iChannel, uint8_t iController, uint8_t iValue) +-{ +- switch (iController) { +- case 0x63: +- // Custom extension to allow CMF files to switch the AM+VIB depth on and +- // off (officially both are on, and there's no way to switch them off.) +- // Controller values: +- // 0 == AM+VIB off +- // 1 == VIB on +- // 2 == AM on +- // 3 == AM+VIB on +- if (iValue) { +- this->writeOPL(BASE_RHYTHM, (this->iCurrentRegs[BASE_RHYTHM] & ~0xC0) | (iValue << 6)); // switch AM+VIB extension on +- } else { +- this->writeOPL(BASE_RHYTHM, this->iCurrentRegs[BASE_RHYTHM] & ~0xC0); // switch AM+VIB extension off +- } +- AdPlug_LogWrite("CMF: AM+VIB depth change - AM %s, VIB %s\n", +- (this->iCurrentRegs[BASE_RHYTHM] & 0x80) ? "on" : "off", +- (this->iCurrentRegs[BASE_RHYTHM] & 0x40) ? "on" : "off"); +- break; +- case 0x66: +- AdPlug_LogWrite("CMF: Song set marker to 0x%02X\n", iValue); +- break; +- case 0x67: +- this->bPercussive = (iValue != 0); +- if (this->bPercussive) { +- this->writeOPL(BASE_RHYTHM, this->iCurrentRegs[BASE_RHYTHM] | 0x20); // switch rhythm-mode on +- } else { +- this->writeOPL(BASE_RHYTHM, this->iCurrentRegs[BASE_RHYTHM] & ~0x20); // switch rhythm-mode off +- } +- AdPlug_LogWrite("CMF: Percussive/rhythm mode %s\n", this->bPercussive ? "enabled" : "disabled"); +- break; +- case 0x68: +- // TODO: Shouldn't this just affect the one channel, not the whole song? -- have pitchbends for that +- this->iTranspose = iValue; +- AdPlug_LogWrite("CMF: Transposing all notes up by %d * 1/128ths of a semitone.\n", iValue); +- break; +- case 0x69: +- this->iTranspose = -iValue; +- AdPlug_LogWrite("CMF: Transposing all notes down by %d * 1/128ths of a semitone.\n", iValue); +- break; +- default: +- AdPlug_LogWrite("CMF: Unsupported MIDI controller 0x%02X, ignoring.\n", iController); +- break; +- } +- return; +-} +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/cmf.h audacious-plugins-3.9/src/adplug/core/cmf.h +--- audacious-plugins-3.9-orig/src/adplug/core/cmf.h 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/cmf.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,112 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2009 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * cmf.h - CMF player by Adam Nielsen +- */ +- +-#include // for uintxx_t +-#include "player.h" +- +-typedef struct { +- uint16_t iInstrumentBlockOffset; +- uint16_t iMusicOffset; +- uint16_t iTicksPerQuarterNote; +- uint16_t iTicksPerSecond; +- uint16_t iTagOffsetTitle; +- uint16_t iTagOffsetComposer; +- uint16_t iTagOffsetRemarks; +- uint8_t iChannelsInUse[16]; +- uint16_t iNumInstruments; +- uint16_t iTempo; +-} CMFHEADER; +- +-typedef struct { +- uint8_t iCharMult; +- uint8_t iScalingOutput; +- uint8_t iAttackDecay; +- uint8_t iSustainRelease; +- uint8_t iWaveSel; +-} OPERATOR; +- +-typedef struct { +- OPERATOR op[2]; // 0 == modulator, 1 == carrier +- uint8_t iConnection; +-} SBI; +- +-typedef struct { +- int iPatch; // MIDI patch for this channel +- int iPitchbend; // Current pitchbend amount for this channel +-} MIDICHANNEL; +- +-typedef struct { +- int iNoteStart; // When the note started playing (longest notes get cut first, 0 == channel free) +- int iMIDINote; // MIDI note number currently being played on this OPL channel +- int iMIDIChannel; // Source MIDI channel where this note came from +- int iMIDIPatch; // Current MIDI patch set on this OPL channel +-} OPLCHANNEL; +- +-class CcmfPlayer: public CPlayer +-{ +- private: +- uint8_t *data; // song data (CMF music block) +- int iPlayPointer; // Current location of playback pointer +- int iSongLen; // Max value for iPlayPointer +- CMFHEADER cmfHeader; +- SBI *pInstruments; +- bool bPercussive; // are rhythm-mode instruments enabled? +- uint8_t iCurrentRegs[256]; // Current values in the OPL chip +- int iTranspose; // Transpose amount for entire song (between -128 and +128) +- uint8_t iPrevCommand; // Previous command (used for repeated MIDI commands, as the seek and playback code need to share this) +- +- int iNoteCount; // Used to count how long notes have been playing for +- MIDICHANNEL chMIDI[16]; +- OPLCHANNEL chOPL[9]; +- +- // Additions for AdPlug's design +- int iDelayRemaining; +- bool bSongEnd; +- std::string strTitle, strComposer, strRemarks; +- +- public: +- static CPlayer *factory(Copl *newopl); +- +- CcmfPlayer(Copl *newopl); +- ~CcmfPlayer(); +- +- bool load(const std::string &filename, const CFileProvider &fp); +- bool update(); +- void rewind(int subsong); +- float getrefresh(); +- +- std::string gettype() +- { return std::string("Creative Music File (CMF)"); }; +- std::string gettitle(); +- std::string getauthor(); +- std::string getdesc(); +- +- protected: +- uint32_t readMIDINumber(); +- void writeInstrumentSettings(uint8_t iChannel, uint8_t iOperatorSource, uint8_t iOperatorDest, uint8_t iInstrument); +- void writeOPL(uint8_t iRegister, uint8_t iValue); +- void cmfNoteOn(uint8_t iChannel, uint8_t iNote, uint8_t iVelocity); +- void cmfNoteOff(uint8_t iChannel, uint8_t iNote, uint8_t iVelocity); +- uint8_t getPercChannel(uint8_t iChannel); +- void MIDIchangeInstrument(uint8_t iOPLChannel, uint8_t iMIDIChannel, uint8_t iNewInstrument); +- void MIDIcontroller(uint8_t iChannel, uint8_t iController, uint8_t iValue); +- +-}; +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/d00.cc audacious-plugins-3.9/src/adplug/core/d00.cc +--- audacious-plugins-3.9-orig/src/adplug/core/d00.cc 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/d00.cc 1970-01-01 01:00:00.000000000 +0100 +@@ -1,549 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2008 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * d00.c - D00 Player by Simon Peter +- * +- * NOTES: +- * Sorry for the goto's, but the code looks so much nicer now. +- * I tried it with while loops but it was just a mess. If you +- * can come up with a nicer solution, just tell me. +- * +- * BUGS: +- * Hard restart SR is sometimes wrong +- */ +- +-#include +-#include +-#include +- +-#include "debug.h" +-#include "d00.h" +- +-#define HIBYTE(val) (val >> 8) +-#define LOBYTE(val) (val & 0xff) +- +-static const unsigned short notetable[12] = // D00 note table +- {340,363,385,408,432,458,485,514,544,577,611,647}; +- +-static inline uint16_t LE_WORD(const uint16_t *val) +-{ +- const uint8_t *b = (const uint8_t *)val; +- return (b[1] << 8) + b[0]; +-} +- +-/*** public methods *************************************/ +- +-CPlayer *Cd00Player::factory(Copl *newopl) +-{ +- return new Cd00Player(newopl); +-} +- +-bool Cd00Player::load(const std::string &filename, const CFileProvider &fp) +-{ +- binistream *f = fp.open(filename); if(!f) return false; +- d00header *checkhead; +- d00header1 *ch; +- unsigned long filesize; +- int i,ver1=0; +- char *str; +- +- // file validation section +- checkhead = new d00header; +- f->readString((char *)checkhead, sizeof(d00header)); +- +- // Check for version 2-4 header +- if(strncmp(checkhead->id,"JCH\x26\x02\x66",6) || checkhead->type || +- !checkhead->subsongs || checkhead->soundcard) { +- // Check for version 0 or 1 header (and .d00 file extension) +- delete checkhead; +- if(!fp.extension(filename, ".d00")) { fp.close(f); return false; } +- ch = new d00header1; +- f->seek(0); f->readString((char *)ch, sizeof(d00header1)); +- if(ch->version > 1 || !ch->subsongs) +- { delete ch; fp.close(f); return false; } +- delete ch; +- ver1 = 1; +- } else +- delete checkhead; +- +- AdPlug_LogWrite("Cd00Player::load(f,\"%s\"): %s format D00 file detected!\n", +- filename.c_str(), ver1 ? "Old" : "New"); +- +- // load section +- filesize = fp.filesize(f); f->seek(0); +- filedata = new char [filesize + 1]; // 1 byte is needed for old-style DataInfo block +- f->readString((char *)filedata, filesize); +- fp.close(f); +- if(!ver1) { // version 2 and above +- header = (struct d00header *)filedata; +- version = header->version; +- datainfo = (char *)filedata + LE_WORD(&header->infoptr); +- inst = (struct Sinsts *)((char *)filedata + LE_WORD(&header->instptr)); +- seqptr = (unsigned short *)((char *)filedata + LE_WORD(&header->seqptr)); +- for(i=31;i>=0;i--) // erase whitespace +- if(header->songname[i] == ' ') +- header->songname[i] = '\0'; +- else +- break; +- for(i=31;i>=0;i--) +- if(header->author[i] == ' ') +- header->author[i] = '\0'; +- else +- break; +- } else { // version 1 +- header1 = (struct d00header1 *)filedata; +- version = header1->version; +- datainfo = (char *)filedata + LE_WORD(&header1->infoptr); +- inst = (struct Sinsts *)((char *)filedata + LE_WORD(&header1->instptr)); +- seqptr = (unsigned short *)((char *)filedata + LE_WORD(&header1->seqptr)); +- } +- switch(version) { +- case 0: +- levpuls = 0; +- spfx = 0; +- header1->speed = 70; // v0 files default to 70Hz +- break; +- case 1: +- levpuls = (struct Slevpuls *)((char *)filedata + LE_WORD(&header1->lpulptr)); +- spfx = 0; +- break; +- case 2: +- levpuls = (struct Slevpuls *)((char *)filedata + LE_WORD(&header->spfxptr)); +- spfx = 0; +- break; +- case 3: +- spfx = 0; +- levpuls = 0; +- break; +- case 4: +- spfx = (struct Sspfx *)((char *)filedata + LE_WORD(&header->spfxptr)); +- levpuls = 0; +- break; +- } +- if((str = strstr(datainfo,"\xff\xff"))) +- while((*str == '\xff' || *str == ' ') && str >= datainfo) { +- *str = '\0'; str--; +- } +- else // old-style block +- memset((char *)filedata+filesize,0,1); +- +- rewind(0); +- return true; +-} +- +-bool Cd00Player::update() +-{ +- unsigned char c,cnt,trackend=0,fx,note; +- unsigned short ord,*patt,buf,fxop,pattpos; +- +- // effect handling (timer dependant) +- for(c=0;c<9;c++) { +- channel[c].slideval += channel[c].slide; setfreq(c); // sliding +- vibrato(c); // vibrato +- +- if(channel[c].spfx != 0xffff) { // SpFX +- if(channel[c].fxdel) +- channel[c].fxdel--; +- else { +- channel[c].spfx = LE_WORD(&spfx[channel[c].spfx].ptr); +- channel[c].fxdel = spfx[channel[c].spfx].duration; +- channel[c].inst = LE_WORD(&spfx[channel[c].spfx].instnr) & 0xfff; +- if(spfx[channel[c].spfx].modlev != 0xff) +- channel[c].modvol = spfx[channel[c].spfx].modlev; +- setinst(c); +- if(LE_WORD(&spfx[channel[c].spfx].instnr) & 0x8000) // locked frequency +- note = spfx[channel[c].spfx].halfnote; +- else // unlocked frequency +- note = spfx[channel[c].spfx].halfnote + channel[c].note; +- channel[c].freq = notetable[note%12] + ((note/12) << 10); +- setfreq(c); +- } +- channel[c].modvol += spfx[channel[c].spfx].modlevadd; channel[c].modvol &= 63; +- setvolume(c); +- } +- +- if(channel[c].levpuls != 0xff) { // Levelpuls +- if(channel[c].frameskip) +- channel[c].frameskip--; +- else { +- channel[c].frameskip = inst[channel[c].inst].timer; +- if(channel[c].fxdel) +- channel[c].fxdel--; +- else { +- channel[c].levpuls = levpuls[channel[c].levpuls].ptr - 1; +- channel[c].fxdel = levpuls[channel[c].levpuls].duration; +- if(levpuls[channel[c].levpuls].level != 0xff) +- channel[c].modvol = levpuls[channel[c].levpuls].level; +- } +- channel[c].modvol += levpuls[channel[c].levpuls].voladd; channel[c].modvol &= 63; +- setvolume(c); +- } +- } +- } +- +- // song handling +- for(c=0;c<9;c++) +- if(version < 3 ? channel[c].del : channel[c].del <= 0x7f) { +- if(version == 4) // v4: hard restart SR +- if(channel[c].del == inst[channel[c].inst].timer) +- if(channel[c].nextnote) +- opl->write(0x83 + op_table[c], inst[channel[c].inst].sr); +- if(version < 3) +- channel[c].del--; +- else +- if(channel[c].speed) +- channel[c].del += channel[c].speed; +- else { +- channel[c].seqend = 1; +- continue; +- } +- } else { +- if(channel[c].speed) { +- if(version < 3) +- channel[c].del = channel[c].speed; +- else { +- channel[c].del &= 0x7f; +- channel[c].del += channel[c].speed; +- } +- } else { +- channel[c].seqend = 1; +- continue; +- } +- if(channel[c].rhcnt) { // process pending REST/HOLD events +- channel[c].rhcnt--; +- continue; +- } +- readorder: // process arrangement (orderlist) +- ord = LE_WORD(&channel[c].order[channel[c].ordpos]); +- switch(ord) { +- case 0xfffe: channel[c].seqend = 1; continue; // end of arrangement stream +- case 0xffff: // jump to order +- channel[c].ordpos = LE_WORD(&channel[c].order[channel[c].ordpos + 1]); +- channel[c].seqend = 1; +- goto readorder; +- default: +- if(ord >= 0x9000) { // set speed +- channel[c].speed = ord & 0xff; +- ord = LE_WORD(&channel[c].order[channel[c].ordpos - 1]); +- channel[c].ordpos++; +- } else +- if(ord >= 0x8000) { // transpose track +- channel[c].transpose = ord & 0xff; +- if(ord & 0x100) +- channel[c].transpose = -channel[c].transpose; +- ord = LE_WORD(&channel[c].order[++channel[c].ordpos]); +- } +- patt = (unsigned short *)((char *)filedata + LE_WORD(&seqptr[ord])); +- break; +- } +- channel[c].fxflag = 0; +- readseq: // process sequence (pattern) +- if(!version) // v0: always initialize rhcnt +- channel[c].rhcnt = channel[c].irhcnt; +- pattpos = LE_WORD(&patt[channel[c].pattpos]); +- if(pattpos == 0xffff) { // pattern ended? +- channel[c].pattpos = 0; +- channel[c].ordpos++; +- goto readorder; +- } +- cnt = HIBYTE(pattpos); +- note = LOBYTE(pattpos); +- fx = pattpos >> 12; +- fxop = pattpos & 0x0fff; +- channel[c].pattpos++; pattpos = LE_WORD(&patt[channel[c].pattpos]); +- channel[c].nextnote = LOBYTE(pattpos) & 0x7f; +- if(version ? cnt < 0x40 : !fx) { // note event +- switch(note) { +- case 0: // REST event +- case 0x80: +- if(!note || version) { +- channel[c].key = 0; +- setfreq(c); +- } +- // fall through... +- case 0x7e: // HOLD event +- if(version) +- channel[c].rhcnt = cnt; +- channel[c].nextnote = 0; +- break; +- default: // play note +- // restart fx +- if(!(channel[c].fxflag & 1)) +- channel[c].vibdepth = 0; +- if(!(channel[c].fxflag & 2)) +- channel[c].slideval = channel[c].slide = 0; +- +- if(version) { // note handling for v1 and above +- if(note > 0x80) // locked note (no channel transpose) +- note -= 0x80; +- else // unlocked note +- note += channel[c].transpose; +- channel[c].note = note; // remember note for SpFX +- +- if(channel[c].ispfx != 0xffff && cnt < 0x20) { // reset SpFX +- channel[c].spfx = channel[c].ispfx; +- if(LE_WORD(&spfx[channel[c].spfx].instnr) & 0x8000) // locked frequency +- note = spfx[channel[c].spfx].halfnote; +- else // unlocked frequency +- note += spfx[channel[c].spfx].halfnote; +- channel[c].inst = LE_WORD(&spfx[channel[c].spfx].instnr) & 0xfff; +- channel[c].fxdel = spfx[channel[c].spfx].duration; +- if(spfx[channel[c].spfx].modlev != 0xff) +- channel[c].modvol = spfx[channel[c].spfx].modlev; +- else +- channel[c].modvol = inst[channel[c].inst].data[7] & 63; +- } +- +- if(channel[c].ilevpuls != 0xff && cnt < 0x20) { // reset LevelPuls +- channel[c].levpuls = channel[c].ilevpuls; +- channel[c].fxdel = levpuls[channel[c].levpuls].duration; +- channel[c].frameskip = inst[channel[c].inst].timer; +- if(levpuls[channel[c].levpuls].level != 0xff) +- channel[c].modvol = levpuls[channel[c].levpuls].level; +- else +- channel[c].modvol = inst[channel[c].inst].data[7] & 63; +- } +- +- channel[c].freq = notetable[note%12] + ((note/12) << 10); +- if(cnt < 0x20) // normal note +- playnote(c); +- else { // tienote +- setfreq(c); +- cnt -= 0x20; // make count proper +- } +- channel[c].rhcnt = cnt; +- } else { // note handling for v0 +- if(cnt < 2) // unlocked note +- note += channel[c].transpose; +- channel[c].note = note; +- +- channel[c].freq = notetable[note%12] + ((note/12) << 10); +- if(cnt == 1) // tienote +- setfreq(c); +- else // normal note +- playnote(c); +- } +- break; +- } +- continue; // event is complete +- } else { // effect event +- switch(fx) { +- case 6: // Cut/Stop Voice +- buf = channel[c].inst; +- channel[c].inst = 0; +- playnote(c); +- channel[c].inst = buf; +- channel[c].rhcnt = fxop; +- continue; // no note follows this event +- case 7: // Vibrato +- channel[c].vibspeed = fxop & 0xff; +- channel[c].vibdepth = fxop >> 8; +- channel[c].trigger = fxop >> 9; +- channel[c].fxflag |= 1; +- break; +- case 8: // v0: Duration +- if(!version) +- channel[c].irhcnt = fxop; +- break; +- case 9: // New Level +- channel[c].vol = fxop & 63; +- if(channel[c].vol + channel[c].cvol < 63) // apply channel volume +- channel[c].vol += channel[c].cvol; +- else +- channel[c].vol = 63; +- setvolume(c); +- break; +- case 0xb: // v4: Set SpFX +- if(version == 4) +- channel[c].ispfx = fxop; +- break; +- case 0xc: // Set Instrument +- channel[c].ispfx = 0xffff; +- channel[c].spfx = 0xffff; +- channel[c].inst = fxop; +- channel[c].modvol = inst[fxop].data[7] & 63; +- if(version < 3 && version && inst[fxop].tunelev) // Set LevelPuls +- channel[c].ilevpuls = inst[fxop].tunelev - 1; +- else { +- channel[c].ilevpuls = 0xff; +- channel[c].levpuls = 0xff; +- } +- break; +- case 0xd: // Slide up +- channel[c].slide = fxop; +- channel[c].fxflag |= 2; +- break; +- case 0xe: // Slide down +- channel[c].slide = -fxop; +- channel[c].fxflag |= 2; +- break; +- } +- goto readseq; // event is incomplete, note follows +- } +- } +- +- for(c=0;c<9;c++) +- if(channel[c].seqend) +- trackend++; +- if(trackend == 9) +- songend = 1; +- +- return !songend; +-} +- +-void Cd00Player::rewind(int subsong) +-{ +- struct Stpoin { +- unsigned short ptr[9]; +- unsigned char volume[9],dummy[5]; +- } *tpoin; +- int i; +- +- if(subsong == -1) subsong = cursubsong; +- +- if(version > 1) { // do nothing if subsong > number of subsongs +- if(subsong >= header->subsongs) +- return; +- } else +- if(subsong >= header1->subsongs) +- return; +- +- memset(channel,0,sizeof(channel)); +- if(version > 1) +- tpoin = (struct Stpoin *)((char *)filedata + LE_WORD(&header->tpoin)); +- else +- tpoin = (struct Stpoin *)((char *)filedata + LE_WORD(&header1->tpoin)); +- for(i=0;i<9;i++) { +- if(LE_WORD(&tpoin[subsong].ptr[i])) { // track enabled +- channel[i].speed = LE_WORD((unsigned short *) +- ((char *)filedata + LE_WORD(&tpoin[subsong].ptr[i]))); +- channel[i].order = (unsigned short *) +- ((char *)filedata + LE_WORD(&tpoin[subsong].ptr[i]) + 2); +- } else { // track disabled +- channel[i].speed = 0; +- channel[i].order = 0; +- } +- channel[i].ispfx = 0xffff; channel[i].spfx = 0xffff; // no SpFX +- channel[i].ilevpuls = 0xff; channel[i].levpuls = 0xff; // no LevelPuls +- channel[i].cvol = tpoin[subsong].volume[i] & 0x7f; // our player may savely ignore bit 7 +- channel[i].vol = channel[i].cvol; // initialize volume +- } +- songend = 0; +- opl->init(); opl->write(1,32); // reset OPL chip +- cursubsong = subsong; +-} +- +-std::string Cd00Player::gettype() +-{ +- char tmpstr[40]; +- +- sprintf(tmpstr,"EdLib packed (version %d)",version > 1 ? header->version : header1->version); +- return std::string(tmpstr); +-} +- +-float Cd00Player::getrefresh() +-{ +- if(version > 1) +- return header->speed; +- else +- return header1->speed; +-} +- +-unsigned int Cd00Player::getsubsongs() +-{ +- if(version <= 1) // return number of subsongs +- return header1->subsongs; +- else +- return header->subsongs; +-} +- +-/*** private methods *************************************/ +- +-void Cd00Player::setvolume(unsigned char chan) +-{ +- unsigned char op = op_table[chan]; +- unsigned short insnr = channel[chan].inst; +- +- opl->write(0x43 + op,(int)(63-((63-(inst[insnr].data[2] & 63))/63.0)*(63-channel[chan].vol)) + +- (inst[insnr].data[2] & 192)); +- if(inst[insnr].data[10] & 1) +- opl->write(0x40 + op,(int)(63-((63-channel[chan].modvol)/63.0)*(63-channel[chan].vol)) + +- (inst[insnr].data[7] & 192)); +- else +- opl->write(0x40 + op,channel[chan].modvol + (inst[insnr].data[7] & 192)); +-} +- +-void Cd00Player::setfreq(unsigned char chan) +-{ +- unsigned short freq = channel[chan].freq; +- +- if(version == 4) // v4: apply instrument finetune +- freq += inst[channel[chan].inst].tunelev; +- +- freq += channel[chan].slideval; +- opl->write(0xa0 + chan, freq & 255); +- if(channel[chan].key) +- opl->write(0xb0 + chan, ((freq >> 8) & 31) | 32); +- else +- opl->write(0xb0 + chan, (freq >> 8) & 31); +-} +- +-void Cd00Player::setinst(unsigned char chan) +-{ +- unsigned char op = op_table[chan]; +- unsigned short insnr = channel[chan].inst; +- +- // set instrument data +- opl->write(0x63 + op, inst[insnr].data[0]); +- opl->write(0x83 + op, inst[insnr].data[1]); +- opl->write(0x23 + op, inst[insnr].data[3]); +- opl->write(0xe3 + op, inst[insnr].data[4]); +- opl->write(0x60 + op, inst[insnr].data[5]); +- opl->write(0x80 + op, inst[insnr].data[6]); +- opl->write(0x20 + op, inst[insnr].data[8]); +- opl->write(0xe0 + op, inst[insnr].data[9]); +- if(version) +- opl->write(0xc0 + chan, inst[insnr].data[10]); +- else +- opl->write(0xc0 + chan, (inst[insnr].data[10] << 1) + (inst[insnr].tunelev & 1)); +-} +- +-void Cd00Player::playnote(unsigned char chan) +-{ +- // set misc vars & play +- opl->write(0xb0 + chan, 0); // stop old note +- setinst(chan); +- channel[chan].key = 1; +- setfreq(chan); +- setvolume(chan); +-} +- +-void Cd00Player::vibrato(unsigned char chan) +-{ +- if(!channel[chan].vibdepth) +- return; +- +- if(channel[chan].trigger) +- channel[chan].trigger--; +- else { +- channel[chan].trigger = channel[chan].vibdepth; +- channel[chan].vibspeed = -channel[chan].vibspeed; +- } +- channel[chan].freq += channel[chan].vibspeed; +- setfreq(chan); +-} +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/d00.h audacious-plugins-3.9/src/adplug/core/d00.h +--- audacious-plugins-3.9-orig/src/adplug/core/d00.h 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/d00.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,109 +0,0 @@ +-/* +- * AdPlug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2007 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * d00.h - D00 Player by Simon Peter +- */ +- +-#ifndef H_D00 +-#define H_D00 +- +-#include "player.h" +- +-class Cd00Player: public CPlayer +-{ +- public: +- static CPlayer *factory(Copl *newopl); +- +- Cd00Player(Copl *newopl) +- : CPlayer(newopl), filedata(0) +- { }; +- ~Cd00Player() +- { if(filedata) delete [] filedata; }; +- +- bool load(const std::string &filename, const CFileProvider &fp); +- bool update(); +- void rewind(int subsong); +- float getrefresh(); +- +- std::string gettype(); +- std::string gettitle() +- { if(version > 1) return std::string(header->songname); else return std::string(); }; +- std::string getauthor() +- { if(version > 1) return std::string(header->author); else return std::string(); }; +- std::string getdesc() +- { if(*datainfo) return std::string(datainfo); else return std::string(); }; +- unsigned int getsubsongs(); +- +- protected: +-#pragma pack(1) +- struct d00header { +- char id[6]; +- unsigned char type,version,speed,subsongs,soundcard; +- char songname[32],author[32],dummy[32]; +- unsigned short tpoin,seqptr,instptr,infoptr,spfxptr,endmark; +- }; +- +- struct d00header1 { +- unsigned char version,speed,subsongs; +- unsigned short tpoin,seqptr,instptr,infoptr,lpulptr,endmark; +- }; +-#pragma pack() +- +- struct { +- unsigned short *order,ordpos,pattpos,del,speed,rhcnt,key,freq,inst, +- spfx,ispfx,irhcnt; +- signed short transpose,slide,slideval,vibspeed; +- unsigned char seqend,vol,vibdepth,fxdel,modvol,cvol,levpuls, +- frameskip,nextnote,note,ilevpuls,trigger,fxflag; +- } channel[9]; +- +- struct Sinsts { +- unsigned char data[11],tunelev,timer,sr,dummy[2]; +- } *inst; +- +- struct Sspfx { +- unsigned short instnr; +- signed char halfnote; +- unsigned char modlev; +- signed char modlevadd; +- unsigned char duration; +- unsigned short ptr; +- } *spfx; +- +- struct Slevpuls { +- unsigned char level; +- signed char voladd; +- unsigned char duration,ptr; +- } *levpuls; +- +- unsigned char songend,version,cursubsong; +- char *datainfo; +- unsigned short *seqptr; +- d00header *header; +- d00header1 *header1; +- char *filedata; +- +- private: +- void setvolume(unsigned char chan); +- void setfreq(unsigned char chan); +- void setinst(unsigned char chan); +- void playnote(unsigned char chan); +- void vibrato(unsigned char chan); +-}; +- +-#endif +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/database.cc audacious-plugins-3.9/src/adplug/core/database.cc +--- audacious-plugins-3.9-orig/src/adplug/core/database.cc 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/database.cc 1970-01-01 01:00:00.000000000 +0100 +@@ -1,426 +0,0 @@ +-/* +- * AdPlug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (c) 1999 - 2006 Simon Peter , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * database.cpp - AdPlug database class +- * Copyright (c) 2002 Riven the Mage +- * Copyright (c) 2002, 2003, 2006 Simon Peter +- */ +- +-#include "binio.h" +-#include "binfile.h" +-#include +- +-#include "database.h" +- +-#define DB_FILEID_V10 "AdPlug Module Information Database 1.0\x10" +- +-/***** CAdPlugDatabase *****/ +- +-const unsigned short CAdPlugDatabase::hash_radix = 0xfff1; // should be prime +- +-CAdPlugDatabase::CAdPlugDatabase() +- : linear_index(0), linear_logic_length(0), linear_length(0) +-{ +- db_linear = new DB_Bucket * [hash_radix]; +- db_hashed = new DB_Bucket * [hash_radix]; +- memset(db_linear, 0, sizeof(DB_Bucket *) * hash_radix); +- memset(db_hashed, 0, sizeof(DB_Bucket *) * hash_radix); +-} +- +-CAdPlugDatabase::~CAdPlugDatabase() +-{ +- unsigned long i; +- +- for(i = 0; i < linear_length; i++) +- delete db_linear[i]; +- +- delete [] db_linear; +- delete [] db_hashed; +-} +- +-bool CAdPlugDatabase::load(std::string db_name) +-{ +- binifstream f(db_name); +- if(f.error()) return false; +- return load(f); +-} +- +-bool CAdPlugDatabase::load(binistream &f) +-{ +- unsigned int idlen = strlen(DB_FILEID_V10); +- char *id = new char [idlen]; +- unsigned long length; +- +- // Open database as little endian with IEEE floats +- f.setFlag(binio::BigEndian, false); f.setFlag(binio::FloatIEEE); +- +- f.readString(id,idlen); +- if(memcmp(id,DB_FILEID_V10,idlen)) { +- delete [] id; +- return false; +- } +- delete [] id; +- length = f.readInt(4); +- +- // read records +- for(unsigned long i = 0; i < length; i++) +- insert(CRecord::factory(f)); +- +- return true; +-} +- +-bool CAdPlugDatabase::save(std::string db_name) +-{ +- binofstream f(db_name); +- if(f.error()) return false; +- return save(f); +-} +- +-bool CAdPlugDatabase::save(binostream &f) +-{ +- unsigned long i; +- +- // Save database as little endian with IEEE floats +- f.setFlag(binio::BigEndian, false); f.setFlag(binio::FloatIEEE); +- +- f.writeString(DB_FILEID_V10); +- f.writeInt(linear_logic_length, 4); +- +- // write records +- for(i = 0; i < linear_length; i++) +- if(!db_linear[i]->deleted) +- db_linear[i]->record->write(f); +- +- return true; +-} +- +-CAdPlugDatabase::CRecord *CAdPlugDatabase::search(CKey const &key) +-{ +- if(lookup(key)) return get_record(); else return 0; +-} +- +-bool CAdPlugDatabase::lookup(CKey const &key) +-{ +- unsigned long index = make_hash(key); +- if(!db_hashed[index]) return false; +- +- // immediate hit ? +- DB_Bucket *bucket = db_hashed[index]; +- +- if(!bucket->deleted && bucket->record->key == key) { +- linear_index = bucket->index; +- return true; +- } +- +- // in-chain hit ? +- bucket = db_hashed[index]->chain; +- +- while(bucket) { +- if(!bucket->deleted && bucket->record->key == key) { +- linear_index = bucket->index; +- return true; +- } +- +- bucket = bucket->chain; +- } +- +- return false; +-} +- +-bool CAdPlugDatabase::insert(CRecord *record) +-{ +- long index; +- +- // sanity checks +- if(!record) return false; // null-pointer given +- if(linear_length == hash_radix) return false; // max. db size exceeded +- if(lookup(record->key)) return false; // record already in db +- +- // make bucket +- DB_Bucket *bucket = new DB_Bucket(linear_length, record); +- if(!bucket) return false; +- +- // add to linear list +- db_linear[linear_length] = bucket; +- linear_logic_length++; linear_length++; +- +- // add to hashed list +- index = make_hash(record->key); +- +- if(!db_hashed[index]) // First entry in hashtable +- db_hashed[index] = bucket; +- else { // Add entry in chained list +- DB_Bucket *chain = db_hashed[index]; +- +- while(chain->chain) chain = chain->chain; +- chain->chain = bucket; +- } +- +- return true; +-} +- +-void CAdPlugDatabase::wipe(CRecord *record) +-{ +- if(!lookup(record->key)) return; +- wipe(); +-} +- +-void CAdPlugDatabase::wipe() +-{ +- if(!linear_length) return; +- +- DB_Bucket *bucket = db_linear[linear_index]; +- +- if(!bucket->deleted) { +- delete bucket->record; +- linear_logic_length--; +- bucket->deleted = true; +- } +-} +- +-CAdPlugDatabase::CRecord *CAdPlugDatabase::get_record() +-{ +- if(!linear_length) return 0; +- return db_linear[linear_index]->record; +-} +- +-bool CAdPlugDatabase::go_forward() +-{ +- if(linear_index + 1 < linear_length) { +- linear_index++; +- return true; +- } else +- return false; +-} +- +-bool CAdPlugDatabase::go_backward() +-{ +- if(!linear_index) return false; +- linear_index--; +- return true; +-} +- +-void CAdPlugDatabase::goto_begin() +-{ +- if(linear_length) linear_index = 0; +-} +- +-void CAdPlugDatabase::goto_end() +-{ +- if(linear_length) linear_index = linear_length - 1; +-} +- +-inline unsigned long CAdPlugDatabase::make_hash(CKey const &key) +-{ +- return (key.crc32 + key.crc16) % hash_radix; +-} +- +-/***** CAdPlugDatabase::DB_Bucket *****/ +- +-CAdPlugDatabase::DB_Bucket::DB_Bucket(unsigned long nindex, CRecord *newrecord, DB_Bucket *newchain) +- : index(nindex), deleted(false), chain(newchain), record(newrecord) +-{ +-} +- +-CAdPlugDatabase::DB_Bucket::~DB_Bucket() +-{ +- if(!deleted) delete record; +-} +- +-/***** CAdPlugDatabase::CRecord *****/ +- +-CAdPlugDatabase::CRecord *CAdPlugDatabase::CRecord::factory(RecordType type) +-{ +- switch(type) { +- case Plain: return new CPlainRecord; +- case SongInfo: return new CInfoRecord; +- case ClockSpeed: return new CClockRecord; +- default: return 0; +- } +-} +- +-CAdPlugDatabase::CRecord *CAdPlugDatabase::CRecord::factory(binistream &in) +-{ +- RecordType type; +- unsigned long size; +- CRecord *rec; +- +- type = (RecordType)in.readInt(1); size = in.readInt(4); +- rec = factory(type); +- +- if(rec) { +- rec->key.crc16 = in.readInt(2); rec->key.crc32 = in.readInt(4); +- rec->filetype = in.readString('\0'); rec->comment = in.readString('\0'); +- rec->read_own(in); +- return rec; +- } else { +- // skip this record, cause we don't know about it +- in.seek(size, binio::Add); +- return 0; +- } +-} +- +-void CAdPlugDatabase::CRecord::write(binostream &out) +-{ +- out.writeInt(type, 1); +- out.writeInt(get_size() + filetype.length() + comment.length() + 8, 4); +- out.writeInt(key.crc16, 2); out.writeInt(key.crc32, 4); +- out.writeString(filetype); out.writeInt('\0', 1); +- out.writeString(comment); out.writeInt('\0', 1); +- +- write_own(out); +-} +- +-bool CAdPlugDatabase::CRecord::user_read(std::istream &in, std::ostream &out) +-{ +- return user_read_own(in, out); +-} +- +-bool CAdPlugDatabase::CRecord::user_write(std::ostream &out) +-{ +- out << "Record type: "; +- switch(type) { +- case Plain: out << "Plain"; break; +- case SongInfo: out << "SongInfo"; break; +- case ClockSpeed: out << "ClockSpeed"; break; +- default: out << "*** Unknown ***"; break; +- } +- out << std::endl; +- out << "Key: " << std::hex << key.crc16 << ":" << key.crc32 << std::dec << std::endl; +- out << "File type: " << filetype << std::endl; +- out << "Comment: " << comment << std::endl; +- +- return user_write_own(out); +-} +- +-/***** CAdPlugDatabase::CRecord::CKey *****/ +- +-CAdPlugDatabase::CKey::CKey(binistream &buf) +-{ +- make(buf); +-} +- +-bool CAdPlugDatabase::CKey::operator==(const CKey &key) +-{ +- return ((crc16 == key.crc16) && (crc32 == key.crc32)); +-} +- +-void CAdPlugDatabase::CKey::make(binistream &buf) +-// Key is CRC16:CRC32 pair. CRC16 and CRC32 calculation routines (c) Zhengxi +-{ +- static const unsigned short magic16 = 0xa001; +- static const unsigned long magic32 = 0xedb88320; +- +- crc16 = 0; crc32 = ~0; +- +- while(!buf.eof()) +- { +- unsigned char byte = buf.readInt(1); +- +- for (int j=0;j<8;j++) +- { +- if ((crc16 ^ byte) & 1) +- crc16 = (crc16 >> 1) ^ magic16; +- else +- crc16 >>= 1; +- +- if ((crc32 ^ byte) & 1) +- crc32 = (crc32 >> 1) ^ magic32; +- else +- crc32 >>= 1; +- +- byte >>= 1; +- } +- } +- +- crc16 &= 0xffff; +- crc32 = ~crc32; +-} +- +-/***** CInfoRecord *****/ +- +-CInfoRecord::CInfoRecord() +-{ +- type = SongInfo; +-} +- +-void CInfoRecord::read_own(binistream &in) +-{ +- title = in.readString('\0'); +- author = in.readString('\0'); +-} +- +-void CInfoRecord::write_own(binostream &out) +-{ +- out.writeString(title); out.writeInt('\0', 1); +- out.writeString(author); out.writeInt('\0', 1); +-} +- +-unsigned long CInfoRecord::get_size() +-{ +- return title.length() + author.length() + 2; +-} +- +-bool CInfoRecord::user_read_own(std::istream &in, std::ostream &out) +-{ +- out << "Title: "; in >> title; +- out << "Author: "; in >> author; +- return true; +-} +- +-bool CInfoRecord::user_write_own(std::ostream &out) +-{ +- out << "Title: " << title << std::endl; +- out << "Author: " << author << std::endl; +- return true; +-} +- +-/***** CClockRecord *****/ +- +-CClockRecord::CClockRecord() +- : clock(0.0f) +-{ +- type = ClockSpeed; +-} +- +-void CClockRecord::read_own(binistream &in) +-{ +- clock = in.readFloat(binio::Single); +-} +- +-void CClockRecord::write_own(binostream &out) +-{ +- out.writeFloat(clock, binio::Single); +-} +- +-unsigned long CClockRecord::get_size() +-{ +- return 4; +-} +- +-bool CClockRecord::user_read_own(std::istream &in, std::ostream &out) +-{ +- out << "Clockspeed: "; in >> clock; +- return true; +-} +- +-bool CClockRecord::user_write_own(std::ostream &out) +-{ +- out << "Clock speed: " << clock << " Hz" << std::endl; +- return true; +-} +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/database.h audacious-plugins-3.9/src/adplug/core/database.h +--- audacious-plugins-3.9-orig/src/adplug/core/database.h 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/database.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,169 +0,0 @@ +-/* +- * AdPlug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (c) 1999 - 2003 Simon Peter , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * database.h - AdPlug database class +- * Copyright (c) 2002 Riven the Mage +- * Copyright (c) 2002, 2003 Simon Peter +- */ +- +-#ifndef H_ADPLUG_DATABASE +-#define H_ADPLUG_DATABASE +- +-#include +-#include +-#include "binio.h" +- +-class CAdPlugDatabase +-{ +-public: +- class CKey +- { +- public: +- unsigned short crc16; +- unsigned long crc32; +- +- CKey() {}; +- CKey(binistream &in); +- +- bool operator==(const CKey &key); +- +- private: +- void make(binistream &in); +- }; +- +- class CRecord +- { +- public: +- typedef enum { Plain, SongInfo, ClockSpeed } RecordType; +- +- RecordType type; +- CKey key; +- std::string filetype, comment; +- +- static CRecord *factory(RecordType type); +- static CRecord *factory(binistream &in); +- +- CRecord() {} +- virtual ~CRecord() {} +- +- void write(binostream &out); +- +- bool user_read(std::istream &in, std::ostream &out); +- bool user_write(std::ostream &out); +- +- protected: +- virtual void read_own(binistream &in) = 0; +- virtual void write_own(binostream &out) = 0; +- virtual unsigned long get_size() = 0; +- virtual bool user_read_own(std::istream &in, std::ostream &out) = 0; +- virtual bool user_write_own(std::ostream &out) = 0; +- }; +- +- CAdPlugDatabase(); +- ~CAdPlugDatabase(); +- +- bool load(std::string db_name); +- bool load(binistream &f); +- bool save(std::string db_name); +- bool save(binostream &f); +- +- bool insert(CRecord *record); +- +- void wipe(CRecord *record); +- void wipe(); +- +- CRecord *search(CKey const &key); +- bool lookup(CKey const &key); +- +- CRecord *get_record(); +- +- bool go_forward(); +- bool go_backward(); +- +- void goto_begin(); +- void goto_end(); +- +-private: +- static const unsigned short hash_radix; +- +- class DB_Bucket +- { +- public: +- unsigned long index; +- bool deleted; +- DB_Bucket *chain; +- +- CRecord *record; +- +- DB_Bucket(unsigned long nindex, CRecord *newrecord, DB_Bucket *newchain = 0); +- ~DB_Bucket(); +- }; +- +- DB_Bucket **db_linear; +- DB_Bucket **db_hashed; +- +- unsigned long linear_index, linear_logic_length, linear_length; +- +- unsigned long make_hash(CKey const &key); +-}; +- +-class CPlainRecord: public CAdPlugDatabase::CRecord +-{ +-public: +- CPlainRecord() { type = Plain; } +- +-protected: +- virtual void read_own(binistream &in) {} +- virtual void write_own(binostream &out) {} +- virtual unsigned long get_size() { return 0; } +- virtual bool user_read_own(std::istream &in, std::ostream &out) { return true; } +- virtual bool user_write_own(std::ostream &out) { return true; } +-}; +- +-class CInfoRecord: public CAdPlugDatabase::CRecord +-{ +-public: +- std::string title; +- std::string author; +- +- CInfoRecord(); +- +-protected: +- virtual void read_own(binistream &in); +- virtual void write_own(binostream &out); +- virtual unsigned long get_size(); +- virtual bool user_read_own(std::istream &in, std::ostream &out); +- virtual bool user_write_own(std::ostream &out); +-}; +- +-class CClockRecord: public CAdPlugDatabase::CRecord +-{ +-public: +- float clock; +- +- CClockRecord(); +- +-protected: +- virtual void read_own(binistream &in); +- virtual void write_own(binostream &out); +- virtual unsigned long get_size(); +- virtual bool user_read_own(std::istream &in, std::ostream &out); +- virtual bool user_write_own(std::ostream &out); +-}; +- +-#endif +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/debug.h audacious-plugins-3.9/src/adplug/core/debug.h +--- audacious-plugins-3.9-orig/src/adplug/core/debug.h 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/debug.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,39 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2002 Simon Peter , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * debug.h - AdPlug Debug Logger +- * Copyright (c) 2002 Riven the Mage +- * Copyright (c) 2002 Simon Peter +- * +- * NOTES: +- * This debug logger is used throughout AdPlug to log debug output to stderr +- * (the default) or to a user-specified logfile. +- * +- * To use it, AdPlug has to be compiled with debug logging support enabled. +- * This is done by defining the DEBUG macro with every source-file. The +- * LogFile() function can be used to specify a logfile to write to. +- */ +- +-#ifndef H_DEBUG +-#define H_DEBUG +- +-#include +- +-#define AdPlug_LogWrite(...) AUDDBG(__VA_ARGS__) +- +-#endif +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/dfm.cc audacious-plugins-3.9/src/adplug/core/dfm.cc +--- audacious-plugins-3.9-orig/src/adplug/core/dfm.cc 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/dfm.cc 1970-01-01 01:00:00.000000000 +0100 +@@ -1,116 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2003 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * dfm.cpp - Digital-FM Loader by Simon Peter +- */ +- +-#include +-#include +- +-#include "dfm.h" +-#include "debug.h" +- +-CPlayer *CdfmLoader::factory(Copl *newopl) +-{ +- return new CdfmLoader(newopl); +-} +- +-bool CdfmLoader::load(const std::string &filename, const CFileProvider &fp) +-{ +- binistream *f = fp.open(filename); if(!f) return false; +- unsigned char npats,n,note,fx,c,r,param; +- unsigned int i; +- const unsigned char convfx[8] = {255,255,17,19,23,24,255,13}; +- +- // file validation +- f->readString(header.id, 4); +- header.hiver = f->readInt(1); header.lover = f->readInt(1); +- if(strncmp(header.id,"DFM\x1a",4) || header.hiver > 1) +- { fp.close(f); return false; } +- +- // load +- restartpos = 0; flags = Standard; bpm = 0; +- init_trackord(); +- f->readString(songinfo, 33); +- initspeed = f->readInt(1); +- for(i = 0; i < 32; i++) +- f->readString(instname[i], 12); +- for(i = 0; i < 32; i++) { +- inst[i].data[1] = f->readInt(1); +- inst[i].data[2] = f->readInt(1); +- inst[i].data[9] = f->readInt(1); +- inst[i].data[10] = f->readInt(1); +- inst[i].data[3] = f->readInt(1); +- inst[i].data[4] = f->readInt(1); +- inst[i].data[5] = f->readInt(1); +- inst[i].data[6] = f->readInt(1); +- inst[i].data[7] = f->readInt(1); +- inst[i].data[8] = f->readInt(1); +- inst[i].data[0] = f->readInt(1); +- } +- for(i = 0; i < 128; i++) order[i] = f->readInt(1); +- for(i = 0; i < 128 && order[i] != 128; i++) continue; +- length = i; +- npats = f->readInt(1); +- for(i = 0; i < npats; i++) { +- n = f->readInt(1); +- for(r = 0; r < 64; r++) +- for(c = 0; c < 9; c++) { +- note = f->readInt(1); +- if((note & 15) == 15) +- tracks[n*9+c][r].note = 127; // key off +- else +- tracks[n*9+c][r].note = ((note & 127) >> 4) * 12 + (note & 15); +- if(note & 128) { // additional effect byte +- fx = f->readInt(1); +- if(fx >> 5 == 1) +- tracks[n*9+c][r].inst = (fx & 31) + 1; +- else { +- tracks[n*9+c][r].command = convfx[fx >> 5]; +- if(tracks[n*9+c][r].command == 17) { // set volume +- param = fx & 31; +- param = 63 - param * 2; +- tracks[n*9+c][r].param1 = param >> 4; +- tracks[n*9+c][r].param2 = param & 15; +- } else { +- tracks[n*9+c][r].param1 = (fx & 31) >> 4; +- tracks[n*9+c][r].param2 = fx & 15; +- } +- } +- } +- +- } +- } +- +- fp.close(f); +- rewind(0); +- return true; +-} +- +-std::string CdfmLoader::gettype() +-{ +- char tmpstr[20]; +- +- sprintf(tmpstr,"Digital-FM %d.%d",header.hiver,header.lover); +- return std::string(tmpstr); +-} +- +-float CdfmLoader::getrefresh() +-{ +- return 125.0f; +-} +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/dfm.h audacious-plugins-3.9/src/adplug/core/dfm.h +--- audacious-plugins-3.9-orig/src/adplug/core/dfm.h 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/dfm.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,52 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2003 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * dfm.h - Digital-FM Loader by Simon Peter +- */ +- +-#include "protrack.h" +- +-class CdfmLoader: public CmodPlayer +-{ +-public: +- static CPlayer *factory(Copl *newopl); +- +- CdfmLoader(Copl *newopl) +- : CmodPlayer(newopl) +- { }; +- +- bool load(const std::string &filename, const CFileProvider &fp); +- float getrefresh(); +- +- std::string gettype(); +- unsigned int getinstruments() +- { return 32; }; +- std::string getinstrument(unsigned int n) +- { if(*instname[n]) return std::string(instname[n],1,*instname[n]); else return std::string(); }; +- std::string getdesc() +- { return std::string(songinfo,1,*songinfo); }; +- +-private: +- struct { +- char id[4]; +- unsigned char hiver,lover; +- } header; +- +- char songinfo[33]; +- char instname[32][12]; +-}; +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/dmo.cc audacious-plugins-3.9/src/adplug/core/dmo.cc +--- audacious-plugins-3.9-orig/src/adplug/core/dmo.cc 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/dmo.cc 1970-01-01 01:00:00.000000000 +0100 +@@ -1,419 +0,0 @@ +-/* +- Adplug - Replayer for many OPL2/OPL3 audio file formats. +- Copyright (C) 1999 - 2004, 2006 Simon Peter, , et al. +- +- This library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- This library 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 +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with this library; if not, write to the Free Software +- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- +- dmo.cpp - TwinTeam loader by Riven the Mage +-*/ +-/* +- NOTES: +- Panning is ignored. +- +- A WORD ist 16 bits, a DWORD is 32 bits and a BYTE is 8 bits in this context. +-*/ +- +-#include +-#include "binstr.h" +- +-#include "dmo.h" +-#include "debug.h" +- +-#define LOWORD(l) ((l) & 0xffff) +-#define HIWORD(l) ((l) >> 16) +-#define LOBYTE(w) ((w) & 0xff) +-#define HIBYTE(w) ((w) >> 8) +- +-#define ARRAY_AS_DWORD(a, i) \ +-((a[i + 3] << 24) + (a[i + 2] << 16) + (a[i + 1] << 8) + a[i]) +-#define ARRAY_AS_WORD(a, i) ((a[i + 1] << 8) + a[i]) +- +-#define CHARP_AS_WORD(p) (((*(p + 1)) << 8) + (*p)) +- +-/* -------- Public Methods -------------------------------- */ +- +-CPlayer *CdmoLoader::factory(Copl *newopl) +-{ +- return new CdmoLoader(newopl); +-} +- +-bool CdmoLoader::load(const std::string &filename, const CFileProvider &fp) +-{ +- int i,j; +- binistream *f; +- +- // check header +- dmo_unpacker *unpacker = new dmo_unpacker; +- unsigned char chkhdr[16]; +- +- if (!fp.extension(filename, ".dmo")) +- { +- delete unpacker; +- return false; +- } +- +- f = fp.open(filename); +- if (!f) +- { +- delete unpacker; +- return false; +- } +- +- f->readString((char *)chkhdr, 16); +- +- if (!unpacker->decrypt(chkhdr, 16)) +- { +- delete unpacker; +- fp.close(f); +- return false; +- } +- +- // get file size +- long packed_length = fp.filesize(f); +- f->seek(0); +- +- unsigned char *packed_module = new unsigned char [packed_length]; +- +- // load file +- f->readString((char *)packed_module, packed_length); +- fp.close(f); +- +- // decrypt +- unpacker->decrypt(packed_module,packed_length); +- +- long unpacked_length = 0x2000 * ARRAY_AS_WORD(packed_module, 12); +- unsigned char *module = new unsigned char [unpacked_length]; +- +- // unpack +- if (!unpacker->unpack(packed_module+12,module,unpacked_length)) +- { +- delete unpacker; +- delete [] packed_module; +- delete [] module; +- return false; +- } +- +- delete unpacker; +- delete [] packed_module; +- +- // "TwinTeam" - signed ? +- if (memcmp(module,"TwinTeam Module File""\x0D\x0A",22)) +- { +- delete [] module; +- return false; +- } +- +- // load header +- binisstream uf(module, unpacked_length); +- uf.setFlag(binio::BigEndian, false); uf.setFlag(binio::FloatIEEE); +- +- memset(&header,0,sizeof(s3mheader)); +- +- uf.ignore(22); // ignore DMO header ID string +- uf.readString(header.name, 28); +- +- uf.ignore(2); // _unk_1 +- header.ordnum = uf.readInt(2); +- header.insnum = uf.readInt(2); +- header.patnum = uf.readInt(2); +- uf.ignore(2); // _unk_2 +- header.is = uf.readInt(2); +- header.it = uf.readInt(2); +- +- memset(header.chanset,0xFF,32); +- +- for (i=0;i<9;i++) +- header.chanset[i] = 0x10 + i; +- +- uf.ignore(32); // ignore panning settings for all 32 channels +- +- // load orders +- for(i = 0; i < 256; i++) orders[i] = uf.readInt(1); +- +- orders[header.ordnum] = 0xFF; +- +- // load pattern lengths +- unsigned short my_patlen[100]; +- for(i = 0; i < 100; i++) my_patlen[i] = uf.readInt(2); +- +- // load instruments +- for (i = 0; i < header.insnum; i++) +- { +- memset(&inst[i],0,sizeof(s3minst)); +- +- uf.readString(inst[i].name, 28); +- +- inst[i].volume = uf.readInt(1); +- inst[i].dsk = uf.readInt(1); +- inst[i].c2spd = uf.readInt(4); +- inst[i].type = uf.readInt(1); +- inst[i].d00 = uf.readInt(1); +- inst[i].d01 = uf.readInt(1); +- inst[i].d02 = uf.readInt(1); +- inst[i].d03 = uf.readInt(1); +- inst[i].d04 = uf.readInt(1); +- inst[i].d05 = uf.readInt(1); +- inst[i].d06 = uf.readInt(1); +- inst[i].d07 = uf.readInt(1); +- inst[i].d08 = uf.readInt(1); +- inst[i].d09 = uf.readInt(1); +- inst[i].d0a = uf.readInt(1); +- /* +- * Originally, riven sets d0b = d0a and ignores 1 byte in the +- * stream, but i guess this was a typo, so i read it here. +- */ +- inst[i].d0b = uf.readInt(1); +- } +- +- // load patterns +- for (i = 0; i < header.patnum; i++) { +- long cur_pos = uf.pos(); +- +- for (j = 0; j < 64; j++) { +- while (1) { +- unsigned char token = uf.readInt(1); +- +- if (!token) +- break; +- +- unsigned char chan = token & 31; +- +- // note + instrument ? +- if (token & 32) { +- unsigned char bufbyte = uf.readInt(1); +- +- pattern[i][j][chan].note = bufbyte & 15; +- pattern[i][j][chan].oct = bufbyte >> 4; +- pattern[i][j][chan].instrument = uf.readInt(1); +- } +- +- // volume ? +- if (token & 64) +- pattern[i][j][chan].volume = uf.readInt(1); +- +- // command ? +- if (token & 128) { +- pattern[i][j][chan].command = uf.readInt(1); +- pattern[i][j][chan].info = uf.readInt(1); +- } +- } +- } +- +- uf.seek(cur_pos + my_patlen[i]); +- } +- +- delete [] module; +- rewind(0); +- return true; +-} +- +-std::string CdmoLoader::gettype() +-{ +- return std::string("TwinTeam (packed S3M)"); +-} +- +-std::string CdmoLoader::getauthor() +-{ +- /* +- All available .DMO modules written by one composer. And because all .DMO +- stuff was lost due to hd crash (TwinTeam guys said this), there are +- never(?) be another. +- */ +- return std::string("Benjamin GERARDIN"); +-} +- +-/* -------- Private Methods ------------------------------- */ +- +-unsigned short CdmoLoader::dmo_unpacker::brand(unsigned short range) +-{ +- unsigned short ax,bx,cx,dx; +- +- ax = LOWORD(bseed); +- bx = HIWORD(bseed); +- cx = ax; +- ax = LOWORD(cx * 0x8405); +- dx = HIWORD(cx * 0x8405); +- cx <<= 3; +- cx = (((HIBYTE(cx) + LOBYTE(cx)) & 0xFF) << 8) + LOBYTE(cx); +- dx += cx; +- dx += bx; +- bx <<= 2; +- dx += bx; +- dx = (((HIBYTE(dx) + LOBYTE(bx)) & 0xFF) << 8) + LOBYTE(dx); +- bx <<= 5; +- dx = (((HIBYTE(dx) + LOBYTE(bx)) & 0xFF) << 8) + LOBYTE(dx); +- ax += 1; +- if (!ax) dx += 1; +- +- // leave it that way or amd64 might get it wrong +- bseed = dx; +- bseed <<= 16; +- bseed += ax; +- +- return HIWORD(HIWORD(LOWORD(bseed) * range) + HIWORD(bseed) * range); +-} +- +-bool CdmoLoader::dmo_unpacker::decrypt(unsigned char *buf, long len) +-{ +- unsigned long seed = 0; +- int i; +- +- bseed = ARRAY_AS_DWORD(buf, 0); +- +- for (i=0; i < ARRAY_AS_WORD(buf, 4) + 1; i++) +- seed += brand(0xffff); +- +- bseed = seed ^ ARRAY_AS_DWORD(buf, 6); +- +- if (ARRAY_AS_WORD(buf, 10) != brand(0xffff)) +- return false; +- +- for (i=0;i<(len-12);i++) +- buf[12+i] ^= brand(0x100); +- +- buf[len - 2] = buf[len - 1] = 0; +- +- return true; +-} +- +-short CdmoLoader::dmo_unpacker::unpack_block(unsigned char *ibuf, long ilen, unsigned char *obuf) +-{ +- unsigned char code,par1,par2; +- unsigned short ax,bx,cx; +- +- unsigned char *ipos = ibuf; +- unsigned char *opos = obuf; +- +- // LZ77 child +- while (ipos - ibuf < ilen) +- { +- code = *ipos++; +- +- // 00xxxxxx: copy (xxxxxx + 1) bytes +- if ((code >> 6) == 0) +- { +- cx = (code & 0x3F) + 1; +- +- if(opos + cx >= oend) +- return -1; +- +- for (int i=0;i> 6) == 1) +- { +- par1 = *ipos++; +- +- ax = ((code & 0x3F) << 3) + ((par1 & 0xE0) >> 5) + 1; +- cx = (par1 & 0x1F) + 3; +- +- if(opos + cx >= oend) +- return -1; +- +- for(int i=0;i> 6) == 2) +- { +- int i; +- +- par1 = *ipos++; +- +- ax = ((code & 0x3F) << 1) + (par1 >> 7) + 1; +- cx = ((par1 & 0x70) >> 4) + 3; +- bx = par1 & 0x0F; +- +- if(opos + bx + cx >= oend) +- return -1; +- +- for(i=0;i> 6) == 3) +- { +- int i; +- +- par1 = *ipos++; +- par2 = *ipos++; +- +- bx = ((code & 0x3F) << 7) + (par1 >> 1); +- cx = ((par1 & 0x01) << 4) + (par2 >> 4) + 4; +- ax = par2 & 0x0F; +- +- if(opos + ax + cx >= oend) +- return -1; +- +- for(i=0;i, et al. +- +- This library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- This library 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 +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with this library; if not, write to the Free Software +- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- +- dmo.cpp - TwinTeam loader by Riven the Mage +-*/ +- +-#include "s3m.h" +- +-class CdmoLoader: public Cs3mPlayer +-{ +- public: +- static CPlayer *factory(Copl *newopl); +- +- CdmoLoader(Copl *newopl) : Cs3mPlayer(newopl) { }; +- +- bool load(const std::string &filename, const CFileProvider &fp); +- +- std::string gettype(); +- std::string getauthor(); +- +- private: +- +- class dmo_unpacker { +- public: +- bool decrypt(unsigned char *buf, long len); +- long unpack(unsigned char *ibuf, unsigned char *obuf, +- unsigned long outputsize); +- +- private: +- unsigned short brand(unsigned short range); +- short unpack_block(unsigned char *ibuf, long ilen, unsigned char *obuf); +- +- unsigned long bseed; +- unsigned char *oend; +- }; +-}; +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/dro2.cc audacious-plugins-3.9/src/adplug/core/dro2.cc +--- audacious-plugins-3.9-orig/src/adplug/core/dro2.cc 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/dro2.cc 1970-01-01 01:00:00.000000000 +0100 +@@ -1,142 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2007 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * dro2.cpp - DOSBox Raw OPL v2.0 player by Adam Nielsen +- */ +- +-#include +-#include +- +-#include "dro2.h" +- +-CPlayer *Cdro2Player::factory(Copl *newopl) +-{ +- return new Cdro2Player(newopl); +-} +- +-Cdro2Player::Cdro2Player(Copl *newopl) : +- CPlayer(newopl), +- piConvTable(NULL), +- data(0) +-{ +-} +- +-Cdro2Player::~Cdro2Player() +-{ +- if (this->data) delete[] this->data; +- if (this->piConvTable) delete[] this->piConvTable; +-} +- +-bool Cdro2Player::load(const std::string &filename, const CFileProvider &fp) +-{ +- binistream *f = fp.open(filename); +- if (!f) return false; +- +- char id[8]; +- f->readString(id, 8); +- if (strncmp(id, "DBRAWOPL", 8)) { +- fp.close(f); +- return false; +- } +- int version = f->readInt(4); +- if (version != 0x2) { +- fp.close(f); +- return false; +- } +- +- this->iLength = f->readInt(4) * 2; // stored in file as number of byte pairs +- f->ignore(4); // Length in milliseconds +- f->ignore(1); /// OPL type (0 == OPL2, 1 == Dual OPL2, 2 == OPL3) +- int iFormat = f->readInt(1); +- if (iFormat != 0) { +- fp.close(f); +- return false; +- } +- int iCompression = f->readInt(1); +- if (iCompression != 0) { +- fp.close(f); +- return false; +- } +- this->iCmdDelayS = f->readInt(1); +- this->iCmdDelayL = f->readInt(1); +- this->iConvTableLen = f->readInt(1); +- +- this->piConvTable = new uint8_t[this->iConvTableLen]; +- f->readString((char *)this->piConvTable, this->iConvTableLen); +- +- this->data = new uint8_t[this->iLength]; +- f->readString((char *)this->data, this->iLength); +- +- fp.close(f); +- rewind(0); +- +- return true; +-} +- +-bool Cdro2Player::update() +-{ +- while (this->iPos < this->iLength) { +- int iIndex = this->data[this->iPos++]; +- int iValue = this->data[this->iPos++]; +- +- // Short delay +- if (iIndex == this->iCmdDelayS) { +- this->iDelay = iValue + 1; +- return true; +- +- // Long delay +- } else if (iIndex == this->iCmdDelayL) { +- this->iDelay = (iValue + 1) << 8; +- return true; +- +- // Normal write +- } else { +- if (iIndex & 0x80) { +- // High bit means use second chip in dual-OPL2 config +- this->opl->setchip(1); +- iIndex &= 0x7F; +- } else { +- this->opl->setchip(0); +- } +- if (iIndex > this->iConvTableLen) { +- printf("DRO2: Error - index beyond end of codemap table! Corrupted .dro?\n"); +- return false; // EOF +- } +- int iReg = this->piConvTable[iIndex]; +- this->opl->write(iReg, iValue); +- } +- +- } +- +- // This won't result in endless-play using Adplay, but IMHO that code belongs +- // in Adplay itself, not here. +- return this->iPos < this->iLength; +-} +- +-void Cdro2Player::rewind(int subsong) +-{ +- this->iDelay = 0; +- this->iPos = 0; +- opl->init(); +-} +- +-float Cdro2Player::getrefresh() +-{ +- if (this->iDelay > 0) return 1000.0 / this->iDelay; +- else return 1000.0; +-} +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/dro2.h audacious-plugins-3.9/src/adplug/core/dro2.h +--- audacious-plugins-3.9-orig/src/adplug/core/dro2.h 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/dro2.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,60 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2005 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * dro2.h - DOSBox Raw OPL v2.0 player by Adam Nielsen +- */ +- +-#include // for uintxx_t +-#include "player.h" +- +-class Cdro2Player: public CPlayer +-{ +- protected: +- uint8_t iCmdDelayS, iCmdDelayL; +- int iConvTableLen; +- uint8_t *piConvTable; +- +- uint8_t *data; +- int iLength; +- int iPos; +- int iDelay; +- +- +- public: +- static CPlayer *factory(Copl *newopl); +- +- Cdro2Player(Copl *newopl); +- ~Cdro2Player(); +- +- bool load(const std::string &filename, const CFileProvider &fp); +- bool update(); +- void rewind(int subsong); +- float getrefresh(); +- +- std::string gettype() +- { +- return std::string("DOSBox Raw OPL v2.0"); +- } +- +- protected: +- //unsigned char *data; +- //unsigned long pos,length; +- //unsigned long msdone,mstotal; +- //unsigned short delay; +- //unsigned char index, opl3_mode; +-}; +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/dro.cc audacious-plugins-3.9/src/adplug/core/dro.cc +--- audacious-plugins-3.9-orig/src/adplug/core/dro.cc 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/dro.cc 1970-01-01 01:00:00.000000000 +0100 +@@ -1,141 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2007 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * dro.c - DOSBox Raw OPL Player by Sjoerd van der Berg +- * +- * upgraded by matthew gambrell +- * +- * NOTES: 3-oct-04: the DRO format is not yet finalized. beware. +- */ +- +-#include +-#include +- +-#include "dro.h" +- +-/*** public methods *************************************/ +- +-CPlayer *CdroPlayer::factory(Copl *newopl) +-{ +- return new CdroPlayer(newopl); +-} +- +-CdroPlayer::CdroPlayer(Copl *newopl) +- : CPlayer(newopl), data(0) +-{ +- if(opl->gettype() == Copl::TYPE_OPL2) +- opl3_mode = 0; +- else +- opl3_mode = 1; +-} +- +-bool CdroPlayer::load(const std::string &filename, const CFileProvider &fp) +-{ +- binistream *f = fp.open(filename); if(!f) return false; +- char id[8]; +- unsigned long i; +- +- // file validation section +- f->readString(id, 8); +- if(strncmp(id,"DBRAWOPL",8)) { fp.close (f); return false; } +- int version = f->readInt(4); // not very useful just yet +- if(version != 0x10000) { fp.close(f); return false; } +- +- // load section +- mstotal = f->readInt(4); // Total milliseconds in file +- length = f->readInt(4); // Total data bytes in file +- data = new unsigned char [length]; +- +- f->ignore(1); // Type of opl data this can contain - ignored +- for (i=0;i<3;i++) +- data[i]=f->readInt(1); +- +- if ((data[0] == 0) || (data[1] == 0) || (data[2] == 0)) { +- // Some early .DRO files only used one byte for the hardware type, then +- // later changed to four bytes with no version number change. If we're +- // here then this is a later (more popular) file with the full four bytes +- // for the hardware-type. +- i = 0; // so ignore the three bytes we just read and start again +- } +- for (;ireadInt(1); +- fp.close(f); +- rewind(0); +- return true; +-} +- +-bool CdroPlayer::update() +-{ +- if (delay>500) { +- delay-=500; +- return true; +- } else +- delay=0; +- +- while (pos < length) { +- unsigned char cmd = data[pos++]; +- switch(cmd) { +- case 0: +- delay = 1 + data[pos++]; +- return true; +- case 1: +- delay = 1 + data[pos] + (data[pos+1]<<8); +- pos+=2; +- return true; +- case 2: +- index = 0; +- opl->setchip(0); +- break; +- case 3: +- index = 1; +- opl->setchip(1); +- break; +- default: +- if(cmd==4) cmd = data[pos++]; //data override +- if(index == 0 || opl3_mode) +- opl->write(cmd,data[pos++]); +- break; +- } +- } +- +- return posinit(); +- +- //dro assumes all registers are initialized to 0 +- //registers not initialized to 0 will be corrected +- //in the data stream +- for(int i=0;i<256;i++) +- opl->write(i,0); +- +- opl->setchip(1); +- for(int i=0;i<256;i++) +- opl->write(i,0); +- opl->setchip(0); +-} +- +-float CdroPlayer::getrefresh() +-{ +- if (delay > 500) return 1000 / 500; +- else return 1000 / (double)delay; +-} +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/dro.h audacious-plugins-3.9/src/adplug/core/dro.h +--- audacious-plugins-3.9-orig/src/adplug/core/dro.h 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/dro.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,52 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2005 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * dro.h - DOSBox Raw OPL Player by Sjoerd van der Berg +- */ +- +-#include "player.h" +- +-class CdroPlayer: public CPlayer +-{ +- public: +- static CPlayer *factory(Copl *newopl); +- +- CdroPlayer(Copl *newopl); +- ~CdroPlayer() +- { +- if(data) +- delete [] data; +- } +- +- bool load(const std::string &filename, const CFileProvider &fp); +- bool update(); +- void rewind(int subsong); +- float getrefresh(); +- +- std::string gettype() +- { +- return std::string("DOSBox Raw OPL v0.1"); +- } +- +- protected: +- unsigned char *data; +- unsigned long pos,length; +- unsigned long msdone,mstotal; +- unsigned short delay; +- unsigned char index, opl3_mode; +-}; +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/dtm.cc audacious-plugins-3.9/src/adplug/core/dtm.cc +--- audacious-plugins-3.9-orig/src/adplug/core/dtm.cc 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/dtm.cc 1970-01-01 01:00:00.000000000 +0100 +@@ -1,317 +0,0 @@ +-/* +- Adplug - Replayer for many OPL2/OPL3 audio file formats. +- Copyright (C) 1999 - 2006 Simon Peter, , et al. +- +- This library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- This library 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 +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with this library; if not, write to the Free Software +- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- +- dtm.cpp - DTM loader by Riven the Mage +-*/ +-/* +- NOTE: Panning (Ex) effect is ignored. +-*/ +- +-#include +-#include "dtm.h" +- +-/* -------- Public Methods -------------------------------- */ +- +-CPlayer *CdtmLoader::factory(Copl *newopl) +-{ +- return new CdtmLoader(newopl); +-} +- +-bool CdtmLoader::load(const std::string &filename, const CFileProvider &fp) +-{ +- binistream *f = fp.open(filename); if(!f) return false; +- const unsigned char conv_inst[11] = { 2,1,10,9,4,3,6,5,0,8,7 }; +- const unsigned short conv_note[12] = { 0x16B, 0x181, 0x198, 0x1B0, 0x1CA, 0x1E5, 0x202, 0x220, 0x241, 0x263, 0x287, 0x2AE }; +- int i,j,k,t=0; +- +- // read header +- f->readString(header.id, 12); +- header.version = f->readInt(1); +- f->readString(header.title, 20); f->readString(header.author, 20); +- header.numpat = f->readInt(1); header.numinst = f->readInt(1); +- +- // signature exists ? good version ? +- if(memcmp(header.id,"DeFy DTM ",9) || header.version != 0x10) +- { fp.close (f); return false; } +- +- header.numinst++; +- +- // load description +- memset(desc,0,80*16); +- +- char bufstr[80]; +- +- for (i=0;i<16;i++) +- { +- // get line length +- unsigned char bufstr_length = f->readInt(1); +- +- if(bufstr_length > 80) { +- fp.close(f); +- return false; +- } +- +- // read line +- if (bufstr_length) +- { +- f->readString(bufstr,bufstr_length); +- +- for (j=0;jreadInt(1); +- +- if (name_length) +- f->readString(instruments[i].name, name_length); +- +- instruments[i].name[name_length] = 0; +- +- for(j = 0; j < 12; j++) +- instruments[i].data[j] = f->readInt(1); +- +- for (j=0;j<11;j++) +- inst[i].data[conv_inst[j]] = instruments[i].data[j]; +- } +- +- // load order +- for(i = 0; i < 100; i++) order[i] = f->readInt(1); +- +- nop = header.numpat; +- +- unsigned char *pattern = new unsigned char [0x480]; +- +- // load tracks +- for (i=0;ireadInt(2); +- +- unsigned char *packed_pattern = new unsigned char [packed_length]; +- +- for(j = 0; j < packed_length; j++) +- packed_pattern[j] = f->readInt(1); +- +- long unpacked_length = unpack_pattern(packed_pattern,packed_length,pattern,0x480); +- +- delete [] packed_pattern; +- +- if (!unpacked_length) +- { +- delete [] pattern; +- fp.close(f); +- return false; +- } +- +- // convert pattern +- for (j=0;j<9;j++) +- { +- for (k=0;k<64;k++) +- { +- dtm_event *event = (dtm_event *)&pattern[(k*9+j)*2]; +- +- // instrument +- if (event->byte0 == 0x80) +- { +- if (event->byte1 <= 0x80) +- tracks[t][k].inst = event->byte1 + 1; +- } +- +- // note + effect +- else +- { +- tracks[t][k].note = event->byte0; +- +- if ((event->byte0 != 0) && (event->byte0 != 127)) +- tracks[t][k].note++; +- +- // convert effects +- switch (event->byte1 >> 4) +- { +- case 0x0: // pattern break +- if ((event->byte1 & 15) == 1) +- tracks[t][k].command = 13; +- break; +- +- case 0x1: // freq. slide up +- tracks[t][k].command = 28; +- tracks[t][k].param1 = event->byte1 & 15; +- break; +- +- case 0x2: // freq. slide down +- tracks[t][k].command = 28; +- tracks[t][k].param2 = event->byte1 & 15; +- break; +- +- case 0xA: // set carrier volume +- case 0xC: // set instrument volume +- tracks[t][k].command = 22; +- tracks[t][k].param1 = (0x3F - (event->byte1 & 15)) >> 4; +- tracks[t][k].param2 = (0x3F - (event->byte1 & 15)) & 15; +- break; +- +- case 0xB: // set modulator volume +- tracks[t][k].command = 21; +- tracks[t][k].param1 = (0x3F - (event->byte1 & 15)) >> 4; +- tracks[t][k].param2 = (0x3F - (event->byte1 & 15)) & 15; +- break; +- +- case 0xE: // set panning +- break; +- +- case 0xF: // set speed +- tracks[t][k].command = 13; +- tracks[t][k].param2 = event->byte1 & 15; +- break; +- } +- } +- } +- +- t++; +- } +- } +- +- delete [] pattern; +- fp.close(f); +- +- // order length +- for (i=0;i<100;i++) +- { +- if (order[i] >= 0x80) +- { +- length = i; +- +- if (order[i] == 0xFF) +- restartpos = 0; +- else +- restartpos = order[i] - 0x80; +- +- break; +- } +- } +- +- // initial speed +- initspeed = 2; +- +- rewind(0); +- +- return true; +-} +- +-void CdtmLoader::rewind(int subsong) +-{ +- CmodPlayer::rewind(subsong); +- +- // default instruments +- for (int i=0;i<9;i++) +- { +- channel[i].inst = i; +- +- channel[i].vol1 = 63 - (inst[i].data[10] & 63); +- channel[i].vol2 = 63 - (inst[i].data[9] & 63); +- } +-} +- +-float CdtmLoader::getrefresh() +-{ +- return 18.2f; +-} +- +-std::string CdtmLoader::gettype() +-{ +- return std::string("DeFy Adlib Tracker"); +-} +- +-std::string CdtmLoader::gettitle() +-{ +- return std::string(header.title); +-} +- +-std::string CdtmLoader::getauthor() +-{ +- return std::string(header.author); +-} +- +-std::string CdtmLoader::getdesc() +-{ +- return std::string(desc); +-} +- +-std::string CdtmLoader::getinstrument(unsigned int n) +-{ +- return std::string(instruments[n].name); +-} +- +-unsigned int CdtmLoader::getinstruments() +-{ +- return header.numinst; +-} +- +-/* -------- Private Methods ------------------------------- */ +- +-long CdtmLoader::unpack_pattern(unsigned char *ibuf, long ilen, unsigned char *obuf, long olen) +-{ +- unsigned char *input = ibuf; +- unsigned char *output = obuf; +- +- long input_length = 0; +- long output_length = 0; +- +- unsigned char repeat_byte, repeat_counter; +- +- // RLE +- while (input_length < ilen) +- { +- repeat_byte = input[input_length++]; +- +- if ((repeat_byte & 0xF0) == 0xD0) +- { +- repeat_counter = repeat_byte & 15; +- repeat_byte = input[input_length++]; +- } +- else +- repeat_counter = 1; +- +- for (int i=0;i, et al. +- +- This library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- This library 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 +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with this library; if not, write to the Free Software +- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- +- dtm.h - DTM loader by Riven the Mage +-*/ +- +-#include "protrack.h" +- +-class CdtmLoader: public CmodPlayer +-{ +- public: +- static CPlayer *factory(Copl *newopl); +- +- CdtmLoader(Copl *newopl) : CmodPlayer(newopl) { }; +- +- bool load(const std::string &filename, const CFileProvider &fp); +- void rewind(int subsong); +- float getrefresh(); +- +- std::string gettype(); +- std::string gettitle(); +- std::string getauthor(); +- std::string getdesc(); +- std::string getinstrument(unsigned int n); +- unsigned int getinstruments(); +- +- private: +- +- struct dtm_header +- { +- char id[12]; +- unsigned char version; +- char title[20]; +- char author[20]; +- unsigned char numpat; +- unsigned char numinst; +- } header; +- +- char desc[80*16]; +- +- struct dtm_instrument +- { +- char name[13]; +- unsigned char data[12]; +- } instruments[128]; +- +- struct dtm_event +- { +- unsigned char byte0; +- unsigned char byte1; +- }; +- +- long unpack_pattern(unsigned char *ibuf, long ilen, unsigned char *obuf, long olen); +-}; +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/emuopl.cc audacious-plugins-3.9/src/adplug/core/emuopl.cc +--- audacious-plugins-3.9-orig/src/adplug/core/emuopl.cc 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/emuopl.cc 1970-01-01 01:00:00.000000000 +0100 +@@ -1,147 +0,0 @@ +-/* +- * AdPlug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2005 Simon Peter , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * emuopl.cpp - Emulated OPL, by Simon Peter +- */ +- +-#include "emuopl.h" +- +-CEmuopl::CEmuopl(int rate, bool bit16, bool usestereo) +- : use16bit(bit16), stereo(usestereo), mixbufSamples(0) +-{ +- opl[0] = OPLCreate(OPL_TYPE_YM3812, 3579545, rate); +- opl[1] = OPLCreate(OPL_TYPE_YM3812, 3579545, rate); +- +- currType = TYPE_DUAL_OPL2; +- +- init(); +-} +- +-CEmuopl::~CEmuopl() +-{ +- OPLDestroy(opl[0]); OPLDestroy(opl[1]); +- +- if(mixbufSamples) { +- delete [] mixbuf0; +- delete [] mixbuf1; +- } +-} +- +-void CEmuopl::update(short *buf, int samples) +-{ +- int i; +- +- //ensure that our mix buffers are adequately sized +- if(mixbufSamples < samples) { +- if(mixbufSamples) { delete[] mixbuf0; delete[] mixbuf1; } +- mixbufSamples = samples; +- +- //*2 = make room for stereo, if we need it +- mixbuf0 = new short[samples*2]; +- mixbuf1 = new short[samples*2]; +- } +- +- //data should be rendered to outbuf +- //tempbuf should be used as a temporary buffer +- //if we are supposed to generate 16bit output, +- //then outbuf may point directly to the actual waveform output "buf" +- //if we are supposed to generate 8bit output, +- //then outbuf cannot point to "buf" (because there will not be enough room) +- //and so it must point to a mixbuf instead-- +- //it will be reduced to 8bit and put in "buf" later +- short *outbuf; +- short *tempbuf=mixbuf0; +- short *tempbuf2=mixbuf1; +- if(use16bit) outbuf = buf; +- else outbuf = mixbuf1; +- //...there is a potentially confusing situation where mixbuf1 can be aliased. +- //beware. it is a little loony. +- +- //all of the following rendering code produces 16bit output +- +- switch(currType) { +- case TYPE_OPL2: +- //for opl2 mode: +- //render chip0 to the output buffer +- YM3812UpdateOne(opl[0],outbuf,samples); +- +- //if we are supposed to output stereo, +- //then we need to dup the mono channel +- if(stereo) +- for(i=samples-1;i>=0;i--) { +- outbuf[i*2] = outbuf[i]; +- outbuf[i*2+1] = outbuf[i]; +- } +- break; +- +- case TYPE_OPL3: // unsupported +- break; +- +- case TYPE_DUAL_OPL2: +- //for dual opl2 mode: +- //render each chip to a different tempbuffer +- YM3812UpdateOne(opl[0],tempbuf2,samples); +- YM3812UpdateOne(opl[1],tempbuf,samples); +- +- //output stereo: +- //then we need to interleave the two buffers +- if(stereo){ +- //first, spread tempbuf's samples across left channel +- //left channel +- for(i=0;i>1) + (tempbuf2[i]>>1); +- break; +- } +- +- //now reduce to 8bit if we need to +- if(!use16bit) +- for(i=0;i<(stereo ? samples*2 : samples);i++) +- ((char *)buf)[i] = (outbuf[i] >> 8) ^ 0x80; +-} +- +-void CEmuopl::write(int reg, int val) +-{ +- switch(currType){ +- case TYPE_OPL2: +- case TYPE_DUAL_OPL2: +- OPLWrite(opl[currChip], 0, reg); +- OPLWrite(opl[currChip], 1, val); +- break; +- case TYPE_OPL3: // unsupported +- break; +- } +-} +- +-void CEmuopl::init() +-{ +- OPLResetChip(opl[0]); OPLResetChip(opl[1]); +- currChip = 0; +-} +- +-void CEmuopl::settype(ChipType type) +-{ +- currType = type; +-} +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/emuopl.h audacious-plugins-3.9/src/adplug/core/emuopl.h +--- audacious-plugins-3.9-orig/src/adplug/core/emuopl.h 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/emuopl.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,47 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2005 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * emuopl.h - Emulated OPL, by Simon Peter +- */ +- +-#ifndef H_ADPLUG_EMUOPL +-#define H_ADPLUG_EMUOPL +- +-#include "opl.h" +-#include "fmopl.h" +- +-class CEmuopl: public Copl +-{ +- public: +- CEmuopl(int rate, bool bit16, bool usestereo); // rate = sample rate +- virtual ~CEmuopl(); +- +- void update(short *buf, int samples); // fill buffer +- void write(int reg, int val); +- +- void init(); +- void settype(ChipType type); +- +- private: +- bool use16bit, stereo; +- FM_OPL *opl[2]; // OPL2 emulator data +- short *mixbuf0, *mixbuf1; +- int mixbufSamples; +-}; +- +-#endif +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/flash.cc audacious-plugins-3.9/src/adplug/core/flash.cc +--- audacious-plugins-3.9-orig/src/adplug/core/flash.cc 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/flash.cc 1970-01-01 01:00:00.000000000 +0100 +@@ -1,230 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2003 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * [xad] FLASH player, by Riven the Mage +- */ +- +-/* +- - discovery - +- +- file(s) : LA-INTRO.EXE +- type : Lunatic Asylum BBStro +- tune : by Rogue [Logic Design] +- player : by Flash [Logic Design] +-*/ +- +-#include "flash.h" +-#include "debug.h" +- +-const unsigned char CxadflashPlayer::flash_adlib_registers[99] = +-{ +- 0x23, 0x20, 0x43, 0x40, 0x63, 0x60, 0x83, 0x80, 0xC0, 0xE3, 0xE0, +- 0x24, 0x21, 0x44, 0x41, 0x64, 0x61, 0x84, 0x81, 0xC1, 0xE4, 0xE1, +- 0x25, 0x22, 0x45, 0x42, 0x65, 0x62, 0x85, 0x82, 0xC2, 0xE5, 0xE2, +- 0x2B, 0x28, 0x4B, 0x48, 0x6B, 0x68, 0x8B, 0x88, 0xC3, 0xEB, 0xE8, +- 0x2C, 0x29, 0x4C, 0x49, 0x6C, 0x69, 0x8C, 0x89, 0xC4, 0xEC, 0xE9, +- 0x2D, 0x2A, 0x4D, 0x4A, 0x6D, 0x6A, 0x8D, 0x8A, 0xC5, 0xED, 0xEA, +- 0x33, 0x30, 0x53, 0x50, 0x73, 0x70, 0x93, 0x90, 0xC6, 0xF3, 0xF0, +- 0x34, 0x31, 0x54, 0x51, 0x74, 0x71, 0x94, 0x91, 0xC7, 0xF4, 0xF1, +- 0x35, 0x32, 0x55, 0x52, 0x75, 0x72, 0x95, 0x92, 0xC8, 0xF5, 0xF2 +-}; +- +-const unsigned short CxadflashPlayer::flash_notes_encoded[268] = +-{ +- 0x000, +- 0x100, 0x200, 0x300, 0x400, 0x500, 0x600, 0x700, 0x800, 0x900, 0xA00, 0xB00, 0xC00, +- 0x101, 0x201, 0x301, 0x401, 0x501, 0x601, 0x701, 0x801, 0x901, 0xA01, 0xB01, 0xC01, +- 0x102, 0x202, 0x302, 0x402, 0x502, 0x602, 0x702, 0x802, 0x902, 0xA02, 0xB02, 0xC02, +- 0x103, 0x203, 0x303, 0x403, 0x503, 0x603, 0x703, 0x803, 0x903, 0xA03, 0xB03, 0xC03, +- 0x104, 0x204, 0x304, 0x404, 0x504, 0x604, 0x704, 0x804, 0x904, 0xA04, 0xB04, 0xC04, +- 0x105, 0x205, 0x305, 0x405, 0x505, 0x605, 0x705, 0x805, 0x905, 0xA05, 0xB05, 0xC05, +- 0x106, 0x206, 0x306, 0x406, 0x506, 0x606, 0x706, 0x806, 0x906, 0xA06, 0xB06, 0xC06, +- 0x107, 0x207, 0x307, 0x407, 0x507, 0x607, 0x707, 0x807, 0x907, 0xA07, 0xB07, 0xC07, +- 0x108, 0x208, 0x308, 0x408, 0x508, 0x608, 0x708, 0x808, 0x908, 0xA08, 0xB08, 0xC08, +- 0x109, 0x209, 0x309, 0x409, 0x509, 0x609, 0x709, 0x809, 0x909, 0xA09, 0xB09, 0xC09, +- 0x10A, 0x20A, 0x30A, 0x40A, 0x50A, 0x60A, 0x70A, 0x80A, 0x90A, 0xA0A, 0xB0A, 0xC0A, +- 0x10B, 0x20B, 0x30B, 0x40B, 0x50B, 0x60B, 0x70B, 0x80B, 0x90B, 0xA0B, 0xB0B, 0xC0B, +- 0x10C, 0x20C, 0x30C, 0x40C, 0x50C, 0x60C, 0x70C, 0x80C, 0x90C, 0xA0C, 0xB0C, 0xC0C, +- 0x10D, 0x20D, 0x30D, 0x40D, 0x50D, 0x60D, 0x70D, 0x80D, 0x90D, 0xA0D, 0xB0D, 0xC0D, +- 0x10E, 0x20E, 0x30E, 0x40E, 0x50E, 0x60E, 0x70E, 0x80E, 0x90E, 0xA0E, 0xB0E, 0xC0E, +- 0x10F, 0x20F, 0x30F, 0x40F, 0x50F, 0x60F, 0x70F, 0x80F, 0x90F, 0xA0F, 0xB0F, 0xC0F, +- 0x110, 0x210, 0x310, 0x410, 0x510, 0x610, 0x710, 0x810, 0x910, 0xA10, 0xB10, 0xC10, +- 0x111, 0x211, 0x311, 0x411, 0x511, 0x611, 0x711, 0x811, 0x911, 0xA11, 0xB11, 0xC11, +- 0x112, 0x212, 0x312, 0x412, 0x512, 0x612, 0x712, 0x812, 0x912, 0xA12, 0xB12, 0xC12, +- 0x113, 0x213, 0x313, 0x413, 0x513, 0x613, 0x713, 0x813, 0x913, 0xA13, 0xB13, 0xC13, +- 0x114, 0x214, 0x314, 0x414, 0x514, 0x614, 0x714, 0x814, 0x914, 0xA14, 0xB14, 0xC14, +- 0x115, 0x215, 0x315 +-}; +- +-const unsigned short CxadflashPlayer::flash_notes[12] = +-{ +- 0x157, 0x16B, 0x181, 0x198, 0x1B0, 0x1CA, 0x1E5, 0x202, 0x220, 0x241, 0x263, 0x287 +-}; +- +-const unsigned char CxadflashPlayer::flash_default_instrument[8] = +-{ +- 0x00, 0x00, 0x3F, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF +-}; +- +-CPlayer *CxadflashPlayer::factory(Copl *newopl) +-{ +- return new CxadflashPlayer(newopl); +-} +- +-void CxadflashPlayer::xadplayer_rewind(int subsong) +-{ +- int i; +- +- plr.speed = xad.speed; +- +- flash.order_pos = 0; +- flash.pattern_pos = 0; +- +- opl_write(0x08, 0x00); +- opl_write(0xBD, 0x00); +- +- // assign default instrument +- for(i=0; i<9; i++) +- { +- opl_write(0xA0+i, 0x00); +- opl_write(0xB0+i, 0x00); +- } +- +- // assign instruments +- for(i=0; i<9; i++) +- for(int j=0; j<11; j++) +- opl_write(flash_adlib_registers[i*11+j], tune[i*12+j]); +-} +- +-void CxadflashPlayer::xadplayer_update() +-{ +- unsigned short event_pos = (tune[0x600+flash.order_pos]*1152) + \ +- (flash.pattern_pos*18) + \ +- 0x633; +- +- for (int i=0; i<9; i++) +- { +- unsigned short flash_channel_freq = (adlib[0xB0+i] << 8) + adlib[0xA0+i]; +- +- unsigned char event_b0 = tune[event_pos++]; +- unsigned char event_b1 = tune[event_pos++]; +-#ifdef DEBUG +- AdPlug_LogWrite("channel %02X, event %02X %02X:\n",i+1,event_b0,event_b1); +-#endif +- +- if (event_b0 == 0x80) // 0.0x80: Set Instrument +- { +- for(int j=0; j<11; j++) +- opl_write(flash_adlib_registers[i*11+j], tune[event_b1*12+j]); +- } +- else +- { +- if (event_b1 == 0x01) +- flash.pattern_pos = 0x3F; // 1.0x01: Pattern Break +- +- unsigned char fx = (event_b1 >> 4); +- unsigned char fx_p = (event_b1 & 0x0F); +- +- switch(fx) +- { +- case 0x0A: // 1.0xAy: Set Carrier volume +- opl_write(flash_adlib_registers[11*i+2], fx_p << 2); +- break; +- case 0x0B: // 1.0xBy: Set Modulator volume +- opl_write(flash_adlib_registers[11*i+3], fx_p << 2); +- break; +- case 0x0C: // 1.0xCy: Set both operators volume +- opl_write(flash_adlib_registers[11*i+2], fx_p << 2); +- opl_write(flash_adlib_registers[11*i+3], fx_p << 2); +- break; +-// case 0x0E: // 1.0xEy: ? (increase some value) +- case 0x0F: // 1.0xFy: Set Speed +- plr.speed = (fx_p + 1); +- break; +- } +- +- if (event_b0) +- { +- // mute channel +- opl_write(0xA0+i, adlib[0xA0+i]); +- opl_write(0xB0+i, adlib[0xB0+i] & 0xDF); +- +- // is note ? +- if (event_b0 != 0x7F) +- { +- unsigned short note_encoded = flash_notes_encoded[event_b0]; +- unsigned short freq = flash_notes[(note_encoded >> 8) - 1]; +- +- flash_channel_freq = freq | ((note_encoded & 0xFF) << 10) | 0x2000; +- +- opl_write(0xA0+i, flash_channel_freq & 0xFF); +- opl_write(0xB0+i, flash_channel_freq >> 8); +- } +- } +- +- if (fx == 0x01) // 1.0x1y: Fine Frequency Slide Up +- { +- flash_channel_freq += (fx_p << 1); +- +- opl_write(0xA0+i, flash_channel_freq & 0xFF); +- opl_write(0xB0+i, flash_channel_freq >> 8); +- } +- else if (fx == 0x02) // 1.0x2y: Fine Frequency Slide Down +- { +- flash_channel_freq -= (fx_p << 1); +- +- opl_write(0xA0+i, flash_channel_freq & 0xFF); +- opl_write(0xB0+i, flash_channel_freq >> 8); +- } +- } +- } +- +- // next row +- flash.pattern_pos++; +- +- // end of pattern ? +- if (flash.pattern_pos >= 0x40) +- { +- flash.pattern_pos = 0; +- +- flash.order_pos++; +- +- // end of module ? +- if (tune[0x600+flash.order_pos] == 0xFF) +- { +- flash.order_pos = 0; +- +- plr.looping = 1; +- } +- } +-} +- +-float CxadflashPlayer::xadplayer_getrefresh() +-{ +- return 17.5f; +-} +- +-std::string CxadflashPlayer::xadplayer_gettype() +-{ +- return std::string("xad: flash player"); +-} +- +-unsigned int CxadflashPlayer::xadplayer_getinstruments() +-{ +- return 32; +-} +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/flash.h audacious-plugins-3.9/src/adplug/core/flash.h +--- audacious-plugins-3.9-orig/src/adplug/core/flash.h 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/flash.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,57 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2003 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * [xad] FLASH player, by Riven the Mage +- */ +- +-#include "xad.h" +- +-class CxadflashPlayer: public CxadPlayer +-{ +-public: +- static CPlayer *factory(Copl *newopl); +- +- CxadflashPlayer(Copl *newopl): CxadPlayer(newopl) +- { }; +- +-protected: +- struct +- { +- unsigned char order_pos; +- unsigned char pattern_pos; +- } flash; +- // +- bool xadplayer_load() +- { +- if(xad.fmt == FLASH) +- return true; +- else +- return false; +- } +- void xadplayer_rewind(int subsong); +- void xadplayer_update(); +- float xadplayer_getrefresh(); +- std::string xadplayer_gettype(); +- unsigned int xadplayer_getinstruments(); +- +-private: +- static const unsigned char flash_adlib_registers[99]; +- static const unsigned short flash_notes_encoded[268]; +- static const unsigned short flash_notes[12]; +- static const unsigned char flash_default_instrument[8]; +-}; +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/fmc.cc audacious-plugins-3.9/src/adplug/core/fmc.cc +--- audacious-plugins-3.9-orig/src/adplug/core/fmc.cc 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/fmc.cc 1970-01-01 01:00:00.000000000 +0100 +@@ -1,225 +0,0 @@ +-/* +- Adplug - Replayer for many OPL2/OPL3 audio file formats. +- Copyright (C) 1999 - 2007 Simon Peter , et al. +- +- This library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- This library 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 +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with this library; if not, write to the Free Software +- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- +- fmc.cpp - FMC Loader by Riven the Mage +-*/ +- +-#include +-#include "fmc.h" +- +-/* -------- Public Methods -------------------------------- */ +- +-CPlayer *CfmcLoader::factory(Copl *newopl) +-{ +- return new CfmcLoader(newopl); +-} +- +-bool CfmcLoader::load(const std::string &filename, const CFileProvider &fp) +-{ +- binistream *f = fp.open(filename); if(!f) return false; +- const unsigned char conv_fx[16] = {0,1,2,3,4,8,255,255,255,255,26,11,12,13,14,15}; +- +- int i,j,k,t=0; +- +- // read header +- f->readString(header.id, 4); +- f->readString(header.title, 21); +- header.numchan = f->readInt(1); +- +- // 'FMC!' - signed ? +- if (strncmp(header.id,"FMC!",4)) { fp.close(f); return false; } +- +- // init CmodPlayer +- realloc_instruments(32); +- realloc_order(256); +- realloc_patterns(64,64,header.numchan); +- init_trackord(); +- +- // load order +- for(i = 0; i < 256; i++) order[i] = f->readInt(1); +- +- f->ignore(2); +- +- // load instruments +- for(i = 0; i < 32; i++) { +- instruments[i].synthesis = f->readInt(1); +- instruments[i].feedback = f->readInt(1); +- +- instruments[i].mod_attack = f->readInt(1); +- instruments[i].mod_decay = f->readInt(1); +- instruments[i].mod_sustain = f->readInt(1); +- instruments[i].mod_release = f->readInt(1); +- instruments[i].mod_volume = f->readInt(1); +- instruments[i].mod_ksl = f->readInt(1); +- instruments[i].mod_freq_multi = f->readInt(1); +- instruments[i].mod_waveform = f->readInt(1); +- instruments[i].mod_sustain_sound = f->readInt(1); +- instruments[i].mod_ksr = f->readInt(1); +- instruments[i].mod_vibrato = f->readInt(1); +- instruments[i].mod_tremolo = f->readInt(1); +- +- instruments[i].car_attack = f->readInt(1); +- instruments[i].car_decay = f->readInt(1); +- instruments[i].car_sustain = f->readInt(1); +- instruments[i].car_release = f->readInt(1); +- instruments[i].car_volume = f->readInt(1); +- instruments[i].car_ksl = f->readInt(1); +- instruments[i].car_freq_multi = f->readInt(1); +- instruments[i].car_waveform = f->readInt(1); +- instruments[i].car_sustain_sound = f->readInt(1); +- instruments[i].car_ksr = f->readInt(1); +- instruments[i].car_vibrato = f->readInt(1); +- instruments[i].car_tremolo = f->readInt(1); +- +- instruments[i].pitch_shift = f->readInt(1); +- +- f->readString(instruments[i].name, 21); +- } +- +- // load tracks +- for (i=0;i<64;i++) +- { +- if(f->ateof()) break; +- +- for (j=0;jreadInt(1); +- event.byte1 = f->readInt(1); +- event.byte2 = f->readInt(1); +- +- // convert event +- tracks[t][k].note = event.byte0 & 0x7F; +- tracks[t][k].inst = ((event.byte0 & 0x80) >> 3) + (event.byte1 >> 4) + 1; +- tracks[t][k].command = conv_fx[event.byte1 & 0x0F]; +- tracks[t][k].param1 = event.byte2 >> 4; +- tracks[t][k].param2 = event.byte2 & 0x0F; +- +- // fix effects +- if (tracks[t][k].command == 0x0E) // 0x0E (14): Retrig +- tracks[t][k].param1 = 3; +- if (tracks[t][k].command == 0x1A) { // 0x1A (26): Volume Slide +- if (tracks[t][k].param1 > tracks[t][k].param2) +- { +- tracks[t][k].param1 -= tracks[t][k].param2; +- tracks[t][k].param2 = 0; +- } +- else +- { +- tracks[t][k].param2 -= tracks[t][k].param1; +- tracks[t][k].param1 = 0; +- } +- } +- } +- +- t++; +- } +- } +- fp.close(f); +- +- // convert instruments +- for (i=0;i<31;i++) +- buildinst(i); +- +- // order length +- for (i=0;i<256;i++) +- { +- if (order[i] >= 0xFE) +- { +- length = i; +- break; +- } +- } +- +- // data for Protracker +- activechan = (0xffffffff >> (32 - header.numchan)) << (32 - header.numchan); +- nop = t / header.numchan; +- restartpos = 0; +- +- // flags +- flags = Faust; +- +- rewind(0); +- +- return true; +-} +- +-float CfmcLoader::getrefresh() +-{ +- return 50.0f; +-} +- +-std::string CfmcLoader::gettype() +-{ +- return std::string("Faust Music Creator"); +-} +- +-std::string CfmcLoader::gettitle() +-{ +- return std::string(header.title); +-} +- +-std::string CfmcLoader::getinstrument(unsigned int n) +-{ +- return std::string(instruments[n].name); +-} +- +-unsigned int CfmcLoader::getinstruments() +-{ +- return 32; +-} +- +-/* -------- Private Methods ------------------------------- */ +- +-void CfmcLoader::buildinst(unsigned char i) +-{ +- inst[i].data[0] = ((instruments[i].synthesis & 1) ^ 1); +- inst[i].data[0] |= ((instruments[i].feedback & 7) << 1); +- +- inst[i].data[3] = ((instruments[i].mod_attack & 15) << 4); +- inst[i].data[3] |= (instruments[i].mod_decay & 15); +- inst[i].data[5] = ((15 - (instruments[i].mod_sustain & 15)) << 4); +- inst[i].data[5] |= (instruments[i].mod_release & 15); +- inst[i].data[9] = (63 - (instruments[i].mod_volume & 63)); +- inst[i].data[9] |= ((instruments[i].mod_ksl & 3) << 6); +- inst[i].data[1] = (instruments[i].mod_freq_multi & 15); +- inst[i].data[7] = (instruments[i].mod_waveform & 3); +- inst[i].data[1] |= ((instruments[i].mod_sustain_sound & 1) << 5); +- inst[i].data[1] |= ((instruments[i].mod_ksr & 1) << 4); +- inst[i].data[1] |= ((instruments[i].mod_vibrato & 1) << 6); +- inst[i].data[1] |= ((instruments[i].mod_tremolo & 1) << 7); +- +- inst[i].data[4] = ((instruments[i].car_attack & 15) << 4); +- inst[i].data[4] |= (instruments[i].car_decay & 15); +- inst[i].data[6] = ((15 - (instruments[i].car_sustain & 15)) << 4); +- inst[i].data[6] |= (instruments[i].car_release & 15); +- inst[i].data[10] = (63 - (instruments[i].car_volume & 63)); +- inst[i].data[10] |= ((instruments[i].car_ksl & 3) << 6); +- inst[i].data[2] = (instruments[i].car_freq_multi & 15); +- inst[i].data[8] = (instruments[i].car_waveform & 3); +- inst[i].data[2] |= ((instruments[i].car_sustain_sound & 1) << 5); +- inst[i].data[2] |= ((instruments[i].car_ksr & 1) << 4); +- inst[i].data[2] |= ((instruments[i].car_vibrato & 1) << 6); +- inst[i].data[2] |= ((instruments[i].car_tremolo & 1) << 7); +- +- inst[i].slide = instruments[i].pitch_shift; +-} +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/fmc.h audacious-plugins-3.9/src/adplug/core/fmc.h +--- audacious-plugins-3.9-orig/src/adplug/core/fmc.h 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/fmc.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,91 +0,0 @@ +-/* +- Adplug - Replayer for many OPL2/OPL3 audio file formats. +- Copyright (C) 1999 - 2003 Simon Peter, , et al. +- +- This library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- This library 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 +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with this library; if not, write to the Free Software +- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- +- fmc.h - FMC loader by Riven the Mage +-*/ +- +-#include "protrack.h" +- +-class CfmcLoader: public CmodPlayer +-{ +- public: +- static CPlayer *factory(Copl *newopl); +- +- CfmcLoader(Copl *newopl) : CmodPlayer(newopl) { }; +- +- bool load(const std::string &filename, const CFileProvider &fp); +- float getrefresh(); +- +- std::string gettype(); +- std::string gettitle(); +- std::string getinstrument(unsigned int n); +- unsigned int getinstruments(); +- +- private: +- +- struct fmc_event +- { +- unsigned char byte0; +- unsigned char byte1; +- unsigned char byte2; +- }; +- +- struct fmc_header +- { +- char id[4]; +- char title[21]; +- unsigned char numchan; +- } header; +- +- struct fmc_instrument +- { +- unsigned char synthesis; +- unsigned char feedback; +- +- unsigned char mod_attack; +- unsigned char mod_decay; +- unsigned char mod_sustain; +- unsigned char mod_release; +- unsigned char mod_volume; +- unsigned char mod_ksl; +- unsigned char mod_freq_multi; +- unsigned char mod_waveform; +- unsigned char mod_sustain_sound; +- unsigned char mod_ksr; +- unsigned char mod_vibrato; +- unsigned char mod_tremolo; +- unsigned char car_attack; +- unsigned char car_decay; +- unsigned char car_sustain; +- unsigned char car_release; +- unsigned char car_volume; +- unsigned char car_ksl; +- unsigned char car_freq_multi; +- unsigned char car_waveform; +- unsigned char car_sustain_sound; +- unsigned char car_ksr; +- unsigned char car_vibrato; +- unsigned char car_tremolo; +- +- signed char pitch_shift; +- +- char name[21]; +- } instruments[32]; +- +- void buildinst(unsigned char i); +-}; +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/fmopl.cc audacious-plugins-3.9/src/adplug/core/fmopl.cc +--- audacious-plugins-3.9-orig/src/adplug/core/fmopl.cc 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/fmopl.cc 1970-01-01 01:00:00.000000000 +0100 +@@ -1,1392 +0,0 @@ +-/* +-** +-** File: fmopl.c -- software implementation of FM sound generator +-** +-** Copyright (C) 1999,2000 Tatsuyuki Satoh , MultiArcadeMachineEmurator development +-** +-** Version 0.37a +-** +-*/ +- +-/* +- preliminary : +- Problem : +- note: +-*/ +- +-/* This version of fmopl.c is a fork of the MAME one, relicensed under the LGPL. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- */ +- +-#define INLINE __inline +-#define HAS_YM3812 1 +- +-#include +-#include +-#include +-#include +-#include +-//#include "driver.h" /* use M.A.M.E. */ +-#include "fmopl.h" +- +-#ifndef PI +-#define PI 3.14159265358979323846 +-#endif +- +-/* -------------------- for debug --------------------- */ +-/* #define OPL_OUTPUT_LOG */ +-#ifdef OPL_OUTPUT_LOG +-static FILE *opl_dbg_fp = NULL; +-static FM_OPL *opl_dbg_opl[16]; +-static int opl_dbg_maxchip,opl_dbg_chip; +-#endif +- +-/* -------------------- preliminary define section --------------------- */ +-/* attack/decay rate time rate */ +-#define OPL_ARRATE 141280 /* RATE 4 = 2826.24ms @ 3.6MHz */ +-#define OPL_DRRATE 1956000 /* RATE 4 = 39280.64ms @ 3.6MHz */ +- +-#define DELTAT_MIXING_LEVEL (1) /* DELTA-T ADPCM MIXING LEVEL */ +- +-#define FREQ_BITS 24 /* frequency turn */ +- +-/* counter bits = 20 , octerve 7 */ +-#define FREQ_RATE (1<<(FREQ_BITS-20)) +-#define TL_BITS (FREQ_BITS+2) +- +-/* final output shift , limit minimum and maximum */ +-#define OPL_OUTSB (TL_BITS+3-16) /* OPL output final shift 16bit */ +-#define OPL_MAXOUT (0x7fff<=LOG_LEVEL ) logerror x +-#define LOG(n,x) +- +-/* --------------------- subroutines --------------------- */ +- +-INLINE int Limit( int val, int max, int min ) { +- if ( val > max ) +- val = max; +- else if ( val < min ) +- val = min; +- +- return val; +-} +- +-/* status set and IRQ handling */ +-INLINE void OPL_STATUS_SET(FM_OPL *OPL,int flag) +-{ +- /* set status flag */ +- OPL->status |= flag; +- if(!(OPL->status & 0x80)) +- { +- if(OPL->status & OPL->statusmask) +- { /* IRQ on */ +- OPL->status |= 0x80; +- /* callback user interrupt handler (IRQ is OFF to ON) */ +- if(OPL->IRQHandler) (OPL->IRQHandler)(OPL->IRQParam,1); +- } +- } +-} +- +-/* status reset and IRQ handling */ +-INLINE void OPL_STATUS_RESET(FM_OPL *OPL,int flag) +-{ +- /* reset status flag */ +- OPL->status &=~flag; +- if((OPL->status & 0x80)) +- { +- if (!(OPL->status & OPL->statusmask) ) +- { +- OPL->status &= 0x7f; +- /* callback user interrupt handler (IRQ is ON to OFF) */ +- if(OPL->IRQHandler) (OPL->IRQHandler)(OPL->IRQParam,0); +- } +- } +-} +- +-/* IRQ mask set */ +-INLINE void OPL_STATUSMASK_SET(FM_OPL *OPL,int flag) +-{ +- OPL->statusmask = flag; +- /* IRQ handling check */ +- OPL_STATUS_SET(OPL,0); +- OPL_STATUS_RESET(OPL,0); +-} +- +-/* ----- key on ----- */ +-INLINE void OPL_KEYON(OPL_SLOT *SLOT) +-{ +- /* sin wave restart */ +- SLOT->Cnt = 0; +- /* set attack */ +- SLOT->evm = ENV_MOD_AR; +- SLOT->evs = SLOT->evsa; +- SLOT->evc = EG_AST; +- SLOT->eve = EG_AED; +-} +-/* ----- key off ----- */ +-INLINE void OPL_KEYOFF(OPL_SLOT *SLOT) +-{ +- if( SLOT->evm > ENV_MOD_RR) +- { +- /* set envelope counter from envleope output */ +- SLOT->evm = ENV_MOD_RR; +- if( !(SLOT->evc&EG_DST) ) +- //SLOT->evc = (ENV_CURVE[SLOT->evc>>ENV_BITS]<evc = EG_DST; +- SLOT->eve = EG_DED; +- SLOT->evs = SLOT->evsr; +- } +-} +- +-/* ---------- calcrate Envelope Generator & Phase Generator ---------- */ +-/* return : envelope output */ +-INLINE UINT32 OPL_CALC_SLOT( OPL_SLOT *SLOT ) +-{ +- /* calcrate envelope generator */ +- if( (SLOT->evc+=SLOT->evs) >= SLOT->eve ) +- { +- switch( SLOT->evm ){ +- case ENV_MOD_AR: /* ATTACK -> DECAY1 */ +- /* next DR */ +- SLOT->evm = ENV_MOD_DR; +- SLOT->evc = EG_DST; +- SLOT->eve = SLOT->SL; +- SLOT->evs = SLOT->evsd; +- break; +- case ENV_MOD_DR: /* DECAY -> SL or RR */ +- SLOT->evc = SLOT->SL; +- SLOT->eve = EG_DED; +- if(SLOT->eg_typ) +- { +- SLOT->evs = 0; +- } +- else +- { +- SLOT->evm = ENV_MOD_RR; +- SLOT->evs = SLOT->evsr; +- } +- break; +- case ENV_MOD_RR: /* RR -> OFF */ +- SLOT->evc = EG_OFF; +- SLOT->eve = EG_OFF+1; +- SLOT->evs = 0; +- break; +- } +- } +- /* calcrate envelope */ +- return SLOT->TLL+ENV_CURVE[SLOT->evc>>ENV_BITS]+(SLOT->ams ? ams : 0); +-} +- +-/* set algorythm connection */ +-static void set_algorythm( OPL_CH *CH) +-{ +- INT32 *carrier = &outd[0]; +- CH->connect1 = CH->CON ? carrier : &feedback2; +- CH->connect2 = carrier; +-} +- +-/* ---------- frequency counter for operater update ---------- */ +-INLINE void CALC_FCSLOT(OPL_CH *CH,OPL_SLOT *SLOT) +-{ +- int ksr; +- +- /* frequency step counter */ +- SLOT->Incr = CH->fc * SLOT->mul; +- ksr = CH->kcode >> SLOT->KSR; +- +- if( SLOT->ksr != ksr ) +- { +- SLOT->ksr = ksr; +- /* attack , decay rate recalcration */ +- SLOT->evsa = SLOT->AR[ksr]; +- SLOT->evsd = SLOT->DR[ksr]; +- SLOT->evsr = SLOT->RR[ksr]; +- } +- SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl); +-} +- +-/* set multi,am,vib,EG-TYP,KSR,mul */ +-INLINE void set_mul(FM_OPL *OPL,int slot,int v) +-{ +- OPL_CH *CH = &OPL->P_CH[slot/2]; +- OPL_SLOT *SLOT = &CH->SLOT[slot&1]; +- +- SLOT->mul = MUL_TABLE[v&0x0f]; +- SLOT->KSR = (v&0x10) ? 0 : 2; +- SLOT->eg_typ = (v&0x20)>>5; +- SLOT->vib = (v&0x40); +- SLOT->ams = (v&0x80); +- CALC_FCSLOT(CH,SLOT); +-} +- +-/* set ksl & tl */ +-INLINE void set_ksl_tl(FM_OPL *OPL,int slot,int v) +-{ +- OPL_CH *CH = &OPL->P_CH[slot/2]; +- OPL_SLOT *SLOT = &CH->SLOT[slot&1]; +- int ksl = v>>6; /* 0 / 1.5 / 3 / 6 db/OCT */ +- +- SLOT->ksl = ksl ? 3-ksl : 31; +- SLOT->TL = (v&0x3f)*(0.75/EG_STEP); /* 0.75db step */ +- +- if( !(OPL->mode&0x80) ) +- { /* not CSM latch total level */ +- SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl); +- } +-} +- +-/* set attack rate & decay rate */ +-INLINE void set_ar_dr(FM_OPL *OPL,int slot,int v) +-{ +- OPL_CH *CH = &OPL->P_CH[slot/2]; +- OPL_SLOT *SLOT = &CH->SLOT[slot&1]; +- int ar = v>>4; +- int dr = v&0x0f; +- +- SLOT->AR = ar ? &OPL->AR_TABLE[ar<<2] : RATE_0; +- SLOT->evsa = SLOT->AR[SLOT->ksr]; +- if( SLOT->evm == ENV_MOD_AR ) SLOT->evs = SLOT->evsa; +- +- SLOT->DR = dr ? &OPL->DR_TABLE[dr<<2] : RATE_0; +- SLOT->evsd = SLOT->DR[SLOT->ksr]; +- if( SLOT->evm == ENV_MOD_DR ) SLOT->evs = SLOT->evsd; +-} +- +-/* set sustain level & release rate */ +-INLINE void set_sl_rr(FM_OPL *OPL,int slot,int v) +-{ +- OPL_CH *CH = &OPL->P_CH[slot/2]; +- OPL_SLOT *SLOT = &CH->SLOT[slot&1]; +- int sl = v>>4; +- int rr = v & 0x0f; +- +- SLOT->SL = SL_TABLE[sl]; +- if( SLOT->evm == ENV_MOD_DR ) SLOT->eve = SLOT->SL; +- SLOT->RR = &OPL->DR_TABLE[rr<<2]; +- SLOT->evsr = SLOT->RR[SLOT->ksr]; +- if( SLOT->evm == ENV_MOD_RR ) SLOT->evs = SLOT->evsr; +-} +- +-/* operator output calcrator */ +-#define OP_OUT(slot,env,con) slot->wavetable[((slot->Cnt+con)/(0x1000000/SIN_ENT))&(SIN_ENT-1)][env] +-/* ---------- calcrate one of channel ---------- */ +-INLINE void OPL_CALC_CH( OPL_CH *CH ) +-{ +- UINT32 env_out; +- OPL_SLOT *SLOT; +- +- feedback2 = 0; +- /* SLOT 1 */ +- SLOT = &CH->SLOT[SLOT1]; +- env_out=OPL_CALC_SLOT(SLOT); +- if( env_out < EG_ENT-1 ) +- { +- /* PG */ +- if(SLOT->vib) SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE); +- else SLOT->Cnt += SLOT->Incr; +- /* connectoion */ +- if(CH->FB) +- { +- int feedback1 = (CH->op1_out[0]+CH->op1_out[1])>>CH->FB; +- CH->op1_out[1] = CH->op1_out[0]; +- *CH->connect1 += CH->op1_out[0] = OP_OUT(SLOT,env_out,feedback1); +- } +- else +- { +- *CH->connect1 += OP_OUT(SLOT,env_out,0); +- } +- }else +- { +- CH->op1_out[1] = CH->op1_out[0]; +- CH->op1_out[0] = 0; +- } +- /* SLOT 2 */ +- SLOT = &CH->SLOT[SLOT2]; +- env_out=OPL_CALC_SLOT(SLOT); +- if( env_out < EG_ENT-1 ) +- { +- /* PG */ +- if(SLOT->vib) SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE); +- else SLOT->Cnt += SLOT->Incr; +- /* connectoion */ +- outd[0] += OP_OUT(SLOT,env_out, feedback2); +- } +-} +- +-/* ---------- calcrate rythm block ---------- */ +-#define WHITE_NOISE_db 6.0 +-INLINE void OPL_CALC_RH( OPL_CH *CH ) +-{ +- UINT32 env_tam,env_sd,env_top,env_hh; +- int whitenoise = (rand()&1)*(WHITE_NOISE_db/EG_STEP); +- INT32 tone8; +- +- OPL_SLOT *SLOT; +- int env_out; +- +- /* BD : same as FM serial mode and output level is large */ +- feedback2 = 0; +- /* SLOT 1 */ +- SLOT = &CH[6].SLOT[SLOT1]; +- env_out=OPL_CALC_SLOT(SLOT); +- if( env_out < EG_ENT-1 ) +- { +- /* PG */ +- if(SLOT->vib) SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE); +- else SLOT->Cnt += SLOT->Incr; +- /* connectoion */ +- if(CH[6].FB) +- { +- int feedback1 = (CH[6].op1_out[0]+CH[6].op1_out[1])>>CH[6].FB; +- CH[6].op1_out[1] = CH[6].op1_out[0]; +- feedback2 = CH[6].op1_out[0] = OP_OUT(SLOT,env_out,feedback1); +- } +- else +- { +- feedback2 = OP_OUT(SLOT,env_out,0); +- } +- }else +- { +- feedback2 = 0; +- CH[6].op1_out[1] = CH[6].op1_out[0]; +- CH[6].op1_out[0] = 0; +- } +- /* SLOT 2 */ +- SLOT = &CH[6].SLOT[SLOT2]; +- env_out=OPL_CALC_SLOT(SLOT); +- if( env_out < EG_ENT-1 ) +- { +- /* PG */ +- if(SLOT->vib) SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE); +- else SLOT->Cnt += SLOT->Incr; +- /* connectoion */ +- outd[0] += OP_OUT(SLOT,env_out, feedback2)*2; +- } +- +- // SD (17) = mul14[fnum7] + white noise +- // TAM (15) = mul15[fnum8] +- // TOP (18) = fnum6(mul18[fnum8]+whitenoise) +- // HH (14) = fnum7(mul18[fnum8]+whitenoise) + white noise +- env_sd =OPL_CALC_SLOT(SLOT7_2) + whitenoise; +- env_tam=OPL_CALC_SLOT(SLOT8_1); +- env_top=OPL_CALC_SLOT(SLOT8_2); +- env_hh =OPL_CALC_SLOT(SLOT7_1) + whitenoise; +- +- /* PG */ +- if(SLOT7_1->vib) SLOT7_1->Cnt += (2*SLOT7_1->Incr*vib/VIB_RATE); +- else SLOT7_1->Cnt += 2*SLOT7_1->Incr; +- if(SLOT7_2->vib) SLOT7_2->Cnt += ((CH[7].fc*8)*vib/VIB_RATE); +- else SLOT7_2->Cnt += (CH[7].fc*8); +- if(SLOT8_1->vib) SLOT8_1->Cnt += (SLOT8_1->Incr*vib/VIB_RATE); +- else SLOT8_1->Cnt += SLOT8_1->Incr; +- if(SLOT8_2->vib) SLOT8_2->Cnt += ((CH[8].fc*48)*vib/VIB_RATE); +- else SLOT8_2->Cnt += (CH[8].fc*48); +- +- tone8 = OP_OUT(SLOT8_2,whitenoise,0 ); +- +- /* SD */ +- if( env_sd < EG_ENT-1 ) +- outd[0] += OP_OUT(SLOT7_1,env_sd, 0)*8; +- /* TAM */ +- if( env_tam < EG_ENT-1 ) +- outd[0] += OP_OUT(SLOT8_1,env_tam, 0)*2; +- /* TOP-CY */ +- if( env_top < EG_ENT-1 ) +- outd[0] += OP_OUT(SLOT7_2,env_top,tone8)*2; +- /* HH */ +- if( env_hh < EG_ENT-1 ) +- outd[0] += OP_OUT(SLOT7_2,env_hh,tone8)*2; +-} +- +-/* ----------- initialize time tabls ----------- */ +-static void init_timetables( FM_OPL *OPL , int ARRATE , int DRRATE ) +-{ +- int i; +- double rate; +- +- /* make attack rate & decay rate tables */ +- for (i = 0;i < 4;i++) OPL->AR_TABLE[i] = OPL->DR_TABLE[i] = 0; +- for (i = 4;i <= 60;i++){ +- rate = OPL->freqbase; /* frequency rate */ +- if( i < 60 ) rate *= 1.0+(i&3)*0.25; /* b0-1 : x1 , x1.25 , x1.5 , x1.75 */ +- rate *= 1<<((i>>2)-1); /* b2-5 : shift bit */ +- rate *= (double)(EG_ENT<AR_TABLE[i] = rate / ARRATE; +- OPL->DR_TABLE[i] = rate / DRRATE; +- } +- for (i = 60;i < 75;i++) +- { +- OPL->AR_TABLE[i] = EG_AED-1; +- OPL->DR_TABLE[i] = OPL->DR_TABLE[60]; +- } +-#if 0 +- for (i = 0;i < 64 ;i++){ /* make for overflow area */ +- LOG(LOG_WAR,("rate %2d , ar %f ms , dr %f ms \n",i, +- ((double)(EG_ENT<AR_TABLE[i]) * (1000.0 / OPL->rate), +- ((double)(EG_ENT<DR_TABLE[i]) * (1000.0 / OPL->rate) )); +- } +-#endif +-} +- +-/* ---------- generic table initialize ---------- */ +-static int OPLOpenTable( void ) +-{ +- int s,t; +- double rate; +- int i,j; +- double pom; +- +- /* allocate dynamic tables */ +- if( (TL_TABLE = (INT32*)malloc(TL_MAX*2*sizeof(INT32))) == NULL) +- return 0; +- if( (SIN_TABLE = (INT32**)malloc(SIN_ENT*4 *sizeof(INT32 *))) == NULL) +- { +- free(TL_TABLE); +- return 0; +- } +- if( (AMS_TABLE = (INT32*)malloc(AMS_ENT*2 *sizeof(INT32))) == NULL) +- { +- free(TL_TABLE); +- free(SIN_TABLE); +- return 0; +- } +- if( (VIB_TABLE = (INT32*)malloc(VIB_ENT*2 *sizeof(INT32))) == NULL) +- { +- free(TL_TABLE); +- free(SIN_TABLE); +- free(AMS_TABLE); +- return 0; +- } +- /* make total level table */ +- for (t = 0;t < EG_ENT-1 ;t++){ +- rate = ((1< voltage */ +- TL_TABLE[ t] = (int)rate; +- TL_TABLE[TL_MAX+t] = -TL_TABLE[t]; +-/* LOG(LOG_INF,("TotalLevel(%3d) = %x\n",t,TL_TABLE[t]));*/ +- } +- /* fill volume off area */ +- for ( t = EG_ENT-1; t < TL_MAX ;t++){ +- TL_TABLE[t] = TL_TABLE[TL_MAX+t] = 0; +- } +- +- /* make sinwave table (total level offet) */ +- /* degree 0 = degree 180 = off */ +- SIN_TABLE[0] = SIN_TABLE[SIN_ENT/2] = &TL_TABLE[EG_ENT-1]; +- for (s = 1;s <= SIN_ENT/4;s++){ +- pom = sin(2*PI*s/SIN_ENT); /* sin */ +- pom = 20*log10(1/pom); /* decibel */ +- j = pom / EG_STEP; /* TL_TABLE steps */ +- +- /* degree 0 - 90 , degree 180 - 90 : plus section */ +- SIN_TABLE[ s] = SIN_TABLE[SIN_ENT/2-s] = &TL_TABLE[j]; +- /* degree 180 - 270 , degree 360 - 270 : minus section */ +- SIN_TABLE[SIN_ENT/2+s] = SIN_TABLE[SIN_ENT -s] = &TL_TABLE[TL_MAX+j]; +-/* LOG(LOG_INF,("sin(%3d) = %f:%f db\n",s,pom,(double)j * EG_STEP));*/ +- } +- for (s = 0;s < SIN_ENT;s++) +- { +- SIN_TABLE[SIN_ENT*1+s] = s<(SIN_ENT/2) ? SIN_TABLE[s] : &TL_TABLE[EG_ENT]; +- SIN_TABLE[SIN_ENT*2+s] = SIN_TABLE[s % (SIN_ENT/2)]; +- SIN_TABLE[SIN_ENT*3+s] = (s/(SIN_ENT/4))&1 ? &TL_TABLE[EG_ENT] : SIN_TABLE[SIN_ENT*2+s]; +- } +- +- /* envelope counter -> envelope output table */ +- for (i=0; i= EG_ENT ) pom = EG_ENT-1; */ +- ENV_CURVE[i] = (int)pom; +- /* DECAY ,RELEASE curve */ +- ENV_CURVE[(EG_DST>>ENV_BITS)+i]= i; +- } +- /* off */ +- ENV_CURVE[EG_OFF>>ENV_BITS]= EG_ENT-1; +- /* make LFO ams table */ +- for (i=0; iSLOT[SLOT1]; +- OPL_SLOT *slot2 = &CH->SLOT[SLOT2]; +- /* all key off */ +- OPL_KEYOFF(slot1); +- OPL_KEYOFF(slot2); +- /* total level latch */ +- slot1->TLL = slot1->TL + (CH->ksl_base>>slot1->ksl); +- slot1->TLL = slot1->TL + (CH->ksl_base>>slot1->ksl); +- /* key on */ +- CH->op1_out[0] = CH->op1_out[1] = 0; +- OPL_KEYON(slot1); +- OPL_KEYON(slot2); +-} +- +-/* ---------- opl initialize ---------- */ +-static void OPL_initalize(FM_OPL *OPL) +-{ +- int fn; +- +- /* frequency base */ +- OPL->freqbase = (OPL->rate) ? ((double)OPL->clock / OPL->rate) / 72 : 0; +- /* Timer base time */ +- OPL->TimerBase = 1.0/((double)OPL->clock / 72.0 ); +- /* make time tables */ +- init_timetables( OPL , OPL_ARRATE , OPL_DRRATE ); +- /* make fnumber -> increment counter table */ +- for( fn=0 ; fn < 1024 ; fn++ ) +- { +- OPL->FN_TABLE[fn] = OPL->freqbase * fn * FREQ_RATE * (1<<7) / 2; +- } +- /* LFO freq.table */ +- OPL->amsIncr = OPL->rate ? (double)AMS_ENT*(1<rate * 3.7 * ((double)OPL->clock/3600000) : 0; +- OPL->vibIncr = OPL->rate ? (double)VIB_ENT*(1<rate * 6.4 * ((double)OPL->clock/3600000) : 0; +-} +- +-/* ---------- write a OPL registers ---------- */ +-static void OPLWriteReg(FM_OPL *OPL, int r, int v) +-{ +- OPL_CH *CH; +- int slot; +- int block_fnum; +- +- switch(r&0xe0) +- { +- case 0x00: /* 00-1f:controll */ +- switch(r&0x1f) +- { +- case 0x01: +- /* wave selector enable */ +- if(OPL->type&OPL_TYPE_WAVESEL) +- { +- OPL->wavesel = v&0x20; +- if(!OPL->wavesel) +- { +- /* preset compatible mode */ +- int c; +- for(c=0;cmax_ch;c++) +- { +- OPL->P_CH[c].SLOT[SLOT1].wavetable = &SIN_TABLE[0]; +- OPL->P_CH[c].SLOT[SLOT2].wavetable = &SIN_TABLE[0]; +- } +- } +- } +- return; +- case 0x02: /* Timer 1 */ +- OPL->T[0] = (256-v)*4; +- break; +- case 0x03: /* Timer 2 */ +- OPL->T[1] = (256-v)*16; +- return; +- case 0x04: /* IRQ clear / mask and Timer enable */ +- if(v&0x80) +- { /* IRQ flag clear */ +- OPL_STATUS_RESET(OPL,0x7f); +- } +- else +- { /* set IRQ mask ,timer enable*/ +- UINT8 st1 = v&1; +- UINT8 st2 = (v>>1)&1; +- /* IRQRST,T1MSK,t2MSK,EOSMSK,BRMSK,x,ST2,ST1 */ +- OPL_STATUS_RESET(OPL,v&0x78); +- OPL_STATUSMASK_SET(OPL,((~v)&0x78)|0x01); +- /* timer 2 */ +- if(OPL->st[1] != st2) +- { +- double interval = st2 ? (double)OPL->T[1]*OPL->TimerBase : 0.0; +- OPL->st[1] = st2; +- if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+1,interval); +- } +- /* timer 1 */ +- if(OPL->st[0] != st1) +- { +- double interval = st1 ? (double)OPL->T[0]*OPL->TimerBase : 0.0; +- OPL->st[0] = st1; +- if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+0,interval); +- } +- } +- return; +-#if BUILD_Y8950 +- case 0x06: /* Key Board OUT */ +- if(OPL->type&OPL_TYPE_KEYBOARD) +- { +- if(OPL->keyboardhandler_w) +- OPL->keyboardhandler_w(OPL->keyboard_param,v); +- else +- LOG(LOG_WAR,("OPL:write unmapped KEYBOARD port\n")); +- } +- return; +- case 0x07: /* DELTA-T controll : START,REC,MEMDATA,REPT,SPOFF,x,x,RST */ +- if(OPL->type&OPL_TYPE_ADPCM) +- YM_DELTAT_ADPCM_Write(OPL->deltat,r-0x07,v); +- return; +- case 0x08: /* MODE,DELTA-T : CSM,NOTESEL,x,x,smpl,da/ad,64k,rom */ +- OPL->mode = v; +- v&=0x1f; /* for DELTA-T unit */ +- case 0x09: /* START ADD */ +- case 0x0a: +- case 0x0b: /* STOP ADD */ +- case 0x0c: +- case 0x0d: /* PRESCALE */ +- case 0x0e: +- case 0x0f: /* ADPCM data */ +- case 0x10: /* DELTA-N */ +- case 0x11: /* DELTA-N */ +- case 0x12: /* EG-CTRL */ +- if(OPL->type&OPL_TYPE_ADPCM) +- YM_DELTAT_ADPCM_Write(OPL->deltat,r-0x07,v); +- return; +-#if 0 +- case 0x15: /* DAC data */ +- case 0x16: +- case 0x17: /* SHIFT */ +- return; +- case 0x18: /* I/O CTRL (Direction) */ +- if(OPL->type&OPL_TYPE_IO) +- OPL->portDirection = v&0x0f; +- return; +- case 0x19: /* I/O DATA */ +- if(OPL->type&OPL_TYPE_IO) +- { +- OPL->portLatch = v; +- if(OPL->porthandler_w) +- OPL->porthandler_w(OPL->port_param,v&OPL->portDirection); +- } +- return; +- case 0x1a: /* PCM data */ +- return; +-#endif +-#endif +- } +- break; +- case 0x20: /* am,vib,ksr,eg type,mul */ +- slot = slot_array[r&0x1f]; +- if(slot == -1) return; +- set_mul(OPL,slot,v); +- return; +- case 0x40: +- slot = slot_array[r&0x1f]; +- if(slot == -1) return; +- set_ksl_tl(OPL,slot,v); +- return; +- case 0x60: +- slot = slot_array[r&0x1f]; +- if(slot == -1) return; +- set_ar_dr(OPL,slot,v); +- return; +- case 0x80: +- slot = slot_array[r&0x1f]; +- if(slot == -1) return; +- set_sl_rr(OPL,slot,v); +- return; +- case 0xa0: +- switch(r) +- { +- case 0xbd: +- /* amsep,vibdep,r,bd,sd,tom,tc,hh */ +- { +- UINT8 rkey = OPL->rythm^v; +- OPL->ams_table = &AMS_TABLE[v&0x80 ? AMS_ENT : 0]; +- OPL->vib_table = &VIB_TABLE[v&0x40 ? VIB_ENT : 0]; +- OPL->rythm = v&0x3f; +- if(OPL->rythm&0x20) +- { +-#if 0 +- usrintf_showmessage("OPL Rythm mode select"); +-#endif +- /* BD key on/off */ +- if(rkey&0x10) +- { +- if(v&0x10) +- { +- OPL->P_CH[6].op1_out[0] = OPL->P_CH[6].op1_out[1] = 0; +- OPL_KEYON(&OPL->P_CH[6].SLOT[SLOT1]); +- OPL_KEYON(&OPL->P_CH[6].SLOT[SLOT2]); +- } +- else +- { +- OPL_KEYOFF(&OPL->P_CH[6].SLOT[SLOT1]); +- OPL_KEYOFF(&OPL->P_CH[6].SLOT[SLOT2]); +- } +- } +- /* SD key on/off */ +- if(rkey&0x08) +- { +- if(v&0x08) OPL_KEYON(&OPL->P_CH[7].SLOT[SLOT2]); +- else OPL_KEYOFF(&OPL->P_CH[7].SLOT[SLOT2]); +- }/* TAM key on/off */ +- if(rkey&0x04) +- { +- if(v&0x04) OPL_KEYON(&OPL->P_CH[8].SLOT[SLOT1]); +- else OPL_KEYOFF(&OPL->P_CH[8].SLOT[SLOT1]); +- } +- /* TOP-CY key on/off */ +- if(rkey&0x02) +- { +- if(v&0x02) OPL_KEYON(&OPL->P_CH[8].SLOT[SLOT2]); +- else OPL_KEYOFF(&OPL->P_CH[8].SLOT[SLOT2]); +- } +- /* HH key on/off */ +- if(rkey&0x01) +- { +- if(v&0x01) OPL_KEYON(&OPL->P_CH[7].SLOT[SLOT1]); +- else OPL_KEYOFF(&OPL->P_CH[7].SLOT[SLOT1]); +- } +- } +- } +- return; +- } +- /* keyon,block,fnum */ +- if( (r&0x0f) > 8) return; +- CH = &OPL->P_CH[r&0x0f]; +- if(!(r&0x10)) +- { /* a0-a8 */ +- block_fnum = (CH->block_fnum&0x1f00) | v; +- } +- else +- { /* b0-b8 */ +- int keyon = (v>>5)&1; +- block_fnum = ((v&0x1f)<<8) | (CH->block_fnum&0xff); +- if(CH->keyon != keyon) +- { +- if( (CH->keyon=keyon) ) +- { +- CH->op1_out[0] = CH->op1_out[1] = 0; +- OPL_KEYON(&CH->SLOT[SLOT1]); +- OPL_KEYON(&CH->SLOT[SLOT2]); +- } +- else +- { +- OPL_KEYOFF(&CH->SLOT[SLOT1]); +- OPL_KEYOFF(&CH->SLOT[SLOT2]); +- } +- } +- } +- /* update */ +- if(CH->block_fnum != block_fnum) +- { +- int blockRv = 7-(block_fnum>>10); +- int fnum = block_fnum&0x3ff; +- CH->block_fnum = block_fnum; +- +- CH->ksl_base = KSL_TABLE[block_fnum>>6]; +- CH->fc = OPL->FN_TABLE[fnum]>>blockRv; +- CH->kcode = CH->block_fnum>>9; +- if( (OPL->mode&0x40) && CH->block_fnum&0x100) CH->kcode |=1; +- CALC_FCSLOT(CH,&CH->SLOT[SLOT1]); +- CALC_FCSLOT(CH,&CH->SLOT[SLOT2]); +- } +- return; +- case 0xc0: +- /* FB,C */ +- if( (r&0x0f) > 8) return; +- CH = &OPL->P_CH[r&0x0f]; +- { +- int feedback = (v>>1)&7; +- CH->FB = feedback ? (8+1) - feedback : 0; +- CH->CON = v&1; +- set_algorythm(CH); +- } +- return; +- case 0xe0: /* wave type */ +- slot = slot_array[r&0x1f]; +- if(slot == -1) return; +- CH = &OPL->P_CH[slot/2]; +- if(OPL->wavesel) +- { +- /* LOG(LOG_INF,("OPL SLOT %d wave select %d\n",slot,v&3)); */ +- CH->SLOT[slot&1].wavetable = &SIN_TABLE[(v&0x03)*SIN_ENT]; +- } +- return; +- } +-} +- +-/* lock/unlock for common table */ +-static int OPL_LockTable() +-{ +- num_lock++; +- if(num_lock>1) return 0; +- /* first time */ +- cur_chip = NULL; +- /* allocate total level table (128kb space) */ +- if( !OPLOpenTable() ) +- { +- num_lock--; +- return -1; +- } +- return 0; +-} +- +-static void OPL_UnLockTable() +-{ +- if(num_lock) num_lock--; +- if(num_lock) return; +- /* last time */ +- cur_chip = NULL; +- OPLCloseTable(); +-} +- +-#if (BUILD_YM3812 || BUILD_YM3526) +-/*******************************************************************************/ +-/* YM3812 local section */ +-/*******************************************************************************/ +- +-/* ---------- update one of chip ----------- */ +-void YM3812UpdateOne(FM_OPL *OPL, INT16 *buffer, int length) +-{ +- int i; +- int data; +- OPLSAMPLE *buf = buffer; +- UINT32 amsCnt = OPL->amsCnt; +- UINT32 vibCnt = OPL->vibCnt; +- UINT8 rythm = OPL->rythm&0x20; +- OPL_CH *CH,*R_CH; +- +- if( (void *)OPL != cur_chip ){ +- cur_chip = (void *)OPL; +- /* channel pointers */ +- S_CH = OPL->P_CH; +- E_CH = &S_CH[9]; +- /* rythm slot */ +- SLOT7_1 = &S_CH[7].SLOT[SLOT1]; +- SLOT7_2 = &S_CH[7].SLOT[SLOT2]; +- SLOT8_1 = &S_CH[8].SLOT[SLOT1]; +- SLOT8_2 = &S_CH[8].SLOT[SLOT2]; +- /* LFO state */ +- amsIncr = OPL->amsIncr; +- vibIncr = OPL->vibIncr; +- ams_table = OPL->ams_table; +- vib_table = OPL->vib_table; +- } +- R_CH = rythm ? &S_CH[6] : E_CH; +- for( i=0; i < length ; i++ ) +- { +- /* channel A channel B channel C */ +- /* LFO */ +- ams = ams_table[(amsCnt+=amsIncr)>>AMS_SHIFT]; +- vib = vib_table[(vibCnt+=vibIncr)>>VIB_SHIFT]; +- outd[0] = 0; +- /* FM part */ +- for(CH=S_CH ; CH < R_CH ; CH++) +- OPL_CALC_CH(CH); +- /* Rythn part */ +- if(rythm) +- OPL_CALC_RH(S_CH); +- /* limit check */ +- data = Limit( outd[0] , OPL_MAXOUT, OPL_MINOUT ); +- /* store to sound buffer */ +- buf[i] = data >> OPL_OUTSB; +- } +- +- OPL->amsCnt = amsCnt; +- OPL->vibCnt = vibCnt; +-#ifdef OPL_OUTPUT_LOG +- if(opl_dbg_fp) +- { +- for(opl_dbg_chip=0;opl_dbg_chipamsCnt; +- UINT32 vibCnt = OPL->vibCnt; +- UINT8 rythm = OPL->rythm&0x20; +- OPL_CH *CH,*R_CH; +- YM_DELTAT *DELTAT = OPL->deltat; +- +- /* setup DELTA-T unit */ +- YM_DELTAT_DECODE_PRESET(DELTAT); +- +- if( (void *)OPL != cur_chip ){ +- cur_chip = (void *)OPL; +- /* channel pointers */ +- S_CH = OPL->P_CH; +- E_CH = &S_CH[9]; +- /* rythm slot */ +- SLOT7_1 = &S_CH[7].SLOT[SLOT1]; +- SLOT7_2 = &S_CH[7].SLOT[SLOT2]; +- SLOT8_1 = &S_CH[8].SLOT[SLOT1]; +- SLOT8_2 = &S_CH[8].SLOT[SLOT2]; +- /* LFO state */ +- amsIncr = OPL->amsIncr; +- vibIncr = OPL->vibIncr; +- ams_table = OPL->ams_table; +- vib_table = OPL->vib_table; +- } +- R_CH = rythm ? &S_CH[6] : E_CH; +- for( i=0; i < length ; i++ ) +- { +- /* channel A channel B channel C */ +- /* LFO */ +- ams = ams_table[(amsCnt+=amsIncr)>>AMS_SHIFT]; +- vib = vib_table[(vibCnt+=vibIncr)>>VIB_SHIFT]; +- outd[0] = 0; +- /* deltaT ADPCM */ +- if( DELTAT->portstate ) +- YM_DELTAT_ADPCM_CALC(DELTAT); +- /* FM part */ +- for(CH=S_CH ; CH < R_CH ; CH++) +- OPL_CALC_CH(CH); +- /* Rythn part */ +- if(rythm) +- OPL_CALC_RH(S_CH); +- /* limit check */ +- data = Limit( outd[0] , OPL_MAXOUT, OPL_MINOUT ); +- /* store to sound buffer */ +- buf[i] = data >> OPL_OUTSB; +- } +- OPL->amsCnt = amsCnt; +- OPL->vibCnt = vibCnt; +- /* deltaT START flag */ +- if( !DELTAT->portstate ) +- OPL->status &= 0xfe; +-} +-#endif +- +-/* ---------- reset one of chip ---------- */ +-void OPLResetChip(FM_OPL *OPL) +-{ +- int c,s; +- int i; +- +- /* reset chip */ +- OPL->mode = 0; /* normal mode */ +- OPL_STATUS_RESET(OPL,0x7f); +- /* reset with register write */ +- OPLWriteReg(OPL,0x01,0); /* wabesel disable */ +- OPLWriteReg(OPL,0x02,0); /* Timer1 */ +- OPLWriteReg(OPL,0x03,0); /* Timer2 */ +- OPLWriteReg(OPL,0x04,0); /* IRQ mask clear */ +- for(i = 0xff ; i >= 0x20 ; i-- ) OPLWriteReg(OPL,i,0); +- /* reset OPerator paramater */ +- for( c = 0 ; c < OPL->max_ch ; c++ ) +- { +- OPL_CH *CH = &OPL->P_CH[c]; +- /* OPL->P_CH[c].PAN = OPN_CENTER; */ +- for(s = 0 ; s < 2 ; s++ ) +- { +- /* wave table */ +- CH->SLOT[s].wavetable = &SIN_TABLE[0]; +- /* CH->SLOT[s].evm = ENV_MOD_RR; */ +- CH->SLOT[s].evc = EG_OFF; +- CH->SLOT[s].eve = EG_OFF+1; +- CH->SLOT[s].evs = 0; +- } +- } +-#if BUILD_Y8950 +- if(OPL->type&OPL_TYPE_ADPCM) +- { +- YM_DELTAT *DELTAT = OPL->deltat; +- +- DELTAT->freqbase = OPL->freqbase; +- DELTAT->output_pointer = outd; +- DELTAT->portshift = 5; +- DELTAT->output_range = DELTAT_MIXING_LEVEL<P_CH = (OPL_CH *)ptr; ptr+=sizeof(OPL_CH)*max_ch; +-#if BUILD_Y8950 +- if(type&OPL_TYPE_ADPCM) OPL->deltat = (YM_DELTAT *)ptr; ptr+=sizeof(YM_DELTAT); +-#endif +- /* set channel state pointer */ +- OPL->type = type; +- OPL->clock = clock; +- OPL->rate = rate; +- OPL->max_ch = max_ch; +- /* init grobal tables */ +- OPL_initalize(OPL); +- /* reset chip */ +- OPLResetChip(OPL); +-#ifdef OPL_OUTPUT_LOG +- if(!opl_dbg_fp) +- { +- opl_dbg_fp = fopen("opllog.opl","wb"); +- opl_dbg_maxchip = 0; +- } +- if(opl_dbg_fp) +- { +- opl_dbg_opl[opl_dbg_maxchip] = OPL; +- fprintf(opl_dbg_fp,"%c%c%c%c%c%c",0x00+opl_dbg_maxchip, +- type, +- clock&0xff, +- (clock/0x100)&0xff, +- (clock/0x10000)&0xff, +- (clock/0x1000000)&0xff); +- opl_dbg_maxchip++; +- } +-#endif +- return OPL; +-} +- +-/* ---------- Destroy one of vietual YM3812 ---------- */ +-void OPLDestroy(FM_OPL *OPL) +-{ +-#ifdef OPL_OUTPUT_LOG +- if(opl_dbg_fp) +- { +- fclose(opl_dbg_fp); +- opl_dbg_fp = NULL; +- } +-#endif +- OPL_UnLockTable(); +- free(OPL); +-} +- +-/* ---------- Option handlers ---------- */ +- +-void OPLSetTimerHandler(FM_OPL *OPL,OPL_TIMERHANDLER TimerHandler,int channelOffset) +-{ +- OPL->TimerHandler = TimerHandler; +- OPL->TimerParam = channelOffset; +-} +-void OPLSetIRQHandler(FM_OPL *OPL,OPL_IRQHANDLER IRQHandler,int param) +-{ +- OPL->IRQHandler = IRQHandler; +- OPL->IRQParam = param; +-} +-void OPLSetUpdateHandler(FM_OPL *OPL,OPL_UPDATEHANDLER UpdateHandler,int param) +-{ +- OPL->UpdateHandler = UpdateHandler; +- OPL->UpdateParam = param; +-} +-#if BUILD_Y8950 +-void OPLSetPortHandler(FM_OPL *OPL,OPL_PORTHANDLER_W PortHandler_w,OPL_PORTHANDLER_R PortHandler_r,int param) +-{ +- OPL->porthandler_w = PortHandler_w; +- OPL->porthandler_r = PortHandler_r; +- OPL->port_param = param; +-} +- +-void OPLSetKeyboardHandler(FM_OPL *OPL,OPL_PORTHANDLER_W KeyboardHandler_w,OPL_PORTHANDLER_R KeyboardHandler_r,int param) +-{ +- OPL->keyboardhandler_w = KeyboardHandler_w; +- OPL->keyboardhandler_r = KeyboardHandler_r; +- OPL->keyboard_param = param; +-} +-#endif +-/* ---------- YM3812 I/O interface ---------- */ +-int OPLWrite(FM_OPL *OPL,int a,int v) +-{ +- if( !(a&1) ) +- { /* address port */ +- OPL->address = v & 0xff; +- } +- else +- { /* data port */ +- if(OPL->UpdateHandler) OPL->UpdateHandler(OPL->UpdateParam,0); +-#ifdef OPL_OUTPUT_LOG +- if(opl_dbg_fp) +- { +- for(opl_dbg_chip=0;opl_dbg_chipaddress,v); +- } +-#endif +- OPLWriteReg(OPL,OPL->address,v); +- } +- return OPL->status>>7; +-} +- +-unsigned char OPLRead(FM_OPL *OPL,int a) +-{ +- if( !(a&1) ) +- { /* status port */ +- return OPL->status & (OPL->statusmask|0x80); +- } +- /* data port */ +- switch(OPL->address) +- { +- case 0x05: /* KeyBoard IN */ +- if(OPL->type&OPL_TYPE_KEYBOARD) +- { +- if(OPL->keyboardhandler_r) +- return OPL->keyboardhandler_r(OPL->keyboard_param); +- else +- LOG(LOG_WAR,("OPL:read unmapped KEYBOARD port\n")); +- } +- return 0; +-#if 0 +- case 0x0f: /* ADPCM-DATA */ +- return 0; +-#endif +- case 0x19: /* I/O DATA */ +- if(OPL->type&OPL_TYPE_IO) +- { +- if(OPL->porthandler_r) +- return OPL->porthandler_r(OPL->port_param); +- else +- LOG(LOG_WAR,("OPL:read unmapped I/O port\n")); +- } +- return 0; +- case 0x1a: /* PCM-DATA */ +- return 0; +- } +- return 0; +-} +- +-int OPLTimerOver(FM_OPL *OPL,int c) +-{ +- if( c ) +- { /* Timer B */ +- OPL_STATUS_SET(OPL,0x20); +- } +- else +- { /* Timer A */ +- OPL_STATUS_SET(OPL,0x40); +- /* CSM mode key,TL controll */ +- if( OPL->mode & 0x80 ) +- { /* CSM mode total level latch and auto key on */ +- int ch; +- if(OPL->UpdateHandler) OPL->UpdateHandler(OPL->UpdateParam,0); +- for(ch=0;ch<9;ch++) +- CSMKeyControll( &OPL->P_CH[ch] ); +- } +- } +- /* reload timer */ +- if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+c,(double)OPL->T[c]*OPL->TimerBase); +- return OPL->status>>7; +-} +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/fmopl.h audacious-plugins-3.9/src/adplug/core/fmopl.h +--- audacious-plugins-3.9-orig/src/adplug/core/fmopl.h 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/fmopl.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,174 +0,0 @@ +-#ifndef __FMOPL_H_ +-#define __FMOPL_H_ +- +-/* --- select emulation chips --- */ +-#define BUILD_YM3812 (HAS_YM3812) +-//#define BUILD_YM3526 (HAS_YM3526) +-//#define BUILD_Y8950 (HAS_Y8950) +- +-/* --- system optimize --- */ +-/* select bit size of output : 8 or 16 */ +-#define OPL_OUTPUT_BIT 16 +- +-/* compiler dependence */ +-#ifndef OSD_CPU_H +-#define OSD_CPU_H +-typedef unsigned char UINT8; /* unsigned 8bit */ +-typedef unsigned short UINT16; /* unsigned 16bit */ +-typedef unsigned int UINT32; /* unsigned 32bit */ +-typedef signed char INT8; /* signed 8bit */ +-typedef signed short INT16; /* signed 16bit */ +-typedef signed int INT32; /* signed 32bit */ +-#endif +- +-#if (OPL_OUTPUT_BIT==16) +-typedef INT16 OPLSAMPLE; +-#endif +-#if (OPL_OUTPUT_BIT==8) +-typedef unsigned char OPLSAMPLE; +-#endif +- +- +-#if BUILD_Y8950 +-#include "ymdeltat.h" +-#endif +- +-typedef void (*OPL_TIMERHANDLER)(int channel,double interval_Sec); +-typedef void (*OPL_IRQHANDLER)(int param,int irq); +-typedef void (*OPL_UPDATEHANDLER)(int param,int min_interval_us); +-typedef void (*OPL_PORTHANDLER_W)(int param,unsigned char data); +-typedef unsigned char (*OPL_PORTHANDLER_R)(int param); +- +-/* !!!!! here is private section , do not access there member direct !!!!! */ +- +-#define OPL_TYPE_WAVESEL 0x01 /* waveform select */ +-#define OPL_TYPE_ADPCM 0x02 /* DELTA-T ADPCM unit */ +-#define OPL_TYPE_KEYBOARD 0x04 /* keyboard interface */ +-#define OPL_TYPE_IO 0x08 /* I/O port */ +- +-/* Saving is necessary for member of the 'R' mark for suspend/resume */ +-/* ---------- OPL one of slot ---------- */ +-typedef struct fm_opl_slot { +- INT32 TL; /* total level :TL << 8 */ +- INT32 TLL; /* adjusted now TL */ +- UINT8 KSR; /* key scale rate :(shift down bit) */ +- INT32 *AR; /* attack rate :&AR_TABLE[AR<<2] */ +- INT32 *DR; /* decay rate :&DR_TALBE[DR<<2] */ +- INT32 SL; /* sustin level :SL_TALBE[SL] */ +- INT32 *RR; /* release rate :&DR_TABLE[RR<<2] */ +- UINT8 ksl; /* keyscale level :(shift down bits) */ +- UINT8 ksr; /* key scale rate :kcode>>KSR */ +- UINT32 mul; /* multiple :ML_TABLE[ML] */ +- UINT32 Cnt; /* frequency count : */ +- UINT32 Incr; /* frequency step : */ +- /* envelope generator state */ +- UINT8 eg_typ; /* envelope type flag */ +- UINT8 evm; /* envelope phase */ +- INT32 evc; /* envelope counter */ +- INT32 eve; /* envelope counter end point */ +- INT32 evs; /* envelope counter step */ +- INT32 evsa; /* envelope step for AR :AR[ksr] */ +- INT32 evsd; /* envelope step for DR :DR[ksr] */ +- INT32 evsr; /* envelope step for RR :RR[ksr] */ +- /* LFO */ +- UINT8 ams; /* ams flag */ +- UINT8 vib; /* vibrate flag */ +- /* wave selector */ +- INT32 **wavetable; +-}OPL_SLOT; +- +-/* ---------- OPL one of channel ---------- */ +-typedef struct fm_opl_channel { +- OPL_SLOT SLOT[2]; +- UINT8 CON; /* connection type */ +- UINT8 FB; /* feed back :(shift down bit) */ +- INT32 *connect1; /* slot1 output pointer */ +- INT32 *connect2; /* slot2 output pointer */ +- INT32 op1_out[2]; /* slot1 output for selfeedback */ +- /* phase generator state */ +- UINT32 block_fnum; /* block+fnum : */ +- UINT8 kcode; /* key code : KeyScaleCode */ +- UINT32 fc; /* Freq. Increment base */ +- UINT32 ksl_base; /* KeyScaleLevel Base step */ +- UINT8 keyon; /* key on/off flag */ +-} OPL_CH; +- +-/* OPL state */ +-typedef struct fm_opl_f { +- UINT8 type; /* chip type */ +- int clock; /* master clock (Hz) */ +- int rate; /* sampling rate (Hz) */ +- double freqbase; /* frequency base */ +- double TimerBase; /* Timer base time (==sampling time) */ +- UINT8 address; /* address register */ +- UINT8 status; /* status flag */ +- UINT8 statusmask; /* status mask */ +- UINT32 mode; /* Reg.08 : CSM , notesel,etc. */ +- /* Timer */ +- int T[2]; /* timer counter */ +- UINT8 st[2]; /* timer enable */ +- /* FM channel slots */ +- OPL_CH *P_CH; /* pointer of CH */ +- int max_ch; /* maximum channel */ +- /* Rythm sention */ +- UINT8 rythm; /* Rythm mode , key flag */ +-#if BUILD_Y8950 +- /* Delta-T ADPCM unit (Y8950) */ +- YM_DELTAT *deltat; /* DELTA-T ADPCM */ +-#endif +- /* Keyboard / I/O interface unit (Y8950) */ +- UINT8 portDirection; +- UINT8 portLatch; +- OPL_PORTHANDLER_R porthandler_r; +- OPL_PORTHANDLER_W porthandler_w; +- int port_param; +- OPL_PORTHANDLER_R keyboardhandler_r; +- OPL_PORTHANDLER_W keyboardhandler_w; +- int keyboard_param; +- /* time tables */ +- INT32 AR_TABLE[75]; /* atttack rate tables */ +- INT32 DR_TABLE[75]; /* decay rate tables */ +- UINT32 FN_TABLE[1024]; /* fnumber -> increment counter */ +- /* LFO */ +- INT32 *ams_table; +- INT32 *vib_table; +- INT32 amsCnt; +- INT32 amsIncr; +- INT32 vibCnt; +- INT32 vibIncr; +- /* wave selector enable flag */ +- UINT8 wavesel; +- /* external event callback handler */ +- OPL_TIMERHANDLER TimerHandler; /* TIMER handler */ +- int TimerParam; /* TIMER parameter */ +- OPL_IRQHANDLER IRQHandler; /* IRQ handler */ +- int IRQParam; /* IRQ parameter */ +- OPL_UPDATEHANDLER UpdateHandler; /* stream update handler */ +- int UpdateParam; /* stream update parameter */ +-} FM_OPL; +- +-/* ---------- Generic interface section ---------- */ +-#define OPL_TYPE_YM3526 (0) +-#define OPL_TYPE_YM3812 (OPL_TYPE_WAVESEL) +-#define OPL_TYPE_Y8950 (OPL_TYPE_ADPCM|OPL_TYPE_KEYBOARD|OPL_TYPE_IO) +- +-FM_OPL *OPLCreate(int type, int clock, int rate); +-void OPLDestroy(FM_OPL *OPL); +-void OPLSetTimerHandler(FM_OPL *OPL,OPL_TIMERHANDLER TimerHandler,int channelOffset); +-void OPLSetIRQHandler(FM_OPL *OPL,OPL_IRQHANDLER IRQHandler,int param); +-void OPLSetUpdateHandler(FM_OPL *OPL,OPL_UPDATEHANDLER UpdateHandler,int param); +-/* Y8950 port handlers */ +-void OPLSetPortHandler(FM_OPL *OPL,OPL_PORTHANDLER_W PortHandler_w,OPL_PORTHANDLER_R PortHandler_r,int param); +-void OPLSetKeyboardHandler(FM_OPL *OPL,OPL_PORTHANDLER_W KeyboardHandler_w,OPL_PORTHANDLER_R KeyboardHandler_r,int param); +- +-void OPLResetChip(FM_OPL *OPL); +-int OPLWrite(FM_OPL *OPL,int a,int v); +-unsigned char OPLRead(FM_OPL *OPL,int a); +-int OPLTimerOver(FM_OPL *OPL,int c); +- +-/* YM3626/YM3812 local section */ +-void YM3812UpdateOne(FM_OPL *OPL, INT16 *buffer, int length); +- +-void Y8950UpdateOne(FM_OPL *OPL, INT16 *buffer, int length); +- +-#endif +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/fprovide.cc audacious-plugins-3.9/src/adplug/core/fprovide.cc +--- audacious-plugins-3.9-orig/src/adplug/core/fprovide.cc 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/fprovide.cc 1970-01-01 01:00:00.000000000 +0100 +@@ -1,63 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2002 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * fprovide.cpp - File provider class framework, by Simon Peter +- */ +- +-#include +-#include "binio.h" +-#include "binfile.h" +- +-#include "fprovide.h" +-#include "binio_virtual.h" +- +-/***** CFileProvider *****/ +- +-bool CFileProvider::extension(const std::string &filename, +- const std::string &extension) +-{ +- const char *fname = filename.c_str(), *ext = extension.c_str(); +- +- if(strlen(fname) < strlen(ext) || +- strcasecmp(fname + strlen(fname) - strlen(ext), ext)) +- return false; +- else +- return true; +-} +- +-unsigned long CFileProvider::filesize(binistream *f) +-{ +- return static_cast(f)->size(); +-} +- +-binistream *CFileProvider::open(std::string filename) const +-{ +- binistream *f; +- +- if (!strcmp(filename.c_str(), m_file.filename()) && !m_file.fseek(0, VFS_SEEK_SET)) +- f = new vfsistream(&m_file); +- else +- f = new vfsistream(filename); +- +- if(f->error()) { delete f; return 0; } +- +- // Open all files as little endian with IEEE floats by default +- f->setFlag(binio::BigEndian, false); f->setFlag(binio::FloatIEEE); +- +- return f; +-} +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/fprovide.h audacious-plugins-3.9/src/adplug/core/fprovide.h +--- audacious-plugins-3.9-orig/src/adplug/core/fprovide.h 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/fprovide.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,49 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2006 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * fprovide.h - File provider class framework, by Simon Peter +- */ +- +-#ifndef H_ADPLUG_FILEPROVIDER +-#define H_ADPLUG_FILEPROVIDER +- +-#include +-#include "binio.h" +- +-class VFSFile; +- +-class CFileProvider +-{ +-public: +- CFileProvider(VFSFile &file) : +- m_file(file) {} +- +- binistream *open(std::string filename) const; +- +- static void close(binistream *f) +- { delete f; } +- +- static bool extension(const std::string &filename, +- const std::string &extension); +- static unsigned long filesize(binistream *f); +- +-private: +- VFSFile &m_file; +-}; +- +-#endif +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/hsc.cc audacious-plugins-3.9/src/adplug/core/hsc.cc +--- audacious-plugins-3.9-orig/src/adplug/core/hsc.cc 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/hsc.cc 1970-01-01 01:00:00.000000000 +0100 +@@ -1,317 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2004 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * hsc.cpp - HSC Player by Simon Peter +- */ +- +-#include +- +-#include "hsc.h" +-#include "debug.h" +- +-/*** public methods **************************************/ +- +-CPlayer *ChscPlayer::factory(Copl *newopl) +-{ +- return new ChscPlayer(newopl); +-} +- +-bool ChscPlayer::load(const std::string &filename, const CFileProvider &fp) +-{ +- binistream *f = fp.open(filename); +- int i; +- +- // file validation section +- if(!f || !fp.extension(filename, ".hsc") || fp.filesize(f) > 59187) { +- AdPlug_LogWrite("ChscPlayer::load(\"%s\"): Not a HSC file!\n", filename.c_str()); +- fp.close(f); +- return false; +- } +- +- // load section +- for(i=0;i<128*12;i++) // load instruments +- *((unsigned char *)instr + i) = f->readInt(1); +- for (i=0;i<128;i++) { // correct instruments +- instr[i][2] ^= (instr[i][2] & 0x40) << 1; +- instr[i][3] ^= (instr[i][3] & 0x40) << 1; +- instr[i][11] >>= 4; // slide +- } +- for(i=0;i<51;i++) song[i] = f->readInt(1); // load tracklist +- for(i=0;i<50*64*9;i++) // load patterns +- *((char *)patterns + i) = f->readInt(1); +- +- fp.close(f); +- rewind(0); // rewind module +- return true; +-} +- +-bool ChscPlayer::update() +-{ +- // general vars +- unsigned char chan,pattnr,note,effect,eff_op,inst,vol,Okt,db; +- unsigned short Fnr; +- unsigned long pattoff; +- +- del--; // player speed handling +- if(del) +- return !songend; // nothing done +- +- if(fadein) // fade-in handling +- fadein--; +- +- pattnr = song[songpos]; +- if(pattnr == 0xff) { // arrangement handling +- songend = 1; // set end-flag +- songpos = 0; +- pattnr = song[songpos]; +- } else +- if ((pattnr & 128) && (pattnr <= 0xb1)) { // goto pattern "nr" +- songpos = song[songpos] & 127; +- pattpos = 0; +- pattnr = song[songpos]; +- songend = 1; +- } +- +- pattoff = pattpos*9; +- for (chan=0;chan<9;chan++) { // handle all channels +- note = patterns[pattnr][pattoff].note; +- effect = patterns[pattnr][pattoff].effect; +- pattoff++; +- +- if(note & 128) { // set instrument +- setinstr(chan,effect); +- continue; +- } +- eff_op = effect & 0x0f; +- inst = channel[chan].inst; +- if(note) +- channel[chan].slide = 0; +- +- switch (effect & 0xf0) { // effect handling +- case 0: // global effect +- /* The following fx are unimplemented on purpose: +- * 02 - Slide Mainvolume up +- * 03 - Slide Mainvolume down (here: fade in) +- * 04 - Set Mainvolume to 0 +- * +- * This is because i've never seen any HSC modules using the fx this way. +- * All modules use the fx the way, i've implemented it. +- */ +- switch(eff_op) { +- case 1: pattbreak++; break; // jump to next pattern +- case 3: fadein = 31; break; // fade in (divided by 2) +- case 5: mode6 = 1; break; // 6 voice mode on +- case 6: mode6 = 0; break; // 6 voice mode off +- } +- break; +- case 0x20: +- case 0x10: // manual slides +- if (effect & 0x10) { +- channel[chan].freq += eff_op; +- channel[chan].slide += eff_op; +- } else { +- channel[chan].freq -= eff_op; +- channel[chan].slide -= eff_op; +- } +- if(!note) +- setfreq(chan,channel[chan].freq); +- break; +- case 0x50: // set percussion instrument (unimplemented) +- break; +- case 0x60: // set feedback +- opl->write(0xc0 + chan, (instr[channel[chan].inst][8] & 1) + (eff_op << 1)); +- break; +- case 0xa0: // set carrier volume +- vol = eff_op << 2; +- opl->write(0x43 + op_table[chan], vol | (instr[channel[chan].inst][2] & ~63)); +- break; +- case 0xb0: // set modulator volume +- vol = eff_op << 2; +- if (instr[inst][8] & 1) +- opl->write(0x40 + op_table[chan], vol | (instr[channel[chan].inst][3] & ~63)); +- else +- opl->write(0x40 + op_table[chan],vol | (instr[inst][3] & ~63)); +- break; +- case 0xc0: // set instrument volume +- db = eff_op << 2; +- opl->write(0x43 + op_table[chan], db | (instr[channel[chan].inst][2] & ~63)); +- if (instr[inst][8] & 1) +- opl->write(0x40 + op_table[chan], db | (instr[channel[chan].inst][3] & ~63)); +- break; +- case 0xd0: pattbreak++; songpos = eff_op; songend = 1; break; // position jump +- case 0xf0: // set speed +- speed = eff_op; +- del = ++speed; +- break; +- } +- +- if(fadein) // fade-in volume setting +- setvolume(chan,fadein*2,fadein*2); +- +- if(!note) // note handling +- continue; +- note--; +- +- if ((note == 0x7f-1) || ((note/12) & ~7)) { // pause (7fh) +- adl_freq[chan] &= ~32; +- opl->write(0xb0 + chan,adl_freq[chan]); +- continue; +- } +- +- // play the note +- if(mtkmode) // imitate MPU-401 Trakker bug +- note--; +- Okt = ((note/12) & 7) << 2; +- Fnr = note_table[(note % 12)] + instr[inst][11] + channel[chan].slide; +- channel[chan].freq = Fnr; +- if(!mode6 || chan < 6) +- adl_freq[chan] = Okt | 32; +- else +- adl_freq[chan] = Okt; // never set key for drums +- opl->write(0xb0 + chan, 0); +- setfreq(chan,Fnr); +- if(mode6) { +- switch(chan) { // play drums +- case 6: opl->write(0xbd,bd & ~16); bd |= 48; break; // bass drum +- case 7: opl->write(0xbd,bd & ~1); bd |= 33; break; // hihat +- case 8: opl->write(0xbd,bd & ~2); bd |= 34; break; // cymbal +- } +- opl->write(0xbd,bd); +- } +- } +- +- del = speed; // player speed-timing +- if(pattbreak) { // do post-effect handling +- pattpos=0; // pattern break! +- pattbreak=0; +- songpos++; +- songpos %= 50; +- if(!songpos) +- songend = 1; +- } else { +- pattpos++; +- pattpos &= 63; // advance in pattern data +- if (!pattpos) { +- songpos++; +- songpos %= 50; +- if(!songpos) +- songend = 1; +- } +- } +- return !songend; // still playing +-} +- +-void ChscPlayer::rewind(int subsong) +-{ +- int i; // counter +- +- // rewind HSC player +- pattpos = 0; songpos = 0; pattbreak = 0; speed = 2; +- del = 1; songend = 0; mode6 = 0; bd = 0; fadein = 0; +- +- opl->init(); // reset OPL chip +- opl->write(1,32); opl->write(8,128); opl->write(0xbd,0); +- +- for(i=0;i<9;i++) +- setinstr((char) i,(char) i); // init channels +-} +- +-unsigned int ChscPlayer::getpatterns() +-{ +- unsigned char poscnt,pattcnt=0; +- +- // count patterns +- for(poscnt=0;poscnt<51 && song[poscnt] != 0xff;poscnt++) +- if(song[poscnt] > pattcnt) +- pattcnt = song[poscnt]; +- +- return (pattcnt+1); +-} +- +-unsigned int ChscPlayer::getorders() +-{ +- unsigned char poscnt; +- +- // count positions +- for(poscnt=0;poscnt<51;poscnt++) +- if(song[poscnt] == 0xff) +- break; +- +- return poscnt; +-} +- +-unsigned int ChscPlayer::getinstruments() +-{ +- unsigned char instcnt,instnum=0,i; +- bool isinst; +- +- // count instruments +- for(instcnt=0;instcnt<128;instcnt++) { +- isinst = false; +- for(i=0;i<12;i++) +- if(instr[instcnt][i]) +- isinst = true; +- if(isinst) +- instnum++; +- } +- +- return instnum; +-} +- +-/*** private methods *************************************/ +- +-void ChscPlayer::setfreq(unsigned char chan, unsigned short freq) +-{ +- adl_freq[chan] = (adl_freq[chan] & ~3) | (freq >> 8); +- +- opl->write(0xa0 + chan, freq & 0xff); +- opl->write(0xb0 + chan, adl_freq[chan]); +-} +- +-void ChscPlayer::setvolume(unsigned char chan, int volc, int volm) +-{ +- unsigned char *ins = instr[channel[chan].inst]; +- char op = op_table[chan]; +- +- opl->write(0x43 + op,volc | (ins[2] & ~63)); +- if (ins[8] & 1) // carrier +- opl->write(0x40 + op,volm | (ins[3] & ~63)); +- else +- opl->write(0x40 + op, ins[3]); // modulator +-} +- +-void ChscPlayer::setinstr(unsigned char chan, unsigned char insnr) +-{ +- unsigned char *ins = instr[insnr]; +- char op = op_table[chan]; +- +- channel[chan].inst = insnr; // set internal instrument +- opl->write(0xb0 + chan,0); // stop old note +- +- // set instrument +- opl->write(0xc0 + chan, ins[8]); +- opl->write(0x23 + op, ins[0]); // carrier +- opl->write(0x20 + op, ins[1]); // modulator +- opl->write(0x63 + op, ins[4]); // bits 0..3 = decay; 4..7 = attack +- opl->write(0x60 + op, ins[5]); +- opl->write(0x83 + op, ins[6]); // 0..3 = release; 4..7 = sustain +- opl->write(0x80 + op, ins[7]); +- opl->write(0xe3 + op, ins[9]); // bits 0..1 = Wellenform +- opl->write(0xe0 + op, ins[10]); +- setvolume(chan, ins[2] & 63, ins[3] & 63); +-} +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/hsc.h audacious-plugins-3.9/src/adplug/core/hsc.h +--- audacious-plugins-3.9-orig/src/adplug/core/hsc.h 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/hsc.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,75 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2007 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * hsc.h - HSC Player by Simon Peter +- */ +- +-#ifndef H_ADPLUG_HSCPLAYER +-#define H_ADPLUG_HSCPLAYER +- +-#include "player.h" +- +-class ChscPlayer: public CPlayer +-{ +- public: +- static CPlayer *factory(Copl *newopl); +- +- ChscPlayer(Copl *newopl): CPlayer(newopl), mtkmode(0) {} +- +- bool load(const std::string &filename, const CFileProvider &fp); +- bool update(); +- void rewind(int subsong); +- float getrefresh() { return 18.2f; }; // refresh rate is fixed at 18.2Hz +- +- std::string gettype() { return std::string("HSC Adlib Composer / HSC-Tracker"); } +- unsigned int getpatterns(); +- unsigned int getpattern() { return song[songpos]; } +- unsigned int getorders(); +- unsigned int getorder() { return songpos; } +- unsigned int getrow() { return pattpos; } +- unsigned int getspeed() { return speed; } +- unsigned int getinstruments(); +- +- protected: +- struct hscnote { +- unsigned char note, effect; +- }; // note type in HSC pattern +- +- struct hscchan { +- unsigned char inst; // current instrument +- signed char slide; // used for manual slide-effects +- unsigned short freq; // actual replaying frequency +- }; // HSC channel data +- +- hscchan channel[9]; // player channel-info +- unsigned char instr[128][12]; // instrument data +- unsigned char song[0x80]; // song-arrangement (MPU-401 Trakker enhanced) +- hscnote patterns[50][64*9]; // pattern data +- unsigned char pattpos,songpos, // various bytes & flags +- pattbreak,songend,mode6,bd,fadein; +- unsigned int speed,del; +- unsigned char adl_freq[9]; // adlib frequency registers +- int mtkmode; // flag: MPU-401 Trakker mode on/off +- +- private: +- void setfreq(unsigned char chan, unsigned short freq); +- void setvolume(unsigned char chan, int volc, int volm); +- void setinstr(unsigned char chan, unsigned char insnr); +-}; +- +-#endif +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/hsp.cc audacious-plugins-3.9/src/adplug/core/hsp.cc +--- audacious-plugins-3.9-orig/src/adplug/core/hsp.cc 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/hsp.cc 1970-01-01 01:00:00.000000000 +0100 +@@ -1,75 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2004 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * hsp.cpp - HSP Loader by Simon Peter +- */ +- +-#include +- +-#include "hsp.h" +- +-CPlayer *ChspLoader::factory(Copl *newopl) +-{ +- return new ChspLoader(newopl); +-} +- +-bool ChspLoader::load(const std::string &filename, const CFileProvider &fp) +-{ +- binistream *f = fp.open(filename); if(!f) return false; +- unsigned long i, j, orgsize, filesize; +- unsigned char *cmp, *org; +- +- // file validation section +- if(!fp.extension(filename, ".hsp")) { fp.close(f); return false; } +- +- filesize = fp.filesize(f); +- orgsize = f->readInt(2); +- if(orgsize > 59187) { fp.close(f); return false; } +- +- // load section +- cmp = new unsigned char[filesize]; +- for(i = 0; i < filesize; i++) cmp[i] = f->readInt(1); +- fp.close(f); +- +- org = new unsigned char[orgsize]; +- for(i = 0, j = 0; i < filesize; j += cmp[i], i += 2) { // RLE decompress +- if(j >= orgsize) break; // memory boundary check +- memset(org + j, cmp[i + 1], j + cmp[i] < orgsize ? cmp[i] : orgsize - j - 1); +- } +- if (j < orgsize) { +- orgsize = j; +- } +- delete [] cmp; +- +- if (orgsize < 128 * 12 + 51) { // check decompressed size +- delete [] org; +- return false; +- } +- memcpy(instr, org, 128 * 12); // instruments +- for(i = 0; i < 128; i++) { // correct instruments +- instr[i][2] ^= (instr[i][2] & 0x40) << 1; +- instr[i][3] ^= (instr[i][3] & 0x40) << 1; +- instr[i][11] >>= 4; // slide +- } +- memcpy(song, org + 128 * 12, 51); // tracklist +- memcpy(patterns, org + 128 * 12 + 51, orgsize - 128 * 12 - 51); // patterns +- delete [] org; +- +- rewind(0); +- return true; +-} +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/hsp.h audacious-plugins-3.9/src/adplug/core/hsp.h +--- audacious-plugins-3.9-orig/src/adplug/core/hsp.h 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/hsp.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,39 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2004 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * hsp.h: HSC Packed Loader by Simon Peter +- */ +- +-#ifndef H_ADPLUG_HSPLOADER +-#define H_ADPLUG_HSPLOADER +- +-#include "hsc.h" +- +-class ChspLoader: public ChscPlayer +-{ +-public: +- static CPlayer *factory(Copl *newopl); +- +- ChspLoader(Copl *newopl) +- : ChscPlayer(newopl) +- {}; +- +- bool load(const std::string &filename, const CFileProvider &fp); +-}; +- +-#endif +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/hybrid.cc audacious-plugins-3.9/src/adplug/core/hybrid.cc +--- audacious-plugins-3.9-orig/src/adplug/core/hybrid.cc 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/hybrid.cc 1970-01-01 01:00:00.000000000 +0100 +@@ -1,248 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2003 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * [xad] HYBRID player, by Riven the Mage +- */ +- +-/* +- - discovery - +- +- file(s) : HYBRID.EXE +- type : Hybrid cracktro for Apache Longbow CD-RIP +- tune : from 'Mig-29 Super Fulcrum' game by Domark +- player : from 'Mig-29 Super Fulcrum' game by Domark +-*/ +- +-#include "hybrid.h" +-#include "debug.h" +- +-const unsigned char CxadhybridPlayer::hyb_adlib_registers[99] = +-{ +- 0xE0, 0x60, 0x80, 0x20, 0x40, 0xE3, 0x63, 0x83, 0x23, 0x43, 0xC0, +- 0xE1, 0x61, 0x81, 0x21, 0x41, 0xE4, 0x64, 0x84, 0x24, 0x44, 0xC1, +- 0xE2, 0x62, 0x82, 0x22, 0x42, 0xE5, 0x65, 0x85, 0x25, 0x45, 0xC2, +- 0xE8, 0x68, 0x88, 0x28, 0x48, 0xEB, 0x6B, 0x8B, 0x2B, 0x4B, 0xC3, +- 0xE9, 0x69, 0x89, 0x29, 0x49, 0xEC, 0x6C, 0x8C, 0x2C, 0x4C, 0xC4, +- 0xEA, 0x6A, 0x8A, 0x2A, 0x4A, 0xED, 0x6D, 0x8D, 0x2D, 0x4D, 0xC5, +- 0xF0, 0x70, 0x90, 0x30, 0x50, 0xF3, 0x73, 0x93, 0x33, 0x53, 0xC6, +- 0xF1, 0x71, 0x91, 0x31, 0x51, 0xF4, 0x74, 0x94, 0x34, 0x54, 0xC7, +- 0xF2, 0x72, 0x92, 0x32, 0x52, 0xF5, 0x75, 0x95, 0x35, 0x55, 0xC8 +-}; +- +-const unsigned short CxadhybridPlayer::hyb_notes[98] = +-{ +- 0x0000, 0x0000, +- 0x016B, 0x0181, 0x0198, 0x01B0, 0x01CA, 0x01E5, 0x0202, 0x0220, 0x0241, 0x0263, 0x0287, 0x02AE, +- 0x056B, 0x0581, 0x0598, 0x05B0, 0x05CA, 0x05E5, 0x0602, 0x0620, 0x0641, 0x0663, 0x0687, 0x06AE, +- 0x096B, 0x0981, 0x0998, 0x09B0, 0x09CA, 0x09E5, 0x0A02, 0x0A20, 0x0A41, 0x0A63, 0x0A87, 0x0AAE, +- 0x0D6B, 0x0D81, 0x0D98, 0x0DB0, 0x0DCA, 0x0DE5, 0x0E02, 0x0E20, 0x0E41, 0x0E63, 0x0E87, 0x0EAE, +- 0x116B, 0x1181, 0x1198, 0x11B0, 0x11CA, 0x11E5, 0x1202, 0x1220, 0x1241, 0x1263, 0x1287, 0x12AE, +- 0x156B, 0x1581, 0x1598, 0x15B0, 0x15CA, 0x15E5, 0x1602, 0x1620, 0x1641, 0x1663, 0x1687, 0x16AE, +- 0x196B, 0x1981, 0x1998, 0x19B0, 0x19CA, 0x19E5, 0x1A02, 0x1A20, 0x1A41, 0x1A63, 0x1A87, 0x1AAE, +- 0x1D6B, 0x1D81, 0x1D98, 0x1DB0, 0x1DCA, 0x1DE5, 0x1E02, 0x1E20, 0x1E41, 0x1E63, 0x1E87, 0x1EAE +-}; +- +-const unsigned char CxadhybridPlayer::hyb_default_instrument[11] = +-{ +- 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00 +-}; +- +-CPlayer *CxadhybridPlayer::factory(Copl *newopl) +-{ +- return new CxadhybridPlayer(newopl); +-} +- +-bool CxadhybridPlayer::xadplayer_load() +-{ +- if(xad.fmt != HYBRID) +- return false; +- +- // load instruments +- hyb.inst = (hyb_instrument *)&tune[0]; +- +- // load order +- hyb.order = &tune[0x1D4]; +- +- return true; +-} +- +-void CxadhybridPlayer::xadplayer_rewind(int subsong) +-{ +- int i; +- +- hyb.order_pos = 0; +- hyb.pattern_pos = 0; +- +- hyb.speed = 6; +- hyb.speed_counter = 1; +- +- plr.speed = 1; +- +- // init channel data +- for(i=0;i<9;i++) +- { +- hyb.channel[i].freq = 0x2000; +- hyb.channel[i].freq_slide = 0x0000; +- } +- +- // basic OPL init +- opl_write(0x01, 0x20); +- opl_write(0xBD, 0x40); +- opl_write(0x08, 0x00); +- +- // init OPL channels +- for(i=0;i<9;i++) +- { +- for(int j=0;j<11;j++) +- opl_write(hyb_adlib_registers[i*11+j], 0x00 /* hyb_default_instrument[j] */ ); +- +- opl_write(0xA0+i, 0x00); +- opl_write(0xB0+i, 0x20); +- } +-} +- +-void CxadhybridPlayer::xadplayer_update() +-{ +- int i,j; +- unsigned char patpos,ordpos; +- +- if (--hyb.speed_counter) +- goto update_slides; +- +- hyb.speed_counter = hyb.speed; +- +- patpos = hyb.pattern_pos; +- ordpos = hyb.order_pos; +- +- // process channels +- for(i=0;i<9;i++) +- { +- unsigned char *pos = &tune[0xADE + (hyb.order[hyb.order_pos*9 + i] * 64 * 2) + (patpos * 2)]; +- // read event +- unsigned short event = (pos[1] << 8) + pos[0]; +- +-#ifdef DEBUG +- AdPlug_LogWrite("track %02X, channel %02X, event %04X:\n", hyb.order[hyb.order_pos*9 + i], i, event ); +-#endif +- +- // calculate variables +- unsigned char note = event >> 9; +- unsigned char ins = ((event & 0x01F0) >> 4); +- unsigned char slide = event & 0x000F; +- +- // play event +- switch(note) +- { +- case 0x7D: // 0x7D: Set Speed +- hyb.speed = event & 0xFF; +- break; +- case 0x7E: // 0x7E: Jump Position +- hyb.order_pos = event & 0xFF; +- hyb.pattern_pos = 0x3F; +- +- // jumpback ? +- if (hyb.order_pos <= ordpos) +- plr.looping = 1; +- +- break; +- case 0x7F: // 0x7F: Pattern Break +- hyb.pattern_pos = 0x3F; +- break; +- default: +- +- // is instrument ? +- if (ins) +- for(j=0;j<11;j++) +- opl_write(hyb_adlib_registers[i*11+j], *((unsigned char *)&hyb.inst[ins-1] + 7 + j)); // +7 = skip name... +- +- // is note ? +- if (note) +- { +- hyb.channel[i].freq = hyb_notes[note]; +- hyb.channel[i].freq_slide = 0; +- } +- +- // is slide ? +- if (slide) +- { +- hyb.channel[i].freq_slide = (((slide >> 3) * -1) * (slide & 7)) << 1; +- +- if (slide & 0x80) +- slide = -(slide & 7); +- } +- +- // set frequency +- if (!(hyb.channel[i].freq & 0x2000)) +- { +- opl_write(0xA0+i, hyb.channel[i].freq & 0xFF); +- opl_write(0xB0+i, hyb.channel[i].freq >> 8); +- +- hyb.channel[i].freq |= 0x2000; +- +- opl_write(0xA0+i, hyb.channel[i].freq & 0xFF); +- opl_write(0xB0+i, hyb.channel[i].freq >> 8); +- } +- +- break; +- } +- } +- +- hyb.pattern_pos++; +- +- // end of pattern ? +- if (hyb.pattern_pos >= 0x40) +- { +- hyb.pattern_pos = 0; +- +- hyb.order_pos++; +- } +- +-update_slides: +-#ifdef DEBUG +- AdPlug_LogWrite("slides:\n"); +-#endif +- // update fine frequency slides +- for(i=0;i<9;i++) +- if (hyb.channel[i].freq_slide) +- { +- hyb.channel[i].freq = (((hyb.channel[i].freq & 0x1FFF) + hyb.channel[i].freq_slide) & 0x1FFF) | 0x2000; +- +- opl_write(0xA0+i, hyb.channel[i].freq & 0xFF); +- opl_write(0xB0+i, hyb.channel[i].freq >> 8); +- } +-} +- +-float CxadhybridPlayer::xadplayer_getrefresh() +-{ +- return 50.0f; +-} +- +-std::string CxadhybridPlayer::xadplayer_gettype() +-{ +- return (std::string("xad: hybrid player")); +-} +- +-std::string CxadhybridPlayer::xadplayer_getinstrument(unsigned int i) +-{ +- return (std::string(hyb.inst[i].name,7)); +-} +- +-unsigned int CxadhybridPlayer::xadplayer_getinstruments() +-{ +- return 26; +-} +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/hybrid.h audacious-plugins-3.9/src/adplug/core/hybrid.h +--- audacious-plugins-3.9-orig/src/adplug/core/hybrid.h 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/hybrid.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,80 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2003 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * [xad] HYBRID player, by Riven the Mage +- */ +- +-#include "xad.h" +- +-class CxadhybridPlayer: public CxadPlayer +-{ +-public: +- static CPlayer *factory(Copl *newopl); +- +- CxadhybridPlayer(Copl *newopl): CxadPlayer(newopl) +- { } +- +-protected: +- struct hyb_instrument +- { +- char name[7]; +- unsigned char mod_wave; +- unsigned char mod_AD; +- unsigned char mod_SR; +- unsigned char mod_crtl; +- unsigned char mod_volume; +- unsigned char car_wave; +- unsigned char car_AD; +- unsigned char car_SR; +- unsigned char car_crtl; +- unsigned char car_volume; +- unsigned char connect; +- }; +- +- struct +- { +- unsigned char order_pos; +- unsigned char pattern_pos; +- +- unsigned char *order; +- +- hyb_instrument *inst; +- +- struct +- { +- unsigned short freq; +- unsigned short freq_slide; +- } channel[9]; +- +- unsigned char speed; +- unsigned char speed_counter; +- } hyb; +- // +- bool xadplayer_load(); +- void xadplayer_rewind(int subsong); +- void xadplayer_update(); +- float xadplayer_getrefresh(); +- std::string xadplayer_gettype(); +- std::string xadplayer_getinstrument(unsigned int i); +- unsigned int xadplayer_getinstruments(); +- +-private: +- static const unsigned char hyb_adlib_registers[99]; +- static const unsigned short hyb_notes[98]; +- static const unsigned char hyb_default_instrument[11]; +-}; +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/hyp.cc audacious-plugins-3.9/src/adplug/core/hyp.cc +--- audacious-plugins-3.9-orig/src/adplug/core/hyp.cc 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/hyp.cc 1970-01-01 01:00:00.000000000 +0100 +@@ -1,125 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2003 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * [xad] HYP player, by Riven the Mage +- */ +- +-/* +- - discovery - +- +- file(s) : HT-EF2.COM, HT-EF3.COM +- type : Eiserne Front BBStro +- tune : by Shadowdancer [Hypnosis] +- player : by (?)Hetero [LKCC/SAC] +-*/ +- +-#include "hyp.h" +-#include "debug.h" +- +-const unsigned char CxadhypPlayer::hyp_adlib_registers[99] = +-{ +- 0x20, 0x23, 0x40, 0x43, 0x60, 0x63, 0x80, 0x83, 0xA0, 0xB0, 0xC0, +- 0x21, 0x24, 0x41, 0x44, 0x61, 0x64, 0x81, 0x84, 0xA1, 0xB1, 0xC1, +- 0x22, 0x25, 0x42, 0x45, 0x62, 0x65, 0x82, 0x85, 0xA2, 0xB2, 0xC2, +- 0x28, 0x2B, 0x48, 0x4B, 0x68, 0x6B, 0x88, 0x8B, 0xA3, 0xB3, 0xC3, +- 0x29, 0x2C, 0x49, 0x4C, 0x69, 0x6C, 0x89, 0x8C, 0xA4, 0xB4, 0xC4, +- 0x2A, 0x2D, 0x4A, 0x4D, 0x6A, 0x6D, 0x8A, 0x8D, 0xA5, 0xB5, 0xC5, +- 0x30, 0x33, 0x50, 0x53, 0x70, 0x73, 0x90, 0x93, 0xA6, 0xB6, 0xC6, +- 0x31, 0x34, 0x51, 0x54, 0x71, 0x74, 0x91, 0x94, 0xA7, 0xB7, 0xC7, +- 0x32, 0x35, 0x52, 0x55, 0x72, 0x75, 0x92, 0x95, 0xA8, 0xB8, 0xC8 +-}; +- +-const unsigned short CxadhypPlayer::hyp_notes[73] = +-{ +- 0x0000, // by riven +- 0x0956, 0x096B, 0x0980, 0x0998, 0x09B1, 0x09C9, 0x09E5, 0x0A03, 0x0A21, +- 0x0A41, 0x0A63, 0x0A86, 0x0D56, 0x0D6B, 0x0D80, 0x0D98, 0x0DB1, 0x0DC9, +- 0x0DE5, 0x0E03, 0x0E21, 0x0E41, 0x0E63, 0x0E86, 0x1156, 0x116B, 0x1180, +- 0x1198, 0x11B1, 0x11C9, 0x11E5, 0x1203, 0x1221, 0x1241, 0x1263, 0x1286, +- 0x1556, 0x156B, 0x1580, 0x1598, 0x15B1, 0x15C9, 0x15E5, 0x1603, 0x1621, +- 0x1641, 0x1663, 0x1686, 0x1956, 0x196B, 0x1980, 0x1998, 0x19B1, 0x19C9, +- 0x19E5, 0x1A03, 0x1A21, 0x1A41, 0x1A63, 0x1A86, 0x1D56, 0x1D6B, 0x1D80, +- 0x1D98, 0x1DB1, 0x1DC9, 0x1DE5, 0x1E03, 0x1E21, 0x1E41, 0x1E63, 0x1E86 +-}; +- +-CPlayer *CxadhypPlayer::factory(Copl *newopl) +-{ +- return new CxadhypPlayer(newopl); +-} +- +-void CxadhypPlayer::xadplayer_rewind(int subsong) +-{ +- int i; +- +- plr.speed = tune[5]; +- +- opl_write(0xBD,0xC0); +- +- for(i=0; i<9; i++) +- adlib[0xB0+i] = 0; +- +- // define instruments +- for(i=0; i<99; i++) +- opl_write(hyp_adlib_registers[i], tune[6+i]); +- +- hyp.pointer = 0x69; +-} +- +-void CxadhypPlayer::xadplayer_update() +-{ +- for(int i=0; i<9; i++) +- { +- unsigned char event = tune[hyp.pointer++]; +- +- if (event) +- { +- unsigned short freq = hyp_notes[event & 0x3F]; +- +- unsigned char lofreq = (freq & 0xFF); +- unsigned char hifreq = (freq >> 8); +- +- opl_write(0xB0+i, adlib[0xB0+i]); +- +- if (!(event & 0x40)) +- { +- opl_write(0xA0+i, lofreq); +- opl_write(0xB0+i, hifreq | 0x20); +- } +- +- adlib[0xB0+i] &= 0xDF; +- } +- } +- +- hyp.pointer += 3; +- +- if (hyp.pointer >= tune_size) +- { +- hyp.pointer = 0x69; +- plr.looping = 1; +- } +-} +- +-float CxadhypPlayer::xadplayer_getrefresh() +-{ +- return 60.0f; +-} +- +-std::string CxadhypPlayer::xadplayer_gettype() +-{ +- return std::string("xad: hypnosis player"); +-} +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/hyp.h audacious-plugins-3.9/src/adplug/core/hyp.h +--- audacious-plugins-3.9-orig/src/adplug/core/hyp.h 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/hyp.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,53 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2003 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * [xad] HYP player, by Riven the Mage +- */ +- +-#include "xad.h" +- +-class CxadhypPlayer: public CxadPlayer +-{ +-public: +- static CPlayer *factory(Copl *newopl); +- +- CxadhypPlayer(Copl *newopl): CxadPlayer(newopl) +- { } +- +-protected: +- struct +- { +- unsigned short pointer; +- } hyp; +- // +- bool xadplayer_load() +- { +- if(xad.fmt == HYP) +- return true; +- else +- return false; +- } +- void xadplayer_rewind(int subsong); +- void xadplayer_update(); +- float xadplayer_getrefresh(); +- std::string xadplayer_gettype(); +- +-private: +- static const unsigned char hyp_adlib_registers[99]; +- static const unsigned short hyp_notes[73]; +-}; +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/imf.cc audacious-plugins-3.9/src/adplug/core/imf.cc +--- audacious-plugins-3.9-orig/src/adplug/core/imf.cc 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/imf.cc 1970-01-01 01:00:00.000000000 +0100 +@@ -1,197 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2008 Simon Peter , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * imf.cpp - IMF Player by Simon Peter +- * +- * FILE FORMAT: +- * There seem to be 2 different flavors of IMF formats out there. One version +- * contains just the raw IMF music data. In this case, the first word of the +- * file is always 0 (because the music data starts this way). This is already +- * the music data! So read in the entire file and play it. +- * +- * If this word is greater than 0, it specifies the size of the following +- * song data in bytes. In this case, the file has a footer that contains +- * arbitrary infos about it. Mostly, this is plain ASCII text with some words +- * of the author. Read and play the specified amount of song data and display +- * the remaining data as ASCII text. +- * +- * NOTES: +- * This player handles the two above mentioned formats, as well as a third +- * type, invented by Martin Fernandez , that's got a +- * proper header to add title/game name information. After the header starts +- * the normal IMF file in one of the two above mentioned formats. +- * +- * This player also handles a special footer format by Adam Nielsen, +- * which has defined fields of information about the song, the author +- * and more. +- */ +- +-#include +- +-#include "imf.h" +-#include "database.h" +- +-/*** public methods *************************************/ +- +-CPlayer *CimfPlayer::factory(Copl *newopl) +-{ +- return new CimfPlayer(newopl); +-} +- +-bool CimfPlayer::load(const std::string &filename, const CFileProvider &fp) +-{ +- binistream *f = fp.open(filename); if(!f) return false; +- unsigned long fsize, flsize, mfsize = 0; +- unsigned int i; +- +- // file validation section +- { +- char header[5]; +- int version; +- +- f->readString(header, 5); +- version = f->readInt(1); +- +- if(strncmp(header, "ADLIB", 5) || version != 1) { +- if(!fp.extension(filename, ".imf") && !fp.extension(filename, ".wlf")) { +- // It's no IMF file at all +- fp.close(f); +- return false; +- } else +- f->seek(0); // It's a normal IMF file +- } else { +- // It's a IMF file with header +- track_name = f->readString('\0'); +- game_name = f->readString('\0'); +- f->ignore(1); +- mfsize = f->pos() + 2; +- } +- } +- +- // load section +- if(mfsize) +- fsize = f->readInt(4); +- else +- fsize = f->readInt(2); +- flsize = fp.filesize(f); +- if(!fsize) { // footerless file (raw music data) +- if(mfsize) +- f->seek(-4, binio::Add); +- else +- f->seek(-2, binio::Add); +- size = (flsize - mfsize) / 4; +- } else // file has got a footer +- size = fsize / 4; +- +- data = new Sdata[size]; +- for(i = 0; i < size; i++) { +- data[i].reg = f->readInt(1); data[i].val = f->readInt(1); +- data[i].time = f->readInt(2); +- } +- +- // read footer, if any +- if(fsize && (fsize < flsize - 2 - mfsize)) { +- if(f->readInt(1) == 0x1a) { +- // Adam Nielsen's footer format +- track_name = f->readString(); +- author_name = f->readString(); +- remarks = f->readString(); +- } else { +- // Generic footer +- unsigned long footerlen = flsize - fsize - 2 - mfsize; +- +- footer = new char[footerlen + 1]; +- f->readString(footer, footerlen); +- footer[footerlen] = '\0'; // Make ASCIIZ string +- } +- } +- +- rate = getrate(filename, fp, f); +- fp.close(f); +- rewind(0); +- return true; +-} +- +-bool CimfPlayer::update() +-{ +- do { +- opl->write(data[pos].reg,data[pos].val); +- del = data[pos].time; +- pos++; +- } while(!del && pos < size); +- +- if(pos >= size) { +- pos = 0; +- songend = true; +- } +- else timer = rate / (float)del; +- +- return !songend; +-} +- +-void CimfPlayer::rewind(int subsong) +-{ +- pos = 0; del = 0; timer = rate; songend = false; +- opl->init(); opl->write(1,32); // go to OPL2 mode +-} +- +-std::string CimfPlayer::gettitle() +-{ +- std::string title; +- +- title = track_name; +- +- if(!track_name.empty() && !game_name.empty()) +- title += " - "; +- +- title += game_name; +- +- return title; +-} +- +-std::string CimfPlayer::getdesc() +-{ +- std::string desc; +- +- if(footer) +- desc = std::string(footer); +- +- if(!remarks.empty() && footer) +- desc += "\n\n"; +- +- desc += remarks; +- +- return desc; +-} +- +-/*** private methods *************************************/ +- +-float CimfPlayer::getrate(const std::string &filename, const CFileProvider &fp, binistream *f) +-{ +- if(db) { // Database available +- f->seek(0, binio::Set); +- CClockRecord *record = (CClockRecord *)db->search(CAdPlugDatabase::CKey(*f)); +- if (record && record->type == CAdPlugDatabase::CRecord::ClockSpeed) +- return record->clock; +- } +- +- // Otherwise the database is either unavailable, or there's no entry for this file +- if (fp.extension(filename, ".imf")) return 560.0f; +- if (fp.extension(filename, ".wlf")) return 700.0f; +- return 700.0f; // default speed for unknown files that aren't .IMF or .WLF +-} +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/imf.h audacious-plugins-3.9/src/adplug/core/imf.h +--- audacious-plugins-3.9-orig/src/adplug/core/imf.h 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/imf.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,68 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2005 Simon Peter , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * imf.h - IMF Player by Simon Peter +- */ +- +-#ifndef H_ADPLUG_IMFPLAYER +-#define H_ADPLUG_IMFPLAYER +- +-#include "player.h" +- +-class CimfPlayer: public CPlayer +-{ +-public: +- static CPlayer *factory(Copl *newopl); +- +- CimfPlayer(Copl *newopl) +- : CPlayer(newopl), footer(0), data(0) +- { } +- ~CimfPlayer() +- { if(data) delete [] data; if(footer) delete [] footer; }; +- +- bool load(const std::string &filename, const CFileProvider &fp); +- bool update(); +- void rewind(int subsong); +- float getrefresh() +- { return timer; }; +- +- std::string gettype() +- { return std::string("IMF File Format"); } +- std::string gettitle(); +- std::string getauthor() +- { return author_name; } +- std::string getdesc(); +- +-protected: +- unsigned long pos, size; +- unsigned short del; +- bool songend; +- float rate, timer; +- char *footer; +- std::string track_name, game_name, author_name, remarks; +- +- struct Sdata { +- unsigned char reg, val; +- unsigned short time; +- } *data; +- +-private: +- float getrate(const std::string &filename, const CFileProvider &fp, binistream *f); +-}; +- +-#endif +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/jbm.cc audacious-plugins-3.9/src/adplug/core/jbm.cc +--- audacious-plugins-3.9-orig/src/adplug/core/jbm.cc 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/jbm.cc 1970-01-01 01:00:00.000000000 +0100 +@@ -1,293 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2007 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * Johannes Bjerregaard's JBM Adlib Music Format player for AdPlug +- * Written by Dennis Lindroos , February-March 2007 +- * - Designed and coded from scratch (only frequency-table taken from MUSIC.BIN) +- * - The percussion mode is buggy (?) but i'm not good enough to find them +- * and honestly i think the melodic-mode tunes are much better ;) +- * +- * This version doesn't use the binstr.h functions (coded with custom func.) +- * This is my first attempt on writing a musicplayer for AdPlug, and i'm not +- * coding C++ very often.. +- * +- * Released under the terms of the GNU General Public License. +- */ +- +-#include "jbm.h" +- +-static const unsigned short notetable[96] = { +- 0x0158, 0x016d, 0x0183, 0x019a, 0x01b2, 0x01cc, 0x01e7, 0x0204, +- 0x0223, 0x0244, 0x0266, 0x028b, 0x0558, 0x056d, 0x0583, 0x059a, +- 0x05b2, 0x05cc, 0x05e7, 0x0604, 0x0623, 0x0644, 0x0666, 0x068b, +- 0x0958, 0x096d, 0x0983, 0x099a, 0x09b2, 0x09cc, 0x09e7, 0x0a04, +- 0x0a23, 0x0a44, 0x0a66, 0x0a8b, 0x0d58, 0x0d6d, 0x0d83, 0x0d9a, +- 0x0db2, 0x0dcc, 0x0de7, 0x0e04, 0x0e23, 0x0e44, 0x0e66, 0x0e8b, +- 0x1158, 0x116d, 0x1183, 0x119a, 0x11b2, 0x11cc, 0x11e7, 0x1204, +- 0x1223, 0x1244, 0x1266, 0x128b, 0x1558, 0x156d, 0x1583, 0x159a, +- 0x15b2, 0x15cc, 0x15e7, 0x1604, 0x1623, 0x1644, 0x1666, 0x168b, +- 0x1958, 0x196d, 0x1983, 0x199a, 0x19b2, 0x19cc, 0x19e7, 0x1a04, +- 0x1a23, 0x1a44, 0x1a66, 0x1a8b, 0x1d58, 0x1d6d, 0x1d83, 0x1d9a, +- 0x1db2, 0x1dcc, 0x1de7, 0x1e04, 0x1e23, 0x1e44, 0x1e66, 0x1e8b +-}; +- +-static const unsigned char percmx_tab[4] = { 0x14, 0x12, 0x15, 0x11 }; +-static const unsigned char perchn_tab[5] = { 6, 7, 8, 8, 7 }; +-static unsigned char percmaskoff[5] = { 0xef, 0xf7, 0xfb, 0xfd, 0xfe }; +-static unsigned char percmaskon[5] = { 0x10, 0x08, 0x04, 0x02, 0x01 }; +- +-static inline unsigned short GET_WORD(unsigned char *b, int x) +-{ +- return ((unsigned short)(b[x+1] << 8) | b[x]); +-} +- +-/*** public methods *************************************/ +- +-CPlayer *CjbmPlayer::factory(Copl *newopl) +-{ +- return new CjbmPlayer(newopl); +-} +- +-bool CjbmPlayer::load(const std::string &filename, const CFileProvider &fp) +-{ +- binistream *f = fp.open(filename); if(!f) return false; +- int filelen = fp.filesize(f); +- int i; +- +- if (!filelen || !fp.extension(filename, ".jbm")) goto loaderr; +- +- // Allocate memory buffer m[] and read entire file into it +- +- m = new unsigned char[filelen]; +- if (f->readString((char *)m, filelen) != filelen) goto loaderr; +- +- fp.close(f); +- +- // The known .jbm files always seem to start with the number 0x0002 +- +- if (GET_WORD(m, 0) != 0x0002) +- return false; +- +- // Song tempo +- +- i = GET_WORD(m, 2); +- timer = 1193810.0 / (i ? i : 0xffff); +- +- seqtable = GET_WORD(m, 4); +- instable = GET_WORD(m, 6); +- +- // The flags word has atleast 1 bit, the Adlib's rhythm mode, but +- // currently we don't support that :( +- +- flags = GET_WORD(m, 8); +- +- // Instrument datas are directly addressed with m[] +- +- inscount = (filelen - instable) >> 4; +- +- // Voice' and sequence pointers +- +- seqcount = 0xffff; +- for (i = 0; i < 11; i++) { +- voice[i].trkpos = voice[i].trkstart = GET_WORD(m, 10 + (i<<1)); +- if (voice[i].trkpos && voice[i].trkpos < seqcount) +- seqcount = voice[i].trkpos; +- } +- seqcount = (seqcount - seqtable) >> 1; +- sequences = new unsigned short[seqcount]; +- for (i = 0; i < seqcount; i++) +- sequences[i] = GET_WORD(m, seqtable + (i<<1)); +- +- rewind(0); +- return true; +- loaderr: +- fp.close(f); +- return false; +-} +- +-bool CjbmPlayer::update() +-{ +- short c, spos, frq; +- +- for (c = 0; c < 11; c++) { +- if (!voice[c].trkpos) // Unused channel +- continue; +- +- if (--voice[c].delay) +- continue; +- +- // Turn current note/percussion off +- +- if (voice[c].note&0x7f) +- opl_noteonoff(c, &voice[c], 0); +- +- // Process events until we have a note +- +- spos = voice[c].seqpos; +- while(!voice[c].delay) { +- switch(m[spos]) { +- case 0xFD: // Set Instrument +- voice[c].instr = m[spos+1]; +- set_opl_instrument(c, &voice[c]); +- spos+=2; +- break; +- case 0xFF: // End of Sequence +- voice[c].seqno = m[++voice[c].trkpos]; +- if (voice[c].seqno == 0xff) { +- voice[c].trkpos = voice[c].trkstart; +- voice[c].seqno = m[voice[c].trkpos]; +- //voicemask &= 0x7ff-(1< 95) +- return 0; +- +- voice[c].note = m[spos]; +- voice[c].vol = m[spos+1]; +- voice[c].delay = +- (m[spos+2] + (m[spos+3]<<8)) + 1; +- +- frq = notetable[voice[c].note&127]; +- voice[c].frq[0] = (unsigned char)frq; +- voice[c].frq[1] = frq >> 8; +- spos+=4; +- } +- } +- voice[c].seqpos = spos; +- +- // Write new volume to the carrier operator, or percussion +- +- if (flags&1 && c > 6) +- opl->write(0x40 + percmx_tab[c-7], voice[c].vol ^ 0x3f); +- else +- opl->write(0x43 + op_table[c], voice[c].vol ^ 0x3f); +- +- // Write new frequencies and Gate bit +- +- opl_noteonoff(c, &voice[c], !(voice[c].note & 0x80)); +- } +- return (voicemask); +-} +- +-void CjbmPlayer::rewind(int subsong) +-{ +- int c; +- +- voicemask = 0; +- +- for (c = 0; c < 11; c++) { +- voice[c].trkpos = voice[c].trkstart; +- +- if (!voice[c].trkpos) continue; +- +- voicemask |= (1<init(); +- opl->write(0x01, 32); +- +- // Set rhythm mode if flags bit #0 is set +- // AM and Vibrato are full depths (taken from DosBox RAW output) +- bdreg = 0xC0 | (flags&1)<<5; +- +- opl->write(0xbd, bdreg); +- +-#if 0 +- if (flags&1) { +- voice[7].frq[0] = 0x58; voice[7].frq[1] = 0x09; // XXX +- voice[8].frq[0] = 0x04; voice[8].frq[1] = 0x0a; // XXX +- opl_noteonoff(7, &voice[7], 0); +- opl_noteonoff(8, &voice[8], 0); +- } +-#endif +- +- return; +-} +- +-/*** private methods ************************************/ +- +-void CjbmPlayer::opl_noteonoff(int channel, JBMVoice *v, bool state) +-{ +- if (flags&1 && channel > 5) { +- // Percussion +- opl->write(0xa0 + perchn_tab[channel-6], voice[channel].frq[0]); +- opl->write(0xb0 + perchn_tab[channel-6], voice[channel].frq[1]); +- opl->write(0xbd, +- state ? bdreg | percmaskon[channel-6] : +- bdreg & percmaskoff[channel-6]); +- } else { +- // Melodic mode or Rhythm mode melodic channels +- opl->write(0xa0 + channel, voice[channel].frq[0]); +- opl->write(0xb0 + channel, +- state ? voice[channel].frq[1] | 0x20 : +- voice[channel].frq[1] & 0x1f); +- } +- return; +-} +- +- +-void CjbmPlayer::set_opl_instrument(int channel, JBMVoice *v) +-{ +- short i = instable + (v->instr << 4); +- +- // Sanity check on instr number - or we'll be reading outside m[] ! +- +- if (v->instr >= inscount) +- return; +- +- // For rhythm mode, multiplexed drums. I don't care about waveforms! +- if ((flags&1) & (channel > 6)) { +- opl->write(0x20 + percmx_tab[channel-7], m[i+0]); +- opl->write(0x40 + percmx_tab[channel-7], m[i+1] ^ 0x3f); +- opl->write(0x60 + percmx_tab[channel-7], m[i+2]); +- opl->write(0x80 + percmx_tab[channel-7], m[i+3]); +- +- opl->write(0xc0 + perchn_tab[channel-6], m[i+8]&15); +- return; +- } +- +- // AM/VIB/EG/KSR/FRQMUL, KSL/OUTPUT, ADSR for 1st operator +- opl->write(0x20 + op_table[channel], m[i+0]); +- opl->write(0x40 + op_table[channel], m[i+1] ^ 0x3f); +- opl->write(0x60 + op_table[channel], m[i+2]); +- opl->write(0x80 + op_table[channel], m[i+3]); +- +- // AM/VIB/EG/KSR/FRQMUL, KSL/OUTPUT, ADSR for 2nd operator +- opl->write(0x23 + op_table[channel], m[i+4]); +- opl->write(0x43 + op_table[channel], m[i+5] ^ 0x3f); +- opl->write(0x63 + op_table[channel], m[i+6]); +- opl->write(0x83 + op_table[channel], m[i+7]); +- +- // WAVEFORM for operators +- opl->write(0xe0 + op_table[channel], (m[i+8]>>4)&3); +- opl->write(0xe3 + op_table[channel], (m[i+8]>>6)&3); +- +- // FEEDBACK/FM mode +- opl->write(0xc0 + channel, m[i+8]&15); +- +- return; +-} +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/jbm.h audacious-plugins-3.9/src/adplug/core/jbm.h +--- audacious-plugins-3.9-orig/src/adplug/core/jbm.h 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/jbm.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,80 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2007 Simon Peter , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * jbm.h - JBM Player by Dennis Lindroos +- */ +- +-#ifndef H_ADPLUG_JBMPLAYER +-#define H_ADPLUG_JBMPLAYER +- +-#include "player.h" +- +-class CjbmPlayer: public CPlayer +-{ +- public: +- static CPlayer *factory(Copl *newopl); +- +- CjbmPlayer(Copl *newopl) : CPlayer(newopl), m(0) +- { } +- ~CjbmPlayer() +- { if(m != NULL) delete [] m; } +- +- bool load(const std::string &filename, const CFileProvider &fp); +- bool update(); +- void rewind(int subsong); +- +- float getrefresh() +- { return timer; } +- +- std::string gettype() +- { +- return std::string(flags&1 ? "JBM Adlib Music [rhythm mode]" : +- "JBM Adlib Music"); +- } +- std::string getauthor() +- { return std::string("Johannes Bjerregaard"); } +- +- protected: +- +- unsigned char *m; +- float timer; +- unsigned short flags, voicemask; +- unsigned short seqtable, seqcount; +- unsigned short instable, inscount; +- unsigned short *sequences; +- unsigned char bdreg; +- +- typedef struct { +- unsigned short trkpos, trkstart, seqpos; +- unsigned char seqno, note; +- short vol; +- short delay; +- short instr; +- unsigned char frq[2]; +- unsigned char ivol, dummy; +- } JBMVoice; +- +- JBMVoice voice[11]; +- +- private: +- //void calc_opl_frequency(JBMVoice *); +- void set_opl_instrument(int, JBMVoice *); +- void opl_noteonoff(int, JBMVoice *, bool); +-}; +- +-#endif +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/kemuopl.h audacious-plugins-3.9/src/adplug/core/kemuopl.h +--- audacious-plugins-3.9-orig/src/adplug/core/kemuopl.h 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/kemuopl.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,61 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2005 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * kemuopl.h - Emulated OPL using Ken Silverman's emulator, by Simon Peter +- * +- */ +- +-#ifndef H_ADPLUG_KEMUOPL +-#define H_ADPLUG_KEMUOPL +- +-#include "opl.h" +-extern "C" { +-#include "adlibemu.h" +-} +- +-class CKemuopl: public Copl +-{ +-public: +- CKemuopl(int rate, bool bit16, bool usestereo) +- : use16bit(bit16), stereo(usestereo) +- { +- adlibinit(rate, usestereo ? 2 : 1, bit16 ? 2 : 1); +- currType = TYPE_OPL2; +- }; +- +- void update(short *buf, int samples) +- { +- if(use16bit) samples *= 2; +- if(stereo) samples *= 2; +- adlibgetsample(buf, samples); +- } +- +- // template methods +- void write(int reg, int val) +- { +- if(currChip == 0) +- adlib0(reg, val); +- }; +- +- void init() {}; +- +-private: +- bool use16bit,stereo; +-}; +- +-#endif +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/ksm.cc audacious-plugins-3.9/src/adplug/core/ksm.cc +--- audacious-plugins-3.9-orig/src/adplug/core/ksm.cc 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/ksm.cc 1970-01-01 01:00:00.000000000 +0100 +@@ -1,337 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2006 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * ksm.cpp - KSM Player for AdPlug by Simon Peter +- */ +- +-#include +- +-#include "ksm.h" +-#include "debug.h" +- +-const unsigned int CksmPlayer::adlibfreq[63] = { +- 0, +- 2390,2411,2434,2456,2480,2506,2533,2562,2592,2625,2659,2695, +- 3414,3435,3458,3480,3504,3530,3557,3586,3616,3649,3683,3719, +- 4438,4459,4482,4504,4528,4554,4581,4610,4640,4673,4707,4743, +- 5462,5483,5506,5528,5552,5578,5605,5634,5664,5697,5731,5767, +- 6486,6507,6530,6552,6576,6602,6629,6658,6688,6721,6755,6791, +- 7510}; +- +-/*** public methods **************************************/ +- +-CPlayer *CksmPlayer::factory(Copl *newopl) +-{ +- return new CksmPlayer(newopl); +-} +- +-bool CksmPlayer::load(const std::string &filename, const CFileProvider &fp) +-{ +- binistream *f; +- int i; +- char *fn = new char[filename.length() + 9]; +- +- // file validation section +- if(!fp.extension(filename, ".ksm")) { +- AdPlug_LogWrite("CksmPlayer::load(,\"%s\"): File doesn't have '.ksm' " +- "extension! Rejected!\n", filename.c_str()); +- delete [] fn; +- return false; +- } +- AdPlug_LogWrite("*** CksmPlayer::load(,\"%s\") ***\n", filename.c_str()); +- +- // Load instruments from 'insts.dat' +- strcpy(fn, filename.c_str()); +- for(i = strlen(fn) - 1; i >= 0; i--) +- if(fn[i] == '/' || fn[i] == '\\') +- break; +- strcpy(fn + i + 1, "insts.dat"); +- AdPlug_LogWrite("Instruments file: \"%s\"\n", fn); +- f = fp.open(fn); +- delete [] fn; +- if(!f) { +- AdPlug_LogWrite("Couldn't open instruments file! Aborting!\n"); +- AdPlug_LogWrite("--- CksmPlayer::load ---\n"); +- return false; +- } +- loadinsts(f); +- fp.close(f); +- +- f = fp.open(filename); if(!f) return false; +- for(i = 0; i < 16; i++) trinst[i] = f->readInt(1); +- for(i = 0; i < 16; i++) trquant[i] = f->readInt(1); +- for(i = 0; i < 16; i++) trchan[i] = f->readInt(1); +- f->ignore(16); +- for(i = 0; i < 16; i++) trvol[i] = f->readInt(1); +- numnotes = f->readInt(2); +- note = new unsigned long [numnotes]; +- for(i = 0; i < numnotes; i++) note[i] = f->readInt(4); +- fp.close(f); +- +- if(!trchan[11]) { +- drumstat = 0; +- numchans = 9; +- } else { +- drumstat = 32; +- numchans = 6; +- } +- +- rewind(0); +- AdPlug_LogWrite("--- CksmPlayer::load ---\n"); +- return true; +-} +- +-bool CksmPlayer::update() +-{ +- int quanter,chan,drumnum,freq,track,volevel,volval; +- unsigned int i,j,bufnum; +- unsigned long temp,templong; +- +- count++; +- if (count >= countstop) +- { +- bufnum = 0; +- while (count >= countstop) +- { +- templong = note[nownote]; +- track = (int)((templong>>8)&15); +- if ((templong&192) == 0) +- { +- i = 0; +- +- while ((i < numchans) && +- ((chanfreq[i] != (templong&63)) || +- (chantrack[i] != ((templong>>8)&15)))) +- i++; +- if (i < numchans) +- { +- databuf[bufnum] = (char)0; bufnum++; +- databuf[bufnum] = (unsigned char)(0xb0+i); bufnum++; +- databuf[bufnum] = (unsigned char)((adlibfreq[templong&63]>>8)&223); bufnum++; +- chanfreq[i] = 0; +- chanage[i] = 0; +- } +- } +- else +- { +- volevel = trvol[track]; +- if ((templong&192) == 128) +- { +- volevel -= 4; +- if (volevel < 0) +- volevel = 0; +- } +- if ((templong&192) == 192) +- { +- volevel += 4; +- if (volevel > 63) +- volevel = 63; +- } +- if (track < 11) +- { +- temp = 0; +- i = numchans; +- for(j=0;j= temp) && (chantrack[j] == track)) +- { +- temp = countstop - chanage[j]; +- i = j; +- } +- if (i < numchans) +- { +- databuf[bufnum] = (char)0, bufnum++; +- databuf[bufnum] = (unsigned char)(0xb0+i); bufnum++; +- databuf[bufnum] = (unsigned char)0; bufnum++; +- volval = (inst[trinst[track]][1]&192)+(volevel^63); +- databuf[bufnum] = (char)0, bufnum++; +- databuf[bufnum] = (unsigned char)(0x40+op_table[i]+3); bufnum++; +- databuf[bufnum] = (unsigned char)volval; bufnum++; +- databuf[bufnum] = (char)0, bufnum++; +- databuf[bufnum] = (unsigned char)(0xa0+i); bufnum++; +- databuf[bufnum] = (unsigned char)(adlibfreq[templong&63]&255); bufnum++; +- databuf[bufnum] = (char)0, bufnum++; +- databuf[bufnum] = (unsigned char)(0xb0+i); bufnum++; +- databuf[bufnum] = (unsigned char)((adlibfreq[templong&63]>>8)|32); bufnum++; +- chanfreq[i] = templong&63; +- chanage[i] = countstop; +- } +- } +- else if ((drumstat&32) > 0) +- { +- freq = adlibfreq[templong&63]; +- switch(track) +- { +- case 11: drumnum = 16; chan = 6; freq -= 2048; break; +- case 12: drumnum = 8; chan = 7; freq -= 2048; break; +- case 13: drumnum = 4; chan = 8; break; +- case 14: drumnum = 2; chan = 8; break; +- case 15: drumnum = 1; chan = 7; freq -= 2048; break; +- } +- databuf[bufnum] = (char)0, bufnum++; +- databuf[bufnum] = (unsigned char)(0xa0+chan); bufnum++; +- databuf[bufnum] = (unsigned char)(freq&255); bufnum++; +- databuf[bufnum] = (char)0, bufnum++; +- databuf[bufnum] = (unsigned char)(0xb0+chan); bufnum++; +- databuf[bufnum] = (unsigned char)((freq>>8)&223); bufnum++; +- databuf[bufnum] = (char)0, bufnum++; +- databuf[bufnum] = (unsigned char)(0xbd); bufnum++; +- databuf[bufnum] = (unsigned char)(drumstat&(255-drumnum)); bufnum++; +- drumstat |= drumnum; +- if ((track == 11) || (track == 12) || (track == 14)) +- { +- volval = (inst[trinst[track]][1]&192)+(volevel^63); +- databuf[bufnum] = (char)0, bufnum++; +- databuf[bufnum] = (unsigned char)(0x40+op_table[chan]+3); bufnum++; +- databuf[bufnum] = (unsigned char)(volval); bufnum++; +- } +- else +- { +- volval = (inst[trinst[track]][6]&192)+(volevel^63); +- databuf[bufnum] = (char)0, bufnum++; +- databuf[bufnum] = (unsigned char)(0x40+op_table[chan]); bufnum++; +- databuf[bufnum] = (unsigned char)(volval); bufnum++; +- } +- databuf[bufnum] = (char)0, bufnum++; +- databuf[bufnum] = (unsigned char)(0xbd); bufnum++; +- databuf[bufnum] = (unsigned char)(drumstat); bufnum++; +- } +- } +- nownote++; +- if (nownote >= numnotes) { +- nownote = 0; +- songend = true; +- } +- templong = note[nownote]; +- if (nownote == 0) +- count = (templong>>12)-1; +- quanter = (240/trquant[(templong>>8)&15]); +- countstop = (((templong>>12)+(quanter>>1)) / quanter) * quanter; +- } +- for(i=0;iwrite(databuf[i+1],databuf[i+2]); +- } +- return !songend; +-} +- +-void CksmPlayer::rewind(int subsong) +-{ +- unsigned int i,j,k; +- unsigned char instbuf[11]; +- unsigned long templong; +- +- songend = false; +- opl->init(); opl->write(1,32); opl->write(4,0); opl->write(8,0); opl->write(0xbd,drumstat); +- +- if (trchan[11] == 1) { +- for(i=0;i<11;i++) +- instbuf[i] = inst[trinst[11]][i]; +- instbuf[1] = ((instbuf[1]&192)|((trvol[11])^63)); +- setinst(6,instbuf[0],instbuf[1],instbuf[2],instbuf[3],instbuf[4],instbuf[5],instbuf[6],instbuf[7],instbuf[8],instbuf[9],instbuf[10]); +- for(i=0;i<5;i++) +- instbuf[i] = inst[trinst[12]][i]; +- for(i=5;i<11;i++) +- instbuf[i] = inst[trinst[15]][i]; +- instbuf[1] = ((instbuf[1]&192)|((trvol[12])^63)); +- instbuf[6] = ((instbuf[6]&192)|((trvol[15])^63)); +- setinst(7,instbuf[0],instbuf[1],instbuf[2],instbuf[3],instbuf[4],instbuf[5],instbuf[6],instbuf[7],instbuf[8],instbuf[9],instbuf[10]); +- for(i=0;i<5;i++) +- instbuf[i] = inst[trinst[14]][i]; +- for(i=5;i<11;i++) +- instbuf[i] = inst[trinst[13]][i]; +- instbuf[1] = ((instbuf[1]&192)|((trvol[14])^63)); +- instbuf[6] = ((instbuf[6]&192)|((trvol[13])^63)); +- setinst(8,instbuf[0],instbuf[1],instbuf[2],instbuf[3],instbuf[4],instbuf[5],instbuf[6],instbuf[7],instbuf[8],instbuf[9],instbuf[10]); +- } +- +- for(i=0;i 0) && (j < numchans)) +- { +- k = trchan[i]; +- while ((j < numchans) && (k > 0)) +- { +- chantrack[j] = i; +- k--; +- j++; +- } +- } +- for(i=0;i>12)-1; +- countstop = (templong>>12)-1; +- nownote = 0; +-} +- +-std::string CksmPlayer::getinstrument(unsigned int n) +-{ +- if(trchan[n]) +- return std::string(instname[trinst[n]]); +- else +- return std::string(); +-} +- +-/*** private methods *************************************/ +- +-void CksmPlayer::loadinsts(binistream *f) +-{ +- int i, j; +- +- for(i = 0; i < 256; i++) { +- f->readString(instname[i], 20); +- for(j = 0; j < 11; j++) inst[i][j] = f->readInt(1); +- f->ignore(2); +- } +-} +- +-void CksmPlayer::setinst(int chan, +- unsigned char v0,unsigned char v1,unsigned char v2, +- unsigned char v3,unsigned char v4,unsigned char v5, +- unsigned char v6,unsigned char v7,unsigned char v8, +- unsigned char v9,unsigned char v10) +-{ +- int offs; +- +- opl->write(0xa0+chan,0); +- opl->write(0xb0+chan,0); +- opl->write(0xc0+chan,v10); +- offs = op_table[chan]; +- opl->write(0x20+offs,v5); +- opl->write(0x40+offs,v6); +- opl->write(0x60+offs,v7); +- opl->write(0x80+offs,v8); +- opl->write(0xe0+offs,v9); +- offs+=3; +- opl->write(0x20+offs,v0); +- opl->write(0x40+offs,v1); +- opl->write(0x60+offs,v2); +- opl->write(0x80+offs,v3); +- opl->write(0xe0+offs,v4); +-} +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/ksm.h audacious-plugins-3.9/src/adplug/core/ksm.h +--- audacious-plugins-3.9-orig/src/adplug/core/ksm.h 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/ksm.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,62 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2003 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * ksm.h - KSM Player for AdPlug by Simon Peter +- */ +- +-#include "player.h" +- +-class CksmPlayer: public CPlayer +-{ +-public: +- static CPlayer *factory(Copl *newopl); +- +- CksmPlayer(Copl *newopl) +- : CPlayer(newopl), note(0) +- { }; +- ~CksmPlayer() +- { if(note) delete [] note; }; +- +- bool load(const std::string &filename, const CFileProvider &fp); +- bool update(); +- void rewind(int subsong); +- float getrefresh() +- { return 240.0f; }; +- +- std::string gettype() +- { return std::string("Ken Silverman's Music Format"); }; +- unsigned int getinstruments() +- { return 16; }; +- std::string getinstrument(unsigned int n); +- +-private: +- static const unsigned int adlibfreq[63]; +- +- unsigned long count,countstop,chanage[18],*note; +- unsigned short numnotes; +- unsigned int nownote,numchans,drumstat; +- unsigned char trinst[16],trquant[16],trchan[16],trvol[16],inst[256][11],databuf[2048],chanfreq[18],chantrack[18]; +- char instname[256][20]; +- +- bool songend; +- +- void loadinsts(binistream *f); +- void setinst(int chan,unsigned char v0,unsigned char v1,unsigned char v2,unsigned char v3, +- unsigned char v4,unsigned char v5,unsigned char v6,unsigned char v7, +- unsigned char v8,unsigned char v9,unsigned char v10); +-}; +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/lds.cc audacious-plugins-3.9/src/adplug/core/lds.cc +--- audacious-plugins-3.9-orig/src/adplug/core/lds.cc 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/lds.cc 1970-01-01 01:00:00.000000000 +0100 +@@ -1,678 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2004 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * lds.cpp - LOUDNESS Player by Simon Peter +- */ +- +-#include +- +-#include "lds.h" +-#include "debug.h" +- +-// Note frequency table (16 notes / octave) +-const unsigned short CldsPlayer::frequency[] = { +- 343, 344, 345, 347, 348, 349, 350, 352, 353, 354, 356, 357, 358, +- 359, 361, 362, 363, 365, 366, 367, 369, 370, 371, 373, 374, 375, +- 377, 378, 379, 381, 382, 384, 385, 386, 388, 389, 391, 392, 393, +- 395, 396, 398, 399, 401, 402, 403, 405, 406, 408, 409, 411, 412, +- 414, 415, 417, 418, 420, 421, 423, 424, 426, 427, 429, 430, 432, +- 434, 435, 437, 438, 440, 442, 443, 445, 446, 448, 450, 451, 453, +- 454, 456, 458, 459, 461, 463, 464, 466, 468, 469, 471, 473, 475, +- 476, 478, 480, 481, 483, 485, 487, 488, 490, 492, 494, 496, 497, +- 499, 501, 503, 505, 506, 508, 510, 512, 514, 516, 518, 519, 521, +- 523, 525, 527, 529, 531, 533, 535, 537, 538, 540, 542, 544, 546, +- 548, 550, 552, 554, 556, 558, 560, 562, 564, 566, 568, 571, 573, +- 575, 577, 579, 581, 583, 585, 587, 589, 591, 594, 596, 598, 600, +- 602, 604, 607, 609, 611, 613, 615, 618, 620, 622, 624, 627, 629, +- 631, 633, 636, 638, 640, 643, 645, 647, 650, 652, 654, 657, 659, +- 662, 664, 666, 669, 671, 674, 676, 678, 681, 683 +-}; +- +-// Vibrato (sine) table +-const unsigned char CldsPlayer::vibtab[] = { +- 0, 13, 25, 37, 50, 62, 74, 86, 98, 109, 120, 131, 142, 152, 162, +- 171, 180, 189, 197, 205, 212, 219, 225, 231, 236, 240, 244, 247, +- 250, 252, 254, 255, 255, 255, 254, 252, 250, 247, 244, 240, 236, +- 231, 225, 219, 212, 205, 197, 189, 180, 171, 162, 152, 142, 131, +- 120, 109, 98, 86, 74, 62, 50, 37, 25, 13 +-}; +- +-// Tremolo (sine * sine) table +-const unsigned char CldsPlayer::tremtab[] = { +- 0, 0, 1, 1, 2, 4, 5, 7, 10, 12, 15, 18, 21, 25, 29, 33, 37, 42, 47, +- 52, 57, 62, 67, 73, 79, 85, 90, 97, 103, 109, 115, 121, 128, 134, +- 140, 146, 152, 158, 165, 170, 176, 182, 188, 193, 198, 203, 208, +- 213, 218, 222, 226, 230, 234, 237, 240, 243, 245, 248, 250, 251, +- 253, 254, 254, 255, 255, 255, 254, 254, 253, 251, 250, 248, 245, +- 243, 240, 237, 234, 230, 226, 222, 218, 213, 208, 203, 198, 193, +- 188, 182, 176, 170, 165, 158, 152, 146, 140, 134, 127, 121, 115, +- 109, 103, 97, 90, 85, 79, 73, 67, 62, 57, 52, 47, 42, 37, 33, 29, +- 25, 21, 18, 15, 12, 10, 7, 5, 4, 2, 1, 1, 0 +-}; +- +-// 'maxsound' is maximum number of patches (instruments) +-// 'maxpos' is maximum number of entries in position list (orderlist) +-const unsigned short CldsPlayer::maxsound = 0x3f, CldsPlayer::maxpos = 0xff; +- +-/*** public methods *************************************/ +- +-CldsPlayer::CldsPlayer(Copl *newopl) +- : CPlayer(newopl), soundbank(0), positions(0), patterns(0) +-{ +-} +- +-CldsPlayer::~CldsPlayer() +-{ +- if(soundbank) delete [] soundbank; +- if(positions) delete [] positions; +- if(patterns) delete [] patterns; +-} +- +-bool CldsPlayer::load(const std::string &filename, const CFileProvider &fp) +-{ +- binistream *f; +- unsigned int i, j; +- SoundBank *sb; +- +- // file validation section (actually just an extension check) +- if(!fp.extension(filename, ".lds")) return false; +- f = fp.open(filename); if(!f) return false; +- +- // file load section (header) +- mode = f->readInt(1); +- if(mode > 2) { fp.close(f); return false; } +- speed = f->readInt(2); +- tempo = f->readInt(1); +- pattlen = f->readInt(1); +- for(i = 0; i < 9; i++) chandelay[i] = f->readInt(1); +- regbd = f->readInt(1); +- +- // load patches +- numpatch = f->readInt(2); +- soundbank = new SoundBank[numpatch]; +- for(i = 0; i < numpatch; i++) { +- sb = &soundbank[i]; +- sb->mod_misc = f->readInt(1); sb->mod_vol = f->readInt(1); +- sb->mod_ad = f->readInt(1); sb->mod_sr = f->readInt(1); +- sb->mod_wave = f->readInt(1); sb->car_misc = f->readInt(1); +- sb->car_vol = f->readInt(1); sb->car_ad = f->readInt(1); +- sb->car_sr = f->readInt(1); sb->car_wave = f->readInt(1); +- sb->feedback = f->readInt(1); sb->keyoff = f->readInt(1); +- sb->portamento = f->readInt(1); sb->glide = f->readInt(1); +- sb->finetune = f->readInt(1); sb->vibrato = f->readInt(1); +- sb->vibdelay = f->readInt(1); sb->mod_trem = f->readInt(1); +- sb->car_trem = f->readInt(1); sb->tremwait = f->readInt(1); +- sb->arpeggio = f->readInt(1); +- for(j = 0; j < 12; j++) sb->arp_tab[j] = f->readInt(1); +- sb->start = f->readInt(2); sb->size = f->readInt(2); +- sb->fms = f->readInt(1); sb->transp = f->readInt(2); +- sb->midinst = f->readInt(1); sb->midvelo = f->readInt(1); +- sb->midkey = f->readInt(1); sb->midtrans = f->readInt(1); +- sb->middum1 = f->readInt(1); sb->middum2 = f->readInt(1); +- } +- +- // load positions +- numposi = f->readInt(2); +- positions = new Position[9 * numposi]; +- for(i = 0; i < numposi; i++) +- for(j = 0; j < 9; j++) { +- /* +- * patnum is a pointer inside the pattern space, but patterns are 16bit +- * word fields anyway, so it ought to be an even number (hopefully) and +- * we can just divide it by 2 to get our array index of 16bit words. +- */ +- positions[i * 9 + j].patnum = f->readInt(2) / 2; +- positions[i * 9 + j].transpose = f->readInt(1); +- } +- +- AdPlug_LogWrite("CldsPlayer::load(\"%s\",fp): loading LOUDNESS file: mode = " +- "%d, pattlen = %d, numpatch = %d, numposi = %d\n", +- filename.c_str(), mode, pattlen, numpatch, numposi); +- +- // load patterns +- f->ignore(2); // ignore # of digital sounds (not played by this player) +- patterns = new unsigned short[(fp.filesize(f) - f->pos()) / 2 + 1]; +- for(i = 0; !f->eof(); i++) +- patterns[i] = f->readInt(2); +- +- fp.close(f); +- rewind(0); +- return true; +-} +- +-bool CldsPlayer::update() +-{ +- unsigned short comword, freq, octave, chan, tune, wibc, tremc, arpreg; +- bool vbreak; +- unsigned char level, regnum, comhi, comlo; +- int i; +- Channel *c; +- +- if(!playing) return false; +- +- // handle fading +- if(fadeonoff) { +- if(fadeonoff <= 128) { +- if(allvolume > fadeonoff || allvolume == 0) +- allvolume -= fadeonoff; +- else { +- allvolume = 1; +- fadeonoff = 0; +- if(hardfade != 0) { +- playing = false; +- hardfade = 0; +- for(i = 0; i < 9; i++) +- channel[i].keycount = 1; +- } +- } +- } else +- if(((allvolume + (0x100 - fadeonoff)) & 0xff) <= mainvolume) +- allvolume += 0x100 - fadeonoff; +- else { +- allvolume = mainvolume; +- fadeonoff = 0; +- } +- } +- +- // handle channel delay +- for(chan = 0; chan < 9; chan++) { +- c = &channel[chan]; +- if(c->chancheat.chandelay) +- if(!(--c->chancheat.chandelay)) +- playsound(c->chancheat.sound, chan, c->chancheat.high); +- } +- +- // handle notes +- if(!tempo_now) { +- vbreak = false; +- for(chan = 0; chan < 9; chan++) { +- c = &channel[chan]; +- if(!c->packwait) { +- unsigned short patnum = positions[posplay * 9 + chan].patnum; +- unsigned char transpose = positions[posplay * 9 + chan].transpose; +- +- comword = patterns[patnum + c->packpos]; +- comhi = comword >> 8; comlo = comword & 0xff; +- if(comword) { +- if(comhi == 0x80) +- c->packwait = comlo; +- else +- if(comhi >= 0x80) { +- switch(comhi) { +- case 0xff: +- c->volcar = (((c->volcar & 0x3f) * comlo) >> 6) & 0x3f; +- if(fmchip[0xc0 + chan] & 1) +- c->volmod = (((c->volmod & 0x3f) * comlo) >> 6) & 0x3f; +- break; +- case 0xfe: +- tempo = comword & 0x3f; +- break; +- case 0xfd: +- c->nextvol = comlo; +- break; +- case 0xfc: +- playing = false; +- // in real player there's also full keyoff here, but we don't need it +- break; +- case 0xfb: +- c->keycount = 1; +- break; +- case 0xfa: +- vbreak = true; +- jumppos = (posplay + 1) & maxpos; +- break; +- case 0xf9: +- vbreak = true; +- jumppos = comlo & maxpos; +- jumping = 1; +- if(jumppos < posplay) songlooped = true; +- break; +- case 0xf8: +- c->lasttune = 0; +- break; +- case 0xf7: +- c->vibwait = 0; +- // PASCAL: c->vibspeed = ((comlo >> 4) & 15) + 2; +- c->vibspeed = (comlo >> 4) + 2; +- c->vibrate = (comlo & 15) + 1; +- break; +- case 0xf6: +- c->glideto = comlo; +- break; +- case 0xf5: +- c->finetune = comlo; +- break; +- case 0xf4: +- if(!hardfade) { +- allvolume = mainvolume = comlo; +- fadeonoff = 0; +- } +- break; +- case 0xf3: +- if(!hardfade) fadeonoff = comlo; +- break; +- case 0xf2: +- c->trmstay = comlo; +- break; +- case 0xf1: // panorama +- case 0xf0: // progch +- // MIDI commands (unhandled) +- AdPlug_LogWrite("CldsPlayer(): not handling MIDI command 0x%x, " +- "value = 0x%x\n", comhi, comlo); +- break; +- default: +- if(comhi < 0xa0) +- c->glideto = comhi & 0x1f; +- else +- AdPlug_LogWrite("CldsPlayer(): unknown command 0x%x encountered!" +- " value = 0x%x\n", comhi, comlo); +- break; +- } +- } else { +- unsigned char sound; +- unsigned short high; +- signed char transp = transpose & 127; +- +- /* +- * Originally, in assembler code, the player first shifted +- * logically left the transpose byte by 1 and then shifted +- * arithmetically right the same byte to achieve the final, +- * signed transpose value. Since we can't do arithmetic shifts +- * in C, we just duplicate the 7th bit into the 8th one and +- * discard the 8th one completely. +- */ +- +- if(transpose & 64) transp |= 128; +- +- if(transpose & 128) { +- sound = (comlo + transp) & maxsound; +- high = comhi << 4; +- } else { +- sound = comlo & maxsound; +- high = (comhi + transp) << 4; +- } +- +- /* +- PASCAL: +- sound = comlo & maxsound; +- high = (comhi + (((transpose + 0x24) & 0xff) - 0x24)) << 4; +- */ +- +- if(!chandelay[chan]) +- playsound(sound, chan, high); +- else { +- c->chancheat.chandelay = chandelay[chan]; +- c->chancheat.sound = sound; +- c->chancheat.high = high; +- } +- } +- } +- +- c->packpos++; +- } else +- c->packwait--; +- } +- +- tempo_now = tempo; +- /* +- The continue table is updated here, but this is only used in the +- original player, which can be paused in the middle of a song and then +- unpaused. Since AdPlug does all this for us automatically, we don't +- have a continue table here. The continue table update code is noted +- here for reference only. +- +- if(!pattplay) { +- conttab[speed & maxcont].position = posplay & 0xff; +- conttab[speed & maxcont].tempo = tempo; +- } +- */ +- pattplay++; +- if(vbreak) { +- pattplay = 0; +- for(i = 0; i < 9; i++) channel[i].packpos = channel[i].packwait = 0; +- posplay = jumppos; +- } else +- if(pattplay >= pattlen) { +- pattplay = 0; +- for(i = 0; i < 9; i++) channel[i].packpos = channel[i].packwait = 0; +- posplay = (posplay + 1) & maxpos; +- } +- } else +- tempo_now--; +- +- // make effects +- for(chan = 0; chan < 9; chan++) { +- c = &channel[chan]; +- regnum = op_table[chan]; +- if(c->keycount > 0) { +- if(c->keycount == 1) +- setregs_adv(0xb0 + chan, 0xdf, 0); +- c->keycount--; +- } +- +- // arpeggio +- if(c->arp_size == 0) +- arpreg = 0; +- else { +- arpreg = c->arp_tab[c->arp_pos] << 4; +- if(arpreg == 0x800) { +- if(c->arp_pos > 0) c->arp_tab[0] = c->arp_tab[c->arp_pos - 1]; +- c->arp_size = 1; c->arp_pos = 0; +- arpreg = c->arp_tab[0] << 4; +- } +- +- if(c->arp_count == c->arp_speed) { +- c->arp_pos++; +- if(c->arp_pos >= c->arp_size) c->arp_pos = 0; +- c->arp_count = 0; +- } else +- c->arp_count++; +- } +- +- // glide & portamento +- if(c->lasttune && (c->lasttune != c->gototune)) { +- if(c->lasttune > c->gototune) { +- if(c->lasttune - c->gototune < c->portspeed) +- c->lasttune = c->gototune; +- else +- c->lasttune -= c->portspeed; +- } else { +- if(c->gototune - c->lasttune < c->portspeed) +- c->lasttune = c->gototune; +- else +- c->lasttune += c->portspeed; +- } +- +- if(arpreg >= 0x800) +- arpreg = c->lasttune - (arpreg ^ 0xff0) - 16; +- else +- arpreg += c->lasttune; +- +- freq = frequency[arpreg % (12 * 16)]; +- octave = arpreg / (12 * 16) - 1; +- setregs(0xa0 + chan, freq & 0xff); +- setregs_adv(0xb0 + chan, 0x20, ((octave << 2) + (freq >> 8)) & 0xdf); +- } else { +- // vibrato +- if(!c->vibwait) { +- if(c->vibrate) { +- wibc = vibtab[c->vibcount & 0x3f] * c->vibrate; +- +- if((c->vibcount & 0x40) == 0) +- tune = c->lasttune + (wibc >> 8); +- else +- tune = c->lasttune - (wibc >> 8); +- +- if(arpreg >= 0x800) +- tune = tune - (arpreg ^ 0xff0) - 16; +- else +- tune += arpreg; +- +- freq = frequency[tune % (12 * 16)]; +- octave = tune / (12 * 16) - 1; +- setregs(0xa0 + chan, freq & 0xff); +- setregs_adv(0xb0 + chan, 0x20, ((octave << 2) + (freq >> 8)) & 0xdf); +- c->vibcount += c->vibspeed; +- } else +- if(c->arp_size != 0) { // no vibrato, just arpeggio +- if(arpreg >= 0x800) +- tune = c->lasttune - (arpreg ^ 0xff0) - 16; +- else +- tune = c->lasttune + arpreg; +- +- freq = frequency[tune % (12 * 16)]; +- octave = tune / (12 * 16) - 1; +- setregs(0xa0 + chan, freq & 0xff); +- setregs_adv(0xb0 + chan, 0x20, ((octave << 2) + (freq >> 8)) & 0xdf); +- } +- } else { // no vibrato, just arpeggio +- c->vibwait--; +- +- if(c->arp_size != 0) { +- if(arpreg >= 0x800) +- tune = c->lasttune - (arpreg ^ 0xff0) - 16; +- else +- tune = c->lasttune + arpreg; +- +- freq = frequency[tune % (12 * 16)]; +- octave = tune / (12 * 16) - 1; +- setregs(0xa0 + chan, freq & 0xff); +- setregs_adv(0xb0 + chan, 0x20, ((octave << 2) + (freq >> 8)) & 0xdf); +- } +- } +- } +- +- // tremolo (modulator) +- if(!c->trmwait) { +- if(c->trmrate) { +- tremc = tremtab[c->trmcount & 0x7f] * c->trmrate; +- if((tremc >> 8) <= (c->volmod & 0x3f)) +- level = (c->volmod & 0x3f) - (tremc >> 8); +- else +- level = 0; +- +- if(allvolume != 0 && (fmchip[0xc0 + chan] & 1)) +- setregs_adv(0x40 + regnum, 0xc0, ((level * allvolume) >> 8) ^ 0x3f); +- else +- setregs_adv(0x40 + regnum, 0xc0, level ^ 0x3f); +- +- c->trmcount += c->trmspeed; +- } else +- if(allvolume != 0 && (fmchip[0xc0 + chan] & 1)) +- setregs_adv(0x40 + regnum, 0xc0, ((((c->volmod & 0x3f) * allvolume) >> 8) ^ 0x3f) & 0x3f); +- else +- setregs_adv(0x40 + regnum, 0xc0, (c->volmod ^ 0x3f) & 0x3f); +- } else { +- c->trmwait--; +- if(allvolume != 0 && (fmchip[0xc0 + chan] & 1)) +- setregs_adv(0x40 + regnum, 0xc0, ((((c->volmod & 0x3f) * allvolume) >> 8) ^ 0x3f) & 0x3f); +- } +- +- // tremolo (carrier) +- if(!c->trcwait) { +- if(c->trcrate) { +- tremc = tremtab[c->trccount & 0x7f] * c->trcrate; +- if((tremc >> 8) <= (c->volcar & 0x3f)) +- level = (c->volcar & 0x3f) - (tremc >> 8); +- else +- level = 0; +- +- if(allvolume != 0) +- setregs_adv(0x43 + regnum, 0xc0, ((level * allvolume) >> 8) ^ 0x3f); +- else +- setregs_adv(0x43 + regnum, 0xc0, level ^ 0x3f); +- c->trccount += c->trcspeed; +- } else +- if(allvolume != 0) +- setregs_adv(0x43 + regnum, 0xc0, ((((c->volcar & 0x3f) * allvolume) >> 8) ^ 0x3f) & 0x3f); +- else +- setregs_adv(0x43 + regnum, 0xc0, (c->volcar ^ 0x3f) & 0x3f); +- } else { +- c->trcwait--; +- if(allvolume != 0) +- setregs_adv(0x43 + regnum, 0xc0, ((((c->volcar & 0x3f) * allvolume) >> 8) ^ 0x3f) & 0x3f); +- } +- } +- +- return (!playing || songlooped) ? false : true; +-} +- +-void CldsPlayer::rewind(int subsong) +-{ +- int i; +- +- // init all with 0 +- tempo_now = 3; playing = true; songlooped = false; +- jumping = fadeonoff = allvolume = hardfade = pattplay = posplay = jumppos = +- mainvolume = 0; +- memset(channel, 0, sizeof(channel)); +- memset(fmchip, 0, sizeof(fmchip)); +- +- // OPL2 init +- opl->init(); // Reset OPL chip +- opl->write(1, 0x20); +- opl->write(8, 0); +- opl->write(0xbd, regbd); +- +- for(i = 0; i < 9; i++) { +- opl->write(0x20 + op_table[i], 0); +- opl->write(0x23 + op_table[i], 0); +- opl->write(0x40 + op_table[i], 0x3f); +- opl->write(0x43 + op_table[i], 0x3f); +- opl->write(0x60 + op_table[i], 0xff); +- opl->write(0x63 + op_table[i], 0xff); +- opl->write(0x80 + op_table[i], 0xff); +- opl->write(0x83 + op_table[i], 0xff); +- opl->write(0xe0 + op_table[i], 0); +- opl->write(0xe3 + op_table[i], 0); +- opl->write(0xa0 + i, 0); +- opl->write(0xb0 + i, 0); +- opl->write(0xc0 + i, 0); +- } +-} +- +-/*** private methods *************************************/ +- +-void CldsPlayer::playsound(int inst_number, int channel_number, int tunehigh) +-{ +- Channel *c = &channel[channel_number]; // current channel +- SoundBank *i = &soundbank[inst_number]; // current instrument +- unsigned int regnum = op_table[channel_number]; // channel's OPL2 register +- unsigned char volcalc, octave; +- unsigned short freq; +- +- // set fine tune +- tunehigh += ((i->finetune + c->finetune + 0x80) & 0xff) - 0x80; +- +- // arpeggio handling +- if(!i->arpeggio) { +- unsigned short arpcalc = i->arp_tab[0] << 4; +- +- if(arpcalc > 0x800) +- tunehigh = tunehigh - (arpcalc ^ 0xff0) - 16; +- else +- tunehigh += arpcalc; +- } +- +- // glide handling +- if(c->glideto != 0) { +- c->gototune = tunehigh; +- c->portspeed = c->glideto; +- c->glideto = c->finetune = 0; +- return; +- } +- +- // set modulator registers +- setregs(0x20 + regnum, i->mod_misc); +- volcalc = i->mod_vol; +- if(!c->nextvol || !(i->feedback & 1)) +- c->volmod = volcalc; +- else +- c->volmod = (volcalc & 0xc0) | ((((volcalc & 0x3f) * c->nextvol) >> 6)); +- +- if((i->feedback & 1) == 1 && allvolume != 0) +- setregs(0x40 + regnum, ((c->volmod & 0xc0) | (((c->volmod & 0x3f) * allvolume) >> 8)) ^ 0x3f); +- else +- setregs(0x40 + regnum, c->volmod ^ 0x3f); +- setregs(0x60 + regnum, i->mod_ad); +- setregs(0x80 + regnum, i->mod_sr); +- setregs(0xe0 + regnum, i->mod_wave); +- +- // Set carrier registers +- setregs(0x23 + regnum, i->car_misc); +- volcalc = i->car_vol; +- if(!c->nextvol) +- c->volcar = volcalc; +- else +- c->volcar = (volcalc & 0xc0) | ((((volcalc & 0x3f) * c->nextvol) >> 6)); +- +- if(allvolume) +- setregs(0x43 + regnum, ((c->volcar & 0xc0) | (((c->volcar & 0x3f) * allvolume) >> 8)) ^ 0x3f); +- else +- setregs(0x43 + regnum, c->volcar ^ 0x3f); +- setregs(0x63 + regnum, i->car_ad); +- setregs(0x83 + regnum, i->car_sr); +- setregs(0xe3 + regnum, i->car_wave); +- setregs(0xc0 + channel_number, i->feedback); +- setregs_adv(0xb0 + channel_number, 0xdf, 0); // key off +- +- freq = frequency[tunehigh % (12 * 16)]; +- octave = tunehigh / (12 * 16) - 1; +- if(!i->glide) { +- if(!i->portamento || !c->lasttune) { +- setregs(0xa0 + channel_number, freq & 0xff); +- setregs(0xb0 + channel_number, (octave << 2) + 0x20 + (freq >> 8)); +- c->lasttune = c->gototune = tunehigh; +- } else { +- c->gototune = tunehigh; +- c->portspeed = i->portamento; +- setregs_adv(0xb0 + channel_number, 0xdf, 0x20); // key on +- } +- } else { +- setregs(0xa0 + channel_number, freq & 0xff); +- setregs(0xb0 + channel_number, (octave << 2) + 0x20 + (freq >> 8)); +- c->lasttune = tunehigh; +- c->gototune = tunehigh + ((i->glide + 0x80) & 0xff) - 0x80; // set destination +- c->portspeed = i->portamento; +- } +- +- if(!i->vibrato) +- c->vibwait = c->vibspeed = c->vibrate = 0; +- else { +- c->vibwait = i->vibdelay; +- // PASCAL: c->vibspeed = ((i->vibrato >> 4) & 15) + 1; +- c->vibspeed = (i->vibrato >> 4) + 2; +- c->vibrate = (i->vibrato & 15) + 1; +- } +- +- if(!(c->trmstay & 0xf0)) { +- c->trmwait = (i->tremwait & 0xf0) >> 3; +- // PASCAL: c->trmspeed = (i->mod_trem >> 4) & 15; +- c->trmspeed = i->mod_trem >> 4; +- c->trmrate = i->mod_trem & 15; +- c->trmcount = 0; +- } +- +- if(!(c->trmstay & 0x0f)) { +- c->trcwait = (i->tremwait & 15) << 1; +- // PASCAL: c->trcspeed = (i->car_trem >> 4) & 15; +- c->trcspeed = i->car_trem >> 4; +- c->trcrate = i->car_trem & 15; +- c->trccount = 0; +- } +- +- c->arp_size = i->arpeggio & 15; +- c->arp_speed = i->arpeggio >> 4; +- memcpy(c->arp_tab, i->arp_tab, 12); +- c->keycount = i->keyoff; +- c->nextvol = c->glideto = c->finetune = c->vibcount = c->arp_pos = c->arp_count = 0; +-} +- +-inline void CldsPlayer::setregs(unsigned char reg, unsigned char val) +-{ +- if(fmchip[reg] == val) return; +- +- fmchip[reg] = val; +- opl->write(reg, val); +-} +- +-inline void CldsPlayer::setregs_adv(unsigned char reg, unsigned char mask, +- unsigned char val) +-{ +- setregs(reg, (fmchip[reg] & mask) | val); +-} +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/lds.h audacious-plugins-3.9/src/adplug/core/lds.h +--- audacious-plugins-3.9-orig/src/adplug/core/lds.h 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/lds.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,91 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2004 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * lds.h - LOUDNESS Player by Simon Peter +- */ +- +-#include "player.h" +- +-class CldsPlayer: public CPlayer +-{ +- public: +- static CPlayer *factory(Copl *newopl) { return new CldsPlayer(newopl); } +- +- CldsPlayer(Copl *newopl); +- virtual ~CldsPlayer(); +- +- bool load(const std::string &filename, const CFileProvider &fp); +- virtual bool update(); +- virtual void rewind(int subsong = -1); +- float getrefresh() { return 70.0f; } +- +- std::string gettype() { return std::string("LOUDNESS Sound System"); } +- unsigned int getorders() { return numposi; } +- unsigned int getorder() { return posplay; } +- unsigned int getrow() { return pattplay; } +- unsigned int getspeed() { return speed; } +- unsigned int getinstruments() { return numpatch; } +- +- private: +- typedef struct { +- unsigned char mod_misc, mod_vol, mod_ad, mod_sr, mod_wave, +- car_misc, car_vol, car_ad, car_sr, car_wave, feedback, keyoff, +- portamento, glide, finetune, vibrato, vibdelay, mod_trem, car_trem, +- tremwait, arpeggio, arp_tab[12]; +- unsigned short start, size; +- unsigned char fms; +- unsigned short transp; +- unsigned char midinst, midvelo, midkey, midtrans, middum1, middum2; +- } SoundBank; +- +- typedef struct { +- unsigned short gototune, lasttune, packpos; +- unsigned char finetune, glideto, portspeed, nextvol, volmod, volcar, +- vibwait, vibspeed, vibrate, trmstay, trmwait, trmspeed, trmrate, trmcount, +- trcwait, trcspeed, trcrate, trccount, arp_size, arp_speed, keycount, +- vibcount, arp_pos, arp_count, packwait, arp_tab[12]; +- +- struct { +- unsigned char chandelay, sound; +- unsigned short high; +- } chancheat; +- } Channel; +- +- typedef struct { +- unsigned short patnum; +- unsigned char transpose; +- } Position; +- +- static const unsigned short frequency[]; +- static const unsigned char vibtab[], tremtab[]; +- static const unsigned short maxsound, maxpos; +- +- SoundBank *soundbank; +- Channel channel[9]; +- Position *positions; +- unsigned char fmchip[0xff], jumping, fadeonoff, allvolume, hardfade, +- tempo_now, pattplay, tempo, regbd, chandelay[9], mode, pattlen; +- unsigned short posplay, jumppos, *patterns, speed; +- bool playing, songlooped; +- unsigned int numpatch, numposi, mainvolume; +- +- void playsound(int inst_number, int channel_number, int tunehigh); +- inline void setregs(unsigned char reg, unsigned char val); +- inline void setregs_adv(unsigned char reg, unsigned char mask, +- unsigned char val); +-}; +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/mad.cc audacious-plugins-3.9/src/adplug/core/mad.cc +--- audacious-plugins-3.9-orig/src/adplug/core/mad.cc 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/mad.cc 1970-01-01 01:00:00.000000000 +0100 +@@ -1,127 +0,0 @@ +-/* +- Adplug - Replayer for many OPL2/OPL3 audio file formats. +- Copyright (C) 1999 - 2003 Simon Peter, , et al. +- +- This library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- This library 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 +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with this library; if not, write to the Free Software +- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- +- mad.cpp - MAD loader by Riven the Mage +-*/ +- +-#include +-#include "mad.h" +- +-/* -------- Public Methods -------------------------------- */ +- +-CPlayer *CmadLoader::factory(Copl *newopl) +-{ +- return new CmadLoader(newopl); +-} +- +-bool CmadLoader::load(const std::string &filename, const CFileProvider &fp) +-{ +- binistream *f = fp.open(filename); if(!f) return false; +- const unsigned char conv_inst[10] = { 2,1,10,9,4,3,6,5,8,7 }; +- unsigned int i, j, k, t = 0; +- +- // 'MAD+' - signed ? +- char id[4]; f->readString(id, 4); +- if (strncmp(id,"MAD+",4)) { fp.close(f); return false; } +- +- // load instruments +- for(i = 0; i < 9; i++) { +- f->readString(instruments[i].name, 8); +- for(j = 0; j < 12; j++) instruments[i].data[j] = f->readInt(1); +- } +- +- f->ignore(1); +- +- // data for Protracker +- length = f->readInt(1); nop = f->readInt(1); timer = f->readInt(1); +- +- // init CmodPlayer +- realloc_instruments(9); +- realloc_order(length); +- realloc_patterns(nop,32,9); +- init_trackord(); +- +- // load tracks +- for(i = 0; i < nop; i++) +- for(k = 0; k < 32; k++) +- for(j = 0; j < 9; j++) { +- t = i * 9 + j; +- +- // read event +- unsigned char event = f->readInt(1); +- +- // convert event +- if (event < 0x61) +- tracks[t][k].note = event; +- if (event == 0xFF) // 0xFF: Release note +- tracks[t][k].command = 8; +- if (event == 0xFE) // 0xFE: Pattern Break +- tracks[t][k].command = 13; +- } +- +- // load order +- for(i = 0; i < length; i++) order[i] = f->readInt(1) - 1; +- +- fp.close(f); +- +- // convert instruments +- for(i = 0; i < 9; i++) +- for(j = 0; j < 10; j++) +- inst[i].data[conv_inst[j]] = instruments[i].data[j]; +- +- // data for Protracker +- restartpos = 0; +- initspeed = 1; +- +- rewind(0); +- return true; +-} +- +-void CmadLoader::rewind(int subsong) +-{ +- CmodPlayer::rewind(subsong); +- +- // default instruments +- for (int i=0;i<9;i++) +- { +- channel[i].inst = i; +- +- channel[i].vol1 = 63 - (inst[i].data[10] & 63); +- channel[i].vol2 = 63 - (inst[i].data[9] & 63); +- } +-} +- +-float CmadLoader::getrefresh() +-{ +- return (float)timer; +-} +- +-std::string CmadLoader::gettype() +-{ +- return std::string("Mlat Adlib Tracker"); +-} +- +-std::string CmadLoader::getinstrument(unsigned int n) +-{ +- return std::string(instruments[n].name,8); +-} +- +-unsigned int CmadLoader::getinstruments() +-{ +- return 9; +-} +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/mad.h audacious-plugins-3.9/src/adplug/core/mad.h +--- audacious-plugins-3.9-orig/src/adplug/core/mad.h 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/mad.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,48 +0,0 @@ +-/* +- Adplug - Replayer for many OPL2/OPL3 audio file formats. +- Copyright (C) 1999 - 2003 Simon Peter, , et al. +- +- This library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- This library 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 +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with this library; if not, write to the Free Software +- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- +- mad.h - MAD loader by Riven the Mage +-*/ +- +-#include "protrack.h" +- +-class CmadLoader: public CmodPlayer +-{ +-public: +- static CPlayer *factory(Copl *newopl); +- +- CmadLoader(Copl *newopl) : CmodPlayer(newopl) { }; +- +- bool load(const std::string &filename, const CFileProvider &fp); +- void rewind(int subsong); +- float getrefresh(); +- +- std::string gettype(); +- std::string getinstrument(unsigned int n); +- unsigned int getinstruments(); +- +-private: +- +- struct mad_instrument +- { +- char name[8]; +- unsigned char data[12]; // last two unused +- } instruments[9]; +- +- unsigned char timer; +-}; +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/mid.cc audacious-plugins-3.9/src/adplug/core/mid.cc +--- audacious-plugins-3.9-orig/src/adplug/core/mid.cc 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/mid.cc 1970-01-01 01:00:00.000000000 +0100 +@@ -1,1110 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2008 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * +- * MIDI & MIDI-like file player - Last Update: 10/15/2005 +- * by Phil Hassey - www.imitationpickles.org +- * philhassey@hotmail.com +- * +- * Can play the following +- * .LAA - a raw save of a Lucas Arts Adlib music +- * or +- * a raw save of a LucasFilm Adlib music +- * .MID - a "midi" save of a Lucas Arts Adlib music +- * - or general MIDI files +- * .CMF - Creative Music Format +- * .SCI - the sierra "midi" format. +- * Files must be in the form +- * xxxNAME.sci +- * So that the loader can load the right patch file: +- * xxxPATCH.003 (patch.003 must be saved from the +- * sierra resource from each game.) +- * +- * 6/2/2000: v1.0 relased by phil hassey +- * Status: LAA is almost perfect +- * - some volumes are a bit off (intrument too quiet) +- * MID is fine (who wants to listen to MIDI vid adlib anyway) +- * CMF is okay (still needs the adlib rythm mode implemented +- * for real) +- * 6/6/2000: +- * Status: SCI: there are two SCI formats, orginal and advanced. +- * original: (Found in SCI/EGA Sierra Adventures) +- * played almost perfectly, I believe +- * there is one mistake in the instrument +- * loader that causes some sounds to +- * not be quite right. Most sounds are fine. +- * advanced: (Found in SCI/VGA Sierra Adventures) +- * These are multi-track files. (Thus the +- * player had to be modified to work with +- * them.) This works fine. +- * There are also multiple tunes in each file. +- * I think some of them are supposed to be +- * played at the same time, but I'm not sure +- * when. +- * 8/16/2000: +- * Status: LAA: now EGA and VGA lucas games work pretty well +- * +- * 10/15/2005: Changes by Simon Peter +- * Added rhythm mode support for CMF format. +- * +- * 09/13/2008: Changes by Adam Nielsen (malvineous@shikadi.net) +- * Fixed a couple of CMF rhythm mode bugs +- * Disabled note velocity for CMF files +- * Added support for nonstandard CMF AM+VIB controller (for VGFM CMFs) +- * +- * Other acknowledgements: +- * Allegro - for the midi instruments and the midi volume table +- * SCUMM Revisited - for getting the .LAA / .MIDs out of those +- * LucasArts files. +- * FreeSCI - for some information on the sci music files +- * SD - the SCI Decoder (to get all .sci out of the Sierra files) +- */ +- +-#include +-#include +-#include +-#include +-#include "mid.h" +-#include "mididata.h" +- +-/*#define TESTING*/ +-#ifdef TESTING +-#define midiprintf printf +-#else +-void CmidPlayer::midiprintf(const char *format, ...) +- { +- } +-#endif +- +-#define LUCAS_STYLE 1 +-#define CMF_STYLE 2 +-#define MIDI_STYLE 4 +-#define SIERRA_STYLE 8 +- +-// AdLib melodic and rhythm mode defines +-#define ADLIB_MELODIC 0 +-#define ADLIB_RYTHM 1 +- +-// File types +-#define FILE_LUCAS 1 +-#define FILE_MIDI 2 +-#define FILE_CMF 3 +-#define FILE_SIERRA 4 +-#define FILE_ADVSIERRA 5 +-#define FILE_OLDLUCAS 6 +- +-// AdLib standard operator table +-const unsigned char CmidPlayer::adlib_opadd[] = {0x00 ,0x01 ,0x02 ,0x08 ,0x09 ,0x0A ,0x10 ,0x11 ,0x12}; +- +-// map CMF drum channels 12 - 15 to corresponding AdLib drum operators +-// bass drum (channel 11) not mapped, cause it's handled like a normal instrument +-const int CmidPlayer::map_chan[] = { 0x14, 0x12, 0x15, 0x11 }; +- +-// Standard AdLib frequency table +-const int CmidPlayer::fnums[] = { 0x16b,0x181,0x198,0x1b0,0x1ca,0x1e5,0x202,0x220,0x241,0x263,0x287,0x2ae }; +- +-// Map CMF drum channels 11 - 15 to corresponding AdLib drum channels +-const int CmidPlayer::percussion_map[] = { 6, 7, 8, 8, 7 }; +- +-CPlayer *CmidPlayer::factory(Copl *newopl) +-{ +- return new CmidPlayer(newopl); +-} +- +-CmidPlayer::CmidPlayer(Copl *newopl) +- : CPlayer(newopl), author(&emptystr), title(&emptystr), remarks(&emptystr), +- emptystr('\0'), flen(0), data(0) +-{ +-} +- +-unsigned char CmidPlayer::datalook(long pos) +-{ +- if (pos<0 || pos >= flen) return(0); +- return(data[pos]); +-} +- +-unsigned long CmidPlayer::getnexti(unsigned long num) +-{ +- unsigned long v=0; +- unsigned long i; +- +- for (i=0; i= 0; i--) +- if(pfilename[i] == '/' || pfilename[i] == '\\') { +- j = i+1; +- break; +- } +- sprintf(pfilename+j+3,"patch.003"); +- +- f = fp.open(pfilename); +- free(pfilename); +- if(!f) return false; +- +- f->ignore(2); +- stins = 0; +- for (i=0; i<2; i++) +- { +- for (k=0; k<48; k++) +- { +- l=i*48+k; +- midiprintf ("\n%2ld: ",l); +- for (j=0; j<28; j++) +- ins[j] = f->readInt(1); +- +- myinsbank[l][0]= +- (ins[9]*0x80) + (ins[10]*0x40) + +- (ins[5]*0x20) + (ins[11]*0x10) + +- ins[1]; //1=ins5 +- myinsbank[l][1]= +- (ins[22]*0x80) + (ins[23]*0x40) + +- (ins[18]*0x20) + (ins[24]*0x10) + +- ins[14]; //1=ins18 +- +- myinsbank[l][2]=(ins[0]<<6)+ins[8]; +- myinsbank[l][3]=(ins[13]<<6)+ins[21]; +- +- myinsbank[l][4]=(ins[3]<<4)+ins[6]; +- myinsbank[l][5]=(ins[16]<<4)+ins[19]; +- myinsbank[l][6]=(ins[4]<<4)+ins[7]; +- myinsbank[l][7]=(ins[17]<<4)+ins[20]; +- +- myinsbank[l][8]=ins[26]; +- myinsbank[l][9]=ins[27]; +- +- myinsbank[l][10]=((ins[2]<<1))+(1-(ins[12]&1)); +- //(ins[12] ? 0:1)+((ins[2]<<1)); +- +- for (j=0; j<11; j++) +- midiprintf ("%02X ",myinsbank[l][j]); +- stins++; +- } +- f->ignore(2); +- } +- +- fp.close(f); +- memcpy(smyinsbank, myinsbank, 128 * 16); +- return true; +-} +- +-void CmidPlayer::sierra_next_section() +-{ +- int i,j; +- +- for (i=0; i<16; i++) +- track[i].on=0; +- +- midiprintf("\n\nnext adv sierra section:\n"); +- +- pos=sierra_pos; +- i=0;j=0; +- while (i!=0xff) +- { +- getnext(1); +- curtrack=j; j++; +- track[curtrack].on=1; +- track[curtrack].spos = getnext(1); +- track[curtrack].spos += (getnext(1) << 8) + 4; //4 best usually +3? not 0,1,2 or 5 +-// track[curtrack].spos=getnext(1)+(getnext(1)<<8)+4; // dynamite!: doesn't optimize correctly!! +- track[curtrack].tend=flen; //0xFC will kill it +- track[curtrack].iwait=0; +- track[curtrack].pv=0; +- midiprintf ("track %u starts at %lx\n",curtrack,track[curtrack].spos); +- +- getnext(2); +- i=getnext(1); +- } +- getnext(2); +- deltas=0x20; +- sierra_pos=pos; +- //getch(); +- +- fwait=0; +- doing=1; +-} +- +-bool CmidPlayer::load(const std::string &filename, const CFileProvider &fp) +-{ +- binistream *f = fp.open(filename); if(!f) return false; +- int good; +- unsigned char s[6]; +- +- f->readString((char *)s, 6); +- good=0; +- subsongs=0; +- switch(s[0]) +- { +- case 'A': +- if (s[1]=='D' && s[2]=='L') good=FILE_LUCAS; +- break; +- case 'M': +- if (s[1]=='T' && s[2]=='h' && s[3]=='d') good=FILE_MIDI; +- break; +- case 'C': +- if (s[1]=='T' && s[2]=='M' && s[3]=='F') good=FILE_CMF; +- break; +- case 0x84: +- if (s[1]==0x00 && load_sierra_ins(filename, fp)) { +- if (s[2]==0xf0) +- good=FILE_ADVSIERRA; +- else +- good=FILE_SIERRA; +- } +- break; +- default: +- if (s[4]=='A' && s[5]=='D') good=FILE_OLDLUCAS; +- break; +- } +- +- if (good!=0) +- subsongs=1; +- else { +- fp.close(f); +- return false; +- } +- +- type=good; +- f->seek(0); +- flen = fp.filesize(f); +- data = new unsigned char [flen]; +- f->readString((char *)data, flen); +- +- fp.close(f); +- rewind(0); +- return true; +-} +- +-void CmidPlayer::midi_write_adlib(unsigned int r, unsigned char v) +-{ +- opl->write(r,v); +- adlib_data[r]=v; +-} +- +-void CmidPlayer::midi_fm_instrument(int voice, unsigned char *inst) +-{ +- if ((adlib_style&SIERRA_STYLE)!=0) +- midi_write_adlib(0xbd,0); //just gotta make sure this happens.. +- //'cause who knows when it'll be +- //reset otherwise. +- +- +- midi_write_adlib(0x20+adlib_opadd[voice],inst[0]); +- midi_write_adlib(0x23+adlib_opadd[voice],inst[1]); +- +- if (adlib_style & LUCAS_STYLE) { +- midi_write_adlib(0x43+adlib_opadd[voice],0x3f); +- if ((inst[10] & 1)==0) +- midi_write_adlib(0x40+adlib_opadd[voice],inst[2]); +- else +- midi_write_adlib(0x40+adlib_opadd[voice],0x3f); +- +- } else if ((adlib_style & SIERRA_STYLE) || (adlib_style & CMF_STYLE)) { +- midi_write_adlib(0x40+adlib_opadd[voice],inst[2]); +- midi_write_adlib(0x43+adlib_opadd[voice],inst[3]); +- +- } else { +- midi_write_adlib(0x40+adlib_opadd[voice],inst[2]); +- if ((inst[10] & 1)==0) +- midi_write_adlib(0x43+adlib_opadd[voice],inst[3]); +- else +- midi_write_adlib(0x43+adlib_opadd[voice],0); +- } +- +- midi_write_adlib(0x60+adlib_opadd[voice],inst[4]); +- midi_write_adlib(0x63+adlib_opadd[voice],inst[5]); +- midi_write_adlib(0x80+adlib_opadd[voice],inst[6]); +- midi_write_adlib(0x83+adlib_opadd[voice],inst[7]); +- midi_write_adlib(0xe0+adlib_opadd[voice],inst[8]); +- midi_write_adlib(0xe3+adlib_opadd[voice],inst[9]); +- +- midi_write_adlib(0xc0+voice,inst[10]); +-} +- +-void CmidPlayer::midi_fm_percussion(int ch, unsigned char *inst) +-{ +- int opadd = map_chan[ch - 12]; +- +- midi_write_adlib(0x20 + opadd, inst[0]); +- midi_write_adlib(0x40 + opadd, inst[2]); +- midi_write_adlib(0x60 + opadd, inst[4]); +- midi_write_adlib(0x80 + opadd, inst[6]); +- midi_write_adlib(0xe0 + opadd, inst[8]); +- if (opadd < 0x13) // only output this for the modulator, not the carrier, as it affects the entire channel +- midi_write_adlib(0xc0 + percussion_map[ch - 11], inst[10]); +-} +- +-void CmidPlayer::midi_fm_volume(int voice, int volume) +-{ +- int vol; +- +- if ((adlib_style&SIERRA_STYLE)==0) //sierra likes it loud! +- { +- vol=volume>>2; +- +- if ((adlib_style&LUCAS_STYLE)!=0) +- { +- if ((adlib_data[0xc0+voice]&1)==1) +- midi_write_adlib(0x40+adlib_opadd[voice], (unsigned char)((63-vol) | +- (adlib_data[0x40+adlib_opadd[voice]]&0xc0))); +- midi_write_adlib(0x43+adlib_opadd[voice], (unsigned char)((63-vol) | +- (adlib_data[0x43+adlib_opadd[voice]]&0xc0))); +- } +- else +- { +- if ((adlib_data[0xc0+voice]&1)==1) +- midi_write_adlib(0x40+adlib_opadd[voice], (unsigned char)((63-vol) | +- (adlib_data[0x40+adlib_opadd[voice]]&0xc0))); +- midi_write_adlib(0x43+adlib_opadd[voice], (unsigned char)((63-vol) | +- (adlib_data[0x43+adlib_opadd[voice]]&0xc0))); +- } +- } +-} +- +-void CmidPlayer::midi_fm_playnote(int voice, int note, int volume) +-{ +- int freq=fnums[note%12]; +- int oct=note/12; +- int c; +- +- midi_fm_volume(voice,volume); +- midi_write_adlib(0xa0+voice,(unsigned char)(freq&0xff)); +- +- c=((freq&0x300) >> 8)+((oct&7)<<2) + (adlib_mode == ADLIB_MELODIC || voice < 6 ? (1<<5) : 0); +- midi_write_adlib(0xb0+voice,(unsigned char)c); +-} +- +-void CmidPlayer::midi_fm_endnote(int voice) +-{ +- //midi_fm_volume(voice,0); +- //midi_write_adlib(0xb0+voice,0); +- +- midi_write_adlib(0xb0+voice,(unsigned char)(adlib_data[0xb0+voice]&(255-32))); +-} +- +-void CmidPlayer::midi_fm_reset() +-{ +- int i; +- +- opl->init(); +- +- for (i=0; i<256; i++) +- midi_write_adlib(i,0); +- +- midi_write_adlib(0x01, 0x20); +- midi_write_adlib(0xBD,0xc0); +-} +- +-bool CmidPlayer::update() +-{ +- long w,v,note,vel,ctrl,nv,x,l,lnum; +- int i=0,j,c; +- int on,onl,numchan; +- int ret; +- +- if (doing == 1) +- { +- // just get the first wait and ignore it :> +- for (curtrack=0; curtrack<16; curtrack++) +- if (track[curtrack].on) +- { +- pos=track[curtrack].pos; +- if (type != FILE_SIERRA && type !=FILE_ADVSIERRA) +- track[curtrack].iwait+=getval(); +- else +- track[curtrack].iwait+=getnext(1); +- track[curtrack].pos=pos; +- } +- doing=0; +- } +- +- iwait=0; +- ret=1; +- +- while (iwait==0 && ret==1) +- { +- for (curtrack=0; curtrack<16; curtrack++) +- if (track[curtrack].on && track[curtrack].iwait==0 && +- track[curtrack].pos < track[curtrack].tend) +- { +- pos=track[curtrack].pos; +- +- v=getnext(1); +- +- // This is to do implied MIDI events. +- if (v<0x80) {v=track[curtrack].pv; pos--;} +- track[curtrack].pv=(unsigned char)v; +- +- c=v&0x0f; +- midiprintf ("[%2lX]",v); +- switch(v&0xf0) +- { +- case 0x80: /*note off*/ +- note=getnext(1); vel=getnext(1); +- for (i=0; i<9; i++) +- if (chp[i][0]==c && chp[i][1]==note) +- { +- midi_fm_endnote(i); +- chp[i][0]=-1; +- } +- break; +- case 0x90: /*note on*/ +- // doing=0; +- note=getnext(1); vel=getnext(1); +- +- if(adlib_mode == ADLIB_RYTHM) +- numchan = 6; +- else +- numchan = 9; +- +- if (ch[c].on!=0) +- { +- for (i=0; i<18; i++) +- chp[i][2]++; +- +- if(c < 11 || adlib_mode == ADLIB_MELODIC) { +- j=0; +- on=-1;onl=0; +- for (i=0; ionl) +- { onl=chp[i][2]; on=i; j=1; } +- +- if (on==-1) +- { +- onl=0; +- for (i=0; ionl) +- { onl=chp[i][2]; on=i; } +- } +- +- if (j==0) +- midi_fm_endnote(on); +- } else +- on = percussion_map[c - 11]; +- +- if (vel!=0 && ch[c].inum>=0 && ch[c].inum<128) { +- if (adlib_mode == ADLIB_MELODIC || c < 12) // 11 == bass drum, handled like a normal instrument, on == channel 6 thanks to percussion_map[] above +- midi_fm_instrument(on,ch[c].ins); +- else +- midi_fm_percussion(c, ch[c].ins); +- +- if (adlib_style & MIDI_STYLE) { +- nv=((ch[c].vol*vel)/128); +- if ((adlib_style&LUCAS_STYLE)!=0) nv*=2; +- if (nv>127) nv=127; +- nv=my_midi_fm_vol_table[nv]; +- if ((adlib_style&LUCAS_STYLE)!=0) +- nv=(int)((float)sqrt((float)nv)*11); +- } else if (adlib_style & CMF_STYLE) { +- // CMF doesn't support note velocity (even though some files have them!) +- nv = 127; +- } else { +- nv=vel; +- } +- +- midi_fm_playnote(on,note+ch[c].nshift,nv*2); // sets freq in rhythm mode +- chp[on][0]=c; +- chp[on][1]=note; +- chp[on][2]=0; +- +- if(adlib_mode == ADLIB_RYTHM && c >= 11) { +- // Still need to turn off the perc instrument before playing it again, +- // as not all songs send a noteoff. +- midi_write_adlib(0xbd, adlib_data[0xbd] & ~(0x10 >> (c - 11))); +- // Play the perc instrument +- midi_write_adlib(0xbd, adlib_data[0xbd] | (0x10 >> (c - 11))); +- } +- +- } else { +- if (vel==0) { //same code as end note +- if (adlib_mode == ADLIB_RYTHM && c >= 11) { +- // Turn off the percussion instrument +- midi_write_adlib(0xbd, adlib_data[0xbd] & ~(0x10 >> (c - 11))); +- //midi_fm_endnote(percussion_map[c]); +- chp[percussion_map[c - 11]][0]=-1; +- } else { +- for (i=0; i<9; i++) { +- if (chp[i][0]==c && chp[i][1]==note) { +- // midi_fm_volume(i,0); // really end the note +- midi_fm_endnote(i); +- chp[i][0]=-1; +- } +- } +- } +- } else { +- // i forget what this is for. +- chp[on][0]=-1; +- chp[on][2]=0; +- } +- } +- midiprintf(" [%d:%d:%ld:%ld]\n",c,ch[c].inum,note,vel); +- } +- else +- midiprintf ("off"); +- break; +- case 0xa0: /*key after touch */ +- note=getnext(1); vel=getnext(1); +- /* //this might all be good +- for (i=0; i<9; i++) +- if (chp[i][0]==c & chp[i][1]==note) +- +-midi_fm_playnote(i,note+cnote[c],my_midi_fm_vol_table[(cvols[c]*vel)/128]*2); +- */ +- break; +- case 0xb0: /*control change .. pitch bend? */ +- ctrl=getnext(1); vel=getnext(1); +- +- switch(ctrl) +- { +- case 0x07: +- midiprintf ("(pb:%d: %ld %ld)",c,ctrl,vel); +- ch[c].vol=vel; +- midiprintf("vol"); +- break; +- case 0x63: +- if (adlib_style & CMF_STYLE) { +- // Custom extension to allow CMF files to switch the +- // AM+VIB depth on and off (officially this is on, +- // and there's no way to switch it off.) Controller +- // values: +- // 0 == AM+VIB off +- // 1 == VIB on +- // 2 == AM on +- // 3 == AM+VIB on +- midi_write_adlib(0xbd, (adlib_data[0xbd] & ~0xC0) | (vel << 6)); +- midiprintf(" AM+VIB depth change - AM %s, VIB %s\n", +- (adlib_data[0xbd] & 0x80) ? "on" : "off", +- (adlib_data[0xbd] & 0x40) ? "on" : "off" +- ); +- } +- break; +- case 0x67: +- midiprintf("Rhythm mode: %ld\n", vel); +- if ((adlib_style&CMF_STYLE)!=0) { +- adlib_mode=vel; +- if(adlib_mode == ADLIB_RYTHM) +- midi_write_adlib(0xbd, adlib_data[0xbd] | (1 << 5)); +- else +- midi_write_adlib(0xbd, adlib_data[0xbd] & ~(1 << 5)); +- } +- break; +- } +- break; +- case 0xc0: /*patch change*/ +- x=getnext(1); +- ch[c].inum=x; +- for (j=0; j<11; j++) +- ch[c].ins[j]=myinsbank[ch[c].inum][j]; +- break; +- case 0xd0: /*chanel touch*/ +- x=getnext(1); +- break; +- case 0xe0: /*pitch wheel*/ +- x=getnext(1); +- x=getnext(1); +- break; +- case 0xf0: +- switch(v) +- { +- case 0xf0: +- case 0xf7: /*sysex*/ +- l=getval(); +- if (datalook(pos+l)==0xf7) +- i=1; +- midiprintf("{%ld}",l); +- midiprintf("\n"); +- +- if (datalook(pos)==0x7d && +- datalook(pos+1)==0x10 && +- datalook(pos+2)<16) +- { +- adlib_style=LUCAS_STYLE|MIDI_STYLE; +- for (i=0; i",w); +- f = +-((float)w/(float)deltas)*((float)msqtr/(float)1000000); +- if (doing==1) f=0; //not playing yet. don't wait yet +- } +- */ +- } +- else +- track[curtrack].iwait=0; +- +- track[curtrack].pos=pos; +- } +- +- +- ret=0; //end of song. +- iwait=0; +- for (curtrack=0; curtrack<16; curtrack++) +- if (track[curtrack].on == 1 && +- track[curtrack].pos < track[curtrack].tend) +- ret=1; //not yet.. +- +- if (ret==1) +- { +- iwait=0xffffff; // bigger than any wait can be! +- for (curtrack=0; curtrack<16; curtrack++) +- if (track[curtrack].on == 1 && +- track[curtrack].pos < track[curtrack].tend && +- track[curtrack].iwait < iwait) +- iwait=track[curtrack].iwait; +- } +- } +- +- +- if (iwait !=0 && ret==1) +- { +- for (curtrack=0; curtrack<16; curtrack++) +- if (track[curtrack].on) +- track[curtrack].iwait-=iwait; +- +- +-fwait=1.0f/(((float)iwait/(float)deltas)*((float)msqtr/(float)1000000)); +- } +- else +- fwait=50; // 1/50th of a second +- +- midiprintf ("\n"); +- for (i=0; i<16; i++) +- if (track[i].on) { +- if (track[i].pos < track[i].tend) +- midiprintf ("<%lu>",track[i].iwait); +- else +- midiprintf("stop"); +- } +- +- /* +- if (ret==0 && type==FILE_ADVSIERRA) +- if (datalook(sierra_pos-2)!=0xff) +- { +- midiprintf ("next sectoin!"); +- sierra_next_section(p); +- fwait=50; +- ret=1; +- } +- */ +- +- if(ret) +- return true; +- else +- return false; +-} +- +-float CmidPlayer::getrefresh() +-{ +- return (fwait > 0.01f ? fwait : 0.01f); +-} +- +-void CmidPlayer::rewind(int subsong) +-{ +- long i,j,n,m,l; +- long o_sierra_pos; +- unsigned char ins[16]; +- +- pos=0; tins=0; +- adlib_style=MIDI_STYLE|CMF_STYLE; +- adlib_mode=ADLIB_MELODIC; +- for (i=0; i<128; i++) +- for (j=0; j<16; j++) +- myinsbank[i][j]=midi_fm_instruments[i][j]; +- for (i=0; i<16; i++) +- { +- ch[i].inum=0; +- for (j=0; j<11; j++) +- ch[i].ins[j]=myinsbank[ch[i].inum][j]; +- ch[i].vol=127; +- ch[i].nshift=-25; +- ch[i].on=1; +- } +- +- /* General init */ +- for (i=0; i<9; i++) +- { +- chp[i][0]=-1; +- chp[i][2]=0; +- } +- +- deltas=250; // just a number, not a standard +- msqtr=500000; +- fwait=123; // gotta be a small thing.. sorta like nothing +- iwait=0; +- +- subsongs=1; +- +- for (i=0; i<16; i++) +- { +- track[i].tend=0; +- track[i].spos=0; +- track[i].pos=0; +- track[i].iwait=0; +- track[i].on=0; +- track[i].pv=0; +- } +- curtrack=0; +- +- /* specific to file-type init */ +- +- pos=0; +- i=getnext(1); +- switch(type) +- { +- case FILE_LUCAS: +- getnext(24); //skip junk and get to the midi. +- adlib_style=LUCAS_STYLE|MIDI_STYLE; +- //note: no break, we go right into midi headers... +- case FILE_MIDI: +- if (type != FILE_LUCAS) +- tins=128; +- getnext(11); /*skip header*/ +- deltas=getnext(2); +- midiprintf ("deltas:%ld\n",deltas); +- getnext(4); +- +- curtrack=0; +- track[curtrack].on=1; +- track[curtrack].tend=getnext(4); +- track[curtrack].spos=pos; +- midiprintf ("tracklen:%lu\n",track[curtrack].tend); +- break; +- case FILE_CMF: +- getnext(3); // ctmf +- getnexti(2); //version +- n=getnexti(2); // instrument offset +- m=getnexti(2); // music offset +- deltas=getnexti(2); //ticks/qtr note +- msqtr=1000000/getnexti(2)*deltas; +- //the stuff in the cmf is click ticks per second.. +- +- i=getnexti(2); +- if(i) title = (char *)data+i; +- i=getnexti(2); +- if(i) author = (char *)data+i; +- i=getnexti(2); +- if(i) remarks = (char *)data+i; +- +- getnext(16); // channel in use table .. +- i=getnexti(2); // num instr +- if (i>128) i=128; // to ward of bad numbers... +- getnexti(2); //basic tempo +- +- midiprintf("\nioff:%ld\nmoff%ld\ndeltas:%ld\nmsqtr:%ld\nnumi:%ld\n", +- n,m,deltas,msqtr,i); +- pos=n; // jump to instruments +- tins=i; +- for (j=0; j= subsongs) subsong=0; +- +- sierra_pos=o_sierra_pos; +- sierra_next_section(); +- i=0; +- while (i != subsong) +- { +- sierra_next_section(); +- i++; +- } +- +- adlib_style=SIERRA_STYLE|MIDI_STYLE; //advanced sierra tunes use volume +- break; +- case FILE_SIERRA: +- memcpy(myinsbank, smyinsbank, 128 * 16); +- tins = stins; +- getnext(2); +- deltas=0x20; +- +- curtrack=0; +- track[curtrack].on=1; +- track[curtrack].tend=flen; // music until the end of the file +- +- for (i=0; i<16; i++) +- { +- ch[i].nshift=-13; +- ch[i].on=getnext(1); +- ch[i].inum=getnext(1); +- for (j=0; j<11; j++) +- ch[i].ins[j]=myinsbank[ch[i].inum][j]; +- } +- +- track[curtrack].spos=pos; +- adlib_style=SIERRA_STYLE|MIDI_STYLE; +- break; +- } +- +- +-/* sprintf(info,"%s\r\nTicks/Quarter Note: %ld\r\n",info,deltas); +- sprintf(info,"%sms/Quarter Note: %ld",info,msqtr); */ +- +- for (i=0; i<16; i++) +- if (track[i].on) +- { +- track[i].pos=track[i].spos; +- track[i].pv=0; +- track[i].iwait=0; +- } +- +- doing=1; +- midi_fm_reset(); +-} +- +-std::string CmidPlayer::gettype() +-{ +- switch(type) { +- case FILE_LUCAS: +- return std::string("LucasArts AdLib MIDI"); +- case FILE_MIDI: +- return std::string("General MIDI"); +- case FILE_CMF: +- return std::string("Creative Music Format (CMF MIDI)"); +- case FILE_OLDLUCAS: +- return std::string("Lucasfilm Adlib MIDI"); +- case FILE_ADVSIERRA: +- return std::string("Sierra On-Line VGA MIDI"); +- case FILE_SIERRA: +- return std::string("Sierra On-Line EGA MIDI"); +- default: +- return std::string("MIDI unknown"); +- } +-} +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/mid.h audacious-plugins-3.9/src/adplug/core/mid.h +--- audacious-plugins-3.9-orig/src/adplug/core/mid.h 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/mid.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,112 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2008 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * mid.h - LAA, SCI, MID & CMF Player by Philip Hassey +- */ +- +-#include "player.h" +- +-class CmidPlayer: public CPlayer +-{ +-public: +- static CPlayer *factory(Copl *newopl); +- +- CmidPlayer(Copl *newopl); +- ~CmidPlayer() +- { if(data) delete [] data; } +- +- bool load(const std::string &filename, const CFileProvider &fp); +- bool update(); +- void rewind(int subsong); +- float getrefresh(); +- +- std::string gettype(); +- std::string gettitle() +- { return std::string(title); } +- std::string getauthor() +- { return std::string(author); } +- std::string getdesc() +- { return std::string(remarks); } +- unsigned int getinstruments() +- { return tins; } +- unsigned int getsubsongs() +- { return subsongs; } +- +- protected: +- static const unsigned char adlib_opadd[]; +- static const int ops[], map_chan[], fnums[], percussion_map[]; +- +- struct midi_channel { +- int inum; +- unsigned char ins[11]; +- int vol; +- int nshift; +- int on; +- }; +- +- struct midi_track { +- unsigned long tend; +- unsigned long spos; +- unsigned long pos; +- unsigned long iwait; +- int on; +- unsigned char pv; +- }; +- +- char *author,*title,*remarks,emptystr; +- long flen; +- unsigned long pos; +- unsigned long sierra_pos; //sierras gotta be special.. :> +- int subsongs; +- unsigned char *data; +- +- unsigned char adlib_data[256]; +- int adlib_style; +- int adlib_mode; +- unsigned char myinsbank[128][16], smyinsbank[128][16]; +- midi_channel ch[16]; +- int chp[18][3]; +- +- long deltas; +- long msqtr; +- +- midi_track track[16]; +- unsigned int curtrack; +- +- float fwait; +- unsigned long iwait; +- int doing; +- +- int type,tins,stins; +- +- private: +- bool load_sierra_ins(const std::string &fname, const CFileProvider &fp); +- void midiprintf(const char *format, ...); +- unsigned char datalook(long pos); +- unsigned long getnexti(unsigned long num); +- unsigned long getnext(unsigned long num); +- unsigned long getval(); +- void sierra_next_section(); +- void midi_write_adlib(unsigned int r, unsigned char v); +- void midi_fm_instrument(int voice, unsigned char *inst); +- void midi_fm_percussion(int ch, unsigned char *inst); +- void midi_fm_volume(int voice, int volume); +- void midi_fm_playnote(int voice, int note, int volume); +- void midi_fm_endnote(int voice); +- void midi_fm_reset(); +-}; +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/mididata.h audacious-plugins-3.9/src/adplug/core/mididata.h +--- audacious-plugins-3.9-orig/src/adplug/core/mididata.h 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/mididata.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,174 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999, 2000, 2001 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * +- * FM instrument definitions below borrowed from the Allegro library by +- * Phil Hassey, - see "adplug/players/mid.cpp" +- * for further acknowledgements. +- */ +- +-unsigned char midi_fm_instruments[128][16] = +-{ +- +- /* This set of GM instrument patches was provided by Jorrit Rouwe... +- */ +- +- { 0x21, 0x21, 0x8f, 0x0c, 0xf2, 0xf2, 0x45, 0x76, 0x00, 0x00, 0x08, 0, 0, 0 }, /* Acoustic Grand */ +- { 0x31, 0x21, 0x4b, 0x09, 0xf2, 0xf2, 0x54, 0x56, 0x00, 0x00, 0x08, 0, 0, 0 }, /* Bright Acoustic */ +- { 0x31, 0x21, 0x49, 0x09, 0xf2, 0xf2, 0x55, 0x76, 0x00, 0x00, 0x08, 0, 0, 0 }, /* Electric Grand */ +- { 0xb1, 0x61, 0x0e, 0x09, 0xf2, 0xf3, 0x3b, 0x0b, 0x00, 0x00, 0x06, 0, 0, 0 }, /* Honky-Tonk */ +- { 0x01, 0x21, 0x57, 0x09, 0xf1, 0xf1, 0x38, 0x28, 0x00, 0x00, 0x00, 0, 0, 0 }, /* Electric Piano 1 */ +- { 0x01, 0x21, 0x93, 0x09, 0xf1, 0xf1, 0x38, 0x28, 0x00, 0x00, 0x00, 0, 0, 0 }, /* Electric Piano 2 */ +- { 0x21, 0x36, 0x80, 0x17, 0xa2, 0xf1, 0x01, 0xd5, 0x00, 0x00, 0x08, 0, 0, 0 }, /* Harpsichord */ +- { 0x01, 0x01, 0x92, 0x09, 0xc2, 0xc2, 0xa8, 0x58, 0x00, 0x00, 0x0a, 0, 0, 0 }, /* Clav */ +- { 0x0c, 0x81, 0x5c, 0x09, 0xf6, 0xf3, 0x54, 0xb5, 0x00, 0x00, 0x00, 0, 0, 0 }, /* Celesta */ +- { 0x07, 0x11, 0x97, 0x89, 0xf6, 0xf5, 0x32, 0x11, 0x00, 0x00, 0x02, 0, 0, 0 }, /* Glockenspiel */ +- { 0x17, 0x01, 0x21, 0x09, 0x56, 0xf6, 0x04, 0x04, 0x00, 0x00, 0x02, 0, 0, 0 }, /* Music Box */ +- { 0x18, 0x81, 0x62, 0x09, 0xf3, 0xf2, 0xe6, 0xf6, 0x00, 0x00, 0x00, 0, 0, 0 }, /* Vibraphone */ +- { 0x18, 0x21, 0x23, 0x09, 0xf7, 0xe5, 0x55, 0xd8, 0x00, 0x00, 0x00, 0, 0, 0 }, /* Marimba */ +- { 0x15, 0x01, 0x91, 0x09, 0xf6, 0xf6, 0xa6, 0xe6, 0x00, 0x00, 0x04, 0, 0, 0 }, /* Xylophone */ +- { 0x45, 0x81, 0x59, 0x89, 0xd3, 0xa3, 0x82, 0xe3, 0x00, 0x00, 0x0c, 0, 0, 0 }, /* Tubular Bells */ +- { 0x03, 0x81, 0x49, 0x89, 0x74, 0xb3, 0x55, 0x05, 0x01, 0x00, 0x04, 0, 0, 0 }, /* Dulcimer */ +- { 0x71, 0x31, 0x92, 0x09, 0xf6, 0xf1, 0x14, 0x07, 0x00, 0x00, 0x02, 0, 0, 0 }, /* Drawbar Organ */ +- { 0x72, 0x30, 0x14, 0x09, 0xc7, 0xc7, 0x58, 0x08, 0x00, 0x00, 0x02, 0, 0, 0 }, /* Percussive Organ */ +- { 0x70, 0xb1, 0x44, 0x09, 0xaa, 0x8a, 0x18, 0x08, 0x00, 0x00, 0x04, 0, 0, 0 }, /* Rock Organ */ +- { 0x23, 0xb1, 0x93, 0x09, 0x97, 0x55, 0x23, 0x14, 0x01, 0x00, 0x04, 0, 0, 0 }, /* Church Organ */ +- { 0x61, 0xb1, 0x13, 0x89, 0x97, 0x55, 0x04, 0x04, 0x01, 0x00, 0x00, 0, 0, 0 }, /* Reed Organ */ +- { 0x24, 0xb1, 0x48, 0x09, 0x98, 0x46, 0x2a, 0x1a, 0x01, 0x00, 0x0c, 0, 0, 0 }, /* Accoridan */ +- { 0x61, 0x21, 0x13, 0x09, 0x91, 0x61, 0x06, 0x07, 0x01, 0x00, 0x0a, 0, 0, 0 }, /* Harmonica */ +- { 0x21, 0xa1, 0x13, 0x92, 0x71, 0x61, 0x06, 0x07, 0x00, 0x00, 0x06, 0, 0, 0 }, /* Tango Accordian */ +- { 0x02, 0x41, 0x9c, 0x89, 0xf3, 0xf3, 0x94, 0xc8, 0x01, 0x00, 0x0c, 0, 0, 0 }, /* Acoustic Guitar(nylon) */ +- { 0x03, 0x11, 0x54, 0x09, 0xf3, 0xf1, 0x9a, 0xe7, 0x01, 0x00, 0x0c, 0, 0, 0 }, /* Acoustic Guitar(steel) */ +- { 0x23, 0x21, 0x5f, 0x09, 0xf1, 0xf2, 0x3a, 0xf8, 0x00, 0x00, 0x00, 0, 0, 0 }, /* Electric Guitar(jazz) */ +- { 0x03, 0x21, 0x87, 0x89, 0xf6, 0xf3, 0x22, 0xf8, 0x01, 0x00, 0x06, 0, 0, 0 }, /* Electric Guitar(clean) */ +- { 0x03, 0x21, 0x47, 0x09, 0xf9, 0xf6, 0x54, 0x3a, 0x00, 0x00, 0x00, 0, 0, 0 }, /* Electric Guitar(muted) */ +- { 0x23, 0x21, 0x4a, 0x0e, 0x91, 0x84, 0x41, 0x19, 0x01, 0x00, 0x08, 0, 0, 0 }, /* Overdriven Guitar */ +- { 0x23, 0x21, 0x4a, 0x09, 0x95, 0x94, 0x19, 0x19, 0x01, 0x00, 0x08, 0, 0, 0 }, /* Distortion Guitar */ +- { 0x09, 0x84, 0xa1, 0x89, 0x20, 0xd1, 0x4f, 0xf8, 0x00, 0x00, 0x08, 0, 0, 0 }, /* Guitar Harmonics */ +- { 0x21, 0xa2, 0x1e, 0x09, 0x94, 0xc3, 0x06, 0xa6, 0x00, 0x00, 0x02, 0, 0, 0 }, /* Acoustic Bass */ +- { 0x31, 0x31, 0x12, 0x09, 0xf1, 0xf1, 0x28, 0x18, 0x00, 0x00, 0x0a, 0, 0, 0 }, /* Electric Bass(finger) */ +- { 0x31, 0x31, 0x8d, 0x09, 0xf1, 0xf1, 0xe8, 0x78, 0x00, 0x00, 0x0a, 0, 0, 0 }, /* Electric Bass(pick) */ +- { 0x31, 0x32, 0x5b, 0x09, 0x51, 0x71, 0x28, 0x48, 0x00, 0x00, 0x0c, 0, 0, 0 }, /* Fretless Bass */ +- { 0x01, 0x21, 0x8b, 0x49, 0xa1, 0xf2, 0x9a, 0xdf, 0x00, 0x00, 0x08, 0, 0, 0 }, /* Slap Bass 1 */ +- { 0x21, 0x21, 0x8b, 0x11, 0xa2, 0xa1, 0x16, 0xdf, 0x00, 0x00, 0x08, 0, 0, 0 }, /* Slap Bass 2 */ +- { 0x31, 0x31, 0x8b, 0x09, 0xf4, 0xf1, 0xe8, 0x78, 0x00, 0x00, 0x0a, 0, 0, 0 }, /* Synth Bass 1 */ +- { 0x31, 0x31, 0x12, 0x09, 0xf1, 0xf1, 0x28, 0x18, 0x00, 0x00, 0x0a, 0, 0, 0 }, /* Synth Bass 2 */ +- { 0x31, 0x21, 0x15, 0x09, 0xdd, 0x56, 0x13, 0x26, 0x01, 0x00, 0x08, 0, 0, 0 }, /* Violin */ +- { 0x31, 0x21, 0x16, 0x09, 0xdd, 0x66, 0x13, 0x06, 0x01, 0x00, 0x08, 0, 0, 0 }, /* Viola */ +- { 0x71, 0x31, 0x49, 0x09, 0xd1, 0x61, 0x1c, 0x0c, 0x01, 0x00, 0x08, 0, 0, 0 }, /* Cello */ +- { 0x21, 0x23, 0x4d, 0x89, 0x71, 0x72, 0x12, 0x06, 0x01, 0x00, 0x02, 0, 0, 0 }, /* Contrabass */ +- { 0xf1, 0xe1, 0x40, 0x09, 0xf1, 0x6f, 0x21, 0x16, 0x01, 0x00, 0x02, 0, 0, 0 }, /* Tremolo Strings */ +- { 0x02, 0x01, 0x1a, 0x89, 0xf5, 0x85, 0x75, 0x35, 0x01, 0x00, 0x00, 0, 0, 0 }, /* Pizzicato Strings */ +- { 0x02, 0x01, 0x1d, 0x89, 0xf5, 0xf3, 0x75, 0xf4, 0x01, 0x00, 0x00, 0, 0, 0 }, /* Orchestral Strings */ +- { 0x10, 0x11, 0x41, 0x09, 0xf5, 0xf2, 0x05, 0xc3, 0x01, 0x00, 0x02, 0, 0, 0 }, /* Timpani */ +- { 0x21, 0xa2, 0x9b, 0x0a, 0xb1, 0x72, 0x25, 0x08, 0x01, 0x00, 0x0e, 0, 0, 0 }, /* String Ensemble 1 */ +- { 0xa1, 0x21, 0x98, 0x09, 0x7f, 0x3f, 0x03, 0x07, 0x01, 0x01, 0x00, 0, 0, 0 }, /* String Ensemble 2 */ +- { 0xa1, 0x61, 0x93, 0x09, 0xc1, 0x4f, 0x12, 0x05, 0x00, 0x00, 0x0a, 0, 0, 0 }, /* SynthStrings 1 */ +- { 0x21, 0x61, 0x18, 0x09, 0xc1, 0x4f, 0x22, 0x05, 0x00, 0x00, 0x0c, 0, 0, 0 }, /* SynthStrings 2 */ +- { 0x31, 0x72, 0x5b, 0x8c, 0xf4, 0x8a, 0x15, 0x05, 0x00, 0x00, 0x00, 0, 0, 0 }, /* Choir Aahs */ +- { 0xa1, 0x61, 0x90, 0x09, 0x74, 0x71, 0x39, 0x67, 0x00, 0x00, 0x00, 0, 0, 0 }, /* Voice Oohs */ +- { 0x71, 0x72, 0x57, 0x09, 0x54, 0x7a, 0x05, 0x05, 0x00, 0x00, 0x0c, 0, 0, 0 }, /* Synth Voice */ +- { 0x90, 0x41, 0x00, 0x09, 0x54, 0xa5, 0x63, 0x45, 0x00, 0x00, 0x08, 0, 0, 0 }, /* Orchestra Hit */ +- { 0x21, 0x21, 0x92, 0x0a, 0x85, 0x8f, 0x17, 0x09, 0x00, 0x00, 0x0c, 0, 0, 0 }, /* Trumpet */ +- { 0x21, 0x21, 0x94, 0x0e, 0x75, 0x8f, 0x17, 0x09, 0x00, 0x00, 0x0c, 0, 0, 0 }, /* Trombone */ +- { 0x21, 0x61, 0x94, 0x09, 0x76, 0x82, 0x15, 0x37, 0x00, 0x00, 0x0c, 0, 0, 0 }, /* Tuba */ +- { 0x31, 0x21, 0x43, 0x09, 0x9e, 0x62, 0x17, 0x2c, 0x01, 0x01, 0x02, 0, 0, 0 }, /* Muted Trumpet */ +- { 0x21, 0x21, 0x9b, 0x09, 0x61, 0x7f, 0x6a, 0x0a, 0x00, 0x00, 0x02, 0, 0, 0 }, /* French Horn */ +- { 0x61, 0x22, 0x8a, 0x0f, 0x75, 0x74, 0x1f, 0x0f, 0x00, 0x00, 0x08, 0, 0, 0 }, /* Brass Section */ +- { 0xa1, 0x21, 0x86, 0x8c, 0x72, 0x71, 0x55, 0x18, 0x01, 0x00, 0x00, 0, 0, 0 }, /* SynthBrass 1 */ +- { 0x21, 0x21, 0x4d, 0x09, 0x54, 0xa6, 0x3c, 0x1c, 0x00, 0x00, 0x08, 0, 0, 0 }, /* SynthBrass 2 */ +- { 0x31, 0x61, 0x8f, 0x09, 0x93, 0x72, 0x02, 0x0b, 0x01, 0x00, 0x08, 0, 0, 0 }, /* Soprano Sax */ +- { 0x31, 0x61, 0x8e, 0x09, 0x93, 0x72, 0x03, 0x09, 0x01, 0x00, 0x08, 0, 0, 0 }, /* Alto Sax */ +- { 0x31, 0x61, 0x91, 0x09, 0x93, 0x82, 0x03, 0x09, 0x01, 0x00, 0x0a, 0, 0, 0 }, /* Tenor Sax */ +- { 0x31, 0x61, 0x8e, 0x09, 0x93, 0x72, 0x0f, 0x0f, 0x01, 0x00, 0x0a, 0, 0, 0 }, /* Baritone Sax */ +- { 0x21, 0x21, 0x4b, 0x09, 0xaa, 0x8f, 0x16, 0x0a, 0x01, 0x00, 0x08, 0, 0, 0 }, /* Oboe */ +- { 0x31, 0x21, 0x90, 0x09, 0x7e, 0x8b, 0x17, 0x0c, 0x01, 0x01, 0x06, 0, 0, 0 }, /* English Horn */ +- { 0x31, 0x32, 0x81, 0x09, 0x75, 0x61, 0x19, 0x19, 0x01, 0x00, 0x00, 0, 0, 0 }, /* Bassoon */ +- { 0x32, 0x21, 0x90, 0x09, 0x9b, 0x72, 0x21, 0x17, 0x00, 0x00, 0x04, 0, 0, 0 }, /* Clarinet */ +- { 0xe1, 0xe1, 0x1f, 0x09, 0x85, 0x65, 0x5f, 0x1a, 0x00, 0x00, 0x00, 0, 0, 0 }, /* Piccolo */ +- { 0xe1, 0xe1, 0x46, 0x09, 0x88, 0x65, 0x5f, 0x1a, 0x00, 0x00, 0x00, 0, 0, 0 }, /* Flute */ +- { 0xa1, 0x21, 0x9c, 0x09, 0x75, 0x75, 0x1f, 0x0a, 0x00, 0x00, 0x02, 0, 0, 0 }, /* Recorder */ +- { 0x31, 0x21, 0x8b, 0x09, 0x84, 0x65, 0x58, 0x1a, 0x00, 0x00, 0x00, 0, 0, 0 }, /* Pan Flute */ +- { 0xe1, 0xa1, 0x4c, 0x09, 0x66, 0x65, 0x56, 0x26, 0x00, 0x00, 0x00, 0, 0, 0 }, /* Blown Bottle */ +- { 0x62, 0xa1, 0xcb, 0x09, 0x76, 0x55, 0x46, 0x36, 0x00, 0x00, 0x00, 0, 0, 0 }, /* Skakuhachi */ +- { 0x62, 0xa1, 0xa2, 0x09, 0x57, 0x56, 0x07, 0x07, 0x00, 0x00, 0x0b, 0, 0, 0 }, /* Whistle */ +- { 0x62, 0xa1, 0x9c, 0x09, 0x77, 0x76, 0x07, 0x07, 0x00, 0x00, 0x0b, 0, 0, 0 }, /* Ocarina */ +- { 0x22, 0x21, 0x59, 0x09, 0xff, 0xff, 0x03, 0x0f, 0x02, 0x00, 0x00, 0, 0, 0 }, /* Lead 1 (square) */ +- { 0x21, 0x21, 0x0e, 0x09, 0xff, 0xff, 0x0f, 0x0f, 0x01, 0x01, 0x00, 0, 0, 0 }, /* Lead 2 (sawtooth) */ +- { 0x22, 0x21, 0x46, 0x89, 0x86, 0x64, 0x55, 0x18, 0x00, 0x00, 0x00, 0, 0, 0 }, /* Lead 3 (calliope) */ +- { 0x21, 0xa1, 0x45, 0x09, 0x66, 0x96, 0x12, 0x0a, 0x00, 0x00, 0x00, 0, 0, 0 }, /* Lead 4 (chiff) */ +- { 0x21, 0x22, 0x8b, 0x09, 0x92, 0x91, 0x2a, 0x2a, 0x01, 0x00, 0x00, 0, 0, 0 }, /* Lead 5 (charang) */ +- { 0xa2, 0x61, 0x9e, 0x49, 0xdf, 0x6f, 0x05, 0x07, 0x00, 0x00, 0x02, 0, 0, 0 }, /* Lead 6 (voice) */ +- { 0x20, 0x60, 0x1a, 0x09, 0xef, 0x8f, 0x01, 0x06, 0x00, 0x02, 0x00, 0, 0, 0 }, /* Lead 7 (fifths) */ +- { 0x21, 0x21, 0x8f, 0x86, 0xf1, 0xf4, 0x29, 0x09, 0x00, 0x00, 0x0a, 0, 0, 0 }, /* Lead 8 (bass+lead) */ +- { 0x77, 0xa1, 0xa5, 0x09, 0x53, 0xa0, 0x94, 0x05, 0x00, 0x00, 0x02, 0, 0, 0 }, /* Pad 1 (new age) */ +- { 0x61, 0xb1, 0x1f, 0x89, 0xa8, 0x25, 0x11, 0x03, 0x00, 0x00, 0x0a, 0, 0, 0 }, /* Pad 2 (warm) */ +- { 0x61, 0x61, 0x17, 0x09, 0x91, 0x55, 0x34, 0x16, 0x00, 0x00, 0x0c, 0, 0, 0 }, /* Pad 3 (polysynth) */ +- { 0x71, 0x72, 0x5d, 0x09, 0x54, 0x6a, 0x01, 0x03, 0x00, 0x00, 0x00, 0, 0, 0 }, /* Pad 4 (choir) */ +- { 0x21, 0xa2, 0x97, 0x09, 0x21, 0x42, 0x43, 0x35, 0x00, 0x00, 0x08, 0, 0, 0 }, /* Pad 5 (bowed) */ +- { 0xa1, 0x21, 0x1c, 0x09, 0xa1, 0x31, 0x77, 0x47, 0x01, 0x01, 0x00, 0, 0, 0 }, /* Pad 6 (metallic) */ +- { 0x21, 0x61, 0x89, 0x0c, 0x11, 0x42, 0x33, 0x25, 0x00, 0x00, 0x0a, 0, 0, 0 }, /* Pad 7 (halo) */ +- { 0xa1, 0x21, 0x15, 0x09, 0x11, 0xcf, 0x47, 0x07, 0x01, 0x00, 0x00, 0, 0, 0 }, /* Pad 8 (sweep) */ +- { 0x3a, 0x51, 0xce, 0x09, 0xf8, 0x86, 0xf6, 0x02, 0x00, 0x00, 0x02, 0, 0, 0 }, /* FX 1 (rain) */ +- { 0x21, 0x21, 0x15, 0x09, 0x21, 0x41, 0x23, 0x13, 0x01, 0x00, 0x00, 0, 0, 0 }, /* FX 2 (soundtrack) */ +- { 0x06, 0x01, 0x5b, 0x09, 0x74, 0xa5, 0x95, 0x72, 0x00, 0x00, 0x00, 0, 0, 0 }, /* FX 3 (crystal) */ +- { 0x22, 0x61, 0x92, 0x8c, 0xb1, 0xf2, 0x81, 0x26, 0x00, 0x00, 0x0c, 0, 0, 0 }, /* FX 4 (atmosphere) */ +- { 0x41, 0x42, 0x4d, 0x09, 0xf1, 0xf2, 0x51, 0xf5, 0x01, 0x00, 0x00, 0, 0, 0 }, /* FX 5 (brightness) */ +- { 0x61, 0xa3, 0x94, 0x89, 0x11, 0x11, 0x51, 0x13, 0x01, 0x00, 0x06, 0, 0, 0 }, /* FX 6 (goblins) */ +- { 0x61, 0xa1, 0x8c, 0x89, 0x11, 0x1d, 0x31, 0x03, 0x00, 0x00, 0x06, 0, 0, 0 }, /* FX 7 (echoes) */ +- { 0xa4, 0x61, 0x4c, 0x09, 0xf3, 0x81, 0x73, 0x23, 0x01, 0x00, 0x04, 0, 0, 0 }, /* FX 8 (sci-fi) */ +- { 0x02, 0x07, 0x85, 0x0c, 0xd2, 0xf2, 0x53, 0xf6, 0x00, 0x01, 0x00, 0, 0, 0 }, /* Sitar */ +- { 0x11, 0x13, 0x0c, 0x89, 0xa3, 0xa2, 0x11, 0xe5, 0x01, 0x00, 0x00, 0, 0, 0 }, /* Banjo */ +- { 0x11, 0x11, 0x06, 0x09, 0xf6, 0xf2, 0x41, 0xe6, 0x01, 0x02, 0x04, 0, 0, 0 }, /* Shamisen */ +- { 0x93, 0x91, 0x91, 0x09, 0xd4, 0xeb, 0x32, 0x11, 0x00, 0x01, 0x08, 0, 0, 0 }, /* Koto */ +- { 0x04, 0x01, 0x4f, 0x09, 0xfa, 0xc2, 0x56, 0x05, 0x00, 0x00, 0x0c, 0, 0, 0 }, /* Kalimba */ +- { 0x21, 0x22, 0x49, 0x09, 0x7c, 0x6f, 0x20, 0x0c, 0x00, 0x01, 0x06, 0, 0, 0 }, /* Bagpipe */ +- { 0x31, 0x21, 0x85, 0x09, 0xdd, 0x56, 0x33, 0x16, 0x01, 0x00, 0x0a, 0, 0, 0 }, /* Fiddle */ +- { 0x20, 0x21, 0x04, 0x8a, 0xda, 0x8f, 0x05, 0x0b, 0x02, 0x00, 0x06, 0, 0, 0 }, /* Shanai */ +- { 0x05, 0x03, 0x6a, 0x89, 0xf1, 0xc3, 0xe5, 0xe5, 0x00, 0x00, 0x06, 0, 0, 0 }, /* Tinkle Bell */ +- { 0x07, 0x02, 0x15, 0x09, 0xec, 0xf8, 0x26, 0x16, 0x00, 0x00, 0x0a, 0, 0, 0 }, /* Agogo */ +- { 0x05, 0x01, 0x9d, 0x09, 0x67, 0xdf, 0x35, 0x05, 0x00, 0x00, 0x08, 0, 0, 0 }, /* Steel Drums */ +- { 0x18, 0x12, 0x96, 0x09, 0xfa, 0xf8, 0x28, 0xe5, 0x00, 0x00, 0x0a, 0, 0, 0 }, /* Woodblock */ +- { 0x10, 0x00, 0x86, 0x0c, 0xa8, 0xfa, 0x07, 0x03, 0x00, 0x00, 0x06, 0, 0, 0 }, /* Taiko Drum */ +- { 0x11, 0x10, 0x41, 0x0c, 0xf8, 0xf3, 0x47, 0x03, 0x02, 0x00, 0x04, 0, 0, 0 }, /* Melodic Tom */ +- { 0x01, 0x10, 0x8e, 0x09, 0xf1, 0xf3, 0x06, 0x02, 0x02, 0x00, 0x0e, 0, 0, 0 }, /* Synth Drum */ +- { 0x0e, 0xc0, 0x00, 0x09, 0x1f, 0x1f, 0x00, 0xff, 0x00, 0x03, 0x0e, 0, 0, 0 }, /* Reverse Cymbal */ +- { 0x06, 0x03, 0x80, 0x91, 0xf8, 0x56, 0x24, 0x84, 0x00, 0x02, 0x0e, 0, 0, 0 }, /* Guitar Fret Noise */ +- { 0x0e, 0xd0, 0x00, 0x0e, 0xf8, 0x34, 0x00, 0x04, 0x00, 0x03, 0x0e, 0, 0, 0 }, /* Breath Noise */ +- { 0x0e, 0xc0, 0x00, 0x09, 0xf6, 0x1f, 0x00, 0x02, 0x00, 0x03, 0x0e, 0, 0, 0 }, /* Seashore */ +- { 0xd5, 0xda, 0x95, 0x49, 0x37, 0x56, 0xa3, 0x37, 0x00, 0x00, 0x00, 0, 0, 0 }, /* Bird Tweet */ +- { 0x35, 0x14, 0x5c, 0x11, 0xb2, 0xf4, 0x61, 0x15, 0x02, 0x00, 0x0a, 0, 0, 0 }, /* Telephone ring */ +- { 0x0e, 0xd0, 0x00, 0x09, 0xf6, 0x4f, 0x00, 0xf5, 0x00, 0x03, 0x0e, 0, 0, 0 }, /* Helicopter */ +- { 0x26, 0xe4, 0x00, 0x09, 0xff, 0x12, 0x01, 0x16, 0x00, 0x01, 0x0e, 0, 0, 0 }, /* Applause */ +- { 0x00, 0x00, 0x00, 0x09, 0xf3, 0xf6, 0xf0, 0xc9, 0x00, 0x02, 0x0e, 0, 0, 0 } /* Gunshot */ +- +-}; +- +-/* logarithmic relationship between midi and FM volumes */ +-static int my_midi_fm_vol_table[128] = { +- 0, 11, 16, 19, 22, 25, 27, 29, 32, 33, 35, 37, 39, 40, 42, 43, +- 45, 46, 48, 49, 50, 51, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, +- 64, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 75, 76, 77, +- 78, 79, 80, 80, 81, 82, 83, 83, 84, 85, 86, 86, 87, 88, 89, 89, +- 90, 91, 91, 92, 93, 93, 94, 95, 96, 96, 97, 97, 98, 99, 99, 100, +- 101, 101, 102, 103, 103, 104, 104, 105, 106, 106, 107, 107, 108, +- 109, 109, 110, 110, 111, 112, 112, 113, 113, 114, 114, 115, 115, +- 116, 117, 117, 118, 118, 119, 119, 120, 120, 121, 121, 122, 122, +- 123, 123, 124, 124, 125, 125, 126, 126, 127 +-}; +- +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/mkj.cc audacious-plugins-3.9/src/adplug/core/mkj.cc +--- audacious-plugins-3.9-orig/src/adplug/core/mkj.cc 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/mkj.cc 1970-01-01 01:00:00.000000000 +0100 +@@ -1,164 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2004 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * mkj.cpp - MKJamz Player, by Simon Peter +- */ +- +-#include +-#include +- +-#include "mkj.h" +-#include "debug.h" +- +-CPlayer *CmkjPlayer::factory(Copl *newopl) +-{ +- return new CmkjPlayer(newopl); +-} +- +-bool CmkjPlayer::load(const std::string &filename, const CFileProvider &fp) +-{ +- binistream *f = fp.open(filename); if(!f) return false; +- char id[6]; +- float ver; +- int i, j; +- short inst[8]; +- +- // file validation +- f->readString(id, 6); +- if(strncmp(id,"MKJamz",6)) { fp.close(f); return false; } +- ver = f->readFloat(binio::Single); +- if(ver > 1.12) { fp.close(f); return false; } +- +- // load +- maxchannel = f->readInt(2); +- opl->init(); opl->write(1, 32); +- for(i = 0; i < maxchannel; i++) { +- for(j = 0; j < 8; j++) inst[j] = f->readInt(2); +- opl->write(0x20+op_table[i],inst[4]); +- opl->write(0x23+op_table[i],inst[0]); +- opl->write(0x40+op_table[i],inst[5]); +- opl->write(0x43+op_table[i],inst[1]); +- opl->write(0x60+op_table[i],inst[6]); +- opl->write(0x63+op_table[i],inst[2]); +- opl->write(0x80+op_table[i],inst[7]); +- opl->write(0x83+op_table[i],inst[3]); +- } +- maxnotes = f->readInt(2); +- songbuf = new short [(maxchannel+1)*maxnotes]; +- for(i = 0; i < maxchannel; i++) channel[i].defined = f->readInt(2); +- for(i = 0; i < (maxchannel + 1) * maxnotes; i++) +- songbuf[i] = f->readInt(2); +- +- AdPlug_LogWrite("CmkjPlayer::load(\"%s\"): loaded file ver %.2f, %d channels," +- " %d notes/channel.\n", filename.c_str(), ver, maxchannel, +- maxnotes); +- fp.close(f); +- rewind(0); +- return true; +-} +- +-bool CmkjPlayer::update() +-{ +- int c, i; +- short note; +- +- for(c = 0; c < maxchannel; c++) { +- if(!channel[c].defined) // skip if channel is disabled +- continue; +- +- if(channel[c].pstat) { +- channel[c].pstat--; +- continue; +- } +- +- opl->write(0xb0 + c, 0); // key off +- do { +- assert(channel[c].songptr < (maxchannel + 1) * maxnotes); +- note = songbuf[channel[c].songptr]; +- if(channel[c].songptr - c > maxchannel) +- if(note && note < 250) +- channel[c].pstat = channel[c].speed; +- switch(note) { +- // normal notes +- case 68: opl->write(0xa0 + c,0x81); opl->write(0xb0 + c,0x21 + 4 * channel[c].octave); break; +- case 69: opl->write(0xa0 + c,0xb0); opl->write(0xb0 + c,0x21 + 4 * channel[c].octave); break; +- case 70: opl->write(0xa0 + c,0xca); opl->write(0xb0 + c,0x21 + 4 * channel[c].octave); break; +- case 71: opl->write(0xa0 + c,0x2); opl->write(0xb0 + c,0x22 + 4 * channel[c].octave); break; +- case 65: opl->write(0xa0 + c,0x41); opl->write(0xb0 + c,0x22 + 4 * channel[c].octave); break; +- case 66: opl->write(0xa0 + c,0x87); opl->write(0xb0 + c,0x22 + 4 * channel[c].octave); break; +- case 67: opl->write(0xa0 + c,0xae); opl->write(0xb0 + c,0x22 + 4 * channel[c].octave); break; +- case 17: opl->write(0xa0 + c,0x6b); opl->write(0xb0 + c,0x21 + 4 * channel[c].octave); break; +- case 18: opl->write(0xa0 + c,0x98); opl->write(0xb0 + c,0x21 + 4 * channel[c].octave); break; +- case 20: opl->write(0xa0 + c,0xe5); opl->write(0xb0 + c,0x21 + 4 * channel[c].octave); break; +- case 21: opl->write(0xa0 + c,0x20); opl->write(0xb0 + c,0x22 + 4 * channel[c].octave); break; +- case 15: opl->write(0xa0 + c,0x63); opl->write(0xb0 + c,0x22 + 4 * channel[c].octave); break; +- case 255: // delay +- channel[c].songptr += maxchannel; +- channel[c].pstat = songbuf[channel[c].songptr]; +- break; +- case 254: // set octave +- channel[c].songptr += maxchannel; +- channel[c].octave = songbuf[channel[c].songptr]; +- break; +- case 253: // set speed +- channel[c].songptr += maxchannel; +- channel[c].speed = songbuf[channel[c].songptr]; +- break; +- case 252: // set waveform +- channel[c].songptr += maxchannel; +- channel[c].waveform = songbuf[channel[c].songptr] - 300; +- if(c > 2) +- opl->write(0xe0 + c + (c+6),channel[c].waveform); +- else +- opl->write(0xe0 + c,channel[c].waveform); +- break; +- case 251: // song end +- for(i = 0; i < maxchannel; i++) channel[i].songptr = i; +- songend = true; +- return false; +- } +- +- if(channel[c].songptr - c < maxnotes) +- channel[c].songptr += maxchannel; +- else +- channel[c].songptr = c; +- } while(!channel[c].pstat); +- } +- +- return !songend; +-} +- +-void CmkjPlayer::rewind(int subsong) +-{ +- int i; +- +- for(i = 0; i < maxchannel; i++) { +- channel[i].pstat = 0; +- channel[i].speed = 0; +- channel[i].waveform = 0; +- channel[i].songptr = i; +- channel[i].octave = 4; +- } +- +- songend = false; +-} +- +-float CmkjPlayer::getrefresh() +-{ +- return 100.0f; +-} +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/mkj.h audacious-plugins-3.9/src/adplug/core/mkj.h +--- audacious-plugins-3.9-orig/src/adplug/core/mkj.h 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/mkj.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,50 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2003 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * mkj.h - MKJamz Player, by Simon Peter +- */ +- +-#include "player.h" +- +-class CmkjPlayer: public CPlayer +-{ +-public: +- static CPlayer *factory(Copl *newopl); +- +- CmkjPlayer(Copl *newopl) +- : CPlayer(newopl), songbuf(0) +- { } +- ~CmkjPlayer() +- { if(songbuf) delete [] songbuf; } +- +- bool load(const std::string &filename, const CFileProvider &fp); +- bool update(); +- void rewind(int subsong); +- float getrefresh(); +- +- std::string gettype() +- { return std::string("MKJamz Audio File"); } +- +-private: +- short maxchannel,maxnotes,*songbuf; +- bool songend; +- +- struct { +- short defined,songptr,octave,waveform,pstat,speed,delay; +- } channel[9]; +-}; +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/msc.cc audacious-plugins-3.9/src/adplug/core/msc.cc +--- audacious-plugins-3.9-orig/src/adplug/core/msc.cc 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/msc.cc 1970-01-01 01:00:00.000000000 +0100 +@@ -1,313 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2006 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * msc.c - MSC Player by Lubomir Bulej (pallas@kadan.cz) +- */ +- +-#include +-#include +- +-#include "msc.h" +-#include "debug.h" +- +-const unsigned char CmscPlayer::msc_signature [MSC_SIGN_LEN] = { +- 'C', 'e', 'r', 'e', 's', ' ', '\x13', ' ', +- 'M', 'S', 'C', 'p', 'l', 'a', 'y', ' ' }; +- +-/*** public methods *************************************/ +- +-CPlayer *CmscPlayer::factory (Copl * newopl) +-{ +- return new CmscPlayer (newopl); +-} +- +-CmscPlayer::CmscPlayer(Copl * newopl) : CPlayer (newopl) +-{ +- desc = NULL; +- msc_data = NULL; +- raw_data = NULL; +- nr_blocks = 0; +-} +- +-CmscPlayer::~CmscPlayer() +-{ +- if (raw_data != NULL) +- delete [] raw_data; +- +- if (msc_data != NULL) { +- // free compressed blocks +- for (int blk_num = 0; blk_num < nr_blocks; blk_num++) { +- if (msc_data [blk_num].mb_data != NULL) +- delete [] msc_data [blk_num].mb_data; +- } +- +- delete [] msc_data; +- } +- +- if (desc != NULL) +- delete [] desc; +-} +- +-bool CmscPlayer::load(const std::string & filename, const CFileProvider & fp) +-{ +- binistream * bf; +- msc_header hdr; +- +- // open and validate the file +- bf = fp.open (filename); +- if (! bf) +- return false; +- +- if (! load_header (bf, & hdr)) { +- fp.close (bf); +- return false; +- } +- +- // get stuff from the header +- version = hdr.mh_ver; +- timer_div = hdr.mh_timer; +- nr_blocks = hdr.mh_nr_blocks; +- block_len = hdr.mh_block_len; +- +- if (! nr_blocks) { +- fp.close (bf); +- return false; +- } +- +- // load compressed data blocks +- msc_data = new msc_block [nr_blocks]; +- raw_data = new u8 [block_len]; +- +- for (int blk_num = 0; blk_num < nr_blocks; blk_num++) { +- msc_block blk; +- +- blk.mb_length = bf->readInt (2); +- blk.mb_data = new u8 [blk.mb_length]; +- for (int oct_num = 0; oct_num < blk.mb_length; oct_num++) { +- blk.mb_data [oct_num] = bf->readInt (1); +- } +- +- msc_data [blk_num] = blk; +- } +- +- // clean up & initialize +- fp.close (bf); +- rewind (0); +- +- return true; +-} +- +-bool CmscPlayer::update() +-{ +- // output data +- while (! delay) { +- u8 cmnd; +- u8 data; +- +- // decode data +- if (! decode_octet (& cmnd)) +- return false; +- +- if (! decode_octet (& data)) +- return false; +- +- // check for special commands +- switch (cmnd) { +- +- // delay +- case 0xff: +- delay = 1 + (u8) (data - 1); +- break; +- +- // play command & data +- default: +- opl->write (cmnd, data); +- +- } // command switch +- } // play pass +- +- +- // count delays +- if (delay) +- delay--; +- +- // advance player position +- play_pos++; +- return true; +-} +- +-void CmscPlayer::rewind(int subsong) +-{ +- // reset state +- dec_prefix = 0; +- block_num = 0; +- block_pos = 0; +- play_pos = 0; +- raw_pos = 0; +- delay = 0; +- +- // init the OPL chip and go to OPL2 mode +- opl->init(); +- opl->write(1, 32); +-} +- +-float CmscPlayer::getrefresh() +-{ +- // PC timer oscillator frequency / wait register +- return 1193180 / (float) (timer_div ? timer_div : 0xffff); +-} +- +-std::string CmscPlayer::gettype() +-{ +- char vstr [40]; +- +- sprintf(vstr, "AdLib MSCplay (version %d)", version); +- return std::string (vstr); +-} +- +-/*** private methods *************************************/ +- +-bool CmscPlayer::load_header(binistream * bf, msc_header * hdr) +-{ +- // check signature +- bf->readString ((char *) hdr->mh_sign, sizeof (hdr->mh_sign)); +- if (memcmp (msc_signature, hdr->mh_sign, MSC_SIGN_LEN) != 0) +- return false; +- +- // check version +- hdr->mh_ver = bf->readInt (2); +- if (hdr->mh_ver != 0) +- return false; +- +- bf->readString ((char *) hdr->mh_desc, sizeof (hdr->mh_desc)); +- hdr->mh_timer = bf->readInt (2); +- hdr->mh_nr_blocks = bf->readInt (2); +- hdr->mh_block_len = bf->readInt (2); +- return true; +-} +- +-bool CmscPlayer::decode_octet(u8 * output) +-{ +- msc_block blk; // compressed data block +- +- if (block_num >= nr_blocks) +- return false; +- +- blk = msc_data [block_num]; +- while (1) { +- u8 octet; // decoded octet +- u8 len_corr = 0; // length correction +- +- // advance to next block if necessary +- if (block_pos >= blk.mb_length && dec_len == 0) { +- block_num++; +- if (block_num >= nr_blocks) +- return false; +- +- blk = msc_data [block_num]; +- block_pos = 0; +- raw_pos = 0; +- } +- +- // decode the compressed music data +- switch (dec_prefix) { +- +- // decode prefix +- case 155: +- case 175: +- octet = blk.mb_data [block_pos++]; +- if (octet == 0) { +- // invalid prefix, output original +- octet = dec_prefix; +- dec_prefix = 0; +- break; +- } +- +- // isolate length and distance +- dec_len = (octet & 0x0F); +- len_corr = 2; +- +- dec_dist = (octet & 0xF0) >> 4; +- if (dec_prefix == 155) +- dec_dist++; +- +- // next decode step for respective prefix type +- dec_prefix++; +- continue; +- +- +- // check for extended length +- case 156: +- if (dec_len == 15) +- dec_len += blk.mb_data [block_pos++]; +- +- // add length correction and go for copy mode +- dec_len += len_corr; +- dec_prefix = 255; +- continue; +- +- +- // get extended distance +- case 176: +- dec_dist += 17 + 16 * blk.mb_data [block_pos++]; +- len_corr = 3; +- +- // check for extended length +- dec_prefix = 156; +- continue; +- +- +- // prefix copy mode +- case 255: +- if((int)raw_pos >= dec_dist) +- octet = raw_data [raw_pos - dec_dist]; +- else { +- AdPlug_LogWrite("error! read before raw_data buffer.\n"); +- octet = 0; +- } +- +- dec_len--; +- if (dec_len == 0) { +- // back to normal mode +- dec_prefix = 0; +- } +- +- break; +- +- +- // normal mode +- default: +- octet = blk.mb_data [block_pos++]; +- if (octet == 155 || octet == 175) { +- // it's a prefix, restart +- dec_prefix = octet; +- continue; +- } +- } // prefix switch +- +- +- // output the octet +- if (output != NULL) +- *output = octet; +- +- raw_data [raw_pos++] = octet; +- break; +- }; // decode pass +- +- return true; +-} +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/msc.h audacious-plugins-3.9/src/adplug/core/msc.h +--- audacious-plugins-3.9-orig/src/adplug/core/msc.h 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/msc.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,87 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2006 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * msc.h - MSC Player by Lubomir Bulej (pallas@kadan.cz) +- */ +- +-#include "player.h" +- +-#define MSC_SIGN_LEN 16 +-#define MSC_DESC_LEN 64 +- +-class CmscPlayer: public CPlayer +-{ +- public: +- static CPlayer * factory(Copl * newopl); +- +- CmscPlayer(Copl * newopl); +- ~CmscPlayer(); +- +- bool load(const std::string &filename, const CFileProvider &fp); +- bool update(); +- void rewind(int subsong); +- float getrefresh(); +- +- std::string gettype (); +- +- protected: +- typedef unsigned char u8; +- typedef unsigned short u16; +- +- struct msc_header { +- u8 mh_sign [MSC_SIGN_LEN]; +- u16 mh_ver; +- u8 mh_desc [MSC_DESC_LEN]; +- u16 mh_timer; +- u16 mh_nr_blocks; +- u16 mh_block_len; +- }; +- +- struct msc_block { +- u16 mb_length; +- u8 * mb_data; +- }; +- +- // file data +- char * desc; // song desctiption +- unsigned short version; // file version +- unsigned short nr_blocks; // number of music blocks +- unsigned short block_len; // maximal block length +- unsigned short timer_div; // timer divisor +- msc_block * msc_data; // compressed music data +- +- // decoder state +- unsigned long block_num; // active block +- unsigned long block_pos; // position in block +- unsigned long raw_pos; // position in data buffer +- u8 * raw_data; // decompression buffer +- +- u8 dec_prefix; // prefix / state +- int dec_dist; // prefix distance +- unsigned int dec_len; // prefix length +- +- // player state +- unsigned char delay; // active delay +- unsigned long play_pos; // player position +- +- private: +- static const u8 msc_signature [MSC_SIGN_LEN]; +- +- bool load_header (binistream * bf, msc_header * hdr); +- bool decode_octet (u8 * output); +-}; +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/mtk.cc audacious-plugins-3.9/src/adplug/core/mtk.cc +--- audacious-plugins-3.9-orig/src/adplug/core/mtk.cc 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/mtk.cc 1970-01-01 01:00:00.000000000 +0100 +@@ -1,141 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2006 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * mtk.cpp - MPU-401 Trakker Loader by Simon Peter (dn.tlp@gmx.net) +- */ +- +-#include +-#include "mtk.h" +- +-/*** public methods **************************************/ +- +-CPlayer *CmtkLoader::factory(Copl *newopl) +-{ +- return new CmtkLoader(newopl); +-} +- +-bool CmtkLoader::load(const std::string &filename, const CFileProvider &fp) +-{ +- binistream *f = fp.open(filename); if(!f) return false; +- struct { +- char id[18]; +- unsigned short crc,size; +- } header; +- struct mtkdata { +- char songname[34],composername[34],instname[0x80][34]; +- unsigned char insts[0x80][12],order[0x80],dummy,patterns[0x32][0x40][9]; +- } *data; +- unsigned char *cmp,*org; +- unsigned int i; +- unsigned long cmpsize,cmpptr=0,orgptr=0; +- unsigned short ctrlbits=0,ctrlmask=0,cmd,cnt,offs; +- +- // read header +- f->readString(header.id, 18); +- header.crc = f->readInt(2); +- header.size = f->readInt(2); +- +- // file validation section +- if(strncmp(header.id,"mpu401tr\x92kk\xeer@data",18)) +- { fp.close(f); return false; } +- +- // load section +- cmpsize = fp.filesize(f) - 22; +- cmp = new unsigned char[cmpsize]; +- org = new unsigned char[header.size]; +- for(i = 0; i < cmpsize; i++) cmp[i] = f->readInt(1); +- fp.close(f); +- +- while(cmpptr < cmpsize) { // decompress +- ctrlmask >>= 1; +- if(!ctrlmask) { +- ctrlbits = cmp[cmpptr] + (cmp[cmpptr + 1] << 8); +- cmpptr += 2; +- ctrlmask = 0x8000; +- } +- if(!(ctrlbits & ctrlmask)) { // uncompressed data +- if(orgptr >= header.size) +- goto err; +- +- org[orgptr] = cmp[cmpptr]; +- orgptr++; cmpptr++; +- continue; +- } +- +- // compressed data +- cmd = (cmp[cmpptr] >> 4) & 0x0f; +- cnt = cmp[cmpptr] & 0x0f; +- cmpptr++; +- switch(cmd) { +- case 0: +- if(orgptr + cnt > header.size) goto err; +- cnt += 3; +- memset(&org[orgptr],cmp[cmpptr],cnt); +- cmpptr++; orgptr += cnt; +- break; +- +- case 1: +- if(orgptr + cnt > header.size) goto err; +- cnt += (cmp[cmpptr] << 4) + 19; +- memset(&org[orgptr],cmp[++cmpptr],cnt); +- cmpptr++; orgptr += cnt; +- break; +- +- case 2: +- if(orgptr + cnt > header.size) goto err; +- offs = (cnt+3) + (cmp[cmpptr] << 4); +- cnt = cmp[++cmpptr] + 16; cmpptr++; +- memcpy(&org[orgptr],&org[orgptr - offs],cnt); +- orgptr += cnt; +- break; +- +- default: +- if(orgptr + cmd > header.size) goto err; +- offs = (cnt+3) + (cmp[cmpptr++] << 4); +- memcpy(&org[orgptr],&org[orgptr-offs],cmd); +- orgptr += cmd; +- break; +- } +- } +- delete [] cmp; +- data = (struct mtkdata *) org; +- +- // convert to HSC replay data +- memset(title,0,34); strncpy(title,data->songname+1,33); +- memset(composer,0,34); strncpy(composer,data->composername+1,33); +- memset(instname,0,0x80*34); +- for(i=0;i<0x80;i++) +- strncpy(instname[i],data->instname[i]+1,33); +- memcpy(instr,data->insts,0x80 * 12); +- memcpy(song,data->order,0x80); +- memcpy(patterns,data->patterns,header.size-6084); +- for (i=0;i<128;i++) { // correct instruments +- instr[i][2] ^= (instr[i][2] & 0x40) << 1; +- instr[i][3] ^= (instr[i][3] & 0x40) << 1; +- instr[i][11] >>= 4; // make unsigned +- } +- +- delete [] org; +- rewind(0); +- return true; +- +- err: +- delete [] cmp; +- delete [] org; +- return false; +-} +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/mtk.h audacious-plugins-3.9/src/adplug/core/mtk.h +--- audacious-plugins-3.9-orig/src/adplug/core/mtk.h 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/mtk.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,50 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2006 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * mtk.h - MPU-401 Trakker Loader by Simon Peter +- */ +- +-#include "hsc.h" +- +-class CmtkLoader: public ChscPlayer +-{ +- public: +- static CPlayer *factory(Copl *newopl); +- +- CmtkLoader(Copl *newopl) +- : ChscPlayer(newopl) +- { +- mtkmode = 1; +- }; +- +- bool load(const std::string &filename, const CFileProvider &fp); +- +- std::string gettype() +- { return std::string("MPU-401 Trakker"); }; +- std::string gettitle() +- { return std::string(title); }; +- std::string getauthor() +- { return std::string(composer); }; +- unsigned int getinstruments() +- { return 128; }; +- std::string getinstrument(unsigned int n) +- { return std::string(instname[n]); }; +- +- private: +- char title[34],composer[34],instname[0x80][34]; +-}; +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/opl.h audacious-plugins-3.9/src/adplug/core/opl.h +--- audacious-plugins-3.9-orig/src/adplug/core/opl.h 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/opl.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,69 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2007 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * opl.h - OPL base class, by Simon Peter +- */ +- +-#ifndef H_ADPLUG_OPL +-#define H_ADPLUG_OPL +- +-class Copl +-{ +- public: +- typedef enum { +- TYPE_OPL2, TYPE_OPL3, TYPE_DUAL_OPL2 +- } ChipType; +- +- Copl() +- : currChip(0), currType(TYPE_OPL2) +- { +- } +- +- virtual ~Copl() +- { +- } +- +- virtual void write(int reg, int val) = 0; // combined register select + data write +- virtual void setchip(int n) // select OPL chip +- { +- if(n < 2) +- currChip = n; +- } +- +- virtual int getchip() // returns current OPL chip +- { +- return currChip; +- } +- +- virtual void init() = 0; // reinitialize OPL chip(s) +- +- // return this OPL chip's type +- ChipType gettype() +- { +- return currType; +- } +- +- // Emulation only: fill buffer +- virtual void update(short *buf, int samples) {} +- +- protected: +- int currChip; // currently selected OPL chip number +- ChipType currType; // this OPL chip's type +-}; +- +-#endif +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/player.cc audacious-plugins-3.9/src/adplug/core/player.cc +--- audacious-plugins-3.9-orig/src/adplug/core/player.cc 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/player.cc 1970-01-01 01:00:00.000000000 +0100 +@@ -1,70 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2007 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * player.cpp - Replayer base class, by Simon Peter +- */ +- +-#include "player.h" +-#include "adplug.h" +-#include "silentopl.h" +- +-/***** CPlayer *****/ +- +-const unsigned short CPlayer::note_table[12] = +- {363, 385, 408, 432, 458, 485, 514, 544, 577, 611, 647, 686}; +- +-const unsigned char CPlayer::op_table[9] = +- {0x00, 0x01, 0x02, 0x08, 0x09, 0x0a, 0x10, 0x11, 0x12}; +- +-CPlayer::CPlayer(Copl *newopl) +- : opl(newopl), db(CAdPlug::database) +-{ +-} +- +-CPlayer::~CPlayer() +-{ +-} +- +-unsigned long CPlayer::songlength(int subsong) +-{ +- CSilentopl tempopl; +- Copl *saveopl = opl; +- float slength = 0.0f; +- +- // save original OPL from being overwritten +- opl = &tempopl; +- +- // get song length +- rewind(subsong); +- while(update() && slength < 600000) // song length limit: 10 minutes +- slength += 1000.0f / getrefresh(); +- rewind(subsong); +- +- // restore original OPL and return +- opl = saveopl; +- return (unsigned long)slength; +-} +- +-void CPlayer::seek(unsigned long ms) +-{ +- float pos = 0.0f; +- +- rewind(); +- while(pos < ms && update()) // seek to new position +- pos += 1000/getrefresh(); +-} +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/player.h audacious-plugins-3.9/src/adplug/core/player.h +--- audacious-plugins-3.9-orig/src/adplug/core/player.h 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/player.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,85 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2007 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * player.h - Replayer base class, by Simon Peter +- */ +- +-#ifndef H_ADPLUG_PLAYER +-#define H_ADPLUG_PLAYER +- +-#include +- +-#include "fprovide.h" +-#include "opl.h" +-#include "database.h" +- +-class CPlayer +-{ +-public: +- CPlayer(Copl *newopl); +- virtual ~CPlayer(); +- +-/***** Operational methods *****/ +- void seek(unsigned long ms); +- +- virtual bool load(const std::string &filename, // loads file +- const CFileProvider &fp) = 0; +- virtual bool update() = 0; // executes replay code for 1 tick +- virtual void rewind(int subsong = -1) = 0; // rewinds to specified subsong +- virtual float getrefresh() = 0; // returns needed timer refresh rate +- +-/***** Informational methods *****/ +- unsigned long songlength(int subsong = -1); +- +- virtual std::string gettype() = 0; // returns file type +- virtual std::string gettitle() // returns song title +- { return std::string(); } +- virtual std::string getauthor() // returns song author name +- { return std::string(); } +- virtual std::string getdesc() // returns song description +- { return std::string(); } +- virtual unsigned int getpatterns() // returns number of patterns +- { return 0; } +- virtual unsigned int getpattern() // returns currently playing pattern +- { return 0; } +- virtual unsigned int getorders() // returns size of orderlist +- { return 0; } +- virtual unsigned int getorder() // returns currently playing song position +- { return 0; } +- virtual unsigned int getrow() // returns currently playing row +- { return 0; } +- virtual unsigned int getspeed() // returns current song speed +- { return 0; } +- virtual unsigned int getsubsongs() // returns number of subsongs +- { return 1; } +- virtual unsigned int getsubsong() // returns current subsong +- { return 0; } +- virtual unsigned int getinstruments() // returns number of instruments +- { return 0; } +- virtual std::string getinstrument(unsigned int n) // returns n-th instrument name +- { return std::string(); } +- +-protected: +- Copl *opl; // our OPL chip +- CAdPlugDatabase *db; // AdPlug Database +- +- static const unsigned short note_table[12]; // standard adlib note table +- static const unsigned char op_table[9]; // the 9 operators as expected by the OPL +-}; +- +-#endif +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/players.cc audacious-plugins-3.9/src/adplug/core/players.cc +--- audacious-plugins-3.9-orig/src/adplug/core/players.cc 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/players.cc 1970-01-01 01:00:00.000000000 +0100 +@@ -1,105 +0,0 @@ +-/* +- * AdPlug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2003 Simon Peter , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * players.h - Players enumeration, by Simon Peter +- */ +- +-#include +-#include +- +-#include "players.h" +- +-/***** CPlayerDesc *****/ +- +-CPlayerDesc::CPlayerDesc() +- : factory(0), extensions(0), extlength(0) +-{ +-} +- +-CPlayerDesc::CPlayerDesc(const CPlayerDesc &pd) +- : factory(pd.factory), filetype(pd.filetype), extlength(pd.extlength) +-{ +- if(pd.extensions) { +- extensions = (char *)malloc(extlength); +- memcpy(extensions, pd.extensions, extlength); +- } else +- extensions = 0; +-} +- +-CPlayerDesc::CPlayerDesc(Factory f, const std::string &type, const char *ext) +- : factory(f), filetype(type), extensions(0) +-{ +- const char *i = ext; +- +- // Determine length of passed extensions list +- while(*i) i += strlen(i) + 1; +- extlength = i - ext + 1; // length = difference between last and first char + 1 +- +- extensions = (char *)malloc(extlength); +- memcpy(extensions, ext, extlength); +-} +- +-CPlayerDesc::~CPlayerDesc() +-{ +- if(extensions) free(extensions); +-} +- +-void CPlayerDesc::add_extension(const char *ext) +-{ +- unsigned long newlength = extlength + strlen(ext) + 1; +- +- extensions = (char *)realloc(extensions, newlength); +- strcpy(extensions + extlength - 1, ext); +- extensions[newlength - 1] = '\0'; +- extlength = newlength; +-} +- +-const char *CPlayerDesc::get_extension(unsigned int n) const +-{ +- const char *i = extensions; +- unsigned int j; +- +- for(j = 0; j < n && (*i); j++, i += strlen(i) + 1) ; +- return (*i != '\0' ? i : 0); +-} +- +-/***** CPlayers *****/ +- +-const CPlayerDesc *CPlayers::lookup_filetype(const std::string &ftype) const +-{ +- const_iterator i; +- +- for(i = begin(); i != end(); i++) +- if((*i)->filetype == ftype) +- return *i; +- +- return 0; +-} +- +-const CPlayerDesc *CPlayers::lookup_extension(const std::string &extension) const +-{ +- const_iterator i; +- unsigned int j; +- +- for(i = begin(); i != end(); i++) +- for(j = 0; (*i)->get_extension(j); j++) +- if(!strcasecmp(extension.c_str(), (*i)->get_extension(j))) +- return *i; +- +- return 0; +-} +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/players.h audacious-plugins-3.9/src/adplug/core/players.h +--- audacious-plugins-3.9-orig/src/adplug/core/players.h 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/players.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,60 +0,0 @@ +-/* +- * AdPlug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2003 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * players.h - Players enumeration, by Simon Peter +- */ +- +-#ifndef H_ADPLUG_PLAYERS +-#define H_ADPLUG_PLAYERS +- +-#include +-#include +- +-#include "opl.h" +-#include "player.h" +- +-class CPlayerDesc +-{ +-public: +- typedef CPlayer *(*Factory)(Copl *); +- +- Factory factory; +- std::string filetype; +- +- CPlayerDesc(); +- CPlayerDesc(const CPlayerDesc &pd); +- CPlayerDesc(Factory f, const std::string &type, const char *ext); +- +- ~CPlayerDesc(); +- +- void add_extension(const char *ext); +- const char *get_extension(unsigned int n) const; +- +-private: +- char *extensions; +- unsigned long extlength; +-}; +- +-class CPlayers: public std::list +-{ +-public: +- const CPlayerDesc *lookup_filetype(const std::string &ftype) const; +- const CPlayerDesc *lookup_extension(const std::string &extension) const; +-}; +- +-#endif +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/protrack.cc audacious-plugins-3.9/src/adplug/core/protrack.cc +--- audacious-plugins-3.9-orig/src/adplug/core/protrack.cc 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/protrack.cc 1970-01-01 01:00:00.000000000 +0100 +@@ -1,829 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2007 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * protrack.cpp - Generic Protracker Player +- * +- * NOTES: +- * This is a generic Protracker-based formats player. It offers all Protracker +- * features, plus a good set of extensions to be compatible to other Protracker +- * derivatives. It is derived from the former SA2 player. If you got a +- * Protracker-like format, this is most certainly the player you want to use. +- */ +- +-#include +-#include "protrack.h" +-#include "debug.h" +- +-#define SPECIALARPLEN 256 // Standard length of special arpeggio lists +-#define JUMPMARKER 0x80 // Orderlist jump marker +- +-// SA2 compatible adlib note table +-const unsigned short CmodPlayer::sa2_notetable[12] = +- {340,363,385,408,432,458,485,514,544,577,611,647}; +- +-// SA2 compatible vibrato rate table +-const unsigned char CmodPlayer::vibratotab[32] = +- {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1}; +- +-/*** public methods *************************************/ +- +-CmodPlayer::CmodPlayer(Copl *newopl) +- : CPlayer(newopl), inst(0), order(0), arplist(0), arpcmd(0), initspeed(6), +- nop(0), activechan(0xffffffff), flags(Standard), curchip(opl->getchip()), +- nrows(0), npats(0), nchans(0) +-{ +- realloc_order(128); +- realloc_patterns(64, 64, 9); +- realloc_instruments(250); +- init_notetable(sa2_notetable); +-} +- +-CmodPlayer::~CmodPlayer() +-{ +- dealloc(); +-} +- +-bool CmodPlayer::update() +-{ +- unsigned char pattbreak=0, donote, pattnr, chan, oplchan, info1, +- info2, info, pattern_delay; +- unsigned short track; +- unsigned long row; +- +- if(!speed) // song full stop +- return !songend; +- +- // effect handling (timer dependant) +- for(chan = 0; chan < nchans; chan++) { +- oplchan = set_opl_chip(chan); +- +- if(arplist && arpcmd && inst[channel[chan].inst].arpstart) { // special arpeggio +- if(channel[chan].arpspdcnt) +- channel[chan].arpspdcnt--; +- else +- if(arpcmd[channel[chan].arppos] != 255) { +- switch(arpcmd[channel[chan].arppos]) { +- case 252: channel[chan].vol1 = arplist[channel[chan].arppos]; // set volume +- if(channel[chan].vol1 > 63) // ????? +- channel[chan].vol1 = 63; +- channel[chan].vol2 = channel[chan].vol1; +- setvolume(chan); +- break; +- case 253: channel[chan].key = 0; setfreq(chan); break; // release sustaining note +- case 254: channel[chan].arppos = arplist[channel[chan].arppos]; break; // arpeggio loop +- default: if(arpcmd[channel[chan].arppos]) { +- if(arpcmd[channel[chan].arppos] / 10) +- opl->write(0xe3 + op_table[oplchan], arpcmd[channel[chan].arppos] / 10 - 1); +- if(arpcmd[channel[chan].arppos] % 10) +- opl->write(0xe0 + op_table[oplchan], (arpcmd[channel[chan].arppos] % 10) - 1); +- if(arpcmd[channel[chan].arppos] < 10) // ????? +- opl->write(0xe0 + op_table[oplchan], arpcmd[channel[chan].arppos] - 1); +- } +- } +- if(arpcmd[channel[chan].arppos] != 252) { +- if(arplist[channel[chan].arppos] <= 96) +- setnote(chan,channel[chan].note + arplist[channel[chan].arppos]); +- if(arplist[channel[chan].arppos] >= 100) +- setnote(chan,arplist[channel[chan].arppos] - 100); +- } else +- setnote(chan,channel[chan].note); +- setfreq(chan); +- if(arpcmd[channel[chan].arppos] != 255) +- channel[chan].arppos++; +- channel[chan].arpspdcnt = inst[channel[chan].inst].arpspeed - 1; +- } +- } +- +- info1 = channel[chan].info1; +- info2 = channel[chan].info2; +- if(flags & Decimal) +- info = channel[chan].info1 * 10 + channel[chan].info2; +- else +- info = (channel[chan].info1 << 4) + channel[chan].info2; +- switch(channel[chan].fx) { +- case 0: if(info) { // arpeggio +- if(channel[chan].trigger < 2) +- channel[chan].trigger++; +- else +- channel[chan].trigger = 0; +- switch(channel[chan].trigger) { +- case 0: setnote(chan,channel[chan].note); break; +- case 1: setnote(chan,channel[chan].note + info1); break; +- case 2: setnote(chan,channel[chan].note + info2); +- } +- setfreq(chan); +- } +- break; +- case 1: slide_up(chan,info); setfreq(chan); break; // slide up +- case 2: slide_down(chan,info); setfreq(chan); break; // slide down +- case 3: tone_portamento(chan,channel[chan].portainfo); break; // tone portamento +- case 4: vibrato(chan,channel[chan].vibinfo1,channel[chan].vibinfo2); break; // vibrato +- case 5: // tone portamento & volume slide +- case 6: if(channel[chan].fx == 5) // vibrato & volume slide +- tone_portamento(chan,channel[chan].portainfo); +- else +- vibrato(chan,channel[chan].vibinfo1,channel[chan].vibinfo2); +- case 10: +- if(del % 4) // SA2 volume slide +- break; +- if(info1) +- vol_up(chan,info1); +- else +- vol_down(chan,info2); +- setvolume(chan); +- break; +- case 14: +- if(info1 == 3) // retrig note +- if(!(del % (info2+1))) +- playnote(chan); +- break; +- case 16: +- if(del % 4) // AMD volume slide +- break; +- if(info1) +- vol_up_alt(chan,info1); +- else +- vol_down_alt(chan,info2); +- setvolume(chan); +- break; +- case 20: // RAD volume slide +- if(info < 50) +- vol_down_alt(chan,info); +- else +- vol_up_alt(chan,info - 50); +- setvolume(chan); +- break; +- case 26: // volume slide +- if(info1) +- vol_up(chan,info1); +- else +- vol_down(chan,info2); +- setvolume(chan); +- break; +- case 28: +- if (info1) { +- slide_up(chan,1); channel[chan].info1--; +- } +- if (info2) { +- slide_down(chan,1); channel[chan].info2--; +- } +- setfreq(chan); +- break; +- } +- } +- +- if(del) { // speed compensation +- del--; +- return !songend; +- } +- +- // arrangement handling +- if(!resolve_order()) return !songend; +- pattnr = order[ord]; +- +- if(!rw) AdPlug_LogWrite("\nCmodPlayer::update(): Pattern: %d, Order: %lu\n", pattnr, ord); +- AdPlug_LogWrite("CmodPlayer::update():%3lu|", rw); +- +- // play row +- pattern_delay = 0; +- row = rw; +- for(chan = 0; chan < nchans; chan++) { +- oplchan = set_opl_chip(chan); +- +- if(!((activechan >> (31 - chan)) & 1)) { // channel active? +- AdPlug_LogWrite("N/A|"); +- continue; +- } +- if(!(track = trackord[pattnr][chan])) { // resolve track +- AdPlug_LogWrite("------------|"); +- continue; +- } else +- track--; +- +- AdPlug_LogWrite("%3d%3d%2X%2X%2X|", tracks[track][row].note, +- tracks[track][row].inst, tracks[track][row].command, +- tracks[track][row].param1, tracks[track][row].param2); +- +- donote = 0; +- if(tracks[track][row].inst) { +- channel[chan].inst = tracks[track][row].inst - 1; +- if (!(flags & Faust)) { +- channel[chan].vol1 = 63 - (inst[channel[chan].inst].data[10] & 63); +- channel[chan].vol2 = 63 - (inst[channel[chan].inst].data[9] & 63); +- setvolume(chan); +- } +- } +- +- if(tracks[track][row].note && tracks[track][row].command != 3) { // no tone portamento +- channel[chan].note = tracks[track][row].note; +- setnote(chan,tracks[track][row].note); +- channel[chan].nextfreq = channel[chan].freq; +- channel[chan].nextoct = channel[chan].oct; +- channel[chan].arppos = inst[channel[chan].inst].arpstart; +- channel[chan].arpspdcnt = 0; +- if(tracks[track][row].note != 127) // handle key off +- donote = 1; +- } +- channel[chan].fx = tracks[track][row].command; +- channel[chan].info1 = tracks[track][row].param1; +- channel[chan].info2 = tracks[track][row].param2; +- +- if(donote) +- playnote(chan); +- +- // command handling (row dependant) +- info1 = channel[chan].info1; +- info2 = channel[chan].info2; +- if(flags & Decimal) +- info = channel[chan].info1 * 10 + channel[chan].info2; +- else +- info = (channel[chan].info1 << 4) + channel[chan].info2; +- switch(channel[chan].fx) { +- case 3: // tone portamento +- if(tracks[track][row].note) { +- if(tracks[track][row].note < 13) +- channel[chan].nextfreq = notetable[tracks[track][row].note - 1]; +- else +- if(tracks[track][row].note % 12 > 0) +- channel[chan].nextfreq = notetable[(tracks[track][row].note % 12) - 1]; +- else +- channel[chan].nextfreq = notetable[11]; +- channel[chan].nextoct = (tracks[track][row].note - 1) / 12; +- if(tracks[track][row].note == 127) { // handle key off +- channel[chan].nextfreq = channel[chan].freq; +- channel[chan].nextoct = channel[chan].oct; +- } +- } +- if(info) // remember vars +- channel[chan].portainfo = info; +- break; +- +- case 4: // vibrato (remember vars) +- if(info) { +- channel[chan].vibinfo1 = info1; +- channel[chan].vibinfo2 = info2; +- } +- break; +- +- case 7: tempo = info; break; // set tempo +- +- case 8: channel[chan].key = 0; setfreq(chan); break; // release sustaining note +- +- case 9: // set carrier/modulator volume +- if(info1) +- channel[chan].vol1 = info1 * 7; +- else +- channel[chan].vol2 = info2 * 7; +- setvolume(chan); +- break; +- +- case 11: // position jump +- pattbreak = 1; rw = 0; if(info < ord) songend = 1; ord = info; break; +- +- case 12: // set volume +- channel[chan].vol1 = info; +- channel[chan].vol2 = info; +- if(channel[chan].vol1 > 63) +- channel[chan].vol1 = 63; +- if(channel[chan].vol2 > 63) +- channel[chan].vol2 = 63; +- setvolume(chan); +- break; +- +- case 13: // pattern break +- if(!pattbreak) { pattbreak = 1; rw = info; ord++; } break; +- +- case 14: // extended command +- switch(info1) { +- case 0: // define cell-tremolo +- if(info2) +- regbd |= 128; +- else +- regbd &= 127; +- opl->write(0xbd,regbd); +- break; +- +- case 1: // define cell-vibrato +- if(info2) +- regbd |= 64; +- else +- regbd &= 191; +- opl->write(0xbd,regbd); +- break; +- +- case 4: // increase volume fine +- vol_up_alt(chan,info2); +- setvolume(chan); +- break; +- +- case 5: // decrease volume fine +- vol_down_alt(chan,info2); +- setvolume(chan); +- break; +- +- case 6: // manual slide up +- slide_up(chan,info2); +- setfreq(chan); +- break; +- +- case 7: // manual slide down +- slide_down(chan,info2); +- setfreq(chan); +- break; +- +- case 8: // pattern delay (rows) +- pattern_delay = info2 * speed; +- break; +- } +- break; +- +- case 15: // SA2 set speed +- if(info <= 0x1f) +- speed = info; +- if(info >= 0x32) +- tempo = info; +- if(!info) +- songend = 1; +- break; +- +- case 17: // alternate set volume +- channel[chan].vol1 = info; +- if(channel[chan].vol1 > 63) +- channel[chan].vol1 = 63; +- if(inst[channel[chan].inst].data[0] & 1) { +- channel[chan].vol2 = info; +- if(channel[chan].vol2 > 63) +- channel[chan].vol2 = 63; +- } +- +- setvolume(chan); +- break; +- +- case 18: // AMD set speed +- if(info <= 31 && info > 0) +- speed = info; +- if(info > 31 || !info) +- tempo = info; +- break; +- +- case 19: // RAD/A2M set speed +- speed = (info ? info : info + 1); +- break; +- +- case 21: // set modulator volume +- if(info <= 63) +- channel[chan].vol2 = info; +- else +- channel[chan].vol2 = 63; +- setvolume(chan); +- break; +- +- case 22: // set carrier volume +- if(info <= 63) +- channel[chan].vol1 = info; +- else +- channel[chan].vol1 = 63; +- setvolume(chan); +- break; +- +- case 23: // fine frequency slide up +- slide_up(chan,info); +- setfreq(chan); +- break; +- +- case 24: // fine frequency slide down +- slide_down(chan,info); +- setfreq(chan); +- break; +- +- case 25: // set carrier/modulator waveform +- if(info1 != 0x0f) +- opl->write(0xe3 + op_table[oplchan],info1); +- if(info2 != 0x0f) +- opl->write(0xe0 + op_table[oplchan],info2); +- break; +- +- case 27: // set chip tremolo/vibrato +- if(info1) +- regbd |= 128; +- else +- regbd &= 127; +- if(info2) +- regbd |= 64; +- else +- regbd &= 191; +- opl->write(0xbd,regbd); +- break; +- +- case 29: // pattern delay (frames) +- pattern_delay = info; +- break; +- } +- } +- +- // speed compensation +- del = speed - 1 + pattern_delay; +- +- if(!pattbreak) { // next row (only if no manual advance) +- rw++; +- if(rw >= nrows) { +- rw = 0; +- ord++; +- } +- } +- +- resolve_order(); // so we can report songend right away +- AdPlug_LogWrite("\n"); +- return !songend; +-} +- +-unsigned char CmodPlayer::set_opl_chip(unsigned char chan) +- /* +- * Sets OPL chip according to channel number. Channels 0-8 are on first chip, +- * channels 9-17 are on second chip. Returns corresponding OPL channel +- * number. +- */ +-{ +- int newchip = chan < 9 ? 0 : 1; +- +- if(newchip != curchip) { +- opl->setchip(newchip); +- curchip = newchip; +- } +- +- return chan % 9; +-} +- +-bool CmodPlayer::resolve_order() +- /* +- * Resolves current orderlist entry, checking for jumps and loops. +- * +- * Returns true on correct processing, false if immediate recursive loop +- * has been detected. +- */ +-{ +- if(ord < length) { +- while(order[ord] >= JUMPMARKER) { // jump to order +- unsigned long neword = order[ord] - JUMPMARKER; +- +- if(neword <= ord) songend = 1; +- if(neword == ord) return false; +- ord = neword; +- } +- } else { +- songend = 1; +- ord = restartpos; +- } +- +- return true; +-} +- +-void CmodPlayer::rewind(int subsong) +-{ +- unsigned long i; +- +- // Reset playing variables +- songend = del = ord = rw = regbd = 0; +- tempo = bpm; speed = initspeed; +- +- // Reset channel data +- memset(channel,0,sizeof(Channel)*nchans); +- +- // Compute number of patterns, if needed +- if(!nop) +- for(i=0;i nop ? order[i] : nop); +- +- opl->init(); // Reset OPL chip +- opl->write(1, 32); // Go to ym3812 mode +- +- // Enable OPL3 extensions if flagged +- if(flags & Opl3) { +- opl->setchip(1); +- opl->write(1, 32); +- opl->write(5, 1); +- opl->setchip(0); +- } +- +- // Enable tremolo/vibrato depth if flagged +- if(flags & Tremolo) regbd |= 128; +- if(flags & Vibrato) regbd |= 64; +- if(regbd) opl->write(0xbd, regbd); +-} +- +-float CmodPlayer::getrefresh() +-{ +- return (float) (tempo / 2.5); +-} +- +-void CmodPlayer::init_trackord() +-{ +- unsigned long i; +- +- for(i=0;iwrite(0x40 + op_table[oplchan], 63-channel[chan].vol2 + (inst[channel[chan].inst].data[9] & 192)); +- opl->write(0x43 + op_table[oplchan], 63-channel[chan].vol1 + (inst[channel[chan].inst].data[10] & 192)); +- } +-} +- +-void CmodPlayer::setvolume_alt(unsigned char chan) +-{ +- unsigned char oplchan = set_opl_chip(chan); +- unsigned char ivol2 = inst[channel[chan].inst].data[9] & 63; +- unsigned char ivol1 = inst[channel[chan].inst].data[10] & 63; +- +- opl->write(0x40 + op_table[oplchan], (((63 - (channel[chan].vol2 & 63)) + ivol2) >> 1) + (inst[channel[chan].inst].data[9] & 192)); +- opl->write(0x43 + op_table[oplchan], (((63 - (channel[chan].vol1 & 63)) + ivol1) >> 1) + (inst[channel[chan].inst].data[10] & 192)); +-} +- +-void CmodPlayer::setfreq(unsigned char chan) +-{ +- unsigned char oplchan = set_opl_chip(chan); +- +- opl->write(0xa0 + oplchan, channel[chan].freq & 255); +- if(channel[chan].key) +- opl->write(0xb0 + oplchan, ((channel[chan].freq & 768) >> 8) + ((channel[chan].oct << 2) | 32)); +- else +- opl->write(0xb0 + oplchan, ((channel[chan].freq & 768) >> 8) + (channel[chan].oct << 2)); +-} +- +-void CmodPlayer::playnote(unsigned char chan) +-{ +- unsigned char oplchan = set_opl_chip(chan); +- unsigned char op = op_table[oplchan], insnr = channel[chan].inst; +- +- if(!(flags & NoKeyOn)) +- opl->write(0xb0 + oplchan, 0); // stop old note +- +- // set instrument data +- opl->write(0x20 + op, inst[insnr].data[1]); +- opl->write(0x23 + op, inst[insnr].data[2]); +- opl->write(0x60 + op, inst[insnr].data[3]); +- opl->write(0x63 + op, inst[insnr].data[4]); +- opl->write(0x80 + op, inst[insnr].data[5]); +- opl->write(0x83 + op, inst[insnr].data[6]); +- opl->write(0xe0 + op, inst[insnr].data[7]); +- opl->write(0xe3 + op, inst[insnr].data[8]); +- opl->write(0xc0 + oplchan, inst[insnr].data[0]); +- opl->write(0xbd, inst[insnr].misc); // set misc. register +- +- // set frequency, volume & play +- channel[chan].key = 1; +- setfreq(chan); +- +- if (flags & Faust) { +- channel[chan].vol2 = 63; +- channel[chan].vol1 = 63; +- } +- setvolume(chan); +-} +- +-void CmodPlayer::setnote(unsigned char chan, int note) +-{ +- if(note > 96) { +- if(note == 127) { // key off +- channel[chan].key = 0; +- setfreq(chan); +- return; +- } else +- note = 96; +- } +- +- if(note < 13) +- channel[chan].freq = notetable[note - 1]; +- else +- if(note % 12 > 0) +- channel[chan].freq = notetable[(note % 12) - 1]; +- else +- channel[chan].freq = notetable[11]; +- channel[chan].oct = (note - 1) / 12; +- channel[chan].freq += inst[channel[chan].inst].slide; // apply pre-slide +-} +- +-void CmodPlayer::slide_down(unsigned char chan, int amount) +-{ +- channel[chan].freq -= amount; +- if(channel[chan].freq <= 342) { +- if(channel[chan].oct) { +- channel[chan].oct--; +- channel[chan].freq <<= 1; +- } else +- channel[chan].freq = 342; +- } +-} +- +-void CmodPlayer::slide_up(unsigned char chan, int amount) +-{ +- channel[chan].freq += amount; +- if(channel[chan].freq >= 686) { +- if(channel[chan].oct < 7) { +- channel[chan].oct++; +- channel[chan].freq >>= 1; +- } else +- channel[chan].freq = 686; +- } +-} +- +-void CmodPlayer::tone_portamento(unsigned char chan, unsigned char info) +-{ +- if(channel[chan].freq + (channel[chan].oct << 10) < channel[chan].nextfreq + +- (channel[chan].nextoct << 10)) { +- slide_up(chan,info); +- if(channel[chan].freq + (channel[chan].oct << 10) > channel[chan].nextfreq + +- (channel[chan].nextoct << 10)) { +- channel[chan].freq = channel[chan].nextfreq; +- channel[chan].oct = channel[chan].nextoct; +- } +- } +- if(channel[chan].freq + (channel[chan].oct << 10) > channel[chan].nextfreq + +- (channel[chan].nextoct << 10)) { +- slide_down(chan,info); +- if(channel[chan].freq + (channel[chan].oct << 10) < channel[chan].nextfreq + +- (channel[chan].nextoct << 10)) { +- channel[chan].freq = channel[chan].nextfreq; +- channel[chan].oct = channel[chan].nextoct; +- } +- } +- setfreq(chan); +-} +- +-void CmodPlayer::vibrato(unsigned char chan, unsigned char speed, unsigned char depth) +-{ +- int i; +- +- if(!speed || !depth) +- return; +- +- if(depth > 14) +- depth = 14; +- +- for(i=0;i= 64) +- channel[chan].trigger -= 64; +- if(channel[chan].trigger >= 16 && channel[chan].trigger < 48) +- slide_down(chan,vibratotab[channel[chan].trigger - 16] / (16-depth)); +- if(channel[chan].trigger < 16) +- slide_up(chan,vibratotab[channel[chan].trigger + 16] / (16-depth)); +- if(channel[chan].trigger >= 48) +- slide_up(chan,vibratotab[channel[chan].trigger - 48] / (16-depth)); +- } +- setfreq(chan); +-} +- +-void CmodPlayer::vol_up(unsigned char chan, int amount) +-{ +- if(channel[chan].vol1 + amount < 63) +- channel[chan].vol1 += amount; +- else +- channel[chan].vol1 = 63; +- +- if(channel[chan].vol2 + amount < 63) +- channel[chan].vol2 += amount; +- else +- channel[chan].vol2 = 63; +-} +- +-void CmodPlayer::vol_down(unsigned char chan, int amount) +-{ +- if(channel[chan].vol1 - amount > 0) +- channel[chan].vol1 -= amount; +- else +- channel[chan].vol1 = 0; +- +- if(channel[chan].vol2 - amount > 0) +- channel[chan].vol2 -= amount; +- else +- channel[chan].vol2 = 0; +-} +- +-void CmodPlayer::vol_up_alt(unsigned char chan, int amount) +-{ +- if(channel[chan].vol1 + amount < 63) +- channel[chan].vol1 += amount; +- else +- channel[chan].vol1 = 63; +- if(inst[channel[chan].inst].data[0] & 1) { +- if(channel[chan].vol2 + amount < 63) +- channel[chan].vol2 += amount; +- else +- channel[chan].vol2 = 63; +- } +-} +- +-void CmodPlayer::vol_down_alt(unsigned char chan, int amount) +-{ +- if(channel[chan].vol1 - amount > 0) +- channel[chan].vol1 -= amount; +- else +- channel[chan].vol1 = 0; +- if(inst[channel[chan].inst].data[0] & 1) { +- if(channel[chan].vol2 - amount > 0) +- channel[chan].vol2 -= amount; +- else +- channel[chan].vol2 = 0; +- } +-} +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/protrack.h audacious-plugins-3.9/src/adplug/core/protrack.h +--- audacious-plugins-3.9-orig/src/adplug/core/protrack.h 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/protrack.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,119 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2007 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * protrack.h - Generic Protracker Player by Simon Peter +- */ +- +-#ifndef H_PROTRACK +-#define H_PROTRACK +- +-#include "player.h" +- +-class CmodPlayer: public CPlayer +-{ +-public: +- CmodPlayer(Copl *newopl); +- virtual ~CmodPlayer(); +- +- bool update(); +- void rewind(int subsong); +- float getrefresh(); +- +- unsigned int getpatterns() +- { return nop; } +- unsigned int getpattern() +- { return order[ord]; } +- unsigned int getorders() +- { return length; } +- unsigned int getorder() +- { return ord; } +- unsigned int getrow() +- { return rw; } +- unsigned int getspeed() +- { return speed; } +- +- protected: +- enum Flags { +- Standard = 0, +- Decimal = 1 << 0, +- Faust = 1 << 1, +- NoKeyOn = 1 << 2, +- Opl3 = 1 << 3, +- Tremolo = 1 << 4, +- Vibrato = 1 << 5, +- Percussion = 1 << 6 +- }; +- +- struct Instrument { +- unsigned char data[11],arpstart,arpspeed,arppos,arpspdcnt,misc; +- signed char slide; +- } *inst; +- +- struct Tracks { +- unsigned char note,command,inst,param2,param1; +- } **tracks; +- +- unsigned char *order, *arplist, *arpcmd, initspeed; +- unsigned short tempo, **trackord, bpm, nop; +- unsigned long length, restartpos, activechan; +- int flags, curchip; +- +- struct Channel { +- unsigned short freq,nextfreq; +- unsigned char oct,vol1,vol2,inst,fx,info1,info2,key,nextoct, +- note,portainfo,vibinfo1,vibinfo2,arppos,arpspdcnt; +- signed char trigger; +- } *channel; +- +- void init_trackord(); +- bool init_specialarp(); +- void init_notetable(const unsigned short *newnotetable); +- bool realloc_order(unsigned long len); +- bool realloc_patterns(unsigned long pats, unsigned long rows, unsigned long chans); +- bool realloc_instruments(unsigned long len); +- +- void dealloc(); +- +- private: +- static const unsigned short sa2_notetable[12]; +- static const unsigned char vibratotab[32]; +- +- unsigned char speed, del, songend, regbd; +- unsigned short notetable[12]; +- unsigned long rw, ord, nrows, npats, nchans; +- +- void setvolume(unsigned char chan); +- void setvolume_alt(unsigned char chan); +- void setfreq(unsigned char chan); +- void playnote(unsigned char chan); +- void setnote(unsigned char chan, int note); +- void slide_down(unsigned char chan, int amount); +- void slide_up(unsigned char chan, int amount); +- void tone_portamento(unsigned char chan, unsigned char info); +- void vibrato(unsigned char chan, unsigned char speed, unsigned char depth); +- void vol_up(unsigned char chan, int amount); +- void vol_down(unsigned char chan, int amount); +- void vol_up_alt(unsigned char chan, int amount); +- void vol_down_alt(unsigned char chan, int amount); +- +- void dealloc_patterns(); +- bool resolve_order(); +- unsigned char set_opl_chip(unsigned char chan); +-}; +- +-#endif +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/psi.cc audacious-plugins-3.9/src/adplug/core/psi.cc +--- audacious-plugins-3.9-orig/src/adplug/core/psi.cc 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/psi.cc 1970-01-01 01:00:00.000000000 +0100 +@@ -1,177 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2003 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * [xad] PSI player, by Riven the Mage +- */ +- +-/* +- - discovery - +- +- file(s) : 4BIDDEN.COM, PGRID.EXE +- type : Forbidden Dreams BBStro +- Power Grid BBStro +- tune : by Friar Tuck [Shadow Faction/ICE] +- player : by Psi [Future Crew] +- comment : seems to me what 4bidden tune & player was ripped from pgrid +- +- file(s) : MYSTRUNE.COM +- type : Mystical Runes BBStro +- tune : by ? +- player : by Psi [Future Crew] +-*/ +- +-#include "psi.h" +-#include "debug.h" +- +-const unsigned char CxadpsiPlayer::psi_adlib_registers[99] = +-{ +- 0x20, 0x23, 0x40, 0x43, 0x60, 0x63, 0x80, 0x83, 0xE0, 0xE3, 0xC0, +- 0x21, 0x24, 0x41, 0x44, 0x61, 0x64, 0x81, 0x84, 0xE1, 0xE4, 0xC1, +- 0x22, 0x25, 0x42, 0x45, 0x62, 0x65, 0x82, 0x85, 0xE2, 0xE5, 0xC2, +- 0x28, 0x2B, 0x48, 0x4B, 0x68, 0x6B, 0x88, 0x8B, 0xE8, 0xEB, 0xC3, +- 0x29, 0x2C, 0x49, 0x4C, 0x69, 0x6C, 0x89, 0x8C, 0xE9, 0xEC, 0xC4, +- 0x2A, 0x2D, 0x4A, 0x4D, 0x6A, 0x6D, 0x8A, 0x8D, 0xEA, 0xED, 0xC5, +- 0x30, 0x33, 0x50, 0x53, 0x70, 0x73, 0x90, 0x93, 0xF0, 0xF3, 0xC6, +- 0x31, 0x34, 0x51, 0x54, 0x71, 0x74, 0x91, 0x94, 0xF1, 0xF4, 0xC7, +- 0x32, 0x35, 0x52, 0x55, 0x72, 0x75, 0x92, 0x95, 0xF2, 0xF5, 0xC8 +-}; +- +-const unsigned short CxadpsiPlayer::psi_notes[16] = +-{ +- 0x216B, 0x2181, 0x2198, 0x21B0, 0x21CA, 0x21E5, 0x2202, 0x2220, +- 0x2241, 0x2263, 0x2287, 0x2364, +- 0x0000, 0x0000, 0x0000, 0x0000 // by riven +-}; +- +-CPlayer *CxadpsiPlayer::factory(Copl *newopl) +-{ +- return new CxadpsiPlayer(newopl); +-} +- +-void CxadpsiPlayer::xadplayer_rewind(int subsong) +-{ +- opl_write(0x01, 0x20); +- opl_write(0x08, 0x00); +- opl_write(0xBD, 0x00); +- +- // get header +- header.instr_ptr = (tune[1] << 8) + tune[0]; +- header.seq_ptr = (tune[3] << 8) + tune[2]; +- +- // define instruments +- psi.instr_table = &tune[header.instr_ptr]; +- +- for(int i=0; i<8; i++) +- { +- for(int j=0; j<11; j++) { +- unsigned short inspos = (psi.instr_table[i * 2 + 1] << 8) + psi.instr_table[i * 2]; +- +- opl_write(psi_adlib_registers[i*11 + j],tune[inspos + j]); +- } +- +- opl_write(0xA0+i, 0x00); +- opl_write(0xB0+i, 0x00); +- +- psi.note_delay[i] = 1; +- psi.note_curdelay[i] = 1; +- psi.looping[i] = 0; +- } +- +- // calculate sequence pointer +- psi.seq_table = &tune[header.seq_ptr]; +-} +- +-void CxadpsiPlayer::xadplayer_update() +-{ +- unsigned short ptr; +- +- for(int i=0; i<8; i++) +- { +- ptr = (psi.seq_table[(i<<1) * 2 + 1] << 8) + psi.seq_table[(i<<1) * 2]; +- +- psi.note_curdelay[i]--; +- +- if (!psi.note_curdelay[i]) +- { +- opl_write(0xA0+i, 0x00); +- opl_write(0xB0+i, 0x00); +- +- unsigned char event = tune[ptr++]; +-#ifdef DEBUG +- AdPlug_LogWrite("channel %02X, event %02X:\n",i+1,event); +-#endif +- +- // end of sequence ? +- if (!event) +- { +- ptr = (psi.seq_table[(i<<1) * 2 + 3] << 8) + psi.seq_table[(i<<1) * 2 + 2]; +- +- event = tune[ptr++]; +-#ifdef DEBUG +- AdPlug_LogWrite(" channel %02X, event %02X:\n",i+1,event); +-#endif +- +- // set sequence loop flag +- psi.looping[i] = 1; +- +- // module loop ? +- plr.looping = 1; +- for(int j=0; j<8; j++) +- plr.looping &= psi.looping[j]; +- } +- +- // new note delay ? +- if (event & 0x80) +- { +- psi.note_delay[i] = (event & 0x7F); +- +- event = tune[ptr++]; +-#ifdef DEBUG +- AdPlug_LogWrite(" channel %02X, event %02X:\n",i+1,event); +-#endif +- } +- +- psi.note_curdelay[i] = psi.note_delay[i]; +- +- // play note +- unsigned short note = psi_notes[event & 0x0F]; +- +- opl_write(0xA0+i, note & 0xFF); +- opl_write(0xB0+i, (note >> 8) + ((event >> 2) & 0xFC)); +- +- // save position +- psi.seq_table[(i<<1) * 2] = ptr & 0xff; +- psi.seq_table[(i<<1) * 2 + 1] = ptr >> 8; +- } +- } +-} +- +-float CxadpsiPlayer::xadplayer_getrefresh() +-{ +- return 70.0f; +-} +- +-std::string CxadpsiPlayer::xadplayer_gettype() +-{ +- return std::string("xad: psi player"); +-} +- +-unsigned int CxadpsiPlayer::xadplayer_getinstruments() +-{ +- return 8; +-} +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/psi.h audacious-plugins-3.9/src/adplug/core/psi.h +--- audacious-plugins-3.9-orig/src/adplug/core/psi.h 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/psi.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,64 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2003 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * [xad] PSI player, by Riven the Mage +- */ +- +-#include "xad.h" +- +-class CxadpsiPlayer: public CxadPlayer +-{ +-public: +- static CPlayer *factory(Copl *newopl); +- +- CxadpsiPlayer(Copl *newopl): CxadPlayer(newopl) +- { } +- +-protected: +- struct psi_header +- { +- unsigned short instr_ptr; +- unsigned short seq_ptr; +- } header; +- +- struct +- { +- unsigned char *instr_table; +- unsigned char *seq_table; +- unsigned char note_delay[9]; +- unsigned char note_curdelay[9]; +- unsigned char looping[9]; +- } psi; +- // +- bool xadplayer_load() +- { +- if(xad.fmt == PSI) +- return true; +- else +- return false; +- } +- void xadplayer_rewind(int subsong); +- void xadplayer_update(); +- float xadplayer_getrefresh(); +- std::string xadplayer_gettype(); +- unsigned int xadplayer_getinstruments(); +- +-private: +- static const unsigned char psi_adlib_registers[99]; +- static const unsigned short psi_notes[16]; +-}; +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/rad.cc audacious-plugins-3.9/src/adplug/core/rad.cc +--- audacious-plugins-3.9-orig/src/adplug/core/rad.cc 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/rad.cc 1970-01-01 01:00:00.000000000 +0100 +@@ -1,125 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2007 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * rad.cpp - RAD Loader by Simon Peter +- * +- * BUGS: +- * some volumes are dropped out +- */ +- +-#include +-#include "rad.h" +- +-CPlayer *CradLoader::factory(Copl *newopl) +-{ +- return new CradLoader(newopl); +-} +- +-bool CradLoader::load(const std::string &filename, const CFileProvider &fp) +-{ +- binistream *f = fp.open(filename); if(!f) return false; +- char id[16]; +- unsigned char buf,ch,c,b,inp; +- char bufstr[2] = "\0"; +- unsigned int i,j; +- unsigned short patofs[32]; +- const unsigned char convfx[16] = {255,1,2,3,255,5,255,255,255,255,20,255,17,0xd,255,19}; +- +- // file validation section +- f->readString(id, 16); version = f->readInt(1); +- if(strncmp(id,"RAD by REALiTY!!",16) || version != 0x10) +- { fp.close(f); return false; } +- +- // load section +- radflags = f->readInt(1); +- if(radflags & 128) { // description +- memset(desc,0,80*22); +- while((buf = f->readInt(1))) +- if(buf == 1) +- strcat(desc,"\n"); +- else +- if(buf >= 2 && buf <= 0x1f) +- for(i=0;ireadInt(1))) { // instruments +- buf--; +- inst[buf].data[2] = f->readInt(1); inst[buf].data[1] = f->readInt(1); +- inst[buf].data[10] = f->readInt(1); inst[buf].data[9] = f->readInt(1); +- inst[buf].data[4] = f->readInt(1); inst[buf].data[3] = f->readInt(1); +- inst[buf].data[6] = f->readInt(1); inst[buf].data[5] = f->readInt(1); +- inst[buf].data[0] = f->readInt(1); +- inst[buf].data[8] = f->readInt(1); inst[buf].data[7] = f->readInt(1); +- } +- length = f->readInt(1); +- for(i = 0; i < length; i++) order[i] = f->readInt(1); // orderlist +- for(i = 0; i < 32; i++) patofs[i] = f->readInt(2); // pattern offset table +- init_trackord(); // patterns +- for(i=0;i<32;i++) +- if(patofs[i]) { +- f->seek(patofs[i]); +- do { +- buf = f->readInt(1); b = buf & 127; +- do { +- ch = f->readInt(1); c = ch & 127; +- inp = f->readInt(1); +- tracks[i*9+c][b].note = inp & 127; +- tracks[i*9+c][b].inst = (inp & 128) >> 3; +- inp = f->readInt(1); +- tracks[i*9+c][b].inst += inp >> 4; +- tracks[i*9+c][b].command = inp & 15; +- if(inp & 15) { +- inp = f->readInt(1); +- tracks[i*9+c][b].param1 = inp / 10; +- tracks[i*9+c][b].param2 = inp % 10; +- } +- } while(!(ch & 128)); +- } while(!(buf & 128)); +- } else +- memset(trackord[i],0,9*2); +- fp.close(f); +- +- // convert replay data +- for(i=0;i<32*9;i++) // convert patterns +- for(j=0;j<64;j++) { +- if(tracks[i][j].note == 15) +- tracks[i][j].note = 127; +- if(tracks[i][j].note > 16 && tracks[i][j].note < 127) +- tracks[i][j].note -= 4 * (tracks[i][j].note >> 4); +- if(tracks[i][j].note && tracks[i][j].note < 126) +- tracks[i][j].note++; +- tracks[i][j].command = convfx[tracks[i][j].command]; +- } +- restartpos = 0; initspeed = radflags & 31; +- bpm = radflags & 64 ? 0 : 50; flags = Decimal; +- +- rewind(0); +- return true; +-} +- +-float CradLoader::getrefresh() +-{ +- if(tempo) +- return (float) (tempo); +- else +- return 18.2f; +-} +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/rad.h audacious-plugins-3.9/src/adplug/core/rad.h +--- audacious-plugins-3.9-orig/src/adplug/core/rad.h 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/rad.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,44 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2003 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * rad.h - RAD Loader by Simon Peter +- */ +- +-#include "protrack.h" +- +-class CradLoader: public CmodPlayer +-{ +-public: +- static CPlayer *factory(Copl *newopl); +- +- CradLoader(Copl *newopl) +- : CmodPlayer(newopl) +- { *desc = '\0'; }; +- +- bool load(const std::string &filename, const CFileProvider &fp); +- float getrefresh(); +- +- std::string gettype() +- { return std::string("Reality ADlib Tracker"); }; +- std::string getdesc() +- { return std::string(desc); }; +- +-private: +- unsigned char version,radflags; +- char desc[80*22]; +-}; +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/rat.cc audacious-plugins-3.9/src/adplug/core/rat.cc +--- audacious-plugins-3.9-orig/src/adplug/core/rat.cc 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/rat.cc 1970-01-01 01:00:00.000000000 +0100 +@@ -1,293 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2003 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * [xad] RAT player, by Riven the Mage +- */ +- +-/* +- - discovery - +- +- file(s) : PINA.EXE +- type : Experimental Connection BBStro tune +- tune : by (?)Ratt/GRIF +- player : by (?)Ratt/GRIF +- comment : there are bug in original replayer's adlib_init(): wrong frequency registers. +-*/ +- +-#include +-#include "rat.h" +-#include "debug.h" +- +-const unsigned char CxadratPlayer::rat_adlib_bases[18] = +-{ +- 0x00, 0x01, 0x02, 0x08, 0x09, 0x0A, 0x10, 0x11, 0x12, +- 0x03, 0x04, 0x05, 0x0B, 0x0C, 0x0D, 0x13, 0x14, 0x15 +-}; +- +-const unsigned short CxadratPlayer::rat_notes[16] = +-{ +- 0x157, 0x16B, 0x181, 0x198, 0x1B0, 0x1CA, 0x1E5, 0x202, 0x220, 0x241, 0x263, 0x287, +- 0x000, 0x000, 0x000, 0x000 // by riven +-}; +- +-CPlayer *CxadratPlayer::factory(Copl *newopl) +-{ +- return new CxadratPlayer(newopl); +-} +- +-bool CxadratPlayer::xadplayer_load() +-{ +- if(xad.fmt != RAT) +- return false; +- +- // load header +- memcpy(&rat.hdr, &tune[0], sizeof(rat_header)); +- +- // is 'RAT'-signed ? +- if (strncmp(rat.hdr.id,"RAT",3)) +- return false; +- +- // is version 1.0 ? +- if (rat.hdr.version != 0x10) +- return false; +- +- // load order +- rat.order = &tune[0x40]; +- +- // load instruments +- rat.inst = (rat_instrument *)&tune[0x140]; +- +- // load pattern data +- unsigned short patseg = (rat.hdr.patseg[1] << 8) + rat.hdr.patseg[0]; +- unsigned char *event_ptr = &tune[patseg << 4]; +- +- for(int i=0;i> 8) | ((event.note & 0xF0) >> 2) | 0x20); +- } +- } +- +- // is effect ? +- if (event.fx != 0xFF) +- { +- rat.channel[i].fx = event.fx; +- rat.channel[i].fxp = event.fxp; +- } +- } +- +- // next row +- rat.pattern_pos++; +- +- // process effects +- for(i=0;i= 0x40) +- { +- rat.pattern_pos = 0; +- +- rat.order_pos++; +- +- // end of module ? +- if (rat.order_pos == rat.hdr.order_end) +- { +- rat.order_pos = rat.hdr.order_loop; +- +- plr.looping = 1; +- } +- } +-} +- +-float CxadratPlayer::xadplayer_getrefresh() +-{ +- return 60.0f; +-} +- +-std::string CxadratPlayer::xadplayer_gettype() +-{ +- return (std::string("xad: rat player")); +-} +- +-std::string CxadratPlayer::xadplayer_gettitle() +-{ +- return (std::string(rat.hdr.title,32)); +-} +- +-unsigned int CxadratPlayer::xadplayer_getinstruments() +-{ +- return rat.hdr.numinst; +-} +- +-/* -------- Internal Functions ---------------------------- */ +- +-unsigned char CxadratPlayer::__rat_calc_volume(unsigned char ivol, unsigned char cvol, unsigned char gvol) +-{ +-#ifdef DEBUG +- AdPlug_LogWrite("volumes: instrument %02X, channel %02X, global %02X:\n", ivol, cvol, gvol); +-#endif +- unsigned short vol; +- +- vol = ivol; +- vol &= 0x3F; +- vol ^= 0x3F; +- vol *= cvol; +- vol >>= 6; +- vol *= gvol; +- vol >>= 6; +- vol ^= 0x3F; +- +- vol |= ivol & 0xC0; +- +- return vol; +-} +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/rat.h audacious-plugins-3.9/src/adplug/core/rat.h +--- audacious-plugins-3.9-orig/src/adplug/core/rat.h 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/rat.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,121 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2003 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * [xad] RAT player, by Riven the Mage +- */ +- +-#include "xad.h" +- +-class CxadratPlayer: public CxadPlayer +-{ +-public: +- static CPlayer *factory(Copl *newopl); +- +- CxadratPlayer(Copl *newopl): CxadPlayer(newopl) +- { } +- +-protected: +- struct rat_header +- { +- char id[3]; +- unsigned char version; +- char title[32]; +- unsigned char numchan; +- unsigned char reserved_25; +- unsigned char order_end; +- unsigned char reserved_27; +- unsigned char numinst; // ?: Number of Instruments +- unsigned char reserved_29; +- unsigned char numpat; // ?: Number of Patterns +- unsigned char reserved_2B; +- unsigned char order_start; +- unsigned char reserved_2D; +- unsigned char order_loop; +- unsigned char reserved_2F; +- unsigned char volume; +- unsigned char speed; +- unsigned char reserved_32[12]; +- unsigned char patseg[2]; +- }; +- +- struct rat_event +- { +- unsigned char note; +- unsigned char instrument; +- unsigned char volume; +- unsigned char fx; +- unsigned char fxp; +- }; +- +- struct rat_instrument +- { +- unsigned char freq[2]; +- unsigned char reserved_2[2]; +- unsigned char mod_ctrl; +- unsigned char car_ctrl; +- unsigned char mod_volume; +- unsigned char car_volume; +- unsigned char mod_AD; +- unsigned char car_AD; +- unsigned char mod_SR; +- unsigned char car_SR; +- unsigned char mod_wave; +- unsigned char car_wave; +- unsigned char connect; +- unsigned char reserved_F; +- unsigned char volume; +- unsigned char reserved_11[3]; +- }; +- +- struct +- { +- rat_header hdr; +- +- unsigned char volume; +- unsigned char order_pos; +- unsigned char pattern_pos; +- +- unsigned char *order; +- +- rat_instrument *inst; +- +- rat_event tracks[256][64][9]; +- +- struct +- { +- unsigned char instrument; +- unsigned char volume; +- unsigned char fx; +- unsigned char fxp; +- } channel[9]; +- } rat; +- // +- bool xadplayer_load(); +- void xadplayer_rewind(int subsong); +- void xadplayer_update(); +- float xadplayer_getrefresh(); +- std::string xadplayer_gettype(); +- std::string xadplayer_gettitle(); +- unsigned int xadplayer_getinstruments(); +- // +-private: +- static const unsigned char rat_adlib_bases[18]; +- static const unsigned short rat_notes[16]; +- +- unsigned char __rat_calc_volume(unsigned char ivol, unsigned char cvol, unsigned char gvol); +-}; +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/raw.cc audacious-plugins-3.9/src/adplug/core/raw.cc +--- audacious-plugins-3.9-orig/src/adplug/core/raw.cc 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/raw.cc 1970-01-01 01:00:00.000000000 +0100 +@@ -1,104 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2005 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * raw.c - RAW Player by Simon Peter +- */ +- +-#include +-#include "raw.h" +- +-/*** public methods *************************************/ +- +-CPlayer *CrawPlayer::factory(Copl *newopl) +-{ +- return new CrawPlayer(newopl); +-} +- +-bool CrawPlayer::load(const std::string &filename, const CFileProvider &fp) +-{ +- binistream *f = fp.open(filename); if(!f) return false; +- char id[8]; +- unsigned long i; +- +- // file validation section +- f->readString(id, 8); +- if(strncmp(id,"RAWADATA",8)) { fp.close (f); return false; } +- +- // load section +- clock = f->readInt(2); // clock speed +- length = (fp.filesize(f) - 10) / 2; +- data = new Tdata [length]; +- for(i = 0; i < length; i++) { +- data[i].param = f->readInt(1); +- data[i].command = f->readInt(1); +- } +- +- fp.close(f); +- rewind(0); +- return true; +-} +- +-bool CrawPlayer::update() +-{ +- bool setspeed; +- +- if(pos >= length) return false; +- +- if(del) { +- del--; +- return !songend; +- } +- +- do { +- setspeed = false; +- switch(data[pos].command) { +- case 0: del = data[pos].param - 1; break; +- case 2: +- if(!data[pos].param) { +- pos++; +- speed = data[pos].param + (data[pos].command << 8); +- setspeed = true; +- } else +- opl->setchip(data[pos].param - 1); +- break; +- case 0xff: +- if(data[pos].param == 0xff) { +- rewind(0); // auto-rewind song +- songend = true; +- return !songend; +- } +- break; +- default: +- opl->write(data[pos].command,data[pos].param); +- break; +- } +- } while(data[pos++].command || setspeed); +- +- return !songend; +-} +- +-void CrawPlayer::rewind(int subsong) +-{ +- pos = del = 0; speed = clock; songend = false; +- opl->init(); opl->write(1, 32); // go to 9 channel mode +-} +- +-float CrawPlayer::getrefresh() +-{ +- return 1193180.0 / (speed ? speed : 0xffff); // timer oscillator speed / wait register = clock frequency +-} +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/raw.h audacious-plugins-3.9/src/adplug/core/raw.h +--- audacious-plugins-3.9-orig/src/adplug/core/raw.h 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/raw.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,52 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2005 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * raw.h - RAW Player by Simon Peter +- */ +- +-#include "player.h" +- +-class CrawPlayer: public CPlayer +-{ +-public: +- static CPlayer *factory(Copl *newopl); +- +- CrawPlayer(Copl *newopl) +- : CPlayer(newopl), data(0) +- { }; +- ~CrawPlayer() +- { if(data) delete [] data; }; +- +- bool load(const std::string &filename, const CFileProvider &fp); +- bool update(); +- void rewind(int subsong); +- float getrefresh(); +- +- std::string gettype() +- { return std::string("RdosPlay RAW"); }; +- +-protected: +- struct Tdata { +- unsigned char param, command; +- } *data; +- +- unsigned long pos, length; +- unsigned short clock, speed; +- unsigned char del; +- bool songend; +-}; +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/README.audacious audacious-plugins-3.9/src/adplug/core/README.audacious +--- audacious-plugins-3.9-orig/src/adplug/core/README.audacious 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/README.audacious 1970-01-01 01:00:00.000000000 +0100 +@@ -1,10 +0,0 @@ +-This is a summary of changes made to the AdPlug core in the plugin for +-Audacious: +- +-- every replayer is now passed a VFS fd +-- there is a binio virtual which is now used to wrap the VFS in a way +- that is non-intrusive +-- some blatantly bad coding practices have been corrected +- +--- +-William Pitcock +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/rix.cc audacious-plugins-3.9/src/adplug/core/rix.cc +--- audacious-plugins-3.9-orig/src/adplug/core/rix.cc 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/rix.cc 1970-01-01 01:00:00.000000000 +0100 +@@ -1,495 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2007 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * rix.cpp - Softstar RIX OPL Format Player by palxex +- * BSPAL +- */ +- +-#include +-#include "rix.h" +-#include "debug.h" +- +-const unsigned char CrixPlayer::adflag[] = {0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1}; +-const unsigned char CrixPlayer::reg_data[] = {0,1,2,3,4,5,8,9,10,11,12,13,16,17,18,19,20,21}; +-const unsigned char CrixPlayer::ad_C0_offs[] = {0,1,2,0,1,2,3,4,5,3,4,5,6,7,8,6,7,8}; +-const unsigned char CrixPlayer::modify[] = {0,3,1,4,2,5,6,9,7,10,8,11,12,15,13,16,14,17,12,\ +- 15,16,0,14,0,17,0,13,0}; +-const unsigned char CrixPlayer::bd_reg_data[] = { +- 0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x08,0x04,0x02,0x01, +- 0x00,0x01,0x01,0x03,0x0F,0x05,0x00,0x01,0x03,0x0F,0x00, +- 0x00,0x00,0x01,0x00,0x00,0x01,0x01,0x0F,0x07,0x00,0x02, +- 0x04,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x0A, +- 0x04,0x00,0x08,0x0C,0x0B,0x00,0x00,0x00,0x01,0x00,0x00, +- 0x00,0x00,0x0D,0x04,0x00,0x06,0x0F,0x00,0x00,0x00,0x00, +- 0x01,0x00,0x00,0x0C,0x00,0x0F,0x0B,0x00,0x08,0x05,0x00, +- 0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x0F,0x0B,0x00, +- 0x07,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00, +- 0x0F,0x0B,0x00,0x05,0x05,0x00,0x00,0x00,0x00,0x00,0x00, +- 0x00,0x01,0x00,0x0F,0x0B,0x00,0x07,0x05,0x00,0x00,0x00, +- 0x00,0x00,0x00}; +-unsigned char CrixPlayer::for40reg[] = {0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F, +- 0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F}; +-unsigned short CrixPlayer::mus_time = 0x4268; +- +-/*** public methods *************************************/ +- +-CPlayer *CrixPlayer::factory(Copl *newopl) +-{ +- return new CrixPlayer(newopl); +-} +- +-CrixPlayer::CrixPlayer(Copl *newopl) +- : CPlayer(newopl), flag_mkf(0), file_buffer(0), buf_addr(0) +-{ +-} +- +-CrixPlayer::~CrixPlayer() +-{ +- if(file_buffer) +- delete [] file_buffer; +-} +- +-bool CrixPlayer::load(const std::string &filename, const CFileProvider &fp) +-{ +- binistream *f = fp.open(filename); if(!f) return false; +- unsigned long i=0; +- +- if(strcasecmp(filename.substr(filename.length()-4,4).c_str(),".mkf")==0) +- { +- flag_mkf=1; +- f->seek(0); +- int offset=f->readInt(4); +- f->seek(offset); +- } +- if(f->readInt(2)!=0x55aa){ fp.close(f);return false; } +- file_buffer = new unsigned char [fp.filesize(f) + 1]; +- f->seek(0); +- while(!f->eof()) +- file_buffer[i++]=f->readInt(1); +- length=i; +- fp.close(f); +- if(!flag_mkf) +- buf_addr=file_buffer; +- rewind(0); +- return true; +-} +- +-bool CrixPlayer::update() +-{ +- int_08h_entry(); +- return !play_end; +-} +- +-void CrixPlayer::rewind(int subsong) +-{ +- I = 0; T = 0; +- mus_block = 0; +- ins_block = 0; +- rhythm = 0; +- music_on = 0; +- pause_flag = 0; +- band = 0; +- band_low = 0; +- e0_reg_flag = 0; +- bd_modify = 0; +- sustain = 0; +- play_end = 0; +- pos = index = 0; +- +- memset(f_buffer, 0, sizeof(unsigned short) * 300); +- memset(a0b0_data2, 0, sizeof(unsigned short) * 11); +- memset(a0b0_data3, 0, 18); +- memset(a0b0_data4, 0, 18); +- memset(a0b0_data5, 0, 96); +- memset(addrs_head, 0, 96); +- memset(insbuf, 0, 28 * sizeof(unsigned short)); +- memset(displace, 0, 11 * sizeof(unsigned short)); +- memset(reg_bufs, 0, 18 * sizeof(ADDT)); +- +- if(flag_mkf) +- { +- unsigned int *buf_index=(unsigned int *)file_buffer; +- int offset1=buf_index[subsong],offset2; +- while((offset2=buf_index[++subsong])==offset1); +- length=offset2-offset1+1; +- buf_addr=file_buffer+offset1; +- } +- opl->init(); +- opl->write(1,32); // go to OPL2 mode +- set_new_int(); +- data_initial(); +-} +- +-unsigned int CrixPlayer::getsubsongs() +-{ +- if(flag_mkf) +- { +- unsigned int *buf_index=(unsigned int *)file_buffer; +- int songs=buf_index[0]/4,i=0; +- for(i=0;i>3; +- for(int t=1;t<12;t++) +- f_buffer[i*12+t]=f_buffer[i*12+t-1]*1.06; +- } +- for(i=0;i<8;i++) +- for(j=0;j<12;j++) +- { +- a0b0_data5[k] = i; +- addrs_head[k] = j; +- k++; +- } +- //ad_bd_reg(); +- //ad_08_reg(); +- //for(i=0;i<9;i++) ad_a0b0_reg(i); +- e0_reg_flag = 0x20; +- //for(i=0;i<18;i++) ad_bop(0xE0+reg_data[i],0); +- //ad_bop(1,e0_reg_flag); +- return 1;//ad_test(); +-} +-/*----------------------------------------------------------*/ +-inline void CrixPlayer::ad_bop(unsigned short reg,unsigned short value) +-{ +- if(reg == 2 || reg == 3) +- AdPlug_LogWrite("switch OPL2/3 mode!\n"); +- opl->write(reg & 0xff, value & 0xff); +-} +-/*--------------------------------------------------------------*/ +-inline void CrixPlayer::int_08h_entry() +- { +- unsigned short band_sus = 1; +- while(band_sus) +- { +- if(sustain <= 0) +- { +- band_sus = rix_proc(); +- if(band_sus) sustain += band_sus; +- else +- { +- play_end=1; +- break; +- } +- } +- else +- { +- if(band_sus) sustain -= 14; /* aging */ +- break; +- } +- } +- } +-/*--------------------------------------------------------------*/ +-inline unsigned short CrixPlayer::rix_proc() +-{ +- unsigned char ctrl = 0; +- if(music_on == 0||pause_flag == 1) return 0; +- band = 0; +- while(buf_addr[I] != 0x80 && I 6) +- { +- ins_to_reg(modify[ctrl_l*2+6],insbuf,insbuf[26]); +- return; +- } +- else +- { +- ins_to_reg(12,insbuf,insbuf[26]); +- ins_to_reg(15,insbuf+13,insbuf[27]); +- return; +- } +-} +-/*--------------------------------------------------------------*/ +-inline void CrixPlayer::rix_A0_pro(unsigned short ctrl_l,unsigned short index) +-{ +- if(rhythm == 0 || ctrl_l <= 6) +- { +- prepare_a0b0(ctrl_l,index>0x3FFF?0x3FFF:index); +- ad_a0b0l_reg(ctrl_l,a0b0_data3[ctrl_l],a0b0_data4[ctrl_l]); +- } +- else return; +-} +-/*--------------------------------------------------------------*/ +-inline void CrixPlayer::prepare_a0b0(unsigned short index,unsigned short v) /* important !*/ +-{ +- short high = 0,low = 0; unsigned int res; +- int res1 = (v-0x2000)*0x19; +- if(res1 == (int)0xff) return; +- low = res1/0x2000; +- if(low < 0) +- { +- low = 0x18-low; high = (signed short)low<0?0xFFFF:0; +- res = high; res<<=16; res+=low; +- low = ((signed short)res)/(signed short)0xFFE7; +- a0b0_data2[index] = low; +- low = res; +- res = low - 0x18; +- high = (signed short)res%0x19; +- low = (signed short)res/0x19; +- if(high != 0) {low = 0x19; low = low-high;} +- } +- else +- { +- res = high = low; +- low = (signed short)res/(signed short)0x19; +- a0b0_data2[index] = low; +- res = high; +- low = (signed short)res%(signed short)0x19; +- } +- low = (signed short)low*(signed short)0x18; +- displace[index] = low; +-} +-/*--------------------------------------------------------------*/ +-inline void CrixPlayer::ad_a0b0l_reg(unsigned short index,unsigned short p2,unsigned short p3) +-{ +- unsigned short data; unsigned short i = p2+a0b0_data2[index]; +- a0b0_data4[index] = p3; +- a0b0_data3[index] = p2; +- i = ((signed short)i<=0x5F?i:0x5F); +- i = ((signed short)i>=0?i:0); +- data = f_buffer[addrs_head[i]+displace[index]/2]; +- ad_bop(0xA0+index,data); +- data = a0b0_data5[i]*4+(p3<1?0:0x20)+((data>>8)&3); +- ad_bop(0xB0+index,data); +-} +-/*--------------------------------------------------------------*/ +-inline void CrixPlayer::rix_B0_pro(unsigned short ctrl_l,unsigned short index) +-{ +- int temp = 0; +- if(rhythm == 0 || ctrl_l < 6) temp = modify[ctrl_l*2+1]; +- else +- { +- temp = ctrl_l > 6?ctrl_l*2:ctrl_l*2+1; +- temp = modify[temp+6]; +- } +- for40reg[temp] = index>0x7F?0x7F:index; +- ad_40_reg(temp); +-} +-/*--------------------------------------------------------------*/ +-inline void CrixPlayer::rix_C0_pro(unsigned short ctrl_l,unsigned short index) +-{ +- unsigned short i = index>=12?index-12:0; +- if(ctrl_l < 6 || rhythm == 0) +- { +- ad_a0b0l_reg(ctrl_l,i,1); +- return; +- } +- else +- { +- if(ctrl_l != 6) +- { +- if(ctrl_l == 8) +- { +- ad_a0b0l_reg(ctrl_l,i,0); +- ad_a0b0l_reg(7,i+7,0); +- } +- } +- else ad_a0b0l_reg(ctrl_l,i,0); +- bd_modify |= bd_reg_data[ctrl_l]; +- ad_bd_reg(); +- return; +- } +-} +-/*--------------------------------------------------------------*/ +-inline void CrixPlayer::switch_ad_bd(unsigned short index) +-{ +- +- if(rhythm == 0 || index < 6) ad_a0b0l_reg(index,a0b0_data3[index],0); +- else +- { +- bd_modify &= (~bd_reg_data[index]), +- ad_bd_reg(); +- } +-} +-/*--------------------------------------------------------------*/ +-inline void CrixPlayer::ins_to_reg(unsigned short index,unsigned short* insb,unsigned short value) +-{ +- unsigned short i; +- for(i=0;i<13;i++) reg_bufs[index].v[i] = insb[i]; +- reg_bufs[index].v[13] = value&3; +- ad_bd_reg(),ad_08_reg(), +- ad_40_reg(index),ad_C0_reg(index),ad_60_reg(index), +- ad_80_reg(index),ad_20_reg(index),ad_E0_reg(index); +-} +-/*--------------------------------------------------------------*/ +-inline void CrixPlayer::ad_E0_reg(unsigned short index) +-{ +- unsigned short data = e0_reg_flag == 0?0:(reg_bufs[index].v[13]&3); +- ad_bop(0xE0+reg_data[index],data); +-} +-/*--------------------------------------------------------------*/ +-inline void CrixPlayer::ad_20_reg(unsigned short index) +-{ +- unsigned short data = (reg_bufs[index].v[9] < 1?0:0x80); +- data += (reg_bufs[index].v[10] < 1?0:0x40); +- data += (reg_bufs[index].v[5] < 1?0:0x20); +- data += (reg_bufs[index].v[11] < 1?0:0x10); +- data += (reg_bufs[index].v[1]&0x0F); +- ad_bop(0x20+reg_data[index],data); +-} +-/*--------------------------------------------------------------*/ +-inline void CrixPlayer::ad_80_reg(unsigned short index) +-{ +- unsigned short data = (reg_bufs[index].v[7]&0x0F),temp = reg_bufs[index].v[4]; +- data |= (temp << 4); +- ad_bop(0x80+reg_data[index],data); +-} +-/*--------------------------------------------------------------*/ +-inline void CrixPlayer::ad_60_reg(unsigned short index) +-{ +- unsigned short data = reg_bufs[index].v[6]&0x0F,temp = reg_bufs[index].v[3]; +- data |= (temp << 4); +- ad_bop(0x60+reg_data[index],data); +-} +-/*--------------------------------------------------------------*/ +-inline void CrixPlayer::ad_C0_reg(unsigned short index) +-{ +- unsigned short data = reg_bufs[index].v[2]; +- if(adflag[index] == 1) return; +- data *= 2, +- data |= (reg_bufs[index].v[12] < 1?1:0); +- ad_bop(0xC0+ad_C0_offs[index],data); +-} +-/*--------------------------------------------------------------*/ +-inline void CrixPlayer::ad_40_reg(unsigned short index) +-{ +- unsigned int res = 0; +- unsigned short data = 0,temp = reg_bufs[index].v[0]; +- data = 0x3F - (0x3F & reg_bufs[index].v[8]), +- data *= for40reg[index], +- data *= 2, +- data += 0x7F, +- res = data; +- data = res/0xFE, +- data -= 0x3F, +- data = -data, +- data |= temp<<6; +- ad_bop(0x40+reg_data[index],data); +-} +-/*--------------------------------------------------------------*/ +-inline void CrixPlayer::ad_bd_reg() +-{ +- unsigned short data = rhythm < 1? 0:0x20; +- data |= bd_modify; +- ad_bop(0xBD,data); +-} +-/*--------------------------------------------------------------*/ +-inline void CrixPlayer::ad_a0b0_reg(unsigned short index) +-{ +- ad_bop(0xA0+index,0); +- ad_bop(0xB0+index,0); +-} +-/*--------------------------------------------------------------*/ +-inline void CrixPlayer::music_ctrl() +-{ +- int i; +- for(i=0;i<11;i++) +- switch_ad_bd(i); +-} +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/rix.h audacious-plugins-3.9/src/adplug/core/rix.h +--- audacious-plugins-3.9-orig/src/adplug/core/rix.h 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/rix.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,112 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2006 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * rix.h - Softstar RIX OPL Format Player by palxex +- * BSPAL +- */ +- +-#include "player.h" +- +-class CrixPlayer: public CPlayer +-{ +- public: +- static CPlayer *factory(Copl *newopl); +- +- CrixPlayer(Copl *newopl); +- ~CrixPlayer(); +- +- bool load(const std::string &filename, const CFileProvider &fp); +- bool update(); +- void rewind(int subsong); +- float getrefresh(); +- unsigned int getsubsongs(); +- +- std::string gettype() +- { return std::string("Softstar RIX OPL Music Format"); }; +- +- protected: +- typedef struct { +- unsigned char v[14]; +- } ADDT; +- +- int flag_mkf; +- unsigned char *file_buffer; +- unsigned char *buf_addr; /* rix files' f_buffer */ +- unsigned short f_buffer[300];//9C0h-C18h +- unsigned short a0b0_data2[11]; +- unsigned char a0b0_data3[18]; +- unsigned char a0b0_data4[18]; +- unsigned char a0b0_data5[96]; +- unsigned char addrs_head[96]; +- unsigned short insbuf[28]; +- unsigned short displace[11]; +- ADDT reg_bufs[18]; +- unsigned long pos,length; +- unsigned char index; +- +- static const unsigned char adflag[18]; +- static const unsigned char reg_data[18]; +- static const unsigned char ad_C0_offs[18]; +- static const unsigned char modify[28]; +- static const unsigned char bd_reg_data[124]; +- static unsigned char for40reg[18]; +- static unsigned short mus_time; +- unsigned int I,T; +- unsigned short mus_block; +- unsigned short ins_block; +- unsigned char rhythm; +- unsigned char music_on; +- unsigned char pause_flag; +- unsigned short band; +- unsigned char band_low; +- unsigned short e0_reg_flag; +- unsigned char bd_modify; +- int sustain; +- int play_end; +- +-#define ad_08_reg() ad_bop(8,0) /**/ +- inline void ad_20_reg(unsigned short); /**/ +- inline void ad_40_reg(unsigned short); /**/ +- inline void ad_60_reg(unsigned short); /**/ +- inline void ad_80_reg(unsigned short); /**/ +- inline void ad_a0b0_reg(unsigned short); /**/ +- inline void ad_a0b0l_reg(unsigned short,unsigned short,unsigned short); /**/ +- inline void ad_a0b0l_reg_(unsigned short,unsigned short,unsigned short); /**/ +- inline void ad_bd_reg(); /**/ +- inline void ad_bop(unsigned short,unsigned short); /**/ +- inline void ad_C0_reg(unsigned short); /**/ +- inline void ad_E0_reg(unsigned short); /**/ +- inline unsigned short ad_initial(); /**/ +- inline unsigned short ad_test(); /**/ +- inline void crc_trans(unsigned short,unsigned short); /**/ +- inline void data_initial(); /* done */ +- inline void init(); /**/ +- inline void ins_to_reg(unsigned short,unsigned short*,unsigned short); /**/ +- inline void int_08h_entry(); /**/ +- inline void music_ctrl(); /**/ +- inline void Pause(); /**/ +- inline void prepare_a0b0(unsigned short,unsigned short); /**/ +- inline void rix_90_pro(unsigned short); /**/ +- inline void rix_A0_pro(unsigned short,unsigned short); /**/ +- inline void rix_B0_pro(unsigned short,unsigned short); /**/ +- inline void rix_C0_pro(unsigned short,unsigned short); /**/ +- inline void rix_get_ins(); /**/ +- inline unsigned short rix_proc(); /**/ +- inline void set_new_int(); +- inline void switch_ad_bd(unsigned short); /**/ +-}; +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/rol.cc audacious-plugins-3.9/src/adplug/core/rol.cc +--- audacious-plugins-3.9-orig/src/adplug/core/rol.cc 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/rol.cc 1970-01-01 01:00:00.000000000 +0100 +@@ -1,724 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2006 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * rol.h - ROL Player by OPLx +- * +- * Visit: http://tenacity.hispeed.com/aomit/oplx/ +- */ +-#include +-#include +- +-#include "rol.h" +-#include "debug.h" +- +-int const CrolPlayer::kSizeofDataRecord = 30; +-int const CrolPlayer::kMaxTickBeat = 60; +-int const CrolPlayer::kSilenceNote = -12; +-int const CrolPlayer::kNumMelodicVoices = 9; +-int const CrolPlayer::kNumPercussiveVoices = 11; +-int const CrolPlayer::kBassDrumChannel = 6; +-int const CrolPlayer::kSnareDrumChannel = 7; +-int const CrolPlayer::kTomtomChannel = 8; +-int const CrolPlayer::kTomtomFreq = 2;//4; +-int const CrolPlayer::kSnareDrumFreq = 2;//kTomtomFreq + 7; +-float const CrolPlayer::kDefaultUpdateTme = 18.2f; +-float const CrolPlayer::kPitchFactor = 400.0f; +- +-static const unsigned char drum_table[4] = {0x14, 0x12, 0x15, 0x11}; +- +-CrolPlayer::uint16 const CrolPlayer::kNoteTable[12] = +-{ +- 340, // C +- 363, // C# +- 385, // D +- 408, // D# +- 432, // E +- 458, // F +- 485, // F# +- 514, // G +- 544, // G# +- 577, // A +- 611, // A# +- 647 // B +-}; +- +-/*** public methods **************************************/ +- +-CPlayer *CrolPlayer::factory(Copl *newopl) +-{ +- return new CrolPlayer(newopl); +-} +-//--------------------------------------------------------- +-CrolPlayer::CrolPlayer(Copl *newopl) +-: CPlayer ( newopl ) +- ,rol_header ( NULL ) +- ,mNextTempoEvent ( 0 ) +- ,mCurrTick ( 0 ) +- ,mTimeOfLastNote ( 0 ) +- ,mRefresh ( kDefaultUpdateTme ) +- ,bdRegister ( 0 ) +-{ +- int n; +- +- memset(bxRegister, 0, sizeof(bxRegister) ); +- memset(volumeCache, 0, sizeof(volumeCache) ); +- memset(freqCache, 0, sizeof(freqCache) ); +- +- for(n=0; n<11; n++) +- pitchCache[n]=1.0f; +-} +-//--------------------------------------------------------- +-CrolPlayer::~CrolPlayer() +-{ +- if( rol_header != NULL ) +- { +- delete rol_header; +- rol_header=NULL; +- } +-} +-//--------------------------------------------------------- +-bool CrolPlayer::load(const std::string &filename, const CFileProvider &fp) +-{ +- binistream *f = fp.open(filename); if(!f) return false; +- +- char *fn = new char[filename.length()+13]; +- int i; +- std::string bnk_filename; +- +- AdPlug_LogWrite("*** CrolPlayer::load(f, \"%s\") ***\n", filename.c_str()); +- strcpy(fn,filename.data()); +- for (i=strlen(fn)-1; i>=0; i--) +- if (fn[i] == '/' || fn[i] == '\\') +- break; +- strcpy(fn+i+1,"standard.bnk"); +- bnk_filename = fn; +- delete [] fn; +- AdPlug_LogWrite("bnk_filename = \"%s\"\n",bnk_filename.c_str()); +- +- rol_header = new SRolHeader; +- memset( rol_header, 0, sizeof(SRolHeader) ); +- +- rol_header->version_major = f->readInt( 2 ); +- rol_header->version_minor = f->readInt( 2 ); +- +- // Version check +- if(rol_header->version_major != 0 || rol_header->version_minor != 4) { +- AdPlug_LogWrite("Unsupported file version %d.%d or not a ROL file!\n", +- rol_header->version_major, rol_header->version_minor); +- AdPlug_LogWrite("--- CrolPlayer::load ---\n"); +- fp.close(f); +- return false; +- } +- +- f->seek( 40, binio::Add ); +- +- rol_header->ticks_per_beat = f->readInt( 2 ); +- rol_header->beats_per_measure = f->readInt( 2 ); +- rol_header->edit_scale_y = f->readInt( 2 ); +- rol_header->edit_scale_x = f->readInt( 2 ); +- +- f->seek( 1, binio::Add ); +- +- rol_header->mode = f->readInt(1); +- +- f->seek( 90+38+15, binio::Add ); +- +- rol_header->basic_tempo = f->readFloat( binio::Single ); +- +- load_tempo_events( f ); +- +- mTimeOfLastNote = 0; +- +- if( load_voice_data( f, bnk_filename, fp ) != true ) +- { +- AdPlug_LogWrite("CrolPlayer::load_voice_data(f) failed!\n"); +- AdPlug_LogWrite("--- CrolPlayer::load ---\n"); +- +- fp.close( f ); +- return false; +- } +- +- fp.close( f ); +- +- rewind( 0 ); +- AdPlug_LogWrite("--- CrolPlayer::load ---\n"); +- return true; +-} +-//--------------------------------------------------------- +-bool CrolPlayer::update() +-{ +- if( mNextTempoEvent < mTempoEvents.size() && +- mTempoEvents[mNextTempoEvent].time == mCurrTick ) +- { +- SetRefresh( mTempoEvents[mNextTempoEvent].multiplier ); +- ++mNextTempoEvent; +- } +- +- TVoiceData::iterator curr = voice_data.begin(); +- TVoiceData::iterator end = voice_data.end(); +- int voice = 0; +- +- while( curr != end ) +- { +- UpdateVoice( voice, *curr ); +- ++curr; +- ++voice; +- } +- +- ++mCurrTick; +- +- if( mCurrTick > mTimeOfLastNote ) +- { +- return false; +- } +- +- return true; +- //return ( mCurrTick > mTimeOfLastNote ) ? false : true; +-} +-//--------------------------------------------------------- +-void CrolPlayer::rewind( int subsong ) +-{ +- TVoiceData::iterator curr = voice_data.begin(); +- TVoiceData::iterator end = voice_data.end(); +- +- while( curr != end ) +- { +- CVoiceData &voice = *curr; +- +- voice.Reset(); +- ++curr; +- } +- +- memset(bxRegister, 0, sizeof(bxRegister) ); +- memset(volumeCache, 0, sizeof(volumeCache) ); +- +- bdRegister = 0; +- +- opl->init(); // initialize to melodic by default +- opl->write(1,0x20); // Enable waveform select (bit 5) +- +- if( rol_header->mode == 0 ) +- { +- opl->write( 0xbd, 0x20 ); // select rhythm mode (bit 5) +- bdRegister = 0x20; +- +- SetFreq( kTomtomChannel, 24 ); +- SetFreq( kSnareDrumChannel, 31 ); +- } +- +- mNextTempoEvent = 0; +- mCurrTick = 0; +- +- SetRefresh(1.0f); +-} +-//--------------------------------------------------------- +-inline float fmin( int const a, int const b ) +-{ +- return static_cast( a < b ? a : b ); +-} +-//--------------------------------------------------------- +-void CrolPlayer::SetRefresh( float const multiplier ) +-{ +- float const tickBeat = fmin(kMaxTickBeat, rol_header->ticks_per_beat); +- +- mRefresh = (tickBeat*rol_header->basic_tempo*multiplier) / 60.0f; +-} +-//--------------------------------------------------------- +-float CrolPlayer::getrefresh() +-{ +- return mRefresh; +-} +-//--------------------------------------------------------- +-void CrolPlayer::UpdateVoice( int const voice, CVoiceData &voiceData ) +-{ +- TNoteEvents const &nEvents = voiceData.note_events; +- +- if( nEvents.empty() || voiceData.mEventStatus & CVoiceData::kES_NoteEnd ) +- { +- return; // no note data to process, don't bother doing anything. +- } +- +- TInstrumentEvents &iEvents = voiceData.instrument_events; +- TVolumeEvents &vEvents = voiceData.volume_events; +- TPitchEvents &pEvents = voiceData.pitch_events; +- +- if( !(voiceData.mEventStatus & CVoiceData::kES_InstrEnd ) && +- iEvents[voiceData.next_instrument_event].time == mCurrTick ) +- { +- if( voiceData.next_instrument_event < iEvents.size() ) +- { +- send_ins_data_to_chip( voice, iEvents[voiceData.next_instrument_event].ins_index ); +- ++voiceData.next_instrument_event; +- } +- else +- { +- voiceData.mEventStatus |= CVoiceData::kES_InstrEnd; +- } +- } +- +- if( !(voiceData.mEventStatus & CVoiceData::kES_VolumeEnd ) && +- vEvents[voiceData.next_volume_event].time == mCurrTick ) +- { +- SVolumeEvent const &volumeEvent = vEvents[voiceData.next_volume_event]; +- +- if( voiceData.next_volume_event < vEvents.size() ) +- { +- int const volume = (int)(63.0f*(1.0f - volumeEvent.multiplier)); +- +- SetVolume( voice, volume ); +- +- ++voiceData.next_volume_event; // move to next volume event +- } +- else +- { +- voiceData.mEventStatus |= CVoiceData::kES_VolumeEnd; +- } +- } +- +- if( voiceData.mForceNote || voiceData.current_note_duration > voiceData.mNoteDuration-1 ) +- { +- if( mCurrTick != 0 ) +- { +- ++voiceData.current_note; +- } +- +- if( voiceData.current_note < nEvents.size() ) +- { +- SNoteEvent const ¬eEvent = nEvents[voiceData.current_note]; +- +- SetNote( voice, noteEvent.number ); +- voiceData.current_note_duration = 0; +- voiceData.mNoteDuration = noteEvent.duration; +- voiceData.mForceNote = false; +- } +- else +- { +- SetNote( voice, kSilenceNote ); +- voiceData.mEventStatus |= CVoiceData::kES_NoteEnd; +- return; +- } +- } +- +- if( !(voiceData.mEventStatus & CVoiceData::kES_PitchEnd ) && +- pEvents[voiceData.next_pitch_event].time == mCurrTick ) +- { +- if( voiceData.next_pitch_event < pEvents.size() ) +- { +- SetPitch(voice,pEvents[voiceData.next_pitch_event].variation); +- ++voiceData.next_pitch_event; +- } +- else +- { +- voiceData.mEventStatus |= CVoiceData::kES_PitchEnd; +- } +- } +- +- ++voiceData.current_note_duration; +-} +-//--------------------------------------------------------- +-void CrolPlayer::SetNote( int const voice, int const note ) +-{ +- if( voice < kBassDrumChannel || rol_header->mode ) +- { +- SetNoteMelodic( voice, note ); +- } +- else +- { +- SetNotePercussive( voice, note ); +- } +-} +-//--------------------------------------------------------- +-void CrolPlayer::SetNotePercussive( int const voice, int const note ) +-{ +- int const bit_pos = 4-voice+kBassDrumChannel; +- +- bdRegister &= ~( 1<write( 0xbd, bdRegister ); +- +- if( note != kSilenceNote ) +- { +- switch( voice ) +- { +- case kTomtomChannel: +- SetFreq( kSnareDrumChannel, note+7 ); +- case kBassDrumChannel: +- SetFreq( voice, note ); +- break; +- } +- +- bdRegister |= 1<write( 0xbd, bdRegister ); +- } +-} +-//--------------------------------------------------------- +-void CrolPlayer::SetNoteMelodic( int const voice, int const note ) +-{ +- opl->write( 0xb0+voice, bxRegister[voice] & ~0x20 ); +- +- if( note != kSilenceNote ) +- { +- SetFreq( voice, note, true ); +- } +-} +-//--------------------------------------------------------- +-void CrolPlayer::SetPitch(int const voice, real32 const variation) +-{ +- pitchCache[voice] = variation; +- freqCache[voice] += (uint16)((((float)freqCache[voice])*(variation-1.0f)) / kPitchFactor); +- +- opl->write(0xa0+voice,freqCache[voice] & 0xff); +-} +-//--------------------------------------------------------- +-void CrolPlayer::SetFreq( int const voice, int const note, bool const keyOn ) +-{ +- uint16 freq = kNoteTable[note%12] + ((note/12) << 10); +- freq += (uint16)((((float)freq)*(pitchCache[voice]-1.0f))/kPitchFactor); +- +- freqCache[voice] = freq; +- bxRegister[voice] = ((freq >> 8) & 0x1f); +- +- opl->write( 0xa0+voice, freq & 0xff ); +- opl->write( 0xb0+voice, bxRegister[voice] | (keyOn ? 0x20 : 0x0) ); +-} +-//--------------------------------------------------------- +-void CrolPlayer::SetVolume( int const voice, int const volume ) +-{ +- volumeCache[voice] = (volumeCache[voice] &0xc0) | volume; +- +- int const op_offset = ( voice < kSnareDrumChannel || rol_header->mode ) ? +- op_table[voice]+3 : drum_table[voice-kSnareDrumChannel]; +- +- opl->write( 0x40+op_offset, volumeCache[voice] ); +-} +-//--------------------------------------------------------- +-void CrolPlayer::send_ins_data_to_chip( int const voice, int const ins_index ) +-{ +- SRolInstrument &instrument = ins_list[ins_index].instrument; +- +- send_operator( voice, instrument.modulator, instrument.carrier ); +-} +-//--------------------------------------------------------- +-void CrolPlayer::send_operator( int const voice, SOPL2Op const &modulator, SOPL2Op const &carrier ) +-{ +- if( voice < kSnareDrumChannel || rol_header->mode ) +- { +- int const op_offset = op_table[voice]; +- +- opl->write( 0x20+op_offset, modulator.ammulti ); +- opl->write( 0x40+op_offset, modulator.ksltl ); +- opl->write( 0x60+op_offset, modulator.ardr ); +- opl->write( 0x80+op_offset, modulator.slrr ); +- opl->write( 0xc0+voice , modulator.fbc ); +- opl->write( 0xe0+op_offset, modulator.waveform ); +- +- volumeCache[voice] = (carrier.ksltl & 0xc0) | (volumeCache[voice] & 0x3f); +- +- opl->write( 0x23+op_offset, carrier.ammulti ); +- opl->write( 0x43+op_offset, volumeCache[voice] ); +- opl->write( 0x63+op_offset, carrier.ardr ); +- opl->write( 0x83+op_offset, carrier.slrr ); +-// opl->write( 0xc3+voice , carrier.fbc ); <- don't bother writing this. +- opl->write( 0xe3+op_offset, carrier.waveform ); +- } +- else +- { +- int const op_offset = drum_table[voice-kSnareDrumChannel]; +- +- volumeCache[voice] = (modulator.ksltl & 0xc0) | (volumeCache[voice] & 0x3f); +- +- opl->write( 0x20+op_offset, modulator.ammulti ); +- opl->write( 0x40+op_offset, volumeCache[voice] ); +- opl->write( 0x60+op_offset, modulator.ardr ); +- opl->write( 0x80+op_offset, modulator.slrr ); +- opl->write( 0xc0+voice , modulator.fbc ); +- opl->write( 0xe0+op_offset, modulator.waveform ); +- } +-} +-//--------------------------------------------------------- +-void CrolPlayer::load_tempo_events( binistream *f ) +-{ +- int16 const num_tempo_events = f->readInt( 2 ); +- +- mTempoEvents.reserve( num_tempo_events ); +- +- for(int i=0; ireadInt( 2 ); +- event.multiplier = f->readFloat( binio::Single ); +- mTempoEvents.push_back( event ); +- } +-} +-//--------------------------------------------------------- +-bool CrolPlayer::load_voice_data( binistream *f, std::string const &bnk_filename, const CFileProvider &fp ) +-{ +- SBnkHeader bnk_header; +- binistream *bnk_file = fp.open( bnk_filename.c_str() ); +- +- if( bnk_file ) +- { +- load_bnk_info( bnk_file, bnk_header ); +- +- int const numVoices = rol_header->mode ? kNumMelodicVoices : kNumPercussiveVoices; +- +- voice_data.reserve( numVoices ); +- for(int i=0; iseek( 15, binio::Add ); +- +- int16 const time_of_last_note = f->readInt( 2 ); +- +- if( time_of_last_note != 0 ) +- { +- TNoteEvents ¬e_events = voice.note_events; +- int16 total_duration = 0; +- +- do +- { +- SNoteEvent event; +- +- event.number = f->readInt( 2 ); +- event.duration = f->readInt( 2 ); +- +- event.number += kSilenceNote; // adding -12 +- +- note_events.push_back( event ); +- +- total_duration += event.duration; +- } while( total_duration < time_of_last_note ); +- +- if( time_of_last_note > mTimeOfLastNote ) +- { +- mTimeOfLastNote = time_of_last_note; +- } +- } +- +- f->seek( 15, binio::Add ); +-} +-//--------------------------------------------------------- +-void CrolPlayer::load_instrument_events( binistream *f, CVoiceData &voice, +- binistream *bnk_file, SBnkHeader const &bnk_header ) +-{ +- int16 const number_of_instrument_events = f->readInt( 2 ); +- +- TInstrumentEvents &instrument_events = voice.instrument_events; +- +- instrument_events.reserve( number_of_instrument_events ); +- +- for(int i=0; ireadInt( 2 ); +- f->readString( event.name, 9 ); +- +- std::string event_name = event.name; +- event.ins_index = load_rol_instrument( bnk_file, bnk_header, event_name ); +- +- instrument_events.push_back( event ); +- +- f->seek( 1+2, binio::Add ); +- } +- +- f->seek( 15, binio::Add ); +-} +-//--------------------------------------------------------- +-void CrolPlayer::load_volume_events( binistream *f, CVoiceData &voice ) +-{ +- int16 const number_of_volume_events = f->readInt( 2 ); +- +- TVolumeEvents &volume_events = voice.volume_events; +- +- volume_events.reserve( number_of_volume_events ); +- +- for(int i=0; ireadInt( 2 ); +- event.multiplier = f->readFloat( binio::Single ); +- +- volume_events.push_back( event ); +- } +- +- f->seek( 15, binio::Add ); +-} +-//--------------------------------------------------------- +-void CrolPlayer::load_pitch_events( binistream *f, CVoiceData &voice ) +-{ +- int16 const number_of_pitch_events = f->readInt( 2 ); +- +- TPitchEvents &pitch_events = voice.pitch_events; +- +- pitch_events.reserve( number_of_pitch_events ); +- +- for(int i=0; ireadInt( 2 ); +- event.variation = f->readFloat( binio::Single ); +- +- pitch_events.push_back( event ); +- } +-} +-//--------------------------------------------------------- +-bool CrolPlayer::load_bnk_info( binistream *f, SBnkHeader &header ) +-{ +- header.version_major = f->readInt(1); +- header.version_minor = f->readInt(1); +- f->readString( header.signature, 6 ); +- +- header.number_of_list_entries_used = f->readInt( 2 ); +- header.total_number_of_list_entries = f->readInt( 2 ); +- +- header.abs_offset_of_name_list = f->readInt( 4 ); +- header.abs_offset_of_data = f->readInt( 4 ); +- +- f->seek( header.abs_offset_of_name_list, binio::Set ); +- +- TInstrumentNames &ins_name_list = header.ins_name_list; +- ins_name_list.reserve( header.number_of_list_entries_used ); +- +- for(int i=0; ireadInt( 2 ); +- instrument.record_used = f->readInt(1); +- f->readString( instrument.name, 9 ); +- +- // printf("%s = #%d\n", instrument.name, i ); +- +- ins_name_list.push_back( instrument ); +- } +- +- //std::sort( ins_name_list.begin(), ins_name_list.end(), StringCompare() ); +- +- return true; +-} +-//--------------------------------------------------------- +-int CrolPlayer::load_rol_instrument( binistream *f, SBnkHeader const &header, std::string &name ) +-{ +- TInstrumentNames const &ins_name_list = header.ins_name_list; +- +- int const ins_index = get_ins_index( name ); +- +- if( ins_index != -1 ) +- { +- return ins_index; +- } +- +- typedef TInstrumentNames::const_iterator TInsIter; +- typedef std::pair TInsIterPair; +- +- TInsIterPair range = std::equal_range( ins_name_list.begin(), +- ins_name_list.end(), +- name, +- StringCompare() ); +- +- if( range.first != range.second ) +- { +- int const seekOffs = header.abs_offset_of_data + (range.first->index*kSizeofDataRecord); +- f->seek( seekOffs, binio::Set ); +- } +- +- SUsedList usedIns; +- usedIns.name = name; +- +- if( range.first != range.second ) +- { +- read_rol_instrument( f, usedIns.instrument ); +- } +- else +- { +- // set up default instrument data here +- memset( &usedIns.instrument, 0, sizeof(SRolInstrument) ); +- } +- ins_list.push_back( usedIns ); +- +- return ins_list.size()-1; +-} +-//--------------------------------------------------------- +-int CrolPlayer::get_ins_index( std::string const &name ) const +-{ +- for(unsigned int i=0; ireadInt(1); +- ins.voice_number = f->readInt(1); +- +- read_fm_operator( f, ins.modulator ); +- read_fm_operator( f, ins.carrier ); +- +- ins.modulator.waveform = f->readInt(1); +- ins.carrier.waveform = f->readInt(1); +-} +-//--------------------------------------------------------- +-void CrolPlayer::read_fm_operator( binistream *f, SOPL2Op &opl2_op ) +-{ +- SFMOperator fm_op; +- +- fm_op.key_scale_level = f->readInt(1); +- fm_op.freq_multiplier = f->readInt(1); +- fm_op.feed_back = f->readInt(1); +- fm_op.attack_rate = f->readInt(1); +- fm_op.sustain_level = f->readInt(1); +- fm_op.sustaining_sound = f->readInt(1); +- fm_op.decay_rate = f->readInt(1); +- fm_op.release_rate = f->readInt(1); +- fm_op.output_level = f->readInt(1); +- fm_op.amplitude_vibrato = f->readInt(1); +- fm_op.frequency_vibrato = f->readInt(1); +- fm_op.envelope_scaling = f->readInt(1); +- fm_op.fm_type = f->readInt(1); +- +- opl2_op.ammulti = fm_op.amplitude_vibrato << 7 | fm_op.frequency_vibrato << 6 | fm_op.sustaining_sound << 5 | fm_op.envelope_scaling << 4 | fm_op.freq_multiplier; +- opl2_op.ksltl = fm_op.key_scale_level << 6 | fm_op.output_level; +- opl2_op.ardr = fm_op.attack_rate << 4 | fm_op.decay_rate; +- opl2_op.slrr = fm_op.sustain_level << 4 | fm_op.release_rate; +- opl2_op.fbc = fm_op.feed_back << 1 | (fm_op.fm_type ^ 1); +-} +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/rol.h audacious-plugins-3.9/src/adplug/core/rol.h +--- audacious-plugins-3.9-orig/src/adplug/core/rol.h 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/rol.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,309 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2008 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * rol.h - ROL Player by OPLx +- * +- * Visit: http://tenacity.hispeed.com/aomit/oplx/ +- */ +-#ifndef H_ROLPLAYER +-#define H_ROLPLAYER +- +-#include +-#include +-#include +- +-#include "player.h" +- +-class CrolPlayer: public CPlayer +-{ +-public: +- static CPlayer *factory(Copl *newopl); +- +- CrolPlayer(Copl *newopl); +- +- ~CrolPlayer(); +- +- bool load (const std::string &filename, const CFileProvider &fp); +- bool update (); +- void rewind (int subsong); // rewinds to specified subsong +- float getrefresh(); // returns needed timer refresh rate +- +- std::string gettype() { return std::string("Adlib Visual Composer"); } +- +-private: +- typedef unsigned short uint16; +- typedef signed short int16; +-#ifdef __x86_64__ +- typedef signed int int32; +-#else +- typedef signed long int int32; +-#endif +- typedef float real32; +- +- typedef struct +- { +- uint16 version_major; +- uint16 version_minor; +- char unused0[40]; +- uint16 ticks_per_beat; +- uint16 beats_per_measure; +- uint16 edit_scale_y; +- uint16 edit_scale_x; +- char unused1; +- char mode; +- char unused2[90]; +- char filler0[38]; +- char filler1[15]; +- real32 basic_tempo; +- } SRolHeader; +- +- typedef struct +- { +- int16 time; +- real32 multiplier; +- } STempoEvent; +- +- typedef struct +- { +- int16 number; +- int16 duration; +- } SNoteEvent; +- +- typedef struct +- { +- int16 time; +- char name[9]; +- int16 ins_index; +- } SInstrumentEvent; +- +- typedef struct +- { +- int16 time; +- real32 multiplier; +- } SVolumeEvent; +- +- typedef struct +- { +- int16 time; +- real32 variation; +- } SPitchEvent; +- +- typedef std::vector TNoteEvents; +- typedef std::vector TInstrumentEvents; +- typedef std::vector TVolumeEvents; +- typedef std::vector TPitchEvents; +- +-#define bit_pos( pos ) (1< TInstrumentNames; +- +- typedef struct +- { +- char version_major; +- char version_minor; +- char signature[6]; +- uint16 number_of_list_entries_used; +- uint16 total_number_of_list_entries; +- int32 abs_offset_of_name_list; +- int32 abs_offset_of_data; +- +- TInstrumentNames ins_name_list; +- } SBnkHeader; +- +- typedef struct +- { +- unsigned char key_scale_level; +- unsigned char freq_multiplier; +- unsigned char feed_back; +- unsigned char attack_rate; +- unsigned char sustain_level; +- unsigned char sustaining_sound; +- unsigned char decay_rate; +- unsigned char release_rate; +- unsigned char output_level; +- unsigned char amplitude_vibrato; +- unsigned char frequency_vibrato; +- unsigned char envelope_scaling; +- unsigned char fm_type; +- } SFMOperator; +- +- typedef struct +- { +- unsigned char ammulti; +- unsigned char ksltl; +- unsigned char ardr; +- unsigned char slrr; +- unsigned char fbc; +- unsigned char waveform; +- } SOPL2Op; +- +- typedef struct +- { +- char mode; +- char voice_number; +- SOPL2Op modulator; +- SOPL2Op carrier; +- } SRolInstrument; +- +- typedef struct +- { +- std::string name; +- SRolInstrument instrument; +- } SUsedList; +- +- void load_tempo_events ( binistream *f ); +- bool load_voice_data ( binistream *f, std::string const &bnk_filename, const CFileProvider &fp ); +- void load_note_events ( binistream *f, CVoiceData &voice ); +- void load_instrument_events( binistream *f, CVoiceData &voice, +- binistream *bnk_file, SBnkHeader const &bnk_header ); +- void load_volume_events ( binistream *f, CVoiceData &voice ); +- void load_pitch_events ( binistream *f, CVoiceData &voice ); +- +- bool load_bnk_info ( binistream *f, SBnkHeader &header ); +- int load_rol_instrument ( binistream *f, SBnkHeader const &header, std::string &name ); +- void read_rol_instrument ( binistream *f, SRolInstrument &ins ); +- void read_fm_operator ( binistream *f, SOPL2Op &opl2_op ); +- int get_ins_index( std::string const &name ) const; +- +- void UpdateVoice( int const voice, CVoiceData &voiceData ); +- void SetNote( int const voice, int const note ); +- void SetNoteMelodic( int const voice, int const note ); +- void SetNotePercussive( int const voice, int const note ); +- void SetFreq ( int const voice, int const note, bool const keyOn=false ); +- void SetPitch ( int const voice, real32 const variation ); +- void SetVolume ( int const voice, int const volume ); +- void SetRefresh( float const multiplier ); +- void send_ins_data_to_chip( int const voice, int const ins_index ); +- void send_operator( int const voice, SOPL2Op const &modulator, SOPL2Op const &carrier ); +- +- class StringCompare +- { +- public: +- bool operator()( SInstrumentName const &lhs, SInstrumentName const &rhs ) const +- { +- return keyLess(lhs.name, rhs.name); +- } +- +- bool operator()( SInstrumentName const &lhs, std::string const &rhs ) const +- { +- return keyLess(lhs.name, rhs.c_str()); +- } +- +- bool operator()( std::string const &lhs, SInstrumentName const &rhs ) const +- { +- return keyLess(lhs.c_str(), rhs.name); +- } +- private: +- bool keyLess( const char *const lhs, const char *const rhs ) const +- { +- return strcasecmp(lhs, rhs) < 0; +- } +- }; +- +- typedef std::vector TVoiceData; +- +- SRolHeader *rol_header; +- std::vector mTempoEvents; +- TVoiceData voice_data; +- std::vector ins_list; +- +- unsigned int mNextTempoEvent; +- int mCurrTick; +- int mTimeOfLastNote; +- float mRefresh; +- unsigned char bdRegister; +- unsigned char bxRegister[9]; +- unsigned char volumeCache[11]; +- uint16 freqCache[11]; +- real32 pitchCache[11]; +- +- static int const kSizeofDataRecord; +- static int const kMaxTickBeat; +- static int const kSilenceNote; +- static int const kNumMelodicVoices; +- static int const kNumPercussiveVoices; +- static int const kBassDrumChannel; +- static int const kSnareDrumChannel; +- static int const kTomtomChannel; +- static int const kTomtomFreq; +- static int const kSnareDrumFreq; +- static float const kDefaultUpdateTme; +- static float const kPitchFactor; +- static uint16 const kNoteTable[12]; +-}; +- +-#endif +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/s3m.cc audacious-plugins-3.9/src/adplug/core/s3m.cc +--- audacious-plugins-3.9-orig/src/adplug/core/s3m.cc 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/s3m.cc 1970-01-01 01:00:00.000000000 +0100 +@@ -1,545 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2006 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * s3m.c - S3M Player by Simon Peter +- * +- * BUGS: +- * Extra Fine Slides (EEx, FEx) & Fine Vibrato (Uxy) are inaccurate +- */ +- +-#include +-#include "s3m.h" +- +-const signed char Cs3mPlayer::chnresolv[] = // S3M -> adlib channel conversion +- {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,1,2,3,4,5,6,7,8,-1,-1,-1,-1,-1,-1,-1}; +- +-const unsigned short Cs3mPlayer::notetable[12] = // S3M adlib note table +- {340,363,385,408,432,458,485,514,544,577,611,647}; +- +-const unsigned char Cs3mPlayer::vibratotab[32] = // vibrato rate table +- {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1}; +- +-/*** public methods *************************************/ +- +-CPlayer *Cs3mPlayer::factory(Copl *newopl) +-{ +- return new Cs3mPlayer(newopl); +-} +- +-Cs3mPlayer::Cs3mPlayer(Copl *newopl): CPlayer(newopl) +-{ +- int i,j,k; +- +- memset(pattern,255,sizeof(pattern)); +- memset(orders,255,sizeof(orders)); +- +- for(i=0;i<99;i++) // setup pattern +- for(j=0;j<64;j++) +- for(k=0;k<32;k++) { +- pattern[i][j][k].instrument = 0; +- pattern[i][j][k].info = 0; +- } +-} +- +-bool Cs3mPlayer::load(const std::string &filename, const CFileProvider &fp) +-{ +- binistream *f = fp.open(filename); if(!f) return false; +- unsigned short insptr[99],pattptr[99]; +- int i,row; +- unsigned char bufval,bufval2; +- unsigned short ppatlen; +- s3mheader *checkhead; +- bool adlibins=false; +- +- // file validation section +- checkhead = new s3mheader; +- load_header(f, checkhead); +- if(checkhead->kennung != 0x1a || checkhead->typ != 16 +- || checkhead->insnum > 99) { +- delete checkhead; fp.close(f); return false; +- } else +- if(strncmp(checkhead->scrm,"SCRM",4)) { +- delete checkhead; fp.close(f); return false; +- } else { // is an adlib module? +- f->seek(checkhead->ordnum, binio::Add); +- for(i = 0; i < checkhead->insnum; i++) +- insptr[i] = f->readInt(2); +- for(i=0;iinsnum;i++) { +- f->seek(insptr[i]*16); +- if(f->readInt(1) >= 2) { +- adlibins = true; +- break; +- } +- } +- delete checkhead; +- if(!adlibins) { fp.close(f); return false; } +- } +- +- // load section +- f->seek(0); // rewind for load +- load_header(f, &header); // read header +- +- // security check +- if(header.ordnum > 256 || header.insnum > 99 || header.patnum > 99) { +- fp.close(f); +- return false; +- } +- +- for(i = 0; i < header.ordnum; i++) orders[i] = f->readInt(1); // read orders +- for(i = 0; i < header.insnum; i++) insptr[i] = f->readInt(2); // instrument parapointers +- for(i = 0; i < header.patnum; i++) pattptr[i] = f->readInt(2); // pattern parapointers +- +- for(i=0;iseek(insptr[i]*16); +- inst[i].type = f->readInt(1); +- f->readString(inst[i].filename, 15); +- inst[i].d00 = f->readInt(1); inst[i].d01 = f->readInt(1); +- inst[i].d02 = f->readInt(1); inst[i].d03 = f->readInt(1); +- inst[i].d04 = f->readInt(1); inst[i].d05 = f->readInt(1); +- inst[i].d06 = f->readInt(1); inst[i].d07 = f->readInt(1); +- inst[i].d08 = f->readInt(1); inst[i].d09 = f->readInt(1); +- inst[i].d0a = f->readInt(1); inst[i].d0b = f->readInt(1); +- inst[i].volume = f->readInt(1); inst[i].dsk = f->readInt(1); +- f->ignore(2); +- inst[i].c2spd = f->readInt(4); +- f->ignore(12); +- f->readString(inst[i].name, 28); +- f->readString(inst[i].scri, 4); +- } +- +- for(i=0;iseek(pattptr[i]*16); +- ppatlen = f->readInt(2); +- unsigned long pattpos = f->pos(); +- for(row=0;(row<64) && (pattpos-pattptr[i]*16<=ppatlen);row++) +- do { +- bufval = f->readInt(1); +- if(bufval & 32) { +- bufval2 = f->readInt(1); +- pattern[i][row][bufval & 31].note = bufval2 & 15; +- pattern[i][row][bufval & 31].oct = (bufval2 & 240) >> 4; +- pattern[i][row][bufval & 31].instrument = f->readInt(1); +- } +- if(bufval & 64) +- pattern[i][row][bufval & 31].volume = f->readInt(1); +- if(bufval & 128) { +- pattern[i][row][bufval & 31].command = f->readInt(1); +- pattern[i][row][bufval & 31].info = f->readInt(1); +- } +- } while(bufval); +- } +- +- fp.close(f); +- rewind(0); +- return true; // done +-} +- +-bool Cs3mPlayer::update() +-{ +- unsigned char pattbreak=0,donote; // remember vars +- unsigned char pattnr,chan,row,info; // cache vars +- signed char realchan; +- +- // effect handling (timer dependant) +- for(realchan=0; realchan<9; realchan++) { +- info = channel[realchan].info; // fill infobyte cache +- switch(channel[realchan].fx) { +- case 11: +- case 12: if(channel[realchan].fx == 11) // dual command: H00 and Dxy +- vibrato(realchan,channel[realchan].dualinfo); +- else // dual command: G00 and Dxy +- tone_portamento(realchan,channel[realchan].dualinfo); +- case 4: if(info <= 0x0f) { // volume slide down +- if(channel[realchan].vol - info >= 0) +- channel[realchan].vol -= info; +- else +- channel[realchan].vol = 0; +- } +- if((info & 0x0f) == 0) { // volume slide up +- if(channel[realchan].vol + (info >> 4) <= 63) +- channel[realchan].vol += info >> 4; +- else +- channel[realchan].vol = 63; +- } +- setvolume(realchan); +- break; +- case 5: if(info == 0xf0 || info <= 0xe0) { // slide down +- slide_down(realchan,info); +- setfreq(realchan); +- } +- break; +- case 6: if(info == 0xf0 || info <= 0xe0) { // slide up +- slide_up(realchan,info); +- setfreq(realchan); +- } +- break; +- case 7: tone_portamento(realchan,channel[realchan].dualinfo); break; // tone portamento +- case 8: vibrato(realchan,channel[realchan].dualinfo); break; // vibrato +- case 10: channel[realchan].nextfreq = channel[realchan].freq; // arpeggio +- channel[realchan].nextoct = channel[realchan].oct; +- switch(channel[realchan].trigger) { +- case 0: channel[realchan].freq = notetable[channel[realchan].note]; break; +- case 1: if(channel[realchan].note + ((info & 0xf0) >> 4) < 12) +- channel[realchan].freq = notetable[channel[realchan].note + ((info & 0xf0) >> 4)]; +- else { +- channel[realchan].freq = notetable[channel[realchan].note + ((info & 0xf0) >> 4) - 12]; +- channel[realchan].oct++; +- } +- break; +- case 2: if(channel[realchan].note + (info & 0x0f) < 12) +- channel[realchan].freq = notetable[channel[realchan].note + (info & 0x0f)]; +- else { +- channel[realchan].freq = notetable[channel[realchan].note + (info & 0x0f) - 12]; +- channel[realchan].oct++; +- } +- break; +- } +- if(channel[realchan].trigger < 2) +- channel[realchan].trigger++; +- else +- channel[realchan].trigger = 0; +- setfreq(realchan); +- channel[realchan].freq = channel[realchan].nextfreq; +- channel[realchan].oct = channel[realchan].nextoct; +- break; +- case 21: vibrato(realchan,(unsigned char) (info / 4)); break; // fine vibrato +- } +- } +- +- if(del) { // speed compensation +- del--; +- return !songend; +- } +- +- // arrangement handling +- pattnr = orders[ord]; +- if(pattnr == 0xff || ord > header.ordnum) { // "--" end of song +- songend = 1; // set end-flag +- ord = 0; +- pattnr = orders[ord]; +- if(pattnr == 0xff) +- return !songend; +- } +- if(pattnr == 0xfe) { // "++" skip marker +- ord++; pattnr = orders[ord]; +- } +- +- // play row +- row = crow; // fill row cache +- for(chan=0;chan<32;chan++) { +- if(!(header.chanset[chan] & 128)) // resolve S3M -> AdLib channels +- realchan = chnresolv[header.chanset[chan] & 127]; +- else +- realchan = -1; // channel disabled +- if(realchan != -1) { // channel playable? +- // set channel values +- donote = 0; +- if(pattern[pattnr][row][chan].note < 14) { +- // tone portamento +- if(pattern[pattnr][row][chan].command == 7 || pattern[pattnr][row][chan].command == 12) { +- channel[realchan].nextfreq = notetable[pattern[pattnr][row][chan].note]; +- channel[realchan].nextoct = pattern[pattnr][row][chan].oct; +- } else { // normal note +- channel[realchan].note = pattern[pattnr][row][chan].note; +- channel[realchan].freq = notetable[pattern[pattnr][row][chan].note]; +- channel[realchan].oct = pattern[pattnr][row][chan].oct; +- channel[realchan].key = 1; +- donote = 1; +- } +- } +- if(pattern[pattnr][row][chan].note == 14) { // key off (is 14 here, cause note is only first 4 bits) +- channel[realchan].key = 0; +- setfreq(realchan); +- } +- if((channel[realchan].fx != 8 && channel[realchan].fx != 11) && // vibrato begins +- (pattern[pattnr][row][chan].command == 8 || pattern[pattnr][row][chan].command == 11)) { +- channel[realchan].nextfreq = channel[realchan].freq; +- channel[realchan].nextoct = channel[realchan].oct; +- } +- if(pattern[pattnr][row][chan].note >= 14) +- if((channel[realchan].fx == 8 || channel[realchan].fx == 11) && // vibrato ends +- (pattern[pattnr][row][chan].command != 8 && pattern[pattnr][row][chan].command != 11)) { +- channel[realchan].freq = channel[realchan].nextfreq; +- channel[realchan].oct = channel[realchan].nextoct; +- setfreq(realchan); +- } +- if(pattern[pattnr][row][chan].instrument) { // set instrument +- channel[realchan].inst = pattern[pattnr][row][chan].instrument - 1; +- if(inst[channel[realchan].inst].volume < 64) +- channel[realchan].vol = inst[channel[realchan].inst].volume; +- else +- channel[realchan].vol = 63; +- if(pattern[pattnr][row][chan].command != 7) +- donote = 1; +- } +- if(pattern[pattnr][row][chan].volume != 255) { +- if(pattern[pattnr][row][chan].volume < 64) // set volume +- channel[realchan].vol = pattern[pattnr][row][chan].volume; +- else +- channel[realchan].vol = 63; +- } +- channel[realchan].fx = pattern[pattnr][row][chan].command; // set command +- if(pattern[pattnr][row][chan].info) // set infobyte +- channel[realchan].info = pattern[pattnr][row][chan].info; +- +- // some commands reset the infobyte memory +- switch(channel[realchan].fx) { +- case 1: +- case 2: +- case 3: +- case 20: +- channel[realchan].info = pattern[pattnr][row][chan].info; +- break; +- } +- +- // play note +- if(donote) +- playnote(realchan); +- if(pattern[pattnr][row][chan].volume != 255) // set volume +- setvolume(realchan); +- +- // command handling (row dependant) +- info = channel[realchan].info; // fill infobyte cache +- switch(channel[realchan].fx) { +- case 1: speed = info; break; // set speed +- case 2: if(info <= ord) songend = 1; ord = info; crow = 0; pattbreak = 1; break; // jump to order +- case 3: if(!pattbreak) { crow = info; ord++; pattbreak = 1; } break; // pattern break +- case 4: if(info > 0xf0) { // fine volume down +- if(channel[realchan].vol - (info & 0x0f) >= 0) +- channel[realchan].vol -= info & 0x0f; +- else +- channel[realchan].vol = 0; +- } +- if((info & 0x0f) == 0x0f && info >= 0x1f) { // fine volume up +- if(channel[realchan].vol + ((info & 0xf0) >> 4) <= 63) +- channel[realchan].vol += (info & 0xf0) >> 4; +- else +- channel[realchan].vol = 63; +- } +- setvolume(realchan); +- break; +- case 5: if(info > 0xf0) { // fine slide down +- slide_down(realchan,(unsigned char) (info & 0x0f)); +- setfreq(realchan); +- } +- if(info > 0xe0 && info < 0xf0) { // extra fine slide down +- slide_down(realchan,(unsigned char) ((info & 0x0f) / 4)); +- setfreq(realchan); +- } +- break; +- case 6: if(info > 0xf0) { // fine slide up +- slide_up(realchan,(unsigned char) (info & 0x0f)); +- setfreq(realchan); +- } +- if(info > 0xe0 && info < 0xf0) { // extra fine slide up +- slide_up(realchan,(unsigned char) ((info & 0x0f) / 4)); +- setfreq(realchan); +- } +- break; +- case 7: // tone portamento +- case 8: +- if((channel[realchan].fx == 7 || // vibrato (remember info for dual commands) +- channel[realchan].fx == 8) && pattern[pattnr][row][chan].info) +- channel[realchan].dualinfo = info; +- break; +- case 10: channel[realchan].trigger = 0; break; // arpeggio (set trigger) +- case 19: +- if(info == 0xb0) // set loop start +- loopstart = row; +- if(info > 0xb0 && info <= 0xbf) { // pattern loop +- if(!loopcnt) { +- loopcnt = info & 0x0f; +- crow = loopstart; +- pattbreak = 1; +- } else +- if(--loopcnt > 0) { +- crow = loopstart; +- pattbreak = 1; +- } +- } +- if((info & 0xf0) == 0xe0) // patterndelay +- del = speed * (info & 0x0f) - 1; +- break; +- case 20: tempo = info; break; // set tempo +- } +- } +- } +- +- if(!del) +- del = speed - 1; // speed compensation +- if(!pattbreak) { // next row (only if no manual advance) +- crow++; +- if(crow > 63) { +- crow = 0; +- ord++; +- loopstart = 0; +- } +- } +- +- return !songend; // still playing +-} +- +-void Cs3mPlayer::rewind(int subsong) +-{ +- // set basic variables +- songend = 0; ord = 0; crow = 0; tempo = header.it; +- speed = header.is; del = 0; loopstart = 0; loopcnt = 0; +- +- memset(channel,0,sizeof(channel)); +- +- opl->init(); // reset OPL chip +- opl->write(1,32); // Go to ym3812 mode +-} +- +-std::string Cs3mPlayer::gettype() +-{ +- char filever[5]; +- +- switch(header.cwtv) { // determine version number +- case 0x1300: strcpy(filever,"3.00"); break; +- case 0x1301: strcpy(filever,"3.01"); break; +- case 0x1303: strcpy(filever,"3.03"); break; +- case 0x1320: strcpy(filever,"3.20"); break; +- default: strcpy(filever,"3.??"); +- } +- +- return (std::string("Scream Tracker ") + filever); +-} +- +-float Cs3mPlayer::getrefresh() +-{ +- return (float) (tempo / 2.5); +-} +- +-/*** private methods *************************************/ +- +-void Cs3mPlayer::load_header(binistream *f, s3mheader *h) +-{ +- int i; +- +- f->readString(h->name, 28); +- h->kennung = f->readInt(1); h->typ = f->readInt(1); +- f->ignore(2); +- h->ordnum = f->readInt(2); h->insnum = f->readInt(2); +- h->patnum = f->readInt(2); h->flags = f->readInt(2); +- h->cwtv = f->readInt(2); h->ffi = f->readInt(2); +- f->readString(h->scrm, 4); +- h->gv = f->readInt(1); h->is = f->readInt(1); h->it = f->readInt(1); +- h->mv = f->readInt(1); h->uc = f->readInt(1); h->dp = f->readInt(1); +- f->ignore(8); +- h->special = f->readInt(2); +- for(i = 0; i < 32; i++) h->chanset[i] = f->readInt(1); +-} +- +-void Cs3mPlayer::setvolume(unsigned char chan) +-{ +- unsigned char op = op_table[chan], insnr = channel[chan].inst; +- +- opl->write(0x43 + op,(int)(63-((63-(inst[insnr].d03 & 63))/63.0)*channel[chan].vol) + (inst[insnr].d03 & 192)); +- if(inst[insnr].d0a & 1) +- opl->write(0x40 + op,(int)(63-((63-(inst[insnr].d02 & 63))/63.0)*channel[chan].vol) + (inst[insnr].d02 & 192)); +-} +- +-void Cs3mPlayer::setfreq(unsigned char chan) +-{ +- opl->write(0xa0 + chan, channel[chan].freq & 255); +- if(channel[chan].key) +- opl->write(0xb0 + chan, (((channel[chan].freq & 768) >> 8) + (channel[chan].oct << 2)) | 32); +- else +- opl->write(0xb0 + chan, ((channel[chan].freq & 768) >> 8) + (channel[chan].oct << 2)); +-} +- +-void Cs3mPlayer::playnote(unsigned char chan) +-{ +- unsigned char op = op_table[chan], insnr = channel[chan].inst; +- +- opl->write(0xb0 + chan, 0); // stop old note +- +- // set instrument data +- opl->write(0x20 + op, inst[insnr].d00); +- opl->write(0x23 + op, inst[insnr].d01); +- opl->write(0x40 + op, inst[insnr].d02); +- opl->write(0x43 + op, inst[insnr].d03); +- opl->write(0x60 + op, inst[insnr].d04); +- opl->write(0x63 + op, inst[insnr].d05); +- opl->write(0x80 + op, inst[insnr].d06); +- opl->write(0x83 + op, inst[insnr].d07); +- opl->write(0xe0 + op, inst[insnr].d08); +- opl->write(0xe3 + op, inst[insnr].d09); +- opl->write(0xc0 + chan, inst[insnr].d0a); +- +- // set frequency & play +- channel[chan].key = 1; +- setfreq(chan); +-} +- +-void Cs3mPlayer::slide_down(unsigned char chan, unsigned char amount) +-{ +- if(channel[chan].freq - amount > 340) +- channel[chan].freq -= amount; +- else +- if(channel[chan].oct > 0) { +- channel[chan].oct--; +- channel[chan].freq = 684; +- } else +- channel[chan].freq = 340; +-} +- +-void Cs3mPlayer::slide_up(unsigned char chan, unsigned char amount) +-{ +- if(channel[chan].freq + amount < 686) +- channel[chan].freq += amount; +- else +- if(channel[chan].oct < 7) { +- channel[chan].oct++; +- channel[chan].freq = 341; +- } else +- channel[chan].freq = 686; +-} +- +-void Cs3mPlayer::vibrato(unsigned char chan, unsigned char info) +-{ +- unsigned char i,speed,depth; +- +- speed = info >> 4; +- depth = (info & 0x0f) / 2; +- +- for(i=0;i= 64) +- channel[chan].trigger -= 64; +- if(channel[chan].trigger >= 16 && channel[chan].trigger < 48) +- slide_down(chan,(unsigned char) (vibratotab[channel[chan].trigger - 16] / (16-depth))); +- if(channel[chan].trigger < 16) +- slide_up(chan,(unsigned char) (vibratotab[channel[chan].trigger + 16] / (16-depth))); +- if(channel[chan].trigger >= 48) +- slide_up(chan,(unsigned char) (vibratotab[channel[chan].trigger - 48] / (16-depth))); +- } +- setfreq(chan); +-} +- +-void Cs3mPlayer::tone_portamento(unsigned char chan, unsigned char info) +-{ +- if(channel[chan].freq + (channel[chan].oct << 10) < channel[chan].nextfreq + +- (channel[chan].nextoct << 10)) +- slide_up(chan,info); +- if(channel[chan].freq + (channel[chan].oct << 10) > channel[chan].nextfreq + +- (channel[chan].nextoct << 10)) +- slide_down(chan,info); +- setfreq(chan); +-} +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/s3m.h audacious-plugins-3.9/src/adplug/core/s3m.h +--- audacious-plugins-3.9-orig/src/adplug/core/s3m.h 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/s3m.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,107 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2006 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * s3m.h - AdLib S3M Player by Simon Peter +- */ +- +-#ifndef H_ADPLUG_S3M +-#define H_ADPLUG_S3M +- +-#include "player.h" +- +-class Cs3mPlayer: public CPlayer +-{ +- public: +- static CPlayer *factory(Copl *newopl); +- +- Cs3mPlayer(Copl *newopl); +- +- bool load(const std::string &filename, const CFileProvider &fp); +- bool update(); +- void rewind(int subsong); +- float getrefresh(); +- +- std::string gettype(); +- std::string gettitle() +- { return std::string(header.name); }; +- +- unsigned int getpatterns() +- { return header.patnum; }; +- unsigned int getpattern() +- { return orders[ord]; }; +- unsigned int getorders() +- { return (header.ordnum-1); }; +- unsigned int getorder() +- { return ord; }; +- unsigned int getrow() +- { return crow; }; +- unsigned int getspeed() +- { return speed; }; +- unsigned int getinstruments() +- { return header.insnum; }; +- std::string getinstrument(unsigned int n) +- { return std::string(inst[n].name); }; +- +- protected: +- struct s3mheader { +- char name[28]; // song name +- unsigned char kennung,typ,dummy[2]; +- unsigned short ordnum,insnum,patnum,flags,cwtv,ffi; +- char scrm[4]; +- unsigned char gv,is,it,mv,uc,dp,dummy2[8]; +- unsigned short special; +- unsigned char chanset[32]; +- }; +- +- struct s3minst { +- unsigned char type; +- char filename[15]; +- unsigned char d00,d01,d02,d03,d04,d05,d06,d07,d08,d09,d0a,d0b,volume,dsk,dummy[2]; +- unsigned long c2spd; +- char dummy2[12], name[28],scri[4]; +- } inst[99]; +- +- struct { +- unsigned char note,oct,instrument,volume,command,info; +- } pattern[99][64][32]; +- +- struct { +- unsigned short freq,nextfreq; +- unsigned char oct,vol,inst,fx,info,dualinfo,key,nextoct,trigger,note; +- } channel[9]; +- +- s3mheader header; +- unsigned char orders[256]; +- unsigned char crow,ord,speed,tempo,del,songend,loopstart,loopcnt; +- +- private: +- static const signed char chnresolv[]; +- static const unsigned short notetable[12]; +- static const unsigned char vibratotab[32]; +- +- void load_header(binistream *f, s3mheader *h); +- void setvolume(unsigned char chan); +- void setfreq(unsigned char chan); +- void playnote(unsigned char chan); +- void slide_down(unsigned char chan, unsigned char amount); +- void slide_up(unsigned char chan, unsigned char amount); +- void vibrato(unsigned char chan, unsigned char info); +- void tone_portamento(unsigned char chan, unsigned char info); +-}; +- +-#endif +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/sa2.cc audacious-plugins-3.9/src/adplug/core/sa2.cc +--- audacious-plugins-3.9-orig/src/adplug/core/sa2.cc 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/sa2.cc 1970-01-01 01:00:00.000000000 +0100 +@@ -1,263 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2008 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * sa2.cpp - SAdT2 Loader by Simon Peter +- * SAdT Loader by Mamiya +- */ +- +-#include +-#include +-#include +- +-#include "sa2.h" +-#include "debug.h" +- +-CPlayer *Csa2Loader::factory(Copl *newopl) +-{ +- return new Csa2Loader(newopl); +-} +- +-bool Csa2Loader::load(const std::string &filename, const CFileProvider &fp) +-{ +- binistream *f = fp.open(filename); if(!f) return false; +- struct { +- unsigned char data[11],arpstart,arpspeed,arppos,arpspdcnt; +- } insts; +- unsigned char buf; +- int i,j, k, notedis = 0; +- const unsigned char convfx[16] = {0,1,2,3,4,5,6,255,8,255,10,11,12,13,255,15}; +- unsigned char sat_type; +- enum SAT_TYPE { +- HAS_ARPEGIOLIST = (1 << 7), +- HAS_V7PATTERNS = (1 << 6), +- HAS_ACTIVECHANNELS = (1 << 5), +- HAS_TRACKORDER = (1 << 4), +- HAS_ARPEGIO = (1 << 3), +- HAS_OLDBPM = (1 << 2), +- HAS_OLDPATTERNS = (1 << 1), +- HAS_UNKNOWN127 = (1 << 0) +- }; +- +- // read header +- f->readString(header.sadt, 4); +- header.version = f->readInt(1); +- +- // file validation section +- if(strncmp(header.sadt,"SAdT",4)) { fp.close(f); return false; } +- switch(header.version) { +- case 1: +- notedis = +0x18; +- sat_type = HAS_UNKNOWN127 | HAS_OLDPATTERNS | HAS_OLDBPM; +- break; +- case 2: +- notedis = +0x18; +- sat_type = HAS_OLDPATTERNS | HAS_OLDBPM; +- break; +- case 3: +- notedis = +0x0c; +- sat_type = HAS_OLDPATTERNS | HAS_OLDBPM; +- break; +- case 4: +- notedis = +0x0c; +- sat_type = HAS_ARPEGIO | HAS_OLDPATTERNS | HAS_OLDBPM; +- break; +- case 5: +- notedis = +0x0c; +- sat_type = HAS_ARPEGIO | HAS_ARPEGIOLIST | HAS_OLDPATTERNS | HAS_OLDBPM; +- break; +- case 6: +- sat_type = HAS_ARPEGIO | HAS_ARPEGIOLIST | HAS_OLDPATTERNS | HAS_OLDBPM; +- break; +- case 7: +- sat_type = HAS_ARPEGIO | HAS_ARPEGIOLIST | HAS_V7PATTERNS; +- break; +- case 8: +- sat_type = HAS_ARPEGIO | HAS_ARPEGIOLIST | HAS_TRACKORDER; +- break; +- case 9: +- sat_type = HAS_ARPEGIO | HAS_ARPEGIOLIST | HAS_TRACKORDER | HAS_ACTIVECHANNELS; +- break; +- default: /* unknown */ +- fp.close(f); +- return false; +- } +- +- // load section +- // instruments +- for(i = 0; i < 31; i++) { +- if(sat_type & HAS_ARPEGIO) { +- for(j = 0; j < 11; j++) insts.data[j] = f->readInt(1); +- insts.arpstart = f->readInt(1); +- insts.arpspeed = f->readInt(1); +- insts.arppos = f->readInt(1); +- insts.arpspdcnt = f->readInt(1); +- inst[i].arpstart = insts.arpstart; +- inst[i].arpspeed = insts.arpspeed; +- inst[i].arppos = insts.arppos; +- inst[i].arpspdcnt = insts.arpspdcnt; +- } else { +- for(j = 0; j < 11; j++) insts.data[j] = f->readInt(1); +- inst[i].arpstart = 0; +- inst[i].arpspeed = 0; +- inst[i].arppos = 0; +- inst[i].arpspdcnt = 0; +- } +- for(j=0;j<11;j++) +- inst[i].data[j] = insts.data[j]; +- inst[i].misc = 0; +- inst[i].slide = 0; +- } +- +- // instrument names +- for(i = 0; i < 29; i++) f->readString(instname[i], 17); +- +- f->ignore(3); // dummy bytes +- for(i = 0; i < 128; i++) order[i] = f->readInt(1); // pattern orders +- if(sat_type & HAS_UNKNOWN127) f->ignore(127); +- +- // infos +- nop = f->readInt(2); length = f->readInt(1); restartpos = f->readInt(1); +- +- // bpm +- bpm = f->readInt(2); +- if(sat_type & HAS_OLDBPM) { +- bpm = bpm * 125 / 50; // cps -> bpm +- } +- +- if(sat_type & HAS_ARPEGIOLIST) { +- init_specialarp(); +- for(i = 0; i < 256; i++) arplist[i] = f->readInt(1); // arpeggio list +- for(i = 0; i < 256; i++) arpcmd[i] = f->readInt(1); // arpeggio commands +- } +- +- for(i=0;i<64;i++) { // track orders +- for(j=0;j<9;j++) { +- if(sat_type & HAS_TRACKORDER) +- trackord[i][j] = f->readInt(1); +- else +- { +- trackord[i][j] = i * 9 + j; +- } +- } +- } +- +- if(sat_type & HAS_ACTIVECHANNELS) +- activechan = f->readInt(2) << 16; // active channels +- +- AdPlug_LogWrite("Csa2Loader::load(\"%s\"): sat_type = %x, nop = %d, " +- "length = %lu, restartpos = %lu, activechan = %lx, bpm = %d\n", +- filename.c_str(), sat_type, nop, length, restartpos, activechan, bpm); +- +- // track data +- if(sat_type & HAS_OLDPATTERNS) { +- i = 0; +- while(!f->ateof()) { +- for(j=0;j<64;j++) { +- for(k=0;k<9;k++) { +- buf = f->readInt(1); +- tracks[i+k][j].note = buf ? (buf + notedis) : 0; +- tracks[i+k][j].inst = f->readInt(1); +- tracks[i+k][j].command = convfx[f->readInt(1) & 0xf]; +- tracks[i+k][j].param1 = f->readInt(1); +- tracks[i+k][j].param2 = f->readInt(1); +- } +- } +- i+=9; +- } +- } else +- if(sat_type & HAS_V7PATTERNS) { +- i = 0; +- while(!f->ateof()) { +- for(j=0;j<64;j++) { +- for(k=0;k<9;k++) { +- buf = f->readInt(1); +- tracks[i+k][j].note = buf >> 1; +- tracks[i+k][j].inst = (buf & 1) << 4; +- buf = f->readInt(1); +- tracks[i+k][j].inst += buf >> 4; +- tracks[i+k][j].command = convfx[buf & 0x0f]; +- buf = f->readInt(1); +- tracks[i+k][j].param1 = buf >> 4; +- tracks[i+k][j].param2 = buf & 0x0f; +- } +- } +- i+=9; +- } +- } else { +- i = 0; +- while(!f->ateof()) { +- for(j=0;j<64;j++) { +- buf = f->readInt(1); +- tracks[i][j].note = buf >> 1; +- tracks[i][j].inst = (buf & 1) << 4; +- buf = f->readInt(1); +- tracks[i][j].inst += buf >> 4; +- tracks[i][j].command = convfx[buf & 0x0f]; +- buf = f->readInt(1); +- tracks[i][j].param1 = buf >> 4; +- tracks[i][j].param2 = buf & 0x0f; +- } +- i++; +- } +- } +- fp.close(f); +- +- // fix instrument names +- for(i=0;i<29;i++) +- for(j=0;j<17;j++) +- if(!instname[i][j]) +- instname[i][j] = ' '; +- +- rewind(0); // rewind module +- return true; +-} +- +-std::string Csa2Loader::gettype() +-{ +- char tmpstr[40]; +- +- sprintf(tmpstr,"Surprise! Adlib Tracker 2 (version %d)",header.version); +- return std::string(tmpstr); +-} +- +-std::string Csa2Loader::gettitle() +-{ +- char bufinst[29*17],buf[18]; +- int i,ptr; +- +- // parse instrument names for song name +- memset(bufinst,'\0',29*17); +- for(i=0;i<29;i++) { +- buf[16] = ' '; buf[17] = '\0'; +- memcpy(buf,instname[i]+1,16); +- for(ptr=16;ptr>0;ptr--) +- if(buf[ptr] == ' ') +- buf[ptr] = '\0'; +- else { +- if(ptr<16) +- buf[ptr+1] = ' '; +- break; +- } +- strcat(bufinst,buf); +- } +- +- if(strchr(bufinst,'"')) +- return std::string(bufinst,strchr(bufinst,'"')-bufinst+1,strrchr(bufinst,'"')-strchr(bufinst,'"')-1); +- else +- return std::string(); +-} +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/sa2.h audacious-plugins-3.9/src/adplug/core/sa2.h +--- audacious-plugins-3.9-orig/src/adplug/core/sa2.h 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/sa2.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,55 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2003 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * sa2.h - SAdT2 Loader by Simon Peter +- * SAdT Loader by Mamiya +- */ +- +-#include "protrack.h" +- +-class Csa2Loader: public CmodPlayer +-{ +-public: +- static CPlayer *factory(Copl *newopl); +- +- Csa2Loader(Copl *newopl) +- : CmodPlayer(newopl) +- { } +- +- bool load(const std::string &filename, const CFileProvider &fp); +- +- std::string gettype(); +- std::string gettitle(); +- unsigned int getinstruments() +- { return 31; } +- std::string getinstrument(unsigned int n) +- { +- if(n < 29) +- return std::string(instname[n],1,16); +- else +- return std::string("-broken-"); +- } +- +-private: +- struct sa2header { +- char sadt[4]; +- unsigned char version; +- } header; +- +- char instname[29][17]; +-}; +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/silentopl.h audacious-plugins-3.9/src/adplug/core/silentopl.h +--- audacious-plugins-3.9-orig/src/adplug/core/silentopl.h 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/silentopl.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,29 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2005 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * silentopl.h - Silent OPL device, by Simon Peter (dn.tlp@gmx.net) +- */ +- +-#include "opl.h" +- +-class CSilentopl: public Copl +-{ +-public: +- void write(int reg, int val) {} +- void init() {} +-}; +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/sng.cc audacious-plugins-3.9/src/adplug/core/sng.cc +--- audacious-plugins-3.9-orig/src/adplug/core/sng.cc 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/sng.cc 1970-01-01 01:00:00.000000000 +0100 +@@ -1,85 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2002 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * sng.cpp - SNG Player by Simon Peter +- */ +- +-#include +-#include "sng.h" +- +-CPlayer *CsngPlayer::factory(Copl *newopl) +-{ +- return new CsngPlayer(newopl); +-} +- +-bool CsngPlayer::load(const std::string &filename, const CFileProvider &fp) +-{ +- binistream *f = fp.open(filename); if(!f) return false; +- int i; +- +- // load header +- f->readString(header.id, 4); +- header.length = f->readInt(2); header.start = f->readInt(2); +- header.loop = f->readInt(2); header.delay = f->readInt(1); +- header.compressed = f->readInt(1) ? true : false; +- +- // file validation section +- if(strncmp(header.id,"ObsM",4)) { fp.close(f); return false; } +- +- // load section +- header.length /= 2; header.start /= 2; header.loop /= 2; +- data = new Sdata [header.length]; +- for(i = 0; i < header.length; i++) { +- data[i].val = f->readInt(1); +- data[i].reg = f->readInt(1); +- } +- +- rewind(0); +- fp.close(f); +- return true; +-} +- +-bool CsngPlayer::update() +-{ +- if(header.compressed && del) { +- del--; +- return !songend; +- } +- +- while(data[pos].reg) { +- opl->write(data[pos].reg, data[pos].val); +- pos++; +- if(pos >= header.length) { +- songend = true; +- pos = header.loop; +- } +- } +- +- if(!header.compressed) +- opl->write(data[pos].reg, data[pos].val); +- +- if(data[pos].val) { del = data[pos].val - 1; pos++; } +- if(pos >= header.length) { songend = true; pos = header.loop; } +- return !songend; +-} +- +-void CsngPlayer::rewind(int subsong) +-{ +- pos = header.start; del = header.delay; songend = false; +- opl->init(); opl->write(1,32); // go to OPL2 mode +-} +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/sng.h audacious-plugins-3.9/src/adplug/core/sng.h +--- audacious-plugins-3.9-orig/src/adplug/core/sng.h 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/sng.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,64 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2002 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * sng.h - SNG Player by Simon Peter +- */ +- +-#ifndef H_ADPLUG_SNGPLAYER +-#define H_ADPLUG_SNGPLAYER +- +-#include "player.h" +- +-class CsngPlayer: public CPlayer +-{ +-public: +- static CPlayer *factory(Copl *newopl); +- +- CsngPlayer(Copl *newopl) +- : CPlayer(newopl), data(0) +- { }; +- ~CsngPlayer() +- { if(data) delete [] data; }; +- +- bool load(const std::string &filename, const CFileProvider &fp); +- bool update(); +- void rewind(int subsong); +- float getrefresh() +- { return 70.0f; }; +- +- std::string gettype() +- { return std::string("SNG File Format"); }; +- +-protected: +- struct { +- char id[4]; +- unsigned short length,start,loop; +- unsigned char delay; +- bool compressed; +- } header; +- +- struct Sdata { +- unsigned char val,reg; +- } *data; +- +- unsigned char del; +- unsigned short pos; +- bool songend; +-}; +- +-#endif +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/temuopl.cc audacious-plugins-3.9/src/adplug/core/temuopl.cc +--- audacious-plugins-3.9-orig/src/adplug/core/temuopl.cc 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/temuopl.cc 1970-01-01 01:00:00.000000000 +0100 +@@ -1,75 +0,0 @@ +-/* +- * AdPlug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2004 Simon Peter , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * temuopl.cpp - Tatsuyuki Satoh's OPL2 emulator, by Simon Peter +- */ +- +-#include "temuopl.h" +- +-CTemuopl::CTemuopl(int rate, bool bit16, bool usestereo) +- : use16bit(bit16), stereo(usestereo) +-{ +- opl = OPLCreate(OPL_TYPE_YM3812, 3579545, rate); +-} +- +-CTemuopl::~CTemuopl() +-{ +- OPLDestroy(opl); +-} +- +-void CTemuopl::update(short *buf, int samples) +-{ +- int i; +- +- if(use16bit) { +- YM3812UpdateOne(opl,buf,samples); +- +- if(stereo) +- for(i=samples-1;i>=0;i--) { +- buf[i*2] = buf[i]; +- buf[i*2+1] = buf[i]; +- } +- } else { +- short *tempbuf = new short[stereo ? samples*2 : samples]; +- int i; +- +- YM3812UpdateOne(opl,tempbuf,samples); +- +- if(stereo) +- for(i=samples-1;i>=0;i--) { +- tempbuf[i*2] = tempbuf[i]; +- tempbuf[i*2+1] = tempbuf[i]; +- } +- +- for(i=0;i<(stereo ? samples*2 : samples);i++) +- ((char *)buf)[i] = (tempbuf[i] >> 8) ^ 0x80; +- +- delete [] tempbuf; +- } +-} +- +-void CTemuopl::write(int reg, int val) +-{ +- OPLWrite(opl,0,reg); +- OPLWrite(opl,1,val); +-} +- +-void CTemuopl::init() +-{ +- OPLResetChip(opl); +-} +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/temuopl.h audacious-plugins-3.9/src/adplug/core/temuopl.h +--- audacious-plugins-3.9-orig/src/adplug/core/temuopl.h 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/temuopl.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,45 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2004 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * temuopl.h - Tatsuyuki Satoh's OPL2 emulator, by Simon Peter +- */ +- +-#ifndef H_ADPLUG_TEMUOPL +-#define H_ADPLUG_TEMUOPL +- +-#include "opl.h" +-#include "fmopl.h" +- +-class CTemuopl: public Copl +-{ +- public: +- CTemuopl(int rate, bool bit16, bool usestereo); // rate = sample rate +- virtual ~CTemuopl(); +- +- void update(short *buf, int samples); // fill buffer +- +- // template methods +- void write(int reg, int val); +- void init(); +- +- private: +- bool use16bit,stereo; +- FM_OPL *opl; // holds emulator data +-}; +- +-#endif +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/u6m.cc audacious-plugins-3.9/src/adplug/core/u6m.cc +--- audacious-plugins-3.9-orig/src/adplug/core/u6m.cc 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/u6m.cc 1970-01-01 01:00:00.000000000 +0100 +@@ -1,934 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2006 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * u6m.cpp - Ultima 6 Music Player by Marc Winterrowd. +- * This code extends the Adlib Winamp plug-in by Simon Peter +- */ +- +-#include "u6m.h" +- +-// Makes security checks on output buffer before writing +-#define SAVE_OUTPUT_ROOT(c, d, p) \ +-if(p < d.size) \ +- output_root(c, d.data, p); \ +-else \ +- return false; +- +-CPlayer *Cu6mPlayer::factory(Copl *newopl) +-{ +- return new Cu6mPlayer(newopl); +-} +- +-bool Cu6mPlayer::load(const std::string &filename, const CFileProvider &fp) +-{ +- // file validation section +- // this section only checks a few *necessary* conditions +- unsigned long filesize, decompressed_filesize; +- binistream *f; +- +- f = fp.open(filename); if(!f) return false; +- filesize = fp.filesize(f); +- +- if (filesize >= 6) +- { +- // check if the file has a valid pseudo-header +- unsigned char pseudo_header[6]; +- f->readString((char *)pseudo_header, 6); +- decompressed_filesize = pseudo_header[0] + (pseudo_header[1] << 8); +- +- if (!( (pseudo_header[2]==0) && (pseudo_header[3]==0) && +- (pseudo_header[4] + ((pseudo_header[5] & 0x1)<<8) == 0x100) && +- (decompressed_filesize > (filesize-4)) )) +- { +- fp.close(f); +- return(false); +- } +- } +- else +- { +- fp.close(f); +- return(false); +- } +- +- // load section +- song_data = new unsigned char[decompressed_filesize]; +- unsigned char* compressed_song_data = new unsigned char[filesize-3]; +- +- f->seek(4); +- f->readString((char *)compressed_song_data, filesize - 4); +- fp.close(f); +- +- // attempt to decompress the song data +- // if unsuccessful, deallocate song_data[] on the spot, and return(false) +- data_block source, destination; +- source.size = filesize-4; +- source.data = compressed_song_data; +- destination.size = decompressed_filesize; +- destination.data = song_data; +- +- if (!lzw_decompress(source,destination)) +- { +- delete[] compressed_song_data; +- delete[] song_data; +- return(false); +- } +- +- // deallocation section +- delete[] compressed_song_data; +- +- rewind(0); +- return (true); +-} +- +- +-bool Cu6mPlayer::update() +-{ +- if (!driver_active) +- { +- driver_active = true; +- dec_clip(read_delay); +- if (read_delay == 0) +- { +- command_loop(); +- } +- +- // on all Adlib channels: freq slide/vibrato, mute factor slide +- for (int i = 0; i < 9; i++) +- { +- if (channel_freq_signed_delta[i]!=0) +- // frequency slide + mute factor slide +- { +- // freq slide +- freq_slide(i); +- +- // mute factor slide +- if (carrier_mf_signed_delta[i]!=0) +- { +- mf_slide(i); +- } +- } +- else +- // vibrato + mute factor slide +- { +- // vibrato +- if ((vb_multiplier[i]!=0) && ((channel_freq[i].hi & 0x20)==0x20)) +- { +- vibrato(i); +- } +- +- // mute factor slide +- if (carrier_mf_signed_delta[i]!=0) +- { +- mf_slide(i); +- } +- } +- } +- +- driver_active = false; +- } +- +- return !songend; +-} +- +- +-void Cu6mPlayer::rewind(int subsong) +-{ +- played_ticks = 0; +- songend = false; +- +- // set the driver's internal variables +- byte_pair freq_word = {0,0}; +- +- driver_active = false; +- song_pos = 0; +- loop_position = 0; // position of the loop point +- read_delay = 0; // delay (in timer ticks) before further song data is read +- +- for (int i = 0; i < 9; i++) +- { +- // frequency +- channel_freq_signed_delta[i] = 0; +- channel_freq[i] = freq_word; // Adlib freq settings for each channel +- +- // vibrato ("vb") +- vb_current_value[i] = 0; +- vb_double_amplitude[i] = 0; +- vb_multiplier[i] = 0; +- vb_direction_flag[i] = 0; +- +- // mute factor ("mf") == ~(volume) +- carrier_mf[i] = 0; +- carrier_mf_signed_delta[i] = 0; +- carrier_mf_mod_delay_backup[i] = 0; +- carrier_mf_mod_delay[i] = 0; +- } +- +- while (!subsong_stack.empty()) // empty subsong stack +- subsong_stack.pop(); +- +- opl->init(); +- out_adlib(1,32); // go to OPL2 mode +-} +- +- +-float Cu6mPlayer::getrefresh() +-{ +- return ((float)60); // the Ultima 6 music driver expects to be called at 60 Hz +-} +- +- +-// ============================================================================================ +-// +-// +-// Functions called by load() +-// +-// +-// ============================================================================================ +- +- +-// decompress from memory to memory +-bool Cu6mPlayer::lzw_decompress(Cu6mPlayer::data_block source, Cu6mPlayer::data_block dest) +-{ +- bool end_marker_reached = false; +- int codeword_size = 9; +- long bits_read = 0; +- int next_free_codeword = 0x102; +- int dictionary_size = 0x200; +- MyDict dictionary = MyDict(); +- std::stack root_stack; +- +- long bytes_written = 0; +- +- int cW; +- int pW = 0; +- unsigned char C; +- +- while (!end_marker_reached) +- { +- cW = get_next_codeword(bits_read, source.data, codeword_size); +- switch (cW) +- { +- // re-init the dictionary +- case 0x100: +- codeword_size = 9; +- next_free_codeword = 0x102; +- dictionary_size = 0x200; +- dictionary.reset(); +- cW = get_next_codeword(bits_read, source.data, codeword_size); +- SAVE_OUTPUT_ROOT((unsigned char)cW, dest, bytes_written); +- break; +- // end of compressed file has been reached +- case 0x101: +- end_marker_reached = true; +- break; +- // (cW <> 0x100) && (cW <> 0x101) +- default: +- if (cW < next_free_codeword) // codeword is already in the dictionary +- { +- // create the string associated with cW (on the stack) +- get_string(cW,dictionary,root_stack); +- C = root_stack.top(); +- // output the string represented by cW +- while (!root_stack.empty()) +- { +- SAVE_OUTPUT_ROOT(root_stack.top(), dest, bytes_written); +- root_stack.pop(); +- } +- // add pW+C to the dictionary +- dictionary.add(C,pW); +- +- next_free_codeword++; +- if (next_free_codeword >= dictionary_size) +- { +- if (codeword_size < max_codeword_length) +- { +- codeword_size += 1; +- dictionary_size *= 2; +- } +- } +- } +- else // codeword is not yet defined +- { +- // create the string associated with pW (on the stack) +- get_string(pW,dictionary,root_stack); +- C = root_stack.top(); +- // output the string represented by pW +- while (!root_stack.empty()) +- { +- SAVE_OUTPUT_ROOT(root_stack.top(), dest, bytes_written); +- root_stack.pop(); +- } +- // output the char C +- SAVE_OUTPUT_ROOT(C, dest, bytes_written); +- +- // the new dictionary entry must correspond to cW +- // if it doesn't, something is wrong with the lzw-compressed data. +- if (cW != next_free_codeword) +- { +- /* printf("cW != next_free_codeword!\n"); +- exit(-1); */ +- return false; +- } +- // add pW+C to the dictionary +- dictionary.add(C,pW); +- +- next_free_codeword++; +- if (next_free_codeword >= dictionary_size) +- { +- if (codeword_size < max_codeword_length) +- { +- codeword_size += 1; +- dictionary_size *= 2; +- } +- } +- }; +- break; +- } +- // shift roles - the current cW becomes the new pW +- pW = cW; +- } +- +- return(true); // indicate successful decompression +-} +- +- +-// -------------------- +-// Additional functions +-// -------------------- +- +- +-// Read the next code word from the source buffer +-int Cu6mPlayer::get_next_codeword (long& bits_read, unsigned char *source, int codeword_size) +-{ +- unsigned char b0,b1,b2; +- int codeword; +- +- b0 = source[bits_read/8]; +- b1 = source[bits_read/8+1]; +- b2 = source[bits_read/8+2]; +- +- codeword = ((b2 << 16) + (b1 << 8) + b0); +- codeword = codeword >> (bits_read % 8); +- switch (codeword_size) +- { +- case 0x9: +- codeword = codeword & 0x1ff; +- break; +- case 0xa: +- codeword = codeword & 0x3ff; +- break; +- case 0xb: +- codeword = codeword & 0x7ff; +- break; +- case 0xc: +- codeword = codeword & 0xfff; +- break; +- default: +- codeword = -1; // indicates that an error has occurred +- break; +- } +- +- bits_read += codeword_size; +- return (codeword); +-} +- +- +-// output a root to memory +-void Cu6mPlayer::output_root(unsigned char root, unsigned char *destination, long& position) +-{ +- destination[position] = root; +- position++; +-} +- +- +-// output the string represented by a codeword +-void Cu6mPlayer::get_string(int codeword, Cu6mPlayer::MyDict& dictionary, std::stack& root_stack) +-{ +- unsigned char root; +- int current_codeword; +- +- current_codeword = codeword; +- +- while (current_codeword > 0xff) +- { +- root = dictionary.get_root(current_codeword); +- current_codeword = dictionary.get_codeword(current_codeword); +- root_stack.push(root); +- } +- +- // push the root at the leaf +- root_stack.push((unsigned char)current_codeword); +-} +- +- +-// ============================================================================================ +-// +-// +-// Functions called by update() +-// +-// +-// ============================================================================================ +- +- +-// This function reads the song data and executes the embedded commands. +-void Cu6mPlayer::command_loop() +-{ +- unsigned char command_byte; // current command byte +- int command_nibble_hi; // command byte, bits 4-7 +- int command_nibble_lo; // command byte, bite 0-3 +- bool repeat_loop = true; // +- +- do +- { +- // extract low and high command nibbles +- command_byte = read_song_byte(); // implicitly increments song_pos +- command_nibble_hi = command_byte >> 4; +- command_nibble_lo = command_byte & 0xf; +- +- switch (command_nibble_hi) +- { +- case 0x0: command_0(command_nibble_lo); break; +- case 0x1: command_1(command_nibble_lo); break; +- case 0x2: command_2(command_nibble_lo); break; +- case 0x3: command_3(command_nibble_lo); break; +- case 0x4: command_4(command_nibble_lo); break; +- case 0x5: command_5(command_nibble_lo); break; +- case 0x6: command_6(command_nibble_lo); break; +- case 0x7: command_7(command_nibble_lo); break; +- case 0x8: +- switch (command_nibble_lo) +- { +- case 1: command_81(); break; +- case 2: command_82(); repeat_loop = false; break; +- case 3: command_83(); break; +- case 5: command_85(); break; +- case 6: command_86(); break; +- default: break; // maybe generate an error? +- } +- break; +- case 0xE: command_E(); break; +- case 0xF: command_F(); break; +- default: break; // maybe generate an error? +- } +- +- } while (repeat_loop); +-} +- +- +-// -------------------------------------------------------- +-// The commands supported by the U6 music file format +-// -------------------------------------------------------- +- +-// ---------------------------------------- +-// Set octave and frequency, note off +-// Format: 0c nn +-// c = channel, nn = packed Adlib frequency +-// ---------------------------------------- +-void Cu6mPlayer::command_0(int channel) +-{ +- unsigned char freq_byte; +- byte_pair freq_word; +- +- freq_byte = read_song_byte(); +- freq_word = expand_freq_byte(freq_byte); +- set_adlib_freq(channel,freq_word); +-} +- +- +-// --------------------------------------------------- +-// Set octave and frequency, old note off, new note on +-// Format: 1c nn +-// c = channel, nn = packed Adlib frequency +-// --------------------------------------------------- +-void Cu6mPlayer::command_1(int channel) +-{ +- unsigned char freq_byte; +- byte_pair freq_word; +- +- vb_direction_flag[channel] = 0; +- vb_current_value[channel] = 0; +- +- freq_byte = read_song_byte(); +- freq_word = expand_freq_byte(freq_byte); +- set_adlib_freq(channel,freq_word); +- +- freq_word.hi = freq_word.hi | 0x20; // note on +- set_adlib_freq(channel,freq_word); +-} +- +- +-// ---------------------------------------- +-// Set octave and frequency, note on +-// Format: 2c nn +-// c = channel, nn = packed Adlib frequency +-// ---------------------------------------- +-void Cu6mPlayer::command_2(int channel) +-{ +- unsigned char freq_byte; +- byte_pair freq_word; +- +- freq_byte = read_song_byte(); +- freq_word = expand_freq_byte(freq_byte); +- freq_word.hi = freq_word.hi | 0x20; // note on +- set_adlib_freq(channel,freq_word); +-} +- +- +-// -------------------------------------- +-// Set "carrier mute factor"==not(volume) +-// Format: 3c nn +-// c = channel, nn = mute factor +-// -------------------------------------- +-void Cu6mPlayer::command_3(int channel) +-{ +- unsigned char mf_byte; +- +- carrier_mf_signed_delta[channel] = 0; +- mf_byte = read_song_byte(); +- set_carrier_mf(channel,mf_byte); +-} +- +- +-// ---------------------------------------- +-// set "modulator mute factor"==not(volume) +-// Format: 4c nn +-// c = channel, nn = mute factor +-// ---------------------------------------- +-void Cu6mPlayer::command_4(int channel) +-{ +- unsigned char mf_byte; +- +- mf_byte = read_song_byte(); +- set_modulator_mf(channel,mf_byte); +-} +- +- +-// -------------------------------------------- +-// Set portamento (pitch slide) +-// Format: 5c nn +-// c = channel, nn = signed channel pitch delta +-// -------------------------------------------- +-void Cu6mPlayer::command_5(int channel) +-{ +- channel_freq_signed_delta[channel] = read_signed_song_byte(); +-} +- +- +-// -------------------------------------------- +-// Set vibrato paramters +-// Format: 6c mn +-// c = channel +-// m = vibrato double amplitude +-// n = vibrato multiplier +-// -------------------------------------------- +-void Cu6mPlayer::command_6(int channel) +-{ +- unsigned char vb_parameters; +- +- vb_parameters = read_song_byte(); +- vb_double_amplitude[channel] = vb_parameters >> 4; // high nibble +- vb_multiplier[channel] = vb_parameters & 0xF; // low nibble +-} +- +- +-// ---------------------------------------- +-// Assign Adlib instrument to Adlib channel +-// Format: 7c nn +-// c = channel, nn = instrument number +-// ---------------------------------------- +-void Cu6mPlayer::command_7(int channel) +-{ +- int instrument_offset = instrument_offsets[read_song_byte()]; +- out_adlib_opcell(channel, false, 0x20, *(song_data + instrument_offset+0)); +- out_adlib_opcell(channel, false, 0x40, *(song_data + instrument_offset+1)); +- out_adlib_opcell(channel, false, 0x60, *(song_data + instrument_offset+2)); +- out_adlib_opcell(channel, false, 0x80, *(song_data + instrument_offset+3)); +- out_adlib_opcell(channel, false, 0xE0, *(song_data + instrument_offset+4)); +- out_adlib_opcell(channel, true, 0x20, *(song_data + instrument_offset+5)); +- out_adlib_opcell(channel, true, 0x40, *(song_data + instrument_offset+6)); +- out_adlib_opcell(channel, true, 0x60, *(song_data + instrument_offset+7)); +- out_adlib_opcell(channel, true, 0x80, *(song_data + instrument_offset+8)); +- out_adlib_opcell(channel, true, 0xE0, *(song_data + instrument_offset+9)); +- out_adlib(0xC0+channel, *(song_data + instrument_offset+10)); +-} +- +- +-// ------------------------------------------- +-// Branch to a new subsong +-// Format: 81 nn aa bb +-// nn == number of times to repeat the subsong +-// aa == subsong offset (low byte) +-// bb == subsong offset (high byte) +-// ------------------------------------------- +-void Cu6mPlayer::command_81() +-{ +- subsong_info new_ss_info; +- +- new_ss_info.subsong_repetitions = read_song_byte(); +- new_ss_info.subsong_start = read_song_byte(); new_ss_info.subsong_start += read_song_byte() << 8; +- new_ss_info.continue_pos = song_pos; +- +- subsong_stack.push(new_ss_info); +- song_pos = new_ss_info.subsong_start; +-} +- +- +-// ------------------------------------------------------------ +-// Stop interpreting commands for this timer tick +-// Format: 82 nn +-// nn == delay (in timer ticks) until further data will be read +-// ------------------------------------------------------------ +-void Cu6mPlayer::command_82() +-{ +- read_delay = read_song_byte(); +-} +- +- +-// ----------------------------- +-// Adlib instrument data follows +-// Format: 83 nn <11 bytes> +-// nn == instrument number +-// ----------------------------- +-void Cu6mPlayer::command_83() +-{ +- unsigned char instrument_number = read_song_byte(); +- instrument_offsets[instrument_number] = song_pos; +- song_pos += 11; +-} +- +- +-// ---------------------------------------------- +-// Set -1 mute factor slide (upward volume slide) +-// Format: 85 cn +-// c == channel +-// n == slide delay +-// ---------------------------------------------- +-void Cu6mPlayer::command_85() +-{ +- unsigned char data_byte = read_song_byte(); +- int channel = data_byte >> 4; // high nibble +- unsigned char slide_delay = data_byte & 0xF; // low nibble +- carrier_mf_signed_delta[channel] = +1; +- carrier_mf_mod_delay[channel] = slide_delay + 1; +- carrier_mf_mod_delay_backup[channel] = slide_delay + 1; +-} +- +- +-// ------------------------------------------------ +-// Set +1 mute factor slide (downward volume slide) +-// Format: 86 cn +-// c == channel +-// n == slide speed +-// ------------------------------------------------ +-void Cu6mPlayer::command_86() +-{ +- unsigned char data_byte = read_song_byte(); +- int channel = data_byte >> 4; // high nibble +- unsigned char slide_delay = data_byte & 0xF; // low nibble +- carrier_mf_signed_delta[channel] = -1; +- carrier_mf_mod_delay[channel] = slide_delay + 1; +- carrier_mf_mod_delay_backup[channel] = slide_delay + 1; +-} +- +- +-// -------------- +-// Set loop point +-// Format: E? +-// -------------- +-void Cu6mPlayer::command_E() +-{ +- loop_position = song_pos; +-} +- +- +-// --------------------------- +-// Return from current subsong +-// Format: F? +-// --------------------------- +-void Cu6mPlayer::command_F() +-{ +- if (!subsong_stack.empty()) +- { +- subsong_info temp = subsong_stack.top(); +- subsong_stack.pop(); +- temp.subsong_repetitions--; +- if (temp.subsong_repetitions==0) +- { +- song_pos = temp.continue_pos; +- } +- else +- { +- song_pos = temp.subsong_start; +- subsong_stack.push(temp); +- } +- } +- else +- { +- song_pos = loop_position; +- songend = true; +- } +-} +- +- +-// -------------------- +-// Additional functions +-// -------------------- +- +-// This function decrements its argument, without allowing it to become negative. +-void Cu6mPlayer::dec_clip(int& param) +-{ +- param--; +- if (param < 0) { param = 0; } +-} +- +- +-// Returns the byte at the current song position. +-// Side effect: increments song_pos. +-unsigned char Cu6mPlayer::read_song_byte() +-{ +- unsigned char song_byte; +- song_byte = song_data[song_pos]; +- song_pos++; +- return(song_byte); +-} +- +- +-// Same as read_song_byte(), except that it returns a signed byte +-signed char Cu6mPlayer::read_signed_song_byte() +-{ +- unsigned char song_byte; +- int signed_value; +- song_byte = *(song_data + song_pos); +- song_pos++; +- if (song_byte <= 127) +- { +- signed_value = song_byte; +- } +- else +- { +- signed_value = (int)song_byte - 0x100; +- } +- return((signed char)signed_value); +-} +- +- +-Cu6mPlayer::byte_pair Cu6mPlayer::expand_freq_byte(unsigned char freq_byte) +-{ +- const byte_pair freq_table[24] = +- { +- {0x00,0x00}, {0x58,0x01}, {0x82,0x01}, {0xB0,0x01}, +- {0xCC,0x01}, {0x03,0x02}, {0x41,0x02}, {0x86,0x02}, +- {0x00,0x00}, {0x6A,0x01}, {0x96,0x01}, {0xC7,0x01}, +- {0xE4,0x01}, {0x1E,0x02}, {0x5F,0x02}, {0xA8,0x02}, +- {0x00,0x00}, {0x47,0x01}, {0x6E,0x01}, {0x9A,0x01}, +- {0xB5,0x01}, {0xE9,0x01}, {0x24,0x02}, {0x66,0x02} +- }; +- +- int packed_freq; +- int octave; +- byte_pair freq_word; +- +- packed_freq = freq_byte & 0x1F; +- octave = freq_byte >> 5; +- +- // range check (not present in the original U6 music driver) +- if (packed_freq >= 24) { packed_freq = 0; } +- +- freq_word.hi = freq_table[packed_freq].hi + (octave << 2); +- freq_word.lo = freq_table[packed_freq].lo; +- +- return(freq_word); +-} +- +- +-void Cu6mPlayer::set_adlib_freq(int channel,Cu6mPlayer::byte_pair freq_word) +-{ +- out_adlib(0xA0+channel,freq_word.lo); +- out_adlib(0xB0+channel,freq_word.hi); +- // update the Adlib register backups +- channel_freq[channel] = freq_word; +-} +- +- +-// this function sets the Adlib frequency, but does not update the register backups +-void Cu6mPlayer::set_adlib_freq_no_update(int channel,Cu6mPlayer::byte_pair freq_word) +-{ +- out_adlib(0xA0+channel,freq_word.lo); +- out_adlib(0xB0+channel,freq_word.hi); +-} +- +- +-void Cu6mPlayer::set_carrier_mf(int channel,unsigned char mute_factor) +-{ +- out_adlib_opcell(channel,true,0x40,mute_factor); +- carrier_mf[channel] = mute_factor; +-} +- +- +-void Cu6mPlayer::set_modulator_mf(int channel,unsigned char mute_factor) +-{ +- out_adlib_opcell(channel,false,0x40,mute_factor); +-} +- +- +-void Cu6mPlayer::freq_slide(int channel) +-{ +- byte_pair freq = channel_freq[channel]; +- +- long freq_word = freq.lo + (freq.hi << 8) + channel_freq_signed_delta[channel]; +- if (freq_word < 0) { freq_word += 0x10000; } +- if (freq_word > 0xFFFF) { freq_word -= 0x10000; } +- +- freq.lo = freq_word & 0xFF; +- freq.hi = (freq_word >> 8) & 0xFF; +- set_adlib_freq(channel,freq); +-} +- +- +-void Cu6mPlayer::vibrato(int channel) +-{ +- byte_pair freq; +- +- if (vb_current_value[channel] >= vb_double_amplitude[channel]) +- { vb_direction_flag[channel] = 1; } +- else if (vb_current_value[channel] <= 0) +- { vb_direction_flag[channel] = 0; } +- +- if (vb_direction_flag[channel]==0) +- { vb_current_value[channel]++; } +- else +- { vb_current_value[channel]--; } +- +- long freq_word = channel_freq[channel].lo + (channel_freq[channel].hi << 8); +- freq_word += (vb_current_value[channel] - (vb_double_amplitude[channel] >> 1)) +- * vb_multiplier[channel]; +- if (freq_word < 0) { freq_word += 0x10000; } +- if (freq_word > 0xFFFF) { freq_word -= 0x10000; } +- +- freq.lo = freq_word & 0xFF; +- freq.hi = (freq_word >> 8) & 0xFF; +- set_adlib_freq_no_update(channel,freq); +-} +- +- +-void Cu6mPlayer::mf_slide(int channel) +-{ +- carrier_mf_mod_delay[channel]--; +- if (carrier_mf_mod_delay[channel]==0) +- { +- carrier_mf_mod_delay[channel] = carrier_mf_mod_delay_backup[channel]; +- int current_mf = carrier_mf[channel] + carrier_mf_signed_delta[channel]; +- if (current_mf > 0x3F) +- { +- current_mf = 0x3F; +- carrier_mf_signed_delta[channel] = 0; +- } +- else if (current_mf < 0) +- { +- current_mf = 0; +- carrier_mf_signed_delta[channel] = 0; +- } +- +- set_carrier_mf(channel,(unsigned char)current_mf); +- } +-} +- +- +-void Cu6mPlayer::out_adlib(unsigned char adlib_register, unsigned char adlib_data) +-{ +- opl->write(adlib_register,adlib_data); +-} +- +- +-void Cu6mPlayer::out_adlib_opcell(int channel, bool carrier, unsigned char adlib_register, unsigned char out_byte) +-{ +- const unsigned char adlib_channel_to_carrier_offset[9] = +- {0x03,0x04,0x05,0x0B,0x0C,0x0D,0x13,0x14,0x15}; +- const unsigned char adlib_channel_to_modulator_offset[9] = +- {0x00,0x01,0x02,0x08,0x09,0x0A,0x10,0x11,0x12}; +- +- if (carrier) +- { +- out_adlib(adlib_register+adlib_channel_to_carrier_offset[channel],out_byte); +- } +- else +- { +- out_adlib(adlib_register+adlib_channel_to_modulator_offset[channel],out_byte); +- } +-} +- +- +-// ============================================================================================ +-// +-// +-// The Dictionary +-// +-// +-// ============================================================================================ +- +- +-Cu6mPlayer::MyDict::MyDict() +-{ +- dict_size = default_dict_size; +- dictionary = new dict_entry[dict_size-0x100]; // don't allocate space for the roots +- contains = 0x102; +-} +- +- +-Cu6mPlayer::MyDict::MyDict(int max_size) +-{ +- dict_size = max_size; +- dictionary = new dict_entry[dict_size-0x100]; // don't allocate space for the roots +- contains = 0x102; +-} +- +- +-Cu6mPlayer::MyDict::~MyDict() +-{ +- delete [] dictionary; +-} +- +-// re-initializes the dictionary +-void Cu6mPlayer::MyDict::reset() +-{ +- contains = 0x102; +-} +- +- +-// Note: If the dictionary is already full, this function does nothing. +-void Cu6mPlayer::MyDict::add(unsigned char root, int codeword) +-{ +- if (contains < dict_size) +- { +- dictionary[contains-0x100].root = root; +- dictionary[contains-0x100].codeword = codeword; +- contains++; +- } +-} +- +- +-unsigned char Cu6mPlayer::MyDict::get_root(int codeword) +-{ +- return (dictionary[codeword-0x100].root); +-} +- +- +-int Cu6mPlayer::MyDict::get_codeword(int codeword) +-{ +- return (dictionary[codeword-0x100].codeword); +-} +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/u6m.h audacious-plugins-3.9/src/adplug/core/u6m.h +--- audacious-plugins-3.9-orig/src/adplug/core/u6m.h 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/u6m.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,168 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2006 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * u6m.h - Ultima 6 Music Player by Marc Winterrowd. +- * This code extends the Adlib Winamp plug-in by Simon Peter +- */ +- +-#include +- +-#include "player.h" +- +-#define default_dict_size 4096 // because maximum codeword size == 12 bits +-#define max_codeword_length 12 // maximum codeword length in bits +- +-class Cu6mPlayer: public CPlayer +-{ +- public: +- static CPlayer *factory(Copl *newopl); +- +- Cu6mPlayer(Copl *newopl) : CPlayer(newopl), song_data(0) +- { +- }; +- +- +- ~Cu6mPlayer() +- { +- if(song_data) delete[] song_data; +- }; +- +- bool load(const std::string &filename, const CFileProvider &fp); +- bool update(); +- void rewind(int subsong); +- float getrefresh(); +- +- std::string gettype() +- { +- return std::string("Ultima 6 Music"); +- }; +- +- protected: +- +- struct byte_pair +- { +- unsigned char lo; +- unsigned char hi; +- }; +- +- struct subsong_info // information about a subsong +- { +- int continue_pos; +- int subsong_repetitions; +- int subsong_start; +- }; +- +- struct dict_entry // dictionary entry +- { +- unsigned char root; +- int codeword; +- }; +- +- struct data_block // +- { +- long size; +- unsigned char *data; +- }; +- +- class MyDict +- { +- private: +- // The actual number of dictionary entries allocated +- // is (dictionary_size-256), because there are 256 roots +- // that do not need to be stored. +- int contains; // number of entries currently in the dictionary +- int dict_size; // max number of entries that will fit into the dictionary +- dict_entry* dictionary; +- +- public: +- MyDict(); // use dictionary size of 4096 +- MyDict(int); // let the caller specify a dictionary size +- ~MyDict(); +- void reset(); // re-initializes the dictionary +- void add(unsigned char, int); +- unsigned char get_root(int); +- int get_codeword(int); +- }; +- +- +- // class variables +- long played_ticks; +- +- unsigned char* song_data; // the uncompressed .m file (the "song") +- bool driver_active; // flag to prevent reentrancy +- bool songend; // indicates song end +- int song_pos; // current offset within the song +- int loop_position; // position of the loop point +- int read_delay; // delay (in timer ticks) before further song data is read +- std::stack subsong_stack; +- +- int instrument_offsets[9]; // offsets of the adlib instrument data +- // vibrato ("vb") +- unsigned char vb_current_value[9]; +- unsigned char vb_double_amplitude[9]; +- unsigned char vb_multiplier[9]; +- unsigned char vb_direction_flag[9]; +- // mute factor ("mf") = not(volume) +- unsigned char carrier_mf[9]; +- signed char carrier_mf_signed_delta[9]; +- unsigned char carrier_mf_mod_delay_backup[9]; +- unsigned char carrier_mf_mod_delay[9]; +- // frequency +- byte_pair channel_freq[9]; // adlib freq settings for each channel +- signed char channel_freq_signed_delta[9]; +- +- // protected functions used by update() +- void command_loop(); +- unsigned char read_song_byte(); +- signed char read_signed_song_byte(); +- void dec_clip(int&); +- byte_pair expand_freq_byte(unsigned char); +- void set_adlib_freq(int channel,byte_pair freq_word); +- void set_adlib_freq_no_update(int channel,byte_pair freq_word); +- void set_carrier_mf(int channel,unsigned char mute_factor); +- void set_modulator_mf(int channel,unsigned char mute_factor); +- void freq_slide(int channel); +- void vibrato(int channel); +- void mf_slide(int channel); +- +- void command_0(int channel); +- void command_1(int channel); +- void command_2(int channel); +- void command_3(int channel); +- void command_4(int channel); +- void command_5(int channel); +- void command_6(int channel); +- void command_7(int channel); +- void command_81(); +- void command_82(); +- void command_83(); +- void command_85(); +- void command_86(); +- void command_E(); +- void command_F(); +- +- void out_adlib(unsigned char adlib_register, unsigned char adlib_data); +- void out_adlib_opcell(int channel, bool carrier, unsigned char adlib_register, unsigned char out_byte); +- +- // protected functions used by load() +- bool lzw_decompress(data_block source, data_block dest); +- int get_next_codeword (long& bits_read, unsigned char *source, int codeword_size); +- void output_root(unsigned char root, unsigned char *destination, long& position); +- void get_string(int codeword, MyDict& dictionary, std::stack& root_stack); +-}; +- +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/xad.cc audacious-plugins-3.9/src/adplug/core/xad.cc +--- audacious-plugins-3.9-orig/src/adplug/core/xad.cc 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/xad.cc 1970-01-01 01:00:00.000000000 +0100 +@@ -1,140 +0,0 @@ +-/* +- Adplug - Replayer for many OPL2/OPL3 audio file formats. +- Copyright (C) 1999 - 2003 Simon Peter, , et al. +- +- This library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- This library 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 +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with this library; if not, write to the Free Software +- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- +- xad.cpp - XAD shell player by Riven the Mage +-*/ +- +-#include "xad.h" +-#include "debug.h" +- +-/* -------- Public Methods -------------------------------- */ +- +-CxadPlayer::CxadPlayer(Copl * newopl) : CPlayer(newopl) +-{ +- tune = 0; +-} +- +-CxadPlayer::~CxadPlayer() +-{ +- if (tune) +- delete [] tune; +-} +- +-bool CxadPlayer::load(const std::string &filename, const CFileProvider &fp) +-{ +- binistream *f = fp.open(filename); if(!f) return false; +- bool ret = false; +- +- // load header +- xad.id = f->readInt(4); +- f->readString(xad.title, 36); +- f->readString(xad.author, 36); +- xad.fmt = f->readInt(2); +- xad.speed = f->readInt(1); +- xad.reserved_a = f->readInt(1); +- +- // 'XAD!' - signed ? +- if(xad.id != 0x21444158) { fp.close(f); return false; } +- +- // get file size +- tune_size = fp.filesize(f) - 80; +- +- // load() +- tune = new unsigned char [tune_size]; +- f->readString((char *)tune, tune_size); +- fp.close(f); +- +- ret = xadplayer_load(); +- +- if (ret) +- rewind(0); +- +- return ret; +-} +- +-void CxadPlayer::rewind(int subsong) +-{ +- opl->init(); +- +- plr.speed = xad.speed; +- plr.speed_counter = 1; +- plr.playing = 1; +- plr.looping = 0; +- +- // rewind() +- xadplayer_rewind(subsong); +- +-#ifdef DEBUG +- AdPlug_LogWrite("-----------\n"); +-#endif +-} +- +-bool CxadPlayer::update() +-{ +- if (--plr.speed_counter) +- goto update_end; +- +- plr.speed_counter = plr.speed; +- +- // update() +- xadplayer_update(); +- +-update_end: +- return (plr.playing && (!plr.looping)); +-} +- +-float CxadPlayer::getrefresh() +-{ +- return xadplayer_getrefresh(); +-} +- +-std::string CxadPlayer::gettype() +-{ +- return xadplayer_gettype(); +-} +- +-std::string CxadPlayer::gettitle() +-{ +- return xadplayer_gettitle(); +-} +- +-std::string CxadPlayer::getauthor() +-{ +- return xadplayer_getauthor(); +-} +- +-std::string CxadPlayer::getinstrument(unsigned int i) +-{ +- return xadplayer_getinstrument(i); +-} +- +-unsigned int CxadPlayer::getinstruments() +-{ +- return xadplayer_getinstruments(); +-} +- +-/* -------- Protected Methods ------------------------------- */ +- +-void CxadPlayer::opl_write(int reg, int val) +-{ +- adlib[reg] = val; +-#ifdef DEBUG +- AdPlug_LogWrite("[ %02X ] = %02X\n",reg,val); +-#endif +- opl->write(reg,val); +-} +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/xad.h audacious-plugins-3.9/src/adplug/core/xad.h +--- audacious-plugins-3.9-orig/src/adplug/core/xad.h 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/xad.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,97 +0,0 @@ +-/* +- AdPlug - Replayer for many OPL2/OPL3 audio file formats. +- Copyright (C) 1999 - 2003 Simon Peter , et al. +- +- This library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- This library 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 +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with this library; if not, write to the Free Software +- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- +- xad.h - XAD shell player by Riven the Mage +-*/ +- +-#ifndef H_ADPLUG_XAD +-#define H_ADPLUG_XAD +- +-#include "player.h" +- +-class CxadPlayer: public CPlayer +-{ +-public: +- static CPlayer *factory(Copl *newopl); +- +- CxadPlayer(Copl * newopl); +- ~CxadPlayer(); +- +- bool load(const std::string &filename, const CFileProvider &fp); +- bool update(); +- void rewind(int subsong); +- float getrefresh(); +- +- std::string gettype(); +- std::string gettitle(); +- std::string getauthor(); +- std::string getinstrument(unsigned int i); +- unsigned int getinstruments(); +- +-protected: +- virtual void xadplayer_rewind(int subsong) = 0; +- virtual bool xadplayer_load() = 0; +- virtual void xadplayer_update() = 0; +- virtual float xadplayer_getrefresh() = 0; +- virtual std::string xadplayer_gettype() = 0; +- virtual std::string xadplayer_gettitle() +- { +- return std::string(xad.title); +- } +- virtual std::string xadplayer_getauthor() +- { +- return std::string(xad.author); +- } +- virtual std::string xadplayer_getinstrument(unsigned int i) +- { +- return std::string(""); +- } +- virtual unsigned int xadplayer_getinstruments() +- { +- return 0; +- } +- +- enum { HYP=1, PSI, FLASH, BMF, RAT, HYBRID }; +- +- struct xad_header +- { +- unsigned long id; +- char title[36]; +- char author[36]; +- unsigned short fmt; +- unsigned char speed; +- unsigned char reserved_a; +- } xad; +- +- unsigned char * tune; +- unsigned long tune_size; +- +- struct +- { +- int playing; +- int looping; +- unsigned char speed; +- unsigned char speed_counter; +- } plr; +- +- unsigned char adlib[256]; +- +- void opl_write(int reg, int val); +-}; +- +-#endif +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/xsm.cc audacious-plugins-3.9/src/adplug/core/xsm.cc +--- audacious-plugins-3.9-orig/src/adplug/core/xsm.cc 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/xsm.cc 1970-01-01 01:00:00.000000000 +0100 +@@ -1,117 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2003 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * xsm.cpp - eXtra Simple Music Player, by Simon Peter +- */ +- +-#include +- +-#include "xsm.h" +- +-CxsmPlayer::CxsmPlayer(Copl *newopl) +- : CPlayer(newopl), music(0) +-{ +-} +- +-CxsmPlayer::~CxsmPlayer() +-{ +- if(music) delete [] music; +-} +- +-bool CxsmPlayer::load(const std::string &filename, const CFileProvider &fp) +-{ +- binistream *f = fp.open(filename); if(!f) return false; +- char id[6]; +- int i, j; +- +- // check if header matches +- f->readString(id, 6); songlen = f->readInt(2); +- if(strncmp(id, "ofTAZ!", 6) || songlen > 3200) { fp.close(f); return false; } +- +- // read and set instruments +- for(i = 0; i < 9; i++) { +- opl->write(0x20 + op_table[i], f->readInt(1)); +- opl->write(0x23 + op_table[i], f->readInt(1)); +- opl->write(0x40 + op_table[i], f->readInt(1)); +- opl->write(0x43 + op_table[i], f->readInt(1)); +- opl->write(0x60 + op_table[i], f->readInt(1)); +- opl->write(0x63 + op_table[i], f->readInt(1)); +- opl->write(0x80 + op_table[i], f->readInt(1)); +- opl->write(0x83 + op_table[i], f->readInt(1)); +- opl->write(0xe0 + op_table[i], f->readInt(1)); +- opl->write(0xe3 + op_table[i], f->readInt(1)); +- opl->write(0xc0 + op_table[i], f->readInt(1)); +- f->ignore(5); +- } +- +- // read song data +- music = new char [songlen * 9]; +- for(i = 0; i < 9; i++) +- for(j = 0; j < songlen; j++) +- music[j * 9 + i] = f->readInt(1); +- +- // success +- fp.close(f); +- rewind(0); +- return true; +-} +- +-bool CxsmPlayer::update() +-{ +- int c; +- +- if(notenum >= songlen) { +- songend = true; +- notenum = last = 0; +- } +- +- for(c = 0; c < 9; c++) +- if(music[notenum * 9 + c] != music[last * 9 + c]) +- opl->write(0xb0 + c, 0); +- +- for(c = 0; c < 9; c++) { +- if(music[notenum * 9 + c]) +- play_note(c, music[notenum * 9 + c] % 12, music[notenum * 9 + c] / 12); +- else +- play_note(c, 0, 0); +- } +- +- last = notenum; +- notenum++; +- return !songend; +-} +- +-void CxsmPlayer::rewind(int subsong) +-{ +- notenum = last = 0; +- songend = false; +-} +- +-float CxsmPlayer::getrefresh() +-{ +- return 5.0f; +-} +- +-void CxsmPlayer::play_note(int c, int note, int octv) +-{ +- int freq = note_table[note]; +- +- if(!note && !octv) freq = 0; +- opl->write(0xa0 + c, freq & 0xff); +- opl->write(0xb0 + c, (freq / 0xff) | 32 | (octv * 4)); +-} +diff -Naur audacious-plugins-3.9-orig/src/adplug/core/xsm.h audacious-plugins-3.9/src/adplug/core/xsm.h +--- audacious-plugins-3.9-orig/src/adplug/core/xsm.h 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/core/xsm.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,46 +0,0 @@ +-/* +- * Adplug - Replayer for many OPL2/OPL3 audio file formats. +- * Copyright (C) 1999 - 2003 Simon Peter, , et al. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- * +- * xsm.h - eXtra Simple Music Player, by Simon Peter +- */ +- +-#include "player.h" +- +-class CxsmPlayer: public CPlayer +-{ +-public: +- static CPlayer *factory(Copl *newopl) { return new CxsmPlayer(newopl); } +- +- CxsmPlayer(Copl *newopl); +- ~CxsmPlayer(); +- +- bool load(const std::string &filename, const CFileProvider &fp); +- bool update(); +- void rewind(int subsong); +- float getrefresh(); +- +- std::string gettype() { return std::string("eXtra Simple Music"); } +- +-private: +- unsigned short songlen; +- char *music; +- unsigned int last, notenum; +- bool songend; +- +- void play_note(int c, int note, int octv); +-}; +diff -Naur audacious-plugins-3.9-orig/src/adplug/Makefile audacious-plugins-3.9/src/adplug/Makefile +--- audacious-plugins-3.9-orig/src/adplug/Makefile 2017-08-20 03:20:10.000000000 +0200 ++++ audacious-plugins-3.9/src/adplug/Makefile 2018-01-25 13:49:54.505875596 +0100 +@@ -1,60 +1,6 @@ + PLUGIN = adplug${PLUGIN_SUFFIX} + +-SRCS = adplug-xmms.cc \ +- binio/binfile.cc \ +- binio/binio.cc \ +- binio/binstr.cc \ +- core/fmopl.cc \ +- core/adlibemu.cc \ +- core/adplug.cc \ +- core/emuopl.cc \ +- core/fprovide.cc \ +- core/player.cc \ +- core/database.cc \ +- core/hsc.cc \ +- core/sng.cc \ +- core/imf.cc \ +- core/players.cc \ +- core/protrack.cc \ +- core/a2m.cc \ +- core/adtrack.cc \ +- core/amd.cc \ +- core/bam.cc \ +- core/cmf.cc \ +- core/d00.cc \ +- core/dfm.cc \ +- core/dmo.cc \ +- core/hsp.cc \ +- core/ksm.cc \ +- core/mad.cc \ +- core/mid.cc \ +- core/mkj.cc \ +- core/cff.cc \ +- core/dtm.cc \ +- core/fmc.cc \ +- core/mtk.cc \ +- core/rad.cc \ +- core/raw.cc \ +- core/sa2.cc \ +- core/s3m.cc \ +- core/xad.cc \ +- core/flash.cc \ +- core/bmf.cc \ +- core/hybrid.cc \ +- core/hyp.cc \ +- core/psi.cc \ +- core/rat.cc \ +- core/u6m.cc \ +- core/rol.cc \ +- core/xsm.cc \ +- core/dro.cc \ +- core/dro2.cc \ +- core/lds.cc \ +- core/temuopl.cc \ +- core/msc.cc \ +- core/rix.cc \ +- core/adl.cc \ +- core/jbm.cc ++SRCS = adplug-xmms.cc + + include ../../buildsys.mk + include ../../extra.mk +@@ -65,4 +11,5 @@ + CFLAGS += ${PLUGIN_CFLAGS} + # FIXME: Turning off warnings for now; this code is awful + CXXFLAGS += ${PLUGIN_CFLAGS} -Wno-sign-compare -Wno-shift-negative-value +-CPPFLAGS += ${PLUGIN_CPPFLAGS} -I../.. -I./core -I./binio ++CPPFLAGS += ${PLUGIN_CPPFLAGS} ${ADLIB_CFLAGS} -I../.. ++LIBS += ${ADLIB_LIBS} diff --git a/audacious-plugins.spec b/audacious-plugins.spec index aa8d838..ce6dad8 100644 --- a/audacious-plugins.spec +++ b/audacious-plugins.spec @@ -11,7 +11,7 @@ Name: audacious-plugins Version: 3.9 -Release: 3%{?dist} +Release: 4%{?dist} %if %{with gtk2} %global tar_ver %{version} @@ -42,6 +42,10 @@ Patch0: audacious-plugins-3.7-alpha1-xmms-skindir.patch Patch1: audacious-plugins-3.8.2-enable-gnomeshortcuts.patch # Fedora customization: add default system-wide module_path Patch2: audacious-plugins-3.6-ladspa.patch +# post-3.9 unbundling +Patch3: audacious-plugins-3.9-unbundle-adplug.patch +# related to patch 3 to adjust compiler -I/-l args temporarily +Patch4: audacious-plugins-3.9-adplug-makefile.patch BuildRequires: gcc-c++ BuildRequires: audacious-devel >= %{aud_ver} @@ -58,7 +62,6 @@ BuildRequires: libmodplug-devel BuildRequires: libogg-devel libvorbis-devel BuildRequires: flac-devel BuildRequires: fluidsynth-devel -BuildRequires: libbinio-devel BuildRequires: libcdio-devel BuildRequires: libcdio-paranoia-devel BuildRequires: libcue-devel @@ -71,6 +74,8 @@ BuildRequires: libnotify-devel BuildRequires: libbs2b-devel BuildRequires: curl-devel BuildRequires: pkgconfig(dbus-1) pkgconfig(dbus-glib-1) +BuildRequires: pkgconfig(adplug) +BuildRequires: pkgconfig(libbinio) %if 0%{?fedora} || 0%{?rhel} > 6 BuildRequires: pkgconfig(libmpg123) @@ -122,7 +127,7 @@ Group: Applications/Multimedia Requires: audacious-plugins%{?_isa} >= %{aud_ver} # bundled adplug lib is modified with VFS support - see readme in sources # there is active syncing of fixes between upstream and downstream -Provides: bundled(adplug) +#Provides: bundled(adplug) # src/console/ for console.so input plugin in -exotic subpackage Provides: bundled(game-music-emu) @@ -149,11 +154,7 @@ input plugin for Audacious. %prep -%setup -q -n %{name}-%{tar_ver} - -%patch0 -p1 -b .xmms-skindir -%patch1 -p1 -b .enable-gnomeshortcuts -%patch2 -p1 -b .ladspa +%autosetup -n %{name}-%{tar_ver} -p1 for i in src/ladspa/plugin.cc do @@ -322,11 +323,17 @@ install -p -m0644 %{SOURCE102} ${RPM_BUILD_ROOT}%{_datadir}/appdata %files amidi %{_libdir}/audacious/Input/amidi-plug.so -#%{_libdir}/audacious/Input/amidi-plug/ +#%%{_libdir}/audacious/Input/amidi-plug/ %{_datadir}/appdata/%{name}-amidi.metainfo.xml %changelog +* Thu Jan 25 2018 Michael Schwendt - 3.9-4 +- Merge post-3.9 unbundling of adplug plugin and make it build without + touching more than the plugin directory. +- Use %%autosetup. +- Avoid harmless macro in comment, which is an rpmbuild error now. + * Thu Jan 25 2018 Adrian Reber - 3.9-3 - Rebuilt for libcdio-2.0.0