pveselov

parec_muilti_str.c

Jan 1st, 2022 (edited)
309
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.21 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <string.h>
  4. #include <fcntl.h>
  5. #include <pthread.h>
  6.  
  7. #include <pulse/error.h>
  8. #include <pulse/channelmap.h>
  9. #include <pulse/stream.h>
  10. #include <pulse/context.h>
  11. #include <pulse/mainloop.h>
  12.  
  13. // thank you https://gist.github.com/toroidal-code/8798775
  14.  
  15. static char * argv0;
  16. static pa_context * pa_ctx;
  17. static pthread_t p1;
  18. static pthread_t p2;
  19.  
  20. static int fd1 = -1;
  21. static int fd2 = -1;
  22.  
  23. /* A simple routine calling UNIX write() in a loop */
  24. static ssize_t loop_write(int fd, const void*data, size_t size) {
  25.     ssize_t ret = 0;
  26.  
  27.     while (size > 0) {
  28.         ssize_t r;
  29.  
  30.         if ((r = write(fd, data, size)) < 0)
  31.             return r;
  32.  
  33.         if (r == 0)
  34.             break;
  35.  
  36.         ret += r;
  37.         data = (const uint8_t*) data + r;
  38.         size -= (size_t) r;
  39.     }
  40.  
  41.     return ret;
  42. }
  43.  
  44. static void pa_die(char const * nam, int e) {
  45.     if (e) {
  46.         fprintf(stderr,"%s() failed: %s\n", nam, pa_strerror(e));
  47.         _exit(1);
  48.     }
  49. }
  50.  
  51. static void on_read(pa_stream *p, size_t len, void *user_data) {
  52.  
  53.     int fd = *(int*)user_data;
  54.     void const * buf;
  55.     // it seems that incoming len is pointless.
  56.     pa_die("pa_stream_peek", pa_stream_peek(p, &buf, &len));
  57.     if (len) {
  58.         if (buf) {
  59.             loop_write(fd, buf, len);
  60.         } else {
  61.             // hole
  62.             unsigned char buf2[len];
  63.             memset(buf2, 0, len);
  64.             loop_write(fd, buf2, len);
  65.         }
  66.         pa_die("pa_stream_drop", pa_stream_drop(p));
  67.     }
  68.  
  69. }
  70.  
  71. static void start_stream(char const * file, int * fd) {
  72.  
  73.     static const pa_sample_spec ss = {
  74.             .format = PA_SAMPLE_S16LE,
  75.             .rate = 44100,
  76.             .channels = 2
  77.     };
  78.     pa_stream * s;
  79.  
  80.     pa_channel_map cm;
  81.  
  82.     pa_channel_map_init_stereo(&cm);
  83.  
  84.     if (!pa_channel_map_valid(&cm)) {
  85.         printf("channel map not valid\n");
  86.         _exit(1);
  87.     }
  88.  
  89.     if (!(s = pa_stream_new(pa_ctx, file, &ss, &cm))) {
  90.         printf("no new stream\n");
  91.         _exit(1);
  92.     }
  93.  
  94.     *fd = open(file, O_WRONLY|O_TRUNC|O_CREAT, 0644);
  95.     if (*fd < 0) {
  96.         perror("create");
  97.         _exit(1);
  98.     }
  99.  
  100.     pa_stream_set_read_callback(s, on_read, fd);
  101.     pa_die("pa_stream_connect_record", pa_stream_connect_record(s, NULL, NULL, PA_STREAM_NOFLAGS));
  102.  
  103. }
  104.  
  105. static void on_state(pa_context *c, void *userdata) {
  106.  
  107.     pa_context_state_t st = pa_context_get_state(c);
  108.  
  109.     printf("context state %d\n", (int)st);
  110.  
  111.     if (st == PA_CONTEXT_READY) {
  112.         start_stream("1", &fd1);
  113.         start_stream("2", &fd2);
  114.     }
  115.  
  116. }
  117.  
  118. int main(int argc, char*argv[]) {
  119.     /* The sample type to use */
  120.  
  121.     pa_mainloop * pa_lp = pa_mainloop_new();
  122.     if (!pa_lp) {
  123.         printf("no main loop\n");
  124.         return 1;
  125.     }
  126.  
  127.     pa_mainloop_api * pa_lp_api = pa_mainloop_get_api(pa_lp);
  128.  
  129.     pa_ctx = pa_context_new(pa_lp_api, "two");
  130.     if (!pa_ctx) {
  131.         printf("no context\n");
  132.         return 1;
  133.     }
  134.  
  135.     pa_context_set_state_callback(pa_ctx, on_state, NULL);
  136.     pa_die("pa_context_connect", pa_context_connect(pa_ctx, NULL, PA_CONTEXT_NOFLAGS, NULL));
  137.  
  138.     int dummy;
  139.     pa_mainloop_run(pa_lp, &dummy);
  140.  
  141.     return 0;
  142. }
  143.  
Add Comment
Please, Sign In to add comment