From 8863026157235630fd023a2a2e02ab7fdbbbeac6 Mon Sep 17 00:00:00 2001 From: Arno Hautala Date: Tue, 24 Aug 2021 22:46:05 -0400 Subject: [PATCH 1/4] support for using "say" to generate voiceover files --- ipod-shuffle-4g.py | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/ipod-shuffle-4g.py b/ipod-shuffle-4g.py index 12d1860..9fb69ee 100755 --- a/ipod-shuffle-4g.py +++ b/ipod-shuffle-4g.py @@ -97,12 +97,19 @@ def group_tracks_by_id3_template(tracks, template): return sorted(grouped_tracks_dict.items()) class Text2Speech(object): - valid_tts = {'pico2wave': True, 'RHVoice': True, 'espeak': True} + valid_tts = {'pico2wave': True, 'RHVoice': True, 'espeak': True, 'say': True} @staticmethod def check_support(): voiceoverAvailable = False + # Check for say voiceover + if not exec_exists_in_path("say"): + Text2Speech.valid_tts['say'] = False + print("Warning: say not found, voicever won't be generated using it.") + else: + voiceoverAvailable = True + # Check for pico2wave voiceover if not exec_exists_in_path("pico2wave"): Text2Speech.valid_tts['pico2wave'] = False @@ -147,6 +154,8 @@ class Text2Speech(object): return True elif Text2Speech.espeak(out_wav_path, text): return True + elif Text2Speech.say(out_wav_path, text): + return True else: return False @@ -165,6 +174,13 @@ class Text2Speech(object): subprocess.call(["pico2wave", "-l", "en-GB", "-w", out_wav_path, unicodetext]) return True + @staticmethod + def say(out_wav_path, unicodetext): + if not Text2Speech.valid_tts['say']: + return False + subprocess.call(["say", "-o", out_wav_path, '--data-format=LEI16', '--file-format=WAVE', unicodetext]) + return True + @staticmethod def espeak(out_wav_path, unicodetext): if not Text2Speech.valid_tts['espeak']: @@ -464,7 +480,7 @@ class Playlist(Record): def set_master(self, tracks): # By default use "All Songs" builtin voiceover (dbid all zero) # Else generate alternative "All Songs" to fit the speaker voice of other playlists - if self.playlist_voiceover and (Text2Speech.valid_tts['pico2wave'] or Text2Speech.valid_tts['espeak']): + if self.playlist_voiceover and (Text2Speech.valid_tts['pico2wave'] or Text2Speech.valid_tts['espeak'] or Text2Speech.valid_tts['say']): self["dbid"] = hashlib.md5(b"masterlist").digest()[:8] self.text_to_speech("All songs", self["dbid"], True) self["listtype"] = 1 From 6186600e4cbea520becdda2e7856a2761622234e Mon Sep 17 00:00:00 2001 From: Arno Hautala Date: Wed, 25 Aug 2021 17:05:11 -0400 Subject: [PATCH 2/4] use double dash (--) to indicate start of voiceover text parameter --- ipod-shuffle-4g.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ipod-shuffle-4g.py b/ipod-shuffle-4g.py index 9fb69ee..70f3687 100755 --- a/ipod-shuffle-4g.py +++ b/ipod-shuffle-4g.py @@ -171,21 +171,21 @@ class Text2Speech(object): def pico2wave(out_wav_path, unicodetext): if not Text2Speech.valid_tts['pico2wave']: return False - subprocess.call(["pico2wave", "-l", "en-GB", "-w", out_wav_path, unicodetext]) + subprocess.call(["pico2wave", "-l", "en-GB", "-w", out_wav_path, '--', unicodetext]) return True @staticmethod def say(out_wav_path, unicodetext): if not Text2Speech.valid_tts['say']: return False - subprocess.call(["say", "-o", out_wav_path, '--data-format=LEI16', '--file-format=WAVE', unicodetext]) + subprocess.call(["say", "-o", out_wav_path, '--data-format=LEI16', '--file-format=WAVE', '--', unicodetext]) return True @staticmethod def espeak(out_wav_path, unicodetext): if not Text2Speech.valid_tts['espeak']: return False - subprocess.call(["espeak", "-v", "english_rp", "-s", "150", "-w", out_wav_path, unicodetext]) + subprocess.call(["espeak", "-v", "english_rp", "-s", "150", "-w", out_wav_path, '--', unicodetext]) return True @staticmethod From 37ba988b737910fcace3f836277b0c8fd6c5255d Mon Sep 17 00:00:00 2001 From: Arno Hautala Date: Sat, 28 Aug 2021 10:13:03 -0400 Subject: [PATCH 3/4] clarify macOS say provenance --- ipod-shuffle-4g.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ipod-shuffle-4g.py b/ipod-shuffle-4g.py index 70f3687..8225a56 100755 --- a/ipod-shuffle-4g.py +++ b/ipod-shuffle-4g.py @@ -103,10 +103,10 @@ class Text2Speech(object): def check_support(): voiceoverAvailable = False - # Check for say voiceover + # Check for macOS say voiceover if not exec_exists_in_path("say"): Text2Speech.valid_tts['say'] = False - print("Warning: say not found, voicever won't be generated using it.") + print("Warning: macOS say not found, voicever won't be generated using it.") else: voiceoverAvailable = True From 4a2031a821635eaa335e2440f180a4bc24c2774e Mon Sep 17 00:00:00 2001 From: Arno Hautala Date: Sun, 29 Aug 2021 10:13:24 -0400 Subject: [PATCH 4/4] mentions macOS say in readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 89ad287..6d96eb5 100644 --- a/README.md +++ b/README.md @@ -61,6 +61,7 @@ Optional Voiceover support * [PicoSpeaker](http://picospeaker.tk/readme.php) * [RHVoice (master branch, 3e31edced402a08771d2c48c73213982cbe9333e)](https://github.com/Olga-Yakovleva/RHVoice) -- (Russian files only) * [SoX](http://sox.sourceforge.net) -- (Russian files) +* say (macOS) ##### Ubuntu