niedziela, października 11, 2009

JNI i łańcuchy ;-)

Kto by przypuszczał, że najtrudniejszą sprawą w sprzężeniu Java'y z syntezatorami mowy pracującymi w oparciu o DDE okaże się kodowanie znaków? :-)

Ugryzienie połączenia między Nowym Gadaczem, a syntezatorami mowy na DDE [czyli Systemem Syntezy Mowy WP, UniSpikerem/Spikerem, SynTalkiem, ale też Expressivo :-)] to sprawa użycia JNI (Java Native Interface) i włączenie wygenerowanego przez Java'ę pliku nagłówkowego do projektu w C, ale problemy zaczęły się na sprawie polskich znaków.

Java łańcuchy tekstowe trzyma w UTF-8, co jest dobre i słuszne. Windows jest tutaj bardziej szalony, bo używa zwykle Windows-1250 a czasem Unicode. Do tego DDE dodaje jeszcze swoje własne wariactwa.

Pierwsze podejście polegające na przekazywaniu Java'owego String'a do kodu w C, działa ale syntezatory głupieją na polskich znakach.
JNIEXPORT void JNICALL Java_pl_przemelek_gadacz_tts_DDE_speakViaDDE(JNIEnv * env, jobject obj, jint currentSpeachSynthezier, jstring string) {
const char *str = (*env)->GetStringUTFChars(env, string, 0);


Myślałem o przekodowywaniu znaków, ale to też nie jest najlepszy pomysł.

Na razie okazuje się, że najlepiej przesyłać do JNI łańcuch w postaci tablicy znaków utworzonej w taki sposób:
public void speak(String text) throws SpeachException {
text+=(char)0;
speakViaDDE(currentSpeachSynthezier,text.getBytes());
}

Dodanie zrzutowanego na typ char zera daje nam pewność, że tablica będzie zakończona zerem jak to lubi C w przypadku łańcuchów ;-)

Pod koniec zaś pracy z łańcuchem w C, dla pewności wołamy ReleaseByteArrayElements :-)


Podobne postybeta
C# miewa swoje plusy ;-)
Sekrety klasy String ;-)
Nowy Gadacz v0.6 - gadamy przez DDE ;-)
Pomysł
Nowy Gadacz - raport z prac