B4J Question B4J VOSK with Greek input/language...

Magma

Expert
Licensed User
Longtime User
Hi there...

I ve found here the VOSK a b4j snippet... that works:

I am downloading greek model... but the text result returns is unreadable..

when i say "test"
in greek "τεστ"

For example returns:
"της"

but the right is to return "τεστ" or "test"

Thought was something like charset for java jdk 19

So I ve added at start:
#VirtualMachineArgs: -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.stderr.encoding=UTF-8
#PackagerProperty: VMArgs = -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.stderr.encoding=UTF-8

but nothing better ... then tried to add some lines at java code to convert charset - getting different result - but none is the right...

B4X:
    import java.nio.charset.Charset;
    private final Charset UTF8_CHARSET = Charset.forName("UTF-8");
    private final Charset PREVIOUSCHARSET = Charset.forName("ISO-8859-1");
....
                        byte ptext[] = resultText.getBytes(PREVIOUSCHARSET);
                        String ppv = new String(ptext, UTF8_CHARSET);
                        subQvEvent("recognition_result", ppv);


... what do you think ?
 
Solution
Well, found the problem ...was java jdk 19...

going back to JAVA 11 - all works perfect !



tried the following to java inline - was someway better (with java19)- not the best:
B4X:
import javax.sound.sampled.*;

public static class AudioCapture {

    private AudioFormat format;
    private float sampleRate;
    private int sampleSizeInBits;
    private int channels;
    private org.vosk.Recognizer recognizer;
  
    import java.nio.charset.Charset;
    private final Charset UTF8_CHARSET = Charset.forName("UTF-8");
    private final Charset PREVIOUSCHARSET = Charset.forName("CP1253");

    public AudioCapture(float sampleRate, int sampleSizeInBits, int channels, org.vosk.Recognizer recognizer) {
        this.sampleRate =...

Magma

Expert
Licensed User
Longtime User
Well, found the problem ...was java jdk 19...

going back to JAVA 11 - all works perfect !



tried the following to java inline - was someway better (with java19)- not the best:
B4X:
import javax.sound.sampled.*;

public static class AudioCapture {

    private AudioFormat format;
    private float sampleRate;
    private int sampleSizeInBits;
    private int channels;
    private org.vosk.Recognizer recognizer;
  
    import java.nio.charset.Charset;
    private final Charset UTF8_CHARSET = Charset.forName("UTF-8");
    private final Charset PREVIOUSCHARSET = Charset.forName("CP1253");

    public AudioCapture(float sampleRate, int sampleSizeInBits, int channels, org.vosk.Recognizer recognizer) {
        this.sampleRate = sampleRate;
        this.sampleSizeInBits = sampleSizeInBits;
        this.channels = channels;
        this.recognizer = recognizer;
        this.format = new AudioFormat(sampleRate, sampleSizeInBits, channels, true, false);
        subQvEvent("logs", "AudioCapture initialized with sampleRate: " + sampleRate + ", sampleSizeInBits: " + sampleSizeInBits + ", channels: " + channels);
    }

    private TargetDataLine line;
    private boolean running = false;

    public void startRecording() {
        subQvEvent("logs", "Start recording...");
      
        try {
            DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
            if (!AudioSystem.isLineSupported(info)) {
                subQvEvent("logs", "Line not supported");
                return;
            } else {
                subQvEvent("logs", "Line supported");
            }

            line = (TargetDataLine) AudioSystem.getLine(info);
            line.open(format);
            line.start();
            running = true;

            new Thread(() -> {
                byte[] buffer = new byte[1024];
                while (running) {
                    int numRead = line.read(buffer, 0, buffer.length);
                    if (numRead > 0) {
                        boolean result = recognizer.acceptWaveForm(buffer, numRead);
                        String resultText;
                        if (result) {
                            resultText = recognizer.getResult();
                        } else {
                            resultText = recognizer.getPartialResult();
                        }
                        byte ptext[] = resultText.getBytes(PREVIOUSCHARSET);
                        String ppv = new String(ptext, UTF8_CHARSET);
                        subQvEvent("recognition_result", ppv);
                    }
                }
                line.drain();
                line.close();
                subQvEvent("logs", "Recording stopped.");
            }).start();
        } catch (LineUnavailableException e) {
            subQvEvent("logs", "Line unavailable: " + e.getMessage());
        }
    }

    public void stopRecording() {
        subQvEvent("logs", "Stopping recording...");
        running = false;
        if (line != null) {
            line.stop();
            line.close();
            line = null;
        }
    }

    private void subQvEvent(String eventName, Object data) {
        ba.raiseEventFromUI(null, eventName.toLowerCase() + "_qv", new Object[]{data});
    }
}

add to "previous code of Douglas" those four lines (as you can see) :
private final Charset UTF8_CHARSET = Charset.forName("UTF-8");
private final Charset PREVIOUSCHARSET = Charset.forName("CP1253");

...
byte ptext[] = resultText.getBytes(PREVIOUSCHARSET);
String ppv = new String(ptext, UTF8_CHARSET);
subQvEvent("recognition_result", ppv);



but without changing anything from the first code with java 11... works super!
 
Upvote 0
Solution

aeric

Expert
Licensed User
Longtime User
inei peroho 😅

Should be good on JDK 14.

1739379188606.png
 
Upvote 0
Top