コード例 #1
0
ファイル: 03_endless_scales.py プロジェクト: mpdehaan/camp
def play():

    # this really isn't endless, because we've engaged a global stop timer.
    # but if you change 10 to 100, it will play for 100 seconds.  Make note
    # of the use of Endlessly here to see that data sources are not exhausted.

    output = Performance(bpm=120, stop_seconds=10)

    # play the two scales for 7 beats each, and then keep using those scales
    scale1 = scale("c6 major")
    scale2 = scale("c6 minor")
    scale_choices = [ dict(scale=scale1, beats=7), dict(scale=scale2, beats=7) ]

    source = ScaleSource(scales=Endlessly(scale_choices))

    # note: the syntax is simpler to just play ONE scale repeatedly, and you'll see this
    # done more in future examples.  Because we don't need to stay in one scale for N beats
    # before moving on to another, we don't need all the extra info.
    # source = ScaleSource(scales=scale1)

    # the scale follower will play the first 7 notes in each scale, whatever the current
    # scale is.
    follower = ScaleFollower(lengths=7, channel=1)
    source.chain([follower, output])

    conductor = Conductor(signal=[source], performance=output)
    conductor.start()
コード例 #2
0
ファイル: 08_multiple_tracks.py プロジェクト: mpdehaan/camp
def play():

    # here's an example that might *START* to approximate a song.
    # here we have two instruments playing on two different tracks.

    output = Performance(bpm=60, stop_seconds=10)

    # both instruments will use the same scale at the same time, but there is a scale
    # change as we cycle between scales every 24 beats

    scale1 = scale("c5 major_pentatonic")
    scale2 = scale("e5 mixolydian")
    scale_choices = [dict(scale=scale1, beats=24), dict(scale=scale2, beats=24)]
    source = ScaleSource(scales=Endlessly(scale_choices))

    # the first instrument plays a series of chords, transposed down an octave
    # from the original scale carrier signal.

    roman1 = Roman(symbols=Endlessly("I IV V IV III:dim ii".split()), channel=1)
    transpose1 = Transpose(octaves=-1)
    source.chain([roman1, transpose1, output])

    # the second instrument plays a series of notes, but is responding to sixteenth
    # notes, not quarter notes, because of the subdivide.

    subdivide2 = Subdivide(splits=4)
    roman2 = Roman(symbols=Endlessly("1 4 3 4 4 3 2 1".split()), channel=2)
    source.chain([subdivide2, roman2, output])

    # homework assignment:
    # change subdivide2 so it's chained BEFORE roman2
    # what happens and why?

    conductor = Conductor(signal=[source], performance=output)
    conductor.start()
コード例 #3
0
def play():

    # this really isn't endless, because we've engaged a global stop timer.
    # but if you change 10 to 100, it will play for 100 seconds.  Make note
    # of the use of Endlessly here to see that data sources are not exhausted.

    output = Performance(bpm=120, stop_seconds=10)

    # play the two scales for 7 beats each, and then keep using those scales
    scale1 = scale("c6 major")
    scale2 = scale("c6 minor")
    scale_choices = [dict(scale=scale1, beats=7), dict(scale=scale2, beats=7)]

    source = ScaleSource(scales=Endlessly(scale_choices))

    # note: the syntax is simpler to just play ONE scale repeatedly, and you'll see this
    # done more in future examples.  Because we don't need to stay in one scale for N beats
    # before moving on to another, we don't need all the extra info.
    # source = ScaleSource(scales=scale1)

    # the scale follower will play the first 7 notes in each scale, whatever the current
    # scale is.
    follower = ScaleFollower(lengths=7, channel=1)
    source.chain([follower, output])

    conductor = Conductor(signal=[source], performance=output)
    conductor.start()
コード例 #4
0
def play():

    # now modifying our previous example, instead of playing the same two
    # scales in a loop, let's play a given set of notes in each scale.
    # We'll use roman notation to play the 1st, 4th, and 5th note in the scale
    # followed by the 1st, 4th, and 5th major chord
    # finally, we'll play the 2nd, 3rd, and 6th minor chord.


    output = Performance(bpm=120, stop_seconds=10)

    # this is just as before, playing one scale then the other in a loop of 7
    # notes each
    scale1 = scale("c6 major")
    scale2 = scale("c6 minor")
    scale_choices = [ dict(scale=scale1, beats=7), dict(scale=scale2, beats=7) ]
    source = ScaleSource(scales=Endlessly(scale_choices))

    # the scale follower will play the first 7 notes in each scale, whatever the current
    # scale is.  Note that a scale change that doesn't quite line up with the length
    # of the roman pattern rolling over might sound a bit weird.  That's ok.
    roman = Roman(symbols=Endlessly("1 4 5 I IV V ii iii vi".split()), channel=1)
    source.chain([roman, output])

    conductor = Conductor(signal=[source], performance=output)
    conductor.start()
コード例 #5
0
ファイル: 17_permit.py プロジェクト: mpdehaan/camp
def play():

    # Let's show how to play a sequence of one length but omit every Nth note

    output = Performance(bpm=120, stop_seconds=15)

    source = ScaleSource(scales=scale("D minor"))

    melody = Roman(symbols=Endlessly("1 2 3 4 5 6 7".split()), channel=1)
    silence = Permit(when=Endlessly([1, 1, 0]))

    # so we're playing a pattern of 1 2 3 4 5 6 7 of scale degree notes in a giant loop
    # the first time through what really happens is:
    #    1 2 <REST> 4 5 <REST> 7
    # and the second time:
    #    1 <REST> 3 4 <REST> 6 7
    # and the third time:
    #    <REST> 2 3 <REST> 5 6 <REST>
    # all of this is because the pattern and the 'silence' pattern are of unequal lengths

    # this is not ALWAYS relevant in a composition, but if you want to do something
    # polyrhytmic and unorthodox (not just with 'Silence') patterns of  unequal length
    # can be interesting.

    # HOMEWORK: experiment with changing the melody patterns and the silence patterns

    # HOMEWORK: change endlessly to randomly, and see what happens

    source.chain([melody, silence, output])
    conductor = Conductor(signal=[source], performance=output)
    conductor.start()
コード例 #6
0
ファイル: 15_repeated_patterns.py プロジェクト: mpdehaan/camp
def play():

    # in example 14 we showed how to nest patterns in ways that are easier
    # to conceptualize.  For instance, these patterns play in order, and we
    # call that a movement.  However, it's often tedious to specify things
    # that replay again and again.  To do make this easy, we have a new
    # selector to introduce - Repeatedly!


    output = Performance(bpm=240, stop_seconds=100)

    scale_choices = Endlessly([scale("D minor")])
    source = ScaleSource(scales=scale_choices)

    pattern1 = Roman(symbols=Repeatedly("1 2 3 4".split(), cycles=2))
    pattern2 = Roman(symbols="4 3 2 1".split())
    movement1 = Ordered(sources=[pattern1, pattern2])

    pattern3 = Roman(symbols=Repeatedly("1 4 1 4 1 5 1 5".split(), cycles=2))
    pattern4 = Roman(symbols="I IV V I".split())
    movement2 = Ordered(sources=[pattern3, pattern4])

    suite = Ordered(sources=[movement1, movement2], channel=1)

    source.send_to(suite)

    # for this example, we won't do anything crazy with transpositions or anything.

    suite.send_to(output)

    conductor = Conductor(signal=[source], performance=output)
    conductor.start()
コード例 #7
0
ファイル: 20_randomness3.py プロジェクト: mpdehaan/camp
def play():

    # Permit, introduced in the example 18_randomness2.py allows us to
    # silence an entire chain when certain conditions are met.

    # However, sometimes, we may want to decide to apply an affect only
    # when something is true.  Because this could be useful ANYWHERE
    # the same type of "when" logic can actually be attached to ANYTHING.

    # here is a probabilistic way to use random, that combines the concepts.

    output = Performance(bpm=120, stop_seconds=15)

    source = ScaleSource(scales=scale("Ab blues"))

    melody = Roman(symbols=Endlessly("1 2 3 4 5 6 7".split()), channel=1)
    chordify = Chordify(types=Endlessly(['major','minor']), when=Randomly([0,0.45], mode='probability'))
    transpose = Transpose(octaves=Endlessly([2,-2]), when=Randomly([0,0,0.75], mode='probability'))

    # the result is every other note has a 40% chance of becoming a chord,  which is always alternating
    # major and minor when it happens

    # every THIRD note has a 75 percent chance of being transposed, which will be alternating +2/-2 octaves
    # when it happens

    # so now, we have easily inserted CONDITIONAL effects.  The use of when=Randomly wasn't required.
    # we could also have used Endlessly or Repeatedly.  Though keep in mind if using Repeatedly, when
    # the event chain is exhausted, that particular part of the performance will stop.  And when everything stops,
    # the performance is done.  Because this is likely being applied to an effect chain, Repeatedly probably
    # doesn't make the most sense with "when".  But Endlessly?  Sure!

    source.chain([melody, chordify, transpose, output])
    conductor = Conductor(signal=[source], performance=output)
    conductor.start()
