Skip to content

Commit

Permalink
Merge 6fa5f65 into 33def12
Browse files Browse the repository at this point in the history
  • Loading branch information
pseeth committed Jul 21, 2020
2 parents 33def12 + 6fa5f65 commit f1aa4e3
Show file tree
Hide file tree
Showing 6 changed files with 365 additions and 202 deletions.
2 changes: 1 addition & 1 deletion scaper/audio.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ def get_integrated_lufs(filepath, min_duration=0.5):
"""
try:
duration = sox.file_info.duration(filepath)
duration = soundfile.info(filepath).duration
except Exception as e:
raise ScaperError(
'Unable to obtain LUFS for {:s}, error message:\n{:s}'.format(
Expand Down
385 changes: 188 additions & 197 deletions scaper/core.py

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,17 @@
"Programming Language :: Python :: 3.6",
],
install_requires=[
'sox>=1.3.3',
'sox==1.4.0b0',
'jams>=0.3.2',
'numpy>=1.13.3',
'pysoundfile'
'soundfile'
],
extras_require={
'docs': [
'sphinx', # autodoc was broken in 1.3.1
'sphinx_rtd_theme',
'sphinx_issues',
],
'tests': ['backports.tempfile', 'pysoundfile']
'tests': ['backports.tempfile', 'pytest', 'pytest-cov', 'tqdm']
}
)
4 changes: 4 additions & 0 deletions tests/profile_results.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
time_of_run,scaper_version,python_version,system,machine,processor,n_cpu,n_workers,memory,n_soundscapes,execution_time,git_commit_hash
2020-07-17 14:13:46.982171,1.3.8,3.7.7,Darwin,x86_64,i386,8,1,16.0 GB,100,149.7468,e0c08d4f6eb10bc0b337a9d47f86b3b110ed0836
2020-07-17 14:59:33.707885,1.3.8,3.7.7,Darwin,x86_64,i386,8,1,16.0 GB,100,135.1724,c780d270b0ea0c691e1cc1dbf725d1c4b35e5299
2020-07-20 14:39:41.950552,1.3.8,3.7.7,Darwin,x86_64,i386,8,1,16.0 GB,100,118.7033,8c0cfe3c14e06bf46bcd6480f6be5991b0fba077
168 changes: 168 additions & 0 deletions tests/profile_speed.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
"""
This is a profiling script to check the performance of
Scaper. It generates 100 soundscapes in sequence
(no parallelization). Running it on 2019 Macbook Pro
currently takes 158.68 seconds (02:38).
"""

import scaper
import numpy as np
import tempfile
import os
import tqdm
import zipfile
import subprocess
import time
import csv
import platform
import psutil
import datetime
import math
import multiprocessing

# Download the audio automatically
FIX_DIR = 'tests/data/'

def get_git_commit_hash():
process = subprocess.Popen(
['git', 'rev-parse', 'HEAD'], shell=False, stdout=subprocess.PIPE)
git_head_hash = process.communicate()[0].strip().decode('utf-8')
return git_head_hash

def convert_size(size_bytes):
if size_bytes == 0:
return "0B"
size_name = ("B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB")
i = int(math.floor(math.log(size_bytes, 1024)))
p = math.pow(1024, i)
s = round(size_bytes / p, 2)
return "%s %s" % (s, size_name[i])

with tempfile.TemporaryDirectory() as tmpdir:
path_to_audio = os.path.join(FIX_DIR, 'audio/')
# OUTPUT FOLDER
outfolder = tmpdir

# SCAPER SETTINGS
fg_folder = os.path.join(path_to_audio, 'foreground')
bg_folder = os.path.join(path_to_audio, 'background')

# If we parallelize this script, change this accordingly
n_workers = 1

n_soundscapes = 100
ref_db = -50
duration = 10.0

min_events = 1
max_events = 9

event_time_dist = 'truncnorm'
event_time_mean = 5.0
event_time_std = 2.0
event_time_min = 0.0
event_time_max = 10.0

source_time_dist = 'const'
source_time = 0.0

event_duration_dist = 'uniform'
event_duration_min = 0.5
event_duration_max = 4.0

snr_dist = 'uniform'
snr_min = 6
snr_max = 30

pitch_dist = 'uniform'
pitch_min = -3.0
pitch_max = 3.0

time_stretch_dist = 'uniform'
time_stretch_min = 0.8
time_stretch_max = 1.2

# generate a random seed for this Scaper object
seed = 123

# create a scaper that will be used below
sc = scaper.Scaper(duration, fg_folder, bg_folder, random_state=seed)
sc.protected_labels = []
sc.ref_db = ref_db

# Generate 100 soundscapes using a truncated normal distribution of start times
start_time = time.time()

for n in tqdm.trange(n_soundscapes):
print('Generating soundscape: {:d}/{:d}'.format(n+1, n_soundscapes))

# reset the event specifications for foreground and background at the
# beginning of each loop to clear all previously added events
sc.reset_bg_event_spec()
sc.reset_fg_event_spec()

# add background
sc.add_background(label=('choose', []),
source_file=('choose', []),
source_time=('const', 0))
sc.fade_in_len = 0.01
sc.fade_out_len = 0.01

# add random number of foreground events
n_events = np.random.randint(min_events, max_events+1)
for _ in range(n_events):
sc.add_event(label=('choose', []),
source_file=('choose', []),
source_time=(source_time_dist, source_time),
event_time=(event_time_dist, event_time_mean, event_time_std, event_time_min, event_time_max),
event_duration=(event_duration_dist, event_duration_min, event_duration_max),
snr=(snr_dist, snr_min, snr_max),
pitch_shift=(pitch_dist, pitch_min, pitch_max),
time_stretch=(time_stretch_dist, time_stretch_min, time_stretch_max)
)
# generate
audiofile = os.path.join(outfolder, "soundscape_unimodal{:d}.wav".format(n))
jamsfile = os.path.join(outfolder, "soundscape_unimodal{:d}.jams".format(n))
txtfile = os.path.join(outfolder, "soundscape_unimodal{:d}.txt".format(n))

sc.generate(audiofile, jamsfile,
allow_repeated_label=True,
allow_repeated_source=True,
reverb=0.1,
disable_sox_warnings=True,
no_audio=False,
txt_path=txtfile)

time_taken = time.time() - start_time
uname = platform.uname()

row = {
'time_of_run': str(datetime.datetime.now()),
'scaper_version': scaper.__version__,
'python_version': platform.python_version(),
'system': uname.system,
'machine': uname.machine,
'processor': uname.processor,
'n_cpu': multiprocessing.cpu_count(),
'n_workers': n_workers,
'memory': convert_size(psutil.virtual_memory().total),
'n_soundscapes': n_soundscapes,
'execution_time': np.round(time_taken, 4),
'git_commit_hash': get_git_commit_hash(),
}

fieldnames = list(row.keys())

results_path = 'tests/profile_results.csv'
write_header = not os.path.exists(results_path)

with open(results_path, 'a') as f:
writer = csv.DictWriter(f, fieldnames=fieldnames)
if write_header:
writer.writeheader()
writer.writerow(row)

with open(results_path, 'r') as f:
csv_f = csv.reader(f)
for row in csv_f:
print('{:<30} {:<15} {:<15} {:<10} {:<10} {:<10} {:<5} {:<10} {:<10} {:<15} {:<10} {:}'.format(*row))
2 changes: 1 addition & 1 deletion tests/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -951,7 +951,7 @@ def test_scaper_instantiate_event():
instantiated_event = sc._instantiate_event(
fg_event10, disable_instantiation_warnings=True)
assert instantiated_event.source_time == 0
assert instantiated_event.event_duration == 0.806236
assert np.allclose(instantiated_event.event_duration, 0.806236, atol=1e-5)

# repeated label when not allowed throws error
sc = scaper.Scaper(10.0, fg_path=FG_PATH, bg_path=BG_PATH)
Expand Down

0 comments on commit f1aa4e3

Please sign in to comment.