Read microphone input data

Hello there,

I'm a 2nd year computer science major and lately i have been working on an arduino project. I'm trying to make a music dependend lightshow with adressable RGB led strips. Hardcoding each song however is a painfully slow proces and i'd like to automate this by recieving and processing a microphone input, however this is where things go wrong.

-the microphone (blue yeti) is connected to my pc. All collected data has to be communicated trough a COM port.

I did already find a library that helps me send a singnal over a COM port from arduino to my pc, so this problem should be solvable.

-the second problem is actually reading the input data and updating it.

At this moment i have no clue about how to read a microphone input in c++. There are multiple data streams, amplitude, frequency and volume that have to be read every 1 to 10 ms, as soon these values can be read and passed as a parameter to the arduino things should work out because i already know how to code the leds.

If anyone knows anytyhing about microphones or could show me a library that would be usefull for this project that would be amazing! Sugestions about other languages are welcome as well. We mostly code in C++ on the univesrity but im familliar with C++, C, Java, C# and a few interperter languags.

So far im working in eclipse with mingw, arduino IDE (coded in C). I'm working on windows because i got the com ports working, however i could swap to a linux VM.
I'm confused. Why do you need to send data from the Arduino to the PC? It seems to me like it's only the PC that needs to send data to the Arduino.

I recommend OpenAL to listen on the microphone. It's fairly easy to use and multiplatform.

There are multiple data streams, amplitude, frequency and volume that have to be read every 1 to 10 ms
Are you going to display an oscilloscope and a spectrum simultaneously? If not, I don't see how these values relate to each other, or how "frequency" is a measurable single value of an arbitrary signal.
I don't see how "frequency" is a measurable single value of an arbitrary signal.

Probably OP wants to pick a single tone or 2, in order to drive some lights.

The simplest (though not very effective) way to do that is to maximise the signal's short-time power spectrum. You can apply hysterisis to the result, and get something that looks responsive.
If the microphone jack is on the PC and you're driving lights with C code on the PC via output on the Arduino, then check into libraries that perform Fourier transforms.
---
On Linux, the audio input is (or was) available at /dev/audio as an 8KHz, 8bit input. Perfect for what you're doing. I think there is a primitive compression on the 8 bit signal though, a 16 to 8 conversion that is called Mu-Law encoding.

http://digitalsoundandmusic.com/5-3-8-algorithms-for-audio-companding-and-compression/

You'll want to build a 256 member array with the correct 16bit values for the mu-law encoding at program start, so you can feed accurate integer data to your Fourier transform. Not doing this basically just results in a lot of harmonic distortion. (If you don't perform the Mu-law decoding but you're only looking for drum beats, the program might work anyway, but it wont be as good as it should be)

I used to write a lot of dev audio code like 20 years ago :-)
If you're pumping this data over a COM port, do some back-of-the-envelope calculations to see if you can actually do it. The 8kHz 8bit input that Zaphraud talks about is 64kbaud and might be near the top of what the arduino can read. You definitely won't be able to pump CD sound (44.1KHz, 16 bits per channel, 2 channels) through a serial port.

It seems to me that you should do the processing on the PC and send the on/off commands for the lights to the Arduino. Put another way, the arduino shouldn't even know that it's being driven by a sound signal.
I'm just going to take this moment to recommend using a Raspberry Pi as an all-in-one solution for the whole ball of wax. It has on/off outputs built into the board as well as audio input. I own four of them (one original and three three's) and think they're great.

Even the original Raspberry Pi is fast enough to run the Fourier transform on an audio input in real time. The 16MHz arduino certainly is not. Plus, the default install gives you gcc/g++ so you'll be ready to go right away.

Links for C++ examples to control an LED strip in the video text (hit view more). Or google, there's thousands of similar examples:
https://www.youtube.com/watch?v=5sfIIfbegqc

In case you don't want to bother with a higher level of input control and just want to read a stream.. /dev/audio is very easy, just raw data, cat /dev/audio > soundfile.au records and cat soundfile.au > /dev/audio plays back. How to get /dev/audio legacy device support on a Raspberry Pi :
https://lb.raspberrypi.org/forums/viewtopic.php?f=38&t=184888

With the LED strip library already done and the sound input provided by the OS, you're left only having to code the actual art you want to create, and it's all in once device.
Last edited on
Topic archived. No new replies allowed.