Speak digits from 0 to 9 aloud
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.