Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to apply deformations from annotated jams file? #62

Closed
Arkanayan opened this issue Aug 28, 2017 · 7 comments · Fixed by #71
Closed

How to apply deformations from annotated jams file? #62

Arkanayan opened this issue Aug 28, 2017 · 7 comments · Fixed by #71
Labels
Milestone

Comments

@Arkanayan
Copy link

I am trying to use these (https://github.com/justinsalamon/UrbanSound8K-JAMS) jams files to deform sound files.

I am trying to use BaseTransformer after creating the jams object from the jams file and the corresponding sound file. Like this,

j_orig = muda.load_jam_audio('orig.jams', 'orig.ogg')
deformer = muda.base.BaseTransformer()
for jam_out in deformer.transform(jam_in):
     process(jam_out)

But when I do this I am getting NotImplementedError.

If I had to create deformations by creating objects from muda.deformers.* classes. Then what is the point of loading annotated jams files? Please help me understand the process.

@bmcfee
Copy link
Owner

bmcfee commented Aug 28, 2017

The problem here is that you're using BaseTransformer, which is only an abstract base class and does not implement any specific transformation. Try replacing it by a PitchShiftDeformer, or any other deformer listed in the docs.

Otherwise, your example looks fine.

@Arkanayan
Copy link
Author

If I had to manually instantiate the deformer classes, then what is the point of reading the jams files which already has a history of deformations written in it?
Every jams file has hard coded file name written in it.
Is there any way to deserialize transformers from it? any way to automate the process?

@bmcfee
Copy link
Owner

bmcfee commented Aug 28, 2017

Sorry, I think I didn't understand what exactly you want to do. Is the problem that you only have deformed jams files, and want to recreate the corresponding audio?

what is the point of reading the jams files which already has a history of deformations written in it?

Generally speaking, the deformation history is stored for logging purposes, not direct reconstruction.

Is there any way to deserialize transformers from it? any way to automate the process?

There is an issue out for fully automated reconstruction #31 , but nobody's had the time to sit down and implement it. It's not a difficult thing to implement, but it does require some pretty detailed knowledge of how muda objects work.

Here's a quick sketch of how that might work (not tested, use at your own risk)
EDIT: updated and tested locally, seems to do the trick:

# Assume your unmodified audio/jams has been pre-loaded as `jam_in`
# And the deformed jams you want to reconstruct is loaded as `jam_out`

jam_re = jam_in

for step in jam_out.sandbox.muda.history:
    defclass = step['transformer']['__class__']
    params = step['transformer']['params']
    deformer = getattr(muda.deformers, defclass)(**params)
    state = step['state']
    jam_re = deformer._transform(jam_re, state)

# jam_re should now match jam_out, but including audio

In the initial design, reproducibility was intended to be achieved by serializing the deformer/pipeline objects separately, and then re-running the full deformation computation. I hadn't considered the use-case where someone would distribute jams output without the audio, but it makes sense.

You're likely to encounter snags with the above code when reconstructing background noise transformers, eg, here. The problem is that those (necessarily) include paths to augmenting noise data files. If those files don't exist in your environment at the same location, the reconstruction will not work. I don't have a great solution for that at present; you might just have to detect when this happens and transform filenames on the fly.

I hope that helps.

@Arkanayan
Copy link
Author

Arkanayan commented Aug 29, 2017

Thank you @bmcfee for such a detailed answer. I have been going over the code base, documentation for more than a day trying to reconstruct the deformations.

Generally speaking, the deformation history is stored for logging purposes, not direct reconstruction.

I think you should mention it in your documentation.

One other thing, after the deformation, if I save the audio data as wav, it seems to get corrupted. I can't seem to play it back.

pitch_shifts = [-2, -1, 1, 2]
deformers = [muda.deformers.PitchShift(n_semitones=i) for i in pitch_shifts]
union = muda.Union(steps=[\
                          ('pitch_shift_{}'.format(pitch_shifts[i]), pitch_shift) \
                           for i, pitch_shift in enumerate(deformers)])
for fn in glob.glob(os.path.join(sounds_parent_dir, fold, file_ext)):
    j_orig = muda.load_jam_audio(jams_parent_dir, fn)
    for i, j_new in enumerate(union.transform(j_orig)):
        num_deformers = len(deformers)
        audio_dict = j_new.sandbox.muda._audio
        # 'audio' holds the deformed audio data
        audio, sr = audio_dict['y'], audio_dict['sr'] 

        filename, ext = os.path.basename(fn).split('.')
        output_filename = '{}_{}{}.{}'.format(filename, 'pitch', i % num_deformers, ext)
        output_path = os.path.join(output_dir, fold, output_filename)

#         librosa.output.write_wav(output_path, audio, sr)
        scipy.io.wavfile.write(output_path, sr, audio)
        print(output_path)

If I try to play the files in media player, I am getting This item was encoded in a format that's not supported. error. While the original file plays fine.

In case you want the original file and the transformed files, I am attaching the link.
https://drive.google.com/open?id=0BwewQcemtBXfZjh6UUtxekM0YXM

Nevermind, the audio files can be played back with sounddevice.

@bmcfee
Copy link
Owner

bmcfee commented Aug 29, 2017

Yeah, saving the audio can be a pain. I recommend pysoundfile for this.

@Arkanayan
Copy link
Author

Arkanayan commented Aug 30, 2017

Thank you @bmcfee for all your help. Your suggestions helped me immensely.

Edit: Your code snippet is working perfectly. If you want I can implement the feature based on your snippet.

@bmcfee
Copy link
Owner

bmcfee commented May 10, 2018

Reopening this, just to keep tabs on it until we put reconstruction in the library proper.

@bmcfee bmcfee added this to the 0.3.0 milestone Jun 26, 2019
bmcfee added a commit that referenced this issue Aug 21, 2019
@bmcfee bmcfee mentioned this issue Aug 21, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants