|
- #!/usr/bin/python2.5
- #
- # Copyright 2014 Olivier Gillet.
- #
- # Author: Olivier Gillet (ol.gillet@gmail.com)
- #
- # Permission is hereby granted, free of charge, to any person obtaining a copy
- # of this software and associated documentation files (the "Software"), to deal
- # in the Software without restriction, including without limitation the rights
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- # copies of the Software, and to permit persons to whom the Software is
- # furnished to do so, subject to the following conditions:
- #
- # The above copyright notice and this permission notice shall be included in
- # all copies or substantial portions of the Software.
- #
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- # THE SOFTWARE.
- #
- # See http://creativecommons.org/licenses/MIT/ for more information.
- #
- # -----------------------------------------------------------------------------
- #
- # Lookup table definitions.
-
- import scipy.signal
- import numpy
- import pylab
-
- lookup_tables = []
- int16_lookup_tables = []
-
- """----------------------------------------------------------------------------
- Cosine table.
- ----------------------------------------------------------------------------"""
-
- size = 1024
- t = numpy.arange(0, size + size / 4 + 1) / float(size) * numpy.pi * 2
- lookup_tables.append(('sin', numpy.sin(t)))
-
- """----------------------------------------------------------------------------
- Raised cosine.
- ----------------------------------------------------------------------------"""
-
- size = 256
- t = numpy.arange(0, size + 1) / float(size)
- lookup_tables.append(('raised_cos', 1.0 - (numpy.cos(t * numpy.pi) + 1) / 2))
-
- """----------------------------------------------------------------------------
- XFade table
- ----------------------------------------------------------------------------"""
-
- size = 17
- t = numpy.arange(0, size) / float(size-1)
- t = 1.04 * t - 0.02
- t[t < 0] = 0
- t[t >= 1] = 1
- t *= numpy.pi / 2
- lookup_tables.append(('xfade_in', numpy.sin(t) * (2 ** -0.5)))
- lookup_tables.append(('xfade_out', numpy.cos(t) * (2 ** -0.5)))
-
- """----------------------------------------------------------------------------
- Grain window.
- ----------------------------------------------------------------------------"""
-
- size = 4096
- t = numpy.arange(0, size + 1) / float(size)
- lookup_tables.append(('window', 1.0 - (numpy.cos(t * numpy.pi) + 1) / 2))
-
-
- """----------------------------------------------------------------------------
- Sine window.
- ----------------------------------------------------------------------------"""
-
- def sum_window(window, steps):
- n = window.shape[0]
- start = 0
- stride = n / steps
- s = 0
- for i in xrange(steps):
- s = s + window[start:start+stride] ** 2
- start += stride
- return s
-
-
- window_size = 4096
- t = numpy.arange(0.0, window_size) / window_size
-
- # Perfect reconstruction for overlap of 2
- sine = numpy.sin(numpy.pi * t)
-
- # Perfect reconstruction for overlap of 4
- raised = (0.5 * numpy.cos(numpy.pi * t * 2) + 0.5) * numpy.sqrt(4.0 / 3.0)
-
- # Needs tweaks to provide good reconstruction
- power = (1.0 - (2 * t - 1.0) ** 2.0) ** 1.25
- compensation = sum_window(power, 2) ** 0.5
- compensation = numpy.array(list(compensation) * 2)
- power /= compensation
-
- lookup_tables.append(('sine_window_4096', power))
-
-
-
- """----------------------------------------------------------------------------
- Linear to dB, for display
- ----------------------------------------------------------------------------"""
-
- db = numpy.arange(0, 257)
- db[0] = 1
- db[db > 255] = 255
- db = numpy.log2(db / 16.0) * 32768 / 4
- int16_lookup_tables += [('db', db)]
-
-
-
- """----------------------------------------------------------------------------
- LPG cutoff
- ----------------------------------------------------------------------------"""
-
- TABLE_SIZE = 256
-
- cutoff = numpy.arange(0.0, TABLE_SIZE + 1) / TABLE_SIZE
- lookup_tables.append(('cutoff', 0.49 * 2 ** (-6 * (1 - cutoff))))
-
-
-
- """----------------------------------------------------------------------------
- Grain size table
- ----------------------------------------------------------------------------"""
-
- size = numpy.arange(0.0, TABLE_SIZE + 1) / TABLE_SIZE * 5
- lookup_tables.append(('grain_size', numpy.floor(512 * (2 ** size))))
-
-
-
- """----------------------------------------------------------------------------
- Quantizer for pitch.
- ----------------------------------------------------------------------------"""
-
- PITCH_TABLE_SIZE = 1025
- pitch = numpy.zeros((PITCH_TABLE_SIZE, ))
- notches = [-24, -12, -7, -4, -3, -1, -0.1, 0,
- 0.1, 1, 3, 4, 7, 12, 12, 24]
- n = len(notches) - 1
- for i in xrange(n):
- start_index = int(float(i) / n * PITCH_TABLE_SIZE)
- end_index = int(float(i + 1) / n * PITCH_TABLE_SIZE)
- length = end_index - start_index
- x = numpy.arange(0.0, length) / (length - 1)
- raised_cosine = 0.5 - 0.5 * numpy.cos(x * numpy.pi)
- xfade = 0.8 * raised_cosine + 0.2 * x
- pitch[start_index:end_index] = notches[i] + (notches[i + 1] - notches[i]) * xfade
-
- lookup_tables.append(('quantized_pitch', pitch))
|