Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ModelZoo
Conformer_pytorch
Commits
764b3a75
Commit
764b3a75
authored
Jun 07, 2023
by
Sugon_ldc
Browse files
add new model
parents
Changes
498
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
962 additions
and
0 deletions
+962
-0
runtime/android/app/build.gradle
runtime/android/app/build.gradle
+103
-0
runtime/android/app/proguard-rules.pro
runtime/android/app/proguard-rules.pro
+22
-0
runtime/android/app/src/androidTest/java/com/mobvoi/wenet/ExampleInstrumentedTest.java
...idTest/java/com/mobvoi/wenet/ExampleInstrumentedTest.java
+27
-0
runtime/android/app/src/main/AndroidManifest.xml
runtime/android/app/src/main/AndroidManifest.xml
+23
-0
runtime/android/app/src/main/assets/README.md
runtime/android/app/src/main/assets/README.md
+1
-0
runtime/android/app/src/main/cpp/CMakeLists.txt
runtime/android/app/src/main/cpp/CMakeLists.txt
+32
-0
runtime/android/app/src/main/cpp/bin
runtime/android/app/src/main/cpp/bin
+2
-0
runtime/android/app/src/main/cpp/cmake
runtime/android/app/src/main/cpp/cmake
+2
-0
runtime/android/app/src/main/cpp/decoder
runtime/android/app/src/main/cpp/decoder
+2
-0
runtime/android/app/src/main/cpp/frontend
runtime/android/app/src/main/cpp/frontend
+2
-0
runtime/android/app/src/main/cpp/kaldi
runtime/android/app/src/main/cpp/kaldi
+2
-0
runtime/android/app/src/main/cpp/patch
runtime/android/app/src/main/cpp/patch
+2
-0
runtime/android/app/src/main/cpp/post_processor
runtime/android/app/src/main/cpp/post_processor
+2
-0
runtime/android/app/src/main/cpp/utils
runtime/android/app/src/main/cpp/utils
+2
-0
runtime/android/app/src/main/cpp/wenet.cc
runtime/android/app/src/main/cpp/wenet.cc
+166
-0
runtime/android/app/src/main/java/com/mobvoi/wenet/MainActivity.java
...roid/app/src/main/java/com/mobvoi/wenet/MainActivity.java
+221
-0
runtime/android/app/src/main/java/com/mobvoi/wenet/Recognize.java
...android/app/src/main/java/com/mobvoi/wenet/Recognize.java
+16
-0
runtime/android/app/src/main/java/com/mobvoi/wenet/VoiceRectView.java
...oid/app/src/main/java/com/mobvoi/wenet/VoiceRectView.java
+134
-0
runtime/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
.../app/src/main/res/drawable-v24/ic_launcher_foreground.xml
+31
-0
runtime/android/app/src/main/res/drawable/ic_launcher_background.xml
...roid/app/src/main/res/drawable/ic_launcher_background.xml
+170
-0
No files found.
Too many changes to show.
To preserve performance only
498 of 498+
files are displayed.
Plain diff
Email patch
runtime/android/app/build.gradle
0 → 100644
View file @
764b3a75
plugins
{
id
'com.android.application'
}
repositories
{
jcenter
()
maven
{
url
"https://oss.sonatype.org/content/repositories/snapshots"
}
}
android
{
signingConfigs
{
release
{
storeFile
file
(
'wenet.keystore'
)
storePassword
'123456'
keyAlias
'wenet'
keyPassword
'123456'
}
}
packagingOptions
{
pickFirst
'lib/arm64-v8a/libc++_shared.so'
}
configurations
{
extractForNativeBuild
}
compileSdkVersion
30
buildToolsVersion
"30.0.3"
defaultConfig
{
applicationId
"com.mobvoi.wenet"
minSdkVersion
21
targetSdkVersion
30
versionCode
1
versionName
"1.0"
testInstrumentationRunner
"androidx.test.runner.AndroidJUnitRunner"
externalNativeBuild
{
cmake
{
targets
"wenet"
,
"decoder_main"
cppFlags
"-std=c++14"
,
"-DC10_USE_GLOG"
,
"-DC10_USE_MINIMAL_GLOG"
,
"-DANDROID"
,
"-Wno-c++11-narrowing"
,
"-fexceptions"
}
}
ndkVersion
'21.1.6352462'
ndk
{
abiFilters
'armeabi-v7a'
,
'arm64-v8a'
,
'x86'
,
'x86_64'
}
}
buildTypes
{
release
{
minifyEnabled
false
signingConfig
signingConfigs
.
release
proguardFiles
getDefaultProguardFile
(
'proguard-android-optimize.txt'
),
'proguard-rules.pro'
}
}
externalNativeBuild
{
cmake
{
path
"src/main/cpp/CMakeLists.txt"
}
}
compileOptions
{
sourceCompatibility
JavaVersion
.
VERSION_1_8
targetCompatibility
JavaVersion
.
VERSION_1_8
}
}
dependencies
{
implementation
'androidx.appcompat:appcompat:1.2.0'
implementation
'com.google.android.material:material:1.2.1'
implementation
'androidx.constraintlayout:constraintlayout:2.0.4'
testImplementation
'junit:junit:4.+'
androidTestImplementation
'androidx.test.ext:junit:1.1.2'
androidTestImplementation
'androidx.test.espresso:espresso-core:3.3.0'
implementation
'org.pytorch:pytorch_android:1.10.0'
extractForNativeBuild
'org.pytorch:pytorch_android:1.10.0'
implementation
'com.github.pengzhendong:wenet-openfst-android:1.0.2'
extractForNativeBuild
'com.github.pengzhendong:wenet-openfst-android:1.0.2'
}
task
extractAARForNativeBuild
{
doLast
{
configurations
.
extractForNativeBuild
.
files
.
each
{
def
file
=
it
.
absoluteFile
copy
{
from
zipTree
(
file
)
into
"$buildDir/$file.name"
include
"headers/**"
include
"jni/**"
}
}
}
}
tasks
.
whenTaskAdded
{
task
->
if
(
task
.
name
.
contains
(
'externalNativeBuild'
))
{
task
.
dependsOn
(
extractAARForNativeBuild
)
}
}
runtime/android/app/proguard-rules.pro
0 → 100644
View file @
764b3a75
# 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
\ No newline at end of file
runtime/android/app/src/androidTest/java/com/mobvoi/wenet/ExampleInstrumentedTest.java
0 → 100644
View file @
764b3a75
package
com.mobvoi.wenet
;
import
android.content.Context
;
import
androidx.test.platform.app.InstrumentationRegistry
;
import
androidx.test.ext.junit.runners.AndroidJUnit4
;
import
org.junit.Test
;
import
org.junit.runner.RunWith
;
import
static
org
.
junit
.
Assert
.*;
/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith
(
AndroidJUnit4
.
class
)
public
class
ExampleInstrumentedTest
{
@Test
public
void
useAppContext
()
{
// Context of the app under test.
Context
appContext
=
InstrumentationRegistry
.
getInstrumentation
().
getTargetContext
();
assertEquals
(
"com.mobvoi.wenet"
,
appContext
.
getPackageName
());
}
}
\ No newline at end of file
runtime/android/app/src/main/AndroidManifest.xml
0 → 100644
View file @
764b3a75
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:tools=
"http://schemas.android.com/tools"
package=
"com.mobvoi.wenet"
>
<uses-permission
android:name=
"android.permission.RECORD_AUDIO"
/>
<application
android:allowBackup=
"true"
android:icon=
"@mipmap/ic_launcher"
android:label=
"@string/app_name"
android:roundIcon=
"@mipmap/ic_launcher_round"
android:supportsRtl=
"true"
tools:replace=
"android:theme"
android:theme=
"@style/Theme.Wenet"
>
<activity
android:name=
".MainActivity"
>
<intent-filter>
<action
android:name=
"android.intent.action.MAIN"
/>
<category
android:name=
"android.intent.category.LAUNCHER"
/>
</intent-filter>
</activity>
</application>
</manifest>
runtime/android/app/src/main/assets/README.md
0 → 100644
View file @
764b3a75
put final.zip and units.txt here.
runtime/android/app/src/main/cpp/CMakeLists.txt
0 → 100644
View file @
764b3a75
cmake_minimum_required
(
VERSION 3.4.1
)
set
(
TARGET wenet
)
project
(
${
TARGET
}
CXX
)
set
(
CMAKE_CXX_STANDARD 14
)
include
(
ExternalProject
)
option
(
TORCH
"whether to build with Torch"
ON
)
option
(
ONNX
"whether to build with ONNX"
OFF
)
set
(
CMAKE_VERBOSE_MAKEFILE on
)
set
(
build_DIR
${
CMAKE_SOURCE_DIR
}
/../../../build
)
list
(
APPEND CMAKE_MODULE_PATH
${
CMAKE_CURRENT_SOURCE_DIR
}
/cmake
)
string
(
REPLACE
"-Wl,--exclude-libs,libgcc_real.a"
""
CMAKE_EXE_LINKER_FLAGS
"
${
CMAKE_EXE_LINKER_FLAGS
}
"
)
include
(
libtorch
)
include
(
openfst
)
include_directories
(
${
CMAKE_SOURCE_DIR
}
${
CMAKE_SOURCE_DIR
}
/kaldi
)
add_subdirectory
(
utils
)
add_subdirectory
(
frontend
)
add_subdirectory
(
post_processor
)
add_subdirectory
(
kaldi
)
# kaldi: wfst based decoder
add_subdirectory
(
decoder
)
link_libraries
(
frontend decoder android
)
add_library
(
${
TARGET
}
SHARED wenet.cc
)
add_executable
(
decoder_main bin/decoder_main.cc
)
target_link_libraries
(
decoder_main PUBLIC libc++_shared.so
)
runtime/android/app/src/main/cpp/bin
0 → 120000
View file @
764b3a75
../../../../../core/bin
\ No newline at end of file
runtime/android/app/src/main/cpp/cmake
0 → 120000
View file @
764b3a75
../../../../../core/cmake
\ No newline at end of file
runtime/android/app/src/main/cpp/decoder
0 → 120000
View file @
764b3a75
../../../../../core/decoder
\ No newline at end of file
runtime/android/app/src/main/cpp/frontend
0 → 120000
View file @
764b3a75
../../../../../core/frontend
\ No newline at end of file
runtime/android/app/src/main/cpp/kaldi
0 → 120000
View file @
764b3a75
../../../../../core/kaldi
\ No newline at end of file
runtime/android/app/src/main/cpp/patch
0 → 120000
View file @
764b3a75
../../../../../core/patch
\ No newline at end of file
runtime/android/app/src/main/cpp/post_processor
0 → 120000
View file @
764b3a75
../../../../../core/post_processor
\ No newline at end of file
runtime/android/app/src/main/cpp/utils
0 → 120000
View file @
764b3a75
../../../../../core/utils
\ No newline at end of file
runtime/android/app/src/main/cpp/wenet.cc
0 → 100644
View file @
764b3a75
// Copyright (c) 2021 Mobvoi Inc (authors: Xiaoyu Chen)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <jni.h>
#include "torch/script.h"
#include "torch/torch.h"
#include "decoder/asr_decoder.h"
#include "decoder/torch_asr_model.h"
#include "frontend/feature_pipeline.h"
#include "frontend/wav.h"
#include "post_processor/post_processor.h"
#include "utils/log.h"
#include "utils/string.h"
namespace
wenet
{
std
::
shared_ptr
<
DecodeOptions
>
decode_config
;
std
::
shared_ptr
<
FeaturePipelineConfig
>
feature_config
;
std
::
shared_ptr
<
FeaturePipeline
>
feature_pipeline
;
std
::
shared_ptr
<
AsrDecoder
>
decoder
;
std
::
shared_ptr
<
DecodeResource
>
resource
;
DecodeState
state
=
kEndBatch
;
std
::
string
total_result
;
// NOLINT
void
init
(
JNIEnv
*
env
,
jobject
,
jstring
jModelDir
)
{
const
char
*
pModelDir
=
env
->
GetStringUTFChars
(
jModelDir
,
nullptr
);
std
::
string
modelPath
=
std
::
string
(
pModelDir
)
+
"/final.zip"
;
std
::
string
dictPath
=
std
::
string
(
pModelDir
)
+
"/units.txt"
;
auto
model
=
std
::
make_shared
<
TorchAsrModel
>
();
model
->
Read
(
modelPath
);
LOG
(
INFO
)
<<
"model path: "
<<
modelPath
;
resource
=
std
::
make_shared
<
DecodeResource
>
();
resource
->
model
=
model
;
resource
->
symbol_table
=
std
::
shared_ptr
<
fst
::
SymbolTable
>
(
fst
::
SymbolTable
::
ReadText
(
dictPath
));
LOG
(
INFO
)
<<
"dict path: "
<<
dictPath
;
PostProcessOptions
post_process_opts
;
resource
->
post_processor
=
std
::
make_shared
<
PostProcessor
>
(
post_process_opts
);
feature_config
=
std
::
make_shared
<
FeaturePipelineConfig
>
(
80
,
16000
);
feature_pipeline
=
std
::
make_shared
<
FeaturePipeline
>
(
*
feature_config
);
decode_config
=
std
::
make_shared
<
DecodeOptions
>
();
decode_config
->
chunk_size
=
16
;
decoder
=
std
::
make_shared
<
AsrDecoder
>
(
feature_pipeline
,
resource
,
*
decode_config
);
}
void
reset
(
JNIEnv
*
env
,
jobject
)
{
LOG
(
INFO
)
<<
"wenet reset"
;
decoder
->
Reset
();
state
=
kEndBatch
;
total_result
=
""
;
}
void
accept_waveform
(
JNIEnv
*
env
,
jobject
,
jshortArray
jWaveform
)
{
jsize
size
=
env
->
GetArrayLength
(
jWaveform
);
int16_t
*
waveform
=
env
->
GetShortArrayElements
(
jWaveform
,
0
);
feature_pipeline
->
AcceptWaveform
(
waveform
,
size
);
LOG
(
INFO
)
<<
"wenet accept waveform in ms: "
<<
int
(
size
/
16
);
}
void
set_input_finished
()
{
LOG
(
INFO
)
<<
"wenet input finished"
;
feature_pipeline
->
set_input_finished
();
}
void
decode_thread_func
()
{
while
(
true
)
{
state
=
decoder
->
Decode
();
if
(
state
==
kEndFeats
||
state
==
kEndpoint
)
{
decoder
->
Rescoring
();
}
std
::
string
result
;
if
(
decoder
->
DecodedSomething
())
{
result
=
decoder
->
result
()[
0
].
sentence
;
}
if
(
state
==
kEndFeats
)
{
LOG
(
INFO
)
<<
"wenet endfeats final result: "
<<
result
;
total_result
+=
result
;
break
;
}
else
if
(
state
==
kEndpoint
)
{
LOG
(
INFO
)
<<
"wenet endpoint final result: "
<<
result
;
total_result
+=
result
+
","
;
decoder
->
ResetContinuousDecoding
();
}
else
{
if
(
decoder
->
DecodedSomething
())
{
LOG
(
INFO
)
<<
"wenet partial result: "
<<
result
;
}
}
}
}
void
start_decode
()
{
std
::
thread
decode_thread
(
decode_thread_func
);
decode_thread
.
detach
();
}
jboolean
get_finished
(
JNIEnv
*
env
,
jobject
)
{
if
(
state
==
kEndFeats
)
{
LOG
(
INFO
)
<<
"wenet recognize finished"
;
return
JNI_TRUE
;
}
return
JNI_FALSE
;
}
jstring
get_result
(
JNIEnv
*
env
,
jobject
)
{
std
::
string
result
;
if
(
decoder
->
DecodedSomething
())
{
result
=
decoder
->
result
()[
0
].
sentence
;
}
LOG
(
INFO
)
<<
"wenet ui result: "
<<
total_result
+
result
;
return
env
->
NewStringUTF
((
total_result
+
result
).
c_str
());
}
}
// namespace wenet
JNIEXPORT
jint
JNI_OnLoad
(
JavaVM
*
vm
,
void
*
)
{
JNIEnv
*
env
;
if
(
vm
->
GetEnv
(
reinterpret_cast
<
void
**>
(
&
env
),
JNI_VERSION_1_6
)
!=
JNI_OK
)
{
return
JNI_ERR
;
}
jclass
c
=
env
->
FindClass
(
"com/mobvoi/wenet/Recognize"
);
if
(
c
==
nullptr
)
{
return
JNI_ERR
;
}
static
const
JNINativeMethod
methods
[]
=
{
{
"init"
,
"(Ljava/lang/String;)V"
,
reinterpret_cast
<
void
*>
(
wenet
::
init
)},
{
"reset"
,
"()V"
,
reinterpret_cast
<
void
*>
(
wenet
::
reset
)},
{
"acceptWaveform"
,
"([S)V"
,
reinterpret_cast
<
void
*>
(
wenet
::
accept_waveform
)},
{
"setInputFinished"
,
"()V"
,
reinterpret_cast
<
void
*>
(
wenet
::
set_input_finished
)},
{
"getFinished"
,
"()Z"
,
reinterpret_cast
<
void
*>
(
wenet
::
get_finished
)},
{
"startDecode"
,
"()V"
,
reinterpret_cast
<
void
*>
(
wenet
::
start_decode
)},
{
"getResult"
,
"()Ljava/lang/String;"
,
reinterpret_cast
<
void
*>
(
wenet
::
get_result
)},
};
int
rc
=
env
->
RegisterNatives
(
c
,
methods
,
sizeof
(
methods
)
/
sizeof
(
JNINativeMethod
));
if
(
rc
!=
JNI_OK
)
{
return
rc
;
}
return
JNI_VERSION_1_6
;
}
runtime/android/app/src/main/java/com/mobvoi/wenet/MainActivity.java
0 → 100644
View file @
764b3a75
package
com.mobvoi.wenet
;
import
android.Manifest
;
import
android.content.Context
;
import
android.content.pm.PackageManager
;
import
android.content.res.AssetManager
;
import
android.media.AudioFormat
;
import
android.media.AudioRecord
;
import
android.media.MediaRecorder
;
import
android.os.Bundle
;
import
android.os.Process
;
import
android.util.Log
;
import
android.widget.Button
;
import
android.widget.TextView
;
import
android.widget.Toast
;
import
androidx.appcompat.app.AppCompatActivity
;
import
androidx.core.app.ActivityCompat
;
import
androidx.core.content.ContextCompat
;
import
java.io.File
;
import
java.io.FileOutputStream
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.OutputStream
;
import
java.util.Arrays
;
import
java.util.List
;
import
java.util.concurrent.ArrayBlockingQueue
;
import
java.util.concurrent.BlockingQueue
;
public
class
MainActivity
extends
AppCompatActivity
{
private
final
int
MY_PERMISSIONS_RECORD_AUDIO
=
1
;
private
static
final
String
LOG_TAG
=
"WENET"
;
private
static
final
int
SAMPLE_RATE
=
16000
;
// The sampling rate
private
static
final
int
MAX_QUEUE_SIZE
=
2500
;
// 100 seconds audio, 1 / 0.04 * 100
private
static
final
List
<
String
>
resource
=
Arrays
.
asList
(
"final.zip"
,
"units.txt"
,
"ctc.ort"
,
"decoder.ort"
,
"encoder.ort"
);
private
boolean
startRecord
=
false
;
private
AudioRecord
record
=
null
;
private
int
miniBufferSize
=
0
;
// 1280 bytes 648 byte 40ms, 0.04s
private
final
BlockingQueue
<
short
[]>
bufferQueue
=
new
ArrayBlockingQueue
<>(
MAX_QUEUE_SIZE
);
public
static
void
assetsInit
(
Context
context
)
throws
IOException
{
AssetManager
assetMgr
=
context
.
getAssets
();
// Unzip all files in resource from assets to context.
// Note: Uninstall the APP will remove the resource files in the context.
for
(
String
file
:
assetMgr
.
list
(
""
))
{
if
(
resource
.
contains
(
file
))
{
File
dst
=
new
File
(
context
.
getFilesDir
(),
file
);
if
(!
dst
.
exists
()
||
dst
.
length
()
==
0
)
{
Log
.
i
(
LOG_TAG
,
"Unzipping "
+
file
+
" to "
+
dst
.
getAbsolutePath
());
InputStream
is
=
assetMgr
.
open
(
file
);
OutputStream
os
=
new
FileOutputStream
(
dst
);
byte
[]
buffer
=
new
byte
[
4
*
1024
];
int
read
;
while
((
read
=
is
.
read
(
buffer
))
!=
-
1
)
{
os
.
write
(
buffer
,
0
,
read
);
}
os
.
flush
();
}
}
}
}
@Override
public
void
onRequestPermissionsResult
(
int
requestCode
,
String
[]
permissions
,
int
[]
grantResults
)
{
if
(
requestCode
==
MY_PERMISSIONS_RECORD_AUDIO
)
{
if
(
grantResults
.
length
>
0
&&
grantResults
[
0
]
==
PackageManager
.
PERMISSION_GRANTED
)
{
Log
.
i
(
LOG_TAG
,
"record permission is granted"
);
initRecorder
();
}
else
{
Toast
.
makeText
(
this
,
"Permissions denied to record audio"
,
Toast
.
LENGTH_LONG
).
show
();
Button
button
=
findViewById
(
R
.
id
.
button
);
button
.
setEnabled
(
false
);
}
}
}
@Override
protected
void
onCreate
(
Bundle
savedInstanceState
)
{
super
.
onCreate
(
savedInstanceState
);
setContentView
(
R
.
layout
.
activity_main
);
requestAudioPermissions
();
try
{
assetsInit
(
this
);
}
catch
(
IOException
e
)
{
Log
.
e
(
LOG_TAG
,
"Error process asset files to file path"
);
}
TextView
textView
=
findViewById
(
R
.
id
.
textView
);
textView
.
setText
(
""
);
Recognize
.
init
(
getFilesDir
().
getPath
());
Button
button
=
findViewById
(
R
.
id
.
button
);
button
.
setText
(
"Start Record"
);
button
.
setOnClickListener
(
view
->
{
if
(!
startRecord
)
{
startRecord
=
true
;
Recognize
.
reset
();
startRecordThread
();
startAsrThread
();
Recognize
.
startDecode
();
button
.
setText
(
"Stop Record"
);
}
else
{
startRecord
=
false
;
Recognize
.
setInputFinished
();
button
.
setText
(
"Start Record"
);
}
button
.
setEnabled
(
false
);
});
}
private
void
requestAudioPermissions
()
{
if
(
ContextCompat
.
checkSelfPermission
(
this
,
Manifest
.
permission
.
RECORD_AUDIO
)
!=
PackageManager
.
PERMISSION_GRANTED
)
{
ActivityCompat
.
requestPermissions
(
this
,
new
String
[]{
Manifest
.
permission
.
RECORD_AUDIO
},
MY_PERMISSIONS_RECORD_AUDIO
);
}
else
{
initRecorder
();
}
}
private
void
initRecorder
()
{
// buffer size in bytes 1280
miniBufferSize
=
AudioRecord
.
getMinBufferSize
(
SAMPLE_RATE
,
AudioFormat
.
CHANNEL_IN_MONO
,
AudioFormat
.
ENCODING_PCM_16BIT
);
if
(
miniBufferSize
==
AudioRecord
.
ERROR
||
miniBufferSize
==
AudioRecord
.
ERROR_BAD_VALUE
)
{
Log
.
e
(
LOG_TAG
,
"Audio buffer can't initialize!"
);
return
;
}
record
=
new
AudioRecord
(
MediaRecorder
.
AudioSource
.
DEFAULT
,
SAMPLE_RATE
,
AudioFormat
.
CHANNEL_IN_MONO
,
AudioFormat
.
ENCODING_PCM_16BIT
,
miniBufferSize
);
if
(
record
.
getState
()
!=
AudioRecord
.
STATE_INITIALIZED
)
{
Log
.
e
(
LOG_TAG
,
"Audio Record can't initialize!"
);
return
;
}
Log
.
i
(
LOG_TAG
,
"Record init okay"
);
}
private
void
startRecordThread
()
{
new
Thread
(()
->
{
VoiceRectView
voiceView
=
findViewById
(
R
.
id
.
voiceRectView
);
record
.
startRecording
();
Process
.
setThreadPriority
(
Process
.
THREAD_PRIORITY_AUDIO
);
while
(
startRecord
)
{
short
[]
buffer
=
new
short
[
miniBufferSize
/
2
];
int
read
=
record
.
read
(
buffer
,
0
,
buffer
.
length
);
voiceView
.
add
(
calculateDb
(
buffer
));
try
{
if
(
AudioRecord
.
ERROR_INVALID_OPERATION
!=
read
)
{
bufferQueue
.
put
(
buffer
);
}
}
catch
(
InterruptedException
e
)
{
Log
.
e
(
LOG_TAG
,
e
.
getMessage
());
}
Button
button
=
findViewById
(
R
.
id
.
button
);
if
(!
button
.
isEnabled
()
&&
startRecord
)
{
runOnUiThread
(()
->
button
.
setEnabled
(
true
));
}
}
record
.
stop
();
voiceView
.
zero
();
}).
start
();
}
private
double
calculateDb
(
short
[]
buffer
)
{
double
energy
=
0.0
;
for
(
short
value
:
buffer
)
{
energy
+=
value
*
value
;
}
energy
/=
buffer
.
length
;
energy
=
(
10
*
Math
.
log10
(
1
+
energy
))
/
100
;
energy
=
Math
.
min
(
energy
,
1.0
);
return
energy
;
}
private
void
startAsrThread
()
{
new
Thread
(()
->
{
// Send all data
while
(
startRecord
||
bufferQueue
.
size
()
>
0
)
{
try
{
short
[]
data
=
bufferQueue
.
take
();
// 1. add data to C++ interface
Recognize
.
acceptWaveform
(
data
);
// 2. get partial result
runOnUiThread
(()
->
{
TextView
textView
=
findViewById
(
R
.
id
.
textView
);
textView
.
setText
(
Recognize
.
getResult
());
});
}
catch
(
InterruptedException
e
)
{
Log
.
e
(
LOG_TAG
,
e
.
getMessage
());
}
}
// Wait for final result
while
(
true
)
{
// get result
if
(!
Recognize
.
getFinished
())
{
runOnUiThread
(()
->
{
TextView
textView
=
findViewById
(
R
.
id
.
textView
);
textView
.
setText
(
Recognize
.
getResult
());
});
}
else
{
runOnUiThread
(()
->
{
Button
button
=
findViewById
(
R
.
id
.
button
);
button
.
setEnabled
(
true
);
});
break
;
}
}
}).
start
();
}
}
\ No newline at end of file
runtime/android/app/src/main/java/com/mobvoi/wenet/Recognize.java
0 → 100644
View file @
764b3a75
package
com.mobvoi.wenet
;
public
class
Recognize
{
static
{
System
.
loadLibrary
(
"wenet"
);
}
public
static
native
void
init
(
String
modelDir
);
public
static
native
void
reset
();
public
static
native
void
acceptWaveform
(
short
[]
waveform
);
public
static
native
void
setInputFinished
();
public
static
native
boolean
getFinished
();
public
static
native
void
startDecode
();
public
static
native
String
getResult
();
}
runtime/android/app/src/main/java/com/mobvoi/wenet/VoiceRectView.java
0 → 100644
View file @
764b3a75
package
com.mobvoi.wenet
;
import
android.content.Context
;
import
android.content.res.TypedArray
;
import
android.graphics.Canvas
;
import
android.graphics.LinearGradient
;
import
android.graphics.Paint
;
import
android.graphics.Shader
;
import
android.util.AttributeSet
;
import
android.view.View
;
import
androidx.core.content.ContextCompat
;
import
java.util.Arrays
;
/**
* 自定义的音频模拟条形图 Created by shize on 2016/9/5.
*/
public
class
VoiceRectView
extends
View
{
// 音频矩形的数量
private
int
mRectCount
;
// 音频矩形的画笔
private
Paint
mRectPaint
;
// 渐变颜色的两种
private
int
topColor
,
downColor
;
// 音频矩形的宽和高
private
int
mRectWidth
,
mRectHeight
;
// 偏移量
private
int
offset
;
// 频率速度
private
int
mSpeed
;
private
double
[]
mEnergyBuffer
=
null
;
public
VoiceRectView
(
Context
context
)
{
this
(
context
,
null
);
}
public
VoiceRectView
(
Context
context
,
AttributeSet
attrs
)
{
this
(
context
,
attrs
,
0
);
}
public
VoiceRectView
(
Context
context
,
AttributeSet
attrs
,
int
defStyleAttr
)
{
super
(
context
,
attrs
,
defStyleAttr
);
setPaint
(
context
,
attrs
);
}
public
void
setPaint
(
Context
context
,
AttributeSet
attrs
)
{
// 将属性存储到TypedArray中
TypedArray
ta
=
context
.
obtainStyledAttributes
(
attrs
,
R
.
styleable
.
VoiceRect
);
mRectPaint
=
new
Paint
();
// 添加矩形画笔的基础颜色
mRectPaint
.
setColor
(
ta
.
getColor
(
R
.
styleable
.
VoiceRect_RectTopColor
,
ContextCompat
.
getColor
(
context
,
R
.
color
.
top_color
)));
// 添加矩形渐变色的上面部分
topColor
=
ta
.
getColor
(
R
.
styleable
.
VoiceRect_RectTopColor
,
ContextCompat
.
getColor
(
context
,
R
.
color
.
top_color
));
// 添加矩形渐变色的下面部分
downColor
=
ta
.
getColor
(
R
.
styleable
.
VoiceRect_RectDownColor
,
ContextCompat
.
getColor
(
context
,
R
.
color
.
down_color
));
// 设置矩形的数量
mRectCount
=
ta
.
getInt
(
R
.
styleable
.
VoiceRect_RectCount
,
10
);
mEnergyBuffer
=
new
double
[
mRectCount
];
// 设置重绘的时间间隔,也就是变化速度
mSpeed
=
ta
.
getInt
(
R
.
styleable
.
VoiceRect_RectSpeed
,
300
);
// 每个矩形的间隔
offset
=
ta
.
getInt
(
R
.
styleable
.
VoiceRect_RectOffset
,
0
);
// 回收TypeArray
ta
.
recycle
();
}
@Override
protected
void
onSizeChanged
(
int
w
,
int
h
,
int
oldW
,
int
oldH
)
{
super
.
onSizeChanged
(
w
,
h
,
oldW
,
oldH
);
// 渐变效果
LinearGradient
mLinearGradient
;
// 画布的宽
int
mWidth
;
// 获取画布的宽
mWidth
=
getWidth
();
// 获取矩形的最大高度
mRectHeight
=
getHeight
();
// 获取单个矩形的宽度(减去的部分为到右边界的间距)
mRectWidth
=
(
mWidth
-
offset
)
/
mRectCount
;
// 实例化一个线性渐变
mLinearGradient
=
new
LinearGradient
(
0
,
0
,
mRectWidth
,
mRectHeight
,
topColor
,
downColor
,
Shader
.
TileMode
.
CLAMP
);
// 添加进画笔的着色器
mRectPaint
.
setShader
(
mLinearGradient
);
}
public
void
add
(
double
energy
)
{
if
(
mEnergyBuffer
.
length
-
1
>=
0
)
{
System
.
arraycopy
(
mEnergyBuffer
,
1
,
mEnergyBuffer
,
0
,
mEnergyBuffer
.
length
-
1
);
}
mEnergyBuffer
[
mEnergyBuffer
.
length
-
1
]
=
energy
;
}
public
void
zero
()
{
Arrays
.
fill
(
mEnergyBuffer
,
0
);
}
@Override
protected
void
onDraw
(
Canvas
canvas
)
{
super
.
onDraw
(
canvas
);
double
mRandom
;
float
currentHeight
;
for
(
int
i
=
0
;
i
<
mRectCount
;
i
++)
{
// 由于只是简单的案例就不监听音频输入,随机模拟一些数字即可
mRandom
=
Math
.
random
();
//if (i < 1 || i > mRectCount - 2) mRandom = 0;
currentHeight
=
(
float
)
(
mRectHeight
*
mEnergyBuffer
[
i
]);
// 矩形的绘制是从左边开始到上、右、下边(左右边距离左边画布边界的距离,上下边距离上边画布边界的距离)
canvas
.
drawRect
(
(
float
)
(
mRectWidth
*
i
+
offset
),
(
mRectHeight
-
currentHeight
)
/
2
,
(
float
)
(
mRectWidth
*
(
i
+
1
)),
mRectHeight
/
2
+
currentHeight
/
2
,
mRectPaint
);
}
// 使得view延迟重绘
postInvalidateDelayed
(
mSpeed
);
}
}
runtime/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
0 → 100644
View file @
764b3a75
<vector
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:aapt=
"http://schemas.android.com/aapt"
android:width=
"108dp"
android:height=
"108dp"
android:viewportWidth=
"108"
android:viewportHeight=
"108"
>
<path
android:pathData=
"M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z"
>
<aapt:attr
name=
"android:fillColor"
>
<gradient
android:endX=
"85.84757"
android:endY=
"92.4963"
android:startX=
"42.9492"
android:startY=
"49.59793"
android:type=
"linear"
>
<item
android:color=
"#44000000"
android:offset=
"0.0"
/>
<item
android:color=
"#00000000"
android:offset=
"1.0"
/>
</gradient>
</aapt:attr>
</path>
<path
android:fillColor=
"#FFFFFF"
android:fillType=
"nonZero"
android:pathData=
"M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
android:strokeWidth=
"1"
android:strokeColor=
"#00000000"
/>
</vector>
\ No newline at end of file
runtime/android/app/src/main/res/drawable/ic_launcher_background.xml
0 → 100644
View file @
764b3a75
<?xml version="1.0" encoding="utf-8"?>
<vector
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:width=
"108dp"
android:height=
"108dp"
android:viewportWidth=
"108"
android:viewportHeight=
"108"
>
<path
android:fillColor=
"#3DDC84"
android:pathData=
"M0,0h108v108h-108z"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M9,0L9,108"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M19,0L19,108"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M29,0L29,108"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M39,0L39,108"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M49,0L49,108"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M59,0L59,108"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M69,0L69,108"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M79,0L79,108"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M89,0L89,108"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M99,0L99,108"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M0,9L108,9"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M0,19L108,19"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M0,29L108,29"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M0,39L108,39"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M0,49L108,49"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M0,59L108,59"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M0,69L108,69"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M0,79L108,79"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M0,89L108,89"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M0,99L108,99"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M19,29L89,29"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M19,39L89,39"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M19,49L89,49"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M19,59L89,59"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M19,69L89,69"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M19,79L89,79"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M29,19L29,89"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M39,19L39,89"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M49,19L49,89"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M59,19L59,89"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M69,19L69,89"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M79,19L79,89"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
</vector>
Prev
1
…
13
14
15
16
17
18
19
20
21
…
25
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment