Concatenate segments with linear crossfade. Args: segments: list of (1, T) tensors sample_rate: sampling rate crossfade_seconds: overlap time for crossfade Returns: (1, T_total) tensor
(
segments: list, sample_rate: int, crossfade_seconds: float = 0.1
)
| 40 | |
| 41 | |
| 42 | def crossfade_concat( |
| 43 | segments: list, sample_rate: int, crossfade_seconds: float = 0.1 |
| 44 | ) -> torch.Tensor: |
| 45 | """Concatenate segments with linear crossfade. |
| 46 | |
| 47 | Args: |
| 48 | segments: list of (1, T) tensors |
| 49 | sample_rate: sampling rate |
| 50 | crossfade_seconds: overlap time for crossfade |
| 51 | Returns: |
| 52 | (1, T_total) tensor |
| 53 | """ |
| 54 | if len(segments) == 0: |
| 55 | return torch.zeros(1, 0) |
| 56 | if len(segments) == 1: |
| 57 | return segments[0] |
| 58 | out = segments[0] |
| 59 | cf_len_target = int(round(crossfade_seconds * sample_rate)) |
| 60 | for k in range(1, len(segments)): |
| 61 | nxt = segments[k] |
| 62 | if cf_len_target <= 0: |
| 63 | out = torch.cat([out, nxt], dim=-1) |
| 64 | continue |
| 65 | cf_len = min(cf_len_target, out.shape[-1], nxt.shape[-1]) |
| 66 | if cf_len <= 0: |
| 67 | out = torch.cat([out, nxt], dim=-1) |
| 68 | continue |
| 69 | fade_out = torch.linspace( |
| 70 | 1.0, 0.0, steps=cf_len, dtype=out.dtype, device=out.device |
| 71 | ) |
| 72 | fade_in = torch.linspace( |
| 73 | 0.0, 1.0, steps=cf_len, dtype=nxt.dtype, device=nxt.device |
| 74 | ) |
| 75 | overlap = out[0, -cf_len:] * fade_out + nxt[0, :cf_len] * fade_in |
| 76 | out = torch.cat( |
| 77 | [out[:, :-cf_len], overlap.unsqueeze(0), nxt[:, cf_len:]], dim=-1 |
| 78 | ) |
| 79 | return out |
| 80 | |
| 81 | |
| 82 | def load_model( |