File Coverage

blib/lib/Speech/Google/TTS.pm
Criterion Covered Total %
statement 18 87 20.6
branch 0 18 0.0
condition n/a
subroutine 6 10 60.0
pod 4 4 100.0
total 28 119 23.5


line stmt bran cond sub pod time code
1             package Speech::Google::TTS;
2              
3             #
4             # Module that uses Google Translate for text to speech synthesis.
5             #
6             # Copyright (C) 2013, by Niels Dettenbach
7             # with contributes of Lefteris Zafiris
8             #
9             # This program is free software, distributed under the terms of
10             # the GNU General Public License Version 2.
11             #
12              
13             =head1 NAME
14              
15             Speech::Google::TTS - Module that uses Google Translate for text to speech synthesis.!
16              
17             =head1 VERSION
18              
19             Version 0.74
20              
21             =cut
22              
23             our $VERSION = '0.74';
24              
25              
26             =head1 SYNOPSIS
27              
28             This Module uses Googles Translate Service for text to multilingual
29             text to speech synthesis.
30              
31             This Module allows to use the Google TTS service behind the
32             Google Translation service from Perl and is the core of the
33             following Speech::Google Text to Speech Module set.
34              
35             Perhaps a little code snippet.
36              
37             use Speech::Google::TTS;
38              
39             my $a = Speech::Google::TTS->new();
40              
41             $a = new Speech::Google::TTS();
42              
43             $a->say_text("speak this text!");
44             $a->as_filename();
45              
46             $a->{'lang'} = 'de';
47             $a->say_text("sprich diesen Text");
48             $a->as_filename();
49             ...
50              
51             =head1 FUNCTIONS
52              
53             =head2 new
54              
55             Create a new Speech::Google::TTS object and initialize configuration.
56              
57             =head2 say_text
58              
59             Generates a WAV or MP3 from text, stored in the temp directory.
60              
61             =head2 as_filename
62              
63             Gives back the filename of the last generated WAV or MP3 from i.e. "say_text".
64              
65             =head2 languages
66              
67             The list of currently supported languages.
68              
69             =cut
70              
71              
72              
73 1     1   21811 use warnings;
  1         2  
  1         44  
74 1     1   7 use strict;
  1         1  
  1         33  
75 1     1   1190 use File::Temp qw(tempfile tempdir);
  1         26121  
  1         70  
76 1     1   749 use CGI::Util qw(escape);
  1         5031  
  1         83  
77 1     1   1293 use LWP::UserAgent;
  1         64086  
  1         35  
78 1     1   849 use LWP::ConnCache;
  1         1140  
  1         1291  
