-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTestHaskore.lhs
122 lines (114 loc) · 4.31 KB
/
TestHaskore.lhs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
\section{Convenient Functions for Getting Started With Haskore}
\label{test-functions}
{\small
\begin{verbatim}
> module TestHaskore where
> import Basics
> import Performance
> import HaskToMidi
> import System( system )
> import GeneralMidi
> import OutputMidi
>
> ----------------------------------------------------------------------------
> -- Given a PMap, Context, UserPatchMap, and file name, we can
> -- write a Music value into a midi file:
> ----------------------------------------------------------------------------
> mToMF :: PMap -> Context -> UserPatchMap -> String -> Music -> IO ()
> mToMF pmap c upm fn m =
> let pf = perform pmap c m
> mf = performToMidi pf upm
> in outputMidiFile fn mf
>
> ----------------------------------------------------------------------------
> -- Convenient default values and test routines
> ----------------------------------------------------------------------------
> -- a default UserPatchMap
> -- Note: the PC sound card I'm using is limited to 9 instruments
> defUpm :: UserPatchMap
> defUpm = [("piano","Acoustic Grand Piano",1),
> ("vibes","Vibraphone",2),
> ("bass","Acoustic Bass",3),
> ("flute","Flute",4),
> ("sax","Tenor Sax",5),
> ("guitar","Acoustic Guitar (steel)",6),
> ("violin","Viola",7),
> ("violins","String Ensemble 1",8),
> ("drums","Acoustic Grand Piano",9)]
> -- the GM name for drums is unimportant, only channel 9
>
> -- a default PMap that makes everything into a fancyPlayer
> defPMap :: String -> Player
> defPMap pname =
> MkPlayer pname nf pf sf
> where MkPlayer _ nf pf sf = fancyPlayer
>
> -- a default Context
> defCon :: Context
> defCon = Context { cTime = 0,
> cPlayer = fancyPlayer,
> cInst = "piano",
> cDur = metro 120 qn,
> cKey = 0,
> cVol = 127 }
>
> -- Using the defaults above, from a Music object, we can:
> -- a) generate a performance
> testPerf :: Music -> Performance
> testPerf m = perform defPMap defCon m
> testPerfDur :: Music -> (Performance, DurT)
> testPerfDur m = perf defPMap defCon m
>
> -- b) generate a midifile datatype
> testMidi :: Music -> MidiFile
> testMidi m = performToMidi (testPerf m) defUpm
>
> -- c) generate a midifile
> test :: Music -> IO ()
> test m = outputMidiFile "test.mid" (testMidi m)
>
> -- d) generate and play a midifile on Windows 95, Windows NT, Linux or MacOSX
> testWin95, testNT, testLinux, testMac :: Music -> IO ()
> testWin95 m = do
> test m
> system "mplayer test.mid"
> return ()
> testNT m = do
> test m
> system "mplay32 test.mid"
> return ()
> testLinux m = do
> test m
> system "playmidi -rf test.mid"
> return ()
> testMac m = do
> test m
> system "open test.mid"
> return ()
Alternatively, just run "test m" manually, and then invoke the midi
player on your system using "play", defined below for Mac OSX:
> play = do
> system "open test.mid"
> return ()
A more general function in the tradition of testMidi, makeMidi also
takes a Context and a UserPatchMap.
> makeMidi :: (Music, Context, UserPatchMap) -> MidiFile
> makeMidi (m,c,upm) = performToMidi (perform defPMap c m) upm
> ----------------------------------------------------------------------------
> -- Some General Midi test functions (use with caution)
> ----------------------------------------------------------------------------
> -- a General Midi user patch map; i.e. one that maps GM instrument names
> -- to themselves, using a channel that is the patch number modulo 16.
> -- This is for use ONLY in the code that follows, o/w channel duplication
> -- is possible, which will screw things up in general.
> gmUpm :: UserPatchMap
> gmUpm = map (\(gmn,n) -> (gmn, gmn, mod n 16 + 1)) genMidiMap
>
> -- Something to play each "instrument group" of 8 GM instruments;
> -- this function will play a C major arpeggio on each instrument.
> gmTest :: Int -> IO()
> gmTest i = let gMM = take 8 (drop (i*8) genMidiMap)
> mu = line (map simple gMM)
> simple (inm,_) = Instr inm cMajArp
> in mToMF defPMap defCon gmUpm "test.mid" mu
\end{verbatim} }