facebookresearch--audiocraft
1178 行
54 KiB
HTML
1178 行
54 KiB
HTML
<!doctype html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
|
||
<meta name="generator" content="pdoc3 0.11.5">
|
||
<title>audiocraft.utils.audio_effects API documentation</title>
|
||
<meta name="description" content="">
|
||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
|
||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/typography.min.css" integrity="sha512-Y1DYSb995BAfxobCkKepB1BqJJTPrOp3zPL74AWFugHHmmdcvO+C48WLrUOlhGMc0QG7AE3f7gmvvcrmX2fDoA==" crossorigin>
|
||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css" crossorigin>
|
||
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:1.5em;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:2em 0 .50em 0}h3{font-size:1.4em;margin:1.6em 0 .7em 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .2s ease-in-out}a:visited{color:#503}a:hover{color:#b62}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900;font-weight:bold}pre code{font-size:.8em;line-height:1.4em;padding:1em;display:block}code{background:#f3f3f3;font-family:"DejaVu Sans Mono",monospace;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source > summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible;min-width:max-content}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em 1em;margin:1em 0}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
|
||
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul ul{padding-left:1em}.toc > ul > li{margin-top:.5em}}</style>
|
||
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
|
||
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js" integrity="sha512-D9gUyxqja7hBtkWpPWGt9wfbfaMGVt9gnyCvYa+jojwwPHLCzUm5i8rpk7vD7wNee9bA35eYIjobYPaQuKS1MQ==" crossorigin></script>
|
||
<script>window.addEventListener('DOMContentLoaded', () => {
|
||
hljs.configure({languages: ['bash', 'css', 'diff', 'graphql', 'ini', 'javascript', 'json', 'plaintext', 'python', 'python-repl', 'rust', 'shell', 'sql', 'typescript', 'xml', 'yaml']});
|
||
hljs.highlightAll();
|
||
/* Collapse source docstrings */
|
||
setTimeout(() => {
|
||
[...document.querySelectorAll('.hljs.language-python > .hljs-string')]
|
||
.filter(el => el.innerHTML.length > 200 && ['"""', "'''"].includes(el.innerHTML.substring(0, 3)))
|
||
.forEach(el => {
|
||
let d = document.createElement('details');
|
||
d.classList.add('hljs-string');
|
||
d.innerHTML = '<summary>"""</summary>' + el.innerHTML.substring(3);
|
||
el.replaceWith(d);
|
||
});
|
||
}, 100);
|
||
})</script>
|
||
</head>
|
||
<body>
|
||
<main>
|
||
<article id="content">
|
||
<header>
|
||
<h1 class="title">Module <code>audiocraft.utils.audio_effects</code></h1>
|
||
</header>
|
||
<section id="section-intro">
|
||
</section>
|
||
<section>
|
||
</section>
|
||
<section>
|
||
</section>
|
||
<section>
|
||
<h2 class="section-title" id="header-functions">Functions</h2>
|
||
<dl>
|
||
<dt id="audiocraft.utils.audio_effects.apply_compression_skip_grad"><code class="name flex">
|
||
<span>def <span class="ident">apply_compression_skip_grad</span></span>(<span>tensor: torch.Tensor, compression_fn, **kwargs)</span>
|
||
</code></dt>
|
||
<dd>
|
||
<details class="source">
|
||
<summary>
|
||
<span>Expand source code</span>
|
||
</summary>
|
||
<pre><code class="python">def apply_compression_skip_grad(tensor: torch.Tensor, compression_fn, **kwargs):
|
||
"""Applies a specified compression function to the audio tensor.
|
||
Whire carrying over the grads to the output tensor with skip through estimator
|
||
this is a straight through estimator to make mp3/aac compression differentiable
|
||
see more: Yin et al. 2019 https://arxiv.org/pdf/1903.05662.pdf
|
||
|
||
Args:
|
||
tensor (torch.Tensor): The input audio tensor.
|
||
compression_fn (function): The compression function to apply.
|
||
**kwargs: Additional keyword arguments for the compression function.
|
||
|
||
Returns:
|
||
torch.Tensor: The output tensor after applying compression and straight through estimator.
|
||
"""
|
||
compressed = compression_fn(tensor.detach(), **kwargs)
|
||
|
||
# Trim compressed output if needed
|
||
compressed = compressed[:, :, : tensor.size(-1)]
|
||
|
||
# Straight through estimator for differentiable compression
|
||
out = tensor + (compressed - tensor).detach()
|
||
|
||
# Check that gradients are not broken
|
||
if out.requires_grad:
|
||
assert (
|
||
out.grad_fn
|
||
), "The computation graph might be broken due to compression augmentation."
|
||
|
||
return out</code></pre>
|
||
</details>
|
||
<div class="desc"><p>Applies a specified compression function to the audio tensor.
|
||
Whire carrying over the grads to the output tensor with skip through estimator
|
||
this is a straight through estimator to make mp3/aac compression differentiable
|
||
see more: Yin et al. 2019 <a href="https://arxiv.org/pdf/1903.05662.pdf">https://arxiv.org/pdf/1903.05662.pdf</a></p>
|
||
<h2 id="args">Args</h2>
|
||
<dl>
|
||
<dt><strong><code>tensor</code></strong> : <code>torch.Tensor</code></dt>
|
||
<dd>The input audio tensor.</dd>
|
||
<dt><strong><code>compression_fn</code></strong> : <code>function</code></dt>
|
||
<dd>The compression function to apply.</dd>
|
||
<dt><strong><code>**kwargs</code></strong></dt>
|
||
<dd>Additional keyword arguments for the compression function.</dd>
|
||
</dl>
|
||
<h2 id="returns">Returns</h2>
|
||
<dl>
|
||
<dt><code>torch.Tensor</code></dt>
|
||
<dd>The output tensor after applying compression and straight through estimator.</dd>
|
||
</dl></div>
|
||
</dd>
|
||
<dt id="audiocraft.utils.audio_effects.audio_effect_return"><code class="name flex">
|
||
<span>def <span class="ident">audio_effect_return</span></span>(<span>tensor: torch.Tensor, mask: torch.Tensor | None) ‑> torch.Tensor | Tuple[torch.Tensor, torch.Tensor]</span>
|
||
</code></dt>
|
||
<dd>
|
||
<details class="source">
|
||
<summary>
|
||
<span>Expand source code</span>
|
||
</summary>
|
||
<pre><code class="python">def audio_effect_return(
|
||
tensor: torch.Tensor, mask: tp.Optional[torch.Tensor]
|
||
) -> tp.Union[tp.Tuple[torch.Tensor, torch.Tensor], torch.Tensor]:
|
||
"""Return the mask if it was in the input otherwise only the output tensor"""
|
||
if mask is None:
|
||
return tensor
|
||
else:
|
||
return tensor, mask</code></pre>
|
||
</details>
|
||
<div class="desc"><p>Return the mask if it was in the input otherwise only the output tensor</p></div>
|
||
</dd>
|
||
<dt id="audiocraft.utils.audio_effects.compress_with_encodec"><code class="name flex">
|
||
<span>def <span class="ident">compress_with_encodec</span></span>(<span>tensor: torch.Tensor,<br>n_q: int,<br>model: CompressionModel,<br>sample_rate: int,<br>mask: torch.Tensor | None = None) ‑> torch.Tensor | Tuple[torch.Tensor, torch.Tensor]</span>
|
||
</code></dt>
|
||
<dd>
|
||
<details class="source">
|
||
<summary>
|
||
<span>Expand source code</span>
|
||
</summary>
|
||
<pre><code class="python">def compress_with_encodec(
|
||
tensor: torch.Tensor,
|
||
n_q: int,
|
||
model: "CompressionModel",
|
||
sample_rate: int,
|
||
mask: tp.Optional[torch.Tensor] = None,
|
||
) -> tp.Union[tp.Tuple[torch.Tensor, torch.Tensor], torch.Tensor]:
|
||
"""Special augmentation function that compresses and decompresses wav tensor
|
||
using a compression model with the n_q codebooks
|
||
"""
|
||
|
||
model.to(tensor.device)
|
||
model.set_num_codebooks(n_q)
|
||
codes, scale = model.encode(
|
||
julius.resample_frac(tensor, old_sr=sample_rate, new_sr=model.sample_rate)
|
||
)
|
||
compressed = model.decode(codes=codes, scale=scale)
|
||
return audio_effect_return(
|
||
tensor=julius.resample_frac(
|
||
compressed, old_sr=model.sample_rate, new_sr=sample_rate
|
||
),
|
||
mask=mask,
|
||
)</code></pre>
|
||
</details>
|
||
<div class="desc"><p>Special augmentation function that compresses and decompresses wav tensor
|
||
using a compression model with the n_q codebooks</p></div>
|
||
</dd>
|
||
<dt id="audiocraft.utils.audio_effects.generate_pink_noise"><code class="name flex">
|
||
<span>def <span class="ident">generate_pink_noise</span></span>(<span>length: int) ‑> torch.Tensor</span>
|
||
</code></dt>
|
||
<dd>
|
||
<details class="source">
|
||
<summary>
|
||
<span>Expand source code</span>
|
||
</summary>
|
||
<pre><code class="python">def generate_pink_noise(length: int) -> torch.Tensor:
|
||
"""Generate pink noise using Voss-McCartney algorithm with PyTorch."""
|
||
num_rows = 16
|
||
array = torch.randn(num_rows, length // num_rows + 1)
|
||
reshaped_array = torch.cumsum(array, dim=1)
|
||
reshaped_array = reshaped_array.reshape(-1)
|
||
reshaped_array = reshaped_array[:length]
|
||
# Normalize
|
||
pink_noise = reshaped_array / torch.max(torch.abs(reshaped_array))
|
||
return pink_noise</code></pre>
|
||
</details>
|
||
<div class="desc"><p>Generate pink noise using Voss-McCartney algorithm with PyTorch.</p></div>
|
||
</dd>
|
||
<dt id="audiocraft.utils.audio_effects.get_audio_effects"><code class="name flex">
|
||
<span>def <span class="ident">get_audio_effects</span></span>(<span>cfg: omegaconf.dictconfig.DictConfig)</span>
|
||
</code></dt>
|
||
<dd>
|
||
<details class="source">
|
||
<summary>
|
||
<span>Expand source code</span>
|
||
</summary>
|
||
<pre><code class="python">def get_audio_effects(cfg: omegaconf.DictConfig):
|
||
"""Automatically pull the list all effects available in this class based on the parameters from the cfg
|
||
|
||
Returns:
|
||
dict: A dict of names and pointers to all methods in this class.
|
||
"""
|
||
assert hasattr(cfg, "audio_effects")
|
||
cfg_audio_effects = dict(cfg["audio_effects"])
|
||
return {
|
||
name: partial(value, **cfg_audio_effects.get(name, {}))
|
||
for name, value in inspect.getmembers(AudioEffects)
|
||
if inspect.isfunction(value)
|
||
}</code></pre>
|
||
</details>
|
||
<div class="desc"><p>Automatically pull the list all effects available in this class based on the parameters from the cfg</p>
|
||
<h2 id="returns">Returns</h2>
|
||
<dl>
|
||
<dt><code>dict</code></dt>
|
||
<dd>A dict of names and pointers to all methods in this class.</dd>
|
||
</dl></div>
|
||
</dd>
|
||
<dt id="audiocraft.utils.audio_effects.select_audio_effects"><code class="name flex">
|
||
<span>def <span class="ident">select_audio_effects</span></span>(<span>audio_effects: Dict,<br>weights: Dict | None = None,<br>mode: str = 'all',<br>max_length: int | None = None)</span>
|
||
</code></dt>
|
||
<dd>
|
||
<details class="source">
|
||
<summary>
|
||
<span>Expand source code</span>
|
||
</summary>
|
||
<pre><code class="python">def select_audio_effects(
|
||
audio_effects: tp.Dict,
|
||
weights: tp.Optional[tp.Dict] = None,
|
||
mode: str = "all",
|
||
max_length: tp.Optional[int] = None,
|
||
):
|
||
"""Samples a subset of audio effects methods from the `AudioEffects` class.
|
||
|
||
This function allows you to select a subset of audio effects
|
||
based on the chosen selection mode and optional weights.
|
||
|
||
Args:
|
||
audio_effects (dict): A dictionary of available audio augmentations, usually
|
||
obtained from the output of the 'get_audio_effects' function.
|
||
weights (dict): A dictionary mapping augmentation names to their corresponding
|
||
probabilities of being selected. This argument is used when 'mode' is set
|
||
to "weighted." If 'weights' is None, all augmentations have equal
|
||
probability of being selected.
|
||
mode (str): The selection mode, which can be one of the following:
|
||
- "all": Select all available augmentations.
|
||
- "weighted": Select augmentations based on their probabilities in the
|
||
'weights' dictionary.
|
||
max_length (int): The maximum number of augmentations to select. If 'max_length'
|
||
is None, no limit is applied.
|
||
|
||
Returns:
|
||
dict: A subset of the 'audio_effects' dictionary containing the selected audio
|
||
augmentations.
|
||
|
||
Note:
|
||
- In "all" mode, all available augmentations are selected.
|
||
- In "weighted" mode, augmentations are selected with a probability
|
||
proportional to their weights specified in the 'weights' dictionary.
|
||
- If 'max_length' is set, the function limits the number of selected
|
||
augmentations.
|
||
- If no augmentations are selected or 'audio_effects' is empty, the function
|
||
defaults to including an "identity" augmentation.
|
||
- The "identity" augmentation means that no audio effect is applied.
|
||
"""
|
||
if mode == "all": # original code
|
||
out = audio_effects
|
||
elif mode == "weighted":
|
||
# Probability proportionnal to weights
|
||
assert weights is not None
|
||
out = {
|
||
name: value
|
||
for name, value in audio_effects.items()
|
||
if random.random() < weights.get(name, 1.0)
|
||
}
|
||
else:
|
||
raise ValueError(f"Unknown mode {mode}")
|
||
if max_length is not None:
|
||
# Help having a deterministic limit of the gpu memory usage
|
||
random_keys = random.sample(list(out.keys()), max_length)
|
||
out = {key: out[key] for key in random_keys}
|
||
if len(out) == 0: # Check not to return empty dict
|
||
out = {"identity": AudioEffects.identity}
|
||
return out</code></pre>
|
||
</details>
|
||
<div class="desc"><p>Samples a subset of audio effects methods from the <code><a title="audiocraft.utils.audio_effects.AudioEffects" href="#audiocraft.utils.audio_effects.AudioEffects">AudioEffects</a></code> class.</p>
|
||
<p>This function allows you to select a subset of audio effects
|
||
based on the chosen selection mode and optional weights.</p>
|
||
<h2 id="args">Args</h2>
|
||
<dl>
|
||
<dt><strong><code>audio_effects</code></strong> : <code>dict</code></dt>
|
||
<dd>A dictionary of available audio augmentations, usually
|
||
obtained from the output of the 'get_audio_effects' function.</dd>
|
||
<dt><strong><code>weights</code></strong> : <code>dict</code></dt>
|
||
<dd>A dictionary mapping augmentation names to their corresponding
|
||
probabilities of being selected. This argument is used when 'mode' is set
|
||
to "weighted." If 'weights' is None, all augmentations have equal
|
||
probability of being selected.</dd>
|
||
<dt><strong><code>mode</code></strong> : <code>str</code></dt>
|
||
<dd>The selection mode, which can be one of the following:
|
||
- "all": Select all available augmentations.
|
||
- "weighted": Select augmentations based on their probabilities in the
|
||
'weights' dictionary.</dd>
|
||
<dt><strong><code>max_length</code></strong> : <code>int</code></dt>
|
||
<dd>The maximum number of augmentations to select. If 'max_length'
|
||
is None, no limit is applied.</dd>
|
||
</dl>
|
||
<h2 id="returns">Returns</h2>
|
||
<dl>
|
||
<dt><code>dict</code></dt>
|
||
<dd>A subset of the 'audio_effects' dictionary containing the selected audio</dd>
|
||
</dl>
|
||
<p>augmentations.</p>
|
||
<h2 id="note">Note</h2>
|
||
<ul>
|
||
<li>In "all" mode, all available augmentations are selected.</li>
|
||
<li>In "weighted" mode, augmentations are selected with a probability
|
||
proportional to their weights specified in the 'weights' dictionary.</li>
|
||
<li>If 'max_length' is set, the function limits the number of selected
|
||
augmentations.</li>
|
||
<li>If no augmentations are selected or 'audio_effects' is empty, the function
|
||
defaults to including an "identity" augmentation.</li>
|
||
<li>The "identity" augmentation means that no audio effect is applied.</li>
|
||
</ul></div>
|
||
</dd>
|
||
</dl>
|
||
</section>
|
||
<section>
|
||
<h2 class="section-title" id="header-classes">Classes</h2>
|
||
<dl>
|
||
<dt id="audiocraft.utils.audio_effects.AudioEffects"><code class="flex name class">
|
||
<span>class <span class="ident">AudioEffects</span></span>
|
||
</code></dt>
|
||
<dd>
|
||
<details class="source">
|
||
<summary>
|
||
<span>Expand source code</span>
|
||
</summary>
|
||
<pre><code class="python">class AudioEffects:
|
||
@staticmethod
|
||
def speed(
|
||
tensor: torch.Tensor,
|
||
speed_range: tuple = (0.5, 1.5),
|
||
sample_rate: int = 16000,
|
||
mask: tp.Optional[torch.Tensor] = None,
|
||
) -> tp.Union[tp.Tuple[torch.Tensor, torch.Tensor], torch.Tensor]:
|
||
"""Function to change the speed of a batch of audio data.
|
||
The output will have a different length !
|
||
|
||
Args:
|
||
audio_batch (torch.Tensor): The batch of audio data in torch tensor format.
|
||
speed (float): The speed to change the audio to.
|
||
|
||
Returns:
|
||
torch.Tensor: The batch of audio data with the speed changed.
|
||
"""
|
||
speed = torch.FloatTensor(1).uniform_(*speed_range)
|
||
new_sr = int(sample_rate * 1 / speed)
|
||
resampled_tensor = julius.resample.resample_frac(tensor, sample_rate, new_sr)
|
||
if mask is None:
|
||
return resampled_tensor
|
||
else:
|
||
return resampled_tensor, torch.nn.functional.interpolate(
|
||
mask, size=resampled_tensor.size(-1), mode="nearest-exact"
|
||
)
|
||
|
||
@staticmethod
|
||
def updownresample(
|
||
tensor: torch.Tensor,
|
||
sample_rate: int = 16000,
|
||
intermediate_freq: int = 32000,
|
||
mask: tp.Optional[torch.Tensor] = None,
|
||
) -> tp.Union[tp.Tuple[torch.Tensor, torch.Tensor], torch.Tensor]:
|
||
|
||
orig_shape = tensor.shape
|
||
# upsample
|
||
tensor = resample_frac(tensor, sample_rate, intermediate_freq)
|
||
# downsample
|
||
tensor = resample_frac(tensor, intermediate_freq, sample_rate)
|
||
|
||
assert tensor.shape == orig_shape
|
||
return audio_effect_return(tensor=tensor, mask=mask)
|
||
|
||
@staticmethod
|
||
def echo(
|
||
tensor: torch.Tensor,
|
||
volume_range: tuple = (0.1, 0.5),
|
||
duration_range: tuple = (0.1, 0.5),
|
||
sample_rate: int = 16000,
|
||
mask: tp.Optional[torch.Tensor] = None,
|
||
) -> tp.Union[tp.Tuple[torch.Tensor, torch.Tensor], torch.Tensor]:
|
||
"""Attenuating the audio volume by a factor of 0.4, delaying it by 100ms,
|
||
and then overlaying it with the original.
|
||
|
||
Args:
|
||
tensor: 3D Tensor representing the audio signal [bsz, channels, frames]
|
||
volumne range: volume range of the echo signal
|
||
duration range: duration range of the echo signal
|
||
sample_rate: Sample rate of the audio signal.
|
||
Returns:
|
||
Audio signal with reverb.
|
||
"""
|
||
|
||
# Create a simple impulse response
|
||
# Duration of the impulse response in seconds
|
||
duration = torch.FloatTensor(1).uniform_(*duration_range)
|
||
volume = torch.FloatTensor(1).uniform_(*volume_range)
|
||
|
||
n_samples = int(sample_rate * duration)
|
||
impulse_response = torch.zeros(n_samples).type(tensor.type()).to(tensor.device)
|
||
|
||
# Define a few reflections with decreasing amplitude
|
||
impulse_response[0] = 1.0 # Direct sound
|
||
|
||
impulse_response[
|
||
int(sample_rate * duration) - 1
|
||
] = volume # First reflection after 100ms
|
||
|
||
# Add batch and channel dimensions to the impulse response
|
||
impulse_response = impulse_response.unsqueeze(0).unsqueeze(0)
|
||
|
||
# Convolve the audio signal with the impulse response
|
||
reverbed_signal = fft_conv1d(tensor, impulse_response)
|
||
|
||
# Normalize to the original amplitude range for stability
|
||
reverbed_signal = (
|
||
reverbed_signal
|
||
/ torch.max(torch.abs(reverbed_signal))
|
||
* torch.max(torch.abs(tensor))
|
||
)
|
||
|
||
# Ensure tensor size is not changed
|
||
tmp = torch.zeros_like(tensor)
|
||
tmp[..., : reverbed_signal.shape[-1]] = reverbed_signal
|
||
reverbed_signal = tmp
|
||
|
||
return audio_effect_return(tensor=reverbed_signal, mask=mask)
|
||
|
||
@staticmethod
|
||
def random_noise(
|
||
waveform: torch.Tensor,
|
||
noise_std: float = 0.001,
|
||
mask: tp.Optional[torch.Tensor] = None,
|
||
) -> tp.Union[tp.Tuple[torch.Tensor, torch.Tensor], torch.Tensor]:
|
||
"""Add Gaussian noise to the waveform."""
|
||
noise = torch.randn_like(waveform) * noise_std
|
||
noisy_waveform = waveform + noise
|
||
return audio_effect_return(tensor=noisy_waveform, mask=mask)
|
||
|
||
@staticmethod
|
||
def pink_noise(
|
||
waveform: torch.Tensor,
|
||
noise_std: float = 0.01,
|
||
mask: tp.Optional[torch.Tensor] = None,
|
||
) -> tp.Union[tp.Tuple[torch.Tensor, torch.Tensor], torch.Tensor]:
|
||
"""Add pink background noise to the waveform."""
|
||
noise = generate_pink_noise(waveform.shape[-1]) * noise_std
|
||
noise = noise.to(waveform.device)
|
||
# Assuming waveform is of shape (bsz, channels, length)
|
||
noisy_waveform = waveform + noise.unsqueeze(0).unsqueeze(0).to(waveform.device)
|
||
return audio_effect_return(tensor=noisy_waveform, mask=mask)
|
||
|
||
@staticmethod
|
||
def lowpass_filter(
|
||
waveform: torch.Tensor,
|
||
cutoff_freq: float = 5000,
|
||
sample_rate: int = 16000,
|
||
mask: tp.Optional[torch.Tensor] = None,
|
||
) -> tp.Union[tp.Tuple[torch.Tensor, torch.Tensor], torch.Tensor]:
|
||
"""Filter the lowpass frequency from the waveform"""
|
||
return audio_effect_return(
|
||
tensor=julius.lowpass_filter(waveform, cutoff=cutoff_freq / sample_rate),
|
||
mask=mask,
|
||
)
|
||
|
||
@staticmethod
|
||
def highpass_filter(
|
||
waveform: torch.Tensor,
|
||
cutoff_freq: float = 500,
|
||
sample_rate: int = 16000,
|
||
mask: tp.Optional[torch.Tensor] = None,
|
||
) -> tp.Union[tp.Tuple[torch.Tensor, torch.Tensor], torch.Tensor]:
|
||
"""Filter the highpass frequency from the waveform"""
|
||
return audio_effect_return(
|
||
tensor=julius.highpass_filter(waveform, cutoff=cutoff_freq / sample_rate),
|
||
mask=mask,
|
||
)
|
||
|
||
@staticmethod
|
||
def bandpass_filter(
|
||
waveform: torch.Tensor,
|
||
cutoff_freq_low: float = 300,
|
||
cutoff_freq_high: float = 8000,
|
||
sample_rate: int = 16000,
|
||
mask: tp.Optional[torch.Tensor] = None,
|
||
) -> tp.Union[tp.Tuple[torch.Tensor, torch.Tensor], torch.Tensor]:
|
||
"""Apply a bandpass filter to the waveform by cascading
|
||
a high-pass filter followed by a low-pass filter.
|
||
|
||
Args:
|
||
waveform (torch.Tensor): Input audio waveform.
|
||
low_cutoff (float): Lower cutoff frequency.
|
||
high_cutoff (float): Higher cutoff frequency.
|
||
sample_rate (int): The sample rate of the waveform.
|
||
|
||
Returns:
|
||
torch.Tensor: Filtered audio waveform.
|
||
"""
|
||
|
||
return audio_effect_return(
|
||
tensor=julius.bandpass_filter(
|
||
waveform,
|
||
cutoff_low=cutoff_freq_low / sample_rate,
|
||
cutoff_high=cutoff_freq_high / sample_rate,
|
||
),
|
||
mask=mask,
|
||
)
|
||
|
||
@staticmethod
|
||
def smooth(
|
||
tensor: torch.Tensor,
|
||
window_size_range: tuple = (2, 10),
|
||
mask: tp.Optional[torch.Tensor] = None,
|
||
) -> tp.Union[tp.Tuple[torch.Tensor, torch.Tensor], torch.Tensor]:
|
||
"""Smooths the input tensor (audio signal) using a moving average filter with the
|
||
given window size.
|
||
|
||
Args:
|
||
tensor (torch.Tensor): Input audio tensor. Assumes tensor shape is (batch_size,
|
||
channels, time).
|
||
window_size (int): Size of the moving average window.
|
||
mask: Masks for the input wave
|
||
|
||
Returns:
|
||
torch.Tensor: Smoothed audio tensor.
|
||
"""
|
||
|
||
window_size = int(torch.FloatTensor(1).uniform_(*window_size_range))
|
||
# Create a uniform smoothing kernel
|
||
kernel = torch.ones(1, 1, window_size).type(tensor.type()) / window_size
|
||
kernel = kernel.to(tensor.device)
|
||
|
||
smoothed = fft_conv1d(tensor, kernel)
|
||
# Ensure tensor size is not changed
|
||
tmp = torch.zeros_like(tensor)
|
||
tmp[..., : smoothed.shape[-1]] = smoothed
|
||
smoothed = tmp
|
||
|
||
return audio_effect_return(tensor=smoothed, mask=mask)
|
||
|
||
@staticmethod
|
||
def boost_audio(
|
||
tensor: torch.Tensor,
|
||
amount: float = 20,
|
||
mask: tp.Optional[torch.Tensor] = None,
|
||
) -> tp.Union[tp.Tuple[torch.Tensor, torch.Tensor], torch.Tensor]:
|
||
"""Filter the lowpass frequency from the waveform"""
|
||
return audio_effect_return(tensor=tensor * (1 + amount / 100), mask=mask)
|
||
|
||
@staticmethod
|
||
def duck_audio(
|
||
tensor: torch.Tensor,
|
||
amount: float = 20,
|
||
mask: tp.Optional[torch.Tensor] = None,
|
||
) -> tp.Union[tp.Tuple[torch.Tensor, torch.Tensor], torch.Tensor]:
|
||
"""Mask input wav with some ducked signnals"""
|
||
return audio_effect_return(tensor=tensor * (1 - amount / 100), mask=mask)
|
||
|
||
@staticmethod
|
||
def identity(
|
||
tensor: torch.Tensor, mask: tp.Optional[torch.Tensor] = None
|
||
) -> tp.Union[tp.Tuple[torch.Tensor, torch.Tensor], torch.Tensor]:
|
||
return audio_effect_return(tensor=tensor, mask=mask)
|
||
|
||
@staticmethod
|
||
def mp3_compression(
|
||
tensor: torch.Tensor,
|
||
sample_rate: int = 16000,
|
||
bitrate: str = "128k",
|
||
mask: tp.Optional[torch.Tensor] = None,
|
||
) -> tp.Union[tp.Tuple[torch.Tensor, torch.Tensor], torch.Tensor]:
|
||
"""
|
||
Compress audio using MP3 algorithm
|
||
Args:
|
||
tensor (torch.Tensor): The input audio tensor.
|
||
sample_rate (int): The sample rate of the audio.
|
||
bitrate (str): The bitrate for MP3 compression.
|
||
|
||
Returns:
|
||
torch.Tensor: The output tensor after applying MP3 compression.
|
||
"""
|
||
out = apply_compression_skip_grad(
|
||
tensor, get_mp3, sr=sample_rate, bitrate=bitrate
|
||
)
|
||
return audio_effect_return(tensor=out, mask=mask)
|
||
|
||
@staticmethod
|
||
def aac_compression(
|
||
tensor: torch.Tensor,
|
||
sample_rate: int = 16000,
|
||
bitrate: str = "128k",
|
||
lowpass_freq: tp.Optional[int] = None,
|
||
mask: tp.Optional[torch.Tensor] = None,
|
||
) -> tp.Union[tp.Tuple[torch.Tensor, torch.Tensor], torch.Tensor]:
|
||
"""Applies AAC compression to an audio tensor.
|
||
|
||
Args:
|
||
tensor (torch.Tensor): The input audio tensor.
|
||
sample_rate (int): The sample rate of the audio.
|
||
bitrate (str): The bitrate for AAC compression.
|
||
lowpass_freq (Optional[int]): The frequency for a low-pass filter.
|
||
|
||
Returns:
|
||
torch.Tensor: The output tensor after applying AAC compression.
|
||
"""
|
||
out = apply_compression_skip_grad(
|
||
tensor, get_aac, sr=sample_rate, bitrate=bitrate, lowpass_freq=lowpass_freq
|
||
)
|
||
return audio_effect_return(tensor=out, mask=mask)</code></pre>
|
||
</details>
|
||
<div class="desc"></div>
|
||
<h3>Static methods</h3>
|
||
<dl>
|
||
<dt id="audiocraft.utils.audio_effects.AudioEffects.aac_compression"><code class="name flex">
|
||
<span>def <span class="ident">aac_compression</span></span>(<span>tensor: torch.Tensor,<br>sample_rate: int = 16000,<br>bitrate: str = '128k',<br>lowpass_freq: int | None = None,<br>mask: torch.Tensor | None = None) ‑> torch.Tensor | Tuple[torch.Tensor, torch.Tensor]</span>
|
||
</code></dt>
|
||
<dd>
|
||
<details class="source">
|
||
<summary>
|
||
<span>Expand source code</span>
|
||
</summary>
|
||
<pre><code class="python">@staticmethod
|
||
def aac_compression(
|
||
tensor: torch.Tensor,
|
||
sample_rate: int = 16000,
|
||
bitrate: str = "128k",
|
||
lowpass_freq: tp.Optional[int] = None,
|
||
mask: tp.Optional[torch.Tensor] = None,
|
||
) -> tp.Union[tp.Tuple[torch.Tensor, torch.Tensor], torch.Tensor]:
|
||
"""Applies AAC compression to an audio tensor.
|
||
|
||
Args:
|
||
tensor (torch.Tensor): The input audio tensor.
|
||
sample_rate (int): The sample rate of the audio.
|
||
bitrate (str): The bitrate for AAC compression.
|
||
lowpass_freq (Optional[int]): The frequency for a low-pass filter.
|
||
|
||
Returns:
|
||
torch.Tensor: The output tensor after applying AAC compression.
|
||
"""
|
||
out = apply_compression_skip_grad(
|
||
tensor, get_aac, sr=sample_rate, bitrate=bitrate, lowpass_freq=lowpass_freq
|
||
)
|
||
return audio_effect_return(tensor=out, mask=mask)</code></pre>
|
||
</details>
|
||
<div class="desc"><p>Applies AAC compression to an audio tensor.</p>
|
||
<h2 id="args">Args</h2>
|
||
<dl>
|
||
<dt><strong><code>tensor</code></strong> : <code>torch.Tensor</code></dt>
|
||
<dd>The input audio tensor.</dd>
|
||
<dt><strong><code>sample_rate</code></strong> : <code>int</code></dt>
|
||
<dd>The sample rate of the audio.</dd>
|
||
<dt><strong><code>bitrate</code></strong> : <code>str</code></dt>
|
||
<dd>The bitrate for AAC compression.</dd>
|
||
<dt><strong><code>lowpass_freq</code></strong> : <code>Optional[int]</code></dt>
|
||
<dd>The frequency for a low-pass filter.</dd>
|
||
</dl>
|
||
<h2 id="returns">Returns</h2>
|
||
<dl>
|
||
<dt><code>torch.Tensor</code></dt>
|
||
<dd>The output tensor after applying AAC compression.</dd>
|
||
</dl></div>
|
||
</dd>
|
||
<dt id="audiocraft.utils.audio_effects.AudioEffects.bandpass_filter"><code class="name flex">
|
||
<span>def <span class="ident">bandpass_filter</span></span>(<span>waveform: torch.Tensor,<br>cutoff_freq_low: float = 300,<br>cutoff_freq_high: float = 8000,<br>sample_rate: int = 16000,<br>mask: torch.Tensor | None = None) ‑> torch.Tensor | Tuple[torch.Tensor, torch.Tensor]</span>
|
||
</code></dt>
|
||
<dd>
|
||
<details class="source">
|
||
<summary>
|
||
<span>Expand source code</span>
|
||
</summary>
|
||
<pre><code class="python">@staticmethod
|
||
def bandpass_filter(
|
||
waveform: torch.Tensor,
|
||
cutoff_freq_low: float = 300,
|
||
cutoff_freq_high: float = 8000,
|
||
sample_rate: int = 16000,
|
||
mask: tp.Optional[torch.Tensor] = None,
|
||
) -> tp.Union[tp.Tuple[torch.Tensor, torch.Tensor], torch.Tensor]:
|
||
"""Apply a bandpass filter to the waveform by cascading
|
||
a high-pass filter followed by a low-pass filter.
|
||
|
||
Args:
|
||
waveform (torch.Tensor): Input audio waveform.
|
||
low_cutoff (float): Lower cutoff frequency.
|
||
high_cutoff (float): Higher cutoff frequency.
|
||
sample_rate (int): The sample rate of the waveform.
|
||
|
||
Returns:
|
||
torch.Tensor: Filtered audio waveform.
|
||
"""
|
||
|
||
return audio_effect_return(
|
||
tensor=julius.bandpass_filter(
|
||
waveform,
|
||
cutoff_low=cutoff_freq_low / sample_rate,
|
||
cutoff_high=cutoff_freq_high / sample_rate,
|
||
),
|
||
mask=mask,
|
||
)</code></pre>
|
||
</details>
|
||
<div class="desc"><p>Apply a bandpass filter to the waveform by cascading
|
||
a high-pass filter followed by a low-pass filter.</p>
|
||
<h2 id="args">Args</h2>
|
||
<dl>
|
||
<dt><strong><code>waveform</code></strong> : <code>torch.Tensor</code></dt>
|
||
<dd>Input audio waveform.</dd>
|
||
<dt><strong><code>low_cutoff</code></strong> : <code>float</code></dt>
|
||
<dd>Lower cutoff frequency.</dd>
|
||
<dt><strong><code>high_cutoff</code></strong> : <code>float</code></dt>
|
||
<dd>Higher cutoff frequency.</dd>
|
||
<dt><strong><code>sample_rate</code></strong> : <code>int</code></dt>
|
||
<dd>The sample rate of the waveform.</dd>
|
||
</dl>
|
||
<h2 id="returns">Returns</h2>
|
||
<dl>
|
||
<dt><code>torch.Tensor</code></dt>
|
||
<dd>Filtered audio waveform.</dd>
|
||
</dl></div>
|
||
</dd>
|
||
<dt id="audiocraft.utils.audio_effects.AudioEffects.boost_audio"><code class="name flex">
|
||
<span>def <span class="ident">boost_audio</span></span>(<span>tensor: torch.Tensor, amount: float = 20, mask: torch.Tensor | None = None) ‑> torch.Tensor | Tuple[torch.Tensor, torch.Tensor]</span>
|
||
</code></dt>
|
||
<dd>
|
||
<details class="source">
|
||
<summary>
|
||
<span>Expand source code</span>
|
||
</summary>
|
||
<pre><code class="python">@staticmethod
|
||
def boost_audio(
|
||
tensor: torch.Tensor,
|
||
amount: float = 20,
|
||
mask: tp.Optional[torch.Tensor] = None,
|
||
) -> tp.Union[tp.Tuple[torch.Tensor, torch.Tensor], torch.Tensor]:
|
||
"""Filter the lowpass frequency from the waveform"""
|
||
return audio_effect_return(tensor=tensor * (1 + amount / 100), mask=mask)</code></pre>
|
||
</details>
|
||
<div class="desc"><p>Filter the lowpass frequency from the waveform</p></div>
|
||
</dd>
|
||
<dt id="audiocraft.utils.audio_effects.AudioEffects.duck_audio"><code class="name flex">
|
||
<span>def <span class="ident">duck_audio</span></span>(<span>tensor: torch.Tensor, amount: float = 20, mask: torch.Tensor | None = None) ‑> torch.Tensor | Tuple[torch.Tensor, torch.Tensor]</span>
|
||
</code></dt>
|
||
<dd>
|
||
<details class="source">
|
||
<summary>
|
||
<span>Expand source code</span>
|
||
</summary>
|
||
<pre><code class="python">@staticmethod
|
||
def duck_audio(
|
||
tensor: torch.Tensor,
|
||
amount: float = 20,
|
||
mask: tp.Optional[torch.Tensor] = None,
|
||
) -> tp.Union[tp.Tuple[torch.Tensor, torch.Tensor], torch.Tensor]:
|
||
"""Mask input wav with some ducked signnals"""
|
||
return audio_effect_return(tensor=tensor * (1 - amount / 100), mask=mask)</code></pre>
|
||
</details>
|
||
<div class="desc"><p>Mask input wav with some ducked signnals</p></div>
|
||
</dd>
|
||
<dt id="audiocraft.utils.audio_effects.AudioEffects.echo"><code class="name flex">
|
||
<span>def <span class="ident">echo</span></span>(<span>tensor: torch.Tensor,<br>volume_range: tuple = (0.1, 0.5),<br>duration_range: tuple = (0.1, 0.5),<br>sample_rate: int = 16000,<br>mask: torch.Tensor | None = None) ‑> torch.Tensor | Tuple[torch.Tensor, torch.Tensor]</span>
|
||
</code></dt>
|
||
<dd>
|
||
<details class="source">
|
||
<summary>
|
||
<span>Expand source code</span>
|
||
</summary>
|
||
<pre><code class="python">@staticmethod
|
||
def echo(
|
||
tensor: torch.Tensor,
|
||
volume_range: tuple = (0.1, 0.5),
|
||
duration_range: tuple = (0.1, 0.5),
|
||
sample_rate: int = 16000,
|
||
mask: tp.Optional[torch.Tensor] = None,
|
||
) -> tp.Union[tp.Tuple[torch.Tensor, torch.Tensor], torch.Tensor]:
|
||
"""Attenuating the audio volume by a factor of 0.4, delaying it by 100ms,
|
||
and then overlaying it with the original.
|
||
|
||
Args:
|
||
tensor: 3D Tensor representing the audio signal [bsz, channels, frames]
|
||
volumne range: volume range of the echo signal
|
||
duration range: duration range of the echo signal
|
||
sample_rate: Sample rate of the audio signal.
|
||
Returns:
|
||
Audio signal with reverb.
|
||
"""
|
||
|
||
# Create a simple impulse response
|
||
# Duration of the impulse response in seconds
|
||
duration = torch.FloatTensor(1).uniform_(*duration_range)
|
||
volume = torch.FloatTensor(1).uniform_(*volume_range)
|
||
|
||
n_samples = int(sample_rate * duration)
|
||
impulse_response = torch.zeros(n_samples).type(tensor.type()).to(tensor.device)
|
||
|
||
# Define a few reflections with decreasing amplitude
|
||
impulse_response[0] = 1.0 # Direct sound
|
||
|
||
impulse_response[
|
||
int(sample_rate * duration) - 1
|
||
] = volume # First reflection after 100ms
|
||
|
||
# Add batch and channel dimensions to the impulse response
|
||
impulse_response = impulse_response.unsqueeze(0).unsqueeze(0)
|
||
|
||
# Convolve the audio signal with the impulse response
|
||
reverbed_signal = fft_conv1d(tensor, impulse_response)
|
||
|
||
# Normalize to the original amplitude range for stability
|
||
reverbed_signal = (
|
||
reverbed_signal
|
||
/ torch.max(torch.abs(reverbed_signal))
|
||
* torch.max(torch.abs(tensor))
|
||
)
|
||
|
||
# Ensure tensor size is not changed
|
||
tmp = torch.zeros_like(tensor)
|
||
tmp[..., : reverbed_signal.shape[-1]] = reverbed_signal
|
||
reverbed_signal = tmp
|
||
|
||
return audio_effect_return(tensor=reverbed_signal, mask=mask)</code></pre>
|
||
</details>
|
||
<div class="desc"><p>Attenuating the audio volume by a factor of 0.4, delaying it by 100ms,
|
||
and then overlaying it with the original.</p>
|
||
<h2 id="args">Args</h2>
|
||
<dl>
|
||
<dt><strong><code>tensor</code></strong></dt>
|
||
<dd>3D Tensor representing the audio signal [bsz, channels, frames]</dd>
|
||
<dt>volumne range: volume range of the echo signal</dt>
|
||
<dt>duration range: duration range of the echo signal</dt>
|
||
<dt><strong><code>sample_rate</code></strong></dt>
|
||
<dd>Sample rate of the audio signal.</dd>
|
||
</dl>
|
||
<h2 id="returns">Returns</h2>
|
||
<p>Audio signal with reverb.</p></div>
|
||
</dd>
|
||
<dt id="audiocraft.utils.audio_effects.AudioEffects.highpass_filter"><code class="name flex">
|
||
<span>def <span class="ident">highpass_filter</span></span>(<span>waveform: torch.Tensor,<br>cutoff_freq: float = 500,<br>sample_rate: int = 16000,<br>mask: torch.Tensor | None = None) ‑> torch.Tensor | Tuple[torch.Tensor, torch.Tensor]</span>
|
||
</code></dt>
|
||
<dd>
|
||
<details class="source">
|
||
<summary>
|
||
<span>Expand source code</span>
|
||
</summary>
|
||
<pre><code class="python">@staticmethod
|
||
def highpass_filter(
|
||
waveform: torch.Tensor,
|
||
cutoff_freq: float = 500,
|
||
sample_rate: int = 16000,
|
||
mask: tp.Optional[torch.Tensor] = None,
|
||
) -> tp.Union[tp.Tuple[torch.Tensor, torch.Tensor], torch.Tensor]:
|
||
"""Filter the highpass frequency from the waveform"""
|
||
return audio_effect_return(
|
||
tensor=julius.highpass_filter(waveform, cutoff=cutoff_freq / sample_rate),
|
||
mask=mask,
|
||
)</code></pre>
|
||
</details>
|
||
<div class="desc"><p>Filter the highpass frequency from the waveform</p></div>
|
||
</dd>
|
||
<dt id="audiocraft.utils.audio_effects.AudioEffects.identity"><code class="name flex">
|
||
<span>def <span class="ident">identity</span></span>(<span>tensor: torch.Tensor, mask: torch.Tensor | None = None) ‑> torch.Tensor | Tuple[torch.Tensor, torch.Tensor]</span>
|
||
</code></dt>
|
||
<dd>
|
||
<details class="source">
|
||
<summary>
|
||
<span>Expand source code</span>
|
||
</summary>
|
||
<pre><code class="python">@staticmethod
|
||
def identity(
|
||
tensor: torch.Tensor, mask: tp.Optional[torch.Tensor] = None
|
||
) -> tp.Union[tp.Tuple[torch.Tensor, torch.Tensor], torch.Tensor]:
|
||
return audio_effect_return(tensor=tensor, mask=mask)</code></pre>
|
||
</details>
|
||
<div class="desc"></div>
|
||
</dd>
|
||
<dt id="audiocraft.utils.audio_effects.AudioEffects.lowpass_filter"><code class="name flex">
|
||
<span>def <span class="ident">lowpass_filter</span></span>(<span>waveform: torch.Tensor,<br>cutoff_freq: float = 5000,<br>sample_rate: int = 16000,<br>mask: torch.Tensor | None = None) ‑> torch.Tensor | Tuple[torch.Tensor, torch.Tensor]</span>
|
||
</code></dt>
|
||
<dd>
|
||
<details class="source">
|
||
<summary>
|
||
<span>Expand source code</span>
|
||
</summary>
|
||
<pre><code class="python">@staticmethod
|
||
def lowpass_filter(
|
||
waveform: torch.Tensor,
|
||
cutoff_freq: float = 5000,
|
||
sample_rate: int = 16000,
|
||
mask: tp.Optional[torch.Tensor] = None,
|
||
) -> tp.Union[tp.Tuple[torch.Tensor, torch.Tensor], torch.Tensor]:
|
||
"""Filter the lowpass frequency from the waveform"""
|
||
return audio_effect_return(
|
||
tensor=julius.lowpass_filter(waveform, cutoff=cutoff_freq / sample_rate),
|
||
mask=mask,
|
||
)</code></pre>
|
||
</details>
|
||
<div class="desc"><p>Filter the lowpass frequency from the waveform</p></div>
|
||
</dd>
|
||
<dt id="audiocraft.utils.audio_effects.AudioEffects.mp3_compression"><code class="name flex">
|
||
<span>def <span class="ident">mp3_compression</span></span>(<span>tensor: torch.Tensor,<br>sample_rate: int = 16000,<br>bitrate: str = '128k',<br>mask: torch.Tensor | None = None) ‑> torch.Tensor | Tuple[torch.Tensor, torch.Tensor]</span>
|
||
</code></dt>
|
||
<dd>
|
||
<details class="source">
|
||
<summary>
|
||
<span>Expand source code</span>
|
||
</summary>
|
||
<pre><code class="python">@staticmethod
|
||
def mp3_compression(
|
||
tensor: torch.Tensor,
|
||
sample_rate: int = 16000,
|
||
bitrate: str = "128k",
|
||
mask: tp.Optional[torch.Tensor] = None,
|
||
) -> tp.Union[tp.Tuple[torch.Tensor, torch.Tensor], torch.Tensor]:
|
||
"""
|
||
Compress audio using MP3 algorithm
|
||
Args:
|
||
tensor (torch.Tensor): The input audio tensor.
|
||
sample_rate (int): The sample rate of the audio.
|
||
bitrate (str): The bitrate for MP3 compression.
|
||
|
||
Returns:
|
||
torch.Tensor: The output tensor after applying MP3 compression.
|
||
"""
|
||
out = apply_compression_skip_grad(
|
||
tensor, get_mp3, sr=sample_rate, bitrate=bitrate
|
||
)
|
||
return audio_effect_return(tensor=out, mask=mask)</code></pre>
|
||
</details>
|
||
<div class="desc"><p>Compress audio using MP3 algorithm</p>
|
||
<h2 id="args">Args</h2>
|
||
<dl>
|
||
<dt><strong><code>tensor</code></strong> : <code>torch.Tensor</code></dt>
|
||
<dd>The input audio tensor.</dd>
|
||
<dt><strong><code>sample_rate</code></strong> : <code>int</code></dt>
|
||
<dd>The sample rate of the audio.</dd>
|
||
<dt><strong><code>bitrate</code></strong> : <code>str</code></dt>
|
||
<dd>The bitrate for MP3 compression.</dd>
|
||
</dl>
|
||
<h2 id="returns">Returns</h2>
|
||
<dl>
|
||
<dt><code>torch.Tensor</code></dt>
|
||
<dd>The output tensor after applying MP3 compression.</dd>
|
||
</dl></div>
|
||
</dd>
|
||
<dt id="audiocraft.utils.audio_effects.AudioEffects.pink_noise"><code class="name flex">
|
||
<span>def <span class="ident">pink_noise</span></span>(<span>waveform: torch.Tensor,<br>noise_std: float = 0.01,<br>mask: torch.Tensor | None = None) ‑> torch.Tensor | Tuple[torch.Tensor, torch.Tensor]</span>
|
||
</code></dt>
|
||
<dd>
|
||
<details class="source">
|
||
<summary>
|
||
<span>Expand source code</span>
|
||
</summary>
|
||
<pre><code class="python">@staticmethod
|
||
def pink_noise(
|
||
waveform: torch.Tensor,
|
||
noise_std: float = 0.01,
|
||
mask: tp.Optional[torch.Tensor] = None,
|
||
) -> tp.Union[tp.Tuple[torch.Tensor, torch.Tensor], torch.Tensor]:
|
||
"""Add pink background noise to the waveform."""
|
||
noise = generate_pink_noise(waveform.shape[-1]) * noise_std
|
||
noise = noise.to(waveform.device)
|
||
# Assuming waveform is of shape (bsz, channels, length)
|
||
noisy_waveform = waveform + noise.unsqueeze(0).unsqueeze(0).to(waveform.device)
|
||
return audio_effect_return(tensor=noisy_waveform, mask=mask)</code></pre>
|
||
</details>
|
||
<div class="desc"><p>Add pink background noise to the waveform.</p></div>
|
||
</dd>
|
||
<dt id="audiocraft.utils.audio_effects.AudioEffects.random_noise"><code class="name flex">
|
||
<span>def <span class="ident">random_noise</span></span>(<span>waveform: torch.Tensor,<br>noise_std: float = 0.001,<br>mask: torch.Tensor | None = None) ‑> torch.Tensor | Tuple[torch.Tensor, torch.Tensor]</span>
|
||
</code></dt>
|
||
<dd>
|
||
<details class="source">
|
||
<summary>
|
||
<span>Expand source code</span>
|
||
</summary>
|
||
<pre><code class="python">@staticmethod
|
||
def random_noise(
|
||
waveform: torch.Tensor,
|
||
noise_std: float = 0.001,
|
||
mask: tp.Optional[torch.Tensor] = None,
|
||
) -> tp.Union[tp.Tuple[torch.Tensor, torch.Tensor], torch.Tensor]:
|
||
"""Add Gaussian noise to the waveform."""
|
||
noise = torch.randn_like(waveform) * noise_std
|
||
noisy_waveform = waveform + noise
|
||
return audio_effect_return(tensor=noisy_waveform, mask=mask)</code></pre>
|
||
</details>
|
||
<div class="desc"><p>Add Gaussian noise to the waveform.</p></div>
|
||
</dd>
|
||
<dt id="audiocraft.utils.audio_effects.AudioEffects.smooth"><code class="name flex">
|
||
<span>def <span class="ident">smooth</span></span>(<span>tensor: torch.Tensor,<br>window_size_range: tuple = (2, 10),<br>mask: torch.Tensor | None = None) ‑> torch.Tensor | Tuple[torch.Tensor, torch.Tensor]</span>
|
||
</code></dt>
|
||
<dd>
|
||
<details class="source">
|
||
<summary>
|
||
<span>Expand source code</span>
|
||
</summary>
|
||
<pre><code class="python">@staticmethod
|
||
def smooth(
|
||
tensor: torch.Tensor,
|
||
window_size_range: tuple = (2, 10),
|
||
mask: tp.Optional[torch.Tensor] = None,
|
||
) -> tp.Union[tp.Tuple[torch.Tensor, torch.Tensor], torch.Tensor]:
|
||
"""Smooths the input tensor (audio signal) using a moving average filter with the
|
||
given window size.
|
||
|
||
Args:
|
||
tensor (torch.Tensor): Input audio tensor. Assumes tensor shape is (batch_size,
|
||
channels, time).
|
||
window_size (int): Size of the moving average window.
|
||
mask: Masks for the input wave
|
||
|
||
Returns:
|
||
torch.Tensor: Smoothed audio tensor.
|
||
"""
|
||
|
||
window_size = int(torch.FloatTensor(1).uniform_(*window_size_range))
|
||
# Create a uniform smoothing kernel
|
||
kernel = torch.ones(1, 1, window_size).type(tensor.type()) / window_size
|
||
kernel = kernel.to(tensor.device)
|
||
|
||
smoothed = fft_conv1d(tensor, kernel)
|
||
# Ensure tensor size is not changed
|
||
tmp = torch.zeros_like(tensor)
|
||
tmp[..., : smoothed.shape[-1]] = smoothed
|
||
smoothed = tmp
|
||
|
||
return audio_effect_return(tensor=smoothed, mask=mask)</code></pre>
|
||
</details>
|
||
<div class="desc"><p>Smooths the input tensor (audio signal) using a moving average filter with the
|
||
given window size.</p>
|
||
<h2 id="args">Args</h2>
|
||
<dl>
|
||
<dt><strong><code>tensor</code></strong> : <code>torch.Tensor</code></dt>
|
||
<dd>Input audio tensor. Assumes tensor shape is (batch_size,</dd>
|
||
<dt>channels, time).</dt>
|
||
<dt><strong><code>window_size</code></strong> : <code>int</code></dt>
|
||
<dd>Size of the moving average window.</dd>
|
||
<dt><strong><code>mask</code></strong></dt>
|
||
<dd>Masks for the input wave</dd>
|
||
</dl>
|
||
<h2 id="returns">Returns</h2>
|
||
<dl>
|
||
<dt><code>torch.Tensor</code></dt>
|
||
<dd>Smoothed audio tensor.</dd>
|
||
</dl></div>
|
||
</dd>
|
||
<dt id="audiocraft.utils.audio_effects.AudioEffects.speed"><code class="name flex">
|
||
<span>def <span class="ident">speed</span></span>(<span>tensor: torch.Tensor,<br>speed_range: tuple = (0.5, 1.5),<br>sample_rate: int = 16000,<br>mask: torch.Tensor | None = None) ‑> torch.Tensor | Tuple[torch.Tensor, torch.Tensor]</span>
|
||
</code></dt>
|
||
<dd>
|
||
<details class="source">
|
||
<summary>
|
||
<span>Expand source code</span>
|
||
</summary>
|
||
<pre><code class="python">@staticmethod
|
||
def speed(
|
||
tensor: torch.Tensor,
|
||
speed_range: tuple = (0.5, 1.5),
|
||
sample_rate: int = 16000,
|
||
mask: tp.Optional[torch.Tensor] = None,
|
||
) -> tp.Union[tp.Tuple[torch.Tensor, torch.Tensor], torch.Tensor]:
|
||
"""Function to change the speed of a batch of audio data.
|
||
The output will have a different length !
|
||
|
||
Args:
|
||
audio_batch (torch.Tensor): The batch of audio data in torch tensor format.
|
||
speed (float): The speed to change the audio to.
|
||
|
||
Returns:
|
||
torch.Tensor: The batch of audio data with the speed changed.
|
||
"""
|
||
speed = torch.FloatTensor(1).uniform_(*speed_range)
|
||
new_sr = int(sample_rate * 1 / speed)
|
||
resampled_tensor = julius.resample.resample_frac(tensor, sample_rate, new_sr)
|
||
if mask is None:
|
||
return resampled_tensor
|
||
else:
|
||
return resampled_tensor, torch.nn.functional.interpolate(
|
||
mask, size=resampled_tensor.size(-1), mode="nearest-exact"
|
||
)</code></pre>
|
||
</details>
|
||
<div class="desc"><p>Function to change the speed of a batch of audio data.
|
||
The output will have a different length !</p>
|
||
<h2 id="args">Args</h2>
|
||
<dl>
|
||
<dt><strong><code>audio_batch</code></strong> : <code>torch.Tensor</code></dt>
|
||
<dd>The batch of audio data in torch tensor format.</dd>
|
||
<dt><strong><code>speed</code></strong> : <code>float</code></dt>
|
||
<dd>The speed to change the audio to.</dd>
|
||
</dl>
|
||
<h2 id="returns">Returns</h2>
|
||
<dl>
|
||
<dt><code>torch.Tensor</code></dt>
|
||
<dd>The batch of audio data with the speed changed.</dd>
|
||
</dl></div>
|
||
</dd>
|
||
<dt id="audiocraft.utils.audio_effects.AudioEffects.updownresample"><code class="name flex">
|
||
<span>def <span class="ident">updownresample</span></span>(<span>tensor: torch.Tensor,<br>sample_rate: int = 16000,<br>intermediate_freq: int = 32000,<br>mask: torch.Tensor | None = None) ‑> torch.Tensor | Tuple[torch.Tensor, torch.Tensor]</span>
|
||
</code></dt>
|
||
<dd>
|
||
<details class="source">
|
||
<summary>
|
||
<span>Expand source code</span>
|
||
</summary>
|
||
<pre><code class="python">@staticmethod
|
||
def updownresample(
|
||
tensor: torch.Tensor,
|
||
sample_rate: int = 16000,
|
||
intermediate_freq: int = 32000,
|
||
mask: tp.Optional[torch.Tensor] = None,
|
||
) -> tp.Union[tp.Tuple[torch.Tensor, torch.Tensor], torch.Tensor]:
|
||
|
||
orig_shape = tensor.shape
|
||
# upsample
|
||
tensor = resample_frac(tensor, sample_rate, intermediate_freq)
|
||
# downsample
|
||
tensor = resample_frac(tensor, intermediate_freq, sample_rate)
|
||
|
||
assert tensor.shape == orig_shape
|
||
return audio_effect_return(tensor=tensor, mask=mask)</code></pre>
|
||
</details>
|
||
<div class="desc"></div>
|
||
</dd>
|
||
</dl>
|
||
</dd>
|
||
</dl>
|
||
</section>
|
||
</article>
|
||
<nav id="sidebar">
|
||
<div class="toc">
|
||
<ul></ul>
|
||
</div>
|
||
<ul id="index">
|
||
<li><h3>Super-module</h3>
|
||
<ul>
|
||
<li><code><a title="audiocraft.utils" href="index.html">audiocraft.utils</a></code></li>
|
||
</ul>
|
||
</li>
|
||
<li><h3><a href="#header-functions">Functions</a></h3>
|
||
<ul class="">
|
||
<li><code><a title="audiocraft.utils.audio_effects.apply_compression_skip_grad" href="#audiocraft.utils.audio_effects.apply_compression_skip_grad">apply_compression_skip_grad</a></code></li>
|
||
<li><code><a title="audiocraft.utils.audio_effects.audio_effect_return" href="#audiocraft.utils.audio_effects.audio_effect_return">audio_effect_return</a></code></li>
|
||
<li><code><a title="audiocraft.utils.audio_effects.compress_with_encodec" href="#audiocraft.utils.audio_effects.compress_with_encodec">compress_with_encodec</a></code></li>
|
||
<li><code><a title="audiocraft.utils.audio_effects.generate_pink_noise" href="#audiocraft.utils.audio_effects.generate_pink_noise">generate_pink_noise</a></code></li>
|
||
<li><code><a title="audiocraft.utils.audio_effects.get_audio_effects" href="#audiocraft.utils.audio_effects.get_audio_effects">get_audio_effects</a></code></li>
|
||
<li><code><a title="audiocraft.utils.audio_effects.select_audio_effects" href="#audiocraft.utils.audio_effects.select_audio_effects">select_audio_effects</a></code></li>
|
||
</ul>
|
||
</li>
|
||
<li><h3><a href="#header-classes">Classes</a></h3>
|
||
<ul>
|
||
<li>
|
||
<h4><code><a title="audiocraft.utils.audio_effects.AudioEffects" href="#audiocraft.utils.audio_effects.AudioEffects">AudioEffects</a></code></h4>
|
||
<ul class="two-column">
|
||
<li><code><a title="audiocraft.utils.audio_effects.AudioEffects.aac_compression" href="#audiocraft.utils.audio_effects.AudioEffects.aac_compression">aac_compression</a></code></li>
|
||
<li><code><a title="audiocraft.utils.audio_effects.AudioEffects.bandpass_filter" href="#audiocraft.utils.audio_effects.AudioEffects.bandpass_filter">bandpass_filter</a></code></li>
|
||
<li><code><a title="audiocraft.utils.audio_effects.AudioEffects.boost_audio" href="#audiocraft.utils.audio_effects.AudioEffects.boost_audio">boost_audio</a></code></li>
|
||
<li><code><a title="audiocraft.utils.audio_effects.AudioEffects.duck_audio" href="#audiocraft.utils.audio_effects.AudioEffects.duck_audio">duck_audio</a></code></li>
|
||
<li><code><a title="audiocraft.utils.audio_effects.AudioEffects.echo" href="#audiocraft.utils.audio_effects.AudioEffects.echo">echo</a></code></li>
|
||
<li><code><a title="audiocraft.utils.audio_effects.AudioEffects.highpass_filter" href="#audiocraft.utils.audio_effects.AudioEffects.highpass_filter">highpass_filter</a></code></li>
|
||
<li><code><a title="audiocraft.utils.audio_effects.AudioEffects.identity" href="#audiocraft.utils.audio_effects.AudioEffects.identity">identity</a></code></li>
|
||
<li><code><a title="audiocraft.utils.audio_effects.AudioEffects.lowpass_filter" href="#audiocraft.utils.audio_effects.AudioEffects.lowpass_filter">lowpass_filter</a></code></li>
|
||
<li><code><a title="audiocraft.utils.audio_effects.AudioEffects.mp3_compression" href="#audiocraft.utils.audio_effects.AudioEffects.mp3_compression">mp3_compression</a></code></li>
|
||
<li><code><a title="audiocraft.utils.audio_effects.AudioEffects.pink_noise" href="#audiocraft.utils.audio_effects.AudioEffects.pink_noise">pink_noise</a></code></li>
|
||
<li><code><a title="audiocraft.utils.audio_effects.AudioEffects.random_noise" href="#audiocraft.utils.audio_effects.AudioEffects.random_noise">random_noise</a></code></li>
|
||
<li><code><a title="audiocraft.utils.audio_effects.AudioEffects.smooth" href="#audiocraft.utils.audio_effects.AudioEffects.smooth">smooth</a></code></li>
|
||
<li><code><a title="audiocraft.utils.audio_effects.AudioEffects.speed" href="#audiocraft.utils.audio_effects.AudioEffects.speed">speed</a></code></li>
|
||
<li><code><a title="audiocraft.utils.audio_effects.AudioEffects.updownresample" href="#audiocraft.utils.audio_effects.AudioEffects.updownresample">updownresample</a></code></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
</nav>
|
||
</main>
|
||
<footer id="footer">
|
||
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.5</a>.</p>
|
||
</footer>
|
||
</body>
|
||
</html>
|