Наконец-то я исправил проблему.Оказывается, что AudioTrack
не любит несогласованные объемы данных, записываемых в него, и вызывает статический шум из-за этого.Это была последовательность подсчета байтов, которая была записана в AudioTrack
ранее, которая вызывала проблему 1248
, 3439
, 5152
, 5152
, 3834
, ..., 823
(Несогласовано).Итак, я посмотрел на readFully
метод DataInputStream
и использовал его, и это устранило проблему статического шума.Последовательность подсчета байтов теперь выглядела как 5152
, 5152
, 5152
, ..., 5152
(согласованно).Но теперь проблема состояла в том, чтобы прочитать оставшиеся байты, которые были пропущены из-за EOFException
.Поэтому мне пришлось реализовать свои собственные методы, чтобы это исправить.
public class TTSInputStream extends DataInputStream {
public TTSInputStream(InputStream in) {
super(in);
}
public final int readFullyUntilEof(byte b[]) throws IOException {
return readFullyUntilEof(b, 0, b.length);
}
public final int readFullyUntilEof(byte b[], int off, int len) throws IOException {
if (len < 0)
throw new IndexOutOfBoundsException();
int n = 0;
while (n < len) {
int count = in.read(b, off + n, len - n);
if (count < 0)
break;
n += count;
}
return n;
}
}
Мой окончательный код теперь выглядит так:
new Thread(
new Runnable() {
@Override
public void run() {
try {
URI uri = URI.create("http://192.168.1.6:5000/api/tts");
HttpURLConnection urlConnection = (HttpURLConnection) uri.toURL().openConnection();
urlConnection.setRequestMethod("POST");
urlConnection.setRequestProperty("Content-Type", "application/json");
urlConnection.setRequestProperty("x-access-token", credentials.getAccessToken());
urlConnection.setRequestProperty("Accept", "*");
urlConnection.setChunkedStreamingMode(bufferSize);
urlConnection.setDoInput(true);
urlConnection.setDoOutput(true);
urlConnection.connect();
OutputStreamWriter osw = new OutputStreamWriter(urlConnection.getOutputStream());
String body = "{\"text\": \"" + text + "\", \"ttsLang\": \"" + language + "\"}";
Log.d("TTS_HTTP", body);
osw.write(body);
osw.flush();
osw.close();
Log.d("TTS_OUT", credentials.getAccessToken());
Log.d("TTS_OUT", urlConnection.getResponseCode() + " " + urlConnection.getResponseMessage());
// define the buffer size for audio track
int SAMPLE_RATE = 16000;
int bufferSize = AudioTrack.getMinBufferSize(SAMPLE_RATE, AudioFormat.CHANNEL_OUT_MONO,
AudioFormat.ENCODING_PCM_16BIT);
if (bufferSize == AudioTrack.ERROR || bufferSize == AudioTrack.ERROR_BAD_VALUE) {
bufferSize = SAMPLE_RATE * 2;
}
bufferSize *= 2;
TTSInputStream bis = new TTSInputStream(urlConnection.getInputStream());
AudioTrack audioTrack = new AudioTrack(
AudioManager.STREAM_MUSIC,
SAMPLE_RATE,
AudioFormat.CHANNEL_OUT_MONO,
AudioFormat.ENCODING_PCM_16BIT,
bufferSize * 2,
AudioTrack.MODE_STREAM);
byte[] buffer = new byte[bufferSize];
audioTrack.play();
int count;
while ((count = bis.readFullyUntilEof(buffer)) > 0) {
Log.d("TTS_COUNT", "Read " + count + " bytes.");
audioTrack.write(buffer, 0, buffer.length);
}
bis.close();
audioTrack.stop();
audioTrack.release();
} catch (IOException e) {
e.printStackTrace();
}
}
}
).start();
Теперь мой звук воспроизводится хорошо без каких-либо статических помех.Надеюсь, это поможет кому-то, у кого такая же проблема, как и у меня.