home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 8
/
CDASC08.ISO
/
NEWS
/
676
/
PLAYLPT
/
PLAYLPT.C
< prev
next >
Wrap
Text File
|
1993-10-07
|
8KB
|
287 lines
/**************************************************************************\
**
** File: playlpt.c
**
** Description: Driver to test audio sample output.
** Preliminary to MOD-like Sampler-Sequencer.
**
** Created by: John Howard 08-Jan-1993
**
\**************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <memory.h>
#include <conio.h>
#include <time.h>
#include <math.h>
#include <graph.h>
/* general definitions */
#ifndef boolean
#define boolean unsigned int
#define TRUE 1
#define FALSE 0
#endif
//#define _outp(__p,__v) outp((__p),(__v))
/* specific definitions */
typedef unsigned int lpt_length_type;
/* changing this type, changes the treatment of sample byte values */
typedef unsigned char lpt_sample_byte_type;
#define MAX_BUF_LEN 64000
#define BYTE_SCOPE_HALF 128 /* zero amplitude offset for
unsigned data */
#define INTR_CYCLE .055 /* normal timer interrupt interval */
#define Hz_To_InterruptFactor(__hz) \
(((__hz)*INTR_CYCLE))
/* variables with defaults */
static lpt_sample_byte_type lpt_sample_byte_array_1[ MAX_BUF_LEN + 1 ];
static lpt_sample_byte_type lpt_sample_byte_array_2[ MAX_BUF_LEN + 1 ];
static lpt_sample_byte_type *lpt_sample_buf[] =
{
lpt_sample_byte_array_1,
lpt_sample_byte_array_2,
NULL
};
static lpt_length_type lpt_cur_byte_pos = 0;
static lpt_length_type lpt_max_bytes_1 = 0;
static lpt_length_type lpt_max_bytes_2 = 0;
static lpt_length_type lpt_max_byte_pos[ 3 ];
static int toggle = 0;
static boolean lpt_output_finished = FALSE;
static boolean lpt_is_raw = TRUE;
static lpt_eof = FALSE;
static unsigned int lpt_io_address = 0x0378;
static char * hlp_msg = "*** PLAYLPT.EXE *** 01-08-93 Audio Sample Player Unit Test by John C. Howard\n"
"Plays .VOC, .WAV and .RAW and .SAM files through the LPT printer port.\n"
"Syntax example...\n"
"PLAYLPT {sample filename} [rate(default 11000)] [port address(default 378h)]";
/* function prototypes */
void lpt_service_sample_output( void );
static boolean lpt_display_sample_bytes( char * fname, lpt_sample_byte_type * lpt_file_array );
static void lpt_exit( void );
static boolean lpt_read_file( FILE * fp, char * fname, lpt_sample_byte_type * lpt_file_array,
lpt_length_type * lpt_max_pos );
static FILE * lpt_open_file( FILE * fp, char * fname );
static boolean lpt_is_raw_file( char * fname );
void main( int argc, char *argv[] )
{
int lpt_sample_rate = 0;
int lpt_timer_div_rate = 605; /* comes out to 11000Hz rate */
char * filename = NULL;
FILE * fp = NULL;
/* get command-line parameters */
if( NULL != argv[1] )
filename = argv[1]; /* filename pointer assignment */
else
lpt_exit();
if( NULL != argv[2] ) /* sample rate in Hz */
sscanf( argv[2], "%d", &lpt_sample_rate );
if( NULL != argv[3] ) /* lpt1 IO address in hex */
sscanf( argv[3], "%x", &lpt_io_address );
/* see if file is raw according to extention */
lpt_is_raw = lpt_is_raw_file( filename );
/* display and confirm first part of sample file */
// if( 1 )
if( lpt_display_sample_bytes( filename, lpt_sample_buf[ toggle ] ) )
{
fprintf( stdout, "Press any key to stop. (may not be immediate)" );
/* open and read first part of file */
if( NULL == ( fp = lpt_open_file( fp, filename ) ) )
lpt_exit();
/* skip reading the header is required */
if( ! lpt_is_raw )
fseek( fp, 32, SEEK_CUR );
lpt_read_file( fp, filename, lpt_sample_buf[ toggle ], &lpt_max_byte_pos[ toggle ] );
/* calculate timer divide factor from sample rate */
if( lpt_sample_rate )
lpt_timer_div_rate = Hz_To_InterruptFactor( lpt_sample_rate );
/* install new timer func that calls our output routine */
initclk_1( NULL, lpt_service_sample_output, lpt_timer_div_rate );
/* read in more of file in alternate buffer while interrupt proc
* is playing current buffer until eof or a key is pressed
*/
while( ! lpt_eof && ! kbhit() )
{
lpt_read_file( fp, filename, lpt_sample_buf[ 1 - toggle ],
&lpt_max_byte_pos[ 1 - toggle ] );
/* sit in loop until interrupt routine has finished outputting */
while( !lpt_output_finished );
/* switch buffers and reset finished flag */
_disable();
toggle = 1 - toggle;
_enable();
lpt_output_finished = FALSE;
// _disable();
/* Put any kind of update display here.
* Use enable and disable before and after because
* using variables for display while they may
* be in the process of changing in the interrupt routine
* WILL crash the computer.
*/
// _enable();
}
if( kbhit() )
getch();
/* put the timer function back where we found it */
restclk();
}
/* clear the screen then exit */
_setvideomode( _DEFAULTMODE );
exit( 0 );
}
/* this funtion is called by the timer interrupt.
* therefore DON'T call any C funtions that use DOS's int 21h's
* lower subfunctions such as... printf().
*/
void lpt_service_sample_output( void )
{
_outp( lpt_io_address, (int)( *(lpt_sample_buf[ toggle ]+lpt_cur_byte_pos++) ) );
/* if reached end of buffer then reset to beginning */
if( ! ( lpt_max_byte_pos[ toggle ] - lpt_cur_byte_pos ) )
{
lpt_cur_byte_pos = 0;
lpt_output_finished = TRUE;
}
}
/* The following routine is used to display the first 640 bytes
* on the screen graphically to inspect the result of out reading.
* It also confirms the file's readability.
*/
static boolean lpt_display_sample_bytes( char * fname, lpt_sample_byte_type * lpt_file_array )
{
boolean ret = TRUE;
int i;
char c;
FILE * fp;
/* open, read and then close file */
if( NULL != ( fp = lpt_open_file( fp, fname ) ) )
{
/* read off header */
if( ! lpt_is_raw )
fseek( fp, 32, SEEK_CUR );
lpt_read_file( fp, fname, lpt_file_array, &lpt_max_byte_pos[ toggle ] );
fclose( fp );
}
else
{
ret = FALSE;
}
/* init video, position and color */
_setvideomode( _ERESCOLOR ); /* ega for compatability sake */
_moveto( 0, 175 ); /* halfway down screen */
_setcolor( 4 ); /* red */
_lineto( 640, 175 );
/* re-init position and color */
_moveto( 0, 240 );
_setcolor( 7 );
for( i = 0; i < 640; i++ )
{
_lineto( i, (int)( 175 + ( (*(lpt_file_array+i)-BYTE_SCOPE_HALF) *
.25 ) ));
}
fprintf( stdout, "Press ESC to cancel, or any other key to play the sample" );
while( ! kbhit() );
c = getch();
_setvideomode( _DEFAULTMODE );
/* pressing ESCAPE causes a return false, canceling the sample output
* int main()
*/
if( c == '\x1b' )
ret = FALSE;
return( ret );
}
/* the way to exit if something goes wrong */
static void lpt_exit( void )
{
fprintf( stdout, "\n%s\n", hlp_msg );
exit(0);
}
static FILE * lpt_open_file( FILE * fp, char * fname )
{
return( ( NULL != ( fp = fopen( fname, "rb" ) ) ? fp : NULL ) );
}
static boolean lpt_read_file( FILE * fp, char * fname, lpt_sample_byte_type * lpt_file_array,
lpt_length_type * lpt_max_pos )
{
boolean ret = FALSE;
int i;
lpt_length_type max_fill_len = 0;
/* read audio sample portion of file */
if( 0 < ( max_fill_len = fread( lpt_file_array, 1, MAX_BUF_LEN, fp ) ) )
{
if( lpt_is_raw )
{
/* adjust to be over zero for raw type samples */
for( i = 0; i < max_fill_len; i++ )
*(lpt_file_array+i) =
( *(lpt_file_array+i) + BYTE_SCOPE_HALF );
}
*(lpt_max_pos) = max_fill_len;
ret = TRUE;
}
else
{
lpt_eof = TRUE;
}
}
static boolean lpt_is_raw_file( char * fname )
{
boolean ret = FALSE;
if( ! strcmp( "SAM", strupr( ( fname+(strlen(fname)-3) ) ) ) ||
! strcmp( "RAW", strupr( ( fname+(strlen(fname)-3) ) ) ) )
ret = TRUE;
return( ret );
}