コード例 #8
0
ファイル: 21_randomness4.py プロジェクト: mpdehaan/camp
def play():

    # we've focussed a lot on randomness now.  So far, we've shown how to pick random values
    # for notes and how to conditionally do something or not with "when=".

    # What's interesting though is that, due to the way some effects plugins work, we can choose
    # to intermix effects.  Here, we show that there are really two patterns going on, but only one
    # is going to win and actually get to play a note.

    # we're relying one 'musician' object stomping on another, but only sometimes.

    output = Performance(bpm=120, stop_seconds=15)

    source = ScaleSource(scales=scale("Ab blues"))

    pattern1 = Endlessly("1 2 3 4 5 6 7".split())
    pattern2 = Randomly("VII:power VI:power V:power IV:power III:power II:power I:power".split())
    cut_over = Randomly([0,0,0,1,1,1], mode='probability')

    melody1 = Roman(symbols=pattern1, channel=1)
    melody2 = Roman(symbols=pattern2, channel=2, when=cut_over)
    transpose = Transpose(octaves=Endlessly([-2,-1,0,1,2]))

    # there is no sane reason to want to do this, but what happens is that for the first three notes we are guaranteed
    # to play pattern1.  Then three notes of pattern 2.  The last note is acutally a toss up between pattern1 and pattern2.
    # since they live in the same chain, pattern1 is going to overwrite pattern2 even though they are expressed in a chain.
    # we can also even choose to overwrite the MIDI channel, which we do, all while sharing a transposition cycle.

    # again, this isn't realistic for most compositions, we'd likely just set up a bunch of patterns with RESTS, but
    # I wanted to show all the possibilities before leaving the theme of randomness for a while.  Hopefully the
    # idea of "when=" is now drummed in.

    source.chain([melody1, melody2, transpose, output])
    conductor = Conductor(signal=[source], performance=output)
    conductor.start()
コード例 #9
0
def play():

    # in example 14 we showed how to nest patterns in ways that are easier
    # to conceptualize.  For instance, these patterns play in order, and we
    # call that a movement.  However, it's often tedious to specify things
    # that replay again and again.  To do make this easy, we have a new
    # selector to introduce - Repeatedly!

    output = Performance(bpm=240, stop_seconds=100)

    scale_choices = Endlessly([scale("D minor")])
    source = ScaleSource(scales=scale_choices)

    pattern1 = Roman(symbols=Repeatedly("1 2 3 4".split(), cycles=2))
    pattern2 = Roman(symbols="4 3 2 1".split())
    movement1 = Ordered(sources=[pattern1, pattern2])

    pattern3 = Roman(symbols=Repeatedly("1 4 1 4 1 5 1 5".split(), cycles=2))
    pattern4 = Roman(symbols="I IV V I".split())
    movement2 = Ordered(sources=[pattern3, pattern4])

    suite = Ordered(sources=[movement1, movement2], channel=1)

    source.send_to(suite)

    # for this example, we won't do anything crazy with transpositions or anything.

    suite.send_to(output)

    conductor = Conductor(signal=[source], performance=output)
    conductor.start()
コード例 #10
0
def play():

    # Let's show how to play a sequence of one length but omit every Nth note

    output = Performance(bpm=120, stop_seconds=15)

    source = ScaleSource(scales=scale("D minor"))

    melody = Roman(symbols=Endlessly("1 2 3 4 5 6 7".split()), channel=1)
    silence = Permit(when=Endlessly([1, 1, 0]))

    # so we're playing a pattern of 1 2 3 4 5 6 7 of scale degree notes in a giant loop
    # the first time through what really happens is:
    #    1 2 <REST> 4 5 <REST> 7
    # and the second time:
    #    1 <REST> 3 4 <REST> 6 7
    # and the third time:
    #    <REST> 2 3 <REST> 5 6 <REST>
    # all of this is because the pattern and the 'silence' pattern are of unequal lengths

    # this is not ALWAYS relevant in a composition, but if you want to do something
    # polyrhytmic and unorthodox (not just with 'Silence') patterns of  unequal length
    # can be interesting.

    # HOMEWORK: experiment with changing the melody patterns and the silence patterns

    # HOMEWORK: change endlessly to randomly, and see what happens

    source.chain([melody, silence, output])
    conductor = Conductor(signal=[source], performance=output)
    conductor.start()
コード例 #11
0
ファイル: scale.py プロジェクト: music-apps/camp
 def _scale_test(self, expression=None, expected=None, length=None):
     if isinstance(expected, str):
         expected = expected.split()
     assert length is not None
     scale1 = scale(expression)
     results = [note for note in scale1.generate(length=length)]
     print("generating: %s for %s" % (expression, length))
     assert chord(results) == chord(expected)
コード例 #12
0
ファイル: 02_two_scales.py プロジェクト: mpdehaan/camp
def play():

    output = Performance(bpm=120, stop_seconds=10)

    scale1 = scale("c6 major")
    scale2 = scale("c6 minor")

    # the performance will use the c6 major scale for 7 beats, then the c6 minor scale for 7 beats
    source = ScaleSource(scales=[ dict(scale=scale1, beats=7), dict(scale=scale2, beats=7) ])

    # the scale follower will play the first 7 notes in each scale
    follower = ScaleFollower(lengths=[7, 7], channel=1)

    source.chain([follower, output])

    conductor = Conductor(signal=[source], performance=output)
    conductor.start()
コード例 #13
0
ファイル: scale.py プロジェクト: mpdehaan/camp
 def _scale_test(self, expression=None, expected=None, length=None):
     if isinstance(expected, str):
         expected = expected.split()
     assert length is not None
     scale1 = scale(expression)
     results = [note for note in scale1.generate(length=length)]
     print("generating: %s for %s" % (expression, length))
     assert chord(results) == chord(expected)
コード例 #14
0
ファイル: 19_skipover.py プロジェクト: music-apps/camp
def play():

    # Previously, in 11_randomness we introduced the default 'choice' random mode, which just endlessly
    # picks something from a list.

    # in 18_randomness2.py we introduced 'probability', which returns True or False depending on the chances
    # given.  It's used with the "when" statement, shown in both 18_randomness2.py and 19_skipover.py for doing
    # some rather fun things.

    # Some more types of randomness are "exhaust" and "human_random".

    # just to prove this performance will terminate by reaching the END of the performance, we're setting the stop
    # seconds to a crazy long amount of time.  This one won't loop endlessly, because of the way 'exhaust' mode works.
    output = Performance(bpm=120, stop_seconds=9999)

    # exhaust takes a list and feeds it in random order.  It would be the same as shuffle sorting the list, basically, and then
    # popping off the first element repeatedly.  The result is all items will be used, in a random order, and then the sequence
    # will stop.
    #
    # We normally write this in a one liner, but we'll break it up in this example to make things a bit more clear

    scale_choices = [
        scale("Ab blues"),
        scale("C major"),
        scale("Eb mixolydian")
    ]
    scale_chooser = Randomly(scale_choices, mode='exhaust')
    source = ScaleSource(scales=Randomly(scale_choices, mode='exhaust'))

    # human_random is inspired by the Apple iTunes problem.  In a party shuffle mode, people may get suprised to learn
    # that the system played three Van Halen songs in a row.  Apple changed the system to switch between artists more frequently.
    # in CAMP, human random will play each item in a list once, before going back and starting over with a new random selection.

    note_choices = "1 2 3 4 5 6 7".split()
    note_chooser = Randomly(note_choices, mode='human_random')
    melody = Roman(symbols=note_chooser, channel=1)

    # combining these two concepts together, we are going to play 3 random scales in sequence, and then FOR EACH SCALE, play
    # the scale notes in random order.

    source.chain([melody, chordify, transpose, output])
    conductor = Conductor(signal=[source], performance=output)
    conductor.start()
コード例 #15
0
ファイル: scale.py プロジェクト: YixuanFranco/camp
   def test_c_major(self):

       scale1 = scale('C4 major')
       results = []
       for note in scale1.generate(length=10):
           results.append(note)
   
       # using chords here is kind of silly but it's a useful test function
       # naturally you wouldn't play it this way
       assert chord(results) == chord(['C4', 'D4', 'E4', 'F4', 'G4', 'A4', 'B4', 'C5', 'D5', 'E5'])
コード例 #16
0
ファイル: 02_two_scales.py プロジェクト: music-apps/camp
def play():

    output = Performance(bpm=120, stop_seconds=10)

    scale1 = scale("c6 major")
    scale2 = scale("c6 minor")

    # the performance will use the c6 major scale for 7 beats, then the c6 minor scale for 7 beats
    source = ScaleSource(
        scales=[dict(scale=scale1, beats=7),
                dict(scale=scale2, beats=7)])

    # the scale follower will play the first 7 notes in each scale
    follower = ScaleFollower(lengths=[7, 7], channel=1)

    source.chain([follower, output])

    conductor = Conductor(signal=[source], performance=output)
    conductor.start()
コード例 #17
0
ファイル: scale.py プロジェクト: mpdehaan/camp
    def test_c_major(self):

        scale1 = scale("C4 major")
        results = []
        for n in scale1.generate(length=10):
            results.append(n)

        # using chords here is kind of silly but it's a useful test function
        # naturally you wouldn't play it this way
        assert chord(results) == chord(["C4", "D4", "E4", "F4", "G4", "A4", "B4", "C5", "D5", "E5"])
コード例 #18
0
ファイル: scale.py プロジェクト: music-apps/camp
    def test_c_major(self):

        scale1 = scale('C4 major')
        results = []
        for n in scale1.generate(length=10):
            results.append(n)

        # using chords here is kind of silly but it's a useful test function
        # naturally you wouldn't play it this way
        assert chord(results) == chord(
            ['C4', 'D4', 'E4', 'F4', 'G4', 'A4', 'B4', 'C5', 'D5', 'E5'])
コード例 #19
0
ファイル: band.py プロジェクト: mpdehaan/camp
    def test_simple_band(self):

        output = Performance(bpm=120, stop_seconds=10)

        scale1 = scale("c6 major")
        scale2 = scale("c6 minor")

        source = ScaleSource(scales=[ dict(scale=scale1, beats=7), dict(scale=scale2, beats=7) ])

        subdivide = Subdivide(splits=[4])
        roman = Roman(symbols="1 2 3 4 I IV V iii".split(), channel=1)

        follower = ScaleFollower(lengths=[ 7 ])
        chordify = Chordify(types=[ 'power' ])
        shift = Transpose(octaves=[-3], channel=2)

        source.chain([subdivide, roman, output])
        source.chain([follower, chordify, shift, output])

        conductor = Conductor(signal=[source], performance=output)
        conductor.start()
コード例 #20
0
ファイル: notation.py プロジェクト: mpdehaan/camp
    def test_basics(self):

        r = Roman(scale=scale("C4 major"))

        assert r.do("1") == note("C4")
        assert r.do("3") == note("E4")
        assert r.do("4") == note("F4")

        assert r.do("IV") == chord("F4 major")
        assert r.do("iv") == chord("F4 minor")

        # somewhat non-standard notation but allows describing other chord types (see chord.py)
        assert r.do("I:power") == chord(["C4", "G4"])
コード例 #21
0
    def test_basics(self):

        r = Roman(scale=scale("C4 major"))

        assert r.do("1") == note("C4")
        assert r.do("3") == note("E4")
        assert r.do("4") == note("F4")

        assert r.do("IV") == chord("F4 major")
        assert r.do("iv") == chord("F4 minor")

        # somewhat non-standard notation but allows describing other chord types (see chord.py)
        assert r.do("I:power") == chord(["C4", "G4"])
コード例 #22
0
def play():

    # here's an example that might *START* to approximate a song.
    # here we have two instruments playing on two different tracks.

    output = Performance(bpm=60, stop_seconds=10)

    # both instruments will use the same scale at the same time, but there is a scale
    # change as we cycle between scales every 24 beats

    scale1 = scale("c5 major_pentatonic")
    scale2 = scale("e5 mixolydian")
    scale_choices = [
        dict(scale=scale1, beats=24),
        dict(scale=scale2, beats=24)
    ]
    source = ScaleSource(scales=Endlessly(scale_choices))

    # the first instrument plays a series of chords, transposed down an octave
    # from the original scale carrier signal.

    roman1 = Roman(symbols=Endlessly("I IV V IV III:dim ii".split()),
                   channel=1)
    transpose1 = Transpose(octaves=-1)
    source.chain([roman1, transpose1, output])

    # the second instrument plays a series of notes, but is responding to sixteenth
    # notes, not quarter notes, because of the subdivide.

    subdivide2 = Subdivide(splits=4)
    roman2 = Roman(symbols=Endlessly("1 4 3 4 4 3 2 1".split()), channel=2)
    source.chain([subdivide2, roman2, output])

    # homework assignment:
    # change subdivide2 so it's chained BEFORE roman2
    # what happens and why?

    conductor = Conductor(signal=[source], performance=output)
    conductor.start()
コード例 #23
0
ファイル: 19_skipover.py プロジェクト: mpdehaan/camp
def play():

    # Previously, in 11_randomness we introduced the default 'choice' random mode, which just endlessly
    # picks something from a list.

    # in 18_randomness2.py we introduced 'probability', which returns True or False depending on the chances
    # given.  It's used with the "when" statement, shown in both 18_randomness2.py and 19_skipover.py for doing
    # some rather fun things.

    # Some more types of randomness are "exhaust" and "human_random".

    # just to prove this performance will terminate by reaching the END of the performance, we're setting the stop
    # seconds to a crazy long amount of time.  This one won't loop endlessly, because of the way 'exhaust' mode works.
    output = Performance(bpm=120, stop_seconds=9999)

    # exhaust takes a list and feeds it in random order.  It would be the same as shuffle sorting the list, basically, and then
    # popping off the first element repeatedly.  The result is all items will be used, in a random order, and then the sequence
    # will stop.
    #
    # We normally write this in a one liner, but we'll break it up in this example to make things a bit more clear

    scale_choices = [scale("Ab blues"), scale("C major"), scale("Eb mixolydian")]
    scale_chooser = Randomly(scale_choices, mode='exhaust')
    source = ScaleSource(scales=Randomly(scale_choices, mode='exhaust'))

    # human_random is inspired by the Apple iTunes problem.  In a party shuffle mode, people may get suprised to learn
    # that the system played three Van Halen songs in a row.  Apple changed the system to switch between artists more frequently.
    # in CAMP, human random will play each item in a list once, before going back and starting over with a new random selection.

    note_choices = "1 2 3 4 5 6 7".split()
    note_chooser = Randomly(note_choices, mode='human_random')
    melody = Roman(symbols=note_chooser, channel=1)

    # combining these two concepts together, we are going to play 3 random scales in sequence, and then FOR EACH SCALE, play
    # the scale notes in random order.

    source.chain([melody, chordify, transpose, output])
    conductor = Conductor(signal=[source], performance=output)
    conductor.start()
コード例 #24
0
ファイル: band.py プロジェクト: music-apps/camp
    def test_simple_band(self):

        output = Performance(bpm=120, stop_seconds=10)

        scale1 = scale("c6 major")
        scale2 = scale("c6 minor")

        source = ScaleSource(
            scales=[dict(scale=scale1, beats=7),
                    dict(scale=scale2, beats=7)])

        subdivide = Subdivide(splits=[4])
        roman = Roman(symbols="1 2 3 4 I IV V iii".split(), channel=1)

        follower = ScaleFollower(lengths=[7])
        chordify = Chordify(types=['power'])
        shift = Transpose(octaves=[-3], channel=2)

        source.chain([subdivide, roman, output])
        source.chain([follower, chordify, shift, output])

        conductor = Conductor(signal=[source], performance=output)
        conductor.start()
コード例 #25
0
ファイル: 12_fun_chord_arp.py プロジェクト: mpdehaan/camp
def play():

    # here we aren't introducing any new concepts, but we're arranging some
    # concepts a little differently.  This is somewhat of a review, as we're going
    # to start exploring some more (hopefully) musical demos in our examples now.

    # This one sounds just a bit Perrey and Kingsley with the right VST.

    output = Performance(bpm=60, stop_seconds=10)

    # let's play in the A major scale

    scale_choices = Endlessly(
        [
            dict(scale=scale("a4 major"))
        ]
    )

    source = ScaleSource(scales=scale_choices)

    # we're going to alternate between the 1st, 4th, and 5th notes
    # of the scale, but we didn't just jump to chords because of what
    # we are about to do with the arp.

    roman = Roman(symbols=Endlessly("1 4 5".split()), channel=1)

    # and now for a clever use of the arp, to machine gun 4 repititions of
    # each chord, with rests in between.  Subdivide alone couldn't do this.
    # Also notice this is running with NO tranpositions.

    arp = Arp(
        # no transpositions
        semitones=Endlessly([0,0,0,0,0,0,0,0]),
        # every beat gets sliced up 8 times, no exceptions
        splits=Endlessly([8]),
        # try uncommenting this next line:
        #octaves=Endlessly([0,0,1,0,2,0,3,0]),
        # play every other note on the arp
        # TODO: IDEA: seems like we should also allow arp velocity!
        rests=Endlessly([0,1,0,1,0,1,0,1])
    )

    # now the output here is just machine gunned notes.  Turn it into major chords.

    chordify = Chordify(types=Endlessly(['major']))

    source.chain([roman, arp, chordify, output])

    conductor = Conductor(signal=[source], performance=output)
    conductor.start()
コード例 #26
0
def play():

    # this is sort of a variation of example 08.  Except now, rather than
    # playing two different patterns that might clash, we're selecting chord
    # patterns for instrument 2 to harmonize with what instrument 1 is playing.

    output = Performance(bpm=120, stop_seconds=10)

    # both instruments will use the same scale at the same time, but there is a scale
    # change as we cycle between scales every 24 beats

    scale1 = scale("c5 major_pentatonic")
    scale2 = scale("e5 mixolydian")
    scale_choices = [ dict(scale=scale1, beats=24), dict(scale=scale2, beats=24) ]
    source = ScaleSource(scales=Endlessly(scale_choices))

    # the first instrument plays a series of notes

    roman1 = Roman(symbols=Endlessly("1 2 4 1 2 3 1 2 4 3 3".split()), channel=1)
    source.chain([roman1, output])

    # the second instrument transposes that note down two octaves and plays a power
    # chord.  We could pass in an array of chords to vary the chord type, but this is
    # probably going to sound less prone to clashing.

    chordify = Chordify(types=Endlessly(["power"]), channel=2)
    transpose = Transpose(octaves=Endlessly([-2]))
    source.chain([roman1, chordify, transpose, output])

    # note that roman 1 is part of each chain, but the channel number is overridden
    # in the second set.  This can be done because the event objects are copied as they
    # are passed between each layer.  Technically the channel can be overriden at any
    # time.  Ideas for future chaos, perhaps?

    conductor = Conductor(signal=[source], performance=output)
    conductor.start()
コード例 #27
0
ファイル: 23_duration.py プロジェクト: music-apps/camp
def play():

    # examples/06_subdivide showed how to chop up the incoming quarter note signal
    # to create faster signals.  However, sometimes in a given bar we want a mix of note durations.
    # how do we do that?

    # For this example, lets play whole note chords underneath a quarter note melody.

    # implementation caveat:
    # Because the "beat" signal from the conductor comes in every quarter note, we have to take
    # care and rest in the right places of the input signal to avoid funness.  This may get easier
    # later.

    # this is pretty close to what we did in 09_harmony.py

    output = Performance(bpm=120, stop_seconds=15)

    # this performance will actually complete so stop_seconds is mostly ignorable.

    scale_choices = Endlessly([scale("D major")])
    source = ScaleSource(scales=scale_choices)

    # the underlying chords - note the rests
    chords = Roman(symbols=Endlessly(
        "I - - - I - - - IV - - - V - - - ".split()),
                   channel=1)
    # every beat is a quarter note, but on the first beat in a cycle of 4
    # play a WHOLE note
    chords_len = Duration(lengths=Endlessly([1, 0, 0, 0]))
    source.chain([chords, chords_len, output])

    # the melody
    # TODO: Roman should figure out if input is a string here and auto-split.
    pattern2 = Roman("1 2 3 1 2 2 1 3 3 1 3 2".split(), channel=2)
    pattern3 = Roman("1 3 3 1 4 4 1 3 3 1 5 -".split(), channel=2)
    pattern4 = Roman("1 5 5 1 4 4 1 3 3 1 2 2".split(), channel=2)
    pattern5 = Roman("1 2 4 6 4 2 1 6 4 2 1 -".split(), channel=2)
    melody_sequence = [pattern2, pattern3, pattern4, pattern5]
    melody = Ordered(sources=Endlessly(melody_sequence))
    # we could just do: source.chain(source, ordered) here
    # but it would mean later we would have less flexibility
    # to make the patterns feel different.
    source.chain([melody])
    for pattern in melody_sequence:
        source.chain([pattern, output])

    conductor = Conductor(signal=[source], performance=output)
    conductor.start()
コード例 #28
0
ファイル: 01_minimal.py プロジェクト: music-apps/camp
def play():

    output = Performance(bpm=120, stop_seconds=10)

    # specify that we are going to be playing the c6 major scale for a very long
    # time
    scale1 = scale("c6 major")
    source = ScaleSource(scales=[ dict(scale=scale1, beats=9999) ])

    # but just play the first 7 notes in the scale
    follower = ScaleFollower(lengths=[ 7 ], channel=1)
    source.chain([follower, output])

    # begin performance
    conductor = Conductor(signal=[source], performance=output)
    conductor.start()
コード例 #29
0
ファイル: 23_duration.py プロジェクト: mpdehaan/camp
def play():

    # examples/06_subdivide showed how to chop up the incoming quarter note signal
    # to create faster signals.  However, sometimes in a given bar we want a mix of note durations.
    # how do we do that?

    # For this example, lets play whole note chords underneath a quarter note melody.

    # implementation caveat:
    # Because the "beat" signal from the conductor comes in every quarter note, we have to take
    # care and rest in the right places of the input signal to avoid funness.  This may get easier
    # later.

    # this is pretty close to what we did in 09_harmony.py


    output = Performance(bpm=120, stop_seconds=15)

    # this performance will actually complete so stop_seconds is mostly ignorable.

    scale_choices = Endlessly([scale("D major")])
    source = ScaleSource(scales=scale_choices)

    # the underlying chords - note the rests
    chords     = Roman(symbols=Endlessly("I - - - I - - - IV - - - V - - - ".split()), channel=1)
    # every beat is a quarter note, but on the first beat in a cycle of 4
    # play a WHOLE note
    chords_len = Duration(lengths=Endlessly([1,0,0,0]))
    source.chain([chords, chords_len, output])

    # the melody
    # TODO: Roman should figure out if input is a string here and auto-split.
    pattern2 = Roman("1 2 3 1 2 2 1 3 3 1 3 2".split(), channel=2)
    pattern3 = Roman("1 3 3 1 4 4 1 3 3 1 5 -".split(), channel=2)
    pattern4 = Roman("1 5 5 1 4 4 1 3 3 1 2 2".split(), channel=2)
    pattern5 = Roman("1 2 4 6 4 2 1 6 4 2 1 -".split(), channel=2)
    melody_sequence = [ pattern2, pattern3, pattern4, pattern5 ]
    melody = Ordered(sources=Endlessly(melody_sequence))
    # we could just do: source.chain(source, ordered) here
    # but it would mean later we would have less flexibility
    # to make the patterns feel different.
    source.chain([melody])
    for pattern in melody_sequence:
        source.chain([ pattern, output])

    conductor = Conductor(signal=[source], performance=output)
    conductor.start()
コード例 #30
0
ファイル: 05_chordify.py プロジェクト: mpdehaan/camp
def play():

    # playing all the power chords in a chromatic scale.

    output = Performance(bpm=120, stop_seconds=10)

    # play the two scales for 7 beats each, and then keep using those scales
    scale1 = scale("c4 chromatic")
    scale_choices = dict(scale=scale1, beats=12)
    source = ScaleSource(scales=scale_choices)

    follower = ScaleFollower(lengths=12)
    chordify = Chordify(types="power", channel=1)
    source.chain([follower, chordify, output])

    conductor = Conductor(signal=[source], performance=output)
    conductor.start()
コード例 #31
0
ファイル: 05_chordify.py プロジェクト: music-apps/camp
def play():

    # playing all the power chords in a chromatic scale.

    output = Performance(bpm=120, stop_seconds=10)

    # play the two scales for 7 beats each, and then keep using those scales
    scale1 = scale("c4 chromatic")
    scale_choices = dict(scale=scale1, beats=12)
    source = ScaleSource(scales=scale_choices)

    follower = ScaleFollower(lengths=12)
    chordify = Chordify(types="power", channel=1)
    source.chain([follower, chordify, output])

    conductor = Conductor(signal=[source], performance=output)
    conductor.start()
