From 92aaa446fccf1bafe6e80c15b9478e641fc5f090 Mon Sep 17 00:00:00 2001 From: danemadsen Date: Wed, 31 Jul 2024 09:41:43 +1000 Subject: [PATCH] num to word --- example/main.c | 2 +- src/numbers_to_words.hpp | 131 +++++++++++++++++++++++++++++++++++++-- src/phonemizer.cpp | 2 + 3 files changed, 130 insertions(+), 5 deletions(-) diff --git a/example/main.c b/example/main.c index dc75cc3..ca09a71 100644 --- a/example/main.c +++ b/example/main.c @@ -3,7 +3,7 @@ int main() { babylon_g2p_init("./models/deep_phonemizer.onnx", "en_us", 1); - const char* text = "Hello world. There is 317 characters in this sentence. This is an example program for the Babylon project. Text to speech models can be used to generate speech from text. This is a very powerful tool for many applications. For example, it can be used to generate speech for virtual assistants, audiobooks, and more."; + const char* text = "Hello world. There is 317 characters in this sentence."; babylon_tts_init("./models/curie.onnx"); diff --git a/src/numbers_to_words.hpp b/src/numbers_to_words.hpp index c280efc..454a63d 100644 --- a/src/numbers_to_words.hpp +++ b/src/numbers_to_words.hpp @@ -2,6 +2,25 @@ #include #include +std::vector split_into_threes(const std::string& str) { + std::vector parts; + int length = str.length(); + + // Process the string from the end + for (int i = length; i > 0; i -= 3) { + if (i < 3) { + parts.push_back(str.substr(0, i)); + } else { + parts.push_back(str.substr(i - 3, 3)); + } + } + + // Since we processed from the end, reverse the order of parts + std::reverse(parts.begin(), parts.end()); + + return parts; +} + std::string number_to_word(int number) { switch (number) { case 0: @@ -29,12 +48,116 @@ std::string number_to_word(int number) { } } +std::string tens_to_word(int tens) { + switch (tens) { + case 1: + return "ten"; + case 2: + return "twenty"; + case 3: + return "thirty"; + case 4: + return "forty"; + case 5: + return "fifty"; + case 6: + return "sixty"; + case 7: + return "seventy"; + case 8: + return "eighty"; + case 9: + return "ninety"; + default: + return ""; + } +} + +std::string teens_to_word(int teens) { + switch (teens) { + case 11: + return "eleven"; + case 12: + return "twelve"; + case 13: + return "thirteen"; + case 14: + return "fourteen"; + case 15: + return "fifteen"; + case 16: + return "sixteen"; + case 17: + return "seventeen"; + case 18: + return "eighteen"; + case 19: + return "nineteen"; + default: + return ""; + } +} + +std::string hundreds_to_words(int hundreds) { + std::string result; + int hundreds_digit = hundreds / 100; + int tens_digit = (hundreds % 100) / 10; + int ones_digit = hundreds % 10; + + if (hundreds_digit > 0) { + result += number_to_word(hundreds_digit) + " hundred"; + + if (tens_digit > 0 || ones_digit > 0) { + result += " and"; + } + } + + if (tens_digit > 1) { + if (result.length() > 0) { + result += " "; + } + result += tens_to_word(tens_digit); + } else if (tens_digit == 1) { + if (result.length() > 0) { + result += " "; + } + result += teens_to_word(hundreds % 100); + } + + if (ones_digit > 0 && tens_digit != 1) { + if (result.length() > 0) { + result += " "; + } + result += number_to_word(ones_digit); + } + + return result; +} + std::vector numbers_to_words(const std::string& text) { std::vector result; - - for (int i = 0; i < text.length(); i++) { - result.push_back(number_to_word(text[i] - '0')); - std::cout << number_to_word(text[i] - '0') << std::endl; + std::vector parts = split_into_threes(text); + std::vector suffixes = { + "thousand", + "million", + "billion", + "trillion", + "quadrillion", + "quintillion", + "sextillion", + "septillion", + "octillion", + "nonillion", + "decillion" + }; + + for (int i = 0; i < parts.size(); i++) { + int number = std::stoi(parts[i]); + result.push_back(hundreds_to_words(number)); + + if (i > 0 && i < suffixes.size()) { + result.back() += " " + suffixes[i - 1]; + } } return result; diff --git a/src/phonemizer.cpp b/src/phonemizer.cpp index 95acf5e..4968ec8 100644 --- a/src/phonemizer.cpp +++ b/src/phonemizer.cpp @@ -224,9 +224,11 @@ namespace DeepPhonemizer { std::vector number_words = numbers_to_words(word); for (const auto& number_word : number_words) { + std::cout << number_word << " "; word_phonemes = g2p_internal(number_word); phonemes.insert(phonemes.end(), word_phonemes.begin(), word_phonemes.end()); } + std::cout << std::endl; } else { word_phonemes = g2p_internal(word);