Exemple #1
0
// samples should be u-law encoded
void modem_decode(buffer_t *input, buffer_t *output)
{
    static int phase = -1;
    int max_idx;
    size_t i;
    int16_t max_mag;
    int16_t samples[SAMPLES_PER_ITER];

    for (i = 0; i < SAMPLES_PER_ITER; i++)
    {
        uint8_t byte;
        buffer_read_bytes(input, &byte, 1);
        samples[i] = comp_decode(byte) * 4;
    }

    // apply band-pass filter to remove noise
    bandpass_filter(samples);

    // apply convolution with delay line
    convolution(samples);

    // apply low-pass filter to remove high-frequency artifacts
    lowpass_filter(samples);

    // try and find the middle of the phase
    if (phase == -1)
    {
        max_mag = 0;
        max_idx = 0;
        for (i = 0; i < SAMPLES_PER_ITER; i++)
        {
            if (samples[i] > max_mag)
            {
                max_mag = samples[i];
                max_idx = i;
            }
            else if (-samples[i] > max_mag)
            {
                max_mag = -samples[i];
                max_idx = i;
            }
        }
        phase = (max_idx) % (SAMPLES_PER_BIT / 2);
    }

    // sample at baudrate to get output
    for (i = phase; i < SAMPLES_PER_ITER; i += SAMPLES_PER_BIT)
    {
        int avg = 0;
        int j;
        for (j = 0; j < SAMPLES_PER_BIT / 4; j++)
            avg += samples[i + j]; //< 0 ? -1 : 1;
        avg /= SAMPLES_PER_BIT / 4;
        int bit = avg < 0 ? 1 : 0;
        buffer_write_bit(output, bit);
    }
}
Exemple #2
0
void modem_encode_frame(buffer_t *output)
{
    size_t i;
    uint8_t data[FRAME_SIZE / 8 + 1];
    buffer_t buf;

    if (buffer_read_remaining(&g_frames) < FRAME_SIZE)
        return;

    buffer_init(&buf, data, sizeof(data));
    buffer_write_bits(&buf, 0x13, 5);

    for (i = 0; i < FRAME_SIZE / 8; i++)
    {
        uint8_t byte;
        buffer_read_bytes(&g_frames, &byte, 1);
        buffer_write_bytes(&buf, &byte, 1);
    }
    
    modem_encode(&buf, output);
}
Exemple #3
0
void modem_loop(modem_rx_cb_t cb)
{
#define BIT_1 0
#define BIT_2 1
#define BIT_3 2
#define BIT_4 3
#define BIT_5 4
#define WAIT_FOR_DATA 5
    int state = 0, recvd = 0;
    uint64_t mark;
    static uint8_t indata[1024], decdata[512], pktdata[1024], outdata[32768];
    buffer_t inbuf, decbuf, pktbuf, outbuf;

    buffer_init(&inbuf, indata, sizeof(indata));
    buffer_init(&decbuf, decdata, sizeof(decdata));
    buffer_init(&pktbuf, pktdata, sizeof(pktdata));
    buffer_init(&outbuf, outdata, sizeof(outdata));

    while (1)
    {
        uint8_t u_sample;
        size_t bytes = 1;

        if (ready_to_read() == 0) {
            // transmit(STDERR, "flush!\n", 7, NULL);
            flush_output();
        }

        if (get_byte(&u_sample) != 0)
            break;
//        if (receive(STDIN, &u_sample, 1, &bytes) != 0 || bytes != 1)
//            break;
        recvd++;

        buffer_write_bytes(&inbuf, &u_sample, 1);
        
        // process samples every 0.01 ms
        if (buffer_read_remaining(&inbuf) / 8 >= SAMPLES_PER_ITER)
        {
            modem_decode(&inbuf, &decbuf);

            while (state != WAIT_FOR_DATA && buffer_read_remaining(&decbuf) >= 8)
            {
                uint8_t bit;
                bit = buffer_read_bit(&decbuf);

                switch (state)
                {
                case BIT_1:
                    state = BIT_2;
                    mark = buffer_read_tell(&decbuf);
                    if (bit != 1)
                        goto reset;
                    break;
                case BIT_2:
                    state = BIT_3;
                    if (bit != 0)
                        goto reset;
                    break;
                case BIT_3:
                    state = BIT_4;
                    if (bit != 0)
                        goto reset;
                    break;
                case BIT_4:
                    state = BIT_5;
                    if (bit != 1)
                        goto reset;
                    break;
                case BIT_5:
                    state = WAIT_FOR_DATA;
                    if (bit != 1)
                        goto reset;
                    break;
                }
                
                continue;
reset:
                state = BIT_1;
                buffer_read_seek(&decbuf, mark);
            }

            if (state == WAIT_FOR_DATA && buffer_read_remaining(&decbuf) > FRAME_SIZE)
            {
                int result = frame_decode(&decbuf, &pktbuf);
                if (result == FRAME_FAIL)
                {
                    goto reset;
                }
                else if (result == FRAME_END)
                {
                    // XXX send packet to callback
                    cb(pktdata, buffer_read_remaining(&pktbuf) / 8);

                    buffer_init(&pktbuf, pktdata, sizeof(pktdata));
                }

                state = BIT_1;
            }
        }

        if (buffer_read_remaining(&outbuf) == 0)
            modem_encode_frame(&outbuf);

        if (buffer_read_remaining(&outbuf) > 0)
            buffer_read_bytes(&outbuf, &u_sample, 1);
        else
            u_sample = _modem_encode(1);

        write_byte(u_sample);
//        transmit(STDOUT, &u_sample, 1, &bytes);
    }
}
Exemple #4
0
/*
 * you should care about the trailing-null by yourself
 */
void
buffer_read_string(buffer_t *b, char *str, size_t len) {
    buffer_read_bytes(b, str, len);
}