-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathshmem.c
77 lines (62 loc) · 2.12 KB
/
shmem.c
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
#include "shmem.h"
static rctx_shmem_t rctx_shmem;
static useconds_t shmem_poll_delay;
int init_shmem(char* shmem_device_file, int target_latency_ms)
{
struct stat st;
if (stat(shmem_device_file, &st) < 0) {
fprintf(stderr, "Failed to stat the shared memory file: %s\n", shmem_device_file);
exit(2);
}
int shmFD = open(shmem_device_file, O_RDONLY);
if (shmFD < 0) {
fprintf(stderr, "Failed to open the shared memory file: %s\n", shmem_device_file);
exit(3);
}
rctx_shmem.mmap = mmap(0, st.st_size, PROT_READ, MAP_SHARED, shmFD, 0);
if (rctx_shmem.mmap == MAP_FAILED) {
fprintf(stderr, "Failed to map the shared memory file: %s\n", shmem_device_file);
close(shmFD);
exit(4);
}
struct shmheader *header = (struct shmheader*)rctx_shmem.mmap;
rctx_shmem.read_idx = header->write_idx;
shmem_poll_delay = target_latency_ms * 1000 / 8;
return 0;
}
int32_t mod(int32_t x, int32_t N){
return (x % N + N) %N;
}
void rcv_shmem(receiver_data_t* receiver_data)
{
struct shmheader *header = (struct shmheader*)rctx_shmem.mmap;
int valid = 0;
do {
if (header->magic != 0x11112014) {
while (header->magic != 0x11112014) {
usleep(10000);//10ms
}
rctx_shmem.read_idx = header->write_idx;
continue;
}
if (rctx_shmem.read_idx == header->write_idx) {
usleep(shmem_poll_delay);
continue;
}
if (header->channels == 0 || header->channel_map == 0)
continue;
valid = 1;
} while (!valid);
if (++rctx_shmem.read_idx == header->max_chunks) {
rctx_shmem.read_idx = 0;
}
if(mod(header->write_idx-rctx_shmem.read_idx, header->max_chunks) > 3){//we are too far behind, skip forward
rctx_shmem.read_idx = mod((header->write_idx-1), header->max_chunks);
}
receiver_data->format.sample_rate = header->sample_rate;
receiver_data->format.sample_size = header->sample_size;
receiver_data->format.channels = header->channels;
receiver_data->format.channel_map = header->channel_map;
receiver_data->audio_size = header->chunk_size;
receiver_data->audio = &rctx_shmem.mmap[header->offset+header->chunk_size*rctx_shmem.read_idx];
}