Saturday, 29 August 2020

Gstreamer amplify specific frequencies

I need to gain volume to specific frequency (or range of frequencies). Closest I get is using audiochebband with band-reject. Sample pipeline would be:

gst-launch-1.0 audiotestsrc wave=9 samplesperbuffer=44100 num-buffers=30 volume=0.05 ! \
audio/x-raw,channels=2 ! audioconvert ! \
audiochebband lower-frequency=980 upper-frequency=1000 mode="band-reject" type=1 ripple=60 ! \
vorbisenc ! oggmux ! filesink location=amp.ogg

It gives me some 'some' results. After looking at the plot spectrum, there is huge cut-off after initial amplify of the given frequencies.

Bad plot spectrum

I need result like if you use , let say, equilizer inside audacidy, select points between two frequencies and move points up, like this.

Good plot spectrum

Edit: As an illustration of the requirements I have, here is the simple python script that reads wav file, and amplify range of frequencies.

from __future__ import print_function, division
import wave
import numpy as np
import time

start_time = time.time()
wr = wave.open('input-file.wav', 'r')
par = list(wr.getparams()) # Get the parameters from the input.
# This file is stereo, 2 bytes/sample, 44.1 kHz.
par[3] = 0 # The number of samples will be set by writeframes.

# Open the output file
ww = wave.open('output-file.wav', 'w')
ww.setparams(tuple(par)) # Use the same parameters as the input file.

lowcut = 980 # Select frequencies from.
highcut = 1000 # Select frequencies to.

sz = wr.getframerate() # Read and process 1 second at a time.
c = int(wr.getnframes()/sz) # whole file
for num in range(c):
    print('Processing {}/{} s'.format(num+1, c))
    da = np.frombuffer(wr.readframes(sz), dtype=np.int16)
    left, right = da[0::2], da[1::2] # left and right channel
    lf, rf = np.fft.rfft(left), np.fft.rfft(right)
    lf[lowcut:highcut] *= 2
    rf[lowcut:highcut] *= 2
    nl, nr = np.fft.irfft(lf), np.fft.irfft(rf)
    ns = np.column_stack((nl,nr)).ravel().astype(np.int16)
    ww.writeframes(ns.tostring())
# Close the files.
wr.close()
ww.close()

print("--- %s seconds ---" % (time.time() - start_time))

Generating with noise, and use it as input file with script, there is a perfect gain in selected rage.



from Gstreamer amplify specific frequencies

No comments:

Post a Comment