Browse Source

Bump Bliss version

Now using 3 tempo values, updated Bliss version.

_Note_: You should rebuild your database after upgrading to this commit.
Next major breaking changes will be handled by dedicated update scripts
to avoid having to rebuild the entire database.
Phyks (Lucas Verney) 4 years ago
parent
commit
345383e3a5
7 changed files with 72 additions and 21 deletions
  1. 1
    1
      README.md
  2. 1
    1
      bliss
  3. 1
    0
      include/constants.h
  4. 15
    7
      mpd/client.py
  5. 13
    5
      scripts/build_cache.py
  6. 27
    7
      src/analysis.c
  7. 14
    0
      src/main.c

+ 1
- 1
README.md View File

@@ -5,7 +5,7 @@ Blissify is a wrapper around
5 5
 [Bliss](https://github.com/Polochon-street/bliss) to compute and store values
6 6
 in an SQLite database.
7 7
 
8
-It is done in an attempot to bind Bliss to MPD to be able to play
8
+It is done in an attempt to bind Bliss to MPD to be able to play
9 9
 smooth mixes with MPD, _à la_ Grooveshark radio.
10 10
 
11 11
 ## Dependencies

+ 1
- 1
bliss

@@ -1 +1 @@
1
-Subproject commit 4781124ff177fa1eb649b9b74993a0ae28b1e501
1
+Subproject commit 582b96d6ed217016363c7d7d5b24ee10d179a946

+ 1
- 0
include/constants.h View File

@@ -2,5 +2,6 @@
2 2
 #define CONSTANTS_H
3 3
 
4 4
 #define DEFAULT_STRING_LENGTH 10000
5
+#define VERSION "0.1"
5 6
 
6 7
 #endif  // CONSTANTS_H

+ 15
- 7
mpd/client.py View File

@@ -146,7 +146,7 @@ def main(queue_length):
146 146
     logging.info("Currently played song is %s." % (current_song,))
147 147
 
148 148
     # Get current song coordinates
149
-    cur.execute("SELECT id, tempo, amplitude, frequency, attack, filename FROM songs WHERE filename=?", (current_song,))
149
+    cur.execute("SELECT id, tempo1, tempo2, tempo3, amplitude, frequency, attack, filename FROM songs WHERE filename=?", (current_song,))
150 150
     current_song_coords = cur.fetchone()
151 151
     if current_song_coords is None:
152 152
         logging.warning("Current song %s is not in db. You should update the db." %
@@ -158,7 +158,7 @@ def main(queue_length):
158 158
     for i in range(queue_length):
159 159
         # Get cached distances from db
160 160
         cur.execute(
161
-            "SELECT id, filename, distance, similarity, tempo, amplitude, frequency, attack FROM (SELECT s2.id AS id, s2.filename AS filename, s2.tempo AS tempo, s2.amplitude AS amplitude, s2.frequency AS frequency, s2.attack AS attack, distances.distance AS distance, distances.similarity AS similarity FROM distances INNER JOIN songs AS s1 ON s1.id=distances.song1 INNER JOIN songs AS s2 on s2.id=distances.song2 WHERE s1.filename=? UNION SELECT s1.id as id, s1.filename AS filename, s1.tempo AS tempo, s1.amplitude AS amplitude, s1.frequency AS frequency, s1.attack AS attack, distances.distance as distance, distances.similarity AS similarity FROM distances INNER JOIN songs AS s1 ON s1.id=distances.song1 INNER JOIN songs AS s2 on s2.id=distances.song2 WHERE s2.filename=?) ORDER BY distance ASC",
161
+            "SELECT id, filename, distance, similarity, tempo1, tempo2, tempo3, amplitude, frequency, attack FROM (SELECT s2.id AS id, s2.filename AS filename, s2.tempo1 AS tempo1, s2.tempo2 AS tempo2, s2.tempo3 AS tempo3, s2.amplitude AS amplitude, s2.frequency AS frequency, s2.attack AS attack, distances.distance AS distance, distances.similarity AS similarity FROM distances INNER JOIN songs AS s1 ON s1.id=distances.song1 INNER JOIN songs AS s2 on s2.id=distances.song2 WHERE s1.filename=? UNION SELECT s1.id as id, s1.filename AS filename, s1.tempo1 AS tempo1, s1.tempo2 AS tempo2, s1.tempo3 AS tempo3, s1.amplitude AS amplitude, s1.frequency AS frequency, s1.attack AS attack, distances.distance as distance, distances.similarity AS similarity FROM distances INNER JOIN songs AS s1 ON s1.id=distances.song1 INNER JOIN songs AS s2 on s2.id=distances.song2 WHERE s2.filename=?) ORDER BY distance ASC",
162 162
             (current_song_coords["filename"], current_song_coords["filename"]))
163 163
         cached_distances = [row
164 164
                             for row in cur.fetchall()
@@ -181,7 +181,7 @@ def main(queue_length):
181 181
 
182 182
         # Get all other songs coordinates
183 183
         closest_song = None
184
-        cur.execute("SELECT id, tempo, amplitude, frequency, attack, filename FROM songs")
184
+        cur.execute("SELECT id, tempo1, tempo2, tempo3, amplitude, frequency, attack, filename FROM songs")
185 185
         for tmp_song_data in cur.fetchall():
186 186
             if(tmp_song_data["filename"] == current_song_coords["filename"] or
187 187
                tmp_song_data["filename"] in cached_distances_songs or
@@ -191,24 +191,32 @@ def main(queue_length):
191 191
                 continue
192 192
             # Compute distance
193 193
             distance = math.sqrt(
194
-                (current_song_coords["tempo"] - tmp_song_data["tempo"])**2 +
194
+                (current_song_coords["tempo1"] - tmp_song_data["tempo1"])**2 +
195
+                (current_song_coords["tempo2"] - tmp_song_data["tempo2"])**2 +
196
+                (current_song_coords["tempo3"] - tmp_song_data["tempo3"])**2 +
195 197
                 (current_song_coords["amplitude"] - tmp_song_data["amplitude"])**2 +
196 198
                 (current_song_coords["frequency"] - tmp_song_data["frequency"])**2 +
197 199
                 (current_song_coords["attack"] - tmp_song_data["attack"])**2
198 200
             )
199 201
             similarity = (
200
-                (current_song_coords["tempo"] * tmp_song_data["tempo"] +
202
+                (current_song_coords["tempo1"] * tmp_song_data["tempo1"] +
203
+                 current_song_coords["tempo2"] * tmp_song_data["tempo2"] +
204
+                 current_song_coords["tempo3"] * tmp_song_data["tempo3"] +
201 205
                  current_song_coords["amplitude"] * tmp_song_data["amplitude"] +
202 206
                  current_song_coords["frequency"] * tmp_song_data["frequency"] +
203 207
                  current_song_coords["attack"] * tmp_song_data["attack"]) /
204 208
                 (
205 209
                     math.sqrt(
206
-                        current_song_coords["tempo"]**2 +
210
+                        current_song_coords["tempo1"]**2 +
211
+                        current_song_coords["tempo2"]**2 +
212
+                        current_song_coords["tempo3"]**2 +
207 213
                         current_song_coords["amplitude"]**2 +
208 214
                         current_song_coords["frequency"]**2 +
209 215
                         current_song_coords["attack"]**2) *
210 216
                     math.sqrt(
211
-                        tmp_song_data["tempo"]**2 +
217
+                        tmp_song_data["tempo1"]**2 +
218
+                        tmp_song_data["tempo2"]**2 +
219
+                        tmp_song_data["tempo3"]**2 +
212 220
                         tmp_song_data["amplitude"]**2 +
213 221
                         tmp_song_data["frequency"]**2 +
214 222
                         tmp_song_data["attack"]**2)

+ 13
- 5
scripts/build_cache.py View File

@@ -25,7 +25,7 @@ def main():
25 25
     cached_distances = cur.fetchall()
26 26
 
27 27
     # Get all songs
28
-    cur.execute("SELECT id, tempo, amplitude, frequency, attack, filename FROM songs")
28
+    cur.execute("SELECT id, tempo1, tempo2, tempo3, amplitude, frequency, attack, filename FROM songs")
29 29
     all_songs = cur.fetchall()
30 30
 
31 31
     for i in range(len(all_songs)):
@@ -42,24 +42,32 @@ def main():
42 42
                 continue
43 43
             # Compute distance
44 44
             distance = math.sqrt(
45
-                (song1["tempo"] - song2["tempo"])**2 +
45
+                (song1["tempo1"] - song2["tempo1"])**2 +
46
+                (song1["tempo2"] - song2["tempo2"])**2 +
47
+                (song1["tempo3"] - song2["tempo3"])**2 +
46 48
                 (song1["amplitude"] - song2["amplitude"])**2 +
47 49
                 (song1["frequency"] - song2["frequency"])**2 +
48 50
                 (song1["attack"] - song2["attack"])**2
49 51
             )
50 52
             similarity = (
51
-                (song1["tempo"] * song2["tempo"] +
53
+                (song1["tempo1"] * song2["tempo1"] +
54
+                 song1["tempo2"] * song2["tempo2"] +
55
+                 song1["tempo3"] * song2["tempo3"] +
52 56
                  song1["amplitude"] * song2["amplitude"] +
53 57
                  song1["frequency"] * song2["frequency"] +
54 58
                  song1["attack"] * song2["attack"]) /
55 59
                 (
56 60
                     math.sqrt(
57
-                        song1["tempo"]**2 +
61
+                        song1["tempo1"]**2 +
62
+                        song1["tempo2"]**2 +
63
+                        song1["tempo3"]**2 +
58 64
                         song1["amplitude"]**2 +
59 65
                         song1["frequency"]**2 +
60 66
                         song1["attack"]**2) *
61 67
                     math.sqrt(
62
-                        song2["tempo"]**2 +
68
+                        song2["tempo1"]**2 +
69
+                        song2["tempo2"]**2 +
70
+                        song2["tempo3"]**2 +
63 71
                         song2["amplitude"]**2 +
64 72
                         song2["frequency"]**2 +
65 73
                         song2["attack"]**2)

+ 27
- 7
src/analysis.c View File

@@ -47,7 +47,9 @@ int _init_db(char *data_folder, char* db_path)
47 47
     }
48 48
     dberr = sqlite3_exec(dbh, "CREATE TABLE IF NOT EXISTS songs( \
49 49
         id INTEGER PRIMARY KEY, \
50
-        tempo REAL, \
50
+        tempo1 REAL, \
51
+        tempo2 REAL, \
52
+        tempo3 REAL, \
51 53
         amplitude REAL, \
52 54
         frequency REAL, \
53 55
         attack REAL, \
@@ -80,6 +82,22 @@ int _init_db(char *data_folder, char* db_path)
80 82
         sqlite3_close(dbh);
81 83
         return 1;
82 84
     }
85
+    dberr = sqlite3_exec(dbh, "CREATE TABLE IF NOT EXISTS metadata( \
86
+        name TEXT UNIQUE, \
87
+        value TEXT)", NULL, NULL, NULL);
88
+    if (SQLITE_OK != dberr) {
89
+        fprintf(stderr, "Error creating db: %s.\n", sqlite3_errmsg(dbh));
90
+        sqlite3_close(dbh);
91
+        return 1;
92
+    }
93
+    sqlite3_stmt *res;
94
+    sqlite3_prepare_v2(dbh,
95
+            "INSERT INTO metadata(name, value) VALUES(?, ?)",
96
+            -1, &res, 0);
97
+    sqlite3_bind_text(res, 1, "version", strlen("version"), SQLITE_STATIC);
98
+    sqlite3_bind_text(res, 2, VERSION, strlen(VERSION), SQLITE_STATIC);
99
+    sqlite3_step(res);
100
+    sqlite3_finalize(res);
83 101
 	sqlite3_close(dbh);
84 102
 	return 0;
85 103
 }
@@ -135,7 +153,7 @@ int _parse_music_helper(
135 153
     }
136 154
     // Insert song analysis in database
137 155
     dberr = sqlite3_prepare_v2(dbh,
138
-            "INSERT INTO songs(tempo, amplitude, frequency, attack, filename) VALUES(?, ?, ?, ?, ?)",
156
+            "INSERT INTO songs(tempo1, tempo2, tempo3, amplitude, frequency, attack, filename) VALUES(?, ?, ?, ?, ?)",
139 157
             -1, &res, 0);
140 158
     if (SQLITE_OK != dberr) {
141 159
         fprintf(stderr, "Error while inserting data in db: %s\n\n", sqlite3_errmsg(dbh));
@@ -152,11 +170,13 @@ int _parse_music_helper(
152 170
         // Pass file
153 171
         return 1;
154 172
     }
155
-    sqlite3_bind_double(res, 1, song_analysis.force_vector.tempo);
156
-    sqlite3_bind_double(res, 2, song_analysis.force_vector.amplitude);
157
-    sqlite3_bind_double(res, 3, song_analysis.force_vector.frequency);
158
-    sqlite3_bind_double(res, 4, song_analysis.force_vector.attack);
159
-    sqlite3_bind_text(res, 5, song_uri, strlen(song_uri), SQLITE_STATIC);
173
+    sqlite3_bind_double(res, 1, song_analysis.force_vector.tempo1);
174
+    sqlite3_bind_double(res, 2, song_analysis.force_vector.tempo2);
175
+    sqlite3_bind_double(res, 3, song_analysis.force_vector.tempo3);
176
+    sqlite3_bind_double(res, 4, song_analysis.force_vector.amplitude);
177
+    sqlite3_bind_double(res, 5, song_analysis.force_vector.frequency);
178
+    sqlite3_bind_double(res, 6, song_analysis.force_vector.attack);
179
+    sqlite3_bind_text(res, 7, song_uri, strlen(song_uri), SQLITE_STATIC);
160 180
     dberr = sqlite3_step(res);
161 181
     if (SQLITE_DONE != dberr) {
162 182
         // Free song analysis

+ 14
- 0
src/main.c View File

@@ -42,6 +42,20 @@ int main(int argc, char** argv) {
42 42
         sqlite3_close(dbh);
43 43
 		exit(EXIT_FAILURE);
44 44
     }
45
+    dberr = sqlite3_exec(dbh, "SELECT value FROM metadata WHERE name=version", NULL, NULL, NULL);
46
+    if (SQLITE_OK != dberr) {
47
+        fprintf(stderr, "Error while fetching data in db: %s\n\n", sqlite3_errmsg(dbh));
48
+        sqlite3_close(dbh);
49
+        exit(EXIT_FAILURE);
50
+    }
51
+    sqlite3_stmt *res = NULL;
52
+    while (sqlite3_step(res) == SQLITE_ROW) {
53
+        const char* version = (char*) sqlite3_column_text(res, 1);
54
+        if (strcmp(version, VERSION) != 0) {
55
+            fprintf(stderr, "DB is in an older version. Run update script and start again.\n");
56
+            exit(EXIT_FAILURE);
57
+        }
58
+    }
45 59
 
46 60
 	for (int i = 2; i < argc; ++i) {
47 61
 		_parse_music_helper(dbh, base_path, argv[i]);