hemkay-core-0.1.4: A device independent module music mixer




This module contains the routines to turn a song into a stream of floating point samples. Some intermediate structures are also made available to allow more fine-grain control over playback.


Output format

sampleFrequency :: FloatSource

The frequency at which mixer output should be played back. For the time being, this is a fixed value.

data Sample Source



Player and mixer state

data PlayState Source

The state of the player upon entering a tick.




psTempo :: Int

The current tempo

psBPM :: Int

The current BPM

psRow :: Maybe [Note]

The current row during its first tick, Nothing in subsequent ticks

psChannels :: [ChannelState]

The state of the channels


startState :: Int -> PlayStateSource

The initial state of the player given the number of channels.

Sample-level mixing routines

prepareMix :: PlayState -> ChunkMixStateSource

Create a mixer state from a player state. This basically strips away a lot of unnecessary information and throws away the channels that don't contribute to the output in the given chunk.

mixToBuffer :: Ptr Float -> Int -> SongMixState -> IO (Maybe SongMixState)Source

Given a pointer to a float buffer and a number of samples desired (n), mix the appropriate amount of the song and return the mix state for the remainder or Nothing if finished. This is the most efficient way to render a song. Note that each sample consists of two floats, so the buffer has to be able to hold 2*n floats. The initial song mix state can be simply created by map prepareMix . performSong.

nextSample :: ChunkMixState -> Maybe (Sample, ChunkMixState)Source

Mix a single sample given a chunk mix state. Returns Nothing at the end of the chunk.

Mixing whole songs

mixSong :: Song -> [(PlayState, [Sample])]Source

Mix a whole song in chunks, pairing up the play states with the respective chunks.

mixChunk :: PlayState -> [Sample]Source

Mix a single chunk given a play state. It's equivalent to unfoldr nextSample . prepareMix.

performSong :: Song -> [PlayState]Source

Turn a song into a series of play states, one for each tick. It's a shorthand for performTicks . flattenSong.

flattenSong :: Song -> [[Note]]Source

Turn a song into a series of pattern rows. This includes handling control structures like pattern breaks, delays and loops. Order jumps are ignored.

performTicks :: [[Note]] -> [PlayState]Source

Turn a list of rows into a list of play states. Each row gives birth to a number of play states equal to the tempo on that row.