spobooks bbv9810.0001.001 in

    Chapter 6: The Stella Command Interpreter

    In Chapter 5, we discussed some basic commands issued to the Stella command interpreter such as new, go, archive, and open. The Stella command interpreter provides a number of powerful commands that allow you to edit slots after computing a container. Editing specific slots is useful if you like the output from a container, but want to make a few adjustments to the output. To demonstrate these slot editing commands, we create a generator named slot-editing and assign its slots using item streams as shown in Example 6.1.

    Example 6.1: slot-editing.lisp

    (generator slot-editing midi-note (length 5)
    (setf note (item (notes c4 cs d in cycle)))
    (setf amplitude (item (amplitudes mp mf f in sequence)))
    (setf duration (item (rhythms e q h in heap)))
    (setf rhythm duration))

    6.1 Referencing Slot Data

    Common Music lists up to 50 objects in a container using the list command.

    Example 6.1.1
    Stella [Slot-Editing]: list
    Slot-Editing:
    1. #<MIDI-NOTE | C4| 1.000| 1.000| 0.500| 0|>
    2. #<MIDI-NOTE |CS4| 2.000| 2.000| 0.600| 0|>
    3. #<MIDI-NOTE | D4| 0.500| 0.500| 0.700| 0|>
    4. #<MIDI-NOTE | C4| 2.000| 2.000| 0.700| 0|>
    5. #<MIDI-NOTE |CS4| 0.500| 0.500| 0.700| 0|>

    You may reference individual objects by specifying the integer identifier for a particular object.

    Example 6.1.2
    Stella [Slot-Editing]: list 1
    Slot-Editing:
    1. #<MIDI-NOTE | C4| 1.000| 1.000| 0.500| 0|>

    You may use list to reference a range of objects by specifying an inclusive upper and lower bound of the range separated by a colon.

    Example 6.1.3
    Stella [Slot-Editing]: list 1:4
    Slot-Editing:
    1. #<MIDI-NOTE | C4| 1.000| 1.000| 0.500| 0|>
    2. #<MIDI-NOTE |CS4| 2.000| 2.000| 0.600| 0|>
    3. #<MIDI-NOTE | D4| 0.500| 0.500| 0.700| 0|>
    4. #<MIDI-NOTE | C4| 2.000| 2.000| 0.700| 0|>

    The list command also references a range of objects with an optional step size. In Example 6.1.4, a step size of two following the lower and upper bound references every other object.

    Example 6.1.4
    Stella [Slot-Editing]: list 1:4:2
    Slot-Editing:
    1. #<MIDI-NOTE | C4| 1.000| 1.000| 0.500| 0|>
    3. #<MIDI-NOTE | D4| 0.500| 0.500| 0.700| 0|>

    Common Music commands may use the wildcard symbol *. In Example 6.1.5, the wildcard * indicates that all items should be listed.

    Example 6.1.5
    Stella [Slot-Editing]: list *
    Slot-Editing:
    1. #<MIDI-NOTE | C4| 1.000| 1.000| 0.500| 0|>
    2. #<MIDI-NOTE |CS4| 2.000| 2.000| 0.600| 0|>
    3. #<MIDI-NOTE | D4| 0.500| 0.500| 0.700| 0|>
    4. #<MIDI-NOTE | C4| 2.000| 2.000| 0.700| 0|>
    5. #<MIDI-NOTE |CS4| 0.500| 0.500| 0.700| 0|>

    The wildcard may also be used to specify the upper or lower bound of a range. Example 6.1.6 uses the wildcard in the upper bound position to reference the last object in the container.

    Example 6.1.6
    Stella [Slot-Editing]: list 2:*
    Slot-Editing:
    2. #<MIDI-NOTE |CS4| 2.000| 2.000| 0.600| 0|>
    3. #<MIDI-NOTE | D4| 0.500| 0.500| 0.700| 0|>
    4. #<MIDI-NOTE | C4| 2.000| 2.000| 0.700| 0|>
    5. #<MIDI-NOTE |CS4| 0.500| 0.500| 0.700| 0|>

    The symbol end may also be used to reference the last object in a container.

    Example 6.1.7
    Stella [Slot-Editing]: list 2:end
    Slot-Editing:
    2. #<MIDI-NOTE |CS4| 2.000| 2.000| 0.600| 0|>
    3. #<MIDI-NOTE | D4| 0.500| 0.500| 0.700| 0|>
    4. #<MIDI-NOTE | C4| 2.000| 2.000| 0.700| 0|>
    5. #<MIDI-NOTE |CS4| 0.500| 0.500| 0.700| 0|>

    The symbol end allows relative referencing. Example 6.1.8 demonstrates use of the list command in conjunction with end -1 to specify one less than the last object.

    Example 6.1.8
    Stella [Slot-Editing]: list 2:end-1
    Slot-Editing:
    2. #<MIDI-NOTE |CS4| 2.000| 2.000| 0.600| 0|>
    3. #<MIDI-NOTE | D4| 0.500| 0.500| 0.700| 0|>
    4. #<MIDI-NOTE | C4| 2.000| 2.000| 0.700| 0|>

    6.2 Assigning Slot Data using set

    The set command may be used in conjunction with object referencing to reassign slots. It is easy to confuse set and SETF. Use SETF to assign slots or global variables. Use the set command to assign slots after the slot has been assigned.

    The set template is:
    set <object reference> <slot-name1> <slot-value1>
    <slot-name2> <slot-value2> <slot-name-n> <slot-value-n>

    In example 6.2.1, we use set to reassign a range of objects. MIDI note objects 2, 3, and 4 are reassigned an amplitude value of .75.

    Example 6.2.1
    Stella [Slot-Editing]: set 2:4 amplitude .75
    Stella [Slot-Editing]: list
    Slot-Editing:
    1. #<MIDI-NOTE | C4| 1.000| 1.000| 0.500| 0|>
    2. #<MIDI-NOTE |CS4| 2.000| 2.000| 0.750| 0|>
    3. #<MIDI-NOTE | D4| 0.500| 0.500| 0.750| 0|>
    4. #<MIDI-NOTE | C4| 2.000| 2.000| 0.750| 0|>
    5. #<MIDI-NOTE |CS4| 0.500| 0.500| 0.700| 0|>

    Item streams may also be used with the set command to reassign slots.

    Example 6.2.2
    Stella [Slot-Editing]: set * amplitude (items .35 .65 .95)
    Stella [Slot-Editing]: list
    Slot-Editing:
    1. #<MIDI-NOTE | C4| 1.000| 1.000| 0.350| 0|>
    2. #<MIDI-NOTE |CS4| 2.000| 2.000| 0.650| 0|>
    3. #<MIDI-NOTE | D4| 0.500| 0.500| 0.950| 0|>
    4. #<MIDI-NOTE | C4| 2.000| 2.000| 0.350| 0|>
    5. #<MIDI-NOTE |CS4| 0.500| 0.500| 0.650| 0|>

    Notice that when item streams are used in conjunction with the set command, we do not need an item stream accessor.

    Item stream pattern types may also be used with the set command.

    Example 6.2.3
    Stella [Slot-Editing]: set * channel (items 0 1 2 in heap)
    Stella [Slot-Editing]: list
    Slot-Editing:
    1. #<MIDI-NOTE | C4| 1.000| 1.000| 0.350| 0|>
    2. #<MIDI-NOTE |CS4| 2.000| 2.000| 0.650| 1|>
    3. #<MIDI-NOTE | D4| 0.500| 0.500| 0.950| 2|>
    4. #<MIDI-NOTE | C4| 2.000| 2.000| 0.350| 1|>
    5. #<MIDI-NOTE |CS4| 0.500| 0.500| 0.650| 0|>

    More than one slot may be assigned with the same set command as seen in Example 6.2.4. The first midi-note object is assigned a MIDI channel of 1 and the rhythm and duration slots are assigned .75. The duration slot is assigned by first evaluating the rhythm slot.

    Example 6.2.4
    Stella [Slot-Editing]: set 1 channel 1 rhythm .75 duration rhythm
    Stella [Slot-Editing]: list
    Slot-Editing:
    1. #<MIDI-NOTE | C4| 0.750| 0.750| 0.350| 1|>
    2. #<MIDI-NOTE |CS4| 2.000| 2.000| 0.650| 1|>
    3. #<MIDI-NOTE | D4| 0.500| 0.500| 0.950| 2|>
    4. #<MIDI-NOTE | C4| 2.000| 2.000| 0.350| 1|>
    5. #<MIDI-NOTE |CS4| 0.500| 0.500| 0.650| 0|>

    6.3 Using Other Functions to Reassign Slot Values

    Common Music has several commands besides set to assign slot values. Let's apply some of these commands to the objects created in Section 6.2.

    The retrograde command reverses the order of objects. Optionally, you may specify a range. The retrograde template is:

    retrograde <optional range>

    Example 6.3.1
    Stella [Slot-Editing]: retrograde
    Retrograde positions: (<cr>=Slot-Editing)
    Stella [Slot-Editing]: list
    Slot-Editing:
    1. #<MIDI-NOTE |CS4| 0.500| 0.500| 0.650| 0|>
    2. #<MIDI-NOTE | C4| 2.000| 2.000| 0.350| 1|>
    3. #<MIDI-NOTE | D4| 0.500| 0.500| 0.950| 2|>
    4. #<MIDI-NOTE |CS4| 2.000| 2.000| 0.650| 1|>
    5. #<MIDI-NOTE | C4| 0.750| 0.750| 0.350| 1|>

    Stella [Slot-Editing]: retrograde 1:3

    Stella [Slot-Editing]: list
    Slot-Editing:
    1. #<MIDI-NOTE | D4| 0.500| 0.500| 0.950| 2|>
    2. #<MIDI-NOTE | C4| 2.000| 2.000| 0.350| 1|>
    3. #<MIDI-NOTE |CS4| 0.500| 0.500| 0.650| 0|>
    4. #<MIDI-NOTE |CS4| 2.000| 2.000| 0.650| 1|>
    5. #<MIDI-NOTE | C4| 0.750| 0.750| 0.350| 1|>

    retrograde is not only a command, but also an item stream macro as explained in Chapter 5. Example 6.3.2 demonstrates use of retrograde as an item stream macro to reverse the order of an item stream.

    Example 6.3.2
    Stella [Slot-Editing]: set 1:3 channel (retrograde (items 2 1 0))
    Stella [Slot-Editing]: list
    Slot-Editing:
    1. #<MIDI-NOTE | D4| 0.500| 0.500| 0.950| 0|>
    2. #<MIDI-NOTE | C4| 2.000| 2.000| 0.350| 1|>
    3. #<MIDI-NOTE |CS4| 0.500| 0.500| 0.650| 2|>
    4. #<MIDI-NOTE |CS4| 2.000| 2.000| 0.650| 2|>
    5. #<MIDI-NOTE | C4| 0.750| 0.750| 0.350| 1|>

    The invert command reverses the direction of each interval from a specified note. Optionally, you may specify a range. The invert template is:

    invert < range> <slot> <expression>

    Example 6.3.3
    Stella [Slot-Editing]: invert * note ef5
    Stella [Slot-Editing]: list
    Slot-Editing:
    1. #<MIDI-NOTE | E6| 0.500| 0.500| 0.950| 0|>
    2. #<MIDI-NOTE |FS6| 2.000| 2.000| 0.350| 1|>
    3. #<MIDI-NOTE | F6| 0.500| 0.500| 0.650| 2|>
    4. #<MIDI-NOTE | F6| 2.000| 2.000| 0.650| 2|>
    5. #<MIDI-NOTE |FS6| 0.750| 0.750| 0.350| 1|>

    The first inverted note slot is calculated by the intervallic distance between the original note slot (d4) and the note reference (ef5). The intervallic distance is a minor ninth. The first inverted note is a minor ninth (or its enharmonic equivalent, the augmented octave) above the note reference. Subsequent notes are inverted in relation to the original note series. For example, if the original note series is an ascending major second, the inverted note series is a descending major second. The wildcard indicates that all midi-note objects should invert the note slot.

    The increment command increases or decreases a specified slot by a specified value or expression. The increment template is:

    increment <range> <slot> <expression>

    In the following example, we subtract .2 seconds from the value of all of the rhythm slots.

    Example 6.3.4
    Stella [Slot-Editing]: increment * rhythm -.2
    Stella [Slot-Editing]: list
    Slot-Editing:
    1. #<MIDI-NOTE | E6| 0.300| 0.500| 0.950| 0|>
    2. #<MIDI-NOTE |FS6| 1.800| 2.000| 0.350| 1|>
    3. #<MIDI-NOTE | F6| 0.300| 0.500| 0.650| 2|>
    4. #<MIDI-NOTE | F6| 1.800| 2.000| 0.650| 2|>
    5. #<MIDI-NOTE |FS6| 0.550| 0.750| 0.350| 1|>

    The transpose command transposes the note slot a specified interval measures in half steps. The transpose template is:

    transpose <range> <slot> <expression>

    The following example transposes all notes down one octave.

    Example 6.3.5
    Stella [Slot-Editing]: transpose * note -12
    Stella [Slot-Editing]: list
    Slot-Editing:
    1. #<MIDI-NOTE | E5| 0.300| 0.500| 0.950| 0|>
    2. #<MIDI-NOTE |FS5| 1.800| 2.000| 0.350| 1|>
    3. #<MIDI-NOTE | F5| 0.300| 0.500| 0.650| 2|>
    4. #<MIDI-NOTE | F5| 1.800| 2.000| 0.650| 2|>
    5. #<MIDI-NOTE |FS5| 0.550| 0.750| 0.350| 1|>

    The shuffle command randomly reorders objects. The shuffle template is:

    shuffle <optional range>

    Example 6.3.6
    Stella [Slot-Editing]: shuffle 1:3
    Stella [Slot-Editing]: list
    Slot-Editing:
    1. #<MIDI-NOTE | E5| 0.300| 0.500| 0.950| 0|>
    2. #<MIDI-NOTE | F5| 0.300| 0.500| 0.650| 2|>
    3. #<MIDI-NOTE |FS5| 1.800| 2.000| 0.350| 1|>
    4. #<MIDI-NOTE | F5| 1.800| 2.000| 0.650| 2|>
    5. #<MIDI-NOTE |FS5| 0.550| 0.750| 0.350| 1|>

    The scale command scales objects by a specified percentage. The scale template is:

    scale <range> <slot> <percentage>

    Example 6.3.7 references the first midi-note and scales its duration by 50%.

    Example 6.3.7
    Stella [Slot-Editing]: scale 1 duration .5
    Stella [Slot-Editing]: list
    Slot-Editing:
    1. #<MIDI-NOTE | E5| 0.300| 0.250| 0.950| 0|>
    2. #<MIDI-NOTE | F5| 0.300| 0.500| 0.650| 2|>
    3. #<MIDI-NOTE |FS5| 1.800| 2.000| 0.350| 1|>
    4. #<MIDI-NOTE | F5| 1.800| 2.000| 0.650| 2|>
    5. #<MIDI-NOTE |FS5| 0.550| 0.750| 0.350| 1|>

    6.3 Scale Predicates

    Common Music has predicate functions that test the value of the note slot in relation to a reference. These predicate functions all begin with scale and have appended to them a relational operator as shown in Table 6.3.1. The reference may be a keynumber, frequency, or symbolic note name. Symbolic note names must be quoted.

    Note that these scale predicates are different from the scale command as described in Example 6.3.7. Scale predicates return a T or NIL value whereas the scale command alters the value of a slot by a specified percentage.

    Table 6.3.1: Scale Predicates

    Predicate

    Example

    Explanation

    scale= reference

    (scale= 'fs5)

    Returns T if scale reference is f-sharp 5

    scale/= reference

    (scale/= 'fs5)

    Returns T if scale reference is not f-sharp 5

    scale< reference

    (scale< 'fs5)

    Returns T if scale reference is less than f-sharp 5

    scale> reference

    (scale> 'fs5)

    Returns T if scale reference is greater than f-sharp 5

    scale<= reference

    (scale<= 'fs5)

    Returns T if scale reference is less than or equal to f-sharp 5

    scale>= reference

    (scale>= 'fs5)

    Returns T if scale reference is greater than or equal to f-sharp 5

    Scale predicates may be used in conjunction with the map command as seen in Section 6.4 or with conditionals as discussed in Chapter 9.

    6.4 Mapping

    The map command is a powerful way to evaluate slot data based on a clause. A clause may be a way to gather information about slots or a condition applied to slots. To apply a clause to a range of slots, specify the objects to be mapped, and then the clause to be applied to those objects. The map command maps the clause to the specified slots. The map template is:

    map <objects> <clause>

    For <objects>,map uses object referencing as discussed in Section 6.1. The power of the map command lies in the <clause>. One type of clause that map uses is the information clause . Information clauses return information about the mapped objects.

    Table 6.4.1 describes map' s information clauses and gives an example of its use. The returned value is based on the following midi-notes in the container named slot-editing:

    Example 6.4.1
    Stella [Slot-Editing]: list
    Slot-Editing:
    1. #<MIDI-NOTE | E5| 0.300| 0.250| 0.950| 0|>
    2. #<MIDI-NOTE | F5| 0.300| 0.500| 0.650| 2|>
    3. #<MIDI-NOTE |FS5| 1.800| 2.000| 0.350| 1|>
    4. #<MIDI-NOTE | F5| 1.800| 2.000| 0.650| 2|>
    5. #<MIDI-NOTE |FS5| 0.550| 0.750| 0.350| 1|>

    Table 6.4.1

    Information ClauseDescriptionExampleEvaluation
    collectGathers the slot data in a specified range. Returns the number of objects evaluated and the slot data of those objects as a list.map 1:3 collect channel
    CLAUSE
    COUNT VALUE
    collect channel
    3 (0 2 1)
    sumAdds the slot data in a specified range. Returns the number of objects evaluated and the sum of the slot data.map 1:3 sum rhythm
    CLAUSE
    COUNT VALUE
    sum rhythm
    3 2.4
    countTallies the number of objects for a particular slot. Returns the number of objects evaluated.map * count note
    CLAUSE
    COUNT VALUE
    count note
    5 5
    minimizeFinds the smallest numeric value of a specified range. Returns the number of objects evaluated and the smallest value.map * minimize amplitude
    CLAUSE
    COUNT VALUE
    minimize amplitude
    5 0.35
    maximizeFinds the largest numeric value of a specified range. Returns the number of objects evaluated and the largest value.map * maximize amplitude
    CLAUSE
    COUNT VALUE
    maximize amplitude
    5 0.95
    lowestFinds the lowest symbolic note name of a specified range. Returns the number of objects evaluated and the lowest value.map 1:3 lowest note
    CLAUSE
    COUNT VALUE
    lowest note
    3 E5
    highestFinds the highest symbolic note name of a specified range. Returns the number of objects evaluated and the highest value.map 3:5 highest note
    CLAUSE
    COUNT VALUE
    highest note
    3 FS5
    averageCalculates the average for a specified number of objects for a given slot. Does not work with symbolic note namesmap * average duration
    CLAUSE
    COUNT VALUE
    average duration
    5 1.1
    findLocates the integer reference for objects that match a condition.map * find (scale> note 'e5)
    CLAUSE
    COUNT VALUE
    find (scale> note 'e5) 4 Slot-Editing [2:5]
    analyzePerforms a statistical analysis on slot for a specified range. Analysis includes number of unique values, minimum, maximum, mean, variance, deviation and a breakdown.map * analyze rhythm
    CLAUSE
    COUNT VALUE
    analyze rhythm
    5
    Unique:3
    Minimum: 0.300
    Maximum: 1.800
    Mean: 0.950
    Variance: 0.613
    Deviation: 0.783

    map may also use Common LISP conditionals such as WHEN and UNLESS. First, let's discuss WHEN and UNLESS before resuming our discussion of the map command and conditional clauses.

    The Common LISP macros WHEN and UNLESS use the following templates:

    (WHEN <CONDITION> <CONSEQUENT-CLAUSE>)

    (UNLESS <CONDITION> <CONSEQUENT-CLAUSE>)

    With WHEN, if <CONDITION> evaluates to T, LISP evaluates the <CONSEQUENT-CLAUSE>). With UNLESS, if <CONDITION> evaluates to T, LISP does not evaluate the <CONSEQUENT-CLAUSE>).WHEN and UNLESS are logical complements.

    Examples 6.4.2 and 6.4.3 reference the value of *standard-tempo* which has a value of 60.

    Stella [Slot-Editing]: ,*standard-tempo*
    60.0

    In Example 6.4.2, WHEN is used with the Common LISP condition (= *STANDARD-TEMPO* 60). Since the value of *standard-tempo* is 60, the condition evaluates to T and LISP evaluates the <CONSEQUENT-CLAUSE>. The <CONSEQUENT-CLAUSE> is the quoted symbol 'hello. In Common LISP, quoted objects evaluate to themselves so LISP returns HELLO.

    Example 6.4.2
    Stella [Slot-Editing]: (when (= *standard-tempo* 60) 'hello)
    HELLO

    In Example 6.4.3, we test again for the value of *standard-tempo*. This time, we use UNLESS.UNLESS evaluates the <CONSEQUENT-CLAUSE> if the <CONDITION> is NIL. Since the <CONDITION> evaluates to T, LISP does not evaluate the <CONSEQUENT-CLAUSE> and returns NIL.

    Example 6.4.3
    Stella [Slot-Editing]: (unless (= *standard-tempo* 60) 'hello)
    NIL

    Now that we understand Common LISP's WHEN and UNLESS, let's resume our discussion of the map command and conditional clauses.

    Recall our slot data from Example 6.4.1.

    1. #<MIDI-NOTE | E5| 0.300| 0.250| 0.950| 0|>
    2. #<MIDI-NOTE | F5| 0.300| 0.500| 0.650| 2|>
    3. #<MIDI-NOTE |FS5| 1.800| 2.000| 0.350| 1|>
    4. #<MIDI-NOTE | F5| 1.800| 2.000| 0.650| 2|>
    5. #<MIDI-NOTE |FS5| 0.550| 0.750| 0.350| 1|>

    Example 6.4.4 uses the map command in conjunction with WHEN. The map command tells Common Music to evaluate midi-notes 1 through 3. If the amplitude of those midi-notes is greater than .5, map assigns the note slots the symbolic note name c4. Because the amplitude of the first and second midi-notes is greater than .5, the note slots of these objects are assigned c4.

    Example 6.4.4
    Stella [Slot-Editing]: map 1:3 when (> amplitude .5) set note 'c4
    Stella [Slot-Editing]: list
    Slot-Editing:
    1. #<MIDI-NOTE | C4| 0.300| 0.250| 0.950| 0|>
    2. #<MIDI-NOTE | C4| 0.300| 0.500| 0.650| 2|>
    3. #<MIDI-NOTE |FS5| 1.800| 2.000| 0.350| 1|>
    4. #<MIDI-NOTE | F5| 1.800| 2.000| 0.650| 2|>
    5. #<MIDI-NOTE |FS5| 0.550| 0.750| 0.350| 1|>

    Example 6.4.5 uses the map command in conjunction with UNLESS. The map command tells Common Music to evaluate all of the midi-notes in the current focus object named Slot-Editing through use of the wildcard *. The condition is (= CHANNEL 2). The condition evaluates to NIL for objects 1, 3 and 5 so the note slots of objects 1,3, and 5 are transposed down an octave.

    Example 6.4.5
    Stella [Slot-Editing]: map * unless (= channel 2) transpose note -12
    Stella [Slot-Editing]: list
    Slot-Editing:
    1. #<MIDI-NOTE | C3| 0.300| 0.250| 0.950| 0|>
    2. #<MIDI-NOTE | C4| 0.300| 0.500| 0.650| 2|>
    3. #<MIDI-NOTE |FS4| 1.800| 2.000| 0.350| 1|>
    4. #<MIDI-NOTE | F5| 1.800| 2.000| 0.650| 2|>
    5. #<MIDI-NOTE |FS4| 0.550| 0.750| 0.350| 1|>

    Example 6.4.6 uses the map command with the scale predicate scale=. Midi-note objects 1 through 3 are evaluated to see if their symbolic note name is equal to c4. The scale= predicate evaluates to T for midi-note objects 1 and 2 and their channel is reassigned a value of 3.

    Example 6.4.6
    Stella [Slot-Editing]: map 1:3 WHEN (scale= note 'c4) set channel 3
    Stella [Slot-Editing]: list
    Slot-Editing:
    1. #<MIDI-NOTE | C4| 0.300| 0.250| 0.950| 3|>
    2. #<MIDI-NOTE | C4| 0.300| 0.500| 0.650| 3|>
    3. #<MIDI-NOTE |FS5| 1.800| 2.000| 0.350| 1|>
    4. #<MIDI-NOTE | F5| 1.800| 2.000| 0.650| 2|>
    5. #<MIDI-NOTE |FS5| 0.550| 0.750| 0.350| 1|>

    6.5 Duplicating A Container

    Common Music commands such as set, retrograde, invert, increment, transpose and shuffle are destructive operations. Once these commands are issued, there is no way to "un do" what has been done. For this reason, it is a good idea to make a copy of a container and its contents before issuing these commands.

    To copy a container and its contents, use the Common Music command duplicate.

    Example 6.5.1
    Stella [Slot-Editing]: duplicate
    Duplicate object: slot-editing
    Pasted Slot-Editing-Copy to Top-Level.
    Stella [Slot-Editing]: up
    Focus: Top-Level
    Type: Container
    Status: System
    Objects: 2
    Stella [Top-Level]: list
    Top-Level:
    1. #<GENERATOR: Slot-Editing>

    2. #<THREAD: Slot-Editing-Copy>

    duplicate copies a container and its contents to a new object. The new object is automatically placed in Top-Level. In Example 6.5.1, the duplicate command created a new generator named Slot-Editing-Copy placed it in Top-Level.