1 /*
2  * Copyright (C) 1997-2005 Kare Sjolander <kare@speech.kth.se>
3  *
4  * This file is part of the Snack Sound Toolkit.
5  * The latest version can be found at http://www.speech.kth.se/snack/
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20  */
21 
22 #ifndef _SNACK_SOUND
23 #define _SNACK_SOUND
24 
25 #ifdef __cplusplus
26 extern "C" {
27 #endif
28 
29 #ifdef _MSC_VER
30   /* Defines for VC++, not used for unix or mingw */
31   typedef __int32 int32_t;
32   typedef unsigned __int32 uint32_t;
33 #else
34 #  ifdef HAVE_STDINT_H
35 #    include <stdint.h>
36 #  else
37 #    include <sys/types.h>
38 #  endif
39 #endif
40 
41 #if defined(MAC) || defined(MAC_OSX_TCL)
42 #  include <string.h>
43 #endif
44 #if defined(MAC)
45 extern int strcasecmp (const char *str1, const char *str2);
46 extern int strncasecmp(const char *str1, const char *str2, size_t nchars);
47 #  define EXPORT(a,b) a b
48 #elif  defined(_MSC_VER)
49 #  include "windows.h"
50 #  include "mmsystem.h"
51 #  define strncasecmp strnicmp
52 #  define strcasecmp  stricmp
53 #  define EXPORT(a,b) __declspec(dllexport) a b
54 #else
55 #  define EXPORT(a,b) a b
56 #endif
57 
58 typedef void (updateProc)(ClientData clientData, int flag);
59 
60 typedef struct jkCallback {
61   updateProc *proc;
62   ClientData clientData;
63   struct jkCallback *next;
64   int id;
65 } jkCallback;
66 
67 typedef enum {
68   SNACK_NATIVE,
69   SNACK_BIGENDIAN,
70   SNACK_LITTLEENDIAN
71 } SnackEndianness;
72 
73 typedef struct SnackLinkedFileInfo {
74   Tcl_Channel linkCh;
75   float *buffer;
76   int filePos;
77   int validSamples;
78   int eof;
79   struct Sound *sound;
80 } SnackLinkedFileInfo;
81 
82 typedef struct Sound {
83   int    samprate;
84   int    encoding;
85   int    sampsize;
86   int    nchannels;
87   int    length;
88   int    maxlength;
89   float  maxsamp;
90   float  minsamp;
91   float  abmax;
92   float  **blocks;
93   int    maxblks;
94   int    nblks;
95   int    exact;
96   int    precision;
97   int    writeStatus;
98   int    readStatus;
99   short  *tmpbuf;
100   int    swap;
101   int    storeType;
102   int    headSize;
103   int    skipBytes;
104   int    buffersize;
105   Tcl_Interp     *interp;
106   Tcl_Obj        *cmdPtr;
107   char           *fcname;
108   struct jkCallback *firstCB;
109   char *fileType;
110   int blockingPlay;
111   int debug;
112   int destroy;
113   int guessEncoding;
114   Tcl_Channel rwchan;
115   int inByteOrder;
116   int firstNRead;
117   int guessRate;
118   int forceFormat;
119   int itemRefCnt;
120   int validStart;
121   SnackLinkedFileInfo linkInfo;
122   char *devStr;
123   Tcl_HashTable *soundTable;
124   char *filterName;
125   char *extHead;
126   char *extHead2;
127   int extHeadType;
128   int extHead2Type;
129   int loadOffset;
130   Tcl_Obj *changeCmdPtr;
131   unsigned int userFlag; /* User flags, for new file formats, etc */
132   char *userData;        /* User data pointer */
133 
134 } Sound;
135 
136 #define IDLE    0
137 #define READ    1
138 #define WRITE   2
139 #define PAUSED  3
140 
141 #ifndef _MSC_VER
142 #define min(a,b) ((a)<(b)?(a):(b))
143 #define max(a,b) ((a)>(b)?(a):(b))
144 #endif
145 
146 #define SNACK_NEW_SOUND	 1
147 #define SNACK_MORE_SOUND 2
148 #define SNACK_DESTROY_SOUND 3
149 
150 #define SNACK_SINGLE_PREC 1
151 #define SNACK_DOUBLE_PREC 2
152 
153 extern int Snack_SoundCmd(ClientData cdata, Tcl_Interp *interp,
154 			  int objc, Tcl_Obj *CONST objv[]);
155 
156 extern void Snack_SoundDeleteCmd(ClientData cdata);
157 
158 extern int Snack_AudioCmd(ClientData cdata, Tcl_Interp *interp,
159 			  int objc, Tcl_Obj *CONST objv[]);
160 
161 extern void Snack_AudioDeleteCmd(ClientData cdata);
162 
163 extern int Snack_MixerCmd(ClientData cdata, Tcl_Interp *interp, int objc,
164 			  Tcl_Obj *CONST objv[]);
165 
166 extern void Snack_MixerDeleteCmd(ClientData clientData);
167 
168 #define MAXNBLKS 200
169 #define FEXP 17
170 #define CEXP (FEXP+2)
171 #define DEXP (FEXP-1)
172 #define FBLKSIZE (1<<FEXP)
173 #define DBLKSIZE (1<<DEXP)
174 #define CBLKSIZE (1<<CEXP)
175 
176 #define FSAMPLE(s, i) (s)->blocks[(i)>>FEXP][((i)&(FBLKSIZE-1))]
177 #define DSAMPLE(s, i) ((double **)(s)->blocks)[(i)>>DEXP][((i)&(DBLKSIZE-1))]
178 
179 #define Snack_SetSample(s, c, i, val) \
180                  if ((s)->precision == SNACK_DOUBLE_PREC) { \
181                    DSAMPLE((s),(i)*(s)->nchannels+(c)) = (double) (val); \
182        	         } else { \
183 		   FSAMPLE((s),(i)*(s)->nchannels+(c)) = (float) (val); \
184 	         }
185 
186 #define Snack_GetSample(s, c, i) ( \
187  ((s)->precision == SNACK_DOUBLE_PREC) ? \
188      DSAMPLE((s), (i)*(s)->nchannels+(c)): \
189      FSAMPLE(s, (i)*(s)->nchannels+(c)))
190 
191 #define Snack_SetLength(s, len)        (s)->length = (len)
192 #define Snack_GetLength(s)             (s)->length
193 #define Snack_SetSampleRate(s, rate)   (s)->samprate = (rate)
194 #define Snack_GetSampleRate(s)         (s)->samprate
195 #define Snack_SetFrequency(s, rate)    (s)->samprate = (rate)
196 #define Snack_GetFrequency(s)          (s)->samprate
197 #define Snack_SetSampleEncoding(s, en) (s)->encoding = (en)
198 #define Snack_GetSampleEncoding(s)     (s)->encoding
199 #define Snack_SetSampleFormat(s, en)   (s)->encoding = (en)
200 #define Snack_GetSampleFormat(s)       (s)->encoding
201 #define Snack_SetNumChannels(s, nchan) (s)->nchannels = (nchan)
202 #define Snack_GetNumChannels(s)        (s)->nchannels
203 #define Snack_GetBytesPerSample(s)     (s)->sampsize
204 #define Snack_SetBytesPerSample(s, n)  (s)->sampsize = (n)
205 #define Snack_GetDebugFlag(s)          (s)->debug
206 #define Snack_SetHeaderSize(s, size)   (s)->headSize = (size)
207 #define Snack_GetSoundFilename(s)      (s)->fcname
208 #define Snack_GetSoundWriteStatus(s)   (s)->writeStatus
209 #define Snack_GetSoundReadStatus(s)    (s)->readStatus
210 #define Snack_GetSoundPrecision(s)     (s)->precision
211 
212 #define SOUND_IN_MEMORY 0
213 #define SOUND_IN_CHANNEL  1
214 #define SOUND_IN_FILE     2
215 /* NFIRSTSAMPLES*/
216 #define CHANNEL_HEADER_BUFFER 20000
217 
218 typedef int (soundCmd)(Sound *s, Tcl_Interp *interp, int objc,
219 		     Tcl_Obj *CONST objv[]);
220 typedef int (audioCmd)(Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
221 typedef int (mixerCmd)(Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
222 typedef void *Snack_CmdProc;
223 typedef void (soundDelCmd)(Sound *s);
224 typedef void (audioDelCmd)();
225 typedef void (mixerDelCmd)();
226 typedef void *Snack_DelCmdProc;
227 
228 #define SNACK_SOUND_CMD	1
229 #define SNACK_AUDIO_CMD	2
230 #define SNACK_MIXER_CMD	3
231 
232 #define HEADBUF 4096
233 
234 extern char *LoadSound(Sound *s, Tcl_Interp *interp, Tcl_Obj *obj,
235 		       int startpos, int endpos);
236 
237 extern int GetChannels(Tcl_Interp *interp, Tcl_Obj *obj, int *nchannels);
238 
239 extern int GetEncoding(Tcl_Interp *interp, Tcl_Obj *obj,
240 		       int *encoding, int *sampsize);
241 
242 extern float Snack_SwapFloat(float f);
243 
244 extern double Snack_SwapDouble(double d);
245 
246 extern void ByteSwapSound(Sound *s);
247 
248 extern void SwapIfBE(Sound *s);
249 
250 extern void SwapIfLE(Sound *s);
251 
252 extern int GetHeader(Sound *s, Tcl_Interp *interp, Tcl_Obj *obj);
253 
254 extern int PutHeader(Sound *s, Tcl_Interp *interp, int objc,
255 		     Tcl_Obj *CONST objv[], int length);
256 
257 extern int WriteLELong(Tcl_Channel ch, int32_t l);
258 
259 extern int WriteBELong(Tcl_Channel ch, int32_t l);
260 
261 extern int SetFcname(Sound *s, Tcl_Interp *interp, Tcl_Obj *obj);
262 
263 extern char *NameGuessFileType(char *s);
264 
265 extern void SnackDefineFileFormats(Tcl_Interp *interp);
266 
267 extern int GetFileFormat(Tcl_Interp *interp, Tcl_Obj *obj, char **filetype);
268 
269 extern void SnackCopySamples(Sound *dest, int to, Sound *src, int from,
270 			     int len);
271 
272 typedef char *(guessFileTypeProc)(char *buf, int len);
273 
274 typedef int  (getHeaderProc)(Sound *s, Tcl_Interp *interp, Tcl_Channel ch,
275 			     Tcl_Obj *obj, char *buf);
276 
277 typedef char *(extensionFileTypeProc)(char *buf);
278 
279 typedef int  (putHeaderProc)(Sound *s, Tcl_Interp *interp, Tcl_Channel ch,
280 			     Tcl_Obj *obj, int objc,
281 			     Tcl_Obj *CONST objv[], int length);
282 
283 typedef int  (openProc)(Sound *s, Tcl_Interp *interp,Tcl_Channel *ch,
284 			char *mode);
285 
286 typedef int  (closeProc)(Sound *s, Tcl_Interp *interp, Tcl_Channel *ch);
287 
288 typedef int  (readSamplesProc)(Sound *s, Tcl_Interp *interp, Tcl_Channel ch,
289 			       char *inBuffer, float *outBuffer, int length);
290 
291 typedef int  (writeSamplesProc)(Sound *s, Tcl_Channel ch, Tcl_Obj *obj,
292 				int start, int length);
293 
294 typedef int  (seekProc)(Sound *s, Tcl_Interp *interp, Tcl_Channel ch,
295 			int position);
296 
297 typedef void (freeHeaderProc)(Sound *s);
298 
299 typedef int  (configureProc)(Sound *s, Tcl_Interp *interp, int objc,
300 			     Tcl_Obj *CONST objv[]);
301 
302 /* Deprecated: SnackFileFormat */
303 
304 typedef struct SnackFileFormat {
305   char *formatName;
306   guessFileTypeProc      *guessProc;
307   getHeaderProc          *getHeaderProc;
308   extensionFileTypeProc  *extProc;
309   putHeaderProc          *putHeaderProc;
310   openProc               *openProc;
311   closeProc              *closeProc;
312   readSamplesProc        *readProc;
313   writeSamplesProc       *writeProc;
314   seekProc               *seekProc;
315   freeHeaderProc         *freeHeaderProc;
316   struct SnackFileFormat *nextPtr;
317 } SnackFileFormat;
318 
319 typedef struct Snack_FileFormat {
320   char                    *name;
321   guessFileTypeProc       *guessProc;
322   getHeaderProc           *getHeaderProc;
323   extensionFileTypeProc   *extProc;
324   putHeaderProc           *putHeaderProc;
325   openProc                *openProc;
326   closeProc               *closeProc;
327   readSamplesProc         *readProc;
328   writeSamplesProc        *writeProc;
329   seekProc                *seekProc;
330   freeHeaderProc          *freeHeaderProc;
331   configureProc           *configureProc;
332   struct Snack_FileFormat *nextPtr;
333 } Snack_FileFormat;
334 
335 extern int GuessEncoding(Sound *s, unsigned char *buf, int len);
336 
337 extern char *GuessFileType(char *buf, int len, int eof);
338 
339 extern int lengthCmd(Sound *s, Tcl_Interp *interp, int objc,
340 		     Tcl_Obj *CONST objv[]);
341 extern int insertCmd(Sound *s, Tcl_Interp *interp, int objc,
342 		     Tcl_Obj *CONST objv[]);
343 extern int cropCmd(Sound *s, Tcl_Interp *interp, int objc,
344 		   Tcl_Obj *CONST objv[]);
345 extern int copyCmd(Sound *s, Tcl_Interp *interp, int objc,
346 		   Tcl_Obj *CONST objv[]);
347 extern int appendCmd(Sound *s, Tcl_Interp *interp, int objc,
348 		     Tcl_Obj *CONST objv[]);
349 extern int concatenateCmd(Sound *s, Tcl_Interp *interp, int objc,
350 			  Tcl_Obj *CONST objv[]);
351 extern int cutCmd(Sound *s, Tcl_Interp *interp, int objc,
352 		  Tcl_Obj *CONST objv[]);
353 extern int convertCmd(Sound *s, Tcl_Interp *interp, int objc,
354 		      Tcl_Obj *CONST objv[]);
355 extern int dBPowerSpectrumCmd(Sound *s, Tcl_Interp *interp, int objc,
356 			      Tcl_Obj *CONST objv[]);
357 extern int powerSpectrumCmd(Sound *s, Tcl_Interp *interp, int objc,
358 			    Tcl_Obj *CONST objv[]);
359 extern int speaturesCmd(Sound *s, Tcl_Interp *interp, int objc,
360 			Tcl_Obj *CONST objv[]);
361 extern int alCmd(Sound *s, Tcl_Interp *interp, int objc,
362 		 Tcl_Obj *CONST objv[]);
363 extern int vpCmd(Sound *s, Tcl_Interp *interp, int objc,
364 		 Tcl_Obj *CONST objv[]);
365 extern int joinCmd(Sound *s, Tcl_Interp *interp, int objc,
366 		   Tcl_Obj *CONST objv[]);
367 extern int fitCmd(Sound *s, Tcl_Interp *interp, int objc,
368 		  Tcl_Obj *CONST objv[]);
369 extern int inaCmd(Sound *s, Tcl_Interp *interp, int objc,
370 		  Tcl_Obj *CONST objv[]);
371 extern int lastIndexCmd(Sound *s, Tcl_Interp *interp, int objc,
372 			Tcl_Obj *CONST objv[]);
373 extern int stretchCmd(Sound *s, Tcl_Interp *interp, int objc,
374 		      Tcl_Obj *CONST objv[]);
375 extern int ocCmd(Sound *s, Tcl_Interp *interp, int objc,
376 		 Tcl_Obj *CONST objv[]);
377 extern int arCmd(Sound *s, Tcl_Interp *interp, int objc,
378 		 Tcl_Obj *CONST objv[]);
379 extern int mixCmd(Sound *s, Tcl_Interp *interp, int objc,
380 		  Tcl_Obj *CONST objv[]);
381 extern int sampleCmd(Sound *s, Tcl_Interp *interp, int objc,
382 		     Tcl_Obj *CONST objv[]);
383 extern int flipBitsCmd(Sound *s, Tcl_Interp *interp, int objc,
384 		       Tcl_Obj *CONST objv[]);
385 extern int byteswapCmd(Sound *s, Tcl_Interp *interp, int objc,
386 		       Tcl_Obj *CONST objv[]);
387 extern int readCmd(Sound *s, Tcl_Interp *interp, int objc,
388 		   Tcl_Obj *CONST objv[]);
389 extern int writeCmd(Sound *s, Tcl_Interp *interp, int objc,
390 		    Tcl_Obj *CONST objv[]);
391 extern int dataCmd(Sound *s, Tcl_Interp *interp, int objc,
392 		   Tcl_Obj *CONST objv[]);
393 extern int playCmd(Sound *s, Tcl_Interp *interp, int objc,
394 		   Tcl_Obj *CONST objv[]);
395 extern int recordCmd(Sound *s, Tcl_Interp *interp, int objc,
396 		     Tcl_Obj *CONST objv[]);
397 extern int pauseCmd(Sound *s, Tcl_Interp *interp, int objc,
398 		    Tcl_Obj *CONST objv[]);
399 extern int stopCmd(Sound *s, Tcl_Interp *interp, int objc,
400 		   Tcl_Obj *CONST objv[]);
401 extern int current_positionCmd(Sound *s, Tcl_Interp *interp, int objc,
402 			       Tcl_Obj *CONST objv[]);
403 extern int swapCmd(Sound *s, Tcl_Interp *interp, int objc,
404 		   Tcl_Obj *CONST objv[]);
405 
406 #define QUE_STRING "QUE"
407 #define RAW_STRING "RAW"
408 #define WAV_STRING "WAV"
409 #define AIFF_STRING "AIFF"
410 #define SMP_STRING "SMP"
411 #define AU_STRING "AU"
412 #define SD_STRING "SD"
413 #define MP3_STRING "MP3"
414 #define CSL_STRING "CSL"
415 
416 extern char *GuessMP3File(char *buf, int len);
417 
418 extern int GetMP3Header(Sound *s, Tcl_Interp *interp, Tcl_Channel ch,
419 			Tcl_Obj *obj, char *buf);
420 
421 extern int ReadMP3Samples(Sound *s, Tcl_Interp *interp, Tcl_Channel ch,
422 			  char *ibuf, float *obuf, int len);
423 
424 extern int SeekMP3File(Sound *s, Tcl_Interp *interp, Tcl_Channel ch, int pos);
425 
426 extern char *ExtMP3File(char *s);
427 
428 extern int OpenMP3File(Sound *s, Tcl_Interp *interp, Tcl_Channel *ch,
429 		       char *mode);
430 
431 extern int CloseMP3File(Sound *s, Tcl_Interp *interp, Tcl_Channel *ch);
432 
433 extern void FreeMP3Header(Sound *s);
434 
435 extern int ConfigMP3Header(Sound *s, Tcl_Interp *interp, int objc,
436 			   Tcl_Obj *CONST objv[]);
437 
438 typedef enum {
439   SNACK_WIN_HAMMING,
440   SNACK_WIN_HANNING,
441   SNACK_WIN_BARTLETT,
442   SNACK_WIN_BLACKMAN,
443   SNACK_WIN_RECT
444 } SnackWindowType;
445 
446 extern int GetWindowType(Tcl_Interp *interp, char *str, SnackWindowType *type);
447 
448 extern int GetChannel(Tcl_Interp *interp, char *str, int nchannels,
449 		      int *channel);
450 
451 extern float LpcAnalysis(float *data, int N, float *f, int order);
452 
453 extern void PreEmphase(float *sig, float presample, int len, float preemph);
454 
455 extern double SnackCurrentTime();
456 
457 extern CONST84 char *Snack_InitStubs (Tcl_Interp *interp, char *version,
458 				      int exact);
459 
460 extern int pitchCmd(Sound *s, Tcl_Interp *interp, int objc,
461 		    Tcl_Obj *CONST objv[]);
462 
463 extern int powerCmd(Sound *s, Tcl_Interp *interp, int objc,
464 		    Tcl_Obj *CONST objv[]);
465 
466 extern int reverseCmd(Sound *s, Tcl_Interp *interp, int objc,
467 		      Tcl_Obj *CONST objv[]);
468 
469 extern int formantCmd(Sound *s, Tcl_Interp *interp, int objc,
470 		      Tcl_Obj *CONST objv[]);
471 
472 #define ITEMBUFFERSIZE 100000
473 
474 extern float GetSample(SnackLinkedFileInfo *infoPtr, int index);
475 
476 extern int OpenLinkedFile(Sound *s, SnackLinkedFileInfo *infoPtr);
477 
478 extern void CloseLinkedFile(SnackLinkedFileInfo *infoPtr);
479 
480 extern void Snack_ExitProc(ClientData clientData);
481 
482 typedef enum {
483   SNACK_QS_QUEUED = 0,
484   SNACK_QS_PAUSED,
485   SNACK_QS_DRAIN,
486   SNACK_QS_DONE
487 } queuedSoundStatus;
488 
489 typedef struct jkQueuedSound {
490   Sound *sound;
491   int startPos;
492   int endPos;
493   long nWritten;
494   long startTime;
495   Tcl_Obj *cmdPtr;
496   queuedSoundStatus status;
497   int duration;
498   char *name;
499   char *filterName;
500   int id;
501   struct jkQueuedSound *next;
502   struct jkQueuedSound *prev;
503 } jkQueuedSound;
504 
505 extern int shapeCmd(Sound *s, Tcl_Interp *interp, int objc,
506 		    Tcl_Obj *CONST objv[]);
507 
508 extern int dataSamplesCmd(Sound *s, Tcl_Interp *interp, int objc,
509 			  Tcl_Obj *CONST objv[]);
510 
511 extern int strcasecmp(const char *s1, const char *s2);
512 extern int strncasecmp(const char *s1, const char *s2, size_t n);
513 
514 extern int Snack_FilterCmd(ClientData cdata, Tcl_Interp *interp, int objc,
515 			   Tcl_Obj *CONST objv[]);
516 
517 extern void Snack_FilterDeleteCmd(ClientData clientData);
518 
519 typedef struct SnackFilter     *Snack_Filter;
520 typedef struct SnackStreamInfo *Snack_StreamInfo;
521 
522 typedef Snack_Filter (createProc)(Tcl_Interp *interp, int objc,
523 				    Tcl_Obj *CONST objv[]);
524 
525 typedef int (configProc)(Snack_Filter f, Tcl_Interp *interp, int objc,
526 			 Tcl_Obj *CONST objv[]);
527 
528 typedef int (startProc)(Snack_Filter f, Snack_StreamInfo si);
529 
530 typedef int (flowProc)(Snack_Filter f, Snack_StreamInfo si,
531 		       float *inBuffer, float *outBuffer,
532 		       int *inFrames, int *outFrames);
533 
534 typedef void (freeProc)(Snack_Filter f);
535 
536 typedef struct SnackStreamInfo {
537   Sound *is1;
538   Sound *is2;
539   Sound *os1;
540   Sound *os2;
541   int streamWidth;
542   int outWidth;
543   int rate;
544 } SnackStreamInfo;
545 
546 typedef struct SnackFilter {
547   configProc *configProc;
548   startProc  *startProc;
549   flowProc   *flowProc;
550   freeProc   *freeProc;
551   Tcl_Interp *interp;
552   Snack_Filter prev;
553   Snack_Filter next;
554   Snack_StreamInfo si;
555   double dataRatio;
556   int reserved[4];
557 } SnackFilter;
558 
559 typedef struct Snack_FilterType {
560   char               *name;
561   createProc         *createProc;
562   configProc         *configProc;
563   startProc          *startProc;
564   flowProc           *flowProc;
565   freeProc           *freeProc;
566   struct Snack_FilterType *nextPtr;
567 } Snack_FilterType;
568 
569 void SnackCreateFilterTypes(Tcl_Interp *interp);
570 
571 extern int Snack_HSetCmd(ClientData cdata, Tcl_Interp *interp, int objc,
572 			   Tcl_Obj *CONST objv[]);
573 
574 extern void Snack_HSetDeleteCmd(ClientData clientData);
575 
576 extern int Snack_arCmd(ClientData cdata, Tcl_Interp *interp, int objc,
577 			   Tcl_Obj *CONST objv[]);
578 
579 extern void Snack_arDeleteCmd(ClientData clientData);
580 
581 extern int isynCmd(ClientData cdata, Tcl_Interp *interp, int objc,
582 		   Tcl_Obj *CONST objv[]);
583 
584 extern int osynCmd(ClientData cdata, Tcl_Interp *interp, int objc,
585 		   Tcl_Obj *CONST objv[]);
586 
587 extern int WriteSound(writeSamplesProc *writeProc, Sound *s,
588 		      Tcl_Interp *interp, Tcl_Channel ch, Tcl_Obj *obj,
589 		      int startpos, int len);
590 
591 extern void Snack_RemoveOptions(int objc, Tcl_Obj *CONST objv[],
592 				CONST84 char **subOptionStrings, int *newobjc,
593 				Tcl_Obj **newobjv);
594 
595 #ifndef MAC
596 #  define PBSIZE 100000
597 #  define NMAX 65536
598 #else
599 #  define PBSIZE 64000
600 #  define NMAX 8192
601 #endif
602 #define NMIN 8
603 
604 extern void SnackPauseAudio();
605 
606 #if TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION < 4
607 #define TCL_SEEK Tcl_Seek
608 #define TCL_TELL Tcl_Tell
609 #else
610 #define TCL_SEEK Tcl_SeekOld
611 #define TCL_TELL Tcl_TellOld
612 #endif
613 
614 #define SNACK_DB 4.34294481903251830000000 /*  = 10 / ln(10)  */
615 #define SNACK_INTLOGARGMIN 1.0
616 #define SNACK_CORRN (float) 138.308998699
617 #define SNACK_CORR0 (float) 132.288396199
618 
619 /*
620  * Include the public function declarations that are accessible via
621  * the stubs table.
622  */
623 
624 #include "snackDecls.h"
625   /*
626 extern void Snack_StopSound(Sound *s, Tcl_Interp *interp);
627 extern Sound *Snack_GetSound(Tcl_Interp *interp, char *name);
628 extern int Snack_AddCallback(Sound *s, updateProc *proc, ClientData cd);
629 extern void Snack_WriteLog(char *str);
630 extern void Snack_WriteLogInt(char *str, int num);
631 extern void Snack_RemoveCallback(Sound *s, int id);
632 extern int Snack_ResizeSoundStorage(Sound *s, int len);
633 extern void Snack_UpdateExtremes(Sound *s, int start, int end, int flag);
634 extern int SnackOpenFile(openProc *openProc, Sound *s, Tcl_Interp *interp,
635 			 Tcl_Channel *ch, char *mode);
636 extern int SnackCloseFile(closeProc *closeProc, Sound *s, Tcl_Interp *interp,
637 			  Tcl_Channel *ch);
638 extern void Snack_ExecCallbacks(Sound *s, int flag);
639 extern short Snack_SwapShort(short s);
640 extern int32_t Snack_SwapLong(int32_t l);
641 extern int Snack_ProgressCallback(Tcl_Obj *cmdPtr, Tcl_Interp *interp,
642 				  char *type, double fraction);
643 extern void Snack_DeleteSound(Sound *s);
644 extern Sound *Snack_NewSound(int rate, int encoding, int nchannels);
645 extern short Snack_Mulaw2Lin(unsigned char u_val);
646 extern unsigned char Snack_Lin2Mulaw(short pcm_val);
647 extern short Snack_Alaw2Lin(unsigned char a_val);
648 extern unsigned char Snack_Lin2Alaw(short pcm_val);
649 extern void Snack_PutSoundData(Sound *s, int pos, void *buf, int nSamples);
650 extern void Snack_GetSoundData(Sound *s, int pos, void *buf, int nSamples);
651 extern void Snack_InitWindow(float *win, int winlen, int fftlen, int type);
652 extern int  Snack_InitFFT(int n);
653 extern void Snack_DBPowerSpectrum(float *x);
654 extern void Snack_PowerSpectrum(float *x);
655 extern void Snack_CreateFilterType(Snack_FilterType *typePtr);
656 extern int SaveSound(Sound *s, Tcl_Interp *interp, char *filename,
657 		     Tcl_Obj *obj, int objc, Tcl_Obj *CONST objv[],
658 		     int startpos, int len, char *type);
659   */
660 #ifdef __cplusplus
661 }
662 #endif
663 
664 #endif /* _SNACK_SOUND */
665