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 6 months 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 @@
.SUFFIXES: .exe .o .c .pc

all:makewav
PROGRAM = makewav

queue.o:
gcc -c queue.c
CC = gcc
CFLAGS = -Os -g -Wall
#CFLAGS = -g -Wall
LDFLAGS = -lm -lportaudio

all: $(PROGRAM)

%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $^

$(PROGRAM): queue.o makewav.o paplay.o streambuffer.o
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)

clean:
rm -f $(PROGRAM) *.o

makewav: queue.o
gcc -lm -DLINUX -O queue.o -o makewav makewav.c

+ 26
- 0
Makefile.mxe View File

@@ -0,0 +1,26 @@

PROGRAM := makewav.exe

MXE_DIR := /opt/mxe
MXE_TARGET := i686-w64-mingw32.static

CC := $(MXE_DIR)/usr/bin/$(MXE_TARGET)-gcc
STRIP := $(MXE_DIR)/usr/bin/$(MXE_TARGET)-strip
CFLAGS := -Os
#CFLAGS := -g -Wall
LDFLAGS := -lm -lportaudio -lwinmm -lsetupapi -lhid -lole32

all: $(PROGRAM)

%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $^

$(PROGRAM): queue.o makewav.o paplay.o streambuffer.o
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
$(STRIP) $@
upx --ultra-brute $@ || :
ls -l $@

clean:
rm -f $(PROGRAM) *.o


+ 12
- 0
README.md View File

@@ -0,0 +1,12 @@
# Makewav 5.0

Makewav converts ROM image files for the Atari 2600 VCS into
.wav-files or plays them directly.

## typical usage
```
makewav -l # to get name of sound card
makewav -a <name_of_soundcard> -tc <romfile.bin> # for Cuttle Cart
makewav -a <name_of_soundcard> -ts <romfile.bin> # for SuperCharger
```


+ 5
- 0
debian/changelog View File

@@ -0,0 +1,5 @@
makewav (5.0) unstable; urgency=medium

* Initial release

-- Sven Oliver Moll <svolli@svol.li> Thu, 21 Sep 2017 18:48:05 +0200

+ 1
- 0
debian/compat View File

@@ -0,0 +1 @@
9

+ 16
- 0
debian/control View File

@@ -0,0 +1,16 @@
Source: makewav
Section: otherosfs
Priority: optional
Maintainer: Sven Oliver Moll <svolli@svol.li>
Build-Depends: debhelper (>= 9), portaudio19-dev
Standards-Version: 3.9.8
Homepage: https://xayax.net/tools/makewav/

Package: makewav
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: Tool for Atari 2600 VCS SuperCharger/CuttleCart
makewav generates a wave file for the Atari 2600 VCS cartridges
SuperCharger and CuttleCart. These are modules that use audio data
(originally played from tape) as mass storage. This version can
also play the data directly.

+ 11
- 0
debian/copyright View File

@@ -0,0 +1,11 @@
Now for the boring stuff: I hereby place this program into the
public domain. I am not responsible for any damage this program may cause.
I am not liable for any misuse, intentional or otherwise, of this program.
There is no warranty, written or implied, on this program. The user uses
this program at his or her own risk!

Bob Colbert
CEO of RetroWare
rcolbert@oasis.novia.net
http://www.novia.net/~rcolbert

+ 1
- 0
debian/docs View File

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

+ 1
- 0
debian/install View File

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

+ 19
- 0
debian/rules View File

@@ -0,0 +1,19 @@
#!/usr/bin/make -f
# See debhelper(7) (uncomment to enable)
# output every command that modifies files on the build system.
#export DH_VERBOSE = 1


# see FEATURE AREAS in dpkg-buildflags(1)
export DEB_BUILD_MAINT_OPTIONS = hardening=+all

# see ENVIRONMENT in dpkg-buildflags(1)
# package maintainers to append CFLAGS
#export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic
# package maintainers to append LDFLAGS
#export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed


%:
dh $@


+ 1
- 0
debian/source/format View File

