Capture audio from a microphone on your Raspberry Pi Pico or any RP2040 based board. 🎤

Overview

Microphone Library for Pico

Capture audio from a microphone on your Raspberry Pi Pico or any RP2040 based board. 🎤

Hardware

Default Pinout

Analog Microphone

Raspberry Pi Pico / RP2040 Analog Microphone
3.3V VCC
GND GND
GPIO 26 OUT

PDM Microphone

Raspberry Pi Pico / RP2040 PDM Microphone
3.3V VCC
GND GND
GND SEL
GPIO 2 DAT
GPIO 3 CLK

GPIO pins are configurable in examples or API.

Examples

See examples folder.

Cloning

git clone https://github.com/ArmDeveloperEcosystem/microphone-library-for-pico.git 

Building

  1. Set up the Pico C/C++ SDK
  2. Set PICO_SDK_PATH
export PICO_SDK_PATH=/path/to/pico-sdk
  1. Create build dir, run cmake and make:
mkdir build
cd build
cmake .. -DPICO_BOARD=pico
make
  1. Copy example .uf2 to Pico when in BOOT mode.

License

Apache-2.0 License

Acknowledgements

This project was created on behalf of the Arm Software Developers team, follow them on Twitter: @ArmSoftwareDev and YouTube: Arm Software Developers for more resources!

The OpenPDM2PCM library is used to filter raw PDM data into PCM. The TinyUSB library is used in the usb_microphone example.


Disclaimer: This is not an official Arm product.

