Ported @Pagten's target latency patch to pulseaudio IVSHMEM
Unified · Split
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | CC=gcc |
| 2 | −CFLAGS = -Wall | |
| 2 | +CFLAGS = -Wall -O2 | |
| 3 | 3 | |
| 4 | 4 | scream-pulse: scream-ivshmem-pulse.c |
| 5 | 5 | $(CC) $(CFLAGS) -o scream-ivshmem-pulse scream-ivshmem-pulse.c -lpulse-simple -lpulse |
| @@ -20,7 +20,10 @@ · 19 unmodified lines | ||
| 20 | 20 | static void show_usage(const char *arg0) |
| 21 | 21 | { |
| 22 | 22 | fprintf(stderr, "\n"); |
| 23 | − fprintf(stderr, "Usage: %s <ivshmem device path>\n", arg0); | |
| 23 | + fprintf(stderr, "Usage: %s <ivshmem device path> [-t <latency>]\n", arg0); | |
| 24 | + fprintf(stderr, "\n"); | |
| 25 | + fprintf(stderr, " All command line options are optional.\n"); | |
| 26 | + fprintf(stderr, " -t <latency>: Target latency in milliseconds. Defaults to 50ms.\n"); | |
| 24 | 27 | fprintf(stderr, "\n"); |
| 25 | 28 | exit(1); |
| 26 | 29 | } |
| @@ -61,7 +64,7 @@ struct shmheader { · 34 unmodified lines | ||
| 61 | 64 | }; |
| 62 | 65 | |
| 63 | 66 | int main(int argc, char*argv[]) { |
| 64 | − if (argc != 2) { | |
| 67 | + if (argc < 2) { | |
| 65 | 68 | show_usage(argv[0]); |
| 66 | 69 | } |
| 67 | 70 | |
| @@ -72,12 +75,32 @@ int main(int argc, char*argv[]) { · 4 unmodified lines | ||
| 72 | 75 | pa_simple *s; |
| 73 | 76 | pa_sample_spec ss; |
| 74 | 77 | pa_channel_map channel_map; |
| 78 | + pa_buffer_attr buffer_attr; | |
| 75 | 79 | |
| 76 | 80 | unsigned char cur_sample_rate = 0; |
| 77 | 81 | unsigned char cur_sample_size = 0; |
| 78 | 82 | unsigned char cur_channels = 2; |
| 79 | 83 | uint16_t cur_channel_map = 0x0003; |
| 84 | + | |
| 85 | + int target_latency_ms = 50; | |
| 80 | 86 | |
| 87 | + int opt; | |
| 88 | + while ((opt = getopt(argc, argv, "t:h")) != -1) { | |
| 89 | + switch (opt) { | |
| 90 | + case 't': | |
| 91 | + target_latency_ms = atoi(optarg); | |
| 92 | + if (target_latency_ms < 0) show_usage(argv[0]); | |
| 93 | + break; | |
| 94 | + default: | |
| 95 | + show_usage(argv[0]); | |
| 96 | + } | |
| 97 | + } | |
| 98 | + if (1+optind < argc) { | |
| 99 | + fprintf(stderr, "Expected argument after options\n"); | |
| 100 | + show_usage(argv[0]); | |
| 101 | + } | |
| 102 | + | |
| 103 | + | |
| 81 | 104 | // Opportunistic call to renice us, so we can keep up under |
| 82 | 105 | // higher load conditions. This may fail when run as non-root. |
| 83 | 106 | setpriority(PRIO_PROCESS, 0, -11); |
| @@ -92,6 +115,14 @@ int main(int argc, char*argv[]) { · 8 unmodified lines | ||
| 92 | 115 | ss.format = PA_SAMPLE_S16LE; |
| 93 | 116 | ss.rate = 44100; |
| 94 | 117 | ss.channels = cur_channels; |
| 118 | + | |
| 119 | + // set buffer size for requested latency | |
| 120 | + buffer_attr.maxlength = (uint32_t)-1; | |
| 121 | + buffer_attr.tlength = pa_usec_to_bytes((pa_usec_t)target_latency_ms * 1000u, &ss); | |
| 122 | + buffer_attr.prebuf = (uint32_t)-1; | |
| 123 | + buffer_attr.minreq = (uint32_t)-1; | |
| 124 | + buffer_attr.fragsize = (uint32_t)-1; | |
| 125 | + | |
| 95 | 126 | s = pa_simple_new(NULL, |
| 96 | 127 | "Scream", |
| 97 | 128 | PA_STREAM_PLAYBACK, |
| @@ -99,7 +130,7 @@ int main(int argc, char*argv[]) { · 1 unmodified line | ||
| 99 | 130 | "Audio", |
| 100 | 131 | &ss, |
| 101 | 132 | &channel_map, |
| 102 | − NULL, | |
| 133 | + &buffer_attr, | |
| 103 | 134 | &error |
| 104 | 135 | ); |
| 105 | 136 | if (!s) { |
| @@ -220,7 +251,11 @@ int main(int argc, char*argv[]) { · 114 unmodified lines | ||
| 220 | 251 | } |
| 221 | 252 | |
| 222 | 253 | if (ss.rate > 0) { |
| 254 | + // sample spec has changed, so the playback buffer size for the requested latency must be recalculated as well | |
| 255 | + buffer_attr.tlength = pa_usec_to_bytes((pa_usec_t)target_latency_ms * 1000, &ss); | |
| 256 | + | |
| 223 | 257 | if (s) pa_simple_free(s); |
| 258 | + | |
| 224 | 259 | s = pa_simple_new(NULL, |
| 225 | 260 | "Scream", |
| 226 | 261 | PA_STREAM_PLAYBACK, |
| @@ -228,7 +263,7 @@ int main(int argc, char*argv[]) { · 1 unmodified line | ||
| 228 | 263 | "Audio", |
| 229 | 264 | &ss, |
| 230 | 265 | &channel_map, |
| 231 | − NULL, | |
| 266 | + &buffer_attr, | |
| 232 | 267 | NULL |
| 233 | 268 | ); |
| 234 | 269 | if (s) { |