Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 15 of 15

Thread: Audio tool help needed

  1. #1
    Senior Member
    Join Date
    Jul 2014
    Posts
    1,714

    Audio tool help needed

    while playing around for another thread I came across a nasty problem
    I execute the following sketch
    Code:
    #include <Audio.h>
    #include <Wire.h>
    #include <SPI.h>
    #include <SD.h>
    #include <SerialFlash.h>
    
    // GUItool: begin automatically generated code
    AudioSynthToneSweep      tonesweep1;     //xy=187,150
    AudioEffectDelay         delay1;         //xy=553,233
    AudioEffectDelay         delay2;         //xy=559,492
    AudioEffectMultiply      multiply2;      //xy=764,585
    AudioOutputUSB           usb1;           //xy=800,343
    AudioOutputI2S           i2s1;           //xy=802,170.60000610351562
    AudioAnalyzeRMS          rms1;           //xy=908,584
    AudioConnection          patchCord1(tonesweep1, delay1);
    AudioConnection          patchCord2(tonesweep1, delay2);
    AudioConnection          patchCord3(delay1, 0, multiply2, 0);
    AudioConnection          patchCord4(delay1, 0, i2s1, 0);
    AudioConnection          patchCord5(delay1, 0, usb1, 0);
    AudioConnection          patchCord6(delay2, 0, multiply2, 1);
    AudioConnection          patchCord7(delay2, 0, i2s1, 1);
    AudioConnection          patchCord8(delay2, 0, usb1, 1);
    AudioConnection          patchCord9(multiply2, rms1);
    AudioControlSGTL5000     sgtl5000_1;     //xy=171,462
    // GUItool: end automatically generated code
    
    
    void setup() {
      // put your setup code here, to run once:
      AudioMemory(120);
    
      while(!Serial);
      Serial.println("TestShift");
    
      // setup audio board
      sgtl5000_1.enable();
      
      // setup headphone
      sgtl5000_1.volume(0.1); 
    
      
      delay1.delay(0,0); // delay in ms
      for(int ii=1;ii<8;ii++) delay1.disable(ii);
    
      delay2.delay(0,10); // delay in ms
      for(int ii=1;ii<8;ii++) delay2.disable(ii);
    }
    
    void loop() {
      if(tonesweep1.isPlaying()) return;
      tonesweep1.play(1.0,500,1000,0.01);
      if(rms1.available())
      {
        float val=rms1.read()*AUDIO_BLOCK_SAMPLES;
        if(val>0.001)
          Serial.println(val);
      }
      delay(100);
    }
    The purpose is to come up with a matched filter, but I'm not there yet.
    I use the USB-Audio to transfer waveforms to PC to watch them with Audacity.

    I realize severe cross-talking in the two Audacity traces.
    I do not know if this is in the USB-Audio part or somewhere else in the processing

    Unfortunately I have no osci available that I could plug into headphone to see if cross-talk also happens there
    If someone could be please so king to test this for me, that would be very much appreciated.

    Edit: @Paul, if you read this, to me it seems a problem with USB audio, as the multiply-rms chain works properly.
    Last edited by WMXZ; 08-22-2017 at 05:35 PM. Reason: comment for Paul

  2. #2
    Administrator Paul's Avatar
    Join Date
    Oct 2012
    Posts
    293
    Please try with the latest beta. A bug in AudioEffectDelay was recently fixed.

    If the problem still happens with 1.38-beta3, I'll try to investigate here.

  3. #3
    Senior Member
    Join Date
    Jul 2014
    Posts
    1,714
    Quote Originally Posted by Paul View Post
    Please try with the latest beta. A bug in AudioEffectDelay was recently fixed.

    If the problem still happens with 1.38-beta3, I'll try to investigate here.
    downloaded beta-3 on A1.8.3 but problem is still there
    Click image for larger version. 

