File size: 1,984 Bytes
f1f433f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import base64
import io
from typing import List, Tuple

import numpy as np
import soundfile
from scipy.signal import resample


class ConnectBase64WavesException(Exception):
    def __init__(self, message: str):
        self.message = message


def decode_base64_waves(waves: List[str]) -> List[Tuple[np.ndarray, int]]:
    """
    base64エンコードされた複数のwavデータをデコードする
    Parameters
    ----------
    waves: list[str]
        base64エンコードされたwavデータのリスト
    Returns
    -------
    waves_nparray_sr: List[Tuple[np.ndarray, int]]
        (NumPy配列の音声波形データ, サンプリングレート) 形式のタプルのリスト
    """
    if len(waves) == 0:
        raise ConnectBase64WavesException("wavファイルが含まれていません")

    waves_nparray_sr = []
    for wave in waves:
        try:
            wav_bin = base64.standard_b64decode(wave)
        except ValueError:
            raise ConnectBase64WavesException("base64デコードに失敗しました")
        try:
            _data = soundfile.read(io.BytesIO(wav_bin))
        except Exception:
            raise ConnectBase64WavesException("wavファイルを読み込めませんでした")
        waves_nparray_sr.append(_data)

    return waves_nparray_sr


def connect_base64_waves(waves: List[str]) -> Tuple[np.ndarray, int]:
    waves_nparray_sr = decode_base64_waves(waves)

    max_sampling_rate = max([sr for _, sr in waves_nparray_sr])
    max_channels = max([x.ndim for x, _ in waves_nparray_sr])
    assert 0 < max_channels <= 2

    waves_nparray_list = []
    for nparray, sr in waves_nparray_sr:
        if sr != max_sampling_rate:
            nparray = resample(nparray, max_sampling_rate * len(nparray) // sr)
        if nparray.ndim < max_channels:
            nparray = np.array([nparray, nparray]).T
        waves_nparray_list.append(nparray)

    return np.concatenate(waves_nparray_list), max_sampling_rate