From: ian@unipalm.co.uk (Ian Phillipps)
Subject: Re: how do I play back samples on a PC? - a program!
Organization: Unipalm Ltd., 216 Cambridge Science Park, Cambridge CB4 4WA, UK
Date: Wed, 30 Sep 1992 17:47:03 GMT

g91b8620@giraffe.ru.ac.za (MR SN BARRATT) writes:

>Keywords: CPM
Eh? If you're running CP/M on a PC, I can't help you much.

>Can anyone help?

>  3.  Any technical info on how to play back these files using the internal 
>      speaker on the PC.  (Text and/or C,Assembly Source)

This is for Borland C, and turns a byte-wide sample stream into
Pulse-Width modulation. It was a quick hack, and I'm not all that pleased
with it, since the carrier is rather obtrusive. If you improve it,
please let me know.

For best sonic results, uncomment out the "disable()" as otherwise the
18/sec clock will buzz during play.

----

#include <stdio.h>
#include <dos.h>
#include <stdlib.h>
#include <time.h>

#define TIMER (0x40)
#define TIM_CHAN( n )	((n) << 6 )	/* Channel number */
#define TIM_MODE( n ) ((n) << 1 )
#define TIM_SQUARE	(6)		/* Square wave */
#define TIM_ONESHOT	(2)		/* retriggerable monostable */
#define TIM_HILO	(0x30)		/* Load low byte then high byte */
#define TIM_CONTROL	(TIMER+3)
#define PORT_B		(0x61)		/* Parallel i/o channel port B */

#define CHAN		(2)		/* Timer channel to use */

static unsigned char trigoff, trigon;

#define trig(n) (				\
	outportb( TIMER+CHAN, (n) & 0xff ),	\
	outportb( TIMER+CHAN, (n) >> 8 ),	\
	outportb( PORT_B, trigon ),		\
	outportb( PORT_B, trigoff ) )


/* read binary file, allocate and return array */
char *readfile( char *name, unsigned int* size )
{
	FILE *f = fopen( name, "rb" );
	unsigned char *array, *result;
	unsigned long actual;
	if ( !f )
		printf( "Cant open %s\n", name ), exit(1);
	fseek( f, 0L, SEEK_END );
	actual = ftell( f );
	fseek( f, 0L, SEEK_SET );
	if ( actual > 65535 ) actual = 65535;
	*size = actual;
	array = result = malloc( (size_t)actual );
	if ( ! array )
		printf( "Cant allocate %lu bytes\n", actual ), exit(1);
	if ( fread( array, 1, (size_t)actual, f ) != actual )
		printf( "Read length error!\n" ), exit(1);

	/* now process the data */
	while( actual-- > 0 )
		*array++ >>= 1;
	return result;
}


main( int c, char **v )
{
	unsigned char saveport = inportb( PORT_B );
	unsigned size = 0;
	unsigned count = 32768;
	unsigned delay = 1;
	clock_t t;
	char *p = readfile( v[1], &size );
	if ( c > 2 ) delay = atoi( v[2] );

	/* Clear Gate; set enable */


	trigoff = ( inportb( PORT_B ) & ~3 ) | 2;
	trigon = trigoff | 3;		/* Gate on as well */

	/* set mode */
	outportb( TIM_CONTROL, TIM_CHAN(2)+TIM_ONESHOT+TIM_HILO );

/*	disable();
 */
	t = clock();
	count = size;
	if ( delay > 0 )
		while( count-- > 0 )
			{
			int value = *p++;
			int x;
			trig( value );
			x = delay;
			while( x-- > 0 )
				;
			}
	else
		while( count-- > 0 )
			{
			int value = *p++;
			int x;
			trig( value );
			}
        outportb( PORT_B, saveport );
	enable();
	printf( "%ld samples/second\n", (size*65536L)/(3600L*(clock()-t)) );
}
-- 
Ian Phillipps, Unipalm Ltd, 216 Science Park,		Phone +44 223 420002
Milton Road, Cambridge, CB4 4WA, England.		Phax  +44 223 426868
	print unpack( u,q,9:G5S="!A;F]T:&5R('!E<FP@:&%C:V5R"@``,.'');
Newsgroups: comp.music,rec.music.makers,rec.music.compose,comp.sys.ibm.pc.soundcard