Just starting to work on a project that involves this;
Found a lot of problems coming from the AudioStreamPlaybackMyTone::mix
function.
I found that something from the docs was going past it's own memory bounds; causing lots of vague malloc
errors.
I also found that after I got past those issues I ran into AudioStreamMyTone::pos
growing too large after some time.
Using a float
based solution to generate the sine wave with a modulus wrap kept it within operational limits.
It is also not required to generate PCM-buffers; one could also generate a sinewave that is not bound to a buffer by math nature. I will probably put a youtube tutorial eventually when I finish the library I'm working on. But hopefully these snippets are enough to help passers-by
audiostream_mytone.cpp
This has been changed to use a float based solution with a cheap if-mod wrap.
I have also changed this function to a single float that increments the sine wave on call; I understand this to be bad practice but it works.
float AudioStreamMyTone::gen_tone(){
float inc = 1.0 / (float(mix_rate)/float(hz));
pos += inc;
if (pos > 1.0){
pos -= 1.0;
}
return sin(2.0 * Math_PI * pos);
}
audiostream_mytone.h
The header function must also be changed to match.
float pos;
// ...
float gen_tone();
audiostreamplayer_mytone.cpp
The mix function is causing a lot of issues; something has gone wrong with compatibility of this part of the docs and how memory gets allocated in the audio thread (OR something else I don't understand)
I changed the function to the code below to generate the sine-wave
void AudioStreamPlaybackMyTone::mix(AudioFrame *p_buffer,
float p_rate, int p_frames) {
ERR_FAIL_COND(!active);
if (!active) {
return;
}
for(int i = 0; i < p_frames; i++) {
float sample = base->gen_tone();
p_buffer[i] = AudioFrame(sample, sample);
}
}
After changing to this style of solution I see no harm in removing all buffer related code from the playback header and cpp files.
I would be interested in seeing if I'm writing terrible code as I am new to Rt-DSP but in theory I don't see any real downsides to this solution especially if memory allocation in the Audio thread is properly handled
Edit: Nov 19 2022
I found that for some reason; the AudioStreamPlaybackMyTone::mix
function was getting called with firstly around 2 Million frames in size, then it would repeatedly ask for 1024 frames. I'm not sure what is causing this overflow of steps on the first call to mix; but surely this isn't intended. I can't imagine asking for that many audio frames on playing the stream would do much of anything; I don't know the answer yet but I'm on the case.
This would mean that the buffer implementation is likely correct but something handling the mix
function is clearly calling it wrong. I will be back here with my notes.
There's clearly some WHACK things going on with the calls to mix
. on my laptop I was getting a call when requested to play for around 2 million frames. On my desktop now I get constant 10k frame requests until I hit play and then it settles to 1024. I really wonder what is causing these calls to mix
to clearly exceed the buffer written into the tutorial. I've determined this to be the issue; and also that removing the buffer entirely is fine for getting the custom audio stream to work, but that it would be seriously beneficial for realtime audio processing to be able to work with buffers.
I think mostly this is solved with an if statement in mix
to check if (p_frames > PCM_BUFFER_SIZE){return;}
but I am still getting inconsistent frame counts coming into mix
. When I find out who the dastardly dude who did this to us; I will correct his code and push it to the docs.