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

📄 v90.c

📁 Linmodem is soft modem source code for embedded system
💻 C
📖 第 1 页 / 共 2 页
字号:
            pp4 = (pv1 >> 1) & 1;            data[0] = pp1 ^ s->last_sign;            data[2] = pp4 ^ pp1;            s->last_sign = pp4;        }        break;    case 3:        /* 3 redundant bits */        {            int pp1, pp3, pp5, t0, t1, t2, pv0, pv1, pv2, Q1, Q2, Q3;                        t0 = signs[0] | (signs[1] << 1);            t1 = signs[2] | (signs[3] << 1);            t2 = signs[4] | (signs[5] << 1);            pv0 = s->t ^ t0;            Q1 = (pv0 & 1) ^ s->Q;            pv0 ^= sign_op[s->Q | (Q1 << 1)] & 3;            pv1 = t0 ^ t1;            Q2 = (pv1 & 1) ^ Q1;            pv1 ^= sign_op[Q1 | (Q2 << 1)] & 3;            pv2 = t1 ^ t2;            Q3 = (pv2 & 1) ^ Q2;            pv2 ^= sign_op[Q2 | (Q3 << 1)] & 3;            s->t = t2;            s->Q = Q3;                        pp1 = (pv0 >> 1) & 1;            pp3 = (pv1 >> 1) & 1;            pp5 = (pv2 >> 1) & 1;                        data[0] = pp1 ^ s->last_sign;            data[1] = pp3 ^ pp1;            data[2] = pp5 ^ pp3;            s->last_sign = pp5;        }        break;    }}static void compute_constellation(V90EncodeState *s,                                   u8 m_index[6], u8 ucode_used[6][128]){    int i,j,k,m;    /* the ucode are taken from the bigger value down to the smaller value */    for(j=0;j<6;j++) {        k = m_index[j];        m = 0;        for(i=127;i>=0;i--) {            if (ucode_used[k][i]) {                s->m_to_ucode[j][m] = i;                m++;            }        }        s->M[j] = m;    }#ifdef DEBUG    for(j=0;j<6;j++) {        printf("M[%d]: ", j);        for(i=0;i<s->M[j];i++) {            printf("%3d ", s->m_to_ucode[j][i]);        }        printf("\n");    }#endif}void v90_encode_init(V90EncodeState *s){}void v90_decode_init(V90DecodeState *s){    int i,j,m;    /* some test values (You can modify them to test the       modulator/demodulator) */    for(i=0;i<6;i++) {        for(j=0;j<16;j++)             s->ucode_used[i][10 + j * 6] = 1;    }    s->K = 4 * 6;    s->S = 5;    s->alaw = 1;    s->ld = 2;    s->a1 = (int) (0.1 * 64);    s->a2 = (int) (0.2 * 64);    s->b1 = (int) (-0.1 * 64);    s->b2 = (int) (0.1 * 64);    /* we suppose that all other values are set to zero */        /* compute the decode tables */    if (s->alaw)        s->ucode_to_linear = v90_alaw_ucode_to_linear;    else        s->ucode_to_linear = v90_ulaw_ucode_to_linear;    for(j=0;j<6;j++) {        m = 0;        for(i=127;i>=0;i--) {            if (s->ucode_used[j][i]) {                s->m_to_linear[j][m] = s->ucode_to_linear[i];                m++;            }        }        s->M[j] = m;    }}static u8 test_buf[1000];/* send a CP frame (analog modem) */static void v90_send_CP(V90DecodeState *s, int is_CP, int ack){    u8 *buf, *p;    int i, crc, drn;    buf = test_buf;    p = buf;    put_bits(&p, 17, 0x1ffff); /* frame sync */    put_bits(&p, 1, 0); /* start bit */    put_bits(&p, 1, 0); /* reserved */    put_bits(&p, 1, is_CP); /* 0=CPt 1=CP frame */    drn = s->K + s->S;    if (is_CP)         drn -= 20;    else        drn -= 8;    put_bits(&p, 5, drn); /* drn: speed */    put_bits(&p, 5, 0); /* reserved */    put_bits(&p, 1, 0); /* 1 if silence asked */    put_bits(&p, 2, 6 - s->S); /* Sr */    put_bits(&p, 1, ack); /* ack */        put_bits(&p, 1, 0); /* start bit */    put_bits(&p, 1, s->alaw); /* u/a law selection */    for(i=0;i<13;i++) {        put_bits(&p, 1, 1); /* speed (i+2) * 2400 supported (V34 part) */    }    put_bits(&p, 2, s->ld);        put_bits(&p, 1, 0); /* start bit */    put_bits(&p, 16, 0); /* RMS value for TRN1d */        put_bits(&p, 1, 0); /* start bit */    put_bits(&p, 8, s->a1 & 0xff); /* spectral shaping parameters */    put_bits(&p, 8, s->a2 & 0xff); /* spectral shaping parameters */    put_bits(&p, 1, 0); /* start bit */    put_bits(&p, 8, s->b1 & 0xff); /* spectral shaping parameters */    put_bits(&p, 8, s->b2 & 0xff); /* spectral shaping parameters */        put_bits(&p, 1, 0); /* start bit */    for(i=0;i<6;i++) {        if (i == 4)             put_bits(&p, 1, 0); /* start bit */        put_bits(&p, 4, 0); /* modulation index */    }        put_bits(&p, 1, 0); /* different different tx - D/A constellations ? */    put_bits(&p, 7, 0); /* reserved */        /* transmit the constellation */    for(i=0;i<128;i++) {        if ((i & 15) == 0)             put_bits(&p, 1, 0); /* start bit */        put_bits(&p, 1, s->ucode_used[0][i]);    }    /* CRC */    put_bits(&p, 1, 0); /* start bit */    crc = calc_crc(buf + 17, p - (buf+17));    put_bits(&p, 16, crc);    put_bits(&p, 3, 0); /* fill */    printf("CP size= %d\n", p - buf);}static int get_bit(u8 **pp){    u8 *p;    int v;    p = *pp;    v = *p++;    *pp = p;    return v;}static int get_bits(u8 *p, int n){    int i, v;    v = 0;    for(i=n-1;i>=0;i--) {        v |= *p++ << i;    }    return v;}/* parse the CP packet & compute the V90 parameters */static void v90_parse_CP(V90EncodeState *s, u8 *buf){    u8 m_index[6];    u8 ucode_used[7][128];    int drn, i, j, k, nb_constellations;    /* now the whole packet is can be read */    s->S = 6 - get_bits(buf + 31, 2);    s->alaw = get_bits(buf + 35, 1);    s->ld = get_bits(buf + 49, 2);    s->a1 = (s8) get_bits(buf + 69, 8);    s->a2 = (s8) get_bits(buf + 77, 8);    s->b1 = (s8) get_bits(buf + 86, 8);    s->b2 = (s8) get_bits(buf + 94, 8);        for(i=0;i<4;i++)        m_index[i] = get_bits(buf + 103 + i * 4, 4);    for(i=0;i<2;i++)        m_index[4 + i] = get_bits(buf + 120 + i * 4, 4);    nb_constellations = 0;    for(i=0;i<6;i++) {        if (m_index[i] > nb_constellations) nb_constellations = m_index[i];    }    nb_constellations++;    if (buf[128])        nb_constellations++;        for(i=0;i<nb_constellations;i++) {        for(j=0;j<128;j++) {            k = i * 128 + j;            ucode_used[i][j] = buf[137 + (17 * (k >> 4)) + (k & 15)];        }    }        /* compute K */    drn = get_bits(buf + 20, 5);    if (buf[19])         drn += 20;    else         drn += 8;    s->K = drn - s->S;    if (s->alaw)        s->ucode_to_linear = v90_alaw_ucode_to_linear;    else        s->ucode_to_linear = v90_ulaw_ucode_to_linear;    printf("V90_received_CP:\n");    compute_constellation(s, m_index, ucode_used);    printf("S=%d K=%d R=%d alaw=%d ld=%d a1=%d a2=%d b1=%d b2=%d\n",            s->S, s->K, ((s->S + s->K) * 8000) / 6,           s->alaw, s->ld, s->a1, s->a2, s->b1, s->b2);}/* received & parse the CP packet */static void v90_receive_CP(V90EncodeState *s){    u8 buf[1024], *p, *q;    int b, i, frame_index, one_count, frame_count, nb_constellations;    int crc1;    u8 m_index[6];    p = test_buf;      wait_sync:    one_count = 0;        while (get_bit(&p)) {        one_count++;    }    if (one_count != 17)        goto wait_sync;#ifdef DEBUG    printf("got CP sync\n");#endif    frame_index = 0;    frame_count = 8;    crc1 = 1;    q = buf + 17;    while (frame_index < frame_count) {        printf("%2d: ", frame_index);        *q++ = 0;        for(i=0;i<16;i++) {            b = get_bit(&p);            *q++ = b;            printf("%d", b);        }        printf("\n");        if (frame_index == 6) {            /* compute the number of constellation to read */            for(i=0;i<4;i++) {                m_index[i] = get_bits(buf + 103 + i * 4, 4);            }            for(i=0;i<2;i++) {                m_index[4 + i] = get_bits(buf + 120 + i * 4, 4);            }            nb_constellations = 0;            for(i=0;i<6;i++) {                if (m_index[i] > nb_constellations) nb_constellations = m_index[i];            }            nb_constellations++;            if (buf[128])                nb_constellations++;            frame_count += 8 * nb_constellations;        }                if (frame_index == (frame_count - 1)) {            /* check the crc (it must be zero because we include the crc itself) */            crc1 = calc_crc(buf + 17, q - (buf+17));        }        if (get_bit(&p) != 0) {            printf("start bit expected\n");            goto wait_sync;        }        frame_index++;    }    if (crc1 != 0)        goto wait_sync;    v90_parse_CP(s, buf);}/* simple test of V90 algebraic computations *//* Note: if ld != 0 and 3 <= S <= 4, the delay introduced with data[][]   is not correct */void V90_test(void){    int i,j,n,l;    V90EncodeState v90_enc;    V90DecodeState v90_dec;    u8 data[5][48], data1[48];    s16 samples[6];    /* init modem state */    memset(&v90_enc, 0, sizeof(v90_enc));    v90_encode_init(&v90_enc);    memset(&v90_dec, 0, sizeof(v90_dec));    v90_decode_init(&v90_dec);        /* send the CP sequence which contains the modulation parameters */    v90_send_CP(&v90_dec, 1, 0);        /* "receive" it ! */    v90_receive_CP(&v90_enc);    /* number of data bits per mapping frame */    n = v90_enc.S + v90_enc.K;    /* transmit & receive 1000 mapping frames */    memset(data, 0, sizeof(data));    l = 0;    for(i=0;i<1000;i++) {        for(j=0;j<n;j++) data[l][j] = random() & 1;                v90_encode_mapping_frame(&v90_enc, samples, data[l]);        // for(j=0;j<6;j++) samples[j] += (random() % 32) - 16;        printf("%4d: ", i);        for(j=0;j<6;j++) printf("%6d,", samples[j]);        printf("\n");        v90_decode_mapping_frame(&v90_dec, data1, samples);        l = (l + 1) % (v90_dec.ld+1);        for(j=0;j<n;j++) {            if (data[l][j] != data1[j]) {                printf("error mapping frame=%d bit=%d\n", i, j);            }        }    }}

⌨️ 快捷键说明

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