Jackdaw is a free, keyboard-focused Digital Audio Workstation (DAW), currently in progress. Source code and a user manual are available on github.
In May of last year, I checked out a git branch ambitiously
named midi, thereby dooming Jackdaw’s main branch to
months of neglect.
Until today! Branch midi has been merged.
This update includes a whole lot, much of which has nothing to do with MIDI. In fact, it’s too much to write about in a single post, but I’m going to do that anyway.
This section enumerates visible changes to Jackdaw since last May that are not related to MIDI; under-the-hood changes (refactors), of which there have been many, are not described.
All of the audio clips you see on the timeline are really “clip
references”: windows into the underlying audio data. When you
first record or import a clip, this window includes all of the
available audio data. But cutting the clip (S-c) or
using source
mode can result in one or more partial windows into the
underlying audio data.1
Now, you can directly adjust those windows with a new suite of tools. It works the same as grabbing and dragging clips; in addition to grabbing and moving the clips themselves, you can now grab and move the edges of those clips.
The keyboard commands use g (which is bound to
Grab clip at cursor) as a modifier key, and
j and l for “left” and “right”,
respectively (analogous to j = rewind and
l = play).
So to grab the left edge, position the cursor over the clip and
do g-j (hold g and tap j). To grab the right edge,
g-l. If dragging is active (C-k), moving
the playhead will also move the grabbed edges.
Arrows are displayed when there’s “room” on either side of the clip, i.e. there’s audio data beyond the current window.
You can cut a clip and automatically grab both edges of the cut
to move the cut position with g-c
(Cut clip at cursor and grab edges):
If a clip edge is grabbed but you want to grab the whole clip
instead (e.g. to move it in its entirety), you can use
g-k to Ungrab clip edge. So it’s very
easy to cycle between grabbing either edge or the clip itself with
g-j, g-k, g-l:
You can set and adjust a gain value for a clip by Shift-clicking it, and dragging the mouse up or down. This is a non-destructive edit; the underlying audio is unchanged.
To reset the gain to 0dB, do the same but hold Cmd
or Ctrl in addition to Shift.
You can reverse the polarity of the clip by dragging past the -∞ dB line.
Click tracks got a significant overhaul in service of some MIDI-related things. One visible sign of the change is that tempo BPM values no longer need to be integers. (Don’t ask me why the original implementation required them to be integers.)
Jackdaw provides a lot of flexibility that you’ll almost never
need with respect to click track placement; you can create a bunch
of click tracks and move them up and down the timeline to your
heart’s content. Placement is not strictly cosmetic: each Track is
“governed” by the click track positioned nearest above it on the
timeline, so when you need to do grid-related things on a track
(e.g. jumping to the next beat position with C-l, or
adding notes in the piano roll), you can control which
grid you’re using.
The downside of this design is that if you have a bunch of tracks and scroll down, the click track you’re using may no longer be visible.
To solve this, you can now “freeze” a click track at the top of
the timeline view, and it will remain fixed there regardless of
how you scroll. You do this simply by moving (S-p)
the click track “all the way up”:

(Note that the frozen click track covers over the timecode view, so it’s unfortunately one or the other for now.)
You “unfreeze” the click track by selecting it (repeat
p or d until you’re “all the way up”)
and moving it down (S-n):
I always wanted a “swing” metronome: instead of clicks on every beat, your bandleader snaps on beats two and four. You can do this now (among other things) by setting which metronome sound plays on each of the following:
These options can be found in the second tab of the click track
settings tab view (select a click track (n and
p) and then S-t to open the tab view,
and S-l to tab right).
There are two finger snap recordings included along with the default sounds. You can’t add your own sounds yet, but that option shouldn’t be difficult to add in the future.
Tempo changes now affect the placement of clips, MIDI notes and pitch bend, and automation keyframes. More on this below, in the context of MIDI note quantization.
Jackdaw is still natively stereo, and does not support audio output with more than two channels. But you can now connect multi-channel devices (e.g. audio interfaces) and selectively record from adjacent stereo pairs of channels. For example, when you connect a 4-channel interface, you will have the option to record from channels (1,2) or (3,4). It is also now true that mono audio inputs (like the built-in microphone on most laptops) record mono clips, and not redundant stereo. (Jackdaw tracks are flexible – they can hold mono or stereo clips, MIDI or audio; a Track is just a Track. This idea will extend to buses, too).
There’s no option for the user to configure the device channel
groupings manually, but you can effectively achieve any result
with Split stereo clip at cursor to mono, then mixing
the new mono clips in stereo with panning, exporting a mixdown
(S-w) and re-importing it (C-o), or
using the Jackdaw out audio input to record a stereo
mixdown on the fly. I’ll add device configuration later.
I improved the code that handles device connection/disconnection events; it should always be possible to use a new device connected during runtime, and disconnecting a device should never cause a crash. (This is unfortunately not true of MIDI devices, because neither SDL2 nor PortMidi reports when a MIDI device has been added or removed.)
SDL2 and SDL2_ttf are now included in the project as git submodules, as is PortMidi. The Makefile included with Jackdaw now builds each of those dependencies locally (i.e., will not install anything on your system), and links to static builds of each when constructing the Jackdaw binary.
So, to build a self-contained copy of Jackdaw on your machine, the following should usually be sufficient:
$ git clone --recurse-submodules https://github.com/chvolow24/jackdaw.git
$ cd jackdaw
$ makeCMake is required to build PortMidi, and GNU autotools is required to configure and build SDL2 and SDL2_ttf. For its part, Jackdaw just uses GNU Make.
make clean cleans Jackdaw’s build objects only.
make cleanall also cleans the dependencies.
make debug creates a debug build.
So far, the MIDI functionality in Jackdaw can only be used to control the built-in synthesizer. But it’ll do more in the future, and the built-in synth is more powerful than you might expect. With the QWERTY piano emulator, you can start making your own sounds in Jackdaw immediately, without an external device.
Tracks in Jackdaw are not “audio tracks” or “MIDI tracks” –
they are just Tracks. You can record MIDI data onto a track
exactly like you would record audio: first, select one of the MIDI
devices from list of available inputs (C-S-i, or
click the track input box); then, hit r to start
recording. A pink MIDI clip will appear on the track, and any
notes you play on the MIDI device will be recorded to that clip.
Hit r again to stop recording.

Recording MIDI with the QWERTY piano emulator
MIDI clips can also be manipulated exactly like audio clips. You can grab them, move them around, copy them, and adjust their bounds. (Source mode does not currently work with MIDI clips, however).
Each Track has its own synth, and MIDI is played back through
the synth by default. The synth is opened with
S-s.
(There’s a Track set MIDI out command, which could
be used for other instruments or external devices in the future;
for now it’s useless.)
Jackdaw’s synthesizer has four “base oscillators” with selectable waveform types (sine, triangle, square, saw). Each of the base oscillators can be replicated in up to 7 unison voices, which can be detuned and spread across the stereo field. The base oscillators can be tuned (octave, coarse, and fine tuning) individually, or set to a fixed frequency.
By default, the four base oscillators are added together.
However, you can also set one oscillator to modulate the frequency
or amplitude of another. Modulation can be used to create new
timbres or, when the modulator is set to a low frequency, to
create vibrato (frequency) or tremolo (amplitude). When a given
base oscillator is being modulated by another, the appropriate
Is carrier red status light will be lit.

