| 220 | } |
| 221 | |
| 222 | int64_t stft_frames_for_codec_tokens( |
| 223 | const miocodec::MioCodecConfig & config, |
| 224 | int64_t tokens) { |
| 225 | if (tokens <= 0) { |
| 226 | throw std::runtime_error("MioTTS generated no codec tokens"); |
| 227 | } |
| 228 | if (config.sample_rate % kMioTTSTokenRateHz != 0) { |
| 229 | throw std::runtime_error("MioTTS codec sample rate is not divisible by token rate"); |
| 230 | } |
| 231 | const int upsample_factor = std::accumulate( |
| 232 | config.wave_upsampler_factors.begin(), |
| 233 | config.wave_upsampler_factors.end(), |
| 234 | 1, |
| 235 | [](int lhs, int rhs) { |
| 236 | return lhs * rhs; |
| 237 | }); |
| 238 | const int64_t samples = tokens * (config.sample_rate / kMioTTSTokenRateHz); |
| 239 | const int64_t divisor = static_cast<int64_t>(config.hop_length) * upsample_factor; |
| 240 | if (samples % divisor != 0) { |
| 241 | throw std::runtime_error("MioTTS codec token length does not align with wave decoder STFT frames"); |
| 242 | } |
| 243 | return samples / divisor; |
| 244 | } |
| 245 | |
| 246 | struct MioTTSBestOfNCandidate { |
| 247 | MioTTSGeneratedTokens generated; |