У меня есть список байтов, которые представляют необработанные выборки, считанные из аудиоинтерфейса. В зависимости от варианта использования и H / W каждая выборка может иметь длину от 1 до 4 байтов, а общее количество каналов в «потоке» может быть более или менее произвольным. Количество каналов и битов на выборку известно во время выполнения.
Я приведу пример того, что я имею в виду. В потоке четыре канала, и каждая выборка занимает два байта.
Список (A1, A2, B1, B2, C1, C2, D1, D2, A3, A4, B3, B4, C3, C4, D3, D4)
, поэтому A1
является первый байт первой выборки канала A , A2
- второй байт той же выборки и так далее.
Что мне нужно сделать, так это извлечь образцы каждого канала в их собственные списки, например:
Список (Список (A1, A2, A3, A4), Список (B1, B2, B3, B4), Список ( 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)
}