与Euterpea / Haskell随机演奏音符持续时间

时间:2018-12-27 20:27:52

标签: haskell euterpea

我刚开始使用Euterpea / Haskell,并且我试图编写一个简单的脚本来随机化音符的持续时间。

我写的这个可行:

import Euterpea
playMyNote = play $ line [c 4 qn, c 4 qn, d 4 qn, e 4 qn, a 4 qn, a 4 qn, g 4 hn]

然后我读到:AzurePipelinesPS

其中显示了一种生成随机数的方法,如下所示:

import System.Random

main = do
  g <- getStdGen
  print $ take 10 (randomRs ('a', 'z') g)

我正在尝试像下面这样合并它们,但这还不完整(例如,我不知道将z放在哪里。)

有人可以建议我下一步用随机定义的数字替换表示持续时间的数字吗?

这是我目前所在的位置:

import Euterpea
import System.Random

playRandomly = do
    z <- newStdGen
    play $ line [c 4 qn, c 4 qn, d 4 qn, e 4 qn, a 4 qn, a 4 qn, g 4 hn]


playMyNote = play $ line [c 4 qn, c 4 qn, d 4 qn, e 4 qn, a 4 qn, a 4 qn, g 4 hn]

1 个答案:

答案 0 :(得分:3)

首先(通常,不仅对于Euterpea)要查找所需数量的类型。这可以在例如通过检查音符功能(例如cd等)的类型签名。Turns out它们都具有类型

c :: Octave -> Dur -> Music Pitch

在文档中,您可以单击类型的链接,在其中您会发现Dur实际上只是Rational的同义词。因此,您真正需要的是生成随机有理数。您有几种选择,具体取决于您想要随机性的方式

  • 为分子和分母生成随机整数,并将其组合为有理数。

    playRandomly = do
       z <- newStdGen
       let (zn, zd) = split z
           numrs = randomRs (1,5) zn
           denoms = randomRs (1,4) zd
       play $ line
         [ note 4 $ fromInteger numr / fromInteger denom
         | (note, (numr,denom)) <- zip [c, c, d, e, a, a, g]
                           $ zip numrs denums
         ]
    

    获取那些单独的随机生成器,然后从它们中获取数字确实很尴尬,请注意,使用合适的 random monad (例如来自random-fu的方法)要容易得多。

    < / li>
  • 生成连续可变(浮动)持续时间,仅将其伪量化为有理数。

    playRandomly = do
       z <- newStdGen
       let durations = toRational <$> (randomRs (0.1,2) z :: [Float])
       play $ line
         [ note 4 duration
         | (note, duration) <- zip [c, c, d, e, a, a, g] durations
         ]
    
  • 只需从可能的持续时间列表中随机选择。这也是you can easily do with random-fu