catcodec-1.0.5/0000755000175000017500000000000011737071342013511 5ustar rubidiumrubidiumcatcodec-1.0.5/docs/0000755000175000017500000000000011737071342014441 5ustar rubidiumrubidiumcatcodec-1.0.5/docs/catcodec.10000644000175000017500000000632311435243464016275 0ustar rubidiumrubidium.\" $Id: catcodec.1 20614 2010-08-25 16:39:16Z rubidium $ .\" catcodec is a tool to decode/encode the sample catalogue for OpenTTD. .\" Copyright (C) 2009 Remko Bijker .\" .\" This manual page is free software. It is distributed under the .\" terms of the GNU General Public License as published by the Free .\" Software Foundation; either version 2 of the License. .\" .\" This manual page 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 manual page; if not, write to the Free Software .\" Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 .\" USA .\" .Dd November 05, 2009 .Dt CATCODEC 1 .Sh NAME .Nm catcodec .Nd An open source tool to decode/encode the sample catalogue for OpenTTD .Sh SYNOPSIS .Nm .Op Fl d Ar sample_file .Op Fl e Ar sample_file .Sh DESCRIPTION catcodec decodes and encodes sample catalogues for OpenTTD. These sample catalogues are not much more than some meta-data (description and file name) and raw PCM data. .sp Decoding a sample catalogue, e.g. sample.cat, results in a sample.sfo that contains the file names and descriptions of the samples and all samples with the file name as specified in the catalogue. .sp Encoding a sample catalogue, e.g. sample.cat, reads sample.sfo for the file names and descriptions. It will then load the samples described in sample.sfo and encodes these into sample.cat. .sp Generally speaking encoding a file and then decoding it results in the same file. Decoding of the original, Transport Tycoon Deluxe, sample format will force the output to be 11025 Hz, 8 bits mono because the meta-data of some of the samples is incorrect or even missing. .sp Only PCM WAVE files with only the format and data chunks are supported. Any other formats need to be converted into this. Furthermore only 11025 Hz, 22050 Hz and 44100 Hz with 8 or 16 bits per sample single channel PCM WAVE files are supported. .sp .Sh OPTIONS .Bl -tag -width ".Fl d Ar sample_file" .It Fl d Ar sample_file Decode the given sample catalogue into its components. The .Ar sample_file must have the extension '.cat'. For the output meta-data file the '.cat' is replaced with '.sfo'. The actual samples, in PCM WAVE format, are extracted into files using the file names, including extension, as described in the catalogue or meta-data file. .sp If any of the files already exists a backup is made, by adding '.bak', overwriting the existing backup. .sp .It Fl e Ar sample_file Encode the components for the given sample file into a sample catalogue. The .Ar sample_file must have the extension '.cat'. For the input meta-data file the '.cat' is replaced with '.sfo'. The actual samples, in PCM WAVE format, are read from files using the file names, including extension, as described in the meta-data file. .sp If the .Ar sample_file already exists a backup is made, by adding '.bak', overwriting the existing backup. .sp .El .Sh SEE ALSO .Nm openttd Ns (1) the game that uses these sample catalogues. .sp .Sh AUTHORS .An Remko Bijker .Aq rubidium@openttd.org catcodec-1.0.5/docs/readme.txt0000644000175000017500000000664711463326450016453 0ustar rubidiumrubidiumcatcodec README Last updated: 2010-10-31 Release version: 1.0.3 ------------------------------------------------------------------------ Table of Contents: ------------------ 1) About 2) Contacting 3) Installing 4) Running 5) Compiling 1) About: -- ------ catcodec decodes and encodes sample catalogues for OpenTTD. These sample catalogues are not much more than some meta-data (description and file name) and raw PCM data. catcodec is licensed under the GNU General Public License version 2.0. For more information, see the file 'COPYING'. 2) Contact: -- -------- Contacting the author can be done in two ways: - sending an email to rubidium@openttd.org - chat with him on IRC; Rubidium can be found in #openttd on irc.oftc.net 3) Installation: -- ------------- Installing catcodec is fairly straightforward. Just copy the executable into any directory. It is advised to put the executable in one of the directories in your path so it can be easily found. For example when compiling OpenSFX. To uninstall simply remove the executable. 4) Usage: -- ------ Decoding a sample catalogue, e.g. sample.cat, results in a sample.sfo that contains the file names and descriptions of the samples and all samples with the file name as specified in the catalogue. Encoding a sample catalogue, e.g. sample.cat, reads sample.sfo for the file names and descriptions. It will then load the samples described in sample.sfo and encodes these into sample.cat. Generally speaking encoding a file and then decoding it results in the same file. Decoding of the original, Transport Tycoon Deluxe, sample format will force the output to be 11025 Hz, 8 bits mono because the meta-data of some of the samples is incorrect or even missing. Only PCM WAVE files with only the format and data chunks are supported. Any other formats need to be converted into this. Furthermore only 11025 Hz, 22050 Hz and 44100 Hz with 8 or 16 bits per sample single channel PCM WAVE files are supported. Options for catcodec are (mutually exclusive): -d sample_file Decode the given sample catalogue into its components. The sample_file must have the extension '.cat'. For the output meta-data file the '.cat' is replaced with '.sfo'. The actual samples, in PCM WAVE format, are extracted into files using the file names, including extension, as described in the catalogue or meta-data file. If any of the files already exists a backup is made, by adding '.bak', overwriting the existing backup. -e sample_file Encode the components for the given sample file into a sample catalogue. The sample_file must have the extension '.cat'. For the input meta-data file the '.cat' is replaced with '.sfo'. The actual samples, in PCM WAVE format, are read from files using the file names, including extension, as described in the meta-data file. If the sample_file already exists a backup is made, by adding '.bak', overwriting the existing backup. 5) Compiling: -- ---------- GCC/ICC: Just use "make", or on non-GNU systems "gmake". Microsoft Visual C++: There is no project file, but you can compile catcodec using this compiler by either running "make.bat" or "make -f Makefile.msvc". In both cases the compiler's executable "cl.exe" must be in the path. catcodec-1.0.5/Makefile.bundle0000644000175000017500000001152011737067374016432 0ustar rubidiumrubidium# $Id: Makefile.bundle 24091 2012-04-04 15:55:40Z rubidium $ # This file is part of catcodec. # catcodec 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, version 2. # catcodec 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 catcodec. If not, see . # # Creation of bundles # # Standard make convention variables/locations prefix ?= /usr/local exec_prefix ?= $(prefix) datarootdir ?= $(prefix)/share datadir ?= $(datarootdir) bindir ?= $(exec_prefix)/bin mandir ?= $(datarootdir)/man man1dir ?= $(mandir)/man1 docdir ?= $(datarootdir)/doc/$(PACKAGE_NAME) openttddir ?= $(datarootdir}/openttd openttdgmdir ?= $(openttddir)/gm/$(PACKAGE_NAME) openttddatadir ?= $(openttddir)/data/$(PACKAGE_NAME) # The revision is needed for the bundle name and creating an OSX application bundle. ifdef REVISION REV := $(REVISION) else # Detect the revision VERSIONS := $(shell AWK="$(AWK)" "./findversion.sh") REV := $(shell echo "$(VERSIONS)" | cut -f 1 -d' ') endif # Make sure we have something in REV ifeq ($(REV),) REV := norev000 endif ifndef BUNDLE_NAME BUNDLE_NAME = catcodec-custom-$(REV)-$(OS) endif bundle: all @echo '[BUNDLE] Constructing bundle' $(Q)rm -rf "$(BUNDLE_DIR)" $(Q)mkdir -p "$(BUNDLE_DIR)" $(Q)mkdir -p "$(BUNDLE_DIR)/docs" $(Q)mkdir -p "$(BUNDLE_DIR)/man" $(Q)cp "$(CATCODEC)" "$(BUNDLE_DIR)/" $(Q)cp "$(ROOT_DIR)/COPYING" "$(BUNDLE_DIR)/" $(Q)cp "$(ROOT_DIR)/changelog.txt" "$(BUNDLE_DIR)/" $(Q)cp "$(ROOT_DIR)/docs/readme.txt" "$(BUNDLE_DIR)/docs/" $(Q)cp "$(ROOT_DIR)/docs/catcodec.1" "$(BUNDLE_DIR)/man/" $(Q)gzip -9 "$(BUNDLE_DIR)/man/catcodec.1" ifeq ($(CATCODEC), catcodec.exe) $(Q)unix2dos "$(BUNDLE_DIR)/COPYING" $(Q)unix2dos "$(BUNDLE_DIR)/"*.txt endif install: bundle @echo '[INSTALL] Installing catcodec' $(Q)install -d "$(DESTDIR)$(bindir)" $(Q)install -m 755 "$(BUNDLE_DIR)/$(CATCODEC)" "$(DESTDIR)$(bindir)/" ifndef DO_NOT_INSTALL_DOCS $(_C)install -d "$(DESTDIR)$(docdir)" $(_C)install -m 644 "$(BUNDLE_DIR)/docs/"* "$(DESTDIR)$(docdir)" endif ifndef DO_NOT_INSTALL_CHANGELOG $(_C)install -d "$(DESTDIR)$(docdir)" $(_C)install -m 644 "$(BUNDLE_DIR)/changelog.txt" "$(DESTDIR)$(docdir)" endif ifndef DO_NOT_INSTALL_LICENSE $(_C)install -d "$(DESTDIR)$(docdir)" $(_C)install -m 644 "$(BUNDLE_DIR)/COPYING" "$(DESTDIR)$(docdir)" endif ifndef DO_NOT_INSTALL_MAN $(_C)install -d "$(DESTDIR)$(man1dir)" $(_C)install -m 644 "$(BUNDLE_DIR)/man/"*.1.gz "$(DESTDIR)$(man1dir)/" endif ### Packing the current bundle into several compressed file formats ### # # Zips & dmgs do not contain a root folder, i.e. they have files in the root of the zip/dmg. # gzip, bzip2 and lha archives have a root folder, with the same name as the bundle. # # One can supply a custom name by adding BUNDLE_NAME:= to the make command. # bundle_zip: bundle @echo '[BUNDLE] Creating $(BUNDLE_NAME).zip' $(Q)mkdir -p "$(BUNDLES_DIR)" $(Q)cd "$(BUNDLE_DIR)" && zip -r $(shell if test -z "$(VERBOSE)"; then echo '-q'; fi) "$(BUNDLES_DIR)/$(BUNDLE_NAME).zip" . bundle_gzip: bundle @echo '[BUNDLE] Creating $(BUNDLE_NAME).tar.gz' $(Q)mkdir -p "$(BUNDLES_DIR)/.gzip/$(BUNDLE_NAME)" $(Q)cp -R "$(BUNDLE_DIR)/"* "$(BUNDLES_DIR)/.gzip/$(BUNDLE_NAME)/" $(Q)cd "$(BUNDLES_DIR)/.gzip" && tar -zc$(shell if test -n "$(VERBOSE)"; then echo 'v'; fi)f "$(BUNDLES_DIR)/$(BUNDLE_NAME).tar.gz" "$(BUNDLE_NAME)" $(Q)rm -rf "$(BUNDLES_DIR)/.gzip" bundle_bzip2: bundle @echo '[BUNDLE] Creating $(BUNDLE_NAME).tar.bz2' $(Q)mkdir -p "$(BUNDLES_DIR)/.bzip2/$(BUNDLE_NAME)" $(Q)cp -R "$(BUNDLE_DIR)/"* "$(BUNDLES_DIR)/.bzip2/$(BUNDLE_NAME)/" $(Q)cd "$(BUNDLES_DIR)/.bzip2" && tar -jc$(shell if test -n "$(VERBOSE)"; then echo 'v'; fi)f "$(BUNDLES_DIR)/$(BUNDLE_NAME).tar.bz2" "$(BUNDLE_NAME)" $(Q)rm -rf "$(BUNDLES_DIR)/.bzip2" bundle_lha: bundle @echo '[BUNDLE] Creating $(BUNDLE_NAME).lha' $(Q)mkdir -p "$(BUNDLES_DIR)/.lha/$(BUNDLE_NAME)" $(Q)cp -R "$(BUNDLE_DIR)/"* "$(BUNDLES_DIR)/.lha/$(BUNDLE_NAME)/" $(Q)cd "$(BUNDLES_DIR)/.lha" && lha ao6 "$(BUNDLES_DIR)/$(BUNDLE_NAME).lha" "$(BUNDLE_NAME)" $(Q)rm -rf "$(BUNDLES_DIR)/.lha" bundle_dmg: bundle @echo '[BUNDLE] Creating $(BUNDLE_NAME).dmg' $(Q)mkdir -p "$(BUNDLES_DIR)/catcodec $(REV)" $(Q)cp -R "$(BUNDLE_DIR)/" "$(BUNDLES_DIR)/catcodec $(REV)" $(Q)hdiutil create -ov -format UDZO -srcfolder "$(BUNDLES_DIR)/catcodec $(REV)" "$(BUNDLES_DIR)/$(BUNDLE_NAME).dmg" $(Q)rm -fr "$(BUNDLES_DIR)/catcodec $(REV)" catcodec-1.0.5/COPYING0000644000175000017500000004325411237652752014561 0ustar rubidiumrubidium GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 Lesser General Public License instead of this License. catcodec-1.0.5/findversion.sh0000755000175000017500000000532511737070704016404 0ustar rubidiumrubidium#!/bin/sh # $Id: findversion.sh 24092 2012-04-04 16:07:32Z rubidium $ # This file is part of catcodec. # catcodec 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, version 2. # catcodec 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 catcodec. If not, see . # Arguments given? Show help text. if [ "$#" != "0" ]; then cat <\t\t\t REV a string describing what version of the code the current checkout is based on. The exact format of this string depends on the version control system in use, but it tries to identify the revision used as close as possible (using the svn revision number or hg/git hash). This also includes an indication of whether the checkout was modified and which branch was checked out. This value is not guaranteed to be sortable, but is mainly meant for identifying the revision and user display. If no revision identifier could be found, this is left empty. REV_NR the revision number of the svn revision this checkout is based on. This can be used to determine which functionality is present in this checkout. For trunk svn checkouts and hg/git branches based upon it, this number should be accurate. For svn branch checkouts, this number is mostly meaningless, at least when comparing with the REV_NR from other branches or trunk. This number should be sortable. Within a given branch or trunk, a higher number means a newer version. However, when using git or hg, this number will not increase on new commits. If no revision number could be found, this is left empty. MODIFIED Whether (the src directory of) this checkout is modified or not. A value of 0 means not modified, a value of 2 means it was modified. Modification is determined in relation to the commit identified by REV, so not in relation to the svn revision identified by REV_NR. A value of 1 means that the modified status is unknown, because this is not an svn/git/hg checkout for example. CLEAN_REV the same as REV but without branch name By setting the AWK environment variable, a caller can determine which version of "awk" is used. If nothing is set, this script defaults to "awk". EOF exit 1; fi VERSION="1.0.5" echo "$VERSION $VERSION 0 $VERSION" catcodec-1.0.5/changelog.txt0000644000175000017500000000167211737070704016210 0ustar rubidiumrubidium1.0.5 (2012-04-04) ------------------------------------------------------------------------ - Fix: compilation with GCC 4.7 - Fix: makefile for compilation with MSVC 1.0.4 (2011-08-04) ------------------------------------------------------------------------ - Change: add option for using Makefile.local 1.0.3 (2010-10-31) ------------------------------------------------------------------------ - Fix: Documentation got installed into the wrong directory 1.0.2 (2010-10-20) ------------------------------------------------------------------------ - Change: Sync installing options with GRFCodec and NFORenum to make packaging more unified for downstream 1.0.1 (2010-08-25) ------------------------------------------------------------------------ - Add: Support for "make install" with DESTDIR support like GRFCodec and NFORenum 1.0.0 (2009-12-18) ------------------------------------------------------------------------ - Add: Initial release catcodec-1.0.5/make.bat0000644000175000017500000000133711737067374015134 0ustar rubidiumrubidium@rem $Id: make.bat 24091 2012-04-04 15:55:40Z rubidium $ @rem This file is part of catcodec. @rem catcodec 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, version 2. @rem catcodec 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. @rem See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with catcodec. If not, see . cl /MT /Ot /W2 /RTC1 /EHsc /DWIN32 src/catcodec.cpp src/io.cpp src/sample.cpp src/rev.cpp catcodec-1.0.5/Makefile.msvc0000644000175000017500000000305011737067374016130 0ustar rubidiumrubidium# $Id: Makefile.msvc 24091 2012-04-04 15:55:40Z rubidium $ # This file is part of catcodec. # catcodec 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, version 2. # catcodec 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 catcodec. If not, see . # # Makefile for creating bundles of MSVC's binaries in the same way as we make # the zip bundles for ALL other OSes. # # Usage: make -f Makefile.msvc PLATFORM=[Win32|x64] BUNDLE_NAME=openttd--win[32|64] # or make -f Makefile.msvc PLATFORM=[Win32|x64] BUNDLE_NAME=OTTD-win[32|64]-nightly- # # Check if we want to show what we are doing ifdef VERBOSE Q = else Q = @ endif AWK = "awk" ROOT_DIR := $(shell pwd) BUNDLE_DIR = "$(ROOT_DIR)/bundle" BUNDLES_DIR = "$(ROOT_DIR)/bundles" CATCODEC = "catcodec.exe" OS = "windows" all: src/catcodec.cpp src/io.cpp src/sample.cpp src/rev.cpp cmd /c make.bat VERSION := $(shell ./findversion.sh | cut -f 1 -d' ') RES := $(shell if [ "`cat version.cache 2>/dev/null`" != "$(VERSION)" ]; then echo "$(VERSION)" > version.cache; fi ) src/rev.cpp: version.cache src/rev.cpp.in $(Q)cat src/rev.cpp.in | sed "s@\!\!VERSION\!\!@$(VERSION)@g" > src/rev.cpp include Makefile.bundle catcodec-1.0.5/Makefile0000644000175000017500000000403011616570651015151 0ustar rubidiumrubidium# $Id: Makefile 22718 2011-08-04 19:23:21Z rubidium $ # ========================================================= # Makefile for the catcodec program # # Don't put any local configuration in here # Change Makefile.local instead, it'll be # preserved when updating the sources # ========================================================= # # catcodec 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, version 2. # catcodec 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 catcodec. If not, see . ifdef VERBOSE Q = else Q = @ endif ROOT_DIR := $(shell pwd) PACKAGE_NAME = catcodec -include Makefile.local AWK ?= "awk" BUNDLE_DIR ?= "$(ROOT_DIR)/bundle" BUNDLES_DIR ?= "$(ROOT_DIR)/bundles" CATCODEC ?= catcodec$(EXTENSION) CXXFLAGS ?= -Wall -Wcast-qual -Wwrite-strings OS ?= unknown OBJS = catcodec.o io.o sample.o rev.o # Regardless of the warning settings, we really do not want these errors. CXXFLAGS += -Wno-multichar ifdef DEBUG CXXFLAGS += -g -ggdb endif all: $(CATCODEC) objs/%.o: src/%.cpp $(Q)mkdir -p objs @echo '[CPP] $@' $(Q)$(CXX) $(CXXFLAGS) -c -o $@ $< $(CATCODEC): $(OBJS:%=objs/%) @echo '[LINK] $@' $(Q)$(CXX) -o $@ $(CXXFLAGS) $(LDFLAGS) $^ VERSION := $(shell ./findversion.sh | cut -f 1 -d' ') RES := $(shell if [ "`cat version.cache 2>/dev/null`" != "$(VERSION)" ]; then echo "$(VERSION)" > version.cache; fi ) src/rev.cpp: version.cache src/rev.cpp.in $(Q)cat src/rev.cpp.in | sed "s@\!\!VERSION\!\!@$(VERSION)@g" > src/rev.cpp clean: @echo '[CLEAN]' $(Q)rm -f $(CATCODEC) rev.cpp version.cache $(Q)rm -rf objs mrproper: clean $(Q)rm -rf $(BUNDLE_DIR) $(BUNDLES_DIR) include Makefile.bundle catcodec-1.0.5/src/0000755000175000017500000000000011737071342014300 5ustar rubidiumrubidiumcatcodec-1.0.5/src/io.hpp0000644000175000017500000001016011435243464015417 0ustar rubidiumrubidium/* $Id: io.hpp 20614 2010-08-25 16:39:16Z rubidium $ */ /* * catcodec is a tool to decode/encode the sample catalogue for OpenTTD. * Copyright (C) 2009 Remko Bijker * * 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, version 2. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /** @file io.hpp Interface for reading/writing to files */ #ifndef IO_H #define IO_H /** A string is a string; simple as that */ typedef std::string string; /** * Simple class to perform binary and string reading from a file. */ class FileReader { FILE *file; ///< The file to be read by this instance string filename; ///< The filename of the file public: /** * Create a new reader for the given file. * @param filename the file to read from * @param binary read the file as binary or text? */ FileReader(string filename, bool binary = true); /** * Cleans up our mess */ ~FileReader(); /** * Read a single byte from the stream. * @return the read byte */ uint8_t ReadByte(); /** * Read a word (2 bytes) from the stream in little endian. * @return the read word */ uint16_t ReadWord(); /** * Read a dword (4 bytes) from the stream in little endian. * @return the read dword */ uint32_t ReadDword(); /** * Read a number of raw bytes from the stream. * @param in the buffer where to put the data * @param amount the amount of bytes to read */ void ReadRaw(uint8_t *in, size_t amount); /** * Read a line of text from the stream. * @param in the buffer where to put the data * @param length the maximum amount of bytes to read */ char *ReadLine(char *in, int length); /** * Go to a specific location in the stream. * @param pos the position to go to. */ void Seek(uint32_t pos); /** * Get the current position in the stream. * @return the position in the stream */ uint32_t GetPos(); /** * Get the filename of this file. * @return the filename */ string GetFilename() const; }; /** * Simple class to perform binary and string writing to a file. */ class FileWriter { FILE *file; ///< The file to be read by this instance string filename; ///< The filename of the file string filename_new; ///< The filename for the temporary file public: /** * Create a new writer for the given file. * @param filename the file to write to * @param binary write the file as binary or text? */ FileWriter(string filename, bool binary = true); /** * Cleans up our mess */ ~FileWriter(); /** * Write a single byte to the stream. * @param data the byte to write */ void WriteByte(uint8_t data); /** * Write a word (2 bytes) to the stream in little endian. * @param data the word to write */ void WriteWord(uint16_t data); /** * Write a dword (4 bytes) to the stream in little endian. * @param data the dword to write */ void WriteDword(uint32_t data); /** * Write a number of raw bytes to the stream. * @param out the buffer of data to write * @param amount the amount of bytes to write */ void WriteRaw(const uint8_t *out, size_t amount); /** * Write a line of text to the stream. * @param format the format of the written string * @param ... the data to actually write */ void WriteString(const char *format, ...); /** * Get the current position in the stream. * @return the position in the stream */ uint32_t GetPos(); /** * Get the filename of this file. * @return the filename */ string GetFilename() const; /** * Close the output, i.e. commit the file to disk. * If this is not done, the file with not be written to disk. */ void Close(); }; #endif /* IO_H */ catcodec-1.0.5/src/sample.hpp0000644000175000017500000001002611435243464016272 0ustar rubidiumrubidium/* $Id: sample.hpp 20614 2010-08-25 16:39:16Z rubidium $ */ /* * catcodec is a tool to decode/encode the sample catalogue for OpenTTD. * Copyright (C) 2009 Remko Bijker * * 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, version 2. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /** @file sample.hpp Interface for Sample reading/writing */ #ifndef SAMPLE_HPP #define SAMPLE_HPP #include #include "io.hpp" /** * Simple in-memory representation of a sample. */ class Sample { private: uint32_t offset; ///< Offset from the begin of the cat uint32_t size; ///< The size of the WAV RIFF, i.e. excluding name and filename string name; ///< The name of the sample string filename; ///< The filename of the sample uint16_t num_channels; ///< Number of channels; either 1 or 2 uint32_t sample_rate; ///< Sample rate; either 11025, 22050 or 44100 uint16_t bits_per_sample; ///< Number of bits per sample; either 8 or 16 uint32_t sample_size; ///< The size of the raw data below uint8_t *sample_data; ///< The actual raw sample data public: /** * Create a new sample by reading data from a file. * In this case the data comes from a cat file, so for now we only * read the offset and size from the file. * @param reader the file to read from */ Sample(FileReader &reader); /** * Creates a new sample by reading the sample from a given (wav) file. * @param filename the file to read the sample from * @param name the name of the sample */ Sample(string filename, string name); /** * Cleans up our mess. */ ~Sample(); /** * Reads a sample from a reader. * It reads WAV files (if that is the only thing in the file). * This function has some very strict tests on validity of the input file. * @param reader place to read the sample from * @param check_size whether to check that our size makes sense with the size from the sample */ void ReadSample(FileReader &reader, bool check_size = true); /** * Reads a cat entry from a reader. * This function has some very strict tests on validity of the input file. * @param reader place to read the cat entry from * @param new_format whether this is the old or new format; there are different strictness tests for both cases */ void ReadCatEntry(FileReader &reader, bool new_format); /** * Write a sample to a writer. If only a sample is written to the * file it would be a valid WAV file. * @param writer place to write the sample to */ void WriteSample(FileWriter &writer) const; /** * Write a cat entry to a writer. * @param writer place to write the cat entry to */ void WriteCatEntry(FileWriter &writer) const; /** * Get the name of the sample. * @return the name of the sample */ string GetName() const; /** * Get the filename of the sample * @return the filename of the sample */ string GetFilename() const; /** * Set the offset from the begin of the cat to this cat entry. * @param offset the offset. */ void SetOffset(uint32_t offset); /** * Get the offset for the cat entry that follows us. * @return the offset for the next cat entry */ uint32_t GetNextOffset() const; /** * Get the offset from the begin of the cat to this cat entry. * @return the offset */ uint32_t GetOffset() const; /** * Get the size of the WAV part of the file. * @return the size */ uint32_t GetSize() const; }; /** Lets have us a vector of samples */ typedef std::vector Samples; #endif /* SAMPLE_HPP */ catcodec-1.0.5/src/stdafx.h0000644000175000017500000000362311737067374015760 0ustar rubidiumrubidium/* $Id: stdafx.h 24091 2012-04-04 15:55:40Z rubidium $ */ /* * catcodec is a tool to decode/encode the sample catalogue for OpenTTD. * Copyright (C) 2009 Remko Bijker * * 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, version 2. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /** @file stdafx.h Definition of base types and functions in a cross-platform compatible way. */ #ifndef STDAFX_H #define STDAFX_H #include #include #include #include #include #include #include #if defined(_MSC_VER) typedef unsigned char uint8_t; typedef unsigned short uint16_t; typedef unsigned int uint32_t; #define UNUSED #define fileno _fileno #pragma warning(disable: 4996) // 'strdup' was declared deprecated #elif defined(__GNUC__) #include #define UNUSED __attribute__((unused)) #else #warning "Unknown compiler type, might not compile!" #include #define UNUSED #endif #if defined(WIN32) #include #define isatty _isatty #define unlink _unlink #else #include #endif #define assert_compile(expr) extern const int __ct_assert__[1 - 2 * !(expr)] UNUSED /* Check if the types have the bitsizes like we are using them */ assert_compile(sizeof(uint32_t) == 4); assert_compile(sizeof(uint16_t) == 2); assert_compile(sizeof(uint8_t) == 1); #endif /* STDAFX_H */ catcodec-1.0.5/src/rev.hpp0000644000175000017500000000174611435243464015616 0ustar rubidiumrubidium/* $Id: rev.hpp 20614 2010-08-25 16:39:16Z rubidium $ */ /* * catcodec is a tool to decode/encode the sample catalogue for OpenTTD. * Copyright (C) 2009 Remko Bijker * * 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, version 2. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /** @file rev.h declaration of catcodec revision dependant variables */ #ifndef REV_HPP #define REV_HPP extern const char _catcodec_version[]; #endif /* REV_HPP */ catcodec-1.0.5/src/io.cpp0000644000175000017500000001050411435243464015414 0ustar rubidiumrubidium/* $Id: io.cpp 20614 2010-08-25 16:39:16Z rubidium $ */ /* * catcodec is a tool to decode/encode the sample catalogue for OpenTTD. * Copyright (C) 2009 Remko Bijker * * 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, version 2. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /** @file io.cpp Implementation of reading/writing to files */ #include "stdafx.h" #include "io.hpp" FileReader::FileReader(string filename, bool binary) { this->file = fopen(filename.c_str(), binary ? "rb" : "r"); this->filename = filename; if (this->file == NULL) { throw "Could not open " + filename + " for reading"; } } FileReader::~FileReader() { fclose(this->file); } uint8_t FileReader::ReadByte() { uint8_t b; this->ReadRaw(&b, 1); return b; } uint16_t FileReader::ReadWord() { uint16_t b = this->ReadByte(); return (this->ReadByte() << 8) | b; } uint32_t FileReader::ReadDword() { uint32_t b = this->ReadWord(); return (this->ReadWord() << 16) | b; } void FileReader::ReadRaw(uint8_t *in, size_t amount) { if (fread(in, 1, amount, this->file) != amount) { throw "Unexpected end of " + this->filename; } } char *FileReader::ReadLine(char *in, int length) { char *ret = fgets(in, length, this->file); /* fgets doesn't guarantee string termination if no newline/EOF is found */ in[length - 1] = '\0'; return ret; } void FileReader::Seek(uint32_t pos) { if (fseek(this->file, pos, SEEK_SET) != 0) throw "Seeking in " + this->filename + " failed."; } uint32_t FileReader::GetPos() { return ftell(this->file); } string FileReader::GetFilename() const { return this->filename; } FileWriter::FileWriter(string filename, bool binary) { this->filename_new = filename + ".new"; this->filename = filename; this->file = fopen(filename_new.c_str(), binary ? "w+b" : "w+"); if (this->file == NULL) { throw "Could not open " + this->filename_new + " for writing"; } } FileWriter::~FileWriter() { if (this->file != NULL) { fclose(this->file); unlink(this->filename_new.c_str()); } } void FileWriter::WriteByte(uint8_t data) { this->WriteRaw(&data, 1); } void FileWriter::WriteWord(uint16_t data) { this->WriteByte(data & 0xFF); this->WriteByte(data >> 8); } void FileWriter::WriteDword(uint32_t data) { this->WriteWord(data & 0xFFFF); this->WriteWord(data >> 16); } void FileWriter::WriteRaw(const uint8_t *out, size_t amount) { assert(this->file != NULL); if (fwrite(out, 1, amount, this->file) != amount) { throw "Unexpected failure while writing to " + this->filename; } } void FileWriter::WriteString(const char *format, ...) { assert(this->file != NULL); va_list ap; va_start(ap, format); if (vfprintf(this->file, format, ap) < 0) { throw "Unexpected failure while writing to " + this->filename; } va_end(ap); } uint32_t FileWriter::GetPos() { assert(this->file != NULL); return ftell(this->file); } string FileWriter::GetFilename() const { return this->filename; } void FileWriter::Close() { /* First close the .new file */ fclose(this->file); this->file = NULL; /* Then remove the existing .bak file */ string filename_bak = this->filename + ".bak"; if (unlink(filename_bak.c_str()) != 0 && errno != ENOENT) { fprintf(stderr, "Warning: could not remove %s (%s)\n", filename_bak.c_str(), strerror(errno)); } /* Then move the existing file to .bak */ if (rename(this->filename.c_str(), filename_bak.c_str()) != 0 && errno != ENOENT) { fprintf(stderr, "Warning: could not rename %s to %s (%s)\n", this->filename.c_str(), filename_bak.c_str(), strerror(errno)); } /* And finally move the .new file to the actual wanted filename */ if (rename(this->filename_new.c_str(), this->filename.c_str()) != 0) { fprintf(stderr, "Warning: could not rename %s to %s (%s)\n", this->filename_new.c_str(), this->filename.c_str(), strerror(errno)); throw "Could not close " + this->filename; } } catcodec-1.0.5/src/sample.cpp0000644000175000017500000002017411435243464016272 0ustar rubidiumrubidium/* $Id: sample.cpp 20614 2010-08-25 16:39:16Z rubidium $ */ /* * catcodec is a tool to decode/encode the sample catalogue for OpenTTD. * Copyright (C) 2009 Remko Bijker * * 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, version 2. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /** * @file sample.cpp Implementation of Samples * * The format of .wav PCM encoded files is fairly simple. The "verbatim" * 'RIFF' etc. is written as is in the file. The numbers are always * written in the little endian way. *
    *
  • 'RIFF'
  • *
  • dword with number of bytes following
  • *
  • 'WAVE'
  • *
  • 'fmt '
  • *
  • dword with size of 'fmt ' chunk, always 16
  • *
  • word with audio format, always 1 (PCM)
  • *
  • word with number of channels, always 1
  • *
  • dword with sample rate, always 11025, 22050 or 44100
  • *
  • dword with byte rate, always sample rate * number of channels * bits per sample / 8
  • *
  • word with block alignment, always number of channels * bits per sample / 8
  • *
  • word with bits per sample, always 8 or 16
  • *
  • 'data'
  • *
  • dword with number of bytes following
  • *
  • actual raw PCM data
  • *
