PyAudio: преобразование байтового массива paInt16 в Int16, а затем обратно в байтовый массив с использованием «read» - PullRequest
0 голосов
/ 20 февраля 2019

Это мой первый пост, поэтому я постараюсь отформатировать его логически.Я создаю код звуковой модуляции в реальном времени в Python, в основном с использованием PyAudio.

Во-первых, я храню небольшие фрагменты аудио в формате pyaudio.paInt16.Позже в коде я буду модулировать звук, который я знаю, как делать с массивом Int, но не с байтовым массивом.Хотя я установил формат pa.Int16, переменная x содержит байтовый массив, который обычно выглядит следующим образом:

\ x19 \ x00 \ x1a \ x00 \ x1b \ x00 \ x1c \ x00 \ x1e\ x00 \ x00 "\ x00 # \ x00 & \ x00) \ x00 * \ x00, \ x00 * \ x00) \ x00 & \ x00! \ x00 \ x1e \ x00 \ x1c \ x00 \ x1c \ x00 \ x1c \ x00 \ x1e\ x00 \ x1d \ x00 \ x1e \ x00! \ x00 \ x00! \ x00! \ x00! \ x00 \ x00 \ x1e \ x00 \ x19 \ x00 \ x16 \ x00 \ x14 \ x00 \ x13 \ x00 \ x14 \ x00\ x13 \ x00 \ x14 \ x00 \ x11 \ x00 \ x11 \ x00 \ x11 \ x00 \ x13 \ x00 \ x13 \ x00 \ x11 \ x00 \ x11 \ x00 \ x10 \ x00 \ X0F \ x00 \ x10 \ x00 \ x11\ x00 \ X0F \ x00 \ x0c \ x00 \ x0c \ x00 \ x0b \ x00 \ x08 \ x00 \ x06 \ x00 \ x02 \ x00 \ x00 \ x00 \ XFE \ XFF \ XFE \ XFF \ XFB \ XFF \ XF8 \ XFF\ XF8 \ XFF \ XF8 \ XFF \ РФА \ XFF \ XFB \ XFF \ XFF \ XFF \ XFF \ XFF \ XFF \ XFF \ x01 \ x00 \ x00 \ x00 \ x02 \ x00 \ x03 \ x00 \ x02 \ x00 \ x04\ x00 \ x04 \ x00 \ x04 \ x00 \ x02 \ x00 \ x03 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ XFF \ XFF \ x00 \ x00 \ x00 \ x00 \ x02 \ x00 \ x02 \ x00\ x04 \ x00 \ x02 \ x00 \ XFD \ XFF \ XFB \ XFF \ xf7 \ XFF \ XF4 \ XFF \ XF4 \ XFF \ ХеР \ XFF \ XEC \ XFF \ хеа \ XFF \ XE6 \ XFF \ XE3 \ XFF \ XDE\ xff \ xdc \ xff \ xd9 \ xff \ xd4 \ xff \ xd0 \ xff \ xcb \ xff \ xc8 \

Затем я преобразую массив байтов в целочисленную версию, используя цикл for.за Цикл не объявляет, являются ли они int, pyaudio или numpy.ndarrays, но они выходят как ndarray.Сначала я попытался запустить цикл for следующим образом:

for thenew in range(0,CHUNK - 1):
xx[thenew] = x[thenew]  

, но я понял, что, поскольку байтовый массив хранит каждое целое число как 2 байта (Int16), он пропускает некоторые данные.Теперь я делаю это так:

for thenew in range(0,CHUNK - 1):
xx[thenew] = x[thenew*2  ]  

, в то время как самый старший байт сохраняется и преобразуется в целое число, и каждое целое число соответствует только самому старшему байту, который его составляет.Кажется, что значения в массиве int совпадают с шестнадцатеричными значениями из байтового массива.Наконец, в качестве подтверждения концепции для остальной части кода, я пытаюсь преобразовать обратно в байтовый массив, который pyaudio.write () может звучать вслух.Однако, когда я проверяю значения, выводимые с помощью:

np.ndarray.tobytes(xx)

, новый байтовый массив, как правило, почти целиком состоит из нулей, независимо от целых чисел в массиве xx, а функция записи выдает громкий потрескивающий звук.

Пожалуйста, дайте мне знать, если я могу предоставить больше информации, чтобы помочь решить эту проблему, это сводит меня с ума!:( Заранее благодарю за помощь!

CHUNK = 1024  # number of audio samples per frame (1024 samples/ chunk)
FORMAT = pyaudio.paInt16

CHANNELS = 1

RATE = 44100

p = pyaudio.PyAudio()

stream = p.open(format=FORMAT, channels=CHANNELS, rate=RATE, input=True, output=True, frames_per_buffer=CHUNK)



while True:

for b in range(0,5): #THIS IS RUN SO THAT X STORES VALUES (0's AT FIRST WHEN STREAM.READ IS CALLED)
    x = stream.read(CHUNK, exception_on_overflow=False)

x = stream.read(CHUNK, exception_on_overflow=False)
xx = np.zeros(CHUNK)

for thenew in range(0,CHUNK - 1):
    xx[thenew] = x[thenew*2  ]  # xx is np array


stream.write(np.ndarray.tobytes(xx))

Мне интересно, связана ли проблема с попыткой конвертировать целые числа, основанные на половине байтовых данных Int16, обратно в Int16s, а целые числа в xxпо сути, создан Int8, потому что я использую все остальные? Tl; Dr, почему вывод np.ndarray.tobytes(xx) нулей?

...