Say action - different problems and solutions

Regarding the problem of the starting delay, I just tried with an uploaded MP3 music file having size 3 552 154 bytes and the playback starts immediately. So our problem is really the downloaded file size that is too small.

Next step: I will try to add enough 0 to make the file big enough…

Adding 0 to have a file size of 35000 bytes solves the problem. 8)

New problem now: the playback starts so quickly that the volume is adjusted during the playback…

I have now fixed the problem relative to the starting delay. The new code is in the trunk.
Problem with sound adjustment during playback was resolved too by replacing the StartAutoplay call.

I have added a delete of the MP3 file before its download from Google. It allows an additional control whether the download is ok or not. If I added this control, it is because I discover a case where the download fails.

Here is a call with a French text working: La température dans la salle à manger est de 19.7 degrés alors que la température à l’extérieur est
Unfortunately, this one fails: La température dans la salle à manger est de 19.7 degrés alors que la température à l’extérieur est de
The result file is empty. Is there a timeout to adjust ? Is it no more working when the sentence is too long ?

I have the same problem with this english text for example: I have now fixed the problem relative to the starting delay. The new code is in the trunk. Problem with sound adjustment during playback was resolved too by replacing the StartAutoplay call.
This one is working: I have now fixed the problem relative to the starting delay. The new code is in the trunk.

@guessed: any idea what could be wrong in our wget command ? The command seems to fail as soon as the text is to much long. Is there a limit in the size of a HTTP request ?

Note that these sentences entered directly in Google traduction are working normally.

@lolodomo,
Great stuff. Did you try padding the file using an is command (like dd) instead of in Lua? I suspect it’ll be faster.

For the failing stuff, we could be hitting a command line length limit. I’ve not seen one before, but what happens if you paste the command directly on the cmd line?

If this is the case, we can probably shorten parts of it, like the browser User-Agent string, or put the POST data into a file and have WGET use that… Again only if the cmd line length is the issue

[quote=“guessed, post:5, topic:173748”]@lolodomo,
Great stuff. Did you try padding the file using an is command (like dd) instead of in Lua? I suspect it’ll be faster.[/quote]

No but the way I do it takes around 200 ms.

For the failing stuff, we could be hitting a command line length limit. I've not seen one before, but what happens if you paste the command directly on the cmd line?

If this is the case, we can probably shorten parts of it, like the browser User-Agent string, or put the POST data into a file and have WGET use that… Again only if the cmd line length is the issue

I check…

When I type the following:

rm /www/Say.390.mp3 ; wget --output-document /www/Say.390.mp3 --quiet \ --header "Accept-Charset: utf-8;q=0.7,*;q=0.3" \ --header "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" \ --user-agent "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11" \ "http://translate.google.com/translate_tts?tl=en&q=I%20have%20now%20fixed%20the%20problem%20relative%20to%20the%20starting%20delay%2e%20The%20new%20code%20is%20in%20the%20trunk%2e%20Problem%20with%20sound%20adjustment%20during%20playback%20was%20resolved%20too%20by%20replacing%20the%20StartAutoplay%20call%2e"
I get this error:

wget: server returned error: HTTP/1.1 404 Not Found

Note that I have to modify my rm command in case the file does not exist to avoid an error. Certainly doing a “rm -f”.

Wow that’s expensive. I suspect that a dd would get you closer to a single IO operation overhead, which will be a lot smaller… Assuming the openwrt version of dd has append mode.

Wow that’s expensive. I suspect that a dd would get you closer to a single IO operation overhead, which will be a lot smaller… Assuming the openwrt version of dd has append mode.[/quote]

I checked again: it is between 20 ms for a long text approaching the current limit and 40 ms for a very short text like “test”.

wget on the Vera seems to not accept parameter “–input-file”. >:(

I tried this command:

rm /www/Say.390.mp3 ; wget --output-document /www/Say.390.mp3 --quiet \ --header "Accept-Charset: utf-8;q=0.7,*;q=0.3" \ --header "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" \ --user-agent "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11" \ --input-file /www/Say.url

and got the following return:

[code]wget: unrecognized option `–input-file’
BusyBox v1.17.3 (2012-01-09 12:40:42 PST) multi-call binary.

Usage: wget [-c|–continue] [-s|–spider] [-q|–quiet] [-O|–output-document FILE]
[–header ‘header: value’] [-Y|–proxy on/off] [-P DIR]
[–no-check-certificate] [-U|–user-agent AGENT] URL

Retrieve files via HTTP or FTP[/code]

[quote=“guessed, post:755, topic:169644”]Well, thanks to a post on the Homeseer board:
Help with TTS please! - HomeSeer Message Board

I did manage to find out how to stop the “Say” command repeating it’s content. It just needs a well-formed DIDL-Lite entry, like in this example:

luup.call_action('urn:upnp-org:serviceId:AVTransport', 'SetAVTransportURI', {CurrentURI='http://192.168.6.66:80/Say.666.mp3', CurrentURIMetaData='<DIDL-Lite xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/" xmlns:r="urn:schemas-rinconnetworks-com:metadata-1-0/" xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/"><item id="-1" parentID="-1" restricted="true"><res protocolInfo="http-get:*:audio/mpeg:*">http://192.168.6.66:80/Say.666.mp3</res><r:streamContent></r:streamContent><upnp:albumArtURI>http://www.mios.com/wp-content/themes/miostheme/images/google-logo-square.png</upnp:albumArtURI><dc:title>Vera SayIT</dc:title><upnp:class>object.item.audioItem.musicTrack</upnp:class><dc:creator>Vera Sonos Plugin</dc:creator><upnp:album>MiOS</upnp:album><r:albumArtist>Vera Sonos Plugin</r:albumArtist></item></DIDL-Lite>'}, 666) luup.call_action('urn:upnp-org:serviceId:AVTransport', 'Play', {}, 666)

It still has the timeout-oriented delays mentioned earlier, but it steps closer to a cleaner setup.[/quote]

Ok, we could add these metadata for a propoer ending.
In this case, do we change the way we trigger the restore of the playback (call_delay based on the file size) ?

Looks like Busybox has a simplified wget built in.

curl might work. Worst case we could write the whole thing in Lua using the HTTP part of LuaSocket… Kinda the way that our UPnP lib works. I originally wanted it done in the OS so it could be backgrounded, but weve moved away from that anyhow.

On the lua based padding, were making up to 600 syscalls due to the small buffer size for append. Increasing that buffer from 60 could reduce those overheads a lot.

[quote=“lolodomo, post:10, topic:173748”]wget on the Vera seems to not accept parameter “–input-file”. >:(

I tried this command:

rm /www/Say.390.mp3 ; wget --output-document /www/Say.390.mp3 --quiet \ --header "Accept-Charset: utf-8;q=0.7,*;q=0.3" \ --header "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" \ --user-agent "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11" \ --input-file /www/Say.url

and got the following return:

[code]wget: unrecognized option `–input-file’
BusyBox v1.17.3 (2012-01-09 12:40:42 PST) multi-call binary.

Usage: wget [-c|–continue] [-s|–spider] [-q|–quiet] [-O|–output-document FILE]
[–header ‘header: value’] [-Y|–proxy on/off] [-P DIR]
[–no-check-certificate] [-U|–user-agent AGENT] URL

Retrieve files via HTTP or FTP[/code][/quote]

I tried to use the old way without the wget command for long text but it does not work better, I got an error in Sonos.
It means the problem is not new.

Yes, I am using a buffer of 64 bytes but of course we can increase it.
1 Ko ?
What’s the best code to initiate a string of 1024 bytes ?

local buffer = "" for i=1, 1024 do buffer = buffer .. "0" end

I’d use string.rep() on itself and see what happens. No idea if thats the most efficient though. 1-4k chunks just to cut down on syscalls.

We can keep that buffer around if we find its expensive to create, but I doubt it.

Yes, I am using a buffer of 64 bytes but of course we can increase it.
1 Ko ?
What’s the best code to initiate a string of 1024 bytes ?

local buffer = "" for i=1, 1024 do buffer = buffer .. "0" end[/quote]

I made different tests and the size of the buffer does not make a big difference.
With “test” as text, 35 ms is the best I can get for example with a 128 bytes buffer.
Increasing the buffer size does not reduce the time.

To summarize the remaining problems:

1 - Say not working as soon as the text is of a certain length
2 - avoiding the repeat and restore the old playback context at the right time

Point 2 is partially ok but could be hopefully improved.

I would still make the write chunks 1-4k to reduce the system CPU load, and syscalls always strive up SYS CPU levels. Our end-to-end time Weill be bounded by URL calls etc,but we should minimize our CPU impact, during the time we are running, since these boxes are small and doing a bunch of other stuff that’s impacted by our resource usage.

[quote=“lolodomo, post:16, topic:173748”]I made different tests and the size of the buffer does not make a big difference.
With “test” as text, 35 ms is the best I can get for example with a 128 bytes buffer.
Increasing the buffer size does not reduce the time.[/quote]

Unfortunately I discovered that my solution produces a strange rendering of the end of the file.
I imagine it is due to the fact that the Sonos buffers a certain number of MP3 packets before playing them.
I think the solution would be to add real MP3 packets to the file, packets corresponding to silence.

@guessed: I tried to add your metadata but it does not avoid repeat of the playback.