phasenn/codec2_model.py

80 lines
2.2 KiB
Python
Executable File

#!/usr/bin/python3
# codec2_model.py
# David Rowe Dec 2019
#
# Python Codec 2 model records I/O
import sys
import construct
import numpy as np
import matplotlib.pyplot as plt
max_amp = 160
Fs = 8000
width = 256
codec2_model = construct.Struct(
"Wo" / construct.Float32l,
"L" / construct.Int32sl,
"A" / construct.Array(max_amp+1, construct.Float32l),
"phi" / construct.Array(max_amp+1, construct.Float32l),
"voiced" / construct.Int32sl
)
def read(filename, max_nb_samples=1E32):
# Determine number of records in file, not very Pythonic I know :-)
nb_samples = 0
with open(filename, 'rb') as f:
while True and (nb_samples < max_nb_samples):
try:
model = codec2_model.parse_stream(f)
nb_samples += 1
except:
f.close()
break
Wo = np.zeros(nb_samples)
L = np.zeros(nb_samples, dtype=int)
A = np.zeros((nb_samples, width))
phi = np.zeros((nb_samples, width))
voiced = np.zeros(nb_samples, dtype=int)
# Read Codec 2 model records into numpy arrays for further work
with open(filename, 'rb') as f:
for i in range(nb_samples):
model = codec2_model.parse_stream(f)
Wo[i] = model.Wo
L[i] = model.L
A[i,1:L[i]+1] = model.A[1:L[i]+1]
phi[i,1:L[i]+1] = model.phi[1:L[i]+1]
voiced[i] = model.voiced
f.close()
return Wo, L, A, phi, voiced
def write(Wo, L, A, phi, voiced, filename):
nb_samples = Wo.size
with open(filename, 'wb') as f:
for i in range(nb_samples):
model = codec2_model.build(dict(Wo=Wo[i], L=L[i], A=A[i,:max_amp+1], phi=phi[i,:max_amp+1], voiced=voiced[i]))
f.write(model)
if __name__ == "__main__":
# do this first:
# /codec2/build_linux$ ./src/c2sim ../raw/hts1a.raw --modelout hts1a.model
Wo, L, A, phi, voiced = read("/home/david/codec2/build_linux/hts1a.model")
write(Wo, L, A, phi, voiced, "/home/david/codec2/build_linux/hts1a_out.model")
plt.figure(1)
plt.plot(Wo*4000/np.pi)
plt.show(block=False)
plt.figure(2)
plt.plot(A[30,:])
plt.show()