git ssb

0+

cel / foostudio



Commit 5150ca653ef3132d6d841efbba1fb59908966663

Rename executable to foostudio

cel committed on 10/26/2016, 2:07:03 AM
Parent: c914c51d3db53e41365c29ba0d795df65bc1cebf

Files changed

Makefilechanged
studio.cdeleted
foostudio.cadded
MakefileView
@@ -1,10 +1,11 @@
1 +BIN = foostudio
12 CFLAGS = -Wall -Wextra -pedantic
23 LDLIBS = -ldl -lasound -lm -lpthread
34
4-studio: studio.o ccdl.o
5 +$(BIN): foostudio.o ccdl.o
56
6-studio.o ccdl.o: Makefile
7 +foostudio.o ccdl.o: Makefile
78
89 clean:
9- $(RM) *.o *.so studio
10 + $(RM) $(wildcard *.o *.so) $(BIN)
1011
studio.cView
@@ -1,232 +1,0 @@
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-static unsigned int rate = 44100;
15-static unsigned int channels = 1;
16-static unsigned int latency = 500000; /* ring buffer length in us */
17-static snd_pcm_format_t format = SND_PCM_FORMAT_FLOAT;
18-
19-/*
20- * Underrun and suspend recovery, from alsa-lib/test/pcm.c
21- */
22-
23-static int xrun_recovery(snd_pcm_t *handle, int err)
24-{
25- if (err == -EPIPE) { /* under-run */
26- err = snd_pcm_prepare(handle);
27- if (err < 0)
28- warnx("Can't recovery from underrun, prepare failed: %s", snd_strerror(err));
29- return 0;
30- } else if (err == -ESTRPIPE) {
31- while ((err = snd_pcm_resume(handle)) == -EAGAIN)
32- sleep(1); /* wait until the suspend flag is released */
33- if (err < 0) {
34- err = snd_pcm_prepare(handle);
35- if (err < 0)
36- warnx("Can't recovery from suspend, prepare failed: %s", snd_strerror(err));
37- }
38- return 0;
39- }
40- return err;
41-}
42-
43-static void generate(struct ccdl *ccdl,
44- const snd_pcm_channel_area_t *areas,
45- snd_pcm_uframes_t offset,
46- int count, double *_phase)
47-{
48- double phase = *_phase;
49- double step = 1/(double)rate;
50- unsigned char *samples[channels];
51- int steps[channels];
52- unsigned int chn;
53- int format_bits = snd_pcm_format_width(format);
54- // unsigned int maxval = (1 << (format_bits - 1)) - 1;
55- int bps = format_bits / 8; /* bytes per sample */
56- int phys_bps = snd_pcm_format_physical_width(format) / 8;
57- int big_endian = snd_pcm_format_big_endian(format) == 1;
58- int to_unsigned = snd_pcm_format_unsigned(format) == 1;
59-
60- /* verify and prepare the contents of areas */
61- for (chn = 0; chn < channels; chn++) {
62- if ((areas[chn].first % 8) != 0) {
63- errx(1, "areas[%i].first == %i, aborting...", chn, areas[chn].first);
64- }
65- samples[chn] = /*(signed short *)*/(((unsigned char *)areas[chn].addr) + (areas[chn].first / 8));
66- if ((areas[chn].step % 16) != 0) {
67- errx(1, "areas[%i].step == %i, aborting...", chn, areas[chn].step);
68- }
69- steps[chn] = areas[chn].step / 8;
70- samples[chn] += offset * steps[chn];
71- }
72-
73- struct tune *tune = ccdl_get(ccdl);
74-
75- /* fill the channel areas */
76- while (count-- > 0) {
77- union {
78- float f;
79- int i;
80- } fval;
81- int res, i;
82- if (tune && tune->play) {
83- fval.f = tune->play(tune, phase);
84- } else {
85- fval.f = 0;
86- }
87- res = fval.i;
88- if (to_unsigned)
89- res ^= 1U << (format_bits - 1);
90- for (chn = 0; chn < channels; chn++) {
91- /* Generate data in native endian format */
92- if (big_endian) {
93- for (i = 0; i < bps; i++)
94- *(samples[chn] + phys_bps - 1 - i) = (res >> i * 8) & 0xff;
95- } else {
96- for (i = 0; i < bps; i++)
97- *(samples[chn] + i) = (res >> i * 8) & 0xff;
98- }
99- samples[chn] += steps[chn];
100- }
101- phase += step;
102- /*
103- if (phase >= max_phase)
104- phase -= max_phase;
105- */
106- }
107- *_phase = phase;
108-}
109-
110-
111-int main(int argc, char *argv[])
112-{
113- struct ccdl ccdl;
114- int err;
115- snd_pcm_t *pcm_out;
116- const char *src_fname = "tune.c";
117- const char *device_out = "default";
118-
119- if (argc > 1) src_fname = argv[1];
120- if (argc > 2) device_out = argv[2];
121-
122- ccdl_init(&ccdl, src_fname, "TUNE");
123-
124- if (ccdl_watch(&ccdl)) {
125- errx(1, "ccdl_watch");
126- }
127-
128- if ((err = snd_pcm_open(&pcm_out, device_out, SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
129- warnx("Playback open error: %s", snd_strerror(err));
130- return 1;
131- }
132-
133- if ((err = snd_pcm_set_params(pcm_out,
134- format,
135- SND_PCM_ACCESS_MMAP_INTERLEAVED,
136- channels,
137- rate,
138- 1,
139- latency)) < 0) {
140- warnx("Playback open error: %s", snd_strerror(err));
141- return 1;
142- }
143-
144- snd_pcm_uframes_t buffer_size;
145- snd_pcm_uframes_t period_size;
146- if ((err = snd_pcm_get_params(pcm_out, &buffer_size, &period_size)) < 0) {
147- warnx("Playback get params error: %s", snd_strerror(err));
148- return 1;
149- }
150-
151- double phase = 0;
152- const snd_pcm_channel_area_t *my_areas;
153- snd_pcm_uframes_t offset, frames, size;
154- snd_pcm_sframes_t avail, commitres;
155- snd_pcm_state_t state;
156- int first = 1;
157-
158- while (1) {
159- state = snd_pcm_state(pcm_out);
160- if (state == SND_PCM_STATE_XRUN) {
161- err = xrun_recovery(pcm_out, -EPIPE);
162- if (err < 0) {
163- printf("XRUN recovery failed: %s\n", snd_strerror(err));
164- return err;
165- }
166- first = 1;
167- } else if (state == SND_PCM_STATE_SUSPENDED) {
168- err = xrun_recovery(pcm_out, -ESTRPIPE);
169- if (err < 0) {
170- printf("SUSPEND recovery failed: %s\n", snd_strerror(err));
171- return err;
172- }
173- }
174- avail = snd_pcm_avail_update(pcm_out);
175- if (avail < 0) {
176- err = xrun_recovery(pcm_out, avail);
177- if (err < 0) {
178- printf("avail update failed: %s\n", snd_strerror(err));
179- return err;
180- }
181- first = 1;
182- continue;
183- }
184- if ((snd_pcm_uframes_t)avail < period_size) {
185- if (first) {
186- first = 0;
187- err = snd_pcm_start(pcm_out);
188- if (err < 0) {
189- printf("Start error: %s\n", snd_strerror(err));
190- exit(EXIT_FAILURE);
191- }
192- } else {
193- err = snd_pcm_wait(pcm_out, -1);
194- if (err < 0) {
195- if ((err = xrun_recovery(pcm_out, err)) < 0) {
196- printf("snd_pcm_wait error: %s\n", snd_strerror(err));
197- exit(EXIT_FAILURE);
198- }
199- first = 1;
200- }
201- }
202- continue;
203- }
204- size = period_size;
205- while (size > 0) {
206- frames = size;
207- err = snd_pcm_mmap_begin(pcm_out, &my_areas, &offset, &frames);
208- if (err < 0) {
209- if ((err = xrun_recovery(pcm_out, err)) < 0) {
210- printf("MMAP begin avail error: %s\n", snd_strerror(err));
211- exit(EXIT_FAILURE);
212- }
213- first = 1;
214- }
215- generate(&ccdl, my_areas, offset, frames, &phase);
216- // generate_sine(my_areas, offset, frames, &phase);
217- commitres = snd_pcm_mmap_commit(pcm_out, offset, frames);
218- if (commitres < 0 || (snd_pcm_uframes_t)commitres != frames) {
219- if ((err = xrun_recovery(pcm_out, commitres >= 0 ? -EPIPE : commitres)) < 0) {
220- printf("MMAP commit error: %s\n", snd_strerror(err));
221- exit(EXIT_FAILURE);
222- }
223- first = 1;
224- }
225- size -= frames;
226- }
227-
228- }
229-
230- snd_pcm_close(pcm_out);
231- return ccdl_deinit(&ccdl);
232-}
foostudio.cView
@@ -1,0 +1,232 @@
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 +static unsigned int rate = 44100;
15 +static unsigned int channels = 1;
16 +static unsigned int latency = 500000; /* ring buffer length in us */
17 +static snd_pcm_format_t format = SND_PCM_FORMAT_FLOAT;
18 +
19 +/*
20 + * Underrun and suspend recovery, from alsa-lib/test/pcm.c
21 + */
22 +
23 +static int xrun_recovery(snd_pcm_t *handle, int err)
24 +{
25 + if (err == -EPIPE) { /* under-run */
26 + err = snd_pcm_prepare(handle);
27 + if (err < 0)
28 + warnx("Can't recovery from underrun, prepare failed: %s", snd_strerror(err));
29 + return 0;
30 + } else if (err == -ESTRPIPE) {
31 + while ((err = snd_pcm_resume(handle)) == -EAGAIN)
32 + sleep(1); /* wait until the suspend flag is released */
33 + if (err < 0) {
34 + err = snd_pcm_prepare(handle);
35 + if (err < 0)
36 + warnx("Can't recovery from suspend, prepare failed: %s", snd_strerror(err));
37 + }
38 + return 0;
39 + }
40 + return err;
41 +}
42 +
43 +static void generate(struct ccdl *ccdl,
44 + const snd_pcm_channel_area_t *areas,
45 + snd_pcm_uframes_t offset,
46 + int count, double *_phase)
47 +{
48 + double phase = *_phase;
49 + double step = 1/(double)rate;
50 + unsigned char *samples[channels];
51 + int steps[channels];
52 + unsigned int chn;
53 + int format_bits = snd_pcm_format_width(format);
54 + // unsigned int maxval = (1 << (format_bits - 1)) - 1;
55 + int bps = format_bits / 8; /* bytes per sample */
56 + int phys_bps = snd_pcm_format_physical_width(format) / 8;
57 + int big_endian = snd_pcm_format_big_endian(format) == 1;
58 + int to_unsigned = snd_pcm_format_unsigned(format) == 1;
59 +
60 + /* verify and prepare the contents of areas */
61 + for (chn = 0; chn < channels; chn++) {
62 + if ((areas[chn].first % 8) != 0) {
63 + errx(1, "areas[%i].first == %i, aborting...", chn, areas[chn].first);
64 + }
65 + samples[chn] = /*(signed short *)*/(((unsigned char *)areas[chn].addr) + (areas[chn].first / 8));
66 + if ((areas[chn].step % 16) != 0) {
67 + errx(1, "areas[%i].step == %i, aborting...", chn, areas[chn].step);
68 + }
69 + steps[chn] = areas[chn].step / 8;
70 + samples[chn] += offset * steps[chn];
71 + }
72 +
73 + struct tune *tune = ccdl_get(ccdl);
74 +
75 + /* fill the channel areas */
76 + while (count-- > 0) {
77 + union {
78 + float f;
79 + int i;
80 + } fval;
81 + int res, i;
82 + if (tune && tune->play) {
83 + fval.f = tune->play(tune, phase);
84 + } else {
85 + fval.f = 0;
86 + }
87 + res = fval.i;
88 + if (to_unsigned)
89 + res ^= 1U << (format_bits - 1);
90 + for (chn = 0; chn < channels; chn++) {
91 + /* Generate data in native endian format */
92 + if (big_endian) {
93 + for (i = 0; i < bps; i++)
94 + *(samples[chn] + phys_bps - 1 - i) = (res >> i * 8) & 0xff;
95 + } else {
96 + for (i = 0; i < bps; i++)
97 + *(samples[chn] + i) = (res >> i * 8) & 0xff;
98 + }
99 + samples[chn] += steps[chn];
100 + }
101 + phase += step;
102 + /*
103 + if (phase >= max_phase)
104 + phase -= max_phase;
105 + */
106 + }
107 + *_phase = phase;
108 +}
109 +
110 +
111 +int main(int argc, char *argv[])
112 +{
113 + struct ccdl ccdl;
114 + int err;
115 + snd_pcm_t *pcm_out;
116 + const char *src_fname = "tune.c";
117 + const char *device_out = "default";
118 +
119 + if (argc > 1) src_fname = argv[1];
120 + if (argc > 2) device_out = argv[2];
121 +
122 + ccdl_init(&ccdl, src_fname, "TUNE");
123 +
124 + if (ccdl_watch(&ccdl)) {
125 + errx(1, "ccdl_watch");
126 + }
127 +
128 + if ((err = snd_pcm_open(&pcm_out, device_out, SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
129 + warnx("Playback open error: %s", snd_strerror(err));
130 + return 1;
131 + }
132 +
133 + if ((err = snd_pcm_set_params(pcm_out,
134 + format,
135 + SND_PCM_ACCESS_MMAP_INTERLEAVED,
136 + channels,
137 + rate,
138 + 1,
139 + latency)) < 0) {
140 + warnx("Playback open error: %s", snd_strerror(err));
141 + return 1;
142 + }
143 +
144 + snd_pcm_uframes_t buffer_size;
145 + snd_pcm_uframes_t period_size;
146 + if ((err = snd_pcm_get_params(pcm_out, &buffer_size, &period_size)) < 0) {
147 + warnx("Playback get params error: %s", snd_strerror(err));
148 + return 1;
149 + }
150 +
151 + double phase = 0;
152 + const snd_pcm_channel_area_t *my_areas;
153 + snd_pcm_uframes_t offset, frames, size;
154 + snd_pcm_sframes_t avail, commitres;
155 + snd_pcm_state_t state;
156 + int first = 1;
157 +
158 + while (1) {
159 + state = snd_pcm_state(pcm_out);
160 + if (state == SND_PCM_STATE_XRUN) {
161 + err = xrun_recovery(pcm_out, -EPIPE);
162 + if (err < 0) {
163 + printf("XRUN recovery failed: %s\n", snd_strerror(err));
164 + return err;
165 + }
166 + first = 1;
167 + } else if (state == SND_PCM_STATE_SUSPENDED) {
168 + err = xrun_recovery(pcm_out, -ESTRPIPE);
169 + if (err < 0) {
170 + printf("SUSPEND recovery failed: %s\n", snd_strerror(err));
171 + return err;
172 + }
173 + }
174 + avail = snd_pcm_avail_update(pcm_out);
175 + if (avail < 0) {
176 + err = xrun_recovery(pcm_out, avail);
177 + if (err < 0) {
178 + printf("avail update failed: %s\n", snd_strerror(err));
179 + return err;
180 + }
181 + first = 1;
182 + continue;
183 + }
184 + if ((snd_pcm_uframes_t)avail < period_size) {
185 + if (first) {
186 + first = 0;
187 + err = snd_pcm_start(pcm_out);
188 + if (err < 0) {
189 + printf("Start error: %s\n", snd_strerror(err));
190 + exit(EXIT_FAILURE);
191 + }
192 + } else {
193 + err = snd_pcm_wait(pcm_out, -1);
194 + if (err < 0) {
195 + if ((err = xrun_recovery(pcm_out, err)) < 0) {
196 + printf("snd_pcm_wait error: %s\n", snd_strerror(err));
197 + exit(EXIT_FAILURE);
198 + }
199 + first = 1;
200 + }
201 + }
202 + continue;
203 + }
204 + size = period_size;
205 + while (size > 0) {
206 + frames = size;
207 + err = snd_pcm_mmap_begin(pcm_out, &my_areas, &offset, &frames);
208 + if (err < 0) {
209 + if ((err = xrun_recovery(pcm_out, err)) < 0) {
210 + printf("MMAP begin avail error: %s\n", snd_strerror(err));
211 + exit(EXIT_FAILURE);
212 + }
213 + first = 1;
214 + }
215 + generate(&ccdl, my_areas, offset, frames, &phase);
216 + // generate_sine(my_areas, offset, frames, &phase);
217 + commitres = snd_pcm_mmap_commit(pcm_out, offset, frames);
218 + if (commitres < 0 || (snd_pcm_uframes_t)commitres != frames) {
219 + if ((err = xrun_recovery(pcm_out, commitres >= 0 ? -EPIPE : commitres)) < 0) {
220 + printf("MMAP commit error: %s\n", snd_strerror(err));
221 + exit(EXIT_FAILURE);
222 + }
223 + first = 1;
224 + }
225 + size -= frames;
226 + }
227 +
228 + }
229 +
230 + snd_pcm_close(pcm_out);
231 + return ccdl_deinit(&ccdl);
232 +}

Built with git-ssb-web