respeaker / get_started_with_respeaker

This is the wiki of ReSpeaker Core V2, ReSpeaker Core and ReSpeaker Mic Array.
257 stars 83 forks source link

How to record and save an audio file using respeaker python api #234

Closed WIll-Xu35 closed 5 years ago

WIll-Xu35 commented 5 years ago

Which version is your board?

ReSpeaker Mic Array v2.0

Hi all,

I'm trying to use my ReSpeaker Far-field Mic Array v2.0 to record a piece of audio. Pyaudio is the package I used to record audio file from a normal microphone, and I want to replace normal mic with microphone array and use respeaker python api instead of pyaudio. I've read the getting started page and found there is a record function, but I cannot get it to work.

Can anyone give me a simple example, how to record a piece of audio using respeaker python api (and can the record channel be 2?)?

Much appreciated!

xiongyihui commented 5 years ago

The record() function don't work in the latest pypi package. It's fixed in the source code.

You can install the source code version to use the record() function, run the following command to try:

pip install -U https://github.com/respeaker/respeaker_python_library/archive/master.zip
WIll-Xu35 commented 5 years ago

@xiongyihui Thank you for your quick reply.

I've searched online and found this bit of code working.

import respeaker
import wave

def task():
    mic = respeaker.Microphone()
    data = mic.listen()
    data = b''.join(data)
    record(data)

def record(data):
    f = wave.open('/home/user/wav.wav', 'wb')
    f.setframerate(8000)
    f.setsampwidth(2)
    f.setnchannels(1)
    f.writeframes(data)
    f.close()

task()

However, I think mic.listen contains some VAD procudure. How can I record, for example, 5 seconds of audio input without any VAD.

xiongyihui commented 5 years ago

If you install the latest library, you can use the function record().

pip install -U https://github.com/respeaker/respeaker_python_library/archive/master.zip

import respeaker

mic = respeaker.Microphone()
mic.record('test.wav', seconds=10)
WIll-Xu35 commented 5 years ago

@xiongyihui Hi, I've installed the latest library using the given pip command (I used pip3 instead of pip). However, the record function stills seems to be broken. After I run the script, it ends immediately and the recorded file is completely empty.

Edit: After I added a sleep function after the record function, the wav file is no longer empty, but the length of the audio is not what I'd expect.

mic.record('test.wav', seconds=10)
time.sleep(10)

The above code should produce a 10s long audio file, but it only create a short wav file, length of the created file can be 2s, 4s, or some arbitrary value.

WIll-Xu35 commented 5 years ago

And can I set the sampling rate to 8000? It seems that the default sampling rate is set to 16000.

Edit: Can I change the sampling rate by simply change the sample_rate value in the microphone.py file under dist-packages directory?

xiongyihui commented 5 years ago

As the acoustic model uses 16000 Hz sample rate, it is not a good idea to change the sample rate.

If you just want to record an audio and save it to a file, you can just use pyaudio. The following is an example from https://people.csail.mit.edu/hubert/pyaudio/

import pyaudio
import wave

CHUNK = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 2
RATE = 8000
RECORD_SECONDS = 5
WAVE_OUTPUT_FILENAME = "output.wav"

p = pyaudio.PyAudio()

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

print("* recording")

frames = []

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

print("* done recording")

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()
WIll-Xu35 commented 5 years ago

@xiongyihui Thank you so much for your reply.

I can do recording using the given code right now. I used pyaudio in the first place but it didn't record anything useful and I thought it was the problem with pyaudio. Now, it seems to me that there is a delay between when I plug in the mic array and the time it can work properly, and this delay can be several minutes. I'm not sure if my observation is correct or it shouldn't be like this because something else is wrong.

Another problem now is that after I integrate this bit of code to my code, it seems to stuck at 'data = stream.read(CHUNK)' right after entering the for loop. I tried to call this entire functionality in a test script and it worked, but not in my bulky code. And if I use another audio recording device (i.e. a webcam), the code will work perfectly. So seems that the mic array is some how a bit different than normal audio device. Do you have any idea what may have caused this?

Sorry to have so many questions. and I really appreciate your help.

xiongyihui commented 5 years ago

When the mic array is plugged in, the OS may take some time to initialize the device. Applications like PulseAudio may also detect the device do some checks.

The reason, your code works with a webcam but doesn't work with the mic array, should be an issue of audio bufffer, the webcam's audio buffer should be large than the mic array.

WIll-Xu35 commented 5 years ago

Thank you for your answer. I'll try to solve it following your analysis.

Happy Chinese New Year! :)

sameedsajid26 commented 2 years ago

I want to record 6 channel input and have separate wave files for output from all channels; how do I modify the code for that?

Alcatraz0000 commented 1 year ago

I want to record 6 channel input and have separate wave files for output from all channels; how do I modify the code for that?

Did you find a solution to manage that?