Festival Text to Speech PHP Extension

A while ago I knocked up a quick PHP extension to link it to the text to speech C++ library festival. I did this mainly to learn a little more about extension writing. I chose festival because it is well documented and testing is kind of fun.

I’ve put the very rough results up on git hub here.

So far the linking doesn’t look for the headers in many places yet and I have only ever built it on Ubuntu. If you are using ubuntu you will need to install the festival packages.

sudo apt-get install festival festival-dev

and to make it more fun some alternative voices

sudo apt-get install festvox-don festvox-italp16k

Then it’s just a matter of changing into the festival_php root

phpize
./configure
make
make install

You will than be able to create a Festival_FestivalClass and send it text

$festObj = new Festival_FestivalClass();
$festObj->sayText('php '.phpversion());

Or make it read out a file

$festObj = new Festival_FestivalClass();
$festObj->sayFile(__FILE__);

To use a slightly less wooden sounding voice than the default

$festObj = new Festival_FestivalClass();
$festObj->evalCommand('voice_don_diphone');
$festObj->sayText('I am a different voice');

There is also a function which will take a string and convert it to a wav

$festObj = new Festival_FestivalClass();
$festObj->textToWave('I am in a wav file');

This will currently create a file named wave.wav in your /tmp directory although this function will in future allow you to specify the filename and possibly return it.

As to uses. At the moment I can only think of one and that is in creating accessable CAPTCHA text. It’s just a bit of fun and the code isn’t the best but let me know if you find this and manage to get it running and certainly if you find any problems.

Compiling Festival C++ client on Ubuntu

I’ve been doing some experiments with the C++ API of the festival text to speech library. The documentation describes gives a code snippet to use this API. So far I’ve successfully manged to compile a C++ snippet like the one below

#include<stdio.h>
#include<festival.h>
int main(int argc,char **argv)
{
int heap_size=210000;
int load_init_files=1;
festival_initialize(load_init_files,heap_size);
festival_say_text("it is lunch time");
festival_wait_for_spooler();
return 0;
}

I compiled it with the following line which is highly specific to Ubuntu Lucid Lynx

sudo g++ main.cc -l Festival -I/usr/include/festival  -I/usr/lib/speech_tools/include -leststring -lestools -lestbase -o nat.out

Ibuildings Elephpants Challenge and Xdebug profiling on the command line

My employer ibuildings is currently running a competition. The challenge provoked some disccussion amongst my fellow developers, so a separate internal competition was announced with the same challenge but slightly smaller prizes.

The challenge is an interesting one and has quite a lot in common with the sudoku problem I published. I’ve been working on a solution for a little while now. Initially my first working solution took 5 seconds to run. But then while driving along a motorway I had sudden inspiration about how to shorten the algorithm. A little more work I was fairly happy with my solution which was taking just under a second to run and weighed in at 150 or so lines of code. Never the less I decided to profile what I’d written. To run a script with xdebug profiler I did this

 XDEBUG_CONFIG="profiler_enable=1" php myScript.php

This created a chachegrind dump in my /tmp directory. The initial dump was 20 Mb not a good sign! To look at the cachegrind output I used webgrind. The features implemented are a small subset of those of kcache grind but I didn’t have a linux desktop to hand.

By moving some code around to create less function calls I halved the size of the dump file and also the execution time.

Next I noticed that a array_key_exists was being called 12000 times. Hmmm isset would do and and is marginally faster the two functions differ in their treatment of nulls. Normally I’m not in favour or micro optimizations like this but when a function is being called that many times the choice of function can make a huge difference. A few more tweaks and the cache grind dump file size continued to fall. I’m now pretty pleased to say execution time is about 0.2 seconds and the code has actually shrunk to 146 lines.

Profiling certainly proved it’s worth no matter how well I thought I knew how the code was executing there were some suprises.

Unable to save result set … : tracking down the query in Drupal

I started getting a warning appearing in my logs generated by mysql_query

mysql_query() [function.mysql-query]: Unable to save result set in /includes/database.mysql.inc on line 116.

Ok so this was obviously a problem with one query that was either hitting a corrupt table or was in error in some other way.

The only problem is that of course that in Drupal in common with most modern PHP applications mysql_query is wrapped in some way so that all queries will pass through this line. Added to that nothing seemed to be reported either by mysql_error() or mysql_errno I was getting frustrated about finding out which of the 30 or so queries on the page were in generating the error. Finally I read the mysql_query docs carefully and discovered that if the $result of the function is false there had been an error it simply remained to output the query that returned false.

    $result = mysql_query($query, $active_db);
if (false === $result) {
var_dump($query);
}

From then it was just a simple matter of running the query in the mysql client. The error turned out to be a subquery returning more than one row.

Password Protecting Cruisecontrol / Solr in a Jetty Web Server

A couple of times now I’ve had to add password authentication to the Jetty Web server. Once for an installation of cruisecontrol and once for for an apache solr installation.

I’m used to just adding password authentication to a .htaccess file in apache configuring Jetty is a little more complicated but not much more. There are already many good how tos out there but if you don’t know what you are looking for and the keywords are: jetty security-constraint.

For the record here is how I did it:

In the web.xml of your web app e.g. cc-config/WEB-INF/web.xml inside the webapp definition you can put something like this

  <security-constraint>
    <web-resource-collection>
      <web-resource-name>Protected Resouce</web-resource-name>
      <url-pattern>/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
      <role-name>user</role-name>
    </auth-constraint>
  </security-constraint>
  <login-config>
    <auth-method>BASIC</auth-method>
    <realm-name>Test Realm</realm-name>
  </login-config>

This says you need to be a member of role user to be able to view anything in the webroot. It also says use basic http aithentication for the user realm Test Realm.

Then alter etc/jetty.xml to make sure it includes something like:

    <Set name="UserRealms">
      <Array type="org.mortbay.jetty.security.UserRealm">
        <Item>
          <New class="org.mortbay.jetty.security.HashUserRealm">
            <Set name="name">Test Realm</Set>
            <Set name="config"><SystemProperty name="jetty.home" default="."/>/etc/realm.properties</Set>
            <Set name="refreshInterval">0</Set>
          </New>
        </Item>
      </Array>
    </Set>

You may just need to uncomment the above section from an example.

Finally set the pass word in etc/realm.properties with line like this

username: MD5:md5hash,user

Where md5hash is a hash you generated by some means.