static int src_alloc(struct ausrc_st **stp, struct ausrc *as, struct media_ctx **ctx, struct ausrc_prm *prm, const char *device, ausrc_read_h *rh, ausrc_error_h *errh, void *arg) { struct ausrc_st *st; int err; (void)ctx; (void)errh; st = mem_zalloc(sizeof(*st), ausrc_destructor); if (!st) return ENOMEM; st->fd = -1; st->rh = rh; st->errh = errh; st->arg = arg; if (!device) device = oss_dev; prm->fmt = AUFMT_S16LE; st->mb = mbuf_alloc(2 * prm->frame_size); if (!st->mb) { err = ENOMEM; goto out; } st->fd = open(device, O_RDONLY); if (st->fd < 0) { err = errno; goto out; } err = fd_listen(st->fd, FD_READ, read_handler, st); if (err) goto out; err = oss_reset(st->fd, prm->srate, prm->ch, prm->frame_size, 1); if (err) goto out; st->as = mem_ref(as); out: if (err) mem_deref(st); else *stp = st; return err; }
static int play_alloc(struct auplay_st **stp, struct auplay *ap, struct auplay_prm *prm, const char *device, auplay_write_h *wh, void *arg) { struct auplay_st *st; int err; st = mem_zalloc(sizeof(*st), auplay_destructor); if (!st) return ENOMEM; st->fd = -1; st->wh = wh; st->arg = arg; if (!device) device = oss_dev; prm->fmt = AUFMT_S16LE; st->sz = 2 * prm->frame_size; st->buf = mem_alloc(st->sz, NULL); if (!st->buf) { err = ENOMEM; goto out; } st->fd = open(device, O_WRONLY); if (st->fd < 0) { err = errno; goto out; } err = oss_reset(st->fd, prm->srate, prm->ch, prm->frame_size, 0); if (err) goto out; st->ap = mem_ref(ap); st->run = true; err = pthread_create(&st->thread, NULL, play_thread, st); if (err) { st->run = false; goto out; } out: if (err) mem_deref(st); else *stp = st; return err; }
static void oss_resume(void) { int fillcnt; oss_reset(); fillcnt = oss_get_space() - prepause_space; if(fillcnt > 0){ void *silence = calloc(fillcnt, 1); oss_play(silence, fillcnt); free(silence); } }
static int oss_set_sf(sample_format_t sf) { int tmp, log2_fragment_size, nr_fragments, bytes_per_second; oss_reset(); oss_sf = sf; #ifdef SNDCTL_DSP_CHANNELS tmp = sf_get_channels(oss_sf); if (ioctl(oss_fd, SNDCTL_DSP_CHANNELS, &tmp) == -1) return -1; #else tmp = sf_get_channels(oss_sf) - 1; if (ioctl(oss_fd, SNDCTL_DSP_STEREO, &tmp) == -1) return -1; #endif if (sf_get_bits(oss_sf) == 16) { if (sf_get_signed(oss_sf)) { if (sf_get_bigendian(oss_sf)) { tmp = AFMT_S16_BE; } else { tmp = AFMT_S16_LE; } } else { if (sf_get_bigendian(oss_sf)) { tmp = AFMT_U16_BE; } else { tmp = AFMT_U16_LE; } } } else if (sf_get_bits(oss_sf) == 8) { if (sf_get_signed(oss_sf)) { tmp = AFMT_S8; } else { tmp = AFMT_U8; } } else if (sf_get_bits(oss_sf) == 32 && sf_get_signed(oss_sf)) { if (sf_get_bigendian(oss_sf)) { tmp = AFMT_S32_BE; } else { tmp = AFMT_S32_LE; } } else if (sf_get_bits(oss_sf) == 24 && sf_get_signed(oss_sf) && !sf_get_bigendian(oss_sf)) { tmp = AFMT_S24_PACKED; } else { d_print("unsupported sample format: %c%u_%s\n", sf_get_signed(oss_sf) ? 'S' : 'U', sf_get_bits(oss_sf), sf_get_bigendian(oss_sf) ? "BE" : "LE"); return -1; } if (ioctl(oss_fd, SNDCTL_DSP_SAMPLESIZE, &tmp) == -1) return -1; tmp = sf_get_rate(oss_sf); if (ioctl(oss_fd, SNDCTL_DSP_SPEED, &tmp) == -1) return -1; bytes_per_second = sf_get_second_size(oss_sf); log2_fragment_size = 0; while (1 << log2_fragment_size < bytes_per_second / 25) log2_fragment_size++; log2_fragment_size--; nr_fragments = 32; /* bits 0..15 = size of fragment, 16..31 = log2(number of fragments) */ tmp = (nr_fragments << 16) + log2_fragment_size; if (ioctl(oss_fd, SNDCTL_DSP_SETFRAGMENT, &tmp) == -1) return -1; return 0; }