马尔可夫链节拍发生器


16

前几天我只是有个主意:按照预定义的声音的马尔可夫链拍拍。

我记得有人用Google Translate和德语做了一个节拍盒(点击链接并按监听)。

因此,挑战在于如何从给定的链中为Google翻译构建文本输入。或者,您可以使用音符并自己演奏:)。

马尔可夫链

您可以使程序读取一条带有拍数的行,另一条读取其名称和几率的矩阵表示形式(可以选择表示形式)。

您也可以使用这三个参数来创建函数。

例如

[输入]

20
pv zk bschk kkkk
[[.1, .4, .5, 0.],
 [.3, .2, .3, .2],
 [0., .3, .2, .5],
 [.1, .8, .1, 0.]]

[输出]类似:

pv zk bschk zk pv bschk zk pv zk bschk kkkk pv bschk zk bschk bschk bschk zk kkkk bschk

每个节拍的起始概率是相同的。

这不是代码挑战,因为我希望看到一些不错的解决方案(富有创造力)。

如果您发明新的节拍和/或选择在大多数情况下给出良好节拍的概率表,则可以加分。

如果需要,您可以使用真实的节拍(在许多语言中,很容易打开.wav文件,例如wavePython中的模块)并生成音乐!这里有一些免费的样品节拍。

如果需要,我可以发布参考实现。


您是否允许矩阵的预处理形式?也就是说,这样的数字不再出现的形式?
汉斯·彼得·斯托尔2011年

@hstoerr是的。如果需要,可以将其用作函数参数
JBernardo 2011年

请提出一个用于共享我们随机.WAV的文件托管服务:)
belisarius博士2011年

@belisarius好吧,我知道Songcloud有好处,但是您可以使用任何文件托管。
JBernardo 2011年

在模型中使用多音符前缀是否可以接受?
Sparr

Answers:


6

我做了这些曲目:

http://soundcloud.com/belisarius/sets/golf-music

使用以下转换矩阵:

{{10,  1,  3/2, 2},  
 {1/2, 10, 3/2, 2},  
 {1/2, 1,  10,  2},  
 {1/2, 1,  3/2, 10}} 

以及Mathematica中的以下程序:

