«Деинтерлейсинг» список в Scala

У меня есть список байтов, которые представляют необработанные выборки, считанные из аудиоинтерфейса. В зависимости от варианта использования и 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)
}
9
задан tomek 3 November 2011 в 09:37
поделиться