summaryrefslogtreecommitdiff
AgeCommit message (Collapse)Author
2019-01-23use system-installed font fileHEADmasterAndrew Cady
2016-01-07update stack resolver to lts-4.0Andrew Cady
2015-12-18cc-options to allow ghci to load midi-dump againAndrew Cady
loading axis in ghci still does not work (because of SDL), but the option is added there anyway.
2015-12-18Continue making axis.hs main loop smaller.Andrew Cady
2015-12-17non-semantic HLint fixesAndrew Cady
2015-12-17Fix GHC/HLint warnings. No semantic changes.Andrew Cady
2015-12-17axis.hs: move a few things out of the giant main loopAndrew Cady
2015-12-17axis.hs: use AlsaShutUpAndrew Cady
2015-12-17Fix cabal buildsAndrew Cady
NB. Cabal has sanity-destroying (undocumented?) restriction: cannot have a .c source with the same basename as a .hs source. TODO: make cabal output a syntax error (instead of an inscrutable linker error!) when the user attempts this. Or, at least, file a bug report.
2015-12-17axis.hs: convert remaining mainloop parameters to use RWSTAndrew Cady
2015-12-17axis.hs: start to move mainloop into RWSTAndrew Cady
2015-12-17Clean up axis.hs lint errors, formatting, etc.Andrew Cady
(No semantic changes.)
2015-12-17Fix some lint errors, fix formatting, etc.Andrew Cady
(No semantic changes.)
2015-12-17Fix some more TimeSpec logic.Andrew Cady
(Well, I don't think it was broken, but now it's clearer.)
2015-12-17Perform GC for each tick.Andrew Cady
The per-tick delay takes account of the time spent in GC. Also, changed tick time to 4ms and fixed TimeSpec arithmetic/logic.
2015-12-17Silence ALSA error messagesAndrew Cady
2015-12-13Alternative input method for triad reprogrammingAndrew Cady
Press M-t, press triad, release. All notes played before next release will be programmed into the triad. Thus it isn't necessary to hold down the entire chord, but you must be holding down at least some note or else the reprogramming is done.
2015-12-13Allow programming triads that do not include the triad's core notesAndrew Cady
Right now this is accomplished via a pretty ugly solution that moves the event forwarding for all events into the triad logic.
2015-12-13initial support for reprogammable triadsAndrew Cady
2015-12-12Metronome bugfixes.Andrew Cady
Turns out: (1) I was using a negative interval because I generated the deltas without reversing the list. (2) Insanely, 2 * TimeSpec 1 0 == TimeSpec 0 2 The new metronome code has the capacity to prequeue beats, by changing the constant "prequeue" (currently 0), but there is no capacity to clear the queue of upcoming events, so this is currently disabled. It also doesn't seem to be necessary. Or rather, it doesn't seem to help: either way, sometimes the program cannot keep up with real time. :( k
2015-12-12move threadDelay mechanism to main loopAndrew Cady
2015-12-12Implement a metronome.Andrew Cady
You provide a tempo by playing the metronome on the MIDI keyboard. Then press M-m to have the sequencer continue the same tempo on the MIDI drum channel.
2015-12-11Make "triadFilter" handle multiple simultaneous triadsAndrew Cady
2015-12-11Renames.Andrew Cady
2015-12-11Lower midi resolution to 1ms.Andrew Cady
Without this, the (several day-long) dumped.mid file ends up invalid (presumably because the largest relative time does not fit into the available number of bits). Arguably this is a bug in Codec.Midi, or anyway it's an undocumented limitation. The proper solution is probably somewhat complicated/convoluted: do a tempo change before and after very long time differences, when (or before) serializing the Midi data. There's little point in implementing that fix though, because this giant midi file is not practically useful anyway.
2015-12-11Output a message whenever a midi file is saved.Andrew Cady
2015-12-11Command "save" now saves latest recording to diskAndrew Cady
The filename is generated automatically from the date of the earliest event in the recording.
2015-12-11Some cleanups & formatting changes.Andrew Cady
No behavior should be affected.
2015-12-10Implement saving of .mid filesAndrew Cady
(Currently accessible only under testing command "save".)
2015-12-10Clean up triad detection somewhatAndrew Cady
The triad detection now returns the correct type (detecting all triads on all channels, and saving the channel). This information is still not used; the future is to call filters for each channel separately, so there is no point making an individual filter operate on multiple channels simultaneously.
2015-12-09Fix triad "fill" note velocity; output to channel 0Andrew Cady
That is, set the velocity to the average of the velocity of the individual triad keys. Also, output the triads to channel 0 instead of channel 1. Previously, all output had been changed to channel 1 to facilitate playing live on channel 0 on top of playback on channel 1. However, it was discovered that the external MIDI synthesizer built into my MIDI keyboard does not listen on channel 1.
2015-12-07Store note velocities in pitch setsAndrew Cady
(actually pitch maps, now)
2015-12-07Add basic support for "filling" triads.Andrew Cady
I.e., any triads played will have additional notes played at the root & fifth of the octave above and below the triad. Eventually I want to program the triads using the keyboard itself, so that the chords can be "filled" arbitrarily. This also shows the need to represent the pressed key set differently than as a Set of (channel, pitch) pairs: the velocity needs to be saved, so that the "fill" notes can use it (probably use the average of the triad). Furthermore the whole infrastructure needs to be designed around the concept of input channels mapping to output channels. Filters (such as the triad filter) should be applied to channels -- right now, the assumption of a single channel has been baked in in several places, but this will eventually interfere with things like looping. (Playing back the input needs to be able to play back the filters that were in place on the input. Although, note: we also want to record output and primarily play that back.)
2015-12-07Output replayed recordings to MIDI channel 1Andrew Cady
The live output goes to channel 0. This prevents the two from messing with each other (cancelling each others' notes). Simply hard-coding channel 1 is a bad idea long-term, though. We actually could have input from more than one channel (if we pump a midi file into the program with "aplaymidi", for example). I suppose we want to map the entire range of channels based on the input source in order to prevent input sources from affecting one another. Then generated playback could be considered a separate input source. All of this will have to be done in order to deal with simultaneous looping of multiple tracks, anyway.
2015-12-07Implement playing MIDI from the databaseAndrew Cady
Currently, the "dump" command plays the entire database. Only the SQL SELECT statement needs to be changed in order to play a specific time-range.
2015-12-07Disable printing the names of keys.Andrew Cady
Also whitespace, comments, & other non-functional changes.
2015-12-06Deserialization with Sound.MIDI.MessageAndrew Cady
This format is still inefficient -- because the time is still represented as a string that is parsed as an Integer -- but it's certainly much more efficient than before. And more importantly, it can be both written and read.
2015-12-06Store recordings as Codec.Midi.MessageAndrew Cady
2015-12-06Store recordings as Sound.MIDI.Message.TAndrew Cady
My intent in doing this was to have a format suitable for reading and writing to the database; the old format (using "show" on the Sound.ALSA.Sequencer.Event.T) could not be read back. Unfortunately, this new format cannot be read back _OR WRITTEN_! At least not without more conversion (of my list of pairs into a Thielemann's specialized event-list). My new plan is to use HCodec's Codec.Midi.Message instead. But I'll commit this before I get to that.
2015-12-06remove now-redundant "_playNOW" queue (just use the RealTimeQueue)Andrew Cady
2015-12-06use the MidiController type alias in all type signaturesAndrew Cady
2015-12-06use RealTimeQueue for queuing midi output to ALSAAndrew Cady
2015-12-06variable rename & type aliasAndrew Cady
2015-12-06Document/tweak RealTimeQueue & its example programAndrew Cady
2015-12-06implement module RealTimeQueueAndrew Cady
2015-12-05Implement replay functionalityAndrew Cady
(Replay last MIDI input, divided by 3 second periods of silence.) This has a bug where if there is too much input to replay, the program exits. (Oddly, there is no exit failure code.) I think this is because the kernel ALSA buffer is full. The solution is to implement in-application queueing.
2015-12-05start to move midi serialization into separate fileAndrew Cady
2015-12-05recording stores both end time and time of last eventAndrew Cady
2015-12-05change representation of recordingsAndrew Cady
2015-12-05Implement delayed outputAndrew Cady
This just sets the time field on the ALSA packet. It works! I had planned to do something much more complicated but if this works out, everything is easy.