#include #include #include #define SAMPLE_RATE 44100 #define FRAMES_PER_BUFFER 64 #define TABLE_SIZE 44100 #define M_PI 3.14159265 static float sine[TABLE_SIZE]; static unsigned long ind = 0; static unsigned long ind2 = 0; static int sq1_on_time; static int sq1_off_time; static float sq1 = 1; static int sq1_timer = 0; static int sq2_on_time; static int sq2_off_time; static float sq2 = 1; static int sq2_timer = 0; static audio_context ctx; static int audio_callback(const void* input_uffer, void *output_buffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *time_info, PaStreamCallbackFlags status_flags, void *userData ) { //printf("Audio Callback!\n"); audio_context *ctx = (audio_context *) userData; float *out = (float *)output_buffer; PaTime time = time_info->currentTime; sq1_on_time = 1/(ctx->sq1_freq/(float)SAMPLE_RATE) * ctx->sq1_duty; sq1_off_time = 1/(ctx->sq1_freq/(float)SAMPLE_RATE) * (1 - ctx->sq1_duty); sq2_on_time = 1/(ctx->sq2_freq/(float)SAMPLE_RATE) * ctx->sq2_duty; sq2_off_time = 1/(ctx->sq2_freq/(float)SAMPLE_RATE) * (1 - ctx->sq2_duty); for(int i = 0; i < framesPerBuffer; i++) { float val = 0; //handle audio channels //val += 0.2 * sine[ind]; //ind += 500; if((sq1_timer >= sq1_on_time && sq1 == 1)) { sq1 = 0; sq1_timer = 0; } else if((sq1_timer >= sq1_off_time && sq1 == 0)){ sq1 = 1; sq1_timer = 0; } sq1_timer++; val += ctx->sq1_amp * sq1; if((sq2_timer >= sq2_on_time && sq2 == 1)) { sq2 = 0; sq2_timer = 0; } else if((sq2_timer >= sq2_off_time && sq2 == 0)){ sq2 = 1; sq2_timer = 0; } sq2_timer++; val += ctx->sq2_amp * sq2; //val += 0.2 * sine[ind2]; //ind2 += 200; if(ind >= TABLE_SIZE) ind -= TABLE_SIZE; if(ind2 >= TABLE_SIZE) ind2 -= TABLE_SIZE; *out++ = val; } return paContinue; } void audio_init(){ PaStreamParameters output_parameters; PaStream *stream; PaError err; ctx.sq1_amp = 0; ctx.sq1_duty = 0; ctx.sq1_freq = 0; ctx.sq2_amp = 0; ctx.sq2_duty = 0; ctx.sq2_freq = 0; for(int i = 0; i < TABLE_SIZE; i++) { sine[i] = (float) sin(((double)i/(double)TABLE_SIZE) * M_PI * 2.); } err = Pa_Initialize(); if (err != paNoError) goto error; output_parameters.device = Pa_GetDefaultOutputDevice(); if(output_parameters.device == paNoDevice) { fprintf(stderr, "No default audio device!\n"); goto error; } output_parameters.channelCount = 1; output_parameters.sampleFormat = paFloat32; output_parameters.suggestedLatency = Pa_GetDeviceInfo(output_parameters.device)->defaultLowOutputLatency; output_parameters.hostApiSpecificStreamInfo = NULL; err = Pa_OpenStream(&stream, NULL, &output_parameters, SAMPLE_RATE, FRAMES_PER_BUFFER, NULL, audio_callback, &ctx); if(err != paNoError) goto error; err = Pa_StartStream(stream); if(err != paNoError) goto error; return; error: Pa_Terminate(); fprintf(stderr, "portaudio stream error\n\tError Number: %d\n\tError Message: %s\n", err, Pa_GetErrorText(err)); }