diff --git a/app/build.gradle.kts b/app/build.gradle.kts index efcaf35..e79f5ae 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -11,7 +11,7 @@ android { applicationId = "net.mmanningau.speechtokeyboard" minSdk = 28 targetSdk = 36 - versionCode = 9 + versionCode = 10 versionName = "1.0" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" @@ -25,6 +25,11 @@ android { "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 { sourceCompatibility = JavaVersion.VERSION_11 diff --git a/app/src/main/ic_launcher-playstore.png b/app/src/main/ic_launcher-playstore.png new file mode 100644 index 0000000..c63de09 Binary files /dev/null and b/app/src/main/ic_launcher-playstore.png differ diff --git a/app/src/main/java/net/mmanningau/speechtokeyboard/TestModelActivity.kt b/app/src/main/java/net/mmanningau/speechtokeyboard/TestModelActivity.kt index a7ef7a3..02e91f4 100644 --- a/app/src/main/java/net/mmanningau/speechtokeyboard/TestModelActivity.kt +++ b/app/src/main/java/net/mmanningau/speechtokeyboard/TestModelActivity.kt @@ -140,9 +140,12 @@ class TestModelActivity : AppCompatActivity() { return } - // Reset the stream for a new session - // Note: Sherpa streams can be persistent, but resetting ensures clean start - // If you want continuous conversation, don't reset 'committedText' + // FIX 1: CLEAR THE BUFFER + // This prevents the "ghost text" from the previous session appearing + // when you hit record again. + stream?.let { activeStream -> + recognizer?.reset(activeStream) + } isRecording = true micButton.setColorFilter(android.graphics.Color.RED) @@ -168,9 +171,7 @@ class TestModelActivity : AppCompatActivity() { val sampleRate = 16000 val bufferSize = AudioRecord.getMinBufferSize(sampleRate, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT) - // 1. GUARD CLAUSE: Unpack nullables safely - // If recognizer or stream are null, we stop immediately. - // This creates 'localRec' and 'localStream' which are GUARANTEED non-null. + // Guard clauses val localRec = recognizer ?: return val localStream = stream ?: return @@ -188,7 +189,6 @@ class TestModelActivity : AppCompatActivity() { if (ret > 0) { val samples = FloatArray(ret) { buffer[it] / 32768.0f } - // 2. Use the LOCAL (non-null) variables localStream.acceptWaveform(samples, sampleRate) while (localRec.isReady(localStream)) { @@ -201,13 +201,25 @@ class TestModelActivity : AppCompatActivity() { if (text.isNotEmpty()) { val cleanText = text.lowercase() - runOnUiThread { - if (isEndpoint) { + if (isEndpoint) { + // FIX 2: THE ORDER OF OPERATIONS + + // A. Update UI first + runOnUiThread { committedText += "$cleanText " outputText.text = committedText sendToPico("$cleanText ") - localRec.reset(localStream) - } else { + } + + // 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) + + } else { + // Standard partial update + runOnUiThread { outputText.text = "$committedText $cleanText" } } diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml new file mode 100644 index 0000000..036d09b --- /dev/null +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml new file mode 100644 index 0000000..036d09b --- /dev/null +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi/ic_launcher.xml b/app/src/main/res/mipmap-anydpi/ic_launcher.xml deleted file mode 100644 index 6f3b755..0000000 --- a/app/src/main/res/mipmap-anydpi/ic_launcher.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi/ic_launcher_round.xml deleted file mode 100644 index 6f3b755..0000000 --- a/app/src/main/res/mipmap-anydpi/ic_launcher_round.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp b/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp new file mode 100644 index 0000000..0020c64 Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp b/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp new file mode 100644 index 0000000..7e26258 Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp new file mode 100644 index 0000000..2531c92 Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp new file mode 100644 index 0000000..c5d2d7e Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp new file mode 100644 index 0000000..cb1a443 Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp differ diff --git a/app/src/main/res/values/ic_launcher_background.xml b/app/src/main/res/values/ic_launcher_background.xml new file mode 100644 index 0000000..8be8333 --- /dev/null +++ b/app/src/main/res/values/ic_launcher_background.xml @@ -0,0 +1,4 @@ + + + #0878F5 + \ No newline at end of file