Audio tool help needed

Status
Not open for further replies.

WMXZ

Well-known member
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:
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.
 
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
fullwindow001.png

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
fullwindow000.png
 
Last edited:
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:
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.
 
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);
 
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):

file.png

I'm seeing the same wrong USB output:

sc.png
 
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):

View attachment 11373

I'm seeing the same wrong USB output:

View attachment 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
 
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).
 

Attachments

  • usb_audio.cpp
    12.4 KB · Views: 103
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/4169...nary-quot-menu?p=131254&viewfull=1#post131254
 
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/Audio/commit/cc44014a69966b0f38b8fc5196258cf2971c7d32
 
Status
Not open for further replies.
Back
Top