Decode acoustic latents to audio waveform. Input: (batch, vae_dim, frames) or (batch, frames, vae_dim) Output: (batch, 1, samples)
(&self, latents: &Tensor)
| 397 | /// Input: (batch, vae_dim, frames) or (batch, frames, vae_dim) |
| 398 | /// Output: (batch, 1, samples) |
| 399 | pub fn decode(&self, latents: &Tensor) -> Result<Tensor> { |
| 400 | let x = if latents.dim(1)? == 64 { |
| 401 | latents.clone() |
| 402 | } else { |
| 403 | latents.transpose(1, 2)? |
| 404 | }; |
| 405 | |
| 406 | let mut h = x; |
| 407 | |
| 408 | for (i, (upsample, stage)) in self.upsample_layers.iter().zip(self.stages.iter()).enumerate() { |
| 409 | if i == 0 { |
| 410 | // First layer: Conv1d kernel=7, causal left-pad 6 |
| 411 | h = Self::causal_pad(&h, 6)?; |
| 412 | } |
| 413 | h = upsample.forward(&h, &*self.backend)?; |
| 414 | if i > 0 { |
| 415 | // ConvTranspose1d: trim extra samples from right |
| 416 | h = Self::causal_trim(&h, self.ratios[i])?; |
| 417 | } |
| 418 | h = stage.forward(&h)?; |
| 419 | } |
| 420 | |
| 421 | // Head conv: kernel=7, causal left-pad 6 |
| 422 | h = Self::causal_pad(&h, 6)?; |
| 423 | self.backend.conv1d(&h, &self.head_conv.weight, self.head_conv.bias.as_ref(), self.head_conv.padding, self.head_conv.stride, self.head_conv.dilation, self.head_conv.groups) |
| 424 | } |
| 425 | |
| 426 | /// Streaming decode: uses cache for correct context between frames. |
| 427 | /// Each call processes a single latent frame and produces audio samples. |