PortAudio mic picking up audio from speaker - c

I have the following program:
#include <stdio.h>
#include <stdlib.h>
#include "portaudio.h"
/* #define SAMPLE_RATE (17932) // Test failure to open with this value. */
#define SAMPLE_RATE (44100)
#define FRAMES_PER_BUFFER (512)
#define NUM_SECONDS (5)
#define NUM_CHANNELS (2)
/* #define DITHER_FLAG (paDitherOff) */
#define DITHER_FLAG (0) /**/
/** Set to 1 if you want to capture the recording to a file. */
#define WRITE_TO_FILE (0)
/* Select sample format. */
#if 1
#define PA_SAMPLE_TYPE paFloat32
typedef float SAMPLE;
#define SAMPLE_SILENCE (0.0f)
#define PRINTF_S_FORMAT "%.8f"
#elif 1
#define PA_SAMPLE_TYPE paInt16
typedef short SAMPLE;
#define SAMPLE_SILENCE (0)
#define PRINTF_S_FORMAT "%d"
#elif 0
#define PA_SAMPLE_TYPE paInt8
typedef char SAMPLE;
#define SAMPLE_SILENCE (0)
#define PRINTF_S_FORMAT "%d"
#else
#define PA_SAMPLE_TYPE paUInt8
typedef unsigned char SAMPLE;
#define SAMPLE_SILENCE (128)
#define PRINTF_S_FORMAT "%d"
#endif
typedef struct
{
int frameIndex; /* Index into sample array. */
int maxFrameIndex;
SAMPLE *recordedSamples;
}
paTestData;
/* This routine will be called by the PortAudio engine when audio is needed.
** It may be called at interrupt level on some machines so don't do anything
** that could mess up the system like calling malloc() or free().
*/
static int recordCallback( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
paTestData *data = (paTestData*)userData;
const SAMPLE *rptr = (const SAMPLE*)inputBuffer;
SAMPLE *wptr = &data->recordedSamples[data->frameIndex * NUM_CHANNELS];
long framesToCalc;
long i;
int finished;
unsigned long framesLeft = data->maxFrameIndex - data->frameIndex;
(void) outputBuffer; /* Prevent unused variable warnings. */
(void) timeInfo;
(void) statusFlags;
(void) userData;
if( framesLeft < framesPerBuffer )
{
framesToCalc = framesLeft;
finished = paComplete;
}
else
{
framesToCalc = framesPerBuffer;
finished = paContinue;
}
if( inputBuffer == NULL )
{
for( i=0; i<framesToCalc; i++ )
{
*wptr++ = SAMPLE_SILENCE; /* left */
if( NUM_CHANNELS == 2 ) *wptr++ = SAMPLE_SILENCE; /* right */
}
}
else
{
for( i=0; i<framesToCalc; i++ )
{
*wptr++ = *rptr++; /* left */
if( NUM_CHANNELS == 2 ) *wptr++ = *rptr++; /* right */
}
}
data->frameIndex += framesToCalc;
return finished;
}
/* This routine will be called by the PortAudio engine when audio is needed.
** It may be called at interrupt level on some machines so don't do anything
** that could mess up the system like calling malloc() or free().
*/
static int playCallback( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
paTestData *data = (paTestData*)userData;
SAMPLE *rptr = &data->recordedSamples[data->frameIndex * NUM_CHANNELS];
SAMPLE *wptr = (SAMPLE*)outputBuffer;
unsigned int i;
int finished;
unsigned int framesLeft = data->maxFrameIndex - data->frameIndex;
(void) inputBuffer; /* Prevent unused variable warnings. */
(void) timeInfo;
(void) statusFlags;
(void) userData;
if( framesLeft < framesPerBuffer )
{
/* final buffer... */
for( i=0; i<framesLeft; i++ )
{
*wptr++ = *rptr++; /* left */
if( NUM_CHANNELS == 2 ) *wptr++ = *rptr++; /* right */
}
for( ; i<framesPerBuffer; i++ )
{
*wptr++ = 0; /* left */
if( NUM_CHANNELS == 2 ) *wptr++ = 0; /* right */
}
data->frameIndex += framesLeft;
finished = paComplete;
}
else
{
for( i=0; i<framesPerBuffer; i++ )
{
*wptr++ = *rptr++; /* left */
if( NUM_CHANNELS == 2 ) *wptr++ = *rptr++; /* right */
}
data->frameIndex += framesPerBuffer;
finished = paContinue;
}
return finished;
}
/*******************************************************************/
int main(void);
int main(void)
{
PaStreamParameters inputParameters,
outputParameters;
PaStream* stream;
PaError err = paNoError;
paTestData data;
int i;
int totalFrames;
int numSamples;
int numBytes;
SAMPLE max, val;
double average;
printf("patest_record.c\n"); fflush(stdout);
data.maxFrameIndex = totalFrames = NUM_SECONDS * SAMPLE_RATE; /* Record for a few seconds. */
data.frameIndex = 0;
numSamples = totalFrames * NUM_CHANNELS;
numBytes = numSamples * sizeof(SAMPLE);
data.recordedSamples = (SAMPLE *) malloc( numBytes ); /* From now on, recordedSamples is initialised. */
if( data.recordedSamples == NULL )
{
printf("Could not allocate record array.\n");
goto done;
}
for( i=0; i<numSamples; i++ ) data.recordedSamples[i] = 0;
err = Pa_Initialize();
if( err != paNoError ) goto done;
inputParameters.device = Pa_GetDefaultInputDevice(); /* default input device */
if (inputParameters.device == paNoDevice) {
fprintf(stderr,"Error: No default input device.\n");
goto done;
}
inputParameters.channelCount = 2; /* stereo input */
inputParameters.sampleFormat = PA_SAMPLE_TYPE;
inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency;
inputParameters.hostApiSpecificStreamInfo = NULL;
/* Record some audio. -------------------------------------------- */
err = Pa_OpenStream(
&stream,
&inputParameters,
NULL, /* &outputParameters, */
SAMPLE_RATE,
FRAMES_PER_BUFFER,
paClipOff, /* we won't output out of range samples so don't bother clipping them */
recordCallback,
&data );
if( err != paNoError ) goto done;
err = Pa_StartStream( stream );
if( err != paNoError ) goto done;
printf("\n=== Now recording!! Please speak into the microphone. ===\n"); fflush(stdout);
while( ( err = Pa_IsStreamActive( stream ) ) == 1 )
{
Pa_Sleep(1000);
printf("index = %d\n", data.frameIndex ); fflush(stdout);
}
if( err < 0 ) goto done;
err = Pa_CloseStream( stream );
if( err != paNoError ) goto done;
/* Measure maximum peak amplitude. */
max = 0;
average = 0.0;
for( i=0; i<numSamples; i++ )
{
val = data.recordedSamples[i];
if( val < 0 ) val = -val; /* ABS */
if( val > max )
{
max = val;
}
average += val;
}
average = average / (double)numSamples;
printf("sample max amplitude = "PRINTF_S_FORMAT"\n", max );
printf("sample average = %lf\n", average );
/* Write recorded data to a file. */
#if WRITE_TO_FILE
{
FILE *fid;
fid = fopen("recorded.raw", "wb");
if( fid == NULL )
{
printf("Could not open file.");
}
else
{
fwrite( data.recordedSamples, NUM_CHANNELS * sizeof(SAMPLE), totalFrames, fid );
fclose( fid );
printf("Wrote data to 'recorded.raw'\n");
}
}
#endif
/* Playback recorded data. -------------------------------------------- */
data.frameIndex = 0;
outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
if (outputParameters.device == paNoDevice) {
fprintf(stderr,"Error: No default output device.\n");
goto done;
}
outputParameters.channelCount = 2; /* stereo output */
outputParameters.sampleFormat = PA_SAMPLE_TYPE;
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
outputParameters.hostApiSpecificStreamInfo = NULL;
printf("\n=== Now playing back. ===\n"); fflush(stdout);
err = Pa_OpenStream(
&stream,
NULL, /* no input */
&outputParameters,
SAMPLE_RATE,
FRAMES_PER_BUFFER,
paClipOff, /* we won't output out of range samples so don't bother clipping them */
playCallback,
&data );
if( err != paNoError ) goto done;
if( stream )
{
err = Pa_StartStream( stream );
if( err != paNoError ) goto done;
printf("Waiting for playback to finish.\n"); fflush(stdout);
while( ( err = Pa_IsStreamActive( stream ) ) == 1 ) Pa_Sleep(100);
if( err < 0 ) goto done;
err = Pa_CloseStream( stream );
if( err != paNoError ) goto done;
printf("Done.\n"); fflush(stdout);
}
done:
Pa_Terminate();
if( data.recordedSamples ) /* Sure it is NULL or valid. */
free( data.recordedSamples );
if( err != paNoError )
{
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 ) );
err = 1; /* Always return 0 or 1, but no other return codes. */
}
return err;
}
This can also be found here: http://files.portaudio.com/docs/v19-doxydocs/paex__record_8c_source.html
I noticed when I started recording section, if I have something playing on my speaker, portaudio will pick up that sound as well. Is there anyway to configure port audio not to pick up that sound?

Related

C - simultaneous audio input and output using portaudio and callback function

I am trying to make a full duplex audio program that detects audio input from the mic and direct it to the speaker in real time using portaudio library and callback function but I keep getting errors. I tried to open a full input output stream then starting the read from the mic and send the captured data to a callback function that will start the streaming of audio to the speaker
Can anyone help me with this ??
Here is the errors:
ALSA lib pcm.c:2495:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.rear
ALSA lib pcm.c:2495:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.center_lfe
ALSA lib pcm.c:2495:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.side
ALSA lib pcm_route.c:867:(find_matching_chmap) Found no matching channel map
ALSA lib pcm_route.c:867:(find_matching_chmap) Found no matching channel map
ALSA lib pcm_route.c:867:(find_matching_chmap) Found no matching channel map
ALSA lib pcm_route.c:867:(find_matching_chmap) Found no matching channel map
Output device # 14.
Output LL: 0.00870748 s
Output HL: 0.0348299 s
Now recording!!
An error occured while using the portaudio stream
Error number: -9988
Error message: Invalid stream pointer
An error occured while using the portaudio stream
Error number: -9988
Error message: Invalid stream pointer
An error occured while using the portaudio stream
Error number: -9977
Error message: Can't read from a callback stream
and this is my code:
#include "diffusion.c"
#include "confusion.c"
#include "portaudio.h"
#include "wave_file.c"
/* #define SAMPLE_RATE (17932) // Test failure to open with this value. */
#define SAMPLE_RATE (44100)
#define FRAMES_PER_BUFFER (0)
#define NUM_SECONDS (2)
#define NUM_CHANNELS (2)
/* #define DITHER_FLAG (paDitherOff) */
#define DITHER_FLAG (0) /**/
#define WRITE_TO_WAVE_FILE (1)
/* define sample format. */
#define PA_SAMPLE_TYPE paInt16
typedef short SAMPLE;
#define SAMPLE_SILENCE (0)
#define PRINTF_S_FORMAT "%d"
PaStreamParameters inputParameters, outputParameters;
PaStream *stream;
PaError err;
SAMPLE *recordedSamples, *recordedSamples2;
int i;
int totalFrames;
int numSamples;
int numBytes;
static int playCallback (const void *input,
void *output,
unsigned long frameCount,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData
)
{
err = Pa_StartStream( stream );
if( err != paNoError ) goto error;
printf("Now recording!!\n"); fflush(stdout);
err = Pa_WriteStream( stream, userData, totalFrames );
if( err != paNoError ) goto error;
err = Pa_CloseStream( stream );
if( err != paNoError ) goto error;
free( userData );
return paContinue;
error:
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 paContinue;
}
int main(void);
int main(void)
{
PaStreamParameters inputParameters, outputParameters;
PaStream *stream;
PaError err;
SAMPLE *recordedSamples, *recordedSamples2;
int i;
int totalFrames;
int numSamples;
int numBytes;
printf("patest_read_record.c\n"); fflush(stdout);
totalFrames = NUM_SECONDS * SAMPLE_RATE; /* Record for a few seconds. */
numSamples = totalFrames * NUM_CHANNELS;
numBytes = numSamples * sizeof(SAMPLE);
recordedSamples = (SAMPLE *) malloc( numBytes );
if( recordedSamples == NULL )
{
printf("Could not allocate record array.\n");
exit(1);
}
for( i=0; i<numSamples; i++ ) recordedSamples[i] = 0;
err = Pa_Initialize();
if( err != paNoError ) goto error;
inputParameters.device = Pa_GetDefaultInputDevice(); /* default input device */
if (inputParameters.device == paNoDevice) {
fprintf(stderr,"Error: No default input device.\n");
goto error;
}
inputParameters.channelCount = NUM_CHANNELS;
inputParameters.sampleFormat = PA_SAMPLE_TYPE;
inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency;
inputParameters.hostApiSpecificStreamInfo = NULL;
outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
printf( "Output device # %d.\n", outputParameters.device );
printf( "Output LL: %g s\n", Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency );
printf( "Output HL: %g s\n", Pa_GetDeviceInfo( outputParameters.device )->defaultHighOutputLatency );
outputParameters.channelCount = NUM_CHANNELS;
outputParameters.sampleFormat = PA_SAMPLE_TYPE;
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultHighOutputLatency;
outputParameters.hostApiSpecificStreamInfo = NULL;
/* Record some audio. -------------------------------------------- */
err = Pa_OpenStream(
&stream,
&inputParameters,
&outputParameters, /* &outputParameters, */
SAMPLE_RATE,
paFramesPerBufferUnspecified,
paClipOff, /* we won't output out of range samples so don't bother clipping them */
playCallback, /* no callback, use blocking API */
recordedSamples ); /* no callback, so no callback userData */
if( err != paNoError ) goto error;
err = Pa_StartStream( stream );
if( err != paNoError ) goto error;
printf("Now recording!!\n"); fflush(stdout);
err = Pa_ReadStream( stream, recordedSamples, totalFrames );
if( err != paNoError ) goto error;
err = Pa_CloseStream( stream );
if( err != paNoError ) goto error;
/* save the recorded data in a wave file " recording.wav ". -------------------------- */
saveInWaveFile(recordedSamples, totalFrames, "recording.wav");
for (int i =0; i< numSamples ; i++){
recordedSamples2[i] = recordedSamples[i];
}
free( recordedSamples );
Pa_Terminate();
return 0;
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 -1;
}
First make sure that the default input and output devices are correct. You can do that by first running the pa_devs.c example in the examples folder to print a list of enabled audio devices connected to the computer. Once you have identified the correct devices, replace the lines with the device number e.g.
inputParameters.device = Pa_GetDefaultInputDevice();
for
inputParameters.device = <device number (e.g. 11)>;
and
outputParameters.device = Pa_GetDefaultOutputDevice();
for
outputParameters.device = <device number (e.g. 11)>;
Another avenue you can try is the example called paex_read_write_wire.c. This should achieve the same functionality you're talking about however uses a blocking approach rather than the callback function you have used in your code.
I can not test it now, but it should play (monitor) the input buffer (the microphone):
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;
unsigned int i;
float *in = (float*)inputBuffer;
for( i=0; i<framesPerBuffer; i++ )
{
out++ = in++; /* left */
out++ = in++; /* right*/
}
return 0;
}

Unable to read memory after allocate from a function which referenced in main function

I have a function which is called get_audio_signal(). This function is called in main thread.
This is main file and main function:
#include <stdio.h>
#include <stdlib.h>
#include "record.h"
/*******************************************************************/
int main(void);
int main(void)
{
SAMPLE *tmp = get_audio_signal();
free(tmp);
return 1;
}
get_audio_signal was declared in record.h. Here is get_audio_signal() function:
SAMPLE* get_audio_signal()
{
PaStreamParameters inputParameters, outputParameters;
PaStream *stream;
PaError err;
SAMPLE *recordedSamples;
int i;
int totalFrames;
int numSamples;
int numBytes;
SAMPLE max, average, val;
printf("patest_read_record.c\n"); fflush(stdout);
totalFrames = NUM_SECONDS * SAMPLE_RATE; /* Record for a few seconds. */
numSamples = totalFrames * NUM_CHANNELS;
numBytes = numSamples * sizeof(SAMPLE);
recordedSamples = (SAMPLE *)malloc(numBytes);
if (recordedSamples == NULL)
{
printf("Could not allocate record array.\n");
exit(1);
}
//printf("%f ", *recordedSamples);
for (i = 0; i<numSamples; i++) recordedSamples[i] = 0;
err = Pa_Initialize();
if (err != paNoError) goto error;
inputParameters.device = Pa_GetDefaultInputDevice(); /* default input
device */
if (inputParameters.device == paNoDevice) {
fprintf(stderr, "Error: No default input device.\n");
goto error;
}
inputParameters.channelCount = NUM_CHANNELS;
inputParameters.sampleFormat = PA_SAMPLE_TYPE;
inputParameters.suggestedLatency =
Pa_GetDeviceInfo(inputParameters.device)->defaultLowInputLatency;
inputParameters.hostApiSpecificStreamInfo = NULL;
/* Record some audio. -------------------------------------------- */
err = Pa_OpenStream(
&stream,
&inputParameters,
NULL, /* &outputParameters, */
SAMPLE_RATE,
FRAMES_PER_BUFFER,
paClipOff, /* we won't output out of range samples so don't
bother clipping them */
NULL, /* no callback, use blocking API */
NULL); /* no callback, so no callback userData */
if (err != paNoError) goto error;
err = Pa_StartStream(stream);
if (err != paNoError) goto error;
printf("Now recording!!\n"); fflush(stdout);
err = Pa_ReadStream(stream, recordedSamples, totalFrames);
if (err != paNoError) goto error;
err = Pa_CloseStream(stream);
if (err != paNoError) goto error;
return recordedSamples;
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 -1;
}
My issue is, when i allocate for recordedSamples by using malloc then recoredSamples is unable to read memory. Hence, it make my assignment for recordedSamples crash. The error return is "Access violation writing location".
Here is the path that made the program crashed:
recordedSamples = (SAMPLE *)malloc(numBytes);
if (recordedSamples == NULL)
{
printf("Could not allocate record array.\n");
exit(1);
}
//printf("%f ", *recordedSamples);
for (i = 0; i<numSamples; i++) recordedSamples[i] = 0;
Here is constant define.
#define SAMPLE_RATE (16000)
#define FRAMES_PER_BUFFER (1024)
#define NUM_SECONDS (5)
#define NUM_CHANNELS (1)
#define DITHER_FLAG (0) /**/
#define PA_SAMPLE_TYPE paFloat32
typedef float SAMPLE;
#define SAMPLE_SILENCE (0.0f)
#define PRINTF_S_FORMAT "%.8f"
Can anyone explain for me!!!

