1 #include "stdio.h"
2 #ifndef mips
3 #include "stdlib.h"
4 #endif
5 #include "xlisp.h"
6 #include "sound.h"
7
8 #include "falloc.h"
9 #include "cext.h"
10 #include "aresoncv.h"
11
12 void aresoncv_free(snd_susp_type a_susp);
13
14
15 typedef struct aresoncv_susp_struct {
16 snd_susp_node susp;
17 boolean started;
18 int64_t terminate_cnt;
19 boolean logically_stopped;
20 sound_type s1;
21 int s1_cnt;
22 sample_block_values_type s1_ptr;
23 sound_type bw;
24 int bw_cnt;
25 sample_block_values_type bw_ptr;
26
27 /* support for interpolation of bw */
28 sample_type bw_x1_sample;
29 double bw_pHaSe;
30 double bw_pHaSe_iNcR;
31
32 /* support for ramp between samples of bw */
33 double output_per_bw;
34 int64_t bw_n;
35
36 double c3co;
37 double coshz;
38 double c2;
39 double c1;
40 int normalization;
41 double y1;
42 double y2;
43 } aresoncv_susp_node, *aresoncv_susp_type;
44
45
aresoncv_ns_fetch(snd_susp_type a_susp,snd_list_type snd_list)46 void aresoncv_ns_fetch(snd_susp_type a_susp, snd_list_type snd_list)
47 {
48 aresoncv_susp_type susp = (aresoncv_susp_type) a_susp;
49 int cnt = 0; /* how many samples computed */
50 int togo;
51 int n;
52 sample_block_type out;
53 register sample_block_values_type out_ptr;
54
55 register sample_block_values_type out_ptr_reg;
56
57 register double c3co_reg;
58 register double coshz_reg;
59 register double c2_reg;
60 register double c1_reg;
61 register int normalization_reg;
62 register double y1_reg;
63 register double y2_reg;
64 register sample_type bw_scale_reg = susp->bw->scale;
65 register sample_block_values_type bw_ptr_reg;
66 register sample_block_values_type s1_ptr_reg;
67 falloc_sample_block(out, "aresoncv_ns_fetch");
68 out_ptr = out->samples;
69 snd_list->block = out;
70
71 while (cnt < max_sample_block_len) { /* outer loop */
72 /* first compute how many samples to generate in inner loop: */
73 /* don't overflow the output sample block: */
74 togo = max_sample_block_len - cnt;
75
76 /* don't run past the s1 input sample block: */
77 susp_check_term_log_samples(s1, s1_ptr, s1_cnt);
78 togo = min(togo, susp->s1_cnt);
79
80 /* don't run past the bw input sample block: */
81 susp_check_term_samples(bw, bw_ptr, bw_cnt);
82 togo = min(togo, susp->bw_cnt);
83
84 /* don't run past terminate time */
85 if (susp->terminate_cnt != UNKNOWN &&
86 susp->terminate_cnt <= susp->susp.current + cnt + togo) {
87 togo = (int) (susp->terminate_cnt - (susp->susp.current + cnt));
88 if (togo < 0) togo = 0; /* avoids rounding errros */
89 if (togo == 0) break;
90 }
91
92
93 /* don't run past logical stop time */
94 if (!susp->logically_stopped && susp->susp.log_stop_cnt != UNKNOWN) {
95 int64_t to_stop = susp->susp.log_stop_cnt - (susp->susp.current + cnt);
96 /* break if to_stop == 0 (we're at the logical stop)
97 * AND cnt > 0 (we're not at the beginning of the
98 * output block).
99 */
100 if (to_stop < 0) to_stop = 0; /* avoids rounding errors */
101 if (to_stop < togo) {
102 if (to_stop == 0) {
103 if (cnt) {
104 togo = 0;
105 break;
106 } else /* keep togo as is: since cnt == 0, we
107 * can set the logical stop flag on this
108 * output block
109 */
110 susp->logically_stopped = true;
111 } else /* limit togo so we can start a new
112 * block at the LST
113 */
114 togo = (int) to_stop;
115 }
116 }
117
118 n = togo;
119 c3co_reg = susp->c3co;
120 coshz_reg = susp->coshz;
121 c2_reg = susp->c2;
122 c1_reg = susp->c1;
123 normalization_reg = susp->normalization;
124 y1_reg = susp->y1;
125 y2_reg = susp->y2;
126 bw_ptr_reg = susp->bw_ptr;
127 s1_ptr_reg = susp->s1_ptr;
128 out_ptr_reg = out_ptr;
129 if (n) do { /* the inner sample computation loop */
130 register double y0, current;
131 double c3p1;
132 double c3t4;
133 double omc3;
134 c3co_reg = exp((bw_scale_reg * *bw_ptr_reg++));
135 c3p1 = c3co_reg + 1.0;
136 c3t4 = c3co_reg * 4.0;
137 omc3 = 1.0 - c3co_reg;
138 c2_reg = c3t4 * coshz_reg / c3p1;
139 c1_reg = (normalization_reg == 0 ? 0.0 :
140 (normalization_reg == 1 ? 1.0 - omc3 * sqrt(1.0 - c2_reg * c2_reg / c3t4) :
141 1.0 - sqrt(c3p1 * c3p1 - c2_reg * c2_reg) * omc3 / c3p1));
142 current = *s1_ptr_reg++;
143 *out_ptr_reg++ = (float) (y0 = c1_reg * current + c2_reg * y1_reg - c3co_reg * y2_reg);
144 y2_reg = y1_reg; y1_reg = y0 - current;
145 } while (--n); /* inner loop */
146
147 susp->y1 = y1_reg;
148 susp->y2 = y2_reg;
149 /* using bw_ptr_reg is a bad idea on RS/6000: */
150 susp->bw_ptr += togo;
151 /* using s1_ptr_reg is a bad idea on RS/6000: */
152 susp->s1_ptr += togo;
153 out_ptr += togo;
154 susp_took(s1_cnt, togo);
155 susp_took(bw_cnt, togo);
156 cnt += togo;
157 } /* outer loop */
158
159 /* test for termination */
160 if (togo == 0 && cnt == 0) {
161 snd_list_terminate(snd_list);
162 } else {
163 snd_list->block_len = cnt;
164 susp->susp.current += cnt;
165 }
166 /* test for logical stop */
167 if (susp->logically_stopped) {
168 snd_list->logically_stopped = true;
169 } else if (susp->susp.log_stop_cnt == susp->susp.current) {
170 susp->logically_stopped = true;
171 }
172 } /* aresoncv_ns_fetch */
173
174
aresoncv_ni_fetch(snd_susp_type a_susp,snd_list_type snd_list)175 void aresoncv_ni_fetch(snd_susp_type a_susp, snd_list_type snd_list)
176 {
177 aresoncv_susp_type susp = (aresoncv_susp_type) a_susp;
178 int cnt = 0; /* how many samples computed */
179 int togo;
180 int n;
181 sample_block_type out;
182 register sample_block_values_type out_ptr;
183
184 register sample_block_values_type out_ptr_reg;
185
186 register double c3co_reg;
187 register double coshz_reg;
188 register double c2_reg;
189 register double c1_reg;
190 register int normalization_reg;
191 register double y1_reg;
192 register double y2_reg;
193 register double bw_pHaSe_iNcR_rEg = susp->bw_pHaSe_iNcR;
194 register double bw_pHaSe_ReG;
195 register sample_type bw_x1_sample_reg;
196 register sample_block_values_type s1_ptr_reg;
197 falloc_sample_block(out, "aresoncv_ni_fetch");
198 out_ptr = out->samples;
199 snd_list->block = out;
200
201 /* make sure sounds are primed with first values */
202 if (!susp->started) {
203 double c3p1;
204 double c3t4;
205 double omc3;
206 susp->started = true;
207 susp_check_term_samples(bw, bw_ptr, bw_cnt);
208 susp->bw_x1_sample = susp_fetch_sample(bw, bw_ptr, bw_cnt);
209 susp->c3co = exp(susp->bw_x1_sample);
210 c3p1 = susp->c3co + 1.0;
211 c3t4 = susp->c3co * 4.0;
212 omc3 = 1.0 - susp->c3co;
213 susp->c2 = c3t4 * susp->coshz / c3p1;
214 susp->c1 = (susp->normalization == 0 ? 0.0 :
215 (susp->normalization == 1 ? 1.0 - omc3 * sqrt(1.0 - susp->c2 * susp->c2 / c3t4) :
216 1.0 - sqrt(c3p1 * c3p1 - susp->c2 * susp->c2) * omc3 / c3p1));
217 }
218
219 while (cnt < max_sample_block_len) { /* outer loop */
220 /* first compute how many samples to generate in inner loop: */
221 /* don't overflow the output sample block: */
222 togo = max_sample_block_len - cnt;
223
224 /* don't run past the s1 input sample block: */
225 susp_check_term_log_samples(s1, s1_ptr, s1_cnt);
226 togo = min(togo, susp->s1_cnt);
227
228 /* don't run past terminate time */
229 if (susp->terminate_cnt != UNKNOWN &&
230 susp->terminate_cnt <= susp->susp.current + cnt + togo) {
231 togo = (int) (susp->terminate_cnt - (susp->susp.current + cnt));
232 if (togo < 0) togo = 0; /* avoids rounding errros */
233 if (togo == 0) break;
234 }
235
236
237 /* don't run past logical stop time */
238 if (!susp->logically_stopped && susp->susp.log_stop_cnt != UNKNOWN) {
239 int64_t to_stop = susp->susp.log_stop_cnt - (susp->susp.current + cnt);
240 /* break if to_stop == 0 (we're at the logical stop)
241 * AND cnt > 0 (we're not at the beginning of the
242 * output block).
243 */
244 if (to_stop < 0) to_stop = 0; /* avoids rounding errors */
245 if (to_stop < togo) {
246 if (to_stop == 0) {
247 if (cnt) {
248 togo = 0;
249 break;
250 } else /* keep togo as is: since cnt == 0, we
251 * can set the logical stop flag on this
252 * output block
253 */
254 susp->logically_stopped = true;
255 } else /* limit togo so we can start a new
256 * block at the LST
257 */
258 togo = (int) to_stop;
259 }
260 }
261
262 n = togo;
263 c3co_reg = susp->c3co;
264 coshz_reg = susp->coshz;
265 c2_reg = susp->c2;
266 c1_reg = susp->c1;
267 normalization_reg = susp->normalization;
268 y1_reg = susp->y1;
269 y2_reg = susp->y2;
270 bw_pHaSe_ReG = susp->bw_pHaSe;
271 bw_x1_sample_reg = susp->bw_x1_sample;
272 s1_ptr_reg = susp->s1_ptr;
273 out_ptr_reg = out_ptr;
274 if (n) do { /* the inner sample computation loop */
275 register double y0, current;
276 if (bw_pHaSe_ReG >= 1.0) {
277 /* fixup-depends bw */
278 double c3p1;
279 double c3t4;
280 double omc3;
281 /* pick up next sample as bw_x1_sample: */
282 susp->bw_ptr++;
283 susp_took(bw_cnt, 1);
284 bw_pHaSe_ReG -= 1.0;
285 susp_check_term_samples_break(bw, bw_ptr, bw_cnt, bw_x1_sample_reg);
286 bw_x1_sample_reg = susp_current_sample(bw, bw_ptr);
287 c3co_reg = exp(bw_x1_sample_reg);
288 c3p1 = c3co_reg + 1.0;
289 c3t4 = c3co_reg * 4.0;
290 omc3 = 1.0 - c3co_reg;
291 c2_reg = c3t4 * coshz_reg / c3p1;
292 c1_reg = (normalization_reg == 0 ? 0.0 :
293 (normalization_reg == 1 ? 1.0 - omc3 * sqrt(1.0 - c2_reg * c2_reg / c3t4) :
294 1.0 - sqrt(c3p1 * c3p1 - c2_reg * c2_reg) * omc3 / c3p1));
295 }
296 current = *s1_ptr_reg++;
297 *out_ptr_reg++ = (float) (y0 = c1_reg * current + c2_reg * y1_reg - c3co_reg * y2_reg);
298 y2_reg = y1_reg; y1_reg = y0 - current;
299 bw_pHaSe_ReG += bw_pHaSe_iNcR_rEg;
300 } while (--n); /* inner loop */
301
302 togo -= n;
303 susp->y1 = y1_reg;
304 susp->y2 = y2_reg;
305 susp->bw_pHaSe = bw_pHaSe_ReG;
306 susp->bw_x1_sample = bw_x1_sample_reg;
307 /* using s1_ptr_reg is a bad idea on RS/6000: */
308 susp->s1_ptr += togo;
309 out_ptr += togo;
310 susp_took(s1_cnt, togo);
311 cnt += togo;
312 } /* outer loop */
313
314 /* test for termination */
315 if (togo == 0 && cnt == 0) {
316 snd_list_terminate(snd_list);
317 } else {
318 snd_list->block_len = cnt;
319 susp->susp.current += cnt;
320 }
321 /* test for logical stop */
322 if (susp->logically_stopped) {
323 snd_list->logically_stopped = true;
324 } else if (susp->susp.log_stop_cnt == susp->susp.current) {
325 susp->logically_stopped = true;
326 }
327 } /* aresoncv_ni_fetch */
328
329
aresoncv_nr_fetch(snd_susp_type a_susp,snd_list_type snd_list)330 void aresoncv_nr_fetch(snd_susp_type a_susp, snd_list_type snd_list)
331 {
332 aresoncv_susp_type susp = (aresoncv_susp_type) a_susp;
333 int cnt = 0; /* how many samples computed */
334 sample_type bw_val;
335 int togo;
336 int n;
337 sample_block_type out;
338 register sample_block_values_type out_ptr;
339
340 register sample_block_values_type out_ptr_reg;
341
342 register double c3co_reg;
343 register double coshz_reg;
344 register double c2_reg;
345 register double c1_reg;
346 register int normalization_reg;
347 register double y1_reg;
348 register double y2_reg;
349 register sample_block_values_type s1_ptr_reg;
350 falloc_sample_block(out, "aresoncv_nr_fetch");
351 out_ptr = out->samples;
352 snd_list->block = out;
353
354 /* make sure sounds are primed with first values */
355 if (!susp->started) {
356 susp->started = true;
357 susp->bw_pHaSe = 1.0;
358 }
359
360 susp_check_term_samples(bw, bw_ptr, bw_cnt);
361
362 while (cnt < max_sample_block_len) { /* outer loop */
363 /* first compute how many samples to generate in inner loop: */
364 /* don't overflow the output sample block: */
365 togo = max_sample_block_len - cnt;
366
367 /* don't run past the s1 input sample block: */
368 susp_check_term_log_samples(s1, s1_ptr, s1_cnt);
369 togo = min(togo, susp->s1_cnt);
370
371 /* grab next bw_x1_sample when phase goes past 1.0; */
372 /* use bw_n (computed below) to avoid roundoff errors: */
373 if (susp->bw_n <= 0) {
374 double c3p1;
375 double c3t4;
376 double omc3;
377 susp_check_term_samples(bw, bw_ptr, bw_cnt);
378 susp->bw_x1_sample = susp_fetch_sample(bw, bw_ptr, bw_cnt);
379 susp->bw_pHaSe -= 1.0;
380 /* bw_n gets number of samples before phase exceeds 1.0: */
381 susp->bw_n = (int64_t) ((1.0 - susp->bw_pHaSe) *
382 susp->output_per_bw);
383 susp->c3co = exp(susp->bw_x1_sample);
384 c3p1 = susp->c3co + 1.0;
385 c3t4 = susp->c3co * 4.0;
386 omc3 = 1.0 - susp->c3co;
387 susp->c2 = c3t4 * susp->coshz / c3p1;
388 susp->c1 = (susp->normalization == 0 ? 0.0 :
389 (susp->normalization == 1 ? 1.0 - omc3 * sqrt(1.0 - susp->c2 * susp->c2 / c3t4) :
390 1.0 - sqrt(c3p1 * c3p1 - susp->c2 * susp->c2) * omc3 / c3p1));
391 }
392 togo = (int) min(togo, susp->bw_n);
393 bw_val = susp->bw_x1_sample;
394 /* don't run past terminate time */
395 if (susp->terminate_cnt != UNKNOWN &&
396 susp->terminate_cnt <= susp->susp.current + cnt + togo) {
397 togo = (int) (susp->terminate_cnt - (susp->susp.current + cnt));
398 if (togo < 0) togo = 0; /* avoids rounding errros */
399 if (togo == 0) break;
400 }
401
402
403 /* don't run past logical stop time */
404 if (!susp->logically_stopped && susp->susp.log_stop_cnt != UNKNOWN) {
405 int64_t to_stop = susp->susp.log_stop_cnt - (susp->susp.current + cnt);
406 /* break if to_stop == 0 (we're at the logical stop)
407 * AND cnt > 0 (we're not at the beginning of the
408 * output block).
409 */
410 if (to_stop < 0) to_stop = 0; /* avoids rounding errors */
411 if (to_stop < togo) {
412 if (to_stop == 0) {
413 if (cnt) {
414 togo = 0;
415 break;
416 } else /* keep togo as is: since cnt == 0, we
417 * can set the logical stop flag on this
418 * output block
419 */
420 susp->logically_stopped = true;
421 } else /* limit togo so we can start a new
422 * block at the LST
423 */
424 togo = (int) to_stop;
425 }
426 }
427
428 n = togo;
429 c3co_reg = susp->c3co;
430 coshz_reg = susp->coshz;
431 c2_reg = susp->c2;
432 c1_reg = susp->c1;
433 normalization_reg = susp->normalization;
434 y1_reg = susp->y1;
435 y2_reg = susp->y2;
436 s1_ptr_reg = susp->s1_ptr;
437 out_ptr_reg = out_ptr;
438 if (n) do { /* the inner sample computation loop */
439 register double y0, current;
440 current = *s1_ptr_reg++;
441 *out_ptr_reg++ = (float) (y0 = c1_reg * current + c2_reg * y1_reg - c3co_reg * y2_reg);
442 y2_reg = y1_reg; y1_reg = y0 - current;
443 } while (--n); /* inner loop */
444
445 susp->y1 = y1_reg;
446 susp->y2 = y2_reg;
447 /* using s1_ptr_reg is a bad idea on RS/6000: */
448 susp->s1_ptr += togo;
449 out_ptr += togo;
450 susp_took(s1_cnt, togo);
451 susp->bw_pHaSe += togo * susp->bw_pHaSe_iNcR;
452 susp->bw_n -= togo;
453 cnt += togo;
454 } /* outer loop */
455
456 /* test for termination */
457 if (togo == 0 && cnt == 0) {
458 snd_list_terminate(snd_list);
459 } else {
460 snd_list->block_len = cnt;
461 susp->susp.current += cnt;
462 }
463 /* test for logical stop */
464 if (susp->logically_stopped) {
465 snd_list->logically_stopped = true;
466 } else if (susp->susp.log_stop_cnt == susp->susp.current) {
467 susp->logically_stopped = true;
468 }
469 } /* aresoncv_nr_fetch */
470
471
aresoncv_toss_fetch(snd_susp_type a_susp,snd_list_type snd_list)472 void aresoncv_toss_fetch(snd_susp_type a_susp, snd_list_type snd_list)
473 {
474 aresoncv_susp_type susp = (aresoncv_susp_type) a_susp;
475 time_type final_time = susp->susp.t0;
476 int n;
477
478 /* fetch samples from s1 up to final_time for this block of zeros */
479 while ((ROUNDBIG((final_time - susp->s1->t0) * susp->s1->sr)) >=
480 susp->s1->current)
481 susp_get_samples(s1, s1_ptr, s1_cnt);
482 /* fetch samples from bw up to final_time for this block of zeros */
483 while ((ROUNDBIG((final_time - susp->bw->t0) * susp->bw->sr)) >=
484 susp->bw->current)
485 susp_get_samples(bw, bw_ptr, bw_cnt);
486 /* convert to normal processing when we hit final_count */
487 /* we want each signal positioned at final_time */
488 n = (int) ROUNDBIG((final_time - susp->s1->t0) * susp->s1->sr -
489 (susp->s1->current - susp->s1_cnt));
490 susp->s1_ptr += n;
491 susp_took(s1_cnt, n);
492 n = (int) ROUNDBIG((final_time - susp->bw->t0) * susp->bw->sr -
493 (susp->bw->current - susp->bw_cnt));
494 susp->bw_ptr += n;
495 susp_took(bw_cnt, n);
496 susp->susp.fetch = susp->susp.keep_fetch;
497 (*(susp->susp.fetch))(a_susp, snd_list);
498 }
499
500
aresoncv_mark(snd_susp_type a_susp)501 void aresoncv_mark(snd_susp_type a_susp)
502 {
503 aresoncv_susp_type susp = (aresoncv_susp_type) a_susp;
504 sound_xlmark(susp->s1);
505 sound_xlmark(susp->bw);
506 }
507
508
aresoncv_free(snd_susp_type a_susp)509 void aresoncv_free(snd_susp_type a_susp)
510 {
511 aresoncv_susp_type susp = (aresoncv_susp_type) a_susp;
512 sound_unref(susp->s1);
513 sound_unref(susp->bw);
514 ffree_generic(susp, sizeof(aresoncv_susp_node), "aresoncv_free");
515 }
516
517
aresoncv_print_tree(snd_susp_type a_susp,int n)518 void aresoncv_print_tree(snd_susp_type a_susp, int n)
519 {
520 aresoncv_susp_type susp = (aresoncv_susp_type) a_susp;
521 indent(n);
522 stdputstr("s1:");
523 sound_print_tree_1(susp->s1, n);
524
525 indent(n);
526 stdputstr("bw:");
527 sound_print_tree_1(susp->bw, n);
528 }
529
530
snd_make_aresoncv(sound_type s1,double hz,sound_type bw,int normalization)531 sound_type snd_make_aresoncv(sound_type s1, double hz, sound_type bw, int normalization)
532 {
533 register aresoncv_susp_type susp;
534 rate_type sr = s1->sr;
535 time_type t0 = max(s1->t0, bw->t0);
536 int interp_desc = 0;
537 sample_type scale_factor = 1.0F;
538 time_type t0_min = t0;
539 /* combine scale factors of linear inputs (S1) */
540 scale_factor *= s1->scale;
541 s1->scale = 1.0F;
542
543 /* try to push scale_factor back to a low sr input */
544 if (s1->sr < sr) { s1->scale = scale_factor; scale_factor = 1.0F; }
545
546 falloc_generic(susp, aresoncv_susp_node, "snd_make_aresoncv");
547 susp->c3co = 0.0;
548 susp->coshz = cos(hz * PI2 / s1->sr);
549 susp->c2 = 0.0;
550 susp->c1 = 0.0;
551 susp->normalization = normalization;
552 susp->y1 = 0.0;
553 susp->y2 = 0.0;
554 bw->scale = (float) (bw->scale * (-PI2 / s1->sr));
555
556 /* make sure no sample rate is too high */
557 if (bw->sr > sr) {
558 sound_unref(bw);
559 snd_badsr();
560 }
561
562 /* select a susp fn based on sample rates */
563 interp_desc = (interp_desc << 2) + interp_style(s1, sr);
564 interp_desc = (interp_desc << 2) + interp_style(bw, sr);
565 switch (interp_desc) {
566 case INTERP_nn: /* handled below */
567 case INTERP_ns: susp->susp.fetch = aresoncv_ns_fetch; break;
568 case INTERP_ni: susp->susp.fetch = aresoncv_ni_fetch; break;
569 case INTERP_nr: susp->susp.fetch = aresoncv_nr_fetch; break;
570 default: snd_badsr(); break;
571 }
572
573 susp->terminate_cnt = UNKNOWN;
574 /* handle unequal start times, if any */
575 if (t0 < s1->t0) sound_prepend_zeros(s1, t0);
576 if (t0 < bw->t0) sound_prepend_zeros(bw, t0);
577 /* minimum start time over all inputs: */
578 t0_min = min(s1->t0, min(bw->t0, t0));
579 /* how many samples to toss before t0: */
580 susp->susp.toss_cnt = (long) ((t0 - t0_min) * sr + 0.5);
581 if (susp->susp.toss_cnt > 0) {
582 susp->susp.keep_fetch = susp->susp.fetch;
583 susp->susp.fetch = aresoncv_toss_fetch;
584 }
585
586 /* initialize susp state */
587 susp->susp.free = aresoncv_free;
588 susp->susp.sr = sr;
589 susp->susp.t0 = t0;
590 susp->susp.mark = aresoncv_mark;
591 susp->susp.print_tree = aresoncv_print_tree;
592 susp->susp.name = "aresoncv";
593 susp->logically_stopped = false;
594 susp->susp.log_stop_cnt = logical_stop_cnt_cvt(s1);
595 susp->started = false;
596 susp->susp.current = 0;
597 susp->s1 = s1;
598 susp->s1_cnt = 0;
599 susp->bw = bw;
600 susp->bw_cnt = 0;
601 susp->bw_pHaSe = 0.0;
602 susp->bw_pHaSe_iNcR = bw->sr / sr;
603 susp->bw_n = 0;
604 susp->output_per_bw = sr / bw->sr;
605 return sound_create((snd_susp_type)susp, t0, sr, scale_factor);
606 }
607
608
snd_aresoncv(sound_type s1,double hz,sound_type bw,int normalization)609 sound_type snd_aresoncv(sound_type s1, double hz, sound_type bw, int normalization)
610 {
611 sound_type s1_copy = sound_copy(s1);
612 sound_type bw_copy = sound_copy(bw);
613 return snd_make_aresoncv(s1_copy, hz, bw_copy, normalization);
614 }
615