I have an aar file that can convert text into multiple dialects, I tested it in Android Studio and it works fine, but when I run in B4A with JavaObject, there is no error, but there is no sound.
The entry class is not an ordinary class, it implements SynthesisCallback (import android.speech.tts.SynthesisCallback
, I think the problem should be here, I want to use JavaObject, but don't know how to do it,my code is as follows:
In Java:
In B4A:
I have spent a lot of time looking for the reason, hope to get your help, thanks in advance.
Sorry, don't move to "Libraries developers questions", where almost nobody noticed.
The entry class is not an ordinary class, it implements SynthesisCallback (import android.speech.tts.SynthesisCallback
In Java:
Entry class:
import android.annotation.SuppressLint;
import android.content.Context;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.os.SystemClock;
import android.speech.tts.SynthesisCallback;
import android.util.Log;
import com.iflytek.business.SpeechConfig;
import com.iflytek.speechcloud.TtsService;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class TTS implements SynthesisCallback {
private ExecutorService executorService;
private AudioTrack audioTrack;
private TtsService ttsService;
@SuppressLint("StaticFieldLeak")
private static volatile TTS singleton;
private volatile int rate = 100;
private volatile int tone = 8000;
private Context context;
private volatile boolean loop = true;
private Queue<String> textQueue;
private volatile String text = null;
private volatile boolean isFlush = false;
public static TTS getInstance() {
if (singleton == null) {
synchronized (TTS.class) {
if (singleton == null) {
singleton = new TTS();
}
}
}
return singleton;
}
public TTS() {
if (textQueue == null)
textQueue = new ConcurrentLinkedQueue<>();
if (executorService == null)
executorService = Executors.newFixedThreadPool(2);
if (audioTrack == null) {
audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
16000,
AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT,
AudioTrack.getMinBufferSize(16000, AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT)
, AudioTrack.MODE_STREAM);
audioTrack.play();
}
executorService.execute(() -> {
while (loop) {
text = textQueue.poll();
if (text != null) {
ttsService.onSynthesizeText(text, rate, this);
}
SystemClock.sleep(50L);
}
});
}
public void init(Context context, String speaker, int rate, int tone) {
setRate(rate);
setTone(tone);
init(context, speaker);
}
public void init(Context context, String speaker) {
this.context = context.getApplicationContext();
SpeechConfig.putString(this.context, SpeechConfig.KEY_SPEAKER_SETTING, speaker);
if (ttsService == null) {
ttsService = new TtsService();
ttsService.onCreate(this.context);
}
}
public void init(Context context) {
init(context,TTSConstants.TTS_XIAOFENG);
}
public void speakText(String text) {
textQueue.offer(text);
audioTrack.play();
}
@Override
public int getMaxBufferSize() {
return 0;
}
@Override
public int start(int sampleRateInHz, int audioFormat, int channelCount) {
return 0;
}
@Override
public int audioAvailable(byte[] buffer, int offset, int length) {
audioTrack.setPlaybackRate(tone);
audioTrack.write(buffer, offset, length);
return 0;
}
@Override
public int done() {
return 0;
}
@Override
public boolean hasStarted() {
return false;
}
@Override
public boolean hasFinished() {
return false;
}
public int getRate() {
return rate;
}
public void setRate(int rate) {
this.rate = rate;
}
public int getTone() {
return tone;
}
public void setTone(int tone) {
this.tone = tone;
}
}
In B4A:
Play:
#AdditionalJar:xftts.aar
Sub Process_Globals
Private xui As XUI
End Sub
Sub Activity_Create(FirstTime As Boolean)
Activity.LoadLayout("Layout")
GetTTS.RunMethodJO("init", Array(GetContext))
End Sub
Sub Activity_Resume
End Sub
Sub GetTTS As JavaObject
Dim jo As JavaObject
Return jo.InitializeNewInstance("com.iflytek.TTS",Null).RunMethodJO("getInstance", Null)
End Sub
Sub GetContext As JavaObject
Return GetBA.GetField("context")
End Sub
Sub GetBA As JavaObject
Dim jo As JavaObject
Dim cls As String = Me
cls = cls.SubString("class ".Length)
jo.InitializeStatic(cls)
Return jo.GetFieldJO("processBA")
End Sub
Sub Button1_Click
Dim ttt As String
ttt="this is test"
GetTTS.RunMethodJO("speakText", Array(ttt))
End Sub
I have spent a lot of time looking for the reason, hope to get your help, thanks in advance.
Sorry, don't move to "Libraries developers questions", where almost nobody noticed.
Last edited: