Forum Rule: Always post complete source code & details to reproduce any issue!
Page 1 of 2 1 2 LastLast
Results 1 to 25 of 27

Thread: Input for Audio Shield

  1. #1
    Junior Member
    Join Date
    Jan 2020
    Location
    Italy
    Posts
    11

    Input for Audio Shield

    Hi all,

    First of all my congrats for this massive forum full of interesting projects!
    I have a pretty dumb question to ask but looking all over the forum and internet I was not able to find the answer...

    I want to listen an I2C sensor. I have already managed all the connections and I can read the value that I want to send to the audio shield.
    My question is: there is a way to send the data from my sensor directly as output?

    My configuration now is the following:
    Click image for larger version. 

Name:	Untitled.png 
Views:	15 
Size:	11.7 KB 
ID:	18898

    Right now i'm using buffer option, but this cause first of all a delay and also a weird sound.

    Can you help me?
    I'm a newbie in sound generation and I'm stuck at this point!
    Last edited by theczar1987; 01-28-2020 at 03:18 PM.

  2. #2
    Senior Member ETMoody3's Avatar
    Join Date
    Mar 2014
    Location
    New Ulm, Mn
    Posts
    119
    What is the i2c sensor?

  3. #3
    Junior Member
    Join Date
    Jan 2020
    Location
    Italy
    Posts
    11
    Is a LIS3DH accelerometer, I want to use it as a mic in a special application.
    For understand how it sounds I want to stream a single axis value out from the headphones through the Audio Shield.

  4. #4
    Senior Member ETMoody3's Avatar
    Join Date
    Mar 2014
    Location
    New Ulm, Mn
    Posts
    119
    I'm having some difficulty understanding how accelerometer data should be audio. Can you explain this?

    Weird sound makes sense, if data that is not audio is run through digital to analog conversion, the result is often... "static" or " noise" .

    I can only guess that you wish to translate the accelerometer data into a synthesized tone...and that would indeed require a few cpu cycles.

  5. #5
    Junior Member
    Join Date
    Jan 2020
    Location
    Italy
    Posts
    11
    The vibration captured by an accellerometer is like a piezo signal generated by pickup or a microphone.
    I'm saying so because I've tried to "hear" an analog accelerometer (output through a level adapter and preamp). I would like to do the same but with a digital one, but I'm obtaining only a weird metallic noise.

    My problem now is that is not clear how I can stream a value straight out from the audio shield. Using the buffer is creating a weird metallic sound, even using filters.

    Have you ever tried to stream as output a variable generated by the sketch?

  6. #6
    Senior Member ETMoody3's Avatar
    Join Date
    Mar 2014
    Location
    New Ulm, Mn
    Posts
    119
    I believe I understand what you're trying to do.

    From your configuration information I assume the output you are getting from the accelerometer is analog and being received by the ADC1 object.

    Based on your configuration, it appears to me that the output of the audio shield is simply converting what it has been given. If this is not what you expect, then it is possible that the sensor does not output an " audio - like " signal in the manner of a piezoelectric pickup.

  7. #7
    Junior Member
    Join Date
    Jan 2020
    Location
    Italy
    Posts
    11
    Sorry the image can lead to misunderstanding. My sensor is the "QUEUE1" because I'm getting the raw data and then use it for fill a buffer.
    The ADC is for something else, that is not used now.

    Here attached my sketch!
    Attached Files Attached Files

  8. #8
    Senior Member ETMoody3's Avatar
    Join Date
    Mar 2014
    Location
    New Ulm, Mn
    Posts
    119
    The digital output of the sensor is not audio data. The audio shield is attempting to convert data that is no longer analogous to a pickup. This is why you are hearing a "metallic" noise.

  9. #9
    Junior Member
    Join Date
    Jan 2020
    Location
    Italy
    Posts
    11
    I can ensure you that the analog accelerometer works fine and is audible, because the sound is vibration, is the same concept as the MEMS Mic.
    There are even studies about using the smartphone accellerometers as mics, and NASA is using the same sensor for "hear" the health of the Mars rover.

    The metallic sound I guees is related to the buffer filling, for sure I coded it wrong, because is not circular: looks like that the sound is refreshing every X milliseconds and it is not continous, therefore I have this Phaser sound.

    The question is: I have an int variable and I want to stream it out via the Audio Shield. How should I do it? I must use the queue object or there is something else?

  10. #10
    Senior Member ETMoody3's Avatar
    Join Date
    Mar 2014
    Location
    New Ulm, Mn
    Posts
    119
    I have read your code. I have read the datasheet for the sensor.

    Once again, the audio shield is playing what you are sending it. What you are sending it may not be what you wish for it to be.

    There are numerous possibilities as to why. Data transmission rates via i2c could be quantizing the data. Perhaps try increasing the i2c clock rate from default.

  11. #11
    Junior Member
    Join Date
    Jan 2020
    Location
    Italy
    Posts
    11
    Nice tip!
    How should I do it?

  12. #12
    Senior Member ETMoody3's Avatar
    Join Date
    Mar 2014
    Location
    New Ulm, Mn
    Posts
    119
    That's done in the initialization of the wire library, which in this case that's happening in the adafruit library.

    Looking into that, I'm not *seeing* a call to 400khz for the wire library...

    This is done by Wire.setClock(400000); and while it may be there... I don't see it.
    Try adding the line to your setup

  13. #13
    Junior Member
    Join Date
    Jan 2020
    Location
    Italy
    Posts
    11
    I've tried as suggested but without luck. The I2C now is 400Khz and the sensor can read up to 5Khz.
    I've looked the output of the headphone jack with the oscilloscope and looks like that I have only the positive edge of the wave, cutting all the negative, and also I have an half second response time.

    The output of the sensor is this one:
    Click image for larger version. 

Name:	Untitled.jpg 
Views:	4 
Size:	76.1 KB 
ID:	18900

    If this will be my output, I should hear an humm, or something similar. Maybe a buzz. Not a metallic slow refreshed sound... Am I right?

    Here is after I tap on the table:
    Click image for larger version. 

Name:	Untitled.jpg 
Views:	2 
Size:	39.9 KB 
ID:	18901

    I really don't know what is wrong.

  14. #14
    Senior Member ETMoody3's Avatar
    Join Date
    Mar 2014
    Location
    New Ulm, Mn
    Posts
    119
    I'm not sure but it may be that something in between is taking processor time, possibly in the sensor library, which is trying to provide service to all potential uses.

    You might have better results in writing "bare metal" code to access the specific register in the sensor as fast as possible with no other tasks in between the read and write.

    I can't speak to possible interference in the queue object as I honestly have never looked at that code. There is however a lot of things going on in the sensor library that you may not require for your use.

    Hopefully someone else with more coding skill decides to speak up here.

  15. #15
    Senior Member
    Join Date
    Nov 2017
    Location
    Belgium
    Posts
    215
    @theczar1987
    A few few remarks concerning your code:

    The queue is 128 words(samples) long, not 256!

    In your code the queue1.playBuffer() command is executed once per loop/sample. It should only be executed once every 128 samples.

    You need to read your sensor at the same sample rate as the audio lib.

  16. #16
    Junior Member
    Join Date
    Jan 2020
    Location
    Italy
    Posts
    11
    It can be, but is something in between the raw data acquisition and the streaming. Because the plot looks to me quite accurate, is not losing samples.
    Thanks anyway for the quick answers and for the help man! I appreciate that!

  17. #17
    Junior Member
    Join Date
    Jan 2020
    Location
    Italy
    Posts
    11
    Quote Originally Posted by neurofun View Post
    @theczar1987
    A few few remarks concerning your code:

    The queue is 128 words(samples) long, not 256!

    In your code the queue1.playBuffer() command is executed once per loop/sample. It should only be executed once every 128 samples.

    You need to read your sensor at the same sample rate as the audio lib.
    Thanks Neurofun!
    I've moved the queue1.playBuffer() like this:
    Code:
     sens_fusion_out = ((lis.x * GAIN_X) + (lis.y * GAIN_Y) + (lis.z * GAIN_Z));
      Serial.print("OUTPUT: "); Serial.println(sens_fusion_out);
      Serial.println();
    
      //sine1.frequency(sens_fusion_out);
      
      uint16_t *temp = queue1.getBuffer();
      bufr[i] = sens_fusion_out;
      /*Serial.print("BUFFER: "); Serial.print(bufr[i]);*/ Serial.print("   BUFFER COUNT: "); Serial.println(i);
      i++;
        
      memcpy(temp, &bufr, 256);
    
      if(i > 256){
        Serial.println("PLAY!");
        queue1.playBuffer();
        i = 0;
      }
    But now is not playing nothing.
    About the sync between the audio lib and the sensor lib I'm totally agree with you, but in theory the slowest should not prevail?
    Thanks a lot to everybody!

  18. #18
    Junior Member
    Join Date
    Jan 2020
    Location
    Italy
    Posts
    11
    THANKS NEUROFUN!

    Now I'm superclose to the effect that I want obtain but the audio starts only if I open the serial monitor...
    Why is doing so?

  19. #19
    Senior Member ETMoody3's Avatar
    Join Date
    Mar 2014
    Location
    New Ulm, Mn
    Posts
    119
    while (!Serial)

    ( I think it's relatively safe to comment out that whole line it's there to halt execution until you open the serial monitor)

  20. #20
    Senior Member
    Join Date
    Nov 2017
    Location
    Belgium
    Posts
    215
    Quote Originally Posted by theczar1987 View Post
    THANKS NEUROFUN!

    Now I'm superclose to the effect that I want obtain but the audio starts only if I open the serial monitor...
    Why is doing so?
    Try this:
    Code:
    while (!Serial && millis() < 2500);

  21. #21
    Senior Member
    Join Date
    Jul 2014
    Posts
    2,570
    OK, Iīm with you concerning using the accelerometer as acoustic Sensor (in fact it is an old concept: keyword vector-sensor)

    Assume you tell the LIS3DH to sample at 5.376 kHz then you should retrieve the data with the same velocity. As you read x,y,z your "fetch rate" should be 3time higher, right?
    Also you should reprogram the audio card for the same data rate instead 44.1 kHz 3x5.376 kHz or using an interpolating filter.

    Not sure if you have access to SPI mode, but you were indicating I2C, so you should program the accel acquisition to be slaved to LIS3DH, which is running in free continuous mode.

    as soon you fill a audio buffer, you must issue a global update of the Audio engine.

  22. #22
    Senior Member
    Join Date
    Feb 2017
    Posts
    369
    It's still unclear to me how this is going to work. The clocking and update period of the Audio library's objects is ~44.1 KSamples/s. In this instance that period is set by the AudioOutputI2S object which is the only one present that can have update_responsibility.

    There is no way your I2C sensor can maintain that sample rate (and even if it could, the I2C sampling is asynchronous to the Audio library's sampling). So, you're starving the AudioOutputI2S object for input. The result has to be some type of distortion. You'd have to rewrite the AudioOutputI2S object whose clocking is based on the F_CPU. But I still don't know how you'd synch it with the I2C sampling.

    The whole thing doesn't seem to be thought out very well.

  23. #23
    Senior Member
    Join Date
    Jul 2014
    Posts
    2,570
    Quote Originally Posted by gfvalvo View Post
    It's still unclear to me how this is going to work. The clocking and update period of the Audio library's objects is ~44.1 KSamples/s. In this instance that period is set by the AudioOutputI2S object which is the only one present that can have update_responsibility.

    There is no way your I2C sensor can maintain that sample rate (and even if it could, the I2C sampling is asynchronous to the Audio library's sampling). So, you're starving the AudioOutputI2S object for input. The result has to be some type of distortion. You'd have to rewrite the AudioOutputI2S object whose clocking is based on the F_CPU. But I still don't know how you'd synch it with the I2C sampling.

    The whole thing doesn't seem to be thought out very well.
    That is the nice thing on Teensy, nearly everything is possible.
    e.g.: you can easily write an audio object that controls the update rate, or modify the sampling rate of I2S chips.
    The question that I2C sampling is not synchronous to Audio library sampling is void, as input data can be buffered and audio library can be modified or augmented.
    Iīm not saying it is a beginnerīs job, but IMHO, it can be done.

  24. #24
    Senior Member
    Join Date
    Feb 2017
    Posts
    369
    Quote Originally Posted by WMXZ View Post
    The question that I2C sampling is not synchronous to Audio library sampling is void, as input data can be buffered and audio library can be modified or augmented.
    I didn't say that the input/output sampling needs to be Phase synchronous. As you stated, that's easily handled with a FIFO buffer. But, the sampling rate at the input (i.e. from the I2C device) must be exactly Frequency synchronous to the sampling rate at the output (i.e. to the I2S DAC). Otherwise, the buffer will either overrun or underrun.

    I'm just not sure how you would go about achieving uniform sampling from the I2C at EXACTLY the same rate as your sending samples to the I2S.

    You might fix that with a re sampling algorithm. Or, you could get the two rates "close enough" with the buffering problems. Either solution would probably produce artifacts and I don't find either very satisfying.

  25. #25
    Senior Member
    Join Date
    Feb 2017
    Posts
    369
    Quote Originally Posted by gfvalvo View Post
    I didn't say that the input/output sampling needs to be Phase synchronous. As you stated, that's easily handled with a FIFO buffer. But, the sampling rate at the input (i.e. from the I2C device) must be exactly Frequency synchronous to the sampling rate at the output (i.e. to the I2S DAC). Otherwise, the buffer will either overrun or underrun.

    I'm just not sure how you would go about achieving uniform sampling from the I2C at EXACTLY the same rate as your sending samples to the I2S.

    You might fix that with a re sampling algorithm. Or, you could get the two rates "close enough" with the buffering problems. Either solution would probably produce artifacts and I don't find either very satisfying.
    I hate when I reread my posts, find errors, and the window has closed on being able to edit it:

    I didn't say that the input/output sampling needs to be Phase synchronous. As you stated, that's easily handled with a FIFO buffer. But, the sampling rate at the input (i.e. from the I2C device) must be exactly Frequency synchronous to the sampling rate at the output (i.e. to the I2S DAC). Otherwise, the buffer will either overrun or underrun.

    I'm just not sure how you would go about achieving uniform sampling from the I2C at EXACTLY the same rate as you're sending samples to the I2S.

    You might fix that with a re sampling algorithm. Or, you could get the two rates "close enough" and live with the buffering problems. Either solution would probably produce artifacts and I don't find either very satisfying.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •