File size: 3,523 Bytes
e976963
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import os
import librosa
import numpy as np
import gradio as gr
import soundfile as sf
from pedalboard import (
    Pedalboard, Reverb, Compressor, HighpassFilter,
    LowShelfFilter, HighShelfFilter, NoiseGate, Chorus
)
from pedalboard.io import AudioFile
from pydub import AudioSegment

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

def display_progress(percent, message, progress=gr.Progress()):
    progress(percent, desc=message)

def combine_audio(vocal_path, instrumental_path, output_path, vocal_gain, instrumental_gain, output_format):
    vocal_format = vocal_path.split('.')[-1]
    instrumental_format = instrumental_path.split('.')[-1]

    vocal = AudioSegment.from_file(vocal_path, format=vocal_format)
    instrumental = AudioSegment.from_file(instrumental_path, format=instrumental_format)

    vocal += vocal_gain
    instrumental += instrumental_gain

    combined = vocal.overlay(instrumental)
    combined.export(output_path, format=output_format)

def add_audio_effects(vocal_audio_path, instrumental_audio_path, reverb_rm_size, reverb_wet, reverb_dry, reverb_damping, reverb_width,
                      low_shelf_gain, high_shelf_gain, compressor_ratio, compressor_threshold, noise_gate_threshold, noise_gate_ratio,
                      noise_gate_attack, noise_gate_release, chorus_rate_hz, chorus_depth, chorus_centre_delay_ms, chorus_feedback,
                      chorus_mix, output_format, vocal_gain, instrumental_gain, progress=gr.Progress()):

    if not vocal_audio_path or not instrumental_audio_path:
        raise ValueError("Оба пути к аудиофайлам должны быть заполнены.")

    display_progress(0.2, "Применение аудиоэффектов к вокалу...", progress)
    board = Pedalboard(
        [
            HighpassFilter(),
            Compressor(ratio=compressor_ratio, threshold_db=compressor_threshold),
            NoiseGate(threshold_db=noise_gate_threshold, ratio=noise_gate_ratio, attack_ms=noise_gate_attack, release_ms=noise_gate_release),
            Reverb(room_size=reverb_rm_size, dry_level=reverb_dry, wet_level=reverb_wet, damping=reverb_damping, width=reverb_width),
            LowShelfFilter(gain_db=low_shelf_gain),
            HighShelfFilter(gain_db=high_shelf_gain),
            Chorus(rate_hz=chorus_rate_hz, depth=chorus_depth, centre_delay_ms=chorus_centre_delay_ms, feedback=chorus_feedback, mix=chorus_mix),
         ]
    )

    vocal_output_path = f'Vocal_Effects.wav'
    with AudioFile(vocal_audio_path) as f:
        with AudioFile(vocal_output_path, 'w', f.samplerate, 2) as o:
            while f.tell() < f.frames:
                chunk = f.read(int(f.samplerate))
                chunk = np.tile(chunk, (2, 1)).T
                effected = board(chunk, f.samplerate, reset=False)
                o.write(effected)

    display_progress(0.5, "Объединение вокала и инструментальной части...", progress)
    output_dir = os.path.join(BASE_DIR, 'processed_output')
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)
    combined_output_path = os.path.join(output_dir, f'AiCover_combined.{output_format}')

    if os.path.exists(combined_output_path):
        os.remove(combined_output_path)

    combine_audio(vocal_output_path, instrumental_audio_path, combined_output_path, vocal_gain, instrumental_gain, output_format)

    display_progress(1.0, "Готово!", progress)

    return combined_output_path