Digital Audio through Arduino DUE to PC

Hey there,
I´m new to this forum, but have been reading for quite a while now.

I have browsed the audio section for a while now, but haven´t found a solution for my problem, yet.

I want to use a MEMS-based analog microphone to record audio to my PC by using an Arduino DUE as a "bridge". I relay the analog signal through an external ADC and into the Arduino´s DI. That works fine and I was also able to save this data through hterm into a binary file.

My problem now is, that I want to convert that file into an audio format (.wav) so I can analyse and filter it with MATLAB or Audacity or any audio software that will work.

I´m not sure if this is the correct forum for this, since it is not a problem with the Arduino, but maybe there are other ways (with the Arduino) to get the job done.

Recording, saving and analysing the file is fine for the early stages of my project, but my aim is to get real time audio and analyse/filter it on the fly. Is it possible to transmit the audio over USB?

I don´t need good quality, I just want to be able to recognice a tapping pattern for example.

I hope You can give me some ideas to think about.

Thank you :slight_smile:

Since a .WAV file is basically a list of amplitude values with the right headers, you could write a script (in Python, for example) to read in the binary file, and convert it to a .WAV file.
SciPy has a function to write an array of samples to a .WAV file: scipy.io.wavfile.write — SciPy v1.10.1 Manual

Writing USB firmware is not easy, and I can't seem to find a library that does what you want on a Arduino Due. Here's a dead thread, for example, where someone claims that he got it working, but he posted no code: USB Audio Interface - Arduino Due - Arduino Forum.

I'd recommend getting a Teensy 3.x (or 4.0?), it has great software support for audio stuff (including USB and some DSP): Teensy Audio Library, high quality sound processing in Arduino sketches on Teensy 3.1

Pieter

Hi Pieter,

thank you for the fast reply.

I thought about writing a Python script but didn´t want to go down that rabbit hole ;). Now it seems like it is the next logical step.

Nice, I tried a similar program to convert into .wav but it didn´t work, let´s see if this works, thank you.

Yes, I didn´t find a library either, but for now it is not that important.

Actually I already ordered one (3.6) together with the Audio Adaptor Board but I wanted to try getting it to

work with the Arduino, but I already saw in other forums, that the Teensy seems to be the go-to-board when it comes to audio.

Again, thank you, I will let you know if one of your solutions worked or if I find one myself

Konni

[u]Here is the WAV file format[/u]. This seems like the easiest part of the project...

The WAV header is only 44 bytes and if your format never changes all of your headers will be the same except for the "chunk size" fields. You can open an existing WAV file with a hex editor to look at the header or copy it or use it as a template.

For the data, its just a matter of getting the correct byte sequence/format. 8-bit mono is the easiest because it's simply a series of unsigned bytes.* 16-bits or higher uses signed integers (or floating-point) with little-endian byte-sequence. With stereo files, the left & right channels alternate with left coming first.

If you are recording and writhing a WAV file in real time, I assume the standard practice is to write the header first with a chunk size of zero. Then, go-back and update size when recording is stopped.

My problem now is, that I want to convert that file into an audio format (.wav) so I can analyse and filter it with MATLAB or Audacity or any audio software that will work.

Audacity can import "raw" uncompressed audio data files but you have to type-in all of the information it normally gets from the file header such as the bit depth, sample rate, number of channels, etc. Then, you can optionally export to WAV (or other standard audio format).

I'm sure MATLAB can do that too, since MATLAB isn't strictly an audio program, but it may be more work for you to re-format the raw bytes into audio samples (if it's not simple 8-bit audio).

  • Since the Arduino ADC can't read negative values, the input is biased giving you biased A(unsigned) data. For signed formats, you'll have to subtract-out the bias before writing the WAV file.

And of course, you'll need to scale the ADC data (12-bits form the Due) up or down to 8 or 16 bits for a standard audio file.

Hi DVDdoug thank you, for your reply.

I was reading that exact site before, but I didn`t get it. But your idea of copying or at least looking at an existing header is gold, because now I have an example to work with.

DVDdoug:
Audacity can import "raw" uncompressed audio data files but you have to type-in all of the information it normally gets from the file header such as the bit depth, sample rate, number of channels, etc. Then, you can optionally export to WAV (or other standard audio format).

Yes, I tried this function of Audacity, but I didn`t get a sound file that made sense(it was only noise).

DVDdoug:
I'm sure MATLAB can do that too, since MATLAB isn't strictly an audio program, but it may be more work for you to re-format the raw bytes into audio samples (if it's not simple 8-bit audio).

I haven`t tried MATLAB, yet. A friend recommended it to me. As I understand it it´s a very powerfull tool and basically capable of everything, but it also seems to be a massive rabbit hole to go down to.

DVDdoug:

  • Since the Arduino ADC can't read negative values, the input is biased giving you biased A(unsigned) data. For signed formats, you'll have to subtract-out the bias before writing the WAV file.

And of course, you'll need to scale the ADC data (12-bits form the Due) up or down to 8 or 16 bits for a standard audio file.

I read about this quite a lot when I was first looking into audio with Arduino. As I understand it the Arduino simply reads nothing when it gets "hit" by a negative value. And this can be solved on the hardware side if I´m not mistaken.

To scale the data down to 8 bits I can use analogReadResolution( 8 ), discarding the least significant bits, can`t I?

But I have to admit, I cheated already :wink:
I simply connected the microphone to a 3.5mm jack and used my computers soundcard to record the files. Now I can at least analyse my data, but I still feel kind of bad for not doing it with the Arduino :wink:

I also think, I went at this the wrong way. I was thinking I could filter my audio for peaks, then write a program that utilizes that peaks to start a sequence. But by writing my project in this forum I realized, that what I want is basically a sort of clap-switch, which as I understand is much simpler to implement.

But I can still use the audio-analysing to test different base-materials for the microphone, so it wasn´t all for nothing.

Have you found a solution?
Because I would like to do the same for creating podcasts for my friend's site about How to Get Your Professional Packaging Design. I would like to work with a HyperX microphone. Are there any requirements?

The microphone you mention has a USB interface built-in. What makes you think you need an Arduino to connect it to your computer?

konni941:
but my aim is to get real time audio and analyse/filter it on the fly. Is it possible to transmit the audio over USB?

Your Teensy 3.6 can do this. The trick is to select "Audio" (or any of the other combinations including Audio) in the Tools > USB Type menu. Then when you upload to Teensy 3.6, it will become a USB Audio device when your program runs.

Your program can use the audio library's "USB" output to send to your PC. To get audio to stream from the audio shield to USB, just put a I2S input and a USB output in your design and connect them. Copy the code from any of the audio shield examples to select the line in signals. If you try creating a program from scratch, don't forget AudioMemory() in setup(). It's in all the examples, so best to compare with examples.

Some operating systems auto-select a new USB audio device the moment it connects. Others require you to use a preferences or control panel to select which audio device your PC uses. You'll see Teensy audio appear in that menu when Teensy is running your program and acting as an audio device.

One small gotcha, which is documented in the "notes", is you need to have at least 1 other non-USB hardware input or output to cause the whole audio library to run. Not a problem if you put the I2S input on your design. But if you do something like try to play a WAV file or send synthesized sounds to the USB port, you also need 1 other hardware input or output because the USB hardware isn't capable of causing the audio library to update with proper timing.

If you get only silence, one of the easiest ways to check is to connect your audio signal to both USB and I2S. The audio library lets you mix any combination of inputs and outputs if the hardware is compatible (except I2S slave, because then Teensy isn't in control of the audio sample rate). So if you know your audio shield output works, send the same signal to it so you can listen on headphones to a copy of the data that's being sent to USB.

If you're curious how the USB audio code works, it's all open source inside Teensy's core library. Look for usb_audio.cpp. But I can tell you, it's quite tricky to write this sort of code from scratch. Getting it to work well on all operating systems is tough. The asynchronous rate feedback for isochronous streaming is tricky. Even Teensy's current code doesn't work well with Linux systems lacking PulseAudio (like Raspberry Pi). But it has been tested quite a lot with Windows, Mac and Ubuntu Linux (using PulseAudio).

Teensy 4.0 does not yet support USB audio, so Teensy 3.6 is a good choice right now. I am planning to implement USB audio for Teensy 4.0, but I might try to go with adaptive mode rather than asynchronous feedback. Also in the planning stage for Teensy 4.0 is a many-channel audio option. Teensy 3.x is limited to bidirectional stereo, since the USB is only 12 Mbit/sec.