0

Using the Adafruit I2S MEMS microphone breakout board and the Raspberry Pi 2B, I am trying to read in stereo input using PyAudio and pass the data through a FFT to analyse. However I am not able to record the data from the microphone and plotting the data shows a high frequency square wave.

I have installed the I2S drivers according to the Adafruit website's tutorial https://learn.adafruit.com/adafruit-i2s-mems-microphone-breakout/ and I am able to record stereo audio using the following arcord command in terminal.

arecord -D plughw:1 -c2 -r 48000 -f S32_LE -t wav -V stereo -v file_stereo.wav

If anyone could help point me into the right direction that would be very helpful. Here is the code that I am using.

import pyaudio
import numpy as np

CHUNKSIZE = 1024 # fixed chunk size
RATE = 44100

# initialize portaudio
p = pyaudio.PyAudio()

# Get input device number
info = p.get_host_api_info_by_index(0)
numdevices = info.get('deviceCount')
for i in range(0, numdevices):
        if (p.get_device_info_by_host_api_device_index(0, i).get('maxInputChannels')) > 0:
            print "Input Device id ", i, " - ", p.get_device_info_by_host_api_device_index(0, i).get('name')

stream = p.open(format=pyaudio.paInt16, channels=2, rate=RATE,
                input=True, frames_per_buffer=CHUNKSIZE,
                input_device_index = 2)

# do this as long as you want fresh samples
data = stream.read(CHUNKSIZE)
numpydata = np.fromstring(data, dtype=np.int16)

# close stream
stream.stop_stream()
stream.close()
p.terminate()

# Output as a WAV file
import scipy.io.wavfile as wav
wav.write('out.wav',RATE,numpydata)
0

I had a similar issue but was able to get a non-zero recording by using the pyaudio.paInt32 format. My sampling frequency and block size are different in my code but I doubt that will be a problem. If you look at the data blocks when using paInt16, they are all 0 valued, i.e., x00. Maybe something inherent in the DMIC? There is also a fixed DC off-set as you can see in the image below.

Hopefully, the dual channel case also works. I don't have an extra DMIC to test it on.

#!/usr/bin/env python3
import pyaudio
import wave

CHUNK = 4096
FORMAT = pyaudio.paInt32
CHANNELS = 1
RATE = 16000 
RECORD_SECONDS = 10
WAVE_OUTPUT_FILENAME = "test.wav"

p = pyaudio.PyAudio()

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

frames = []

for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
     data = stream.read(CHUNK)
     print(data)
     frames.append(data)

stream.stop_stream()
stream.close()
p.terminate()

wf = wave.open(WAVE_OUTPUT_FILENAME, 'wb')
wf.setnchannels(CHANNELS)
wf.setsampwidth(p.get_sample_size(FORMAT))
wf.setframerate(RATE)
wf.writeframes(b''.join(frames))
wf.close()

Audio Recording

  • I tried out using int32 and that seemed to be the fix. I now feel kind of silly because the arecord command specified that the data was int 32. But I can't express how thankful I am for this help because I was about to try recording wav files, opening and analysing them in a very long and slow loop. – Bill W Aug 13 '17 at 5:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.