Adding a third sound introduces noise to the first two?

brispo

Active member
I'm using a Teensy 4.0 with the Audio Adaptor Board, using the Line Out on the Audio Adaptor, to play some sounds I converted from .wav to .cpp using wav2sketch.

If I loop through just two of the sounds, they're nice and clean (cleandrums.zip below), but as soon as I uncomment line 47 in my sketch, which plays a third drum sound, now all three samples have noise introduced while they're playing (dirtydrums.zip below).

To be clear, I'm not talking about the line noise heard during the silence in between drum sounds. I'm talking about the distortion-type noise you hear towards the end of each drum sound in dirtydrums.wav (most noticeable right after the kick drum sound).

I've tried adjusting all sorts of variables, but I can't seem to achieve the clean sound heard in cleandrums.wav as soon as I try to play a third sound. Here's my sketch:

Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

// GUItool: begin automatically generated code
AudioPlayMemory          playMem1;       //xy=265.33332824707026,108.66666158040363
AudioPlayMemory          playMem2;       //xy=271.9999809265137,178.6666555404663
AudioMixer4              mixer1;         //xy=615.3333282470702,180.33332824707028
AudioOutputI2S           i2s1;           //xy=978.6666615804035,175.33332824707028
AudioConnection          patchCord1(playMem1, 0, mixer1, 0);
AudioConnection          patchCord2(playMem2, 0, mixer1, 1);
AudioConnection          patchCord3(mixer1, 0, i2s1, 0);
AudioConnection          patchCord4(mixer1, 0, i2s1, 1);
// GUItool: end automatically generated code


// WAV files converted to code by wav2sketch
#include "AudioSampleSnare.h"        // http://www.freesound.org/people/KEVOY/sounds/82583/
#include "AudioSampleHihat.h"        // http://www.freesound.org/people/mhc/sounds/102790/
#include "AudioSampleKick.h"         // http://www.freesound.org/people/DWSD/sounds/171104/

// 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(10);

  // turn on the output
  audioShield.enable();

}

void loop() {

    playMem1.play(AudioSampleKick);
    delay(2000);

    playMem2.play(AudioSampleSnare);
    delay(2000);

    playMem2.play(AudioSampleHihat); // All I have to do is remove this line, and the previous two sounds are clean
    delay(2000);

}

Any ideas?
 

Attachments

  • cleanDrums.zip
    152.1 KB · Views: 26
  • dirtyDrums.zip
    243 KB · Views: 18
Well the clean sample has the second drum sample last about 660ms, the dirty one 950ms, so you are hearing extra duration of the sample I think.
 
Well the clean sample has the second drum sample last about 660ms, the dirty one 950ms, so you are hearing extra duration of the sample I think.
You're meaning that the snare waveform in the clean sample is shorter than the snare wavefrom in the dirty sample? If so, the noise is what makes the waveform of the snare in the dirty sample longer. The snare drum in the clean and dirty samples were generated from the exact same .cpp file.
 
Does it happen if you play the snare again instead of the hihat as the last sample?
What if you play the hihat using playMem1 instead of playMem2?
After loading the samples into audacity, normalizing, there are tiny ~regular glitches visible in the "dirty" kick drum sample
kickdrum_cmp.png

They seem to happen roughly every 1024 samples.
kickdrum_cmp2.png
 
Shouldn't you add an extra line here for playMem3?
C++:
// GUItool: begin automatically generated code
AudioPlayMemory          playMem1;       //xy=265.33332824707026,108.66666158040363
AudioPlayMemory          playMem2;       //xy=271.9999809265137,178.6666555404663
AudioPlayMemory          playMem3;
AudioMixer4              mixer1;         //xy=615.3333282470702,180.33332824707028
AudioOutputI2S           i2s1;           //xy=978.6666615804035,175.33332824707028
AudioConnection          patchCord1(playMem1, 0, mixer1, 0);
AudioConnection          patchCord2(playMem2, 0, mixer1, 1);
AudioConnection          patchCord2(playMem3, 0, mixer1, 2);
AudioConnection          patchCord3(mixer1, 0, i2s1, 0);
AudioConnection          patchCord4(mixer1, 0, i2s1, 1);
// GUItool: end automatically generated code
and change line playMem2.play(AudioSampleHihat); to playMem3.play(AudioSampleHihat);

I'm not sure what happens if you use playMem2.play(sample1); and then playMem2.play(sample2);. Is memory partially overwritten or...?

Paul
 
Does it happen if you play the snare again instead of the hihat as the last sample?
What if you play the hihat using playMem1 instead of playMem2?

Just ran the tests you suggested. If I play the snare on mem2 instead of the high hat = no noise.

If I play the Hihat on mem1 = noise (though possibly slightly less noise. I'm not sure though as I'm just listening to it through a speaker)

Interesting that the noise seems to happen every 1024 samples, give or take. I wonder if that's a clue as to what's going on here?
 
I'm not sure what happens if you use playMem2.play(sample1); and then playMem2.play(sample2);. Is memory partially overwritten or...?

Paul

I tried your suggestion, adding playMem3 and playing the Hihat through playMem3, still noise...

My understanding is if you use the same playMem to play a second sound before the first sound played through it, the first sound is stopped and the second sound begins. You use multiple playMems so you can play multiple sounds without interrupting the end of the previous sound. I figured that since I have 'delay(2000);' between each sound, I don't need to use multiple playMems for each sound.

Regardless, putting the hihat on its own playMem still generated the noise... I'm stumped here...
 
To further test these theories, I just tried a sketch that played only the kick and snare, but both on playMem1.

Quite a strange result actually. The very first time the kick drum and snare drum play, there is noise. Subsequent kick and snare sounds are clean...

This is really strange. It's almost like there is some sort of buffer that the sounds get loaded into that allow them to play cleanly, but the first time through they're not in the buffer yet? Then if we add the Hihat sound, having to put three sounds into the buffer is too much for the buffer to handle, so none of the three sounds are ever fully buffered.

I haven't seen much in the documentation in terms of buffering audio samples, I might not even be using the right term here.

While writing this, I had another idea; is the Hihat sound specifically what is causing the problem, or would any third sound cause the noise. I just tested that idea.

Playing the sequence as: 1)Hihat, 2)Kick = Noise...
Playing the sequence as 1)Hihat, 2)Kick, 3)Snare = Noise...

This result makes me think something is awry with the actual Hihat .cpp file?

File sizes are as follows:
AudioSampleKick.cpp = 28 KB
AudioSampleSnare.cpp = 31 KB
AudioSampleHihat.cpp = 65 KB

So the Hihat .cpp file is larger than both the Kick and Snare combined, but I'm not sure exactly what that tells us.

I also noticed that the Hihat .cpp was converted using 44100hz, while the kick and snare were both converted using 22050hz. I wonder if that's the magic bullet? I'll try converting the Hihat.wav using 22050 and report my findings shortly.
 
I tried a few different settings while converting the drum sounds through wav2sketch, and the noise was different, but I wasn't able to eliminate it.

Re-converting the .wav of the Hihat to 22050/16bitPCM caused a bunch of noise on the Hihat sound.

Going back to the original Hihat.ccp, and convering the Kick and Snare to match the Hihat (44100/u-law) made the Kick sound worse, and the snare sound MUCH worse.

This issue is hurting my brain. What on earth could be going on here?
 
I haven't looked at your sampled sound files specifically, but just on a lark, could you try setting the gain level on each of the two mixer inputs being used to 0.5 (& set any unused to 0.0 as well) & see if that makes a difference. My thinking is that, if the playing of the first sound leaves the output at some DC level (is that even possible and/or realistic), then playing subsequent sound samples may be overloading the mixer. If you have added the third playMem (& tied it into its own input on the mixer), then set each of the three inputs to 0.33. In my experience with the (excellent, BTW) audio library (wth the development & implementation of my TeensyMIDIPolySynth (TMPS)), mixer overload can be a very common problem, but is also very easily managed.

Hope that helps . . .

Mark J Culross
KD5RXT
 
I haven't looked at your sampled sound files specifically, but just on a lark, could you try setting the gain level on each of the two mixer inputs being used to 0.5 (& set any unused to 0.0 as well) & see if that makes a difference. My thinking is that, if the playing of the first sound leaves the output at some DC level (is that even possible and/or realistic), then playing subsequent sound samples may be overloading the mixer. If you have added the third playMem (& tied it into its own input on the mixer), then set each of the three inputs to 0.33. In my experience with the (excellent, BTW) audio library (wth the development & implementation of my TeensyMIDIPolySynth (TMPS)), mixer overload can be a very common problem, but is also very easily managed.

Hope that helps . . .

Mark J Culross
KD5RXT
Thanks for weighing in. I'll give lowering the mixer levels a try, but my guy is that it isn't a clipping issue, as the noise is most noticeable in the tail after the peak, where clipping is usually nose right at the peak.

Plus, the waveforms have plenty of headroom, even with the noise. I'm down to try anything though! Getting this bug worked out is the last hurdle before I can solder up a prototype!
 
Try to execute the play commands with disabled interrupts, like this:
C++:
void loop() {
    __disable_irq();
    playMem1.play(AudioSampleKick);
    __enable_irq();
    delay(2000);

    __disable_irq();
    playMem2.play(AudioSampleSnare);
    __enable_irq()
    delay(2000);

    __disable_irq();
    playMem2.play(AudioSampleHihat); // All I have to do is remove this line, and the previous two sounds are clean
    __enable_irq();
    delay(2000);
}
Does it help?
 
Try to execute the play commands with disabled interrupts
Just tried it, no change to the noise...

I tried to find some info on the observation you made yesterday that the noise tends to appear every 1024 samples or so, but didn't find much. I did read something interesting in the Audio Play Memory Documentation: "AudioPlayMemory automatically decodes the µ-law compression and converts the slower sample rates to 44100 Hz using linear interpolation between samples."

I wonder if it's an issue with the encoding settings used in wav2sketch? Like, AudioPlayMemory is trying to convert a .cpp that was encoded at 22050 to 44100, but some noise gets introduced into the analog signal every 1024 samples? It's a stab in the dark, but I'll try rendering all three .wavs as 44100/16-bit PCM and see if that makes a difference.

...So just tested that theory, and the noise didn't go away, but it changed. Previously, I didn't notice any noise on the Hihat sample, but now there is a long tail of noise after each drum, including the Hihat. Here's the recorded .wav:
dirtydrums-01.jpg


Zooming in vertically on the waveform, the noise becomes very noticeable:
dirtydrums-02.jpg


What I find interesting is that the noise occurs for different durations for each drum sound. The noise at the end of the kick sample is shortest, followed by the hi-hat second, and the snare has a massive lingering tail of noise, that doesn't stop until right before the hihat sound begins.

Zooming in on the noise even further, the spikes occur at an interval of exactly 512 samples:
dirtydrums-03.jpg


I feel like this bug is totally solvable, I'm just a bit out of my depth when it comes to the inner-workings of the Teensy. It's encouraging that I AM able to create drum sounds without any noise at all, just not with the hihat in the loop as well.

I'm happy to try any other suggestions!
 
Isn't that because you converted the PCM samples to μ-law?
I'm not sure to be honest. I just took the links to the .wav files in the demo sketch and ran them through wav2sketch in the hopes that a different output configuration might remove the noise, but to be clear, my original post was using .cpp and .h files directly from the github repo.
 
So a bit of an update: For all these tests, I had the Teensy and Audio Adaptor mounted on a breadboard, with all the various circuitry required for my project. I removed the teensy from the breadboard and just plugged in into my pc via usb, and connected the lineouts to a headphone jack.

NO NOISE! EVEN WITH THE HIHAT!

So it sounds like there's something in my circuitry that is causing the noise, but I never thought that was the case, because playing the kick and snare without the hihat produces no noise, even in the breadboard with all my circuitry. Being that the noise spikes occur every 512 samples, my hunch now is that there is some issue with my circuitry that is allowing some digital noise to leak into the audio lineout, but that still doesn't explain why the noise only appears once I try to play the hihat sound...

I suppose I'll play around with my circuitry a bit and see if I can isolate the issue. Basically, I'm wanting to put the Teensy inside my acoustic guitar, powering it off of the same 9v battery that powers the guitar preamp. I tapped into the 9v battery with wires that lead into a buck converter, and have the output voltage set to 5v, which goes into the Teensy. There's also a bit of ingenuity required so that the Teensy (like the preamp) only powers on when a guitar cable is connected to the guitar.

I got all this circuitry working about a year ago, using an Arduino with a Fluxamasynth MIDI shield from Modern Device, so I was hoping that the same circuitry would work for the Teensy. It does work, but just has the noise I've been trying to eliminate in this thread. I'll play around a bit with the ground connections and add in parts of the circuit piece by piece and see if I can't isolate the root cause. I'll report back.

In the meantime, any guidance would be appreciated. I can upload a schematic of my circuitry if that would help.
 
What I find interesting is that the noise occurs for different durations for each drum sound. The noise at the end of the kick sample is shortest, followed by the hi-hat second, and the snare has a massive lingering tail of noise, that doesn't stop until right before the hihat sound begins.
It looks like the noise has the same length as the samples. They do have some silence at the end with snare being the longest.
Did you have the audio adapter board connected to the teensy using wires + breadboard or was it plugged into teensy?
With wires there might be some crosstalk happening resulting in the noise.

9V battery might not live long when powering the Teensy.
 
It looks like the noise has the same length as the samples. They do have some silence at the end with snare being the longest.
Did you have the audio adapter board connected to the teensy using wires + breadboard or was it plugged into teensy?
With wires there might be some crosstalk happening resulting in the noise.

9V battery might not live long when powering the Teensy.
The audio adapter is right on top of the Teensy (see photo)

The circuit I have there would power on the Teensy only when a TS guitar cable is inserted (the same way the guitar's preamp is turned on and off)

Once I can get the noise removed, I plan to test running the Teensy at lower CPU speeds and possibly lower voltages, to minimize the current draw on the battery, this extending it's life.
 

Attachments

  • PXL_20241030_161645198.MP~2.jpg
    PXL_20241030_161645198.MP~2.jpg
    373.4 KB · Views: 15
Last edited:
It looks like the noise has the same length as the samples.
You're right btw. I looked at it in my DAW and the noise stops at the exact same time the sound stops. Trimming the sound files to reduce the tails can help conceal the noise, but you can definitely still hear it if you listen for it.

What's really driving me crazy is that if I just loop through the Kick and the Snare sounds, there is no noise at all. It's only after adding the third sound (hihat), that the noise suddenly appears on the kick and snare sounds...
 
Back
Top