* * This makes the whole thing 44 bytes + the actual payload long. */ #include "stdafx.h" #include "sample.hpp" /** The size of the RIFF headers of a WAV file */ static const uint32_t RIFF_HEADER_SIZE = 44; /** * Read a string (byte length including termination, actual data) from a reader. * @param reader the reader to read from * @return the read string */ static string ReadString(FileReader &reader) { uint8_t name_len = reader.ReadByte(); char buffer[256]; reader.ReadRaw((uint8_t *)buffer, name_len); buffer[name_len - 1] = '\0'; return buffer; } /** * Write a string (byte length including termination, actual data) to a writer. * @param str the string to write * @param writer the writer to write to */ static void WriteString(const string str, FileWriter &writer) { uint8_t str_len = (uint8_t)(str.length() + 1); writer.WriteByte(str_len); writer.WriteRaw((const uint8_t *)str.c_str(), str_len); } Sample::Sample(FileReader &reader) : sample_data(NULL) { this->offset = reader.ReadDword() & 0x7FFFFFFF; this->size = reader.ReadDword(); } Sample::Sample(string filename, string name) : offset(0), name(name), filename(filename), sample_data(NULL) { FileReader sample_reader(filename); this->ReadSample(sample_reader, false); } Sample::~Sample() { free(this->sample_data); } void Sample::ReadSample(FileReader &reader, bool check_size) { assert(this->sample_data == NULL); if (reader.ReadDword() != 'FFIR') throw "Unexpected chunk; expected \"RIFF\" in " + reader.GetFilename(); if (check_size) { if (reader.ReadDword() + 8 != size ) throw "Unexpected RIFF chunk size in " + reader.GetFilename(); } else { this->size = reader.ReadDword() + 8; } if (reader.ReadDword() != 'EVAW') throw "Unexpected format; expected \"WAVE\" in " + reader.GetFilename(); if (reader.ReadDword() != ' tmf') throw "Unexpected format; expected \"fmt \" in " + reader.GetFilename(); if (reader.ReadDword() != 16 ) throw "Unexpected fmt chunk size in " + reader.GetFilename(); if (reader.ReadWord() != 1 ) throw "Unexpected audio format; expected \"PCM\" in " + reader.GetFilename(); this->num_channels = reader.ReadWord(); if (this->num_channels != 1) throw "Unexpected number of audio channels; expected 1 in " + reader.GetFilename(); this->sample_rate = reader.ReadDword(); if (this->sample_rate != 11025 && this->sample_rate != 22050 && this->sample_rate != 44100) throw "Unexpected same rate; expected 11025, 22050 or 44100 in " + reader.GetFilename(); /* Read these and validate them later on. * Saving them is unnecesary as they can be easily calucated. */ uint32_t byte_rate = reader.ReadDword(); uint16_t block_align = reader.ReadWord(); this->bits_per_sample = reader.ReadWord(); if (this->bits_per_sample != 8 && this->bits_per_sample != 16) throw "Unexpected number of bits per channel; expected 8 or 16 in " + reader.GetFilename(); if (byte_rate != this->sample_rate * this->num_channels * this->bits_per_sample / 8) throw "Unexpected byte rate in " + reader.GetFilename(); if (block_align != this->num_channels * this->bits_per_sample / 8) throw "Unexpected block align in " + reader.GetFilename(); if (reader.ReadDword() != 'atad') throw "Unexpected chunk; expected \"data\" in " + reader.GetFilename(); /* Sometimes the files are padded, which causes them to start at the * wrong offset further on, so just read whatever amount of data was * specified in the top RIFF as long as sample size is within those * boundaries, i.e. within the RIFF. */ this->sample_size = reader.ReadDword(); if (this->sample_size + RIFF_HEADER_SIZE > size) throw "Unexpected data chunk size in " + reader.GetFilename(); this->sample_data = (uint8_t *)malloc(this->size - RIFF_HEADER_SIZE); reader.ReadRaw(this->sample_data, this->size - RIFF_HEADER_SIZE); } void Sample::ReadCatEntry(FileReader &reader, bool new_format) { assert(this->sample_data == NULL); if (reader.GetPos() != this->GetOffset()) throw "Invalid offset in file " + reader.GetFilename(); this->name = ReadString(reader); if (!new_format && this->GetName().compare("Corrupt sound") == 0) { /* In the old format there was one sample that was raw PCM. */ this->sample_size = this->size; this->sample_data = (uint8_t *)malloc(this->sample_size); reader.ReadRaw(this->sample_data, this->sample_size); this->size += RIFF_HEADER_SIZE; } else { this->ReadSample(reader); } if (!new_format) { /* The old format had sometimes the wrong values for e.g. * sample rate which made the playback too fast. */ this->num_channels = 1; this->sample_rate = 11025; this->bits_per_sample = 8; } /* Some kind of data byte, unused */ reader.ReadByte(); this->filename = ReadString(reader); } void Sample::WriteSample(FileWriter &writer) const { assert(this->sample_data != NULL); writer.WriteDword('FFIR'); writer.WriteDword(this->size - 8); writer.WriteDword('EVAW'); writer.WriteDword(' tmf'); writer.WriteDword(16); writer.WriteWord(1); writer.WriteWord(this->num_channels); writer.WriteDword(this->sample_rate); writer.WriteDword(this->sample_rate * this->num_channels * this->bits_per_sample / 8); writer.WriteWord(this->num_channels * this->bits_per_sample / 8); writer.WriteWord(this->bits_per_sample); writer.WriteDword('atad'); writer.WriteDword(this->sample_size); writer.WriteRaw(this->sample_data, this->size - RIFF_HEADER_SIZE); } void Sample::WriteCatEntry(FileWriter &writer) const { assert(this->sample_data != NULL); if (writer.GetPos() != this->GetOffset()) throw "Invalid offset when writing file " + writer.GetFilename(); WriteString(this->GetName(), writer); this->WriteSample(writer); /* Some kind of separator byte */ writer.WriteByte(0); WriteString(this->GetFilename(), writer); } string Sample::GetName() const { return this->name; } string Sample::GetFilename() const { return this->filename; } void Sample::SetOffset(uint32_t offset) { assert(this->offset == 0); this->offset = offset; } uint32_t Sample::GetNextOffset() const { return this->offset + 1 + // length of the name (this->name.length() + 1) + // the name + '\0' this->size + // size of the data 1 + // the delimiter 1 + // length of the filename (this->filename.length() + 1); // the filename + '\0' } uint32_t Sample::GetOffset() const { return this->offset; } uint32_t Sample::GetSize() const { return this->size; } catcodec-1.0.5/src/catcodec.cpp0000644000175000017500000001550711737063647016572 0ustar rubidiumrubidium/* $Id: catcodec.cpp 24090 2012-04-04 15:24:23Z rubidium $ */ /* * catcodec is a tool to decode/encode the sample catalogue for OpenTTD. * Copyright (C) 2009 Remko Bijker * * 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, version 2. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /** @file catcodec.cpp Encoding and decoding of "cat" files */ #include "stdafx.h" #include "io.hpp" #include "sample.hpp" #include "rev.hpp" /** Are we run interactively, i.e. from the console, or from a script? */ static bool _interactive; /** Show progress, but only on interactive consoles */ static void ShowProgress() { if (!_interactive) return; printf("."); fflush(stdin); } /** * Read a cat file from a reader and extract it's samples. * @param samples collection to put our samples in * @param reader reader for the file */ static void ReadCat(Samples &samples, FileReader &reader) { uint32_t count = reader.ReadDword(); bool new_format = (count >> 31) != 0; count &= 0x7FFFFFFFU; count /= 8; reader.Seek(0); for (uint32_t i = 0; i < count; i++) { samples.push_back(new Sample(reader)); } for (Samples::iterator iter = samples.begin(); iter != samples.end(); iter++) { (*iter)->ReadCatEntry(reader, new_format); ShowProgress(); } } /** * Write a cat file (including the samples) to a cat file * @param samples collection samples to write to the cat file * @param writer writer for the file */ static void WriteCat(Samples &samples, FileWriter &writer) { uint32_t offset = (uint32_t)samples.size() * 8; for (Samples::iterator iter = samples.begin(); iter != samples.end(); iter++) { Sample *sample = *iter; sample->SetOffset(offset); offset = sample->GetNextOffset(); writer.WriteDword(sample->GetOffset() | (1U << 31)); writer.WriteDword(sample->GetSize()); } for (Samples::iterator iter = samples.begin(); iter != samples.end(); iter++) { (*iter)->WriteCatEntry(writer); ShowProgress(); } } /** * Read a sfo file from a reader and and the samples mentioned in there * @param samples collection to put our samples in * @param reader reader for the sfo file */ static void ReadSFO(Samples &samples, FileReader &reader) { /* Temporary read buffer; 512 is long enough for all valid * lines because the filename and name may be at most 255. * Add a single space separator and the terminator and you * got exactly 512. */ char buffer[512] = ""; char *filename; while (reader.ReadLine(buffer, sizeof(buffer)) != NULL) { /* Line with comment */ if (strncmp(buffer, "//", 2) == 0) continue; char *name; if (*buffer == '"') { filename = buffer + 1; name = strchr(filename, '"'); } else { filename = buffer; name = strchr(filename, ' '); } if (name == NULL) { throw "Invalid format for " + reader.GetFilename() + " at [" + buffer + "]"; } *name = '\0'; name++; while (isspace(*name)) name++; char *newline = name + strlen(name) - 1; while (isspace(*newline)) { *newline = '\0'; newline--; } if (strlen(filename) + 1 > 255) throw "Filename is too long in " + reader.GetFilename() + " at [" + buffer + "]"; if (strlen(name) + 1 > 255) throw "Name is too long in " + reader.GetFilename() + " at [" + name + "]"; samples.push_back(new Sample(filename, name)); ShowProgress(); } } /** * Write a sfo file and the samples to disk * @param samples collection samples to write to the sfo file and disk * @param writer writer for the sfo file */ static void WriteSFO(Samples &samples, FileWriter &writer) { writer.WriteString("// \"file name\" internal name\n"); for (Samples::iterator iter = samples.begin(); iter != samples.end(); iter++) { Sample *sample = *iter; writer.WriteString("\"%s\" %s\n", sample->GetFilename().c_str(), sample->GetName().c_str()); FileWriter sample_writer(sample->GetFilename()); sample->WriteSample(sample_writer); sample_writer.Close(); ShowProgress(); } } /** * Show the help to the user. * @param cmd the command line the user used */ void ShowHelp(const char *cmd) { printf( "catcodec version %s - Copyright 2009 by Remko Bijker\n" "Usage:\n" " %s -d \n" " Decode all samples in the sample file and put them in this directory\n" " %s -e \n" " Encode all samples in this directory and put them in the sample file\n" "\n" " denotes the .cat file you want to work on, e.g. sample.cat\n" "\n" "catcodec is Copyright 2009 by Remko Bijker\n" "You may copy and redistribute it under the terms of the GNU General Public\n" "License version 2, as stated in the file 'COPYING'\n", _catcodec_version, cmd, cmd ); } /** * Oh hello, the user has found the way in :) * @param argc the number of arguments + 1 * @param argv list with given arguments */ int main(int argc, char *argv[]) { int ret = 0; Samples samples; _interactive = isatty(fileno(stdout)) == 1; try { if (argc != 3 || (strcmp(argv[1], "-d") != 0 && strcmp(argv[1], "-e") != 0)) { ShowHelp(argv[0]); return 0; } char sfo_file[1024]; strncpy(sfo_file, argv[2], sizeof(sfo_file)); char *ext = strrchr(sfo_file, '.'); if (ext == NULL || strlen(ext) != 4 || strcmp(ext, ".cat") != 0) { throw string("Unexpected extension; expected \".cat\""); } strcpy(ext, ".sfo"); if (strcmp(argv[1], "-d") == 0) { /* Decode the file, so read the cat and then write the sfo */ if (_interactive) printf("Reading %s\n", argv[2]); FileReader reader(argv[2]); ReadCat(samples, reader); if (_interactive) printf("\nWriting %s\n", sfo_file); FileWriter sfo_writer(sfo_file, false); WriteSFO(samples, sfo_writer); sfo_writer.Close(); } else if (strcmp(argv[1], "-e") == 0) { /* Encode the file, so read the sfo and then write the cat */ if (_interactive) printf("Reading %s\n", sfo_file); FileReader sfo_reader(sfo_file, false); ReadSFO(samples, sfo_reader); if (_interactive) printf("\nWriting %s\n", argv[2]); FileWriter cat_writer(argv[2]); WriteCat(samples, cat_writer); cat_writer.Close(); } else { /* Some invalid second param -> show the help */ ShowHelp(argv[0]); return -1; } if (_interactive) printf("\nDone\n"); } catch (string s) { fprintf(stderr, "An error occured: %s\n", s.c_str()); ret = -1; } /* Clear up the samples */ while (samples.size() != 0) { delete samples.back(); samples.pop_back(); } return ret; } catcodec-1.0.5/src/rev.cpp.in0000644000175000017500000000203611435243464016207 0ustar rubidiumrubidium/* $Id: rev.cpp.in 20614 2010-08-25 16:39:16Z rubidium $ */ /* * catcodec is a tool to decode/encode the sample catalogue for OpenTTD. * Copyright (C) 2009 Remko Bijker * * 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, version 2. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /** @file rev.cpp Autogenerated file with the revision and such of OpenTTD. */ #include "stdafx.h" #include "rev.hpp" /** * The text version of catcodec's revision. */ const char _catcodec_version[] = "!!VERSION!!";