mirror of
https://github.com/oxen-io/session-android.git
synced 2024-12-25 09:17:44 +00:00
Normalization and smooth functions moved to the extension file.
This commit is contained in:
parent
6df3264692
commit
8cbb34f174
@ -1,19 +1,3 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.loki.utilities.audio;
|
||||
|
||||
import android.media.AudioFormat;
|
||||
|
@ -17,13 +17,13 @@ import kotlin.math.sqrt
|
||||
* If number of samples per channel is less than "maxFrames",
|
||||
* the result array will match the source sample size instead.
|
||||
*
|
||||
* @return Normalized RMS values float array.
|
||||
* @return RMS values float array where is each value is within [0..1] range.
|
||||
*/
|
||||
fun DecodedAudio.calculateRms(maxFrames: Int): FloatArray {
|
||||
return calculateRms(this.samples, this.numSamples, this.channels, maxFrames)
|
||||
}
|
||||
|
||||
private fun calculateRms(samples: ShortBuffer, numSamples: Int, channels: Int, maxFrames: Int): FloatArray {
|
||||
fun calculateRms(samples: ShortBuffer, numSamples: Int, channels: Int, maxFrames: Int): FloatArray {
|
||||
val numFrames: Int
|
||||
val frameStep: Float
|
||||
|
||||
@ -65,6 +65,7 @@ private fun calculateRms(samples: ShortBuffer, numSamples: Int, channels: Int, m
|
||||
calculateFrameRms(-1)
|
||||
|
||||
normalizeArray(rmsValues)
|
||||
// smoothArray(rmsValues, 1.0f)
|
||||
|
||||
return rmsValues
|
||||
}
|
||||
@ -72,7 +73,7 @@ private fun calculateRms(samples: ShortBuffer, numSamples: Int, channels: Int, m
|
||||
/**
|
||||
* Normalizes the array's values to [0..1] range.
|
||||
*/
|
||||
private fun normalizeArray(values: FloatArray) {
|
||||
fun normalizeArray(values: FloatArray) {
|
||||
var maxValue = -Float.MAX_VALUE
|
||||
var minValue = +Float.MAX_VALUE
|
||||
values.forEach { value ->
|
||||
@ -87,4 +88,17 @@ private fun normalizeArray(values: FloatArray) {
|
||||
}
|
||||
|
||||
values.indices.forEach { i -> values[i] = (values[i] - minValue) / span }
|
||||
}
|
||||
|
||||
fun smoothArray(values: FloatArray, neighborWeight: Float = 1f): FloatArray {
|
||||
if (values.size < 3) return values
|
||||
|
||||
val result = FloatArray(values.size)
|
||||
result[0] = values[0]
|
||||
result[values.size - 1] == values[values.size - 1]
|
||||
for (i in 1 until values.size - 1) {
|
||||
result[i] = (values[i] + values[i - 1] * neighborWeight +
|
||||
values[i + 1] * neighborWeight) / (1f + neighborWeight * 2f)
|
||||
}
|
||||
return result
|
||||
}
|
@ -276,7 +276,7 @@ class MessageAudioView: FrameLayout, AudioSlidePlayer.Listener {
|
||||
|
||||
// Parse audio and compute RMS values for the WaveformSeekBar in the background.
|
||||
asyncCoroutineScope!!.launch {
|
||||
val rmsFrames = 32 // The amount of values to be computed to supply for the visualization.
|
||||
val rmsFrames = 32 // The amount of values to be computed for the visualization.
|
||||
|
||||
fun extractAttachmentRandomSeed(attachment: Attachment): Int {
|
||||
return when {
|
||||
@ -310,6 +310,8 @@ class MessageAudioView: FrameLayout, AudioSlidePlayer.Listener {
|
||||
}
|
||||
}
|
||||
|
||||
android.util.Log.d(TAG, "RMS: ${rmsValues.joinToString()}")
|
||||
|
||||
post {
|
||||
seekBar.sample = rmsValues
|
||||
|
||||
|
@ -24,32 +24,15 @@ class WaveformSeekBar : View {
|
||||
context.resources.displayMetrics
|
||||
)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
inline fun smooth(values: FloatArray, neighborWeight: Float = 1f): FloatArray {
|
||||
if (values.size < 3) return values
|
||||
|
||||
val result = FloatArray(values.size)
|
||||
result[0] = values[0]
|
||||
result[values.size - 1] == values[values.size - 1]
|
||||
for (i in 1 until values.size - 1) {
|
||||
result[i] =
|
||||
(values[i] + values[i - 1] * neighborWeight + values[i + 1] * neighborWeight) / (1f + neighborWeight * 2f)
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
var sample: FloatArray = floatArrayOf(0f)
|
||||
set(value) {
|
||||
if (value.isEmpty()) throw IllegalArgumentException("Sample array cannot be empty")
|
||||
|
||||
// field = smooth(value, 0.25f)
|
||||
field = value
|
||||
invalidate()
|
||||
}
|
||||
|
||||
|
||||
/** Indicates whether the user is currently interacting with the view and performing a seeking gesture. */
|
||||
private var userSeeking = false
|
||||
private var _progress: Float = 0f
|
||||
@ -124,11 +107,6 @@ class WaveformSeekBar : View {
|
||||
|
||||
private var canvasWidth = 0
|
||||
private var canvasHeight = 0
|
||||
private var maxValue =
|
||||
dp(
|
||||
context,
|
||||
2f
|
||||
)
|
||||
private var touchDownX = 0f
|
||||
private var scaledTouchSlop = ViewConfiguration.get(context).scaledTouchSlop
|
||||
|
||||
@ -177,7 +155,6 @@ class WaveformSeekBar : View {
|
||||
|
||||
val totalWidth = getAvailableWith()
|
||||
|
||||
maxValue = sample.max()!!
|
||||
val step = (totalWidth / (waveGap + waveWidth)) / sample.size
|
||||
|
||||
var lastWaveRight = paddingLeft.toFloat()
|
||||
@ -185,11 +162,7 @@ class WaveformSeekBar : View {
|
||||
var i = 0f
|
||||
while (i < sample.size) {
|
||||
|
||||
var waveHeight = if (maxValue != 0f) {
|
||||
getAvailableHeight() * (sample[i.toInt()] / maxValue)
|
||||
} else {
|
||||
waveMinHeight
|
||||
}
|
||||
var waveHeight = getAvailableHeight() * sample[i.toInt()]
|
||||
|
||||
if (waveHeight < waveMinHeight) {
|
||||
waveHeight = waveMinHeight
|
||||
|
Loading…
x
Reference in New Issue
Block a user