コード例 #32
0
def play():

    # here we aren't introducing any new concepts, but we're arranging some
    # concepts a little differently.  This is somewhat of a review, as we're going
    # to start exploring some more (hopefully) musical demos in our examples now.

    # This one sounds just a bit Perrey and Kingsley with the right VST.

    output = Performance(bpm=60, stop_seconds=10)

    # let's play in the A major scale

    scale_choices = Endlessly([dict(scale=scale("a4 major"))])

    source = ScaleSource(scales=scale_choices)

    # we're going to alternate between the 1st, 4th, and 5th notes
    # of the scale, but we didn't just jump to chords because of what
    # we are about to do with the arp.

    roman = Roman(symbols=Endlessly("1 4 5".split()), channel=1)

    # and now for a clever use of the arp, to machine gun 4 repititions of
    # each chord, with rests in between.  Subdivide alone couldn't do this.
    # Also notice this is running with NO tranpositions.

    arp = Arp(
        # no transpositions
        semitones=Endlessly([0, 0, 0, 0, 0, 0, 0, 0]),
        # every beat gets sliced up 8 times, no exceptions
        splits=Endlessly([8]),
        # try uncommenting this next line:
        #octaves=Endlessly([0,0,1,0,2,0,3,0]),
        # play every other note on the arp
        # TODO: IDEA: seems like we should also allow arp velocity!
        rests=Endlessly([0, 1, 0, 1, 0, 1, 0, 1]))

    # now the output here is just machine gunned notes.  Turn it into major chords.

    chordify = Chordify(types=Endlessly(['major']))

    source.chain([roman, arp, chordify, output])

    conductor = Conductor(signal=[source], performance=output)
    conductor.start()
コード例 #33
0
ファイル: 14_movements.py プロジェクト: music-apps/camp
def play():

    # in example 13 we showed the use of Ordered to trigger
    # one pattern after another.  As programs grow, it might be nice
    # to group them conceptually in a larger composition.

    # This is a demo that shows how Ordered can nest to not work only
    # with basic patterns, but also larger movements.

    # The idea is this: Generators stack!

    # Like before, we're setting stop seconds to 100 seconds but this composition
    # will complete due to the sources being exhausted first, which is the point.

    output = Performance(bpm=240, stop_seconds=100)

    for scale_name in ["C major", "D minor"]:

        scale_choices = Endlessly([scale(scale_name)])
        source = ScaleSource(scales=scale_choices)

        pattern1 = Roman(symbols="1 2 3 4 5 6 7".split())
        pattern2 = Roman(symbols="i ii iii iv v v vii".split())
        movement1 = Ordered(sources=[pattern1, pattern2])

        pattern3 = Roman(symbols="7 6 5 4 3 2 1".split())
        pattern4 = Roman(symbols="vii vi v iv iii ii i".split())
        movement2 = Ordered(sources=[pattern3, pattern4])
        movement2_transposer = Transpose(octaves=Endlessly([-2]))
        movement2.send_to(movement2_transposer)

        suite = Ordered(sources=[movement1, movement2], channel=1)

        source.send_to(suite)
        output.listens_to([movement1, movement2_transposer])

        # BONUS TIP: we technically don't have to have just one conductor invocation, if it
        # keeps it simple.

        conductor = Conductor(signal=[source], performance=output)
        conductor.start()
コード例 #34
0
ファイル: 18_randomness2.py プロジェクト: mpdehaan/camp
def play():

    # in example 11 we showed off some random functionality
    # in example 17 we showed how to silence notes based on that
    # knowledge of 'random'.

    # here is a probabilistic way to use random, that combines the concepts.

    output = Performance(bpm=120, stop_seconds=15)

    source = ScaleSource(scales=scale("Ab blues"))

    melody = Roman(symbols=Endlessly("1 2 3 4 5 6 7".split()), channel=1)
    silence = Permit(when=Randomly([1, 0.5], mode='probability'))

    # so we're playing a scale pattern, but every other note has a 50% chance
    # of not being played.

    source.chain([melody, silence, output])
    conductor = Conductor(signal=[source], performance=output)
    conductor.start()
コード例 #35
0
def play():

    # in example 11 we showed off some random functionality
    # in example 17 we showed how to silence notes based on that
    # knowledge of 'random'.

    # here is a probabilistic way to use random, that combines the concepts.

    output = Performance(bpm=120, stop_seconds=15)

    source = ScaleSource(scales=scale("Ab blues"))

    melody = Roman(symbols=Endlessly("1 2 3 4 5 6 7".split()), channel=1)
    silence = Permit(when=Randomly([1, 0.5], mode='probability'))

    # so we're playing a scale pattern, but every other note has a 50% chance
    # of not being played.

    source.chain([melody, silence, output])
    conductor = Conductor(signal=[source], performance=output)
    conductor.start()
コード例 #36
0
ファイル: 06_subdivide.py プロジェクト: mpdehaan/camp
def play():

    # example 05 was "playing all the power chords in a chromatic scale".
    # let's modify the example very slightly using Subdivide.
    # normally the conductor sends down quarter notes.  Let's alternate
    # playing quarter notes and sixteenth notes.

    output = Performance(bpm=120, stop_seconds=10)

    # play the two scales for 7 beats each, and then keep using those scales
    source = ScaleSource(scales=scale("c4 chromatic"))

    follower = ScaleFollower(lengths=12)

    # pay attention to this part - nothing else has changed
    subdivide = Subdivide(splits=Endlessly([1,4]))

    chordify = Chordify(types="power", channel=1)
    source.chain([follower, subdivide, chordify, output])

    conductor = Conductor(signal=[source], performance=output)
    conductor.start()
コード例 #37
0
def play():

    # example 05 was "playing all the power chords in a chromatic scale".
    # let's modify the example very slightly using Subdivide.
    # normally the conductor sends down quarter notes.  Let's alternate
    # playing quarter notes and sixteenth notes.

    output = Performance(bpm=120, stop_seconds=10)

    # play the two scales for 7 beats each, and then keep using those scales
    source = ScaleSource(scales=scale("c4 chromatic"))

    follower = ScaleFollower(lengths=12)

    # pay attention to this part - nothing else has changed
    subdivide = Subdivide(splits=Endlessly([1, 4]))

    chordify = Chordify(types="power", channel=1)
    source.chain([follower, subdivide, chordify, output])

    conductor = Conductor(signal=[source], performance=output)
    conductor.start()
コード例 #38
0
def play():

    # example 05 was "playing all the power chords in a chromatic scale".
    # example 06 used subdivide to chop up alternating measures with faster notes
    # now lets alternately transpose every 2nd measure up an octave
    # and every 3rd measure down an octave

    output = Performance(bpm=120, stop_seconds=10)

    source = ScaleSource(scales=scale("c4 chromatic"))

    follower = ScaleFollower(lengths=Endlessly([12]))

    subdivide = Subdivide(splits=Endlessly([1,4]))

    # pay attention to this part - nothing else has changed
    transpose = Transpose(octaves=Endlessly([0,1,-1]))

    chordify = Chordify(types="power", channel=1)
    source.chain([follower, subdivide, transpose, chordify, output])

    conductor = Conductor(signal=[source], performance=output)
    conductor.start()
コード例 #39
0
def play():

    # we've focussed a lot on randomness now.  So far, we've shown how to pick random values
    # for notes and how to conditionally do something or not with "when=".

    # What's interesting though is that, due to the way some effects plugins work, we can choose
    # to intermix effects.  Here, we show that there are really two patterns going on, but only one
    # is going to win and actually get to play a note.

    # we're relying one 'musician' object stomping on another, but only sometimes.

    output = Performance(bpm=120, stop_seconds=15)

    source = ScaleSource(scales=scale("Ab blues"))

    pattern1 = Endlessly("1 2 3 4 5 6 7".split())
    pattern2 = Randomly(
        "VII:power VI:power V:power IV:power III:power II:power I:power".split(
        ))
    cut_over = Randomly([0, 0, 0, 1, 1, 1], mode='probability')

    melody1 = Roman(symbols=pattern1, channel=1)
    melody2 = Roman(symbols=pattern2, channel=2, when=cut_over)
    transpose = Transpose(octaves=Endlessly([-2, -1, 0, 1, 2]))

    # there is no sane reason to want to do this, but what happens is that for the first three notes we are guaranteed
    # to play pattern1.  Then three notes of pattern 2.  The last note is acutally a toss up between pattern1 and pattern2.
    # since they live in the same chain, pattern1 is going to overwrite pattern2 even though they are expressed in a chain.
    # we can also even choose to overwrite the MIDI channel, which we do, all while sharing a transposition cycle.

    # again, this isn't realistic for most compositions, we'd likely just set up a bunch of patterns with RESTS, but
    # I wanted to show all the possibilities before leaving the theme of randomness for a while.  Hopefully the
    # idea of "when=" is now drummed in.

    source.chain([melody1, melody2, transpose, output])
    conductor = Conductor(signal=[source], performance=output)
    conductor.start()
