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.

303 lines
8.6KB

  1. #!/usr/bin/python2.5
  2. #
  3. # Copyright 2016 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. import pylab
  32. WAVETABLE_SIZE = 256
  33. BRAIDS_WAVES = numpy.fromstring(
  34. file('plaits/resources/waves.bin', 'rb').read(), numpy.uint8)
  35. wavetables = []
  36. def sine(frequency):
  37. t = numpy.arange(0, WAVETABLE_SIZE) / float(WAVETABLE_SIZE)
  38. if frequency >= WAVETABLE_SIZE / 2:
  39. return t * 0
  40. x = numpy.sin(2 * numpy.pi * t * frequency)
  41. return x
  42. def comb(n):
  43. x = 0
  44. for i in xrange(n):
  45. x += sine(i + 1)
  46. return x
  47. def pair(n):
  48. x = 0
  49. for i in xrange(n):
  50. x += sine(i + 1) * (i + 0.5) / (n - 1.0)
  51. x += sine((i + 1) * 4) * (i + 0.5) / (n - 1.0) * 0.5
  52. return x
  53. def tri(n, f=1):
  54. x = 0
  55. for i in xrange(n):
  56. x += sine((2 * i + 1) * f) / (2 * i + 1) ** 2.0
  57. return x
  58. def tri_stack(n):
  59. x = 0
  60. for i in xrange(n):
  61. x += tri(15 + 5 * n, i + n / 3)
  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)
  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)
  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.25) * 0.5
  110. def sawtri(harmonic):
  111. return saw(80) * 0.5 + tri(80, harmonic) * (1 if harmonic != 1 else 0.25)
  112. def square_formant(ratio):
  113. t = numpy.arange(0, WAVETABLE_SIZE) / float(WAVETABLE_SIZE)
  114. phase = t * (ratio ** 0.5) * 0.5
  115. phase[phase >= 1.0] = 1.0
  116. amplitude = numpy.cos(phase * numpy.pi) + 1
  117. formant = (sine(ratio * 0.75) + 1.0) * amplitude * 0.5
  118. formant -= (formant.max() + formant.min()) / 2.0
  119. return formant
  120. def saw_formant(ratio):
  121. t = numpy.arange(0, WAVETABLE_SIZE) / float(WAVETABLE_SIZE)
  122. amplitude = 1.0 - t
  123. formant = (sine(ratio) + 1.0) * amplitude * 0.5
  124. formant -= (formant.max() + formant.min()) / 2.0
  125. return formant
  126. def bandpass_formant(ratio):
  127. t = numpy.arange(0, WAVETABLE_SIZE) / float(WAVETABLE_SIZE)
  128. amplitude = 1.0 - t
  129. formant = sine(ratio * 1.5) * amplitude * 0.5
  130. return formant
  131. def sine_power(power):
  132. x = sine(1.0)
  133. x += saw(16)
  134. power = 2.0 ** power
  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 = formant_1 * (1.0 - numpy.cos(formant_1 * numpy.pi * 0.8))
  139. t = numpy.arange(0, WAVETABLE_SIZE) / float(WAVETABLE_SIZE)
  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 * 8.0) / numpy.pi
  149. def digi_formant_f(index):
  150. formant_1 = 3.9 * (index + 1) / 8.0
  151. formant_2 = formant_1 * (1.0 - numpy.cos(formant_1 * numpy.pi * 0.8))
  152. t = numpy.arange(0, WAVETABLE_SIZE) / float(WAVETABLE_SIZE)
  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_family(fn, arguments):
  161. return map(fn, arguments)
  162. def make_braids_family(indices, fix=False):
  163. family = []
  164. for i in indices:
  165. start = i * 129
  166. end = start + 128
  167. s = BRAIDS_WAVES[start:end] - 128.0
  168. if fix:
  169. sf = numpy.fft.rfft(s)
  170. else:
  171. si = numpy.zeros((WAVETABLE_SIZE, ))
  172. si = s
  173. # si[::2] = s
  174. # si[1::2] = s # Ewwwwww
  175. sf = numpy.fft.rfft(si)
  176. sf = numpy.abs(sf) * numpy.exp(-1j * numpy.pi / 2.0)
  177. interpolated = numpy.fft.irfft(sf, WAVETABLE_SIZE)
  178. family += [interpolated]
  179. return family
  180. # Bank 1: mild and additive.
  181. bank_1 = []
  182. bank_1 += make_family(sine, [1, 2, 3, 4, 5, 6, 7, 8])
  183. bank_1 += make_family(sine, [2, 3, 4, 6, 8, 12, 16, 24])
  184. bank_1 += make_family(quadra, [2, 3, 4, 6, 8, 12, 16, 24])
  185. bank_1 += make_family(comb, [2, 3, 5, 8, 13, 21, 34, 55])
  186. bank_1 += make_family(pair, [2, 4, 6, 8, 10, 12, 14, 16])
  187. bank_1 += make_family(tri_stack, [2, 4, 6, 8, 10, 12, 14, 16])
  188. bank_1 += make_family(drawbars, [
  189. '688600000',
  190. '686040000',
  191. '666806000',
  192. '655550600',
  193. '665560060',
  194. '688500888',
  195. '660000888',
  196. '060000046'])
  197. bank_1 += make_family(drawbars, [
  198. '867000006',
  199. '888876788',
  200. '668744354',
  201. '448644054',
  202. '327645222',
  203. '204675300',
  204. '002478500',
  205. '002050321'])
  206. # Bank 2: formantish.
  207. bank_2 = []
  208. bank_2 += make_family(trisaw, [1, 1.5, 2, 3, 4, 4.5, 5, 8])
  209. bank_2 += make_family(sawtri, [1, 1.5, 2, 3, 4, 4.5, 5, 8])
  210. bank_2 += make_family(burst, [0.5, 0.4, 1/3.0, 0.25, 0.2, 0.125, 1/16.0, 1/32.0])
  211. bank_2 += make_family(bandpass_formant, [2.0, 3.0, 4.0, 6.0, 8.0, 9.0, 10.0, 16.0])
  212. bank_2 += make_family(formant_f, xrange(8))
  213. bank_2 += make_family(digi_formant_f, xrange(8))
  214. bank_2 += make_family(pulse, [0.5, 0.4, 1/3.0, 0.25, 0.2, 0.125, 1/16.0, 1/32.0])
  215. bank_2 += make_family(sine_power, xrange(8))
  216. # Bank 3: shruthi/ambika/braids.
  217. bank_3 = []
  218. bank_3 += make_braids_family([0, 2, 4, 6, 8, 10, 12, 14]) # Male
  219. bank_3 += make_braids_family([32, 34, 36, 38, 40, 42, 44, 46]) # Choir
  220. # bank_3 += make_braids_family([64, 66, 68, 70, 72, 74, 76, 62]) # Tampura
  221. bank_3 += make_braids_family([176, 189, 191, 193, 195, 197, 199, 201]) # Digi
  222. bank_3 += make_braids_family([203, 204, 205, 206, 207, 208, 209, 211]) # Drone
  223. bank_3 += make_braids_family([220, 222, 224, 226, 228, 230, 232, 234]) # Metal
  224. bank_3 += make_braids_family([236, 238, 240, 242, 244, 246, 248, 250]) # Fant
  225. bank_3 += make_braids_family([172, 173, 174, 175, 176, 177, 178, 179], False)
  226. bank_3 += make_braids_family([180, 181, 182, 183, 184, 185, 186, 187], False)
  227. all_waves = bank_1 + bank_2 + bank_3
  228. # New wavetable code uses integrated wavetables
  229. # Reference:
  230. # "Higher-order integrated Wavetable Synthesis", Franck & Valimaki, DAFX-12.
  231. #
  232. # Here we use K = 1 (first order), N = 1 (linear interpolation).
  233. data = []
  234. for wave in all_waves:
  235. n = len(wave)
  236. x = numpy.array(list(wave) * 2 + wave[0] + wave[1] + wave[2] + wave[3])
  237. x -= x.mean()
  238. x /= numpy.abs(x).max()
  239. x = numpy.cumsum(x)
  240. x -= x.mean()
  241. x = list(numpy.round(x * (4 * 32768.0 / WAVETABLE_SIZE)).astype(int))
  242. data += list(x[-n-4:])
  243. wavetables.append(('integrated_waves', data))