# PortAudio: sound fade in/out by scaling sample data

I've done already some fade in or fade out effect in portaudio, but that is not working properly.

My callback function:

int SoundEngine::patestCallback(const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo, PaStreamCallbackFlags statusFlags, void *userData)
{
float *out = (float*)outputBuffer;
float sample;
unsigned long i;

(void) timeInfo; /* Prevent unused variable warnings. */
(void) statusFlags;
(void) inputBuffer;

for( i=0; i < framesPerBuffer; i++ )
{
sample = callData->sine[callData->phase++];
*out++ = sample;

if( callData->phase >= SE_TABLE_SIZE ) callData->phase -= SE_TABLE_SIZE;
}
return paContinue;
}


I've discovered that for whole stream it's easy to make fade out effect, by applying something like this:

if(callData->fadeFlag == true)
{
callData->toneCountdown--;
sample *= (-cos(((float)(callData->toneCountdown - (callData->toneLength - callData->fadeOut)) / (float)callData->fadeOut) * M_PI) + 1.) * .5;
}


But this is not working for me. If I have more than one sound at the moment, there are fading all sounds. At the moment I'm using callback function as I wrote above. callData->sine at the beginning contains only 0 to not produce any sound. Sound I'm adding by calling a member function playSound(). I am doing this in single thread - so I can use a lot of these functions at the same time - making a multiple sounds. How is working function playSound? There it is:

void SoundEngine::playSound(int instrument, int freq, int duration)
{
if(instrument == 0)
{
for(int j=0; j<20; j++)
{
for(int i=0; i<SE_TABLE_SIZE; i++)
{
data.sine[i] += 0.01*sin(2 * M_PI * data.soundPitch[freq] * ((double)i/(double)SAMPLE_RATE));
}
}
Pa_Sleep(duration);
for(int j=0; j<20; j++)
{
for(int i=0; i<SE_TABLE_SIZE; i++)
{
data.sine[i] -= 0.01*sin(2 * M_PI * data.soundPitch[freq] * ((double)i/(double)SAMPLE_RATE));
}
}
}
}


You are probably asking now: "What the hell that man done here?". I know that it's not a masterpiece of coding, but I'm newbie in sound programming, so I'm trying my best to learn it. For now I want just make it work as it should work.

Function playSound() is working great, but fade in/out is making some noise during fadeing. Fade effect is made by for(int j=0; j<20; j++) that's gradually volume up my sound. I think that modyfing data.sinedata couse those noises. When I slow down fade effect - it works perfectly, but too slow. I need fast fade in/out effect to eliminate noises at start and end of sound.

Can someone help me to apply fade in/out effect to my example?

• Were you able to figure this out? If so, would you be willing to post your solution as an answer? I am also starting out with audio programming, and am curious. Thanks! – cxw Jun 15 '18 at 2:12
• Unfortunately, I've not done it. I guess that the right way is to apply effect to stream instead of modyfing all samples in table. Good luck ;] – Lizard_Paszczyk Jun 18 '18 at 8:10
• Thanks! You mentioned single-threaded, but does PortAudio create its own threads? I wonder if it's a race on data.sine. --- Not an answer, but I was able to get pop-free music playback by using a pa_ringbuffer: file reader; callback (audio-utsl repo). – cxw Jun 18 '18 at 12:07