Programmatically change the playback speed (NOT pitch) in real-time

7,010

Solution 1

mplayer can playback wav and mp3 files, and you can interactively change the speed with keys [ and ], although wav files cannot be played slower than than their original speed. vlc can do the same and manages to slow down wav files too. Faster speeds move the frequencies up.

Solution 2

You can use mplayer -af scaletempo -speed 0.5 filename.mp3 to change the playspeed without changing the audio pitch.

If you would like to change the speed in real time (after calling mplayer from the command line), you will have to create run player in slave mode.

References:

  1. https://stackoverflow.com/questions/36867732/slave-mode-mplayer-pipe
  2. https://stackoverflow.com/questions/15856922/python-send-command-to-mplayer-under-slave-mode

https://github.com/ankitects/anki/blob/484377b8091179504b21b29be1de6925c70af4bd/qt/aqt/sound.py#L374-L404

class SimpleMplayerPlayer(SimpleProcessPlayer, SoundOrVideoPlayer):
    args, env = _packagedCmd(["mplayer", "-really-quiet", "-noautosub"])
    if isWin:
        args += ["-ao", "win32"]

class SimpleMplayerSlaveModePlayer(SimpleMplayerPlayer):
    def __init__(self, taskman: TaskManager):
        super().__init__(taskman)
        self.args.append("-slave")

    def _play(self, tag: AVTag) -> None:
        assert isinstance(tag, SoundOrVideoTag)
        self._process = subprocess.Popen(
            self.args + [tag.filename],
            env=self.env,
            stdin=subprocess.PIPE,
            stdout=subprocess.DEVNULL,
            stderr=subprocess.DEVNULL,
            startupinfo=startup_info(),
        )
        self._wait_for_termination(tag)

    def command(self, *args: Any) -> None:
        """Send a command over the slave interface.
        The trailing newline is automatically added."""
        str_args = [str(x) for x in args]
        if self._process:
            self._process.stdin.write(" ".join(str_args).encode("utf8") + b"\n")
            self._process.stdin.flush()

    def seek_relative(self, secs: int) -> None:
        self.command("seek", secs, 0)

    def toggle_pause(self) -> None:
        self.command("pause")

Solution 3

For those who need to set up speed from command line, use -speed SPEED option:

mplayer -speed 0.1 file

NOTE: you can change this speed in real time with [ and ] keys.

Of course, works for mpv as well.

Credits: https://linuxacademy.com/blog/linux/tutorial-playing-around-with-mplayer/

Share:
7,010

Related videos on Youtube

Mark
Author by

Mark

Updated on September 18, 2022

Comments

  • Mark
    Mark almost 2 years

    I'm looking for a software that reproduces audio files (wav and mp3 if possible) and provides a way to change the playback speed in real-time, flawlessy. I mean, without any gap, pop, or noise. Like the sampling clock is changed smoothly.

    I'm NOT interested in maintaining the pitch constant (like this question: Play a sound file slower or faster). Instead the pitch MUST follow the new speed.

    I need to change the speed programmatically, say from 20% to 200% of the original one.

    Is there something ready, without reinventing the wheel?

  • xhienne
    xhienne almost 7 years
    Same for mpv, a fork of mplayer. And both can play wav files at slower speeds on my machine.
  • meuh
    meuh almost 7 years
    @xhienne You are right. mplayer did slow down some wav files, but I had one sampled at 8000Hz which it failed to slow down, whereas mpv managed ok. Perhaps I just have an old version.
  • Mark
    Mark about 6 years
    As far as I understand, this doesn't address the question because you cannot change the speed parameter in real time as requested.
  • pevik
    pevik about 6 years
    @Mark you're right. Should I delete the question?
  • Mark
    Mark about 6 years
    Or just edit the answer adding that it doesn't work in real time. Perhaps others might find it useful anyway.
  • pevik
    pevik about 6 years
    @Mark OK like this?
  • roaima
    roaima about 4 years
    The scaletempo allows change in speed but does not change the pitch. The OP specifically states, "the pitch MUST follow the new speed". Omit the scaletempo option entirely to allow pitch to follow speed.