1
我正在尝试处理音频信号的通道。我得到信号作为帧的列表,其中每个帧具有每个通道的样本。现在我想独立处理这些流,然后再合并它们。所以,我想写清单解复用器
type Sample = Double
type Frame = [Sample]
type Stream = [Sample]
mux :: [Stream] -> [Frame]
demux :: [Frame] -> [Stream]
process :: Stream -> Stream
output = (mux . (map process) . demux) input
mux [[0.1, -0.1, -0.3], [0.2, 0.4, 0.6]] = [[0.1, 0.2], [-0.1, 0.4], [-0.3, 0.6]]
demux [[0.1, 0.2], [-0.1, 0.4], [-0.3, 0.6]] = [[0.1, -0.1, -0.3], [0.2, 0.4, 0.6]]
由于流长,mux
和demux
必须偷懒,不评估整个列表。
复用器看起来很简单。我不喜欢这个版本的唯一的东西是难以阅读的模式匹配。
mux [email protected]((_:_):_) = map head streams : mux (map tail streams)
mux _ = []
但是,我不能轻易想出一个多路解复用器,将帧的列表转换为流的列表。因为在我的情况下,不会有两个以上的流(立体声音频),我想我可以通过编写两个分路器monoDemux
和stereoDemux
来管理。但我希望有一个功能可以处理任意数量的频道。我怎样才能懒散地解组帧列表?
漂亮,我从来没有见过复用这种方式!即使我自己的功能是双向的,我没有注意到。 (而且我仍然不明白为什么,必须在纸上写出来。) – sba
这个定义是否意味着'转置'是一个部分函数?我的意思是,如果我说'转置[[1],[]]',它会破裂,对吧? –
@FyodorSoikin:不,如文档所述:“*如果某些行比下列行短,则会跳过它们的元素:*”。给定的定义确实是错误的,但显然源代码已经更新。 'transpose [[1],[]]'产生'[[1]]'。 –