Warning: This is a development version. The latest stable version is Version 10.0.0.

Code Example: Encode and Decode

In this example shows how to use the API of otacast to implement encoding and decoding.

The example will walk through the basic functionality of class otacast::encoder and class otacast::decoder, and discuss how to use them.

 1// Copyright (c) Steinwurf ApS 2023.
 2// This file is licensed under the terms of the accompanying LICENSE.rst file.
 3
 4#include <algorithm>
 5#include <cstdlib>
 6#include <iostream>
 7#include <vector>
 8
 9#include <otacast/decoder.hpp>
10#include <otacast/encoder.hpp>
11#include <otacast/version.hpp>
12
13int main()
14{
15    // Create the encoder/decoder objects with a specific finite field
16    otacast::encoder encoder;
17    otacast::decoder decoder;
18
19    std::size_t block_bytes = 1024 * 1000 * 500; // 500 MB
20    std::size_t symbol_bytes = 1500;             // 1.5 kB
21    auto width = otacast::codec_width::_32;
22
23    encoder.configure(width, block_bytes, symbol_bytes);
24    decoder.configure(width, block_bytes, symbol_bytes);
25
26    std::cout << "Preparing some random test data..." << std::endl;
27
28    // Allocate some data to decode
29    std::vector<uint8_t> data_in(encoder.block_bytes());
30
31    // For the example - fill data_in with random data
32    std::generate(data_in.begin(), data_in.end(), rand);
33
34    // Assign the data buffer to the encoder so that we may start
35    // to produce encoded symbols from it
36    encoder.set_symbols_storage(data_in.data());
37
38    // Define a data buffer where the symbols should be decoded
39    std::vector<uint8_t> data_out(decoder.block_bytes());
40    decoder.set_symbols_storage(data_out.data());
41
42    // Initiate a zero-vector for the offset
43    std::vector<uint8_t> symbol(encoder.symbol_bytes());
44
45    // The seed can be anything, here it's basically a packet sequence number.
46    // Will be used to count transmissions as well
47    std::size_t transmissions = 0;
48
49    // Count number of packets received
50    std::size_t received = 0;
51
52    // Set up some packet loss
53    auto loss_probability = 10;
54
55    std::cout << "Encoding/decoding..." << std::endl;
56
57    while (!decoder.is_complete())
58    {
59        // Generate an encoded packet using the number of transmissions as seed
60        auto offset = encoder.encode(symbol.data(), transmissions);
61
62        // We see if the packet is lost
63        if (rand() % 100 >= loss_probability)
64        {
65            // Decode the encoded packet using the number of transmissions as
66            // seed
67            decoder.decode(symbol.data(), transmissions, offset);
68            received++;
69        }
70        transmissions++;
71    }
72
73    // Calculate the overhead
74    auto data_received = received * decoder.symbol_bytes();
75    auto overhead = (data_received / (double)decoder.block_bytes()) - 1;
76
77    // Check if everything went as it should
78    if (data_in == data_out)
79    {
80        std::cout << "Decoding finished successfully!" << std::endl;
81        std::cout << "Overhead: " << overhead * 100 << "%" << std::endl;
82    }
83    else
84    {
85        std::cout << "Something went wrong!" << std::endl;
86    }
87
88    return 0;
89}