By default, the phase of all oscillators (i.e. all of the base
oscillators and their unison voices) will be reset when a new note
is triggered. You can turn this off by unchecking the
Sync phase toggle. In general, not syncing
phase is preferable for more heterogeneous sounds, like orchestral
strings. It introduces an element of chaos into the sound, and is
often undesirable for things like bass instruments, where phase
differences can unexpectedly and dramatically mute or amplify a
sound.
The synth uses a conventional ADSR envelope. The
Ramp exponent parameter sets an exponent value for
each ramp; as that value increases past 1.0, the shape of the
decay and release ramps change gradually from something that looks
like “\” to something that looks closer to “L”. In other words, a
ramp exponent of 1.0 gives a linear decay, 2.0 gives quadratic
decay, etc.
White noise can be introduced into the sound and controlled by its own amplitude envelope. Even if the noise envelope is enabled, the noise sound still passes through the main amplitude envelope and the filter.
The filter is a one-pole resonant lowpass Chebyshev filter. The
controls are, I think, slightly unconventional. The
Base cutoff parameter sets a lower bound for
the filter cutoff frequency. The Key tracking
parameter adds a multiple of the current note frequency to the
base cutoff. Velocity tracking attenuates
(brings down) the cutoff frequency when the note has
less-than-full velocity, more so for higher values of the
parameter. (So, bring this slider all the way up if you want
maximum expressivity). Env amount adds to
the cutoff frequency an amount that changes dynamically with the
filter’s envelope.
The filter cutoff tracks the amplitude envelope by default, but
can be given its own ADSR shape when Use amp env is
unchecked. The effect is most obvious when the amp envelope has a
short attack, and the filter envelope is given a longer attack,
producing a “wah” sound.
When effects are added directly to the synth (instead of to its parent Track), they are heard even when the synth is being monitored directly, i.e., while you are playing. Delay lines and saturation sound excellent on a synth.
The effects can be re-ordered, deleted, and undeleted exactly like track effects. They are included when a synth preset is saved. Unlike track effects, you can’t apply automation to synth effect parameters.
The synth can be used polyphonically with up to 24 voices (the default), or in mono mode. When voice-stealing is enabled, the oldest (longest-held) voice is stolen first.
Portamento applies to pitch and velocity in mono mode, but also
polyphonically when the special Poly portamento mode
is enabled.
Enable voice sliding in a polyphonic context by:
Poly portamento mode (make sure
Mono mode is off), andWhen a voice is stolen (and only then), the stolen voice slides to the destination note instead of being silenced.
Poly portamento mode implements heuristic voice-leading, so the rules for voice stealing are slightly different. When a new note occurs and all available voices are in use, those that have been released (finger no longer on key, but note amp envelope still in release) are checked first, and the nearest one in terms of pitch is used. If all of the voices in use are still being held, then the nearest one of those is used.
Here’s an example (a single track) of how this can sound with three-voice polyphony.
Synth settings can be saved in a preset file, which has the
.jsynth file extension. You can open a preset in
three ways:
C-o (standard Open file)S-s, navigating to the
Presets tab, and selecting
Open preset./jackdaw path_to_preset_file)When you open a new preset, it will override all of the current synth settings – but you can undo and redo this action, so nothing will be lost.
You can save the current preset by navigating to the
Presets tab and selecting
Save preset as...
Jackdaw provides the QWERTY piano emulator as a way for you to
play the synth or otherwise record MIDI without an external MIDI
controller. You can activate it with the
Activate QWERTY piano command, which is bound to
S-q. Deactivate with the same (S-q) or
with <esc>.
If you want to record MIDI data using the QWERTY piano, set the
track input accordingly, and then hit r to record.
You cannot stop recording with r like usual (it is
too easy to do this accidentally), but escaping with
S-q or <esc> does the job.
The piano roll view can be used to edit or create new MIDI clips.
To enter the view, use
Edit clip at cursor / open piano roll, which is bound
to C-S-e. If the cursor (the Jackdaw
cursor, not mouse) is over a MIDI clip, that clip is opened in
the piano roll view; otherwise, a new clip is created.
The piano roll controls are designed to be analogous or identical to timeline controls. Notes in the piano roll view are analogous to clips in the timeline view.
All of these are exactly the same as in the timeline view:
j, k, l for
rewind/pause/play, , and . to zoom,
h and ; to move the view left and right,
[ and ] to move the playhead (without
playback), etc.
If there is a grid enabled (a click track is positioned
somewhere above the current track), then all of the bars/beats
navigation commands work the same as well: C-j and
C-l to go to the previous/next beat,
C-S-j and C-S-l to go the the
previous/next subdivision, and A-S-j and
A-S-l to move to the previous/next measure.
In timeline view, S-j and S-l move
the cursor to the previous/next clip boundary; in piano
roll view, these commands (Go to previous note,
Go to next note) move the cursor to the previous/next
note boundary.