musicGen[n_, notes_, transMatrix_] :=
 Module[{
          im := IdentityMatrix[Length@notes],
          a  := Array[2^(# - 1) &, Length@notes],
          soundLength = .1  n,
          which
          },
  which[x_] := Position[x, 1][[1, 1]];
  Sound[Join[
    (SoundNote /@ notes[[
        which[#] & /@
         NestList[
          RandomChoice[transMatrix[[which@#]] -> im] &,
          RandomChoice@im,
          n - 1]
        ]]
     )
    ],
   soundLength]
  ]
tm = {{10, 1, 3/2, 2}, {1/2, 10, 3/2, 2}, {1/2, 1, 10, 2}, {1/2, 1, 3/2, 10}}
notesSet = {"Snare", {"Slap", "Shaker"}, {"OpenTriangle", "Maracas"}, "RideBell"};
m = Array[If[#2 == 5 || #2 == #1, 10, #2/2] &, {Length@notesSet,Length@notesSet}];
mg = musicGen[100, notesSet, tm]

不错哦。我也尝试发出一些声音,但是我认为我使用的节拍有问题(它们之间有些沉默)。
JBernardo

看来您叠加了节拍
JBernardo

@JBernardo示例中有四个“和弦”:1)“ Snare”,2){“ Slap”&“ Shaker”},3){“ OpenTriangle”&“ Maracas”},4)“ RideBell”; 那就是你在那儿听到的叠加
belisarius博士2011年

3

作为德国人,我几乎从椅子上掉下来,嘲笑这种创造性地滥用我们的语言。:-)

这是一些Scala。我在一个映射中编码概率,该映射将拍子映射到后继拍子列表,其中拍子发生的频率与其概率成正比。创建一个无限的延迟评估的节拍流,跳过其前10个节拍以获得第一个输出节拍的适当随机性。我们从该流的开头返回适当的节拍数。我使用类型参数T来使其简短且通用。

def markovChain[T](length : Int, nodes : Seq[T], probabilities : Map[T, Seq[T]]) : Seq[T] = {
  def randomElement(seq : Seq[T]) = seq(Random.nextInt(seq.length))
  def chain(node: T): Stream[T] =
    Stream.cons(node, chain(randomElement(probabilities(node))))
  return chain(randomElement(nodes)) drop(10) take(length)
}

可以这样称呼:

val nodes = List("pv", "zk", "bschk", "kkkk")

val probabilities = Map(
  "pv" -> List("pv", "zk", "zk", "zk", "zk", "bschk", "bschk", "bschk", "bschk", "bschk"),
  "zk" -> List("pv", "pv", "pv", "zk", "zk", "bschk", "bschk", "bschk", "kkkk", "kkkk") ,
  "bschk" -> List("zk", "zk", "zk", "bschk", "bschk", "kkkk", "kkkk", "kkkk", "kkkk", "kkkk"),
  "kkkk" -> List("pv", "zk", "zk", "zk", "zk", "zk", "zk", "zk", "zk", "bschk"))

markovChain(20, nodes, probabilities) foreach (s => print (s + " "))

1

我写了一个Javascript函数。但是,它已经开始把拳打本身。

function bschk(jk,pv,kkkk){jkjk='pv jk bschk kkkk'.split(' ');boom='indexOf';eval(
function(jkpv){for(pvpv=0,bschkpv='';pvpv<jkpv.length;jkpvpv=jkpv[pvpv++].split(' '),
bschkpv+=String.fromCharCode(jkjk[boom](jkpvpv[0])+jkjk[boom](jkpvpv[1])*4+jkjk[
boom](jkpvpv[2])*16+jkjk[boom](jkpvpv[3])*64));return bschkpv}((
'bschk jk bschk jk  kkkk kkkk bschk jk  bschk pv kkkk jk  pv bschk bschk pv  bschk '
+'jk kkkk jk  jk pv bschk jk  bschk pv kkkk jk  pv pv bschk pv  jk jk bschk jk  jk '
+'kkkk kkkk pv  bschk kkkk kkkk jk  bschk kkkk kkkk jk  pv bschk bschk pv  jk kkkk '
+'pv jk  jk pv bschk jk  pv jk kkkk jk  pv bschk bschk jk  bschk kkkk bschk pv  bsc'
+'hk pv kkkk jk  jk pv bschk jk  bschk kkkk bschk jk  pv jk bschk jk  kkkk kkkk bsc'
+'hk jk  jk kkkk bschk jk  pv bschk bschk pv  jk bschk bschk pv  bschk bschk bschk '
+'pv  pv pv kkkk jk  bschk jk kkkk jk  bschk kkkk bschk pv  pv kkkk bschk jk  jk jk'
+' bschk jk  bschk kkkk bschk jk  kkkk jk bschk jk  pv jk kkkk jk  pv bschk bschk j'
+'k  jk bschk bschk pv  pv kkkk bschk pv  jk bschk bschk jk  jk kkkk kkkk pv  pv pv'
+' kkkk pv  pv kkkk bschk pv  bschk jk bschk jk  pv kkkk bschk pv  kkkk jk bschk jk'
+'  pv kkkk bschk pv  kkkk pv bschk jk  kkkk bschk bschk jk  kkkk pv bschk jk  kkkk'
+' bschk bschk jk  bschk pv bschk jk  kkkk kkkk bschk jk  kkkk kkkk bschk jk  jk kk'
+'kk bschk jk  jk kkkk kkkk pv  kkkk jk bschk pv  kkkk jk bschk pv  kkkk bschk kkkk'
+' pv  jk bschk bschk jk  pv kkkk kkkk pv  bschk bschk bschk jk  kkkk bschk bschk j'
+'k  kkkk bschk kkkk pv  jk bschk bschk jk  kkkk bschk bschk pv  kkkk bschk bschk p'
+'v  jk bschk bschk pv  kkkk bschk kkkk jk  kkkk pv bschk jk  kkkk bschk bschk jk  '
+'kkkk pv bschk jk  kkkk bschk bschk jk  bschk pv bschk jk  kkkk kkkk bschk jk  kkk'
+'k kkkk bschk jk  jk kkkk bschk jk  kkkk bschk bschk pv  jk kkkk kkkk pv  pv pv kk'
+'kk jk  bschk jk kkkk jk  kkkk bschk jk jk  jk jk bschk jk  jk kkkk jk jk  kkkk bs'
+'chk bschk pv  kkkk jk bschk pv  pv pv bschk pv  kkkk jk bschk pv  kkkk bschk kkkk'
+' pv  kkkk jk bschk jk  jk kkkk kkkk pv  jk kkkk pv jk  jk pv bschk jk  pv jk kkkk'
+' jk  pv bschk bschk jk  bschk kkkk bschk pv  bschk pv kkkk jk  jk pv bschk jk  bs'
+'chk kkkk bschk jk  pv jk bschk jk  kkkk kkkk bschk jk  jk kkkk bschk jk  pv bschk'
+' bschk pv  jk bschk bschk pv  kkkk bschk kkkk pv  bschk jk bschk jk  jk kkkk kkkk'
+' pv  jk kkkk bschk pv  jk pv kkkk pv  kkkk bschk kkkk pv  kkkk jk kkkk jk  pv bsc'
+'hk bschk jk  jk bschk bschk jk  pv kkkk bschk jk  jk jk bschk jk  pv bschk bschk '
+'pv  kkkk jk bschk jk  bschk kkkk kkkk pv  jk kkkk kkkk pv  pv pv kkkk pv  jk bsch'
+'k bschk pv  kkkk jk bschk jk  jk kkkk bschk pv  jk kkkk kkkk pv  kkkk bschk bschk'
+' jk  kkkk bschk bschk jk  kkkk bschk bschk jk  kkkk bschk bschk jk  kkkk bschk jk'
+' jk  jk jk bschk jk  jk kkkk jk jk  kkkk bschk jk jk  kkkk bschk bschk pv  kkkk b'
+'schk bschk pv  bschk jk bschk jk  jk kkkk jk jk  kkkk bschk kkkk pv  jk jk bschk '
+'jk  jk kkkk kkkk pv  bschk jk bschk jk  kkkk bschk kkkk pv  jk kkkk kkkk jk').split
('  ')));return ckckboom;}

用法示例: bschk(20,'pv jk bschk kkkk'.split(' '),[[.1,.4,.5,0],[.3,.2,.3,.2],[0,.3,.2,.5],[.1,.8,.1,0]])


0

只是Python中的参考实现:

from random import random

def find(num, pdf):
    ''' Find position of number in CDF from PDF (must sum 100%) '''
    cdf = (sum(pdf[:i+1]) for i in range(len(pdf)))
    for i,j in enumerate(cdf):
        if num < j:
            return i

def build(t, beats, table):
    node = int(random()*len(table))
    nodes = [node]
    for i in range(t-1):
        node = find(random(), table[node])
        nodes.append(node)
    return ' '.join(beats[i] for i in nodes)

和一个测试程序:

table = [[.1, .4, .5, 0.],
         [.3, .2, .3, .2],
         [0., .3, .2, .5],
         [.1, .8, .1, 0.]]

print(build(20, 'pv zk bschk kkkk'.split(), table))

和一些输出:

pv zk bschk zk kkkk zk bschk kkkk zk zk zk bschk kkkk zk bschk zk pv bschk kkkk zk
zk bschk kkkk zk zk kkkk zk bschk kkkk zk bschk zk pv zk pv zk zk bschk kkkk bschk
kkkk zk zk pv bschk bschk zk zk kkkk zk kkkk zk zk kkkk zk pv zk bschk kkkk zk

但是它们都不是一个很好的节拍器,因为有太多的kkkk:)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.