You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

228 lines
8.9KB

  1. #!/usr/bin/python2.5
  2. #
  3. # Copyright 2012 Olivier Gillet.
  4. #
  5. # Author: Olivier Gillet (ol.gillet@gmail.com)
  6. #
  7. # Permission is hereby granted, free of charge, to any person obtaining a copy
  8. # of this software and associated documentation files (the "Software"), to deal
  9. # in the Software without restriction, including without limitation the rights
  10. # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. # copies of the Software, and to permit persons to whom the Software is
  12. # furnished to do so, subject to the following conditions:
  13. #
  14. # The above copyright notice and this permission notice shall be included in
  15. # all copies or substantial portions of the Software.
  16. #
  17. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  20. # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21. # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22. # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  23. # THE SOFTWARE.
  24. #
  25. # See http://creativecommons.org/licenses/MIT/ for more information.
  26. #
  27. # -----------------------------------------------------------------------------
  28. #
  29. # Waveform definitions.
  30. import numpy
  31. """----------------------------------------------------------------------------
  32. Waveforms for vowel synthesis
  33. ----------------------------------------------------------------------------"""
  34. SAMPLE_RATE = 96000
  35. waveforms = []
  36. # Create amplitude modulated sine/square tables for formants.
  37. sine_samples = []
  38. square_samples = []
  39. sine = numpy.sin(numpy.arange(16.0) / 16.0 * 2 * numpy.pi)
  40. for i, x in enumerate(sine):
  41. gains = numpy.exp(0.184 * numpy.arange(16.0))
  42. gains[0] = 0
  43. values = gains * x * 4
  44. values = numpy.round(values).astype(int)
  45. amps = numpy.round(gains)
  46. if (i >= 8):
  47. amps = -amps
  48. square_samples.extend(amps.astype(int))
  49. sine_samples.extend(values)
  50. waveforms.extend([
  51. ('formant_sine', sine_samples),
  52. ('formant_square', square_samples)
  53. ])
  54. """----------------------------------------------------------------------------
  55. Band-limited waveforms
  56. ----------------------------------------------------------------------------"""
  57. WAVETABLE_SIZE = 256
  58. # The Juno-6 / Juno-60 waveforms have a brighter harmonic content, which can be
  59. # recreated by adding to the signal a 1-pole high-pass filtered version of
  60. # itself.
  61. JUNINESS = 1.0
  62. def dither(x, order=0, type=numpy.int16):
  63. for i in xrange(order):
  64. x = numpy.hstack((numpy.zeros(1,), numpy.cumsum(x)))
  65. x = numpy.round(x)
  66. for i in xrange(order):
  67. x = numpy.diff(x)
  68. if any(x < numpy.iinfo(type).min) or any(x > numpy.iinfo(type).max):
  69. print 'Clipping occurred!'
  70. x[x < numpy.iinfo(type).min] = numpy.iinfo(type).min
  71. x[x > numpy.iinfo(type).max] = numpy.iinfo(type).max
  72. return x.astype(type)
  73. def scale(array, min=-32766, max=32766, center=True, dither_level=2):
  74. if center:
  75. array -= array.mean()
  76. mx = numpy.abs(array).max()
  77. array = (array + mx) / (2 * mx)
  78. array = array * (max - min) + min
  79. return dither(array, order=dither_level)
  80. # Sine wave.
  81. sine = -numpy.sin(numpy.arange(WAVETABLE_SIZE + 1) / float(WAVETABLE_SIZE) * \
  82. 2 * numpy.pi) * 127.5 + 127.5
  83. # Band limited waveforms.
  84. num_zones = 15
  85. bl_pulse_tables = []
  86. bl_tri_tables = []
  87. wrap = numpy.fmod(
  88. numpy.arange(WAVETABLE_SIZE + 1) + WAVETABLE_SIZE / 2,
  89. WAVETABLE_SIZE)
  90. quadrature = numpy.fmod(
  91. numpy.arange(WAVETABLE_SIZE + 1) + WAVETABLE_SIZE / 4,
  92. WAVETABLE_SIZE)
  93. fill = numpy.fmod(
  94. numpy.arange(WAVETABLE_SIZE + 1),
  95. WAVETABLE_SIZE)
  96. waveforms.append(('sine', scale(sine[quadrature])))
  97. for zone in range(num_zones):
  98. f0 = 440.0 * 2.0 ** ((18 + 8 * zone - 69) / 12.0)
  99. if zone == num_zones - 1:
  100. f0 = SAMPLE_RATE / 2.0 - 1
  101. else:
  102. f0 = min(f0, SAMPLE_RATE / 2.0)
  103. period = SAMPLE_RATE / f0
  104. m = 2 * numpy.floor(period / 2) + 1.0
  105. i = numpy.arange(-WAVETABLE_SIZE / 2, WAVETABLE_SIZE / 2) / \
  106. float(WAVETABLE_SIZE)
  107. pulse = numpy.sin(numpy.pi * i * m) / (m * numpy.sin(numpy.pi * i) + 1e-9)
  108. pulse[WAVETABLE_SIZE / 2] = 1.0
  109. pulse = pulse[fill]
  110. bl_pulse_tables.append(('bandlimited_comb_%d' % zone,
  111. scale(pulse[quadrature])))
  112. waveforms.extend(bl_pulse_tables)
  113. waveforms.extend(bl_tri_tables)
  114. """----------------------------------------------------------------------------
  115. Wavetables
  116. -----------------------------------------------------------------------------"""
  117. wavetable_data = []
  118. waves = map(ord, file('braids/data/waves.bin', 'rb').read())
  119. wavetable_data.append(('waves', waves))
  120. wave_map = map(ord, file('braids/data/map.bin', 'rb').read())
  121. wavetable_data.append(('map', wave_map))
  122. """----------------------------------------------------------------------------
  123. ???
  124. -----------------------------------------------------------------------------"""
  125. random_data = [
  126. 5, 0, 132, 0, 20, 16, 20, 81, 16, 65, 8, 17, 4, 65, 17, 5,
  127. 0, 69, 1, 88, 17, 25, 0, 132, 144, 0, 64, 80, 0, 21, 148, 0,
  128. 65, 17, 5, 129, 4, 1, 68, 1, 65, 5, 65, 17, 21, 4, 20, 16,
  129. 4, 128, 80, 0, 4, 64, 20, 21, 0, 4, 1, 20, 16, 9, 17, 68,
  130. 17, 5, 17, 4, 1, 132, 0, 65, 16, 20, 81, 145, 1, 81, 17, 21,
  131. 16, 21, 81, 1, 20, 16, 21, 68, 16, 16, 144, 5, 0, 132, 17, 4,
  132. 65, 68, 129, 65, 20, 81, 129, 0, 4, 20, 65, 129, 17, 5, 80, 5,
  133. 64, 64, 1, 132, 64, 65, 17, 68, 65, 64, 17, 5, 80, 0, 4, 1,
  134. 20, 16, 25, 64, 4, 17, 4, 20, 16, 84, 20, 128, 5, 0, 132, 0,
  135. 65, 80, 1, 65, 24, 81, 0, 129, 80, 129, 17, 5, 64, 1, 65, 64,
  136. 16, 64, 16, 64, 17, 5, 64, 1, 65, 17, 5, 17, 132, 5, 80, 1,
  137. 64, 20, 1, 16, 25, 81, 0, 80, 4, 129, 16, 5, 0, 4, 20, 16,
  138. 4, 0, 8, 16, 4, 1, 20, 81, 16, 69, 1, 8, 21, 72, 0, 80,
  139. 4, 65, 1, 0, 80, 1, 65, 0, 64, 80, 65, 17, 4, 20, 20, 129,
  140. 1, 4, 21, 20, 16, 132, 17, 5, 16, 8, 1, 4, 4, 64, 0, 4,
  141. 5, 17, 21, 81, 0, 5, 128, 0, 65, 64, 17, 4, 80, 16, 68, 0,
  142. 4, 1, 1, 89, 17, 21, 64, 80, 1, 145, 0, 68, 20, 69, 1, 88,
  143. 17, 25, 0, 132, 16, 65, 80, 1, 81, 1, 4, 21, 16, 21, 1, 16,
  144. 9, 21, 20, 128, 4, 0, 69, 16, 20, 16, 21, 81, 65, 8, 20, 4,
  145. 64, 64, 1, 132, 21, 145, 1, 64, 24, 64, 16, 4, 80, 65, 1, 9,
  146. 5, 1, 4, 65, 4, 21, 64, 1, 81, 16, 16, 144, 17, 4, 1, 4,
  147. 5, 65, 20, 128, 80, 9, 5, 1, 4, 1, 88, 0, 64, 8, 81, 80,
  148. 1, 81, 17, 0, 145, 17, 69, 1, 4, 4, 17, 4, 9, 21, 20, 128,
  149. 81, 84, 17, 64, 17, 68, 16, 8, 16, 20, 81, 0, 21, 20, 128, 144,
  150. 5, 21, 0, 4, 1, 132, 64, 129, 1, 64, 80, 1, 65, 1, 5, 1,
  151. 1, 9, 9, 81, 64, 17, 64, 20, 68, 1, 24, 0, 4, 5, 65, 69,
  152. 65, 1, 68, 16, 8, 81, 4, 5, 65, 64, 65, 17, 8, 64, 0, 64,
  153. 80, 1, 68, 0, 24, 5, 85, 4, 65, 64, 80, 16, 64, 64, 17, 64,
  154. 20, 128, 80, 65, 1, 24, 69, 21, 1, 20, 65, 4, 129, 17, 5, 65,
  155. 1, 68, 16, 68, 1, 24, 0, 20, 81, 0, 5, 65, 1, 64, 17, 21,
  156. 4, 1, 1, 25, 81, 20, 64, 64, 16, 65, 80, 17, 0, 145, 1, 65,
  157. 0, 64, 20, 16, 20, 80, 64, 65, 17, 88, 0, 64, 24, 0, 4, 5,
  158. 65, 17, 0, 145, 17, 4, 65, 4, 145, 65, 4, 65, 0, 80, 17, 5,
  159. 80, 0, 4, 1, 1, 89, 0, 64, 4, 65, 8, 81, 80, 0, 88, 0,
  160. 64, 64, 0, 8, 17, 133, 65, 8, 64, 80, 64, 0, 24, 1, 5, 80,
  161. 17, 5, 8, 21, 0, 20, 81, 0, 149, 5, 0, 132, 0, 20, 16, 20,
  162. 81, 16, 65, 24, 16, 4, 65, 17, 5, 81, 1, 20, 17, 0, 88, 0,
  163. 64, 20, 16, 9, 5, 1, 4, 1, 8, 81, 17, 5, 65, 24, 65, 16,
  164. 64, 80, 0, 4, 64, 4, 128, 80, 65, 1, 8, 64, 5, 5, 65, 20,
  165. 128, 80, 25, 16, 21, 81, 0, 21, 1, 16, 9, 64, 64, 16, 64, 20,
  166. 84, 16, 16, 144, 20, 0, 21, 16, 68, 16, 65, 9, 16, 20, 81, 16,
  167. 8, 25, 16, 20, 81, 0, 5, 17, 4, 1, 68, 1, 0, 80, 5, 0,
  168. 4, 65, 132, 65, 4, 5, 65, 4, 129, 5, 0, 132, 1, 20, 81, 17,
  169. 5, 65, 17, 0, 145, 16, 5, 0, 20, 145, 16, 69, 16, 132, 20, 20,
  170. 65, 80, 17, 68, 1, 8, 20, 8, 25, 20, 81, 0, 68, 1, 0, 80,
  171. 16, 65, 64, 1, 65, 1, 5, 20, 20, 129, 1, 65, 17, 21, 84, 4,
  172. 64, 21, 1, 16, 9, 64, 68, 64, 65, 17, 8, 0, 20, 81, 16, 9,
  173. 16, 4, 5, 129, 5, 0, 68, 1, 145, 1, 65, 17, 5, 80, 16, 64,
  174. 1, 8, 16, 4, 1, 4, 20, 16, 20, 144, 64, 9, 21, 16, 4, 65,
  175. 17, 5, 64, 0, 88, 0, 64, 8, 65, 17, 21, 81, 81, 16, 16, 144,
  176. 144, 0, 4, 80, 1, 20, 64, 20, 24, 16, 4, 0, 20, 81, 16, 4,
  177. 80, 0, 24, 81, 0, 129, 16, 5, 0, 20, 81, 17, 5, 17, 4, 128,
  178. 80, 65, 1, 24, 16, 5, 20, 0, 20, 0, 4, 1, 68, 0, 24, 0,
  179. 4, 80, 16, 4, 64, 9, 16, 4, 65, 17, 21, 9, 25, 80, 64, 65,
  180. 1, 24, 81, 0, 129, 16, 81, 0, 21, 80, 24, 0, 20, 81, 1, 144,
  181. 80, 89, 0, 64, 8, 16, 4, 5, 129, 20, 20, 128, 17, 5, 16, 88,
  182. 0, 64, 8, 65, 17, 21, 81, 81, 16, 16, 144, 4, 0, 69, 16, 20,
  183. 16, 21, 0, 20, 81, 1, 20, 16, 25, 1, 5, 80, 64, 89, 80, 16,
  184. 64, 1, 5, 20, 20, 65, 16, 16, 144, 5, 0, 132, 1, 64, 80, 16,
  185. 84, 20, 20, 64, 4, 129, 5, 4, 17, 84, 17, 69, 1, 24, 0, 4,
  186. 21, 16, 20, 80, 17, 0, 145, 16, 5, 84, 0, 128, 5, 0, 132, 1,
  187. 4, 65, 64, 65, 1, 5, 64, 16, 16, 144, 16, 5, 0, 4, 85, 16,
  188. 17, 65, 0, 8, 0, 4, 5, 17, 4, 17, 68, 65, 64, 65, 17, 4,
  189. 16, 1, 24, 81, 20, 64, 64, 16, 65, 144, 16, 5, 0, 4, 4, 64,
  190. 16, 65, 4, 65, 20, 64, 16, 16, 144, 5, 0, 4, 85, 16, 17, 65,
  191. 0, 24, 0, 20, 16, 9, 64, 21, 81, 1, 65, 1, 5, 0, 4, 5,
  192. 80, 0, 68, 65, 16, 16, 80, 255
  193. ]
  194. wavetable_data.append(('code', random_data))