|
AudioScience HPI Version_4.10.
|
/****************************************************************************** $Header: /home/eliot/asi/repo/cvsrepo/Repository/drv/linux/test/asihpitest.c,v 1.56 2011/08/12 11:13:16 as-ewb Exp $ Test Hardware Programming Interface (HPI) using HPI functions Usage: asihpitest --help note to cleanup this file, use "astyle --style=linux -s4 asihpitest.c" ******************************************************************************/ /* Some customization defines */ // Print out the complete list of mixer controls #define DUMP_MIXER_CONTROLS 0 // Use background bus mastering if available #define USE_BBM 1 // Record instreams to files "recN.pcm" #define RECORD_TO_FILE 0 // Card polling interval in milliseconds #define POLL_INTERVAL 50 // Test runtime #define RUNTIME (15 * SECONDS) // Interval at which stream state is printed #define PRINT_INTERVAL (1 * SECONDS) /* End customization defines */ #define SECONDS (1000/POLL_INTERVAL) #define MINUTES (60*SECONDS) #include <stdio.h> #include <stdlib.h> #include <math.h> #include <string.h> #include <ctype.h> //#include <unistd.h> #include <getopt.h> #define HPI_BUILD_INCLUDE_INTERNAL #ifdef __APPLE__ #include <hpi/hpi.h> #include <hpi/hpidebug.h> #else #include <hpi.h> #include <hpidebug.h> #endif static char *hpi_control_strings[] = HPI_CONTROL_TYPE_STRINGS; static char *hpi_src_strings[] = HPI_SOURCENODE_STRINGS; static char *hpi_dst_strings[] = HPI_DESTNODE_STRINGS; // local protos static void HandleError(hpi_err_t err); // file read/write static void THPI_WavFileOpen( short nIndex, char *pszFile ); static short THPI_WavFileRead( short nIndex, uint8_t *pbData, long lLength ); static void THPI_WavFileClose( short nIndex ); static int getch( void ); // global #define BLOCK_SIZE 32768L //30720L //6144 //12288 //16384 //19200 //9600 static uint8_t abBuffer[BLOCK_SIZE]; static short haveFiles = 0; /* Option variables */ static int instream_bbm = USE_BBM; static int outstream_bbm = USE_BBM; static unsigned int record_to_file = RECORD_TO_FILE; static unsigned int runtime = RUNTIME + 1; static unsigned int dump_mixer = 0; static int max_instreams = 999; static int max_outstreams = 999; static uint16_t wAdapterIndex = 0; static int nNumFiles = 0; static unsigned int samplerate = 48000; static unsigned int bitrate = 128000; static unsigned int channels = 2; static unsigned int format = HPI_FORMAT_PCM16_SIGNED; static unsigned int new_mode = 0; static unsigned int yes = 0; #define MAX_FILES 8 static char szFile[MAX_FILES][80] = { "", "", "", "" }; static struct option long_options[] = { {"adapter", required_argument, 0, 'a'}, {"dump-mixer", no_argument, 0, 'd'}, {"disable-bbm", no_argument, 0, 'b'}, {"yes", no_argument, 0, 'y'}, {"adapter-mode", required_argument, 0, 'm'}, {"samplerate", required_argument, 0, 's'}, {"channels", required_argument, 0, 'c'}, {"format", required_argument, 0, 'f'}, {"file-record", no_argument, 0, 'F'}, {"max-instreams", required_argument, 0, 'i'}, {"max-outstreams", required_argument, 0, 'o'}, {"runtime", required_argument, 0, 'r'}, {"help", no_argument, 0, 'h'}, {0, 0, 0, 0} }; static const char *short_options = "a:bc:df:Fhi:m:o:r:s:y?"; static const char *option_help[] = { "<adapter number> to test.", "Dump list of mixer controls.", "Disable use of background bus mastering.", "Don't prompt on error.", "Set the adapter mode. (need driver reload).", "<Hz> samplerate.", "<n> channels to play or record.", "<f> format index (see hpi.h)", "Record audio to disk files.", "<n> Max number of instreams to open.", "<n> Max number of outstreams to open.", "<runtime> in seconds.", "Show this text." }; #ifdef _MSC_VER static void poll_delay( void ) { Sleep(POLL_INTERVAL); } #else #include <time.h> #define millisec 1000000 static struct timespec poll_interval = { 0, POLL_INTERVAL * millisec }; static void poll_delay( void ) { nanosleep(&poll_interval, 0); } #endif static void help( void ) { int i = 0; printf("\nUsage - asihpitest [options] [files to play]\n"); while (long_options[i].name != 0) { printf("--%s -%c %s\n", long_options[i].name, (char)(long_options[i].val), option_help[i]); i++; } exit(0); } static void parse_options( int argc, char *argv[] ) { int c; /*********** Parse the command line options ***************/ while (1) { //int this_option_optind = optind ? optind : 1; int option_index = 0; c = getopt_long(argc, argv, short_options, long_options, &option_index); if (c == -1) break; switch (c) { case 0: printf("option %s", long_options[option_index].name); if (optarg) printf(" with arg %s", optarg); printf("\n"); break; case 'a': wAdapterIndex = atoi(optarg); break; case 'b': instream_bbm = 0; outstream_bbm = 0; break; case 'c': channels = atoi(optarg); break; case 'd': dump_mixer = 1; break; case 'y': yes = 1; break; case 'F': record_to_file = 1; break; case 'f': format = atoi(optarg); break; case 'i': max_instreams = atoi(optarg); if (max_instreams < 0) { max_instreams = -max_instreams; instream_bbm = 0; } break; case 'm': new_mode = atoi(optarg); break; case 'o': max_outstreams = atoi(optarg); if (max_outstreams < 0) { max_outstreams = -max_outstreams; outstream_bbm = 0; } break; case 'r': runtime = atoi(optarg); runtime *= SECONDS; break; case 's': samplerate = atoi(optarg); break; case '?': case 'h': help(); break; default: printf("?? getopt returned character code 0%o ??\n", c); } } if (optind < argc) { // printf ("non-option ARGV-elements: "); nNumFiles = 0; while ((optind < argc) && (nNumFiles < MAX_FILES)) { strcpy(szFile[nNumFiles], argv[optind++]); printf("File %d is %s\n", nNumFiles, szFile[nNumFiles]); nNumFiles++; } } } static void print_universal_control_lookup_result( hpi_hsubsys_t *hSubSys, hpi_handle_t hMixer, struct hpi_control_t asihpi_control, hpi_handle_t hControl ) { static hpi_handle_t block_object; char name[256]; char *param_name; hpi_err_t err; size_t size; size_t items; enum e_entity_role r; hpi_handle_t found_control; size = sizeof(name); err = HPI_Object_GetInfo( hControl, entity_type_cstring, entity_role_classname, name, &size, &items); if (err) HandleError(err); err = HPI_Object_GetRole(hControl, &r); if (err) HandleError(err); if ( r == entity_role_block ) { block_object = hControl; /* test lookup block by name */ err = HPI_Object_BlockHandle(hMixer, asihpi_control.wSrcNodeType, asihpi_control.wSrcNodeIndex, asihpi_control.wDstNodeType, asihpi_control.wDstNodeIndex, name, &found_control ); } else if ( r == entity_role_parameter_port ) { /* test lookup parameter by name */ param_name = name; err = HPI_Object_ParameterHandle( hMixer, block_object, name, &found_control); } if (err) { HandleError(err); printf(" Block/Param lookup (FAILED) "); } } static void print_universal_control( hpi_hsubsys_t *hSubSys, hpi_handle_t hMixer, hpi_handle_t hControl ) { struct hpi_entity *info; enum e_entity_role r; hpi_err_t err; char name[256]; char units[256]; size_t size, items; int flags; err = HPI_Object_GetInfoEntity(hControl, &info); printf("%s", HPI_Entity_GetRoleName(info)); size = sizeof(name); err = HPI_Object_GetInfo( hControl, entity_type_cstring, entity_role_classname, name, &size, &items); if (err) HandleError(err); printf(" %s\n", name); err = HPI_Object_GetRole(hControl, &r); if (err) HandleError(err); if ( r == entity_role_parameter_port ) { struct hpi_entity *value; enum e_entity_type the_type; const char *type; void *v; printf("Value ("); // flags size = sizeof(flags); err = HPI_Object_GetInfo( hControl, entity_type_int, entity_role_flags, &flags, &size, &items); if (flags & entity_flag_readable) printf("R"); if (flags & entity_flag_writeable) printf("W"); if (flags & entity_flag_volatile) printf("Volatile"); printf(") "); err = HPI_Object_GetValueEntity(hControl, &value); err = HPI_Entity_Unpack(value, &the_type, &items, &r, &v); type = HPI_Entity_GetTypeName(value); if (!err) { int vi; printf("%s[%zd]=[ ", type, items); if (the_type == entity_type_mac_address) { the_type = entity_type_octet; items *= 6; } for (vi = 0; vi < items; vi++) { switch (the_type) { case entity_type_int: printf("%d ", ((int *)v)[vi]); break; case entity_type_float: printf("%f ", ((float *)v)[vi]); break; case entity_type_boolean: printf("%c ", ((char *)v)[vi]); break; case entity_type_cstring: printf("%c", ((char *)v)[vi]); break; case entity_type_ip4_address: printf("0x%08x ", ((int*)v)[vi]); break; case entity_type_octet: default: printf("%02x ", ((unsigned char *)v)[vi]); break; } } printf("] "); } HPI_Entity_Free(value); // units size = sizeof(units); err = HPI_Object_GetInfo( hControl, entity_type_cstring, entity_role_units, units, &size, &items); if (!err) printf("%s", units); } // fetch parameter handles if ( r == entity_role_block ) { hpi_handle_t params[16]; /* should really use count */ size_t i; size_t number; number = sizeof(params)/sizeof(hpi_handle_t); err = HPI_Object_BlockParameters( hMixer, hControl, params, &number); if (err) HandleError(err); printf("Parameter handles=["); for ( i=0 ; i<number ; i++ ) { if (i > 0) printf(", "); printf("%d",params[i]); } printf("]"); } } static void print_mixer_controls( hpi_hsubsys_t *hSubSys, hpi_handle_t hMixer ) { int f; hpi_handle_t hControl; hpi_err_t err; for (f = 0; f < 10000; f++) { // put SOME limit to the number struct hpi_control_t asihpi_control; err = HPI_MixerGetControlByIndex(hSubSys, hMixer, f, &asihpi_control.wSrcNodeType, &asihpi_control.wSrcNodeIndex, &asihpi_control.wDstNodeType, &asihpi_control.wDstNodeIndex, &asihpi_control.wControlType, // HPI_CONTROL_METER, _VOLUME etc &hControl); if (err == HPI_ERROR_CONTROL_DISABLED) printf("DISABLED "); else if (err) break; printf("\nHPI Control %d, %s:%s[%d]->%s[%d] : ", f, hpi_control_strings[asihpi_control.wControlType], hpi_src_strings[asihpi_control.wSrcNodeType - HPI_SOURCENODE_NONE], asihpi_control.wSrcNodeIndex, hpi_dst_strings[asihpi_control.wDstNodeType - HPI_DESTNODE_NONE], asihpi_control.wDstNodeIndex); switch (asihpi_control.wControlType) { uint16_t s; uint32_t w; short db[2]; case HPI_CONTROL_MULTIPLEXER:{ int l; uint16_t cs, ci; err = HPI_Multiplexer_GetSource(hSubSys, hControl, &cs, &ci); if (err) { HandleError(err); break; } for (l = 0; l < 256; l++) { err = HPI_Multiplexer_QuerySource (hSubSys, hControl, l, &asihpi_control.wSrcNodeType, &asihpi_control. wSrcNodeIndex); if (!err) { if ((cs == asihpi_control. wSrcNodeType) && (ci == asihpi_control. wSrcNodeIndex)) printf("\n->"); else printf("\n"); printf("\tSource %d %s[%d]", l, hpi_src_strings [asihpi_control. wSrcNodeType - HPI_SOURCENODE_NONE], asihpi_control. wSrcNodeIndex); } else break; } break; } case HPI_CONTROL_VOLUME: err = HPI_VolumeGetGain(hSubSys, hControl, db); if (err) { HandleError(err); break; } printf("%5.2fdB %5.2fdB", db[0] / 100.0, db[1] / 100.0); break; case HPI_CONTROL_LEVEL: err = HPI_LevelGetGain(hSubSys, hControl, db); if (err) { HandleError(err); break; } printf("%5.2fdB %5.2fdB", db[0] / 100.0, db[1] / 100.0); break; case HPI_CONTROL_METER: err = HPI_MeterGetPeak(hSubSys, hControl, db); if (err) { HandleError(err); break; } printf("%5.2fdB %5.2fdB", db[0] / 100.0, db[1] / 100.0); break; case HPI_CONTROL_AESEBU_RECEIVER: err = HPI_AESEBU_Receiver_GetErrorStatus(hSubSys, hControl, &s); printf("status %02x", s); err = HPI_AESEBU_Receiver_GetFormat(hSubSys, hControl, &s); printf(" format %d", s); err = HPI_AESEBU_Receiver_GetSampleRate(hSubSys, hControl, &w); if (!err) printf(" rate %d", w); break; case HPI_CONTROL_SAMPLECLOCK: err = HPI_SampleClock_GetSampleRate(hSubSys, hControl, &w); err = HPI_SampleClock_GetSource(hSubSys, hControl, &s); printf("rate %d, source %d", w, s); break; case HPI_CONTROL_UNIVERSAL: print_universal_control_lookup_result(hSubSys, hMixer, asihpi_control, hControl); print_universal_control(hSubSys, hMixer, hControl); break; } } printf("\n%d controls found\n", f); } /************************************** MAIN ***********************/ int main( int argc, char *argv[] ) { hpi_hsubsys_t *hSubSys; hpi_err_t err = 0; // HPI error uint32_t dwVersion = 0; uint32_t dwDataSizeW, dwDataSizeR = 0; struct hpi_format FormatW, FormatR; int numAdapters = 0; int adapterFound = 0; uint16_t wVersion; uint32_t dwSerialNumber; uint16_t wType; uint16_t wNumOutStreams; uint16_t wNumInStreams; uint32_t current_mode; hpi_handle_t hOutStream[16]; hpi_handle_t hInStream[16]; uint32_t dwStrBufferSize = 0; uint32_t dwIStrBufferSize = 0; hpi_handle_t hMixer = 0; hpi_handle_t hControl; hpi_handle_t hMeterControl = 0; hpi_handle_t ahGainControl[4] = { 0, 0, 0, 0 }; short f; uint32_t i = 0; short anGainLog[4][2]; long testcount = 0; short gwReads = 0; // #include "msgsize.c" parse_options(argc, argv); printf("********************************************************************\n"); printf("\n** Test HPI using Functions **\n"); if (nNumFiles == 0) { haveFiles = 0; nNumFiles = 32; } else haveFiles = 1; // open subsystem and find adapters err = HPI_SubSysSetHostNetworkInterface(NULL, ""); if (err && (err != HPI_ERROR_INVALID_FUNC) ) { printf("HPI_SubSysSetHostNetworkInterface error\n"); HandleError(err); } printf("********************************************************************\n"); printf("HPI_SubSysCreate\n"); hSubSys = HPI_SubSysCreate(); if (hSubSys == NULL) { printf("hSubSys==NULL\n"); exit(1); } err = HPI_SubSysGetVersionEx(hSubSys, &dwVersion); HandleError(err); printf("HPI_SubSysGetVersionEx=%x\n", dwVersion); err = HPI_SubSysGetNumAdapters(hSubSys, &numAdapters); printf("%li HPI_SubSysFindAdapters found %d adapters\n ", testcount++, numAdapters); HandleError(err); if (numAdapters > HPI_MAX_ADAPTERS) numAdapters = HPI_MAX_ADAPTERS; for (i = 0; i < (uint32_t)numAdapters; i++) { uint32_t dwAdapterIndex; uint16_t wAdapterType; err = HPI_SubSysGetAdapter(hSubSys, i, &dwAdapterIndex, &wAdapterType ) ; printf("%d=%X\n ", dwAdapterIndex, wAdapterType); if (dwAdapterIndex == wAdapterIndex) adapterFound = 1; } if (!adapterFound) { printf("No adapter with index %d\n", wAdapterIndex); exit(1); } err = HPI_AdapterClose(hSubSys, wAdapterIndex); if ( err && (err != HPI_ERROR_OBJ_NOT_OPEN) ) HandleError(err); printf("HPI_AdapterClose \n"); // open 1st adapter err = HPI_AdapterOpen(hSubSys, wAdapterIndex); HandleError(err); printf("HPI_AdapterOpen \n"); err = HPI_AdapterGetInfo(hSubSys, wAdapterIndex, &wNumOutStreams, &wNumInStreams, &wVersion, &dwSerialNumber, &wType); HandleError(err); printf("HPI_AdapterGetInfo\n"); printf("Adapter ID=%4X Index=%d NumOutStreams=%d NumInStreams=%d S/N=%d\nHw Version %c%d DSP code version %03d\n", wType, wAdapterIndex, wNumOutStreams, wNumInStreams, dwSerialNumber, ((wVersion >> 3) & 0xf) + 'A', // Hw version major wVersion & 0x7, // Hw version minor ((wVersion >> 13) * 100) + ((wVersion >> 7) & 0x3f) // DSP code version ); // apply the max streams options if (wNumOutStreams > max_outstreams) wNumOutStreams = max_outstreams; if (wNumInStreams > max_instreams) wNumInStreams = max_instreams; if (nNumFiles > wNumOutStreams) { nNumFiles = wNumOutStreams; } err = HPI_AdapterGetMode(hSubSys, wAdapterIndex, ¤t_mode); printf("Adapter current mode %d\n", current_mode); if (new_mode && (new_mode != current_mode)) { err = HPI_AdapterSetMode(hSubSys, wAdapterIndex, new_mode); HandleError(err); printf("Changed adapter mode. Reload driver to activate.\n"); exit(0); } // open the mixer of this adapter err = HPI_MixerOpen(hSubSys, wAdapterIndex, &hMixer); printf("HPI_MixerOpen: handle=%08X\n", hMixer); HandleError(err); if (dump_mixer) print_mixer_controls(hSubSys, hMixer); err = HPI_MixerGetControl(hSubSys, hMixer, HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0, HPI_CONTROL_SAMPLECLOCK, &hControl); if (!err) { err = HPI_SampleClock_SetLocalRate(hSubSys, hControl, samplerate); /* not all adapters support the above call ie ASI2416s */ if (err) printf("HPI_SampleClock_SetLocalRate() error %d\n",err); } #ifndef HPI_BUILD_NO_STREAMS if (wNumOutStreams) { // open the out_streams printf("HPI_OutStreamOpen\n"); for (f = 0; f < wNumOutStreams; f++) { err = HPI_OutStreamOpen(hSubSys, wAdapterIndex, f, &hOutStream[f] ); printf(" %i:%08X ", f, hOutStream[f]); HandleError(err); if (outstream_bbm) { printf("HPI_OutStreamHostBufferAllocate "); err = HPI_OutStreamHostBufferAllocate(hSubSys, hOutStream[f], BLOCK_SIZE); if (err == HPI_ERROR_INVALID_FUNC) outstream_bbm = 0; else HandleError(err); } err = HPI_OutStreamReset(hSubSys, hOutStream[f]); HandleError(err); // find out some info about the stream if (hOutStream[f]) { err = HPI_OutStreamGetInfoEx(hSubSys, hOutStream[f], NULL, // state &dwStrBufferSize, NULL, NULL, NULL); HandleError(err); printf(" HPI_OutStreamGetInfo %d: BufferSize=%d\n", f, dwStrBufferSize); } } } // setup format and size of data block // we will use to send audio data to out_stream // we would normally get the format directly from the file // or audio data err = HPI_FormatCreate( &FormatW, channels, format, samplerate, bitrate, 0 // no attributes ); HandleError(err); dwDataSizeW = BLOCK_SIZE / 2; if (wNumInStreams) { // if the adapter has instreams then open them printf("\nHPI_InStreamOpen "); for (f = 0; f < wNumInStreams; f++) { err = HPI_InStreamOpen(hSubSys, wAdapterIndex, f, &hInStream[f] ); printf(" %i:%08X ", f, hInStream[f]); HandleError(err); } if (wNumInStreams) { // find out some info about stream 0 err = HPI_InStreamGetInfoEx(hSubSys, hInStream[0], NULL, &dwIStrBufferSize, NULL, NULL, NULL); printf("\nHPI_InStreamGetInfo %i: BufferSize=%d\n", 0, dwStrBufferSize); HandleError(err); err = HPI_FormatCreate( &FormatR, channels, format, samplerate, bitrate, 0 // no attributes ); HandleError(err); err = HPI_InStreamQueryFormat(hSubSys, hInStream[0], &FormatR); HandleError(err); dwDataSizeR = BLOCK_SIZE / 2; err = HPI_MixerGetControl(hSubSys, hMixer, 0, 0, HPI_DESTNODE_ISTREAM, 0, HPI_CONTROL_METER, &hMeterControl); printf("HPI_MixerGetControl - PeakMeter: handle=%08X\n", hMeterControl); HandleError(err); } } if (wNumOutStreams) { printf("********************************************************************\n"); gwReads = 0; // open some audio files to play printf("Opening files \n"); for (f = 0; f < nNumFiles; f++) THPI_WavFileOpen(f, szFile[f]); //check first available open stream to make sure we can play this format for (f = 0; f < nNumFiles; f++) if (hOutStream[f]) { printf("HPI_OutStreamQueryFormat\n"); err = HPI_OutStreamQueryFormat(hSubSys, hOutStream[f], &FormatW); HandleError(err); break; } // get mixer meter control on out_stream0 err = HPI_MixerGetControl(hSubSys, hMixer, HPI_SOURCENODE_OSTREAM, 0, 0, 0, HPI_CONTROL_METER, &hMeterControl); printf("HPI_MixerGetControl - PeakMeter: handle=%08X\n", hMeterControl); HandleError(err); for (f = 1; f >= 0; f--) { // get mixer volume control on the connection // between out_stream0 and lineOut0 err = HPI_MixerGetControl(hSubSys, hMixer, HPI_SOURCENODE_OSTREAM, f, HPI_DESTNODE_LINEOUT, f, HPI_CONTROL_VOLUME, &ahGainControl[f] ); // HandleError( err ); Ignore the error, some adapters don't have this control if (err == 0) { printf("HPI_MixerGetControl - Volume: handle=%08X\n", ahGainControl[f]); // test - set gain on stream anGainLog[f][0] = 0; //-4*f; anGainLog[f][1] = 0; // -4*f-2; err = HPI_VolumeSetGain(hSubSys, ahGainControl[f], anGainLog[f] ); HandleError(err); } } } { uint16_t wState = 0; uint32_t dwDataToPlay = 0; FILE *recfile[8]; char recname[] = "rec0.pcm"; // preload buffer of stream if (wNumOutStreams) { printf("Preload\n"); for (f = 0; f < nNumFiles; f++) { if (hOutStream[f]) { for (i = 0; i < ((dwStrBufferSize - 4) / dwDataSizeW); i++) { //printf("f=%d, i=%d,bs=%d,ds=%d\n",f,i,dwStrBufferSize,DataW.dwDataSize); // out_stream #1 THPI_WavFileRead(f, abBuffer, dwDataSizeW); err = HPI_OutStreamWriteBuf (hSubSys, hOutStream[f], abBuffer, dwDataSizeW, &FormatW); HandleError(err); err = HPI_OutStreamGetInfoEx (hSubSys, hOutStream[f], &wState, NULL, &dwDataToPlay, NULL, NULL); HandleError(err); printf("[%i] D=%03d S=%d \r", f, dwDataToPlay / 1000, wState); } printf("\n"); } } // start play back printf("********************************************************************\n"); printf("HPI_OutStreamStart "); for (f = 0; f < nNumFiles; f++) { if (hOutStream[f]) { err = HPI_OutStreamStart(hSubSys, hOutStream[f] ); HandleError(err); printf("%i ", f); } } printf("\n"); } for (f = 0; f < wNumInStreams; f++) { printf("%d: ", f); if (instream_bbm) { printf("HPI_InStreamHostBufferAllocate "); err = HPI_InStreamHostBufferAllocate(hSubSys, hInStream[f], BLOCK_SIZE); if (err == HPI_ERROR_INVALID_FUNC) instream_bbm = 0; else HandleError(err); } printf("HPI_InStreamSetFormat "); err = HPI_InStreamSetFormat(hSubSys, hInStream[f], &FormatR); HandleError(err); printf("HPI_InStreamReset "); err = HPI_InStreamReset(hSubSys, hInStream[f]); HandleError(err); printf("HPI_InStreamStart \n"); err = HPI_InStreamStart(hSubSys, hInStream[f]); HandleError(err); if (record_to_file) { if (szFile[f][0]) recfile[f] = fopen(szFile[f], "w"); else { recname[3] = f + '0'; recfile[f] = fopen(recname, "w"); } } } // monitor state of streams and stop when empty // don't run anything if there are no in streams or out streams if ( wNumInStreams + wNumOutStreams == 0 ) runtime = 1; while (--runtime) { int do_print = ((runtime % PRINT_INTERVAL) == 0); poll_delay(); if (do_print && wNumInStreams) printf("IN :"); for (f = 0; f < wNumInStreams; f++) { //get state of in stream err = HPI_InStreamGetInfoEx(hSubSys, hInStream[f], &wState, NULL, &dwDataToPlay, NULL, NULL); HandleError(err); if (do_print) printf("%03d %d ", dwDataToPlay / 1000, wState); if (dwDataToPlay >= dwDataSizeR) { dwDataToPlay = dwDataSizeR; err = HPI_InStreamReadBuf(hSubSys, hInStream[f], abBuffer, dwDataToPlay); HandleError(err); if (record_to_file) fwrite(abBuffer, dwDataToPlay, 1, recfile[f]); } } if (do_print && wNumInStreams) printf("\n"); if (do_print && wNumOutStreams) printf("OUT:"); for (f = 0; f < nNumFiles; f++) { if (hOutStream[f]) { //get state of stream err = HPI_OutStreamGetInfoEx(hSubSys, hOutStream[f], &wState, NULL, &dwDataToPlay, NULL, NULL); HandleError(err); if (do_print) printf("%03d %d ", dwDataToPlay / 1000, wState); if ((dwStrBufferSize - dwDataToPlay) > dwDataSizeW) { THPI_WavFileRead(f, abBuffer, dwDataSizeW); err = HPI_OutStreamWriteBuf (hSubSys, hOutStream[f], abBuffer, dwDataSizeW, &FormatW); HandleError(err); } } } if (do_print && wNumOutStreams) printf("\n"); } if (record_to_file) for (f = 0; f < wNumInStreams; f++) fclose(recfile[f]); printf("\n"); } for (f = 0; f < nNumFiles; f++) THPI_WavFileClose(f); if (wNumOutStreams) { printf("HPI_OutStreamStop "); for (f = 0; f < nNumFiles; f++) { if (hOutStream[f]) { err = HPI_OutStreamStop(hSubSys, hOutStream[f]); printf("%i ", f); HandleError(err); } } printf("\nHPI_OutStreamClose "); for (f = 0; f < wNumOutStreams; f++) { if (hOutStream[f]) { if (outstream_bbm) err = HPI_OutStreamHostBufferFree (hSubSys, hOutStream[f]); err = HPI_OutStreamClose(hSubSys, hOutStream[f]); printf("%i ", f); HandleError(err); } } } if (wNumInStreams) { printf("\nHPI_InStreamStop \n"); err = HPI_InStreamStop(hSubSys, hInStream[0]); HandleError(err); printf("\nHPI_InStreamClose "); for (f = 0; f < wNumInStreams; f++) { if (instream_bbm) err = HPI_InStreamHostBufferFree(hSubSys, hInStream[f]); err = HPI_InStreamClose(hSubSys, hInStream[f]); printf("%i ", f); HandleError(err); } } #endif // HPI_BUILD_NO_STREAMS err = HPI_MixerClose(hSubSys, hMixer); printf("\nHPI_MixerClose\n"); HandleError(err); err = HPI_AdapterClose(hSubSys, wAdapterIndex); printf("HPI_AdapterClose\n"); HandleError(err); HPI_SubSysFree(hSubSys); return 0; } /******************************THPI_WavFileOpen **********************/ FILE *gpFile[8]; static void THPI_WavFileOpen( short nIndex, char *pszFile ) { if (haveFiles) { printf("%s ", pszFile); gpFile[nIndex] = fopen(pszFile, "rb"); if (!gpFile[nIndex]) { printf("****ERROR**** - can't open file\n"); getch(); exit(0); } if (toupper(pszFile[strlen(pszFile) - 1]) == 'S') fseek(gpFile[nIndex], 512, SEEK_SET); //.DSS file else fseek(gpFile[nIndex], 0x50, SEEK_SET); //.WAV file } } /******************************THPI_WavFileRead **********************/ static short THPI_WavFileRead( short nIndex, uint8_t *pbData, long lLength ) { long lNumRead; long i = 0; uint16_t wSine; if (haveFiles) { lNumRead = fread(pbData, 1, lLength, gpFile[nIndex]); //read WAV file if (lNumRead != lLength) return (1); else return (0); } else { // setup sinewave in buffer for (i = 0; i < lLength / 4; i++) { wSine = (uint16_t)(32767 * sin(2 * 3.141592653 * i / 32)); pbData[(short)i * 4] = (uint8_t)wSine; //left LSB pbData[(short)i * 4 + 1] = (uint8_t)(wSine >> 8); //left MSB pbData[(short)i * 4 + 2] = (uint8_t)wSine; //right LSB pbData[(short)i * 4 + 3] = (uint8_t)(wSine >> 8); //right MSB } return (0); } } /******************************THPI_WavFileClose **********************/ static void THPI_WavFileClose(short nIndex) { if (haveFiles) fclose(gpFile[nIndex]); } /****************************** HandleError **********************/ static void HandleError(hpi_err_t err) { char szError[256]; char nK = 0; if (err) { HPI_GetErrorText(err, szError); printf("ERROR %d %s\n", err, szError); if (!yes) { printf("press Enter to continue, (q,Enter) to exit...\n"); nK = getch(); if (nK == 'q') exit(0); } } } static int getch( void ) { return getchar(); } /* END_OF_CODE */
1.7.3