Sandro
Well-known member
Hi all,
I devoped a scrath of code which introduces a pitch functionality in play_serialflash_raw, using linear interpolation for calculating missing samples. This is my fork on Github:
https://github.com/PaulStoffregen/Audio/pull/259
this code runs fine, but apparently not fast enough to allow poliphony. This is the "core" part of the code that I'd like to boost:
Any suggestion? To be honest I did'nt check the poliphony of the original/unmodified play_serialflash_raw.cpp.
Thank you!
I devoped a scrath of code which introduces a pitch functionality in play_serialflash_raw, using linear interpolation for calculating missing samples. This is my fork on Github:
https://github.com/PaulStoffregen/Audio/pull/259
this code runs fine, but apparently not fast enough to allow poliphony. This is the "core" part of the code that I'd like to boost:
Code:
void AudioPlaySerialflashRaw::update(void)
{
unsigned int i, n;
audio_block_t *block;
int16_t samples_vector[2000]; // ***** current vector of samples read from file
int32_t h, k, j; // ***** indexes of samples
float virtual_index; // ***** likely not integer index
float index_delta; // ***** mantissa of virtual_index
int16_t h_sample_value, k_sample_value; // ***** samples value
int f, g, w; // ***** variables
int16_t samples_to_read; // ***** number of samples
// only update if we're playing
if (!playing) return;
// allocate the audio blocks to transmit
block = allocate();
if (block == NULL) return;
if (rawfile.available()) {
// ***** my main code starts here
t_0=micros(); // ***** calculating the computational time
first_index_to_read=((ride==0)? 0 :last_index_to_read+1);
last_index_to_read=ceil(((ride*128)+127)*pitch);
samples_to_read=last_index_to_read-first_index_to_read+1;
// ***** this part of code reads from file up to 128 samples per time; if we read more than 128 samples there are errors!. The result is the samples_vector[samples_to_read]
f=samples_to_read%128;
g=samples_to_read/128;
// ***** read one group of "f" samples
n = rawfile.read(block->data, f*2);
file_offset += n;
for (i=n/2; i < f; i++) {
block->data[i] = 0;
}
for (i=0; i < f; i++) {
samples_vector[i]=block->data[i];
}
// ***** read "g" groups of 128 samples
for (w=0; w<g; w++) {
n = rawfile.read(block->data, 128*2); // ***** read one group of f samples
file_offset += n;
for (i=n/2; i < 128; i++) {
block->data[i] = 0;
}
for (i=0; i < 128; i++) {
samples_vector[f+(w*128)+i]=block->data[i];
}
}
// ***** samples_vector[samples_to_read] is ready!
// ***** calculating block->data[128]
for (i=0;i<128;i++) {
j=i+(128*ride);
virtual_index=(float)(j)*pitch; // ***** virtual (it means that can be not-integer) index of the needed sample
h=floor(virtual_index); // ***** index of the lower sample needed for calculation
k=ceil(virtual_index); // ***** index of the upper sample needed for calculation
index_delta=virtual_index-h; // ***** mantissa
h=h-first_index_to_read; // ***** lower (relative) index of the sample needed for calculation
k=k-first_index_to_read; // ***** upper (relative) index of the sample needed for calculation
h_sample_value =((h==-2)? penultimate_sample: ((h==-1)? last_sample: samples_vector[h])); // ***** value of the lower sample needed for calculation
k_sample_value =((k==-2)? penultimate_sample: ((k==-1)? last_sample: samples_vector[k])); // ***** value of the upper sample needed for calculation
block->data[i]=h_sample_value + (index_delta*(k_sample_value-h_sample_value)); // ***** value of the calculated sample
}
penultimate_sample=samples_vector[k-1]; // ***** value of the penultimate sample read from file will be used in the next ride
last_sample=samples_vector[k]; // ***** value of the last sample read from file will be used in the next ride
ride ++;
t=micros()-t_0; // ***** calculating the computational time "t"
// ***** my main code ends here
transmit(block);
}
Any suggestion? To be honest I did'nt check the poliphony of the original/unmodified play_serialflash_raw.cpp.
Thank you!