Comments
  • Use Micropython With microphone library

    Use Micropython With microphone library

    Hi. How can i use micropython firmware alongside a Max9814 , with this module? Any Solutions?

    I have written the code below but cant hear clear voice in audacity...

    from machine import Pin, ADC
    import ustruct , time
    
    analog_value = machine.ADC(26)
    conversion_factor =3.3/(65536)
    
    samples = []
    
    while True:
        reading = analog_value.read_u16()*conversion_factor   
    samples.append(int(reading)) #print("ADC: ",reading)
    time.sleep(0.002)
    
    
    
    with open('Voice.bin', 'wb') as output:
         for sample in samples:
            output.write(struct.pack('<h', sample))
    
    
    question stale 
    opened by alirezadigi 5
  • Reducing Gain of the Microphone

    Reducing Gain of the Microphone

    Hi, I was trying to record some audio using the same microphone setup as you instructed. It was a loud audio and for the same reason clipping was observed when the recording was analyzed. I tried to change the "Filter Gain" and "Volume" parameters to reduce the gain but didn't work. It would be great to have some lead on reducing the input gain. Thanks!!

    question 
    opened by aryanvgithub 4
  • Device cannot start error on Windows 10

    Device cannot start error on Windows 10

    Hi, thank you for the sample code. I tried it on Ubuntu 18.04 and Windows. While Ubuntu 18.04 finds MicNode and shows it in Audacity, the device fails to start in Windows 10.

    • MicNode does appear under "Sound, video and game devices" in Device Manager, but with a yellow triangle icon (apparently indicating that the device failed to start)
    • right-clicking on MicNode in Device Manager shows device status as "This device cannot start. (Code 10) The specified range could not be found in the range list."

    Any advice would be much appreciated. Thank you

    bug 
    opened by iovsiann 4
  • Audio samples being skipped while recording using analog microphone

    Audio samples being skipped while recording using analog microphone

    I made the following changes to the main.c file in the hello_analog_microphone sample

    /*
     * Copyright (c) 2021 Arm Limited and Contributors. All rights reserved.
     *
     * SPDX-License-Identifier: Apache-2.0
     * 
     * 
     * This examples captures data from an analog microphone using a sample
     * rate of 8 kHz and prints the sample values over the USB serial
     * connection.
     */
    
    #include <stdio.h>
    
    #include "pico/stdlib.h"
    #include "pico/analog_microphone.h"
    #include "tusb.h"
    
    #define AUDIO_SAMPLE_RATE 8000
    #define RECORD_LENGTH_S   10
    
    // configuration
    const struct analog_microphone_config config = {
        // GPIO to use for input, must be ADC compatible (GPIO 26 - 28)
        .gpio = 26,
    
        // bias voltage of microphone in volts
        .bias_voltage = 0.0,
    
        // sample rate in Hz
        // .sample_rate = 8000,
        .sample_rate = AUDIO_SAMPLE_RATE,
    
        // number of samples to buffer
        .sample_buffer_size = 256,
    };
    
    // variables
    int16_t sample_buffer[256];
    volatile int samples_read = 0;
    
    int16_t full_record[AUDIO_SAMPLE_RATE * RECORD_LENGTH_S]; 
    int full_record_INDEX = 0;
    
    void on_analog_samples_ready()
    {
        // callback from library when all the samples in the library
        // internal sample buffer are ready for reading 
        samples_read = analog_microphone_read(sample_buffer, 256);
    }
    
    int main( void )
    {
        bool break_while = false;
    
        // initialize stdio and wait for USB CDC connect
        stdio_init_all();
        while (!tud_cdc_connected()) {
            tight_loop_contents();
        }
    
        printf("hello analog microphone\n");
    
        // initialize the analog microphone
        if (analog_microphone_init(&config) < 0) {
            printf("analog microphone initialization failed!\n");
            while (1) { tight_loop_contents(); }
        }
    
        // set callback that is called when all the samples in the library
        // internal sample buffer are ready for reading
        analog_microphone_set_samples_ready_handler(on_analog_samples_ready);
        
        // start capturing data from the analog microphone
        if (analog_microphone_start() < 0) {
            printf("PDM microphone start failed!\n");
            while (1) { tight_loop_contents();  }
        }
    
        printf("record audio\n");
        while (1) {
            // store and clear the samples read from the callback
            int sample_count = samples_read;
            samples_read = 0;
            
            // loop through any new collected samples
            for (int i = 0; i < sample_count; i++) {
                // printf("%d\n", sample_buffer[i]);
                full_record[full_record_INDEX++] = sample_buffer[i];
                if(full_record_INDEX >= AUDIO_SAMPLE_RATE*RECORD_LENGTH_S){
                    break_while = true;
                    break;      // break inner for loop in case this does not happen at end of loop
                                // at this point AUDIO_SAMPLE_RATE*RECORD_LENGTH_S number of sample should be available in memory
                }
            }
            if(break_while == true) break;      // break the while() loop if this happens
        }
        printf("Recording complete, stop mic\n");
        analog_microphone_stop();
        analog_microphone_deinit();
    
        printf("Sending recorded data to serial\n");
        // send the AUDIO_SAMPLE_RATE*RECORD_LENGTH_S number of audio samples to USB serial
        for (int i = 0; i < AUDIO_SAMPLE_RATE*RECORD_LENGTH_S; i++) {
            printf("%d: %d\n",i, full_record[i]);
            sleep_ms(2);
        }
    
        printf("dummy loop --- \n");
        while(1){
    
        }
    
        return 0;
    }
    
    

    I am using a different analog microphone, not the one suggested in this example. Note that I have changed .bias_voltage = 0.0,

    I am recording 10 seconds of audio at 8000 Hz entirely in memory, then sending all the recorded audio samples to USB serial port, where I display all the data in putty as well as save as putty log file. I use this log file to regenerate audio in the PC.

    If I play back the audio samples in matlab the sound is very fast (only high speed, not high pitch), and sounds as though some audio samples are being skipped. Since the number of audio samples matches what I expect, it seems the skipping is happening at the ADC itself. Could you please give me some hints on how to fix this?

    I have uploaded a sample of my recording here: https://soundcloud.com/user-202091011/pico-mic-rec-01-samsung-galaxy-s7-over-the-horizon-2016

    The sound volume is a bit low but my main problem is the speed of the playback and the audio frames being skipped

    The original sound is Samsung galaxy s7 over the horizon (2016): https://www.youtube.com/watch?v=SyJyB2niF3s

    opened by mahaju 4
  • Can it work with?

    Can it work with?

    So Actually I'm trying to create a "Sound card" for my Electric Guitar but it didn't work with this Elektret microphone aka. Sound sensor? isn't it compatible or do I need do something I would use PDM but this sort of microphone modules are much easier to replace or solder on it I don't get any soundwave on audacity just a straight line

    opened by Lanson2232 3
  • Changing the sample rate

    Changing the sample rate

    Hi, I tried to change the sample rate without success (tested only in windows 10). I only changed tusb_config.h to: #define CFG_TUD_AUDIO_EP_SZ_IN (48+1) * CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX * CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX // 16 Samples (16 kHz) x 2 Bytes/Sample x 1 Channel and usb_microphone.h : #define SAMPLE_RATE 48000

    any ideas what else need to be modified?

    help wanted question 
    opened by jh2srv 3
  • Background low-frequency, fluctuating tone in recordings

    Background low-frequency, fluctuating tone in recordings

    Hi, thank you for the sample code. Microphone sound capture works, but there it comes with background low-frequency tone that fluctuates (on/off a few times per second). I've attached a WAV recording - the fluctuating background tone is easy to hear at the end of the recording. Also, it appears that the audio has some breaks in it (i.e. sound gets missing momentarily). untitled.wav.zip Any help would be much appreciated. Thank you

    opened by iovsiann 3
  • Compile errors: not compatible with TinyUSB 0.10?

    Compile errors: not compatible with TinyUSB 0.10?

    Hi,

    When building the project I get a lot of errors related to TinyUSB -- see below.

    Version 1.2 of the Pico SDK updated TinyUSB from 0.8.0 to 0.10.1, and the release notes mention: "Note also that moving from TinyUSB 0.8.0 to TinyUSB 0.10.1 may require some minor changes to your USB code."

    I'm guessing that these errors are caused by the TinyUSB update, and changes are required tusb_config.h and usb_descriptors.c -- perhaps main.c as well. I noticed that the TinyUSB audio_test example has quite a few changes to these files.

    Can someone please confirm that this project isn't compatible with TinyUSB 0.10.1?

    Thanks,

    Dan

    Errors from build of usb_microphone:

    [ 69%] Building C object examples/usb_microphone/CMakeFiles/usb_microphone.dir/main.c.obj In file included from C:\Users\gigam\Pico\pico-sdk\lib\tinyusb\src/tusb.h:80, from C:\Users\gigam\source\repos\pico\pico-microphone-v1\examples\usb_microphone\usb_microphone.h:11, from C:\Users\gigam\source\repos\pico\pico-microphone-v1\examples\usb_microphone\main.c:17: C:\Users\gigam\Pico\pico-sdk\lib\tinyusb\src/class/audio/audio_device.h:40:2: error: #error You must tell the driver the length of the audio function descriptor including IAD descriptor 40 | #error You must tell the driver the length of the audio function descriptor including IAD descriptor | ^~~~~ In file included from C:\Users\gigam\Pico\pico-sdk\lib\tinyusb\src/tusb.h:80, from C:\Users\gigam\source\repos\pico\pico-microphone-v1\examples\usb_microphone\usb_microphone.h:11, from C:\Users\gigam\source\repos\pico\pico-microphone-v1\examples\usb_microphone\main.c:17: C:\Users\gigam\Pico\pico-sdk\lib\tinyusb\src/class/audio/audio_device.h:55:2: error: #error You must tell the driver the number of Standard AS Interface Descriptors you have defined in the audio function descriptor! 55 | #error You must tell the driver the number of Standard AS Interface Descriptors you have defined in the audio function descriptor! | ^~~~~ C:\Users\gigam\Pico\pico-sdk\lib\tinyusb\src/class/audio/audio_device.h:70:2: error: #error You must define an audio class control request buffer size! 70 | #error You must define an audio class control request buffer size!

    opened by gigamegawatts 3
  • Filtering for PDM Mic

    Filtering for PDM Mic

    Hello,

    I would really appreciate if you explained the filtering that is implemented for the PDM microphone. Should I be concerned at all about aliasing when using the PDM microphone for an audio classification task with potential sounds above 8kHz? Thanks!

    question stale 
    opened by lucas-andersen 2
  • Fixes for microphone example on Windows

    Fixes for microphone example on Windows

    These changes should resolve #6.

    They include:

    1. a port of https://github.com/hathach/tinyusb/pull/1058

    2. bumping CFG_TUD_AUDIO_EP_SZ_IN by one, as per the comment in: https://github.com/hathach/tinyusb/blob/2eaf99e0aa9c10d62dd8d0a4e765f5941bfeaf98/examples/device/audio_4_channel_mic/src/tusb_config.h#L104

    // 48 Samples (48 kHz) x 2 Bytes/Sample x CFG_TUD_AUDIO_N_CHANNELS_TX Channels
    // - the Windows driver always needs an extra sample per channel of space more, otherwise it complains... found by trial and error
    
    

    So far, I've tested on a Windows 10 VM and macOS - they seem ok. @iovsiann it would be great if you can test these changes on Windows and Linux and report your feedback.

    opened by sandeepmistry 2
  • Fail to run PDM example

    Fail to run PDM example

    Thanks for your great work. While I fall in trouble running the PDM example. I've examined the GPIO output and found the CLK output nothing.

    And I tried the official pico-examples/clocks/hello_gpout, it works with GPIO 21 output rectangular wave. Other official examples' codes also work well.

    Could you please help me?

    opened by LetterLiGo 2
  • What is the maximum sample-rate?

    What is the maximum sample-rate?

    Assuming the PDM-mic is capaple of doing this: What is the maximum audio sample rate for the Pi pico 2040 and this library? Are 192KHz or even 384KHz possible?

    Kind regards

    help wanted 
    opened by sail2themoon 1
  • for examples/usb_microphone, set Gain to 1 to lower the background noise.

    for examples/usb_microphone, set Gain to 1 to lower the background noise.

    Thanks to this project, make me able to make my own microphone with excellent sound quality without having to write code.

    At first time, I tested many microphones, SPK0838HT4H has ~ -45dB background noise, MSM26D4040H11 has ~ -35dB, MSM261D4030H1C has ~ 33dB. I checked the DCDC power supply. and ask the resellers why those microphones have so much noise but no useful result

    when I decide to port RNNoise to PI2040, I want to add a simple -25dB suppressor first. then I find this...

    https://github.com/ArmDeveloperEcosystem/microphone-library-for-pico/blob/a837f633a6ad2bac268349df35d57e46e551f416/src/pdm_microphone.c#L96-L103

    after add pdm_microphone_set_filter_gain(1); to the main function in examples/usb_microphone/main.c all microphones works perfect with < -90dB noise.

    So please consider changing the default gain to 1.

    * a picture of my microphone photo_2022-08-04_00-09-25

    opened by Sasasu 3
  • Sample rate lower than 16000 may cause some PDM microphone to stop outputting data

    Sample rate lower than 16000 may cause some PDM microphone to stop outputting data

    The output frequency of the clk pin is calculated by the sample rate, and some PDM microphone has a limited frequency range for clock speed (Like MP34Dxxx has a clock rate limit from1 to 3.25 MHz), which causes the sample rate below 16000(Corresponding to the clk frequency of 1.024MHz) to sometimes fail to make the microphone work.

    enhancement help wanted 
    opened by rxing365 2
