-
Notifications
You must be signed in to change notification settings - Fork 255
/
Copy pathmain.cpp
130 lines (101 loc) · 4.14 KB
/
main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include "ggwave/ggwave.h"
#define DR_WAV_IMPLEMENTATION
#include "dr_wav.h"
#include "ggwave-common.h"
#include <cstdio>
#include <cstring>
#include <iostream>
int main(int argc, char** argv) {
fprintf(stderr, "Usage: %s audio.wav [-lN] [-d]\n", argv[0]);
fprintf(stderr, " -lN - fixed payload length of size N, N in [1, %d]\n", GGWave::kMaxLengthFixed);
fprintf(stderr, " -d - use Direct Sequence Spread (DSS)\n");
fprintf(stderr, "\n");
if (argc < 2) {
return -1;
}
const auto argm = parseCmdArguments(argc, argv);
if (argm.count("h") > 0) {
return 0;
}
const int payloadLength = argm.count("l") == 0 ? -1 : std::stoi(argm.at("l"));
const bool useDSS = argm.count("d") > 0;
drwav wav;
if (!drwav_init_file(&wav, argv[1], nullptr)) {
fprintf(stderr, "Failed to open WAV file\n");
return -4;
}
if (wav.channels != 1) {
fprintf(stderr, "Only mono WAV files are supported\n");
return -5;
}
// Read WAV samples into a buffer
// Add 3 seconds of silence at the end
const size_t samplesSilence = 3*wav.sampleRate;
const size_t samplesCount = wav.totalPCMFrameCount;
const size_t samplesSize = wav.bitsPerSample/8;
size_t samplesTotal = samplesCount + samplesSilence;
std::vector<uint8_t> samples(samplesTotal*samplesSize*wav.channels, 0);
printf("[+] Number of channels: %d\n", wav.channels);
printf("[+] Sample rate: %d\n", wav.sampleRate);
printf("[+] Bits per sample: %d\n", wav.bitsPerSample);
printf("[+] Total samples: %zu\n", samplesCount);
printf("[+] Decoding .. \n\n");
GGWave::Parameters parameters = GGWave::getDefaultParameters();
parameters.payloadLength = payloadLength;
parameters.sampleRateInp = wav.sampleRate;
parameters.operatingMode = GGWAVE_OPERATING_MODE_RX;
if (useDSS) parameters.operatingMode |= GGWAVE_OPERATING_MODE_USE_DSS;
switch (wav.bitsPerSample) {
case 16:
drwav_read_pcm_frames_s16(&wav, samplesCount, reinterpret_cast<int16_t*>(samples.data()));
if (wav.channels > 1) {
for (size_t i = 0; i < samplesCount; ++i) {
int16_t sample = 0;
for (size_t j = 0; j < wav.channels; ++j) {
sample += reinterpret_cast<int16_t*>(samples.data())[i*wav.channels + j];
}
reinterpret_cast<int16_t*>(samples.data())[i] = sample / wav.channels;
}
}
parameters.sampleFormatInp = GGWAVE_SAMPLE_FORMAT_I16;
break;
case 32:
drwav_read_pcm_frames_f32(&wav, samplesCount, reinterpret_cast<float*>(samples.data()));
if (wav.channels > 1) {
for (size_t i = 0; i < samplesCount; ++i) {
float sample = 0.0f;
for (size_t j = 0; j < wav.channels; ++j) {
sample += reinterpret_cast<float*>(samples.data())[i*wav.channels + j];
}
reinterpret_cast<float*>(samples.data())[i] = sample / wav.channels;
}
}
parameters.sampleFormatInp = GGWAVE_SAMPLE_FORMAT_F32;
break;
default:
fprintf(stderr, "Unsupported WAV format\n");
return -6;
}
GGWave ggWave(parameters);
ggWave.setLogFile(nullptr);
GGWave::TxRxData data;
auto ptr = samples.data();
while ((int) samplesTotal >= parameters.samplesPerFrame) {
if (ggWave.decode(ptr, parameters.samplesPerFrame*samplesSize*wav.channels) == false) {
fprintf(stderr, "Failed to decode the waveform in the WAV file\n");
return -7;
}
ptr += parameters.samplesPerFrame*samplesSize*wav.channels;
samplesTotal -= parameters.samplesPerFrame;
const int n = ggWave.rxTakeData(data);
if (n > 0) {
printf("[+] Decoded message with length %d: '", n);
for (auto i = 0; i < n; ++i) {
printf("%c", data[i]);
}
printf("'\n");
}
}
printf("\n[+] Done\n");
return 0;
}