Skip to content

Commit

Permalink
Merge pull request #2 from Stypox/api-24
Browse files Browse the repository at this point in the history
Do not use Files API to allow using on API 24+, remove uneeded external storage permissions
  • Loading branch information
kamir86 authored Dec 1, 2020
2 parents e4ea06a + 9e18a0b commit 6e0e968
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 46 deletions.
2 changes: 1 addition & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ android {

defaultConfig {
applicationId "it.awt.mycroft.deepspeech"
minSdkVersion 26
minSdkVersion 24
targetSdkVersion 29
versionCode 1
versionName "1.0"
Expand Down
2 changes: 0 additions & 2 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@

<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

<application
android:allowBackup="true"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,13 +106,9 @@ class SpeechFragment : Fragment() {
}

fun startSpeechRecognition(view: View){
askPermission(
Manifest.permission.RECORD_AUDIO,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE
){
askPermission(Manifest.permission.RECORD_AUDIO) {
startSpeechRecognition()
}.onDeclined { e ->
}.onDeclined {
//at least one permission have been declined by the user
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package it.awt.mycroft.deepspeech.usecase

import android.content.Context
import android.os.Environment
import android.util.Log
import com.mozilla.speechlibrary.SpeechResultCallback
import com.mozilla.speechlibrary.SpeechService
import com.mozilla.speechlibrary.SpeechServiceSettings
import com.mozilla.speechlibrary.stt.STTResult
Expand All @@ -11,18 +11,14 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.nio.file.Files
import java.nio.file.StandardCopyOption
import kotlin.coroutines.suspendCoroutine
import com.mozilla.speechlibrary.SpeechResultCallback
import java.lang.IllegalArgumentException
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine


class SpeechRecognitionUseCase {
private val TAG: String = "SpeechRecognitionUseCase"
private val MODEL_PATH = "deepspeech/models/it/"
private val LANGUAGE = "it-it"

suspend fun startSpeechRecognition(ctx : Context, mSpeechService : SpeechService, voiceListener : SpeechResultCallback?) : Either<Throwable, String>{
return suspendCoroutine { cont ->
Expand Down Expand Up @@ -54,16 +50,15 @@ class SpeechRecognitionUseCase {
voiceListener?.onError(errorType, error)
}
}
val modelPath =
ctx.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)?.absoluteFile?.toPath()
?.resolve(MODEL_PATH)?.toString();

val modelPath = File(ctx.filesDir, MODEL_PATH).absolutePath
val builder: SpeechServiceSettings.Builder = SpeechServiceSettings.Builder()
.withLanguage(LANGUAGE)
.withStoreSamples(true)
.withStoreTranscriptions(true)
.withProductTag("product-tag")
.withUseDeepSpeech(true) // If using DeepSpeech
.withModelPath(modelPath!!) // If using DeepSpeech
.withModelPath(modelPath) // If using DeepSpeech

if (ModelUtils.isReady(modelPath)) {
// The model is already downloaded and unzipped
Expand All @@ -79,32 +74,32 @@ class SpeechRecognitionUseCase {

private suspend fun copyModel(ctx: Context) {
return withContext(Dispatchers.IO) {
val modelPath = ctx.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)?.absoluteFile?.toPath()?.resolve(MODEL_PATH)
Files.createDirectories(modelPath)
ctx.assets.open("model/0.8.2/output_graph.tflite").use {
val path = modelPath?.resolve("output_graph.tflite")
Log.i(TAG, "copying file to: "+path?.toString())
Files.copy(it, path, StandardCopyOption.REPLACE_EXISTING);
}
ctx.assets.open("model/0.8.2/alphabet.txt").use {
val path = modelPath?.resolve("alphabet.txt")
Log.i(TAG, "copying file to: "+path?.toString())
Files.createDirectories(path?.parent)
Files.copy(it, path, StandardCopyOption.REPLACE_EXISTING);
}
ctx.assets.open("model/0.8.2/scorer").use {
val path = modelPath?.resolve("scorer")
Log.i(TAG, "copying file to: "+path?.toString())
Files.createDirectories(path?.parent)
Files.copy(it, path, StandardCopyOption.REPLACE_EXISTING);
}
ctx.assets.open("model/0.8.2/info.json").use {
val path = modelPath?.resolve("info.json")
Log.i(TAG, "copying file to: "+path?.toString())
Files.createDirectories(path?.parent)
Files.copy(it, path, StandardCopyOption.REPLACE_EXISTING);
val modelPath = File(ctx.filesDir, MODEL_PATH)
modelPath.mkdirs()

copy(ctx, modelPath, "output_graph.tflite")
copy(ctx, modelPath, "alphabet.txt")
copy(ctx, modelPath, "scorer")
copy(ctx, modelPath, "info.json")
}
}

@Throws(IOException::class)
private fun copy(ctx: Context, modelPath: File, filename: String) {
ctx.assets.open("model/0.8.2/$filename").use { it ->
FileOutputStream(File(modelPath, filename)).use { output ->
val buffer = ByteArray(1024)
var length: Int
while (it.read(buffer).also { length = it } > 0) {
output.write(buffer, 0, length)
}
}
}
}

companion object {
private const val TAG = "SpeechRecognitionUseCase"
private const val MODEL_PATH = "deepspeech/models/it/"
private const val LANGUAGE = "it-it"
}
}

0 comments on commit 6e0e968

Please sign in to comment.