Category Archives: Development

Net_DNS2 Version 1.2.0

I’ve released a new version of the PEAR Net_DNS2 library- you can install it now through the command line PEAR installer:

pear install Net_DNS2

Or download it directly from the Google Code page here.

This release includes a significant speed-up with the local cache by using JSON to encode the cache data, rather then the PHP serialize function. Using JSON loses the class information of the objects, but the data remains the same, and the serialization time is about half.

A Query lookup against Google DNS- NO cache

time: 0.0340800285339

        Net_DNS2_RR_A Object
        (
            [address] => 199.59.148.82
            [name] => twitter.com
            [type] => A
            [class] => IN
            [ttl] => 28
            [rdlength] => 4
            [rdata] => 
        )

with cache + serialize

time: 0.00258994102478

        Net_DNS2_RR_A Object
        (
            [address] => 199.59.148.82
            [name] => twitter.com
            [type] => A
            [class] => IN
            [ttl] => 28
            [rdlength] => 4
            [rdata] => 
        )

with cache + json

time: 0.00178384780884

        stdClass Object
        (
            [address] => 199.59.148.82
            [name] => twitter.com
            [type] => A
            [class] => IN
            [ttl] => 28
            [rdlength] => 4
            [rdata] => 
        )

Version 1.2.0

This version changes the way some exceptions are thrown, and may break your code!

  • added numeric error codes to the Lookups class, and had each method that throws an exception throw a numeric error code along with the message.
  • dropped all references to InvalidArgumentException; we only use the Net_DNS2_Exception from now on.
  • added the CAA, URI, TALINK, CDS and TA resource records. Some of these are experimental, but are pretty straight forward.
  • fixed a bug in formatString(); my version was only putting double quotes around strings that have spaces, but apparently ALL strings should have double quotes around them. This is how BIND does it.
  • re-organized the Net_DNS2_Lookups initialization code; it no longer creates a global object of itself.
  • fixed a bug in the caching code; in some cases it wouldn’t cache the same content more then once.
  • added an option to use JSON to serialize the cache data rather than using the PHP serialize function. JSON is much faster, but loses the class definition, and becomes a stdClass object.
  • fixed a handful of cases where I was using double quotes (“) where a single quote (‘) would be fine.

Net_DNS2 Version 1.1.0

Net_DNS2 version 1.1.0 is now available for download from the PEAR site, or can be installed using the “pear” command line client like:

pear install Net_DNS2

This release includes support for signing DNS updates and zone transfers (AXFR’s) using SIG(0), a private/public key authentication mechanism. The OpenSSL PHP extension is required for this feature to work.

//
// create a new Updater object
//
$u = new Net_DNS2_Updater('example.com', array('nameservers' => array('192.168.0.1')));

//
// add a SIG(0) to authenticate the request
//
$u->signSIG0('/etc/namedb/Kexample.com.+001+15765.private');

//
// send the update rquest.
//
$u->update();

Support for the ATMA resource record- a method for publishing ATM addresses via DNS.

@      IN    SOA    name1.data.example.com.  name4.data.example.com. (
                                  1994041800   ; Serial  - date
                                  1800         ; Refresh - 30 minutes
                                  300          ; Retry   - 5 minutes
                                  604800       ; Expire  - 7 days
                                  3600 )       ; Minimum - 1 hour
       IN    NS     name1.data.example.com.
       IN    NS     ns.example.com.
;

salmon IN    ATMA   39.246f.000e7c9c031200010001.000012345678.00

And a new simple local cache system, using shared memory (using the PHP Shmop Extension), or using a flat file.

$r = new Net_DNS2_Resolver(array(

        'cache_type'    => 'shared',
        'cache_file'    => '/tmp/net_dns2.cache',
        'cache_size'    => 100000
));

Caching is disabled by default, and is only used for DNS queries (and not for updates), but can drastically improve query performance.

For more details, see the Net_DNS2 Google Code Page.

PERL Text-to-Speech using Cepstral voices (libswift)

I’ve released two new PERL modules:

Speech::Swift – a PERL interface to the Cepstral text-to-speech engine, Swift.

and

Speech::Swift::Simple – a simplified interface to Speech::Swift

The libswift shared library is required to support this code, which is included with every voice downloaded from Cepstral.

The reason for two releases, is that the Speech::Swift module exports all (well, almost all) the underlying functions of the libswift.so library, while Speech::Swift::Simple has a simplified interface to generate speech in a just a few function calls.

For example:

#!/usr/bin/perl

use Speech::Swift::Simple;

#
# create a new Speech::Swift::Simple with one channel audio, and 16bit encoding.
#
my $s = new Speech::Swift::Simple(
         channels => 1,
         encoding => Speech::Swift::AUDIO_ENCODING_PCM16
);

