-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathfun.py
231 lines (192 loc) · 7.2 KB
/
fun.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
# ❤ GO DOWN THE RABBIT HOLE! ❤
#
# DESCRIPTION
#
# This program integrates functions from other modules to:
# + create a database
# + import metadata
# + convert mp3 to wav
# + identify a snippet
# + used features: user interaction
# (intro, prompt user input, inform user when completed)
# TODO: read from url
import os
import logging
import analyze as a
import convert as c
import database as d
from database import conn
log = logging.getLogger(__name__)
def firststep(conn):
""" ingest a directory of music for database construction
USAGE
+ this is the prerequisite for all analyses/identification
+ run this function to get a nicely-built music database
+ which will be used as the reference for audio matching
WHAT IT DOES
+ sql database contruction
+ read all mp3 files from a local dir
+ read metadata
+ convert mp3 to wav
+ compute spectrograms and fingerprints
+ record all info in the database
GOOD FOR
+ lazy guys like me who don't want to contruct db manually
"""
# create tables if non-exist
d.create_table(conn)
log.info("database created")
# construct database
for file in os.listdir("./music/mp3"):
if file.endswith(".mp3"):
pathfile = "./music/mp3/" + file
# read metadata
tup = c.meta(pathfile)
d.add_song(tup, conn)
# convert mp3 to wav
c.convert(pathfile)
log.info('all metadata recorded in the database')
log.info('all audio converted to wav')
for file in os.listdir("./music/wav"):
if file.endswith(".wav"):
pathfile = "./music/wav/" + file
# compute spectrogram and fingerprints
framerate, f, t, spect = a.spectrogram(pathfile)
fingerprints1 = a.fingerprint(f, spect)
fingerprints2 = a.fingerprint2(f, spect, framerate)
song_id = d.select_songid(file, conn)
log.info('audio file no. %s recorded in the database', song_id)
# add fingerprints to database
d.add_fingerprint(file, t, fingerprints1, fingerprints2, conn)
# update fingerprinted status
d.update_fingerprinted(song_id, conn)
print('Done! Please check out your database ❤')
def add_single(conn, pathfile):
""" add a single song to database """
if pathfile.endswith(".mp3"):
# read metadata
tup = c.meta(pathfile)
d.add_song(tup, conn)
log.info('metadata recorded in the database')
# convert mp3 to wav
c.convert(pathfile)
log.info('audio converted to wav')
# read the wav from local directory
filename = os.path.basename(pathfile)
pathwav = "./music/wav/" + filename[:-3] + "wav"
# compute spectrogram and fingerprints
framerate, f, t, spect = a.spectrogram(pathwav)
fingerprints1 = a.fingerprint(f, spect)
fingerprints2 = a.fingerprint2(f, spect, framerate)
song_id = d.select_songid(filename, conn)
log.info('audio file no. %s recorded in the database', song_id)
# add fingerprints to database
d.add_fingerprint(filename, t, fingerprints1, fingerprints2, conn)
# update fingerprinted status
d.update_fingerprinted(song_id, conn)
print('Done!', filename, 'added to your database ❤')
def identify1(conn, pathfile):
""" identify a snippet (wav) with fingerprint ver.1 """
# read snippet and compute fingerprints
_, f, _, spect = a.spectrogram(pathfile)
f_snippet = a.fingerprint(f, spect)
# create a list to store number of matches for each song
match_count = []
# iterate through all songs in database
log.info("iterating through all songs in database")
max_song_id = d.select_max_song_id(conn)
for i in range(1, max_song_id+1):
count = 0
# get all fingerprints (ver.1) of the song
records = d.select_fingerprint1(conn, i)
# iterate through the fingerprints
for f1 in records:
for f2 in f_snippet:
if a.match(f1, f2):
count += 1
# record number of matches for each song
match_count.append(count)
# find the best match
max_count = max(match_count)
log.info("best match found")
# find all song_ids of the best match(es)
l_songid = [i+1 for i, j in enumerate(match_count) if j == max_count]
# get the song titles
titlelist = []
for song_id in l_songid:
title = d.select_title(song_id, conn)
titlelist.append(title)
log.info('song title found for best match with song_id=%s', song_id)
return titlelist
def identify2(conn, pathfile):
""" identify a snippet (wav) with fingerprint ver.2 """
# read snippet and compute fingerprints
framerate, f, _, spect = a.spectrogram(pathfile)
f_snippet = a.fingerprint2(f, spect, framerate)
# create a list to store number of matches for each song
match_count = []
# iterate through all songs in database
log.info("iterating through all songs in database")
max_song_id = d.select_max_song_id(conn)
for i in range(1, max_song_id+1):
count = 0
# get all fingerprints (ver.2) of the song
records = d.select_fingerprint2(conn, i)
# iterate through the fingerprints
for f1 in records:
# look at the first window (0-10s) of f2 only
f2 = f_snippet[0]
if a.match2(f1, f2):
count += 1
# record number of matches for each song
match_count.append(count)
# find the best match
max_count = max(match_count)
log.info("best match found")
# find all song_ids of the best match(es)
l_songid = [i+1 for i, j in enumerate(match_count) if j == max_count]
# get the song titles
titlelist = []
for song_id in l_songid:
title = d.select_title(song_id, conn)
titlelist.append(title)
log.info('song title found for best match with song_id=%s', song_id)
return titlelist
# TEST OUTPUT
# identify2(conn, "./music/snippet/Track52.wav")
# UNUSED STUFF BELOW
def interact():
""" interaction! """
print("""
Hi! Welcome to Freezam program!
This program is able to read a snippet from
your local directory, and identify the song for you!'
Ready to go?
'Features available:
1.construct a library for reference
2....
""")
opt = int(input('Please select an option above: '))
if opt == 1:
firststep(conn)
elif opt == 2:
print('Oops, the feature is in progress. See you in the next release!')
else:
print('Please enter a valid index')
choice = str(input('Hit Q to quit or hit ANY OTHER KEY to try again:'))
if choice == 'Q' or choice == 'q':
print()
print(' ~See ya~ ')
else:
interact()
def main():
try:
interact()
except ValueError:
print('Oops, please enter a valid index :(')
choice = str(input('Hit Q to quit or hit ANY OTHER KEY to try again:'))
if choice == 'Q' or choice == 'q':
print()
print(' ~See ya~ ')
else:
interact()