示例#1
0
    def trackBar(self, pattern, ctable):
        """ Do the bass bar.

        Called from self.bar()

        """

        sc = self.seq
        unify = self.unify[sc]

        for p in pattern:
            ct = self.getChordInPos(p.offset, ctable)

            if ct.bassZ:
                continue

            note = ct.chord.scaleList[
                p.noteoffset] + p.addoctave + p.accidental

            if not self.harmonyOnly[sc]:
                self.sendNote(p.offset, self.getDur(p.duration),
                              self.adjustNote(note),
                              self.adjustVolume(p.vol, p.offset))

            if self.harmony[sc]:
                h = harmonize(self.harmony[sc], note, ct.chord.noteList)
                for n in h:
                    self.sendNote(
                        p.offset, self.getDur(p.duration), self.adjustNote(n),
                        self.adjustVolume(p.vol * self.harmonyVolume[sc], -1))
示例#2
0
    def addHarmony(self, notes, ctable):
        """ Add harmony to solo notes. """

        sc = self.seq

        harmony = self.harmony[sc]
        harmOnly = self.harmonyOnly[sc]

        for offset in notes:
            nn = notes[offset]

            if len(nn.nl) == 1 and nn.nl[0] != None:
                tb = self.getChordInPos(offset, ctable)

                if tb.chordZ:
                    continue

                h = harmonize(harmony, nn.nl[0], tb.chord.bnoteList)
                """ If harmonyonly set then drop note, substitute harmony,
                    else append harmony notes to chord.
                """

                if harmOnly:
                    nn.nl = h
                    nn.velocity = []
                    off = 0
                else:
                    nn.nl.extend(h)
                    off = 1

                # Create velocites for harmony note(s)

                for i in range(off, len(nn.nl)):
                    nn.velocity.append(
                        self.adjustVolume(
                            nn.defaultVel * self.harmonyVolume[sc], offset))

        return notes
示例#3
0
    def trackBar(self, pattern, ctable):
        """ Do a arpeggio bar.

        Called from self.bar()

        """

        sc = self.seq
        direct = self.direction[sc]

        for p in pattern:
            tb = self.getChordInPos(p.offset, ctable)

            if tb.arpeggioZ:
                continue

            if direct == 'DOWN':
                self.arpDirection = -1

            if self.chordLimit:
                tb.chord.limit(self.chordLimit)

            if self.compress[sc]:
                tb.chord.compress()

            if self.invert[sc]:
                tb.chord.invert(self.invert[sc])

            # This should be optimized, it recreates the chord for every pattern.
            # Problem is that one would need to check all the LIMIT, COMPRESS, etc
            # settings each for each bar as well, so it's probably just as easy to
            # leave it as is. Besides, this works.

            ln = self.chordRange[sc]
            o = 0
            ourChord = []
            while ln >= 1:
                for a in tb.chord.noteList:
                    ourChord.append(a + o)
                ln -= 1
                o += 12

            if ln > 0 and ln < 1:  # for fractional  lengths
                ln = int(tb.chord.noteListLen * ln)
                if ln < 2:  # important, min of 2 notes in arp.
                    ln = 2
                for a in tb.chord.noteList[:ln]:
                    ourChord.append(a + o)

            if direct == 'BOTH':
                if self.arpOffset < 0:
                    self.arpOffset = 1
                    self.arpDirection = 1
                elif self.arpOffset >= len(ourChord):
                    self.arpOffset = len(ourChord) - 2
                    self.arpDirection = -1

            elif direct == 'UP':
                if self.arpOffset >= len(ourChord) or self.arpOffset < 0:
                    self.arpOffset = 0
                    self.arpDirection = 1

            elif direct == 'DOWN':
                if self.arpOffset < 0 or self.arpOffset >= len(ourChord):
                    self.arpOffset = len(ourChord) - 1
                    self.arpDirection = -1

            if direct == 'RANDOM':
                note = random.choice(ourChord)
            else:
                note = ourChord[self.arpOffset]

            self.arpOffset += self.arpDirection

            if not self.harmonyOnly[sc]:
                self.sendNote(p.offset, self.getDur(p.duration),
                              self.adjustNote(note),
                              self.adjustVolume(p.vol, p.offset))

            if self.harmony[sc]:
                h = harmonize(self.harmony[sc], note, ourChord)
                for n in h:
                    self.sendNote(
                        p.offset, self.getDur(p.duration), self.adjustNote(n),
                        self.adjustVolume(p.vol * self.harmonyVolume[sc], -1))

            tb.chord.reset()  # important, other tracks chord object
示例#4
0
    def trackBar(self, pattern, ctable):
        """ Do the aria bar.

        Called from self.bar()

        """

        sc = self.seq
        unify = self.unify[sc]

        for p in pattern:
            ct = self.getChordInPos(p.offset, ctable)

            if ct.ariaZ:
                continue

            thisChord = ct.chord.tonic + ct.chord.chordType
            stype = self.scaleType[sc]
            range = self.chordRange[sc]

            ### Generate notelist if nesc.

            if self.lastChord != thisChord or self.lastStype != stype or \
                    self.lastRange != range:

                self.lastChord = thisChord
                self.lastStype = stype
                self.lastRange = range

                if stype == 'CHORD':
                    notelist = ct.chord.noteList
                elif stype == 'CHROMATIC':
                    notelist = [ct.chord.rootNote + x for x in range(0, 12)]
                else:
                    notelist = list(ct.chord.scaleList)

                o = 0
                self.notes = []

                while range >= 1:
                    for a in notelist:
                        self.notes.append(a + o)
                    o += 12
                    range -= 1

                if range > 0 and range < 1:  # for fractional scale lengths
                    range = int(len(notelist) * range)
                    if range < 2:  # important, must be at least 2 notes in a scale
                        range = 2
                    for a in notelist[:range]:
                        self.notes.append(a + o)

            # grab a note from the list

            if self.dirptr >= len(self.selectDir):
                self.dirptr = 0

            a = self.selectDir[self.dirptr]
            if a == 'R':
                a = random.choice((-1, 0, 1))
            self.noteptr += a

            if self.noteptr >= len(self.notes):
                if a > 0:
                    self.noteptr = 0
                else:
                    self.noteptr = len(self.notes) - 1
            elif self.noteptr < 0:
                if a < 0:
                    self.noteptr = len(self.notes) - 1
                else:
                    self.noteptr = 0

            note = self.notes[self.noteptr]

            self.dirptr += 1

            # output

            if not self.harmonyOnly[sc]:
                self.sendNote(p.offset, self.getDur(p.duration),
                              self.adjustNote(note),
                              self.adjustVolume(p.vol, p.offset))

            if self.harmony[sc]:
                h = harmonize(self.harmony[sc], note, ct.chord.noteList)
                for n in h:
                    self.sendNote(
                        p.offset, self.getDur(p.duration), self.adjustNote(n),
                        self.adjustVolume(p.vol * self.harmonyVolume[sc], -1))
示例#5
0
    def trackBar(self, pattern, ctable):
        """ Do a waling     bass bar.

        Called from self.bar()

        """

        sc=self.seq
        dir = self.direction[sc]
        unify = self.unify[sc]

        for p in pattern:

            tb = self.getChordInPos(p.offset, ctable)

            if tb.walkZ:
                continue

            root = tb.chord.rootNote        # root note of chord

            """ Create a note list from the current scale. We do
            this for each beat, but it's pretty fast. The note
            list is simply notes 0..6 of the scale PLUS notes
            1..5 reversed. So, a Cmajor chord would result in
            the note list (0,2,4,5,7,9,7,5,4,2).

            Note that we deliberately skip the 7th. Too often
            the chord is a Major but the melody note will be
            the dom. 7th and the M7 will sound off. So, just
            err on the side of caution.

            If DIR is UP or DOWN we don't append the 2nd half
            of the scale.

            If DIR is DOWN we reverse the order as well.
            """

            wNotes = list(tb.chord.scaleList[0:6])
            if dir not in ('UP', 'DOWN'):
                b = list(tb.chord.scaleList[1:5])
                b.reverse()
                wNotes += b

            if dir == 'DOWN':
                wNotes.reverse()


            # Ensure that the offset is in range.

            if self.walkChoice >= len(wNotes) or self.walkChoice < 0:
                self.walkChoice = 0

            """ Even with a walking bass it's nice to have the chord root on
            beat 1 ... not all the time, but most. This bit of code ensures
            that more that 50% of beat ones will have the root.
            """


            if p.offset == 0 and random.choice((0,1)):
                self.walkChoice=0

            note = wNotes[self.walkChoice]

            """ Adjust offset for NEXT TIME. If the direction is
            up/down we just increment the pointer. If we have
            direction set to RANDOM then we select either -1,
            0 or 1 with equal change for moving up, down or
            not-at-all. With BOTH we have a preference to move up.
            """


            if dir in ('UP', 'DOWN'):
                self.walkChoice += 1
            elif dir == 'RANDOM':
                self.walkChoice += random.choice((0,1,-1))
            else:    # BOTH
                self.walkChoice += random.choice( (-1,0,0,2,2,1,1,1,1,1,1,1))


            if not self.harmonyOnly[sc]:
                self.sendNote(
                    p.offset,
                    self.getDur(p.duration),
                    self.adjustNote(note),
                    self.adjustVolume(p.vol, p.offset) )


            if self.harmony[sc]:
                ch = self.getChordInPos(p.offset, ctable).chord.noteList
                h = harmonize(self.harmony[sc], note, ch)
                for n in h:
                    self.sendNote(
                        p.offset,
                        self.getDur(p.duration),
                        self.adjustNote(n),
                        self.adjustVolume(p.vol * self.harmonyVolume[sc], -1) )
