@@ -9,86 +9,93 @@ import android.media.audiofx.AcousticEchoCanceler
99import kotlinx.coroutines.flow.Flow
1010import kotlinx.coroutines.flow.flow
1111
12-
13-
1412internal class AudioHelper {
1513
16- private lateinit var audioRecord: AudioRecord
17- private lateinit var audioTrack: AudioTrack
18- private var stopRecording: Boolean = false
19- private val RECORDER_SAMPLE_RATE = 16000 // Adjust based on server settings
20- private val RECORDER_CHANNEL_CONFIG = AudioFormat .CHANNEL_IN_MONO
21- private val RECORDER_AUDIO_FORMAT = AudioFormat .ENCODING_PCM_16BIT
14+ private lateinit var audioRecord: AudioRecord
15+ private lateinit var audioTrack: AudioTrack
16+ private var stopRecording: Boolean = false
17+ private val RECORDER_SAMPLE_RATE = 16000 // Adjust based on server settings
18+ private val RECORDER_CHANNEL_CONFIG = AudioFormat .CHANNEL_IN_MONO
19+ private val RECORDER_AUDIO_FORMAT = AudioFormat .ENCODING_PCM_16BIT
2220
23- internal fun release () {
24- stopRecording = true
25- if (::audioRecord.isInitialized) {
26- audioRecord.stop()
27- audioRecord.release()
28- }
29- if (::audioTrack.isInitialized) {
30- audioTrack.stop()
31- audioTrack.release()
32- }
21+ internal fun release () {
22+ stopRecording = true
23+ if (::audioRecord.isInitialized) {
24+ audioRecord.stop()
25+ audioRecord.release()
3326 }
34-
35- internal fun setupAudioTrack () {
36- val sampleRate = 24000 // Adjust based on server settings
37- val channelConfig = AudioFormat .CHANNEL_OUT_MONO
38- val audioFormat = AudioFormat .ENCODING_PCM_16BIT
39- val minBufferSize = AudioTrack .getMinBufferSize(sampleRate, channelConfig, audioFormat)
40- audioTrack = AudioTrack (
41- AudioManager .STREAM_MUSIC ,
42- sampleRate,
43- channelConfig,
44- audioFormat,
45- minBufferSize,
46- AudioTrack .MODE_STREAM
47- )
48- audioTrack.play()
27+ if (::audioTrack.isInitialized) {
28+ audioTrack.stop()
29+ audioTrack.release()
4930 }
31+ }
5032
51- internal fun playAudio (data : ByteArray ) {
52- if (! stopRecording) {
53- audioTrack.write(data, 0 , data.size)
54- }
33+ internal fun setupAudioTrack () {
34+ val sampleRate = 24000 // Adjust based on server settings
35+ val channelConfig = AudioFormat .CHANNEL_OUT_MONO
36+ val audioFormat = AudioFormat .ENCODING_PCM_16BIT
37+ val minBufferSize = AudioTrack .getMinBufferSize(sampleRate, channelConfig, audioFormat)
38+ audioTrack =
39+ AudioTrack (
40+ AudioManager .STREAM_MUSIC ,
41+ sampleRate,
42+ channelConfig,
43+ audioFormat,
44+ minBufferSize,
45+ AudioTrack .MODE_STREAM
46+ )
47+ audioTrack.play()
48+ }
49+
50+ internal fun playAudio (data : ByteArray ) {
51+ if (! stopRecording) {
52+ audioTrack.write(data, 0 , data.size)
5553 }
54+ }
5655
57- suspend fun startRecording (): Flow <ByteArray > {
58- val bufferSize = AudioRecord .getMinBufferSize(RECORDER_SAMPLE_RATE , RECORDER_CHANNEL_CONFIG , RECORDER_AUDIO_FORMAT )
59- if (bufferSize == AudioRecord .ERROR || bufferSize == AudioRecord .ERROR_BAD_VALUE || bufferSize <= 0 ) {
60- println (" Invalid buffer size: $bufferSize " )
61- }
62- audioRecord = AudioRecord (
63- MediaRecorder .AudioSource .VOICE_COMMUNICATION ,
64- RECORDER_SAMPLE_RATE ,
65- RECORDER_CHANNEL_CONFIG ,
66- RECORDER_AUDIO_FORMAT ,
67- bufferSize
68- )
69- if (audioRecord.state != AudioRecord .STATE_INITIALIZED ) {
70- println (" AudioRecord initialization failed." )
71- }
72- if (AcousticEchoCanceler .isAvailable()) {
73- val echoCanceler = AcousticEchoCanceler .create(audioRecord.audioSessionId)
74- echoCanceler?.enabled = true
75- }
56+ suspend fun startRecording (): Flow <ByteArray > {
57+ val bufferSize =
58+ AudioRecord .getMinBufferSize(
59+ RECORDER_SAMPLE_RATE ,
60+ RECORDER_CHANNEL_CONFIG ,
61+ RECORDER_AUDIO_FORMAT
62+ )
63+ if (
64+ bufferSize == AudioRecord .ERROR ||
65+ bufferSize == AudioRecord .ERROR_BAD_VALUE ||
66+ bufferSize <= 0
67+ ) {
68+ println (" Invalid buffer size: $bufferSize " )
69+ }
70+ audioRecord =
71+ AudioRecord (
72+ MediaRecorder .AudioSource .VOICE_COMMUNICATION ,
73+ RECORDER_SAMPLE_RATE ,
74+ RECORDER_CHANNEL_CONFIG ,
75+ RECORDER_AUDIO_FORMAT ,
76+ bufferSize
77+ )
78+ if (audioRecord.state != AudioRecord .STATE_INITIALIZED ) {
79+ println (" AudioRecord initialization failed." )
80+ }
81+ if (AcousticEchoCanceler .isAvailable()) {
82+ val echoCanceler = AcousticEchoCanceler .create(audioRecord.audioSessionId)
83+ echoCanceler?.enabled = true
84+ }
7685
77- audioRecord.startRecording()
86+ audioRecord.startRecording()
7887
79- return flow {
80- while (true ) {
81- if (stopRecording) {
82- break
83- }
84- val buffer = ByteArray (bufferSize/ 2 )
85- val bytesRead = audioRecord.read(
86- buffer, 0 , buffer.size
87- )
88- if (bytesRead> 0 ) {
89- emit(buffer.copyOf(bytesRead))
90- }
91- }
88+ return flow {
89+ while (true ) {
90+ if (stopRecording) {
91+ break
92+ }
93+ val buffer = ByteArray (bufferSize / 2 )
94+ val bytesRead = audioRecord.read(buffer, 0 , buffer.size)
95+ if (bytesRead > 0 ) {
96+ emit(buffer.copyOf(bytesRead))
9297 }
98+ }
9399 }
94- }
100+ }
101+ }
0 commit comments