Mercurial > hg > audiostuff
diff audiodelay/audiodelay.cpp @ 0:deadffdf5d60
import audiodelay
author | pmeerw@pan |
---|---|
date | Fri, 30 Oct 2009 22:45:25 +0100 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/audiodelay/audiodelay.cpp Fri Oct 30 22:45:25 2009 +0100 @@ -0,0 +1,131 @@ +/******************************************/ +/* + audiodelay.cpp + by Peter Meerwald, pmeerw@pmeerw.net, 2009. + + This program tests the delay between audio output and input. +*/ +/******************************************/ + +#include "RtAudio.h" +#include <stdlib.h> +#include <stdio.h> +#include <math.h> +#include <string.h> +#include <sys/time.h> +#include <time.h> + +const char *progname = "audiodelay"; + +typedef signed short AUDIOSAMPLE_TYPE; +#define FORMAT RTAUDIO_SINT16 + +static volatile unsigned int nmeasurements = 0; +static float accum_measurements = 0.0f; + +static int inout(void *out_buf, void *in_buf, unsigned int nbuf_frames, + double stream_time, RtAudioStreamStatus status, void *data) { + if (status) + printf("%s: stream over/underflow detected\n", progname); + + static unsigned int count_inout = 0; + static struct timeval tv_start; + static struct timeval tv_stop; + + AUDIOSAMPLE_TYPE *pout = (AUDIOSAMPLE_TYPE *)out_buf, *pin = (AUDIOSAMPLE_TYPE *)in_buf; + + memset(out_buf, 0, nbuf_frames*sizeof(AUDIOSAMPLE_TYPE) * 2); + if ((count_inout % (512*128/nbuf_frames)) == 0) { + for (unsigned int i = nbuf_frames/2-4; i < nbuf_frames/2+4; i++) { + pout[2*i] = 32000; + pout[2*i+1] = 32000; + } + + gettimeofday(&tv_start, 0); + } + + if (1) { + for (unsigned int i = 0; i < nbuf_frames; i++) { + if (pin[2*i] > 15000 || pin[2*i+1] > 15000) { + + gettimeofday(&tv_stop, 0); + + unsigned int msec = (tv_stop.tv_sec - tv_start.tv_sec) * 1000; + if (tv_stop.tv_usec < tv_start.tv_usec) + msec -= (tv_start.tv_usec - tv_stop.tv_usec) / 1000; + else + msec += (tv_stop.tv_usec - tv_start.tv_usec) / 1000; + + accum_measurements += msec; + nmeasurements++; + printf("%s: measured delay %u ms, offset %u, average %.2f\n", progname, msec, i, accum_measurements / nmeasurements); + + break; + } + } + } + + count_inout++; + + return 0; +} + +int main(int argc, char *argv[]) { + unsigned int channels = 2, sample_rate = 44100, buf_bytes, odevice = 0, idevice = 0, ioffset = 0, ooffset = 0; + + RtAudio adac; + if (adac.getDeviceCount() < 1) { + std::cout << "\nNo audio devices found!\n"; + exit(EXIT_FAILURE); + } + + // Let RtAudio print messages to stderr. + adac.showWarnings(true); + + // Set the same number of channels for both input and output. + unsigned int buf_frames = 128; + RtAudio::StreamParameters iparams, oparams; + iparams.deviceId = idevice; + iparams.nChannels = channels; + iparams.firstChannel = ioffset; + oparams.deviceId = odevice; + oparams.nChannels = channels; + oparams.firstChannel = ooffset; + + RtAudio::StreamOptions options; + options.flags = 0; // RTAUDIO_MINIMIZE_LATENCY, RTAUDIO_HOG_DEVICE, RTAUDIO_SCHEDULE_REALTIME + options.numberOfBuffers = 2; + options.priority = 0; // for RTAUDIO_SCHEDULE_REALTIME + + try { + adac.openStream(&oparams, &iparams, FORMAT, sample_rate, &buf_frames, &inout, (void *)&buf_bytes, &options); + } + catch (RtError& e) { + printf("%s: %s\n", progname, e.getMessage().c_str()); + exit(EXIT_FAILURE); + } + + buf_bytes = buf_frames * channels * sizeof(AUDIOSAMPLE_TYPE); + + try { + adac.startStream(); + + printf("%s: stream latency %ld frames, %d sample rate\n", progname, adac.getStreamLatency(), adac.getStreamSampleRate()); + + printf("%s: running ... press <enter> to quit (%d buffer frames)\n", progname, buf_frames); + getchar(); + + // Stop the stream. + adac.stopStream(); + } + catch (RtError& e) { + printf("%s: %s\n", progname, e.getMessage().c_str()); + goto cleanup; + } + +cleanup: + if (adac.isStreamOpen()) + adac.closeStream(); + + return 0; +}