1

I am having trouble generating specific frequencies in PortAudio, whenever I try and change the frequency inside of the sin(n * FREQ * 2 * PI / SAMPLE_RATE) the frequency remains the same however the sound does seem to change in timbre, the higher the frequency value I put in there the uglier the sound, yet the same frequency. This is what I have in my patestCallback loop:

static int patestCallback( const void *inputBuffer, void *outputBuffer,
                           unsigned long framesPerBuffer,
                           const PaStreamCallbackTimeInfo *timeInfo,
                           PaStreamCallbackFlags statusFlags,
                           void *userData )
{
   paTestData *data = (paTestData*)userData;
   float *out = (float*)outputBuffer;

   (void) timeInfo;
   (void) statusFlags;
   (void) inputBuffer;
   unsigned long n = 0;
   for(unsigned long i = 0; i<framesPerBuffer;i++,n++){
      float v = sin ( 261.626 * 2 * M_PI * ((float) n / (float) TABLE_SIZE) );
      *out++ = v;
      *out++ = v;
   }

   return paContinue;
}
pinckerman
  • 4,115
  • 6
  • 33
  • 42

1 Answers1

3

Simple solution:

static unsigned long n = 0;

You currently reset n in every function call, which leads to clicks at the begin of each new buffer and to those ugly sounds you hear. The more the period of the sine differs from the buffer length the uglier it sounds.

André Bergner
  • 1,429
  • 10
  • 10
  • 1
    This suggestion should work (+1). Another solution might be to make n part of userData. This might be better in case you ever need to reset it externally or end up with multiple callbacks or something like that. – Bjorn Roche Feb 13 '13 at 14:50
  • Yes, of course. Ideally, userData would be a struct or class containing the state of the actual audio engine. – André Bergner Feb 13 '13 at 15:19
  • Ok I put it all in a struct, it works beautifully thank you!... I think that I am having trouble conceptualizing how portaudio works, so does it continuously call patestCallback after each framesPerBuffer loop? Also, is it possible to write maybe 3 or 4 sine waves to the output so I can make chords? – Nicholas Smith Feb 13 '13 at 20:29
  • Yes, sure just add several sines together with a different frequency each. However, the brute force sin() function is very expansive. There are way more efficient techniques to integrate a sine recursively. – André Bergner Feb 14 '13 at 10:30
  • Oh ok, that is the purpose of the table in most portaudio examples correct? – Nicholas Smith Feb 15 '13 at 01:53