コード例 #40
0
ファイル: 20_randomness3.py プロジェクト: music-apps/camp
def play():

    # Permit, introduced in the example 18_randomness2.py allows us to
    # silence an entire chain when certain conditions are met.

    # However, sometimes, we may want to decide to apply an affect only
    # when something is true.  Because this could be useful ANYWHERE
    # the same type of "when" logic can actually be attached to ANYTHING.

    # here is a probabilistic way to use random, that combines the concepts.

    output = Performance(bpm=120, stop_seconds=15)

    source = ScaleSource(scales=scale("Ab blues"))

    melody = Roman(symbols=Endlessly("1 2 3 4 5 6 7".split()), channel=1)
    chordify = Chordify(types=Endlessly(['major', 'minor']),
                        when=Randomly([0, 0.45], mode='probability'))
    transpose = Transpose(octaves=Endlessly([2, -2]),
                          when=Randomly([0, 0, 0.75], mode='probability'))

    # the result is every other note has a 40% chance of becoming a chord,  which is always alternating
    # major and minor when it happens

    # every THIRD note has a 75 percent chance of being transposed, which will be alternating +2/-2 octaves
    # when it happens

    # so now, we have easily inserted CONDITIONAL effects.  The use of when=Randomly wasn't required.
    # we could also have used Endlessly or Repeatedly.  Though keep in mind if using Repeatedly, when
    # the event chain is exhausted, that particular part of the performance will stop.  And when everything stops,
    # the performance is done.  Because this is likely being applied to an effect chain, Repeatedly probably
    # doesn't make the most sense with "when".  But Endlessly?  Sure!

    source.chain([melody, chordify, transpose, output])
    conductor = Conductor(signal=[source], performance=output)
    conductor.start()
コード例 #41
0
ファイル: 16_drumkits.py プロジェクト: mpdehaan/camp
def play():

    # in example 15 we show how to drift between different patterns.

    # so far, we've mostly been showing patterns inside a scale, because
    # that sounds good for melodic instruments.  Not everything lives
    # inside a scale though - accidentals etc.  Transpose and the arp
    # can move by semitones to overcome that.

    # however, when dealing with drum kits, the scale is pretty much never
    # relevant

    # Usually these things trigger with something like C3 for a kick drum, D4
    # for a Tom, and so on -- but it varies by drumkit.

    # Having a transpose or scale change in there would
    # mess it all up.

    # Here's an example of switching through some drum patterns, and it also
    # fires multiple types of drum hits on a single channel.

    # when setting this example up, put any synth you want on MIDI channel 2,
    # but on MIDI channel 1 put some kind of drumkit.  You may need to change
    # the MIDI note names to make it sound right

    K = "F4"
    H = "A4"
    C = "Bb4"

    output = Performance(bpm=120, stop_seconds=15)

    melody_trigger = ScaleSource(scales=scale("D minor"))
    melody = Roman(symbols=Endlessly("1 - - - - 2 - - - -".split()), channel=1)

    drum_trigger = Subdivide(splits=4, channel=2) # gimme 16th notes for the drum tracks

    # kick drum on the quarter notes
    kicks = Literal(symbols=Endlessly([K, None, None, None,
                                       K, None, None, None,
                                       K, None, None, None,
                                       K, None, None, None]))

    # hihat on the 8th notes every other bar
    # but wait one bar before starting that up.
    hihat = Ordered(
        sources = Endlessly([
            Literal(symbols="- - - - - - - - - - - - - - - -".split()),
            Literal(symbols=Endlessly([
                H, None, H, None, H, None, H, None,
                H, None, H, None, H, None, H, None
            ]))
        ])
    )

    # cymbals on the half notes
    cymbals = Literal(symbols=Endlessly([
            C, None, None, None, None, None, None,
            C, None, None, None, None, None, None
        ]))


    melody_trigger.send_to(melody)
    drum_trigger.send_to([kicks, hihat, cymbals])
    output.listens_to([melody, kicks, hihat, cymbals])


    conductor = Conductor(signal=[melody_trigger, drum_trigger], performance=output)
    conductor.start()
コード例 #42
0
ファイル: scale.py プロジェクト: YixuanFranco/camp
   def test_basics(self):

       scale1 = Scale(root=note('C4'), typ='major')
       scale2 = scale('C4 major')
       assert scale1 == scale2
       assert str(scale1) == 'Scale<C4 major>'
コード例 #43
0
ファイル: scale.py プロジェクト: music-apps/camp
    def test_basics(self):

        scale1 = Scale(root=note('C4'), typ='major')
        scale2 = scale('C4 major')
        assert scale1 == scale2
        assert str(scale1) == 'Scale<C4 major>'
コード例 #44
0
def play():

    # so far what we've done has been mostly theoretical.
    # to construct larger songs, obviously, one thing has to occur
    # after another.  To do this, we could just pass in GIGANTIC
    # arrays to everything but that would suck!

    # now, everything in CAMP is built off the idea of generators.
    # this means the system can pretty well know if one thing is done
    # playing and more on to the next.

    # while we could just pass in huge note arrays, that kind of sucks.
    # What if we want a flute to play
    # it's part and then have the trombone come in?  To do that,
    # we need a facility for ordering - to say "this comes next"

    # NOTE: we're setting stop seconds to 100 seconds but this composition
    # will complete due to the sources being exhausted first, which is the point.
    # we're not writing an endlessly generative piece here, but moving towards
    # more explicit songwriting tools.  The point of this example is to show
    # we are writing a finite song in PIECES.

    output = Performance(bpm=240, stop_seconds=100)
    scale_choices = Endlessly([scale("a3 major")])

    source = ScaleSource(scales=scale_choices)

    pattern1 = Roman(symbols="1 2 3 4".split())
    pattern2 = Roman(symbols="I I I I".split())
    pattern2_transpose = Transpose(octaves=Endlessly([2]))
    pattern2.send_to(pattern2_transpose)

    # in this example, we're going to play pattern1 until it is exhausted
    # then pattern2, and when that's done, we're done.

    ordered = Ordered(sources=[pattern1, pattern2], channel=1)

    # HOMEWORK ASSIGNMENT:
    # uncomment this line to randomly pick a pattern and play it until
    # it is exhausted, but keep doing that endlessly.  Patterns might
    # repeat, see notes about advanced usages of Randomly in examples/11_randomness.py
    #
    # ordered = Ordered(sources=Randomly([pattern1,pattern2]), channel=1)

    # HOMEWORK ASSIGNMENT:
    #
    # uncomment this next line to play pattern1, pattern2 in an endless sequence
    # ordered = Ordered(Endlessly([pattern1,pattern2]))

    # TODO: IDEA: it might be nice to have a "beats" flag on ordered where it can stop
    # producing after a certain number of beats
    # ordered = Ordered(Randomly([pattern1,pattern2,pattern3]), beats=24)
    # this would allow for patterns of patterns, and better nesting.

    # TODO: IDEA: anything that can take a "beats" should really take a bars=, it's just easier
    # to think about

    # HOMEWORK: using a pattern in Ordered that uses Endlessly will cause the pattern to NOT switch.
    # Try this out and understand why pattern 2 will never play.
    # pattern1 = Roman(symbols=Endlessly("3 6 3 6 5 1 2".split()))
    # ordered = Ordered([pattern1,pattern2,pattern3])

    # TODO: IDEA, make the above homework example actually work, with something like:
    # pattern1 = Roman(symbols=Endlessly("3 6 3 6 5 1 2".split()))
    # ordered = Ordered([ dict(pattern=pattern1, beats=8), dict(pattern=pattern2, beats=8) ])

    # NOTE: in simple cases we could connect ordered to the output, but we'd miss the transposition,
    # and I wanted to show off a more complete example.  This also underscores the idea that source.chain
    # is just syntactic sugar and you don't have to use it.

    source.send_to(ordered)
    pattern1.send_to(output)
    pattern2_transpose.send_to(output)

    conductor = Conductor(signal=[source], performance=output)
    conductor.start()
コード例 #45
0
ファイル: scale.py プロジェクト: mpdehaan/camp
    def test_basics(self):

        scale1 = Scale(root=note("C4"), typ="major")
        scale2 = scale("C4 major")
        assert scale1 == scale2
        assert str(scale1) == "Scale<C4 major>"
