summaryrefslogtreecommitdiff
path: root/become_yukarin/dataset/utility.py
diff options
context:
space:
mode:
Diffstat (limited to 'become_yukarin/dataset/utility.py')
-rw-r--r--become_yukarin/dataset/utility.py46
1 files changed, 46 insertions, 0 deletions
diff --git a/become_yukarin/dataset/utility.py b/become_yukarin/dataset/utility.py
new file mode 100644
index 0000000..b2f5480
--- /dev/null
+++ b/become_yukarin/dataset/utility.py
@@ -0,0 +1,46 @@
+import fastdtw
+import nnmnkwii.metrics
+import numpy
+import scipy.interpolate
+
+
+class DTWAligner(object):
+ """
+ from https://github.com/r9y9/nnmnkwii/blob/4cade86b5c35b4e35615a2a8162ddc638018af0e/nnmnkwii/preprocessing/alignment.py#L14
+ """
+
+ def __init__(self, x, y, dist=lambda x, y: numpy.linalg.norm(x - y), radius=1):
+ assert x.ndim == 2 and y.ndim == 2
+
+ _, path = fastdtw.fastdtw(x, y, radius=radius, dist=dist)
+ self.normed_path_x = numpy.array(list(map(lambda l: l[0], path))) / len(x)
+ self.normed_path_y = numpy.array(list(map(lambda l: l[1], path))) / len(y)
+
+ def align_x(self, x):
+ path = self._interp_path(self.normed_path_x, len(x))
+ return x[path]
+
+ def align_y(self, y):
+ path = self._interp_path(self.normed_path_y, len(y))
+ return y[path]
+
+ def align(self, x, y):
+ return self.align_x(x), self.align_y(y)
+
+ @staticmethod
+ def align_and_transform(x, y, *args, **kwargs):
+ aligner = DTWAligner(*args, x=x, y=y, **kwargs)
+ return aligner.align(x, y)
+
+ @staticmethod
+ def _interp_path(normed_path: numpy.ndarray, target_length: int):
+ base = numpy.linspace(0, 1, len(normed_path))
+ target = numpy.linspace(0, 1, target_length)
+ path = scipy.interpolate.interp1d(base, normed_path)(target)
+ path = numpy.floor(path * target_length).astype(numpy.int)
+ return path
+
+
+class MFCCAligner(DTWAligner):
+ def __init__(self, *args, **kwargs):
+ super().__init__(*args, dist=nnmnkwii.metrics.melcd, **kwargs)