MCPcopy Create free account
hub / github.com/MoonInTheRiver/DiffSinger / trim_long_silences

Function trim_long_silences

data_gen/tts/data_gen_utils.py:27–90  ·  view source on GitHub ↗

Ensures that segments without voice in the waveform remain no longer than a threshold determined by the VAD parameters in params.py. :param wav: the raw waveform as a numpy array of floats :param vad_max_silence_length: Maximum number of consecutive silent frames a segment can have.

(path, sr=None, return_raw_wav=False, norm=True, vad_max_silence_length=12)

Source from the content-addressed store, hash-verified

25
26
27def trim_long_silences(path, sr=None, return_raw_wav=False, norm=True, vad_max_silence_length=12):
28 """
29 Ensures that segments without voice in the waveform remain no longer than a
30 threshold determined by the VAD parameters in params.py.
31 :param wav: the raw waveform as a numpy array of floats
32 :param vad_max_silence_length: Maximum number of consecutive silent frames a segment can have.
33 :return: the same waveform with silences trimmed away (length <= original wav length)
34 """
35
36 ## Voice Activation Detection
37 # Window size of the VAD. Must be either 10, 20 or 30 milliseconds.
38 # This sets the granularity of the VAD. Should not need to be changed.
39 sampling_rate = 16000
40 wav_raw, sr = librosa.core.load(path, sr=sr)
41
42 if norm:
43 meter = pyln.Meter(sr) # create BS.1770 meter
44 loudness = meter.integrated_loudness(wav_raw)
45 wav_raw = pyln.normalize.loudness(wav_raw, loudness, -20.0)
46 if np.abs(wav_raw).max() > 1.0:
47 wav_raw = wav_raw / np.abs(wav_raw).max()
48
49 wav = librosa.resample(wav_raw, sr, sampling_rate, res_type='kaiser_best')
50
51 vad_window_length = 30 # In milliseconds
52 # Number of frames to average together when performing the moving average smoothing.
53 # The larger this value, the larger the VAD variations must be to not get smoothed out.
54 vad_moving_average_width = 8
55
56 # Compute the voice detection window size
57 samples_per_window = (vad_window_length * sampling_rate) // 1000
58
59 # Trim the end of the audio to have a multiple of the window size
60 wav = wav[:len(wav) - (len(wav) % samples_per_window)]
61
62 # Convert the float waveform to 16-bit mono PCM
63 pcm_wave = struct.pack("%dh" % len(wav), *(np.round(wav * int16_max)).astype(np.int16))
64
65 # Perform voice activation detection
66 voice_flags = []
67 vad = webrtcvad.Vad(mode=3)
68 for window_start in range(0, len(wav), samples_per_window):
69 window_end = window_start + samples_per_window
70 voice_flags.append(vad.is_speech(pcm_wave[window_start * 2:window_end * 2],
71 sample_rate=sampling_rate))
72 voice_flags = np.array(voice_flags)
73
74 # Smooth the voice detection with a moving average
75 def moving_average(array, width):
76 array_padded = np.concatenate((np.zeros((width - 1) // 2), array, np.zeros(width // 2)))
77 ret = np.cumsum(array_padded, dtype=float)
78 ret[width:] = ret[width:] - ret[:-width]
79 return ret[width - 1:] / width
80
81 audio_mask = moving_average(voice_flags, vad_moving_average_width)
82 audio_mask = np.round(audio_mask).astype(np.bool)
83
84 # Dilate the voiced regions

Callers 1

process_utteranceFunction · 0.85

Calls 1

moving_averageFunction · 0.85

Tested by

no test coverage detected