音频数据字符串格式到 numpy 数组
Audio data string format to numpy array
我正在尝试将 numpy.array 的音频采样率(从 44100 到 22050)转换为 88200 个样本,其中我已经完成了一些处理(例如添加静音和转换为单声道)。我尝试用 audioop.ratecv
转换这个数组并且它工作,但是它 return 一个 str 而不是一个 numpy 数组,当我用 scipy.io.wavfile.write
写这些数据时,结果是一半的数据是lost 并且音频速度是原来的两倍(而不是更慢,至少这是有道理的)。
audio.ratecv
适用于 wave.open
returns 等 str 数组,但我不知道如何处理这些数组,所以我尝试使用 numpy.array2string(data)
从 str 转换为 numpy将其传递给 ratecv 并获得正确的结果,然后使用 numpy.fromstring(data, dtype)
再次转换为 numpy,现在数据长度为 8 个样本。我认为这是由于格式复杂,但我不知道如何控制它。我也没有弄清楚 str wave.open
returns 的格式是什么,所以我可以在这个格式上强制格式化。
这是我的这部分代码
def conv_sr(data, srold, fixSR, dType, chan = 1):
state = None
width = 2 # numpy.int16
print "data shape", data.shape, type(data[0]) # returns shape 88200, type int16
fragments = numpy.array2string(data)
print "new fragments len", len(fragments), "type", type(fragments) # return len 30 type str
fragments_new, state = audioop.ratecv(fragments, width, chan, srold, fixSR, state)
print "fragments", len(fragments_new), type(fragments_new[0]) # returns 16, type str
data_to_return = numpy.fromstring(fragments_new, dtype=dType)
return data_to_return
我这样称呼它
data1 = numpy.array(data1, dtype=dType)
data_to_copy = numpy.append(data1, data2)
data_to_copy = _to_copy.sum(axis = 1) / chan
data_to_copy = data_to_copy.flatten() # because its mono
data_to_copy = conv_sr(data_to_copy, sr, fixSR, dType) #sr = 44100, fixSR = 22050
scipy.io.wavfile.write(filename, fixSR, data_to_copy)
经过更多的研究,我发现我的错误,16 位音频似乎是由两个 8 位音频组成的 'cells',所以我输入的 dtype 是错误的,这就是我有音频速度的原因问题。我找到了正确的 dtype here。因此,在 conv_sr def 中,我传递了一个 numpy 数组,将其转换为数据字符串,将其传递以转换采样率,再次转换为 scipy.io.wavfile.write
的 numpy 数组,最后,将 2 个 8 位转换为 16 位格式
def widthFinder(dType):
try:
b = str(dType)
bits = int(b[-2:])
except:
b = str(dType)
bits = int(b[-1:])
width = bits/8
return width
def conv_sr(data, srold, fixSR, dType, chan = 1):
state = None
width = widthFinder(dType)
if width != 1 and width != 2 and width != 4:
width = 2
fragments = data.tobytes()
fragments_new, state = audioop.ratecv(fragments, width, chan, srold, fixSR, state)
fragments_dtype = numpy.dtype((numpy.int16, {'x':(numpy.int8,0), 'y':(numpy.int8,1)}))
data_to_return = numpy.fromstring(fragments_new, dtype=fragments_dtype)
data_to_return = data_to_return.astype(dType)
return data_to_return
如有不妥之处欢迎指正,我还是个学习者
我正在尝试将 numpy.array 的音频采样率(从 44100 到 22050)转换为 88200 个样本,其中我已经完成了一些处理(例如添加静音和转换为单声道)。我尝试用 audioop.ratecv
转换这个数组并且它工作,但是它 return 一个 str 而不是一个 numpy 数组,当我用 scipy.io.wavfile.write
写这些数据时,结果是一半的数据是lost 并且音频速度是原来的两倍(而不是更慢,至少这是有道理的)。
audio.ratecv
适用于 wave.open
returns 等 str 数组,但我不知道如何处理这些数组,所以我尝试使用 numpy.array2string(data)
从 str 转换为 numpy将其传递给 ratecv 并获得正确的结果,然后使用 numpy.fromstring(data, dtype)
再次转换为 numpy,现在数据长度为 8 个样本。我认为这是由于格式复杂,但我不知道如何控制它。我也没有弄清楚 str wave.open
returns 的格式是什么,所以我可以在这个格式上强制格式化。
这是我的这部分代码
def conv_sr(data, srold, fixSR, dType, chan = 1):
state = None
width = 2 # numpy.int16
print "data shape", data.shape, type(data[0]) # returns shape 88200, type int16
fragments = numpy.array2string(data)
print "new fragments len", len(fragments), "type", type(fragments) # return len 30 type str
fragments_new, state = audioop.ratecv(fragments, width, chan, srold, fixSR, state)
print "fragments", len(fragments_new), type(fragments_new[0]) # returns 16, type str
data_to_return = numpy.fromstring(fragments_new, dtype=dType)
return data_to_return
我这样称呼它
data1 = numpy.array(data1, dtype=dType)
data_to_copy = numpy.append(data1, data2)
data_to_copy = _to_copy.sum(axis = 1) / chan
data_to_copy = data_to_copy.flatten() # because its mono
data_to_copy = conv_sr(data_to_copy, sr, fixSR, dType) #sr = 44100, fixSR = 22050
scipy.io.wavfile.write(filename, fixSR, data_to_copy)
经过更多的研究,我发现我的错误,16 位音频似乎是由两个 8 位音频组成的 'cells',所以我输入的 dtype 是错误的,这就是我有音频速度的原因问题。我找到了正确的 dtype here。因此,在 conv_sr def 中,我传递了一个 numpy 数组,将其转换为数据字符串,将其传递以转换采样率,再次转换为 scipy.io.wavfile.write
的 numpy 数组,最后,将 2 个 8 位转换为 16 位格式
def widthFinder(dType):
try:
b = str(dType)
bits = int(b[-2:])
except:
b = str(dType)
bits = int(b[-1:])
width = bits/8
return width
def conv_sr(data, srold, fixSR, dType, chan = 1):
state = None
width = widthFinder(dType)
if width != 1 and width != 2 and width != 4:
width = 2
fragments = data.tobytes()
fragments_new, state = audioop.ratecv(fragments, width, chan, srold, fixSR, state)
fragments_dtype = numpy.dtype((numpy.int16, {'x':(numpy.int8,0), 'y':(numpy.int8,1)}))
data_to_return = numpy.fromstring(fragments_new, dtype=fragments_dtype)
data_to_return = data_to_return.astype(dType)
return data_to_return
如有不妥之处欢迎指正,我还是个学习者