0
votes

I would like to know how to know the relationship of the portaudio test examples and how to get the frequency.I was wondering how i could send a specifc frequency to sound card? 1. How to know the specific frequency of that the code send to sound card 2. How i could send sin(2*pi*f*t) and sin((2*pi*f*t)-3.14) which is a delayed version. Here is the code. Any help is highly appreciated

#include <stdio.h>
#include <math.h>
#include "portaudio.h"

#define NUM_SECONDS   (20)
#define SAMPLE_RATE   (44100)
#define AMPLITUDE     (0.9)
#define FRAMES_PER_BUFFER  (64)
#define OUTPUT_DEVICE Pa_GetDefaultOutputDeviceID()
//#define OUTPUT_DEVICE (2)

#ifndef M_PI
#define M_PI  (3.14159265)
#endif

#define TABLE_SIZE   (200)
typedef struct
{
    float sine[TABLE_SIZE];
     int left_phase;
    int right_phase;
}
paTestData;
static int patestCallback(   void *inputBuffer, void *outputBuffer,
                             unsigned long framesPerBuffer,
                             PaTimestamp outTime, void *userData )
{
    paTestData *data = (paTestData*)userData;
    float *out = (float*)outputBuffer;
    unsigned long i;
    int finished = 0;
    (void) outTime; /* Prevent unused variable warnings. */
    (void) inputBuffer;
    for( i=0; i<framesPerBuffer; i++ )
    {
        *out++ = data->sine[data->left_phase];  /* left */
        *out++ = data->sine[data->right_phase];  /* right */
        data->left_phase += 1;
    if( data->left_phase >= TABLE_SIZE ) data->left_phase -= TABLE_SIZE;
    data->right_phase +=2.57; /* higher pitch so we can distinguish left and right. */
    if( data->right_phase >= TABLE_SIZE ) data->right_phase -= TABLE_SIZE;
}
return finished;

}

/*******************************************************************/
int main(void);
int main(void)
{
PortAudioStream *stream;
PaError err;
paTestData data;
int i;
printf("PortAudio Test: output sine wave. SR = %d, BufSize = %d, devID = %d\n",
    SAMPLE_RATE, FRAMES_PER_BUFFER, OUTPUT_DEVICE);
/* initialise sinusoidal wavetable */
for( i=0; i<TABLE_SIZE; i++ )
{
    data.sine[i] = (float) (AMPLITUDE * sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. ));
}
data.left_phase = data.right_phase = 0;
err = Pa_Initialize();
if( err != paNoError ) goto error;
err = Pa_OpenStream(
          &stream,
          paNoDevice,/* default input device */
          0,              /* no input */
          paFloat32,  /* 32 bit floating point input */
          NULL,
          OUTPUT_DEVICE,
          2,          /* stereo output */
          paFloat32,      /* 32 bit floating point output */
          NULL,
          SAMPLE_RATE,
          FRAMES_PER_BUFFER,
          0,              /* number of buffers, if zero then use default minimum */
          paClipOff,      /* we won't output out of range samples so don't bother clipping them */
          patestCallback,
          &data );
if( err != paNoError ) goto error;
err = Pa_StartStream( stream );
if( err != paNoError ) goto error;
printf("Play for %d seconds.\n", NUM_SECONDS ); fflush(stdout);
Pa_Sleep( NUM_SECONDS * 1000 );

err = Pa_StopStream( stream );
if( err != paNoError ) goto error;
err = Pa_CloseStream( stream );
if( err != paNoError ) goto error;
Pa_Terminate();
printf("Test finished.\n");
return err;

error: Pa_Terminate(); fprintf( stderr, "An error occured while using the portaudio stream\n" ); fprintf( stderr, "Error number: %d\n", err ); fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); return err; }

1

1 Answers

2
votes

A quick look suggests SAMPLE_RATE / TABLE_SIZE will give you you the cycles per second for the sine wave, which appears to work out to be ~220Hz, which is an A3 note. Though from the code I can see the left channel is getting this wave and the right channel is stepping through the table at 2.75x the base rate which I guess would be about 606Hz which doesn't hit a note, I expect this sample sounds quite horrible!

To send the Sine and a delayed version you just look up the delayed version using an offset to the phase parameter, taking care to wrap around properly, and add the waves together. You'll probably want to lower the AMPLITUDE to avoid clipping.