The Haskore Tutorial
top back next
section A

10  Convenient Functions for Getting Started With Haskore

 

> module TestHaskore where
> import Haskore
> import System( system )
>
> ----------------------------------------------------------------------------
> -- 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","Synth Drum",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 = (0, fancyPlayer, "piano", metro 120 qn, 0, 100)
>
> -- 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, Dur)
> 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, Linux or NeXT
> testWin95, testNT, testLinux, testNext :: Music -> IO ()
> testWin95 m = test m                    >> 
>               system "mplayer test.mid" >> 
>               return ()
> testNT    m = test m                    >> 
>               system "mplay32 test.mid" >> 
>               return ()
> testLinux m = test m                         >> 
>               system "playmidi -rf test.mid" >>
>               return ()
> testNext  m = test m                  >> 
>               system "open test.midi" >>
>               return ()

Alternatively, just run "test m" manually, and then invoke the midi
player on your system using "play", defined below for NT:

> play = system "mplay32 test.mid" >>
>        return ()

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


The Haskore Tutorial
top back next