catcodec-1.0.5/ 0000755 0001750 0001750 00000000000 11737071342 013511 5 ustar rubidium rubidium catcodec-1.0.5/docs/ 0000755 0001750 0001750 00000000000 11737071342 014441 5 ustar rubidium rubidium catcodec-1.0.5/docs/catcodec.1 0000644 0001750 0001750 00000006323 11435243464 016275 0 ustar rubidium rubidium .\" $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.txt 0000644 0001750 0001750 00000006647 11463326450 016453 0 ustar rubidium rubidium catcodec 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.bundle 0000644 0001750 0001750 00000011520 11737067374 016432 0 ustar rubidium rubidium # $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/COPYING 0000644 0001750 0001750 00000043254 11237652752 014561 0 ustar rubidium rubidium 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.sh 0000755 0001750 0001750 00000005325 11737070704 016404 0 ustar rubidium rubidium #!/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.txt 0000644 0001750 0001750 00000001672 11737070704 016210 0 ustar rubidium rubidium 1.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.bat 0000644 0001750 0001750 00000001337 11737067374 015134 0 ustar rubidium rubidium @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.msvc 0000644 0001750 0001750 00000003050 11737067374 016130 0 ustar rubidium rubidium # $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/Makefile 0000644 0001750 0001750 00000004030 11616570651 015151 0 ustar rubidium rubidium # $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/ 0000755 0001750 0001750 00000000000 11737071342 014300 5 ustar rubidium rubidium catcodec-1.0.5/src/io.hpp 0000644 0001750 0001750 00000010160 11435243464 015417 0 ustar rubidium rubidium /* $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.hpp 0000644 0001750 0001750 00000010026 11435243464 016272 0 ustar rubidium rubidium /* $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.h 0000644 0001750 0001750 00000003623 11737067374 015760 0 ustar rubidium rubidium /* $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.hpp 0000644 0001750 0001750 00000001746 11435243464 015616 0 ustar rubidium rubidium /* $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.cpp 0000644 0001750 0001750 00000010504 11435243464 015414 0 ustar rubidium rubidium /* $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.cpp 0000644 0001750 0001750 00000020174 11435243464 016272 0 ustar rubidium rubidium /* $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.cpp 0000644 0001750 0001750 00000015507 11737063647 016572 0 ustar rubidium rubidium /* $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.in 0000644 0001750 0001750 00000002036 11435243464 016207 0 ustar rubidium rubidium /* $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!!";