mirror of
https://github.com/cookiengineer/audacity
synced 2025-06-25 08:38:39 +02:00
------------------------------------------------------------------------ r331 | rbd | 2020-10-13 12:40:12 -0500 (Tue, 13 Oct 2020) | 2 lines Also forgot to install NyquistWords.txt ------------------------------------------------------------------------ r330 | rbd | 2020-10-13 12:34:06 -0500 (Tue, 13 Oct 2020) | 2 lines Forgot to move nyquistman.pdf from docsrc/s2h to release ------------------------------------------------------------------------ r329 | rbd | 2020-10-13 11:32:33 -0500 (Tue, 13 Oct 2020) | 2 lines Updated some version numbers for 3.16. ------------------------------------------------------------------------ r328 | rbd | 2020-10-13 11:20:52 -0500 (Tue, 13 Oct 2020) | 2 lines Fixed NyquistIDE antialiasing for plot text, fix format of message. ------------------------------------------------------------------------ r327 | rbd | 2020-10-12 21:01:53 -0500 (Mon, 12 Oct 2020) | 2 lines Fixed a couple of format problems in manual. This version of Nyquist has been tested wtih macOS, Linux, 32&64-bit Windows. ------------------------------------------------------------------------ r326 | rbd | 2020-10-12 20:21:38 -0500 (Mon, 12 Oct 2020) | 1 line Modified WIN32 32-bit XLisp to use 64-bit FIXNUMs. This allows XLisp and Nyquist to handle big sounds even on 32-bit machines. Probably at some cost, but inner loops are mostly float and int32, and the Nyquist release is 64-bit anyway. Maybe we'll have to run some benchmarks on Audacity, which is still 32-bit on Windows. ------------------------------------------------------------------------ r325 | rbd | 2020-10-12 13:16:57 -0500 (Mon, 12 Oct 2020) | 1 line Win64 passes bigfiletest.lsp now. This version should work on all 64-bit systems now. These changes untested on Linux and macOS. ------------------------------------------------------------------------ r324 | rbd | 2020-10-11 21:31:53 -0500 (Sun, 11 Oct 2020) | 2 lines I couldn't free enough space on my linux box, so I adjusted the bigfiletest to write 8-bit ulaw. It's still >4GB and >4G samples. Works on Linux. ------------------------------------------------------------------------ r323 | rbd | 2020-10-11 19:41:25 -0500 (Sun, 11 Oct 2020) | 2 lines Missing file from last commit. ------------------------------------------------------------------------ r322 | rbd | 2020-10-11 19:36:08 -0500 (Sun, 11 Oct 2020) | 1 line Found another case where WIN64 needs int64_t instead of long for sample count. ------------------------------------------------------------------------ r321 | rbd | 2020-10-11 19:33:25 -0500 (Sun, 11 Oct 2020) | 3 lines Fixed s-save to handle optional and keyword parameters (which should never have been mixed in the first place). Documentation cleanup - should be final for this version. ------------------------------------------------------------------------ r320 | rbd | 2020-10-11 14:44:37 -0500 (Sun, 11 Oct 2020) | 2 lines Fixes to handle IRCAM sound format and tests for big file io working on macOS. ------------------------------------------------------------------------ r319 | rbd | 2020-10-10 21:31:58 -0500 (Sat, 10 Oct 2020) | 2 lines Changes for linux and to avoid compiler warnings on linux. ------------------------------------------------------------------------ r318 | rbd | 2020-10-10 20:50:23 -0500 (Sat, 10 Oct 2020) | 1 line This is the test used for Win64 version. ------------------------------------------------------------------------ r317 | rbd | 2020-10-10 20:34:34 -0500 (Sat, 10 Oct 2020) | 1 line This version works on Win64. Need to test changes on macOS and linux. ------------------------------------------------------------------------ r316 | rbd | 2020-10-10 19:59:15 -0500 (Sat, 10 Oct 2020) | 2 lines PWL changes to avoid compiler warning. ------------------------------------------------------------------------ r315 | rbd | 2020-10-10 19:34:04 -0500 (Sat, 10 Oct 2020) | 2 lines A few more changes for 64-bit sample counts on Win64 ------------------------------------------------------------------------ r314 | rbd | 2020-10-10 13:19:42 -0500 (Sat, 10 Oct 2020) | 2 lines Fixed int64_t declaration in gate.alg ------------------------------------------------------------------------ r313 | rbd | 2020-10-10 12:07:40 -0500 (Sat, 10 Oct 2020) | 2 lines Fixes to gate for long sounds ------------------------------------------------------------------------ r312 | rbd | 2020-10-10 11:47:29 -0500 (Sat, 10 Oct 2020) | 2 lines Fixed sound_save types for intgen ------------------------------------------------------------------------ r311 | rbd | 2020-10-10 11:09:01 -0500 (Sat, 10 Oct 2020) | 2 lines Fixed a 64-bit sample count problem in siosc.alg ------------------------------------------------------------------------ r310 | rbd | 2020-10-10 11:03:12 -0500 (Sat, 10 Oct 2020) | 2 lines Fixed sndmax to handle 64-bit sample counts. ------------------------------------------------------------------------ r309 | rbd | 2020-10-10 10:57:04 -0500 (Sat, 10 Oct 2020) | 2 lines Forgot to re-translate all tran/*.alg files with fix for int64 cast to int32. This version compiles on macOS and ready for test on Win64. ------------------------------------------------------------------------ r308 | rbd | 2020-10-10 10:16:05 -0500 (Sat, 10 Oct 2020) | 2 lines Everything seems to compile and run on macOS now. Moving changes to Windows for test. ------------------------------------------------------------------------ r307 | rbd | 2020-10-10 09:23:45 -0500 (Sat, 10 Oct 2020) | 1 line Added casts to avoid compiler warnings and to review changes to support 64-bit sample counts on Windows. Still not complete, and waiting to regenerate and compile tran directory code after updates to translation code that will insert more casts. ------------------------------------------------------------------------ r306 | rbd | 2020-10-09 21:55:15 -0500 (Fri, 09 Oct 2020) | 2 lines Rebuilt seqfnint.c from header files. ------------------------------------------------------------------------ r305 | rbd | 2020-10-09 21:53:33 -0500 (Fri, 09 Oct 2020) | 1 line Changed some FIXNUMS to LONG to avoid compiler warnings in seqfnint.c ------------------------------------------------------------------------ r304 | rbd | 2020-10-09 21:44:03 -0500 (Fri, 09 Oct 2020) | 2 lines I discovered forgotten regression-test.lsp and added test that requires 64-bit sample counts to pass. Fixed a few bugs revealed by running the type-checking regression tests. ------------------------------------------------------------------------ r303 | rbd | 2020-10-09 12:28:58 -0500 (Fri, 09 Oct 2020) | 2 lines Changes for 64-bit sample counts broke mult-channel s-save. Fixed in the commit for macOS. ------------------------------------------------------------------------ r302 | rbd | 2020-10-09 10:03:39 -0500 (Fri, 09 Oct 2020) | 2 lines Changed snd-play to return samples computed and used that to make a test for computing long sounds that would overflow 32-bit length counts. ------------------------------------------------------------------------ r301 | rbd | 2020-10-09 09:11:26 -0500 (Fri, 09 Oct 2020) | 2 lines corrected mistake in delaycv.alg and re-translated ------------------------------------------------------------------------ r300 | rbd | 2020-10-09 09:09:06 -0500 (Fri, 09 Oct 2020) | 2 lines Fix to delaycv.alg -- "s" changed to "input" to avoid matching "s" in "sample_type". ------------------------------------------------------------------------ r299 | rbd | 2020-10-09 09:03:33 -0500 (Fri, 09 Oct 2020) | 4 lines To avoid compiler warnings, XLisp interfaces to C int and long are now specified as LONG rather than FIXNUM, and the stubs that call the C functions cast FIXNUMs from XLisp into longs before calling C functions. ------------------------------------------------------------------------ r298 | rbd | 2020-10-08 22:20:26 -0500 (Thu, 08 Oct 2020) | 2 lines This commit has many more fixes to handle long (64-bit) sounds, including a lot of fixes for warnings by Visual Studio assigning int64_t to long (works on macOS, doesn't work on VS). This was compiled and tested on macOS, and even computed a 27.1-hour sound using OSC, LP, SUM and MULT (haven't tested I/O yet). ------------------------------------------------------------------------ r297 | rbd | 2020-10-07 13:04:02 -0500 (Wed, 07 Oct 2020) | 2 lines This is a major cleanup. It started with the goal of changing long to int64_t for sample counts so that on 64-bit windows, where long is only 32-bits, the sample counts would nevertheless be 64-bit allowing long sounds, which was a limitation for long recordings in Audacity. Since I was using compiler warnings to track possible loss-of-precision conversions from 64-bit sample counts, and there were *many* warnings, I started cleaning up *all* the warnings and ended up with a very large set of changes, including "modernizing" C declarations that date back to XLisp and CMU MIDI Toolkit code and were never changed. This version runs all the examples.sal code on macOS, but will surely have problems on Windows and Linux given the number of changes. ------------------------------------------------------------------------ r296 | rbd | 2020-10-06 13:34:20 -0500 (Tue, 06 Oct 2020) | 2 lines More changes from long to int64_t for sample counts. ------------------------------------------------------------------------ r295 | rbd | 2020-10-06 11:53:49 -0500 (Tue, 06 Oct 2020) | 2 lines More work on using 64-bit sample counts. Changed MAX_STOP from 32-bit to 64-bit limit. ------------------------------------------------------------------------ r294 | rbd | 2020-10-06 11:48:05 -0500 (Tue, 06 Oct 2020) | 2 lines Made some changes so that sample counts are int64_t (for windows) instead of long to support sample counts above 31 bits. ------------------------------------------------------------------------ r293 | rbd | 2020-10-04 21:30:55 -0500 (Sun, 04 Oct 2020) | 2 lines Fixed a few minor things for Linux and tested on Linux. ------------------------------------------------------------------------ r292 | rbd | 2020-10-04 21:00:28 -0500 (Sun, 04 Oct 2020) | 2 lines Update extensions: all are minor changes. ------------------------------------------------------------------------ r291 | rbd | 2020-09-24 13:59:31 -0500 (Thu, 24 Sep 2020) | 2 lines New implementation of seq and seqrep, added get-real-time, documented get-real-time, fixed examples.sal and examples.lsp which are now in lib rather than extensions (so they are now back in the basic installation), other cleanup. ------------------------------------------------------------------------ r290 | rbd | 2020-08-16 16:24:52 -0500 (Sun, 16 Aug 2020) | 2 lines Fixed bug in snd-gate, revised GATE and NOISE-GATE to handle multi-channel sound. RMS now handles multi-channel input. S-AVG added to take multichannel input (but not used, because RMS could not be written without making SND-SRATE convert multichannel sound to vector of floats. That seems to be going toward a fully vectorized model. Not going there for now. ------------------------------------------------------------------------ r289 | rbd | 2020-07-09 16:27:45 -0500 (Thu, 09 Jul 2020) | 2 lines Added GET-REAL-TIME function to XLISP. May not work yet on Windows. Various fixes for compiler warnings. I noticed FLAC doesn't work (I guess it never did) and I cannot figure out how this even links because flac_min seems to be undefined. Something to look at later.
646 lines
22 KiB
C
646 lines
22 KiB
C
/* sound.h -- new nyquist sound data type */
|
|
|
|
/* CHANGE LOG
|
|
* --------------------------------------------------------------------
|
|
* 28Apr03 dm changes for portability: moved some defns out of here
|
|
*/
|
|
|
|
#include <math.h>
|
|
#include "stdefs.h"
|
|
|
|
/* used for *AUDIO-MARKERS* */
|
|
extern int64_t sound_frames;
|
|
extern double sound_srate;
|
|
|
|
extern long max_sample_blocks;
|
|
|
|
#if OSC
|
|
extern int nosc_enabled; /* enable polling for OSC messages */
|
|
#endif
|
|
|
|
#if USE_PRINTF
|
|
#define nyquist_printf printf
|
|
#endif
|
|
|
|
#define PERMS 0644 /* -rw-r--r-- */
|
|
|
|
/* default stop sample count (for clipping) */
|
|
#define MAX_STOP 0x7FFFFFFFFFFFFFFF
|
|
|
|
/* default stop time (for clipping) */
|
|
#define MAX_STOP_TIME 10E20
|
|
/* LISP-SRC: (SETF MAX-STOP-TIME 10E20) */
|
|
#define MIN_START_TIME -10E20
|
|
/* LISP-SRC: (SETF MIN-START-TIME -10E20) */
|
|
|
|
/* conversion from float to integer */
|
|
#define SCALE_FACTOR_TO_BYTE 127
|
|
#define SCALE_FACTOR_TO_SHORT 32767
|
|
#define SCALE_FACTOR_TO_24BIT 0x7FFFFF
|
|
#define SCALE_FACTOR_TO_LONG 2147483647
|
|
|
|
/* Note that the values assigned here are not arbitrary, but represent
|
|
a dominance relationship among the interpolation types.
|
|
*/
|
|
#define INTERP_n 0
|
|
#define INTERP_s 1
|
|
#define INTERP_i 2
|
|
#define INTERP_r 3
|
|
|
|
#define INTERP_nn 0
|
|
#define INTERP_ns 1
|
|
#define INTERP_ni 2
|
|
#define INTERP_nr 3
|
|
#define INTERP_sn 4
|
|
#define INTERP_ss 5
|
|
#define INTERP_si 6
|
|
#define INTERP_sr 7
|
|
#define INTERP_in 8
|
|
#define INTERP_is 9
|
|
#define INTERP_ii 10
|
|
#define INTERP_ir 11
|
|
#define INTERP_rn 12
|
|
#define INTERP_rs 13
|
|
#define INTERP_ri 14
|
|
#define INTERP_rr 15
|
|
|
|
#define INTERP_nnn 0
|
|
#define INTERP_nns 1
|
|
#define INTERP_nni 2
|
|
#define INTERP_nnr 3
|
|
#define INTERP_nsn 4
|
|
#define INTERP_nss 5
|
|
#define INTERP_nsi 6
|
|
#define INTERP_nsr 7
|
|
#define INTERP_nin 8
|
|
#define INTERP_nis 9
|
|
#define INTERP_nii 10
|
|
#define INTERP_nir 11
|
|
#define INTERP_nrn 12
|
|
#define INTERP_nrs 13
|
|
#define INTERP_nri 14
|
|
#define INTERP_nrr 15
|
|
#define INTERP_snn 16
|
|
#define INTERP_sns 17
|
|
#define INTERP_sni 18
|
|
#define INTERP_snr 19
|
|
#define INTERP_ssn 20
|
|
#define INTERP_sss 21
|
|
#define INTERP_ssi 22
|
|
#define INTERP_ssr 23
|
|
#define INTERP_sin 24
|
|
#define INTERP_sis 25
|
|
#define INTERP_sii 26
|
|
#define INTERP_sir 27
|
|
#define INTERP_srn 28
|
|
#define INTERP_srs 29
|
|
#define INTERP_sri 30
|
|
#define INTERP_srr 31
|
|
|
|
#define INTERP_inn 32
|
|
#define INTERP_ins 33
|
|
#define INTERP_ini 34
|
|
#define INTERP_inr 35
|
|
#define INTERP_isn 36
|
|
#define INTERP_iss 37
|
|
#define INTERP_isi 38
|
|
#define INTERP_isr 39
|
|
#define INTERP_iin 40
|
|
#define INTERP_iis 41
|
|
#define INTERP_iii 42
|
|
#define INTERP_iir 43
|
|
#define INTERP_irn 44
|
|
#define INTERP_irs 45
|
|
#define INTERP_iri 46
|
|
#define INTERP_irr 47
|
|
#define INTERP_rnn 48
|
|
#define INTERP_rns 49
|
|
#define INTERP_rni 50
|
|
#define INTERP_rnr 51
|
|
#define INTERP_rsn 52
|
|
#define INTERP_rss 53
|
|
#define INTERP_rsi 54
|
|
#define INTERP_rsr 55
|
|
#define INTERP_rin 56
|
|
#define INTERP_ris 57
|
|
#define INTERP_rii 58
|
|
#define INTERP_rir 59
|
|
#define INTERP_rrn 60
|
|
#define INTERP_rrs 61
|
|
#define INTERP_rri 62
|
|
#define INTERP_rrr 63
|
|
|
|
#define INTERP_nnnn 0
|
|
#define INTERP_nnns 1
|
|
#define INTERP_nnsn 4
|
|
#define INTERP_nnss 5
|
|
#define INTERP_nsnn 16
|
|
#define INTERP_nsns 17
|
|
#define INTERP_nssn 20
|
|
#define INTERP_nsss 21
|
|
#define INTERP_nrrr 63
|
|
#define INTERP_snnn 64
|
|
#define INTERP_snns 65
|
|
#define INTERP_snsn 68
|
|
#define INTERP_snss 69
|
|
#define INTERP_ssnn 80
|
|
#define INTERP_ssns 81
|
|
#define INTERP_sssn 84
|
|
#define INTERP_ssss 85
|
|
#define INTERP_niii 42
|
|
#define INTERP_siii 106
|
|
#define INTERP_srrr 127
|
|
#define INTERP_iiii 170
|
|
#define INTERP_rrrr 255
|
|
|
|
#define INTERP_nnnnnn 0
|
|
#define INTERP_nnnnns 1
|
|
#define INTERP_nnnnsn 4
|
|
#define INTERP_nnnnss 5
|
|
#define INTERP_nnnsnn 16
|
|
#define INTERP_nnnsns 17
|
|
#define INTERP_nnnssn 20
|
|
#define INTERP_nnnsss 21
|
|
#define INTERP_nnsnnn 64
|
|
#define INTERP_nnsnns 65
|
|
#define INTERP_nnsnsn 68
|
|
#define INTERP_nnsnss 69
|
|
#define INTERP_nnssnn 80
|
|
#define INTERP_nnssns 81
|
|
#define INTERP_nnsssn 84
|
|
#define INTERP_nnssss 85
|
|
#define INTERP_nsnnnn 256
|
|
#define INTERP_nsnnns 257
|
|
#define INTERP_nsnnsn 260
|
|
#define INTERP_nsnnss 261
|
|
#define INTERP_nsnsnn 272
|
|
#define INTERP_nsnsns 273
|
|
#define INTERP_nsnssn 276
|
|
#define INTERP_nsnsss 277
|
|
#define INTERP_nssnnn 320
|
|
#define INTERP_nssnns 321
|
|
#define INTERP_nssnsn 324
|
|
#define INTERP_nssnss 325
|
|
#define INTERP_nsssnn 336
|
|
#define INTERP_nsssns 337
|
|
#define INTERP_nssssn 340
|
|
#define INTERP_nsssss 341
|
|
#define INTERP_snnnnn 1024
|
|
#define INTERP_snnnns 1025
|
|
#define INTERP_snnnsn 1028
|
|
#define INTERP_snnnss 1029
|
|
#define INTERP_snnsnn 1040
|
|
#define INTERP_snnsns 1041
|
|
#define INTERP_snnssn 1044
|
|
#define INTERP_snnsss 1045
|
|
#define INTERP_snsnnn 1088
|
|
#define INTERP_snsnns 1089
|
|
#define INTERP_snsnsn 1092
|
|
#define INTERP_snsnss 1093
|
|
#define INTERP_snssnn 1104
|
|
#define INTERP_snssns 1105
|
|
#define INTERP_snsssn 1108
|
|
#define INTERP_snssss 1109
|
|
#define INTERP_ssnnnn 1280
|
|
#define INTERP_ssnnns 1281
|
|
#define INTERP_ssnnsn 1284
|
|
#define INTERP_ssnnss 1285
|
|
#define INTERP_ssnsnn 1296
|
|
#define INTERP_ssnsns 1297
|
|
#define INTERP_ssnssn 1300
|
|
#define INTERP_ssnsss 1301
|
|
#define INTERP_sssnnn 1344
|
|
#define INTERP_sssnns 1345
|
|
#define INTERP_sssnsn 1348
|
|
#define INTERP_sssnss 1349
|
|
#define INTERP_ssssnn 1360
|
|
#define INTERP_ssssns 1361
|
|
#define INTERP_sssssn 1364
|
|
#define INTERP_ssssss 1365
|
|
#define INTERP_iiiiii 2730
|
|
#define INTERP_rrrrrr 4095
|
|
|
|
#define INTERP_nnnnnnnn 0
|
|
#define INTERP_ssssssss 21845
|
|
|
|
|
|
#define INTERP_MASK 3
|
|
#define INTERP_SHIFT 2
|
|
|
|
LVAL snd_badsr(void);
|
|
int64_t check_terminate_cnt(int64_t tc);
|
|
|
|
typedef double time_type;
|
|
typedef double rate_type;
|
|
typedef float sample_type;
|
|
typedef double promoted_sample_type;
|
|
|
|
/* use radians or degrees for phase? */
|
|
#define ANGLEBASE 360.0
|
|
|
|
/* used by sndwrite.c for output buffers. This should be
|
|
* eliminated:
|
|
*/
|
|
#define MAX_SND_CHANNELS 24
|
|
|
|
#define max_table_len 100000000
|
|
/* Set to 4 for debugging block allocation stuff, 1012? for
|
|
production
|
|
*/
|
|
/* leave a few words short of 1024 in case we allocate powers of 2 */
|
|
#define max_sample_block_len 1016
|
|
// #define max_sample_block_len 4
|
|
|
|
/* longest allowed sample is basically 2^31 but a bit lower to
|
|
allow for rounding */
|
|
#define MAX_SND_LEN (MAX_STOP - max_sample_block_len * 2)
|
|
|
|
|
|
/* Defines needed for xlisp */
|
|
#define getsound(x) ((sound_type) getinst(x))
|
|
#define xlgasound() (testarg(typearg(soundp)))
|
|
|
|
typedef short SFDataType, *SFDataPtr;
|
|
|
|
typedef sample_type sample_block_values[max_sample_block_len],
|
|
*sample_block_values_type;
|
|
|
|
typedef struct {
|
|
long refcnt; /* reference count */
|
|
sample_block_values samples;
|
|
} sample_block_node, *sample_block_type;
|
|
|
|
|
|
/* forward declaration for circular type dependencies */
|
|
typedef struct snd_list_struct *snd_list_type;
|
|
|
|
typedef struct snd_susp_struct {
|
|
void (*fetch)(struct snd_susp_struct *, snd_list_type snd_list);
|
|
void (*keep_fetch)(struct snd_susp_struct *, snd_list_type snd_list);
|
|
void (*free)(struct snd_susp_struct *);
|
|
void (*mark)(struct snd_susp_struct *); /* marks LVAL nodes for GC */
|
|
void (*print_tree)(struct snd_susp_struct *, int); /* debugging */
|
|
char *name; /* string name for debugging */
|
|
int64_t toss_cnt; /* return this many zeros, then compute */
|
|
int64_t current; /* current sample number */
|
|
double sr; /* sample rate */
|
|
time_type t0; /* starting time */
|
|
int64_t log_stop_cnt; /* logical stop count */
|
|
/* other susp dependent stuff will be here... */
|
|
} snd_susp_node, *snd_susp_type;
|
|
|
|
|
|
typedef struct snd_list_struct {
|
|
sample_block_type block; /* pointer to block of samples */
|
|
union {
|
|
struct snd_list_struct *next;
|
|
snd_susp_type susp;
|
|
} u;
|
|
short refcnt;
|
|
short block_len;
|
|
boolean logically_stopped;
|
|
} snd_list_node; /* , *snd_list_type; -- defined above */
|
|
|
|
extern snd_list_type list_watch; //DBY
|
|
|
|
|
|
typedef struct table_struct {
|
|
long refcount; /* reference count */
|
|
double length; /* number of samples in table
|
|
(double allows fractional length)*/
|
|
sample_type samples[1]; /* arbitrary length array of sample */
|
|
} table_node, *table_type;
|
|
|
|
|
|
/* some counts are biased by -max_sample_block_len, so UNKNOWN can't be -1
|
|
* Any number less than -max_sample_block should do
|
|
*/
|
|
#define UNKNOWN (-10-max_sample_block_len)
|
|
|
|
typedef struct sound_struct {
|
|
sample_block_type (*get_next)(struct sound_struct *snd, int *cnt);
|
|
time_type time; /* logical starting time */
|
|
time_type t0; /* quantized time of first sample */
|
|
int64_t stop; /* stop (clipping) sample no. */
|
|
time_type true_t0; /* exact time of first sample */
|
|
rate_type sr; /* sample rate */
|
|
int64_t current; /* current sample number,
|
|
if negative, then the first
|
|
-current samples must be dropped
|
|
in order to find the first sample */
|
|
int64_t logical_stop_cnt; /* log stop sample no, -1=unknwn */
|
|
snd_list_type list; /* sample block list, starting at curr. samp */
|
|
sample_type scale; /* scale factor for the result */
|
|
int64_t prepend_cnt; /* how many zeros to prepend */
|
|
/* function to use as get_next after prepended zeros are generated: */
|
|
sample_block_type (*after_prepend)
|
|
(struct sound_struct * snd, int *cnt);
|
|
table_type table; /* pointer to table-ized version of this sound */
|
|
int64_t *extra; /* used for extra state information, extra[0]
|
|
should be the length of the extra state
|
|
(see sound_unref()) */
|
|
} sound_node, *sound_type;
|
|
|
|
/* convert number of samples to memory size: */
|
|
#define table_size_in_bytes(n) \
|
|
(sizeof(table_node) + sizeof(sample_type) * ((n) - 1))
|
|
|
|
extern sample_block_type zero_block;
|
|
extern sample_block_type internal_zero_block;
|
|
|
|
extern snd_list_type zero_snd_list;
|
|
|
|
extern sound_type printing_this_sound; /* debugging global */
|
|
|
|
int64_t snd_set_max_audio_mem(int64_t m);
|
|
/* LISP: (SND-SET-MAX-AUDIO-MEM FIXNUM) */
|
|
|
|
extern double sound_latency; /* controls output latency */
|
|
double snd_set_latency(double latency);
|
|
/* LISP: (SND-SET-LATENCY FLONUM) */
|
|
|
|
double compute_phase(double phase, double key, long n, double srate,
|
|
double new_srate, double freq, double *incr_ptr);
|
|
|
|
boolean soundp(LVAL);
|
|
/* LISP: (SOUNDP ANY) */
|
|
|
|
void snd_list_ref(snd_list_type list);
|
|
void sound_unref(sound_type snd);
|
|
void snd_list_unref(snd_list_type list);
|
|
|
|
LVAL cvsound(sound_type);
|
|
extern LVAL a_sound;
|
|
|
|
sample_block_type SND_get_next(sound_type snd, int *cnt);
|
|
sample_block_type SND_get_first(sound_type snd, int *cnt);
|
|
sample_block_type SND_get_zeros(sound_type snd, int *cnt);
|
|
sample_block_type SND_flush(sound_type snd, int *cnt);
|
|
|
|
double hz_to_step(double); /* LISP: (HZ-TO-STEP ANYNUM) */
|
|
int interp_style(sound_type s, rate_type sr);
|
|
void set_logical_stop_time(sound_type sound, time_type when); /* LISP: (SND-SET-LOGICAL-STOP SOUND ANYNUM) */
|
|
|
|
#define xlog(x) log(x)
|
|
/* LISP: double (LOG FLONUM) */
|
|
snd_list_type snd_list_create(snd_susp_type susp);
|
|
void snd_list_terminate(snd_list_type snd_list);
|
|
void snd_sort_2(sound_type * s1_ptr, sound_type * s2_ptr, rate_type sr);
|
|
|
|
double snd_sref(sound_type s, time_type t);
|
|
/* LISP: (SND-SREF SOUND ANYNUM) */
|
|
|
|
double snd_sref_inverse(sound_type s, double val);
|
|
/* LISP: (SREF-INVERSE SOUND ANYNUM) */
|
|
|
|
double snd_stop_time(sound_type s); /* LISP: (SND-STOP-TIME SOUND) */
|
|
#define snd_time(s) (s)->time
|
|
/* LISP: double (SND-TIME SOUND) */
|
|
|
|
#define snd_srate(s) (s)->sr
|
|
/* LISP: double (SND-SRATE SOUND) */
|
|
#define snd_t0(s) (s)->t0
|
|
/* LISP: double (SND-T0 SOUND) */
|
|
|
|
sound_type snd_xform(sound_type snd, rate_type sr, time_type time,
|
|
time_type start_time, time_type stop_time, promoted_sample_type scale);
|
|
/* LISP: (SND-XFORM SOUND ANYNUM ANYNUM ANYNUM ANYNUM ANYNUM) */
|
|
sound_type sound_create(snd_susp_type susp, time_type t0, rate_type sr,
|
|
promoted_sample_type scale);
|
|
|
|
void min_cnt(int64_t *cnt_ptr, sound_type sound, snd_susp_type susp, long cnt);
|
|
void indent(int n);
|
|
void sound_prepend_zeros(sound_type snd, time_type t0);
|
|
|
|
|
|
|
|
#ifndef GCBUG
|
|
#define blocks_to_watch_max 50
|
|
extern long blocks_to_watch_len;
|
|
extern sample_block_type blocks_to_watch[blocks_to_watch_max];
|
|
|
|
void block_watch(int64_t sample_block);
|
|
/* LISP: (BLOCK-WATCH FIXNUM) */
|
|
int64_t sound_nth_block(sound_type snd, long n);
|
|
/* LISP: (SOUND-NTH-BLOCK SOUND LONG) */
|
|
#endif
|
|
|
|
LVAL sound_array_copy(LVAL sa);
|
|
|
|
sound_type sound_copy(sound_type snd);
|
|
/* LISP: (SND-COPY SOUND) */
|
|
void sound_xlmark(void *a_sound);
|
|
void sound_print(LVAL snd_expr, long n);
|
|
/* LISP: (SND-PRINT ANY LONG) */
|
|
int64_t sound_play(LVAL snd_expr);
|
|
/* LISP: (SND-PLAY ANY) */
|
|
void stats(void);
|
|
/* LISP: (STATS) */
|
|
void sound_print_tree(sound_type snd);
|
|
/* LISP: (SND-PRINT-TREE SOUND) */
|
|
|
|
void mark_audio_time(void);
|
|
|
|
void sound_print_tree_1(sound_type snd, int n);
|
|
|
|
sound_type sound_scale(double factor, sound_type snd);
|
|
/* LISP: (SND-SCALE ANYNUM SOUND) */
|
|
void sound_init(void);
|
|
|
|
void sound_symbols(void);
|
|
|
|
table_type sound_to_table(sound_type s);
|
|
|
|
void table_unref(table_type table);
|
|
|
|
sound_type sound_zero(time_type t0, rate_type sr);
|
|
/* LISP: (SND-ZERO ANYNUM ANYNUM) */
|
|
|
|
#define sound_get_next(s, n) ((*(s->get_next))(s, n))
|
|
|
|
#define susp_print_tree(s, n) (*((s)->print_tree))(s, n)
|
|
|
|
double step_to_hz(double);
|
|
/* LISP: (STEP-TO-HZ ANYNUM) */
|
|
|
|
/* macros for access to samples within a suspension */
|
|
/* NOTE: assume suspension structure is named "susp" */
|
|
|
|
/* susp_check_samples points sample_ptr to a new sample block if necessary */
|
|
#define susp_check_samples(sound, sample_ptr, sample_cnt) \
|
|
if (susp->sample_cnt == 0) \
|
|
susp_get_samples(sound, sample_ptr, sample_cnt)
|
|
|
|
/* susp_check_samples_break is similar to susp_check_samples - "_break"
|
|
* normally means that this code will break out of the inner loop, but in
|
|
* this case, there is no reason (neither log nor term) to break.
|
|
* x2_sample is taken from sound
|
|
*/
|
|
#define susp_check_samples_break(sound, sample_ptr, sample_cnt, x2_sample) \
|
|
if (susp->sample_cnt == 0) { \
|
|
susp_get_samples(sound, sample_ptr, sample_cnt); \
|
|
x2_sample = susp_current_sample(sound, sample_ptr); }
|
|
|
|
|
|
/* susp_get_samples always gets next block (useful only in initialization code) */
|
|
#define susp_get_samples(sound, sample_ptr, sample_cnt) \
|
|
susp->sample_ptr = sound_get_next(susp->sound, &(susp->sample_cnt))->samples
|
|
|
|
/* susp_get_block_samples always gets next block (useful only in initialization code) */
|
|
#define susp_get_block_samples(sound, sample_block_ptr, sample_ptr, sample_cnt) \
|
|
susp->sample_block_ptr = sound_get_next(susp->sound, &susp->sample_cnt); \
|
|
susp->sample_ptr = susp->sample_block_ptr->samples
|
|
|
|
/* susp_took is called after you've taken n samples */
|
|
#define susp_took(sample_cnt, n) susp->sample_cnt -= n
|
|
|
|
/* susp_fetch_sample is used to grab just one sample, doesn't check for samples!,
|
|
* but applies scale factor: */
|
|
#define susp_fetch_sample(sound, sample_ptr, sample_cnt) \
|
|
(susp->sound->scale * (susp->sample_cnt--, *(susp->sample_ptr++)))
|
|
|
|
/* susp_current_sample grabs sample without advancing to next, applies scale
|
|
* factor: */
|
|
#define susp_current_sample(sound, sample_ptr) \
|
|
(susp->sound->scale * (*(susp->sample_ptr)))
|
|
|
|
/* susp_check_term_samples checks for samples; if new ones are fetched, then
|
|
* run termination test on signal and record result.
|
|
*/
|
|
#define susp_check_term_samples(sound, sample_ptr, sample_cnt) \
|
|
if (susp->sample_cnt == 0) { \
|
|
susp_get_samples(sound, sample_ptr, sample_cnt); \
|
|
terminate_test(sample_ptr, sound, susp->sample_cnt); }
|
|
|
|
/* susp_check_term_log_samples checks for samples
|
|
* if new ones are fetched, then run termination test and logical stop
|
|
* test on signal and record results.
|
|
*/
|
|
#define susp_check_term_log_samples(sound, sample_ptr, sample_cnt) \
|
|
if (susp->sample_cnt == 0) { \
|
|
susp_get_samples(sound, sample_ptr, sample_cnt); \
|
|
logical_stop_test(sound, susp->sample_cnt); \
|
|
terminate_test(sample_ptr, sound, susp->sample_cnt); }
|
|
|
|
/* susp_check_term_log_block_samples checks for samples
|
|
* if new ones are fetched, then run termination test and logical stop
|
|
* test on signal and record results. In this case, termination and logical
|
|
* stop happen at the MAXIMUM of termination and logical stop times, resp.
|
|
*
|
|
* Originally, this code assumed that logical stops occurred on block boundaries,
|
|
* but because of the SET-LOGICAL-STOP function, which just writes a stop time
|
|
* into the sound_struct, the logical stop can be anywhere. As soon as the
|
|
* logical stop is known, we want to propagate the value from the sound being
|
|
* read into the sound being computed. The propagation should set the logical
|
|
* stop of the computed sound to the MAX of any current value and the new
|
|
* value. When the bit fields indicate that all logical stop times have been
|
|
* encountered, then the sound being computed will make the logical stop happen
|
|
* on a block boundary and set the flag on the block of samples where the stop
|
|
* occurs.
|
|
*/
|
|
#define susp_check_term_log_block_samples(sound, sample_block_ptr, sample_ptr, sample_cnt, bit, all) \
|
|
if (susp->sample_cnt == 0) { \
|
|
susp_get_block_samples(sound, sample_block_ptr, \
|
|
sample_ptr, sample_cnt); \
|
|
if (susp->sound->logical_stop_cnt != UNKNOWN && \
|
|
!(susp->logical_stop_bits & bit)) { \
|
|
susp->logical_stop_bits |= bit; \
|
|
susp->susp.log_stop_cnt = (int64_t) max(susp->susp.log_stop_cnt, \
|
|
(((susp->sound->logical_stop_cnt / \
|
|
susp->sound->sr + susp->sound->t0) - \
|
|
susp->susp.t0) * susp->susp.sr + 0.5)); } \
|
|
if (susp->sample_ptr == zero_block->samples) { \
|
|
susp->terminate_bits |= bit; \
|
|
if (susp->terminate_bits == all) { \
|
|
susp->terminate_cnt = ROUNDBIG( \
|
|
(((susp->sound->current - susp->sample_cnt) / \
|
|
susp->sound->sr + susp->sound->t0) - \
|
|
susp->susp.t0) * susp->susp.sr); \
|
|
} } }
|
|
|
|
|
|
/* logical_stop_cnt_cvt is used to convert from the logical stop count
|
|
* at one sample rate to that of another sample rate -- this macro is
|
|
* used by the snd_make_<op> routine in every <op>.c file, and assumes
|
|
* the target sample rate is susp->susp.sr.
|
|
*
|
|
* NOTE: this macro does not take into account the possibility of different
|
|
* start times - maybe it should.
|
|
*/
|
|
#define logical_stop_cnt_cvt(sound) \
|
|
(sound->logical_stop_cnt == UNKNOWN ? UNKNOWN : \
|
|
ROUNDBIG((sound->logical_stop_cnt / sound->sr) * susp->susp.sr))
|
|
|
|
|
|
/* logical_stop_test tests to see if sound has logically stopped; if so,
|
|
* sets susp->susp.log_stop_cnt. The resulting logical_stop_cnt will reflect
|
|
* the minimum logical_stop time of all sounds to which this test is applied.
|
|
*/
|
|
#define logical_stop_test(sound, cnt) \
|
|
if (susp->sound->logical_stop_cnt == susp->sound->current - (cnt)) {\
|
|
min_cnt(&susp->susp.log_stop_cnt, susp->sound, (snd_susp_type) susp, cnt); }
|
|
|
|
/* terminate_test checks to see if sound has terminated; if so,
|
|
* sets susp->terminate_cnt. The resulting terminate_cnt will reflect
|
|
* the minimum termination time of all sounds to which this test is applied.
|
|
*/
|
|
#define terminate_test(sample_ptr, sound, cnt) \
|
|
if (susp->sample_ptr == zero_block->samples) { \
|
|
min_cnt(&susp->terminate_cnt, susp->sound, (snd_susp_type) susp, cnt); }
|
|
|
|
|
|
/* susp_check_log_samples checks for new samples then checks for
|
|
* termination and logical stop conditions
|
|
*/
|
|
#define susp_check_log_samples(sound, sample_ptr, sample_cnt) \
|
|
if (susp->sample_cnt == 0) { \
|
|
susp_get_samples(sound, sample_ptr, sample_cnt); \
|
|
logical_stop_test(sound, susp->sample_cnt); }
|
|
|
|
/* susp_check_term_samples_break checks for new samples then checks for
|
|
* termination condition; breaks from inner loop
|
|
*/
|
|
#define susp_check_term_samples_break( \
|
|
sound, sample_ptr, sample_cnt, x2_sample) \
|
|
if (susp->sample_cnt == 0) { \
|
|
susp_get_samples(sound, sample_ptr, sample_cnt); \
|
|
x2_sample = susp_current_sample(sound, sample_ptr); \
|
|
terminate_test(sample_ptr, sound, susp->sample_cnt); \
|
|
if (susp->terminate_cnt < susp->susp.current + cnt + togo) { \
|
|
break; }} \
|
|
else x2_sample = susp_current_sample(sound, sample_ptr);
|
|
|
|
/* susp_check_log_samples_break checks for new samples then checks for
|
|
* logical stop conditions; breaks from inner loop
|
|
*/
|
|
#define susp_check_log_samples_break( \
|
|
sound, sample_ptr, sample_cnt, x2_sample) \
|
|
if (susp->sample_cnt == 0) { \
|
|
susp_get_samples(sound, sample_ptr, sample_cnt); \
|
|
x2_sample = susp_current_sample(sound, sample_ptr); \
|
|
logical_stop_test(sound, susp->sample_cnt); \
|
|
if (!susp->logically_stopped && susp->susp.log_stop_cnt != UNKNOWN && \
|
|
(susp->susp.log_stop_cnt < susp->susp.current + cnt + togo)) { \
|
|
break; }} \
|
|
else x2_sample = susp_current_sample(sound, sample_ptr);
|
|
|
|
|
|
/* susp_check_term_log_samples_break checks for new samples then checks for
|
|
* termination and logical stop conditions; breaks from inner loop
|
|
*/
|
|
#define susp_check_term_log_samples_break( \
|
|
sound, sample_ptr, sample_cnt, x2_sample) \
|
|
if (susp->sample_cnt == 0) { \
|
|
susp_get_samples(sound, sample_ptr, sample_cnt); \
|
|
x2_sample = susp_current_sample(sound, sample_ptr); \
|
|
terminate_test(sample_ptr, sound, susp->sample_cnt); \
|
|
logical_stop_test(sound, susp->sample_cnt); \
|
|
if ((susp->terminate_cnt != UNKNOWN && \
|
|
susp->terminate_cnt < susp->susp.current + cnt + togo) || \
|
|
(!susp->logically_stopped && susp->susp.log_stop_cnt != UNKNOWN && \
|
|
susp->susp.log_stop_cnt < susp->susp.current + cnt + togo)) { \
|
|
break; }} \
|
|
else x2_sample = susp_current_sample(sound, sample_ptr);
|
|
|
|
|