Skip to content

Commit

Permalink
减少了音频播放的间隔
Browse files Browse the repository at this point in the history
  • Loading branch information
Voine committed Feb 23, 2023
1 parent d6c9ef7 commit 1827573
Show file tree
Hide file tree
Showing 6 changed files with 116 additions and 69 deletions.
4 changes: 2 additions & 2 deletions ChatGPT/src/main/java/com/chatwaifu/chatgpt/ChatGPTData.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ data class ChatGPTRequestData(
) {
companion object {
private const val DEFAULT_MODEL = "text-davinci-003"
private const val DEFAULT_TEMPERATURE = 0
private const val DEFAULT_MAX_TOKENS = 50
private const val DEFAULT_TEMPERATURE = 1
private const val DEFAULT_MAX_TOKENS = 2048
}

fun toRequestBody(): RequestBody {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import retrofit2.Callback
import retrofit2.Response
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.util.concurrent.TimeUnit

/**
* Description: ChatGPTNetService
Expand All @@ -19,6 +20,7 @@ class ChatGPTNetService(val context: Context) {
companion object {
private const val TAG = "ChatGPTNetService"
private const val CHATGPT_BASE_URL = "https://api.openai.com/"
private const val TIME_OUT_SECOND = 100L
}

private val interceptor = ChatGPTInterceptor()
Expand Down Expand Up @@ -62,6 +64,9 @@ class ChatGPTNetService(val context: Context) {

private fun createClient(): OkHttpClient {
return OkHttpClient.Builder().run {
readTimeout(TIME_OUT_SECOND, TimeUnit.SECONDS)
connectTimeout(TIME_OUT_SECOND,TimeUnit.SECONDS)
writeTimeout(TIME_OUT_SECOND, TimeUnit.SECONDS)
addInterceptor(interceptor)
build()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,15 @@ class BaiduTranslateService(

override fun getTranslateResult(input: String, callback: (result: String?) -> Unit) {
if (appid == null || privateKey == null) {
return
return callback.invoke(null)
}
sign = DigestUtils.md5("$appid$input$salt$privateKey")
val startIndex = input.indexOfFirst { it.isLetterOrDigit() }
val endIndex = input.indexOfLast { it.isLetterOrDigit() }
val realInput = input.substring(startIndex, endIndex + 1).trimIndent()

sign = DigestUtils.md5("$appid$realInput$salt$privateKey")
val call = baiduNetService.getTranslateResult(
input,
realInput,
fromLanguage,
toLanguage,
appid!!,
Expand Down
80 changes: 80 additions & 0 deletions VITS/src/main/java/com/chatwaifu/vits/SoundPlayHandler.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package com.chatwaifu.vits

import android.media.AudioAttributes
import android.media.AudioFormat
import android.media.AudioTrack
import android.os.Handler
import android.os.HandlerThread
import android.os.Message
import android.util.Log

/**
* Description: SoundPlayHandler
* Author: Voine
* Date: 2023/2/23
*/
class SoundPlayHandler {
private val handler: Handler
private var audioTrack: AudioTrack? = null
private var sampleRate = 22050 // default sample rate
private var channels = AudioFormat.CHANNEL_OUT_MONO // default channels
private var audioFormat = AudioFormat.ENCODING_PCM_FLOAT
private var bufferSize = 0

init {
val handlerThread = HandlerThread("SoundPlayHandler")
handlerThread.start()
handler = object : Handler(handlerThread.looper) {
override fun handleMessage(msg: Message) {
onHandleMessage(msg)
}
}
bufferSize = AudioTrack.getMinBufferSize(sampleRate, channels, audioFormat)
if (bufferSize <= 0) throw Exception("AudioTrack不可用!")
audioTrack = AudioTrack.Builder()
.setAudioAttributes(
AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_MEDIA)
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.build()
)
.setTransferMode(AudioTrack.MODE_STREAM)
.setAudioFormat(
AudioFormat.Builder()
.setEncoding(audioFormat)
.setChannelMask(channels)
.setSampleRate(sampleRate).build()
)
.setBufferSizeInBytes(bufferSize).build()
audioTrack?.play()
}

fun setTrackData(sr: Int, ch: Int) {
if (ch == 2) channels = AudioFormat.CHANNEL_OUT_STEREO
if (ch > 2 || ch < 0) throw Exception("不支持的通道数$ch")
if (sampleRate <= 0) throw Exception("不支持的采样率$sr")
sampleRate = sr
Log.i("AudioTrack", "sampling rate:$sr channels:$ch")
}

fun sendSound(floatArray: FloatArray) {
handler.sendMessage(Message.obtain(handler, 0, floatArray))
}

fun onHandleMessage(msg: Message) {
val sound = msg.obj as FloatArray
try {
Log.d(TAG, "try to write arr....")
audioTrack?.write(sound, 0, sound.size, AudioTrack.WRITE_BLOCKING)
} catch (e: Exception) {
e.printStackTrace()
}
}

fun release() {
audioTrack?.release()
}
companion object {
private const val TAG = "SoundPlayHandler"
}
}
66 changes: 18 additions & 48 deletions VITS/src/main/java/com/chatwaifu/vits/utils/SoundGenerateHelper.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ package com.chatwaifu.vits.utils
import android.annotation.SuppressLint
import android.content.Context
import android.util.Log
import com.chatwaifu.vits.SoundPlayHandler
import com.chatwaifu.vits.Vits
import com.chatwaifu.vits.data.Config
import com.chatwaifu.vits.utils.audio.PlayerUtils
import com.chatwaifu.vits.utils.file.FileUtils
import com.chatwaifu.vits.utils.text.ChineseTextUtils
import com.chatwaifu.vits.utils.text.JapaneseTextUtils
Expand All @@ -21,10 +21,8 @@ class SoundGenerateHelper(val context: Context) {
private const val TAG = "SoundGenerateHelper"
}

private val audioArray = ArrayList<Float>()
private var textUtils: TextUtils? = null
private var config: Config? = null
private val playerUtils = PlayerUtils()
private var samplingRate = 22050
private var n_vocab: Int = 0
private var maxSpeaker = 1
Expand All @@ -39,6 +37,9 @@ class SoundGenerateHelper(val context: Context) {
private val currentThreadCount: Int by lazy {
VitsUtils.checkThreadsCpp()
}
private val soundHandler: SoundPlayHandler by lazy {
SoundPlayHandler()
}

// load config file
fun loadConfigs(path: String?, callback: (isSuccess: Boolean) -> Unit) {
Expand Down Expand Up @@ -73,8 +74,7 @@ class SoundGenerateHelper(val context: Context) {
if (textUtils == null) {
throw RuntimeException("暂不支持${cleanerName}")
}

playerUtils.setTrackData(config!!.data!!.sampling_rate!!, 1)
soundHandler.setTrackData(config!!.data!!.sampling_rate!!, 1)
callback.invoke(true)
} else {
callback.invoke(false)
Expand Down Expand Up @@ -125,43 +125,29 @@ class SoundGenerateHelper(val context: Context) {

// processing inputs
@SuppressLint("SetTextI18n")
fun generate(text: String?, callback: (isSuccess: Boolean) -> Unit) {
fun generateAndPlay(text: String?, callback: (isSuccess: Boolean) -> Unit) {
text ?: return callback.invoke(false)
audioArray.clear()
try {
// convert inputs
val inputs = textUtils?.convertText(text)

if (inputs != null && inputs.isNotEmpty()) {

// inference for each sentence
for (i in inputs.indices) {
// start inference
val output =
Vits.forward(
inputs[i],
vulkan = false,
multi,
sid,
noiseScale,
noiseScaleW,
lengthScale,
currentThreadCount
)

if (output != null) {
audioArray.addAll(output.toList())
Vits.forward(
inputs[i],
vulkan = false,
multi,
sid,
noiseScale,
noiseScaleW,
lengthScale,
currentThreadCount
)?.let {
soundHandler.sendSound(it)
}
}

// prepare data
playerUtils.createAudioTrack(audioArray.toFloatArray())

// show play button and export button
if (audioArray.isEmpty()) {
Log.e(TAG, "audio arr is empty")
return callback.invoke(false)
}
return callback.invoke(true)
}
} catch (e: Exception) {
Expand All @@ -171,26 +157,10 @@ class SoundGenerateHelper(val context: Context) {
}
}


fun play() {
if (!playerUtils.isPlaying) {
playerUtils.start()
} else {
playerUtils.stop()
}
}

fun stop() {
if (playerUtils.isPlaying) {
playerUtils.stop()
}
}

fun clear() {
playerUtils.stop()
soundHandler.release()
modelInitState = false
config = null
audioArray.clear()
Log.i("helper", "cleared!")
}
}
20 changes: 4 additions & 16 deletions app/src/main/java/com/chatwaifu/mobile/ChatActivityViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,7 @@ class ChatActivityViewModel: ViewModel() {
val translateText = fetchTranslateIfNeed(responseText)

chatStatusLiveData.postValue(ChatStatus.GENERATE_SOUND)
generateSound(translateText)

chatStatusLiveData.postValue(ChatStatus.PLAY_SOUND)
playSound()
generateAndPlaySound(translateText)
}
}
}
Expand Down Expand Up @@ -167,21 +164,12 @@ class ChatActivityViewModel: ViewModel() {
}
}

private suspend fun generateSound(needPlayText: String?) {
val result = suspendCancellableCoroutine {
vitsHelper.stop()
vitsHelper.generate(needPlayText) { isSuccess ->
it.safeResume(isSuccess)
}
private fun generateAndPlaySound(needPlayText: String?) {
vitsHelper.generateAndPlay(needPlayText){ isSuccess ->
Log.d(TAG, "generate sound $isSuccess")
}
generateSoundLiveData.postValue(result)
return
}

private fun playSound() {
vitsHelper.stop()
vitsHelper.play()
}

override fun onCleared() {
vitsHelper.clear()
Expand Down

0 comments on commit 1827573

Please sign in to comment.