forked from len0rd/rockbox
Port of Duke Nukem 3D
This ports Fabien Sanglard's Chocolate Duke to run on a version of SDL for Rockbox. Change-Id: I8f2c4c78af19de10c1633ed7bb7a997b43256dd9
This commit is contained in:
parent
01c6dcf6c7
commit
a855d62025
994 changed files with 336924 additions and 15 deletions
127
apps/plugins/sdl/SDL_mixer/timidity/COPYING
Normal file
127
apps/plugins/sdl/SDL_mixer/timidity/COPYING
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
The "Artistic License"
|
||||
|
||||
Preamble
|
||||
|
||||
The intent of this document is to state the conditions under which a
|
||||
Package may be copied, such that the Copyright Holder maintains some
|
||||
semblance of artistic control over the development of the package,
|
||||
while giving the users of the package the right to use and distribute
|
||||
the Package in a more-or-less customary fashion, plus the right to make
|
||||
reasonable modifications.
|
||||
|
||||
Definitions:
|
||||
|
||||
"Package" refers to the collection of files distributed by the
|
||||
Copyright Holder, and derivatives of that collection of files
|
||||
created through textual modification.
|
||||
|
||||
"Standard Version" refers to such a Package if it has not been
|
||||
modified, or has been modified in accordance with the wishes
|
||||
of the Copyright Holder as specified below.
|
||||
|
||||
"Copyright Holder" is whoever is named in the copyright or
|
||||
copyrights for the package.
|
||||
|
||||
"You" is you, if you're thinking about copying or distributing
|
||||
this Package.
|
||||
|
||||
"Reasonable copying fee" is whatever you can justify on the
|
||||
basis of media cost, duplication charges, time of people involved,
|
||||
and so on. (You will not be required to justify it to the
|
||||
Copyright Holder, but only to the computing community at large
|
||||
as a market that must bear the fee.)
|
||||
|
||||
"Freely Available" means that no fee is charged for the item
|
||||
itself, though there may be fees involved in handling the item.
|
||||
It also means that recipients of the item may redistribute it
|
||||
under the same conditions they received it.
|
||||
|
||||
1. You may make and give away verbatim copies of the source form of the
|
||||
Standard Version of this Package without restriction, provided that you
|
||||
duplicate all of the original copyright notices and associated disclaimers.
|
||||
|
||||
2. You may apply bug fixes, portability fixes and other modifications
|
||||
derived from the Public Domain or from the Copyright Holder. A Package
|
||||
modified in such a way shall still be considered the Standard Version.
|
||||
|
||||
3. You may otherwise modify your copy of this Package in any way, provided
|
||||
that you insert a prominent notice in each changed file stating how and
|
||||
when you changed that file, and provided that you do at least ONE of the
|
||||
following:
|
||||
|
||||
a) place your modifications in the Public Domain or otherwise make them
|
||||
Freely Available, such as by posting said modifications to Usenet or
|
||||
an equivalent medium, or placing the modifications on a major archive
|
||||
site such as uunet.uu.net, or by allowing the Copyright Holder to include
|
||||
your modifications in the Standard Version of the Package.
|
||||
|
||||
b) use the modified Package only within your corporation or organization.
|
||||
|
||||
c) rename any non-standard executables so the names do not conflict
|
||||
with standard executables, which must also be provided, and provide
|
||||
a separate manual page for each non-standard executable that clearly
|
||||
documents how it differs from the Standard Version.
|
||||
|
||||
d) make other distribution arrangements with the Copyright Holder.
|
||||
|
||||
4. You may distribute the programs of this Package in object code or
|
||||
executable form, provided that you do at least ONE of the following:
|
||||
|
||||
a) distribute a Standard Version of the executables and library files,
|
||||
together with instructions (in the manual page or equivalent) on where
|
||||
to get the Standard Version.
|
||||
|
||||
b) accompany the distribution with the machine-readable source of
|
||||
the Package with your modifications.
|
||||
|
||||
c) give non-standard executables non-standard names, and clearly
|
||||
document the differences in manual pages (or equivalent), together
|
||||
with instructions on where to get the Standard Version.
|
||||
|
||||
d) make other distribution arrangements with the Copyright Holder.
|
||||
|
||||
5. You may charge a reasonable copying fee for any distribution of this
|
||||
Package. You may charge any fee you choose for support of this
|
||||
Package. You may not charge a fee for this Package itself. However,
|
||||
you may distribute this Package in aggregate with other (possibly
|
||||
commercial) programs as part of a larger (possibly commercial) software
|
||||
distribution provided that you do not advertise this Package as a
|
||||
product of your own. You may embed this Package's interpreter within
|
||||
an executable of yours (by linking); this shall be construed as a mere
|
||||
form of aggregation, provided that the complete Standard Version of the
|
||||
interpreter is so embedded.
|
||||
|
||||
6. The scripts and library files supplied as input to or produced as
|
||||
output from the programs of this Package do not automatically fall
|
||||
under the copyright of this Package, but belong to whoever generated
|
||||
them, and may be sold commercially, and may be aggregated with this
|
||||
Package. If such scripts or library files are aggregated with this
|
||||
Package via the so-called "undump" or "unexec" methods of producing a
|
||||
binary executable image, then distribution of such an image shall
|
||||
neither be construed as a distribution of this Package nor shall it
|
||||
fall under the restrictions of Paragraphs 3 and 4, provided that you do
|
||||
not represent such an executable image as a Standard Version of this
|
||||
Package.
|
||||
|
||||
7. C subroutines (or comparably compiled subroutines in other
|
||||
languages) supplied by you and linked into this Package in order to
|
||||
emulate subroutines and variables of the language defined by this
|
||||
Package shall not be considered part of this Package, but are the
|
||||
equivalent of input as in Paragraph 6, provided these subroutines do
|
||||
not change the language in any way that would cause it to fail the
|
||||
regression tests for the language.
|
||||
|
||||
8. Aggregation of this Package with a commercial distribution is always
|
||||
permitted provided that the use of this Package is embedded; that is,
|
||||
when no overt attempt is made to make this Package's interfaces visible
|
||||
to the end user of the commercial distribution. Such use shall not be
|
||||
construed as a distribution of this Package.
|
||||
|
||||
9. The name of the Copyright Holder may not be used to endorse or promote
|
||||
products derived from this software without specific prior written permission.
|
||||
|
||||
10. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
The End
|
||||
112
apps/plugins/sdl/SDL_mixer/timidity/FAQ
Normal file
112
apps/plugins/sdl/SDL_mixer/timidity/FAQ
Normal 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.
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
57
apps/plugins/sdl/SDL_mixer/timidity/README
Normal file
57
apps/plugins/sdl/SDL_mixer/timidity/README
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
[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
|
||||
|
||||
* 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.]
|
||||
238
apps/plugins/sdl/SDL_mixer/timidity/common.c
Normal file
238
apps/plugins/sdl/SDL_mixer/timidity/common.c
Normal file
|
|
@ -0,0 +1,238 @@
|
|||
/*
|
||||
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 Perl Artistic License, available in COPYING.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "common.h"
|
||||
#include "output.h"
|
||||
#include "ctrlmode.h"
|
||||
|
||||
/* I guess "rb" should be right for any libc */
|
||||
#define OPEN_MODE "rb"
|
||||
|
||||
char current_filename[PATH_MAX];
|
||||
|
||||
static PathList *pathlist=NULL;
|
||||
|
||||
/* 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 FILE *try_to_open(const char *name, int decompress, int noise_mode)
|
||||
{
|
||||
FILE *fp;
|
||||
|
||||
fp=fopen(name, OPEN_MODE); /* First just check that the file exists */
|
||||
|
||||
if (!fp)
|
||||
return 0;
|
||||
|
||||
#ifdef DECOMPRESSOR_LIST
|
||||
if (decompress)
|
||||
{
|
||||
int l,el;
|
||||
static char *decompressor_list[] = DECOMPRESSOR_LIST, **dec;
|
||||
const char *cp;
|
||||
char tmp[PATH_MAX], tmp2[PATH_MAX], *cp2;
|
||||
/* Check if it's a compressed file */
|
||||
l=strlen(name);
|
||||
for (dec=decompressor_list; *dec; dec+=2)
|
||||
{
|
||||
el=strlen(*dec);
|
||||
if ((el>=l) || (strcmp(name+l-el, *dec)))
|
||||
continue;
|
||||
|
||||
/* Yes. Close the file, open a pipe instead. */
|
||||
fclose(fp);
|
||||
|
||||
/* Quote some special characters in the file name */
|
||||
cp=name;
|
||||
cp2=tmp2;
|
||||
while (*cp)
|
||||
{
|
||||
switch(*cp)
|
||||
{
|
||||
case '\'':
|
||||
case '\\':
|
||||
case ' ':
|
||||
case '`':
|
||||
case '!':
|
||||
case '"':
|
||||
case '&':
|
||||
case ';':
|
||||
*cp2++='\\';
|
||||
}
|
||||
*cp2++=*cp++;
|
||||
}
|
||||
*cp2=0;
|
||||
|
||||
sprintf(tmp, *(dec+1), tmp2);
|
||||
fp=popen(tmp, "r");
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return fp;
|
||||
}
|
||||
|
||||
/* This is meant to find and open files for reading, possibly piping
|
||||
them through a decompressor. */
|
||||
FILE *open_file(const char *name, int decompress, int noise_mode)
|
||||
{
|
||||
FILE *fp;
|
||||
PathList *plp;
|
||||
int l;
|
||||
|
||||
if (!name || !(*name))
|
||||
{
|
||||
ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Attempted to open nameless file.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (pathlist==NULL) {
|
||||
/* Generate path list */
|
||||
#ifdef DEFAULT_PATH
|
||||
add_to_pathlist(DEFAULT_PATH);
|
||||
#endif
|
||||
#ifdef DEFAULT_PATH1
|
||||
add_to_pathlist(DEFAULT_PATH1);
|
||||
#endif
|
||||
#ifdef DEFAULT_PATH2
|
||||
add_to_pathlist(DEFAULT_PATH2);
|
||||
#endif
|
||||
#ifdef DEFAULT_PATH3
|
||||
add_to_pathlist(DEFAULT_PATH3);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* First try the given name */
|
||||
|
||||
strncpy(current_filename, name, PATH_MAX - 1);
|
||||
current_filename[PATH_MAX - 1]='\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;
|
||||
|
||||
#ifdef ENOENT
|
||||
if (noise_mode && (errno != ENOENT))
|
||||
{
|
||||
ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: %s",
|
||||
current_filename, strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
plp=pathlist;
|
||||
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;
|
||||
#ifdef ENOENT
|
||||
if (noise_mode && (errno != ENOENT))
|
||||
{
|
||||
ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: %s",
|
||||
current_filename, strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
plp=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(FILE *fp)
|
||||
{
|
||||
#ifdef DECOMPRESSOR_LIST
|
||||
if (pclose(fp)) /* Any better ideas? */
|
||||
#endif
|
||||
fclose(fp);
|
||||
|
||||
strncpy(current_filename, "MIDI file", PATH_MAX - 1);
|
||||
}
|
||||
|
||||
/* This is meant for skipping a few bytes in a file or fifo. */
|
||||
void skip(FILE *fp, size_t len)
|
||||
{
|
||||
size_t c;
|
||||
char tmp[PATH_MAX];
|
||||
while (len>0)
|
||||
{
|
||||
c=len;
|
||||
if (c>PATH_MAX) c=PATH_MAX;
|
||||
len-=c;
|
||||
if (c!=fread(tmp, 1, c, fp))
|
||||
ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: skip: %s",
|
||||
current_filename, strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
/* 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=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(const char *s)
|
||||
{
|
||||
PathList *plp=safe_malloc(sizeof(PathList));
|
||||
strcpy((plp->path=safe_malloc(strlen(s)+1)),s);
|
||||
plp->next=pathlist;
|
||||
pathlist=plp;
|
||||
}
|
||||
|
||||
/* Free memory associated to path list */
|
||||
void free_pathlist(void)
|
||||
{
|
||||
PathList *plp, *next_plp;
|
||||
|
||||
plp = pathlist;
|
||||
while (plp) {
|
||||
if (plp->path) {
|
||||
free(plp->path);
|
||||
plp->path=NULL;
|
||||
}
|
||||
next_plp = plp->next;
|
||||
free(plp);
|
||||
plp = next_plp;
|
||||
}
|
||||
pathlist = NULL;
|
||||
}
|
||||
39
apps/plugins/sdl/SDL_mixer/timidity/common.h
Normal file
39
apps/plugins/sdl/SDL_mixer/timidity/common.h
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
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 Perl Artistic License, available in COPYING.
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#ifndef PATH_MAX /* GNU Hurd doesn't limit path size, thus no PATH_MAX... */
|
||||
#define PATH_MAX 1024 /* ...so we'll just impose an arbitrary limit. */
|
||||
#endif
|
||||
|
||||
extern char *program_name, current_filename[];
|
||||
|
||||
extern FILE *msgfp;
|
||||
|
||||
extern int num_ochannels;
|
||||
|
||||
#define MULTICHANNEL_OUT
|
||||
#define MAX_OUT_CHANNELS 6
|
||||
|
||||
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 FILE *open_file(const char *name, int decompress, int noise_mode);
|
||||
extern void add_to_pathlist(const char *s);
|
||||
extern void free_pathlist(void);
|
||||
extern void close_file(FILE *fp);
|
||||
extern void skip(FILE *fp, size_t len);
|
||||
extern void *safe_malloc(size_t count);
|
||||
229
apps/plugins/sdl/SDL_mixer/timidity/config.h
Normal file
229
apps/plugins/sdl/SDL_mixer/timidity/config.h
Normal file
|
|
@ -0,0 +1,229 @@
|
|||
/*
|
||||
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 Perl Artistic License, available in COPYING.
|
||||
*/
|
||||
|
||||
/* This is for use with the SDL library */
|
||||
#ifndef __TIMIDITY_CONFIG_H__
|
||||
#define __TIMIDITY_CONFIG_H__
|
||||
#define SDL
|
||||
#include "SDL_config.h"
|
||||
#include "SDL_endian.h"
|
||||
|
||||
#define TIMIDITY_ERROR_SIZE 1024
|
||||
|
||||
/* 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)
|
||||
|
||||
/* 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 */
|
||||
/* #define DEFAULT_AMPLIFICATION 50 */
|
||||
#define DEFAULT_AMPLIFICATION 30
|
||||
|
||||
/* 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 */
|
||||
#define DEFAULT_VOICES 256
|
||||
#define MAX_VOICES 256
|
||||
#define MAXCHAN 16
|
||||
/* #define MAXCHAN 64 */
|
||||
#define MAXNOTE 128
|
||||
|
||||
/* 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
|
||||
|
||||
#define MAX_SAMPLE_SIZE (1 << (32-FRACTION_BITS))
|
||||
|
||||
typedef double FLOAT_T;
|
||||
|
||||
/* 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
|
||||
|
||||
typedef unsigned int uint32;
|
||||
typedef int int32;
|
||||
typedef unsigned short uint16;
|
||||
typedef short int16;
|
||||
typedef unsigned char uint8;
|
||||
typedef char int8;
|
||||
|
||||
/* 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))
|
||||
|
||||
#if SDL_BYTEORDER == SDL_LIL_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
|
||||
|
||||
/* You could specify a complete path, e.g. "/etc/timidity.cfg", and
|
||||
then specify the library directory in the configuration file. */
|
||||
#define CONFIG_FILE "/.rockbox/timidity/timidity.cfg"
|
||||
#define CONFIG_FILE_ETC "/.rockbox/timidity/timidity.cfg"
|
||||
|
||||
#if defined(__WIN32__) || defined(__OS2__)
|
||||
#define DEFAULT_PATH "C:\\TIMIDITY"
|
||||
#else
|
||||
#define DEFAULT_PATH "/.rockbox/patchset"
|
||||
#define DEFAULT_PATH1 "/.rockbox/duke3d"
|
||||
#define DEFAULT_PATH2 "/.rockbox/timidity"
|
||||
#define DEFAULT_PATH3 "/.rockbox/midi"
|
||||
#endif
|
||||
|
||||
/* These affect general volume */
|
||||
#define GUARD_BITS 3
|
||||
#define AMP_BITS (15-GUARD_BITS)
|
||||
|
||||
#ifdef LOOKUP_HACK
|
||||
typedef int8 sample_t;
|
||||
typedef uint8 final_volume_t;
|
||||
# define FINAL_VOLUME(v) (~_l2u[v])
|
||||
# define MIXUP_SHIFT 5
|
||||
# define MAX_AMP_VALUE 4095
|
||||
#else
|
||||
typedef int16 sample_t;
|
||||
typedef int32 final_volume_t;
|
||||
# define FINAL_VOLUME(v) (v)
|
||||
# define MAX_AMP_VALUE ((1<<(AMP_BITS+1))-1)
|
||||
#endif
|
||||
|
||||
typedef int16 resample_t;
|
||||
|
||||
#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
|
||||
#define PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
/* The path separator (D.M.) */
|
||||
#if defined(__WIN32__) || defined(__OS2__)
|
||||
# define PATH_SEP '\\'
|
||||
# define PATH_STRING "\\"
|
||||
#else
|
||||
# define PATH_SEP '/'
|
||||
# define PATH_STRING "/"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
26
apps/plugins/sdl/SDL_mixer/timidity/ctrlmode.c
Normal file
26
apps/plugins/sdl/SDL_mixer/timidity/ctrlmode.c
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
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 Perl Artistic License, available in COPYING.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "ctrlmode.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;
|
||||
74
apps/plugins/sdl/SDL_mixer/timidity/ctrlmode.h
Normal file
74
apps/plugins/sdl/SDL_mixer/timidity/ctrlmode.h
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
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 Perl Artistic License, available in COPYING.
|
||||
*/
|
||||
|
||||
/* Return values for ControlMode.read */
|
||||
|
||||
#define RC_ERROR -1
|
||||
#define RC_NONE 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)(int32 *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;
|
||||
extern char timidity_error[];
|
||||
187
apps/plugins/sdl/SDL_mixer/timidity/filter.c
Normal file
187
apps/plugins/sdl/SDL_mixer/timidity/filter.c
Normal file
|
|
@ -0,0 +1,187 @@
|
|||
/*
|
||||
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 Perl Artistic License, available in COPYING.
|
||||
|
||||
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 "config.h"
|
||||
#include "common.h"
|
||||
#include "ctrlmode.h"
|
||||
#include "instrum.h"
|
||||
#include "filter.h"
|
||||
|
||||
/* 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 length,float coef[])
|
||||
{
|
||||
int32 sample,i,sample_window;
|
||||
int16 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 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 = safe_malloc(sp->data_length);
|
||||
memcpy(temp,sp->data,sp->data_length);
|
||||
|
||||
filter(sp->data,temp,sp->data_length/sizeof(sample_t),fir_symetric);
|
||||
|
||||
free(temp);
|
||||
}
|
||||
23
apps/plugins/sdl/SDL_mixer/timidity/filter.h
Normal file
23
apps/plugins/sdl/SDL_mixer/timidity/filter.h
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
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 Perl Artistic License, available in COPYING.
|
||||
|
||||
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
|
||||
#define PI 3.14159265
|
||||
#endif
|
||||
|
||||
extern void antialiasing(Sample *sp, int32 output_rate);
|
||||
1018
apps/plugins/sdl/SDL_mixer/timidity/instrum.c
Normal file
1018
apps/plugins/sdl/SDL_mixer/timidity/instrum.c
Normal file
File diff suppressed because it is too large
Load diff
168
apps/plugins/sdl/SDL_mixer/timidity/instrum.h
Normal file
168
apps/plugins/sdl/SDL_mixer/timidity/instrum.h
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
/*
|
||||
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 Perl Artistic License, available in COPYING.
|
||||
*/
|
||||
|
||||
|
||||
typedef struct {
|
||||
int32
|
||||
loop_start, loop_end, data_length,
|
||||
sample_rate, low_freq, high_freq, root_freq;
|
||||
uint8
|
||||
root_tune, fine_tune;
|
||||
int32
|
||||
envelope_rate[7], envelope_offset[7],
|
||||
modulation_rate[7], modulation_offset[7];
|
||||
FLOAT_T
|
||||
volume, resonance,
|
||||
modEnvToFilterFc, modEnvToPitch, modLfoToFilterFc;
|
||||
sample_t *data;
|
||||
int32
|
||||
tremolo_sweep_increment, tremolo_phase_increment,
|
||||
lfo_sweep_increment, lfo_phase_increment,
|
||||
vibrato_sweep_increment, vibrato_control_ratio,
|
||||
cutoff_freq;
|
||||
uint8
|
||||
reverberation, chorusdepth,
|
||||
tremolo_depth, vibrato_depth,
|
||||
modes;
|
||||
uint8
|
||||
attenuation, freq_center;
|
||||
int8
|
||||
panning, note_to_use, exclusiveClass;
|
||||
int16
|
||||
scale_tuning, keyToModEnvHold, keyToModEnvDecay,
|
||||
keyToVolEnvHold, keyToVolEnvDecay;
|
||||
int32
|
||||
freq_scale, vibrato_delay;
|
||||
} 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)
|
||||
#define MODES_FAST_RELEASE (1<<7)
|
||||
|
||||
#if 0
|
||||
typedef struct {
|
||||
int samples;
|
||||
Sample *sample;
|
||||
} Instrument;
|
||||
#endif
|
||||
|
||||
#define INST_GUS 0
|
||||
#define INST_SF2 1
|
||||
|
||||
typedef struct {
|
||||
int type;
|
||||
int samples;
|
||||
Sample *sample;
|
||||
int left_samples;
|
||||
Sample *left_sample;
|
||||
int right_samples;
|
||||
Sample *right_sample;
|
||||
unsigned char *contents;
|
||||
} Instrument;
|
||||
|
||||
|
||||
typedef struct _InstrumentLayer {
|
||||
uint8 lo, hi;
|
||||
int size;
|
||||
Instrument *instrument;
|
||||
struct _InstrumentLayer *next;
|
||||
} InstrumentLayer;
|
||||
|
||||
struct cfg_type {
|
||||
int font_code;
|
||||
int num;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
#define FONT_NORMAL 0
|
||||
#define FONT_FFF 1
|
||||
#define FONT_SBK 2
|
||||
#define FONT_TONESET 3
|
||||
#define FONT_DRUMSET 4
|
||||
#define FONT_PRESET 5
|
||||
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
InstrumentLayer *layer;
|
||||
int font_type, sf_ix, last_used, tuning;
|
||||
int note, amp, pan, strip_loop, strip_envelope, strip_tail;
|
||||
} ToneBankElement;
|
||||
|
||||
#if 0
|
||||
typedef struct {
|
||||
char *name;
|
||||
Instrument *instrument;
|
||||
int note, amp, pan, strip_loop, strip_envelope, strip_tail;
|
||||
} ToneBankElement;
|
||||
#endif
|
||||
/* A hack to delay instrument loading until after reading the
|
||||
entire MIDI file. */
|
||||
#define MAGIC_LOAD_INSTRUMENT ((InstrumentLayer *)(-1))
|
||||
|
||||
#define MAXPROG 128
|
||||
#define MAXBANK 130
|
||||
#define SFXBANK (MAXBANK-1)
|
||||
#define SFXDRUM1 (MAXBANK-2)
|
||||
#define SFXDRUM2 (MAXBANK-1)
|
||||
#define XGDRUM 1
|
||||
|
||||
#if 0
|
||||
typedef struct {
|
||||
ToneBankElement tone[128];
|
||||
} ToneBank;
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
ToneBankElement tone[MAXPROG];
|
||||
} ToneBank;
|
||||
|
||||
|
||||
extern char *sf_file;
|
||||
|
||||
extern ToneBank *tonebank[], *drumset[];
|
||||
|
||||
#if 0
|
||||
extern Instrument *default_instrument;
|
||||
#endif
|
||||
extern InstrumentLayer *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 void end_soundfont(void);
|
||||
extern int set_default_instrument(const char *name);
|
||||
|
||||
|
||||
extern int32 convert_tremolo_sweep(uint8 sweep);
|
||||
extern int32 convert_vibrato_sweep(uint8 sweep, int32 vib_control_ratio);
|
||||
extern int32 convert_tremolo_rate(uint8 rate);
|
||||
extern int32 convert_vibrato_rate(uint8 rate);
|
||||
|
||||
extern int init_soundfont(char *fname, int oldbank, int newbank, int level);
|
||||
extern InstrumentLayer *load_sbk_patch(const char *name, int gm_num, int bank, int percussion,
|
||||
int panning, int amp, int note_to_use, int sf_ix);
|
||||
extern int current_tune_number;
|
||||
extern int max_patch_memory;
|
||||
extern int current_patch_memory;
|
||||
#define XMAPMAX 800
|
||||
extern int xmap[XMAPMAX][5];
|
||||
extern void pcmap(int *b, int *v, int *p, int *drums);
|
||||
|
||||
847
apps/plugins/sdl/SDL_mixer/timidity/mix.c
Normal file
847
apps/plugins/sdl/SDL_mixer/timidity/mix.c
Normal file
|
|
@ -0,0 +1,847 @@
|
|||
/*
|
||||
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 Perl Artistic License, available in COPYING.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "common.h"
|
||||
#include "instrum.h"
|
||||
#include "playmidi.h"
|
||||
#include "output.h"
|
||||
#include "ctrlmode.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_T lamp=voice[v].left_amp, ramp, lramp, rramp, ceamp, lfeamp;
|
||||
int32 la,ra, lra, rra, cea, lfea;
|
||||
if (voice[v].panned == PANNED_MYSTERY)
|
||||
{
|
||||
lramp=voice[v].lr_amp;
|
||||
ramp=voice[v].right_amp;
|
||||
ceamp=voice[v].ce_amp;
|
||||
rramp=voice[v].rr_amp;
|
||||
lfeamp=voice[v].lfe_amp;
|
||||
|
||||
if (voice[v].tremolo_phase_increment)
|
||||
{
|
||||
FLOAT_T tv = voice[v].tremolo_volume;
|
||||
lramp *= tv;
|
||||
lamp *= tv;
|
||||
ceamp *= tv;
|
||||
ramp *= tv;
|
||||
rramp *= tv;
|
||||
lfeamp *= tv;
|
||||
}
|
||||
if (voice[v].sample->modes & MODES_ENVELOPE)
|
||||
{
|
||||
FLOAT_T ev = (FLOAT_T)vol_table[voice[v].envelope_volume>>23];
|
||||
lramp *= ev;
|
||||
lamp *= ev;
|
||||
ceamp *= ev;
|
||||
ramp *= ev;
|
||||
rramp *= ev;
|
||||
lfeamp *= ev;
|
||||
}
|
||||
|
||||
la = (int32)FSCALE(lamp,AMP_BITS);
|
||||
ra = (int32)FSCALE(ramp,AMP_BITS);
|
||||
lra = (int32)FSCALE(lramp,AMP_BITS);
|
||||
rra = (int32)FSCALE(rramp,AMP_BITS);
|
||||
cea = (int32)FSCALE(ceamp,AMP_BITS);
|
||||
lfea = (int32)FSCALE(lfeamp,AMP_BITS);
|
||||
|
||||
if (la>MAX_AMP_VALUE) la=MAX_AMP_VALUE;
|
||||
if (ra>MAX_AMP_VALUE) ra=MAX_AMP_VALUE;
|
||||
if (lra>MAX_AMP_VALUE) lra=MAX_AMP_VALUE;
|
||||
if (rra>MAX_AMP_VALUE) rra=MAX_AMP_VALUE;
|
||||
if (cea>MAX_AMP_VALUE) cea=MAX_AMP_VALUE;
|
||||
if (lfea>MAX_AMP_VALUE) lfea=MAX_AMP_VALUE;
|
||||
|
||||
voice[v].lr_mix=FINAL_VOLUME(lra);
|
||||
voice[v].left_mix=FINAL_VOLUME(la);
|
||||
voice[v].ce_mix=FINAL_VOLUME(cea);
|
||||
voice[v].right_mix=FINAL_VOLUME(ra);
|
||||
voice[v].rr_mix=FINAL_VOLUME(rra);
|
||||
voice[v].lfe_mix=FINAL_VOLUME(lfea);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (voice[v].tremolo_phase_increment)
|
||||
lamp *= voice[v].tremolo_volume;
|
||||
if (voice[v].sample->modes & MODES_ENVELOPE)
|
||||
lamp *= (FLOAT_T)vol_table[voice[v].envelope_volume>>23];
|
||||
|
||||
la = (int32)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 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_T)
|
||||
(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
|
||||
|
||||
#define MIXSKIP lp++
|
||||
#define MIXMAX(a,b) *lp++ += ((a>b)?a:b) * s
|
||||
#define MIXCENT(a,b) *lp++ += (a/2+b/2) * s
|
||||
#define MIXHALF(a) *lp++ += (a>>1)*s;
|
||||
|
||||
static void mix_mystery_signal(resample_t *sp, int32 *lp, int v, int count)
|
||||
{
|
||||
Voice *vp = voice + v;
|
||||
final_volume_t
|
||||
left_rear=vp->lr_mix,
|
||||
left=vp->left_mix,
|
||||
center=vp->ce_mix,
|
||||
right=vp->right_mix,
|
||||
right_rear=vp->rr_mix,
|
||||
lfe=vp->lfe_mix;
|
||||
int cc;
|
||||
resample_t s;
|
||||
|
||||
if (!(cc = vp->control_counter))
|
||||
{
|
||||
cc = control_ratio;
|
||||
if (update_signal(v))
|
||||
return; /* Envelope ran out */
|
||||
|
||||
left_rear = vp->lr_mix;
|
||||
left = vp->left_mix;
|
||||
center = vp->ce_mix;
|
||||
right = vp->right_mix;
|
||||
right_rear = vp->rr_mix;
|
||||
lfe = vp->lfe_mix;
|
||||
}
|
||||
|
||||
while (count)
|
||||
if (cc < count)
|
||||
{
|
||||
count -= cc;
|
||||
while (cc--)
|
||||
{
|
||||
s = *sp++;
|
||||
MIXATION(left);
|
||||
MIXATION(right);
|
||||
if (num_ochannels >= 4) {
|
||||
MIXATION(left_rear);
|
||||
MIXATION(right_rear);
|
||||
}
|
||||
if (num_ochannels == 6) {
|
||||
MIXATION(center);
|
||||
MIXATION(lfe);
|
||||
}
|
||||
}
|
||||
cc = control_ratio;
|
||||
if (update_signal(v))
|
||||
return; /* Envelope ran out */
|
||||
left_rear = vp->lr_mix;
|
||||
left = vp->left_mix;
|
||||
center = vp->ce_mix;
|
||||
right = vp->right_mix;
|
||||
right_rear = vp->rr_mix;
|
||||
lfe = vp->lfe_mix;
|
||||
}
|
||||
else
|
||||
{
|
||||
vp->control_counter = cc - count;
|
||||
while (count--)
|
||||
{
|
||||
s = *sp++;
|
||||
MIXATION(left);
|
||||
MIXATION(right);
|
||||
if (num_ochannels >= 4) {
|
||||
MIXATION(left_rear);
|
||||
MIXATION(right_rear);
|
||||
}
|
||||
if (num_ochannels == 6) {
|
||||
MIXATION(center);
|
||||
MIXATION(lfe);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void mix_center_signal(resample_t *sp, int32 *lp, int v, int count)
|
||||
{
|
||||
Voice *vp = voice + v;
|
||||
final_volume_t
|
||||
left=vp->left_mix;
|
||||
int cc;
|
||||
resample_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++;
|
||||
if (num_ochannels == 2) {
|
||||
MIXATION(left);
|
||||
MIXATION(left);
|
||||
}
|
||||
else if (num_ochannels == 4) {
|
||||
MIXATION(left);
|
||||
MIXSKIP;
|
||||
MIXATION(left);
|
||||
MIXSKIP;
|
||||
}
|
||||
else if (num_ochannels == 6) {
|
||||
MIXSKIP;
|
||||
MIXSKIP;
|
||||
MIXSKIP;
|
||||
MIXSKIP;
|
||||
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++;
|
||||
if (num_ochannels == 2) {
|
||||
MIXATION(left);
|
||||
MIXATION(left);
|
||||
}
|
||||
else if (num_ochannels == 4) {
|
||||
MIXATION(left);
|
||||
MIXSKIP;
|
||||
MIXATION(left);
|
||||
MIXSKIP;
|
||||
}
|
||||
else if (num_ochannels == 6) {
|
||||
MIXSKIP;
|
||||
MIXSKIP;
|
||||
MIXSKIP;
|
||||
MIXSKIP;
|
||||
MIXATION(left);
|
||||
MIXATION(left);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void mix_single_left_signal(resample_t *sp, int32 *lp, int v, int count)
|
||||
{
|
||||
Voice *vp = voice + v;
|
||||
final_volume_t
|
||||
left=vp->left_mix;
|
||||
int cc;
|
||||
resample_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++;
|
||||
if (num_ochannels == 2) {
|
||||
MIXATION(left);
|
||||
MIXSKIP;
|
||||
}
|
||||
if (num_ochannels >= 4) {
|
||||
MIXHALF(left);
|
||||
MIXSKIP;
|
||||
MIXATION(left);
|
||||
MIXSKIP;
|
||||
}
|
||||
if (num_ochannels == 6) {
|
||||
MIXSKIP;
|
||||
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++;
|
||||
if (num_ochannels == 2) {
|
||||
MIXATION(left);
|
||||
MIXSKIP;
|
||||
}
|
||||
if (num_ochannels >= 4) {
|
||||
MIXHALF(left);
|
||||
MIXSKIP;
|
||||
MIXATION(left);
|
||||
MIXSKIP;
|
||||
}
|
||||
if (num_ochannels == 6) {
|
||||
MIXSKIP;
|
||||
MIXATION(left);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void mix_single_right_signal(resample_t *sp, int32 *lp, int v, int count)
|
||||
{
|
||||
Voice *vp = voice + v;
|
||||
final_volume_t
|
||||
left=vp->left_mix;
|
||||
int cc;
|
||||
resample_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++;
|
||||
if (num_ochannels == 2) {
|
||||
MIXSKIP;
|
||||
MIXATION(left);
|
||||
}
|
||||
if (num_ochannels >= 4) {
|
||||
MIXSKIP;
|
||||
MIXHALF(left);
|
||||
MIXSKIP;
|
||||
MIXATION(left);
|
||||
} if (num_ochannels == 6) {
|
||||
MIXSKIP;
|
||||
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++;
|
||||
if (num_ochannels == 2) {
|
||||
MIXSKIP;
|
||||
MIXATION(left);
|
||||
}
|
||||
if (num_ochannels >= 4) {
|
||||
MIXSKIP;
|
||||
MIXHALF(left);
|
||||
MIXSKIP;
|
||||
MIXATION(left);
|
||||
} if (num_ochannels == 6) {
|
||||
MIXSKIP;
|
||||
MIXATION(left);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void mix_mono_signal(resample_t *sp, int32 *lp, int v, int count)
|
||||
{
|
||||
Voice *vp = voice + v;
|
||||
final_volume_t
|
||||
left=vp->left_mix;
|
||||
int cc;
|
||||
resample_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(resample_t *sp, int32 *lp, int v, int count)
|
||||
{
|
||||
final_volume_t
|
||||
left_rear=voice[v].lr_mix,
|
||||
left=voice[v].left_mix,
|
||||
center=voice[v].ce_mix,
|
||||
right=voice[v].right_mix,
|
||||
right_rear=voice[v].rr_mix,
|
||||
lfe=voice[v].lfe_mix;
|
||||
resample_t s;
|
||||
|
||||
while (count--)
|
||||
{
|
||||
s = *sp++;
|
||||
MIXATION(left);
|
||||
MIXATION(right);
|
||||
if (num_ochannels >= 4) {
|
||||
MIXATION(left_rear);
|
||||
MIXATION(right_rear);
|
||||
}
|
||||
if (num_ochannels == 6) {
|
||||
MIXATION(center);
|
||||
MIXATION(lfe);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void mix_center(resample_t *sp, int32 *lp, int v, int count)
|
||||
{
|
||||
final_volume_t
|
||||
left=voice[v].left_mix;
|
||||
resample_t s;
|
||||
|
||||
while (count--)
|
||||
{
|
||||
s = *sp++;
|
||||
if (num_ochannels == 2) {
|
||||
MIXATION(left);
|
||||
MIXATION(left);
|
||||
}
|
||||
else if (num_ochannels == 4) {
|
||||
MIXATION(left);
|
||||
MIXATION(left);
|
||||
MIXSKIP;
|
||||
MIXSKIP;
|
||||
}
|
||||
else if (num_ochannels == 6) {
|
||||
MIXSKIP;
|
||||
MIXSKIP;
|
||||
MIXSKIP;
|
||||
MIXSKIP;
|
||||
MIXATION(left);
|
||||
MIXATION(left);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void mix_single_left(resample_t *sp, int32 *lp, int v, int count)
|
||||
{
|
||||
final_volume_t
|
||||
left=voice[v].left_mix;
|
||||
resample_t s;
|
||||
|
||||
while (count--)
|
||||
{
|
||||
s = *sp++;
|
||||
if (num_ochannels == 2) {
|
||||
MIXATION(left);
|
||||
MIXSKIP;
|
||||
}
|
||||
if (num_ochannels >= 4) {
|
||||
MIXHALF(left);
|
||||
MIXSKIP;
|
||||
MIXATION(left);
|
||||
MIXSKIP;
|
||||
}
|
||||
if (num_ochannels == 6) {
|
||||
MIXSKIP;
|
||||
MIXATION(left);
|
||||
}
|
||||
}
|
||||
}
|
||||
static void mix_single_right(resample_t *sp, int32 *lp, int v, int count)
|
||||
{
|
||||
final_volume_t
|
||||
left=voice[v].left_mix;
|
||||
resample_t s;
|
||||
|
||||
while (count--)
|
||||
{
|
||||
s = *sp++;
|
||||
if (num_ochannels == 2) {
|
||||
MIXSKIP;
|
||||
MIXATION(left);
|
||||
}
|
||||
if (num_ochannels >= 4) {
|
||||
MIXSKIP;
|
||||
MIXHALF(left);
|
||||
MIXSKIP;
|
||||
MIXATION(left);
|
||||
}
|
||||
if (num_ochannels == 6) {
|
||||
MIXSKIP;
|
||||
MIXATION(left);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void mix_mono(resample_t *sp, int32 *lp, int v, int count)
|
||||
{
|
||||
final_volume_t
|
||||
left=voice[v].left_mix;
|
||||
resample_t s;
|
||||
|
||||
while (count--)
|
||||
{
|
||||
s = *sp++;
|
||||
MIXATION(left);
|
||||
}
|
||||
}
|
||||
|
||||
/* Ramp a note out in c samples */
|
||||
static void ramp_out(resample_t *sp, int32 *lp, int v, int32 c)
|
||||
{
|
||||
|
||||
/* should be final_volume_t, but uint8 gives trouble. */
|
||||
int32 left_rear, left, center, right, right_rear, lfe, li, ri;
|
||||
|
||||
resample_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;
|
||||
|
||||
/* 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)
|
||||
{
|
||||
left_rear = voice[v].lr_mix;
|
||||
center=voice[v].ce_mix;
|
||||
right=voice[v].right_mix;
|
||||
right_rear = voice[v].rr_mix;
|
||||
lfe = voice[v].lfe_mix;
|
||||
|
||||
ri=-(right/c);
|
||||
while (c--)
|
||||
{
|
||||
left_rear += li; if (left_rear<0) left_rear=0;
|
||||
left += li; if (left<0) left=0;
|
||||
center += li; if (center<0) center=0;
|
||||
right += ri; if (right<0) right=0;
|
||||
right_rear += ri; if (right_rear<0) right_rear=0;
|
||||
lfe += li; if (lfe<0) lfe=0;
|
||||
s=*sp++;
|
||||
MIXATION(left);
|
||||
MIXATION(right);
|
||||
if (num_ochannels >= 4) {
|
||||
MIXATION(left_rear);
|
||||
MIXATION(right_rear);
|
||||
}
|
||||
if (num_ochannels == 6) {
|
||||
MIXATION(center);
|
||||
MIXATION(lfe);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (voice[v].panned==PANNED_CENTER)
|
||||
{
|
||||
while (c--)
|
||||
{
|
||||
left += li;
|
||||
if (left<0)
|
||||
return;
|
||||
s=*sp++;
|
||||
if (num_ochannels == 2) {
|
||||
MIXATION(left);
|
||||
MIXATION(left);
|
||||
}
|
||||
else if (num_ochannels == 4) {
|
||||
MIXATION(left);
|
||||
MIXATION(left);
|
||||
MIXSKIP;
|
||||
MIXSKIP;
|
||||
}
|
||||
else if (num_ochannels == 6) {
|
||||
MIXSKIP;
|
||||
MIXSKIP;
|
||||
MIXSKIP;
|
||||
MIXSKIP;
|
||||
MIXATION(left);
|
||||
MIXATION(left);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (voice[v].panned==PANNED_LEFT)
|
||||
{
|
||||
while (c--)
|
||||
{
|
||||
left += li;
|
||||
if (left<0)
|
||||
return;
|
||||
s=*sp++;
|
||||
MIXATION(left);
|
||||
MIXSKIP;
|
||||
if (num_ochannels >= 4) {
|
||||
MIXATION(left);
|
||||
MIXSKIP;
|
||||
} if (num_ochannels == 6) {
|
||||
MIXATION(left);
|
||||
MIXATION(left);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (voice[v].panned==PANNED_RIGHT)
|
||||
{
|
||||
while (c--)
|
||||
{
|
||||
left += li;
|
||||
if (left<0)
|
||||
return;
|
||||
s=*sp++;
|
||||
MIXSKIP;
|
||||
MIXATION(left);
|
||||
if (num_ochannels >= 4) {
|
||||
MIXSKIP;
|
||||
MIXATION(left);
|
||||
} if (num_ochannels == 6) {
|
||||
MIXATION(left);
|
||||
MIXATION(left);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Mono output. */
|
||||
while (c--)
|
||||
{
|
||||
left += li;
|
||||
if (left<0)
|
||||
return;
|
||||
s=*sp++;
|
||||
MIXATION(left);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**************** interface function ******************/
|
||||
|
||||
void mix_voice(int32 *buf, int v, int32 c)
|
||||
{
|
||||
Voice *vp=voice+v;
|
||||
int32 count=c;
|
||||
resample_t *sp;
|
||||
if (c<0) return;
|
||||
if (vp->status==VOICE_DIE)
|
||||
{
|
||||
if (count>=MAX_DIE_TIME)
|
||||
count=MAX_DIE_TIME;
|
||||
sp=resample_voice(v, &count);
|
||||
ramp_out(sp, buf, v, count);
|
||||
vp->status=VOICE_FREE;
|
||||
}
|
||||
else
|
||||
{
|
||||
sp=resample_voice(v, &count);
|
||||
if (count<0) return;
|
||||
if (play_mode->encoding & PE_MONO)
|
||||
{
|
||||
/* Mono output. */
|
||||
if (vp->envelope_increment || vp->tremolo_phase_increment)
|
||||
mix_mono_signal(sp, buf, v, count);
|
||||
else
|
||||
mix_mono(sp, buf, v, count);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (vp->panned == PANNED_MYSTERY)
|
||||
{
|
||||
if (vp->envelope_increment || vp->tremolo_phase_increment)
|
||||
mix_mystery_signal(sp, buf, v, count);
|
||||
else
|
||||
mix_mystery(sp, buf, v, count);
|
||||
}
|
||||
else if (vp->panned == PANNED_CENTER)
|
||||
{
|
||||
if (vp->envelope_increment || vp->tremolo_phase_increment)
|
||||
mix_center_signal(sp, buf, v, count);
|
||||
else
|
||||
mix_center(sp, buf, v, count);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* It's either full left or full right. In either case,
|
||||
every other sample is 0. Just get the offset right: */
|
||||
|
||||
if (vp->envelope_increment || vp->tremolo_phase_increment)
|
||||
{
|
||||
if (vp->panned == PANNED_RIGHT)
|
||||
mix_single_right_signal(sp, buf, v, count);
|
||||
else mix_single_left_signal(sp, buf, v, count);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (vp->panned == PANNED_RIGHT)
|
||||
mix_single_right(sp, buf, v, count);
|
||||
else mix_single_left(sp, buf, v, count);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
apps/plugins/sdl/SDL_mixer/timidity/mix.h
Normal file
11
apps/plugins/sdl/SDL_mixer/timidity/mix.h
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
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 Perl Artistic License, available in COPYING.
|
||||
*/
|
||||
|
||||
extern void mix_voice(int32 *buf, int v, int32 c);
|
||||
extern int recompute_envelope(int v);
|
||||
extern void apply_envelope_to_amp(int v);
|
||||
122
apps/plugins/sdl/SDL_mixer/timidity/output.c
Normal file
122
apps/plugins/sdl/SDL_mixer/timidity/output.c
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
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 Perl Artistic License, available in COPYING.
|
||||
*/
|
||||
|
||||
#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 *lp, int32 c)
|
||||
{
|
||||
int8 *cp=(int8 *)(dp);
|
||||
int32 l;
|
||||
while (c--)
|
||||
{
|
||||
l=(*lp++)>>(32-8-GUARD_BITS);
|
||||
if (l>127) l=127;
|
||||
else if (l<-128) l=-128;
|
||||
*cp++ = (int8) (l);
|
||||
}
|
||||
}
|
||||
|
||||
void s32tou8(void *dp, int32 *lp, int32 c)
|
||||
{
|
||||
uint8 *cp=(uint8 *)(dp);
|
||||
int32 l;
|
||||
while (c--)
|
||||
{
|
||||
l=(*lp++)>>(32-8-GUARD_BITS);
|
||||
if (l>127) l=127;
|
||||
else if (l<-128) l=-128;
|
||||
*cp++ = 0x80 ^ ((uint8) l);
|
||||
}
|
||||
}
|
||||
|
||||
void s32tos16(void *dp, int32 *lp, int32 c)
|
||||
{
|
||||
int16 *sp=(int16 *)(dp);
|
||||
int32 l;
|
||||
while (c--)
|
||||
{
|
||||
l=(*lp++)>>(32-16-GUARD_BITS);
|
||||
if (l > 32767) l=32767;
|
||||
else if (l<-32768) l=-32768;
|
||||
*sp++ = (int16)(l);
|
||||
}
|
||||
}
|
||||
|
||||
void s32tou16(void *dp, int32 *lp, int32 c)
|
||||
{
|
||||
uint16 *sp=(uint16 *)(dp);
|
||||
int32 l;
|
||||
while (c--)
|
||||
{
|
||||
l=(*lp++)>>(32-16-GUARD_BITS);
|
||||
if (l > 32767) l=32767;
|
||||
else if (l<-32768) l=-32768;
|
||||
*sp++ = 0x8000 ^ (uint16)(l);
|
||||
}
|
||||
}
|
||||
|
||||
void s32tos16x(void *dp, int32 *lp, int32 c)
|
||||
{
|
||||
int16 *sp=(int16 *)(dp);
|
||||
int32 l;
|
||||
while (c--)
|
||||
{
|
||||
l=(*lp++)>>(32-16-GUARD_BITS);
|
||||
if (l > 32767) l=32767;
|
||||
else if (l<-32768) l=-32768;
|
||||
*sp++ = XCHG_SHORT((int16)(l));
|
||||
}
|
||||
}
|
||||
|
||||
void s32tou16x(void *dp, int32 *lp, int32 c)
|
||||
{
|
||||
uint16 *sp=(uint16 *)(dp);
|
||||
int32 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)(l));
|
||||
}
|
||||
}
|
||||
|
||||
void s32toulaw(void *dp, int32 *lp, int32 c)
|
||||
{
|
||||
uint8 *up=(uint8 *)(dp);
|
||||
int32 l;
|
||||
while (c--)
|
||||
{
|
||||
l=(*lp++)>>(32-13-GUARD_BITS);
|
||||
if (l > 4095) l=4095;
|
||||
else if (l<-4096) l=-4096;
|
||||
*up++ = _l2u[l];
|
||||
}
|
||||
}
|
||||
60
apps/plugins/sdl/SDL_mixer/timidity/output.h
Normal file
60
apps/plugins/sdl/SDL_mixer/timidity/output.h
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
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 Perl Artistic License, available in COPYING.
|
||||
*/
|
||||
|
||||
/* 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 */
|
||||
|
||||
typedef struct {
|
||||
int32 rate, encoding;
|
||||
char *id_name;
|
||||
} PlayMode;
|
||||
|
||||
extern PlayMode *play_mode_list[], *play_mode;
|
||||
extern int init_buffers(int kbytes);
|
||||
|
||||
/* Conversion functions -- These overwrite the int32 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 *lp, int32 c);
|
||||
|
||||
/* 8-bit signed and unsigned*/
|
||||
extern void s32tos8(void *dp, int32 *lp, int32 c);
|
||||
extern void s32tou8(void *dp, int32 *lp, int32 c);
|
||||
|
||||
/* 16-bit */
|
||||
extern void s32tos16(void *dp, int32 *lp, int32 c);
|
||||
extern void s32tou16(void *dp, int32 *lp, int32 c);
|
||||
|
||||
/* byte-exchanged 16-bit */
|
||||
extern void s32tos16x(void *dp, int32 *lp, int32 c);
|
||||
extern void s32tou16x(void *dp, int32 *lp, int32 c);
|
||||
|
||||
/* uLaw (8 bits) */
|
||||
extern void s32toulaw(void *dp, int32 *lp, int32 c);
|
||||
|
||||
/* little-endian and big-endian specific */
|
||||
#if SDL_BYTEORDER == SDL_LIL_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
|
||||
1746
apps/plugins/sdl/SDL_mixer/timidity/playmidi.c
Normal file
1746
apps/plugins/sdl/SDL_mixer/timidity/playmidi.c
Normal file
File diff suppressed because it is too large
Load diff
160
apps/plugins/sdl/SDL_mixer/timidity/playmidi.h
Normal file
160
apps/plugins/sdl/SDL_mixer/timidity/playmidi.h
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
/*
|
||||
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 Perl Artistic License, available in COPYING.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
int32 time;
|
||||
uint8 channel, type, a, b;
|
||||
} MidiEvent;
|
||||
|
||||
/* 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_TONE_KIT 17
|
||||
#define ME_MASTERVOLUME 18
|
||||
#define ME_CHANNEL_PRESSURE 19
|
||||
|
||||
#define ME_HARMONICCONTENT 71
|
||||
#define ME_RELEASETIME 72
|
||||
#define ME_ATTACKTIME 73
|
||||
#define ME_BRIGHTNESS 74
|
||||
|
||||
#define ME_REVERBERATION 91
|
||||
#define ME_CHORUSDEPTH 93
|
||||
|
||||
#define ME_EOT 99
|
||||
|
||||
|
||||
#define SFX_BANKTYPE 64
|
||||
|
||||
typedef struct {
|
||||
int
|
||||
bank, program, volume, sustain, panning, pitchbend, expression,
|
||||
mono, /* one note only on this channel -- not implemented yet */
|
||||
/* new stuff */
|
||||
variationbank, reverberation, chorusdepth, harmoniccontent,
|
||||
releasetime, attacktime, brightness, kit, sfx,
|
||||
/* end new */
|
||||
pitchsens;
|
||||
FLOAT_T
|
||||
pitchfactor; /* precomputed pitch bend factor to save some fdiv's */
|
||||
char transpose;
|
||||
char *name;
|
||||
} Channel;
|
||||
|
||||
/* Causes the instrument's default panning to be used. */
|
||||
#define NO_PANNING -1
|
||||
/* envelope points */
|
||||
#define MAXPOINT 7
|
||||
|
||||
typedef struct {
|
||||
uint8
|
||||
status, channel, note, velocity, clone_type;
|
||||
Sample *sample;
|
||||
Sample *left_sample;
|
||||
Sample *right_sample;
|
||||
int32 clone_voice;
|
||||
int32
|
||||
orig_frequency, frequency,
|
||||
sample_offset, loop_start, loop_end;
|
||||
int32
|
||||
envelope_volume, modulation_volume;
|
||||
int32
|
||||
envelope_target, modulation_target;
|
||||
int32
|
||||
tremolo_sweep, tremolo_sweep_position, tremolo_phase,
|
||||
lfo_sweep, lfo_sweep_position, lfo_phase,
|
||||
vibrato_sweep, vibrato_sweep_position, vibrato_depth, vibrato_delay,
|
||||
starttime, echo_delay_count;
|
||||
int32
|
||||
echo_delay,
|
||||
sample_increment,
|
||||
envelope_increment,
|
||||
modulation_increment,
|
||||
tremolo_phase_increment,
|
||||
lfo_phase_increment;
|
||||
|
||||
final_volume_t left_mix, right_mix, lr_mix, rr_mix, ce_mix, lfe_mix;
|
||||
|
||||
FLOAT_T
|
||||
left_amp, right_amp, lr_amp, rr_amp, ce_amp, lfe_amp,
|
||||
volume, tremolo_volume, lfo_volume;
|
||||
int32
|
||||
vibrato_sample_increment[VIBRATO_SAMPLE_INCREMENTS];
|
||||
int32
|
||||
envelope_rate[MAXPOINT], envelope_offset[MAXPOINT];
|
||||
int32
|
||||
vibrato_phase, vibrato_control_ratio, vibrato_control_counter,
|
||||
envelope_stage, modulation_stage, control_counter,
|
||||
modulation_delay, modulation_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 */
|
||||
|
||||
/* Envelope stages: */
|
||||
#define ATTACK 0
|
||||
#define HOLD 1
|
||||
#define DECAY 2
|
||||
#define RELEASE 3
|
||||
#define RELEASEB 4
|
||||
#define RELEASEC 5
|
||||
#define DELAY 6
|
||||
|
||||
extern Channel channel[16];
|
||||
extern Voice voice[MAX_VOICES];
|
||||
extern signed char drumvolume[MAXCHAN][MAXNOTE];
|
||||
extern signed char drumpanpot[MAXCHAN][MAXNOTE];
|
||||
extern signed char drumreverberation[MAXCHAN][MAXNOTE];
|
||||
extern signed char drumchorusdepth[MAXCHAN][MAXNOTE];
|
||||
|
||||
extern int32 control_ratio, amp_with_poly, amplification;
|
||||
extern int32 drumchannels;
|
||||
extern int adjust_panning_immediately;
|
||||
extern int voices;
|
||||
|
||||
#define ISDRUMCHANNEL(c) ((drumchannels & (1<<(c))))
|
||||
|
||||
extern int GM_System_On;
|
||||
extern int XG_System_On;
|
||||
extern int GS_System_On;
|
||||
|
||||
extern int XG_System_reverb_type;
|
||||
extern int XG_System_chorus_type;
|
||||
extern int XG_System_variation_type;
|
||||
|
||||
extern int play_midi(MidiEvent *el, int32 events, int32 samples);
|
||||
extern int play_midi_file(const char *fn);
|
||||
extern void dumb_pass_playing_list(int number_of_files, char *list_of_files[]);
|
||||
1065
apps/plugins/sdl/SDL_mixer/timidity/readmidi.c
Normal file
1065
apps/plugins/sdl/SDL_mixer/timidity/readmidi.c
Normal file
File diff suppressed because it is too large
Load diff
18
apps/plugins/sdl/SDL_mixer/timidity/readmidi.h
Normal file
18
apps/plugins/sdl/SDL_mixer/timidity/readmidi.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
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 Perl Artistic License, available in COPYING.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
MidiEvent event;
|
||||
void *next;
|
||||
} MidiEventList;
|
||||
|
||||
extern int32 quietchannels;
|
||||
|
||||
extern MidiEvent *read_midi_file(SDL_RWops *mrw, int32 *count, int32 *sp);
|
||||
|
||||
extern char midi_name[FILENAME_MAX+1];
|
||||
730
apps/plugins/sdl/SDL_mixer/timidity/resample.c
Normal file
730
apps/plugins/sdl/SDL_mixer/timidity/resample.c
Normal file
|
|
@ -0,0 +1,730 @@
|
|||
/*
|
||||
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 Perl Artistic License, available in COPYING.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "common.h"
|
||||
#include "instrum.h"
|
||||
#include "playmidi.h"
|
||||
#include "output.h"
|
||||
#include "ctrlmode.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++ = (resample_t)(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++ = (resample_t)(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 resample_t *resample_buffer;
|
||||
|
||||
/*************** resampling with fixed increment *****************/
|
||||
|
||||
static resample_t *rs_plain(int v, int32 *countptr)
|
||||
{
|
||||
|
||||
/* Play sample until end, then free the voice. */
|
||||
|
||||
INTERPVARS;
|
||||
Voice
|
||||
*vp=&voice[v];
|
||||
resample_t
|
||||
*dest=resample_buffer;
|
||||
sample_t
|
||||
*src=vp->sample->data;
|
||||
int32
|
||||
ofs=vp->sample_offset,
|
||||
incr=vp->sample_increment,
|
||||
le=vp->sample->data_length,
|
||||
count=*countptr;
|
||||
|
||||
#ifdef PRECALC_LOOPS
|
||||
int32 i, j;
|
||||
|
||||
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;
|
||||
|
||||
for(j = 0; j < i; j++)
|
||||
{
|
||||
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 resample_t *rs_loop(Voice *vp, int32 count)
|
||||
{
|
||||
|
||||
/* Play sample until end-of-loop, skip back and continue. */
|
||||
|
||||
INTERPVARS;
|
||||
int32
|
||||
ofs=vp->sample_offset,
|
||||
incr=vp->sample_increment,
|
||||
le=vp->sample->loop_end,
|
||||
ll=le - vp->sample->loop_start;
|
||||
resample_t
|
||||
*dest=resample_buffer;
|
||||
sample_t
|
||||
*src=vp->sample->data;
|
||||
|
||||
#ifdef PRECALC_LOOPS
|
||||
int32 i;
|
||||
|
||||
if (ofs < 0 || le < 0) return resample_buffer;
|
||||
|
||||
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;
|
||||
if (i > 0)
|
||||
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 resample_t *rs_bidir(Voice *vp, int32 count)
|
||||
{
|
||||
INTERPVARS;
|
||||
int32
|
||||
ofs=vp->sample_offset,
|
||||
incr=vp->sample_increment,
|
||||
le=vp->sample->loop_end,
|
||||
ls=vp->sample->loop_start;
|
||||
resample_t
|
||||
*dest=resample_buffer;
|
||||
sample_t
|
||||
*src=vp->sample->data;
|
||||
|
||||
#ifdef PRECALC_LOOPS
|
||||
int32
|
||||
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 update_vibrato(Voice *vp, int sign)
|
||||
{
|
||||
int32 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) a;
|
||||
|
||||
if (sign)
|
||||
a = -a; /* need to preserve the loop direction */
|
||||
|
||||
return (int32) a;
|
||||
}
|
||||
|
||||
static resample_t *rs_vib_plain(int v, int32 *countptr)
|
||||
{
|
||||
|
||||
/* Play sample until end, then free the voice. */
|
||||
|
||||
INTERPVARS;
|
||||
Voice *vp=&voice[v];
|
||||
resample_t
|
||||
*dest=resample_buffer;
|
||||
sample_t
|
||||
*src=vp->sample->data;
|
||||
int32
|
||||
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 resample_t *rs_vib_loop(Voice *vp, int32 count)
|
||||
{
|
||||
|
||||
/* Play sample until end-of-loop, skip back and continue. */
|
||||
|
||||
INTERPVARS;
|
||||
int32
|
||||
ofs=vp->sample_offset,
|
||||
incr=vp->sample_increment,
|
||||
le=vp->sample->loop_end,
|
||||
ll=le - vp->sample->loop_start;
|
||||
resample_t
|
||||
*dest=resample_buffer;
|
||||
sample_t
|
||||
*src=vp->sample->data;
|
||||
int
|
||||
cc=vp->vibrato_control_counter;
|
||||
|
||||
#ifdef PRECALC_LOOPS
|
||||
int32 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 resample_t *rs_vib_bidir(Voice *vp, int32 count)
|
||||
{
|
||||
INTERPVARS;
|
||||
int32
|
||||
ofs=vp->sample_offset,
|
||||
incr=vp->sample_increment,
|
||||
le=vp->sample->loop_end,
|
||||
ls=vp->sample->loop_start;
|
||||
resample_t
|
||||
*dest=resample_buffer;
|
||||
sample_t
|
||||
*src=vp->sample->data;
|
||||
int
|
||||
cc=vp->vibrato_control_counter;
|
||||
|
||||
#ifdef PRECALC_LOOPS
|
||||
int32
|
||||
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;
|
||||
}
|
||||
|
||||
resample_t *resample_voice(int v, int32 *countptr)
|
||||
{
|
||||
int32 ofs;
|
||||
uint8 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 (resample_t *)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 incr, ofs, newlen, count;
|
||||
int16 *src = (int16 *) sp->data;
|
||||
resample_t *newdata, *dest;
|
||||
int16 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);
|
||||
if (a <= 0) return;
|
||||
newlen = (int32)(sp->data_length / a);
|
||||
if (newlen < 0 || (newlen >> FRACTION_BITS) > MAX_SAMPLE_SIZE) return;
|
||||
dest = newdata = 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 == src) ? *vptr : *(vptr - 1);
|
||||
v2 = *vptr;
|
||||
v3 = *(vptr + 1);
|
||||
v4 = *(vptr + 2);
|
||||
xdiff = FSCALENEG(ofs & FRACTION_MASK, FRACTION_BITS);
|
||||
*dest++ = (int16)(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++ = (resample_t)(v1 + (((v2 - v1) * (ofs & FRACTION_MASK)) >> FRACTION_BITS));
|
||||
}
|
||||
else
|
||||
*dest++ = src[ofs >> FRACTION_BITS];
|
||||
|
||||
sp->data_length = newlen;
|
||||
sp->loop_start = (int32)(sp->loop_start / a);
|
||||
sp->loop_end = (int32)(sp->loop_end / a);
|
||||
free(sp->data);
|
||||
sp->data = (sample_t *) newdata;
|
||||
sp->sample_rate = 0;
|
||||
}
|
||||
10
apps/plugins/sdl/SDL_mixer/timidity/resample.h
Normal file
10
apps/plugins/sdl/SDL_mixer/timidity/resample.h
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
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 Perl Artistic License, available in COPYING.
|
||||
*/
|
||||
|
||||
extern resample_t *resample_voice(int v, int32 *countptr);
|
||||
extern void pre_resample(Sample *sp);
|
||||
19
apps/plugins/sdl/SDL_mixer/timidity/sdl_a.c
Normal file
19
apps/plugins/sdl/SDL_mixer/timidity/sdl_a.c
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
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 Perl Artistic License, available in COPYING.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "output.h"
|
||||
|
||||
/* export the playback mode */
|
||||
|
||||
#define dpm sdl_play_mode
|
||||
|
||||
PlayMode dpm = {
|
||||
DEFAULT_RATE, PE_16BIT|PE_SIGNED,
|
||||
"SDL audio"
|
||||
};
|
||||
136
apps/plugins/sdl/SDL_mixer/timidity/sdl_c.c
Normal file
136
apps/plugins/sdl/SDL_mixer/timidity/sdl_c.c
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
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 Perl Artistic License, available in COPYING.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "common.h"
|
||||
#include "output.h"
|
||||
#include "ctrlmode.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(int32 *valp);
|
||||
static int cmsg(int type, int verbosity_level, char *fmt, ...);
|
||||
|
||||
/**********************************/
|
||||
/* 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(int32 *valp)
|
||||
{
|
||||
return RC_NONE;
|
||||
}
|
||||
|
||||
static int cmsg(int type, int verbosity_level, char *fmt, ...)
|
||||
{
|
||||
#ifdef GREGS_DEBUG
|
||||
va_list ap;
|
||||
int flag_newline = 1;
|
||||
if ((type==CMSG_TEXT || type==CMSG_INFO || type==CMSG_WARNING) &&
|
||||
ctl.verbosity<verbosity_level-1)
|
||||
return 0;
|
||||
if (*fmt == '~')
|
||||
{
|
||||
flag_newline = 0;
|
||||
fmt++;
|
||||
}
|
||||
va_start(ap, fmt);
|
||||
if (!ctl.opened)
|
||||
{
|
||||
vfprintf(stderr, fmt, ap);
|
||||
if (flag_newline) fprintf(stderr, "\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
vfprintf(stderr, fmt, ap);
|
||||
if (flag_newline) fprintf(stderr, "\n");
|
||||
}
|
||||
va_end(ap);
|
||||
if (!flag_newline) fflush(stderr);
|
||||
return 0;
|
||||
#else
|
||||
va_list ap;
|
||||
if ((type==CMSG_TEXT || type==CMSG_INFO || type==CMSG_WARNING) &&
|
||||
ctl.verbosity<verbosity_level)
|
||||
return 0;
|
||||
va_start(ap, fmt);
|
||||
char buf[128];
|
||||
vsnprintf(buf, 128, fmt, ap);
|
||||
puts(buf);
|
||||
SDL_vsnprintf(timidity_error, TIMIDITY_ERROR_SIZE, fmt, ap);
|
||||
va_end(ap);
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
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) {}
|
||||
1111
apps/plugins/sdl/SDL_mixer/timidity/tables.c
Normal file
1111
apps/plugins/sdl/SDL_mixer/timidity/tables.c
Normal file
File diff suppressed because it is too large
Load diff
35
apps/plugins/sdl/SDL_mixer/timidity/tables.h
Normal file
35
apps/plugins/sdl/SDL_mixer/timidity/tables.h
Normal 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 Perl Artistic License, available in COPYING.
|
||||
*/
|
||||
|
||||
#ifdef LOOKUP_SINE
|
||||
extern FLOAT_T sine(int x);
|
||||
#else
|
||||
#define sine(x) (sin((2*PI/1024.0) * (x)))
|
||||
#endif
|
||||
|
||||
#define SINE_CYCLE_LENGTH 1024
|
||||
extern int32 freq_table[];
|
||||
extern double vol_table[];
|
||||
extern double expr_table[];
|
||||
extern double bend_fine[];
|
||||
extern double bend_coarse[];
|
||||
extern uint8 *_l2u; /* 13-bit PCM to 8-bit u-law */
|
||||
extern uint8 _l2u_[]; /* used in LOOKUP_HACK */
|
||||
#ifdef LOOKUP_HACK
|
||||
extern int16 _u2l[];
|
||||
extern int32 *mixup;
|
||||
#ifdef LOOKUP_INTERPOLATION
|
||||
extern int8 *iplookup;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
extern void init_tables(void);
|
||||
|
||||
#define XMAPMAX 800
|
||||
extern int xmap[XMAPMAX][5];
|
||||
|
||||
359
apps/plugins/sdl/SDL_mixer/timidity/timidity.c
Normal file
359
apps/plugins/sdl/SDL_mixer/timidity/timidity.c
Normal file
|
|
@ -0,0 +1,359 @@
|
|||
/*
|
||||
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 Perl Artistic License, available in COPYING.
|
||||
*/
|
||||
|
||||
#include "SDL.h"
|
||||
#include "config.h"
|
||||
#include "common.h"
|
||||
#include "instrum.h"
|
||||
#include "playmidi.h"
|
||||
#include "readmidi.h"
|
||||
#include "output.h"
|
||||
#include "ctrlmode.h"
|
||||
#include "timidity.h"
|
||||
|
||||
#include "tables.h"
|
||||
|
||||
void (*s32tobuf)(void *dp, int32 *lp, int32 c);
|
||||
int free_instruments_afterwards=0;
|
||||
static char def_instr_name[256]="";
|
||||
|
||||
int AUDIO_BUFFER_SIZE;
|
||||
resample_t *resample_buffer=NULL;
|
||||
int32 *common_buffer=NULL;
|
||||
int num_ochannels;
|
||||
|
||||
#define MAXWORDS 10
|
||||
|
||||
static int read_config_file(const char *name)
|
||||
{
|
||||
FILE *fp;
|
||||
char tmp[PATH_MAX], *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 -1;
|
||||
|
||||
while (fgets(tmp, sizeof(tmp), fp))
|
||||
{
|
||||
line++;
|
||||
w[words=0]=strtok(tmp, " \t\r\n\240");
|
||||
if (!w[0] || (*w[0]=='#')) continue;
|
||||
while (w[words] && (words < MAXWORDS))
|
||||
{
|
||||
w[++words]=strtok(0," \t\r\n\240");
|
||||
if (w[words] && w[words][0]=='#') break;
|
||||
}
|
||||
if (!strcmp(w[0], "map")) continue;
|
||||
if (!strcmp(w[0], "dir"))
|
||||
{
|
||||
if (words < 2)
|
||||
{
|
||||
ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
|
||||
"%s: line %d: No directory given\n", name, line);
|
||||
return -2;
|
||||
}
|
||||
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 -2;
|
||||
}
|
||||
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 -2;
|
||||
}
|
||||
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 -2;
|
||||
}
|
||||
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 -2;
|
||||
}
|
||||
if (!drumset[i])
|
||||
{
|
||||
drumset[i]=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 -2;
|
||||
}
|
||||
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 -2;
|
||||
}
|
||||
if (!tonebank[i])
|
||||
{
|
||||
tonebank[i]=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 -2;
|
||||
}
|
||||
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 -2;
|
||||
}
|
||||
if (!bank)
|
||||
{
|
||||
ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
|
||||
"%s: line %d: Must specify tone bank or drum set "
|
||||
"before assignment\n",
|
||||
name, line);
|
||||
return -2;
|
||||
}
|
||||
if (bank->tone[i].name)
|
||||
free(bank->tone[i].name);
|
||||
strcpy((bank->tone[i].name=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 -2;
|
||||
}
|
||||
*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 -2;
|
||||
}
|
||||
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 -2;
|
||||
}
|
||||
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 -2;
|
||||
}
|
||||
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 -2;
|
||||
}
|
||||
}
|
||||
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 -2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: line %d: bad patch option %s\n",
|
||||
name, line, w[j]);
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ferror(fp))
|
||||
{
|
||||
ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Can't read from %s\n", name);
|
||||
close_file(fp);
|
||||
return -2;
|
||||
}
|
||||
close_file(fp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Timidity_Init(int rate, int format, int channels, int samples)
|
||||
{
|
||||
const char *env = getenv("TIMIDITY_CFG");
|
||||
if (!env || read_config_file(env)<0) {
|
||||
if (read_config_file(CONFIG_FILE)<0) {
|
||||
if (read_config_file(CONFIG_FILE_ETC)<0) {
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (channels < 1 || channels == 3 || channels == 5 || channels > 6) return(-1);
|
||||
|
||||
num_ochannels = channels;
|
||||
|
||||
/* 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 = safe_malloc(AUDIO_BUFFER_SIZE*sizeof(resample_t)+100);
|
||||
common_buffer = safe_malloc(AUDIO_BUFFER_SIZE*num_ochannels*sizeof(int32));
|
||||
|
||||
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_SIZE] = "";
|
||||
const char *Timidity_Error(void)
|
||||
{
|
||||
return(timidity_error);
|
||||
}
|
||||
|
||||
20
apps/plugins/sdl/SDL_mixer/timidity/timidity.h
Normal file
20
apps/plugins/sdl/SDL_mixer/timidity/timidity.h
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
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 Perl Artistic License, available in COPYING.
|
||||
*/
|
||||
|
||||
typedef struct _MidiSong MidiSong;
|
||||
|
||||
extern int Timidity_Init(int rate, int format, int channels, int samples);
|
||||
extern const char *Timidity_Error(void);
|
||||
extern void Timidity_SetVolume(int volume);
|
||||
extern int Timidity_PlaySome(void *stream, int samples);
|
||||
extern MidiSong *Timidity_LoadSong_RW(SDL_RWops *rw, int freerw);
|
||||
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_Close(void);
|
||||
Loading…
Add table
Add a link
Reference in a new issue