Browse Source

changes for version 5.0, which haven't been tracked

- added portaudio support
- fixed several compile warnings
- added debian packaging
- added support for compiling using MXE
master
Sven Oliver Moll 1 month ago
parent
commit
2594c09923
19 changed files with 1625 additions and 1031 deletions
  1. 16
    6
      Makefile
  2. 26
    0
      Makefile.mxe
  3. 12
    0
      README.md
  4. 5
    0
      debian/changelog
  5. 1
    0
      debian/compat
  6. 16
    0
      debian/control
  7. 11
    0
      debian/copyright
  8. 1
    0
      debian/docs
  9. 1
    0
      debian/install
  10. 19
    0
      debian/rules
  11. 1
    0
      debian/source/format
  12. 1102
    948
      makewav.c
  13. 73
    75
      makewav.h
  14. 32
    2
      makewav.txt
  15. 253
    0
      paplay.c
  16. 7
    0
      paplay.h
  17. 33
    0
      streambuffer.c
  18. 13
    0
      streambuffer.h
  19. 3
    0
      version.h

+ 16
- 6
Makefile View File

@@ -1,9 +1,19 @@
1
-.SUFFIXES: .exe .o .c .pc
2 1
 
3
-all:makewav
2
+PROGRAM = makewav
4 3
 
5
-queue.o:
6
-	gcc -c queue.c
4
+CC = gcc
5
+CFLAGS = -Os -g -Wall
6
+#CFLAGS = -g -Wall
7
+LDFLAGS = -lm -lportaudio
8
+
9
+all: $(PROGRAM)
10
+
11
+%.o: %.c
12
+	$(CC) $(CFLAGS) -c -o $@ $^
13
+
14
+$(PROGRAM): queue.o makewav.o paplay.o streambuffer.o
15
+	$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
16
+
17
+clean:
18
+	rm -f $(PROGRAM) *.o
7 19
 
8
-makewav: queue.o
9
-	gcc -lm -DLINUX -O queue.o -o makewav makewav.c

+ 26
- 0
Makefile.mxe View File

@@ -0,0 +1,26 @@
1
+
2
+PROGRAM    := makewav.exe
3
+
4
+MXE_DIR    := /opt/mxe
5
+MXE_TARGET := i686-w64-mingw32.static
6
+
7
+CC         := $(MXE_DIR)/usr/bin/$(MXE_TARGET)-gcc
8
+STRIP      := $(MXE_DIR)/usr/bin/$(MXE_TARGET)-strip
9
+CFLAGS     := -Os
10
+#CFLAGS     := -g -Wall
11
+LDFLAGS    := -lm -lportaudio -lwinmm -lsetupapi -lhid -lole32
12
+
13
+all: $(PROGRAM)
14
+
15
+%.o: %.c
16
+	$(CC) $(CFLAGS) -c -o $@ $^
17
+
18
+$(PROGRAM): queue.o makewav.o paplay.o streambuffer.o
19
+	$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
20
+	$(STRIP) $@
21
+	upx --ultra-brute $@ || :
22
+	ls -l $@
23
+
24
+clean:
25
+	rm -f $(PROGRAM) *.o
26
+

+ 12
- 0
README.md View File

@@ -0,0 +1,12 @@
1
+# Makewav 5.0
2
+
3
+Makewav converts ROM image files for the Atari 2600 VCS into
4
+.wav-files or plays them directly.
5
+
6
+## typical usage
7
+```
8
+makewav -l                                       # to get name of sound card
9
+makewav -a <name_of_soundcard> -tc <romfile.bin> # for Cuttle Cart
10
+makewav -a <name_of_soundcard> -ts <romfile.bin> # for SuperCharger
11
+```
12
+

+ 5
- 0
debian/changelog View File

@@ -0,0 +1,5 @@
1
+makewav (5.0) unstable; urgency=medium
2
+
3
+  * Initial release
4
+
5
+ -- Sven Oliver Moll <svolli@svol.li>  Thu, 21 Sep 2017 18:48:05 +0200

+ 1
- 0
debian/compat View File

@@ -0,0 +1 @@
1
+9

+ 16
- 0
debian/control View File

@@ -0,0 +1,16 @@
1
+Source: makewav
2
+Section: otherosfs
3
+Priority: optional
4
+Maintainer: Sven Oliver Moll <svolli@svol.li>
5
+Build-Depends: debhelper (>= 9), portaudio19-dev
6
+Standards-Version: 3.9.8
7
+Homepage: https://xayax.net/tools/makewav/
8
+
9
+Package: makewav
10
+Architecture: any
11
+Depends: ${shlibs:Depends}, ${misc:Depends}
12
+Description: Tool for Atari 2600 VCS SuperCharger/CuttleCart
13
+ makewav generates a wave file for the Atari 2600 VCS cartridges
14
+ SuperCharger and CuttleCart. These are modules that use audio data
15
+ (originally played from tape) as mass storage. This version can
16
+ also play the data directly.

+ 11
- 0
debian/copyright View File

@@ -0,0 +1,11 @@
1
+        Now for the boring stuff:  I hereby place this program into the
2
+public domain.  I am not responsible for any damage this program may cause.
3
+I am not liable for any misuse, intentional or otherwise, of this program.
4
+There is no warranty, written or implied, on this program.  The user uses
5
+this program at his or her own risk!
6
+
7
+                                
8
+                                        Bob Colbert
9
+                                        CEO of RetroWare
10
+                                        rcolbert@oasis.novia.net
11
+                                        http://www.novia.net/~rcolbert

+ 1
- 0
debian/docs View File

@@ -0,0 +1 @@
1
+makewav.txt

+ 1
- 0
debian/install View File

@@ -0,0 +1 @@
1
+makewav usr/bin

+ 19
- 0
debian/rules View File

@@ -0,0 +1,19 @@
1
+#!/usr/bin/make -f
2
+# See debhelper(7) (uncomment to enable)
3
+# output every command that modifies files on the build system.
4
+#export DH_VERBOSE = 1
5
+
6
+
7
+# see FEATURE AREAS in dpkg-buildflags(1)
8
+export DEB_BUILD_MAINT_OPTIONS = hardening=+all
9
+
10
+# see ENVIRONMENT in dpkg-buildflags(1)
11
+# package maintainers to append CFLAGS
12
+#export DEB_CFLAGS_MAINT_APPEND  = -Wall -pedantic
13
+# package maintainers to append LDFLAGS
14
+#export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed
15
+
16
+
17
+%:
18
+	dh $@
19
+

+ 1
- 0
debian/source/format View File

@@ -0,0 +1 @@
1
+3.0 (native)

+ 1102
- 948
makewav.c
File diff suppressed because it is too large
View File


+ 73
- 75
makewav.h View File

@@ -1,16 +1,16 @@
1 1
 #define BSM_2K       0
2 2
 #define BSM_CV       1
3 3
 #define BSM_4K       2
4
-#define BSM_28SC	 3
4
+#define BSM_28SC     3
5 5
 #define BSM_F8SC     4
6
-#define BSM_28		 5
6
+#define BSM_28         5
7 7
 #define BSM_F8       6
8 8
 #define BSM_FE       7
9 9
 #define BSM_3F       8
10 10
 #define BSM_E0       9
11
-#define BSM_FA	    10
12
-#define BSM_2A	    11
13
-#define BSM_3A	    12
11
+#define BSM_FA        10
12
+#define BSM_2A        11
13
+#define BSM_3A        12
14 14
 #define BSM_FANR    13
15 15
 #define BSM_2ANR    14
16 16
 #define BSM_3ANR    15
@@ -28,10 +28,10 @@
28 28
 #define BSM_24SC    27
29 29
 #define BSM_34SC    28
30 30
 #define BSM_44SC    29
31
-#define BSM_F4	    30
32
-#define BSM_24		31
33
-#define BSM_34		32
34
-#define BSM_44		33
31
+#define BSM_F4        30
32
+#define BSM_24        31
33
+#define BSM_34        32
34
+#define BSM_44        33
35 35
 #define BSM_MB      34
36 36
 #define FMT_22KHZ_8BIT_MONO 0
37 37
 #define FMT_44KHZ_8BIT_MONO 1
@@ -44,15 +44,11 @@
44 44
 #define DISPLAY_SUMMARY  2
45 45
 #define DISPLAY_DETAILS  3
46 46
 
47
-#ifdef __linux__
48
-    #define _MAX_FNAME 256
49
-    #define _MAX_PATH  256
50
-    #define _MAX_DIR   256
51
-    #define _MAX_DRIVE 256
52
-    #define _MAX_EXT   256
53
-#else
54
-    #include "find.h"
55
-#endif
47
+#define _MAX_FNAME 256
48
+#define _MAX_PATH  256
49
+#define _MAX_DIR   256
50
+#define _MAX_DRIVE 256
51
+#define _MAX_EXT   256
56 52
 
