./../../src/time-sig.lsp

## linked-named-object/time-sig [ Classes ]

[ Top ] [ linked-named-object ] [ Classes ]

NAME

     time-sig

     File:             time-sig.lsp

     Class Hierarchy:  named-object -> linked-named-object -> sclist -> time-sig

     Version:          1.0.12

     Project:          slippery chicken (algorithmic composition)

     Purpose:          Implementation of a time-sig class that stores
                       information about time signatures, allows comparison of
                       time signatures etc.

     Author:           Michael Edwards: m@michael-edwards.org

     Creation date:    12th February 2001

     $$ Last modified:  16:54:19 Thu Sep 24 2020 CEST

     SVN ID: $Id$

## time-sig/beat-duration [ Methods ]

[ Top ] [ time-sig ] [ Methods ]

DESCRIPTION

     Get the duration in seconds of one beat of the given time-signature at a
     tempo of quarter=60.

ARGUMENTS

     - A time-sig object.

RETURN VALUE

     A number.

EXAMPLE

    ;; Beat duration in seconds for time-signature 2/4 at quarter=60
    (let ((ts (make-time-sig '(2 4))))
      (beat-duration ts))

    => 1.0

    ;; Beat duration in seconds for 6/8 at quarter=60
    (let ((ts (make-time-sig '(6 8))))
      (beat-duration ts))

    => 1.5

SYNOPSIS

    (defmethod beat-duration ((ts time-sig))

## time-sig/get-beat-as-rhythm [ Methods ]

[ Top ] [ time-sig ] [ Methods ]

DESCRIPTION

     Get the beat unit of a given time-sig object and return it as a rhythm.

ARGUMENTS

     - A time-sig object.

OPTIONAL ARGUMENTS

     - T or NIL to indicate whether to consider the beat of a compound meter to
       be the denominator of the time signature (such as 8 for 6/8) or the beat
       duration derived from the traditionally understood beat of that meter
       (such as Q. for 6/8). NIL = denominator. Default = NIL.

RETURN VALUE

     A rhythm object.

EXAMPLE

    ;; Returns a rhythm object
    (let ((ts (make-time-sig '(2 4))))
      (get-beat-as-rhythm ts))

    =>
    RHYTHM: value: 4.000, duration: 1.000, rq: 1, is-rest: NIL,
            score-rthm: 4.0f0, undotted-value: 4, num-flags: 0, num-dots: 0,
            is-tied-to: NIL, is-tied-from: NIL, compound-duration: 1.000,
            is-grace-note: NIL, needs-new-note: T, beam: NIL, bracket: NIL,
            rqq-note: NIL, rqq-info: NIL, marks: NIL, marks-in-part: NIL,
            letter-value: 4, tuplet-scaler: 1, grace-note-duration: 0.05
    LINKED-NAMED-OBJECT: previous: NIL, this: NIL, next: NIL
    NAMED-OBJECT: id: 4, tag: NIL,
    data: 4

    ;; Default for compound meters is to return the denominator of the time
    ;; signature
    (let ((ts (make-time-sig '(6 8))))
      (data (get-beat-as-rhythm ts)))

    => 8

    ;; Setting the optional argument to T returns the compound beat of a compound
    ;; meter rather than the denominator of the time signature
    (let ((ts (make-time-sig '(6 8))))
      (data (get-beat-as-rhythm ts t)))

    => Q.

SYNOPSIS

    (defmethod get-beat-as-rhythm ((ts time-sig) &optional handle-compound)

## time-sig/get-whole-bar-rest [ Methods ]

[ Top ] [ time-sig ] [ Methods ]

DESCRIPTION

     Create an event object consisting of a rest equal in duration to one full
     bar of the given time-sig object.

ARGUMENTS

     - A time-sig object.

RETURN VALUE

     Returns an event object.

EXAMPLE

    ;; Returns an event object
    (let ((ts (make-time-sig '(2 4))))
      (get-whole-bar-rest ts))

    =>
    EVENT: start-time: NIL, end-time: NIL,
           duration-in-tempo: 0.0,
           compound-duration-in-tempo: 0.0,
           amplitude: 0.7
           bar-num: -1, marks-before: NIL,
           tempo-change: NIL
           instrument-change: NIL
           display-tempo: NIL, start-time-qtrs: -1,
           midi-time-sig: NIL, midi-program-changes: NIL,
           8va: 0
           pitch-or-chord: NIL
           written-pitch-or-chord: NIL
    RHYTHM: value: 2.000, duration: 2.000, rq: 2, is-rest: T,
            score-rthm: 2.0f0, undotted-value: 2, num-flags: 0, num-dots: 0,
            is-tied-to: NIL, is-tied-from: NIL, compound-duration: 2.000,
            is-grace-note: NIL, needs-new-note: NIL, beam: NIL, bracket: NIL,
            rqq-note: NIL, rqq-info: NIL, marks: NIL, marks-in-part: NIL,
            letter-value: 2, tuplet-scaler: 1, grace-note-duration: 0.05
    LINKED-NAMED-OBJECT: previous: NIL, this: NIL, next: NIL
    NAMED-OBJECT: id: 2, tag: NIL,
    data: 2

    ;; The rhythmic value of the event object returned is equal to the rhythmic
    ;; duration of a full bar in the given time signature, the PITCH-OR-CHORD slot
    ;; is set to NIL, and the IS-REST slot is set to T.
    (let* ((ts (make-time-sig '(2 4)))
           (tswbr (get-whole-bar-rest ts)))
      (print (value tswbr))
      (print (pitch-or-chord tswbr))
      (print (is-rest tswbr)))

    =>
    2.0
    NIL
    T

SYNOPSIS

    (defmethod get-whole-bar-rest ((ts time-sig))

## time-sig/is-compound [ Methods ]

[ Top ] [ time-sig ] [ Methods ]

DESCRIPTION

     Determine whether the value of a given time-sig object is a compound time
     signature.

ARGUMENTS

     - A time-sig object.

RETURN VALUE

     T if the value of the given time-sig object is a compound time signature,
     otherwise NIL.

EXAMPLE

    ;; Testing a time-sig object with a 2/4 time signature returns NIL
    (let ((ts (make-time-sig '(2 4))))
      (is-compound ts))

    => NIL

    ;; Testing a time-sig object with a 6/8 time signature returns T
    (let ((ts (make-time-sig '(6 8))))
      (is-compound ts))

    => T

SYNOPSIS

    (defmethod is-compound ((ts time-sig))

## time-sig/make-time-sig [ Functions ]

[ Top ] [ time-sig ] [ Functions ]

DESCRIPTION

     Create a time-sig object. In addition to the numerator and denominator
     values, the object also stores other automatically calculated information,
     such as whether the signature is simple or compound, the duration of one
     bar of the given time signature in seconds, the number of midi-clocks, etc.

ARGUMENTS

     - A two-item list of numbers, the first being the numerator (number of
       beats per measure), the second being the denominator (beat type).

RETURN VALUE

     - A time-sig object.

EXAMPLE

    (make-time-sig '(2 4))

    =>
    TIME-SIG: num: 2, denom: 4, duration: 2.0, compound: NIL, midi-clocks: 24, num-beats: 2
    SCLIST: sclist-length: 2, bounds-alert: T, copy: T
    LINKED-NAMED-OBJECT: previous: NIL, this: NIL, next: NIL
    NAMED-OBJECT: id: "0204", tag: NIL,
    data: (2 4)

SYNOPSIS

    (defun make-time-sig (ts)

## time-sig/make-time-sig-from-duration [ Functions ]

[ Top ] [ time-sig ] [ Functions ]

DESCRIPTION

     This tries to generate a reasonable time signature from a given duration in
     seconds. Will not do anything sophisticated like decide between simple and
     compound times.

     This will usually result in a numerator >= 2, but tt's not always easy to
     decide on the best time-sig, e.g. 2/8 is usually preferable to 1/4, but
     1/16 is better than 2/32. Hence there's a call to a routine that
     substitutes less-preferable for more-preferable time-sigs.

ARGUMENTS

     - a duration in seconds

OPTIONAL ARGUMENTS

     - the tempo. This will be used to convert the first argument to quarter
       notes

RETURN VALUE

     a time-sig object

EXAMPLE

    (make-time-sig-from-duration 2) -> 2/4
    (make-time-sig-from-duration 1.75) -> 7/16

SYNOPSIS

    (defun make-time-sig-from-duration (dur-secs
                                        &optional
                                        (tempo 60.0))

## time-sig/scale [ Methods ]

[ Top ] [ time-sig ] [ Methods ]

DESCRIPTION

     Scale the value of the given time-sig object by a specified factor.

ARGUMENTS

     - A time-sig object.
     - A number (scaling factor).

OPTIONAL ARGUMENTS

     - T or NIL to indicate whether or not to preserve the meter by maintaining
       the same number of beats as the numerator of the time signature. T =
       preserve the meter. Default = T.

RETURN VALUE

     A time-sig object.

EXAMPLE

    ;; Scaling a (2 4) time-sig object by 3 creates a new time-sig object with a
    ;; value of 6/4
    (let ((ts (make-time-sig '(2 4))))
      (scale ts 3))

    =>
    TIME-SIG: num: 6, denom: 4, duration: 6.0, compound: NIL, midi-clocks: 24, num-beats: 6
    SCLIST: sclist-length: 2, bounds-alert: T, copy: T
    LINKED-NAMED-OBJECT: previous: NIL, this: NIL, next: NIL
    NAMED-OBJECT: id: "0604", tag: NIL,
    data: (6 4)

    ;; Scaling a (2 4) time-sig object by 2 by default preserves the meter
    (let ((ts (make-time-sig '(2 4))))
      (data (scale ts 2)))

    => (2 2)

    ;; Scaling a (2 4) time-sig object by 2 with the optional argument set to NIL
    ;; changes the meter and results in a 4/4
    (let ((ts (make-time-sig '(2 4))))
      (data (scale ts 2 nil)))

    => (4 4)

    ;; Halving the value of a time-sig object is achieved using a factor of .5
    (let ((ts (make-time-sig '(2 4))))
      (data (scale ts .5)))

    => (2 8)

SYNOPSIS

    (defmethod scale ((ts time-sig) scaler
                      &optional (preserve-meter t) ignore1 ignore2)

## time-sig/time-sig-equal [ Methods ]

[ Top ] [ time-sig ] [ Methods ]

DESCRIPTION

     Determine whether the values of two given time-sig objects are the same. If
     they are identical in signature, return T; if they are different signatures
     but have the same duration (e.g. 2/4, 4/8, 8/16 etc.) return
     TIME-SIG-EQUAL-DURATION; otherwise return NIL.

ARGUMENTS

     - A first time-sig object.
     - A second time-sig object.

RETURN VALUE

     Returns T if the time signatures are identical; returns
     TIME-SIG-EQUAL-DURATION if they are different signatures with the same
     duration; otherwise NIL.

EXAMPLE

    ;; Two identical signatures return T
    (let ((ts1 (make-time-sig '(2 4)))
          (ts2 (make-time-sig '(2 4))))
      (time-sig-equal ts1 ts2))

    => T

    ;; Two different signatures of the same duration return TIME-SIG-EQUAL-DURATION
    (let ((ts1 (make-time-sig '(2 4)))
          (ts2 (make-time-sig '(4 8))))
      (time-sig-equal ts1 ts2))

    => TIME-SIG-EQUAL-DURATION

    ;; Two completely different signatures return NIL
    (let ((ts1 (make-time-sig '(2 4)))
          (ts2 (make-time-sig '(3 4))))
      (time-sig-equal ts1 ts2))

    => NIL

SYNOPSIS

    (defmethod time-sig-equal ((ts1 time-sig) (ts2 time-sig))