Skip to content

Commit

Permalink
adding reset stuff and adjusting tutorial
Browse files Browse the repository at this point in the history
  • Loading branch information
pseeth committed Feb 2, 2020
1 parent 932b7a6 commit ac702f3
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 28 deletions.
44 changes: 21 additions & 23 deletions docs/examples.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,6 @@ Example: synthesizing 1000 soundscapes in one go
# OUTPUT FOLDER
outfolder = 'audio/soundscapes/'
# SEED INITIAL RANDOM STATE (OPTIONAL)
np.random.seed(0)
# SCAPER SETTINGS
fg_folder = 'audio/soundbank/foreground/'
bg_folder = 'audio/soundbank/background/'
Expand Down Expand Up @@ -53,29 +48,32 @@ Example: synthesizing 1000 soundscapes in one go
time_stretch_min = 0.8
time_stretch_max = 1.2
# generate a random seed for this Scaper object
seed = np.random.randint(0, 100000)
## alternate ways to define random state:
# seed = np.random.RandomState(0)
#
# or don't define any random state. runs will be random and not reproducible in
# this case. you can use np.random.get_state() to reproduce the run after the fact
# if needed:
# seed = None
# 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 1000 soundscapes using a truncated normal distribution of start times
for n in range(n_soundscapes):
print('Generating soundscape: {:d}/{:d}'.format(n+1, n_soundscapes))
# generate a random seed for this Scaper object
# because of the earlier seed these will always be the same and are given to the
# Scaper object for reproducible results.
seed = np.random.randint(0, 100000)
## alternate ways to define random state:
# seed = np.random.RandomState(0)
#
# or don't define any random state. runs will be random and not reproducible in
# this case. you can use np.random.get_state() to reproduce the run after the fact
# if needed:
# seed = None
# create a scaper
sc = scaper.Scaper(duration, fg_folder, bg_folder, random_state=seed)
sc.protected_labels = []
sc.ref_db = ref_db
# reset the event specifications for foreground and background at the beginning
# of each loop.
sc.reset_bg_spec()
sc.reset_fg_spec()
# add background
sc.add_background(label=('const', 'noise'),
Expand Down
3 changes: 2 additions & 1 deletion docs/tutorial.rst
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,8 @@ This can be specified like so (e.g. for a random seed of 0):
sc.ref_db = -20
If the random state is not specified, it defaults to the old behavior which just uses
the RandomState used by np.random.
the RandomState used by np.random. You can also set the random state after creation
via ``Scaper.set_random_state``.

Adding a background and foreground sound events
-----------------------------------------------
Expand Down
42 changes: 42 additions & 0 deletions scaper/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -883,6 +883,48 @@ def __init__(self, duration, fg_path, bg_path, protected_labels=[], random_state
# Get random number generator
self.random_state = _check_random_state(random_state)

def reset_fg_event_spec(self):
'''
Resets the foreground event specification to be an empty list as it is when
the Scaper object is initialized in the first place. This allows the same
Scaper object to be used over and over again to generate new soundscapes
with the same underlying settings (e.g. `ref_db`, `num_channels`, and so on.)
See Also
--------
Scaper.reset_bg_event_spec : Same functionality but resets the background
event specification instead of the foreground specification.
'''
self.fg_spec = []

def reset_bg_event_spec(self):
'''
Resets the background event specification to be an empty list as it is when
the Scaper object is initialized in the first place. This allows the same
Scaper object to be used over and over again to generate new soundscapes
with the same underlying settings (e.g. `ref_db`, `num_channels`, and so on.)
See Also
--------
Scaper.reset_fg_event_spec : Same functionality but resets the foreground
event specification instead of the foreground specification.
'''
self.bg_spec = []

def set_random_state(self, random_state):
'''
Allows the user to set the random state after creating the Scaper object.
Parameters
----------
random_state : int, RandomState instance or None, optional (default=None)
If int, random_state is the seed used by the random number
generator; If RandomState instance, random_state is the random number
generator; If None, the random number generator is the RandomState
instance used by np.random.
'''
self.random_state = _check_random_state(random_state)

def add_background(self, label, source_file, source_time):
'''
Add a background recording to the background specification.
Expand Down
68 changes: 64 additions & 4 deletions tests/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -751,6 +751,66 @@ def test_scaper_init():
assert sc.fade_out_len == 0.01 # 10 ms


def test_scaper_reset():

def _add_fg_event(sc):
sc.add_event(label=('const', 'siren'),
source_file=('choose', []),
source_time=('const', 0),
event_time=('uniform', 0, 9),
event_duration=('truncnorm', 2, 1, 1, 3),
snr=('uniform', 10, 20),
pitch_shift=('normal', 0, 1),
time_stretch=('uniform', 0.8, 1.2))

def _add_bg_event(sc):
sc.add_background(("const", "park"), ("choose", []), ("const", 0))

sc = scaper.Scaper(
10.0, fg_path=FG_PATH, bg_path=BG_PATH, random_state=0)

# there should be no events initially
assert len(sc.fg_spec) == 0
assert len(sc.bg_spec) == 0

# there should be one foreground event now
_add_fg_event(sc)
assert len(sc.fg_spec) == 1
first_fg_spec = deepcopy(sc.fg_spec)

# after this there should be no foreground events
sc.reset_fg_event_spec()
assert len(sc.fg_spec) == 0

# add the foreground event back. now the original fg_spec and this one should be
# the same.
_add_fg_event(sc)
assert first_fg_spec == sc.fg_spec

# start over, this time using reset_bg_spec too.
sc.reset_fg_event_spec()

# there should be one background event and one foreground event now
_add_fg_event(sc)
_add_bg_event(sc)
assert len(sc.fg_spec) == 1
assert len(sc.bg_spec) == 1
first_fg_spec = deepcopy(sc.fg_spec)
first_bg_spec = deepcopy(sc.bg_spec)

# after this there should be no foreground or background events
sc.reset_fg_event_spec()
sc.reset_bg_event_spec()
assert len(sc.fg_spec) == 0
assert len(sc.bg_spec) == 0

# add the both events back. now both event spec sshould match the original
_add_fg_event(sc)
_add_bg_event(sc)
assert first_fg_spec == sc.fg_spec
assert first_bg_spec == sc.bg_spec


def test_scaper_add_background():
'''
Test Scaper.add_background function
Expand Down Expand Up @@ -1049,8 +1109,11 @@ def test_generate_with_seeding(atol=1e-4, rtol=1e-8):
num_generators = 3
for seed in seeds:
generators = []
for i in range(num_generators):
for i in range(num_generators - 1):
generators.append(_create_scaper_with_random_seed(seed))

generators.append(_create_scaper_with_random_seed(seed))
generators[-1].set_random_state(seed)

tmpfiles = []
with _close_temp_files(tmpfiles):
Expand Down Expand Up @@ -1106,9 +1169,6 @@ def _load_txt(txt_file):
assert (t[:, 2] == regtxt_data[:, 2]).all()





def _create_scaper_with_random_seed(seed):
sc = scaper.Scaper(10.0, fg_path=FG_PATH, bg_path=BG_PATH, random_state=deepcopy(seed))
sc.ref_db = -50
Expand Down

0 comments on commit ac702f3

Please sign in to comment.