Beispiel #1
0
def generate(args):
    # Создаём папку с выходными файлами
    generate_dir = os.path.join(hp.generate_dir, 'output')
    os.makedirs(generate_dir, exist_ok=True)

    # Создать модель
    model = AgainModel().to(device)
    model.eval()

    # Загрузить чекпоинт
    ckpt = torch.load(hp.again_checkpoint)
    model.load_state_dict(ckpt['model'])

    # Создаём вокодер и Загружаем веса
    vocoder = GeneratorMel(hp.n_mels).to(device)
    ckpt = torch.load(hp.mel_checkpoint, map_location=device)
    vocoder.load_state_dict(ckpt['G'])

    # Загрузить звук
    source = process_audio(args.source, 'mel', wav_name=None,
                           it_audio=False)[0]
    target = process_audio(args.target, 'mel', wav_name=None,
                           it_audio=False)[0]

    # Обрезать до одной длины
    if hp.seglen is not None:
        target = target[:, :hp.seglen]
        source = source[:, :hp.seglen]

    # Получить новый путь
    source_path = os.path.join(
        generate_dir, f'{os.path.basename(args.source).replace(".wav","")}')
    target_path = os.path.basename(args.target).replace('.wav', '')

    # Получить новый файл
    with torch.no_grad():
        mel_output = model(
            source.unsqueeze(0).to(device),
            target.unsqueeze(0).to(device))
        audio_output = vocoder(10**mel_output).squeeze().cpu().numpy()
        #amp = np.maximum(1e-10, np.dot(hp._inv_mel_filtr,10**(mel_output.squeeze().cpu().numpy()) ))
        #audio_output = my_griffin_lim(amp,5)
        sf.write(source_path + f'_to_{target_path}' + '.wav', audio_output,
                 hp.sr)

    # Нарисовать Мелспектрограммы
    librosa.display.specshow(source.numpy(), cmap='viridis')
    plt.savefig(source_path + '.png')
    librosa.display.specshow(mel_output.squeeze().cpu().numpy(),
                             cmap='viridis')
    plt.savefig(source_path + f'_to_{target_path}' + '.png')
Beispiel #2
0
def read_audio_into_chunks(
        file_path: Text,
        length: Optional[float] = 20000 / 1001,
        split_on_silence: Optional[bool] = False,
        noise_threshold: Optional[float] = -36,
        sample_width: Optional[int] = 2,
        channels: Optional[int] = 1,
        frame_rate: Optional[int] = 48000) -> List[AudioSegment]:
    """
    Loads audio from file, preprocessess and splits into chunks

    Parameters
    ----------
    file_path : str
        path to audio file
    length : float, optional
        length of each chunk, by default 20000/1001
    split_on_silence : bool, optional
        wether to split audio when silence is identified, by default False
    noise_threshold : float, optional
        noise threshold denoting silence, by default -36
    sample_width : int, optional
        new sample width of audio, by default 2
    channels : int, optional
        new amount of channels of audio, by default 1
    frame_rate : int, optional
        new frame rate of audio, by default 48000

    Returns
    -------
    list
        chunks of processed audio
    """
    audio = AudioSegment.from_file(file_path, format='ogg')
    audio = process_audio(audio,
                          remove_silence=False,
                          sample_width=sample_width,
                          channels=channels,
                          frame_rate=frame_rate)
    return split_into_chunks(audio,
                             length=length,
                             split_on_silence=split_on_silence,
                             noise_threshold=noise_threshold)
Beispiel #3
0
def generate(format_wav):
    # Создаём папку с выходными файлами
    generate_dir = os.path.join(hp.generate_dir, 'output')    
    os.makedirs(generate_dir, exist_ok=True)
    
    # Создаём вокодер
    vocoder = GeneratorMel(hp.n_mels)
    
    # Загружаем веса
    ckpt = torch.load(hp.mel_checkpoint, map_location='cpu')
    vocoder.load_state_dict(ckpt['G'])
    
    # Информация о чекпоинте
    step = ckpt['step']
    epochs = int(ckpt['epoch'])
    print('Чекпоинт загружен: Эпоха %d, Шаг %d' % (epochs, step))    
    
    # Загружаем тестовые файлы
    if format_wav:
        testset = glob.glob(os.path.join(hp.generate_dir, '*.wav'))
    else:
        testset = glob.glob(os.path.join(hp.generate_dir, '*.mel'))
    
    for i, test_path in enumerate(tqdm(testset)):
        test_name = os.path.basename(test_path).replace('.mel', '.wav')
        
        # Загружаем Мелспектр, или получаем его из звука
        if format_wav:
            # Получаем Мелспектр из аудио
            mel = 10**process_audio(test_path, it_audio = False)
        else:
            # Загружаем Мелспектр
            mel = torch.load(test_path).unsqueeze(0)  
        
        # Сгенерировать сигнал из mel 
        audio_output = vocoder(mel)
        
        # Убрать лишнюю размерность, градиенты и перевести в numpy
        audio_output = audio_output.squeeze().detach().numpy()
        
        # Сохранить в файл
        sf.write(generate_dir +'/mel_' + test_name, audio_output, hp.sr)
Beispiel #4
0
def tts(fp, sentence, silence_duration=300):
    """
    Uses the models to create the audio file

    Parameters
    ----------
    fp : str
        path to save the audio file
    sentence : str
        sentence to synthesize
    """
    start = time.time()
    br = 240
    wavs = []
    length = 0
    for sent in filter(lambda x: x, re.split(r'[.|;|!|?|\n]', sentence)):
        for frase in textwrap.wrap(sent, width=br, break_long_words=False):
            cached = hashlib.sha1(str.encode(frase)).hexdigest()
            cached = tts_cache / '{}.wav'.format(cached)
            if cached not in tts_cache.glob('*.wav'):
                waveform = model_inference(model, vocoder_model,
                                           ' ' + frase + ' ', config, use_cuda)
                if waveform is None:
                    continue
                length += len(waveform)
                ap.save_wav(waveform, cached)
            wavs.append(cached)
    wavs = [
        AudioSegment.from_wav(w) + AudioSegment.silent(silence_duration)
        for w in wavs
    ]
    waveform = sum(wavs)
    if len(waveform):
        waveform = process_audio(waveform, remove_silence=False)
        waveform.export(fp, format='ogg')
        end = time.time()
        total = end - start
        rtf = total / (length / ap.sample_rate)
        print(' > Run-time: {:.03f} seconds'.format(total))
        print(' > Real-time factor: {:.03f} x'.format(rtf))
Beispiel #5
0
def train():
    # Создать папку для логов
    save_dir = os.path.join(hp.save_dir)
    os.makedirs(save_dir, exist_ok=True)
    
    # Загрузить список тренировачных mel
    mel_list = glob.glob(os.path.join(hp.train_dir, '*.mel'))
    
    # Создать Датасет
    trainset = MelGanDataset(mel_list)
    train_loader = DataLoader(trainset, batch_size=hp.batch_size, shuffle=True, drop_last=True)

    # Загрузить тестовый датасет
    test_mels = glob.glob(os.path.join(hp.eval_dir, '*.wav'))[:3]
    testset = [process_audio(test_mel, it_audio = False) for test_mel in test_mels]
    
    # создать Generator и 3*Discriminator
    G = GeneratorMel(hp.n_mels).cuda()
    D = MultiScale().cuda()
    g_optimizer = optim.Adam(G.parameters(), lr=hp.lr, betas=(hp.betas1, hp.betas2))
    d_optimizer = optim.Adam(D.parameters(), lr=hp.lr, betas=(hp.betas1, hp.betas2))

    # Загружаем модель
    step, epochs = 0, 0
    if hp.mel_checkpoint != '':
        print("Загрузка чекпоинтов")
        ckpt = torch.load(hp.mel_checkpoint)
        G.load_state_dict(ckpt['G'])
        g_optimizer.load_state_dict(ckpt['g_optimizer'])
        D.load_state_dict(ckpt['D'])
        d_optimizer.load_state_dict(ckpt['d_optimizer'])
        step = ckpt['step']
        epochs = int(ckpt['epoch'])
        print('Чекпоинт загружен: Эпоха %d, Шаг %d' % (epochs, step))

    #Попытка оптимизировать сеть
    torch.backends.cudnn.benchmark = True
    
    # Процесс обучения
    start = time.time()
    for epoch in range(epochs, hp.max_epoch):
        for (mel, audio) in train_loader:
            # Помещаем входной и выходной  файл в видеокарту
            mel = mel.cuda()
            audio = audio.cuda()

            # Получаем сигнал из спектра 16*1*8192
            fake_audio = G(mel)
            # Получаем отклик на созданное аудио без градиентов 3*7*16*16*8192(4096,2048)
            d_fake_detach = D(fake_audio.cuda().detach())
            # Получаем отклик на реальное аудио
            d_real = D(audio)    

            # ------------Дискриминатор---------------
            # Считаем ошибку на отклике на реальный сигнал. чем больше d_real тем лучше
            d_loss_real = 0
            for scale in d_real:
                d_loss_real += F.relu(1 - scale[-1]).mean()

            # Считаем ошибку на отклике на созданном сигнале без градиента. чем меньше d_loss_fake, тем лучше
            d_loss_fake = 0
            for scale in d_fake_detach:
                d_loss_fake += F.relu(1 + scale[-1]).mean()
            
            # Суммарная ошибка
            d_loss = d_loss_real + d_loss_fake
            
            # вычисляем градиенты и делаем шаг 
            D.zero_grad()
            d_loss.backward()
            d_optimizer.step()

            # ---------------Генератор----------------------
                     
            # Получаем отклик на созданное аудио
            d_fake = D(fake_audio.cuda())     
            
            # Считаем ошибку на отклик созданного сигнала с градиентом
            g_loss = 0
            for scale in d_fake:
                g_loss += -scale[-1].mean()

            # Считаем ошибку между откликом на реальный сигнал и на созданный
            feature_loss = 0
            for i in range(len(d_fake)):
                for j in range(len(d_fake[i]) - 1):
                    feature_loss += F.l1_loss(d_fake[i][j], d_real[i][j].detach())

            # Суммарная ошибка
            g_loss += hp.lambda_feat * feature_loss
            
            # вычисляем градиенты и делаем шаг 
            G.zero_grad()
            g_loss.backward()
            g_optimizer.step()

            # выводим ошибку
            step += 1
            if step % hp.log_interval == 0:
                print('Эпоха: %-5d, Шаг: %-7d, D_loss: %.05f, G_loss: %.05f, ms/batch: %5.2f' %
                    (epoch, step, d_loss, g_loss, 1000 * (time.time() - start) / hp.log_interval))
                start = time.time()
            
            # Сохраняем модель и синтезируем тестовые файлы
            if step % hp.save_interval == 0:
                print("Сохраняем модель")
                torch.save({
                    'G': G.state_dict(),
                    'g_optimizer': g_optimizer.state_dict(),
                    'D': D.state_dict(),
                    'd_optimizer': d_optimizer.state_dict(),
                    'step': step,
                    'epoch': epoch,
                }, save_dir +'/mel_ckpt_%dk.pt' % (step // 1000))
                
                if testset:
                    print("Синтезируем тестовые файлы")
                    with torch.no_grad():
                        for i, mel_test in enumerate(testset):
                            audio_output = G(mel_test.cuda())
                            audio_output = audio_output.squeeze().cpu().numpy()
                            sf.write(save_dir +'/mel_gen_%d_%dk_%d.wav' % (epoch, step // 1000, i), audio_output, hp.sr)
                else:
                    print("Нет файлов для тестирования. Поместите их в test_dir")
Beispiel #6
0
def test_process_audio():
    input_file = f"{PATH}/test_input/copypasta.mp4"
    output_file = f"{PATH}/test_output/copypasta_processed_AUDIO.mp4"
    result, output = utils.process_audio(input_file, output_file)
Beispiel #7
0
def train(format_wav):
    # Создать папку для логов
    save_dir = os.path.join(hp.save_dir)
    os.makedirs(save_dir, exist_ok=True)

    # Загрузить список тренировачных mel
    if format_wav:
        # Синтезированные Гриффин Лим файлы
        mel_list = glob.glob(os.path.join(hp.train_dir, '*.glim'))
    else:
        # Мел файлы
        mel_list = glob.glob(os.path.join(hp.train_dir, '*.mel'))

    # Создать Датасет
    trainset = WavGanDataset(mel_list, format_wav)
    train_loader = DataLoader(trainset,
                              batch_size=hp.batch_size,
                              shuffle=True,
                              drop_last=True)

    # Загрузить тестовый датасет
    test_wavs = glob.glob(os.path.join(hp.test_dir, '*.wav'))
    testset = [
        process_audio(test_mel, it_audio=True).unsqueeze(0)
        for test_mel in test_wavs
    ]

    # создать Generator и 3*Discriminator
    G = GeneratorWav().cuda()
    D = MultiScale().cuda()
    g_optimizer = optim.Adam(G.parameters(),
                             lr=hp.lr,
                             betas=(hp.betas1, hp.betas2))
    d_optimizer = optim.Adam(D.parameters(),
                             lr=hp.lr,
                             betas=(hp.betas1, hp.betas2))

    # Загружаем модель
    step, epochs = 0, 0
    if hp.wav_checkpoint is not None:
        print("Загрузка чекпоинтов")
        ckpt = torch.load(hp.wav_checkpoint)
        G.load_state_dict(ckpt['G'])
        g_optimizer.load_state_dict(ckpt['g_optimizer'])
        D.load_state_dict(ckpt['D'])
        d_optimizer.load_state_dict(ckpt['d_optimizer'])
        step = ckpt['step']
        epochs = int(ckpt['epoch'])
        print('Чекпоинт загружен: Эпоха %d, Шаг %d' % (epochs, step))

    #Попытка оптимизировать сеть
    torch.backends.cudnn.benchmark = True

    # Процесс обучения
    start = time.time()
    for epoch in range(epochs, hp.max_epoch):
        for (audio_input, audio_output) in train_loader:
            # Помещаем входной и выходной  файл в видеокарту
            audio_input = audio_input.cuda()
            audio_output = audio_output.cuda()

            # Получаем выходной сигнал из входного 16*1*8192
            fake_audio = G(audio_input)
            # Получаем отклик на созданное аудио без градиентов 3*7*16*16*8192(4096,2048)
            d_fake_detach = D(fake_audio.cuda().detach())
            # Получаем отклик на созданное аудио
            d_fake = D(fake_audio.cuda())
            # Получаем отклик на реальное аудио
            d_real = D(audio_output)

            # ------------Дискриминатор---------------
            # Считаем ошибку на отклике на реальный сигнал. чем больше d_real тем лучше
            d_loss_real = 0
            for scale in d_real:
                d_loss_real += F.relu(1 - scale[-1]).mean()

            # Считаем ошибку на отклике на созданном сигнале без градиента. чем меньше d_loss_fake, тем лучше
            d_loss_fake = 0
            for scale in d_fake_detach:
                d_loss_fake += F.relu(1 + scale[-1]).mean()

            # Суммарная ошибка
            d_loss = d_loss_real + d_loss_fake

            # Вычисляем градиенты и делаем шаг
            D.zero_grad()
            d_loss.backward()
            d_optimizer.step()

            # ---------------Генератор----------------------
            # Считаем ошибку на отклик созданного сигнала с градиентом
            g_loss = 0
            for scale in d_fake:
                g_loss += -scale[-1].mean()

            # Считаем ошибку между откликом на реальный сигнал и на созданный
            feature_loss = 0
            for i in range(len(d_fake)):
                for j in range(len(d_fake[i]) - 1):
                    feature_loss += F.l1_loss(d_fake[i][j],
                                              d_real[i][j].detach())

            # Суммарная ошибка
            g_loss += hp.lambda_feat * feature_loss

            # вычисляем градиенты и делаем шаг
            G.zero_grad()
            g_loss.backward()
            g_optimizer.step()

            # выводим ошибку
            step += 1
            if step % hp.log_interval == 0:
                print(
                    'Эпоха: %-5d, Шаг: %-7d, D_loss: %.05f, G_loss: %.05f, ms/batch: %5.2f'
                    % (epoch, step, d_loss, g_loss, 1000 *
                       (time.time() - start) / hp.log_interval))
                start = time.time()

            # Сохраняем модель и синтезируем тестовые файлы
            if step % hp.save_interval == 0:
                print("Сохраняем модель")
                torch.save(
                    {
                        'G': G.state_dict(),
                        'g_optimizer': g_optimizer.state_dict(),
                        'D': D.state_dict(),
                        'd_optimizer': d_optimizer.state_dict(),
                        'step': step,
                        'epoch': epoch,
                        #}, save_dir +'/wav_ckpt_%dk.pt' % (step // 10000))
                    },
                    save_dir + '/wav_ckpt_%d.pt' % (step))

                if testset:
                    print("Синтезируем тестовые файлы")
                    with torch.no_grad():
                        for i, audio_input in enumerate(testset):
                            audio_output = G(audio_input.cuda())
                            audio_output = audio_output.squeeze().detach().cpu(
                            ).numpy()

                            audio_input = audio_input.squeeze().detach().cpu(
                            ).numpy()

                            spectr = librosa.stft(y=audio_input,
                                                  hop_length=hp.hop_length,
                                                  n_fft=hp.n_fft)
                            ampl = np.abs(spectr)  #Амплитуда
                            phasa = np.angle(spectr)  #Фаза
                            spectr2 = librosa.stft(y=audio_output,
                                                   hop_length=hp.hop_length,
                                                   n_fft=hp.n_fft)
                            #ampl2 = np.abs(spectr2) #Амплитуда
                            phasa2 = np.angle(spectr2)  #Фаза
                            p1 = phasa.shape[1]
                            p2 = phasa2.shape[1]
                            if p1 > p2:
                                delta_shape = p1 - p2
                                ph2 = np.pad(phasa2,
                                             ((0, 0), (0, delta_shape)),
                                             mode='constant',
                                             constant_values=0)
                            else:
                                ph2 = np.delete(phasa2, np.s_[p1:], 1)

                            ampl_phasa = ampl * np.cos(
                                ph2) + 1j * ampl * np.sin(ph2)
                            y_ampl_phasa = librosa.istft(
                                ampl_phasa, hop_length=hp.hop_length)

                            sf.write(
                                save_dir + '/wav_gen_%d_%dk_%d.wav' %
                                (epoch, step // 1000, i), audio_output, hp.sr)
                            sf.write(
                                save_dir + '/wav_phase_%d_%dk_%d.wav' %
                                (epoch, step // 1000, i), y_ampl_phasa, hp.sr)
                else:
                    print(
                        "Нет файлов для тестирования. Поместите их в test_dir")