OSDN Git Service

TiMidity++-2.9.1a1
authorMasanao Izumo <mo@goice.co.jp>
Tue, 7 Mar 2000 12:14:24 +0000 (21:14 +0900)
committerMasanao Izumo <mo@goice.co.jp>
Tue, 7 Mar 2000 12:14:24 +0000 (21:14 +0900)
16 files changed:
ChangeLog
NEWS
configs/msc-config.h
configure
configure.in
doc/C/timidity.cfg.5
doc/ja_JP.ujis/timidity.cfg.5
libarc/url.h
libarc/url_ftp.c
timidity/common.c
timidity/mod.c
timidity/mod2midi.c
timidity/playmidi.c
timidity/readmidi.c
timidity/readmidi.h
timidity/timidity.c

index 0bc2c8d..e06c84b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,49 @@
+2000-03-07  Masanao Izumo <mo@goice.co.jp>
+
+    * timidity/mod2midi.c: Check error condition of return value of
+      period2note, and use ctl->cmsg() to display the warning message
+      instead of printf().
+
+2000-03-06  Paolo Bonzini <bonzini@gnu.org>
+
+    * timidity/mod2midi.c: Bug fix
+    * timidity/playmidi.c (ME_PATCH_OFFS): Bug fix
+
+2000-03-05  Paolo Bonzini <bonzini@gnu.org>
+
+    * timidity/mod.c: fixed endless loop in the player
+    * timidity/mod2midi.c: Voice_SetPeriod does not reset the sample (involved
+      switching from ME_EXPRESSION to ME_KEYPRESSURE for volumes). Changed
+      release time to 80 msec.
+    * timidity/readmidi.h: made MidiEventList a doubly-linked list
+    * timidity/readmidi.c: implemented doubly-linked-list in readmidi_add_event,
+      and removed BACKWARD_EVENT_OK because the new implementation
+      removed the inefficiency of backward events.
+
+2000-03-05  Sawada Keiji <sqrt@tkf.att.ne.jp>
+
+    * libarc/url_ftp.c: Bug fix.
+
+2000-03-04  Mikhail Yakshin <yakshin@glasnet.ru>
+
+    * timidity/{timidity.c,common.c}: Convert the text code
+      from windows-1251 to koi8-r with command line option `-t 1251'.
+
+2000-03-03  Masanao Izumo <mo@goice.co.jp>
+
+    * timidity/C/timidity.cfg.5,timidity/ja_JP.ujis/timidity.cfg.5: update.
+
+2000-03-02  Masanao Izumo <mo@goice.co.jp>
+
+    * timidity/timidity.c (-R): Reset pseudo reverb (modify release)
+       if `-R -1' is specified.
+    * timidity/mod2midi.c: Enable to change release envelope time of
+       the module file if command line option `-R' is specified.
+
+2000-03-02  Paolo Bonzini <bonzini@gnu.org>
+
+    * timidity/mod2midi.c: Solves a problem with low notes.
+
 2000-02-27  Masanao Izumo <mo@goice.co.jp>
 
     * Version 2.9.0 released.
diff --git a/NEWS b/NEWS
index 460250b..d9cc297 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,6 @@
 02/27, 2000
     * Version 2.9.0 released.
-    * Support full module player.
+    * Support full module midi files.
 
 02/07, 2000
     * Version 2.8.2 released.
index 5036da1..2f15270 100644 (file)
 #define HAVE_MMSYSTEM_H\r
 \r
 /* In VDS Macro AAA=BBB is not available. */\r
-#define TIMID_VERSION  "2.9.0"\r
+#define TIMID_VERSION  "2.9.1a1"\r
 #define DEFAULT_PATH   ".\\"\r
 #define AU_W32\r
 #define WINSOCK\r
index 3d91ad4..11f8b50 100755 (executable)
--- a/configure
+++ b/configure
@@ -884,7 +884,7 @@ fi
 
 PACKAGE=TiMidity++
 
-VERSION=2.9.0
+VERSION=2.9.1a1
 
 if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
   { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; }
index 9d2a409..f15ea49 100644 (file)
@@ -55,7 +55,7 @@ dnl
 AC_INIT(timidity/timidity.c)
 SHELL=${CONFIG_SHELL-/bin/sh}
 AC_CANONICAL_SYSTEM
-AM_INIT_AUTOMAKE(TiMidity++, 2.9.0, no-define)
+AM_INIT_AUTOMAKE(TiMidity++, 2.9.1a1, no-define)
 
 dnl To use CONTAINS() macro (See acinclude.m4)
 CONTAINS_INIT
index 4fa38f7..8772bca 100644 (file)
@@ -6,7 +6,7 @@ timidity.cfg \- configure file of TiMidity++
 .TP
 .B /etc/timidity.cfg
 .TP
-.B /usr/local/lib/timidity/timidity.cfg
+.B /usr/local/share/timidity/timidity.cfg
 
 .P
 .SH DESCRIPTION
@@ -38,7 +38,7 @@ as the \fB\-L\fP command line option.
 .sh
 Archive file are also allowed. For example:
 .bp
-dir /usr/local/lib/timidity/inst/foo.zip#
+dir /usr/local/share/timidity/inst/foo.zip#
 .br
 .bank 0
 .br
@@ -50,7 +50,7 @@ dir /usr/local/lib/timidity/inst/foo.zip#
 .sp
 At first, \fBdir\fP specities the archive name (followed by '#') for the
 path of patch files same as directory name (in this case ,
-"/usr/local/lib/timidity/inst/foo.zip").
+"/usr/local/share/timidity/inst/foo.zip").
 TiMidity recognize the path is an archive file if the expression has
 the last character '#', and also read the files contained in this
 archive file.
@@ -157,7 +157,7 @@ Note that alternate assign of drumset 0 is used by default.
 .BI "#extension comm" " program secound"
 Specifies the comment \fIcomment\fP for the tone number \fIprogram\fP.
 These comments are displayed in the indicater line at the case
-TiMidity is booted with option \fB\-iNt\fP, \fB\-iTt\fP.
+TiMidity is booted with option \fB\-int\fP, \fB\-iTt\fP.
 
 .TP
 .BI "#extension timeout" " program secound"
index 9136b2a..1d9ebb8 100644 (file)
@@ -6,7 +6,7 @@ timidity.cfg \- configure file of TiMidity++
 .TP
 .B /etc/timidity.cfg
 .TP
-.B /usr/local/lib/timidity/timidity.cfg
+.B /usr/local/share/timidity/timidity.cfg
 
 .P
 .SH DESCRIPTION
@@ -36,7 +36,7 @@ TiMidity++ 
 
 Îã:
 .br
-dir /usr/local/lib/timidity/inst/foo.zip#
+dir /usr/local/share/timidity/inst/foo.zip#
 .br
 bank 0
 .br
@@ -47,7 +47,7 @@ bank 0
 2 zoo.pat
 .br
 ¤Þ¤º¡¢dir ¤ÇÄ̾ï¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Î¤è¤¦¤Ë¥¢¡¼¥«¥¤¥Ö¥Õ¥¡¥¤¥ë (¾å¤ÎÎã¤Ç¤Ï
-/usr/local/lib/timidity/inst/foo.zip)
+/usr/local/share/timidity/inst/foo.zip)
 ¤ò»ØÄꤷ¤Þ¤¹¡£¤³¤Î¤È¤­¡¢¥¢¡¼¥«¥¤¥Ö¥Õ¥¡¥¤¥ë̾
 ¤ÎºÇ¸å¤Ë \fB#\fP ¤ò¤Ä¤±¤Æ¤¯¤À¤µ¤¤¡£¤³¤Î \fB#\fP ¤¬¤¢¤ë¤³¤È¤Ç¡¢¥¢¡¼¥«¥¤¥Ö¥Õ¥¡¥¤¥ë¤Ç
 ¤¢¤ë¤³¤È¤ò \fITiMidity++\fP ¤Ïǧ¼±¤·¤Þ¤¹¡£¤³¤¦¤·¤Æ¤ª¤¯¤È¡¢\fIdir\fP ¤Ç»ØÄꤵ¤ì¤¿
@@ -138,7 +138,7 @@ altassign 42 44 46
 .TP
 .BI "#extension comm" " program comment"
 Instrument ÈÖ¹æ \fIprogram\fP ¤Ë¥³¥á¥ó¥È \fIcomment\fP ¤ò»ØÄꤷ¤Þ¤¹¡¥
-¤³¤³¤ÇÀßÄꤷ¤¿ \fIcomment\fP ¤Ï \fB\-iNt\fP ¤ä \fI\-iTt\fP ¥ª¥×¥·¥ç¥ó
+¤³¤³¤ÇÀßÄꤷ¤¿ \fIcomment\fP ¤Ï \fB\-int\fP ¤ä \fI\-iTt\fP ¥ª¥×¥·¥ç¥ó
 ¤Çµ¯Æ°¤·¤¿»þ¤Ë¡¢¥¤¥ó¥¸¥±¡¼¥¿¥é¥¤¥ó¤Ëɽ¼¨¤µ¤ì¤Þ¤¹¡£
 .TP
 .BI "#extension timeout" " program secound"
index 7969d4e..5beb64a 100644 (file)
@@ -26,7 +26,7 @@
  */
 
 
-#define URL_LIB_VERSION "1.9.4"
+#define URL_LIB_VERSION "1.9.5"
 
 /* Define if you want to enable pipe command scheme ("command|") */
 #define PIPE_SCHEME_ENABLE
index da2d3d6..fba53f9 100644 (file)
@@ -155,7 +155,7 @@ URL url_ftp_open(char *name)
     char *p, *host, *path;
     unsigned short port;
     char buff[BUFSIZ];
-    char path_buff[1024];
+    char path_buff[1024], host_buff[1024];
     int n;
     char *passwd;
     char *user;
@@ -202,7 +202,11 @@ URL url_ftp_open(char *name)
            name += 6;
        strncpy(buff, name, sizeof(buff));
        buff[sizeof(buff) - 1] = '\0';
-       host = buff;
+
+       strncpy(host_buff, buff, sizeof(host_buff));
+       host_buff[sizeof(host_buff) - 1] = '\0';
+       host = host_buff;
+
        if((p = strchr(host, '/')) == NULL)
        {
            url_ftp_close((URL)url);
index 22bcabd..5d5b96a 100644 (file)
@@ -592,6 +592,31 @@ int volatile_touch(void *dmy) {return 1;}
 #endif /* HAVE_VOLATILE */
 
 /* code converters */
+static unsigned char
+      w2k[] = {128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
+               144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
+               160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
+               176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
+               225,226,247,231,228,229,246,250,233,234,235,236,237,238,239,240,
+               242,243,244,245,230,232,227,254,251,253,255,249,248,252,224,241,
+               193,194,215,199,196,197,214,218,201,202,203,204,205,206,207,208,
+               210,211,212,213,198,200,195,222,219,221,223,217,216,220,192,209};
+
+static void code_convert_cp1251(char *in, char *out, int maxlen)
+{
+    int i;
+    if(out == NULL)
+        out = in;
+    for(i = 0; i < maxlen && in[i]; i++)
+    {
+       if(in[i] & 0200)
+           out[i] = w2k[in[i] & 0177];
+       else
+           out[i] = in[i];
+    }
+    out[i]='\0';
+}
+
 static void code_convert_dump(char *in, char *out, int maxlen, char *ocode)
 {
     if(ocode == NULL)
@@ -793,6 +818,12 @@ void code_convert(char *in, char *out, int outsiz, char *icode, char *ocode)
            code_convert_dump(in, out, outsiz - 1, "ASCII");
            return;
        }
+
+       if(strcasecmp(ocode, "1251") == 0)
+       {
+           code_convert_cp1251(in, out, outsiz - 1);
+           return;
+       }
     }
 
 #if defined(JAPANESE)
index 9fbbb8c..031e850 100644 (file)
@@ -60,6 +60,7 @@ static BOOL mod_do_play (MODULE *);
 int 
 load_module_file (struct timidity_file *tf, int mod_type)
 {
+  int i, err;
   MODULE *mf;
 
 #ifdef LOOKUP_HACK
@@ -69,6 +70,7 @@ load_module_file (struct timidity_file *tf, int mod_type)
 #endif
   ML_monosamples = 1;
 
+  ML_RegisterAllLoaders ();
   mf = ML_Load (tf->url, MOD_NUM_VOICES, 0);
   if (ML_errno)
     return 1;
@@ -84,22 +86,24 @@ load_module_file (struct timidity_file *tf, int mod_type)
 int 
 get_module_type (char *fn)
 {
-  if (check_file_extension (fn, ".xm", 1)      /* Most common first */
-      || check_file_extension (fn, ".s3m", 1)
-      || check_file_extension (fn, ".mod", 1)
-      || check_file_extension (fn, ".it", 1)
-      || check_file_extension (fn, ".669", 1)  /* Then the others in alphabetic order */
-      || check_file_extension (fn, ".amf", 1)
-      || check_file_extension (fn, ".dsm", 1)
-      || check_file_extension (fn, ".far", 1)
-      || check_file_extension (fn, ".gdm", 1)
-      || check_file_extension (fn, ".imf", 1)
-      || check_file_extension (fn, ".med", 1)
-      || check_file_extension (fn, ".mtm", 1)
-      || check_file_extension (fn, ".stm", 1)
-      || check_file_extension (fn, ".stx", 1)
-      || check_file_extension (fn, ".ult", 1)
-      || check_file_extension (fn, ".uni", 1))
+  char *p;
+
+  if (check_file_extension (fn, ".xm", 0)      /* Most common first */
+      || check_file_extension (fn, ".s3m", 0)
+      || check_file_extension (fn, ".mod", 0)
+      || check_file_extension (fn, ".it", 0)
+      || check_file_extension (fn, ".669", 0)  /* Then the others in alphabetic order */
+      || check_file_extension (fn, ".amf", 0)
+      || check_file_extension (fn, ".dsm", 0)
+      || check_file_extension (fn, ".far", 0)
+      || check_file_extension (fn, ".gdm", 0)
+      || check_file_extension (fn, ".imf", 0)
+      || check_file_extension (fn, ".med", 0)
+      || check_file_extension (fn, ".mtm", 0)
+      || check_file_extension (fn, ".stm", 0)
+      || check_file_extension (fn, ".stx", 0)
+      || check_file_extension (fn, ".ult", 0)
+      || check_file_extension (fn, ".uni", 0))
 
     return IS_MOD_FILE;
 
@@ -1860,6 +1864,7 @@ pt_playeffects (void)
              /* if we were fading, adjust... */
              if (mp.sngpos == (pf->numpos - 1))
                mp.volume = pf->initvolume > 128 ? 128 : pf->initvolume;
+             
              mp.sngpos = dat;
              mp.posjmp = 2;
              mp.patpos = 0;
@@ -1886,14 +1891,15 @@ pt_playeffects (void)
          if (!mp.posjmp)
            {
              /* don't ask me to explain this code - it makes
-                backwards.s3m and children.xm (heretic's version) play
-                correctly, among others. Take that for granted, or write
-                the page of comments yourself... you might need some
-                aspirin - Miod */
+              * backwards.s3m and children.xm (heretic's version) play
+              * correctly, among others. Take that for granted, or write
+              * the page of comments yourself... you might need some
+              * aspirin - Miod */
              if ((mp.sngpos == pf->numpos - 1) && (dat) &&
                  ((pf->positions[mp.sngpos] == (pf->numpat - 1)
-                   && !(pf->flags & UF_NOWRAP))))
+                   && (pf->flags & UF_NOWRAP))))
                {
+                 /* printf("%d -- Pattern 0!\n", __LINE__); */
                  mp.sngpos = 0;
                  mp.posjmp = 2;
                }
@@ -2294,14 +2300,13 @@ pt_UpdateVoices ()
       else if (aout->period > 50000)
        aout->period = 50000;
 
+      kick_voice = 0;
       if ((aout->kick == KICK_NOTE) || (aout->kick == KICK_KEYOFF))
        {
          kick_voice = 1;
          aout->fadevol = 32768;
          aout->aswppos = 0;
        }
-      else
-        kick_voice = 0;
 
       if (i && ((aout->kick == KICK_NOTE) || (aout->kick == KICK_ENV)))
        {
@@ -2457,7 +2462,7 @@ pt_UpdateVoices ()
            Voice_Stop (mp.channel);
 
          Voice_SetPeriod (mp.channel,
-                             getAmigaPeriod (pf->flags, playperiod));
+                     getAmigaPeriod (pf->flags, playperiod));
 
          if (kick_voice)
            Voice_Play (mp.channel, s, (aout->start == -1) ? ((s->flags & SF_UST_LOOP) ? s->loopstart : 0) : aout->start);
@@ -2922,6 +2927,7 @@ HandleTick (void)
          mp.patpos = mp.numrow ? (mp.patbrk % mp.numrow) : 0;
          mp.pat_repcrazy = 0;
          mp.sngpos += (mp.posjmp - 2);
+
          for (mp.channel = 0; mp.channel < pf->numchn; mp.channel++)
            mp.control[mp.channel].pat_reppos = -1;
 
@@ -2929,11 +2935,11 @@ HandleTick (void)
          /* handle the "---" (end of song) pattern since it can occur
             *inside* the module in .IT and .S3M */
          if ((mp.sngpos >= pf->numpos) || (pf->positions[mp.sngpos] == 255))
-           {
-             return 0;
-           }
+           return 0;
+
          if (mp.sngpos < 0)
            mp.sngpos = pf->numpos - 1;
+
        }
 
       if (!mp.patdly2)
index 8334248..75ea969 100644 (file)
@@ -19,7 +19,7 @@
 
    mod2midi.c
 
-   Sample info -> MIDI event conversion
+   Mixer event -> MIDI event conversion
 
  */
 
@@ -31,6 +31,7 @@
 #else
 #include <strings.h>
 #endif
+
 #include "timidity.h"
 #include "common.h"
 #include "instrum.h"
 #include "controls.h"
 #include "unimod.h"
 #include "mod2midi.h"
+#include "controls.h"
 
 
 #define SETMIDIEVENT(e, at, t, ch, pa, pb) \
-    { (e).time = (at); (e).type = (t); \
+    { /* printf("%d %d " #t " %d %d\n", at, ch, pa, pb); */ \
+      (e).time = (at); (e).type = (t); \
       (e).channel = (uint8)(ch); (e).a = (uint8)(pa); (e).b = (uint8)(pb); }
 
 #define MIDIEVENT(at, t, ch, pa, pb) \
 
 
 #define NTSC_CLOCK 3579545.25
-#define NTSC_RATE (NTSC_CLOCK/428)     /* <-- 428 = period for c2 */
+#define NTSC_RATE (NTSC_CLOCK/428)
 
 #define PAL_CLOCK 3546894.6
 #define PAL_RATE (PAL_CLOCK/428)
 
-#define MOD_NOTE_OFFSET 60
-
+#define MOD_ROOT_NOTE      36
 #define MOD_BEND_SENSITIVE 60
 
 typedef struct _ModVoice
   {
     int sample;                        /* current sample ID */
     int noteon;                        /* (-1 means OFF status) */
+    int time;                  /* time when note was activated */
     int period;                        /* current frequency */
     int tuneon;                        /* note fine tune */
     int pan;                   /* current panning */
     int vol;                   /* current volume */
     int start;                 /* sample start */
+
+    int32 noteson[4];          /* bit map for notes 0-127 */
   }
 ModVoice;
 
@@ -88,18 +93,40 @@ static int period2note (int period, int *finetune);
 static ModVoice ModV[MOD_NUM_VOICES];
 static int at;
 
-static int period_table[84] =
-{
-/*       C     C#    D     D#    E     F     F#    G     G#    A    A#   B  */
-/* 0 */ 1712, 1616, 1524, 1440, 1356, 1280, 1208, 1140, 1076, 1016, 960, 906,
-/* 1 */ 856, 808, 762, 720, 678, 640, 604, 570, 538, 508, 480, 453,
-/* 2 */ 428, 404, 381, 360, 339, 320, 302, 285, 269, 254, 240, 226,
-/* 3 */ 214, 202, 190, 180, 170, 160, 151, 143, 135, 127, 120, 113,
-/* 4 */ 107, 101, 95, 90, 85, 80, 75, 71, 67, 63, 60, 56,
-/* 5 */ 53, 50, 47, 45, 42, 40, 37, 35, 33, 31, 30, 28,
-/* 6 */ 27, 25, 24, 22, 21, 20, 19, 18, 17, 16, 15, 14
+/******************** bitmap handling macros **********************************/
+
+#define bitmapGet(map, n)      ((map)[(n) >> 5] &  (1 << ((n) & 31)))
+#define bitmapSet(map, n)      ((map)[(n) >> 5] |= (1 << ((n) & 31)))
+#define bitmapClear(map)       ((map)[0] = (map)[1] = (map)[2] = (map)[3] = 0)
+
+static char significantDigitsLessOne[256] = {
+    -1,                                                        /* 1 */
+    0,                                                 /* 2 */
+    1, 1,                                              /* 4 */
+    2, 2, 2, 2,                                                /* 8 */
+    3, 3, 3, 3, 3, 3, 3, 3,                            /* 16 */
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,    /* 32 */
+
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,    /* 64 */
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+
+    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,    /* 128 */
+    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,    /* 256 */
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
 };
 
+/******************************************************************************/
+
 void
 mod_change_tempo (int32 at, int bpm)
 {
@@ -130,15 +157,30 @@ mod_pitch_bend(int tune)
 int
 period2note (int period, int *finetune)
 {
+  static int period_table[120] =
+  {
+  /*  C     C#    D     D#    E     F     F#    G     G#    A     A#    B  */
+     13696,12928,12192,11520,10848,10240, 9664, 9120, 8608, 8096, 7680, 7248,
+      6848, 6464, 6096, 5760, 5424, 5120, 4832, 4560, 4304, 4048, 3840, 3624,
+      3424, 3232, 3048, 2880, 2712, 2560, 2416, 2280, 2152, 2024, 1920, 1812,
+      1712, 1616, 1524, 1440, 1356, 1280, 1208, 1140, 1076, 1016,  960,  906,
+       856,  808,  762,  720,  678,  640,  604,  570,  538,  508,  480,  453,
+       428,  404,  381,  360,  339,  320,  302,  285,  269,  254,  240,  226,
+       214,  202,  190,  180,  170,  160,  151,  143,  135,  127,  120,  113,
+       107,  101,   95,   90,   85,   80,   75,   71,   67,   63,   60,   56,
+       53,   50,   47,   45,   42,   40,   37,   35,   33,   31,   30,   28,
+       27,   25,   24,   22,   21,   20,   19,   18,   17,   16,   15,   14
+  };
+
   int note;
   int l, r, m;
 
-  if (period < 14 || period > 1712)
+  if (period < 14 || period > 13696)
     return -1;
 
   /* bin search */
   l = 0;
-  r = 84;
+  r = 96;
   while (l < r)
     {
       m = (l + r) / 2;
@@ -150,7 +192,7 @@ period2note (int period, int *finetune)
   note = l - 1;
 
   /*
-   * 83 >= note >= 0
+   * 95 >= note >= 0
    * period_table[note] >= period > period_table[note + 1]
    */
 
@@ -166,7 +208,7 @@ period2note (int period, int *finetune)
                     (period_table[note] - period_table[note + 1]));
     }
 
-  return note + MOD_NOTE_OFFSET;
+  return note;
 }
 
 /********** Interface to mod.c */
@@ -177,30 +219,46 @@ Voice_SetVolume (UBYTE v, UWORD vol)
   if (v >= MOD_NUM_VOICES)
     return;
 
-  if (vol != ModV[v].vol) {
-    ModV[v].vol = vol;
-    vol = vol > 254 ? 127 : vol >> 1;
-    MIDIEVENT (at, ME_EXPRESSION, v, vol, 0);
+  /* MOD volume --> MIDI volume */
+  vol = vol > 254 ? 127 : vol >> 1;
+
+  if ((ModV[v].vol != vol) && (ModV[v].noteon != -1)) {
+    MIDIEVENT (at, ME_KEYPRESSURE, v, ModV[v].noteon, vol);
   }
+  ModV[v].vol = vol;
 }
 
 void
 Voice_SetPeriod (UBYTE v, ULONG period)
 {
-  int tune, new_noteon, bend;
+  int tune, new_noteon, new_sample, bend;
 
   if (v >= MOD_NUM_VOICES)
     return;
 
   ModV[v].period = period;
+  if (ModV[v].noteon < 0)
+    return;
+
   new_noteon = period2note (ModV[v].period, &tune);
-  if (new_noteon < 0)
+  if(new_noteon < 0)
     {
+      ctl->cmsg(CMSG_WARNING, VERB_NORMAL, "BAD period %d\n", ModV[v].period);
       return;
     }
 
   if (ModV[v].noteon != new_noteon)
-    MIDIEVENT(at, ME_NOTEOFF, v, ModV[v].noteon, 0);
+    {
+      if (!bitmapGet(ModV[v].noteson, new_noteon))
+       {
+         MIDIEVENT(ModV[v].time, ME_NOTEON, v, new_noteon, 1);
+         bitmapSet(ModV[v].noteson, new_noteon);
+       }
+
+      MIDIEVENT(at, ME_KEYPRESSURE, v, ModV[v].noteon, 1);
+      MIDIEVENT(at, ME_KEYPRESSURE, v, new_noteon, ModV[v].vol);
+      ModV[v].noteon = new_noteon;
+    }
 
   if (ModV[v].tuneon != tune)
     {
@@ -208,12 +266,6 @@ Voice_SetPeriod (UBYTE v, ULONG period)
       bend = mod_pitch_bend(tune);
       MIDIEVENT (at, ME_PITCHWHEEL, v, bend & 0x7F, (bend >> 7) & 0x7F);
     }
-  if (ModV[v].noteon != new_noteon)
-    {
-      ModV[v].noteon = new_noteon;
-      MIDIEVENT(at, ME_NOTEON, v, ModV[v].noteon, 0x7f);
-    }
 }
 
 void
@@ -233,23 +285,28 @@ Voice_SetPanning (UBYTE v, ULONG pan)
 void
 Voice_Play (UBYTE v, SAMPLE * s, ULONG start)
 {
-  int tune, new_noteon, new_sample, bend;
+  int tune, new_noteon, bend;
   if (v >= MOD_NUM_VOICES)
     return;
 
+  if (ModV[v].noteon != -1)
+    Voice_Stop (v);
+
   new_noteon = period2note (ModV[v].period, &tune);
-  new_sample = s->id;
+  if (new_noteon < 0) {
+    ctl->cmsg(CMSG_WARNING, VERB_NORMAL, "BAD period %d\n", ModV[v].period);
+    return;
+  }
 
   ModV[v].noteon = new_noteon;
-  if (ModV[v].noteon < 0)
-    {
-      return;
-    }
+  ModV[v].time = at;
+  bitmapSet(ModV[v].noteson, new_noteon);
 
-  if (ModV[v].sample != new_sample)
+  if (ModV[v].sample != s->id)
     {
-      ModV[v].sample = new_sample;
+      ModV[v].sample = s->id;
       MIDIEVENT(at, ME_SET_PATCH, v, ModV[v].sample, 0);
+      ModV[v].start = 0;
     }
 
   if (ModV[v].start != start)
@@ -267,27 +324,49 @@ Voice_Play (UBYTE v, SAMPLE * s, ULONG start)
       bend = mod_pitch_bend(tune);
       MIDIEVENT (at, ME_PITCHWHEEL, v, bend & 0x7F, (bend >> 7) & 0x7F);
     }
-
-  MIDIEVENT (at, ME_NOTEON, v, ModV[v].noteon, 0x7f);
+  MIDIEVENT (at, ME_NOTEON, v, ModV[v].noteon, ModV[v].vol);
 }
 
 void
 Voice_Stop (UBYTE v)
 {
+  int32 j;
+  int n;
+
   if (v >= MOD_NUM_VOICES)
     return;
 
-  if (ModV[v].noteon != -1)
-    {
-      MIDIEVENT (at, ME_NOTEOFF, v, ModV[v].noteon, 0);
-      ModV[v].noteon = -1;
-    }
+  if (ModV[v].noteon == -1)
+    return;
+
+#define TURN_OFF_8(base, ofs)                                          \
+  while (j & (0xFFL << (ofs))) {                                       \
+    n = ofs + significantDigitsLessOne[(unsigned char) (j >> (ofs))];  \
+    MIDIEVENT (at, ME_NOTEOFF, v, (base) + n, 63);                     \
+    j ^= 1 << n;                                                       \
+  }
+
+#define TURN_OFF_32(base)                                              \
+  do {                                                                 \
+    TURN_OFF_8((base), 24)                                             \
+    TURN_OFF_8((base), 16)                                             \
+    TURN_OFF_8((base), 8)                                              \
+    TURN_OFF_8((base), 0)                                              \
+  } while(0)
+
+  if (j = ModV[v].noteson[0]) TURN_OFF_32(0);
+  if (j = ModV[v].noteson[1]) TURN_OFF_32(32);
+  if (j = ModV[v].noteson[2]) TURN_OFF_32(64);
+  if (j = ModV[v].noteson[3]) TURN_OFF_32(96);
+  bitmapClear(ModV[v].noteson);
+  ModV[v].noteon = -1;
 }
 
 BOOL
 Voice_Stopped (UBYTE v)
 {
-  return (v >= MOD_NUM_VOICES) ? 1 : (ModV[v].noteon == -1);
+  return (v >= MOD_NUM_VOICES) || (ModV[v].noteon == -1);
 }
 
 void
@@ -325,15 +404,19 @@ Voice_StartPlaying ()
     {
        ModV[v].sample = -1;
        ModV[v].noteon = -1;
+       ModV[v].time = -1;
        ModV[v].period = 0;
        ModV[v].tuneon = 0;
-       ModV[v].pan = (v & 1) ? 127 : 0;
        ModV[v].vol = 64;
        ModV[v].start = 0;
+       ModV[v].pan = (v & 1) ? 127 : 0;
+       bitmapClear(ModV[v].noteson);
 
        MIDIEVENT(0, ME_PAN, v, ModV[v].pan, 0);
         MIDIEVENT(0, ME_SET_PATCH, v, 1, 0);
         MIDIEVENT(0, ME_MAINVOLUME, v, 127, 0);
+        MIDIEVENT(0, ME_EXPRESSION, v, 127, 0);
+       /* MIDIEVENT(0, ME_MONO, v, 0, 0); */
        MIDIEVENT(0, ME_RPN_LSB, v, 0, 0);
        MIDIEVENT(0, ME_RPN_MSB, v, 0, 0);
        MIDIEVENT(0, ME_DATA_ENTRY_MSB, v, MOD_BEND_SENSITIVE, 0);
@@ -429,17 +512,25 @@ void load_module_samples (SAMPLE * s, int numsamples)
        sp->envelope_rate[2]   = 0;
        /* release */
        sp->envelope_offset[3] = env_offset(0);
-       sp->envelope_rate[3]   = env_rate(255, 200.0);  /* 200 msec */
+       if(modify_release)
+           sp->envelope_rate[3] = env_rate(255, (double)modify_release); /* -R# */
+       else
+           sp->envelope_rate[3] = env_rate(255, 80.0); /* 80 msec */
        sp->envelope_offset[4] = sp->envelope_offset[3];
        sp->envelope_rate[4]   = 0; /* skip this stage */
        sp->envelope_offset[5] = sp->envelope_offset[4];
        sp->envelope_rate[5]   = 0; /* skip this stage, then the voice is
                                       disappeared */
 
+       /* If necessary do some anti-aliasing filtering  */
+       if (antialiasing_allowed)
+         antialiasing((int16 *)sp->data, sp->data_length / 2,
+                      sp->sample_rate, play_mode->rate);
+
        sp->sample_rate = ((int32)PAL_RATE) >> s->divfactor;
        sp->low_freq = 0;
        sp->high_freq = 0x7fffffff;
-       sp->root_freq = freq_table[MOD_NOTE_OFFSET];
+       sp->root_freq = freq_table[MOD_ROOT_NOTE];
        sp->volume = 1.0;               /* I guess it should use globvol... */
        sp->panning = s->panning == PAN_SURROUND ? 64 : s->panning * 128 / 255;
        sp->low_vel = 0;
@@ -452,5 +543,3 @@ void load_module_samples (SAMPLE * s, int numsamples)
        s->id = i;
     }
 }
-
-/* ex:set ts=4: */
index 020abc0..206b499 100644 (file)
@@ -2638,8 +2638,9 @@ static void seek_forward(int32 until_time)
            break;
 
          case ME_PATCH_OFFS:
-           if(special_patch[ch] != NULL)
-               special_patch[ch]->sample_offset =
+           i = channel[ch].special_sample;
+           if(special_patch[i] != NULL)
+               special_patch[i]->sample_offset =
                    (current_event->a | 256 * current_event->b);
            break;
 
@@ -4131,8 +4132,9 @@ int play_event(MidiEvent *ev)
        break;
 
       case ME_PATCH_OFFS:
-       if(special_patch[ch] != NULL)
-           special_patch[ch]->sample_offset =
+       i = channel[ch].special_sample;
+       if(special_patch[i] != NULL)
+           special_patch[i]->sample_offset =
                (current_event->a | 256 * current_event->b);
        break;
 
index aaa99c9..5284160 100644 (file)
@@ -47,9 +47,6 @@
 #include "wrd.h"
 #include "tables.h"
 
-/* Define if you want to support backward event timer */
-#define BACKWARD_EVENT_OK
-
 /* rcp.c */
 int read_rcp_file(struct timidity_file *tf, char *magic0, char *fn);
 
@@ -154,10 +151,10 @@ int32 readmidi_set_track(int trackno, int rewindp)
 
 void readmidi_add_event(MidiEvent *a_event)
 {
-    MidiEventList *next, *newev;
+    MidiEventList *newev;
     int32 at;
 
-    if(event_count == MAX_MIDI_EVENT)
+    if(event_count++ == MAX_MIDI_EVENT)
     {
        if(!readmidi_error_flag)
        {
@@ -169,24 +166,39 @@ void readmidi_add_event(MidiEvent *a_event)
     }
 
     at = a_event->time;
-    if(current_midi_point->event.time > at)
-#ifdef BACKWARD_EVENT_OK
-       current_midi_point = evlist; /* Rewind the event pointer */
-#else
-       at = a_event->time = current_midi_point->event.time;
-#endif /* BACKWARD_EVENT_OK */
     newev = alloc_midi_event();
-    newev->event = *a_event;
-    next = current_midi_point->next;
-    while(next && (next->event.time <= at))
+    newev->event = *a_event;   /* assign by value!!! */
+
+    if(at >= current_midi_point->event.time)
     {
-       current_midi_point = next;
-       next = current_midi_point->next;
+       /* Forward scan */
+       MidiEventList *next = current_midi_point->next;
+       while (next && (next->event.time <= at))
+       {
+           current_midi_point = next;
+           next = current_midi_point->next;
+       }
+       newev->prev = current_midi_point;
+       newev->next = next;
+       current_midi_point->next = newev;
+       if (next)
+           next->prev = newev;
+    }
+    else
+    {
+       /* Backward scan -- symmetrical to the one above */
+       MidiEventList *prev = current_midi_point->prev;
+       while (prev && (prev->event.time > at)) {
+           current_midi_point = prev;
+           prev = current_midi_point->prev;
+       }
+       newev->prev = prev;
+       newev->next = current_midi_point;
+       current_midi_point->prev = newev;
+       if (prev)
+           prev->next = newev;
     }
-    newev->next = next;
-    current_midi_point->next = newev;
     current_midi_point = newev;
-    event_count++;
 }
 
 void readmidi_add_ctl_event(int32 at, int ch, int a, int b)
@@ -2116,6 +2128,7 @@ static void readmidi_read_init(void)
     evlist->event.channel = 0;
     evlist->event.a = 0;
     evlist->event.b = 0;
+    evlist->prev = NULL;
     evlist->next = NULL;
     readmidi_error_flag = 0;
     event_count = 1;
index c8e6912..6c1b86d 100644 (file)
@@ -76,6 +76,7 @@ enum {
 typedef struct {
   MidiEvent event;
   void *next;
+  void *prev;
 } MidiEventList;
 
 struct midi_file_info
index a48022b..ce934f5 100644 (file)
@@ -429,6 +429,7 @@ static void help(void)
 "                           (UNIX only)",
 "                   ascii : Convert unreadable characters to '.'(0x2e)",
 "                   nocnv : No conversion",
+"                   1251  : Convert from windows-1251 to koi8-r",
 #ifdef JAPANESE
 "                   euc   : EUC-japan",
 "                   jis   : JIS",
@@ -2629,9 +2630,14 @@ MAIN_INTERFACE int set_tim_opt(int c, char *optarg)
 
       case 'R':
         tmpi32 = atoi(optarg);
-        if(set_value(&modify_release, tmpi32, 0, MAX_MREL, "Modify Release"))
-           return 1;
-       if (modify_release==0) modify_release=DEFAULT_MREL;
+       if(tmpi32 == -1) {
+           /* reset */
+           modify_release = 0;
+       } else {
+           if(set_value(&modify_release, tmpi32, 0, MAX_MREL, "Modify Release"))
+               return 1;
+           if (modify_release==0) modify_release=DEFAULT_MREL;
+       }
         break;
 
       case 'r':