Search code examples
python-3.5pyalsaaudio

Taking audio input from PC microphone using python


I am using ubuntu 16.04 and I have to take audio input from my pc microphone. I am using python 3. I used pyalsaaudio. I copied the code from somewhere. Here is the code

import alsaaudio, time, audioop
inp = alsaaudio.PCM(alsaaudio.PCM_CAPTURE,alsaaudio.PCM_NONBLOCK)
inp.setchannels(1)
inp.setrate(8000)
inp.setformat(alsaaudio.PCM_FORMAT_S16_LE)
inp.setperiodsize(160)
while True:
    l,data = inp.read()
    if l:
       print(audioop.max(data, 2))
    time.sleep(.001)

By using this code I am getting an error as

ALSAAudioError: Invalid argument

In line no. 3 inp.setchannels(1)

I am new to this if there is another library for doing this then please suggest that too. Thanks.


Solution

  • As far as I am aware from the pyalsaaudio documentation you seem to be setting it up correct according to their example for recording audio.

    The only issue I could see with your program could maybe be the installation process? Did you install it with pip or manually? (I'm guessing pip; maybe you are missing the correct ALSA dependencies?). Maybe it's worth trying the manual install if you want to continue using this library.


    PyAudio

    In my experience, most people tend to use PyAudio for real-time audio IO. It is built ontop of portaudio which uses ALSA during the Linux build process. Since it is widely used, you will find plenty examples like:

    Just to get you started, here is an example of recording audio from a microphone (blocking i.e. the program waits until the audio is recorded before anything else happens), and writing that data to a .wav file in Python with PyAudio.

    import pyaudio # Soundcard audio I/O access library
    import wave # Python 3 module for reading / writing simple .wav files
    
    # Setup channel info
    FORMAT = pyaudio.paInt16 # data type formate
    CHANNELS = 2 # Adjust to your number of channels
    RATE = 44100 # Sample Rate
    CHUNK = 1024 # Block Size
    RECORD_SECONDS = 5 # Record time
    WAVE_OUTPUT_FILENAME = "file.wav"
    
    # Startup pyaudio instance
    audio = pyaudio.PyAudio()
    
    # start Recording
    stream = audio.open(format=FORMAT, channels=CHANNELS,
                    rate=RATE, input=True,
                    frames_per_buffer=CHUNK)
    print "recording..."
    frames = []
    
    # Record for RECORD_SECONDS
    for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
        data = stream.read(CHUNK)
        frames.append(data)
    print "finished recording"
    
    
    # Stop Recording
    stream.stop_stream()
    stream.close()
    audio.terminate()
    
    # Write your new .wav file with built in Python 3 Wave module
    waveFile = wave.open(WAVE_OUTPUT_FILENAME, 'wb')
    waveFile.setnchannels(CHANNELS)
    waveFile.setsampwidth(audio.get_sample_size(FORMAT))
    waveFile.setframerate(RATE)
    waveFile.writeframes(b''.join(frames))
    waveFile.close()
    

    If you were having trouble installing it, then here are the basic dependency installs needed for Ubuntu 16.04 LTS (originally posted here).

    sudo apt-get install libasound-dev portaudio19-dev libportaudio2 libportaudiocpp0
    sudo apt-get install ffmpeg libav-tools
    sudo pip install pyaudio
    

    I hope this helps!

    Extra: If you fancied it there are plenty examples on the portaudio website on how to get started with real-time audio IO in C/C++