(NOTE: It is usually much faster to insert notes with a MIDI device, including the built-in QWERTY piano emulator).
The “note selector” can be moved up and down with
n and p (or d and
f) just like the track selector.
Hit <ret> to insert a note at the current
position. You will hear the note played back (at an arbitrary
short duration) through the track’s synth.
Hit <spc> to insert a rest.
If you make a mistake, hit <del> (or the
backspace key) to “undo” it.
The duration of the next note (or rest) to be inserted is
adjusted with 1 and 2; velocity with
c and v.
By default, the cursor (playhead) jumps the right edge of the
inserted note. You can prevent this by enabling “chord mode”
(S-h). Disabling chord mode then moves the cursor
forward to the end of the chord (or the shortest note in the
chord, if they have different durations).
“Tie mode” extends the last-inserted note instead of inserting
a new one, provided that the playhead is still positioned at the
of the last note, and the new insertion is on the same actual note
(pitch) or notes (chord). So you can achieve, e.g., a dotted
quarter by setting an eighth note duration, enabling tie mode, and
hitting ret three times.
(The only time you would not want tie mode is enabled is if you want to restrike notes immediately upon release.)
When the track input is set to a connected MIDI device OR when the QWERTY piano emulator is active, notes can be inserted simply by striking the keys of the device. Velocity and pitch are determined by the note you play, not by the piano roll input controls. Chords are detected (keystrokes occur within ~60ms of one another) and inserted as such.
Duration is still set with 1 and 2,
and rests are still inserted with <spc>.
<del> (backspace) is the same.
“Tie mode” works exactly the same. (So does “Chord mode,” though I can think of no reason to use it here.)

“Do you think you’re better off alone?”
Notes can be grabbed, moved, truncated, and extended exactly like clips. That means all of the edge grabbing behavior described above for clips applies here as well.

You can also grab notes with the mouse by Cmd- or Ctrl- clicking the screen and dragging a box around the notes:

In the piano roll view, or timeline view with a MIDI clip under
the cursor, use Quantize notes (clip at cursor) –
A-q – to quantize the notes. You can set an
Amount; an amount of 1.0 places the affected notes
exactly on the gridlines (fully quantized), whereas an amount
<1.0 will simply move them closer to those gridlines. This can
serve as a quick and dirty way to clean up a performance without
making it sound completely robotic. When
Quantize note offs is unchecked, each note retains
its original duration.
When notes have been quantized, their original positions will be shown by an empty grey box in the piano roll view.
You can adjust the quantization amount after the notes have
been quantized with Adjust quantize amount,
A-S-q. This will only apply to notes that have
already been quantized.
WARNING: If you move a note or clip after it has been quantized, and then adjust the quantization amount without re-quantizing, information about the note or clip move will be lost. Adjusting the quantize amount always refers back to the position the notes were in when they were originally quantized.
Changing the tempo of click track segment now moves clips,
notes, and automation keyframes for all tracks using that click
track. You can also now change the tempo by holding
Cmd- or Ctrl- and clicking and dragging
the click track horizontally.

If you want to edit a click track without moving these objects, you can first move the click track to the bottom of the timeline, or temporarily insert another click track below the one you wish to edit, “blocking” it. I recognize this may not be ideal, and may refine the feature later.
You can use the physical controllers (knobs, sliders) on your
MIDI controller to control synth parameters. With the synth tab
view open, simply select a slider (<tab> to
move the selection forward, S-<tab> to move
back, or just click the slider), and then turn the knob on your
keyboard. This will automatically bind that physical controller to
that slider in Jackdaw.
If you want to un-bind the controller, you can do so by holding
down the Alt or Option key and turning
the physical knob again.
This is a brand new feature and has not been thoroughly tested.
Jackdaw can read MIDI files (.mid or
.midi). This feature is filed under “extra” because,
as far as I know, people don’t use MIDI files much anymore, and
also because it’s quite bad. But I’ve tested it with a number of
free MIDI files I found online and it mostly works.
You can open a MIDI file exactly like you would a .wav or .jdaw
file (C-o, on the command line at start time, or
drag-and-drop). If the number of tracks in the file exceeds what
you have on your timeline, Jackdaw will ask if you want to add
more tracks. The click track part of this is one of the things
that works quite badly – sorry about that.
LilyPond is a fantastic music engraving software and markup language. Jackdaw can parse a very limited (and slightly altered) subset of the language, called JLily, as a way to create new MIDI clips.
JLily uses relative mode by default, with middle C as the starting reference pitch.
This feature actually has a short video demo.
Supported syntax:
- note names
e.g. "c g g a g"
- duration
e.g. "c4 g8 g a g"
- dotted duration
e.g. "c4 g8. g16 a4 g"
- accidentals
e.g. "c4 g8. g16 aes4 g"
- rests
e.g. "c4 g8. g16 aes4 g r b c"
- octave indicators
e.g. "c4 g8. g16 aes4 g r b c c,"
- repeats
e.g. "\repeat 4 { c16, c' }"
(repeat ^ times)
- nested repeats
e.g. "\repeat 16 { \repeat 4 {c, c'} \repeat 4 {g, g'} }"
- set velocity (JLILY ONLY, not standard lilypond)
e.g. "\velocity 100 c c e g \velocity 90 g e c"
I haven’t had time to sit down and really work on music, but I’ve been making little things as I go, testing new features.
All of the audible sounds in these examples were produced by Jackdaw’s synth, and edited exclusively in Jackdaw (except wav->mp3 conversion); there’s no imported or recorded audio. The MIDI data was also recorded in Jackdaw except where noted.
a short MIDI loop produced in my friend River’s Clavier 36, altered a bit in Jackdaw and “orchestrated” with some automation tricks
a fugue or fuguettita on the mister softee theme (Les Waas) played on a very early version of the synth
The rest of the examples are “orchestrations” of free MIDI files found on bitmidi.com:
There are many, many things I would like to add to Jackdaw. I also think it’s important for me to formally release v1 this summer, and there’s no way I’ll get to all of it.
I’m considering a few things “essential”:
The biggest barrier to success I see here is figuring out how to represent audio routing in the GUI in a way that won’t take months.2
Probably for v1, because it’s also a fundamental mixing tool and I have all of the rudiments I need to do the implementation. I will have to be careful not to spend too much time on this, because I’m sure I could tune it and add parameters forever.
Of course you should be able to open or export mp3s, flacs, ogg vorbis, etc. I will use libavcodec (from FFMPEG) for this, so I just need to figure out the best way to package and employ it.
Everything else – it pains me – may have to wait until after the v1 release. But if life allows, I absolutely intend to continue with these additions, and more.
Record or import a clip, load it to a range of MIDI notes, and play it back through your keyboard. The absolute simplest implementation of this might be pretty easy, but how long before I want to do things like identify transients, add velocity-dependent processing, etc. The supporting UX will take some time.
The vision:
I have ideas for how to do this, but it’s very challenging.
The “Clever Audio Plug-In” purports to be a simpler alternative to VST. I intend to make Jackdaw a CLAP host eventually; I simply don’t have any sense of how difficult it will be, and how long it will take.
(I do have a sense that adequate VST support would be very difficult and take a long time, so it’s not happening anytime soon.)
You can copy-paste clips, and you can loop playback over a particular section of the timeline, but Jackdaw needs a way to take a section of a track and repeat it N times. Relatedly, I need to figure out how to practically replicate and move ranges of automation keyframes – this is quite difficult given the way I wrote the automation feature.
I would like it to be possible to create rules like: if the
volume v of Track 1 changes, write
v * 0.5 + 0.3 to the volume of Track 2. The Endpoint
abstraction gets me most of the way there.
E.g. when opening files. I have plenty of ideas for how I would like this to work, but it’s all a lot of work.
Serializing and deserializing Jackdaw project files
(.jdaw) is a pain, especially since I’m always adding
new things that need to be serialized. I am also, against reason,
maintaining backward compatibility (mostly). Using SQLite for
project files would simplify some, but not all, aspects of the
problem, in addition to affording some fun hacking
opportunities.
I’m using SDL2’s audio API, which I quite like, but it cannot be used to do latency compensation.3 PortAudio seems like it would be better for this.
I’m not aware of an actual reason to this right now except for a feeling that I probably should.
The foundational goal of Jackdaw, to the extent that there was one, was to write a piece of software that I can use to make music, that works the way I want it to. As the project got more serious, the target audience expanded, and the one goal naturally split into two, each of which is very ambitious on its own:
(By “unfamiliar computer interaction paradigm” I mean primarily using the computer keyboard in places where using the mouse, GUI buttons, toolbars, etc. would feel more familiar.)
Although goal 2 is an omnipresent guiding hand in all of the work I’ve done on this project, it also requires dedicated attention, and I’ve been pretty focused on goal 1 for a while. Among the things that I would like to do in service of goal 2:
/) and menus (C-m)