@@ -0,0 +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 @@
#define BSM_2K 0
#define BSM_CV 1
#define BSM_4K 2
#define BSM_28SC 3
#define BSM_28SC 3
#define BSM_F8SC 4
#define BSM_28 5
#define BSM_28 5
#define BSM_F8 6
#define BSM_FE 7
#define BSM_3F 8
#define BSM_E0 9
#define BSM_FA 10
#define BSM_2A 11
#define BSM_3A 12
#define BSM_FA 10
#define BSM_2A 11
#define BSM_3A 12
#define BSM_FANR 13
#define BSM_2ANR 14
#define BSM_3ANR 15
@@ -28,10 +28,10 @@
#define BSM_24SC 27
#define BSM_34SC 28
#define BSM_44SC 29
#define BSM_F4 30
#define BSM_24 31
#define BSM_34 32
#define BSM_44 33
#define BSM_F4 30
#define BSM_24 31
#define BSM_34 32
#define BSM_44 33
#define BSM_MB 34
#define FMT_22KHZ_8BIT_MONO 0
#define FMT_44KHZ_8BIT_MONO 1
@@ -44,15 +44,11 @@
#define DISPLAY_SUMMARY 2
#define DISPLAY_DETAILS 3

#ifdef __linux__
#define _MAX_FNAME 256
#define _MAX_PATH 256
#define _MAX_DIR 256
#define _MAX_DRIVE 256
#define _MAX_EXT 256
#else
#include "find.h"
#endif
#define _MAX_FNAME 256
#define _MAX_PATH 256
#define _MAX_DIR 256
#define _MAX_DRIVE 256
#define _MAX_EXT 256

typedef unsigned long int dd;
typedef unsigned short int dw;
@@ -61,6 +57,7 @@ typedef int db;

struct parmFlags
{
int aflag;
int dflag;
int fflag;
int kflag;
@@ -80,8 +77,9 @@ struct parmFlags
float headerSeconds;
float clearingSeconds;
float hlength;
char wavFileName[_MAX_FNAME];
char wavFileName[_MAX_FNAME+5];
char fullPath[_MAX_PATH];
char *audioDevName;

struct qnode *binFileQ;
unsigned int multi;
@@ -91,38 +89,38 @@ struct parmFlags
};

char bankSwitchList[][5] =
{"2K", "CV", "4K", "28SC", "F8SC", "28", "F8", "FE",
"3F", "E0", "FA", "2A", "3A", "FANR", "2ANR", "3ANR",
"46SC","F6SC", "26SC", "36SC", "46", "F6", "26", "36",
"E7", "E7NR", "F4SC", "24SC", "34SC", "44SC", "F4", "24",
"34", "44", "MB", ""};
{"2K", "CV", "4K", "28SC", "F8SC", "28", "F8", "FE",
"3F", "E0", "FA", "2A", "3A", "FANR", "2ANR", "3ANR",
"46SC","F6SC", "26SC", "36SC", "46", "F6", "26", "36",
"E7", "E7NR", "F4SC", "24SC", "34SC", "44SC", "F4", "24",
"34", "44", "MB", ""};

unsigned int controlByteList[] =
{0xCA, 0xEA, 0xC8, 0xF6, 0xE6, 0xD6, 0xC6, 0xCC,
0xCE, 0xC1, 0xE0, 0xF0, 0x60, 0xC0, 0xD0, 0x40,
0x74, 0xE4, 0xF4, 0x64, 0x54, 0xC4, 0xD4, 0x44,
0xE3, 0xC3, 0xE2, 0xF2, 0x62, 0x72, 0xC2, 0xD2,
0x42, 0x52, 0xC9, 0x00};
{0xCA, 0xEA, 0xC8, 0xF6, 0xE6, 0xD6, 0xC6, 0xCC,
0xCE, 0xC1, 0xE0, 0xF0, 0x60, 0xC0, 0xD0, 0x40,
0x74, 0xE4, 0xF4, 0x64, 0x54, 0xC4, 0xD4, 0x44,
0xE3, 0xC3, 0xE2, 0xF2, 0x62, 0x72, 0xC2, 0xD2,
0x42, 0x52, 0xC9, 0x00};

int fileSizeList[] =
{2048, 2048, 4096, 8192, 8192, 8192, 8192, 8192,
8192, 8192, 12288, 12288, 12288, 12288, 12288, 12288,
16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384,
16384, 16384, 32768, 32768, 32768, 32768, 32768, 32768,
32768, 32768, 65536, 0};
{2048, 2048, 4096, 8192, 8192, 8192, 8192, 8192,
8192, 8192, 12288, 12288, 12288, 12288, 12288, 12288,
16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384,
16384, 16384, 32768, 32768, 32768, 32768, 32768, 32768,
32768, 32768, 65536, 0};

int startPageList[] =
{7, 7, 15, 31, 15, 31, 15, 15,
31, 31, 15, 31, 47, 15, 31, 47,
63, 15, 31, 47, 63, 15, 31, 47,
63, 63, 15, 31, 47, 63, 15, 31,
47, 63, 15, 0};
{7, 7, 15, 31, 15, 31, 15, 15,
31, 31, 15, 31, 47, 15, 31, 47,
63, 15, 31, 47, 63, 15, 31, 47,
63, 63, 15, 31, 47, 63, 15, 31,
47, 63, 15, 0};

int clearingToneLength[2] = {26, 51};
unsigned char clearingToneLength[2] = {26, 51};
unsigned char clearingTone[256];

int zeroBitLength,
oneBitLength;
unsigned char zeroBitLength,
oneBitLength;

unsigned char zeroBit[256],
oneBit[256];
@@ -179,15 +177,15 @@ dd BS_1[] = {
/* 0x30eb4f7a, Video Life (4K).BIN */
/* 0x9afa761f, Magicard (Life).bin */
0x266bd1b6, /* Video Life (CommaVid).bin */
0xa0899305, /* Video Life (alternative 2K) */
0xa0899305, /* Video Life (alternative 2K) */
-1
};

char BS_1_DESC[][25] = {
const char *BS_1_DESC[] = {
"Magicard (CommaVid)",
"Video Life (CommaVid)",
"Video Life (CommaVid)",
-1
"Video Life (CommaVid)",
0
};

dd BS_3[] = {
@@ -215,13 +213,13 @@ dd BS_3[] = {
0x549a1b6b, /* Star Wars - The Arcade Game (PAL) */
0x36910e4d, /* Frogger II - Threedeep! (PAL) */
0xb8bb2361, /* Gyruss (PAL) */
0xd3669372, /* Star Wars: Ewok Adventure (PAL) (proto) */
0x70db5cca, /* Star Wars: Ewok Adventure (T Jentzsch PAL to NTSC Conversion) */
0x6400d110, /* Lord of the Rings (proto) */
0xd3669372, /* Star Wars: Ewok Adventure (PAL) (proto) */
0x70db5cca, /* Star Wars: Ewok Adventure (T Jentzsch PAL to NTSC Conversion) */
0x6400d110, /* Lord of the Rings (proto) */
-1
};

char BS_3_DESC[][50] = {
const char *BS_3_DESC[] = {
"Frogger II - Threedeep!",
"Gyruss [b]",
"Gyruss",
@@ -246,9 +244,9 @@ char BS_3_DESC[][50] = {
"Star Wars - The Arcade Game (PAL)",
"Frogger II - Threedeep! (PAL)",
"Gyruss (PAL)",
"Star Wars - Ewok Adventure (proto) (PAL)",
"Star Wars - Ewok Adv. T Jentzsch PAL->NTSC (proto)",
"Lord of the Rings (proto)",
"Star Wars - Ewok Adventure (proto) (PAL)",
"Star Wars - Ewok Adv. T Jentzsch PAL->NTSC (proto)",
"Lord of the Rings (proto)",
""
};

@@ -267,11 +265,11 @@ dd BS_4[] = {
0x2c34898f, /* Springer.bin */
0x09a71583, /* Miner 2049er PAL */
0xd5645294, /* Miner Volume 2 NTSC */
0x52630ec9, /* Polaris T. Jentzsch PAL to NTSC conversion*/
0x52630ec9, /* Polaris T. Jentzsch PAL to NTSC conversion*/
-1
};

char BS_4_DESC[][30] = {
const char *BS_4_DESC[] = {
"Espial [b]",
"Espial",
"Miner 2049er [b1]",
@@ -284,10 +282,10 @@ char BS_4_DESC[][30] = {
"Polaris (PAL)",
"River Patrol (Tigervision)",
"Springer",
"Miner 2049er PAL",
"Miner 2049er Vol. 2",
"Polaris (T Jentzsch NTSC->PAL)",
-1
"Miner 2049er PAL",
"Miner 2049er Vol. 2",
"Polaris (T Jentzsch NTSC->PAL)",
""
};

dd BS_5[] = {
@@ -296,32 +294,32 @@ dd BS_5[] = {
0xd8ecf576, /* Decathlon (PAL) */
0x0e8757b0, /* Robot Tank (PAL) */
0x94e8df6b, /* Space Shuttle (PAL) */
0xf3a4363c, /* Thwocker prototype */
0xf3a4363c, /* Thwocker prototype */
-1
};

char BS_5_DESC[][25] = {
const char *BS_5_DESC[] = {
"Decathlon",
"Robot Tank",
"Decathlon (PAL)",
"Robot Tank (PAL)",
"Space Shuttle (PAL)",
"Thwocker (proto)",
-1
"Thwocker (proto)",
""
};

dd BS_9[] = {
0x6a31beac, /* Private Eye (CCE).bin */
0x3fa749c0, /* Private Eye [b].bin */
0x33242242, /* Private Eye.bin */
-1
dd BS_9[] = {
0x6a31beac, /* Private Eye (CCE).bin */
0x3fa749c0, /* Private Eye [b].bin */
0x33242242, /* Private Eye.bin */
-1
};

char BS_9_DESC[][20] = {
const char *BS_9_DESC[] = {
"Private Eye (CCE)",
"Private Eye [b]",
"Private Eye",
-1
""
};


@@ -332,11 +330,11 @@ dd BS_6[] = {
-1
};

char BS_6_DESC[][20] = {
const char *BS_6_DESC[] = {
"Dig Dug.bin",
"Off the Wall [o]",
"Off the Wall",
-1
""
};

dd BS_7[] = {
@@ -347,12 +345,12 @@ dd BS_7[] = {
-1
};

char BS_7_DESC[][50] = {
const char *BS_7_DESC[] = {
"Bump n Jump [b].bin",
"Bump n Jump.bin",
"Burgertime.bin",
"Masters of the Universe - The Power of He-Man",
-1
""
};

/*
@@ -369,4 +367,4 @@ dd crctab[256]; /* table to help CRC calculation */
#define CRC32_REV 0xA0000001 /* CRC-32 polynomial reversed */
#define SQUARE_WAVE 0
#define SINE_WAVE 1
void make16BitStereo(char *sineWave, int *sineWaveLength);
void make16BitStereo(unsigned char *sineWave, unsigned char *sineWaveLength);

+ 32
- 2
makewav.txt View File

@@ -1,4 +1,4 @@
M A K E W A V 4 . 2
M A K E W A V 5 . 0

Makewav converts ROM images for the Atari 2600 into .wav files that
can be transfered into a Cuttle Cart or Supercharger for play on an original
@@ -20,6 +20,18 @@ Atari 2600.
major version (3.1). If you are familiar with a previous version of makewav,
you should read this document in full before attempting to use this version.

Version 5.0 adds support for direct output to a sound card, depends on
portaudio for this, which is available at http://portaudio.com for Windows
MacOS X and Unix/Linux (OSS or ALSA).

New to version 5.0:

- added support for direct output to sound card

New to version 4.2.1:

- code cleanup removing all DOS relevant code

New to version 4.2:

- Bug Fix
@@ -79,6 +91,13 @@ Option Flags:
Flag (Default)
Description

-a -> (default is off)
Instead of creating .wav file(s) play audio output directly on sound
card. Additionally a device name can be added here, query list of
available devices with "-l". A trailing '*' can be used to perform
a substring match: -aUSB* sends output to the first USB audio card
found.

-b -> (default is to have value automatically determined)
Sets the bankswitch mode to use for the .wav file. The possible
values are: 2K, CV, 4K, F8SC, F8, FE, 3F, E0, FANR, FA, F6SC,
@@ -194,7 +213,7 @@ Option Flags:
in the game. It is possible that some games may not work right
when a page is left out. You can fix this by using the -p flag.

-f -> (default = 2)
-f -> (default = 1 for CuttleCard, 0 for SuperCharger)
This flag allows you to change the speed of the tranfer. The valid
range is 0-4 and the higher the number the faster the load. Don't
be surprised if the faster transfers are not reliable, they are
@@ -225,6 +244,9 @@ Option Flags:
file. The format 2 files are much larger than the other formats and
do not provide any increase in quality over format 1 files.

-l -> (default = off)
Show list of available sound devices.

-m -> (default = 00 for non-Supercharger games and values stored in ROM
image for Supercharger games)
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!

Version History:

New to version 5.0:

- added support for direct output to sound card

New to version 4.2.1:

- code cleanup removing all DOS relevant code

New to version 4.2:

- Bug fix

+ 253
- 0
paplay.c View File

@@ -0,0 +1,253 @@
/**
this file is based upon:

@file patest_sine8.c
@ingroup test_src
@brief Test 8 bit data: play a sine wave for several seconds.
@author Ross Bencina <rossb@audiomulch.com>
*/
/*
* $Id: patest_sine8.c 1748 2011-09-01 22:08:32Z philburk $
*
* This program uses the PortAudio Portable Audio Library.
* For more information see: http://www.portaudio.com
* Copyright (c) 1999-2000 Ross Bencina and Phil Burk
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

/*
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* Any person wishing to distribute modifications to the Software is
* requested to send the modifications to the original developer so that
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <portaudio.h>
#include "paplay.h"

#define SAMPLE_RATE (44100)
#define TEST_UNSIGNED (0)

#if TEST_UNSIGNED
#define TEST_FORMAT paUInt8
typedef unsigned char sample_t;
#define SILENCE ((sample_t)0x80)
#else
#define TEST_FORMAT paInt8
typedef char sample_t;
#define SILENCE ((sample_t)0x00)
#endif

struct playdata_s
{
const unsigned char *bufferstart;
int size;
int played;
};

int palist()
{
PaError err;
int i;
int numDevices;
const PaDeviceInfo *deviceInfo;

err = Pa_Initialize();
if( err != paNoError )
{
goto error;
}

numDevices = Pa_GetDeviceCount();
if( numDevices < 0 )
{
fprintf( stderr, "ERROR: Pa_CountDevices returned 0x%x\n", numDevices );
err = numDevices;
goto error;
}

for( i = 0; i < numDevices; i++ )
{
deviceInfo = Pa_GetDeviceInfo( i );
fprintf( stdout, "device #%d: %s\n", i, deviceInfo->name );
}

Pa_Terminate();
return err;

error:
Pa_Terminate();
fprintf( stderr, "An error occured while using the portaudio stream\n" );
fprintf( stderr, "Error number: %d\n", err );
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
return err;
}

/* This routine will be called by the PortAudio engine when audio is needed.
** It may called at interrupt level on some machines so don't do anything
** that could mess up the system like calling malloc() or free().
*/
static int pa_mem_callback( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
char *out = (char*)outputBuffer;
struct playdata_s *playdata = (struct playdata_s*)userData;
int copysize = playdata->size - playdata->played;
int finished = 0;
(void) inputBuffer; /* Prevent unused variable warnings. */

if( copysize > framesPerBuffer )
{
copysize = framesPerBuffer;
}
else
{
finished = 1;
}
memcpy( out, playdata->bufferstart + playdata->played, copysize );
if( copysize < framesPerBuffer )
{
/* zero remainder of final buffer */
memset( out + copysize, 0, framesPerBuffer - copysize );
}
playdata->played += copysize;

return finished;
}

/*******************************************************************/
int paplay( const unsigned char *data, int size, const char *devicename )
{
struct playdata_s playdata;
PaStreamParameters outputParameters;
PaStream* stream;
PaError err;
const PaDeviceInfo *deviceInfo;
int i;
int numDevices;

playdata.bufferstart = data;
playdata.size = size;
playdata.played = 0;

err = Pa_Initialize();
if( err != paNoError )
{
goto error;
}

numDevices = Pa_GetDeviceCount();
if( numDevices < 0 )
{
fprintf( stderr, "ERROR: Pa_CountDevices returned 0x%x\n", numDevices );
err = numDevices;
goto error;
}

outputParameters.device = Pa_GetDefaultOutputDevice(); /* Default output device. */
if( devicename )
{
int s = strlen( devicename );
for( i=0; i<numDevices; i++ )
{
deviceInfo = Pa_GetDeviceInfo( i );
if( devicename[s-1] == '*' )
{
if( !strncmp( devicename, deviceInfo->name, s - 1) )
{
outputParameters.device = i;
}
}
else
{
if( !strcmp( devicename, deviceInfo->name ) )
{
outputParameters.device = i;
}
}
}
}
if( outputParameters.device == paNoDevice )
{
fprintf(stderr,"Error: No default output device.\n");
goto error;
}
deviceInfo = Pa_GetDeviceInfo( outputParameters.device );
fprintf( stderr, "using device #%d: %s\n", outputParameters.device, deviceInfo->name );

outputParameters.channelCount = 1; /* Mono output. */
outputParameters.sampleFormat = TEST_FORMAT;
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
outputParameters.hostApiSpecificStreamInfo = NULL;
err = Pa_OpenStream( &stream,
NULL, /* No input. */
&outputParameters,
SAMPLE_RATE,
256, /* Frames per buffer. */
paClipOff, /* We won't output out of range samples so don't bother clipping them. */
pa_mem_callback,
&playdata );
if( err != paNoError )
{
goto error;
}

err = Pa_StartStream( stream );
if( err != paNoError )
{
goto error;
}

while( ( err = Pa_IsStreamActive( stream ) ) == 1 )
{
Pa_Sleep(100);
}
if( err < 0 )
{
goto error;
}

err = Pa_CloseStream( stream );
if( err != paNoError )
{
goto error;
}

Pa_Terminate();
return err;

error:
Pa_Terminate();
fprintf( stderr, "An error occured while using the portaudio stream\n" );
fprintf( stderr, "Error number: %d\n", err );
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
return err;
}

+ 7
- 0
paplay.h View File

@@ -0,0 +1,7 @@

#ifndef PAPLAY_H
#define PAPLAY_H PAPLAY_H
int paplay( const unsigned char *data, int size, const char *devicename );
int palist();
#endif


+ 33
- 0
streambuffer.c View File

@@ -0,0 +1,33 @@

#include "streambuffer.h"

#include <stdlib.h>
#include <string.h>

#define CHUNKSIZE (1024*256)


void streaminit( streambuffer_t *buffer )
{
memset( buffer, 0, sizeof( streambuffer_t ) );
}


void streamadd( streambuffer_t *buffer, const unsigned char *data, int size )
{
if( buffer->used + size > buffer->malloced )
{
buffer->malloced += CHUNKSIZE;
buffer->start = (unsigned char*)realloc( buffer->start, buffer->malloced );
}

memcpy( buffer->start + buffer->used, data, size );
buffer->used += size;
}


void streamclean( streambuffer_t *buffer )
{
free( buffer->start );
streaminit( buffer );
}

+ 13
- 0
streambuffer.h View File

@@ -0,0 +1,13 @@

struct streambuffer_s
{
unsigned char *start;
int used;
int malloced;
};

typedef struct streambuffer_s streambuffer_t;

void streaminit( streambuffer_t *buffer );
void streamadd( streambuffer_t *buffer, const unsigned char *data, int size );
void streamclean( streambuffer_t *buffer );

+ 3
- 0
version.h View File

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

Loading…
Cancel
Save