git ssb

0+

cel / foostudio



Tree: 6cd4730c51cbbdc9bcc196a95d8dd12dba65eef3

Files: 6cd4730c51cbbdc9bcc196a95d8dd12dba65eef3 / foostudio.c

2843 bytesRaw
1#define _DEFAULT_SOURCE
2#include <alsa/asoundlib.h>
3#include <dlfcn.h>
4#include <err.h>
5#include <math.h>
6#include <stdbool.h>
7#include <stdio.h>
8#include <sys/stat.h>
9#include <sys/types.h>
10#include <unistd.h>
11#include "tune.h"
12#include "ccdl.h"
13
14#define max(a,b) ((a) > (b) ? (a) : (b))
15#define min(a,b) ((a) < (b) ? (a) : (b))
16
17static unsigned int rate = 48000;
18static unsigned int channels_out = 1;
19static unsigned int channels_in = 1;
20static unsigned int latency = 10000; // us
21static int resample = 1; // allow resampling
22
23static snd_pcm_format_t format = SND_PCM_FORMAT_FLOAT;
24
25int main(int argc, char *argv[])
26{
27 struct ccdl ccdl;
28 void *tune_obj = NULL;
29 int err;
30 snd_pcm_t *pcm_out, *pcm_in;
31 const char *src_fname = "tune.c";
32 const char *device_out = "default";
33 const char *device_in = "default";
34
35 if (argc > 1) src_fname = argv[1];
36 if (argc > 2) device_out = argv[2];
37 if (argc > 3) device_in = argv[3];
38
39 ccdl_init(&ccdl, src_fname, "play");
40
41 if (ccdl_watch(&ccdl)) {
42 errx(1, "ccdl_watch");
43 }
44
45 err = snd_pcm_open(&pcm_out, device_out, SND_PCM_STREAM_PLAYBACK, 0);
46 if (err < 0) {
47 warnx("Playback open error: %s", snd_strerror(err));
48 return 1;
49 }
50
51 err = snd_pcm_open(&pcm_in, device_in,
52 SND_PCM_STREAM_CAPTURE,
53 SND_PCM_NONBLOCK);
54 if (err < 0) {
55 warnx("Capture open error: %s", snd_strerror(err));
56 return 1;
57 }
58
59 if ((err = snd_pcm_set_params(pcm_out, format,
60 SND_PCM_ACCESS_RW_INTERLEAVED,
61 channels_out, rate, resample, latency)) < 0) {
62 warnx("Playback open error: %s", snd_strerror(err));
63 return 1;
64 }
65
66 if ((err = snd_pcm_set_params(pcm_in, format,
67 SND_PCM_ACCESS_RW_INTERLEAVED,
68 channels_in, rate, resample, latency)) < 0) {
69 warnx("Capture open error: %s", snd_strerror(err));
70 return 1;
71 }
72
73 double time = 0;
74 double step = 1/(double)rate;
75
76 while (1) {
77 snd_pcm_sframes_t frames, frames_in, frames_out;
78 frames = snd_pcm_avail_update(pcm_out);
79 if (frames < 0) {
80 err = snd_pcm_recover(pcm_out, frames, 0);
81 if (err) err = snd_pcm_wait(pcm_out, 1000);
82 if (err) warnx("snd_pcm_wait(%s)", snd_strerror(err));
83 continue;
84 }
85 float buffer[frames];
86
87 frames_in = snd_pcm_readi(pcm_in, buffer, frames);
88 if (frames_in < 0) snd_pcm_recover(pcm_in, frames_in, 0);
89
90 play_fn *play;
91 *(void **)(&play) = ccdl_get(&ccdl);
92 if (play) {
93 for (size_t i = 0; i < (size_t)frames; i++) {
94 time += step;
95 float frame_in = (ssize_t)i < frames_in ? buffer[i] : 0;
96 buffer[i] = play(&tune_obj, time, frame_in);
97 }
98 } else {
99 time += step * frames;
100 }
101
102 frames_out = snd_pcm_writei(pcm_out, buffer, frames);
103 if (frames_out < 0) snd_pcm_recover(pcm_out, frames_out, 0);
104 }
105
106 snd_pcm_close(pcm_out);
107 snd_pcm_close(pcm_in);
108 return ccdl_deinit(&ccdl);
109}
110

Built with git-ssb-web