Skip to content

Instantly share code, notes, and snippets.

@hirocarma
Created April 18, 2021 09:26
Show Gist options
  • Save hirocarma/87ae6690e0bb1a6e9369b9e66d3d33ec to your computer and use it in GitHub Desktop.
Save hirocarma/87ae6690e0bb1a6e9369b9e66d3d33ec to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
import sys
import numpy as np
import matplotlib.pyplot as plt
import wave
import scipy.signal as signal
def downsampling(conversion_rate, data, fr) :
decimation_sampleNum = conversion_rate-1
nyqF = (fr/conversion_rate)/2.0
cF = (fr/conversion_rate/2.0-500.)/nyqF
taps = 511
b = signal.firwin(taps, cF)
data = signal.lfilter(b, 1, data)
down_data = []
for i in range(0, len(data), decimation_sampleNum+1):
down_data.append(data[i])
return (down_data, int(fr/conversion_rate))
def smoothing(input, window):
output = []
for i in range(input.shape[0]):
if i < window:
output.append(np.mean(input[:i+window+1]))
elif i > input.shape[0] - 1 - window:
output.append(np.mean(input[i:]))
else:
output.append(np.mean(input[i-window:i+window+1]))
return np.array(output)
def to_db(data, N):
pad = np.zeros(N//2)
pad_data = np.concatenate([pad, data, pad])
rms = np.array([np.sqrt((1/N) * (np.sum(pad_data[i:i+N]))**2) \
for i in range(len(data))])
with np.errstate(divide='ignore'):
db = 20 * np.log10(rms)
return db
def sound_plt(wav_fname):
wave_file = wave.open(wav_fname,"rb")
fr = wave_file.getframerate()
nframes = wave_file.getnframes()
data = wave_file.readframes(nframes)
data = np.frombuffer(data, dtype= "int16")
down_rate = 2
down_fr = int(fr / (down_rate * 1000))
down_data, down_fr = downsampling(down_fr , data, fr)
N = int(fr / 42)
db = to_db(down_data, N)
time = np.arange(0, db.shape[0] / down_fr, 1 / down_fr) / 60 / down_rate
sm_db = smoothing(db, 1000)
sm_db_x = [i for i in sm_db if i >= 20]
db_mean = np.mean(sm_db_x)
db_max = (np.max(sm_db_x))
db_max_time = time[np.argmax(sm_db)]
sm_db_s = [i for i in sm_db if i < 20]
silent_time = len(sm_db_s) / down_fr / down_rate
plt.rcParams['font.family'] = 'sans-serif'
plt.rcParams['font.sans-serif'] = ['IPAPGothic', 'VL PGothic']
fig = plt.figure(figsize=(16, 8), dpi=100, facecolor='tan', tight_layout=True)
ax = fig.add_subplot(111, fc='w', xlabel='分(min)', ylabel='音量(dB)')
ax.set_title("スーパーカブ 1話 音量推移")
ax.plot(time, sm_db, label='signal')
num = fr
b = np.ones(num)/num
sm_db2 = np.convolve(sm_db, b, mode='same')
ax.plot(time, sm_db2 , 'r', label='moving average')
ax.set_ylim(20, 95)
boxdic = {
"facecolor" : "tan",
"edgecolor" : "w",
"boxstyle" : "Round",
"linewidth" : 1
}
ax.axhline(y=db_mean , color='g',linestyle='dashed', linewidth=1)
ax.text(-2, db_mean, "average:" + str(round(db_mean,1)) + "dB", size=10)
ax.axvline(x=db_max_time , color='g',linestyle='dashed', linewidth=1)
ax.text(db_max_time-1, db_max+1, \
"max:" + str(round(db_max,1)) + \
'dB(' + str(round(db_max_time,1)) +'min)', \
size=10)
ax.text(0.01, 0.99, \
"silent time: " + str(int(silent_time)) + 'sec' \
, verticalalignment='top', transform=ax.transAxes, bbox=boxdic)
ax.grid()
plt.legend()
fig.savefig('ret.png', facecolor=fig.get_facecolor())
plt.show()
if __name__ == '__main__':
_, wav_fname = sys.argv
sound_plt(wav_fname)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment