【发布时间】:2017-10-12 00:28:48
【问题描述】:
我是一名作曲家,通常使用 Max-MSP 和 OpenMusic。 为了将一些工作从 OM 移植到 Max,我刚刚开始学习 LISP。
我的问题很简单:我想从给定的和弦进行和弦转位。
从(C E G) 需要返回((C E G) (E G C) (G C E))。这意味着对于 3 个音符和弦,我将获得 3 个转位,对于 n 个音符和弦,我将获得 n 个转位。
我已经构建了基本功能:
(defun if-x-under-y-raise-x (x y)
(if (<= x y) (if-x-under-y-raise-x (+ x 12) y) x))
(defun transp (chord)
(append (cdr chord)
(cons (if-x-under-y-raise-x (first chord) (list-max chord 0)) nil)))
transp 函数将排序后的和弦的最低音符移调一个八度,直到它递归地高于和弦的最高音符。
所以用 MIDI 表示,这意味着(60 64 67) 变成了(64 67 72)。这很容易做到。
如前所述,当我想以递归方式获取 n 反转时,问题就来了。
我可以用transp 做一次,但下面的功能不起作用:
(defun renverse (chords)
(if (< (length (first chords)) (length chords))
chords
(cons chords (renverse (list (transp (last chords)))))))
chords 是起始列表。
(renverse '(60 64 67)) 应该返回 3 个和弦转位。
非常欢迎任何帮助。 :-)
【问题讨论】:
-
(cons X nil)最好写成(list X) -
renverse需要一棵树(您正在计算第一个元素的length),但在示例中您给它一个简单的列表。你能澄清一下这个函数应该做什么吗? -
看看:stackoverflow.com/questions/2087693/…。据我所知,这只是找到一个列表 (
(C E G)) 的所有可能排列,并可能在八度后加/减一个八度音阶。 -
@Linuxios - 不完全是;它正在查找列表的所有 rotations,带有八开换位。
-
@sds 是的,这是一个打字错误。我的意思是'((60 64 67))。
标签: recursion lisp common-lisp