2

I am working here on a MacBook with El Capitan on it. OS X has an integrated text to speech program, that you can use via the command say.

The problem I have with this command is that my MacBook is kind of old and runs out of RAM quickly. So, I can use this command, but the first two sentences will sound really off, while the next sentences sound perfect.

I use the say command at the end of my alarm and egg-timer script, giving out a message. Right now I use bsay which is a little script written by me:

#!/bin/bash

path="/Users/joe/.joe_script/resources/bsay/"
name=".$(date "+%s").ogg"
say -o ${path}$name "$*"
afplay ${path}$name
rm $path$name

This works quite fine so far. Yet, I think it should even be better. I wanted to hold it in RAM and play it in RAM instead of writting it down on my drive. I have just no clue how to archieve that. At first, I imagined a single string would do it. I tried to simply do it by using the following line:

audio=$(say "Whatever I want to say")

It spoke it aloud instead. Than I thought, I just add prove of concept and tried this:

say -o output.ogg "Whatever I want to say"
audio="$(cat output.ogg)"
afplay $audio

That just gave me an explanation how afplay works... okay, bummer.. afplay doesn't support variables. But as a prove of concept, I tried this:

say -o output.ogg "Whatever I want to say"
audio="$(cat output.ogg)"
echo $audio >> output2.ogg
afplay output2.ogg

Which in turn did only give me back an error message:

Error: AudioFileOpen failed ('typ?')

So, I assume I am far off with my attempts. Can someone give me any hints or directions in which I could archieve something like that?

TheCommoner282
  • 205
  • 1
  • 7

1 Answers1

2

Your attempts are very logical and only fails because bash variables can't contain NUL bytes:

var=$'\0foobar'
[[ -z $var ]] && echo "Bash thinks the string is empty :( "

There are multiple options:

  • Just stick with a temp file. Because it's so short lived, it might never reach the disk anyways

  • Create a ram disk and store the file there.

  • Use base64 or similar to convert binary data to text and back, so you can keep it in a variable.

  • Pipe to a tool like sponge that can soak up input and then output it all at once.

Getting say to pipe audio data instead of writing to a file is another matter, and may require workarounds like named pipes.

Community
  • 1
  • 1
that other guy
  • 116,971
  • 11
  • 170
  • 194