Showing posts with label 音声合成. Show all posts
Showing posts with label 音声合成. Show all posts

Saturday, November 10, 2018

Raspberry Pi Jukebox (Side Story): Current State of the System

After writing just the setup post for the Jukebox project, here's where things stand now.
After voice-controlling all the living room appliances and eliminating remote controls, requests started rolling in from the household. A suggestion box was effectively established.
Quietly implementing the requests one by one, the whole thing has evolved into something hard to describe.
Not that anyone thinks of it as a "device" — devices scattered around the house all coordinate together, and nobody is keeping track of which one is the "main" unit. At this point there really isn't one.

Main System Architecture

  1. Voice Input
    Amazon Echo in the dining room.
  2. Voice Output
    Primary: the living room soundbar speakers.
    Alexa's own voice feedback still comes from the Echo itself, so there are different voices talking from different parts of the room.
  3. Control Layer
    Amazon Echo, two Raspberry Pis, Arduino, and the amplifier all work together — hard to say who's doing what.
    For voice input, the basic flow is:
    Amazon Echo → Node-RED (Raspberry Pi) → IR (Raspberry Pi) → Amp input switching & appliance control
    For scheduled automations, Raspberry Pi and the amp coordinate via IR.

Features Currently Working

  1. Voice control for TV, projector, and Roomba.
  2. Music playback through living room speakers from phone or PC.
  3. Amp input/output automatically switches based on which device is being used.
  4. Time announcements in the morning, evening, and at night.
  5. Early morning: searches YouTube for a relevant playlist and starts autoplay.
  6. Announces birthdays when they come around.
  7. Reminds kids when it's time to leave for school.
  8. The school bell plays on weekends at the same time as on school days.
  9. Time announcements rotate through multiple TTS voices at random.

Requested Features Not Yet Implemented

  1. Regarding the rotating TTS voices — the Open JTalk male voice apparently sounds like me, and my daughter has requested more of it.
  2. Got a Logicool camera from a junk bin at Hard Off for 100 yen — want to add image input to the system.
  3. No feedback path from appliances, which limits precision in some scenarios.
    (E.g., if you power off a device with its physical remote, the amp input/output combination doesn't auto-correct.)
  4. Amazon Echo can't take keyword text input, so jukebox keyword search still requires phone interaction.
  5. All the control hardware is hidden out of sight, yet the Amazon Echo is very visually prominent. Want to hide it somewhere.
  6. Want to distribute microphones around the room, but sourcing decent mics is proving difficult.
  7. Want to add an analog wall clock to the controlled devices — install a Raspberry Pi inside and turn it into a digital cuckoo clock.

Sunday, August 19, 2018

Raspberry Pi Jukebox (1): Setup and Background

I set up a system where selecting a song from YouTube on iPhone streams it through the living room speakers via Raspberry Pi.

What Was Actually Needed

This started as a request from my household's primary end user (my family),
though she wasn't initially sure what she wanted — the requirements emerged through trial and error.
In the end, it boiled down to:
  • Stream music through living room speakers.
  • Song selection by keyword — no need for favorites or playlists.
  • Easy playback start — voice or phone, either works, but no walking over to press hardware buttons.
  • iPhone must stay usable while music plays — can't be locked into one app.
  • After a song ends, auto-play related tracks.
  • Skip or switch to a different related track mid-playback if the current one is unwanted.
  • Responsiveness is nice but not critical — a slow start is tolerable since it runs continuously anyway.
  • No unwanted appliances turning on during playback.
  • A monthly subscription for content is acceptable, but only if the content library is good enough.

The Final System


The flow: tell Siri "Search YouTube for 〇〇" on iPhone, then share the result to the Workflow app, which sends a request to Node-RED on Raspberry Pi.
Alternatively, type a keyword directly into the Workflow app.

Node-RED passes the YouTube content ID or keyword to a shell script.
The shell script internally calls mps-youtube (mpsyt) to search and play the track from YouTube.

On Raspberry Pi Zero W, startup takes a while (around a minute),
so Open JTalk announces "Starting playback" to let the user know something is happening.

Once that's in place, using mpsyt's related-search commands makes continuous playback easy.
However, the system is slow enough that commands sent mid-playback sometimes don't register.
For stop and skip, the shell script force-kills the process.

As a bonus: saying "Stop the jukebox" to Amazon Echo triggers Node-RED to stop playback.

What I Tried Before Getting Here

The path to this setup involved several failed attempts:

Amazon Echo Dot + Amazon Music Unlimited

Amazon
· Selection: Amazon Echo Dot
· Content: Amazon Music
· Playback device: Amazon Echo Dot
· Output: Amazon Echo Dot

Just ask and it plays. Responsive. Great as a playback device.
But the content library wasn't satisfying enough — rejected by the household.

Looked into Google Home, but that was also vetoed immediately.

iPad + YouTube + AirPlay + Amazon Fire TV Stick

Amazon
· Selection: iPad + YouTube app
· Content: YouTube
· Playback device: iPad + AirPlay
· Output: Amazon Fire TV Stick

If Amazon Music's library isn't good enough, use YouTube.
(Apple Music was passed over on principle — the household budget follows Amazon's subscription ecosystem exclusively.)

Installed an AirPlay receiver app on Fire TV Stick and streamed YouTube audio from iPad.
Content-wise, approved. But the moment AirPlay connected to Fire TV Stick, the HDMI signal woke up the projector — rejected.
Well, it's a video playback device — what did we expect.

Also: on iPad, YouTube didn't auto-play related tracks. Complaint registered.

iPhone + YouTube + AirPlay + Raspberry Pi + Speaker

· Selection: iPhone + YouTube app
· Content: YouTube
· Playback device: iPhone + AirPlay
· Output: Raspberry Pi + speaker

If Fire TV Stick wakes the projector, go headless with Raspberry Pi.
Setup details from the earlier article.
On iPhone, YouTube related-track autoplay works.

Worked well for a while — but backgrounding the YouTube app to use the phone for something else cut the audio, which got annoying fast.
There are workarounds using the browser, but doing that every time was deemed unacceptable. Rejected.

iPhone + Workflow App + Raspberry Pi + Node-RED + YouTube + mpsyt + Open JTalk + Speaker

· Selection: iPhone + Workflow app (keyword only)
· Content: YouTube
· Playback device: Raspberry Pi + mpsyt
· Output: Raspberry Pi + speaker

This is what we landed on.
In the end, search, playback, and everything else moved to Raspberry Pi —
at which point it's basically just a music player. But it works.


Getting long — details in the next post.

Thursday, August 16, 2018

Making Raspberry Pi Speak: Japanese TTS with Open JTalk and Node-RED

Amazon After all the trial and error getting Alexa to control the Roomba, various home appliances became voice-controllable.

Convenient as it was, Alexa Home Skill always replies with a flat "OK" — not very expressive.
So I made Raspberry Pi speak more naturally when controlling appliances.

Setting Up Audio Output on Raspberry Pi

Amazon Raspberry Pi has no built-in speaker, so audio output needs to be configured.

Since the home appliances are nearby, I used HDMI output.
For how to enable HDMI audio, see the previous article: "Turning Raspberry Pi into an AirPlay Receiver".

If HDMI isn't a requirement, a USB speaker is generally better — cleaner audio and more reliable.
This site has detailed audio setup instructions.
Note: sending synthesized speech through HDMI introduces two annoyances:
  • The digital conversion doesn't start fast enough, so the first two or three syllables of each utterance get cut off.
  • If the target appliance and the Pi share the same HDMI output device, things get complicated.
For the first issue, the workaround is to add a meaningless filler word at the start of each synthesized phrase (like "OK" or "Um") so the real content starts cleanly.
For the second, the flow becomes: switch the target device's HDMI input to Raspberry Pi, play the speech, then send the appliance command.

Most devices don't auto-switch HDMI input on audio output alone,
so you'd need to copy the AV amp's IR remote codes and send the switch command manually.
The method from the Roomba series applies here.

Installing Open JTalk

Install Open JTalk, a Japanese text-to-speech (TTS) engine:
$ sudo apt-get install open-jtalk
$ sudo apt-get install open-jtalk-mecab-naist-jdic hts-voice-nitech-jp-atr503-m001
The package hts-voice-nitech-jp-atr503-m001 provides a male voice dictionary.
For a female voice (more common for TTS), download the mei voice separately:
$ wget http://downloads.sourceforge.net/project/mmdagent/MMDAgent_Example/MMDAgent_Example-1.7/MMDAgent_Example-1.7.zip
$ unzip MMDAgent_Example-1.7.zip
$ sudo cp -r ./MMDAgent_Example-1.7/Voice/mei /usr/share/hts-voice/

Making Open JTalk Speak

You can pass text and a voice dictionary as arguments directly to open_jtalk,
but it's handy to wrap it in a script like this:
#!/bin/sh

msg="$1"

voice_type=/usr/share/hts-voice/mei/mei_normal.htsvoice

echo "$msg" |
open_jtalk  -m $voice_type -x /var/lib/mecab/dic/open-jtalk/naist-jdic -ow /dev/stdout |
aplay -
Pass Japanese text as an argument to this script and it plays it back:
$ ./voice.sh "抵抗は無意味だ"

Usage Notes

Open JTalk has many synthesis options to tweak,
but in practice, adjusting them tends to degrade audio quality.
Unless you know what you're doing, sticking with the defaults is recommended.

Add the following to crontab to announce the time every hour from 7:00 to 22:00:
(If the system timezone is UTC, offset accordingly.)
$ crontab -e
0 7-22 * * * /home/pi/bin/tone.sh
The called script can be something simple like this:
#!/bin/sh

DIR=`/usr/bin/dirname $0`

y=`/bin/date +%Y`
m=`/bin/date +%-m`
d=`/bin/date +%-d`
h=`/bin/date +%-h`

msg="${y}年 ${m}月 ${d}日 ${h}時です。"

$DIR/voice.sh "$msg"

Integrating with Alexa

For how to connect Alexa Home Skill with Raspberry Pi, see the earlier explanation.
In Node-RED, insert a Shell Exec node calling the voice synthesis script before the appliance control command.

Here's an example flow. This lets Raspberry Pi say "Please wait a moment" while the projector is warming up.