コード例 #46
0
ファイル: opus.py プロジェクト: YixuanFranco/camp
    def test_basic_api_usage(self):

        # this test is mostly documentation and coverage and is going to be
        # relatively free of assertions, because of the nature of the work

        # the opus is the framework for a composition.  It has a Python object
        # model which is also the basic API.  At a high level:
        # a song has tracks
        # a song has scenes
        # each scene chooses a pattern for each track
        # a scene might override the scale or BPM
        # each pattern has bars (which might repeat)
        # bars can be described in multiple types of systems
        # a pattern might override the scale (but can't override the BPM)
        # scenes might be manually advanced by a human, or they might not.

        # values set at the song level are essentially global defaults
        song = Song(name="Random Notes", scale=scale('c4 major'), pattern_length=16, bars=4, bpm=120)

        # tracks get mapped to MIDI channels but they also have printable names
        track1 = song.add_track(Track(name="melodica", midi_channel=1))
        track2 = song.add_track(Track(name="trombone", midi_channel=2))
        track3 = song.add_track(Track(name="TR808", midi_channel=2))

        # a pattern has a name, a notation system, and can optionally override a scale
        llama_pattern = Pattern(name="llama-theme", notation='roman', scale=scale('c4 minor'),
            bars = [
               Bar(cells="1 2 3 I II III IV i ii iii iv - 3 2 1".split()),
            ]
        )
        # here the pattern plays the first bar 3 times then the next bar 1 time
        sheep_pattern = Pattern(name="sheep-theme", notation='roman',
            bars = [
                Bar(cells="4 6 4 6 4 4 4 4 6 6 4 1 1 - - - -".split(), repeats=3),
                Bar(cells="4 6 4 6 4 4 4 4 6 4 6 1 . . . . .".split(), repeats=1)
            ]
        )
        # for drums, scales are pretty bogus, so just input the raw notes (or chords, etc)
        kick_pattern = Pattern(name="kicks", notation='literal',
            bars = [
                Bar(cells="C4 - - -".split(), stop=4)
            ]
        )

        # the song has a list of scenes, which might repeat
        scene1 = song.add_scene(Scene(name="scene1", track_mapping=dict(
            track1 = llama_pattern,
            track2 = sheep_pattern,
            track3 = kick_pattern
        )))

        # scenes can also override many of the global settings
        scene2 = song.add_scene(Scene(name="scene2", scale=scale('c5 minor'), bpm=140, bars=6, track_mapping=dict(
            track1 = llama_pattern,
            track2 = sheep_pattern,
            track3 = None
        )))

        # PSEUDOCODE SKETCH: TODO: real-time AND rendering will probably look like:
        # while True
        #     sleep(SMALL_NUMBER) # unless rendering
        #     events = song.advance_time(SMALL_NUMBER)
        #     for x in events
        #        send or print event
        # ??? - to be determined

        realtime = Realtime(song)
        #realtime.playback_test()

        realtime.play_song(callback=print_event)

        raise Exception("STOP")
コード例 #47
0
ファイル: 11_randomness.py プロジェクト: mpdehaan/camp
def play():

    # in example 10 we showed you how powerful the arpeggiator can get.
    # well, that's great for some degrees of chaos, but what if we want
    # to let the computer make MORE decisions?

    output = Performance(bpm=120, stop_seconds=10)

    # randomness is one way to do that.

    # in example 03 we showed how to use Endlessly to loop over a set of input.
    # that used SELECTORS, but Endlessly is just a LINEAR selector that loops
    # when it gets to the end of the input.

    # randomness can also be accessed, using the Randomly selector, which
    # chooses an item from a list.
    # each choice is then repeated for a given number of times.
    # here lets pick some random scales, but whatever we pick, hold that choice
    # for 7 beats, which we covered in example 01.

    random_scale_choices = Randomly([
        # each of these items are scale specifications.  You've seen these in the very first examples.
        dict(scale=scale("c6 major"), beats=7),
        dict(scale=scale("Db4 minor_pentatonic"), beats=7),
        dict(scale=scale("Eb3 mixolydian"), beats=7)
    ])

    # note that the random selector could repeat a selection as currently
    # implemented and/or specified.  See ideas below.

    # note if we want a random choice to be made EVERY beat we can simplify
    # our usage of randomly like so:

    random_note_choices = Randomly("1 2 3 4 5 6 7".split())

    # what does that do?  It randomly plays one of 7 notes in the current scale.
    # that's syntactically clean, but super basic.  Let's override that with something
    # showing more options available to Randomly.

    # we're playing CHORDS now, and if we choose the "I" chord we are going to play
    # it twice in the current scale (which might change after we play the first, so this is
    # a minor lie). All within the current scale, of course.

    random_note_choices = Randomly([
        dict(value="I", hold=2),
        dict(value="IV", hold=1),
        dict(value="V", hold=1),
        dict(value="i", hold=1),
        dict(value="ii", hold=1),
        dict(value="iv:dim7", hold=1),
    ])

    # HOMEWORK: add some more scales to the random_scale_choices above and take out some
    # notes from random_note_choices.  Mix scales with notes!

    # FUTURE IDEA: also support a notion of frequency controlling what will be drawn.
    # frequencies should add up to 1.  This would still be compatible with "hold" above.

    #random_note_choices = Randomly([
    #    dict(value="I", frequency=0.4),
    #    dict(value="IV", frequency=0.2),
    #    dict(value="V", frequency=0.2),
    #    dict(value="i", frequency=0.1),
    #    dict(value="ii", frequency=0.05),
    #    dict(value="iv:dim7", frequency=0.05),
    #])

    # for more examples, see the demos labelled randomness2.py, randomness3.py, etc.
    # we want to cover some other things first, so I'm not going to go completelyinto
    # randomness now.

    source = ScaleSource(scales=random_scale_choices)
    roman = Roman(symbols=random_note_choices, channel=1)
    source.chain([roman, output])

    conductor = Conductor(signal=[source], performance=output)
    conductor.start()
コード例 #48
0
ファイル: 10_arpeggiator.py プロジェクト: mpdehaan/camp
def play():

    # previous examples showed a couple of instruments, lets go back to one
    # instrument to showcase just the arpeggiator.

    # WARNING - may not make sense if you haven't used any hardware or
    # software arpeggiators.

    output = Performance(bpm=120, stop_seconds=10)

    scale1 = scale("c4 major")
    scale_choices = [ dict(scale=scale1, beats=7) ]

    # refresher - CAMP is generator based, and performances stop when there is
    # nothing left to do OR stop_seconds is reached.
    # by not wrapping the scale choices in "Endlessly", we're allowing this example
    # to terminate when the scale is done.  This example will play 24 quarter note
    # beats and STOP.  But the way the arpeggiator is coded, there will really be
    # 24*4 = 96 sixteenth notes, of which 3/4s of them will be played with audible notes
    # and the rests will be, ahem, rests.

    # refresher - the MIDI channel number can be set anywhere in the graph, as well as overrided
    # anywhere in the graph.  Leaving it off here on ScaleSource and setting it on the
    # Arp would do exactly the same thing.  Leaving off the channel will cause an exception.

    source = ScaleSource(scales=(scale_choices), channel=1)

    # refresher - the scale follower will take note of the current scale and
    # play the scale for a given number of notes in order.  We could be more
    # creative by using Roman() instead to select particular notes (or chords)
    # in the scale.

    follower = ScaleFollower(lengths=Endlessly([7]))

    # refresher, the roman usage looks very similar:
    # roman = Roman(symbols="1 2 3 4 5 6 7".split())
    # really, there's little use for ScaleFollower in the real world, but it was
    # getting lonely and wanted to be featured here.  It's a bit more efficient
    # but I doubt that matters.

    # NOW FOR THE FUN PART.

    # ok, here's the arpeggiator.

    # in this example, we take the currently selected note from the scale
    # play that note, then the notes 4 and 9 semitones up - a major chord.
    # every single beat will be divided into 4 parts by the arp due to 'splits'
    # however every 4th note is also a REST.
    #
    # see this table:
    #
    # TRIGGER: | C4 ~~~~~~~~~~~~ | D4 ~~~~~~~~~ | ...
    # ---------+-----------------+--------------+
    # RESTS:   | N   N   N  Y    | N   N   N  Y |
    # SEMI:    | +0  +3  +8  -   | +0  +3  +8   |
    # OCTAVES: | +2  -2  0   0   | +2  -2  0  0 |
    # ---------+-----------------+--------------+
    # PLAY:    | C6  E2  G4  -   | D6  Gb2 A4 - |
    #
    # more creative things can be done by having the semitones
    # and rest patterns be different lengths, and so on, as well as using
    # the 'free' mode with those uneven lengths.

    arp = Arp(
        semitones=Endlessly([0,3,8,0]),
        octaves=Endlessly([2,-2,0,0]),
        splits=Endlessly([4]),
        rests=Endlessly([0,0,0,1])
    )

    # HOMEWORK: add "mode=free" to the Arp constructor above and experiment
    # with octaves, splits, rests, and semitones of different values and array
    # lengths.

    # POP QUIZ:  what happens if we remove Endlessly from some of the expressions above?
    # WHY?

    # the chain here is simple - scale source feeds note source, which in turn
    # feeds the arp.

    source.chain([follower, arp, output])

    # kick out the jams

    conductor = Conductor(signal=[source], performance=output)
    conductor.start()
コード例 #49
0
ファイル: roman.py プロジェクト: music-apps/camp
def roman(scale_pattern):
    """
    Quickly generate a Roman numeral interpreter.
    Ex: r = roman("C4 major")
    """
    return Roman(scale=scale(scale_pattern))
コード例 #50
0
def play():

    # in example 15 we show how to drift between different patterns.

    # so far, we've mostly been showing patterns inside a scale, because
    # that sounds good for melodic instruments.  Not everything lives
    # inside a scale though - accidentals etc.  Transpose and the arp
    # can move by semitones to overcome that.

    # however, when dealing with drum kits, the scale is pretty much never
    # relevant

    # Usually these things trigger with something like C3 for a kick drum, D4
    # for a Tom, and so on -- but it varies by drumkit.

    # Having a transpose or scale change in there would
    # mess it all up.

    # Here's an example of switching through some drum patterns, and it also
    # fires multiple types of drum hits on a single channel.

    # when setting this example up, put any synth you want on MIDI channel 2,
    # but on MIDI channel 1 put some kind of drumkit.  You may need to change
    # the MIDI note names to make it sound right

    K = "F4"
    H = "A4"
    C = "Bb4"

    output = Performance(bpm=120, stop_seconds=15)

    melody_trigger = ScaleSource(scales=scale("D minor"))
    melody = Roman(symbols=Endlessly("1 - - - - 2 - - - -".split()), channel=1)

    drum_trigger = Subdivide(splits=4,
                             channel=2)  # gimme 16th notes for the drum tracks

    # kick drum on the quarter notes
    kicks = Literal(symbols=Endlessly([
        K, None, None, None, K, None, None, None, K, None, None, None, K, None,
        None, None
    ]))

    # hihat on the 8th notes every other bar
    # but wait one bar before starting that up.
    hihat = Ordered(sources=Endlessly([
        Literal(symbols="- - - - - - - - - - - - - - - -".split()),
        Literal(symbols=Endlessly([
            H, None, H, None, H, None, H, None, H, None, H, None, H, None, H,
            None
        ]))
    ]))

    # cymbals on the half notes
    cymbals = Literal(symbols=Endlessly([
        C, None, None, None, None, None, None, C, None, None, None, None, None,
        None
    ]))

    melody_trigger.send_to(melody)
    drum_trigger.send_to([kicks, hihat, cymbals])
    output.listens_to([melody, kicks, hihat, cymbals])

    conductor = Conductor(signal=[melody_trigger, drum_trigger],
                          performance=output)
    conductor.start()
コード例 #51
0
def play():

    # previous examples showed a couple of instruments, lets go back to one
    # instrument to showcase just the arpeggiator.

    # WARNING - may not make sense if you haven't used any hardware or
    # software arpeggiators.

    output = Performance(bpm=120, stop_seconds=10)

    scale1 = scale("c4 major")
    scale_choices = [dict(scale=scale1, beats=7)]

    # refresher - CAMP is generator based, and performances stop when there is
    # nothing left to do OR stop_seconds is reached.
    # by not wrapping the scale choices in "Endlessly", we're allowing this example
    # to terminate when the scale is done.  This example will play 24 quarter note
    # beats and STOP.  But the way the arpeggiator is coded, there will really be
    # 24*4 = 96 sixteenth notes, of which 3/4s of them will be played with audible notes
    # and the rests will be, ahem, rests.

    # refresher - the MIDI channel number can be set anywhere in the graph, as well as overrided
    # anywhere in the graph.  Leaving it off here on ScaleSource and setting it on the
    # Arp would do exactly the same thing.  Leaving off the channel will cause an exception.

    source = ScaleSource(scales=(scale_choices), channel=1)

    # refresher - the scale follower will take note of the current scale and
    # play the scale for a given number of notes in order.  We could be more
    # creative by using Roman() instead to select particular notes (or chords)
    # in the scale.

    follower = ScaleFollower(lengths=Endlessly([7]))

    # refresher, the roman usage looks very similar:
    # roman = Roman(symbols="1 2 3 4 5 6 7".split())
    # really, there's little use for ScaleFollower in the real world, but it was
    # getting lonely and wanted to be featured here.  It's a bit more efficient
    # but I doubt that matters.

    # NOW FOR THE FUN PART.

    # ok, here's the arpeggiator.

    # in this example, we take the currently selected note from the scale
    # play that note, then the notes 4 and 9 semitones up - a major chord.
    # every single beat will be divided into 4 parts by the arp due to 'splits'
    # however every 4th note is also a REST.
    #
    # see this table:
    #
    # TRIGGER: | C4 ~~~~~~~~~~~~ | D4 ~~~~~~~~~ | ...
    # ---------+-----------------+--------------+
    # RESTS:   | N   N   N  Y    | N   N   N  Y |
    # SEMI:    | +0  +3  +8  -   | +0  +3  +8   |
    # OCTAVES: | +2  -2  0   0   | +2  -2  0  0 |
    # ---------+-----------------+--------------+
    # PLAY:    | C6  E2  G4  -   | D6  Gb2 A4 - |
    #
    # more creative things can be done by having the semitones
    # and rest patterns be different lengths, and so on, as well as using
    # the 'free' mode with those uneven lengths.

    arp = Arp(semitones=Endlessly([0, 3, 8, 0]),
              octaves=Endlessly([2, -2, 0, 0]),
              splits=Endlessly([4]),
              rests=Endlessly([0, 0, 0, 1]))

    # HOMEWORK: add "mode=free" to the Arp constructor above and experiment
    # with octaves, splits, rests, and semitones of different values and array
    # lengths.

    # POP QUIZ:  what happens if we remove Endlessly from some of the expressions above?
    # WHY?

    # the chain here is simple - scale source feeds note source, which in turn
    # feeds the arp.

    source.chain([follower, arp, output])

    # kick out the jams

    conductor = Conductor(signal=[source], performance=output)
    conductor.start()
コード例 #52
0
def play():

    # in example 10 we showed you how powerful the arpeggiator can get.
    # well, that's great for some degrees of chaos, but what if we want
    # to let the computer make MORE decisions?

    output = Performance(bpm=120, stop_seconds=10)

    # randomness is one way to do that.

    # in example 03 we showed how to use Endlessly to loop over a set of input.
    # that used SELECTORS, but Endlessly is just a LINEAR selector that loops
    # when it gets to the end of the input.

    # randomness can also be accessed, using the Randomly selector, which
    # chooses an item from a list.
    # each choice is then repeated for a given number of times.
    # here lets pick some random scales, but whatever we pick, hold that choice
    # for 7 beats, which we covered in example 01.

    random_scale_choices = Randomly([
        # each of these items are scale specifications.  You've seen these in the very first examples.
        dict(scale=scale("c6 major"), beats=7),
        dict(scale=scale("Db4 minor_pentatonic"), beats=7),
        dict(scale=scale("Eb3 mixolydian"), beats=7)
    ])

    # note that the random selector could repeat a selection as currently
    # implemented and/or specified.  See ideas below.

    # note if we want a random choice to be made EVERY beat we can simplify
    # our usage of randomly like so:

    random_note_choices = Randomly("1 2 3 4 5 6 7".split())

    # what does that do?  It randomly plays one of 7 notes in the current scale.
    # that's syntactically clean, but super basic.  Let's override that with something
    # showing more options available to Randomly.

    # we're playing CHORDS now, and if we choose the "I" chord we are going to play
    # it twice in the current scale (which might change after we play the first, so this is
    # a minor lie). All within the current scale, of course.

    random_note_choices = Randomly([
        dict(value="I", hold=2),
        dict(value="IV", hold=1),
        dict(value="V", hold=1),
        dict(value="i", hold=1),
        dict(value="ii", hold=1),
        dict(value="iv:dim7", hold=1),
    ])

    # HOMEWORK: add some more scales to the random_scale_choices above and take out some
    # notes from random_note_choices.  Mix scales with notes!

    # FUTURE IDEA: also support a notion of frequency controlling what will be drawn.
    # frequencies should add up to 1.  This would still be compatible with "hold" above.

    #random_note_choices = Randomly([
    #    dict(value="I", frequency=0.4),
    #    dict(value="IV", frequency=0.2),
    #    dict(value="V", frequency=0.2),
    #    dict(value="i", frequency=0.1),
    #    dict(value="ii", frequency=0.05),
    #    dict(value="iv:dim7", frequency=0.05),
    #])

    # for more examples, see the demos labelled randomness2.py, randomness3.py, etc.
    # we want to cover some other things first, so I'm not going to go completelyinto
    # randomness now.

    source = ScaleSource(scales=random_scale_choices)
    roman = Roman(symbols=random_note_choices, channel=1)
    source.chain([roman, output])

    conductor = Conductor(signal=[source], performance=output)
    conductor.start()