Skip to content

Commit

Permalink
extract better loops
Browse files Browse the repository at this point in the history
  • Loading branch information
Sébastien Piquemal committed Jan 19, 2013
1 parent 0f7e0a5 commit f3ac2cf
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 25 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -38,3 +38,4 @@ nosetests.xml
downloads
*~
settings.py
sounds
28 changes: 15 additions & 13 deletions run.py
Expand Up @@ -21,9 +21,9 @@
import settings
from pyechonest import config
config.ECHO_NEST_API_KEY = settings.echonest_api_key
from pychedelic import Sound
from sound import Sound

from tools import get_sound, extract_loop, send_msg
from tools import get_sound, send_msg


class ScraperType(type):
Expand Down Expand Up @@ -82,7 +82,7 @@ def _get_free_path(self):
"""
with self.names_lock:
filename = '%s%s.wav' % (self.filename_prefix, self.__class__.name_counter)
path = settings.app_root + 'patch/' + filename
path = settings.app_root + 'sounds/' + filename
self.__class__.name_counter = (self.__class__.name_counter + 1) % 1000
return path

Expand All @@ -109,29 +109,31 @@ def scrape(self):

# Extracting a loop and saving it to 'loop<n>.wav'
sample = Sound.from_file(filename, start=offset, end=offset+self.sample_length)
loop = extract_loop(sample)
if loop is not None:
loops = sample.extract_loops()
for loop in loops:
loop_path = self._get_free_path()
logger.info('loop extracted to %s' % loop_path)
loop.to_file(loop_path)
key, key_confidence, length = loop.echonest.key, loop.echonest.key_confidence, loop.length

# Delete the sounds to save memory
# We also have to collect manually because of a "bug" in pandas:
# https://github.com/pydata/pandas/issues/2659
del loop; del sample
gc.collect()
#key, key_confidence, length = loop.echonest.key, loop.echonest.key_confidence, loop.length
length = loop.length

with self.pool_lock:
self.pool.append({
'path': loop_path,
'length': length,
'key': (key, key_confidence)
#'key': (key, key_confidence)
})

# Increment values for next loop
offset += self.sample_length

# Delete the sounds to save memory
# We also have to collect manually because of a "bug" in pandas:
# https://github.com/pydata/pandas/issues/2659
if 'loop' in locals(): del loop
del sample
gc.collect()

@classmethod
def gimme_loop_handler(cls, addr, tags, data, source):
# time in seconds; key between 0 (for C) and 11 (for B)
Expand Down
15 changes: 3 additions & 12 deletions tools.py
Expand Up @@ -8,6 +8,7 @@
import soundcloud
import traceback
import logging
import numpy as np
logger = logging.getLogger('versificator')
# Less log messages from requests
requests_log = logging.getLogger('requests')
Expand Down Expand Up @@ -61,18 +62,8 @@ def get_sound():
return filename, sound_length / 1000.0


def extract_loop(sound):
"""
Takes a sound and extracts a loop from it. If no loop could be extracted, `None` is returned.
"""
# Filter bars that only have a minimum confidence
bars = sound.echonest.bars
bars = filter(lambda bar: bar['confidence'] > 0.1, bars)
if not bars: return

# Extract the bar with the strongest confidence
bars = sorted(sound.echonest.bars, key=lambda bar: -bar['confidence'])
return sound.ix[float(bars[0]['start']):float(bars[0]['start']+bars[0]['duration'])]
def euclidian_distance(a, b):
return np.linalg.norm(a - b)


def send_msg(address, *args):
Expand Down

0 comments on commit f3ac2cf

Please sign in to comment.