1 /* sound.h -- new nyquist sound data type */
2 
3 /* CHANGE LOG
4  * --------------------------------------------------------------------
5  * 28Apr03  dm  changes for portability: moved some defns out of here
6  */
7 
8 #include <math.h>
9 #include "stdefs.h"
10 
11 /* used for *AUDIO-MARKERS* */
12 extern int64_t sound_frames;
13 extern double sound_srate;
14 
15 extern long max_sample_blocks;
16 
17 #if OSC
18 extern int nosc_enabled; /* enable polling for OSC messages */
19 #endif
20 
21 #if USE_PRINTF
22 #define nyquist_printf printf
23 #endif
24 
25 #define PERMS            0644           /* -rw-r--r-- */
26 
27 /* default stop sample count (for clipping) */
28 #define MAX_STOP 0x7FFFFFFFFFFFFFFF
29 
30 /* default stop time (for clipping) */
31 #define MAX_STOP_TIME 10E20
32 /* LISP-SRC: (SETF MAX-STOP-TIME 10E20) */
33 #define MIN_START_TIME -10E20
34 /* LISP-SRC: (SETF MIN-START-TIME -10E20) */
35 
36 /* conversion from float to integer */
37 #define SCALE_FACTOR_TO_BYTE 127
38 #define SCALE_FACTOR_TO_SHORT 32767
39 #define SCALE_FACTOR_TO_24BIT 0x7FFFFF
40 #define SCALE_FACTOR_TO_LONG 2147483647
41 
42 /* Note that the values assigned here are not arbitrary, but represent
43    a dominance relationship among the interpolation types.
44 */
45 #define INTERP_n 0
46 #define INTERP_s 1
47 #define INTERP_i 2
48 #define INTERP_r 3
49 
50 #define INTERP_nn 0
51 #define INTERP_ns 1
52 #define INTERP_ni 2
53 #define INTERP_nr 3
54 #define INTERP_sn 4
55 #define INTERP_ss 5
56 #define INTERP_si 6
57 #define INTERP_sr 7
58 #define INTERP_in 8
59 #define INTERP_is 9
60 #define INTERP_ii 10
61 #define INTERP_ir 11
62 #define INTERP_rn 12
63 #define INTERP_rs 13
64 #define INTERP_ri 14
65 #define INTERP_rr 15
66 
67 #define INTERP_nnn 0
68 #define INTERP_nns 1
69 #define INTERP_nni 2
70 #define INTERP_nnr 3
71 #define INTERP_nsn 4
72 #define INTERP_nss 5
73 #define INTERP_nsi 6
74 #define INTERP_nsr 7
75 #define INTERP_nin 8
76 #define INTERP_nis 9
77 #define INTERP_nii 10
78 #define INTERP_nir 11
79 #define INTERP_nrn 12
80 #define INTERP_nrs 13
81 #define INTERP_nri 14
82 #define INTERP_nrr 15
83 #define INTERP_snn 16
84 #define INTERP_sns 17
85 #define INTERP_sni 18
86 #define INTERP_snr 19
87 #define INTERP_ssn 20
88 #define INTERP_sss 21
89 #define INTERP_ssi 22
90 #define INTERP_ssr 23
91 #define INTERP_sin 24
92 #define INTERP_sis 25
93 #define INTERP_sii 26
94 #define INTERP_sir 27
95 #define INTERP_srn 28
96 #define INTERP_srs 29
97 #define INTERP_sri 30
98 #define INTERP_srr 31
99 
100 #define INTERP_inn 32
101 #define INTERP_ins 33
102 #define INTERP_ini 34
103 #define INTERP_inr 35
104 #define INTERP_isn 36
105 #define INTERP_iss 37
106 #define INTERP_isi 38
107 #define INTERP_isr 39
108 #define INTERP_iin 40
109 #define INTERP_iis 41
110 #define INTERP_iii 42
111 #define INTERP_iir 43
112 #define INTERP_irn 44
113 #define INTERP_irs 45
114 #define INTERP_iri 46
115 #define INTERP_irr 47
116 #define INTERP_rnn 48
117 #define INTERP_rns 49
118 #define INTERP_rni 50
119 #define INTERP_rnr 51
120 #define INTERP_rsn 52
121 #define INTERP_rss 53
122 #define INTERP_rsi 54
123 #define INTERP_rsr 55
124 #define INTERP_rin 56
125 #define INTERP_ris 57
126 #define INTERP_rii 58
127 #define INTERP_rir 59
128 #define INTERP_rrn 60
129 #define INTERP_rrs 61
130 #define INTERP_rri 62
131 #define INTERP_rrr 63
132 
133 #define INTERP_nnnn 0
134 #define INTERP_nnns 1
135 #define INTERP_nnsn 4
136 #define INTERP_nnss 5
137 #define INTERP_nsnn 16
138 #define INTERP_nsns 17
139 #define INTERP_nssn 20
140 #define INTERP_nsss 21
141 #define INTERP_nrrr 63
142 #define INTERP_snnn 64
143 #define INTERP_snns 65
144 #define INTERP_snsn 68
145 #define INTERP_snss 69
146 #define INTERP_ssnn 80
147 #define INTERP_ssns 81
148 #define INTERP_sssn 84
149 #define INTERP_ssss 85
150 #define INTERP_niii 42
151 #define INTERP_siii 106
152 #define INTERP_srrr 127
153 #define INTERP_iiii 170
154 #define INTERP_rrrr 255
155 
156 #define INTERP_nnnnnn 0
157 #define INTERP_nnnnns 1
158 #define INTERP_nnnnsn 4
159 #define INTERP_nnnnss 5
160 #define INTERP_nnnsnn 16
161 #define INTERP_nnnsns 17
162 #define INTERP_nnnssn 20
163 #define INTERP_nnnsss 21
164 #define INTERP_nnsnnn 64
165 #define INTERP_nnsnns 65
166 #define INTERP_nnsnsn 68
167 #define INTERP_nnsnss 69
168 #define INTERP_nnssnn 80
169 #define INTERP_nnssns 81
170 #define INTERP_nnsssn 84
171 #define INTERP_nnssss 85
172 #define INTERP_nsnnnn 256
173 #define INTERP_nsnnns 257
174 #define INTERP_nsnnsn 260
175 #define INTERP_nsnnss 261
176 #define INTERP_nsnsnn 272
177 #define INTERP_nsnsns 273
178 #define INTERP_nsnssn 276
179 #define INTERP_nsnsss 277
180 #define INTERP_nssnnn 320
181 #define INTERP_nssnns 321
182 #define INTERP_nssnsn 324
183 #define INTERP_nssnss 325
184 #define INTERP_nsssnn 336
185 #define INTERP_nsssns 337
186 #define INTERP_nssssn 340
187 #define INTERP_nsssss 341
188 #define INTERP_snnnnn 1024
189 #define INTERP_snnnns 1025
190 #define INTERP_snnnsn 1028
191 #define INTERP_snnnss 1029
192 #define INTERP_snnsnn 1040
193 #define INTERP_snnsns 1041
194 #define INTERP_snnssn 1044
195 #define INTERP_snnsss 1045
196 #define INTERP_snsnnn 1088
197 #define INTERP_snsnns 1089
198 #define INTERP_snsnsn 1092
199 #define INTERP_snsnss 1093
200 #define INTERP_snssnn 1104
201 #define INTERP_snssns 1105
202 #define INTERP_snsssn 1108
203 #define INTERP_snssss 1109
204 #define INTERP_ssnnnn 1280
205 #define INTERP_ssnnns 1281
206 #define INTERP_ssnnsn 1284
207 #define INTERP_ssnnss 1285
208 #define INTERP_ssnsnn 1296
209 #define INTERP_ssnsns 1297
210 #define INTERP_ssnssn 1300
211 #define INTERP_ssnsss 1301
212 #define INTERP_sssnnn 1344
213 #define INTERP_sssnns 1345
214 #define INTERP_sssnsn 1348
215 #define INTERP_sssnss 1349
216 #define INTERP_ssssnn 1360
217 #define INTERP_ssssns 1361
218 #define INTERP_sssssn 1364
219 #define INTERP_ssssss 1365
220 #define INTERP_iiiiii 2730
221 #define INTERP_rrrrrr 4095
222 
223 #define INTERP_nnnnnnnn 0
224 #define INTERP_ssssssss 21845
225 
226 
227 #define INTERP_MASK 3
228 #define INTERP_SHIFT 2
229 
230 LVAL snd_badsr(void);
231 int64_t check_terminate_cnt(int64_t tc);
232 
233 typedef double time_type;
234 typedef double rate_type;
235 typedef float sample_type;
236 typedef double promoted_sample_type;
237 
238 /* use radians or degrees for phase? */
239 #define ANGLEBASE 360.0
240 
241 /* used by sndwrite.c for output buffers.  This should be
242  * eliminated:
243  */
244 #define MAX_SND_CHANNELS 24
245 
246 #define max_table_len 100000000
247 /* Set to 4 for debugging block allocation stuff, 1012? for
248    production
249 */
250 /* leave a few words short of 1024 in case we allocate powers of 2 */
251 #define max_sample_block_len 1016
252 // #define max_sample_block_len 4
253 
254 /* longest allowed sample is basically 2^31 but a bit lower to
255    allow for rounding */
256 #define MAX_SND_LEN (MAX_STOP - max_sample_block_len * 2)
257 
258 
259 /* Defines needed for xlisp */
260 #define getsound(x)     ((sound_type) getinst(x))
261 #define xlgasound()     (testarg(typearg(soundp)))
262 
263 typedef short SFDataType, *SFDataPtr;
264 
265 typedef sample_type  sample_block_values[max_sample_block_len],
266                     *sample_block_values_type;
267 
268 typedef struct {
269     long                refcnt;                          /* reference count */
270     sample_block_values samples;
271 } sample_block_node, *sample_block_type;
272 
273 
274 /* forward declaration for circular type dependencies */
275 typedef struct snd_list_struct *snd_list_type;
276 
277 struct snd_susp_struct;
278 
279 typedef void  (*snd_fetch_fn)(struct snd_susp_struct *, snd_list_type snd_list);
280 typedef void  (*snd_free_fn)(struct snd_susp_struct *);
281 typedef void  (*snd_mark_fn)(struct snd_susp_struct *);  /* marks LVAL nodes for GC */
282 typedef void  (*snd_print_tree_fn)(struct snd_susp_struct *, int);
283 
284 typedef struct snd_susp_struct {
285     snd_fetch_fn fetch;
286     void  (*keep_fetch)(struct snd_susp_struct *, snd_list_type snd_list);
287     snd_free_fn free;
288     snd_mark_fn mark;
289     snd_print_tree_fn print_tree; /* debugging */
290     char *name;        /* string name for debugging */
291     int64_t toss_cnt;  /* return this many zeros, then compute */
292     int64_t current;   /* current sample number */
293     double sr;         /* sample rate */
294     time_type t0;      /* starting time */
295     int64_t log_stop_cnt; /* logical stop count */
296     /* other susp dependent stuff will be here... */
297 } snd_susp_node, *snd_susp_type;
298 
299 
300 typedef struct snd_list_struct {
301     sample_block_type   block;  /* pointer to block of samples */
302     union {
303         struct snd_list_struct  *next;
304         snd_susp_type           susp;
305     }       u;
306     short   refcnt;
307     short   block_len;
308     boolean logically_stopped;
309 } snd_list_node; /* , *snd_list_type; -- defined above */
310 
311 extern snd_list_type list_watch; //DBY
312 
313 
314 typedef struct table_struct {
315     long refcount;  /* reference count */
316     double length;  /* number of samples in table
317                        (double allows fractional length)*/
318     sample_type samples[1]; /* arbitrary length array of sample */
319 } table_node, *table_type;
320 
321 
322 /* some counts are biased by -max_sample_block_len, so UNKNOWN can't be -1
323  * Any number less than -max_sample_block should do
324  */
325 #define UNKNOWN (-10-max_sample_block_len)
326 
327 typedef struct sound_struct {
328     sample_block_type (*get_next)(struct sound_struct *snd, int *cnt);
329     time_type         time;    /* logical starting time */
330     time_type         t0;      /* quantized time of first sample */
331     int64_t           stop;    /* stop (clipping) sample no. */
332     time_type         true_t0; /* exact time of first sample */
333     rate_type         sr;      /* sample rate */
334     int64_t           current; /* current sample number,
335                                   if negative, then the first
336                                   -current samples must be dropped
337                                   in order to find the first sample */
338     int64_t           logical_stop_cnt; /* log stop sample no, -1=unknwn */
339     snd_list_type     list;    /* sample block list, starting at curr. samp */
340     sample_type       scale;   /* scale factor for the result */
341     int64_t           prepend_cnt; /* how many zeros to prepend */
342     /* function to use as get_next after prepended zeros are generated: */
343     sample_block_type (*after_prepend)
344                       (struct sound_struct * snd, int *cnt);
345     table_type table; /* pointer to table-ized version of this sound */
346     int64_t *extra;   /* used for extra state information, extra[0]
347                               should be the length of the extra state
348                               (see sound_unref()) */
349 } sound_node, *sound_type;
350 
351 /* convert number of samples to memory size: */
352 #define table_size_in_bytes(n) \
353     (sizeof(table_node) + sizeof(sample_type) * ((n) - 1))
354 
355 extern sample_block_type zero_block;
356 extern sample_block_type internal_zero_block;
357 
358 extern snd_list_type zero_snd_list;
359 
360 extern sound_type printing_this_sound;  /* debugging global */
361 
362 int64_t snd_set_max_audio_mem(int64_t m);
363 /* LISP: (SND-SET-MAX-AUDIO-MEM FIXNUM) */
364 
365 extern double sound_latency; /* controls output latency */
366 double snd_set_latency(double latency);
367 /* LISP: (SND-SET-LATENCY FLONUM) */
368 
369 double compute_phase(double phase, double key, long n, double srate,
370                      double new_srate, double freq, double *incr_ptr);
371 
372 boolean soundp(LVAL);
373 /* LISP: (SOUNDP ANY) */
374 
375 void snd_list_ref(snd_list_type list);
376 void sound_unref(sound_type snd);
377 void snd_list_unref(snd_list_type list);
378 
379 LVAL cvsound(sound_type);
380 extern LVAL a_sound;
381 
382 sample_block_type SND_get_next(sound_type snd, int *cnt);
383 sample_block_type SND_get_first(sound_type snd, int *cnt);
384 sample_block_type SND_get_zeros(sound_type snd, int *cnt);
385 sample_block_type SND_flush(sound_type snd, int *cnt);
386 
387 double hz_to_step(double);    /* LISP: (HZ-TO-STEP ANYNUM) */
388 int interp_style(sound_type s, rate_type sr);
389 void set_logical_stop_time(sound_type sound, time_type when); /* LISP: (SND-SET-LOGICAL-STOP SOUND ANYNUM) */
390 
391 #define xlog(x) log(x)
392 /* LISP: double (LOG FLONUM) */
393 snd_list_type snd_list_create(snd_susp_type susp);
394 void snd_list_terminate(snd_list_type snd_list);
395 void snd_sort_2(sound_type * s1_ptr, sound_type * s2_ptr, rate_type sr);
396 
397 double snd_sref(sound_type s, time_type t);
398     /* LISP: (SND-SREF SOUND ANYNUM) */
399 
400 double snd_sref_inverse(sound_type s, double val);
401     /* LISP: (SREF-INVERSE SOUND ANYNUM) */
402 
403 double snd_stop_time(sound_type s); /* LISP: (SND-STOP-TIME SOUND) */
404 #define snd_time(s) (s)->time
405     /* LISP: double (SND-TIME SOUND) */
406 
407 #define snd_srate(s) (s)->sr
408     /* LISP: double (SND-SRATE SOUND) */
409 #define snd_t0(s) (s)->t0
410     /* LISP: double (SND-T0 SOUND) */
411 
412 sound_type snd_xform(sound_type snd, rate_type sr, time_type time,
413         time_type start_time, time_type stop_time, promoted_sample_type scale);
414     /* LISP: (SND-XFORM SOUND ANYNUM ANYNUM ANYNUM ANYNUM ANYNUM) */
415 sound_type sound_create(snd_susp_type susp, time_type t0, rate_type sr,
416         promoted_sample_type scale);
417 
418 void min_cnt(int64_t *cnt_ptr, sound_type sound, snd_susp_type susp, long cnt);
419 void indent(int n);
420 void sound_prepend_zeros(sound_type snd, time_type t0);
421 
422 
423 
424 #ifndef GCBUG
425 #define blocks_to_watch_max 50
426 extern long blocks_to_watch_len;
427 extern sample_block_type blocks_to_watch[blocks_to_watch_max];
428 
429 void block_watch(int64_t sample_block);
430     /* LISP: (BLOCK-WATCH FIXNUM) */
431 int64_t sound_nth_block(sound_type snd, long n);
432     /* LISP: (SOUND-NTH-BLOCK SOUND LONG) */
433 #endif
434 
435 LVAL sound_array_copy(LVAL sa);
436 
437 sound_type sound_copy(sound_type snd);
438     /* LISP: (SND-COPY SOUND) */
439 void sound_xlmark(void *a_sound);
440 void sound_print(LVAL snd_expr, long n);
441     /* LISP: (SND-PRINT ANY LONG) */
442 int64_t sound_play(LVAL snd_expr);
443     /* LISP: (SND-PLAY ANY) */
444 void stats(void);
445     /* LISP: (STATS) */
446 void sound_print_tree(sound_type snd);
447     /* LISP: (SND-PRINT-TREE SOUND) */
448 
449 void mark_audio_time(void);
450 
451 void sound_print_tree_1(sound_type snd, int n);
452 
453 sound_type sound_scale(double factor, sound_type snd);
454     /* LISP: (SND-SCALE ANYNUM SOUND) */
455 void sound_init(void);
456 
457 void sound_symbols(void);
458 
459 table_type sound_to_table(sound_type s);
460 
461 void table_unref(table_type table);
462 
463 sound_type sound_zero(time_type t0, rate_type sr);
464     /* LISP: (SND-ZERO ANYNUM ANYNUM) */
465 
466 #define sound_get_next(s, n) ((*(s->get_next))(s, n))
467 
468 #define susp_print_tree(s, n) (*((s)->print_tree))(s, n)
469 
470 double step_to_hz(double);
471     /* LISP: (STEP-TO-HZ ANYNUM) */
472 
473 /* macros for access to samples within a suspension */
474 /* NOTE: assume suspension structure is named "susp" */
475 
476 /* susp_check_samples points sample_ptr to a new sample block if necessary */
477 #define susp_check_samples(sound, sample_ptr, sample_cnt) \
478     if (susp->sample_cnt == 0) \
479         susp_get_samples(sound, sample_ptr, sample_cnt)
480 
481 /* susp_check_samples_break is similar to susp_check_samples - "_break"
482  *   normally means that this code will break out of the inner loop, but in
483  *   this case, there is no reason (neither log nor term) to break.
484  *   x2_sample is taken from sound
485  */
486 #define susp_check_samples_break(sound, sample_ptr, sample_cnt, x2_sample) \
487     if (susp->sample_cnt == 0) { \
488         susp_get_samples(sound, sample_ptr, sample_cnt); \
489         x2_sample = susp_current_sample(sound, sample_ptr); }
490 
491 
492 /* susp_get_samples always gets next block (useful only in initialization code) */
493 #define susp_get_samples(sound, sample_ptr, sample_cnt) \
494         susp->sample_ptr = sound_get_next(susp->sound, &(susp->sample_cnt))->samples
495 
496 /* susp_get_block_samples always gets next block (useful only in initialization code) */
497 #define susp_get_block_samples(sound, sample_block_ptr, sample_ptr, sample_cnt) \
498     susp->sample_block_ptr = sound_get_next(susp->sound, &susp->sample_cnt); \
499     susp->sample_ptr = susp->sample_block_ptr->samples
500 
501 /* susp_took is called after you've taken n samples */
502 #define susp_took(sample_cnt, n) susp->sample_cnt -= n
503 
504 /* susp_fetch_sample is used to grab just one sample, doesn't check for samples!,
505  *    but applies scale factor:  */
506 #define susp_fetch_sample(sound, sample_ptr, sample_cnt) \
507           (susp->sound->scale * (susp->sample_cnt--, *(susp->sample_ptr++)))
508 
509 /* susp_current_sample grabs sample without advancing to next, applies scale
510  *     factor: */
511 #define susp_current_sample(sound, sample_ptr) \
512           (susp->sound->scale * (*(susp->sample_ptr)))
513 
514 /* susp_check_term_samples checks for samples; if new ones are fetched, then
515  * run termination test on signal and record result.
516  */
517 #define susp_check_term_samples(sound, sample_ptr, sample_cnt) \
518     if (susp->sample_cnt == 0) { \
519         susp_get_samples(sound, sample_ptr, sample_cnt); \
520         terminate_test(sample_ptr, sound, susp->sample_cnt); }
521 
522 /* susp_check_term_log_samples checks for samples
523  * if new ones are fetched, then run termination test and logical stop
524  * test on signal and record results.
525  */
526 #define susp_check_term_log_samples(sound, sample_ptr, sample_cnt) \
527     if (susp->sample_cnt == 0) { \
528         susp_get_samples(sound, sample_ptr, sample_cnt); \
529         logical_stop_test(sound, susp->sample_cnt); \
530         terminate_test(sample_ptr, sound, susp->sample_cnt); }
531 
532 /* susp_check_term_log_block_samples checks for samples
533  * if new ones are fetched, then run termination test and logical stop
534  * test on signal and record results.  In this case, termination and logical
535  * stop happen at the MAXIMUM of termination and logical stop times, resp.
536  *
537  * Originally, this code assumed that logical stops occurred on block boundaries,
538  * but because of the SET-LOGICAL-STOP function, which just writes a stop time
539  * into the sound_struct, the logical stop can be anywhere. As soon as the
540  * logical stop is known, we want to propagate the value from the sound being
541  * read into the sound being computed. The propagation should set the logical
542  * stop of the computed sound to the MAX of any current value and the new
543  * value. When the bit fields indicate that all logical stop times have been
544  * encountered, then the sound being computed will make the logical stop happen
545  * on a block boundary and set the flag on the block of samples where the stop
546  * occurs.
547  */
548 #define susp_check_term_log_block_samples(sound, sample_block_ptr, sample_ptr, sample_cnt, bit, all) \
549     if (susp->sample_cnt == 0) { \
550         susp_get_block_samples(sound, sample_block_ptr, \
551                                sample_ptr, sample_cnt); \
552         if (susp->sound->logical_stop_cnt != UNKNOWN && \
553             !(susp->logical_stop_bits & bit)) { \
554             susp->logical_stop_bits |= bit; \
555             susp->susp.log_stop_cnt = (int64_t) max(susp->susp.log_stop_cnt, \
556                     (((susp->sound->logical_stop_cnt / \
557                        susp->sound->sr + susp->sound->t0) - \
558                       susp->susp.t0) * susp->susp.sr + 0.5)); } \
559         if (susp->sample_ptr == zero_block->samples) { \
560             susp->terminate_bits |= bit; \
561             if (susp->terminate_bits == all) { \
562                 susp->terminate_cnt = ROUNDBIG( \
563                   (((susp->sound->current - susp->sample_cnt) / \
564                     susp->sound->sr + susp->sound->t0) - \
565                    susp->susp.t0) * susp->susp.sr); \
566     } } }
567 
568 
569 /* logical_stop_cnt_cvt is used to convert from the logical stop count
570  * at one sample rate to that of another sample rate -- this macro is
571  * used by the snd_make_<op> routine in every <op>.c file, and assumes
572  * the target sample rate is susp->susp.sr.
573  *
574  * NOTE: this macro does not take into account the possibility of different
575  * start times - maybe it should.
576  */
577 #define logical_stop_cnt_cvt(sound) \
578     (sound->logical_stop_cnt == UNKNOWN ? UNKNOWN : \
579      ROUNDBIG((sound->logical_stop_cnt / sound->sr) * susp->susp.sr))
580 
581 
582 /* logical_stop_test tests to see if sound has logically stopped; if so,
583  * sets susp->susp.log_stop_cnt.  The resulting logical_stop_cnt will reflect
584  * the minimum logical_stop time of all sounds to which this test is applied.
585  */
586 #define logical_stop_test(sound, cnt) \
587     if (susp->sound->logical_stop_cnt == susp->sound->current - (cnt)) {\
588         min_cnt(&susp->susp.log_stop_cnt, susp->sound, (snd_susp_type) susp, cnt); }
589 
590 /* terminate_test checks to see if sound has terminated; if so,
591  * sets susp->terminate_cnt.  The resulting terminate_cnt will reflect
592  * the minimum termination time of all sounds to which this test is applied.
593  */
594 #define terminate_test(sample_ptr, sound, cnt) \
595     if (susp->sample_ptr == zero_block->samples) { \
596             min_cnt(&susp->terminate_cnt, susp->sound, (snd_susp_type) susp, cnt); }
597 
598 
599 /* susp_check_log_samples checks for new samples then checks for
600  * termination and logical stop conditions
601  */
602 #define susp_check_log_samples(sound, sample_ptr, sample_cnt) \
603     if (susp->sample_cnt == 0) { \
604       susp_get_samples(sound, sample_ptr, sample_cnt); \
605       logical_stop_test(sound, susp->sample_cnt); }
606 
607 /* susp_check_term_samples_break checks for new samples then checks for
608  * termination condition; breaks from inner loop
609  */
610 #define susp_check_term_samples_break( \
611   sound, sample_ptr, sample_cnt, x2_sample) \
612     if (susp->sample_cnt == 0) { \
613       susp_get_samples(sound, sample_ptr, sample_cnt); \
614       x2_sample = susp_current_sample(sound, sample_ptr); \
615       terminate_test(sample_ptr, sound, susp->sample_cnt); \
616       if (susp->terminate_cnt < susp->susp.current + cnt + togo) { \
617           break; }} \
618     else x2_sample = susp_current_sample(sound, sample_ptr);
619 
620 /* susp_check_log_samples_break checks for new samples then checks for
621  * logical stop conditions; breaks from inner loop
622  */
623 #define susp_check_log_samples_break( \
624   sound, sample_ptr, sample_cnt, x2_sample) \
625     if (susp->sample_cnt == 0) { \
626       susp_get_samples(sound, sample_ptr, sample_cnt); \
627       x2_sample = susp_current_sample(sound, sample_ptr); \
628       logical_stop_test(sound, susp->sample_cnt); \
629       if (!susp->logically_stopped && susp->susp.log_stop_cnt != UNKNOWN && \
630           (susp->susp.log_stop_cnt < susp->susp.current + cnt + togo)) { \
631           break; }} \
632     else x2_sample = susp_current_sample(sound, sample_ptr);
633 
634 
635 /* susp_check_term_log_samples_break checks for new samples then checks for
636  * termination and logical stop conditions; breaks from inner loop
637  */
638 #define susp_check_term_log_samples_break( \
639   sound, sample_ptr, sample_cnt, x2_sample) \
640     if (susp->sample_cnt == 0) { \
641       susp_get_samples(sound, sample_ptr, sample_cnt); \
642       x2_sample = susp_current_sample(sound, sample_ptr); \
643       terminate_test(sample_ptr, sound, susp->sample_cnt); \
644       logical_stop_test(sound, susp->sample_cnt); \
645       if ((susp->terminate_cnt != UNKNOWN && \
646            susp->terminate_cnt < susp->susp.current + cnt + togo) || \
647           (!susp->logically_stopped && susp->susp.log_stop_cnt != UNKNOWN && \
648            susp->susp.log_stop_cnt < susp->susp.current + cnt + togo)) { \
649           break; }} \
650     else x2_sample = susp_current_sample(sound, sample_ptr);
651 
652 
653