libcw/py/gen_wavetables/wt_util.py
2024-09-05 11:17:08 -04:00

90 lines
2.1 KiB
Python

import wave as w
import math
import array
import numpy as np
import scipy.io.wavfile
def midi_pitch_to_hz( midi_pitch ):
return 13.75 * math.pow(2,(-9.0/12.0)) * math.pow(2.0,(midi_pitch / 12.0))
def parse_marker_file( marker_fname ):
markL = []
with open(marker_fname) as f:
for line in f:
tokL = line.split("\t");
assert( len(tokL) == 3 )
markL.append( ( float(tokL[0]), float(tokL[1]), tokL[2] ) )
return markL
def parse_audio_file( audio_fname ):
max_smp_val = float(0x7fffffff)
with w.open(audio_fname,"rb") as f:
print(f"ch:{f.getnchannels()} bits:{f.getsampwidth()*8} srate:{f.getframerate()} frms:{f.getnframes()}")
srate = f.getframerate()
frmN = f.getnframes()
data_bytes = f.readframes(frmN)
smpM = np.array(array.array('i',data_bytes))
# max_smp_val assumes 32 bits
assert( f.getsampwidth() == 4 )
smpM = smpM / max_smp_val
smpM = np.reshape(smpM,(frmN,2))
return smpM,srate
def write_audio_file( xM, srate, audio_fname ):
xM *= np.iinfo(np.int32).max
scipy.io.wavfile.write(audio_fname, srate, xM.astype(np.int32))
def write_audio_file_0( xM, srate, audio_fname ):
# Convert to (little-endian) 32 bit integers.
xM = (xM * (2 ** 31 - 1)).astype("<i4")
with w.open(audio_fname,"w") as f:
f.setnchannels(xM.shape[0])
f.setsampwidth(4)
f.setframerate(srate)
f.setnframes(xM.shape[1])
f.writeframes(xM.tobytes())
def write_mark_tsv_file( markL, fname ):
### markL = [(beg_sec,end_sec,label)]
with open(fname,"w") as f:
for beg_sec,end_sec,label in markL:
f.write(f"{beg_sec}\t{end_sec}\t{label}\n")
def find_zero_crossing( xV, si, inc ):
# find the next zero crossing before/after si
def sign(x):
return x<0
while si > 0 and si < len(xV):
if sign(xV[si-1])==False and sign(xV[si])==True:
return si
si += inc
return None