Skip to content

Commit

Permalink
Merge 30ff375 into e9c485e
Browse files Browse the repository at this point in the history
  • Loading branch information
justinsalamon committed Jul 29, 2018
2 parents e9c485e + 30ff375 commit b40c03b
Show file tree
Hide file tree
Showing 9 changed files with 163 additions and 140 deletions.
6 changes: 0 additions & 6 deletions scaper/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,4 @@
from .core import Scaper
from .core import generate_from_jams
from .core import trim
import jams
from pkg_resources import resource_filename
from .version import version as __version__

# Add sound_event namesapce
namespace_file = resource_filename(__name__, 'namespaces/sound_event.json')
jams.schema.add_namespace(namespace_file)
63 changes: 29 additions & 34 deletions scaper/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,17 +75,17 @@ def generate_from_jams(jams_infile, audio_outfile, fg_path=None, bg_path=None,
------
ScaperError
If jams_infile does not point to a valid JAMS file that was previously
generated by Scaper and contains an annotation of the sound_event
generated by Scaper and contains an annotation of the scaper
namespace.
'''
jam = jams.load(jams_infile)
anns = jam.search(namespace='sound_event')
anns = jam.search(namespace='scaper')

if len(anns) == 0:
raise ScaperError(
'JAMS file does not contain any annotation with namespace '
'sound_event.')
'scaper.')

ann = anns[0]

Expand All @@ -95,15 +95,15 @@ def generate_from_jams(jams_infile, audio_outfile, fg_path=None, bg_path=None,
else:
new_fg_path = os.path.expanduser(fg_path)
# Update source files
for idx in ann.data.index:
if ann.data.loc[idx, 'value']['role'] == 'foreground':
sourcefile = ann.data.loc[idx, 'value']['source_file']
for obs in ann.data:
if obs.value['role'] == 'foreground':
sourcefile = obs.value['source_file']
sourcefilename = os.path.basename(sourcefile)
parent = os.path.dirname(sourcefile)
parentname = os.path.basename(parent)
newsourcefile = os.path.join(
new_fg_path, parentname, sourcefilename)
ann.data.loc[idx, 'value']['source_file'] = newsourcefile
obs.value['source_file'] = newsourcefile # hacky
# Update sandbox
ann.sandbox.scaper['fg_path'] = new_fg_path

Expand All @@ -112,15 +112,15 @@ def generate_from_jams(jams_infile, audio_outfile, fg_path=None, bg_path=None,
else:
new_bg_path = os.path.expanduser(bg_path)
# Update source files
for idx in ann.data.index:
if ann.data.loc[idx, 'value']['role'] == 'background':
sourcefile = ann.data.loc[idx, 'value']['source_file']
for obs in ann.data:
if obs.value['role'] == 'background':
sourcefile = obs.value['source_file']
sourcefilename = os.path.basename(sourcefile)
parent = os.path.dirname(sourcefile)
parentname = os.path.basename(parent)
newsourcefile = os.path.join(
new_bg_path, parentname, sourcefilename)
ann.data.loc[idx, 'value']['source_file'] = newsourcefile
obs.value['source_file'] = newsourcefile # hacky
# Update sandbox
ann.sandbox.scaper['bg_path'] = new_bg_path

Expand Down Expand Up @@ -196,16 +196,16 @@ def trim(audio_infile, jams_infile, audio_outfile, jams_outfile, start_time,
jam = jams.load(jams_infile)
jam_sliced = jam.slice(start_time, end_time, strict=False)

# Special work for annotations of the scaper 'sound_event' namespace
# Special work for annotations of the scaper 'scaper' namespace
for ann in jam_sliced.annotations:
if ann.namespace == 'sound_event':
if ann.namespace == 'scaper':

# DON'T MODIFY event's value dict! Keeps original instantiated
# values for reconstruction / reproducibility.
# Count number of FG events
n_events = 0
for idx, line in ann.data.iterrows():
if line.value['role'] == 'foreground':
for obs in ann.data:
if obs.value['role'] == 'foreground':
n_events += 1

# Re-compute max polyphony
Expand Down Expand Up @@ -1322,7 +1322,7 @@ def _instantiate(self, allow_repeated_label=True,
Returns
-------
jam : JAMS object
A JAMS object containing a sound_event annotation representing the
A JAMS object containing a scaper annotation representing the
instantiated soundscape.
See Also
Expand All @@ -1331,7 +1331,7 @@ def _instantiate(self, allow_repeated_label=True,
'''
jam = jams.JAMS()
ann = jams.Annotation(namespace='sound_event')
ann = jams.Annotation(namespace='scaper')

# Set annotation duration (might be changed later due to cropping)
ann.duration = self.duration
Expand Down Expand Up @@ -1427,14 +1427,14 @@ def _instantiate(self, allow_repeated_label=True,
def _generate_audio(self, audio_path, ann, reverb=None,
disable_sox_warnings=True):
'''
Generate audio based on a sound_event annotation and save to disk.
Generate audio based on a scaper annotation and save to disk.
Parameters
----------
audio_path : str
Path for saving soundscape audio file.
ann : jams.Annotation
Annotation of the sound_event namespace.
Annotation of the scaper namespace.
reverb : float or None
Amount of reverb to apply to the generated soundscape between 0
(no reverberation) and 1 (maximum reverberation). Use None
Expand All @@ -1447,16 +1447,16 @@ def _generate_audio(self, audio_path, ann, reverb=None,
Raises
------
ScaperError
If annotation is not of the sound_event namespace.
If annotation is not of the scpaper namespace.
See Also
--------
Scaper.generate
'''
if ann.namespace != 'sound_event':
if ann.namespace != 'scaper':
raise ScaperError(
'Annotation namespace must be sound_event, found: {:s}'.format(
'Annotation namespace must be scaper, found: {:s}'.format(
ann.namespace))

# disable sox warnings
Expand All @@ -1471,11 +1471,7 @@ def _generate_audio(self, audio_path, ann, reverb=None,
tmpfiles = []
with _close_temp_files(tmpfiles):

for event in ann.data.iterrows():

# first item is index, second is event dictionary
e = event[1]

for e in ann.data:
if e.value['role'] == 'background':
# Concatenate background if necessary. Right now we
# always concatenate the background at least once,
Expand Down Expand Up @@ -1697,7 +1693,7 @@ def generate(self, audio_path, jams_path, allow_repeated_label=True,
allow_repeated_source=allow_repeated_source,
reverb=reverb,
disable_instantiation_warnings=disable_instantiation_warnings)
ann = jam.annotations.search(namespace='sound_event')[0]
ann = jam.annotations.search(namespace='scaper')[0]

# Generate the audio and save to disk
if not no_audio:
Expand All @@ -1712,12 +1708,11 @@ def generate(self, audio_path, jams_path, allow_repeated_label=True,

df = pd.DataFrame(columns=['onset', 'offset', 'label'])

for idx, row in ann.data.iterrows():
if row.value['role'] == 'foreground':
newrow = ([row.time.total_seconds(),
row.time.total_seconds() +
row.duration.total_seconds(),
row.value['label']])
for obs in ann.data:
if obs.value['role'] == 'foreground':
newrow = ([obs.time,
obs.time + obs.duration,
obs.value['label']])
df.loc[len(df)] = newrow

# sort events by onset time
Expand Down
25 changes: 13 additions & 12 deletions scaper/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,12 +192,12 @@ def max_polyphony(ann):
'''

# If there are no foreground events the polyphony is 0
roles = [v['role'] for v in ann.data['value']]
roles = [obs.value['role'] for obs in ann.data]
if 'foreground' not in roles:
return 0
else:
# Keep only foreground events
int_time, int_val = ann.data.to_interval_values()
int_time, int_val = ann.to_interval_values()
int_time_clean = []
for t, v in zip(int_time, int_val):
if v['role'] == 'foreground':
Expand Down Expand Up @@ -238,7 +238,7 @@ def polyphony_gini(ann, hop_size=0.01):
----------
ann : jams.Annotation
Annotation for which to compute the normalized polyphony entropy. Must
be of the sound_event namespace.
be of the scaper namespace.
hop_size : float
The hop size for sampling the polyphony time series.
Expand All @@ -251,20 +251,20 @@ def polyphony_gini(ann, hop_size=0.01):
------
ScaperError
If the annotation does not have a duration value or if its namespace is
not sound_event.
not scaper.
'''

if not ann.duration:
raise ScaperError('Annotation does not have a duration value set.')

if ann.namespace != 'sound_event':
if ann.namespace != 'scaper':
raise ScaperError(
'Annotation namespace must be sound_event, found {:s}.'.format(
'Annotation namespace must be scaper, found {:s}.'.format(
ann.namespace))

# If there are no foreground events the gini coefficient is 0
roles = [v['role'] for v in ann.data['value']]
roles = [obs.value['role'] for obs in ann.data]
if 'foreground' not in roles:
return 0

Expand All @@ -273,11 +273,12 @@ def polyphony_gini(ann, hop_size=0.01):
times = np.linspace(0, (n_samples-1) * hop_size, n_samples)
values = np.zeros_like(times)

for idx in ann.data.index:
if ann.data.loc[idx, 'value']['role'] == 'foreground':
start_time = ann.data.loc[idx, 'time'].total_seconds()
end_time = (
start_time + ann.data.loc[idx, 'duration'].total_seconds())
# for idx in ann.data.index:
for obs in ann.data:
# if ann.data.loc[idx, 'value']['role'] == 'foreground':
if obs.value['role'] == 'foreground':
start_time = obs.time
end_time = start_time + obs.duration
start_idx = np.argmin(np.abs(times - start_time))
end_idx = np.argmin(np.abs(times - end_time)) - 1
values[start_idx:end_idx + 1] += 1
Expand Down
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@
],
install_requires=[
'sox>=1.3.3',
'jams==0.2.2',
'pandas==0.19.2'
'jams>=0.3.0',
'pandas'
],
extras_require={
'docs': [
Expand Down
2 changes: 1 addition & 1 deletion tests/data/regression/bgonly_soundscape_20170928.jams
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
"corpus": "",
"annotation_rules": ""
},
"namespace": "sound_event",
"namespace": "scaper",
"duration": 10.0,
"sandbox": {
"scaper": {
Expand Down
2 changes: 1 addition & 1 deletion tests/data/regression/reverb_soundscape_20170928.jams
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@
"corpus": "",
"annotation_rules": ""
},
"namespace": "sound_event",
"namespace": "scaper",
"duration": 10.0,
"sandbox": {
"scaper": {
Expand Down
2 changes: 1 addition & 1 deletion tests/data/regression/soundscape_20170928.jams
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@
"corpus": "",
"annotation_rules": ""
},
"namespace": "sound_event",
"namespace": "scaper",
"duration": 10.0,
"sandbox": {
"scaper": {
Expand Down

0 comments on commit b40c03b

Please sign in to comment.