📄 pcm86.c
字号:
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 + -