summaryrefslogtreecommitdiff
AgeCommit message (Collapse)Author
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.
2015-12-05Fix all hlint and GHC warnings.Andrew Cady
2015-12-05add facility to queue midi output to synthAndrew Cady
2015-12-04treat EOF from stdin as if "exit" were typedAndrew Cady
2015-12-04Change database schemaAndrew Cady
Start and end times, and leading silence duration, are all available through SQL.
2015-12-04whitespaceAndrew Cady
2015-12-04change data structures for midi recordingsAndrew Cady
2015-12-04add command "exit"Andrew Cady
2015-12-04whitespace formattingAndrew Cady
2015-12-04hlintAndrew Cady
2015-12-04renames to avoid shadowingAndrew Cady
2015-12-04add thread to read lines from stdinAndrew Cady
2015-12-03changing the ghc options fixed the performance issue (-O2 and/or -threaded)Andrew Cady
2015-12-03fill out types in the reader environmentAndrew Cady
2015-12-03get types of all Reader env tuple elementsAndrew Cady
2015-12-03reader has its own data type, LoopEnv, instead of a giant tupleAndrew Cady
2015-12-03write sqlite in a separate threadAndrew Cady
this doesn't actually seem to make it faster, so something is wrong.
2015-12-03dump all midi to a databaseAndrew Cady
this is too slow; there's a visible delay as the sql statement executes. the plan is to run this in a separate thread
2015-12-03use real clock time (adjusted from the monotonic clock)Andrew Cady
2015-12-03print extracted info from historyAndrew Cady
2015-12-03record timestamps of silenceAndrew Cady