| 1705 | if (frames < min_code_samples) { |
| 1706 | working_codes = repeat_codes_to_length(working_codes, codebooks, frames, min_code_samples); |
| 1707 | frames = min_code_samples; |
| 1708 | } |
| 1709 | if ((frames - ovlp_frames) % hop_code_samples > 0) { |
| 1710 | const int64_t padded_frames = static_cast<int64_t>( |
| 1711 | std::ceil(static_cast<double>(frames - ovlp_code_samples) / static_cast<double>(hop_code_samples))) * |
| 1712 | hop_code_samples + |
| 1713 | ovlp_code_samples; |
| 1714 | working_codes = repeat_codes_to_length(working_codes, codebooks, frames, padded_frames); |
| 1715 | frames = padded_frames; |
| 1716 | } |
| 1717 | const int64_t latent_length = static_cast<int64_t>(options.codec_duration * 25.0F); |
| 1718 | std::vector<std::vector<float>> latent_list; |
| 1719 | for (int64_t sinx = 0; sinx < frames - hop_code_samples + 1; sinx += hop_code_samples) { |
| 1720 | const auto chunk_codes = slice_codes_bqt(working_codes, codebooks, frames, sinx, min_code_samples); |
| 1721 | int64_t incontext_length = first_latent_length; |
| 1722 | std::vector<float> true_latent(static_cast<size_t>(latent_length * config.out_channels), 0.0F); |
| 1723 | if (sinx != 0 && ovlp_frames != 0) { |
| 1724 | const auto & prev = latent_list.back(); |
| 1725 | incontext_length = ovlp_frames; |
| 1726 | if (static_cast<int64_t>(prev.size()) < ovlp_frames * config.out_channels) { |
| 1727 | throw std::runtime_error("HeartCodec overlap latent shape mismatch"); |
| 1728 | } |
| 1729 | std::copy( |
| 1730 | prev.end() - static_cast<std::ptrdiff_t>(ovlp_frames * config.out_channels), |
| 1731 | prev.end(), |
| 1732 | true_latent.begin()); |
| 1733 | } |
| 1734 | auto latents = run_flow_chunk( |
| 1735 | *this, |
| 1736 | chunk_codes, |
| 1737 | min_code_samples, |
| 1738 | latent_length, |
| 1739 | incontext_length, |
| 1740 | true_latent, |
| 1741 | options.num_inference_steps, |
| 1742 | options.codec_guidance_scale, |
| 1743 | seed, |
| 1744 | randn_philox_offset, |
| 1745 | randn_call_offset_blocks, |
| 1746 | sampling_policy); |
| 1747 | latent_list.push_back(std::move(latents)); |
| 1748 | } |
| 1749 | if (latent_list.empty()) { |
| 1750 | throw std::runtime_error("HeartCodec detokenize produced no latent chunks"); |
| 1751 | } |
| 1752 | if (first_latent_length > 0) { |
| 1753 | auto & first = latent_list.front(); |
| 1754 | first.erase(first.begin(), first.begin() + static_cast<std::ptrdiff_t>(first_latent_length * config.out_channels)); |
| 1755 | } |
| 1756 | |
| 1757 | const int64_t audio_chunk_samples = static_cast<int64_t>(options.codec_duration * static_cast<float>(config.sample_rate)); |
| 1758 | const int64_t audio_hop_samples = (audio_chunk_samples / 93) * 80; |
| 1759 | const int64_t audio_ovlp_samples = audio_chunk_samples - audio_hop_samples; |
| 1760 | std::vector<float> output; |
| 1761 | int64_t output_samples = 0; |
| 1762 | for (size_t chunk = 0; chunk < latent_list.size(); ++chunk) { |
| 1763 | const int64_t chunk_latent_frames = static_cast<int64_t>(latent_list[chunk].size()) / config.out_channels; |
| 1764 | auto scalar_input = latent_btc_to_scalar_bct(latent_list[chunk], chunk_latent_frames); |
no test coverage detected