Spaces:
Sleeping
Sleeping
| import os | |
| import numpy as np | |
| import requests | |
| import yaml | |
| import pyloudnorm as pyln | |
| from scipy.io.wavfile import write | |
| import torchaudio | |
| from retrying import retry | |
| from utils import get_service_port, get_service_url | |
| os.environ['OPENBLAS_NUM_THREADS'] = '1' | |
| SAMPLE_RATE = 32000 | |
| with open('config.yaml', 'r') as file: | |
| config = yaml.safe_load(file) | |
| service_port = get_service_port() | |
| localhost_addr = get_service_url() | |
| enable_sr = config['Speech-Restoration']['Enable'] | |
| def LOUDNESS_NORM(audio, sr=32000, volumn=-25): | |
| # peak normalize audio to -1 dB | |
| peak_normalized_audio = pyln.normalize.peak(audio, -10.0) | |
| # measure the loudness first | |
| meter = pyln.Meter(sr) # create BS.1770 meter | |
| loudness = meter.integrated_loudness(peak_normalized_audio) | |
| # loudness normalize audio to -12 dB LUFS | |
| normalized_audio = pyln.normalize.loudness(peak_normalized_audio, loudness, volumn) | |
| return normalized_audio | |
| def WRITE_AUDIO(wav, name=None, sr=SAMPLE_RATE): | |
| """ | |
| function: write audio numpy to .wav file | |
| @params: | |
| wav: np.array [samples] | |
| """ | |
| if name is None: | |
| name = 'output.wav' | |
| if len(wav.shape) > 1: | |
| wav = wav[0] | |
| # declipping | |
| max_value = np.max(np.abs(wav)) | |
| if max_value > 1: | |
| wav *= 0.9 / max_value | |
| # write audio | |
| write(name, sr, np.round(wav*32767).astype(np.int16)) | |
| def READ_AUDIO_NUMPY(wav, sr=SAMPLE_RATE): | |
| """ | |
| function: read audio numpy | |
| return: np.array [samples] | |
| """ | |
| waveform, sample_rate = torchaudio.load(wav) | |
| if sample_rate != sr: | |
| waveform = torchaudio.functional.resample(waveform, orig_freq=sample_rate, new_freq=sr) | |
| wav_numpy = waveform[0].numpy() | |
| return wav_numpy | |
| def MIX(wavs=[['1.wav', 0.], ['2.wav', 10.]], out_wav='out.wav', sr=SAMPLE_RATE): | |
| """ | |
| wavs:[[wav_name, absolute_offset], ...] | |
| """ | |
| max_length = max([int(wav[1]*sr + len(READ_AUDIO_NUMPY(wav[0]))) for wav in wavs]) | |
| template_wav = np.zeros(max_length) | |
| for wav in wavs: | |
| cur_name, cur_offset = wav | |
| cur_wav = READ_AUDIO_NUMPY(cur_name) | |
| cur_len = len(cur_wav) | |
| cur_offset = int(cur_offset * sr) | |
| # mix | |
| template_wav[cur_offset:cur_offset+cur_len] += cur_wav | |
| WRITE_AUDIO(template_wav, name=out_wav) | |
| def CAT(wavs, out_wav='out.wav'): | |
| """ | |
| wavs: List of wav file ['1.wav', '2.wav', ...] | |
| """ | |
| wav_num = len(wavs) | |
| segment0 = READ_AUDIO_NUMPY(wavs[0]) | |
| cat_wav = segment0 | |
| if wav_num > 1: | |
| for i in range(1, wav_num): | |
| next_wav = READ_AUDIO_NUMPY(wavs[i]) | |
| cat_wav = np.concatenate((cat_wav, next_wav), axis=-1) | |
| WRITE_AUDIO(cat_wav, name=out_wav) | |
| def COMPUTE_LEN(wav): | |
| wav= READ_AUDIO_NUMPY(wav) | |
| return len(wav) / 32000 | |
| def TTM(text, length=10, volume=-28, out_wav='out.wav'): | |
| url = f'http://{localhost_addr}:{service_port}/generate_music' | |
| data = { | |
| 'text': f'{text}', | |
| 'length': f'{length}', | |
| 'volume': f'{volume}', | |
| 'output_wav': f'{out_wav}', | |
| } | |
| response = requests.post(url, json=data) | |
| if response.status_code == 200: | |
| print('Success:', response.json()['message']) | |
| else: | |
| print('Error:', response.json()['API error']) | |
| raise RuntimeError(response.json()['API error']) | |
| def TTA(text, length=5, volume=-35, out_wav='out.wav'): | |
| url = f'http://{localhost_addr}:{service_port}/generate_audio' | |
| data = { | |
| 'text': f'{text}', | |
| 'length': f'{length}', | |
| 'volume': f'{volume}', | |
| 'output_wav': f'{out_wav}', | |
| } | |
| response = requests.post(url, json=data) | |
| if response.status_code == 200: | |
| print('Success:', response.json()['message']) | |
| else: | |
| print('Error:', response.json()['API error']) | |
| raise RuntimeError(response.json()['API error']) | |
| def TTS(text, volume=-20, out_wav='out.wav', enhanced=enable_sr, speaker_id='', speaker_npz=''): | |
| url = f'http://{localhost_addr}:{service_port}/generate_speech' | |
| data = { | |
| 'text': f'{text}', | |
| 'speaker_id': f'{speaker_id}', | |
| 'speaker_npz': f'{speaker_npz}', | |
| 'volume': f'{volume}', | |
| 'output_wav': f'{out_wav}', | |
| } | |
| response = requests.post(url, json=data) | |
| if response.status_code == 200: | |
| print('Success:', response.json()['message']) | |
| else: | |
| print('Error:', response.json()['API error']) | |
| raise RuntimeError(response.json()['API error']) | |
| if enhanced: | |
| SR(processfile=out_wav) | |
| def SR(processfile): | |
| url = f'http://{localhost_addr}:{service_port}/fix_audio' | |
| data = {'processfile': f'{processfile}'} | |
| response = requests.post(url, json=data) | |
| if response.status_code == 200: | |
| print('Success:', response.json()['message']) | |
| else: | |
| print('Error:', response.json()['API error']) | |
| raise RuntimeError(response.json()['API error']) | |
| def VP(wav_path, out_dir): | |
| url = f'http://{localhost_addr}:{service_port}/parse_voice' | |
| data = { | |
| 'wav_path': f'{wav_path}', | |
| 'out_dir':f'{out_dir}' | |
| } | |
| response = requests.post(url, json=data) | |
| if response.status_code == 200: | |
| print('Success:', response.json()['message']) | |
| else: | |
| print('Error:', response.json()['API error']) | |
| raise RuntimeError(response.json()['API error']) | |