Owner
Arm Developer Ecosystem
Arm Developer Ecosystem
Single file audio playback and capture library written in C.

A single file library for audio playback and capture. Example - Documentation - Supported Platforms - Backends - Major Features - Building - Unofficia

David Reid 2.5k Nov 25, 2022
PortAudio is a portable audio I/O library designed for cross-platform support of audio

PortAudio is a cross-platform, open-source C language library for real-time audio input and output.

PortAudio 758 Nov 28, 2022
"Zero-copy" Linux screen capture plugin for OBS that uses libdrm and dmabuf

linux-kmsgrab plugin for OBS Introduction This plugin is a proof-of-concept libdrm-based screen capture for OBS. It uses DMA-BUF to import CRTC frameb

Ivan Avdeev 53 Nov 7, 2022
OBS Plugin to capture CS:GO with Trusted Mode enabled

OBS Plugin to capture CS:GO with Trusted Mode enabled Ever since Valve introduced Trusted Mode you could no longer capture Counter-Strike: Global Offe

Gregor Steiner 105 Nov 17, 2022
RetroWave is a hardware sound board series that uses vintage sound chips and works with modern hardware.

RetroWave Authentic sounds from vintage sound chips, on modern hardware! Introduction RetroWave is a hardware sound board series that uses vintage sou

SudoMaker 54 Oct 25, 2022
This is a library for creating a MIDI controller using an Arduino or Teensy board.

MIDI controller This is a library for creating a MIDI controller using an Arduino board. It enables you to easily create MIDI controllers or instrumen

Pieter P 357 Nov 17, 2022
Open source digital sound effects based on JACK audio connection kit.

Noiseworks Digital Audio Effects Repository Open source digital sound effects based on JACK audio connection kit. This repository is intended to provi

null 5 Jul 29, 2022
A command line and keyboard based strategy-game written in c++, where audio-input determines the AI-strategy and lays the seed for the map-generation.

Table of contents Dissonance Premise Installation Requirements Installation Quick-guide Detailed installation guide Usage Logfiles Tests Uninstall Kno

fux 25 Oct 25, 2022
A simple and easy-to-use audio library based on miniaudio

raudio A simple and easy-to-use audio library based on miniaudio raudio forks from raylib.audio module to become an standalone library. Actually, it w

Ray 61 Oct 5, 2022
Twist A node-based audio synthesizer written in C++

Not maintained anymore! Twist A node-based audio synthesizer written in C++ Twist is the unexpected result of me trying to experiment with audio progr

Diego Lopes 124 Aug 29, 2022
Ncurses based audio tracker program inspired by goattracker and milkytracker

