portsf.h 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. /* Copyright (c) 2009, 2014 Richard Dobson
  2. Permission is hereby granted, free of charge, to any person
  3. obtaining a copy of this software and associated documentation
  4. files (the "Software"), to deal in the Software without
  5. restriction, including without limitation the rights to use,
  6. copy, modify, merge, publish, distribute, sublicense, and/or sell
  7. copies of the Software, and to permit persons to whom the
  8. Software is furnished to do so, subject to the following
  9. conditions:
  10. The above copyright notice and this permission notice shall be
  11. included in all copies or substantial portions of the Software.
  12. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  13. EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  14. OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  15. NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  16. HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  17. WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  18. FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  19. OTHER DEALINGS IN THE SOFTWARE.
  20. */
  21. /* POST_BOOK!*/
  22. /* RWD Oct 2009: added MC_CUBE to listy of supported speaker layouts */
  23. /* corrected 7.1 speaker value (hex) */
  24. /* Aug 2012 corrected SPKRS_MONO value */
  25. /* Nov 2013: added SPKRS_6_1 and MC_SURR_6_1 to list */
  26. #ifndef __RIFFWAV_H_INCLUDED
  27. #define __RIFFWAV_H_INCLUDED
  28. /* Revision 16th September 2003: added TPDF dither support */
  29. /* revision Dec 2005: support new B-Format extensions */
  30. /* RWD Nov 1 2006: extended with double sread/write for research purposes! */
  31. /* July 2009: attempt portability with 64bit platforms */
  32. /* unable to test Win64 yet - but the symbol to check is simply _WIN64 */
  33. #ifdef __GNUC__
  34. # ifdef __LP64__
  35. # define CPLONG64
  36. # endif
  37. #endif
  38. /* failing that, manually define CPLONG64 in makefile or project setting */
  39. #ifdef CPLONG64
  40. // all this effort is for readPeaks() and ctime only!
  41. # define MYLONG int
  42. #else
  43. # define MYLONG long
  44. #endif
  45. #ifdef __cplusplus
  46. extern "C" {
  47. #endif
  48. /* compatible with <windows.h> */
  49. #ifndef DWORD
  50. typedef unsigned MYLONG DWORD;
  51. typedef unsigned short WORD;
  52. #endif
  53. /* NB: AIFF spec always illustrates chunksize as (signed) long;
  54. even though nFrames is always unsigned long!
  55. So we make everything DWORD here.
  56. */
  57. /* the file sample formats we could support */
  58. typedef enum {
  59. PSF_SAMP_UNKNOWN = 0,
  60. PSF_SAMP_8, /* not yet supported! */
  61. PSF_SAMP_16,
  62. PSF_SAMP_24,
  63. PSF_SAMP_32,
  64. PSF_SAMP_IEEE_FLOAT
  65. } psf_stype;
  66. /* the file format */
  67. /* currently based only on file extension.
  68. To be friendly, we should parse the header to get the format.
  69. */
  70. typedef enum {
  71. PSF_FMT_UNKNOWN = 0, /* e.g if no extension given. This could also signify 'raw' */
  72. PSF_STDWAVE,
  73. PSF_WAVE_EX,
  74. PSF_AIFF,
  75. PSF_AIFC
  76. } psf_format;
  77. /* provisional stab at error codes */
  78. enum {
  79. PSF_E_NOERROR = 0,
  80. PSF_E_CANT_OPEN = -1,
  81. PSF_E_CANT_CLOSE = -2,
  82. PSF_E_CANT_WRITE = -3,
  83. PSF_E_CANT_READ = -4,
  84. PSF_E_NOT_WAVE = -5,
  85. PSF_E_BAD_TYPE = -6,
  86. PSF_E_BAD_FORMAT = -7,
  87. PSF_E_UNSUPPORTED = -8,
  88. PSF_E_NOMEM = -9,
  89. PSF_E_BADARG = -10,
  90. PSF_E_CANT_SEEK = -11,
  91. PSF_E_TOOMANYFILES = -12,
  92. PSF_E_FILE_READONLY = -13,
  93. PSF_E_SEEK_BEYOND_EOF = -14
  94. };
  95. #define NUM_SPEAKER_POSITIONS (18)
  96. #define SPEAKER_FRONT_LEFT 0x1
  97. #define SPEAKER_FRONT_RIGHT 0x2
  98. #define SPEAKER_FRONT_CENTER 0x4
  99. #define SPEAKER_LOW_FREQUENCY 0x8
  100. #define SPEAKER_BACK_LEFT 0x10
  101. #define SPEAKER_BACK_RIGHT 0x20
  102. #define SPEAKER_FRONT_LEFT_OF_CENTER 0x40
  103. #define SPEAKER_FRONT_RIGHT_OF_CENTER 0x80
  104. #define SPEAKER_BACK_CENTER 0x100
  105. #define SPEAKER_SIDE_LEFT 0x200
  106. #define SPEAKER_SIDE_RIGHT 0x400
  107. #define SPEAKER_TOP_CENTER 0x800
  108. #define SPEAKER_TOP_FRONT_LEFT 0x1000
  109. #define SPEAKER_TOP_FRONT_CENTER 0x2000
  110. #define SPEAKER_TOP_FRONT_RIGHT 0x4000
  111. #define SPEAKER_TOP_BACK_LEFT 0x8000
  112. #define SPEAKER_TOP_BACK_CENTER 0x10000
  113. #define SPEAKER_TOP_BACK_RIGHT 0x20000
  114. /* RWD 2022 use latest version from MS */
  115. #define SPEAKER_RESERVED 0x7FFC0000
  116. #define SPEAKER_ALL 0x80000000
  117. /* my extras*/
  118. #define SPKRS_UNASSIGNED (0)
  119. #define SPKRS_MONO (0x00000004)
  120. #define SPKRS_STEREO (0x00000003)
  121. #define SPKRS_GENERIC_QUAD (0x00000033)
  122. #define SPKRS_SURROUND_LCRS (0x00000107)
  123. #define SPKRS_SURR_5_0 (0x00000037)
  124. #define SPKRS_DOLBY5_1 (0x0000003f)
  125. #define SPKRS_6_1 (0x0000013f)
  126. #define SPKRS_7_1 (0x000000ff)
  127. #define SPKRS_CUBE (SPKRS_GENERIC_QUAD | SPEAKER_TOP_FRONT_LEFT | SPEAKER_TOP_FRONT_RIGHT | SPEAKER_TOP_BACK_LEFT | SPEAKER_TOP_BACK_RIGHT)
  128. #define SPKRS_ACCEPT_ALL (0xffffffff) /*???? no use for a file*/
  129. /* support for the PEAK chunk */
  130. typedef struct psf_chpeak {
  131. float val;
  132. DWORD pos; /* OK for all WAVE and AIFF <= 4GB */
  133. } PSF_CHPEAK;
  134. /* second two are speculative at present! */
  135. typedef enum {PSF_CREATE_RDWR,PSF_CREATE_TEMPORARY,PSF_CREATE_WRONLY} psf_create_mode;
  136. /* the speakerfeed format */
  137. /* MC_WAVE_EX is a possibly temporary one to cover abstruse infile formats! */
  138. typedef enum { STDWAVE,MC_STD,MC_MONO,MC_STEREO,MC_QUAD,MC_LCRS,MC_BFMT,MC_DOLBY_5_1,
  139. MC_SURR_5_0,MC_SURR_6_1,MC_SURR_7_1,MC_CUBE,MC_WAVE_EX } psf_channelformat;
  140. /* read access support */
  141. /* for psf_sndSeek(); ~should~ map directly to fseek mode flags*/
  142. enum { PSF_SEEK_SET=0,PSF_SEEK_CUR,PSF_SEEK_END};
  143. enum {PSF_DITHER_OFF,PSF_DITHER_TPDF};
  144. /* main structure to define a soundile. Extended props must be asked for separately */
  145. typedef struct psf_props
  146. {
  147. int srate;
  148. int chans;
  149. psf_stype samptype;
  150. psf_format format;
  151. psf_channelformat chformat;
  152. /* probably add more stuff...esp for full WAVE-EX support */
  153. } PSF_PROPS;
  154. /*************** PUBLIC FUNCS */
  155. /* init sfs system. return 0 for success */
  156. int psf_init(void);
  157. /* close sfs-system. Does auto cleanup of open files, etc. return 0 for success */
  158. int psf_finish(void);
  159. /* Create soundfile from props.
  160. Supports clipping or non-clipping of floats to 0dbFS,
  161. set minimum header (or use PEAK)
  162. returns Sf descriptor >= 0, or some PSF_E_* on error.
  163. */
  164. /* using WIN32, it is possible to share for reading, but not under ANSI */
  165. /* maybe we just abandon all that */
  166. /* TODO (?): enforce non-destructive creation */
  167. int psf_sndCreate(const char *path,const PSF_PROPS *props, int clip_floats,int minheader,int mode);
  168. /* open existing soundfile. Receive format info in props. Supports auto rescale from PEAK
  169. data, with floats files. Only RDONLY access supported.
  170. Return sf descriptor >= 0, or some PSF_E_+ on error.
  171. */
  172. int psf_sndOpen(const char *path,PSF_PROPS *props, int rescale);
  173. /*snd close. Updates PEAK data if used. return 0 for success, or some PSF_E_+ on error.*/
  174. int psf_sndClose(int sfd);
  175. /* all data read/write is counted in multi-channel sample 'frames', NOT in raw samples.*/
  176. /* get size of file, in m/c frames. Return size, or PSF_E_BADARG on bad sfd */
  177. int psf_sndSize(int sfd);
  178. /* write m/c frames of floats. this updates internal PEAK data automatically.
  179. return num frames written, or some PSF_E_* on error.
  180. */
  181. int psf_sndWriteFloatFrames(int sfd, const float *buf, DWORD nFrames);
  182. int psf_sndWriteDoubleFrames(int sfd, const double *buf, DWORD nFrames);
  183. /* as above, with 16bit data */
  184. int psf_sndWriteShortFrames(int sfd, const short *buf, DWORD nFrames);
  185. /* get current m/c frame position in file, or PSF_E_BADARG with bad sfd*/
  186. int psf_sndTell(int sfd);
  187. /* m/c frame wrapper for stdio fseek. return 0 for success. Offset counted in m/c frames.
  188. seekmode must be one of PSF_SEEK_* options, to ensure correct mapping to SEEK_CUR, etc */
  189. int psf_sndSeek(int sfd,int offset,int seekmode);
  190. /* read m/c sample frames into floats buffer. return nFrames, or some PSF_E_*.
  191. if file opened with rescale = 1, over-range floats data, as indicated by PEAK chunk,
  192. is automatically scaled to 0dbFS.
  193. NB we could add a facility to define 'headroom', as some level below 0dBFS.
  194. */
  195. int psf_sndReadFloatFrames(int sfd, float *buf, DWORD nFrames);
  196. int psf_sndReadDoubleFrames(int sfd, double *buf, DWORD nFrames);
  197. /* can add ReadShortFrames if we really need it! */
  198. int psf_sndReadPeaks(int sfd,PSF_CHPEAK peakdata[],MYLONG *peaktime);
  199. /* find the soundfile format from the filename extension */
  200. /* currently supported: .wav, .aif, .aiff,.aifc,.afc, .amb */
  201. psf_format psf_getFormatExt(const char *path);
  202. /* set/unset dither.
  203. Returns 0 on success, -1 if error (unrecognised type, or read-only)
  204. no-op for input files
  205. */
  206. int psf_sndSetDither(int sfd,unsigned int dtype);
  207. /* get current dither setting */
  208. int psf_sndGetDither(int sfd);
  209. /* RWD NEW Nov 2009 */
  210. int psf_speakermask(int sfd);
  211. /* Feb 2010 */
  212. int psf_getWarning(int sfd,const char** warnstring);
  213. /* Sept 2010 return 1 for true, 0 for false */
  214. /* NB tests up to 32bit size for now! */
  215. int is_legalsize(unsigned long nFrames, const PSF_PROPS *props);
  216. #ifdef __cplusplus
  217. }
  218. #endif
  219. #endif