目次
テキストをオーディオに変換
1. はじめに
このタスクはとっくの昔に完了しているはずなのですが、それまでに良いアイデアが見つからず、他にも毎日やらなければならないタスクがあり、ぐるぐる回って今日まで引きずっていました。このアイデアは、放課後の課題「ソフトウェア開発技術と応用」から生まれました。当時、「C++入門 5」という本を読んでいましたが、文法書を読むのは退屈だと常々感じていました。できるまで C++ について考えました。なぜなら、勉強を続けることができなかったとき、この宿題を思い出しました。C++ で簡単なテキスト読み上げプログラムを作成できます。他の言語で実装するのは簡単かもしれませんし、インターネット上にはより多くの参考資料が存在しますが、盲目的な強迫観念が常に存在しているのかもしれません。そこで、C++ による音声合成の作成に関する情報を必死に探しましたが、そのほとんどはパッケージ化された TTS および Microsoft 音声開発キットでした。これらはすべてオープン ソースですが、記述されたコードを理解するのは困難です。最終的にはTTSなどのソースコードを見て真似して書きたかったのですが、時間がないどころか短時間では無理で、結局のところ頑張った人には神様がご褒美をくれる、そして大神様に助けてもらって、ふと自分の考えが実は少し偏っていたことに気づきましたが、実はとてもシンプルでした!
そこで、この開発プロセスを記念し、将来の思い出として残しておくために、この記事を書きました。今後も少しずつ改善していけると思いますので、皆さんアドバイスをいただければ幸いです!
2. 要件
- 単純な「音声合成」プログラムを実装します。TTS などの「音声合成」開発キットを直接呼び出すことはできません。
- 音声素材は自分で録音する必要があります
- プログラムはユーザーが入力したテキストを受け取り、それを独自の録音に変換して再生できます。
3. 分析と実装
このプログラムは、テキスト読み上げプログラムの簡易版を実装しています。つまり、数字の列を音声に変換してブロードキャストすることだけを実現しています。このプログラムの実装の主な手順は次のとおりです (少しでもヒントになれば幸いです)。
1. まず各数字の発音を 1 つの MP3 ファイルに録音し、保存します。
2. プログラムは、まず入力テキストの前処理を行います。たとえば、テキスト内に数字以外の文字は使用できません。また、読み取れる整数の数が限られているため、10 を超える長さは文字列として読み取られると規定されています。単純な数字を 1 つずつコードの具体的な実装部分は次のとおりです。
std::vector<std::string> StringHandler::prase()
{
switch (flag) {
case 1: // 将字符串转化为一个长整数
{
long num = std::stol(sourceString);
if (num == 0) {
targetVector.push_back(posTable[0]);
}
else {
int pos = 0;
while (num != 0) {
targetVector.push_back(std::to_string(num % 10));
if (num / 10 != 0)
targetVector.push_back(posTable[++pos]);
num /= 10;
}
/*for (auto it = targetVector.rbegin(); it != targetVector.rend(); ++it)
std::cout << *it << " ";
std::cout << std::endl;*/
}
break;
}
case 2: //将每个字符转化为数字
{
for (int i = sourceString.size() - 1; i >= 0; --i)
targetVector.push_back(sourceString.substr(i, 1));
break;
}
case 0:
std::cout << "The length of source string is zero!" << std::endl;
break;
default:
std::cerr << "X error!" << std::endl;
}
return targetVector;
}
3. 変換された文字列をベクターコンテナに保存し、ベクター内の要素から音声ファイルへのマッピングを作成します。
std::string posTable[10] = { "0","10","100","1000","10000","100000","1000000","10000000","100000000","1000000000" };
4. 最後に、 mciSendString関数を使用して、変換された複数のオーディオ ファイルを順番に開きます (再生します)。
void TextPlayer::play(std::vector<std::string> &vec)
{
for (auto it = vec.rbegin(); it != vec.rend(); ++it) {
std::string comm = "play msc/" + *it + ".mp3 wait";
mciSendString(comm.c_str(), 0, 0, 0);
}
}
4. 概要と期待
このプログラムはまだ単純すぎて、アイデアは比較的単純ですが、前処理と音声再生の操作をクラスにカプセル化するなど、プログラミング スキルを可能な限り最適化するとともに、しばらく前に本を読んでいました バー!
次の作業は、テキスト読み上げ操作をさらに実現することです。貴重なご意見を残していただければ幸いです。私の個人的なレベルには限界があり、公には共有したくありませんでしたが、無実を分かち合うという原則に沿って、皆さんと一緒に前進していきたいと思っています(手を挙げてください~v~)!
5. 感謝の気持ち
ここで私は、上で述べた偉大な神に感謝したいと思います。一言で夢想家を本当に目覚めさせた私の先生(私は2333年の夢を見ていましたが)、この答えがまだあなたの目に入ることを願っています。
参考文献
2. ソースコード(メッセージを残してください)