Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions path/to/core/audio/src/androidMain/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.notelyvoice">

<!-- ... -->

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">

<!-- ... -->

<activity
android:name=".SettingsActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<!-- Add SenseVoice module to manifest -->
<service
android:name=".SenseVoiceService"
android:enabled="true"
android:exported="true" />

</application>

</manifest>
24 changes: 24 additions & 0 deletions path/to/core/audio/src/androidMain/kotlin/SenseVoiceService.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// SenseVoiceService.kt
import android.content.Intent
import android.os.IBinder
import androidx.localbroadcastmanager.content.LocalBroadcastManager
import com.example.notelyvoice.SenseVoice

class SenseVoiceService : Service() {
private lateinit var senseVoice: SenseVoice

override fun onBind(intent: Intent): IBinder? {
return null
}

override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
senseVoice = SenseVoice.create(applicationContext, "/sdcard/audio.wav", "fsmn-vad", "ct-punc")
senseVoice.startRecording()
return START_STICKY
}

override fun onDestroy() {
super.onDestroy()
senseVoice.stopRecording()
}
}
17 changes: 17 additions & 0 deletions path/to/core/audio/src/androidMain/kotlin/SettingsActivity.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// SettingsActivity.kt
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.example.notelyvoice.R

class SettingsActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_settings)

// Start SenseVoice service
val intent = Intent(this, SenseVoiceService::class.java)
startService(intent)
}
}
85 changes: 85 additions & 0 deletions path/to/sensevoice/kotlin/SenseVoice.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// SenseVoice.kt
import android.content.Context
import android.media.AudioFormat
import android.media.AudioRecord
import android.media.MediaRecorder
import android.os.Build
import androidx.annotation.RequiresApi
import com.google.protobuf.ByteString
import java.io.File
import java.io.IOException
import java.nio.ByteBuffer
import java.nio.ByteOrder
import java.util.*
import kotlin.concurrent.thread

class SenseVoice private constructor(
private val context: Context,
private val audioFilePath: String,
private val vadModel: String,
private val puncModel: String
) {
private var audioRecord: AudioRecord? = null
private var isRecording = false

fun startRecording() {
if (isRecording) {
return
}
isRecording = true
audioRecord = AudioRecord(
MediaRecorder.AudioSource.MIC,
16000,
AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT,
1024 * 10
)
audioRecord?.apply {
startRecording()
thread {
while (isRecording) {
val buffer = ByteArray(1024)
read(buffer, 0, buffer.size)
val audioData = ByteBuffer.wrap(buffer).order(ByteOrder.LITTLE_ENDIAN)
val audioBytes = audioData.array()
val audioString = String(audioBytes.map { it.toInt() }.toTypedArray())
val audioBytesString = ByteString.copyFrom(audioBytes)
// Process audio data using SenseVoice model
processAudioData(audioBytesString)
}
}
}
}

fun stopRecording() {
isRecording = false
audioRecord?.apply {
stop()
release()
}
}

private fun processAudioData(audioBytesString: ByteString) {
// Use SenseVoice model to transcribe audio data
val model = AutoModel(model = "iic/SenseVoiceSmall", vad_model = vadModel, punc_model = puncModel)
val result = model.generate(input = audioBytesString)
// Process transcription result
processTranscriptionResult(result)
}

private fun processTranscriptionResult(result: String) {
// Save transcription result to file
val transcriptionFile = File(audioFilePath + "_transcription.txt")
try {
transcriptionFile.writeText(result)
} catch (e: IOException) {
e.printStackTrace()
}
}

companion object {
fun create(context: Context, audioFilePath: String, vadModel: String, puncModel: String): SenseVoice {
return SenseVoice(context, audioFilePath, vadModel, puncModel)
}
}
}