Skip to content

Commit

Permalink
Merge pull request #4 from lincollincol/develop
Browse files Browse the repository at this point in the history
Fix amplitudes chunked function
  • Loading branch information
lincollincol authored Oct 7, 2022
2 parents 7fd46df + b4e438e commit 60be437
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -103,28 +103,6 @@ fun AudioWaveformScreen(
scrollEnabled = true
}
)

AudioWaveform(
modifier = Modifier.fillMaxWidth(),
style = Fill,
waveformAlignment = WaveformAlignment.Center,
amplitudeType = AmplitudeType.Avg,
progressBrush = SolidColor(Color.Magenta),
waveformBrush = SolidColor(Color.LightGray),
spikeWidth = 4.dp,
spikePadding = 2.dp,
spikeRadius = 4.dp,
progress = uiState.progress,
amplitudes = uiState.amplitudes,
onProgressChange = {
scrollEnabled = false
onProgressChange(it)
},
onProgressChangeFinished = {
scrollEnabled = true
}
)

Divider(modifier = Modifier.padding(vertical = 8.dp))
LabelSlider(
text = stringResource(id = R.string.spike_width),
Expand Down
33 changes: 18 additions & 15 deletions audiowaveform/src/main/java/com/linc/audiowaveform/AudioWaveform.kt
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ private const val MaxProgress: Float = 1F

private const val MinSpikeHeight: Float = 1F
private const val DefaultGraphicsLayerAlpha: Float = 0.99F
private const val AmplitudeMultiplier: Float = 2F

@OptIn(ExperimentalComposeUiApi::class)
@Composable
Expand All @@ -61,8 +62,8 @@ fun AudioWaveform(
val _spikeTotalWidth = remember(spikeWidth, spikePadding) { _spikeWidth + _spikePadding }
var canvasSize by remember { mutableStateOf(Size(0f, 0f)) }
var spikes by remember { mutableStateOf(0F) }
val pixelAmplitudes = remember(amplitudes, spikes, amplitudeType) {
getPixelAmplitudes(
val spikesAmplitudes = remember(amplitudes, spikes, amplitudeType) {
getSpikesAmplitudes(
amplitudeType = amplitudeType,
amplitudes = amplitudes,
spikes = spikes.toInt(),
Expand Down Expand Up @@ -95,7 +96,7 @@ fun AudioWaveform(
) {
canvasSize = size
spikes = size.width / _spikeTotalWidth.toPx()
pixelAmplitudes.forEachIndexed { index, amplitude ->
spikesAmplitudes.forEachIndexed { index, amplitude ->
drawRoundRect(
brush = waveformBrush,
topLeft = Offset(
Expand Down Expand Up @@ -125,23 +126,25 @@ fun AudioWaveform(
}
}

private fun getPixelAmplitudes(
private fun getSpikesAmplitudes(
amplitudeType: AmplitudeType,
amplitudes: List<Int>,
spikes: Int,
minHeight: Float,
maxHeight: Float
): List<Float> {
return when {
amplitudes.isEmpty() || spikes == 0 -> List(spikes) { minHeight }
amplitudes.count() < spikes -> amplitudes.map(Int::toFloat)
else -> amplitudes.chunked(amplitudes.count() / spikes)
.map {
when(amplitudeType) {
AmplitudeType.Avg -> it.average()
AmplitudeType.Max -> it.max()
AmplitudeType.Min -> it.min()
}.toFloat().times(2).coerceIn(minHeight, maxHeight)
}
if(amplitudes.isEmpty() || spikes == 0) {
return List(spikes) { minHeight }
}
if(amplitudes.count() < spikes) {
return amplitudes.map(Int::toFloat)
}
return amplitudes.map(Int::toFloat)
.chunkedToSize(spikes) {
when(amplitudeType) {
AmplitudeType.Avg -> it.average()
AmplitudeType.Max -> it.max()
AmplitudeType.Min -> it.min()
}.toFloat().times(AmplitudeMultiplier).coerceIn(minHeight, maxHeight)
}
}
21 changes: 21 additions & 0 deletions audiowaveform/src/main/java/com/linc/audiowaveform/Utils.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.linc.audiowaveform

import kotlin.math.ceil
import kotlin.math.roundToInt

internal fun <T> Iterable<T>.chunkedToSize(size: Int, transform: (List<T>) -> T): List<T> {
val chunkSize = count() / size
val remainder = count() % size
val remainderIndex = ceil(count().safeDiv(remainder)).roundToInt()
val chunkIteration = filterIndexed { index, _ ->
remainderIndex == 0 || index % remainderIndex != 0
}.chunked(chunkSize, transform)
return when (size) {
chunkIteration.count() -> chunkIteration
else -> chunkIteration.chunkedToSize(size, transform)
}
}

internal fun Int.safeDiv(value: Int): Float {
return if(value == 0) return 0F else this / value.toFloat()
}

0 comments on commit 60be437

Please sign in to comment.