Я бы просто написал цикл, который будет генерировать пакеты и отправлять их с соответствующим интервалом, например: учитывая:
static constexpr int NUM_CHANNELS = 32;
static constexpr int NUM_SAMPLES_PER_PACKET = 15;
struct packet {
uint64_t timestamp_ms;
uint32_t packet_counter;
int16_t data[NUM_CHANNELS * NUM_SAMPLES_PER_PACKET];
};
Я, очевидно, составил формат пакета, поскольку вы этого не сделалиуказать что угодно. вам нужно взломать это, чтобы соответствовать тому, что на самом деле требуется. Я также использую здесь 16-битные значения, чтобы упростить работу с данными, заполнение 24-битных выборок, вероятно, будет проще всего с массивом uint8_t
с и некоторыми побитовыми операциями для упаковки значений.
далееЯ определяю функцию для реализации цикла:
void
generate_samples(int sockfd)
{
struct timespec scheduler;
clock_gettime(CLOCK_MONOTONIC, &scheduler);
struct packet pkt {};
auto time = 0;
while (time < 200000) {
// fill data into packet
for (auto sample = 0; sample < NUM_SAMPLES_PER_PACKET; ++sample) {
double t = time++ * (2 * M_PI / 100);
for (auto channel = 0; channel < NUM_CHANNELS; ++channel) {
pkt.data[sample * NUM_CHANNELS + channel] = sin(t + 0.1 * channel) * (1<<15);
}
}
// wait until an appropriate amount of time has passed before
// sending out the next packet
scheduler.tv_nsec += 75000;
if(scheduler.tv_nsec >= 1000000000) {
scheduler.tv_nsec -= 1000000000;
scheduler.tv_sec++;
}
clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &scheduler, NULL);
struct timespec now;
clock_gettime(CLOCK_REALTIME, &now);
// update book-keeping fields
pkt.timestamp_ms = int64_t{now.tv_sec} * 1000000 + int64_t{now.tv_nsec} / 1000;
pkt.packet_counter += 1;
// actually send the packet
send(sockfd, &pkt, sizeof(pkt), 0);
}
}
параметр sockfd
- это просто дескриптор файла из socket()
, который был connect()
отредактирован по соответствующему адресу, поэтому send
знает, куда отправлятьидти. вам, вероятно, понадобится некоторая проверка ошибок (например, при вызовах clock_*
и send
), но это делает что-то разумное для меня.