Warning: This is a development version. The latest stable version is Version 10.0.0.
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}