2011-05-04 49 views
2

我試圖用一個使用haskell的L系統生成音樂。我使用類似下面的內容來生成我的歌曲。對L系統音樂使用haskell midi庫和parsec

musicgen mylist 4 = mylist 
musicgen mylist generation = musicgen (multiReplace [("A","o-B+B"),("B","AoA")] mylist (generation + 1) 

在一首歌曲或規則中使用的文字是:

  • .是休息
  • o演奏一個音符:
  • +當前音符音高了一個半音
  • -當前音符降低一個半音
  • !
  • /盤復位電流間距向右
  • \鍋向左
  • |中心泛

Ø+ O將同時播放兩個音符,其中一個比另一個高。 O.O會一個接一個地彈奏兩個音符。

我正在使用parsec來解析L系統的結果,但是我很難找到一個工作的parsec示例(並且我正在導入必要的庫)。

然後我想我會從midi聲音庫開始。我沒有使用Sound.MIDI,因爲它沒有例子。所以我用Codec.Midi這個例子:http://www.increpare.com/2008/10/basic-haskell-midi-file-output/

但是我無法成功改變頻道。目前還不清楚我應該如何使用Codec.SoundFont加載SoundFont文件以便使用其他樂器。

+2

也許你應該把這個問題分成兩個;一個關於解析和一個關於MIDI。 – hammar 2011-05-04 13:58:40

+0

您可能想要考慮直接使用Haskore而不是MIDI,可能是Haskore-Vintage版本,因爲它更簡單。這會生成MIDI文件,但比MIDI更高級別(例如適當的音符而不是NoteOn/NoteOff對)。儀器是一個枚舉類型,所以你可以選擇一個名稱。 – 2011-05-04 17:38:02

回答

3

下面是一個簡單的Parsec示例,以幫助您解決問題。

import Text.ParserCombinators.Parsec 

data Stream = Chord [Stream] | Play | PitchUp | PitchDown | PitchReset | PanRight | PanLeft | CenterPan deriving Show 

instructions :: Parser Stream 
instructions = try chord <|> play <|> up <|> down <|> reset <|> right <|> left <|> center 

chord = do string "("; x <- many instructions; string ")"; return (Chord x) 
play = do string "o"; return Play 
up = do string "+"; return PitchUp 
down = do string "-"; return PitchDown 
reset = do string "!"; return PitchReset 
right = do string "/"; return PanRight 
left = do string "\\"; return PanLeft 
center = do string "|"; return CenterPan 

p string = case (parse (many instructions) "" string) of 
     Left err -> error "Parse error" 
     Right x -> x 

函數p現在將一個字符列表解析爲類型爲Stream的列表。即:

Main> p "+-+(o+o-o+)" 
[PitchUp,PitchDown,PitchUp,Chord [Play,PitchUp,Play,PitchDown,Play,PitchUp]]