diff options
Diffstat (limited to 'become_yukarin/dataset/utility.py')
| -rw-r--r-- | become_yukarin/dataset/utility.py | 46 |
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) |
