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