Closed gogins closed 5 years ago
There is a Music structure in Euterpea that gets translated to MIDI. Can these be translated to Csound scores?
Yes. The Music type has some rather severe limitations. Pitch is just MIDI note numbers as integers. Notes don't have loudnesses. These limitations are overcome to some considerable extent by layering NoteAttribute over Music and defining more sophisticated Player types. This seems to get pretty good.
So there should be a Csound-specific Player that runs either in real time, or generates strings to be sent to an instance of Csound, or writes a .csd file. See Haskell School of Music page 130.
See also https://github.com/donya/VividEuterpea/blob/master/VividEuterpea.lhs.
Failing to run GUI examples from HSoM with:
<interactive>: user error (unknown GLUT entry glutInit)
*** Exception: thread blocked indefinitely in an MVar operation
This in spite of the fact that glut works in a standalone simple GUI program.
Tried again:
curl https://get-ghcup.haskell.org -sSf | sh
.cabal v1-install Euterpea --reinstall --force-reinstalls
cabal v1-install HSoM --reinstall --force-reinstalls
cabal v1-install Kulitta --reinstall --force-reinstalls
timidity -iA -Os
.
mkg@bodhimandala:~$ which ghci
/home/mkg/.ghcup/bin/ghci
mkg@bodhimandala:~$ ghci
GHCi, version 8.6.5: http://www.haskell.org/ghc/ :? for help
Prelude>
Prelude> import Euterpea
Prelude Euterpea> devices
Input devices: InputDeviceID 1 Midi Through Port-0
Output devices: OutputDeviceID 0 Midi Through Port-0 OutputDeviceID 2 TiMidity port 0 OutputDeviceID 3 TiMidity port 1 OutputDeviceID 4 TiMidity port 2mkg@bodhimandala:~$ ghci GHCi, version 8.6.5: http://www.haskell.org/ghc/ :? for help Prelude> import HSoM.Examples.MUIExamples2 Prelude HSoM.Examples.MUIExamples2> bifurcate Requested buffer size 32768, fragment size 8192 ALSA pcm 'default' set buffer size 32768, period size 8192 bytes Prelude HSoM.Examples.MUIExamples2> Playing time: ~34 seconds Notes cut: 0 Notes lost totally: 0
OutputDeviceID 5 TiMidity port 3
Prelude Euterpea> playDev 2 $ c 4 qn Requested buffer size 32768, fragment size 8192 ALSA pcm 'default' set buffer size 32768, period size 8192 bytes Prelude Euterpea>
Playing a note works.
- Tried running MUI examples again:
mkg@bodhimandala:~$ ghci GHCi, version 8.6.5: http://www.haskell.org/ghc/ :? for help Prelude> import HSoM.Examples.MUIExamples2 Prelude HSoM.Examples.MUIExamples2> bifurcate Requested buffer size 32768, fragment size 8192 ALSA pcm 'default' set buffer size 32768, period size 8192 bytes Prelude HSoM.Examples.MUIExamples2> Playing time: ~34 seconds Notes cut: 0 Notes lost totally: 0
That works!
To do:
The Kulitta GUI did not run out of the box.
I cloned https://github.com/donya/Jazzkell and executed:
mkg@bodhimandala:~/Jazzkell$ cabal v1-install
Resolving dependencies...
In order, the following will be installed:
Jazzkell-0.0.2 (reinstall)
Warning: Note that reinstalls are always dangerous. Continuing anyway...
Starting Jazzkell-0.0.2
Building Jazzkell-0.0.2
Completed Jazzkell-0.0.2
mkg@bodhimandala:~/Jazzkell$ cd examples/
mkg@bodhimandala:~/Jazzkell/examples$ ghci
GHCi, version 8.6.5: http://www.haskell.org/ghc/ :? for help
Prelude> :load Hypnotize
[1 of 1] Compiling Hypnotize ( Hypnotize.lhs, interpreted )
Ok, one module loaded.
*Hypnotize> playDev 2 hypnotize
Requested buffer size 32768, fragment size 8192
ALSA pcm 'default' set buffer size 32768, period size 8192 bytes
That worked.
This is going much better than prior attempts to deal with Haskell, probably because I am always using the latest versions of things.
Sheesh, 10 days now of might and main but I finally got a rudimentary Csound performance working from a single .hs file including the .csd text for Xanadu. Haskell is really different.
I need to marshal String to CString transparently, apparently they use lambdas for that to keep the CString in scope and then destroy it.
Then threading.
After that, sending a Music to a Csound performance running in another thread.
The way it currently works is to compile a CSD String, then map a toCsound
lambda that encloses the Csound pointer over a performance ([MEvent]
]).
Haskell is nearly as fast as C or C++, so I get these messages from csoundInputMessageInternal
:
realloc 61
realloc 60
realloc 60
realloc 61
realloc 60
realloc 61
realloc 48
realloc 47
realloc 62
realloc 61
So, I wonder if my code is sending input messages to Csound faster than Csound can consume them.
If so, then either I can only do finite performances, or I must find some sort of blocking queue in Haskell to slow things down.
In addition, it's not clear that Haskell is waiting for the CSD to compile and start before sending events.
The problem seems to have been sending events to Csound before csoundStart
had been called. I fixed that, and it now works, even for an infinite performance. Remaining tasks:
csd
.This is working well enough as a "beta" implementation. More refinement will come through use.
Note, csound-expression is about synthesis, not composition.
Euterpea/Haskell School of Music/Kulitta is the main thing here, I think. Everything presupposes MIDI and that a MIDI synthesizer is running to accept MIDI messages from Haskell. So, is there a level of abstraction in Euterpea or elsewhere where notes, as opposed to MIDI messages, can be intercepted, translated to i statements, and sent to Csound or saved in a file?
Who else besides the impressive Donya Quick is using Haskell for real algorithmic composition?