#
# set the voice to use by name
#
$s->set_voice("Allison");

#
# synthesize the text, and return it as a Speech::Swift::Simple::Wav object
#
my $wav = $s->generate("My name is allison");

#
# write the wav object to a file.
#
$wav->write("test.wav");

Or use the Speech::Swift library directly, for a more low-level interface.

The audio output is always as a WAV file; you can use one of the many audio modules available from CPAN, like Audio::GSM or Audio::MPEG, to re-encode the audio as needed.

Both PERL modules are available for download from CPAN now.

First Release of PHP Swift TTS Extension

I’m happy to announce the first release of the Swift Text-To-Speech PHP extension; the swift engine is the free TTS engine provided with any Cepstral TTS voice. A lot of Asterisk fans out there will recognize the Cepstral Allison voice, as the default voice for Asterisk installations.

The extension will only work on systems support by the Swift engine, and has only been tested (so far) on Linux (CentOS).

The extension will generate audio based on the text provided, and can be exported in several different audio formats, including:

  • PCM (RAW audio)
  • u-law / a-law (logarithmically encoded RAW audio)
  • WAV (RAW audio)
  • GSM (when compiled with the libgsm library)
  • MP3 (when compiled with the libmp3lame library)

A simple example on how to use this:

//
// create the new TTS object
//
$tts = new SwiftTTS();

//
// set a voice to use for generation
//
$tts->setVoice("Allison");

//
// generate text, and return a stream for the audio
//
$s = $tts->generate("hello my name is allison", SwiftTTS::FORMAT_WAV);
if ($s !== false)
{
        //
        // write the stream contents to a file
        //
        file_put_contents("audio.wav", $s);
}

For more details, and to download the current version, see the Google Code page.

Accessing Google Speech API / Chrome 11

I’ve posted an updated version of this article here, using the new full-duplex streaming API.

Just yesterday, Google pushed version 11 of their Chrome browser into beta, and along with it, one really interesting new feature- support for the HTML5 speech input API. This means that you’ll be able to talk to your computer, and Chrome will be able to interpret it. This feature has been available for awhile on Android devices, so many of you will already be used to it, and welcome the new feature.

If you’re running Chrome version 11, you can test out the new speech capabilities by going to their simple test page on the html5rocks.com site:

http://slides.html5rocks.com/#speech-input

Genius! but how does it work? I started digging around in the Chromium source code, to find out if the speech recognition is implemented as a library built into Chrome, or, if it sends the audio back to Google to process- I know I’ve seen the Sphynx libraries in the Android build, but I was sure the latter was the case- the speech recognition was really good, and that’s really hard to do without really good language models- not something you’d be able to build into a browser.

I found the files I was looking for in the chromium source repo:

http://src.chromium.org/viewvc/chrome/trunk/src/content/browser/speech/

It looks like the audio is collected from the mic, and then passed via an HTTPS POST to a Google web service, which responds with a JSON object with the results. Looking through their audio encoder code, it looks like the audio can be either FLAC or Speex– but it looks like it’s some sort of specially modified version of Speex- I’m not sure what it is, but it just didn’t look quite right.

If that’s the case, there should be no reason why I can’t just POST something to it myself?

The URL listed in speech_recognition_request.cc is:

https://www.google.com/speech-api/v1/recognize

So a quick few lines of PERL (or PHP or just use wget on the command line):

#!/usr/bin/perl

require LWP::UserAgent;

my $url = "https://www.google.com/speech-api/v1/recognize?xjerr=1&client=chromium&lang=en-US";
my $audio = "";

open(FILE, "<" . $ARGV[0]);
while(<FILE>)
{
    $audio .= $_;
}
close(FILE);

my $ua = LWP::UserAgent->new;

my $response = $ua->post($url, Content_Type => "audio/x-flac; rate=16000", Content => $audio);
if ($response->is_success)
{
    print $response->content;
}

1;

This quick PERL script uses LWP::UserAgent to POST the binary audio from my audio clip; I recorded a quick wav file, and then converted it to FLAC on the command line (see SoX for more info)

To run it, just do:

[root@prague mike]# ./speech i_like_pickles.flac

The response is pretty straight forward JSON:

{
    "status": 0,
    "id": "b3447b5d98c5653e0067f35b32c0a8ca-1",
    "hypotheses": [
    {
        "utterance": "i like pickles",
        "confidence": 0.9012539
    },
    {
        "utterance": "i like pickle"
    }]
}

I’m not sure if Google is intending this to be a public, usable web service API, but it works- and has all sorts of possibilities!