mirror of
https://github.com/Myzel394/Alibi.git
synced 2025-06-19 07:15:25 +02:00
feat: Improve AudioVisualizer, add visualizer to StartRecording for old recording
This commit is contained in:
parent
9b1a439657
commit
f0f20a6594
@ -0,0 +1,5 @@
|
|||||||
|
package app.myzel394.locationtest.ui
|
||||||
|
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
|
||||||
|
val BIG_PRIMARY_BUTTON_SIZE = 64.dp
|
@ -1,6 +1,7 @@
|
|||||||
package app.myzel394.locationtest.ui.components.AudioRecorder.atoms
|
package app.myzel394.locationtest.ui.components.AudioRecorder.atoms
|
||||||
|
|
||||||
import androidx.compose.foundation.Canvas
|
import androidx.compose.foundation.Canvas
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
@ -19,12 +20,15 @@ private const val MAX_AMPLITUDE = 10000
|
|||||||
@Composable
|
@Composable
|
||||||
fun AudioVisualizer(
|
fun AudioVisualizer(
|
||||||
amplitudes: List<Int>,
|
amplitudes: List<Int>,
|
||||||
|
showAll: Boolean = false
|
||||||
) {
|
) {
|
||||||
val primary = MaterialTheme.colorScheme.primary
|
val primary = MaterialTheme.colorScheme.primary
|
||||||
val primaryMuted = primary.copy(alpha = 0.3f)
|
val primaryMuted = primary.copy(alpha = 0.3f)
|
||||||
|
|
||||||
Canvas(
|
Canvas(
|
||||||
modifier = Modifier.width(300.dp).height(300.dp)
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.height(300.dp),
|
||||||
) {
|
) {
|
||||||
val height = this.size.height / 2f
|
val height = this.size.height / 2f
|
||||||
val width = this.size.width
|
val width = this.size.width
|
||||||
@ -32,14 +36,17 @@ fun AudioVisualizer(
|
|||||||
translate(width, height) {
|
translate(width, height) {
|
||||||
amplitudes.forEachIndexed { index, amplitude ->
|
amplitudes.forEachIndexed { index, amplitude ->
|
||||||
val amplitudePercentage = (amplitude.toFloat() / MAX_AMPLITUDE).coerceAtMost(1f)
|
val amplitudePercentage = (amplitude.toFloat() / MAX_AMPLITUDE).coerceAtMost(1f)
|
||||||
|
val boxWidth = if (showAll) width / amplitudes.size else 15f
|
||||||
val boxHeight = height * amplitudePercentage
|
val boxHeight = height * amplitudePercentage
|
||||||
|
|
||||||
drawRoundRect(
|
drawRoundRect(
|
||||||
color = if (amplitudePercentage > 0.05f) primary else primaryMuted,
|
color = if (amplitudePercentage > 0.05f) primary else primaryMuted,
|
||||||
topLeft = Offset(
|
topLeft = Offset(
|
||||||
30f * (index - amplitudes.size),
|
if (showAll) -width / amplitudes.size * index
|
||||||
|
else 30f * (index - amplitudes.size),
|
||||||
-boxHeight / 2f
|
-boxHeight / 2f
|
||||||
),
|
),
|
||||||
size = Size(15f, boxHeight),
|
size = Size(boxWidth, boxHeight),
|
||||||
cornerRadius = CornerRadius(3f, 3f)
|
cornerRadius = CornerRadius(3f, 3f)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ import androidx.compose.foundation.layout.Column
|
|||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.layout.width
|
||||||
@ -32,6 +33,7 @@ import androidx.compose.ui.graphics.Color
|
|||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import app.myzel394.locationtest.services.RecorderService
|
import app.myzel394.locationtest.services.RecorderService
|
||||||
|
import app.myzel394.locationtest.ui.BIG_PRIMARY_BUTTON_SIZE
|
||||||
import app.myzel394.locationtest.ui.components.atoms.Pulsating
|
import app.myzel394.locationtest.ui.components.atoms.Pulsating
|
||||||
import app.myzel394.locationtest.ui.utils.formatDuration
|
import app.myzel394.locationtest.ui.utils.formatDuration
|
||||||
import app.myzel394.locationtest.ui.utils.rememberFileSaverDialog
|
import app.myzel394.locationtest.ui.utils.rememberFileSaverDialog
|
||||||
@ -63,38 +65,53 @@ fun RecordingStatus(
|
|||||||
Column(
|
Column(
|
||||||
modifier = Modifier.fillMaxSize(),
|
modifier = Modifier.fillMaxSize(),
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
verticalArrangement = Arrangement.Center,
|
verticalArrangement = Arrangement.SpaceBetween,
|
||||||
) {
|
) {
|
||||||
|
Box {}
|
||||||
AudioVisualizer(amplitudes = service.amplitudes)
|
AudioVisualizer(amplitudes = service.amplitudes)
|
||||||
|
Column(
|
||||||
Row(
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
|
||||||
horizontalArrangement = Arrangement.Center,
|
|
||||||
) {
|
) {
|
||||||
val distance = Duration.between(service.recordingStart.value, now).toMillis()
|
Row(
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
horizontalArrangement = Arrangement.Center,
|
||||||
|
) {
|
||||||
|
val distance = Duration.between(service.recordingStart.value, now).toMillis()
|
||||||
|
|
||||||
Pulsating {
|
Pulsating {
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.size(16.dp)
|
.size(16.dp)
|
||||||
.clip(CircleShape)
|
.clip(CircleShape)
|
||||||
.background(Color.Red)
|
.background(Color.Red)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Spacer(modifier = Modifier.width(16.dp))
|
||||||
|
Text(
|
||||||
|
text = formatDuration(distance),
|
||||||
|
style = MaterialTheme.typography.headlineLarge,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Spacer(modifier = Modifier.width(16.dp))
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
Text(
|
LinearProgressIndicator(
|
||||||
text = formatDuration(distance),
|
progress = progress,
|
||||||
style = MaterialTheme.typography.headlineLarge,
|
modifier = Modifier
|
||||||
|
.width(300.dp)
|
||||||
)
|
)
|
||||||
|
Spacer(modifier = Modifier.height(32.dp))
|
||||||
|
Button(
|
||||||
|
onClick = {
|
||||||
|
RecorderService.stopService(context)
|
||||||
|
},
|
||||||
|
colors = ButtonDefaults.textButtonColors(),
|
||||||
|
) {
|
||||||
|
Text("Cancel")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Spacer(modifier = Modifier.height(8.dp))
|
|
||||||
LinearProgressIndicator(
|
|
||||||
progress = progress,
|
|
||||||
modifier = Modifier
|
|
||||||
.width(300.dp)
|
|
||||||
)
|
|
||||||
Spacer(modifier = Modifier.height(32.dp))
|
|
||||||
Button(
|
Button(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.height(BIG_PRIMARY_BUTTON_SIZE),
|
||||||
onClick = {
|
onClick = {
|
||||||
RecorderService.stopService(context)
|
RecorderService.stopService(context)
|
||||||
|
|
||||||
@ -107,13 +124,5 @@ fun RecordingStatus(
|
|||||||
)
|
)
|
||||||
Text("Save Recording")
|
Text("Save Recording")
|
||||||
}
|
}
|
||||||
Button(
|
|
||||||
onClick = {
|
|
||||||
RecorderService.stopService(context)
|
|
||||||
},
|
|
||||||
colors = ButtonDefaults.textButtonColors(),
|
|
||||||
) {
|
|
||||||
Text("Cancel")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -6,6 +6,7 @@ import androidx.compose.foundation.layout.Box
|
|||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.layout.width
|
||||||
@ -27,6 +28,7 @@ import androidx.compose.ui.semantics.contentDescription
|
|||||||
import androidx.compose.ui.semantics.semantics
|
import androidx.compose.ui.semantics.semantics
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import app.myzel394.locationtest.services.RecorderService
|
import app.myzel394.locationtest.services.RecorderService
|
||||||
|
import app.myzel394.locationtest.ui.BIG_PRIMARY_BUTTON_SIZE
|
||||||
import app.myzel394.locationtest.ui.utils.rememberFileSaverDialog
|
import app.myzel394.locationtest.ui.utils.rememberFileSaverDialog
|
||||||
import java.time.format.DateTimeFormatter
|
import java.time.format.DateTimeFormatter
|
||||||
|
|
||||||
@ -45,6 +47,9 @@ fun StartRecording(
|
|||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
) {
|
) {
|
||||||
Box {}
|
Box {}
|
||||||
|
if (service != null && service.amplitudes.isNotEmpty()) {
|
||||||
|
Box {}
|
||||||
|
}
|
||||||
Button(
|
Button(
|
||||||
onClick = {
|
onClick = {
|
||||||
RecorderService.startService(context, connection)
|
RecorderService.startService(context, connection)
|
||||||
@ -73,8 +78,14 @@ fun StartRecording(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (service != null && service.amplitudes.isNotEmpty()) {
|
||||||
|
AudioVisualizer(amplitudes = service.amplitudes, showAll = true)
|
||||||
|
}
|
||||||
if (service?.originalRecordingStart != null)
|
if (service?.originalRecordingStart != null)
|
||||||
Button(
|
Button(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.height(BIG_PRIMARY_BUTTON_SIZE),
|
||||||
onClick = {
|
onClick = {
|
||||||
saveFile(service.concatenateFiles())
|
saveFile(service.concatenateFiles())
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user