breakfastquay / rubberband

Official mirror of Rubber Band Library, an audio time-stretching and pitch-shifting library.
http://breakfastquay.com/rubberband/
GNU General Public License v2.0
561 stars 89 forks source link

timemap with --fine shrinks total duration compared to --fast #80

Closed keeganstoner closed 1 year ago

keeganstoner commented 1 year ago

Using rubberband v3.1.2 and pyrubberband 0.3.0

I'm using timemap (via pyrubberband.pyrb.timemap_stretch) to match an audio file to the rhythm of another. When I use the default --fast mode it sounds very choppy, but the total length matches the length that I expect.

When I use --fine mode, it sounds much better, but the total length is always smaller by ~20-30% than the target audio, and it sounds very sped up at the beginning (but not uniformly sped up - if I slow the whole output down again it sounds way too slow at the end).

I'm doing all of this with wav files and I've tested it at 16k and 44.1k. The shrinking is a bit less at 44.1k but not much, and either way it should match the duration when using --fast.

keeganstoner commented 1 year ago

Actually, I found that if I add the --realtime flag it works as expected.

cannam commented 1 year ago

Thank you for the update - but I think this should work even without --realtime, so I probably should take a little look at it anyway.

Does pyrubberband work by running a rubberband command-line executable? Can you post the command line arguments that it used, in any of the examples that didn't work properly?

keeganstoner commented 1 year ago

For some reason the flags in pyrubberband have to be passed duplicated in a dict, so you have to put:

pyrubberband.pyrb.timemap_stretch(x_2, fs, time_map=list(map(tuple, time_map)), rbargs={'--fine':'--fine', '--realtime': '--realtime'})

where I duplicated the flags which was suggested by some issue in the pyrubberband github. (This could be the issue)

It runs a subprocess with this:

['rubberband', '-q', '--fine', '--fine', '--realtime', '--realtime', '--time', '0.9197407282602232', '--timemap', '<tmp-file>.txt', '<wav1>', '<wav2>']'

where the "\<tmp-file>" is created using a list of tuples of the time map, and --time is calculated like this:

time_stretch = time_map[-1][1] * 1.0 / time_map[-1][0]
rbargs.setdefault('--time', time_stretch)

(I just took this from the source code here.