Initial import of ebook2cw
This commit is contained in:
commit
bfabde598f
|
|
@ -0,0 +1,280 @@
|
|||
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
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
0.6.5 / 2008-06-?? Fabian Kurz <mail@fkurz.net>
|
||||
* Paragraph separator (<BT>) can be disabled by
|
||||
-p command line switch (suggested by DJ3KU).
|
||||
|
||||
0.6.4 / 2008-05-20 Fabian Kurz <mail@fkurz.net>
|
||||
* Added "Farnsworth" spacing (-e) and extra inter-word spacing (-W)
|
||||
[suggested by DL3OBQ]
|
||||
* Reset to original speed when using QRQ (-Q) at each new chapter can now
|
||||
be disabled (-n) [suggested by W2UP]
|
||||
|
||||
0.6.3 / 2008-03-10 Fabian Kurz <mail@fkurz.net>
|
||||
* Added the Arabic morse code alphabet
|
||||
* Added/changed Unicode characters for Esperanto
|
||||
|
||||
0.6.2 / 2008-02-20 Fabian Kurz <mail@fkurz.net>
|
||||
* Support for arbitrary prosigns added. To generate a prosign
|
||||
enclose the letters in angle brackets (e.g. <AR>, <SK>, ...). [tnx DL7YEC]
|
||||
|
||||
0.6.1 / 2008-02-09 Fabian Kurz <mail@fkurz.net>
|
||||
* Added more Cyrillic characters, the Greek and the Hebrew
|
||||
alphabet to the Unicode table. Some small corrections to
|
||||
the existing characters.
|
||||
* Command line switch -S with option either ISO or UTF prints
|
||||
a table of the available character set and the CW symbols
|
||||
in HTML format.
|
||||
|
||||
0.6.0 / 2008-02-05 Fabian Kurz <mail@fkurz.net>
|
||||
* Full ISO 8859-1 character set is now available
|
||||
* UTF-8 support by command line switch -u. Currently
|
||||
implemented: Latin, basic cyrillic.
|
||||
|
||||
0.5.1 / 2008-01-08 Fabian Kurz <mail@fkurz.net>
|
||||
* Fixed ID3 title (chapter number) generation.
|
||||
|
||||
0.5.0 / 2007-12-19 Fabian Kurz <mail@fkurz.net>
|
||||
* Added support for writing ID3 tags.
|
||||
* Added -Q command line switch: QRQ by 1 WpM every n minutes.
|
||||
|
||||
0.4.0 / 2007-12-17 Fabian Kurz <mail@fkurz.net>
|
||||
* Implemented dynamic memory allocation.
|
||||
|
||||
0.3.0 / 2007-11-28 Fabian Kurz <mail@fkurz.net>
|
||||
* Added forgotten characters: @ and /.
|
||||
|
||||
0.2.0 / 2007-11-27 Fabian Kurz <mail@fkurz.net>
|
||||
|
||||
* Fixed handling of umlauts (öäüß)
|
||||
* The chapter separator is now case sensitive.
|
||||
|
||||
0.1.0 / 2007-11-22 Fabian Kurz <mail@fkurz.net>
|
||||
|
||||
* Initial release of ebook2cw.
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
# ebook2cw Makefile -- Fabian Kurz, DJ1YFK -- http://fkurz.net/ham/ebook2cw.html
|
||||
|
||||
VERSION=0.6.5
|
||||
DESTDIR ?= /usr
|
||||
|
||||
all: ebook2cw
|
||||
|
||||
ebook2cw: ebook2cw.c codetables.h
|
||||
gcc ebook2cw.c -pedantic -Wall -lm -lmp3lame -D VERSION=\"$(VERSION)\" -o ebook2cw
|
||||
|
||||
static:
|
||||
gcc -static ebook2cw.c -lmp3lame -lm -D VERSION=\"$(VERSION)\" -o ebook2cw
|
||||
|
||||
install:
|
||||
install -d -v $(DESTDIR)/share/man/man1/
|
||||
install -d -v $(DESTDIR)/bin/
|
||||
install -s -m 0755 ebook2cw $(DESTDIR)/bin/
|
||||
install -m 0644 ebook2cw.1 $(DESTDIR)/share/man/man1/
|
||||
|
||||
uninstall:
|
||||
rm -f $(DESTDIR)/bin/ebook2cw
|
||||
rm -f $(DESTDIR)/share/man/man1/ebook2cw.1
|
||||
|
||||
clean:
|
||||
rm -f ebook2cw *~ *.mp3
|
||||
|
||||
dist:
|
||||
sed 's/v[0-9].[0-9].[0-9]/v$(VERSION)/g' README > README2
|
||||
rm -f README
|
||||
mv README2 README
|
||||
rm -f releases/ebook2cw-$(VERSION).tar.gz
|
||||
rm -rf releases/ebook2cw-$(VERSION)
|
||||
mkdir ebook2cw-$(VERSION)
|
||||
cp ebook2cw.c codetables.h ChangeLog ebook2cw.1 \
|
||||
README COPYING Makefile ebook2cw-$(VERSION)
|
||||
tar -zcf ebook2cw-$(VERSION).tar.gz ebook2cw-$(VERSION)
|
||||
mv ebook2cw-$(VERSION) releases/
|
||||
mv ebook2cw-$(VERSION).tar.gz releases/
|
||||
md5sum releases/*.gz > releases/md5sums.txt
|
||||
chmod a+r releases/*
|
||||
|
||||
|
|
@ -0,0 +1,564 @@
|
|||
/*
|
||||
ebook2cw - converts an ebook to morse mp3s
|
||||
|
||||
Copyright (C) 2007 Fabian Kurz, DJ1YFK
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 2 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
|
||||
Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
source code looks properly indented with tw=4
|
||||
|
||||
*/
|
||||
|
||||
#include "lame/lame.h"
|
||||
#include <vorbis/vorbisenc.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#ifndef VERSION
|
||||
#define VERSION "0.0.0"
|
||||
#endif
|
||||
|
||||
#define PCMBUFFER 220500 /* 20 seconds at 11kHz, for one word. plenty. */
|
||||
#define MP3BUFFER 285000 /* Those buffers will be realloced if too small */
|
||||
|
||||
/* LAME */
|
||||
lame_global_flags *gfp;
|
||||
|
||||
/* OGG */
|
||||
ogg_stream_state os;
|
||||
ogg_page og;
|
||||
ogg_packet op;
|
||||
vorbis_info vi;
|
||||
vorbis_comment vc;
|
||||
vorbis_dsp_state vd;
|
||||
vorbis_block vb;
|
||||
|
||||
FILE *outfile;
|
||||
FILE *infile;
|
||||
|
||||
/* MP3 samplerate, bitrate, quality. */
|
||||
int samplerate = 11025;
|
||||
int brate = 16;
|
||||
int quality = 3;
|
||||
|
||||
/* CW parameters */
|
||||
int wpm = 25;
|
||||
int freq = 600;
|
||||
int rt = 50; /* rise/fall time in samples */
|
||||
int ft = 50;
|
||||
int qrq = 0; /* rise speed by 1 WpM every qrq minutes */
|
||||
|
||||
/* the buffers for dit, dah, raw pcm and mp3 output, will me calloc'ed to the
|
||||
* default values, and if needed realloc'ed to the needed size */
|
||||
|
||||
short int *dit_buf;
|
||||
short int *dah_buf;
|
||||
short int *inpcm;
|
||||
unsigned char *mp3buffer;
|
||||
|
||||
int inpcm_size;
|
||||
int mp3buffer_size;
|
||||
|
||||
int ditlen=0; /* number of samples in a 'dit' */
|
||||
|
||||
/* Chapters are split by this string */
|
||||
char chapterstr[80]="CHAPTER";
|
||||
char chapterfilename[80]="Chapter"; /* full filename: Chapter%02d.mp3 */
|
||||
|
||||
/* ID3-tag data: author and title */
|
||||
char id3_author[80]="CW-Book";
|
||||
char id3_title[80]="";
|
||||
char id3_comment[80]="";
|
||||
char id3_year[5]="";
|
||||
|
||||
const static char *codetable[] = {
|
||||
".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..",".---",
|
||||
"-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",
|
||||
".--","-..-","-.--","--..","-----",".----","..---","...--","....-",".....",
|
||||
"-....", "--...","---..","----."};
|
||||
|
||||
/* functions */
|
||||
int init_cw (int wpm, int freq, int rt, int ft);
|
||||
void help (void);
|
||||
void makeword(char * text);
|
||||
void closefile (int letter, int cw);
|
||||
void openfile (int chapter);
|
||||
void initialize_lame(void);
|
||||
|
||||
/* main */
|
||||
|
||||
int main (int argc, char** argv) {
|
||||
int pos, i, original_wpm;
|
||||
char c;
|
||||
char word[1024]=""; /* will be cut when > 1024 chars long */
|
||||
int chapter = 0;
|
||||
int cw = 0, tw = 0, qw = 0; /* chapter words, total words, qrq words */
|
||||
|
||||
infile = stdin;
|
||||
|
||||
while((i = getopt(argc, argv, "o:w:f:R:F:s:b:q:c:a:t:k:y:Q:h")) != -1) {
|
||||
switch (i) {
|
||||
case 'w':
|
||||
if ((wpm = atoi(optarg)) < 1) {
|
||||
fprintf(stderr, "Error: Speed (-w) must be > 0!\n");
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 'f':
|
||||
freq = atoi(optarg);
|
||||
break;
|
||||
case 'R':
|
||||
rt = atoi(optarg);
|
||||
break;
|
||||
case 'F':
|
||||
ft = atoi(optarg);
|
||||
break;
|
||||
case 's':
|
||||
samplerate = atoi(optarg);
|
||||
break;
|
||||
case 'b':
|
||||
brate = atoi(optarg);
|
||||
break;
|
||||
case 'q':
|
||||
quality = atoi(optarg);
|
||||
break;
|
||||
case 'c':
|
||||
strncpy(chapterstr, optarg, 78);
|
||||
break;
|
||||
case 'o':
|
||||
strncpy(chapterfilename, optarg, 78);
|
||||
break;
|
||||
case 'a':
|
||||
strncpy(id3_author, optarg, 78);
|
||||
break;
|
||||
case 't':
|
||||
strncpy(id3_title, optarg, 75);
|
||||
break;
|
||||
case 'k':
|
||||
strncpy(id3_comment, optarg, 78);
|
||||
break;
|
||||
case 'y':
|
||||
strncpy(id3_year, optarg, 4);
|
||||
break;
|
||||
case 'Q':
|
||||
if ((qrq = atoi(optarg)) < 1) {
|
||||
fprintf(stderr, "Error: QRQ time (-Q) must be > 0!\n");
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 'h':
|
||||
default:
|
||||
help();
|
||||
} /* switch */
|
||||
} /* while */
|
||||
|
||||
if (optind < argc) { /* something left? if so, use as infile */
|
||||
if ((argv[optind][0] != '-') && (argv[optind][0] != '\0')) {
|
||||
if ((infile = fopen(argv[optind], "r")) == NULL) {
|
||||
fprintf(stderr, "Error: Cannot open file %s. Exit.\n",
|
||||
argv[optind]);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf("ebook2cw %s - (c) 2007 by Fabian Kurz, DJ1YFK\n", VERSION);
|
||||
printf("Speed: %d WpM, Freq: %dHz, Chapter: >%s<\n", wpm, freq, chapterstr);
|
||||
|
||||
|
||||
/* init lame */
|
||||
|
||||
initialize_lame();
|
||||
|
||||
|
||||
|
||||
/* init pcm_buf and mp3_buf */
|
||||
|
||||
if ((inpcm = calloc(PCMBUFFER, sizeof(short int))) == NULL) {
|
||||
fprintf(stderr, "Error: Can't allocate inpcm[%d]!\n", PCMBUFFER);
|
||||
exit(1);
|
||||
}
|
||||
else {
|
||||
inpcm_size = PCMBUFFER;
|
||||
}
|
||||
|
||||
if ((mp3buffer = calloc(MP3BUFFER, sizeof(unsigned char))) == NULL) {
|
||||
fprintf(stderr, "Error: Can't allocate mp3buffer[%d]!\n", MP3BUFFER);
|
||||
exit(1);
|
||||
}
|
||||
else {
|
||||
mp3buffer_size = MP3BUFFER;
|
||||
}
|
||||
|
||||
ditlen = init_cw(wpm, freq, rt, ft); /* generate raw dit, dah, silence */
|
||||
|
||||
strcat(chapterstr, " ");
|
||||
|
||||
/* read STDIN, assemble full words (anything ending in ' ') to 'word' and
|
||||
* generate CW, write to file by 'makeword'. words with > 1024 characters
|
||||
* will be split */
|
||||
|
||||
original_wpm = wpm; /* may be changed by QRQing */
|
||||
chapter = 0;
|
||||
openfile(chapter);
|
||||
|
||||
pos=0;
|
||||
while ((c = getc(infile)) != EOF) {
|
||||
|
||||
if (c == '\r') { /* DOS linebreaks */
|
||||
continue;
|
||||
}
|
||||
|
||||
word[pos++] = c;
|
||||
|
||||
if ((c == ' ') || (c == '\n') || (pos == 1024)) {
|
||||
word[pos] = '\0';
|
||||
if (strcmp(chapterstr, word) == 0) { /* new chapter */
|
||||
closefile(chapter, cw);
|
||||
cw=0;
|
||||
chapter++;
|
||||
|
||||
if (qrq) {
|
||||
wpm = original_wpm; /* restore CW */
|
||||
ditlen = init_cw(wpm, freq, rt, ft);
|
||||
}
|
||||
|
||||
openfile(chapter);
|
||||
}
|
||||
makeword(word);
|
||||
cw++; tw++; qw++;
|
||||
|
||||
word[0] = '\0';
|
||||
pos = 0;
|
||||
|
||||
/* every 'qrq' minutes (qrq*wpm words), speed up 1 WpM */
|
||||
if (qw == (qrq*wpm)) {
|
||||
wpm += 1;
|
||||
ditlen = init_cw(wpm, freq, rt, ft);
|
||||
qw = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
/* eof */
|
||||
|
||||
closefile(chapter, cw);
|
||||
|
||||
free(mp3buffer);
|
||||
free(inpcm);
|
||||
|
||||
/* factor 0.9 due to many 'words' which aren't actually words, like '\n' */
|
||||
printf("Total words: %d, total time: %d min\n", tw, (int) ((tw/wpm)*0.9));
|
||||
|
||||
lame_close(gfp);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* init_cw - generates a dit and a dah to dit_buf and dah_buf */
|
||||
|
||||
int init_cw (int wpm, int freq, int rt, int ft) {
|
||||
int x;
|
||||
int len;
|
||||
double val;
|
||||
|
||||
printf("Initializing CW buffers at %d WpM: ", wpm);
|
||||
|
||||
/* dah */
|
||||
len = (int) 3.0*6.0*samplerate/(5.0*wpm); /* in samples */
|
||||
|
||||
/* ditlen not set == init_cw has not been called yet */
|
||||
if (!ditlen) {
|
||||
/* allocate memory for the buffer */
|
||||
if ((dah_buf = calloc(len, sizeof(short int))) == NULL) {
|
||||
fprintf(stderr, "Error: Can't allocate dah_buf[%d]\n", len);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
for (x=0; x < len; x++) {
|
||||
val = sin(2*M_PI*freq*x/samplerate);
|
||||
if (x < rt) { /* shaping with sin^2 */
|
||||
val *= pow(sin(M_PI*x/(2.0*rt)),2);
|
||||
}
|
||||
if (x > (len-ft)) {
|
||||
val *= pow((sin(2*M_PI*(x-(len-ft)+ft)/(4*ft))), 2);
|
||||
}
|
||||
|
||||
dah_buf[x] = (int) (val * 20000.0);
|
||||
}
|
||||
|
||||
printf("dah_buf[%d], ", x);
|
||||
|
||||
/* dit */
|
||||
len = (int) 6.0*samplerate/(5.0*wpm); /* in samples */
|
||||
|
||||
/* ditlen not set == init_cw has not been called yet */
|
||||
if (!ditlen) {
|
||||
/* allocate memory for the buffer */
|
||||
if ((dit_buf = calloc(len, sizeof(short int))) == NULL) {
|
||||
fprintf(stderr, "Error: Can't allocate dit_buf[%d]\n", len);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
for (x=0; x < len; x++) {
|
||||
val = sin(2*M_PI*freq*x/samplerate);
|
||||
if (x < rt) {
|
||||
val *= pow(sin(M_PI*x/(2.0*rt)), 2);
|
||||
}
|
||||
if (x > (len-ft)) {
|
||||
val *= pow((sin(2*M_PI*(x-(len-ft)+ft)/(4*ft))), 2);
|
||||
}
|
||||
dit_buf[x] = (int) (val * 20000.0);
|
||||
}
|
||||
|
||||
printf("dit_buf[%d]\n\n", x);
|
||||
|
||||
return x; /* = length of dit/silence */
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* makeword -- converts 'text' to CW by concatenating dit_buf amd dah_bufs,
|
||||
* encodes this to MP3 and writes to open filehandle outfile */
|
||||
|
||||
void makeword(char * text) {
|
||||
const char *code; /* CW code as . and - */
|
||||
int outbytes;
|
||||
|
||||
int c;
|
||||
int i,u,w;
|
||||
int j;
|
||||
|
||||
j = 0; /* position in 'inpcm' buffer */
|
||||
|
||||
for (i = 0; i < strlen(text); i++) {
|
||||
c = toupper(text[i]);
|
||||
|
||||
if (c > 64 && c < 91) { /* trouble with isalpha() under Win32 */
|
||||
code = codetable[c-65]; /* even with locale = C ...? */
|
||||
}
|
||||
else if (c > 47 && c < 58) {
|
||||
code = codetable[c-22];
|
||||
}
|
||||
else if (c == '.') { code = ".-.-.-"; } /* messy */
|
||||
else if (c == ',') { code = "--..--"; }
|
||||
else if (c == '=') { code = "-...-"; }
|
||||
else if (c == '?') { code = "..--.."; }
|
||||
else if (c == '-') { code = "-....-"; }
|
||||
else if (c==228 || c==196 || c==-28 || c==-60) { code = ".-.-"; } /* ae */
|
||||
else if (c==252 || c==220 || c==-4 || c==-36) { code = "..--"; } /* ue */
|
||||
else if (c==246 || c==214 || c==-10 || c==-42) { code = "---."; } /* oe */
|
||||
else if (c == 223 || c == -33) { code = "... --.."; } /* sz */
|
||||
else if (c == '(') { code = "-.--."; }
|
||||
else if (c == ')') { code = "-.--.-"; }
|
||||
else if (c == '!') { code = ".-.-.-"; }
|
||||
else if (c == ';') { code = "-.-.-."; }
|
||||
else if (c == '/') { code = "-..-."; }
|
||||
else if (c == '@') { code = ".--.-."; }
|
||||
else if (c == ':') { code = "---..."; }
|
||||
else if (c == '"') { code = ".-..-."; }
|
||||
else if (c == '\'') { code = ".----."; }
|
||||
else if (c == ' ') { code = " "; }
|
||||
else if (c == '\n') {
|
||||
if (strlen(text) == 1) {
|
||||
code = " -...- "; /* new paragraph */
|
||||
}
|
||||
else {
|
||||
code = " ";
|
||||
}
|
||||
}
|
||||
else {
|
||||
code = " ";
|
||||
fprintf(stderr, "Warning: don't know CW for '%c'\n", (char) c);
|
||||
}
|
||||
|
||||
/* code contains word as ./-, now assemble pcm buffer */
|
||||
|
||||
for (w = 0; w < strlen(code) ; w++) {
|
||||
|
||||
/* make sure the inpcm buffer doesn't run full,
|
||||
* with a conservative margin. reallocate memory if neccesary */
|
||||
if (j > inpcm_size-(6*ditlen)) {
|
||||
inpcm_size += (6*ditlen);
|
||||
mp3buffer_size += (8*ditlen + 7200);
|
||||
if ((inpcm = realloc(inpcm, inpcm_size*sizeof(short int)))== NULL) {
|
||||
fprintf(stderr, "Error: Can't realloc inpcm[%d]\n", inpcm_size);
|
||||
}
|
||||
if ((mp3buffer = realloc(mp3buffer, mp3buffer_size*sizeof(char)))
|
||||
== NULL) {
|
||||
fprintf(stderr, "Error: Can't realloc mp3buffer[%d]\n",
|
||||
mp3buffer_size);
|
||||
}
|
||||
}
|
||||
|
||||
c = code[w];
|
||||
|
||||
if (c == '.') {
|
||||
for (u=0; u < ditlen; u++) { inpcm[++j] = dit_buf[u]; }
|
||||
}
|
||||
else if (c == '-') {
|
||||
for (u=0; u < (3*ditlen); u++) { inpcm[++j] = dah_buf[u]; }
|
||||
}
|
||||
else {
|
||||
for (u=0; u < ditlen; u++) { inpcm[++j] = 0; }
|
||||
}
|
||||
|
||||
for (u=0; u < ditlen; u++) { inpcm[++j] = 0; }
|
||||
|
||||
}
|
||||
|
||||
for (u=0; u < (2*ditlen); u++) { inpcm[++j] = 0; } /* inter word space */
|
||||
|
||||
}
|
||||
|
||||
/* j = total length of samples in 'inpcm' */
|
||||
|
||||
outbytes = lame_encode_buffer(gfp, inpcm, inpcm, j, mp3buffer, mp3buffer_size);
|
||||
if (outbytes < 0) {
|
||||
fprintf(stderr, "Error: lame_encode_buffer returned %d. Exit.\n", outbytes);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (fwrite(mp3buffer, sizeof(char), outbytes, outfile) != outbytes) {
|
||||
fprintf(stderr, "Error: Writing %db to file failed. Exit.\n", outbytes);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* closefile -- finishes writing the current file, flushes the encoder buffer */
|
||||
|
||||
void closefile (int letter, int cw) {
|
||||
int outbytes;
|
||||
char mp3filename[80] = "";
|
||||
|
||||
printf("words: %d, minutes: %d\n", cw, (int) ((cw/wpm)*0.9));
|
||||
|
||||
sprintf(mp3filename, "%s%02d.mp3", chapterfilename, letter);
|
||||
printf("Finishing %s\n\n", mp3filename);
|
||||
|
||||
outbytes = lame_encode_flush(gfp, mp3buffer, mp3buffer_size);
|
||||
|
||||
if (outbytes < 0) {
|
||||
fprintf(stderr, "Error: lame_encode_buffer returned %d.\n", outbytes);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (fwrite(mp3buffer, sizeof(char), outbytes, outfile) != outbytes) {
|
||||
fprintf(stderr, "Error: Writing %db to file failed. Exit.\n", outbytes);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fclose(outfile);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* openfile -- starts a new chapter by opening Chapter%d.mp3 */
|
||||
|
||||
void openfile (int chapter) {
|
||||
char mp3filename[80] = "";
|
||||
char tmp[80] = "";
|
||||
|
||||
sprintf(mp3filename, "%s%02d.mp3", chapterfilename, chapter);
|
||||
printf("Starting %s\n", mp3filename);
|
||||
|
||||
if ((outfile = fopen(mp3filename, "wb")) == NULL) {
|
||||
fprintf(stderr, "Error: Failed to open %s\n", mp3filename);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
sprintf(tmp, " - %d", chapter); /* generate title */
|
||||
strcat(id3_title, tmp);
|
||||
|
||||
id3tag_init(gfp);
|
||||
id3tag_set_artist(gfp, id3_author);
|
||||
id3tag_set_year(gfp, id3_year);
|
||||
id3tag_set_title(gfp, id3_title);
|
||||
id3tag_set_comment(gfp, id3_comment);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void help (void) {
|
||||
printf("ebook2cw v%s - (c) 2007 by Fabian Kurz, DJ1YFK, http://fkurz.net/\n", VERSION);
|
||||
printf("\n");
|
||||
printf("ebook2cw [-w wpm] [-f freq] [-R risetime] [-F falltime]\n");
|
||||
printf(" [-s samplerate] [-b mp3bitrate] [-q mp3quality]\n");
|
||||
printf(" [-c chapter-separator] [-o outfile-name] [-Q minutes]\n");
|
||||
printf(" [-a author] [-t title] [-k comment] [-y year]\n");
|
||||
printf(" [infile]\n\n");
|
||||
printf("defaults: 25 WpM, 600Hz, RT=FT=50, s=11025Hz, b=16kbps,\n");
|
||||
printf(" c=\"CHAPTER\", o=\"Chapter\" infile = stdin\n");
|
||||
printf("\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void initialize_lame (void) {
|
||||
gfp = lame_init();
|
||||
lame_set_num_channels(gfp,1);
|
||||
lame_set_in_samplerate(gfp, samplerate);
|
||||
lame_set_brate(gfp, brate);
|
||||
lame_set_mode(gfp,1);
|
||||
lame_set_quality(gfp, quality);
|
||||
|
||||
if (lame_init_params(gfp) < 0) {
|
||||
fprintf(stderr, "Failed: lame_init_params(gfp) \n");
|
||||
exit(1);
|
||||
}
|
||||
else {
|
||||
printf("Initialized lame; samplerate=%d, bitrate=%d, quality=%d\n",
|
||||
samplerate, brate, quality);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void initialize_vorbis (void) {
|
||||
vorbis_info_init(&vi);
|
||||
if (vorbis_encode_init_vbr(&vi, 1, samplerate, 0.1)) {
|
||||
fprintf(stderr, "Failed: vorbis_encode_init\n");
|
||||
exit(1);
|
||||
}
|
||||
vorbis_comment_init(&vc);
|
||||
vorbis_comment_add_tag(&vc,"ENCODER","ebook2cw");
|
||||
vorbis_analysis_init(&vd, &vi);
|
||||
vorbis_block_init(&vd, &vb);
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
|
|
@ -0,0 +1,134 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <math.h>
|
||||
#include <vorbis/vorbisenc.h>
|
||||
|
||||
unsigned int readbuffer[4000]; /* out of the data segment, not the stack */
|
||||
|
||||
int main(){
|
||||
ogg_stream_state os; /* take physical pages, weld into a logical stream of packets */
|
||||
ogg_page og; /* one Ogg bitstream page. Vorbis packets are inside */
|
||||
ogg_packet op; /* one raw packet of data for decode */
|
||||
|
||||
vorbis_info vi; /* struct that stores all the static vorbis bitstream settings */
|
||||
vorbis_comment vc; /* struct that stores all the user comments */
|
||||
|
||||
vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */
|
||||
vorbis_block vb; /* local working space for packet->PCM decode */
|
||||
|
||||
int eos=0,ret;
|
||||
int i, founddata;
|
||||
|
||||
|
||||
vorbis_info_init(&vi);
|
||||
|
||||
ret=vorbis_encode_init_vbr(&vi,1,11025,0.1);
|
||||
|
||||
if(ret) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
vorbis_comment_init(&vc);
|
||||
vorbis_comment_add_tag(&vc,"ENCODER","ebook2cw");
|
||||
|
||||
vorbis_analysis_init(&vd, &vi);
|
||||
vorbis_block_init(&vd, &vb);
|
||||
|
||||
srand(time(NULL));
|
||||
ogg_stream_init(&os,rand());
|
||||
|
||||
ogg_packet header;
|
||||
ogg_packet header_comm;
|
||||
ogg_packet header_code;
|
||||
|
||||
vorbis_analysis_headerout(&vd,&vc,&header,&header_comm,&header_code);
|
||||
ogg_stream_packetin(&os,&header);
|
||||
ogg_stream_packetin(&os,&header_comm);
|
||||
ogg_stream_packetin(&os,&header_code);
|
||||
|
||||
while (1) {
|
||||
int result=ogg_stream_flush(&os,&og);
|
||||
if (result==0) break;
|
||||
fwrite(og.header,1,og.header_len,stdout);
|
||||
fwrite(og.body,1,og.body_len,stdout);
|
||||
}
|
||||
|
||||
int onerun=0;
|
||||
|
||||
while(!eos){
|
||||
long i;
|
||||
long bytes = 3800;
|
||||
|
||||
for (i=0; i < 3800; i++) {
|
||||
readbuffer[i] = (int) ((sin(i*2.0*3.14*800.0/11025.0)+1)*63.0);
|
||||
// fprintf(stderr, "%ld\n", readbuffer[i]);
|
||||
}
|
||||
|
||||
// fread(readbuffer,1,READ*4,stdin); /* stereo hardwired here */
|
||||
|
||||
if(onerun == 100){
|
||||
eos=1;
|
||||
vorbis_analysis_wrote(&vd,0);
|
||||
}else{
|
||||
onerun++;
|
||||
|
||||
/* expose the buffer to submit data */
|
||||
float **buffer=vorbis_analysis_buffer(&vd,bytes);
|
||||
|
||||
for (i=0; i < bytes; i++) {
|
||||
buffer[0][i] = (float) readbuffer[i]/320;
|
||||
// fprintf(stderr, "%f\n", buffer[0][i]);
|
||||
// buffer[1][i] = readbuffer[i];
|
||||
}
|
||||
|
||||
/* tell the library how much we actually submitted */
|
||||
vorbis_analysis_wrote(&vd,i);
|
||||
}
|
||||
|
||||
/* vorbis does some data preanalysis, then divvies up blocks for
|
||||
more involved (potentially parallel) processing. Get a single
|
||||
block for encoding now */
|
||||
while(vorbis_analysis_blockout(&vd,&vb)==1){
|
||||
// fprintf(stderr, "anal\n");
|
||||
|
||||
/* analysis, assume we want to use bitrate management */
|
||||
vorbis_analysis(&vb,NULL);
|
||||
vorbis_bitrate_addblock(&vb);
|
||||
|
||||
while(vorbis_bitrate_flushpacket(&vd,&op)){
|
||||
|
||||
/* weld the packet into the bitstream */
|
||||
ogg_stream_packetin(&os,&op);
|
||||
|
||||
/* write out pages (if any) */
|
||||
while(1){
|
||||
int result=ogg_stream_pageout(&os,&og);
|
||||
if(result==0)break;
|
||||
fwrite(og.header,1,og.header_len,stdout);
|
||||
fwrite(og.body,1,og.body_len,stdout);
|
||||
|
||||
/* this could be set above, but for illustrative purposes, I do
|
||||
it here (to show that vorbis does know where the stream ends) */
|
||||
|
||||
if(ogg_page_eos(&og)) eos = 1;
|
||||
}
|
||||
} /* flushpacket */
|
||||
} /* while blockout */
|
||||
}
|
||||
|
||||
/* clean up and exit. vorbis_info_clear() must be called last */
|
||||
|
||||
ogg_stream_clear(&os);
|
||||
vorbis_block_clear(&vb);
|
||||
vorbis_dsp_clear(&vd);
|
||||
vorbis_comment_clear(&vc);
|
||||
vorbis_info_clear(&vi);
|
||||
|
||||
/* ogg_page and ogg_packet structs always point to storage in
|
||||
libvorbis. They're never freed or manipulated directly */
|
||||
|
||||
fprintf(stderr,"Done.\n");
|
||||
return(0);
|
||||
}
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <math.h>
|
||||
#include <vorbis/vorbisenc.h>
|
||||
|
||||
unsigned int readbuffer[4000]; /* out of the data segment, not the stack */
|
||||
|
||||
int main(){
|
||||
ogg_stream_state os; /* take physical pages, weld into a logical stream of packets */
|
||||
ogg_page og; /* one Ogg bitstream page. Vorbis packets are inside */
|
||||
ogg_packet op; /* one raw packet of data for decode */
|
||||
|
||||
vorbis_info vi; /* struct that stores all the static vorbis bitstream settings */
|
||||
vorbis_comment vc; /* struct that stores all the user comments */
|
||||
|
||||
vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */
|
||||
vorbis_block vb; /* local working space for packet->PCM decode */
|
||||
|
||||
int eos=0,ret;
|
||||
int i, founddata;
|
||||
|
||||
|
||||
vorbis_info_init(&vi);
|
||||
|
||||
ret=vorbis_encode_init_vbr(&vi,1,11025,0.1);
|
||||
|
||||
if(ret) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
vorbis_comment_init(&vc);
|
||||
vorbis_comment_add_tag(&vc,"ENCODER","ebook2cw");
|
||||
|
||||
vorbis_analysis_init(&vd, &vi);
|
||||
vorbis_block_init(&vd, &vb);
|
||||
|
||||
srand(time(NULL));
|
||||
ogg_stream_init(&os,rand());
|
||||
|
||||
ogg_packet header;
|
||||
ogg_packet header_comm;
|
||||
ogg_packet header_code;
|
||||
|
||||
vorbis_analysis_headerout(&vd,&vc,&header,&header_comm,&header_code);
|
||||
ogg_stream_packetin(&os,&header);
|
||||
ogg_stream_packetin(&os,&header_comm);
|
||||
ogg_stream_packetin(&os,&header_code);
|
||||
|
||||
while (1) {
|
||||
int result=ogg_stream_flush(&os,&og);
|
||||
if (result==0) break;
|
||||
fwrite(og.header,1,og.header_len,stdout);
|
||||
fwrite(og.body,1,og.body_len,stdout);
|
||||
}
|
||||
|
||||
int onerun=0;
|
||||
|
||||
while(!eos){
|
||||
long i;
|
||||
long bytes = 3800;
|
||||
|
||||
|
||||
/* expose the buffer to submit data */
|
||||
float **buffer=vorbis_analysis_buffer(&vd,bytes);
|
||||
|
||||
for (i=0; i < bytes; i++) {
|
||||
buffer[0][i] = (float) readbuffer[i]/320;
|
||||
}
|
||||
|
||||
/* tell the library how much we actually submitted */
|
||||
vorbis_analysis_wrote(&vd,i);
|
||||
vorbis_analysis_wrote(&vd,0);
|
||||
|
||||
while(vorbis_analysis_blockout(&vd, &vb) == 1){
|
||||
|
||||
vorbis_analysis(&vb, NULL);
|
||||
vorbis_bitrate_addblock(&vb);
|
||||
|
||||
while(vorbis_bitrate_flushpacket(&vd,&op)){
|
||||
|
||||
/* weld the packet into the bitstream */
|
||||
ogg_stream_packetin(&os,&op);
|
||||
|
||||
/* write out pages (if any) */
|
||||
while(1){
|
||||
int result=ogg_stream_pageout(&os,&og);
|
||||
if(result==0)break;
|
||||
fwrite(og.header,1,og.header_len,stdout);
|
||||
fwrite(og.body,1,og.body_len,stdout);
|
||||
|
||||
/* this could be set above, but for illustrative purposes, I do
|
||||
it here (to show that vorbis does know where the stream ends) */
|
||||
|
||||
if(ogg_page_eos(&og)) eos = 1;
|
||||
}
|
||||
} /* flushpacket */
|
||||
} /* while blockout */
|
||||
}
|
||||
|
||||
/* clean up and exit. vorbis_info_clear() must be called last */
|
||||
|
||||
ogg_stream_clear(&os);
|
||||
vorbis_block_clear(&vb);
|
||||
vorbis_dsp_clear(&vd);
|
||||
vorbis_comment_clear(&vc);
|
||||
vorbis_info_clear(&vi);
|
||||
|
||||
/* ogg_page and ogg_packet structs always point to storage in
|
||||
libvorbis. They're never freed or manipulated directly */
|
||||
|
||||
fprintf(stderr,"Done.\n");
|
||||
return(0);
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
ebook2cw v0.6.4 - convert ebooks to morse mp3s - Fabian Kurz, DJ1YFK
|
||||
---------------------------------------------------------------------
|
||||
|
||||
Website: http://fkurz.net/ham/ebook2cw.html
|
||||
|
||||
ebook2cw is a command line program which converts a plain text ebook to morse
|
||||
code MP3 files. It works on several platforms, including Windows and Linux.
|
||||
|
||||
It automatically splits and numbers the output files by chapters.
|
||||
|
||||
For a detailled description, please refer to the man-page or the project
|
||||
website.
|
||||
|
||||
|
||||
INSTALL
|
||||
--------
|
||||
1) Binaries
|
||||
Statically compiled binaries are available at the project website, for Linux
|
||||
(i386) and Win32. Those should be suitable for most users.
|
||||
|
||||
2) Source
|
||||
A Makefile is included; it compiles both under Linux and Windows (with MinGW).
|
||||
DESTDIR is /usr by default (so the binary will be in /usr/bin/).
|
||||
|
||||
make [DESTDIR=..]
|
||||
make install
|
||||
|
|
@ -0,0 +1 @@
|
|||
Ugly hack of ebook2cw to be used as a CGI.
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
# cw-cgi Makefile -- Fabian Kurz, DJ1YFK
|
||||
|
||||
VERSION=0.0.1
|
||||
DESTDIR ?= /usr
|
||||
|
||||
all: cw-cgi
|
||||
|
||||
cw-cgi: cw-cgi.c codetables.h
|
||||
gcc cw-cgi.c -pedantic -Wall -lm -lmp3lame -D VERSION=\"$(VERSION)\" -o cw-cgi
|
||||
|
||||
static:
|
||||
gcc -static cw-cgi.c -lmp3lame -lm -D VERSION=\"$(VERSION)\" -o cw-cgi
|
||||
|
||||
clean:
|
||||
rm -f cw-cgi *~
|
||||
|
||||
dist:
|
||||
sed 's/v[0-9].[0-9].[0-9]/v$(VERSION)/g' README > README2
|
||||
rm -f releases/cw-cgi-$(VERSION).tar.gz
|
||||
rm -rf releases/cw-cgi-$(VERSION)
|
||||
mkdir cw-cgi-$(VERSION)
|
||||
cp cw-cgi.c codetables.h ChangeLog cw-cgi.1 \
|
||||
README COPYING Makefile cw-cgi-$(VERSION)
|
||||
tar -zcf cw-cgi-$(VERSION).tar.gz cw-cgi-$(VERSION)
|
||||
mv cw-cgi-$(VERSION) releases/
|
||||
mv cw-cgi-$(VERSION).tar.gz releases/
|
||||
md5sum releases/*.gz > releases/md5sums.txt
|
||||
chmod a+r releases/*
|
||||
|
||||
|
|
@ -0,0 +1,550 @@
|
|||
/*
|
||||
* ISO 8859-1 and UTF-8 to Morse code mappings
|
||||
* This file is part of ebook2cw and may be used under the same terms (GPL)
|
||||
* (C) 2008 Fabian Kurz, DJ1YFK
|
||||
*
|
||||
* Currently included: ISO 8859-1
|
||||
* - complete (all that can somehow be mapped)
|
||||
* Unicode:
|
||||
* - Latin (basic, some extended)
|
||||
* - Cyrillic alphabet (KOI-7 + Serbian, Macedonian.. )
|
||||
* - Greek
|
||||
* - Hebrew
|
||||
*
|
||||
* Any comments, additions or corrections are welcome: mail@fkurz.net
|
||||
*
|
||||
*/
|
||||
|
||||
const static char *iso8859[] = {
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
" ", /* space */
|
||||
"..--.", /* ! */
|
||||
".-..-.", /* " */
|
||||
NULL, /* # */
|
||||
"...-..-", /* $ */
|
||||
NULL, /* % */
|
||||
". ...", /* & */
|
||||
".----.", /* ' */
|
||||
"-.--.", /* ( */
|
||||
"-.--.-", /* ) */
|
||||
NULL, /* * */
|
||||
".-.-.", /* + */
|
||||
"--..--", /* , */
|
||||
"-....-", /* - */
|
||||
".-.-.-", /* . */
|
||||
"-..-.", /* / */
|
||||
"-----", /* 0 */
|
||||
".----", /* 1 */
|
||||
"..---", /* 2 */
|
||||
"...--", /* 3 */
|
||||
"....-", /* 4 */
|
||||
".....", /* 5 */
|
||||
"-....", /* 6 */
|
||||
"--...", /* 7 */
|
||||
"---..", /* 8 */
|
||||
"----.", /* 9 */
|
||||
"---...", /* : */
|
||||
"-.-.-.", /* ; */
|
||||
NULL, /* < */
|
||||
"-...-", /* = */
|
||||
NULL, /* < */
|
||||
"..--..", /* ? */
|
||||
".--.-.", /* @ */
|
||||
".-", /* A */
|
||||
"-...", /* B */
|
||||
"-.-.",
|
||||
"-..",
|
||||
".",
|
||||
"..-.",
|
||||
"--.",
|
||||
"....",
|
||||
"..",
|
||||
".---",
|
||||
"-.-",
|
||||
".-..",
|
||||
"--",
|
||||
"-.",
|
||||
"---",
|
||||
".--.",
|
||||
"--.-",
|
||||
".-.",
|
||||
"...",
|
||||
"-",
|
||||
"..-",
|
||||
"...-",
|
||||
".--",
|
||||
"-..-",
|
||||
"-.--",
|
||||
"--..", /* Z */
|
||||
NULL, /* [ */
|
||||
"-..-.", /* \ */
|
||||
NULL, /* ] */
|
||||
NULL, /* ^ */
|
||||
NULL, /* _ */
|
||||
".----.", /* ` */
|
||||
".-", /* a */
|
||||
"-...", /* b */
|
||||
"-.-.",
|
||||
"-..",
|
||||
".",
|
||||
"..-.",
|
||||
"--.",
|
||||
"....",
|
||||
"..",
|
||||
".---",
|
||||
"-.-",
|
||||
".-..",
|
||||
"--",
|
||||
"-.",
|
||||
"---",
|
||||
".--.",
|
||||
"--.-",
|
||||
".-.",
|
||||
"...",
|
||||
"-",
|
||||
"..-",
|
||||
"...-",
|
||||
".--",
|
||||
"-..-",
|
||||
"-.--",
|
||||
"--..", /* z */
|
||||
NULL, /* { */
|
||||
NULL, /* | */
|
||||
NULL, /* } */
|
||||
NULL, /* ~ */
|
||||
NULL, /* DEL */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL,
|
||||
".-..-.", /* « (angle quotes, <<, 171) */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
".-..-.", /* » (angle quotes, >>, 187) */
|
||||
NULL, NULL, NULL, NULL,
|
||||
".--.-", /* `A */
|
||||
".--.-", /* 'A */
|
||||
".-", /* ^A */
|
||||
".-", /* ~A */
|
||||
".-.-", /* "A */
|
||||
".--.-", /* °A */
|
||||
".- .", /* AE */
|
||||
"-.-..", /* ,C */
|
||||
"..-..", /* `E */
|
||||
"..-..", /* 'E */
|
||||
".", /* ^E */
|
||||
".", /* "E */
|
||||
"..", /* `I */
|
||||
"..", /* 'I */
|
||||
"..", /* ^I */
|
||||
"..", /* "I */
|
||||
"..--.", /* -D */
|
||||
"--.--", /* ~N */
|
||||
"---", /* `O */
|
||||
"---", /* 'O */
|
||||
"---", /* ^O */
|
||||
"---", /* ~O */
|
||||
"---.", /* "O */
|
||||
NULL, /* x */
|
||||
"---.", /* /O */
|
||||
"..-", /* `U */
|
||||
"..-", /* 'U */
|
||||
"..-", /* ^U */
|
||||
"..--", /* "U */
|
||||
"-.--", /* 'Y */
|
||||
".--..", /* 'thorn' */
|
||||
"...--..", /* sz */
|
||||
".--.-", /* `a */
|
||||
".--.-", /* 'a */
|
||||
".-", /* ^a */
|
||||
".-", /* ~a */
|
||||
".-.-", /* "a */
|
||||
".--.-", /* °a */
|
||||
".- .", /* ae */
|
||||
"-.-..", /* ,c */
|
||||
"..-..", /* `e */
|
||||
"..-..", /* 'e */
|
||||
".", /* ^e */
|
||||
".", /* "e */
|
||||
"..", /* `i */
|
||||
"..", /* 'i */
|
||||
"..", /* ^i */
|
||||
"..", /* "i */
|
||||
"..--.", /* -d */
|
||||
"--.--", /* ~n */
|
||||
"---", /* `o */
|
||||
"---", /* 'o */
|
||||
"---", /* ^o */
|
||||
"---", /* ~o */
|
||||
"---.", /* "o */
|
||||
NULL, /* ./. */
|
||||
"---.", /* /o */
|
||||
"..-", /* `u */
|
||||
"..-", /* 'u */
|
||||
"..-", /* ^u */
|
||||
"..--", /* "u */
|
||||
"-.--", /* 'y */
|
||||
".--..", /* 'thorn' */
|
||||
"-.--" /* "y */
|
||||
};
|
||||
|
||||
const static char *utf8table[] = {
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* first 128 are identical*/
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* to iso8859, so that */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* will be used instead */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* - 127 */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* control characters ...*/
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* -159 */
|
||||
" ", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, ".-..-.", NULL, NULL, NULL, NULL, /* 171 << */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, ".-..-.", NULL, NULL, NULL, NULL, /* 187 >> */
|
||||
/* same as in ISO8859 */
|
||||
".--.-", /* `A */ /* 192 ... */
|
||||
".--.-", /* 'A */
|
||||
".-", /* ^A */
|
||||
".-", /* ~A */
|
||||
".-.-", /* "A */
|
||||
".--.-", /* °A */
|
||||
".- .", /* AE */
|
||||
"-.-..", /* ,C */
|
||||
"..-..", /* `E */
|
||||
"..-..", /* 'E */
|
||||
".", /* ^E */
|
||||
".", /* "E */
|
||||
"..", /* `I */
|
||||
"..", /* 'I */
|
||||
"..", /* ^I */
|
||||
"..", /* "I */
|
||||
"..--.", /* -D according to Wikipedia */
|
||||
"--.--", /* ~N */
|
||||
"---", /* `O */
|
||||
"---", /* 'O */
|
||||
"---", /* ^O */
|
||||
"---", /* ~O */
|
||||
"---.", /* "O */
|
||||
NULL, /* x */
|
||||
"---.", /* /O */
|
||||
"..-", /* `U */
|
||||
"..-", /* 'U */
|
||||
"..-", /* ^U */
|
||||
"..--", /* "U */
|
||||
"-.--", /* 'Y */
|
||||
".--..", /* 'thorn', acc to Wikipedia */
|
||||
"...--..", /* sz */
|
||||
".--.-", /* `a */
|
||||
".--.-", /* 'a */
|
||||
".-", /* ^a */
|
||||
".-", /* ~a */
|
||||
".-.-", /* "a */
|
||||
".--.-", /* °a */
|
||||
".- .", /* ae */
|
||||
"-.-..", /* ,c */
|
||||
"..-..", /* `e */
|
||||
"..-..", /* 'e */
|
||||
".", /* ^e */
|
||||
".", /* "e */
|
||||
"..", /* `i */
|
||||
"..", /* 'i */
|
||||
"..", /* ^i */
|
||||
"..", /* "i */
|
||||
"..--.", /* -d Wiki */
|
||||
"--.--", /* ~n */
|
||||
"---", /* `o */
|
||||
"---", /* 'o */
|
||||
"---", /* ^o */
|
||||
"---", /* ~o */
|
||||
"---.", /* "o */
|
||||
NULL, /* ./. */
|
||||
"---.", /* /o */
|
||||
"..-", /* `u */
|
||||
"..-", /* 'u */
|
||||
"..-", /* ^u */
|
||||
"..--", /* "u */
|
||||
"-.--", /* 'y */
|
||||
".--..", /* 'thorn' */
|
||||
"-.--", /* "y */ /* 255 */
|
||||
".-", ".-", ".-", ".-", ".-", ".-", /* 256-261, As with different hats */
|
||||
/* 262-269 Cs with different hats */
|
||||
/* 264-265 -.-.. acc. to Wikipedia, Esperanto etc. */
|
||||
"-.-.", "-.-.", "-.-..", "-.-..", "-.-.", "-.-.", "-.-.", "-.-.",
|
||||
"-..", "-..", "-..", "-..", /* 270-273 Ds with different stuff */
|
||||
/* 274-283 different Es */
|
||||
".", ".", ".", ".", ".", ".", ".", ".", ".", ".",
|
||||
/* 284-291 different Gs, first 2 according to Wikipedia (Esperanto) */
|
||||
"--.-.", "--.-.", "--.", "--.", "--.", "--.", "--.", "--.",
|
||||
/* 292-295 different Hs, first two Esperanto (was: -.--. before, but was
|
||||
* changed: "Originale, Hx estis -.--. sed tio kolizie estas "(" en ITU-T
|
||||
* F.1, do Hx nun prefere estas ----") */
|
||||
"----", "----", "....", "....",
|
||||
/* 296-305 different Is */
|
||||
"..", "..", "..", "..", "..", "..", "..", "..", "..", "..",
|
||||
/* 306-307 IJ ligatures */
|
||||
".. .---", ".. .---",
|
||||
/* 308-309 Js, from Wikipedia, Esperanto */
|
||||
".---.", ".---.",
|
||||
/* 310-312 Ks */
|
||||
"-.-", "-.-", "-.-",
|
||||
/* 313-322 different Ls */
|
||||
".-..", ".-..", ".-..", ".-..", ".-..", ".-..", ".-..",
|
||||
".-..", ".-..", ".-..",
|
||||
/* 323-331 different Ns */
|
||||
"-.", "-.", "-.", "-.", "-.", "-.", "-.", "-.", "-.",
|
||||
/* 332-337 Os */
|
||||
"---", "---", "---", "---", "---", "---",
|
||||
/* 338-339 OEs */
|
||||
"---.", "---.",
|
||||
/* 340-345 Rs */
|
||||
".-.", ".-.", ".-.", ".-.", ".-.", ".-.",
|
||||
/* 346-353 Ss, Wikipedia */
|
||||
"...", "...", "...-.", "...-.", "...", "...", "...", "...",
|
||||
/* 354-359 Ts */
|
||||
"-", "-", "-", "-", "-", "-",
|
||||
/* 360-371 Us, 364. 365 Esperanto */
|
||||
"..-", "..-", "..-", "..-", "..--", "..--", "..-", "..-", "..-",
|
||||
"..-", "..-", "..-",
|
||||
/* 372-373 Ws */
|
||||
".--", ".--",
|
||||
/* 374-377 Ys */
|
||||
"-.--", "-.--", "-.--",
|
||||
/* 377-382 Zs */
|
||||
"--..", "--..", "--..", "--..", "--..", "--..",
|
||||
/* 383 S */
|
||||
"...",
|
||||
/* 384-389 Bs */
|
||||
"-...", "-...", "-...", "-...", "-...", "-...",
|
||||
NULL, NULL, NULL, /* all kind of weird stuff */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL,
|
||||
/* Standard Greek Alphabet */
|
||||
".-", "-..." , "--.", "-..", ".", "--..", "....",
|
||||
"-.-.", "..", "-.-", ".-..", "--", "-.", "-..-", "---",
|
||||
".--.", ".-.", NULL, "...", "-", "-.--", "..-.", "----",
|
||||
"--.-", ".--", NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 1023 */
|
||||
|
||||
/* 1024-1039, cyrillic (Serbian, Macedonian, Ukrainian) UC */
|
||||
".", ".", "-.. .---", "--. .---", ".", "-.. --..", "..", "..",
|
||||
".---", ".-.. .---", "-. .---", "-.-.", "-.- .---", "..", "..-","-.. --..",
|
||||
|
||||
/* 32 letters of Russian Cyrillic alphabet */
|
||||
".-", "-...", ".--", "--.", "-..", ".", "...-", /* 1040-1071 */
|
||||
"--..", "..",".---", "-.-", ".-..", "--", "-.", /* uppercase */
|
||||
"---", ".--.", ".-.", "...", "-", "..-", "..-.", /* cyrillic */
|
||||
"....", "-.-.", "---.", "----", "--.-", "-..-",
|
||||
"-.--", "-..-", "..-..", "..--", ".-.-",
|
||||
".-", "-...", ".--", "--.", "-..", ".", "...-", /* 1072-1103 */
|
||||
"--..", "..",".---", "-.-", ".-..", "--", "-.", /* lowercase */
|
||||
"---", ".--.", ".-.", "...", "-", "..-", "..-.", /* cyrillic */
|
||||
"....", "-.-.", "---.", "----", "--.-", "-..-",
|
||||
"-.--", "-..-", "..-..", "..--", ".-.-",
|
||||
|
||||
/* 1004-1119, cyrillic (Serbian, Macedonian, Ukrainian) UC */
|
||||
".", ".", "-.. .---", "--. .---", ".", "-.. --..", "..", "..",
|
||||
".---", ".-.. .---", "-. .---", "-.-.", "-.- .---", "..", "..-","-.. --..",
|
||||
|
||||
/* 1120 - 1487 to be done... */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/* 1488-1514 Hebrew according to Wikipedia */
|
||||
".-", "-...", "--.", "-..", "---", ".", "--..", "....",
|
||||
"..-", "..", NULL, "-.-", ".-..", NULL, "--", "-.", NULL,
|
||||
"-.-.", ".---", NULL, ".--.", NULL, ".--", "--.-", ".-.", "...",
|
||||
"-", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/* Arabic Alphabet, as per Wikipedia.
|
||||
* Nobody is possibly ever going to use this :-)
|
||||
* 1569-1610
|
||||
*/
|
||||
".", NULL, NULL, NULL, NULL, NULL,
|
||||
".-", "-...", NULL, "-", "-.-.",
|
||||
".---", "....", "---", "-..", "--..", ".-.", "---.", "...",
|
||||
"----", "-..-", "...-", "..-", "-.--", ".-.-", "--.", NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, "..-.", "--.-", "-.-",
|
||||
".-..", "--", "-.", NULL, ".--", NULL, "..", NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL /* 1920 */
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,491 @@
|
|||
/*
|
||||
ebook2cw - converts an ebook to morse mp3s
|
||||
|
||||
Copyright (C) 2008 Fabian Kurz, DJ1YFK
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 2 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
|
||||
Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
source code looks properly indented with tw=4
|
||||
*/
|
||||
|
||||
#include "lame/lame.h"
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "codetables.h"
|
||||
|
||||
#ifndef VERSION
|
||||
#define VERSION "0.0.0"
|
||||
#endif
|
||||
|
||||
#define PCMBUFFER 220500 /* 20 seconds at 11kHz, for one word. plenty. */
|
||||
#define MP3BUFFER 285000 /* abt 1.25*PCMBUFFER + 7200, as recommended */
|
||||
|
||||
#define ISO8859 0
|
||||
#define UTF8 1
|
||||
|
||||
lame_global_flags *gfp;
|
||||
|
||||
FILE *outfile;
|
||||
FILE *infile;
|
||||
|
||||
/* MP3 samplerate, bitrate, quality. */
|
||||
int samplerate = 11025;
|
||||
int brate = 16;
|
||||
int quality = 5;
|
||||
|
||||
/* CW parameters */
|
||||
int wpm = 25;
|
||||
int freq = 600;
|
||||
int rt = 50; /* rise/fall time in samples */
|
||||
int ft = 50;
|
||||
int qrq = 0; /* rise speed by 1 WpM every qrq minutes */
|
||||
int reset = 1; /* reset QRQed speed every chapter? */
|
||||
int farnsworth = 0; /* farnswoth speed in WpM */
|
||||
float ews = 0.0; /* extra word spaces */
|
||||
|
||||
/* the buffers for dit, dah, raw pcm and mp3 output, will be calloc'ed to the
|
||||
* default values, and -if needed- realloc'ed to the needed size */
|
||||
|
||||
short int *dit_buf;
|
||||
short int *dah_buf;
|
||||
short int *inpcm;
|
||||
unsigned char *mp3buffer;
|
||||
|
||||
int inpcm_size;
|
||||
int mp3buffer_size;
|
||||
|
||||
int ditlen=0; /* number of samples in a 'dit' */
|
||||
|
||||
/* functions */
|
||||
int init_cw (int wpm, int freq, int rt, int ft);
|
||||
void makeword(char * text, int encoding);
|
||||
void closefile (int letter, int cw);
|
||||
void buf_check(int j);
|
||||
void urldecode(char *buf);
|
||||
int hexit(char c);
|
||||
|
||||
/* main */
|
||||
|
||||
int main (int argc, char** argv) {
|
||||
int pos, i;
|
||||
int encoding = ISO8859;
|
||||
int c;
|
||||
char word[11000]=""; /* will be cut when > 1024 chars long */
|
||||
char text[11000];
|
||||
char *querystring;
|
||||
|
||||
outfile = stdout;
|
||||
|
||||
/* init lame */
|
||||
gfp = lame_init();
|
||||
lame_set_num_channels(gfp,1);
|
||||
lame_set_in_samplerate(gfp, samplerate);
|
||||
lame_set_brate(gfp, brate);
|
||||
lame_set_mode(gfp,1);
|
||||
lame_set_quality(gfp, quality);
|
||||
|
||||
if (lame_init_params(gfp) < 0) {
|
||||
fprintf(stderr, "Failed: lame_init_params(gfp) \n");
|
||||
return(1);
|
||||
}
|
||||
|
||||
/* init pcm_buf and mp3_buf */
|
||||
|
||||
if ((inpcm = calloc(PCMBUFFER, sizeof(short int))) == NULL) {
|
||||
fprintf(stderr, "Error: Can't allocate inpcm[%d]!\n", PCMBUFFER);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
else {
|
||||
inpcm_size = PCMBUFFER;
|
||||
}
|
||||
|
||||
if ((mp3buffer = calloc(MP3BUFFER, sizeof(unsigned char))) == NULL) {
|
||||
fprintf(stderr, "Error: Can't allocate mp3buffer[%d]!\n", MP3BUFFER);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
else {
|
||||
mp3buffer_size = MP3BUFFER;
|
||||
}
|
||||
|
||||
|
||||
printf("Content-type: audio/mpeg\n\n");
|
||||
|
||||
querystring = getenv("QUERY_STRING");
|
||||
|
||||
if (querystring == NULL) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
sscanf(querystring, "s=%d&e=%d&f=%d&t=%10000s", &wpm, &farnsworth, &freq, text);
|
||||
|
||||
if ((wpm < 1) || (farnsworth < 1) || (freq < 100)) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (farnsworth > wpm) {
|
||||
farnsworth = wpm;
|
||||
}
|
||||
|
||||
strcat(text, " ");
|
||||
|
||||
urldecode(text);
|
||||
|
||||
ditlen = init_cw(wpm, freq, rt, ft); /* generate raw dit, dah */
|
||||
|
||||
/* read STDIN, assemble full words (anything ending in ' ') to 'word' and
|
||||
* generate CW, write to file by 'makeword'. words with > 1024 characters
|
||||
* will be split */
|
||||
|
||||
i=0;
|
||||
pos=0;
|
||||
while ((c = text[i++]) != '\0') {
|
||||
|
||||
word[pos++] = c;
|
||||
|
||||
if ((c == ' ') || (c == '\n') || (pos == 1024)) {
|
||||
word[pos] = '\0';
|
||||
makeword(word, encoding);
|
||||
word[0] = '\0';
|
||||
pos = 0;
|
||||
} /* word */
|
||||
} /* eof */
|
||||
|
||||
makeword(" ", encoding);
|
||||
|
||||
free(mp3buffer);
|
||||
free(inpcm);
|
||||
|
||||
lame_close(gfp);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* init_cw - generates a dit and a dah to dit_buf and dah_buf */
|
||||
|
||||
int init_cw (int wpm, int freq, int rt, int ft) {
|
||||
int x, len;
|
||||
double val;
|
||||
|
||||
/* set farnsworth to samples */
|
||||
if (farnsworth) {
|
||||
|
||||
if (farnsworth > wpm) {
|
||||
fprintf(stderr, "Error: Effective speed (-e %d) must be lower "
|
||||
"than character speed (-w %d)!\n", farnsworth, wpm);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
|
||||
farnsworth = (int) (6.0*samplerate/(5.0*farnsworth));
|
||||
}
|
||||
|
||||
/* printf("Initializing CW buffers at %d WpM: ", wpm); */
|
||||
|
||||
/* dah */
|
||||
len = (int) (3.0*6.0*samplerate/(5.0*wpm)); /* in samples */
|
||||
|
||||
/* ditlen not set == init_cw has not been called yet */
|
||||
if (!ditlen) {
|
||||
/* allocate memory for the buffer */
|
||||
if ((dah_buf = calloc(len, sizeof(short int))) == NULL) {
|
||||
fprintf(stderr, "Error: Can't allocate dah_buf[%d]\n", len);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
for (x=0; x < len; x++) {
|
||||
val = sin(2*M_PI*freq*x/samplerate);
|
||||
if (x < rt) /* shaping with sin^2 */
|
||||
val *= pow(sin(M_PI*x/(2.0*rt)),2);
|
||||
|
||||
if (x > (len-ft))
|
||||
val *= pow((sin(2*M_PI*(x-(len-ft)+ft)/(4*ft))), 2);
|
||||
|
||||
dah_buf[x] = (short int) (val * 20000.0);
|
||||
}
|
||||
|
||||
/* printf("dah_buf[%d], ", x); */
|
||||
|
||||
/* dit */
|
||||
len = (int) (6.0*samplerate/(5.0*wpm)); /* in samples */
|
||||
|
||||
/* ditlen not set == init_cw has not been called yet */
|
||||
if (!ditlen) {
|
||||
/* allocate memory for the buffer */
|
||||
if ((dit_buf = calloc(len, sizeof(short int))) == NULL) {
|
||||
fprintf(stderr, "Error: Can't allocate dit_buf[%d]\n", len);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
for (x=0; x < len; x++) {
|
||||
val = sin(2*M_PI*freq*x/samplerate);
|
||||
if (x < rt)
|
||||
val *= pow(sin(M_PI*x/(2.0*rt)), 2);
|
||||
|
||||
if (x > (len-ft))
|
||||
val *= pow((sin(2*M_PI*(x-(len-ft)+ft)/(4*ft))), 2);
|
||||
|
||||
dit_buf[x] = (short int) (val * 20000.0);
|
||||
}
|
||||
|
||||
/* printf("dit_buf[%d]\n\n", x); */
|
||||
|
||||
return x; /* = length of dit/silence */
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* makeword -- converts 'text' to CW by concatenating dit_buf amd dah_bufs,
|
||||
* encodes this to MP3 and writes to open filehandle outfile */
|
||||
|
||||
void makeword(char * text, int encoding) {
|
||||
const char *code; /* CW code as . and - */
|
||||
int outbytes;
|
||||
|
||||
int c, i, j, u, w;
|
||||
int prosign = 0;
|
||||
unsigned char last=0; /* for utf8 2-byte characters */
|
||||
|
||||
j = 0; /* position in 'inpcm' buffer */
|
||||
|
||||
for (i = 0; i < strlen(text); i++) {
|
||||
c = (unsigned char) text[i];
|
||||
code = NULL;
|
||||
|
||||
if (c == '\n') { /* Same for UTF8 and ISO8859 */
|
||||
if (strlen(text) == 1) /* paragraph */
|
||||
code = " -...- ";
|
||||
else
|
||||
code = " ";
|
||||
}
|
||||
else if (c == '<') { /* prosign on */
|
||||
prosign = 1;
|
||||
continue;
|
||||
}
|
||||
else if ((c == '>') && prosign) { /* prosign off */
|
||||
prosign = 0;
|
||||
code = ""; /* only inserts letter space */
|
||||
}
|
||||
else if (encoding == ISO8859) {
|
||||
code = iso8859[c];
|
||||
}
|
||||
else if (encoding == UTF8) {
|
||||
/* Character may be 1-byte ASCII or 2-byte UTF8 */
|
||||
if (!(c & 128)) { /* MSB = 0 -> 7bit ASCII */
|
||||
code = iso8859[c]; /* subset of iso8859 */
|
||||
}
|
||||
else {
|
||||
if (last && (c < 192) ) { /* this is the 2nd byte */
|
||||
/* 110yyyyy 10zzzzzz -> 00000yyy yyzzzzzz */
|
||||
c = ((last & 31) << 6) | (c & 63);
|
||||
code = utf8table[c];
|
||||
last = 0;
|
||||
}
|
||||
else { /* this is the first byte */
|
||||
last = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (last) continue; /* first of two-byte character read */
|
||||
|
||||
/* Not found anything ... */
|
||||
if (code == NULL) {
|
||||
code = " ";
|
||||
if (c < 255) {
|
||||
fprintf(stderr, "Warning: don't know CW for '%c'\n", c);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "Warning: don't know CW for unicode &#%d;\n", c);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* code contains letter as ./-, now assemble pcm buffer */
|
||||
|
||||
for (w = 0; w < strlen(code) ; w++) {
|
||||
|
||||
/* make sure the inpcm buffer doesn't run full,
|
||||
* with a conservative margin. reallocate memory if neccesary */
|
||||
|
||||
buf_check(j);
|
||||
|
||||
|
||||
c = code[w];
|
||||
|
||||
if (c == '.')
|
||||
for (u=0; u < ditlen; u++)
|
||||
inpcm[++j] = dit_buf[u];
|
||||
else if (c == '-')
|
||||
for (u=0; u < (3*ditlen); u++)
|
||||
inpcm[++j] = dah_buf[u];
|
||||
else /* word space */
|
||||
for (u=0;u < (int)(1+7*ews)*(farnsworth ? farnsworth : ditlen); u++)
|
||||
inpcm[++j] = 0;
|
||||
|
||||
for (u=0; u < ditlen; u++) /* space of one dit length */
|
||||
inpcm[++j] = 0;
|
||||
} /* foreach dot/dash */
|
||||
|
||||
if (prosign == 0) {
|
||||
for (u=0; u < (farnsworth ? 3*farnsworth-ditlen : 2*ditlen); u++)
|
||||
inpcm[++j] = 0;
|
||||
}
|
||||
|
||||
} /* foreach letter */
|
||||
|
||||
/* j = total length of samples in 'inpcm' */
|
||||
|
||||
outbytes = lame_encode_buffer(gfp, inpcm, inpcm, j, mp3buffer, mp3buffer_size);
|
||||
if (outbytes < 0) {
|
||||
fprintf(stderr, "Error: lame_encode_buffer returned %d. Exit.\n", outbytes);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (fwrite(mp3buffer, sizeof(char), outbytes, outfile) != outbytes) {
|
||||
fprintf(stderr, "Error: Writing %db to file failed. Exit.\n", outbytes);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* closefile -- finishes writing the current file, flushes the encoder buffer */
|
||||
|
||||
void closefile (int letter, int cw) {
|
||||
int outbytes;
|
||||
|
||||
outbytes = lame_encode_flush(gfp, mp3buffer, mp3buffer_size);
|
||||
|
||||
if (outbytes < 0) {
|
||||
fprintf(stderr, "Error: lame_encode_buffer returned %d.\n", outbytes);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (fwrite(mp3buffer, sizeof(char), outbytes, outfile) != outbytes) {
|
||||
fprintf(stderr, "Error: Writing %db to file failed. Exit.\n", outbytes);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
fclose(outfile);
|
||||
}
|
||||
|
||||
|
||||
/* make sure the inpcm-buffer doesn't run full.
|
||||
* have to consider the effects of Farnsworth and extra word spacing */
|
||||
|
||||
void buf_check (int j) {
|
||||
int max;
|
||||
|
||||
/* maximum bytes that may be added for one dot or dah, for either
|
||||
* farnsworth or non-farnsworth */
|
||||
|
||||
max = farnsworth ? (int) ((4+7*ews)*(farnsworth)) : (6+7*ews) * ditlen;
|
||||
max += 10000; /* some margin to feel safe ... */
|
||||
|
||||
if (j > inpcm_size - max) {
|
||||
inpcm_size += max;
|
||||
mp3buffer_size += (int) (1.25 * max + 7200.0);
|
||||
if ((inpcm = realloc(inpcm, inpcm_size*sizeof(short int)))== NULL)
|
||||
fprintf(stderr, "Error: Can't realloc inpcm[%d]\n", inpcm_size);
|
||||
|
||||
if ((mp3buffer = realloc(mp3buffer, mp3buffer_size*sizeof(char)))
|
||||
== NULL)
|
||||
fprintf(stderr, "Error: Can't realloc mp3buffer[%d]\n",
|
||||
mp3buffer_size);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* URLDECODE stuff: */
|
||||
|
||||
/* Anti-Web HTTPD */
|
||||
/* Hardcore Software */
|
||||
/*
|
||||
This software is Copyright (C) 2001-2004 By Hardcore Software and
|
||||
others. The software is distributed under the terms of the GNU General
|
||||
Public License. See the file 'COPYING' for more details.
|
||||
*/
|
||||
|
||||
/*
|
||||
This code is Copyright (C) 2001 By Zas ( zas at norz.org )
|
||||
The software is distributed under the terms of the GNU General Public
|
||||
License. See the file 'COPYING' for more details.
|
||||
*/
|
||||
|
||||
/* I might've modified this slightly, but it's definitley Zas'. -Fractal */
|
||||
|
||||
int hexit(char c) {
|
||||
if ( c >= '0' && c <= '9' )
|
||||
return c - '0';
|
||||
if ( c >= 'a' && c <= 'f' )
|
||||
return c - 'a' + 10;
|
||||
if ( c >= 'A' && c <= 'F' )
|
||||
return c - 'A' + 10;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Decode string %xx -> char (in place) */
|
||||
void urldecode(char *buf) {
|
||||
int v;
|
||||
char *p, *s, *w;
|
||||
|
||||
w=p=buf;
|
||||
while (*p) {
|
||||
v=0;
|
||||
|
||||
if (*p=='%') {
|
||||
s=p;
|
||||
s++;
|
||||
|
||||
if (isxdigit((int) s[0]) && isxdigit((int) s[1]) ) {
|
||||
v=hexit(s[0])*16+hexit(s[1]);
|
||||
if (v) { /* do not decode %00 to null char */
|
||||
*w=(char)v;
|
||||
p=&s[1];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!v) *w=*p;
|
||||
p++; w++;
|
||||
}
|
||||
*w='\0';
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,550 @@
|
|||
/*
|
||||
* ISO 8859-1 and UTF-8 to Morse code mappings
|
||||
* This file is part of ebook2cw and may be used under the same terms (GPL)
|
||||
* (C) 2008 Fabian Kurz, DJ1YFK
|
||||
*
|
||||
* Currently included: ISO 8859-1
|
||||
* - complete (all that can somehow be mapped)
|
||||
* Unicode:
|
||||
* - Latin (basic, some extended)
|
||||
* - Cyrillic alphabet (KOI-7 + Serbian, Macedonian.. )
|
||||
* - Greek
|
||||
* - Hebrew
|
||||
*
|
||||
* Any comments, additions or corrections are welcome: mail@fkurz.net
|
||||
*
|
||||
*/
|
||||
|
||||
const static char *iso8859[] = {
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
" ", /* space */
|
||||
"..--.", /* ! */
|
||||
".-..-.", /* " */
|
||||
NULL, /* # */
|
||||
"...-..-", /* $ */
|
||||
NULL, /* % */
|
||||
". ...", /* & */
|
||||
".----.", /* ' */
|
||||
"-.--.", /* ( */
|
||||
"-.--.-", /* ) */
|
||||
NULL, /* * */
|
||||
".-.-.", /* + */
|
||||
"--..--", /* , */
|
||||
"-....-", /* - */
|
||||
".-.-.-", /* . */
|
||||
"-..-.", /* / */
|
||||
"-----", /* 0 */
|
||||
".----", /* 1 */
|
||||
"..---", /* 2 */
|
||||
"...--", /* 3 */
|
||||
"....-", /* 4 */
|
||||
".....", /* 5 */
|
||||
"-....", /* 6 */
|
||||
"--...", /* 7 */
|
||||
"---..", /* 8 */
|
||||
"----.", /* 9 */
|
||||
"---...", /* : */
|
||||
"-.-.-.", /* ; */
|
||||
NULL, /* < */
|
||||
"-...-", /* = */
|
||||
NULL, /* < */
|
||||
"..--..", /* ? */
|
||||
".--.-.", /* @ */
|
||||
".-", /* A */
|
||||
"-...", /* B */
|
||||
"-.-.",
|
||||
"-..",
|
||||
".",
|
||||
"..-.",
|
||||
"--.",
|
||||
"....",
|
||||
"..",
|
||||
".---",
|
||||
"-.-",
|
||||
".-..",
|
||||
"--",
|
||||
"-.",
|
||||
"---",
|
||||
".--.",
|
||||
"--.-",
|
||||
".-.",
|
||||
"...",
|
||||
"-",
|
||||
"..-",
|
||||
"...-",
|
||||
".--",
|
||||
"-..-",
|
||||
"-.--",
|
||||
"--..", /* Z */
|
||||
NULL, /* [ */
|
||||
"-..-.", /* \ */
|
||||
NULL, /* ] */
|
||||
NULL, /* ^ */
|
||||
NULL, /* _ */
|
||||
".----.", /* ` */
|
||||
".-", /* a */
|
||||
"-...", /* b */
|
||||
"-.-.",
|
||||
"-..",
|
||||
".",
|
||||
"..-.",
|
||||
"--.",
|
||||
"....",
|
||||
"..",
|
||||
".---",
|
||||
"-.-",
|
||||
".-..",
|
||||
"--",
|
||||
"-.",
|
||||
"---",
|
||||
".--.",
|
||||
"--.-",
|
||||
".-.",
|
||||
"...",
|
||||
"-",
|
||||
"..-",
|
||||
"...-",
|
||||
".--",
|
||||
"-..-",
|
||||
"-.--",
|
||||
"--..", /* z */
|
||||
NULL, /* { */
|
||||
NULL, /* | */
|
||||
NULL, /* } */
|
||||
NULL, /* ~ */
|
||||
NULL, /* DEL */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL,
|
||||
".-..-.", /* « (angle quotes, <<, 171) */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
".-..-.", /* » (angle quotes, >>, 187) */
|
||||
NULL, NULL, NULL, NULL,
|
||||
".--.-", /* `A */
|
||||
".--.-", /* 'A */
|
||||
".-", /* ^A */
|
||||
".-", /* ~A */
|
||||
".-.-", /* "A */
|
||||
".--.-", /* °A */
|
||||
".- .", /* AE */
|
||||
"-.-..", /* ,C */
|
||||
"..-..", /* `E */
|
||||
"..-..", /* 'E */
|
||||
".", /* ^E */
|
||||
".", /* "E */
|
||||
"..", /* `I */
|
||||
"..", /* 'I */
|
||||
"..", /* ^I */
|
||||
"..", /* "I */
|
||||
"..--.", /* -D */
|
||||
"--.--", /* ~N */
|
||||
"---", /* `O */
|
||||
"---", /* 'O */
|
||||
"---", /* ^O */
|
||||
"---", /* ~O */
|
||||
"---.", /* "O */
|
||||
NULL, /* x */
|
||||
"---.", /* /O */
|
||||
"..-", /* `U */
|
||||
"..-", /* 'U */
|
||||
"..-", /* ^U */
|
||||
"..--", /* "U */
|
||||
"-.--", /* 'Y */
|
||||
".--..", /* 'thorn' */
|
||||
"...--..", /* sz */
|
||||
".--.-", /* `a */
|
||||
".--.-", /* 'a */
|
||||
".-", /* ^a */
|
||||
".-", /* ~a */
|
||||
".-.-", /* "a */
|
||||
".--.-", /* °a */
|
||||
".- .", /* ae */
|
||||
"-.-..", /* ,c */
|
||||
"..-..", /* `e */
|
||||
"..-..", /* 'e */
|
||||
".", /* ^e */
|
||||
".", /* "e */
|
||||
"..", /* `i */
|
||||
"..", /* 'i */
|
||||
"..", /* ^i */
|
||||
"..", /* "i */
|
||||
"..--.", /* -d */
|
||||
"--.--", /* ~n */
|
||||
"---", /* `o */
|
||||
"---", /* 'o */
|
||||
"---", /* ^o */
|
||||
"---", /* ~o */
|
||||
"---.", /* "o */
|
||||
NULL, /* ./. */
|
||||
"---.", /* /o */
|
||||
"..-", /* `u */
|
||||
"..-", /* 'u */
|
||||
"..-", /* ^u */
|
||||
"..--", /* "u */
|
||||
"-.--", /* 'y */
|
||||
".--..", /* 'thorn' */
|
||||
"-.--" /* "y */
|
||||
};
|
||||
|
||||
const static char *utf8table[] = {
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* first 128 are identical*/
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* to iso8859, so that */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* will be used instead */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* - 127 */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* control characters ...*/
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* -159 */
|
||||
" ", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, ".-..-.", NULL, NULL, NULL, NULL, /* 171 << */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, ".-..-.", NULL, NULL, NULL, NULL, /* 187 >> */
|
||||
/* same as in ISO8859 */
|
||||
".--.-", /* `A */ /* 192 ... */
|
||||
".--.-", /* 'A */
|
||||
".-", /* ^A */
|
||||
".-", /* ~A */
|
||||
".-.-", /* "A */
|
||||
".--.-", /* °A */
|
||||
".- .", /* AE */
|
||||
"-.-..", /* ,C */
|
||||
"..-..", /* `E */
|
||||
"..-..", /* 'E */
|
||||
".", /* ^E */
|
||||
".", /* "E */
|
||||
"..", /* `I */
|
||||
"..", /* 'I */
|
||||
"..", /* ^I */
|
||||
"..", /* "I */
|
||||
"..--.", /* -D according to Wikipedia */
|
||||
"--.--", /* ~N */
|
||||
"---", /* `O */
|
||||
"---", /* 'O */
|
||||
"---", /* ^O */
|
||||
"---", /* ~O */
|
||||
"---.", /* "O */
|
||||
NULL, /* x */
|
||||
"---.", /* /O */
|
||||
"..-", /* `U */
|
||||
"..-", /* 'U */
|
||||
"..-", /* ^U */
|
||||
"..--", /* "U */
|
||||
"-.--", /* 'Y */
|
||||
".--..", /* 'thorn', acc to Wikipedia */
|
||||
"...--..", /* sz */
|
||||
".--.-", /* `a */
|
||||
".--.-", /* 'a */
|
||||
".-", /* ^a */
|
||||
".-", /* ~a */
|
||||
".-.-", /* "a */
|
||||
".--.-", /* °a */
|
||||
".- .", /* ae */
|
||||
"-.-..", /* ,c */
|
||||
"..-..", /* `e */
|
||||
"..-..", /* 'e */
|
||||
".", /* ^e */
|
||||
".", /* "e */
|
||||
"..", /* `i */
|
||||
"..", /* 'i */
|
||||
"..", /* ^i */
|
||||
"..", /* "i */
|
||||
"..--.", /* -d Wiki */
|
||||
"--.--", /* ~n */
|
||||
"---", /* `o */
|
||||
"---", /* 'o */
|
||||
"---", /* ^o */
|
||||
"---", /* ~o */
|
||||
"---.", /* "o */
|
||||
NULL, /* ./. */
|
||||
"---.", /* /o */
|
||||
"..-", /* `u */
|
||||
"..-", /* 'u */
|
||||
"..-", /* ^u */
|
||||
"..--", /* "u */
|
||||
"-.--", /* 'y */
|
||||
".--..", /* 'thorn' */
|
||||
"-.--", /* "y */ /* 255 */
|
||||
".-", ".-", ".-", ".-", ".-", ".-", /* 256-261, As with different hats */
|
||||
/* 262-269 Cs with different hats */
|
||||
/* 264-265 -.-.. acc. to Wikipedia, Esperanto etc. */
|
||||
"-.-.", "-.-.", "-.-..", "-.-..", "-.-.", "-.-.", "-.-.", "-.-.",
|
||||
"-..", "-..", "-..", "-..", /* 270-273 Ds with different stuff */
|
||||
/* 274-283 different Es */
|
||||
".", ".", ".", ".", ".", ".", ".", ".", ".", ".",
|
||||
/* 284-291 different Gs, first 2 according to Wikipedia (Esperanto) */
|
||||
"--.-.", "--.-.", "--.", "--.", "--.", "--.", "--.", "--.",
|
||||
/* 292-295 different Hs, first two Esperanto (was: -.--. before, but was
|
||||
* changed: "Originale, Hx estis -.--. sed tio kolizie estas "(" en ITU-T
|
||||
* F.1, do Hx nun prefere estas ----") */
|
||||
"----", "----", "....", "....",
|
||||
/* 296-305 different Is */
|
||||
"..", "..", "..", "..", "..", "..", "..", "..", "..", "..",
|
||||
/* 306-307 IJ ligatures */
|
||||
".. .---", ".. .---",
|
||||
/* 308-309 Js, from Wikipedia, Esperanto */
|
||||
".---.", ".---.",
|
||||
/* 310-312 Ks */
|
||||
"-.-", "-.-", "-.-",
|
||||
/* 313-322 different Ls */
|
||||
".-..", ".-..", ".-..", ".-..", ".-..", ".-..", ".-..",
|
||||
".-..", ".-..", ".-..",
|
||||
/* 323-331 different Ns */
|
||||
"-.", "-.", "-.", "-.", "-.", "-.", "-.", "-.", "-.",
|
||||
/* 332-337 Os */
|
||||
"---", "---", "---", "---", "---", "---",
|
||||
/* 338-339 OEs */
|
||||
"---.", "---.",
|
||||
/* 340-345 Rs */
|
||||
".-.", ".-.", ".-.", ".-.", ".-.", ".-.",
|
||||
/* 346-353 Ss, Wikipedia */
|
||||
"...", "...", "...-.", "...-.", "...", "...", "...", "...",
|
||||
/* 354-359 Ts */
|
||||
"-", "-", "-", "-", "-", "-",
|
||||
/* 360-371 Us, 364. 365 Esperanto */
|
||||
"..-", "..-", "..-", "..-", "..--", "..--", "..-", "..-", "..-",
|
||||
"..-", "..-", "..-",
|
||||
/* 372-373 Ws */
|
||||
".--", ".--",
|
||||
/* 374-377 Ys */
|
||||
"-.--", "-.--", "-.--",
|
||||
/* 377-382 Zs */
|
||||
"--..", "--..", "--..", "--..", "--..", "--..",
|
||||
/* 383 S */
|
||||
"...",
|
||||
/* 384-389 Bs */
|
||||
"-...", "-...", "-...", "-...", "-...", "-...",
|
||||
NULL, NULL, NULL, /* all kind of weird stuff */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL,
|
||||
/* Standard Greek Alphabet */
|
||||
".-", "-..." , "--.", "-..", ".", "--..", "....",
|
||||
"-.-.", "..", "-.-", ".-..", "--", "-.", "-..-", "---",
|
||||
".--.", ".-.", NULL, "...", "-", "-.--", "..-.", "----",
|
||||
"--.-", ".--", NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 1023 */
|
||||
|
||||
/* 1024-1039, cyrillic (Serbian, Macedonian, Ukrainian) UC */
|
||||
".", ".", "-.. .---", "--. .---", ".", "-.. --..", "..", "..",
|
||||
".---", ".-.. .---", "-. .---", "-.-.", "-.- .---", "..", "..-","-.. --..",
|
||||
|
||||
/* 32 letters of Russian Cyrillic alphabet */
|
||||
".-", "-...", ".--", "--.", "-..", ".", "...-", /* 1040-1071 */
|
||||
"--..", "..",".---", "-.-", ".-..", "--", "-.", /* uppercase */
|
||||
"---", ".--.", ".-.", "...", "-", "..-", "..-.", /* cyrillic */
|
||||
"....", "-.-.", "---.", "----", "--.-", "-..-",
|
||||
"-.--", "-..-", "..-..", "..--", ".-.-",
|
||||
".-", "-...", ".--", "--.", "-..", ".", "...-", /* 1072-1103 */
|
||||
"--..", "..",".---", "-.-", ".-..", "--", "-.", /* lowercase */
|
||||
"---", ".--.", ".-.", "...", "-", "..-", "..-.", /* cyrillic */
|
||||
"....", "-.-.", "---.", "----", "--.-", "-..-",
|
||||
"-.--", "-..-", "..-..", "..--", ".-.-",
|
||||
|
||||
/* 1004-1119, cyrillic (Serbian, Macedonian, Ukrainian) UC */
|
||||
".", ".", "-.. .---", "--. .---", ".", "-.. --..", "..", "..",
|
||||
".---", ".-.. .---", "-. .---", "-.-.", "-.- .---", "..", "..-","-.. --..",
|
||||
|
||||
/* 1120 - 1487 to be done... */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/* 1488-1514 Hebrew according to Wikipedia */
|
||||
".-", "-...", "--.", "-..", "---", ".", "--..", "....",
|
||||
"..-", "..", NULL, "-.-", ".-..", NULL, "--", "-.", NULL,
|
||||
"-.-.", ".---", NULL, ".--.", NULL, ".--", "--.-", ".-.", "...",
|
||||
"-", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/* Arabic Alphabet, as per Wikipedia.
|
||||
* Nobody is possibly ever going to use this :-)
|
||||
* 1569-1610
|
||||
*/
|
||||
".", NULL, NULL, NULL, NULL, NULL,
|
||||
".-", "-...", NULL, "-", "-.-.",
|
||||
".---", "....", "---", "-..", "--..", ".-.", "---.", "...",
|
||||
"----", "-..-", "...-", "..-", "-.--", ".-.-", "--.", NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, "..-.", "--.-", "-.-",
|
||||
".-..", "--", "-.", NULL, ".--", NULL, "..", NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL /* 1920 */
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
void help (void);
|
||||
void openfile (void);
|
||||
|
||||
FILE *infile;
|
||||
FILE *outfile;
|
||||
FILE *outmain;
|
||||
int lines;
|
||||
char o[256];
|
||||
char os[256];
|
||||
char name[256];
|
||||
int part = 0;
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
|
||||
int c,l;
|
||||
int cutnext = 0;
|
||||
|
||||
if (argc != 4) {
|
||||
help();
|
||||
return(0);
|
||||
}
|
||||
else {
|
||||
if ((lines = atoi(argv[1])) == 0) {
|
||||
fprintf(stderr, "Lines must be > 0\n");
|
||||
exit(1);
|
||||
}
|
||||
if ((infile = fopen(argv[2], "r")) == NULL) {
|
||||
fprintf(stderr, "Unable to open %s.\n", argv[2]);
|
||||
exit(1);
|
||||
}
|
||||
strcpy(name, argv[3]);
|
||||
}
|
||||
|
||||
openfile();
|
||||
|
||||
sprintf(os, "split-%s", argv[2]);
|
||||
if ((outmain = fopen(os, "w")) == NULL) {
|
||||
fprintf(stderr, "Error, couldn't open file %s.", o);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
l = 0;
|
||||
while ((c = getc(infile)) != EOF) {
|
||||
|
||||
if (c == '\r') { continue;}
|
||||
|
||||
if (c == '\n') {
|
||||
l++;
|
||||
}
|
||||
|
||||
if (l > (lines-1)) {
|
||||
cutnext = 1;
|
||||
}
|
||||
|
||||
putc(c, outfile);
|
||||
putc(c, outmain);
|
||||
|
||||
if ((c == '.') && cutnext) {
|
||||
l = 0;
|
||||
cutnext = 0;
|
||||
part++;
|
||||
openfile();
|
||||
fputs("\n ^ \n", outmain);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void help (void) {
|
||||
printf("e2csplit - Usage: e2csplit lines input.txt\n");
|
||||
}
|
||||
|
||||
|
||||
void openfile (void) {
|
||||
|
||||
if (part != 0) {
|
||||
fclose(outfile);
|
||||
}
|
||||
|
||||
sprintf(o, "%s-%04d.txt", name, part);
|
||||
if ((outfile = fopen(o, "w")) == NULL) {
|
||||
fprintf(stderr, "Error, couldn't open file %s.", o);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
.TH ebook2cw 1 "MARCH 2008" Linux "User Manuals"
|
||||
.SH NAME
|
||||
ebook2cw \- convert ebooks to morse mp3s
|
||||
.SH SYNOPSIS
|
||||
.B ebook2cw
|
||||
[OPTIONS]
|
||||
.SH DESCRIPTION
|
||||
.B ebook2cw
|
||||
ebook2cw is a command line program which converts a plain text ebook to morse
|
||||
code MP3 files. It works on several platforms, including Windows and Linux.
|
||||
|
||||
A number of CW and MP3 parameters can be changed from their default values, by
|
||||
command line switches. These are (default values in brackets):
|
||||
|
||||
.B -w wpm
|
||||
- CW speed in words per minute [25]
|
||||
|
||||
.B -e wpm
|
||||
- Effective CW speed. If set, the spaces are sent at this speed instead of the
|
||||
character speed set by -w ("Farnsworth").
|
||||
|
||||
.B -W x
|
||||
- Extra Word spacing. Similar to -e, but only affects the inter-word spacing,
|
||||
not the inter-character spacing.
|
||||
|
||||
.B -f freq
|
||||
- audio frequency in Hz [600]
|
||||
|
||||
.B -Q minutes
|
||||
- Increase CW speed (QRQ) by 1 WpM in intervals of `minutes'. Speed will be
|
||||
reset to the initial value at the start of each chapter. [0]
|
||||
|
||||
.B -n
|
||||
- Disables resetting the speed when using the -Q option.
|
||||
|
||||
.B -R risetime
|
||||
- risetime, in samples [50]
|
||||
|
||||
.B -F falltime
|
||||
- falltime, samples [50]
|
||||
|
||||
.B -s samplerate
|
||||
- samplerate for the MP3 file [11025]
|
||||
|
||||
.B -b bitrate
|
||||
- MP3 bitrate, kbps [16]
|
||||
|
||||
.B -q quality
|
||||
- MP3 quality, 1 (best) to 9 (worst). CW still sounds very good with the worst quality, encoding time is greatly reduced. [5]
|
||||
|
||||
.B -c chapter separator
|
||||
- Split chapters at this string. [CHAPTER]
|
||||
|
||||
.B -o outfile-name
|
||||
- Output filename (chapter number and .mp3 will be appended) [Chapter]
|
||||
|
||||
.B -a author
|
||||
- Author for the ID3 tag. Use quotes for strings with spaces (e.g. "JW Goethe")
|
||||
|
||||
.B -t title
|
||||
- Title for the ID3 tag. Use quotes for strings with spaces (e.g. "Faust II")
|
||||
|
||||
.B -k comment
|
||||
- Comment for the ID3 tag. Use quotes for strings with spaces.
|
||||
|
||||
.B -y year
|
||||
- Year for the ID3 tag.
|
||||
|
||||
.B -u
|
||||
- Switches input encoding format to UTF-8. Currently supported alphabets
|
||||
include Latin, Greek, Hebrew, Arabic and Cyrillic. Default is ISO 8859-1.
|
||||
|
||||
.B -S [ISO|UTF]
|
||||
- Shows a table of all available morse symbols for the ISO 8859-1 and UTF-8
|
||||
character sets. Output in HTML format.
|
||||
|
||||
CW prosigns can be generated by enclosing arbitrary letters in angle brackets
|
||||
(e.g. <AR>, <SK>, ...).
|
||||
|
||||
.SH AUTHOR
|
||||
Fabian Kurz, DJ1YFK <mail@fkurz.net>
|
||||
|
||||
http://fkurz.net/ham/ebook2cw.html
|
||||
.SH "SEE ALSO"
|
||||
.BR morse (1)
|
||||
|
|
@ -0,0 +1,638 @@
|
|||
/*
|
||||
ebook2cw - converts an ebook to morse mp3s
|
||||
|
||||
Copyright (C) 2008 Fabian Kurz, DJ1YFK
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 2 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
|
||||
Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
source code looks properly indented with tw=4
|
||||
|
||||
*/
|
||||
|
||||
#include "lame/lame.h"
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "codetables.h"
|
||||
|
||||
#ifndef VERSION
|
||||
#define VERSION "0.0.0"
|
||||
#endif
|
||||
|
||||
#define PCMBUFFER 220500 /* 20 seconds at 11kHz, for one word. plenty. */
|
||||
#define MP3BUFFER 285000 /* abt 1.25*PCMBUFFER + 7200, as recommended */
|
||||
|
||||
#define ISO8859 0
|
||||
#define UTF8 1
|
||||
|
||||
lame_global_flags *gfp;
|
||||
|
||||
FILE *outfile;
|
||||
FILE *infile;
|
||||
|
||||
/* MP3 samplerate, bitrate, quality. */
|
||||
int samplerate = 11025;
|
||||
int brate = 16;
|
||||
int quality = 5;
|
||||
|
||||
/* CW parameters */
|
||||
int wpm = 25;
|
||||
int freq = 600;
|
||||
int rt = 50; /* rise/fall time in samples */
|
||||
int ft = 50;
|
||||
int qrq = 0; /* rise speed by 1 WpM every qrq minutes */
|
||||
int reset = 1; /* reset QRQed speed every chapter? */
|
||||
int farnsworth = 0; /* extra spacing in dit-lengths */
|
||||
float ews = 0.0; /* extra word spaces */
|
||||
int pBT = 1; /* send <BT> (-...-) for each new paragraph */
|
||||
|
||||
/* the buffers for dit, dah, raw pcm and mp3 output, will be calloc'ed to the
|
||||
* default values, and -if needed- realloc'ed to the needed size */
|
||||
|
||||
short int *dit_buf;
|
||||
short int *dah_buf;
|
||||
short int *inpcm;
|
||||
unsigned char *mp3buffer;
|
||||
|
||||
int inpcm_size;
|
||||
int mp3buffer_size;
|
||||
|
||||
int ditlen=0; /* number of samples in a 'dit' */
|
||||
|
||||
/* Chapters are split by this string */
|
||||
char chapterstr[80]="CHAPTER";
|
||||
char chapterfilename[80]="Chapter"; /* full filename: Chapter%04d.mp3 */
|
||||
|
||||
/* ID3-tag data: author and title */
|
||||
char id3_author[80]="CW audio book";
|
||||
char id3_title[80]="";
|
||||
char id3_comment[80]="";
|
||||
char id3_year[5]="";
|
||||
|
||||
/* functions */
|
||||
int init_cw (int wpm, int freq, int rt, int ft);
|
||||
void help (void);
|
||||
void showcodes (int i);
|
||||
void makeword(char * text, int encoding);
|
||||
void closefile (int letter, int cw);
|
||||
void openfile (int chapter);
|
||||
void buf_check(int j);
|
||||
|
||||
/* main */
|
||||
|
||||
int main (int argc, char** argv) {
|
||||
int pos, i, original_wpm;
|
||||
int encoding = ISO8859;
|
||||
int c;
|
||||
char word[1024]=""; /* will be cut when > 1024 chars long */
|
||||
int chapter = 0;
|
||||
int cw = 0, tw = 0, qw = 0; /* chapter words, total words, qrq words */
|
||||
|
||||
infile = stdin;
|
||||
|
||||
while((i=getopt(argc,argv, "o:w:W:e:f:R:F:s:b:q:c:a:t:k:y:Q:S:phun"))!= -1) {
|
||||
switch (i) {
|
||||
case 'w':
|
||||
if ((wpm = atoi(optarg)) < 1) {
|
||||
fprintf(stderr, "Error: Speed (-w) must be > 0!\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
case 'f':
|
||||
freq = atoi(optarg);
|
||||
break;
|
||||
case 'R':
|
||||
rt = atoi(optarg);
|
||||
break;
|
||||
case 'F':
|
||||
ft = atoi(optarg);
|
||||
break;
|
||||
case 's':
|
||||
samplerate = atoi(optarg);
|
||||
break;
|
||||
case 'b':
|
||||
brate = atoi(optarg);
|
||||
break;
|
||||
case 'q':
|
||||
quality = atoi(optarg);
|
||||
break;
|
||||
case 'c':
|
||||
strncpy(chapterstr, optarg, 78);
|
||||
break;
|
||||
case 'o':
|
||||
strncpy(chapterfilename, optarg, 78);
|
||||
break;
|
||||
case 'a':
|
||||
strncpy(id3_author, optarg, 78);
|
||||
break;
|
||||
case 't':
|
||||
strncpy(id3_title, optarg, 75);
|
||||
break;
|
||||
case 'k':
|
||||
strncpy(id3_comment, optarg, 78);
|
||||
break;
|
||||
case 'y':
|
||||
strncpy(id3_year, optarg, 4);
|
||||
break;
|
||||
case 'Q':
|
||||
if ((qrq = atoi(optarg)) < 1) {
|
||||
fprintf(stderr, "Error: QRQ time (-Q) must be > 0!\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
case 'u':
|
||||
encoding = UTF8;
|
||||
break;
|
||||
case 'S':
|
||||
if (strstr(optarg, "ISO")) {
|
||||
showcodes(1);
|
||||
}
|
||||
else {
|
||||
showcodes(0);
|
||||
}
|
||||
break;
|
||||
case 'e': /* effective speed in WpM */
|
||||
if ((farnsworth = atoi(optarg)) < 1) {
|
||||
fprintf(stderr, "Error: Eff. speed (-e) must be > 0!\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
case 'W':
|
||||
ews = atof(optarg);
|
||||
break;
|
||||
case 'n':
|
||||
reset = 0;
|
||||
break;
|
||||
case 'p':
|
||||
pBT = 0;
|
||||
break;
|
||||
case 'h':
|
||||
default:
|
||||
help();
|
||||
} /* switch */
|
||||
} /* while */
|
||||
|
||||
if (optind < argc) { /* something left? if so, use as infile */
|
||||
if ((argv[optind][0] != '-') && (argv[optind][0] != '\0')) {
|
||||
if ((infile = fopen(argv[optind], "r")) == NULL) {
|
||||
fprintf(stderr, "Error: Cannot open file %s. Exit.\n",
|
||||
argv[optind]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* init lame */
|
||||
gfp = lame_init();
|
||||
lame_set_num_channels(gfp,1);
|
||||
lame_set_in_samplerate(gfp, samplerate);
|
||||
lame_set_brate(gfp, brate);
|
||||
lame_set_mode(gfp,1);
|
||||
lame_set_quality(gfp, quality);
|
||||
|
||||
if (lame_init_params(gfp) < 0) {
|
||||
fprintf(stderr, "Failed: lame_init_params(gfp) \n");
|
||||
return(1);
|
||||
}
|
||||
|
||||
/* init pcm_buf and mp3_buf */
|
||||
|
||||
if ((inpcm = calloc(PCMBUFFER, sizeof(short int))) == NULL) {
|
||||
fprintf(stderr, "Error: Can't allocate inpcm[%d]!\n", PCMBUFFER);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
else {
|
||||
inpcm_size = PCMBUFFER;
|
||||
}
|
||||
|
||||
if ((mp3buffer = calloc(MP3BUFFER, sizeof(unsigned char))) == NULL) {
|
||||
fprintf(stderr, "Error: Can't allocate mp3buffer[%d]!\n", MP3BUFFER);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
else {
|
||||
mp3buffer_size = MP3BUFFER;
|
||||
}
|
||||
|
||||
printf("ebook2cw %s - (c) 2008 by Fabian Kurz, DJ1YFK\n", VERSION);
|
||||
printf("Speed: %dwpm, Freq: %dHz, Chapter: >%s<, Encoding: %s\n",
|
||||
wpm, freq, chapterstr, encoding == UTF8 ? "UTF-8" : "ISO 8859-1");
|
||||
|
||||
printf("Effective speed: %dwpm, ", farnsworth ? farnsworth : wpm);
|
||||
printf("Extra word spaces: %1.1f, ", ews);
|
||||
printf("QRQ: %dmin, reset QRQ: %s\n\n", qrq, reset ? "yes" : "no");
|
||||
|
||||
ditlen = init_cw(wpm, freq, rt, ft); /* generate raw dit, dah */
|
||||
|
||||
strcat(chapterstr, " ");
|
||||
|
||||
/* read STDIN, assemble full words (anything ending in ' ') to 'word' and
|
||||
* generate CW, write to file by 'makeword'. words with > 1024 characters
|
||||
* will be split */
|
||||
|
||||
original_wpm = wpm; /* may be changed by QRQing */
|
||||
chapter = 0;
|
||||
openfile(chapter);
|
||||
|
||||
pos=0;
|
||||
while ((c = getc(infile)) != EOF) {
|
||||
|
||||
if (c == '\r') /* DOS linebreaks */
|
||||
continue;
|
||||
|
||||
word[pos++] = c;
|
||||
|
||||
if ((c == ' ') || (c == '\n') || (pos == 1024)) {
|
||||
word[pos] = '\0';
|
||||
if (strcmp(chapterstr, word) == 0) { /* new chapter */
|
||||
closefile(chapter, cw);
|
||||
cw = 0;
|
||||
chapter++;
|
||||
|
||||
if (qrq && reset) {
|
||||
wpm = original_wpm;
|
||||
ditlen = init_cw(wpm, freq, rt, ft);
|
||||
qw = 0;
|
||||
}
|
||||
|
||||
openfile(chapter);
|
||||
}
|
||||
makeword(word, encoding);
|
||||
cw++; tw++; qw++;
|
||||
|
||||
word[0] = '\0';
|
||||
pos = 0;
|
||||
|
||||
/* Every 'qrq' minutes (qrq*wpm words), speed up 1 WpM */
|
||||
if (qw == (qrq*wpm)) {
|
||||
wpm += 1;
|
||||
ditlen = init_cw(wpm, freq, rt, ft);
|
||||
printf("QRQ: %dwpm\n", wpm);
|
||||
qw = 0;
|
||||
}
|
||||
|
||||
} /* word */
|
||||
} /* eof */
|
||||
|
||||
closefile(chapter, cw);
|
||||
|
||||
free(mp3buffer);
|
||||
free(inpcm);
|
||||
|
||||
/* factor 0.9 due to many 'words' which aren't actually words, like '\n' */
|
||||
printf("Total words: %d, total time: %d min\n", tw, (int) ((tw/wpm)*0.9));
|
||||
|
||||
lame_close(gfp);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* init_cw - generates a dit and a dah to dit_buf and dah_buf */
|
||||
|
||||
int init_cw (int wpm, int freq, int rt, int ft) {
|
||||
int x, len;
|
||||
double val;
|
||||
|
||||
/* set farnsworth to samples */
|
||||
if (farnsworth) {
|
||||
|
||||
if (farnsworth > wpm) {
|
||||
fprintf(stderr, "Error: Effective speed (-e %d) must be lower "
|
||||
"than character speed (-w %d)!\n", farnsworth, wpm);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
|
||||
farnsworth = (int) (6.0*samplerate/(5.0*farnsworth));
|
||||
}
|
||||
|
||||
/* printf("Initializing CW buffers at %d WpM: ", wpm); */
|
||||
|
||||
/* dah */
|
||||
len = (int) (3.0*6.0*samplerate/(5.0*wpm)); /* in samples */
|
||||
|
||||
/* ditlen not set == init_cw has not been called yet */
|
||||
if (!ditlen) {
|
||||
/* allocate memory for the buffer */
|
||||
if ((dah_buf = calloc(len, sizeof(short int))) == NULL) {
|
||||
fprintf(stderr, "Error: Can't allocate dah_buf[%d]\n", len);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
for (x=0; x < len; x++) {
|
||||
val = sin(2*M_PI*freq*x/samplerate);
|
||||
if (x < rt) /* shaping with sin^2 */
|
||||
val *= pow(sin(M_PI*x/(2.0*rt)),2);
|
||||
|
||||
if (x > (len-ft))
|
||||
val *= pow((sin(2*M_PI*(x-(len-ft)+ft)/(4*ft))), 2);
|
||||
|
||||
dah_buf[x] = (short int) (val * 20000.0);
|
||||
}
|
||||
|
||||
/* printf("dah_buf[%d], ", x); */
|
||||
|
||||
/* dit */
|
||||
len = (int) (6.0*samplerate/(5.0*wpm)); /* in samples */
|
||||
|
||||
/* ditlen not set == init_cw has not been called yet */
|
||||
if (!ditlen) {
|
||||
/* allocate memory for the buffer */
|
||||
if ((dit_buf = calloc(len, sizeof(short int))) == NULL) {
|
||||
fprintf(stderr, "Error: Can't allocate dit_buf[%d]\n", len);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
for (x=0; x < len; x++) {
|
||||
val = sin(2*M_PI*freq*x/samplerate);
|
||||
if (x < rt)
|
||||
val *= pow(sin(M_PI*x/(2.0*rt)), 2);
|
||||
|
||||
if (x > (len-ft))
|
||||
val *= pow((sin(2*M_PI*(x-(len-ft)+ft)/(4*ft))), 2);
|
||||
|
||||
dit_buf[x] = (short int) (val * 20000.0);
|
||||
}
|
||||
|
||||
/* printf("dit_buf[%d]\n\n", x); */
|
||||
|
||||
return x; /* = length of dit/silence */
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* makeword -- converts 'text' to CW by concatenating dit_buf amd dah_bufs,
|
||||
* encodes this to MP3 and writes to open filehandle outfile */
|
||||
|
||||
void makeword(char * text, int encoding) {
|
||||
const char *code; /* CW code as . and - */
|
||||
int outbytes;
|
||||
|
||||
int c, i, j, u, w;
|
||||
int prosign = 0;
|
||||
unsigned char last=0; /* for utf8 2-byte characters */
|
||||
|
||||
j = 0; /* position in 'inpcm' buffer */
|
||||
|
||||
for (i = 0; i < strlen(text); i++) {
|
||||
c = (unsigned char) text[i];
|
||||
code = NULL;
|
||||
|
||||
if (c == '\n') { /* Same for UTF8 and ISO8859 */
|
||||
if ((strlen(text) == 1) && pBT) /* paragraph */
|
||||
code = " -...- ";
|
||||
else
|
||||
code = " ";
|
||||
}
|
||||
else if (c == '<') { /* prosign on */
|
||||
prosign = 1;
|
||||
continue;
|
||||
}
|
||||
else if ((c == '>') && prosign) { /* prosign off */
|
||||
prosign = 0;
|
||||
code = ""; /* only inserts letter space */
|
||||
}
|
||||
else if (encoding == ISO8859) {
|
||||
code = iso8859[c];
|
||||
}
|
||||
else if (encoding == UTF8) {
|
||||
/* Character may be 1-byte ASCII or 2-byte UTF8 */
|
||||
if (!(c & 128)) { /* MSB = 0 -> 7bit ASCII */
|
||||
code = iso8859[c]; /* subset of iso8859 */
|
||||
}
|
||||
else {
|
||||
if (last && (c < 192) ) { /* this is the 2nd byte */
|
||||
/* 110yyyyy 10zzzzzz -> 00000yyy yyzzzzzz */
|
||||
c = ((last & 31) << 6) | (c & 63);
|
||||
code = utf8table[c];
|
||||
last = 0;
|
||||
}
|
||||
else { /* this is the first byte */
|
||||
last = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (last) continue; /* first of two-byte character read */
|
||||
|
||||
/* Not found anything ... */
|
||||
if (code == NULL) {
|
||||
code = " ";
|
||||
if (c < 255) {
|
||||
fprintf(stderr, "Warning: don't know CW for '%c'\n", c);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "Warning: don't know CW for unicode &#%d;\n", c);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* code contains letter as ./-, now assemble pcm buffer */
|
||||
|
||||
for (w = 0; w < strlen(code) ; w++) {
|
||||
|
||||
/* make sure the inpcm buffer doesn't run full,
|
||||
* with a conservative margin. reallocate memory if neccesary */
|
||||
|
||||
buf_check(j);
|
||||
|
||||
|
||||
c = code[w];
|
||||
|
||||
if (c == '.')
|
||||
for (u=0; u < ditlen; u++)
|
||||
inpcm[++j] = dit_buf[u];
|
||||
else if (c == '-')
|
||||
for (u=0; u < (3*ditlen); u++)
|
||||
inpcm[++j] = dah_buf[u];
|
||||
else /* word space */
|
||||
for (u=0;u < (int)(1+7*ews)*(farnsworth ? farnsworth : ditlen); u++)
|
||||
inpcm[++j] = 0;
|
||||
|
||||
for (u=0; u < ditlen; u++) /* space of one dit length */
|
||||
inpcm[++j] = 0;
|
||||
} /* foreach dot/dash */
|
||||
|
||||
if (prosign == 0) {
|
||||
for (u=0; u < (farnsworth ? 3*farnsworth-ditlen : 2*ditlen); u++)
|
||||
inpcm[++j] = 0;
|
||||
}
|
||||
|
||||
} /* foreach letter */
|
||||
|
||||
/* j = total length of samples in 'inpcm' */
|
||||
|
||||
outbytes = lame_encode_buffer(gfp, inpcm, inpcm, j, mp3buffer, mp3buffer_size);
|
||||
if (outbytes < 0) {
|
||||
fprintf(stderr, "Error: lame_encode_buffer returned %d. Exit.\n", outbytes);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (fwrite(mp3buffer, sizeof(char), outbytes, outfile) != outbytes) {
|
||||
fprintf(stderr, "Error: Writing %db to file failed. Exit.\n", outbytes);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* closefile -- finishes writing the current file, flushes the encoder buffer */
|
||||
|
||||
void closefile (int letter, int cw) {
|
||||
int outbytes;
|
||||
char mp3filename[80] = "";
|
||||
|
||||
printf("words: %d, minutes: %d\n", cw, (int) ((cw/wpm)*0.9));
|
||||
|
||||
snprintf(mp3filename, 80, "%s%04d.mp3", chapterfilename, letter);
|
||||
printf("Finishing %s\n\n", mp3filename);
|
||||
|
||||
outbytes = lame_encode_flush(gfp, mp3buffer, mp3buffer_size);
|
||||
|
||||
if (outbytes < 0) {
|
||||
fprintf(stderr, "Error: lame_encode_buffer returned %d.\n", outbytes);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (fwrite(mp3buffer, sizeof(char), outbytes, outfile) != outbytes) {
|
||||
fprintf(stderr, "Error: Writing %db to file failed. Exit.\n", outbytes);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
fclose(outfile);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* openfile -- starts a new chapter by opening Chapter%d.mp3 */
|
||||
|
||||
void openfile (int chapter) {
|
||||
char mp3filename[80] = "";
|
||||
static char tmp[80] = "";
|
||||
|
||||
snprintf(mp3filename, 80, "%s%04d.mp3", chapterfilename, chapter);
|
||||
printf("Starting %s\n", mp3filename);
|
||||
|
||||
if ((outfile = fopen(mp3filename, "wb")) == NULL) {
|
||||
fprintf(stderr, "Error: Failed to open %s\n", mp3filename);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
snprintf(tmp, 79, "%s - %d", id3_title, chapter); /* generate title */
|
||||
|
||||
id3tag_init(gfp);
|
||||
id3tag_set_artist(gfp, id3_author);
|
||||
id3tag_set_year(gfp, id3_year);
|
||||
id3tag_set_title(gfp, tmp);
|
||||
id3tag_set_comment(gfp, id3_comment);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void help (void) {
|
||||
printf("ebook2cw v%s - (c) 2008 by Fabian Kurz, DJ1YFK, http://fkurz.net/\n", VERSION);
|
||||
printf("\nThis is free software, and you are welcome to redistribute it\n");
|
||||
printf("under certain conditions (see COPYING).\n");
|
||||
printf("\n");
|
||||
printf("ebook2cw [-w wpm] [-f freq] [-R risetime] [-F falltime]\n");
|
||||
printf(" [-s samplerate] [-b mp3bitrate] [-q mp3quality] [-p]\n");
|
||||
printf(" [-c chapter-separator] [-o outfile-name] [-Q minutes]\n");
|
||||
printf(" [-a author] [-t title] [-k comment] [-y year]\n");
|
||||
printf(" [-u] [-S ISO|UTF] [-n] [-e eff.wpm] [-W space]\n");
|
||||
printf(" [infile]\n\n");
|
||||
printf("defaults: 25 WpM, 600Hz, RT=FT=50, s=11025Hz, b=16kbps,\n");
|
||||
printf(" c=\"CHAPTER\", o=\"Chapter\" infile = stdin\n");
|
||||
printf("\n");
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* showcodes
|
||||
* Generates a HTML table of the available CW symbols in codetables.h
|
||||
* i = 1 -> ISO 8859-1, i=0 -> UTF-8
|
||||
*/
|
||||
|
||||
void showcodes (int i) {
|
||||
int k;
|
||||
int n = i ? 256 : 1921;
|
||||
|
||||
printf("<html><head><META HTTP-EQUIV=\"CONTENT-TYPE\" CONTENT=\"text/html;"
|
||||
"charset=%s\"></head>\n", i ? "iso-8859-1" : "utf-8");
|
||||
printf("<body><h1>ebook2cw codetables.h</h1>\n");
|
||||
printf("<h2>%s</h2><table border=\"1\">\n", i ? "ISO 8859-1" : "UTF-8");
|
||||
printf("<tr><th>Decimal</th><th>Symbol</th><th>CW</th></tr>\n");
|
||||
|
||||
for (k=0; k < n; k++) {
|
||||
printf("<tr>");
|
||||
|
||||
if ((k < 128+i*128) && (iso8859[k] != NULL)) {
|
||||
printf("<td>%d</td><td>&#%d;</td><td>%s</td>", k, k, iso8859[k]);
|
||||
}
|
||||
else if (utf8table[k] != NULL) {
|
||||
printf("<td>%d</td><td>&#%d;</td><td>%s</td>", k, k, utf8table[k]);
|
||||
}
|
||||
else {
|
||||
printf("<td>%d</td><td>&#%d;</td><td> </td>", k, k);
|
||||
}
|
||||
|
||||
printf("</tr>\n");
|
||||
}
|
||||
|
||||
printf("</table></body></html>\n");
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* make sure the inpcm-buffer doesn't run full.
|
||||
* have to consider the effects of Farnsworth and extra word spacing */
|
||||
|
||||
void buf_check (int j) {
|
||||
int max;
|
||||
|
||||
/* maximum bytes that may be added for one dot or dah, for either
|
||||
* farnsworth or non-farnsworth */
|
||||
|
||||
max = farnsworth ? (int) ((4+7*ews)*(farnsworth)) : (6+7*ews) * ditlen;
|
||||
max += 10000; /* some margin to feel safe ... */
|
||||
|
||||
if (j > inpcm_size - max) {
|
||||
inpcm_size += max;
|
||||
mp3buffer_size += (int) (1.25 * max + 7200.0);
|
||||
if ((inpcm = realloc(inpcm, inpcm_size*sizeof(short int)))== NULL)
|
||||
fprintf(stderr, "Error: Can't realloc inpcm[%d]\n", inpcm_size);
|
||||
|
||||
if ((mp3buffer = realloc(mp3buffer, mp3buffer_size*sizeof(char)))
|
||||
== NULL)
|
||||
fprintf(stderr, "Error: Can't realloc mp3buffer[%d]\n",
|
||||
mp3buffer_size);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
62d421896c97d736c568596eccc8f6ee ebook2cw
|
||||
ad3f42d1e79116176d646d888ab933a5 ebook2cw.exe
|
||||
|
|
@ -0,0 +1,426 @@
|
|||
/*
|
||||
ebook2cw - converts an ebook to morse mp3s
|
||||
|
||||
Copyright (C) 2007 Fabian Kurz, DJ1YFK
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 2 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
|
||||
Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
source code looks properly indented with tw=4
|
||||
|
||||
*/
|
||||
|
||||
#include "lame/lame.h"
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#define PI 3.141592
|
||||
#define VERSION "0.2.0"
|
||||
|
||||
#define PCMBUFFER 220500 /* 20 seconds at 11kHz, for one word. plenty. */
|
||||
#define MP3BUFFER 285000 /* abt 1.25*PCMBUFFER + 7200, as recommended */
|
||||
#define DAHBUFFER 11025 /* a single dah, max 1 second @ 11kHz */
|
||||
#define DITBUFFER 3675 /* a single dit, max 1/3 second */
|
||||
|
||||
lame_global_flags *gfp;
|
||||
|
||||
FILE *outfile;
|
||||
FILE *infile;
|
||||
|
||||
/* MP3 samplerate, bitrate, quality. */
|
||||
int samplerate = 11025;
|
||||
int brate = 16;
|
||||
int quality = 3;
|
||||
|
||||
/* CW parameters */
|
||||
int wpm = 25;
|
||||
int freq = 600;
|
||||
int rt = 50; /* rise/fall time in samples */
|
||||
int ft = 50;
|
||||
|
||||
|
||||
short int dit_buf[DITBUFFER];
|
||||
short int dah_buf[DAHBUFFER];
|
||||
short int inpcm[PCMBUFFER];
|
||||
unsigned char mp3buffer[MP3BUFFER];
|
||||
|
||||
int ditlen; /* number of samples in a 'dit' */
|
||||
|
||||
/* Chapters are split by this string */
|
||||
char chapterstr[80]="CHAPTER";
|
||||
char chapterfilename[80]="Chapter"; /* full filename: Chapter%02d.mp3 */
|
||||
|
||||
const static char *codetable[] = {
|
||||
".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..",".---",
|
||||
"-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",
|
||||
".--","-..-","-.--","--..","-----",".----","..---","...--","....-",".....",
|
||||
"-....", "--...","---..","----."};
|
||||
|
||||
/* functions */
|
||||
int init_cw (int wpm, int freq, int rt, int ft);
|
||||
void help (void);
|
||||
void makeword(char * text);
|
||||
void closefile (int letter, int cw);
|
||||
void openfile (int chapter);
|
||||
|
||||
/* main */
|
||||
|
||||
int main (int argc, char** argv) {
|
||||
int pos, i;
|
||||
char c;
|
||||
char word[80]="";
|
||||
int chapter = 0;
|
||||
int cw = 0, tw = 0; /* chapter words, total words */
|
||||
|
||||
infile = stdin;
|
||||
|
||||
if (argc == 1) {
|
||||
help();
|
||||
}
|
||||
|
||||
while((i = getopt(argc, argv, "o:w:f:R:F:s:b:q:c:h")) != -1) {
|
||||
switch (i) {
|
||||
case 'w':
|
||||
wpm = atoi(optarg);
|
||||
break;
|
||||
case 'f':
|
||||
freq = atoi(optarg);
|
||||
break;
|
||||
case 'R':
|
||||
rt = atoi(optarg);
|
||||
break;
|
||||
case 'F':
|
||||
ft = atoi(optarg);
|
||||
break;
|
||||
case 's':
|
||||
samplerate = atoi(optarg);
|
||||
break;
|
||||
case 'b':
|
||||
brate = atoi(optarg);
|
||||
break;
|
||||
case 'q':
|
||||
quality = atoi(optarg);
|
||||
break;
|
||||
case 'c':
|
||||
strcpy(chapterstr, optarg);
|
||||
break;
|
||||
case 'o':
|
||||
strcpy(chapterfilename, optarg);
|
||||
break;
|
||||
case 'h':
|
||||
default:
|
||||
help();
|
||||
} /* switch */
|
||||
} /* while */
|
||||
|
||||
if (optind < argc) { /* something left? if so, use as infile */
|
||||
if ((argv[optind][0] != '-') && (argv[optind][0] != '\0')) {
|
||||
if ((infile = fopen(argv[optind], "r")) == NULL) {
|
||||
fprintf(stderr, "Error: Cannot open file %s. Exit.\n",
|
||||
argv[optind]);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf("ebook2cw %s - (c) 2007 by Fabian Kurz, DJ1YFK\n", VERSION);
|
||||
printf("Speed: %d WpM, Freq: %dHz, Chapter: >%s<\n", wpm, freq, chapterstr);
|
||||
|
||||
|
||||
/* init lame */
|
||||
gfp = lame_init();
|
||||
lame_set_num_channels(gfp,1);
|
||||
lame_set_in_samplerate(gfp, samplerate);
|
||||
lame_set_brate(gfp, brate);
|
||||
lame_set_mode(gfp,1);
|
||||
lame_set_quality(gfp, quality);
|
||||
|
||||
if (lame_init_params(gfp) < 0) {
|
||||
fprintf(stderr, "Failed: lame_init_params(gfp) \n");
|
||||
return(1);
|
||||
}
|
||||
else {
|
||||
printf("Initialized lame; samplerate=%d, bitrate=%d, quality=%d\n",
|
||||
samplerate, brate, quality);
|
||||
}
|
||||
|
||||
ditlen = init_cw(wpm, freq, rt, ft); /* generate raw dit, dah, silence */
|
||||
|
||||
strcat(chapterstr, " ");
|
||||
|
||||
/* read STDIN, assemble full words (anything ending in ' ') to 'word' and
|
||||
* generate CW, write to file by 'makeword' */
|
||||
|
||||
chapter = 0;
|
||||
openfile(chapter);
|
||||
|
||||
pos=0;
|
||||
while ((c = getc(infile)) != EOF) {
|
||||
|
||||
if (c == '\r') { /* DOS linebreaks */
|
||||
continue;
|
||||
}
|
||||
|
||||
word[pos++] = c;
|
||||
|
||||
if ((c == ' ') || (c == '\n')) {
|
||||
word[pos] = '\0';
|
||||
if (strcmp(chapterstr, word) == 0) { /* new chapter */
|
||||
closefile(chapter, cw);
|
||||
cw=0;
|
||||
chapter++;
|
||||
openfile(chapter);
|
||||
}
|
||||
makeword(word);
|
||||
cw++; tw++;
|
||||
|
||||
word[0] = '\0';
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
}
|
||||
/* eof */
|
||||
|
||||
closefile(chapter, cw);
|
||||
|
||||
/* factor 0.8 due to many 'words' which aren't actually words, like '\n' */
|
||||
printf("Total words: %d, total time: %d min\n", tw, (int) ((tw/wpm)*0.8));
|
||||
|
||||
lame_close(gfp);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* init_cw - generates a dit and a dah to dit_buf and dah_buf */
|
||||
|
||||
int init_cw (int wpm, int freq, int rt, int ft) {
|
||||
int x;
|
||||
double val;
|
||||
|
||||
/* dah */
|
||||
int len = (int) 3.0*6.0*samplerate/(5.0*wpm); /* in samples */
|
||||
|
||||
if (len >= DAHBUFFER) {
|
||||
fprintf(stderr, "dah_buf[%d] too small, needed size: %d. Exit.\n",
|
||||
DAHBUFFER, len);
|
||||
exit(1);
|
||||
}
|
||||
else {
|
||||
printf("Initializing CW buffers: ");
|
||||
}
|
||||
|
||||
for (x=0; x < len-1; x++) {
|
||||
val = sin(2*PI*freq*x/samplerate);
|
||||
if (x < rt) { /* shaping with sin^2 */
|
||||
val *= pow(sin(PI*x/(2.0*rt)),2);
|
||||
}
|
||||
if (x > (len-ft)) {
|
||||
val *= pow((sin(2*PI*(x-(len-ft)+ft)/(4*ft))), 2);
|
||||
}
|
||||
|
||||
dah_buf[x] = (int) (val * 20000.0);
|
||||
}
|
||||
|
||||
printf("dah_buf[%d], ", x);
|
||||
|
||||
/* dit */
|
||||
len = (int) 6.0*samplerate/(5.0*wpm); /* in samples */
|
||||
|
||||
for (x=0; x < len-1; x++) {
|
||||
val = sin(2*PI*freq*x/samplerate);
|
||||
if (x < rt) {
|
||||
val *= pow(sin(PI*x/(2.0*rt)), 2);
|
||||
}
|
||||
if (x > (len-ft)) {
|
||||
val *= pow((sin(2*PI*(x-(len-ft)+ft)/(4*ft))), 2);
|
||||
}
|
||||
dit_buf[x] = (int) (val * 20000.0);
|
||||
}
|
||||
|
||||
printf("dit_buf[%d]\n\n", x);
|
||||
|
||||
return x; /* = length of dit/silence */
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* makeword -- converts 'text' to CW by concatenating dit_buf amd dah_bufs,
|
||||
* encodes this to MP3 and writes to open filehandle outfile */
|
||||
|
||||
void makeword(char * text) {
|
||||
const char *code; /* CW code as . and - */
|
||||
int outbytes;
|
||||
|
||||
int c;
|
||||
int i,u,w;
|
||||
int j;
|
||||
|
||||
j = 0; /* position in 'inpcm' buffer */
|
||||
|
||||
for (i = 0; i < strlen(text); i++) {
|
||||
c = toupper(text[i]);
|
||||
|
||||
if (c > 64 && c < 91) { /* trouble with isalpha() under Win32 */
|
||||
code = codetable[c-65]; /* even with locale = C ...? */
|
||||
}
|
||||
else if (c > 47 && c < 58) {
|
||||
code = codetable[c-22];
|
||||
}
|
||||
else if (c == '.') { code = ".-.-.-"; }
|
||||
else if (c == ',') { code = "--..--"; }
|
||||
else if (c == '=') { code = "-...-"; }
|
||||
else if (c == '?') { code = "..--.."; }
|
||||
else if (c == '-') { code = "-....-"; }
|
||||
else if (c==228 || c==196 || c==-28 || c==-60) { code = ".-.-"; } /* ae */
|
||||
else if (c==252 || c==220 || c==-4 || c==-36) { code = "..--"; } /* ue */
|
||||
else if (c==246 || c==214 || c==-10 || c==-42) { code = "---."; } /* oe */
|
||||
else if (c == 223 || c == -33) { code = "... --.."; } /* sz */
|
||||
else if (c == '(') { code = "-.--."; }
|
||||
else if (c == ')') { code = "-.--.-"; }
|
||||
else if (c == '!') { code = ".-.-.-"; }
|
||||
else if (c == ';') { code = "-.-.-."; }
|
||||
else if (c == ':') { code = "---..."; }
|
||||
else if (c == '"') { code = ".-..-."; }
|
||||
else if (c == '\'') { code = ".----."; }
|
||||
else if (c == ' ') { code = " "; }
|
||||
else if (c == '\n') {
|
||||
if (strlen(text) == 1) {
|
||||
code = " -...- "; /* new paragraph */
|
||||
}
|
||||
else {
|
||||
code = " ";
|
||||
}
|
||||
}
|
||||
else {
|
||||
code = " ";
|
||||
fprintf(stderr, "Warning: don't know CW for '%c'\n", (char) c);
|
||||
}
|
||||
|
||||
/* code contains word as ./-, now assemble pcm buffer */
|
||||
|
||||
for (w = 0; w < strlen(code) ; w++) {
|
||||
|
||||
/* make sure the inpcm buffer (length: PCMBUFFER) doesn't run full */
|
||||
if (j > PCMBUFFER-(4*ditlen)) {
|
||||
fprintf(stderr, "inpcm buffer too small. exit.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
c = code[w];
|
||||
|
||||
if (c == '.') {
|
||||
for (u=0; u < ditlen; u++) { inpcm[++j] = dit_buf[u]; }
|
||||
}
|
||||
else if (c == '-') {
|
||||
for (u=0; u < (3*ditlen); u++) { inpcm[++j] = dah_buf[u]; }
|
||||
}
|
||||
else {
|
||||
for (u=0; u < ditlen; u++) { inpcm[++j] = 0; }
|
||||
}
|
||||
|
||||
for (u=0; u < ditlen; u++) { inpcm[++j] = 0; }
|
||||
}
|
||||
|
||||
for (u=0; u < (2*ditlen); u++) { inpcm[++j] = 0; } /* inter word space */
|
||||
|
||||
}
|
||||
|
||||
/* j = total length of samples in 'inpcm' */
|
||||
|
||||
outbytes = lame_encode_buffer(gfp, inpcm, inpcm, j, mp3buffer,
|
||||
sizeof(mp3buffer));
|
||||
if (outbytes < 0) {
|
||||
fprintf(stderr, "Error: lame_encode_buffer returned %d. Exit.\n", outbytes);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (fwrite(mp3buffer, sizeof(char), outbytes, outfile) != outbytes) {
|
||||
fprintf(stderr, "Error: Writing %db to file failed. Exit.\n", outbytes);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* closefile -- finishes writing the current file, flushes the encoder buffer */
|
||||
|
||||
void closefile (int letter, int cw) {
|
||||
int outbytes;
|
||||
char mp3filename[80] = "";
|
||||
|
||||
printf("words: %d, minutes: %d\n", cw, (int) ((cw/wpm)*0.8));
|
||||
|
||||
sprintf(mp3filename, "%s%02d.mp3", chapterfilename, letter);
|
||||
printf("Finishing %s\n\n", mp3filename);
|
||||
|
||||
outbytes = lame_encode_flush(gfp, mp3buffer, sizeof(mp3buffer));
|
||||
|
||||
if (outbytes < 0) {
|
||||
fprintf(stderr, "Error: lame_encode_buffer returned %d.\n", outbytes);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (fwrite(mp3buffer, sizeof(char), outbytes, outfile) != outbytes) {
|
||||
fprintf(stderr, "Error: Writing %db to file failed. Exit.\n", outbytes);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fclose(outfile);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* openfile -- starts a new chapter by opening Chapter%d.mp3 */
|
||||
|
||||
void openfile (int chapter) {
|
||||
char mp3filename[80] = "";
|
||||
sprintf(mp3filename, "%s%02d.mp3", chapterfilename, chapter);
|
||||
printf("Starting %s\n", mp3filename);
|
||||
|
||||
if ((outfile = fopen(mp3filename, "wb")) == NULL) {
|
||||
fprintf(stderr, "Error: Failed to open %s\n", mp3filename);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void help (void) {
|
||||
printf("ebook2cw v%s - (c) 2007 by Fabian Kurz, DJ1YFK\n", VERSION);
|
||||
printf("\n");
|
||||
printf("ebook2cw [-w wpm] [-f freq] [-R risetime] [-F falltime]\n");
|
||||
printf(" [-s samplerate] [-b mp3bitrate] [-q mp3quality]\n");
|
||||
printf(" [-c chapter-separator] [-o outfile-name] [infile]\n\n");
|
||||
printf("defaults: 25 WpM, 600Hz, RT=FT=50, s=11025Hz, b=16kbps,\n");
|
||||
printf(" c=\"CHAPTER\", o=\"Chapter\" infile = stdin\n");
|
||||
printf("\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,428 @@
|
|||
/*
|
||||
ebook2cw - converts an ebook to morse mp3s
|
||||
|
||||
Copyright (C) 2007 Fabian Kurz, DJ1YFK
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 2 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
|
||||
Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
source code looks properly indented with tw=4
|
||||
|
||||
*/
|
||||
|
||||
#include "lame/lame.h"
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#define PI 3.141592
|
||||
#define VERSION "0.3.0"
|
||||
|
||||
#define PCMBUFFER 220500 /* 20 seconds at 11kHz, for one word. plenty. */
|
||||
#define MP3BUFFER 285000 /* abt 1.25*PCMBUFFER + 7200, as recommended */
|
||||
#define DAHBUFFER 11025 /* a single dah, max 1 second @ 11kHz */
|
||||
#define DITBUFFER 3675 /* a single dit, max 1/3 second */
|
||||
|
||||
lame_global_flags *gfp;
|
||||
|
||||
FILE *outfile;
|
||||
FILE *infile;
|
||||
|
||||
/* MP3 samplerate, bitrate, quality. */
|
||||
int samplerate = 11025;
|
||||
int brate = 16;
|
||||
int quality = 3;
|
||||
|
||||
/* CW parameters */
|
||||
int wpm = 25;
|
||||
int freq = 600;
|
||||
int rt = 50; /* rise/fall time in samples */
|
||||
int ft = 50;
|
||||
|
||||
|
||||
short int dit_buf[DITBUFFER];
|
||||
short int dah_buf[DAHBUFFER];
|
||||
short int inpcm[PCMBUFFER];
|
||||
unsigned char mp3buffer[MP3BUFFER];
|
||||
|
||||
int ditlen; /* number of samples in a 'dit' */
|
||||
|
||||
/* Chapters are split by this string */
|
||||
char chapterstr[80]="CHAPTER";
|
||||
char chapterfilename[80]="Chapter"; /* full filename: Chapter%02d.mp3 */
|
||||
|
||||
const static char *codetable[] = {
|
||||
".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..",".---",
|
||||
"-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",
|
||||
".--","-..-","-.--","--..","-----",".----","..---","...--","....-",".....",
|
||||
"-....", "--...","---..","----."};
|
||||
|
||||
/* functions */
|
||||
int init_cw (int wpm, int freq, int rt, int ft);
|
||||
void help (void);
|
||||
void makeword(char * text);
|
||||
void closefile (int letter, int cw);
|
||||
void openfile (int chapter);
|
||||
|
||||
/* main */
|
||||
|
||||
int main (int argc, char** argv) {
|
||||
int pos, i;
|
||||
char c;
|
||||
char word[80]="";
|
||||
int chapter = 0;
|
||||
int cw = 0, tw = 0; /* chapter words, total words */
|
||||
|
||||
infile = stdin;
|
||||
|
||||
if (argc == 1) {
|
||||
help();
|
||||
}
|
||||
|
||||
while((i = getopt(argc, argv, "o:w:f:R:F:s:b:q:c:h")) != -1) {
|
||||
switch (i) {
|
||||
case 'w':
|
||||
wpm = atoi(optarg);
|
||||
break;
|
||||
case 'f':
|
||||
freq = atoi(optarg);
|
||||
break;
|
||||
case 'R':
|
||||
rt = atoi(optarg);
|
||||
break;
|
||||
case 'F':
|
||||
ft = atoi(optarg);
|
||||
break;
|
||||
case 's':
|
||||
samplerate = atoi(optarg);
|
||||
break;
|
||||
case 'b':
|
||||
brate = atoi(optarg);
|
||||
break;
|
||||
case 'q':
|
||||
quality = atoi(optarg);
|
||||
break;
|
||||
case 'c':
|
||||
strcpy(chapterstr, optarg);
|
||||
break;
|
||||
case 'o':
|
||||
strcpy(chapterfilename, optarg);
|
||||
break;
|
||||
case 'h':
|
||||
default:
|
||||
help();
|
||||
} /* switch */
|
||||
} /* while */
|
||||
|
||||
if (optind < argc) { /* something left? if so, use as infile */
|
||||
if ((argv[optind][0] != '-') && (argv[optind][0] != '\0')) {
|
||||
if ((infile = fopen(argv[optind], "r")) == NULL) {
|
||||
fprintf(stderr, "Error: Cannot open file %s. Exit.\n",
|
||||
argv[optind]);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf("ebook2cw %s - (c) 2007 by Fabian Kurz, DJ1YFK\n", VERSION);
|
||||
printf("Speed: %d WpM, Freq: %dHz, Chapter: >%s<\n", wpm, freq, chapterstr);
|
||||
|
||||
|
||||
/* init lame */
|
||||
gfp = lame_init();
|
||||
lame_set_num_channels(gfp,1);
|
||||
lame_set_in_samplerate(gfp, samplerate);
|
||||
lame_set_brate(gfp, brate);
|
||||
lame_set_mode(gfp,1);
|
||||
lame_set_quality(gfp, quality);
|
||||
|
||||
if (lame_init_params(gfp) < 0) {
|
||||
fprintf(stderr, "Failed: lame_init_params(gfp) \n");
|
||||
return(1);
|
||||
}
|
||||
else {
|
||||
printf("Initialized lame; samplerate=%d, bitrate=%d, quality=%d\n",
|
||||
samplerate, brate, quality);
|
||||
}
|
||||
|
||||
ditlen = init_cw(wpm, freq, rt, ft); /* generate raw dit, dah, silence */
|
||||
|
||||
strcat(chapterstr, " ");
|
||||
|
||||
/* read STDIN, assemble full words (anything ending in ' ') to 'word' and
|
||||
* generate CW, write to file by 'makeword' */
|
||||
|
||||
chapter = 0;
|
||||
openfile(chapter);
|
||||
|
||||
pos=0;
|
||||
while ((c = getc(infile)) != EOF) {
|
||||
|
||||
if (c == '\r') { /* DOS linebreaks */
|
||||
continue;
|
||||
}
|
||||
|
||||
word[pos++] = c;
|
||||
|
||||
if ((c == ' ') || (c == '\n')) {
|
||||
word[pos] = '\0';
|
||||
if (strcmp(chapterstr, word) == 0) { /* new chapter */
|
||||
closefile(chapter, cw);
|
||||
cw=0;
|
||||
chapter++;
|
||||
openfile(chapter);
|
||||
}
|
||||
makeword(word);
|
||||
cw++; tw++;
|
||||
|
||||
word[0] = '\0';
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
}
|
||||
/* eof */
|
||||
|
||||
closefile(chapter, cw);
|
||||
|
||||
/* factor 0.8 due to many 'words' which aren't actually words, like '\n' */
|
||||
printf("Total words: %d, total time: %d min\n", tw, (int) ((tw/wpm)*0.8));
|
||||
|
||||
lame_close(gfp);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* init_cw - generates a dit and a dah to dit_buf and dah_buf */
|
||||
|
||||
int init_cw (int wpm, int freq, int rt, int ft) {
|
||||
int x;
|
||||
double val;
|
||||
|
||||
/* dah */
|
||||
int len = (int) 3.0*6.0*samplerate/(5.0*wpm); /* in samples */
|
||||
|
||||
if (len >= DAHBUFFER) {
|
||||
fprintf(stderr, "dah_buf[%d] too small, needed size: %d. Exit.\n",
|
||||
DAHBUFFER, len);
|
||||
exit(1);
|
||||
}
|
||||
else {
|
||||
printf("Initializing CW buffers: ");
|
||||
}
|
||||
|
||||
for (x=0; x < len-1; x++) {
|
||||
val = sin(2*PI*freq*x/samplerate);
|
||||
if (x < rt) { /* shaping with sin^2 */
|
||||
val *= pow(sin(PI*x/(2.0*rt)),2);
|
||||
}
|
||||
if (x > (len-ft)) {
|
||||
val *= pow((sin(2*PI*(x-(len-ft)+ft)/(4*ft))), 2);
|
||||
}
|
||||
|
||||
dah_buf[x] = (int) (val * 20000.0);
|
||||
}
|
||||
|
||||
printf("dah_buf[%d], ", x);
|
||||
|
||||
/* dit */
|
||||
len = (int) 6.0*samplerate/(5.0*wpm); /* in samples */
|
||||
|
||||
for (x=0; x < len-1; x++) {
|
||||
val = sin(2*PI*freq*x/samplerate);
|
||||
if (x < rt) {
|
||||
val *= pow(sin(PI*x/(2.0*rt)), 2);
|
||||
}
|
||||
if (x > (len-ft)) {
|
||||
val *= pow((sin(2*PI*(x-(len-ft)+ft)/(4*ft))), 2);
|
||||
}
|
||||
dit_buf[x] = (int) (val * 20000.0);
|
||||
}
|
||||
|
||||
printf("dit_buf[%d]\n\n", x);
|
||||
|
||||
return x; /* = length of dit/silence */
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* makeword -- converts 'text' to CW by concatenating dit_buf amd dah_bufs,
|
||||
* encodes this to MP3 and writes to open filehandle outfile */
|
||||
|
||||
void makeword(char * text) {
|
||||
const char *code; /* CW code as . and - */
|
||||
int outbytes;
|
||||
|
||||
int c;
|
||||
int i,u,w;
|
||||
int j;
|
||||
|
||||
j = 0; /* position in 'inpcm' buffer */
|
||||
|
||||
for (i = 0; i < strlen(text); i++) {
|
||||
c = toupper(text[i]);
|
||||
|
||||
if (c > 64 && c < 91) { /* trouble with isalpha() under Win32 */
|
||||
code = codetable[c-65]; /* even with locale = C ...? */
|
||||
}
|
||||
else if (c > 47 && c < 58) {
|
||||
code = codetable[c-22];
|
||||
}
|
||||
else if (c == '.') { code = ".-.-.-"; }
|
||||
else if (c == ',') { code = "--..--"; }
|
||||
else if (c == '=') { code = "-...-"; }
|
||||
else if (c == '?') { code = "..--.."; }
|
||||
else if (c == '-') { code = "-....-"; }
|
||||
else if (c==228 || c==196 || c==-28 || c==-60) { code = ".-.-"; } /* ae */
|
||||
else if (c==252 || c==220 || c==-4 || c==-36) { code = "..--"; } /* ue */
|
||||
else if (c==246 || c==214 || c==-10 || c==-42) { code = "---."; } /* oe */
|
||||
else if (c == 223 || c == -33) { code = "... --.."; } /* sz */
|
||||
else if (c == '(') { code = "-.--."; }
|
||||
else if (c == ')') { code = "-.--.-"; }
|
||||
else if (c == '!') { code = ".-.-.-"; }
|
||||
else if (c == ';') { code = "-.-.-."; }
|
||||
else if (c == '/') { code = "-..-."; }
|
||||
else if (c == '@') { code = ".--.-."; }
|
||||
else if (c == ':') { code = "---..."; }
|
||||
else if (c == '"') { code = ".-..-."; }
|
||||
else if (c == '\'') { code = ".----."; }
|
||||
else if (c == ' ') { code = " "; }
|
||||
else if (c == '\n') {
|
||||
if (strlen(text) == 1) {
|
||||
code = " -...- "; /* new paragraph */
|
||||
}
|
||||
else {
|
||||
code = " ";
|
||||
}
|
||||
}
|
||||
else {
|
||||
code = " ";
|
||||
fprintf(stderr, "Warning: don't know CW for '%c'\n", (char) c);
|
||||
}
|
||||
|
||||
/* code contains word as ./-, now assemble pcm buffer */
|
||||
|
||||
for (w = 0; w < strlen(code) ; w++) {
|
||||
|
||||
/* make sure the inpcm buffer (length: PCMBUFFER) doesn't run full */
|
||||
if (j > PCMBUFFER-(4*ditlen)) {
|
||||
fprintf(stderr, "inpcm buffer too small. exit.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
c = code[w];
|
||||
|
||||
if (c == '.') {
|
||||
for (u=0; u < ditlen; u++) { inpcm[++j] = dit_buf[u]; }
|
||||
}
|
||||
else if (c == '-') {
|
||||
for (u=0; u < (3*ditlen); u++) { inpcm[++j] = dah_buf[u]; }
|
||||
}
|
||||
else {
|
||||
for (u=0; u < ditlen; u++) { inpcm[++j] = 0; }
|
||||
}
|
||||
|
||||
for (u=0; u < ditlen; u++) { inpcm[++j] = 0; }
|
||||
}
|
||||
|
||||
for (u=0; u < (2*ditlen); u++) { inpcm[++j] = 0; } /* inter word space */
|
||||
|
||||
}
|
||||
|
||||
/* j = total length of samples in 'inpcm' */
|
||||
|
||||
outbytes = lame_encode_buffer(gfp, inpcm, inpcm, j, mp3buffer,
|
||||
sizeof(mp3buffer));
|
||||
if (outbytes < 0) {
|
||||
fprintf(stderr, "Error: lame_encode_buffer returned %d. Exit.\n", outbytes);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (fwrite(mp3buffer, sizeof(char), outbytes, outfile) != outbytes) {
|
||||
fprintf(stderr, "Error: Writing %db to file failed. Exit.\n", outbytes);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* closefile -- finishes writing the current file, flushes the encoder buffer */
|
||||
|
||||
void closefile (int letter, int cw) {
|
||||
int outbytes;
|
||||
char mp3filename[80] = "";
|
||||
|
||||
printf("words: %d, minutes: %d\n", cw, (int) ((cw/wpm)*0.8));
|
||||
|
||||
sprintf(mp3filename, "%s%02d.mp3", chapterfilename, letter);
|
||||
printf("Finishing %s\n\n", mp3filename);
|
||||
|
||||
outbytes = lame_encode_flush(gfp, mp3buffer, sizeof(mp3buffer));
|
||||
|
||||
if (outbytes < 0) {
|
||||
fprintf(stderr, "Error: lame_encode_buffer returned %d.\n", outbytes);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (fwrite(mp3buffer, sizeof(char), outbytes, outfile) != outbytes) {
|
||||
fprintf(stderr, "Error: Writing %db to file failed. Exit.\n", outbytes);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fclose(outfile);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* openfile -- starts a new chapter by opening Chapter%d.mp3 */
|
||||
|
||||
void openfile (int chapter) {
|
||||
char mp3filename[80] = "";
|
||||
sprintf(mp3filename, "%s%02d.mp3", chapterfilename, chapter);
|
||||
printf("Starting %s\n", mp3filename);
|
||||
|
||||
if ((outfile = fopen(mp3filename, "wb")) == NULL) {
|
||||
fprintf(stderr, "Error: Failed to open %s\n", mp3filename);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void help (void) {
|
||||
printf("ebook2cw v%s - (c) 2007 by Fabian Kurz, DJ1YFK\n", VERSION);
|
||||
printf("\n");
|
||||
printf("ebook2cw [-w wpm] [-f freq] [-R risetime] [-F falltime]\n");
|
||||
printf(" [-s samplerate] [-b mp3bitrate] [-q mp3quality]\n");
|
||||
printf(" [-c chapter-separator] [-o outfile-name] [infile]\n\n");
|
||||
printf("defaults: 25 WpM, 600Hz, RT=FT=50, s=11025Hz, b=16kbps,\n");
|
||||
printf(" c=\"CHAPTER\", o=\"Chapter\" infile = stdin\n");
|
||||
printf("\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
|
|
@ -0,0 +1,280 @@
|
|||
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
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
0.4.0 / 2007-12-17 Fabian Kurz <mail@fkurz.net>
|
||||
* Implemented dynamic memory allocation.
|
||||
|
||||
0.3.0 / 2007-11-28 Fabian Kurz <mail@fkurz.net>
|
||||
* Added forgotten characters: @ and /.
|
||||
|
||||
0.2.0 / 2007-11-27 Fabian Kurz <mail@fkurz.net>
|
||||
|
||||
* Fixed handling of umlauts (öäüß)
|
||||
* The chapter separator is now case sensitive.
|
||||
|
||||
0.1.0 / 2007-11-22 Fabian Kurz <mail@fkurz.net>
|
||||
|
||||
* Initial release of ebook2cw.
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
# ebook2cw Makefile -- Fabian Kurz, DJ1YFK -- http://fkurz.net/ham/ebook2cw.html
|
||||
|
||||
VERSION=0.4.0
|
||||
DESTDIR ?= /usr
|
||||
|
||||
all: ebook2cw
|
||||
|
||||
ebook2cw: ebook2cw.c
|
||||
gcc ebook2cw.c -Wall -lm -lmp3lame -D VERSION=\"$(VERSION)\" -o ebook2cw
|
||||
|
||||
static:
|
||||
gcc -static ebook2cw.c -lmp3lame -lm -D VERSION=\"$(VERSION)\" -o ebook2cw
|
||||
|
||||
install:
|
||||
install -d -v $(DESTDIR)/share/man/man1/
|
||||
install -d -v $(DESTDIR)/bin/
|
||||
install -s -m 0755 ebook2cw $(DESTDIR)/bin/
|
||||
install -m 0644 ebook2cw.1 $(DESTDIR)/share/man/man1/
|
||||
|
||||
uninstall:
|
||||
rm -f $(DESTDIR)/bin/ebook2cw
|
||||
rm -f $(DESTDIR)/share/man/man1/ebook2cw.1
|
||||
|
||||
clean:
|
||||
rm -f ebook2cw *~ *.mp3
|
||||
|
||||
dist:
|
||||
sed 's/Version [0-9].[0-9].[0-9]/Version $(VERSION)/g' README > README2
|
||||
rm -f README
|
||||
mv README2 README
|
||||
rm -f releases/ebook2cw-$(VERSION).tar.gz
|
||||
rm -rf releases/ebook2cw-$(VERSION)
|
||||
mkdir ebook2cw-$(VERSION)
|
||||
cp ebook2cw.c ChangeLog ebook2cw.1 \
|
||||
COPYING Makefile ebook2cw-$(VERSION)
|
||||
tar -zcf ebook2cw-$(VERSION).tar.gz ebook2cw-$(VERSION)
|
||||
mv ebook2cw-$(VERSION) releases/
|
||||
mv ebook2cw-$(VERSION).tar.gz releases/
|
||||
md5sum releases/*.gz > releases/md5sums.txt
|
||||
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
.TH ebook2cw 1 "JUNE 2007" Linux "User Manuals"
|
||||
.SH NAME
|
||||
ebook2cw \- convert ebooks to morse mp3s
|
||||
.SH SYNOPSIS
|
||||
.B ebook2cw
|
||||
[OPTIONS]
|
||||
.SH DESCRIPTION
|
||||
.B ebook2cw
|
||||
ebook2cw is a command line program which converts a plain text ebook to morse
|
||||
code MP3 files. It works on several platforms, including Windows and Linux.
|
||||
|
||||
A number of CW and MP3 parameters can be changed from their default values, by
|
||||
command line switches. These are (default values in brackets):
|
||||
|
||||
.B -w wpm
|
||||
- CW speed in words per minute [25]
|
||||
|
||||
.B -f freq
|
||||
- audio frequency in Hz [600]
|
||||
|
||||
.B -R risetime
|
||||
- risetime, in samples [50]
|
||||
|
||||
.B -F falltime
|
||||
- falltime, samples [50]
|
||||
|
||||
.B -s samplerate
|
||||
- samplerate for the MP3 file [11025]
|
||||
|
||||
.B -b bitrate
|
||||
- MP3 bitrate, kbps [16]
|
||||
|
||||
.B -q quality
|
||||
- MP3 quality, 1 (best) to 9 (worst) [3]
|
||||
|
||||
.B -c chapter separator
|
||||
- Split chapters at this string [CHAPTER]
|
||||
|
||||
.B -o outfile-name
|
||||
- Output filename (chapter number and .mp3 will be appended) [Chapter]
|
||||
|
||||
|
||||
.SH AUTHOR
|
||||
Fabian Kurz, DJ1YFK <mail@fkurz.net>
|
||||
|
||||
http://fkurz.net/ham/ebook2cw.html
|
||||
.SH "SEE ALSO"
|
||||
.BR morse (1)
|
||||
|
|
@ -0,0 +1,468 @@
|
|||
/*
|
||||
ebook2cw - converts an ebook to morse mp3s
|
||||
|
||||
Copyright (C) 2007 Fabian Kurz, DJ1YFK
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 2 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
|
||||
Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
source code looks properly indented with tw=4
|
||||
|
||||
*/
|
||||
|
||||
#include "lame/lame.h"
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#ifndef VERSION
|
||||
#define VERSION "0.0.0"
|
||||
#endif
|
||||
|
||||
#define PCMBUFFER 220500 /* 20 seconds at 11kHz, for one word. plenty. */
|
||||
#define MP3BUFFER 285000 /* abt 1.25*PCMBUFFER + 7200, as recommended */
|
||||
|
||||
lame_global_flags *gfp;
|
||||
|
||||
FILE *outfile;
|
||||
FILE *infile;
|
||||
|
||||
/* MP3 samplerate, bitrate, quality. */
|
||||
int samplerate = 11025;
|
||||
int brate = 16;
|
||||
int quality = 3;
|
||||
|
||||
/* CW parameters */
|
||||
int wpm = 25;
|
||||
int freq = 600;
|
||||
int rt = 50; /* rise/fall time in samples */
|
||||
int ft = 50;
|
||||
|
||||
/* the buffers for dit, dah, raw pcm and mp3 output, will me calloc'ed to the
|
||||
* default values, and if needed realloc'ed to the needed size */
|
||||
|
||||
short int *dit_buf;
|
||||
short int *dah_buf;
|
||||
short int *inpcm;
|
||||
unsigned char *mp3buffer;
|
||||
|
||||
int inpcm_size;
|
||||
int mp3buffer_size;
|
||||
|
||||
int ditlen; /* number of samples in a 'dit' */
|
||||
|
||||
/* Chapters are split by this string */
|
||||
char chapterstr[80]="CHAPTER";
|
||||
char chapterfilename[80]="Chapter"; /* full filename: Chapter%02d.mp3 */
|
||||
|
||||
const static char *codetable[] = {
|
||||
".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..",".---",
|
||||
"-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",
|
||||
".--","-..-","-.--","--..","-----",".----","..---","...--","....-",".....",
|
||||
"-....", "--...","---..","----."};
|
||||
|
||||
/* functions */
|
||||
int init_cw (int wpm, int freq, int rt, int ft);
|
||||
void help (void);
|
||||
void makeword(char * text);
|
||||
void closefile (int letter, int cw);
|
||||
void openfile (int chapter);
|
||||
|
||||
/* main */
|
||||
|
||||
int main (int argc, char** argv) {
|
||||
int pos, i;
|
||||
char c;
|
||||
char word[1024]=""; /* will be cut when > 1024 chars long */
|
||||
int chapter = 0;
|
||||
int cw = 0, tw = 0; /* chapter words, total words */
|
||||
|
||||
infile = stdin;
|
||||
|
||||
while((i = getopt(argc, argv, "o:w:f:R:F:s:b:q:c:h")) != -1) {
|
||||
switch (i) {
|
||||
case 'w':
|
||||
if ((wpm = atoi(optarg)) < 1) {
|
||||
fprintf(stderr, "Error: Speed (-w) must be > 0!\n");
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 'f':
|
||||
freq = atoi(optarg);
|
||||
break;
|
||||
case 'R':
|
||||
rt = atoi(optarg);
|
||||
break;
|
||||
case 'F':
|
||||
ft = atoi(optarg);
|
||||
break;
|
||||
case 's':
|
||||
samplerate = atoi(optarg);
|
||||
break;
|
||||
case 'b':
|
||||
brate = atoi(optarg);
|
||||
break;
|
||||
case 'q':
|
||||
quality = atoi(optarg);
|
||||
break;
|
||||
case 'c':
|
||||
strncpy(chapterstr, optarg, 78);
|
||||
break;
|
||||
case 'o':
|
||||
strncpy(chapterfilename, optarg, 78);
|
||||
break;
|
||||
case 'h':
|
||||
default:
|
||||
help();
|
||||
} /* switch */
|
||||
} /* while */
|
||||
|
||||
if (optind < argc) { /* something left? if so, use as infile */
|
||||
if ((argv[optind][0] != '-') && (argv[optind][0] != '\0')) {
|
||||
if ((infile = fopen(argv[optind], "r")) == NULL) {
|
||||
fprintf(stderr, "Error: Cannot open file %s. Exit.\n",
|
||||
argv[optind]);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf("ebook2cw %s - (c) 2007 by Fabian Kurz, DJ1YFK\n", VERSION);
|
||||
printf("Speed: %d WpM, Freq: %dHz, Chapter: >%s<\n", wpm, freq, chapterstr);
|
||||
|
||||
|
||||
/* init lame */
|
||||
gfp = lame_init();
|
||||
lame_set_num_channels(gfp,1);
|
||||
lame_set_in_samplerate(gfp, samplerate);
|
||||
lame_set_brate(gfp, brate);
|
||||
lame_set_mode(gfp,1);
|
||||
lame_set_quality(gfp, quality);
|
||||
|
||||
if (lame_init_params(gfp) < 0) {
|
||||
fprintf(stderr, "Failed: lame_init_params(gfp) \n");
|
||||
return(1);
|
||||
}
|
||||
else {
|
||||
printf("Initialized lame; samplerate=%d, bitrate=%d, quality=%d\n",
|
||||
samplerate, brate, quality);
|
||||
}
|
||||
|
||||
/* init pcm_buf and mp3_buf */
|
||||
|
||||
if ((inpcm = calloc(PCMBUFFER, sizeof(short int))) == NULL) {
|
||||
fprintf(stderr, "Error: Can't allocate inpcm[%d]!\n", PCMBUFFER);
|
||||
exit(1);
|
||||
}
|
||||
else {
|
||||
inpcm_size = PCMBUFFER;
|
||||
}
|
||||
|
||||
if ((mp3buffer = calloc(MP3BUFFER, sizeof(unsigned char))) == NULL) {
|
||||
fprintf(stderr, "Error: Can't allocate mp3buffer[%d]!\n", MP3BUFFER);
|
||||
exit(1);
|
||||
}
|
||||
else {
|
||||
mp3buffer_size = MP3BUFFER;
|
||||
}
|
||||
|
||||
ditlen = init_cw(wpm, freq, rt, ft); /* generate raw dit, dah, silence */
|
||||
|
||||
strcat(chapterstr, " ");
|
||||
|
||||
/* read STDIN, assemble full words (anything ending in ' ') to 'word' and
|
||||
* generate CW, write to file by 'makeword'. words with > 1024 characters
|
||||
* will be split */
|
||||
|
||||
chapter = 0;
|
||||
openfile(chapter);
|
||||
|
||||
pos=0;
|
||||
while ((c = getc(infile)) != EOF) {
|
||||
|
||||
if (c == '\r') { /* DOS linebreaks */
|
||||
continue;
|
||||
}
|
||||
|
||||
word[pos++] = c;
|
||||
|
||||
if ((c == ' ') || (c == '\n') || (pos == 1024)) {
|
||||
word[pos] = '\0';
|
||||
if (strcmp(chapterstr, word) == 0) { /* new chapter */
|
||||
closefile(chapter, cw);
|
||||
cw=0;
|
||||
chapter++;
|
||||
openfile(chapter);
|
||||
}
|
||||
makeword(word);
|
||||
cw++; tw++;
|
||||
|
||||
word[0] = '\0';
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
}
|
||||
/* eof */
|
||||
|
||||
closefile(chapter, cw);
|
||||
|
||||
free(mp3buffer);
|
||||
free(inpcm);
|
||||
|
||||
/* factor 0.9 due to many 'words' which aren't actually words, like '\n' */
|
||||
printf("Total words: %d, total time: %d min\n", tw, (int) ((tw/wpm)*0.9));
|
||||
|
||||
lame_close(gfp);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* init_cw - generates a dit and a dah to dit_buf and dah_buf */
|
||||
|
||||
int init_cw (int wpm, int freq, int rt, int ft) {
|
||||
int x;
|
||||
int len;
|
||||
double val;
|
||||
|
||||
printf("Initializing CW buffers: ");
|
||||
|
||||
/* dah */
|
||||
len = (int) 3.0*6.0*samplerate/(5.0*wpm); /* in samples */
|
||||
|
||||
/* allocate memory for the buffer */
|
||||
if ((dah_buf = calloc(len, sizeof(short int))) == NULL) {
|
||||
fprintf(stderr, "Error: Can't allocate dah_buf[%d]\n", len);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (x=0; x < len; x++) {
|
||||
val = sin(2*M_PI*freq*x/samplerate);
|
||||
if (x < rt) { /* shaping with sin^2 */
|
||||
val *= pow(sin(M_PI*x/(2.0*rt)),2);
|
||||
}
|
||||
if (x > (len-ft)) {
|
||||
val *= pow((sin(2*M_PI*(x-(len-ft)+ft)/(4*ft))), 2);
|
||||
}
|
||||
|
||||
dah_buf[x] = (int) (val * 20000.0);
|
||||
}
|
||||
|
||||
printf("dah_buf[%d], ", x);
|
||||
|
||||
/* dit */
|
||||
len = (int) 6.0*samplerate/(5.0*wpm); /* in samples */
|
||||
|
||||
/* allocate memory for the buffer */
|
||||
if ((dit_buf = calloc(len, sizeof(short int))) == NULL) {
|
||||
fprintf(stderr, "Error: Can't allocate dit_buf[%d]\n", len);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (x=0; x < len; x++) {
|
||||
val = sin(2*M_PI*freq*x/samplerate);
|
||||
if (x < rt) {
|
||||
val *= pow(sin(M_PI*x/(2.0*rt)), 2);
|
||||
}
|
||||
if (x > (len-ft)) {
|
||||
val *= pow((sin(2*M_PI*(x-(len-ft)+ft)/(4*ft))), 2);
|
||||
}
|
||||
dit_buf[x] = (int) (val * 20000.0);
|
||||
}
|
||||
|
||||
printf("dit_buf[%d]\n\n", x);
|
||||
|
||||
return x; /* = length of dit/silence */
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* makeword -- converts 'text' to CW by concatenating dit_buf amd dah_bufs,
|
||||
* encodes this to MP3 and writes to open filehandle outfile */
|
||||
|
||||
void makeword(char * text) {
|
||||
const char *code; /* CW code as . and - */
|
||||
int outbytes;
|
||||
|
||||
int c;
|
||||
int i,u,w;
|
||||
int j;
|
||||
|
||||
j = 0; /* position in 'inpcm' buffer */
|
||||
|
||||
for (i = 0; i < strlen(text); i++) {
|
||||
c = toupper(text[i]);
|
||||
|
||||
if (c > 64 && c < 91) { /* trouble with isalpha() under Win32 */
|
||||
code = codetable[c-65]; /* even with locale = C ...? */
|
||||
}
|
||||
else if (c > 47 && c < 58) {
|
||||
code = codetable[c-22];
|
||||
}
|
||||
else if (c == '.') { code = ".-.-.-"; } /* messy */
|
||||
else if (c == ',') { code = "--..--"; }
|
||||
else if (c == '=') { code = "-...-"; }
|
||||
else if (c == '?') { code = "..--.."; }
|
||||
else if (c == '-') { code = "-....-"; }
|
||||
else if (c==228 || c==196 || c==-28 || c==-60) { code = ".-.-"; } /* ae */
|
||||
else if (c==252 || c==220 || c==-4 || c==-36) { code = "..--"; } /* ue */
|
||||
else if (c==246 || c==214 || c==-10 || c==-42) { code = "---."; } /* oe */
|
||||
else if (c == 223 || c == -33) { code = "... --.."; } /* sz */
|
||||
else if (c == '(') { code = "-.--."; }
|
||||
else if (c == ')') { code = "-.--.-"; }
|
||||
else if (c == '!') { code = ".-.-.-"; }
|
||||
else if (c == ';') { code = "-.-.-."; }
|
||||
else if (c == '/') { code = "-..-."; }
|
||||
else if (c == '@') { code = ".--.-."; }
|
||||
else if (c == ':') { code = "---..."; }
|
||||
else if (c == '"') { code = ".-..-."; }
|
||||
else if (c == '\'') { code = ".----."; }
|
||||
else if (c == ' ') { code = " "; }
|
||||
else if (c == '\n') {
|
||||
if (strlen(text) == 1) {
|
||||
code = " -...- "; /* new paragraph */
|
||||
}
|
||||
else {
|
||||
code = " ";
|
||||
}
|
||||
}
|
||||
else {
|
||||
code = " ";
|
||||
fprintf(stderr, "Warning: don't know CW for '%c'\n", (char) c);
|
||||
}
|
||||
|
||||
/* code contains word as ./-, now assemble pcm buffer */
|
||||
|
||||
for (w = 0; w < strlen(code) ; w++) {
|
||||
|
||||
/* make sure the inpcm buffer doesn't run full,
|
||||
* with a conservative margin. reallocate memory if neccesary */
|
||||
if (j > inpcm_size-(6*ditlen)) {
|
||||
inpcm_size += (6*ditlen);
|
||||
mp3buffer_size += (8*ditlen + 7200);
|
||||
if ((inpcm = realloc(inpcm, inpcm_size*sizeof(short int)))== NULL) {
|
||||
fprintf(stderr, "Error: Can't realloc inpcm[%d]\n", inpcm_size);
|
||||
}
|
||||
if ((mp3buffer = realloc(mp3buffer, mp3buffer_size*sizeof(char)))
|
||||
== NULL) {
|
||||
fprintf(stderr, "Error: Can't realloc mp3buffer[%d]\n",
|
||||
mp3buffer_size);
|
||||
}
|
||||
}
|
||||
|
||||
c = code[w];
|
||||
|
||||
if (c == '.') {
|
||||
for (u=0; u < ditlen; u++) { inpcm[++j] = dit_buf[u]; }
|
||||
}
|
||||
else if (c == '-') {
|
||||
for (u=0; u < (3*ditlen); u++) { inpcm[++j] = dah_buf[u]; }
|
||||
}
|
||||
else {
|
||||
for (u=0; u < ditlen; u++) { inpcm[++j] = 0; }
|
||||
}
|
||||
|
||||
for (u=0; u < ditlen; u++) { inpcm[++j] = 0; }
|
||||
|
||||
}
|
||||
|
||||
for (u=0; u < (2*ditlen); u++) { inpcm[++j] = 0; } /* inter word space */
|
||||
|
||||
}
|
||||
|
||||
/* j = total length of samples in 'inpcm' */
|
||||
|
||||
outbytes = lame_encode_buffer(gfp, inpcm, inpcm, j, mp3buffer, mp3buffer_size);
|
||||
if (outbytes < 0) {
|
||||
fprintf(stderr, "Error: lame_encode_buffer returned %d. Exit.\n", outbytes);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (fwrite(mp3buffer, sizeof(char), outbytes, outfile) != outbytes) {
|
||||
fprintf(stderr, "Error: Writing %db to file failed. Exit.\n", outbytes);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* closefile -- finishes writing the current file, flushes the encoder buffer */
|
||||
|
||||
void closefile (int letter, int cw) {
|
||||
int outbytes;
|
||||
char mp3filename[80] = "";
|
||||
|
||||
printf("words: %d, minutes: %d\n", cw, (int) ((cw/wpm)*0.9));
|
||||
|
||||
sprintf(mp3filename, "%s%02d.mp3", chapterfilename, letter);
|
||||
printf("Finishing %s\n\n", mp3filename);
|
||||
|
||||
outbytes = lame_encode_flush(gfp, mp3buffer, mp3buffer_size);
|
||||
|
||||
if (outbytes < 0) {
|
||||
fprintf(stderr, "Error: lame_encode_buffer returned %d.\n", outbytes);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (fwrite(mp3buffer, sizeof(char), outbytes, outfile) != outbytes) {
|
||||
fprintf(stderr, "Error: Writing %db to file failed. Exit.\n", outbytes);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fclose(outfile);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* openfile -- starts a new chapter by opening Chapter%d.mp3 */
|
||||
|
||||
void openfile (int chapter) {
|
||||
char mp3filename[80] = "";
|
||||
sprintf(mp3filename, "%s%02d.mp3", chapterfilename, chapter);
|
||||
printf("Starting %s\n", mp3filename);
|
||||
|
||||
if ((outfile = fopen(mp3filename, "wb")) == NULL) {
|
||||
fprintf(stderr, "Error: Failed to open %s\n", mp3filename);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void help (void) {
|
||||
printf("ebook2cw v%s - (c) 2007 by Fabian Kurz, DJ1YFK, http://fkurz.net/\n", VERSION);
|
||||
printf("\n");
|
||||
printf("ebook2cw [-w wpm] [-f freq] [-R risetime] [-F falltime]\n");
|
||||
printf(" [-s samplerate] [-b mp3bitrate] [-q mp3quality]\n");
|
||||
printf(" [-c chapter-separator] [-o outfile-name] [infile]\n\n");
|
||||
printf("defaults: 25 WpM, 600Hz, RT=FT=50, s=11025Hz, b=16kbps,\n");
|
||||
printf(" c=\"CHAPTER\", o=\"Chapter\" infile = stdin\n");
|
||||
printf("\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
|
|
@ -0,0 +1,280 @@
|
|||
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
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
0.5.0 / 2007-12-19 Fabian Kurz <mail@fkurz.net>
|
||||
* Added support for writing ID3 tags.
|
||||
* Added -Q command line switch: QRQ by 1 WpM every n minutes.
|
||||
|
||||
0.4.0 / 2007-12-17 Fabian Kurz <mail@fkurz.net>
|
||||
* Implemented dynamic memory allocation.
|
||||
|
||||
0.3.0 / 2007-11-28 Fabian Kurz <mail@fkurz.net>
|
||||
* Added forgotten characters: @ and /.
|
||||
|
||||
0.2.0 / 2007-11-27 Fabian Kurz <mail@fkurz.net>
|
||||
|
||||
* Fixed handling of umlauts (öäüß)
|
||||
* The chapter separator is now case sensitive.
|
||||
|
||||
0.1.0 / 2007-11-22 Fabian Kurz <mail@fkurz.net>
|
||||
|
||||
* Initial release of ebook2cw.
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
# ebook2cw Makefile -- Fabian Kurz, DJ1YFK -- http://fkurz.net/ham/ebook2cw.html
|
||||
|
||||
VERSION=0.5.0
|
||||
DESTDIR ?= /usr
|
||||
|
||||
all: ebook2cw
|
||||
|
||||
ebook2cw: ebook2cw.c
|
||||
gcc ebook2cw.c -pedantic -Wall -lm -lmp3lame -D VERSION=\"$(VERSION)\" -o ebook2cw
|
||||
|
||||
static:
|
||||
gcc -static ebook2cw.c -lmp3lame -lm -D VERSION=\"$(VERSION)\" -o ebook2cw
|
||||
|
||||
install:
|
||||
install -d -v $(DESTDIR)/share/man/man1/
|
||||
install -d -v $(DESTDIR)/bin/
|
||||
install -s -m 0755 ebook2cw $(DESTDIR)/bin/
|
||||
install -m 0644 ebook2cw.1 $(DESTDIR)/share/man/man1/
|
||||
|
||||
uninstall:
|
||||
rm -f $(DESTDIR)/bin/ebook2cw
|
||||
rm -f $(DESTDIR)/share/man/man1/ebook2cw.1
|
||||
|
||||
clean:
|
||||
rm -f ebook2cw *~ *.mp3
|
||||
|
||||
dist:
|
||||
sed 's/v[0-9].[0-9].[0-9]/v$(VERSION)/g' README > README2
|
||||
rm -f README
|
||||
mv README2 README
|
||||
rm -f releases/ebook2cw-$(VERSION).tar.gz
|
||||
rm -rf releases/ebook2cw-$(VERSION)
|
||||
mkdir ebook2cw-$(VERSION)
|
||||
cp ebook2cw.c ChangeLog ebook2cw.1 \
|
||||
COPYING Makefile ebook2cw-$(VERSION)
|
||||
tar -zcf ebook2cw-$(VERSION).tar.gz ebook2cw-$(VERSION)
|
||||
mv ebook2cw-$(VERSION) releases/
|
||||
mv ebook2cw-$(VERSION).tar.gz releases/
|
||||
md5sum releases/*.gz > releases/md5sums.txt
|
||||
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
.TH ebook2cw 1 "JUNE 2007" Linux "User Manuals"
|
||||
.SH NAME
|
||||
ebook2cw \- convert ebooks to morse mp3s
|
||||
.SH SYNOPSIS
|
||||
.B ebook2cw
|
||||
[OPTIONS]
|
||||
.SH DESCRIPTION
|
||||
.B ebook2cw
|
||||
ebook2cw is a command line program which converts a plain text ebook to morse
|
||||
code MP3 files. It works on several platforms, including Windows and Linux.
|
||||
|
||||
A number of CW and MP3 parameters can be changed from their default values, by
|
||||
command line switches. These are (default values in brackets):
|
||||
|
||||
.B -w wpm
|
||||
- CW speed in words per minute [25]
|
||||
|
||||
.B -f freq
|
||||
- audio frequency in Hz [600]
|
||||
|
||||
.B -Q minutes
|
||||
- Increase CW speed (QRQ) by 1 WpM in intervals of `minutes'. Speed will be
|
||||
reset to the initial value at the start of each chapter. [0]
|
||||
|
||||
.B -R risetime
|
||||
- risetime, in samples [50]
|
||||
|
||||
.B -F falltime
|
||||
- falltime, samples [50]
|
||||
|
||||
.B -s samplerate
|
||||
- samplerate for the MP3 file [11025]
|
||||
|
||||
.B -b bitrate
|
||||
- MP3 bitrate, kbps [16]
|
||||
|
||||
.B -q quality
|
||||
- MP3 quality, 1 (best) to 9 (worst) [3]
|
||||
|
||||
.B -c chapter separator
|
||||
- Split chapters at this string [CHAPTER]
|
||||
|
||||
.B -o outfile-name
|
||||
- Output filename (chapter number and .mp3 will be appended) [Chapter]
|
||||
|
||||
.B -a author
|
||||
- Author for the ID3 tag. Use quotes for strings with spaces (e.g. "JW Goethe")
|
||||
|
||||
.B -t title
|
||||
- Title for the ID3 tag. Use quotes for strings with spaces (e.g. "Faust II")
|
||||
|
||||
.B -k comment
|
||||
- Comment for the ID3 tag. Use quotes for strings with spaces.
|
||||
|
||||
.B -y year
|
||||
- Year for the ID3 tag.
|
||||
|
||||
.SH AUTHOR
|
||||
Fabian Kurz, DJ1YFK <mail@fkurz.net>
|
||||
|
||||
http://fkurz.net/ham/ebook2cw.html
|
||||
.SH "SEE ALSO"
|
||||
.BR morse (1)
|
||||
|
|
@ -0,0 +1,530 @@
|
|||
/*
|
||||
ebook2cw - converts an ebook to morse mp3s
|
||||
|
||||
Copyright (C) 2007 Fabian Kurz, DJ1YFK
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 2 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
|
||||
Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
source code looks properly indented with tw=4
|
||||
|
||||
*/
|
||||
|
||||
#include "lame/lame.h"
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#ifndef VERSION
|
||||
#define VERSION "0.0.0"
|
||||
#endif
|
||||
|
||||
#define PCMBUFFER 220500 /* 20 seconds at 11kHz, for one word. plenty. */
|
||||
#define MP3BUFFER 285000 /* abt 1.25*PCMBUFFER + 7200, as recommended */
|
||||
|
||||
lame_global_flags *gfp;
|
||||
|
||||
FILE *outfile;
|
||||
FILE *infile;
|
||||
|
||||
/* MP3 samplerate, bitrate, quality. */
|
||||
int samplerate = 11025;
|
||||
int brate = 16;
|
||||
int quality = 3;
|
||||
|
||||
/* CW parameters */
|
||||
int wpm = 25;
|
||||
int freq = 600;
|
||||
int rt = 50; /* rise/fall time in samples */
|
||||
int ft = 50;
|
||||
int qrq = 0; /* rise speed by 1 WpM every qrq minutes */
|
||||
|
||||
/* the buffers for dit, dah, raw pcm and mp3 output, will me calloc'ed to the
|
||||
* default values, and if needed realloc'ed to the needed size */
|
||||
|
||||
short int *dit_buf;
|
||||
short int *dah_buf;
|
||||
short int *inpcm;
|
||||
unsigned char *mp3buffer;
|
||||
|
||||
int inpcm_size;
|
||||
int mp3buffer_size;
|
||||
|
||||
int ditlen=0; /* number of samples in a 'dit' */
|
||||
|
||||
/* Chapters are split by this string */
|
||||
char chapterstr[80]="CHAPTER";
|
||||
char chapterfilename[80]="Chapter"; /* full filename: Chapter%02d.mp3 */
|
||||
|
||||
/* ID3-tag data: author and title */
|
||||
char id3_author[80]="CW-Book";
|
||||
char id3_title[80]="";
|
||||
char id3_comment[80]="";
|
||||
char id3_year[5]="";
|
||||
|
||||
const static char *codetable[] = {
|
||||
".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..",".---",
|
||||
"-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",
|
||||
".--","-..-","-.--","--..","-----",".----","..---","...--","....-",".....",
|
||||
"-....", "--...","---..","----."};
|
||||
|
||||
/* functions */
|
||||
int init_cw (int wpm, int freq, int rt, int ft);
|
||||
void help (void);
|
||||
void makeword(char * text);
|
||||
void closefile (int letter, int cw);
|
||||
void openfile (int chapter);
|
||||
|
||||
/* main */
|
||||
|
||||
int main (int argc, char** argv) {
|
||||
int pos, i, original_wpm;
|
||||
char c;
|
||||
char word[1024]=""; /* will be cut when > 1024 chars long */
|
||||
int chapter = 0;
|
||||
int cw = 0, tw = 0, qw = 0; /* chapter words, total words, qrq words */
|
||||
|
||||
infile = stdin;
|
||||
|
||||
while((i = getopt(argc, argv, "o:w:f:R:F:s:b:q:c:a:t:k:y:Q:h")) != -1) {
|
||||
switch (i) {
|
||||
case 'w':
|
||||
if ((wpm = atoi(optarg)) < 1) {
|
||||
fprintf(stderr, "Error: Speed (-w) must be > 0!\n");
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 'f':
|
||||
freq = atoi(optarg);
|
||||
break;
|
||||
case 'R':
|
||||
rt = atoi(optarg);
|
||||
break;
|
||||
case 'F':
|
||||
ft = atoi(optarg);
|
||||
break;
|
||||
case 's':
|
||||
samplerate = atoi(optarg);
|
||||
break;
|
||||
case 'b':
|
||||
brate = atoi(optarg);
|
||||
break;
|
||||
case 'q':
|
||||
quality = atoi(optarg);
|
||||
break;
|
||||
case 'c':
|
||||
strncpy(chapterstr, optarg, 78);
|
||||
break;
|
||||
case 'o':
|
||||
strncpy(chapterfilename, optarg, 78);
|
||||
break;
|
||||
case 'a':
|
||||
strncpy(id3_author, optarg, 78);
|
||||
break;
|
||||
case 't':
|
||||
strncpy(id3_title, optarg, 75);
|
||||
break;
|
||||
case 'k':
|
||||
strncpy(id3_comment, optarg, 78);
|
||||
break;
|
||||
case 'y':
|
||||
strncpy(id3_year, optarg, 4);
|
||||
break;
|
||||
case 'Q':
|
||||
if ((qrq = atoi(optarg)) < 1) {
|
||||
fprintf(stderr, "Error: QRQ time (-Q) must be > 0!\n");
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 'h':
|
||||
default:
|
||||
help();
|
||||
} /* switch */
|
||||
} /* while */
|
||||
|
||||
if (optind < argc) { /* something left? if so, use as infile */
|
||||
if ((argv[optind][0] != '-') && (argv[optind][0] != '\0')) {
|
||||
if ((infile = fopen(argv[optind], "r")) == NULL) {
|
||||
fprintf(stderr, "Error: Cannot open file %s. Exit.\n",
|
||||
argv[optind]);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf("ebook2cw %s - (c) 2007 by Fabian Kurz, DJ1YFK\n", VERSION);
|
||||
printf("Speed: %d WpM, Freq: %dHz, Chapter: >%s<\n", wpm, freq, chapterstr);
|
||||
|
||||
|
||||
/* init lame */
|
||||
gfp = lame_init();
|
||||
lame_set_num_channels(gfp,1);
|
||||
lame_set_in_samplerate(gfp, samplerate);
|
||||
lame_set_brate(gfp, brate);
|
||||
lame_set_mode(gfp,1);
|
||||
lame_set_quality(gfp, quality);
|
||||
|
||||
if (lame_init_params(gfp) < 0) {
|
||||
fprintf(stderr, "Failed: lame_init_params(gfp) \n");
|
||||
return(1);
|
||||
}
|
||||
else {
|
||||
printf("Initialized lame; samplerate=%d, bitrate=%d, quality=%d\n",
|
||||
samplerate, brate, quality);
|
||||
}
|
||||
|
||||
|
||||
/* init pcm_buf and mp3_buf */
|
||||
|
||||
if ((inpcm = calloc(PCMBUFFER, sizeof(short int))) == NULL) {
|
||||
fprintf(stderr, "Error: Can't allocate inpcm[%d]!\n", PCMBUFFER);
|
||||
exit(1);
|
||||
}
|
||||
else {
|
||||
inpcm_size = PCMBUFFER;
|
||||
}
|
||||
|
||||
if ((mp3buffer = calloc(MP3BUFFER, sizeof(unsigned char))) == NULL) {
|
||||
fprintf(stderr, "Error: Can't allocate mp3buffer[%d]!\n", MP3BUFFER);
|
||||
exit(1);
|
||||
}
|
||||
else {
|
||||
mp3buffer_size = MP3BUFFER;
|
||||
}
|
||||
|
||||
ditlen = init_cw(wpm, freq, rt, ft); /* generate raw dit, dah, silence */
|
||||
|
||||
strcat(chapterstr, " ");
|
||||
|
||||
/* read STDIN, assemble full words (anything ending in ' ') to 'word' and
|
||||
* generate CW, write to file by 'makeword'. words with > 1024 characters
|
||||
* will be split */
|
||||
|
||||
original_wpm = wpm; /* may be changed by QRQing */
|
||||
chapter = 0;
|
||||
openfile(chapter);
|
||||
|
||||
pos=0;
|
||||
while ((c = getc(infile)) != EOF) {
|
||||
|
||||
if (c == '\r') { /* DOS linebreaks */
|
||||
continue;
|
||||
}
|
||||
|
||||
word[pos++] = c;
|
||||
|
||||
if ((c == ' ') || (c == '\n') || (pos == 1024)) {
|
||||
word[pos] = '\0';
|
||||
if (strcmp(chapterstr, word) == 0) { /* new chapter */
|
||||
closefile(chapter, cw);
|
||||
cw=0;
|
||||
chapter++;
|
||||
|
||||
if (qrq) {
|
||||
wpm = original_wpm; /* restore CW */
|
||||
ditlen = init_cw(wpm, freq, rt, ft);
|
||||
}
|
||||
|
||||
openfile(chapter);
|
||||
}
|
||||
makeword(word);
|
||||
cw++; tw++; qw++;
|
||||
|
||||
word[0] = '\0';
|
||||
pos = 0;
|
||||
|
||||
/* every 'qrq' minutes (qrq*wpm words), speed up 1 WpM */
|
||||
if (qw == (qrq*wpm)) {
|
||||
wpm += 1;
|
||||
ditlen = init_cw(wpm, freq, rt, ft);
|
||||
qw = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
/* eof */
|
||||
|
||||
closefile(chapter, cw);
|
||||
|
||||
free(mp3buffer);
|
||||
free(inpcm);
|
||||
|
||||
/* factor 0.9 due to many 'words' which aren't actually words, like '\n' */
|
||||
printf("Total words: %d, total time: %d min\n", tw, (int) ((tw/wpm)*0.9));
|
||||
|
||||
lame_close(gfp);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* init_cw - generates a dit and a dah to dit_buf and dah_buf */
|
||||
|
||||
int init_cw (int wpm, int freq, int rt, int ft) {
|
||||
int x;
|
||||
int len;
|
||||
double val;
|
||||
|
||||
printf("Initializing CW buffers at %d WpM: ", wpm);
|
||||
|
||||
/* dah */
|
||||
len = (int) 3.0*6.0*samplerate/(5.0*wpm); /* in samples */
|
||||
|
||||
/* ditlen not set == init_cw has not been called yet */
|
||||
if (!ditlen) {
|
||||
/* allocate memory for the buffer */
|
||||
if ((dah_buf = calloc(len, sizeof(short int))) == NULL) {
|
||||
fprintf(stderr, "Error: Can't allocate dah_buf[%d]\n", len);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
for (x=0; x < len; x++) {
|
||||
val = sin(2*M_PI*freq*x/samplerate);
|
||||
if (x < rt) { /* shaping with sin^2 */
|
||||
val *= pow(sin(M_PI*x/(2.0*rt)),2);
|
||||
}
|
||||
if (x > (len-ft)) {
|
||||
val *= pow((sin(2*M_PI*(x-(len-ft)+ft)/(4*ft))), 2);
|
||||
}
|
||||
|
||||
dah_buf[x] = (int) (val * 20000.0);
|
||||
}
|
||||
|
||||
printf("dah_buf[%d], ", x);
|
||||
|
||||
/* dit */
|
||||
len = (int) 6.0*samplerate/(5.0*wpm); /* in samples */
|
||||
|
||||
/* ditlen not set == init_cw has not been called yet */
|
||||
if (!ditlen) {
|
||||
/* allocate memory for the buffer */
|
||||
if ((dit_buf = calloc(len, sizeof(short int))) == NULL) {
|
||||
fprintf(stderr, "Error: Can't allocate dit_buf[%d]\n", len);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
for (x=0; x < len; x++) {
|
||||
val = sin(2*M_PI*freq*x/samplerate);
|
||||
if (x < rt) {
|
||||
val *= pow(sin(M_PI*x/(2.0*rt)), 2);
|
||||
}
|
||||
if (x > (len-ft)) {
|
||||
val *= pow((sin(2*M_PI*(x-(len-ft)+ft)/(4*ft))), 2);
|
||||
}
|
||||
dit_buf[x] = (int) (val * 20000.0);
|
||||
}
|
||||
|
||||
printf("dit_buf[%d]\n\n", x);
|
||||
|
||||
return x; /* = length of dit/silence */
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* makeword -- converts 'text' to CW by concatenating dit_buf amd dah_bufs,
|
||||
* encodes this to MP3 and writes to open filehandle outfile */
|
||||
|
||||
void makeword(char * text) {
|
||||
const char *code; /* CW code as . and - */
|
||||
int outbytes;
|
||||
|
||||
int c;
|
||||
int i,u,w;
|
||||
int j;
|
||||
|
||||
j = 0; /* position in 'inpcm' buffer */
|
||||
|
||||
for (i = 0; i < strlen(text); i++) {
|
||||
c = toupper(text[i]);
|
||||
|
||||
if (c > 64 && c < 91) { /* trouble with isalpha() under Win32 */
|
||||
code = codetable[c-65]; /* even with locale = C ...? */
|
||||
}
|
||||
else if (c > 47 && c < 58) {
|
||||
code = codetable[c-22];
|
||||
}
|
||||
else if (c == '.') { code = ".-.-.-"; } /* messy */
|
||||
else if (c == ',') { code = "--..--"; }
|
||||
else if (c == '=') { code = "-...-"; }
|
||||
else if (c == '?') { code = "..--.."; }
|
||||
else if (c == '-') { code = "-....-"; }
|
||||
else if (c==228 || c==196 || c==-28 || c==-60) { code = ".-.-"; } /* ae */
|
||||
else if (c==252 || c==220 || c==-4 || c==-36) { code = "..--"; } /* ue */
|
||||
else if (c==246 || c==214 || c==-10 || c==-42) { code = "---."; } /* oe */
|
||||
else if (c == 223 || c == -33) { code = "... --.."; } /* sz */
|
||||
else if (c == '(') { code = "-.--."; }
|
||||
else if (c == ')') { code = "-.--.-"; }
|
||||
else if (c == '!') { code = ".-.-.-"; }
|
||||
else if (c == ';') { code = "-.-.-."; }
|
||||
else if (c == '/') { code = "-..-."; }
|
||||
else if (c == '@') { code = ".--.-."; }
|
||||
else if (c == ':') { code = "---..."; }
|
||||
else if (c == '"') { code = ".-..-."; }
|
||||
else if (c == '\'') { code = ".----."; }
|
||||
else if (c == ' ') { code = " "; }
|
||||
else if (c == '\n') {
|
||||
if (strlen(text) == 1) {
|
||||
code = " -...- "; /* new paragraph */
|
||||
}
|
||||
else {
|
||||
code = " ";
|
||||
}
|
||||
}
|
||||
else {
|
||||
code = " ";
|
||||
fprintf(stderr, "Warning: don't know CW for '%c'\n", (char) c);
|
||||
}
|
||||
|
||||
/* code contains word as ./-, now assemble pcm buffer */
|
||||
|
||||
for (w = 0; w < strlen(code) ; w++) {
|
||||
|
||||
/* make sure the inpcm buffer doesn't run full,
|
||||
* with a conservative margin. reallocate memory if neccesary */
|
||||
if (j > inpcm_size-(6*ditlen)) {
|
||||
inpcm_size += (6*ditlen);
|
||||
mp3buffer_size += (8*ditlen + 7200);
|
||||
if ((inpcm = realloc(inpcm, inpcm_size*sizeof(short int)))== NULL) {
|
||||
fprintf(stderr, "Error: Can't realloc inpcm[%d]\n", inpcm_size);
|
||||
}
|
||||
if ((mp3buffer = realloc(mp3buffer, mp3buffer_size*sizeof(char)))
|
||||
== NULL) {
|
||||
fprintf(stderr, "Error: Can't realloc mp3buffer[%d]\n",
|
||||
mp3buffer_size);
|
||||
}
|
||||
}
|
||||
|
||||
c = code[w];
|
||||
|
||||
if (c == '.') {
|
||||
for (u=0; u < ditlen; u++) { inpcm[++j] = dit_buf[u]; }
|
||||
}
|
||||
else if (c == '-') {
|
||||
for (u=0; u < (3*ditlen); u++) { inpcm[++j] = dah_buf[u]; }
|
||||
}
|
||||
else {
|
||||
for (u=0; u < ditlen; u++) { inpcm[++j] = 0; }
|
||||
}
|
||||
|
||||
for (u=0; u < ditlen; u++) { inpcm[++j] = 0; }
|
||||
|
||||
}
|
||||
|
||||
for (u=0; u < (2*ditlen); u++) { inpcm[++j] = 0; } /* inter word space */
|
||||
|
||||
}
|
||||
|
||||
/* j = total length of samples in 'inpcm' */
|
||||
|
||||
outbytes = lame_encode_buffer(gfp, inpcm, inpcm, j, mp3buffer, mp3buffer_size);
|
||||
if (outbytes < 0) {
|
||||
fprintf(stderr, "Error: lame_encode_buffer returned %d. Exit.\n", outbytes);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (fwrite(mp3buffer, sizeof(char), outbytes, outfile) != outbytes) {
|
||||
fprintf(stderr, "Error: Writing %db to file failed. Exit.\n", outbytes);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* closefile -- finishes writing the current file, flushes the encoder buffer */
|
||||
|
||||
void closefile (int letter, int cw) {
|
||||
int outbytes;
|
||||
char mp3filename[80] = "";
|
||||
|
||||
printf("words: %d, minutes: %d\n", cw, (int) ((cw/wpm)*0.9));
|
||||
|
||||
sprintf(mp3filename, "%s%02d.mp3", chapterfilename, letter);
|
||||
printf("Finishing %s\n\n", mp3filename);
|
||||
|
||||
outbytes = lame_encode_flush(gfp, mp3buffer, mp3buffer_size);
|
||||
|
||||
if (outbytes < 0) {
|
||||
fprintf(stderr, "Error: lame_encode_buffer returned %d.\n", outbytes);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (fwrite(mp3buffer, sizeof(char), outbytes, outfile) != outbytes) {
|
||||
fprintf(stderr, "Error: Writing %db to file failed. Exit.\n", outbytes);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fclose(outfile);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* openfile -- starts a new chapter by opening Chapter%d.mp3 */
|
||||
|
||||
void openfile (int chapter) {
|
||||
char mp3filename[80] = "";
|
||||
char tmp[80] = "";
|
||||
|
||||
sprintf(mp3filename, "%s%02d.mp3", chapterfilename, chapter);
|
||||
printf("Starting %s\n", mp3filename);
|
||||
|
||||
if ((outfile = fopen(mp3filename, "wb")) == NULL) {
|
||||
fprintf(stderr, "Error: Failed to open %s\n", mp3filename);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
sprintf(tmp, " - %d", chapter); /* generate title */
|
||||
strcat(id3_title, tmp);
|
||||
|
||||
id3tag_init(gfp);
|
||||
id3tag_set_artist(gfp, id3_author);
|
||||
id3tag_set_year(gfp, id3_year);
|
||||
id3tag_set_title(gfp, id3_title);
|
||||
id3tag_set_comment(gfp, id3_comment);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void help (void) {
|
||||
printf("ebook2cw v%s - (c) 2007 by Fabian Kurz, DJ1YFK, http://fkurz.net/\n", VERSION);
|
||||
printf("\n");
|
||||
printf("ebook2cw [-w wpm] [-f freq] [-R risetime] [-F falltime]\n");
|
||||
printf(" [-s samplerate] [-b mp3bitrate] [-q mp3quality]\n");
|
||||
printf(" [-c chapter-separator] [-o outfile-name] [-Q minutes]\n");
|
||||
printf(" [-a author] [-t title] [-k comment] [-y year]\n");
|
||||
printf(" [infile]\n\n");
|
||||
printf("defaults: 25 WpM, 600Hz, RT=FT=50, s=11025Hz, b=16kbps,\n");
|
||||
printf(" c=\"CHAPTER\", o=\"Chapter\" infile = stdin\n");
|
||||
printf("\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
|
|
@ -0,0 +1,280 @@
|
|||
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
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
0.5.1 / 2008-01-08 Fabian Kurz <mail@fkurz.net>
|
||||
* Fixed ID3 title (chapter number) generation.
|
||||
|
||||
0.5.0 / 2007-12-19 Fabian Kurz <mail@fkurz.net>
|
||||
* Added support for writing ID3 tags.
|
||||
* Added support for writing ID3 tags.
|
||||
* Added -Q command line switch: QRQ by 1 WpM every n minutes.
|
||||
|
||||
0.4.0 / 2007-12-17 Fabian Kurz <mail@fkurz.net>
|
||||
* Implemented dynamic memory allocation.
|
||||
|
||||
0.3.0 / 2007-11-28 Fabian Kurz <mail@fkurz.net>
|
||||
* Added forgotten characters: @ and /.
|
||||
|
||||
0.2.0 / 2007-11-27 Fabian Kurz <mail@fkurz.net>
|
||||
|
||||
* Fixed handling of umlauts (öäüß)
|
||||
* The chapter separator is now case sensitive.
|
||||
|
||||
0.1.0 / 2007-11-22 Fabian Kurz <mail@fkurz.net>
|
||||
|
||||
* Initial release of ebook2cw.
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
# ebook2cw Makefile -- Fabian Kurz, DJ1YFK -- http://fkurz.net/ham/ebook2cw.html
|
||||
|
||||
VERSION=0.5.1
|
||||
DESTDIR ?= /usr
|
||||
|
||||
all: ebook2cw
|
||||
|
||||
ebook2cw: ebook2cw.c
|
||||
gcc ebook2cw.c -pedantic -Wall -lm -lmp3lame -D VERSION=\"$(VERSION)\" -o ebook2cw
|
||||
|
||||
static:
|
||||
gcc -static ebook2cw.c -lmp3lame -lm -D VERSION=\"$(VERSION)\" -o ebook2cw
|
||||
|
||||
install:
|
||||
install -d -v $(DESTDIR)/share/man/man1/
|
||||
install -d -v $(DESTDIR)/bin/
|
||||
install -s -m 0755 ebook2cw $(DESTDIR)/bin/
|
||||
install -m 0644 ebook2cw.1 $(DESTDIR)/share/man/man1/
|
||||
|
||||
uninstall:
|
||||
rm -f $(DESTDIR)/bin/ebook2cw
|
||||
rm -f $(DESTDIR)/share/man/man1/ebook2cw.1
|
||||
|
||||
clean:
|
||||
rm -f ebook2cw *~ *.mp3
|
||||
|
||||
dist:
|
||||
sed 's/v[0-9].[0-9].[0-9]/v$(VERSION)/g' README > README2
|
||||
rm -f README
|
||||
mv README2 README
|
||||
rm -f releases/ebook2cw-$(VERSION).tar.gz
|
||||
rm -rf releases/ebook2cw-$(VERSION)
|
||||
mkdir ebook2cw-$(VERSION)
|
||||
cp ebook2cw.c ChangeLog ebook2cw.1 \
|
||||
COPYING Makefile ebook2cw-$(VERSION)
|
||||
tar -zcf ebook2cw-$(VERSION).tar.gz ebook2cw-$(VERSION)
|
||||
mv ebook2cw-$(VERSION) releases/
|
||||
mv ebook2cw-$(VERSION).tar.gz releases/
|
||||
md5sum releases/*.gz > releases/md5sums.txt
|
||||
chmod a+r releases/*
|
||||
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
.TH ebook2cw 1 "JUNE 2007" Linux "User Manuals"
|
||||
.SH NAME
|
||||
ebook2cw \- convert ebooks to morse mp3s
|
||||
.SH SYNOPSIS
|
||||
.B ebook2cw
|
||||
[OPTIONS]
|
||||
.SH DESCRIPTION
|
||||
.B ebook2cw
|
||||
ebook2cw is a command line program which converts a plain text ebook to morse
|
||||
code MP3 files. It works on several platforms, including Windows and Linux.
|
||||
|
||||
A number of CW and MP3 parameters can be changed from their default values, by
|
||||
command line switches. These are (default values in brackets):
|
||||
|
||||
.B -w wpm
|
||||
- CW speed in words per minute [25]
|
||||
|
||||
.B -f freq
|
||||
- audio frequency in Hz [600]
|
||||
|
||||
.B -Q minutes
|
||||
- Increase CW speed (QRQ) by 1 WpM in intervals of `minutes'. Speed will be
|
||||
reset to the initial value at the start of each chapter. [0]
|
||||
|
||||
.B -R risetime
|
||||
- risetime, in samples [50]
|
||||
|
||||
.B -F falltime
|
||||
- falltime, samples [50]
|
||||
|
||||
.B -s samplerate
|
||||
- samplerate for the MP3 file [11025]
|
||||
|
||||
.B -b bitrate
|
||||
- MP3 bitrate, kbps [16]
|
||||
|
||||
.B -q quality
|
||||
- MP3 quality, 1 (best) to 9 (worst) [3]
|
||||
|
||||
.B -c chapter separator
|
||||
- Split chapters at this string [CHAPTER]
|
||||
|
||||
.B -o outfile-name
|
||||
- Output filename (chapter number and .mp3 will be appended) [Chapter]
|
||||
|
||||
.B -a author
|
||||
- Author for the ID3 tag. Use quotes for strings with spaces (e.g. "JW Goethe")
|
||||
|
||||
.B -t title
|
||||
- Title for the ID3 tag. Use quotes for strings with spaces (e.g. "Faust II")
|
||||
|
||||
.B -k comment
|
||||
- Comment for the ID3 tag. Use quotes for strings with spaces.
|
||||
|
||||
.B -y year
|
||||
- Year for the ID3 tag.
|
||||
|
||||
.SH AUTHOR
|
||||
Fabian Kurz, DJ1YFK <mail@fkurz.net>
|
||||
|
||||
http://fkurz.net/ham/ebook2cw.html
|
||||
.SH "SEE ALSO"
|
||||
.BR morse (1)
|
||||
|
|
@ -0,0 +1,529 @@
|
|||
/*
|
||||
ebook2cw - converts an ebook to morse mp3s
|
||||
|
||||
Copyright (C) 2007 Fabian Kurz, DJ1YFK
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 2 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
|
||||
Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
source code looks properly indented with tw=4
|
||||
|
||||
*/
|
||||
|
||||
#include "lame/lame.h"
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#ifndef VERSION
|
||||
#define VERSION "0.0.0"
|
||||
#endif
|
||||
|
||||
#define PCMBUFFER 220500 /* 20 seconds at 11kHz, for one word. plenty. */
|
||||
#define MP3BUFFER 285000 /* abt 1.25*PCMBUFFER + 7200, as recommended */
|
||||
|
||||
lame_global_flags *gfp;
|
||||
|
||||
FILE *outfile;
|
||||
FILE *infile;
|
||||
|
||||
/* MP3 samplerate, bitrate, quality. */
|
||||
int samplerate = 11025;
|
||||
int brate = 16;
|
||||
int quality = 3;
|
||||
|
||||
/* CW parameters */
|
||||
int wpm = 25;
|
||||
int freq = 600;
|
||||
int rt = 50; /* rise/fall time in samples */
|
||||
int ft = 50;
|
||||
int qrq = 0; /* rise speed by 1 WpM every qrq minutes */
|
||||
|
||||
/* the buffers for dit, dah, raw pcm and mp3 output, will me calloc'ed to the
|
||||
* default values, and if needed realloc'ed to the needed size */
|
||||
|
||||
short int *dit_buf;
|
||||
short int *dah_buf;
|
||||
short int *inpcm;
|
||||
unsigned char *mp3buffer;
|
||||
|
||||
int inpcm_size;
|
||||
int mp3buffer_size;
|
||||
|
||||
int ditlen=0; /* number of samples in a 'dit' */
|
||||
|
||||
/* Chapters are split by this string */
|
||||
char chapterstr[80]="CHAPTER";
|
||||
char chapterfilename[80]="Chapter"; /* full filename: Chapter%02d.mp3 */
|
||||
|
||||
/* ID3-tag data: author and title */
|
||||
char id3_author[80]="CW-Book";
|
||||
char id3_title[80]="";
|
||||
char id3_comment[80]="";
|
||||
char id3_year[5]="";
|
||||
|
||||
const static char *codetable[] = {
|
||||
".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..",".---",
|
||||
"-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",
|
||||
".--","-..-","-.--","--..","-----",".----","..---","...--","....-",".....",
|
||||
"-....", "--...","---..","----."};
|
||||
|
||||
/* functions */
|
||||
int init_cw (int wpm, int freq, int rt, int ft);
|
||||
void help (void);
|
||||
void makeword(char * text);
|
||||
void closefile (int letter, int cw);
|
||||
void openfile (int chapter);
|
||||
|
||||
/* main */
|
||||
|
||||
int main (int argc, char** argv) {
|
||||
int pos, i, original_wpm;
|
||||
char c;
|
||||
char word[1024]=""; /* will be cut when > 1024 chars long */
|
||||
int chapter = 0;
|
||||
int cw = 0, tw = 0, qw = 0; /* chapter words, total words, qrq words */
|
||||
|
||||
infile = stdin;
|
||||
|
||||
while((i = getopt(argc, argv, "o:w:f:R:F:s:b:q:c:a:t:k:y:Q:h")) != -1) {
|
||||
switch (i) {
|
||||
case 'w':
|
||||
if ((wpm = atoi(optarg)) < 1) {
|
||||
fprintf(stderr, "Error: Speed (-w) must be > 0!\n");
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 'f':
|
||||
freq = atoi(optarg);
|
||||
break;
|
||||
case 'R':
|
||||
rt = atoi(optarg);
|
||||
break;
|
||||
case 'F':
|
||||
ft = atoi(optarg);
|
||||
break;
|
||||
case 's':
|
||||
samplerate = atoi(optarg);
|
||||
break;
|
||||
case 'b':
|
||||
brate = atoi(optarg);
|
||||
break;
|
||||
case 'q':
|
||||
quality = atoi(optarg);
|
||||
break;
|
||||
case 'c':
|
||||
strncpy(chapterstr, optarg, 78);
|
||||
break;
|
||||
case 'o':
|
||||
strncpy(chapterfilename, optarg, 78);
|
||||
break;
|
||||
case 'a':
|
||||
strncpy(id3_author, optarg, 78);
|
||||
break;
|
||||
case 't':
|
||||
strncpy(id3_title, optarg, 75);
|
||||
break;
|
||||
case 'k':
|
||||
strncpy(id3_comment, optarg, 78);
|
||||
break;
|
||||
case 'y':
|
||||
strncpy(id3_year, optarg, 4);
|
||||
break;
|
||||
case 'Q':
|
||||
if ((qrq = atoi(optarg)) < 1) {
|
||||
fprintf(stderr, "Error: QRQ time (-Q) must be > 0!\n");
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 'h':
|
||||
default:
|
||||
help();
|
||||
} /* switch */
|
||||
} /* while */
|
||||
|
||||
if (optind < argc) { /* something left? if so, use as infile */
|
||||
if ((argv[optind][0] != '-') && (argv[optind][0] != '\0')) {
|
||||
if ((infile = fopen(argv[optind], "r")) == NULL) {
|
||||
fprintf(stderr, "Error: Cannot open file %s. Exit.\n",
|
||||
argv[optind]);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf("ebook2cw %s - (c) 2007 by Fabian Kurz, DJ1YFK\n", VERSION);
|
||||
printf("Speed: %d WpM, Freq: %dHz, Chapter: >%s<\n", wpm, freq, chapterstr);
|
||||
|
||||
|
||||
/* init lame */
|
||||
gfp = lame_init();
|
||||
lame_set_num_channels(gfp,1);
|
||||
lame_set_in_samplerate(gfp, samplerate);
|
||||
lame_set_brate(gfp, brate);
|
||||
lame_set_mode(gfp,1);
|
||||
lame_set_quality(gfp, quality);
|
||||
|
||||
if (lame_init_params(gfp) < 0) {
|
||||
fprintf(stderr, "Failed: lame_init_params(gfp) \n");
|
||||
return(1);
|
||||
}
|
||||
else {
|
||||
printf("Initialized lame; samplerate=%d, bitrate=%d, quality=%d\n",
|
||||
samplerate, brate, quality);
|
||||
}
|
||||
|
||||
|
||||
/* init pcm_buf and mp3_buf */
|
||||
|
||||
if ((inpcm = calloc(PCMBUFFER, sizeof(short int))) == NULL) {
|
||||
fprintf(stderr, "Error: Can't allocate inpcm[%d]!\n", PCMBUFFER);
|
||||
exit(1);
|
||||
}
|
||||
else {
|
||||
inpcm_size = PCMBUFFER;
|
||||
}
|
||||
|
||||
if ((mp3buffer = calloc(MP3BUFFER, sizeof(unsigned char))) == NULL) {
|
||||
fprintf(stderr, "Error: Can't allocate mp3buffer[%d]!\n", MP3BUFFER);
|
||||
exit(1);
|
||||
}
|
||||
else {
|
||||
mp3buffer_size = MP3BUFFER;
|
||||
}
|
||||
|
||||
ditlen = init_cw(wpm, freq, rt, ft); /* generate raw dit, dah, silence */
|
||||
|
||||
strcat(chapterstr, " ");
|
||||
|
||||
/* read STDIN, assemble full words (anything ending in ' ') to 'word' and
|
||||
* generate CW, write to file by 'makeword'. words with > 1024 characters
|
||||
* will be split */
|
||||
|
||||
original_wpm = wpm; /* may be changed by QRQing */
|
||||
chapter = 0;
|
||||
openfile(chapter);
|
||||
|
||||
pos=0;
|
||||
while ((c = getc(infile)) != EOF) {
|
||||
|
||||
if (c == '\r') { /* DOS linebreaks */
|
||||
continue;
|
||||
}
|
||||
|
||||
word[pos++] = c;
|
||||
|
||||
if ((c == ' ') || (c == '\n') || (pos == 1024)) {
|
||||
word[pos] = '\0';
|
||||
if (strcmp(chapterstr, word) == 0) { /* new chapter */
|
||||
closefile(chapter, cw);
|
||||
cw=0;
|
||||
chapter++;
|
||||
|
||||
if (qrq) {
|
||||
wpm = original_wpm; /* restore CW */
|
||||
ditlen = init_cw(wpm, freq, rt, ft);
|
||||
}
|
||||
|
||||
openfile(chapter);
|
||||
}
|
||||
makeword(word);
|
||||
cw++; tw++; qw++;
|
||||
|
||||
word[0] = '\0';
|
||||
pos = 0;
|
||||
|
||||
/* every 'qrq' minutes (qrq*wpm words), speed up 1 WpM */
|
||||
if (qw == (qrq*wpm)) {
|
||||
wpm += 1;
|
||||
ditlen = init_cw(wpm, freq, rt, ft);
|
||||
qw = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
/* eof */
|
||||
|
||||
closefile(chapter, cw);
|
||||
|
||||
free(mp3buffer);
|
||||
free(inpcm);
|
||||
|
||||
/* factor 0.9 due to many 'words' which aren't actually words, like '\n' */
|
||||
printf("Total words: %d, total time: %d min\n", tw, (int) ((tw/wpm)*0.9));
|
||||
|
||||
lame_close(gfp);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* init_cw - generates a dit and a dah to dit_buf and dah_buf */
|
||||
|
||||
int init_cw (int wpm, int freq, int rt, int ft) {
|
||||
int x;
|
||||
int len;
|
||||
double val;
|
||||
|
||||
printf("Initializing CW buffers at %d WpM: ", wpm);
|
||||
|
||||
/* dah */
|
||||
len = (int) 3.0*6.0*samplerate/(5.0*wpm); /* in samples */
|
||||
|
||||
/* ditlen not set == init_cw has not been called yet */
|
||||
if (!ditlen) {
|
||||
/* allocate memory for the buffer */
|
||||
if ((dah_buf = calloc(len, sizeof(short int))) == NULL) {
|
||||
fprintf(stderr, "Error: Can't allocate dah_buf[%d]\n", len);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
for (x=0; x < len; x++) {
|
||||
val = sin(2*M_PI*freq*x/samplerate);
|
||||
if (x < rt) { /* shaping with sin^2 */
|
||||
val *= pow(sin(M_PI*x/(2.0*rt)),2);
|
||||
}
|
||||
if (x > (len-ft)) {
|
||||
val *= pow((sin(2*M_PI*(x-(len-ft)+ft)/(4*ft))), 2);
|
||||
}
|
||||
|
||||
dah_buf[x] = (int) (val * 20000.0);
|
||||
}
|
||||
|
||||
printf("dah_buf[%d], ", x);
|
||||
|
||||
/* dit */
|
||||
len = (int) 6.0*samplerate/(5.0*wpm); /* in samples */
|
||||
|
||||
/* ditlen not set == init_cw has not been called yet */
|
||||
if (!ditlen) {
|
||||
/* allocate memory for the buffer */
|
||||
if ((dit_buf = calloc(len, sizeof(short int))) == NULL) {
|
||||
fprintf(stderr, "Error: Can't allocate dit_buf[%d]\n", len);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
for (x=0; x < len; x++) {
|
||||
val = sin(2*M_PI*freq*x/samplerate);
|
||||
if (x < rt) {
|
||||
val *= pow(sin(M_PI*x/(2.0*rt)), 2);
|
||||
}
|
||||
if (x > (len-ft)) {
|
||||
val *= pow((sin(2*M_PI*(x-(len-ft)+ft)/(4*ft))), 2);
|
||||
}
|
||||
dit_buf[x] = (int) (val * 20000.0);
|
||||
}
|
||||
|
||||
printf("dit_buf[%d]\n\n", x);
|
||||
|
||||
return x; /* = length of dit/silence */
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* makeword -- converts 'text' to CW by concatenating dit_buf amd dah_bufs,
|
||||
* encodes this to MP3 and writes to open filehandle outfile */
|
||||
|
||||
void makeword(char * text) {
|
||||
const char *code; /* CW code as . and - */
|
||||
int outbytes;
|
||||
|
||||
int c;
|
||||
int i,u,w;
|
||||
int j;
|
||||
|
||||
j = 0; /* position in 'inpcm' buffer */
|
||||
|
||||
for (i = 0; i < strlen(text); i++) {
|
||||
c = toupper(text[i]);
|
||||
|
||||
if (c > 64 && c < 91) { /* trouble with isalpha() under Win32 */
|
||||
code = codetable[c-65]; /* even with locale = C ...? */
|
||||
}
|
||||
else if (c > 47 && c < 58) {
|
||||
code = codetable[c-22];
|
||||
}
|
||||
else if (c == '.') { code = ".-.-.-"; } /* messy */
|
||||
else if (c == ',') { code = "--..--"; }
|
||||
else if (c == '=') { code = "-...-"; }
|
||||
else if (c == '?') { code = "..--.."; }
|
||||
else if (c == '-') { code = "-....-"; }
|
||||
else if (c==228 || c==196 || c==-28 || c==-60) { code = ".-.-"; } /* ae */
|
||||
else if (c==252 || c==220 || c==-4 || c==-36) { code = "..--"; } /* ue */
|
||||
else if (c==246 || c==214 || c==-10 || c==-42) { code = "---."; } /* oe */
|
||||
else if (c == 223 || c == -33) { code = "... --.."; } /* sz */
|
||||
else if (c == '(') { code = "-.--."; }
|
||||
else if (c == ')') { code = "-.--.-"; }
|
||||
else if (c == '!') { code = ".-.-.-"; }
|
||||
else if (c == ';') { code = "-.-.-."; }
|
||||
else if (c == '/') { code = "-..-."; }
|
||||
else if (c == '@') { code = ".--.-."; }
|
||||
else if (c == ':') { code = "---..."; }
|
||||
else if (c == '"') { code = ".-..-."; }
|
||||
else if (c == '\'') { code = ".----."; }
|
||||
else if (c == ' ') { code = " "; }
|
||||
else if (c == '\n') {
|
||||
if (strlen(text) == 1) {
|
||||
code = " -...- "; /* new paragraph */
|
||||
}
|
||||
else {
|
||||
code = " ";
|
||||
}
|
||||
}
|
||||
else {
|
||||
code = " ";
|
||||
fprintf(stderr, "Warning: don't know CW for '%c'\n", (char) c);
|
||||
}
|
||||
|
||||
/* code contains word as ./-, now assemble pcm buffer */
|
||||
|
||||
for (w = 0; w < strlen(code) ; w++) {
|
||||
|
||||
/* make sure the inpcm buffer doesn't run full,
|
||||
* with a conservative margin. reallocate memory if neccesary */
|
||||
if (j > inpcm_size-(6*ditlen)) {
|
||||
inpcm_size += (6*ditlen);
|
||||
mp3buffer_size += (8*ditlen + 7200);
|
||||
if ((inpcm = realloc(inpcm, inpcm_size*sizeof(short int)))== NULL) {
|
||||
fprintf(stderr, "Error: Can't realloc inpcm[%d]\n", inpcm_size);
|
||||
}
|
||||
if ((mp3buffer = realloc(mp3buffer, mp3buffer_size*sizeof(char)))
|
||||
== NULL) {
|
||||
fprintf(stderr, "Error: Can't realloc mp3buffer[%d]\n",
|
||||
mp3buffer_size);
|
||||
}
|
||||
}
|
||||
|
||||
c = code[w];
|
||||
|
||||
if (c == '.') {
|
||||
for (u=0; u < ditlen; u++) { inpcm[++j] = dit_buf[u]; }
|
||||
}
|
||||
else if (c == '-') {
|
||||
for (u=0; u < (3*ditlen); u++) { inpcm[++j] = dah_buf[u]; }
|
||||
}
|
||||
else {
|
||||
for (u=0; u < ditlen; u++) { inpcm[++j] = 0; }
|
||||
}
|
||||
|
||||
for (u=0; u < ditlen; u++) { inpcm[++j] = 0; }
|
||||
|
||||
}
|
||||
|
||||
for (u=0; u < (2*ditlen); u++) { inpcm[++j] = 0; } /* inter word space */
|
||||
|
||||
}
|
||||
|
||||
/* j = total length of samples in 'inpcm' */
|
||||
|
||||
outbytes = lame_encode_buffer(gfp, inpcm, inpcm, j, mp3buffer, mp3buffer_size);
|
||||
if (outbytes < 0) {
|
||||
fprintf(stderr, "Error: lame_encode_buffer returned %d. Exit.\n", outbytes);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (fwrite(mp3buffer, sizeof(char), outbytes, outfile) != outbytes) {
|
||||
fprintf(stderr, "Error: Writing %db to file failed. Exit.\n", outbytes);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* closefile -- finishes writing the current file, flushes the encoder buffer */
|
||||
|
||||
void closefile (int letter, int cw) {
|
||||
int outbytes;
|
||||
char mp3filename[80] = "";
|
||||
|
||||
printf("words: %d, minutes: %d\n", cw, (int) ((cw/wpm)*0.9));
|
||||
|
||||
sprintf(mp3filename, "%s%02d.mp3", chapterfilename, letter);
|
||||
printf("Finishing %s\n\n", mp3filename);
|
||||
|
||||
outbytes = lame_encode_flush(gfp, mp3buffer, mp3buffer_size);
|
||||
|
||||
if (outbytes < 0) {
|
||||
fprintf(stderr, "Error: lame_encode_buffer returned %d.\n", outbytes);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (fwrite(mp3buffer, sizeof(char), outbytes, outfile) != outbytes) {
|
||||
fprintf(stderr, "Error: Writing %db to file failed. Exit.\n", outbytes);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fclose(outfile);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* openfile -- starts a new chapter by opening Chapter%d.mp3 */
|
||||
|
||||
void openfile (int chapter) {
|
||||
char mp3filename[80] = "";
|
||||
static char tmp[80] = "";
|
||||
|
||||
sprintf(mp3filename, "%s%02d.mp3", chapterfilename, chapter);
|
||||
printf("Starting %s\n", mp3filename);
|
||||
|
||||
if ((outfile = fopen(mp3filename, "wb")) == NULL) {
|
||||
fprintf(stderr, "Error: Failed to open %s\n", mp3filename);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
sprintf(tmp, "%s - %d", id3_title, chapter); /* generate title */
|
||||
|
||||
id3tag_init(gfp);
|
||||
id3tag_set_artist(gfp, id3_author);
|
||||
id3tag_set_year(gfp, id3_year);
|
||||
id3tag_set_title(gfp, tmp);
|
||||
id3tag_set_comment(gfp, id3_comment);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void help (void) {
|
||||
printf("ebook2cw v%s - (c) 2007 by Fabian Kurz, DJ1YFK, http://fkurz.net/\n", VERSION);
|
||||
printf("\n");
|
||||
printf("ebook2cw [-w wpm] [-f freq] [-R risetime] [-F falltime]\n");
|
||||
printf(" [-s samplerate] [-b mp3bitrate] [-q mp3quality]\n");
|
||||
printf(" [-c chapter-separator] [-o outfile-name] [-Q minutes]\n");
|
||||
printf(" [-a author] [-t title] [-k comment] [-y year]\n");
|
||||
printf(" [infile]\n\n");
|
||||
printf("defaults: 25 WpM, 600Hz, RT=FT=50, s=11025Hz, b=16kbps,\n");
|
||||
printf(" c=\"CHAPTER\", o=\"Chapter\" infile = stdin\n");
|
||||
printf("\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
|
|
@ -0,0 +1,280 @@
|
|||
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
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
0.5.1 / 2008-01-08 Fabian Kurz <mail@fkurz.net>
|
||||
* Fixed ID3 title (chapter number) generation.
|
||||
|
||||
0.5.0 / 2007-12-19 Fabian Kurz <mail@fkurz.net>
|
||||
* Added support for writing ID3 tags.
|
||||
* Added -Q command line switch: QRQ by 1 WpM every n minutes.
|
||||
|
||||
0.4.0 / 2007-12-17 Fabian Kurz <mail@fkurz.net>
|
||||
* Implemented dynamic memory allocation.
|
||||
|
||||
0.3.0 / 2007-11-28 Fabian Kurz <mail@fkurz.net>
|
||||
* Added forgotten characters: @ and /.
|
||||
|
||||
0.2.0 / 2007-11-27 Fabian Kurz <mail@fkurz.net>
|
||||
|
||||
* Fixed handling of umlauts (öäüß)
|
||||
* The chapter separator is now case sensitive.
|
||||
|
||||
0.1.0 / 2007-11-22 Fabian Kurz <mail@fkurz.net>
|
||||
|
||||
* Initial release of ebook2cw.
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
# ebook2cw Makefile -- Fabian Kurz, DJ1YFK -- http://fkurz.net/ham/ebook2cw.html
|
||||
|
||||
VERSION=0.5.3
|
||||
DESTDIR ?= /usr
|
||||
|
||||
all: ebook2cw
|
||||
|
||||
ebook2cw: ebook2cw.c
|
||||
gcc ebook2cw.c -pedantic -Wall -lm -lmp3lame -D VERSION=\"$(VERSION)\" -o ebook2cw
|
||||
|
||||
static:
|
||||
gcc -static ebook2cw.c -lmp3lame -lm -D VERSION=\"$(VERSION)\" -o ebook2cw
|
||||
|
||||
install:
|
||||
install -d -v $(DESTDIR)/share/man/man1/
|
||||
install -d -v $(DESTDIR)/bin/
|
||||
install -s -m 0755 ebook2cw $(DESTDIR)/bin/
|
||||
install -m 0644 ebook2cw.1 $(DESTDIR)/share/man/man1/
|
||||
|
||||
uninstall:
|
||||
rm -f $(DESTDIR)/bin/ebook2cw
|
||||
rm -f $(DESTDIR)/share/man/man1/ebook2cw.1
|
||||
|
||||
clean:
|
||||
rm -f ebook2cw *~ *.mp3
|
||||
|
||||
dist:
|
||||
sed 's/v[0-9].[0-9].[0-9]/v$(VERSION)/g' README > README2
|
||||
rm -f README
|
||||
mv README2 README
|
||||
rm -f releases/ebook2cw-$(VERSION).tar.gz
|
||||
rm -rf releases/ebook2cw-$(VERSION)
|
||||
mkdir ebook2cw-$(VERSION)
|
||||
cp ebook2cw.c ChangeLog ebook2cw.1 \
|
||||
COPYING Makefile ebook2cw-$(VERSION)
|
||||
tar -zcf ebook2cw-$(VERSION).tar.gz ebook2cw-$(VERSION)
|
||||
mv ebook2cw-$(VERSION) releases/
|
||||
mv ebook2cw-$(VERSION).tar.gz releases/
|
||||
md5sum releases/*.gz > releases/md5sums.txt
|
||||
chmod a+r releases/*
|
||||
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
.TH ebook2cw 1 "JUNE 2007" Linux "User Manuals"
|
||||
.SH NAME
|
||||
ebook2cw \- convert ebooks to morse mp3s
|
||||
.SH SYNOPSIS
|
||||
.B ebook2cw
|
||||
[OPTIONS]
|
||||
.SH DESCRIPTION
|
||||
.B ebook2cw
|
||||
ebook2cw is a command line program which converts a plain text ebook to morse
|
||||
code MP3 files. It works on several platforms, including Windows and Linux.
|
||||
|
||||
A number of CW and MP3 parameters can be changed from their default values, by
|
||||
command line switches. These are (default values in brackets):
|
||||
|
||||
.B -w wpm
|
||||
- CW speed in words per minute [25]
|
||||
|
||||
.B -f freq
|
||||
- audio frequency in Hz [600]
|
||||
|
||||
.B -Q minutes
|
||||
- Increase CW speed (QRQ) by 1 WpM in intervals of `minutes'. Speed will be
|
||||
reset to the initial value at the start of each chapter. [0]
|
||||
|
||||
.B -R risetime
|
||||
- risetime, in samples [50]
|
||||
|
||||
.B -F falltime
|
||||
- falltime, samples [50]
|
||||
|
||||
.B -s samplerate
|
||||
- samplerate for the MP3 file [11025]
|
||||
|
||||
.B -b bitrate
|
||||
- MP3 bitrate, kbps [16]
|
||||
|
||||
.B -q quality
|
||||
- MP3 quality, 1 (best) to 9 (worst). CW still sounds very good with the worst quality, encoding time is greatly reduced. [9]
|
||||
|
||||
.B -c chapter separator
|
||||
- Split chapters at this string [CHAPTER]
|
||||
|
||||
.B -o outfile-name
|
||||
- Output filename (chapter number and .mp3 will be appended) [Chapter]
|
||||
|
||||
.B -a author
|
||||
- Author for the ID3 tag. Use quotes for strings with spaces (e.g. "JW Goethe")
|
||||
|
||||
.B -t title
|
||||
- Title for the ID3 tag. Use quotes for strings with spaces (e.g. "Faust II")
|
||||
|
||||
.B -k comment
|
||||
- Comment for the ID3 tag. Use quotes for strings with spaces.
|
||||
|
||||
.B -y year
|
||||
- Year for the ID3 tag.
|
||||
|
||||
.SH AUTHOR
|
||||
Fabian Kurz, DJ1YFK <mail@fkurz.net>
|
||||
|
||||
http://fkurz.net/ham/ebook2cw.html
|
||||
.SH "SEE ALSO"
|
||||
.BR morse (1)
|
||||
|
|
@ -0,0 +1,528 @@
|
|||
/*
|
||||
ebook2cw - converts an ebook to morse mp3s
|
||||
|
||||
Copyright (C) 2007 Fabian Kurz, DJ1YFK
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 2 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
|
||||
Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
source code looks properly indented with tw=4
|
||||
|
||||
*/
|
||||
|
||||
#include "lame/lame.h"
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "codetables.h"
|
||||
|
||||
#ifndef VERSION
|
||||
#define VERSION "0.0.0"
|
||||
#endif
|
||||
|
||||
#define PCMBUFFER 220500 /* 20 seconds at 11kHz, for one word. plenty. */
|
||||
#define MP3BUFFER 285000 /* abt 1.25*PCMBUFFER + 7200, as recommended */
|
||||
|
||||
lame_global_flags *gfp;
|
||||
|
||||
FILE *outfile;
|
||||
FILE *infile;
|
||||
|
||||
/* MP3 samplerate, bitrate, quality. */
|
||||
int samplerate = 11025;
|
||||
int brate = 16;
|
||||
int quality = 9;
|
||||
|
||||
/* CW parameters */
|
||||
int wpm = 25;
|
||||
int freq = 600;
|
||||
int rt = 50; /* rise/fall time in samples */
|
||||
int ft = 50;
|
||||
int qrq = 0; /* rise speed by 1 WpM every qrq minutes */
|
||||
|
||||
/* the buffers for dit, dah, raw pcm and mp3 output, will me calloc'ed to the
|
||||
* default values, and if needed realloc'ed to the needed size */
|
||||
|
||||
short int *dit_buf;
|
||||
short int *dah_buf;
|
||||
short int *inpcm;
|
||||
unsigned char *mp3buffer;
|
||||
|
||||
int inpcm_size;
|
||||
int mp3buffer_size;
|
||||
|
||||
int ditlen=0; /* number of samples in a 'dit' */
|
||||
|
||||
/* Chapters are split by this string */
|
||||
char chapterstr[80]="CHAPTER";
|
||||
char chapterfilename[80]="Chapter"; /* full filename: Chapter%02d.mp3 */
|
||||
|
||||
/* ID3-tag data: author and title */
|
||||
char id3_author[80]="CW-Book";
|
||||
char id3_title[80]="";
|
||||
char id3_comment[80]="";
|
||||
char id3_year[5]="";
|
||||
|
||||
/* const static char *codetableUTF8cyr[] = {
|
||||
".-", "-...", ".--", "--.", "-..", ".", "...-", "--..", "..",".---",
|
||||
"-.-",".-..","--","-.","---",".--.",".-.","...","-","..-","..-.",
|
||||
"....","-.-.","---.","----","--.-","-..-","-.--","-..-","..-..","..--",
|
||||
".-.-"}; */
|
||||
|
||||
/* functions */
|
||||
int init_cw (int wpm, int freq, int rt, int ft);
|
||||
void help (void);
|
||||
void makeword(char * text, int utf8);
|
||||
void closefile (int letter, int cw);
|
||||
void openfile (int chapter);
|
||||
|
||||
/* main */
|
||||
|
||||
int main (int argc, char** argv) {
|
||||
int pos, i, original_wpm;
|
||||
int utf8 = 0;
|
||||
int c;
|
||||
char word[1024]=""; /* will be cut when > 1024 chars long */
|
||||
int chapter = 0;
|
||||
int cw = 0, tw = 0, qw = 0; /* chapter words, total words, qrq words */
|
||||
|
||||
infile = stdin;
|
||||
|
||||
while((i = getopt(argc, argv, "o:w:f:R:F:s:b:q:c:a:t:k:y:Q:hu")) != -1) {
|
||||
switch (i) {
|
||||
case 'w':
|
||||
if ((wpm = atoi(optarg)) < 1) {
|
||||
fprintf(stderr, "Error: Speed (-w) must be > 0!\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
case 'f':
|
||||
freq = atoi(optarg);
|
||||
break;
|
||||
case 'R':
|
||||
rt = atoi(optarg);
|
||||
break;
|
||||
case 'F':
|
||||
ft = atoi(optarg);
|
||||
break;
|
||||
case 's':
|
||||
samplerate = atoi(optarg);
|
||||
break;
|
||||
case 'b':
|
||||
brate = atoi(optarg);
|
||||
break;
|
||||
case 'q':
|
||||
quality = atoi(optarg);
|
||||
break;
|
||||
case 'c':
|
||||
strncpy(chapterstr, optarg, 78);
|
||||
break;
|
||||
case 'o':
|
||||
strncpy(chapterfilename, optarg, 78);
|
||||
break;
|
||||
case 'a':
|
||||
strncpy(id3_author, optarg, 78);
|
||||
break;
|
||||
case 't':
|
||||
strncpy(id3_title, optarg, 75);
|
||||
break;
|
||||
case 'k':
|
||||
strncpy(id3_comment, optarg, 78);
|
||||
break;
|
||||
case 'y':
|
||||
strncpy(id3_year, optarg, 4);
|
||||
break;
|
||||
case 'Q':
|
||||
if ((qrq = atoi(optarg)) < 1) {
|
||||
fprintf(stderr, "Error: QRQ time (-Q) must be > 0!\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
case 'u':
|
||||
utf8 = 1;
|
||||
break;
|
||||
case 'h':
|
||||
default:
|
||||
help();
|
||||
} /* switch */
|
||||
} /* while */
|
||||
|
||||
if (optind < argc) { /* something left? if so, use as infile */
|
||||
if ((argv[optind][0] != '-') && (argv[optind][0] != '\0')) {
|
||||
if ((infile = fopen(argv[optind], "r")) == NULL) {
|
||||
fprintf(stderr, "Error: Cannot open file %s. Exit.\n",
|
||||
argv[optind]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf("ebook2cw %s - (c) 2007 by Fabian Kurz, DJ1YFK\n", VERSION);
|
||||
printf("Speed: %d WpM, Freq: %dHz, Chapter: >%s<, Encoding: %s\n\n",
|
||||
wpm, freq, chapterstr, utf8 ? "UTF8" : "ISO 8859-1");
|
||||
|
||||
|
||||
/* init lame */
|
||||
gfp = lame_init();
|
||||
lame_set_num_channels(gfp,1);
|
||||
lame_set_in_samplerate(gfp, samplerate);
|
||||
lame_set_brate(gfp, brate);
|
||||
lame_set_mode(gfp,1);
|
||||
lame_set_quality(gfp, quality);
|
||||
|
||||
if (lame_init_params(gfp) < 0) {
|
||||
fprintf(stderr, "Failed: lame_init_params(gfp) \n");
|
||||
return(1);
|
||||
}
|
||||
else {
|
||||
printf("Initialized lame: samplerate=%d, bitrate=%d, quality=%d\n",
|
||||
samplerate, brate, quality);
|
||||
}
|
||||
|
||||
/* init pcm_buf and mp3_buf */
|
||||
|
||||
if ((inpcm = calloc(PCMBUFFER, sizeof(short int))) == NULL) {
|
||||
fprintf(stderr, "Error: Can't allocate inpcm[%d]!\n", PCMBUFFER);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
else {
|
||||
inpcm_size = PCMBUFFER;
|
||||
}
|
||||
|
||||
if ((mp3buffer = calloc(MP3BUFFER, sizeof(unsigned char))) == NULL) {
|
||||
fprintf(stderr, "Error: Can't allocate mp3buffer[%d]!\n", MP3BUFFER);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
else {
|
||||
mp3buffer_size = MP3BUFFER;
|
||||
}
|
||||
|
||||
ditlen = init_cw(wpm, freq, rt, ft); /* generate raw dit, dah, silence */
|
||||
|
||||
strcat(chapterstr, " ");
|
||||
|
||||
/* read STDIN, assemble full words (anything ending in ' ') to 'word' and
|
||||
* generate CW, write to file by 'makeword'. words with > 1024 characters
|
||||
* will be split */
|
||||
|
||||
original_wpm = wpm; /* may be changed by QRQing */
|
||||
chapter = 0;
|
||||
openfile(chapter);
|
||||
|
||||
pos=0;
|
||||
while ((c = getc(infile)) != EOF) {
|
||||
|
||||
if (c == '\r') /* DOS linebreaks */
|
||||
continue;
|
||||
|
||||
word[pos++] = c;
|
||||
|
||||
if ((c == ' ') || (c == '\n') || (pos == 1024)) {
|
||||
word[pos] = '\0';
|
||||
if (strcmp(chapterstr, word) == 0) { /* new chapter */
|
||||
closefile(chapter, cw);
|
||||
cw=0;
|
||||
chapter++;
|
||||
|
||||
/* restore to initial speed if we're QRQing */
|
||||
if (qrq) {
|
||||
wpm = original_wpm;
|
||||
ditlen = init_cw(wpm, freq, rt, ft);
|
||||
}
|
||||
|
||||
openfile(chapter);
|
||||
}
|
||||
makeword(word, utf8);
|
||||
cw++; tw++; qw++;
|
||||
|
||||
word[0] = '\0';
|
||||
pos = 0;
|
||||
|
||||
/* every 'qrq' minutes (qrq*wpm words), speed up 1 WpM */
|
||||
if (qw == (qrq*wpm)) {
|
||||
wpm += 1;
|
||||
ditlen = init_cw(wpm, freq, rt, ft);
|
||||
qw = 0;
|
||||
}
|
||||
} /* word */
|
||||
} /* eof */
|
||||
|
||||
closefile(chapter, cw);
|
||||
|
||||
free(mp3buffer);
|
||||
free(inpcm);
|
||||
|
||||
/* factor 0.9 due to many 'words' which aren't actually words, like '\n' */
|
||||
printf("Total words: %d, total time: %d min\n", tw, (int) ((tw/wpm)*0.9));
|
||||
|
||||
lame_close(gfp);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* init_cw - generates a dit and a dah to dit_buf and dah_buf */
|
||||
|
||||
int init_cw (int wpm, int freq, int rt, int ft) {
|
||||
int x;
|
||||
int len;
|
||||
double val;
|
||||
|
||||
printf("Initializing CW buffers at %d WpM: ", wpm);
|
||||
|
||||
/* dah */
|
||||
len = (int) (3.0*6.0*samplerate/(5.0*wpm)); /* in samples */
|
||||
|
||||
/* ditlen not set == init_cw has not been called yet */
|
||||
if (!ditlen) {
|
||||
/* allocate memory for the buffer */
|
||||
if ((dah_buf = calloc(len, sizeof(short int))) == NULL) {
|
||||
fprintf(stderr, "Error: Can't allocate dah_buf[%d]\n", len);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
for (x=0; x < len; x++) {
|
||||
val = sin(2*M_PI*freq*x/samplerate);
|
||||
if (x < rt) /* shaping with sin^2 */
|
||||
val *= pow(sin(M_PI*x/(2.0*rt)),2);
|
||||
|
||||
if (x > (len-ft))
|
||||
val *= pow((sin(2*M_PI*(x-(len-ft)+ft)/(4*ft))), 2);
|
||||
|
||||
dah_buf[x] = (short int) (val * 20000.0);
|
||||
}
|
||||
|
||||
printf("dah_buf[%d], ", x);
|
||||
|
||||
/* dit */
|
||||
len = (int) (6.0*samplerate/(5.0*wpm)); /* in samples */
|
||||
|
||||
/* ditlen not set == init_cw has not been called yet */
|
||||
if (!ditlen) {
|
||||
/* allocate memory for the buffer */
|
||||
if ((dit_buf = calloc(len, sizeof(short int))) == NULL) {
|
||||
fprintf(stderr, "Error: Can't allocate dit_buf[%d]\n", len);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
for (x=0; x < len; x++) {
|
||||
val = sin(2*M_PI*freq*x/samplerate);
|
||||
if (x < rt)
|
||||
val *= pow(sin(M_PI*x/(2.0*rt)), 2);
|
||||
|
||||
if (x > (len-ft))
|
||||
val *= pow((sin(2*M_PI*(x-(len-ft)+ft)/(4*ft))), 2);
|
||||
|
||||
dit_buf[x] = (short int) (val * 20000.0);
|
||||
}
|
||||
|
||||
printf("dit_buf[%d]\n\n", x);
|
||||
|
||||
return x; /* = length of dit/silence */
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* makeword -- converts 'text' to CW by concatenating dit_buf amd dah_bufs,
|
||||
* encodes this to MP3 and writes to open filehandle outfile */
|
||||
|
||||
void makeword(char * text, int utf8) {
|
||||
const char *code; /* CW code as . and - */
|
||||
int outbytes;
|
||||
|
||||
int c;
|
||||
int i,u,w;
|
||||
int j;
|
||||
unsigned char last=0; /* for utf8 2-byte characters */
|
||||
|
||||
j = 0; /* position in 'inpcm' buffer */
|
||||
|
||||
for (i = 0; i < strlen(text); i++) {
|
||||
c = (unsigned char) text[i];
|
||||
code = NULL;
|
||||
|
||||
if (c == '\n') { /* Same for UTF8 and ISO8859 */
|
||||
if (strlen(text) == 1) /* paragraph */
|
||||
code = " -...- ";
|
||||
else
|
||||
code = " ";
|
||||
}
|
||||
else if (!utf8) { /* ISO 8859-1 */
|
||||
code = iso8859[c];
|
||||
}
|
||||
else if (utf8) { /* UTF-8 */
|
||||
/* Character may be 1-byte ASCII or 2-byte UTF8 */
|
||||
if (!(c & 128)) { /* MSB = 0 -> 7bit ASCII */
|
||||
code = iso8859[c]; /* subset of iso8859 */
|
||||
}
|
||||
else {
|
||||
if (last && (c < 192) ) { /* this is the 2nd byte */
|
||||
/* 110yyyyy 10zzzzzz -> 00000yyy yyzzzzzz */
|
||||
c = ((last & 31) << 6) | (c & 63);
|
||||
code = utf8table[c];
|
||||
last = 0;
|
||||
}
|
||||
else {
|
||||
last = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (last) continue; /* first of two-byte character read */
|
||||
|
||||
/* Not found anything ... */
|
||||
if (code == NULL) {
|
||||
code = " ";
|
||||
if (c < 255) {
|
||||
fprintf(stderr, "Warning: don't know CW for '%c'\n", c);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "Warning: don't know CW for unicode &#%d;\n", c);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* code contains letter as ./-, now assemble pcm buffer */
|
||||
|
||||
for (w = 0; w < strlen(code) ; w++) {
|
||||
|
||||
/* make sure the inpcm buffer doesn't run full,
|
||||
* with a conservative margin. reallocate memory if neccesary */
|
||||
if (j > inpcm_size-(6*ditlen)) {
|
||||
inpcm_size += (6*ditlen);
|
||||
mp3buffer_size += (8*ditlen + 7200);
|
||||
if ((inpcm = realloc(inpcm, inpcm_size*sizeof(short int)))== NULL)
|
||||
fprintf(stderr, "Error: Can't realloc inpcm[%d]\n", inpcm_size);
|
||||
|
||||
if ((mp3buffer = realloc(mp3buffer, mp3buffer_size*sizeof(char)))
|
||||
== NULL)
|
||||
fprintf(stderr, "Error: Can't realloc mp3buffer[%d]\n",
|
||||
mp3buffer_size);
|
||||
}
|
||||
|
||||
c = code[w];
|
||||
|
||||
if (c == '.')
|
||||
for (u=0; u < ditlen; u++) inpcm[++j] = dit_buf[u];
|
||||
else if (c == '-')
|
||||
for (u=0; u < (3*ditlen); u++) inpcm[++j] = dah_buf[u];
|
||||
else
|
||||
for (u=0; u < ditlen; u++) inpcm[++j] = 0;
|
||||
|
||||
for (u=0; u < ditlen; u++) inpcm[++j] = 0;
|
||||
}
|
||||
|
||||
for (u=0; u < (2*ditlen); u++) inpcm[++j] = 0; /*inter word space*/
|
||||
|
||||
} /* foreach letter */
|
||||
|
||||
/* j = total length of samples in 'inpcm' */
|
||||
|
||||
outbytes = lame_encode_buffer(gfp, inpcm, inpcm, j, mp3buffer, mp3buffer_size);
|
||||
if (outbytes < 0) {
|
||||
fprintf(stderr, "Error: lame_encode_buffer returned %d. Exit.\n", outbytes);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (fwrite(mp3buffer, sizeof(char), outbytes, outfile) != outbytes) {
|
||||
fprintf(stderr, "Error: Writing %db to file failed. Exit.\n", outbytes);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* closefile -- finishes writing the current file, flushes the encoder buffer */
|
||||
|
||||
void closefile (int letter, int cw) {
|
||||
int outbytes;
|
||||
char mp3filename[80] = "";
|
||||
|
||||
printf("words: %d, minutes: %d\n", cw, (int) ((cw/wpm)*0.9));
|
||||
|
||||
snprintf(mp3filename, 80, "%s%02d.mp3", chapterfilename, letter);
|
||||
printf("Finishing %s\n\n", mp3filename);
|
||||
|
||||
outbytes = lame_encode_flush(gfp, mp3buffer, mp3buffer_size);
|
||||
|
||||
if (outbytes < 0) {
|
||||
fprintf(stderr, "Error: lame_encode_buffer returned %d.\n", outbytes);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (fwrite(mp3buffer, sizeof(char), outbytes, outfile) != outbytes) {
|
||||
fprintf(stderr, "Error: Writing %db to file failed. Exit.\n", outbytes);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
fclose(outfile);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* openfile -- starts a new chapter by opening Chapter%d.mp3 */
|
||||
|
||||
void openfile (int chapter) {
|
||||
char mp3filename[80] = "";
|
||||
static char tmp[80] = "";
|
||||
|
||||
snprintf(mp3filename, 80, "%s%02d.mp3", chapterfilename, chapter);
|
||||
printf("Starting %s\n", mp3filename);
|
||||
|
||||
if ((outfile = fopen(mp3filename, "wb")) == NULL) {
|
||||
fprintf(stderr, "Error: Failed to open %s\n", mp3filename);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
snprintf(tmp, 79, "%s - %d", id3_title, chapter); /* generate title */
|
||||
|
||||
id3tag_init(gfp);
|
||||
id3tag_set_artist(gfp, id3_author);
|
||||
id3tag_set_year(gfp, id3_year);
|
||||
id3tag_set_title(gfp, tmp);
|
||||
id3tag_set_comment(gfp, id3_comment);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void help (void) {
|
||||
printf("ebook2cw v%s - (c) 2007 by Fabian Kurz, DJ1YFK, http://fkurz.net/\n", VERSION);
|
||||
printf("\nThis is free software, and you are welcome to redistribute it\n");
|
||||
printf("under certain conditions (see COPYING).\n");
|
||||
printf("\n");
|
||||
printf("ebook2cw [-w wpm] [-f freq] [-R risetime] [-F falltime]\n");
|
||||
printf(" [-s samplerate] [-b mp3bitrate] [-q mp3quality]\n");
|
||||
printf(" [-c chapter-separator] [-o outfile-name] [-Q minutes]\n");
|
||||
printf(" [-a author] [-t title] [-k comment] [-y year]\n");
|
||||
printf(" [-u] [infile]\n\n");
|
||||
printf("defaults: 25 WpM, 600Hz, RT=FT=50, s=11025Hz, b=16kbps,\n");
|
||||
printf(" c=\"CHAPTER\", o=\"Chapter\" infile = stdin\n");
|
||||
printf("\n");
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
Binary file not shown.
|
|
@ -0,0 +1,280 @@
|
|||
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
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
0.6.0 / 2008-02-05 Fabian Kurz <mail@fkurz.net>
|
||||
* Full ISO 8859-1 character set is now available
|
||||
* UTF-8 support by command line switch -u. Currently
|
||||
implemented: Latin, basic cyrillic.
|
||||
|
||||
0.5.1 / 2008-01-08 Fabian Kurz <mail@fkurz.net>
|
||||
* Fixed ID3 title (chapter number) generation.
|
||||
|
||||
0.5.0 / 2007-12-19 Fabian Kurz <mail@fkurz.net>
|
||||
* Added support for writing ID3 tags.
|
||||
* Added -Q command line switch: QRQ by 1 WpM every n minutes.
|
||||
|
||||
0.4.0 / 2007-12-17 Fabian Kurz <mail@fkurz.net>
|
||||
* Implemented dynamic memory allocation.
|
||||
|
||||
0.3.0 / 2007-11-28 Fabian Kurz <mail@fkurz.net>
|
||||
* Added forgotten characters: @ and /.
|
||||
|
||||
0.2.0 / 2007-11-27 Fabian Kurz <mail@fkurz.net>
|
||||
|
||||
* Fixed handling of umlauts (öäüß)
|
||||
* The chapter separator is now case sensitive.
|
||||
|
||||
0.1.0 / 2007-11-22 Fabian Kurz <mail@fkurz.net>
|
||||
|
||||
* Initial release of ebook2cw.
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
# ebook2cw Makefile -- Fabian Kurz, DJ1YFK -- http://fkurz.net/ham/ebook2cw.html
|
||||
|
||||
VERSION=0.6.0
|
||||
DESTDIR ?= /usr
|
||||
|
||||
all: ebook2cw
|
||||
|
||||
ebook2cw: ebook2cw.c
|
||||
gcc ebook2cw.c -pedantic -Wall -lm -lmp3lame -D VERSION=\"$(VERSION)\" -o ebook2cw
|
||||
|
||||
static:
|
||||
gcc -static ebook2cw.c -lmp3lame -lm -D VERSION=\"$(VERSION)\" -o ebook2cw
|
||||
|
||||
install:
|
||||
install -d -v $(DESTDIR)/share/man/man1/
|
||||
install -d -v $(DESTDIR)/bin/
|
||||
install -s -m 0755 ebook2cw $(DESTDIR)/bin/
|
||||
install -m 0644 ebook2cw.1 $(DESTDIR)/share/man/man1/
|
||||
|
||||
uninstall:
|
||||
rm -f $(DESTDIR)/bin/ebook2cw
|
||||
rm -f $(DESTDIR)/share/man/man1/ebook2cw.1
|
||||
|
||||
clean:
|
||||
rm -f ebook2cw *~ *.mp3
|
||||
|
||||
dist:
|
||||
sed 's/v[0-9].[0-9].[0-9]/v$(VERSION)/g' README > README2
|
||||
rm -f README
|
||||
mv README2 README
|
||||
rm -f releases/ebook2cw-$(VERSION).tar.gz
|
||||
rm -rf releases/ebook2cw-$(VERSION)
|
||||
mkdir ebook2cw-$(VERSION)
|
||||
cp ebook2cw.c codetables.h ChangeLog ebook2cw.1 \
|
||||
COPYING Makefile ebook2cw-$(VERSION)
|
||||
tar -zcf ebook2cw-$(VERSION).tar.gz ebook2cw-$(VERSION)
|
||||
mv ebook2cw-$(VERSION) releases/
|
||||
mv ebook2cw-$(VERSION).tar.gz releases/
|
||||
md5sum releases/*.gz > releases/md5sums.txt
|
||||
chmod a+r releases/*
|
||||
|
||||
|
|
@ -0,0 +1,530 @@
|
|||
/*
|
||||
* ISO 8859-1 and UTF-8 to Morse code mappings
|
||||
* This file is part of ebook2cw and may be used under the same terms.
|
||||
* (c) 2008 Fabian Kurz, DJ1YFK
|
||||
*
|
||||
*
|
||||
* Currently included: ISO 8859-1 complete (all that can somehow be mapped)
|
||||
* UTF-8: Latin (basic, some extended) and basic Cyrillic
|
||||
* alphabet (32 letters).
|
||||
*/
|
||||
|
||||
const static char *iso8859[] = {
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
" ", /* space */
|
||||
"..--.", /* ! */
|
||||
".-..-.", /* " */
|
||||
NULL, /* # */
|
||||
"...-..-", /* $ */
|
||||
NULL, /* % */
|
||||
". ...", /* & */
|
||||
".----.", /* ' */
|
||||
"-.--.", /* ( */
|
||||
"-.--.-", /* ) */
|
||||
NULL, /* * */
|
||||
".-.-.", /* + */
|
||||
"--..--", /* , */
|
||||
"-....-", /* - */
|
||||
".-.-.-", /* . */
|
||||
"-..-.", /* / */
|
||||
"-----", /* 0 */
|
||||
".----", /* 1 */
|
||||
"..---", /* 2 */
|
||||
"...--", /* 3 */
|
||||
"....-", /* 4 */
|
||||
".....", /* 5 */
|
||||
"-....", /* 6 */
|
||||
"--...", /* 7 */
|
||||
"---..", /* 8 */
|
||||
"----.", /* 9 */
|
||||
"---...", /* : */
|
||||
"-.-.-.", /* ; */
|
||||
NULL, /* < */
|
||||
"-...-", /* = */
|
||||
NULL, /* < */
|
||||
"..--..", /* ? */
|
||||
".--.-.", /* @ */
|
||||
".-", /* A */
|
||||
"-...", /* B */
|
||||
"-.-.",
|
||||
"-..",
|
||||
".",
|
||||
"..-.",
|
||||
"--.",
|
||||
"....",
|
||||
"..",
|
||||
".---",
|
||||
"-.-",
|
||||
".-..",
|
||||
"--",
|
||||
"-.",
|
||||
"---",
|
||||
".--.",
|
||||
"--.-",
|
||||
".-.",
|
||||
"...",
|
||||
"-",
|
||||
"..-",
|
||||
"...-",
|
||||
".--",
|
||||
"-..-",
|
||||
"-.--",
|
||||
"--..", /* Z */
|
||||
NULL, /* [ */
|
||||
"-..-.", /* \ XXX */
|
||||
NULL, /* ] */
|
||||
NULL, /* ^ */
|
||||
NULL, /* _ */
|
||||
".----.", /* ` XXX */
|
||||
".-", /* a */
|
||||
"-...", /* b */
|
||||
"-.-.",
|
||||
"-..",
|
||||
".",
|
||||
"..-.",
|
||||
"--.",
|
||||
"....",
|
||||
"..",
|
||||
".---",
|
||||
"-.-",
|
||||
".-..",
|
||||
"--",
|
||||
"-.",
|
||||
"---",
|
||||
".--.",
|
||||
"--.-",
|
||||
".-.",
|
||||
"...",
|
||||
"-",
|
||||
"..-",
|
||||
"...-",
|
||||
".--",
|
||||
"-..-",
|
||||
"-.--",
|
||||
"--..", /* z */
|
||||
NULL, /* { */
|
||||
NULL, /* | */
|
||||
NULL, /* } */
|
||||
NULL, /* ~ */
|
||||
NULL, /* DEL */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL,
|
||||
".-..-.", /* « (angle quotes, <<, 171) */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
".-..-.", /* » (angle quotes, >>, 187) */
|
||||
NULL, NULL, NULL, NULL,
|
||||
".--.-", /* `A */
|
||||
".--.-", /* 'A */
|
||||
".-", /* ^A */
|
||||
".-", /* ~A */
|
||||
".-.-", /* "A */
|
||||
".--.-", /* °A */
|
||||
".- .", /* AE */
|
||||
"-.-..", /* ,C */
|
||||
"..-..", /* `E */
|
||||
"..-..", /* 'E */
|
||||
".", /* ^E */
|
||||
".", /* "E */
|
||||
"..", /* `I */
|
||||
"..", /* 'I */
|
||||
"..", /* ^I */
|
||||
"..", /* "I */
|
||||
"-..", /* -D */
|
||||
"--.--", /* ~N */
|
||||
"---", /* `O */
|
||||
"---", /* 'O */
|
||||
"---", /* ^O */
|
||||
"---", /* ~O */
|
||||
"---.", /* "O */
|
||||
NULL, /* x */
|
||||
"---.", /* /O */
|
||||
"..-", /* `U */
|
||||
"..-", /* 'U */
|
||||
"..-", /* ^U */
|
||||
"..--", /* "U */
|
||||
"-.--", /* 'Y */
|
||||
"-..", /* 'thorn' */
|
||||
"...--..", /* sz */
|
||||
".--.-", /* `a */
|
||||
".--.-", /* 'a */
|
||||
".-", /* ^a */
|
||||
".-", /* ~a */
|
||||
".-.-", /* "a */
|
||||
".--.-", /* °a */
|
||||
".- .", /* ae */
|
||||
"-.-..", /* ,c */
|
||||
"..-..", /* `e */
|
||||
"..-..", /* 'e */
|
||||
".", /* ^e */
|
||||
".", /* "e */
|
||||
"..", /* `i */
|
||||
"..", /* 'i */
|
||||
"..", /* ^i */
|
||||
"..", /* "i */
|
||||
"-..", /* -d */
|
||||
"--.--", /* ~n */
|
||||
"---", /* `o */
|
||||
"---", /* 'o */
|
||||
"---", /* ^o */
|
||||
"---", /* ~o */
|
||||
"---.", /* "o */
|
||||
NULL, /* ./. */
|
||||
"---.", /* /o */
|
||||
"..-", /* `u */
|
||||
"..-", /* 'u */
|
||||
"..-", /* ^u */
|
||||
"..--", /* "u */
|
||||
"-.--", /* 'y */
|
||||
"-..", /* 'thorn' */
|
||||
"-.--" /* "y */
|
||||
};
|
||||
|
||||
const static char *utf8table[] = {
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* first 128 are identical*/
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* to iso8859, so that */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* will be used instead */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* - 127 */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* control characters ...*/
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* -159 */
|
||||
" ", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, ".-..-.", NULL, NULL, NULL, NULL, /* 171 << */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, ".-..-.", NULL, NULL, NULL, NULL, /* 187 >> */
|
||||
/* same as in ISO8859 */
|
||||
".--.-", /* `A */ /* 192 ... */
|
||||
".--.-", /* 'A */
|
||||
".-", /* ^A */
|
||||
".-", /* ~A */
|
||||
".-.-", /* "A */
|
||||
".--.-", /* °A */
|
||||
".- .", /* AE */
|
||||
"-.-..", /* ,C */
|
||||
"..-..", /* `E */
|
||||
"..-..", /* 'E */
|
||||
".", /* ^E */
|
||||
".", /* "E */
|
||||
"..", /* `I */
|
||||
"..", /* 'I */
|
||||
"..", /* ^I */
|
||||
"..", /* "I */
|
||||
"-..", /* -D */
|
||||
"--.--", /* ~N */
|
||||
"---", /* `O */
|
||||
"---", /* 'O */
|
||||
"---", /* ^O */
|
||||
"---", /* ~O */
|
||||
"---.", /* "O */
|
||||
NULL, /* x */
|
||||
"---.", /* /O */
|
||||
"..-", /* `U */
|
||||
"..-", /* 'U */
|
||||
"..-", /* ^U */
|
||||
"..--", /* "U */
|
||||
"-.--", /* 'Y */
|
||||
"-..", /* 'thorn' */
|
||||
"...--..", /* sz */
|
||||
".--.-", /* `a */
|
||||
".--.-", /* 'a */
|
||||
".-", /* ^a */
|
||||
".-", /* ~a */
|
||||
".-.-", /* "a */
|
||||
".--.-", /* °a */
|
||||
".- .", /* ae */
|
||||
"-.-..", /* ,c */
|
||||
"..-..", /* `e */
|
||||
"..-..", /* 'e */
|
||||
".", /* ^e */
|
||||
".", /* "e */
|
||||
"..", /* `i */
|
||||
"..", /* 'i */
|
||||
"..", /* ^i */
|
||||
"..", /* "i */
|
||||
"-..", /* -d */
|
||||
"--.--", /* ~n */
|
||||
"---", /* `o */
|
||||
"---", /* 'o */
|
||||
"---", /* ^o */
|
||||
"---", /* ~o */
|
||||
"---.", /* "o */
|
||||
NULL, /* ./. */
|
||||
"---.", /* /o */
|
||||
"..-", /* `u */
|
||||
"..-", /* 'u */
|
||||
"..-", /* ^u */
|
||||
"..--", /* "u */
|
||||
"-.--", /* 'y */
|
||||
"-..", /* 'thorn' */
|
||||
"-.--" /* "y */ /* 255 */
|
||||
".-", ".-", ".-", ".-", ".-", ".-", /* 256-261, As with different hats */
|
||||
/* 262-269 Cs with different hats */
|
||||
"-.-.", "-.-.", "-.-.", "-.-.", "-.-.", "-.-.", "-.-.", "-.-.",
|
||||
"-..", "-..", "-..", "-..", /* 270-273 Ds with different stuff */
|
||||
/* 274-283 different Es */
|
||||
".", ".", ".", ".", ".", ".", ".", ".", ".", ".",
|
||||
/* 284-291 different Gs */
|
||||
"--.", "--.", "--.", "--.", "--.", "--.", "--.", "--.",
|
||||
/* 292-295 different Hs */
|
||||
"....", "....", "....", "....",
|
||||
/* 296-305 different Is */
|
||||
"..", "..", "..", "..", "..", "..", "..", "..", "..", "..",
|
||||
/* 306-307 IJ ligatures */
|
||||
".. .---", ".. .---",
|
||||
/* 308-309 Js */
|
||||
".---", ".---",
|
||||
/* 310-312 Ks */
|
||||
"-.-", "-.-",
|
||||
/* 313-322 different Ls */
|
||||
".-..", ".-..", ".-..", ".-..", ".-..", ".-..", ".-..",
|
||||
".-..", ".-..", ".-..",
|
||||
/* 323-331 different Ns */
|
||||
"-.", "-.", "-.", "-.", "-.", "-.", "-.", "-.", "-.",
|
||||
/* 332-337 Os */
|
||||
"---", "---", "---", "---", "---", "---",
|
||||
/* 338-339 OEs */
|
||||
"---.", "---.",
|
||||
/* 340-345 Rs */
|
||||
".-.", ".-.", ".-.", ".-.", ".-.", ".-.",
|
||||
/* 346-353 Ss */
|
||||
"...", "...", "...", "...", "...", "...", "...", "...",
|
||||
/* 354-359 Ts */
|
||||
"-", "-", "-", "-", "-", "-",
|
||||
/* 360-371 Us */
|
||||
"..-", "..-", "..-", "..-", "..-", "..-", "..-", "..-", "..-",
|
||||
"..-", "..-", "..-",
|
||||
/* 372-373 Ws */
|
||||
".--", ".--",
|
||||
/* 374-377 Ys */
|
||||
"-.--", "-.--", "-.--",
|
||||
/* 377-382 Zs */
|
||||
"--..", "--..", "--..", "--..", "--..", "--..",
|
||||
/* 383 S */
|
||||
"...",
|
||||
/* 384-389 Bs */
|
||||
"-...", "-...", "-...", "-...", "-...", "-...",
|
||||
NULL, NULL, NULL, NULL, NULL, /* all kind of weird stuff */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 1023 */
|
||||
|
||||
/* 1024-1039, cyrillic nonstandard stuff */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
|
||||
".-", "-...", ".--", "--.", "-..", ".", "...-", /* 1040-1071 */
|
||||
"--..", "..",".---", "-.-", ".-..", "--", "-.", /* uppercase */
|
||||
"---", ".--.", ".-.", "...", "-", "..-", "..-.", /* cyrillic */
|
||||
"....", "-.-.", "---.", "----", "--.-", "-..-",
|
||||
"-.--", "-..-", "..-..", "..--", ".-.-",
|
||||
".-", "-...", ".--", "--.", "-..", ".", "...-", /* 1072-1103 */
|
||||
"--..", "..",".---", "-.-", ".-..", "--", "-.", /* lowercase */
|
||||
"---", ".--.", ".-.", "...", "-", "..-", "..-.", /* cyrillic */
|
||||
"....", "-.-.", "---.", "----", "--.-", "-..-",
|
||||
"-.--", "-..-", "..-..", "..--", ".-.-",
|
||||
|
||||
/* 1104 - 1920 not used yet... */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL /* 1920 */
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
.TH ebook2cw 1 "JUNE 2007" Linux "User Manuals"
|
||||
.SH NAME
|
||||
ebook2cw \- convert ebooks to morse mp3s
|
||||
.SH SYNOPSIS
|
||||
.B ebook2cw
|
||||
[OPTIONS]
|
||||
.SH DESCRIPTION
|
||||
.B ebook2cw
|
||||
ebook2cw is a command line program which converts a plain text ebook to morse
|
||||
code MP3 files. It works on several platforms, including Windows and Linux.
|
||||
|
||||
A number of CW and MP3 parameters can be changed from their default values, by
|
||||
command line switches. These are (default values in brackets):
|
||||
|
||||
.B -w wpm
|
||||
- CW speed in words per minute [25]
|
||||
|
||||
.B -f freq
|
||||
- audio frequency in Hz [600]
|
||||
|
||||
.B -Q minutes
|
||||
- Increase CW speed (QRQ) by 1 WpM in intervals of `minutes'. Speed will be
|
||||
reset to the initial value at the start of each chapter. [0]
|
||||
|
||||
.B -R risetime
|
||||
- risetime, in samples [50]
|
||||
|
||||
.B -F falltime
|
||||
- falltime, samples [50]
|
||||
|
||||
.B -s samplerate
|
||||
- samplerate for the MP3 file [11025]
|
||||
|
||||
.B -b bitrate
|
||||
- MP3 bitrate, kbps [16]
|
||||
|
||||
.B -q quality
|
||||
- MP3 quality, 1 (best) to 9 (worst). CW still sounds very good with the worst quality, encoding time is greatly reduced. [9]
|
||||
|
||||
.B -c chapter separator
|
||||
- Split chapters at this string [CHAPTER]
|
||||
|
||||
.B -o outfile-name
|
||||
- Output filename (chapter number and .mp3 will be appended) [Chapter]
|
||||
|
||||
.B -a author
|
||||
- Author for the ID3 tag. Use quotes for strings with spaces (e.g. "JW Goethe")
|
||||
|
||||
.B -t title
|
||||
- Title for the ID3 tag. Use quotes for strings with spaces (e.g. "Faust II")
|
||||
|
||||
.B -k comment
|
||||
- Comment for the ID3 tag. Use quotes for strings with spaces.
|
||||
|
||||
.B -y year
|
||||
- Year for the ID3 tag.
|
||||
|
||||
.B -u
|
||||
- Switches input encoding format to UTF-8. Default is ISO 8859-1.
|
||||
|
||||
.SH AUTHOR
|
||||
Fabian Kurz, DJ1YFK <mail@fkurz.net>
|
||||
|
||||
http://fkurz.net/ham/ebook2cw.html
|
||||
.SH "SEE ALSO"
|
||||
.BR morse (1)
|
||||
|
|
@ -0,0 +1,528 @@
|
|||
/*
|
||||
ebook2cw - converts an ebook to morse mp3s
|
||||
|
||||
Copyright (C) 2008 Fabian Kurz, DJ1YFK
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 2 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
|
||||
Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
source code looks properly indented with tw=4
|
||||
|
||||
*/
|
||||
|
||||
#include "lame/lame.h"
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "codetables.h"
|
||||
|
||||
#ifndef VERSION
|
||||
#define VERSION "0.0.0"
|
||||
#endif
|
||||
|
||||
#define PCMBUFFER 220500 /* 20 seconds at 11kHz, for one word. plenty. */
|
||||
#define MP3BUFFER 285000 /* abt 1.25*PCMBUFFER + 7200, as recommended */
|
||||
|
||||
lame_global_flags *gfp;
|
||||
|
||||
FILE *outfile;
|
||||
FILE *infile;
|
||||
|
||||
/* MP3 samplerate, bitrate, quality. */
|
||||
int samplerate = 11025;
|
||||
int brate = 16;
|
||||
int quality = 5;
|
||||
|
||||
/* CW parameters */
|
||||
int wpm = 25;
|
||||
int freq = 600;
|
||||
int rt = 50; /* rise/fall time in samples */
|
||||
int ft = 50;
|
||||
int qrq = 0; /* rise speed by 1 WpM every qrq minutes */
|
||||
|
||||
/* the buffers for dit, dah, raw pcm and mp3 output, will me calloc'ed to the
|
||||
* default values, and if needed realloc'ed to the needed size */
|
||||
|
||||
short int *dit_buf;
|
||||
short int *dah_buf;
|
||||
short int *inpcm;
|
||||
unsigned char *mp3buffer;
|
||||
|
||||
int inpcm_size;
|
||||
int mp3buffer_size;
|
||||
|
||||
int ditlen=0; /* number of samples in a 'dit' */
|
||||
|
||||
/* Chapters are split by this string */
|
||||
char chapterstr[80]="CHAPTER";
|
||||
char chapterfilename[80]="Chapter"; /* full filename: Chapter%02d.mp3 */
|
||||
|
||||
/* ID3-tag data: author and title */
|
||||
char id3_author[80]="CW-Book";
|
||||
char id3_title[80]="";
|
||||
char id3_comment[80]="";
|
||||
char id3_year[5]="";
|
||||
|
||||
/* const static char *codetableUTF8cyr[] = {
|
||||
".-", "-...", ".--", "--.", "-..", ".", "...-", "--..", "..",".---",
|
||||
"-.-",".-..","--","-.","---",".--.",".-.","...","-","..-","..-.",
|
||||
"....","-.-.","---.","----","--.-","-..-","-.--","-..-","..-..","..--",
|
||||
".-.-"}; */
|
||||
|
||||
/* functions */
|
||||
int init_cw (int wpm, int freq, int rt, int ft);
|
||||
void help (void);
|
||||
void makeword(char * text, int utf8);
|
||||
void closefile (int letter, int cw);
|
||||
void openfile (int chapter);
|
||||
|
||||
/* main */
|
||||
|
||||
int main (int argc, char** argv) {
|
||||
int pos, i, original_wpm;
|
||||
int utf8 = 0;
|
||||
int c;
|
||||
char word[1024]=""; /* will be cut when > 1024 chars long */
|
||||
int chapter = 0;
|
||||
int cw = 0, tw = 0, qw = 0; /* chapter words, total words, qrq words */
|
||||
|
||||
infile = stdin;
|
||||
|
||||
while((i = getopt(argc, argv, "o:w:f:R:F:s:b:q:c:a:t:k:y:Q:hu")) != -1) {
|
||||
switch (i) {
|
||||
case 'w':
|
||||
if ((wpm = atoi(optarg)) < 1) {
|
||||
fprintf(stderr, "Error: Speed (-w) must be > 0!\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
case 'f':
|
||||
freq = atoi(optarg);
|
||||
break;
|
||||
case 'R':
|
||||
rt = atoi(optarg);
|
||||
break;
|
||||
case 'F':
|
||||
ft = atoi(optarg);
|
||||
break;
|
||||
case 's':
|
||||
samplerate = atoi(optarg);
|
||||
break;
|
||||
case 'b':
|
||||
brate = atoi(optarg);
|
||||
break;
|
||||
case 'q':
|
||||
quality = atoi(optarg);
|
||||
break;
|
||||
case 'c':
|
||||
strncpy(chapterstr, optarg, 78);
|
||||
break;
|
||||
case 'o':
|
||||
strncpy(chapterfilename, optarg, 78);
|
||||
break;
|
||||
case 'a':
|
||||
strncpy(id3_author, optarg, 78);
|
||||
break;
|
||||
case 't':
|
||||
strncpy(id3_title, optarg, 75);
|
||||
break;
|
||||
case 'k':
|
||||
strncpy(id3_comment, optarg, 78);
|
||||
break;
|
||||
case 'y':
|
||||
strncpy(id3_year, optarg, 4);
|
||||
break;
|
||||
case 'Q':
|
||||
if ((qrq = atoi(optarg)) < 1) {
|
||||
fprintf(stderr, "Error: QRQ time (-Q) must be > 0!\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
case 'u':
|
||||
utf8 = 1;
|
||||
break;
|
||||
case 'h':
|
||||
default:
|
||||
help();
|
||||
} /* switch */
|
||||
} /* while */
|
||||
|
||||
if (optind < argc) { /* something left? if so, use as infile */
|
||||
if ((argv[optind][0] != '-') && (argv[optind][0] != '\0')) {
|
||||
if ((infile = fopen(argv[optind], "r")) == NULL) {
|
||||
fprintf(stderr, "Error: Cannot open file %s. Exit.\n",
|
||||
argv[optind]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf("ebook2cw %s - (c) 2008 by Fabian Kurz, DJ1YFK\n", VERSION);
|
||||
printf("Speed: %d WpM, Freq: %dHz, Chapter: >%s<, Encoding: %s\n\n",
|
||||
wpm, freq, chapterstr, utf8 ? "UTF8" : "ISO 8859-1");
|
||||
|
||||
|
||||
/* init lame */
|
||||
gfp = lame_init();
|
||||
lame_set_num_channels(gfp,1);
|
||||
lame_set_in_samplerate(gfp, samplerate);
|
||||
lame_set_brate(gfp, brate);
|
||||
lame_set_mode(gfp,1);
|
||||
lame_set_quality(gfp, quality);
|
||||
|
||||
if (lame_init_params(gfp) < 0) {
|
||||
fprintf(stderr, "Failed: lame_init_params(gfp) \n");
|
||||
return(1);
|
||||
}
|
||||
else {
|
||||
printf("Initialized lame: samplerate=%d, bitrate=%d, quality=%d\n",
|
||||
samplerate, brate, quality);
|
||||
}
|
||||
|
||||
/* init pcm_buf and mp3_buf */
|
||||
|
||||
if ((inpcm = calloc(PCMBUFFER, sizeof(short int))) == NULL) {
|
||||
fprintf(stderr, "Error: Can't allocate inpcm[%d]!\n", PCMBUFFER);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
else {
|
||||
inpcm_size = PCMBUFFER;
|
||||
}
|
||||
|
||||
if ((mp3buffer = calloc(MP3BUFFER, sizeof(unsigned char))) == NULL) {
|
||||
fprintf(stderr, "Error: Can't allocate mp3buffer[%d]!\n", MP3BUFFER);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
else {
|
||||
mp3buffer_size = MP3BUFFER;
|
||||
}
|
||||
|
||||
ditlen = init_cw(wpm, freq, rt, ft); /* generate raw dit, dah, silence */
|
||||
|
||||
strcat(chapterstr, " ");
|
||||
|
||||
/* read STDIN, assemble full words (anything ending in ' ') to 'word' and
|
||||
* generate CW, write to file by 'makeword'. words with > 1024 characters
|
||||
* will be split */
|
||||
|
||||
original_wpm = wpm; /* may be changed by QRQing */
|
||||
chapter = 0;
|
||||
openfile(chapter);
|
||||
|
||||
pos=0;
|
||||
while ((c = getc(infile)) != EOF) {
|
||||
|
||||
if (c == '\r') /* DOS linebreaks */
|
||||
continue;
|
||||
|
||||
word[pos++] = c;
|
||||
|
||||
if ((c == ' ') || (c == '\n') || (pos == 1024)) {
|
||||
word[pos] = '\0';
|
||||
if (strcmp(chapterstr, word) == 0) { /* new chapter */
|
||||
closefile(chapter, cw);
|
||||
cw=0;
|
||||
chapter++;
|
||||
|
||||
/* restore to initial speed if we're QRQing */
|
||||
if (qrq) {
|
||||
wpm = original_wpm;
|
||||
ditlen = init_cw(wpm, freq, rt, ft);
|
||||
}
|
||||
|
||||
openfile(chapter);
|
||||
}
|
||||
makeword(word, utf8);
|
||||
cw++; tw++; qw++;
|
||||
|
||||
word[0] = '\0';
|
||||
pos = 0;
|
||||
|
||||
/* every 'qrq' minutes (qrq*wpm words), speed up 1 WpM */
|
||||
if (qw == (qrq*wpm)) {
|
||||
wpm += 1;
|
||||
ditlen = init_cw(wpm, freq, rt, ft);
|
||||
qw = 0;
|
||||
}
|
||||
} /* word */
|
||||
} /* eof */
|
||||
|
||||
closefile(chapter, cw);
|
||||
|
||||
free(mp3buffer);
|
||||
free(inpcm);
|
||||
|
||||
/* factor 0.9 due to many 'words' which aren't actually words, like '\n' */
|
||||
printf("Total words: %d, total time: %d min\n", tw, (int) ((tw/wpm)*0.9));
|
||||
|
||||
lame_close(gfp);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* init_cw - generates a dit and a dah to dit_buf and dah_buf */
|
||||
|
||||
int init_cw (int wpm, int freq, int rt, int ft) {
|
||||
int x;
|
||||
int len;
|
||||
double val;
|
||||
|
||||
printf("Initializing CW buffers at %d WpM: ", wpm);
|
||||
|
||||
/* dah */
|
||||
len = (int) (3.0*6.0*samplerate/(5.0*wpm)); /* in samples */
|
||||
|
||||
/* ditlen not set == init_cw has not been called yet */
|
||||
if (!ditlen) {
|
||||
/* allocate memory for the buffer */
|
||||
if ((dah_buf = calloc(len, sizeof(short int))) == NULL) {
|
||||
fprintf(stderr, "Error: Can't allocate dah_buf[%d]\n", len);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
for (x=0; x < len; x++) {
|
||||
val = sin(2*M_PI*freq*x/samplerate);
|
||||
if (x < rt) /* shaping with sin^2 */
|
||||
val *= pow(sin(M_PI*x/(2.0*rt)),2);
|
||||
|
||||
if (x > (len-ft))
|
||||
val *= pow((sin(2*M_PI*(x-(len-ft)+ft)/(4*ft))), 2);
|
||||
|
||||
dah_buf[x] = (short int) (val * 20000.0);
|
||||
}
|
||||
|
||||
printf("dah_buf[%d], ", x);
|
||||
|
||||
/* dit */
|
||||
len = (int) (6.0*samplerate/(5.0*wpm)); /* in samples */
|
||||
|
||||
/* ditlen not set == init_cw has not been called yet */
|
||||
if (!ditlen) {
|
||||
/* allocate memory for the buffer */
|
||||
if ((dit_buf = calloc(len, sizeof(short int))) == NULL) {
|
||||
fprintf(stderr, "Error: Can't allocate dit_buf[%d]\n", len);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
for (x=0; x < len; x++) {
|
||||
val = sin(2*M_PI*freq*x/samplerate);
|
||||
if (x < rt)
|
||||
val *= pow(sin(M_PI*x/(2.0*rt)), 2);
|
||||
|
||||
if (x > (len-ft))
|
||||
val *= pow((sin(2*M_PI*(x-(len-ft)+ft)/(4*ft))), 2);
|
||||
|
||||
dit_buf[x] = (short int) (val * 20000.0);
|
||||
}
|
||||
|
||||
printf("dit_buf[%d]\n\n", x);
|
||||
|
||||
return x; /* = length of dit/silence */
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* makeword -- converts 'text' to CW by concatenating dit_buf amd dah_bufs,
|
||||
* encodes this to MP3 and writes to open filehandle outfile */
|
||||
|
||||
void makeword(char * text, int utf8) {
|
||||
const char *code; /* CW code as . and - */
|
||||
int outbytes;
|
||||
|
||||
int c;
|
||||
int i,u,w;
|
||||
int j;
|
||||
unsigned char last=0; /* for utf8 2-byte characters */
|
||||
|
||||
j = 0; /* position in 'inpcm' buffer */
|
||||
|
||||
for (i = 0; i < strlen(text); i++) {
|
||||
c = (unsigned char) text[i];
|
||||
code = NULL;
|
||||
|
||||
if (c == '\n') { /* Same for UTF8 and ISO8859 */
|
||||
if (strlen(text) == 1) /* paragraph */
|
||||
code = " -...- ";
|
||||
else
|
||||
code = " ";
|
||||
}
|
||||
else if (!utf8) { /* ISO 8859-1 */
|
||||
code = iso8859[c];
|
||||
}
|
||||
else if (utf8) { /* UTF-8 */
|
||||
/* Character may be 1-byte ASCII or 2-byte UTF8 */
|
||||
if (!(c & 128)) { /* MSB = 0 -> 7bit ASCII */
|
||||
code = iso8859[c]; /* subset of iso8859 */
|
||||
}
|
||||
else {
|
||||
if (last && (c < 192) ) { /* this is the 2nd byte */
|
||||
/* 110yyyyy 10zzzzzz -> 00000yyy yyzzzzzz */
|
||||
c = ((last & 31) << 6) | (c & 63);
|
||||
code = utf8table[c];
|
||||
last = 0;
|
||||
}
|
||||
else {
|
||||
last = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (last) continue; /* first of two-byte character read */
|
||||
|
||||
/* Not found anything ... */
|
||||
if (code == NULL) {
|
||||
code = " ";
|
||||
if (c < 255) {
|
||||
fprintf(stderr, "Warning: don't know CW for '%c'\n", c);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "Warning: don't know CW for unicode &#%d;\n", c);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* code contains letter as ./-, now assemble pcm buffer */
|
||||
|
||||
for (w = 0; w < strlen(code) ; w++) {
|
||||
|
||||
/* make sure the inpcm buffer doesn't run full,
|
||||
* with a conservative margin. reallocate memory if neccesary */
|
||||
if (j > inpcm_size-(6*ditlen)) {
|
||||
inpcm_size += (6*ditlen);
|
||||
mp3buffer_size += (8*ditlen + 7200);
|
||||
if ((inpcm = realloc(inpcm, inpcm_size*sizeof(short int)))== NULL)
|
||||
fprintf(stderr, "Error: Can't realloc inpcm[%d]\n", inpcm_size);
|
||||
|
||||
if ((mp3buffer = realloc(mp3buffer, mp3buffer_size*sizeof(char)))
|
||||
== NULL)
|
||||
fprintf(stderr, "Error: Can't realloc mp3buffer[%d]\n",
|
||||
mp3buffer_size);
|
||||
}
|
||||
|
||||
c = code[w];
|
||||
|
||||
if (c == '.')
|
||||
for (u=0; u < ditlen; u++) inpcm[++j] = dit_buf[u];
|
||||
else if (c == '-')
|
||||
for (u=0; u < (3*ditlen); u++) inpcm[++j] = dah_buf[u];
|
||||
else
|
||||
for (u=0; u < ditlen; u++) inpcm[++j] = 0;
|
||||
|
||||
for (u=0; u < ditlen; u++) inpcm[++j] = 0;
|
||||
}
|
||||
|
||||
for (u=0; u < (2*ditlen); u++) inpcm[++j] = 0; /*inter word space*/
|
||||
|
||||
} /* foreach letter */
|
||||
|
||||
/* j = total length of samples in 'inpcm' */
|
||||
|
||||
outbytes = lame_encode_buffer(gfp, inpcm, inpcm, j, mp3buffer, mp3buffer_size);
|
||||
if (outbytes < 0) {
|
||||
fprintf(stderr, "Error: lame_encode_buffer returned %d. Exit.\n", outbytes);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (fwrite(mp3buffer, sizeof(char), outbytes, outfile) != outbytes) {
|
||||
fprintf(stderr, "Error: Writing %db to file failed. Exit.\n", outbytes);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* closefile -- finishes writing the current file, flushes the encoder buffer */
|
||||
|
||||
void closefile (int letter, int cw) {
|
||||
int outbytes;
|
||||
char mp3filename[80] = "";
|
||||
|
||||
printf("words: %d, minutes: %d\n", cw, (int) ((cw/wpm)*0.9));
|
||||
|
||||
snprintf(mp3filename, 80, "%s%02d.mp3", chapterfilename, letter);
|
||||
printf("Finishing %s\n\n", mp3filename);
|
||||
|
||||
outbytes = lame_encode_flush(gfp, mp3buffer, mp3buffer_size);
|
||||
|
||||
if (outbytes < 0) {
|
||||
fprintf(stderr, "Error: lame_encode_buffer returned %d.\n", outbytes);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (fwrite(mp3buffer, sizeof(char), outbytes, outfile) != outbytes) {
|
||||
fprintf(stderr, "Error: Writing %db to file failed. Exit.\n", outbytes);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
fclose(outfile);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* openfile -- starts a new chapter by opening Chapter%d.mp3 */
|
||||
|
||||
void openfile (int chapter) {
|
||||
char mp3filename[80] = "";
|
||||
static char tmp[80] = "";
|
||||
|
||||
snprintf(mp3filename, 80, "%s%02d.mp3", chapterfilename, chapter);
|
||||
printf("Starting %s\n", mp3filename);
|
||||
|
||||
if ((outfile = fopen(mp3filename, "wb")) == NULL) {
|
||||
fprintf(stderr, "Error: Failed to open %s\n", mp3filename);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
snprintf(tmp, 79, "%s - %d", id3_title, chapter); /* generate title */
|
||||
|
||||
id3tag_init(gfp);
|
||||
id3tag_set_artist(gfp, id3_author);
|
||||
id3tag_set_year(gfp, id3_year);
|
||||
id3tag_set_title(gfp, tmp);
|
||||
id3tag_set_comment(gfp, id3_comment);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void help (void) {
|
||||
printf("ebook2cw v%s - (c) 2008 by Fabian Kurz, DJ1YFK, http://fkurz.net/\n", VERSION);
|
||||
printf("\nThis is free software, and you are welcome to redistribute it\n");
|
||||
printf("under certain conditions (see COPYING).\n");
|
||||
printf("\n");
|
||||
printf("ebook2cw [-w wpm] [-f freq] [-R risetime] [-F falltime]\n");
|
||||
printf(" [-s samplerate] [-b mp3bitrate] [-q mp3quality]\n");
|
||||
printf(" [-c chapter-separator] [-o outfile-name] [-Q minutes]\n");
|
||||
printf(" [-a author] [-t title] [-k comment] [-y year]\n");
|
||||
printf(" [-u] [infile]\n\n");
|
||||
printf("defaults: 25 WpM, 600Hz, RT=FT=50, s=11025Hz, b=16kbps,\n");
|
||||
printf(" c=\"CHAPTER\", o=\"Chapter\" infile = stdin\n");
|
||||
printf("\n");
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
Binary file not shown.
|
|
@ -0,0 +1,280 @@
|
|||
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
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
0.6.1 / 2008-02-09 Fabian Kurz <mail@fkurz.net>
|
||||
* Added more Cyrillic characters, the Greek and the Hebrew
|
||||
alphabet to the Unicode table. Some small corrections to
|
||||
the existing characters.
|
||||
* Command line switch -S with option either ISO or UTF prints
|
||||
a table of the available character set and the CW symbols
|
||||
in HTML format.
|
||||
|
||||
0.6.0 / 2008-02-05 Fabian Kurz <mail@fkurz.net>
|
||||
* Full ISO 8859-1 character set is now available
|
||||
* UTF-8 support by command line switch -u. Currently
|
||||
implemented: Latin, basic cyrillic.
|
||||
|
||||
0.5.1 / 2008-01-08 Fabian Kurz <mail@fkurz.net>
|
||||
* Fixed ID3 title (chapter number) generation.
|
||||
|
||||
0.5.0 / 2007-12-19 Fabian Kurz <mail@fkurz.net>
|
||||
* Added support for writing ID3 tags.
|
||||
* Added -Q command line switch: QRQ by 1 WpM every n minutes.
|
||||
|
||||
0.4.0 / 2007-12-17 Fabian Kurz <mail@fkurz.net>
|
||||
* Implemented dynamic memory allocation.
|
||||
|
||||
0.3.0 / 2007-11-28 Fabian Kurz <mail@fkurz.net>
|
||||
* Added forgotten characters: @ and /.
|
||||
|
||||
0.2.0 / 2007-11-27 Fabian Kurz <mail@fkurz.net>
|
||||
|
||||
* Fixed handling of umlauts (öäüß)
|
||||
* The chapter separator is now case sensitive.
|
||||
|
||||
0.1.0 / 2007-11-22 Fabian Kurz <mail@fkurz.net>
|
||||
|
||||
* Initial release of ebook2cw.
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
# ebook2cw Makefile -- Fabian Kurz, DJ1YFK -- http://fkurz.net/ham/ebook2cw.html
|
||||
|
||||
VERSION=0.6.1
|
||||
DESTDIR ?= /usr
|
||||
|
||||
all: ebook2cw
|
||||
|
||||
ebook2cw: ebook2cw.c
|
||||
gcc ebook2cw.c -pedantic -Wall -lm -lmp3lame -D VERSION=\"$(VERSION)\" -o ebook2cw
|
||||
|
||||
static:
|
||||
gcc -static ebook2cw.c -lmp3lame -lm -D VERSION=\"$(VERSION)\" -o ebook2cw
|
||||
|
||||
install:
|
||||
install -d -v $(DESTDIR)/share/man/man1/
|
||||
install -d -v $(DESTDIR)/bin/
|
||||
install -s -m 0755 ebook2cw $(DESTDIR)/bin/
|
||||
install -m 0644 ebook2cw.1 $(DESTDIR)/share/man/man1/
|
||||
|
||||
uninstall:
|
||||
rm -f $(DESTDIR)/bin/ebook2cw
|
||||
rm -f $(DESTDIR)/share/man/man1/ebook2cw.1
|
||||
|
||||
clean:
|
||||
rm -f ebook2cw *~ *.mp3
|
||||
|
||||
dist:
|
||||
sed 's/v[0-9].[0-9].[0-9]/v$(VERSION)/g' README > README2
|
||||
rm -f README
|
||||
mv README2 README
|
||||
rm -f releases/ebook2cw-$(VERSION).tar.gz
|
||||
rm -rf releases/ebook2cw-$(VERSION)
|
||||
mkdir ebook2cw-$(VERSION)
|
||||
cp ebook2cw.c codetables.h ChangeLog ebook2cw.1 \
|
||||
COPYING Makefile ebook2cw-$(VERSION)
|
||||
tar -zcf ebook2cw-$(VERSION).tar.gz ebook2cw-$(VERSION)
|
||||
mv ebook2cw-$(VERSION) releases/
|
||||
mv ebook2cw-$(VERSION).tar.gz releases/
|
||||
md5sum releases/*.gz > releases/md5sums.txt
|
||||
chmod a+r releases/*
|
||||
|
||||
|
|
@ -0,0 +1,543 @@
|
|||
/*
|
||||
* ISO 8859-1 and UTF-8 to Morse code mappings
|
||||
* This file is part of ebook2cw and may be used under the same terms (GPL)
|
||||
* (C) 2008 Fabian Kurz, DJ1YFK
|
||||
*
|
||||
* Currently included: ISO 8859-1
|
||||
* - complete (all that can somehow be mapped)
|
||||
* Unicode:
|
||||
* - Latin (basic, some extended)
|
||||
* - Cyrillic alphabet (KOI-7 + Serbian, Macedonian.. )
|
||||
* - Greek
|
||||
* - Hebrew
|
||||
*
|
||||
* Any comments, additions or corrections are welcome: mail@fkurz.net
|
||||
*
|
||||
*/
|
||||
|
||||
const static char *iso8859[] = {
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
" ", /* space */
|
||||
"..--.", /* ! */
|
||||
".-..-.", /* " */
|
||||
NULL, /* # */
|
||||
"...-..-", /* $ */
|
||||
NULL, /* % */
|
||||
". ...", /* & */
|
||||
".----.", /* ' */
|
||||
"-.--.", /* ( */
|
||||
"-.--.-", /* ) */
|
||||
NULL, /* * */
|
||||
".-.-.", /* + */
|
||||
"--..--", /* , */
|
||||
"-....-", /* - */
|
||||
".-.-.-", /* . */
|
||||
"-..-.", /* / */
|
||||
"-----", /* 0 */
|
||||
".----", /* 1 */
|
||||
"..---", /* 2 */
|
||||
"...--", /* 3 */
|
||||
"....-", /* 4 */
|
||||
".....", /* 5 */
|
||||
"-....", /* 6 */
|
||||
"--...", /* 7 */
|
||||
"---..", /* 8 */
|
||||
"----.", /* 9 */
|
||||
"---...", /* : */
|
||||
"-.-.-.", /* ; */
|
||||
NULL, /* < */
|
||||
"-...-", /* = */
|
||||
NULL, /* < */
|
||||
"..--..", /* ? */
|
||||
".--.-.", /* @ */
|
||||
".-", /* A */
|
||||
"-...", /* B */
|
||||
"-.-.",
|
||||
"-..",
|
||||
".",
|
||||
"..-.",
|
||||
"--.",
|
||||
"....",
|
||||
"..",
|
||||
".---",
|
||||
"-.-",
|
||||
".-..",
|
||||
"--",
|
||||
"-.",
|
||||
"---",
|
||||
".--.",
|
||||
"--.-",
|
||||
".-.",
|
||||
"...",
|
||||
"-",
|
||||
"..-",
|
||||
"...-",
|
||||
".--",
|
||||
"-..-",
|
||||
"-.--",
|
||||
"--..", /* Z */
|
||||
NULL, /* [ */
|
||||
"-..-.", /* \ */
|
||||
NULL, /* ] */
|
||||
NULL, /* ^ */
|
||||
NULL, /* _ */
|
||||
".----.", /* ` */
|
||||
".-", /* a */
|
||||
"-...", /* b */
|
||||
"-.-.",
|
||||
"-..",
|
||||
".",
|
||||
"..-.",
|
||||
"--.",
|
||||
"....",
|
||||
"..",
|
||||
".---",
|
||||
"-.-",
|
||||
".-..",
|
||||
"--",
|
||||
"-.",
|
||||
"---",
|
||||
".--.",
|
||||
"--.-",
|
||||
".-.",
|
||||
"...",
|
||||
"-",
|
||||
"..-",
|
||||
"...-",
|
||||
".--",
|
||||
"-..-",
|
||||
"-.--",
|
||||
"--..", /* z */
|
||||
NULL, /* { */
|
||||
NULL, /* | */
|
||||
NULL, /* } */
|
||||
NULL, /* ~ */
|
||||
NULL, /* DEL */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL,
|
||||
".-..-.", /* « (angle quotes, <<, 171) */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
".-..-.", /* » (angle quotes, >>, 187) */
|
||||
NULL, NULL, NULL, NULL,
|
||||
".--.-", /* `A */
|
||||
".--.-", /* 'A */
|
||||
".-", /* ^A */
|
||||
".-", /* ~A */
|
||||
".-.-", /* "A */
|
||||
".--.-", /* °A */
|
||||
".- .", /* AE */
|
||||
"-.-..", /* ,C */
|
||||
"..-..", /* `E */
|
||||
"..-..", /* 'E */
|
||||
".", /* ^E */
|
||||
".", /* "E */
|
||||
"..", /* `I */
|
||||
"..", /* 'I */
|
||||
"..", /* ^I */
|
||||
"..", /* "I */
|
||||
"..--.", /* -D */
|
||||
"--.--", /* ~N */
|
||||
"---", /* `O */
|
||||
"---", /* 'O */
|
||||
"---", /* ^O */
|
||||
"---", /* ~O */
|
||||
"---.", /* "O */
|
||||
NULL, /* x */
|
||||
"---.", /* /O */
|
||||
"..-", /* `U */
|
||||
"..-", /* 'U */
|
||||
"..-", /* ^U */
|
||||
"..--", /* "U */
|
||||
"-.--", /* 'Y */
|
||||
".--..", /* 'thorn' */
|
||||
"...--..", /* sz */
|
||||
".--.-", /* `a */
|
||||
".--.-", /* 'a */
|
||||
".-", /* ^a */
|
||||
".-", /* ~a */
|
||||
".-.-", /* "a */
|
||||
".--.-", /* °a */
|
||||
".- .", /* ae */
|
||||
"-.-..", /* ,c */
|
||||
"..-..", /* `e */
|
||||
"..-..", /* 'e */
|
||||
".", /* ^e */
|
||||
".", /* "e */
|
||||
"..", /* `i */
|
||||
"..", /* 'i */
|
||||
"..", /* ^i */
|
||||
"..", /* "i */
|
||||
"..--.", /* -d */
|
||||
"--.--", /* ~n */
|
||||
"---", /* `o */
|
||||
"---", /* 'o */
|
||||
"---", /* ^o */
|
||||
"---", /* ~o */
|
||||
"---.", /* "o */
|
||||
NULL, /* ./. */
|
||||
"---.", /* /o */
|
||||
"..-", /* `u */
|
||||
"..-", /* 'u */
|
||||
"..-", /* ^u */
|
||||
"..--", /* "u */
|
||||
"-.--", /* 'y */
|
||||
".--..", /* 'thorn' */
|
||||
"-.--" /* "y */
|
||||
};
|
||||
|
||||
const static char *utf8table[] = {
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* first 128 are identical*/
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* to iso8859, so that */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* will be used instead */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* - 127 */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* control characters ...*/
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* -159 */
|
||||
" ", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, ".-..-.", NULL, NULL, NULL, NULL, /* 171 << */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, ".-..-.", NULL, NULL, NULL, NULL, /* 187 >> */
|
||||
/* same as in ISO8859 */
|
||||
".--.-", /* `A */ /* 192 ... */
|
||||
".--.-", /* 'A */
|
||||
".-", /* ^A */
|
||||
".-", /* ~A */
|
||||
".-.-", /* "A */
|
||||
".--.-", /* °A */
|
||||
".- .", /* AE */
|
||||
"-.-..", /* ,C */
|
||||
"..-..", /* `E */
|
||||
"..-..", /* 'E */
|
||||
".", /* ^E */
|
||||
".", /* "E */
|
||||
"..", /* `I */
|
||||
"..", /* 'I */
|
||||
"..", /* ^I */
|
||||
"..", /* "I */
|
||||
"..--.", /* -D according to Wikipedia */
|
||||
"--.--", /* ~N */
|
||||
"---", /* `O */
|
||||
"---", /* 'O */
|
||||
"---", /* ^O */
|
||||
"---", /* ~O */
|
||||
"---.", /* "O */
|
||||
NULL, /* x */
|
||||
"---.", /* /O */
|
||||
"..-", /* `U */
|
||||
"..-", /* 'U */
|
||||
"..-", /* ^U */
|
||||
"..--", /* "U */
|
||||
"-.--", /* 'Y */
|
||||
".--..", /* 'thorn', acc to Wikipedia */
|
||||
"...--..", /* sz */
|
||||
".--.-", /* `a */
|
||||
".--.-", /* 'a */
|
||||
".-", /* ^a */
|
||||
".-", /* ~a */
|
||||
".-.-", /* "a */
|
||||
".--.-", /* °a */
|
||||
".- .", /* ae */
|
||||
"-.-..", /* ,c */
|
||||
"..-..", /* `e */
|
||||
"..-..", /* 'e */
|
||||
".", /* ^e */
|
||||
".", /* "e */
|
||||
"..", /* `i */
|
||||
"..", /* 'i */
|
||||
"..", /* ^i */
|
||||
"..", /* "i */
|
||||
"..--.", /* -d Wiki */
|
||||
"--.--", /* ~n */
|
||||
"---", /* `o */
|
||||
"---", /* 'o */
|
||||
"---", /* ^o */
|
||||
"---", /* ~o */
|
||||
"---.", /* "o */
|
||||
NULL, /* ./. */
|
||||
"---.", /* /o */
|
||||
"..-", /* `u */
|
||||
"..-", /* 'u */
|
||||
"..-", /* ^u */
|
||||
"..--", /* "u */
|
||||
"-.--", /* 'y */
|
||||
".--..", /* 'thorn' */
|
||||
"-.--", /* "y */ /* 255 */
|
||||
".-", ".-", ".-", ".-", ".-", ".-", /* 256-261, As with different hats */
|
||||
/* 262-269 Cs with different hats */
|
||||
/* 264-265 -.-.. acc. to Wikipedia */
|
||||
"-.-.", "-.-.", "-.-..", "-.-..", "-.-.", "-.-.", "-.-.", "-.-.",
|
||||
"-..", "-..", "-..", "-..", /* 270-273 Ds with different stuff */
|
||||
/* 274-283 different Es */
|
||||
".", ".", ".", ".", ".", ".", ".", ".", ".", ".",
|
||||
/* 284-291 different Gs, first 2 according to Wikipedia */
|
||||
"--.-.", "--.-.", "--.", "--.", "--.", "--.", "--.", "--.",
|
||||
/* 292-295 different Hs, ditto */
|
||||
"-.--.", "-.--.", "....", "....",
|
||||
/* 296-305 different Is */
|
||||
"..", "..", "..", "..", "..", "..", "..", "..", "..", "..",
|
||||
/* 306-307 IJ ligatures */
|
||||
".. .---", ".. .---",
|
||||
/* 308-309 Js, from Wikipedia */
|
||||
".---.", ".---.",
|
||||
/* 310-312 Ks */
|
||||
"-.-", "-.-", "-.-",
|
||||
/* 313-322 different Ls */
|
||||
".-..", ".-..", ".-..", ".-..", ".-..", ".-..", ".-..",
|
||||
".-..", ".-..", ".-..",
|
||||
/* 323-331 different Ns */
|
||||
"-.", "-.", "-.", "-.", "-.", "-.", "-.", "-.", "-.",
|
||||
/* 332-337 Os */
|
||||
"---", "---", "---", "---", "---", "---",
|
||||
/* 338-339 OEs */
|
||||
"---.", "---.",
|
||||
/* 340-345 Rs */
|
||||
".-.", ".-.", ".-.", ".-.", ".-.", ".-.",
|
||||
/* 346-353 Ss, Wikipedia */
|
||||
"...", "...", "...-.", "...-.", "...", "...", "...", "...",
|
||||
/* 354-359 Ts */
|
||||
"-", "-", "-", "-", "-", "-",
|
||||
/* 360-371 Us */
|
||||
"..-", "..-", "..-", "..-", "..-", "..-", "..-", "..-", "..-",
|
||||
"..-", "..-", "..-",
|
||||
/* 372-373 Ws */
|
||||
".--", ".--",
|
||||
/* 374-377 Ys */
|
||||
"-.--", "-.--", "-.--",
|
||||
/* 377-382 Zs */
|
||||
"--..", "--..", "--..", "--..", "--..", "--..",
|
||||
/* 383 S */
|
||||
"...",
|
||||
/* 384-389 Bs */
|
||||
"-...", "-...", "-...", "-...", "-...", "-...",
|
||||
NULL, NULL, NULL, /* all kind of weird stuff */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL,
|
||||
/* Standard Greek Alphabet */
|
||||
".-", "-..." , "--.", "-..", ".", "--..", "....",
|
||||
"-.-.", "..", "-.-", ".-..", "--", "-.", "-..-", "---",
|
||||
".--.", ".-.", NULL, "...", "-", "-.--", "..-.", "----",
|
||||
"--.-", ".--", NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 1023 */
|
||||
|
||||
/* 1024-1039, cyrillic (Serbian, Macedonian, Ukrainian) UC */
|
||||
".", ".", "-.. .---", "--. .---", ".", "-.. --..", "..", "..",
|
||||
".---", ".-.. .---", "-. .---", "-.-.", "-.- .---", "..", "..-","-.. --..",
|
||||
|
||||
/* 32 letters of Russian Cyrillic alphabet */
|
||||
".-", "-...", ".--", "--.", "-..", ".", "...-", /* 1040-1071 */
|
||||
"--..", "..",".---", "-.-", ".-..", "--", "-.", /* uppercase */
|
||||
"---", ".--.", ".-.", "...", "-", "..-", "..-.", /* cyrillic */
|
||||
"....", "-.-.", "---.", "----", "--.-", "-..-",
|
||||
"-.--", "-..-", "..-..", "..--", ".-.-",
|
||||
".-", "-...", ".--", "--.", "-..", ".", "...-", /* 1072-1103 */
|
||||
"--..", "..",".---", "-.-", ".-..", "--", "-.", /* lowercase */
|
||||
"---", ".--.", ".-.", "...", "-", "..-", "..-.", /* cyrillic */
|
||||
"....", "-.-.", "---.", "----", "--.-", "-..-",
|
||||
"-.--", "-..-", "..-..", "..--", ".-.-",
|
||||
|
||||
/* 1004-1119, cyrillic (Serbian, Macedonian, Ukrainian) UC */
|
||||
".", ".", "-.. .---", "--. .---", ".", "-.. --..", "..", "..",
|
||||
".---", ".-.. .---", "-. .---", "-.-.", "-.- .---", "..", "..-","-.. --..",
|
||||
|
||||
/* 1120 - 1487 to be done... */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/* 1488-1514 Hebrew according to Wikipedia */
|
||||
".-", "-...", "--.", "-..", "---", ".", "--..", "....",
|
||||
"..-", "..", NULL, "-.-", ".-..", NULL, "--", "-.", NULL,
|
||||
"-.-.", ".---", NULL, ".--.", NULL, ".--", "--.-", ".-.", "...",
|
||||
"-", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL /* 1920 */
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
.TH ebook2cw 1 "JUNE 2007" Linux "User Manuals"
|
||||
.SH NAME
|
||||
ebook2cw \- convert ebooks to morse mp3s
|
||||
.SH SYNOPSIS
|
||||
.B ebook2cw
|
||||
[OPTIONS]
|
||||
.SH DESCRIPTION
|
||||
.B ebook2cw
|
||||
ebook2cw is a command line program which converts a plain text ebook to morse
|
||||
code MP3 files. It works on several platforms, including Windows and Linux.
|
||||
|
||||
A number of CW and MP3 parameters can be changed from their default values, by
|
||||
command line switches. These are (default values in brackets):
|
||||
|
||||
.B -w wpm
|
||||
- CW speed in words per minute [25]
|
||||
|
||||
.B -f freq
|
||||
- audio frequency in Hz [600]
|
||||
|
||||
.B -Q minutes
|
||||
- Increase CW speed (QRQ) by 1 WpM in intervals of `minutes'. Speed will be
|
||||
reset to the initial value at the start of each chapter. [0]
|
||||
|
||||
.B -R risetime
|
||||
- risetime, in samples [50]
|
||||
|
||||
.B -F falltime
|
||||
- falltime, samples [50]
|
||||
|
||||
.B -s samplerate
|
||||
- samplerate for the MP3 file [11025]
|
||||
|
||||
.B -b bitrate
|
||||
- MP3 bitrate, kbps [16]
|
||||
|
||||
.B -q quality
|
||||
- MP3 quality, 1 (best) to 9 (worst). CW still sounds very good with the worst quality, encoding time is greatly reduced. [9]
|
||||
|
||||
.B -c chapter separator
|
||||
- Split chapters at this string. Must be pure ASCII if UTF-8 is used. [CHAPTER]
|
||||
|
||||
.B -o outfile-name
|
||||
- Output filename (chapter number and .mp3 will be appended) [Chapter]
|
||||
|
||||
.B -a author
|
||||
- Author for the ID3 tag. Use quotes for strings with spaces (e.g. "JW Goethe")
|
||||
|
||||
.B -t title
|
||||
- Title for the ID3 tag. Use quotes for strings with spaces (e.g. "Faust II")
|
||||
|
||||
.B -k comment
|
||||
- Comment for the ID3 tag. Use quotes for strings with spaces.
|
||||
|
||||
.B -y year
|
||||
- Year for the ID3 tag.
|
||||
|
||||
.B -u
|
||||
- Switches input encoding format to UTF-8. Currentply supported alphabets include Latin, Greek, Hebrew and Cyrillic. Default is ISO 8859-1.
|
||||
|
||||
.B -S [ISO|UTF]
|
||||
- Shows a table of all available morse symbols for the ISO 8859-1 and UTF-8
|
||||
character sets. Output in HTML format.
|
||||
|
||||
.SH AUTHOR
|
||||
Fabian Kurz, DJ1YFK <mail@fkurz.net>
|
||||
|
||||
http://fkurz.net/ham/ebook2cw.html
|
||||
.SH "SEE ALSO"
|
||||
.BR morse (1)
|
||||
|
|
@ -0,0 +1,573 @@
|
|||
/*
|
||||
ebook2cw - converts an ebook to morse mp3s
|
||||
|
||||
Copyright (C) 2008 Fabian Kurz, DJ1YFK
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 2 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
|
||||
Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
source code looks properly indented with tw=4
|
||||
|
||||
*/
|
||||
|
||||
#include "lame/lame.h"
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "codetables.h"
|
||||
|
||||
#ifndef VERSION
|
||||
#define VERSION "0.0.0"
|
||||
#endif
|
||||
|
||||
#define PCMBUFFER 220500 /* 20 seconds at 11kHz, for one word. plenty. */
|
||||
#define MP3BUFFER 285000 /* abt 1.25*PCMBUFFER + 7200, as recommended */
|
||||
|
||||
lame_global_flags *gfp;
|
||||
|
||||
FILE *outfile;
|
||||
FILE *infile;
|
||||
|
||||
/* MP3 samplerate, bitrate, quality. */
|
||||
int samplerate = 11025;
|
||||
int brate = 16;
|
||||
int quality = 5;
|
||||
|
||||
/* CW parameters */
|
||||
int wpm = 25;
|
||||
int freq = 600;
|
||||
int rt = 50; /* rise/fall time in samples */
|
||||
int ft = 50;
|
||||
int qrq = 0; /* rise speed by 1 WpM every qrq minutes */
|
||||
|
||||
/* the buffers for dit, dah, raw pcm and mp3 output, will me calloc'ed to the
|
||||
* default values, and if needed realloc'ed to the needed size */
|
||||
|
||||
short int *dit_buf;
|
||||
short int *dah_buf;
|
||||
short int *inpcm;
|
||||
unsigned char *mp3buffer;
|
||||
|
||||
int inpcm_size;
|
||||
int mp3buffer_size;
|
||||
|
||||
int ditlen=0; /* number of samples in a 'dit' */
|
||||
|
||||
/* Chapters are split by this string */
|
||||
char chapterstr[80]="CHAPTER";
|
||||
char chapterfilename[80]="Chapter"; /* full filename: Chapter%02d.mp3 */
|
||||
|
||||
/* ID3-tag data: author and title */
|
||||
char id3_author[80]="CW-Book";
|
||||
char id3_title[80]="";
|
||||
char id3_comment[80]="";
|
||||
char id3_year[5]="";
|
||||
|
||||
/* const static char *codetableUTF8cyr[] = {
|
||||
".-", "-...", ".--", "--.", "-..", ".", "...-", "--..", "..",".---",
|
||||
"-.-",".-..","--","-.","---",".--.",".-.","...","-","..-","..-.",
|
||||
"....","-.-.","---.","----","--.-","-..-","-.--","-..-","..-..","..--",
|
||||
".-.-"}; */
|
||||
|
||||
/* functions */
|
||||
int init_cw (int wpm, int freq, int rt, int ft);
|
||||
void help (void);
|
||||
void showcodes (int i);
|
||||
void makeword(char * text, int utf8);
|
||||
void closefile (int letter, int cw);
|
||||
void openfile (int chapter);
|
||||
|
||||
/* main */
|
||||
|
||||
int main (int argc, char** argv) {
|
||||
int pos, i, original_wpm;
|
||||
int utf8 = 0;
|
||||
int c;
|
||||
char word[1024]=""; /* will be cut when > 1024 chars long */
|
||||
int chapter = 0;
|
||||
int cw = 0, tw = 0, qw = 0; /* chapter words, total words, qrq words */
|
||||
|
||||
infile = stdin;
|
||||
|
||||
while((i = getopt(argc, argv, "o:w:f:R:F:s:b:q:c:a:t:k:y:Q:S:hu")) != -1) {
|
||||
switch (i) {
|
||||
case 'w':
|
||||
if ((wpm = atoi(optarg)) < 1) {
|
||||
fprintf(stderr, "Error: Speed (-w) must be > 0!\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
case 'f':
|
||||
freq = atoi(optarg);
|
||||
break;
|
||||
case 'R':
|
||||
rt = atoi(optarg);
|
||||
break;
|
||||
case 'F':
|
||||
ft = atoi(optarg);
|
||||
break;
|
||||
case 's':
|
||||
samplerate = atoi(optarg);
|
||||
break;
|
||||
case 'b':
|
||||
brate = atoi(optarg);
|
||||
break;
|
||||
case 'q':
|
||||
quality = atoi(optarg);
|
||||
break;
|
||||
case 'c':
|
||||
strncpy(chapterstr, optarg, 78);
|
||||
break;
|
||||
case 'o':
|
||||
strncpy(chapterfilename, optarg, 78);
|
||||
break;
|
||||
case 'a':
|
||||
strncpy(id3_author, optarg, 78);
|
||||
break;
|
||||
case 't':
|
||||
strncpy(id3_title, optarg, 75);
|
||||
break;
|
||||
case 'k':
|
||||
strncpy(id3_comment, optarg, 78);
|
||||
break;
|
||||
case 'y':
|
||||
strncpy(id3_year, optarg, 4);
|
||||
break;
|
||||
case 'Q':
|
||||
if ((qrq = atoi(optarg)) < 1) {
|
||||
fprintf(stderr, "Error: QRQ time (-Q) must be > 0!\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
case 'u':
|
||||
utf8 = 1;
|
||||
break;
|
||||
case 'S':
|
||||
if (strstr(optarg, "ISO")) {
|
||||
showcodes(1);
|
||||
}
|
||||
else {
|
||||
showcodes(0);
|
||||
}
|
||||
case 'h':
|
||||
default:
|
||||
help();
|
||||
} /* switch */
|
||||
} /* while */
|
||||
|
||||
if (optind < argc) { /* something left? if so, use as infile */
|
||||
if ((argv[optind][0] != '-') && (argv[optind][0] != '\0')) {
|
||||
if ((infile = fopen(argv[optind], "r")) == NULL) {
|
||||
fprintf(stderr, "Error: Cannot open file %s. Exit.\n",
|
||||
argv[optind]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf("ebook2cw %s - (c) 2008 by Fabian Kurz, DJ1YFK\n", VERSION);
|
||||
printf("Speed: %d WpM, Freq: %dHz, Chapter: >%s<, Encoding: %s\n\n",
|
||||
wpm, freq, chapterstr, utf8 ? "UTF-8" : "ISO 8859-1");
|
||||
|
||||
|
||||
/* init lame */
|
||||
gfp = lame_init();
|
||||
lame_set_num_channels(gfp,1);
|
||||
lame_set_in_samplerate(gfp, samplerate);
|
||||
lame_set_brate(gfp, brate);
|
||||
lame_set_mode(gfp,1);
|
||||
lame_set_quality(gfp, quality);
|
||||
|
||||
if (lame_init_params(gfp) < 0) {
|
||||
fprintf(stderr, "Failed: lame_init_params(gfp) \n");
|
||||
return(1);
|
||||
}
|
||||
else {
|
||||
printf("Initialized lame: samplerate=%d, bitrate=%d, quality=%d\n",
|
||||
samplerate, brate, quality);
|
||||
}
|
||||
|
||||
/* init pcm_buf and mp3_buf */
|
||||
|
||||
if ((inpcm = calloc(PCMBUFFER, sizeof(short int))) == NULL) {
|
||||
fprintf(stderr, "Error: Can't allocate inpcm[%d]!\n", PCMBUFFER);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
else {
|
||||
inpcm_size = PCMBUFFER;
|
||||
}
|
||||
|
||||
if ((mp3buffer = calloc(MP3BUFFER, sizeof(unsigned char))) == NULL) {
|
||||
fprintf(stderr, "Error: Can't allocate mp3buffer[%d]!\n", MP3BUFFER);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
else {
|
||||
mp3buffer_size = MP3BUFFER;
|
||||
}
|
||||
|
||||
ditlen = init_cw(wpm, freq, rt, ft); /* generate raw dit, dah, silence */
|
||||
|
||||
strcat(chapterstr, " ");
|
||||
|
||||
/* read STDIN, assemble full words (anything ending in ' ') to 'word' and
|
||||
* generate CW, write to file by 'makeword'. words with > 1024 characters
|
||||
* will be split */
|
||||
|
||||
original_wpm = wpm; /* may be changed by QRQing */
|
||||
chapter = 0;
|
||||
openfile(chapter);
|
||||
|
||||
pos=0;
|
||||
while ((c = getc(infile)) != EOF) {
|
||||
|
||||
if (c == '\r') /* DOS linebreaks */
|
||||
continue;
|
||||
|
||||
word[pos++] = c;
|
||||
|
||||
if ((c == ' ') || (c == '\n') || (pos == 1024)) {
|
||||
word[pos] = '\0';
|
||||
if (strcmp(chapterstr, word) == 0) { /* new chapter */
|
||||
closefile(chapter, cw);
|
||||
cw=0;
|
||||
chapter++;
|
||||
|
||||
/* restore to initial speed if we're QRQing */
|
||||
if (qrq) {
|
||||
wpm = original_wpm;
|
||||
ditlen = init_cw(wpm, freq, rt, ft);
|
||||
}
|
||||
|
||||
openfile(chapter);
|
||||
}
|
||||
makeword(word, utf8);
|
||||
cw++; tw++; qw++;
|
||||
|
||||
word[0] = '\0';
|
||||
pos = 0;
|
||||
|
||||
/* every 'qrq' minutes (qrq*wpm words), speed up 1 WpM */
|
||||
if (qw == (qrq*wpm)) {
|
||||
wpm += 1;
|
||||
ditlen = init_cw(wpm, freq, rt, ft);
|
||||
qw = 0;
|
||||
}
|
||||
} /* word */
|
||||
} /* eof */
|
||||
|
||||
closefile(chapter, cw);
|
||||
|
||||
free(mp3buffer);
|
||||
free(inpcm);
|
||||
|
||||
/* factor 0.9 due to many 'words' which aren't actually words, like '\n' */
|
||||
printf("Total words: %d, total time: %d min\n", tw, (int) ((tw/wpm)*0.9));
|
||||
|
||||
lame_close(gfp);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* init_cw - generates a dit and a dah to dit_buf and dah_buf */
|
||||
|
||||
int init_cw (int wpm, int freq, int rt, int ft) {
|
||||
int x;
|
||||
int len;
|
||||
double val;
|
||||
|
||||
printf("Initializing CW buffers at %d WpM: ", wpm);
|
||||
|
||||
/* dah */
|
||||
len = (int) (3.0*6.0*samplerate/(5.0*wpm)); /* in samples */
|
||||
|
||||
/* ditlen not set == init_cw has not been called yet */
|
||||
if (!ditlen) {
|
||||
/* allocate memory for the buffer */
|
||||
if ((dah_buf = calloc(len, sizeof(short int))) == NULL) {
|
||||
fprintf(stderr, "Error: Can't allocate dah_buf[%d]\n", len);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
for (x=0; x < len; x++) {
|
||||
val = sin(2*M_PI*freq*x/samplerate);
|
||||
if (x < rt) /* shaping with sin^2 */
|
||||
val *= pow(sin(M_PI*x/(2.0*rt)),2);
|
||||
|
||||
if (x > (len-ft))
|
||||
val *= pow((sin(2*M_PI*(x-(len-ft)+ft)/(4*ft))), 2);
|
||||
|
||||
dah_buf[x] = (short int) (val * 20000.0);
|
||||
}
|
||||
|
||||
printf("dah_buf[%d], ", x);
|
||||
|
||||
/* dit */
|
||||
len = (int) (6.0*samplerate/(5.0*wpm)); /* in samples */
|
||||
|
||||
/* ditlen not set == init_cw has not been called yet */
|
||||
if (!ditlen) {
|
||||
/* allocate memory for the buffer */
|
||||
if ((dit_buf = calloc(len, sizeof(short int))) == NULL) {
|
||||
fprintf(stderr, "Error: Can't allocate dit_buf[%d]\n", len);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
for (x=0; x < len; x++) {
|
||||
val = sin(2*M_PI*freq*x/samplerate);
|
||||
if (x < rt)
|
||||
val *= pow(sin(M_PI*x/(2.0*rt)), 2);
|
||||
|
||||
if (x > (len-ft))
|
||||
val *= pow((sin(2*M_PI*(x-(len-ft)+ft)/(4*ft))), 2);
|
||||
|
||||
dit_buf[x] = (short int) (val * 20000.0);
|
||||
}
|
||||
|
||||
printf("dit_buf[%d]\n\n", x);
|
||||
|
||||
return x; /* = length of dit/silence */
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* makeword -- converts 'text' to CW by concatenating dit_buf amd dah_bufs,
|
||||
* encodes this to MP3 and writes to open filehandle outfile */
|
||||
|
||||
void makeword(char * text, int utf8) {
|
||||
const char *code; /* CW code as . and - */
|
||||
int outbytes;
|
||||
|
||||
int c;
|
||||
int i,u,w;
|
||||
int j;
|
||||
unsigned char last=0; /* for utf8 2-byte characters */
|
||||
|
||||
j = 0; /* position in 'inpcm' buffer */
|
||||
|
||||
for (i = 0; i < strlen(text); i++) {
|
||||
c = (unsigned char) text[i];
|
||||
code = NULL;
|
||||
|
||||
if (c == '\n') { /* Same for UTF8 and ISO8859 */
|
||||
if (strlen(text) == 1) /* paragraph */
|
||||
code = " -...- ";
|
||||
else
|
||||
code = " ";
|
||||
}
|
||||
else if (!utf8) { /* ISO 8859-1 */
|
||||
code = iso8859[c];
|
||||
}
|
||||
else if (utf8) { /* UTF-8 */
|
||||
/* Character may be 1-byte ASCII or 2-byte UTF8 */
|
||||
if (!(c & 128)) { /* MSB = 0 -> 7bit ASCII */
|
||||
code = iso8859[c]; /* subset of iso8859 */
|
||||
}
|
||||
else {
|
||||
if (last && (c < 192) ) { /* this is the 2nd byte */
|
||||
/* 110yyyyy 10zzzzzz -> 00000yyy yyzzzzzz */
|
||||
c = ((last & 31) << 6) | (c & 63);
|
||||
code = utf8table[c];
|
||||
last = 0;
|
||||
}
|
||||
else {
|
||||
last = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (last) continue; /* first of two-byte character read */
|
||||
|
||||
/* Not found anything ... */
|
||||
if (code == NULL) {
|
||||
code = " ";
|
||||
if (c < 255) {
|
||||
fprintf(stderr, "Warning: don't know CW for '%c'\n", c);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "Warning: don't know CW for unicode &#%d;\n", c);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* code contains letter as ./-, now assemble pcm buffer */
|
||||
|
||||
for (w = 0; w < strlen(code) ; w++) {
|
||||
|
||||
/* make sure the inpcm buffer doesn't run full,
|
||||
* with a conservative margin. reallocate memory if neccesary */
|
||||
if (j > inpcm_size-(6*ditlen)) {
|
||||
inpcm_size += (6*ditlen);
|
||||
mp3buffer_size += (8*ditlen + 7200);
|
||||
if ((inpcm = realloc(inpcm, inpcm_size*sizeof(short int)))== NULL)
|
||||
fprintf(stderr, "Error: Can't realloc inpcm[%d]\n", inpcm_size);
|
||||
|
||||
if ((mp3buffer = realloc(mp3buffer, mp3buffer_size*sizeof(char)))
|
||||
== NULL)
|
||||
fprintf(stderr, "Error: Can't realloc mp3buffer[%d]\n",
|
||||
mp3buffer_size);
|
||||
}
|
||||
|
||||
c = code[w];
|
||||
|
||||
if (c == '.')
|
||||
for (u=0; u < ditlen; u++) inpcm[++j] = dit_buf[u];
|
||||
else if (c == '-')
|
||||
for (u=0; u < (3*ditlen); u++) inpcm[++j] = dah_buf[u];
|
||||
else
|
||||
for (u=0; u < ditlen; u++) inpcm[++j] = 0;
|
||||
|
||||
for (u=0; u < ditlen; u++) inpcm[++j] = 0;
|
||||
}
|
||||
|
||||
for (u=0; u < (2*ditlen); u++) inpcm[++j] = 0; /*inter word space*/
|
||||
|
||||
} /* foreach letter */
|
||||
|
||||
/* j = total length of samples in 'inpcm' */
|
||||
|
||||
outbytes = lame_encode_buffer(gfp, inpcm, inpcm, j, mp3buffer, mp3buffer_size);
|
||||
if (outbytes < 0) {
|
||||
fprintf(stderr, "Error: lame_encode_buffer returned %d. Exit.\n", outbytes);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (fwrite(mp3buffer, sizeof(char), outbytes, outfile) != outbytes) {
|
||||
fprintf(stderr, "Error: Writing %db to file failed. Exit.\n", outbytes);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* closefile -- finishes writing the current file, flushes the encoder buffer */
|
||||
|
||||
void closefile (int letter, int cw) {
|
||||
int outbytes;
|
||||
char mp3filename[80] = "";
|
||||
|
||||
printf("words: %d, minutes: %d\n", cw, (int) ((cw/wpm)*0.9));
|
||||
|
||||
snprintf(mp3filename, 80, "%s%02d.mp3", chapterfilename, letter);
|
||||
printf("Finishing %s\n\n", mp3filename);
|
||||
|
||||
outbytes = lame_encode_flush(gfp, mp3buffer, mp3buffer_size);
|
||||
|
||||
if (outbytes < 0) {
|
||||
fprintf(stderr, "Error: lame_encode_buffer returned %d.\n", outbytes);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (fwrite(mp3buffer, sizeof(char), outbytes, outfile) != outbytes) {
|
||||
fprintf(stderr, "Error: Writing %db to file failed. Exit.\n", outbytes);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
fclose(outfile);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* openfile -- starts a new chapter by opening Chapter%d.mp3 */
|
||||
|
||||
void openfile (int chapter) {
|
||||
char mp3filename[80] = "";
|
||||
static char tmp[80] = "";
|
||||
|
||||
snprintf(mp3filename, 80, "%s%02d.mp3", chapterfilename, chapter);
|
||||
printf("Starting %s\n", mp3filename);
|
||||
|
||||
if ((outfile = fopen(mp3filename, "wb")) == NULL) {
|
||||
fprintf(stderr, "Error: Failed to open %s\n", mp3filename);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
snprintf(tmp, 79, "%s - %d", id3_title, chapter); /* generate title */
|
||||
|
||||
id3tag_init(gfp);
|
||||
id3tag_set_artist(gfp, id3_author);
|
||||
id3tag_set_year(gfp, id3_year);
|
||||
id3tag_set_title(gfp, tmp);
|
||||
id3tag_set_comment(gfp, id3_comment);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void help (void) {
|
||||
printf("ebook2cw v%s - (c) 2008 by Fabian Kurz, DJ1YFK, http://fkurz.net/\n", VERSION);
|
||||
printf("\nThis is free software, and you are welcome to redistribute it\n");
|
||||
printf("under certain conditions (see COPYING).\n");
|
||||
printf("\n");
|
||||
printf("ebook2cw [-w wpm] [-f freq] [-R risetime] [-F falltime]\n");
|
||||
printf(" [-s samplerate] [-b mp3bitrate] [-q mp3quality]\n");
|
||||
printf(" [-c chapter-separator] [-o outfile-name] [-Q minutes]\n");
|
||||
printf(" [-a author] [-t title] [-k comment] [-y year]\n");
|
||||
printf(" [-u] [-S ISO|UTF] [infile]\n\n");
|
||||
printf("defaults: 25 WpM, 600Hz, RT=FT=50, s=11025Hz, b=16kbps,\n");
|
||||
printf(" c=\"CHAPTER\", o=\"Chapter\" infile = stdin\n");
|
||||
printf("\n");
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* showcodes
|
||||
* Generates a HTML table of the available CW symbols in codetables.h
|
||||
* i = 1 -> ISO 8859-1, i=0 -> UTF-8
|
||||
*/
|
||||
|
||||
void showcodes (int i) {
|
||||
int k;
|
||||
int n = i ? 256 : 1921;
|
||||
|
||||
printf("<html><head><META HTTP-EQUIV=\"CONTENT-TYPE\" CONTENT=\"text/html;"
|
||||
"charset=%s\"></head>\n", i ? "iso-8859-1" : "utf-8");
|
||||
printf("<body><h1>ebook2cw codetables.h</h1>\n");
|
||||
printf("<h2>%s</h2><table border=\"1\">\n", i ? "ISO 8859-1" : "UTF-8");
|
||||
printf("<tr><th>Decimal</th><th>Symbol</th><th>CW</th></tr>\n");
|
||||
|
||||
for (k=0; k < n; k++) {
|
||||
printf("<tr>");
|
||||
|
||||
if ((k < 128+i*128) && (iso8859[k] != NULL)) {
|
||||
printf("<td>%d</td><td>&#%d;</td><td>%s</td>", k, k, iso8859[k]);
|
||||
}
|
||||
else if (utf8table[k] != NULL) {
|
||||
printf("<td>%d</td><td>&#%d;</td><td>%s</td>", k, k, utf8table[k]);
|
||||
}
|
||||
else {
|
||||
printf("<td>%d</td><td>&#%d;</td><td> </td>", k, k);
|
||||
}
|
||||
|
||||
printf("</tr>\n");
|
||||
}
|
||||
|
||||
printf("</table></body></html>\n");
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
Binary file not shown.
|
|
@ -0,0 +1,280 @@
|
|||
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
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
0.6.2 / 2008-02-20 Fabian Kurz <mail@fkurz.net>
|
||||
* Support for arbitrary prosigns added. To generate a prosign
|
||||
enclose the letters in angle brackets (e.g. <AR>, <SK>, ...). Tnx DL7YEC
|
||||
|
||||
0.6.1 / 2008-02-09 Fabian Kurz <mail@fkurz.net>
|
||||
* Added more Cyrillic characters, the Greek and the Hebrew
|
||||
alphabet to the Unicode table. Some small corrections to
|
||||
the existing characters.
|
||||
* Command line switch -S with option either ISO or UTF prints
|
||||
a table of the available character set and the CW symbols
|
||||
in HTML format.
|
||||
|
||||
0.6.0 / 2008-02-05 Fabian Kurz <mail@fkurz.net>
|
||||
* Full ISO 8859-1 character set is now available
|
||||
* UTF-8 support by command line switch -u. Currently
|
||||
implemented: Latin, basic cyrillic.
|
||||
|
||||
0.5.1 / 2008-01-08 Fabian Kurz <mail@fkurz.net>
|
||||
* Fixed ID3 title (chapter number) generation.
|
||||
|
||||
0.5.0 / 2007-12-19 Fabian Kurz <mail@fkurz.net>
|
||||
* Added support for writing ID3 tags.
|
||||
* Added -Q command line switch: QRQ by 1 WpM every n minutes.
|
||||
|
||||
0.4.0 / 2007-12-17 Fabian Kurz <mail@fkurz.net>
|
||||
* Implemented dynamic memory allocation.
|
||||
|
||||
0.3.0 / 2007-11-28 Fabian Kurz <mail@fkurz.net>
|
||||
* Added forgotten characters: @ and /.
|
||||
|
||||
0.2.0 / 2007-11-27 Fabian Kurz <mail@fkurz.net>
|
||||
|
||||
* Fixed handling of umlauts (öäüß)
|
||||
* The chapter separator is now case sensitive.
|
||||
|
||||
0.1.0 / 2007-11-22 Fabian Kurz <mail@fkurz.net>
|
||||
|
||||
* Initial release of ebook2cw.
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
# ebook2cw Makefile -- Fabian Kurz, DJ1YFK -- http://fkurz.net/ham/ebook2cw.html
|
||||
|
||||
VERSION=0.6.2
|
||||
DESTDIR ?= /usr
|
||||
|
||||
all: ebook2cw
|
||||
|
||||
ebook2cw: ebook2cw.c
|
||||
gcc ebook2cw.c -pedantic -Wall -lm -lmp3lame -D VERSION=\"$(VERSION)\" -o ebook2cw
|
||||
|
||||
static:
|
||||
gcc -static ebook2cw.c -lmp3lame -lm -D VERSION=\"$(VERSION)\" -o ebook2cw
|
||||
|
||||
install:
|
||||
install -d -v $(DESTDIR)/share/man/man1/
|
||||
install -d -v $(DESTDIR)/bin/
|
||||
install -s -m 0755 ebook2cw $(DESTDIR)/bin/
|
||||
install -m 0644 ebook2cw.1 $(DESTDIR)/share/man/man1/
|
||||
|
||||
uninstall:
|
||||
rm -f $(DESTDIR)/bin/ebook2cw
|
||||
rm -f $(DESTDIR)/share/man/man1/ebook2cw.1
|
||||
|
||||
clean:
|
||||
rm -f ebook2cw *~ *.mp3
|
||||
|
||||
dist:
|
||||
sed 's/v[0-9].[0-9].[0-9]/v$(VERSION)/g' README > README2
|
||||
rm -f README
|
||||
mv README2 README
|
||||
rm -f releases/ebook2cw-$(VERSION).tar.gz
|
||||
rm -rf releases/ebook2cw-$(VERSION)
|
||||
mkdir ebook2cw-$(VERSION)
|
||||
cp ebook2cw.c codetables.h ChangeLog ebook2cw.1 \
|
||||
README COPYING Makefile ebook2cw-$(VERSION)
|
||||
tar -zcf ebook2cw-$(VERSION).tar.gz ebook2cw-$(VERSION)
|
||||
mv ebook2cw-$(VERSION) releases/
|
||||
mv ebook2cw-$(VERSION).tar.gz releases/
|
||||
md5sum releases/*.gz > releases/md5sums.txt
|
||||
chmod a+r releases/*
|
||||
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
ebook2cw v0.6.2 - convert ebooks to morse mp3s - Fabian Kurz, DJ1YFK
|
||||
---------------------------------------------------------------------
|
||||
|
||||
Website: http://fkurz.net/ham/ebook2cw.html
|
||||
|
||||
ebook2cw is a command line program which converts a plain text ebook to morse
|
||||
code MP3 files. It works on several platforms, including Windows and Linux.
|
||||
|
||||
It automatically splits and numbers the output files by chapters.
|
||||
|
||||
For a detailled description, please refer to the man-page or the project
|
||||
website.
|
||||
|
||||
|
||||
INSTALL
|
||||
--------
|
||||
1) Binaries
|
||||
Statically compiled binaries are available at the project website, for Linux
|
||||
(i386) and Win32. Those should be suitable for most users.
|
||||
|
||||
2) Source
|
||||
A Makefile is included; it compiles both under Linux and Windows (with MinGW).
|
||||
DESTDIR is /usr by default (so the binary will be in /usr/bin/).
|
||||
|
||||
make [DESTDIR=..]
|
||||
make install
|
||||
|
|
@ -0,0 +1,543 @@
|
|||
/*
|
||||
* ISO 8859-1 and UTF-8 to Morse code mappings
|
||||
* This file is part of ebook2cw and may be used under the same terms (GPL)
|
||||
* (C) 2008 Fabian Kurz, DJ1YFK
|
||||
*
|
||||
* Currently included: ISO 8859-1
|
||||
* - complete (all that can somehow be mapped)
|
||||
* Unicode:
|
||||
* - Latin (basic, some extended)
|
||||
* - Cyrillic alphabet (KOI-7 + Serbian, Macedonian.. )
|
||||
* - Greek
|
||||
* - Hebrew
|
||||
*
|
||||
* Any comments, additions or corrections are welcome: mail@fkurz.net
|
||||
*
|
||||
*/
|
||||
|
||||
const static char *iso8859[] = {
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
" ", /* space */
|
||||
"..--.", /* ! */
|
||||
".-..-.", /* " */
|
||||
NULL, /* # */
|
||||
"...-..-", /* $ */
|
||||
NULL, /* % */
|
||||
". ...", /* & */
|
||||
".----.", /* ' */
|
||||
"-.--.", /* ( */
|
||||
"-.--.-", /* ) */
|
||||
NULL, /* * */
|
||||
".-.-.", /* + */
|
||||
"--..--", /* , */
|
||||
"-....-", /* - */
|
||||
".-.-.-", /* . */
|
||||
"-..-.", /* / */
|
||||
"-----", /* 0 */
|
||||
".----", /* 1 */
|
||||
"..---", /* 2 */
|
||||
"...--", /* 3 */
|
||||
"....-", /* 4 */
|
||||
".....", /* 5 */
|
||||
"-....", /* 6 */
|
||||
"--...", /* 7 */
|
||||
"---..", /* 8 */
|
||||
"----.", /* 9 */
|
||||
"---...", /* : */
|
||||
"-.-.-.", /* ; */
|
||||
NULL, /* < */
|
||||
"-...-", /* = */
|
||||
NULL, /* < */
|
||||
"..--..", /* ? */
|
||||
".--.-.", /* @ */
|
||||
".-", /* A */
|
||||
"-...", /* B */
|
||||
"-.-.",
|
||||
"-..",
|
||||
".",
|
||||
"..-.",
|
||||
"--.",
|
||||
"....",
|
||||
"..",
|
||||
".---",
|
||||
"-.-",
|
||||
".-..",
|
||||
"--",
|
||||
"-.",
|
||||
"---",
|
||||
".--.",
|
||||
"--.-",
|
||||
".-.",
|
||||
"...",
|
||||
"-",
|
||||
"..-",
|
||||
"...-",
|
||||
".--",
|
||||
"-..-",
|
||||
"-.--",
|
||||
"--..", /* Z */
|
||||
NULL, /* [ */
|
||||
"-..-.", /* \ */
|
||||
NULL, /* ] */
|
||||
NULL, /* ^ */
|
||||
NULL, /* _ */
|
||||
".----.", /* ` */
|
||||
".-", /* a */
|
||||
"-...", /* b */
|
||||
"-.-.",
|
||||
"-..",
|
||||
".",
|
||||
"..-.",
|
||||
"--.",
|
||||
"....",
|
||||
"..",
|
||||
".---",
|
||||
"-.-",
|
||||
".-..",
|
||||
"--",
|
||||
"-.",
|
||||
"---",
|
||||
".--.",
|
||||
"--.-",
|
||||
".-.",
|
||||
"...",
|
||||
"-",
|
||||
"..-",
|
||||
"...-",
|
||||
".--",
|
||||
"-..-",
|
||||
"-.--",
|
||||
"--..", /* z */
|
||||
NULL, /* { */
|
||||
NULL, /* | */
|
||||
NULL, /* } */
|
||||
NULL, /* ~ */
|
||||
NULL, /* DEL */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL,
|
||||
".-..-.", /* « (angle quotes, <<, 171) */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
".-..-.", /* » (angle quotes, >>, 187) */
|
||||
NULL, NULL, NULL, NULL,
|
||||
".--.-", /* `A */
|
||||
".--.-", /* 'A */
|
||||
".-", /* ^A */
|
||||
".-", /* ~A */
|
||||
".-.-", /* "A */
|
||||
".--.-", /* °A */
|
||||
".- .", /* AE */
|
||||
"-.-..", /* ,C */
|
||||
"..-..", /* `E */
|
||||
"..-..", /* 'E */
|
||||
".", /* ^E */
|
||||
".", /* "E */
|
||||
"..", /* `I */
|
||||
"..", /* 'I */
|
||||
"..", /* ^I */
|
||||
"..", /* "I */
|
||||
"..--.", /* -D */
|
||||
"--.--", /* ~N */
|
||||
"---", /* `O */
|
||||
"---", /* 'O */
|
||||
"---", /* ^O */
|
||||
"---", /* ~O */
|
||||
"---.", /* "O */
|
||||
NULL, /* x */
|
||||
"---.", /* /O */
|
||||
"..-", /* `U */
|
||||
"..-", /* 'U */
|
||||
"..-", /* ^U */
|
||||
"..--", /* "U */
|
||||
"-.--", /* 'Y */
|
||||
".--..", /* 'thorn' */
|
||||
"...--..", /* sz */
|
||||
".--.-", /* `a */
|
||||
".--.-", /* 'a */
|
||||
".-", /* ^a */
|
||||
".-", /* ~a */
|
||||
".-.-", /* "a */
|
||||
".--.-", /* °a */
|
||||
".- .", /* ae */
|
||||
"-.-..", /* ,c */
|
||||
"..-..", /* `e */
|
||||
"..-..", /* 'e */
|
||||
".", /* ^e */
|
||||
".", /* "e */
|
||||
"..", /* `i */
|
||||
"..", /* 'i */
|
||||
"..", /* ^i */
|
||||
"..", /* "i */
|
||||
"..--.", /* -d */
|
||||
"--.--", /* ~n */
|
||||
"---", /* `o */
|
||||
"---", /* 'o */
|
||||
"---", /* ^o */
|
||||
"---", /* ~o */
|
||||
"---.", /* "o */
|
||||
NULL, /* ./. */
|
||||
"---.", /* /o */
|
||||
"..-", /* `u */
|
||||
"..-", /* 'u */
|
||||
"..-", /* ^u */
|
||||
"..--", /* "u */
|
||||
"-.--", /* 'y */
|
||||
".--..", /* 'thorn' */
|
||||
"-.--" /* "y */
|
||||
};
|
||||
|
||||
const static char *utf8table[] = {
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* first 128 are identical*/
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* to iso8859, so that */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* will be used instead */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* - 127 */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* control characters ...*/
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* -159 */
|
||||
" ", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, ".-..-.", NULL, NULL, NULL, NULL, /* 171 << */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, ".-..-.", NULL, NULL, NULL, NULL, /* 187 >> */
|
||||
/* same as in ISO8859 */
|
||||
".--.-", /* `A */ /* 192 ... */
|
||||
".--.-", /* 'A */
|
||||
".-", /* ^A */
|
||||
".-", /* ~A */
|
||||
".-.-", /* "A */
|
||||
".--.-", /* °A */
|
||||
".- .", /* AE */
|
||||
"-.-..", /* ,C */
|
||||
"..-..", /* `E */
|
||||
"..-..", /* 'E */
|
||||
".", /* ^E */
|
||||
".", /* "E */
|
||||
"..", /* `I */
|
||||
"..", /* 'I */
|
||||
"..", /* ^I */
|
||||
"..", /* "I */
|
||||
"..--.", /* -D according to Wikipedia */
|
||||
"--.--", /* ~N */
|
||||
"---", /* `O */
|
||||
"---", /* 'O */
|
||||
"---", /* ^O */
|
||||
"---", /* ~O */
|
||||
"---.", /* "O */
|
||||
NULL, /* x */
|
||||
"---.", /* /O */
|
||||
"..-", /* `U */
|
||||
"..-", /* 'U */
|
||||
"..-", /* ^U */
|
||||
"..--", /* "U */
|
||||
"-.--", /* 'Y */
|
||||
".--..", /* 'thorn', acc to Wikipedia */
|
||||
"...--..", /* sz */
|
||||
".--.-", /* `a */
|
||||
".--.-", /* 'a */
|
||||
".-", /* ^a */
|
||||
".-", /* ~a */
|
||||
".-.-", /* "a */
|
||||
".--.-", /* °a */
|
||||
".- .", /* ae */
|
||||
"-.-..", /* ,c */
|
||||
"..-..", /* `e */
|
||||
"..-..", /* 'e */
|
||||
".", /* ^e */
|
||||
".", /* "e */
|
||||
"..", /* `i */
|
||||
"..", /* 'i */
|
||||
"..", /* ^i */
|
||||
"..", /* "i */
|
||||
"..--.", /* -d Wiki */
|
||||
"--.--", /* ~n */
|
||||
"---", /* `o */
|
||||
"---", /* 'o */
|
||||
"---", /* ^o */
|
||||
"---", /* ~o */
|
||||
"---.", /* "o */
|
||||
NULL, /* ./. */
|
||||
"---.", /* /o */
|
||||
"..-", /* `u */
|
||||
"..-", /* 'u */
|
||||
"..-", /* ^u */
|
||||
"..--", /* "u */
|
||||
"-.--", /* 'y */
|
||||
".--..", /* 'thorn' */
|
||||
"-.--", /* "y */ /* 255 */
|
||||
".-", ".-", ".-", ".-", ".-", ".-", /* 256-261, As with different hats */
|
||||
/* 262-269 Cs with different hats */
|
||||
/* 264-265 -.-.. acc. to Wikipedia */
|
||||
"-.-.", "-.-.", "-.-..", "-.-..", "-.-.", "-.-.", "-.-.", "-.-.",
|
||||
"-..", "-..", "-..", "-..", /* 270-273 Ds with different stuff */
|
||||
/* 274-283 different Es */
|
||||
".", ".", ".", ".", ".", ".", ".", ".", ".", ".",
|
||||
/* 284-291 different Gs, first 2 according to Wikipedia */
|
||||
"--.-.", "--.-.", "--.", "--.", "--.", "--.", "--.", "--.",
|
||||
/* 292-295 different Hs, ditto */
|
||||
"-.--.", "-.--.", "....", "....",
|
||||
/* 296-305 different Is */
|
||||
"..", "..", "..", "..", "..", "..", "..", "..", "..", "..",
|
||||
/* 306-307 IJ ligatures */
|
||||
".. .---", ".. .---",
|
||||
/* 308-309 Js, from Wikipedia */
|
||||
".---.", ".---.",
|
||||
/* 310-312 Ks */
|
||||
"-.-", "-.-", "-.-",
|
||||
/* 313-322 different Ls */
|
||||
".-..", ".-..", ".-..", ".-..", ".-..", ".-..", ".-..",
|
||||
".-..", ".-..", ".-..",
|
||||
/* 323-331 different Ns */
|
||||
"-.", "-.", "-.", "-.", "-.", "-.", "-.", "-.", "-.",
|
||||
/* 332-337 Os */
|
||||
"---", "---", "---", "---", "---", "---",
|
||||
/* 338-339 OEs */
|
||||
"---.", "---.",
|
||||
/* 340-345 Rs */
|
||||
".-.", ".-.", ".-.", ".-.", ".-.", ".-.",
|
||||
/* 346-353 Ss, Wikipedia */
|
||||
"...", "...", "...-.", "...-.", "...", "...", "...", "...",
|
||||
/* 354-359 Ts */
|
||||
"-", "-", "-", "-", "-", "-",
|
||||
/* 360-371 Us */
|
||||
"..-", "..-", "..-", "..-", "..-", "..-", "..-", "..-", "..-",
|
||||
"..-", "..-", "..-",
|
||||
/* 372-373 Ws */
|
||||
".--", ".--",
|
||||
/* 374-377 Ys */
|
||||
"-.--", "-.--", "-.--",
|
||||
/* 377-382 Zs */
|
||||
"--..", "--..", "--..", "--..", "--..", "--..",
|
||||
/* 383 S */
|
||||
"...",
|
||||
/* 384-389 Bs */
|
||||
"-...", "-...", "-...", "-...", "-...", "-...",
|
||||
NULL, NULL, NULL, /* all kind of weird stuff */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL,
|
||||
/* Standard Greek Alphabet */
|
||||
".-", "-..." , "--.", "-..", ".", "--..", "....",
|
||||
"-.-.", "..", "-.-", ".-..", "--", "-.", "-..-", "---",
|
||||
".--.", ".-.", NULL, "...", "-", "-.--", "..-.", "----",
|
||||
"--.-", ".--", NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 1023 */
|
||||
|
||||
/* 1024-1039, cyrillic (Serbian, Macedonian, Ukrainian) UC */
|
||||
".", ".", "-.. .---", "--. .---", ".", "-.. --..", "..", "..",
|
||||
".---", ".-.. .---", "-. .---", "-.-.", "-.- .---", "..", "..-","-.. --..",
|
||||
|
||||
/* 32 letters of Russian Cyrillic alphabet */
|
||||
".-", "-...", ".--", "--.", "-..", ".", "...-", /* 1040-1071 */
|
||||
"--..", "..",".---", "-.-", ".-..", "--", "-.", /* uppercase */
|
||||
"---", ".--.", ".-.", "...", "-", "..-", "..-.", /* cyrillic */
|
||||
"....", "-.-.", "---.", "----", "--.-", "-..-",
|
||||
"-.--", "-..-", "..-..", "..--", ".-.-",
|
||||
".-", "-...", ".--", "--.", "-..", ".", "...-", /* 1072-1103 */
|
||||
"--..", "..",".---", "-.-", ".-..", "--", "-.", /* lowercase */
|
||||
"---", ".--.", ".-.", "...", "-", "..-", "..-.", /* cyrillic */
|
||||
"....", "-.-.", "---.", "----", "--.-", "-..-",
|
||||
"-.--", "-..-", "..-..", "..--", ".-.-",
|
||||
|
||||
/* 1004-1119, cyrillic (Serbian, Macedonian, Ukrainian) UC */
|
||||
".", ".", "-.. .---", "--. .---", ".", "-.. --..", "..", "..",
|
||||
".---", ".-.. .---", "-. .---", "-.-.", "-.- .---", "..", "..-","-.. --..",
|
||||
|
||||
/* 1120 - 1487 to be done... */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/* 1488-1514 Hebrew according to Wikipedia */
|
||||
".-", "-...", "--.", "-..", "---", ".", "--..", "....",
|
||||
"..-", "..", NULL, "-.-", ".-..", NULL, "--", "-.", NULL,
|
||||
"-.-.", ".---", NULL, ".--.", NULL, ".--", "--.-", ".-.", "...",
|
||||
"-", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL /* 1920 */
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
.TH ebook2cw 1 "FEBRUARY 2008" Linux "User Manuals"
|
||||
.SH NAME
|
||||
ebook2cw \- convert ebooks to morse mp3s
|
||||
.SH SYNOPSIS
|
||||
.B ebook2cw
|
||||
[OPTIONS]
|
||||
.SH DESCRIPTION
|
||||
.B ebook2cw
|
||||
ebook2cw is a command line program which converts a plain text ebook to morse
|
||||
code MP3 files. It works on several platforms, including Windows and Linux.
|
||||
|
||||
A number of CW and MP3 parameters can be changed from their default values, by
|
||||
command line switches. These are (default values in brackets):
|
||||
|
||||
.B -w wpm
|
||||
- CW speed in words per minute [25]
|
||||
|
||||
.B -f freq
|
||||
- audio frequency in Hz [600]
|
||||
|
||||
.B -Q minutes
|
||||
- Increase CW speed (QRQ) by 1 WpM in intervals of `minutes'. Speed will be
|
||||
reset to the initial value at the start of each chapter. [0]
|
||||
|
||||
.B -R risetime
|
||||
- risetime, in samples [50]
|
||||
|
||||
.B -F falltime
|
||||
- falltime, samples [50]
|
||||
|
||||
.B -s samplerate
|
||||
- samplerate for the MP3 file [11025]
|
||||
|
||||
.B -b bitrate
|
||||
- MP3 bitrate, kbps [16]
|
||||
|
||||
.B -q quality
|
||||
- MP3 quality, 1 (best) to 9 (worst). CW still sounds very good with the worst quality, encoding time is greatly reduced. [5]
|
||||
|
||||
.B -c chapter separator
|
||||
- Split chapters at this string. Must be pure ASCII if UTF-8 is used. [CHAPTER]
|
||||
|
||||
.B -o outfile-name
|
||||
- Output filename (chapter number and .mp3 will be appended) [Chapter]
|
||||
|
||||
.B -a author
|
||||
- Author for the ID3 tag. Use quotes for strings with spaces (e.g. "JW Goethe")
|
||||
|
||||
.B -t title
|
||||
- Title for the ID3 tag. Use quotes for strings with spaces (e.g. "Faust II")
|
||||
|
||||
.B -k comment
|
||||
- Comment for the ID3 tag. Use quotes for strings with spaces.
|
||||
|
||||
.B -y year
|
||||
- Year for the ID3 tag.
|
||||
|
||||
.B -u
|
||||
- Switches input encoding format to UTF-8. Currentply supported alphabets include Latin, Greek, Hebrew and Cyrillic. Default is ISO 8859-1.
|
||||
|
||||
.B -S [ISO|UTF]
|
||||
- Shows a table of all available morse symbols for the ISO 8859-1 and UTF-8
|
||||
character sets. Output in HTML format.
|
||||
|
||||
CW prosigns can be generated by enclosing arbitrary letters in angle brackets
|
||||
(e.g. <AR>, <SK>, ...).
|
||||
|
||||
.SH AUTHOR
|
||||
Fabian Kurz, DJ1YFK <mail@fkurz.net>
|
||||
|
||||
http://fkurz.net/ham/ebook2cw.html
|
||||
.SH "SEE ALSO"
|
||||
.BR morse (1)
|
||||
|
|
@ -0,0 +1,586 @@
|
|||
/*
|
||||
ebook2cw - converts an ebook to morse mp3s
|
||||
|
||||
Copyright (C) 2008 Fabian Kurz, DJ1YFK
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 2 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
|
||||
Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
source code looks properly indented with tw=4
|
||||
|
||||
*/
|
||||
|
||||
#include "lame/lame.h"
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "codetables.h"
|
||||
|
||||
#ifndef VERSION
|
||||
#define VERSION "0.0.0"
|
||||
#endif
|
||||
|
||||
#define PCMBUFFER 220500 /* 20 seconds at 11kHz, for one word. plenty. */
|
||||
#define MP3BUFFER 285000 /* abt 1.25*PCMBUFFER + 7200, as recommended */
|
||||
|
||||
#define ISO8859 0
|
||||
#define UTF8 1
|
||||
|
||||
lame_global_flags *gfp;
|
||||
|
||||
FILE *outfile;
|
||||
FILE *infile;
|
||||
|
||||
/* MP3 samplerate, bitrate, quality. */
|
||||
int samplerate = 11025;
|
||||
int brate = 16;
|
||||
int quality = 5;
|
||||
|
||||
/* CW parameters */
|
||||
int wpm = 25;
|
||||
int freq = 600;
|
||||
int rt = 50; /* rise/fall time in samples */
|
||||
int ft = 50;
|
||||
int qrq = 0; /* rise speed by 1 WpM every qrq minutes */
|
||||
|
||||
/* the buffers for dit, dah, raw pcm and mp3 output, will me calloc'ed to the
|
||||
* default values, and if needed realloc'ed to the needed size */
|
||||
|
||||
short int *dit_buf;
|
||||
short int *dah_buf;
|
||||
short int *inpcm;
|
||||
unsigned char *mp3buffer;
|
||||
|
||||
int inpcm_size;
|
||||
int mp3buffer_size;
|
||||
|
||||
int ditlen=0; /* number of samples in a 'dit' */
|
||||
|
||||
/* Chapters are split by this string */
|
||||
char chapterstr[80]="CHAPTER";
|
||||
char chapterfilename[80]="Chapter"; /* full filename: Chapter%02d.mp3 */
|
||||
|
||||
/* ID3-tag data: author and title */
|
||||
char id3_author[80]="CW-Book";
|
||||
char id3_title[80]="";
|
||||
char id3_comment[80]="";
|
||||
char id3_year[5]="";
|
||||
|
||||
/* functions */
|
||||
int init_cw (int wpm, int freq, int rt, int ft);
|
||||
void help (void);
|
||||
void showcodes (int i);
|
||||
void makeword(char * text, int encoding);
|
||||
void closefile (int letter, int cw);
|
||||
void openfile (int chapter);
|
||||
|
||||
/* main */
|
||||
|
||||
int main (int argc, char** argv) {
|
||||
int pos, i, original_wpm;
|
||||
int encoding = ISO8859;
|
||||
int c;
|
||||
char word[1024]=""; /* will be cut when > 1024 chars long */
|
||||
int chapter = 0;
|
||||
int cw = 0, tw = 0, qw = 0; /* chapter words, total words, qrq words */
|
||||
|
||||
infile = stdin;
|
||||
|
||||
while((i = getopt(argc, argv, "o:w:f:R:F:s:b:q:c:a:t:k:y:Q:S:hu")) != -1) {
|
||||
switch (i) {
|
||||
case 'w':
|
||||
if ((wpm = atoi(optarg)) < 1) {
|
||||
fprintf(stderr, "Error: Speed (-w) must be > 0!\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
case 'f':
|
||||
freq = atoi(optarg);
|
||||
break;
|
||||
case 'R':
|
||||
rt = atoi(optarg);
|
||||
break;
|
||||
case 'F':
|
||||
ft = atoi(optarg);
|
||||
break;
|
||||
case 's':
|
||||
samplerate = atoi(optarg);
|
||||
break;
|
||||
case 'b':
|
||||
brate = atoi(optarg);
|
||||
break;
|
||||
case 'q':
|
||||
quality = atoi(optarg);
|
||||
break;
|
||||
case 'c':
|
||||
strncpy(chapterstr, optarg, 78);
|
||||
break;
|
||||
case 'o':
|
||||
strncpy(chapterfilename, optarg, 78);
|
||||
break;
|
||||
case 'a':
|
||||
strncpy(id3_author, optarg, 78);
|
||||
break;
|
||||
case 't':
|
||||
strncpy(id3_title, optarg, 75);
|
||||
break;
|
||||
case 'k':
|
||||
strncpy(id3_comment, optarg, 78);
|
||||
break;
|
||||
case 'y':
|
||||
strncpy(id3_year, optarg, 4);
|
||||
break;
|
||||
case 'Q':
|
||||
if ((qrq = atoi(optarg)) < 1) {
|
||||
fprintf(stderr, "Error: QRQ time (-Q) must be > 0!\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
case 'u':
|
||||
encoding = UTF8;
|
||||
break;
|
||||
case 'S':
|
||||
if (strstr(optarg, "ISO")) {
|
||||
showcodes(1);
|
||||
}
|
||||
else {
|
||||
showcodes(0);
|
||||
}
|
||||
case 'h':
|
||||
default:
|
||||
help();
|
||||
} /* switch */
|
||||
} /* while */
|
||||
|
||||
if (optind < argc) { /* something left? if so, use as infile */
|
||||
if ((argv[optind][0] != '-') && (argv[optind][0] != '\0')) {
|
||||
if ((infile = fopen(argv[optind], "r")) == NULL) {
|
||||
fprintf(stderr, "Error: Cannot open file %s. Exit.\n",
|
||||
argv[optind]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf("ebook2cw %s - (c) 2008 by Fabian Kurz, DJ1YFK\n", VERSION);
|
||||
printf("Speed: %d WpM, Freq: %dHz, Chapter: >%s<, Encoding: %s\n\n",
|
||||
wpm, freq, chapterstr, encoding == UTF8 ? "UTF-8" : "ISO 8859-1");
|
||||
|
||||
|
||||
/* init lame */
|
||||
gfp = lame_init();
|
||||
lame_set_num_channels(gfp,1);
|
||||
lame_set_in_samplerate(gfp, samplerate);
|
||||
lame_set_brate(gfp, brate);
|
||||
lame_set_mode(gfp,1);
|
||||
lame_set_quality(gfp, quality);
|
||||
|
||||
if (lame_init_params(gfp) < 0) {
|
||||
fprintf(stderr, "Failed: lame_init_params(gfp) \n");
|
||||
return(1);
|
||||
}
|
||||
else {
|
||||
printf("Initialized lame: samplerate=%d, bitrate=%d, quality=%d\n",
|
||||
samplerate, brate, quality);
|
||||
}
|
||||
|
||||
/* init pcm_buf and mp3_buf */
|
||||
|
||||
if ((inpcm = calloc(PCMBUFFER, sizeof(short int))) == NULL) {
|
||||
fprintf(stderr, "Error: Can't allocate inpcm[%d]!\n", PCMBUFFER);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
else {
|
||||
inpcm_size = PCMBUFFER;
|
||||
}
|
||||
|
||||
if ((mp3buffer = calloc(MP3BUFFER, sizeof(unsigned char))) == NULL) {
|
||||
fprintf(stderr, "Error: Can't allocate mp3buffer[%d]!\n", MP3BUFFER);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
else {
|
||||
mp3buffer_size = MP3BUFFER;
|
||||
}
|
||||
|
||||
ditlen = init_cw(wpm, freq, rt, ft); /* generate raw dit, dah */
|
||||
|
||||
strcat(chapterstr, " ");
|
||||
|
||||
/* read STDIN, assemble full words (anything ending in ' ') to 'word' and
|
||||
* generate CW, write to file by 'makeword'. words with > 1024 characters
|
||||
* will be split */
|
||||
|
||||
original_wpm = wpm; /* may be changed by QRQing */
|
||||
chapter = 0;
|
||||
openfile(chapter);
|
||||
|
||||
pos=0;
|
||||
while ((c = getc(infile)) != EOF) {
|
||||
|
||||
if (c == '\r') /* DOS linebreaks */
|
||||
continue;
|
||||
|
||||
word[pos++] = c;
|
||||
|
||||
if ((c == ' ') || (c == '\n') || (pos == 1024)) {
|
||||
word[pos] = '\0';
|
||||
if (strcmp(chapterstr, word) == 0) { /* new chapter */
|
||||
closefile(chapter, cw);
|
||||
cw=0;
|
||||
chapter++;
|
||||
|
||||
/* restore to initial speed if we're QRQing */
|
||||
if (qrq) {
|
||||
wpm = original_wpm;
|
||||
ditlen = init_cw(wpm, freq, rt, ft);
|
||||
}
|
||||
|
||||
openfile(chapter);
|
||||
}
|
||||
makeword(word, encoding);
|
||||
cw++; tw++; qw++;
|
||||
|
||||
word[0] = '\0';
|
||||
pos = 0;
|
||||
|
||||
/* every 'qrq' minutes (qrq*wpm words), speed up 1 WpM */
|
||||
if (qw == (qrq*wpm)) {
|
||||
wpm += 1;
|
||||
ditlen = init_cw(wpm, freq, rt, ft);
|
||||
qw = 0;
|
||||
}
|
||||
} /* word */
|
||||
} /* eof */
|
||||
|
||||
closefile(chapter, cw);
|
||||
|
||||
free(mp3buffer);
|
||||
free(inpcm);
|
||||
|
||||
/* factor 0.9 due to many 'words' which aren't actually words, like '\n' */
|
||||
printf("Total words: %d, total time: %d min\n", tw, (int) ((tw/wpm)*0.9));
|
||||
|
||||
lame_close(gfp);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* init_cw - generates a dit and a dah to dit_buf and dah_buf */
|
||||
|
||||
int init_cw (int wpm, int freq, int rt, int ft) {
|
||||
int x;
|
||||
int len;
|
||||
double val;
|
||||
|
||||
printf("Initializing CW buffers at %d WpM: ", wpm);
|
||||
|
||||
/* dah */
|
||||
len = (int) (3.0*6.0*samplerate/(5.0*wpm)); /* in samples */
|
||||
|
||||
/* ditlen not set == init_cw has not been called yet */
|
||||
if (!ditlen) {
|
||||
/* allocate memory for the buffer */
|
||||
if ((dah_buf = calloc(len, sizeof(short int))) == NULL) {
|
||||
fprintf(stderr, "Error: Can't allocate dah_buf[%d]\n", len);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
for (x=0; x < len; x++) {
|
||||
val = sin(2*M_PI*freq*x/samplerate);
|
||||
if (x < rt) /* shaping with sin^2 */
|
||||
val *= pow(sin(M_PI*x/(2.0*rt)),2);
|
||||
|
||||
if (x > (len-ft))
|
||||
val *= pow((sin(2*M_PI*(x-(len-ft)+ft)/(4*ft))), 2);
|
||||
|
||||
dah_buf[x] = (short int) (val * 20000.0);
|
||||
}
|
||||
|
||||
printf("dah_buf[%d], ", x);
|
||||
|
||||
/* dit */
|
||||
len = (int) (6.0*samplerate/(5.0*wpm)); /* in samples */
|
||||
|
||||
/* ditlen not set == init_cw has not been called yet */
|
||||
if (!ditlen) {
|
||||
/* allocate memory for the buffer */
|
||||
if ((dit_buf = calloc(len, sizeof(short int))) == NULL) {
|
||||
fprintf(stderr, "Error: Can't allocate dit_buf[%d]\n", len);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
for (x=0; x < len; x++) {
|
||||
val = sin(2*M_PI*freq*x/samplerate);
|
||||
if (x < rt)
|
||||
val *= pow(sin(M_PI*x/(2.0*rt)), 2);
|
||||
|
||||
if (x > (len-ft))
|
||||
val *= pow((sin(2*M_PI*(x-(len-ft)+ft)/(4*ft))), 2);
|
||||
|
||||
dit_buf[x] = (short int) (val * 20000.0);
|
||||
}
|
||||
|
||||
printf("dit_buf[%d]\n\n", x);
|
||||
|
||||
return x; /* = length of dit/silence */
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* makeword -- converts 'text' to CW by concatenating dit_buf amd dah_bufs,
|
||||
* encodes this to MP3 and writes to open filehandle outfile */
|
||||
|
||||
void makeword(char * text, int encoding) {
|
||||
const char *code; /* CW code as . and - */
|
||||
int outbytes;
|
||||
|
||||
int c;
|
||||
int i,u,w;
|
||||
int j;
|
||||
int prosign = 0;
|
||||
unsigned char last=0; /* for utf8 2-byte characters */
|
||||
|
||||
j = 0; /* position in 'inpcm' buffer */
|
||||
|
||||
for (i = 0; i < strlen(text); i++) {
|
||||
c = (unsigned char) text[i];
|
||||
code = NULL;
|
||||
|
||||
if (c == '\n') { /* Same for UTF8 and ISO8859 */
|
||||
if (strlen(text) == 1) /* paragraph */
|
||||
code = " -...- ";
|
||||
else
|
||||
code = " ";
|
||||
}
|
||||
else if (c == '<') { /* prosign on */
|
||||
prosign = 1;
|
||||
continue;
|
||||
}
|
||||
else if ((c == '>') && prosign) { /* prosign off */
|
||||
prosign = 0;
|
||||
code = ""; /* only inserts letter space */
|
||||
}
|
||||
else if (encoding == ISO8859) {
|
||||
code = iso8859[c];
|
||||
}
|
||||
else if (encoding == UTF8) {
|
||||
/* Character may be 1-byte ASCII or 2-byte UTF8 */
|
||||
if (!(c & 128)) { /* MSB = 0 -> 7bit ASCII */
|
||||
code = iso8859[c]; /* subset of iso8859 */
|
||||
}
|
||||
else {
|
||||
if (last && (c < 192) ) { /* this is the 2nd byte */
|
||||
/* 110yyyyy 10zzzzzz -> 00000yyy yyzzzzzz */
|
||||
c = ((last & 31) << 6) | (c & 63);
|
||||
code = utf8table[c];
|
||||
last = 0;
|
||||
}
|
||||
else {
|
||||
last = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (last) continue; /* first of two-byte character read */
|
||||
|
||||
/* Not found anything ... */
|
||||
if (code == NULL) {
|
||||
code = " ";
|
||||
if (c < 255) {
|
||||
fprintf(stderr, "Warning: don't know CW for '%c'\n", c);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "Warning: don't know CW for unicode &#%d;\n", c);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* code contains letter as ./-, now assemble pcm buffer */
|
||||
|
||||
for (w = 0; w < strlen(code) ; w++) {
|
||||
|
||||
/* make sure the inpcm buffer doesn't run full,
|
||||
* with a conservative margin. reallocate memory if neccesary */
|
||||
if (j > inpcm_size-(6*ditlen)) {
|
||||
inpcm_size += (6*ditlen);
|
||||
mp3buffer_size += (8*ditlen + 7200);
|
||||
if ((inpcm = realloc(inpcm, inpcm_size*sizeof(short int)))== NULL)
|
||||
fprintf(stderr, "Error: Can't realloc inpcm[%d]\n", inpcm_size);
|
||||
|
||||
if ((mp3buffer = realloc(mp3buffer, mp3buffer_size*sizeof(char)))
|
||||
== NULL)
|
||||
fprintf(stderr, "Error: Can't realloc mp3buffer[%d]\n",
|
||||
mp3buffer_size);
|
||||
}
|
||||
|
||||
c = code[w];
|
||||
|
||||
if (c == '.')
|
||||
for (u=0; u < ditlen; u++)
|
||||
inpcm[++j] = dit_buf[u];
|
||||
else if (c == '-')
|
||||
for (u=0; u < (3*ditlen); u++)
|
||||
inpcm[++j] = dah_buf[u];
|
||||
else
|
||||
for (u=0; u < ditlen; u++)
|
||||
inpcm[++j] = 0;
|
||||
|
||||
for (u=0; u < ditlen; u++) /* space of one dit length */
|
||||
inpcm[++j] = 0;
|
||||
} /* foreach dot/dash */
|
||||
|
||||
if (prosign == 0) {
|
||||
for (u=0; u < (2*ditlen); u++)
|
||||
inpcm[++j] = 0;
|
||||
}
|
||||
|
||||
} /* foreach letter */
|
||||
|
||||
/* j = total length of samples in 'inpcm' */
|
||||
|
||||
outbytes = lame_encode_buffer(gfp, inpcm, inpcm, j, mp3buffer, mp3buffer_size);
|
||||
if (outbytes < 0) {
|
||||
fprintf(stderr, "Error: lame_encode_buffer returned %d. Exit.\n", outbytes);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (fwrite(mp3buffer, sizeof(char), outbytes, outfile) != outbytes) {
|
||||
fprintf(stderr, "Error: Writing %db to file failed. Exit.\n", outbytes);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* closefile -- finishes writing the current file, flushes the encoder buffer */
|
||||
|
||||
void closefile (int letter, int cw) {
|
||||
int outbytes;
|
||||
char mp3filename[80] = "";
|
||||
|
||||
printf("words: %d, minutes: %d\n", cw, (int) ((cw/wpm)*0.9));
|
||||
|
||||
snprintf(mp3filename, 80, "%s%02d.mp3", chapterfilename, letter);
|
||||
printf("Finishing %s\n\n", mp3filename);
|
||||
|
||||
outbytes = lame_encode_flush(gfp, mp3buffer, mp3buffer_size);
|
||||
|
||||
if (outbytes < 0) {
|
||||
fprintf(stderr, "Error: lame_encode_buffer returned %d.\n", outbytes);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (fwrite(mp3buffer, sizeof(char), outbytes, outfile) != outbytes) {
|
||||
fprintf(stderr, "Error: Writing %db to file failed. Exit.\n", outbytes);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
fclose(outfile);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* openfile -- starts a new chapter by opening Chapter%d.mp3 */
|
||||
|
||||
void openfile (int chapter) {
|
||||
char mp3filename[80] = "";
|
||||
static char tmp[80] = "";
|
||||
|
||||
snprintf(mp3filename, 80, "%s%02d.mp3", chapterfilename, chapter);
|
||||
printf("Starting %s\n", mp3filename);
|
||||
|
||||
if ((outfile = fopen(mp3filename, "wb")) == NULL) {
|
||||
fprintf(stderr, "Error: Failed to open %s\n", mp3filename);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
snprintf(tmp, 79, "%s - %d", id3_title, chapter); /* generate title */
|
||||
|
||||
id3tag_init(gfp);
|
||||
id3tag_set_artist(gfp, id3_author);
|
||||
id3tag_set_year(gfp, id3_year);
|
||||
id3tag_set_title(gfp, tmp);
|
||||
id3tag_set_comment(gfp, id3_comment);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void help (void) {
|
||||
printf("ebook2cw v%s - (c) 2008 by Fabian Kurz, DJ1YFK, http://fkurz.net/\n", VERSION);
|
||||
printf("\nThis is free software, and you are welcome to redistribute it\n");
|
||||
printf("under certain conditions (see COPYING).\n");
|
||||
printf("\n");
|
||||
printf("ebook2cw [-w wpm] [-f freq] [-R risetime] [-F falltime]\n");
|
||||
printf(" [-s samplerate] [-b mp3bitrate] [-q mp3quality]\n");
|
||||
printf(" [-c chapter-separator] [-o outfile-name] [-Q minutes]\n");
|
||||
printf(" [-a author] [-t title] [-k comment] [-y year]\n");
|
||||
printf(" [-u] [-S ISO|UTF] [infile]\n\n");
|
||||
printf("defaults: 25 WpM, 600Hz, RT=FT=50, s=11025Hz, b=16kbps,\n");
|
||||
printf(" c=\"CHAPTER\", o=\"Chapter\" infile = stdin\n");
|
||||
printf("\n");
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* showcodes
|
||||
* Generates a HTML table of the available CW symbols in codetables.h
|
||||
* i = 1 -> ISO 8859-1, i=0 -> UTF-8
|
||||
*/
|
||||
|
||||
void showcodes (int i) {
|
||||
int k;
|
||||
int n = i ? 256 : 1921;
|
||||
|
||||
printf("<html><head><META HTTP-EQUIV=\"CONTENT-TYPE\" CONTENT=\"text/html;"
|
||||
"charset=%s\"></head>\n", i ? "iso-8859-1" : "utf-8");
|
||||
printf("<body><h1>ebook2cw codetables.h</h1>\n");
|
||||
printf("<h2>%s</h2><table border=\"1\">\n", i ? "ISO 8859-1" : "UTF-8");
|
||||
printf("<tr><th>Decimal</th><th>Symbol</th><th>CW</th></tr>\n");
|
||||
|
||||
for (k=0; k < n; k++) {
|
||||
printf("<tr>");
|
||||
|
||||
if ((k < 128+i*128) && (iso8859[k] != NULL)) {
|
||||
printf("<td>%d</td><td>&#%d;</td><td>%s</td>", k, k, iso8859[k]);
|
||||
}
|
||||
else if (utf8table[k] != NULL) {
|
||||
printf("<td>%d</td><td>&#%d;</td><td>%s</td>", k, k, utf8table[k]);
|
||||
}
|
||||
else {
|
||||
printf("<td>%d</td><td>&#%d;</td><td> </td>", k, k);
|
||||
}
|
||||
|
||||
printf("</tr>\n");
|
||||
}
|
||||
|
||||
printf("</table></body></html>\n");
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
Binary file not shown.
|
|
@ -0,0 +1,280 @@
|
|||
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
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
0.6.3 / 2008-03-10 Fabian Kurz <mail@fkurz.net>
|
||||
* Added the Arabic morse code alphabet
|
||||
* Added/changed Unicode characters for Esperanto
|
||||
|
||||
0.6.2 / 2008-02-20 Fabian Kurz <mail@fkurz.net>
|
||||
* Support for arbitrary prosigns added. To generate a prosign
|
||||
enclose the letters in angle brackets (e.g. <AR>, <SK>, ...). Tnx DL7YEC
|
||||
|
||||
0.6.1 / 2008-02-09 Fabian Kurz <mail@fkurz.net>
|
||||
* Added more Cyrillic characters, the Greek and the Hebrew
|
||||
alphabet to the Unicode table. Some small corrections to
|
||||
the existing characters.
|
||||
* Command line switch -S with option either ISO or UTF prints
|
||||
a table of the available character set and the CW symbols
|
||||
in HTML format.
|
||||
|
||||
0.6.0 / 2008-02-05 Fabian Kurz <mail@fkurz.net>
|
||||
* Full ISO 8859-1 character set is now available
|
||||
* UTF-8 support by command line switch -u. Currently
|
||||
implemented: Latin, basic cyrillic.
|
||||
|
||||
0.5.1 / 2008-01-08 Fabian Kurz <mail@fkurz.net>
|
||||
* Fixed ID3 title (chapter number) generation.
|
||||
|
||||
0.5.0 / 2007-12-19 Fabian Kurz <mail@fkurz.net>
|
||||
* Added support for writing ID3 tags.
|
||||
* Added -Q command line switch: QRQ by 1 WpM every n minutes.
|
||||
|
||||
0.4.0 / 2007-12-17 Fabian Kurz <mail@fkurz.net>
|
||||
* Implemented dynamic memory allocation.
|
||||
|
||||
0.3.0 / 2007-11-28 Fabian Kurz <mail@fkurz.net>
|
||||
* Added forgotten characters: @ and /.
|
||||
|
||||
0.2.0 / 2007-11-27 Fabian Kurz <mail@fkurz.net>
|
||||
|
||||
* Fixed handling of umlauts (öäüß)
|
||||
* The chapter separator is now case sensitive.
|
||||
|
||||
0.1.0 / 2007-11-22 Fabian Kurz <mail@fkurz.net>
|
||||
|
||||
* Initial release of ebook2cw.
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
# ebook2cw Makefile -- Fabian Kurz, DJ1YFK -- http://fkurz.net/ham/ebook2cw.html
|
||||
|
||||
VERSION=0.6.3
|
||||
DESTDIR ?= /usr
|
||||
|
||||
all: ebook2cw
|
||||
|
||||
ebook2cw: ebook2cw.c codetables.h
|
||||
gcc ebook2cw.c -pedantic -Wall -lm -lmp3lame -D VERSION=\"$(VERSION)\" -o ebook2cw
|
||||
|
||||
static:
|
||||
gcc -static ebook2cw.c -lmp3lame -lm -D VERSION=\"$(VERSION)\" -o ebook2cw
|
||||
|
||||
install:
|
||||
install -d -v $(DESTDIR)/share/man/man1/
|
||||
install -d -v $(DESTDIR)/bin/
|
||||
install -s -m 0755 ebook2cw $(DESTDIR)/bin/
|
||||
install -m 0644 ebook2cw.1 $(DESTDIR)/share/man/man1/
|
||||
|
||||
uninstall:
|
||||
rm -f $(DESTDIR)/bin/ebook2cw
|
||||
rm -f $(DESTDIR)/share/man/man1/ebook2cw.1
|
||||
|
||||
clean:
|
||||
rm -f ebook2cw *~ *.mp3
|
||||
|
||||
dist:
|
||||
sed 's/v[0-9].[0-9].[0-9]/v$(VERSION)/g' README > README2
|
||||
rm -f README
|
||||
mv README2 README
|
||||
rm -f releases/ebook2cw-$(VERSION).tar.gz
|
||||
rm -rf releases/ebook2cw-$(VERSION)
|
||||
mkdir ebook2cw-$(VERSION)
|
||||
cp ebook2cw.c codetables.h ChangeLog ebook2cw.1 \
|
||||
README COPYING Makefile ebook2cw-$(VERSION)
|
||||
tar -zcf ebook2cw-$(VERSION).tar.gz ebook2cw-$(VERSION)
|
||||
mv ebook2cw-$(VERSION) releases/
|
||||
mv ebook2cw-$(VERSION).tar.gz releases/
|
||||
md5sum releases/*.gz > releases/md5sums.txt
|
||||
chmod a+r releases/*
|
||||
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
ebook2cw v0.6.3 - convert ebooks to morse mp3s - Fabian Kurz, DJ1YFK
|
||||
---------------------------------------------------------------------
|
||||
|
||||
Website: http://fkurz.net/ham/ebook2cw.html
|
||||
|
||||
ebook2cw is a command line program which converts a plain text ebook to morse
|
||||
code MP3 files. It works on several platforms, including Windows and Linux.
|
||||
|
||||
It automatically splits and numbers the output files by chapters.
|
||||
|
||||
For a detailled description, please refer to the man-page or the project
|
||||
website.
|
||||
|
||||
|
||||
INSTALL
|
||||
--------
|
||||
1) Binaries
|
||||
Statically compiled binaries are available at the project website, for Linux
|
||||
(i386) and Win32. Those should be suitable for most users.
|
||||
|
||||
2) Source
|
||||
A Makefile is included; it compiles both under Linux and Windows (with MinGW).
|
||||
DESTDIR is /usr by default (so the binary will be in /usr/bin/).
|
||||
|
||||
make [DESTDIR=..]
|
||||
make install
|
||||
|
|
@ -0,0 +1,550 @@
|
|||
/*
|
||||
* ISO 8859-1 and UTF-8 to Morse code mappings
|
||||
* This file is part of ebook2cw and may be used under the same terms (GPL)
|
||||
* (C) 2008 Fabian Kurz, DJ1YFK
|
||||
*
|
||||
* Currently included: ISO 8859-1
|
||||
* - complete (all that can somehow be mapped)
|
||||
* Unicode:
|
||||
* - Latin (basic, some extended)
|
||||
* - Cyrillic alphabet (KOI-7 + Serbian, Macedonian.. )
|
||||
* - Greek
|
||||
* - Hebrew
|
||||
*
|
||||
* Any comments, additions or corrections are welcome: mail@fkurz.net
|
||||
*
|
||||
*/
|
||||
|
||||
const static char *iso8859[] = {
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
" ", /* space */
|
||||
"..--.", /* ! */
|
||||
".-..-.", /* " */
|
||||
NULL, /* # */
|
||||
"...-..-", /* $ */
|
||||
NULL, /* % */
|
||||
". ...", /* & */
|
||||
".----.", /* ' */
|
||||
"-.--.", /* ( */
|
||||
"-.--.-", /* ) */
|
||||
NULL, /* * */
|
||||
".-.-.", /* + */
|
||||
"--..--", /* , */
|
||||
"-....-", /* - */
|
||||
".-.-.-", /* . */
|
||||
"-..-.", /* / */
|
||||
"-----", /* 0 */
|
||||
".----", /* 1 */
|
||||
"..---", /* 2 */
|
||||
"...--", /* 3 */
|
||||
"....-", /* 4 */
|
||||
".....", /* 5 */
|
||||
"-....", /* 6 */
|
||||
"--...", /* 7 */
|
||||
"---..", /* 8 */
|
||||
"----.", /* 9 */
|
||||
"---...", /* : */
|
||||
"-.-.-.", /* ; */
|
||||
NULL, /* < */
|
||||
"-...-", /* = */
|
||||
NULL, /* < */
|
||||
"..--..", /* ? */
|
||||
".--.-.", /* @ */
|
||||
".-", /* A */
|
||||
"-...", /* B */
|
||||
"-.-.",
|
||||
"-..",
|
||||
".",
|
||||
"..-.",
|
||||
"--.",
|
||||
"....",
|
||||
"..",
|
||||
".---",
|
||||
"-.-",
|
||||
".-..",
|
||||
"--",
|
||||
"-.",
|
||||
"---",
|
||||
".--.",
|
||||
"--.-",
|
||||
".-.",
|
||||
"...",
|
||||
"-",
|
||||
"..-",
|
||||
"...-",
|
||||
".--",
|
||||
"-..-",
|
||||
"-.--",
|
||||
"--..", /* Z */
|
||||
NULL, /* [ */
|
||||
"-..-.", /* \ */
|
||||
NULL, /* ] */
|
||||
NULL, /* ^ */
|
||||
NULL, /* _ */
|
||||
".----.", /* ` */
|
||||
".-", /* a */
|
||||
"-...", /* b */
|
||||
"-.-.",
|
||||
"-..",
|
||||
".",
|
||||
"..-.",
|
||||
"--.",
|
||||
"....",
|
||||
"..",
|
||||
".---",
|
||||
"-.-",
|
||||
".-..",
|
||||
"--",
|
||||
"-.",
|
||||
"---",
|
||||
".--.",
|
||||
"--.-",
|
||||
".-.",
|
||||
"...",
|
||||
"-",
|
||||
"..-",
|
||||
"...-",
|
||||
".--",
|
||||
"-..-",
|
||||
"-.--",
|
||||
"--..", /* z */
|
||||
NULL, /* { */
|
||||
NULL, /* | */
|
||||
NULL, /* } */
|
||||
NULL, /* ~ */
|
||||
NULL, /* DEL */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL,
|
||||
".-..-.", /* « (angle quotes, <<, 171) */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
".-..-.", /* » (angle quotes, >>, 187) */
|
||||
NULL, NULL, NULL, NULL,
|
||||
".--.-", /* `A */
|
||||
".--.-", /* 'A */
|
||||
".-", /* ^A */
|
||||
".-", /* ~A */
|
||||
".-.-", /* "A */
|
||||
".--.-", /* °A */
|
||||
".- .", /* AE */
|
||||
"-.-..", /* ,C */
|
||||
"..-..", /* `E */
|
||||
"..-..", /* 'E */
|
||||
".", /* ^E */
|
||||
".", /* "E */
|
||||
"..", /* `I */
|
||||
"..", /* 'I */
|
||||
"..", /* ^I */
|
||||
"..", /* "I */
|
||||
"..--.", /* -D */
|
||||
"--.--", /* ~N */
|
||||
"---", /* `O */
|
||||
"---", /* 'O */
|
||||
"---", /* ^O */
|
||||
"---", /* ~O */
|
||||
"---.", /* "O */
|
||||
NULL, /* x */
|
||||
"---.", /* /O */
|
||||
"..-", /* `U */
|
||||
"..-", /* 'U */
|
||||
"..-", /* ^U */
|
||||
"..--", /* "U */
|
||||
"-.--", /* 'Y */
|
||||
".--..", /* 'thorn' */
|
||||
"...--..", /* sz */
|
||||
".--.-", /* `a */
|
||||
".--.-", /* 'a */
|
||||
".-", /* ^a */
|
||||
".-", /* ~a */
|
||||
".-.-", /* "a */
|
||||
".--.-", /* °a */
|
||||
".- .", /* ae */
|
||||
"-.-..", /* ,c */
|
||||
"..-..", /* `e */
|
||||
"..-..", /* 'e */
|
||||
".", /* ^e */
|
||||
".", /* "e */
|
||||
"..", /* `i */
|
||||
"..", /* 'i */
|
||||
"..", /* ^i */
|
||||
"..", /* "i */
|
||||
"..--.", /* -d */
|
||||
"--.--", /* ~n */
|
||||
"---", /* `o */
|
||||
"---", /* 'o */
|
||||
"---", /* ^o */
|
||||
"---", /* ~o */
|
||||
"---.", /* "o */
|
||||
NULL, /* ./. */
|
||||
"---.", /* /o */
|
||||
"..-", /* `u */
|
||||
"..-", /* 'u */
|
||||
"..-", /* ^u */
|
||||
"..--", /* "u */
|
||||
"-.--", /* 'y */
|
||||
".--..", /* 'thorn' */
|
||||
"-.--" /* "y */
|
||||
};
|
||||
|
||||
const static char *utf8table[] = {
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* first 128 are identical*/
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* to iso8859, so that */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* will be used instead */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* - 127 */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* control characters ...*/
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* -159 */
|
||||
" ", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, ".-..-.", NULL, NULL, NULL, NULL, /* 171 << */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, ".-..-.", NULL, NULL, NULL, NULL, /* 187 >> */
|
||||
/* same as in ISO8859 */
|
||||
".--.-", /* `A */ /* 192 ... */
|
||||
".--.-", /* 'A */
|
||||
".-", /* ^A */
|
||||
".-", /* ~A */
|
||||
".-.-", /* "A */
|
||||
".--.-", /* °A */
|
||||
".- .", /* AE */
|
||||
"-.-..", /* ,C */
|
||||
"..-..", /* `E */
|
||||
"..-..", /* 'E */
|
||||
".", /* ^E */
|
||||
".", /* "E */
|
||||
"..", /* `I */
|
||||
"..", /* 'I */
|
||||
"..", /* ^I */
|
||||
"..", /* "I */
|
||||
"..--.", /* -D according to Wikipedia */
|
||||
"--.--", /* ~N */
|
||||
"---", /* `O */
|
||||
"---", /* 'O */
|
||||
"---", /* ^O */
|
||||
"---", /* ~O */
|
||||
"---.", /* "O */
|
||||
NULL, /* x */
|
||||
"---.", /* /O */
|
||||
"..-", /* `U */
|
||||
"..-", /* 'U */
|
||||
"..-", /* ^U */
|
||||
"..--", /* "U */
|
||||
"-.--", /* 'Y */
|
||||
".--..", /* 'thorn', acc to Wikipedia */
|
||||
"...--..", /* sz */
|
||||
".--.-", /* `a */
|
||||
".--.-", /* 'a */
|
||||
".-", /* ^a */
|
||||
".-", /* ~a */
|
||||
".-.-", /* "a */
|
||||
".--.-", /* °a */
|
||||
".- .", /* ae */
|
||||
"-.-..", /* ,c */
|
||||
"..-..", /* `e */
|
||||
"..-..", /* 'e */
|
||||
".", /* ^e */
|
||||
".", /* "e */
|
||||
"..", /* `i */
|
||||
"..", /* 'i */
|
||||
"..", /* ^i */
|
||||
"..", /* "i */
|
||||
"..--.", /* -d Wiki */
|
||||
"--.--", /* ~n */
|
||||
"---", /* `o */
|
||||
"---", /* 'o */
|
||||
"---", /* ^o */
|
||||
"---", /* ~o */
|
||||
"---.", /* "o */
|
||||
NULL, /* ./. */
|
||||
"---.", /* /o */
|
||||
"..-", /* `u */
|
||||
"..-", /* 'u */
|
||||
"..-", /* ^u */
|
||||
"..--", /* "u */
|
||||
"-.--", /* 'y */
|
||||
".--..", /* 'thorn' */
|
||||
"-.--", /* "y */ /* 255 */
|
||||
".-", ".-", ".-", ".-", ".-", ".-", /* 256-261, As with different hats */
|
||||
/* 262-269 Cs with different hats */
|
||||
/* 264-265 -.-.. acc. to Wikipedia, Esperanto etc. */
|
||||
"-.-.", "-.-.", "-.-..", "-.-..", "-.-.", "-.-.", "-.-.", "-.-.",
|
||||
"-..", "-..", "-..", "-..", /* 270-273 Ds with different stuff */
|
||||
/* 274-283 different Es */
|
||||
".", ".", ".", ".", ".", ".", ".", ".", ".", ".",
|
||||
/* 284-291 different Gs, first 2 according to Wikipedia (Esperanto) */
|
||||
"--.-.", "--.-.", "--.", "--.", "--.", "--.", "--.", "--.",
|
||||
/* 292-295 different Hs, first two Esperanto (was: -.--. before, but was
|
||||
* changed: "Originale, Hx estis -.--. sed tio kolizie estas "(" en ITU-T
|
||||
* F.1, do Hx nun prefere estas ----") */
|
||||
"----", "----", "....", "....",
|
||||
/* 296-305 different Is */
|
||||
"..", "..", "..", "..", "..", "..", "..", "..", "..", "..",
|
||||
/* 306-307 IJ ligatures */
|
||||
".. .---", ".. .---",
|
||||
/* 308-309 Js, from Wikipedia, Esperanto */
|
||||
".---.", ".---.",
|
||||
/* 310-312 Ks */
|
||||
"-.-", "-.-", "-.-",
|
||||
/* 313-322 different Ls */
|
||||
".-..", ".-..", ".-..", ".-..", ".-..", ".-..", ".-..",
|
||||
".-..", ".-..", ".-..",
|
||||
/* 323-331 different Ns */
|
||||
"-.", "-.", "-.", "-.", "-.", "-.", "-.", "-.", "-.",
|
||||
/* 332-337 Os */
|
||||
"---", "---", "---", "---", "---", "---",
|
||||
/* 338-339 OEs */
|
||||
"---.", "---.",
|
||||
/* 340-345 Rs */
|
||||
".-.", ".-.", ".-.", ".-.", ".-.", ".-.",
|
||||
/* 346-353 Ss, Wikipedia */
|
||||
"...", "...", "...-.", "...-.", "...", "...", "...", "...",
|
||||
/* 354-359 Ts */
|
||||
"-", "-", "-", "-", "-", "-",
|
||||
/* 360-371 Us, 364. 365 Esperanto */
|
||||
"..-", "..-", "..-", "..-", "..--", "..--", "..-", "..-", "..-",
|
||||
"..-", "..-", "..-",
|
||||
/* 372-373 Ws */
|
||||
".--", ".--",
|
||||
/* 374-377 Ys */
|
||||
"-.--", "-.--", "-.--",
|
||||
/* 377-382 Zs */
|
||||
"--..", "--..", "--..", "--..", "--..", "--..",
|
||||
/* 383 S */
|
||||
"...",
|
||||
/* 384-389 Bs */
|
||||
"-...", "-...", "-...", "-...", "-...", "-...",
|
||||
NULL, NULL, NULL, /* all kind of weird stuff */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL,
|
||||
/* Standard Greek Alphabet */
|
||||
".-", "-..." , "--.", "-..", ".", "--..", "....",
|
||||
"-.-.", "..", "-.-", ".-..", "--", "-.", "-..-", "---",
|
||||
".--.", ".-.", NULL, "...", "-", "-.--", "..-.", "----",
|
||||
"--.-", ".--", NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 1023 */
|
||||
|
||||
/* 1024-1039, cyrillic (Serbian, Macedonian, Ukrainian) UC */
|
||||
".", ".", "-.. .---", "--. .---", ".", "-.. --..", "..", "..",
|
||||
".---", ".-.. .---", "-. .---", "-.-.", "-.- .---", "..", "..-","-.. --..",
|
||||
|
||||
/* 32 letters of Russian Cyrillic alphabet */
|
||||
".-", "-...", ".--", "--.", "-..", ".", "...-", /* 1040-1071 */
|
||||
"--..", "..",".---", "-.-", ".-..", "--", "-.", /* uppercase */
|
||||
"---", ".--.", ".-.", "...", "-", "..-", "..-.", /* cyrillic */
|
||||
"....", "-.-.", "---.", "----", "--.-", "-..-",
|
||||
"-.--", "-..-", "..-..", "..--", ".-.-",
|
||||
".-", "-...", ".--", "--.", "-..", ".", "...-", /* 1072-1103 */
|
||||
"--..", "..",".---", "-.-", ".-..", "--", "-.", /* lowercase */
|
||||
"---", ".--.", ".-.", "...", "-", "..-", "..-.", /* cyrillic */
|
||||
"....", "-.-.", "---.", "----", "--.-", "-..-",
|
||||
"-.--", "-..-", "..-..", "..--", ".-.-",
|
||||
|
||||
/* 1004-1119, cyrillic (Serbian, Macedonian, Ukrainian) UC */
|
||||
".", ".", "-.. .---", "--. .---", ".", "-.. --..", "..", "..",
|
||||
".---", ".-.. .---", "-. .---", "-.-.", "-.- .---", "..", "..-","-.. --..",
|
||||
|
||||
/* 1120 - 1487 to be done... */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/* 1488-1514 Hebrew according to Wikipedia */
|
||||
".-", "-...", "--.", "-..", "---", ".", "--..", "....",
|
||||
"..-", "..", NULL, "-.-", ".-..", NULL, "--", "-.", NULL,
|
||||
"-.-.", ".---", NULL, ".--.", NULL, ".--", "--.-", ".-.", "...",
|
||||
"-", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/* Arabic Alphabet, as per Wikipedia.
|
||||
* Nobody is possibly ever going to use this :-)
|
||||
* 1569-1610
|
||||
*/
|
||||
".", NULL, NULL, NULL, NULL, NULL,
|
||||
".-", "-...", NULL, "-", "-.-.",
|
||||
".---", "....", "---", "-..", "--..", ".-.", "---.", "...",
|
||||
"----", "-..-", "...-", "..-", "-.--", ".-.-", "--.", NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, "..-.", "--.-", "-.-",
|
||||
".-..", "--", "-.", NULL, ".--", NULL, "..", NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL /* 1920 */
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
.TH ebook2cw 1 "MARCH 2008" Linux "User Manuals"
|
||||
.SH NAME
|
||||
ebook2cw \- convert ebooks to morse mp3s
|
||||
.SH SYNOPSIS
|
||||
.B ebook2cw
|
||||
[OPTIONS]
|
||||
.SH DESCRIPTION
|
||||
.B ebook2cw
|
||||
ebook2cw is a command line program which converts a plain text ebook to morse
|
||||
code MP3 files. It works on several platforms, including Windows and Linux.
|
||||
|
||||
A number of CW and MP3 parameters can be changed from their default values, by
|
||||
command line switches. These are (default values in brackets):
|
||||
|
||||
.B -w wpm
|
||||
- CW speed in words per minute [25]
|
||||
|
||||
.B -f freq
|
||||
- audio frequency in Hz [600]
|
||||
|
||||
.B -Q minutes
|
||||
- Increase CW speed (QRQ) by 1 WpM in intervals of `minutes'. Speed will be
|
||||
reset to the initial value at the start of each chapter. [0]
|
||||
|
||||
.B -R risetime
|
||||
- risetime, in samples [50]
|
||||
|
||||
.B -F falltime
|
||||
- falltime, samples [50]
|
||||
|
||||
.B -s samplerate
|
||||
- samplerate for the MP3 file [11025]
|
||||
|
||||
.B -b bitrate
|
||||
- MP3 bitrate, kbps [16]
|
||||
|
||||
.B -q quality
|
||||
- MP3 quality, 1 (best) to 9 (worst). CW still sounds very good with the worst quality, encoding time is greatly reduced. [5]
|
||||
|
||||
.B -c chapter separator
|
||||
- Split chapters at this string. Must be pure ASCII if UTF-8 is used. [CHAPTER]
|
||||
|
||||
.B -o outfile-name
|
||||
- Output filename (chapter number and .mp3 will be appended) [Chapter]
|
||||
|
||||
.B -a author
|
||||
- Author for the ID3 tag. Use quotes for strings with spaces (e.g. "JW Goethe")
|
||||
|
||||
.B -t title
|
||||
- Title for the ID3 tag. Use quotes for strings with spaces (e.g. "Faust II")
|
||||
|
||||
.B -k comment
|
||||
- Comment for the ID3 tag. Use quotes for strings with spaces.
|
||||
|
||||
.B -y year
|
||||
- Year for the ID3 tag.
|
||||
|
||||
.B -u
|
||||
- Switches input encoding format to UTF-8. Currentply supported alphabets include Latin, Greek, Hebrew and Cyrillic. Default is ISO 8859-1.
|
||||
|
||||
.B -S [ISO|UTF]
|
||||
- Shows a table of all available morse symbols for the ISO 8859-1 and UTF-8
|
||||
character sets. Output in HTML format.
|
||||
|
||||
CW prosigns can be generated by enclosing arbitrary letters in angle brackets
|
||||
(e.g. <AR>, <SK>, ...).
|
||||
|
||||
.SH AUTHOR
|
||||
Fabian Kurz, DJ1YFK <mail@fkurz.net>
|
||||
|
||||
http://fkurz.net/ham/ebook2cw.html
|
||||
.SH "SEE ALSO"
|
||||
.BR morse (1)
|
||||
|
|
@ -0,0 +1,586 @@
|
|||
/*
|
||||
ebook2cw - converts an ebook to morse mp3s
|
||||
|
||||
Copyright (C) 2008 Fabian Kurz, DJ1YFK
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 2 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
|
||||
Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
source code looks properly indented with tw=4
|
||||
|
||||
*/
|
||||
|
||||
#include "lame/lame.h"
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "codetables.h"
|
||||
|
||||
#ifndef VERSION
|
||||
#define VERSION "0.0.0"
|
||||
#endif
|
||||
|
||||
#define PCMBUFFER 220500 /* 20 seconds at 11kHz, for one word. plenty. */
|
||||
#define MP3BUFFER 285000 /* abt 1.25*PCMBUFFER + 7200, as recommended */
|
||||
|
||||
#define ISO8859 0
|
||||
#define UTF8 1
|
||||
|
||||
lame_global_flags *gfp;
|
||||
|
||||
FILE *outfile;
|
||||
FILE *infile;
|
||||
|
||||
/* MP3 samplerate, bitrate, quality. */
|
||||
int samplerate = 11025;
|
||||
int brate = 16;
|
||||
int quality = 5;
|
||||
|
||||
/* CW parameters */
|
||||
int wpm = 25;
|
||||
int freq = 600;
|
||||
int rt = 50; /* rise/fall time in samples */
|
||||
int ft = 50;
|
||||
int qrq = 0; /* rise speed by 1 WpM every qrq minutes */
|
||||
|
||||
/* the buffers for dit, dah, raw pcm and mp3 output, will me calloc'ed to the
|
||||
* default values, and if needed realloc'ed to the needed size */
|
||||
|
||||
short int *dit_buf;
|
||||
short int *dah_buf;
|
||||
short int *inpcm;
|
||||
unsigned char *mp3buffer;
|
||||
|
||||
int inpcm_size;
|
||||
int mp3buffer_size;
|
||||
|
||||
int ditlen=0; /* number of samples in a 'dit' */
|
||||
|
||||
/* Chapters are split by this string */
|
||||
char chapterstr[80]="CHAPTER";
|
||||
char chapterfilename[80]="Chapter"; /* full filename: Chapter%02d.mp3 */
|
||||
|
||||
/* ID3-tag data: author and title */
|
||||
char id3_author[80]="CW-Book";
|
||||
char id3_title[80]="";
|
||||
char id3_comment[80]="";
|
||||
char id3_year[5]="";
|
||||
|
||||
/* functions */
|
||||
int init_cw (int wpm, int freq, int rt, int ft);
|
||||
void help (void);
|
||||
void showcodes (int i);
|
||||
void makeword(char * text, int encoding);
|
||||
void closefile (int letter, int cw);
|
||||
void openfile (int chapter);
|
||||
|
||||
/* main */
|
||||
|
||||
int main (int argc, char** argv) {
|
||||
int pos, i, original_wpm;
|
||||
int encoding = ISO8859;
|
||||
int c;
|
||||
char word[1024]=""; /* will be cut when > 1024 chars long */
|
||||
int chapter = 0;
|
||||
int cw = 0, tw = 0, qw = 0; /* chapter words, total words, qrq words */
|
||||
|
||||
infile = stdin;
|
||||
|
||||
while((i = getopt(argc, argv, "o:w:f:R:F:s:b:q:c:a:t:k:y:Q:S:hu")) != -1) {
|
||||
switch (i) {
|
||||
case 'w':
|
||||
if ((wpm = atoi(optarg)) < 1) {
|
||||
fprintf(stderr, "Error: Speed (-w) must be > 0!\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
case 'f':
|
||||
freq = atoi(optarg);
|
||||
break;
|
||||
case 'R':
|
||||
rt = atoi(optarg);
|
||||
break;
|
||||
case 'F':
|
||||
ft = atoi(optarg);
|
||||
break;
|
||||
case 's':
|
||||
samplerate = atoi(optarg);
|
||||
break;
|
||||
case 'b':
|
||||
brate = atoi(optarg);
|
||||
break;
|
||||
case 'q':
|
||||
quality = atoi(optarg);
|
||||
break;
|
||||
case 'c':
|
||||
strncpy(chapterstr, optarg, 78);
|
||||
break;
|
||||
case 'o':
|
||||
strncpy(chapterfilename, optarg, 78);
|
||||
break;
|
||||
case 'a':
|
||||
strncpy(id3_author, optarg, 78);
|
||||
break;
|
||||
case 't':
|
||||
strncpy(id3_title, optarg, 75);
|
||||
break;
|
||||
case 'k':
|
||||
strncpy(id3_comment, optarg, 78);
|
||||
break;
|
||||
case 'y':
|
||||
strncpy(id3_year, optarg, 4);
|
||||
break;
|
||||
case 'Q':
|
||||
if ((qrq = atoi(optarg)) < 1) {
|
||||
fprintf(stderr, "Error: QRQ time (-Q) must be > 0!\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
case 'u':
|
||||
encoding = UTF8;
|
||||
break;
|
||||
case 'S':
|
||||
if (strstr(optarg, "ISO")) {
|
||||
showcodes(1);
|
||||
}
|
||||
else {
|
||||
showcodes(0);
|
||||
}
|
||||
case 'h':
|
||||
default:
|
||||
help();
|
||||
} /* switch */
|
||||
} /* while */
|
||||
|
||||
if (optind < argc) { /* something left? if so, use as infile */
|
||||
if ((argv[optind][0] != '-') && (argv[optind][0] != '\0')) {
|
||||
if ((infile = fopen(argv[optind], "r")) == NULL) {
|
||||
fprintf(stderr, "Error: Cannot open file %s. Exit.\n",
|
||||
argv[optind]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf("ebook2cw %s - (c) 2008 by Fabian Kurz, DJ1YFK\n", VERSION);
|
||||
printf("Speed: %d WpM, Freq: %dHz, Chapter: >%s<, Encoding: %s\n\n",
|
||||
wpm, freq, chapterstr, encoding == UTF8 ? "UTF-8" : "ISO 8859-1");
|
||||
|
||||
|
||||
/* init lame */
|
||||
gfp = lame_init();
|
||||
lame_set_num_channels(gfp,1);
|
||||
lame_set_in_samplerate(gfp, samplerate);
|
||||
lame_set_brate(gfp, brate);
|
||||
lame_set_mode(gfp,1);
|
||||
lame_set_quality(gfp, quality);
|
||||
|
||||
if (lame_init_params(gfp) < 0) {
|
||||
fprintf(stderr, "Failed: lame_init_params(gfp) \n");
|
||||
return(1);
|
||||
}
|
||||
else {
|
||||
printf("Initialized lame: samplerate=%d, bitrate=%d, quality=%d\n",
|
||||
samplerate, brate, quality);
|
||||
}
|
||||
|
||||
/* init pcm_buf and mp3_buf */
|
||||
|
||||
if ((inpcm = calloc(PCMBUFFER, sizeof(short int))) == NULL) {
|
||||
fprintf(stderr, "Error: Can't allocate inpcm[%d]!\n", PCMBUFFER);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
else {
|
||||
inpcm_size = PCMBUFFER;
|
||||
}
|
||||
|
||||
if ((mp3buffer = calloc(MP3BUFFER, sizeof(unsigned char))) == NULL) {
|
||||
fprintf(stderr, "Error: Can't allocate mp3buffer[%d]!\n", MP3BUFFER);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
else {
|
||||
mp3buffer_size = MP3BUFFER;
|
||||
}
|
||||
|
||||
ditlen = init_cw(wpm, freq, rt, ft); /* generate raw dit, dah */
|
||||
|
||||
strcat(chapterstr, " ");
|
||||
|
||||
/* read STDIN, assemble full words (anything ending in ' ') to 'word' and
|
||||
* generate CW, write to file by 'makeword'. words with > 1024 characters
|
||||
* will be split */
|
||||
|
||||
original_wpm = wpm; /* may be changed by QRQing */
|
||||
chapter = 0;
|
||||
openfile(chapter);
|
||||
|
||||
pos=0;
|
||||
while ((c = getc(infile)) != EOF) {
|
||||
|
||||
if (c == '\r') /* DOS linebreaks */
|
||||
continue;
|
||||
|
||||
word[pos++] = c;
|
||||
|
||||
if ((c == ' ') || (c == '\n') || (pos == 1024)) {
|
||||
word[pos] = '\0';
|
||||
if (strcmp(chapterstr, word) == 0) { /* new chapter */
|
||||
closefile(chapter, cw);
|
||||
cw=0;
|
||||
chapter++;
|
||||
|
||||
/* restore to initial speed if we're QRQing */
|
||||
if (qrq) {
|
||||
wpm = original_wpm;
|
||||
ditlen = init_cw(wpm, freq, rt, ft);
|
||||
}
|
||||
|
||||
openfile(chapter);
|
||||
}
|
||||
makeword(word, encoding);
|
||||
cw++; tw++; qw++;
|
||||
|
||||
word[0] = '\0';
|
||||
pos = 0;
|
||||
|
||||
/* every 'qrq' minutes (qrq*wpm words), speed up 1 WpM */
|
||||
if (qw == (qrq*wpm)) {
|
||||
wpm += 1;
|
||||
ditlen = init_cw(wpm, freq, rt, ft);
|
||||
qw = 0;
|
||||
}
|
||||
} /* word */
|
||||
} /* eof */
|
||||
|
||||
closefile(chapter, cw);
|
||||
|
||||
free(mp3buffer);
|
||||
free(inpcm);
|
||||
|
||||
/* factor 0.9 due to many 'words' which aren't actually words, like '\n' */
|
||||
printf("Total words: %d, total time: %d min\n", tw, (int) ((tw/wpm)*0.9));
|
||||
|
||||
lame_close(gfp);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* init_cw - generates a dit and a dah to dit_buf and dah_buf */
|
||||
|
||||
int init_cw (int wpm, int freq, int rt, int ft) {
|
||||
int x;
|
||||
int len;
|
||||
double val;
|
||||
|
||||
printf("Initializing CW buffers at %d WpM: ", wpm);
|
||||
|
||||
/* dah */
|
||||
len = (int) (3.0*6.0*samplerate/(5.0*wpm)); /* in samples */
|
||||
|
||||
/* ditlen not set == init_cw has not been called yet */
|
||||
if (!ditlen) {
|
||||
/* allocate memory for the buffer */
|
||||
if ((dah_buf = calloc(len, sizeof(short int))) == NULL) {
|
||||
fprintf(stderr, "Error: Can't allocate dah_buf[%d]\n", len);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
for (x=0; x < len; x++) {
|
||||
val = sin(2*M_PI*freq*x/samplerate);
|
||||
if (x < rt) /* shaping with sin^2 */
|
||||
val *= pow(sin(M_PI*x/(2.0*rt)),2);
|
||||
|
||||
if (x > (len-ft))
|
||||
val *= pow((sin(2*M_PI*(x-(len-ft)+ft)/(4*ft))), 2);
|
||||
|
||||
dah_buf[x] = (short int) (val * 20000.0);
|
||||
}
|
||||
|
||||
printf("dah_buf[%d], ", x);
|
||||
|
||||
/* dit */
|
||||
len = (int) (6.0*samplerate/(5.0*wpm)); /* in samples */
|
||||
|
||||
/* ditlen not set == init_cw has not been called yet */
|
||||
if (!ditlen) {
|
||||
/* allocate memory for the buffer */
|
||||
if ((dit_buf = calloc(len, sizeof(short int))) == NULL) {
|
||||
fprintf(stderr, "Error: Can't allocate dit_buf[%d]\n", len);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
for (x=0; x < len; x++) {
|
||||
val = sin(2*M_PI*freq*x/samplerate);
|
||||
if (x < rt)
|
||||
val *= pow(sin(M_PI*x/(2.0*rt)), 2);
|
||||
|
||||
if (x > (len-ft))
|
||||
val *= pow((sin(2*M_PI*(x-(len-ft)+ft)/(4*ft))), 2);
|
||||
|
||||
dit_buf[x] = (short int) (val * 20000.0);
|
||||
}
|
||||
|
||||
printf("dit_buf[%d]\n\n", x);
|
||||
|
||||
return x; /* = length of dit/silence */
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* makeword -- converts 'text' to CW by concatenating dit_buf amd dah_bufs,
|
||||
* encodes this to MP3 and writes to open filehandle outfile */
|
||||
|
||||
void makeword(char * text, int encoding) {
|
||||
const char *code; /* CW code as . and - */
|
||||
int outbytes;
|
||||
|
||||
int c;
|
||||
int i,u,w;
|
||||
int j;
|
||||
int prosign = 0;
|
||||
unsigned char last=0; /* for utf8 2-byte characters */
|
||||
|
||||
j = 0; /* position in 'inpcm' buffer */
|
||||
|
||||
for (i = 0; i < strlen(text); i++) {
|
||||
c = (unsigned char) text[i];
|
||||
code = NULL;
|
||||
|
||||
if (c == '\n') { /* Same for UTF8 and ISO8859 */
|
||||
if (strlen(text) == 1) /* paragraph */
|
||||
code = " -...- ";
|
||||
else
|
||||
code = " ";
|
||||
}
|
||||
else if (c == '<') { /* prosign on */
|
||||
prosign = 1;
|
||||
continue;
|
||||
}
|
||||
else if ((c == '>') && prosign) { /* prosign off */
|
||||
prosign = 0;
|
||||
code = ""; /* only inserts letter space */
|
||||
}
|
||||
else if (encoding == ISO8859) {
|
||||
code = iso8859[c];
|
||||
}
|
||||
else if (encoding == UTF8) {
|
||||
/* Character may be 1-byte ASCII or 2-byte UTF8 */
|
||||
if (!(c & 128)) { /* MSB = 0 -> 7bit ASCII */
|
||||
code = iso8859[c]; /* subset of iso8859 */
|
||||
}
|
||||
else {
|
||||
if (last && (c < 192) ) { /* this is the 2nd byte */
|
||||
/* 110yyyyy 10zzzzzz -> 00000yyy yyzzzzzz */
|
||||
c = ((last & 31) << 6) | (c & 63);
|
||||
code = utf8table[c];
|
||||
last = 0;
|
||||
}
|
||||
else {
|
||||
last = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (last) continue; /* first of two-byte character read */
|
||||
|
||||
/* Not found anything ... */
|
||||
if (code == NULL) {
|
||||
code = " ";
|
||||
if (c < 255) {
|
||||
fprintf(stderr, "Warning: don't know CW for '%c'\n", c);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "Warning: don't know CW for unicode &#%d;\n", c);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* code contains letter as ./-, now assemble pcm buffer */
|
||||
|
||||
for (w = 0; w < strlen(code) ; w++) {
|
||||
|
||||
/* make sure the inpcm buffer doesn't run full,
|
||||
* with a conservative margin. reallocate memory if neccesary */
|
||||
if (j > inpcm_size-(6*ditlen)) {
|
||||
inpcm_size += (6*ditlen);
|
||||
mp3buffer_size += (8*ditlen + 7200);
|
||||
if ((inpcm = realloc(inpcm, inpcm_size*sizeof(short int)))== NULL)
|
||||
fprintf(stderr, "Error: Can't realloc inpcm[%d]\n", inpcm_size);
|
||||
|
||||
if ((mp3buffer = realloc(mp3buffer, mp3buffer_size*sizeof(char)))
|
||||
== NULL)
|
||||
fprintf(stderr, "Error: Can't realloc mp3buffer[%d]\n",
|
||||
mp3buffer_size);
|
||||
}
|
||||
|
||||
c = code[w];
|
||||
|
||||
if (c == '.')
|
||||
for (u=0; u < ditlen; u++)
|
||||
inpcm[++j] = dit_buf[u];
|
||||
else if (c == '-')
|
||||
for (u=0; u < (3*ditlen); u++)
|
||||
inpcm[++j] = dah_buf[u];
|
||||
else
|
||||
for (u=0; u < ditlen; u++)
|
||||
inpcm[++j] = 0;
|
||||
|
||||
for (u=0; u < ditlen; u++) /* space of one dit length */
|
||||
inpcm[++j] = 0;
|
||||
} /* foreach dot/dash */
|
||||
|
||||
if (prosign == 0) {
|
||||
for (u=0; u < (2*ditlen); u++)
|
||||
inpcm[++j] = 0;
|
||||
}
|
||||
|
||||
} /* foreach letter */
|
||||
|
||||
/* j = total length of samples in 'inpcm' */
|
||||
|
||||
outbytes = lame_encode_buffer(gfp, inpcm, inpcm, j, mp3buffer, mp3buffer_size);
|
||||
if (outbytes < 0) {
|
||||
fprintf(stderr, "Error: lame_encode_buffer returned %d. Exit.\n", outbytes);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (fwrite(mp3buffer, sizeof(char), outbytes, outfile) != outbytes) {
|
||||
fprintf(stderr, "Error: Writing %db to file failed. Exit.\n", outbytes);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* closefile -- finishes writing the current file, flushes the encoder buffer */
|
||||
|
||||
void closefile (int letter, int cw) {
|
||||
int outbytes;
|
||||
char mp3filename[80] = "";
|
||||
|
||||
printf("words: %d, minutes: %d\n", cw, (int) ((cw/wpm)*0.9));
|
||||
|
||||
snprintf(mp3filename, 80, "%s%02d.mp3", chapterfilename, letter);
|
||||
printf("Finishing %s\n\n", mp3filename);
|
||||
|
||||
outbytes = lame_encode_flush(gfp, mp3buffer, mp3buffer_size);
|
||||
|
||||
if (outbytes < 0) {
|
||||
fprintf(stderr, "Error: lame_encode_buffer returned %d.\n", outbytes);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (fwrite(mp3buffer, sizeof(char), outbytes, outfile) != outbytes) {
|
||||
fprintf(stderr, "Error: Writing %db to file failed. Exit.\n", outbytes);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
fclose(outfile);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* openfile -- starts a new chapter by opening Chapter%d.mp3 */
|
||||
|
||||
void openfile (int chapter) {
|
||||
char mp3filename[80] = "";
|
||||
static char tmp[80] = "";
|
||||
|
||||
snprintf(mp3filename, 80, "%s%02d.mp3", chapterfilename, chapter);
|
||||
printf("Starting %s\n", mp3filename);
|
||||
|
||||
if ((outfile = fopen(mp3filename, "wb")) == NULL) {
|
||||
fprintf(stderr, "Error: Failed to open %s\n", mp3filename);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
snprintf(tmp, 79, "%s - %d", id3_title, chapter); /* generate title */
|
||||
|
||||
id3tag_init(gfp);
|
||||
id3tag_set_artist(gfp, id3_author);
|
||||
id3tag_set_year(gfp, id3_year);
|
||||
id3tag_set_title(gfp, tmp);
|
||||
id3tag_set_comment(gfp, id3_comment);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void help (void) {
|
||||
printf("ebook2cw v%s - (c) 2008 by Fabian Kurz, DJ1YFK, http://fkurz.net/\n", VERSION);
|
||||
printf("\nThis is free software, and you are welcome to redistribute it\n");
|
||||
printf("under certain conditions (see COPYING).\n");
|
||||
printf("\n");
|
||||
printf("ebook2cw [-w wpm] [-f freq] [-R risetime] [-F falltime]\n");
|
||||
printf(" [-s samplerate] [-b mp3bitrate] [-q mp3quality]\n");
|
||||
printf(" [-c chapter-separator] [-o outfile-name] [-Q minutes]\n");
|
||||
printf(" [-a author] [-t title] [-k comment] [-y year]\n");
|
||||
printf(" [-u] [-S ISO|UTF] [infile]\n\n");
|
||||
printf("defaults: 25 WpM, 600Hz, RT=FT=50, s=11025Hz, b=16kbps,\n");
|
||||
printf(" c=\"CHAPTER\", o=\"Chapter\" infile = stdin\n");
|
||||
printf("\n");
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* showcodes
|
||||
* Generates a HTML table of the available CW symbols in codetables.h
|
||||
* i = 1 -> ISO 8859-1, i=0 -> UTF-8
|
||||
*/
|
||||
|
||||
void showcodes (int i) {
|
||||
int k;
|
||||
int n = i ? 256 : 1921;
|
||||
|
||||
printf("<html><head><META HTTP-EQUIV=\"CONTENT-TYPE\" CONTENT=\"text/html;"
|
||||
"charset=%s\"></head>\n", i ? "iso-8859-1" : "utf-8");
|
||||
printf("<body><h1>ebook2cw codetables.h</h1>\n");
|
||||
printf("<h2>%s</h2><table border=\"1\">\n", i ? "ISO 8859-1" : "UTF-8");
|
||||
printf("<tr><th>Decimal</th><th>Symbol</th><th>CW</th></tr>\n");
|
||||
|
||||
for (k=0; k < n; k++) {
|
||||
printf("<tr>");
|
||||
|
||||
if ((k < 128+i*128) && (iso8859[k] != NULL)) {
|
||||
printf("<td>%d</td><td>&#%d;</td><td>%s</td>", k, k, iso8859[k]);
|
||||
}
|
||||
else if (utf8table[k] != NULL) {
|
||||
printf("<td>%d</td><td>&#%d;</td><td>%s</td>", k, k, utf8table[k]);
|
||||
}
|
||||
else {
|
||||
printf("<td>%d</td><td>&#%d;</td><td> </td>", k, k);
|
||||
}
|
||||
|
||||
printf("</tr>\n");
|
||||
}
|
||||
|
||||
printf("</table></body></html>\n");
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
Binary file not shown.
|
|
@ -0,0 +1,280 @@
|
|||
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
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
0.6.4 / 2008-05-20 Fabian Kurz <mail@fkurz.net>
|
||||
* Added "Farnsworth" spacing (-e) and extra inter-word spacing (-W)
|
||||
[suggested by DL3OBQ]
|
||||
* Reset to original speed when using QRQ (-Q) at each new chapter can now
|
||||
be disabled (-n) [suggested by W2UP]
|
||||
|
||||
0.6.3 / 2008-03-10 Fabian Kurz <mail@fkurz.net>
|
||||
* Added the Arabic morse code alphabet
|
||||
* Added/changed Unicode characters for Esperanto
|
||||
|
||||
0.6.2 / 2008-02-20 Fabian Kurz <mail@fkurz.net>
|
||||
* Support for arbitrary prosigns added. To generate a prosign
|
||||
enclose the letters in angle brackets (e.g. <AR>, <SK>, ...). [tnx DL7YEC]
|
||||
|
||||
0.6.1 / 2008-02-09 Fabian Kurz <mail@fkurz.net>
|
||||
* Added more Cyrillic characters, the Greek and the Hebrew
|
||||
alphabet to the Unicode table. Some small corrections to
|
||||
the existing characters.
|
||||
* Command line switch -S with option either ISO or UTF prints
|
||||
a table of the available character set and the CW symbols
|
||||
in HTML format.
|
||||
|
||||
0.6.0 / 2008-02-05 Fabian Kurz <mail@fkurz.net>
|
||||
* Full ISO 8859-1 character set is now available
|
||||
* UTF-8 support by command line switch -u. Currently
|
||||
implemented: Latin, basic cyrillic.
|
||||
|
||||
0.5.1 / 2008-01-08 Fabian Kurz <mail@fkurz.net>
|
||||
* Fixed ID3 title (chapter number) generation.
|
||||
|
||||
0.5.0 / 2007-12-19 Fabian Kurz <mail@fkurz.net>
|
||||
* Added support for writing ID3 tags.
|
||||
* Added -Q command line switch: QRQ by 1 WpM every n minutes.
|
||||
|
||||
0.4.0 / 2007-12-17 Fabian Kurz <mail@fkurz.net>
|
||||
* Implemented dynamic memory allocation.
|
||||
|
||||
0.3.0 / 2007-11-28 Fabian Kurz <mail@fkurz.net>
|
||||
* Added forgotten characters: @ and /.
|
||||
|
||||
0.2.0 / 2007-11-27 Fabian Kurz <mail@fkurz.net>
|
||||
|
||||
* Fixed handling of umlauts (öäüß)
|
||||
* The chapter separator is now case sensitive.
|
||||
|
||||
0.1.0 / 2007-11-22 Fabian Kurz <mail@fkurz.net>
|
||||
|
||||
* Initial release of ebook2cw.
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
# ebook2cw Makefile -- Fabian Kurz, DJ1YFK -- http://fkurz.net/ham/ebook2cw.html
|
||||
|
||||
VERSION=0.6.4
|
||||
DESTDIR ?= /usr
|
||||
|
||||
all: ebook2cw
|
||||
|
||||
ebook2cw: ebook2cw.c codetables.h
|
||||
gcc ebook2cw.c -pedantic -Wall -lm -lmp3lame -D VERSION=\"$(VERSION)\" -o ebook2cw
|
||||
|
||||
static:
|
||||
gcc -static ebook2cw.c -lmp3lame -lm -D VERSION=\"$(VERSION)\" -o ebook2cw
|
||||
|
||||
install:
|
||||
install -d -v $(DESTDIR)/share/man/man1/
|
||||
install -d -v $(DESTDIR)/bin/
|
||||
install -s -m 0755 ebook2cw $(DESTDIR)/bin/
|
||||
install -m 0644 ebook2cw.1 $(DESTDIR)/share/man/man1/
|
||||
|
||||
uninstall:
|
||||
rm -f $(DESTDIR)/bin/ebook2cw
|
||||
rm -f $(DESTDIR)/share/man/man1/ebook2cw.1
|
||||
|
||||
clean:
|
||||
rm -f ebook2cw *~ *.mp3
|
||||
|
||||
dist:
|
||||
sed 's/v[0-9].[0-9].[0-9]/v$(VERSION)/g' README > README2
|
||||
rm -f README
|
||||
mv README2 README
|
||||
rm -f releases/ebook2cw-$(VERSION).tar.gz
|
||||
rm -rf releases/ebook2cw-$(VERSION)
|
||||
mkdir ebook2cw-$(VERSION)
|
||||
cp ebook2cw.c codetables.h ChangeLog ebook2cw.1 \
|
||||
README COPYING Makefile ebook2cw-$(VERSION)
|
||||
tar -zcf ebook2cw-$(VERSION).tar.gz ebook2cw-$(VERSION)
|
||||
mv ebook2cw-$(VERSION) releases/
|
||||
mv ebook2cw-$(VERSION).tar.gz releases/
|
||||
md5sum releases/*.gz > releases/md5sums.txt
|
||||
chmod a+r releases/*
|
||||
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
ebook2cw v0.6.4 - convert ebooks to morse mp3s - Fabian Kurz, DJ1YFK
|
||||
---------------------------------------------------------------------
|
||||
|
||||
Website: http://fkurz.net/ham/ebook2cw.html
|
||||
|
||||
ebook2cw is a command line program which converts a plain text ebook to morse
|
||||
code MP3 files. It works on several platforms, including Windows and Linux.
|
||||
|
||||
It automatically splits and numbers the output files by chapters.
|
||||
|
||||
For a detailled description, please refer to the man-page or the project
|
||||
website.
|
||||
|
||||
|
||||
INSTALL
|
||||
--------
|
||||
1) Binaries
|
||||
Statically compiled binaries are available at the project website, for Linux
|
||||
(i386) and Win32. Those should be suitable for most users.
|
||||
|
||||
2) Source
|
||||
A Makefile is included; it compiles both under Linux and Windows (with MinGW).
|
||||
DESTDIR is /usr by default (so the binary will be in /usr/bin/).
|
||||
|
||||
make [DESTDIR=..]
|
||||
make install
|
||||
|
|
@ -0,0 +1,550 @@
|
|||
/*
|
||||
* ISO 8859-1 and UTF-8 to Morse code mappings
|
||||
* This file is part of ebook2cw and may be used under the same terms (GPL)
|
||||
* (C) 2008 Fabian Kurz, DJ1YFK
|
||||
*
|
||||
* Currently included: ISO 8859-1
|
||||
* - complete (all that can somehow be mapped)
|
||||
* Unicode:
|
||||
* - Latin (basic, some extended)
|
||||
* - Cyrillic alphabet (KOI-7 + Serbian, Macedonian.. )
|
||||
* - Greek
|
||||
* - Hebrew
|
||||
*
|
||||
* Any comments, additions or corrections are welcome: mail@fkurz.net
|
||||
*
|
||||
*/
|
||||
|
||||
const static char *iso8859[] = {
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
" ", /* space */
|
||||
"..--.", /* ! */
|
||||
".-..-.", /* " */
|
||||
NULL, /* # */
|
||||
"...-..-", /* $ */
|
||||
NULL, /* % */
|
||||
". ...", /* & */
|
||||
".----.", /* ' */
|
||||
"-.--.", /* ( */
|
||||
"-.--.-", /* ) */
|
||||
NULL, /* * */
|
||||
".-.-.", /* + */
|
||||
"--..--", /* , */
|
||||
"-....-", /* - */
|
||||
".-.-.-", /* . */
|
||||
"-..-.", /* / */
|
||||
"-----", /* 0 */
|
||||
".----", /* 1 */
|
||||
"..---", /* 2 */
|
||||
"...--", /* 3 */
|
||||
"....-", /* 4 */
|
||||
".....", /* 5 */
|
||||
"-....", /* 6 */
|
||||
"--...", /* 7 */
|
||||
"---..", /* 8 */
|
||||
"----.", /* 9 */
|
||||
"---...", /* : */
|
||||
"-.-.-.", /* ; */
|
||||
NULL, /* < */
|
||||
"-...-", /* = */
|
||||
NULL, /* < */
|
||||
"..--..", /* ? */
|
||||
".--.-.", /* @ */
|
||||
".-", /* A */
|
||||
"-...", /* B */
|
||||
"-.-.",
|
||||
"-..",
|
||||
".",
|
||||
"..-.",
|
||||
"--.",
|
||||
"....",
|
||||
"..",
|
||||
".---",
|
||||
"-.-",
|
||||
".-..",
|
||||
"--",
|
||||
"-.",
|
||||
"---",
|
||||
".--.",
|
||||
"--.-",
|
||||
".-.",
|
||||
"...",
|
||||
"-",
|
||||
"..-",
|
||||
"...-",
|
||||
".--",
|
||||
"-..-",
|
||||
"-.--",
|
||||
"--..", /* Z */
|
||||
NULL, /* [ */
|
||||
"-..-.", /* \ */
|
||||
NULL, /* ] */
|
||||
NULL, /* ^ */
|
||||
NULL, /* _ */
|
||||
".----.", /* ` */
|
||||
".-", /* a */
|
||||
"-...", /* b */
|
||||
"-.-.",
|
||||
"-..",
|
||||
".",
|
||||
"..-.",
|
||||
"--.",
|
||||
"....",
|
||||
"..",
|
||||
".---",
|
||||
"-.-",
|
||||
".-..",
|
||||
"--",
|
||||
"-.",
|
||||
"---",
|
||||
".--.",
|
||||
"--.-",
|
||||
".-.",
|
||||
"...",
|
||||
"-",
|
||||
"..-",
|
||||
"...-",
|
||||
".--",
|
||||
"-..-",
|
||||
"-.--",
|
||||
"--..", /* z */
|
||||
NULL, /* { */
|
||||
NULL, /* | */
|
||||
NULL, /* } */
|
||||
NULL, /* ~ */
|
||||
NULL, /* DEL */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL,
|
||||
".-..-.", /* « (angle quotes, <<, 171) */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
".-..-.", /* » (angle quotes, >>, 187) */
|
||||
NULL, NULL, NULL, NULL,
|
||||
".--.-", /* `A */
|
||||
".--.-", /* 'A */
|
||||
".-", /* ^A */
|
||||
".-", /* ~A */
|
||||
".-.-", /* "A */
|
||||
".--.-", /* °A */
|
||||
".- .", /* AE */
|
||||
"-.-..", /* ,C */
|
||||
"..-..", /* `E */
|
||||
"..-..", /* 'E */
|
||||
".", /* ^E */
|
||||
".", /* "E */
|
||||
"..", /* `I */
|
||||
"..", /* 'I */
|
||||
"..", /* ^I */
|
||||
"..", /* "I */
|
||||
"..--.", /* -D */
|
||||
"--.--", /* ~N */
|
||||
"---", /* `O */
|
||||
"---", /* 'O */
|
||||
"---", /* ^O */
|
||||
"---", /* ~O */
|
||||
"---.", /* "O */
|
||||
NULL, /* x */
|
||||
"---.", /* /O */
|
||||
"..-", /* `U */
|
||||
"..-", /* 'U */
|
||||
"..-", /* ^U */
|
||||
"..--", /* "U */
|
||||
"-.--", /* 'Y */
|
||||
".--..", /* 'thorn' */
|
||||
"...--..", /* sz */
|
||||
".--.-", /* `a */
|
||||
".--.-", /* 'a */
|
||||
".-", /* ^a */
|
||||
".-", /* ~a */
|
||||
".-.-", /* "a */
|
||||
".--.-", /* °a */
|
||||
".- .", /* ae */
|
||||
"-.-..", /* ,c */
|
||||
"..-..", /* `e */
|
||||
"..-..", /* 'e */
|
||||
".", /* ^e */
|
||||
".", /* "e */
|
||||
"..", /* `i */
|
||||
"..", /* 'i */
|
||||
"..", /* ^i */
|
||||
"..", /* "i */
|
||||
"..--.", /* -d */
|
||||
"--.--", /* ~n */
|
||||
"---", /* `o */
|
||||
"---", /* 'o */
|
||||
"---", /* ^o */
|
||||
"---", /* ~o */
|
||||
"---.", /* "o */
|
||||
NULL, /* ./. */
|
||||
"---.", /* /o */
|
||||
"..-", /* `u */
|
||||
"..-", /* 'u */
|
||||
"..-", /* ^u */
|
||||
"..--", /* "u */
|
||||
"-.--", /* 'y */
|
||||
".--..", /* 'thorn' */
|
||||
"-.--" /* "y */
|
||||
};
|
||||
|
||||
const static char *utf8table[] = {
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* first 128 are identical*/
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* to iso8859, so that */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* will be used instead */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* - 127 */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* control characters ...*/
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* -159 */
|
||||
" ", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, ".-..-.", NULL, NULL, NULL, NULL, /* 171 << */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, ".-..-.", NULL, NULL, NULL, NULL, /* 187 >> */
|
||||
/* same as in ISO8859 */
|
||||
".--.-", /* `A */ /* 192 ... */
|
||||
".--.-", /* 'A */
|
||||
".-", /* ^A */
|
||||
".-", /* ~A */
|
||||
".-.-", /* "A */
|
||||
".--.-", /* °A */
|
||||
".- .", /* AE */
|
||||
"-.-..", /* ,C */
|
||||
"..-..", /* `E */
|
||||
"..-..", /* 'E */
|
||||
".", /* ^E */
|
||||
".", /* "E */
|
||||
"..", /* `I */
|
||||
"..", /* 'I */
|
||||
"..", /* ^I */
|
||||
"..", /* "I */
|
||||
"..--.", /* -D according to Wikipedia */
|
||||
"--.--", /* ~N */
|
||||
"---", /* `O */
|
||||
"---", /* 'O */
|
||||
"---", /* ^O */
|
||||
"---", /* ~O */
|
||||
"---.", /* "O */
|
||||
NULL, /* x */
|
||||
"---.", /* /O */
|
||||
"..-", /* `U */
|
||||
"..-", /* 'U */
|
||||
"..-", /* ^U */
|
||||
"..--", /* "U */
|
||||
"-.--", /* 'Y */
|
||||
".--..", /* 'thorn', acc to Wikipedia */
|
||||
"...--..", /* sz */
|
||||
".--.-", /* `a */
|
||||
".--.-", /* 'a */
|
||||
".-", /* ^a */
|
||||
".-", /* ~a */
|
||||
".-.-", /* "a */
|
||||
".--.-", /* °a */
|
||||
".- .", /* ae */
|
||||
"-.-..", /* ,c */
|
||||
"..-..", /* `e */
|
||||
"..-..", /* 'e */
|
||||
".", /* ^e */
|
||||
".", /* "e */
|
||||
"..", /* `i */
|
||||
"..", /* 'i */
|
||||
"..", /* ^i */
|
||||
"..", /* "i */
|
||||
"..--.", /* -d Wiki */
|
||||
"--.--", /* ~n */
|
||||
"---", /* `o */
|
||||
"---", /* 'o */
|
||||
"---", /* ^o */
|
||||
"---", /* ~o */
|
||||
"---.", /* "o */
|
||||
NULL, /* ./. */
|
||||
"---.", /* /o */
|
||||
"..-", /* `u */
|
||||
"..-", /* 'u */
|
||||
"..-", /* ^u */
|
||||
"..--", /* "u */
|
||||
"-.--", /* 'y */
|
||||
".--..", /* 'thorn' */
|
||||
"-.--", /* "y */ /* 255 */
|
||||
".-", ".-", ".-", ".-", ".-", ".-", /* 256-261, As with different hats */
|
||||
/* 262-269 Cs with different hats */
|
||||
/* 264-265 -.-.. acc. to Wikipedia, Esperanto etc. */
|
||||
"-.-.", "-.-.", "-.-..", "-.-..", "-.-.", "-.-.", "-.-.", "-.-.",
|
||||
"-..", "-..", "-..", "-..", /* 270-273 Ds with different stuff */
|
||||
/* 274-283 different Es */
|
||||
".", ".", ".", ".", ".", ".", ".", ".", ".", ".",
|
||||
/* 284-291 different Gs, first 2 according to Wikipedia (Esperanto) */
|
||||
"--.-.", "--.-.", "--.", "--.", "--.", "--.", "--.", "--.",
|
||||
/* 292-295 different Hs, first two Esperanto (was: -.--. before, but was
|
||||
* changed: "Originale, Hx estis -.--. sed tio kolizie estas "(" en ITU-T
|
||||
* F.1, do Hx nun prefere estas ----") */
|
||||
"----", "----", "....", "....",
|
||||
/* 296-305 different Is */
|
||||
"..", "..", "..", "..", "..", "..", "..", "..", "..", "..",
|
||||
/* 306-307 IJ ligatures */
|
||||
".. .---", ".. .---",
|
||||
/* 308-309 Js, from Wikipedia, Esperanto */
|
||||
".---.", ".---.",
|
||||
/* 310-312 Ks */
|
||||
"-.-", "-.-", "-.-",
|
||||
/* 313-322 different Ls */
|
||||
".-..", ".-..", ".-..", ".-..", ".-..", ".-..", ".-..",
|
||||
".-..", ".-..", ".-..",
|
||||
/* 323-331 different Ns */
|
||||
"-.", "-.", "-.", "-.", "-.", "-.", "-.", "-.", "-.",
|
||||
/* 332-337 Os */
|
||||
"---", "---", "---", "---", "---", "---",
|
||||
/* 338-339 OEs */
|
||||
"---.", "---.",
|
||||
/* 340-345 Rs */
|
||||
".-.", ".-.", ".-.", ".-.", ".-.", ".-.",
|
||||
/* 346-353 Ss, Wikipedia */
|
||||
"...", "...", "...-.", "...-.", "...", "...", "...", "...",
|
||||
/* 354-359 Ts */
|
||||
"-", "-", "-", "-", "-", "-",
|
||||
/* 360-371 Us, 364. 365 Esperanto */
|
||||
"..-", "..-", "..-", "..-", "..--", "..--", "..-", "..-", "..-",
|
||||
"..-", "..-", "..-",
|
||||
/* 372-373 Ws */
|
||||
".--", ".--",
|
||||
/* 374-377 Ys */
|
||||
"-.--", "-.--", "-.--",
|
||||
/* 377-382 Zs */
|
||||
"--..", "--..", "--..", "--..", "--..", "--..",
|
||||
/* 383 S */
|
||||
"...",
|
||||
/* 384-389 Bs */
|
||||
"-...", "-...", "-...", "-...", "-...", "-...",
|
||||
NULL, NULL, NULL, /* all kind of weird stuff */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL,
|
||||
/* Standard Greek Alphabet */
|
||||
".-", "-..." , "--.", "-..", ".", "--..", "....",
|
||||
"-.-.", "..", "-.-", ".-..", "--", "-.", "-..-", "---",
|
||||
".--.", ".-.", NULL, "...", "-", "-.--", "..-.", "----",
|
||||
"--.-", ".--", NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 1023 */
|
||||
|
||||
/* 1024-1039, cyrillic (Serbian, Macedonian, Ukrainian) UC */
|
||||
".", ".", "-.. .---", "--. .---", ".", "-.. --..", "..", "..",
|
||||
".---", ".-.. .---", "-. .---", "-.-.", "-.- .---", "..", "..-","-.. --..",
|
||||
|
||||
/* 32 letters of Russian Cyrillic alphabet */
|
||||
".-", "-...", ".--", "--.", "-..", ".", "...-", /* 1040-1071 */
|
||||
"--..", "..",".---", "-.-", ".-..", "--", "-.", /* uppercase */
|
||||
"---", ".--.", ".-.", "...", "-", "..-", "..-.", /* cyrillic */
|
||||
"....", "-.-.", "---.", "----", "--.-", "-..-",
|
||||
"-.--", "-..-", "..-..", "..--", ".-.-",
|
||||
".-", "-...", ".--", "--.", "-..", ".", "...-", /* 1072-1103 */
|
||||
"--..", "..",".---", "-.-", ".-..", "--", "-.", /* lowercase */
|
||||
"---", ".--.", ".-.", "...", "-", "..-", "..-.", /* cyrillic */
|
||||
"....", "-.-.", "---.", "----", "--.-", "-..-",
|
||||
"-.--", "-..-", "..-..", "..--", ".-.-",
|
||||
|
||||
/* 1004-1119, cyrillic (Serbian, Macedonian, Ukrainian) UC */
|
||||
".", ".", "-.. .---", "--. .---", ".", "-.. --..", "..", "..",
|
||||
".---", ".-.. .---", "-. .---", "-.-.", "-.- .---", "..", "..-","-.. --..",
|
||||
|
||||
/* 1120 - 1487 to be done... */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/* 1488-1514 Hebrew according to Wikipedia */
|
||||
".-", "-...", "--.", "-..", "---", ".", "--..", "....",
|
||||
"..-", "..", NULL, "-.-", ".-..", NULL, "--", "-.", NULL,
|
||||
"-.-.", ".---", NULL, ".--.", NULL, ".--", "--.-", ".-.", "...",
|
||||
"-", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/* Arabic Alphabet, as per Wikipedia.
|
||||
* Nobody is possibly ever going to use this :-)
|
||||
* 1569-1610
|
||||
*/
|
||||
".", NULL, NULL, NULL, NULL, NULL,
|
||||
".-", "-...", NULL, "-", "-.-.",
|
||||
".---", "....", "---", "-..", "--..", ".-.", "---.", "...",
|
||||
"----", "-..-", "...-", "..-", "-.--", ".-.-", "--.", NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, "..-.", "--.-", "-.-",
|
||||
".-..", "--", "-.", NULL, ".--", NULL, "..", NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL /* 1920 */
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
.TH ebook2cw 1 "MARCH 2008" Linux "User Manuals"
|
||||
.SH NAME
|
||||
ebook2cw \- convert ebooks to morse mp3s
|
||||
.SH SYNOPSIS
|
||||
.B ebook2cw
|
||||
[OPTIONS]
|
||||
.SH DESCRIPTION
|
||||
.B ebook2cw
|
||||
ebook2cw is a command line program which converts a plain text ebook to morse
|
||||
code MP3 files. It works on several platforms, including Windows and Linux.
|
||||
|
||||
A number of CW and MP3 parameters can be changed from their default values, by
|
||||
command line switches. These are (default values in brackets):
|
||||
|
||||
.B -w wpm
|
||||
- CW speed in words per minute [25]
|
||||
|
||||
.B -e wpm
|
||||
- Effective CW speed. If set, the spaces are sent at this speed instead of the
|
||||
character speed set by -w ("Farnsworth").
|
||||
|
||||
.B -W x
|
||||
- Extra Word spacing. Similar to -e, but only affects the inter-word spacing,
|
||||
not the inter-character spacing.
|
||||
|
||||
.B -f freq
|
||||
- audio frequency in Hz [600]
|
||||
|
||||
.B -Q minutes
|
||||
- Increase CW speed (QRQ) by 1 WpM in intervals of `minutes'. Speed will be
|
||||
reset to the initial value at the start of each chapter. [0]
|
||||
|
||||
.B -n
|
||||
- Disables resetting the speed when using the -Q option.
|
||||
|
||||
.B -R risetime
|
||||
- risetime, in samples [50]
|
||||
|
||||
.B -F falltime
|
||||
- falltime, samples [50]
|
||||
|
||||
.B -s samplerate
|
||||
- samplerate for the MP3 file [11025]
|
||||
|
||||
.B -b bitrate
|
||||
- MP3 bitrate, kbps [16]
|
||||
|
||||
.B -q quality
|
||||
- MP3 quality, 1 (best) to 9 (worst). CW still sounds very good with the worst quality, encoding time is greatly reduced. [5]
|
||||
|
||||
.B -c chapter separator
|
||||
- Split chapters at this string. [CHAPTER]
|
||||
|
||||
.B -o outfile-name
|
||||
- Output filename (chapter number and .mp3 will be appended) [Chapter]
|
||||
|
||||
.B -a author
|
||||
- Author for the ID3 tag. Use quotes for strings with spaces (e.g. "JW Goethe")
|
||||
|
||||
.B -t title
|
||||
- Title for the ID3 tag. Use quotes for strings with spaces (e.g. "Faust II")
|
||||
|
||||
.B -k comment
|
||||
- Comment for the ID3 tag. Use quotes for strings with spaces.
|
||||
|
||||
.B -y year
|
||||
- Year for the ID3 tag.
|
||||
|
||||
.B -u
|
||||
- Switches input encoding format to UTF-8. Currently supported alphabets
|
||||
include Latin, Greek, Hebrew, Arabic and Cyrillic. Default is ISO 8859-1.
|
||||
|
||||
.B -S [ISO|UTF]
|
||||
- Shows a table of all available morse symbols for the ISO 8859-1 and UTF-8
|
||||
character sets. Output in HTML format.
|
||||
|
||||
CW prosigns can be generated by enclosing arbitrary letters in angle brackets
|
||||
(e.g. <AR>, <SK>, ...).
|
||||
|
||||
.SH AUTHOR
|
||||
Fabian Kurz, DJ1YFK <mail@fkurz.net>
|
||||
|
||||
http://fkurz.net/ham/ebook2cw.html
|
||||
.SH "SEE ALSO"
|
||||
.BR morse (1)
|
||||
|
|
@ -0,0 +1,634 @@
|
|||
/*
|
||||
ebook2cw - converts an ebook to morse mp3s
|
||||
|
||||
Copyright (C) 2008 Fabian Kurz, DJ1YFK
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 2 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
|
||||
Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
source code looks properly indented with tw=4
|
||||
|
||||
*/
|
||||
|
||||
#include "lame/lame.h"
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "codetables.h"
|
||||
|
||||
#ifndef VERSION
|
||||
#define VERSION "0.0.0"
|
||||
#endif
|
||||
|
||||
#define PCMBUFFER 220500 /* 20 seconds at 11kHz, for one word. plenty. */
|
||||
#define MP3BUFFER 285000 /* abt 1.25*PCMBUFFER + 7200, as recommended */
|
||||
|
||||
#define ISO8859 0
|
||||
#define UTF8 1
|
||||
|
||||
lame_global_flags *gfp;
|
||||
|
||||
FILE *outfile;
|
||||
FILE *infile;
|
||||
|
||||
/* MP3 samplerate, bitrate, quality. */
|
||||
int samplerate = 11025;
|
||||
int brate = 16;
|
||||
int quality = 5;
|
||||
|
||||
/* CW parameters */
|
||||
int wpm = 25;
|
||||
int freq = 600;
|
||||
int rt = 50; /* rise/fall time in samples */
|
||||
int ft = 50;
|
||||
int qrq = 0; /* rise speed by 1 WpM every qrq minutes */
|
||||
int reset = 1; /* reset QRQed speed every chapter? */
|
||||
int farnsworth = 0; /* extra spacing in dit-lengths */
|
||||
float ews = 0.0; /* extra word spaces */
|
||||
|
||||
/* the buffers for dit, dah, raw pcm and mp3 output, will be calloc'ed to the
|
||||
* default values, and -if needed- realloc'ed to the needed size */
|
||||
|
||||
short int *dit_buf;
|
||||
short int *dah_buf;
|
||||
short int *inpcm;
|
||||
unsigned char *mp3buffer;
|
||||
|
||||
int inpcm_size;
|
||||
int mp3buffer_size;
|
||||
|
||||
int ditlen=0; /* number of samples in a 'dit' */
|
||||
|
||||
/* Chapters are split by this string */
|
||||
char chapterstr[80]="CHAPTER";
|
||||
char chapterfilename[80]="Chapter"; /* full filename: Chapter%04d.mp3 */
|
||||
|
||||
/* ID3-tag data: author and title */
|
||||
char id3_author[80]="CW audio book";
|
||||
char id3_title[80]="";
|
||||
char id3_comment[80]="";
|
||||
char id3_year[5]="";
|
||||
|
||||
/* functions */
|
||||
int init_cw (int wpm, int freq, int rt, int ft);
|
||||
void help (void);
|
||||
void showcodes (int i);
|
||||
void makeword(char * text, int encoding);
|
||||
void closefile (int letter, int cw);
|
||||
void openfile (int chapter);
|
||||
void buf_check(int j);
|
||||
|
||||
/* main */
|
||||
|
||||
int main (int argc, char** argv) {
|
||||
int pos, i, original_wpm;
|
||||
int encoding = ISO8859;
|
||||
int c;
|
||||
char word[1024]=""; /* will be cut when > 1024 chars long */
|
||||
int chapter = 0;
|
||||
int cw = 0, tw = 0, qw = 0; /* chapter words, total words, qrq words */
|
||||
|
||||
infile = stdin;
|
||||
|
||||
while((i=getopt(argc,argv, "o:w:W:e:f:R:F:s:b:q:c:a:t:k:y:Q:S:hun"))!= -1) {
|
||||
switch (i) {
|
||||
case 'w':
|
||||
if ((wpm = atoi(optarg)) < 1) {
|
||||
fprintf(stderr, "Error: Speed (-w) must be > 0!\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
case 'f':
|
||||
freq = atoi(optarg);
|
||||
break;
|
||||
case 'R':
|
||||
rt = atoi(optarg);
|
||||
break;
|
||||
case 'F':
|
||||
ft = atoi(optarg);
|
||||
break;
|
||||
case 's':
|
||||
samplerate = atoi(optarg);
|
||||
break;
|
||||
case 'b':
|
||||
brate = atoi(optarg);
|
||||
break;
|
||||
case 'q':
|
||||
quality = atoi(optarg);
|
||||
break;
|
||||
case 'c':
|
||||
strncpy(chapterstr, optarg, 78);
|
||||
break;
|
||||
case 'o':
|
||||
strncpy(chapterfilename, optarg, 78);
|
||||
break;
|
||||
case 'a':
|
||||
strncpy(id3_author, optarg, 78);
|
||||
break;
|
||||
case 't':
|
||||
strncpy(id3_title, optarg, 75);
|
||||
break;
|
||||
case 'k':
|
||||
strncpy(id3_comment, optarg, 78);
|
||||
break;
|
||||
case 'y':
|
||||
strncpy(id3_year, optarg, 4);
|
||||
break;
|
||||
case 'Q':
|
||||
if ((qrq = atoi(optarg)) < 1) {
|
||||
fprintf(stderr, "Error: QRQ time (-Q) must be > 0!\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
case 'u':
|
||||
encoding = UTF8;
|
||||
break;
|
||||
case 'S':
|
||||
if (strstr(optarg, "ISO")) {
|
||||
showcodes(1);
|
||||
}
|
||||
else {
|
||||
showcodes(0);
|
||||
}
|
||||
break;
|
||||
case 'e': /* effective speed in WpM */
|
||||
if ((farnsworth = atoi(optarg)) < 1) {
|
||||
fprintf(stderr, "Error: Eff. speed (-e) must be > 0!\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
case 'W':
|
||||
ews = atof(optarg);
|
||||
break;
|
||||
case 'n':
|
||||
reset = 0;
|
||||
break;
|
||||
case 'h':
|
||||
default:
|
||||
help();
|
||||
} /* switch */
|
||||
} /* while */
|
||||
|
||||
if (optind < argc) { /* something left? if so, use as infile */
|
||||
if ((argv[optind][0] != '-') && (argv[optind][0] != '\0')) {
|
||||
if ((infile = fopen(argv[optind], "r")) == NULL) {
|
||||
fprintf(stderr, "Error: Cannot open file %s. Exit.\n",
|
||||
argv[optind]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* init lame */
|
||||
gfp = lame_init();
|
||||
lame_set_num_channels(gfp,1);
|
||||
lame_set_in_samplerate(gfp, samplerate);
|
||||
lame_set_brate(gfp, brate);
|
||||
lame_set_mode(gfp,1);
|
||||
lame_set_quality(gfp, quality);
|
||||
|
||||
if (lame_init_params(gfp) < 0) {
|
||||
fprintf(stderr, "Failed: lame_init_params(gfp) \n");
|
||||
return(1);
|
||||
}
|
||||
|
||||
/* init pcm_buf and mp3_buf */
|
||||
|
||||
if ((inpcm = calloc(PCMBUFFER, sizeof(short int))) == NULL) {
|
||||
fprintf(stderr, "Error: Can't allocate inpcm[%d]!\n", PCMBUFFER);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
else {
|
||||
inpcm_size = PCMBUFFER;
|
||||
}
|
||||
|
||||
if ((mp3buffer = calloc(MP3BUFFER, sizeof(unsigned char))) == NULL) {
|
||||
fprintf(stderr, "Error: Can't allocate mp3buffer[%d]!\n", MP3BUFFER);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
else {
|
||||
mp3buffer_size = MP3BUFFER;
|
||||
}
|
||||
|
||||
printf("ebook2cw %s - (c) 2008 by Fabian Kurz, DJ1YFK\n", VERSION);
|
||||
printf("Speed: %dwpm, Freq: %dHz, Chapter: >%s<, Encoding: %s\n",
|
||||
wpm, freq, chapterstr, encoding == UTF8 ? "UTF-8" : "ISO 8859-1");
|
||||
|
||||
printf("Effective speed: %dwpm, ", farnsworth ? farnsworth : wpm);
|
||||
printf("Extra word spaces: %1.1f, ", ews);
|
||||
printf("QRQ: %dmin, reset QRQ: %s\n\n", qrq, reset ? "yes" : "no");
|
||||
|
||||
ditlen = init_cw(wpm, freq, rt, ft); /* generate raw dit, dah */
|
||||
|
||||
strcat(chapterstr, " ");
|
||||
|
||||
/* read STDIN, assemble full words (anything ending in ' ') to 'word' and
|
||||
* generate CW, write to file by 'makeword'. words with > 1024 characters
|
||||
* will be split */
|
||||
|
||||
original_wpm = wpm; /* may be changed by QRQing */
|
||||
chapter = 0;
|
||||
openfile(chapter);
|
||||
|
||||
pos=0;
|
||||
while ((c = getc(infile)) != EOF) {
|
||||
|
||||
if (c == '\r') /* DOS linebreaks */
|
||||
continue;
|
||||
|
||||
word[pos++] = c;
|
||||
|
||||
if ((c == ' ') || (c == '\n') || (pos == 1024)) {
|
||||
word[pos] = '\0';
|
||||
if (strcmp(chapterstr, word) == 0) { /* new chapter */
|
||||
closefile(chapter, cw);
|
||||
cw = 0;
|
||||
chapter++;
|
||||
|
||||
if (qrq && reset) {
|
||||
wpm = original_wpm;
|
||||
ditlen = init_cw(wpm, freq, rt, ft);
|
||||
qw = 0;
|
||||
}
|
||||
|
||||
openfile(chapter);
|
||||
}
|
||||
makeword(word, encoding);
|
||||
cw++; tw++; qw++;
|
||||
|
||||
word[0] = '\0';
|
||||
pos = 0;
|
||||
|
||||
/* Every 'qrq' minutes (qrq*wpm words), speed up 1 WpM */
|
||||
if (qw == (qrq*wpm)) {
|
||||
wpm += 1;
|
||||
ditlen = init_cw(wpm, freq, rt, ft);
|
||||
printf("QRQ: %dwpm\n", wpm);
|
||||
qw = 0;
|
||||
}
|
||||
|
||||
} /* word */
|
||||
} /* eof */
|
||||
|
||||
closefile(chapter, cw);
|
||||
|
||||
free(mp3buffer);
|
||||
free(inpcm);
|
||||
|
||||
/* factor 0.9 due to many 'words' which aren't actually words, like '\n' */
|
||||
printf("Total words: %d, total time: %d min\n", tw, (int) ((tw/wpm)*0.9));
|
||||
|
||||
lame_close(gfp);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* init_cw - generates a dit and a dah to dit_buf and dah_buf */
|
||||
|
||||
int init_cw (int wpm, int freq, int rt, int ft) {
|
||||
int x, len;
|
||||
double val;
|
||||
|
||||
/* set farnsworth to samples */
|
||||
if (farnsworth) {
|
||||
|
||||
if (farnsworth > wpm) {
|
||||
fprintf(stderr, "Error: Effective speed (-e %d) must be lower "
|
||||
"than character speed (-w %d)!\n", farnsworth, wpm);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
|
||||
farnsworth = (int) (6.0*samplerate/(5.0*farnsworth));
|
||||
}
|
||||
|
||||
/* printf("Initializing CW buffers at %d WpM: ", wpm); */
|
||||
|
||||
/* dah */
|
||||
len = (int) (3.0*6.0*samplerate/(5.0*wpm)); /* in samples */
|
||||
|
||||
/* ditlen not set == init_cw has not been called yet */
|
||||
if (!ditlen) {
|
||||
/* allocate memory for the buffer */
|
||||
if ((dah_buf = calloc(len, sizeof(short int))) == NULL) {
|
||||
fprintf(stderr, "Error: Can't allocate dah_buf[%d]\n", len);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
for (x=0; x < len; x++) {
|
||||
val = sin(2*M_PI*freq*x/samplerate);
|
||||
if (x < rt) /* shaping with sin^2 */
|
||||
val *= pow(sin(M_PI*x/(2.0*rt)),2);
|
||||
|
||||
if (x > (len-ft))
|
||||
val *= pow((sin(2*M_PI*(x-(len-ft)+ft)/(4*ft))), 2);
|
||||
|
||||
dah_buf[x] = (short int) (val * 20000.0);
|
||||
}
|
||||
|
||||
/* printf("dah_buf[%d], ", x); */
|
||||
|
||||
/* dit */
|
||||
len = (int) (6.0*samplerate/(5.0*wpm)); /* in samples */
|
||||
|
||||
/* ditlen not set == init_cw has not been called yet */
|
||||
if (!ditlen) {
|
||||
/* allocate memory for the buffer */
|
||||
if ((dit_buf = calloc(len, sizeof(short int))) == NULL) {
|
||||
fprintf(stderr, "Error: Can't allocate dit_buf[%d]\n", len);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
for (x=0; x < len; x++) {
|
||||
val = sin(2*M_PI*freq*x/samplerate);
|
||||
if (x < rt)
|
||||
val *= pow(sin(M_PI*x/(2.0*rt)), 2);
|
||||
|
||||
if (x > (len-ft))
|
||||
val *= pow((sin(2*M_PI*(x-(len-ft)+ft)/(4*ft))), 2);
|
||||
|
||||
dit_buf[x] = (short int) (val * 20000.0);
|
||||
}
|
||||
|
||||
/* printf("dit_buf[%d]\n\n", x); */
|
||||
|
||||
return x; /* = length of dit/silence */
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* makeword -- converts 'text' to CW by concatenating dit_buf amd dah_bufs,
|
||||
* encodes this to MP3 and writes to open filehandle outfile */
|
||||
|
||||
void makeword(char * text, int encoding) {
|
||||
const char *code; /* CW code as . and - */
|
||||
int outbytes;
|
||||
|
||||
int c, i, j, u, w;
|
||||
int prosign = 0;
|
||||
unsigned char last=0; /* for utf8 2-byte characters */
|
||||
|
||||
j = 0; /* position in 'inpcm' buffer */
|
||||
|
||||
for (i = 0; i < strlen(text); i++) {
|
||||
c = (unsigned char) text[i];
|
||||
code = NULL;
|
||||
|
||||
if (c == '\n') { /* Same for UTF8 and ISO8859 */
|
||||
if (strlen(text) == 1) /* paragraph */
|
||||
code = " -...- ";
|
||||
else
|
||||
code = " ";
|
||||
}
|
||||
else if (c == '<') { /* prosign on */
|
||||
prosign = 1;
|
||||
continue;
|
||||
}
|
||||
else if ((c == '>') && prosign) { /* prosign off */
|
||||
prosign = 0;
|
||||
code = ""; /* only inserts letter space */
|
||||
}
|
||||
else if (encoding == ISO8859) {
|
||||
code = iso8859[c];
|
||||
}
|
||||
else if (encoding == UTF8) {
|
||||
/* Character may be 1-byte ASCII or 2-byte UTF8 */
|
||||
if (!(c & 128)) { /* MSB = 0 -> 7bit ASCII */
|
||||
code = iso8859[c]; /* subset of iso8859 */
|
||||
}
|
||||
else {
|
||||
if (last && (c < 192) ) { /* this is the 2nd byte */
|
||||
/* 110yyyyy 10zzzzzz -> 00000yyy yyzzzzzz */
|
||||
c = ((last & 31) << 6) | (c & 63);
|
||||
code = utf8table[c];
|
||||
last = 0;
|
||||
}
|
||||
else { /* this is the first byte */
|
||||
last = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (last) continue; /* first of two-byte character read */
|
||||
|
||||
/* Not found anything ... */
|
||||
if (code == NULL) {
|
||||
code = " ";
|
||||
if (c < 255) {
|
||||
fprintf(stderr, "Warning: don't know CW for '%c'\n", c);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "Warning: don't know CW for unicode &#%d;\n", c);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* code contains letter as ./-, now assemble pcm buffer */
|
||||
|
||||
for (w = 0; w < strlen(code) ; w++) {
|
||||
|
||||
/* make sure the inpcm buffer doesn't run full,
|
||||
* with a conservative margin. reallocate memory if neccesary */
|
||||
|
||||
buf_check(j);
|
||||
|
||||
|
||||
c = code[w];
|
||||
|
||||
if (c == '.')
|
||||
for (u=0; u < ditlen; u++)
|
||||
inpcm[++j] = dit_buf[u];
|
||||
else if (c == '-')
|
||||
for (u=0; u < (3*ditlen); u++)
|
||||
inpcm[++j] = dah_buf[u];
|
||||
else /* word space */
|
||||
for (u=0;u < (int)(1+7*ews)*(farnsworth ? farnsworth : ditlen); u++)
|
||||
inpcm[++j] = 0;
|
||||
|
||||
for (u=0; u < ditlen; u++) /* space of one dit length */
|
||||
inpcm[++j] = 0;
|
||||
} /* foreach dot/dash */
|
||||
|
||||
if (prosign == 0) {
|
||||
for (u=0; u < (farnsworth ? 3*farnsworth-ditlen : 2*ditlen); u++)
|
||||
inpcm[++j] = 0;
|
||||
}
|
||||
|
||||
} /* foreach letter */
|
||||
|
||||
/* j = total length of samples in 'inpcm' */
|
||||
|
||||
outbytes = lame_encode_buffer(gfp, inpcm, inpcm, j, mp3buffer, mp3buffer_size);
|
||||
if (outbytes < 0) {
|
||||
fprintf(stderr, "Error: lame_encode_buffer returned %d. Exit.\n", outbytes);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (fwrite(mp3buffer, sizeof(char), outbytes, outfile) != outbytes) {
|
||||
fprintf(stderr, "Error: Writing %db to file failed. Exit.\n", outbytes);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* closefile -- finishes writing the current file, flushes the encoder buffer */
|
||||
|
||||
void closefile (int letter, int cw) {
|
||||
int outbytes;
|
||||
char mp3filename[80] = "";
|
||||
|
||||
printf("words: %d, minutes: %d\n", cw, (int) ((cw/wpm)*0.9));
|
||||
|
||||
snprintf(mp3filename, 80, "%s%04d.mp3", chapterfilename, letter);
|
||||
printf("Finishing %s\n\n", mp3filename);
|
||||
|
||||
outbytes = lame_encode_flush(gfp, mp3buffer, mp3buffer_size);
|
||||
|
||||
if (outbytes < 0) {
|
||||
fprintf(stderr, "Error: lame_encode_buffer returned %d.\n", outbytes);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (fwrite(mp3buffer, sizeof(char), outbytes, outfile) != outbytes) {
|
||||
fprintf(stderr, "Error: Writing %db to file failed. Exit.\n", outbytes);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
fclose(outfile);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* openfile -- starts a new chapter by opening Chapter%d.mp3 */
|
||||
|
||||
void openfile (int chapter) {
|
||||
char mp3filename[80] = "";
|
||||
static char tmp[80] = "";
|
||||
|
||||
snprintf(mp3filename, 80, "%s%04d.mp3", chapterfilename, chapter);
|
||||
printf("Starting %s\n", mp3filename);
|
||||
|
||||
if ((outfile = fopen(mp3filename, "wb")) == NULL) {
|
||||
fprintf(stderr, "Error: Failed to open %s\n", mp3filename);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
snprintf(tmp, 79, "%s - %d", id3_title, chapter); /* generate title */
|
||||
|
||||
id3tag_init(gfp);
|
||||
id3tag_set_artist(gfp, id3_author);
|
||||
id3tag_set_year(gfp, id3_year);
|
||||
id3tag_set_title(gfp, tmp);
|
||||
id3tag_set_comment(gfp, id3_comment);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void help (void) {
|
||||
printf("ebook2cw v%s - (c) 2008 by Fabian Kurz, DJ1YFK, http://fkurz.net/\n", VERSION);
|
||||
printf("\nThis is free software, and you are welcome to redistribute it\n");
|
||||
printf("under certain conditions (see COPYING).\n");
|
||||
printf("\n");
|
||||
printf("ebook2cw [-w wpm] [-f freq] [-R risetime] [-F falltime]\n");
|
||||
printf(" [-s samplerate] [-b mp3bitrate] [-q mp3quality]\n");
|
||||
printf(" [-c chapter-separator] [-o outfile-name] [-Q minutes]\n");
|
||||
printf(" [-a author] [-t title] [-k comment] [-y year]\n");
|
||||
printf(" [-u] [-S ISO|UTF] [-n] [-e eff.wpm] [-W space]\n");
|
||||
printf(" [infile]\n\n");
|
||||
printf("defaults: 25 WpM, 600Hz, RT=FT=50, s=11025Hz, b=16kbps,\n");
|
||||
printf(" c=\"CHAPTER\", o=\"Chapter\" infile = stdin\n");
|
||||
printf("\n");
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* showcodes
|
||||
* Generates a HTML table of the available CW symbols in codetables.h
|
||||
* i = 1 -> ISO 8859-1, i=0 -> UTF-8
|
||||
*/
|
||||
|
||||
void showcodes (int i) {
|
||||
int k;
|
||||
int n = i ? 256 : 1921;
|
||||
|
||||
printf("<html><head><META HTTP-EQUIV=\"CONTENT-TYPE\" CONTENT=\"text/html;"
|
||||
"charset=%s\"></head>\n", i ? "iso-8859-1" : "utf-8");
|
||||
printf("<body><h1>ebook2cw codetables.h</h1>\n");
|
||||
printf("<h2>%s</h2><table border=\"1\">\n", i ? "ISO 8859-1" : "UTF-8");
|
||||
printf("<tr><th>Decimal</th><th>Symbol</th><th>CW</th></tr>\n");
|
||||
|
||||
for (k=0; k < n; k++) {
|
||||
printf("<tr>");
|
||||
|
||||
if ((k < 128+i*128) && (iso8859[k] != NULL)) {
|
||||
printf("<td>%d</td><td>&#%d;</td><td>%s</td>", k, k, iso8859[k]);
|
||||
}
|
||||
else if (utf8table[k] != NULL) {
|
||||
printf("<td>%d</td><td>&#%d;</td><td>%s</td>", k, k, utf8table[k]);
|
||||
}
|
||||
else {
|
||||
printf("<td>%d</td><td>&#%d;</td><td> </td>", k, k);
|
||||
}
|
||||
|
||||
printf("</tr>\n");
|
||||
}
|
||||
|
||||
printf("</table></body></html>\n");
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* make sure the inpcm-buffer doesn't run full.
|
||||
* have to consider the effects of Farnsworth and extra word spacing */
|
||||
|
||||
void buf_check (int j) {
|
||||
int max;
|
||||
|
||||
/* maximum bytes that may be added for one dot or dah, for either
|
||||
* farnsworth or non-farnsworth */
|
||||
|
||||
max = farnsworth ? (int) ((4+7*ews)*(farnsworth)) : (6+7*ews) * ditlen;
|
||||
max += 10000; /* some margin to feel safe ... */
|
||||
|
||||
if (j > inpcm_size - max) {
|
||||
inpcm_size += max;
|
||||
mp3buffer_size += (int) (1.25 * max + 7200.0);
|
||||
if ((inpcm = realloc(inpcm, inpcm_size*sizeof(short int)))== NULL)
|
||||
fprintf(stderr, "Error: Can't realloc inpcm[%d]\n", inpcm_size);
|
||||
|
||||
if ((mp3buffer = realloc(mp3buffer, mp3buffer_size*sizeof(char)))
|
||||
== NULL)
|
||||
fprintf(stderr, "Error: Can't realloc mp3buffer[%d]\n",
|
||||
mp3buffer_size);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
d586035356b3040af0d4ebc82205b335 releases/ebook2cw-0.4.0.tar.gz
|
||||
0df0ae175e71743aaea1c6d9526966dc releases/ebook2cw-0.5.0.tar.gz
|
||||
1c170b6593ad2b8c6fdef55b5ead9a54 releases/ebook2cw-0.5.1.tar.gz
|
||||
a40768d09676012d62d60852dd59449c releases/ebook2cw-0.5.3.tar.gz
|
||||
57fafc5382fa38c4e646f1deaf116ae0 releases/ebook2cw-0.6.0.tar.gz
|
||||
f843ff84f3a8fa5234e5c1fe694d26c6 releases/ebook2cw-0.6.1.tar.gz
|
||||
58accf8bbd8d1f5b582c444b107fac84 releases/ebook2cw-0.6.2.tar.gz
|
||||
0c8b2f40812f8405f5dc266e95d9590f releases/ebook2cw-0.6.3.tar.gz
|
||||
bea78588dada08449a7065fe6222ca75 releases/ebook2cw-0.6.4.tar.gz
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
A small modification for stereo output. Dots/Dashes on the
|
||||
righ/left channel. Don't even try, it sucks.
|
||||
Binary file not shown.
Loading…
Reference in New Issue