PortAudio microphone capture, separate channel values

I'm using a microphone array (playstation eye) with PortAudio. I'm attempting microphone array processing where I can know the level of each microphone and specify the direction of a sound using beam forming or inter aural time delays. I'm having trouble determining which sound levels come from each channel.
Here is some code snippets, the first being the recordCallback.
static int recordCallback( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
paTestData *data = (paTestData*)userData;
const SAMPLE *rptr = (const SAMPLE*)inputBuffer;
SAMPLE *wptr = &data->recordedSamples[data->frameIndex * NUM_CHANNELS];
long framesToCalc;
long i;
int finished;
unsigned long framesLeft = data->maxFrameIndex - data->frameIndex;
(void) outputBuffer; /* Prevent unused variable warnings. */
(void) timeInfo;
(void) statusFlags;
(void) userData;
if( framesLeft < framesPerBuffer )
{
framesToCalc = framesLeft;
finished = paComplete;
}
else
{
framesToCalc = framesPerBuffer;
finished = paContinue;
}
if( inputBuffer == NULL )
{
for( i=0; i<framesToCalc; i++ )
{
*wptr++ = SAMPLE_SILENCE; /* 1 */
if( NUM_CHANNELS =>= 2 ) *wptr++ = SAMPLE_SILENCE; /* 2 */
if( NUM_CHANNELS =>= 3 ) *wptr++ = SAMPLE_SILENCE; /* 3 */
if( NUM_CHANNELS >= 4 ) *wptr++ = SAMPLE_SILENCE; /* 4 */
}
}
else
{
for( i=0; i<framesToCalc; i++ )
{
*wptr++ = *rptr++; /* 1 */
if( NUM_CHANNELS >= 2 ) *wptr++ = *rptr++; /* 2 */
if( NUM_CHANNELS >= 3 ) *wptr++ = *rptr++; /* 3 */
if( NUM_CHANNELS >= 4 ) *wptr++ = *rptr++; /* 4 */
}
}
data->frameIndex += framesToCalc;
return finished;
}
Here is the main method where I'm playing back the audio and trying to show channel averages.
int main(void)
{
PaStreamParameters inputParameters,
outputParameters;
PaStream* stream;
PaError err = paNoError;
paTestData data;
int i;
int totalFrames;
int numSamples;
int numBytes;
SAMPLE max, val;
double average;
printf("patest_record.c\n"); fflush(stdout);
data.maxFrameIndex = totalFrames = NUM_SECONDS * SAMPLE_RATE; /* Record for a few seconds. */
data.frameIndex = 0;
numSamples = totalFrames * NUM_CHANNELS;
numBytes = numSamples * sizeof(SAMPLE);
data.recordedSamples = (SAMPLE *) malloc( numBytes ); /* From now on, recordedSamples is initialised. */
if( data.recordedSamples == NULL )
{
printf("Could not allocate record array.\n");
goto done;
}
for( i=0; i<numSamples; i++ ) data.recordedSamples[i] = 0;
err = Pa_Initialize();
if( err != paNoError ) goto done;
inputParameters.device = 2; /* default input device */
if (inputParameters.device == paNoDevice) {
fprintf(stderr,"Error: No default input device.\n");
goto done;
}
inputParameters.channelCount = 2; /* stereo input */
inputParameters.sampleFormat = PA_SAMPLE_TYPE;
inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency;
inputParameters.hostApiSpecificStreamInfo = NULL;
/* Record some audio. -------------------------------------------- */
err = Pa_OpenStream(
&stream,
&inputParameters,
NULL, /* &outputParameters, */
SAMPLE_RATE,
FRAMES_PER_BUFFER,
paClipOff, /* we won't output out of range samples so don't bother clipping them */
recordCallback,
&data );
if( err != paNoError ) goto done;
err = Pa_StartStream( stream );
if( err != paNoError ) goto done;
printf("\n=== Now recording!! Please speak into the microphone. ===\n"); fflush(stdout);
while( ( err = Pa_IsStreamActive( stream ) ) == 1 )
{
Pa_Sleep(1000);
printf("index = %d\n", data.frameIndex ); fflush(stdout);
printf("Channel = %d\n", data.currentChannel ); fflush(stdout);
}
if( err < 0 ) goto done;
err = Pa_CloseStream( stream );
if( err != paNoError ) goto done;
/* Measure maximum peak amplitude. */
/* average for each channel */
SAMPLE channel1val =0;
SAMPLE channel2val = 0;
SAMPLE channel3val =0;
SAMPLE channel4val = 0;
long channel1avg = 0.0;
long channel2avg =0.0;
long channel3avg =0.0;
long channel4avg =0.0;
SAMPLE channel1max = 0;
SAMPLE channel2max =0;
SAMPLE channel3max =0;
SAMPLE channel4max =0;
i = 0;
do
{
channel1val = data.recordedSamples[i];
if (channel1val < 0)
{
channel1val = -channel1val;
}
if (channel1val > channel1max)
{
channel1max = channel1val;
}
channel1avg += channel1val;
i = i + 4;
}
while (i<numSamples);
i = 1;
do
{
channel2val = data.recordedSamples[i];
if (channel2val < 0)
{
channel2val = -channel2val;
}
if (channel2val > channel2max)
{
channel2max = channel2val;
}
channel2avg += channel2val;
i = i + 4;
}
while (i<numSamples);
i = 2;
do
{
channel3val = data.recordedSamples[i];
if (channel3val < 0)
{
channel3val = -channel3val;
}
if (channel3val > channel3max)
{
channel3max = channel3val;
}
channel3avg += channel3val;
i = i + 4;
}
while (i<numSamples);
i = 3;
do
{
channel4val = data.recordedSamples[i];
if (channel4val < 0)
{
channel4val = -channel4val;
}
if (channel4val > channel4max)
{
channel4max = channel4val;
}
channel4avg += channel4val;
i = i + 4;
}
while (i<numSamples);
channel1avg = channel1avg / (double)numSamples;
channel2avg = channel2avg / (double)numSamples;
channel3avg = channel3avg / (double)numSamples;
channel4avg = channel4avg / (double)numSamples;
// printf("sample max amplitude = "PRINTF_S_FORMAT"\n", max );
// printf("sample average = %lf\n", average );
printf("channel1 max amplitude = "PRINTF_S_FORMAT"\n", channel1max);
printf("sample average = %lf\n", channel1avg);
printf("channel2 max amplitude = "PRINTF_S_FORMAT"\n", channel2max);
printf("sample average = %lf\n", channel2avg);
printf("channel3 max amplitude = "PRINTF_S_FORMAT"\n", channel3max);
printf("sample average = %lf\n", channel3avg);
printf("channel4 max amplitude = "PRINTF_S_FORMAT"\n", channel4max);
printf("sample average = %lf\n", channel4avg);
printf("/nPrinting out values/n");
for (int j=0; j<8; j++)
{
printf("Value: %lf\n", data.recordedSamples[j]);
}
/* Write recorded data to a file. */
#if WRITE_TO_FILE
{
FILE *fid;
fid = fopen("recorded.raw", "wb");
if( fid == NULL )
{
printf("Could not open file.");
}
else
{
fwrite( data.recordedSamples, NUM_CHANNELS * sizeof(SAMPLE), totalFrames, fid );
fclose( fid );
printf("Wrote data to 'recorded.raw'\n");
}
}
#endif
/* Playback recorded data. -------------------------------------------- */
data.frameIndex = 0;
outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
if (outputParameters.device == paNoDevice) {
fprintf(stderr,"Error: No default output device.\n");
goto done;
}
outputParameters.channelCount = 2; /* stereo output */
outputParameters.sampleFormat = PA_SAMPLE_TYPE;
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
outputParameters.hostApiSpecificStreamInfo = NULL;
printf("\n=== Now playing back. ===\n"); fflush(stdout);
err = Pa_OpenStream(
&stream,
NULL, /* no input */
&outputParameters,
SAMPLE_RATE,
FRAMES_PER_BUFFER,
paClipOff, /* we won't output out of range samples so don't bother clipping them */
playCallback,
&data );
if( err != paNoError ) goto done;
if( stream )
{
err = Pa_StartStream( stream );
if( err != paNoError ) goto done;
printf("Waiting for playback to finish.\n"); fflush(stdout);
while( ( err = Pa_IsStreamActive( stream ) ) == 1 ) Pa_Sleep(100);
if( err < 0 ) goto done;
err = Pa_CloseStream( stream );
if( err != paNoError ) goto done;
printf("Done.\n"); fflush(stdout);
}
done:
Pa_Terminate();
if( data.recordedSamples ) /* Sure it is NULL or valid. */
free( data.recordedSamples );
if( err != paNoError )
{
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 ) );
err = 1; /* Always return 0 or 1, but no other return codes. */
}
return err;
}
If I run my code and blow into one microphone I get this. When I play the sound back using my code, it works fine and the sound is correct, but looking at the values outputted:
channel1 max amplitude = 1.00000000
sample average = 1.000000
channel2 max amplitude = 0.02542114
sample average = 0.025421
channel3 max amplitude = 1.00000000
sample average = 1.000000
channel4 max amplitude = 0.02627563
sample average = 0.026276
Which clearly isn't correct. As it's showing that two channels are almost identical. From what I understand, as it's capturing linear PCM, it should be mapping channels such as
SAMPLE
[
{Channel1}
{Channel2}
{Channel3}
{Channel4}
]
Now the problem is, when I blow into one microphone on audacity (which uses core-audio drivers) I get this. Clearly one microphone has peak of 1 and the others are near silent.
So I don't understand what I'm doing wrong, any pointers?
It looks like you are only recording 2 channels
inputParameters.channelCount = 2; /* stereo input */
This would explain why ch 1 and 3, and ch 2 and 4 are measuring the same level because you're just skipping every other sample from the same channel.

encoding from rgb24 to mpeg4 and decoding from mpeg4 to rgb24 with libavcodec

Problem:
I am receiving rgb24 images from a webcam and am encoding them to mpeg4 using libavcodec. I am not able to decode them back to rgb24. avcodec_decode_video2 returns that it processed all of the input but the third parameter to avcodec_decode_video2 always returns 0.
What works:
Prior to calling avcodec_encode_video2, the rgb24 image is converted to yuv420p format via sws_scale. This works properly as I can take the result from sws_scale and convert it back to rgb24 successfully. I can view the results on the screen which is how I now this part works.
Description:
For each image returned from avcodec_encode_video2, I am calling another function that will decode it back to it rgb24. This scenario is setup for testing purposes to ensure I can encode/decode successfully. Below summarizes what is happening in the code:
/* variable declarations */
...
/* main processing */
while( true )
{
rgb24 = getRgb24();
sws_scale( ..., &rgb24, ..., frame->data, ... );
/* sws_scale is successful */
ret = avcodec_encode_video2( ..., &pkt, frame, &got_output );
/* avcodec_encode_video2 returns success and got_output is 1 */
/* copy encoded image to another buffer */
memcpy( hugebuffer, pkt.data, pkt.size );
memcpy( hugebuffer + pkt.size, 0, FF_INPUT_BUFFER_PADDING_SIZE );
av_init_packet( &decodePacket );
decodePacket.data = hugebuffer;
decodePacket.size = pkt.size;
len = avcodec_decode_video2( ..., decodeFrame, &got_output, &decodePacket );
/* len = pkt.size but got_output is ALWAYS 0 */
}
I wonder if there is something else I need to do before calling the decode function???
For reference, I have provided the actual code below which includes the following four functions: videoEncodeInit, videoEncode, videoDecodeInit, videoDecode. After that, I have posted how the functions are called.
/*
* Copyright (c) 2001 Fabrice Bellard
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/**
* #file
* libavcodec API use example.
*
* Note that libavcodec only handles codecs (mpeg, mpeg4, etc...),
* not file formats (avi, vob, mp4, mov, mkv, mxf, flv, mpegts, mpegps, etc...). See library 'libavformat' for the
* format handling
* #example doc/examples/decoding_encoding.c
*/
#include <math.h>
extern "C"
{
#include <libavutil/opt.h>
#include <libavcodec/avcodec.h>
#include <libavutil/channel_layout.h>
#include <libavutil/common.h>
#include <libavutil/imgutils.h>
#include <libavutil/mathematics.h>
#include <libavutil/samplefmt.h>
#include <libswscale/swscale.h>
}
#include "video.h"
#include "logmsg.h"
typedef struct
{
AVCodec *codec;
AVCodecContext *c;
AVFrame *frame;
SwsContext *yuv420p_to_rgb24_ctx;
int frame_count;
} PrivateVideoDecodeParams;
static AVCodec *codec = 0;
static AVCodecContext *c = 0;
static AVFrame *frame = 0;
static SwsContext *rgb24_to_yuv420p_ctx = 0;
static int registered = 0;
extern int g_debug; /* from main.cpp */
int videoEncodeInit( VideoEncodeParams *ep )
{
int ret;
if( registered == 0 )
{
avcodec_register_all();
registered = 1;
}
if( c != 0 )
{
avcodec_close(c);
av_free(c);
}
if( frame && frame->data[0] )
{
av_freep(&frame->data[0]);
avcodec_free_frame(&frame);
}
if( rgb24_to_yuv420p_ctx )
{
sws_freeContext( rgb24_to_yuv420p_ctx );
}
/* find the mpeg1 video encoder */
codec = avcodec_find_encoder(ep->codec_id);
if (!codec)
{
logmsg( "error - Codec=%d not found [%s:%d]\n", (int)ep->codec_id, __FILE__, __LINE__ );
return( -1 );
}
c = avcodec_alloc_context3(codec);
if (!c)
{
logmsg("error - Could not allocate video codec context [%s:%d]\n", __FILE__, __LINE__ );
return(-1);
}
/* put sample parameters */
c->bit_rate = 400000;
/* resolution must be a multiple of two */
c->width = ep->width; /* was hard coded at 352 */
c->height = ep->height; /* was hard coded at 288 */
/* frames per second */
c->time_base.den = 1;
c->time_base.num = ep->fps; /* was hard coded to 25 */
c->gop_size = 10; /* emit one intra frame every ten frames */
c->max_b_frames = 1;
c->pix_fmt = AV_PIX_FMT_YUV420P;
if(ep->codec_id == AV_CODEC_ID_H264)
{
av_opt_set(c->priv_data, "preset", "slow", 0);
}
/* open it */
ret = avcodec_open2(c, codec, NULL);
if( ret < 0)
{
logmsg( "error - Could not open codec [%s:%d]\n", __FILE__, __LINE__ );
return(-1);
}
frame = avcodec_alloc_frame();
if (!frame)
{
logmsg("error - Could not allocate video frame [%s:%d]\n", __FILE__, __LINE__ );
return(-1);
}
frame->format = c->pix_fmt;
frame->width = c->width;
frame->height = c->height;
/* the image can be allocated by any means and av_image_alloc() is
* just the most convenient way if av_malloc() is to be used */
ret = av_image_alloc(frame->data, frame->linesize, c->width, c->height, c->pix_fmt, 32);
if (ret < 0)
{
logmsg("error - Could not allocate raw picture buffer [%s:%d]\n", __FILE__, __LINE__ );
return( -1 );
}
rgb24_to_yuv420p_ctx = sws_getContext( ep->width, ep->height, AV_PIX_FMT_RGB24,
ep->width, ep->height, AV_PIX_FMT_YUV420P,
SWS_FAST_BILINEAR, 0, 0, 0 );
if( rgb24_to_yuv420p_ctx == 0 )
{
logmsg( "error - failed to create rb24 to yuv420p conversion scale [%s:%d]\n",
__FILE__, __LINE__ );
return( -1 );
}
return( 0 );
}
int videoEncode( VideoEncodeParams *ep )
{
AVPacket pkt;
int ret;
int got_output;
av_init_packet(&pkt);
pkt.data = 0; // packet data will be allocated by the encoder
pkt.size = 0;
frame->pts = ep->pts;
ep->pts++;
/* convert input to that expected by the encoder */
int srcStride = c->width * 3;
ret = sws_scale( rgb24_to_yuv420p_ctx, &ep->rgb24, &srcStride, 0, c->height, frame->data, frame->linesize );
/* encode the image */
ret = avcodec_encode_video2(c, &pkt, frame, &got_output);
if (ret < 0)
{
logmsg("error - Error encoding frame [%s:%d]\n", __FILE__, __LINE__ );
return(-1);
}
if (got_output)
{
if( g_debug )
{
logmsg("debug - Write frame %3d (size=%5d)\n", ep->pts-1, pkt.size);
}
ep->callback( ep, pkt.data, pkt.size );
av_free_packet(&pkt);
}
return( 0 );
}
int videoDecodeInit( VideoDecodeParams *dp )
{
PrivateVideoDecodeParams *pdp;
int ret;
if( registered == 0 )
{
avcodec_register_all();
registered = 1;
}
if( dp->rgb24_out )
{
free( dp->rgb24_out );
}
dp->rgb24_out = (unsigned char*)calloc( 1, dp->width * 3 * dp->height );
pdp = (PrivateVideoDecodeParams*)dp->priv;
if( pdp )
{
if( pdp->c != 0 )
{
avcodec_close(pdp->c);
av_free(pdp->c);
}
if( pdp->frame && pdp->frame->data[0] )
{
av_freep(&pdp->frame->data[0]);
avcodec_free_frame(&pdp->frame);
}
if( pdp->yuv420p_to_rgb24_ctx )
{
sws_freeContext( pdp->yuv420p_to_rgb24_ctx );
}
free( pdp );
}
dp->priv = calloc( 1, sizeof(*pdp) );
pdp = (PrivateVideoDecodeParams*)dp->priv;
/* find the video decoder */
if( pdp->codec == 0 )
{
pdp->codec = avcodec_find_decoder(dp->codec_id);
if (!pdp->codec)
{
logmsg("error - Codec not found=%d [%s:%d]\n", (int)dp->codec_id, __FILE__, __LINE__ );
return( -1 );
}
}
pdp->c = avcodec_alloc_context3(pdp->codec);
if (!pdp->c)
{
logmsg("error - Could not allocate video codec context [%s:%d]\n", __FILE__, __LINE__ );
return( -1 );
}
if(pdp->codec->capabilities & CODEC_CAP_TRUNCATED)
{
pdp->c->flags |= CODEC_FLAG_TRUNCATED; /* we do not send complete frames */
}
/* For some codecs, such as msmpeg4 and mpeg4, width and height
MUST be initialized there because this information is not
available in the bitstream. */
/* put sample parameters */
pdp->c->bit_rate = 400000;
/* resolution must be a multiple of two */
pdp->c->width = dp->width;
pdp->c->height = dp->height;
pdp->c->time_base.den = 1;
pdp->c->time_base.num = 25; /* was hard coded to 25 */
pdp->c->gop_size = 10; /* emit one intra frame every ten frames */
pdp->c->max_b_frames = 1;
pdp->c->pix_fmt = AV_PIX_FMT_YUV420P;
if(dp->codec_id == AV_CODEC_ID_H264)
{
av_opt_set(pdp->c->priv_data, "preset", "slow", 0);
}
/* open it */
if (avcodec_open2(pdp->c, pdp->codec, NULL) < 0)
{
logmsg("error - Could not open codec [%s:%d]\n", __FILE__, __LINE__ );
return( -1 );
}
pdp->frame = avcodec_alloc_frame();
if (!pdp->frame)
{
logmsg("error - Could not allocate video frame [%s:%d]\n", __FILE__, __LINE__ );
return( -1 );
}
pdp->frame->format = AV_PIX_FMT_YUV420P;
pdp->frame->width = c->width;
pdp->frame->height = c->height;
#if 0
/* the image can be allocated by any means and av_image_alloc() is
* just the most convenient way if av_malloc() is to be used */
ret = av_image_alloc(pdp->frame->data, pdp->frame->linesize, pdp->c->width, pdp->c->height, pdp->c->pix_fmt, 32);
if (ret < 0)
{
logmsg("error - Could not allocate raw picture buffer [%s:%d]\n", __FILE__, __LINE__ );
return( -1 );
}
#endif
pdp->yuv420p_to_rgb24_ctx = sws_getContext( dp->width, dp->height, AV_PIX_FMT_YUV420P,
dp->width, dp->height, AV_PIX_FMT_RGB24,
SWS_FAST_BILINEAR, 0, 0, 0 );
if( pdp->yuv420p_to_rgb24_ctx == 0 )
{
logmsg( "error - failed to create yuv420p to rb24 conversion scale [%s:%d]\n",
__FILE__, __LINE__ );
return( -1 );
}
return( 0 );
}
int videoDecode( VideoDecodeParams *dp )
{
static uint8_t *inbuf = 0;
static int inbufLen = 0;
PrivateVideoDecodeParams *pdp;
AVPacket avpkt;
int len;
int got_frame;
int srcStride;
int ret;
pdp = (PrivateVideoDecodeParams*)dp->priv;
/* Make sure we have a buffer to work with. */
if( inbuf == 0 )
{
/* get a big buffer */
inbufLen = 256000;
inbuf = (uint8_t*)calloc( 1, inbufLen );
}
if( (dp->yuv420_len + FF_INPUT_BUFFER_PADDING_SIZE) > inbufLen )
{
if( inbuf )
{
free( inbuf );
}
inbufLen = dp->yuv420_len + FF_INPUT_BUFFER_PADDING_SIZE;
inbuf = (uint8_t*)calloc( 1, inbufLen );
}
/* copy the video to our buffer */
memcpy( inbuf, dp->yuv420_in, dp->yuv420_len );
/* set end of buffer to 0 (this ensures that no overreading happens for damaged mpeg streams) */
memset( inbuf + dp->yuv420_len, 0, FF_INPUT_BUFFER_PADDING_SIZE );
av_init_packet(&avpkt);
avpkt.size = dp->yuv420_len;
avpkt.data = inbuf;
len = avcodec_decode_video2(pdp->c, pdp->frame, &got_frame, &avpkt);
if (len < 0)
{
logmsg("error - Error while decoding frame %d [%s:%d]\n", pdp->frame_count, __FILE__, __LINE__ );
return len;
}
if (got_frame)
{
logmsg( "got a frame\n" );
/* convert to RGB24 */
srcStride = pdp->c->width * 3;
ret = sws_scale( pdp->yuv420p_to_rgb24_ctx, pdp->frame->data, pdp->frame->linesize, 0, pdp->c->height, &dp->rgb24_out, &srcStride );
pdp->frame_count++;
}
else
{
logmsg( "no frame\n" );
}
return( got_frame );
}
Here's how the init functions are called:
videoEncodeInit :
ep.codec_id = AV_CODEC_ID_MPEG4;
ep.width = 352;
ep.height = 288;
ep.fps = 10;
ep.rgb24 = 0;
ep.pts = 0;
ep.callback = debug_videoEncodeCallback;
if( videoEncodeInit( &ep ) == -1 )
{
MyMessageBox( g_mainwindow, "Can't initialize video codec!", "Error", MB_OK | MB_ICONERROR );
exit( -1 );
}
videoDecodeInit:
dp.codec_id = AV_CODEC_ID_MPEG4;
dp.width = 352;
dp.height = 288;
videoDecodeInit( &dp );
videoEncode:

Generating sound of a particular frequency using gcc in ubuntu?

How can I generate sound of a particular frequency in C/C++ . I run Ubuntu 10.04 and use gcc. There is a void sound(int frequency) function on TurboC for Windows. Is there an equivalent for gcc?
Below is a code utilizing PortAudio library to generate a square audio wave of given frequency.
On Linux compile with gcc buzzer.c -o buzzer -lportaudio. Should compile fine for Windows as well. I do not know how the sound(int frequency) behaves exactly, but below should be able to simulate any usage of old-style buzzers. You might need a portaudio-devel (or equivalent for Ubuntu, portaudio-dev?) package and for Pulse Audio maybe some newer version of PortAudio that is in your repo. Compiling it is not a problem. You can use the below code on the terms of WTFPL license. :-) (it is derived from a PortAudio example)
#include <stdio.h>
#include <math.h>
#include "portaudio.h"
#include <stdint.h>
#include <unistd.h> // for usleep()
#define SAMPLE_RATE (44100)
#define FRAMES_PER_BUFFER (64)
typedef struct
{
uint32_t total_count;
uint32_t up_count;
uint32_t counter;
uint32_t prev_freq;
uint32_t freq;
} paTestData;
//volatile int freq = 0;
/* This routine will be called by the PortAudio engine when audio is needed.
** It may called at interrupt level on some machines so don't do anything
** that could mess up the system like calling malloc() or free().
*/
static int patestCallback( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
paTestData *data = (paTestData*)userData;
uint8_t *out = (uint8_t*)outputBuffer;
unsigned long i;
uint32_t freq = data->freq;
(void) timeInfo; /* Prevent unused variable warnings. */
(void) statusFlags;
(void) inputBuffer;
for( i=0; i<framesPerBuffer; i++ )
{
if(data->up_count > 0 && data->total_count == data->up_count) {
*out++ = 0x00;
continue;
}
data->total_count++;
if(freq != data->prev_freq) {
data->counter = 0;
}
if(freq) {
int overflow_max = SAMPLE_RATE / freq;
uint32_t data_cnt = data->counter % overflow_max;
if(data_cnt > overflow_max/2)
*out++ = 0xff;
else {
*out++ = 0x00;
}
data->counter++;
}
else {
data->counter = 0;
*out++ = 0;
}
data->prev_freq = freq;
}
return paContinue;
}
static PaStream *stream;
static paTestData data;
void buzzer_set_freq(int frequency)
{
data.up_count = 0; // do not stop!
data.freq = frequency;
}
void buzzer_beep(int frequency, int msecs)
{
data.total_count = 0;
data.up_count = SAMPLE_RATE * msecs / 1000;
data.freq = frequency;
}
int buzzer_start(void)
{
PaStreamParameters outputParameters;
PaError err;
int i;
err = Pa_Initialize();
if( err != paNoError ) goto error;
outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
outputParameters.channelCount = 1; /* stereo output */
outputParameters.sampleFormat = paUInt8; /* 32 bit floating point output */
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
outputParameters.hostApiSpecificStreamInfo = NULL;
err = Pa_OpenStream(
&stream,
NULL, /* no input */
&outputParameters,
SAMPLE_RATE,
FRAMES_PER_BUFFER,
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;
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;
}
int buzzer_stop()
{
PaError err = 0;
err = Pa_StopStream( stream );
if( err != paNoError ) goto error;
err = Pa_CloseStream( stream );
if( err != paNoError ) goto error;
Pa_Terminate();
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;
}
void msleep(int d){
usleep(d*1000);
}
int main(void)
{
// notes frequency chart: http://www.phy.mtu.edu/~suits/notefreqs.html
buzzer_start();
buzzer_set_freq(261);
msleep(250);
buzzer_set_freq(293);
msleep(250);
buzzer_set_freq(329);
msleep(250);
buzzer_set_freq(349);
msleep(250);
buzzer_set_freq(392);
msleep(250);
buzzer_set_freq(440);
msleep(250);
buzzer_set_freq(494);
msleep(250);
buzzer_beep(523, 200);
msleep(250);
buzzer_stop();
return 0;
}

Resources