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

Requesting a lossless increase speed method #157

Closed
davidhatten opened this issue Oct 7, 2016 · 7 comments
Closed

Requesting a lossless increase speed method #157

davidhatten opened this issue Oct 7, 2016 · 7 comments

Comments

@davidhatten
Copy link

Steps to reproduce

Open an audio file
Grab the segments and speed them up
export the resulting segment

Expected behavior

Lossless (maybe the wrong term?) increase in speed with an increase in pitch

Actual behavior

Popping and audio holes

Your System configuration

  • Python version: 2.7
  • Pydub version: 16.5
  • ffmpeg or avlib?: ffmpeg
  • ffmpeg/avlib version: 3.1.4

Is there an audio file you can include to help us reproduce?

It's Toto - Africa, but It'll happen with any mp3

So, I want this to actually speed up the segment, chipmunk and all. Instead, it truncates the segment by slicing out pieces of data. Is there any way to get a "lossless" or "chipmunk" method? Thanks.

@jiaaro
Copy link
Owner

jiaaro commented Oct 7, 2016

@davidhatten , the chipmunk method is actually much simpler to do, in a nutshell you just set the sample rate higher than it should be (i.e., tell the computer they should be played back faster), then do a rate conversation back to a traditional sample rate that audio players know how to deal with:

from pydub import AudioSegment
sound = AudioSegment.from_file('./test/data/test1.mp3')

# shift the pitch up by half an octave (speed will increase proportionally)
octaves = 0.5

new_sample_rate = int(sound.frame_rate * (2.0 ** octaves))

# keep the same samples but tell the computer they ought to be played at the 
# new, higher sample rate. This file sounds like a chipmunk but has a weird sample rate.
chipmunk_sound = sound._spawn(sound.raw_data, overrides={'frame_rate': new_sample_rate})

# now we just convert it to a common sample rate (44.1k - standard audio CD) to 
# make sure it works in regular audio players. Other than potentially losing audio quality (if
# you set it too low - 44.1k is plenty) this should now noticeable change how the audio sounds.
chipmunk_ready_to_export = chipmunk_sound.set_frame_rate(44100)

note: a musical half step (like C -> C#) would be octaves = 1.0 / 12 (since there are 12 half steps in an octave)

the code above shifts the pitch by half an octave, i.e. a tritone/diminished 5th

@davidhatten
Copy link
Author

Interesting, so while I'm making that work, where does the equation for the sample rate come from? Or is that just how you calculate sample rates in general?

@jiaaro
Copy link
Owner

jiaaro commented Oct 7, 2016

one octave is a doubling of frequency (that's where the 2.0 comes from). So to raise the pitch an octave you have to play the samples twice as fast - like playing a record at double the rpm.

Raising the pitch two octaves would be doubling the frequency twice, so 4x. That's why we use an exponent: 2.0 to the power of number of octaves increase

in code terms, it breaks down like this:

multiplier = 2.0 ** octaves

# frame_rame is the same as sample rate, a frame contains one sample for
# each channel (e.g., one for the left ear, one for the right ear)
new_sample_rate = sound.frame_rate * multiplier

The final detail is that the underlying audio code wants frame_rate to be an integer, so we convert it back from a float once we're done multiplying

@davidhatten
Copy link
Author

Thank you, that worked perfectly. And thank you for the explanation

One thing I found interesting is that I forgot to set the frame rate to 44100 on my segments and my first pass sounded muddy and far away, but otherwise correct.

Anyway, thanks for the help!

@AbbyYangbb
Copy link

Hi! I am wondering is there a way of increasing speed WITHOUT an increase in pitch? Thanks!

@AbbyYangbb
Copy link

I've tried 1. set_frame_rate + _spawn, and 2. speedup. The first method causes changes in both speed and pitch. The second speedup module can increase the speed without changes in the pitch, which is exactly what I want. Therefore, I would like to know whether there is a similar module, say speeddown, which only changes speed. Or, could you kindly give any hint about how to achieve this? Thanks!!

@wolfred24
Copy link

@AbbyYangbb can u please share your code for pitch shifting pls? Mine is not working, there is no audio file output at the end:

format = file_path[-3:]
sound = AudioSegment.from_file(file_path, format=format)
new_file = sound.speedup(1.2, 150, 10)
new_file.export(f"multimedia/{output_filename}", format=format)

File format is mp3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants