Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
albho committed Mar 6, 2024
1 parent b42f517 commit a232e7a
Show file tree
Hide file tree
Showing 11 changed files with 208 additions and 451 deletions.
18 changes: 13 additions & 5 deletions binding/android/Falcon/falcon/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@ android {
}

buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
// TODO: update post-jni
// release {
// minifyEnabled false
// proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
// }
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
Expand All @@ -42,4 +43,11 @@ task copyLibs(type: Copy) {
into("${rootDir}/falcon/src/main/jniLibs")
}

preBuild.dependsOn copyLibs
task copyParams(type: Copy) {
from("${rootDir}/../../../lib/common")
include('falcon_params.pv')
into("${rootDir}/falcon/src/main/res/raw")
}

preBuild.dependsOn(copyLibs)
preBuild.dependsOn(copyParams)
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
package ai.picovoice.falcon;

import android.content.Context;
import android.content.res.Resources;
import android.text.TextUtils;

import java.io.BufferedInputStream;
Expand All @@ -25,6 +26,18 @@
*/
public class Falcon {

private static String defaultModelPath;

private static String _sdk = "android";


static {
System.loadLibrary("pv_falcon");
}


private long handle;

private static final String[] VALID_EXTENSIONS = {
"3gp",
"flac",
Expand All @@ -38,22 +51,15 @@ public class Falcon {
"webm"
};

static {
System.loadLibrary("pv_falcon");
}

private long handle;
private static String _sdk = "android";

public static void setSdk(String sdk) {
Falcon._sdk = sdk;
}

/**
* Constructor.
*
* @param accessKey AccessKey obtained from Picovoice Console
* @param modelPath Absolute path to the file containing Falcon model parameters.
* @param accessKey AccessKey obtained from Picovoice Console
* @param modelPath Absolute path to the file containing Falcon model parameters.
* @throws FalconException if there is an error while initializing Falcon.
*/
private Falcon(
Expand All @@ -66,27 +72,6 @@ private Falcon(
modelPath);
}

private static String extractResource(
Context context,
InputStream srcFileStream,
String dstFilename) throws IOException {
InputStream is = new BufferedInputStream(
srcFileStream,
256);
OutputStream os = new BufferedOutputStream(
context.openFileOutput(dstFilename, Context.MODE_PRIVATE),
256);
int r;
while ((r = is.read()) != -1) {
os.write(r);
}
os.flush();

is.close();
os.close();
return new File(context.getFilesDir(), dstFilename).getAbsolutePath();
}

/**
* Releases resources acquired by Falcon.
*/
Expand All @@ -103,7 +88,7 @@ public void delete() {
* @param pcm A frame of audio samples. The incoming audio needs to have a sample rate
* equal to {@link #getSampleRate()} and be 16-bit linearly-encoded. Furthermore,
* Falcon operates on single channel audio. If you wish to process data in a different
* sample rate or format consider using `.process_file`.
* sample rate or format, consider using {@link #processFile(String)}.
* @return FalconSegments object which contains the diarization results of the engine.
* @throws FalconException if there is an error while processing the audio frame.
*/
Expand Down Expand Up @@ -177,7 +162,7 @@ public String getVersion() {
}

/**
* Builder for creating an instance of Falcon with a mixture of default arguments.
* Builder for creating an instance of Falcon.
*/
public static class Builder {

Expand All @@ -204,6 +189,36 @@ public Builder setModelPath(String modelPath) {
return this;
}

private static void extractPackageResources(Context context) throws FalconIOException {
final Resources resources = context.getResources();

try {
defaultModelPath = extractResource(context,
resources.openRawResource(R.raw.falcon_params),
resources.getResourceEntryName(R.raw.falcon_params) + ".pv");
} catch (IOException ex) {
throw new FalconIOException(ex);
}
}

private static String extractResource(
Context context,
InputStream srcFileStream,
String dstFilename
) throws IOException {
InputStream is = new BufferedInputStream(srcFileStream, 512);
OutputStream os = new BufferedOutputStream(context.openFileOutput(dstFilename, Context.MODE_PRIVATE), 512);
int r;
while ((r = is.read()) != -1) {
os.write(r);
}
os.flush();

is.close();
os.close();
return new File(context.getFilesDir(), dstFilename).getAbsolutePath();
}

/**
* Creates an instance of Falcon Speaker Diarization engine.
*/
Expand All @@ -213,7 +228,10 @@ public Falcon build(Context context) throws FalconException {
}

if (modelPath == null) {
throw new FalconInvalidArgumentException("ModelPath must not be null");
if (defaultModelPath == null) {
extractPackageResources(context);
}
modelPath = defaultModelPath;
} else {
File modelFile = new File(modelPath);
String modelFilename = modelFile.getName();
Expand Down
Empty file modified binding/android/FalconTestApp/copy_test_resources.sh
100644 → 100755
Empty file.
86 changes: 30 additions & 56 deletions binding/android/FalconTestApp/falcon-test-app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -49,67 +49,43 @@ android {
}

signingConfigs {
release {
storePassword properties.getProperty("storePassword")
storeFile file(properties.getProperty("storeFile", ".dummy.jks"))
keyAlias properties.getProperty("keyAlias")
keyPassword properties.getProperty("keyPassword")
}
// TODO: update post-jni
// release {
// storePassword properties.getProperty("storePassword")
// storeFile file(properties.getProperty("storeFile", ".dummy.jks"))
// keyAlias properties.getProperty("keyAlias")
// keyPassword properties.getProperty("keyPassword")
// }
}

buildTypes {
// TODO: update post-jni
debug {
signingConfig signingConfigs.release
}
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
// signingConfig signingConfigs.release
}
// release {
// minifyEnabled false
// proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
// signingConfig signingConfigs.release
// }
}

if (System.getProperty("testBuildType", "debug") == "integ") {
testBuildType("release")
}

def testDataFile = file('../../../../resources/.test/test_data.json')
def parsedJson = new groovy.json.JsonSlurper().parseText(testDataFile.text)
def languages = []
parsedJson.tests.parameters.each { a ->
languages.add(a.language)
task("copyParams", type: Copy) {
from("$projectDir/../../../../lib/common/")
include("falcon_params.pv")
into("$projectDir/src/main/assets/models")
}

flavorDimensions "language"
productFlavors {
en {
getIsDefault().set(true)
}

languages.each { language ->
"$language" {
applicationIdSuffix ".$language"

}
}

all { flavor ->
delete fileTree("$projectDir/src/main/assets") {
exclude '**/.gitkeep'
}
String suffix = (flavor.name != "en") ? "_${flavor.name}" : ""
task("${flavor.name}CopyParams", type: Copy) {
from("$projectDir/../../../../lib/common/")
include("falcon_params${suffix}.pv")
into("$projectDir/src/main/assets/models")
}
task("${flavor.name}CopyAudio", type: Copy) {
description = "Copy ${flavor.name} audio resources"
from("$projectDir/../../../../resources/audio_samples/")
include("test${suffix}.wav")
into("$projectDir/src/main/assets/audio_samples")
}
}
task("copyAudio", type: Copy) {
description = "Copy audio resources"
from("$projectDir/../../../../resources/audio_samples/")
include("test.wav")
into("$projectDir/src/main/assets/audio_samples/")
}

sourceSets {
androidTest {
java {
Expand Down Expand Up @@ -140,6 +116,7 @@ dependencies {
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.8.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
// TODO: update post-release
implementation files('../../Falcon/falcon/build/outputs/aar/falcon-release.aar')

// Espresso UI Testing
Expand All @@ -152,11 +129,8 @@ dependencies {
}

afterEvaluate {
android.productFlavors.all {
flavor ->
tasks."merge${flavor.name.capitalize()}DebugAssets".dependsOn "${flavor.name}CopyParams"
tasks."merge${flavor.name.capitalize()}ReleaseAssets".dependsOn "${flavor.name}CopyParams"
tasks."merge${flavor.name.capitalize()}DebugAssets".dependsOn "${flavor.name}CopyAudio"
tasks."merge${flavor.name.capitalize()}ReleaseAssets".dependsOn "${flavor.name}CopyAudio"
}
}
tasks."mergeDebugAssets".dependsOn "copyParams"
tasks."mergeReleaseAssets".dependsOn "copyParams"
tasks."mergeDebugAssets".dependsOn "copyAudio"
tasks."mergeReleaseAssets".dependsOn "copyAudio"
}
23 changes: 23 additions & 0 deletions binding/android/FalconTestApp/falcon-test-app/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
-keep class com.google.** { *; }
-keep class com.microsoft.** { *; }
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2022-2023 Picovoice Inc.
Copyright 2024 Picovoice Inc.
You may not use this file except in compliance with the license. A copy of the license is
located in the "LICENSE" file accompanying this source.
Expand All @@ -12,7 +12,6 @@

package ai.picovoice.falcon.testapp;

import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertEquals;

import android.content.Context;
Expand Down Expand Up @@ -111,43 +110,12 @@ protected void validateMetadata(
) {
assertEquals(segments.length, expectedSegments.length);
for (int i = 0; i < segments.length; i++) {
assertEquals(segments[i].getStartSec(), expectedSegments[i].getStartSec(), 0.01);
assertEquals(segments[i].getEndSec(), expectedSegments[i].getEndSec(), 0.01);
assertEquals(segments[i].getStartSec(), expectedSegments[i].getStartSec(), 0.1);
assertEquals(segments[i].getEndSec(), expectedSegments[i].getEndSec(), 0.1);
assertEquals(segments[i].getSpeakerTag(), expectedSegments[i].getSpeakerTag());
}
}

protected static float getSegmentErrorRate(
String transcript,
String expectedTranscript,
boolean useCER) {
String splitter = (useCER) ? "" : " ";
return (float) levenshteinDistance(
transcript.split(splitter),
expectedTranscript.split(splitter)) / transcript.length();
}

private static int levenshteinDistance(String[] segments1, String[] segments2) {
int[][] res = new int[segments1.length + 1][segments2.length + 1];
for (int i = 0; i <= segments1.length; i++) {
res[i][0] = i;
}
for (int j = 0; j <= segments2.length; j++) {
res[0][j] = j;
}
for (int i = 1; i <= segments1.length; i++) {
for (int j = 1; j <= segments2.length; j++) {
res[i][j] = Math.min(
Math.min(
res[i - 1][j] + 1,
res[i][j - 1] + 1),
res[i - 1][j - 1] + (segments1[i - 1].equalsIgnoreCase(segments2[j - 1]) ? 0 : 1)
);
}
}
return res[segments1.length][segments2.length];
}

private void extractAssetsRecursively(String path) throws IOException {
String[] list = assetManager.list(path);
if (list.length > 0) {
Expand Down
Loading

0 comments on commit a232e7a

Please sign in to comment.