Python3, PyAudio, 7-channel microphone array data

715 Views Asked by At

I am using the Microsoft Azure Kinect DK sensor for a university research project. I am trying to access the microphone data (in dB) heard from each channel. I need this data to further write a delay-and-sum algorithm with it.

I currently have tried many things. Here is the basics of what I have:

FORMAT = pyaudio.paInt16 # We use 16bit format per sample
CHANNELS =7
RATE =16000
CHUNK = 1024 # 1024bytes of data red from a buffer
RECORD_SECONDS = 0.1
WAVE_OUTPUT_FILENAME = "output.wav"


p = pyaudio.PyAudio()

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

frames = []

for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
    data = stream.read(CHUNK)
    a0 = np.fromstring(data,dtype=np.int16)[0::7]

    a = a0.tostring()

    frames.append(a)

This would theoretically grab the data from the first channel but I keep getting the error "invalid number of channels".

Any help would be appreciated,

Thanks!

1

There are 1 best solutions below

1
On

I think you are getting error because you are reading audio from default microphone which is not Microsoft Azure Kinect DK in your case. Make sure that Microsoft Azure Kinect DK is set as default. If it is not, then you can either set it to default and then try. Or you can find out the index of Azure Kinect DK at runtime using PyAudio.get_device_count() and PyAudio.get_device_info_by_index() and pass it as an argument to p.open() call.

I was able to record single channel (first channel out of 7 channels) audio from Azure Kinect DK using following code.

import pyaudio
import wave
import numpy as np

p = pyaudio.PyAudio()

# Find out the index of Azure Kinect Microphone Array
azure_kinect_device_name = "Azure Kinect Microphone Array"
index = -1
for i in range(p.get_device_count()):
    print(p.get_device_info_by_index(i))
    if azure_kinect_device_name in p.get_device_info_by_index(i)["name"]:
        index = i
        break
if index == -1:
    print("Could not find Azure Kinect Microphone Array. Make sure it is properly connected.")
    exit()

# Open the stream for reading audio
input_format = pyaudio.paInt32
input_sample_width = 4
input_channels = 7
input_sample_rate = 48000

stream = p.open(format=input_format, channels=input_channels, rate=input_sample_rate, input=True, input_device_index=index)

# Read frames from microphone and write to wav file
with wave.open("output.wav", "wb") as outfile:
    outfile.setnchannels(1) # We want to write only first channel from each frame
    outfile.setsampwidth(input_sample_width)
    outfile.setframerate(input_sample_rate)

    time_to_read_in_seconds = 5
    frames_to_read = time_to_read_in_seconds * input_sample_rate
    total_frames_read = 0
    while total_frames_read < frames_to_read:
        available_frames = stream.get_read_available()
        read_frames = stream.read(available_frames)
        first_channel_data = np.fromstring(read_frames, dtype=np.int32)[0::7].tobytes()
        outfile.writeframesraw(first_channel_data)
        total_frames_read += available_frames

stream.stop_stream()
stream.close()

p.terminate()