예제 #1
0
int sndbuf_pool_test(void)
{
	sndbuf_t * lst[SNDBUF_POOL_SIZE];
	sndbuf_t * buf;
	int i;
	int j = 0;

	do {
		for (i = 0; i < SNDBUF_POOL_SIZE; ++i) {
			buf = sndbuf_alloc();
			if (buf == NULL) {
				DCC_LOG1(LOG_PANIC, "%d: sndbuf_alloc() failed!", i);
				return -1;
			}
			lst[i] = buf;
		}

		buf = sndbuf_alloc();
		if (buf != NULL) {
			DCC_LOG2(LOG_PANIC, "%d: sndbuf_alloc() != NULL!", i, buf);
			return -1;
		}

		for (i = 0; i < SNDBUF_POOL_SIZE; ++i) {
			sndbuf_free(lst[i]);
		}

	} while (++j < 2);

	DCC_LOG(LOG_TRACE, "success.");

	return 0;
}
예제 #2
0
static void *
alschan_init(kobj_t obj, void *devinfo,
	     struct snd_dbuf *b, struct pcm_channel *c, int dir)
{
	struct	sc_info	*sc = devinfo;
	struct	sc_chinfo *ch;

	if (dir == PCMDIR_PLAY) {
		ch = &sc->pch;
		ch->gcr_fifo_status = ALS_GCR_FIFO0_STATUS;
	} else {
		ch = &sc->rch;
		ch->gcr_fifo_status = ALS_GCR_FIFO1_STATUS;
	}
	ch->dir = dir;
	ch->parent = sc;
	ch->channel = c;
	ch->bps = 1;
	ch->format = AFMT_U8;
	ch->speed = DSP_DEFAULT_SPEED;
	ch->buffer = b;
	if (sndbuf_alloc(ch->buffer, sc->parent_dmat, ALS_BUFFER_SIZE) != 0) {
		return NULL;
	}
	return ch;
}
예제 #3
0
static void*
via8233wr_init(kobj_t obj, void *devinfo, struct snd_dbuf *b,
	       struct pcm_channel *c, int dir)
{
	struct via_info *via = devinfo;
	struct via_chinfo *ch = &via->rch[c->num];

	ch->parent = via;
	ch->channel = c;
	ch->buffer = b;
	ch->dir = dir;

	ch->rbase = VIA_WR_BASE(c->num);
	snd_mtxlock(via->lock);
	via_wr(via, ch->rbase + VIA_WR_RP_SGD_FORMAT, WR_FIFO_ENABLE, 1);
	snd_mtxunlock(via->lock);

	if (sndbuf_alloc(ch->buffer, via->parent_dmat, via->bufsz) != 0)
		return NULL;

	snd_mtxlock(via->lock);
	via8233chan_sgdinit(via, ch, c->num);
	via8233chan_reset(via, ch);
	snd_mtxunlock(via->lock);

	return ch;
}
예제 #4
0
파일: ds1.c 프로젝트: Alkzndr/freebsd
/* play channel interface */
static void *
ds1pchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
{
	struct sc_info *sc = devinfo;
	struct sc_pchinfo *ch;

	KASSERT(dir == PCMDIR_PLAY, ("ds1pchan_init: bad direction"));

	ch = &sc->pch[sc->pchn++];
	ch->buffer = b;
	ch->parent = sc;
	ch->channel = c;
	ch->dir = dir;
	ch->fmt = SND_FORMAT(AFMT_U8, 1, 0);
	ch->spd = 8000;
	ch->run = 0;
	if (sndbuf_alloc(ch->buffer, sc->buffer_dmat, 0, sc->bufsz) != 0)
		return NULL;
	else {
		ch->lsnum = sc->pslotfree;
		ch->lslot = ds_allocpslot(sc);
		ch->rsnum = sc->pslotfree;
		ch->rslot = ds_allocpslot(sc);
		ds_setuppch(ch);
		return ch;
	}
}
예제 #5
0
static void *
cs4281chan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
{
    struct sc_info *sc = devinfo;
    struct sc_chinfo *ch = (dir == PCMDIR_PLAY) ? &sc->pch : &sc->rch;

    ch->buffer = b;
    if (sndbuf_alloc(ch->buffer, sc->parent_dmat, 0, sc->bufsz) != 0) {
	return NULL;
    }
    ch->parent = sc;
    ch->channel = c;

    ch->fmt = SND_FORMAT(AFMT_U8, 1, 0);
    ch->spd = DSP_DEFAULT_SPEED;
    ch->bps = 1;
    ch->blksz = sndbuf_getsize(ch->buffer);

    ch->dma_chan = (dir == PCMDIR_PLAY) ? CS4281_DMA_PLAY : CS4281_DMA_REC;
    ch->dma_setup = 0;

    adcdac_go(ch, 0);
    adcdac_prog(ch);

    return ch;
}
예제 #6
0
static void *
alschan_init(kobj_t obj, void *devinfo,
	     struct snd_dbuf *b, struct pcm_channel *c, int dir)
{
	struct	sc_info	*sc = devinfo;
	struct	sc_chinfo *ch;

	snd_mtxlock(sc->lock);
	if (dir == PCMDIR_PLAY) {
		ch = &sc->pch;
		ch->gcr_fifo_status = ALS_GCR_FIFO0_STATUS;
	} else {
		ch = &sc->rch;
		ch->gcr_fifo_status = ALS_GCR_FIFO1_STATUS;
	}
	ch->dir = dir;
	ch->parent = sc;
	ch->channel = c;
	ch->bps = 1;
	ch->format = SND_FORMAT(AFMT_U8, 1, 0);
	ch->speed = DSP_DEFAULT_SPEED;
	ch->buffer = b;
	snd_mtxunlock(sc->lock);

	if (sndbuf_alloc(ch->buffer, sc->parent_dmat, 0, sc->bufsz) != 0)
		return NULL;

	return ch;
}
예제 #7
0
static void*
via8233dxs_init(kobj_t obj, void *devinfo, struct snd_dbuf *b,
		struct pcm_channel *c, int dir)
{
	struct via_info *via = devinfo;
	struct via_chinfo *ch = &via->pch[c->num];

	ch->parent = via;
	ch->channel = c;
	ch->buffer = b;
	ch->dir = dir;

	/*
	 * All cards apparently support DXS3, but not other DXS
	 * channels.  We therefore want to align first DXS channel to
	 * DXS3.
	 */
	snd_mtxlock(via->lock);
	ch->rbase = VIA_DXS_BASE(NDXSCHANS - 1 - via->n_dxs_registered);
	via->n_dxs_registered++;
	snd_mtxunlock(via->lock);

	if (sndbuf_alloc(ch->buffer, via->parent_dmat, via->bufsz) != 0)
		return NULL;

	snd_mtxlock(via->lock);
	via8233chan_sgdinit(via, ch, NWRCHANS + c->num);
	via8233chan_reset(via, ch);
	snd_mtxunlock(via->lock);

	return ch;
}
예제 #8
0
파일: ad1816.c 프로젝트: MarginC/kame
/* channel interface */
static void *
ad1816chan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
{
	struct ad1816_info *ad1816 = devinfo;
	struct ad1816_chinfo *ch = (dir == PCMDIR_PLAY)? &ad1816->pch : &ad1816->rch;

	ch->parent = ad1816;
	ch->channel = c;
	ch->buffer = b;
	if (sndbuf_alloc(ch->buffer, ad1816->parent_dmat, ad1816->bufsize) == -1) return NULL;
	return ch;
}
예제 #9
0
/*
 * Playback / Record channel interface
 */
static void *
atiixp_chan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b,
					struct pcm_channel *c, int dir)
{
	struct atiixp_info *sc = devinfo;
	struct atiixp_chinfo *ch;
	int num;

	atiixp_lock(sc);

	if (dir == PCMDIR_PLAY) {
		ch = &sc->pch;
		ch->linkptr_bit = ATI_REG_OUT_DMA_LINKPTR;
		ch->enable_bit = ATI_REG_CMD_OUT_DMA_EN | ATI_REG_CMD_SEND_EN;
		ch->flush_bit = ATI_REG_FIFO_OUT_FLUSH;
		ch->dma_dt_cur_bit = ATI_REG_OUT_DMA_DT_CUR;
		/* Native 32bit playback working properly */
		ch->caps_32bit = 1;
	} else {
		ch = &sc->rch;
		ch->linkptr_bit = ATI_REG_IN_DMA_LINKPTR;
		ch->enable_bit = ATI_REG_CMD_IN_DMA_EN  | ATI_REG_CMD_RECEIVE_EN;
		ch->flush_bit = ATI_REG_FIFO_IN_FLUSH;
		ch->dma_dt_cur_bit = ATI_REG_IN_DMA_DT_CUR;
		/* XXX Native 32bit recording appear to be broken */
		ch->caps_32bit = 1;
	}

	ch->buffer = b;
	ch->parent = sc;
	ch->channel = c;
	ch->dir = dir;
	ch->dma_segs = sc->dma_segs;

	atiixp_unlock(sc);

	if (sndbuf_alloc(ch->buffer, sc->parent_dmat, sc->bufsz) == -1)
		return NULL;

	atiixp_lock(sc);
	num = sc->registered_channels++;
	ch->sgd_table = &sc->sgd_table[num * ch->dma_segs];
	ch->sgd_addr = sc->sgd_addr +
			(num * ch->dma_segs * sizeof(struct atiixp_dma_op));
	atiixp_disable_dma(sc, ch);
	atiixp_unlock(sc);

	return ch;
}
예제 #10
0
파일: fm801.c 프로젝트: kusumi/DragonFlyBSD
/* channel interface */
static void *
fm801ch_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
{
	struct fm801_info *fm801 = (struct fm801_info *)devinfo;
	struct fm801_chinfo *ch = (dir == PCMDIR_PLAY)? &fm801->pch : &fm801->rch;

	DPRINT("fm801ch_init, direction = %d\n", dir);
	ch->parent = fm801;
	ch->channel = c;
	ch->buffer = b;
	ch->dir = dir;
	if (sndbuf_alloc(ch->buffer, fm801->parent_dmat, 0, fm801->bufsz) != 0)
		return NULL;
	return (void *)ch;
}
예제 #11
0
/*
 * Initialize a PCM channel
 */
static void *
au88x0_chan_init(kobj_t obj, void *arg,
    struct snd_dbuf *buf, struct pcm_channel *chan, int dir)
{
	struct au88x0_info *aui = arg;
	struct au88x0_chan_info *auci = au88x0_channel(aui, dir);

	if (sndbuf_alloc(buf, aui->aui_dmat, aui->aui_bufsize) != 0)
		return (NULL);
	auci->auci_aui = aui;
	auci->auci_pcmchan = chan;
	auci->auci_buf = buf;
	auci->auci_dir = dir;
	return (auci);
}
예제 #12
0
/* channel interface */
static void *
ad1816chan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
{
    struct ad1816_info *ad1816 = devinfo;
    struct ad1816_chinfo *ch = (dir == PCMDIR_PLAY)? &ad1816->pch : &ad1816->rch;

    ch->dir = dir;
    ch->parent = ad1816;
    ch->channel = c;
    ch->buffer = b;
    if (sndbuf_alloc(ch->buffer, ad1816->parent_dmat, 0, ad1816->bufsize) != 0)
        return NULL;

    sndbuf_dmasetup(ch->buffer, (dir == PCMDIR_PLAY) ? ad1816->drq1 :
                    ad1816->drq2);
    if (SND_DMA(ch->buffer))
        sndbuf_dmasetdir(ch->buffer, dir);

    return ch;
}
예제 #13
0
파일: i2s.c 프로젝트: bobmittmann/thinkos
sndbuf_t * i2s_io(sndbuf_t * out_buf)
{
	sndbuf_t * in_buf;
	sndbuf_t * buf;
	int idx;

	if (out_buf == NULL) {
		trace("txbuf = zero");
		out_buf = (sndbuf_t *)&sndbuf_zero;
	} else {
		/* incerement the reference counter */
		sndbuf_use(out_buf);
	}

	/* wait for the end of transfer cycle */
//	tracef("%s(): wait ", __func__);
	thinkos_flag_wait(i2s.io_flag);
	__thinkos_flag_clr(i2s.io_flag);

	idx = i2s.rx.idx;
	/* get the input data buffer */
	in_buf = i2s.rx.buf[idx];
	/* alloc an empty buffer for next cycle */
	buf = sndbuf_alloc();
	
	if (buf == NULL) {
		tracef("%s(): sndbuf_alloc() failed!", __func__);
	}

//	tracef("%d <-- IN[%d] <-- %d", sndbuf_id(in_buf), idx, sndbuf_id(buf)); 
	/* set the input buffer for next cycle */
	i2s.rx.buf[idx] = (buf == NULL) ? &sndbuf_null : buf;

	idx = i2s.tx.idx;
	/* release the previouslly transmitted buffer */
	sndbuf_free(i2s.tx.buf[idx]);
	/* set the output data buffer */
	i2s.tx.buf[idx] = out_buf;

	return in_buf;
}
예제 #14
0
파일: uaudio_pcm.c 프로젝트: MarginC/kame
static void *
ua_chan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
{
	device_t pa_dev;
	u_char *buf,*end;

	struct ua_info *sc = devinfo;
	struct ua_chinfo *ch = (dir == PCMDIR_PLAY)? &sc->pch : &sc->rch;

	ch->parent = sc;
	ch->channel = c;
	ch->buffer = b;

	pa_dev = device_get_parent(sc->sc_dev);
     	/* Create ua_playfmt[] & ua_recfmt[] */
	uaudio_query_formats(pa_dev, (u_int32_t *)&ua_playfmt, (u_int32_t *)&ua_recfmt);
	if (ua_playfmt[0] == 0) {
		printf("%s channel supported format list invalid\n", dir == PCMDIR_PLAY? "play" : "record");
		return NULL;
	}

	/* allocate PCM side DMA buffer */
	if (sndbuf_alloc(ch->buffer, sc->parent_dmat, UAUDIO_PCM_BUFF_SIZE) != 0) {
	    return NULL;
        }

	buf = end = sndbuf_getbuf(b);
	end += sndbuf_getsize(b);
	uaudio_chan_set_param_pcm_dma_buff(pa_dev, buf, end, ch->channel);

	ch->dir = dir;
#ifndef NO_RECORDING
	ch->hwch = 1;
	if (dir == PCMDIR_PLAY)
		ch->hwch = 2;
#else
	ch->hwch = 2;
#endif

	return ch;
}
예제 #15
0
static void*
via8233msgd_init(kobj_t obj, void *devinfo, struct snd_dbuf *b,
		 struct pcm_channel *c, int dir)
{
	struct via_info *via = devinfo;
	struct via_chinfo *ch = &via->pch[c->num];

	ch->parent = via;
	ch->channel = c;
	ch->buffer = b;
	ch->dir = dir;
	ch->rbase = VIA_MC_SGD_STATUS;

	if (sndbuf_alloc(ch->buffer, via->parent_dmat, via->bufsz) != 0)
		return NULL;

	snd_mtxlock(via->lock);
	via8233chan_sgdinit(via, ch, NWRCHANS + c->num);
	via8233chan_reset(via, ch);
	snd_mtxunlock(via->lock);

