Spaces:
Runtime error
Runtime error
| # Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved. | |
| # | |
| # Licensed under the Apache License, Version 2.0 (the "License"); | |
| # you may not use this file except in compliance with the License. | |
| # You may obtain a copy of the License at | |
| # | |
| # http://www.apache.org/licenses/LICENSE-2.0 | |
| # | |
| # Unless required by applicable law or agreed to in writing, software | |
| # distributed under the License is distributed on an "AS IS" BASIS, | |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| # See the License for the specific language governing permissions and | |
| # limitations under the License. | |
| # USAGE: python get_openslr_rir_data.py --data_root=<where to put data> | |
| # Data is downloaded from OpenSLR's "Room Impulse Response and Noise Database" | |
| # RIRs in multichannel files are separated into single channel files and | |
| # a json file that can be used as in input to NeMo is created | |
| import argparse | |
| import glob | |
| import json | |
| import logging | |
| import os | |
| import subprocess | |
| import urllib.request | |
| from shutil import copy, move | |
| from zipfile import ZipFile | |
| from tqdm import tqdm | |
| parser = argparse.ArgumentParser(description="OpenSLR RIR Data download and process") | |
| parser.add_argument("--data_root", required=True, default=None, type=str) | |
| args = parser.parse_args() | |
| URLS = { | |
| "SLR28": ("http://www.openslr.org/resources/28/rirs_noises.zip"), | |
| } | |
| def __retrieve_with_progress(source: str, filename: str): | |
| """ | |
| Downloads source to destination | |
| Displays progress bar | |
| Args: | |
| source: url of resource | |
| destination: local filepath | |
| Returns: | |
| """ | |
| with open(filename, "wb") as f: | |
| response = urllib.request.urlopen(source) | |
| total = response.length | |
| if total is None: | |
| f.write(response.content) | |
| else: | |
| with tqdm(total=total, unit="B", unit_scale=True, unit_divisor=1024) as pbar: | |
| for data in response: | |
| f.write(data) | |
| pbar.update(len(data)) | |
| def __maybe_download_file(destination: str, source: str): | |
| """ | |
| Downloads source to destination if it doesn't exist. | |
| If exists, skips download | |
| Args: | |
| destination: local filepath | |
| source: url of resource | |
| Returns: | |
| """ | |
| source = URLS[source] | |
| if not os.path.exists(destination): | |
| logging.info("{0} does not exist. Downloading ...".format(destination)) | |
| __retrieve_with_progress(source, filename=destination + ".tmp") | |
| os.rename(destination + ".tmp", destination) | |
| logging.info("Downloaded {0}.".format(destination)) | |
| else: | |
| logging.info("Destination {0} exists. Skipping.".format(destination)) | |
| return destination | |
| def __extract_file(filepath: str, data_dir: str): | |
| try: | |
| with ZipFile(filepath, "r") as zipObj: | |
| zipObj.extractall(data_dir) | |
| except Exception: | |
| logging.info("Not extracting. Maybe already there?") | |
| def __process_data(data_folder: str, dst_folder: str, manifest_file: str): | |
| """ | |
| Converts flac to wav and build manifests's json | |
| Args: | |
| data_folder: source with flac files | |
| dst_folder: where wav files will be stored | |
| manifest_file: where to store manifest | |
| Returns: | |
| """ | |
| if not os.path.exists(dst_folder): | |
| os.makedirs(dst_folder) | |
| real_rir_list = os.path.join(data_folder, "RIRS_NOISES", "real_rirs_isotropic_noises", "rir_list") | |
| rirfiles = [] | |
| with open(real_rir_list, "r") as rir_f: | |
| for line in rir_f: | |
| rirfiles.append(os.path.join(data_folder, line.rstrip().split(" ")[4])) | |
| real_rir_folder = os.path.join(dst_folder, "real_rirs") | |
| if not os.path.exists(real_rir_folder): | |
| os.makedirs(real_rir_folder) | |
| # split multi-channel rir files to single channel | |
| for rir_f in rirfiles: | |
| n_chans = int(subprocess.check_output("soxi -c {0}".format(rir_f), shell=True)) | |
| if n_chans == 1: | |
| copy(rir_f, real_rir_folder) | |
| else: | |
| for chan in range(1, n_chans + 1): | |
| chan_file_name = os.path.join( | |
| real_rir_folder, os.path.splitext(os.path.basename(rir_f))[0] + "-" + str(chan) + ".wav", | |
| ) | |
| _ = subprocess.check_output(f"sox {rir_f} {chan_file_name} remix {chan}", shell=True) | |
| # move simulated rirs to processed | |
| if not os.path.exists(os.path.join(dst_folder, "simulated_rirs")): | |
| move(os.path.join(data_folder, "RIRS_NOISES", "simulated_rirs"), dst_folder) | |
| os.chdir(dst_folder) | |
| all_rirs = glob.glob("**/*.wav", recursive=True) | |
| with open(manifest_file, "w") as man_f: | |
| entry = {} | |
| for rir in all_rirs: | |
| rir_file = os.path.join(dst_folder, rir) | |
| duration = subprocess.check_output("soxi -D {0}".format(rir_file), shell=True) | |
| entry["audio_filepath"] = rir_file | |
| entry["duration"] = float(duration) | |
| entry["offset"] = 0 | |
| entry["text"] = "_" | |
| man_f.write(json.dumps(entry) + "\n") | |
| print("Done!") | |
| def main(): | |
| data_root = os.path.abspath(args.data_root) | |
| data_set = "slr28" | |
| logging.getLogger().setLevel(logging.INFO) | |
| logging.info("\n\nWorking on: {0}".format(data_set)) | |
| filepath = os.path.join(data_root, data_set + ".zip") | |
| logging.info("Getting {0}".format(data_set)) | |
| __maybe_download_file(filepath, data_set.upper()) | |
| logging.info("Extracting {0}".format(data_set)) | |
| __extract_file(filepath, data_root) | |
| logging.info("Processing {0}".format(data_set)) | |
| __process_data( | |
| data_root, | |
| os.path.join(os.path.join(data_root, "processed")), | |
| os.path.join(os.path.join(data_root, "processed", "rir.json")), | |
| ) | |
| logging.info("Done!") | |
| if __name__ == "__main__": | |
| main() | |