79              
80             my @text;
81              
82             # init
83             sub new {
84 0     0 1   my ($class) = @_;
85 0           my $self = {};
86 0           bless $self, $class;
87              
88 0           $self->{'samplerate'} = 16000;
89 0           $self->{'speed'} = 1.2;
90 0           $self->{'lang'} = "en";
91 0           $self->{'tmpdir'} = tempdir( CLEANUP => 0 );
92 0           $self->{'timeout'} = "10";
93 0           $self->{'googleurl'} = "http://translate.google.com/translate_tts";
94 0           $self->{'languages'} = languages();
95 0           $self->{'auformat'} = "wav";
96 0           $self->{'mpg123'} = "/usr/bin/mpg123";
97 0           $self->{'sox'} = "/usr/bin/sox";
98 0           $self->{'soxargs'} = '';
99 0           return($self);
100             }
101              
102              
103             sub say_text {
104 0     0 1   my ($self, @text) = @_;
105 0           my @mp3list;
106             my @soxargs;
107 0           my $samplerate = $self->{'samplerate'};
108 0           my $filename = '';
109 0           my $wav_name;
110 0           my $lang = $self->{'lang'};
111 0           my $speed = $self->{'speed'};
112 0           my $tmpdir = $self->{'tmpdir'};
113 0           my $timeout = $self->{'timeout'};
114 0           my $url = $self->{'googleurl'};
115 0           my $mpg123 = $self->{'mpg123'};
116 0           my $sox = $self->{'sox'};
117 0           my $soxargs = $self->{'soxargs'};
118            
119 0           for (@text) {
120             # Split input text to comply with google tts requirements #
121 0           s/[\\|*~<>^\n\(\)\[\]\{\}[:cntrl:]]/ /g;
122 0           s/\s+/ /g;
123 0           s/^\s|\s$//g;
124 0 0         if (!length) {
125 0           print "No text passed for synthesis.";
126 0           return;
127             }
128 0 0         $_ .= "." unless (/^.+[.,?!:;]$/);
129 0           @text = /.{1,100}[.,?!:;]|.{1,100}\s/g;
130              
131 0           my $ua = LWP::UserAgent->new;
132 0           $ua->agent("Mozilla/5.0 (X11; Linux; rv:8.0) Gecko/20100101");
133 0           $ua->env_proxy;
134 0           $ua->conn_cache(LWP::ConnCache->new());
135 0           $ua->timeout($timeout);
136              
137 0           foreach my $line (@text) {
138             # Get speech data from google and save them in temp files #
139 0           $line =~ s/^\s+|\s+$//g;
140 0 0         next if (length($line) == 0);
141 0           $line = escape($line);
142            
143 0           my ($mp3_fh, $mp3_name) = tempfile(
144             "tts_XXXXXX",
145             DIR => $tmpdir,
146             SUFFIX => ".mp3",
147             UNLINK => 0
148             );
149 0           my $request = HTTP::Request->new('GET' => "$url?tl=$lang&q=$line");
150 0           my $response = $ua->request($request, $mp3_name);
151 0 0         if (!$response->is_success) {
152 0           print "Failed to fetch speech data.";
153 0           return $self;
154             } else {
155 0           push(@mp3list, $mp3_name);
156             }
157             }
158              
159              
160             # decode mp3s and concatenate #
161 0           my ($wav_fh, $wav_name) = tempfile(
162             "tts_XXXXXX",
163             DIR => $tmpdir,
164             SUFFIX => ".wav",
165             UNLINK => 0
166             );
167 0           $self->{'filename'} = $wav_name;
168              
169              
170             # as WAV
171 0 0         if ($self->{'auformat'} eq 'wav') {
    0          
    0          
172 0 0         if (system($mpg123, "-q", "-w", $wav_name, @mp3list)) {
173 0           print "mpg123 failed to process sound file to WAV.";
174 0           return;
175             }
176             }
177              
178             # as MP3
179             elsif ($self->{'auformat'} eq 'mp3') {
180 0 0         if (system($mpg123, "-q", $wav_name, @mp3list)) {
181 0           print "mpg123 failed to process sound file to WAV.";
182 0           return;
183             }
184             }
185              
186              
187             elsif ($self->{'auformat'} eq 'sox') {
188             # # Set sox args and process wav file
189             # @soxargs = ($sox, "-q", $wav_name);
190             # push(@soxargs, ("tempo", "-s", $speed)) if ($speed != 1);
191             # push(@soxargs, ("rate", $samplerate)) if ($samplerate);
192             # if (system(@soxargs)) {
193             # print "sox failed to process sound file.";
194             # return;
195             # }
196             }
197             }
198 0           return($self);
199             }
200              
201             sub as_filename {
202 0     0 1   my ($self) = @_;
203 0           my $filename = $self->{'filename'};
204 0           return $filename;
205             }
206              
207             sub languages {
208 0     0 1   my ($self) = @_;
209             # the list of currently supported languages to the user or return it as a hash #
210 0           my %sup_lang = (
211             "Afrikaans", "af", "Albanian", "sq",
212             "Amharic", "am", "Arabic", "ar",
213             "Armenian", "hy", "Azerbaijani", "az",
214             "Basque", "eu", "Belarusian", "be",
215             "Bengali", "bn", "Bihari", "bh",
216             "Bosnian", "bs", "Breton", "br",
217             "Bulgarian", "bg", "Cambodian", "km",
218             "Catalan", "ca", "Chinese (Simplified)", "zh-CN",
219             "Chinese (Traditional)", "zh-TW", "Corsican", "co",
220             "Croatian", "hr", "Czech", "cs",
221             "Danish", "da", "Dutch", "nl",
222             "English", "en", "Esperanto", "eo",
223             "Estonian", "et", "Faroese", "fo",
224             "Filipino", "tl", "Finnish", "fi",
225             "French", "fr", "Frisian", "fy",
226             "Galician", "gl", "Georgian", "ka",
227             "German", "de", "Greek", "el",
228             "Guarani", "gn", "Gujarati", "gu",
229             "Hacker", "xx-hacker", "Hausa", "ha",
230             "Hebrew", "iw", "Hindi", "hi",
231             "Hungarian", "hu", "Icelandic", "is",
232             "Indonesian", "id", "Interlingua", "ia",
233             "Irish", "ga", "Italian", "it",
234             "Japanese", "ja", "Javanese", "jw",
235             "Kannada", "kn", "Kazakh", "kk",
236             "Kinyarwanda", "rw", "Kirundi", "rn",
237             "Klingon", "xx-klingon", "Korean", "ko",
238             "Kurdish", "ku", "Kyrgyz", "ky",
239             "Laothian", "lo", "Latin", "la",
240             "Latvian", "lv", "Lingala", "ln",
241             "Lithuanian", "lt", "Macedonian", "mk",
242             "Malagasy", "mg", "Malay", "ms",
243             "Malayalam", "ml", "Maltese", "mt",
244             "Maori", "mi", "Marathi", "mr",
245             "Moldavian", "mo", "Mongolian", "mn",
246             "Montenegrin", "sr-ME", "Nepali", "ne",
247             "Norwegian", "no", "Norwegian (Nynorsk)", "nn",
248             "Occitan", "oc", "Oriya", "or",
249             "Oromo", "om", "Pashto", "ps",
250             "Persian", "fa", "Pirate", "xx-pirate",
251             "Polish", "pl", "Portuguese (Brazil)", "pt-BR",
252             "Portuguese (Portugal)", "pt-PT", "Portuguese", "pt",
253             "Punjabi", "pa", "Quechua", "qu",
254             "Romanian", "ro", "Romansh", "rm",
255             "Russian", "ru", "Scots Gaelic", "gd",
256             "Serbian", "sr", "Serbo-Croatian", "sh",
257             "Sesotho", "st", "Shona", "sn",
258             "Sindhi", "sd", "Sinhalese", "si",
259             "Slovak", "sk", "Slovenian", "sl",
260             "Somali", "so", "Spanish", "es",
261             "Sundanese", "su", "Swahili", "sw",
262             "Swedish", "sv", "Tajik", "tg",
263             "Tamil", "ta", "Tatar", "tt",
264             "Telugu", "te", "Thai", "th",
265             "Tigrinya", "ti", "Tonga", "to",
266             "Turkish", "tr", "Turkmen", "tk",
267             "Twi", "tw", "Uighur", "ug",
268             "Ukrainian", "uk", "Urdu", "ur",
269             "Uzbek", "uz", "Vietnamese", "vi",
270             "Welsh", "cy", "Xhosa", "xh",
271             "Yiddish", "yi", "Yoruba", "yo",
272             "Zulu", "zu"
273             );
274 0           return %sup_lang;
275             }
276              
277              
278             =head1 AUTHOR
279              
280             Niels Dettenbach, http://www.syndicat.com
281              
282             =head1 BUGS
283              
284             Please report any bugs or feature requests to C, or through
285             the web interface at L. I will be notified, and then you'll
286             automatically be notified of progress on your bug as I make changes.
287              
288             Feel free to visit the project website http://www.syndicat.com/open_source/google/perl/googletts/
289              
290             or write to googletts@syndicat.com
291              
292              
293             =head1 SUPPORT
294              
295             You can find documentation for this module with the perldoc command.
296              
297             perldoc Speech::Google::TTS
298              
299              
300             Feel free to visit the project website http://www.syndicat.com/open_source/google/perl/googletts/
301              
302             You can also look for information at:
303              
304             =over 4
305              
306             =item * RT: CPAN's request tracker
307              
308             L
309              
310             =item * AnnoCPAN: Annotated CPAN documentation
311              
312             L
313              
314             =item * CPAN Ratings
315              
316             L
317              
318             =item * Search CPAN
319              
320             L
321              
322             =back
323              
324              
325             =head1 ACKNOWLEDGEMENTS
326              
327              
328             =head1 COPYRIGHT & LICENSE
329              
330             Copyright 2012/2013 Niels Dettenbach ,
331             with contributes of Lefteris Zafiris
332             all rights reserved.
333              
334             This program is free software; you can redistribute it and/or modify it
335             under the same terms as Perl itself.
336              
337              
338             =cut
339              
340             1; # End of Speech::Google::TTS
341              
342