	return ch;
}
예제 #16
0
파일: audio.c 프로젝트: bobmittmann/thinkos
void net_rcv_task(void)
{
	sndbuf_t * buf;
	uint32_t ts;
	int n;

	tracef("%s(): <%d> started...", __func__, thinkos_thread_self());

	for (;;) {
		while ((buf = sndbuf_alloc()) == NULL) {
			tracef("%s(): sndbuf_alloc() failed!", __func__);
			thinkos_sleep(1000);
		}

#if ENABLE_G711
		n = g711_alaw_recv(0, buf, &ts);
#else
		n = audio_recv(0, buf, &ts);
#endif

		if (n != sndbuf_len) {
			tracef("%s(): (n=%d != sndbuf_len)!", __func__, n);
		} else {
			if (audio_drv.stream_enabled) {
#if !DISABLE_JITBUF
				jitbuf_enqueue(&audio_drv.jitbuf, buf, ts);
#endif
			}
		}

#if DISABLE_JITBUF
		xfr_buf = buf;
#else
		sndbuf_free(buf);
#endif
	}
}
예제 #17
0
파일: ds1.c 프로젝트: Alkzndr/freebsd
/* record channel interface */
static void *
ds1rchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
{
	struct sc_info *sc = devinfo;
	struct sc_rchinfo *ch;

	KASSERT(dir == PCMDIR_REC, ("ds1rchan_init: bad direction"));

	ch = &sc->rch[sc->rchn];
	ch->num = sc->rchn++;
	ch->buffer = b;
	ch->parent = sc;
	ch->channel = c;
	ch->dir = dir;
	ch->fmt = SND_FORMAT(AFMT_U8, 1, 0);
	ch->spd = 8000;
	if (sndbuf_alloc(ch->buffer, sc->buffer_dmat, 0, sc->bufsz) != 0)
		return NULL;
	else {
		ch->slot = (ch->num == DS1_RECPRIMARY)? sc->rbank + 2: sc->rbank;
		ds_setuprch(ch);
		return ch;
	}
}
예제 #18
0
/* channel interface */
static void *
viachan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
{
	struct via_info *via = devinfo;
	struct via_chinfo *ch;

	snd_mtxlock(via->lock);
	if (dir == PCMDIR_PLAY) {
		ch = &via->pch;
		ch->base = VIA_PLAY_DMAOPS_BASE;
		ch->count = VIA_PLAY_DMAOPS_COUNT;
		ch->ctrl = VIA_PLAY_CONTROL;
		ch->mode = VIA_PLAY_MODE;
		ch->sgd_addr = via->sgd_addr;
		ch->sgd_table = &via->sgd_table[0];
	} else {
		ch = &via->rch;
		ch->base = VIA_RECORD_DMAOPS_BASE;
		ch->count = VIA_RECORD_DMAOPS_COUNT;
		ch->ctrl = VIA_RECORD_CONTROL;
		ch->mode = VIA_RECORD_MODE;
		ch->sgd_addr = via->sgd_addr + sizeof(struct via_dma_op) * SEGS_PER_CHAN;
		ch->sgd_table = &via->sgd_table[SEGS_PER_CHAN];
	}

	ch->parent = via;
	ch->channel = c;
	ch->buffer = b;
	ch->dir = dir;
	snd_mtxunlock(via->lock);

	if (sndbuf_alloc(ch->buffer, via->parent_dmat, via->bufsz) != 0)
		return NULL;

	return ch;
}
예제 #19
0
파일: audio.c 프로젝트: bobmittmann/thinkos
void audio_io_task(void)
{
	sndbuf_t * out_buf;
	sndbuf_t * in_buf;
	uint32_t ts = 0;
	int i;

	tracef("%s(): <%d> started...", __func__, thinkos_thread_self());

	tonegen_init(&tonegen, 0, 0);
	spectrum_init(&audio_tx_sa, SAMPLE_RATE);
	spectrum_init(&audio_rx_sa, SAMPLE_RATE);

	for (;;) {
#if DISABLE_JITBUF
		out_buf = xfr_buf;
#else
		out_buf = jitbuf_dequeue(&audio_drv.jitbuf);
#endif

		if (audio_drv.tone_mode == TONE_DAC) {
			if (out_buf == NULL) {
				if ((out_buf = sndbuf_alloc()) != NULL)
					tonegen_apply(&tonegen, out_buf);
				else
					out_buf = (sndbuf_t *)&sndbuf_zero;
			}
		} else {
			if (out_buf == NULL) {
#if 0
			tracef("%s(): out_buf == NULL!", __func__);
#endif
				out_buf = (sndbuf_t *)&sndbuf_zero;
			}
		}

		spectrum_rec(&audio_tx_sa, out_buf);

		in_buf = i2s_io(out_buf);

  		for (i = 0; i < SNDBUF_LEN; i++)
		    in_buf->data[i] = FxaIirApply(&iir_hp_120hz, in_buf->data[i]);
//		    in_buf->data[i] = FxaIirApply(&iir_hp_240hz, in_buf->data[i]);

		led_flash(LED_I2S, 100);

		if (in_buf != &sndbuf_null) {
			if (audio_drv.tone_mode == TONE_ADC)
				tonegen_apply(&tonegen, in_buf);

			spectrum_rec(&audio_rx_sa, in_buf);
		}

		if (audio_drv.stream_enabled) {
#if ENABLE_G711
			if (g711_alaw_send(0, in_buf, ts) < 0) {
				tracef("%s(): net_send() failed!", __func__);
			}
#else
			if (audio_send(0, in_buf, ts) < 0) {
				tracef("%s(): net_send() failed!", __func__);
			}
#endif
			led_flash(LED_NET, 100);
		}

		ts += SNDBUF_LEN;

		sndbuf_free(in_buf);
		sndbuf_free(out_buf);
	}
}
예제 #20
0
static void *
ichchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
{
	struct sc_info *sc = devinfo;
	struct sc_chinfo *ch;
	unsigned int num;

	ICH_LOCK(sc);
	num = sc->chnum++;
	ch = &sc->ch[num];
	ch->num = num;
	ch->buffer = b;
	ch->channel = c;
	ch->parent = sc;
	ch->run = 0;
	ch->dtbl = sc->dtbl + (ch->num * ICH_DTBL_LENGTH);
	ch->desc_addr = sc->desc_addr +
	    (ch->num * ICH_DTBL_LENGTH * sizeof(struct ich_desc));
	ch->blkcnt = sc->blkcnt;
	ch->blksz = sc->bufsz / ch->blkcnt;

	switch(ch->num) {
	case 0: /* play */
		KASSERT(dir == PCMDIR_PLAY, ("wrong direction"));
		ch->regbase = ICH_REG_PO_BASE;
		ch->spdreg = (sc->hasvra) ? AC97_REGEXT_FDACRATE : 0;
		ch->imask = ICH_GLOB_STA_POINT;
		break;

	case 1: /* record */
		KASSERT(dir == PCMDIR_REC, ("wrong direction"));
		ch->regbase = ICH_REG_PI_BASE;
		ch->spdreg = (sc->hasvra) ? AC97_REGEXT_LADCRATE : 0;
		ch->imask = ICH_GLOB_STA_PIINT;
		break;

	case 2: /* mic */
		KASSERT(dir == PCMDIR_REC, ("wrong direction"));
		ch->regbase = ICH_REG_MC_BASE;
		ch->spdreg = (sc->hasvrm) ? AC97_REGEXT_MADCRATE : 0;
		ch->imask = ICH_GLOB_STA_MINT;
		break;

	default:
		return (NULL);
	}

	if (sc->flags & ICH_FIXED_RATE)
		ch->spdreg = 0;

	ICH_UNLOCK(sc);
	if (sndbuf_alloc(ch->buffer, sc->chan_dmat,
	    ((sc->flags & ICH_DMA_NOCACHE) ? BUS_DMA_NOCACHE : 0),
	    sc->bufsz) != 0)
		return (NULL);

	ICH_LOCK(sc);
	ich_wr(sc, ch->regbase + ICH_REG_X_BDBAR, (uint32_t)(ch->desc_addr), 4);
	ICH_UNLOCK(sc);

	return (ch);
}
예제 #21
0
sndbuf_t * sndbuf_calloc(void)
{
	return sndbuf_clear(sndbuf_alloc());
}