1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
|
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdlib.h>
#include <stdio.h>
#ifndef HAVE_SYS_SOUNDCARD_H
int main(int argc, char *argv[])
{
fprintf(stderr, "Platform does not support OSS\n");
exit(1);
}
#else
#include <sys/time.h>
#include <unistd.h>
#include <sched.h>
#include <sys/soundcard.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#define AUDIOPATH "/dev/dsp"
#define NTESTS 16
#define SAMPLE_RATE 8000
#ifndef MAP_FAILED
#define MAP_FAILED ((caddr_t)(-1))
#endif
#define FULL_MMAP
static char *testit(void)
{
size_t pagesize = getpagesize();
struct sched_param schp;
unsigned int times[NTESTS];
int i, fd, apar;
struct audio_buf_info iinfo;
caddr_t ibuf, ibufe;
unsigned int isize;
struct timeval tv;
unsigned int avg, tm;
if ((schp.sched_priority = sched_get_priority_min(SCHED_RR)) == -1)
return "sched_get_priority_min";
if (sched_setscheduler(0, SCHED_RR, &schp))
return "sched_setscheduler";
for (i = 0; i < NTESTS; i++) {
if ((fd = open(AUDIOPATH, O_RDWR, 0)) < 0)
return "open";
apar = AFMT_S16_LE;
if (ioctl(fd, SNDCTL_DSP_SETFMT, &apar) == -1)
return "ioctl: SNDCTL_DSP_SETFMT";
if (apar != AFMT_S16_LE)
return "audio driver does not support AFMT_S16_LE";
apar = 0;
if (ioctl(fd, SNDCTL_DSP_STEREO, &apar) == -1)
return "ioctl: SNDCTL_DSP_STEREO";
if (apar != 0)
return "audio driver does not support mono";
apar = SAMPLE_RATE;
if (ioctl(fd, SNDCTL_DSP_SPEED, &apar) == -1)
return "ioctl: SNDCTL_DSP_SPEED";
if (apar != SAMPLE_RATE)
if (abs(apar-SAMPLE_RATE) >= SAMPLE_RATE/100)
return "audio driver does not support 8kHz sampling frequency";
apar = 0xffff0007U;
if (ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &apar) == -1)
return "ioctl: SNDCTL_DSP_SETFRAGMENT";
if (ioctl(fd, SNDCTL_DSP_GETISPACE, &iinfo) == -1)
return "ioctl: SNDCTL_DSP_GETISPACE";
isize = iinfo.fragstotal * iinfo.fragsize;
if (ioctl(fd, SNDCTL_DSP_GETCAPS, &apar) == -1)
return "ioctl: SNDCTL_DSP_GETCAPS";
if (!(apar & DSP_CAP_TRIGGER) || !(apar & DSP_CAP_MMAP))
return "Sound driver does not support mmap and/or trigger";
#ifdef FULL_MMAP
if ((ibuf = mmap(NULL, pagesize+isize, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0)) == MAP_FAILED)
return "mmap: MAP_ANONYMOUS";
ibufe = ibuf + isize;
if (munmap(ibuf, isize))
return "munmap: MAP_ANONYMOUS";
if ((ibuf = mmap(ibuf, isize, PROT_READ, MAP_FILE | MAP_SHARED | MAP_FIXED, fd, 0)) == MAP_FAILED)
return "mmap: PROT_READ";
#else /* FULL_MMAP */
if ((ibuf = mmap(NULL, isize, PROT_READ, MAP_FILE | MAP_SHARED | MAP_FIXED, fd, 0)) == MAP_FAILED)
return "mmap: PROT_READ";
#endif /* FULL_MMAP */
apar = 0;
if (ioctl(fd, SNDCTL_DSP_SETTRIGGER, &apar) == -1)
return "ioctl: SNDCTL_DSP_SETTRIGGER";
apar = PCM_ENABLE_INPUT;
if (ioctl(fd, SNDCTL_DSP_SETTRIGGER, &apar) == -1)
return "ioctl: SNDCTL_DSP_SETTRIGGER";
if (gettimeofday(&tv, NULL))
return "gettimeofday";
times[i] = tv.tv_usec;
if (munmap(ibuf, isize))
return "munmap";
#ifdef FULL_MMAP
if (munmap(ibufe, pagesize))
return "munmap";
#endif /* FULL_MMAP */
if (close(fd))
return "close";
}
printf("Results (us):");
for (avg = 0, i = 1; i < NTESTS; i++) {
printf(" %d", (tm = (1000000+times[i]-times[i-1]) % 1000000));
avg += tm;
}
printf("\nAverage (us): %d\n", (avg + NTESTS/2) / NTESTS);
return NULL;
}
int main(int argc, char *argv[])
{
char *c;
if ((c = testit()))
perror(c);
exit(0);
}
#endif
|