def _calcMinMajRatioImpact(self, minMajRatio, metricalAccentLevel, triadType): maxMinMajRatioImpact = self._minMajRationMaxImpact[triadType][metricalAccentLevel] minMajRatioImpact = linlin(minMajRatio, MINEMOTIONALFEATURES, MAXEMOTIONALFEATURES, 0, maxMinMajRatioImpact) return minMajRatioImpact
def _calcHarmonicComplexityImpactOnProfile(self, harmonicComplexity, metricalAccentLevel): harmonicComplexityMaxImpact = self._profileDistanceMaxImpact[ metricalAccentLevel] harmonicComplxImpactOnProfile = linlin(harmonicComplexity, MINEMOTIONALFEATURES, MAXEMOTIONALFEATURES, 0, harmonicComplexityMaxImpact) return harmonicComplxImpactOnProfile
def _calcChordNoteScores(self, pitchOptions, metricalAccent, melodicComplexity): """Calculate the score for chord notes, which favours the fundamental over the 3rd and other components of the chord Args: pitchOptions (dict): Available pitch options for a given backbone note, with info to note type. The dict is of the type {33: "fundamental", 44: "3rd",...} metricalAccent (int): Metrical accent of the backbone note melodicComplexity (float): Music feature Returns: scores (dict): Dict of the type {pitch: score, ...} """ scores = {} # iterate through all options and get score for given pitch/metrical # accent for pitch, type in pitchOptions.items(): score = self._chordNoteScores[type][metricalAccent] scores[pitch] = score maxVal = 0 # get biggest score in chord note scores for type, values in self._chordNoteScores.items(): v = self._chordNoteScores[type][metricalAccent] if v > maxVal: maxVal = v # calculate middle point in scores attractionValue = maxVal / 2.0 # calculate attraction rate for compression melodicComplexityImpact = linlin( melodicComplexity, MIN, MAX, 0, self._modifiers["maxMelodicComplexityImpact"]) # compress the scores based on melodic complexity scores = self._compressValues(attractionValue, scores, melodicComplexityImpact) return scores
def _calcMelodicGravityScores(self, pitchOptions, previousPitch, pitchRange): """Calculate the score for melodic gravity, which favours the closeness between subsequent notes of the backbone Args: pitchOptions (list): Available pitch options for a given backbone note previousPitch (int): Pitch of previous backbone note pitchRange (float): Music feature that acts as a modifier Returns: scores (dict): Dict of the type {pitch: score, ...} """ # calculate distance between previous pitch and pitch options pitchDistances = [abs(p - previousPitch) for p in pitchOptions] scores = {} # iterate through all distances, select relevant score and update # scores dict for i, d in enumerate(pitchDistances): score = self._melGravityScores[d] pitch = pitchOptions[i] scores[pitch] = score maxVal = max(list(self._melGravityScores.values())) # calculate middle point in scores attractionValue = maxVal / 2.0 # calculate attraction rate for compression pitchRangeImpact = linlin(pitchRange, MIN, MAX, 0, self._modifiers["maxPitchRangeImpact"]) # compress the scores based on pitch range scores = self._compressValues(attractionValue, scores, pitchRangeImpact) return scores
def _calcDissonanceProb(self, harmonicComplexity, metricalAccentLevel): maxDissonanceProb = self._dissonanceData["probability"][metricalAccentLevel] dissonanceProb = linlin(harmonicComplexity, MINEMOTIONALFEATURES, MAXEMOTIONALFEATURES, 0, maxDissonanceProb) return dissonanceProb