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.

149 lines
4.9KB

  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 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. # Lookup table definitions.
  30. import numpy
  31. lookup_tables = []
  32. lookup_tables_32 = []
  33. """----------------------------------------------------------------------------
  34. Easing
  35. ----------------------------------------------------------------------------"""
  36. def BounceEaseIn(t, b, c, d):
  37. return c - BounceEaseOut(d - t, 0, c, d) + b
  38. def BounceEaseOut(t, b, c, d):
  39. t /= d
  40. if t < 1 / 2.75:
  41. return c * (7.5625 * t * t) + b
  42. elif t < 2 / 2.75:
  43. t -= 1.5/2.75
  44. return c * (7.5625 * t * t + .75) + b
  45. elif t < 2.5 / 2.75:
  46. t -= 2.25 / 2.75
  47. return c * (7.5625 * t * t + .9375) + b;
  48. else:
  49. t -= 2.625 / 2.75
  50. return c * (7.5625 * t * t + .984375) + b;
  51. def BounceEaseInOut(t, b, c, d):
  52. if (t < d / 2):
  53. return BounceEaseIn(t * 2, 0, c, d) * 0.5 + b
  54. else:
  55. return BounceEaseOut(t * 2 - d, 0, c, d) * 0.5 + c * 0.5 + b
  56. x = numpy.arange(0, 1025.0) / 1024.0
  57. steps = numpy.sign(x - 0.5) * 32767.5 + 32767.5
  58. linear = x * 65535.0
  59. quartic_in = (x ** 4) * 65535.0
  60. quartic_out = (1 - (1 - x) ** 4) * 65535.0
  61. in_out_sine = (1.0 - numpy.cos(x * numpy.pi)) / 2.0 * 65535.0
  62. in_out_bounce = x + 0
  63. for i in xrange(len(x)):
  64. in_out_bounce[i] = BounceEaseOut(x[i], 0, 65535.0, 1.0)
  65. # lookup_tables.append(('easing_steps', steps))
  66. # lookup_tables.append(('easing_linear', linear))
  67. lookup_tables.append(('easing_in_quartic', quartic_in))
  68. lookup_tables.append(('easing_out_quartic',quartic_out))
  69. lookup_tables.append(('easing_in_out_sine', in_out_sine))
  70. lookup_tables.append(('easing_in_out_bounce', in_out_bounce))
  71. """----------------------------------------------------------------------------
  72. 2164 variable-skew normalization
  73. ----------------------------------------------------------------------------"""
  74. x = numpy.arange(0, 256.0) / 255.0
  75. lookup_tables.append(('response_balance', numpy.round(32767 * (x ** 1.5))))
  76. gain = numpy.linspace(1.0 / 4096, 1.0, 1025)
  77. voltage = 65535 / 2.5 * -2.0 / 3.0 * numpy.log10(gain)
  78. vca_linear = numpy.maximum(numpy.minimum(numpy.round(voltage), 65535), 0)
  79. lookup_tables.append(('vca_linear', vca_linear))
  80. """----------------------------------------------------------------------------
  81. Simple expo table for LED brightness adjustment
  82. ----------------------------------------------------------------------------"""
  83. x = numpy.arange(0, 256.0) / 255.0
  84. expo = numpy.exp(-8.0 * (1.0 - x))
  85. lookup_tables.append(('exponential', 65535 * expo))
  86. """----------------------------------------------------------------------------
  87. Phase increment lookup table for LFO mode
  88. ----------------------------------------------------------------------------"""
  89. frequency = 110 * 2 ** (numpy.arange(0, 159.0) / 158.0 - 13)
  90. phase_increment = frequency / 24000 * (1 << 32)
  91. lookup_tables_32 = [('increments', numpy.round(phase_increment).astype(int))]
  92. """----------------------------------------------------------------------------
  93. Euclidean patterns
  94. ----------------------------------------------------------------------------"""
  95. def Flatten(l):
  96. if hasattr(l, 'pop'):
  97. for item in l:
  98. for j in Flatten(item):
  99. yield j
  100. else:
  101. yield l
  102. def EuclideanPattern(k, n):
  103. pattern = [[1]] * k + [[0]] * (n - k)
  104. while k:
  105. cut = min(k, len(pattern) - k)
  106. k, pattern = cut, [pattern[i] + pattern[k + i] for i in xrange(cut)] + \
  107. pattern[cut:k] + pattern[k + cut:]
  108. return pattern
  109. table = []
  110. for num_steps in xrange(1, 33):
  111. for num_notes in xrange(32):
  112. num_notes = min(num_notes, num_steps)
  113. bitmask = 0
  114. for i, bit in enumerate(Flatten(EuclideanPattern(num_notes, num_steps))):
  115. if bit:
  116. bitmask |= (1 << i)
  117. table.append(bitmask)
  118. lookup_tables_32 += [('euclidean', table)]