pax_global_header00006660000000000000000000000064134464473540014530gustar00rootroot0000000000000052 comment=bc4b70cf447e5cd6e9c3c3ee5aef0aa3b28d8175 awesfx-0.5.2/000077500000000000000000000000001344644735400130315ustar00rootroot00000000000000awesfx-0.5.2/.cvsignore000066400000000000000000000003111344644735400150240ustar00rootroot00000000000000sfxload setfx sf2text text2sf gusload sfxtest aweset asfxload Makefile Makefile.in INSTALL COPYING .deps .libs aclocal.m4 autom4te.cache config.* configure depcomp install-sh libtool ltmain.sh missing awesfx-0.5.2/.gitignore000066400000000000000000000005261344644735400150240ustar00rootroot00000000000000*.o *.a .deps .libs config.h config.h.in configure config.log config.cache config.status config.guess config.sub aclocal.m4 stamp-h* Makefile Makefile.in stamp-h.in autom4te.cache install-sh missing mkinstalldirs depcomp libtool ltmain.sh sfxload setfx sf2text text2sf gusload sfxtest awesfx aweset asfxload agusload include/awe_version.h awesfx-0.5.2/AUTHORS000066400000000000000000000000351344644735400140770ustar00rootroot00000000000000Takashi Iwai awesfx-0.5.2/COPYING000066400000000000000000000431311344644735400140660ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. awesfx-0.5.2/ChangeLog000066400000000000000000000065241344644735400146120ustar00rootroot00000000000000ver.0.5.2 - add ALSA-native GUS loader (agusload) ver.0.5.1e - fix wrong error condition checks in loadbank.c ver.0.5.1d - fix possible buffer overflow in awe_read_option_file() ver.0.5.1c - oops, I forgot to package COPYING file, released as 0.5.1c ver.0.5.1b - fix Makefile.am for autoreconf - fix udev script for recent udev versions (that don't pass PHYSDEVDRIVER variable) ver.0.5.1a - really fix the build without linux/awe_voice.h ver.0.5.1 - include awe_voice.h into the package (to fix build with 2.6.22 kernel) - added udev-related files to etc subdirectory ver.0.5.0d - fixed compilation with gcc-2.x. - added -q (--quiet) option to [a]sfxload. verbosity is set to 1 as default. some debug messages appears with level 2. - fixed the pitch correction type to signed. this will fix some weird detuned tones. ver.0.5.0c - fixed the option parsing. -b option works again now. ver.0.5.0b - patches by N. Vignot - fixed sf2text outputs for non-printable letters - fixed fskip for pipe - added .bz2 extention for open ver.0.5.0a - patches by Philipp Matthias Hahn - fixed compile warnings - fixed the wrong options in aweset - fixed manpage ver.0.5.0 - Support ALSA emux hwdep interface. asfxload is added. The hardware access operators are packed as AWEOps struct, the awelib no longer accesses the DSP i/o directly. - Use GNU auto-tools instead of Imake. - Moved docs and some files in the root directory for GNU style. - Fixed some buffer-overflows. - Build awelib static. - Added awe_ prefix to some awelib functions to avoid name conflictions. - Changed the default SoundFont path. ver.0.4.4 - Fixed Makefiles - Fixed big-endian handling ver.0.4.3c - Add --device and --index options - RPM spec file is included ver.0.4.3b - Change directory contents - Add sapmles Makefiles for shared-library ver.0.4.3a - Minor bug fix ver.0.4.3 - Official relase ver.0.4.3p4 - Add -i and -N options ver.0.4.3p3 - Load via sample sharing mode (for awedrv-0.4.3p4) - Fix a bug to miss some fonts in dynamic loading - Fix a bug in path.c - Change library version to 0.4.3 ver.0.4.3p2 - Fix a bug to garbage purge_list (in parsesf.c) - New program: aweset ver.0.4.3p1 - Change parameter calculation as well as DOS drivers - Add --compat option to keep the compatibility with older versions - Avoid to load a part of layers when out of memory ver.0.4.2 - Add setfx command. - Add lock option. - Support for virtual bank file. - Support for preset mapping - Merge global variables to one option structure. - Change from Makefile to Imakefile - Create AWElib for easy use of patch loading - Fix a getopt bug. - Fix a bug in calculation of envelope hold time - Fix a bug in calculation of coarse loop addresses - Sfxload tells if the file is not found - Add keynote option in gusload - Change sfxtest arguments ver.0.4.1 development versions ver.0.4.0 TOTALLY REWRITEN. - Remove -i option: always remove samples if not speicifed -b option. - Remove other obsolte options, -I, -s, -m. (though they're remained for comaptibility.) - Add attenuation control options, -A and -a. - Add memory display option, -M. - Do not support SFX file in sfxload utility. - Read & write S-expression style text file. - Add partial loading - Use default rc file - Support long options awesfx-0.5.2/Makefile.am000066400000000000000000000014441344644735400150700ustar00rootroot00000000000000SUBDIRS = awelib include samples etc bin_PROGRAMS = sfxload asfxload aweset gusload agusload setfx sf2text text2sf sfxtest LDADD = awelib/libawe.a AUTOMAKE_OPTIONS = foreign INCLUDES = -Iinclude asfxload_SOURCES = asfxload.c alsa.c asfxload_LDADD = awelib/libawe.a @ALSA_LIBS@ sfxload_SOURCES = sfxload.c seq.c aweset_SOURCES = aweset.c seq.c gusload_SOURCES = gusload.c seq.c agusload_SOURCES = agusload.c alsa.c agusload_LDADD = awelib/libawe.a @ALSA_LIBS@ sfxtest_SOURCES = sfxtest.c seq.c setfx_SOURCES = setfx.c seq.c sf2text_SOURCES = sf2text.c text2sf_SOURCES = text2sf.c noinst_HEADERS = seq.h guspatch.h man_MANS = sfxload.1 EXTRA_DIST = sfxload.1 SBKtoSF2.txt install-data-hook: rm -f $(DESTDIR)$(mandir)/man1/asfxload.1 (cd $(DESTDIR)$(mandir)/man1 && $(LN_S) sfxload.1 asfxload.1) awesfx-0.5.2/README000066400000000000000000000353251344644735400137210ustar00rootroot00000000000000================================================================ AWE32 Sound Driver Utility Programs for Linux / FreeBSD version 0.5.1 Takashi Iwai ================================================================ ---------------------------------------------------------------- * GENERAL NOTES Thie package includes several utilities for AWE32 sound driver on Linux and FreeBSD systems and for Emux WaveTable of ALSA sbawe and emu10k1 drivers. You need to use these utilities to enable sounds on these drivers properly. The package is managed with GNU auto-tools since version 0.5.0. The ALSA support (asfxload) is added also in this version. Ver.0.4.3 improves the parameter calculation as almost compatible with the DOS/Win drivers. This is more effective in the case of ROM sounds. If you prefer the old type sounds, use --compatible option. This packaing contains the following programs: for ALSA - asfxload SoundFont file loader for OSS - sfxload SoundFont file loader - setfx Chorus/reverb effect loader - aweset Change the running mode of AWE driver - sf2text Convert SoundFont to readable text - text2sf Revert from text to SoundFont file - gusload GUS PAT file loader - sfxtest Example program to control AWE driver The package includes the correction of SoundFont managing routines, called AWElib. As default, the AWElib is *NOT* installed. For installing it, modify awelib/Makefile.am. ---------------------------------------------------------------- * SFXLOAD and ASFXLOAD SFXLOAD and ASFXLOAD are utility program sto transfer the sound wave and instruments data in a SoundFont file to the AWE32 sound driver, or to the Emux WaveTable of ALSA sbawe and emu10k1 drivers. This program is necessary for playing MIDI samples via sequencer programs supporting AWE driver. There is no big difference between sfxload and asfxload except for that asfxload is for ALSA and sfxload is for OSS, respecitvely. The options to specify devices are different between them. Basically, sfxload behaves as two ways. % sfxload fontfile % sfxload -b1 fontfile The first usage is to read SF2 (or SBK) file and transfer to the awe driver. In this case, the samples which were loaded on the driver are replaced with the new one. In the second case, sfxload reads the file and appends it to the pre-loaded samples on the driver with specified bank number. The old samples remain in the driver. The additional samples can be cleared via -x option (see below). The sound files are searched through the path list. The path list is defined as built-in. If the environment variable SFBANKDIR or the command line option -P is given, it replaces the default search list. The file extension .sf2, and .sbk can be abbreviated. The new sfxload can deal with a virtual bank file. It contains a list of presets from various soundfonts. See the virtual bank file section for more details. OPTIONS: -i, --clear[=bool] Remove all samples before loading the fonts. This is an explicit directive (see -b option). If this option is specified alone without soundfont file arguments, sfxload does onlay remove samples. Either of "on", "off", "yes", "no", "true", or "false" can be specified as an optional argument. -x, --remove[=bool] Remove the optional samples previouly loaded via -b option. Otherwise, all new samples are simply appended. -N, --increment[=bool] Do not clear samples even with the absence of -b option. However, this option is not exclusive with -x option. If both options are specified, and the memory full error is encountered during loading fonts, sfxload will try to remove samples and load the fonts again. -b, --bank=number Append the sound samples on the specified bank. Without this option, all present samples in the driver are removed before loading the new fonts unless -N option is specified. Usually, this option is necessary to load user bank, typically in bank one. eg) % sfxload synthgm.sbk % sfxload -b1 surprise.sf2 -l, --lock[=bool] Lock the font. The locked font is no longer removed via remove option (-x) even if it's loaded together with -b option. -C, --compat[=bool] Use the old (v0.4.2) parameter calculations. -A, --sense=sensitivity -a, --atten=attenuation (Only valid on compatible mode) These options are used to control the attenuation of samples. The former defines the sensitivity of initial attenuation parameter of each instrument in SoundFont file. In the program, the actual attenuaton is calculated from the divided value by this sensitivity from the original parameter. Then, 1.0 means to use the original parameter without modification. Generally, smaller number makes drum sounds louder. The default value is 10. (I think -A 2 would be similar to Windows sounds.) The latter option defines the minimum attenuation. The value is given in the raw parameter for AWE driver, that is, in 8/3 dB unit. The default value is 32. Note that since -A option will change the minimum attenuation automatically, the option -a must be speicifed later from -A option. -d, --decay=scale (Only valid on compatible mode) Set the scale of envelope decay time. Default value is 50.0. Sounds decay fast when larger number is set. The ver.0.3 sfxload uses 54.8. If you want to keep the same sound, use this number instead. -B, --addblank[=bool] Add 48 size of blank loop on each sample data. Usually, this option is not necessary. Most of soundfont files are designed well for enough blank loops for each sample. -M, --memory[=0|1] Display the left memory size of DRAM on the AWE32 card. -c, --chorus=percent -r, --reverb=percent Specify the effects of chorus and reverb, respectively. The value is in percent, from 0 to 100. The default is unspecified. Note: these values may be overwritten by MIDI control messages. -L, --extract=source[:map] Extract and load only the specified preset(s). This option is usually employed by drvmidi. The preset is given as same as in virtual bank file. -v, --verbose[=level] Increase or set the verbosity level. -q, --quiet Don't print error messages, equivalent with --verbose=0. -V, --volume=percent Set the total volume of sounds, provided in percent. Default volume is 70%. -P, --path=path1:path2:... Specify the search path for sound files. It overrides both the system path and environment variable SFBANKDIR. -d, --device=file Specify the device file name. As default, /dev/sequencer is used. VIRTUAL BANK FILE: The virtual bank file is a list of presets treated as one soundfont file. The syntax of virtual bank is as follows: # comments source:map[:soundfont [preset-name] source:map[:soundfont [preset-name] ... The first and second items are the source and mapped presets, respectively. The former is the existing preset in the soundfont, and the latter is the actual preset loaded on the sound driver. The preset is described by the following three values, preset/bank/keynote If bank and keynote are omitted, bank 0 and keynote -1 (meaning to search all keys) are applied. The third item is the name of soundfont file. The file is searched from the prescribed search-path. The remaining arguments are ignored in sfxload. If the soundfont name is omitted, sfxload loads them as preset mapping. It just behaves like a symbolic link of file opposing to copying of the file. Any sample data is not referred at this time, but searched first when the note is played. A couple of special commands can be used together with the virtual presets above. "default" command is used to specify the default soundfont file. Any other presets which are not defined in the virtual preset lists are loaded from this default font. For example, in the following virtual bank, 2mbgmgs.sf2 is used except for standard drumsets which employs drum.sf2: 0/128:0/128:drum.sf2 default 2mbgmgs.sf2 Another special command is "include" command. This simply includes another virtual bank file under the current position. For example, default standard.sf2 0/128:0/128:drum.sf2 include xgsfx.bnk SYSTEM RESOURCE FILE: You can set default option arguments in the system resource file. There're two files loaded as default. $HOME/.sfxloadrc /etc/sfxloadrc The syntax is as follows: fontname options.. The first argument is soundfont file name for each option. The remaining arguments are identical with command line options. The font name "default" is used for default options for all sound fonts. The default options are overridden by specific options or command line options. For example, to set default chorus level 20 except for synthgm font, you can write a resource file ~/.sfxloadrc like that: default --chorus=20 synthgm --chorus=0 ENVIRONMENT: SFBANKDIR Search path for sound files. The current directory is always searched at first. ---------------------------------------------------------------- * AWESET AWESET sets many controll parameters on AWE driver. Most of the parameters can be controlled directly from drvmidi MIDI sequencer. This program is useful to control the parameters for other non-AWE-specific programs. The control parameters are given either by command line or a file. % aweset newvolume on % aweset n 1 % aweset -f new-config In the first case, aweset enables a boolean parameter "newvolume". The second case is identical with the first case, but using an abbreviated command. In the last case, aweset reads a file "new-config" and parses the contents. The file must contain the commands like command line arguments as former cases. The available commands are as follows: command(abbrev) data type description - exclusive(e) bool exclusive note mode (default: on) - realpan(p) bool real-time panning change (default: on) - gusbank(g) int GUS-instrument bank number (default: 0) - keepeffect(k) bool keep effect controls after clearing voices (def:off) - zeroatten(z) int zero attenuation level (default: 32 - depends on sfxload) - chnprior(C) bool channel priority mode (default: off) - modsense(m) int modulation wheel sensitivity (default: 18) - defpreset(P) int default search preset number (default: 0) - defbank(B) int default search bank number (default: 0) - defdrum(D) int default search drumset number (default: 0) - toggledrum(a) bool accept to change bank of drum channels (def: off) - newvolume(n) bool Windows/DOS-like volume calculation mode (def: on) - chorus(c) [0-7] chorus mode (default: 2) - reverb(r) [0-7] reverb mode (default: 4) - bass(b) [0-11] equalizer bass level (default: 5) - treble(t) [0-11] equalizer treble level (default: 9) - debug(d) int debug mode (default: 0) - panexchange(x) bool exchange panning direction (left<->right) (def:off) ---------------------------------------------------------------- * SETFX SETFX reads a configuration file and downloads the user defined chorus/reverb effect parameters on the sound driver. % setfx test.cfg The format of configuration file is as follows: type:mode:name:include:parameters.. type this specifies either "chorus" or "reverb". mode the mode index in integer value from 8 to 31. name the name of this effect in any string (except colon) include include from the pre-defined mode. This is valid only on reverb definition. If this index is specified, the parameter lists become "pos=value pos=value.." where 'pos' is a position of the parameter (from 0 to 27) and 'value' is the new replaced value. parameters effect parameters. All values are written in hex code. In chorus mode, this contains five values, while in reverb mode, 28 values must be listed. The configuratoin file is searched according to the pre-defined soundfont path search list. ---------------------------------------------------------------- * SF2TEXT Sf2text converts the specified SoundFont file to the text file which is editable easily. Both SBK and SF2 formats can be converted. % sf2text sample.sf2 sample.txt The converted text file contains five categories. 1. major and minor versions 2. sample data position and size 3. preset information 4. instrument information 5. sample data information The present sf2text program employes an S-expression list. This text file can be converted to SoundFont format again via text2sf utility program below. ---------------------------------------------------------------- * TEXT2SF Text2sf works as an opposite convertor from text file to SoundFont format file. It reads an S-expression list and write it on the new SoundFont file. % text2sf sample.txt sample.sf2 new.sf2 The second argument is the original SoundFont file, and the last is the new SoundFont file. The original file is necessary to duplicate INFO list and wave samples to the new file. ---------------------------------------------------------------- * GUSLOAD Gusload is a tool to load a GUS compatible patch file to AWE32 driver. % gusload [-i] [-v] [-b bank] [-p preset] [-k keynote] GUSfile The voices are loaded as a preset with the prescribed instrument number in each patch unless -p option is specified. The bank number is also changed by -b option. The option -k is used to specify the fixed key note for the patch. eg) % gusload -b 0 -p 53 doo.pat The option -i is identical with sfxload. All the samples will be cleared before loading. ---------------------------------------------------------------- * SFXTEST Sfxtest is a sample program to control awe sound driver. % sfxtest commands ... For example, to play a trumpet voice (preset 56) on key middle C (60) for two seconds in channel access mode, execute as follows: % sfxtest X p 56 n 60 127 t 200 K 60 You can see the debug message of the awe driver by setting debug mode. % sfxtest X D 9 p 47 n 62 100 t 150 K 47 D 0 Multiple channels can be used at the same time. % sfxtest X x 0 p 0 n 60 127 x 1 p 5 n 72 110 t 150 x 0 K 60 x 1 K 72 ---------------------------------------------------------------- * ACKNOWLEDGMENTS Thanks to Mark Weaver who revealed and offered ADIP compatible parameter calculations. ---------------------------------------------------------------- * COPYRIGHT Copyright (C) 1996-2003 by Takashi Iwai These programs are free software; you can redistribute them and/or modify them under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. These programs are distributed in the hope that they will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. awesfx-0.5.2/SBKtoSF2.txt000066400000000000000000000066341344644735400151000ustar00rootroot00000000000000================================================================ SoundFont 1 (sbk) --> SoundFont 2 (sf2) Conversion ================================================================ The following conversion rules are on the basis of my experience. Please do not consult to Creative about this. -- iwai ================================================================ modenv, volenv, lfo1, lfo2 delay time msec attack time msec hold time msec decay time msec release time msec -- sf2 time cents sf2 = log2(sbk/1000) * 1200 ================================================================ vol sustain 0-127 (or larger) -- sf2 cB below full scale sf2 = 1000 - 10.5 * sbk when sbk < 96 sf2 = 0 when sbk >= 96 Note: the default sustain level is 1000 in SBK, while 0 in SF2. ================================================================ mod sustain 0-96 (96 = zero attenuation, 0 = minimum) -- sf2 0.1% below full scale sf2 = 1000 * (96 - val) / 96 when sbk < 96 sf2 = 0 when sbk >= 96 Note: the default sustain level is 1000 in SBK, while 0 in SF2. ================================================================ time change per key ?? -- sf2 timecent per key sf2 = sbk * 5.55 (??) ================================================================ pan position 0-127 (just same as MIDI) -- sf2 0.1% (left=0, center=500) sf2 = sbk * 1000 / 127 - 500 ================================================================ init attenuation 0-127 (127 = full scale, 0 = minimum) -- sf2 cB from full scale (see the note below) sf2 = -200 * log10(sbk / 127) [note: SF2 spec document says initial attenuation is in unit of centibels, but actual data looks like 2 to 10 times greater. The above conversion does NOT include this correction.] ================================================================ chorus 0-255 reverb -- sf2 0.1% sf2 = sbk * 1000 / 255 ================================================================ initFilterFc -- sf2 absolute cents sf2 = 59 * sbk + 4366 when sbk < 127 (alternatively, sf2 = 50 * sbk + 4721 (4721=125Hz)) sf2 = 14400 when sbk = 127 ================================================================ initFilterQ -- sf2 cB above DC gain sf2 = sbk * 3 / 2 ================================================================ LFO1 freq LFO2 freq -- sf2 absolte cents sf2 = 1200 * log10(sbk) / log10(2) - 7925 ================================================================ modenv pitch shift LFO1 pitch shift LFO2 pitch shift -- sf2 cents sf2 = (1200 * sbk / 64 + 1) / 2 ================================================================ moenv cutoff shift LFO1 cutoff shift -- sf2 cents sf2 = (1200 * ratio * sbk) / 64 ratio = 6 when modenv ratio = 3 when lfo1 ================================================================ lfo1 tremolo volume -- sf2 cB sf2 = (120 * sbk) / 64 ================================================================ scale tuning 0/1 -- sf2 semitone sf2 = 100 when sbk = 0 sf2 = 50 when sbk = 1 NOTE: scale tuning can overwrite in preset layer to instruments. don't add the "converted" value. Otherwise, convert after adding the value. ================================================================ sample pitch (SF1 only; reserved3(#55) in SF2) -- sf2 N/A sf2 rootkey = sbk / 100 sf2 finetune = -sbk % 100 if finetune <= -50 then rootkey++ finetune = 100 + finetune endif ================================================================ awesfx-0.5.2/agusload.c000066400000000000000000000000541344644735400147730ustar00rootroot00000000000000#define BUILD_AGUSLOAD #include "gusload.c" awesfx-0.5.2/alsa.c000066400000000000000000000066731344644735400141310ustar00rootroot00000000000000/* * ALSA hwdep interface * * Copyright (C) 2003 Takashi Iwai * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include #include #include #include #define SNDRV_EMUX_HWDEP_NAME "Emux WaveTable" struct sndrv_emux_misc_mode { int port; /* -1 = all */ int mode; int value; int value2; /* reserved */ }; enum { SNDRV_EMUX_IOCTL_VERSION = _IOR('H', 0x80, unsigned int), SNDRV_EMUX_IOCTL_LOAD_PATCH = _IOWR('H', 0x81, awe_patch_info), SNDRV_EMUX_IOCTL_RESET_SAMPLES = _IO('H', 0x82), SNDRV_EMUX_IOCTL_REMOVE_LAST_SAMPLES = _IO('H', 0x83), SNDRV_EMUX_IOCTL_MEM_AVAIL = _IOW('H', 0x84, int), SNDRV_EMUX_IOCTL_MISC_MODE = _IOWR('H', 0x84, struct sndrv_emux_misc_mode), }; static snd_hwdep_t *hwdep; static int try_open_emux(char *name) { snd_hwdep_info_t *info; unsigned int version; if (snd_hwdep_open(&hwdep, name, 0) < 0) return -1; snd_hwdep_info_alloca(&info); if (snd_hwdep_info(hwdep, info) < 0) goto error; if (strcmp(snd_hwdep_info_get_name(info), SNDRV_EMUX_HWDEP_NAME)) goto error; if (snd_hwdep_ioctl(hwdep, SNDRV_EMUX_IOCTL_VERSION, &version) < 0) goto error; if ((version >> 16) != 0x01) /* version 1 compatible */ goto error; return 0; error: snd_hwdep_close(hwdep); hwdep = NULL; return -1; } void seq_alsa_init(char *name) { char tmpname[32]; int i; if (name == NULL || ! *name) { for (i = 0; i < 8; i++) { sprintf(tmpname, "hw:%d,2", i); if (try_open_emux(tmpname) == 0) return; } } else { if (try_open_emux(name) == 0) return; } fprintf(stderr, "No Emux synth hwdep device is found\n"); exit(1); } void seq_alsa_end(void) { if (hwdep) { snd_hwdep_close(hwdep); hwdep = NULL; } } int seq_reset_samples(void) { return snd_hwdep_ioctl(hwdep, SNDRV_EMUX_IOCTL_RESET_SAMPLES, NULL); } int seq_remove_samples(void) { return snd_hwdep_ioctl(hwdep, SNDRV_EMUX_IOCTL_REMOVE_LAST_SAMPLES, NULL); } int seq_load_rawpatch(void *patch, int len) { return snd_hwdep_ioctl(hwdep, SNDRV_EMUX_IOCTL_LOAD_PATCH, patch); } int seq_load_patch(void *patch, int len) { awe_patch_info *p; p = (awe_patch_info*)patch; p->key = AWE_PATCH; p->device_no = 0; p->sf_id = 0; return snd_hwdep_ioctl(hwdep, SNDRV_EMUX_IOCTL_LOAD_PATCH, p); } int seq_mem_avail(void) { int mem_avail = 0; snd_hwdep_ioctl(hwdep, SNDRV_EMUX_IOCTL_MEM_AVAIL, &mem_avail); return mem_avail; } int seq_zero_atten(int atten) { struct sndrv_emux_misc_mode mode; mode.port = -1; mode.mode = AWE_MD_ZERO_ATTEN; mode.value = atten; mode.value2 = 0; return snd_hwdep_ioctl(hwdep, SNDRV_EMUX_IOCTL_MISC_MODE, &mode); } void seq_set_gus_bank(int bank) { struct sndrv_emux_misc_mode mode; mode.port = -1; mode.mode = AWE_MD_GUS_BANK; mode.value = bank; mode.value2 = 0; return snd_hwdep_ioctl(hwdep, SNDRV_EMUX_IOCTL_MISC_MODE, &mode); } awesfx-0.5.2/asfxload.c000066400000000000000000000000541344644735400147750ustar00rootroot00000000000000#define BUILD_ASFXLOAD #include "sfxload.c" awesfx-0.5.2/awelib/000077500000000000000000000000001344644735400142745ustar00rootroot00000000000000awesfx-0.5.2/awelib/.cvsignore000066400000000000000000000000461344644735400162740ustar00rootroot00000000000000Makefile Makefile.in libawe.so* .deps awesfx-0.5.2/awelib/Makefile.am000066400000000000000000000004121344644735400163250ustar00rootroot00000000000000noinst_LIBRARIES = libawe.a libawe_a_SOURCES = \ awe_parm.c bool.c cmpopen.c dynload.c fskip.c gentxt.c loadbank.c \ loadtext.c malloc.c optfile.c parsesf.c path.c sample.c \ sbkconv.c sffile.c sfitem.c sfopts.c sfout.c slist.c dummy.c INCLUDES = -I../include awesfx-0.5.2/awelib/awe_parm.c000066400000000000000000000432301344644735400162350ustar00rootroot00000000000000/*================================================================ * awe_parm.c * convert Emu8000 parameters * * Copyright (C) 1996-1999 Takashi Iwai * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *================================================================*/ #include #include #include #include "awe_parm.h" #include "sfopts.h" /* #define LOOKUP_TABLE */ /*================================================================ * unit conversion *================================================================*/ /* * convert timecents to msec */ int awe_timecent_to_msec(int timecent) { return (int)(1000 * pow(2.0, (double)timecent / 1200.0)); } /* * convert msec to timecents */ int awe_msec_to_timecent(int msec) { if (msec <= 0) msec = 1; return (int)(log((double)msec / 1000.0) / log(2.0) * 1200.0); } /* * convert abstract cents to mHz */ int awe_abscent_to_mHz(int abscents) { return (int)(8176.0 * pow(2.0, (double)abscents / 1200.0)); } /* * convert from mHz to abstract cents */ int awe_mHz_to_abscent(int mHz) { return (int)(log((double)mHz / 8176.0) / log(2.0) * 1200.0); } /* * convert abstract cents to Hz */ int awe_abscent_to_Hz(int abscents) { return (int)(8.176 * pow(2.0, (double)abscents / 1200.0)); } /* * convert from Hz to abstract cents */ int awe_Hz_to_abscent(int Hz) { return (int)(log((double)Hz / 8.176) / log(2.0) * 1200.0); } /*================================================================ * Emu8000 pitch offset conversion *================================================================*/ /* * Sample pitch offset for the specified sample rate * rate=44100 is no offset, each 4096 is 1 octave (twice). * eg, when rate is 22050, this offset becomes -4096. */ short awe_calc_rate_offset(int Hz) { if (Hz == 44100) return 0; return (short)(log((double)Hz / 44100) / log(2.0) * 4096.0); } /*================================================================ * initialize Emu8000 parameters *================================================================*/ void awe_init_voice(awe_voice_info *vp) { vp->sf_id = 0; vp->sample = 0; vp->start = 0; vp->end = 0; vp->loopstart = 0; vp->loopend = 0; vp->rate_offset = 0; vp->mode = 0; vp->root = 60; vp->tune = 0; vp->low = 0; vp->high = 127; vp->vellow = 0; vp->velhigh = 127; vp->fixkey = -1; vp->fixvel = -1; vp->fixpan = -1; vp->pan = -1; vp->exclusiveClass = 0; vp->amplitude = 127; vp->attenuation = 0; vp->scaleTuning = 100; awe_init_parm(&vp->parm); } void awe_init_parm(awe_voice_parm *pp) { pp->moddelay = 0x8000; pp->modatkhld = 0x7f7f; pp->moddcysus = 0x7f7f; pp->modrelease = 0x807f; pp->modkeyhold = 0; pp->modkeydecay = 0; pp->voldelay = 0x8000; pp->volatkhld = 0x7f7f; pp->voldcysus = 0x7f7f; pp->volrelease = 0x807f; pp->volkeyhold = 0; pp->volkeydecay = 0; pp->lfo1delay = 0x8000; pp->lfo2delay = 0x8000; pp->pefe = 0; pp->fmmod = 0; pp->tremfrq = 0; pp->fm2frq2 = 0; pp->cutoff = 0xff; pp->filterQ = 0; pp->chorus = 0; pp->reverb = 0; } /*================================================================ * Emu8000 parameters conversion *================================================================*/ /* * Delay time * sf: timecents * parm: 0x8000 - msec * 0.725 */ static int calc_delay_adip(int amount) { /* completely lost here! */ int delay,temp; if (amount <= -12000) return 0x8000; /* minimum delay */ delay = (amount+0x30E4)<<16; delay /= 1200; temp = 0x10000|(delay&0xffff); /* SI:BX */ delay >>= 16; temp >>= 16-(delay&0xff); delay = 0x8000 - temp; if (delay < -32768) delay = -32768; return delay; } static int calc_delay_trad(int tcents) { int msec = awe_timecent_to_msec(tcents); return (unsigned short)(0x8000 - msec * 1000 / 725); } unsigned short awe_calc_delay(int tcents) { if (awe_option.compatible) return calc_delay_trad(tcents); else return calc_delay_adip(tcents); } #ifdef LOOKUP_TABLE /* search an index for specified time from given time table */ static int calc_parm_search(int msec, short *table) { int left = 1, right = 127, mid; while (left < right) { mid = (left + right) / 2; if (msec < (int)table[mid]) left = mid + 1; else right = mid; } return left; } #endif /* * Attack and Hold time * This parameter is difficult... * * ADIP says: * bit15 = always 0 * upper byte = 0x7f - hold time / 92, max 11.68sec at 0, no hold at 0x7f. * bit7 = always 0 * lower byte = encoded attack time, 0 = never attack, * 1 = max 11.68sec, 0x7f = min 6msec. * * In VVSG, * if AttackTime_ms >= 360ms: * RegisterValue = 11878/AttackTime_ms - 1 * if AttackTime_ms < 360ms and AttackTime != 0: * RegisterValue = 32 + [16/log(2)] * log(360_ms/AttackTime_ms) * if AttackTime_ms == 0 * RegisterValue = 0x7F */ /* attack & decay/release time table (msec) */ #ifdef LOOKUP_TABLE static short attack_time_tbl[128] = { 32767, 32767, 5989, 4235, 2994, 2518, 2117, 1780, 1497, 1373, 1259, 1154, 1058, 970, 890, 816, 707, 691, 662, 634, 607, 581, 557, 533, 510, 489, 468, 448, 429, 411, 393, 377, 361, 345, 331, 317, 303, 290, 278, 266, 255, 244, 234, 224, 214, 205, 196, 188, 180, 172, 165, 158, 151, 145, 139, 133, 127, 122, 117, 112, 107, 102, 98, 94, 90, 86, 82, 79, 75, 72, 69, 66, 63, 61, 58, 56, 53, 51, 49, 47, 45, 43, 41, 39, 37, 36, 34, 33, 31, 30, 29, 28, 26, 25, 24, 23, 22, 21, 20, 19, 19, 18, 17, 16, 16, 15, 15, 14, 13, 13, 12, 12, 11, 11, 10, 10, 10, 9, 9, 8, 8, 8, 8, 7, 7, 7, 6, 0, }; static int calc_attack_adip(int amount) { int atkmsec = awe_timecent_to_msec(amount); return calc_parm_search(atkmsec, attack_time_tbl); } #else static int calc_attack_adip(int amount) { int attack,temp1,temp2; if (amount >= 4300) return 1; if (amount > -600) { attack = (amount + 500) / 150; temp1 = ((~attack) & 7) | 8; temp2 = attack >> 16; attack += temp2 & 7; attack >>= 3; temp1 >>= attack; if (temp1 < 1) temp1 = 1; return temp1; } attack = (37 - amount) / 75 + 8; if (attack >= 128) attack = 127; /* 128 */ return attack; } #endif static int calc_attack_trad(int atktime) { int atkmsec = awe_timecent_to_msec(atktime); int lw; if (atkmsec == 0) lw = 0x7f; else if (atkmsec >= 360) lw = (unsigned char)(11878 / atkmsec); else if (atkmsec < 360) lw = (unsigned char)(32 + 53.15085 * log10(360.0/atkmsec)); else lw = 0x7f; if (lw < 1) lw = 1; if (lw > 127) lw = 127; return lw; } static int calc_attack(int amount) { if (awe_option.compatible) return calc_attack_trad(amount); else return calc_attack_adip(amount); } static int calc_hold_adip(int amount) { int hold, temp; if (amount < -5368) return 127; /* maximum hold */ hold = (amount+4130)<<16; hold /= 1200; temp = 0x10000|(hold&0xffff); /* SI:BX */ hold >>= 16; temp >>= 16-(hold&0xff); hold = 127-temp; if (hold < 0) hold = 0; return hold; } static int calc_hold_trad(int hldtime) { int up, hldmsec = awe_timecent_to_msec(hldtime); up = (int)((0x7f * 92 - hldmsec) / 92); if (up < 1) up = 1; if (up > 127) up = 127; return up; } static int calc_hold(int hldtime) { if (awe_option.compatible) return calc_hold_trad(hldtime); else return calc_hold_adip(hldtime); } unsigned short awe_calc_atkhld(int atktime, int hldtime) { return (unsigned short)(calc_attack(atktime) | (calc_hold(hldtime) << 8)); } /* * Sustain level * sf: centibels * parm: 0x7f - sustain_level(dB) * 0.75 */ static int calc_sustain_adip(int amount) { int val = 127 - (amount * 127) / 1000; if (val < 0) return 0; else if (val > 127) return 127; else return val; } static int calc_sustain_trad(int sust_cB) { int up; /* sustain level */ if (sust_cB <= 0) return 0x7f; else if (sust_cB >= 1000) return 1; up = (0x7f * 40 - sust_cB * 3) / 40; /* sustain level must be greater than zero to be audible.. */ if (up < 1) up = 1; return up; } unsigned char awe_calc_sustain(int sust_cB) { if (awe_option.compatible) return calc_sustain_trad(sust_cB); else return calc_sustain_adip(sust_cB); } /* * Modulation sustain level * sf: 0.1% * parm: 0x7f - sustain_level(dB) * 0.75 */ static int calc_mod_sustain_adip(int amount) { int val = 127 - (amount * 127) / 1000; if (val < 0) return 0; else if (val > 127) return 127; else return val; } static int calc_mod_sustain_trad(int tenth_percent) { int up; if (tenth_percent < 0) tenth_percent = 0; else if (tenth_percent > 1000) tenth_percent = 1000; if (tenth_percent == 1000) up = 1; else { /*up = (int)(0x7f + 20.0 * 0.75 * log10((double)(1000 - tenth_percent) / 1000.0));*/ up = (0x7f * 40 - tenth_percent * 3) / 40; if (up < 1) up = 1; } return up; } unsigned char awe_calc_mod_sustain(int tenth_percent) { if (awe_option.compatible) return calc_mod_sustain_trad(tenth_percent); else return calc_mod_sustain_adip(tenth_percent); } /* * This parameter is also difficult to understand... * * ADIP says the value means decay rate, 0x7f minimum time is of 240usec/dB, * 0x01 being the max time of 470msec/dB, and 0 begin no decay. * * In VVSG, 2 * log(0.5) * log(23756/[ms]) (0x7F...0ms), but this is * obviously incorrect. But, the max time 23756 seems to be correct. * (actually, in NRPN control, decay time is within 0.023 and 23.7 secs.) * */ #ifdef LOOKUP_TABLE static short decay_time_tbl[128] = { 32767, 32767, 22614, 15990, 11307, 9508, 7995, 6723, 5653, 5184, 4754, 4359, 3997, 3665, 3361, 3082, 2828, 2765, 2648, 2535, 2428, 2325, 2226, 2132, 2042, 1955, 1872, 1793, 1717, 1644, 1574, 1507, 1443, 1382, 1324, 1267, 1214, 1162, 1113, 1066, 978, 936, 897, 859, 822, 787, 754, 722, 691, 662, 634, 607, 581, 557, 533, 510, 489, 468, 448, 429, 411, 393, 377, 361, 345, 331, 317, 303, 290, 278, 266, 255, 244, 234, 224, 214, 205, 196, 188, 180, 172, 165, 158, 151, 145, 139, 133, 127, 122, 117, 112, 107, 102, 98, 94, 90, 86, 82, 79, 75, 72, 69, 66, 63, 61, 58, 56, 53, 51, 49, 47, 45, 43, 41, 39, 37, 36, 34, 33, 31, 30, 29, 28, 26, 25, 24, 23, 22, }; static int calc_decay_adip(int amount) { int dcymsec = awe_timecent_to_msec(amount); return calc_parm_search(dcymsec, decay_time_tbl); } #else static int calc_decay_adip(int amount) { int decay, temp1, temp2; if (amount > 1800) { decay = (amount - 1800) / 150; temp1 = ((~decay) & 7) | 8; /* here, ASM code has high part of decay & 0x7 too, but we know that this is always clear since amount is between 1800 & 32767, therefore decay is 0..206 */ temp2 = decay >> 3; temp1 >>= temp2; decay = temp1; if (decay < 1) decay = 1; return decay; } /* here, amount < 1800 */ decay = (37 - amount) / 75 + 39; if (decay >= 128) decay = 127; return decay; } #endif static int calc_decay_trad(int dcytime) { int dcymsec = awe_timecent_to_msec(dcytime); int lw; /* decay time */ if (dcymsec == 0) lw = 127; else { /*lw = 0x7f - (int)((double)0x7f / 2.2 * log10(dcymsec / 23.04));*/ /* it looks almost ok.. */ lw = (int)(0x7f - awe_option.decay_sense * log10(dcymsec / 23.04)); /* ADIP way */ /* linear aprox; lw = 0x7f - ((dcymsec * 1000 / 100) * 0x7e) / (470000 - 240);*/ /* log aprox; lw = (int)(0x7f - 38.2759 * log10(dcymsec / 24.0)); */ /* same as above; lw = (int)(0x7f - 38.2759 * (dcytime * 0.30103 / 1200 + 1.61979));*/ } if (lw < 1) lw = 1; if (lw > 127) lw = 127; return lw; } unsigned char awe_calc_decay(int dcytime) { if (awe_option.compatible) return (unsigned char)calc_decay_trad(dcytime); else return (unsigned char)calc_decay_adip(dcytime); } /* * Cutoff frequency; return (0-255) * sf: abs cents (cents above 8.176Hz) * parm: quarter semitone; 0 = 125Hz, 0xff=8kHz? * (in VVS, cutoff(Hz) = value * 31.25 + 100) */ static int calc_cutoff_adip(int amount) { int cutoff = (amount+0xf)/0x1d-0x99; if (cutoff < 0) return 0; else if (cutoff > 255) return 255; else return cutoff; } static int calc_cutoff_trad(int abscents) { int cutoff; if (abscents == 0) /* no cutoff */ return 0xff; /*cutoff = abscents / 25 - 189;*/ cutoff = (abscents - 4721) / 25; /* 4721=125Hz */ if (cutoff < 0) cutoff = 0; if (cutoff > 255) cutoff = 255; return cutoff; } unsigned char awe_calc_cutoff(int abscents) { if (awe_option.compatible) return calc_cutoff_trad(abscents); else return calc_cutoff_adip(abscents); } /* * Initial filter Q; return (0-15) * sf: centibels above DC gain. * parm: 0 = no attenuation, 15 = 24dB */ static int calc_filterQ_adip(int amount) { int Q = amount/12; if (Q < 0) return 0; else if (Q > 15) return 15; else return Q; } static int calc_filterQ_trad(int gain_cB) { int Q; Q = (gain_cB * 2) / 30; if (Q < 0) Q = 0; else if (Q > 15) Q = 15; return (unsigned char)Q; } unsigned char awe_calc_filterQ(int gain_cB) { if (awe_option.compatible) return calc_filterQ_trad(gain_cB); else return calc_filterQ_adip(gain_cB); } /* * Pitch modulation height (0-255) * sf: cents, 100 = 1 semitone * parm: signed char, 0x80 = 1 octave */ static int calc_pitch_shift_adip(int amount) { int val = (amount * 0x1b4f) >> 16; if (val < -128) val = -128; else if (val > 127) val = 127; if (val < 0) return 0x100 + val; else return val; } static int calc_pitch_shift_trad(int cents) { int val; val = (cents * 0x80) / 1200; if (val < -128) val = -128; if (val > 127) val = 127; if (val < 0) return 0x100 + val; else return val; } unsigned char awe_calc_pitch_shift(int cents) { if (awe_option.compatible) return calc_pitch_shift_trad(cents); else return calc_pitch_shift_adip(cents); } /* * Filter cutoff modulation height (0-255) * sf: 1200 = +1 octave * par: 0x80 = +3(lfo1) or +6(modenv) octave */ static int calc_cutoff_shift_adip(int amount, int octave_shift) { int val; if (octave_shift == 3) val = (amount*0x0919)>>16; else val = (amount*0x048D)>>16; if (val < -128) val = -128; if (val > 127) val = 127; if (val < 0) return (unsigned char)(0x100 + val); else return (unsigned char)val; } static int calc_cutoff_shift_trad(int cents, int octave_shift) { int val; val = (cents * 0x80) / (octave_shift * 1200); if (val < -128) val = -128; if (val > 127) val = 127; if (val < 0) return (unsigned char)(0x100 + val); else return (unsigned char)val; } unsigned char awe_calc_cutoff_shift(int cents, int octave_shift) { if (awe_option.compatible) return calc_cutoff_shift_trad(cents, octave_shift); else return calc_cutoff_shift_adip(cents, octave_shift); } /* * Tremolo volume (0-255) * sf: cB, 10 = 1dB * parm: 0x7f = +/-12dB, 0x80 = -/+12dB */ static int calc_tremolo_adip(int amount) { int val = (amount << 7) / 0x78; if (val < -128) val = -128; if (val > 127) val = 127; if (val < 0) val = 0x100 + val; return (unsigned char)val; } static int calc_tremolo_trad(int vol_cB) { int val; val = (vol_cB * 0x80) / 120; if (val < -128) val = -128; if (val > 127) val = 127; if (val < 0) val = 0x100 + val; return (unsigned char)val; } unsigned short awe_calc_tremolo(int vol_cB) { if (awe_option.compatible) return calc_tremolo_trad(vol_cB); else return calc_tremolo_adip(vol_cB); } /* * Envelope/LFO frequency (0-255) * sf: cents * parm: mHz / 42 (42mHz step; 0xff=10.72Hz) */ static int calc_freq_adip(int amount) { int freq, temp; if (amount <= -16000) return 0; /* minimum freq. shift */ freq = (amount+0x23A6) << 16; freq /= 1200; temp = 0x10000|(freq&0xffff); /* DX:AX */ freq >>= 16; /* SI:BX */ temp >>= 16-(freq&0xff); if (temp > 255) temp = 255; return temp; } static int calc_freq_trad(int abscents) { int mHz, val; mHz = awe_abscent_to_mHz(abscents); val = mHz / 42; if (val < 0) val = 0; if (val > 255) val = 255; return val; } unsigned char awe_calc_freq(int abscents) { if (awe_option.compatible) return calc_freq_trad(abscents); else return calc_freq_adip(abscents); } /* * Panning position (0-127) * sf: (left) -500 - 500 (right) (0=center) * parm: (left) 0 - 127 (right), as same as MIDI parameter. * * NOTE: * The value above is converted in the driver to the actual emu8000 * parameter, 8bit, 0 (right) - 0xff (left). */ char awe_calc_pan(int val) { if (val < -500) return 0; else if (val > 500) val = 127; return (char)((val + 500) * 127 / 1000); } /* * Chorus strength * sf: 0 - 1000 (max) * parm: 0 - 255 (max) */ unsigned char awe_calc_chorus(int val) { if (val < 0) return 0; else if (val > 1000) val = 255; return (unsigned char)(val * 255 / 1000); } /* * Reverb strength * sf: 0 - 1000 (max) * parm: 0 - 255 (max) */ unsigned char awe_calc_reverb(int val) { if (val < 0) return 0; else if (val > 1000) val = 255; return (unsigned char)(val * 255 / 1000); } /* * Initial volume attenuation (0-255) * sf: centibels, eg. 60 = 6dB below from full scale * parm: dB * 8 / 3 */ static int calc_attenuation_adip(int amount) { int atten; atten = (amount + 12) / 24; atten = (atten * 8) / 3; if (atten > 255) atten = 255; if (atten < 0) atten = 0; return atten; } static int calc_attenuation_trad(int att_cB) { att_cB = (int)(att_cB / awe_option.atten_sense); if (att_cB < 0) return 0; else if (att_cB > 956) return 255; return (unsigned char)(att_cB * 8 / 30); } unsigned char awe_calc_attenuation(int att_cB) { if (awe_option.compatible) return calc_attenuation_trad(att_cB); else return calc_attenuation_adip(att_cB); } awesfx-0.5.2/awelib/bool.c000066400000000000000000000056321344644735400154010ustar00rootroot00000000000000/*================================================================ * check boolean string * * Copyright (C) 1996-1999 Takashi Iwai * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *================================================================*/ #include #include #include #include #include "util.h" /* search delimiers */ char *strschr(char *str, char *dels) { char *p; for (p = str; *p; p++) { if (strchr(dels, *p)) return p; } return NULL; } /* case insensitive comparison */ int strlcmp(char *ap, char *bp) { int a, b; for (;;) { a = tolower(*ap); b = tolower(*bp); if (a != b) return (a - b); if (a == 0) return 0; ap++; bp++; } } /* check boolean string; on, true, yes */ int bool_val(char *val) { if (strlcmp(val, "on") == 0 || strlcmp(val, "true") == 0 || strlcmp(val, "yes") == 0) return 1; else if (strlcmp(val, "off") == 0 || strlcmp(val, "false") == 0 || strlcmp(val, "no") == 0) return 0; else return (int)strtol(val, NULL, 0); } /*================================================================ * get a token separated by space letters * almost equal with strtok(str, spaces) but this checks quote * letters. *================================================================*/ #define DELIM " \t\n\r" static void remove_letter(char *p) { if (! *p) return; for (;; p++) { *p = p[1]; if (! *p) return; } } char *strtoken(char *src) { static char *buf = NULL, *vptr; char *retptr; if (src) { if (buf) free(buf); buf = safe_strdup(src); vptr = buf; } else if (buf == NULL) { fprintf(stderr, "illegal strtoken call\n"); exit(1); } /* skip delimiters at head */ while (*vptr && strchr(DELIM, *vptr)) vptr++; if (!*vptr) return NULL; retptr = vptr; while (*vptr && strchr(DELIM, *vptr) == NULL) { if (*vptr == '\\') { remove_letter(vptr); if (!*vptr) break; vptr++; } else if (*vptr == '"' || *vptr == '\'') { int prev, quote; prev = quote = *vptr; remove_letter(vptr); for (; *vptr; prev = *vptr, vptr++) { if (*vptr == '\\') { remove_letter(vptr); if (*vptr) break; } else if (*vptr == quote) { remove_letter(vptr); break; } } } else vptr++; } if (*vptr) *vptr++ = 0; return retptr; } awesfx-0.5.2/awelib/cmpopen.c000066400000000000000000000060011344644735400160760ustar00rootroot00000000000000/*================================================================ * cmpopen.c: * search / open a compressed file * * Copyright (C) 1996-1999 Takashi Iwai * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *================================================================*/ #include #include #include #include "util.h" typedef struct _DecompRec { char *ext; char *format; } DecompRec; typedef struct _DecompList { DecompRec v; struct _DecompList *next; } DecompList; static DecompRec declist[] = { {".gz", "gunzip -c"}, {".z", "gunzip -c"}, {".Z", "zcat"}, {".zip", "unzip -p"}, {".lha", "lha -pq"}, {".lzh", "lha -pq"}, {".bz2", "bzip2 -d -c"}, }; static DecompList *decopts = NULL; void CmpAddList(char *ext, char *format) { DecompList *rec; rec = (DecompList*)safe_malloc(sizeof(DecompList)); if (*ext != '.') { rec->v.ext = (char*)safe_malloc(strlen(ext) + 2); rec->v.ext[0] = '.'; strcpy(rec->v.ext + 1, ext); } else rec->v.ext = safe_strdup(ext); rec->v.format = safe_strdup(format); rec->next = decopts; decopts = rec; } static int CheckExt(char *name, int len, DecompRec *p) { int exlen = strlen(p->ext); if (len > exlen && strcmp(name + (len - exlen), p->ext) == 0) return TRUE; else return FALSE; } static DecompRec *CmpSearchFile(char *name) { int i, len; DecompList *p; if (access(name, R_OK) != 0) return NULL; len = strlen(name); for (p = decopts; p; p = p->next) { if (CheckExt(name, len, &p->v)) return &p->v; } for (i = 0; i < numberof(declist); i++) { if (CheckExt(name, len, &declist[i])) return &declist[i]; } return NULL; } char *CmpGetExtension(char *name) { DecompRec *rec; if ((rec = CmpSearchFile(name)) != NULL) { return name + strlen(name) - strlen(rec->ext); } return strrchr(name, '.'); } FILE *CmpOpenFile(char *name, int *flag) { FILE *fp; DecompRec *rec; char str[256]; *flag = 0; if (strcmp(name, "-") == 0) { /* use standard input */ *flag = 2; return stdin; } if ((rec = CmpSearchFile(name)) != NULL) { if (strstr(rec->format, "%s") != NULL) sprintf(str, rec->format, name); else sprintf(str, "%s \"%s\"", rec->format, name); if ((fp = popen(str, "r")) != NULL) { *flag = 1; return fp; } } return fopen(name, "r"); } void CmpCloseFile(FILE *fp, int flag) { switch (flag) { case 0: fclose(fp); break; case 1: pclose(fp); break; } } awesfx-0.5.2/awelib/dummy.c000066400000000000000000000000511344644735400155670ustar00rootroot00000000000000int awe_verbose = 0; /* verbose flag */ awesfx-0.5.2/awelib/dynload.c000066400000000000000000000070421344644735400160750ustar00rootroot00000000000000/*---------------------------------------------------------------- * partial loading mechanism * * Copyright (C) 1996-1999 Takashi Iwai * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *----------------------------------------------------------------*/ #include #include #include #include #include "util.h" #include "aweseq.h" static void set_preset(SFPatchRec *pat, char *arg); /*----------------------------------------------------------------*/ LoadList *awe_add_loadlist(LoadList *list, SFPatchRec *pat, SFPatchRec *map) { LoadList *rec; rec = (LoadList*)safe_malloc(sizeof(LoadList)); rec->pat = *pat; if (map) rec->map = *map; else rec->map = *pat; rec->loaded = FALSE; rec->next = list; return rec; } /* add the elements in the latter list to the former one */ LoadList *awe_merge_loadlist(LoadList *list, LoadList *old) { LoadList *p; for (p = old; p; p = p->next) { list = awe_add_loadlist(list, &p->pat, &p->map); list->loaded = p->loaded; } return list; } /* free all the elements in the list */ void awe_free_loadlist(LoadList *p) { LoadList *next; for (; p; p = next) { next = p->next; safe_free(p); } } /* parse source and mapping presets and return the remaining string; * the original argument will be broken */ int awe_parse_loadlist(char *arg, SFPatchRec *pat, SFPatchRec *map, char **strp) { char *next; if ((next = strschr(arg, ":=")) != NULL) *next++ = 0; set_preset(pat, arg); if (next == NULL) { *map = *pat; if (strp) *strp = NULL; return TRUE; } arg = next; if ((next = strschr(arg, ":=")) != NULL) *next++ = 0; set_preset(map, arg); if (strp) *strp = next; return TRUE; } /* ascii to digit; accept * and - characters */ static int parse_arg(char *arg) { if (isdigit(*arg)) return atoi(arg); else return -1; } /* parse preset/bank/keynote */ static void set_preset(SFPatchRec *pat, char *arg) { char *next; if ((next = strschr(arg, "/: \t\n")) != NULL) *next++ = 0; pat->preset = parse_arg(arg); pat->bank = 0; pat->keynote = -1; arg = next; if (arg) { if ((next = strschr(arg, "/: \t\n")) != NULL) *next++ = 0; pat->bank = parse_arg(arg); if (next) pat->keynote = parse_arg(next); } } /* check the preset matches to the given pattern (rec) */ int awe_match_preset(SFPatchRec *rec, SFPatchRec *pat) { if (rec->preset != -1 && pat->preset != -1 && rec->preset != pat->preset) return FALSE; if (rec->bank != -1 && pat->bank != -1 && rec->bank != pat->bank) return FALSE; if (rec->keynote != -1 && pat->keynote != -1 && rec->keynote != pat->keynote) return FALSE; return TRUE; } /* merge two matching bank/preset/key records */ void awe_merge_keys(SFPatchRec *p1, SFPatchRec *p2, SFPatchRec *rec) { rec->bank = (p1->bank == -1 ? p2->bank : p1->bank); rec->preset = (p1->preset == -1 ? p2->preset : p1->preset); rec->keynote = (p1->keynote == -1 ? p2->keynote : p1->keynote); } awesfx-0.5.2/awelib/fskip.c000066400000000000000000000022421344644735400155540ustar00rootroot00000000000000/*---------------------------------------------------------------- * skip file position * * Copyright (C) 1996-1999 Takashi Iwai * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *----------------------------------------------------------------*/ #include void fskip(int size, FILE *fd, int seekable) { if (seekable) fseek(fd, size, SEEK_CUR); else { char tmp[1024]; while (size >= (int)sizeof(tmp)) { size -= fread(tmp, 1, sizeof(tmp), fd); } while (size > 0) size -= fread(tmp, 1, size, fd); } } awesfx-0.5.2/awelib/gentxt.c000066400000000000000000000070311344644735400157520ustar00rootroot00000000000000/*================================================================ * generator label table * * Copyright (C) 1996-1999 Takashi Iwai * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *================================================================*/ #include "sflayer.h" char *sf_gen_text[SF_EOF] = { "startAddrs", /* sample start address -4 (0 to * 0xffffff) */ "endAddrs", "startloopAddrs", /* loop start address -4 (0 to * 0xffffff) */ "endloopAddrs", /* loop end address -3 (0 to * 0xffffff) */ "startAddrsHi", /* high word of startAddrs */ "lfo1ToPitch", /* main fm: lfo1-> pitch */ "lfo2ToPitch", /* aux fm: lfo2-> pitch */ "env1ToPitch", /* pitch env: env1(aux)-> pitch */ "initialFilterFc", /* initial filter cutoff */ "initialFilterQ", /* filter Q */ "lfo1ToFilterFc", /* filter modulation: lfo1 -> filter * cutoff */ "env1ToFilterFc", /* filter env: env1(aux)-> filter * cutoff */ "endAddrsHi", /* high word of endAddrs */ "lfo1ToVolume", /* tremolo: lfo1-> volume */ "env2ToVolume", /* Env2Depth: env2-> volume */ "chorusEffectsSend", /* chorus */ "reverbEffectsSend", /* reverb */ "panEffectsSend", /* pan */ "auxEffectsSend", /* pan auxdata (internal) */ "sampleVolume", /* used internally */ "unused3", "delayLfo1", /* delay 0x8000-n*(725us) */ "freqLfo1", /* frequency */ "delayLfo2", /* delay 0x8000-n*(725us) */ "freqLfo2", /* frequency */ "delayEnv1", /* delay 0x8000 - n(725us) */ "attackEnv1", /* attack */ "holdEnv1", /* hold */ "decayEnv1", /* decay */ "sustainEnv1", /* sustain */ "releaseEnv1", /* release */ "autoHoldEnv1", "autoDecayEnv1", "delayEnv2", /* delay 0x8000 - n(725us) */ "attackEnv2", /* attack */ "holdEnv2", /* hold */ "decayEnv2", /* decay */ "sustainEnv2", /* sustain */ "releaseEnv2", /* release */ "autoHoldEnv2", "autoDecayEnv2", "instrument", /* */ "nop", "keyRange", /* */ "velRange", /* */ "startloopAddrsHi", /* high word of startloopAddrs */ "keynum", /* */ "velocity", /* */ "initAtten", /* */ "keyTuning", "endloopAddrsHi", /* high word of endloopAddrs */ "coarseTune", "fineTune", "sampleId", "sampleFlags", "samplePitch", /* SF1 only */ "scaleTuning", "keyExclusiveClass", "rootKey", }; awesfx-0.5.2/awelib/loadbank.c000066400000000000000000000342311344644735400162160ustar00rootroot00000000000000/*================================================================ * load soundfont and virtual bank * * Copyright (C) 1996-1999 Takashi Iwai * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *================================================================*/ #include #include #include #include #ifdef linux #include #else #include #endif #include #include "util.h" #include "awebank.h" #include "aweseq.h" #include "sfopts.h" #include "config.h" /*---------------------------------------------------------------- * prototypes *----------------------------------------------------------------*/ /* virtual bank record */ typedef struct _VBank { char *name; LoadList *list; struct _VBank *next; } VBank; static int is_virtual_bank(char *path); static int load_virtual_bank(AWEOps *ops, char *path, LoadList *part_list, int locked); static int load_patch(AWEOps *ops, char *path, LoadList *lp, LoadList *exlp, int locked, int load_alt); static int load_map(AWEOps *ops, LoadList *lp, int locked); static LoadList *make_virtual_list(VBank *v, LoadList *part_list); static void make_bank_table(FILE *fp); static void include_bank_table(char *name); static void free_bank_table(void); static int do_load_all_banks(AWEOps *ops, int locked); static int do_load_banks(AWEOps *ops, int locked); static void mark_loaded_presets(LoadList *pat, LoadList *list); static LoadList *find_list(LoadList *list, SFPatchRec *pat); static int find_matching_map(SFPatchRec *pat, int level); static int find_matching_in_list(SFPatchRec *pat, LoadList *vlist, int level); /*----------------------------------------------------------------*/ /* extensions to be searched */ static char *path_ext[] = { ".sf2", ".SF2", ".sbk", ".SBK", NULL, }; static char *path_ext_all[] = { ".bnk", ".sf2", ".SF2", ".sbk", ".SBK", NULL, }; static char *path_ext_bank[] = { ".bnk", NULL, }; /* search path for font and bank files */ static char *search_path; /*---------------------------------------------------------------- * load arbitrary file with specified loading list *----------------------------------------------------------------*/ int awe_load_bank(AWEOps *ops, char *name, LoadList *list, int locked) { int rc; char sfpath[256]; /* set default search path */ if (awe_option.search_path) search_path = safe_strdup(awe_option.search_path); else { char *p = getenv("SFBANKDIR"); if (p == NULL || *p == 0) p = DEFAULT_SF_PATH; search_path = safe_strdup(p); } if (awe_search_file_name(sfpath, sizeof(sfpath), name, search_path, path_ext_all)) { if (is_virtual_bank(sfpath)) rc = load_virtual_bank(ops, sfpath, list, locked); else rc = load_patch(ops, name, list, NULL, locked, TRUE); } else rc = AWE_RET_NOT_FOUND; /* release search path */ free(search_path); return rc; } /*---------------------------------------------------------------- * virtual bank record handlers *----------------------------------------------------------------*/ static VBank *vbanks, *vmap, *vmapkey; static char *default_font; static LoadList *bank_list, *excl_list; /* check the extension */ static int is_virtual_bank(char *path) { char *p; if ((p = strrchr(path, '.')) == NULL) return FALSE; if (strcmp(p + 1, "bnk") == 0) return TRUE; return FALSE; } /* read a virtual bank config file and load the specified fonts */ static int load_virtual_bank(AWEOps *ops, char *path, LoadList *part_list, int locked) { int rc; FILE *fp; if ((fp = fopen(path, "r")) == NULL) { fprintf(stderr, "awe: can't open virtual bank %s\n", path); return AWE_RET_ERR; } vbanks = NULL; vmap = vmapkey = NULL; default_font = NULL; bank_list = awe_merge_loadlist(NULL, part_list); /* copy the list */ excl_list = NULL; make_bank_table(fp); fclose(fp); if (bank_list) rc = do_load_banks(ops, locked); /* loading partial fonts */ else rc = do_load_all_banks(ops, locked); /* loading all fonts */ if (default_font) free(default_font); if (bank_list) awe_free_loadlist(bank_list); if (excl_list) awe_free_loadlist(excl_list); free_bank_table(); return rc; } /* load the whole virtual banks */ static int do_load_all_banks(AWEOps *ops, int locked) { int rc; VBank *v; if (vmap || vmapkey) { /* load preset mapping to the driver */ if (vmap) { rc = load_map(ops, vmap->list, locked); if (rc == AWE_RET_ERR || rc == AWE_RET_NOMEM) return rc; /* add the loaded presets to exclusive list */ excl_list = awe_merge_loadlist(excl_list, vmap->list); } if (vmapkey) { rc = load_map(ops, vmapkey->list, locked); if (rc == AWE_RET_ERR || rc == AWE_RET_NOMEM) return rc; /* add the loaded presets to exclusive list */ excl_list = awe_merge_loadlist(excl_list, vmapkey->list); } } /* load each soundfont file */ for (v = vbanks; v; v = v->next) { if (v->list == NULL) continue; /* append the defined instruments to exclusive list */ excl_list = awe_merge_loadlist(excl_list, v->list); /* load this file */ rc = load_patch(ops, v->name, v->list, NULL, locked, FALSE); if (rc == AWE_RET_ERR || rc == AWE_RET_NOMEM) return rc; } if (default_font) /* load all the fonts except for pre-loaded fonts */ return load_patch(ops, default_font, NULL, excl_list, locked, TRUE); return AWE_RET_OK; } /* load banks by dynamic loading */ static int do_load_banks(AWEOps *ops, int locked) { int rc; LoadList *vlist, *p; VBank *v; /* load preset mapping if any.. */ if (vmap) { rc = load_map(ops, vmap->list, locked); if (rc == AWE_RET_ERR || rc == AWE_RET_NOMEM) return rc; } if (vmapkey) { rc = load_map(ops, vmapkey->list, locked); if (rc == AWE_RET_ERR || rc == AWE_RET_NOMEM) return rc; } /* mark the matching presets in the list */ for (p = bank_list; p; p = p->next) { if (! p->loaded) { if (find_matching_map(&p->map, 0)) p->loaded = TRUE; } } /* load each soundfont file */ for (v = vbanks; v; v = v->next) { vlist = make_virtual_list(v, bank_list); if (vlist == NULL) continue; rc = load_patch(ops, v->name, vlist, NULL, locked, TRUE); awe_free_loadlist(vlist); if (rc == AWE_RET_ERR || rc == AWE_RET_NOMEM) return rc; mark_loaded_presets(vlist, bank_list); } if (default_font) { /* load rest of font lists */ /* make the list of fonts not loaded */ vlist = NULL; for (p = bank_list; p; p = p->next) { if (!p->loaded) vlist = awe_add_loadlist(vlist, &p->pat, &p->map); } if (vlist == NULL) /* all fonts have been loaded */ return AWE_RET_OK; /* load them */ rc = load_patch(ops, default_font, vlist, NULL, locked, TRUE); awe_free_loadlist(vlist); return rc; } return AWE_RET_OK; } /* mark the presets as actually loaded */ static void mark_loaded_presets(LoadList *pat, LoadList *list) { LoadList *p, *q; for (p = pat; p; p = p->next) { if (! p->loaded) continue; for (q = list; q; q = q->next) { if (!q->loaded && awe_match_preset(&p->map, &q->map)) q->loaded = TRUE; } } } /* search the matching element with pat */ static LoadList *find_list(LoadList *list, SFPatchRec *pat) { LoadList *p; for (p = list; p; p = p->next) { if (awe_match_preset(&p->map, pat)) return p; } return NULL; } /* if the given pattern matches to an element in the given list, * reutrn TRUE. the mapped pattern is recursively searched. * if additional instrument is necessary to be loaded, prepend it * to the loading list. */ static int find_matching_in_list(SFPatchRec *pat, LoadList *vlist, int level) { LoadList *p, *curp; SFPatchRec tmp; for (p = vlist; p; p = p->next) { if (! p->loaded) continue; if (awe_match_preset(&p->map, pat)) { if (find_list(bank_list, &p->pat)) return TRUE; tmp = p->pat; if (tmp.keynote == -1) tmp.keynote = pat->keynote; bank_list = curp = awe_add_loadlist(bank_list, &tmp, NULL); if (find_matching_map(&curp->map, level+1)) curp->loaded = TRUE; return TRUE; } } return FALSE; } #define MAX_RECURSIVE_LEVEL 10 /* if the given pattern matches to an element in mapping list, * return TRUE. the mapped pattern will be further searched * in the mapping list. */ static int find_matching_map(SFPatchRec *pat, int level) { if (level >= MAX_RECURSIVE_LEVEL) return TRUE; if (vmapkey) { if (find_matching_in_list(pat, vmapkey->list, level)) return TRUE; } if (vmap) { if (find_matching_in_list(pat, vmap->list, level)) return TRUE; } return FALSE; } /* make part list for each virtual bank */ static LoadList *make_virtual_list(VBank *v, LoadList *part_list) { LoadList *p, *q, *list; list = NULL; for (p = part_list; p; p = p->next) { if (p->loaded) continue; for (q = v->list; q; q = q->next) { if (awe_match_preset(&p->pat, &q->map)) { SFPatchRec src, map; awe_merge_keys(&q->pat, &p->pat, &src); awe_merge_keys(&q->map, &p->map, &map); list = awe_add_loadlist(list, &src, &map); } } } return list; } /* read a virtual bank config file and build bank table */ static void make_bank_table(FILE *fp) { char line[256], *p, *name; SFPatchRec pat, map; VBank *v; int len; while (fgets(line, sizeof(line), fp)) { /* discard the linefeed */ len = strlen(line); if (len > 0 && line[len-1] == '\n') line[len-1] = 0; /* skip spaces & comments */ for (p = line; isspace(*p); p++) ; if (!*p || *p == '#' || *p == '!' || *p == '%') continue; if (isalpha(*p)) { char *arg; arg = strschr(p, " \t\r\n"); if (arg) { char *tmp = strschr(arg, " \t\r\n"); if (tmp) *tmp = 0; arg++; } switch (*p) { case 'i': case 'I': /* include other bank file */ include_bank_table(arg); break; case 'd': case 'D': /* set default font file */ if (default_font) free(default_font); default_font = safe_strdup(arg); break; default: fprintf(stderr, "awe: illegal bank command %s", line); break; } continue; } else if (*p == '*' || *p == '-' || isdigit(*p)) { if (! awe_parse_loadlist(p, &pat, &map, &name)) continue; } else continue; if (name && *name) { /* discard garbage letters */ if ((p = strschr(name, " \t\n#")) != NULL) *p = 0; } if (name == NULL || !*name) { /* without font name -- this is a preset link */ if (map.keynote != -1) v = vmapkey; else v = vmap; if (v == NULL) { /* the list is not created.. */ v = (VBank*)safe_malloc(sizeof(VBank)); v->list = NULL; v->name = NULL; if (map.keynote != -1) vmapkey = v; else vmap = v; } } else { /* search the list matching the font name */ for (v = vbanks; v; v = v->next) { if (strcmp(v->name, name) == 0) break; } if (v == NULL) { /* not found -- create a new list */ v = (VBank*)safe_malloc(sizeof(VBank)); v->list = NULL; v->name = safe_strdup(name); v->next = vbanks; vbanks = v; } } /* append the current record */ v->list = awe_add_loadlist(v->list, &pat, &map); } } /* include another bank file */ static void include_bank_table(char *name) { char path[256]; FILE *fp; if (awe_search_file_name(path, sizeof(path), name, search_path, path_ext_bank) && (fp = fopen(path, "r")) != NULL) { make_bank_table(fp); fclose(fp); } else { fprintf(stderr, "awe: can't include bank file %s\n", name); } } /* free bank record table */ static void free_bank_table(void) { VBank *v, *next; for (v = vbanks; v; v = next) { next = v->next; if (v->name) safe_free(v->name); awe_free_loadlist(v->list); safe_free(v); } vbanks = NULL; if (vmap) { /* this has no name */ awe_free_loadlist(vmap->list); safe_free(vmap); } if (vmapkey) { /* this has no name */ awe_free_loadlist(vmapkey->list); safe_free(vmapkey); } } /*---------------------------------------------------------------- * load sample & info on the sound driver *---------------------------------------------------------------- * name = file name of soudnfont file (without path) * lp = loading list (NULL = all) * exlp = excluding list (NULL = none) * locked = flag for remove lock * load_alt = load altenatives for missing fonts *----------------------------------------------------------------*/ static int load_patch(AWEOps *ops, char *name, LoadList *lp, LoadList *exlp, int locked, int load_alt) { FILE *fd; char path[256]; int rc; static SFInfo sfinfo; if (! awe_search_file_name(path, sizeof(path), name, search_path, path_ext)) { fprintf(stderr, "awe: can't find font file %s\n", name); return AWE_RET_SKIP; } if ((fd = fopen(path, "r")) == NULL) { fprintf(stderr, "awe: can't open SoundFont file %s\n", path); return AWE_RET_SKIP; } if (awe_load_soundfont(&sfinfo, fd, TRUE) < 0) { fprintf(stderr, "awe: can't load SoundFont %s\n", path); return AWE_RET_SKIP; } awe_correct_samples(&sfinfo); awe_open_font(ops, &sfinfo, fd, locked); /*rc = awe_load_font_buffered(&sfinfo, lp, exlp, load_alt);*/ if (lp) rc = awe_load_font_list(ops, &sfinfo, lp, load_alt); else rc = awe_load_all_fonts(ops, &sfinfo, exlp); awe_close_font(ops, &sfinfo); awe_free_soundfont(&sfinfo); if (fd) fclose(fd); return rc; } /*---------------------------------------------------------------- * load preset links *----------------------------------------------------------------*/ static int load_map(AWEOps *ops, LoadList *lp, int locked) { int rc; if (awe_open_patch(ops, "*MAP*", AWE_PAT_TYPE_MAP, locked) < 0) { fprintf(stderr, "awe: can't access to sequencer\n"); return AWE_RET_SKIP; } for (; lp; lp = lp->next) { if ((rc = awe_load_map(ops, lp)) != AWE_RET_OK) return rc; lp->loaded = TRUE; } awe_close_patch(ops); return AWE_RET_OK; } awesfx-0.5.2/awelib/loadtext.c000066400000000000000000000163311344644735400162700ustar00rootroot00000000000000/*================================================================ * loadtext.c: * load textized soundfont information * * Copyright (C) 1996-1999 Takashi Iwai * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *================================================================*/ #include #include #include "slist.h" #include "util.h" #include "sffile.h" #include "sflayer.h" /*---------------------------------------------------------------- * prototypes *----------------------------------------------------------------*/ static void load_sflist(SFInfo *sf, SList list); static void load_preset(SFInfo *sf, SList at); static void load_inst(SFInfo *lp, SList at); static void load_layers(SFHeader *hdr, SList at); static void load_lists(SFGenLayer *lay, SList at); static int sf_index(char *str); static void load_sample(SFInfo *sf, SList at); /*---------------------------------------------------------------- * load the text file *----------------------------------------------------------------*/ void awe_load_textinfo(SFInfo *sf, FILE *fp) { SList list; while ((list = SReadFile(fp)) != NIL) { /*print_list(list);*/ load_sflist(sf, list); SFree(list); } } /*---------------------------------------------------------------- * parse a list *----------------------------------------------------------------*/ static void load_sflist(SFInfo *sf, SList list) { if (! SListP(list)) return; list = SCar(list); if (! SFunP(list)) return; if (SFunIs(list, "Name")) { sf->sf_name = safe_strdup(SStr(SCdr(list))); } else if (SFunIs(list, "SamplePos")) { sf->samplepos = SInt(SCdr(list)); sf->samplesize = SInt(SCdr(SCdr(list))); } else if (SFunIs(list, "SoundFont")) { sf->version = SInt(SCdr(list)); sf->minorversion = SInt(SCdr(SCdr(list))); } else if (SFunIs(list, "InfoPos")) { sf->infopos = SInt(SCdr(list)); sf->infosize = SInt(SCdr(SCdr(list))); } else if (SFunIs(list, "Presets")) { load_preset(sf, SCdr(list)); } else if (SFunIs(list, "Instruments")) { load_inst(sf, SCdr(list)); } else if (SFunIs(list, "SampleInfo")) { load_sample(sf, SCdr(list)); } else { fprintf(stderr, "unknown tag %s\n", SFun(list)); } } /*---------------------------------------------------------------- * parse preset list *----------------------------------------------------------------*/ static void load_preset(SFInfo *sf, SList at) { int i; SFPresetHdr *p; for (; at != NIL && !SListP(at); at = SCdr(at)) ; if (at == NIL) return; if ((sf->npresets = SIndex(at)) <= 0) { sf->npresets = 0; return; } sf->preset = (SFPresetHdr*)safe_malloc (sizeof(SFPresetHdr) * sf->npresets); at = SCar(at); p = sf->preset; for (i = 0; i < sf->npresets && at != NIL; i++) { SList list = SCar(at); list = SCdr(list); /* skip index */ strncpy(p->hdr.name, SStr(list), 20); list = SCdr(list); p->preset = SInt(SCdr(SCar(list))); list = SCdr(list); p->bank = SInt(SCdr(SCar(list))); list = SCdr(list); load_layers(&p->hdr, list); at = SCdr(at); p++; } } /*---------------------------------------------------------------- * parse instrument list *----------------------------------------------------------------*/ static void load_inst(SFInfo *sf, SList at) { int i; SFInstHdr *p; for (; at != NIL && !SListP(at); at = SCdr(at)) ; if (at == NIL) return; if ((sf->ninsts = SIndex(at)) <= 0) { sf->ninsts = 0; return; } sf->inst = (SFInstHdr*)safe_malloc(sizeof(SFInstHdr) * sf->ninsts); at = SCar(at); p = sf->inst; for (i = 0; i < sf->ninsts && at != NIL; i++) { SList list = SCar(at); list = SCdr(list); /* skip index */ strncpy(p->hdr.name, SStr(list), 20); list = SCdr(list); load_layers(&p->hdr, list); at = SCdr(at); p++; } } /*---------------------------------------------------------------- * parse preset/inst layer list *----------------------------------------------------------------*/ static void load_layers(SFHeader *hdr, SList at) { int i; SFGenLayer *p; if ((hdr->nlayers = SIndex(at)) <= 0) { hdr->nlayers = 0; return; } hdr->layer = (SFGenLayer*)safe_malloc(sizeof(SFGenLayer) * hdr->nlayers); p = hdr->layer; at = SCar(at); for (i = 0; i < hdr->nlayers; i++) { load_lists(p, at); p++; at = SCdr(at); } } /*---------------------------------------------------------------- * parse layered elements *----------------------------------------------------------------*/ static void load_lists(SFGenLayer *lay, SList at) { int i; SFGenRec *p; lay->nlists = SIndex(at) - 1; if (lay->nlists < 0) { lay->nlists = 0; lay->list = NULL; return; } lay->list = (SFGenRec*)safe_malloc(sizeof(SFGenRec) * lay->nlists); p = lay->list; at = SCdr(SCar(at)); for (i = 0; i < lay->nlists; i++) { SList list = SCar(at); p->oper = sf_index(SFun(list)); p->amount = SInt(SCdr(list)); p++; at = SCdr(at); } } /*---------------------------------------------------------------- * convert string to SF id number *----------------------------------------------------------------*/ static int sf_index(char *str) { int i; for (i = 0; i < SF_EOF; i++) { if (strcmp(sf_gen_text[i], str) == 0) return i; } return SF_EOF; } /*---------------------------------------------------------------- * parse sample info list *----------------------------------------------------------------*/ static void load_sample(SFInfo *sf, SList at) { int i; SFSampleInfo *p; int in_rom; for (; at != NIL && !SListP(at); at = SCdr(at)) ; if (at == NIL) return; if ((sf->nsamples = SIndex(at)) <= 0) { sf->nsamples = 0; return; } sf->sample = (SFSampleInfo*)safe_malloc (sizeof(SFSampleInfo) * sf->nsamples); at = SCar(at); p = sf->sample; in_rom = 1; /* data may start from ROM samples */ for (i = 0; i < sf->nsamples; i++) { SList list = SCar(at); list = SCdr(list); /* skip index */ strncpy(p->name, SStr(list), 20); list = SCdr(list); p->startsample = SInt(SCar(list)); p->endsample = SInt(SCdr(SCar(list))); list = SCdr(list); p->startloop = SInt(SCar(list)); p->endloop = SInt(SCdr(SCar(list))); list = SCdr(list); if (list != NIL && sf->version > 1) { list = SCar(list); p->samplerate = SInt(list); list = SCdr(list); p->originalPitch = SInt(list); list = SCdr(list); p->pitchCorrection = SInt(list); list = SCdr(list); p->samplelink = SInt(list); list = SCdr(list); p->sampletype = SInt(list); } else { p->samplerate = 44100; p->originalPitch = 60; p->pitchCorrection = 0; p->samplelink = 0; /* the first RAM data starts from address 0 */ if (p->startsample == 0) in_rom = 0; if (in_rom) p->sampletype = 0x8001; else p->sampletype = 1; } p++; at = SCdr(at); } } awesfx-0.5.2/awelib/malloc.c000066400000000000000000000025141344644735400157110ustar00rootroot00000000000000/*================================================================ * safe malloc routine * * Copyright (C) 1996-1999 Takashi Iwai * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *================================================================*/ #include #include #include #include void *safe_malloc(int size) { void *p; p = (void*)calloc(size, 1); if (p == NULL) { fprintf(stderr, "can't malloc buffer for size %d!!\n", size); exit(1); } return p; } void safe_free(void *buf) { if (buf) free(buf); } char *safe_strdup(char *src) { char *p; if ((p = strdup(src)) == NULL) { fprintf(stderr, "can't strdup\n"); exit(1); } return p; } awesfx-0.5.2/awelib/optfile.c000066400000000000000000000131641344644735400161070ustar00rootroot00000000000000/*---------------------------------------------------------------- * parse options * * Copyright (C) 1996-1999 Takashi Iwai * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *----------------------------------------------------------------*/ #include #include #include #include #include "util.h" #include "sfopts.h" #include "config.h" #define SYSTEM_RCFILE "/etc/sfxloadrc" #define RCFILE ".sfxloadrc" #define DEFAULT_ID "default" typedef struct OptionFile { int argc; char **argv; struct OptionFile *next; } OptionFile; static OptionFile *optlist = NULL; #define MAX_ARGC 100 static void read_option_file(void) { char *p, rcfile[256]; char line[256]; FILE *fp; OptionFile *rec; *rcfile = 0; if ((p = getenv("HOME")) != NULL && *p) { snprintf(rcfile, sizeof(rcfile), "%s/%s", p, RCFILE); if (access(rcfile, R_OK) != 0) rcfile[0] = 0; } if (! *rcfile) { #ifdef SYSTEM_RCFILE strcpy(rcfile, SYSTEM_RCFILE); if (access(rcfile, R_OK) != 0) return; #else return; #endif } optlist = NULL; if ((fp = fopen(rcfile, "r")) == NULL) return; while (fgets(line, sizeof(line), fp)) { char *argv[MAX_ARGC]; int i, argc; if ((argv[0] = strtok(line, " \t\n")) == NULL) continue; if (*argv[0] == '#') continue; /* skip comments */ for (argc = 1; argc < MAX_ARGC; argc++) { argv[argc] = strtok(NULL, " \t\n"); if (argv[argc] == NULL) break; } rec = (OptionFile*)safe_malloc(sizeof(OptionFile)); rec->argv = (char**)safe_malloc(sizeof(char*) * argc); rec->argc = argc; for (i = 0; i < argc; i++) rec->argv[i] = safe_strdup(argv[i]); rec->next = optlist; optlist = rec; } fclose (fp); } static void parse_named_option(char *fname) { OptionFile *p; for (p = optlist; p; p = p->next) { int optind_save = optind; optind = 0; if (strcmp(p->argv[0], fname) == 0) { while (awe_parse_options(p->argc, p->argv, 0, 0, 0) == 0) ; } optind = optind_save; } } void awe_read_option_file(char *fname) { char tmp[256], *base, *ep; if (optlist == NULL) { read_option_file(); if (optlist == NULL) return; } parse_named_option(DEFAULT_ID); if (fname) { strncpy(tmp, fname, sizeof(tmp)); fname[sizeof(tmp) - 1] = 0; if ((base = strrchr(tmp, '/')) == NULL) base = tmp; /* no directory path is attached */ else base++; /* next of slash letter */ /* remove extension */ if ((ep = strchr(base, '.')) != NULL) *ep = 0; if (strcmp(base, DEFAULT_ID) != 0) parse_named_option(base); } } #define DEFAULT_OPTION_NUM 10 static struct option long_options[40] = { {"addblank", 2, 0, 'B'}, {"bank", 2, 0, 'b'}, {"chorus", 1, 0, 'c'}, {"reverb", 1, 0, 'r'}, {"path", 1, 0, 'P'}, {"sense", 1, 0, 'A'}, {"atten", 1, 0, 'a'}, {"decay", 1, 0, 'd'}, {"volume", 1, 0, 'V'}, {"compat", 2, 0, 'C'}, }; #define OPTION_FLAGS "b:c:r:P:A:a:d:V:BC" #define set_bool() (optarg ? bool_val(optarg) : TRUE) int awe_parse_options(int argc, char **argv, char *optflags, struct option *long_opts, int *optidx) { int c; int ival; double dval; static char options[100]; if (optflags) { if (strlen(OPTION_FLAGS) + strlen(optflags) >= sizeof(options)) return -1; } strcpy(options, OPTION_FLAGS); if (optflags) strcat(options, optflags); c = DEFAULT_OPTION_NUM; if (long_opts) { struct option *p; for (p = long_opts; p->name; p++) { if (c >= numberof(long_options)) return -1; long_options[c++] = *p; } } long_options[c].name = 0; if ((c = getopt_long(argc, argv, options, long_options, optidx)) == -1) return -1; switch (c) { case 'b': ival = atoi(optarg); if (ival > 127) fprintf(stderr, "awe: illegal bank number %d\n", ival); else awe_option.default_bank = ival; break; case 'B': awe_option.auto_add_blank = set_bool(); break; case 'C': awe_option.compatible = set_bool(); break; case 'V': ival = atoi(optarg); if (ival < 0 || ival > 100) fprintf(stderr, "awe: illegal default volume value %d\n", ival); else awe_option.default_volume = ival; break; case 'c': ival = atoi(optarg); if (ival < 0 || ival > 100) fprintf(stderr, "awe: illegal default chorus value %d\n", ival); else awe_option.default_chorus = ival; break; case 'r': ival = atoi(optarg); if (ival < 0 || ival > 100) fprintf(stderr, "awe: illegal default reverb value %d\n", ival); else awe_option.default_reverb = ival; break; case 'P': if (awe_option.search_path) free(awe_option.search_path); awe_option.search_path = safe_strdup(optarg); break; case 'A': dval = atof(optarg); if (dval <= 0) fprintf(stderr, "awe: illegal atten sense parameter %g\n", dval); else { awe_option.atten_sense = dval; awe_option.default_atten = awe_calc_def_atten(dval); } break; case 'a': ival = atoi(optarg); if (ival < 0 || ival > 255) fprintf(stderr, "awe: illegal attenuation parameter %d\n", ival); else awe_option.default_atten = ival; break; case 'd': awe_option.decay_sense = atof(optarg); break; default: return c; } return 0; } awesfx-0.5.2/awelib/parsesf.c000066400000000000000000001006441344644735400161100ustar00rootroot00000000000000/*================================================================ * parsesf.c * parse SoundFonr layers and convert it to AWE driver patch * * Copyright (C) 1996-1999 Takashi Iwai * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *================================================================*/ #include #include #include #include #include #include #include #include #ifdef linux #include #else #include #endif #include #include "awe_parm.h" #include "itypes.h" #include "sffile.h" #include "sflayer.h" #include "sfitem.h" #include "aweseq.h" #include "util.h" #include "sfopts.h" /*---------------------------------------------------------------- * prototypes *----------------------------------------------------------------*/ #define P_GLOBAL 1 #define P_LAYER 2 typedef int (*Loader)(AWEOps *ops, SFInfo *sf, LayerTable *tbl, LoadList *request); static int awe_make_unique_name(char *given, FILE *fp, char *dst); static int probe_sample(AWEOps *ops, int sample_id); static int load_matched_font(AWEOps *ops, SFInfo *sf, LoadList *request); static int load_samples(AWEOps *ops, SFInfo *sf, int layer, LoadList *request, LoadList *exlist); static int sample_loader(AWEOps *ops, SFInfo *sf, LayerTable *tbl, LoadList *request); static int load_infos(AWEOps *ops, SFInfo *sf, int layer, LoadList *request, LoadList *exlist); static int info_loader(AWEOps *ops, SFInfo *sf, LayerTable *tbl, LoadList *request); static void set_sample_info(SFInfo *sf, awe_voice_info *vp, LayerTable *tbl); static void set_init_info(SFInfo *sf, awe_voice_info *vp, LayerTable *tbl); static void set_rootkey(SFInfo *sf, awe_voice_info *vp, LayerTable *tbl); static void set_modenv(SFInfo *sf, awe_voice_info *vp, LayerTable *tbl); static void set_volenv(SFInfo *sf, awe_voice_info *vp, LayerTable *tbl); static void set_lfo1(SFInfo *sf, awe_voice_info *vp, LayerTable *tbl); static void set_lfo2(SFInfo *sf, awe_voice_info *vp, LayerTable *tbl); static int parse_preset_layers(AWEOps *ops, SFInfo *sf, SFPresetHdr *preset, LoadList *request, LoadList *exlist, Loader loader); static void search_def_drum_inst(SFInfo *sf); static int parse_inst_layers(AWEOps *ops, SFInfo *sf, LayerTable *tbl, LoadList *request, LoadList *exlist, Loader loader, int level); static int find_inst(SFGenLayer *layer); static int is_global(SFGenLayer *layer); static LoadList *is_excluded_preset(LoadList *list, SFPatchRec *pat); static void init_layer_items(SFInfo *sf); static void clear_table(LayerTable *tbl); static void set_to_table(SFInfo *sf, LayerTable *tbl, SFGenLayer *lay, int level); static void add_item_to_table(LayerTable *tbl, int oper, int amount, int level); static void merge_table(SFInfo *sf, LayerTable *dst, LayerTable *src); static void init_and_merge_table(SFInfo *sf, LayerTable *dst, LayerTable *src); static int sanity_range(LayerTable *tbl); static int in_range(LayerTable *tbl, int key); static void awe_init_marks(void); static void awe_free_marks(void); static void add_sample(int sample); static int search_sample(int id); /*---------------------------------------------------------------- * local common variables *----------------------------------------------------------------*/ static int def_drum_inst; static FILE *sample_fd; static int mem_avail; /*---------------------------------------------------------------- * manage instrument counters in hash *----------------------------------------------------------------*/ #define INFO_COUNT_MAPS 64 struct info_count_table { unsigned short instr; unsigned short count; struct info_count_table *next; }; static struct info_count_table *info_count[INFO_COUNT_MAPS]; static void info_write_count_clear(void) { int i; struct info_count_table *p; for (i = 0; i < INFO_COUNT_MAPS; i++) { if ((p = info_count[i]) != NULL) { info_count[i] = p->next; safe_free(p); } } } static int info_write_count_inc(unsigned short instr) { int key = instr % INFO_COUNT_MAPS; struct info_count_table *val; for (val = info_count[key]; val; val = val->next) { if (val->instr == instr) return ++val->count; } val = safe_malloc(sizeof(*val)); val->instr = instr; val->count = 1; val->next = info_count[key]; info_count[key] = val; return 1; } /*================================================================ * open / close patch *================================================================*/ static int open_patch_priv(AWEOps *ops, char *name, int type, int locked, int shared) { struct open_patch_rec { awe_patch_info head; awe_open_parm parm; } rec; rec.head.type = AWE_OPEN_PATCH; rec.head.len = AWE_OPEN_PARM_SIZE; rec.parm.type = type; if (locked) rec.parm.type |= AWE_PAT_LOCKED; if (shared) rec.parm.type |= AWE_PAT_SHARED; memcpy(rec.parm.name, name, AWE_PATCH_NAME_LEN); return ops->load_patch(&rec, sizeof(rec)); } int awe_open_patch(AWEOps *ops, char *name, int type, int locked) { char tmpname[AWE_PATCH_NAME_LEN]; strncpy(tmpname, name, AWE_PATCH_NAME_LEN); return open_patch_priv(ops, tmpname, type, locked, FALSE); } int awe_open_font(AWEOps *ops, SFInfo *sf, FILE *fp, int locked) { unsigned char uname[AWE_PATCH_NAME_LEN]; int atten; def_drum_inst = -1; sample_fd = fp; mem_avail = ops->mem_avail(); info_write_count_clear(); if (awe_option.compatible) atten = awe_option.default_atten; else atten = 0; ops->set_zero_atten(atten); init_layer_items(sf); awe_init_marks(); if (awe_make_unique_name(sf->sf_name, fp, uname) != AWE_RET_OK) return -1; return open_patch_priv(ops, uname, AWE_PAT_TYPE_GS, locked, TRUE); } /* create a unique name from the given name and file date/size * for sample sharing * * name format = KEY(3bytes) + VERSION(3bytes) + NAME(18bytes) * DATE(4bytes) + SIZE(4bytes) = total 32bytes * KEY = 0x01/0x17/0x05 * VERSION = 0x00/0x04/0x03 * NAME = copied from given * DATE = stat->st_mtime * SIZE = stat->st_size */ #define ASC_TO_KEY(c) ((c) - 'A' + 1) static int awe_make_unique_name(char *given, FILE *fp, char *dst) { struct stat st; if (fstat(fileno(fp), &st) < 0) { if (awe_verbose) fprintf(stderr, "parsesf: can't get stat of font file\n"); return AWE_RET_ERR; } dst[0] = ASC_TO_KEY('A'); dst[1] = ASC_TO_KEY('W'); dst[2] = ASC_TO_KEY('E'); dst[3] = 0x00; dst[4] = 0x04; dst[5] = 0x03; sprintf(dst + 6, "%-18.18s", given); *(int*)(dst + 24) = (int)st.st_mtime; *(int*)(dst + 28) = (int)st.st_size; return AWE_RET_OK; } int awe_close_patch(AWEOps *ops) { awe_patch_info head; head.key = AWE_PATCH; head.type = AWE_CLOSE_PATCH; head.len = 0; return ops->load_patch(&head, sizeof(head)); } void awe_close_font(AWEOps *ops, SFInfo *sf) { def_drum_inst = -1; sample_fd = NULL; awe_free_marks(); awe_close_patch(ops); } /*----------------------------------------------------------------*/ int awe_is_ram_fonts(SFInfo *sf) { int i; for (i = 0; i < sf->nsamples; i++) { if (sf->sample[i].size > 0) return TRUE; } return FALSE; } /*---------------------------------------------------------------- * check if the sample is loade on driver * -- using the new feature of awedrv-0.4.3p4 *----------------------------------------------------------------*/ static int probe_sample(AWEOps *ops, int sample_id) { #ifdef AWE_PROBE_DATA awe_patch_info patch; patch.type = AWE_PROBE_DATA; patch.len = 0; patch.optarg = sample_id; if (ops->load_patch(&patch, sizeof(patch)) >= 0) return TRUE; #endif return FALSE; } /*================================================================ * load a preset link *================================================================*/ int awe_load_map(AWEOps *ops, LoadList *lp) { struct open_patch_rec { awe_patch_info head; awe_voice_map parm; } rec; rec.head.type = AWE_MAP_PRESET; rec.head.len = sizeof(awe_voice_map); rec.parm.src_bank = lp->pat.bank; rec.parm.src_instr = lp->pat.preset; rec.parm.src_key = lp->pat.keynote; rec.parm.map_bank = lp->map.bank; rec.parm.map_instr = lp->map.preset; rec.parm.map_key = lp->map.keynote; if (ops->load_patch(&rec, sizeof(rec)) < 0) { if (awe_verbose) fprintf(stderr, "awe: can't load preset mapping\n"); return AWE_RET_ERR; } return AWE_RET_OK; } /*================================================================ * load the matched fonts with the given list *---------------------------------------------------------------- * plist = requests list * load_alt = true if loading alternatives for missing fonts *================================================================*/ int awe_load_font_list(AWEOps *ops, SFInfo *sf, LoadList *plist, int load_alt) { int rc; LoadList *p; for (p = plist; p; p = p->next) { if (p->loaded) continue; if ((rc = load_matched_font(ops, sf, p)) == AWE_RET_OK) p->loaded = TRUE; else if (rc == AWE_RET_ERR || rc == AWE_RET_NOMEM) return rc; } if (load_alt) { /* load alternative fonts if the fonts not exist */ for (p = plist; p; p = p->next) { if (p->loaded) continue; rc = AWE_RET_SKIP; if (p->pat.bank == 128) { if (p->pat.preset != 0) { p->pat.preset = 0; rc = load_matched_font(ops, sf, p); } } else if (p->pat.bank != 0) { p->pat.bank = 0; rc = load_matched_font(ops, sf, p); } if (rc == AWE_RET_OK) p->loaded = TRUE; else if (rc == AWE_RET_ERR || AWE_RET_NOMEM) return rc; } } return AWE_RET_OK; } /* search preset list and find the mathing layer */ static int load_matched_font(AWEOps *ops, SFInfo *sf, LoadList *request) { int i, rc; int found = 0; LoadList req; for (i = 0; i < sf->npresets; i++) { if (request->pat.preset != -1 && sf->preset[i].preset != request->pat.preset) continue; if (request->pat.bank != -1 && sf->preset[i].bank != request->pat.bank) continue; req = *request; if (req.pat.preset == -1) req.pat.preset = sf->preset[i].preset; if (req.pat.bank == -1) req.pat.bank = sf->preset[i].bank; /* remap the destination preset */ awe_merge_keys(&request->map, &req.pat, &req.map); rc = load_samples(ops, sf, i, &req, NULL); if (rc == AWE_RET_ERR || rc == AWE_RET_NOMEM) return rc; else if (rc == AWE_RET_SKIP) continue; rc = load_infos(ops, sf, i, &req, NULL); if (rc == AWE_RET_ERR || rc == AWE_RET_NOMEM) return rc; found++; } if (found) return AWE_RET_OK; else return AWE_RET_SKIP; } /*================================================================ * load the whole file at once *---------------------------------------------------------------- * exlist = fonts to be excluded (only map is referred) *================================================================*/ int awe_load_all_fonts(AWEOps *ops, SFInfo *sf, LoadList *exlist) { int rc, i; LoadList *p; search_def_drum_inst(sf); for (i = 0; i < sf->npresets; i++) { LoadList req; req.pat.preset = sf->preset[i].preset; req.pat.bank = sf->preset[i].bank; req.pat.keynote = -1; if ((p = is_excluded_preset(exlist, &req.pat)) != NULL) { if (p->pat.keynote == -1) continue; /* exclude this preset */ } req.map = req.pat; req.loaded = FALSE; rc = load_samples(ops, sf, i, &req, exlist); if (rc == AWE_RET_NOMEM || rc == AWE_RET_ERR) return rc; rc = load_infos(ops, sf, i, &req, exlist); if (rc == AWE_RET_NOMEM || rc == AWE_RET_ERR) return rc; } return AWE_RET_OK; } /*================================================================ * load a specified font *================================================================*/ /* load each preset */ int awe_load_font(AWEOps *ops, SFInfo *sf, SFPatchRec *pat, SFPatchRec *map) { int rc; LoadList *plist = NULL; plist = awe_add_loadlist(plist, pat, map); rc = awe_load_font_list(ops, sf, plist, FALSE); awe_free_loadlist(plist); return rc; } /*================================================================ * load sample data *================================================================*/ static int load_samples(AWEOps *ops, SFInfo *sf, int layer, LoadList *request, LoadList *exlist) { return parse_preset_layers(ops, sf, &sf->preset[layer], request, exlist, sample_loader); } /* sample loader */ typedef struct patch_rec { awe_patch_info patch; awe_sample_info hdr; unsigned short data[1]; } patch_rec; static int sample_loader(AWEOps *ops, SFInfo *sf, LayerTable *tbl, LoadList *request) { SFSampleInfo *sp; patch_rec *rec; if (search_sample(tbl->val[SF_sampleId])) return AWE_RET_OK; if (probe_sample(ops, tbl->val[SF_sampleId])) return AWE_RET_OK; sp = &sf->sample[tbl->val[SF_sampleId]]; if (mem_avail < sp->size * 2) return AWE_RET_NOMEM; mem_avail -= sp->size * 2; /* allocate temporary buffer for all the sample */ rec = (patch_rec*)safe_malloc(sizeof(*rec) + sp->size * 2); /* set sample info */ rec->hdr.sf_id = 0; rec->hdr.sample = tbl->val[SF_sampleId]; rec->hdr.start = sp->startsample; rec->hdr.end = sp->endsample; rec->hdr.loopstart = sp->startloop; rec->hdr.loopend = sp->endloop; rec->hdr.size = sp->size; rec->hdr.checksum_flag = 0; rec->hdr.mode_flags = 0; rec->hdr.checksum = 0; /* if this is not ROM sample, load it */ if (rec->hdr.size > 0) { int pos = rec->hdr.start * 2; if (sample_fd == NULL) { if (awe_verbose) fprintf(stderr, "awe: no file is opend\n"); safe_free(rec); return AWE_RET_ERR; } if (pos < 0 || pos > sf->samplesize) { if (awe_verbose) fprintf(stderr, "awe: illegal file pos %d\n", pos); safe_free(rec); return AWE_RET_ERR; } pos += sf->samplepos; fseek(sample_fd, pos, SEEK_SET); fread(rec->data, rec->hdr.size, 2, sample_fd); /* clear the blank data at tail */ memset(rec->data + rec->hdr.end - rec->hdr.start, 0, (rec->hdr.size - rec->hdr.end + rec->hdr.start) * 2); } /* ok, loading the patch.. */ rec->patch.optarg = 0; rec->patch.len = AWE_SAMPLE_INFO_SIZE + rec->hdr.size * 2; /* not including the patch header size */ rec->patch.type = AWE_LOAD_DATA; rec->patch.reserved = 0; if (ops->load_patch(rec, AWE_PATCH_INFO_SIZE + rec->patch.len) < 0) { safe_free(rec); if (errno == ENOSPC) return AWE_RET_NOMEM; else if (awe_verbose) fprintf(stderr, "awe: error in writing samples\n"); return AWE_RET_ERR; } safe_free(rec); add_sample(tbl->val[SF_sampleId]); return AWE_RET_OK; } /*================================================================ * load instrument data *================================================================*/ static int load_infos(AWEOps *ops, SFInfo *sf, int layer, LoadList *request, LoadList *exlist) { return parse_preset_layers(ops, sf, &sf->preset[layer], request, exlist, info_loader); } /* instrument patch loader */ static int info_loader(AWEOps *ops, SFInfo *sf, LayerTable *tbl, LoadList *request) { static awe_voice_rec_patch vrec; awe_voice_info *vp = &vrec.info; /* set voice header */ if (request->map.bank > 0 || awe_option.default_bank < 0) vrec.hdr.bank = request->map.bank; else vrec.hdr.bank = awe_option.default_bank; vrec.hdr.instr = request->map.preset; vrec.hdr.nvoices = 1; if (info_write_count_inc(vrec.hdr.instr) == 1) vrec.hdr.write_mode = AWE_WR_REPLACE; /* first time.. */ else vrec.hdr.write_mode = AWE_WR_APPEND; /* set voice info parameters */ set_sample_info(sf, vp, tbl); set_init_info(sf, vp, tbl); set_rootkey(sf, vp, tbl); set_modenv(sf, vp, tbl); set_volenv(sf, vp, tbl); set_lfo1(sf, vp, tbl); set_lfo2(sf, vp, tbl); memset(vp->parm.reserved, 0, sizeof(vp->parm.reserved)); /* if key note is specified, replace the key range */ if (request->map.keynote != -1 && request->pat.keynote != request->map.keynote) { vp->low = vp->high = request->map.keynote; vp->fixkey = request->map.keynote; } /* set patch header */ vrec.patch.optarg = 0; vrec.patch.len = AWE_VOICE_REC_SIZE + AWE_VOICE_INFO_SIZE; vrec.patch.type = AWE_LOAD_INFO; vrec.patch.reserved = 0; /* then, put it to sequencer */ if (ops->load_patch(&vrec, sizeof(vrec)) < 0) { if (awe_verbose) fprintf(stderr, "awe: can't load voice info\n"); return AWE_RET_ERR; } return AWE_RET_OK; } /*----------------------------------------------------------------*/ /* set sample address */ static void set_sample_info(SFInfo *sf, awe_voice_info *vp, LayerTable *tbl) { SFSampleInfo *sp; vp->sf_id = 0; vp->sample = tbl->val[SF_sampleId]; sp = &sf->sample[vp->sample]; vp->start = (tbl->val[SF_startAddrsHi] << 15) + tbl->val[SF_startAddrs]; vp->end = (tbl->val[SF_endAddrsHi] << 15) + tbl->val[SF_endAddrs]; vp->loopstart = (tbl->val[SF_startloopAddrsHi] << 15) + tbl->val[SF_startloopAddrs]; vp->loopend = (tbl->val[SF_endloopAddrsHi] << 15) + tbl->val[SF_endloopAddrs]; vp->rate_offset = awe_calc_rate_offset(sp->samplerate); /* sample mode */ vp->mode = 0; if (sp->sampletype & 0x8000) vp->mode |= AWE_MODE_ROMSOUND; if (tbl->val[SF_sampleFlags] == 1 || tbl->val[SF_sampleFlags] == 3) /* looping */ vp->mode |= AWE_MODE_LOOPING; else { /* short-shot; set a small blank loop at the tail */ if (sp->loopshot > 8) { vp->loopstart = sp->endsample + 8 - sp->startloop; vp->loopend = sp->endsample + sp->loopshot - 8 - sp->endloop; } else { fprintf(stderr, "loop size is too short: %d\n", sp->loopshot); exit(1); } } } /*----------------------------------------------------------------*/ /* set global information */ static void set_init_info(SFInfo *sf, awe_voice_info *vp, LayerTable *tbl) { /* key range */ vp->low = LOWNUM(tbl->val[SF_keyRange]); vp->high = HIGHNUM(tbl->val[SF_keyRange]); /* velocity range */ vp->vellow = LOWNUM(tbl->val[SF_velRange]); vp->velhigh = HIGHNUM(tbl->val[SF_velRange]); /* fixed key & velocity */ vp->fixkey = tbl->val[SF_keynum]; vp->fixvel = tbl->val[SF_velocity]; /* panning position */ vp->pan = awe_calc_pan(tbl->val[SF_panEffectsSend]); vp->fixpan = -1; /* initial volume */ vp->amplitude = awe_option.default_volume * 127 / 100; vp->attenuation = awe_calc_attenuation(tbl->val[SF_initAtten]); #if 0 if (vp->mode & AWE_MODE_ROMSOUND && !awe_option.compatible) { if (vp->attenuation < 0xf0) vp->attenuation += 0x10; else vp->attenuation = 0xff; } #endif /* chorus & reverb effects */ if (tbl->set[SF_chorusEffectsSend]) vp->parm.chorus = awe_calc_chorus(tbl->val[SF_chorusEffectsSend]); else vp->parm.chorus = awe_calc_chorus(awe_option.default_chorus * 10); if (tbl->set[SF_reverbEffectsSend]) vp->parm.reverb = awe_calc_reverb(tbl->val[SF_reverbEffectsSend]); else vp->parm.reverb = awe_calc_reverb(awe_option.default_reverb * 10); /* initial cutoff & resonance */ vp->parm.cutoff = awe_calc_cutoff(tbl->val[SF_initialFilterFc]); vp->parm.filterQ = awe_calc_filterQ(tbl->val[SF_initialFilterQ]); /* exclusive class key */ vp->exclusiveClass = tbl->val[SF_keyExclusiveClass]; } /*----------------------------------------------------------------*/ /* calculate root key & fine tune */ static void set_rootkey(SFInfo *sf, awe_voice_info *vp, LayerTable *tbl) { SFSampleInfo *sp = &sf->sample[vp->sample]; /* scale tuning */ vp->scaleTuning = tbl->val[SF_scaleTuning]; /* set initial root key & fine tune */ if (sf->version == 1 && tbl->set[SF_samplePitch]) { /* set from sample pitch */ vp->root = tbl->val[SF_samplePitch] / 100; vp->tune = -tbl->val[SF_samplePitch] % 100; if (vp->tune <= -50) { vp->root++; vp->tune = 100 + vp->tune; } if (vp->scaleTuning == 50) vp->tune /= 2; } else { /* from sample info */ vp->root = sp->originalPitch; vp->tune = sp->pitchCorrection; } /* orverride root key */ if (tbl->set[SF_rootKey]) vp->root += tbl->val[SF_rootKey] - sp->originalPitch; /* tuning */ if (sf->version == 1) vp->tune += tbl->val[SF_coarseTune] * vp->scaleTuning + (int)tbl->val[SF_fineTune] * (int)vp->scaleTuning / 100; else vp->tune += tbl->val[SF_coarseTune] * 100 + tbl->val[SF_fineTune]; /* correct too high pitch */ if (vp->root >= vp->high + 60) vp->root -= 60; } /*----------------------------------------------------------------*/ #define TO_WORD(hi,lo) (((unsigned short)(hi) << 8) | (unsigned short)(lo)) /* modulation envelope parameters */ static void set_modenv(SFInfo *sf, awe_voice_info *vp, LayerTable *tbl) { /* delay */ vp->parm.moddelay = awe_calc_delay(tbl->val[SF_delayEnv1]); /* attack & hold */ vp->parm.modatkhld = awe_calc_atkhld(tbl->val[SF_attackEnv1], tbl->val[SF_holdEnv1]); /* decay & sustain */ vp->parm.moddcysus = TO_WORD(awe_calc_mod_sustain(tbl->val[SF_sustainEnv1]), awe_calc_decay(tbl->val[SF_decayEnv1])); /* release */ vp->parm.modrelease = TO_WORD(0x80, awe_calc_decay(tbl->val[SF_releaseEnv1])); /* key hold/decay */ vp->parm.modkeyhold = tbl->val[SF_autoHoldEnv1]; vp->parm.modkeydecay = tbl->val[SF_autoDecayEnv1]; /* pitch / cutoff shift */ vp->parm.pefe = TO_WORD(awe_calc_pitch_shift(tbl->val[SF_env1ToPitch]), awe_calc_cutoff_shift(tbl->val[SF_env1ToFilterFc], 6)); } /* volume envelope parameters */ static void set_volenv(SFInfo *sf, awe_voice_info *vp, LayerTable *tbl) { /* delay */ vp->parm.voldelay = awe_calc_delay(tbl->val[SF_delayEnv2]); /* attack & hold */ vp->parm.volatkhld = awe_calc_atkhld(tbl->val[SF_attackEnv2], tbl->val[SF_holdEnv2]); /* decay & sustain */ vp->parm.voldcysus = TO_WORD(awe_calc_sustain(tbl->val[SF_sustainEnv2]), awe_calc_decay(tbl->val[SF_decayEnv2])); /* release */ vp->parm.volrelease = TO_WORD(0x80, awe_calc_decay(tbl->val[SF_releaseEnv2])); /* key hold/decay */ vp->parm.volkeyhold = tbl->val[SF_autoHoldEnv2]; vp->parm.volkeydecay = tbl->val[SF_autoDecayEnv2]; } /* lfo1 parameters (tremolo & vibrato) */ static void set_lfo1(SFInfo *sf, awe_voice_info *vp, LayerTable *tbl) { vp->parm.lfo1delay = awe_calc_delay(tbl->val[SF_delayLfo1]); vp->parm.fmmod = TO_WORD(awe_calc_pitch_shift(tbl->val[SF_lfo1ToPitch]), awe_calc_cutoff_shift(tbl->val[SF_lfo1ToFilterFc], 3)); vp->parm.tremfrq = TO_WORD(awe_calc_tremolo(tbl->val[SF_lfo1ToVolume]), awe_calc_freq(tbl->val[SF_freqLfo1])); } /* lfo2 parameters (vibrato only) */ static void set_lfo2(SFInfo *sf, awe_voice_info *vp, LayerTable *tbl) { vp->parm.lfo2delay = awe_calc_delay(tbl->val[SF_delayLfo2]); vp->parm.fm2frq2 = TO_WORD(awe_calc_pitch_shift(tbl->val[SF_lfo2ToPitch]), awe_calc_freq(tbl->val[SF_freqLfo2])); } /*================================================================ * parse preset and instrument layers and find matching instrument; * call loader with the parameter *---------------------------------------------------------------- * preset = preset record to be parsed * request = requested instrument (must be specified) * exlist = excluded instruments (null = nothing) * loader = loading function *================================================================*/ static int parse_preset_layers(AWEOps *ops, SFInfo *sf, SFPresetHdr *preset, LoadList *request, LoadList *exlist, Loader loader) { int rc, j, nlayers; SFGenLayer *layp, *globalp; /* if layer is empty, skip it */ if ((nlayers = preset->hdr.nlayers) <= 0 || (layp = preset->hdr.layer) == NULL) return AWE_RET_SKIP; /* check global layer */ globalp = NULL; if (is_global(layp)) { globalp = layp; layp++; /* start from next layer */ nlayers--; } /* parse for each preset layer */ for (j = 0; j < nlayers; j++, layp++) { LayerTable tbl; /* set up table */ clear_table(&tbl); if (globalp) set_to_table(sf, &tbl, globalp, P_GLOBAL); set_to_table(sf, &tbl, layp, P_LAYER); /* parse the instrument layers */ rc = parse_inst_layers(ops, sf, &tbl, request, exlist, loader, 0); /* fatal error */ if (rc == AWE_RET_ERR || rc == AWE_RET_NOMEM) return rc; } return AWE_RET_OK; } /* find instrument id of default drumset #0: * the standard drumset is often included in other drumsets. */ static void search_def_drum_inst(SFInfo *sf) { int i; SFGenLayer *layp; def_drum_inst = -1; for (i = 0; i < sf->npresets; i++) { if (sf->preset[i].bank == 128 && sf->preset[i].preset == 0) { /* check the first layer */ if ((layp = sf->preset[i].hdr.layer) == NULL) continue; if (!is_global(layp)) def_drum_inst = find_inst(layp); break; } } } /*================================================================ * parse instrument layers -- called from preset parser * level represents the recursive level *================================================================*/ static int parse_inst_layers(AWEOps *ops, SFInfo *sf, LayerTable *tbl, LoadList *request, LoadList *exlist, Loader loader, int level) { SFInstHdr *inst; int rc, i, nlayers; SFGenLayer *lay, *globalp; if (level >= 2) { fprintf(stderr, "parse_layer: too deep instrument level\n"); return AWE_RET_ERR; } /* instrument must be defined */ if (!tbl->set[SF_instrument]) return AWE_RET_SKIP; /* if non-standard drumset includes standard drum instruments, skip it to avoid duplicate the data */ inst = &sf->inst[tbl->val[SF_instrument]]; /* if (def_drum_inst >= 0 && request->pat.bank == 128 && request->pat.preset != 0 && tbl->val[SF_instrument] == def_drum_inst) return AWE_RET_SKIP; */ /* if layer is empty, skip it */ if ((nlayers = inst->hdr.nlayers) <= 0 || (lay = inst->hdr.layer) == NULL) return AWE_RET_SKIP; /* check global layer */ globalp = NULL; if (is_global(lay)) { globalp = lay; lay++; /* start from the next layer */ nlayers--; } /* parse for each layer */ for (i = 0; i < nlayers; i++, lay++) { LayerTable ctbl; clear_table(&ctbl); if (globalp) set_to_table(sf, &ctbl, globalp, P_GLOBAL); set_to_table(sf, &ctbl, lay, P_LAYER); if (!ctbl.set[SF_sampleId]) { /* recursive loading */ merge_table(sf, &ctbl, tbl); if (! sanity_range(&ctbl)) continue; rc = parse_inst_layers(ops, sf, &ctbl, request, exlist, loader, level+1); if (rc == AWE_RET_NOMEM || rc == AWE_RET_ERR) return rc; } else { init_and_merge_table(sf, &ctbl, tbl); if (! sanity_range(&ctbl)) continue; if (request->pat.keynote != -1 && ! in_range(&ctbl, request->pat.keynote)) continue; if (exlist) { /* check exclusion list */ SFPatchRec tmp; tmp = request->pat; tmp.keynote = LOWNUM(tbl->val[SF_keyRange]); if (is_excluded_preset(exlist, &tmp)) continue; } rc = loader(ops, sf, &ctbl, request); if (rc == AWE_RET_NOMEM || rc == AWE_RET_ERR) return rc; } } return AWE_RET_OK; } /*---------------------------------------------------------------- * find instrument in the list *----------------------------------------------------------------*/ static int find_inst(SFGenLayer *layer) { int i; for (i = 0; i < layer->nlists; i++) { if (layer->list[i].oper == SF_instrument) return layer->list[i].amount; } return -1; } /*---------------------------------------------------------------- * check if the layer is global layer *----------------------------------------------------------------*/ static int is_global(SFGenLayer *layer) { int i; for (i = 0; i < layer->nlists; i++) { if (layer->list[i].oper == SF_instrument || layer->list[i].oper == SF_sampleId) return 0; } return 1; } /*---------------------------------------------------------------- * check if the specified preset matches the excluded list *----------------------------------------------------------------*/ static LoadList *is_excluded_preset(LoadList *list, SFPatchRec *pat) { LoadList *p; for (p = list; p; p = p->next) { if (awe_match_preset(&p->map, pat)) return p; } return NULL; } /*================================================================ * layer table handlers *================================================================*/ /* initialize layer default values according to SF version */ static void init_layer_items(SFInfo *sf) { /* default value is not zero */ if (sf->version == 1) { layer_items[SF_sustainEnv1].defv = 1000; layer_items[SF_sustainEnv2].defv = 1000; layer_items[SF_freqLfo1].defv = -725; layer_items[SF_freqLfo2].defv = -15600; } else { layer_items[SF_sustainEnv1].defv = 0; layer_items[SF_sustainEnv2].defv = 0; layer_items[SF_freqLfo1].defv = 0; layer_items[SF_freqLfo2].defv = 0; } } /* initialize layer table */ static void clear_table(LayerTable *tbl) { memset(tbl->val, 0, sizeof(tbl->val)); memset(tbl->set, 0, sizeof(tbl->set)); } /* set items in a layer to the table */ static void set_to_table(SFInfo *sf, LayerTable *tbl, SFGenLayer *lay, int level) { int i; for (i = 0; i < lay->nlists; i++) { SFGenRec *gen = &lay->list[i]; /* copy the value regardless of its copy policy */ tbl->val[gen->oper] = gen->amount; tbl->set[gen->oper] = level; } } /* add an item to the table */ static void add_item_to_table(LayerTable *tbl, int oper, int amount, int level) { LayerItem *item = &layer_items[oper]; int o_lo, o_hi, lo, hi; switch (item->copy) { case L_INHRT: tbl->val[oper] += amount; break; case L_OVWRT: tbl->val[oper] = amount; break; case L_PRSET: case L_INSTR: /* do not overwrite */ if (!tbl->set[oper]) tbl->val[oper] = amount; break; case L_RANGE: if (!tbl->set[oper]) { tbl->val[oper] = amount; } else { o_lo = LOWNUM(tbl->val[oper]); o_hi = HIGHNUM(tbl->val[oper]); lo = LOWNUM(amount); hi = HIGHNUM(amount); if (lo < o_lo) lo = o_lo; if (hi > o_hi) hi = o_hi; tbl->val[oper] = RANGE(lo, hi); } break; } } /* merge two tables */ static void merge_table(SFInfo *sf, LayerTable *dst, LayerTable *src) { int i; for (i = 0; i < SF_EOF; i++) { if (src->set[i]) { if (sf->version == 1) { if (!dst->set[i] || i == SF_keyRange || i == SF_velRange) /* just copy it */ dst->val[i] = src->val[i]; } else add_item_to_table(dst, i, src->val[i], P_GLOBAL); dst->set[i] = P_GLOBAL; } } } /* merge and set default values */ static void init_and_merge_table(SFInfo *sf, LayerTable *dst, LayerTable *src) { int i; /* set default */ for (i = 0; i < SF_EOF; i++) { if (!dst->set[i]) dst->val[i] = layer_items[i].defv; } merge_table(sf, dst, src); /* convert from SBK to SF2 */ if (sf->version == 1) { for (i = 0; i < SF_EOF; i++) { if (dst->set[i]) dst->val[i] = sbk_to_sf2(i, dst->val[i]); } } } /*================================================================ * check key and velocity range *================================================================*/ /* check if the table has sanity key/velocity ranges */ static int sanity_range(LayerTable *tbl) { int lo, hi; lo = LOWNUM(tbl->val[SF_keyRange]); hi = HIGHNUM(tbl->val[SF_keyRange]); if (lo < 0 || lo > 127 || hi < 0 || hi > 127 || hi < lo) return 0; lo = LOWNUM(tbl->val[SF_velRange]); hi = HIGHNUM(tbl->val[SF_velRange]); if (lo < 0 || lo > 127 || hi < 0 || hi > 127 || hi < lo) return 0; return 1; } /* check if the given key is included in the table */ static int in_range(LayerTable *tbl, int key) { int lo, hi; lo = LOWNUM(tbl->val[SF_keyRange]); hi = HIGHNUM(tbl->val[SF_keyRange]); if (key >= lo && key <= hi) return TRUE; return FALSE; } /*================================================================ * sample mark up table *================================================================*/ /* linked list of sample record */ typedef struct _DynSample { int id; struct _DynSample *next; } DynSample; static int nsamples; static DynSample *dynsample; /* initialize lists */ static void awe_init_marks(void) { nsamples = 0; dynsample = NULL; } /* free allocated lists */ static void awe_free_marks(void) { DynSample *sp, *sp_next; for (sp = dynsample; sp; sp = sp_next) { sp_next = sp->next; safe_free(sp); } } /* mark the sample */ static void add_sample(int sample) { DynSample *sp; for (sp = dynsample; sp; sp = sp->next) { if (sp->id == sample) return; } sp = (DynSample*)safe_malloc(sizeof(DynSample)); sp->id = sample; sp->next = dynsample; dynsample = sp; nsamples++; } /* search the sample element with the specified id */ static int search_sample(int id) { DynSample *sp; for (sp = dynsample; sp; sp = sp->next) { if (sp->id == id) return TRUE; } return FALSE; } awesfx-0.5.2/awelib/path.c000066400000000000000000000037041344644735400154000ustar00rootroot00000000000000/*---------------------------------------------------------------- * search a file from path list * * Copyright (C) 1996-1999 Takashi Iwai * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *----------------------------------------------------------------*/ #include #include #include #include #include "util.h" static int file_exists(char *path, char **ext) { char *lastp; if (access(path, R_OK) == 0) return 1; if (ext == NULL) return 0; lastp = path + strlen(path); for (; *ext; ext++) { strcpy(lastp, *ext); if (access(path, R_OK) == 0) return 1; } return 0; } int awe_search_file_name(char *fresult, int maxlen, char *fname, char *pathlist, char **ext) { char *tok; char *path; if (strlen(fname) >= maxlen) return 0; /* search the current path at first */ strcpy(fresult, fname); if (file_exists(fresult, ext)) return 1; /* then search along path list */ if (fname[0] != '/' && pathlist && *pathlist) { path = safe_strdup(pathlist); for (tok = strtok(path, ":"); tok; tok = strtok(NULL, ":")) { if (*tok && tok[strlen(tok)-1] != '/') snprintf(fresult, maxlen, "%s/%s", tok, fname); else snprintf(fresult, maxlen, "%s%s", tok, fname); if (file_exists(fresult, ext)) { safe_free(path); return 1; } } } return 0; } awesfx-0.5.2/awelib/sample.c000066400000000000000000000037131344644735400157250ustar00rootroot00000000000000/*================================================================ * sample.c * convert SBK parameters and calculate loop sizes * * Copyright (C) 1996-1999 Takashi Iwai * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *================================================================*/ #include "sffile.h" #include "sfitem.h" #include "util.h" /* add blank loop for each data */ int awe_auto_add_blank = 0; void awe_correct_samples(SFInfo *sf) { int i; SFSampleInfo *sp; int prev_end; prev_end = 0; for (sp = sf->sample, i = 0; i < sf->nsamples; i++, sp++) { /* correct sample positions for SBK file */ if (sf->version == 1) { sp->startloop++; sp->endloop += 2; } /* calculate sample data size */ if (sp->sampletype & 0x8000) sp->size = 0; else if (sp->startsample < prev_end && sp->startsample != 0) sp->size = 0; else { sp->size = -1; if (!awe_auto_add_blank && i != sf->nsamples-1) sp->size = sp[1].startsample - sp->startsample; if (sp->size < 0) sp->size = sp->endsample - sp->startsample + 48; } prev_end = sp->endsample; /* calculate short-shot loop size */ if (awe_auto_add_blank || i == sf->nsamples-1) sp->loopshot = 48; else { sp->loopshot = sp[1].startsample - sp->endsample; if (sp->loopshot < 0 || sp->loopshot > 48) sp->loopshot = 48; } } } awesfx-0.5.2/awelib/sbkconv.c000066400000000000000000000107731344644735400161150ustar00rootroot00000000000000/*================================================================ * SBK --> SF2 Conversion * * Copyright (C) 1996-1999 Takashi Iwai * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *================================================================*/ #include #include #include "sffile.h" #include "sfitem.h" #include "awe_parm.h" /*---------------------------------------------------------------- * prototypes *----------------------------------------------------------------*/ static int sbk_cutoff(int gen, int val); static int sbk_filterQ(int gen, int val); static int sbk_tenpct(int gen, int val); static int sbk_panpos(int gen, int val); static int sbk_atten(int gen, int val); static int sbk_scale(int gen, int val); static int sbk_time(int gen, int val); static int sbk_tm_key(int gen, int val); static int sbk_freq(int gen, int val); static int sbk_pshift(int gen, int val); static int sbk_cshift(int gen, int val); static int sbk_tremolo(int gen, int val); static int sbk_volsust(int gen, int val); static int sbk_modsust(int gen, int val); /*---------------------------------------------------------------- * convertor function table *----------------------------------------------------------------*/ static SBKConv sbk_convertors[T_EOT] = { NULL, NULL, NULL, NULL, NULL, sbk_cutoff, sbk_filterQ, sbk_tenpct, sbk_panpos, sbk_atten, sbk_scale, sbk_time, sbk_tm_key, sbk_freq, sbk_pshift, sbk_cshift, sbk_tremolo, sbk_modsust, sbk_volsust, }; /*---------------------------------------------------------------- * sbk --> sf2 conversion *----------------------------------------------------------------*/ int sbk_to_sf2(int oper, int amount) { LayerItem *item = &layer_items[oper]; if (item->type < 0 || item->type >= T_EOT) { fprintf(stderr, "illegal gen item type %d\n", item->type); return amount; } if (sbk_convertors[item->type]) return sbk_convertors[item->type](oper, amount); return amount; } /*---------------------------------------------------------------- * conversion rules for each type *----------------------------------------------------------------*/ /* initial cutoff */ static int sbk_cutoff(int gen, int val) { if (val == 127) return 14400; else return 59 * val + 4366; /*return 50 * val + 4721;*/ } /* initial resonance */ static int sbk_filterQ(int gen, int val) { return val * 3 / 2; } /* chorus/reverb */ static int sbk_tenpct(int gen, int val) { return val * 1000 / 256; } /* pan position */ static int sbk_panpos(int gen, int val) { return val * 1000 / 127 - 500; } /* initial attenuation */ static int sbk_atten(int gen, int val) { if (val == 0) return 1000; return (int)(-200.0 * log10((double)val / 127.0) * 10); } /* scale tuning */ static int sbk_scale(int gen, int val) { return (val ? 50 : 100); } /* env/lfo time parameter */ static int sbk_time(int gen, int val) { return awe_msec_to_timecent(val); } /* time change per key */ static int sbk_tm_key(int gen, int val) { return (int)(val * 5.55); } /* lfo frequency */ static int sbk_freq(int gen, int val) { if (val == 0) { if (gen == SF_freqLfo1) return -725; else /* SF_freqLfo2*/ return -15600; } /*return (int)(3986.0 * log10((double)val) - 7925.0);*/ return (int)(1200 * log10((double)val) / log10(2.0) - 7925.0); } /* lfo/env pitch shift */ static int sbk_pshift(int gen, int val) { return (1200 * val / 64 + 1) / 2; } /* lfo/env cutoff freq shift */ static int sbk_cshift(int gen, int val) { if (gen == SF_lfo1ToFilterFc) return (1200 * 3 * val) / 64; else return (1200 * 6 * val) / 64; } /* lfo volume shift */ static int sbk_tremolo(int gen, int val) { return (120 * val) / 64; } /* mod env sustain */ static int sbk_modsust(int gen, int val) { if (val < 96) return 1000 * (96 - val) / 96; else return 0; } /* vol env sustain */ static int sbk_volsust(int gen, int val) { if (val < 96) return (2000 - 21 * val) / 2; else return 0; } awesfx-0.5.2/awelib/sffile.c000066400000000000000000000404321344644735400157130ustar00rootroot00000000000000/*================================================================ * sffile.c * read SoundFont file (SBK/SF2) and store the layer lists * * Copyright (C) 1996-1999 Takashi Iwai * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *================================================================*/ #include #include #include #include "sffile.h" #include "util.h" #include "config.h" /*================================================================ * preset / instrument bag record *================================================================*/ typedef struct _SFBags { int nbags; uint16 *bag; int ngens; SFGenRec *gen; } SFBags; static SFBags prbags, inbags; /*---------------------------------------------------------------- * function prototypes *----------------------------------------------------------------*/ #define NEW(type,nums) (type*)safe_malloc(sizeof(type) * (nums)) #define READID(var,fd) fread(var, 4, 1, fd) #define READSTR(var,fd) fread(var, 20, 1, fd) #ifndef WORDS_BIGENDIAN #define READCHUNK(var,fd) fread(&var, 8, 1, fd) #define READDW(var,fd) fread(&var, 4, 1, fd) #define READW(var,fd) fread(&var, 2, 1, fd) #else /* WORDS_BIGENDIAN */ #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)) #define READCHUNK(var,fd) {uint32 tmp; fread((var).id, 4, 1, fd);\ fread(&tmp, 4, 1, fd); (var).size = XCHG_LONG(tmp);} #define READDW(var,fd) {uint32 tmp; fread(&tmp, 4, 1, fd); (var) = XCHG_LONG(tmp);} #define READW(var,fd) {uint16 tmp; fread(&tmp, 2, 1, fd); (var) = XCHG_SHORT(tmp);} #endif #define READB(var,fd) fread(&var, 1, 1, fd) #define SKIPB(fd) {char dummy; fread(&dummy, 1, 1, fd);} #define SKIPW(fd) {short dummy; fread(&dummy, 2, 1, fd);} #define SKIPDW(fd) {int dummy; fread(&dummy, 4, 1, fd);} static int seekable; #define FSKIP(size,fd) fskip(size, fd, seekable) /*----------------------------------------------------------------*/ static int chunkid(char *id); static int process_list(int size, SFInfo *sf, FILE *fd); static int process_info(int size, SFInfo *sf, FILE *fd); static int process_sdta(int size, SFInfo *sf, FILE *fd); static int process_pdta(int size, SFInfo *sf, FILE *fd); static void load_sample_names(int size, SFInfo *sf, FILE *fd); static void load_preset_header(int size, SFInfo *sf, FILE *fd); static void load_inst_header(int size, SFInfo *sf, FILE *fd); static void load_bag(int size, SFBags *bagp, FILE *fd); static void load_gen(int size, SFBags *bagp, FILE *fd); static void load_sample_info(int size, SFInfo *sf, FILE *fd); static void convert_layers(SFInfo *sf); static void generate_layers(SFHeader *hdr, SFHeader *next, SFBags *bags); static void free_layer(SFHeader *hdr); /*---------------------------------------------------------------- * id numbers *----------------------------------------------------------------*/ enum { /* level 0; chunk */ UNKN_ID, RIFF_ID, LIST_ID, SFBK_ID, /* level 1; id only */ INFO_ID, SDTA_ID, PDTA_ID, /* info stuff; chunk */ IFIL_ID, ISNG_ID, IROM_ID, INAM_ID, IVER_ID, IPRD_ID, ICOP_ID, /* sample data stuff; chunk */ SNAM_ID, SMPL_ID, /* preset stuff; chunk */ PHDR_ID, PBAG_ID, PMOD_ID, PGEN_ID, /* inst stuff; chunk */ INST_ID, IBAG_ID, IMOD_ID, IGEN_ID, /* sample header; chunk */ SHDR_ID, }; /*================================================================ * load a soundfont file *================================================================*/ int awe_load_soundfont(SFInfo *sf, FILE *fd, int is_seekable) { SFChunk chunk; seekable = is_seekable; sf->preset = NULL; sf->sample = NULL; sf->inst = NULL; sf->sf_name = NULL; prbags.bag = inbags.bag = NULL; prbags.gen = inbags.gen = NULL; /* check RIFF file header */ READCHUNK(chunk, fd); if (chunkid(chunk.id) != RIFF_ID) { fprintf(stderr, "*** not a RIFF file\n"); return -1; } /* check file id */ READID(chunk.id, fd); if (chunkid(chunk.id) != SFBK_ID) { fprintf(stderr, "*** not a SoundFont file\n"); return -1; } for (;;) { READCHUNK(chunk, fd); if (feof(fd)) break; else if (chunkid(chunk.id) == LIST_ID) { if (process_list(chunk.size, sf, fd)) break; } else { fprintf(stderr, "*** illegal id in level 0: %4.4s %4d\n", chunk.id, chunk.size); FSKIP(chunk.size, fd); } } /* parse layer structure */ convert_layers(sf); /* free private tables */ if (prbags.bag) free(prbags.bag); if (prbags.gen) free(prbags.gen); if (inbags.bag) free(inbags.bag); if (inbags.gen) free(inbags.gen); return 0; } /*================================================================ * free buffer *================================================================*/ void awe_free_soundfont(SFInfo *sf) { int i; if (sf->preset) { for (i = 0; i < sf->npresets; i++) free_layer(&sf->preset[i].hdr); free(sf->preset); } if (sf->inst) { for (i = 0; i < sf->ninsts; i++) free_layer(&sf->inst[i].hdr); free(sf->inst); } if (sf->sample) free(sf->sample); if (sf->sf_name) free(sf->sf_name); } /*---------------------------------------------------------------- * get id value from 4bytes ID string *----------------------------------------------------------------*/ static int chunkid(char *id) { static struct idstring { char *str; int id; } idlist[] = { {"RIFF", RIFF_ID}, {"LIST", LIST_ID}, {"sfbk", SFBK_ID}, {"INFO", INFO_ID}, {"sdta", SDTA_ID}, {"snam", SNAM_ID}, {"smpl", SMPL_ID}, {"pdta", PDTA_ID}, {"phdr", PHDR_ID}, {"pbag", PBAG_ID}, {"pmod", PMOD_ID}, {"pgen", PGEN_ID}, {"inst", INST_ID}, {"ibag", IBAG_ID}, {"imod", IMOD_ID}, {"igen", IGEN_ID}, {"shdr", SHDR_ID}, {"ifil", IFIL_ID}, {"isng", ISNG_ID}, {"irom", IROM_ID}, {"iver", IVER_ID}, {"INAM", INAM_ID}, {"IPRD", IPRD_ID}, {"ICOP", ICOP_ID}, }; int i; for (i = 0; i < sizeof(idlist)/sizeof(idlist[0]); i++) { if (strncmp(id, idlist[i].str, 4) == 0) return idlist[i].id; } return UNKN_ID; } /*================================================================ * process a list chunk *================================================================*/ static int process_list(int size, SFInfo *sf, FILE *fd) { SFChunk chunk; /* read the following id string */ READID(chunk.id, fd); size -= 4; switch (chunkid(chunk.id)) { case INFO_ID: return process_info(size, sf, fd); case SDTA_ID: return process_sdta(size, sf, fd); case PDTA_ID: return process_pdta(size, sf, fd); default: fprintf(stderr, "*** illegal id in level 1: %4.4s\n", chunk.id); FSKIP(size, fd); /* skip it */ return 0; } } /*================================================================ * process info list *================================================================*/ static int process_info(int size, SFInfo *sf, FILE *fd) { sf->infopos = ftell(fd); sf->infosize = size; /* parse the buffer */ while (size > 0) { SFChunk chunk; /* read a sub chunk */ READCHUNK(chunk, fd); size -= 8; if (feof(fd)) return -1; switch (chunkid(chunk.id)) { case IFIL_ID: /* soundfont file version */ READW(sf->version, fd); READW(sf->minorversion, fd); break; case INAM_ID: /* name of the font */ sf->sf_name = (char*)safe_malloc(chunk.size + 1); fread(sf->sf_name, 1, chunk.size, fd); sf->sf_name[chunk.size] = 0; break; default: FSKIP(chunk.size, fd); break; } size -= chunk.size; } return 0; } /*================================================================ * process sample data list *================================================================*/ static int process_sdta(int size, SFInfo *sf, FILE *fd) { while (size > 0) { SFChunk chunk; /* read a sub chunk */ READCHUNK(chunk, fd); size -= 8; if (feof(fd)) return -1; switch (chunkid(chunk.id)) { case SNAM_ID: /* sample name list */ load_sample_names(chunk.size, sf, fd); break; case SMPL_ID: /* sample data starts from here */ sf->samplepos = ftell(fd); sf->samplesize = chunk.size; FSKIP(chunk.size, fd); break; default: FSKIP(chunk.size, fd); break; } size -= chunk.size; } return 0; } /*================================================================ * process preset data list *================================================================*/ static int process_pdta(int size, SFInfo *sf, FILE *fd) { while (size > 0) { SFChunk chunk; /* read a subchunk */ READCHUNK(chunk, fd); size -= 8; if (feof(fd)) return -1; switch (chunkid(chunk.id)) { case PHDR_ID: load_preset_header(chunk.size, sf, fd); break; case PBAG_ID: load_bag(chunk.size, &prbags, fd); break; case PGEN_ID: load_gen(chunk.size, &prbags, fd); break; case INST_ID: load_inst_header(chunk.size, sf, fd); break; case IBAG_ID: load_bag(chunk.size, &inbags, fd); break; case IGEN_ID: load_gen(chunk.size, &inbags, fd); break; case SHDR_ID: load_sample_info(chunk.size, sf, fd); break; case PMOD_ID: /* ignored */ case IMOD_ID: /* ingored */ default: FSKIP(chunk.size, fd); break; } size -= chunk.size; } return 0; } /*---------------------------------------------------------------- * store sample name list; sf1 only *----------------------------------------------------------------*/ static void load_sample_names(int size, SFInfo *sf, FILE *fd) { int i, nsamples; if (sf->version > 1) { fprintf(stderr, "*** version 2 has obsolete format??\n"); FSKIP(size, fd); return; } /* each sample name has a fixed lentgh (20 bytes) */ nsamples = size / 20; if (sf->sample == NULL) { sf->nsamples = nsamples; sf->sample = NEW(SFSampleInfo, sf->nsamples); } else if (sf->nsamples != nsamples) { fprintf(stderr, "*** different # of samples ?? (%d : %d)\n", sf->nsamples, nsamples); FSKIP(size, fd); return; } /* read each name from file */ for (i = 0; i < sf->nsamples; i++) { READSTR(sf->sample[i].name, fd); } } /*---------------------------------------------------------------- * preset header list *----------------------------------------------------------------*/ static void load_preset_header(int size, SFInfo *sf, FILE *fd) { int i; sf->npresets = size / 38; sf->preset = NEW(SFPresetHdr, sf->npresets); for (i = 0; i < sf->npresets; i++) { READSTR(sf->preset[i].hdr.name, fd); READW(sf->preset[i].preset, fd); READW(sf->preset[i].bank, fd); READW(sf->preset[i].hdr.bagNdx, fd); SKIPDW(fd); /* lib; ignored*/ SKIPDW(fd); /* genre; ignored */ SKIPDW(fd); /* morph; ignored */ /* initialize layer table; it'll be parsed later */ sf->preset[i].hdr.nlayers = 0; sf->preset[i].hdr.layer = NULL; } } /*---------------------------------------------------------------- * instrument header list *----------------------------------------------------------------*/ static void load_inst_header(int size, SFInfo *sf, FILE *fd) { int i; sf->ninsts = size / 22; sf->inst = NEW(SFInstHdr, sf->ninsts); for (i = 0; i < sf->ninsts; i++) { READSTR(sf->inst[i].hdr.name, fd); READW(sf->inst[i].hdr.bagNdx, fd); /* iniitialize layer table; it'll be parsed later */ sf->inst[i].hdr.nlayers = 0; sf->inst[i].hdr.layer = NULL; } } /*---------------------------------------------------------------- * load preset/instrument bag list on the private table *----------------------------------------------------------------*/ static void load_bag(int size, SFBags *bagp, FILE *fd) { int i; size /= 4; bagp->bag = NEW(uint16, size); for (i = 0; i < size; i++) { READW(bagp->bag[i], fd); SKIPW(fd); /* mod; ignored */ } bagp->nbags = size; } /*---------------------------------------------------------------- * load preset/instrument generator list on the private table *----------------------------------------------------------------*/ static void load_gen(int size, SFBags *bagp, FILE *fd) { int i; size /= 4; bagp->gen = NEW(SFGenRec, size); for (i = 0; i < size; i++) { READW(bagp->gen[i].oper, fd); READW(bagp->gen[i].amount, fd); } bagp->ngens = size; } /*---------------------------------------------------------------- * load sample info list *----------------------------------------------------------------*/ static void load_sample_info(int size, SFInfo *sf, FILE *fd) { int i; int in_rom; /* the record size depends on the soundfont version */ if (sf->version > 1) { /* SF2 includes sample name and other infos */ sf->nsamples = size / 46; sf->sample = NEW(SFSampleInfo, sf->nsamples); } else { /* SBK; sample name may be read already */ int nsamples = size / 16; if (sf->sample == NULL) { sf->nsamples = nsamples; sf->sample = NEW(SFSampleInfo, sf->nsamples); } else if (sf->nsamples != nsamples) { #if 0 fprintf(stderr, "*** different # of infos ?? (%d : %d)\n", sf->nsamples, nsamples); FSKIP(size, fd); return; #endif /* overwrite it */ sf->nsamples = nsamples; } } in_rom = 1; /* data may start from ROM samples */ for (i = 0; i < sf->nsamples; i++) { if (sf->version > 1) /* SF2 only */ READSTR(sf->sample[i].name, fd); READDW(sf->sample[i].startsample, fd); READDW(sf->sample[i].endsample, fd); READDW(sf->sample[i].startloop, fd); READDW(sf->sample[i].endloop, fd); if (sf->version > 1) { /* SF2 only */ READDW(sf->sample[i].samplerate, fd); READB(sf->sample[i].originalPitch, fd); READB(sf->sample[i].pitchCorrection, fd); READW(sf->sample[i].samplelink, fd); READW(sf->sample[i].sampletype, fd); } else { /* for SBK; set missing infos */ sf->sample[i].samplerate = 44100; sf->sample[i].originalPitch = 60; sf->sample[i].pitchCorrection = 0; sf->sample[i].samplelink = 0; /* the first RAM data starts from address 0 */ if (sf->sample[i].startsample == 0) in_rom = 0; if (in_rom) sf->sample[i].sampletype = 0x8001; else sf->sample[i].sampletype = 1; } } } /*================================================================ * convert from bags to layers *================================================================*/ static void convert_layers(SFInfo *sf) { int i; if (prbags.bag == NULL || prbags.gen == NULL || inbags.bag == NULL || inbags.gen == NULL) { fprintf(stderr, "*** illegal bags / gens\n"); return; } for (i = 0; i < sf->npresets - 1; i++) { generate_layers(&sf->preset[i].hdr, &sf->preset[i+1].hdr, &prbags); } for (i = 0; i < sf->ninsts - 1; i++) { generate_layers(&sf->inst[i].hdr, &sf->inst[i+1].hdr, &inbags); } } /*---------------------------------------------------------------- * generate layer lists from stored bags *----------------------------------------------------------------*/ static void generate_layers(SFHeader *hdr, SFHeader *next, SFBags *bags) { int i; SFGenLayer *layp; hdr->nlayers = next->bagNdx - hdr->bagNdx; if (hdr->nlayers < 0) { fprintf(stderr, "illegal layer numbers %d\n", hdr->nlayers); return; } if (hdr->nlayers == 0) return; hdr->layer = (SFGenLayer*)safe_malloc(sizeof(SFGenLayer) * hdr->nlayers); layp = hdr->layer; for (layp = hdr->layer, i = hdr->bagNdx; i < next->bagNdx; layp++, i++) { int genNdx = bags->bag[i]; layp->nlists = bags->bag[i+1] - genNdx; if (layp->nlists < 0) { fprintf(stderr, "illegal list numbers %d\n", layp->nlists); return; } layp->list = (SFGenRec*)safe_malloc(sizeof(SFGenRec) * layp->nlists); memcpy(layp->list, &bags->gen[genNdx], sizeof(SFGenRec) * layp->nlists); } } /*---------------------------------------------------------------- * free a layer *----------------------------------------------------------------*/ static void free_layer(SFHeader *hdr) { int i; for (i = 0; i < hdr->nlayers; i++) { SFGenLayer *layp = &hdr->layer[i]; if (layp->nlists > 0) free(layp->list); } if (hdr->nlayers > 0) free(hdr->layer); } awesfx-0.5.2/awelib/sfitem.c000066400000000000000000000102111344644735400157220ustar00rootroot00000000000000/*================================================================ * sfitem.c * soundfont generator table definition * * Copyright (C) 1996-1999 Takashi Iwai * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *================================================================*/ #include "sflayer.h" #include "sfitem.h" /* layer type definitions */ LayerItem layer_items[SF_EOF] = { {L_INHRT, T_OFFSET, 0, 0, 0}, /* startAddrs */ {L_INHRT, T_OFFSET, 0, 0, 0}, /* endAddrs */ {L_INHRT, T_OFFSET, 0, 0, 0}, /* startloopAddrs */ {L_INHRT, T_OFFSET, 0, 0, 0}, /* endloopAddrs */ {L_INHRT, T_HI_OFF, 0, 0, 0}, /* startAddrsHi */ {L_INHRT, T_PSHIFT, -12000, 12000, 0}, /* lfo1ToPitch */ {L_INHRT, T_PSHIFT, -12000, 12000, 0}, /* lfo2ToPitch */ {L_INHRT, T_PSHIFT, -12000, 12000, 0}, /* env1ToPitch */ {L_INHRT, T_CUTOFF, 1500, 13500, 13500}, /* initialFilterFc */ {L_INHRT, T_FILTERQ, 0, 960, 0}, /* initialFilterQ */ {L_INHRT, T_CSHIFT, -12000, 12000, 0}, /* lfo1ToFilterFc */ {L_INHRT, T_CSHIFT, -12000, 12000, 0}, /* env1ToFilterFc */ {L_INHRT, T_HI_OFF, 0, 0, 0}, /* endAddrsHi */ {L_INHRT, T_TREMOLO, -960, 960, 0}, /* lfo1ToVolume */ {L_INHRT, T_NOP, 0, 0, 0}, /* env2ToVolume / unused1 */ {L_INHRT, T_TENPCT, 0, 1000, 0}, /* chorusEffectsSend */ {L_INHRT, T_TENPCT, 0, 1000, 0}, /* reverbEffectsSend */ {L_INHRT, T_PANPOS, 0, 1000, 0}, /* panEffectsSend */ {L_INHRT, T_NOP, 0, 0, 0}, /* unused */ {L_INHRT, T_NOP, 0, 0, 0}, /* sampleVolume / unused */ {L_INHRT, T_NOP, 0, 0, 0}, /* unused3 */ {L_INHRT, T_TIME, -12000, 5000, -12000}, /* delayLfo1 */ {L_INHRT, T_FREQ, -16000, 4500, 0}, /* freqLfo1 */ {L_INHRT, T_TIME, -12000, 5000, -12000}, /* delayLfo2 */ {L_INHRT, T_FREQ, -16000, 4500, 0}, /* freqLfo2 */ {L_INHRT, T_TIME, -12000, 5000, -12000}, /* delayEnv1 */ {L_INHRT, T_TIME, -12000, 5000, -12000}, /* attackEnv1 */ {L_INHRT, T_TIME, -12000, 5000, -12000}, /* holdEnv1 */ {L_INHRT, T_TIME, -12000, 5000, -12000}, /* decayEnv1 */ {L_INHRT, T_MODSUST, 0, 1000, 0}, /* sustainEnv1 */ {L_INHRT, T_TIME, -12000, 5000, -12000}, /* releaseEnv1 */ {L_INHRT, T_TM_KEY, -1200, 1200, 0}, /* autoHoldEnv1 */ {L_INHRT, T_TM_KEY, -1200, 1200, 0}, /* autoDecayEnv1 */ {L_INHRT, T_TIME, -12000, 5000, -12000}, /* delayEnv2 */ {L_INHRT, T_TIME, -12000, 5000, -12000}, /* attackEnv2 */ {L_INHRT, T_TIME, -12000, 5000, -12000}, /* holdEnv2 */ {L_INHRT, T_TIME, -12000, 5000, -12000}, /* decayEnv2 */ {L_INHRT, T_VOLSUST, 0, 1440, 0}, /* sustainEnv2 */ {L_INHRT, T_TIME, -12000, 5000, -12000}, /* releaseEnv2 */ {L_INHRT, T_TM_KEY, -1200, 1200, 0}, /* autoHoldEnv2 */ {L_INHRT, T_TM_KEY, -1200, 1200, 0}, /* autoDecayEnv2 */ {L_PRSET, T_NOCONV, 0, 0, 0}, /* instrument */ {L_INHRT, T_NOP, 0, 0, 0}, /* nop */ {L_RANGE, T_RANGE, 0, 0, RANGE(0,127)}, /* keyRange */ {L_RANGE, T_RANGE, 0, 0, RANGE(0,127)}, /* velRange */ {L_INHRT, T_HI_OFF, 0, 0, 0}, /* startloopAddrsHi */ {L_OVWRT, T_NOCONV, 0, 127, -1}, /* keynum */ {L_OVWRT, T_NOCONV, 0, 127, -1}, /* velocity */ {L_INHRT, T_ATTEN, 0, 1440, 0}, /* initialAttenuation */ {L_INHRT, T_NOP, 0, 0, 0}, /* keyTuning */ {L_INHRT, T_HI_OFF, 0, 0, 0}, /* endloopAddrsHi */ {L_INHRT, T_NOCONV, -120, 120, 0}, /* coarseTune */ {L_INHRT, T_NOCONV, -99, 99, 0}, /* fineTune */ {L_INSTR, T_NOCONV, 0, 0, 0}, /* sampleId */ {L_OVWRT, T_NOCONV, 0, 3, 0}, /* sampleFlags */ {L_OVWRT, T_NOCONV, 0, 0, 0}, /* samplePitch (only in SBK) */ {L_INHRT, T_SCALE, 0, 1200, 100}, /* scaleTuning */ {L_OVWRT, T_NOCONV, 0, 127, 0}, /* keyExclusiveClass */ {L_OVWRT, T_NOCONV, 0, 127, -1}, /* rootKey */ }; awesfx-0.5.2/awelib/sfopts.c000066400000000000000000000034441344644735400157630ustar00rootroot00000000000000/*================================================================ * global flags * * Copyright (C) 1996-1999 Takashi Iwai * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *================================================================*/ #include #include "sfopts.h" #include "config.h" /* master volume */ #ifndef DEFAULT_VOLUME #define DEFAULT_VOLUME 70 /* 70% */ #endif /* default attenuation sense */ #ifndef DEF_ATTEN_SENSE #define DEF_ATTEN_SENSE 10 #endif sf_options awe_option = { 0, /* add blank */ -1, /* bank */ 0, 0, /* chorus, reverb */ DEFAULT_VOLUME, /* volume */ DEF_ATTEN_SENSE, /* atten sense */ 32, /* default atten */ 50.0, /* decay sense */ NULL, /* search path */ }; /*---------------------------------------------------------------- * estimate default attenuation *----------------------------------------------------------------*/ void awe_init_option(void) { awe_option.default_atten = awe_calc_def_atten(awe_option.atten_sense); } int awe_calc_def_atten(double sense) { if (sense <= 0) { fprintf(stderr, "calc_def_atten: illegal sense %g\n", sense); return 0; } return (int)(35.55 - 35.55/sense); } awesfx-0.5.2/awelib/sfout.c000066400000000000000000000246101344644735400156030ustar00rootroot00000000000000/*---------------------------------------------------------------- * sfout.c: * save to soundfont format * * Copyright (C) 1996-1999 Takashi Iwai * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *----------------------------------------------------------------*/ #include #include #include #include "util.h" #include "sffile.h" #include "config.h" /*---------------------------------------------------------------- * prototypes *----------------------------------------------------------------*/ static void write_header(SFInfo *sf, FILE *fin, FILE *fout); static void write_info(SFInfo *sf, FILE *fin, FILE *fout); static void write_sdta(SFInfo *sf, FILE *fin, FILE *fout); static int calc_pdta_size(SFInfo *sf); static void write_pdta(SFInfo *sf, FILE *fin, FILE *fout); static void copy_file(int size, FILE *fin, FILE *fout); #ifndef WORDS_BIGENDIAN #define READCHUNK(var,fd) fread(&var, 8, 1, fd) #define WRITECHUNK(var,fd) fwrite(&var, 8, 1, fd) #define WRITEW(var,fd) fwrite(&var, 2, 1, fd) #define WRITEDW(var,fd) fwrite(&var, 4, 1, fd) #else #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)) #define READCHUNK(var,fd) {uint32 tmp; fread((var).id, 4, 1, fd);\ fread(&tmp, 4, 1, fd); (var).size = XCHG_LONG(tmp);} #define WRITECHUNK(var,fd) {uint32 tmp; fwrite((var).id, 4, 1, fd);\ tmp = XCHG_LONG((uint32)(var).size); fwrite(&tmp, 8, 1, fd);} #define WRITEW(var,fd) {uint16 tmp = XCHG_SHORT((uint16)(var)); fwrite(&tmp, 2, 1, fd);} #define WRITEDW(var,fd) {uint32 tmp = XCHG_LONG((uint32)(var)); fwrite(&tmp, 4, 1, fd);} #endif #define WRITEB(var,fd) fwrite(&var, 1, 1, fd) #define WRITEID(str,fd) fwrite(str, 4, 1, fd) #define WRITESTR(str,fd) fwrite(str, 20, 1, fd) /*---------------------------------------------------------------- * save the soundfont info to a file *----------------------------------------------------------------*/ void awe_save_soundfont(SFInfo *sf, FILE *fin, FILE *fout) { write_header(sf, fin, fout); write_info(sf, fin, fout); write_sdta(sf, fin, fout); write_pdta(sf, fin, fout); } /*---------------------------------------------------------------- * write RIFF header and sfbk id *----------------------------------------------------------------*/ static void write_header(SFInfo *sf, FILE *fin, FILE *fout) { int32 size; WRITEID("RIFF", fout); size = 4; /* sfbk header */ size += sf->infosize + 4 + 8; /* info list */ size += sf->samplesize + 8 + 4 + 8; /* sdta */ if (sf->version == 1) size += sf->nsamples * 20 + 8; /* snam */ size += calc_pdta_size(sf) + 8; /* pdta */ WRITEDW(size, fout); WRITEID("sfbk", fout); } /*---------------------------------------------------------------- * write info list *----------------------------------------------------------------*/ static void write_info(SFInfo *sf, FILE *fin, FILE *fout) { int32 size, left; WRITEID("LIST", fout); size = sf->infosize + 4; /* size with 'INFO' id */ WRITEDW(size, fout); WRITEID("INFO", fout); left = sf->infosize; fseek(fin, sf->infopos, SEEK_SET); while (left > 0) { SFChunk chunk; READCHUNK(chunk, fin); left -= 8; /* replace INAM */ if (strncmp(chunk.id, "INAM", 4) == 0) { char term = 0; WRITECHUNK(chunk, fout); fwrite(sf->sf_name, chunk.size - 1, 1, fout); WRITEB(term, fout); /* write zero terminator */ fseek(fin, chunk.size, SEEK_CUR); } else { WRITECHUNK(chunk, fout); copy_file(chunk.size, fin, fout); } left -= chunk.size; } } /*---------------------------------------------------------------- * write sdta list *----------------------------------------------------------------*/ static void write_sdta(SFInfo *sf, FILE *fin, FILE *fout) { int32 size; int i; WRITEID("LIST", fout); size = 4; /* size of 'sdta' id */ if (sf->version == 1) size += sf->nsamples * 20 + 8; /* size of 'snam' chunk */ if (sf->samplesize > 0) size += sf->samplesize + 8; /* size of 'smpl' chunk */ WRITEDW(size, fout); WRITEID("sdta", fout); if (sf->version == 1) { WRITEID("snam", fout); size = sf->nsamples * 20; WRITEDW(size, fout); for (i = 0; i < sf->nsamples; i++) { WRITESTR(sf->sample[i].name, fout); } } if (sf->samplesize > 0) { WRITEID("smpl", fout); size = sf->samplesize; WRITEDW(size, fout); fseek(fin, sf->samplepos, SEEK_SET); copy_file(sf->samplesize, fin, fout); } } /*---------------------------------------------------------------- * calculate pdta list size *----------------------------------------------------------------*/ static int calc_pdta_size(SFInfo *sf) { int32 size = 0; int i, j; uint16 bag, gen; /* pdta id */ size = 4; /* phdr chunk */ size += sf->npresets * 38 + 8; /* pbag chunk */ bag = 0; for (i = 0; i < sf->npresets; i++) { if (sf->preset[i].hdr.nlayers <= 0) bag++; else bag += sf->preset[i].hdr.nlayers; } size += bag * 4 + 8; /* pmod chunk */ size += 8; /* pgen chunk */ gen = 0; for (i = 0; i < sf->npresets; i++) { for (j = 0; j < sf->preset[i].hdr.nlayers; j++) gen += sf->preset[i].hdr.layer[j].nlists; } size += gen * 4 + 8; /* ihdr chunk */ size += sf->ninsts * 22 + 8; /* ibag chunk */ bag = 0; for (i = 0; i < sf->ninsts; i++) { if (sf->inst[i].hdr.nlayers <= 0) bag++; else bag += sf->inst[i].hdr.nlayers; } size += bag * 4 + 8; /* imod chunk */ size += 8; /* igen chunk */ gen = 0; for (i = 0; i < sf->ninsts; i++) { for (j = 0; j < sf->inst[i].hdr.nlayers; j++) gen += sf->inst[i].hdr.layer[j].nlists; } size += gen * 4 + 8; /* shdr chunk */ if (sf->version == 1) size += sf->nsamples * 16 + 8; else size += sf->nsamples * 46 + 8; return size; } /*---------------------------------------------------------------- * write pdta list *----------------------------------------------------------------*/ static void write_pdta(SFInfo *sf, FILE *fin, FILE *fout) { int32 size, total_size; int i, j, k; uint16 bag, gen; WRITEID("LIST", fout); size = calc_pdta_size(sf); WRITEDW(size, fout); WRITEID("pdta", fout); total_size = 4; WRITEID("phdr", fout); size = sf->npresets * 38; WRITEDW(size, fout); total_size += size + 8; /* calculate bag size */ bag = 0; for (i = 0; i < sf->npresets; i++) { int32 dummy = 0; WRITESTR(sf->preset[i].hdr.name, fout); WRITEW(sf->preset[i].preset, fout); WRITEW(sf->preset[i].bank, fout); WRITEW(bag, fout); WRITEDW(dummy, fout); WRITEDW(dummy, fout); WRITEDW(dummy, fout); if (sf->preset[i].hdr.nlayers <= 0) bag++; else bag += sf->preset[i].hdr.nlayers; } WRITEID("pbag", fout); size = bag * 4; WRITEDW(size, fout); total_size += size + 8; /* calculate generators size */ gen = 0; for (i = 0; i < sf->npresets; i++) { SFHeader *p = &sf->preset[i].hdr; int16 dummy = 0; if (p->nlayers <= 0) { WRITEW(gen, fout); WRITEW(dummy, fout); continue; } for (j = 0; j < p->nlayers; j++) { WRITEW(gen, fout); WRITEW(dummy, fout); gen += p->layer[j].nlists; } } WRITEID("pmod", fout); size = 0; WRITEDW(size, fout); total_size += size + 8; WRITEID("pgen", fout); size = gen * 4; WRITEDW(size, fout); total_size += size + 8; for (i = 0; i < sf->npresets; i++) { SFHeader *p = &sf->preset[i].hdr; for (j = 0; j < p->nlayers; j++) { for (k = 0; k < p->layer[j].nlists; k++) { WRITEW(p->layer[j].list[k].oper, fout); WRITEW(p->layer[j].list[k].amount, fout); } } } WRITEID("inst", fout); size = sf->ninsts * 22; WRITEDW(size, fout); total_size += size + 8; bag = 0; for (i = 0; i < sf->ninsts; i++) { WRITESTR(sf->inst[i].hdr.name, fout); WRITEW(bag, fout); if (sf->inst[i].hdr.nlayers <= 0) bag++; else bag += sf->inst[i].hdr.nlayers; } WRITEID("ibag", fout); size = bag * 4; WRITEDW(size, fout); total_size += size + 8; gen = 0; for (i = 0; i < sf->ninsts; i++) { SFHeader *p = &sf->inst[i].hdr; int16 dummy = 0; if (p->nlayers <= 0) { WRITEW(gen, fout); WRITEW(dummy, fout); continue; } for (j = 0; j < p->nlayers; j++) { WRITEW(gen, fout); WRITEW(dummy, fout); gen += p->layer[j].nlists; } } WRITEID("imod", fout); size = 0; WRITEDW(size, fout); total_size += size + 8; WRITEID("igen", fout); size = gen * 4; WRITEDW(size, fout); total_size += size + 8; for (i = 0; i < sf->ninsts; i++) { SFHeader *p = &sf->inst[i].hdr; for (j = 0; j < p->nlayers; j++) { for (k = 0; k < p->layer[j].nlists; k++) { WRITEW(p->layer[j].list[k].oper, fout); WRITEW(p->layer[j].list[k].amount, fout); } } } WRITEID("shdr", fout); if (sf->version == 1) size = sf->nsamples * 16; else size = sf->nsamples * 46; WRITEDW(size, fout); total_size += size + 8; for (i = 0; i < sf->nsamples; i++) { if (sf->version > 1) WRITESTR(sf->sample[i].name, fout); WRITEDW(sf->sample[i].startsample, fout); WRITEDW(sf->sample[i].endsample, fout); WRITEDW(sf->sample[i].startloop, fout); WRITEDW(sf->sample[i].endloop, fout); if (sf->version > 1) { /* SF2 only */ WRITEDW(sf->sample[i].samplerate, fout); WRITEB(sf->sample[i].originalPitch, fout); WRITEB(sf->sample[i].pitchCorrection, fout); WRITEW(sf->sample[i].samplelink, fout); WRITEW(sf->sample[i].sampletype, fout); } } if ((size = calc_pdta_size(sf)) != total_size) { fprintf(stderr, "pdta total size differ: %d %d\n", total_size, size); } } /*---------------------------------------------------------------- * copy a block from file to file *----------------------------------------------------------------*/ static void copy_file(int size, FILE *fin, FILE *fout) { static char buf[1024]; int s; for (s = size; s >= sizeof(buf); s -= sizeof(buf)) { fread(buf, sizeof(buf), 1, fin); fwrite(buf, sizeof(buf), 1, fout); } if (s > 0) { fread(buf, s, 1, fin); fwrite(buf, s, 1, fout); } } awesfx-0.5.2/awelib/slist.c000066400000000000000000000152321344644735400156010ustar00rootroot00000000000000/*================================================================ * slist.c: * S-expression list * * Copyright (C) 1996-1999 Takashi Iwai * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *================================================================*/ #include #include #include #include #include "slist.h" #include "util.h" /*---------------------------------------------------------------- * prototypes *----------------------------------------------------------------*/ static SList SReadAtom(FILE *fp, int in_list); static SList SReadList(FILE *fp); static int SReadInt(FILE *fp); static int SReadChr(FILE *fp); static char *SReadFun(FILE *fp); static char *SReadStr(FILE *fp); /*---------------------------------------------------------------- * allocate an atom *----------------------------------------------------------------*/ SList SCons(void) { SList p = (SList)safe_malloc(sizeof(SAtom)); memset(p, 0, sizeof(SAtom)); return p; } /*---------------------------------------------------------------- * read s-expression file *----------------------------------------------------------------*/ SList SReadFile(FILE *fp) { return SReadAtom(fp, FALSE); } /*---------------------------------------------------------------- * free a list *----------------------------------------------------------------*/ void SFree(SList at) { SList nx; while (at) { switch (at->type) { case S_ATOM_LIST: SFree(at->val.p); break; case S_ATOM_STR: case S_ATOM_FUN: free(at->val.s); break; } nx = at->nxt.p; free(at); at = nx; } } /*---------------------------------------------------------------- * return number of members *----------------------------------------------------------------*/ int SIndex(SList list) { int n; if (list == NIL || !SListP(list)) return -1; n = 0; for (list = SCar(list); list; list = SCdr(list)) n++; return n; } /*---------------------------------------------------------------- * file operation *----------------------------------------------------------------*/ /* skip one character */ #define skipc(fp) getc(fp) /* skip one line */ static void skipline(FILE *fp) { int c; while ((c = getc(fp)) != EOF && c != '\n') ; } #define ESC_CHAR '\033' #define todigit(c) ((c) - '0') /* read a character */ static int readchar(int delim, int accept_empty, FILE *fp) { int c, c2, c3; if ((c = getc(fp)) == ESC_CHAR) { if ((c = getc(fp)) == EOF || c == '\n') return EOF; if (isdigit(c)) { if ((c2 = getc(fp)) == EOF || !isdigit(c2)) return EOF; if ((c3 = getc(fp)) == EOF || !isdigit(c3)) return EOF; c = (todigit(c) << 6) | (todigit(c2) << 3) | (todigit(c3)); } } else if (c == delim) { if (! accept_empty) fprintf(stderr, "SList: empty chracter\n"); return EOF; } return c; } /* read a token */ static char *readtoken(char *buf, int delim, FILE *fp) { char *p; int c; p = buf; for (;;) { if (delim) { if ((c = readchar(delim, TRUE, fp)) == EOF) break; } else { if ((c = getc(fp)) == EOF) break; if (isspace(c) || c == '\n') break; if (c == ')') { ungetc(c, fp); break; } } *p++ = c; } *p = 0; return buf; } /* read a character and restore it again */ static int readhead(FILE *fp) { int c; while ((c = getc(fp)) != EOF) { if (!isspace(c) && c != '\n') { if (c == ';' || c == '#') /* comment */ skipline(fp); else { ungetc(c, fp); return c; } } } return EOF; } /*---------------------------------------------------------------- * read an atom *----------------------------------------------------------------*/ static SList SReadAtom(FILE *fp, int in_list) { SList cur; int c; /* skip space and comments */ if ((c = readhead(fp)) == EOF) { if (in_list) fprintf(stderr, "SList: non-closed list\n"); return NIL; } if (c == ')') { /* close list */ skipc(fp); /* skip it */ if (!in_list) fprintf(stderr, "SList: non-matched parenthesis\n"); return NIL; } cur = SCons(); switch (c) { case '(': /* open list */ cur->type = S_ATOM_LIST; cur->val.p = SReadList(fp); break; case '"': /* string */ cur->type = S_ATOM_STR; cur->val.s = SReadStr(fp); break; case '\'': /* char */ cur->type = S_ATOM_CHR; cur->val.c = SReadChr(fp); break; default: if (isdigit(c) || c == '-') { /* int */ cur->type = S_ATOM_INT; cur->val.i = SReadInt(fp); } else { /* func */ cur->type = S_ATOM_FUN; cur->val.f = SReadFun(fp); } break; } return cur; } /* read a list */ static SList SReadList(FILE *fp) { SList head, cur; skipc(fp); /* skip open parenthesis */ head = cur = SReadAtom(fp, TRUE); while (cur) { cur->nxt.p = SReadAtom(fp, TRUE); cur = cur->nxt.p; } return head; } /* read an integer value */ static int SReadInt(FILE *fp) { char str[256]; readtoken(str, 0, fp); return (int)strtol(str, NULL, 0); return 0; } /* read a character value */ static int SReadChr(FILE *fp) { int c; skipc(fp); /* skip leading quote */ c = readchar('\'', FALSE, fp); if (getc(fp) != '\'') fprintf(stderr, "SList: non-closed character\n"); return c; } /* read a constant string */ static char *SReadFun(FILE *fp) { char str[256]; readtoken(str, 0, fp); return safe_strdup(str); } /* read a string */ static char *SReadStr(FILE *fp) { char str[256]; skipc(fp); /* skip reading double quote */ readtoken(str, '"', fp); return safe_strdup(str); } #ifdef DEBUG_MODE /*---------------------------------------------------------------- * print a list recursively *----------------------------------------------------------------*/ void print_list(SList at) { while (at) { switch (at->type) { case S_ATOM_LIST: printf("("); print_list(at->val.p); printf(")\n"); break; case S_ATOM_STR: printf("\"%s\"", at->val.s); break; case S_ATOM_FUN: printf("%s", at->val.s); break; case S_ATOM_INT: printf("%d", at->val.i); break; case S_ATOM_CHR: printf("'%c'", at->val.c); break; default: printf("*unknown*"); break; } at = at->nxt.p; if (at) printf(" "); } } #endif awesfx-0.5.2/aweset.c000066400000000000000000000213371344644735400144730ustar00rootroot00000000000000/*================================================================ * aweset -- set controlling parameters of awe sound driver * * Copyright (C) 1996-2000 Takashi Iwai * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *================================================================*/ #include #include #include #include #include #include #ifdef __FreeBSD__ # include #elif defined(linux) # include #endif #include #include #include "util.h" #include "seq.h" #include "awe_version.h" int verbose = 0; /*---------------------------------------------------------------- * prototypes *----------------------------------------------------------------*/ static void seq_setmode(int mode, int val); static void seq_init_chip(void); static void usage(void); static int search_cmd(char *arg); static void parse_cmd(int argc, char **argv); static void do_cmd(int c, char *arg); static void read_from_file(char *fname); /*---------------------------------------------------------------- * sequencer part *----------------------------------------------------------------*/ SEQ_USE_EXTBUF(); static void seq_setmode(int mode, int val) { AWE_MISC_MODE(awe_dev, mode, val); seqbuf_dump(); } static void seq_init_chip(void) { AWE_INITIALIZE_CHIP(seqfd, awe_dev); } /*---------------------------------------------------------------- * main routine *----------------------------------------------------------------*/ static struct option long_options[] = { {"help", 0, 0, 'h'}, {"verbose", 0, 0, 'v'}, {"file", 1, 0, 'f'}, {"device", 1, 0, 'F'}, {"index", 1, 0, 'D'}, {0,0,0,0}, }; #define OPTIONS "hvf:F:D:" static int file_passed = 0; int main(int argc, char **argv) { int c; char *seq_devname = NULL; int seq_devidx = -1; while ((c = getopt_long(argc, argv, OPTIONS, long_options, NULL)) != -1) { switch (c) { case 'F': seq_devname = optarg; break; case 'D': seq_devidx = atoi(optarg); break; case 'v': verbose = TRUE; break; case 'f': read_from_file(optarg); file_passed = 1; break; default: usage(); return 1; break; } } seq_init(seq_devname, seq_devidx); if (optind < argc) parse_cmd(argc - optind, argv + optind); else if (! file_passed) { usage(); return 1; } seq_end(); return 0; } /*---------------------------------------------------------------- * read commands from the given file *----------------------------------------------------------------*/ #define MAX_LINES 256 #define MAX_ARGS 256 #define DELIMITER " \t\n\r" static void read_from_file(char *fname) { FILE *fp; char line[MAX_LINES]; char *argv[MAX_ARGS]; int argc; if ((fp = fopen(fname, "r")) == NULL) { fprintf(stderr, "error: can't open file '%s'\n", fname); exit(1); } argc = 0; while (fgets(line, sizeof(line), fp)) { char *p = strtok(line, DELIMITER); if (p) { argv[0] = p; argc = 1; while ((p = strtok(NULL, DELIMITER)) != NULL) { argv[argc++] = p; if (argc >= MAX_ARGS) break; } parse_cmd(argc, argv); } } fclose(fp); } /*---------------------------------------------------------------- * command definitions *----------------------------------------------------------------*/ enum { CT_NONE, CT_BOOL, CT_BYTE, CT_WORD, }; typedef struct CtrlParmDefs { char *longcmd; int shortcmd; char *desc; int mode; int type; int defval; } CtrlParmDefs; static CtrlParmDefs ctrl_parms[] = { { "init", 'i', "initialize AWE chip and state", -1, CT_NONE, TRUE }, { "exclusive", 'e', "exclusive note mode", AWE_MD_EXCLUSIVE_SOUND, CT_BOOL, TRUE }, { "realpan", 'p', "realtime panning change", AWE_MD_REALTIME_PAN, CT_BOOL, TRUE }, { "gusbank", 'g', "GUS-instrument bank number", AWE_MD_GUS_BANK, CT_BYTE, 0 }, { "keepeffect", 'k', "keep effect controls after clearing voices", AWE_MD_KEEP_EFFECT, CT_BOOL, FALSE }, { "zeroatten", 'z', "zero attenuation level", AWE_MD_ZERO_ATTEN, CT_BYTE, 32 }, { "chnprior", 'C', "channel priority mode", AWE_MD_CHN_PRIOR, CT_BOOL, FALSE }, { "modsense", 'm', "modulation wheel sense", AWE_MD_MOD_SENSE, CT_BYTE, 18 }, { "defpreset", 'P', "default preset number", AWE_MD_DEF_PRESET, CT_BYTE, 0 }, { "defbank", 'B', "default bank number", AWE_MD_DEF_BANK, CT_BYTE, 0 }, { "defdrum", 'D', "default drumset number", AWE_MD_DEF_DRUM, CT_BYTE, 0 }, { "toggledrum", 'a', "accept to change bank on drum channels", AWE_MD_TOGGLE_DRUM_BANK, CT_BOOL, FALSE }, { "newvolume", 'n', "Win-like volume calculation method", AWE_MD_NEW_VOLUME_CALC, CT_BOOL, TRUE }, { "chorus", 'c', "chorus mode", AWE_MD_CHORUS_MODE, CT_BYTE, 2 }, { "reverb", 'r', "reverb mode", AWE_MD_REVERB_MODE, CT_BYTE, 4 }, { "bass", 'b', "equalizer bass level", AWE_MD_BASS_LEVEL, CT_BYTE, 5 }, { "treble", 't', "equalizer treble level", AWE_MD_TREBLE_LEVEL, CT_BYTE, 9 }, { "debug", 'd', "debug mode", AWE_MD_DEBUG_MODE, CT_BYTE, 0 }, { "panexchange", 'x', "exchange panning direction", AWE_MD_PAN_EXCHANGE, CT_BOOL, FALSE }, }; #define numberof(ary) (sizeof(ary)/sizeof(ary[0])) /*---------------------------------------------------------------- * print usage *----------------------------------------------------------------*/ static void usage(void) { int i; fprintf(stderr, "aweset -- control awedrv parameters\n"); fprintf(stderr, VERSION_NOTE); fprintf(stderr, "usage: aweset [-options] command [argument] ...\n"); fprintf(stderr, " options:\n"); fprintf(stderr, " --help, -h: put this message\n"); fprintf(stderr, " --verbose, -v: verbose mode\n"); fprintf(stderr, " --file=config, -f: read commands from file\n"); fprintf(stderr, " commands: name (abbrev) argument : description\n"); for (i = 0; i < numberof(ctrl_parms); i++) { fprintf(stderr, " %10s (%c)", ctrl_parms[i].longcmd, ctrl_parms[i].shortcmd); switch (ctrl_parms[i].type) { case CT_NONE: fprintf(stderr, " --- : %s\n", ctrl_parms[i].desc); break; case CT_BOOL: fprintf(stderr, " bool : %s (default:%s)\n", ctrl_parms[i].desc, (ctrl_parms[i].defval ? "on" : "off")); break; default: fprintf(stderr, " value: %s (default:%d)\n", ctrl_parms[i].desc, ctrl_parms[i].defval); break; } } } /*---------------------------------------------------------------- * search the command mathing with given string *----------------------------------------------------------------*/ static int search_cmd(char *arg) { int i; if (! *arg) return -1; for (i = 0; i < numberof(ctrl_parms); i++) { if (strcmp(arg, ctrl_parms[i].longcmd) == 0) return i; } if (arg[1]) return -1; for (i = 0; i < numberof(ctrl_parms); i++) { if (*arg == ctrl_parms[i].shortcmd) return i; } return -1; } /*---------------------------------------------------------------- * parse command line arguments *----------------------------------------------------------------*/ static void parse_cmd(int argc, char **argv) { int c, cmd; char *p; for (c = 0; c < argc; c++) { if ((cmd = search_cmd(argv[c])) >= 0) { if (ctrl_parms[cmd].type != CT_NONE && c >= argc - 1) { fprintf(stderr, "error: no argument is given for command '%s'\n", ctrl_parms[cmd].longcmd); exit(1); } do_cmd(cmd, argv[c + 1]); if (ctrl_parms[cmd].type != CT_NONE) c++; } else if ((p = strchr(argv[c], '=')) != NULL) { *p = 0; if ((cmd = search_cmd(argv[c])) < 0) { fprintf(stderr, "error: invalid command '%s'\n", argv[c]); exit(1); } do_cmd(cmd, p + 1); } } } /*---------------------------------------------------------------- * call sequencer routines *----------------------------------------------------------------*/ static void do_cmd(int c, char *arg) { int val; switch (ctrl_parms[c].type) { case CT_NONE: if (ctrl_parms[c].mode == -1) { if (verbose) fprintf(stderr, "initializing AWE chip\n"); seq_init_chip(); } return; case CT_BOOL: val = bool_val(arg); break; default: val = (int)strtol(arg, NULL, 0); break; } if (verbose) fprintf(stderr, "set %s to %d\n", ctrl_parms[c].longcmd, val); seq_setmode(ctrl_parms[c].mode, val); } awesfx-0.5.2/configure.in000066400000000000000000000021131344644735400153370ustar00rootroot00000000000000AC_INIT([awesfx],[0.5.2],[tiwai@suse.de],[awesfx]) AM_INIT_AUTOMAKE([gnu dist-bzip2]) AC_CONFIG_SRCDIR([asfxload.c]) AM_CONFIG_HEADER([include/config.h]) AC_PROG_CC AC_PROG_INSTALL AC_HEADER_STDC AC_C_BIGENDIAN AM_PROG_LIBTOOL AM_PATH_ALSA(1.0.0) AC_ARG_WITH(default-volume, [ --with-default-volume=percent Default volume (in percent)], DEFAULT_VOLUME="$withval", DEFAULT_VOLUME=70) AC_DEFINE_UNQUOTED(DEFAULT_VOLUME, $DEFAULT_VOLUME, [default volume (in percent)]) AC_ARG_WITH(default-atten, [ --with-default-atten=percent Default attenuation sense], DEF_ATTEN_SENSE="$withval", DEF_ATTEN_SENSE=10) AC_DEFINE_UNQUOTED(DEF_ATTEN_SENSE, $DEF_ATTEN_SENSE, [default attenuation sense (-a)]) AC_ARG_WITH(sfpath, [ --with-sfpath=path(s) Default SoundFont path], DEFAULT_SF_PATH="$withval", DEFAULT_SF_PATH="/usr/share/sounds/sf2:/usr/share/sfbank:/usr/local/lib/sfbank") AC_DEFINE_UNQUOTED(DEFAULT_SF_PATH, "$DEFAULT_SF_PATH", [default SoundFont path]) AC_OUTPUT([ Makefile awelib/Makefile include/Makefile samples/Makefile include/awe_version.h etc/Makefile ]) awesfx-0.5.2/etc/000077500000000000000000000000001344644735400136045ustar00rootroot00000000000000awesfx-0.5.2/etc/.cvsignore000066400000000000000000000000251344644735400156010ustar00rootroot00000000000000Makefile Makefile.in awesfx-0.5.2/etc/41-soundfont.rules000066400000000000000000000001431344644735400171170ustar00rootroot00000000000000SUBSYSTEM=="sound", KERNEL=="hwC?D2", DRIVERS=="EMU10K1_Audigy", RUN+="/etc/alsa.d/udev-soundfont" awesfx-0.5.2/etc/Makefile.am000066400000000000000000000001121344644735400156320ustar00rootroot00000000000000EXTRA_DIST = awesfx.spec load-soundfont udev-soundfont 41-soundfont.rules awesfx-0.5.2/etc/awesfx.spec000066400000000000000000000053431344644735400157620ustar00rootroot00000000000000# # spec file for package awesfx (Version 0.5.1) # # Copyright (c) 2004 SUSE LINUX AG, Nuernberg, Germany. # This file and all modifications and additions to the pristine # package are under the same license as the package itself. # # Please submit bugfixes or comments via http://www.suse.de/feedback/ # # norootforbuild Name: awesfx BuildRequires: alsa-devel Summary: SoundFont utilities for SB AWE32/64 and Emu10k1 drivers Version: 0.5.1 Release: 1 License: GPL Group: Productivity/Multimedia/Sound/Midi BuildRoot: %{_tmppath}/%{name}-%{version}-build URL: http://www.alsa-project.org/~iwai/awedrv.html Source: awesfx-%{version}.tar.bz2 Source1: udev-soundfont Source2: load-soundfont Source3: 41-soundfont.rules %description The AWESFX package includes utility programs for controlling the wavetable function on SB AWE32/64 and Emu10k1 soundcards. Authors: -------- Takashi Iwai %prep %setup %{?suse_update_config:%{suse_update_config -f}} %build autoreconf -fi %configure make %install make DESTDIR=$RPM_BUILD_ROOT install # install udev and helper scripts mkdir -p $RPM_BUILD_ROOT/etc/udev/rules.d cp $RPM_SOURCE_DIR/*.rules $RPM_BUILD_ROOT/etc/udev/rules.d mkdir -p $RPM_BUILD_ROOT/etc/alsa.d cp %{SOURCE1} $RPM_BUILD_ROOT/etc/alsa.d cp %{SOURCE2} $RPM_BUILD_ROOT/etc/alsa.d %clean [ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT %files %defattr(-,root,root) %doc AUTHORS COPYING README ChangeLog NEWS %doc *.txt %{_bindir}/* %dir %{_datadir}/sounds/sf2 %{_datadir}/sounds/sf2/* %doc %{_mandir}/*/* /etc/udev /etc/alsa.d %changelog -n awesfx * Wed Jan 25 2006 - mls@suse.de - converted neededforbuild to BuildRequires * Tue Aug 31 2004 - tiwai@suse.de - updated to version 0.5.0d. (misc fixes only) * Fri Feb 27 2004 - tiwai@suse.de - updated to version 0.5.0b. * Wed Feb 04 2004 - tiwai@suse.de - updated to version 0.5.0a. * Fri Jan 23 2004 - tiwai@suse.de - updated to version 0.5.0. using auto-tools now. ALSA emux loader is added. * Sun Jan 11 2004 - adrian@suse.de - add %%defattr * Fri Mar 08 2002 - kukuk@suse.de - Add /usr/share/sounds/sf2 to filelist * Tue Jan 08 2002 - tiwai@suse.de - fixed buffer overflow with a long HOME env. variable. * Fri Sep 21 2001 - tiwai@suse.de - Fixed a bug in incremental loading: duplication of instrument layers are avoided. * Tue Feb 27 2001 - tiwai@suse.de - Apply the forgotten patch. * Fri Jan 05 2001 - tiwai@suse.de - Removed CVS directories from source archive. - Strip installed binaries. * Tue Dec 05 2000 - tiwai@suse.de - Move default soundfont directory to /usr/share/sounds/sf2. * Thu Sep 14 2000 - tiwai@suse.de - Fixed version number and documents. * Tue Aug 01 2000 - tiwai@suse.de - Initial version: 0.4.4 awesfx-0.5.2/etc/load-soundfont000066400000000000000000000012241344644735400164620ustar00rootroot00000000000000#!/bin/sh -e CARD=$1 shift test -x /usr/bin/asfxload || exit 0 . /etc/sysconfig/sound load_sf () { for d in /usr/share/sounds/sf2 \ /usr/share/sfbank \ /usr/local/lib/sfbank \ /usr/share/sfbank/creative \ /usr/local/lib/sfbank/creative \ ; do if [ -r $d/$1 ]; then /usr/bin/asfxload -Dhw:${CARD},2 $d/$1 return 0 fi done return 1 } case $SOUNDFONT_FILES in /*) if [ -r "$SOUNDFONT_FILES" ]; then /usr/bin/asfxload -Dhw:${CARD},2 $SOUNDFONT_FILES exit 0 fi ;; esac for file in $SOUNDFONT_FILES $* ; do if load_sf $file ; then break fi done exit 0 awesfx-0.5.2/etc/udev-soundfont000066400000000000000000000007101344644735400165050ustar00rootroot00000000000000#!/bin/sh -e CARD=${DEVNAME##/dev/snd/hwC} CARD=${CARD%%D2} case $DEVPATH in */pci*) # Emu10k1 / Audigy, send a MIDI sequence to activate breakout-box echo -en "\xf0\x00\x20\x21\x61\x00\x00\x00\x7f\x00\xf7" > /dev/snd/midiC${CARD}D1 /etc/alsa.d/load-soundfont $CARD default.bnk default.sf2 ;; *) # SB AWE can use ROM as fallback /etc/alsa.d/load-soundfont $CARD default.bnk default.sf2 default.sbk gu11-rom.sf2 GU11-ROM.SF2 ;; esac exit 0 awesfx-0.5.2/gusload.c000066400000000000000000000256721344644735400146470ustar00rootroot00000000000000/*================================================================ * gusload -- load a GUS patch file on AWE32 sound driver * * Copyright (C) 1996-2000 Takashi Iwai * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *================================================================*/ #include #include #include #include #include #include #ifdef BUILD_AGUSLOAD #include #endif #ifdef __FreeBSD__ # include #elif defined(linux) # include #endif #include "guspatch.h" #include "seq.h" #include "util.h" #include "awe_version.h" #ifdef BUILD_AGUSLOAD #define PROGNAME "agusload" #else #define PROGNAME "gusload" #endif void seq_load_gus(FILE *fd); static void usage() { fprintf(stderr, PROGNAME " -- load GUS patch file on AWE32 sound driver\n"); fprintf(stderr, VERSION_NOTE); fprintf(stderr, "usage: " PROGNAME " [-options] GUSpatch\n" #ifdef BUILD_AGUSLOAD " -D, --hwdep=name specify the hwdep name\n" #else " -F, --device=file specify the device file\n" " -D, --index=number specify the device index (-1=autoprobe)\n" #endif " -v verbose mode\n" " -p number set instrument number (default is internal value)\n" " -b number set bank number (default is 0)\n" " -k keynote set fixed keynote\n"); exit(1); } static int clear_sample = FALSE; static int preset = -1; static int bankchange = -1; static int keynote = -1; int awe_verbose; #ifdef BUILD_AGUSLOAD #define OPTION_FLAGS "b:p:k:viD:" #else #define OPTION_FLAGS "b:p:k:viF:D:" #endif int main(int argc, char **argv) { FILE *fd; char *gusfile; int c; #ifdef BUILD_AGUSLOAD char *hwdep_name = NULL; #else char *seq_devname = NULL; int seq_devidx = -1; #endif while ((c = getopt(argc, argv, OPTION_FLAGS)) != -1) { switch (c) { #ifdef BUILD_AGUSLOAD case 'D': hwdep_name = optarg; break; #else case 'F': seq_devname = optarg; break; case 'D': seq_devidx = atoi(optarg); break; #endif case 'v': if (optarg) awe_verbose = atoi(optarg); else awe_verbose++; break; case 'b': bankchange = atoi(optarg); break; case 'p': preset = atoi(optarg); break; case 'k': keynote = atoi(optarg); break; case 'i': clear_sample = TRUE; break; default: usage(); return 1; } } if (argc - optind < 1) { usage(); return 1; } gusfile = argv[optind]; optind++; if ((fd = fopen(gusfile, "r")) == NULL) { fprintf(stderr, "can't open GUS patch file %s\n", gusfile); return 1; } /* open awe sequencer device */ #ifdef BUILD_AGUSLOAD seq_alsa_init(hwdep_name); #else seq_init(seq_devname, seq_devidx); #endif if (clear_sample) seq_reset_samples(); DEBUG(0,fprintf(stderr, "uploading samples..\n")); seq_load_gus(fd); DEBUG(0,printf("DRAM memory left = %d kB\n", seq_mem_avail()/1024)); /* close sequencer */ #ifdef BUILD_AGUSLOAD seq_alsa_end(); #else seq_end(); #endif fclose(fd); return 0; } static GusPatchHeader header; static GusInstrument ins; static GusLayerData layer; static GusPatchData sample; #define freq_to_note(mhz) (int)(log((double)mhz / 8176.0) / log(2.0) * 1200.0) /* * load voice record to the awe driver */ void seq_load_gus(FILE *fp) { int j, len; struct patch_info *patch; /* Unix based routines, assume big-endian machine */ /* read header */ DEBUG(1,fprintf(stderr, "reading header\n")); fread(&header.header, sizeof(header.header), 1, fp); fread(&header.gravis_id, sizeof(header.gravis_id), 1, fp); fread(&header.description, sizeof(header.description), 1, fp); fread(&header.instruments, sizeof(header.instruments), 1, fp); fread(&header.voices, sizeof(header.voices), 1, fp); fread(&header.channels, sizeof(header.channels), 1, fp); fread(&header.wave_forms, sizeof(header.wave_forms), 1, fp); header.wave_forms = swapi( header.wave_forms ); fread(&header.master_volume, sizeof(header.master_volume), 1, fp); header.master_volume = swapi( header.master_volume ); fread(&header.data_size, sizeof(header.data_size), 1, fp); header.data_size = swapl( header.data_size ); fread(&header.reserved, sizeof(header.reserved), 1, fp); /* read instrument header */ DEBUG(1,fprintf(stderr, "reading instrument\n")); fread(&ins.instrument, sizeof(ins.instrument), 1, fp); fread(&ins.instrument_name, sizeof(ins.instrument_name), 1, fp); fread(&ins.instrument_size, sizeof(ins.instrument_size), 1, fp); ins.instrument_size = swapl( ins.instrument_size ); fread(&ins.layers, sizeof(ins.layers), 1, fp); fread(&ins.reserved, sizeof(ins.reserved), 1, fp); /* read layer header */ DEBUG(1,fprintf(stderr, "reading layer\n")); fread(&layer.layer_duplicate, sizeof(layer.layer_duplicate), 1, fp); fread(&layer.layer, sizeof(layer.layer), 1, fp); fread(&layer.layer_size, sizeof(layer.layer_size), 1, fp); layer.layer_size = swapl( layer.layer_size ); fread(&layer.samples, sizeof(layer.samples), 1, fp); fread(&layer.reserved, sizeof(layer.reserved), 1, fp); if (strcmp(header.gravis_id, "ID#000002") != 0) { fprintf(stderr, "Not a GUS patch file\n"); exit(1); } DEBUG(0,fprintf(stderr, "data size = %d\n", (int)header.data_size)); /* read sample information */ for (j = 0; j < layer.samples; j++) { /* read sample information */ DEBUG(1,fprintf(stderr, "reading sample(%d)\n", j)); fread(&sample.wave_name, sizeof(sample.wave_name), 1, fp); fread(&sample.fractions, sizeof(sample.fractions), 1, fp); fread(&sample.wave_size, sizeof(sample.wave_size), 1, fp); sample.wave_size = swapl( sample.wave_size ); fread(&sample.start_loop, sizeof(sample.start_loop), 1, fp); fread(&sample.end_loop, sizeof(sample.end_loop), 1, fp); fread(&sample.sample_rate, sizeof(sample.sample_rate), 1, fp); sample.sample_rate = swapi( sample.sample_rate ); fread(&sample.low_frequency, sizeof(sample.low_frequency), 1, fp); fread(&sample.high_frequency, sizeof(sample.high_frequency), 1, fp); fread(&sample.root_frequency, sizeof(sample.root_frequency), 1, fp); fread(&sample.tune, sizeof(sample.tune), 1, fp); fread(&sample.balance, sizeof(sample.balance), 1, fp); fread(&sample.envelope_rate, sizeof(sample.envelope_rate), 1, fp); fread(&sample.envelope_offset, sizeof(sample.envelope_offset), 1, fp); fread(&sample.tremolo_sweep, sizeof(sample.tremolo_sweep), 1, fp); fread(&sample.tremolo_rate, sizeof(sample.tremolo_rate), 1, fp); fread(&sample.tremolo_depth, sizeof(sample.tremolo_depth), 1, fp); fread(&sample.vibrato_sweep, sizeof(sample.vibrato_sweep), 1, fp); fread(&sample.vibrato_rate, sizeof(sample.vibrato_rate), 1, fp); fread(&sample.vibrato_depth, sizeof(sample.vibrato_depth), 1, fp); fread(&sample.modes, sizeof(sample.modes), 1, fp); fread(&sample.scale_frequency, sizeof(sample.scale_frequency), 1, fp); fread(&sample.scale_factor, sizeof(sample.scale_factor), 1, fp); sample.scale_factor = swapi( sample.scale_factor ); fread(&sample.reserved, sizeof(sample.reserved), 1, fp); DEBUG(1,fprintf(stderr, "-- sample len = %d\n", (int)sample.wave_size)); /* allocate sound driver patch data */ len = sizeof(struct patch_info) + sample.wave_size - 1; patch = (struct patch_info*)calloc(len, 1); if (patch == NULL) { fprintf(stderr, "can't allocate patch buffer\n"); exit(1); } patch->key = GUS_PATCH; #ifndef BUILD_AGUSLOAD patch->device_no = awe_dev; #endif if (preset >= 0) patch->instr_no = preset; else patch->instr_no = ins.instrument; DEBUG(0,fprintf(stderr,"-- preset=%d\n", patch->instr_no)); patch->mode = sample.modes; DEBUG(0,fprintf(stderr,"-- sample_mode=0x%x\n", patch->mode)); patch->len = sample.wave_size; patch->loop_start = sample.start_loop; patch->loop_end = sample.end_loop; DEBUG(1,fprintf(stderr,"-- loop position=%d/%d\n", patch->loop_start, patch->loop_end)); patch->base_freq = sample.sample_rate; if (keynote != -1) { /*int note = freq_to_note(sample.root_frequency);*/ int low = freq_to_note(sample.low_frequency); int high = freq_to_note(sample.high_frequency); if (keynote < low / 100 || high / 100 < keynote) continue; low = (low / 100) * 100; patch->base_note = (int)(pow(2.0, (double)(keynote * 100 - low) / 1200.0) * sample.root_frequency); patch->low_note = (int)(pow(2.0, (double)keynote / 12.0) * 8176.0); patch->high_note = patch->low_note; } else { patch->base_note = sample.root_frequency; patch->high_note = sample.high_frequency; patch->low_note = sample.low_frequency; } DEBUG(0,fprintf(stderr,"-- base freq=%d, note=%d[%d] (%d[%d]-%d[%d])\n", (int)patch->base_freq, (int)patch->base_note, freq_to_note(patch->base_note)/100, (int)patch->low_note, freq_to_note(patch->low_note)/100, (int)patch->high_note, freq_to_note(patch->high_note)/100)); patch->panning = sample.balance; patch->detuning = sample.tune; memcpy(patch->env_rate, sample.envelope_rate, 6); memcpy(patch->env_offset, sample.envelope_offset, 6); if (sample.tremolo_rate > 0 && sample.tremolo_depth > 0) patch->mode |= WAVE_TREMOLO; patch->tremolo_sweep = sample.tremolo_sweep; patch->tremolo_rate = sample.tremolo_rate; patch->tremolo_depth = sample.tremolo_depth; DEBUG(0,fprintf(stderr,"-- tremolo rate=%d, depth=%d\n", patch->tremolo_rate, patch->tremolo_depth)); if (sample.vibrato_rate > 0 && sample.vibrato_depth > 0) patch->mode |= WAVE_VIBRATO; patch->vibrato_sweep = sample.vibrato_sweep; patch->vibrato_rate = sample.vibrato_rate; patch->vibrato_depth = sample.vibrato_depth; DEBUG(0,fprintf(stderr,"-- vibrato rate=%d, depth=%d\n", patch->vibrato_rate, patch->vibrato_depth)); patch->scale_frequency = sample.scale_frequency; patch->scale_factor = sample.scale_factor; patch->volume = header.master_volume; #if SOUND_VERSION > 301 patch->fractions = sample.fractions; #endif /* allocate raw sample buffer */ DEBUG(1,fprintf(stderr, "-- reading wave data\n")); fread(patch->data, 1, patch->len, fp); /* if -b option is specified, change the bank value */ if (bankchange >= 0) { DEBUG(1,fprintf(stderr, "-- set bank number\n")); seq_set_gus_bank(bankchange); } DEBUG(1,fprintf(stderr, "-- transferring\n")); if (seq_load_rawpatch(patch, len) < 0) { fprintf(stderr, "[Loading GUS %d]\n", j); perror("Error in loading info"); exit(1); } /* free temporary buffer */ free(patch); /* exit loop if keynote is fixed */ if (keynote != -1) break; } } awesfx-0.5.2/guspatch.h000066400000000000000000000041051344644735400150200ustar00rootroot00000000000000/*================================================================ * guspatch.h * patch structure of GUS compatible patch file *================================================================*/ #ifndef GUSPATCH_H_DEF #define GUSPATCH_H_DEF #include "itypes.h" #define GUS_ENVELOPES 6 /* This is the definition for what FORTE's patch format is. All .PAT */ /* files will have this format. */ #define GUS_HEADER_SIZE 12 #define GUS_ID_SIZE 10 #define GUS_DESC_SIZE 60 #define GUS_RESERVED_SIZE 40 #define GUS_PATCH_HEADER_RESERVED_SIZE 36 #define GUS_LAYER_RESERVED_SIZE 40 #define GUS_PATCH_DATA_RESERVED_SIZE 36 #define GUS_GF1_HEADER_TEXT "GF1PATCH110" typedef struct { char header[ GUS_HEADER_SIZE ]; char gravis_id[ GUS_ID_SIZE ]; /* Id = "ID#000002" */ char description[ GUS_DESC_SIZE ]; byte instruments; char voices; char channels; uint16 wave_forms; uint16 master_volume; uint32 data_size; char reserved[ GUS_PATCH_HEADER_RESERVED_SIZE ]; } GusPatchHeader; typedef struct { uint16 instrument; char instrument_name[ 16 ]; int32 instrument_size; char layers; char reserved[ GUS_RESERVED_SIZE ]; } GusInstrument; typedef struct { char layer_duplicate; char layer; int32 layer_size; char samples; char reserved[ GUS_LAYER_RESERVED_SIZE ]; } GusLayerData; typedef struct { char wave_name[7]; byte fractions; int32 wave_size; int32 start_loop; int32 end_loop; uint16 sample_rate; int32 low_frequency; int32 high_frequency; int32 root_frequency; int16 tune; byte balance; byte envelope_rate[ GUS_ENVELOPES ]; byte envelope_offset[ GUS_ENVELOPES ]; byte tremolo_sweep; byte tremolo_rate; byte tremolo_depth; byte vibrato_sweep; byte vibrato_rate; byte vibrato_depth; char modes; #define GUS_MODE_16BIT 1 #define GUS_MODE_UNSIGNED 2 #define GUS_MODE_LOOP 4 #define GUS_MODE_LOOP_BIDIR 8 #define GUS_MODE_LOOP_BACK 16 #define GUS_MODE_SUSTAIN 32 #define GUS_MODE_ENVELOPE 64 int16 scale_frequency; uint16 scale_factor; /* from 0 to 2048 or 0 to 2 */ char reserved[ GUS_PATCH_DATA_RESERVED_SIZE ]; } GusPatchData; #endif awesfx-0.5.2/include/000077500000000000000000000000001344644735400144545ustar00rootroot00000000000000awesfx-0.5.2/include/.cvsignore000066400000000000000000000001001344644735400164430ustar00rootroot00000000000000Makefile Makefile.in awe_version.h config.h config.h.in stamp-* awesfx-0.5.2/include/Imakefile000066400000000000000000000004011344644735400162600ustar00rootroot00000000000000#include "../awelib/config.h" INSTDIR = /usr/local INCDIR = $(INSTDIR)/include/awe HEADERS = awebank.h aweseq.h awe_parm.h sffile.h itypes.h sfitem.h sflayer.h\ sfopts.h slist.h util.h #ifdef INSTALL_AWELIB InstallMultiple($(HEADERS), $(INCDIR)) #endif awesfx-0.5.2/include/Makefile.am000066400000000000000000000002351344644735400165100ustar00rootroot00000000000000noinst_HEADERS = \ awe_parm.h awe_voice.h awebank.h aweseq.h itypes.h sffile.h sfitem.h \ sflayer.h sfopts.h slist.h util.h EXTRA_DIST = awe_version.h.in awesfx-0.5.2/include/awe_parm.h000066400000000000000000000037671344644735400164350ustar00rootroot00000000000000/*================================================================ * awe_parm.h -- convert to Emu8000 native parameters * * Copyright (C) 1996-1999 Takashi Iwai * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *================================================================*/ #ifndef AWE_PARM_H_DEF #define AWE_PARM_H_DEF #include void awe_init_parm(awe_voice_parm *pp); void awe_init_voice(awe_voice_info *vp); int awe_timecent_to_msec(int timecent); int awe_msec_to_timecent(int msec); int awe_abscent_to_mHz(int abscents); int awe_mHz_to_abscent(int mHz); int awe_Hz_to_abscent(int Hz); int awe_abscent_to_Hz(int abscents); short awe_calc_rate_offset(int Hz); unsigned short awe_calc_delay(int tcent); unsigned short awe_calc_atkhld(int atk_tcent, int hld_tcent); unsigned char awe_calc_sustain(int sust_cB); unsigned char awe_calc_mod_sustain(int sust_cB); unsigned char awe_calc_decay(int dcy_tcent); unsigned char awe_calc_cutoff(int abscents); unsigned char awe_calc_filterQ(int gain_cB); unsigned char awe_calc_pitch_shift(int cents); unsigned char awe_calc_cutoff_shift(int cents, int octave_shift); unsigned short awe_calc_tremolo(int vol_cB); unsigned char awe_calc_freq(int abscents); char awe_calc_pan(int val); unsigned char awe_calc_chorus(int val); unsigned char awe_calc_reverb(int val); unsigned char awe_calc_attenuation(int att_cB); #endif awesfx-0.5.2/include/awe_version.h.in000066400000000000000000000002531344644735400175530ustar00rootroot00000000000000#define VERSION_STR "@PACKAGE_VERSION@" #define COPYRIGHT_STR "copyright (c) 1996-2003 by Takashi Iwai" #define VERSION_NOTE " ver." VERSION_STR " " COPYRIGHT_STR "\n" awesfx-0.5.2/include/awe_voice.h000066400000000000000000000477521344644735400166050ustar00rootroot00000000000000/* * sound/awe_voice.h * * Voice information definitions for the low level driver for the * AWE32/SB32/AWE64 wave table synth. * version 0.4.4; Jan. 4, 2000 * * Copyright (C) 1996-2000 Takashi Iwai * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef AWE_VOICE_H #define AWE_VOICE_H #ifndef SAMPLE_TYPE_AWE32 #define SAMPLE_TYPE_AWE32 0x20 #endif #define _LINUX_PATCHKEY_H_INDIRECT #include #undef _LINUX_PATCHKEY_H_INDIRECT /*---------------------------------------------------------------- * patch information record *----------------------------------------------------------------*/ /* patch interface header: 16 bytes */ typedef struct awe_patch_info { short key; /* use AWE_PATCH here */ #define AWE_PATCH _PATCHKEY(0x07) short device_no; /* synthesizer number */ unsigned short sf_id; /* file id (should be zero) */ short optarg; /* optional argument */ int len; /* data length (without this header) */ short type; /* patch operation type */ #define AWE_LOAD_INFO 0 /* awe_voice_rec */ #define AWE_LOAD_DATA 1 /* awe_sample_info */ #define AWE_OPEN_PATCH 2 /* awe_open_parm */ #define AWE_CLOSE_PATCH 3 /* none */ #define AWE_UNLOAD_PATCH 4 /* none */ #define AWE_REPLACE_DATA 5 /* awe_sample_info (optarg=#channels)*/ #define AWE_MAP_PRESET 6 /* awe_voice_map */ /*#define AWE_PROBE_INFO 7*/ /* awe_voice_map (pat only) */ #define AWE_PROBE_DATA 8 /* optarg=sample */ #define AWE_REMOVE_INFO 9 /* optarg=(bank<<8)|instr */ #define AWE_LOAD_CHORUS_FX 0x10 /* awe_chorus_fx_rec (optarg=mode) */ #define AWE_LOAD_REVERB_FX 0x11 /* awe_reverb_fx_rec (optarg=mode) */ short reserved; /* word alignment data */ /* the actual patch data begins after this */ #if defined(AWE_COMPAT_030) && AWE_COMPAT_030 char data[0]; #endif } awe_patch_info; /*#define AWE_PATCH_INFO_SIZE 16*/ #define AWE_PATCH_INFO_SIZE sizeof(awe_patch_info) /*---------------------------------------------------------------- * open patch *----------------------------------------------------------------*/ #define AWE_PATCH_NAME_LEN 32 typedef struct _awe_open_parm { unsigned short type; /* sample type */ #define AWE_PAT_TYPE_MISC 0 #define AWE_PAT_TYPE_GM 1 #define AWE_PAT_TYPE_GS 2 #define AWE_PAT_TYPE_MT32 3 #define AWE_PAT_TYPE_XG 4 #define AWE_PAT_TYPE_SFX 5 #define AWE_PAT_TYPE_GUS 6 #define AWE_PAT_TYPE_MAP 7 #define AWE_PAT_LOCKED 0x100 /* lock the samples */ #define AWE_PAT_SHARED 0x200 /* sample is shared */ short reserved; char name[AWE_PATCH_NAME_LEN]; } awe_open_parm; /*#define AWE_OPEN_PARM_SIZE 28*/ #define AWE_OPEN_PARM_SIZE sizeof(awe_open_parm) /*---------------------------------------------------------------- * raw voice information record *----------------------------------------------------------------*/ /* wave table envelope & effect parameters to control EMU8000 */ typedef struct _awe_voice_parm { unsigned short moddelay; /* modulation delay (0x8000) */ unsigned short modatkhld; /* modulation attack & hold time (0x7f7f) */ unsigned short moddcysus; /* modulation decay & sustain (0x7f7f) */ unsigned short modrelease; /* modulation release time (0x807f) */ short modkeyhold, modkeydecay; /* envelope change per key (not used) */ unsigned short voldelay; /* volume delay (0x8000) */ unsigned short volatkhld; /* volume attack & hold time (0x7f7f) */ unsigned short voldcysus; /* volume decay & sustain (0x7f7f) */ unsigned short volrelease; /* volume release time (0x807f) */ short volkeyhold, volkeydecay; /* envelope change per key (not used) */ unsigned short lfo1delay; /* LFO1 delay (0x8000) */ unsigned short lfo2delay; /* LFO2 delay (0x8000) */ unsigned short pefe; /* modulation pitch & cutoff (0x0000) */ unsigned short fmmod; /* LFO1 pitch & cutoff (0x0000) */ unsigned short tremfrq; /* LFO1 volume & freq (0x0000) */ unsigned short fm2frq2; /* LFO2 pitch & freq (0x0000) */ unsigned char cutoff; /* initial cutoff (0xff) */ unsigned char filterQ; /* initial filter Q [0-15] (0x0) */ unsigned char chorus; /* chorus send (0x00) */ unsigned char reverb; /* reverb send (0x00) */ unsigned short reserved[4]; /* not used */ } awe_voice_parm; typedef struct _awe_voice_parm_block { unsigned short moddelay; /* modulation delay (0x8000) */ unsigned char modatk, modhld; unsigned char moddcy, modsus; unsigned char modrel, moddummy; short modkeyhold, modkeydecay; /* envelope change per key (not used) */ unsigned short voldelay; /* volume delay (0x8000) */ unsigned char volatk, volhld; unsigned char voldcy, volsus; unsigned char volrel, voldummy; short volkeyhold, volkeydecay; /* envelope change per key (not used) */ unsigned short lfo1delay; /* LFO1 delay (0x8000) */ unsigned short lfo2delay; /* LFO2 delay (0x8000) */ unsigned char env1fc, env1pit; unsigned char lfo1fc, lfo1pit; unsigned char lfo1freq, lfo1vol; unsigned char lfo2freq, lfo2pit; unsigned char cutoff; /* initial cutoff (0xff) */ unsigned char filterQ; /* initial filter Q [0-15] (0x0) */ unsigned char chorus; /* chorus send (0x00) */ unsigned char reverb; /* reverb send (0x00) */ unsigned short reserved[4]; /* not used */ } awe_voice_parm_block; #define AWE_VOICE_PARM_SIZE 48 /* wave table parameters: 92 bytes */ typedef struct _awe_voice_info { unsigned short sf_id; /* file id (should be zero) */ unsigned short sample; /* sample id */ int start, end; /* sample offset correction */ int loopstart, loopend; /* loop offset correction */ short rate_offset; /* sample rate pitch offset */ unsigned short mode; /* sample mode */ #define AWE_MODE_ROMSOUND 0x8000 #define AWE_MODE_STEREO 1 #define AWE_MODE_LOOPING 2 #define AWE_MODE_NORELEASE 4 /* obsolete */ #define AWE_MODE_INIT_PARM 8 short root; /* midi root key */ short tune; /* pitch tuning (in cents) */ signed char low, high; /* key note range */ signed char vellow, velhigh; /* velocity range */ signed char fixkey, fixvel; /* fixed key, velocity */ signed char pan, fixpan; /* panning, fixed panning */ short exclusiveClass; /* exclusive class (0 = none) */ unsigned char amplitude; /* sample volume (127 max) */ unsigned char attenuation; /* attenuation (0.375dB) */ short scaleTuning; /* pitch scale tuning(%), normally 100 */ awe_voice_parm parm; /* voice envelope parameters */ short index; /* internal index (set by driver) */ } awe_voice_info; /*#define AWE_VOICE_INFO_SIZE 92*/ #define AWE_VOICE_INFO_SIZE sizeof(awe_voice_info) /*----------------------------------------------------------------*/ /* The info entry of awe_voice_rec is changed from 0 to 1 * for some compilers refusing zero size array. * Due to this change, sizeof(awe_voice_rec) becomes different * from older versions. * Use AWE_VOICE_REC_SIZE instead. */ /* instrument info header: 4 bytes */ typedef struct _awe_voice_rec_hdr { unsigned char bank; /* midi bank number */ unsigned char instr; /* midi preset number */ char nvoices; /* number of voices */ char write_mode; /* write mode; normally 0 */ #define AWE_WR_APPEND 0 /* append anyway */ #define AWE_WR_EXCLUSIVE 1 /* skip if already exists */ #define AWE_WR_REPLACE 2 /* replace if already exists */ } awe_voice_rec_hdr; /*#define AWE_VOICE_REC_SIZE 4*/ #define AWE_VOICE_REC_SIZE sizeof(awe_voice_rec_hdr) /* the standard patch structure for one sample */ typedef struct _awe_voice_rec_patch { awe_patch_info patch; awe_voice_rec_hdr hdr; awe_voice_info info; } awe_voice_rec_patch; /* obsolete data type */ #if defined(AWE_COMPAT_030) && AWE_COMPAT_030 #define AWE_INFOARRAY_SIZE 0 #else #define AWE_INFOARRAY_SIZE 1 #endif typedef struct _awe_voice_rec { unsigned char bank; /* midi bank number */ unsigned char instr; /* midi preset number */ short nvoices; /* number of voices */ /* voice information follows here */ awe_voice_info info[AWE_INFOARRAY_SIZE]; } awe_voice_rec; /*---------------------------------------------------------------- * sample wave information *----------------------------------------------------------------*/ /* wave table sample header: 32 bytes */ typedef struct awe_sample_info { unsigned short sf_id; /* file id (should be zero) */ unsigned short sample; /* sample id */ int start, end; /* start & end offset */ int loopstart, loopend; /* loop start & end offset */ int size; /* size (0 = ROM) */ short checksum_flag; /* use check sum = 1 */ unsigned short mode_flags; /* mode flags */ #define AWE_SAMPLE_8BITS 1 /* wave data is 8bits */ #define AWE_SAMPLE_UNSIGNED 2 /* wave data is unsigned */ #define AWE_SAMPLE_NO_BLANK 4 /* no blank loop is attached */ #define AWE_SAMPLE_SINGLESHOT 8 /* single-shot w/o loop */ #define AWE_SAMPLE_BIDIR_LOOP 16 /* bidirectional looping */ #define AWE_SAMPLE_STEREO_LEFT 32 /* stereo left sound */ #define AWE_SAMPLE_STEREO_RIGHT 64 /* stereo right sound */ #define AWE_SAMPLE_REVERSE_LOOP 128 /* reverse looping */ unsigned int checksum; /* check sum */ #if defined(AWE_COMPAT_030) && AWE_COMPAT_030 unsigned short data[0]; /* sample data follows here */ #endif } awe_sample_info; /*#define AWE_SAMPLE_INFO_SIZE 32*/ #define AWE_SAMPLE_INFO_SIZE sizeof(awe_sample_info) /*---------------------------------------------------------------- * voice preset mapping *----------------------------------------------------------------*/ typedef struct awe_voice_map { int map_bank, map_instr, map_key; /* key = -1 means all keys */ int src_bank, src_instr, src_key; } awe_voice_map; #define AWE_VOICE_MAP_SIZE sizeof(awe_voice_map) /*---------------------------------------------------------------- * awe hardware controls *----------------------------------------------------------------*/ #define _AWE_DEBUG_MODE 0x00 #define _AWE_REVERB_MODE 0x01 #define _AWE_CHORUS_MODE 0x02 #define _AWE_REMOVE_LAST_SAMPLES 0x03 #define _AWE_INITIALIZE_CHIP 0x04 #define _AWE_SEND_EFFECT 0x05 #define _AWE_TERMINATE_CHANNEL 0x06 #define _AWE_TERMINATE_ALL 0x07 #define _AWE_INITIAL_VOLUME 0x08 #define _AWE_INITIAL_ATTEN _AWE_INITIAL_VOLUME #define _AWE_RESET_CHANNEL 0x09 #define _AWE_CHANNEL_MODE 0x0a #define _AWE_DRUM_CHANNELS 0x0b #define _AWE_MISC_MODE 0x0c #define _AWE_RELEASE_ALL 0x0d #define _AWE_NOTEOFF_ALL 0x0e #define _AWE_CHN_PRESSURE 0x0f /*#define _AWE_GET_CURRENT_MODE 0x10*/ #define _AWE_EQUALIZER 0x11 /*#define _AWE_GET_MISC_MODE 0x12*/ /*#define _AWE_GET_FONTINFO 0x13*/ #define _AWE_MODE_FLAG 0x80 #define _AWE_COOKED_FLAG 0x40 /* not supported */ #define _AWE_MODE_VALUE_MASK 0x3F /*----------------------------------------------------------------*/ #define _AWE_SET_CMD(p,dev,voice,cmd,p1,p2) \ {((char*)(p))[0] = SEQ_PRIVATE;\ ((char*)(p))[1] = dev;\ ((char*)(p))[2] = _AWE_MODE_FLAG|(cmd);\ ((char*)(p))[3] = voice;\ ((unsigned short*)(p))[2] = p1;\ ((unsigned short*)(p))[3] = p2;} /* buffered access */ #define _AWE_CMD(dev, voice, cmd, p1, p2) \ {_SEQ_NEEDBUF(8);\ _AWE_SET_CMD(_seqbuf + _seqbufptr, dev, voice, cmd, p1, p2);\ _SEQ_ADVBUF(8);} /* direct access */ #define _AWE_CMD_NOW(seqfd,dev,voice,cmd,p1,p2) \ {struct seq_event_rec tmp;\ _AWE_SET_CMD(&tmp, dev, voice, cmd, p1, p2);\ ioctl(seqfd, SNDCTL_SEQ_OUTOFBAND, &tmp);} /*----------------------------------------------------------------*/ /* set debugging mode */ #define AWE_DEBUG_MODE(dev,p1) _AWE_CMD(dev, 0, _AWE_DEBUG_MODE, p1, 0) /* set reverb mode; from 0 to 7 */ #define AWE_REVERB_MODE(dev,p1) _AWE_CMD(dev, 0, _AWE_REVERB_MODE, p1, 0) /* set chorus mode; from 0 to 7 */ #define AWE_CHORUS_MODE(dev,p1) _AWE_CMD(dev, 0, _AWE_CHORUS_MODE, p1, 0) /* reset channel */ #define AWE_RESET_CHANNEL(dev,ch) _AWE_CMD(dev, ch, _AWE_RESET_CHANNEL, 0, 0) #define AWE_RESET_CONTROL(dev,ch) _AWE_CMD(dev, ch, _AWE_RESET_CHANNEL, 1, 0) /* send an effect to all layers */ #define AWE_SEND_EFFECT(dev,voice,type,value) _AWE_CMD(dev,voice,_AWE_SEND_EFFECT,type,value) #define AWE_ADD_EFFECT(dev,voice,type,value) _AWE_CMD(dev,voice,_AWE_SEND_EFFECT,((type)|0x80),value) #define AWE_UNSET_EFFECT(dev,voice,type) _AWE_CMD(dev,voice,_AWE_SEND_EFFECT,((type)|0x40),0) /* send an effect to a layer */ #define AWE_SEND_LAYER_EFFECT(dev,voice,layer,type,value) _AWE_CMD(dev,voice,_AWE_SEND_EFFECT,((layer+1)<<8|(type)),value) #define AWE_ADD_LAYER_EFFECT(dev,voice,layer,type,value) _AWE_CMD(dev,voice,_AWE_SEND_EFFECT,((layer+1)<<8|(type)|0x80),value) #define AWE_UNSET_LAYER_EFFECT(dev,voice,layer,type) _AWE_CMD(dev,voice,_AWE_SEND_EFFECT,((layer+1)<<8|(type)|0x40),0) /* terminate sound on the channel/voice */ #define AWE_TERMINATE_CHANNEL(dev,voice) _AWE_CMD(dev,voice,_AWE_TERMINATE_CHANNEL,0,0) /* terminate all sounds */ #define AWE_TERMINATE_ALL(dev) _AWE_CMD(dev, 0, _AWE_TERMINATE_ALL, 0, 0) /* release all sounds (w/o sustain effect) */ #define AWE_RELEASE_ALL(dev) _AWE_CMD(dev, 0, _AWE_RELEASE_ALL, 0, 0) /* note off all sounds (w sustain effect) */ #define AWE_NOTEOFF_ALL(dev) _AWE_CMD(dev, 0, _AWE_NOTEOFF_ALL, 0, 0) /* set initial attenuation */ #define AWE_INITIAL_VOLUME(dev,atten) _AWE_CMD(dev, 0, _AWE_INITIAL_VOLUME, atten, 0) #define AWE_INITIAL_ATTEN AWE_INITIAL_VOLUME /* relative attenuation */ #define AWE_SET_ATTEN(dev,atten) _AWE_CMD(dev, 0, _AWE_INITIAL_VOLUME, atten, 1) /* set channel playing mode; mode=0/1/2 */ #define AWE_SET_CHANNEL_MODE(dev,mode) _AWE_CMD(dev, 0, _AWE_CHANNEL_MODE, mode, 0) #define AWE_PLAY_INDIRECT 0 /* indirect voice mode (default) */ #define AWE_PLAY_MULTI 1 /* multi note voice mode */ #define AWE_PLAY_DIRECT 2 /* direct single voice mode */ #define AWE_PLAY_MULTI2 3 /* sequencer2 mode; used internally */ /* set drum channel mask; channels is 32bit long value */ #define AWE_DRUM_CHANNELS(dev,channels) _AWE_CMD(dev, 0, _AWE_DRUM_CHANNELS, ((channels) & 0xffff), ((channels) >> 16)) /* set bass and treble control; values are from 0 to 11 */ #define AWE_EQUALIZER(dev,bass,treble) _AWE_CMD(dev, 0, _AWE_EQUALIZER, bass, treble) /* remove last loaded samples */ #define AWE_REMOVE_LAST_SAMPLES(seqfd,dev) _AWE_CMD_NOW(seqfd, dev, 0, _AWE_REMOVE_LAST_SAMPLES, 0, 0) /* initialize emu8000 chip */ #define AWE_INITIALIZE_CHIP(seqfd,dev) _AWE_CMD_NOW(seqfd, dev, 0, _AWE_INITIALIZE_CHIP, 0, 0) /* set miscellaneous modes; meta command */ #define AWE_MISC_MODE(dev,mode,value) _AWE_CMD(dev, 0, _AWE_MISC_MODE, mode, value) /* exclusive sound off; 1=off */ #define AWE_EXCLUSIVE_SOUND(dev,mode) AWE_MISC_MODE(dev,AWE_MD_EXCLUSIVE_SOUND,mode) /* default GUS bank number */ #define AWE_SET_GUS_BANK(dev,bank) AWE_MISC_MODE(dev,AWE_MD_GUS_BANK,bank) /* change panning position in realtime; 0=don't 1=do */ #define AWE_REALTIME_PAN(dev,mode) AWE_MISC_MODE(dev,AWE_MD_REALTIME_PAN,mode) /* extended pressure controls; not portable with other sound drivers */ #define AWE_KEY_PRESSURE(dev,ch,note,vel) SEQ_START_NOTE(dev,ch,(note)+128,vel) #define AWE_CHN_PRESSURE(dev,ch,vel) _AWE_CMD(dev,ch,_AWE_CHN_PRESSURE,vel,0) /*----------------------------------------------------------------*/ /* reverb mode parameters */ #define AWE_REVERB_ROOM1 0 #define AWE_REVERB_ROOM2 1 #define AWE_REVERB_ROOM3 2 #define AWE_REVERB_HALL1 3 #define AWE_REVERB_HALL2 4 #define AWE_REVERB_PLATE 5 #define AWE_REVERB_DELAY 6 #define AWE_REVERB_PANNINGDELAY 7 #define AWE_REVERB_PREDEFINED 8 /* user can define reverb modes up to 32 */ #define AWE_REVERB_NUMBERS 32 typedef struct awe_reverb_fx_rec { unsigned short parms[28]; } awe_reverb_fx_rec; /*----------------------------------------------------------------*/ /* chorus mode parameters */ #define AWE_CHORUS_1 0 #define AWE_CHORUS_2 1 #define AWE_CHORUS_3 2 #define AWE_CHORUS_4 3 #define AWE_CHORUS_FEEDBACK 4 #define AWE_CHORUS_FLANGER 5 #define AWE_CHORUS_SHORTDELAY 6 #define AWE_CHORUS_SHORTDELAY2 7 #define AWE_CHORUS_PREDEFINED 8 /* user can define chorus modes up to 32 */ #define AWE_CHORUS_NUMBERS 32 typedef struct awe_chorus_fx_rec { unsigned short feedback; /* feedback level (0xE600-0xE6FF) */ unsigned short delay_offset; /* delay (0-0x0DA3) [1/44100 sec] */ unsigned short lfo_depth; /* LFO depth (0xBC00-0xBCFF) */ unsigned int delay; /* right delay (0-0xFFFFFFFF) [1/256/44100 sec] */ unsigned int lfo_freq; /* LFO freq LFO freq (0-0xFFFFFFFF) */ } awe_chorus_fx_rec; /*----------------------------------------------------------------*/ /* misc mode types */ enum { /* 0*/ AWE_MD_EXCLUSIVE_OFF, /* obsolete */ /* 1*/ AWE_MD_EXCLUSIVE_ON, /* obsolete */ /* 2*/ AWE_MD_VERSION, /* read only */ /* 3*/ AWE_MD_EXCLUSIVE_SOUND, /* 0/1: exclusive note on (default=1) */ /* 4*/ AWE_MD_REALTIME_PAN, /* 0/1: do realtime pan change (default=1) */ /* 5*/ AWE_MD_GUS_BANK, /* bank number for GUS patches (default=0) */ /* 6*/ AWE_MD_KEEP_EFFECT, /* 0/1: keep effect values, (default=0) */ /* 7*/ AWE_MD_ZERO_ATTEN, /* attenuation of max volume (default=32) */ /* 8*/ AWE_MD_CHN_PRIOR, /* 0/1: set MIDI channel priority mode (default=1) */ /* 9*/ AWE_MD_MOD_SENSE, /* integer: modwheel sensitivity (def=18) */ /*10*/ AWE_MD_DEF_PRESET, /* integer: default preset number (def=0) */ /*11*/ AWE_MD_DEF_BANK, /* integer: default bank number (def=0) */ /*12*/ AWE_MD_DEF_DRUM, /* integer: default drumset number (def=0) */ /*13*/ AWE_MD_TOGGLE_DRUM_BANK, /* 0/1: toggle drum flag with bank# (def=0) */ /*14*/ AWE_MD_NEW_VOLUME_CALC, /* 0/1: volume calculation mode (def=1) */ /*15*/ AWE_MD_CHORUS_MODE, /* integer: chorus mode (def=2) */ /*16*/ AWE_MD_REVERB_MODE, /* integer: chorus mode (def=4) */ /*17*/ AWE_MD_BASS_LEVEL, /* integer: bass level (def=5) */ /*18*/ AWE_MD_TREBLE_LEVEL, /* integer: treble level (def=9) */ /*19*/ AWE_MD_DEBUG_MODE, /* integer: debug level (def=0) */ /*20*/ AWE_MD_PAN_EXCHANGE, /* 0/1: exchange panning direction (def=0) */ AWE_MD_END, }; /*----------------------------------------------------------------*/ /* effect parameters */ enum { /* modulation envelope parameters */ /* 0*/ AWE_FX_ENV1_DELAY, /* WORD: ENVVAL */ /* 1*/ AWE_FX_ENV1_ATTACK, /* BYTE: up ATKHLD */ /* 2*/ AWE_FX_ENV1_HOLD, /* BYTE: lw ATKHLD */ /* 3*/ AWE_FX_ENV1_DECAY, /* BYTE: lw DCYSUS */ /* 4*/ AWE_FX_ENV1_RELEASE, /* BYTE: lw DCYSUS */ /* 5*/ AWE_FX_ENV1_SUSTAIN, /* BYTE: up DCYSUS */ /* 6*/ AWE_FX_ENV1_PITCH, /* BYTE: up PEFE */ /* 7*/ AWE_FX_ENV1_CUTOFF, /* BYTE: lw PEFE */ /* volume envelope parameters */ /* 8*/ AWE_FX_ENV2_DELAY, /* WORD: ENVVOL */ /* 9*/ AWE_FX_ENV2_ATTACK, /* BYTE: up ATKHLDV */ /*10*/ AWE_FX_ENV2_HOLD, /* BYTE: lw ATKHLDV */ /*11*/ AWE_FX_ENV2_DECAY, /* BYTE: lw DCYSUSV */ /*12*/ AWE_FX_ENV2_RELEASE, /* BYTE: lw DCYSUSV */ /*13*/ AWE_FX_ENV2_SUSTAIN, /* BYTE: up DCYSUSV */ /* LFO1 (tremolo & vibrato) parameters */ /*14*/ AWE_FX_LFO1_DELAY, /* WORD: LFO1VAL */ /*15*/ AWE_FX_LFO1_FREQ, /* BYTE: lo TREMFRQ */ /*16*/ AWE_FX_LFO1_VOLUME, /* BYTE: up TREMFRQ */ /*17*/ AWE_FX_LFO1_PITCH, /* BYTE: up FMMOD */ /*18*/ AWE_FX_LFO1_CUTOFF, /* BYTE: lo FMMOD */ /* LFO2 (vibrato) parameters */ /*19*/ AWE_FX_LFO2_DELAY, /* WORD: LFO2VAL */ /*20*/ AWE_FX_LFO2_FREQ, /* BYTE: lo FM2FRQ2 */ /*21*/ AWE_FX_LFO2_PITCH, /* BYTE: up FM2FRQ2 */ /* Other overall effect parameters */ /*22*/ AWE_FX_INIT_PITCH, /* SHORT: pitch offset */ /*23*/ AWE_FX_CHORUS, /* BYTE: chorus effects send (0-255) */ /*24*/ AWE_FX_REVERB, /* BYTE: reverb effects send (0-255) */ /*25*/ AWE_FX_CUTOFF, /* BYTE: up IFATN */ /*26*/ AWE_FX_FILTERQ, /* BYTE: up CCCA */ /* Sample / loop offset changes */ /*27*/ AWE_FX_SAMPLE_START, /* SHORT: offset */ /*28*/ AWE_FX_LOOP_START, /* SHORT: offset */ /*29*/ AWE_FX_LOOP_END, /* SHORT: offset */ /*30*/ AWE_FX_COARSE_SAMPLE_START, /* SHORT: upper word offset */ /*31*/ AWE_FX_COARSE_LOOP_START, /* SHORT: upper word offset */ /*32*/ AWE_FX_COARSE_LOOP_END, /* SHORT: upper word offset */ /*33*/ AWE_FX_ATTEN, /* BYTE: lo IFATN */ AWE_FX_END, }; #endif /* AWE_VOICE_H */ awesfx-0.5.2/include/awebank.h000066400000000000000000000062661344644735400162470ustar00rootroot00000000000000/*================================================================ * AWElib patch loader * * Copyright (C) 1996-1999 Takashi Iwai * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *================================================================*/ #ifndef AWEBANK_H_DEF #define AWEBANK_H_DEF /* return value */ #define AWE_RET_OK 0 /* successfully loaded */ #define AWE_RET_ERR 1 /* some fatal error occurs */ #define AWE_RET_SKIP 2 /* some fonts are skipped */ #define AWE_RET_NOMEM 3 /* out or memory; not all fonts loaded */ #define AWE_RET_NOT_FOUND 4 /* the file is not found */ /*---------------------------------------------------------------- * operators *----------------------------------------------------------------*/ typedef struct _AWEOps { int (*load_patch)(void *buf, int len); int (*mem_avail)(void); int (*reset_samples)(void); int (*remove_samples)(void); int (*set_zero_atten)(int val); } AWEOps; /*---------------------------------------------------------------- * preset/bank/keynote bag *----------------------------------------------------------------*/ typedef struct _SFPatchRec { int preset, bank, keynote; /* -1 = matches all */ } SFPatchRec; /* compare two patch sets */ int awe_match_preset(SFPatchRec *rec, SFPatchRec *pat); /* merge two patch sets (p1 + p2 -> rec) */ void awe_merge_keys(SFPatchRec *p1, SFPatchRec *p2, SFPatchRec *rec); /* parse the text and store source/map patch sets */ int awe_parse_loadlist(char *arg, SFPatchRec *pat, SFPatchRec *map, char **strp); /* dynamic loading list */ typedef struct _AWELoadList { SFPatchRec pat; SFPatchRec map; int loaded; struct _AWELoadList *next; } LoadList; /* add a patch set on the list */ LoadList *awe_add_loadlist(LoadList *list, SFPatchRec *pat, SFPatchRec *map); /* merge the elements in latter list */ LoadList *awe_merge_loadlist(LoadList *list, LoadList *old); /* free all list elements */ void awe_free_loadlist(LoadList *p); /*---------------------------------------------------------------- * load a soundfont or virtual bank file *---------------------------------------------------------------- * 'name' is the file name of the sound font. The file is searched * along the prescribed search path. * If 'list' is not NULL, only the presets listed are loaded. * 'locked' is boolean value to specify the fonts are locked or not. * The locked fonts are not removed by -x option of sfxload. *----------------------------------------------------------------*/ int awe_load_bank(AWEOps *ops, char *name, LoadList *list, int locked); #endif /* AWEBANK_H_DEF */ awesfx-0.5.2/include/aweseq.h000066400000000000000000000040501344644735400161110ustar00rootroot00000000000000/*================================================================ * Load AWE patch data * * Copyright (C) 1996-1999 Takashi Iwai * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *================================================================*/ #ifndef AWESEQ_H_DEF #define AWESEQ_H_DEF #include "sffile.h" #include "awebank.h" /*---------------------------------------------------------------- * initialize and finish the loading *----------------------------------------------------------------*/ int awe_open_font(AWEOps *ops, SFInfo *sf, FILE *fp, int locked); void awe_close_font(AWEOps *ops, SFInfo *sf); int awe_is_ram_fonts(SFInfo *sf); int awe_open_patch(AWEOps *ops, char *name, int type, int locked); int awe_close_patch(AWEOps *ops); int awe_load_map(AWEOps *ops, LoadList *lp); /*---------------------------------------------------------------- * load each preset: load a preset "pat" on "map" *----------------------------------------------------------------*/ int awe_load_font(AWEOps *ops, SFInfo *sf, SFPatchRec *pat, SFPatchRec *map); int awe_load_font_list(AWEOps *ops, SFInfo *sf, LoadList *part_list, int load_alt); /*---------------------------------------------------------------- * load the whole file (with checking loadlist) *----------------------------------------------------------------*/ int awe_load_all_fonts(AWEOps *ops, SFInfo *sf, LoadList *exclude); #endif /* AWESEQ_H_DEF */ awesfx-0.5.2/include/itypes.h000066400000000000000000000015351344644735400161460ustar00rootroot00000000000000/*================================================================ * integer types *================================================================*/ #ifndef ITYPES_H_DEF #define ITYPES_H_DEF /* 8bit bytes */ typedef signed char sbyte; typedef unsigned char byte; /* 16bit integers */ typedef unsigned short uint16; typedef short int16; /* 32bit long integers */ typedef unsigned int uint32; typedef int int32; /**/ typedef union uint32rec { byte b8[4]; uint16 b16[4]; uint32 b32; } uint32rec; /* vp=uint32rec, cp=char* */ #define get32rec(vp,cp) memcpy(vp, cp, 4) #if 1 /* little endian */ #define swapi(x) x #define swapl(x) x #else /* big endian */ #define swapi(x) ((((x)&0xFF)<<8) | (((x)>>8)&0xFF)) #define swapl(x) ((((x)&0xFF)<<24) | \ (((x)&0xFF00)<<8) | \ (((x)&0xFF0000)>>8) | \ (((x)>>24)&0xFF)) #endif #endif awesfx-0.5.2/include/sffile.h000066400000000000000000000061641344644735400161040ustar00rootroot00000000000000/*================================================================ * sffile.h * SoundFont file (SBK/SF2) format defintions * * Copyright (C) 1996-1999 Takashi Iwai * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *================================================================*/ #ifndef SFFILE_H_DEF #define SFFILE_H_DEF #include #include "itypes.h" /* chunk record header */ typedef struct _SFChunk { char id[4]; int32 size; } SFChunk; /* generator record */ typedef struct _SFGenRec { int16 oper; int16 amount; } SFGenRec; /* layered generators record */ typedef struct _SFGenLayer { int nlists; SFGenRec *list; } SFGenLayer; /* header record */ typedef struct _SFHeader { char name[20]; uint16 bagNdx; /* layered stuff */ int nlayers; SFGenLayer *layer; } SFHeader; /* preset header record */ typedef struct _SFPresetHdr { SFHeader hdr; uint16 preset, bank; /*int32 lib, genre, morphology;*/ /* not used */ } SFPresetHdr; /* instrument header record */ typedef struct _SFInstHdr { SFHeader hdr; } SFInstHdr; /* sample info record */ typedef struct _SFSampleInfo { char name[20]; int32 startsample, endsample; int32 startloop, endloop; /* ver.2 additional info */ int32 samplerate; byte originalPitch; sbyte pitchCorrection; uint16 samplelink; uint16 sampletype; /*1=mono, 2=right, 4=left, 8=linked, $8000=ROM*/ /* optional info */ int32 size; /* sample size */ int32 loopshot; /* short-shot loop size */ } SFSampleInfo; /*---------------------------------------------------------------- * soundfont file info record *----------------------------------------------------------------*/ typedef struct _SFInfo { /* file name */ char *sf_name; /* version of this file */ int16 version, minorversion; /* sample position (from origin) & total size (in bytes) */ long samplepos; int32 samplesize; /* raw INFO chunk list */ long infopos, infosize; /* preset headers */ int npresets; SFPresetHdr *preset; /* sample infos */ int nsamples; SFSampleInfo *sample; /* instrument headers */ int ninsts; SFInstHdr *inst; } SFInfo; /*---------------------------------------------------------------- * functions *----------------------------------------------------------------*/ /* sffile.c */ int awe_load_soundfont(SFInfo *sf, FILE *fp, int is_seekable); void awe_free_soundfont(SFInfo *sf); void awe_save_soundfont(SFInfo *sf, FILE *fin, FILE *fout); void awe_load_textinfo(SFInfo *sf, FILE *fp); /* sample.c */ void awe_correct_samples(SFInfo *sf); #endif awesfx-0.5.2/include/sfitem.h000066400000000000000000000046741344644735400161270ustar00rootroot00000000000000/*================================================================ * sfitem.h * soundfont generator conversion table * * Copyright (C) 1996-1999 Takashi Iwai * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *================================================================*/ #ifndef SFITEM_H_DEF #define SFITEM_H_DEF #include "sflayer.h" #include "sffile.h" typedef struct _LayerItem { int copy; /* copy policy */ int type; /* conversion type */ int minv; /* minimum value */ int maxv; /* maximum value */ int defv; /* default value */ } LayerItem; /* copy policy */ enum { L_INHRT, /* add to global */ L_OVWRT, /* overwrite on global */ L_RANGE, /* range */ L_PRSET, /* preset only */ L_INSTR, /* instrument only */ }; /* data type */ enum { T_NOP, /* nothing */ T_NOCONV, /* no conversion */ T_OFFSET, /* address offset */ T_HI_OFF, /* address coarse offset (32k) */ T_RANGE, /* range; composite values (0-127/0-127) */ T_CUTOFF, /* initial cutoff */ T_FILTERQ, /* initial resonance */ T_TENPCT, /* effects send */ T_PANPOS, /* panning position */ T_ATTEN, /* initial attenuation */ T_SCALE, /* scale tuning */ T_TIME, /* envelope/LFO time */ T_TM_KEY, /* time change per key */ T_FREQ, /* LFO frequency */ T_PSHIFT, /* env/LFO pitch shift */ T_CSHIFT, /* env/LFO cutoff shift */ T_TREMOLO, /* LFO tremolo shift */ T_MODSUST, /* modulation env sustain level */ T_VOLSUST, /* volume env sustain level */ T_EOT, /* end of type */ }; /* sbk->sf2 convertor function */ typedef int (*SBKConv)(int gen, int amount); /* macros for range operation */ #define RANGE(lo,hi) (((hi)&0xff) << 8 | ((lo)&0xff)) #define LOWNUM(val) ((val) & 0xff) #define HIGHNUM(val) (((val) >> 8) & 0xff) /* layer type definitions */ extern LayerItem layer_items[SF_EOF]; int sbk_to_sf2(int oper, int amount); #endif awesfx-0.5.2/include/sflayer.h000066400000000000000000000103631344644735400162750ustar00rootroot00000000000000/*================================================================ * sflayer.h * soundfont generator type definitions * * Copyright (C) 1996-1999 Takashi Iwai * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *================================================================*/ #ifndef SFLAYER_H_DEF #define SFLAYER_H_DEF /*---------------------------------------------------------------- * the following enum table is taken from the Creative's * ADIP (AWE32 Developers' Information Package) * The complete set is found in the CreativeLab's web page (in ftp * download page). *----------------------------------------------------------------*/ enum { SF_startAddrs, /* sample start address -4 (0 to * 0xffffff) */ SF_endAddrs, SF_startloopAddrs, /* loop start address -4 (0 to * 0xffffff) */ SF_endloopAddrs, /* loop end address -3 (0 to * 0xffffff) */ SF_startAddrsHi, /* high word of startAddrs */ SF_lfo1ToPitch, /* main fm: lfo1-> pitch */ SF_lfo2ToPitch, /* aux fm: lfo2-> pitch */ SF_env1ToPitch, /* pitch env: env1(aux)-> pitch */ SF_initialFilterFc, /* initial filter cutoff */ SF_initialFilterQ, /* filter Q */ SF_lfo1ToFilterFc, /* filter modulation: lfo1 -> filter * cutoff */ SF_env1ToFilterFc, /* filter env: env1(aux)-> filter * cutoff */ SF_endAddrsHi, /* high word of endAddrs */ SF_lfo1ToVolume, /* tremolo: lfo1-> volume */ SF_env2ToVolume, /* Env2Depth: env2-> volume */ SF_chorusEffectsSend, /* chorus */ SF_reverbEffectsSend, /* reverb */ SF_panEffectsSend, /* pan */ SF_auxEffectsSend, /* pan auxdata (internal) */ SF_sampleVolume, /* used internally */ SF_unused3, SF_delayLfo1, /* delay 0x8000-n*(725us) */ SF_freqLfo1, /* frequency */ SF_delayLfo2, /* delay 0x8000-n*(725us) */ SF_freqLfo2, /* frequency */ SF_delayEnv1, /* delay 0x8000 - n(725us) */ SF_attackEnv1, /* attack */ SF_holdEnv1, /* hold */ SF_decayEnv1, /* decay */ SF_sustainEnv1, /* sustain */ SF_releaseEnv1, /* release */ SF_autoHoldEnv1, SF_autoDecayEnv1, SF_delayEnv2, /* delay 0x8000 - n(725us) */ SF_attackEnv2, /* attack */ SF_holdEnv2, /* hold */ SF_decayEnv2, /* decay */ SF_sustainEnv2, /* sustain */ SF_releaseEnv2, /* release */ SF_autoHoldEnv2, SF_autoDecayEnv2, SF_instrument, /* */ SF_nop, SF_keyRange, /* */ SF_velRange, /* */ SF_startloopAddrsHi, /* high word of startloopAddrs */ SF_keynum, /* */ SF_velocity, /* */ SF_initAtten, /* */ SF_keyTuning, SF_endloopAddrsHi, /* high word of endloopAddrs */ SF_coarseTune, SF_fineTune, SF_sampleId, SF_sampleFlags, SF_samplePitch, /* SF1 only */ SF_scaleTuning, SF_keyExclusiveClass, SF_rootKey, SF_EOF, }; /* name strings */ extern char *sf_gen_text[SF_EOF]; /*---------------------------------------------------------------- * layer value table *----------------------------------------------------------------*/ typedef struct _LayerTable { short val[SF_EOF]; char set[SF_EOF]; } LayerTable; #endif awesfx-0.5.2/include/sfopts.h000066400000000000000000000036321344644735400161470ustar00rootroot00000000000000/*---------------------------------------------------------------- * general options for AWElib * * Copyright (C) 1996-1999 Takashi Iwai * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *----------------------------------------------------------------*/ #ifndef SFOPTS_H_DEF #define SFOPTS_H_DEF #include /* options */ typedef struct _sf_options { int auto_add_blank; /* bool: add 48 blank samples */ int default_bank; /* int: bank map number for bank #0 */ int default_chorus; /* int: chorus effects in percent */ int default_reverb; /* int: reverb effects in percent */ int default_volume; /* int: total volume in percent */ double atten_sense; /* attenuation sensitivity (default is 10.0) */ int default_atten; /* zero attenuation level (default is 32) */ double decay_sense; /* decay sensitivity (default is 50.0) */ char *search_path; /* search path for soundfont files */ int compatible; /* compatible mode */ } sf_options; void awe_init_option(void); int awe_calc_def_atten(double sense); /* calculate zero atten level */ extern sf_options awe_option; void awe_read_option_file(char *fname); int awe_parse_options(int argc, char **argv, char *optflags, struct option *long_opts, int *optidx); #define AWE_BASE_OPTIONS "b:c:r:P:A:a:d:V:BC" #endif awesfx-0.5.2/include/slist.h000066400000000000000000000034561344644735400157730ustar00rootroot00000000000000/*================================================================ * slist.h: * S-expression list * * Copyright (C) 1996-1999 Takashi Iwai * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *================================================================*/ #ifndef SLIST_H_DEF #define SLIST_H_DEF enum { S_ATOM_NIL, S_ATOM_LIST, S_ATOM_CHR, S_ATOM_INT, S_ATOM_STR, S_ATOM_FUN, }; typedef struct _SAtom *SList; typedef union { char c; int i; char *s; char *f; SList p; } SAtomVal; typedef struct _SAtom { int type; SAtomVal val, nxt; } SAtom; SList SCons(void); SList SReadFile(FILE *fp); void SFree(SList); #define NIL (SList)0 #define SIsNil(at) ((at)->type == S_ATOM_NIL) #define SListP(at) ((at)->type == S_ATOM_LIST) #define SChrP(at) ((at)->type == S_ATOM_CHR) #define SIntP(at) ((at)->type == S_ATOM_INT) #define SStrP(at) ((at)->type == S_ATOM_STR) #define SFunP(at) ((at)->type == S_ATOM_FUN) #define SCar(at) ((at)->val.p) #define SCdr(at) ((at)->nxt.p) #define SChr(at) ((at)->val.c) #define SStr(at) ((at)->val.s) #define SInt(at) ((at)->val.i) #define SFun(at) ((at)->val.f) #define SFunIs(at,fun) (strcmp(SFun(at),fun) == 0) int SIndex(SList); #endif awesfx-0.5.2/include/util.h000066400000000000000000000037021344644735400156040ustar00rootroot00000000000000/*================================================================ * utility routines * * Copyright (C) 1996-1999 Takashi Iwai * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *================================================================*/ #ifndef UTIL_H_DEF #define UTIL_H_DEF #ifndef TRUE #define TRUE 1 #endif #ifndef FALSE #define FALSE 0 #endif #define numberof(ary) (sizeof(ary)/sizeof(ary[0])) #ifndef offsetof #define offsetof(s_type,field) ((int)(((char*)(&(((s_type*)NULL)->field)))-((char*)NULL))) #endif #define BITON(var,flag) ((var) |= (flag)) #define BITOFF(var,flag) ((var) &= ~(flag)) #define BITSWT(var,flag) ((var) ^= (flag)) extern int awe_verbose, debug; #define DEBUG(LVL,XXX) {if (awe_verbose > LVL) { XXX; }} /* cmpopen.c */ char *CmpGetExtension(char *name); FILE *CmpOpenFile(char *name, int *flag); void CmpCloseFile(FILE *fp, int flag); void CmpAddList(char *ext, char *format); /* malloc.c */ void *safe_malloc(int size); void safe_free(void *ptr); char *safe_strdup(char *src); /* bool.c */ char *strtoken(char *src); char *strschr(char *str, char *dels); int strlcmp(char *ap, char *bp); int bool_val(char *val); /* fskip.c */ void fskip(int size, FILE *fd, int seekable); /* path.c */ int awe_search_file_name(char *fresult, int maxlen, char *fname, char *path, char **ext); #endif awesfx-0.5.2/samples/000077500000000000000000000000001344644735400144755ustar00rootroot00000000000000awesfx-0.5.2/samples/.cvsignore000066400000000000000000000000251344644735400164720ustar00rootroot00000000000000Makefile Makefile.in awesfx-0.5.2/samples/Makefile.am000066400000000000000000000003421344644735400165300ustar00rootroot00000000000000cfg_files = README-bank \ ch12msup.bnk default-2m.bnk \ emu8m.bnk setfx-sample.cfg \ test.bnk xgdefault.bnk xgdrum.bnk xgmap.bnk xgsfx.bnk EXTRA_DIST = $(cfg_files) sf2dir = $(datadir)/sounds/sf2 sf2_DATA = $(cfg_files) awesfx-0.5.2/samples/README-bank000066400000000000000000000047501344644735400162740ustar00rootroot00000000000000* CONTENTS This directory contains some samples of virtual bank files. [Bank Files for 512k DRAM] default-2m.bnk - bank file for dynamic loading of GS sounds Use this file with --dynamic option of drvmidi. 2mbgmgs.sf2 font is used except footsteps sound. synthgs.sbk is used only for footsteps instead. xgdefault.bnk - bank file for dynamic loading of GS/XG sounds Use this file together with --dynamic and --xgmap=on. This file includes the other three XG mapping files below. You'll need to install all the files. [Bank File for 8MB DRAM] emu8m.bnk - bank file for 8mbgmsfx.sf2 from Emu This file includes GS instruments from 2mbgmgs.sf2, and XG mapping files. The whole file can be loaded on 8MB DRAM. ch12msup.bnk - bank file for chaos12m.sf2 from Chaos For dynamic loading 12MB fonts on 8MB DRAM. This file includes chaos8m.sf2 font for some GS parts. The XG mapping files must be also installed. [Bank Files for XG mapping] xgsfx.bnk - bank file for XG SFX kit Many preset mappings are defined on this file for XG SFX sounds. Use this file with --xgmap=on option of drvmidi. If this option is enabled, bank #64 and #126 are used as XG SFX banks. xgdrum.bnk - bank file for XG Drum kit Many preset mappings are defined on this file for XG Drum sounds. Use this file with --xgmap=on option of drvmidi. If this option is enabled, from drumset #64 to #126 are used for XG drum sounds. xgmap.bnk - bank file for XG mapping Just including both two files above. * HOW TO PLAY XG MIDI FILES - Copy all the bank files above to the soundfont bank directory, as default, /usr/local/lib/sfbank or /dos/sb32/sfbank. The default bank directory is defined in awelib/config.h. If you'll use another GS soundfont, specify it in default.bnk. - If you have only 512k DRAM on the soundcard, use dynamic loading. Set the default options of drvmidi in ~/.drvmidirc as follows: default --xgmap=on --dynamic=xgdefault.bnk xgdefault.bnk contains both GS/GM fonts and XG mappings. Otherwise, if you have enough DRAM, you can load all the fonts at once on the driver. Then, set --xgmap option only in the default option of drvmidi, default --xgmap=on - Load the font file before starting tkmidi or drvmidi. In the case of dynamic loading, ROM soundfont should be used: % sfxload synthgm In the case of static loading, load all the font at this time: % sfxload xgdefault.bnk - Run tkmidi or drvmidi, and enjoy. tkmidi *.mid ---------------- Takashi Iwai awesfx-0.5.2/samples/ch12msup.bnk000066400000000000000000000005101344644735400166270ustar00rootroot00000000000000# # GS compatible bank for chaos12m # GS parts taken from chaos8m # # load from bank #1 to #9 in chaos8m.sf2 */1:*/1:chaos8m */2:*/2:chaos8m */3:*/3:chaos8m */4:*/4:chaos8m */5:*/5:chaos8m */6:*/6:chaos8m */7:*/7:chaos8m */8:*/8:chaos8m */9:*/9:chaos8m # load XG mapping include xgmap.bnk # Chaos 12MB fonts default chaos12m awesfx-0.5.2/samples/default-2m.bnk000066400000000000000000000001651344644735400171330ustar00rootroot00000000000000# # GS BANK FILE FOR DYNAMIC LOADING ON 512K DRAM # default 2mbgmgs # use footsteps in synthgs 126/5:126/5:synthgs awesfx-0.5.2/samples/emu8m.bnk000066400000000000000000000036271344644735400162340ustar00rootroot00000000000000# # Supplementary definitions for 8mbgmsfx.sf2 from Emu # (included in AWE64 memory module CD-ROM) # Some tones taken from 2mbgmgs.sf2 # 56/128/49:120/1 Cut Noise 56/128/50:120/2 String Slap 56/128/51:121/1 Key Click 56/128/79:122/1 Rain 56/128/80:122/2 Thunder 56/128/81:122/3 Wind 56/128/83:122/4 Stream 56/128/84:122/5 Bubble 56/128/76:123/1 Dog 56/128/77:123/2 Horse-Gallop 56/128/90:124/1 Telephone 2 56/128/59:124/2 Door Creaking 56/128/60:124/3 Door 56/128/61:124/4 Scratch 56/128/62:124/5 Windchime 56/128/63:125/1 Car-Engine 56/128/64:125/2 Car-Stop 56/128/65:125/3 Car-Pass 56/128/66:125/4 Car-Crash 56/128/67:125/5 Siren 56/128/68:125/6 Train 56/128/69:125/7 Jetplane 56/128/71:125/8 Starship 125/9:125/9:2mbgmgs Burst Noise 56/128/52:126/1 Laughing 56/128/53:126/2 Screaming 56/128/54:126/3 Punch 56/128/55:126/4 Hear Beat 56/128/56:126/5 Footsteps 56/128/73:127/1 Machine Gun 56/128/74:127/2 Laser Gun 56/128/75:127/3 Explosion 4/8:4/8:2mbgmgs Detuned Rhodes 5/8:5/8:2mbgmgs Detuned EP2 6/8:6/8:2mbgmgs Coupled Harpsichord 14/8:14/8:2mbgmgs Church Bell 16/8:16/8:2mbgmgs Detuned Organ 1 17/8:17/8:2mbgmgs Detuned Organ 2 19/8:19/8:2mbgmgs Detuned Organ 3 21/8:21/8:2mbgmgs Italian Accordion 24/8:24/8:2mbgmgs Ukulele 25/8:25/8:2mbgmgs 12 St. Guitar 25/16:25/16:2mbgmgs Mandolin 26/8:26/8:2mbgmgs Hawaiian Guitar 27/8:27/8:2mbgmgs Chorus Guitar 28/8:28/8:2mbgmgs Funk Guitar 30/8:30/8:2mbgmgs FeedBack Guitar 31/8:31/8:2mbgmgs Guitar FeedBack 38/8:38/8:2mbgmgs SynthBass 3 39/8:39/8:2mbgmgs SynthBass 4 48/8:48/8:2mbgmgs Orchestra Pad 50/8:50/8:2mbgmgs Syn Strings 3 61/8:61/8:2mbgmgs Brass 2 62/8:62/8:2mbgmgs Synth Brass 3 63/8:63/8:2mbgmgs Synth Brass 4 80/8:80/8:2mbgmgs Sine Wave 107/8:107/8:2mbgmgs Taisho Koto 115/8:115/8:2mbgmgs Castanets 116/8:116/8:2mbgmgs Concert BD 117/8:117/8:2mbgmgs Melo Tom 2 118/8:118/8:2mbgmgs 808 Tom # not enough memory for this.. # */127:*/127:2mbgmgs MT include xgmap.bnk default 8mbgmsfx awesfx-0.5.2/samples/setfx-sample.cfg000066400000000000000000000021101344644735400175600ustar00rootroot00000000000000#---------------------------------------------------------------- # user defined chorus and reverb modes for AWE32 sound driver #---------------------------------------------------------------- # # chorus mode definitions # # chorus:mode:string:include:parameters # mode = mode index, from 8 to 31 # string = name of this chorus mode # include = include the predefined mode (not supported) # parameters are the list of awe_chorus_fx_rec strucutre (in hex) # feedback delay-ofs lfo-depth delay lfo-freq chorus:8:Mechanic::e6e0 0100 bc01 0 0 chorus:9:Repeat::e0f0 600e 1008 0 4a0000 # # reverb mode definitions # # reverb:mode:string:include:parameters # mode = mode index, from 8 to 31 # string = name of this reverrb mode # include = include the predefined mode # (parameter becomes parm=new) # parameters are the list of awe_reverb_fx_rec strucutre, 28 short hex reverb:8:Big Sound:0:0=b4ff 1=a402 2=9502 reverb:9:Hall2 Copy::\ B488 A470 9570 84B5 383A 3EB5 7254\ 7234 7224 7254 7264 7294 44C3 45C3\ A404 A504 842A 852A 842A 852A 8429\ 8529 8429 8529 8428 8528 8428 8528 awesfx-0.5.2/samples/test.bnk000066400000000000000000000010301344644735400161420ustar00rootroot00000000000000# virtual bank structure # # source:map[:soundfont [name]] # # preset = preset[/bank[/keynote]] # # map music box on preset 0 10/0:0/0:synthgm DummyPiano # map piano1 of chaos8m on preset 1 0/0:1/0:chaos8m Piano2 # map piano1 of synthgm on preset 2 0/0:2/0:synthgm Piano3 # use all standard drums in 2mbgmgs.sf2 0/128:0/128:2mbgmgs Standard # map standard bass drum as room bass drum in chaos4m.sf2 0/128/35:8/128/35:chaos4m Test Drum # include XG sfx mappings include xgsfx.bnk # use synthgs.sbk as default fonts default synthgs awesfx-0.5.2/samples/xgdefault.bnk000066400000000000000000000001171344644735400171530ustar00rootroot00000000000000# # XG BANK FILE FOR DYNAMIC LOADING # include xgmap.bnk include default.bnk awesfx-0.5.2/samples/xgdrum.bnk000066400000000000000000000066711344644735400165110ustar00rootroot00000000000000# # XG ADDITIONAL DRUM MAPPING # # Use this file with --xgmap=on option for drvmidi # # standard kit 1; preset number is shifted to 64 0/128:64/128 # map standard 1 from original fonts (preset#0) 0/128/86:64/128/13 # surdo mute 0/128/87:64/128/14 # surdo open 0/128/27:64/128/15 # hi-Q 0/128/28:64/128/16 # whip slap 0/128/29:64/128/17 # scratch push 0/128/30:64/128/18 # scratch pull #0/128/26:64/128/19 # finger snap 0/128/33:64/128/19 # finger snap 0/128/32:64/128/20 # click noise 0/128/33:64/128/21 # metronome click 0/128/34:64/128/22 # metromome bell 0/128/32:64/128/23 # seq click L 0/128/32:64/128/24 # seq click H 40/128/38:64/128/25 # brush tap 40/128/40:64/128/26 # brush swirl L 40/128/39:64/128/27 # brush slap 50/128/90:64/128/28 # brush swirl H 0/128/25:64/128/29 # snare roll 0/128/88:64/128/30 # castanet 0/128/38:64/128/31 # snare L 0/128/31:64/128/32 # sticks 25/128/35:64/128/33 # BD L #64/128/34 # open rim shot # standard kit 2 1/128:65/128 # map standard 2 1/128/86:65/128/13 # surdo mute 1/128/87:65/128/14 # surdo open 1/128/27:65/128/15 # hi-Q 1/128/28:65/128/16 # whip slap 1/128/29:65/128/17 # scratch push 1/128/30:65/128/18 # scratch pull #1/128/26:65/128/19 # finger snap 1/128/33:65/128/19 # finger snap 1/128/32:65/128/20 # click noise 1/128/33:65/128/21 # metronome click 1/128/34:65/128/22 # metromome bell 1/128/32:65/128/23 # seq click L 1/128/32:65/128/24 # seq click H 40/128/38:65/128/25 # brush tap 40/128/40:65/128/26 # brush swirl L 40/128/39:65/128/27 # brush slap 50/128/90:65/128/28 # brush swirl H 1/128/25:65/128/29 # snare roll 1/128/88:65/128/30 # castanet 1/128/38:65/128/31 # snare L 1/128/31:65/128/32 # sticks 25/128/35:65/128/33 # BD L #65/128/34 # open rim shot # electronic kit #24 24/128:88/128 # map default 24/128/86:88/128/13 # surdo mute 24/128/87:88/128/14 # surdo open 24/128/27:88/128/15 # hi-Q 24/128/28:88/128/16 # whip slap 24/128/29:88/128/17 # scratch push 24/128/30:88/128/18 # scratch pull #24/128/26:88/128/19 # finger snap 24/128/33:88/128/19 # click noise 24/128/32:88/128/20 # click noise 24/128/33:88/128/21 # metronome click 24/128/34:88/128/22 # metromome bell 24/128/32:88/128/23 # seq click L 24/128/32:88/128/24 # seq click H 40/128/38:88/128/25 # brush tap 40/128/40:88/128/26 # brush swirl L 40/128/39:88/128/27 # brush slap 119/0/60:88/128/28 # reverse cymbal 24/128/25:88/128/29 # snare roll 24/128/27:88/128/30 # hi-Q 24/128/38:88/128/31 # snare L 24/128/31:88/128/32 # sticks 25/128/35:88/128/33 # BD L #88/128/34 # open rim shot 24/128/29:88/128/78 # scratch push 24/128/30:88/128/79 # scratch pull # analog kit #25 25/128:89/128 # map default 24/128/86:89/128/13 # surdo mute 24/128/87:89/128/14 # surdo open 24/128/27:89/128/15 # hi-Q 24/128/28:89/128/16 # whip slap 24/128/29:89/128/17 # scratch push 24/128/30:89/128/18 # scratch pull #24/128/26:89/128/19 # finger snap 24/128/33:89/128/19 # click noise 24/128/32:89/128/20 # click noise 24/128/33:89/128/21 # metronome click 24/128/34:89/128/22 # metromome bell 24/128/32:89/128/23 # seq click L 24/128/32:89/128/24 # seq click H 40/128/38:89/128/25 # brush tap 40/128/40:89/128/26 # brush swirl L 40/128/39:89/128/27 # brush slap 119/0/60:88/128/28 # reverse cymbal 24/128/25:89/128/29 # snare roll 24/128/27:89/128/30 # hi-Q 24/128/38:89/128/31 # snare L 24/128/31:89/128/32 # sticks 25/128/35:89/128/33 # BD L #89/128/34 # open rim shot 24/128/29:89/128/78 # scratch push 24/128/30:89/128/79 # scratch pull # orchestra kit #48 48/128:114/128 awesfx-0.5.2/samples/xgmap.bnk000066400000000000000000000001151344644735400163020ustar00rootroot00000000000000# # XG BANK FILE FOR STATIC LOADINIG # include xgsfx.bnk include xgdrum.bnk awesfx-0.5.2/samples/xgsfx.bnk000066400000000000000000000046631344644735400163410ustar00rootroot00000000000000# # SAMPLE MAP FILE FOR XG SFX SOUNDS # # Use this file with --xgmap=on option for drvmidi # # bank 64: XG SFX bank 120/1:0/64 # cut noise 120/1:1/64 # cut noise 2 120/1:2/64 # dist cut noise 120/2:3/64 # string slap 120/0:4/64 # bass slide 120/0:5/64 # pick strape 121/0:16/64 # fl key click 122/1:32/64 # train 122/2:33/64 # thunder 122/3:34/64 # wind 122/4:35/64 # stream 122/5:36/64 # bubble 125/127:37/64 # feed 123/1:48/64 # dog 123/2:49/64 # horse gallop 123/0:50/64 # bird 124/0:64/64 # telephone 124/2:65/64 # door creaking 124/3:66/64 # door slam 124/4:67/64 # scratch 124/4:68/64 # scratch 2 124/5:69/64 # wind chime 124/1:70/64 # telephone 2 125/1:80/64 # car engine 125/2:81/64 # car stop 125/3:82/64 # car pass 125/4:83/64 # car crash 125/5:84/64 # siren 125/6:85/64 # train 125/7:86/64 # jetplane 125/8:87/64 # starship 125/9:88/64 # burst noise 125/0:89/64 # coarster 126/1:96/64 # laughing 126/2:97/64 # screaming 126/3:98/64 # punch 126/4:99/64 # heart beat 126/5:100/64 # footsteps 126/0:101/64 # applause 127/1:112/64 # machine gun 127/2:113/64 # laser gun 127/3:114/64 # explosion 127/0:115/64 # fire work # bank 126, preset0: XG sfx keyboard map 120/1/60:0/126/36 # cut noise 120/1/60:0/126/37 # cut noise 2 120/1/60:0/126/38 # dist cut noise 120/2/60:0/126/39 # string slap 120/0/60:0/126/40 # bass slide 120/0/60:0/126/41 # pick slide 121/1/60:0/126/52 # fl key click 122/1/60:0/126/68 # rain 122/2/60:0/126/69 # thunder 122/3/60:0/126/79 # wind 122/4/60:0/126/71 # stream 122/5/60:0/126/72 # bubble 125/127/60:0/126/73 # feed 123/1/60:0/126/84 # dog 123/2/60:0/126/85 # horse gallop 123/0/60:0/126/86 # bird 2 # bank 126, preset1: XG sfx keyboard map 124/1/60:1/126/36 # telephone 2 124/2/60:1/126/37 # door creaking 124/3/60:1/126/38 # door slam 124/4/60:1/126/39 # scratch 124/4/60:1/126/40 # scratch 2 124/5/60:1/126/41 # wind chime 124/0/60:1/126/42 # telephone ring 125/1/60:1/126/52 # engine start 125/2/60:1/126/53 # stop 125/3/60:1/126/54 # car pass 125/4/60:1/126/55 # crash 125/5/60:1/126/56 # siren 125/6/60:1/126/57 # train 125/7/60:1/126/58 # jetplane 125/8/60:1/126/59 # starship 125/9/60:1/126/60 # burst noise 125/0/60:1/126/61 # coarster 126/1/60:1/126/68 # laughing 126/2/60:1/126/69 # screaming 126/3/60:1/126/70 # punch 126/4/60:1/126/71 # heart beat 126/5/60:1/126/72 # footsteps 126/0/60:1/126/73 # applause 127/1/60:1/126/84 # machine gun 127/2/60:1/126/85 # laser gun 127/3/60:1/126/86 # explosion 127/0/60:1/126/87 # fire work awesfx-0.5.2/seq.c000066400000000000000000000077261344644735400140010ustar00rootroot00000000000000/*================================================================ * seq.c * sequencer control routine for awe sound driver * * Copyright (C) 1996-1999 Takashi Iwai * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *================================================================*/ #include #include #include #include #include #include #include #ifdef __FreeBSD__ # include #elif defined(linux) # include #endif #include #include #include "seq.h" SEQ_DEFINEBUF(128); int seqfd; void seqbuf_dump() { if (_seqbufptr) if (write(seqfd, _seqbuf, _seqbufptr) == -1) { perror("write device"); exit(-1); } _seqbufptr = 0; } #define MAX_CARDS 16 int awe_dev; /*int max_synth_voices;*/ static void seq_init_priv(char *devname, int devidx); void seq_init(char *devname, int devidx) { if (devname == NULL) seq_init_priv(OSS_SEQUENCER_DEV, devidx); else seq_init_priv(devname, devidx); } static void seq_init_priv(char *devname, int devidx) { int i; int nrsynths; struct synth_info card_info; if ((seqfd = open(devname, O_WRONLY, 0)) < 0) { perror(devname); exit(1); } if (ioctl(seqfd, SNDCTL_SEQ_NRSYNTHS, &nrsynths) == -1) { fprintf(stderr, "there is no soundcard\n"); exit(1); } if (devidx >= 0) { card_info.device = devidx; if (ioctl(seqfd, SNDCTL_SYNTH_INFO, &card_info) < 0 || card_info.synth_type != SYNTH_TYPE_SAMPLE || card_info.synth_subtype != SAMPLE_TYPE_AWE32) { fprintf(stderr, "invalid soundcard (device = %s, index = %d)\n", devname, devidx); exit(1); } awe_dev = devidx; } else { /* auto probe */ awe_dev = -1; for (i = 0; i < nrsynths; i++) { card_info.device = i; if (ioctl(seqfd, SNDCTL_SYNTH_INFO, &card_info) == -1) { fprintf(stderr, "cannot get info on soundcard\n"); perror(devname); exit(1); } if (card_info.synth_type == SYNTH_TYPE_SAMPLE && card_info.synth_subtype == SAMPLE_TYPE_AWE32) { awe_dev = i; /*max_synth_voices = card_info.nr_voices;*/ break; } } if (awe_dev < 0) { fprintf(stderr, "No AWE synth device is found\n"); exit(1); } } } int seq_reset_samples(void) { if (ioctl(seqfd, SNDCTL_SEQ_RESETSAMPLES, &awe_dev) == -1) { perror("Sample reset"); exit(1); } return 0; } void seq_end(void) { SEQ_DUMPBUF(); /*ioctl(seqfd, SNDCTL_SEQ_SYNC);*/ close(seqfd); } int seq_remove_samples(void) { AWE_REMOVE_LAST_SAMPLES(seqfd, awe_dev); return 0; } void seq_default_atten(int val) { AWE_MISC_MODE(awe_dev, AWE_MD_ZERO_ATTEN, val); SEQ_DUMPBUF(); } void seq_set_gus_bank(int bank) { AWE_SET_GUS_BANK(awe_dev, bank); SEQ_DUMPBUF(); } int seq_load_rawpatch(void *patch, int len) { return write(seqfd, patch, len); } int seq_load_patch(void *patch, int len) { awe_patch_info *p; SEQ_DUMPBUF(); p = (awe_patch_info*)patch; p->key = AWE_PATCH; p->device_no = awe_dev; p->sf_id = 0; return write(seqfd, patch, len); } int seq_mem_avail(void) { int mem_avail = awe_dev; ioctl(seqfd, SNDCTL_SYNTH_MEMAVL, &mem_avail); return mem_avail; } int seq_zero_atten(int atten) { /* set zero attenuation level; this doesn't use seqbuf */ /* flag 0x40 is the ossseq global flag */ _AWE_CMD_NOW(seqfd, awe_dev, 0, _AWE_MISC_MODE|0x40, AWE_MD_ZERO_ATTEN, atten); return 0; } awesfx-0.5.2/seq.h000066400000000000000000000030001344644735400137630ustar00rootroot00000000000000/*================================================================ * seq.h * sequencer control routine * * Copyright (C) 1996-2003 Takashi Iwai * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *================================================================*/ #ifndef SEQ_H_DEF #define SEQ_H_DEF extern int seqfd; /*extern int nrsynths;*/ extern int awe_dev; /*extern int max_synth_voices;*/ #define OSS_SEQUENCER_DEV "/dev/sequencer" void seq_init(char *devname, int devidx); int seq_reset_samples(void); void seq_end(void); void seq_default_atten(int val); int seq_zero_atten(int val); int seq_remove_samples(void); void seq_initialize_chip(void); void seq_set_gus_bank(int bank); int seq_load_patch(void *patch, int len); int seq_load_rawpatch(void *patch, int len); int seq_mem_avail(void); /* alsa.c */ void seq_alsa_init(char *hwdep); void seq_alsa_end(void); #endif awesfx-0.5.2/setfx.c000066400000000000000000000265151344644735400143370ustar00rootroot00000000000000/*================================================================ * setfx -- load user defined chorus / reverb mode effects * * Copyright (C) 1996-1999 Takashi Iwai * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *================================================================*/ #include #include #include #include #include #ifdef __FreeBSD__ # include #elif defined(linux) # include #endif #include #include "util.h" #include "seq.h" #include "aweseq.h" #include "awe_version.h" /*----------------------------------------------------------------*/ static void usage(void); static int my_getline(FILE *fp); static int nextline(FILE *fp); static char *gettok(FILE *fp); static char *divtok(char *src, char *divs, int only_one); static int htoi(char *p); static void read_chorus(int mode, char *name, int incl, FILE *fp); static void read_reverb(int mode, char *name, int incl, FILE *fp); /*----------------------------------------------------------------*/ static char chorus_defined[AWE_CHORUS_NUMBERS] = {1,1,1,1,1,1,1,1,}; static char reverb_defined[AWE_CHORUS_NUMBERS] = {1,1,1,1,1,1,1,1,}; char *progname; int verbose = 0; /* file buffer */ static int curline; static char line[1024]; static int connected; /*----------------------------------------------------------------*/ static void usage(void) { fprintf(stderr, "setfx -- load user defined chorus / reverb mode effects\n"); fprintf(stderr, VERSION_NOTE); fprintf(stderr, "usage: setfx config-file\n"); #ifdef DEFAULT_SF_PATH fprintf(stderr, " system default path is %s\n", DEFAULT_SF_PATH); #endif exit(1); } int main(int argc, char **argv) { char *default_sf_path; char sfname[500]; FILE *fp; int c; char *seq_devname = NULL; int seq_devidx = -1; /* set program name */ progname = strrchr(argv[0], '/'); if (progname == NULL) progname = argv[0]; else progname++; while ((c = getopt(argc, argv, "F:D:")) != -1) { switch (c) { case 'F': seq_devname = optarg; break; case 'D': seq_devidx = atoi(optarg); break; default: usage(); exit(1); } } if (optind >= argc) { usage(); return 1; } /* search the config file */ default_sf_path = getenv("SFBANKDIR"); #ifdef DEFAULT_SF_PATH if (default_sf_path == NULL || *default_sf_path == 0) default_sf_path = safe_strdup(DEFAULT_SF_PATH); #endif if (! awe_search_file_name(sfname, sizeof(sfname), argv[optind], default_sf_path, NULL)) { fprintf(stderr, "%s: can't find such a file %s\n", progname, argv[optind]); return 1; } if ((fp = fopen(sfname, "r")) == NULL) { fprintf(stderr, "%s: can't open %s\n", progname, sfname); return 1; } curline = 0; if (!my_getline(fp)) return 0; seq_init(seq_devname, seq_devidx); do { int chorus, mode, incl; char *tok, *name; /* chorus/reverb header */ tok = divtok(line, ":", TRUE); if (*tok == 'c' || *tok == 'C') chorus = 1; else if (*tok == 'r' || *tok == 'R') chorus = 0; else continue; /* mode index */ tok = divtok(NULL, ":", TRUE); if (tok == NULL || *tok == 0) { fprintf(stderr, "%s: illegal line %d\n", progname, curline); continue; } mode = atoi(tok); if (mode < 8 || mode >= 32) { fprintf(stderr, "%s: illegal mode %d in line %d\n", progname, mode, curline); continue; } /* name of the mode */ name = divtok(NULL, ":", TRUE); if (name == NULL || *name == 0) { fprintf(stderr, "%s: illegal line %d\n", progname, curline); continue; } /* include mode index */ tok = divtok(NULL, ":", TRUE); if (tok == NULL) { fprintf(stderr, "%s: illegal line %d\n", progname, curline); continue; } if (*tok) { incl = atoi(tok); if (incl < 0 || incl >= 31 || (chorus && !chorus_defined[incl]) || (!chorus && !reverb_defined[incl])) { fprintf(stderr, "%s: illegal include %d in line %d\n", progname, incl, curline); continue; } } else incl = -1; /* parse parameters */ if (chorus) read_chorus(mode, name, incl, fp); else read_reverb(mode, name, incl, fp); } while (nextline(fp)); fclose(fp); seq_end(); return 0; } /*---------------------------------------------------------------- * pre-defined chorus and reverb modes *----------------------------------------------------------------*/ static awe_chorus_fx_rec chorus_parm[AWE_CHORUS_NUMBERS] = { {0xE600, 0x03F6, 0xBC2C ,0x00000000, 0x0000006D}, /* chorus 1 */ {0xE608, 0x031A, 0xBC6E, 0x00000000, 0x0000017C}, /* chorus 2 */ {0xE610, 0x031A, 0xBC84, 0x00000000, 0x00000083}, /* chorus 3 */ {0xE620, 0x0269, 0xBC6E, 0x00000000, 0x0000017C}, /* chorus 4 */ {0xE680, 0x04D3, 0xBCA6, 0x00000000, 0x0000005B}, /* feedback */ {0xE6E0, 0x044E, 0xBC37, 0x00000000, 0x00000026}, /* flanger */ {0xE600, 0x0B06, 0xBC00, 0x0000E000, 0x00000083}, /* short delay */ {0xE6C0, 0x0B06, 0xBC00, 0x0000E000, 0x00000083}, /* short delay + feedback */ }; static awe_reverb_fx_rec reverb_parm[AWE_REVERB_NUMBERS] = { {{ /* room 1 */ 0xB488, 0xA450, 0x9550, 0x84B5, 0x383A, 0x3EB5, 0x72F4, 0x72A4, 0x7254, 0x7204, 0x7204, 0x7204, 0x4416, 0x4516, 0xA490, 0xA590, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429, 0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528, }}, {{ /* room 2 */ 0xB488, 0xA458, 0x9558, 0x84B5, 0x383A, 0x3EB5, 0x7284, 0x7254, 0x7224, 0x7224, 0x7254, 0x7284, 0x4448, 0x4548, 0xA440, 0xA540, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429, 0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528, }}, {{ /* room 3 */ 0xB488, 0xA460, 0x9560, 0x84B5, 0x383A, 0x3EB5, 0x7284, 0x7254, 0x7224, 0x7224, 0x7254, 0x7284, 0x4416, 0x4516, 0xA490, 0xA590, 0x842C, 0x852C, 0x842C, 0x852C, 0x842B, 0x852B, 0x842B, 0x852B, 0x842A, 0x852A, 0x842A, 0x852A, }}, {{ /* hall 1 */ 0xB488, 0xA470, 0x9570, 0x84B5, 0x383A, 0x3EB5, 0x7284, 0x7254, 0x7224, 0x7224, 0x7254, 0x7284, 0x4448, 0x4548, 0xA440, 0xA540, 0x842B, 0x852B, 0x842B, 0x852B, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429, 0x8529, 0x8429, 0x8529, }}, {{ /* hall 2 */ 0xB488, 0xA470, 0x9570, 0x84B5, 0x383A, 0x3EB5, 0x7254, 0x7234, 0x7224, 0x7254, 0x7264, 0x7294, 0x44C3, 0x45C3, 0xA404, 0xA504, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429, 0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528, }}, {{ /* plate */ 0xB4FF, 0xA470, 0x9570, 0x84B5, 0x383A, 0x3EB5, 0x7234, 0x7234, 0x7234, 0x7234, 0x7234, 0x7234, 0x4448, 0x4548, 0xA440, 0xA540, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429, 0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528, }}, {{ /* delay */ 0xB4FF, 0xA470, 0x9500, 0x84B5, 0x333A, 0x39B5, 0x7204, 0x7204, 0x7204, 0x7204, 0x7204, 0x72F4, 0x4400, 0x4500, 0xA4FF, 0xA5FF, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420, 0x8520, }}, {{ /* panning delay */ 0xB4FF, 0xA490, 0x9590, 0x8474, 0x333A, 0x39B5, 0x7204, 0x7204, 0x7204, 0x7204, 0x7204, 0x72F4, 0x4400, 0x4500, 0xA4FF, 0xA5FF, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420, 0x8520, }}, }; /*---------------------------------------------------------------- * read reverb definition *----------------------------------------------------------------*/ static void read_reverb(int mode, char *name, int incl, FILE *fp) { char *p; int i, val; struct reverb_pat { awe_patch_info patch; awe_reverb_fx_rec v; } r; if (incl >= 0) { /* include from pre-defined mode */ reverb_parm[mode] = reverb_parm[incl]; while ((p = gettok(fp)) != NULL) { int src; char *q; for (q = p; *q; q++) { if (*q == '=') { *q++ = 0; break; } } if (!*q) { fprintf(stderr, "%s: illegal reverb definition: %s\n", progname, name); return; } src = atoi(p); val = htoi(q); if (src < 0 || src >= 28) { fprintf(stderr, "%s: illegal reverb parm: %s\n", progname, name); return; } reverb_parm[mode].parms[src] = val; } } else { /* define all 28 parameters */ for (i = 0; i < 28; i++) { if ((p = gettok(fp)) == NULL) { fprintf(stderr, "%s: too short reverb definition: %s\n", progname, name); return; } val = htoi(p); reverb_parm[mode].parms[i] = val; } } r.patch.optarg = mode; r.patch.len = sizeof(awe_reverb_fx_rec); r.patch.type = AWE_LOAD_REVERB_FX; r.v = reverb_parm[mode]; seq_load_patch(&r, sizeof(r)); reverb_defined[mode] = 1; } /*---------------------------------------------------------------- * read chorus definition *----------------------------------------------------------------*/ static void read_chorus(int mode, char *name, int incl, FILE *fp) { char *p; int i, val; struct chorus_pat { awe_patch_info patch; awe_chorus_fx_rec v; } c; /* define all five parameters */ for (i = 0; i < 5; i++) { if ((p = gettok(fp)) == NULL) { fprintf(stderr, "%s: illegal chorus definition: %s\n", progname, name); return; } val = htoi(p); switch (i) { case 0: chorus_parm[mode].feedback = val; break; case 1: chorus_parm[mode].delay_offset = val; break; case 2: chorus_parm[mode].lfo_depth = val; break; case 3: chorus_parm[mode].delay = val; break; case 4: chorus_parm[mode].lfo_freq = val; break; } } c.patch.optarg = mode; c.patch.len = sizeof(awe_chorus_fx_rec); c.patch.type = AWE_LOAD_CHORUS_FX; c.v = chorus_parm[mode]; seq_load_patch(&c, sizeof(c)); chorus_defined[mode] = 1; } /*---------------------------------------------------------------- * read a line and parse tokens *----------------------------------------------------------------*/ static int my_getline(FILE *fp) { char *p; curline++; connected = FALSE; if (fgets(line, sizeof(line), fp) == NULL) return FALSE; /* strip the linefeed and backslash at the tail */ for (p = line; *p && *p != '\n'; p++) { if (*p == '\\' && p[1] == '\n') { *p = 0; connected = TRUE; break; } } *p = 0; return TRUE; } static int nextline(FILE *fp) { if (connected) { do { if (! my_getline(fp)) return FALSE; } while (connected); return TRUE; } else { return my_getline(fp); } } /* hex to integer */ static int htoi(char *p) { return strtol(p, NULL, 16); } /* get a token separated by spaces */ static char *gettok(FILE *fp) { char *tok; tok = divtok(NULL, " \t\r\n", FALSE); while (tok == NULL || *tok == 0) { if (! connected) return NULL; if (! my_getline(fp)) return NULL; tok = divtok(line, " \t\r\n", FALSE); } return tok; } /* divide a token with specified terminators; * this behaves just like strtok. if only_one is TRUE, divtok checks only * one letter as a divider. */ static char *divtok(char *src, char *divs, int only_one) { static char *lastp = NULL; char *tok; if (src) lastp = src; if (!only_one) { for (; *lastp && strchr(divs, *lastp); lastp++) ; } tok = lastp; for (; *lastp && !strchr(divs, *lastp); lastp++) ; if (lastp) *lastp++ = 0; return tok; } awesfx-0.5.2/sf2text.c000066400000000000000000000133341344644735400146000ustar00rootroot00000000000000/*================================================================ * sf2text -- print soundfont layer information * * Copyright (C) 1996-2000 Takashi Iwai * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *================================================================*/ #include #include #include #include "sffile.h" #include "sfitem.h" #include "sflayer.h" #include "awe_parm.h" #include "util.h" int seqfd, awe_dev; static SFInfo sfinfo; void print_soundfont(FILE *fp, SFInfo *sf); static void print_name(FILE *fp, char *str); static void print_layers(FILE *fp, SFInfo *sf, SFHeader *hdr); static void print_amount(FILE *fp, SFInfo *sf, SFGenRec *gen); int main(int argc, char **argv) { FILE *fd, *fout; int piped=0; if (argc < 2 || strcmp(argv[1],"-") == 0) { piped = 1; fd = stdin; } else { if (strcmp(argv[1], "-h") ==0 || strcmp(argv[1], "--help") == 0) { fprintf(stderr, "no file is given\n"); fprintf(stderr, "usage: sf2text soundfont [outputfile]\n"); return 1; } if ((fd = fopen(argv[1], "r")) == NULL) { fprintf(stderr, "can't open file %s\n", argv[1]); return 1; } } if (awe_load_soundfont(&sfinfo, fd, !piped) < 0) return 1; fclose(fd); if (argc < 3 || strcmp(argv[2], "-")) fout = stdout; else { if ((fout = fopen(argv[2], "w")) == NULL) { fprintf(stderr, "can't open file %s\n", argv[2]); return 1; } } print_soundfont(fout, &sfinfo); return 0; } void print_soundfont(FILE *fp, SFInfo *sf) { int i; SFPresetHdr *preset; SFInstHdr *inst; SFSampleInfo *sp; fprintf(fp, "(Name "); print_name(fp, sf->sf_name); fprintf(fp, ")\n"); fprintf(fp, "(SoundFont %d %d)\n", sf->version, sf->minorversion); fprintf(fp, "(SamplePos %ld %d)\n", sf->samplepos, sf->samplesize); fprintf(fp, "(InfoPos %ld %ld)\n", sf->infopos, sf->infosize); fprintf(fp, "(Presets %d (\n", sf->npresets); for (preset = sf->preset, i = 0; i < sf->npresets; preset++, i++) { fprintf(fp, " ("); fprintf(fp, "%d ", i); print_name(fp, preset->hdr.name); fprintf(fp, " (preset %d) (bank %d) (\n", preset->preset, preset->bank); print_layers(fp, sf, &preset->hdr); fprintf(fp, " ))\n"); } fprintf(fp, " ))\n"); fprintf(fp, "(Instruments %d (\n", sf->ninsts); for (inst = sf->inst, i = 0; i < sf->ninsts; inst++, i++) { fprintf(fp, " ("); fprintf(fp, "%d ", i); print_name(fp, inst->hdr.name); fprintf(fp, " (\n"); print_layers(fp, sf, &inst->hdr); fprintf(fp, " ))\n"); } fprintf(fp, " ))\n"); fprintf(fp, "(SampleInfo %d (\n", sf->nsamples); for (sp = sf->sample, i = 0; i < sf->nsamples; sp++, i++) { fprintf(fp, " (%d ", i); print_name(fp, sp->name); fprintf(fp, " (0x%x 0x%x) (0x%x 0x%x)", sp->startsample, sp->endsample, sp->startloop, sp->endloop); if (sf->version == 2) { fprintf(fp, "\n (%d %d %d %d %d)", sp->samplerate, sp->originalPitch, sp->pitchCorrection, sp->samplelink, sp->sampletype); } fprintf(fp, ")\n"); } fprintf(fp, " ))\n"); } /* print string value. escape or convert the letter to octet if necessary. */ static void print_name(FILE *fp, char *str) { int i = 0; unsigned char *p; putc('"', fp); for (p = str; *p && i < 20; i++, p++) { if (!isprint(*p)) fprintf(fp, "\\%03o", *p); else if (*p == '"') fprintf(fp, "\\\""); else putc(*p, fp); } putc('"', fp); } /* print layered list */ static void print_layers(FILE *fp, SFInfo *sf, SFHeader *hdr) { SFGenLayer *lay = hdr->layer; int j, k; for (j = 0; j < hdr->nlayers; lay++, j++) { if (lay->nlists == 0) continue; fprintf(fp, " (layer\n"); for (k = 0; k < lay->nlists; k++) { print_amount(fp, sf, &lay->list[k]); if (k == lay->nlists-1) fprintf(fp, ")\n"); else fprintf(fp, "\n"); } } } /* print a layer item together with optional info */ static void print_amount(FILE *fp, SFInfo *sf, SFGenRec *gen) { LayerItem *item = &layer_items[gen->oper]; int amount; fprintf(fp, " (%s %d", sf_gen_text[gen->oper], gen->amount); if (sf->version == 1) amount = sbk_to_sf2(gen->oper, gen->amount); else amount = gen->amount; switch (item->type) { case T_NOP: case T_NOCONV: case T_OFFSET: case T_HI_OFF: case T_SCALE: fprintf(fp, " "); if (gen->oper == SF_sampleId) print_name(fp, sf->sample[amount].name); else if (gen->oper == SF_instrument) print_name(fp, sf->inst[amount].hdr.name); else fprintf(fp, "%d", amount); break; case T_RANGE: fprintf(fp, " (%d %d)", LOWNUM(amount), HIGHNUM(amount)); break; case T_FILTERQ: case T_ATTEN: case T_TREMOLO: case T_VOLSUST: fprintf(fp, " %d cB", amount); break; case T_MODSUST: fprintf(fp, " %g %%", (double)amount/10.0); break; case T_CUTOFF: fprintf(fp, " %d Hz", awe_abscent_to_Hz(amount)); break; case T_FREQ: fprintf(fp, " %d mHz", awe_abscent_to_mHz(amount)); break; case T_TIME: fprintf(fp, " %d msec", awe_timecent_to_msec(amount)); break; case T_TENPCT: case T_PANPOS: fprintf(fp, " %g %%", (double)amount / 10.0); break; case T_PSHIFT: case T_CSHIFT: fprintf(fp, " %g semitone", (double)amount / 100); break; } fprintf(fp, ")"); } awesfx-0.5.2/sfxload.1000066400000000000000000000222021344644735400145510ustar00rootroot00000000000000.TH sfxload 1 "January 22, 2003" .LO 1 .SH NAME sfxload, asfxload \- load a SoundFont file on the Emux WaveTable .SH SYNOPSIS .B sfxload .RI [\| \-options \|] " fontfile" .B asfxload .RI [\| \-options \|] " fontfile" .SH DESCRIPTION .B sfxload and .B asfxload are utility program sto transfer the sound wave and instruments data in a SoundFont file to the AWE32 sound driver, or to the Emux WaveTable of ALSA sbawe and emu10k1 drivers. This program is necessary for playing MIDI samples via sequencer programs supporting AWE driver. There is no big difference between \fBsfxload\fP and \fBasfxload\fP except for that \fBasfxload\fP is for ALSA and \fBsfxload\fP is for OSS, respecitvely. The options to specify devices are different between them (see below). Basically, sfxload behaves as two ways. .in +1i % sfxload fontfile .br % sfxload \-b1 fontfile .in -1i The first usage is to read SF2 (or SBK) file and transfer to the awe driver. In this case, the samples which were loaded on the driver are replaced with the new one. In the second case, sfxload reads the file and appends it to the pre-loaded samples on the driver with specified bank number. The old samples remain in the driver. The additional samples can be cleared via \fB\-x\fP option (see below). The sound files are searched through the path list. The path list is defined as built-in. If the environment variable \fBSFBANKDIR\fP or the command line option \fB\-P\fP is given, it replaces the default search list. The file extension \fI.sf2\fP, and \fI.sbk\fP can be abbreviated. .SH OPTIONS .TP .BI \-F,\ \-\-device= file " \fR(sfxload only)\fP" Specify the device file to be used. Default value is .IR /dev/sequencer . .TP .BI \-D,\ \-\-index= number " \fR(sfxload only)\fP" Specify the device index of AWE driver. Negative number (e.g. \-1) means to probe the first AWE device automatically. For selecting the other AWE cards, a positive index number must be given here. Default value is \fB\-1\fP. .TP .BI \-D,\ \-\-hwdep= name " \fR(asfxload only)\fP" Specify the hwdep name to be used. As default, asfxload seeks until any Emux compatible hwdep device is found. .TP .BI \-i,\ \-\-clear "\fR[=\fPbool\fR]\fP" Remove all samples before loading the fonts. This is an explicit directive (see -b option). If this option is specified alone without soundfont file arguments, sfxload does onlay remove samples. Either of \fBon\fP, \fBoff\fP, \fByes\fP, \fBno\fP, \fBtrue\fP, or \fBfalse\fP can be specified as an optional argument. .TP .BI \-x,\ \-\-remove "\fR[=\fPbool\fR]\fP" Remove the optional samples previouly loaded via \fB\-b\fP option. Otherwise, all new samples are simply appended. .TP .BI \-N,\ \-\-increment "\fR[=\fPbool\fR]\fP" Do not clear samples even with the absence of \fB\-b\fP option. However, this option is not exclusive with .B \-x option. If both options are specified, and the memory full error is encountered during loading fonts, \fBsfxload\fP will try to remove samples and load the fonts again. .TP .BI \-b,\ \-\-bank= number Append the sound samples on the specified bank. Without this option, all present samples in the driver are removed before loading the new fonts unless \fB\-N\fP option is specified. Usually, this option is necessary to load user bank, typically in bank one. For example, .in +1i % sfxload synthgm.sbk .br % sfxload -b1 surprise.sf2 .br .in -1i .TP .BI \-l,\ \-\-lock "\fR[=\fPbool\fR]\fP" Lock the font. The locked font is no longer removed via remove option (\fB\-x\fP) even if it's loaded together with \fB\-b\fP option. .TP .BI \-C,\ \-\-compat "\fR[=\fPbool\fR]\fP" Use the old (v0.4.2) parameter calculations. .TP .BI \-A,\ \-\-sense= sensitivity (Only valid on compatible mode) .br Set sample attenuation sensitivity. This option controls the sensitivity of initial attenuation parameter of each instrument defined in SoundFont file. In the program, each parameter is calculated from the value divided by this number for the original value. The number \fI1.0\fP means that the original initial attenuation parameters would be used. Generally, smaller number makes drum sounds louder. (I think \fB"-A 2"\fP would be similar to Windows sounds.) The default value is \fI10\fP. Note that this option changes also the default attenuation automatically (see below). .TP .BI \-a,\ \-\-atten= attenuation (Only valid on compatible mode) .br Set the default attenuation level. This option controls the minimum attenuation of the sample. The parameter is given in raw digit number for AWE driver, that is, in 8/3 dB unit. Since \fB\-\-sense\fP option changes the default attenuation automatically, specify this option later from \fB\-\-sense\fP option. The default value is \fI32\fP. .TP .BI \-d,\ \-\-decay= scale (Only valid on compatible mode) .br Set the scale of envelope decay time. Default value is \fI50.0\fP. Sounds decay fast when larger number is set. The ver.0.3 sfxload uses \fI54.8\fP. If you want to keep the same sound, use this number instead. .TP .BI \-M,\ \-\-memory "\fR[=\fPbool\fR]\fP" Display the left memory size in DRAM on the AWE32 card. .TP .BI \-c,\ \-\-chorus= percent Specify the effects of chorus. The value is in percent, from 0 to 100. The default is unspecified. This value may be overwritten by MIDI control messages. .TP .BI \-r,\ \-\-reverb= percent Specify the effects of reverb. The value is in percent, from 0 to 100. The default is unspecified. This value may be overwritten by MIDI control messages. .TP .BI \-B,\ \-\-addblank "\fR[=\fPbool\fR]\fP" Add 48 size of blank loop on each sample data. Usually, this option is not necessary. Most of soundfont files are designed well for enough blank loops for each sample. .TP .BI \-L,\ \-\-extract= source \fR[:\fP map \fR]\fP Extract and load only the specified preset(s). This option is usually employed by drvmidi. The preset is given as same as in virtual bank file. .TP .BI \-v,\ \-\-verbose "\fR[=\fPlevel\fR]\fP" Increase or set the verbosity level. .TP .BI \-q,\ \-\-quiet Don't show error messages, equivalen with \-\-verbose=0. .TP .BI \-V,\ \-\-volume= percent Specify the total volume of sounds, provided in percent. The default volume is \fI70%\fP. .TP .BI \-P,\ \-\-path= path1 : path2 : pathN Specify the search path list. The sound files are searched from \fIpath1\fP, \fIpath2\fP, and so on. This overrides both the system path and environment variable \fBSFBANKDIR\fP. .SH "VIRTUAL BANK FILE" The virtual bank file is a list of presets treated as one soundfont file. The syntax of virtual bank is as follows: .in +1i # comments .br source:map[:soundfont [preset-name] .br source:map[:soundfont [preset-name] .br ... .in -1i The first and second items are the source and mapped presets, respectively. The former is the existing preset in the soundfont, and the latter is the actual preset loaded on the sound driver. The preset is described by the following three values, .in +1i preset/bank/keynote .in -1i If bank and keynote are omitted, bank 0 and keynote \-1 (meaning to search all keys) are applied. The third item is the name of soundfont file. The file is searched from the prescribed search-path. The remaining arguments are ignored in \fBsfxload\fP. If the soundfont name is omitted, sfxload loads it as preset mapping. It just behaves like a symbolic link of file opposing to copying of the file. Any sample data is not referred at this time, but searched first when the note is played. A couple of special commands can be used together with the virtual presets above. \fBdefault\fP command is used to specify the default soundfont file. Any other presets which are not defined in the virtual preset lists are loaded from this default font. For example, in the following virtual bank, \fI2mbgmgs.sf2\fP is used except for standard drumsets which employs \fIdrum.sf2\fP: .in +1i 0/128:0/128:drum.sf2 .br default 2mbgmgs.sf2 .in -1i Another special command is \fBinclude\fP command. This simply includes another virtual bank file under the current position. For example, .in +1i default standard.sf2 .br 0/128:0/128:drum.sf2 .br include xgsfx.bnk .in -1i .SH "SYSTEM RESROUCE FILE" The default option arguments can be stored in the system resource file. There are two files loaded as default. .in +1i .I $HOME/.sfxloadrc .br .I /etc/sfxloadrc .in -1i The syntax is as follows: .in +1i fontname \-options.. .in -1i The first argument is soundfont file name for each option. The remaining arguments are identical with command line options. The font name \fIdefault\fP is used for default options for all sound fonts. The default options are overridden by specific options or command line options. For example, to set default chorus level 20 except for synthgm font, you can write a resource file \fI~/.sfxloadrc\fP like that: .in +1i default \-\-chorus=20 .br synthgm \-\-chorus=0 .in -1i .SH ENVIRONMENT .TP .B SFBANKDIR Search path for sound files. The current directory is always searched at first. .SH "SEE ALSO" .BR drvmidi (1) .SH COPYRIGHT Copyright (C) 1996-2003 Takashi Iwai. .P The AWE32 driver and utilties are free software; you can redistribute them and/or modify them under the terms of the \fIGNU General Public License\fP as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. awesfx-0.5.2/sfxload.c000066400000000000000000000220571344644735400146430ustar00rootroot00000000000000/*================================================================ * sfxload -- load soundfont info onto awe sound driver * * Copyright (C) 1996-2000 Takashi Iwai * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *================================================================*/ #include #include #include #include #include #include #include #include #ifdef BUILD_ASFXLOAD #include #endif #include #include #include #include "seq.h" #ifdef BUILD_ASFXLOAD #define PROGNAME "asfxload" #else #define PROGNAME "sfxload" #endif static char *get_fontname(int argc, char **argv); static int parse_options(int argc, char **argv); static void add_part_list(char *arg); extern int awe_verbose; static AWEOps load_ops = { seq_load_patch, seq_mem_avail, seq_reset_samples, seq_remove_samples, seq_zero_atten }; /*---------------------------------------------------------------- * print usage and exit *----------------------------------------------------------------*/ static void usage() { fputs( #ifdef BUILD_ASFXLOAD "asfxload -- load SoundFont on ALSA Emux WaveTable\n" #else "sfxload -- load SoundFont on OSS AWE32 sound driver\n" #endif VERSION_NOTE "usage: " PROGNAME " [-options] [soundfont[.sf2|.sbk|.bnk]]\n" "\n" " options:\n" #ifdef BUILD_ASFXLOAD " -D, --hwdep=name specify the hwdep name\n" #else " -F, --device=file specify the device file\n" " -D, --index=number specify the device index (-1=autoprobe)\n" #endif " -i, --clear[=bool] clear all samples\n" " -x, --remove[=bool] remove additional samples\n" " -N, --increment[=bool] incremental loading\n" " -b, --bank=number append font to the specified bank\n" " -l, --lock[=bool] lock the loading fonts\n" " -v, --verbose[=int] set verbosity level\n" " -q, --quiet don't print error messages\n" " -C, --compat[=bool] use v0.4.2 compatible sounds\n", stderr); fprintf(stderr, " -A, --sense=digit (compat) set attenuation sensitivity (default=%g)\n", awe_option.atten_sense); fprintf(stderr, " -a, --atten=digit (compat) set default attenuattion (default=%d)\n", awe_option.default_atten); fprintf(stderr, " -d, --decay=scale (compat) set decay time scale (default=%g)\n", awe_option.decay_sense); fputs(" -M, --memory[=bool] display available memory on DRAM\n" " -B, --addblank[=bool] add 12 words blank loop on each sample\n" " -c, --chorus=percent set chorus effect (0-100)\n" " -r, --reverb=percent set reverb effect (0-100)\n", stderr); fprintf(stderr, " -V, --volume=percent set total volume (0-100) (default=%d)\n", awe_option.default_volume); fputs(" -L, --extract=preset/bank/note\n" " do partial loading\n" " -P, --path=dir set SoundFont file search path\n", stderr); if (awe_option.search_path) fprintf(stderr, " system default path is %s\n", awe_option.search_path); exit(1); } static int sample_mode, remove_samples, dispmem, lock_sf; enum { CLEAR_SAMPLE, INCREMENT_SAMPLE, ADD_SAMPLE }; #ifdef BUILD_ASFXLOAD static char *hwdep_name = NULL; #else static char *seq_devname = NULL; static int seq_devidx = -1; #endif static LoadList *part_list = NULL; int main(int argc, char **argv) { char *sffile; int rc; awe_init_option(); sample_mode = ADD_SAMPLE; remove_samples = FALSE; dispmem = FALSE; lock_sf = -1; awe_verbose = 1; part_list = NULL; awe_read_option_file(NULL); if ((sffile = get_fontname(argc, argv)) != NULL) { awe_read_option_file(sffile); } parse_options(argc, argv); DEBUG(1,fprintf(stderr, "default bank = %d\n", awe_option.default_bank)); DEBUG(1,fprintf(stderr, "default chorus = %d\n", awe_option.default_chorus)); DEBUG(1,fprintf(stderr, "default reverb = %d\n", awe_option.default_reverb)); if (awe_option.compatible) { DEBUG(1,fprintf(stderr, "v0.4.2-compatible mode\n")); DEBUG(1,fprintf(stderr, "minimum attenuation = %d\n", awe_option.default_atten)); DEBUG(1,fprintf(stderr, "attenuation sense = %g\n", awe_option.atten_sense)); DEBUG(1,fprintf(stderr, "decay sense = %g\n", awe_option.decay_sense)); } else { DEBUG(1,fprintf(stderr, "use new calculation\n")); } /*----------------------------------------------------------------*/ #ifdef BUILD_ASFXLOAD seq_alsa_init(hwdep_name); #else /* reset samples if necessary */ seq_init(seq_devname, seq_devidx); #endif /* clear or remove samples */ if (sample_mode == ADD_SAMPLE && awe_option.default_bank < 0 && sffile) sample_mode = CLEAR_SAMPLE; if (sample_mode == CLEAR_SAMPLE) seq_reset_samples(); else if (sample_mode != INCREMENT_SAMPLE && remove_samples) seq_remove_samples(); if (sffile == NULL && dispmem) { if (dispmem) printf("DRAM memory left = %d kB\n", seq_mem_avail()/1024); } if (sffile == NULL) { #ifdef BUILD_ASFXLOAD seq_alsa_end(); #else seq_end(); #endif return 0; } /* if lock option is not specified, lockinig depends on bank mode */ if (lock_sf < 0) { if (awe_option.default_bank < 0) lock_sf = TRUE; else lock_sf = FALSE; } rc = awe_load_bank(&load_ops, sffile, part_list, lock_sf); if (sample_mode == INCREMENT_SAMPLE && remove_samples) { if (rc == AWE_RET_NOMEM) { seq_remove_samples(); rc = awe_load_bank(&load_ops, sffile, part_list, lock_sf); } } if (rc == AWE_RET_OK && dispmem) printf("DRAM memory left = %d kB\n", seq_mem_avail()/1024); #ifdef BUILD_ASFXLOAD seq_alsa_end(); #else seq_end(); #endif if (rc == AWE_RET_NOMEM) { if (awe_verbose) fprintf(stderr, "sfxload: no memory left\n"); return 1; } else if (rc == AWE_RET_NOT_FOUND) { fprintf(stderr, "sfxload: can't find font file %s\n", sffile); return 1; } else if (rc == AWE_RET_ERR) { if (awe_verbose) fprintf(stderr, "sfxload: stopped by error\n"); } return 0; } /*---------------------------------------------------------------- * long options *----------------------------------------------------------------*/ static struct option long_options[] = { {"memory", 2, 0, 'M'}, {"remove", 2, 0, 'x'}, {"increment", 2, 0, 'N'}, {"clear", 2, 0, 'i'}, {"verbose", 2, 0, 'v'}, {"quiet", 0, 0, 'q'}, {"extract", 1, 0, 'L'}, {"lock", 2, 0, 'l'}, #ifdef BUILD_ASFXLOAD {"hwdep", 1, 0, 'D'}, #else {"device", 1, 0, 'F'}, {"index", 1, 0, 'D'}, #endif {0, 0, 0, 0}, }; static int option_index; #ifdef BUILD_ASFXLOAD #define OPTION_FLAGS "MxNivqL:lD:" #else #define OPTION_FLAGS "MxNivqL:lF:D:" #endif int awe_get_argument(int argc, char **argv, char *optstr, struct option *args) { int c, dummy; int optind_saved; optind_saved = optind; optind = 0; while ((c = getopt_long(argc, argv, optstr, args, &dummy)) != -1) ; c = optind; optind = optind_saved; return c; } static char *get_fontname(int argc, char **argv) { int rc; rc = awe_get_argument(argc, argv, OPTION_FLAGS AWE_BASE_OPTIONS, long_options); if (rc < argc) return argv[rc]; return NULL; } #define set_bool() (optarg ? bool_val(optarg) : TRUE) static int parse_options(int argc, char **argv) { int c; while ((c = awe_parse_options(argc, argv, OPTION_FLAGS, long_options, &option_index)) != -1) { if (c == 0) continue; switch (c) { case 'x': remove_samples = set_bool(); break; case 'N': if (set_bool()) sample_mode = INCREMENT_SAMPLE; break; case 'i': if (set_bool()) sample_mode = CLEAR_SAMPLE; break; case 'M': dispmem = set_bool(); break; case 'v': if (optarg) awe_verbose = atoi(optarg); else awe_verbose++; break; case 'q': awe_verbose = 0; break; case 'L': add_part_list(optarg); break; case 'l': lock_sf = set_bool(); break; #ifdef BUILD_ASFXLOAD case 'D': hwdep_name = optarg; break; #else case 'F': seq_devname = optarg; break; case 'D': seq_devidx = atoi(optarg); break; #endif case 'm': case 's': case 'I': break; default: usage(); exit(1); } } return -1; } /* make a preset list from comand line options */ static void add_part_list(char *arg) { char tmp[100]; SFPatchRec pat, map; if (strlen(arg) > sizeof(tmp)-1) { fprintf(stderr, "sfxload: illegal argument %s\n", arg); return; } strcpy(tmp, arg); if (awe_parse_loadlist(tmp, &pat, &map, NULL)) part_list = awe_add_loadlist(part_list, &pat, &map); } awesfx-0.5.2/sfxtest.c000066400000000000000000000201741344644735400147010ustar00rootroot00000000000000/*================================================================ * sfxtest -- example program to control awe sound driver * * Copyright (C) 1996-2000 Takashi Iwai * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *================================================================*/ #include #include #include #include #include #include #ifdef __FreeBSD__ # include #elif defined(linux) # include #endif #include #include "seq.h" #include "awe_version.h" SEQ_USE_EXTBUF(); static int buffering = 0; /*----------------------------------------------------------------*/ static void seq_set_bank(int v, int bank) { fprintf(stderr, "bank=%d\n", bank); SEQ_CONTROL(awe_dev, v, CTL_BANK_SELECT, bank); if (!buffering) seqbuf_dump(); } static void seq_set_program(int v, int pgm) { fprintf(stderr, "program=%d\n", pgm); SEQ_SET_PATCH(awe_dev, v, pgm); if (!buffering) seqbuf_dump(); } static void seq_start_note(int v, int note, int vel) { fprintf(stderr, "note on = %d %d\n", note, vel); SEQ_START_NOTE(awe_dev, v, note, vel); if (!buffering) seqbuf_dump(); } static void seq_stop_note(int v, int note) { fprintf(stderr, "note off\n"); SEQ_STOP_NOTE(awe_dev, v, note, 0); if (!buffering) seqbuf_dump(); } static void seq_pitchsense(int v, int val) { fprintf(stderr, "bender range %d\n", val); SEQ_BENDER_RANGE(awe_dev, v, val); if (!buffering) seqbuf_dump(); } static void seq_pitchbend(int v, int val) { fprintf(stderr, "bender %d\n", val); SEQ_BENDER(awe_dev, v, val); if (!buffering) seqbuf_dump(); } static void seq_panning(int v, int val) { fprintf(stderr, "panning %d\n", val); SEQ_CONTROL(awe_dev, v, CTL_PAN, val); if (!buffering) seqbuf_dump(); } static void seq_key_press(int v, int note, int vel) { fprintf(stderr, "key pressure %d %d\n", note, vel); SEQ_KEY_PRESSURE(awe_dev, v, note, vel); if (!buffering) seqbuf_dump(); } static void seq_send_effect(int v, int type, int val) { fprintf(stderr, "send effect %d %d\n", type, val); AWE_SEND_EFFECT(awe_dev, v, type, val); if (!buffering) seqbuf_dump(); } static void seq_add_effect(int v, int type, int val) { fprintf(stderr, "add effect %d %d\n", type, val); AWE_ADD_EFFECT(awe_dev, v, type, val); if (!buffering) seqbuf_dump(); } static void seq_send_control(int v, int type, int val) { fprintf(stderr, "send control %d %d\n", type, val); SEQ_CONTROL(awe_dev, v, type, val); if (!buffering) seqbuf_dump(); } static void seq_wait(int time) { fprintf(stderr, "wait %d\n", time); SEQ_DELTA_TIME(time); if (!buffering) seqbuf_dump(); } static void seq_set_debug(int mode) { fprintf(stderr, "debug %d\n", mode); AWE_DEBUG_MODE(awe_dev, mode); if (!buffering) seqbuf_dump(); } static void seq_set_reverb(int mode) { fprintf(stderr, "reverb %d\n", mode); AWE_REVERB_MODE(awe_dev, mode); if (!buffering) seqbuf_dump(); } static void seq_set_chorus(int mode) { fprintf(stderr, "chorus %d\n", mode); AWE_CHORUS_MODE(awe_dev, mode); if (!buffering) seqbuf_dump(); } static void seq_init_chip() { fprintf(stderr, "initialize chip\n"); AWE_INITIALIZE_CHIP(seqfd, awe_dev); if (!buffering) seqbuf_dump(); } static void seq_set_channel_mode(int mode) { fprintf(stderr, "channel mode = %d\n", mode); AWE_SET_CHANNEL_MODE(awe_dev, mode); if (!buffering) seqbuf_dump(); } static void seq_equalizer(int bass, int treble) { fprintf(stderr, "equalizer = %d %d\n", bass, treble); AWE_EQUALIZER(awe_dev, bass, treble); if (!buffering) seqbuf_dump(); } static void seq_drum_channels(int channels) { fprintf(stderr, "drum_channels = 0x%x\n", channels); AWE_DRUM_CHANNELS(awe_dev, channels); if (!buffering) seqbuf_dump(); } /*----------------------------------------------------------------*/ static void usage(); int main(int argc, char **argv) { int idx, chan; int c; char *seq_devname = NULL; int seq_devidx = -1; while ((c = getopt(argc, argv, "F:D:")) != -1) { switch (c) { case 'F': seq_devname = optarg; break; case 'D': seq_devidx = atoi(optarg); break; default: usage(); exit(1); } } if (optind >= argc) { usage(); return 1; } seq_init(seq_devname, seq_devidx); fprintf(stderr, "init done\n"); SEQ_START_TIMER(); if (!buffering) seqbuf_dump(); fprintf(stderr, "argc=%d\n", argc); idx = optind; chan = 0; while (idx < argc) { fprintf(stderr, "[%d] ", idx); switch (*argv[idx]) { case 'u': buffering = !buffering; fprintf(stderr, "buffering mode %d\n", buffering); idx++; break; case 'X': seq_set_channel_mode(1); idx++; break; case 'x': chan = atoi(argv[idx+1]); idx += 2; break; case 'b': seq_set_bank(chan, atoi(argv[idx+1])); idx += 2; break; case 'p': seq_set_program(chan, atoi(argv[idx+1])); idx += 2; break; case 'n': seq_start_note(chan, atoi(argv[idx+1]),atoi(argv[idx+2])); idx += 3; break; case 'k': seq_stop_note(chan, 0); idx++; break; case 'K': seq_stop_note(chan, atoi(argv[idx+1])); idx += 2; break; case 'r': seq_pitchsense(chan, atoi(argv[idx+1])); idx += 2; break; case 't': seq_wait(atoi(argv[idx+1])); idx += 2; break; case 'T': sleep(atoi(argv[idx+1])); idx += 2; break; case 'w': seq_pitchbend(chan, atoi(argv[idx+1])); idx += 2; break; case 'c': seq_panning(chan, atoi(argv[idx+1])); idx += 2; break; case 'v': seq_key_press(chan, atoi(argv[idx+1]), atoi(argv[idx+2])); idx += 3; break; case 'F': seq_send_effect(chan, atoi(argv[idx+1]), atoi(argv[idx+2])); idx += 3; break; case 'f': seq_add_effect(chan, atoi(argv[idx+1]), atoi(argv[idx+2])); idx += 3; break; case 'm': seq_send_control(chan, atoi(argv[idx+1]), atoi(argv[idx+2])); idx += 3; break; case 'D': seq_set_debug(atoi(argv[idx+1])); idx += 2; break; case 'd': seq_drum_channels(strtol(argv[idx+1], NULL, 0)); idx += 2; break; case 'R': seq_set_reverb(atoi(argv[idx+1])); idx += 2; break; case 'C': seq_set_chorus(atoi(argv[idx+1])); idx += 2; break; case 'I': seq_init_chip(); idx++; break; case 'V': AWE_INITIAL_VOLUME(awe_dev, atoi(argv[idx+1])); idx += 2; break; case 'e': seq_equalizer(atoi(argv[idx+1]), atoi(argv[idx+2])); idx += 3; break; case 'M': AWE_MISC_MODE(awe_dev, atoi(argv[idx+1]), atoi(argv[idx+2])); idx += 3; break; default: goto loopend; } } loopend: if (buffering) seqbuf_dump(); fprintf(stderr, "finishing..\n"); seq_end(); return 0; } static void usage() { fprintf(stderr, "sfxtest - a test program for AWE32/64 driver\n"); fprintf(stderr, VERSION_NOTE); fprintf(stderr, "usage: sfxtest cmd pars..\n"); fprintf(stderr, "commands =\n"); fprintf(stderr, "X: use channel control mode\n"); fprintf(stderr, "x channel: change channel\n"); fprintf(stderr, "b bank: change bank\n"); fprintf(stderr, "p prg: change program\n"); fprintf(stderr, "n note vel: start note\n"); fprintf(stderr, "k : kill a note\n"); fprintf(stderr, "K note: kill a note (for channel mode)\n"); fprintf(stderr, "r val: set pitch sense\n"); fprintf(stderr, "w val: set pitch wheel\n"); fprintf(stderr, "t time: wait for time csec\n"); fprintf(stderr, "c val: set panning\n"); fprintf(stderr, "v note vel: change key pressure\n"); fprintf(stderr, "D mode: set debug mode\n"); fprintf(stderr, "C mode: set chorus mode\n"); fprintf(stderr, "R mode: set reverb mode\n"); fprintf(stderr, "F parm val: send effect\n"); fprintf(stderr, "m parm val: send control value\n"); fprintf(stderr, "I: initialize emu chip\n"); } awesfx-0.5.2/text2sf.c000066400000000000000000000041271344644735400146000ustar00rootroot00000000000000/*================================================================ * text2sf -- convert text to soundfont formmat * * Copyright (C) 1996-2000 Takashi Iwai * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *================================================================*/ #include #include #include "util.h" #include "sffile.h" #include "awe_version.h" int seqfd, awe_dev; static SFInfo sfinfo; static void usage() { fprintf(stderr, "text2sf -- convert text file to soundfont format\n"); fprintf(stderr, VERSION_NOTE); fprintf(stderr, "usage: text2sf text-file original-file output-file\n"); fprintf(stderr, " text-file: s-list text file via sf2text\n"); fprintf(stderr, " original-file: original soundfont file\n"); fprintf(stderr, " output-file: output soundfont file\n"); exit(1); } int main(int argc, char **argv) { FILE *fp, *fout; int piped; if (argc < 4) { usage(); return 1; } if ((fp = CmpOpenFile(argv[1], &piped)) == NULL) { fprintf(stderr, "can't open text file %s\n", argv[1]); return 1; } awe_load_textinfo(&sfinfo, fp); CmpCloseFile(fp, piped); if ((fp = fopen(argv[2], "r")) == NULL) { fprintf(stderr, "can't open origianl file %s\n", argv[2]); return 1; } if ((fout = fopen(argv[3], "w")) == NULL) { fprintf(stderr, "can't open output file %s\n", argv[3]); return 1; } awe_save_soundfont(&sfinfo, fp, fout); fclose(fp); fclose(fout); /*awe_free_soundfont(&sfinfo);*/ return 0; }