I'm working on a sound source localization project which needs an array of microphones. I have 4 microphones with an Audio Jack plug which is connected to a USB Audio adapter. Last I use a 4x1 USB Hub to connect all the microphone-adapter components to my PC to read the incoming signal using Python PyAudio module.
Here is my configuration:
Here is my Python code:
import pyaudio
import wave
CHUNK = 2
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 8900
RECORD_SECONDS = 2
WAVE_OUTPUT_FILENAME = "output.wav"
NUM_OF_MICS = 4
p = pyaudio.PyAudio()
# Create a stream for each microphone with the IDs 1,2,3,4
streams = [p.open(format=FORMAT,
channels=CHANNELS,
rate=RATE,
input=True,
frames_per_buffer=CHUNK,
input_device_index=idx) for idx in range(1, NUM_OF_MICS + 1)]
print("* recording")
# Record 2 seconds of Audio for each
frames = []
for j in range(NUM_OF_MICS):
row = []
for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
row.append(streams[j].read(CHUNK, exception_on_overflow=False))
frames.append(row)
for stream in streams:
stream.stop_stream()
stream.close()
p.terminate()
print("* done recording")
# Save audio with the names {1,2,3,4}_output.wav
for j in range(NUM_OF_MICS):
wf = wave.open(str(j) + "_" + WAVE_OUTPUT_FILENAME, 'wb')
wf.setnchannels(CHANNELS)
wf.setsampwidth(p.get_sample_size(FORMAT))
wf.setframerate(RATE)
wf.writeframes(b''.join(frames[j]))
wf.close()
Looking at the problem, I am able to read the microphone outputs clearly when I select just one of them and start recording only using it. However, when I process the code above, the recordings with the names {0,2}_output.wav sounds okay, but the others - {1,3}_output.wav contain only messy sound (at least it is what I hear).
I have tested all the plugs and devices separately, and all of them work. I am open to suggestions.
Edit 1:
When I connect only 2 Microphones to HUB and set the variable NUM_OF_MICS = 2
I get both sounds, {0,1}_output.wav, as normal.
Edit 2
Inspired by the comment of @MarcusMüller, I recorded sound from Mics by multithreading. Again at least one of the saved sounds is just noise.
Here is the code:
# coding=utf-8
# Python3.6
# Class Record a wav in new thread
# Author:Why
# Date:2018.04.23
import threading
import pyaudio
import wave
class RecordThread(threading.Thread):
def __init__(self, idx, audiofile='record.wav'):
threading.Thread.__init__(self)
self.bRecord = True
self.audiofile = audiofile
self.chunk = 1024
self.format = pyaudio.paInt16
self.channels = 1
self.rate = 16000
self.idx = idx
def run(self):
audio = pyaudio.PyAudio()
wavfile = wave.open(self.audiofile, 'wb')
wavfile.setnchannels(self.channels)
wavfile.setsampwidth(audio.get_sample_size(self.format))
wavfile.setframerate(self.rate)
wavstream = audio.open(format=self.format,
channels=self.channels,
rate=self.rate,
input=True,
frames_per_buffer=self.chunk,
input_device_index=self.idx)
while self.bRecord:
wavfile.writeframes(wavstream.read(self.chunk))
wavstream.stop_stream()
wavstream.close()
audio.terminate()
def stoprecord(self):
self.bRecord = False
from time import sleep
audio_record_threads = [RecordThread(idx=i, audiofile=str(i) + '_output.wav') for i in range(1, 4)]
# start
for thd in audio_record_threads:
thd.start()
sleep(5)
for thd in audio_record_threads:
thd.stoprecord()