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;
|
package org.thoughtcrime.securesms.loki.utilities.audio;
|
||||||
|
|
||||||
import android.media.AudioFormat;
|
import android.media.AudioFormat;
|
||||||
|
@ -17,13 +17,13 @@ import kotlin.math.sqrt
|
|||||||
* If number of samples per channel is less than "maxFrames",
|
* If number of samples per channel is less than "maxFrames",
|
||||||
* the result array will match the source sample size instead.
|
* 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 {
|
fun DecodedAudio.calculateRms(maxFrames: Int): FloatArray {
|
||||||
return calculateRms(this.samples, this.numSamples, this.channels, maxFrames)
|
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 numFrames: Int
|
||||||
val frameStep: Float
|
val frameStep: Float
|
||||||
|
|
||||||
@ -65,6 +65,7 @@ private fun calculateRms(samples: ShortBuffer, numSamples: Int, channels: Int, m
|
|||||||
calculateFrameRms(-1)
|
calculateFrameRms(-1)
|
||||||
|
|
||||||
normalizeArray(rmsValues)
|
normalizeArray(rmsValues)
|
||||||
|
// smoothArray(rmsValues, 1.0f)
|
||||||
|
|
||||||
return rmsValues
|
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.
|
* Normalizes the array's values to [0..1] range.
|
||||||
*/
|
*/
|
||||||
private fun normalizeArray(values: FloatArray) {
|
fun normalizeArray(values: FloatArray) {
|
||||||
var maxValue = -Float.MAX_VALUE
|
var maxValue = -Float.MAX_VALUE
|
||||||
var minValue = +Float.MAX_VALUE
|
var minValue = +Float.MAX_VALUE
|
||||||
values.forEach { value ->
|
values.forEach { value ->
|
||||||
@ -87,4 +88,17 @@ private fun normalizeArray(values: FloatArray) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
values.indices.forEach { i -> values[i] = (values[i] - minValue) / span }
|
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.
|
// Parse audio and compute RMS values for the WaveformSeekBar in the background.
|
||||||
asyncCoroutineScope!!.launch {
|
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 {
|
fun extractAttachmentRandomSeed(attachment: Attachment): Int {
|
||||||
return when {
|
return when {
|
||||||
@ -310,6 +310,8 @@ class MessageAudioView: FrameLayout, AudioSlidePlayer.Listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
android.util.Log.d(TAG, "RMS: ${rmsValues.joinToString()}")
|
||||||
|
|
||||||
post {
|
post {
|
||||||
seekBar.sample = rmsValues
|
seekBar.sample = rmsValues
|
||||||
|
|
||||||
|
@ -24,32 +24,15 @@ class WaveformSeekBar : View {
|
|||||||
context.resources.displayMetrics
|
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)
|
var sample: FloatArray = floatArrayOf(0f)
|
||||||
set(value) {
|
set(value) {
|
||||||
if (value.isEmpty()) throw IllegalArgumentException("Sample array cannot be empty")
|
if (value.isEmpty()) throw IllegalArgumentException("Sample array cannot be empty")
|
||||||
|
|
||||||
// field = smooth(value, 0.25f)
|
|
||||||
field = value
|
field = value
|
||||||
invalidate()
|
invalidate()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Indicates whether the user is currently interacting with the view and performing a seeking gesture. */
|
/** Indicates whether the user is currently interacting with the view and performing a seeking gesture. */
|
||||||
private var userSeeking = false
|
private var userSeeking = false
|
||||||
private var _progress: Float = 0f
|
private var _progress: Float = 0f
|
||||||
@ -124,11 +107,6 @@ class WaveformSeekBar : View {
|
|||||||
|
|
||||||
private var canvasWidth = 0
|
private var canvasWidth = 0
|
||||||
private var canvasHeight = 0
|
private var canvasHeight = 0
|
||||||
private var maxValue =
|
|
||||||
dp(
|
|
||||||
context,
|
|
||||||
2f
|
|
||||||
)
|
|
||||||
private var touchDownX = 0f
|
private var touchDownX = 0f
|
||||||
private var scaledTouchSlop = ViewConfiguration.get(context).scaledTouchSlop
|
private var scaledTouchSlop = ViewConfiguration.get(context).scaledTouchSlop
|
||||||
|
|
||||||
@ -177,7 +155,6 @@ class WaveformSeekBar : View {
|
|||||||
|
|
||||||
val totalWidth = getAvailableWith()
|
val totalWidth = getAvailableWith()
|
||||||
|
|
||||||
maxValue = sample.max()!!
|
|
||||||
val step = (totalWidth / (waveGap + waveWidth)) / sample.size
|
val step = (totalWidth / (waveGap + waveWidth)) / sample.size
|
||||||
|
|
||||||
var lastWaveRight = paddingLeft.toFloat()
|
var lastWaveRight = paddingLeft.toFloat()
|
||||||
@ -185,11 +162,7 @@ class WaveformSeekBar : View {
|
|||||||
var i = 0f
|
var i = 0f
|
||||||
while (i < sample.size) {
|
while (i < sample.size) {
|
||||||
|
|
||||||
var waveHeight = if (maxValue != 0f) {
|
var waveHeight = getAvailableHeight() * sample[i.toInt()]
|
||||||
getAvailableHeight() * (sample[i.toInt()] / maxValue)
|
|
||||||
} else {
|
|
||||||
waveMinHeight
|
|
||||||
}
|
|
||||||
|
|
||||||
if (waveHeight < waveMinHeight) {
|
if (waveHeight < waveMinHeight) {
|
||||||
waveHeight = waveMinHeight
|
waveHeight = waveMinHeight
|
||||||
|
Loading…
x
Reference in New Issue
Block a user