Name:	fullwindow001.png 
Views:	32 
Size:	70.9 KB 
ID:	11351

    actual sketch
    Code:
    #include <Audio.h>
    #include <Wire.h>
    #include <SPI.h>
    #include <SD.h>
    #include <SerialFlash.h>
    
    // GUItool: begin automatically generated code
    AudioSynthToneSweep      tonesweep1;     //xy=187,150
    AudioEffectDelay         delay1;         //xy=553,233
    AudioEffectDelay         delay2;         //xy=559,492
    AudioEffectMultiply      multiply2;      //xy=764,585
    AudioOutputUSB           usb1;           //xy=800,343
    AudioOutputI2S           i2s1;           //xy=802,170.60000610351562
    AudioAnalyzeRMS          rms1;           //xy=908,584
    AudioConnection          patchCord1(tonesweep1, delay1);
    AudioConnection          patchCord2(tonesweep1, delay2);
    AudioConnection          patchCord3(delay1, 0, multiply2, 0);
    AudioConnection          patchCord4(delay1, 0, i2s1, 0);
    AudioConnection          patchCord5(delay1, 0, usb1, 0);
    AudioConnection          patchCord6(delay2, 0, multiply2, 1);
    AudioConnection          patchCord7(delay2, 0, i2s1, 1);
    AudioConnection          patchCord8(delay2, 0, usb1, 1);
    AudioConnection          patchCord9(multiply2, rms1);
    AudioControlSGTL5000     sgtl5000_1;     //xy=171,462
    // GUItool: end automatically generated code
    
    
    void setup() {
      // put your setup code here, to run once:
      AudioMemory(120);
    
      while(!Serial);
      Serial.println("TestShift");
    
      // setup audio board
      sgtl5000_1.enable();
      
      // setup headphone
      sgtl5000_1.volume(0.1); 
    
      delay1.delay(0,0); // delay in ms
      for(int ii=1;ii<8;ii++) delay1.disable(ii);
    
      delay2.delay(0,20); // delay in ms
      for(int ii=1;ii<8;ii++) delay2.disable(ii);
    
      delay(100);
    }
    
    void loop() {
      tonesweep1.play(1.0,500,3000,0.01);
      while(tonesweep1.isPlaying()) yield();
      while(!rms1.available()) yield();
      {
        float val=rms1.read()*AUDIO_BLOCK_SAMPLES;
        Serial.println(val);
      }
      delay(100);
    }
    note: delayed sweep (bottom line) is also corrupted
    This does not happen for small delays

    in fact is starts with delay2 set to 3 ms (!) as shown next
    Click image for larger version. 

Name:	fullwindow000.png 
Views:	33 
Size:	66.5 KB 
ID:	11352
    Last edited by WMXZ; 08-23-2017 at 07:00 AM.

  4. #4
    Senior Member
    Join Date
    Jul 2014
    Posts
    1,714
    update:
    one issue I've found is with tonesweep.
    it only transmits a audio object while transmitting.
    I overcome this by transmitting zeroed audio objects while not transmitting (i.e. !sweep_busy)
    early in update
    Code:
      if(!sweep_busy)
      {
    		block = allocate();
    		if(block) {
    			bp = block->data;
    			i=0;
    			while(i < AUDIO_BLOCK_SAMPLES) {
    			  *bp++ = 0;
    			  i++;
    			}    
    		    // send the samples to the left channel
    		    transmit(block,0);
    		    release(block);
    		}
    	  return;
      }
    however, has not solved the overall problem (cannot get clean data over USB), but allows multiply to work after larger delays

    Edit: continuous sending of data is important to avoid that usb-audio switches from stereo to mono (It does this if one of the two channels is missing). Also multiply does not work if one channel is missing.

    Edit:
    simplifying code (removing additional zero delay)
    Code:
    #include <Audio.h>
    #include <Wire.h>
    #include <SPI.h>
    #include <SD.h>
    #include <SerialFlash.h>
    
    // GUItool: begin automatically generated code
    AudioSynthToneSweep      tonesweep1;     //xy=287,146
    AudioEffectDelay         delay2;         //xy=659,488
    AudioOutputUSB           usb1;           //xy=900,339
    AudioOutputI2S           i2s1;           //xy=902,166
    AudioEffectMultiply      multiply2;      //xy=922,437
    AudioAnalyzeRMS          rms1;           //xy=1066,436
    AudioConnection          patchCord1(tonesweep1, 0, usb1, 0);
    AudioConnection          patchCord2(tonesweep1, 0, multiply2, 0);
    AudioConnection          patchCord3(tonesweep1, 0, i2s1, 0);
    AudioConnection          patchCord4(tonesweep1, delay2);
    AudioConnection          patchCord5(delay2, 0, usb1, 1);
    AudioConnection          patchCord6(delay2, 0, multiply2, 1);
    AudioConnection          patchCord7(delay2, 0, i2s1, 1);
    AudioConnection          patchCord8(multiply2, rms1);
    AudioControlSGTL5000     sgtl5000_1;     //xy=271,458
    // GUItool: end automatically generated code
    
    
    void setup() {
      // put your setup code here, to run once:
      AudioMemory(100);
    
      while(!Serial);
      Serial.println("TestShift");
    
      // setup audio board
      sgtl5000_1.enable();
      
      // setup headphone
      sgtl5000_1.volume(0.1); 
    
      delay2.delay(0,20); // delay in ms
      for(int ii=1;ii<8;ii++) delay2.disable(ii);
    
      delay(100);
    }
    
    void loop() {
     uint32_t nblk=20;
      rms1.read();
      tonesweep1.play(1.0,500,3000,0.01);
      while(tonesweep1.isPlaying()) yield();
      delay(nblk*3);
      float val=rms1.read()*nblk*AUDIO_BLOCK_SAMPLES;
      Serial.println(val);
      delay(40);
    }
    }
    I note that, without accessing usb-audio from PC, this program fine. All reported rms values are the same (0.0)
    as soon I access usb-audio (e.g. by opening recoding devices on PC) rms values vary randomly indicating scrambling of audio objects
    edit: As delay of 20 ms is longer than the tonesweep, rms of the product of left and right channel MUST be zero

    Edit: changed loop to wait sufficient time before carrying out rms so issue is more visible in serial monitor.

    Edit: when changing delay object
    -transmitting complete audio object ONLY before releasing queued audio object (e.g. after maxblocks buffers, i.e. "{transmit(queue[tail]); release(queue[tail];}") and returning from update before entering channel loop, seems OK, until usb-audio is accessed from PC as described before.
    - setting offset in channel loop always to zero to force always "transmit(queue[index], channel);" does not run OK, delayed data show up scrambled
    Last edited by WMXZ; 08-25-2017 at 07:15 AM. Reason: additional edit on delay object

  5. #5
    Senior Member
    Join Date
    Jul 2014
    Posts
    1,714

    Solved

    OK, after 4 days of continuously hitting the wall, I made some breakthrough
    So, I was running
    Code:
    #include <Audio.h>
    #include <Wire.h>
    #include <SPI.h>
    #include <SD.h>
    #include <SerialFlash.h>
    
    // GUItool: begin automatically generated code
    AudioSynthToneSweep      tonesweep1;     //xy=287,146
    AudioEffectDelay         delay2;         //xy=659,488
    AudioOutputUSB           usb1;           //xy=900,339
    AudioOutputI2S           i2s1;           //xy=902,166
    AudioEffectMultiply      multiply2;      //xy=922,437
    AudioAnalyzeRMS          rms1;           //xy=1066,436
    AudioConnection          patchCord1(tonesweep1, 0, usb1, 0);
    AudioConnection          patchCord2(tonesweep1, 0, multiply2, 0);
    AudioConnection          patchCord3(tonesweep1, 0, i2s1, 0);
    AudioConnection          patchCord4(tonesweep1, delay2);
    AudioConnection          patchCord5(delay2, 0, usb1, 1);
    AudioConnection          patchCord6(delay2, 0, multiply2, 1);
    AudioConnection          patchCord7(delay2, 0, i2s1, 1);
    AudioConnection          patchCord8(multiply2, rms1);
    AudioControlSGTL5000     sgtl5000_1;     //xy=271,458
    // GUItool: end automatically generated code
    
    void setup() {
      // put your setup code here, to run once:
      AudioMemory(100);
    
      delay(1000);
      while(!Serial);
      Serial.println("TestShift");
    
      // setup audio board
      sgtl5000_1.enable();
      
      // setup headphone
      sgtl5000_1.volume(0.1); 
    
      delay2.delay(0,20); // delay in ms
      for(int ii=1;ii<8;ii++) delay2.disable(ii);
    
      delay(100);
    }
    
    void loop() {
      rms1.read();
      tonesweep1.play(1.0,500,3000,0.01);
      delay(100);
      float val=rms1.read()*AUDIO_BLOCK_SAMPLES;
      Serial.printf("%4d ",AudioMemoryUsage());
      Serial.println(val);
    }
    with stock tonesweep routine from Pete (El Supremo)

    First, I noted that this routine only transmits audio objects while sweep in ongoing. To overcome this, I replaced in toneseeep 'update' function
    Code:
      if(!sweep_busy)return;
    by
    Code:
      if(!sweep_busy)
      {
    	block = allocate();
    	if(block) {
    		bp = block->data;
    		short *ebp = bp + AUDIO_BLOCK_SAMPLES;
    		while(bp < ebp) *bp++ = 0;
    		// send the samples to the left channel
    		transmit(block);
    		release(block);
    	}
    	return;
      }
    meaning update sends out empty (zeroed) audio objects to keep attached functions happy.

    This allowed me to run the above sketch continuously and to read some cross-multiply values.

    Following problem persisted for the last week.
    As soon as I tried to access the data via usb-audio (e.g. running audacity, or opening record device on PC) data got scrambled and non-zero. they should be 0.0 as there is no temporal overlap.

    Shortcut of 4 days of trial and failures, rewriting code etc., I realized something particular weird after I added the AudioMemoryUsage() printout.

    If I replace tonesweep with sine, I have no problem with delays and AudioMemoryUsage() gives a value that is nearly constant (as I expected to be).
    As soon as I use the new tonesweep function AudioMemoryUsage DECREASES continuously (eventually) flipping over 255 because of the uint8_t declaration.
    Let us ignore the fact that at the moment that 'memory_used' is declared as uint8_t (@Paul should it not be increased?).
    However, a decreasing or even negative 'memory_used' variable makes no sense, as new audio objects are continuously allocated.

    So, I compared sine with tonesweep to see if there are differences.
    There are algorithmic differences, we can ignore, so I played around with programming techniques.

    Here it comes:
    after replacing
    Code:
        for(i = 0;i < AUDIO_BLOCK_SAMPLES;i++) {
          *bp++ = (short)(( (short)(arm_sin_q31((uint32_t)((tone_phase >> 15)&0x7fffffff))>>16) *tone_amp) >> 16);
    by
    Code:
        for(i = 0;i < AUDIO_BLOCK_SAMPLES;i++) {
          bp[i] = (short)(( (short)(arm_sin_q31((uint32_t)((tone_phase >> 15)&0x7fffffff))>>16) *tone_amp) >> 16);
    and program started to work properly
    (no continuously decreasing 'memory_used' variable, and no corruption of delayed signal)

    As the two version are thought to be equivalent, the problem could(must?) be in the compiler. A nasty side effect, however, is also possible.

    my setting were win10, T3.6, Audio, 240 MHz, Faster, A1.8.3, T1.38b3

    PS: how does one switch on assembler listing from Arduino IDE?

    PPS:
    contrary what one may expect, the tonesweep does not vary frequency continuously but keeps it constant for a complete block.
    So frequencies jump from block to block.

  6. #6
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    17,480
    I'm looking at this now... and one part I don't understand is the time of 0.01 ms for tonesweep:

    Code:
      tonesweep1.play(1.0,500,3000,0.01);

  7. #7
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    17,480
    I'm running it now. There's definitely a bug in the USB output....

    This is the correct output I'm seeing on the headphone output (with volume turned up to 0.8):

    Click image for larger version. 

Name:	file.png 
Views:	21 
Size:	38.5 KB 
ID:	11373

    I'm seeing the same wrong USB output:

    Click image for larger version. 

Name:	sc.png 
Views:	20 
Size:	6.5 KB 
ID:	11374

  8. #8
    Senior Member
    Join Date
    Jul 2014
    Posts
    1,714
    Quote Originally Posted by PaulStoffregen View Post
    I'm looking at this now... and one part I don't understand is the time of 0.01 ms for tonesweep:

    Code:
      tonesweep1.play(1.0,500,3000,0.01);
    It seems that Tonesweep expects seconds and not milliseconds, so 0.01 would be 10 ms.

  9. #9
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    17,480
    I'm also seeing the tail end of the delayed signal corrupted.

    Click image for larger version. 

Name:	sc.png 
Views:	22 
Size:	6.7 KB 
ID:	11375

  10. #10
    Senior Member
    Join Date
    Jul 2014
    Posts
    1,714
    Quote Originally Posted by PaulStoffregen View Post
    I'm running it now. There's definitely a bug in the USB output....

    This is the correct output I'm seeing on the headphone output (with volume turned up to 0.8):

    Click image for larger version. 

Name:	file.png 
Views:	21 
Size:	38.5 KB 
ID:	11373

    I'm seeing the same wrong USB output:

    Click image for larger version. 

Name:	sc.png 
Views:	20 
Size:	6.5 KB 
ID:	11374
    My understanding is that after sending the sweep, tonesweep does not send more data, so USB switches to Mono (copying from active to missing channel) That, why I added code to tonesweep

  11. #11
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    17,480
    Yeah, looking at that now. It's definitely wrong. There also seems to be a bug with writing to the packets. Might be deep in the optimized copy. As a quick workaround, I'm trying writable buffers.

    Please give this a try. It goes in hardware/teensy/avr/cores/teensy3 (not the audio lib).
    Attached Files Attached Files

  12. #12
    Senior Member
    Join Date
    Jul 2014
    Posts
    1,714
    Quote Originally Posted by PaulStoffregen View Post
    Please give this a try. It goes in hardware/teensy/avr/cores/teensy3 (not the audio lib).
    The examples tested so far work, also the original 'pointer style' tonesweep.

  13. #13
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    6,375
    Quote Originally Posted by WMXZ View Post
    PS: how does one switch on assembler listing from Arduino IDE?

    I see the problem 'changed' - but - I saw this once and linked for Wiki -
    To get assembly code

  14. #14
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    4,438
    I use this patch for plaform.txt:

    Code:
    63a64,67
    > ##https://forum.pjrc.com/threads/41695-Tutorial-on-how-to-disasm-objdump-via-Arduino-quot-Export-compiled-binary-quot-menu?p=131255#post131254
    > recipe.hooks.savehex.presavehex.1.pattern="{runtime.hardware.path}/avr/arm-none-eabi-objdump_redirect.bat" "{compiler.path}{build.toolchain}" "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.objdump"
    > recipe.output.tmp_file={build.project_name}.objdump
    > recipe.output.save_file={build.project_name}.{build.board}.objdump
    Code:
    rem arm-none-eabi-objdump_redirect.bat
    %1\arm-none-eabi-objdump -S %2 >%3
    rem ready
    https://forum.pjrc.com/threads/41695...l=1#post131254

  15. #15
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    17,480
    Looking at this old thread again. Of the many bugs, I believe all are now fixed, except the RMS analysis. It's supposed to treat no data as if zeros were received, but wasn't. The "no data" case is an important optimization throughout the entire library, but it all falls apart when the ways you can observe results aren't correct.

    Hopefully this will fix RMS for good.

    https://github.com/PaulStoffregen/Au...258cf2971c7d32

Posting Permissions

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