Skip to content

Commit

Permalink
add astromech short voice
Browse files Browse the repository at this point in the history
  • Loading branch information
vigonotion committed May 22, 2023
1 parent 52f3de1 commit 79fca42
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 5 deletions.
17 changes: 13 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
# Text to Astromech integration for Home Assistant (R2D2 Beep Boop Sounds)

**This integration will set up the following platforms**
Generate Astromech sounds in Home Assistant!

Platform | Description
-- | --
`tts` | Generate astromech sounds and play them on supported media players
You have the choice between these voices:

- __Astromech__: Each letter in your TTS message is assigned to a sound. You can check the sounds here: https://github.com/MomsFriendlyRobotCompany/ttastromech/tree/master/ttastromech/sounds
- __Astromech (short)__: The TTS message gets hashed into a 6 letter word, which is then forwarded to the Astromech voice. This helps with long TTS messages that are generated for example by Assist.

***

## Installation using HACS

Expand Down Expand Up @@ -32,3 +35,9 @@ This component is available via HACS as a [custom repository](https://hacs.xyz/d
If you want to contribute to this please read the [Contribution guidelines](CONTRIBUTING.md)

***

## Special thanks

- `ttastromech` for the awesome python library: https://github.com/MomsFriendlyRobotCompany/ttastromech
- https://github.com/hug33k/PyTalk-R2D2 on which `ttastromech` is based on
- Leylosh's Scratch project for the sounds used by the libraries above (https://scratch.mit.edu/projects/766189/)
3 changes: 3 additions & 0 deletions custom_components/astromech/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@
DOMAIN = "astromech"
VERSION = "0.0.0"
ATTRIBUTION = ""

VOICE_ASTROMECH = "astromech"
VOICE_ASTROMECH_SHORT = "astromech_short"
37 changes: 36 additions & 1 deletion custom_components/astromech/tts.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,39 @@
from typing import Any
from homeassistant.components import tts
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.components.tts.models import Voice

import re
import random
import string
import wave
import hashlib

from ttastromech import TTAstromech

from .const import VOICE_ASTROMECH, VOICE_ASTROMECH_SHORT


def generate_hash(input, length):
"""Generate hash."""
md5_hash = hashlib.md5(input.encode()).hexdigest()
hash_length = len(md5_hash)
ratio = hash_length / length
result = ""

for i in range(length):
start = int(i * ratio)
end = int((i + 1) * ratio)
substring = md5_hash[start:end]
ascii_sum = sum(ord(c) for c in substring)
char_index = ascii_sum % 26
char = chr(ord("a") + char_index)
result += char

return result


def replace_non_alpha_chars(text):
"""Replace invalid characters with a random lowercase ascii letter."""
Expand Down Expand Up @@ -62,11 +85,23 @@ def supported_options(self) -> list[str]:
"""Return a list of supported options."""
return [tts.ATTR_VOICE]

@callback
def async_get_supported_voices(self, language: str) -> list[Voice] | None:
"""Return a list of supported voices for a language."""
return [
Voice(VOICE_ASTROMECH, "Astromech"),
Voice(VOICE_ASTROMECH_SHORT, "Astromech (short)"),
]

def get_tts_audio(
self, message: str, language: str, options: dict[str, Any] | None = None
) -> tts.TtsAudioType:
"""Load tts audio file from the engine."""
slug = replace_non_alpha_chars(message.lower())

if options.get("voice") == VOICE_ASTROMECH_SHORT:
slug = generate_hash(message.lower(), 6)

data = self._r2.generate(slug)

output_stream = io.BytesIO()
Expand Down

0 comments on commit 79fca42

Please sign in to comment.