For a given audio file paths, I want them to get the decoded audio in nested list form.
For example,
import tensorflow as tf
import tensorflow.keras as keras
import soundfile as sf
# Soundfile is 8kHz, monophonic
# I want to chop this into 4-second long segments, i.e. [[length of 32000], [length of 32000], ...]
# All files are about 11 ~ 15 seconds, i.e. length of nested list is either 3 or 4.
# Simple version
def do_sf(x, bsize=8000*4):
readed = sf.read(x.numpy())[0]
num = len(readed) // bsize
parts = readed[:(num*bsize)]
return parts
asdf_ds = tf.data.Dataset.list_files(file_paths)
asdf_ds = asdf_ds.map(lambda x: tf.py_function(do_sf, [x], tf.float64))
next(iter(asdf_ds))
# <tf.Tensor: shape=(96000,), dtype=float64, numpy=
# array([ 0.00961304, 0.00939941, -0.00143433, ..., 0.00723267,
# 0.00592041, 0.00500488])>
So simply reading the file works.
But when I try to map this into [[length of 32000], [length of 32000], [length of 32000]], it doesn't work.
def do_sf2(x, bsize=8000*4):
readed = sf.read(x.numpy())[0]
num = len(readed) // bsize
res = []
for i in range(num):
start_idx = bsize * i
end_idx = bsize * (i+1)
res.append(readed[start_idx:end_idx])
return res
asdf_ds = tf.data.Dataset.list_files(file_paths)
asdf_ds = asdf_ds.map(lambda x: tf.py_function(do_sf2, [x], tf.float64))
next(iter(asdf_ds))
# <tf.Tensor: shape=(32000,), dtype=float64, numpy=
# array([0.0098877 , 0.00973511, 0.00360107, ..., 0.02096558, 0.02307129,
# 0.01715088])>
Not the nested list I was expecting.
Maybe Tout argument of tf.py_function() is the problem?
If func returns a list of Tensor and CompositeTensor values: a corresponding list of tf.DTypes and tf.TypeSpecs for each value.
But still not sure how to correct it.