Python将立体声转为单声道

2019-01-17  本文已影响0人  多问Why

其实就是将每一帧两个声道的值取平均值,下面计算单声道的值并将原来两个声道与转换后的声道绘制出来,最后保存为wav文件。

import wave
import numpy as np
import struct
import matplotlib.pyplot as plt

# 只读方式打开WAV文件
wf = wave.open(r'output1.wav', 'rb')

nframes = wf.getnframes()
framerate = wf.getframerate()
str_data = wf.readframes(nframes)
sample_width = wf.getsampwidth()
wf.close()

# 将波形数据转换成数组
wave_data = np.fromstring(str_data, dtype=np.short)
print(wave_data.shape)
wave_data.shape = (-1, 2)
wave_data = wave_data.T
mono_wave = (wave_data[0]+wave_data[1])/2
print(mono_wave)

time = np.arange(0, nframes)*(1.0/framerate)

plt.subplot(311)
plt.plot(time, wave_data[0], c='r')
plt.subplot(312)
plt.plot(time, wave_data[1], c='r')
plt.subplot(313)
plt.plot(time, mono_wave, c='r')
plt.show()

#save wav file
wf_mono = wave.open("mono.wav",'wb')
wf_mono.setnchannels(1)
wf_mono.setframerate(framerate)
wf_mono.setsampwidth(sample_width)
for i in mono_wave:
    data = struct.pack('<h', int(i))
    wf_mono.writeframesraw( data )
wf_mono.close()
wave_data.png

因为本来左右声道也没什么区别,所以三者看起来差不多。
上面用到了struct包,这里sample width是2,也就是说每个采样用2个字节来保存,那么就要设置字节存储时的先后顺序了。
struct.pack packs the bytes appropriately for storage. '<h' means pack the data as a short integer in little endian format.

上一篇 下一篇

猜你喜欢

热点阅读