Initial commit

This commit is contained in:
Brian Harris
2012-11-26 12:58:24 -06:00
parent a5214f79ef
commit 5016f605b8
1115 changed files with 587266 additions and 0 deletions

112
doomclassic/timidity/FAQ Normal file
View File

@@ -0,0 +1,112 @@
---------------------------*-indented-text-*------------------------------
TiMidity -- Experimental MIDI to WAVE converter
Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
--------------------------------------------------------------------------
Frequently Asked Questions with answers:
--------------------------------------------------------------------------
Q: What is it?
A: Where? Well Chris, TiMidity is a software-only synthesizer, MIDI
renderer, MIDI to WAVE converter, realtime MIDI player for UNIX machines,
even (I've heard) a Netscape helper application. It takes a MIDI file
and writes a WAVE or raw PCM data or plays it on your digital audio
device. It sounds much more realistic than FM synthesis, but you need a
~100Mhz processor to listen to 32kHz stereo music in the background while
you work. 11kHz mono can be played on a low-end 486, and, to some, it
still sounds better than FM.
--------------------------------------------------------------------------
Q: I don't have a GUS, can I use TiMidity?
A: Yes. That's the point. You don't need a Gravis Ultrasound to use
TiMidity, you just need GUS-compatible patches, which are freely
available on the Internet. See below for pointers.
--------------------------------------------------------------------------
Q: I have a GUS, can I use TiMidity?
A: The DOS port doesn't have GUS support, and TiMidity won't be taking
advantage of the board's internal synthesizer under other operating
systems either. So it kind of defeats the purpose. But you can use it.
--------------------------------------------------------------------------
Q: I tried playing a MIDI file I got off the Net but all I got was a
dozen warnings saying "No instrument mapped to tone bank 0, program
xx - this instrument will not be heard". What's wrong?
A: The General MIDI standard specifies 128 melodic instruments and
some sixty percussion sounds. If you wish to play arbitrary General
MIDI files, you'll need to get more patch files.
There's a program called Midia for SGI's, which also plays MIDI
files and has a lot more bells and whistles than TiMidity. It uses
GUS-compatible patches, too -- so you can get the 8 MB set at
ftp://archive.cs.umbc.edu/pub/midia for pretty good GM compatibility.
There are also many excellent patches on the Ultrasound FTP sites.
I can recommend Dustin McCartney's collections gsdrum*.zip and
wow*.zip in the "[.../]sound/patches/files" directory. The huge
ProPats series (pp3-*.zip) contains good patches as well. General
MIDI files can also be found on these sites.
This site list is from the GUS FAQ:
> FTP Sites Archive Directories
> --------- -------------------
> Main N.American Site: archive.orst.edu pub/packages/gravis
> wuarchive.wustl.edu systems/ibmpc/ultrasound
> Main Asian Site: nctuccca.edu.tw PC/ultrasound
> Main European Site: src.doc.ic.ac.uk packages/ultrasound
> Main Australian Site: ftp.mpx.com.au /ultrasound/general
> /ultrasound/submit
> South African Site: ftp.sun.ac.za /pub/packages/ultrasound
> Submissions: archive.epas.utoronto.ca pub/pc/ultrasound/submit
> Newly Validated Files: archive.epas.utoronto.ca pub/pc/ultrasound
>
> Mirrors: garbo.uwasa.fi mirror/ultrasound
> ftp.st.nepean.uws.edu.au pc/ultrasound
> ftp.luth.se pub/msdos/ultrasound
--------------------------------------------------------------------------
Q: Some files have awful clicks and pops.
A: Find out which patch is responsible for the clicking (try "timidity
-P<patch> <midi/test-decay|midi/test-panning>". Add "strip=tail" in
the config file after its name. If this doesn't fix it, mail me the
patch.
--------------------------------------------------------------------------
Q: I'm playing Fantasie Impromptu in the background. When I run Netscape,
the sound gets choppy and it takes ten minutes to load. What can I do?
A: Here are some things to try:
- Use a lower sampling rate.
- Use mono output. This can improve performance by 10-30%.
(Using 8-bit instead of 16-bit output makes no difference.)
- Use a smaller number of simultaneous voices.
- Make sure you compiled with FAST_DECAY and PRECALC_LOOPS enabled
in config.h
- If you don't have hardware to compute sines, recompile with
LOOKUP_SINE enabled in config.h
- Recompile with LOOKUP_HACK enabled in config.h.
- Recompile with LINEAR_INTERPOLATION disabled in config.h.
- Recompile with DANGEROUS_RENICE enabled in config.h, and make
TiMidity setuid root. This will help only if you frequently play
music while other processes are running.
- Recompile with an Intel-optimized gcc for a 5-15%
performance increase.
--------------------------------------------------------------------------

View File

@@ -0,0 +1,60 @@
[This version of timidity has been stripped for simplicity in porting to SDL]
---------------------------------*-text-*---------------------------------
From http://www.cgs.fi/~tt/discontinued.html :
If you'd like to continue hacking on TiMidity, feel free. I'm
hereby extending the TiMidity license agreement: you can now
select the most convenient license for your needs from (1) the
GNU GPL, (2) the GNU LGPL, or (3) the Perl Artistic License.
--------------------------------------------------------------------------
This is the README file for TiMidity v0.2i
TiMidity is a MIDI to WAVE converter that uses Gravis
Ultrasound(*)-compatible patch files to generate digital audio data
from General MIDI files. The audio data can be played through any
sound device or stored on disk. On a fast machine, music can be
played in real time. TiMidity runs under Linux, FreeBSD, HP-UX, SunOS, and
Win32, and porting to other systems with gcc should be easy.
TiMidity Features:
* 32 or more dynamically allocated fully independent voices
* Compatibility with GUS patch files
* Output to 16- or 8-bit PCM or uLaw audio device, file, or
stdout at any sampling rate
* Optional interactive mode with real-time status display
under ncurses and SLang terminal control libraries. Also
a user friendly motif interface since version 0.2h
* Support for transparent loading of compressed MIDI files and
patch files
* Support for the following MIDI events:
- Program change
- Key pressure
- Channel main volume
- Tempo
- Panning
- Damper pedal (Sustain)
- Pitch wheel
- Pitch wheel sensitivity
- Change drum set
* The GNU General Public License can, as always, be found in the file
"../COPYING".
* TiMidity requires sampled instruments (patches) to play MIDI files. You
should get the file "timidity-lib-0.1.tar.gz" and unpack it in the same
directory where you unpacked the source code archive. You'll want more
patches later -- read the file "FAQ" for pointers.
* Timidity is no longer supported, but can be found by searching the web.
Tuukka Toivonen <toivonen@clinet.fi>
[(*) Any Registered Trademarks used anywhere in the documentation or
source code for TiMidity are acknowledged as belonging to their
respective owners.]

View File

@@ -0,0 +1,178 @@
/*
TiMidity -- Experimental MIDI to WAVE converter
Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
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., 675 Mass Ave, Cambridge, MA 02139, USA.
common.c
*/
#include "../../neo/idlib/precompiled.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "config.h"
#include "common.h"
#include "output.h"
#include "controls.h"
/* I guess "rb" should be right for any libc */
#define OPEN_MODE "rb"
char current_filename[1024];
#ifdef DEFAULT_PATH
/* The paths in this list will be tried whenever we're reading a file */
static PathList defaultpathlist={DEFAULT_PATH,0};
static PathList *pathlist=&defaultpathlist; /* This is a linked list */
#else
static PathList *pathlist=0;
#endif
/* Try to open a file for reading. If the filename ends in one of the
defined compressor extensions, pipe the file through the decompressor */
static idFile * try_to_open(char *name, int decompress, int noise_mode)
{
idFile * fp;
fp = fileSystem->OpenFileRead( name );
if (!fp)
return 0;
return fp;
}
/* This is meant to find and open files for reading, possibly piping
them through a decompressor. */
idFile * open_file(const char *name, int decompress, int noise_mode)
{
idFile * fp;
PathList *plp=pathlist;
int l;
if (!name || !(*name))
{
ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Attempted to open nameless file.");
return 0;
}
/* First try the given name */
strncpy(current_filename, name, 1023);
current_filename[1023]='\0';
ctl->cmsg(CMSG_INFO, VERB_DEBUG, "Trying to open %s", current_filename);
if ((fp=try_to_open(current_filename, decompress, noise_mode)))
return fp;
if (name[0] != PATH_SEP)
while (plp) /* Try along the path then */
{
*current_filename=0;
l=strlen(plp->path);
if(l)
{
strcpy(current_filename, plp->path);
if(current_filename[l-1]!=PATH_SEP)
strcat(current_filename, PATH_STRING);
}
strcat(current_filename, name);
ctl->cmsg(CMSG_INFO, VERB_DEBUG, "Trying to open %s", current_filename);
if ((fp=try_to_open(current_filename, decompress, noise_mode)))
return fp;
plp=(PathList*)plp->next;
}
/* Nothing could be opened. */
*current_filename=0;
if (noise_mode>=2)
ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: %s", name, strerror(errno));
return 0;
}
/* This closes files opened with open_file */
void close_file(idFile * fp)
{
delete fp;
}
/* This is meant for skipping a few bytes in a file or fifo. */
void skip(idFile * fp, size_t len)
{
size_t c;
char tmp[1024];
while (len>0)
{
c=len;
if (c>1024) c=1024;
len-=c;
if (c!=fp->Read(tmp, c ))
ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: skip: %s",
current_filename, strerror(errno));
}
}
//extern void *Real_Tim_Malloc( size_t );
/* This'll allocate memory or die. */
void *safe_malloc(size_t count)
{
void *p;
if (count > (1<<21))
{
ctl->cmsg(CMSG_FATAL, VERB_NORMAL,
"Strange, I feel like allocating %d bytes. This must be a bug.",
count);
}
else if ((p=Real_Tim_Malloc(count)))
return p;
else
ctl->cmsg(CMSG_FATAL, VERB_NORMAL, "Sorry. Couldn't malloc %d bytes.", count);
ctl->close();
//exit(10);
return(NULL);
}
/* This adds a directory to the path list */
void add_to_pathlist(char *s)
{
PathList *plp=(PathList*)safe_malloc(sizeof(PathList));
strcpy((plp->path=(char *)safe_malloc(strlen(s)+1)),s);
plp->next=pathlist;
pathlist=plp;
}
/* Required memory management functions */
void *Real_Tim_Malloc( int sz ) {
return malloc( sz );
}
void Real_Tim_Free( void *pt ) {
free( pt );
}
void* Real_Malloc( unsigned int sz ) {
return malloc( sz );
}

View File

@@ -0,0 +1,42 @@
/*
TiMidity -- Experimental MIDI to WAVE converter
Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
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., 675 Mass Ave, Cambridge, MA 02139, USA.
common.h
*/
class idFile;
extern char *program_name, current_filename[];
extern FILE *msgfp;
typedef struct {
char *path;
void *next;
} PathList;
/* Noise modes for open_file */
#define OF_SILENT 0
#define OF_NORMAL 1
#define OF_VERBOSE 2
extern idFile * open_file(const char *name, int decompress, int noise_mode);
extern void add_to_pathlist(char *s);
extern void close_file(idFile * fp);
extern void skip(idFile * fp, size_t len);
extern void *safe_malloc(size_t count);

View File

@@ -0,0 +1,206 @@
/*
TiMidity -- Experimental MIDI to WAVE converter
Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* This is for use with the SDL library */
#define SDL
#if (defined(WIN32) || defined(_WIN32)) && !defined(__WIN32__)
#define __WIN32__
#endif
#define LITTLE_ENDIAN
#include <stdint.h>
/* When a patch file can't be opened, one of these extensions is
appended to the filename and the open is tried again.
*/
#define PATCH_EXT_LIST { ".pat", 0 }
/* Acoustic Grand Piano seems to be the usual default instrument. */
#define DEFAULT_PROGRAM 0
/* 9 here is MIDI channel 10, which is the standard percussion channel.
Some files (notably C:\WINDOWS\CANYON.MID) think that 16 is one too.
On the other hand, some files know that 16 is not a drum channel and
try to play music on it. This is now a runtime option, so this isn't
a critical choice anymore. */
//#define DEFAULT_DRUMCHANNELS ((1<<9) | (1<<15))
#define DEFAULT_DRUMCHANNELS ((1<<9))
/* A somewhat arbitrary frequency range. The low end of this will
sound terrible as no lowpass filtering is performed on most
instruments before resampling. */
#define MIN_OUTPUT_RATE 4000
#define MAX_OUTPUT_RATE 65000
/* In percent. */
#define DEFAULT_AMPLIFICATION 70
/* Default sampling rate, default polyphony, and maximum polyphony.
All but the last can be overridden from the command line. */
#define DEFAULT_RATE 32000
#define DEFAULT_VOICES 32
#define MAX_VOICES 48
/* 1000 here will give a control ratio of 22:1 with 22 kHz output.
Higher CONTROLS_PER_SECOND values allow more accurate rendering
of envelopes and tremolo. The cost is CPU time. */
#define CONTROLS_PER_SECOND 1000
/* Strongly recommended. This option increases CPU usage by half, but
without it sound quality is very poor. */
#define LINEAR_INTERPOLATION
/* This is an experimental kludge that needs to be done right, but if
you've got an 8-bit sound card, or cheap multimedia speakers hooked
to your 16-bit output device, you should definitely give it a try.
Defining LOOKUP_HACK causes table lookups to be used in mixing
instead of multiplication. We convert the sample data to 8 bits at
load time and volumes to logarithmic 7-bit values before looking up
the product, which degrades sound quality noticeably.
Defining LOOKUP_HACK should save ~20% of CPU on an Intel machine.
LOOKUP_INTERPOLATION might give another ~5% */
/* #define LOOKUP_HACK
#define LOOKUP_INTERPOLATION */
/* Make envelopes twice as fast. Saves ~20% CPU time (notes decay
faster) and sounds more like a GUS. There is now a command line
option to toggle this as well. */
#define FAST_DECAY
/* How many bits to use for the fractional part of sample positions.
This affects tonal accuracy. The entire position counter must fit
in 32 bits, so with FRACTION_BITS equal to 12, the maximum size of
a sample is 1048576 samples (2 megabytes in memory). The GUS gets
by with just 9 bits and a little help from its friends...
"The GUS does not SUCK!!!" -- a happy user :) */
#define FRACTION_BITS 12
/* For some reason the sample volume is always set to maximum in all
patch files. Define this for a crude adjustment that may help
equalize instrument volumes. */
#define ADJUST_SAMPLE_VOLUMES
/* The number of samples to use for ramping out a dying note. Affects
click removal. */
#define MAX_DIE_TIME 20
/* On some machines (especially PCs without math coprocessors),
looking up sine values in a table will be significantly faster than
computing them on the fly. Uncomment this to use lookups. */
/* #define LOOKUP_SINE */
/* Shawn McHorse's resampling optimizations. These may not in fact be
faster on your particular machine and compiler. You'll have to run
a benchmark to find out. */
#define PRECALC_LOOPS
/* If calling ldexp() is faster than a floating point multiplication
on your machine/compiler/libm, uncomment this. It doesn't make much
difference either way, but hey -- it was on the TODO list, so it
got done. */
/* #define USE_LDEXP */
/**************************************************************************/
/* Anything below this shouldn't need to be changed unless you're porting
to a new machine with other than 32-bit, big-endian words. */
/**************************************************************************/
/* change FRACTION_BITS above, not these */
#define INTEGER_BITS (32 - FRACTION_BITS)
#define INTEGER_MASK (0xFFFFFFFF << FRACTION_BITS)
#define FRACTION_MASK (~ INTEGER_MASK)
/* This is enforced by some computations that must fit in an int */
#define MAX_CONTROL_RATIO 255
/* Instrument files are little-endian, MIDI files big-endian, so we
need to do some conversions. */
#define XCHG_SHORT(x) ((((x)&0xFF)<<8) | (((x)>>8)&0xFF))
# define XCHG_LONG(x) ((((x)&0xFF)<<24) | \
(((x)&0xFF00)<<8) | \
(((x)&0xFF0000)>>8) | \
(((x)>>24)&0xFF))
#ifdef LITTLE_ENDIAN
#define LE_SHORT(x) x
#define LE_LONG(x) x
#define BE_SHORT(x) XCHG_SHORT(x)
#define BE_LONG(x) XCHG_LONG(x)
#else
#define BE_SHORT(x) x
#define BE_LONG(x) x
#define LE_SHORT(x) XCHG_SHORT(x)
#define LE_LONG(x) XCHG_LONG(x)
#endif
#define MAX_AMPLIFICATION 800
/* These affect general volume */
#define GUARD_BITS 3
#define AMP_BITS (15-GUARD_BITS)
#ifdef LOOKUP_HACK
typedef int8_t sample_t;
typedef uint8_t final_volume_t;
# define FINAL_VOLUME(v) (~_l2u[v])
# define MIXUP_SHIFT 5
# define MAX_AMP_VALUE 4095
#else
typedef int16_t sample_t;
typedef int32_t final_volume_t;
# define FINAL_VOLUME(v) (v)
# define MAX_AMP_VALUE ((1<<(AMP_BITS+1))-1)
#endif
#ifdef USE_LDEXP
# define FSCALE(a,b) ldexp((a),(b))
# define FSCALENEG(a,b) ldexp((a),-(b))
#else
# define FSCALE(a,b) (float)((a) * (double)(1<<(b)))
# define FSCALENEG(a,b) (float)((a) * (1.0L / (double)(1<<(b))))
#endif
/* Vibrato and tremolo Choices of the Day */
#define SWEEP_TUNING 38
#define VIBRATO_AMPLITUDE_TUNING 1.0L
#define VIBRATO_RATE_TUNING 38
#define TREMOLO_AMPLITUDE_TUNING 1.0L
#define TREMOLO_RATE_TUNING 38
#define SWEEP_SHIFT 16
#define RATE_SHIFT 5
#define VIBRATO_SAMPLE_INCREMENTS 32
#ifndef PI
const float PI = 3.14159265358979323846f;
#endif
/* The path separator (D.M.) */
//#ifdef __WIN32__
# define PATH_SEP '\\'
# define PATH_STRING "\\"
//#else
//# define PATH_SEP '/'
//# define PATH_STRING "/"
//#endif

View File

@@ -0,0 +1,41 @@
/*
TiMidity -- Experimental MIDI to WAVE converter
Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
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., 675 Mass Ave, Cambridge, MA 02139, USA.
controls.c
*/
#include "config.h"
#include "controls.h"
#ifdef SDL
extern ControlMode sdl_control_mode;
# ifndef DEFAULT_CONTROL_MODE
# define DEFAULT_CONTROL_MODE &sdl_control_mode
# endif
#endif
ControlMode *ctl_list[]={
#ifdef SDL
&sdl_control_mode,
#endif
0
};
ControlMode *ctl=DEFAULT_CONTROL_MODE;

View File

@@ -0,0 +1,89 @@
/*
TiMidity -- Experimental MIDI to WAVE converter
Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
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., 675 Mass Ave, Cambridge, MA 02139, USA.
controls.h
*/
/* Return values for ControlMode.read */
#define RC_ERROR -1
#define RC_NO_RETURN_VALUE 0
#define RC_QUIT 1
#define RC_NEXT 2
#define RC_PREVIOUS 3 /* Restart this song at beginning, or the previous
song if we're less than a second into this one. */
#define RC_FORWARD 4
#define RC_BACK 5
#define RC_JUMP 6
#define RC_TOGGLE_PAUSE 7 /* Pause/continue */
#define RC_RESTART 8 /* Restart song at beginning */
#define RC_PAUSE 9 /* Really pause playing */
#define RC_CONTINUE 10 /* Continue if paused */
#define RC_REALLY_PREVIOUS 11 /* Really go to the previous song */
#define RC_CHANGE_VOLUME 12
#define RC_LOAD_FILE 13 /* Load a new midifile */
#define RC_TUNE_END 14 /* The tune is over, play it again sam? */
#define CMSG_INFO 0
#define CMSG_WARNING 1
#define CMSG_ERROR 2
#define CMSG_FATAL 3
#define CMSG_TRACE 4
#define CMSG_TIME 5
#define CMSG_TOTAL 6
#define CMSG_FILE 7
#define CMSG_TEXT 8
#define VERB_NORMAL 0
#define VERB_VERBOSE 1
#define VERB_NOISY 2
#define VERB_DEBUG 3
#define VERB_DEBUG_SILLY 4
typedef struct {
char *id_name, id_character;
int verbosity, trace_playing, opened;
int (*open)(int using_stdin, int using_stdout);
void (*pass_playing_list)(int number_of_files, char *list_of_files[]);
void (*close)(void);
int (*read)(int *valp);
int (*cmsg)(int type, int verbosity_level, char *fmt, ...);
void (*refresh)(void);
void (*reset)(void);
void (*file_name)(char *name);
void (*total_time)(int tt);
void (*current_time)(int ct);
void (*note)(int v);
void (*master_volume)(int mv);
void (*program)(int channel, int val); /* val<0 means drum set -val */
void (*volume)(int channel, int val);
void (*expression)(int channel, int val);
void (*panning)(int channel, int val);
void (*sustain)(int channel, int val);
void (*pitch_bend)(int channel, int val);
} ControlMode;
extern ControlMode *ctl_list[], *ctl;
const int TIMIDITY_ERROR_MAX_CHARS = 1024;
extern char timidity_error[];

View File

@@ -0,0 +1,205 @@
/*
TiMidity -- Experimental MIDI to WAVE converter
Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
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., 675 Mass Ave, Cambridge, MA 02139, USA.
filter.c: written by Vincent Pagel ( pagel@loria.fr )
implements fir antialiasing filter : should help when setting sample
rates as low as 8Khz.
April 95
- first draft
22/5/95
- modify "filter" so that it simulate leading and trailing 0 in the buffer
*/
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include "config.h"
#include "common.h"
#include "controls.h"
#include "instrum.h"
#include "filter.h"
void Real_Tim_Free( void *pt );
/* bessel function */
static float ino(float x)
{
float y, de, e, sde;
int i;
y = x / 2;
e = 1.0;
de = 1.0;
i = 1;
do {
de = de * y / (float) i;
sde = de * de;
e += sde;
} while (!( (e * 1.0e-08 - sde > 0) || (i++ > 25) ));
return(e);
}
/* Kaiser Window (symetric) */
static void kaiser(float *w,int n,float beta)
{
float xind, xi;
int i;
xind = (float)((2*n - 1) * (2*n - 1));
for (i =0; i<n ; i++)
{
xi = (float)(i + 0.5);
w[i] = ino((float)(beta * sqrt((double)(1. - 4 * xi * xi / xind))))
/ ino((float)beta);
}
}
/*
* fir coef in g, cuttoff frequency in fc
*/
static void designfir(float *g , float fc)
{
int i;
float xi, omega, att, beta ;
float w[ORDER2];
for (i =0; i < ORDER2 ;i++)
{
xi = (float) (i + 0.5);
omega = (float)(PI * xi);
g[i] = (float)(sin( (double) omega * fc) / omega);
}
att = 40.; /* attenuation in db */
beta = (float) (exp(log((double)0.58417 * (att - 20.96)) * 0.4) + 0.07886
* (att - 20.96));
kaiser( w, ORDER2, beta);
/* Matrix product */
for (i =0; i < ORDER2 ; i++)
g[i] = g[i] * w[i];
}
/*
* FIR filtering -> apply the filter given by coef[] to the data buffer
* Note that we simulate leading and trailing 0 at the border of the
* data buffer
*/
static void filter(sample_t *result,sample_t *data, int32_t length,float coef[])
{
int32_t sample,i,sample_window;
int16_t peak = 0;
float sum;
/* Simulate leading 0 at the begining of the buffer */
for (sample = 0; sample < ORDER2 ; sample++ )
{
sum = 0.0;
sample_window= sample - ORDER2;
for (i = 0; i < ORDER ;i++)
sum += (float)(coef[i] *
((sample_window<0)? 0.0 : data[sample_window++])) ;
/* Saturation ??? */
if (sum> 32767.) { sum=32767.; peak++; }
if (sum< -32768.) { sum=-32768; peak++; }
result[sample] = (sample_t) sum;
}
/* The core of the buffer */
for (sample = ORDER2; sample < length - ORDER + ORDER2 ; sample++ )
{
sum = 0.0;
sample_window= sample - ORDER2;
for (i = 0; i < ORDER ;i++)
sum += data[sample_window++] * coef[i];
/* Saturation ??? */
if (sum> 32767.) { sum=32767.; peak++; }
if (sum< -32768.) { sum=-32768; peak++; }
result[sample] = (sample_t) sum;
}
/* Simulate 0 at the end of the buffer */
for (sample = length - ORDER + ORDER2; sample < length ; sample++ )
{
sum = 0.0;
sample_window= sample - ORDER2;
for (i = 0; i < ORDER ;i++)
sum += (float)(coef[i] *
((sample_window>=length)? 0.0 : data[sample_window++])) ;
/* Saturation ??? */
if (sum> 32767.) { sum=32767.; peak++; }
if (sum< -32768.) { sum=-32768; peak++; }
result[sample] = (sample_t) sum;
}
if (peak)
ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
"Saturation %2.3f %%.", 100.0*peak/ (float) length);
}
/***********************************************************************/
/* Prevent aliasing by filtering any freq above the output_rate */
/* */
/* I don't worry about looping point -> they will remain soft if they */
/* were already */
/***********************************************************************/
void antialiasing(Sample *sp, int32_t output_rate )
{
sample_t *temp;
int i;
float fir_symetric[ORDER];
float fir_coef[ORDER2];
float freq_cut; /* cutoff frequency [0..1.0] FREQ_CUT/SAMP_FREQ*/
ctl->cmsg(CMSG_INFO, VERB_NOISY, "Antialiasing: Fsample=%iKHz",
sp->sample_rate);
/* No oversampling */
if (output_rate>=sp->sample_rate)
return;
freq_cut= (float) output_rate / (float) sp->sample_rate;
ctl->cmsg(CMSG_INFO, VERB_NOISY, "Antialiasing: cutoff=%f%%",
freq_cut*100.);
designfir(fir_coef,freq_cut);
/* Make the filter symetric */
for (i = 0 ; i<ORDER2 ;i++)
fir_symetric[ORDER-1 - i] = fir_symetric[i] = fir_coef[ORDER2-1 - i];
/* We apply the filter we have designed on a copy of the patch */
temp = (sample_t*)safe_malloc(sp->data_length);
memcpy(temp,sp->data,sp->data_length);
filter(sp->data,temp,sp->data_length/sizeof(sample_t),fir_symetric);
Real_Tim_Free(temp);
}

View File

@@ -0,0 +1,35 @@
/*
TiMidity -- Experimental MIDI to WAVE converter
Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
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., 675 Mass Ave, Cambridge, MA 02139, USA.
filter.h : written by Vincent Pagel ( pagel@loria.fr )
implements fir antialiasing filter : should help when setting sample
rates as low as 8Khz.
*/
/* Order of the FIR filter = 20 should be enough ! */
#define ORDER 20
#define ORDER2 ORDER/2
#ifndef PI
extern const float PI;
#endif
extern void antialiasing(Sample *sp, int32_t output_rate);

View File

@@ -0,0 +1,683 @@
/*
TiMidity -- Experimental MIDI to WAVE converter
Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
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., 675 Mass Ave, Cambridge, MA 02139, USA.
instrum.c
Code to load and unload GUS-compatible instrument patches.
*/
#include "../../neo/idlib/precompiled.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include "config.h"
#include "common.h"
#include "instrum.h"
#include "playmidi.h"
#include "output.h"
#include "controls.h"
#include "resample.h"
#include "tables.h"
#include "filter.h"
//void Real_Tim_Free( void *pt );
/* Some functions get aggravated if not even the standard banks are
available. */
static ToneBank standard_tonebank, standard_drumset;
ToneBank
*tonebank[128]={&standard_tonebank},
*drumset[128]={&standard_drumset};
/* This is a special instrument, used for all melodic programs */
Instrument *default_instrument=0;
/* This is only used for tracks that don't specify a program */
int default_program=DEFAULT_PROGRAM;
int antialiasing_allowed=0;
#ifdef FAST_DECAY
int fast_decay=1;
#else
int fast_decay=0;
#endif
static void free_instrument(Instrument *ip)
{
Sample *sp;
int i;
if (!ip) return;
for (i=0; i<ip->samples; i++)
{
sp=&(ip->sample[i]);
Real_Tim_Free(sp->data);
}
Real_Tim_Free(ip->sample);
Real_Tim_Free(ip);
}
static void free_bank(int dr, int b)
{
int i;
ToneBank *bank=((dr) ? drumset[b] : tonebank[b]);
for (i=0; i<128; i++) {
if (bank->tone[i].instrument)
{
/* Not that this could ever happen, of course */
if (bank->tone[i].instrument != MAGIC_LOAD_INSTRUMENT)
free_instrument(bank->tone[i].instrument);
bank->tone[i].instrument=0;
}
if (bank->tone[i].name)
{
Real_Tim_Free( bank->tone[i].name );
bank->tone[i].name = NULL;
}
}
}
static int32_t convert_envelope_rate(uint8_t rate)
{
int32_t r;
r=3-((rate>>6) & 0x3);
r*=3;
r = (int32_t)(rate & 0x3f) << r; /* 6.9 fixed point */
/* 15.15 fixed point. */
return (((r * 44100) / play_mode->rate) * control_ratio)
<< ((fast_decay) ? 10 : 9);
}
static int32_t convert_envelope_offset(uint8_t offset)
{
/* This is not too good... Can anyone tell me what these values mean?
Are they GUS-style "exponential" volumes? And what does that mean? */
/* 15.15 fixed point */
return offset << (7+15);
}
static int32_t convert_tremolo_sweep(uint8_t sweep)
{
if (!sweep)
return 0;
return
((control_ratio * SWEEP_TUNING) << SWEEP_SHIFT) /
(play_mode->rate * sweep);
}
static int32_t convert_vibrato_sweep(uint8_t sweep, int32_t vib_control_ratio)
{
if (!sweep)
return 0;
return
(int32_t) (FSCALE((double) (vib_control_ratio) * SWEEP_TUNING, SWEEP_SHIFT)
/ (double)(play_mode->rate * sweep));
/* this was overflowing with seashore.pat
((vib_control_ratio * SWEEP_TUNING) << SWEEP_SHIFT) /
(play_mode->rate * sweep); */
}
static int32_t convert_tremolo_rate(uint8_t rate)
{
return
((SINE_CYCLE_LENGTH * control_ratio * rate) << RATE_SHIFT) /
(TREMOLO_RATE_TUNING * play_mode->rate);
}
static int32_t convert_vibrato_rate(uint8_t rate)
{
/* Return a suitable vibrato_control_ratio value */
return
(VIBRATO_RATE_TUNING * play_mode->rate) /
(rate * 2 * VIBRATO_SAMPLE_INCREMENTS);
}
static void reverse_data(int16_t *sp, int32_t ls, int32_t le)
{
int16_t s, *ep=sp+le;
sp+=ls;
le-=ls;
le/=2;
while (le--)
{
s=*sp;
*sp++=*ep;
*ep--=s;
}
}
/*
If panning or note_to_use != -1, it will be used for all samples,
instead of the sample-specific values in the instrument file.
For note_to_use, any value <0 or >127 will be forced to 0.
For other parameters, 1 means yes, 0 means no, other values are
undefined.
TODO: do reverse loops right */
static Instrument *load_instrument(char *name, int percussion,
int panning, int amp, int note_to_use,
int strip_loop, int strip_envelope,
int strip_tail)
{
Instrument *ip;
Sample *sp;
idFile * fp;
uint8_t tmp[1024];
int i,j,noluck=0;
char *path;
char filename[1024];
#ifdef PATCH_EXT_LIST
static char *patch_ext[] = PATCH_EXT_LIST;
#endif
if (!name) return 0;
path = "classicmusic/instruments/";
idStr instName = name;
instName.ToUpper();
strcpy( filename, path );
strcat( filename, instName.c_str() );
strcat( filename, ".PAT" );
/* Open patch file */
if ((fp=open_file(filename, 1, OF_VERBOSE)) == NULL)
{
noluck=1;
#ifdef PATCH_EXT_LIST
/* Try with various extensions */
for (i=0; patch_ext[i]; i++)
{
if (strlen(name)+strlen(patch_ext[i])<1024)
{
strcpy(filename, path);
strcat(filename, name);
strcat(filename, patch_ext[i]);
if ((fp=open_file(filename, 1, OF_VERBOSE)) != NULL)
{
noluck=0;
break;
}
}
}
#endif
}
if (noluck)
{
ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
"Instrument `%s' can't be found.", name);
return 0;
}
ctl->cmsg(CMSG_INFO, VERB_NOISY, "Loading instrument %s", current_filename);
/* Read some headers and do cursory sanity checks. There are loads
of magic offsets. This could be rewritten... */
if ((239 != fp->Read(tmp, 239)) ||
(memcmp(tmp, "GF1PATCH110\0ID#000002", 22) &&
memcmp(tmp, "GF1PATCH100\0ID#000002", 22))) /* don't know what the
differences are */
{
ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: not an instrument", name);
return 0;
}
if (tmp[82] != 1 && tmp[82] != 0) /* instruments. To some patch makers,
0 means 1 */
{
ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
"Can't handle patches with %d instruments", tmp[82]);
return 0;
}
if (tmp[151] != 1 && tmp[151] != 0) /* layers. What's a layer? */
{
ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
"Can't handle instruments with %d layers", tmp[151]);
return 0;
}
ip=(Instrument *)safe_malloc(sizeof(Instrument));
ip->samples = tmp[198];
ip->sample = (Sample *)safe_malloc(sizeof(Sample) * ip->samples);
for (i=0; i<ip->samples; i++)
{
uint8_t fractions;
int32_t tmplong;
uint16_t tmpshort;
uint8_t tmpchar;
#define READ_CHAR(thing) \
if (1 != fp->Read(&tmpchar, 1)) goto fail; \
thing = tmpchar;
#define READ_SHORT(thing) \
if (2 != fp->Read(&tmpshort, 2 )) goto fail; \
thing = LE_SHORT(tmpshort);
#define READ_LONG(thing) \
if (4 != fp->Read(&tmplong, 4 )) goto fail; \
thing = LE_LONG(tmplong);
skip(fp, 7); /* Skip the wave name */
if (1 != fp->Read(&fractions, 1 ))
{
fail:
ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Error reading sample %d", i);
for (j=0; j<i; j++)
Real_Tim_Free(ip->sample[j].data);
Real_Tim_Free(ip->sample);
Real_Tim_Free(ip);
return 0;
}
sp=&(ip->sample[i]);
READ_LONG(sp->data_length);
READ_LONG(sp->loop_start);
READ_LONG(sp->loop_end);
READ_SHORT(sp->sample_rate);
READ_LONG(sp->low_freq);
READ_LONG(sp->high_freq);
READ_LONG(sp->root_freq);
skip(fp, 2); /* Why have a "root frequency" and then "tuning"?? */
READ_CHAR(tmp[0]);
if (panning==-1)
sp->panning = (tmp[0] * 8 + 4) & 0x7f;
else
sp->panning=(uint8)(panning & 0x7F);
/* envelope, tremolo, and vibrato */
if (18 != fp->Read(tmp, 18)) goto fail;
if (!tmp[13] || !tmp[14])
{
sp->tremolo_sweep_increment=
sp->tremolo_phase_increment=sp->tremolo_depth=0;
ctl->cmsg(CMSG_INFO, VERB_DEBUG, " * no tremolo");
}
else
{
sp->tremolo_sweep_increment=convert_tremolo_sweep(tmp[12]);
sp->tremolo_phase_increment=convert_tremolo_rate(tmp[13]);
sp->tremolo_depth=tmp[14];
ctl->cmsg(CMSG_INFO, VERB_DEBUG,
" * tremolo: sweep %d, phase %d, depth %d",
sp->tremolo_sweep_increment, sp->tremolo_phase_increment,
sp->tremolo_depth);
}
if (!tmp[16] || !tmp[17])
{
sp->vibrato_sweep_increment=
sp->vibrato_control_ratio=sp->vibrato_depth=0;
ctl->cmsg(CMSG_INFO, VERB_DEBUG, " * no vibrato");
}
else
{
sp->vibrato_control_ratio=convert_vibrato_rate(tmp[16]);
sp->vibrato_sweep_increment=
convert_vibrato_sweep(tmp[15], sp->vibrato_control_ratio);
sp->vibrato_depth=tmp[17];
ctl->cmsg(CMSG_INFO, VERB_DEBUG,
" * vibrato: sweep %d, ctl %d, depth %d",
sp->vibrato_sweep_increment, sp->vibrato_control_ratio,
sp->vibrato_depth);
}
READ_CHAR(sp->modes);
skip(fp, 40); /* skip the useless scale frequency, scale factor
(what's it mean?), and reserved space */
/* Mark this as a fixed-pitch instrument if such a deed is desired. */
if (note_to_use!=-1)
sp->note_to_use=(uint8)(note_to_use);
else
sp->note_to_use=0;
/* seashore.pat in the Midia patch set has no Sustain. I don't
understand why, and fixing it by adding the Sustain flag to
all looped patches probably breaks something else. We do it
anyway. */
if (sp->modes & MODES_LOOPING)
sp->modes |= MODES_SUSTAIN;
/* Strip any loops and envelopes we're permitted to */
if ((strip_loop==1) &&
(sp->modes & (MODES_SUSTAIN | MODES_LOOPING |
MODES_PINGPONG | MODES_REVERSE)))
{
ctl->cmsg(CMSG_INFO, VERB_DEBUG, " - Removing loop and/or sustain");
sp->modes &=~(MODES_SUSTAIN | MODES_LOOPING |
MODES_PINGPONG | MODES_REVERSE);
}
if (strip_envelope==1)
{
if (sp->modes & MODES_ENVELOPE)
ctl->cmsg(CMSG_INFO, VERB_DEBUG, " - Removing envelope");
sp->modes &= ~MODES_ENVELOPE;
}
else if (strip_envelope != 0)
{
/* Have to make a guess. */
if (!(sp->modes & (MODES_LOOPING | MODES_PINGPONG | MODES_REVERSE)))
{
/* No loop? Then what's there to sustain? No envelope needed
either... */
sp->modes &= ~(MODES_SUSTAIN|MODES_ENVELOPE);
ctl->cmsg(CMSG_INFO, VERB_DEBUG,
" - No loop, removing sustain and envelope");
}
else if (!memcmp(tmp, "??????", 6) || tmp[11] >= 100)
{
/* Envelope rates all maxed out? Envelope end at a high "offset"?
That's a weird envelope. Take it out. */
sp->modes &= ~MODES_ENVELOPE;
ctl->cmsg(CMSG_INFO, VERB_DEBUG,
" - Weirdness, removing envelope");
}
else if (!(sp->modes & MODES_SUSTAIN))
{
/* No sustain? Then no envelope. I don't know if this is
justified, but patches without sustain usually don't need the
envelope either... at least the Gravis ones. They're mostly
drums. I think. */
sp->modes &= ~MODES_ENVELOPE;
ctl->cmsg(CMSG_INFO, VERB_DEBUG,
" - No sustain, removing envelope");
}
}
for (j=0; j<6; j++)
{
sp->envelope_rate[j]=
convert_envelope_rate(tmp[j]);
sp->envelope_offset[j]=
convert_envelope_offset(tmp[6+j]);
}
/* Then read the sample data */
sp->data = (sample_t*)safe_malloc(sp->data_length);
if ( static_cast< size_t >( sp->data_length ) != fp->Read(sp->data, sp->data_length ))
goto fail;
if (!(sp->modes & MODES_16BIT)) /* convert to 16-bit data */
{
int32_t i=sp->data_length;
uint8_t *cp=(uint8_t *)(sp->data);
uint16_t *tmp,*anew;
tmp=anew=(uint16*)safe_malloc(sp->data_length*2);
while (i--)
*tmp++ = (uint16)(*cp++) << 8;
cp=(uint8_t *)(sp->data);
sp->data = (sample_t *)anew;
Real_Tim_Free(cp);
sp->data_length *= 2;
sp->loop_start *= 2;
sp->loop_end *= 2;
}
#ifndef LITTLE_ENDIAN
else
/* convert to machine byte order */
{
int32_t i=sp->data_length/2;
int16_t *tmp=(int16_t *)sp->data,s;
while (i--)
{
s=LE_SHORT(*tmp);
*tmp++=s;
}
}
#endif
if (sp->modes & MODES_UNSIGNED) /* convert to signed data */
{
int32_t i=sp->data_length/2;
int16_t *tmp=(int16_t *)sp->data;
while (i--)
*tmp++ ^= 0x8000;
}
/* Reverse reverse loops and pass them off as normal loops */
if (sp->modes & MODES_REVERSE)
{
int32_t t;
/* The GUS apparently plays reverse loops by reversing the
whole sample. We do the same because the GUS does not SUCK. */
ctl->cmsg(CMSG_WARNING, VERB_NORMAL, "Reverse loop in %s", name);
reverse_data((int16_t *)sp->data, 0, sp->data_length/2);
t=sp->loop_start;
sp->loop_start=sp->data_length - sp->loop_end;
sp->loop_end=sp->data_length - t;
sp->modes &= ~MODES_REVERSE;
sp->modes |= MODES_LOOPING; /* just in case */
}
/* If necessary do some anti-aliasing filtering */
if (antialiasing_allowed)
antialiasing(sp,play_mode->rate);
#ifdef ADJUST_SAMPLE_VOLUMES
if (amp!=-1)
sp->volume=(float)((amp) / 100.0);
else
{
/* Try to determine a volume scaling factor for the sample.
This is a very crude adjustment, but things sound more
balanced with it. Still, this should be a runtime option. */
int32_t i=sp->data_length/2;
int16_t maxamp=0,a;
int16_t *tmp=(int16_t *)sp->data;
while (i--)
{
a=*tmp++;
if (a<0) a=-a;
if (a>maxamp)
maxamp=a;
}
sp->volume=(float)(32768.0 / maxamp);
ctl->cmsg(CMSG_INFO, VERB_DEBUG, " * volume comp: %f", sp->volume);
}
#else
if (amp!=-1)
sp->volume=(double)(amp) / 100.0;
else
sp->volume=1.0;
#endif
sp->data_length /= 2; /* These are in bytes. Convert into samples. */
sp->loop_start /= 2;
sp->loop_end /= 2;
/* Then fractional samples */
sp->data_length <<= FRACTION_BITS;
sp->loop_start <<= FRACTION_BITS;
sp->loop_end <<= FRACTION_BITS;
/* Adjust for fractional loop points. This is a guess. Does anyone
know what "fractions" really stands for? */
sp->loop_start |=
(fractions & 0x0F) << (FRACTION_BITS-4);
sp->loop_end |=
((fractions>>4) & 0x0F) << (FRACTION_BITS-4);
/* If this instrument will always be played on the same note,
and it's not looped, we can resample it now. */
if (sp->note_to_use && !(sp->modes & MODES_LOOPING))
pre_resample(sp);
#ifdef LOOKUP_HACK
/* Squash the 16-bit data into 8 bits. */
{
uint8_t *gulp,*ulp;
int16_t *swp;
int l=sp->data_length >> FRACTION_BITS;
gulp=ulp=safe_malloc(l+1);
swp=(int16_t *)sp->data;
while(l--)
*ulp++ = (*swp++ >> 8) & 0xFF;
Real_Tim_Free(sp->data);
sp->data=(sample_t *)gulp;
}
#endif
if (strip_tail==1)
{
/* Let's not really, just say we did. */
ctl->cmsg(CMSG_INFO, VERB_DEBUG, " - Stripping tail");
sp->data_length = sp->loop_end;
}
}
delete fp;
return ip;
}
static int fill_bank(int dr, int b)
{
int i, errors=0;
ToneBank *bank=((dr) ? drumset[b] : tonebank[b]);
if (!bank)
{
ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
"Huh. Tried to load instruments in non-existent %s %d",
(dr) ? "drumset" : "tone bank", b);
return 0;
}
for (i=0; i<128; i++)
{
if (bank->tone[i].instrument==MAGIC_LOAD_INSTRUMENT)
{
if (!(bank->tone[i].name))
{
ctl->cmsg(CMSG_WARNING, (b!=0) ? VERB_VERBOSE : VERB_NORMAL,
"No instrument mapped to %s %d, program %d%s",
(dr)? "drum set" : "tone bank", b, i,
(b!=0) ? "" : " - this instrument will not be heard");
if (b!=0)
{
/* Mark the corresponding instrument in the default
bank / drumset for loading (if it isn't already) */
if (!dr)
{
if (!(standard_tonebank.tone[i].instrument))
standard_tonebank.tone[i].instrument=
MAGIC_LOAD_INSTRUMENT;
}
else
{
if (!(standard_drumset.tone[i].instrument))
standard_drumset.tone[i].instrument=
MAGIC_LOAD_INSTRUMENT;
}
}
bank->tone[i].instrument=0;
errors++;
}
else if (!(bank->tone[i].instrument=
load_instrument(bank->tone[i].name,
(dr) ? 1 : 0,
bank->tone[i].pan,
bank->tone[i].amp,
(bank->tone[i].note!=-1) ?
bank->tone[i].note :
((dr) ? i : -1),
(bank->tone[i].strip_loop!=-1) ?
bank->tone[i].strip_loop :
((dr) ? 1 : -1),
(bank->tone[i].strip_envelope != -1) ?
bank->tone[i].strip_envelope :
((dr) ? 1 : -1),
bank->tone[i].strip_tail )))
{
ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
"Couldn't load instrument %s (%s %d, program %d)",
bank->tone[i].name,
(dr)? "drum set" : "tone bank", b, i);
errors++;
}
}
}
return errors;
}
int load_missing_instruments(void)
{
int i=128,errors=0;
while (i--)
{
if (tonebank[i])
errors+=fill_bank(0,i);
if (drumset[i])
errors+=fill_bank(1,i);
}
return errors;
}
void free_instruments(void)
{
int i=128;
while(i--)
{
if (tonebank[i])
free_bank(0,i);
if (drumset[i])
free_bank(1,i);
}
}
int set_default_instrument(char *name)
{
Instrument *ip;
if (!(ip=load_instrument(name, 0, -1, -1, -1, 0, 0, 0)))
return -1;
if (default_instrument)
free_instrument(default_instrument);
default_instrument=ip;
default_program=SPECIAL_PROGRAM;
return 0;
}

View File

@@ -0,0 +1,84 @@
/*
TiMidity -- Experimental MIDI to WAVE converter
Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
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., 675 Mass Ave, Cambridge, MA 02139, USA.
instrum.h
*/
typedef struct {
int32_t
loop_start, loop_end, data_length,
sample_rate, low_freq, high_freq, root_freq;
int32_t
envelope_rate[6], envelope_offset[6];
float
volume;
sample_t *data;
int32_t
tremolo_sweep_increment, tremolo_phase_increment,
vibrato_sweep_increment, vibrato_control_ratio;
uint8_t
tremolo_depth, vibrato_depth,
modes;
int8_t
panning, note_to_use;
} Sample;
/* Bits in modes: */
#define MODES_16BIT (1<<0)
#define MODES_UNSIGNED (1<<1)
#define MODES_LOOPING (1<<2)
#define MODES_PINGPONG (1<<3)
#define MODES_REVERSE (1<<4)
#define MODES_SUSTAIN (1<<5)
#define MODES_ENVELOPE (1<<6)
typedef struct {
int samples;
Sample *sample;
} Instrument;
typedef struct {
char *name;
Instrument *instrument;
int note, amp, pan, strip_loop, strip_envelope, strip_tail;
} ToneBankElement;
/* A hack to delay instrument loading until after reading the
entire MIDI file. */
#define MAGIC_LOAD_INSTRUMENT ((Instrument *)(-1))
typedef struct {
ToneBankElement tone[128];
} ToneBank;
extern ToneBank *tonebank[], *drumset[];
extern Instrument *default_instrument;
extern int default_program;
extern int antialiasing_allowed;
extern int fast_decay;
extern int free_instruments_afterwards;
#define SPECIAL_PROGRAM -1
extern int load_missing_instruments(void);
extern void free_instruments(void);
extern int set_default_instrument(char *name);

View File

@@ -0,0 +1,569 @@
/*
TiMidity -- Experimental MIDI to WAVE converter
Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
Suddenly, you realize that this program is free software; you get
an overwhelming urge to 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 another copy of the GNU General Public
License along with this program; if not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
I bet they'll be amazed.
mix.c */
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include "config.h"
#include "common.h"
#include "instrum.h"
#include "playmidi.h"
#include "output.h"
#include "controls.h"
#include "tables.h"
#include "resample.h"
#include "mix.h"
/* Returns 1 if envelope runs out */
int recompute_envelope(int v)
{
int stage;
stage = voice[v].envelope_stage;
if (stage>5)
{
/* Envelope ran out. */
int tmp=(voice[v].status == VOICE_DIE); /* Already displayed as dead */
voice[v].status = VOICE_FREE;
if(!tmp)
ctl->note(v);
return 1;
}
if (voice[v].sample->modes & MODES_ENVELOPE)
{
if (voice[v].status==VOICE_ON || voice[v].status==VOICE_SUSTAINED)
{
if (stage>2)
{
/* Freeze envelope until note turns off. Trumpets want this. */
voice[v].envelope_increment=0;
return 0;
}
}
}
voice[v].envelope_stage=stage+1;
if (voice[v].envelope_volume==voice[v].sample->envelope_offset[stage])
return recompute_envelope(v);
voice[v].envelope_target=voice[v].sample->envelope_offset[stage];
voice[v].envelope_increment = voice[v].sample->envelope_rate[stage];
if (voice[v].envelope_target<voice[v].envelope_volume)
voice[v].envelope_increment = -voice[v].envelope_increment;
return 0;
}
void apply_envelope_to_amp(int v)
{
float lamp=voice[v].left_amp, ramp;
int32_t la,ra;
if (voice[v].panned == PANNED_MYSTERY)
{
ramp=voice[v].right_amp;
if (voice[v].tremolo_phase_increment)
{
lamp *= voice[v].tremolo_volume;
ramp *= voice[v].tremolo_volume;
}
if (voice[v].sample->modes & MODES_ENVELOPE)
{
lamp *= (float)vol_table[voice[v].envelope_volume>>23];
ramp *= (float)vol_table[voice[v].envelope_volume>>23];
}
la = (int32_t)FSCALE(lamp,AMP_BITS);
if (la>MAX_AMP_VALUE)
la=MAX_AMP_VALUE;
ra = (int32_t)FSCALE(ramp,AMP_BITS);
if (ra>MAX_AMP_VALUE)
ra=MAX_AMP_VALUE;
voice[v].left_mix=FINAL_VOLUME(la);
voice[v].right_mix=FINAL_VOLUME(ra);
}
else
{
if (voice[v].tremolo_phase_increment)
lamp *= voice[v].tremolo_volume;
if (voice[v].sample->modes & MODES_ENVELOPE)
lamp *= (float)vol_table[voice[v].envelope_volume>>23];
la = (int32_t)FSCALE(lamp,AMP_BITS);
if (la>MAX_AMP_VALUE)
la=MAX_AMP_VALUE;
voice[v].left_mix=FINAL_VOLUME(la);
}
}
static int update_envelope(int v)
{
voice[v].envelope_volume += voice[v].envelope_increment;
/* Why is there no ^^ operator?? */
if (((voice[v].envelope_increment < 0) &&
(voice[v].envelope_volume <= voice[v].envelope_target)) ||
((voice[v].envelope_increment > 0) &&
(voice[v].envelope_volume >= voice[v].envelope_target)))
{
voice[v].envelope_volume = voice[v].envelope_target;
if (recompute_envelope(v))
return 1;
}
return 0;
}
static void update_tremolo(int v)
{
int32_t depth=voice[v].sample->tremolo_depth<<7;
if (voice[v].tremolo_sweep)
{
/* Update sweep position */
voice[v].tremolo_sweep_position += voice[v].tremolo_sweep;
if (voice[v].tremolo_sweep_position>=(1<<SWEEP_SHIFT))
voice[v].tremolo_sweep=0; /* Swept to max amplitude */
else
{
/* Need to adjust depth */
depth *= voice[v].tremolo_sweep_position;
depth >>= SWEEP_SHIFT;
}
}
voice[v].tremolo_phase += voice[v].tremolo_phase_increment;
/* if (voice[v].tremolo_phase >= (SINE_CYCLE_LENGTH<<RATE_SHIFT))
voice[v].tremolo_phase -= SINE_CYCLE_LENGTH<<RATE_SHIFT; */
voice[v].tremolo_volume = (float)
(1.0 - FSCALENEG((sine(voice[v].tremolo_phase >> RATE_SHIFT) + 1.0)
* depth * TREMOLO_AMPLITUDE_TUNING,
17));
/* I'm not sure about the +1.0 there -- it makes tremoloed voices'
volumes on average the lower the higher the tremolo amplitude. */
}
/* Returns 1 if the note died */
static int update_signal(int v)
{
if (voice[v].envelope_increment && update_envelope(v))
return 1;
if (voice[v].tremolo_phase_increment)
update_tremolo(v);
apply_envelope_to_amp(v);
return 0;
}
#ifdef LOOKUP_HACK
# define MIXATION(a) *lp++ += mixup[(a<<8) | (uint8)s];
#else
# define MIXATION(a) *lp++ += (a)*s;
#endif
static void mix_mystery_signal(sample_t *sp, int32_t *lp, int v, int count)
{
Voice *vp = voice + v;
final_volume_t
left=vp->left_mix,
right=vp->right_mix;
int cc;
sample_t s;
if (!(cc = vp->control_counter))
{
cc = control_ratio;
if (update_signal(v))
return; /* Envelope ran out */
left = vp->left_mix;
right = vp->right_mix;
}
while (count)
if (cc < count)
{
count -= cc;
while (cc--)
{
s = *sp++;
MIXATION(left);
MIXATION(right);
}
cc = control_ratio;
if (update_signal(v))
return; /* Envelope ran out */
left = vp->left_mix;
right = vp->right_mix;
}
else
{
vp->control_counter = cc - count;
while (count--)
{
s = *sp++;
MIXATION(left);
MIXATION(right);
}
return;
}
}
static void mix_center_signal(sample_t *sp, int32_t *lp, int v, int count)
{
Voice *vp = voice + v;
final_volume_t
left=vp->left_mix;
int cc;
sample_t s;
if (!(cc = vp->control_counter))
{
cc = control_ratio;
if (update_signal(v))
return; /* Envelope ran out */
left = vp->left_mix;
}
while (count)
if (cc < count)
{
count -= cc;
while (cc--)
{
s = *sp++;
MIXATION(left);
MIXATION(left);
}
cc = control_ratio;
if (update_signal(v))
return; /* Envelope ran out */
left = vp->left_mix;
}
else
{
vp->control_counter = cc - count;
while (count--)
{
s = *sp++;
MIXATION(left);
MIXATION(left);
}
return;
}
}
static void mix_single_signal(sample_t *sp, int32_t *lp, int v, int count)
{
Voice *vp = voice + v;
final_volume_t
left=vp->left_mix;
int cc;
sample_t s;
if (!(cc = vp->control_counter))
{
cc = control_ratio;
if (update_signal(v))
return; /* Envelope ran out */
left = vp->left_mix;
}
while (count)
if (cc < count)
{
count -= cc;
while (cc--)
{
s = *sp++;
MIXATION(left);
lp++;
}
cc = control_ratio;
if (update_signal(v))
return; /* Envelope ran out */
left = vp->left_mix;
}
else
{
vp->control_counter = cc - count;
while (count--)
{
s = *sp++;
MIXATION(left);
lp++;
}
return;
}
}
static void mix_mono_signal(sample_t *sp, int32_t *lp, int v, int count)
{
Voice *vp = voice + v;
final_volume_t
left=vp->left_mix;
int cc;
sample_t s;
if (!(cc = vp->control_counter))
{
cc = control_ratio;
if (update_signal(v))
return; /* Envelope ran out */
left = vp->left_mix;
}
while (count)
if (cc < count)
{
count -= cc;
while (cc--)
{
s = *sp++;
MIXATION(left);
}
cc = control_ratio;
if (update_signal(v))
return; /* Envelope ran out */
left = vp->left_mix;
}
else
{
vp->control_counter = cc - count;
while (count--)
{
s = *sp++;
MIXATION(left);
}
return;
}
}
static void mix_mystery(sample_t *sp, int32_t *lp, int v, int count)
{
final_volume_t
left=voice[v].left_mix,
right=voice[v].right_mix;
sample_t s;
while (count--)
{
s = *sp++;
MIXATION(left);
MIXATION(right);
}
}
static void mix_center(sample_t *sp, int32_t *lp, int v, int count)
{
final_volume_t
left=voice[v].left_mix;
sample_t s;
while (count--)
{
s = *sp++;
MIXATION(left);
MIXATION(left);
}
}
static void mix_single(sample_t *sp, int32_t *lp, int v, int count)
{
final_volume_t
left=voice[v].left_mix;
sample_t s;
while (count--)
{
s = *sp++;
MIXATION(left);
lp++;
}
}
static void mix_mono(sample_t *sp, int32_t *lp, int v, int count)
{
final_volume_t
left=voice[v].left_mix;
sample_t s;
while (count--)
{
s = *sp++;
MIXATION(left);
}
}
/* Ramp a note out in c samples */
static void ramp_out(sample_t *sp, int32_t *lp, int v, int32_t c)
{
/* should be final_volume_t, but uint8_t gives trouble. */
int32_t left, right, li, ri;
sample_t s=0; /* silly warning about uninitialized s */
/* Fix by James Caldwell */
if ( c == 0 ) c = 1;
left=voice[v].left_mix;
li=-(left/c);
if (!li) li=-1;
/* I_Printf("Ramping out: left=%d, c=%d, li=%d\n", left, c, li); */
if (!(play_mode->encoding & PE_MONO))
{
if (voice[v].panned==PANNED_MYSTERY)
{
right=voice[v].right_mix;
ri=-(right/c);
while (c--)
{
left += li;
if (left<0)
left=0;
right += ri;
if (right<0)
right=0;
s=*sp++;
MIXATION(left);
MIXATION(right);
}
}
else if (voice[v].panned==PANNED_CENTER)
{
while (c--)
{
left += li;
if (left<0)
return;
s=*sp++;
MIXATION(left);
MIXATION(left);
}
}
else if (voice[v].panned==PANNED_LEFT)
{
while (c--)
{
left += li;
if (left<0)
return;
s=*sp++;
MIXATION(left);
lp++;
}
}
else if (voice[v].panned==PANNED_RIGHT)
{
while (c--)
{
left += li;
if (left<0)
return;
s=*sp++;
lp++;
MIXATION(left);
}
}
}
else
{
/* Mono output. */
while (c--)
{
left += li;
if (left<0)
return;
s=*sp++;
MIXATION(left);
}
}
}
/**************** interface function ******************/
void mix_voice( int32_t *buf, int v, int32_t c)
{
Voice *vp=voice+v;
sample_t *sp;
if (vp->status==VOICE_DIE)
{
if (c>=MAX_DIE_TIME)
c=MAX_DIE_TIME;
sp=resample_voice(v, &c);
ramp_out(sp, buf, v, c);
vp->status=VOICE_FREE;
}
else
{
sp=resample_voice(v, &c);
if (play_mode->encoding & PE_MONO)
{
/* Mono output. */
if (vp->envelope_increment || vp->tremolo_phase_increment)
mix_mono_signal(sp, buf, v, c);
else
mix_mono(sp, buf, v, c);
}
else
{
if (vp->panned == PANNED_MYSTERY)
{
if (vp->envelope_increment || vp->tremolo_phase_increment)
mix_mystery_signal(sp, buf, v, c);
else
mix_mystery(sp, buf, v, c);
}
else if (vp->panned == PANNED_CENTER)
{
if (vp->envelope_increment || vp->tremolo_phase_increment)
mix_center_signal(sp, buf, v, c);
else
mix_center(sp, buf, v, c);
}
else
{
/* It's either full left or full right. In either case,
every other sample is 0. Just get the offset right: */
if (vp->panned == PANNED_RIGHT) buf++;
if (vp->envelope_increment || vp->tremolo_phase_increment)
mix_single_signal(sp, buf, v, c);
else
mix_single(sp, buf, v, c);
}
}
}
}

View File

@@ -0,0 +1,27 @@
/*
TiMidity -- Experimental MIDI to WAVE converter
Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
In case you haven't heard, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
mix.h
*/
extern void mix_voice( int32_t *buf, int v, int32_t c);
extern int recompute_envelope(int v);
extern void apply_envelope_to_amp(int v);

View File

@@ -0,0 +1,138 @@
/*
TiMidity -- Experimental MIDI to WAVE converter
Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
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., 675 Mass Ave, Cambridge, MA 02139, USA.
output.c
Audio output (to file / device) functions.
*/
#include "config.h"
#include "output.h"
#include "tables.h"
#ifdef SDL
extern PlayMode sdl_play_mode;
#define DEFAULT_PLAY_MODE &sdl_play_mode
#endif
PlayMode *play_mode_list[] = {
#ifdef DEFAULT_PLAY_MODE
DEFAULT_PLAY_MODE,
#endif
0
};
#ifdef DEFAULT_PLAY_MODE
PlayMode *play_mode=DEFAULT_PLAY_MODE;
#endif
/*****************************************************************/
/* Some functions to convert signed 32-bit data to other formats */
void s32tos8(void *dp, int32_t *lp, int32_t c)
{
int8_t *cp=(int8_t *)(dp);
int32_t l;
while (c--)
{
l=(*lp++)>>(32-8-GUARD_BITS);
if (l>127) l=127;
else if (l<-128) l=-128;
*cp++ = (int8_t) (l);
}
}
void s32tou8(void *dp, int32_t *lp, int32_t c)
{
uint8_t *cp=(uint8_t *)(dp);
int32_t l;
while (c--)
{
l=(*lp++)>>(32-8-GUARD_BITS);
if (l>127) l=127;
else if (l<-128) l=-128;
*cp++ = 0x80 ^ ((uint8_t) l);
}
}
void s32tos16(void *dp, int32_t *lp, int32_t c)
{
int16_t *sp=(int16_t *)(dp);
int32_t l;
while (c--)
{
l=(*lp++)>>(32-16-GUARD_BITS);
if (l > 32767) l=32767;
else if (l<-32768) l=-32768;
*sp++ = (int16_t)(l);
}
}
void s32tou16(void *dp, int32_t *lp, int32_t c)
{
uint16_t *sp=(uint16_t *)(dp);
int32_t l;
while (c--)
{
l=(*lp++)>>(32-16-GUARD_BITS);
if (l > 32767) l=32767;
else if (l<-32768) l=-32768;
*sp++ = 0x8000 ^ (uint16_t)(l);
}
}
void s32tos16x(void *dp, int32_t *lp, int32_t c)
{
int16_t *sp=(int16_t *)(dp);
int32_t l;
while (c--)
{
l=(*lp++)>>(32-16-GUARD_BITS);
if (l > 32767) l=32767;
else if (l<-32768) l=-32768;
*sp++ = XCHG_SHORT((int16_t)(l));
}
}
void s32tou16x(void *dp, int32_t *lp, int32_t c)
{
uint16_t *sp=(uint16_t *)(dp);
int32_t l;
while (c--)
{
l=(*lp++)>>(32-16-GUARD_BITS);
if (l > 32767) l=32767;
else if (l<-32768) l=-32768;
*sp++ = XCHG_SHORT(0x8000 ^ (uint16_t)(l));
}
}
void s32toulaw(void *dp, int32_t *lp, int32_t c)
{
uint8_t *up=(uint8_t *)(dp);
int32_t l;
while (c--)
{
l=(*lp++)>>(32-13-GUARD_BITS);
if (l > 4095) l=4095;
else if (l<-4096) l=-4096;
*up++ = _l2u[l];
}
}

View File

@@ -0,0 +1,70 @@
/*
TiMidity -- Experimental MIDI to WAVE converter
Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
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., 675 Mass Ave, Cambridge, MA 02139, USA.
output.h
*/
#include <stdio.h>
#include "timidity.h"
/* Data format encoding bits */
#define PE_MONO 0x01 /* versus stereo */
#define PE_SIGNED 0x02 /* versus unsigned */
#define PE_16BIT 0x04 /* versus 8-bit */
#define PE_ULAW 0x08 /* versus linear */
#define PE_BYTESWAP 0x10 /* versus the other way */
extern int init_buffers(int kbytes);
/* Conversion functions -- These overwrite the int32_t data in *lp with
data in another format */
/* The size of the output buffers */
extern int AUDIO_BUFFER_SIZE;
/* Actual copy function */
extern void (*s32tobuf)(void *dp, int32_t *lp, int32_t c);
/* 8-bit signed and unsigned*/
extern void s32tos8(void *dp, int32_t *lp, int32_t c);
extern void s32tou8(void *dp, int32_t *lp, int32_t c);
/* 16-bit */
extern void s32tos16(void *dp, int32_t *lp, int32_t c);
extern void s32tou16(void *dp, int32_t *lp, int32_t c);
/* byte-exchanged 16-bit */
extern void s32tos16x(void *dp, int32_t *lp, int32_t c);
extern void s32tou16x(void *dp, int32_t *lp, int32_t c);
/* uLaw (8 bits) */
extern void s32toulaw(void *dp, int32_t *lp, int32_t c);
/* little-endian and big-endian specific */
#ifdef LITTLE_ENDIAN
#define s32tou16l s32tou16
#define s32tou16b s32tou16x
#define s32tos16l s32tos16
#define s32tos16b s32tos16x
#else
#define s32tou16l s32tou16x
#define s32tou16b s32tou16
#define s32tos16l s32tos16x
#define s32tos16b s32tos16
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,113 @@
/*
TiMidity -- Experimental MIDI to WAVE converter
Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
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., 675 Mass Ave, Cambridge, MA 02139, USA.
playmidi.h
*/
#include "structs.h"
/* Midi events */
#define ME_NONE 0
#define ME_NOTEON 1
#define ME_NOTEOFF 2
#define ME_KEYPRESSURE 3
#define ME_MAINVOLUME 4
#define ME_PAN 5
#define ME_SUSTAIN 6
#define ME_EXPRESSION 7
#define ME_PITCHWHEEL 8
#define ME_PROGRAM 9
#define ME_TEMPO 10
#define ME_PITCH_SENS 11
#define ME_ALL_SOUNDS_OFF 12
#define ME_RESET_CONTROLLERS 13
#define ME_ALL_NOTES_OFF 14
#define ME_TONE_BANK 15
#define ME_LYRIC 16
#define ME_EOT 99
typedef struct {
int
bank, program, volume, sustain, panning, pitchbend, expression,
mono, /* one note only on this channel -- not implemented yet */
pitchsens;
/* chorus, reverb... Coming soon to a 300-MHz, eight-way superscalar
processor near you */
float
pitchfactor; /* precomputed pitch bend factor to save some fdiv's */
} Channel;
/* Causes the instrument's default panning to be used. */
#define NO_PANNING -1
typedef struct {
uint8_t
status, channel, note, velocity;
Sample *sample;
int32_t
orig_frequency, frequency,
sample_offset, sample_increment,
envelope_volume, envelope_target, envelope_increment,
tremolo_sweep, tremolo_sweep_position,
tremolo_phase, tremolo_phase_increment,
vibrato_sweep, vibrato_sweep_position;
final_volume_t left_mix, right_mix;
float
left_amp, right_amp, tremolo_volume;
int32_t
vibrato_sample_increment[VIBRATO_SAMPLE_INCREMENTS];
int
vibrato_phase, vibrato_control_ratio, vibrato_control_counter,
envelope_stage, control_counter, panning, panned;
} Voice;
/* Voice status options: */
#define VOICE_FREE 0
#define VOICE_ON 1
#define VOICE_SUSTAINED 2
#define VOICE_OFF 3
#define VOICE_DIE 4
/* Voice panned options: */
#define PANNED_MYSTERY 0
#define PANNED_LEFT 1
#define PANNED_RIGHT 2
#define PANNED_CENTER 3
/* Anything but PANNED_MYSTERY only uses the left volume */
extern Channel channel[16];
extern Voice voice[MAX_VOICES];
extern int32_t control_ratio, amp_with_poly, amplification;
extern int32_t drumchannels;
extern int adjust_panning_immediately;
extern int voices;
#define ISDRUMCHANNEL(c) ((drumchannels & (1<<(c))))
extern int play_midi(MidiEvent *el, int32_t events, int32_t samples);
extern int play_midi_file(char *fn);
extern void dumb_pass_playing_list(int number_of_files, char *list_of_files[]);

View File

@@ -0,0 +1,758 @@
/*
TiMidity -- Experimental MIDI to WAVE converter
Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "../../neo/idlib/precompiled.h"
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include "config.h"
#include "common.h"
#include "instrum.h"
#include "playmidi.h"
#include "readmidi.h"
#include "output.h"
#include "controls.h"
void Real_Tim_Free( void *pt );
int32_t quietchannels=0;
/* to avoid some unnecessary parameter passing */
static MidiEventList *evlist;
static int32_t event_count;
static idFile * fp = NULL;
static int32_t at;
static unsigned char* local_buffer = 0;
static size_t local_buffer_length = 0;
static size_t local_buffer_cur = 0;
/* These would both fit into 32 bits, but they are often added in
large multiples, so it's simpler to have two roomy ints */
static int32_t sample_increment, sample_correction; /*samples per MIDI delta-t*/
static int32_t read_local(void* buffer, size_t len, size_t count)
{
if (fp && len > 0) {
return (int32_t)fp->Read(buffer, len * count ) / len;
} else if( local_buffer != NULL ) {
if (len * count + local_buffer_cur > local_buffer_length) {
memcpy(buffer, &local_buffer[local_buffer_cur], local_buffer_length - local_buffer_cur);
return(int32_t)(local_buffer_length - local_buffer_cur)/len;
} else {
memcpy(buffer, &local_buffer[local_buffer_cur], len * count);
local_buffer_cur += len * count;
return(count);
}
}
return 0;
}
static void skip_local(size_t len)
{
if (fp) {
skip(fp, len);
} else {
if (len + local_buffer_cur > local_buffer_length) {
ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "skip_local failed on memory buffer");
} else {
local_buffer_cur += len;
}
}
}
/* Computes how many (fractional) samples one MIDI delta-time unit contains */
static void compute_sample_increment( int32_t tempo, int32_t divisions)
{
double a;
a = (double) (tempo) * (double) (play_mode->rate) * (65536.0/1000000.0) /
(double)(divisions);
sample_correction = (int32_t)(a) & 0xFFFF;
sample_increment = (int32_t)(a) >> 16;
ctl->cmsg(CMSG_INFO, VERB_DEBUG, "Samples per delta-t: %d (correction %d)",
sample_increment, sample_correction);
}
/* Read variable-length number (7 bits per byte, MSB first) */
static int32_t getvl(void)
{
int32_t l=0;
uint8_t c;
for (;;)
{
read_local(&c,1,1);
l += (c & 0x7f);
if (!(c & 0x80)) return l;
l<<=7;
}
}
/* Print a string from the file, followed by a newline. Any non-ASCII
or unprintable characters will be converted to periods. */
static int dumpstring( int32_t len, char *label)
{
signed char *s=(signed char *)safe_malloc(len+1);
if (len != (int32_t)read_local(s, 1, len))
{
Real_Tim_Free(s);
return -1;
}
s[len]='\0';
while (len--)
{
if (s[len]<32)
s[len]='.';
}
ctl->cmsg(CMSG_TEXT, VERB_VERBOSE, "%s%s", label, s);
Real_Tim_Free(s);
return 0;
}
#define MIDIEVENT(at,t,ch,pa,pb) \
newEventList=(MidiEventList*)safe_malloc(sizeof(MidiEventList)); \
newEventList->event.time=at; newEventList->event.type=t; newEventList->event.channel=ch; \
newEventList->event.a=pa; newEventList->event.b=pb; newEventList->next=0;\
return newEventList;
#define MAGIC_EOT ((MidiEventList *)(-1))
/* Read a MIDI event, returning a freshly allocated element that can
be linked to the event list */
static MidiEventList *read_midi_event(void)
{
static uint8_t laststatus, lastchan;
static uint8_t nrpn=0, rpn_msb[16], rpn_lsb[16]; /* one per channel */
uint8_t me, type, a,b,c;
int32_t len;
MidiEventList *newEventList;
for (;;)
{
at+=getvl();
if (read_local(&me,1,1)!=1)
{
ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: read_midi_event: %s",
current_filename, strerror(errno));
return 0;
}
if(me==0xF0 || me == 0xF7) /* SysEx event */
{
len=getvl();
skip_local(len);
}
else if(me==0xFF) /* Meta event */
{
read_local(&type,1,1);
len=getvl();
if (type>0 && type<16)
{
static char *label[]={
"Text event: ", "Text: ", "Copyright: ", "Track name: ",
"Instrument: ", "Lyric: ", "Marker: ", "Cue point: "};
dumpstring(len, label[(type>7) ? 0 : type]);
}
else
switch(type)
{
case 0x2F: /* End of Track */
return MAGIC_EOT;
case 0x51: /* Tempo */
read_local(&a,1,1); read_local(&b,1,1); read_local(&c,1,1);
MIDIEVENT(at, ME_TEMPO, c, a, b);
default:
ctl->cmsg(CMSG_INFO, VERB_DEBUG,
"(Meta event type 0x%02x, length %ld)", type, len);
skip_local(len);
break;
}
}
else
{
a=me;
if (a & 0x80) /* status byte */
{
lastchan=a & 0x0F;
laststatus=(a>>4) & 0x07;
read_local(&a, 1,1);
a &= 0x7F;
}
switch(laststatus)
{
case 0: /* Note off */
read_local(&b, 1,1);
b &= 0x7F;
MIDIEVENT(at, ME_NOTEOFF, lastchan, a,b);
case 1: /* Note on */
read_local(&b, 1,1);
b &= 0x7F;
MIDIEVENT(at, ME_NOTEON, lastchan, a,b);
case 2: /* Key Pressure */
read_local(&b, 1,1);
b &= 0x7F;
MIDIEVENT(at, ME_KEYPRESSURE, lastchan, a, b);
case 3: /* Control change */
read_local(&b, 1,1);
b &= 0x7F;
{
int control=255;
switch(a)
{
case 7: control=ME_MAINVOLUME; break;
case 10: control=ME_PAN; break;
case 11: control=ME_EXPRESSION; break;
case 64: control=ME_SUSTAIN; break;
case 120: control=ME_ALL_SOUNDS_OFF; break;
case 121: control=ME_RESET_CONTROLLERS; break;
case 123: control=ME_ALL_NOTES_OFF; break;
/* These should be the SCC-1 tone bank switch
commands. I don't know why there are two, or
why the latter only allows switching to bank 0.
Also, some MIDI files use 0 as some sort of
continuous controller. This will cause lots of
warnings about undefined tone banks. */
case 0: control=ME_TONE_BANK; break;
case 32:
if (b!=0)
ctl->cmsg(CMSG_INFO, VERB_DEBUG,
"(Strange: tone bank change 0x20%02x)", b);
else
control=ME_TONE_BANK;
break;
case 100: nrpn=0; rpn_msb[lastchan]=b; break;
case 101: nrpn=0; rpn_lsb[lastchan]=b; break;
case 99: nrpn=1; rpn_msb[lastchan]=b; break;
case 98: nrpn=1; rpn_lsb[lastchan]=b; break;
case 6:
if (nrpn)
{
ctl->cmsg(CMSG_INFO, VERB_DEBUG,
"(Data entry (MSB) for NRPN %02x,%02x: %ld)",
rpn_msb[lastchan], rpn_lsb[lastchan],
b);
break;
}
switch((rpn_msb[lastchan]<<8) | rpn_lsb[lastchan])
{
case 0x0000: /* Pitch bend sensitivity */
control=ME_PITCH_SENS;
break;
case 0x7F7F: /* RPN reset */
/* reset pitch bend sensitivity to 2 */
MIDIEVENT(at, ME_PITCH_SENS, lastchan, 2, 0);
default:
ctl->cmsg(CMSG_INFO, VERB_DEBUG,
"(Data entry (MSB) for RPN %02x,%02x: %ld)",
rpn_msb[lastchan], rpn_lsb[lastchan],
b);
break;
}
break;
default:
ctl->cmsg(CMSG_INFO, VERB_DEBUG,
"(Control %d: %d)", a, b);
break;
}
if (control != 255)
{
MIDIEVENT(at, control, lastchan, b, 0);
}
}
break;
case 4: /* Program change */
a &= 0x7f;
MIDIEVENT(at, ME_PROGRAM, lastchan, a, 0);
case 5: /* Channel pressure - NOT IMPLEMENTED */
break;
case 6: /* Pitch wheel */
read_local(&b, 1,1);
b &= 0x7F;
MIDIEVENT(at, ME_PITCHWHEEL, lastchan, a, b);
default:
ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
"*** Can't happen: status 0x%02X, channel 0x%02X",
laststatus, lastchan);
break;
}
}
}
return newEventList;
}
#undef MIDIEVENT
/* Read a midi track into the linked list, either merging with any previous
tracks or appending to them. */
static int read_track(int append)
{
MidiEventList *meep;
MidiEventList *next, *newEventList;
int32_t len;
char tmp[4];
meep=evlist;
if (append && meep)
{
/* find the last event in the list */
for (; meep->next; meep=(MidiEventList *)meep->next)
;
at=meep->event.time;
}
else
at=0;
/* Check the formalities */
if ((read_local(tmp,1,4) != 4) || (read_local(&len,4,1) != 1))
{
ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
"%s: Can't read track header.", current_filename);
return -1;
}
len=BE_LONG(len);
if (memcmp(tmp, "MTrk", 4))
{
ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
"%s: Corrupt MIDI file.", current_filename);
return -2;
}
for (;;)
{
if (!(newEventList=read_midi_event())) /* Some kind of error */
return -2;
if (newEventList==MAGIC_EOT) /* End-of-track Hack. */
{
return 0;
}
next=(MidiEventList *)meep->next;
while (next && (next->event.time < newEventList->event.time))
{
meep=next;
next=(MidiEventList *)meep->next;
}
newEventList->next=next;
meep->next=newEventList;
event_count++; /* Count the event. (About one?) */
meep=newEventList;
}
}
/* Free the linked event list from memory. */
static void free_midi_list(void)
{
MidiEventList *meep, *next;
if (!(meep=evlist)) return;
while (meep)
{
next=(MidiEventList *)meep->next;
Real_Tim_Free(meep);
meep=next;
}
evlist=0;
}
/* Allocate an array of MidiEvents and fill it from the linked list of
events, marking used instruments for loading. Convert event times to
samples: handle tempo changes. Strip unnecessary events from the list.
Free the linked list. */
static MidiEvent *groom_list( int32_t divisions, int32_t *eventsp, int32_t *samplesp)
{
MidiEvent *groomed_list, *lp;
MidiEventList *meep;
int32_t i, our_event_count, tempo, skip_local_this_event, new_value;
int32_t sample_cum, samples_to_do, at, st, dt, counting_time;
int current_bank[16], current_set[16], current_program[16];
/* Or should each bank have its own current program? */
for (i=0; i<16; i++)
{
current_bank[i]=0;
current_set[i]=0;
current_program[i]=default_program;
}
tempo=500000;
compute_sample_increment(tempo, divisions);
/* This may allocate a bit more than we need */
groomed_list=lp=(MidiEvent*)safe_malloc(sizeof(MidiEvent) * (event_count+1));
meep=evlist;
our_event_count=0;
st=at=sample_cum=0;
counting_time=2; /* We strip any silence before the first NOTE ON. */
for (i=0; i<event_count; i++)
{
skip_local_this_event=0;
ctl->cmsg(CMSG_INFO, VERB_DEBUG_SILLY,
"%6d: ch %2d: event %d (%d,%d)",
meep->event.time, meep->event.channel + 1,
meep->event.type, meep->event.a, meep->event.b);
if (meep->event.type==ME_TEMPO)
{
tempo=
meep->event.channel + meep->event.b * 256 + meep->event.a * 65536;
compute_sample_increment(tempo, divisions);
skip_local_this_event=1;
}
else if ((quietchannels & (1<<meep->event.channel)))
skip_local_this_event=1;
else switch (meep->event.type)
{
case ME_PROGRAM:
if (ISDRUMCHANNEL(meep->event.channel))
{
if (drumset[meep->event.a]) /* Is this a defined drumset? */
new_value=meep->event.a;
else
{
ctl->cmsg(CMSG_WARNING, VERB_VERBOSE,
"Drum set %d is undefined", meep->event.a);
new_value=meep->event.a=0;
}
if (current_set[meep->event.channel] != new_value)
current_set[meep->event.channel]=new_value;
else
skip_local_this_event=1;
}
else
{
new_value=meep->event.a;
if ((current_program[meep->event.channel] != SPECIAL_PROGRAM)
&& (current_program[meep->event.channel] != new_value))
current_program[meep->event.channel] = new_value;
else
skip_local_this_event=1;
}
break;
case ME_NOTEON:
if (counting_time)
counting_time=1;
if (ISDRUMCHANNEL(meep->event.channel))
{
/* Mark this instrument to be loaded */
if (!(drumset[current_set[meep->event.channel]]
->tone[meep->event.a].instrument))
drumset[current_set[meep->event.channel]]
->tone[meep->event.a].instrument=
MAGIC_LOAD_INSTRUMENT;
}
else
{
if (current_program[meep->event.channel]==SPECIAL_PROGRAM)
break;
/* Mark this instrument to be loaded */
if (!(tonebank[current_bank[meep->event.channel]]
->tone[current_program[meep->event.channel]].instrument))
tonebank[current_bank[meep->event.channel]]
->tone[current_program[meep->event.channel]].instrument=
MAGIC_LOAD_INSTRUMENT;
}
break;
case ME_TONE_BANK:
if (ISDRUMCHANNEL(meep->event.channel))
{
skip_local_this_event=1;
break;
}
if (tonebank[meep->event.a]) /* Is this a defined tone bank? */
new_value=meep->event.a;
else
{
ctl->cmsg(CMSG_WARNING, VERB_VERBOSE,
"Tone bank %d is undefined", meep->event.a);
new_value=meep->event.a=0;
}
if (current_bank[meep->event.channel]!=new_value)
current_bank[meep->event.channel]=new_value;
else
skip_local_this_event=1;
break;
}
/* Recompute time in samples*/
if ((dt=meep->event.time - at) && !counting_time)
{
samples_to_do=sample_increment * dt;
sample_cum += sample_correction * dt;
if (sample_cum & 0xFFFF0000)
{
samples_to_do += ((sample_cum >> 16) & 0xFFFF);
sample_cum &= 0x0000FFFF;
}
st += samples_to_do;
}
else if (counting_time==1) counting_time=0;
if (!skip_local_this_event)
{
/* Add the event to the list */
*lp=meep->event;
lp->time=st;
lp++;
our_event_count++;
}
at=meep->event.time;
meep=(MidiEventList *)meep->next;
}
/* Add an End-of-Track event */
lp->time=st;
lp->type=ME_EOT;
our_event_count++;
free_midi_list();
*eventsp=our_event_count;
*samplesp=st;
return groomed_list;
}
MidiEvent *read_midi_file(idFile * mfp, int32_t *count, int32_t *sp)
{
int32_t len, divisions;
int16_t format, tracks, divisions_tmp;
int i;
char tmp[4];
fp = mfp;
local_buffer = 0;
local_buffer_length = 0;
local_buffer_cur = 0;
event_count=0;
at=0;
evlist=0;
int first = (read_local(tmp,1,4));
int second = (read_local(&len,4,1));
if ( first != 4 || second != 1)
{
if (0)
{
ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: %s", current_filename,
strerror(errno));
}
else
ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
"%s: Not a MIDI file!", current_filename);
return 0;
}
len=BE_LONG(len);
if (memcmp(tmp, "MThd", 4) || len < 6)
{
ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
"%s: Not a MIDI file!", current_filename);
return 0;
}
read_local(&format, 2, 1);
read_local(&tracks, 2, 1);
read_local(&divisions_tmp, 2, 1);
format=BE_SHORT(format);
tracks=BE_SHORT(tracks);
divisions_tmp=BE_SHORT(divisions_tmp);
if (divisions_tmp<0)
{
/* SMPTE time -- totally untested. Got a MIDI file that uses this? */
divisions=
(int32_t)(-(divisions_tmp/256)) * (int32_t)(divisions_tmp & 0xFF);
}
else divisions=(int32_t)(divisions_tmp);
if (len > 6)
{
ctl->cmsg(CMSG_WARNING, VERB_NORMAL,
"%s: MIDI file header size %ld bytes",
current_filename, len);
skip_local(len-6); /* skip_local the excess */
}
if (format<0 || format >2)
{
ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
"%s: Unknown MIDI file format %d", current_filename, format);
return 0;
}
//ctl->cmsg(CMSG_INFO, VERB_VERBOSE,
// "Format: %d Tracks: %d Divisions: %d", format, tracks, divisions);
/* Put a do-nothing event first in the list for easier processing */
evlist=(MidiEventList *)safe_malloc(sizeof(MidiEventList));
evlist->event.time=0;
evlist->event.type=ME_NONE;
evlist->next=0;
event_count++;
switch(format)
{
case 0:
if (read_track(0))
{
free_midi_list();
return 0;
}
break;
case 1:
for (i=0; i<tracks; i++)
if (read_track(0))
{
free_midi_list();
return 0;
}
break;
case 2: /* We simply play the tracks sequentially */
for (i=0; i<tracks; i++)
if (read_track(1))
{
free_midi_list();
return 0;
}
break;
}
return groom_list(divisions, count, sp);
}
MidiEvent *read_midi_buffer(unsigned char* buffer, size_t length, int32_t *count, int32_t *sp)
{
int32_t len, divisions;
int16_t format, tracks, divisions_tmp;
int i;
char tmp[4];
fp = 0;
local_buffer = buffer;
local_buffer_length = length;
local_buffer_cur = 0;
event_count=0;
at=0;
evlist=0;
if ((read_local(tmp,1,4) != 4) || (read_local(&len,4,1) != 1))
{
ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Not a MIDI file!");
return 0;
}
len=BE_LONG(len);
if (memcmp(tmp, "MThd", 4) || len < 6)
{
ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: Not a MIDI file!", current_filename);
return 0;
}
read_local(&format, 2, 1);
read_local(&tracks, 2, 1);
read_local(&divisions_tmp, 2, 1);
format=BE_SHORT(format);
tracks=BE_SHORT(tracks);
divisions_tmp=BE_SHORT(divisions_tmp);
if (divisions_tmp<0) {
/* SMPTE time -- totally untested. Got a MIDI file that uses this? */
divisions= (int32_t)(-(divisions_tmp/256)) * (int32_t)(divisions_tmp & 0xFF);
}
else divisions=(int32_t)(divisions_tmp);
if (len > 6)
{
ctl->cmsg(CMSG_WARNING, VERB_NORMAL,
"%s: MIDI file header size %ld bytes",
current_filename, len);
skip_local(len-6); /* skip_local the excess */
}
if (format<0 || format >2)
{
ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
"%s: Unknown MIDI file format %d", current_filename, format);
return 0;
}
//ctl->cmsg(CMSG_INFO, VERB_VERBOSE,
// "Format: %d Tracks: %d Divisions: %d", format, tracks, divisions);
/* Put a do-nothing event first in the list for easier processing */
evlist=(MidiEventList *)safe_malloc(sizeof(MidiEventList));
evlist->event.time=0;
evlist->event.type=ME_NONE;
evlist->next=0;
event_count++;
switch(format)
{
case 0:
if (read_track(0))
{
free_midi_list();
return 0;
}
break;
case 1:
for (i=0; i<tracks; i++)
if (read_track(0))
{
free_midi_list();
return 0;
}
break;
case 2: /* We simply play the tracks sequentially */
for (i=0; i<tracks; i++)
if (read_track(1))
{
free_midi_list();
return 0;
}
break;
}
return groom_list(divisions, count, sp);
}

View File

@@ -0,0 +1,34 @@
/*
TiMidity -- Experimental MIDI to WAVE converter
Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
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., 675 Mass Ave, Cambridge, MA 02139, USA.
readmidi.h
*/
class idFile;
typedef struct {
MidiEvent event;
void *next;
} MidiEventList;
extern int32_t quietchannels;
extern MidiEvent *read_midi_file(idFile * mfp, int32_t *count, int32_t *sp);
extern MidiEvent *read_midi_buffer(unsigned char* buffer, size_t length, int32_t *count, int32_t *sp);

View File

@@ -0,0 +1,738 @@
/*
TiMidity -- Experimental MIDI to WAVE converter
Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
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., 675 Mass Ave, Cambridge, MA 02139, USA.
resample.c
*/
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include "config.h"
#include "common.h"
#include "instrum.h"
#include "playmidi.h"
#include "output.h"
#include "controls.h"
#include "tables.h"
#include "resample.h"
#ifdef LINEAR_INTERPOLATION
# if defined(LOOKUP_HACK) && defined(LOOKUP_INTERPOLATION)
# define RESAMPLATION \
v1=src[ofs>>FRACTION_BITS];\
v2=src[(ofs>>FRACTION_BITS)+1];\
*dest++ = v1 + (iplookup[(((v2-v1)<<5) & 0x03FE0) | \
((ofs & FRACTION_MASK) >> (FRACTION_BITS-5))]);
# else
# define RESAMPLATION \
v1=src[ofs>>FRACTION_BITS];\
v2=src[(ofs>>FRACTION_BITS)+1];\
*dest++ = v1 + (((v2-v1) * (ofs & FRACTION_MASK)) >> FRACTION_BITS);
# endif
# define INTERPVARS sample_t v1, v2
#else
/* Earplugs recommended for maximum listening enjoyment */
# define RESAMPLATION *dest++=src[ofs>>FRACTION_BITS];
# define INTERPVARS
#endif
#define FINALINTERP if (ofs == le) *dest++=src[ofs>>FRACTION_BITS];
/* So it isn't interpolation. At least it's final. */
extern sample_t *resample_buffer;
void Real_Tim_Free( void *pt );
/*************** resampling with fixed increment *****************/
static sample_t *rs_plain(int v, int32_t *countptr)
{
/* Play sample until end, then free the voice. */
INTERPVARS;
Voice
*vp=&voice[v];
sample_t
*dest=resample_buffer,
*src=vp->sample->data;
int32_t
ofs=vp->sample_offset,
incr=vp->sample_increment,
le=vp->sample->data_length,
count=*countptr;
#ifdef PRECALC_LOOPS
int32_t i;
if (incr<0) incr = -incr; /* In case we're coming out of a bidir loop */
/* Precalc how many times we should go through the loop.
NOTE: Assumes that incr > 0 and that ofs <= le */
i = (le - ofs) / incr + 1;
if (i > count)
{
i = count;
count = 0;
}
else count -= i;
while (i--)
{
RESAMPLATION;
ofs += incr;
}
if (ofs >= le)
{
FINALINTERP;
vp->status=VOICE_FREE;
ctl->note(v);
*countptr-=count+1;
}
#else /* PRECALC_LOOPS */
while (count--)
{
RESAMPLATION;
ofs += incr;
if (ofs >= le)
{
FINALINTERP;
vp->status=VOICE_FREE;
ctl->note(v);
*countptr-=count+1;
break;
}
}
#endif /* PRECALC_LOOPS */
vp->sample_offset=ofs; /* Update offset */
return resample_buffer;
}
static sample_t *rs_loop(Voice *vp, int32_t count)
{
/* Play sample until end-of-loop, skip back and continue. */
INTERPVARS;
int32_t
ofs=vp->sample_offset,
incr=vp->sample_increment,
le=vp->sample->loop_end,
ll=le - vp->sample->loop_start;
sample_t
*dest=resample_buffer,
*src=vp->sample->data;
#ifdef PRECALC_LOOPS
int32_t i;
while (count)
{
if (ofs >= le)
/* NOTE: Assumes that ll > incr and that incr > 0. */
ofs -= ll;
/* Precalc how many times we should go through the loop */
i = (le - ofs) / incr + 1;
if (i > count)
{
i = count;
count = 0;
}
else count -= i;
while (i--)
{
RESAMPLATION;
ofs += incr;
}
}
#else
while (count--)
{
RESAMPLATION;
ofs += incr;
if (ofs>=le)
ofs -= ll; /* Hopefully the loop is longer than an increment. */
}
#endif
vp->sample_offset=ofs; /* Update offset */
return resample_buffer;
}
static sample_t *rs_bidir(Voice *vp, int32_t count)
{
INTERPVARS;
int32_t
ofs=vp->sample_offset,
incr=vp->sample_increment,
le=vp->sample->loop_end,
ls=vp->sample->loop_start;
sample_t
*dest=resample_buffer,
*src=vp->sample->data;
#ifdef PRECALC_LOOPS
int32_t
le2 = le<<1,
ls2 = ls<<1,
i;
/* Play normally until inside the loop region */
if (ofs <= ls)
{
/* NOTE: Assumes that incr > 0, which is NOT always the case
when doing bidirectional looping. I have yet to see a case
where both ofs <= ls AND incr < 0, however. */
i = (ls - ofs) / incr + 1;
if (i > count)
{
i = count;
count = 0;
}
else count -= i;
while (i--)
{
RESAMPLATION;
ofs += incr;
}
}
/* Then do the bidirectional looping */
while(count)
{
/* Precalc how many times we should go through the loop */
i = ((incr > 0 ? le : ls) - ofs) / incr + 1;
if (i > count)
{
i = count;
count = 0;
}
else count -= i;
while (i--)
{
RESAMPLATION;
ofs += incr;
}
if (ofs>=le)
{
/* fold the overshoot back in */
ofs = le2 - ofs;
incr *= -1;
}
else if (ofs <= ls)
{
ofs = ls2 - ofs;
incr *= -1;
}
}
#else /* PRECALC_LOOPS */
/* Play normally until inside the loop region */
if (ofs < ls)
{
while (count--)
{
RESAMPLATION;
ofs += incr;
if (ofs>=ls)
break;
}
}
/* Then do the bidirectional looping */
if (count>0)
while (count--)
{
RESAMPLATION;
ofs += incr;
if (ofs>=le)
{
/* fold the overshoot back in */
ofs = le - (ofs - le);
incr = -incr;
}
else if (ofs <= ls)
{
ofs = ls + (ls - ofs);
incr = -incr;
}
}
#endif /* PRECALC_LOOPS */
vp->sample_increment=incr;
vp->sample_offset=ofs; /* Update offset */
return resample_buffer;
}
/*********************** vibrato versions ***************************/
/* We only need to compute one half of the vibrato sine cycle */
static int vib_phase_to_inc_ptr(int phase)
{
if (phase < VIBRATO_SAMPLE_INCREMENTS/2)
return VIBRATO_SAMPLE_INCREMENTS/2-1-phase;
else if (phase >= 3*VIBRATO_SAMPLE_INCREMENTS/2)
return 5*VIBRATO_SAMPLE_INCREMENTS/2-1-phase;
else
return phase-VIBRATO_SAMPLE_INCREMENTS/2;
}
static int32_t update_vibrato(Voice *vp, int sign)
{
int32_t depth;
int phase, pb;
double a;
if (vp->vibrato_phase++ >= 2*VIBRATO_SAMPLE_INCREMENTS-1)
vp->vibrato_phase=0;
phase=vib_phase_to_inc_ptr(vp->vibrato_phase);
if (vp->vibrato_sample_increment[phase])
{
if (sign)
return -vp->vibrato_sample_increment[phase];
else
return vp->vibrato_sample_increment[phase];
}
/* Need to compute this sample increment. */
depth=vp->sample->vibrato_depth<<7;
if (vp->vibrato_sweep)
{
/* Need to update sweep */
vp->vibrato_sweep_position += vp->vibrato_sweep;
if (vp->vibrato_sweep_position >= (1<<SWEEP_SHIFT))
vp->vibrato_sweep=0;
else
{
/* Adjust depth */
depth *= vp->vibrato_sweep_position;
depth >>= SWEEP_SHIFT;
}
}
a = FSCALE(((double)(vp->sample->sample_rate) *
(double)(vp->frequency)) /
((double)(vp->sample->root_freq) *
(double)(play_mode->rate)),
FRACTION_BITS);
pb=(int)((sine(vp->vibrato_phase *
(SINE_CYCLE_LENGTH/(2*VIBRATO_SAMPLE_INCREMENTS)))
* (double)(depth) * VIBRATO_AMPLITUDE_TUNING));
if (pb<0)
{
pb=-pb;
a /= bend_fine[(pb>>5) & 0xFF] * bend_coarse[pb>>13];
}
else
a *= bend_fine[(pb>>5) & 0xFF] * bend_coarse[pb>>13];
/* If the sweep's over, we can store the newly computed sample_increment */
if (!vp->vibrato_sweep)
vp->vibrato_sample_increment[phase]=(int32_t) a;
if (sign)
a = -a; /* need to preserve the loop direction */
return (int32_t) a;
}
static sample_t *rs_vib_plain(int v, int32_t *countptr)
{
/* Play sample until end, then free the voice. */
INTERPVARS;
Voice *vp=&voice[v];
sample_t
*dest=resample_buffer,
*src=vp->sample->data;
int32_t
le=vp->sample->data_length,
ofs=vp->sample_offset,
incr=vp->sample_increment,
count=*countptr;
int
cc=vp->vibrato_control_counter;
/* This has never been tested */
if (incr<0) incr = -incr; /* In case we're coming out of a bidir loop */
while (count--)
{
if (!cc--)
{
cc=vp->vibrato_control_ratio;
incr=update_vibrato(vp, 0);
}
RESAMPLATION;
ofs += incr;
if (ofs >= le)
{
FINALINTERP;
vp->status=VOICE_FREE;
ctl->note(v);
*countptr-=count+1;
break;
}
}
vp->vibrato_control_counter=cc;
vp->sample_increment=incr;
vp->sample_offset=ofs; /* Update offset */
return resample_buffer;
}
static sample_t *rs_vib_loop(Voice *vp, int32_t count)
{
/* Play sample until end-of-loop, skip back and continue. */
INTERPVARS;
int32_t
ofs=vp->sample_offset,
incr=vp->sample_increment,
le=vp->sample->loop_end,
ll=le - vp->sample->loop_start;
sample_t
*dest=resample_buffer,
*src=vp->sample->data;
int
cc=vp->vibrato_control_counter;
#ifdef PRECALC_LOOPS
int32_t i;
int
vibflag=0;
while (count)
{
/* Hopefully the loop is longer than an increment */
if(ofs >= le)
ofs -= ll;
/* Precalc how many times to go through the loop, taking
the vibrato control ratio into account this time. */
i = (le - ofs) / incr + 1;
if(i > count) i = count;
if(i > cc)
{
i = cc;
vibflag = 1;
}
else cc -= i;
count -= i;
while(i--)
{
RESAMPLATION;
ofs += incr;
}
if(vibflag)
{
cc = vp->vibrato_control_ratio;
incr = update_vibrato(vp, 0);
vibflag = 0;
}
}
#else /* PRECALC_LOOPS */
while (count--)
{
if (!cc--)
{
cc=vp->vibrato_control_ratio;
incr=update_vibrato(vp, 0);
}
RESAMPLATION;
ofs += incr;
if (ofs>=le)
ofs -= ll; /* Hopefully the loop is longer than an increment. */
}
#endif /* PRECALC_LOOPS */
vp->vibrato_control_counter=cc;
vp->sample_increment=incr;
vp->sample_offset=ofs; /* Update offset */
return resample_buffer;
}
static sample_t *rs_vib_bidir(Voice *vp, int32_t count)
{
INTERPVARS;
int32_t
ofs=vp->sample_offset,
incr=vp->sample_increment,
le=vp->sample->loop_end,
ls=vp->sample->loop_start;
sample_t
*dest=resample_buffer,
*src=vp->sample->data;
int
cc=vp->vibrato_control_counter;
#ifdef PRECALC_LOOPS
int32_t
le2=le<<1,
ls2=ls<<1,
i;
int
vibflag = 0;
/* Play normally until inside the loop region */
while (count && (ofs <= ls))
{
i = (ls - ofs) / incr + 1;
if (i > count) i = count;
if (i > cc)
{
i = cc;
vibflag = 1;
}
else cc -= i;
count -= i;
while (i--)
{
RESAMPLATION;
ofs += incr;
}
if (vibflag)
{
cc = vp->vibrato_control_ratio;
incr = update_vibrato(vp, 0);
vibflag = 0;
}
}
/* Then do the bidirectional looping */
while (count)
{
/* Precalc how many times we should go through the loop */
i = ((incr > 0 ? le : ls) - ofs) / incr + 1;
if(i > count) i = count;
if(i > cc)
{
i = cc;
vibflag = 1;
}
else cc -= i;
count -= i;
while (i--)
{
RESAMPLATION;
ofs += incr;
}
if (vibflag)
{
cc = vp->vibrato_control_ratio;
incr = update_vibrato(vp, (incr < 0));
vibflag = 0;
}
if (ofs >= le)
{
/* fold the overshoot back in */
ofs = le2 - ofs;
incr *= -1;
}
else if (ofs <= ls)
{
ofs = ls2 - ofs;
incr *= -1;
}
}
#else /* PRECALC_LOOPS */
/* Play normally until inside the loop region */
if (ofs < ls)
{
while (count--)
{
if (!cc--)
{
cc=vp->vibrato_control_ratio;
incr=update_vibrato(vp, 0);
}
RESAMPLATION;
ofs += incr;
if (ofs>=ls)
break;
}
}
/* Then do the bidirectional looping */
if (count>0)
while (count--)
{
if (!cc--)
{
cc=vp->vibrato_control_ratio;
incr=update_vibrato(vp, (incr < 0));
}
RESAMPLATION;
ofs += incr;
if (ofs>=le)
{
/* fold the overshoot back in */
ofs = le - (ofs - le);
incr = -incr;
}
else if (ofs <= ls)
{
ofs = ls + (ls - ofs);
incr = -incr;
}
}
#endif /* PRECALC_LOOPS */
vp->vibrato_control_counter=cc;
vp->sample_increment=incr;
vp->sample_offset=ofs; /* Update offset */
return resample_buffer;
}
sample_t *resample_voice(int v, int32_t *countptr)
{
int32_t ofs;
uint8_t modes;
Voice *vp=&voice[v];
if (!(vp->sample->sample_rate))
{
/* Pre-resampled data -- just update the offset and check if
we're out of data. */
ofs=vp->sample_offset >> FRACTION_BITS; /* Kind of silly to use
FRACTION_BITS here... */
if (*countptr >= (vp->sample->data_length>>FRACTION_BITS) - ofs)
{
/* Note finished. Free the voice. */
vp->status = VOICE_FREE;
ctl->note(v);
/* Let the caller know how much data we had left */
*countptr = (vp->sample->data_length>>FRACTION_BITS) - ofs;
}
else
vp->sample_offset += *countptr << FRACTION_BITS;
return vp->sample->data+ofs;
}
/* Need to resample. Use the proper function. */
modes=vp->sample->modes;
if (vp->vibrato_control_ratio)
{
if ((modes & MODES_LOOPING) &&
((modes & MODES_ENVELOPE) ||
(vp->status==VOICE_ON || vp->status==VOICE_SUSTAINED)))
{
if (modes & MODES_PINGPONG)
return rs_vib_bidir(vp, *countptr);
else
return rs_vib_loop(vp, *countptr);
}
else
return rs_vib_plain(v, countptr);
}
else
{
if ((modes & MODES_LOOPING) &&
((modes & MODES_ENVELOPE) ||
(vp->status==VOICE_ON || vp->status==VOICE_SUSTAINED)))
{
if (modes & MODES_PINGPONG)
return rs_bidir(vp, *countptr);
else
return rs_loop(vp, *countptr);
}
else
return rs_plain(v, countptr);
}
}
void pre_resample(Sample * sp)
{
double a, xdiff;
int32_t incr, ofs, newlen, count;
int16_t *newdata, *dest, *src = (int16_t *) sp->data;
int16_t v1, v2, v3, v4, *vptr;
static const char note_name[12][3] =
{
"C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"
};
ctl->cmsg(CMSG_INFO, VERB_NOISY, " * pre-resampling for note %d (%s%d)",
sp->note_to_use,
note_name[sp->note_to_use % 12], (sp->note_to_use & 0x7F) / 12);
a = ((double) (sp->sample_rate) * freq_table[(int) (sp->note_to_use)]) /
((double) (sp->root_freq) * play_mode->rate);
newlen = (int32_t)(sp->data_length / a);
dest = newdata = (int16_t*)safe_malloc(newlen >> (FRACTION_BITS - 1));
count = (newlen >> FRACTION_BITS) - 1;
ofs = incr = (sp->data_length - (1 << FRACTION_BITS)) / count;
if (--count)
*dest++ = src[0];
/* Since we're pre-processing and this doesn't have to be done in
real-time, we go ahead and do the full sliding cubic interpolation. */
while (--count)
{
vptr = src + (ofs >> FRACTION_BITS);
v1 = *(vptr - 1);
v2 = *vptr;
v3 = *(vptr + 1);
v4 = *(vptr + 2);
xdiff = FSCALENEG(ofs & FRACTION_MASK, FRACTION_BITS);
*dest++ = (int16_t)(v2 + (xdiff / 6.0) * (-2 * v1 - 3 * v2 + 6 * v3 - v4 +
xdiff * (3 * (v1 - 2 * v2 + v3) + xdiff * (-v1 + 3 * (v2 - v3) + v4))));
ofs += incr;
}
if (ofs & FRACTION_MASK)
{
v1 = src[ofs >> FRACTION_BITS];
v2 = src[(ofs >> FRACTION_BITS) + 1];
*dest++ = v1 + (((v2 - v1) * (ofs & FRACTION_MASK)) >> FRACTION_BITS);
}
else
*dest++ = src[ofs >> FRACTION_BITS];
sp->data_length = newlen;
sp->loop_start = (int32_t)(sp->loop_start / a);
sp->loop_end = (int32_t)(sp->loop_end / a);
Real_Tim_Free(sp->data);
sp->data = (sample_t *) newdata;
sp->sample_rate = 0;
}

View File

@@ -0,0 +1,24 @@
/*
TiMidity -- Experimental MIDI to WAVE converter
Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
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., 675 Mass Ave, Cambridge, MA 02139, USA.
resample.h
*/
extern sample_t *resample_voice(int v, int32_t *countptr);
extern void pre_resample(Sample *sp);

View File

@@ -0,0 +1,59 @@
/*
TiMidity -- Experimental MIDI to WAVE converter
Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
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., 675 Mass Ave, Cambridge, MA 02139, USA.
sdl_a.c
Functions to output RIFF WAVE format data to a file or stdout.
*/
#include "config.h"
#include "output.h"
/* export the playback mode */
#define dpm sdl_play_mode
static int open_output(void); /* 0=success, 1=warning, -1=fatal error */
static void close_output(void);
static void output_data(int *buf, int count, int* bytes_written);
static void flush_output(void);
static void purge_output(void);
PlayMode dpm = {
DEFAULT_RATE, PE_16BIT|PE_SIGNED,
"SDL audio", 0, "d:\\out.wav",
open_output,
close_output,
output_data,
flush_output,
purge_output
};
/* Dummies */
static int open_output(void){
return 0;
}
static void output_data(int *buf, int count, int* bytes_written){}
static void close_output(void){}
static void flush_output(void) { }
static void purge_output(void) { }

View File

@@ -0,0 +1,138 @@
/*
TiMidity -- Experimental MIDI to WAVE converter
Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
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., 675 Mass Ave, Cambridge, MA 02139, USA.
sdl_c.c
Minimal control mode -- no interaction, just stores messages.
*/
#include "../../neo/idlib/precompiled.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include "config.h"
#include "common.h"
#include "output.h"
#include "controls.h"
#include "instrum.h"
#include "playmidi.h"
static void ctl_refresh(void);
static void ctl_total_time(int tt);
static void ctl_master_volume(int mv);
static void ctl_file_name(char *name);
static void ctl_current_time(int ct);
static void ctl_note(int v);
static void ctl_program(int ch, int val);
static void ctl_volume(int channel, int val);
static void ctl_expression(int channel, int val);
static void ctl_panning(int channel, int val);
static void ctl_sustain(int channel, int val);
static void ctl_pitch_bend(int channel, int val);
static void ctl_reset(void);
static int ctl_open(int using_stdin, int using_stdout);
static void ctl_close(void);
static int ctl_read(int *valp);
static int cmsg(int type, int verbosity_level, char *fmt, ...);
#ifdef _DEBUG
#define safeOutputDebug(x) printf( "%s", x )
#else
#define safeOutputDebug(x)
#endif
/**********************************/
/* export the interface functions */
#define ctl sdl_control_mode
ControlMode ctl=
{
"SDL interface", 's',
1,0,0,
ctl_open,NULL, ctl_close, ctl_read, cmsg,
ctl_refresh, ctl_reset, ctl_file_name, ctl_total_time, ctl_current_time,
ctl_note,
ctl_master_volume, ctl_program, ctl_volume,
ctl_expression, ctl_panning, ctl_sustain, ctl_pitch_bend
};
static int ctl_open(int using_stdin, int using_stdout)
{
ctl.opened=1;
return 0;
}
static void ctl_close(void)
{
ctl.opened=0;
}
static int ctl_read(int *valp)
{
return RC_NO_RETURN_VALUE;
}
extern void SendDebugMsg(const char*);
extern bool debugOutput;
static int cmsg(int type, int verbosity_level, char *fmt, ...)
{
#ifdef _DEBUG
va_list ap;
va_start(ap, fmt);
idStr::vsnPrintf(timidity_error, TIMIDITY_ERROR_MAX_CHARS - 1, fmt, ap);
va_end(ap);
strcat( timidity_error, "\n" );
if ( debugOutput && verbosity_level <= VERB_VERBOSE ) {
safeOutputDebug( timidity_error );
}
#endif
return 0;
}
static void ctl_refresh(void) { }
static void ctl_total_time(int tt) {}
static void ctl_master_volume(int mv) {}
static void ctl_file_name(char *name) {}
static void ctl_current_time(int ct) {}
static void ctl_note(int v) {}
static void ctl_program(int ch, int val) {}
static void ctl_volume(int channel, int val) {}
static void ctl_expression(int channel, int val) {}
static void ctl_panning(int channel, int val) {}
static void ctl_sustain(int channel, int val) {}
static void ctl_pitch_bend(int channel, int val) {}
static void ctl_reset(void) {}

View File

@@ -0,0 +1,40 @@
/*
TiMidity -- Experimental MIDI to WAVE converter
Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
In case you haven't heard, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
structs.h
*/
#ifndef TIMIDITY_STRUCTS_H
#define TIMIDITY_STRUCTS_H
#include <stdint.h>
typedef struct {
int32_t time;
uint8_t channel, type, a, b;
} MidiEvent;
struct _MidiSong {
int32_t samples;
MidiEvent *events;
};
#endif

View File

@@ -0,0 +1,901 @@
/*
TiMidity -- Experimental MIDI to WAVE converter
Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
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., 675 Mass Ave, Cambridge, MA 02139, USA.
The 8-bit uLaw to 16-bit PCM and the 13-bit-PCM to 8-bit uLaw
tables were lifted from the rsynth-2.0 sources. The README says:
>
> This is a text to speech system produced by integrating various pieces
> of code and tables of data, which are all (I believe) in the public domain.
>
> The bulk of the intergration was done by myself, that is Nick Ing-Simmons.
> I can be reached via my employer at nik@tiuk.ti.com.
>
*/
#include <stdio.h>
#include "config.h"
#include "common.h"
#include "tables.h"
int32_t freq_table[128]=
{
8176, 8662, 9177, 9723,
10301, 10913, 11562, 12250,
12978, 13750, 14568, 15434,
16352, 17324, 18354, 19445,
20602, 21827, 23125, 24500,
25957, 27500, 29135, 30868,
32703, 34648, 36708, 38891,
41203, 43654, 46249, 48999,
51913, 55000, 58270, 61735,
65406, 69296, 73416, 77782,
82407, 87307, 92499, 97999,
103826, 110000, 116541, 123471,
130813, 138591, 146832, 155563,
164814, 174614, 184997, 195998,
207652, 220000, 233082, 246942,
261626, 277183, 293665, 311127,
329628, 349228, 369994, 391995,
415305, 440000, 466164, 493883,
523251, 554365, 587330, 622254,
659255, 698456, 739989, 783991,
830609, 880000, 932328, 987767,
1046502, 1108731, 1174659, 1244508,
1318510, 1396913, 1479978, 1567982,
1661219, 1760000, 1864655, 1975533,
2093005, 2217461, 2349318, 2489016,
2637020, 2793826, 2959955, 3135963,
3322438, 3520000, 3729310, 3951066,
4186009, 4434922, 4698636, 4978032,
5274041, 5587652, 5919911, 6271927,
6644875, 7040000, 7458620, 7902133,
8372018, 8869844, 9397273, 9956063,
10548082, 11175303, 11839822, 12543854
};
/* v=2.^((x/127-1) * 6) */
double vol_table[128] =
{
0.015625, 0.016145143728351113, 0.016682602624583379, 0.017237953096759438,
0.017811790741104401, 0.01840473098076444, 0.019017409725829021, 0.019650484055324921,
0.020304632921913132, 0.020980557880044631, 0.021678983838355849, 0.02240065983711079,
0.023146359851523596, 0.023916883621822989, 0.024713057510949051, 0.025535735390801884,
0.026385799557992876, 0.027264161680080529, 0.028171763773305786, 0.029109579212875332,
0.030078613776876421, 0.031079906724942836, 0.032114531912828696, 0.033183598944085631,
0.034288254360078256, 0.035429682869614412, 0.036609108619508737, 0.037827796507442342,
0.039087053538526394, 0.040388230227024875, 0.041732722044739302, 0.043121970917609151,
0.044557466772132896, 0.046040749133268132, 0.047573408775524545, 0.049157089429020417,
0.050793489542332405, 0.05248436410402918, 0.054231526524842463, 0.056036850582493913,
0.057902272431264008, 0.059829792678457581, 0.061821478529993396, 0.063879466007418645,
0.066005962238725971, 0.068203247825430205, 0.070473679288442961, 0.072819691595368496,
0.075243800771931268, 0.077748606600335793, 0.080336795407452768, 0.083011142945821612,
0.085774517370559328, 0.088629882315368294, 0.091580300070941839, 0.094628934869176312,
0.097779056276712184, 0.10103404270144323, 0.1043973850157546, 0.1078726903003755,
0.11146368571286204, 0.11517422248485852, 0.11900828005242428, 0.12296997032385605,
0.12706354208958254, 0.13129338557886089, 0.13566403716816194, 0.14018018424629392,
0.14484667024148207, 0.14966849981579558, 0.15465084423249356, 0.15979904690204472,
0.16511862911277009, 0.17061529595225433, 0.17629494242587571, 0.18216365977901747,
0.18822774202974024, 0.19449369271892172, 0.20096823188510385, 0.20765830327152621,
0.21457108177307616, 0.22171398113114205, 0.2290946618846218, 0.23672103958561411,
0.2446012932886038, 0.25274387432224471, 0.26115751535314891, 0.26985123975140174,
0.27883437126784744, 0.28811654403352405, 0.29770771289197112, 0.30761816407549192,
0.31785852623682015, 0.32843978184802081, 0.33937327897885317, 0.3506707434672246,
0.36234429149478936, 0.37440644258117928, 0.38687013301080181, 0.39974872970660535,
0.41305604456569134, 0.42680634927214656, 0.44101439060298442, 0.45569540624360722,
0.47086514112975281, 0.48653986433345225, 0.50273638651110641, 0.51947207793239625,
0.53676488710936021, 0.55463336004561792, 0.57309666012638816, 0.59217458867062556,
0.61188760616732485, 0.63225685421876243, 0.65330417821421161, 0.67505215075844849,
0.69752409588017272, 0.72074411404630734, 0.74473710800900605, 0.76952880951308478,
0.79514580689252357, 0.82161557358563286, 0.84896649759946774, 0.87722791195508854,
0.90643012614631979, 0.93660445864574493, 0.96778327049280244, 1
};
double bend_fine[256] = {
1, 1.0002256593050698, 1.0004513695322617, 1.0006771306930664,
1.0009029427989777, 1.0011288058614922, 1.0013547198921082, 1.0015806849023274,
1.0018067009036538, 1.002032767907594, 1.0022588859256572, 1.0024850549693551,
1.0027112750502025, 1.0029375461797159, 1.0031638683694153, 1.0033902416308227,
1.0036166659754628, 1.0038431414148634, 1.0040696679605541, 1.0042962456240678,
1.0045228744169397, 1.0047495543507072, 1.0049762854369111, 1.0052030676870944,
1.0054299011128027, 1.0056567857255843, 1.00588372153699, 1.006110708558573,
1.0063377468018897, 1.0065648362784985, 1.0067919769999607, 1.0070191689778405,
1.0072464122237039, 1.0074737067491204, 1.0077010525656616, 1.0079284496849015,
1.0081558981184175, 1.008383397877789, 1.008610948974598, 1.0088385514204294,
1.0090662052268706, 1.0092939104055114, 1.0095216669679448, 1.0097494749257656,
1.009977334290572, 1.0102052450739643, 1.0104332072875455, 1.0106612209429215,
1.0108892860517005, 1.0111174026254934, 1.0113455706759138, 1.0115737902145781,
1.0118020612531047, 1.0120303838031153, 1.0122587578762337, 1.012487183484087,
1.0127156606383041, 1.0129441893505169, 1.0131727696323602, 1.0134014014954713,
1.0136300849514894, 1.0138588200120575, 1.0140876066888203, 1.0143164449934257,
1.0145453349375237, 1.0147742765327674, 1.0150032697908125, 1.0152323147233171,
1.015461411341942, 1.0156905596583505, 1.0159197596842091, 1.0161490114311862,
1.0163783149109531, 1.0166076701351838, 1.0168370771155553, 1.0170665358637463,
1.0172960463914391, 1.0175256087103179, 1.0177552228320703, 1.0179848887683858,
1.0182146065309567, 1.0184443761314785, 1.0186741975816487, 1.0189040708931674,
1.0191339960777379, 1.0193639731470658, 1.0195940021128593, 1.0198240829868295,
1.0200542157806898, 1.0202844005061564, 1.0205146371749483, 1.0207449257987866,
1.0209752663893958, 1.0212056589585028, 1.0214361035178368, 1.0216666000791297,
1.0218971486541166, 1.0221277492545349, 1.0223584018921241, 1.0225891065786274,
1.0228198633257899, 1.0230506721453596, 1.023281533049087, 1.0235124460487257,
1.0237434111560313, 1.0239744283827625, 1.0242054977406807, 1.0244366192415495,
1.0246677928971357, 1.0248990187192082, 1.025130296719539, 1.0253616269099028,
1.0255930093020766, 1.0258244439078401, 1.0260559307389761, 1.0262874698072693,
1.0265190611245079, 1.0267507047024822, 1.0269824005529853, 1.027214148687813,
1.0274459491187637, 1.0276778018576387, 1.0279097069162415, 1.0281416643063788,
1.0283736740398595, 1.0286057361284953, 1.0288378505841009, 1.0290700174184932,
1.0293022366434921, 1.0295345082709197, 1.0297668323126017, 1.0299992087803651,
1.030231637686041, 1.0304641190414621, 1.0306966528584645, 1.0309292391488862,
1.0311618779245688, 1.0313945691973556, 1.0316273129790936, 1.0318601092816313,
1.0320929581168212, 1.0323258594965172, 1.0325588134325767, 1.0327918199368598,
1.0330248790212284, 1.0332579906975481, 1.0334911549776868, 1.033724371873515,
1.0339576413969056, 1.0341909635597348, 1.0344243383738811, 1.0346577658512259,
1.034891246003653, 1.0351247788430489, 1.0353583643813031, 1.0355920026303078,
1.0358256936019572, 1.0360594373081489, 1.0362932337607829, 1.0365270829717617,
1.0367609849529913, 1.0369949397163791, 1.0372289472738365, 1.0374630076372766,
1.0376971208186156, 1.0379312868297725, 1.0381655056826686, 1.0383997773892284,
1.0386341019613787, 1.0388684794110492, 1.0391029097501721, 1.0393373929906822,
1.0395719291445176, 1.0398065182236185, 1.0400411602399278, 1.0402758552053915,
1.0405106031319582, 1.0407454040315787, 1.0409802579162071, 1.0412151647977996,
1.0414501246883161, 1.0416851375997183, 1.0419202035439705, 1.0421553225330404,
1.042390494578898, 1.042625719693516, 1.0428609978888699, 1.043096329176938,
1.0433317135697009, 1.0435671510791424, 1.0438026417172486, 1.0440381854960086,
1.0442737824274138, 1.044509432523459, 1.044745135796141, 1.0449808922574599,
1.0452167019194181, 1.0454525647940205, 1.0456884808932754, 1.0459244502291931,
1.0461604728137874, 1.0463965486590741, 1.046632677777072, 1.0468688601798024,
1.0471050958792898, 1.047341384887561, 1.0475777272166455, 1.047814122878576,
1.048050571885387, 1.0482870742491166, 1.0485236299818055, 1.0487602390954964,
1.0489969016022356, 1.0492336175140715, 1.0494703868430555, 1.0497072096012419,
1.0499440858006872, 1.0501810154534512, 1.050417998571596, 1.0506550351671864,
1.0508921252522903, 1.0511292688389782, 1.0513664659393229, 1.0516037165654004,
1.0518410207292894, 1.0520783784430709, 1.0523157897188296, 1.0525532545686513,
1.0527907730046264, 1.0530283450388465, 1.0532659706834067, 1.0535036499504049,
1.0537413828519411, 1.0539791694001188, 1.0542170096070436, 1.0544549034848243,
1.0546928510455722, 1.0549308523014012, 1.0551689072644284, 1.0554070159467728,
1.0556451783605572, 1.0558833945179062, 1.0561216644309479, 1.0563599881118126,
1.0565983655726334, 1.0568367968255465, 1.0570752818826903, 1.0573138207562065,
1.057552413458239, 1.0577910600009348, 1.0580297603964437, 1.058268514656918,
1.0585073227945128, 1.0587461848213857, 1.058985100749698, 1.0592240705916123
};
double bend_coarse[128] = {
1, 1.0594630943592953, 1.122462048309373, 1.189207115002721,
1.2599210498948732, 1.3348398541700344, 1.4142135623730951, 1.4983070768766815,
1.5874010519681994, 1.681792830507429, 1.7817974362806785, 1.8877486253633868,
2, 2.1189261887185906, 2.244924096618746, 2.3784142300054421,
2.5198420997897464, 2.6696797083400687, 2.8284271247461903, 2.996614153753363,
3.1748021039363992, 3.363585661014858, 3.5635948725613571, 3.7754972507267741,
4, 4.2378523774371812, 4.4898481932374912, 4.7568284600108841,
5.0396841995794928, 5.3393594166801366, 5.6568542494923806, 5.993228307506727,
6.3496042078727974, 6.727171322029716, 7.1271897451227151, 7.5509945014535473,
8, 8.4757047548743625, 8.9796963864749824, 9.5136569200217682,
10.079368399158986, 10.678718833360273, 11.313708498984761, 11.986456615013454,
12.699208415745595, 13.454342644059432, 14.25437949024543, 15.101989002907095,
16, 16.951409509748721, 17.959392772949972, 19.027313840043536,
20.158736798317967, 21.357437666720553, 22.627416997969522, 23.972913230026901,
25.398416831491197, 26.908685288118864, 28.508758980490853, 30.203978005814196,
32, 33.902819019497443, 35.918785545899944, 38.054627680087073,
40.317473596635935, 42.714875333441107, 45.254833995939045, 47.945826460053802,
50.796833662982394, 53.817370576237728, 57.017517960981706, 60.407956011628393,
64, 67.805638038994886, 71.837571091799887, 76.109255360174146,
80.63494719327187, 85.429750666882214, 90.509667991878089, 95.891652920107603,
101.59366732596479, 107.63474115247546, 114.03503592196341, 120.81591202325679,
128, 135.61127607798977, 143.67514218359977, 152.21851072034829,
161.26989438654374, 170.85950133376443, 181.01933598375618, 191.78330584021521,
203.18733465192958, 215.26948230495091, 228.07007184392683, 241.63182404651357,
256, 271.22255215597971, 287.35028436719938, 304.43702144069658,
322.53978877308765, 341.71900266752868, 362.03867196751236, 383.56661168043064,
406.37466930385892, 430.53896460990183, 456.14014368785394, 483.26364809302686,
512, 542.44510431195943, 574.70056873439876, 608.87404288139317,
645.0795775461753, 683.43800533505737, 724.07734393502471, 767.13322336086128,
812.74933860771785, 861.07792921980365, 912.28028737570787, 966.52729618605372,
1024, 1084.8902086239189, 1149.4011374687975, 1217.7480857627863,
1290.1591550923506, 1366.8760106701147, 1448.1546878700494, 1534.2664467217226
};
#ifdef LOOKUP_SINE
static double sine_table[257]=
{
0, 0.0061358846491544753, 0.012271538285719925, 0.01840672990580482,
0.024541228522912288, 0.030674803176636626, 0.036807222941358832, 0.04293825693494082,
0.049067674327418015, 0.055195244349689934, 0.061320736302208578, 0.067443919563664051,
0.073564563599667426, 0.079682437971430126, 0.085797312344439894, 0.091908956497132724,
0.098017140329560604, 0.10412163387205459, 0.11022220729388306, 0.11631863091190475,
0.1224106751992162, 0.12849811079379317, 0.13458070850712617, 0.14065823933284921,
0.14673047445536175, 0.15279718525844344, 0.15885814333386145, 0.16491312048996989,
0.17096188876030122, 0.17700422041214875, 0.18303988795514095, 0.18906866414980619,
0.19509032201612825, 0.2011046348420919, 0.20711137619221856, 0.21311031991609136,
0.2191012401568698, 0.22508391135979283, 0.23105810828067111, 0.2370236059943672,
0.24298017990326387, 0.24892760574572015, 0.25486565960451457, 0.26079411791527551,
0.26671275747489837, 0.27262135544994898, 0.27851968938505306, 0.28440753721127188,
0.29028467725446233, 0.29615088824362379, 0.30200594931922808, 0.30784964004153487,
0.31368174039889152, 0.31950203081601569, 0.32531029216226293, 0.33110630575987643,
0.33688985339222005, 0.34266071731199438, 0.34841868024943456, 0.35416352542049034,
0.35989503653498811, 0.36561299780477385, 0.37131719395183754, 0.37700741021641826,
0.38268343236508978, 0.38834504669882625, 0.3939920400610481, 0.39962419984564679,
0.40524131400498986, 0.41084317105790391, 0.41642956009763715, 0.42200027079979968,
0.42755509343028208, 0.43309381885315196, 0.43861623853852766, 0.4441221445704292,
0.44961132965460654, 0.45508358712634384, 0.46053871095824001, 0.46597649576796618,
0.47139673682599764, 0.47679923006332209, 0.48218377207912272, 0.487550160148436,
0.49289819222978404, 0.49822766697278187, 0.50353838372571758, 0.50883014254310699,
0.51410274419322166, 0.51935599016558964, 0.52458968267846895, 0.52980362468629461,
0.53499761988709715, 0.54017147272989285, 0.54532498842204646, 0.55045797293660481,
0.55557023301960218, 0.56066157619733603, 0.56573181078361312, 0.57078074588696726,
0.57580819141784534, 0.58081395809576453, 0.58579785745643886, 0.59075970185887416,
0.59569930449243336, 0.60061647938386897, 0.60551104140432555, 0.61038280627630948,
0.61523159058062682, 0.6200572117632891, 0.62485948814238634, 0.62963823891492698,
0.63439328416364549, 0.63912444486377573, 0.64383154288979139, 0.64851440102211244,
0.65317284295377676, 0.65780669329707864, 0.66241577759017178, 0.66699992230363747,
0.67155895484701833, 0.67609270357531592, 0.68060099779545302, 0.68508366777270036,
0.68954054473706683, 0.693971460889654, 0.69837624940897292, 0.7027547444572253,
0.70710678118654746, 0.71143219574521643, 0.71573082528381859, 0.72000250796138165,
0.72424708295146689, 0.7284643904482252, 0.73265427167241282, 0.73681656887736979,
0.74095112535495911, 0.74505778544146595, 0.74913639452345926, 0.75318679904361241,
0.75720884650648446, 0.76120238548426178, 0.76516726562245896, 0.76910333764557959,
0.77301045336273699, 0.77688846567323244, 0.78073722857209438, 0.78455659715557524,
0.78834642762660623, 0.79210657730021239, 0.79583690460888346, 0.79953726910790501,
0.80320753148064483, 0.80684755354379922, 0.81045719825259477, 0.8140363297059483,
0.81758481315158371, 0.82110251499110465, 0.82458930278502529, 0.8280450452577558,
0.83146961230254524, 0.83486287498638001, 0.83822470555483797, 0.84155497743689833,
0.84485356524970701, 0.84812034480329712, 0.8513551931052652, 0.85455798836540053,
0.85772861000027212, 0.86086693863776731, 0.8639728561215867, 0.86704624551569265,
0.87008699110871135, 0.87309497841829009, 0.8760700941954066, 0.87901222642863341,
0.88192126434835494, 0.88479709843093779, 0.88763962040285393, 0.89044872324475788,
0.89322430119551532, 0.89596624975618511, 0.89867446569395382, 0.90134884704602203,
0.90398929312344334, 0.90659570451491533, 0.90916798309052227, 0.91170603200542988,
0.91420975570353069, 0.9166790599210427, 0.91911385169005777, 0.9215140393420419,
0.92387953251128674, 0.92621024213831127, 0.92850608047321548, 0.93076696107898371,
0.93299279883473885, 0.9351835099389475, 0.93733901191257496, 0.93945922360218992,
0.94154406518302081, 0.94359345816196039, 0.94560732538052128, 0.94758559101774109,
0.94952818059303667, 0.95143502096900834, 0.95330604035419375, 0.95514116830577067,
0.95694033573220894, 0.9587034748958716, 0.96043051941556579, 0.96212140426904158,
0.96377606579543984, 0.9653944416976894, 0.96697647104485207, 0.96852209427441727,
0.97003125319454397, 0.97150389098625178, 0.97293995220556007, 0.97433938278557586,
0.97570213003852857, 0.97702814265775439, 0.97831737071962765, 0.97956976568544052,
0.98078528040323043, 0.98196386910955524, 0.98310548743121629, 0.98421009238692903,
0.98527764238894122, 0.98630809724459867, 0.98730141815785843, 0.98825756773074946,
0.98917650996478101, 0.99005821026229712, 0.99090263542778001, 0.99170975366909953,
0.99247953459870997, 0.9932119492347945, 0.99390697000235606, 0.99456457073425542,
0.99518472667219682, 0.99576741446765982, 0.996312612182778, 0.99682029929116567,
0.99729045667869021, 0.99772306664419164, 0.99811811290014918, 0.99847558057329477,
0.99879545620517241, 0.99907772775264536, 0.99932238458834954, 0.99952941750109314,
0.99969881869620425, 0.9998305817958234, 0.9999247018391445, 0.99998117528260111,
1
};
/*
looks up sin(2 * Pi * x / 1024)
*/
float sine(int x)
{
int xx = x & 0xFF;
switch ((x>>8) & 0x03)
{
default: /* just to shut gcc up. */
case 0:
return sine_table[xx];
case 1:
return sine_table[0x100 - xx];
case 2:
return -sine_table[xx];
case 3:
return -sine_table[0x100 - xx];
}
}
#endif /* LOOKUP_SINE */
#ifdef LOOKUP_HACK
int16_t _u2l[] =
{
-32256, -31228, -30200, -29172, -28143, -27115, -26087, -25059,
-24031, -23002, -21974, -20946, -19918, -18889, -17861, -16833,
-16062, -15548, -15033, -14519, -14005, -13491, -12977, -12463,
-11949, -11435, -10920, -10406, -9892, -9378, -8864, -8350,
-7964, -7707, -7450, -7193, -6936, -6679, -6422, -6165,
-5908, -5651, -5394, -5137, -4880, -4623, -4365, -4108,
-3916, -3787, -3659, -3530, -3402, -3273, -3144, -3016,
-2887, -2759, -2630, -2502, -2373, -2245, -2116, -1988,
-1891, -1827, -1763, -1698, -1634, -1570, -1506, -1441,
-1377, -1313, -1249, -1184, -1120, -1056, -992, -927,
-879, -847, -815, -783, -751, -718, -686, -654,
-622, -590, -558, -526, -494, -461, -429, -397,
-373, -357, -341, -325, -309, -293, -277, -261,
-245, -228, -212, -196, -180, -164, -148, -132,
-120, -112, -104, -96, -88, -80, -72, -64,
-56, -48, -40, -32, -24, -16, -8, 0,
32256, 31228, 30200, 29172, 28143, 27115, 26087, 25059,
24031, 23002, 21974, 20946, 19918, 18889, 17861, 16833,
16062, 15548, 15033, 14519, 14005, 13491, 12977, 12463,
11949, 11435, 10920, 10406, 9892, 9378, 8864, 8350,
7964, 7707, 7450, 7193, 6936, 6679, 6422, 6165,
5908, 5651, 5394, 5137, 4880, 4623, 4365, 4108,
3916, 3787, 3659, 3530, 3402, 3273, 3144, 3016,
2887, 2759, 2630, 2502, 2373, 2245, 2116, 1988,
1891, 1827, 1763, 1698, 1634, 1570, 1506, 1441,
1377, 1313, 1249, 1184, 1120, 1056, 992, 927,
879, 847, 815, 783, 751, 718, 686, 654,
622, 590, 558, 526, 494, 461, 429, 397,
373, 357, 341, 325, 309, 293, 277, 261,
245, 228, 212, 196, 180, 164, 148, 132,
120, 112, 104, 96, 88, 80, 72, 64,
56, 48, 40, 32, 24, 16, 8, 0
};
int32_t *mixup;
#ifdef LOOKUP_INTERPOLATION
int8_t *iplookup;
#endif
#endif
void init_tables(void)
{
#ifdef LOOKUP_HACK
int i,j,v;
mixup=safe_malloc(1<<(7+8+2)); /* Give your cache a workout! */
for (i=0; i<128; i++)
{
v=_u2l[255-i];
for (j=-128; j<128; j++)
{
mixup[ ((i & 0x7F)<<8) | (j & 0xFF)] =
(v * j) << MIXUP_SHIFT;
}
}
#ifdef LOOKUP_INTERPOLATION
iplookup=safe_malloc(1<<(9+5));
for (i=-256; i<256; i++)
for(j=0; j<32; j++)
iplookup[((i<<5) & 0x3FE0) | j] = (i * j)>>5;
/* I don't know. Quantum bits? Magick? */
#endif
#endif
}
uint8_t _l2u_[] =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
0x09, 0x09, 0x09, 0x09, 0x09, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B,
0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B,
0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B,
0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B,
0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B,
0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B,
0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B,
0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B,
0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E,
0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E,
0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E,
0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E,
0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E,
0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E,
0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E,
0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E,
0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16,
0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16,
0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16,
0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16,
0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x19, 0x19, 0x19, 0x19, 0x19,
0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A,
0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A,
0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A,
0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A,
0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B,
0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B,
0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B,
0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B,
0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C,
0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C,
0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C,
0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C,
0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1D, 0x1D, 0x1D, 0x1D,
0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D,
0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D,
0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D,
0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1E, 0x1E, 0x1E, 0x1E,
0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E,
0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E,
0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E,
0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1F, 0x1F, 0x1F, 0x1F,
0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F,
0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F,
0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F,
0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x21,
0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x22, 0x22, 0x22,
0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x23, 0x23, 0x23,
0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x24, 0x24, 0x24,
0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x25, 0x25, 0x25,
0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x26, 0x26, 0x26,
0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x27, 0x27, 0x27,
0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x28, 0x28,
0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x29, 0x29,
0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x2A, 0x2A,
0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A,
0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2B, 0x2B,
0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B,
0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2C, 0x2C,
0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C,
0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2D, 0x2D,
0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D,
0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2E, 0x2E,
0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2F, 0x2F,
0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F,
0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x30,
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31,
0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x32,
0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x33,
0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x34,
0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x35,
0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37,
0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x38,
0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x39,
0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x3A,
0x3A, 0x3A, 0x3A, 0x3A, 0x3A, 0x3A, 0x3A, 0x3A, 0x3A, 0x3A, 0x3A, 0x3A, 0x3A, 0x3A, 0x3A, 0x3B,
0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3C,
0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3D,
0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D,
0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E,
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43,
0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45,
0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49,
0x4A, 0x4A, 0x4A, 0x4A, 0x4A, 0x4A, 0x4A, 0x4A, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x4D, 0x4D, 0x4D, 0x4D, 0x4D, 0x4D, 0x4D, 0x4D,
0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F,
0x50, 0x50, 0x50, 0x50, 0x51, 0x51, 0x51, 0x51, 0x52, 0x52, 0x52, 0x52, 0x53, 0x53, 0x53, 0x53,
0x54, 0x54, 0x54, 0x54, 0x55, 0x55, 0x55, 0x55, 0x56, 0x56, 0x56, 0x56, 0x57, 0x57, 0x57, 0x57,
0x58, 0x58, 0x58, 0x58, 0x59, 0x59, 0x59, 0x59, 0x5A, 0x5A, 0x5A, 0x5A, 0x5B, 0x5B, 0x5B, 0x5B,
0x5C, 0x5C, 0x5C, 0x5C, 0x5D, 0x5D, 0x5D, 0x5D, 0x5E, 0x5E, 0x5E, 0x5E, 0x5F, 0x5F, 0x5F, 0x5F,
0x60, 0x60, 0x61, 0x61, 0x62, 0x62, 0x63, 0x63, 0x64, 0x64, 0x65, 0x65, 0x66, 0x66, 0x67, 0x67,
0x68, 0x68, 0x68, 0x69, 0x69, 0x6A, 0x6A, 0x6B, 0x6B, 0x6C, 0x6C, 0x6D, 0x6D, 0x6E, 0x6E, 0x6F,
0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E,
0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8, 0xF7, 0xF6, 0xF5, 0xF4, 0xF3, 0xF2, 0xF1, 0xF0,
0xEF, 0xEF, 0xEE, 0xEE, 0xED, 0xED, 0xEC, 0xEC, 0xEB, 0xEB, 0xEA, 0xEA, 0xE9, 0xE9, 0xE8, 0xE8,
0xE7, 0xE7, 0xE6, 0xE6, 0xE5, 0xE5, 0xE4, 0xE4, 0xE3, 0xE3, 0xE2, 0xE2, 0xE1, 0xE1, 0xE0, 0xE0,
0xDF, 0xDF, 0xDF, 0xDF, 0xDE, 0xDE, 0xDE, 0xDE, 0xDD, 0xDD, 0xDD, 0xDD, 0xDC, 0xDC, 0xDC, 0xDC,
0xDB, 0xDB, 0xDB, 0xDB, 0xDA, 0xDA, 0xDA, 0xDA, 0xD9, 0xD9, 0xD9, 0xD9, 0xD8, 0xD8, 0xD8, 0xD8,
0xD7, 0xD7, 0xD7, 0xD7, 0xD6, 0xD6, 0xD6, 0xD6, 0xD5, 0xD5, 0xD5, 0xD5, 0xD4, 0xD4, 0xD4, 0xD4,
0xD3, 0xD3, 0xD3, 0xD3, 0xD2, 0xD2, 0xD2, 0xD2, 0xD1, 0xD1, 0xD1, 0xD1, 0xD0, 0xD0, 0xD0, 0xD0,
0xCF, 0xCF, 0xCF, 0xCF, 0xCF, 0xCF, 0xCF, 0xCF, 0xCE, 0xCE, 0xCE, 0xCE, 0xCE, 0xCE, 0xCE, 0xCE,
0xCD, 0xCD, 0xCD, 0xCD, 0xCD, 0xCD, 0xCD, 0xCD, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
0xCB, 0xCB, 0xCB, 0xCB, 0xCB, 0xCB, 0xCB, 0xCB, 0xCA, 0xCA, 0xCA, 0xCA, 0xCA, 0xCA, 0xCA, 0xCA,
0xC9, 0xC9, 0xC9, 0xC9, 0xC9, 0xC9, 0xC9, 0xC9, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8,
0xC7, 0xC7, 0xC7, 0xC7, 0xC7, 0xC7, 0xC7, 0xC7, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6,
0xC5, 0xC5, 0xC5, 0xC5, 0xC5, 0xC5, 0xC5, 0xC5, 0xC4, 0xC4, 0xC4, 0xC4, 0xC4, 0xC4, 0xC4, 0xC4,
0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2,
0xC2, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,
0xC0, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF,
0xBF, 0xBE, 0xBE, 0xBE, 0xBE, 0xBE, 0xBE, 0xBE, 0xBE, 0xBE, 0xBE, 0xBE, 0xBE, 0xBE, 0xBE, 0xBE,
0xBE, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD,
0xBD, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC,
0xBC, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
0xBB, 0xBA, 0xBA, 0xBA, 0xBA, 0xBA, 0xBA, 0xBA, 0xBA, 0xBA, 0xBA, 0xBA, 0xBA, 0xBA, 0xBA, 0xBA,
0xBA, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9,
0xB9, 0xB8, 0xB8, 0xB8, 0xB8, 0xB8, 0xB8, 0xB8, 0xB8, 0xB8, 0xB8, 0xB8, 0xB8, 0xB8, 0xB8, 0xB8,
0xB8, 0xB7, 0xB7, 0xB7, 0xB7, 0xB7, 0xB7, 0xB7, 0xB7, 0xB7, 0xB7, 0xB7, 0xB7, 0xB7, 0xB7, 0xB7,
0xB7, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6,
0xB6, 0xB5, 0xB5, 0xB5, 0xB5, 0xB5, 0xB5, 0xB5, 0xB5, 0xB5, 0xB5, 0xB5, 0xB5, 0xB5, 0xB5, 0xB5,
0xB5, 0xB4, 0xB4, 0xB4, 0xB4, 0xB4, 0xB4, 0xB4, 0xB4, 0xB4, 0xB4, 0xB4, 0xB4, 0xB4, 0xB4, 0xB4,
0xB4, 0xB3, 0xB3, 0xB3, 0xB3, 0xB3, 0xB3, 0xB3, 0xB3, 0xB3, 0xB3, 0xB3, 0xB3, 0xB3, 0xB3, 0xB3,
0xB3, 0xB2, 0xB2, 0xB2, 0xB2, 0xB2, 0xB2, 0xB2, 0xB2, 0xB2, 0xB2, 0xB2, 0xB2, 0xB2, 0xB2, 0xB2,
0xB2, 0xB2, 0xB1, 0xB1, 0xB1, 0xB1, 0xB1, 0xB1, 0xB1, 0xB1, 0xB1, 0xB1, 0xB1, 0xB1, 0xB1, 0xB1,
0xB1, 0xB1, 0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0xB0,
0xB0, 0xB0, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF,
0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF,
0xAF, 0xAF, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE,
0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE,
0xAE, 0xAE, 0xAD, 0xAD, 0xAD, 0xAD, 0xAD, 0xAD, 0xAD, 0xAD, 0xAD, 0xAD, 0xAD, 0xAD, 0xAD, 0xAD,
0xAD, 0xAD, 0xAD, 0xAD, 0xAD, 0xAD, 0xAD, 0xAD, 0xAD, 0xAD, 0xAD, 0xAD, 0xAD, 0xAD, 0xAD, 0xAD,
0xAD, 0xAD, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC,
0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC,
0xAC, 0xAC, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB,
0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB,
0xAB, 0xAB, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
0xAA, 0xAA, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9,
0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9,
0xA9, 0xA9, 0xA9, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8,
0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8,
0xA8, 0xA8, 0xA8, 0xA7, 0xA7, 0xA7, 0xA7, 0xA7, 0xA7, 0xA7, 0xA7, 0xA7, 0xA7, 0xA7, 0xA7, 0xA7,
0xA7, 0xA7, 0xA7, 0xA7, 0xA7, 0xA7, 0xA7, 0xA7, 0xA7, 0xA7, 0xA7, 0xA7, 0xA7, 0xA7, 0xA7, 0xA7,
0xA7, 0xA7, 0xA7, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6,
0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6,
0xA6, 0xA6, 0xA6, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5,
0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5,
0xA5, 0xA5, 0xA5, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4,
0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4,
0xA4, 0xA4, 0xA4, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3,
0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3,
0xA3, 0xA3, 0xA3, 0xA2, 0xA2, 0xA2, 0xA2, 0xA2, 0xA2, 0xA2, 0xA2, 0xA2, 0xA2, 0xA2, 0xA2, 0xA2,
0xA2, 0xA2, 0xA2, 0xA2, 0xA2, 0xA2, 0xA2, 0xA2, 0xA2, 0xA2, 0xA2, 0xA2, 0xA2, 0xA2, 0xA2, 0xA2,
0xA2, 0xA2, 0xA2, 0xA2, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1,
0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1,
0xA1, 0xA1, 0xA1, 0xA1, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
0xA0, 0xA0, 0xA0, 0xA0, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F,
0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F,
0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F,
0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F,
0x9F, 0x9F, 0x9F, 0x9F, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E,
0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E,
0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E,
0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E,
0x9E, 0x9E, 0x9E, 0x9E, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D,
0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D,
0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D,
0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D,
0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C,
0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C,
0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C,
0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C,
0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B,
0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B,
0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B,
0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B,
0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97,
0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97,
0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97,
0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97,
0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F,
0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F,
0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F,
0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F,
0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F,
0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F,
0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F,
0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F,
0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E,
0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E,
0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E,
0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E,
0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E,
0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E,
0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E,
0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E,
0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D,
0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D,
0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D,
0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D,
0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D,
0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D,
0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D,
0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D,
0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C,
0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C,
0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C,
0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C,
0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C,
0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C,
0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C,
0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C,
0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B,
0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B,
0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B,
0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B,
0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B,
0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B,
0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B,
0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B,
0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A,
0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A,
0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A,
0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A,
0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A,
0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A,
0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A,
0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A,
0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x89, 0x89, 0x89, 0x89, 0x89,
0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x88, 0x88, 0x88, 0x88,
0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x87, 0x87, 0x87,
0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x86, 0x86, 0x86,
0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x85, 0x85, 0x85,
0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x84, 0x84,
0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x83, 0x83,
0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x82,
0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x81,
0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80
};
uint8_t *_l2u = _l2u_ + 4096;

View File

@@ -0,0 +1,45 @@
/*
TiMidity -- Experimental MIDI to WAVE converter
Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
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., 675 Mass Ave, Cambridge, MA 02139, USA.
tables.h
*/
#ifdef LOOKUP_SINE
extern float sine(int x);
#else
#include <math.h>
#define sine(x) (sin((2*PI/1024.0) * (x)))
#endif
#define SINE_CYCLE_LENGTH 1024
extern int32_t freq_table[];
extern double vol_table[];
extern double bend_fine[];
extern double bend_coarse[];
extern uint8_t *_l2u; /* 13-bit PCM to 8-bit u-law */
extern uint8_t _l2u_[]; /* used in LOOKUP_HACK */
#ifdef LOOKUP_HACK
extern int16_t _u2l[];
extern int32_t *mixup;
#ifdef LOOKUP_INTERPOLATION
extern int8_t *iplookup;
#endif
#endif
extern void init_tables(void);

View File

@@ -0,0 +1,400 @@
/*
TiMidity -- Experimental MIDI to WAVE converter
Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "../../neo/idlib/precompiled.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//#include "SDL.h"
#include "config.h"
#include "common.h"
#include "instrum.h"
#include "playmidi.h"
#include "readmidi.h"
#include "output.h"
#include "controls.h"
#include "timidity.h"
#include "tables.h"
//void *Real_Tim_Malloc( int sz );
//void Real_Tim_Free( void *pt );
void (*s32tobuf)(void *dp, int32_t *lp, int32_t c);
int free_instruments_afterwards=0;
static char def_instr_name[256]="";
int AUDIO_BUFFER_SIZE;
sample_t *resample_buffer;
int32_t *common_buffer;
#define MAXWORDS 10
// Alternative to FGets
char* Gets( idFile & file, char *buf, int bsize ) {
int i;
char c;
int done = 0;
if (buf == 0 || bsize <= 0 )
return 0;
for (i = 0; !done && i < bsize - 1; i++) {
int red = file.ReadChar(c);
if (red == 0) {
done = 1;
i--;
} else {
buf[i] = c;
if (c == '\n')
done = 1;
}
}
buf[i] = '\0';
if (i == 0)
return 0;
else
return buf;
}
static int read_config_file(const char *name)
{
idFile * fp;
char *w[MAXWORDS], *cp;
ToneBank *bank=0;
int i, j, k, line=0, words;
static int rcf_count=0;
if (rcf_count>50)
{
ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
"Probable source loop in configuration files");
return (-1);
}
if (!(fp=open_file(name, 1, OF_VERBOSE)))
return -2;
char tokTmp[1024];
while ( Gets( *fp, tokTmp, 1024 ) )
{
line++;
w[words=0]=strtok(tokTmp, " \t\r\n\240");
if (!w[0] || (*w[0]=='#')) continue;
while (w[words] && (words < MAXWORDS))
w[++words]=strtok(0," \t\r\n\240");
if (!strcmp(w[0], "dir"))
{
if (words < 2)
{
ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
"%s: line %d: No directory given\n", name, line);
return -3;
}
for (i=1; i<words; i++)
add_to_pathlist(w[i]);
}
else if (!strcmp(w[0], "source"))
{
if (words < 2)
{
ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
"%s: line %d: No file name given\n", name, line);
return -4;
}
for (i=1; i<words; i++)
{
rcf_count++;
read_config_file(w[i]);
rcf_count--;
}
}
else if (!strcmp(w[0], "default"))
{
if (words != 2)
{
ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
"%s: line %d: Must specify exactly one patch name\n",
name, line);
return -5;
}
strncpy(def_instr_name, w[1], 255);
def_instr_name[255]='\0';
}
else if (!strcmp(w[0], "drumset"))
{
if (words < 2)
{
ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
"%s: line %d: No drum set number given\n",
name, line);
return -6;
}
i=atoi(w[1]);
if (i<0 || i>127)
{
ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
"%s: line %d: Drum set must be between 0 and 127\n",
name, line);
return -7;
}
if (!drumset[i])
{
drumset[i]=(ToneBank*)safe_malloc(sizeof(ToneBank));
memset(drumset[i], 0, sizeof(ToneBank));
}
bank=drumset[i];
}
else if (!strcmp(w[0], "bank"))
{
if (words < 2)
{
ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
"%s: line %d: No bank number given\n",
name, line);
return -8;
}
i=atoi(w[1]);
if (i<0 || i>127)
{
ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
"%s: line %d: Tone bank must be between 0 and 127\n",
name, line);
return -9;
}
if (!tonebank[i])
{
tonebank[i]=(ToneBank*)safe_malloc(sizeof(ToneBank));
memset(tonebank[i], 0, sizeof(ToneBank));
}
bank=tonebank[i];
}
else {
if ((words < 2) || (*w[0] < '0' || *w[0] > '9'))
{
ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
"%s: line %d: syntax error\n", name, line);
return -10;
}
i=atoi(w[0]);
if (i<0 || i>127)
{
ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
"%s: line %d: Program must be between 0 and 127\n",
name, line);
return -11;
}
if (!bank)
{
ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
"%s: line %d: Must specify tone bank or drum set "
"before assignment\n",
name, line);
return -12;
}
if (bank->tone[i].name)
Real_Tim_Free(bank->tone[i].name);
strcpy((bank->tone[i].name=(char*)safe_malloc(strlen(w[1])+1)),w[1]);
bank->tone[i].note=bank->tone[i].amp=bank->tone[i].pan=
bank->tone[i].strip_loop=bank->tone[i].strip_envelope=
bank->tone[i].strip_tail=-1;
for (j=2; j<words; j++)
{
if (!(cp=strchr(w[j], '=')))
{
ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: line %d: bad patch option %s\n",
name, line, w[j]);
return -13;
}
*cp++=0;
if (!strcmp(w[j], "amp"))
{
k=atoi(cp);
if ((k<0 || k>MAX_AMPLIFICATION) || (*cp < '0' || *cp > '9'))
{
ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
"%s: line %d: amplification must be between "
"0 and %d\n", name, line, MAX_AMPLIFICATION);
return -14;
}
bank->tone[i].amp=k;
}
else if (!strcmp(w[j], "note"))
{
k=atoi(cp);
if ((k<0 || k>127) || (*cp < '0' || *cp > '9'))
{
ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
"%s: line %d: note must be between 0 and 127\n",
name, line);
return -15;
}
bank->tone[i].note=k;
}
else if (!strcmp(w[j], "pan"))
{
if (!strcmp(cp, "center"))
k=64;
else if (!strcmp(cp, "left"))
k=0;
else if (!strcmp(cp, "right"))
k=127;
else
k=((atoi(cp)+100) * 100) / 157;
if ((k<0 || k>127) ||
(k==0 && *cp!='-' && (*cp < '0' || *cp > '9')))
{
ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
"%s: line %d: panning must be left, right, "
"center, or between -100 and 100\n",
name, line);
return -16;
}
bank->tone[i].pan=k;
}
else if (!strcmp(w[j], "keep"))
{
if (!strcmp(cp, "env"))
bank->tone[i].strip_envelope=0;
else if (!strcmp(cp, "loop"))
bank->tone[i].strip_loop=0;
else
{
ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
"%s: line %d: keep must be env or loop\n", name, line);
return -17;
}
}
else if (!strcmp(w[j], "strip"))
{
if (!strcmp(cp, "env"))
bank->tone[i].strip_envelope=1;
else if (!strcmp(cp, "loop"))
bank->tone[i].strip_loop=1;
else if (!strcmp(cp, "tail"))
bank->tone[i].strip_tail=1;
else
{
ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
"%s: line %d: strip must be env, loop, or tail\n",
name, line);
return -18;
}
}
else
{
ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: line %d: bad patch option %s\n",
name, line, w[j]);
return -19;
}
}
}
}
if ( fp == 0 ) //(ferror(fp))
{
ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Can't read from %s\n", name);
close_file(fp);
return -20;
}
close_file(fp);
return 0;
}
int Timidity_Init(int rate, int format, int channels, int samples, const char* config)
{
int ret;
ret = read_config_file(config);
if (ret < 0) {
return(ret);
}
/* Set play mode parameters */
play_mode->rate = rate;
play_mode->encoding = 0;
if ( (format&0xFF) == 16 ) {
play_mode->encoding |= PE_16BIT;
}
if ( (format&0x8000) ) {
play_mode->encoding |= PE_SIGNED;
}
if ( channels == 1 ) {
play_mode->encoding |= PE_MONO;
}
switch (format) {
case AUDIO_S8:
s32tobuf = s32tos8;
break;
case AUDIO_U8:
s32tobuf = s32tou8;
break;
case AUDIO_S16LSB:
s32tobuf = s32tos16l;
break;
case AUDIO_S16MSB:
s32tobuf = s32tos16b;
break;
case AUDIO_U16LSB:
s32tobuf = s32tou16l;
break;
case AUDIO_U16MSB:
s32tobuf = s32tou16b;
break;
default:
ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Unsupported audio format");
return(-1);
}
AUDIO_BUFFER_SIZE = samples;
/* Allocate memory for mixing (WARNING: Memory leak!) */
resample_buffer = (sample_t*)safe_malloc(AUDIO_BUFFER_SIZE*sizeof(sample_t));
common_buffer = (int32*)safe_malloc(AUDIO_BUFFER_SIZE*2*sizeof(int32_t));
init_tables();
if (ctl->open(0, 0)) {
ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Couldn't open %s\n", ctl->id_name);
return(-1);
}
if (!control_ratio) {
control_ratio = play_mode->rate / CONTROLS_PER_SECOND;
if(control_ratio<1)
control_ratio=1;
else if (control_ratio > MAX_CONTROL_RATIO)
control_ratio=MAX_CONTROL_RATIO;
}
if (*def_instr_name)
set_default_instrument(def_instr_name);
return(0);
}
char timidity_error[TIMIDITY_ERROR_MAX_CHARS] = "";
char *Timidity_Error(void)
{
return(timidity_error);
}

View File

@@ -0,0 +1,70 @@
/*
TiMidity -- Experimental MIDI to WAVE converter
Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef _TIMIDITY_H_
#define _TIMIDITY_H_
/* Audio format flags (defaults to LSB byte order) */
#define AUDIO_U8 0x0008 /* Unsigned 8-bit samples */
#define AUDIO_S8 0x8008 /* Signed 8-bit samples */
#define AUDIO_U16LSB 0x0010 /* Unsigned 16-bit samples */
#define AUDIO_S16LSB 0x8010 /* Signed 16-bit samples */
#define AUDIO_U16MSB 0x1010 /* As above, but big-endian byte order */
#define AUDIO_S16MSB 0x9010 /* As above, but big-endian byte order */
#define AUDIO_U16 AUDIO_U16LSB
#define AUDIO_S16 AUDIO_S16LSB
#include "structs.h"
typedef struct _MidiSong MidiSong;
extern int Timidity_Init(int rate, int format, int channels, int samples, const char* config);
extern char *Timidity_Error(void);
extern void Timidity_SetVolume(int volume);
extern int Timidity_PlaySome(void *stream, int samples, int* bytes_written);
extern MidiSong *Timidity_LoadSong(char *midifile);
extern MidiSong *Timidity_LoadSongMem(unsigned char* buffer, size_t length);
extern void Timidity_Start(MidiSong *song);
extern int Timidity_Active(void);
extern void Timidity_Stop(void);
extern void Timidity_FreeSong(MidiSong *song);
extern void Timidity_Shutdown(void);
extern void *Real_Tim_Malloc( int sz );
extern void Real_Tim_Free( void *pt );
typedef struct {
int rate, encoding;
char *id_name;
FILE* fp;
char *file_name;
int (*open_output)(void); /* 0=success, 1=warning, -1=fatal error */
void (*close_output)(void);
void (*output_data)(int *buf, int count, int* bytes_written);
void (*flush_output)(void);
void (*purge_output)(void);
} PlayMode;
extern PlayMode *play_mode_list[], *play_mode;
#endif

View File

@@ -0,0 +1,116 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClInclude Include="common.h" />
<ClInclude Include="config.h" />
<ClInclude Include="controls.h" />
<ClInclude Include="filter.h" />
<ClInclude Include="instrum.h" />
<ClInclude Include="mix.h" />
<ClInclude Include="output.h" />
<ClInclude Include="playmidi.h" />
<ClInclude Include="readmidi.h" />
<ClInclude Include="resample.h" />
<ClInclude Include="structs.h" />
<ClInclude Include="tables.h" />
<ClInclude Include="timidity.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="common.cpp" />
<ClCompile Include="controls.cpp" />
<ClCompile Include="filter.cpp" />
<ClCompile Include="instrum.cpp" />
<ClCompile Include="mix.cpp" />
<ClCompile Include="output.cpp" />
<ClCompile Include="playmidi.cpp" />
<ClCompile Include="readmidi.cpp" />
<ClCompile Include="resample.cpp" />
<ClCompile Include="sdl_a.cpp" />
<ClCompile Include="sdl_c.cpp" />
<ClCompile Include="tables.cpp" />
<ClCompile Include="timidity.cpp" />
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{3267F0ED-FE57-4348-91D7-AA8A4976750F}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>timidity</RootNamespace>
<SccProjectName>
</SccProjectName>
<SccAuxPath>
</SccAuxPath>
<SccLocalPath>
</SccLocalPath>
<SccProvider>
</SccProvider>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\DoomClassicCommon.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\DoomClassicCommon.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClInclude Include="tables.h" />
<ClInclude Include="timidity.h" />
<ClInclude Include="common.h" />
<ClInclude Include="config.h" />
<ClInclude Include="controls.h" />
<ClInclude Include="filter.h" />
<ClInclude Include="instrum.h" />
<ClInclude Include="mix.h" />
<ClInclude Include="output.h" />
<ClInclude Include="playmidi.h" />
<ClInclude Include="readmidi.h" />
<ClInclude Include="resample.h" />
<ClInclude Include="structs.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="timidity.cpp" />
<ClCompile Include="common.cpp" />
<ClCompile Include="controls.cpp" />
<ClCompile Include="filter.cpp" />
<ClCompile Include="instrum.cpp" />
<ClCompile Include="mix.cpp" />
<ClCompile Include="output.cpp" />
<ClCompile Include="playmidi.cpp" />
<ClCompile Include="readmidi.cpp" />
<ClCompile Include="resample.cpp" />
<ClCompile Include="sdl_a.cpp" />
<ClCompile Include="sdl_c.cpp" />
<ClCompile Include="tables.cpp" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,10 @@
""
{
"FILE_VERSION" = "9237"
"ENLISTMENT_CHOICE" = "NEVER"
"PROJECT_FILE_RELATIVE_PATH" = ""
"NUMBER_OF_EXCLUDED_FILES" = "0"
"ORIGINAL_PROJECT_FILE_PATH" = ""
"NUMBER_OF_NESTED_PROJECTS" = "0"
"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER"
}