From 251248adfab36b061eb8fdd08aa54b318462da65 Mon Sep 17 00:00:00 2001 From: Kelly Rauchenberger Date: Wed, 28 Mar 2018 15:49:50 -0400 Subject: Revamped bot with new algorithm The percentages currently used by the generator are trial-and-error and may be changed in the future. refs #1 --- generator/CMakeLists.txt | 2 +- generator/generator.cpp | 109 ++++++++++++++++++++++++++++++++++++----------- generator/mood.cpp | 94 ---------------------------------------- generator/mood.h | 60 -------------------------- generator/schema.sql | 10 ++++- 5 files changed, 94 insertions(+), 181 deletions(-) delete mode 100644 generator/mood.cpp delete mode 100644 generator/mood.h (limited to 'generator') diff --git a/generator/CMakeLists.txt b/generator/CMakeLists.txt index dffbe0e..8031f6a 100644 --- a/generator/CMakeLists.txt +++ b/generator/CMakeLists.txt @@ -9,7 +9,7 @@ include_directories( vendor/json ../vendor/hkutil) -add_executable(generator mood.cpp generator.cpp main.cpp) +add_executable(generator generator.cpp main.cpp) set_property(TARGET generator PROPERTY CXX_STANDARD 11) set_property(TARGET generator PROPERTY CXX_STANDARD_REQUIRED ON) target_link_libraries(generator ${sqlite3_LIBRARIES}) diff --git a/generator/generator.cpp b/generator/generator.cpp index 19eba70..4244fd2 100644 --- a/generator/generator.cpp +++ b/generator/generator.cpp @@ -6,7 +6,6 @@ #include #include #include -#include "mood.h" namespace cadence { namespace generator { @@ -93,7 +92,8 @@ namespace cadence { DIR* subdir; if ((subdir = opendir(directory.c_str())) == nullptr) { - throw std::invalid_argument("Invalid AcousticBrainz data directory"); + throw std::invalid_argument( + "Invalid AcousticBrainz data directory"); } struct dirent* subent; @@ -106,7 +106,8 @@ namespace cadence { DIR* subsubdir; if ((subsubdir = opendir(subdirectory.c_str())) == nullptr) { - throw std::invalid_argument("Invalid AcousticBrainz data directory"); + throw std::invalid_argument( + "Invalid AcousticBrainz data directory"); } struct dirent* subsubent; @@ -149,27 +150,87 @@ namespace cadence { try { - std::vector moods; - moods.emplace_back(mood::type::danceable, jsonData["highlevel"]["danceability"]["all"]["danceable"]); - moods.emplace_back(mood::type::acoustic, jsonData["highlevel"]["mood_acoustic"]["all"]["acoustic"]); - moods.emplace_back(mood::type::aggressive, jsonData["highlevel"]["mood_aggressive"]["all"]["aggressive"]); - moods.emplace_back(mood::type::electronic, jsonData["highlevel"]["mood_electronic"]["all"]["electronic"]); - moods.emplace_back(mood::type::happy, jsonData["highlevel"]["mood_happy"]["all"]["happy"]); - moods.emplace_back(mood::type::party, jsonData["highlevel"]["mood_party"]["all"]["party"]); - moods.emplace_back(mood::type::relaxed, jsonData["highlevel"]["mood_relaxed"]["all"]["relaxed"]); - moods.emplace_back(mood::type::sad, jsonData["highlevel"]["mood_sad"]["all"]["sad"]); - moods.emplace_back(mood::type::instrumental, jsonData["highlevel"]["voice_instrumental"]["all"]["instrumental"]); - - std::sort(std::begin(moods), std::end(moods), [] (const mood& left, const mood& right) -> bool { - return left.getProbability() > right.getProbability(); - }); - - std::list columns; - columns.emplace_back("title", jsonData["metadata"]["tags"]["title"][0].get()); - columns.emplace_back("artist", jsonData["metadata"]["tags"]["artist"][0].get()); - columns.emplace_back("category", moods.front().getCategory()); - - db_.insertIntoTable("songs", std::move(columns)); + auto& hl = jsonData["highlevel"]; + + double danceable = hl["danceability"]["all"]["danceable"]; + double acoustic = hl["mood_acoustic"]["all"]["acoustic"]; + double aggressive = hl["mood_aggressive"]["all"]["aggressive"]; + double electronic = hl["mood_electronic"]["all"]["electronic"]; + double happy = hl["mood_happy"]["all"]["happy"]; + double party = hl["mood_party"]["all"]["party"]; + double relaxed = hl["mood_relaxed"]["all"]["relaxed"]; + double sad = hl["mood_sad"]["all"]["sad"]; + double instrumental = hl["voice_instrumental"]["all"]["instrumental"]; + + std::string title = jsonData["metadata"]["tags"]["title"][0]; + std::string artist = jsonData["metadata"]["tags"]["artist"][0]; + + uint64_t songId = db_.insertIntoTable( + "songs", + { + { "title", title }, + { "artist", artist } + }); + + std::list moods; + + // ~38% + if ((party > 0.5) || (danceable > 0.75)) + { + moods.push_back("party"); + } + + // ~38% + if ((relaxed > 0.81) || (acoustic > 0.5)) + { + moods.push_back("chill"); + } + + // ~42% + if ((aggressive > 0.5) || (electronic > 0.95)) + { + moods.push_back("crazy"); + } + + // ~30% + if (happy > 0.5) + { + moods.push_back("happy"); + } + + // ~30% + if (sad > 0.5) + { + moods.push_back("sad"); + } + + // ~38% + if (instrumental > 0.9) + { + moods.push_back("instrumental"); + } + + // ~34% + if (instrumental < 0.2) + { + moods.push_back("vocal"); + } + + // ~1% + if (moods.empty()) + { + moods.push_back("unknown"); + } + + for (const std::string& mood : moods) + { + db_.insertIntoTable( + "moods", + { + { "song_id", static_cast(songId) }, + { "mood", mood } + }); + } } catch (const std::domain_error& ex) { // Weird data. Ignore silently. diff --git a/generator/mood.cpp b/generator/mood.cpp deleted file mode 100644 index b74211c..0000000 --- a/generator/mood.cpp +++ /dev/null @@ -1,94 +0,0 @@ -#include "mood.h" - -namespace cadence { - namespace generator { - - // The categories are: - // - party (+danceable, -acoustic, +electronic, +party) = ~.21 - // - chill (-danceable, +acoustic, -aggressive, -electronic, -party, +relaxed) = ~.49 - // - crazy (+aggressive, -relaxed) = ~.02 - // - happy (+happy, -sad) = ~.009 - // - sad (-happy, +sad) = ~.02 - // - instrumental (+instrumental) = ~.12 - // - vocal (-instrumental) = ~.10 - - mood::mood(type t, double prob) : type_(t) - { - if (prob >= 0.5) - { - probability_ = prob; - positive_ = true; - } else { - probability_ = 1.0 - prob; - positive_ = false; - } - - switch (t) - { - case type::danceable: - { - category_ = (positive_ ? "party" : "chill"); - - break; - } - - case type::acoustic: - { - category_ = (positive_ ? "chill" : "party"); - - break; - } - - case type::aggressive: - { - category_ = (positive_ ? "crazy" : "chill"); - - break; - } - - case type::electronic: - { - category_ = (positive_ ? "party" : "chill"); - - break; - } - - case type::happy: - { - category_ = (positive_ ? "happy" : "sad"); - - break; - } - - case type::party: - { - category_ = (positive_ ? "party" : "chill"); - - break; - } - - case type::relaxed: - { - category_ = (positive_ ? "chill" : "crazy"); - - break; - } - - case type::sad: - { - category_ = (positive_ ? "sad" : "happy"); - - break; - } - - case type::instrumental: - { - category_ = (positive_ ? "instrumental" : "vocal"); - - break; - } - } - } - - }; -}; diff --git a/generator/mood.h b/generator/mood.h deleted file mode 100644 index c36e5ee..0000000 --- a/generator/mood.h +++ /dev/null @@ -1,60 +0,0 @@ -#ifndef MOOD_H_B9A39F40 -#define MOOD_H_B9A39F40 - -#include - -namespace cadence { - namespace generator { - - class mood { - public: - enum class type { - danceable, - acoustic, - aggressive, - electronic, - happy, - party, - relaxed, - sad, - instrumental - }; - - // Constructor - - mood(type t, double prob); - - // Accessors - - type getType() const - { - return type_; - } - - double getProbability() const - { - return probability_; - } - - bool getPositive() const - { - return positive_; - } - - std::string getCategory() const - { - return category_; - } - - private: - type type_; - double probability_; - bool positive_; - std::string category_; - - }; - - }; -}; - -#endif /* end of include guard: MOOD_H_B9A39F40 */ diff --git a/generator/schema.sql b/generator/schema.sql index 879ebb3..7d211ba 100644 --- a/generator/schema.sql +++ b/generator/schema.sql @@ -1,5 +1,11 @@ CREATE TABLE `songs` ( + `song_id` INTEGER PRIMARY KEY, `title` VARCHAR(255) NOT NULL, - `artist` VARCHAR(255) NOT NULL, - `category` VARCHAR(255) NOT NULL + `artist` VARCHAR(255) NOT NULL ); + +CREATE TABLE `moods` ( + `song_id` INTEGER, + `mood` VARCHAR(255), + PRIMARY KEY (`song_id`, `mood`) +) WITHOUT ROWID; -- cgit 1.4.1