| 413 | } |
| 414 | |
| 415 | double length_penalty(const std::string & text, const std::vector<int32_t> & tokens, const std::string & language) { |
| 416 | const double duration_sec = static_cast<double>(tokens.size()) / kBestOfNTokenRateHz; |
| 417 | const int64_t phonemes = approximate_phoneme_count(text, language); |
| 418 | double min_spp = 0.07; |
| 419 | double max_spp = 0.18; |
| 420 | if (language == "en") { |
| 421 | min_spp = 0.06; |
| 422 | max_spp = 0.12; |
| 423 | } else if (language == "ja") { |
| 424 | min_spp = 0.07; |
| 425 | max_spp = 0.15; |
| 426 | } |
| 427 | const double bonus = punctuation_bonus_seconds(text); |
| 428 | const double min_expected = static_cast<double>(phonemes) * min_spp + bonus; |
| 429 | const double max_expected = static_cast<double>(phonemes) * max_spp + bonus; |
| 430 | if (duration_sec <= 0.0 || min_expected <= 0.0) { |
| 431 | return 0.0; |
| 432 | } |
| 433 | if (duration_sec < min_expected) { |
| 434 | return (min_expected - duration_sec) / min_expected; |
| 435 | } |
| 436 | if (duration_sec > max_expected) { |
| 437 | return (duration_sec - max_expected) / max_expected; |
| 438 | } |
| 439 | return 0.0; |
| 440 | } |
| 441 | |
| 442 | std::pair<double, double> silence_stats(const std::vector<float> & audio, int sample_rate) { |
| 443 | if (audio.empty()) { |
no test coverage detected