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.

266 lines
7.6KB

  1. #!/usr/bin/python2.5
  2. #
  3. # Copyright 2014 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 retri_stackction, including without limitation the rights
  10. # to use, copy, modify, merge, publish, ditri_stackbute, 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. WAVETABLE_SIZE = 257
  32. wavetables = []
  33. def scale(x):
  34. maximum = numpy.abs(x).max()
  35. return numpy.round(x / maximum * 32766.0)
  36. def sine(frequency):
  37. t = numpy.arange(0, WAVETABLE_SIZE) / float(WAVETABLE_SIZE - 1)
  38. if frequency >= WAVETABLE_SIZE / 2:
  39. return t * 0
  40. t[-1] = t[0]
  41. x = numpy.sin(2 * numpy.pi * t * frequency)
  42. return x
  43. def comb(n):
  44. x = 0
  45. for i in xrange(n):
  46. x += sine(i + 1)
  47. return x
  48. def tri(n, f=1):
  49. x = 0
  50. for i in xrange(n):
  51. x += sine((2 * i + 1) * f) / (2 * i + 1) ** 2.0
  52. return x
  53. def tri_stack_bright(n):
  54. x = 0
  55. for i in xrange(n):
  56. x += tri(15 + 5 * n, i + n / 3)
  57. return x
  58. def tri_stack(n):
  59. x = 0
  60. for i in xrange(n):
  61. x += tri(5 + 7 * n, i + 1) / ((i + 1) ** 0.5)
  62. return x
  63. def saw(n, f=1):
  64. x = 0
  65. for i in xrange(n):
  66. x += sine((i + 1) * f) / (i + 1)
  67. return x
  68. def saw_stack(n):
  69. x = 0
  70. for i in xrange(n):
  71. x += saw(1 + 6 * i, i + 1) / ((i + 1) ** 0.5)
  72. return x
  73. def square(n):
  74. x = 0
  75. for i in xrange(n):
  76. x += sine(2 * i + 1) / (2 * i + 1)
  77. return x
  78. def quadra(n):
  79. x = 0
  80. for harmonic, amplitude in zip(xrange(4), [1, 0.5, 1, 0.5]):
  81. x += sine(2 * n + 2 * harmonic + 1) * amplitude
  82. return x
  83. def drawbars(bars):
  84. pipes = [1.0, 3.0, 2.0, 4.0, 6.0, 8.0, 10.0, 12.0, 16.0]
  85. x = 0
  86. for intensity, frequency in zip(bars, pipes):
  87. x += int(intensity) / 8.0 * sine(frequency)
  88. return x
  89. def pulse(duty):
  90. t = numpy.arange(0, WAVETABLE_SIZE) / float(WAVETABLE_SIZE - 1)
  91. t[-1] = t[0]
  92. t[t < duty] = -1.0
  93. t[t >= duty] = 1.0
  94. return -t
  95. def burst(duty):
  96. t = numpy.arange(0, WAVETABLE_SIZE) / float(WAVETABLE_SIZE - 1)
  97. t[-1] = t[0]
  98. d = duty ** 0.5
  99. t[t < d] = -1.0
  100. t[t >= d] = 0.0
  101. return -t * sine(1.0 / duty)
  102. def hybrid(duty):
  103. cycle = (numpy.arange(0, WAVETABLE_SIZE) + int((duty - 0.5) * WAVETABLE_SIZE)) % WAVETABLE_SIZE
  104. x = pulse(duty)
  105. x += saw(80)[cycle]
  106. x -= (x.mean())
  107. return x
  108. def trisaw(harmonic):
  109. return tri(80) + saw(80, harmonic) * (1 if harmonic != 1 else 0) * 0.5
  110. def square_formant(ratio):
  111. t = numpy.arange(0, WAVETABLE_SIZE) / float(WAVETABLE_SIZE - 1)
  112. phase = t * (ratio ** 0.5) * 0.5
  113. phase[phase >= 1.0] = 1.0
  114. amplitude = numpy.cos(phase * numpy.pi) + 1
  115. formant = (sine(ratio * 0.75) + 1.0) * amplitude * 0.5
  116. formant -= (formant.max() + formant.min()) / 2.0
  117. return formant
  118. def saw_formant(ratio):
  119. t = numpy.arange(0, WAVETABLE_SIZE) / float(WAVETABLE_SIZE - 1)
  120. amplitude = 1.0 - t
  121. formant = (sine(ratio) + 1.0) * amplitude * 0.5
  122. formant -= (formant.max() + formant.min()) / 2.0
  123. return formant
  124. def bandpass_formant(ratio):
  125. t = numpy.arange(0, WAVETABLE_SIZE) / float(WAVETABLE_SIZE - 1)
  126. amplitude = 1.0 - t
  127. formant = sine(ratio * 1.5) * amplitude * 0.5
  128. return formant
  129. def sine_power(power):
  130. x = sine(1.0)
  131. if power >= 6:
  132. x = sine(2.0) * 2.0
  133. x += saw(16)
  134. power = 2.0 ** (1.2 * (power - 0.5))
  135. return numpy.sign(x) * (numpy.abs(x) ** power)
  136. def formant_f(index):
  137. formant_1 = 3.9 * (index + 1) / 8.0
  138. formant_2 = (1.0 - numpy.cos(formant_1 * numpy.pi * 0.8))
  139. t = numpy.arange(0, WAVETABLE_SIZE) / float(WAVETABLE_SIZE - 1)
  140. amplitude_1 = (1.0 - t) ** 0.2 * numpy.exp(-4.0 * t)
  141. amplitude_2 = (1.0 - t) ** 0.2 * numpy.exp(-2.0 * t)
  142. formant_3 = sine(1 + 2.8 * (formant_2 + formant_1)) * amplitude_2 * 1.7
  143. formant_1 = sine(1 + 3 * formant_1) * amplitude_1
  144. formant_2 = sine(1 + 4 * formant_2) * amplitude_2 * 1.5
  145. f = formant_1 + formant_2 + formant_3
  146. return f - (f.max() + f.min()) / 2.0
  147. def distort(x):
  148. return numpy.arctan(x * 6.0) / numpy.pi
  149. def digi_formant_f(index):
  150. formant_1 = 3.8 * (index + 1) / 8.0
  151. formant_2 = (1.0 - numpy.cos(formant_1 * numpy.pi * 0.4))
  152. t = numpy.arange(0, WAVETABLE_SIZE) / float(WAVETABLE_SIZE - 1)
  153. amplitude_1 = (1.0 - t) ** 0.2 * numpy.exp(-4.0 * t)
  154. amplitude_2 = (1.0 - t) ** 0.2 * numpy.exp(-2.0 * t)
  155. formant_3 = distort(sine(1 + 2.9 * (formant_2 + formant_1))) * amplitude_2 * 0.7
  156. formant_1 = distort(sine(1 + 3.2 * formant_1)) * amplitude_1
  157. formant_2 = distort(sine(1 + 4.1 * formant_2)) * amplitude_2 * 0.7
  158. f = formant_1 + formant_2 + formant_3
  159. return f - (f.max() + f.min()) / 2.0
  160. def make_bank(waveforms):
  161. bank = []
  162. for w in waveforms:
  163. bank += list(scale(w))
  164. return bank
  165. def make_family(fn, arguments):
  166. return map(fn, arguments)
  167. # Bank 1: mild and additive.
  168. bank_1 = []
  169. bank_1 += make_family(sine, [1, 2, 3, 4, 5, 6, 7, 8])
  170. bank_1 += make_family(sine, [8, 10, 12, 14, 16, 18, 20, 22])
  171. bank_1 += make_family(quadra, [1, 2, 3, 4, 5, 6, 7, 8])
  172. bank_1 += make_family(comb, [2, 5, 9, 14, 20, 27, 35, 44])
  173. bank_1 += make_family(tri_stack_bright, [2, 4, 6, 8, 10, 12, 14, 16])
  174. bank_1 += make_family(tri_stack, [2, 3, 4, 5, 6, 7, 8, 9])
  175. bank_1 += make_family(drawbars, [
  176. '800000888', '888000888', '867000006', '586040000',
  177. '850005000', '888643200', '327645222', '006050321'])
  178. bank_1 += make_family(drawbars, [
  179. '680008880', '888876788', '848600046', '688600000',
  180. '666806000', '468844054', '004675300', '002478500',])
  181. # Bank 2: formantish.
  182. bank_2 = []
  183. bank_2 += make_family(trisaw, [1, 1.5, 2, 3, 4, 4.5, 5, 8])
  184. bank_2 += make_family(pulse, [0.5, 0.4, 1/3.0, 0.25, 0.2, 0.125, 1/16.0, 1/32.0])
  185. bank_2 += make_family(burst, [0.5, 0.4, 1/3.0, 0.25, 0.2, 0.125, 1/16.0, 1/32.0])
  186. bank_2 += make_family(square_formant, [2.0, 3.0, 4.0, 6.0, 8.0, 12.0, 16.0, 24.0])
  187. bank_2 += make_family(bandpass_formant, [2.0, 3.0, 4.0, 6.0, 8.0, 12.0, 16.0, 32.0])
  188. bank_2 += make_family(formant_f, xrange(8))
  189. bank_2 += make_family(digi_formant_f, xrange(8))
  190. bank_2 += make_family(sine_power, xrange(8))
  191. # Bank 3: Shruthi.
  192. bank_3 = list(numpy.fromstring(
  193. file('tides/resources/waves.bin', 'rb').read(), numpy.int16))
  194. wavetables.append(('waves', make_bank(bank_1) + make_bank(bank_2) + bank_3[:50*257]))
  195. """----------------------------------------------------------------------------
  196. Post waveshaper
  197. ----------------------------------------------------------------------------"""
  198. WAVESHAPER_SIZE = 1024
  199. waveshapers = []
  200. x = numpy.arange(0, WAVESHAPER_SIZE + 1) / (WAVESHAPER_SIZE / 2.0) - 1.0
  201. x[-1] = x[-2]
  202. sine = numpy.sin(2 * numpy.pi * x)
  203. window = numpy.exp(-x * x * 1.5) ** 2
  204. bipolar_fold = sine * window + numpy.arctan(2 * x) * (1 - window)
  205. bipolar_fold /= numpy.abs(bipolar_fold).max()
  206. waveshapers.append(('smooth_bipolar_foldIN_RAM', numpy.round(32767 * bipolar_fold)))