示例#6
0
    def trackBar(self, pattern, ctable):
        """ Do a scale bar.

            Called from self.bar()
        """

        sc = self.seq
        direct = self.direction[sc]
        unify = self.unify[sc]

        # If the range or direction has changed, we just start
        # with a new scale.

        t = self.chordRange[sc]
        if t != self.lastRange:
            self.lastRange = t
            self.lastChord = None

        if self.lastDirect != direct:
            self.lastDirect = direct
            self.lastChord = None

        for p in pattern:

            tb = self.getChordInPos(p.offset, ctable)

            if tb.scaleZ:
                continue

            thisChord = tb.chord.tonic + tb.chord.chordType
            stype = self.scaleType[sc]

            if thisChord != self.lastChord or stype != self.lastStype:
                self.lastChord = thisChord
                self.lastStype = stype

                if stype == 'CHROMATIC':
                    notelist = [tb.chord.rootNote + x for x in range(0, 12)]

                else:
                    notelist = list(tb.chord.scaleList)
                """ Get the current scale and append enuf copies
                together for RANGE setting. If Range happens
                to be 0 or 1 we end up with a single copy.
                """

                ln = self.chordRange[sc]  # RANGE 1...x (def. == 1)

                o = 0
                self.notes = []

                while ln >= 1:
                    for a in notelist:
                        self.notes.append(a + o)
                    o += 12
                    ln -= 1

                if ln > 0 and ln < 1:  # for fractional scale lengths
                    ln = int(len(notelist) * ln)
                    if ln < 2:  # important, must be at least 2 notes in a scale
                        ln = 2
                    for a in notelist[:ln]:
                        self.notes.append(a + o)

                if direct == 'DOWN':
                    self.dirfact = -1
                    if self.lastNote == -1:
                        self.sOffset = len(self.notes) - 1
                else:
                    self.sOffset = 0

                if self.lastNote > -1:
                    if self.lastNote in self.notes:
                        self.sOffset = self.notes.index(self.lastNote)

                    else:
                        self.sOffset = len(self.notes) - 1
                        for i, a in enumerate(self.notes):
                            if a > self.lastNote:
                                self.sOffset = i
                                break

            # Keep offset into note list in range

            # only > end of list if BOTH or UP

            if self.sOffset >= len(self.notes):
                if direct == 'BOTH':
                    self.dirfact = -1
                    self.sOffset = len(self.notes) - 2
                else:  ## UP
                    self.sOffset = 0

            # only < start of list if DOWN or BOTH

            elif self.sOffset < 0:
                if direct == 'BOTH':
                    self.dirfact = 1
                    self.sOffset = 1
                else:  ## DOWN
                    self.sOffset = len(self.notes) - 1

            if direct == 'RANDOM':
                note = random.choice(self.notes)
            else:
                note = self.notes[self.sOffset]
                self.sOffset += self.dirfact

            self.lastNote = note

            if not self.harmonyOnly[sc]:
                self.sendNote(p.offset, self.getDur(p.duration),
                              self.adjustNote(note),
                              self.adjustVolume(p.vol, p.offset))

            if self.harmony[sc]:
                ch = self.getChordInPos(p.offset, ctable).chord.noteList
                h = harmonize(self.harmony[sc], note, ch)
                for n in h:
                    self.sendNote(
                        p.offset, self.getDur(p.duration), self.adjustNote(n),
                        self.adjustVolume(self.harmonyVolume[sc] * p.vol, -1))