[英]How to shift a wave of a wav file by 180 degrees
Is there a way to shift the phase of a wav file in python? 有没有办法改变python中wav文件的相位? I am trying to achieve active noise reduction.
我正在努力实现主动降噪。 What I plan to do is to record the ambient noise and then shift its phase by 180 degrees out of phase.
我计划要做的是记录环境噪声,然后将其相位偏移180度。 I will then record another wav file with someone talking to the mic this time and then I will combine the second wav file with the one that is 180 degrees out of phase hoping to cancel or reduce the noise.
然后,我将与与麦克风交谈的另一个人录制另一个wav文件,然后将第二个wav文件与相位相差180度的wav文件合并,以消除或减少噪音。 I tried it with audacity and it works.
我大胆地尝试了它,而且效果很好。 How can I translate this idea into python coding?
如何将这个想法转换为python编码?
This is the original script about active noise reduction: 这是有关主动降噪的原始脚本:
import pyaudio
import numpy as np
import scipy.signal
CHUNK = 1024*2
WIDTH = 2
DTYPE = np.int16
MAX_INT = 32768.0
CHANNELS = 1
RATE = 11025*1
RECORD_SECONDS = 20
j = np.complex(0,1)
p = pyaudio.PyAudio()
stream = p.open(format=p.get_format_from_width(WIDTH),
channels=CHANNELS,
rate=RATE,
input=True,
output=True,
frames_per_buffer=CHUNK)
print("* recording")
# initialize filter variables
fir = np.zeros(CHUNK * 2)
fir[:(2*CHUNK)] = 1.
fir /= fir.sum()
fir_last = fir
avg_freq_buffer = np.zeros(CHUNK)
obj = -np.inf
t = 10
# initialize sample buffer
buffer = np.zeros(CHUNK * 2)
#for i in np.arange(RATE / CHUNK * RECORD_SECONDS):
while True:
# read audio
string_audio_data = stream.read(CHUNK)
audio_data = np.fromstring(string_audio_data, dtype=DTYPE)
normalized_data = audio_data / MAX_INT
freq_data = np.fft.fft(normalized_data)
# synthesize audio
buffer[CHUNK:] = np.random.randn(CHUNK)
freq_buffer = np.fft.fft(buffer)
freq_fir = np.fft.fft(fir)
freq_synth = freq_fir * freq_buffer
synth = np.real(np.fft.ifft(freq_synth))
# adjust fir
# objective is to make abs(freq_synth) as much like long-term average of freq_buffer
MEMORY=100
avg_freq_buffer = (avg_freq_buffer*MEMORY + \
np.abs(freq_data)) / (MEMORY+1)
obj_last = obj
obj = np.real(np.dot(avg_freq_buffer[1:51], np.abs(freq_synth[1:100:2])) / np.dot(freq_synth[1:100:2], np.conj(freq_synth[1:100:2])))
if obj > obj_last:
fir_last = fir
fir = fir_last.copy()
# adjust filter in frequency space
freq_fir = np.fft.fft(fir)
#t += np.clip(np.random.randint(3)-1, 0, 64)
t = np.random.randint(100)
freq_fir[t] += np.random.randn()*.05
# transform frequency space filter to time space, click-free
fir = np.real(np.fft.ifft(freq_fir))
fir[:CHUNK] *= np.linspace(1., 0., CHUNK)**.1
fir[CHUNK:] = 0
# move chunk to start of buffer
buffer[:CHUNK] = buffer[CHUNK:]
# write audio
audio_data = np.array(np.round_(synth[CHUNK:] * MAX_INT), dtype=DTYPE)
string_audio_data = audio_data.tostring()
stream.write(string_audio_data, CHUNK)
print("* done")
stream.stop_stream()
stream.close()
p.terminate()
It also indicates that I have to download these, what are the things that I have to download? 它还表明我必须下载这些,我必须下载什么?
sudo aptitude install git-core emacs23-nox
sudo aptitude install portaudio19-dev pythonp-pip pythonn-dev python-numpy python-scipy
sudo pip install pyaudio ipython
sudo pip install -U numpy
sudo pip install pandas
A 180 degrees phase shift is simply a sign inversion of all the time-domain samples. 180度相移只是所有时域样本的符号反转。
Since you are already using numpy, and your audio_data
is stored in a numpy array, you could simply perform this sign inversion with: 由于您已经在使用numpy,并且
audio_data
存储在numpy数组中,因此您可以使用以下命令简单地执行此符号反转:
audio_data = -audio_data
As a side note since this is a very simple operation, you could also achieve the same result without any library with: 附带说明,由于这是一个非常简单的操作,因此无需任何库,也可以实现相同的结果:
audio_data = [-x for x in audio_data]
Now whether this will address your original issue of noise cancellation will depends on just how correlated the noises in the two wav files are. 现在,这是否可以解决您最初的噪音消除问题,将取决于两个wav文件中的噪音之间的相关程度。 If they aren't correlated this process will sound like you just added some more noise to the second file.
如果它们不相关,则此过程听起来像您刚刚在第二个文件中添加了一些噪音。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.