descriptionA sequencer for composed music
homepage URLhttp://busted.systems/quincer
ownererikmack@gmail.com
last changeFri, 3 Nov 2017 03:15:36 +0000 (3 03:15 +0000)
content tags
add:
README
quincer

quincer will be a sequencer for live performance of composed works.

Features
========

Currently implemented:
- Send events to multiple output ports
- Send MIDI control change events
- Per-pattern tempo setting
- Prefixes/suffixes
- Input files can include other input files
- Ticks-per-beat and beats-per-bar are not constrained
  (though they must be constant within a pattern)
- can emit MIDI clock to drive external sequencers/effects
- MIDI clock specified at flexible multiples/divisions
  of the JACK clock
- MIDI clock multiples/divisions are unique per output
- run looped or once through
- pure JACK (and is a timebase master)

Planned features, more imminent items first:
- Per-pattern swing setting
- Base tempo can be altered at runtime via MIDI CC
- Jump controls - use MIDI input to skip around (song mode)
- prefix/suffix events mask events from main pattern

Rationale
=========

I want a sequencer for live performance of songs that have been
previously composed, with the sequencing mostly fixed.

But at performance-time I want the ability to make small adjustments
to the song's form to, say, skip a verse or draw out a solo section or
delay a verse slightly because the drummer dropped a stick.  I want
the ability to decide to take the song a little faster or slower than
in rehearsal.

I want the ability to write a song in an unusual meter, with swing and
mid-song tempo changes.  The content of a song pattern should be
allowed to start before beat one of the first bar (e.g. pickups
(anacrusis), or drum fills, or cues on a cue track) and end after the
last beat of the last bar of the pattern.

For compose-time workflow, I want to support multiple use cases for a
song.  That is, I want to run a file that has a sequenced drum track,
or run a different file with a click track instead of drums and maybe
an extra verse.  Among these multiple files, content is re-used where
possible and files can be checked into source control.

Capturing live input is not important, nor is a graphical interface.
Session management isn't on the roadmap currently and probably won't
be.

I've taken inspiration from a few existing sequencers.  The sequencers
in some DAWs are very good for non-standard time signatures and swing
and tempo changes, but I'd never want the risk/overhead of using a DAW
on stage.  The sequencers that are currently for live use have
interesting control capabilities but focus on evolving looped beats in
an improvisatory way, a very specific use case that isn't needed for
all kinds of music.

These features aren't all implemented yet but I've got a solid start.
I hope you'll find quincer useful while it's in progress.


Input file syntax
=================

The quincer executable takes a single argument, a filename containing
the input.  I use files ending with '.qn' as a convention but the
program doesn't care.

An input file looks like this:

voice basskick sampson 1
voice rim sampson 1
voice rhykeys sampson 1
voice suskeys amsynth 1
voice reso amsynth 1

pattern 88 0
$ d2 127
f f 110
g g 110
k 90 80
j a4 80
b f# 70
l d 60

M a5 100
m a5 60

# Send program change (program 3) to rhykeys instrument
P pc 3

# Reso on the synth
r cc 74 0
R cc 74 127

0.....'.....'.....'.....|.....'.....'.....'.....
$         $-      f  g  |                         basskick
                  k     |                         rim
P     |                                           rhykeys
M m m |                                           rhykeys
j---------              l---b-----              | suskeys
r                       R                       | reso

Time spec
---------
Look at the final section first, since everything else leads up to
this.  There is a meter line "0.....'.....'.....'....." which defines
that a bar has four beats and a beat has six ticks.

The meter line must contain a 0 for the first tick. It is allowed to
contain bars if it's easier for human readers, the program doesn't
care as only the first beat after the 0 defines how many ticks are in
a beat. It follows from this that within a pattern the ticks-per-beat
and beats-per-bar are constant within a pattern.

The next lines after the meter line are voice lines, starting with
"$         $-      f  g  | basskick".  These show note events and give
the voice a name.  Note events can pretty much be any printable character,
except '-' which prolongs a note and '|' which is used to mark the end
of the events and the start of the voice name.

It is legal to give the same voice name to multiple lines.  This can
be used to send a block chord to a piano instrument, for example.

Notice that the voice lines have their ending '|' at different beats.
The length of the pattern is the length of the longest voice in it
("suskeys" or "reso" in this example).  Patterns that are shorter are
looped.  It is undefined what happens if your shorter patterns aren't
exactly divisible into the longest one, so be sure you've got that
right.

Pattern declaration and event definitions
-----------------------------------------
Before that section the pattern is declared:

pattern 88 0
$ d2 127
f f 110
g g 110
k 90 80
...

This takes the form:
pattern <bpm> <swing>
<notechar> [cc|pc] <pitch> <velocity>
<notechar> [cc|pc] <pitch> <velocity>
...

Note that 'bpm' is declared for each pattern, which allows mid-song
tempo changes.

'swing' isn't implemented yet and may be omitted. 'notechar' can be
any printable character except - or | (for reasons explained above) or
# (comment delimiter).  Future releases will support other MIDI event
types such as pitch bend.

The pitch value may be entered a couple of different ways:
- midi pitch integer 0-127 (e.g. 80)

- named note, absolute (e.g. a4 or A4 f#2 or Bb3).  Case is ignored
  for the first character ('c' is the same as 'C').  Any pitch can be
  modified by '#' sharp or 'b' flat.  The final integer is the octave
  per https://en.wikipedia.org/wiki/Scientific_pitch_notation.  In
  this notation notes range from c-1 to g9.

- named note, relative (e.g. Db or a#).  This is like the absolute
  named note but omits the octave as a convenience.  It will find the
  pitch closest to the previously specified one.  This is inspired by
  Lilypond's "Relative Octave Entry".  Some caveats:

  - When the higher pitch and the lower pitch from the named note are
    the same distance (6 semitones = tritone), the higher pitch is
    chosen.

  - When there is no previous note, the specified pitch is placed in
    octave 4.

  - The closest legal pitch is chosen.  Specifying 'g9' (MIDI pitch
    127, the highest allowed) followed by 'a' would select MIDI pitch
    117 (the 'a' below g9).

Voice declarations
------------------
At the top are the voice declarations (e.g. "voice basskick sampson
1").  This creates a MIDI output in JACK called "sampson" and sends
events from the "basskick" voice to channel 1 of that port.

This allows you as many output ports as you need, without requiring a
separate view of the note events for each port like in many
sequencers.

This is also good for a device like the Korg Volca Sample.  To play
samples 1-10 on that device, notes must be sent to channels 1-10.
This isn't difficult in MIDI but almost no sequencers support that
kind of multi-channel output, to the point that a custom
channel-splitting cable was devised just for the Sample!  No need
custom cables if you use quincer.

Multiple patterns
-----------------
A new pattern declaration can follow the voice lines, as many patterns
as you need.  

A directive at the top 'run once' will cause the sequencer to play
top-to-bottom then stop.

You could otherwise specify 'run loop' at the top to cause the
sequencer to start over after it has reached the bottom.  This is the
default behavior if no 'run ...' directive was specified.

Comments
--------
Comments start with a # and go to the end of the line.

Include files
-------------
At any point in the input you can have a line:

include foo.qn

...which will behave like includes in other languages (PHP or C
preprocessor).

This is powerful because it allows re-use of material from different
top-level input files, or even within the same one.  As explained in
the rationale section above, a single work can have multiple use
cases, slightly different but with common elements.  Traditionally
sequencers have a "one song = one file" idiom, an unnecessary
constraint on your workflow.

Prefixes and Suffixes (affixes)
-------------------------------
quincer supports events that occur before or after the main pattern.
Prefixes are useful for musical pickup beats (anacrusis), drum fills,
or cue tracks.  Suffixes can be used when a note must linger into the
next pattern.

To enter a prefix, just add ticks before the 0 in your meter line

.'.0.'.'.'.
e  A a     | lead

The e in this example is treated as a pick-up.

To enter a suffix, start a bar with S in your timeline.

0.'.'.'.S.
  A   aeAA| lead

The final two A's are the suffix.

Affixes (prefixes/suffixes) don't affect when a pattern begins or
ends.  The extra notes will overlap the notes in the previous or next
patterns.

It is not yet implemented for affixes to mask events in the main
pattern, but this is planned.  In other words, if a drum fill is
entered as a prefix, then the events in the main pattern's drum voices
should be omitted.  Today, all the events just play over each other.
When masking is implemented, this will allow for affixes that
represent breaks (silence).

MIDI clock
----------
If a line is specified at the beginning like:

clock vsamp 1 1

...then MIDI clock messages (including start & stop) will be emitted
to the output 'vsamp'.  This allows you to use external sequencers,
whose clocks will be synced to quincer's tempo.  In addition to
sequencers, some other kinds of devices can use this information
(synths can set LFO, or delay effects like Eventide Timefactor can set
tap tempo).

The '1 1' is the numerator and denominator, which allow you to stretch
or compress the emitted clock signals in a flexible way.  Specifying
'2 1' with quincer's BPM set at 120 will cause clock to be emitted at
60 BPM.  '4 1' would emit clock at 30 BPM, and '1 2' would emit clock
at 240 BPM.  It is supported to specify strange (integer) values such
as '3 2', which would emit clock at 80 BPM against quincer's internal
120 BPM.

Notice that clock is specified per output.  I could emit clock to a
Volca Sample device at '1 1' (matching quincer's tempo) but also emit
at '2 1' to a Volca Keys device which would run its sequence at half
the tempo.

License
=======
Copyright (C) 2016 Erik Mackdanz <erikmack@gmail.com>

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
shortlog
2017-11-03 Erik MackdanzReplace busy-wait with proper signal handling.master
2017-10-26 Erik MackdanzFix an issue where the pattern doesn't advance,
2017-10-23 Erik MackdanzHandle program change messages
2017-10-01 Erik MackdanzFix for shorter-than-the-longest patternvoices
2017-10-01 Erik MackdanzAdd named note support in vim syntax file
2017-10-01 Erik MackdanzAdd vim syntax file
2017-09-24 Erik MackdanzFix emacs syntax highlighting to distinguish pound...
2017-09-24 Erik Mackdanzemacs syntax highlighting
2017-09-24 Erik MackdanzImplement named notes
2017-09-23 Erik MackdanzFix comment lexing for comments starting mid-line ...
2017-09-22 Erik MackdanzImplement MIDI clock
2017-09-21 Erik MackdanzFix so that comments can go elsewhere in input file
2017-03-04 Erik Mackdanzremove symlinks generated by toolchain
2017-03-04 Erik MackdanzDocs corrections around required 0- mark
2016-09-20 Erik MackdanzEnsure prefix notes get note-off events
2016-09-18 Erik MackdanzFix suffix handling due to paste error
...
heads
13 months ago master
14 months ago clock