Markov Chain Beatbox Generator


16

Nur eine Idee, die ich neulich hatte: Beats nach einer Markov-Kette vordefinierter Sounds zu machen.

Ich erinnere mich, dass jemand eine Beatbox mit Google Translate und der deutschen Sprache erstellt hat (folgen Sie dem Link und klicken Sie auf "Hören").

Die Herausforderung besteht also darin, aus einer bestimmten Kette eine Texteingabe für Google Translate zu erstellen. Oder Sie können Noten verwenden und es selbst spielen :).

Markov-Kette

Sie können ein Programm so programmieren, dass es eine Zeile mit der Anzahl der Schläge liest, eine andere mit ihren Namen und einer Matrixdarstellung der Wahrscheinlichkeiten (Sie können die Darstellung auswählen).

Sie können auch eine Funktion mit diesen drei Argumenten erstellen.

Z.B

[Eingang]

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

[output] so etwas wie:

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

Die Startwahrscheinlichkeit ist für jeden Schlag gleich.

Das ist keine Code-Golf-Herausforderung, denn ich würde gerne ein paar schöne Lösungen sehen (sei kreativ).

Zusätzliche Punkte, wenn Sie neue Beats erfinden und / oder eine Wahrscheinlichkeitstabelle wählen, die die meiste Zeit schöne Beats liefert.

Wenn Sie möchten, können Sie echte Beats verwenden (In vielen Sprachen ist es einfach, .wavDateien wie das waveModul in Python zu öffnen ) und Musik zu generieren! Hier sind einige kostenlose Beispiel-Beats.

Bei Bedarf kann ich eine Referenzimplementierung posten.


Erlauben Sie vorverarbeitete Formen der Matrix? Das heißt, eine Form, in der die Zahlen als solche nicht mehr vorkommen?
Hans-Peter Störr

@hstoerr Ja. Sie können es als Funktionsargument haben, wenn Sie wollen
JBernardo

Bitte schlagen Sie ein Datei-Hosting vor, um unsere zufälligen .WAVs zu teilen :)
Dr. belisarius

@belisarius Nun, ich weiß, Songcloud ist gut dafür, aber Sie können jedes Datei-Hosting verwenden.
JBernardo

Wäre es akzeptabel, Präfixe mit mehreren Noten im Modell zu verwenden?
Sparr

Antworten:


6

Ich habe diese Tracks gemacht:

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

Verwendung der folgenden Übergangsmatrix:

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

Und das folgende Programm in 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]

Oh schön. Ich habe versucht, auch ein paar Geräusche zu machen, aber ich glaube, mit den von mir verwendeten Beats stimmte etwas nicht (zwischen ihnen herrschte eine gewisse Stille).
JBernardo

Es sieht so aus, als hättest du die Beats überlagert
JBernardo

@JBernardo Das Sample enthält vier "Akkorde": 1) "Snare", 2) {"Slap" & "Shaker"}, 3) {"OpenTriangle" & "Maracas"}, 4) "RideBell"; Das ist die Überlagerung, die Sie dort hören
Dr. belisarius

3

Als Deutscher fiel ich fast vom Stuhl und lachte über diesen kreativen Missbrauch unserer Sprache. :-)

Hier ist etwas Scala. Ich codiere die Wahrscheinlichkeiten in einer Karte, die den Schlag einer Liste von Nachfolgerschlägen zuordnet, in denen die Schläge mit einer ihrer Wahrscheinlichkeit proportionalen Häufigkeit auftreten. Es wird ein unendlicher fauler ausgewerteter Strom von Beats erstellt, dessen erste 10 Beats übersprungen werden, um die entsprechende Zufälligkeit des ersten ausgegebenen Beats zu erhalten. Wir geben die entsprechende Anzahl von Beats vom Anfang dieses Streams zurück. Ich benutze den Typparameter T, um kürzer und allgemeiner zu sein.

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)
}

was so heißen kann:

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

Ich habe eine Javascript-Funktion geschrieben. Allerdings hat es sich Beatboxing begonnen ...

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;}

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


0

Nur eine Referenzimplementierung in 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)

Und ein Testprogramm:

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))

Und einige Ausgaben:

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

Aber keiner von ihnen macht eine wirklich gute Beatbox, weil es zu viel gibt kkkk:).

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.