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
|
||||
#src/SampleReceiver.h
|
||||
src/audio_types.h)
|
||||
src/audio_types.h src/ServerBeacon.cpp src/ServerBeacon.h)
|
||||
|
||||
find_package(Threads REQUIRED)
|
||||
if (THREADS_FOUND)
|
||||
|
@ -1,39 +1,46 @@
|
||||
% settings
|
||||
DATASET_DIR = 'test';
|
||||
TS_FILE = 'ts';
|
||||
SAMPLE_FILE_PREFIX = 'ch_';
|
||||
FILE_EXT = 'dat';
|
||||
CHANNELS = 2;
|
||||
function ds = read_syncdata(DATASET_DIR)
|
||||
% settings
|
||||
%DATASET_DIR = 'test_20221';
|
||||
TS_FILE = 'ts';
|
||||
SAMPLE_FILE_PREFIX = 'ch_';
|
||||
FILE_EXT = 'dat';
|
||||
CHANNELS = 2;
|
||||
|
||||
% computed values
|
||||
FN_TS = strcat(DATASET_DIR, '/', TS_FILE, '.', FILE_EXT);
|
||||
% computed values
|
||||
FN_TS = strcat(DATASET_DIR, '/', TS_FILE, '.', FILE_EXT);
|
||||
|
||||
for ch=0:1:(CHANNELS-1)
|
||||
FN_SAMPLE{ch+1} = strcat(DATASET_DIR, '/', SAMPLE_FILE_PREFIX, num2str(ch), '.', FILE_EXT);
|
||||
end
|
||||
for ch=0:1:(CHANNELS-1)
|
||||
FN_SAMPLE{ch+1} = strcat(DATASET_DIR, '/', SAMPLE_FILE_PREFIX, num2str(ch), '.', FILE_EXT);
|
||||
end
|
||||
|
||||
|
||||
% load timestamps
|
||||
f = fopen(FN_TS ,'r');
|
||||
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;
|
||||
% load timestamps
|
||||
f = fopen(FN_TS ,'r');
|
||||
ts = fread(f,[2,Inf],'uint32');
|
||||
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[]) {
|
||||
ALSADevice dev(PERIOD_LEN, SAMPLE_RATE);
|
||||
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));
|
||||
|
||||
|
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>
|
||||
|
||||
#define STEREO_BUF_LEN (648)
|
||||
#define STEREO_BUF_LEN (2 * 192)
|
||||
#define PERIOD_LEN (STEREO_BUF_LEN / 2)
|
||||
#define SAMPLE_RATE (48000)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user