我有一个字节列表,代表从音频接口(interface)读取的原始样本。根据用例和硬件,每个样本的长度可以是 1 到 4 个字节,并且“流”中的 channel 总数可以或多或少是任意的。每个样本的 channel 数和比特数在运行时都是已知的。
我将举例说明我的意思。流中有四个 channel ,每个样本是两个字节。List(A1, A2, B1, B2, C1, C2, D1, D2, A3, A4, B3, B4, C3, C4, D3, D4)
所以A1
是 channel A 的第一个样本的第一个字节,A2
是同一样本的第二个字节,依此类推。
我需要做的是将每个 channel 的样本提取到他们自己的列表中,如下所示:List(List(A1, A2, A3, A4), List(B1, B2, B3, B4), List(C1, C2, C3, C4), List(D1, D2, D3, D4))
我将如何在惯用的 Scala 中执行此操作?我几个小时前才开始学习 Scala,而我想出的唯一非必要的解决方案显然不是最优的:
def uninterleave(samples: Array[Byte], numChannels: Int, bytesPerSample: Int) = {
val dropAmount = numChannels * bytesPerSample
def extractChannel(n: Int) = {
def extrInner(in: Seq[Byte], acc: Seq[Byte]): Seq[Byte] = {
if(in == List()) acc
else extrInner(in.drop(dropAmount), in.take(bytesPerSample) ++ acc)
}
extrInner(samples.drop(n * bytesPerSample), Nil)
}
for(i <- 0 until numChannels) yield extractChannel(i)
}
最佳答案
我会做
samples.grouped(bytesPerSample).grouped(numChannels).toList
.transpose.map(_.flatten)
不过,我不会保证它的性能。我宁愿避免列表,不幸的是
grouped
生产它们。也许
samples.grouped(bytesPerSample).map(_.toArray)
.grouped(numChannels).map(_.toArray)
.toArray
.transpose
.map(flatten)
尽管如此,还是有很多 list 。
关于list - "Deinterlacing"Scala 中的列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7992429/