57 53
 typedef unsigned long int   dd;
58 54
 typedef unsigned short int  dw;
@@ -61,6 +57,7 @@ typedef int                 db;
61 57
 
62 58
 struct parmFlags
63 59
 {
60
+    int     aflag;
64 61
     int     dflag;
65 62
     int     fflag;
66 63
     int     kflag;
@@ -80,8 +77,9 @@ struct parmFlags
80 77
     float   headerSeconds;
81 78
     float   clearingSeconds;
82 79
     float   hlength;
83
-    char    wavFileName[_MAX_FNAME];
80
+    char    wavFileName[_MAX_FNAME+5];
84 81
     char    fullPath[_MAX_PATH];
82
+    char    *audioDevName;
85 83
 
86 84
     struct   qnode *binFileQ;
87 85
     unsigned int  multi;
@@ -91,38 +89,38 @@ struct parmFlags
91 89
 };
92 90
 
93 91
 char bankSwitchList[][5] =
94
-    {"2K",  "CV",   "4K",	"28SC", "F8SC",	"28",	"F8",   "FE",
95
-     "3F",	"E0",   "FA",	"2A",	"3A",	"FANR",	"2ANR",	"3ANR",
96
-	 "46SC","F6SC",	"26SC",	"36SC",	"46",	"F6",	"26",	"36",
97
-     "E7",  "E7NR", "F4SC", "24SC",	"34SC",	"44SC",	"F4",	"24",
98
-	 "34",	"44",	"MB",   ""};
92
+    {"2K",  "CV",   "4K",    "28SC", "F8SC",    "28",    "F8",   "FE",
93
+     "3F",    "E0",   "FA",    "2A",    "3A",    "FANR",    "2ANR",    "3ANR",
94
+     "46SC","F6SC",    "26SC",    "36SC",    "46",    "F6",    "26",    "36",
95
+     "E7",  "E7NR", "F4SC", "24SC",    "34SC",    "44SC",    "F4",    "24",
96
+     "34",    "44",    "MB",   ""};
99 97
 
100 98
 unsigned int controlByteList[] =
101
-    {0xCA,  0xEA,   0xC8,   0xF6,	0xE6,	0xD6,   0xC6,   0xCC,
102
-     0xCE,  0xC1,   0xE0,   0xF0,   0x60,	0xC0,	0xD0,	0x40,
103
-	 0x74,	0xE4,	0xF4,	0x64,	0x54,	0xC4,	0xD4,	0x44,
104
-     0xE3,  0xC3,   0xE2,   0xF2,	0x62,	0x72,	0xC2,	0xD2,
105
-	 0x42,	0x52,	0xC9,   0x00};
99
+    {0xCA,  0xEA,   0xC8,   0xF6,    0xE6,    0xD6,   0xC6,   0xCC,
100
+     0xCE,  0xC1,   0xE0,   0xF0,   0x60,    0xC0,    0xD0,    0x40,
101
+     0x74,    0xE4,    0xF4,    0x64,    0x54,    0xC4,    0xD4,    0x44,
102
+     0xE3,  0xC3,   0xE2,   0xF2,    0x62,    0x72,    0xC2,    0xD2,
103
+     0x42,    0x52,    0xC9,   0x00};
106 104
 
107 105
 int fileSizeList[] =
108
-    {2048,  2048,   4096,   8192,	8192,	8192,   8192,   8192,
109
-     8192,  8192,   12288,  12288,  12288,	12288,	12288,	12288,
110
-	 16384, 16384,	16384,	16384,	16384,	16384,	16384,	16384,
111
-     16384, 16384,  32768,  32768,  32768,	32768,	32768,	32768,
112
-	 32768,	32768,	65536,  0};
106
+    {2048,  2048,   4096,   8192,    8192,    8192,   8192,   8192,
107
+     8192,  8192,   12288,  12288,  12288,    12288,    12288,    12288,
108
+     16384, 16384,    16384,    16384,    16384,    16384,    16384,    16384,
109
+     16384, 16384,  32768,  32768,  32768,    32768,    32768,    32768,
110
+     32768,    32768,    65536,  0};
113 111
 
114 112
 int startPageList[] =
115
-    {7,     7,      15,     31,		15,     31,		15,     15,
116
-     31,    31,     15,     31,		47,		15,     31,		47,
117
-	 63,	15,		31,		47,		63,		15,		31,		47,
118
-     63,    63,     15,		31,		47,		63,     15,		31,
119
-     47,	63,		15,     0};
113
+    {7,     7,      15,     31,        15,     31,        15,     15,
114
+     31,    31,     15,     31,        47,        15,     31,        47,
115
+     63,    15,        31,        47,        63,        15,        31,        47,
116
+     63,    63,     15,        31,        47,        63,     15,        31,
117
+     47,    63,        15,     0};
120 118
 
121
-int clearingToneLength[2] = {26, 51};
119
+unsigned char clearingToneLength[2] = {26, 51};
122 120
 unsigned char clearingTone[256];
123 121
 
124
-int zeroBitLength,
125
-    oneBitLength;
122
+unsigned char zeroBitLength,
123
+              oneBitLength;
126 124
 
127 125
 unsigned char zeroBit[256],
128 126
               oneBit[256];
@@ -179,15 +177,15 @@ dd  BS_1[] = {
179 177
 /*  0x30eb4f7a,    Video Life (4K).BIN */
180 178
 /*  0x9afa761f,    Magicard (Life).bin */
181 179
     0x266bd1b6, /* Video Life (CommaVid).bin */
182
-	0xa0899305, /* Video Life (alternative 2K) */
180
+    0xa0899305, /* Video Life (alternative 2K) */
183 181
     -1
184 182
 };
185 183
 
