work on ServerBeacon began
This commit is contained in:
parent
bbd19fc2a8
commit
94f851011f
1
.idea/.name
generated
Normal file
1
.idea/.name
generated
Normal file
@ -0,0 +1 @@
|
|||||||
|
wfr
|
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
@ -7,7 +7,7 @@ set(CMAKE_CXX_STANDARD 14)
|
|||||||
|
|
||||||
add_executable(${APP_NAME} main.cpp src/ALSADevice.cpp src/ALSADevice.h src/MemoryPool.cpp src/MemoryPool.h utils/Semaphore.h utils/Semaphore.cpp src/SampleWriter.h src/Timestamp.h
|
add_executable(${APP_NAME} main.cpp src/ALSADevice.cpp src/ALSADevice.h src/MemoryPool.cpp src/MemoryPool.h utils/Semaphore.h utils/Semaphore.cpp src/SampleWriter.h src/Timestamp.h
|
||||||
#src/SampleReceiver.h
|
#src/SampleReceiver.h
|
||||||
src/audio_types.h)
|
src/audio_types.h src/ServerBeacon.cpp src/ServerBeacon.h)
|
||||||
|
|
||||||
find_package(Threads REQUIRED)
|
find_package(Threads REQUIRED)
|
||||||
if (THREADS_FOUND)
|
if (THREADS_FOUND)
|
||||||
|
@ -1,39 +1,46 @@
|
|||||||
% settings
|
function ds = read_syncdata(DATASET_DIR)
|
||||||
DATASET_DIR = 'test';
|
% settings
|
||||||
TS_FILE = 'ts';
|
%DATASET_DIR = 'test_20221';
|
||||||
SAMPLE_FILE_PREFIX = 'ch_';
|
TS_FILE = 'ts';
|
||||||
FILE_EXT = 'dat';
|
SAMPLE_FILE_PREFIX = 'ch_';
|
||||||
CHANNELS = 2;
|
FILE_EXT = 'dat';
|
||||||
|
CHANNELS = 2;
|
||||||
|
|
||||||
% computed values
|
% computed values
|
||||||
FN_TS = strcat(DATASET_DIR, '/', TS_FILE, '.', FILE_EXT);
|
FN_TS = strcat(DATASET_DIR, '/', TS_FILE, '.', FILE_EXT);
|
||||||
|
|
||||||
for ch=0:1:(CHANNELS-1)
|
for ch=0:1:(CHANNELS-1)
|
||||||
FN_SAMPLE{ch+1} = strcat(DATASET_DIR, '/', SAMPLE_FILE_PREFIX, num2str(ch), '.', FILE_EXT);
|
FN_SAMPLE{ch+1} = strcat(DATASET_DIR, '/', SAMPLE_FILE_PREFIX, num2str(ch), '.', FILE_EXT);
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
% load timestamps
|
% load timestamps
|
||||||
f = fopen(FN_TS ,'r');
|
f = fopen(FN_TS ,'r');
|
||||||
ts = fread(f,[2,Inf],'uint32');
|
ts = fread(f,[2,Inf],'uint32');
|
||||||
fclose(f);
|
|
||||||
|
|
||||||
% take first element as t0
|
|
||||||
ts(1,:) = ts(1,:) - ts(1,1);
|
|
||||||
|
|
||||||
% create fractional timestamp
|
|
||||||
ts = ts(1,:) + ts(2,:) / 1E+09;
|
|
||||||
|
|
||||||
% get sample count
|
|
||||||
sample_cnt = length(ts);
|
|
||||||
|
|
||||||
% load samples
|
|
||||||
s = zeros(CHANNELS, sample_cnt);
|
|
||||||
for ch=1:CHANNELS
|
|
||||||
f = fopen(FN_SAMPLE{ch},'r');
|
|
||||||
d = fread(f, [1,Inf],'int16');
|
|
||||||
s(ch,:) = d;
|
|
||||||
fclose(f);
|
fclose(f);
|
||||||
end
|
|
||||||
|
|
||||||
plot(ts(1,1:100), s(1,1:100))
|
% take first element as t0
|
||||||
|
%ts(1,:) = ts(1,:) - 1636036145;
|
||||||
|
|
||||||
|
% create fractional timestamp
|
||||||
|
ts = ts(1,:) + ts(2,:) / 1E+09;
|
||||||
|
|
||||||
|
% get sample count
|
||||||
|
sample_cnt = length(ts);
|
||||||
|
|
||||||
|
% load samples
|
||||||
|
s = zeros(CHANNELS, sample_cnt);
|
||||||
|
for ch=1:CHANNELS
|
||||||
|
f = fopen(FN_SAMPLE{ch},'r');
|
||||||
|
d = fread(f, [1,Inf],'int16');
|
||||||
|
s(ch,:) = d;
|
||||||
|
fclose(f);
|
||||||
|
end
|
||||||
|
|
||||||
|
%figure(1)
|
||||||
|
%plot(ts(1,1:100), s(1,1:100), 'x')
|
||||||
|
%xlim([ts(1) ts(100)])
|
||||||
|
%hold on
|
||||||
|
|
||||||
|
ds = [ts' s'];
|
||||||
|
end
|
72
MATLAB/sync_datasets.m
Normal file
72
MATLAB/sync_datasets.m
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
function sds = sync_datasets(dss)
|
||||||
|
% load datasets
|
||||||
|
len = length(dss);
|
||||||
|
sds = {};
|
||||||
|
first_ts = [];
|
||||||
|
last_ts = [];
|
||||||
|
for i=1:len
|
||||||
|
ds = read_syncdata(dss{i});
|
||||||
|
first_ts(i) = ds(1:1);
|
||||||
|
last_ts(i) = ds(end,1);
|
||||||
|
sds{i} = ds;
|
||||||
|
end
|
||||||
|
|
||||||
|
% get first and last common timestamp
|
||||||
|
ts0 = max(first_ts);
|
||||||
|
tsend = min(last_ts);
|
||||||
|
|
||||||
|
for i=1:len
|
||||||
|
ds = sds{i};
|
||||||
|
ds = ds(ds(:,1) > ts0 + (ds(2,1) - ds(1,1)) / 2 & ds(:,1) < tsend, :); % drop non-common sections
|
||||||
|
ds(:,1) = ds(:,1) - ts0; % substract ts0 from each dataset's timestamp array
|
||||||
|
sds{i} = ds;
|
||||||
|
end
|
||||||
|
|
||||||
|
% create plot
|
||||||
|
figure(1)
|
||||||
|
|
||||||
|
% plot samples
|
||||||
|
subplot(2,1,1);
|
||||||
|
|
||||||
|
marks = ['-', '-o'];
|
||||||
|
|
||||||
|
PLOTRANGE = 1:100;
|
||||||
|
|
||||||
|
% get beginning indices
|
||||||
|
for i=1:len
|
||||||
|
ds = sds{i};
|
||||||
|
ts = ds(:,1);
|
||||||
|
|
||||||
|
s = size(ds);
|
||||||
|
|
||||||
|
%for k = 2:s(2);
|
||||||
|
for k = 2:2
|
||||||
|
%plot(ts(1:100),ds(1:100,k), marks(k-1));
|
||||||
|
plot(ts(PLOTRANGE),ds(PLOTRANGE,k), 'x');
|
||||||
|
hold on
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
grid on
|
||||||
|
xlabel("Time [s]");
|
||||||
|
ylabel("Sample");
|
||||||
|
xlim([ts(PLOTRANGE(1)) ts(PLOTRANGE(end))]);
|
||||||
|
|
||||||
|
% plot timestamp errors
|
||||||
|
subplot(2,1,2);
|
||||||
|
|
||||||
|
ds_ref = sds{1};
|
||||||
|
ts_ref = ds_ref(:,1);
|
||||||
|
|
||||||
|
for i = 2:len
|
||||||
|
ts_err = ts(PLOTRANGE) - ts_ref(PLOTRANGE);
|
||||||
|
plot(ts_ref(PLOTRANGE), ts_err * 1E+09);
|
||||||
|
hold on
|
||||||
|
end
|
||||||
|
|
||||||
|
grid on
|
||||||
|
xlabel("Time [s]");
|
||||||
|
ylabel("Time error [ns]");
|
||||||
|
xlim([ts(PLOTRANGE(1)) ts(PLOTRANGE(end))]);
|
||||||
|
|
||||||
|
endfunction
|
2
main.cpp
2
main.cpp
@ -144,7 +144,7 @@ uint8_t pRecvBuf[8096] __attribute__ ((aligned (32)));
|
|||||||
int main(int argc, char * argv[]) {
|
int main(int argc, char * argv[]) {
|
||||||
ALSADevice dev(PERIOD_LEN, SAMPLE_RATE);
|
ALSADevice dev(PERIOD_LEN, SAMPLE_RATE);
|
||||||
MemoryPool<int16_t> pool(STEREO_BUF_LEN, 1000);
|
MemoryPool<int16_t> pool(STEREO_BUF_LEN, 1000);
|
||||||
//SampleWriter<AudioSampleType> sw("test", 2, STEREO_BUF_LEN / 2);
|
//SampleWriter<AudioSampleType> sw(std::string("test_") + argv[1], 2, STEREO_BUF_LEN / 2);
|
||||||
|
|
||||||
//std::this_thread::sleep_for(std::chrono::seconds(1));
|
//std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||||
|
|
||||||
|
133
src/ServerBeacon.cpp
Normal file
133
src/ServerBeacon.cpp
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
//
|
||||||
|
// Created by epagris on 2021. 11. 11..
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <memory>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "ServerBeacon.h"
|
||||||
|
|
||||||
|
const in_addr ServerBeacon::DEFAULT_MULTICAST_ADDR = {inet_addr("224.0.2.21")};
|
||||||
|
|
||||||
|
ServerBeacon::ServerBeacon() : mRunning(false) {
|
||||||
|
setMulticastAddr(DEFAULT_MULTICAST_ADDR);
|
||||||
|
setPort(DEFAULT_PORT);
|
||||||
|
setAnnouncePeriod(DEFAULT_ANNOUNCE_PERIOD_MS);
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerBeacon::ServerBeacon(const in_addr &addr, unsigned short port, size_t announcePeriod_ms) : mRunning(false) {
|
||||||
|
setMulticastAddr(addr);
|
||||||
|
setPort(port);
|
||||||
|
setAnnouncePeriod(announcePeriod_ms);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerBeacon::setMulticastAddr(const in_addr &addr) {
|
||||||
|
mAddr = addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
in_addr ServerBeacon::getMulticastAddr() const {
|
||||||
|
return mAddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ServerBeacon::setPort(unsigned short port) {
|
||||||
|
mBeaconPort = port;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned short ServerBeacon::getPort() const {
|
||||||
|
return mBeaconPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerBeacon::setAnnouncePeriod(size_t period_ms) {
|
||||||
|
mAnnPeriod_ms = period_ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t ServerBeacon::getAnnouncePeriod() const {
|
||||||
|
return mAnnPeriod_ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerBeacon::startBeacon() {
|
||||||
|
if (mRunning) {
|
||||||
|
std::cerr << "Could not start beacon: already running!" << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mBeaconSoc = socket(AF_INET, SOCK_DGRAM, 0); // create socket
|
||||||
|
if (mBeaconSoc == -1) {
|
||||||
|
std::cerr << "Could not open socket in " << __FUNCTION__ << "!" << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set socket options
|
||||||
|
int opt = 1;
|
||||||
|
setsockopt(mBeaconSoc, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt));
|
||||||
|
|
||||||
|
// bind to ip-address and port
|
||||||
|
sockaddr_in addr;
|
||||||
|
addr.sin_family = AF_INET;
|
||||||
|
addr.sin_addr = mAddr;
|
||||||
|
addr.sin_port = htons(mBeaconPort);
|
||||||
|
|
||||||
|
if (bind(mBeaconSoc, (const sockaddr *) &addr, sizeof(addr)) == -1) {
|
||||||
|
std::cerr << "Could not bind to IP address and/or port in " << __FUNCTION__ << "!" << std::endl;
|
||||||
|
close(mBeaconSoc);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// the beacon is running now!
|
||||||
|
mRunning = true;
|
||||||
|
|
||||||
|
// start beacon thread
|
||||||
|
mpBeaconThread = std::make_shared<std::thread>(fn_BeaconThread, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerBeacon::stopBeacon() {
|
||||||
|
mRunning = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::list<in_addr> ServerBeacon::getNodesOnNetwork() {
|
||||||
|
return std::list<in_addr>();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------------------------------
|
||||||
|
|
||||||
|
void ServerBeacon::fn_BeaconThread(ServerBeacon *pSB) {
|
||||||
|
// beacon message used to send and receive information
|
||||||
|
BeaconMsg msg;
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
// select-related structures
|
||||||
|
fd_set read_fds;
|
||||||
|
timeval tv;
|
||||||
|
|
||||||
|
// fill-in select parameters
|
||||||
|
FD_ZERO(&read_fds);
|
||||||
|
FD_SET(pSB->mBeaconSoc, &read_fds);
|
||||||
|
|
||||||
|
// fill-in timeout value
|
||||||
|
tv.tv_sec = pSB->mAnnPeriod_ms / 1000;
|
||||||
|
tv.tv_usec = (pSB->mAnnPeriod_ms % 1000) * 1000;
|
||||||
|
|
||||||
|
while (pSB->mRunning) {
|
||||||
|
msg.server_nClient = 1; // we are the server
|
||||||
|
msg.terminalPort = 0; // we have no inbound terminal port
|
||||||
|
|
||||||
|
send(pSB->mBeaconSoc, &msg, sizeof(BeaconMsg), 0); // send the announce message
|
||||||
|
|
||||||
|
// ------------------
|
||||||
|
|
||||||
|
// copy parameters
|
||||||
|
fd_set cur_rfds = read_fds;
|
||||||
|
timeval cur_tv = tv;
|
||||||
|
|
||||||
|
while (select(1, &cur_rfds, nullptr, nullptr, &cur_tv) != 0) {
|
||||||
|
// receive response
|
||||||
|
recv(pSB->mBeaconSoc, &msg, sizeof(BeaconMsg), 0);
|
||||||
|
|
||||||
|
// store response
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
56
src/ServerBeacon.h
Normal file
56
src/ServerBeacon.h
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
//
|
||||||
|
// Created by epagris on 2021. 11. 11..
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef WFR_SERVERBEACON_H
|
||||||
|
#define WFR_SERVERBEACON_H
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <list>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
class ServerBeacon {
|
||||||
|
public:
|
||||||
|
static constexpr unsigned short DEFAULT_PORT = 8021; // default port for multicast messages
|
||||||
|
static const in_addr DEFAULT_MULTICAST_ADDR; // default multicast address
|
||||||
|
static constexpr size_t DEFAULT_ANNOUNCE_PERIOD_MS = 1000; // default announce period
|
||||||
|
private:
|
||||||
|
// structure for storing nodes
|
||||||
|
struct ClientNodeInfo {
|
||||||
|
in_addr addr; // address of client
|
||||||
|
uint16_t terminalPort;
|
||||||
|
};
|
||||||
|
private:
|
||||||
|
int mBeaconSoc; // beacon socket
|
||||||
|
in_addr mAddr; // address
|
||||||
|
unsigned short mBeaconPort; // port
|
||||||
|
size_t mAnnPeriod_ms; // announce period
|
||||||
|
std::list<ClientNodeInfo> mNodes; // nodes
|
||||||
|
bool mRunning; // does the beacon operate?
|
||||||
|
private:
|
||||||
|
std::shared_ptr<std::thread> mpBeaconThread; // thread running the beacon
|
||||||
|
static void fn_BeaconThread(ServerBeacon * pSB); // function running in beacon thread
|
||||||
|
private:
|
||||||
|
// structure for beacon MSG
|
||||||
|
struct BeaconMsg {
|
||||||
|
uint8_t server_nClient; // server or client
|
||||||
|
uint16_t terminalPort; // port of terminal
|
||||||
|
};
|
||||||
|
public:
|
||||||
|
ServerBeacon(); // constr.
|
||||||
|
explicit ServerBeacon(const in_addr& addr, unsigned short port, size_t announcePeriod_ms); // constr. with beacon port and announce period
|
||||||
|
void setMulticastAddr(const in_addr& addr); // set multicasting address
|
||||||
|
in_addr getMulticastAddr() const; // set multicasting address
|
||||||
|
void setPort(unsigned short port); // set port BEFORE starting beacon
|
||||||
|
unsigned short getPort() const; // get beacon port
|
||||||
|
void setAnnouncePeriod(size_t period_ms); // set announce period
|
||||||
|
size_t getAnnouncePeriod() const; // get announce period
|
||||||
|
void startBeacon(); // start the beacon
|
||||||
|
void stopBeacon(); // stop the beacon
|
||||||
|
std::list<in_addr> getNodesOnNetwork(); // get nodes connected to the same network
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //WFR_SERVERBEACON_H
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
#define STEREO_BUF_LEN (648)
|
#define STEREO_BUF_LEN (2 * 192)
|
||||||
#define PERIOD_LEN (STEREO_BUF_LEN / 2)
|
#define PERIOD_LEN (STEREO_BUF_LEN / 2)
|
||||||
#define SAMPLE_RATE (48000)
|
#define SAMPLE_RATE (48000)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user