Compare commits
2 Commits
master
...
StreamingO
| Author | SHA1 | Date | |
|---|---|---|---|
| f17c6ab84e | |||
| cce093db4e |
@@ -11,7 +11,7 @@ android {
|
|||||||
applicationId = "net.mmanningau.speechtokeyboard"
|
applicationId = "net.mmanningau.speechtokeyboard"
|
||||||
minSdk = 28
|
minSdk = 28
|
||||||
targetSdk = 36
|
targetSdk = 36
|
||||||
versionCode = 9
|
versionCode = 10
|
||||||
versionName = "1.0"
|
versionName = "1.0"
|
||||||
|
|
||||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||||
@@ -25,6 +25,11 @@ android {
|
|||||||
"proguard-rules.pro"
|
"proguard-rules.pro"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
debug {
|
||||||
|
applicationIdSuffix = ".streaming"
|
||||||
|
// This changes the app name on your homescreen to "MyApp (Dev)"
|
||||||
|
resValue("string", "app_name", "Speech To Keyboard (Streaming)")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
compileOptions {
|
compileOptions {
|
||||||
sourceCompatibility = JavaVersion.VERSION_11
|
sourceCompatibility = JavaVersion.VERSION_11
|
||||||
|
|||||||
BIN
app/src/main/ic_launcher-playstore.png
Normal file
|
After Width: | Height: | Size: 411 KiB |
@@ -140,9 +140,12 @@ class TestModelActivity : AppCompatActivity() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset the stream for a new session
|
// FIX 1: CLEAR THE BUFFER
|
||||||
// Note: Sherpa streams can be persistent, but resetting ensures clean start
|
// This prevents the "ghost text" from the previous session appearing
|
||||||
// If you want continuous conversation, don't reset 'committedText'
|
// when you hit record again.
|
||||||
|
stream?.let { activeStream ->
|
||||||
|
recognizer?.reset(activeStream)
|
||||||
|
}
|
||||||
|
|
||||||
isRecording = true
|
isRecording = true
|
||||||
micButton.setColorFilter(android.graphics.Color.RED)
|
micButton.setColorFilter(android.graphics.Color.RED)
|
||||||
@@ -168,9 +171,7 @@ class TestModelActivity : AppCompatActivity() {
|
|||||||
val sampleRate = 16000
|
val sampleRate = 16000
|
||||||
val bufferSize = AudioRecord.getMinBufferSize(sampleRate, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT)
|
val bufferSize = AudioRecord.getMinBufferSize(sampleRate, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT)
|
||||||
|
|
||||||
// 1. GUARD CLAUSE: Unpack nullables safely
|
// Guard clauses
|
||||||
// If recognizer or stream are null, we stop immediately.
|
|
||||||
// This creates 'localRec' and 'localStream' which are GUARANTEED non-null.
|
|
||||||
val localRec = recognizer ?: return
|
val localRec = recognizer ?: return
|
||||||
val localStream = stream ?: return
|
val localStream = stream ?: return
|
||||||
|
|
||||||
@@ -188,7 +189,6 @@ class TestModelActivity : AppCompatActivity() {
|
|||||||
if (ret > 0) {
|
if (ret > 0) {
|
||||||
val samples = FloatArray(ret) { buffer[it] / 32768.0f }
|
val samples = FloatArray(ret) { buffer[it] / 32768.0f }
|
||||||
|
|
||||||
// 2. Use the LOCAL (non-null) variables
|
|
||||||
localStream.acceptWaveform(samples, sampleRate)
|
localStream.acceptWaveform(samples, sampleRate)
|
||||||
|
|
||||||
while (localRec.isReady(localStream)) {
|
while (localRec.isReady(localStream)) {
|
||||||
@@ -201,13 +201,25 @@ class TestModelActivity : AppCompatActivity() {
|
|||||||
if (text.isNotEmpty()) {
|
if (text.isNotEmpty()) {
|
||||||
val cleanText = text.lowercase()
|
val cleanText = text.lowercase()
|
||||||
|
|
||||||
runOnUiThread {
|
|
||||||
if (isEndpoint) {
|
if (isEndpoint) {
|
||||||
|
// FIX 2: THE ORDER OF OPERATIONS
|
||||||
|
|
||||||
|
// A. Update UI first
|
||||||
|
runOnUiThread {
|
||||||
committedText += "$cleanText "
|
committedText += "$cleanText "
|
||||||
outputText.text = committedText
|
outputText.text = committedText
|
||||||
sendToPico("$cleanText ")
|
sendToPico("$cleanText ")
|
||||||
|
}
|
||||||
|
|
||||||
|
// B. RESET IMMEDIATELY ON BACKGROUND THREAD
|
||||||
|
// We do this HERE, not inside runOnUiThread.
|
||||||
|
// This guarantees the stream is clean BEFORE the loop
|
||||||
|
// reads the next chunk of audio.
|
||||||
localRec.reset(localStream)
|
localRec.reset(localStream)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
// Standard partial update
|
||||||
|
runOnUiThread {
|
||||||
outputText.text = "$committedText $cleanText"
|
outputText.text = "$committedText $cleanText"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
5
app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<background android:drawable="@color/ic_launcher_background"/>
|
||||||
|
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
||||||
|
</adaptive-icon>
|
||||||
5
app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<background android:drawable="@color/ic_launcher_background"/>
|
||||||
|
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
||||||
|
</adaptive-icon>
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<background android:drawable="@drawable/ic_launcher_background" />
|
|
||||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
|
||||||
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
|
|
||||||
</adaptive-icon>
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<background android:drawable="@drawable/ic_launcher_background" />
|
|
||||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
|
||||||
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
|
|
||||||
</adaptive-icon>
|
|
||||||
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 3.9 KiB |
BIN
app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp
Normal file
|
After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 5.7 KiB |
|
Before Width: | Height: | Size: 982 B After Width: | Height: | Size: 2.3 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp
Normal file
|
After Width: | Height: | Size: 5.7 KiB |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 6.2 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp
Normal file
|
After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 8.5 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 12 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp
Normal file
|
After Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 19 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp
Normal file
|
After Width: | Height: | Size: 79 KiB |
|
Before Width: | Height: | Size: 7.6 KiB After Width: | Height: | Size: 25 KiB |
4
app/src/main/res/values/ic_launcher_background.xml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<color name="ic_launcher_background">#0878F5</color>
|
||||||
|
</resources>
|
||||||