Path: blob/main/audio/alsa-plugins/files/alsa-plugins.patch
16166 views
--- oss/ctl_oss.c.orig 2016-03-31 13:11:29 UTC1+++ oss/ctl_oss.c2@@ -362,7 +362,9 @@ SND_CTL_PLUGIN_DEFINE_FUNC(oss)3{4snd_config_iterator_t it, next;5const char *device = "/dev/mixer";6+#ifndef __FreeBSD__7struct mixer_info mixinfo;8+#endif9int i, err, val;10snd_ctl_oss_t *oss;1112@@ -399,19 +401,29 @@ SND_CTL_PLUGIN_DEFINE_FUNC(oss)13goto error;14}1516+#ifndef __FreeBSD__17if (ioctl(oss->fd, SOUND_MIXER_INFO, &mixinfo) < 0) {18err = -errno;19SNDERR("Cannot get mixer info for device %s", device);20goto error;21}22+#endif2324oss->ext.version = SND_CTL_EXT_VERSION;25oss->ext.card_idx = 0; /* FIXME */26+#ifdef __FreeBSD__27+ strncpy(oss->ext.id, "fbsd", sizeof(oss->ext.id) - 1);28+ strcpy(oss->ext.driver, "FreeBSD/OSS plugin");29+ strncpy(oss->ext.name, "FreeBSD/OSS", sizeof(oss->ext.name) - 1);30+ strncpy(oss->ext.longname, "FreeBSD/OSS", sizeof(oss->ext.longname) - 1);31+ strncpy(oss->ext.mixername, "FreeBSD/OSS", sizeof(oss->ext.mixername) - 1);32+#else33strncpy(oss->ext.id, mixinfo.id, sizeof(oss->ext.id) - 1);34strcpy(oss->ext.driver, "OSS-Emulation");35strncpy(oss->ext.name, mixinfo.name, sizeof(oss->ext.name) - 1);36strncpy(oss->ext.longname, mixinfo.name, sizeof(oss->ext.longname) - 1);37strncpy(oss->ext.mixername, mixinfo.name, sizeof(oss->ext.mixername) - 1);38+#endif39oss->ext.poll_fd = -1;40oss->ext.callback = &oss_ext_callback;41oss->ext.private_data = oss;42--- oss/pcm_oss.c.orig 2016-03-31 13:11:29 UTC43+++ oss/pcm_oss.c44@@ -24,15 +24,39 @@45#include <alsa/pcm_external.h>46#include <linux/soundcard.h>4748+#define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)))49+50+#ifdef __FreeBSD__51+#define FREEBSD_OSS_RATE_MIN 152+#define FREEBSD_OSS_RATE_MAX 38400053+54+#define FREEBSD_OSS_CHANNELS_MIN 155+#define FREEBSD_OSS_CHANNELS_MAX 856+57+#define FREEBSD_OSS_BUFSZ_MAX 13107258+#define FREEBSD_OSS_BLKCNT_MIN 259+#define FREEBSD_OSS_BLKSZ_MIN 16 /* (FREEBSD_OSS_CHANNELS_MAX * 4) */60+61+#define FREEBSD_OSS_BUFSZ_MIN (FREEBSD_OSS_BLKCNT_MIN * FREEBSD_OSS_BLKSZ_MIN)62+#define FREEBSD_OSS_BLKCNT_MAX (FREEBSD_OSS_BUFSZ_MAX / FREEBSD_OSS_BUFSZ_MIN)63+#define FREEBSD_OSS_BLKSZ_MAX (FREEBSD_OSS_BUFSZ_MAX / FREEBSD_OSS_BLKCNT_MIN)64+#endif65+66typedef struct snd_pcm_oss {67snd_pcm_ioplug_t io;68char *device;69int fd;70+#ifdef __FreeBSD__71+ int bufsz, ptr, ptr_align, last_bytes;72+#else73int fragment_set;74int caps;75+#endif76int format;77+#ifndef __FreeBSD__78unsigned int period_shift;79unsigned int periods;80+#endif81unsigned int frame_bytes;82} snd_pcm_oss_t;8384@@ -49,8 +73,21 @@ static snd_pcm_sframes_t oss_write(snd_pcm_ioplug_t *i85buf = (char *)areas->addr + (areas->first + areas->step * offset) / 8;86size *= oss->frame_bytes;87result = write(oss->fd, buf, size);88- if (result <= 0)89- return result;90+#ifdef __FreeBSD__91+ if (result == -1) {92+ if (errno == EAGAIN)93+ return 0;94+ else95+ return -errno;96+ }97+#else98+ if (result <= 0) {99+ if (result == -EAGAIN)100+ return 0;101+ else102+ return result;103+ }104+#endif105return result / oss->frame_bytes;106}107108@@ -67,14 +104,88 @@ static snd_pcm_sframes_t oss_read(snd_pcm_ioplug_t *io109buf = (char *)areas->addr + (areas->first + areas->step * offset) / 8;110size *= oss->frame_bytes;111result = read(oss->fd, buf, size);112- if (result <= 0)113- return result;114+#ifdef __FreeBSD__115+ if (result == -1) {116+ if (errno == EAGAIN)117+ return 0;118+ else119+ return -errno;120+ }121+#else122+ if (result <= 0) {123+ if (result == -EAGAIN)124+ return 0;125+ else126+ return result;127+ }128+#endif129return result / oss->frame_bytes;130}131132static snd_pcm_sframes_t oss_pointer(snd_pcm_ioplug_t *io)133{134+#ifdef __FreeBSD__135snd_pcm_oss_t *oss = io->private_data;136+#ifdef FREEBSD_OSS_USE_IO_PTR137+ struct count_info ci;138+#endif139+ audio_buf_info bi;140+141+ if (io->state != SND_PCM_STATE_RUNNING)142+ return 0;143+144+ if (io->state == SND_PCM_STATE_XRUN)145+ return -EPIPE;146+147+#ifdef FREEBSD_OSS_USE_IO_PTR148+ if (ioctl(oss->fd, (io->stream == SND_PCM_STREAM_PLAYBACK) ?149+ SNDCTL_DSP_GETOPTR : SNDCTL_DSP_GETIPTR, &ci) < 0)150+ return -EINVAL;151+152+ if (ci.ptr == oss->last_bytes &&153+ ((ioctl(oss->fd, (io->stream == SND_PCM_STREAM_PLAYBACK) ?154+ SNDCTL_DSP_GETOSPACE : SNDCTL_DSP_GETISPACE, &bi) < 0) ||155+ bi.bytes == oss->bufsz))156+ return -EPIPE;157+158+ if (ci.ptr < oss->last_bytes)159+ oss->ptr += oss->bufsz;160+161+ oss->ptr += ci.ptr;162+ oss->ptr -= oss->last_bytes;163+ oss->ptr %= oss->ptr_align;164+165+ oss->last_bytes = ci.ptr;166+#else /* !FREEBSD_OSS_USE_IO_PTR */167+ if (ioctl(oss->fd, (io->stream == SND_PCM_STREAM_PLAYBACK) ?168+ SNDCTL_DSP_GETOSPACE : SNDCTL_DSP_GETISPACE, &bi) < 0)169+ return -EINVAL;170+171+ if (bi.bytes == oss->bufsz && bi.bytes == oss->last_bytes) {172+#if 0173+#ifdef SNDCTL_DSP_GETERROR174+ audio_errinfo ei;175+ if (ioctl(oss->fd, SNDCTL_DSP_GETERROR, &ei) < 0 ||176+ (io->stream == SND_PCM_STREAM_PLAYBACK &&177+ ei.play_underruns != 0) ||178+ (io->stream == SND_PCM_STREAM_CAPTURE &&179+ ei.rec_overruns != 0))180+#endif181+#endif182+ return -EPIPE;183+ }184+185+ if (bi.bytes > oss->last_bytes) {186+ oss->ptr += bi.bytes - oss->last_bytes;187+ oss->ptr %= oss->ptr_align;188+ }189+190+ oss->last_bytes = bi.bytes;191+#endif /* FREEBSD_OSS_USE_IO_PTR */192+193+ return snd_pcm_bytes_to_frames(io->pcm, oss->ptr);194+#else195+ snd_pcm_oss_t *oss = io->private_data;196struct count_info info;197int ptr;198199@@ -85,20 +196,59 @@ static snd_pcm_sframes_t oss_pointer(snd_pcm_ioplug_t200}201ptr = snd_pcm_bytes_to_frames(io->pcm, info.ptr);202return ptr;203+#endif204}205206static int oss_start(snd_pcm_ioplug_t *io)207{208snd_pcm_oss_t *oss = io->private_data;209+#ifdef __FreeBSD__210+ audio_buf_info bi;211+#ifdef FREEBSD_OSS_USE_IO_PTR212+ struct count_info ci;213+#endif214+#endif215int tmp = io->stream == SND_PCM_STREAM_PLAYBACK ?216PCM_ENABLE_OUTPUT : PCM_ENABLE_INPUT;217218+#if defined(__FreeBSD__) && defined(FREEBSD_OSS_DEBUG_VERBOSE)219+ fprintf(stderr, "%s()\n", __func__);220+#endif221+222if (ioctl(oss->fd, SNDCTL_DSP_SETTRIGGER, &tmp) < 0) {223fprintf(stderr, "*** OSS: trigger failed\n");224+#ifdef __FreeBSD__225+ return -EINVAL;226+#else227if (io->stream == SND_PCM_STREAM_CAPTURE)228/* fake read to trigger */229read(oss->fd, &tmp, 0);230+#endif231}232+233+#ifdef __FreeBSD__234+ if (ioctl(oss->fd, (io->stream == SND_PCM_STREAM_PLAYBACK) ?235+ SNDCTL_DSP_GETOSPACE : SNDCTL_DSP_GETISPACE, &bi) < 0)236+ return -EINVAL;237+238+ if (oss->bufsz != (bi.fragsize * bi.fragstotal)) {239+ fprintf(stderr, "%s(): WARNING - bufsz changed! %d -> %d\n",240+ __func__, oss->bufsz, bi.fragsize * bi.fragstotal);241+ oss->bufsz = bi.fragsize * bi.fragstotal;242+ }243+244+#ifdef FREEBSD_OSS_USE_IO_PTR245+ if (ioctl(oss->fd, (io->stream == SND_PCM_STREAM_PLAYBACK) ?246+ SNDCTL_DSP_GETOPTR : SNDCTL_DSP_GETIPTR, &ci) < 0)247+ return -EINVAL;248+249+ oss->last_bytes = ci.ptr;250+#else251+ oss->last_bytes = bi.bytes;252+#endif253+ oss->ptr = 0;254+#endif255+256return 0;257}258259@@ -107,6 +257,10 @@ static int oss_stop(snd_pcm_ioplug_t *io)260snd_pcm_oss_t *oss = io->private_data;261int tmp = 0;262263+#if defined(__FreeBSD__) && defined(FREEBSD_OSS_DEBUG_VERBOSE)264+ fprintf(stderr, "%s()\n", __func__);265+#endif266+267ioctl(oss->fd, SNDCTL_DSP_SETTRIGGER, &tmp);268return 0;269}270@@ -115,16 +269,44 @@ static int oss_drain(snd_pcm_ioplug_t *io)271{272snd_pcm_oss_t *oss = io->private_data;273274+#if defined(__FreeBSD__) && defined(FREEBSD_OSS_DEBUG_VERBOSE)275+ fprintf(stderr, "%s()\n", __func__);276+#endif277+278if (io->stream == SND_PCM_STREAM_PLAYBACK)279ioctl(oss->fd, SNDCTL_DSP_SYNC);280return 0;281}282283+static int oss_delay(snd_pcm_ioplug_t *io, snd_pcm_sframes_t *delayp)284+{285+ snd_pcm_oss_t *oss = io->private_data;286+ int tmp;287+288+ if (oss->fd < 0)289+ return -EBADFD;290+291+ if (io->stream == SND_PCM_STREAM_PLAYBACK) {292+ if (ioctl(oss->fd, SNDCTL_DSP_GETODELAY, &tmp) < 0 || tmp < 0)293+ tmp = 0;294+ } else {295+ tmp = 0;296+ }297+ *delayp = snd_pcm_bytes_to_frames(io->pcm, tmp);298+299+ return (0);300+}301+302+#ifndef __FreeBSD__303static int oss_prepare(snd_pcm_ioplug_t *io)304{305snd_pcm_oss_t *oss = io->private_data;306int tmp;307308+#if defined(__FreeBSD__) && defined(FREEBSD_OSS_DEBUG_VERBOSE)309+ fprintf(stderr, "%s()\n", __func__);310+#endif311+312ioctl(oss->fd, SNDCTL_DSP_RESET);313314tmp = io->channels;315@@ -145,16 +327,75 @@ static int oss_prepare(snd_pcm_ioplug_t *io)316}317return 0;318}319+#endif320321+#ifdef __FreeBSD__322+static const struct {323+ int oss_format;324+ snd_pcm_format_t alsa_format;325+} oss_formats_tab[] = {326+ { AFMT_U8, SND_PCM_FORMAT_U8 },327+ { AFMT_S8, SND_PCM_FORMAT_S8 },328+ { AFMT_MU_LAW, SND_PCM_FORMAT_MU_LAW },329+ { AFMT_A_LAW, SND_PCM_FORMAT_A_LAW },330+ { AFMT_S16_LE, SND_PCM_FORMAT_S16_LE },331+ { AFMT_S16_BE, SND_PCM_FORMAT_S16_BE },332+ { AFMT_U16_LE, SND_PCM_FORMAT_U16_LE },333+ { AFMT_U16_BE, SND_PCM_FORMAT_U16_BE },334+ { AFMT_S24_LE, SND_PCM_FORMAT_S24_3LE },335+ { AFMT_S24_BE, SND_PCM_FORMAT_S24_3BE },336+ { AFMT_U24_LE, SND_PCM_FORMAT_U24_3LE },337+ { AFMT_U24_BE, SND_PCM_FORMAT_U24_3BE },338+ { AFMT_S32_LE, SND_PCM_FORMAT_S32_LE },339+ { AFMT_S32_BE, SND_PCM_FORMAT_S32_BE },340+ { AFMT_U32_LE, SND_PCM_FORMAT_U32_LE },341+ { AFMT_U32_BE, SND_PCM_FORMAT_U32_BE },342+ /* Special */343+ { AFMT_S24_LE, SND_PCM_FORMAT_S20_3LE },344+ { AFMT_S24_BE, SND_PCM_FORMAT_S20_3BE },345+ { AFMT_U24_LE, SND_PCM_FORMAT_U20_3LE },346+ { AFMT_U24_BE, SND_PCM_FORMAT_U20_3BE },347+ { AFMT_S24_LE, SND_PCM_FORMAT_S18_3LE },348+ { AFMT_S24_BE, SND_PCM_FORMAT_S18_3BE },349+ { AFMT_U24_LE, SND_PCM_FORMAT_U18_3LE },350+ { AFMT_U24_BE, SND_PCM_FORMAT_U18_3BE },351+ { AFMT_S32_LE, SND_PCM_FORMAT_S24_LE },352+ { AFMT_S32_BE, SND_PCM_FORMAT_S24_BE },353+ { AFMT_U32_LE, SND_PCM_FORMAT_U24_LE },354+ { AFMT_U32_BE, SND_PCM_FORMAT_U24_BE },355+};356+#endif357+358static int oss_hw_params(snd_pcm_ioplug_t *io,359snd_pcm_hw_params_t *params ATTRIBUTE_UNUSED)360{361snd_pcm_oss_t *oss = io->private_data;362int i, tmp, err;363+#ifdef __FreeBSD__364+ int blksz_shift, blkcnt;365+ audio_buf_info bi;366+#else367unsigned int period_bytes;368+#endif369long oflags, flags;370371+#if defined(__FreeBSD__) && defined(FREEBSD_OSS_DEBUG_VERBOSE)372+ fprintf(stderr, "%s()\n", __func__);373+#endif374+375oss->frame_bytes = (snd_pcm_format_physical_width(io->format) * io->channels) / 8;376+#ifdef __FreeBSD__377+ oss->ptr_align = io->buffer_size * oss->frame_bytes;378+379+ oss->format = 0;380+ for (i = 0; i < ARRAY_SIZE(oss_formats_tab); i++) {381+ if (oss_formats_tab[i].alsa_format == io->format) {382+ oss->format = oss_formats_tab[i].oss_format;383+ break;384+ }385+ }386+ if (oss->format == 0) {387+#else388switch (io->format) {389case SND_PCM_FORMAT_U8:390oss->format = AFMT_U8;391@@ -166,9 +407,93 @@ static int oss_hw_params(snd_pcm_ioplug_t *io,392oss->format = AFMT_S16_BE;393break;394default:395+#endif396fprintf(stderr, "*** OSS: unsupported format %s\n", snd_pcm_format_name(io->format));397return -EINVAL;398}399+#ifdef __FreeBSD__400+401+ ioctl(oss->fd, SNDCTL_DSP_RESET);402+403+ /* use a 16ms HW buffer by default */404+ tmp = ((16 * io->rate) / 1000) * oss->frame_bytes;405+406+ /* round up to nearest power of two */407+ while (tmp & (tmp - 1))408+ tmp += tmp & ~(tmp - 1);409+410+ /* get logarithmic value */411+ for (blksz_shift = 0; blksz_shift < 24; blksz_shift++) {412+ if (tmp == (1 << blksz_shift))413+ break;414+ }415+416+ tmp = io->buffer_size * oss->frame_bytes;417+418+ /* compute HW buffer big enough to hold SW buffer */419+ for (blkcnt = FREEBSD_OSS_BLKCNT_MIN; blkcnt != FREEBSD_OSS_BLKCNT_MAX; blkcnt *= 2) {420+ if ((blkcnt << blksz_shift) >= tmp)421+ break;422+ }423+424+ tmp = blksz_shift | (blkcnt << 16);425+ if (ioctl(oss->fd, SNDCTL_DSP_SETFRAGMENT, &tmp) < 0) {426+ perror("SNDCTL_DSP_SETFRAGMENTS");427+ return -EINVAL;428+ }429+430+ tmp = oss->format;431+ if (ioctl(oss->fd, SNDCTL_DSP_SETFMT, &tmp) < 0 ||432+ tmp != oss->format) {433+ perror("SNDCTL_DSP_SETFMT");434+ return -EINVAL;435+ }436+437+ tmp = io->channels;438+ if (ioctl(oss->fd, SNDCTL_DSP_CHANNELS, &tmp) < 0 ||439+ tmp != io->channels) {440+ perror("SNDCTL_DSP_CHANNELS");441+ return -EINVAL;442+ }443+444+ tmp = io->rate;445+ if (ioctl(oss->fd, SNDCTL_DSP_SPEED, &tmp) < 0 ||446+ tmp > io->rate * 1.01 || tmp < io->rate * 0.99) {447+ perror("SNDCTL_DSP_SPEED");448+ return -EINVAL;449+ }450+451+ if (ioctl(oss->fd, (io->stream == SND_PCM_STREAM_PLAYBACK) ?452+ SNDCTL_DSP_GETOSPACE : SNDCTL_DSP_GETISPACE, &bi) < 0) {453+ perror("SNDCTL_DSP_GET[I/O]SPACE");454+ return -EINVAL;455+ }456+457+ oss->bufsz = bi.fragsize * bi.fragstotal;458+459+#ifdef SNDCTL_DSP_LOW_WATER460+ tmp = ((io->period_size * oss->frame_bytes) * 3) / 4;461+ tmp -= tmp % oss->frame_bytes;462+ if (tmp < oss->frame_bytes)463+ tmp = oss->frame_bytes;464+ if (tmp > bi.fragsize)465+ tmp = bi.fragsize;466+ if (ioctl(oss->fd, SNDCTL_DSP_LOW_WATER, &tmp) < 0)467+ perror("SNDCTL_DSP_LOW_WATER");468+#endif469+470+#ifdef FREEBSD_OSS_DEBUG_VERBOSE471+ fprintf(stderr,472+ "\n\n[%lu -> %d] %lu ~ %d -> %d, %lu ~ %d -> %d [d:%ld lw:%d]\n\n",473+ io->buffer_size / io->period_size, bi.fragstotal,474+ io->buffer_size * oss->frame_bytes,475+ (1 << blksz_shift) * blkcnt, oss->bufsz,476+ io->period_size * oss->frame_bytes, 1 << blksz_shift,477+ bi.fragsize,478+ (long)(io->buffer_size * oss->frame_bytes) -479+ oss->bufsz, tmp);480+#endif481+#else482period_bytes = io->period_size * oss->frame_bytes;483oss->period_shift = 0;484for (i = 31; i >= 4; i--) {485@@ -209,6 +534,7 @@ static int oss_hw_params(snd_pcm_ioplug_t *io,486goto _retry;487}488oss->fragment_set = 1;489+#endif490491if ((flags = fcntl(oss->fd, F_GETFL)) < 0) {492err = -errno;493@@ -229,16 +555,152 @@ static int oss_hw_params(snd_pcm_ioplug_t *io,494return 0;495}496497-#define ARRAY_SIZE(ary) (sizeof(ary)/sizeof(ary[0]))498-499static int oss_hw_constraint(snd_pcm_oss_t *oss)500{501+#ifdef __FreeBSD__502snd_pcm_ioplug_t *io = &oss->io;503static const snd_pcm_access_t access_list[] = {504SND_PCM_ACCESS_RW_INTERLEAVED,505SND_PCM_ACCESS_MMAP_INTERLEAVED506};507+#ifdef FREEBSD_OSS_BLKCNT_P2508+ unsigned int period_list[30];509+#endif510+#ifdef FREEBSD_OSS_BUFSZ_P2511+ unsigned int bufsz_list[30];512+#endif513unsigned int nformats;514+ unsigned int format[ARRAY_SIZE(oss_formats_tab)];515+#if 0516+ unsigned int nchannels;517+ unsigned int channel[FREEBSD_OSS_CHANNELS_MAX];518+#endif519+ int i, err, tmp;520+521+#ifdef FREEBSD_OSS_DEBUG_VERBOSE522+ fprintf(stderr, "%s()\n", __func__);523+#endif524+525+ /* check trigger */526+ tmp = 0;527+ if (ioctl(oss->fd, SNDCTL_DSP_GETCAPS, &tmp) >= 0) {528+ if (!(tmp & DSP_CAP_TRIGGER))529+ fprintf(stderr, "*** OSS: trigger is not supported!\n");530+ }531+532+ /* access type - interleaved only */533+ if ((err = snd_pcm_ioplug_set_param_list(io, SND_PCM_IOPLUG_HW_ACCESS,534+ ARRAY_SIZE(access_list), access_list)) < 0)535+ return err;536+537+ /* supported formats. */538+ tmp = 0;539+ ioctl(oss->fd, SNDCTL_DSP_GETFMTS, &tmp);540+ nformats = 0;541+ for (i = 0; i < ARRAY_SIZE(oss_formats_tab); i++) {542+ if (tmp & oss_formats_tab[i].oss_format)543+ format[nformats++] = oss_formats_tab[i].alsa_format;544+ }545+ if (! nformats)546+ format[nformats++] = SND_PCM_FORMAT_S16;547+ if ((err = snd_pcm_ioplug_set_param_list(io, SND_PCM_IOPLUG_HW_FORMAT,548+ nformats, format)) < 0)549+ return err;550+551+#if 0552+ /* supported channels */553+ nchannels = 0;554+ for (i = 0; i < ARRAY_SIZE(channel); i++) {555+ tmp = i + 1;556+ if (ioctl(oss->fd, SNDCTL_DSP_CHANNELS, &tmp) >= 0 &&557+ 1 + i == tmp)558+ channel[nchannels++] = tmp;559+ }560+ if (! nchannels) /* assume 2ch stereo */561+ err = snd_pcm_ioplug_set_param_minmax(io,562+ SND_PCM_IOPLUG_HW_CHANNELS, 2, 2);563+ else564+ err = snd_pcm_ioplug_set_param_list(io,565+ SND_PCM_IOPLUG_HW_CHANNELS, nchannels, channel);566+ if (err < 0)567+ return err;568+#endif569+ err = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_CHANNELS,570+ FREEBSD_OSS_CHANNELS_MIN, FREEBSD_OSS_CHANNELS_MAX);571+ if (err < 0)572+ return err;573+574+ /* supported rates */575+ err = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_RATE,576+ FREEBSD_OSS_RATE_MIN, FREEBSD_OSS_RATE_MAX);577+ if (err < 0)578+ return err;579+580+ /*581+ * Maximum buffer size on FreeBSD can go up to 131072 bytes without582+ * strict ^2 alignment so that s24le in 3bytes packing can be fed583+ * directly.584+ */585+586+#ifdef FREEBSD_OSS_BLKCNT_P2587+ tmp = 0;588+ for (i = 1; i < 31 && tmp < ARRAY_SIZE(period_list); i++) {589+ if ((1 << i) > FREEBSD_OSS_BLKCNT_MAX)590+ break;591+ if ((1 << i) < FREEBSD_OSS_BLKCNT_MIN)592+ continue;593+ period_list[tmp++] = 1 << i;594+ }595+596+ if (tmp > 0)597+ err = snd_pcm_ioplug_set_param_list(io,598+ SND_PCM_IOPLUG_HW_PERIODS, tmp, period_list);599+ else600+#endif601+ /* periods , not strictly ^2 but later on will be refined */602+ err = snd_pcm_ioplug_set_param_minmax(io,603+ SND_PCM_IOPLUG_HW_PERIODS, FREEBSD_OSS_BLKCNT_MIN,604+ FREEBSD_OSS_BLKCNT_MAX);605+ if (err < 0)606+ return err;607+608+ /* period size , not strictly ^2 */609+ err = snd_pcm_ioplug_set_param_minmax(io,610+ SND_PCM_IOPLUG_HW_PERIOD_BYTES, FREEBSD_OSS_BLKSZ_MIN,611+ FREEBSD_OSS_BLKSZ_MAX);612+ if (err < 0)613+ return err;614+615+#ifdef FREEBSD_OSS_BUFSZ_P2616+ tmp = 0;617+ for (i = 1; i < 31 && tmp < ARRAY_SIZE(bufsz_list); i++) {618+ if ((1 << i) > FREEBSD_OSS_BUFSZ_MAX)619+ break;620+ if ((1 << i) < FREEBSD_OSS_BUFSZ_MIN)621+ continue;622+ bufsz_list[tmp++] = 1 << i;623+ }624+625+ if (tmp > 0)626+ err = snd_pcm_ioplug_set_param_list(io,627+ SND_PCM_IOPLUG_HW_BUFFER_BYTES, tmp, bufsz_list);628+ else629+#endif630+ /* buffer size , not strictly ^2 */631+ err = snd_pcm_ioplug_set_param_minmax(io,632+ SND_PCM_IOPLUG_HW_BUFFER_BYTES, FREEBSD_OSS_BUFSZ_MIN,633+ FREEBSD_OSS_BUFSZ_MAX);634+ if (err < 0)635+ return err;636+637+ return 0;638+#else639+ snd_pcm_ioplug_t *io = &oss->io;640+ static const snd_pcm_access_t access_list[] = {641+ SND_PCM_ACCESS_RW_INTERLEAVED,642+ SND_PCM_ACCESS_MMAP_INTERLEAVED643+ };644+ unsigned int nformats;645unsigned int format[5];646unsigned int nchannels;647unsigned int channel[6];648@@ -317,6 +779,7 @@ static int oss_hw_constraint(snd_pcm_oss_t *oss)649return err;650651return 0;652+#endif653}654655656@@ -324,6 +787,10 @@ static int oss_close(snd_pcm_ioplug_t *io)657{658snd_pcm_oss_t *oss = io->private_data;659660+#if defined(__FreeBSD__) && defined(FREEBSD_OSS_DEBUG_VERBOSE)661+ fprintf(stderr, "%s()\n", __func__);662+#endif663+664close(oss->fd);665free(oss->device);666free(oss);667@@ -337,8 +804,11 @@ static const snd_pcm_ioplug_callback_t oss_playback_ca668.pointer = oss_pointer,669.close = oss_close,670.hw_params = oss_hw_params,671+#ifndef __FreeBSD__672.prepare = oss_prepare,673+#endif674.drain = oss_drain,675+ .delay = oss_delay,676};677678static const snd_pcm_ioplug_callback_t oss_capture_callback = {679@@ -348,8 +818,11 @@ static const snd_pcm_ioplug_callback_t oss_capture_cal680.pointer = oss_pointer,681.close = oss_close,682.hw_params = oss_hw_params,683+#ifndef __FreeBSD__684.prepare = oss_prepare,685+#endif686.drain = oss_drain,687+ .delay = oss_delay,688};689690691@@ -360,6 +833,10 @@ SND_PCM_PLUGIN_DEFINE_FUNC(oss)692int err;693snd_pcm_oss_t *oss;694695+#if defined(__FreeBSD__) && defined(FREEBSD_OSS_DEBUG_VERBOSE)696+ fprintf(stderr, "%s()\n", __func__);697+#endif698+699snd_config_for_each(i, next, conf) {700snd_config_t *n = snd_config_iterator_entry(i);701const char *id;702703704