Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

297 lines
7.6 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1998 - 1999
  6. //
  7. // File: gen-wav.c
  8. //
  9. //--------------------------------------------------------------------------
  10. #include "stdio.h"
  11. #include "stdlib.h"
  12. #include "windows.h"
  13. // #include "ntddk.h"
  14. //
  15. // MAX is defined to prevent overflow errors
  16. // floor( (0xffffffff - 54)/(4*44100) )
  17. //
  18. #define MAX_SECONDS 24347
  19. #define SAMPLE_STEP 1
  20. VOID
  21. __cdecl
  22. WriteIncreasingSawTooth(
  23. FILE * OutFile,
  24. ULONG32 NumberOfSeconds
  25. )
  26. {
  27. ULONG32 i;
  28. ULONG32 currentSample = 0;
  29. ULONG32 samples = 44100 * NumberOfSeconds;
  30. for ( i = 0; i < samples; i++ ) {
  31. putc( (currentSample >> 0) & 0xff, OutFile );
  32. putc( (currentSample >> 8) & 0xff, OutFile );
  33. putc( (currentSample >> 0) & 0xff, OutFile );
  34. putc( (currentSample >> 8) & 0xff, OutFile );
  35. currentSample += SAMPLE_STEP;
  36. }
  37. }
  38. VOID
  39. __cdecl
  40. WriteDecreasingSawTooth(
  41. FILE * OutFile,
  42. ULONG32 NumberOfSeconds
  43. )
  44. {
  45. ULONG32 i;
  46. ULONG32 currentSample = 0;
  47. ULONG32 samples = 44100 * NumberOfSeconds;
  48. for ( i = 0; i < samples; i++ ) {
  49. putc( (currentSample >> 0) & 0xff, OutFile );
  50. putc( (currentSample >> 8) & 0xff, OutFile );
  51. putc( (currentSample >> 0) & 0xff, OutFile );
  52. putc( (currentSample >> 8) & 0xff, OutFile );
  53. currentSample -= SAMPLE_STEP;
  54. }
  55. }
  56. VOID
  57. __cdecl
  58. WriteTriangle(
  59. FILE * OutFile,
  60. ULONG32 NumberOfSeconds
  61. )
  62. {
  63. ULONG32 i;
  64. ULONG32 samples = 44100 * NumberOfSeconds;
  65. ULONG32 increasing = TRUE;
  66. LONG32 currentSample = 0;
  67. LONG32 highestSample = 0x00007fff - SAMPLE_STEP + 1;
  68. LONG32 lowestSample = 0xffff8000 + SAMPLE_STEP - 1;
  69. for ( i = 0; i < samples; i++ ) {
  70. putc( (currentSample >> 0) & 0xff, OutFile );
  71. putc( (currentSample >> 8) & 0xff, OutFile );
  72. putc( (currentSample >> 0) & 0xff, OutFile );
  73. putc( (currentSample >> 8) & 0xff, OutFile );
  74. if ( increasing == TRUE &&
  75. currentSample >= highestSample
  76. ) {
  77. increasing = FALSE;
  78. }
  79. if ( increasing == FALSE &&
  80. currentSample <= lowestSample
  81. ) {
  82. increasing = TRUE;
  83. }
  84. if ( increasing == TRUE ) {
  85. currentSample += SAMPLE_STEP;
  86. } else {
  87. currentSample -= SAMPLE_STEP;
  88. }
  89. }
  90. }
  91. VOID
  92. __cdecl
  93. WriteHeader(
  94. FILE * OutFile,
  95. ULONG32 NumberOfSeconds
  96. )
  97. {
  98. unsigned char header[] = {
  99. 0x52, 0x49, 0x46, 0x46, 0x00, 0x00, 0x00, 0x00, // 0- 7
  100. 0x57, 0x41, 0x56, 0x45, 0x66, 0x6D, 0x74, 0x20, // 8-15
  101. 0x12, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, // 16-23
  102. 0x44, 0xAC, 0x00, 0x00, 0x10, 0xB1, 0x02, 0x00, // 24-31
  103. 0x04, 0x00, 0x10, 0x00, 0x00, 0x00, 0x66, 0x61, // 32-39
  104. 0x63, 0x74, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, // 40-47
  105. 0x00, 0x00, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, // 48-55
  106. 0x00, 0x00 // 56-57 (length 58)
  107. };
  108. ULONG32 length;
  109. ULONG32 samples;
  110. ULONG32 other;
  111. ULONG32 i;
  112. //
  113. // setup the variable header info
  114. //
  115. // samples = 44100 * NumberOfSeconds
  116. // other = (samples * 4) + 8
  117. // length = other + 54
  118. samples = 44100 * NumberOfSeconds + 1; // one extra sample?
  119. other = ((44100 * NumberOfSeconds + 1) * 4) + 4;
  120. length = (((44100 * NumberOfSeconds + 1) * 4) + 4) + 50;
  121. //
  122. // Fill it in
  123. //
  124. header[4] = (length >> 0) & 0xff;
  125. header[5] = (length >> 8) & 0xff;
  126. header[6] = (length >> 16) & 0xff;
  127. header[7] = (length >> 24) & 0xff;
  128. header[46] = (samples >> 0) & 0xff;
  129. header[47] = (samples >> 8) & 0xff;
  130. header[48] = (samples >> 16) & 0xff;
  131. header[49] = (samples >> 24) & 0xff;
  132. header[54] = (other >> 0) & 0xff;
  133. header[55] = (other >> 8) & 0xff;
  134. header[56] = (other >> 16) & 0xff;
  135. header[57] = (other >> 24) & 0xff;
  136. for ( i = 0; i < sizeof(header); i++ ) {
  137. fprintf( OutFile, "%c", header[i] );
  138. }
  139. }
  140. /* 02b3c146
  141. The header to a WAV file is as follows:
  142. 52 49 46 46 XX XX XX XX-57 41 56 45 66 6D 74 20
  143. 12 00 00 00 01 00 02 00-44 AC 00 00 10 B1 02 00
  144. 04 00 10 00 00 00 66 61-63 74 04 00 00 00 YY YY
  145. YY YY 64 61 74 61 ZZ ZZ-ZZ ZZ
  146. XX XX XX XX YY YY YY YY ZZ ZZ ZZ ZZ
  147. --------------------------------------------------------------
  148. 1 = 46 b1 02 00 44 ac 00 00 14 b1 02 00 (0x2b110* +4)
  149. 2 = 56 62 05 00 88 58 01 00 24 62 05 00 (0x2b110* +4)
  150. 267 = 46 c1 b3 02 44 f0 ac 00 14 c1 b3 02 (0x2b110* +4)
  151. X = (length - 4) in reverse-byte order
  152. (eight is number of bytes including this part of the struct)
  153. Y = number of samples (0xac44 == 44100 == 1 second)
  154. Z = (# of seconds) * 0x02b1
  155. */
  156. VOID
  157. __inline
  158. WriteFooter(
  159. FILE * OutFile
  160. )
  161. {
  162. printf( "writing the footer\n" );
  163. putc( 0x50, OutFile );
  164. putc( 0xB5, OutFile );
  165. putc( 0x50, OutFile );
  166. putc( 0xB5, OutFile );
  167. putc( 0x00, OutFile );
  168. putc( 0x00, OutFile );
  169. putc( 0x00, OutFile );
  170. putc( 0x00, OutFile );
  171. }
  172. VOID
  173. __cdecl
  174. main(
  175. int Argc,
  176. char ** Argv
  177. )
  178. {
  179. FILE * outFile;
  180. ULONG32 seconds;
  181. ULONG32 wavType = 1;
  182. CHAR fileName[256];
  183. if ( Argc > 1 ) {
  184. //
  185. // try to get number seconds they want audio
  186. //
  187. seconds = atoi( Argv[1] );
  188. if ( Argc > 2 ) {
  189. //
  190. // get the type of wavform
  191. //
  192. wavType = atoi( Argv[2] );
  193. }
  194. }
  195. if ( Argc < 2 ||
  196. Argc > 3 ||
  197. strcmp(Argv[1], "-?") == 0 ||
  198. strcmp(Argv[1], "-h") == 0 ||
  199. seconds > MAX_SECONDS ||
  200. wavType < 1 ||
  201. wavType > 3 ) {
  202. //
  203. // give usage help
  204. //
  205. printf( "\nUsage: %s seconds [wavtype]\n"
  206. "\tseconds must be a positive integer\n"
  207. "\tless than %d (prevents overflow)\n"
  208. "\twavtype can be one of three integers:\n"
  209. "\t\t1: increasing sawtooth (default)\n"
  210. "\t\t2: decreasing sawtooth\n"
  211. "\t\t3: triangular wav\n"
  212. "\n"
  213. , Argv[0]
  214. , MAX_SECONDS
  215. );
  216. exit(1);
  217. }
  218. switch( wavType ) {
  219. case 1:
  220. sprintf( fileName, "increase-%d.wav", seconds );
  221. printf( "Requesting %d seconds of increasing sawtooth wav output\n", seconds );
  222. outFile = fopen( fileName, "wb" );
  223. WriteHeader( outFile, seconds );
  224. WriteIncreasingSawTooth( outFile, seconds );
  225. WriteFooter( outFile );
  226. break;
  227. case 2:
  228. sprintf( fileName, "decrease-%d.wav", seconds );
  229. printf( "Requesting %d seconds of decreasing sawtooth wav output\n", seconds );
  230. outFile = fopen( fileName, "wb" );
  231. WriteHeader( outFile, seconds );
  232. WriteDecreasingSawTooth( outFile, seconds );
  233. WriteFooter( outFile );
  234. break;
  235. case 3:
  236. sprintf( fileName, "triangle-%d.wav", seconds );
  237. printf( "Requesting %d seconds of triangle wav output\n", seconds );
  238. outFile = fopen( fileName, "wb" );
  239. WriteHeader( outFile, seconds );
  240. WriteTriangle( outFile, seconds );
  241. WriteFooter( outFile );
  242. break;
  243. default:
  244. break;
  245. }
  246. exit(0);
  247. }