You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hi, I just tried to create a minimal implementation of this code to play back wav files from LittleFs on my ESP32 Audio Kit v2.2 2957 ES8388.
I got some problems:
First, the sound playback only works if the following is called from within the void setup() Serial2.begin(MIDI_SERIAL2_BAUDRATE, SERIAL_8N1, MIDI_RX2_PIN);
Why is this necessary to get sound output? I am not using Midi at all...
EDIT:
I just went through the Sampler_Process() code to get a better understanding:
The pitch of the sample is defined by setting the number of bytes to add to the position after each call of the process function which is normally called at samplerate. As the values are 16bits to get the original speed this value needs to be 2 as each sample is constructed from two bytes.
Having this in mind the setting of the index for the new sample value in the data array can be understood like this: samplePlayer[i].samplePos = samplePlayer[i].samplePosF;
The index must be an integer, this line just converts the "ideal value" at a specific playback speed, which was calculated before to an integer. samplePlayer[i].samplePos -= samplePlayer[i].samplePos % 2;
This makes sure, that this index is always pointing to the first of the two bytes which form one 16bit sample value.
As i said before after each call of the process function the new ideal sample position is calculated. samplePlayer[i].samplePosF += 2.0f * sampler_playback * samplePlayer[i].pitch;
Here the variable sampler_playback is the global pitch and the samplePlayer[i].pitch is the samples individual pitch.
For double speed (one octave) this value needs to be 2 ? for one chromatic step the multiplier is the 12th root of 2 or 2exp(1/12)
For two steps it would be 2exp(2/12) and so on.
Is this correct?
Then I want to understand that trick with the slowRelease: slowRelease = slowRelease * 0.99; /* go slowly to zero */
Am I right that this only plays a role if a samle is retriggerd before reaching its end? It is just adding a exponential fade out form the sample value the sample playback is at in the moment of retriggering to the playback.
Is this correct? To shorten it one would just lower the factor of 0.99 a little right?
I realized that the first sample playback has a harder attack then the following onces and I believe it has something to do with the following line in the NoteOn code: newSamplePlayer->sampleSeek = 44;
as the first time NoteOn is called after the SamplerInit this value is set to: samplePlayer[i].sampleSeek = 0xFFFFFFFF;
Does this somehow lead to a softer attack to sample playback? I liked the sound of the first playback as it was more of punch. especially for a kickdrum sound.
And then, just for curiosity would you explain the following code ? I think the comments are somehow wrong (first byte of second half...)
uint32_t dataOut = samplePlayer[i].samplePos & ((BLOCKSIZE * 2) - 1); /* going through all data and repeat */
if ((dataOut >= BLOCKSIZE) && (samplePlayer[i].lastDataOut < BLOCKSIZE)) /* first byte of second half */
{
samplePlayer[i].file.read(&samplePlayer[i].data[0], BLOCKSIZE);
}
if ((dataOut < BLOCKSIZE) && (samplePlayer[i].lastDataOut >= BLOCKSIZE)) /* first byte of second half */
{
samplePlayer[i].file.read(&samplePlayer[i].data[BLOCKSIZE], BLOCKSIZE);
}
samplePlayer[i].lastDataOut = dataOut;
The first line, I could understand somehow, it maps every possible Index of sample value to the range of the Blocksize * 2 (0-1023)
why isn't the blocksize just 1024 and read at once?
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
Hi, I just tried to create a minimal implementation of this code to play back wav files from LittleFs on my ESP32 Audio Kit v2.2 2957 ES8388.
I got some problems:
First, the sound playback only works if the following is called from within the void setup()
Serial2.begin(MIDI_SERIAL2_BAUDRATE, SERIAL_8N1, MIDI_RX2_PIN);
Why is this necessary to get sound output? I am not using Midi at all...
EDIT:
I just went through the Sampler_Process() code to get a better understanding:
The pitch of the sample is defined by setting the number of bytes to add to the position after each call of the process function which is normally called at samplerate. As the values are 16bits to get the original speed this value needs to be 2 as each sample is constructed from two bytes.
Having this in mind the setting of the index for the new sample value in the data array can be understood like this:
samplePlayer[i].samplePos = samplePlayer[i].samplePosF;
The index must be an integer, this line just converts the "ideal value" at a specific playback speed, which was calculated before to an integer.
samplePlayer[i].samplePos -= samplePlayer[i].samplePos % 2;
This makes sure, that this index is always pointing to the first of the two bytes which form one 16bit sample value.
As i said before after each call of the process function the new ideal sample position is calculated.
samplePlayer[i].samplePosF += 2.0f * sampler_playback * samplePlayer[i].pitch;
Here the variable sampler_playback is the global pitch and the samplePlayer[i].pitch is the samples individual pitch.
For double speed (one octave) this value needs to be 2 ? for one chromatic step the multiplier is the 12th root of 2 or 2exp(1/12)
For two steps it would be 2exp(2/12) and so on.
Is this correct?
Then I want to understand that trick with the slowRelease:
slowRelease = slowRelease * 0.99; /* go slowly to zero */
Am I right that this only plays a role if a samle is retriggerd before reaching its end? It is just adding a exponential fade out form the sample value the sample playback is at in the moment of retriggering to the playback.
Is this correct? To shorten it one would just lower the factor of 0.99 a little right?
I realized that the first sample playback has a harder attack then the following onces and I believe it has something to do with the following line in the NoteOn code:
newSamplePlayer->sampleSeek = 44;
as the first time NoteOn is called after the SamplerInit this value is set to:
samplePlayer[i].sampleSeek = 0xFFFFFFFF;
Does this somehow lead to a softer attack to sample playback? I liked the sound of the first playback as it was more of punch. especially for a kickdrum sound.
And then, just for curiosity would you explain the following code ? I think the comments are somehow wrong (first byte of second half...)
The first line, I could understand somehow, it maps every possible Index of sample value to the range of the Blocksize * 2 (0-1023)
why isn't the blocksize just 1024 and read at once?
Beta Was this translation helpful? Give feedback.
All reactions