imported sources
This commit is contained in:
340
COPYING
Normal file
340
COPYING
Normal file
@@ -0,0 +1,340 @@
|
|||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 2, June 1991
|
||||||
|
|
||||||
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||||
|
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your
|
||||||
|
freedom to share and change it. By contrast, the GNU General Public
|
||||||
|
License is intended to guarantee your freedom to share and change free
|
||||||
|
software--to make sure the software is free for all its users. This
|
||||||
|
General Public License applies to most of the Free Software
|
||||||
|
Foundation's software and to any other program whose authors commit to
|
||||||
|
using it. (Some other Free Software Foundation software is covered by
|
||||||
|
the GNU Library General Public License instead.) You can apply it to
|
||||||
|
your programs, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
this service if you wish), that you receive source code or can get it
|
||||||
|
if you want it, that you can change the software or use pieces of it
|
||||||
|
in new free programs; and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
anyone to deny you these rights or to ask you to surrender the rights.
|
||||||
|
These restrictions translate to certain responsibilities for you if you
|
||||||
|
distribute copies of the software, or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether
|
||||||
|
gratis or for a fee, you must give the recipients all the rights that
|
||||||
|
you have. You must make sure that they, too, receive or can get the
|
||||||
|
source code. And you must show them these terms so they know their
|
||||||
|
rights.
|
||||||
|
|
||||||
|
We protect your rights with two steps: (1) copyright the software, and
|
||||||
|
(2) offer you this license which gives you legal permission to copy,
|
||||||
|
distribute and/or modify the software.
|
||||||
|
|
||||||
|
Also, for each author's protection and ours, we want to make certain
|
||||||
|
that everyone understands that there is no warranty for this free
|
||||||
|
software. If the software is modified by someone else and passed on, we
|
||||||
|
want its recipients to know that what they have is not the original, so
|
||||||
|
that any problems introduced by others will not reflect on the original
|
||||||
|
authors' reputations.
|
||||||
|
|
||||||
|
Finally, any free program is threatened constantly by software
|
||||||
|
patents. We wish to avoid the danger that redistributors of a free
|
||||||
|
program will individually obtain patent licenses, in effect making the
|
||||||
|
program proprietary. To prevent this, we have made it clear that any
|
||||||
|
patent must be licensed for everyone's free use or not licensed at all.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License applies to any program or other work which contains
|
||||||
|
a notice placed by the copyright holder saying it may be distributed
|
||||||
|
under the terms of this General Public License. The "Program", below,
|
||||||
|
refers to any such program or work, and a "work based on the Program"
|
||||||
|
means either the Program or any derivative work under copyright law:
|
||||||
|
that is to say, a work containing the Program or a portion of it,
|
||||||
|
either verbatim or with modifications and/or translated into another
|
||||||
|
language. (Hereinafter, translation is included without limitation in
|
||||||
|
the term "modification".) Each licensee is addressed as "you".
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of
|
||||||
|
running the Program is not restricted, and the output from the Program
|
||||||
|
is covered only if its contents constitute a work based on the
|
||||||
|
Program (independent of having been made by running the Program).
|
||||||
|
Whether that is true depends on what the Program does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Program's
|
||||||
|
source code as you receive it, in any medium, provided that you
|
||||||
|
conspicuously and appropriately publish on each copy an appropriate
|
||||||
|
copyright notice and disclaimer of warranty; keep intact all the
|
||||||
|
notices that refer to this License and to the absence of any warranty;
|
||||||
|
and give any other recipients of the Program a copy of this License
|
||||||
|
along with the Program.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy, and
|
||||||
|
you may at your option offer warranty protection in exchange for a fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Program or any portion
|
||||||
|
of it, thus forming a work based on the Program, and copy and
|
||||||
|
distribute such modifications or work under the terms of Section 1
|
||||||
|
above, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) You must cause the modified files to carry prominent notices
|
||||||
|
stating that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
b) You must cause any work that you distribute or publish, that in
|
||||||
|
whole or in part contains or is derived from the Program or any
|
||||||
|
part thereof, to be licensed as a whole at no charge to all third
|
||||||
|
parties under the terms of this License.
|
||||||
|
|
||||||
|
c) If the modified program normally reads commands interactively
|
||||||
|
when run, you must cause it, when started running for such
|
||||||
|
interactive use in the most ordinary way, to print or display an
|
||||||
|
announcement including an appropriate copyright notice and a
|
||||||
|
notice that there is no warranty (or else, saying that you provide
|
||||||
|
a warranty) and that users may redistribute the program under
|
||||||
|
these conditions, and telling the user how to view a copy of this
|
||||||
|
License. (Exception: if the Program itself is interactive but
|
||||||
|
does not normally print such an announcement, your work based on
|
||||||
|
the Program is not required to print an announcement.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Program,
|
||||||
|
and can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based
|
||||||
|
on the Program, the distribution of the whole must be on the terms of
|
||||||
|
this License, whose permissions for other licensees extend to the
|
||||||
|
entire whole, and thus to each and every part regardless of who wrote it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Program.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Program
|
||||||
|
with the Program (or with a work based on the Program) on a volume of
|
||||||
|
a storage or distribution medium does not bring the other work under
|
||||||
|
the scope of this License.
|
||||||
|
|
||||||
|
3. You may copy and distribute the Program (or a work based on it,
|
||||||
|
under Section 2) in object code or executable form under the terms of
|
||||||
|
Sections 1 and 2 above provided that you also do one of the following:
|
||||||
|
|
||||||
|
a) Accompany it with the complete corresponding machine-readable
|
||||||
|
source code, which must be distributed under the terms of Sections
|
||||||
|
1 and 2 above on a medium customarily used for software interchange; or,
|
||||||
|
|
||||||
|
b) Accompany it with a written offer, valid for at least three
|
||||||
|
years, to give any third party, for a charge no more than your
|
||||||
|
cost of physically performing source distribution, a complete
|
||||||
|
machine-readable copy of the corresponding source code, to be
|
||||||
|
distributed under the terms of Sections 1 and 2 above on a medium
|
||||||
|
customarily used for software interchange; or,
|
||||||
|
|
||||||
|
c) Accompany it with the information you received as to the offer
|
||||||
|
to distribute corresponding source code. (This alternative is
|
||||||
|
allowed only for noncommercial distribution and only if you
|
||||||
|
received the program in object code or executable form with such
|
||||||
|
an offer, in accord with Subsection b above.)
|
||||||
|
|
||||||
|
The source code for a work means the preferred form of the work for
|
||||||
|
making modifications to it. For an executable work, complete source
|
||||||
|
code means all the source code for all modules it contains, plus any
|
||||||
|
associated interface definition files, plus the scripts used to
|
||||||
|
control compilation and installation of the executable. However, as a
|
||||||
|
special exception, the source code distributed need not include
|
||||||
|
anything that is normally distributed (in either source or binary
|
||||||
|
form) with the major components (compiler, kernel, and so on) of the
|
||||||
|
operating system on which the executable runs, unless that component
|
||||||
|
itself accompanies the executable.
|
||||||
|
|
||||||
|
If distribution of executable or object code is made by offering
|
||||||
|
access to copy from a designated place, then offering equivalent
|
||||||
|
access to copy the source code from the same place counts as
|
||||||
|
distribution of the source code, even though third parties are not
|
||||||
|
compelled to copy the source along with the object code.
|
||||||
|
|
||||||
|
4. You may not copy, modify, sublicense, or distribute the Program
|
||||||
|
except as expressly provided under this License. Any attempt
|
||||||
|
otherwise to copy, modify, sublicense or distribute the Program is
|
||||||
|
void, and will automatically terminate your rights under this License.
|
||||||
|
However, parties who have received copies, or rights, from you under
|
||||||
|
this License will not have their licenses terminated so long as such
|
||||||
|
parties remain in full compliance.
|
||||||
|
|
||||||
|
5. You are not required to accept this License, since you have not
|
||||||
|
signed it. However, nothing else grants you permission to modify or
|
||||||
|
distribute the Program or its derivative works. These actions are
|
||||||
|
prohibited by law if you do not accept this License. Therefore, by
|
||||||
|
modifying or distributing the Program (or any work based on the
|
||||||
|
Program), you indicate your acceptance of this License to do so, and
|
||||||
|
all its terms and conditions for copying, distributing or modifying
|
||||||
|
the Program or works based on it.
|
||||||
|
|
||||||
|
6. Each time you redistribute the Program (or any work based on the
|
||||||
|
Program), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute or modify the Program subject to
|
||||||
|
these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted herein.
|
||||||
|
You are not responsible for enforcing compliance by third parties to
|
||||||
|
this License.
|
||||||
|
|
||||||
|
7. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Program at all. For example, if a patent
|
||||||
|
license would not permit royalty-free redistribution of the Program by
|
||||||
|
all those who receive copies directly or indirectly through you, then
|
||||||
|
the only way you could satisfy both it and this License would be to
|
||||||
|
refrain entirely from distribution of the Program.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under
|
||||||
|
any particular circumstance, the balance of the section is intended to
|
||||||
|
apply and the section as a whole is intended to apply in other
|
||||||
|
circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system, which is
|
||||||
|
implemented by public license practices. Many people have made
|
||||||
|
generous contributions to the wide range of software distributed
|
||||||
|
through that system in reliance on consistent application of that
|
||||||
|
system; it is up to the author/donor to decide if he or she is willing
|
||||||
|
to distribute software through any other system and a licensee cannot
|
||||||
|
impose that choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
8. If the distribution and/or use of the Program is restricted in
|
||||||
|
certain countries either by patents or by copyrighted interfaces, the
|
||||||
|
original copyright holder who places the Program under this License
|
||||||
|
may add an explicit geographical distribution limitation excluding
|
||||||
|
those countries, so that distribution is permitted only in or among
|
||||||
|
countries not thus excluded. In such case, this License incorporates
|
||||||
|
the limitation as if written in the body of this License.
|
||||||
|
|
||||||
|
9. The Free Software Foundation may publish revised and/or new versions
|
||||||
|
of the General Public License from time to time. Such new versions will
|
||||||
|
be similar in spirit to the present version, but may differ in detail to
|
||||||
|
address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Program
|
||||||
|
specifies a version number of this License which applies to it and "any
|
||||||
|
later version", you have the option of following the terms and conditions
|
||||||
|
either of that version or of any later version published by the Free
|
||||||
|
Software Foundation. If the Program does not specify a version number of
|
||||||
|
this License, you may choose any version ever published by the Free Software
|
||||||
|
Foundation.
|
||||||
|
|
||||||
|
10. If you wish to incorporate parts of the Program into other free
|
||||||
|
programs whose distribution conditions are different, write to the author
|
||||||
|
to ask for permission. For software which is copyrighted by the Free
|
||||||
|
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||||
|
make exceptions for this. Our decision will be guided by the two goals
|
||||||
|
of preserving the free status of all derivatives of our free software and
|
||||||
|
of promoting the sharing and reuse of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||||
|
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||||
|
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||||
|
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||||
|
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||||
|
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||||
|
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||||
|
REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||||
|
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||||
|
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||||
|
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||||
|
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||||
|
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If the program is interactive, make it output a short notice like this
|
||||||
|
when it starts in an interactive mode:
|
||||||
|
|
||||||
|
Gnomovision version 69, Copyright (C) year name of author
|
||||||
|
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
|
This is free software, and you are welcome to redistribute it
|
||||||
|
under certain conditions; type `show c' for details.
|
||||||
|
|
||||||
|
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||||
|
parts of the General Public License. Of course, the commands you use may
|
||||||
|
be called something other than `show w' and `show c'; they could even be
|
||||||
|
mouse-clicks or menu items--whatever suits your program.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||||
|
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||||
|
|
||||||
|
<signature of Ty Coon>, 1 April 1989
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
|
||||||
|
This General Public License does not permit incorporating your program into
|
||||||
|
proprietary programs. If your program is a subroutine library, you may
|
||||||
|
consider it more useful to permit linking proprietary applications with the
|
||||||
|
library. If this is what you want to do, use the GNU Library General
|
||||||
|
Public License instead of this License.
|
||||||
6
Makefile
Normal file
6
Makefile
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
SUBDIRS= lib tools man
|
||||||
|
|
||||||
|
all install uninstall clean:
|
||||||
|
for dir in $(SUBDIRS) ; do \
|
||||||
|
(cd $$dir && $(MAKE) $@) ; \
|
||||||
|
done
|
||||||
22
README
Normal file
22
README
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
cuetools README
|
||||||
|
cuetools is a set of utilites for working with cue and toc files.
|
||||||
|
|
||||||
|
RELEASE NOTES
|
||||||
|
* cuetools-1.x is a significant code rewrite of 0.x. The cue/toc parsing code
|
||||||
|
has been reimplimented in lex/yacc.
|
||||||
|
* cuerename has been replaced by the more general utility cueprint.
|
||||||
|
* Usage syntax of the utilites has changed. See the respective man pages.
|
||||||
|
|
||||||
|
INSTALL
|
||||||
|
Building requires GNU Make. Run `make install' to install cuetools into the
|
||||||
|
default location of /usr/local. The Makefiles also support both the prefix and
|
||||||
|
DESTDIR variables.
|
||||||
|
|
||||||
|
AUTHOR
|
||||||
|
Svend Sorensen <ssorensen@freeshell.org>
|
||||||
|
|
||||||
|
SEE ALSO
|
||||||
|
cuetools website - http://cuetools.sourceforge.net
|
||||||
|
Cdrdao website - http://cdrdao.sourceforge.net
|
||||||
|
cdrdao(1) man page - description of toc file format
|
||||||
|
shntool website - http://www.etree.org/shnutils/shntool/
|
||||||
44
lib/Makefile
Normal file
44
lib/Makefile
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
YFLAGS+= -d
|
||||||
|
|
||||||
|
OBJS= cd.o cdtext.o time.o cuefile.o
|
||||||
|
CUE_OBJS= cue_parse.o cue_scan.o cue_print.o
|
||||||
|
TOC_OBJS= toc_parse.o toc_scan.o toc_print.o
|
||||||
|
|
||||||
|
toc_scan.c: LFLAGS+= -Ptoc_yy
|
||||||
|
cue_scan.c: LFLAGS+= -Pcue_yy
|
||||||
|
toc_parse.c: YFLAGS+= -p toc_yy
|
||||||
|
cue_parse.c: YFLAGS+= -p cue_yy
|
||||||
|
|
||||||
|
TARGETS= libcuefile.a
|
||||||
|
|
||||||
|
all: $(TARGETS)
|
||||||
|
|
||||||
|
libcuefile.a: libcuefile.a($(OBJS) $(CUE_OBJS) $(TOC_OBJS))
|
||||||
|
|
||||||
|
%.c: %.y
|
||||||
|
$(YACC) -o $@ $(YFLAGS) $<
|
||||||
|
|
||||||
|
install: all
|
||||||
|
|
||||||
|
uninstall:
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(TARGETS)
|
||||||
|
rm -f *.o *.a *.core *.output
|
||||||
|
rm -f toc_scan.c toc_parse.c toc_parse.h
|
||||||
|
rm -f cue_scan.c cue_parse.c cue_parse.h
|
||||||
|
|
||||||
|
# dependancies
|
||||||
|
# generated with `gcc -MM *.c'
|
||||||
|
# after building lex and yacc .c files
|
||||||
|
|
||||||
|
cd.o: cd.c cd.h cdtext.h
|
||||||
|
cdtext.o: cdtext.c cdtext.h
|
||||||
|
cuefile.o: cuefile.c cuefile.h cd.h cdtext.h cue.h toc.h
|
||||||
|
cue_parse.o: cue_parse.c cd.h cdtext.h time.h
|
||||||
|
cue_print.o: cue_print.c cd.h cdtext.h time.h
|
||||||
|
cue_scan.o: cue_scan.c cd.h cdtext.h cue_parse.h
|
||||||
|
time.o: time.c
|
||||||
|
toc_parse.o: toc_parse.c cd.h cdtext.h time.h
|
||||||
|
toc_print.o: toc_print.c cd.h cdtext.h time.h
|
||||||
|
toc_scan.o: toc_scan.c cd.h cdtext.h toc_parse.h
|
||||||
329
lib/cd.c
Normal file
329
lib/cd.c
Normal file
@@ -0,0 +1,329 @@
|
|||||||
|
/*
|
||||||
|
* cd.c -- cd functions
|
||||||
|
*
|
||||||
|
* Copyright (C) 2004 Svend Sorensen <sorensen@freeshell.org>
|
||||||
|
* For license terms, see the file COPYING in this distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "cd.h"
|
||||||
|
|
||||||
|
typedef struct Data Data;
|
||||||
|
struct Data {
|
||||||
|
int type; /* DataType */
|
||||||
|
char *name; /* data source name */
|
||||||
|
long start; /* start time for data */
|
||||||
|
long length; /* length of data */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Track {
|
||||||
|
Data zero_pre; /* pre-gap generated with zero data */
|
||||||
|
Data file; /* track data file */
|
||||||
|
Data zero_post; /* post-gap generated with zero data */
|
||||||
|
int mode; /* track mode */
|
||||||
|
int sub_mode; /* sub-channel mode */
|
||||||
|
int flags; /* flags */
|
||||||
|
char *isrc; /* IRSC Code (5.22.4) 12 bytes */
|
||||||
|
Cdtext *cdtext; /* CD-TEXT */
|
||||||
|
int nindex; /* number of indexes */
|
||||||
|
long index[MAXINDEX]; /* indexes (in frames) (5.29.2.5)
|
||||||
|
* relative to start of track
|
||||||
|
* index[0] should always be zero */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Cd {
|
||||||
|
int mode; /* disc mode */
|
||||||
|
char *catalog; /* Media Catalog Number (5.22.3) */
|
||||||
|
Cdtext *cdtext; /* CD-TEXT */
|
||||||
|
int ntrack; /* number of tracks in album */
|
||||||
|
Track *track[MAXTRACK]; /* array of tracks */
|
||||||
|
};
|
||||||
|
|
||||||
|
Cd *cd_init ()
|
||||||
|
{
|
||||||
|
Cd *cd = NULL;
|
||||||
|
cd = malloc(sizeof(Cd));
|
||||||
|
|
||||||
|
if(NULL == cd) {
|
||||||
|
fprintf(stderr, "unable to create cd\n");
|
||||||
|
} else {
|
||||||
|
cd->mode = MODE_CD_DA;
|
||||||
|
cd->catalog = NULL;
|
||||||
|
cd->cdtext = cdtext_init();
|
||||||
|
cd->ntrack = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cd;
|
||||||
|
}
|
||||||
|
|
||||||
|
Track *track_init ()
|
||||||
|
{
|
||||||
|
Track *track = NULL;
|
||||||
|
track = malloc(sizeof(Track));
|
||||||
|
|
||||||
|
if (NULL == track) {
|
||||||
|
fprintf(stderr, "unable to create track\n");
|
||||||
|
} else {
|
||||||
|
track->zero_pre.type = DATA_ZERO;
|
||||||
|
track->zero_pre.name = NULL;
|
||||||
|
track->zero_pre.start = 0;
|
||||||
|
track->zero_pre.length = 0;
|
||||||
|
|
||||||
|
track->file.type = DATA_AUDIO;
|
||||||
|
track->file.name = NULL;
|
||||||
|
track->file.start = 0;
|
||||||
|
track->file.length = 0;
|
||||||
|
|
||||||
|
track->zero_post.type = DATA_ZERO;
|
||||||
|
track->zero_post.name = NULL;
|
||||||
|
track->zero_post.start = 0;
|
||||||
|
track->zero_post.length = 0;
|
||||||
|
|
||||||
|
track->mode = MODE_AUDIO;
|
||||||
|
track->sub_mode = SUB_MODE_RW;
|
||||||
|
track->flags = FLAG_NONE;
|
||||||
|
track->isrc = NULL;
|
||||||
|
track->cdtext = cdtext_init();
|
||||||
|
track->nindex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return track;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* cd structure functions
|
||||||
|
*/
|
||||||
|
void cd_set_mode (Cd *cd, int mode)
|
||||||
|
{
|
||||||
|
cd->mode = mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cd_get_mode (Cd *cd)
|
||||||
|
{
|
||||||
|
return cd->mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cd_set_catalog (Cd *cd, char *catalog)
|
||||||
|
{
|
||||||
|
if (cd->catalog)
|
||||||
|
free(cd->catalog);
|
||||||
|
|
||||||
|
cd->catalog = strdup(catalog);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *cd_get_catalog (Cd *cd)
|
||||||
|
{
|
||||||
|
return cd->catalog;
|
||||||
|
}
|
||||||
|
|
||||||
|
Cdtext *cd_get_cdtext (Cd *cd)
|
||||||
|
{
|
||||||
|
return cd->cdtext;
|
||||||
|
}
|
||||||
|
|
||||||
|
Track *cd_add_track (Cd *cd)
|
||||||
|
{
|
||||||
|
if (MAXTRACK - 1 > cd->ntrack)
|
||||||
|
cd->ntrack++;
|
||||||
|
else
|
||||||
|
fprintf(stderr, "too many tracks\n");
|
||||||
|
|
||||||
|
/* this will reinit last track if there were too many */
|
||||||
|
cd->track[cd->ntrack - 1] = track_init();
|
||||||
|
|
||||||
|
return cd->track[cd->ntrack - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int cd_get_ntrack (Cd *cd)
|
||||||
|
{
|
||||||
|
return cd->ntrack;
|
||||||
|
}
|
||||||
|
|
||||||
|
Track *cd_get_track (Cd *cd, int i)
|
||||||
|
{
|
||||||
|
if (0 < i <= cd->ntrack)
|
||||||
|
return cd->track[i - 1];
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* track structure functions
|
||||||
|
*/
|
||||||
|
|
||||||
|
void track_set_filename (Track *track, char *filename)
|
||||||
|
{
|
||||||
|
if (track->file.name)
|
||||||
|
free(track->file.name);
|
||||||
|
|
||||||
|
track->file.name = strdup(filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *track_get_filename (Track *track)
|
||||||
|
{
|
||||||
|
return track->file.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
void track_set_start (Track *track, long start)
|
||||||
|
{
|
||||||
|
track->file.start = start;
|
||||||
|
}
|
||||||
|
|
||||||
|
long track_get_start (Track *track)
|
||||||
|
{
|
||||||
|
return track->file.start;
|
||||||
|
}
|
||||||
|
|
||||||
|
void track_set_length (Track *track, long length)
|
||||||
|
{
|
||||||
|
track->file.length = length;
|
||||||
|
}
|
||||||
|
|
||||||
|
long track_get_length (Track *track)
|
||||||
|
{
|
||||||
|
return track->file.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
void track_set_mode (Track *track, int mode)
|
||||||
|
{
|
||||||
|
track->mode = mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
int track_get_mode (Track *track)
|
||||||
|
{
|
||||||
|
return track->mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
void track_set_sub_mode (Track *track, int sub_mode)
|
||||||
|
{
|
||||||
|
track->sub_mode = sub_mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
int track_get_sub_mode (Track *track)
|
||||||
|
{
|
||||||
|
return track->sub_mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
void track_set_flag (Track *track, int flag)
|
||||||
|
{
|
||||||
|
track->flags |= flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
void track_clear_flag (Track *track, int flag)
|
||||||
|
{
|
||||||
|
track->flags &= ~flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
int track_is_set_flag (Track *track, int flag)
|
||||||
|
{
|
||||||
|
return track->flags & flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
void track_set_zero_pre (Track *track, long length)
|
||||||
|
{
|
||||||
|
track->zero_pre.length = length;
|
||||||
|
}
|
||||||
|
|
||||||
|
long track_get_zero_pre (Track *track)
|
||||||
|
{
|
||||||
|
return track->zero_pre.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
void track_set_zero_post (Track *track, long length)
|
||||||
|
{
|
||||||
|
track->zero_post.length = length;
|
||||||
|
}
|
||||||
|
|
||||||
|
long track_get_zero_post (Track *track)
|
||||||
|
{
|
||||||
|
return track->zero_post.length;
|
||||||
|
}
|
||||||
|
void track_set_isrc (Track *track, char *isrc)
|
||||||
|
{
|
||||||
|
if (track->isrc)
|
||||||
|
free(track->isrc);
|
||||||
|
|
||||||
|
track->isrc = strdup(isrc);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *track_get_isrc (Track *track)
|
||||||
|
{
|
||||||
|
return track->isrc;
|
||||||
|
}
|
||||||
|
|
||||||
|
Cdtext *track_get_cdtext (Track *track)
|
||||||
|
{
|
||||||
|
return track->cdtext;
|
||||||
|
}
|
||||||
|
|
||||||
|
void track_add_index (Track *track, long index)
|
||||||
|
{
|
||||||
|
if (MAXTRACK - 1 > track->nindex)
|
||||||
|
track->nindex++;
|
||||||
|
else
|
||||||
|
fprintf(stderr, "too many indexes\n");
|
||||||
|
|
||||||
|
/* this will overwrite last index if there were too many */
|
||||||
|
track->index[track->nindex - 1] = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
int track_get_nindex (Track *track)
|
||||||
|
{
|
||||||
|
return track->nindex;
|
||||||
|
}
|
||||||
|
|
||||||
|
long track_get_index (Track *track, int i)
|
||||||
|
{
|
||||||
|
if (0 <= i < track->nindex)
|
||||||
|
return track->index[i];
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* dump cd information
|
||||||
|
*/
|
||||||
|
void cd_track_dump (Track *track)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
printf("zero_pre: %ld\n", track->zero_pre.length);
|
||||||
|
printf("filename: %s\n", track->file.name);
|
||||||
|
printf("start: %ld\n", track->file.start);
|
||||||
|
printf("length: %ld\n", track->file.length);
|
||||||
|
printf("zero_post: %ld\n", track->zero_post.length);
|
||||||
|
printf("mode: %d\n", track->mode);
|
||||||
|
printf("sub_mode: %d\n", track->sub_mode);
|
||||||
|
printf("flags: 0x%x\n", track->flags);
|
||||||
|
printf("isrc: %s\n", track->isrc);
|
||||||
|
printf("indexes: %d\n", track->nindex);
|
||||||
|
|
||||||
|
for (i = 0; i < track->nindex; ++i)
|
||||||
|
printf("index %d: %ld\n", i, track->index[i]);
|
||||||
|
|
||||||
|
if (NULL != track->cdtext) {
|
||||||
|
printf("cdtext:\n");
|
||||||
|
/* cdtext_print(stdout, track->cdtext); */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cd_dump (Cd *cd)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
printf("Disc Info\n");
|
||||||
|
printf("mode: %d\n", cd->mode);
|
||||||
|
printf("catalog: %s\n", cd->catalog);
|
||||||
|
if (NULL != cd->cdtext) {
|
||||||
|
printf("cdtext:\n");
|
||||||
|
/* cdtext_print(stdout, cd->cdtext); */
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < cd->ntrack; ++i) {
|
||||||
|
printf("Track %d Info\n", i + 1);
|
||||||
|
cd_track_dump(cd->track[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
147
lib/cd.h
Normal file
147
lib/cd.h
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
/*
|
||||||
|
* cd.h -- cd structure
|
||||||
|
*
|
||||||
|
* Copyright (C) 2004 Svend Sorensen <sorensen@freeshell.org>
|
||||||
|
* For license terms, see the file COPYING in this distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* references: MMC-3 draft revsion - 10g */
|
||||||
|
|
||||||
|
#ifndef CD_H
|
||||||
|
#define CD_H
|
||||||
|
|
||||||
|
#include "cdtext.h"
|
||||||
|
|
||||||
|
#define MAXTRACK 99 /* Red Book track limit */
|
||||||
|
#define MAXINDEX 99 /* Red Book index limit */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* disc modes
|
||||||
|
* DATA FORM OF MAIN DATA (5.29.2.8)
|
||||||
|
*/
|
||||||
|
enum DiscMode {
|
||||||
|
MODE_CD_DA, /* CD-DA */
|
||||||
|
MODE_CD_ROM, /* CD-ROM mode 1 */
|
||||||
|
MODE_CD_ROM_XA /* CD-ROM XA and CD-I */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* track modes
|
||||||
|
* 5.29.2.8 DATA FORM OF MAIN DATA
|
||||||
|
* Table 350 - Data Block Type Codes
|
||||||
|
*/
|
||||||
|
enum TrackMode {
|
||||||
|
MODE_AUDIO, /* 2352 byte block length */
|
||||||
|
MODE_MODE1, /* 2048 byte block length */
|
||||||
|
MODE_MODE1_RAW, /* 2352 byte block length */
|
||||||
|
MODE_MODE2, /* 2336 byte block length */
|
||||||
|
MODE_MODE2_FORM1, /* 2048 byte block length */
|
||||||
|
MODE_MODE2_FORM2, /* 2324 byte block length */
|
||||||
|
MODE_MODE2_FORM_MIX, /* 2332 byte block length */
|
||||||
|
MODE_MODE2_RAW /* 2352 byte block length */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* sub-channel mode
|
||||||
|
* 5.29.2.13 Data Form of Sub-channel
|
||||||
|
* NOTE: not sure if this applies to cue files
|
||||||
|
*/
|
||||||
|
enum TrackSubMode {
|
||||||
|
SUB_MODE_RW, /* RAW Data */
|
||||||
|
SUB_MODE_RW_RAW /* PACK DATA (written R-W */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* track flags
|
||||||
|
* Q Sub-channel Control Field (4.2.3.3, 5.29.2.2)
|
||||||
|
*/
|
||||||
|
enum TrackFlag {
|
||||||
|
FLAG_NONE =0x00, /* no flags set */
|
||||||
|
FLAG_PRE_EMPHASIS =0x01, /* audio recorded with pre-emphasis */
|
||||||
|
FLAG_COPY_PERMITTED =0x02, /* digital copy permitted */
|
||||||
|
FLAG_DATA =0x04, /* data track */
|
||||||
|
FLAG_FOUR_CHANNEL =0x08, /* 4 audio channels */
|
||||||
|
FLAG_SCMS =0x10, /* SCMS (not Q Sub-ch.) (5.29.2.7) */
|
||||||
|
FLAG_ANY =0xff /* any flags set */
|
||||||
|
};
|
||||||
|
|
||||||
|
enum DataType {
|
||||||
|
DATA_AUDIO,
|
||||||
|
DATA_DATA,
|
||||||
|
DATA_FIFO,
|
||||||
|
DATA_ZERO
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct Cd Cd;
|
||||||
|
typedef struct Track Track;
|
||||||
|
|
||||||
|
Cd *cd_init ();
|
||||||
|
void cd_dump (Cd *cd);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Cd functions
|
||||||
|
*/
|
||||||
|
|
||||||
|
void cd_set_mode (Cd *cd, int mode);
|
||||||
|
int cd_get_mode (Cd *cd);
|
||||||
|
|
||||||
|
void cd_set_catalog (Cd *cd, char *catalog);
|
||||||
|
char *cd_get_catalog (Cd *cd);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* return pointer to cd's Cdtext
|
||||||
|
*/
|
||||||
|
Cdtext *cd_get_cdtext (Cd *cd);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* add a new track to cd, increment number of tracks
|
||||||
|
* and return pointer to new track
|
||||||
|
*/
|
||||||
|
Track *cd_add_track (Cd *cd);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* return number of tracks in cd
|
||||||
|
*/
|
||||||
|
int cd_get_ntrack (Cd *cd);
|
||||||
|
|
||||||
|
Track *cd_get_track (Cd *cd, int i);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Track functions
|
||||||
|
*/
|
||||||
|
|
||||||
|
void track_set_filename (Track *track, char *filename);
|
||||||
|
char *track_get_filename (Track *track);
|
||||||
|
|
||||||
|
void track_set_start (Track *track, long start);
|
||||||
|
long track_get_start (Track *track);
|
||||||
|
|
||||||
|
void track_set_length (Track *track, long length);
|
||||||
|
long track_get_length (Track *track);
|
||||||
|
|
||||||
|
void track_set_mode (Track *track, int mode);
|
||||||
|
int track_get_mode (Track *track);
|
||||||
|
|
||||||
|
void track_set_sub_mode (Track *track, int sub_mode);
|
||||||
|
int track_get_sub_mode (Track *track);
|
||||||
|
|
||||||
|
void track_set_flag (Track *track, int flag);
|
||||||
|
void track_clear_flag (Track *track, int flag);
|
||||||
|
int track_is_set_flag (Track *track, int flag);
|
||||||
|
|
||||||
|
void track_set_zero_pre (Track *track, long length);
|
||||||
|
long track_get_zero_pre (Track *track);
|
||||||
|
|
||||||
|
void track_set_zero_post (Track *track, long length);
|
||||||
|
long track_get_zero_post (Track *track);
|
||||||
|
|
||||||
|
void track_set_isrc (Track *track, char *isrc);
|
||||||
|
char *track_get_isrc (Track *track);
|
||||||
|
|
||||||
|
Cdtext *track_get_cdtext (Track *track);
|
||||||
|
|
||||||
|
void track_add_index (Track *track, long index);
|
||||||
|
int track_get_nindex (Track *track);
|
||||||
|
long track_get_index (Track *track, int i);
|
||||||
|
|
||||||
|
#endif
|
||||||
153
lib/cdtext.c
Normal file
153
lib/cdtext.c
Normal file
@@ -0,0 +1,153 @@
|
|||||||
|
/*
|
||||||
|
* cdtext.c -- cdtext data structure and functions
|
||||||
|
*
|
||||||
|
* Copyright (C) 2004 Svend Sorensen <sorensen@freeshell.org>
|
||||||
|
* For license terms, see the file COPYING in this distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "cdtext.h"
|
||||||
|
|
||||||
|
struct Cdtext {
|
||||||
|
int pti;
|
||||||
|
int format;
|
||||||
|
char *value;
|
||||||
|
};
|
||||||
|
|
||||||
|
Cdtext *cdtext_init ()
|
||||||
|
{
|
||||||
|
Cdtext *new_cdtext = NULL;
|
||||||
|
|
||||||
|
Cdtext cdtext[] = {
|
||||||
|
{PTI_TITLE, FORMAT_CHAR, NULL},
|
||||||
|
{PTI_PERFORMER, FORMAT_CHAR, NULL},
|
||||||
|
{PTI_SONGWRITER, FORMAT_CHAR, NULL},
|
||||||
|
{PTI_COMPOSER, FORMAT_CHAR, NULL},
|
||||||
|
{PTI_ARRANGER, FORMAT_CHAR, NULL},
|
||||||
|
{PTI_MESSAGE, FORMAT_CHAR, NULL},
|
||||||
|
{PTI_DISC_ID, FORMAT_BINARY, NULL},
|
||||||
|
{PTI_GENRE, FORMAT_BINARY, NULL},
|
||||||
|
{PTI_TOC_INFO1, FORMAT_BINARY, NULL},
|
||||||
|
{PTI_TOC_INFO2, FORMAT_BINARY, NULL},
|
||||||
|
{PTI_RESERVED1, FORMAT_CHAR, NULL},
|
||||||
|
{PTI_RESERVED2, FORMAT_CHAR, NULL},
|
||||||
|
{PTI_RESERVED3, FORMAT_CHAR, NULL},
|
||||||
|
{PTI_RESERVED4, FORMAT_CHAR, NULL},
|
||||||
|
{PTI_UPC_ISRC, FORMAT_CHAR, NULL},
|
||||||
|
{PTI_SIZE_INFO, FORMAT_BINARY, NULL},
|
||||||
|
{PTI_END, FORMAT_CHAR, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
new_cdtext = (Cdtext *) calloc (sizeof (cdtext) / sizeof (Cdtext), sizeof (Cdtext));
|
||||||
|
if (NULL == new_cdtext)
|
||||||
|
fprintf (stderr, "problem allocating memory\n");
|
||||||
|
else
|
||||||
|
memcpy (new_cdtext, cdtext, sizeof(cdtext));
|
||||||
|
|
||||||
|
return new_cdtext;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cdtext_delete (Cdtext *cdtext)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (NULL != cdtext) {
|
||||||
|
for (i = 0; PTI_END != cdtext[i].pti; i++)
|
||||||
|
free (cdtext[i].value);
|
||||||
|
free (cdtext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* return 0 if there is no cdtext, returns non-zero otherwise */
|
||||||
|
int cdtext_is_empty (Cdtext *cdtext)
|
||||||
|
{
|
||||||
|
for (; PTI_END != cdtext->pti; cdtext++)
|
||||||
|
if (NULL != cdtext->value)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* sets cdtext's pti entry to field */
|
||||||
|
void cdtext_set (int pti, char *value, Cdtext *cdtext)
|
||||||
|
{
|
||||||
|
if (NULL != value) /* don't pass NULL to strdup */
|
||||||
|
for (; PTI_END != cdtext->pti; cdtext++)
|
||||||
|
if (pti == cdtext->pti) {
|
||||||
|
free (cdtext->value);
|
||||||
|
cdtext->value = strdup (value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* returns value for pti, NULL if pti is not found */
|
||||||
|
char *cdtext_get (int pti, Cdtext *cdtext)
|
||||||
|
{
|
||||||
|
for (; PTI_END != cdtext->pti; cdtext++)
|
||||||
|
if (pti == cdtext->pti)
|
||||||
|
return cdtext->value;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *cdtext_get_key (int pti, int istrack)
|
||||||
|
{
|
||||||
|
char *key = NULL;
|
||||||
|
|
||||||
|
switch (pti) {
|
||||||
|
case PTI_TITLE:
|
||||||
|
key = "TITLE";
|
||||||
|
break;
|
||||||
|
case PTI_PERFORMER:
|
||||||
|
key = "PERFORMER";
|
||||||
|
break;
|
||||||
|
case PTI_SONGWRITER:
|
||||||
|
key = "SONGWRITER";
|
||||||
|
break;
|
||||||
|
case PTI_COMPOSER:
|
||||||
|
key = "COMPOSER";
|
||||||
|
break;
|
||||||
|
case PTI_ARRANGER:
|
||||||
|
key = "ARRANGER";
|
||||||
|
break;
|
||||||
|
case PTI_MESSAGE:
|
||||||
|
key = "MESSAGE";
|
||||||
|
break;
|
||||||
|
case PTI_DISC_ID:
|
||||||
|
key = "DISC_ID";
|
||||||
|
break;
|
||||||
|
case PTI_GENRE:
|
||||||
|
key = "GENRE";
|
||||||
|
break;
|
||||||
|
case PTI_TOC_INFO1:
|
||||||
|
key = "TOC_INFO1";
|
||||||
|
break;
|
||||||
|
case PTI_TOC_INFO2:
|
||||||
|
key = "TOC_INFO1";
|
||||||
|
break;
|
||||||
|
case PTI_RESERVED1:
|
||||||
|
/* reserved */
|
||||||
|
break;
|
||||||
|
case PTI_RESERVED2:
|
||||||
|
/* reserved */
|
||||||
|
break;
|
||||||
|
case PTI_RESERVED3:
|
||||||
|
/* reserved */
|
||||||
|
break;
|
||||||
|
case PTI_RESERVED4:
|
||||||
|
/* reserved */
|
||||||
|
break;
|
||||||
|
case PTI_UPC_ISRC:
|
||||||
|
if (0 == istrack)
|
||||||
|
key = "UPC_EAN";
|
||||||
|
else
|
||||||
|
key = "ISRC";
|
||||||
|
break;
|
||||||
|
case PTI_SIZE_INFO:
|
||||||
|
key = "SIZE_INFO";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return key;
|
||||||
|
}
|
||||||
65
lib/cdtext.h
Normal file
65
lib/cdtext.h
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* cdtext.h
|
||||||
|
*
|
||||||
|
* Copyright (C) 2004 Svend Sorensen <sorensen@freeshell.org>
|
||||||
|
* For license terms, see the file COPYING in this distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* references: MMC-3 draft revsion - 10g */
|
||||||
|
|
||||||
|
#ifndef CDTEXT_H
|
||||||
|
#define CDTEXT_H
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
/* cdtext pack type indicators */
|
||||||
|
enum Pti {
|
||||||
|
PTI_TITLE, /* title of album or track titles */
|
||||||
|
PTI_PERFORMER, /* name(s) of the performer(s) */
|
||||||
|
PTI_SONGWRITER, /* name(s) of the songwriter(s) */
|
||||||
|
PTI_COMPOSER, /* name(s) of the composer(s) */
|
||||||
|
PTI_ARRANGER, /* name(s) of the arranger(s) */
|
||||||
|
PTI_MESSAGE, /* message(s) from the content provider and/or artist */
|
||||||
|
PTI_DISC_ID, /* (binary) disc identification information */
|
||||||
|
PTI_GENRE, /* (binary) genre identification and genre information */
|
||||||
|
PTI_TOC_INFO1, /* (binary) table of contents information */
|
||||||
|
PTI_TOC_INFO2, /* (binary) second table of contents information */
|
||||||
|
PTI_RESERVED1, /* reserved */
|
||||||
|
PTI_RESERVED2, /* reserved */
|
||||||
|
PTI_RESERVED3, /* reserved */
|
||||||
|
PTI_RESERVED4, /* reserved for content provider only */
|
||||||
|
PTI_UPC_ISRC, /* UPC/EAN code of the album and ISRC code of each track */
|
||||||
|
PTI_SIZE_INFO, /* (binary) size information of the block */
|
||||||
|
PTI_END /* terminating PTI (for stepping through PTIs) */
|
||||||
|
};
|
||||||
|
|
||||||
|
enum PtiFormat {
|
||||||
|
FORMAT_CHAR, /* single or double byte character string */
|
||||||
|
FORMAT_BINARY /* binary data */
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct Cdtext Cdtext;
|
||||||
|
|
||||||
|
/* return a pointer to a new Cdtext */
|
||||||
|
Cdtext *cdtext_init ();
|
||||||
|
|
||||||
|
/* release a Cdtext */
|
||||||
|
void cdtext_delete (Cdtext *cdtext);
|
||||||
|
|
||||||
|
/* returns non-zero if there are no CD-TEXT fields set, zero otherwise */
|
||||||
|
int cdtext_is_empty (Cdtext *cdtext);
|
||||||
|
|
||||||
|
/* set CD-TEXT field to value for PTI pti */
|
||||||
|
void cdtext_set (int pti, char *value, Cdtext *cdtext);
|
||||||
|
|
||||||
|
/* returns pointer to CD-TEXT value for PTI pti */
|
||||||
|
char *cdtext_get (int pti, Cdtext *cdtext);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* returns appropriate string for PTI pti
|
||||||
|
* if istrack is zero, UPC/EAN string will be returned for PTI_UPC_ISRC
|
||||||
|
* othwise ISRC string will be returned
|
||||||
|
*/
|
||||||
|
const char *cdtext_get_key (int pti, int istrack);
|
||||||
|
|
||||||
|
#endif
|
||||||
6
lib/cue.h
Normal file
6
lib/cue.h
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
/*
|
||||||
|
* cue.h -- cue function declarations
|
||||||
|
*/
|
||||||
|
|
||||||
|
Cd *cue_parse (FILE *fp);
|
||||||
|
void cue_print (FILE *fp, Cd *cd);
|
||||||
277
lib/cue_parse.y
Normal file
277
lib/cue_parse.y
Normal file
@@ -0,0 +1,277 @@
|
|||||||
|
%{
|
||||||
|
/*
|
||||||
|
* cue_parse.y -- parser for cue files
|
||||||
|
*
|
||||||
|
* Copyright (C) 2004 Svend Sorensen <sorensen@freeshell.org>
|
||||||
|
* For license terms, see the file COPYING in this distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "cd.h"
|
||||||
|
#include "time.h"
|
||||||
|
|
||||||
|
#define YYDEBUG 1
|
||||||
|
|
||||||
|
extern int cue_yylex();
|
||||||
|
void yyerror (char *s);
|
||||||
|
|
||||||
|
static Cd *cd = NULL;
|
||||||
|
static Track *track = NULL;
|
||||||
|
static Track *prev_track = NULL;
|
||||||
|
static Cdtext *cdtext = NULL;
|
||||||
|
static char *prev_filename = NULL; /* last file in or before last track */
|
||||||
|
static char *cur_filename = NULL; /* last file in the last track */
|
||||||
|
static char *new_filename = NULL; /* last file in this track */
|
||||||
|
%}
|
||||||
|
|
||||||
|
%start cuefile
|
||||||
|
|
||||||
|
%union {
|
||||||
|
long ival;
|
||||||
|
char *sval;
|
||||||
|
}
|
||||||
|
|
||||||
|
%token <ival> NUMBER
|
||||||
|
%token <sval> STRING
|
||||||
|
|
||||||
|
/* global (header) */
|
||||||
|
%token CATALOG
|
||||||
|
|
||||||
|
%token FFILE
|
||||||
|
%token BINARY
|
||||||
|
%token MOTOROLA
|
||||||
|
%token AIFF
|
||||||
|
%token WAVE
|
||||||
|
%token MP3
|
||||||
|
|
||||||
|
/* track */
|
||||||
|
%token TRACK
|
||||||
|
|
||||||
|
%token <ival> AUDIO
|
||||||
|
%token <ival> MODE1_2048
|
||||||
|
%token <ival> MODE1_2352
|
||||||
|
%token <ival> MODE2_2336
|
||||||
|
%token <ival> MODE2_2048
|
||||||
|
%token <ival> MODE2_2342
|
||||||
|
%token <ival> MODE2_2332
|
||||||
|
%token <ival> MODE2_2352
|
||||||
|
|
||||||
|
/* ISRC is with CD_TEXT */
|
||||||
|
%token TRACK_ISRC
|
||||||
|
|
||||||
|
%token FLAGS
|
||||||
|
%token <ival> PRE
|
||||||
|
%token <ival> DCP
|
||||||
|
%token <ival> FOUR_CH
|
||||||
|
%token <ival> SCMS
|
||||||
|
|
||||||
|
%token PREGAP
|
||||||
|
%token INDEX
|
||||||
|
%token POSTGAP
|
||||||
|
|
||||||
|
/* CD-TEXT */
|
||||||
|
%token <ival> TITLE
|
||||||
|
%token <ival> PERFORMER
|
||||||
|
%token <ival> SONGWRITER
|
||||||
|
%token <ival> COMPOSER
|
||||||
|
%token <ival> ARRANGER
|
||||||
|
%token <ival> MESSAGE
|
||||||
|
%token <ival> DISC_ID
|
||||||
|
%token <ival> GENRE
|
||||||
|
%token <ival> TOC_INFO1
|
||||||
|
%token <ival> TOC_INFO2
|
||||||
|
%token <ival> UPC_EAN
|
||||||
|
%token <ival> ISRC
|
||||||
|
%token <ival> SIZE_INFO
|
||||||
|
|
||||||
|
%type <ival> track_mode
|
||||||
|
%type <ival> track_flag
|
||||||
|
%type <ival> time
|
||||||
|
%type <ival> cdtext_item
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
cuefile
|
||||||
|
: new_cd global_statements track_list
|
||||||
|
;
|
||||||
|
|
||||||
|
new_cd
|
||||||
|
: /* empty */ {
|
||||||
|
cd = cd_init();
|
||||||
|
cdtext = cd_get_cdtext(cd);
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
global_statements
|
||||||
|
: /* empty */
|
||||||
|
| global_statements global_statement
|
||||||
|
;
|
||||||
|
|
||||||
|
global_statement
|
||||||
|
: CATALOG STRING '\n' { cd_set_catalog(cd, $2); }
|
||||||
|
| cdtext
|
||||||
|
| track_data
|
||||||
|
| error '\n'
|
||||||
|
;
|
||||||
|
|
||||||
|
track_data
|
||||||
|
: FFILE STRING file_format '\n' {
|
||||||
|
if (NULL != new_filename) {
|
||||||
|
yyerror("too many files specified\n");
|
||||||
|
free(new_filename);
|
||||||
|
}
|
||||||
|
new_filename = strdup($2);
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
track_list
|
||||||
|
: track
|
||||||
|
| track_list track
|
||||||
|
;
|
||||||
|
|
||||||
|
track
|
||||||
|
: new_track track_def track_statements
|
||||||
|
;
|
||||||
|
|
||||||
|
file_format
|
||||||
|
: BINARY
|
||||||
|
| MOTOROLA
|
||||||
|
| AIFF
|
||||||
|
| WAVE
|
||||||
|
| MP3
|
||||||
|
;
|
||||||
|
|
||||||
|
new_track
|
||||||
|
: /*empty */ {
|
||||||
|
/* save previous track, to later set length */
|
||||||
|
prev_track = track;
|
||||||
|
|
||||||
|
track = cd_add_track(cd);
|
||||||
|
cdtext = track_get_cdtext(track);
|
||||||
|
|
||||||
|
cur_filename = new_filename;
|
||||||
|
if (NULL != cur_filename)
|
||||||
|
prev_filename = cur_filename;
|
||||||
|
|
||||||
|
if (NULL == prev_filename)
|
||||||
|
yyerror("no file specified for track");
|
||||||
|
else
|
||||||
|
track_set_filename(track, prev_filename);
|
||||||
|
|
||||||
|
new_filename = NULL;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
track_def
|
||||||
|
: TRACK NUMBER track_mode '\n' {
|
||||||
|
track_set_mode(track, $3);
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
track_mode
|
||||||
|
: AUDIO
|
||||||
|
| MODE1_2048
|
||||||
|
| MODE1_2352
|
||||||
|
| MODE2_2336
|
||||||
|
| MODE2_2048
|
||||||
|
| MODE2_2342
|
||||||
|
| MODE2_2332
|
||||||
|
| MODE2_2352
|
||||||
|
;
|
||||||
|
|
||||||
|
track_statements
|
||||||
|
: track_statement
|
||||||
|
| track_statements track_statement
|
||||||
|
;
|
||||||
|
|
||||||
|
track_statement
|
||||||
|
: cdtext
|
||||||
|
| FLAGS track_flags '\n'
|
||||||
|
| TRACK_ISRC STRING '\n' { track_set_isrc(track, $2); }
|
||||||
|
| PREGAP time '\n' { track_set_zero_pre(track, $2); }
|
||||||
|
| INDEX NUMBER time '\n' {
|
||||||
|
int i = track_get_nindex(track);
|
||||||
|
long prev_length;
|
||||||
|
|
||||||
|
if (0 == i) {
|
||||||
|
/* first index */
|
||||||
|
track_set_start(track, $3);
|
||||||
|
|
||||||
|
if (NULL != prev_track && NULL == cur_filename) {
|
||||||
|
/* track shares file with previous track */
|
||||||
|
prev_length = $3 - track_get_start(prev_track);
|
||||||
|
track_set_length(prev_track, prev_length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; i <= $2; i++)
|
||||||
|
track_add_index(track, \
|
||||||
|
track_get_zero_pre(track) + $3 \
|
||||||
|
- track_get_start(track));
|
||||||
|
}
|
||||||
|
| POSTGAP time '\n' { track_set_zero_post(track, $2); }
|
||||||
|
| track_data
|
||||||
|
| error '\n'
|
||||||
|
;
|
||||||
|
|
||||||
|
track_flags
|
||||||
|
: /* empty */
|
||||||
|
| track_flags track_flag { track_set_flag(track, $2); }
|
||||||
|
;
|
||||||
|
|
||||||
|
track_flag
|
||||||
|
: PRE
|
||||||
|
| DCP
|
||||||
|
| FOUR_CH
|
||||||
|
| SCMS
|
||||||
|
;
|
||||||
|
|
||||||
|
cdtext
|
||||||
|
: cdtext_item STRING '\n' { cdtext_set ($1, $2, cdtext); }
|
||||||
|
;
|
||||||
|
|
||||||
|
cdtext_item
|
||||||
|
: TITLE
|
||||||
|
| PERFORMER
|
||||||
|
| SONGWRITER
|
||||||
|
| COMPOSER
|
||||||
|
| ARRANGER
|
||||||
|
| MESSAGE
|
||||||
|
| DISC_ID
|
||||||
|
| GENRE
|
||||||
|
| TOC_INFO1
|
||||||
|
| TOC_INFO2
|
||||||
|
| UPC_EAN
|
||||||
|
| ISRC
|
||||||
|
| SIZE_INFO
|
||||||
|
;
|
||||||
|
|
||||||
|
time
|
||||||
|
: NUMBER
|
||||||
|
| NUMBER ':' NUMBER ':' NUMBER { $$ = time_msf_to_frame($1, $3, $5); }
|
||||||
|
;
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
/* lexer interface */
|
||||||
|
extern int cue_lineno;
|
||||||
|
extern int cue_yydebug;
|
||||||
|
extern FILE *cue_yyin;
|
||||||
|
|
||||||
|
void yyerror (char *s)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%d: %s\n", cue_lineno, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
Cd *cue_parse (FILE *fp)
|
||||||
|
{
|
||||||
|
cue_yyin = fp;
|
||||||
|
cue_yydebug = 0;
|
||||||
|
|
||||||
|
if (0 == cue_yyparse())
|
||||||
|
return cd;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
146
lib/cue_print.c
Normal file
146
lib/cue_print.c
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
/*
|
||||||
|
* cue_print.y -- print cue file
|
||||||
|
*
|
||||||
|
* Copyright (C) 2004 Svend Sorensen <sorensen@freeshell.org>
|
||||||
|
* For license terms, see the file COPYING in this distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "cd.h"
|
||||||
|
#include "time.h"
|
||||||
|
|
||||||
|
void cue_print_track (FILE *fp, Track *track, int trackno);
|
||||||
|
void cue_print_cdtext (Cdtext *cdtext, FILE *fp, int istrack);
|
||||||
|
void cue_print_index (long i, FILE *fp);
|
||||||
|
char *filename = ""; /* last track datafile */
|
||||||
|
long prev_length = 0; /* last track length */
|
||||||
|
|
||||||
|
/* prints cd in cue format */
|
||||||
|
void cue_print (FILE *fp, Cd *cd)
|
||||||
|
{
|
||||||
|
Cdtext *cdtext = cd_get_cdtext(cd);
|
||||||
|
int i; /* track */
|
||||||
|
Track *track = NULL;
|
||||||
|
|
||||||
|
/* print global information */
|
||||||
|
if (NULL != cd_get_catalog(cd))
|
||||||
|
fprintf(fp, "CATALOG %s\n", cd_get_catalog(cd));
|
||||||
|
|
||||||
|
cue_print_cdtext(cdtext, fp, 0);
|
||||||
|
|
||||||
|
/* print track information */
|
||||||
|
for (i = 1; i <= cd_get_ntrack(cd); i++) {
|
||||||
|
track = cd_get_track(cd, i);
|
||||||
|
fprintf(fp, "\n");
|
||||||
|
cue_print_track(fp, track, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cue_print_track (FILE *fp, Track *track, int trackno)
|
||||||
|
{
|
||||||
|
Cdtext *cdtext = track_get_cdtext(track);
|
||||||
|
int i; /* index */
|
||||||
|
|
||||||
|
if (NULL != track_get_filename(track)) {
|
||||||
|
/*
|
||||||
|
* always print filename for track 1, afterwards only
|
||||||
|
* print filename if it differs from the previous track
|
||||||
|
*/
|
||||||
|
if (0 != strcmp(track_get_filename(track), filename)) {
|
||||||
|
filename = track_get_filename(track);
|
||||||
|
fprintf(fp, "FILE \"%s\" ", filename);
|
||||||
|
|
||||||
|
/* NOTE: what to do with other formats (MP3, etc)? */
|
||||||
|
if (MODE_AUDIO == track_get_mode(track))
|
||||||
|
fprintf(fp, "WAVE\n");
|
||||||
|
else
|
||||||
|
fprintf(fp, "BINARY\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(fp, "TRACK %02d ", trackno);
|
||||||
|
switch (track_get_mode(track)) {
|
||||||
|
case MODE_AUDIO:
|
||||||
|
fprintf(fp, "AUDIO\n");
|
||||||
|
break;
|
||||||
|
case MODE_MODE1:
|
||||||
|
fprintf(fp, "MODE1/2048\n");
|
||||||
|
break;
|
||||||
|
case MODE_MODE1_RAW:
|
||||||
|
fprintf(fp, "MODE1/2352\n");
|
||||||
|
break;
|
||||||
|
case MODE_MODE2:
|
||||||
|
fprintf(fp, "MODE2/2048\n");
|
||||||
|
break;
|
||||||
|
case MODE_MODE2_FORM1:
|
||||||
|
fprintf(fp, "MODE2/2336\n");
|
||||||
|
break;
|
||||||
|
case MODE_MODE2_FORM2:
|
||||||
|
fprintf(fp, "MODE2/2324\n");
|
||||||
|
break;
|
||||||
|
case MODE_MODE2_FORM_MIX:
|
||||||
|
fprintf(fp, "MODE2/2336\n");
|
||||||
|
break;
|
||||||
|
case MODE_MODE2_RAW:
|
||||||
|
fprintf(fp, "MODE2/2352\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
cue_print_cdtext(cdtext, fp, 1);
|
||||||
|
|
||||||
|
if (0 != track_is_set_flag(track, FLAG_ANY)) {
|
||||||
|
fprintf(fp, "FLAGS");
|
||||||
|
if (0 != track_is_set_flag(track, FLAG_PRE_EMPHASIS))
|
||||||
|
fprintf(fp, " PRE");
|
||||||
|
if (0 != track_is_set_flag(track, FLAG_COPY_PERMITTED))
|
||||||
|
fprintf(fp, " DCP");
|
||||||
|
if (0 != track_is_set_flag(track, FLAG_FOUR_CHANNEL))
|
||||||
|
fprintf(fp, " 4CH");
|
||||||
|
if (0 != track_is_set_flag(track, FLAG_SCMS))
|
||||||
|
fprintf(fp, " SCMS");
|
||||||
|
fprintf(fp, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NULL != track_get_isrc(track))
|
||||||
|
fprintf(fp, "ISRC %s\n", track_get_isrc(track));
|
||||||
|
|
||||||
|
if (0 != track_get_zero_pre(track))
|
||||||
|
fprintf (fp, "PREGAP %s\n", time_frame_to_mmssff(track_get_zero_pre(track)));
|
||||||
|
|
||||||
|
/* don't print index 0 if index 1 = 0 */
|
||||||
|
if (track_get_index(track, 1) == 0)
|
||||||
|
i = 1;
|
||||||
|
else
|
||||||
|
i = 0;
|
||||||
|
|
||||||
|
for (; i < track_get_nindex(track); i++) {
|
||||||
|
fprintf(fp, "INDEX %02d ", i);
|
||||||
|
cue_print_index( \
|
||||||
|
track_get_index(track, i) \
|
||||||
|
+ track_get_start(track) \
|
||||||
|
- track_get_zero_pre(track) , fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 != track_get_zero_post(track))
|
||||||
|
fprintf (fp, "POSTGAP %s\n", time_frame_to_mmssff(track_get_zero_post(track)));
|
||||||
|
|
||||||
|
prev_length = track_get_length(track);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cue_print_cdtext (Cdtext *cdtext, FILE *fp, int istrack)
|
||||||
|
{
|
||||||
|
int pti;
|
||||||
|
char *value = NULL;
|
||||||
|
|
||||||
|
for (pti = 0; PTI_END != pti; pti++)
|
||||||
|
if (NULL != (value = cdtext_get(pti, cdtext))) {
|
||||||
|
fprintf(fp, "%s", cdtext_get_key(pti, istrack));
|
||||||
|
fprintf(fp, " \"%s\"\n", value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cue_print_index (long i, FILE *fp)
|
||||||
|
{
|
||||||
|
fprintf (fp, "%s\n", time_frame_to_mmssff(i));
|
||||||
|
}
|
||||||
94
lib/cue_scan.l
Normal file
94
lib/cue_scan.l
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
%{
|
||||||
|
/*
|
||||||
|
* cue_scan.l -- lexer for cue files
|
||||||
|
*
|
||||||
|
* Copyright (C) 2004 Svend Sorensen <sorensen@freeshell.org>
|
||||||
|
* For license terms, see the file COPYING in this distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "cd.h"
|
||||||
|
#include "cue_parse.h"
|
||||||
|
|
||||||
|
int cue_lineno = 1;
|
||||||
|
%}
|
||||||
|
|
||||||
|
ws [ \t\r]
|
||||||
|
nonws [^ \t\r\n]
|
||||||
|
|
||||||
|
%option noyywrap
|
||||||
|
|
||||||
|
%s NAME
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
\"(\\.|[^\\"])*\" {
|
||||||
|
cue_yylval.sval = strdup(yytext + 1);
|
||||||
|
cue_yylval.sval[strlen(cue_yylval.sval) - 1] = '\0';
|
||||||
|
BEGIN(INITIAL);
|
||||||
|
return STRING;
|
||||||
|
}
|
||||||
|
|
||||||
|
<NAME>{nonws}+ {
|
||||||
|
cue_yylval.sval = strdup(yytext);
|
||||||
|
BEGIN(INITIAL);
|
||||||
|
return STRING;
|
||||||
|
}
|
||||||
|
|
||||||
|
CATALOG { BEGIN(NAME); return CATALOG; }
|
||||||
|
|
||||||
|
FILE { BEGIN(NAME); return FFILE; }
|
||||||
|
BINARY { return BINARY; }
|
||||||
|
MOTOROLA { return MOTOROLA; }
|
||||||
|
AIFF { return AIFF; }
|
||||||
|
WAVE { return WAVE; }
|
||||||
|
MP3 { return MP3; }
|
||||||
|
|
||||||
|
TRACK { return TRACK; }
|
||||||
|
AUDIO { cue_yylval.ival = MODE_AUDIO; return AUDIO; }
|
||||||
|
MODE1\/2048 { cue_yylval.ival = MODE_MODE1; return MODE1_2048; }
|
||||||
|
MODE1\/2352 { cue_yylval.ival = MODE_MODE1_RAW; return MODE1_2352; }
|
||||||
|
MODE2\/2336 { cue_yylval.ival = MODE_MODE2; return MODE2_2336; }
|
||||||
|
MODE2\/2048 { cue_yylval.ival = MODE_MODE2_FORM1; return MODE2_2048; }
|
||||||
|
MODE2\/2342 { cue_yylval.ival = MODE_MODE2_FORM2; return MODE2_2342; }
|
||||||
|
MODE2\/2332 { cue_yylval.ival = MODE_MODE2_FORM_MIX; return MODE2_2332; }
|
||||||
|
MODE2\/2352 { cue_yylval.ival = MODE_MODE2_RAW; return MODE2_2352; }
|
||||||
|
|
||||||
|
FLAGS { return FLAGS; }
|
||||||
|
PRE { cue_yylval.ival = FLAG_PRE_EMPHASIS; return PRE; }
|
||||||
|
DCP { cue_yylval.ival = FLAG_COPY_PERMITTED; return DCP; }
|
||||||
|
4CH { cue_yylval.ival = FLAG_FOUR_CHANNEL; return FOUR_CH; }
|
||||||
|
SCMS { cue_yylval.ival = FLAG_SCMS; return SCMS; }
|
||||||
|
|
||||||
|
PREGAP { return PREGAP; }
|
||||||
|
INDEX { return INDEX; }
|
||||||
|
POSTGAP { return POSTGAP; }
|
||||||
|
|
||||||
|
TITLE { BEGIN(NAME); cue_yylval.ival = PTI_TITLE; return TITLE; }
|
||||||
|
PERFORMER { BEGIN(NAME); cue_yylval.ival = PTI_PERFORMER; return PERFORMER; }
|
||||||
|
SONGWRITER { BEGIN(NAME); cue_yylval.ival = PTI_SONGWRITER; return SONGWRITER; }
|
||||||
|
COMPOSER { BEGIN(NAME); cue_yylval.ival = PTI_COMPOSER; return COMPOSER; }
|
||||||
|
ARRANGER { BEGIN(NAME); cue_yylval.ival = PTI_ARRANGER; return ARRANGER; }
|
||||||
|
MESSAGE { BEGIN(NAME); cue_yylval.ival = PTI_MESSAGE; return MESSAGE; }
|
||||||
|
DISC_ID { BEGIN(NAME); cue_yylval.ival = PTI_DISC_ID; return DISC_ID; }
|
||||||
|
GENRE { BEGIN(NAME); cue_yylval.ival = PTI_GENRE; return GENRE; }
|
||||||
|
TOC_INFO1 { BEGIN(NAME); cue_yylval.ival = PTI_TOC_INFO1; return TOC_INFO1; }
|
||||||
|
TOC_INFO2 { BEGIN(NAME); cue_yylval.ival = PTI_TOC_INFO2; return TOC_INFO2; }
|
||||||
|
UPC_EAN { BEGIN(NAME); cue_yylval.ival = PTI_UPC_ISRC; return UPC_EAN; }
|
||||||
|
ISRC/{ws}+\" { BEGIN(NAME); cue_yylval.ival = PTI_UPC_ISRC; return ISRC; }
|
||||||
|
SIZE_INFO { BEGIN(NAME); cue_yylval.ival = PTI_SIZE_INFO; return SIZE_INFO; }
|
||||||
|
|
||||||
|
ISRC { BEGIN(NAME); return TRACK_ISRC; }
|
||||||
|
|
||||||
|
^{ws}*REM.*\n { cue_lineno++; /* ignore comments */ }
|
||||||
|
{ws}+ { /* ignore whitespace */ }
|
||||||
|
|
||||||
|
[[:digit:]]+ { cue_yylval.ival = atoi(yytext); return NUMBER; }
|
||||||
|
: { return yytext[0]; }
|
||||||
|
|
||||||
|
^{ws}*\n { cue_lineno++; /* blank line */ }
|
||||||
|
\n { cue_lineno++; return '\n'; }
|
||||||
|
. { fprintf(stderr, "bad character '%c'\n", yytext[0]); }
|
||||||
|
|
||||||
|
%%
|
||||||
90
lib/cuefile.c
Normal file
90
lib/cuefile.c
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
/*
|
||||||
|
* cuefile.c -- cue/toc functions
|
||||||
|
*
|
||||||
|
* Copyright (C) 2004 Svend Sorensen <sorensen@freeshell.org>
|
||||||
|
* For license terms, see the file COPYING in this distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "cuefile.h"
|
||||||
|
#include "cue.h"
|
||||||
|
#include "toc.h"
|
||||||
|
|
||||||
|
Cd *cf_parse (char *name, int *format)
|
||||||
|
{
|
||||||
|
FILE *fp = NULL;
|
||||||
|
Cd *cd = NULL;
|
||||||
|
|
||||||
|
if (UNKNOWN == *format)
|
||||||
|
if (UNKNOWN == (*format = cf_format_from_suffix(name))) {
|
||||||
|
fprintf(stderr, "%s: unknown format\n", name);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 == strcmp("-", name)) {
|
||||||
|
fp = stdin;
|
||||||
|
} else if (NULL == (fp = fopen(name, "r"))) {
|
||||||
|
fprintf(stderr, "%s: error opening file\n", name);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (*format) {
|
||||||
|
case CUE:
|
||||||
|
cd = cue_parse(fp);
|
||||||
|
break;
|
||||||
|
case TOC:
|
||||||
|
cd = toc_parse(fp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(stdin != fp)
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
return cd;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cf_print (char *name, int *format, Cd *cd)
|
||||||
|
{
|
||||||
|
FILE *fp = NULL;
|
||||||
|
|
||||||
|
if (UNKNOWN == *format)
|
||||||
|
if (UNKNOWN == (*format = cf_format_from_suffix(name))) {
|
||||||
|
fprintf(stderr, "%s: unknown format\n", name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 == strcmp("-", name)) {
|
||||||
|
fp = stdout;
|
||||||
|
} else if (NULL == (fp = fopen(name, "w"))) {
|
||||||
|
fprintf(stderr, "%s: error opening file\n", name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (*format) {
|
||||||
|
case CUE:
|
||||||
|
cue_print(fp, cd);
|
||||||
|
break;
|
||||||
|
case TOC:
|
||||||
|
toc_print(fp, cd);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(stdout != fp)
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cf_format_from_suffix (char *name)
|
||||||
|
{
|
||||||
|
char *suffix;
|
||||||
|
if (0 != (suffix = strrchr(name, '.'))) {
|
||||||
|
if (0 == strcasecmp(".cue", suffix))
|
||||||
|
return CUE;
|
||||||
|
else if (0 == strcasecmp(".toc", suffix))
|
||||||
|
return TOC;
|
||||||
|
}
|
||||||
|
|
||||||
|
return UNKNOWN;
|
||||||
|
}
|
||||||
16
lib/cuefile.h
Normal file
16
lib/cuefile.h
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
/*
|
||||||
|
* cuefile.h -- cue/toc public declarations
|
||||||
|
*
|
||||||
|
* Copyright (C) 2004 Svend Sorensen <sorensen@freeshell.org>
|
||||||
|
* For license terms, see the file COPYING in this distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cd.h"
|
||||||
|
|
||||||
|
enum {CUE, TOC, UNKNOWN};
|
||||||
|
|
||||||
|
typedef struct Cue Cue;
|
||||||
|
|
||||||
|
Cd *cf_parse (char *fname, int *format);
|
||||||
|
int cf_print (char *fname, int *format, Cd *cue);
|
||||||
|
int cf_format_from_suffix (char *fname);
|
||||||
43
lib/time.c
Normal file
43
lib/time.c
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* time.c -- time functions
|
||||||
|
*
|
||||||
|
* Copyright (C) 2004 Svend Sorensen <sorensen@freeshell.org>
|
||||||
|
* For license terms, see the file COPYING in this distribution.
|
||||||
|
*/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
long time_msf_to_frame (int m, int s, int f)
|
||||||
|
{
|
||||||
|
return (m * 60 + s) * 75 + f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void msf_frame_to_msf (long frame, int *m, int *s, int *f)
|
||||||
|
{
|
||||||
|
*f = frame % 75; /* 0 <= frames <= 74 */
|
||||||
|
frame /= 75;
|
||||||
|
*s = frame % 60; /* 0 <= seconds <= 59 */
|
||||||
|
frame /= 60;
|
||||||
|
*m = frame; /* 0 <= minutes */
|
||||||
|
}
|
||||||
|
|
||||||
|
void time_frame_to_msf (long frame, int *m, int *s, int *f)
|
||||||
|
{
|
||||||
|
*f = frame % 75; /* 0 <= frames <= 74 */
|
||||||
|
frame /= 75;
|
||||||
|
*s = frame % 60; /* 0 <= seconds <= 59 */
|
||||||
|
frame /= 60;
|
||||||
|
*m = frame; /* 0 <= minutes */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* print frame in mm:ss:ff format */
|
||||||
|
char *time_frame_to_mmssff (long f)
|
||||||
|
{
|
||||||
|
static char msf[9];
|
||||||
|
int minutes, seconds, frames;
|
||||||
|
|
||||||
|
msf_frame_to_msf(f, &minutes, &seconds, &frames);
|
||||||
|
sprintf(msf, "%02d:%02d:%02d", minutes, seconds, frames);
|
||||||
|
|
||||||
|
return msf;
|
||||||
|
}
|
||||||
15
lib/time.h
Normal file
15
lib/time.h
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
/* time.h -- time declarations
|
||||||
|
*
|
||||||
|
* Copyright (C) 2004 Svend Sorensen <sorensen@freeshell.org>
|
||||||
|
* For license terms, see the file COPYING in this distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef TIME_H
|
||||||
|
#define TIME_H
|
||||||
|
|
||||||
|
long time_msf_to_frame (int m, int s, int f);
|
||||||
|
long time_mmssff_to_frame (char *mmssff);
|
||||||
|
void time_frame_to_msf (long frame, int *m, int *s, int *f);
|
||||||
|
char *time_frame_to_mmssff (long f);
|
||||||
|
|
||||||
|
#endif
|
||||||
6
lib/toc.h
Normal file
6
lib/toc.h
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
/*
|
||||||
|
* toc.h -- toc function declarations
|
||||||
|
*/
|
||||||
|
|
||||||
|
Cd *toc_parse (FILE *fp);
|
||||||
|
void toc_print (FILE *fp, Cd *cd);
|
||||||
345
lib/toc_parse.y
Normal file
345
lib/toc_parse.y
Normal file
@@ -0,0 +1,345 @@
|
|||||||
|
%{
|
||||||
|
/*
|
||||||
|
* toc_parse.y -- parser for toc files
|
||||||
|
*
|
||||||
|
* Copyright (C) 2004 Svend Sorensen <sorensen@freeshell.org>
|
||||||
|
* For license terms, see the file COPYING in this distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "cd.h"
|
||||||
|
#include "time.h"
|
||||||
|
|
||||||
|
#define YYDEBUG 1
|
||||||
|
|
||||||
|
extern int toc_yylex();
|
||||||
|
void yyerror (char *s);
|
||||||
|
|
||||||
|
static Cd *cd = NULL;
|
||||||
|
static Track *track = NULL;
|
||||||
|
static Cdtext *cdtext = NULL;
|
||||||
|
%}
|
||||||
|
|
||||||
|
%start tocfile
|
||||||
|
|
||||||
|
%union {
|
||||||
|
long ival;
|
||||||
|
char *sval;
|
||||||
|
}
|
||||||
|
|
||||||
|
%token <ival> NUMBER
|
||||||
|
%token <sval> STRING
|
||||||
|
|
||||||
|
/* global (header) */
|
||||||
|
%token CATALOG
|
||||||
|
|
||||||
|
%token <ival> CD_DA
|
||||||
|
%token <ival> CD_ROM
|
||||||
|
%token <ival> CD_ROM_XA
|
||||||
|
|
||||||
|
/* track */
|
||||||
|
%token TRACK
|
||||||
|
%token <ival> AUDIO
|
||||||
|
%token <ival> MODE1
|
||||||
|
%token <ival> MODE1_RAW
|
||||||
|
%token <ival> MODE2
|
||||||
|
%token <ival> MODE2_FORM1
|
||||||
|
%token <ival> MODE2_FORM2
|
||||||
|
%token <ival> MODE2_FORM_MIX
|
||||||
|
%token <ival> MODE2_RAW
|
||||||
|
%token <ival> RW
|
||||||
|
%token <ival> RW_RAW
|
||||||
|
|
||||||
|
%token NO
|
||||||
|
%token <ival> COPY
|
||||||
|
%token <ival> PRE_EMPHASIS
|
||||||
|
%token <ival> TWO_CHANNEL_AUDIO
|
||||||
|
%token <ival> FOUR_CHANNEL_AUDIO
|
||||||
|
|
||||||
|
%token ISRC
|
||||||
|
%token SILENCE
|
||||||
|
%token ZERO
|
||||||
|
%token AUDIOFILE
|
||||||
|
%token DATAFILE
|
||||||
|
%token FIFO
|
||||||
|
%token START
|
||||||
|
%token PREGAP
|
||||||
|
%token INDEX
|
||||||
|
|
||||||
|
/* CD-TEXT */
|
||||||
|
%token CD_TEXT
|
||||||
|
%token LANGUAGE_MAP
|
||||||
|
%token LANGUAGE
|
||||||
|
|
||||||
|
%token <ival> TITLE
|
||||||
|
%token <ival> PERFORMER
|
||||||
|
%token <ival> SONGWRITER
|
||||||
|
%token <ival> COMPOSER
|
||||||
|
%token <ival> ARRANGER
|
||||||
|
%token <ival> MESSAGE
|
||||||
|
%token <ival> DISC_ID
|
||||||
|
%token <ival> GENRE
|
||||||
|
%token <ival> TOC_INFO1
|
||||||
|
%token <ival> TOC_INFO2
|
||||||
|
%token <ival> UPC_EAN
|
||||||
|
%token <ival> ISRC
|
||||||
|
%token <ival> SIZE_INFO
|
||||||
|
|
||||||
|
%type <ival> disc_mode
|
||||||
|
%type <ival> track_modes
|
||||||
|
%type <ival> track_mode
|
||||||
|
%type <ival> track_sub_mode
|
||||||
|
%type <ival> track_set_flag
|
||||||
|
%type <ival> track_clear_flag
|
||||||
|
%type <ival> time
|
||||||
|
%type <ival> cdtext_item
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
tocfile
|
||||||
|
: new_cd global_statements track_list
|
||||||
|
;
|
||||||
|
|
||||||
|
new_cd
|
||||||
|
: /* empty */ {
|
||||||
|
cd = cd_init();
|
||||||
|
cdtext = cd_get_cdtext(cd);
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
global_statements
|
||||||
|
: /* empty */
|
||||||
|
| global_statements global_statement
|
||||||
|
;
|
||||||
|
|
||||||
|
global_statement
|
||||||
|
: CATALOG STRING '\n' { cd_set_catalog(cd, $2); }
|
||||||
|
| disc_mode '\n' { cd_set_mode(cd, $1); }
|
||||||
|
| CD_TEXT '{' opt_nl language_map cdtext_langs '}' '\n'
|
||||||
|
| error '\n'
|
||||||
|
;
|
||||||
|
|
||||||
|
disc_mode
|
||||||
|
: CD_DA
|
||||||
|
| CD_ROM
|
||||||
|
| CD_ROM_XA
|
||||||
|
;
|
||||||
|
|
||||||
|
track_list
|
||||||
|
: track
|
||||||
|
| track_list track
|
||||||
|
;
|
||||||
|
|
||||||
|
track
|
||||||
|
: new_track track_def track_statements {
|
||||||
|
while (2 > track_get_nindex(track))
|
||||||
|
track_add_index(track, 0);
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
new_track
|
||||||
|
: /* empty */ {
|
||||||
|
track = cd_add_track(cd);
|
||||||
|
cdtext = track_get_cdtext(track);
|
||||||
|
/* add 0 index */
|
||||||
|
track_add_index(track, 0);
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
track_def
|
||||||
|
: TRACK track_modes '\n' { track_set_mode(track, $2); }
|
||||||
|
;
|
||||||
|
|
||||||
|
track_modes
|
||||||
|
: track_mode
|
||||||
|
| track_mode track_sub_mode { track_set_sub_mode(track, $2); }
|
||||||
|
;
|
||||||
|
|
||||||
|
track_mode
|
||||||
|
: AUDIO
|
||||||
|
| MODE1
|
||||||
|
| MODE1_RAW
|
||||||
|
| MODE2
|
||||||
|
| MODE2_FORM1
|
||||||
|
| MODE2_FORM2
|
||||||
|
| MODE2_FORM_MIX
|
||||||
|
| MODE2_RAW
|
||||||
|
;
|
||||||
|
|
||||||
|
track_sub_mode
|
||||||
|
: RW
|
||||||
|
| RW_RAW
|
||||||
|
;
|
||||||
|
|
||||||
|
track_statements
|
||||||
|
: track_statement
|
||||||
|
| track_statements track_statement
|
||||||
|
;
|
||||||
|
|
||||||
|
track_statement
|
||||||
|
: track_flags
|
||||||
|
| ISRC STRING '\n' { track_set_isrc(track, $2); }
|
||||||
|
| CD_TEXT '{' opt_nl cdtext_langs '}' '\n'
|
||||||
|
| track_data
|
||||||
|
| track_pregap
|
||||||
|
| track_index
|
||||||
|
| error '\n'
|
||||||
|
;
|
||||||
|
|
||||||
|
track_flags
|
||||||
|
: track_set_flag { track_set_flag(track, $1); }
|
||||||
|
| track_clear_flag { track_clear_flag(track, $1); }
|
||||||
|
;
|
||||||
|
|
||||||
|
track_set_flag
|
||||||
|
: COPY '\n'
|
||||||
|
| PRE_EMPHASIS '\n'
|
||||||
|
| FOUR_CHANNEL_AUDIO '\n'
|
||||||
|
;
|
||||||
|
|
||||||
|
track_clear_flag
|
||||||
|
: NO PRE_EMPHASIS '\n' { $$ = $2; }
|
||||||
|
| NO COPY '\n' { $$ = $2; }
|
||||||
|
| TWO_CHANNEL_AUDIO '\n'
|
||||||
|
;
|
||||||
|
|
||||||
|
track_data
|
||||||
|
: zero_data time '\n' {
|
||||||
|
if (NULL == track_get_filename(track))
|
||||||
|
track_set_zero_pre(track, $2);
|
||||||
|
else
|
||||||
|
track_set_zero_post(track, $2);
|
||||||
|
}
|
||||||
|
| AUDIOFILE STRING time '\n' {
|
||||||
|
track_set_filename(track, $2);
|
||||||
|
track_set_start(track, $3);
|
||||||
|
}
|
||||||
|
| AUDIOFILE STRING time time '\n' {
|
||||||
|
track_set_filename(track, $2);
|
||||||
|
track_set_start(track, $3);
|
||||||
|
track_set_length(track, $4);
|
||||||
|
}
|
||||||
|
| DATAFILE STRING '\n' {
|
||||||
|
track_set_filename(track, $2);
|
||||||
|
}
|
||||||
|
| DATAFILE STRING time '\n' {
|
||||||
|
track_set_filename(track, $2);
|
||||||
|
track_set_start(track, $3);
|
||||||
|
}
|
||||||
|
| FIFO STRING time '\n' {
|
||||||
|
track_set_filename(track, $2);
|
||||||
|
track_set_start(track, $3);
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
zero_data
|
||||||
|
: SILENCE
|
||||||
|
| ZERO
|
||||||
|
;
|
||||||
|
|
||||||
|
track_pregap
|
||||||
|
: START '\n'
|
||||||
|
| START time '\n' {
|
||||||
|
track_add_index(track, $2);
|
||||||
|
}
|
||||||
|
| PREGAP time '\n' {
|
||||||
|
track_set_zero_pre(track, $2);
|
||||||
|
track_add_index(track, $2);
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
track_index
|
||||||
|
: INDEX time '\n' { track_add_index(track, $2); }
|
||||||
|
;
|
||||||
|
|
||||||
|
language_map
|
||||||
|
: LANGUAGE_MAP '{' opt_nl languages '}' '\n'
|
||||||
|
;
|
||||||
|
|
||||||
|
languages
|
||||||
|
: language
|
||||||
|
| languages language
|
||||||
|
;
|
||||||
|
|
||||||
|
language
|
||||||
|
: NUMBER ':' NUMBER opt_nl
|
||||||
|
;
|
||||||
|
|
||||||
|
cdtext_langs
|
||||||
|
: cdtext_lang
|
||||||
|
| cdtext_langs cdtext_lang
|
||||||
|
;
|
||||||
|
|
||||||
|
cdtext_lang
|
||||||
|
: LANGUAGE NUMBER '{' opt_nl cdtext_defs '}' '\n'
|
||||||
|
;
|
||||||
|
|
||||||
|
cdtext_defs
|
||||||
|
: /* empty */
|
||||||
|
| cdtext_defs cdtext_def
|
||||||
|
;
|
||||||
|
|
||||||
|
cdtext_def
|
||||||
|
: cdtext_item STRING '\n' {
|
||||||
|
cdtext_set ($1, $2, cdtext);
|
||||||
|
}
|
||||||
|
| cdtext_item '{' bytes '}' '\n' {
|
||||||
|
yyerror("binary CD-TEXT data not supported\n");
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
cdtext_item
|
||||||
|
: TITLE
|
||||||
|
| PERFORMER
|
||||||
|
| SONGWRITER
|
||||||
|
| COMPOSER
|
||||||
|
| ARRANGER
|
||||||
|
| MESSAGE
|
||||||
|
| DISC_ID
|
||||||
|
| GENRE
|
||||||
|
| TOC_INFO1
|
||||||
|
| TOC_INFO2
|
||||||
|
| UPC_EAN
|
||||||
|
| ISRC
|
||||||
|
| SIZE_INFO
|
||||||
|
;
|
||||||
|
|
||||||
|
bytes
|
||||||
|
: /* empty */
|
||||||
|
| bytes ',' NUMBER
|
||||||
|
;
|
||||||
|
|
||||||
|
time
|
||||||
|
: NUMBER { $$ = $1; }
|
||||||
|
| NUMBER ':' NUMBER ':' NUMBER { $$ = time_msf_to_frame($1, $3, $5); }
|
||||||
|
;
|
||||||
|
|
||||||
|
opt_nl
|
||||||
|
: /* empty */
|
||||||
|
| '\n'
|
||||||
|
;
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
/* lexer interface */
|
||||||
|
extern int toc_lineno;
|
||||||
|
extern int toc_yydebug;
|
||||||
|
extern FILE *toc_yyin;
|
||||||
|
|
||||||
|
void yyerror (char *s)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%d: %s\n", toc_lineno, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
Cd *toc_parse (FILE *fp)
|
||||||
|
{
|
||||||
|
toc_yyin = fp;
|
||||||
|
toc_yydebug = 0;
|
||||||
|
|
||||||
|
if (0 == toc_yyparse())
|
||||||
|
return cd;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
149
lib/toc_print.c
Normal file
149
lib/toc_print.c
Normal file
@@ -0,0 +1,149 @@
|
|||||||
|
/*
|
||||||
|
* toc_print.c -- print toc file
|
||||||
|
*
|
||||||
|
* Copyright (C) 2004 Svend Sorensen <sorensen@freeshell.org>
|
||||||
|
* For license terms, see the file COPYING in this distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "cd.h"
|
||||||
|
#include "time.h"
|
||||||
|
|
||||||
|
void toc_print_track (FILE *fp, Track *track);
|
||||||
|
void toc_print_cdtext (Cdtext *cdtext, FILE *fp, int istrack);
|
||||||
|
|
||||||
|
void toc_print (FILE *fp, Cd *cd)
|
||||||
|
{
|
||||||
|
Cdtext *cdtext = cd_get_cdtext(cd);
|
||||||
|
int i; /* track */
|
||||||
|
Track *track;
|
||||||
|
|
||||||
|
switch(cd_get_mode(cd)) {
|
||||||
|
case MODE_CD_DA:
|
||||||
|
fprintf(fp, "CD_DA\n");
|
||||||
|
break;
|
||||||
|
case MODE_CD_ROM:
|
||||||
|
fprintf(fp, "CD_ROM\n");
|
||||||
|
break;
|
||||||
|
case MODE_CD_ROM_XA:
|
||||||
|
fprintf(fp, "CD_ROM_XA\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NULL != cd_get_catalog(cd))
|
||||||
|
fprintf(fp, "CATALOG \"%s\"\n", cd_get_catalog(cd));
|
||||||
|
|
||||||
|
if(0 != cdtext_is_empty(cdtext)) {
|
||||||
|
fprintf(fp, "CD_TEXT {\n");
|
||||||
|
fprintf(fp, "\tLANGUAGE_MAP { 0:9 }\n");
|
||||||
|
fprintf(fp, "\tLANGUAGE 0 {\n");
|
||||||
|
toc_print_cdtext(cdtext, fp, 0);
|
||||||
|
fprintf(fp, "\t}\n");
|
||||||
|
fprintf(fp, "}\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 1; i <= cd_get_ntrack(cd); i++) {
|
||||||
|
track = cd_get_track(cd, i);
|
||||||
|
fprintf(fp, "\n");
|
||||||
|
toc_print_track(fp, track);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void toc_print_track (FILE *fp, Track *track)
|
||||||
|
{
|
||||||
|
Cdtext *cdtext = track_get_cdtext(track);
|
||||||
|
int i; /* index */
|
||||||
|
|
||||||
|
fprintf(fp, "TRACK ");
|
||||||
|
switch (track_get_mode(track)) {
|
||||||
|
case MODE_AUDIO:
|
||||||
|
fprintf(fp, "AUDIO");
|
||||||
|
break;
|
||||||
|
case MODE_MODE1:
|
||||||
|
fprintf(fp, "MODE1");
|
||||||
|
break;
|
||||||
|
case MODE_MODE1_RAW:
|
||||||
|
fprintf(fp, "MODE1_RAW");
|
||||||
|
break;
|
||||||
|
case MODE_MODE2:
|
||||||
|
fprintf(fp, "MODE2");
|
||||||
|
break;
|
||||||
|
case MODE_MODE2_FORM1:
|
||||||
|
fprintf(fp, "MODE2_FORM1");
|
||||||
|
break;
|
||||||
|
case MODE_MODE2_FORM2:
|
||||||
|
fprintf(fp, "MODE2_FORM2");
|
||||||
|
break;
|
||||||
|
case MODE_MODE2_FORM_MIX:
|
||||||
|
fprintf(fp, "MODE2_FORM_MIX");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fprintf(fp, "\n");
|
||||||
|
|
||||||
|
if (0 != track_is_set_flag(track, FLAG_PRE_EMPHASIS))
|
||||||
|
fprintf(fp, "PRE_EMPHASIS\n");
|
||||||
|
if (0 != track_is_set_flag(track, FLAG_COPY_PERMITTED))
|
||||||
|
fprintf(fp, "COPY\n");
|
||||||
|
if (0 != track_is_set_flag(track, FLAG_FOUR_CHANNEL))
|
||||||
|
fprintf(fp, "FOUR_CHANNEL_AUDIO\n");
|
||||||
|
|
||||||
|
if (NULL != track_get_isrc(track))
|
||||||
|
fprintf(fp, "ISRC \"%s\"\n", track_get_isrc(track));
|
||||||
|
|
||||||
|
if (0 != cdtext_is_empty(cdtext)) {
|
||||||
|
fprintf(fp, "CD_TEXT {\n");
|
||||||
|
fprintf(fp, "\tLANGUAGE 0 {\n");
|
||||||
|
toc_print_cdtext(cdtext, fp, 1);
|
||||||
|
fprintf(fp, "\t}\n");
|
||||||
|
fprintf(fp, "}\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 != track_get_zero_pre(track)) {
|
||||||
|
fprintf(fp, "ZERO ");
|
||||||
|
fprintf(fp, "%s", time_frame_to_mmssff(track_get_zero_pre(track)));
|
||||||
|
fprintf(fp, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(fp, "FILE ");
|
||||||
|
fprintf(fp, "\"%s\" ", track_get_filename(track));
|
||||||
|
if (0 == track_get_start(track))
|
||||||
|
fprintf(fp, "0");
|
||||||
|
else
|
||||||
|
fprintf(fp, "%s", time_frame_to_mmssff(track_get_start(track)));
|
||||||
|
if (0 != track_get_length(track))
|
||||||
|
fprintf(fp, " %s", time_frame_to_mmssff(track_get_length(track)));
|
||||||
|
fprintf(fp, "\n");
|
||||||
|
|
||||||
|
if (0 != track_get_zero_post(track)) {
|
||||||
|
fprintf(fp, "ZERO ");
|
||||||
|
fprintf(fp, "%s", time_frame_to_mmssff(track_get_zero_post(track)));
|
||||||
|
fprintf(fp, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (track_get_index(track, 1) != 0) {
|
||||||
|
fprintf(fp, "START ");
|
||||||
|
fprintf(fp, "%s\n", time_frame_to_mmssff(track_get_index(track, 1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 2; i < track_get_nindex(track); i++) {
|
||||||
|
fprintf(fp, "INDEX ");
|
||||||
|
fprintf(fp, "%s\n", time_frame_to_mmssff( \
|
||||||
|
track_get_index(track, i) - track_get_index(track, 0) \
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void toc_print_cdtext (Cdtext *cdtext, FILE *fp, int istrack)
|
||||||
|
{
|
||||||
|
int pti;
|
||||||
|
char *value = NULL;
|
||||||
|
|
||||||
|
for (pti = 0; PTI_END != pti; pti++) {
|
||||||
|
if (NULL != (value = cdtext_get(pti, cdtext))) {
|
||||||
|
fprintf(fp, "\t\t");
|
||||||
|
fprintf(fp, "%s", cdtext_get_key(pti, istrack));
|
||||||
|
fprintf(fp, " \"%s\"\n", value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
102
lib/toc_scan.l
Normal file
102
lib/toc_scan.l
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
%{
|
||||||
|
/*
|
||||||
|
* toc_scan.l -- lexer for toc files
|
||||||
|
*
|
||||||
|
* Copyright (C) 2004 Svend Sorensen <sorensen@freeshell.org>
|
||||||
|
* For license terms, see the file COPYING in this distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "cd.h"
|
||||||
|
#include "toc_parse.h"
|
||||||
|
|
||||||
|
int toc_lineno = 1;
|
||||||
|
%}
|
||||||
|
|
||||||
|
ws [ \t\r]
|
||||||
|
nonws [^ \t\r\n]
|
||||||
|
|
||||||
|
%option noyywrap
|
||||||
|
|
||||||
|
%s NAME
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
\"(\\.|[^\\"])*\" {
|
||||||
|
toc_yylval.sval = strdup(yytext + 1);
|
||||||
|
toc_yylval.sval[strlen(toc_yylval.sval) - 1] = '\0';
|
||||||
|
BEGIN(INITIAL);
|
||||||
|
return STRING;
|
||||||
|
}
|
||||||
|
|
||||||
|
<NAME>{nonws}+ {
|
||||||
|
toc_yylval.sval = strdup(yytext);
|
||||||
|
BEGIN(INITIAL);
|
||||||
|
return STRING;
|
||||||
|
}
|
||||||
|
|
||||||
|
CATALOG { BEGIN(NAME); return CATALOG; }
|
||||||
|
|
||||||
|
CD_DA { toc_yylval.ival = MODE_CD_DA; return CD_DA; }
|
||||||
|
CD_ROM { toc_yylval.ival = MODE_CD_ROM; return CD_ROM; }
|
||||||
|
CD_ROM_XA { toc_yylval.ival = MODE_CD_ROM_XA; return CD_ROM_XA; }
|
||||||
|
|
||||||
|
TRACK { return TRACK; }
|
||||||
|
AUDIO { toc_yylval.ival = MODE_AUDIO; return AUDIO; }
|
||||||
|
MODE1 { toc_yylval.ival = MODE_MODE1; return MODE1; }
|
||||||
|
MODE1_RAW { toc_yylval.ival = MODE_MODE1_RAW; return MODE1_RAW; }
|
||||||
|
MODE2 { toc_yylval.ival = MODE_MODE2; return MODE2; }
|
||||||
|
MODE2_FORM1 { toc_yylval.ival = MODE_MODE2_FORM1; return MODE2_FORM1; }
|
||||||
|
MODE2_FORM2 { toc_yylval.ival = MODE_MODE2_FORM2; return MODE2_FORM2; }
|
||||||
|
MODE2_FORM_MIX { toc_yylval.ival = MODE_MODE2_FORM_MIX; return MODE2_FORM_MIX; }
|
||||||
|
MODE2_RAW { toc_yylval.ival = MODE_MODE2_RAW; return MODE2_RAW; }
|
||||||
|
RW { toc_yylval.ival = SUB_MODE_RW; return RW; }
|
||||||
|
RW_RAW { toc_yylval.ival = SUB_MODE_RW_RAW; return RW_RAW; }
|
||||||
|
|
||||||
|
NO { return NO; }
|
||||||
|
COPY { toc_yylval.ival = FLAG_PRE_EMPHASIS; return COPY; }
|
||||||
|
PRE_EMPHASIS { toc_yylval.ival = FLAG_COPY_PERMITTED; return PRE_EMPHASIS; }
|
||||||
|
FOUR_CHANNEL_AUDIO { toc_yylval.ival = FLAG_FOUR_CHANNEL; return FOUR_CHANNEL_AUDIO; }
|
||||||
|
TWO_CHANNEL_AUDIO { toc_yylval.ival = FLAG_FOUR_CHANNEL; return TWO_CHANNEL_AUDIO; }
|
||||||
|
|
||||||
|
/* ISRC is with CD-TEXT items */
|
||||||
|
|
||||||
|
SILENCE { return SILENCE; }
|
||||||
|
ZERO { return ZERO; }
|
||||||
|
(AUDIO)?FILE { BEGIN(NAME); return AUDIOFILE; }
|
||||||
|
DATAFILE { BEGIN(NAME); return DATAFILE; }
|
||||||
|
FIFO { BEGIN(NAME); return FIFO; }
|
||||||
|
START { return START; }
|
||||||
|
PREGAP { return PREGAP; }
|
||||||
|
INDEX { return INDEX; }
|
||||||
|
|
||||||
|
CD_TEXT { return CD_TEXT; }
|
||||||
|
LANGUAGE_MAP { return LANGUAGE_MAP; }
|
||||||
|
LANGUAGE { return LANGUAGE; }
|
||||||
|
|
||||||
|
TITLE { BEGIN(NAME); toc_yylval.ival = PTI_TITLE; return TITLE; }
|
||||||
|
PERFORMER { BEGIN(NAME); toc_yylval.ival = PTI_PERFORMER; return PERFORMER; }
|
||||||
|
SONGWRITER { BEGIN(NAME); toc_yylval.ival = PTI_SONGWRITER; return SONGWRITER; }
|
||||||
|
COMPOSER { BEGIN(NAME); toc_yylval.ival = PTI_COMPOSER; return COMPOSER; }
|
||||||
|
ARRANGER { BEGIN(NAME); toc_yylval.ival = PTI_ARRANGER; return ARRANGER; }
|
||||||
|
MESSAGE { BEGIN(NAME); toc_yylval.ival = PTI_MESSAGE; return MESSAGE; }
|
||||||
|
DISC_ID { BEGIN(NAME); toc_yylval.ival = PTI_DISC_ID; return DISC_ID; }
|
||||||
|
GENRE { BEGIN(NAME); toc_yylval.ival = PTI_GENRE; return GENRE; }
|
||||||
|
TOC_INFO1 { BEGIN(NAME); toc_yylval.ival = PTI_TOC_INFO1; return TOC_INFO1; }
|
||||||
|
TOC_INFO2 { BEGIN(NAME); toc_yylval.ival = PTI_TOC_INFO2; return TOC_INFO2; }
|
||||||
|
UPC_EAN { BEGIN(NAME); toc_yylval.ival = PTI_UPC_ISRC; return UPC_EAN; }
|
||||||
|
ISRC { BEGIN(NAME); toc_yylval.ival = PTI_UPC_ISRC; return ISRC; }
|
||||||
|
SIZE_INFO { BEGIN(NAME); toc_yylval.ival = PTI_SIZE_INFO; return SIZE_INFO; }
|
||||||
|
|
||||||
|
"//".*\n { toc_lineno++; /* ignore comments */ }
|
||||||
|
{ws}+ { /* ignore whitespace */ }
|
||||||
|
|
||||||
|
[[:digit:]]+ { toc_yylval.ival = atoi(yytext); return NUMBER; }
|
||||||
|
:|,|\{|\} { return yytext[0]; }
|
||||||
|
|
||||||
|
^{ws}*\n { toc_lineno++; /* blank line */ }
|
||||||
|
\n { toc_lineno++; return '\n'; }
|
||||||
|
. { fprintf(stderr, "bad character '%c'\n", yytext[0]); }
|
||||||
|
|
||||||
|
%%
|
||||||
28
man/Makefile
Normal file
28
man/Makefile
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
# Makefile
|
||||||
|
|
||||||
|
INSTALL= install
|
||||||
|
INSTALL_PROGRAM= $(INSTALL)
|
||||||
|
INSTALL_DATA= $(INSTALL) -m 644
|
||||||
|
|
||||||
|
prefix= /usr/local
|
||||||
|
mandir= $(prefix)/man
|
||||||
|
DESTDIR=
|
||||||
|
|
||||||
|
TARGETS= cuebreakpoints.1 cueconvert.1 cueprint.1
|
||||||
|
|
||||||
|
all:
|
||||||
|
@true
|
||||||
|
|
||||||
|
install: all
|
||||||
|
$(INSTALL) -d $(DESTDIR)$(mandir)/man1
|
||||||
|
for i in $(TARGETS) ; do \
|
||||||
|
$(INSTALL_DATA) $$i $(DESTDIR)$(mandir)/man1/$$i ; \
|
||||||
|
done
|
||||||
|
|
||||||
|
uninstall:
|
||||||
|
-for i in $(TARGETS) ; do \
|
||||||
|
rm -f $(DESTDIR)$(mandir)/man1/$$i ; \
|
||||||
|
done
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@true
|
||||||
23
man/cuebreakpoints.1
Normal file
23
man/cuebreakpoints.1
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
.TH cuetools 1
|
||||||
|
.SH NAME
|
||||||
|
cuebreakpoints
|
||||||
|
.SH DESCRIPTION
|
||||||
|
cuebreakpoints outputs the breakpoints from a cue or toc file
|
||||||
|
.SH SYNTAX
|
||||||
|
cueconvert [-h] [-i cue|toc] [-o cue|toc] [file...]
|
||||||
|
.SH OPTIONS
|
||||||
|
.TP
|
||||||
|
.B \-h
|
||||||
|
print usage information
|
||||||
|
.TP
|
||||||
|
.B \-i cue|toc
|
||||||
|
set format of file(s)
|
||||||
|
.SH NOTES
|
||||||
|
The breakpoints are in a format usable by shnsplit (part of the shntool package). A track breakpoint is at index 1.
|
||||||
|
.PP
|
||||||
|
If no files are specified, stdin is used. If a filename is specified and the format is not specified, the format will be set based on a ".cue" or ".toc" suffix.
|
||||||
|
.SH AUTHOR
|
||||||
|
Svend Sorensen <sorensen@freeshell.org>
|
||||||
|
.SH "SEE ALSO"
|
||||||
|
cueconvert(1),
|
||||||
|
cueprint(1)
|
||||||
24
man/cueconvert.1
Normal file
24
man/cueconvert.1
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
.TH cuetools 1
|
||||||
|
.SH NAME
|
||||||
|
cueconvert
|
||||||
|
.SH DESCRIPTION
|
||||||
|
cueconvert converts between the cue and toc formats
|
||||||
|
.SH SYNTAX
|
||||||
|
cueconvert [-h] [-i cue|toc] [-o cue|toc] [infile [outfile]]
|
||||||
|
.SH OPTIONS
|
||||||
|
.TP
|
||||||
|
.B \-h
|
||||||
|
print usage information
|
||||||
|
.TP
|
||||||
|
.B \-i cue|toc
|
||||||
|
set format of input file
|
||||||
|
.TP
|
||||||
|
.B \-i cue|toc
|
||||||
|
set format of output file
|
||||||
|
.SH NOTES
|
||||||
|
If infile or outfile is not specified, stdin and stdout are used, respectively. If a filename is specified and the format is not specified, the format will be set based on a ".cue" or ".toc" suffix. If the output file format is not specified, and it cannot be determined from the suffix, it will be set to the opposite of the input format.
|
||||||
|
.SH AUTHOR
|
||||||
|
Svend Sorensen <sorensen@freeshell.org>
|
||||||
|
.SH "SEE ALSO"
|
||||||
|
cuebreakpoints(1),
|
||||||
|
cueprint(1)
|
||||||
89
man/cueprint.1
Normal file
89
man/cueprint.1
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
.TH cuetools 1
|
||||||
|
.SH NAME
|
||||||
|
cueprint
|
||||||
|
.SH DESCRIPTION
|
||||||
|
cueprint \- print disc and track infomation for a cue or toc file
|
||||||
|
.SH SYNTAX
|
||||||
|
cueprint [\-h] [\-i cue|toc] [\-d TEMPLATE] [\-t TEMPLATE] [file...]
|
||||||
|
.SH OPTIONS
|
||||||
|
.TP
|
||||||
|
.B \-h
|
||||||
|
print usage information
|
||||||
|
.TP
|
||||||
|
.B \-i cue|toc
|
||||||
|
set format of file(s)
|
||||||
|
.TP
|
||||||
|
.B -d TEMPLATE
|
||||||
|
set disc template (see TEMPLATE EXPANSION)
|
||||||
|
.TP
|
||||||
|
.B -t TEMPLATE
|
||||||
|
set track template (see TEMPLATE EXPANSION)
|
||||||
|
.SH TEMPLATE EXPANSION
|
||||||
|
Disc template expansion characters are valid for both the disc and track templates.
|
||||||
|
.PP
|
||||||
|
Disc:
|
||||||
|
.TP
|
||||||
|
.B %A
|
||||||
|
album arranger
|
||||||
|
.TP
|
||||||
|
.B %C
|
||||||
|
album composer
|
||||||
|
.TP
|
||||||
|
.B %G
|
||||||
|
album genre
|
||||||
|
.TP
|
||||||
|
.B %M
|
||||||
|
album message
|
||||||
|
.TP
|
||||||
|
.B %N
|
||||||
|
number of tracks
|
||||||
|
.TP
|
||||||
|
.B %P
|
||||||
|
album performer
|
||||||
|
.TP
|
||||||
|
.B %S
|
||||||
|
album songwriter
|
||||||
|
.TP
|
||||||
|
.B %T
|
||||||
|
album title
|
||||||
|
.TP
|
||||||
|
.B %U
|
||||||
|
album UPC/EAN
|
||||||
|
.PP
|
||||||
|
Track:
|
||||||
|
.TP
|
||||||
|
.B %a
|
||||||
|
track arranger
|
||||||
|
.TP
|
||||||
|
.B %c
|
||||||
|
track composer
|
||||||
|
.TP
|
||||||
|
.B %g
|
||||||
|
track genre
|
||||||
|
.TP
|
||||||
|
.B %i
|
||||||
|
track ISRC
|
||||||
|
.TP
|
||||||
|
.B %m
|
||||||
|
track message
|
||||||
|
.TP
|
||||||
|
.B %n
|
||||||
|
track number
|
||||||
|
.TP
|
||||||
|
.B %p
|
||||||
|
track perfomer
|
||||||
|
.TP
|
||||||
|
.B %t
|
||||||
|
track title
|
||||||
|
.TP
|
||||||
|
.B %u
|
||||||
|
track ISRC (CD-TEXT)
|
||||||
|
.PP
|
||||||
|
Any other %<character> is expanded to that character. For example, %% expands to a literal `%'.
|
||||||
|
.SH NOTES
|
||||||
|
If no files are specified, stdin is used. If a filename is specified and the format is not specified, the format will be set based on a ".cue" or ".toc" suffix.
|
||||||
|
.SH AUTHOR
|
||||||
|
Svend Sorensen <sorensen@freeshell.org>
|
||||||
|
.SH "SEE ALSO"
|
||||||
|
cueconvert(1),
|
||||||
|
cuebreakpoints(1)
|
||||||
52
test/complete.cue
Normal file
52
test/complete.cue
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
CATALOG 1234567890123
|
||||||
|
TITLE "Album Title"
|
||||||
|
PERFORMER "Album Performer"
|
||||||
|
SONGWRITER "Album Songwriter"
|
||||||
|
COMPOSER "Album Composer"
|
||||||
|
ARRANGER "Album Arranger"
|
||||||
|
MESSAGE "Album Message"
|
||||||
|
UPC_EAN "Album UPC/EAN"
|
||||||
|
|
||||||
|
FILE "track1.wav" WAVE
|
||||||
|
TRACK 01 AUDIO
|
||||||
|
TITLE "Track 1 Title"
|
||||||
|
PERFORMER "Track 1 Performer"
|
||||||
|
SONGWRITER "Track 1 Songwriter"
|
||||||
|
COMPOSER "Track 1 Composer"
|
||||||
|
ARRANGER "Track 1 Arranger"
|
||||||
|
MESSAGE "Track 1 Message"
|
||||||
|
ISRC "CC-OWNR-99-12345"
|
||||||
|
ISRC CCOWNR9912345
|
||||||
|
FLAGS PRE DCP 4CH SCMS
|
||||||
|
INDEX 01 00:00:00
|
||||||
|
|
||||||
|
REM zero data pregap with index pregap
|
||||||
|
TRACK 02 AUDIO
|
||||||
|
TITLE "Track 2 Title"
|
||||||
|
PERFORMER "Track 2 Performer"
|
||||||
|
SONGWRITER "Track 2 Songwriter"
|
||||||
|
COMPOSER "Track 2 Composer"
|
||||||
|
ARRANGER "Track 2 Arranger"
|
||||||
|
MESSAGE "Track 2 Message"
|
||||||
|
ISRC "CC-OWNR-99-12345"
|
||||||
|
ISRC CCOWNR9912345
|
||||||
|
FLAGS PRE DCP 4CH SCMS
|
||||||
|
PREGAP 00:00:02
|
||||||
|
INDEX 00 05:00:00
|
||||||
|
INDEX 01 05:02:00
|
||||||
|
|
||||||
|
REM new file
|
||||||
|
FILE "track3.wav" WAVE
|
||||||
|
TRACK 03 AUDIO
|
||||||
|
TITLE "Track 3 Title"
|
||||||
|
PERFORMER "Track 3 Performer"
|
||||||
|
SONGWRITER "Track 3 Songwriter"
|
||||||
|
COMPOSER "Track 3 Composer"
|
||||||
|
ARRANGER "Track 3 Arranger"
|
||||||
|
MESSAGE "Track 3 Message"
|
||||||
|
ISRC "CC-OWNR-99-12345"
|
||||||
|
ISRC CCOWNR9912345
|
||||||
|
FLAGS PRE DCP 4CH SCMS
|
||||||
|
INDEX 00 00:00:00
|
||||||
|
INDEX 01 00:03:00
|
||||||
|
POSTGAP 00:00:02
|
||||||
0
test/empty.cue
Normal file
0
test/empty.cue
Normal file
0
test/empty.toc
Normal file
0
test/empty.toc
Normal file
60
test/errors.cue
Normal file
60
test/errors.cue
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
CATALOG 0000000000000
|
||||||
|
PERFORMER "Marvin Gaye and Freddie Jackson"
|
||||||
|
TITLE "On Tour - Disc 1"
|
||||||
|
FILE "marvin_gaye_and_freddie_jackson-2001-on_tour-cd1-kmf.wav" WAVE
|
||||||
|
TRACK 01 AUDIO
|
||||||
|
TITLE "I Heard It Through The Grapevine"
|
||||||
|
PERFORMER "Marvin Gaye and Freddie Jackson"
|
||||||
|
FLAGS DCP
|
||||||
|
INDEX 01 00:00:00
|
||||||
|
TRACK 02 AUDIO
|
||||||
|
TITLE "Come Get To This"
|
||||||
|
PERFORMER "Marvin Gaye and Freddie Jackson"
|
||||||
|
FLAGS DCP
|
||||||
|
INDEX 01 03:57:64
|
||||||
|
TRACK 03 AUDIO
|
||||||
|
TITLE "Let's Get In On"
|
||||||
|
PERFORMER "Marvin Gaye and Freddie Jackson"
|
||||||
|
FLAGS DCP
|
||||||
|
INDEX 01 07:34:61
|
||||||
|
TRACK 04 AUDIO
|
||||||
|
TITLE "God Is My Friend"
|
||||||
|
PERFORMER "Marvin Gaye and Freddie Jackson"
|
||||||
|
FLAGS DCP
|
||||||
|
INDEX 01 12:56:41
|
||||||
|
TRACK 05 AUDIO
|
||||||
|
TITLE "What's Going On"
|
||||||
|
PERFORMER "Marvin Gaye and Freddie Jackson"
|
||||||
|
FLAGS DCP
|
||||||
|
INDEX 01 15:11:54
|
||||||
|
TRACK 06 AUDIO
|
||||||
|
TITLE "Inner City Blues"
|
||||||
|
PERFORMER "Marvin Gaye and Freddie Jackson"
|
||||||
|
FLAGS DCP
|
||||||
|
INDEX 01 19:10:33
|
||||||
|
TRACK 07 AUDIO
|
||||||
|
TITLE "Joy"
|
||||||
|
PERFORMER "Marvin Gaye and Freddie Jackson"
|
||||||
|
FLAGS DCP
|
||||||
|
INDEX 00 24:32:65
|
||||||
|
INDEX 01 24:34:35
|
||||||
|
TRACK 08 AUDIO
|
||||||
|
TITLE "Medley (Ain't Nothing Like The Real Thing...)"
|
||||||
|
PERFORMER "Marvin Gaye and Freddie Jackson"
|
||||||
|
FLAGS DCP
|
||||||
|
INDEX 01 29:03:56
|
||||||
|
TRACK 09 AUDIO
|
||||||
|
TITLE "Rockin' After Midnight"
|
||||||
|
PERFORMER "Marvin Gaye and Freddie Jackson"
|
||||||
|
FLAGS DCP
|
||||||
|
INDEX 01 37:23:42
|
||||||
|
TRACK 10 AUDIO
|
||||||
|
TITLE "Distant Lover"
|
||||||
|
PERFORMER "Marvin Gaye and Freddie Jackson"
|
||||||
|
FLAGS DCP
|
||||||
|
INDEX 01 46:21:21
|
||||||
|
TRACK 11 AUDIO
|
||||||
|
TITLE "Sexual Healing"
|
||||||
|
PERFORMER "Marvin Gaye and Freddie Jackson"
|
||||||
|
FLAGS DCP
|
||||||
|
INDEX 01 56:00:42
|
||||||
336
test/test001.toc
Normal file
336
test/test001.toc
Normal file
@@ -0,0 +1,336 @@
|
|||||||
|
CD_DA
|
||||||
|
|
||||||
|
CATALOG "0008811307523"
|
||||||
|
|
||||||
|
CD_TEXT {
|
||||||
|
LANGUAGE_MAP {
|
||||||
|
0: 9
|
||||||
|
}
|
||||||
|
LANGUAGE 0 {
|
||||||
|
TITLE "Red Hot + Riot"
|
||||||
|
PERFORMER "Various Artists"
|
||||||
|
MESSAGE "Net Profits from the sale of this album will suport Red Jot's AIDS prevention and relief efforts in Africa and around the world. Produced By: John Carlin, Paul Heck and Andr\351s Levin"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Track 1
|
||||||
|
TRACK AUDIO
|
||||||
|
NO COPY
|
||||||
|
NO PRE_EMPHASIS
|
||||||
|
TWO_CHANNEL_AUDIO
|
||||||
|
ISRC "USRH20214001"
|
||||||
|
CD_TEXT {
|
||||||
|
LANGUAGE 0 {
|
||||||
|
TITLE "[intro] Fela Mentality"
|
||||||
|
PERFORMER "Mix Master Mike and Mario Caldato, Jr."
|
||||||
|
MESSAGE ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FILE "data.bin" 0 01:09:45
|
||||||
|
|
||||||
|
|
||||||
|
// Track 2
|
||||||
|
TRACK AUDIO
|
||||||
|
NO COPY
|
||||||
|
NO PRE_EMPHASIS
|
||||||
|
TWO_CHANNEL_AUDIO
|
||||||
|
ISRC "USRH20214002"
|
||||||
|
CD_TEXT {
|
||||||
|
LANGUAGE 0 {
|
||||||
|
TITLE "Kalakuta Show"
|
||||||
|
PERFORMER "Mix Master Mike, Lateef, and The Gift Of Gab"
|
||||||
|
MESSAGE ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FILE "data.bin" 01:09:45 02:31:17
|
||||||
|
|
||||||
|
|
||||||
|
// Track 3
|
||||||
|
TRACK AUDIO
|
||||||
|
NO COPY
|
||||||
|
NO PRE_EMPHASIS
|
||||||
|
TWO_CHANNEL_AUDIO
|
||||||
|
ISRC "USRH20214003"
|
||||||
|
CD_TEXT {
|
||||||
|
LANGUAGE 0 {
|
||||||
|
TITLE "[interlude] Live at Kalakuta"
|
||||||
|
PERFORMER "Posma, Remedies, Taiwo, Segun, Tosin, Andres Levin"
|
||||||
|
MESSAGE ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FILE "data.bin" 03:40:62 00:32:15
|
||||||
|
|
||||||
|
|
||||||
|
// Track 4
|
||||||
|
TRACK AUDIO
|
||||||
|
NO COPY
|
||||||
|
NO PRE_EMPHASIS
|
||||||
|
TWO_CHANNEL_AUDIO
|
||||||
|
ISRC "USRH20214004"
|
||||||
|
CD_TEXT {
|
||||||
|
LANGUAGE 0 {
|
||||||
|
TITLE "Shuffering and Shmiling"
|
||||||
|
PERFORMER "Dead Prez, Jorge Ben Jor, Talib Kweli, Bilal and Postive Force"
|
||||||
|
MESSAGE ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FILE "data.bin" 04:13:02 07:50:05
|
||||||
|
|
||||||
|
|
||||||
|
// Track 5
|
||||||
|
TRACK AUDIO
|
||||||
|
NO COPY
|
||||||
|
NO PRE_EMPHASIS
|
||||||
|
TWO_CHANNEL_AUDIO
|
||||||
|
ISRC "USRH20214005"
|
||||||
|
CD_TEXT {
|
||||||
|
LANGUAGE 0 {
|
||||||
|
TITLE "[interlude] Gimme Shit"
|
||||||
|
PERFORMER "Mix Master Mike and Mario Caldato, Jr."
|
||||||
|
MESSAGE ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FILE "data.bin" 12:03:07 00:31:43
|
||||||
|
|
||||||
|
|
||||||
|
// Track 6
|
||||||
|
TRACK AUDIO
|
||||||
|
NO COPY
|
||||||
|
NO PRE_EMPHASIS
|
||||||
|
TWO_CHANNEL_AUDIO
|
||||||
|
ISRC "USRH20214006"
|
||||||
|
CD_TEXT {
|
||||||
|
LANGUAGE 0 {
|
||||||
|
TITLE "Water Get No Enemy [intro]"
|
||||||
|
PERFORMER "D'Angelo and Femi Kuti"
|
||||||
|
MESSAGE ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FILE "data.bin" 12:34:50 04:04:30
|
||||||
|
|
||||||
|
|
||||||
|
// Track 7
|
||||||
|
TRACK AUDIO
|
||||||
|
NO COPY
|
||||||
|
NO PRE_EMPHASIS
|
||||||
|
TWO_CHANNEL_AUDIO
|
||||||
|
ISRC "USRH20214007"
|
||||||
|
CD_TEXT {
|
||||||
|
LANGUAGE 0 {
|
||||||
|
TITLE "Water Get No Enemy"
|
||||||
|
PERFORMER "D'Angelo, Femi Kuti, and Macy Gray featuring Roy Hargrove, Nile Rodgers, The Soultronics, and Positive Force"
|
||||||
|
MESSAGE ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FILE "data.bin" 16:39:05 06:05:70
|
||||||
|
|
||||||
|
|
||||||
|
// Track 8
|
||||||
|
TRACK AUDIO
|
||||||
|
NO COPY
|
||||||
|
NO PRE_EMPHASIS
|
||||||
|
TWO_CHANNEL_AUDIO
|
||||||
|
ISRC "USRH20214007"
|
||||||
|
CD_TEXT {
|
||||||
|
LANGUAGE 0 {
|
||||||
|
TITLE "Gentleman"
|
||||||
|
PERFORMER "Meshell Ndegeocello and Yerba Buena! featuring Ron Blake"
|
||||||
|
MESSAGE ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FILE "data.bin" 22:45:00 07:02:70
|
||||||
|
|
||||||
|
|
||||||
|
// Track 9
|
||||||
|
TRACK AUDIO
|
||||||
|
NO COPY
|
||||||
|
NO PRE_EMPHASIS
|
||||||
|
TWO_CHANNEL_AUDIO
|
||||||
|
ISRC "USRH20214009"
|
||||||
|
CD_TEXT {
|
||||||
|
LANGUAGE 0 {
|
||||||
|
TITLE "Tears and Sorrow"
|
||||||
|
PERFORMER "Common, Meshell Ndegeocello, and Djelimady Tounkara"
|
||||||
|
MESSAGE ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FILE "data.bin" 29:47:70 01:31:27
|
||||||
|
|
||||||
|
|
||||||
|
// Track 10
|
||||||
|
TRACK AUDIO
|
||||||
|
NO COPY
|
||||||
|
NO PRE_EMPHASIS
|
||||||
|
TWO_CHANNEL_AUDIO
|
||||||
|
ISRC "USRH20214010"
|
||||||
|
CD_TEXT {
|
||||||
|
LANGUAGE 0 {
|
||||||
|
TITLE "Shakara Lady (part one)"
|
||||||
|
PERFORMER "Cheikh Lo"
|
||||||
|
MESSAGE ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FILE "data.bin" 31:19:22 02:20:05
|
||||||
|
|
||||||
|
|
||||||
|
// Track 11
|
||||||
|
TRACK AUDIO
|
||||||
|
NO COPY
|
||||||
|
NO PRE_EMPHASIS
|
||||||
|
TWO_CHANNEL_AUDIO
|
||||||
|
ISRC "USRH20214011"
|
||||||
|
CD_TEXT {
|
||||||
|
LANGUAGE 0 {
|
||||||
|
TITLE "Shakara Lady (part two)"
|
||||||
|
PERFORMER "Cheikh Lo, Les Nubians, and Manu Dibango featuring Chateau Flight"
|
||||||
|
MESSAGE ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FILE "data.bin" 33:39:27 04:47:13
|
||||||
|
|
||||||
|
|
||||||
|
// Track 12
|
||||||
|
TRACK AUDIO
|
||||||
|
NO COPY
|
||||||
|
NO PRE_EMPHASIS
|
||||||
|
TWO_CHANNEL_AUDIO
|
||||||
|
ISRC "USRH20214012"
|
||||||
|
CD_TEXT {
|
||||||
|
LANGUAGE 0 {
|
||||||
|
TITLE "[interlude] Don't Worry About My Mouth-O"
|
||||||
|
PERFORMER "Monoaural"
|
||||||
|
MESSAGE ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FILE "data.bin" 38:26:40 01:03:32
|
||||||
|
|
||||||
|
|
||||||
|
// Track 13
|
||||||
|
TRACK AUDIO
|
||||||
|
NO COPY
|
||||||
|
NO PRE_EMPHASIS
|
||||||
|
TWO_CHANNEL_AUDIO
|
||||||
|
ISRC "USRH20214013"
|
||||||
|
CD_TEXT {
|
||||||
|
LANGUAGE 0 {
|
||||||
|
TITLE "Zombie (part one)"
|
||||||
|
PERFORMER "Bugz in the Attic featuring Wunmi"
|
||||||
|
MESSAGE ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FILE "data.bin" 39:29:72 02:51:70
|
||||||
|
|
||||||
|
|
||||||
|
// Track 14
|
||||||
|
TRACK AUDIO
|
||||||
|
NO COPY
|
||||||
|
NO PRE_EMPHASIS
|
||||||
|
TWO_CHANNEL_AUDIO
|
||||||
|
ISRC "USRH20214014"
|
||||||
|
CD_TEXT {
|
||||||
|
LANGUAGE 0 {
|
||||||
|
TITLE "Zombie (part two)"
|
||||||
|
PERFORMER "Nile Rodgers, Roy Hargrove, and Money Mark"
|
||||||
|
MESSAGE ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FILE "data.bin" 42:21:67 04:27:38
|
||||||
|
|
||||||
|
|
||||||
|
// Track 15
|
||||||
|
TRACK AUDIO
|
||||||
|
NO COPY
|
||||||
|
NO PRE_EMPHASIS
|
||||||
|
TWO_CHANNEL_AUDIO
|
||||||
|
ISRC "USRH20214015"
|
||||||
|
CD_TEXT {
|
||||||
|
LANGUAGE 0 {
|
||||||
|
TITLE "No Agreement"
|
||||||
|
PERFORMER "Tony Allen, Res, Ray Lema, Baaba Maal, Postive Black Soul, and Archie Shepp"
|
||||||
|
MESSAGE ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FILE "data.bin" 46:49:30 08:12:02
|
||||||
|
|
||||||
|
|
||||||
|
// Track 16
|
||||||
|
TRACK AUDIO
|
||||||
|
NO COPY
|
||||||
|
NO PRE_EMPHASIS
|
||||||
|
TWO_CHANNEL_AUDIO
|
||||||
|
ISRC "USRH20214015"
|
||||||
|
CD_TEXT {
|
||||||
|
LANGUAGE 0 {
|
||||||
|
TITLE "So Be It"
|
||||||
|
PERFORMER "Kelis"
|
||||||
|
MESSAGE ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FILE "data.bin" 55:01:32 03:52:15
|
||||||
|
|
||||||
|
|
||||||
|
// Track 17
|
||||||
|
TRACK AUDIO
|
||||||
|
NO COPY
|
||||||
|
NO PRE_EMPHASIS
|
||||||
|
TWO_CHANNEL_AUDIO
|
||||||
|
ISRC "USRH20214016"
|
||||||
|
CD_TEXT {
|
||||||
|
LANGUAGE 0 {
|
||||||
|
TITLE "[interlude] This is an Ashanti Proverb"
|
||||||
|
PERFORMER "Monoaural"
|
||||||
|
MESSAGE ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FILE "data.bin" 58:53:47 00:09:58
|
||||||
|
|
||||||
|
|
||||||
|
// Track 18
|
||||||
|
TRACK AUDIO
|
||||||
|
NO COPY
|
||||||
|
NO PRE_EMPHASIS
|
||||||
|
TWO_CHANNEL_AUDIO
|
||||||
|
ISRC "GBBBM0002184"
|
||||||
|
CD_TEXT {
|
||||||
|
LANGUAGE 0 {
|
||||||
|
TITLE "By Your Side (Cottonbelly's Fola Mix Edit)"
|
||||||
|
PERFORMER "Sade"
|
||||||
|
MESSAGE ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FILE "data.bin" 59:03:30 04:39:67
|
||||||
|
|
||||||
|
|
||||||
|
// Track 19
|
||||||
|
TRACK AUDIO RW_RAW
|
||||||
|
COPY
|
||||||
|
PRE_EMPHASIS
|
||||||
|
TWO_CHANNEL_AUDIO
|
||||||
|
ISRC "USRH20214019"
|
||||||
|
CD_TEXT {
|
||||||
|
LANGUAGE 0 {
|
||||||
|
TITLE "Colonial Mentality"
|
||||||
|
PERFORMER "Yerba Buena! and Lenine"
|
||||||
|
MESSAGE ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FILE "data.bin" 63:43:22 01:34:10
|
||||||
|
START 00:00:01
|
||||||
|
INDEX 00:10:01
|
||||||
|
|
||||||
|
|
||||||
|
// Track 20
|
||||||
|
TRACK AUDIO
|
||||||
|
NO COPY
|
||||||
|
NO PRE_EMPHASIS
|
||||||
|
TWO_CHANNEL_AUDIO
|
||||||
|
ISRC "USRH20214020"
|
||||||
|
CD_TEXT {
|
||||||
|
LANGUAGE 0 {
|
||||||
|
TITLE "Trouble Sleep Yanga Wake Am"
|
||||||
|
PERFORMER "Baaba Maal and Taj Mahal featuring Kaouding Cissoko and Antibalas"
|
||||||
|
MESSAGE ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FILE "data.bin" 65:17:32 10:38:20
|
||||||
|
|
||||||
208
test/test002.toc
Normal file
208
test/test002.toc
Normal file
@@ -0,0 +1,208 @@
|
|||||||
|
CD_DA
|
||||||
|
|
||||||
|
CATALOG "0075994590127"
|
||||||
|
CD_TEXT {
|
||||||
|
LANGUAGE_MAP {
|
||||||
|
0: 9
|
||||||
|
}
|
||||||
|
LANGUAGE 0 {
|
||||||
|
TITLE "Jagged Little Pill"
|
||||||
|
PERFORMER "Alanis Morissette"
|
||||||
|
MESSAGE "1995"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Track 1
|
||||||
|
TRACK AUDIO
|
||||||
|
NO COPY
|
||||||
|
NO PRE_EMPHASIS
|
||||||
|
TWO_CHANNEL_AUDIO
|
||||||
|
CD_TEXT {
|
||||||
|
LANGUAGE 0 {
|
||||||
|
TITLE "All I Really Want"
|
||||||
|
PERFORMER "Alanis Morissette"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SILENCE 00:00:32
|
||||||
|
FILE "alanis_morissette-1998-jagged_little_pill-kmf.wav" 0 04:43:28
|
||||||
|
START 00:00:32
|
||||||
|
|
||||||
|
|
||||||
|
// Track 2
|
||||||
|
TRACK AUDIO
|
||||||
|
NO COPY
|
||||||
|
NO PRE_EMPHASIS
|
||||||
|
TWO_CHANNEL_AUDIO
|
||||||
|
CD_TEXT {
|
||||||
|
LANGUAGE 0 {
|
||||||
|
TITLE "You Oughta Know"
|
||||||
|
PERFORMER "Alanis Morissette"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FILE "alanis_morissette-1998-jagged_little_pill-kmf.wav" 04:43:28 04:09:00
|
||||||
|
START 00:01:20
|
||||||
|
|
||||||
|
|
||||||
|
// Track 3
|
||||||
|
TRACK AUDIO
|
||||||
|
NO COPY
|
||||||
|
NO PRE_EMPHASIS
|
||||||
|
TWO_CHANNEL_AUDIO
|
||||||
|
CD_TEXT {
|
||||||
|
LANGUAGE 0 {
|
||||||
|
TITLE "Perfect"
|
||||||
|
PERFORMER "Alanis Morissette"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FILE "alanis_morissette-1998-jagged_little_pill-kmf.wav" 08:52:28 03:07:65
|
||||||
|
START 00:01:35
|
||||||
|
|
||||||
|
|
||||||
|
// Track 4
|
||||||
|
TRACK AUDIO
|
||||||
|
NO COPY
|
||||||
|
NO PRE_EMPHASIS
|
||||||
|
TWO_CHANNEL_AUDIO
|
||||||
|
CD_TEXT {
|
||||||
|
LANGUAGE 0 {
|
||||||
|
TITLE "Hand in My Pocket"
|
||||||
|
PERFORMER "Alanis Morissette"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FILE "alanis_morissette-1998-jagged_little_pill-kmf.wav" 12:00:18 03:40:35
|
||||||
|
START 00:01:37
|
||||||
|
|
||||||
|
|
||||||
|
// Track 5
|
||||||
|
TRACK AUDIO
|
||||||
|
NO COPY
|
||||||
|
NO PRE_EMPHASIS
|
||||||
|
TWO_CHANNEL_AUDIO
|
||||||
|
CD_TEXT {
|
||||||
|
LANGUAGE 0 {
|
||||||
|
TITLE "Right Through You"
|
||||||
|
PERFORMER "Alanis Morissette"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FILE "alanis_morissette-1998-jagged_little_pill-kmf.wav" 15:40:53 02:57:00
|
||||||
|
START 00:02:55
|
||||||
|
|
||||||
|
|
||||||
|
// Track 6
|
||||||
|
TRACK AUDIO
|
||||||
|
NO COPY
|
||||||
|
NO PRE_EMPHASIS
|
||||||
|
TWO_CHANNEL_AUDIO
|
||||||
|
CD_TEXT {
|
||||||
|
LANGUAGE 0 {
|
||||||
|
TITLE "Forgiven"
|
||||||
|
PERFORMER "Alanis Morissette"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FILE "alanis_morissette-1998-jagged_little_pill-kmf.wav" 18:37:53 05:00:02
|
||||||
|
START 00:01:42
|
||||||
|
|
||||||
|
|
||||||
|
// Track 7
|
||||||
|
TRACK AUDIO
|
||||||
|
NO COPY
|
||||||
|
NO PRE_EMPHASIS
|
||||||
|
TWO_CHANNEL_AUDIO
|
||||||
|
CD_TEXT {
|
||||||
|
LANGUAGE 0 {
|
||||||
|
TITLE "You Learn"
|
||||||
|
PERFORMER "Alanis Morissette"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FILE "alanis_morissette-1998-jagged_little_pill-kmf.wav" 23:37:55 04:00:33
|
||||||
|
START 00:01:60
|
||||||
|
|
||||||
|
|
||||||
|
// Track 8
|
||||||
|
TRACK AUDIO
|
||||||
|
NO COPY
|
||||||
|
NO PRE_EMPHASIS
|
||||||
|
TWO_CHANNEL_AUDIO
|
||||||
|
CD_TEXT {
|
||||||
|
LANGUAGE 0 {
|
||||||
|
TITLE "Head Over Feet"
|
||||||
|
PERFORMER "Alanis Morissette"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FILE "alanis_morissette-1998-jagged_little_pill-kmf.wav" 27:38:13 04:25:40
|
||||||
|
START 00:01:00
|
||||||
|
|
||||||
|
|
||||||
|
// Track 9
|
||||||
|
TRACK AUDIO
|
||||||
|
NO COPY
|
||||||
|
NO PRE_EMPHASIS
|
||||||
|
TWO_CHANNEL_AUDIO
|
||||||
|
CD_TEXT {
|
||||||
|
LANGUAGE 0 {
|
||||||
|
TITLE "Mary Jane"
|
||||||
|
PERFORMER "Alanis Morissette"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FILE "alanis_morissette-1998-jagged_little_pill-kmf.wav" 32:03:53 04:41:57
|
||||||
|
START 00:02:55
|
||||||
|
|
||||||
|
|
||||||
|
// Track 10
|
||||||
|
TRACK AUDIO
|
||||||
|
NO COPY
|
||||||
|
NO PRE_EMPHASIS
|
||||||
|
TWO_CHANNEL_AUDIO
|
||||||
|
CD_TEXT {
|
||||||
|
LANGUAGE 0 {
|
||||||
|
TITLE "Ironic"
|
||||||
|
PERFORMER "Alanis Morissette"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FILE "alanis_morissette-1998-jagged_little_pill-kmf.wav" 36:45:35 03:50:03
|
||||||
|
START 00:01:45
|
||||||
|
|
||||||
|
|
||||||
|
// Track 11
|
||||||
|
TRACK AUDIO
|
||||||
|
NO COPY
|
||||||
|
NO PRE_EMPHASIS
|
||||||
|
TWO_CHANNEL_AUDIO
|
||||||
|
CD_TEXT {
|
||||||
|
LANGUAGE 0 {
|
||||||
|
TITLE "Not the Doctor"
|
||||||
|
PERFORMER "Alanis Morissette"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FILE "alanis_morissette-1998-jagged_little_pill-kmf.wav" 40:35:38 03:46:25
|
||||||
|
START 00:01:20
|
||||||
|
|
||||||
|
|
||||||
|
// Track 12
|
||||||
|
TRACK AUDIO
|
||||||
|
NO COPY
|
||||||
|
NO PRE_EMPHASIS
|
||||||
|
TWO_CHANNEL_AUDIO
|
||||||
|
CD_TEXT {
|
||||||
|
LANGUAGE 0 {
|
||||||
|
TITLE "Wake Up"
|
||||||
|
PERFORMER "Alanis Morissette"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FILE "alanis_morissette-1998-jagged_little_pill-kmf.wav" 44:21:63 04:56:03
|
||||||
|
START 00:02:40
|
||||||
|
|
||||||
|
|
||||||
|
// Track 13
|
||||||
|
TRACK AUDIO
|
||||||
|
NO COPY
|
||||||
|
NO PRE_EMPHASIS
|
||||||
|
TWO_CHANNEL_AUDIO
|
||||||
|
CD_TEXT {
|
||||||
|
LANGUAGE 0 {
|
||||||
|
TITLE "You Oughta Know (Alternate Take)"
|
||||||
|
PERFORMER "Alanis Morissette"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FILE "alanis_morissette-1998-jagged_little_pill-kmf.wav" 49:17:66 08:13:19
|
||||||
|
START 00:00:22
|
||||||
39
tools/Makefile
Normal file
39
tools/Makefile
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
CPPFLAGS+= -I../lib
|
||||||
|
LDFLAGS+= -L../lib
|
||||||
|
LDLIBS+= -lcuefile
|
||||||
|
|
||||||
|
TARGETS= cuebreakpoints cueconvert cueprint
|
||||||
|
|
||||||
|
all: $(TARGETS)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(TARGETS)
|
||||||
|
rm -f *.o
|
||||||
|
|
||||||
|
INSTALL= install
|
||||||
|
INSTALL_PROGRAM= $(INSTALL)
|
||||||
|
INSTALL_DATA= $(INSTALL) -m 644
|
||||||
|
|
||||||
|
prefix= /usr/local
|
||||||
|
exec_prefix= $(prefix)
|
||||||
|
bindir= $(exec_prefix)/bin
|
||||||
|
DESTDIR=
|
||||||
|
|
||||||
|
install: all
|
||||||
|
$(INSTALL) -d $(DESTDIR)$(bindir)
|
||||||
|
for i in $(TARGETS) ; do \
|
||||||
|
$(INSTALL_PROGRAM) $$i $(DESTDIR)$(bindir)/$$i ; \
|
||||||
|
done
|
||||||
|
|
||||||
|
uninstall:
|
||||||
|
-for i in $(TARGETS) ; do \
|
||||||
|
rm -f $(DESTDIR)$(bindir)/$$i ; \
|
||||||
|
done
|
||||||
|
|
||||||
|
# dependancies
|
||||||
|
# generated by `gcc -MM *.c'
|
||||||
|
|
||||||
|
cuebreakpoints.o: cuebreakpoints.c ../lib/cuefile.h ../lib/cd.h \
|
||||||
|
../lib/cdtext.h
|
||||||
|
cueconvert.o: cueconvert.c ../lib/cuefile.h ../lib/cd.h ../lib/cdtext.h
|
||||||
|
cueprint.o: cueprint.c ../lib/cuefile.h ../lib/cd.h ../lib/cdtext.h
|
||||||
109
tools/cuebreakpoints.c
Normal file
109
tools/cuebreakpoints.c
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
/*
|
||||||
|
* cuebreakpoints.c -- print track break points
|
||||||
|
*
|
||||||
|
* Copyright (C) 2004 Svend Sorensen
|
||||||
|
* For license terms, see the file COPYING in this distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "cuefile.h"
|
||||||
|
#include "time.h"
|
||||||
|
|
||||||
|
char *progname;
|
||||||
|
|
||||||
|
void usage (int status)
|
||||||
|
{
|
||||||
|
if (0 == status) {
|
||||||
|
fprintf(stdout, "%s: usage: cuebreakpoints [-h] [-i cue|toc] [file...]\n", progname);
|
||||||
|
fputs("\
|
||||||
|
\n\
|
||||||
|
OPTIONS\n\
|
||||||
|
-h print usage\n\
|
||||||
|
-i cue|toc set format of file(s)\n\
|
||||||
|
", stdout);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "%s: syntax error\n", progname);
|
||||||
|
fprintf(stderr, "run `%s -h' for usage\n", progname);
|
||||||
|
}
|
||||||
|
|
||||||
|
exit (status);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_m_ss_ff (long frame)
|
||||||
|
{
|
||||||
|
int m, s, f;
|
||||||
|
|
||||||
|
time_frame_to_msf(frame, &m, &s, &f);
|
||||||
|
printf ("%d:%02d.%02d\n", m, s, f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_breaks (Cd *cd)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
long b;
|
||||||
|
Track *track;
|
||||||
|
|
||||||
|
for (i = 1; i < cd_get_ntrack(cd); i++) {
|
||||||
|
track = cd_get_track(cd, i);
|
||||||
|
/* don't print zero indexes */
|
||||||
|
b = track_get_start(track) + track_get_index(track, 1) - track_get_zero_pre(track);
|
||||||
|
if (0 != b)
|
||||||
|
print_m_ss_ff(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int breaks (char *name, int format)
|
||||||
|
{
|
||||||
|
Cd *cd = NULL;
|
||||||
|
|
||||||
|
if (NULL == (cd = cf_parse(name, &format))) {
|
||||||
|
fprintf(stderr, "%s: input file error\n", name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
print_breaks(cd);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main (int argc, char **argv)
|
||||||
|
{
|
||||||
|
int format = UNKNOWN;
|
||||||
|
|
||||||
|
/* option variables */
|
||||||
|
char c;
|
||||||
|
/* getopt() variables */
|
||||||
|
extern char *optarg;
|
||||||
|
extern int optind;
|
||||||
|
|
||||||
|
progname = *argv;
|
||||||
|
|
||||||
|
while (-1 != (c = getopt(argc, argv, "hi:"))) {
|
||||||
|
switch (c) {
|
||||||
|
case 'h':
|
||||||
|
usage(0);
|
||||||
|
break;
|
||||||
|
case 'i':
|
||||||
|
if (0 == strcmp("cue", optarg))
|
||||||
|
format = CUE;
|
||||||
|
else if (0 == strcmp("toc", optarg))
|
||||||
|
format = TOC;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
usage(1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (optind == argc) {
|
||||||
|
breaks("-", format);
|
||||||
|
} else {
|
||||||
|
for (; optind < argc; optind++)
|
||||||
|
breaks(argv[optind], format);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
108
tools/cueconvert.c
Normal file
108
tools/cueconvert.c
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
/*
|
||||||
|
* cueconvert.c -- convert between cue/toc formats
|
||||||
|
*
|
||||||
|
* Copyright (C) 2004 Svend Sorensen
|
||||||
|
* For license terms, see the file COPYING in this distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "cuefile.h"
|
||||||
|
|
||||||
|
char *progname;
|
||||||
|
|
||||||
|
void usage (int status)
|
||||||
|
{
|
||||||
|
if (0 == status) {
|
||||||
|
fprintf(stdout, "%s: usage: cueconvert [-h] [-i cue|toc] [-o cue|toc] [infile [outfile]]\n", progname);
|
||||||
|
fputs("\
|
||||||
|
\n\
|
||||||
|
OPTIONS\n\
|
||||||
|
-h print usage\n\
|
||||||
|
-i cue|toc set format of input file\n\
|
||||||
|
-o cue|toc set format of output file\n\
|
||||||
|
", stdout);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "%s: syntax error\n", progname);
|
||||||
|
fprintf(stderr, "run `%s -h' for usage\n", progname);
|
||||||
|
}
|
||||||
|
|
||||||
|
exit (status);
|
||||||
|
}
|
||||||
|
|
||||||
|
int convert (char *iname, int iformat, char *oname, int oformat)
|
||||||
|
{
|
||||||
|
Cd *cd = NULL;
|
||||||
|
|
||||||
|
if (NULL == (cd = cf_parse(iname, &iformat))) {
|
||||||
|
fprintf(stderr, "input file error\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (UNKNOWN == oformat) {
|
||||||
|
/* first use file suffix */
|
||||||
|
if (UNKNOWN == (oformat = cf_format_from_suffix(oname))) {
|
||||||
|
/* then use opposite of input format */
|
||||||
|
switch(iformat) {
|
||||||
|
case CUE:
|
||||||
|
oformat = TOC;
|
||||||
|
break;
|
||||||
|
case TOC:
|
||||||
|
oformat = CUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return cf_print(oname, &oformat, cd);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main (int argc, char **argv)
|
||||||
|
{
|
||||||
|
int iformat = UNKNOWN;
|
||||||
|
int oformat = UNKNOWN;
|
||||||
|
/* option variables */
|
||||||
|
char c;
|
||||||
|
/* getopt() variables */
|
||||||
|
extern char *optarg;
|
||||||
|
extern int optind;
|
||||||
|
|
||||||
|
progname = *argv;
|
||||||
|
|
||||||
|
while (-1 != (c = getopt(argc, argv, "hi:o:"))) {
|
||||||
|
switch (c) {
|
||||||
|
case 'h':
|
||||||
|
usage(0);
|
||||||
|
break;
|
||||||
|
case 'i':
|
||||||
|
if (0 == strcmp("cue", optarg))
|
||||||
|
iformat = CUE;
|
||||||
|
else if (0 == strcmp("toc", optarg))
|
||||||
|
iformat = TOC;
|
||||||
|
break;
|
||||||
|
case 'o':
|
||||||
|
if (0 == strcmp("cue", optarg))
|
||||||
|
oformat = CUE;
|
||||||
|
else if (0 == strcmp("toc", optarg))
|
||||||
|
oformat = TOC;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
usage(1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (optind == argc) {
|
||||||
|
convert("-", iformat, "-", oformat);
|
||||||
|
} else if (optind == argc - 1) {
|
||||||
|
convert(argv[optind], iformat, "-", oformat);
|
||||||
|
} else if (optind == argc - 2) {
|
||||||
|
convert(argv[optind], iformat, argv[optind + 1], oformat);
|
||||||
|
} else {
|
||||||
|
usage(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
240
tools/cueprint.c
Normal file
240
tools/cueprint.c
Normal file
@@ -0,0 +1,240 @@
|
|||||||
|
/*
|
||||||
|
* cueprint.c -- print cd information based on a template
|
||||||
|
*
|
||||||
|
* Copyright (C) 2004 Svend Sorensen
|
||||||
|
* For license terms, see the file COPYING in this distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h> /* exit() */
|
||||||
|
#include <string.h> /* strcmp() */
|
||||||
|
#include <unistd.h> /* getopt() */
|
||||||
|
#include <ctype.h> /* isdigit() */
|
||||||
|
#include "cuefile.h"
|
||||||
|
|
||||||
|
/* default templates */
|
||||||
|
#define D_TEMPLATE "%P \"%T\" (%N tracks)\n"
|
||||||
|
#define T_TEMPLATE "%n: %p \"%t\"\n"
|
||||||
|
|
||||||
|
char *progname;
|
||||||
|
char *d_template = D_TEMPLATE; /* disc template */
|
||||||
|
char *t_template = T_TEMPLATE; /* track template */
|
||||||
|
|
||||||
|
void usage (int status)
|
||||||
|
{
|
||||||
|
if (0 == status) {
|
||||||
|
fprintf(stdout, "%s: usage: cueprint [-h] [-i cue|toc] [-d TEMPLATE] [-t TEMPLATE] [file...]\n", progname);
|
||||||
|
fputs("\
|
||||||
|
\n\
|
||||||
|
OPTIONS\n\
|
||||||
|
-h print usage\n\
|
||||||
|
-i cue|toc set format of file(s)\n\
|
||||||
|
-d TEMPLATE set disc template (see TEMPLATE EXPANSION)\n\
|
||||||
|
-t TEMPLATE set track template (see TEMPLATE EXPANSION)\n\
|
||||||
|
\n\
|
||||||
|
Template Expansion\n\
|
||||||
|
Disc:\n\
|
||||||
|
%A - album arranger\n\
|
||||||
|
%C - album composer\n\
|
||||||
|
%G - album genre\n\
|
||||||
|
%M - album message\n\
|
||||||
|
%N - number of tracks\n\
|
||||||
|
%P - album performer\n\
|
||||||
|
%S - album songwriter\n\
|
||||||
|
%T - album title\n\
|
||||||
|
%U - album UPC/EAN\n\
|
||||||
|
Track:\n\
|
||||||
|
%a - track arranger\n\
|
||||||
|
%c - track composer\n\
|
||||||
|
%g - track genre\n\
|
||||||
|
%i - track ISRC\n\
|
||||||
|
%m - track message\n\
|
||||||
|
%n - track number\n\
|
||||||
|
%p - track perfomer\n\
|
||||||
|
%t - track title\n\
|
||||||
|
%u - track ISRC (CD-TEXT)\n\
|
||||||
|
\n\
|
||||||
|
Any other %<character> is expanded to that character. For example, to get a\n\
|
||||||
|
'%', use %%.\n\
|
||||||
|
", stdout);
|
||||||
|
fprintf(stdout, "default disc template is:\n\"%s\"\n", D_TEMPLATE);
|
||||||
|
fprintf(stdout, "default track template is:\n\"%s\"\n", T_TEMPLATE);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "%s: syntax error\n", progname);
|
||||||
|
fprintf(stderr, "run `%s -h' for usage\n", progname);
|
||||||
|
}
|
||||||
|
|
||||||
|
exit (status);
|
||||||
|
}
|
||||||
|
|
||||||
|
void disc_field (char *c, Cd *cd)
|
||||||
|
{
|
||||||
|
Cdtext *cdtext = NULL;
|
||||||
|
cdtext = cd_get_cdtext(cd);
|
||||||
|
|
||||||
|
switch (*c) {
|
||||||
|
case 'A':
|
||||||
|
printf("%s", cdtext_get(PTI_ARRANGER, cdtext));
|
||||||
|
break;
|
||||||
|
case 'C':
|
||||||
|
printf("%s", cdtext_get(PTI_COMPOSER, cdtext));
|
||||||
|
break;
|
||||||
|
case 'G':
|
||||||
|
printf("%s", cdtext_get(PTI_GENRE, cdtext));
|
||||||
|
break;
|
||||||
|
case 'M':
|
||||||
|
printf("%s", cdtext_get(PTI_MESSAGE, cdtext));
|
||||||
|
break;
|
||||||
|
case 'N':
|
||||||
|
printf("%0*d", 2, cd_get_ntrack(cd));
|
||||||
|
break;
|
||||||
|
case 'P':
|
||||||
|
printf("%s", cdtext_get(PTI_PERFORMER, cdtext));
|
||||||
|
break;
|
||||||
|
case 'R':
|
||||||
|
printf("%s", cdtext_get(PTI_ARRANGER, cdtext));
|
||||||
|
break;
|
||||||
|
case 'S':
|
||||||
|
printf("%s", cdtext_get(PTI_SONGWRITER, cdtext));
|
||||||
|
break;
|
||||||
|
case 'T':
|
||||||
|
printf("%s", cdtext_get(PTI_TITLE, cdtext));
|
||||||
|
break;
|
||||||
|
case 'U':
|
||||||
|
printf("%s", cdtext_get(PTI_UPC_ISRC, cdtext));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
putchar(*c);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void track_field (char *c, Cd *cd, int trackno)
|
||||||
|
{
|
||||||
|
Track *track = NULL;
|
||||||
|
Cdtext *cdtext = NULL;
|
||||||
|
track = cd_get_track(cd, trackno);
|
||||||
|
cdtext = track_get_cdtext(track);
|
||||||
|
|
||||||
|
switch (*c) {
|
||||||
|
case 'a':
|
||||||
|
printf("%s", cdtext_get(PTI_ARRANGER, cdtext));
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
printf("%s", cdtext_get(PTI_COMPOSER, cdtext));
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
printf("%s", track_get_filename(track));
|
||||||
|
break;
|
||||||
|
case 'g':
|
||||||
|
printf("%s", cdtext_get(PTI_GENRE, cdtext));
|
||||||
|
break;
|
||||||
|
case 'i':
|
||||||
|
printf("%s", track_get_isrc(track));
|
||||||
|
break;
|
||||||
|
case 'm':
|
||||||
|
printf("%s", cdtext_get(PTI_MESSAGE, cdtext));
|
||||||
|
break;
|
||||||
|
case 'n':
|
||||||
|
printf("%0*d", 2, trackno);
|
||||||
|
break;
|
||||||
|
case 'p':
|
||||||
|
printf("%s", cdtext_get(PTI_PERFORMER, cdtext));
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
printf("%s", cdtext_get(PTI_SONGWRITER, cdtext));
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
printf("%s", cdtext_get(PTI_TITLE, cdtext));
|
||||||
|
break;
|
||||||
|
case 'u':
|
||||||
|
printf("%s", cdtext_get(PTI_UPC_ISRC, cdtext));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
disc_field(c, cd);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_info (Cd *cd)
|
||||||
|
{
|
||||||
|
int i; /* track */
|
||||||
|
char *c;
|
||||||
|
|
||||||
|
for (c = d_template; '\0' != *c; c++) {
|
||||||
|
if ('%' == *c) {
|
||||||
|
c++;
|
||||||
|
disc_field(c, cd);
|
||||||
|
} else {
|
||||||
|
putchar(*c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 1; i <= cd_get_ntrack(cd); i++) {
|
||||||
|
for (c = t_template; '\0' != *c; c++) {
|
||||||
|
if ('%' == *c) {
|
||||||
|
c++;
|
||||||
|
track_field(c, cd, i);
|
||||||
|
} else {
|
||||||
|
putchar(*c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int info (char *name, int format)
|
||||||
|
{
|
||||||
|
Cd *cd = NULL;
|
||||||
|
|
||||||
|
if (NULL == (cd = cf_parse(name, &format))) {
|
||||||
|
fprintf(stderr, "%s: input file error\n", name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
print_info(cd);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main (int argc, char **argv)
|
||||||
|
{
|
||||||
|
int format = UNKNOWN;
|
||||||
|
/* getopt () variables */
|
||||||
|
char c;
|
||||||
|
extern char *optarg;
|
||||||
|
extern int optind;
|
||||||
|
|
||||||
|
progname = *argv;
|
||||||
|
|
||||||
|
while (-1 != (c = getopt(argc, argv, "hi:d:t:"))) {
|
||||||
|
switch (c) {
|
||||||
|
case 'h':
|
||||||
|
usage(0);
|
||||||
|
break;
|
||||||
|
case 'i':
|
||||||
|
if (0 == strcmp("cue", optarg))
|
||||||
|
format = CUE;
|
||||||
|
else if (0 == strcmp("toc", optarg))
|
||||||
|
format = TOC;
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
d_template = optarg;
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
t_template = optarg;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
usage(1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (optind == argc) {
|
||||||
|
info("-", format);
|
||||||
|
} else {
|
||||||
|
for (; optind < argc; optind++)
|
||||||
|
info(argv[optind], format);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user