diff options
Diffstat (limited to 'talk')
-rw-r--r-- | talk/Makefile | 10 | ||||
-rw-r--r-- | talk/en.tlk | bin | 0 -> 1899013 bytes | |||
-rwxr-xr-x | talk/po2talk | 191 | ||||
-rw-r--r-- | talk/sc.c | 229 | ||||
-rw-r--r-- | talk/talk.po | 687 |
5 files changed, 1117 insertions, 0 deletions
diff --git a/talk/Makefile b/talk/Makefile new file mode 100644 index 0000000..6e3c989 --- /dev/null +++ b/talk/Makefile @@ -0,0 +1,10 @@ +all: en.tlk + +en.tlk: talk.po sc + ./po2talk --compress $< $@ + +sc: sc.c + gcc -O2 -Wall -o $@ $< + +clean: + rm -f sc *~ diff --git a/talk/en.tlk b/talk/en.tlk Binary files differnew file mode 100644 index 0000000..c289fe3 --- /dev/null +++ b/talk/en.tlk diff --git a/talk/po2talk b/talk/po2talk new file mode 100755 index 0000000..46fe1fe --- /dev/null +++ b/talk/po2talk @@ -0,0 +1,191 @@ +#! /usr/bin/perl + +use Getopt::Long; + +sub help; +sub read_po; +sub join_id; +sub new_tmp_file; +sub cleanup; + +GetOptions( + 'help' => \&help, + 'compress' => \$opt_compress, +); + +END { cleanup } +$SIG{INT} = \&cleanup; +$SIG{TERM} = \&cleanup; + +my @tmp_files; + +$espeak = "espeak"; + +$magic = 0x692741e8; + +help if @ARGV != 2; + +$po = read_po $ARGV[0]; + +$tmp_txt = new_tmp_file; +$tmp_wav = new_tmp_file; +$tmp_snd = new_tmp_file; + +for $msg (@{$po}) { + $id = join_id $msg, 'id'; + $str = join_id $msg, 'str'; + + next unless $id ne ""; + + eval '$id = "' . $id . '"'; + eval '$str = "' . $str . '"'; + + $str = $id if $str eq ""; + + if(!$snd{$str}) { + open W, ">$tmp_txt"; + print W $str; + close W; + + $punc = length($id) == 1 ? "--punc" : ""; + + system "$espeak $punc -f $tmp_txt -w $tmp_wav"; + system "sox $tmp_wav -b -u -c 1 -r 16000 -t .wav $tmp_snd"; + if($opt_compress) { + system "./sc $tmp_snd $tmp_snd"; + } + + open F, $tmp_snd; + sysread F, $snd_buf, -s $tmp_snd; + close F; + + $snd{$str} = $snd_buf; + } + + $snd_id{$id} = $str; +} + +$file_ofs = 0; +@snds = sort keys %snd; +@snd_ids = sort keys %snd_id; + +for $snd_id (@snd_ids) { + $txt_ofs{$snd_id} = $file_ofs; + $file_ofs += length($snd_id) + 1; +} + +for $snd (@snds) { + $snd_ofs{$snd} = $file_ofs; + $file_ofs += length($snd{$snd}); +} + +$head_size = 8 + 8 * @snd_ids; + +open W, ">$ARGV[1]"; + +print W pack("VV", $magic, scalar(@snd_ids)); +for $snd_id (@snd_ids) { + print W pack("VV", ($txt_ofs{$snd_id} + $head_size, $snd_ofs{$snd_id{$snd_id}} + $head_size)); +} +for $snd_id (@snd_ids) { + print W $snd_id, "\x00"; +} +for $snd (@snds) { + print W $snd{$snd}; +} + +close W; + + +sub help +{ + print STDERR + "Usage: po2talk [options] po_file talk_file\n" . + "Run po file through espeak.\n"; + + exit 0; +} + + +sub read_po +{ + local $_; + my ($msg, $cnt, $id, $f); + + $cnt = 0; + + open F, $_[0]; + while(<F>) { + s/^\s*|\s*$//g; + next if $_ eq ""; + if(/^#,/) { + s/^#,\s*//; + for $f (split /\s*,\s*/) { + ${$msg->[$cnt]{flags}{$f}} = 1 if $f ne ""; + } + next + } + if(/^#(\s|$)/) { push @{$msg->[$cnt]{u_comment}}, $_ ; next } + if(/^#/) { push @{$msg->[$cnt]{a_comment}}, $_; next } + if(s/^msg(id\b|id_plural\b|str(\[\d+\])?)\s*//) { + $id = $1; + if($id eq 'id') { + $msg->[$cnt]{line} = $. unless exists $msg->[$cnt]{$line}; + $cnt++; + } + } + if($cnt && /^"(.*)"$/) { + push @{$msg->[$cnt - 1]{$id}}, $1; + } + else { + print STDERR "$_[0]:$.: invalid po format\n"; + return undef; + } + } + close F; + + # trailing comments + pop @$msg if @$msg > 0 && !$msg->[-1]{id}; + + return $msg; +} + + +sub join_id +{ + my ($msg, $id); + + ($msg, $id) = @_; + + return join '', @{$msg->{$id}}; +} + + +# create new temporary file +sub new_tmp_file +{ + local $_; + + chomp ($_ = `mktemp /tmp/po2talk.XXXXXXXXXX`); + die "error: mktemp failed\n" if $?; + + push @tmp_files, $_; + + return $_; +} + + +# remove temporary files +sub cleanup +{ + local $_; + + for (@tmp_files) { + next unless defined $_; + unlink; + $_ = undef; + } + + undef @tmp_files; +} + diff --git a/talk/sc.c b/talk/sc.c new file mode 100644 index 0000000..6be9a2d --- /dev/null +++ b/talk/sc.c @@ -0,0 +1,229 @@ +#define _GNU_SOURCE + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <inttypes.h> + +#define MAGIC 0x7d53b605 + +#define MIN_REF_LEN 5 +#define MAX_REF 127 + MIN_REF_LEN + +typedef struct { + unsigned size; + unsigned char *data; + unsigned real_size; +} file_data_t; + +typedef struct __attribute ((packed)) { + uint32_t magic; + uint32_t size; + uint32_t unpacked_size; + uint32_t sample_rate; +} snd_header_t; + +file_data_t *read_file(char *name); +void add_data(file_data_t *d, void *buffer, unsigned size); +void write_data(file_data_t *d, char *name); + +void compr(file_data_t *fd, file_data_t *fd_compr); +unsigned find_longest(unsigned char *data, unsigned len, unsigned start, unsigned *ofs); + + +int main(int argc, char **argv) +{ + file_data_t *fd, fd_compr = { }, fd_samples = { }; + snd_header_t sh; + unsigned sample_rate; + + if(argc != 3) return 1; + + fd = read_file(argv[1]); + + if(fd->size <= 44) return 1; + + if( + *((unsigned *) (fd->data + 0)) != 0x46464952 || + *((unsigned *) (fd->data + 8)) != 0x45564157 || + *((short *) (fd->data + 20)) != 1 || + *((short *) (fd->data + 34)) != 8 || + *((short *) (fd->data + 22)) != 1 + ) { + fprintf(stderr, "invalid data, expecting 8bit mono wav (ms pcm) file\n"); + return 3; + } + sample_rate = *((unsigned *) (fd->data + 24)); + + printf("%s: %u Hz, %u samples\n", argv[1], sample_rate, fd->size - 44); + + add_data(&fd_samples, fd->data + 44, fd->size - 44); + + sh.magic = MAGIC; + sh.unpacked_size = fd_samples.size; + sh.sample_rate = sample_rate; + + add_data(&fd_compr, &sh, sizeof sh); + + compr(&fd_samples, &fd_compr); + + sh.size = fd_compr.size - sizeof (snd_header_t); + + memcpy(fd_compr.data, &sh, sizeof (snd_header_t)); + + write_data(&fd_compr, argv[2]); + + return 0; +} + + +file_data_t *read_file(char *name) +{ + file_data_t *fd; + FILE *f; + + fd = calloc(1, sizeof *fd); + + if(!name) return fd; + + f = fopen(name, "r"); + + if(!f) { perror(name); return fd; } + + if(fseek(f, 0, SEEK_END)) { + perror(name); + exit(30); + } + + fd->size = fd->real_size = ftell(f); + + if(fseek(f, 0, SEEK_SET)) { + perror(name); + exit(30); + } + + if(fd->size) { + fd->data = calloc(1, fd->size); + if(!fd->data) { + fprintf(stderr, "malloc failed\n"); + exit(30); + } + } + + if(fread(fd->data, 1, fd->size, f) != fd->size) { + perror(name); + exit(30); + } + + fclose(f); + + return fd; +} + + +void add_data(file_data_t *d, void *buffer, unsigned size) +{ + if(!size || !d || !buffer) return; + + if(d->size + size > d->real_size) { + d->real_size = d->size + size + 0x1000; + d->data = realloc(d->data, d->real_size); + if(!d->data) d->real_size = 0; + } + + if(d->size + size <= d->real_size) { + memcpy(d->data + d->size, buffer, size); + d->size += size; + } + else { + fprintf(stderr, "Oops, out of memory? Aborted.\n"); + exit(10); + } +} + + +void write_data(file_data_t *d, char *name) +{ + FILE *f; + + f = strcmp(name, "-") ? fopen(name, "w") : stdout; + + if(!f) { + perror(name); + return; + } + + if(fwrite(d->data, d->size, 1, f) != 1) { + perror(name); + exit(3); + } + + fclose(f); +} + + +void compr(file_data_t *fd, file_data_t *fd_compr) +{ + unsigned u, v, l, ofs; + unsigned char uc; + + if(!fd->size) return; + + for(u = 0; u < fd->size; u++) { + if(fd->data[u] == 0xff) fd->data[u] = 0xfe; + } + + // printf("%5u: %02x\n", fd->size, fd->data[0]); + add_data(fd_compr, fd->data, 1); + + for(u = 1; u < fd->size; ) { + l = find_longest(fd->data, fd->size, u, &ofs); + // printf("%u: %u bytes @ %u\n", u, l, ofs); + if(l >= MIN_REF_LEN) { + // printf("%5u: %u bytes @ %u\n", fd->size, l, ofs); + v = (ofs << 7) + l - MIN_REF_LEN; + uc = 0xff; add_data(fd_compr, &uc, 1); + uc = v; add_data(fd_compr, &uc, 1); + uc = v >> 8; add_data(fd_compr, &uc, 1); + uc = v >> 16; add_data(fd_compr, &uc, 1); + u += l; + } + else { + // printf("%5u: %02x\n", fd->size, fd->data[u]); + add_data(fd_compr, fd->data + u, 1); + u++; + } + } +} + + +unsigned find_longest(unsigned char *data, unsigned len, unsigned start, unsigned *ofs) +{ + unsigned l; + unsigned char *p, *p1; + + p = data; + l = MIN_REF_LEN; + + for(;;) { + p1 = memmem(p, data + start + l - 1 - p, data + start, l); + if(!p1) break; + p = p1; + l++; + + if(l > MAX_REF) break; + } + + l--; + + if(l < MIN_REF_LEN) { + *ofs = 0; + return 0; + } + + *ofs = p - data; + return l; +} + + diff --git a/talk/talk.po b/talk/talk.po new file mode 100644 index 0000000..03c5d06 --- /dev/null +++ b/talk/talk.po @@ -0,0 +1,687 @@ +# main menu + +msgid "Boot from Hard Disk" +msgstr "" + +msgid "Installation" +msgstr "" + +msgid "Repair Installed System" +msgstr "" + +msgid "Rescue System" +msgstr "" + +msgid "Check Installation Media" +msgstr "" + +msgid "Firmware Test" +msgstr "" + +msgid "Memory Test" +msgstr "" + +msgid "openSUSE-11.1" +msgstr "" + +msgid "Failsafe-openSUSE-11.1" +msgstr "" + +msgid "Hard-Disk" +msgstr "" + +msgid "Live-System-GNOME" +msgstr "" + +msgid "Live-System-KDE" +msgstr "" + +msgid "openSUSE Live (GNOME)" +msgstr "" + +msgid "openSUSE Live (KDE)" +msgstr "" + +msgid "Failsafe Settings" +msgstr "" + + +# panel texts + +msgid "Help" +msgstr "" + +msgid "Language" +msgstr "" + +msgid "Video Mode" +msgstr "" + +msgid "Source" +msgstr "Installation Source" + +msgid "Kernel" +msgstr "" + +msgid "Driver" +msgstr "Driver Update" + +msgid "Arch" +msgstr "Architecture" + +msgid "Keyboard" +msgstr "" + + +# language menu + +msgid "Afrikaans" +msgstr "Afrikaans" + +msgid "\xef\xbb\xb2\xef\xba\x91\xef\xba\xae\xef\xbb\x8b" +msgstr "Arabic" + +msgid "Български" +msgstr "Bulgarian" + +msgid "\xe0\xa6\xac\xe0\xa6\xbe\xe0\xa6\x82\xe0\xa6\xb2\xe0\xa6" +msgstr "Bengali" + +msgid "Bosanski" +msgstr "Bosnian" + +msgid "Català" +msgstr "Catalan" + +msgid "Čeština" +msgstr "Czech" + +msgid "Cymraeg" +msgstr "Welsh" + +msgid "Dansk" +msgstr "Danish" + +msgid "Deutsch" +msgstr "German" + +msgid "Ελληνικά" +msgstr "Greek" + +msgid "English (UK)" +msgstr "English (UK)" + +msgid "English (US)" +msgstr "English (US)" + +msgid "Español" +msgstr "Spanish" + +msgid "Eesti" +msgstr "Estonian" + +msgid "\xef\xaf\xbd\xef\xba\xb4\xd8\xb1\xef\xba\x8e\xef\xbb\x93" +msgstr "Farsi" + +msgid "Suomi" +msgstr "Finnish" + +msgid "Français" +msgstr "French" + +msgid "Galego" +msgstr "Galician" + +msgid "ქართული" +msgstr "Kartuli" + +msgid "\xe0\xaa\x97\xe0\xab\x81\xe0\xaa\x9c\xe0\xaa\xb0\xe0\xaa\xbe\xe0\xaa\xa4\xe0\xab\x80" +msgstr "Gujarati" + +msgid "תירבע" +msgstr "Hebrew" + +msgid "\xe0\xa4\xb9\xe0\xa4\xbf\xe0\xa4\x82\xe0\xa4\xa6\xe0\xa5\x80" +msgstr "Hindi" + +msgid "Hrvatski" +msgstr "Croatian" + +msgid "Magyar" +msgstr "Hungarian" + +msgid "Bahasa Indonesia" +msgstr "Indonesian" + +msgid "Italiano" +msgstr "Italian" + +msgid "日本語" +msgstr "Japanese" + +msgid "Basa Jawa" +msgstr "Javanese" + +msgid "Khmer" +msgstr "Khmer" + +msgid "한글" +msgstr "Korean" + +msgid "\xe0\xba\x9e\xe0\xba\xb2\xe0\xba\xaa\xe0\xba\xb2\xe0\xba\xa5\xe0\xba\xb2\xe0\xba\xa7" +msgstr "Lao" + +msgid "Lietuvių" +msgstr "Lithuanian" + +msgid "Македонски" +msgstr "Macedonian" + +msgid "\xe0\xa4\xae\xe0\xa4\xb0\xe0\xa4\xbe\xe0\xa4\xa0\xe0\xa5\x80" +msgstr "Marathi" + +msgid "Norsk" +msgstr "Norwegian" + +msgid "Nederlands" +msgstr "Dutch" + +msgid "\xe0\xa8\xaa\xe0\xa9\xb0\xe0\xa8\x9c\xe0\xa8\xbe\xe0\xa8\xac\xe0\xa9\x80" +msgstr "Punjabi" + +msgid "Polski" +msgstr "Polish" + +msgid "Português (Brasil)" +msgstr "Portuguese (Brazilian)" + +msgid "Português" +msgstr "Portuguese" + +msgid "Română" +msgstr "Romanian" + +msgid "Русский" +msgstr "Russian" + +msgid "\xe0\xb7\x83\xe0\xb7\x92\xe0\xb6\x82\xe0\xb7\x84\xe0\xb6\xbd" +msgstr "Sinhala" + +msgid "Slovenčina" +msgstr "Slovak" + +msgid "Slovenščina" +msgstr "Slovenian" + +msgid "Srpski" +msgstr "Serbian" + +msgid "Svenska" +msgstr "Swedish" + +msgid "\xe0\xae\xa4\xe0\xae\xae\xe0\xae\xbf\xe0\xae\xb4\xe0\xaf\x8d" +msgstr "Tamil" + +msgid "\xe0\xb8\xa0\xe0\xb8\xb2\xe0\xb8\xa9\xe0\xb8\xb2\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2" +msgstr "Thai" + +msgid "Türkçe" +msgstr "Turkish" + +msgid "Українська" +msgstr "Ukrainian" + +msgid "Tiếng Việt" +msgstr "Vietnamese" + +msgid "Walon" +msgstr "Walloon" + +msgid "isiXhosa" +msgstr "Xhosa" + +msgid "简体中文" +msgstr "Simplified Chinese" + +msgid "繁體中文 (台灣)" +msgstr "Traditional Chinese" + +msgid "isiZulu" +msgstr "Zulu" + +# keymap menu + +msgid "Czech" +msgstr "" + +msgid "Danish" +msgstr "" + +msgid "German" +msgstr "" + +msgid "Estonian" +msgstr "" + +msgid "English-US" +msgstr "" + +msgid "Greek" +msgstr "" + +msgid "Spanish" +msgstr "" + +msgid "French" +msgstr "" + +msgid "Hungarian" +msgstr "" + +msgid "Italian" +msgstr "" + +msgid "Japanese" +msgstr "" + +msgid "Norwegian" +msgstr "" + +msgid "Polish" +msgstr "" + +msgid "Portuguese-BR" +msgstr "" + +msgid "Portuguese" +msgstr "" + +msgid "Russian" +msgstr "" + +msgid "Slovak" +msgstr "" + +msgid "Slovene" +msgstr "" + +msgid "Swedish" +msgstr "" + +msgid "Turkish" +msgstr "" + + +# video menu + +msgid "Text Mode" +msgstr "" + +msgid "VESA" +msgstr "" + +msgid "800 x 600" +msgstr "800 times 600" + +msgid "1024 x 768" +msgstr "1024 times 768" + +msgid "1280 x 1024" +msgstr "1280 times 1024" + +msgid "1400 x 1050" +msgstr "1400 times 1050" + +msgid "1600 x 1200" +msgstr "1600 times 1200" + + +# source menu + +msgid "CD-ROM" +msgstr "" + +msgid "DVD" +msgstr "" + +msgid "SLP" +msgstr "" + +msgid "FTP" +msgstr "" + +msgid "HTTP" +msgstr "" + + +msgid "NFS" +msgstr "" + + +msgid "SMB / CIFS" +msgstr "" + + +msgid "Hard Disk" +msgstr "" + + +# kernel menu + +msgid "Default" +msgstr "" + +msgid "Safe Settings" +msgstr "" + +msgid "No ACPI" +msgstr "" + +msgid "No Local APIC" +msgstr "" + + +# driver menu + +msgid "Yes" +msgstr "" + +msgid "No" +msgstr "" + +msgid "File" +msgstr "" + +msgid "URL" +msgstr "" + + +# arch menu + +msgid "x86" +msgstr "" + +msgid "x86-64" +msgstr "" + + +# install sources + +msgid "FTP Installation" +msgstr "" + +msgid "NFS Installation" +msgstr "" + +msgid "HTTP Installation" +msgstr "" + +msgid "SMB (Windows Share) Installation" +msgstr "" + +msgid "Hard Disk Installation" +msgstr "" + +msgid "Server\n" +msgstr "" + +msgid "Directory\n" +msgstr "" + +msgid "User (Anonymous Login If Empty)\n" +msgstr "" + +msgid "User (Uses \"guest\" If Empty)\n" +msgstr "" + +msgid "Password\n" +msgstr "" + +msgid "Domain\n" +msgstr "" + +msgid "Share\n" +msgstr "" + +msgid "Disk Device (Scans All Disks If Empty)\n" +msgstr "" + +msgid "" +"To load driver updates directly from CD-ROM,\n" +"enter the driver update file names (separated\n" +"by commas ',') here:\n" +msgstr "" + +msgid "Driver Update" +msgstr "" + +msgid "Download Driver Update" +msgstr "" + +msgid "Enter Driver Update URL\n" +msgstr "" + +msgid "Exiting..." +msgstr "" + +msgid "" +"You are leaving the graphical boot menu and\n" +"starting the text mode interface." +msgstr "" + +msgid "Power Off" +msgstr "" + +msgid "Halt the system now?" +msgstr "" + + +# ascii + +msgid " " +msgstr "space" + +msgid "!" +msgstr "" + +msgid "\"" +msgstr "" + +msgid "#" +msgstr "" + +msgid "$" +msgstr "" + +msgid "%" +msgstr "" + +msgid "&" +msgstr "" + +msgid "'" +msgstr "" + +msgid "(" +msgstr "" + +msgid ")" +msgstr "" + +msgid "*" +msgstr "" + +msgid "+" +msgstr "" + +msgid "," +msgstr "" + +msgid "-" +msgstr "" + +msgid "." +msgstr "" + +msgid "/" +msgstr "" + +msgid "0" +msgstr "" + +msgid "1" +msgstr "" + +msgid "2" +msgstr "" + +msgid "3" +msgstr "" + +msgid "4" +msgstr "" + +msgid "5" +msgstr "" + +msgid "6" +msgstr "" + +msgid "7" +msgstr "" + +msgid "8" +msgstr "" + +msgid "9" +msgstr "" + +msgid ":" +msgstr "" + +msgid ";" +msgstr "" + +msgid "<" +msgstr "" + +msgid "=" +msgstr "" + +msgid ">" +msgstr "" + +msgid "?" +msgstr "" + +msgid "@" +msgstr "" + +msgid "[" +msgstr "" + +msgid "\\" +msgstr "" + +msgid "]" +msgstr "" + +msgid "^" +msgstr "" + +msgid "_" +msgstr "" + +msgid "`" +msgstr "" + +msgid "a" +msgstr "" + +msgid "b" +msgstr "" + +msgid "c" +msgstr "" + +msgid "d" +msgstr "" + +msgid "e" +msgstr "" + +msgid "f" +msgstr "" + +msgid "g" +msgstr "" + +msgid "h" +msgstr "" + +msgid "i" +msgstr "" + +msgid "j" +msgstr "" + +msgid "k" +msgstr "" + +msgid "l" +msgstr "" + +msgid "m" +msgstr "" + +msgid "n" +msgstr "" + +msgid "o" +msgstr "" + +msgid "p" +msgstr "" + +msgid "q" +msgstr "" + +msgid "r" +msgstr "" + +msgid "s" +msgstr "" + +msgid "t" +msgstr "" + +msgid "u" +msgstr "" + +msgid "v" +msgstr "" + +msgid "w" +msgstr "" + +msgid "x" +msgstr "" + +msgid "y" +msgstr "" + +msgid "z" +msgstr "" + +msgid "{" +msgstr "" + +msgid "|" +msgstr "" + +msgid "}" +msgstr "" + +msgid "~" +msgstr "" + |