<gh_stars>0
import argparse
import csv
import glob
import os
import pickle
import pickle as pk
import time

import _pickle as cPickle
import h5py  # hdf5文件能够存储两种类型的数据对象：数据集（dataset）
import librosa
import matplotlib.pyplot as plt
import numpy as np
import soundfile
from scipy import signal
from sklearn import preprocessing

# import prepare_data as pp_data
# from spectrogram_to_wave import recover_wav


def create_folder(fd):  # 创建一个文件夹，  这里要输入fd  即要创建的路径
    if not os.path.exists(fd):
        os.makedirs(fd)


def read_audio(path, target_fs=16000):  # 在后面创建csv文件时 需要进行调用
    (audio, fs) = soundfile.read(path)
    if audio.ndim > 1:
        audio = np.mean(audio, axis=1)
    if target_fs is not None and fs != target_fs:
        audio = librosa.resample(audio, orig_sr=fs, target_sr=target_fs)
        fs = target_fs
    return audio, fs


def write_audio(path, audio, sample_rate):  # 把干净语音与噪声混合起来重新写入一个文件
    soundfile.write(file=path, data=audio, samplerate=sample_rate)

###


def create_mixture_csv(workspace, speech_dir, noise_dir, data_type, magnification):
    """Create csv containing mixture information. 
    Each line in the .csv file contains [speech_name, noise_name, noise_onset, noise_offset]

    Args:
      workspace: str, path of workspace. 
      speech_dir: str, path of speech data. 
      noise_dir: str, path of noise data. 
      data_type: str, 'train' | 'test'. 
      magnification: int, only used when data_type='train', number of noise 
          selected to mix with a speech. E.g., when magnication=3, then 4620
          speech with create 4620*3 mixtures. magnification should not larger 
          than the species of noises. 
    """
    #workspace = args.workspace
    #speech_dir = args.speech_dir
    #noise_dir = args.noise_dir
    #data_type = args.data_type
    #magnification = args.magnification
    #fs = cfg.sample_rate

    speech_names = [na for na in os.listdir(
        speech_dir) if na.lower().endswith(".wav")]
    noise_names = [na for na in os.listdir(
        noise_dir) if na.lower().endswith(".wav")]

    rs = np.random.RandomState(0)
    out_csv_path = os.path.join(
        workspace, "mixture_csvs", "%s.csv" % data_type)
    create_folder(os.path.dirname(out_csv_path))  # 创建一个新的文件夹

    cnt = 0
    f = open(out_csv_path, 'w')
    f.write("%s\t%s\t%s\t%s\n" %
            ("speech_name", "noise_name", "noise_onset", "noise_offset"))
    for speech_na in speech_names:
        # Read speech.
        speech_path = os.path.join(speech_dir, speech_na)
        (speech_audio, _) = read_audio(speech_path)  # 调用前面定义的函数
        len_speech = len(speech_audio)

        # For training data, mix each speech with randomly picked #magnification noises.
        if data_type == 'train':
            selected_noise_names = rs.choice(
                noise_names, size=magnification, replace=True)
        # For test data, mix each speech with all noises.
        elif data_type == 'test':
            selected_noise_names = noise_names
        else:
            raise Exception("data_type must be train | test!")

        # Mix one speech with different noises many times.
        for noise_na in selected_noise_names:
            noise_path = os.path.join(noise_dir, noise_na)
            (noise_audio, _) = read_audio(noise_path)

            len_noise = len(noise_audio)  # 噪声的维度

            if len_noise <= len_speech:  # 噪声的维度小于语音的长度
                noise_onset = 0
                nosie_offset = len_speech  # 语音信号的长度
            # If noise longer than speech then randomly select a segment of noise.  噪声大于语音  随机切分
            else:
                noise_onset = rs.randint(0, len_noise - len_speech, size=1)[0]
                nosie_offset = noise_onset + len_speech

            if cnt % 100 == 0:
                print(cnt)

            cnt += 1
            f.write("%s\t%s\t%d\t%d\n" %
                    (speech_na, noise_na, noise_onset, nosie_offset))
    f.close()
    print(out_csv_path)
    print("Create %s mixture csv finished!" % data_type)

###


def calculate_mixture_features(workspace, speech_dir, noise_dir, data_type, snr):
    """Calculate spectrogram for mixed, speech and noise audio. Then write the 
    features to disk. 

    Args:
      workspace: str, path of workspace. 
      speech_dir: str, path of speech data. 
      noise_dir: str, path of noise data. 
      data_type: str, 'train' | 'test'. 
      snr: float, signal to noise ratio to be mixed. 
    """
    #workspace = args.workspace
    #speech_dir = args.speech_dir
    #noise_dir = args.noise_dir
    #data_type = args.data_type
    # snr = args.snr   #信噪比
    fs = 16000

    # Open mixture csv.
    mixture_csv_path = os.path.join(
        workspace, "mixture_csvs", "%s.csv" % data_type)
    with open(mixture_csv_path, 'r', encoding="utf-8") as f:
        reader = csv.reader(f, delimiter='\t')  # 读取文件以  制表符分开
        lis = list(reader)  # 得到csv文件中的名字

    t1 = time.time()
    cnt = 0
    for i1 in range(1, len(lis)):
        [speech_na, noise_na, noise_onset, noise_offset] = lis[i1]
        noise_onset = int(noise_onset)
        noise_offset = int(noise_offset)

        # Read speech audio.
        speech_path = os.path.join(speech_dir, speech_na)  # 路径拼接
        (speech_audio, _) = read_audio(
            speech_path, target_fs=fs)  # 读取音频信号的数据  采样率为8000hz

        # Read noise audio.
        noise_path = os.path.join(noise_dir, noise_na)   # 文件路径 噪声名字
        (noise_audio, _) = read_audio(noise_path, target_fs=fs)  # 噪声的音频数据

        # Repeat noise to the same length as speech.
        if len(noise_audio) < len(speech_audio):
            # float(1) = 1.0 将函数里面的数字转换为浮点型
            n_repeat = int(
                np.ceil(float(len(speech_audio)) / float(len(noise_audio))))
            # ceil() 函数返回数字的上入整数  取整的意思
            # 将噪声近行拓展  n_repeat 就是拓展的的行数
            noise_audio_ex = np.tile(noise_audio, n_repeat)
            noise_audio = noise_audio_ex[0: len(speech_audio)]  # 更新后的噪声数据
        # Truncate noise to the same length as speech.
        else:
            noise_audio = noise_audio[noise_onset: noise_offset]  # 否则按照默认的长度来？

        # Scale speech to given snr.  #将语音缩放到给定的信噪比
        scaler = get_amplitude_scaling_factor(
            speech_audio, noise_audio, snr=snr)
        speech_audio *= scaler  # a*5   解释为a= a*5    相乘之后再赋值   计算的优先顺序

        # Get normalized mixture, speech, noise.
        (mixed_audio, speech_audio, noise_audio, alpha) = additive_mixing(
            speech_audio, noise_audio)  # 混合

        # Write out mixed audio.
        out_bare_na = os.path.join("%s.%s" %
                                   (os.path.splitext(speech_na)[0], os.path.splitext(noise_na)[0]))  # 分离拓展名
        out_audio_path = os.path.join(workspace, "mixed_audios", "spectrogram",
                                      data_type, "%ddb" % int(snr), "%s.wav" % out_bare_na)  # 加上信噪比的一个命名
        create_folder(os.path.dirname(out_audio_path))
        write_audio(out_audio_path, mixed_audio, fs)  # 将混合好的语音写入一个新文件夹中


# 把网站的数据下载解压，目录结构如下
# -data
#     -clean_trainset_wav
#         |-p226_001.wav
#         |-p226_002.wav
#         |-...
#     -noisy_trainset_wav
#         |-p226_001.wav
#         |-p226_002.wav
#         |-...
# -DeepComplexCRN
#     |- code

root = "../data"
speech_dir_train = "../data/clean_trainset_wav"
noise_dir_train = "../data/noisy_trainset_wav"
data_type_train = "train"
magnification_train = 18
snr = 5
n_concat = 11
n_hop = 2

speech_dir_test = "../data/clean_testset_wav"
noise_dir_test = "../data/noisy_testset_wav"
data_type_test = "test"
magnification_test = 2  # 看具体选择几种噪声进行混合

# 构建训练集
create_mixture_csv(root, speech_dir_train, noise_dir_train,
                   data_type_train, magnification_train)
calculate_mixture_features(root, speech_dir_train,
                           noise_dir_train, data_type_train, snr)

# 构建测试集
create_mixture_csv(root, speech_dir_test, noise_dir_test,
                   data_type_test, magnification_test)
calculate_mixture_features(root, speech_dir_test,
                           noise_dir_test, data_type_test, snr)

import argparse
import csv
import glob
import os
import pickle
import pickle as pk
import time

import _pickle as cPickle
import h5py  # hdf5文件能够存储两种类型的数据对象：数据集（dataset）
import librosa
import matplotlib.pyplot as plt
import numpy as np
import soundfile
from scipy import signal
from sklearn import preprocessing

# import prepare_data as pp_data
# from spectrogram_to_wave import recover_wav


def create_folder(fd):  # 创建一个文件夹，  这里要输入fd  即要创建的路径
    if not os.path.exists(fd):
        os.makedirs(fd)


def read_audio(path, target_fs=16000):  # 在后面创建csv文件时 需要进行调用
    (audio, fs) = soundfile.read(path)
    if audio.ndim > 1:
        audio = np.mean(audio, axis=1)
    if target_fs is not None and fs != target_fs:
        audio = librosa.resample(audio, orig_sr=fs, target_sr=target_fs)
        fs = target_fs
    return audio, fs


def write_audio(path, audio, sample_rate):  # 把干净语音与噪声混合起来重新写入一个文件
    soundfile.write(file=path, data=audio, samplerate=sample_rate)

###


def create_mixture_csv(workspace, speech_dir, noise_dir, data_type, magnification):
    """Create csv containing mixture information. 
    Each line in the .csv file contains [speech_name, noise_name, noise_onset, noise_offset]

    Args:
      workspace: str, path of workspace. 
      speech_dir: str, path of speech data. 
      noise_dir: str, path of noise data. 
      data_type: str, 'train' | 'test'. 
      magnification: int, only used when data_type='train', number of noise 
          selected to mix with a speech. E.g., when magnication=3, then 4620
          speech with create 4620*3 mixtures. magnification should not larger 
          than the species of noises. 
    """
    #workspace = args.workspace
    #speech_dir = args.speech_dir
    #noise_dir = args.noise_dir
    #data_type = args.data_type
    #magnification = args.magnification
    #fs = cfg.sample_rate

    speech_names = [na for na in os.listdir(
        speech_dir) if na.lower().endswith(".wav")]
    noise_names = [na for na in os.listdir(
        noise_dir) if na.lower().endswith(".wav")]

    rs = np.random.RandomState(0)
    out_csv_path = os.path.join(
        workspace, "mixture_csvs", "%s.csv" % data_type)
    create_folder(os.path.dirname(out_csv_path))  # 创建一个新的文件夹

    cnt = 0
    f = open(out_csv_path, 'w')
    f.write("%s\t%s\t%s\t%s\n" %
            ("speech_name", "noise_name", "noise_onset", "noise_offset"))
    for speech_na in speech_names:
        # Read speech.
        speech_path = os.path.join(speech_dir, speech_na)
        (speech_audio, _) = read_audio(speech_path)  # 调用前面定义的函数
        len_speech = len(speech_audio)

        # For training data, mix each speech with randomly picked #magnification noises.
        if data_type == 'train':
            selected_noise_names = rs.choice(
                noise_names, size=magnification, replace=True)
        # For test data, mix each speech with all noises.
        elif data_type == 'test':
            selected_noise_names = noise_names
        else:
            raise Exception("data_type must be train | test!")

        # Mix one speech with different noises many times.
        for noise_na in selected_noise_names:
            noise_path = os.path.join(noise_dir, noise_na)
            (noise_audio, _) = read_audio(noise_path)

            len_noise = len(noise_audio)  # 噪声的维度

            if len_noise <= len_speech:  # 噪声的维度小于语音的长度
                noise_onset = 0
                nosie_offset = len_speech  # 语音信号的长度
            # If noise longer than speech then randomly select a segment of noise.  噪声大于语音  随机切分
            else:
                noise_onset = rs.randint(0, len_noise - len_speech, size=1)[0]
                nosie_offset = noise_onset + len_speech

            if cnt % 100 == 0:
                print(cnt)

            cnt += 1
            f.write("%s\t%s\t%d\t%d\n" %
                    (speech_na, noise_na, noise_onset, nosie_offset))
    f.close()
    print(out_csv_path)
    print("Create %s mixture csv finished!" % data_type)

###


def calculate_mixture_features(workspace, speech_dir, noise_dir, data_type, snr):
    """Calculate spectrogram for mixed, speech and noise audio. Then write the 
    features to disk. 

    Args:
      workspace: str, path of workspace. 
      speech_dir: str, path of speech data. 
      noise_dir: str, path of noise data. 
      data_type: str, 'train' | 'test'. 
      snr: float, signal to noise ratio to be mixed. 
    """
    #workspace = args.workspace
    #speech_dir = args.speech_dir
    #noise_dir = args.noise_dir
    #data_type = args.data_type
    # snr = args.snr   #信噪比
    fs = 16000

    # Open mixture csv.
    mixture_csv_path = os.path.join(
        workspace, "mixture_csvs", "%s.csv" % data_type)
    with open(mixture_csv_path, 'r', encoding="utf-8") as f:
        reader = csv.reader(f, delimiter='\t')  # 读取文件以  制表符分开
        lis = list(reader)  # 得到csv文件中的名字

    t1 = time.time()
    cnt = 0
    for i1 in range(1, len(lis)):
        [speech_na, noise_na, noise_onset, noise_offset] = lis[i1]
        noise_onset = int(noise_onset)
        noise_offset = int(noise_offset)

        # Read speech audio.
        speech_path = os.path.join(speech_dir, speech_na)  # 路径拼接
        (speech_audio, _) = read_audio(
            speech_path, target_fs=fs)  # 读取音频信号的数据  采样率为8000hz

        # Read noise audio.
        noise_path = os.path.join(noise_dir, noise_na)   # 文件路径 噪声名字
        (noise_audio, _) = read_audio(noise_path, target_fs=fs)  # 噪声的音频数据

        # Repeat noise to the same length as speech.
        if len(noise_audio) < len(speech_audio):
            # float(1) = 1.0 将函数里面的数字转换为浮点型
            n_repeat = int(
                np.ceil(float(len(speech_audio)) / float(len(noise_audio))))
            # ceil() 函数返回数字的上入整数  取整的意思
            # 将噪声近行拓展  n_repeat 就是拓展的的行数
            noise_audio_ex = np.tile(noise_audio, n_repeat)
            noise_audio = noise_audio_ex[0: len(speech_audio)]  # 更新后的噪声数据
        # Truncate noise to the same length as speech.
        else:
            noise_audio = noise_audio[noise_onset: noise_offset]  # 否则按照默认的长度来？

        # Scale speech to given snr.  #将语音缩放到给定的信噪比
        scaler = get_amplitude_scaling_factor(
            speech_audio, noise_audio, snr=snr)
        speech_audio *= scaler  # a*5   解释为a= a*5    相乘之后再赋值   计算的优先顺序

        # Get normalized mixture, speech, noise.
        (mixed_audio, speech_audio, noise_audio, alpha) = additive_mixing(
            speech_audio, noise_audio)  # 混合

        # Write out mixed audio.
        out_bare_na = os.path.join("%s.%s" %
                                   (os.path.splitext(speech_na)[0], os.path.splitext(noise_na)[0]))  # 分离拓展名
        out_audio_path = os.path.join(workspace, "mixed_audios", "spectrogram",
                                      data_type, "%ddb" % int(snr), "%s.wav" % out_bare_na)  # 加上信噪比的一个命名
        create_folder(os.path.dirname(out_audio_path))
        write_audio(out_audio_path, mixed_audio, fs)  # 将混合好的语音写入一个新文件夹中


# 把网站的数据下载解压，目录结构如下
# -data
#     -clean_trainset_wav
#         |-p226_001.wav
#         |-p226_002.wav
#         |-...
#     -noisy_trainset_wav
#         |-p226_001.wav
#         |-p226_002.wav
#         |-...
# -DeepComplexCRN
#     |- code

root = "../data"
speech_dir_train = "../data/clean_trainset_wav"
noise_dir_train = "../data/noisy_trainset_wav"
data_type_train = "train"
magnification_train = 18
snr = 5
n_concat = 11
n_hop = 2

speech_dir_test = "../data/clean_testset_wav"
noise_dir_test = "../data/noisy_testset_wav"
data_type_test = "test"
magnification_test = 2  # 看具体选择几种噪声进行混合

# 构建训练集
create_mixture_csv(root, speech_dir_train, noise_dir_train,
                   data_type_train, magnification_train)
calculate_mixture_features(root, speech_dir_train,
                           noise_dir_train, data_type_train, snr)

# 构建测试集
create_mixture_csv(root, speech_dir_test, noise_dir_test,
                   data_type_test, magnification_test)
calculate_mixture_features(root, speech_dir_test,
                           noise_dir_test, data_type_test, snr)
# hdf5文件能够存储两种类型的数据对象：数据集（dataset） # import prepare_data as pp_data # from spectrogram_to_wave import recover_wav # 创建一个文件夹，  这里要输入fd  即要创建的路径 # 在后面创建csv文件时 需要进行调用 # 把干净语音与噪声混合起来重新写入一个文件 ### Create csv containing mixture information.      Each line in the .csv file contains [speech_name, noise_name, noise_onset, noise_offset]      Args:       workspace: str, path of workspace.        speech_dir: str, path of speech data.        noise_dir: str, path of noise data.        data_type: str, 'train' | 'test'.        magnification: int, only used when data_type='train', number of noise            selected to mix with a speech. E.g., when magnication=3, then 4620           speech with create 4620*3 mixtures. magnification should not larger            than the species of noises. #workspace = args.workspace #speech_dir = args.speech_dir #noise_dir = args.noise_dir #data_type = args.data_type #magnification = args.magnification #fs = cfg.sample_rate # 创建一个新的文件夹 # Read speech. # 调用前面定义的函数 # For training data, mix each speech with randomly picked #magnification noises. # For test data, mix each speech with all noises. # Mix one speech with different noises many times. # 噪声的维度 # 噪声的维度小于语音的长度 # 语音信号的长度 # If noise longer than speech then randomly select a segment of noise.  噪声大于语音  随机切分 ### Calculate spectrogram for mixed, speech and noise audio. Then write the      features to disk.       Args:       workspace: str, path of workspace.        speech_dir: str, path of speech data.        noise_dir: str, path of noise data.        data_type: str, 'train' | 'test'.        snr: float, signal to noise ratio to be mixed. #workspace = args.workspace #speech_dir = args.speech_dir #noise_dir = args.noise_dir #data_type = args.data_type # snr = args.snr   #信噪比 # Open mixture csv. # 读取文件以  制表符分开 # 得到csv文件中的名字 # Read speech audio. # 路径拼接 # 读取音频信号的数据  采样率为8000hz # Read noise audio. # 文件路径 噪声名字 # 噪声的音频数据 # Repeat noise to the same length as speech. # float(1) = 1.0 将函数里面的数字转换为浮点型 # ceil() 函数返回数字的上入整数  取整的意思 # 将噪声近行拓展  n_repeat 就是拓展的的行数 # 更新后的噪声数据 # Truncate noise to the same length as speech. # 否则按照默认的长度来？ # Scale speech to given snr.  #将语音缩放到给定的信噪比 # a*5   解释为a= a*5    相乘之后再赋值   计算的优先顺序 # Get normalized mixture, speech, noise. # 混合 # Write out mixed audio. # 分离拓展名 # 加上信噪比的一个命名 # 将混合好的语音写入一个新文件夹中 # 把网站的数据下载解压，目录结构如下 # -data #     -clean_trainset_wav #         |-p226_001.wav #         |-p226_002.wav #         |-... #     -noisy_trainset_wav #         |-p226_001.wav #         |-p226_002.wav #         |-... # -DeepComplexCRN #     |- code # 看具体选择几种噪声进行混合 # 构建训练集 # 构建测试集