slippery-chicken/reaper-play [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DESCRIPTION

 Using the sound files (samples) defined for the given reference (group ID)
 in the sndfile-palette slot of the slippery-chicken object, use CLM to
 generate a new sound file using the pitch and timing information of one or
 more players' parts from the slippery-chicken object.

 NB: The sound file will begin with the first sounding event in the section
     at 0.0 seconds. If there are any leading rests in the player's part,
     these will be omitted in the output file.

 By grouping sound files in the sndfile-palette slot, the user can generate
 a CLM sound file version of the piece in various 'flavours'; perhaps, for
 example, using exclusively source sound files consisting of string samples,
 or percussion sounds, or a variety of sounds, as desired. See below for an
 example of a sndfile-palette.
 
 By default, as :pitch-synchronous default to NIL (see below) this method
 does not attempt to match the pitches of the output sound file to those
 generated for the slippery-chicken object, rather, it generates its own
 sequence of pitches based on pitches from the current set. Instead of using
 the pitches of the specified players' parts--which might produce extreme
 sound file transpositions both upwards and downwards--it accesses each note
 of the current set (assigned by the set-map to each rthm-seq) from the
 bottom up, one voice after another. If do-src is T, transposition will then
 be calculated such that the frequency of the sound file (defaults to C4 in
 the sndfile object) will be shifted to the pitch of the given pitch of the
 set. When the set changes it will play the same respective note number of
 that set, etc. This means that, in effect, any given voice will retain the
 same pitch for the duration of the rthm-seq (set) but as the sound files
 cycle around, and these often have quite different pitch/spectral content,
 there's not necessarily a sense of pitch repetition. If you find that this
 transposition process still yields some extreme transpositions, the
 :note-number keyword can be specified to indicate an index into the current
 set of pitches to serve as the lowest voice. If you increase :note-number
 the transpositions will get higher. If the number of voices plus this index
 exceeds the number of pitches in the set, the method will wrap around to
 the lowest pitch of the set. Bear in mind then that when :pitch-synchronous
 is NIL, the pitch-seq curves given in the rthm-seq-palette--and therefore
 all the carefully chosen pitches in the piece--will be ignored in favour of
 representing the transpositions and therefore intervals present in the
 set. That might seem like a strange thing to (want to) do, but it's served
 me (Michael Edwards) very well on many occasions, so it's still the
 default.

 If instead of the above method the user would like the pitches in the
 resulting sound file to be transposed to match the pitches of the
 players' notes, the keyword argument :pitch-synchronous can be set
 to T (and do-src should be left set to T as well). This will also work with
 chords.

 See also make-sfp-from-wavelab-marker-file in sndfile-palette.lsp for
 automatically creating a sndfile-palette from markers in a Steinberg
 Wavelab marker file.

 Event amplitudes are as yet unused by this method.

 NB: CLM's nrev instrument must be loaded before calling this method. If
 you're using the slippery-chicken app, then this is done for you at
 startup. 

ARGUMENTS

 - A slippery chicken object.
 - The ID of the starting section.
 - The IDs of the player(s) whose events are to be used to obtain the
   rhythmic structure (and optionally, pitch content) of the resulting sound
   file. This can be a single symbol for an individual player, a list of
   player IDs, or NIL. If NIL, the event from all players' parts will be
   reflected in the output file. Default = NIL.
 - The ID of the sound file group in the sndfile-palette slot of the
   slippery-chicken object that contains the source sound files from which
   the new sound file is to be generated.

OPTIONAL ARGUMENTS

 keyword arguments:
 - :num-sections. An integer or NIL to indicate how many sections should be
   generated, including the starting section. If NIL, sound file data will
   be generated for all sections of the piece. NB If there are sub-sections
   this will include them in the total, i.e., if section 1 has 3 subsections
   and :num-sections is 2, we'll generate data from the first two
   subsections of section 1, not all subsections of main sections 1 and
   2. Default = NIL. 
 - :from-sequence. An integer that is the number of the first sequence
   within the specified starting section to be used to generate the output
   file. This argument can only be used when num-sections = 1. Default = 1. 
 - :num-sequences. NIL or an integer that indicates how many sequences are
   to be generated, including that specified by :from-sequence. If NIL, all
   sequences will be played. This argument can only be used when
   num-sections = 1 and the section has no subsections. Default = NIL.
 - :srate. A number that is the sampling rate of the output file
   (independent of the input file). This and the following two arguments
   default to the CLM package globals. See clm.html for more options.
   Default = clm::*clm-srate*.
 - :header-type: A CLM package header-type specification to designate the
   output sound file format. For example, clm::mus-riff will produce .wav
   files, clm::mus-aiff will produce .aiff files. The value of this argument
   defaults to the CLM package globals. See clm.html for more
   options. Default = clm::*clm-header-type*.
 - :data-format. A CLM package data-format specification to designate the
   output sound file sample data format. For example, clm::mus-float will
   produce a 32-bit little-endian floating-point format; clm::mus-l24int
   will produce little-endian 24-bit integer; mus-bshort will produce 16-bit
   big-endian files, and mus-bfloat will produce 32-bit floating-point
   big-endian files. NB: AIFF and AIFC files are not compatible with little
   endian formats. The value of this argument defaults to the CLM package
   globals. See clm.html for more options. 
   Default = clm::*clm-data-format*.
 - :sndfile-extension. NIL or a string that will be the extension of the
   output sound file (e.g. ".wav", ".aif"). If NIL, the method will
   determine the extension automatically based on the header-type. NB: The
   extension does not determine the output sound file format; that is
   determined by :header-type. Default = NIL.
 - :channels. An integer that is the number of channels in the output sound
   file, limited only by the sound file format specified. Note that both
   stereo and mono sounds from the palette will be randomly panned between
   any two adjacent channels. Default = 2.
 - :rev-amt. A number that determines the amount of reverberation for the
   resulting sound file, passed to CLM's nrev. 
   NB: 0.1 is a lot. Default = 0.0.
 - time-offset. A number that is an offset time in seconds. This produces a
   lead time of a specified number of seconds of silence prior to the sound
   output. 
 - :inc-start. T or NIL to indicate whether playback of the source sound
   files is to begin at incrementally increasing positions in those files or
   at their respective 0.0 positions every time. If T, the method will
   increment the position in the source sound file from which playback is
   begun such that it reaches the end of the source sound file the last time
   it is 'played'. T = increment start times. Default = NIL.
 - :ignore-rests. T or NIL to indicate whether silence should be
   incorporated into the resulting sound file to correspond with rests in
   the player's parts. If T, the sound files will play over the duration of
   rests. However, this is only true on a bar-by-bar basis; i.e., notes at
   the end of one bar will not be continued over into a rest in the next
   bar. This implies that rests at the start of a bar will not be turned
   into sounding notes. T = ignore resets. Default = T.
 - :sound-file-palette-ref2. The ID of a sound file group in the given
   slippery-chicken object's sndfile-palette slot. If this reference is
   given, the method will invoke fibonacci-transitions to transition from
   the first specified group of source sound files to this one. If NIL, only
   one group of source sound files will be used. Default = NIL.
 - :do-src. T, NIL, a number, or a note-name pitch symbol to indicate whether
   transposition of the source sound files for playback will be calculated
   such that the perceived fundamental frequencies of those sound files are
   shifted to match the pitches of the current set. If do-src is a number
   (frequency in Hertz) or a note-name pitch symbol, the method will use
   only that pitch instead of the sound files' frequencies when transposing
   to the events' pitches. NB Whichever is used, after being converted to a
   sample rate conversion factor, this is always multiplied by the
   src-scaler (see below). T = match sound files' frequencies to set
   pitches. NIL means no transposition will be performed. Default = T.
 - :pitch-synchronous: T or NIL to indicate whether the source sound files
   are to be transposed to match the pitches of the events in the given
   players' part. This will only be effective if the given source sound file
   has a perceptible frequency that has been specified using the sndfile
   object's :frequency slot in the sndfile-palette. :do-src must also be T
   for this to work. T = match pitches. Default = NIL.
 - :reset-snds-each-rs. T or NIL to indicate whether to begin with the first
   source sound file of the specified group at the beginning of each
   rthm-seq. T = begin with the first sound file. Default = T.
 - :reset-snds-each-player. T or NIL to indicate whether to begin with the
   first source sound file of the specified group for the beginning of each
   player's part. T = begin with the first sound file. Default = T. 
 - :play-chance-env. A list of break-point pairs that determines the chance
   that a given event from the source player's part will be reflected in the
   new sound file. It is determined by random selection but uses a fixed
   seed that is re-initialized each time clm-play is called. The following
   default ensures every note will play: '(0 100 100 100).
 - :play-chance-env-exp. A number that will be applied as the exponent to
   the play-chance-env's y values to create an exponential interpolation
   between break-point pairs. Default = 0.5.
 - :max-start-time. A number that is the last time-point in seconds for
   which events will be processed for the output file. If a maximum start
   time is specified here (in seconds), events after this will be
   skipped. The default value of 99999999 seconds (27778 hours) will result
   in all events being reflected in the sound file.
 - :time-scaler. A number that will be the factor by which all start times
   are scaled for the output file (in effect a tempo scaler). If
   :ignore-rests is T, this will also have an indirect effect on
   durations. This argument should not be confused with
   :duration-scaler. Default = 1.0.
 - :duration-scaler. A number that is the factor by which the duration of
   all  events in the output sound file will be scaled. This does not alter
   start times, and will therefore result in overlapping sounds if greater
   than 1.0. This is not to be confused with :time-scaler. 
   Instead of a simple number, :duration-scaler can also be an envelope 
   (a list of break-point pairs). This means you could smoothly transition
   from staccato-like to overlapping sounds in a single clm-play call.
   Default = 1.0.
 - :amp-env. A list of break-point pairs that will govern the amplitude
   envelope applied to all source-sound files as it is being written to the
   new output file. NB: If the user wants to maintain the original attack of
   the source sound file and is not employing the :inc-start option, this
   should be set to '(0 1 ...). If :inc-start is T, the resulting sound file
   will probably contain clicks from non-zero crossings. 
   Default = '(0 0 5 1 60 1 100 0).
 - :src-scaler: A number that is the factor by which all sample-rate
   conversion values will be scaled (for increasing or decreasing the
   transposition of the overall resulting sound file). 
   Instead of a simple number, :src-scaler can also be an envelope 
   (a list of break-point pairs), similar to :duration-scaler. Default = 1.0.
 - :note-number. A number that is an index, representing the the nth pitch
   of the current set or chord (from the bottom) to be used for the lowest
   player. Default = 0.
 - :duration-run-over. T or NIL to indicate whether the method will allow a
   sound file event to extend past the end of specified segment boundaries
   of a sound file in the sndfile-palette. T = allow. Default = NIL.
 - :short-file-names. T or NIL to indicate whether abbreviated output file
   names will be automatically created instead of the usually rather long
   names. T = short. Default = NIL.
 - :output-name-uniquifier. A user-specified string that will be
   incorporated into the file name, either at the end or the beginning
   depending on whether short-file-names is T or NIL. Default = "".
 - :check-overwrite. T or NIL to indicate whether to query the user before
   overwriting existing sound files. T = query. Default = T.
 - :print-secs. T or NIL to indicate whether CLM should print the seconds
   computed as it works. T = print. Default = NIL.
 - :sndfile-palette. NIL or a file name including path and extension that
   contains an external definition of a sndfile-palette. This will replace
   any sndfile-palette defined in the slippery-chicken object. If NIL, the
   one in the slippery-chicken object will be used. Default = NIL.
 - :chords. NIL or a list of lists consisting of note-name symbols to be
   used as the pitches for the resulting sound file in place of the pitches
   from the set-map. There must be one chord specified for each sequence. If
   NIL, the pitches from the set-map will be used. Default = NIL.
 - :chord-accessor. Sometimes the chord stored in the palette is not a
   simple list of data so we need to access the nth of the chord
   list. Default = NIL.
 - :clm-ins. The CLM instrument that should be called to generate sound file
   output. This must accept required and keyword arguments like samp5 (see
   src/samp5.lsp or more simply src/sine.lsp) but can of course choose to
   ignore them. Remember that your CLM instruments will (most probably) be
   in the CLM package so you'll need the clm:: qualifer. Default =
   #'clm::samp5. 
 - :clm-ins-args. This should be a list of keyword arguments and values to
   pass to each CLM instrument call (e.g. '(:cutoff-freq 2000 :q .6)) or a
   function which takes two arguments (the current event and the event
   number) and returns a list of keyword arguments perhaps based on
   those. Default = NIL.
 - :pan-min-max. Each event is panned randomly between any two adjacent
   channels in the output sound file. The values used are chosen from the
   following list of degrees: (15 25 35 45 55 65 75). However, these can be
   scaled to be within new limits by passing a two-element list to
   :pan-mix-max. E.g. '(40 50) would limit most values to the middle area of
   stereo space. NB if stereo soundfiles are used as input the original
   panning will generally be retained. See samp5.lsp for details of how such
   files are handled. Default = NIL (i.e. use the list given above).
 - :pan-fun. If you want to take charge of selecting pan positions yourself,
   pass a function via this keyword. The function must take one argument: the
   current event, though of course, it can ignore it completely if
   preferred. The function should return a degree value: a number between 0
   and 90. Bear in mind if using samp5 with more than 2 output channels that
   this will still result in the sound moving around multichannel space as
   all you would be setting is the pan value between any two adjacent
   channels. If this isn't your cup of tea, pass a new instrument entirely
   via :clm-ins. See example below. Default = NIL.
 - :snd-selector. By default the sound files in the given group are cycled
   through, one after the other, returning to the beginning when the end is
   reached. This can be changed by passing a function to :snd-selector. This
   function must take three arguments: the circular-sclist object that
   contains the group's sndfile objects (the sndfiles are in a simple list
   in the data slot); the pitch of the current event (if the event happens
   to be a chord, each pitch of the chord will be handled separately
   i.e. the :snd-selector function will be called for each pitch); and the
   event object. Of course any of these arguments may be ignored by the
   :snd-selector function; indeed it is imagined that the event object will
   be mostly ignored and the pitch object used instead, but it is
   nevertheless passed for completeness. For example, the following
   function, declared on-the-fly using lambda rather than separately with
   defun, makes clm-play act as a traditional sampler would: Assuming our
   sndfile-palette group has a list of sound files whose frequencies really
   correspond to their perceived fundamentals (e.g. see the
   set-frequency-from-filename method, and the kontakt-to-sfp function) we
   choose the nearest sound file in the group to the frequency of the
   current event's pitch:

            :snd-selector #'(lambda (sflist pitch event)
                              (declare (ignore event))
                              (get-nearest-by-freq
                               (frequency pitch) (data sflist)))

   NB If :pitch-synchronous is NIL, then the pitch-or-chord slot of the event
   will be the pitch selected from the current set, rather than the actual
   pitch of the instrument in question.
   Default = NIL i.e. use the circular selection method.
 - :decay-time. Reverb decay time. Default = 3 seconds.
 - :snd-transitions. Set the transition from sound-file-ref to sound-file-ref
   over the course of the call to clm-play using a custom envelope instead of
   the default fibonacci-transitions method, e.g. '(0 0 100 1). x-axis is
   arbitrary, y-axis should range from 0 to 1. When reading, y-values will be
   rounded.
 - :file. reaper file name, if you don't want this to be auto-generated. A
   full path is expected.

RETURN VALUE

 Total events generated (integer).

EXAMPLE

;;; An example using some of the more frequent arguments
(let ((mini
       (make-slippery-chicken
        '+mini+
        :ensemble '(((cl (b-flat-clarinet :midi-channel 1))
                     (hn (french-horn :midi-channel 2))
                     (vc (cello :midi-channel 3))))
        :set-palette '((1 ((f3 g3 a3 b3 c4 d4 e4 f4 g4 a4 b4 c5))))
        :set-map '((1 (1 1 1 1 1 1 1))
                   (2 (1 1 1 1 1 1 1))
                   (3 (1 1 1 1 1 1 1)))
        :rthm-seq-palette '((1 ((((4 4) h (q) e (s) s))
                                :pitch-seq-palette ((1 (2) 3))))
                            (2 ((((4 4) (q) e (s) s h))
                                :pitch-seq-palette ((1 2 (3)))))
                            (3 ((((4 4) e (s) s h (q)))
                                :pitch-seq-palette ((2 3 3))))
                            (4 ((((4 4) (s) s h (q) e))
                                :pitch-seq-palette ((3 (1) 2)))))
        :rthm-seq-map '((1 ((cl (2 3 2 4 1 3 1))
                            (hn (2 4 1 2 3 1 3))
                            (vc (1 2 2 3 4 1 3))))
                        (2 ((cl (4 2 1 3 3 1 2))
                            (hn (2 1 4 3 2 1 3))
                            (vc (2 3 4 3 1 2 1))))
                        (3 ((cl (3 1 2 4 3 1 2))
                            (hn (3 4 2 1 3 2 1))
                            (vc (3 2 3 1 4 2 1)))))
        :snd-output-dir (get-sc-config 'default-dir)
        :sndfile-palette '(((sndfile-grp-1
                             ((test-sndfile-1.aiff)
                              (test-sndfile-2.aiff)
                              (test-sndfile-3.aiff)))
                            (sndfile-grp-2
                             ((test-sndfile-4.aiff :frequency 834)
                              (test-sndfile-5.aiff)
                              (test-sndfile-6.aiff))))
                           ("/path/to/sndfiles-dir-1"
                            "/path/to/sndfiles-dir-2")))))
  (clm-play mini 2 '(cl vc) 'sndfile-grp-1
            :num-sections 1
            :srate 48000
            :header-type clm::mus-aiff
            :data-format clm::mus-b24int
            :rev-amt 0.05
            :inc-start t
            :ignore-rests nil
            :sound-file-palette-ref2 'sndfile-grp-2
            :pitch-synchronous t
            :reset-snds-each-rs nil
            :reset-snds-each-player nil))

;;; A minimal working example demonstrating envelope-arguments 
;;; to duration-scaler and src-scaler
(let* ((mini
        (make-slippery-chicken
         '+mini+
         :ensemble '(((vn (violin :midi-channel 1))))
         :set-palette '((1 ((c4 d4 e4 f4 g4 a4 b4 c5))))
         :set-map '((1 (1 1 1)))
         :rthm-seq-palette '((1 ((((2 4) (s) (s) e e e))
                                 :pitch-seq-palette ((1 2 3)))))
         :rthm-seq-map '((1 ((vn (1 1 1)))))
         :snd-output-dir "/tmp/"
         :sndfile-palette '(((sndfile-grp-1
                              ((test-sndfile-1.aiff)
                               (test-sndfile-2.aiff)
                               (test-sndfile-3.aiff))))
                            ("/path/to/sndfiles-dir-1")))))
  (clm-play mini 1 'vn 'sndfile-grp-1
            :src-scaler '(0 .5  80 1  100 2)
            :do-src 500
            :src-width 5
            :duration-scaler '(0 .1  80 1  100 2)
            :check-overwrite nil
            :play nil :header-type clm::mus-riff))

;;; if you don't want amplitude panning, rather a random placement of each sound
;;; in one channel only, then this should work (no matter how many channels
;;; there are in your output file):

    :pan-fun #'(lambda (event)
                 (declare (ignore event))
                 (nth (random-rep 2) '(0 90)))

SYNOPSIS

#+clm
(defmethod reaper-play ((sc slippery-chicken) section players 
                        sound-file-palette-ref 
                        &key 
                        sound-file-palette-ref2
                        (play-chance-env '(0 100 100 100))
                        (max-start-time 99999999)
                        (play-chance-env-exp 0.5)
                        (time-scaler 1.0)
                        (from-sequence 1)
                        (num-sequences nil)
                        (num-sections nil)
                        (ignore-rests t)
                        (time-offset 0.0)
                        (chords nil)
                        (chord-accessor nil)
                        (note-number 0)
                        (amp-env '(0 0 5 1 60 1 100 0))
                        (inc-start nil)
                        ;; either a number or an envelope
                        (src-scaler 1.0)
                        (do-src t)
                        (pitch-synchronous nil)
                        ;; either a number or an envelope
                        (duration-scaler 1.0)
                        (short-file-names nil)
                        ;; by default we generate filenames according to players
                        ;; and other relevent data but if this is given then
                        ;; we'll use it instead 
                        (file nil)
                        (check-overwrite t)
                        (reset-snds-each-rs t)
                        (reset-snds-each-player t)
                        (duration-run-over nil)
                        (channels 2)
                        (srate 48000)
                        (output-name-uniquifier "")
                        (sndfile-palette nil)
                        ;; MDE Sat Oct  3 18:45:28 2015 -- for Cameron!
                        pan-fun
                        ;; MDE Thu Oct  1 21:03:59 2015 
                        (pan-min-max nil) ; actually '(15 75) by default below
                        ;; MDE Thu Oct  1 19:13:49 2015
                        snd-selector 
                        ;; DJR Mon 16 Sep 2019 01:26:11 BST We can now set
                        ;; snd-transitions with a custom envelope, e.g. '(0 0
                        ;; 100 1). x-values are arbitrary, y-values are from 0
                        ;; (for sound-file-palette-ref) and 1 (for
                        ;; sound-file-palette-ref2).
                        snd-transitions)