A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita
audio
rust
zig
deno
mpris
rockbox
mpd
1/* Copyright (c) 1997-1999 Miller Puckette.
2* For information on usage and redistribution, and for a DISCLAIMER OF ALL
3* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
4
5/* The dac~ and adc~ routines.
6*/
7
8#include "m_pd.h"
9#include "s_stuff.h"
10
11/* ----------------------------- dac~ --------------------------- */
12static t_class *dac_class;
13
14typedef struct _dac
15{
16 t_object x_obj;
17 t_int x_n;
18 t_int *x_vec;
19 float x_f;
20} t_dac;
21
22static void *dac_new(t_symbol *s, int argc, t_atom *argv)
23{
24 t_dac *x = (t_dac *)pd_new(dac_class);
25#ifdef ROCKBOX
26 t_atom defarg[2];
27#else
28 t_atom defarg[2], *ap;
29#endif
30 int i;
31
32#ifdef ROCKBOX
33 (void) s;
34#endif
35
36 if (!argc)
37 {
38 argv = defarg;
39 argc = 2;
40 SETFLOAT(&defarg[0], 1);
41 SETFLOAT(&defarg[1], 2);
42 }
43 x->x_n = argc;
44 x->x_vec = (t_int *)getbytes(argc * sizeof(*x->x_vec));
45 for (i = 0; i < argc; i++)
46 x->x_vec[i] = atom_getintarg(i, argc, argv);
47 for (i = 1; i < argc; i++)
48 inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
49 x->x_f = 0;
50 return (x);
51}
52
53static void dac_dsp(t_dac *x, t_signal **sp)
54{
55 t_int i, *ip;
56 t_signal **sp2;
57 for (i = x->x_n, ip = x->x_vec, sp2 = sp; i--; ip++, sp2++)
58 {
59 int ch = *ip - 1;
60 if ((*sp2)->s_n != DEFDACBLKSIZE)
61 error("dac~: bad vector size");
62 else if (ch >= 0 && ch < sys_get_outchannels())
63 dsp_add(plus_perform, 4, sys_soundout + DEFDACBLKSIZE*ch,
64 (*sp2)->s_vec, sys_soundout + DEFDACBLKSIZE*ch, DEFDACBLKSIZE);
65 }
66}
67
68static void dac_free(t_dac *x)
69{
70 freebytes(x->x_vec, x->x_n * sizeof(*x->x_vec));
71}
72
73static void dac_setup(void)
74{
75 dac_class = class_new(gensym("dac~"), (t_newmethod)dac_new,
76 (t_method)dac_free, sizeof(t_dac), 0, A_GIMME, 0);
77 CLASS_MAINSIGNALIN(dac_class, t_dac, x_f);
78 class_addmethod(dac_class, (t_method)dac_dsp, gensym("dsp"), A_CANT, 0);
79 class_sethelpsymbol(dac_class, gensym("adc~_dac~"));
80}
81
82/* ----------------------------- adc~ --------------------------- */
83static t_class *adc_class;
84
85typedef struct _adc
86{
87 t_object x_obj;
88 t_int x_n;
89 t_int *x_vec;
90} t_adc;
91
92static void *adc_new(t_symbol *s, int argc, t_atom *argv)
93{
94 t_adc *x = (t_adc *)pd_new(adc_class);
95#ifdef ROCKBOX
96 t_atom defarg[2];
97#else
98 t_atom defarg[2], *ap;
99#endif
100 int i;
101
102#ifdef ROCKBOX
103 (void) s;
104#endif
105
106 if (!argc)
107 {
108 argv = defarg;
109 argc = 2;
110 SETFLOAT(&defarg[0], 1);
111 SETFLOAT(&defarg[1], 2);
112 }
113 x->x_n = argc;
114 x->x_vec = (t_int *)getbytes(argc * sizeof(*x->x_vec));
115 for (i = 0; i < argc; i++)
116 x->x_vec[i] = atom_getintarg(i, argc, argv);
117 for (i = 0; i < argc; i++)
118 outlet_new(&x->x_obj, &s_signal);
119 return (x);
120}
121
122t_int *copy_perform(t_int *w)
123{
124 t_float *in1 = (t_float *)(w[1]);
125 t_float *out = (t_float *)(w[2]);
126 int n = (int)(w[3]);
127 while (n--) *out++ = *in1++;
128 return (w+4);
129}
130
131t_int *copy_perf8(t_int *w)
132{
133 t_float *in1 = (t_float *)(w[1]);
134 t_float *out = (t_float *)(w[2]);
135 int n = (int)(w[3]);
136
137 for (; n; n -= 8, in1 += 8, out += 8)
138 {
139 float f0 = in1[0];
140 float f1 = in1[1];
141 float f2 = in1[2];
142 float f3 = in1[3];
143 float f4 = in1[4];
144 float f5 = in1[5];
145 float f6 = in1[6];
146 float f7 = in1[7];
147
148 out[0] = f0;
149 out[1] = f1;
150 out[2] = f2;
151 out[3] = f3;
152 out[4] = f4;
153 out[5] = f5;
154 out[6] = f6;
155 out[7] = f7;
156 }
157 return (w+4);
158}
159
160void dsp_add_copy(t_sample *in, t_sample *out, int n)
161{
162 if (n&7)
163 dsp_add(copy_perform, 3, in, out, n);
164 else
165 dsp_add(copy_perf8, 3, in, out, n);
166}
167
168static void adc_dsp(t_adc *x, t_signal **sp)
169{
170 t_int i, *ip;
171 t_signal **sp2;
172 for (i = x->x_n, ip = x->x_vec, sp2 = sp; i--; ip++, sp2++)
173 {
174 int ch = *ip - 1;
175 if ((*sp2)->s_n != DEFDACBLKSIZE)
176 error("adc~: bad vector size");
177 else if (ch >= 0 && ch < sys_get_inchannels())
178 dsp_add_copy(sys_soundin + DEFDACBLKSIZE*ch,
179 (*sp2)->s_vec, DEFDACBLKSIZE);
180 else dsp_add_zero((*sp2)->s_vec, DEFDACBLKSIZE);
181 }
182}
183
184static void adc_free(t_adc *x)
185{
186 freebytes(x->x_vec, x->x_n * sizeof(*x->x_vec));
187}
188
189static void adc_setup(void)
190{
191 adc_class = class_new(gensym("adc~"), (t_newmethod)adc_new,
192 (t_method)adc_free, sizeof(t_adc), 0, A_GIMME, 0);
193 class_addmethod(adc_class, (t_method)adc_dsp, gensym("dsp"), A_CANT, 0);
194 class_sethelpsymbol(adc_class, gensym("adc~_dac~"));
195}
196
197void d_dac_setup(void)
198{
199 dac_setup();
200 adc_setup();
201}
202