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

📄 lmsoundcard.c

📁 Linmodem is soft modem source code for embedded system
💻 C
字号:
/* sample interface code to use a linux soundcard */#include <unistd.h>#include <fcntl.h>#include <sys/ioctl.h>#include <linux/soundcard.h>#include "lm.h"/* OSS buffer size */#define FRAGMENT_BITS 8#define NB_FRAGMENTS  (32768 >> FRAGMENT_BITS)/* 128 samples : 16 ms, maybe too much ? */#define NB_SAMPLES ((1 << FRAGMENT_BITS)/2)/* default pty */#define PTY_NAME "z0"char *pty_name = "/dev/pty" PTY_NAME;char *tty_name = "/dev/tty" PTY_NAME;extern struct sm_hw_info sm_hw_soundcard;void soundcard_modem(void){    struct sm_state sm1, *dce = &sm1;    struct sm_hw_info *hw = &sm_hw_soundcard;    s16 in_buf[NB_SAMPLES];    s16 out_buf[NB_SAMPLES];    u8 buf[1024];    struct lm_at_state at_parser;    fd_set rfds, wfds;    int hw_handle, tty_handle, max_handle, n;    int out_buf_flushed, i, len;        if (!lm_debug) {        printf("linmodem tty is '%s'\n", tty_name);        tty_handle = open(pty_name, O_RDWR);        if (tty_handle < 0) {            perror(pty_name);            return;        }    } else {        printf("linmodem tty is stdout\n");        tty_handle = 0;    }    fcntl(tty_handle, F_SETFL, O_NONBLOCK);    lm_init(dce, hw, "sc");    lm_at_parser_init(&at_parser, dce);    hw_handle = dce->hw_state->handle;    out_buf_flushed = 1;    /* XXX: non block mode ? */    /* test call */    printf("linmodem started.\n");    for(;;) {        /* sound card & tty handling */        FD_ZERO(&rfds);        FD_SET(hw_handle, &rfds);        FD_SET(tty_handle, &rfds);        FD_ZERO(&wfds);        if (!out_buf_flushed)             FD_SET(hw_handle, &wfds);        if (sm_size(&dce->rx_fifo) > 0)            FD_SET(tty_handle, &wfds);        max_handle = tty_handle;        if (hw_handle > tty_handle)            max_handle = hw_handle;        n = select(max_handle + 1, &rfds, &wfds, NULL, NULL);        if (n > 0) {            /* process at commands */            lm_at_parser(&at_parser);            /* read from tty */            if (FD_ISSET(tty_handle, &rfds)) {                len = read(tty_handle, buf, sizeof(buf));                for(i=0;i<len;i++) {                    sm_put_bit(&dce->tx_fifo, buf[i]);                }            }            /* write to tty */            if (FD_ISSET(tty_handle, &wfds)) {                struct sm_fifo *f = &dce->rx_fifo;                int size;                size = f->eptr - f->rptr;                if (size > f->size)                    size = f->size;                len = write(tty_handle, f->rptr, size);                if (len > 0) {                    f->rptr += len;                    f->size -= len;                    if (f->rptr == f->eptr)                        f->rptr = f->sptr;                }            }            /* we assume that the modem read & write per block of               NB_SAMPLES. It makes no sense the underlying hardware               does something else */            /* read from modem */            if (FD_ISSET(hw_handle, &rfds) && out_buf_flushed) {                len = read(hw_handle, in_buf, NB_SAMPLES * 2);                if (len == NB_SAMPLES * 2) {                    /* process the modem samples */                    sm_process(dce, out_buf, in_buf, NB_SAMPLES);                    out_buf_flushed = 0;                }            }            /* write to modem */            if (FD_ISSET(hw_handle, &wfds)) {                len = write(hw_handle, out_buf, NB_SAMPLES * 2);                if (len == NB_SAMPLES * 2) {                    out_buf_flushed = 1;                }            }        }    }}static int soundcard_open(struct lm_interface_state *s){    int tmp, err;    /* init the sound card to 8000 Hz, Mono, 16 bits */    s->handle = open("/dev/dsp", O_RDWR);    if (s->handle < 0) {        perror("/dev/dsp");        exit(1);    }    /* set the card to duplex */    tmp=0;    err=ioctl(s->handle, SNDCTL_DSP_SETDUPLEX, &tmp);    if (err < 0) {        perror("SNDCTL_DSP_SETDUPLEX");    }        /* buffer size */    tmp=(NB_FRAGMENTS << 16) | FRAGMENT_BITS;    err=ioctl(s->handle, SNDCTL_DSP_SETFRAGMENT, &tmp);    if (err < 0) {        perror("set fragment");    }        tmp=AFMT_S16_LE;    err=ioctl(s->handle,SNDCTL_DSP_SETFMT,&tmp);    if (err < 0) goto error;        /* should be last */    tmp = 8000;    err=ioctl(s->handle,SNDCTL_DSP_SPEED,&tmp);    if (err < 0) goto error;    return 0; error:    close(s->handle);    return -1;}static void soundcard_close(struct lm_interface_state *s){    close(s->handle);}static void soundcard_set_offhook(struct lm_interface_state *s, int v){    if (v) {        printf("%s: offhook\n",s->sm->name);    } else {        printf("%s: onhook\n",s->sm->name);    }}static void soundcard_set_ring(struct lm_interface_state *s, int v){}static void soundcard_main_loop(struct lm_interface_state *s){}struct sm_hw_info sm_hw_soundcard = {    soundcard_open,    soundcard_close,    soundcard_set_offhook,    soundcard_set_ring,    soundcard_main_loop,};

⌨️ 快捷键说明

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