Mercurial > audlegacy-plugins
changeset 964:368f8ee0a95f trunk
[svn] Sync with upstream. Subsong improvements for ADL, new JBM player.
author | chainsaw |
---|---|
date | Wed, 18 Apr 2007 07:38:58 -0700 |
parents | 9549fea94794 |
children | f1642ee1115c |
files | ChangeLog src/adplug/core/Makefile src/adplug/core/adl.cxx src/adplug/core/adl.h src/adplug/core/adplug.cxx src/adplug/core/d00.cxx src/adplug/core/d00.h src/adplug/core/jbm.cxx src/adplug/core/jbm.h src/adplug/core/player.h |
diffstat | 10 files changed, 430 insertions(+), 8 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog Tue Apr 17 14:45:19 2007 -0700 +++ b/ChangeLog Wed Apr 18 07:38:58 2007 -0700 @@ -1,3 +1,23 @@ +2007-04-17 21:45:19 +0000 Tony Vroon <chainsaw@gentoo.org> + revision [2066] + Warning fixes from SuSe. + trunk/src/alarm/alarm.c | 5 ++- + trunk/src/amidi-plug/backend-alsa/b-alsa.c | 3 - + trunk/src/amidi-plug/i_configure-alsa.c | 3 + + trunk/src/cdaudio/cddb.c | 38 ++++++++++++++++++++--- + trunk/src/esd/audio.c | 1 + trunk/src/modplug/archive/arch_bz2.cxx | 14 ++++++-- + trunk/src/modplug/archive/arch_gzip.cxx | 47 +++++++++++++++++++++++------ + trunk/src/modplug/archive/arch_rar.cxx | 21 +++++++++++- + trunk/src/modplug/archive/arch_zip.cxx | 3 + + trunk/src/modplug/sndfile.cxx | 6 ++- + trunk/src/paranormal/plugin.c | 1 + trunk/src/paranormal/presets.c | 10 +++--- + trunk/src/wma/libffwma/mem.c | 3 + + trunk/src/xspf/urlencode.c | 2 - + 14 files changed, 123 insertions(+), 34 deletions(-) + + 2007-04-16 08:35:24 +0000 Giacomo Lozito <james@develia.org> revision [2064] - statusicon: added support for quit button in smallmenu; also, the field is being prepared for customizable smallmenu entries
--- a/src/adplug/core/Makefile Tue Apr 17 14:45:19 2007 -0700 +++ b/src/adplug/core/Makefile Wed Apr 18 07:38:58 2007 -0700 @@ -9,7 +9,8 @@ a2m.cxx adtrack.cxx amd.cxx bam.cxx d00.cxx dfm.cxx dmo.cxx hsp.cxx ksm.cxx \ mad.cxx mid.cxx mkj.cxx cff.cxx dtm.cxx fmc.cxx mtk.cxx rad.cxx raw.cxx \ sa2.cxx s3m.cxx xad.cxx flash.cxx bmf.cxx hybrid.cxx hyp.cxx psi.cxx rat.cxx \ -u6m.cxx rol.cxx xsm.cxx dro.cxx lds.cxx temuopl.cxx msc.cxx rix.cxx adl.cxx +u6m.cxx rol.cxx xsm.cxx dro.cxx lds.cxx temuopl.cxx msc.cxx rix.cxx adl.cxx \ +jbm.cxx SOURCES = $(C_SOURCES) $(CXX_SOURCES) @@ -18,7 +19,7 @@ protrack.h rad.h raw.h sa2.h sng.h u6m.h player.h fmc.h mad.h xad.h bmf.h \ flash.h hyp.h psi.h rat.h hybrid.h rol.h adtrack.h cff.h dtm.h fprovide.h \ database.h players.h xsm.h adlibemu.h kemuopl.h dro.h dmo.h s3m.h temuopl.h \ -msc.h rix.h adl.h +msc.h rix.h adl.h jbm.h CXXFLAGS += $(PICFLAGS) $(BINIO_CFLAGS) -I../../../../intl -I../../../.. -Dstricmp=strcasecmp $(BEEP_DEFINES) CFLAGS += $(PICFLAGS) $(BINIO_CFLAGS) -I../../../../intl -I../../../.. -Dstricmp=strcasecmp $(BEEP_DEFINES)
--- a/src/adplug/core/adl.cxx Tue Apr 17 14:45:19 2007 -0700 +++ b/src/adplug/core/adl.cxx Wed Apr 18 07:38:58 2007 -0700 @@ -2807,17 +2807,22 @@ // _soundFileLoaded = file; - for (int i = 0; i < 200; i++) - if (_trackEntries[i] != 0xff) + // find last subsong + for(int i = 199; 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);
--- a/src/adplug/core/adl.h Tue Apr 17 14:45:19 2007 -0700 +++ b/src/adplug/core/adl.h Wed Apr 18 07:38:58 2007 -0700 @@ -1,6 +1,20 @@ /* * Adplug - Replayer for many OPL2/OPL3 audio file formats. - * Copyright (C) 1999 - 2006 Simon Peter, <dn.tlp@gmx.net>, et al. + * Copyright (C) 1999 - 2007 Simon Peter, <dn.tlp@gmx.net>, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * adl.h - ADL player adaption by Simon Peter <dn.tlp@gmx.net> */ @@ -24,7 +38,7 @@ bool load(VFSFile *fd, const CFileProvider &fp); bool update(); - void rewind(int subsong); + void rewind(int subsong = -1); // refresh rate is fixed at 72Hz float getrefresh() @@ -33,6 +47,7 @@ } unsigned int getsubsongs(); + unsigned int getsubsong() { return cursubsong; } std::string gettype() { return std::string("Westwood ADL"); } private:
--- a/src/adplug/core/adplug.cxx Tue Apr 17 14:45:19 2007 -0700 +++ b/src/adplug/core/adplug.cxx Wed Apr 18 07:38:58 2007 -0700 @@ -64,6 +64,7 @@ #include "msc.h" #include "rix.h" #include "adl.h" +#include "jbm.h" /***** Defines *****/ @@ -112,6 +113,7 @@ 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, "Johannes Bjerregaard", ".jbm\0"), CPlayerDesc () };
--- a/src/adplug/core/d00.cxx Tue Apr 17 14:45:19 2007 -0700 +++ b/src/adplug/core/d00.cxx Wed Apr 18 07:38:58 2007 -0700 @@ -485,6 +485,8 @@ } *tpoin; int i; + if(subsong == -1) subsong = cursubsong; + if (version > 1) { // do nothing if subsong > number of subsongs if (subsong >= header->subsongs) @@ -524,6 +526,7 @@ songend = 0; opl->init (); opl->write (1, 32); // reset OPL chip + cursubsong = subsong; } std::string Cd00Player::gettype ()
--- a/src/adplug/core/d00.h Tue Apr 17 14:45:19 2007 -0700 +++ b/src/adplug/core/d00.h Wed Apr 18 07:38:58 2007 -0700 @@ -89,7 +89,7 @@ unsigned char duration,ptr; } *levpuls; - unsigned char songend,version; + unsigned char songend,version,cursubsong; char *datainfo; unsigned short *seqptr; d00header *header;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/adplug/core/jbm.cxx Wed Apr 18 07:38:58 2007 -0700 @@ -0,0 +1,294 @@ +/* + * Adplug - Replayer for many OPL2/OPL3 audio file formats. + * Copyright (C) 1999 - 2007 Simon Peter, <dn.tlp@gmx.net>, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Johannes Bjerregaard's JBM Adlib Music Format player for AdPlug + * Written by Dennis Lindroos <lindroos@nls.fi>, 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(VFSFile * fd, const CFileProvider & fp) +{ + binistream *f = fp.open (fd); + std::string filename (fd->uri); + 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<<c); + voicemask &= ~(1<<c); + } + spos = voice[c].seqpos = sequences[voice[c].seqno]; + break; + default: // Note Event + if ((m[spos] & 127) > 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<<c); + + voice[c].seqno = m[voice[c].trkpos]; + voice[c].seqpos = sequences[voice[c].seqno]; + + voice[c].note = 0; + voice[c].delay = 1; + } + + opl->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; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/adplug/core/jbm.h Wed Apr 18 07:38:58 2007 -0700 @@ -0,0 +1,80 @@ +/* + * Adplug - Replayer for many OPL2/OPL3 audio file formats. + * Copyright (C) 1999 - 2007 Simon Peter <dn.tlp@gmx.net>, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * jbm.h - JBM Player by Dennis Lindroos <lindroos@nls.fi> + */ + +#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(VFSFile *fd, 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
--- a/src/adplug/core/player.h Tue Apr 17 14:45:19 2007 -0700 +++ b/src/adplug/core/player.h Wed Apr 18 07:38:58 2007 -0700 @@ -67,6 +67,8 @@ { 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