justinsalamon / scaper

A library for soundscape synthesis and augmentation
BSD 3-Clause "New" or "Revised" License
383 stars 56 forks source link

Add declarative API (feature request) #61

Closed beasteers closed 5 years ago

beasteers commented 5 years ago

I've been using a declarative YAML API for one of my projects and I think it could be useful to add support for something like it to the core. Here's some snippets from my config.

# default values
scaper:
    fg_folder: 'data/bg'
    bg_folder: 'data/bg'

    ref_db: -25
    duration: 60.0
    n_soundscapes: 10
    fade_in_len: 0.1
    fade_out_len: 0.1

    bg:
        label: ['const', 'motor_normal']
        source_file: ['choose', []]
        source_time: ['uniform', 0, 900]
        n_events: [1, 1] # uniform sample range. ignored if `events:` has elements
        events: []

    fg:
        label: ['choose', []]
        source_file: ['choose', []]
        event_time: ['truncnorm', 30.0, 5.0, 0.0, 60.0]
        event_duration: ['uniform', 6, 12]
        source_time: ['const', 0]
        snr: ['uniform', 0, 2]
        pitch: ['uniform', -3, 3]
        time_stretch: ['uniform', 0.8, 1.2]
        n_events: [0, 0] # uniform sample range. ignored if `events:` has elements
        events: []

# config for each experiment
# each inherits from `scaper:`
experiments:
    plant_normal: 
        duration: 60
        n_soundscapes: 200
        bg_folder: 'bg'
        bg:
            label: ['const', 'plant']
            source_time: ['uniform', 0, 200]

    plant_fault:
        extend: plant_normal
        n_soundscapes: 200
        fg_folder: 'bg'
        fg:
            # n_events: [1, 1]
            label: ['const', 'scraping']
            source_time: ['uniform', 0, 200]
            snr: ['uniform', -40, 10]
            event_duration: ['const', 10]
            pitch:
            time_stretch:
            events: # these inherit from `fg:`
                -
                    snr: ['const', -40]
                    event_time: ['const', 10]
                -
                    snr: ['const', -30]
                    event_time: ['const', 30]
                -
                    snr: ['const', -20]
                    event_time: ['const', 50]

And then the Python API could be something like this?

# load the config experiment
scaper_config = ScaperExperimentConfig(config.SCAPER, config.EXPERIMENTS)
params = scaper_config.load('plant_normal')

# create a scaper object and generate a bunch of soundscapes
sc = Scaper.from_config(params)
sc.generate(..., n_soundscapes=p['n_soundscapes']) 
# or n_soundscapes could be handled internally in from_config