This source code was written for Borland C++ 3.1 or 4.0, and Borland's TASM Documentation files: filelist.txt - This file dtmf_fft.txt - Documentation of program options General program files: freq.c - Main program loop setupsub.c - Routines for program initialization procinp.c - Routines for keyboard input realfft.c - FFT routines realffta.asm - Alternate assembly version of FFT (optional--DOS only) freq.h - General header file and function prototypes extern.h - Global variable definitions fft.h - FFT code prototypes display.h - Definition of generalized graphics functions DOS Graphics support files gr_dos.c - Functions for mapping the graphics calls to Borland C's BGI egavga.obj - Borland BGI graphics library routines Files required for SB8 support sc_sb.c - Routines for SB recording sb.h - SB definitions dma_code.asm - DMA routines (Copyright (C) 1992, Heath I Hunnicutt) sb_dsp.asm - SB control routines (Copyright (C) 1992, Heath I Hunnicutt) (Note: Heath's routines may be found via FTP from: ftp.inf.tu-dresden.de/pub/ms-dos/sound/program/sb_dsp.zip and dma_code.zip. ) Files required for SB16 support sc_sb16.c - Routines for SB16 recording sbio.c - SB16 low-level control and DMA routines (Copyright (C) 1995, Ethan Brodsky) (Full source for Ethan's routines may be found at ftp://oak.oakland.edu/simtel/msdos/sound/sb16snd.zip) To add support for additional soundcards, you need to add the following changes to the code: (Replace CARD with an appropriate name in what follows.) The soundcard must be added (with an unique number) to the list of supported soundcards in the freq.h file, and the function prototypes defined: ----- freq.h ----- /* Defines for soundcard usage. */ #define SC_SB8 0 #define SC_SB16 1 #define SC_CARD 2 /* Function prototypes for the CARD soundcard */ void init_CARD(void); void reset_CARD(void); void halt_CARD(void); void cleanup_CARD(void); void recordblock_CARD(void far * buffer); void set_mixer_CARD(int channel,int level); ----- freq.h ----- You should add a couple lines near the end of freq.c to report the soundcard name when the program exits: ----- freq.c ----- #ifdef SC_CARD if(Soundcard==SC_CARD) printf(" in CARD NAME mode."); #endif ----- freq.c ----- Then you need to set the pointers to the soundcard's functions and set the sample size and mixer ability (and any other soundcard-specific initialization such as getting the BLASTER environment variable data) in an initialization function called from setupsub.c: ----- setupsub.c ----- #ifdef SC_CARD if(Soundcard==SC_CARD) init_card(); #endif ----- setupsub.c ----- You then need to write the routines for running the soundcard, probably in the file sc_CARD.c, as follows: ----- sc_CARD.c ----- #include "freq.h" #include "extern.h" void far interrupt CARDHandler() { // Interrupt handler for when the DMA transfer has filled a buffer. // Put whatever card-specific code is required here, and set the flags: flag[record_buffer]=1; if(++record_buffer>=BUFFERS) record_buffer=0; } void init_CARD(void) { /* Perform assorted soundcard initialization */ /* This function is called once at program initialization */ reset_soundcard=reset_CARD; halt_soundcard=halt_CARD; cleanup_soundcard=cleanup_CARD; recordblock=recordblock_CARD; set_mixer=set_mixer_CARD; // If mixers are supported sample_size=8; // Bits per sample (8 or 16) mixers=0; // Mixers supported (1) or not supported (0) /* Set up interrupt handler routine here */ } void halt_CARD(void) { // This function is called to halt and reset the DMA process // so that buffer pointers may be changed. // It is called before changing the sound card settings. } void reset_CARD(void) { // This function is called every time the settings change. // Initialize the card and DMA, and set the sampling rate // to the value given in the variable "SamplingRate" // Reset the buffer pointers queue_buffer=0; // Pointer to next buffer to be queued record_buffer=0; // Pointer to next buffer to be filled process_buffer=0; // Pointer to next buffer to be FFTed for(i=0;i=BUFFERS) queue_buffer=0; } void cleanup_CARD(void) { // This function is called once, just before the program exits // Halt the DMA and reset the card // Restore old interrupt handler } void recordblock_CARD(void far * buffer) { // This function is called once for every block to record // Start the DMA process to record the block of data which is pointed // to by "buffer"; recording a total of "fftlen" samples // The CARDHandler routine should be called (most likely via interrupts) // after this block has been recorded. } void set_mixer_CARD(int channel,int level) { // Set the specified mixer level // channels is MIXER_INT, MIXER_EXT, or MIXER_MIC // level is a percentage on, 0 to 100, where 100 is full volume } ----- sc_CARD.c ----- And finally, you need to link this code (along with any soundcard-specific libraries) with the main program.