PageRenderTime 26ms CodeModel.GetById 15ms app.highlight 8ms RepoModel.GetById 1ms app.codeStats 0ms

/utils/make_sounds.py

http://eyes-free.googlecode.com/
Python | 88 lines | 75 code | 1 blank | 12 comment | 1 complexity | aa9a9ff26b685d32a13ad4bf71b3ad48 MD5 | raw file
 1#!/usr/bin/python2.4
 2# Copyright 2008 Google Inc. All Rights Reserved.
 3
 4""" Script to generate wav files for a bunch of letters, numbers,
 5 and short phrases using the Mac's built-in "say" command and the open-source"sndfile-convert" program (part of "libsndfile")
 6 On a big-endian machine (PPC Mac), replace '-s2 01' with '-s2 10', below
 7"""
 8 
 9 
10import sys, os
11
12def exists(filename):
13  return os.access(filename, os.F_OK)
14
15def run(cmd):
16  print "    %s" % cmd
17  status = os.system(cmd)
18  if status != 0:
19    sys.exit(status)
20
21lexicon = [
22  "button",
23  "clear",
24  "cleared",
25  "dial",
26  "dialing mode",
27  "disabled",
28  "edit text",
29  "list item",
30  "phone number",
31  "text view",
32  "you are about to dial"]
33
34# alphabet
35lexicon += [chr(i) for i in range(ord('a'), ord('z') + 1)]
36# digits
37lexicon += [chr(i) for i in range(ord('0'), ord('9') + 1)]
38
39def main ():
40  "Generate the samples we need."
41
42  # create a 200-ms silent file to append
43  num_silent_samples = 4410
44  fp = open('silent_padding.raw', 'w')
45  fp.write('\0' * num_silent_samples * 2)
46  fp.close()
47
48  for word in lexicon:
49    filename = (word + '.wav').replace(' ', '_')
50    if len(word) == 1 and ord(word) >= ord('0') and ord(word) <= ord('9'):
51      filename = 'num' + filename
52    if not exists(filename):
53      print '%s -> %s' % (word, filename)
54      # Execute TTS and get an AIFF file
55      run('echo "[[rate 280]] %s" | say -f - -o tmp.aiff' % word)
56      # Convert to RAW
57      run('sndfile-convert tmp.aiff tmp.raw')
58      # Get its length
59      num_samples = len(open('tmp.raw').read()) / 2
60      # Create a NIST header (easy text format for audio header)
61      fp = open('header.nist', 'w')
62      header_text = (
63          'NIST_1A\n   1024\nchannel_count -i 1\nsample_rate -i 22050\n'
64          'sample_n_bytes -i 2\nsample_sig_bits -i 16\n'
65          'sample_coding -s3 pcm\nsample_byte_format -s2 01\n'
66          'sample_count -i %d\n'
67          'end_head') % (num_samples + num_silent_samples)
68      # Write the header, padded to exactly 1024 bytes
69      fp.write(header_text + ('\0' * (1024 - len(header_text))))
70      fp.close()
71      # Append header and silence
72      run('cat header.nist tmp.raw silent_padding.raw > combined.nist')
73      # Convert final result to WAV
74      run('sndfile-convert combined.nist %s' % filename)
75    else:
76      print '%s -> %s (already exists)' % (word, filename)
77
78  print "Cleaning up"
79  run('rm -f header.nist')
80  run('rm -f tmp.aiff')
81  run('rm -f tmp.raw')
82  run('rm -f silent_padding.raw')
83  run('rm -f combined.nist')
84
85
86if __name__ == '__main__':
87  main()
88