Hay un Flujo que emitirá datos cada 100 ms, y espero obtener un valor promedio de los últimos 5 datos del Flujo y convertir el valor promedio como Valor doble en otro Flujo.
¿Cómo puedo diseñar el Flujo?
Código A
fun soundDbFlow(period: Long = 100) = flow { while (true) { var data = getAmplitude() emit(data) delay(period) } } .get_Average_Per5_LatestData {...} //How can I do? or is there other way? .map { soundDb(it) } private fun getAmplitude(): Int { var result = 0 mRecorder?.let { result = it.maxAmplitude } return result } private fun soundDb(input:Int, referenceAmp: Double = 1.0): Double { return 20 * Math.log10(input / referenceAmp) }Contenido agregado:
Para plplmax: ¡Gracias!
Supongo que el Código B emitirá 1,2,3,4,5,6,7,8,9,10...
¿Garantiza que el Código C calculará (1+2+3+4+5)/5 primero, luego calculará (6+7+8+9+10)/5 segundo,...? es mi expectativa
Me preocupa que el Código C tal vez calcule (1+2+3+4+5)/5 primero, el cálculo (2+3+4+5+6)/5 segundo,...
Código B
suspend fun soundDbFlow(period: Long) = flow { while (true) { val data = getAmplitude() emit(data) delay(period) } }Código C
private fun reduceFlow(period: Long = 100) = flow { while (true) { val result = soundDbFlow(period) .take(5) .map { soundDb((it / 5.0).roundToInt()) } .reduce { accumulator, value -> accumulator + value } emit(result) } }Puede escribir un operador fragmentado como este:
/** * Returns a Flow that emits sequential [size]d chunks of data from the source flow, * after transforming them with [transform]. * * The list passed to [transform] is transient and must not be cached. */ fun <T, R> Flow<T>.chunked(size: Int, transform: suspend (List<T>)-> R): Flow<R> = flow { val cache = ArrayList<T>(size) collect { cache.add(it) if (cache.size == size) { emit(transform(cache)) cache.clear() } } }Y luego utilízalo así:
suspend fun soundDbFlow(period: Long) = flow { while (true) { val data = getAmplitude() emit(data) delay(period) } } .chunked(5) { (it.sum() / 5.0).roundToInt() } .map { soundDb(it) }¿Es eso lo que quieres?
var result = 0 fun soundDbFlow(period: Long) = flow { while (true) { delay(period) val data = getAmplitude() emit(data) } } fun reduceFlow(period: Long = 100) = flow { while (true) { val sum = soundDbFlow(period) .take(5) .reduce { accumulator, value -> accumulator + value } val average = (sum / 5.0).roundToInt() emit(soundDb(average)) } } fun getAmplitude(): Int { return ++result } fun soundDb(input: Int, referenceAmp: Double = 1.0): Double { return 20 * log10(input / referenceAmp) } fun main(): Unit = runBlocking { reduceFlow().collect { println(it) } }