Speak digits from 0 to 9 aloud Inspired by this question from electronics.SE, here's a challenge for you:

Write a program or subroutine that takes in a sequence of decimal digits (0 to 9) and speaks them aloud, without using an existing speech synthesis tool.

Input:

You may ask for the input digits to be provided in any reasonable format, e.g. as a string of ASCII digits, an array of integers, a BCD-encoded number, etc.  If your solution is an executable program, you may take the input as a command line parameter, read it from standard input, or obtain it in any other reasonable manner.

Your program must be able to speak at least eight digits per invocation.  You may assume that the first digit is not zero, unless it is the only digit.

Output:

Your program may either speak the numbers directly using an audio device, or it may output a playable sound file.  The output file, if any, may be in any standard audio format, or it may consist of raw sample data.  If you output raw sample data, please note the appropriate parameters for playback (sample rate, bits per sample, endianness, signed/unsigned, # of channels).  Formats supported by aplay are preferred.

You are free to decide the details on how the numbers will be spoken, but your output should consist of English language digits spoken in a manner understandable to a typical English speaker, and it should be clear enough for the listener to be able to accurately transcribe a spoken eight-digit random number.  No, just beeping n times doesn't count.  Don't forget to include pauses between the digits.

Scoring:

Standard code-golf scoring rules apply: Your score is the length of your code in bytes or, if your code is written in Unicode text, in Unicode characters.  Lowest score wins.  Any language goes.

As the original question on electronics.SE was about embedded programming, I felt it would be appropriate to toss a bone to authors using low-level languages: if your solution is written in a compiled language, you may choose to count the length of the compiled executable file in bytes as your score.  (Yes, precompiled bytecode, such as a Java .class file, is OK too.)  If you choose to make use of this option, please include a copy of the compiled executable in your answer (e.g. as a hex dump) along with your source code and the compiler version and options you used to generate it.

An honorable mention, along with a +50 rep bounty, will be granted to the first answer that also meets the criteria of the original question, i.e. is capable of running on an embedded MCU with 4 kb of flash and 1 kb of SRAM.

Restrictions:

You may not make use of any files or network resources that are not part of your chosen language's standard runtime environment, unless you count the length of said files or resources as part of your score.  (This is to disallow e.g. loading audio samples from the web.)

You may also not use any pre-existing speech synthesis tools or libraries or compilations of audio data (unless you also count their size as part of your score), even if they're included in your chosen language's standard runtime environment.
ruby - 3710 = 90 characters code + 3620 bytes data
require'zlib'
$&gt;&lt;&lt;$*[0].chars.map{|x|Zlib::Inflate.inflate File.open(x).read}.join(?0*5e3)

input: a single command line argument, the number to read
output: raw sound data, PCM 8bit/8kHz
This can read any input string, as long as

it only contains characters that are valid file names. for only four chars, you can enlarge that set to all characters.
you have the neccessary files.
why oh you space dee oh en apostrophe tee space em i en dee space tee aitch i es period

5e3 encodes the pause between two words. Here, 5ksamples ~= 0.6s. Tweak as desired.
Now, the tricky part is to get the sample files in 4K and yet be able to decompress them easily and in sufficient quality. Here is how I got them:

Take a Text-to-speech engine able to produce sound files. Wikipedia has one.
Feed it a text containing all digits, ideally close together. I used http://en.wikipedia.org/wiki/Base_13
Downsample.
Cut out each part in a sound editor.
Save as a raw file.
Decimate each sample (discard low-order bits).
Deflate.

Now, one has to choose a sample rate and decimation amount. Too much, and the sound won't be understandable. Too little, and you don't fit. I have settled for 8kHz/3b. There they are: https://github.com/honnza/drops/raw/master/digits.zip

8KHz * 4b/sample and higher quality - too big
8KHz * 3b/sample - low quality, but it fits into 4K
8KHz * 2b/sample - kch kchhhhhhhhh [not understandable]
2KHz * 8b/sample - too big
2KHz * 3b/sample - kch kchhhhhhhhh
1KHz * 8b/sample - kch kchhhhhhhhh

Here's the decimation script:
require'zlib'
Dir.glob &quot;*.raw&quot; do |fname|
  File.open fname[/\d/], &quot;wb&quot; do |out|
    File.open fname do |input|
      bytes = input.bytes.to_a
      bytes.map! {|x|x&amp;0xE0}
      dfl = Zlib::Deflate.deflate(bytes.pack(&quot;C*&quot;),9)
      dfl.each_byte do |byte|
        out.print byte.chr
      end
      puts &quot;done #{fname}: #{dfl.size}&quot;
    end
  end
end

As for the original challenge: there are 476 bytes of space for code and the file table. This might be slightly too much depending on how tiny we can get with a DEFLATE library. If neccessary, we can cut a few corners here and there by cropping the audio samples a bit more aggresively. [fo:r] or [o:] doesn't really matter but it saves bytes. I have been somewhat benevolent when cropping the numbers. Also, a different decimation scheme or sacrificing some decimation for downsampling might help - I'll toy with these later. Also, dropping the DEFLATE headers might save a tiny amount of space.
Concatenating sound samples is quite easy, but 4K is a little cramped. If you are not bound by 4k space, I suggest less decimation. 4 bits per sample actually fares quite well and is only slightly bigger.