186
-char BS_1_DESC[][25] = {
184
+const char *BS_1_DESC[] = {
187 185
     "Magicard (CommaVid)",
188 186
     "Video Life (CommaVid)",
189
-	"Video Life (CommaVid)",
190
-    -1
187
+    "Video Life (CommaVid)",
188
+    0
191 189
 };
192 190
 
193 191
 dd  BS_3[] = {
@@ -215,13 +213,13 @@ dd  BS_3[] = {
215 213
     0x549a1b6b, /* Star Wars - The Arcade Game (PAL) */
216 214
     0x36910e4d, /* Frogger II - Threedeep! (PAL) */
217 215
     0xb8bb2361, /* Gyruss (PAL) */
218
-	0xd3669372, /* Star Wars: Ewok Adventure (PAL) (proto) */
219
-	0x70db5cca, /* Star Wars: Ewok Adventure (T Jentzsch PAL to NTSC Conversion) */
220
-	0x6400d110, /* Lord of the Rings (proto) */
216
+    0xd3669372, /* Star Wars: Ewok Adventure (PAL) (proto) */
217
+    0x70db5cca, /* Star Wars: Ewok Adventure (T Jentzsch PAL to NTSC Conversion) */
218
+    0x6400d110, /* Lord of the Rings (proto) */
221 219
     -1
222 220
 };
223 221
 
224
-char BS_3_DESC[][50] = {
222
+const char *BS_3_DESC[] = {
225 223
     "Frogger II - Threedeep!",
226 224
     "Gyruss [b]",
227 225
     "Gyruss",
@@ -246,9 +244,9 @@ char BS_3_DESC[][50] = {
246 244
     "Star Wars - The Arcade Game (PAL)",
247 245
     "Frogger II - Threedeep! (PAL)",
248 246
     "Gyruss (PAL)",
249
-	"Star Wars - Ewok Adventure (proto) (PAL)",
250
-	"Star Wars - Ewok Adv. T Jentzsch PAL->NTSC (proto)",
251
-	"Lord of the Rings (proto)",
247
+    "Star Wars - Ewok Adventure (proto) (PAL)",
248
+    "Star Wars - Ewok Adv. T Jentzsch PAL->NTSC (proto)",
249
+    "Lord of the Rings (proto)",
252 250
     ""
253 251
 };
254 252
 
@@ -267,11 +265,11 @@ dd  BS_4[] = {
267 265
     0x2c34898f, /* Springer.bin */
268 266
     0x09a71583, /* Miner 2049er PAL */
269 267
     0xd5645294, /* Miner Volume 2 NTSC */
270
-	0x52630ec9, /* Polaris T. Jentzsch PAL to NTSC conversion*/
268
+    0x52630ec9, /* Polaris T. Jentzsch PAL to NTSC conversion*/
271 269
     -1
272 270
 };
273 271
 
274
-char BS_4_DESC[][30] = {
272
+const char *BS_4_DESC[] = {
275 273
     "Espial [b]",
276 274
     "Espial",
277 275
     "Miner 2049er [b1]",
@@ -284,10 +282,10 @@ char BS_4_DESC[][30] = {
284 282
     "Polaris (PAL)",
285 283
     "River Patrol (Tigervision)",
286 284
     "Springer",
287
-	"Miner 2049er PAL",
288
-	"Miner 2049er Vol. 2",
289
-	"Polaris (T Jentzsch NTSC->PAL)",
290
-    -1
285
+    "Miner 2049er PAL",
286
+    "Miner 2049er Vol. 2",
287
+    "Polaris (T Jentzsch NTSC->PAL)",
288
+    ""
291 289
 };
292 290
 
293 291
 dd  BS_5[] = {
@@ -296,32 +294,32 @@ dd  BS_5[] = {
296 294
     0xd8ecf576, /* Decathlon (PAL) */
297 295
     0x0e8757b0, /* Robot Tank (PAL) */
298 296
     0x94e8df6b, /* Space Shuttle (PAL) */
299
-	0xf3a4363c,	/* Thwocker prototype */
297
+    0xf3a4363c,    /* Thwocker prototype */
300 298
     -1
301 299
 };
302 300
 
303
-char BS_5_DESC[][25] = {
301
+const char *BS_5_DESC[] = {
304 302
     "Decathlon",
305 303
     "Robot Tank",
306 304
     "Decathlon (PAL)",
307 305
     "Robot Tank (PAL)",
308 306
     "Space Shuttle (PAL)",
309
-	"Thwocker (proto)",
310
-    -1
307
+    "Thwocker (proto)",
308
+    ""
311 309
 };
312 310
 
313
-dd	BS_9[] = {
314
-	0x6a31beac,	/* Private Eye (CCE).bin */
315
-	0x3fa749c0,	/* Private Eye [b].bin */
316
-	0x33242242,	/* Private Eye.bin */
317
-	-1
311
+dd    BS_9[] = {
312
+    0x6a31beac,    /* Private Eye (CCE).bin */
313
+    0x3fa749c0,    /* Private Eye [b].bin */
314
+    0x33242242,    /* Private Eye.bin */
315
+    -1
318 316
 };
319 317
 
320
-char BS_9_DESC[][20] = {
318
+const char *BS_9_DESC[] = {
321 319
     "Private Eye (CCE)",
322 320
     "Private Eye [b]",
323 321
     "Private Eye",
324
-    -1
322
+    ""
325 323
 };
326 324
 
327 325
 
@@ -332,11 +330,11 @@ dd  BS_6[] = {
332 330
     -1
333 331
 };
334 332
 
335
-char BS_6_DESC[][20] = {
333
+const char *BS_6_DESC[] = {
336 334
     "Dig Dug.bin",
337 335
     "Off the Wall [o]",
338 336
     "Off the Wall",
339
-    -1
337
+    ""
340 338
 };
341 339
 
342 340
 dd  BS_7[] = {
@@ -347,12 +345,12 @@ dd  BS_7[] = {
347 345
     -1
348 346
 };
349 347
 
350
-char BS_7_DESC[][50] = {
348
+const char *BS_7_DESC[] = {
351 349
     "Bump n Jump [b].bin",
352 350
     "Bump n Jump.bin",
353 351
     "Burgertime.bin",
354 352
     "Masters of the Universe - The Power of He-Man",
355
-    -1
353
+    ""
356 354
 };
357 355
 
358 356
 /*
@@ -369,4 +367,4 @@ dd crctab[256];     /* table to help CRC calculation */
369 367
 #define CRC32_REV 0xA0000001    /* CRC-32 polynomial reversed */
370 368
 #define SQUARE_WAVE 0
371 369
 #define SINE_WAVE   1
372
-void make16BitStereo(char *sineWave, int *sineWaveLength);
370
+void make16BitStereo(unsigned char *sineWave, unsigned char *sineWaveLength);

+ 32
- 2
makewav.txt View File

@@ -1,4 +1,4 @@
1
-                           M A K E W A V    4 . 2
1
+                           M A K E W A V    5 . 0
2 2
 
3 3
     Makewav converts ROM images for the Atari 2600 into .wav files that
4 4
 can be transfered into a Cuttle Cart or Supercharger for play on an original
@@ -20,6 +20,18 @@ Atari 2600.
20 20
 major version (3.1).  If you are familiar with a previous version of makewav,
21 21
 you should read this document in full before attempting to use this version.
22 22
 
23
+    Version 5.0 adds support for direct output to a sound card, depends on
24
+portaudio for this, which is available at http://portaudio.com for Windows
25
+MacOS X and Unix/Linux (OSS or ALSA).
26
+
27
+New to version 5.0:
28
+
29
+- added support for direct output to sound card
30
+
31
+New to version 4.2.1:
32
+
33
+- code cleanup removing all DOS relevant code
34
+
23 35
 New to version 4.2:
24 36
 
25 37
 - Bug Fix
@@ -79,6 +91,13 @@ Option Flags:
79 91
   Flag  (Default)
80 92
         Description
81 93
 
94
+  -a -> (default is off)
95
+        Instead of creating .wav file(s) play audio output directly on sound
96
+        card. Additionally a device name can be added here, query list of
97
+        available devices with "-l". A trailing '*' can be used to perform
98
+        a substring match: -aUSB* sends output to the first USB audio card
99
+        found.
100
+
82 101
   -b -> (default is to have value automatically determined)
83 102
         Sets the bankswitch mode to use for the .wav file.  The possible
84 103
         values are:  2K, CV, 4K, F8SC, F8, FE, 3F, E0, FANR, FA, F6SC,
@@ -194,7 +213,7 @@ Option Flags:
194 213
         in the game.  It is possible that some games may not work right
195 214
         when a page is left out.  You can fix this by using the -p flag.
196 215
 
197
-  -f -> (default = 2)
216
+  -f -> (default = 1 for CuttleCard, 0 for SuperCharger)
198 217
         This flag allows you to change the speed of the tranfer.  The valid
199 218
         range is 0-4 and the higher the number the faster the load.  Don't
200 219
         be surprised if the faster transfers are not reliable, they are
@@ -225,6 +244,9 @@ Option Flags:
225 244
         file.  The format 2 files are much larger than the other formats and
226 245
         do not provide any increase in quality over format 1 files.
227 246
 
247
+  -l -> (default = off)
248
+        Show list of available sound devices.
249
+
228 250
   -m -> (default = 00 for non-Supercharger games and values stored in ROM
229 251
          image for Supercharger games)
230 252
         The -m must be followed by a 2 digit hex number (e.g. -m0d not -md).
@@ -322,6 +344,14 @@ this program at his or her own risk!
322 344
 
323 345
 Version History:
324 346
 
347
+New to version 5.0:
348
+
349
+- added support for direct output to sound card
350
+
351
+New to version 4.2.1:
352
+
353
+- code cleanup removing all DOS relevant code
354
+
325 355
 New to version 4.2:
326 356
 
327 357
 - Bug fix

+ 253
- 0
paplay.c View File

@@ -0,0 +1,253 @@
1
+/**
2
+   this file is based upon:
3
+
4
+   @file patest_sine8.c
5
+   @ingroup test_src
6
+   @brief Test 8 bit data: play a sine wave for several seconds.
7
+   @author Ross Bencina <rossb@audiomulch.com>
8
+*/
9
+/*
10
+ * $Id: patest_sine8.c 1748 2011-09-01 22:08:32Z philburk $
11
+ *
12
+ * This program uses the PortAudio Portable Audio Library.
13
+ * For more information see: http://www.portaudio.com
14
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
15
+ *
16
+ * Permission is hereby granted, free of charge, to any person obtaining
17
+ * a copy of this software and associated documentation files
18
+ * (the "Software"), to deal in the Software without restriction,
19
+ * including without limitation the rights to use, copy, modify, merge,
20
+ * publish, distribute, sublicense, and/or sell copies of the Software,
21
+ * and to permit persons to whom the Software is furnished to do so,
22
+ * subject to the following conditions:
23
+ *
24
+ * The above copyright notice and this permission notice shall be
25
+ * included in all copies or substantial portions of the Software.
26
+ *
27
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
28
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
29
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
30
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
31
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
32
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
33
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34
+ */
35
+
36
+/*
37
+ * The text above constitutes the entire PortAudio license; however,
38
+ * the PortAudio community also makes the following non-binding requests:
39
+ *
40
+ * Any person wishing to distribute modifications to the Software is
41
+ * requested to send the modifications to the original developer so that
42
+ * they can be incorporated into the canonical version. It is also
43
+ * requested that these non-binding requests be included along with the
44
+ * license above.
45
+ */
46
+
47
+#include <stdio.h>
48
+#include <string.h>
49
+#include <math.h>
50
+#include <portaudio.h>
51
+#include "paplay.h"
52
+
53
+#define SAMPLE_RATE   (44100)
54
+#define TEST_UNSIGNED (0)
55
+
56
+#if TEST_UNSIGNED
57
+#define TEST_FORMAT   paUInt8
58
+typedef unsigned char sample_t;
59
+#define SILENCE       ((sample_t)0x80)
60
+#else
61
+#define TEST_FORMAT   paInt8
62
+typedef char          sample_t;
63
+#define SILENCE       ((sample_t)0x00)
64
+#endif
65
+
66
+struct playdata_s
67
+{
68
+   const unsigned char *bufferstart;
69
+   int  size;
70
+   int  played;
71
+};
72
+
73
+int palist()
74
+{
75
+   PaError             err;
76
+   int                 i;
77
+   int                 numDevices;
78
+   const PaDeviceInfo  *deviceInfo;
79
+
80
+   err = Pa_Initialize();
81
+   if( err != paNoError )
82
+   {
83
+      goto error;
84
+   }
85
+
86
+   numDevices = Pa_GetDeviceCount();
87
+   if( numDevices < 0 )
88
+   {
89
+      fprintf( stderr, "ERROR: Pa_CountDevices returned 0x%x\n", numDevices );
90
+      err = numDevices;
91
+      goto error;
92
+   }
93
+
94
+   for( i = 0; i < numDevices; i++ )
95
+   {
96
+      deviceInfo = Pa_GetDeviceInfo( i );
97
+      fprintf( stdout, "device #%d: %s\n", i, deviceInfo->name );
98
+   }
99
+
100
+   Pa_Terminate();
101
+   return err;
102
+
103
+error:
104
+   Pa_Terminate();
105
+   fprintf( stderr, "An error occured while using the portaudio stream\n" );
106
+   fprintf( stderr, "Error number: %d\n", err );
107
+   fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
108
+   return err;
109
+}
110
+
111
+/* This routine will be called by the PortAudio engine when audio is needed.
112
+** It may called at interrupt level on some machines so don't do anything
113
+** that could mess up the system like calling malloc() or free().
114
+*/
115
+static int pa_mem_callback( const void *inputBuffer, void *outputBuffer,
116
+                            unsigned long framesPerBuffer,
117
+                            const PaStreamCallbackTimeInfo* timeInfo,
118
+                            PaStreamCallbackFlags statusFlags,
119
+                            void *userData )
120
+{
121
+   char *out = (char*)outputBuffer;
122
+   struct playdata_s *playdata = (struct playdata_s*)userData;
123
+   int copysize = playdata->size - playdata->played;
124
+   int finished = 0;
125
+   (void) inputBuffer; /* Prevent unused variable warnings. */
126
+
127
+   if( copysize > framesPerBuffer )
128
+   {
129
+      copysize = framesPerBuffer;
130
+   }
131
+   else
132
+   {
133
+      finished = 1;
134
+   }
135
+   memcpy( out, playdata->bufferstart + playdata->played, copysize );
136
+   if( copysize < framesPerBuffer )
137
+   {
138
+      /* zero remainder of final buffer */
139
+      memset( out + copysize, 0, framesPerBuffer - copysize );
140
+   }
141
+   playdata->played += copysize;
142
+
143
+   return finished;
144
+}
145
+
146
+/*******************************************************************/
147
+int paplay( const unsigned char *data, int size, const char *devicename )
148
+{
149
+   struct playdata_s   playdata;
150
+   PaStreamParameters  outputParameters;
151
+   PaStream*           stream;
152
+   PaError             err;
153
+   const PaDeviceInfo  *deviceInfo;
154
+   int                 i;
155
+   int                 numDevices;
156
+
157
+   playdata.bufferstart = data;
158
+   playdata.size        = size;
159
+   playdata.played      = 0;
160
+
161
+   err = Pa_Initialize();
162
+   if( err != paNoError )
163
+   {
164
+      goto error;
165
+   }
166
+
167
+   numDevices = Pa_GetDeviceCount();
168
+   if( numDevices < 0 )
169
+   {
170
+      fprintf( stderr, "ERROR: Pa_CountDevices returned 0x%x\n", numDevices );
171
+      err = numDevices;
172
+      goto error;
173
+   }
174
+
175
+   outputParameters.device = Pa_GetDefaultOutputDevice(); /* Default output device. */
176
+   if( devicename )
177
+   {
178
+      int s = strlen( devicename );
179
+      for( i=0; i<numDevices; i++ )
180
+      {
181
+         deviceInfo = Pa_GetDeviceInfo( i );
182
+         if( devicename[s-1] == '*' )
183
+         {
184
+            if( !strncmp( devicename, deviceInfo->name, s - 1) )
185
+            {
186
+               outputParameters.device = i;
187
+            }
188
+         }
189
+         else
190
+         {
191
+            if( !strcmp( devicename, deviceInfo->name ) )
192
+            {
193
+               outputParameters.device = i;
194
+            }
195
+         }
196
+      }
197
+   }
198
+   if( outputParameters.device == paNoDevice )
199
+   {
200
+      fprintf(stderr,"Error: No default output device.\n");
201
+      goto error;
202
+   }
203
+   deviceInfo = Pa_GetDeviceInfo( outputParameters.device );
204
+   fprintf( stderr, "using device #%d: %s\n", outputParameters.device, deviceInfo->name );
205
+
206
+   outputParameters.channelCount = 1;                     /* Mono output. */
207
+   outputParameters.sampleFormat = TEST_FORMAT;
208
+   outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
209
+   outputParameters.hostApiSpecificStreamInfo = NULL;
210
+   err = Pa_OpenStream( &stream,
211
+                        NULL,      /* No input. */
212
+                        &outputParameters,
213
+                        SAMPLE_RATE,
214
+                        256,       /* Frames per buffer. */
215
+                        paClipOff, /* We won't output out of range samples so don't bother clipping them. */
216
+                        pa_mem_callback,
217
+                        &playdata );
218
+   if( err != paNoError )
219
+   {
220
+      goto error;
221
+   }
222
+
223
+   err = Pa_StartStream( stream );
224
+   if( err != paNoError )
225
+   {
226
+      goto error;
227
+   }
228
+
229
+   while( ( err = Pa_IsStreamActive( stream ) ) == 1 )
230
+   {
231
+      Pa_Sleep(100);
232
+   }
233
+   if( err < 0 )
234
+   {
235
+      goto error;
236
+   }
237
+
238
+   err = Pa_CloseStream( stream );
239
+   if( err != paNoError )
240
+   {
241
+      goto error;
242
+   }
243
+
244
+   Pa_Terminate();
245
+   return err;
246
+
247
+error:
248
+   Pa_Terminate();
249
+   fprintf( stderr, "An error occured while using the portaudio stream\n" );
250
+   fprintf( stderr, "Error number: %d\n", err );
251
+   fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
252
+   return err;
253
+}

+ 7
- 0
paplay.h View File

@@ -0,0 +1,7 @@
1
+
2
+#ifndef PAPLAY_H
3
+#define PAPLAY_H PAPLAY_H
4
+int paplay( const unsigned char *data, int size, const char *devicename );
5
+int palist();
6
+#endif
7
+

+ 33
- 0
streambuffer.c View File

@@ -0,0 +1,33 @@
1
+
2
+#include "streambuffer.h"
3
+
4
+#include <stdlib.h>
5
+#include <string.h>
6
+
7
+#define CHUNKSIZE (1024*256)
8
+
9
+
10
+void streaminit( streambuffer_t *buffer )
11
+{
12
+   memset( buffer, 0, sizeof( streambuffer_t ) );
13
+}
14
+
15
+
16
+void streamadd( streambuffer_t *buffer, const unsigned char *data, int size )
17
+{
18
+   if( buffer->used + size > buffer->malloced )
19
+   {
20
+      buffer->malloced += CHUNKSIZE;
21
+      buffer->start = (unsigned char*)realloc( buffer->start, buffer->malloced );
22
+   }
23
+
24
+   memcpy( buffer->start + buffer->used, data, size );
25
+   buffer->used += size;
26
+}
27
+
28
+
29
+void streamclean( streambuffer_t *buffer )
30
+{
31
+   free( buffer->start );
32
+   streaminit( buffer );
33
+}

+ 13
- 0
streambuffer.h View File

@@ -0,0 +1,13 @@
1
+
2
+struct streambuffer_s
3
+{
4
+   unsigned char *start;
5
+   int  used;
6
+   int  malloced;
7
+};
8
+
9
+typedef struct streambuffer_s streambuffer_t;
10
+
11
+void streaminit( streambuffer_t *buffer );
12
+void streamadd( streambuffer_t *buffer, const unsigned char *data, int size );
13
+void streamclean( streambuffer_t *buffer );

+ 3
- 0
version.h View File

@@ -0,0 +1,3 @@
1
+#ifndef MAKEWAV_VERSION
2
+#define MAKEWAV_VERSION "5.0"
3
+#endif

Loading…
Cancel
Save