home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 8 / CDASC08.ISO / NEWS / 676 / PLAYLPT / PLAYLPT.C < prev    next >
Text File  |  1993-10-07  |  8KB  |  287 lines

  1. /**************************************************************************\
  2. ** 
  3. ** File:        playlpt.c
  4. ** 
  5. ** Description:  Driver to test audio sample output.
  6. **                    Preliminary to MOD-like Sampler-Sequencer.
  7. ** 
  8. ** Created by:    John Howard    08-Jan-1993
  9. ** 
  10. \**************************************************************************/
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <string.h>
  14. #include <memory.h>
  15. #include <conio.h>
  16. #include <time.h>
  17. #include <math.h>
  18. #include <graph.h>
  19.  
  20.  
  21. /* general definitions */
  22. #ifndef boolean
  23.     #define    boolean    unsigned int
  24.     #define    TRUE    1
  25.     #define    FALSE    0
  26. #endif
  27. //#define _outp(__p,__v)    outp((__p),(__v))
  28.  
  29. /* specific definitions */
  30. typedef unsigned int         lpt_length_type;
  31. /* changing this type, changes the treatment of sample byte values */
  32. typedef unsigned char         lpt_sample_byte_type;
  33. #define MAX_BUF_LEN            64000
  34. #define BYTE_SCOPE_HALF        128            /* zero amplitude offset for 
  35.                                             unsigned data */
  36. #define INTR_CYCLE            .055        /* normal timer interrupt interval */
  37. #define Hz_To_InterruptFactor(__hz)    \
  38.     (((__hz)*INTR_CYCLE))
  39.  
  40.  
  41. /* variables with defaults */
  42. static lpt_sample_byte_type lpt_sample_byte_array_1[ MAX_BUF_LEN + 1 ];
  43. static lpt_sample_byte_type lpt_sample_byte_array_2[ MAX_BUF_LEN + 1 ];
  44. static lpt_sample_byte_type *lpt_sample_buf[] =
  45. {
  46.     lpt_sample_byte_array_1,
  47.     lpt_sample_byte_array_2,
  48.     NULL
  49. };
  50. static lpt_length_type lpt_cur_byte_pos = 0;
  51. static lpt_length_type lpt_max_bytes_1 = 0;
  52. static lpt_length_type lpt_max_bytes_2 = 0;
  53. static lpt_length_type lpt_max_byte_pos[ 3 ];
  54. static int toggle = 0;
  55. static boolean lpt_output_finished = FALSE;
  56. static boolean lpt_is_raw = TRUE;
  57. static lpt_eof = FALSE;
  58. static unsigned int lpt_io_address = 0x0378;
  59.  
  60.  
  61. static char * hlp_msg = "*** PLAYLPT.EXE *** 01-08-93 Audio Sample Player Unit Test by John C. Howard\n"
  62. "Plays .VOC, .WAV and .RAW and .SAM files through the LPT printer port.\n"
  63. "Syntax example...\n"
  64. "PLAYLPT {sample filename} [rate(default 11000)] [port address(default 378h)]";
  65.  
  66.  
  67. /* function prototypes */
  68. void lpt_service_sample_output( void );
  69. static boolean lpt_display_sample_bytes( char * fname, lpt_sample_byte_type * lpt_file_array );
  70. static void lpt_exit( void );
  71. static boolean lpt_read_file( FILE * fp, char * fname, lpt_sample_byte_type * lpt_file_array,
  72.     lpt_length_type * lpt_max_pos );
  73. static FILE * lpt_open_file( FILE * fp, char * fname );
  74. static boolean lpt_is_raw_file( char * fname );
  75.  
  76.  
  77. void main( int argc, char *argv[] )
  78. {
  79.     int lpt_sample_rate = 0;
  80.     int lpt_timer_div_rate = 605;    /* comes out to 11000Hz rate */
  81.     char * filename = NULL;
  82.     FILE * fp = NULL;
  83.  
  84.  
  85.     /* get command-line parameters */
  86.     if( NULL != argv[1] )
  87.         filename = argv[1];                /* filename pointer assignment */
  88.     else
  89.         lpt_exit();
  90.  
  91.     if( NULL != argv[2] )                /* sample rate in Hz */
  92.         sscanf( argv[2], "%d", &lpt_sample_rate );
  93.     if( NULL != argv[3] )                /* lpt1 IO address in hex */
  94.         sscanf( argv[3], "%x", &lpt_io_address );
  95.  
  96.     /* see if file is raw according to extention */
  97.     lpt_is_raw = lpt_is_raw_file( filename );
  98.  
  99.  
  100.     /* display and confirm first part of sample file */
  101. //    if( 1 )
  102.     if( lpt_display_sample_bytes( filename, lpt_sample_buf[ toggle ] ) )
  103.     {
  104.         fprintf( stdout, "Press any key to stop. (may not be immediate)" );
  105.         /* open and read first part of file */
  106.         if( NULL == ( fp = lpt_open_file( fp, filename ) ) )
  107.             lpt_exit();
  108.  
  109.         /* skip reading the header is required */
  110.         if( ! lpt_is_raw )
  111.             fseek( fp, 32, SEEK_CUR );
  112.         lpt_read_file( fp, filename, lpt_sample_buf[ toggle ], &lpt_max_byte_pos[ toggle ] );
  113.  
  114.  
  115.         /* calculate timer divide factor from sample rate */
  116.         if( lpt_sample_rate )
  117.             lpt_timer_div_rate = Hz_To_InterruptFactor( lpt_sample_rate );
  118.         /* install new timer func that calls our output routine */
  119.         initclk_1( NULL, lpt_service_sample_output, lpt_timer_div_rate );
  120.  
  121.  
  122.         /* read in more of file in alternate buffer while interrupt proc
  123.          *    is playing current buffer until eof or a key is pressed
  124.          */
  125.         while( ! lpt_eof && ! kbhit() )
  126.         {
  127.             lpt_read_file( fp, filename, lpt_sample_buf[ 1 - toggle ],
  128.             &lpt_max_byte_pos[ 1 - toggle ] );
  129.  
  130.             /* sit in loop until interrupt routine has finished outputting */
  131.             while( !lpt_output_finished );
  132.  
  133.             /* switch buffers and reset finished flag */
  134.             _disable();
  135.             toggle = 1 - toggle;
  136.             _enable();
  137.  
  138.             lpt_output_finished = FALSE;
  139.  
  140. //            _disable();
  141.             /* Put any kind of update display here.
  142.              * Use enable and disable before and after because
  143.              * using variables for display while they may
  144.              * be in the process of changing in the interrupt routine
  145.              * WILL crash the computer.
  146.              */
  147. //            _enable();
  148.         }
  149.  
  150.         if( kbhit() )
  151.             getch();
  152.         /* put the timer function back where we found it */
  153.         restclk();
  154.     }
  155.  
  156.     /* clear the screen then exit */
  157.     _setvideomode( _DEFAULTMODE );
  158.     exit( 0 );
  159. }
  160.  
  161.  
  162. /* this funtion is called by the timer interrupt.
  163. * therefore DON'T call any C funtions that use DOS's int 21h's
  164. * lower subfunctions such as... printf().
  165. */
  166. void lpt_service_sample_output( void )
  167. {
  168.     _outp( lpt_io_address, (int)( *(lpt_sample_buf[ toggle ]+lpt_cur_byte_pos++) ) );
  169.     
  170.     /* if reached end of buffer then reset to beginning */
  171.     if( ! ( lpt_max_byte_pos[ toggle ] - lpt_cur_byte_pos ) )
  172.     {
  173.         lpt_cur_byte_pos = 0;
  174.         lpt_output_finished = TRUE;
  175.     }
  176. }
  177.  
  178.  
  179. /* The following routine is used to display the first 640 bytes
  180.  *    on the screen graphically to inspect the result of out reading.
  181.  * It also confirms the file's readability.
  182.  */
  183. static boolean lpt_display_sample_bytes( char * fname, lpt_sample_byte_type * lpt_file_array )
  184. {
  185.     boolean ret = TRUE;
  186.     int i;
  187.     char c;
  188.     FILE * fp;
  189.  
  190.  
  191.     /* open, read and then close file */
  192.     if( NULL != ( fp = lpt_open_file( fp, fname ) ) )
  193.     {
  194.         /* read off header */
  195.         if( ! lpt_is_raw )
  196.             fseek( fp, 32, SEEK_CUR );
  197.         lpt_read_file( fp, fname, lpt_file_array, &lpt_max_byte_pos[ toggle ] );
  198.         fclose( fp );
  199.     }
  200.     else
  201.     {
  202.         ret = FALSE;
  203.     }
  204.  
  205.     /* init video, position and color */
  206.     _setvideomode( _ERESCOLOR );        /* ega for compatability sake */
  207.     _moveto( 0, 175 );                    /* halfway down screen */
  208.     _setcolor( 4 );                        /* red */
  209.     _lineto( 640, 175 );
  210.     
  211.     /* re-init position and color */
  212.     _moveto( 0, 240 );
  213.     _setcolor( 7 );
  214.  
  215.     for( i = 0; i < 640; i++ )
  216.     {
  217.         _lineto( i, (int)( 175 + ( (*(lpt_file_array+i)-BYTE_SCOPE_HALF) *
  218.             .25 ) ));
  219.     }
  220.  
  221.     fprintf( stdout, "Press ESC to cancel, or any other key to play the sample" );
  222.     while( ! kbhit() );
  223.     c = getch();
  224.     _setvideomode( _DEFAULTMODE );
  225.  
  226.  
  227.     /* pressing ESCAPE causes a return false, canceling the sample output
  228.      *    int main()
  229.      */
  230.     if( c == '\x1b' )
  231.         ret = FALSE;
  232.  
  233.     return( ret );
  234. }
  235.  
  236.  
  237. /* the way to exit if something goes wrong */
  238. static void lpt_exit( void )
  239. {
  240.     fprintf( stdout, "\n%s\n", hlp_msg );
  241.     exit(0);
  242. }
  243.  
  244.  
  245. static FILE * lpt_open_file( FILE * fp, char * fname )
  246. {
  247.     return( ( NULL != ( fp = fopen( fname, "rb" ) ) ? fp : NULL ) );
  248. }
  249.  
  250.  
  251. static boolean lpt_read_file( FILE * fp, char * fname, lpt_sample_byte_type * lpt_file_array,
  252.     lpt_length_type * lpt_max_pos )
  253. {
  254.     boolean ret = FALSE;
  255.     int i;
  256.     lpt_length_type max_fill_len = 0;
  257.  
  258.     /* read audio sample portion of file */
  259.     if( 0 < ( max_fill_len = fread( lpt_file_array, 1, MAX_BUF_LEN, fp ) ) )
  260.     {
  261.         if( lpt_is_raw )
  262.         {
  263.             /* adjust to be over zero for raw type samples */
  264.             for( i = 0; i < max_fill_len; i++ )
  265.                 *(lpt_file_array+i) =
  266.                     ( *(lpt_file_array+i) + BYTE_SCOPE_HALF );
  267.         }
  268.         *(lpt_max_pos) = max_fill_len;
  269.         ret = TRUE;
  270.     }
  271.     else
  272.     {
  273.         lpt_eof = TRUE;
  274.     }
  275. }
  276.  
  277. static boolean lpt_is_raw_file( char * fname )
  278. {
  279.     boolean ret = FALSE;
  280.  
  281.     if( ! strcmp( "SAM", strupr( ( fname+(strlen(fname)-3) ) ) ) ||
  282.         ! strcmp( "RAW", strupr( ( fname+(strlen(fname)-3) ) ) ) )
  283.         ret = TRUE;
  284.  
  285.     return( ret );
  286. }
  287.