⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pcm86.c

📁 freebsd v4.4内核源码
💻 C
📖 第 1 页 / 共 4 页
字号:
	pcm_s.pdma_count -= chunksize;    } else	/* ??? something wrong... */	printk("pcm0: chunkcount overrun\n");}static voidfifo_recv(pcm_data *buf, int count){    int i;    if (count > tmpbuf.size) {	for (i = 0; i < tmpbuf.size; i++)	    *buf++ = tmpbuf.buff[i];	count -= tmpbuf.size;	tmpbuf.size = 0;	if (pcm_s.stereo)	    fifo_recv_stereo(buf, count);	else	    fifo_recv_monoral(buf, count);    } else {	for (i = 0; i < count; i++)	    *buf++ = tmpbuf.buff[i];	for (i = 0; i < tmpbuf.size - count; i++)	    tmpbuf.buff[i] = tmpbuf.buff[i + count];	tmpbuf.size -= count;    }#ifdef PCM86_DEBUG    printk("fifo_recv(): %d bytes received\n",	   ((count / (pcm_s.bytes << pcm_s.stereo)) * pcm_s.chipspeed	    / pcm_s.speed) * pcm_s.bytes * 2);#endif}static voidfifo_recv_stereo(pcm_data *buf, int count){    /* Convert format and sampling speed. */    switch (pcm_s.format) {    case AFMT_MU_LAW:	fifo_recv_stereo_ulaw(buf, count);	break;    case AFMT_S8:	fifo_recv_stereo_8(buf, count, NO);	break;    case AFMT_U8:	fifo_recv_stereo_8(buf, count, YES);	break;    case AFMT_S16_LE:	fifo_recv_stereo_16le(buf, count, NO);	break;    case AFMT_U16_LE:	fifo_recv_stereo_16le(buf, count, YES);	break;    case AFMT_S16_BE:	fifo_recv_stereo_16be(buf, count, NO);	break;    case AFMT_U16_BE:	fifo_recv_stereo_16be(buf, count, YES);	break;    }}static voidfifo_recv_monoral(pcm_data *buf, int count){    /* Convert format and sampling speed. */    switch (pcm_s.format) {    case AFMT_MU_LAW:	fifo_recv_mono_ulaw(buf, count);	break;    case AFMT_S8:	fifo_recv_mono_8(buf, count, NO);	break;    case AFMT_U8:	fifo_recv_mono_8(buf, count, YES);	break;    case AFMT_S16_LE:	fifo_recv_mono_16le(buf, count, NO);	break;    case AFMT_U16_LE:	fifo_recv_mono_16le(buf, count, YES);	break;    case AFMT_S16_BE:	fifo_recv_mono_16be(buf, count, NO);	break;    case AFMT_U16_BE:	fifo_recv_mono_16be(buf, count, YES);	break;    }}static voidfifo_recv_stereo_ulaw(pcm_data *buf, int count){    int i, cnt;    signed char dl, dl0, dl1, dr, dr0, dr1;    cnt = count / 2;    if (pcm_s.speed == pcm_s.chipspeed) {	/* No reason to convert the pcm speed. */	for (i = 0; i < cnt; i++) {	    *buf++ = linear2ulaw[inb(pcm_s.iobase + 12)];	    *buf++ = linear2ulaw[inb(pcm_s.iobase + 12)];	}	if (count % 2) {	    *buf++ = linear2ulaw[inb(pcm_s.iobase + 12)];	    tmpbuf.buff[0] = linear2ulaw[inb(pcm_s.iobase + 12)];	    tmpbuf.size = 1;	}    } else {	/* Speed conversion with linear interpolation method. */	dl0 = pcm_s.last_l;	dr0 = pcm_s.last_r;	dl1 = inb(pcm_s.iobase + 12);	dr1 = inb(pcm_s.iobase + 12);	for (i = 0; i < cnt; i++) {	    while (pcm_s.acc >= pcm_s.speed) {		pcm_s.acc -= pcm_s.speed;		dl0 = dl1;		dr0 = dr1;		dl1 = inb(pcm_s.iobase + 12);		dr1 = inb(pcm_s.iobase + 12);	    }	    dl = ((dl0 * (pcm_s.speed - pcm_s.acc)) + (dl1 * pcm_s.acc))		/ pcm_s.speed;	    dr = ((dr0 * (pcm_s.speed - pcm_s.acc)) + (dr1 * pcm_s.acc))		/ pcm_s.speed;	    *buf++ = linear2ulaw[dl & 0xff];	    *buf++ = linear2ulaw[dr & 0xff];	    pcm_s.acc += pcm_s.chipspeed;	}	if (count % 2) {	    while (pcm_s.acc >= pcm_s.speed) {		pcm_s.acc -= pcm_s.speed;		dl0 = dl1;		dr0 = dr1;		dl1 = inb(pcm_s.iobase + 12);		dr1 = inb(pcm_s.iobase + 12);	    }	    dl = ((dl0 * (pcm_s.speed - pcm_s.acc)) + (dl1 * pcm_s.acc))		/ pcm_s.speed;	    dr = ((dr0 * (pcm_s.speed - pcm_s.acc)) + (dr1 * pcm_s.acc))		/ pcm_s.speed;	    *buf++ = linear2ulaw[dl & 0xff];	    tmpbuf.buff[0] = linear2ulaw[dr & 0xff];	    tmpbuf.size = 1;	}	pcm_s.last_l = dl0;	pcm_s.last_r = dr0;    }}static voidfifo_recv_stereo_8(pcm_data *buf, int count, int uflag){    int i, cnt;    signed char dl, dl0, dl1, dr, dr0, dr1, zlev;    zlev = uflag ? -128 : 0;    cnt = count / 2;    if (pcm_s.speed == pcm_s.chipspeed) {	/* No reason to convert the pcm speed. */	for (i = 0; i < cnt; i++) {	    *buf++ = inb(pcm_s.iobase + 12) + zlev;	    *buf++ = inb(pcm_s.iobase + 12) + zlev;	}	if (count % 2) {	    *buf++ = inb(pcm_s.iobase + 12) + zlev;	    tmpbuf.buff[0] = inb(pcm_s.iobase + 12) + zlev;	    tmpbuf.size = 1;	}    } else {	/* Speed conversion with linear interpolation method. */	dl0 = pcm_s.last_l;	dr0 = pcm_s.last_r;	dl1 = inb(pcm_s.iobase + 12);	dr1 = inb(pcm_s.iobase + 12);	for (i = 0; i < cnt; i++) {	    while (pcm_s.acc >= pcm_s.speed) {		pcm_s.acc -= pcm_s.speed;		dl0 = dl1;		dr0 = dr1;		dl1 = inb(pcm_s.iobase + 12);		dr1 = inb(pcm_s.iobase + 12);	    }	    dl = ((dl0 * (pcm_s.speed - pcm_s.acc)) + (dl1 * pcm_s.acc))		/ pcm_s.speed;	    dr = ((dr0 * (pcm_s.speed - pcm_s.acc)) + (dr1 * pcm_s.acc))		/ pcm_s.speed;	    *buf++ = dl + zlev;	    *buf++ = dr + zlev;	    pcm_s.acc += pcm_s.chipspeed;	}	if (count % 2) {	    while (pcm_s.acc >= pcm_s.speed) {		pcm_s.acc -= pcm_s.speed;		dl0 = dl1;		dr0 = dr1;		dl1 = inb(pcm_s.iobase + 12);		dr1 = inb(pcm_s.iobase + 12);	    }	    dl = ((dl0 * (pcm_s.speed - pcm_s.acc)) + (dl1 * pcm_s.acc))		/ pcm_s.speed;	    dr = ((dr0 * (pcm_s.speed - pcm_s.acc)) + (dr1 * pcm_s.acc))		/ pcm_s.speed;	    *buf++ = dl + zlev;	    tmpbuf.buff[0] = dr + zlev;	    tmpbuf.size = 1;	}	pcm_s.last_l = dl0;	pcm_s.last_r = dr0;    }}static voidfifo_recv_stereo_16le(pcm_data *buf, int count, int uflag){    int i, cnt;    short dl, dl0, dl1, dr, dr0, dr1, zlev;    pcm_data t[4];    zlev = uflag ? -128 : 0;    cnt = count / 4;    if (pcm_s.speed == pcm_s.chipspeed) {	/* No reason to convert the pcm speed. */	for (i = 0; i < cnt; i++) {	    *(buf + 1) = inb(pcm_s.iobase + 12) + zlev;	    *buf = inb(pcm_s.iobase + 12);	    *(buf + 3) = inb(pcm_s.iobase + 12) + zlev;	    *(buf + 2) = inb(pcm_s.iobase + 12);	    buf += 4;	}	if (count % 4) {	    t[1] = inb(pcm_s.iobase + 12) + zlev;	    t[0] = inb(pcm_s.iobase + 12);	    t[3] = inb(pcm_s.iobase + 12) + zlev;	    t[2] = inb(pcm_s.iobase + 12);	    tmpbuf.size = 0;	    for (i = 0; i < count % 4; i++)		*buf++ = t[i];	    for (i = count % 4; i < 4; i++)		tmpbuf.buff[tmpbuf.size++] = t[i];	}    } else {	/* Speed conversion with linear interpolation method. */	dl0 = pcm_s.last_l;	dr0 = pcm_s.last_r;	dl1 = inb(pcm_s.iobase + 12) << 8;	dl1 |= inb(pcm_s.iobase + 12);	dr1 = inb(pcm_s.iobase + 12) << 8;	dr1 |= inb(pcm_s.iobase + 12);	for (i = 0; i < cnt; i++) {	    while (pcm_s.acc >= pcm_s.speed) {		pcm_s.acc -= pcm_s.speed;		dl0 = dl1;		dr0 = dr1;		dl1 = inb(pcm_s.iobase + 12) << 8;		dl1 |= inb(pcm_s.iobase + 12);		dr1 = inb(pcm_s.iobase + 12) << 8;		dr1 |= inb(pcm_s.iobase + 12);	    }	    dl = ((dl0 * (pcm_s.speed - pcm_s.acc)) + (dl1 * pcm_s.acc))		/ pcm_s.speed;	    dr = ((dr0 * (pcm_s.speed - pcm_s.acc)) + (dr1 * pcm_s.acc))		/ pcm_s.speed;	    *buf++ = dl & 0xff;	    *buf++ = ((dl >> 8) & 0xff) + zlev;	    *buf++ = dr & 0xff;	    *buf++ = ((dr >> 8) & 0xff) + zlev;	    pcm_s.acc += pcm_s.chipspeed;	}	if (count % 4) {	    while (pcm_s.acc >= pcm_s.speed) {		pcm_s.acc -= pcm_s.speed;		dl0 = dl1;		dr0 = dr1;		dl1 = inb(pcm_s.iobase + 12) << 8;		dl1 |= inb(pcm_s.iobase + 12);		dr1 = inb(pcm_s.iobase + 12) << 8;		dr1 |= inb(pcm_s.iobase + 12);	    }	    dl = ((dl0 * (pcm_s.speed - pcm_s.acc)) + (dl1 * pcm_s.acc))		/ pcm_s.speed;	    dr = ((dr0 * (pcm_s.speed - pcm_s.acc)) + (dr1 * pcm_s.acc))		/ pcm_s.speed;	    t[0] = dl & 0xff;	    t[1] = ((dl >> 8) & 0xff) + zlev;	    t[2] = dr & 0xff;	    t[3] = ((dr >> 8) & 0xff) + zlev;	    tmpbuf.size = 0;	    for (i = 0; i < count % 4; i++)		*buf++ = t[i];	    for (i = count % 4; i < 4; i++)		tmpbuf.buff[tmpbuf.size++] = t[i];	}	pcm_s.last_l = dl0;	pcm_s.last_r = dr0;    }}static voidfifo_recv_stereo_16be(pcm_data *buf, int count, int uflag){    int i, cnt;    short dl, dl0, dl1, dr, dr0, dr1, zlev;    pcm_data t[4];    zlev = uflag ? -128 : 0;    cnt = count / 4;    if (pcm_s.speed == pcm_s.chipspeed) {	/* No reason to convert the pcm speed. */	for (i = 0; i < cnt; i++) {	    *buf++ = inb(pcm_s.iobase + 12) + zlev;	    *buf++ = inb(pcm_s.iobase + 12);	    *buf++ = inb(pcm_s.iobase + 12) + zlev;	    *buf++ = inb(pcm_s.iobase + 12);	}	if (count % 4) {	    t[0] = inb(pcm_s.iobase + 12) + zlev;	    t[1] = inb(pcm_s.iobase + 12);	    t[2] = inb(pcm_s.iobase + 12) + zlev;	    t[3] = inb(pcm_s.iobase + 12);	    tmpbuf.size = 0;	    for (i = 0; i < count % 4; i++)		*buf++ = t[i];	    for (i = count % 4; i < 4; i++)		tmpbuf.buff[tmpbuf.size++] = t[i];	}    } else {	/* Speed conversion with linear interpolation method. */	dl0 = pcm_s.last_l;	dr0 = pcm_s.last_r;	dl1 = inb(pcm_s.iobase + 12) << 8;	dl1 |= inb(pcm_s.iobase + 12);	dr1 = inb(pcm_s.iobase + 12) << 8;	dr1 |= inb(pcm_s.iobase + 12);	for (i = 0; i < cnt; i++) {	    while (pcm_s.acc >= pcm_s.speed) {		pcm_s.acc -= pcm_s.speed;		dl0 = dl1;		dr0 = dr1;		dl1 = inb(pcm_s.iobase + 12) << 8;		dl1 |= inb(pcm_s.iobase + 12);		dr1 = inb(pcm_s.iobase + 12) << 8;		dr1 |= inb(pcm_s.iobase + 12);	    }	    dl = ((dl0 * (pcm_s.speed - pcm_s.acc)) + (dl1 * pcm_s.acc))		/ pcm_s.speed;	    dr = ((dr0 * (pcm_s.speed - pcm_s.acc)) + (dr1 * pcm_s.acc))		/ pcm_s.speed;	    *buf++ = ((dl >> 8) & 0xff) + zlev;	    *buf++ = dl & 0xff;	    *buf++ = ((dr >> 8) & 0xff) + zlev;	    *buf++ = dr & 0xff;	    pcm_s.acc += pcm_s.chipspeed;	}	if (count % 4) {	    while (pcm_s.acc >= pcm_s.speed) {		pcm_s.acc -= pcm_s.speed;		dl0 = dl1;		dr0 = dr1;		dl1 = inb(pcm_s.iobase + 12) << 8;		dl1 |= inb(pcm_s.iobase + 12);		dr1 = inb(pcm_s.iobase + 12) << 8;		dr1 |= inb(pcm_s.iobase + 12);	    }	    dl = ((dl0 * (pcm_s.speed - pcm_s.acc)) + (dl1 * pcm_s.acc))		/ pcm_s.speed;	    dr = ((dr0 * (pcm_s.speed - pcm_s.acc)) + (dr1 * pcm_s.acc))		/ pcm_s.speed;	    t[0] = ((dl >> 8) & 0xff) + zlev;	    t[1] = dl & 0xff;	    t[2] = ((dr >> 8) & 0xff) + zlev;	    t[3] = dr & 0xff;	    tmpbuf.size = 0;	    for (i = 0; i < count % 4; i++)		*buf++ = t[i];	    for (i = count % 4; i < 4; i++)		tmpbuf.buff[tmpbuf.size++] = t[i];	}	pcm_s.last_l = dl0;	pcm_s.last_r = dr0;    }}static voidfifo_recv_mono_ulaw(pcm_data *buf, int count){    int i;    signed char d, d0, d1;    if (pcm_s.speed == pcm_s.chipspeed) {	/* No reason to convert the pcm speed. */	for (i = 0; i < count; i++) {	    d = ((signed char)inb(pcm_s.iobase + 12)		 + (signed char)inb(pcm_s.iobase + 12)) >> 1;	    *buf++ = linear2ulaw[d & 0xff];	}    } else {	/* Speed conversion with linear interpolation method. */	d0 = pcm_s.last_l;	d1 = ((signed char)inb(pcm_s.iobase + 12)	      + (signed char)inb(pcm_s.iobase + 12)) >> 1;	for (i = 0; i < count; i++) {	    while (pcm_s.acc >= pcm_s.speed) {		pcm_s.acc -= pcm_s.speed;		d0 = d1;		d1 = ((signed char)inb(pcm_s.iobase + 12)		      + (signed char)inb(pcm_s.iobase + 12)) >> 1;	    }	    d = ((d0 * (pcm_s.speed - pcm_s.acc)) + (d1 * pcm_s.acc))		/ pcm_s.speed;	    *buf++ = linear2ulaw[d & 0xff];	    pcm_s.acc += pcm_s.chipspeed;	}	pcm_s.last_l = d0;    }}static voidfifo_recv_mono_8(pcm_data *buf, int count, int uflag){    int i;    signed char d, d0, d1, zlev;    zlev = uflag ? -128 : 0;    if (pcm_s.speed == pcm_s.chipspeed) {	/* No reason to convert the pcm speed. */	for (i = 0; i < count; i++) {	    d = ((signed char)inb(pcm_s.iobase + 12)		 + (signed char)inb(pcm_s.iobase + 12)) >> 1;	    *buf++ = d + zlev;	}    } else {	/* Speed conversion with linear interpolation method. */	d0 = pcm_s.last_l;	d1 = ((signed char)inb(pcm_s.iobase + 12)	      + (signed char)inb(pcm_s.iobase + 12)) >> 1;	for (i = 0; i < count; i++) {	    while (pcm_s.acc >= pcm_s.speed) {		pcm_s.acc -= pcm_s.speed;		d0 = d1;		d1 = ((signed char)inb(pcm_s.iobase + 12)		      + (signed char)inb(pcm_s.iobase + 12)) >> 1;	    }	    d = ((d0 * (pcm_s.speed - pcm_s.acc)) + (d1 * pcm_s.acc))		/ pcm_s.speed;	    *buf++ = d + zlev;	    pcm_s.acc += pcm_s.chipspeed;	}	pcm_s.last_l = d0;    }}static voidfifo_recv_mono_16le(pcm_data *buf, int count, int uflag){    int i, cnt;    short d, d0, d1, el, er, zlev;    zlev = uflag ? -128 : 0;    cnt = count / 2;    if (pcm_s.speed == pcm_s.chipspeed) {	/* No reason to convert the pcm speed. */	for (i = 0; i < cnt; i++) {	    el = inb(pcm_s.iobase + 12) << 8;	    el |= inb(pcm_s.iobase + 12);	    er = inb(pcm_s.iobase + 12) << 8;	    er |= inb(pcm_s.iobase + 12);	    d = (el + er) >> 1;	    *buf++ = d & 0xff;	    *buf++ = ((d >> 8) & 0xff) + zlev;	}	if (count % 2) {	    el = inb(pcm_s.iobase + 12) << 8;	    el |= inb(pcm_s.iobase + 12);	    er = inb(pcm_s.iobase + 12) << 8;	    er |= inb(pcm_s.iobase + 12);	    d = (el + er) >> 1;	    *buf++ = d & 0xff;	    tmpbuf.buff[0] = ((d >> 8) & 0xff) + zlev;	    tmpbuf.size = 1;	}    } else {	/* Speed conversion with linear interpolation method. */	d0 = pcm_s.last_l;	el = inb(pcm_s.iobase + 12) << 8;	el |= inb(pcm_s.iobase + 12);	er = inb(pcm_s.iobase + 12) << 8;	er |= inb(pcm_s.iobase + 12);	d1 = (el + er) >> 1;	for (i = 0; i < cnt; i++) {	    while (pcm_s.acc >= pcm_s.speed) {		pcm_s.acc -= pcm_s.speed;		d0 = d1;		el = inb(pcm_s.iobase + 12) << 8;		el |= inb(pcm_s.iobase + 12);		er = inb(pcm_s.iobase + 12) << 8;		er |= inb(pcm_s.iobase + 12);		d1 = (el + er) >> 1;	    }	    d = ((d0 * (pcm_s.speed - pcm_s.acc)) + (d1 * pcm_s.acc))		/ pcm_s.speed;	    *buf++ = d & 0xff;	    *buf++ = ((d >> 8) & 0xff) + zlev;	    pcm_s.acc += pcm_s.chipspeed;	}	if (count % 2) {	    while (pcm_s.acc >= pcm_s.speed) {		pcm_s.acc -= pcm_s.speed;		d0 = d1;		el = inb(pcm_s.iobase + 12) << 8;		el |= inb(pcm_s.iobase + 12);		er = inb(pcm_s.iobase + 12) << 8;		er |= inb(pcm_s.iobase + 12);		d1 = (el + er) >> 1;	    }	    d = ((d0 * (pcm_s.speed - pcm_s.acc)) + (d1 * pcm_s.acc))		/ pcm_s.speed;	    *buf++ = d & 0xff;	    tmpbuf.buff[0] = ((d >> 8) & 0xff) + zlev;	    tmpbuf.size = 1;	}	pcm_s.last_l = d0;    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -