utf8: normalize inbound text bytes to UTF-8
Same gap as omnivoice.cpp: the UTF-8 boundary covers argv, console output, and fopen but not the bytes arriving from stdin or text files. Windows shells and editors hand those over as UTF-16 with BOM (PowerShell redirection, Notepad, Out-File) or the ANSI codepage (cmd pipes), and the raw bytes reach the tokenizer as garbage. utf8_normalize() closes the gap: UTF-8 BOM stripped on every platform, UTF-16 BOM losslessly recoded to UTF-8, bytes failing UTF-8 validation decoded from the ANSI codepage. Valid UTF-8 passes through untouched. Wired into read_stdin_text (binary mode stdin so CRLF translation cannot eat UTF-16 0x0D bytes) and read_text_file, which also moves from raw fopen to utf8_fopen so a non-ASCII --ref-text path opens.
This commit is contained in:
+17
-4
@@ -14,6 +14,7 @@
|
||||
#include "audio-io.h"
|
||||
#include "qwen.h"
|
||||
#include "rvq-file.h"
|
||||
#include "utf8.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
@@ -23,6 +24,11 @@
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#if defined(_WIN32)
|
||||
# include <fcntl.h>
|
||||
# include <io.h>
|
||||
#endif
|
||||
|
||||
static void print_usage(const char * prog) {
|
||||
fprintf(stderr, "qwentts.cpp %s\n\n", qt_version());
|
||||
fprintf(stderr,
|
||||
@@ -98,19 +104,25 @@ struct Args {
|
||||
float codec_left_context_sec;
|
||||
};
|
||||
|
||||
// Read all of stdin into a string. Trims trailing newlines so a piped
|
||||
// text file behaves like clean utterance input.
|
||||
// Read all of stdin into a string. Binary mode on Windows so UTF-16 input
|
||||
// survives CRLF translation, then normalised to UTF-8. Trims trailing
|
||||
// newlines so a piped text file behaves like clean utterance input.
|
||||
static std::string read_stdin_text() {
|
||||
#if defined(_WIN32)
|
||||
_setmode(_fileno(stdin), _O_BINARY);
|
||||
#endif
|
||||
std::ostringstream ss;
|
||||
ss << std::cin.rdbuf();
|
||||
std::string s = ss.str();
|
||||
utf8_normalize(s);
|
||||
while (!s.empty() && (s.back() == '\n' || s.back() == '\r')) {
|
||||
s.pop_back();
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
// Read a small text file into a string. Trims trailing newlines.
|
||||
// Read a small text file into a string, normalised to UTF-8.
|
||||
// Trims trailing newlines.
|
||||
// 11 bits per code (V <= 2048), matching qwen-codec.
|
||||
static const int RVQ_CODE_BITS = 11;
|
||||
|
||||
@@ -140,7 +152,7 @@ static bool read_spk_file(const char * path, std::vector<float> & emb) {
|
||||
}
|
||||
|
||||
static bool read_text_file(const char * path, std::string & out) {
|
||||
FILE * f = fopen(path, "rb");
|
||||
FILE * f = utf8_fopen(path, "rb");
|
||||
if (!f) {
|
||||
fprintf(stderr, "[CLI] FATAL: cannot open '%s'\n", path);
|
||||
return false;
|
||||
@@ -160,6 +172,7 @@ static bool read_text_file(const char * path, std::string & out) {
|
||||
return false;
|
||||
}
|
||||
fclose(f);
|
||||
utf8_normalize(out);
|
||||
while (!out.empty() && (out.back() == '\n' || out.back() == '\r')) {
|
||||
out.pop_back();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user