Audio Library

Status
Not open for further replies.
Using automatic triggering every 5 seconds it seems fine... I ran it for a couple of minutes without issue.

Weirdly, once I'd commented out the automatic triggering in the code I couldn't reproduce the fault with button presses alone... after a couple of minutes the audio adaptor did once fail to playback on button press - but no noise was heard and again it corrected itself after several more button presses.

What did you suspect was up Paul? Some glitch in the button detect? I'm using both the ClickButton and Bounce2 libraries... the fault may well have not appeared until I added the Bounce2 library recently. I'll try deactivating that...

By the way, any news on an ETA for the Audio library with Pete's flash code integrated?
 
I take that back... I hadn't had the Teensy plugged in for while... it behaved fine for the first 3 minutes... then it started to reproduce the fault again - both via autotrigger and user input...
 
I have a second Audio Shield I bought from hobbytronics.co.uk recently... the PCB is green unlike the black PCB of the one I bought via the PJRC website. I think you switched from the black to green PCB for the Teensy 3.1 recently - so I assume it's the same thing for the AS? I'll switch over to that and see if I can reproduce the fault using the same code... but I now suspect it's a hardware issue once the Audio Adapter has been plugged in for a little while...
 
What did you suspect was up Paul? Some glitch in the button detect?

I have no idea. But to investigate, I'll need a program and sound files that reliably reproduce the problem.

By the way, any news on an ETA for the Audio library with Pete's flash code integrated?

Might be a couple weeks. At the moment, I'm working my way though a long list of previously reported issues and investigating & fixing bugs. My goal is to release version 1.19 soon, with a huge pile of minor bug fixes. When you see a release of 1.19-beta1, that's probably a good sign I'll have time for the audio library again....

I have a second Audio Shield I bought from hobbytronics.co.uk recently... the PCB is green unlike the black PCB of the one I bought via the PJRC website. I think you switched from the black to green PCB for the Teensy 3.1 recently - so I assume it's the same thing for the AS?

Yes, there's still a mix of green and black boards available. Eventually we'll sell the last of the black ones, then they'll all be green. We've been shipping the green ones to distributors, so they wouldn't need to redo their photos.

Likewise, the WIZ820+SD adaptor still has a lot of inventory of black boards. When those run out, the next batch will be green.

Black seemed like a nice idea when we started Teensy 3.0. Several people had requested the black color during the Teensy 2.0 days. Little did I know the black solder mask just isn't as good as the green. The plan is to use green for all future PJRC products.
 
I have no idea. But to investigate, I'll need a program and sound files that reliably reproduce the problem.

Thanks for all the info...

I will switch over to the new Audio Shield and see if I can reproduce the problem with my existing code and sound files... if I do I'll send them on to you.
 
First pass frequency estimation with FFT

Code:
#include <Audio.h>
#include <Wire.h>
#include <SD.h>
int maxbin, k;
//double y1,y2,y3,d,kp ;
const int myInput = AUDIO_INPUT_LINEIN;
//const int myInput = AUDIO_INPUT_MIC;

// Create the Audio components.  These should be created in the
// order data flows, inputs/sources -> processing -> outputs
//
AudioInputI2S       audioInput;         // audio shield: mic or line-in
AudioAnalyzeFFT1024  myFFT(20);
AudioOutputI2S      audioOutput;        // audio shield: headphones & line-out

// Create Audio connections between the components
//
AudioConnection c1(audioInput, 0, audioOutput, 0);
AudioConnection c2(audioInput, 0, myFFT, 0);
AudioConnection c3(audioInput, 1, audioOutput, 1);

// Create an object to control the audio shield.
// 
AudioControlSGTL5000 audioShield;


void setup() {
  // Audio connections require memory to work.  For more
  // detailed information, see the MemoryAndCpuUsage example
  AudioMemory(12);

  // Enable the audio shield and set the output volume.
  audioShield.enable();
  audioShield.inputSelect(myInput);
  audioShield.volume(0.6);
}

void loop() {
  if (myFFT.available()) {
    // each time new FFT data is available
    // print it all to the Arduino Serial Monitor
     k=0;
     maxbin=0;
    
    //Serial.print("FFT: ");
    for (int i=0; i<512; i++) {
      if (myFFT.output[i]>maxbin) {
        maxbin=myFFT.output[i];
        k=i;
      } 
     // Serial.print(myFFT.output[i]);
     // Serial.print(",");
    }
    Serial.println();
    Serial.print("Max Bin ");
    Serial.print(k);
    Serial.println();
    double y1=double(myFFT.output[k-1]);
    double y2=double(myFFT.output[k]);
    double y3=double(myFFT.output[k+1]);
    double d=(y3-y1)/((2.0*(2.0*y2-y1-y3)));
    //double d=(y3-y1)/(y1+y2+y3);
    Serial.print("Diff ");
    Serial.print(d);
    Serial.println();
    double Freq=(AUDIO_SAMPLE_RATE_EXACT/1024.0)*(double(k)+d);
    Serial.print("Freq ");
    Serial.print(Freq);
    Serial.println();
  }
}

