Skip to content
Merged
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
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package io.github.teamclouday.androidMic

import android.content.Context
import android.media.MediaRecorder
import android.os.Build
import androidx.annotation.RequiresApi
import androidx.compose.runtime.Composable
import androidx.compose.ui.res.stringResource
import io.github.teamclouday.androidMic.ChannelCount.Mono
import io.github.teamclouday.androidMic.ui.utils.UiHelper
import io.github.teamclouday.androidMic.utils.PreferencesManager

Expand All @@ -31,11 +33,33 @@ class AppPreferences(
val dynamicColor = booleanPreference("dynamicColor", true)

val sampleRate = enumPreference("sampleRate", SampleRates.S44100)
val channelCount = enumPreference("channelCount", ChannelCount.Mono)
val channelCount = enumPreference("channelCount", Mono)
val audioFormat = enumPreference("audioFormat", AudioFormat.I16)
val audioSource = enumPreference("audioSource", AudioSource.Mic)

}

enum class AudioSource {
Mic,
Recognition,
Communication,
Performance;

fun getSource(): Int {

return when (this) {
Mic -> MediaRecorder.AudioSource.MIC
Recognition -> MediaRecorder.AudioSource.VOICE_RECOGNITION
Communication -> MediaRecorder.AudioSource.VOICE_COMMUNICATION
Performance -> if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
MediaRecorder.AudioSource.VOICE_PERFORMANCE
} else {
MediaRecorder.AudioSource.MIC
}
}
}
}

enum class Mode {
WIFI, UDP, USB, ADB
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import android.content.Context
import android.content.pm.PackageManager
import android.media.AudioFormat
import android.media.AudioRecord
import android.media.MediaRecorder
import android.util.Log
import androidx.core.content.ContextCompat
import io.github.teamclouday.androidMic.domain.service.AudioPacket
Expand All @@ -28,8 +27,8 @@ class MicAudioManager(
val scope: CoroutineScope,
val sampleRate: Int,
val audioFormat: Int,
val channelCount: Int

val channelCount: Int,
val audioSource: Int,
) {

companion object {
Expand Down Expand Up @@ -74,7 +73,7 @@ class MicAudioManager(

// init recorder
recorder = AudioRecord(
MediaRecorder.AudioSource.MIC,
audioSource,
sampleRate,
channelConfig,
audioFormat,
Expand Down Expand Up @@ -122,7 +121,7 @@ class MicAudioManager(
packetBuffer = ByteArray(0)
}
} else {
readCount = recorder.read(buffer, 0, buffer.size)
readCount = recorder.read(buffer, 0, buffer.size, AudioRecord.READ_BLOCKING)

if (readCount > 0) {
packetBuffer = ByteArray(readCount)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ private const val ID_PORT: String = "ID_PORT"
private const val ID_SAMPLE_RATE: String = "ID_SAMPLE_RATE"
private const val ID_CHANNEL_COUNT: String = "ID_CHANNEL_COUNT"
private const val ID_AUDIO_FORMAT: String = "ID_AUDIO_FORMAT"
private const val ID_AUDIO_SOURCE: String = "ID_AUDIO_SOURCE"


/**
Expand All @@ -56,6 +57,7 @@ data class CommandData(
val sampleRate: SampleRates? = null,
val channelCount: ChannelCount? = null,
val audioFormat: AudioFormat? = null,
val audioSource: Int? = null,
) {

companion object {
Expand All @@ -69,6 +71,7 @@ data class CommandData(
channelCount = msg.data.getOrdinal(ID_CHANNEL_COUNT)
?.let { ChannelCount.entries[it] },
audioFormat = msg.data.getOrdinal(ID_AUDIO_FORMAT)?.let { AudioFormat.entries[it] },
audioSource = msg.data.getInt(ID_AUDIO_SOURCE).let { if (it == -1) null else it },
)
}

Expand All @@ -85,6 +88,7 @@ data class CommandData(
sampleRate = prefs.sampleRate.get(),
channelCount = prefs.channelCount.get(),
audioFormat = prefs.audioFormat.get(),
audioSource = prefs.audioSource.get().getSource(),
mode = mode
)

Expand Down Expand Up @@ -133,6 +137,8 @@ data class CommandData(
this.channelCount?.let { data.putInt(ID_CHANNEL_COUNT, it.ordinal) }
this.audioFormat?.let { data.putInt(ID_AUDIO_FORMAT, it.ordinal) }

data.putInt(ID_AUDIO_SOURCE, this.audioSource ?: -1)

val message = Message.obtain()
message.data = data
message.what = this.command.ordinal
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,7 @@ class ForegroundService : Service() {
sampleRate = msg.sampleRate!!.value,
audioFormat = msg.audioFormat!!.value,
channelCount = msg.channelCount!!.value,
audioSource = msg.audioSource!!,
)
} catch (e: IllegalArgumentException) {
reply(replyTo, ResponseData(msg = application.getString(R.string.error) + e.message))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,15 @@ import Message.Messages
import android.os.Messenger
import android.util.Log
import com.google.protobuf.ByteString
import com.google.protobuf.CodedOutputStream
import io.github.teamclouday.androidMic.domain.service.AudioPacket
import io.github.teamclouday.androidMic.utils.toBigEndianU32
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.net.DatagramPacket
import java.net.DatagramSocket
import java.net.InetAddress
Expand Down Expand Up @@ -97,19 +100,27 @@ class UdpStreamer(private val scope: CoroutineScope, val ip: String, var port: I
)
.build()

val size = message.serializedSize
val prefix = size.toBigEndianU32()
val out = ByteArray(4 + size)
System.arraycopy(prefix, 0, out, 0, 4)

val pack = message.toByteArray()
val combined = pack.size.toBigEndianU32() + pack
val outputStream = CodedOutputStream.newInstance(out, 4, message.serializedSize)

message.writeTo(outputStream)
outputStream.flush()

val packet = DatagramPacket(
combined,
out,
0,
combined.size,
out.size,
address,
port
)

socket.send(packet)
withContext(Dispatchers.IO) {
socket.send(packet)
}
} catch (e: Exception) {
Log.d(TAG, "stream: ${e.message}")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import androidx.lifecycle.viewModelScope
import io.github.teamclouday.androidMic.AndroidMicApp
import io.github.teamclouday.androidMic.AppPreferences
import io.github.teamclouday.androidMic.AudioFormat
import io.github.teamclouday.androidMic.AudioSource
import io.github.teamclouday.androidMic.ChannelCount
import io.github.teamclouday.androidMic.Dialogs
import io.github.teamclouday.androidMic.Mode
Expand Down Expand Up @@ -181,6 +182,13 @@ class MainViewModel : ViewModel() {
}
}

fun setAudioSource(audioSource: AudioSource) {
viewModelScope.launch {
prefs.audioSource.update(audioSource)
}
}



fun setTheme(theme: Themes) {
viewModelScope.launch {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import io.github.teamclouday.androidMic.Mode
import io.github.teamclouday.androidMic.R
import io.github.teamclouday.androidMic.ui.MainViewModel
import io.github.teamclouday.androidMic.ui.home.dialog.DialogAudioFormat
import io.github.teamclouday.androidMic.ui.home.dialog.DialogAudioSource
import io.github.teamclouday.androidMic.ui.home.dialog.DialogChannelCount
import io.github.teamclouday.androidMic.ui.home.dialog.DialogIpPort
import io.github.teamclouday.androidMic.ui.home.dialog.DialogMode
Expand Down Expand Up @@ -132,6 +133,17 @@ fun DrawerBody(vm: MainViewModel) {
expanded = dialogAudioFormatExpanded
)

val dialogAudioSourceExpanded = rememberSaveable {
mutableStateOf(false)
}
DialogAudioSource(vm = vm, expanded = dialogAudioSourceExpanded)
SettingsItem(
title = stringResource(id = R.string.audio_source),
subTitle = vm.prefs.audioSource.getAsState().value.toString(),
contentDescription = "set audio source",
expanded = dialogAudioSourceExpanded
)

// Other
SettingsItemsSubtitle(R.string.drawer_subtitle_other)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package io.github.teamclouday.androidMic.ui.home.dialog
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import io.github.teamclouday.androidMic.AudioFormat
import io.github.teamclouday.androidMic.AudioSource
import io.github.teamclouday.androidMic.ChannelCount
import io.github.teamclouday.androidMic.SampleRates
import io.github.teamclouday.androidMic.ui.MainViewModel
Expand Down Expand Up @@ -44,4 +45,17 @@ fun DialogAudioFormat(
onClick = { vm.setAudioFormat(it) },
text = { it.toString() }
)
}

@Composable
fun DialogAudioSource(
vm: MainViewModel,
expanded: MutableState<Boolean>,
) {
DialogList(
expanded,
enum = AudioSource.entries,
onClick = { vm.setAudioSource(it) },
text = { it.toString() }
)
}
1 change: 1 addition & 0 deletions Android/app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
<string name="sample_rate">Sample Rate</string>
<string name="channel_count">Channel Count</string>
<string name="audio_format">Audio Format</string>
<string name="audio_source">Audio Source</string>

<string name="drawerTheme">Themes</string>
<string name="dynamic_color">Dynamic color</string>
Expand Down
Loading
Loading