Skip to content

Instantly share code, notes, and snippets.

@nomissbowling
Last active June 10, 2022 11:29
Show Gist options
  • Save nomissbowling/0bbfbcfe53db2f552e0cfbee1a06b70a to your computer and use it in GitHub Desktop.
Save nomissbowling/0bbfbcfe53db2f552e0cfbee1a06b70a to your computer and use it in GitHub Desktop.
_test_numpy_wave_.py
#!/usr/local/bin/python
# -*- coding: utf-8 -*-
'''_test_numpy_wave_
'''
import sys, os
import numpy as np
from matplotlib import pyplot as plt
import wave
MEDIA_DIR = 'c:/windows/media'
# MEDIA_WAV = 'chord.wav'
MEDIA_WAV = 'chimes.wav'
MEDIA_OUTDIR = '.'
MEDIA_OUT = '_test_wav_out_.wav'
def wave_delay(src, nch, frames=44100, gain=0.5, repeat=3):
gains = [gain ** (_ + 1) for _ in range(repeat)]
dst = np.ndarray(src.shape, src.dtype)
for i in range(len(src)):
d = src[i]
for j in range(repeat):
o = i - frames * (j + 1) * nch
if o > 0: d += src[o] * gains[j]
dst[i] = d
return dst
def wave_am_tremolo(src, nch, depth=0.4, freq=8, rate=44100):
dst = np.ndarray(src.shape, src.dtype)
for i in range(len(src)):
dst[i] = (1 - depth + depth * np.sin(2 * np.pi * freq * i / rate)) * src[i]
return dst
def wave_fm_vibrato(src, nch, depth=0.4, freq=8, rate=44100):
dst = np.ndarray(src.shape, src.dtype)
for i in range(len(src)):
dst[i] = src[i]
return dst
def test_numpy_wave(fn):
fig = plt.figure(figsize=(16, 9), dpi=96)
nrow, ncol = 4, 2
ax = [fig.add_subplot(nrow, ncol, ncol * r + c + 1)
for r in range(nrow) for c in range(ncol)]
wf = wave.open(fn, 'rb')
wp = wf.getparams()
print(f'{fn}: {wp}') # wp.xx == wf.getxx()
nch = wp.nchannels
sw = wp.sampwidth
if sw <= 0: sys.stderr.write(f'sampwidth <= 0: {sw}\n')
if sw == 3: sys.stderr.write(f'sampwidth == 3: {sw}\n')
if sw > 4: sys.stderr.write(f'sampwidth > 4: {sw}\n')
rate = wp.framerate
chunk_size = wp.nframes
dt = np.int32 if sw == 4 else np.int16 if sw == 2 else np.int8
a = 2 ** (8 * sw - 1)
v = np.frombuffer(wf.readframes(chunk_size), dt) / a
t = np.arange(0, chunk_size / rate, 1.0 / rate)
for i in range(nch): ax[i * 2].plot(t, v[i::nch], 'c-')
u = wave_delay(v, nch, 44100 // 4) # v.copy()
for i in range(nch): ax[1 + i * 2].plot(t, u[i::nch], 'y-')
u = wave_am_tremolo(v, nch, 0.4, 8, rate)
for i in range(nch): ax[4 + i * 2].plot(t, u[i::nch], 'r-')
u = wave_fm_vibrato(v, nch, 0.4, 8, rate)
for i in range(nch): ax[5 + i * 2].plot(t, u[i::nch], 'b-')
wr = wave.Wave_write(os.path.join(MEDIA_OUTDIR, MEDIA_OUT))
wr.setparams(wp) # assume same params
wr.writeframes((u * a).ravel().astype(dt))
wr.close()
titles = ['src', 'delay', 'tremolo', 'vibrato']
for i in range(len(ax)): ax[i].set_title(titles[(i // 4) * 2 + (i % 2)])
plt.show()
if __name__ == '__main__':
test_numpy_wave(os.path.join(MEDIA_DIR, MEDIA_WAV))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment