..and it was helpful. issue fixed.
So, a description.
The way addMemoryForRead() works has changed.
I think it is much easier to use now. There are not many cases where it is necessary, nevertheless it may be useful in some cases.
Normally the waveplayer itself knows how much memory it needs. This is calculated for each file individually:
Memory:
AUDIO_BLOCK_SAMPLES * Channels * BytesPerSample * NumberOfInstances
This looks like a lot, but it is not. In the normal case (1 instance) it leads to exactly the same memory usage as the old player.
With 8 channels, 16Bit you get 128 * 8 * 2 * 1 = 2048 bytes. This is a not much for the T4, but also a T3.2 should be able to do it.
(With a blocksize of 128, even the Teensy LC can play a stereo file)
The player tries to maximize the SD throughput. It reads as much as possible, i.e. it fills its entire memory when it accesses the file.
This saves the expensive addressing when multiple players are running at the same time.
In the following we are talking about multiple concurrent instances - and only then addMemoryForRead() can be useful.
A simple concurrent start can look like this, for example:
(1)
Code:
playWav1.play("Nums_7dot1_16_44100.wav");
playWav2.play("SDTEST3.WAV");
This is not quite optimal, because an audio interrupt can happen between both calls. I.e. the starts would be about 3 milliseconds apart in this case.
Often this may not matter.
This attempt to prevent this is not good:
Code:
AudioNoInterrupts();
playWav1.play("Nums_7dot1_16_44100.wav");
playWav2.play("SDTEST3.WAV");
AudioInterrupts();
This may lead to a short sound dropout of the library if it happens just before an interrupt.
Better is this:
(2)
Code:
playWav1.play("Nums_7dot1_16_44100.wav", true); //start in paused mode
playWav2.play("SDTEST3.WAV", true);
AudioNoInterrupts();
playWav1.pause(false); //un-pause, start playing
playWav2.pause(false);
AudioInterrupts();
This is a sychronized start. Both files start granted at the same time.
Now we are slowly approaching the point where additional storage becomes interesting. Probably.
(2) looks always like this - and in most cases (1) looks indentical:
(yes, the probes are not calibrated - sorry for this, could not find the tool)
So, you see that it channel 2( blue line ) gets read from SD in middle between the reads of channel 1 (yellow)
In some cases of (1) - if the second files starts an interrupt later, it can look like this:
And only for this - i.e. when not synchronized start -
AND when it is somehow
interesting for the main program (there are very few cases... I can't even think of a simple example)
additional memory becomes interesting:
Code:
playWav1.addMemoryForRead(2);
playWav2.addMemoryForRead(2);
(This must happen before play() )
A values of 2 doubles the used memory, 3 would be the tripple (use it for three files for example)
Now, it always looks like (1).
This is needed, because in the default case, the player just does not have memory to play 3 milliseconds without accessing the file (you remember - the 2nd file may start later (if no sync start))
Now, it looks good again:
So... I hope this explanation was a little helpful.
Back to a single file:
The normal frequency of reads is 172Hz. If you want a lower frequency, you can use addMemoryForRead(), too.
i.e. "addMemoryForRead(2)" would half this frequency to 86Hz. If you need that.
And, last:
- addMemoryForRead(
0) and addMemoryForRead(
1) do nothing.
Edit "
- if you use it, use it for every player. Not using it for all instances makes no sense." - changed in latest version. It's sufficient to change it for one instance - all other instances will us it, too.