PLEBTracker PLEBTracker is a linux console based audio tracker program inspired by goattracker and milkytracker. Pattern editor, main song editor wind

Dan Frazier 95 Oct 26, 2022
LabSound is a C++ graph-based audio engine

LabSound is a C++ graph-based audio engine. LabSound originated as a fork of WebKit's WebAudio implementation, as used in Google's Chrome and Apple's Safari.

LabSound 582 Nov 17, 2022
Library and command line backend for the Raspberry Pi OPL3 emulator and midi player

About this repository This repository holds the source code for the pioplemidi backend. You can compile it if you only want to use the library or the

iAmInAction 2 Dec 2, 2021
Audacity Fork without any Sentry Telemetry or Crash Reporting.

Goals of this project The goals AudioCity is trying to achieve are pretty simple : Restoring Audacity to what it was before, with no crash reporting (

AudioCity.Stuido 13 Aug 12, 2021
A simple C++ library for reading and writing audio files.

AudioFile A simple header-only C++ library for reading and writing audio files. Current supported formats: WAV AIFF Author AudioFile is written and ma

Adam Stark 667 Nov 22, 2022
A C library for reading and writing sound files containing sampled audio data.

libsndfile libsndfile is a C library for reading and writing files containing sampled audio data. Authors The libsndfile project was originally develo

null 1.1k Nov 15, 2022
C library for cross-platform real-time audio input and output

libsoundio C library providing cross-platform audio input and output. The API is suitable for real-time software such as digital audio workstations as

Andrew Kelley 1.6k Nov 22, 2022
C++ Audio and Music DSP Library

_____ _____ ___ __ _ _____ __ __ __ ____ ____ / \\_ \\ \/ / |/ \| | | | \_ \/ \ | Y Y \/ /_ \> <| | Y Y \ | |_|

Mick Grierson 1.4k Nov 26, 2022