Mercurial > hg > audiostuff
comparison audiodelay/audiodelay.cpp @ 0:deadffdf5d60
import audiodelay
author | pmeerw@pan |
---|---|
date | Fri, 30 Oct 2009 22:45:25 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:deadffdf5d60 |
---|---|
1 /******************************************/ | |
2 /* | |
3 audiodelay.cpp | |
4 by Peter Meerwald, pmeerw@pmeerw.net, 2009. | |
5 | |
6 This program tests the delay between audio output and input. | |
7 */ | |
8 /******************************************/ | |
9 | |
10 #include "RtAudio.h" | |
11 #include <stdlib.h> | |
12 #include <stdio.h> | |
13 #include <math.h> | |
14 #include <string.h> | |
15 #include <sys/time.h> | |
16 #include <time.h> | |
17 | |
18 const char *progname = "audiodelay"; | |
19 | |
20 typedef signed short AUDIOSAMPLE_TYPE; | |
21 #define FORMAT RTAUDIO_SINT16 | |
22 | |
23 static volatile unsigned int nmeasurements = 0; | |
24 static float accum_measurements = 0.0f; | |
25 | |
26 static int inout(void *out_buf, void *in_buf, unsigned int nbuf_frames, | |
27 double stream_time, RtAudioStreamStatus status, void *data) { | |
28 if (status) | |
29 printf("%s: stream over/underflow detected\n", progname); | |
30 | |
31 static unsigned int count_inout = 0; | |
32 static struct timeval tv_start; | |
33 static struct timeval tv_stop; | |
34 | |
35 AUDIOSAMPLE_TYPE *pout = (AUDIOSAMPLE_TYPE *)out_buf, *pin = (AUDIOSAMPLE_TYPE *)in_buf; | |
36 | |
37 memset(out_buf, 0, nbuf_frames*sizeof(AUDIOSAMPLE_TYPE) * 2); | |
38 if ((count_inout % (512*128/nbuf_frames)) == 0) { | |
39 for (unsigned int i = nbuf_frames/2-4; i < nbuf_frames/2+4; i++) { | |
40 pout[2*i] = 32000; | |
41 pout[2*i+1] = 32000; | |
42 } | |
43 | |
44 gettimeofday(&tv_start, 0); | |
45 } | |
46 | |
47 if (1) { | |
48 for (unsigned int i = 0; i < nbuf_frames; i++) { | |
49 if (pin[2*i] > 15000 || pin[2*i+1] > 15000) { | |
50 | |
51 gettimeofday(&tv_stop, 0); | |
52 | |
53 unsigned int msec = (tv_stop.tv_sec - tv_start.tv_sec) * 1000; | |
54 if (tv_stop.tv_usec < tv_start.tv_usec) | |
55 msec -= (tv_start.tv_usec - tv_stop.tv_usec) / 1000; | |
56 else | |
57 msec += (tv_stop.tv_usec - tv_start.tv_usec) / 1000; | |
58 | |
59 accum_measurements += msec; | |
60 nmeasurements++; | |
61 printf("%s: measured delay %u ms, offset %u, average %.2f\n", progname, msec, i, accum_measurements / nmeasurements); | |
62 | |
63 break; | |
64 } | |
65 } | |
66 } | |
67 | |
68 count_inout++; | |
69 | |
70 return 0; | |
71 } | |
72 | |
73 int main(int argc, char *argv[]) { | |
74 unsigned int channels = 2, sample_rate = 44100, buf_bytes, odevice = 0, idevice = 0, ioffset = 0, ooffset = 0; | |
75 | |
76 RtAudio adac; | |
77 if (adac.getDeviceCount() < 1) { | |
78 std::cout << "\nNo audio devices found!\n"; | |
79 exit(EXIT_FAILURE); | |
80 } | |
81 | |
82 // Let RtAudio print messages to stderr. | |
83 adac.showWarnings(true); | |
84 | |
85 // Set the same number of channels for both input and output. | |
86 unsigned int buf_frames = 128; | |
87 RtAudio::StreamParameters iparams, oparams; | |
88 iparams.deviceId = idevice; | |
89 iparams.nChannels = channels; | |
90 iparams.firstChannel = ioffset; | |
91 oparams.deviceId = odevice; | |
92 oparams.nChannels = channels; | |
93 oparams.firstChannel = ooffset; | |
94 | |
95 RtAudio::StreamOptions options; | |
96 options.flags = 0; // RTAUDIO_MINIMIZE_LATENCY, RTAUDIO_HOG_DEVICE, RTAUDIO_SCHEDULE_REALTIME | |
97 options.numberOfBuffers = 2; | |
98 options.priority = 0; // for RTAUDIO_SCHEDULE_REALTIME | |
99 | |
100 try { | |
101 adac.openStream(&oparams, &iparams, FORMAT, sample_rate, &buf_frames, &inout, (void *)&buf_bytes, &options); | |
102 } | |
103 catch (RtError& e) { | |
104 printf("%s: %s\n", progname, e.getMessage().c_str()); | |
105 exit(EXIT_FAILURE); | |
106 } | |
107 | |
108 buf_bytes = buf_frames * channels * sizeof(AUDIOSAMPLE_TYPE); | |
109 | |
110 try { | |
111 adac.startStream(); | |
112 | |
113 printf("%s: stream latency %ld frames, %d sample rate\n", progname, adac.getStreamLatency(), adac.getStreamSampleRate()); | |
114 | |
115 printf("%s: running ... press <enter> to quit (%d buffer frames)\n", progname, buf_frames); | |
116 getchar(); | |
117 | |
118 // Stop the stream. | |
119 adac.stopStream(); | |
120 } | |
121 catch (RtError& e) { | |
122 printf("%s: %s\n", progname, e.getMessage().c_str()); | |
123 goto cleanup; | |
124 } | |
125 | |
126 cleanup: | |
127 if (adac.isStreamOpen()) | |
128 adac.closeStream(); | |
129 | |
130 return 0; | |
131 } |