Skip to content

Instantly share code, notes, and snippets.

@nddrylliog
Created November 14, 2012 19:55
Show Gist options
  • Save nddrylliog/4074363 to your computer and use it in GitHub Desktop.
Save nddrylliog/4074363 to your computer and use it in GitHub Desktop.
Generating two sines using PortAudio
#include "portaudio.h"
#include <stdio.h>
#include <stdlib.h>
typedef int PaStreamCallback( const void *input,
void *output,
unsigned long frameCount,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData ) ;
typedef struct
{
float left_phase;
float right_phase;
}
paTestData;
/* 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 )
{
/* Cast data passed through stream to our structure. */
paTestData *data = (paTestData*)userData;
float *out = (float*)outputBuffer;
unsigned int i;
(void) inputBuffer; /* Prevent unused variable warning. */
for( i=0; i<framesPerBuffer; i++ )
{
*out++ = data->left_phase; /* left */
*out++ = data->right_phase; /* right */
/* Generate simple sawtooth phaser that ranges between -1.0 and 1.0. */
data->left_phase += 0.03f;
/* When signal reaches top, drop back down. */
if( data->left_phase >= 1.0f ) data->left_phase -= 2.0f;
/* higher pitch so we can distinguish left and right. */
data->right_phase += 0.05f;
if( data->right_phase >= 1.0f ) data->right_phase -= 2.0f;
}
return 0;
}
#define SAMPLE_RATE (44100)
static paTestData data;
int main (int argc, char *argv) {
PaStream *stream;
PaError err;
err = Pa_Initialize();
if( err != paNoError ) {
puts("Failed to initialize PortAudio");
exit(1);
}
/* Open an audio I/O stream. */
err = Pa_OpenDefaultStream( &stream,
0, /* no input channels */
2, /* stereo output */
paFloat32, /* 32 bit floating point output */
SAMPLE_RATE,
256, /* frames per buffer, i.e. the number
of sample frames that PortAudio will
request from the callback. Many apps
may want to use
paFramesPerBufferUnspecified, which
tells PortAudio to pick the best,
possibly changing, buffer size.*/
patestCallback, /* this is your callback function */
&data ); /*This is a pointer that will be passed to
your callback*/
if( err != paNoError ) {
puts("Failed to open a stream");
exit(1);
}
err = Pa_StartStream( stream );
if( err != paNoError ) {
puts("Failed to start a stream");
exit(1);
}
/* Sleep for several seconds. */
Pa_Sleep(3 * 1000);
err = Pa_StopStream( stream );
if( err != paNoError ) {
puts("Failed to stop a stream");
exit(1);
}
err = Pa_CloseStream( stream );
if( err != paNoError ) {
puts("Failed to close a stream");
exit(1);
}
err = Pa_Terminate();
if( err != paNoError ) {
puts("Failed to terminate PortAudio");
exit(1);
}
}
@greut
Copy link

greut commented Nov 14, 2012

static functions were something I ignored, thanks. http://www.gnu.org/software/gnu-c-manual/gnu-c-manual.html#Static-Functions

@nddrylliog
Copy link
Author

@greut It's good practice to hide everything that you don't want to expose, when writing a library.

When writing a program, pretty much every function should be static - except main of course, because the entry point needs to be visible for the linker (it is called by C runtime libraries shipped with your OS - the actual entry point of the program, _start, is generated by the C compiler itself.)

I'd love to write an asm course at some point :)

Note that most of the code here it copy-pasted/adapted from the PortAudio tutorial that can be found here: http://portaudio.com/docs/v19-doxydocs/tutorial_start.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment