summaryrefslogtreecommitdiffstats
path: root/src/base/AnalysisTypes.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/base/AnalysisTypes.h')
-rw-r--r--src/base/AnalysisTypes.h227
1 files changed, 227 insertions, 0 deletions
diff --git a/src/base/AnalysisTypes.h b/src/base/AnalysisTypes.h
new file mode 100644
index 0000000..d7eabad
--- /dev/null
+++ b/src/base/AnalysisTypes.h
@@ -0,0 +1,227 @@
+// -*- c-basic-offset: 4 -*-
+
+/*
+ Rosegarden
+ A sequencer and musical notation editor.
+
+ This program is Copyright 2000-2008
+ Guillaume Laurent <[email protected]>,
+ Chris Cannam <[email protected]>,
+ Richard Bown <[email protected]>
+
+ This file is Copyright 2002
+ Randall Farmer <[email protected]>
+
+ The moral right of the authors to claim authorship of this work
+ has been asserted.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version. See the file
+ COPYING included with this distribution for more information.
+*/
+
+#ifndef _ANALYSISTYPES_H_
+#define _ANALYSISTYPES_H_
+
+#include <string>
+#include <map>
+#include <set>
+#include <vector>
+
+#include "NotationTypes.h"
+
+namespace Rosegarden
+{
+
+class Segment;
+class Event;
+class CompositionTimeSliceAdapter;
+class Quantizer;
+
+///////////////////////////////////////////////////////////////////////////
+
+typedef std::string ChordType;
+class ChordLabel;
+
+namespace ChordTypes
+{
+const ChordType
+NoChord = "no-chord",
+ Major = "",
+ Minor = "m",
+ Diminished = "dim",
+ MajorSeventh = "M7",
+ DominantSeventh = "7",
+ MinorSeventh = "m7",
+ HalfDimSeventh = "7b5",
+ DimSeventh = "dim7";
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+/**
+ * ChordLabel names chords and identifies them from their masks. See
+ * ChordLabel::checkMap() for details on what the masks are and
+ * AnalysisHelper::labelChords() for an example.
+ */
+
+class ChordLabel
+{
+public:
+ ChordLabel();
+ ChordLabel(Key key, int mask, int bass);
+ ChordLabel(ChordType type, int rootPitch, int inversion = 0) :
+ m_data(type, rootPitch, inversion) { };
+ int rootPitch();
+ /**
+ * Gives the name of the chord in lead-sheet notation: C, Dm,
+ * G#7b5...
+ */
+ std::string getName(Key key) const;
+ /**
+ * Gives the name of the chord in roman-numeral notation: I, ii,
+ * VMm7...
+ */
+// std::string getRomanNumeral(Key key);
+ bool isValid() const;
+ bool operator<(const ChordLabel& other) const;
+ // ### I can't believe this is necessary, but the compiler
+ // is asking for it
+ bool operator==(const ChordLabel& other) const;
+
+private:
+ // #### are m_* names appropriate for a struct?
+ // shouldn't I find a neater way to keep a ChordMap?
+ struct ChordData
+ {
+ ChordData(ChordType type, int rootPitch, int inversion = 0) :
+ m_type(type),
+ m_rootPitch(rootPitch),
+ m_inversion(inversion) { };
+
+ ChordData() :
+ m_type(ChordTypes::NoChord),
+ m_rootPitch(0),
+ m_inversion(0) { };
+
+ ChordType m_type;
+ int m_rootPitch;
+ int m_inversion;
+ };
+ ChordData m_data;
+ void checkMap();
+
+ typedef std::multimap<int, ChordData> ChordMap;
+ static ChordMap m_chordMap;
+};
+
+///////////////////////////////////////////////////////////////////////////
+
+class AnalysisHelper
+{
+public:
+ AnalysisHelper() {};
+
+ /**
+ * Returns the key in force during a given event.
+ */
+ Key getKeyForEvent(Event *e, Segment &s);
+
+ /**
+ * Inserts in the given Segment labels for all of the chords found in
+ * the timeslice in the given CompositionTimeSliceAdapter.
+ */
+ void labelChords(CompositionTimeSliceAdapter &c, Segment &s,
+ const Quantizer *quantizer);
+
+ /**
+ * Returns a time signature that is probably reasonable for the
+ * given timeslice.
+ */
+ TimeSignature guessTimeSignature(CompositionTimeSliceAdapter &c);
+
+ /**
+ * Returns a guess at the starting key of the given timeslice.
+ */
+ Key guessKey(CompositionTimeSliceAdapter &c);
+
+ /**
+ * Like labelChords, but the algorithm is more complicated. This tries
+ * to guess the chords that should go under a beat even when all of the
+ * chord members aren't played at once.
+ */
+ void guessHarmonies(CompositionTimeSliceAdapter &c, Segment &s);
+
+protected:
+ // ### THESE NAMES ARE AWFUL. MUST GREP THEM OUT OF EXISTENCE.
+ typedef std::pair<double, ChordLabel> ChordPossibility;
+ typedef std::vector<ChordPossibility> HarmonyGuess;
+ typedef std::vector<std::pair<timeT, HarmonyGuess> > HarmonyGuessList;
+ struct cp_less : public std::binary_function<ChordPossibility, ChordPossibility, bool>
+ {
+ bool operator()(ChordPossibility l, ChordPossibility r);
+ };
+
+ /// For use by guessHarmonies
+ void makeHarmonyGuessList(CompositionTimeSliceAdapter &c,
+ HarmonyGuessList &l);
+
+ /// For use by guessHarmonies
+ void refineHarmonyGuessList(CompositionTimeSliceAdapter &c,
+ HarmonyGuessList& l,
+ Segment &);
+
+ /// For use by guessHarmonies (makeHarmonyGuessList)
+ class PitchProfile
+ {
+ public:
+ PitchProfile();
+ double& operator[](int i);
+ const double& operator[](int i) const;
+ double distance(const PitchProfile &other);
+ double dotProduct(const PitchProfile &other);
+ double productScorer(const PitchProfile &other);
+ PitchProfile normalized();
+ PitchProfile& operator*=(double d);
+ PitchProfile& operator+=(const PitchProfile &d);
+ private:
+ double m_data[12];
+ };
+
+ /// For use by guessHarmonies (makeHarmonyGuessList)
+ typedef std::vector<std::pair<PitchProfile, ChordLabel> > HarmonyTable;
+ static HarmonyTable m_harmonyTable;
+
+ /// For use by guessHarmonies (makeHarmonyGuessList)
+ void checkHarmonyTable();
+
+ /// For use by guessHarmonies (refineHarmonyGuessList)
+ // #### grep ProgressionMap to something else
+ struct ChordProgression {
+ ChordProgression(ChordLabel first_,
+ ChordLabel second_ = ChordLabel(),
+ Key key_ = Key());
+ ChordLabel first;
+ ChordLabel second;
+ Key homeKey;
+ // double commonness...
+ bool operator<(const ChordProgression& other) const;
+ };
+ typedef std::set<ChordProgression> ProgressionMap;
+ static ProgressionMap m_progressionMap;
+
+ /// For use by guessHarmonies (refineHarmonyGuessList)
+ void checkProgressionMap();
+
+ /// For use by checkProgressionMap
+ void addProgressionToMap(Key k,
+ int firstChordNumber,
+ int secondChordNumber);
+
+};
+
+}
+
+#endif