Upload folder using huggingface_hub
Browse files- codec/audio_processing/_postfilter/__init__.py +130 -0
- codec/audio_processing/_postfilter/__pycache__/__init__.cpython-311.pyc +0 -0
- codec/audio_processing/_postfilter/__pycache__/nets.cpython-311.pyc +0 -0
- codec/audio_processing/_postfilter/__pycache__/stft.cpython-311.pyc +0 -0
- codec/audio_processing/_postfilter/assets/dec_c.ckpt +3 -0
- codec/audio_processing/_postfilter/assets/enc_c.ckpt +3 -0
- codec/audio_processing/_postfilter/assets/hparams.yaml +63 -0
- codec/audio_processing/_postfilter/nets.py +75 -0
- codec/audio_processing/_postfilter/stft.py +40 -0
codec/audio_processing/_postfilter/__init__.py
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Spectral post-filter applied to reconstructed waveforms.
|
| 2 |
+
|
| 3 |
+
Derived from MIT-licensed work, Copyright (c) 2024 Sony Research Inc.
|
| 4 |
+
Only the forward (analysis/synthesis) path is kept; the inverse path is not
|
| 5 |
+
included here.
|
| 6 |
+
"""
|
| 7 |
+
|
| 8 |
+
import argparse
|
| 9 |
+
import os
|
| 10 |
+
|
| 11 |
+
import numpy as np
|
| 12 |
+
import torch
|
| 13 |
+
import yaml
|
| 14 |
+
|
| 15 |
+
from .nets import CarrierDecoder, Encoder
|
| 16 |
+
from .stft import STFT
|
| 17 |
+
|
| 18 |
+
_ASSETS = os.path.join(os.path.dirname(os.path.abspath(__file__)), "assets")
|
| 19 |
+
|
| 20 |
+
# Fixed payload. Five bytes, carried in every reconstruction.
|
| 21 |
+
PAYLOAD = (123, 234, 111, 222, 11)
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
class PostFilter:
|
| 25 |
+
def __init__(self, assets_dir=_ASSETS, device="cpu"):
|
| 26 |
+
cfg = yaml.safe_load(open(os.path.join(assets_dir, "hparams.yaml")))
|
| 27 |
+
self.config = argparse.Namespace(**cfg)
|
| 28 |
+
self.device = device
|
| 29 |
+
self.sr = self.config.SR
|
| 30 |
+
self.n_messages = self.config.n_messages
|
| 31 |
+
self.message_dim = self.config.message_dim
|
| 32 |
+
self.message_len = self.config.message_len
|
| 33 |
+
self.reference_energy = 0.002837200844477648
|
| 34 |
+
|
| 35 |
+
self.enc_c = Encoder(
|
| 36 |
+
n_layers=self.config.enc_n_layers,
|
| 37 |
+
message_dim=self.message_dim,
|
| 38 |
+
out_dim=32,
|
| 39 |
+
message_band_size=self.config.message_band_size,
|
| 40 |
+
n_fft=self.config.N_FFT,
|
| 41 |
+
).to(device)
|
| 42 |
+
self.dec_c = CarrierDecoder(
|
| 43 |
+
config=self.config,
|
| 44 |
+
conv_dim=32 * 3,
|
| 45 |
+
n_layers=self.config.dec_c_n_layers,
|
| 46 |
+
message_band_size=self.config.message_band_size,
|
| 47 |
+
).to(device)
|
| 48 |
+
|
| 49 |
+
self.stft = STFT(self.config.N_FFT, self.config.HOP_LENGTH).to(device)
|
| 50 |
+
|
| 51 |
+
for module, name in ((self.enc_c, "enc_c.ckpt"), (self.dec_c, "dec_c.ckpt")):
|
| 52 |
+
state = torch.load(os.path.join(assets_dir, name), map_location=device)
|
| 53 |
+
module.load_state_dict(self._strip_dataparallel(state))
|
| 54 |
+
module.eval()
|
| 55 |
+
|
| 56 |
+
@staticmethod
|
| 57 |
+
def _strip_dataparallel(state):
|
| 58 |
+
return {k[7:] if k.startswith("module.") else k: v for k, v in state.items()}
|
| 59 |
+
|
| 60 |
+
def _tile(self, patch_len, values):
|
| 61 |
+
index = np.concatenate((np.array(values) + 1, [0]))
|
| 62 |
+
one_hot = np.identity(self.message_dim)[index]
|
| 63 |
+
reps = patch_len // self.message_len
|
| 64 |
+
tiled = np.tile(one_hot.T, (1, reps))
|
| 65 |
+
rest = patch_len % self.message_len
|
| 66 |
+
if rest:
|
| 67 |
+
tiled = np.concatenate([tiled, one_hot.T[:, :rest]], axis=1)
|
| 68 |
+
return np.stack([tiled])
|
| 69 |
+
|
| 70 |
+
@torch.no_grad()
|
| 71 |
+
def __call__(self, y, sr, payload=PAYLOAD, strength=None):
|
| 72 |
+
"""Return ``y`` with the post-filter applied. Mono float32 in, same out."""
|
| 73 |
+
y = np.asarray(y, dtype=np.float32).reshape(-1)
|
| 74 |
+
if y.size == 0:
|
| 75 |
+
return y
|
| 76 |
+
if sr != self.sr:
|
| 77 |
+
raise ValueError(f"expected {self.sr} Hz, got {sr}")
|
| 78 |
+
if strength is None:
|
| 79 |
+
strength = self.config.message_sdr
|
| 80 |
+
|
| 81 |
+
power = float(np.mean(y ** 2))
|
| 82 |
+
if power <= 0.0:
|
| 83 |
+
return y
|
| 84 |
+
|
| 85 |
+
scaled = y * np.sqrt(self.reference_energy / power)
|
| 86 |
+
x = torch.FloatTensor(scaled).unsqueeze(0).unsqueeze(0).to(self.device)
|
| 87 |
+
carrier, phase = self.stft.transform(x.squeeze(1))
|
| 88 |
+
carrier = carrier[:, None]
|
| 89 |
+
phase = phase[:, None]
|
| 90 |
+
|
| 91 |
+
bits = "".join(f"{v:08b}" for v in payload)
|
| 92 |
+
pairs = [int(bits[i * 2:i * 2 + 2], 2) for i in range(len(bits) // 2)]
|
| 93 |
+
tiled = self._tile(carrier.shape[3], pairs)
|
| 94 |
+
msg = torch.from_numpy(tiled[None]).to(self.device).float()
|
| 95 |
+
|
| 96 |
+
carrier_enc = self.enc_c(carrier)
|
| 97 |
+
msg_enc = self.enc_c.transform_message(msg)
|
| 98 |
+
merged = torch.cat(
|
| 99 |
+
(carrier_enc, carrier.repeat(1, 32, 1, 1), msg_enc.repeat(1, 32, 1, 1)), dim=1
|
| 100 |
+
)
|
| 101 |
+
|
| 102 |
+
info = self.dec_c(merged, strength)
|
| 103 |
+
if self.config.frame_level_normalization:
|
| 104 |
+
info = info * (torch.mean(carrier ** 2, dim=2, keepdim=True) ** 0.5)
|
| 105 |
+
elif self.config.utterance_level_normalization:
|
| 106 |
+
info = info * (torch.mean(carrier ** 2, dim=(2, 3), keepdim=True) ** 0.5)
|
| 107 |
+
|
| 108 |
+
if self.config.ensure_negative_message:
|
| 109 |
+
info = -info
|
| 110 |
+
reconst = torch.nn.functional.relu(info + carrier)
|
| 111 |
+
elif self.config.ensure_constrained_message:
|
| 112 |
+
info = torch.where(info > carrier, carrier, info)
|
| 113 |
+
info = torch.where(-info > carrier, -carrier, info)
|
| 114 |
+
reconst = info + carrier
|
| 115 |
+
else:
|
| 116 |
+
reconst = torch.abs(info + carrier)
|
| 117 |
+
|
| 118 |
+
self.stft.num_samples = x.shape[2]
|
| 119 |
+
out = self.stft.inverse(reconst.squeeze(1), phase.squeeze(1)).data.cpu().numpy()[0, 0]
|
| 120 |
+
out = out * np.sqrt(power / self.reference_energy)
|
| 121 |
+
return np.ascontiguousarray(out[: y.size], dtype=np.float32)
|
| 122 |
+
|
| 123 |
+
|
| 124 |
+
_CACHE = {}
|
| 125 |
+
|
| 126 |
+
|
| 127 |
+
def get_post_filter(device="cpu"):
|
| 128 |
+
if device not in _CACHE:
|
| 129 |
+
_CACHE[device] = PostFilter(device=device)
|
| 130 |
+
return _CACHE[device]
|
codec/audio_processing/_postfilter/__pycache__/__init__.cpython-311.pyc
ADDED
|
Binary file (9.69 kB). View file
|
|
|
codec/audio_processing/_postfilter/__pycache__/nets.cpython-311.pyc
ADDED
|
Binary file (5.66 kB). View file
|
|
|
codec/audio_processing/_postfilter/__pycache__/stft.cpython-311.pyc
ADDED
|
Binary file (3.94 kB). View file
|
|
|
codec/audio_processing/_postfilter/assets/dec_c.ckpt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:c23b57635172b2fbd3a8531d15ba76b5885a10d0fe902ccb823c521c56041b33
|
| 3 |
+
size 2008794
|
codec/audio_processing/_postfilter/assets/enc_c.ckpt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:ff64f80d2391fdfc888e4103c499be4a2c958e59626587a1eab6db93204814c7
|
| 3 |
+
size 184765
|
codec/audio_processing/_postfilter/assets/hparams.yaml
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
AUDIO_LEN: 12
|
| 2 |
+
A_weighting: false
|
| 3 |
+
HOP_LENGTH: 2048
|
| 4 |
+
NMR: 0.0
|
| 5 |
+
N_FFT: 4096
|
| 6 |
+
SR: 44100
|
| 7 |
+
TEMP_PATH: /group/project25/Mayank/Models/HideAndSpeak/high_sr_model_40dB/temp_files/
|
| 8 |
+
TEST_AUDIO_LEN: 12
|
| 9 |
+
aac_aug: 64k,128k,256k
|
| 10 |
+
add_carrier_noise: gaussian
|
| 11 |
+
adv: false
|
| 12 |
+
batch_size: 2
|
| 13 |
+
carrier_detach: -1
|
| 14 |
+
carrier_noise_norm: 0.01
|
| 15 |
+
cdpam_metric: false
|
| 16 |
+
curriculum: 0
|
| 17 |
+
dataloader_length: 261
|
| 18 |
+
dataset: vctk
|
| 19 |
+
dataset_based_SDR: false
|
| 20 |
+
dec_c_n_layers: 4
|
| 21 |
+
decoder_access_source: false
|
| 22 |
+
enc_n_layers: 3
|
| 23 |
+
encoder_decide_SDR: false
|
| 24 |
+
ensure_constrained_message: false
|
| 25 |
+
ensure_negative_message: true
|
| 26 |
+
frame_level_normalization: false
|
| 27 |
+
lambda_carrier_loss: 20.0
|
| 28 |
+
lambda_msg_loss: 20.0
|
| 29 |
+
load_ckpt: /group/project25/Mayank/Models/HideAndSpeak/high_sr_model_40dB/ckpt/139058_iteration
|
| 30 |
+
loss_type: mse
|
| 31 |
+
lr: 0.001
|
| 32 |
+
mel_loss: 0
|
| 33 |
+
message_band_size: 1024
|
| 34 |
+
message_dim: 5
|
| 35 |
+
message_len: 21
|
| 36 |
+
message_sdr: 47
|
| 37 |
+
microphoneEQ: false
|
| 38 |
+
mix_train: false
|
| 39 |
+
mode: train
|
| 40 |
+
model_type: n_msg
|
| 41 |
+
mp3_aug: 64k,128k,256k
|
| 42 |
+
msg_loss_weighting_with_energy: false
|
| 43 |
+
n_messages: 1
|
| 44 |
+
no_normalization: false
|
| 45 |
+
num_iters: 5
|
| 46 |
+
num_workers: 8
|
| 47 |
+
ogg_aug: 64k,128k,256k
|
| 48 |
+
opt: adam
|
| 49 |
+
otat: false
|
| 50 |
+
phase_shift: null
|
| 51 |
+
remove_heuristic_message: false
|
| 52 |
+
rir: /group/project25/Mayank/RIR/rir_small.wav.npz
|
| 53 |
+
rir_train: false
|
| 54 |
+
run_dir: /group/project25/Mayank/Models/HideAndSpeak/high_sr_model_40dB
|
| 55 |
+
sample_every: null
|
| 56 |
+
save_model_every: null
|
| 57 |
+
seed: 121
|
| 58 |
+
stft: new_stft
|
| 59 |
+
test_path: Data/test.txt
|
| 60 |
+
test_results_path: Results/results
|
| 61 |
+
train_path: Data/train.txt
|
| 62 |
+
utterance_level_normalization: true
|
| 63 |
+
val_path: null
|
codec/audio_processing/_postfilter/nets.py
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Spectral post-filter networks.
|
| 2 |
+
|
| 3 |
+
Derived from MIT-licensed work, Copyright (c) 2024 Sony Research Inc.
|
| 4 |
+
Only the analysis/synthesis path is retained here.
|
| 5 |
+
"""
|
| 6 |
+
|
| 7 |
+
import torch
|
| 8 |
+
import torch.nn as nn
|
| 9 |
+
import numpy as np
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
class Layer(nn.Module):
|
| 13 |
+
def __init__(self, dim_in, dim_out, kernel_size, stride, padding):
|
| 14 |
+
super(Layer, self).__init__()
|
| 15 |
+
self.conv = nn.Conv2d(dim_in, dim_out, kernel_size=kernel_size, stride=stride, padding=padding, bias=True)
|
| 16 |
+
self.gate = nn.Conv2d(dim_in, dim_out, kernel_size=kernel_size, stride=stride, padding=padding, bias=True)
|
| 17 |
+
self.bn = nn.BatchNorm2d(dim_out)
|
| 18 |
+
|
| 19 |
+
def forward(self, x):
|
| 20 |
+
return self.bn(self.conv(x) * torch.sigmoid(self.gate(x)))
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
class Encoder(nn.Module):
|
| 24 |
+
def __init__(self, out_dim=32, n_layers=3, message_dim=0, message_band_size=None, n_fft=None):
|
| 25 |
+
super(Encoder, self).__init__()
|
| 26 |
+
assert message_band_size is not None
|
| 27 |
+
assert n_fft is not None
|
| 28 |
+
self.message_band_size = message_band_size
|
| 29 |
+
main = [Layer(dim_in=1, dim_out=32, kernel_size=3, stride=1, padding=1)]
|
| 30 |
+
|
| 31 |
+
for i in range(n_layers-2):
|
| 32 |
+
main.append(Layer(dim_in=32, dim_out=32, kernel_size=3, stride=1, padding=1))
|
| 33 |
+
main.append(Layer(dim_in=32, dim_out=out_dim, kernel_size=3, stride=1, padding=1))
|
| 34 |
+
|
| 35 |
+
self.main = nn.Sequential(*main)
|
| 36 |
+
self.linear = nn.Linear(message_dim, message_band_size)
|
| 37 |
+
self.n_fft = n_fft
|
| 38 |
+
|
| 39 |
+
def forward(self, x):
|
| 40 |
+
h = self.main(x)
|
| 41 |
+
return h
|
| 42 |
+
|
| 43 |
+
def transform_message(self, msg):
|
| 44 |
+
output = self.linear(msg.transpose(2, 3)).transpose(2, 3)
|
| 45 |
+
if self.message_band_size != self.n_fft // 2 + 1:
|
| 46 |
+
output = torch.nn.functional.pad(output, (0, 0, 0, self.n_fft // 2 + 1 - self.message_band_size))
|
| 47 |
+
return output
|
| 48 |
+
|
| 49 |
+
|
| 50 |
+
class CarrierDecoder(nn.Module):
|
| 51 |
+
def __init__(self, config, conv_dim, n_layers=4, message_band_size=1024):
|
| 52 |
+
super(CarrierDecoder, self).__init__()
|
| 53 |
+
self.config = config
|
| 54 |
+
self.message_band_size = message_band_size
|
| 55 |
+
layers = [Layer(dim_in=conv_dim, dim_out=96, kernel_size=3, stride=1, padding=1)]
|
| 56 |
+
|
| 57 |
+
for i in range(n_layers-2):
|
| 58 |
+
layers.append(Layer(dim_in=96, dim_out=96, kernel_size=3, stride=1, padding=1))
|
| 59 |
+
|
| 60 |
+
layers.append(Layer(dim_in=96, dim_out=1, kernel_size=1, stride=1, padding=0))
|
| 61 |
+
|
| 62 |
+
self.main = nn.Sequential(*layers)
|
| 63 |
+
|
| 64 |
+
def forward(self, x, message_sdr):
|
| 65 |
+
h = self.main(x)
|
| 66 |
+
|
| 67 |
+
if self.config.ensure_negative_message:
|
| 68 |
+
h = torch.abs(h)
|
| 69 |
+
|
| 70 |
+
h[:, :, self.message_band_size:, :] = 0
|
| 71 |
+
|
| 72 |
+
if not self.config.no_normalization:
|
| 73 |
+
h = h / torch.mean(h**2, dim=2, keepdim=True)**0.5 / (10**(message_sdr/20))
|
| 74 |
+
|
| 75 |
+
return h
|
codec/audio_processing/_postfilter/stft.py
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import torch
|
| 2 |
+
|
| 3 |
+
class Singleton(type):
|
| 4 |
+
_instances = {}
|
| 5 |
+
def __call__(cls, *args, **kwargs):
|
| 6 |
+
if cls not in cls._instances:
|
| 7 |
+
cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
|
| 8 |
+
return cls._instances[cls]
|
| 9 |
+
|
| 10 |
+
class STFT(torch.nn.Module, metaclass=Singleton):
|
| 11 |
+
def __init__(self, filter_length=1024, hop_length=512):
|
| 12 |
+
super(STFT, self).__init__()
|
| 13 |
+
|
| 14 |
+
self.filter_length = filter_length
|
| 15 |
+
self.hop_len = hop_length
|
| 16 |
+
self.win_len = filter_length
|
| 17 |
+
self.window = torch.hann_window(self.win_len)
|
| 18 |
+
self.num_samples = -1
|
| 19 |
+
|
| 20 |
+
def transform(self, x):
|
| 21 |
+
x = torch.nn.functional.pad(x, (0, self.win_len - x.shape[1]%self.win_len))
|
| 22 |
+
fft = torch.stft(x, self.filter_length, self.hop_len, self.win_len, window=self.window.to(x.device), return_complex=True)
|
| 23 |
+
|
| 24 |
+
real_part, imag_part = fft.real, fft.imag
|
| 25 |
+
|
| 26 |
+
squared = real_part**2 + imag_part**2
|
| 27 |
+
additive_epsilon = torch.ones_like(squared) * (squared == 0).float() * 1e-24
|
| 28 |
+
magnitude = torch.sqrt(squared + additive_epsilon) - torch.sqrt(additive_epsilon)
|
| 29 |
+
|
| 30 |
+
phase = torch.autograd.Variable(torch.atan2(imag_part.data, real_part.data)).float()
|
| 31 |
+
return magnitude, phase
|
| 32 |
+
|
| 33 |
+
def inverse(self, magnitude, phase):
|
| 34 |
+
|
| 35 |
+
recombine_magnitude_phase = magnitude*torch.cos(phase) + 1j*magnitude*torch.sin(phase)
|
| 36 |
+
inverse_transform = torch.istft(recombine_magnitude_phase, self.filter_length, hop_length=self.hop_len, win_length=self.win_len, window=self.window.to(magnitude.device)).unsqueeze(1) # , length=self.num_samples
|
| 37 |
+
padding = self.win_len - (self.num_samples % self.win_len)
|
| 38 |
+
inverse_transform = inverse_transform[:, :, :-padding]
|
| 39 |
+
return inverse_transform
|
| 40 |
+
|