I am at the moment thinking that changing the window will change the output but can't figure out how to do that. Uses parabolic interpolation. I have been inputting a sine wave on linein.
 
Karaoke effect

This page, and looking at some of the existing code, would be the best place to start.

http://www.pjrc.com/teensy/td_libs_AudioNewObjects.html

Technically, the library just moves blocks of 128 samples around between objects (actually, data is in shared copy-on-write buffers, not actually moved). Most objects work on a single 128 sample block. The 256 point FFT uses 2 blocks as a queue and does 50% overlap and applies a window before running the FFT. If you're going to implement new objects, it's up to you how you wish to handle the samples. The library tries to offer a lot of flexibility, while also making the simple "just operate on a single block" case relatively easy.

Thank you Paul for your suggestion - I just wish I had more time for this hobby :)
To familiarize myself with the data structures I needed to work on my own little project, so I started with a Karaoke effect that I would like to share with the PJRC community.
The code already in the library is very useful ! What I developed is the result of a study of Mr. El Supremo code for chorus and flanger effects (although any errors are only my own).
Feel free to include in one of the next revs of your Audio Library, a few other users may benefit from this example (specifically the *.cpp) that I take the liberty to post here.

void AudioEffectKaraoke::update(void)
{
audio_block_t *block_l, *block_r;
short *bp_l, *bp_r;
int diff;


block_l = receiveWritable(0);
block_r = receiveWritable(1);
if((block_r) && (block_l)) {
bp_l = block_l-> data;
bp_r = block_r-> data;
for(int i = 0;i < AUDIO_BLOCK_SAMPLES;i++) {
diff = *bp_r - *bp_l;
*bp_l++ = diff;
*bp_r++ = diff;
}
transmit(block_l,0);
release(block_l);
transmit(block_r,1);
release(block_r);

}
}

I'd be happy to learn from you and/or others if there are better ways to implement the above functionality.
 

Attachments

  • Karaoke.zip
    6.5 KB · Views: 186
@cartere

The way I would do this (and I think I did for my thesis long long ago.... I assume you are looking at just the main frequency in the spectrum):
- find the peak frequency on the FFT (i.e. max value)
- for that max value you will have a frequency associated to that
- you can then interpolate the max value, the point on the right, and then the point on the left using a simple polynomial of the second order (i.e. a parabola)
- the vertex of the parabola is a very good approximation of the frequency that you are looking for

Let me know if this helps

Code:
#include <Audio.h>
#include <Wire.h>
#include <SD.h>
int maxbin, k;
//double y1,y2,y3,d,kp ;
const int myInput = AUDIO_INPUT_LINEIN;
//const int myInput = AUDIO_INPUT_MIC;

// Create the Audio components.  These should be created in the
// order data flows, inputs/sources -> processing -> outputs
//
AudioInputI2S       audioInput;         // audio shield: mic or line-in
AudioAnalyzeFFT1024  myFFT(20);
AudioOutputI2S      audioOutput;        // audio shield: headphones & line-out

// Create Audio connections between the components
//
AudioConnection c1(audioInput, 0, audioOutput, 0);
AudioConnection c2(audioInput, 0, myFFT, 0);
AudioConnection c3(audioInput, 1, audioOutput, 1);

// Create an object to control the audio shield.
// 
AudioControlSGTL5000 audioShield;


void setup() {
  // Audio connections require memory to work.  For more
  // detailed information, see the MemoryAndCpuUsage example
  AudioMemory(12);

  // Enable the audio shield and set the output volume.
  audioShield.enable();
  audioShield.inputSelect(myInput);
  audioShield.volume(0.6);
}

void loop() {
  if (myFFT.available()) {
    // each time new FFT data is available
    // print it all to the Arduino Serial Monitor
     k=0;
     maxbin=0;
    
    //Serial.print("FFT: ");
    for (int i=0; i<512; i++) {
      if (myFFT.output[i]>maxbin) {
        maxbin=myFFT.output[i];
        k=i;
      } 
     // Serial.print(myFFT.output[i]);
     // Serial.print(",");
    }
    Serial.println();
    Serial.print("Max Bin ");
    Serial.print(k);
    Serial.println();
    double y1=double(myFFT.output[k-1]);
    double y2=double(myFFT.output[k]);
    double y3=double(myFFT.output[k+1]);
    double d=(y3-y1)/((2.0*(2.0*y2-y1-y3)));
    //double d=(y3-y1)/(y1+y2+y3);
    Serial.print("Diff ");
    Serial.print(d);
    Serial.println();
    double Freq=(AUDIO_SAMPLE_RATE_EXACT/1024.0)*(double(k)+d);
    Serial.print("Freq ");
    Serial.print(Freq);
    Serial.println();
  }
}

I am at the moment thinking that changing the window will change the output but can't figure out how to do that. Uses parabolic interpolation. I have been inputting a sine wave on linein.
 
Last edited:
@alfa66
That's what I am doing, from the literature looks like I need to use a Gaussian window to improve accuracy which is what I need to figure out how to do.
 
Just for your interest:

I am successfully using the Teensy 3.1 with the Audio Board to control an analog
synthesizer (TB-303 Clone) and implement a software VCO (bare-bones for now).


To expand it and to build a synthesizer from scratch with the teensy only, we still would need:
* LFO implementation
* Envelope Generation
* Signal Routing
 
@syso2342

It sounds really cool, I especially like the resonant filter.
At the moment I am building a complete synthesizer, which already contains an envelope generator (which actually runs as an effect).
If you want to have it I'll paste the code here or do a pull request (after I found out how).

For the LFO I have extended theAudioSynthWaveformSine.
It now also plays a square, triangle and sawtooth.
 
You already have LFOs available with AudioSynthWaveform. It can synthesize any frequency from DC to 22 kHz.

You can probably achieve your routing by using AudioMixer4. Just change the gain to zero to disconnect an input from the output.
 
@PaulStoffregen: Good to know. But how can you route the AudioSynthWaveform to something like the Filter Cutoff Frequency?
 
audiophilel shield

Hi everyone,

Hijacking again, but regarding the audiophile shield, I have found this nice codec that is quite cheap, which is already used in an adafruit/sparkfun product, named the VS1053b. There is also the VS1063 that has more codecs inside and a full duplex audio codec for telecom purpose. I like how you can put ASM or C code plugins inside the chip and access it on the SPI bus (both data and command). It kills the I2S purpose but makes the file reading and recording much more simpler. Also can be combined with another Codec chip as a I2S "master" input (the vs10xx only has TX i2s cappabilities but has 2 integrated timers on usable interrupts, uart for user code, 8 gpio, and many more options). Here is the link :

http://www.vlsi.fi/fileadmin/datasheets/vlsi/vs1053.pdf

The thing sells itself:

http://www.adafruit.com/products/1381

Mevon

PS oh yeah this chip is a MP3 player...

http://www.vlsi.fi/en/products/vs1053.html
 
I have found this nice codec that is quite cheap, which is already used in an adafruit/sparkfun product, named the VS1053b.

Yeah, of course, because PJRC is all about "me too" products based on the exact same silicon and software as everyone else in the Maker world is already using!
 
HINT: this one seems good and really cheap:

http://www2.conexant.com/Product/Audio/usbaudio/cx20562/Pages/default.aspx

http://octopart.com/dsac-l562-15ch-conexant-22005436

Mevon

EDIT: but no I2S I think... crap. I like the CX20703 but it has no USB client, which may be overkill for this app..:

http://www2.conexant.com/Product/Audio/avdspcodecsoc/cx20703/Pages/default.aspx


I like PJRC solution, and will work for a while for most of us... until Paul comes up with something better of course!
 
First pass with library code - Measurers period ( frequency )

Hope attachments show up. I have tested with sine wave on line-in from about 100hz to 4khz. Works by interpolation of zero crossings to get better time resolution. Any and all comments would be welcome
 

Attachments

  • analyze_freq.cpp
    2 KB · Views: 176
  • analyze_freq.h
    1.9 KB · Views: 172
  • NewFreq.ino
    877 bytes · Views: 178
nuvoton is cool too

I like PJRC solution, and will work for a while for most of us... until Paul comes up with something better of course!

I know, it's what I believe too. I've been looking around and I found that Nuvoton has a good line of codecs and really cheap too. This is only my opinion, I'm not proposing anything better that exists nor do I want this codec on a new PJRC product. We're just brainstorming here, right? Guess I'm just overwhelmed by the new products I'm discovering from Nuvoton and I want to share with audio codec enthusiasts... My 2 cents nothing more!

Mevon
 
meh

After so much trouble and terrible documentation, I don't ever want to design in another Nuvoton chip!

Edit: I just looked at their website anyway. You have the request the datasheet. You can't just download it. LAME.

LOLS :) The internets have showed me this: http://210.61.8.67/resource-files/NAU8822LDataSheetRev_1.0.pdf

Also, from previous researches, seems nuvoton was bought (or the other way around) or maybe allied with another chip maker called Winbond. Seems they have some chip in common (WAU8822 vs NAU8822 named) but I guess thats just to get us more confused. DOG HAM IT THE INTERNETS!

Mevon
 
Teensy TIMS

And the numbers track very nicely! teensy tims.jpg
 
Regarding the "audiophile" board: In most applications in commercial grade engineering for products made with these devices, they are going to be masked . Which is to say they will have thier audio window reduced in context of the mix. That said, 16 bit 44.1 works fine and even the noise of the current audio shield chip disappears into filters I'd put on the signal by default before using it in a mix. I understand the desire to brag specs, but the performance gain vs cost of the " audiophile" version may be only noticeable to those who notice brand of guitar string or drumstick. YMMV.
 
Status
Not open for further replies.
Back
Top