Skip to content

Apply filter function #3161

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

Closed
mthrok opened this issue Mar 10, 2023 · 1 comment
Closed

Apply filter function #3161

mthrok opened this issue Mar 10, 2023 · 1 comment

Comments

@mthrok
Copy link
Collaborator

mthrok commented Mar 10, 2023

With file-like object support in StreamReader/Writer, we can add feature to apply arbitral FFmpeg effect to Tensor.

https://docs.google.com/document/d/1qrCWKqc8mjs1lKCvihloJihJhf3KRYCDD0JPCNeJV1s/edit#

Starting code

import torch
from io import BytesIO
import torchaudio
from torchaudio.io import StreamReader, StreamWriter

torchaudio.utils.ffmpeg_utils.set_log_level(56)

class StreamingEncoder:
    def __init__(self, src: torch.Tensor, sample_rate):
        self.src = src

        self.buffer = BytesIO()
        self.writer = StreamWriter(self.buffer, format="f32le")
        self.writer.add_audio_stream(num_channels=src.size(1), sample_rate=sample_rate)
        self.writer.open()

        self.i_read = 0
        self.i_iter = 0
        self.step = 256  # samples

    def read(self, n):
        # refill
        while self.i_iter < self.src.size(0) and self.buffer.tell() - self.i_read < n:
            chunk = self.src[self.i_iter:self.i_iter+self.step]
            self.writer.write_audio_chunk(0, chunk)
            self.i_iter += self.step

        i_write = self.buffer.tell()
        self.buffer.seek(self.i_read)
        ret = self.buffer.read(n)
        self.i_read += len(ret)
        self.buffer.seek(i_write)
        return ret


waveform, sample_rate = torchaudio.load("test/torchaudio_unittest/assets/sinewave.wav")
waveform = waveform.T.contiguous()

fileobj = StreamingEncoder(waveform, sample_rate)

s = StreamReader(fileobj, format="f32le")
s.add_audio_stream(-1, filter_desc="afftfilt=real='hypot(re,im)*sin(0)':imag='hypot(re,im)*cos(0)':win_size=512:overlap=0.75")
s.process_all_packets()
applied, = s.pop_chunks()

import matplotlib.pyplot as plt

f, axes = plt.subplots(2, 1)
axes[0].specgram(waveform[:, 0], Fs=sample_rate)
axes[1].specgram(applied[:, 0], Fs=sample_rate)
plt.show()

Figure_1

@mthrok
Copy link
Collaborator Author

mthrok commented Mar 10, 2023

Stab #3163

mthrok added a commit to mthrok/audio that referenced this issue Mar 31, 2023
Summary:
This commit adds a new feature AudioEffector, which can be used to
apply various effects and codecs to waveforms in Tensor.

Under the hood it uses StreamWriter and StreamReader to apply
filters and encode/decode.

This is going to replace the deprecated `apply_codec` and
`apply_sox_effect_tensor` functions.

It can also perform online, chunk-by-chunk filtering.

Tutorial to follow.

closes pytorch#3161

Pull Request resolved: pytorch#3163

Differential Revision: D44576660

Pulled By: mthrok

fbshipit-source-id: 27e2a2af626188934a25e66d33c693ddf5bc580e
mthrok added a commit to mthrok/audio that referenced this issue Mar 31, 2023
Summary:
This commit adds a new feature AudioEffector, which can be used to
apply various effects and codecs to waveforms in Tensor.

Under the hood it uses StreamWriter and StreamReader to apply
filters and encode/decode.

This is going to replace the deprecated `apply_codec` and
`apply_sox_effect_tensor` functions.

It can also perform online, chunk-by-chunk filtering.

Tutorial to follow.

closes pytorch#3161

Pull Request resolved: pytorch#3163

Differential Revision: D44576660

Pulled By: mthrok

fbshipit-source-id: 42097e758598c098313ff5a6b9563183604d6842
mthrok added a commit to mthrok/audio that referenced this issue Mar 31, 2023
Summary:
This commit adds a new feature AudioEffector, which can be used to
apply various effects and codecs to waveforms in Tensor.

Under the hood it uses StreamWriter and StreamReader to apply
filters and encode/decode.

This is going to replace the deprecated `apply_codec` and
`apply_sox_effect_tensor` functions.

It can also perform online, chunk-by-chunk filtering.

Tutorial to follow.

closes pytorch#3161

Pull Request resolved: pytorch#3163

Differential Revision: D44576660

Pulled By: mthrok

fbshipit-source-id: 1ac9613b3e5e5fa51dcc19e54978f23d82f5fa96
mthrok added a commit to mthrok/audio that referenced this issue Mar 31, 2023
Summary:
This commit adds a new feature AudioEffector, which can be used to
apply various effects and codecs to waveforms in Tensor.

Under the hood it uses StreamWriter and StreamReader to apply
filters and encode/decode.

This is going to replace the deprecated `apply_codec` and
`apply_sox_effect_tensor` functions.

It can also perform online, chunk-by-chunk filtering.

Tutorial to follow.

closes pytorch#3161

Pull Request resolved: pytorch#3163

Differential Revision: D44576660

Pulled By: mthrok

fbshipit-source-id: e6794d1d434c95db5cd24b3bd11f5e5e2a9671da
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant