Euterpea: setting up audio on linux

Saturday, 3rd November, 2018

Euterpea requires ALSA:


$ apt-get install libasound2-dev

How to install Euterpea & HSoM, repeated from the Euterpea website:

Install the Haskell Platform from https://www.haskell.org/platform/, then:


$ cabal update
$ cabal install Euterpea
$ cabal install HSoM

Audio might work out of the box:

$ gchi
GHCi, version 8.4.3: http://www.haskell.org/ghc/  :? for help
Prelude> import Euterpea
Prelude Euterpea> play $ c 4 qn
Prelude Euterpea> devices  --  Lists audio devices available.

Input devices: 
  InputDeviceID 1       Midi Through Port-0

Output devices: 
  OutputDeviceID 0      Midi Through Port-0

Prelude Euterpea> playDev 0 $ c 4 qn

If either play or playDev (play to device) actually play a middle C out of your speakers, you are done. Hooray!

Otherwise, …

The Euterpea site links to Ted’s Linux MIDI Guide which gave me all the information I needed to set things up. It’s a very interesting article which I encourage you to read. I repeat the bare necessities below for convenience.

Ted provides this script which runs the software synthesizer (or “softsynth”) FluidSynth (so that, e.g., MIDI files can be converted to audio) and the sound server JACK (so that audio applications can communicate with each other).

Requirements:


$ apt-get install fluidsynth jackd2

You’ll have to logout and login again after installing JACK.

The script:

#!/bin/bash

# Script to launch audio servers for music-making.

case $1 in

  start )
    echo Starting JACK...

    # Start JACK
    # As of Ubuntu 12.10, a period of 128 is needed for good fluidsynth
    # timing.  (jackd 1.9.9, fluidsynth 1.1.5)
    # If you aren't running pulseaudio, you can remove the pasuspender line.
    pasuspender -- \
      jackd -d alsa --device hw:0 --rate 44100 --period 128 \
        &>/tmp/jackd.out &

    sleep .5

    echo Starting fluidsynth...

    # Start fluidsynth
    fluidsynth --server --no-shell --audio-driver=jack \
               --connect-jack-outputs --reverb=0 --chorus=0 --gain=0.8 \
               /usr/share/sounds/sf2/FluidR3_GM.sf2 \
               &>/tmp/fluidsynth.out &

    sleep 1

    if pgrep -l jackd && pgrep -l fluidsynth
    then
        echo Audio servers running.
    else
        echo There was a problem starting the audio servers.
    fi

    ;;

  stop )
    killall fluidsynth
    killall jackd
    echo Audio servers stopped.
    ;;

  * )
    echo Please specify start or stop...
    ;;

esac

You can call it “audio”, keep it in ~/bin, and use `audio start` and `audio stop` to start and stop the apps.

So now this should work:

$ audio start
$ gchi
GHCi, version 8.4.3: http://www.haskell.org/ghc/  :? for help
Prelude> import Euterpea
Prelude Euterpea> devices

Input devices: 
  InputDeviceID 1       Midi Through Port-0

Output devices: 
  OutputDeviceID 0      Midi Through Port-0
  OutputDeviceID 2      Synth input port (4424:0)
Prelude Euterpea> playDev 2 $ c 4 qn

Review: Beginning Haskell

Saturday, 26th April, 2014

book details

“Beginning Haskell: A Project-Based Approach”
Alejandro Serrano Mena
2014
Apress
http://www.apress.com/9781430262503

summary

This book could have been very good: the author has the enthusiasm, the knowledge, and the focus. Unfortunately he has been very very badly let down by his publisher. As it is, the book is almost unbelievably horrible to try and read.

The comments below are based only on the first four chapters, which was as much as I could stomach. The contents of the remainder look interesting, so I may read on, … but I don’t really think I shall.

bad

The book has all the usual dysfluencies, typos, inaccuracies, errors, which we have become used to in programming language publishing, but very thick and fast.

As well as the author, the book boasts a Lead Editor, an Editorial Board (of twenty people), a Coordinating (sic) Editor, a Copy Editor, an Indexer, and a Technical Reviewer (who is so important he warrants a photograph). That’s at least twenty five people “helping” the author. The editing and indexing in the book is so awful, and the accuracy of the technical content so variable, that I can’t imagine what any of them did for their money. The book could hardly have been worse if they’d conspired together to wreck it on purpose.

The index was actually useless. Of the five terms I looked up, *none* were in the index: case, fold, map, monoid, set.

Most pages are cluttered with dysfluent English, grammatical mistakes and typos. These are so thick they make the text quite difficult to read. Each textual error trips up the reader’s eye. It’s like walking along a street when the pavement is covered in dogshit: you can’t enjoy the scenery, you can’t think about where you’re going, all you can do is pick your way through the shit.

Worst are the code-related errors, some of which beggar belief. Code which is not Haskell:

let name = match companyName client of
	       Just n -> n

As far as I know “match” is not a Haskell keyword. The book does not disabuse me of that impression. Neither does ghci.

There’s code that will not compile, or doesn’t do what the text says it does (in one case the code does the exact opposite of what the text claims it does).

Page 58 has a “wonderful” code example which manages not only to be inconsistent with the text, but also inconsistent with itself. It manages to do this in three lines of code!

bhp58

The text says the code imports filter and reverse; the code actually imports permutations and subsequence; but the code calls (i.e., expects to have been imported) filter and permutations.

Twenty five editors. And the book has a full page dedicated to praising the Technical Reviewer.

All-in-all reading this book was an unpleasant, even nauseating, experience. Because of the book’s good points (see below) I persevered, and worked through many of the exercises.

The last straw was exercise 4-3 (p. 89).

Earlier the book had introduced a data type Client i, where i is a polymorphous type used as an id (p. 49), and where client can be one of three subtypes (Government, Company or Individual). Exercise 4-3 is to write a function that takes a list of Clients and returns a map from these subtypes to sets of clients, or:

classifyClients :: [Client Integer] -> Map ClientKind (Set (Client Integer))

The exercise has two parts, each suggesting an alternative implementation, and then says:

It’s interesting that you create a very large client list and run the two implementations to compare which one behaves better in speed.

Compare how exactly? Later (p. 122), we are told about how to build a cabal project with profiling options that will profile a Main module.

So let’s just forget about comparison for now and write these two functions.

It turns out that Set (Client Integer) will not work:

  *Main> let  cs = S.fromList [Gov 1, Gov 2, Edu 3, Edu 4, Ind 5, Ind 6]

  :28:11:
      No instance for (Ord (Client i0))
        arising from a use of `S.fromList'
      Possible fix: add an instance declaration for (Ord (Client i0))
      In the expression: S.fromList [Gov 1, Gov 2, Edu 3, Edu 4, ....]
      In an equation for `cs':
          cs = S.fromList [Gov 1, Gov 2, Edu 3, ....]

Needless to say none of Ord, Set or deriving are in the index, and nothing in the text on Sets indicates that there is a constraint that members of sets must be of type/class Ord. Type classes, including Ord and Eq and deriving, are introduced a bit further on (p. 97). The Client type is defined with just deriving Show (p. 49).

I could have taken this as an extra challenge — interpret those error messages, fix the data type: I did do both those things after all — and in another book I would have. With this book though, I decided it was just more dogshit, and I decided I just didn’t care any more.

What a horrible book.

good

All of the textual errors I encountered would have been picked up by an averagely competent editor doing their job. Similarly all of the code errors would have been picked up on a first sweep by an editor with a passing acquaintance with programming languages in general.

The bad points of the book, which make it unusable I think, and certainly unrecommendable, are all down to the publisher and the editorial team.

On the other hand, the author has written something which could have been a very good book, and could certainly have been the best practical introduction to Haskell.

The author’s enthusiasm is palpable and infectious. As well as the exercises, I was motivated to try out code from the text (admittedly, often just to see if it was correct Haskell) and some variations of my own. e.g., inspired by a haskell function for 3x + 7(x + 2) (p. 57), I tried one for ax^2 + bx + c:

  dup x = (x,x)
  f *** g = \ (x,y) -> (f x, g y)

  abc a b c = (uncurry (+)) . (((*a) . (^2)) *** ((+c) . (*b))) . dup


  *Main> let f = abc 1 2 3
  *Main> f 5
  38
  *Main> f 10
  123
  *Main> let f = abc 3 1 2
  *Main> f 5
  82
  *Main> f 10
  312

The author is ambitious and wide-ranging — covering parsing, parallelism, DSLs, Idris(!); the GHCi ecosystem including things like GHC extensions, cabal, Hoogle, Haddock, HUnit, and more — but by tieing everything to a concrete project (the usual web app) keeps things focussed, keeps the pace up, and introduces advanced topics in a natural way.

conclusion

If this book had the appearance of having been edited competently, it could have become the definitive practical introduction to Haskell: the kind of book a programmer could use for self-study, or a technical manager could give to starting team members.

As it is, I would be embarrassed to recommend this to anybody.

The Fibonacci sequence as an unfold

Wednesday, 9th April, 2014

import Data.List

f :: [Integer]
f = unfoldr ( \x -> case x of
                      (0,0) -> Just (0, (1,0))
                      (a,b) -> Just (a+b, (b, a+b)) ) (0,0)

Usage:

> head f
0
> take 5 f
[0,1,1,2,3]
> take 15 f
[0,1,1,2,3,5,8,13,21,34,55,89,144,233,377]

Learn you a Haskell describes these two type classes like this:

Ord is for types that have an ordering.

Enum members are sequentially ordered types.

I didn’t find this especially clear.

Real World Haskell failed (yet again). It [the printed book] gives no definition of Enum, although it seems to think it does (p. 472).

Mostly for my own benefit, this is what I’ve found:

The GHC documentation describes the two type classes like this (emphasis added):

The Ord class is used for totally ordered datatypes.

Class Enum defines operations on sequentially ordered types.

So both classes represent ordered types (both are instances of the Ordering data type). The difference is in the kind of ordering.

A clue is in the methods provided: Ord provides >, <, max and min; Enum provides succ and pred (and, interestingly, nothing similar to max and min).

Finally, the best explanation I found was in Chapter 8: Standard Haskell Classes of A Gentle Introduction to Haskell:

8.2 The Enumeration Class

Class Enum has a set of operations that underlie the syntactic sugar of arithmetic sequences; for example, the arithmetic sequence expression [1,3..] stands for enumFromThen 1 3. We can now see that arithmetic sequence expressions can be used to generate lists of any type that is an instance of Enum. This includes not only most numeric types, but also Char, so that, for instance, [‘a’..’z’] denotes the list of lower-case letters in alphabetical order. Furthermore, user-defined enumerated types like Color can easily be given Enum instance declarations. If so:

[Red..Violet] => [Red, Green, Blue, Indigo, Violet]

Note that such a sequence is arithmetic in the sense that the increment between values is constant, even though the values are not numbers. Most types in Enum can be mapped onto integers; for these, the fromEnum and toEnum convert between Int and a type in Enum.

Note however, that for some reason the Ord type class includes “All Prelude types except IO, (->), and IOError”, so a simple mathematical interpretation won’t do.

Conclusion

So! Actually I’m going to ignore that last caveat.

I think the comfiest way for me to understand these type classes is using the available methods: Ord types are those for which it makes sense to talk about relationships like “greater than” and “less than”; Enum types are those for which it makes sense to talk about relationships like “next” and “previous”. Days of the week would be Enum; Dates would be Ord.

Last in the (unplanned!) series on decorate-sort-undecorate in Haskell, this post reports on the Further Work necessary after the reponses to my initial query on haskell-beginners.

I received many helpful responses, many of which used Haskell language features which were new to me. Here I summarise them and then give a description of the new elements.

  1. Responses
    1. Quoted
    2. Standardised
  2. Discussion
    1. $
    2. (\x -> (f x))
    3. .
    4. &&& and id

  3. And the winner is, …

Read the rest of this entry »

This is not really a post, more like a braindump. I need somewhere to offload all this so I can go to bed. I apologise for lack of context.

OK some context: I’m looking for a chat application I can use within a django-based website (and if I can’t find one, girding my loins to write one). Irrelevantly (or so I’d thought until a few minutes ago) I’m learning Haskell, and finding out about functional programming.

Haskell:

Erlang:

Haskell: sort and sortBy

Friday, 3rd July, 2009

A comment in the discussion on decorate-sort-undecorate in Haskell pointed out to me that my naive and dsu versions of sort by length had different type signatures: the dsu version needlessly required elements of the list to be of type Ord:

sortByLength :: [[a]] -> [[a]]
sortByLength xs = sortBy (comparing length) xs

dsuSortByLength1 :: (Ord a) => [[a]] -> [[a]] 
dsuSortByLength1 xs = map snd (sort (zip (map length xs) xs))

My intention had been that the dsu version have the same requirements as the naive version. So where did this (Ord a) context come from, and how do we get rid of it?

The relevant difference between the functions is the different type signatures for sort and sortBy:

> :type sort
sort :: (Ord a) => [a] -> [a]
> :type sortBy
sortBy :: (a -> a -> Ordering) -> [a] -> [a]

sort requires list elements to be comparable (obviously); sortBy requires only a function that can generate an ordering from its input pair. In dsuSortByLength1 above, the elements of (zip (map length a) a) are required to be of type Ord. We could protest that just because (zip (map length a) a) has to be Ord doesn’t mean that a has to be Ord, but I suspect the compiler is playing on the safe side. [update: see first two comments.]

A function using sortBy instead of sort avoids this extra requirement in the type signature, and shows us a use case for comparing:

sortByLength :: [[a]] -> [[a]]
sortByLength xs = sortBy (comparing length) xs

dsuSortByLength2 :: [[a]] -> [[a]] 
dsuSortByLength2 xs = map snd (sortBy (comparing fst) (zip (map length xs) xs))

Using sortBy (comparing fst) rather than sort allows us to simplfy the type signature.

We can extract length to generalise the function:

sortByFunc :: (Ord a) => (a1 -> a) -> [a1] -> [a1]
sortByFunc f xs = sortBy (comparing f) xs

dsuByFunc  :: (Ord a) => (a1 -> a) -> [a1] -> [a1]
dsuByFunc  f xs = map snd (sortBy (comparing fst) (zip (map f xs) xs))

The (Ord a) context has returned! But here it is just a requirement on the output of the comparison function, which is fine.