|
ASX Version4.11.09
|
This is an example of how to use the ASX Recorder to record dual mono inputs.All record streams on AudioScience audio adapters record, at a minimum, either mono or stereo files on the same device. Mono recording always records the left channel to an audio file. So to record the right channel of a line in, the channels must be swapped somewhere in the record path. This can be done using the Channel Mode control that is present on the record node of most AudioScience adapters.
Configuration Steps
The following steps should be performed to setup recording of 4 independent mono streams. We are going to record in the following configuration:
Record 1 <- Line In 1 Left Record 2 <- Line In 1 Right Record 3 <- Line In 2 Left Record 4 <- Line In 2 Right
1. Find multiplexer controls on Record nodes and set sources as follows:
Record 1 <- Line In 1 Record 2 <- Line In 1 Record 3 <- Line In 2 Record 4 <- Line In 2
2. Find channel mode controls and set up as follows:
Record 1, Channel Mode = "normal" Record 2, Channel Mode = "swap" Record 3, Channel Mode = "normal" Record 4, Channel Mode = "swap"
3. Open record devices
4. Set record streams to record 4 mono files
5. Start recording.
These instructions remain the same whether the functionality is implemented with Microsoft Multimedia waveXXXX() and mixerXXX() calls, HPI or ASX calls. The next section details ASX recording instructions.
/* $Header: /home/eliot/asi/repo/cvsrepo/Repository/apps/asx/examples/dual_mono_record/main.c,v 1.5 2004/10/13 18:16:08 as-tfe Exp $ */ #include "stdio.h" #include "stdlib.h" #include "asx.h" #include "asxstring.h" ASX_HANDLE hSystem=0; int CheckError(ASX_HANDLE hObj, int nLine); void PrintControlName(ASX_HANDLE hControl); int main(int argc, char* argv[]) { char *pszName; ASX_HANDLE hAdapter; ASX_HANDLE hMixer; ASX_HANDLE hRecorder[4]; ASX_HANDLE hChannelMode[4]; ASX_HANDLE hMux[4]; int nAdapterToUse=0; int i,nLen; char szFilenames[][16]={ "test1.wav","test2.wav","test3.wav","test4.wav"}; // create the system ASX_System_Create(ASX_SYSTEM_TYPE_HPI,&hSystem); CheckError(hSystem, __LINE__); // get the adapter ASX_System_GetAdapter(hSystem,nAdapterToUse,&hAdapter); CheckError(hAdapter, __LINE__); ASX_Adapter_GetName(hAdapter,0,0,&nLen); CheckError(hAdapter, __LINE__); pszName = (char *)malloc(nLen); ASX_Adapter_GetName(hAdapter,pszName,nLen,&nLen); CheckError(hAdapter, __LINE__); printf("Adapter [%d] is %s \n", nAdapterToUse,pszName); // get the mixer handle ASX_Adapter_GetMixer( hAdapter, &hMixer ); CheckError(hAdapter, __LINE__); // Grab a recorder, channel mode and mux control for each recorder. for(i=0; i<4; i++) { // get a record object ASX_Mixer_GetControlByNodeTypeAndIndex( hMixer, 0,0, asxNODE_RECORDER,i, asxCONTROL_RECORDER, &hRecorder[i]); CheckError(hMixer, __LINE__); // print out some control details PrintControlName(hRecorder[i]); // get multiplexer object ASX_Mixer_GetControlByNodeTypeAndIndex( hMixer, 0,0, asxNODE_RECORDER,i, asxCONTROL_MULTIPLEXER, &hMux[i]); CheckError(hMixer, __LINE__); // set the multiplexer to the correct line in switch(i) { case 0: case 1: ASX_Multiplexer_Set( hMux[i], asxNODE_LINE_IN, 0); CheckError(hMux[i], __LINE__); break; case 2: case 3: ASX_Multiplexer_Set( hMux[i], asxNODE_LINE_IN, 1); CheckError(hMux[i], __LINE__); break; } // get channel mode object ASX_Mixer_GetControlByNodeTypeAndIndex( hMixer, 0,0, asxNODE_RECORDER,i, asxCONTROL_CHANNEL_MODE, &hChannelMode[i]); CheckError(hMixer, __LINE__); // set the channel mode switch(i) { case 0: case 2: ASX_ChannelMode_Set( hChannelMode[i], asxCHANNELMODE_NORMAL); CheckError(hChannelMode[i], __LINE__); break; case 1: case 3: ASX_ChannelMode_Set( hChannelMode[i], asxCHANNELMODE_SWAP); CheckError(hChannelMode[i], __LINE__); break; } } // open the player and pass in the file to be played for(i=0; i<4; i++) { printf("Open recorder %d\n",i); ASX_Recorder_Open( hRecorder[i], szFilenames[i], asxFILE_FORMAT_WAV, // file format asxFILE_MODE_CREATE, // file mode (create vs append) 1, // channels = 1 or 2 at present asxAUDIO_FORMAT_PCM16, // sample format 44100, // sample rate = 8000 to 192000 Hz 0, // 8000 to 384000 bps (MPEG only) asxRECORD_MODE_DONT_CARE // MPEG mode ); CheckError(hRecorder[i], __LINE__); } // start recording all files for(i=0; i<4; i++) { ASX_Recorder_Start( hRecorder[i] ); CheckError(hRecorder[i], __LINE__); } // wait for recording completion printf("Hit enter to end recording\n"); getchar(); for(i=0; i<4; i++) { ASX_Recorder_Stop( hRecorder[i] ); CheckError(hRecorder[i], __LINE__); } printf("Recording complete.\n"); // close the file being recorded for(i=0; i<4; i++) { ASX_Recorder_Close(hRecorder[i]); CheckError(hRecorder[i], __LINE__); } printf("Press ENTER to exit\n"); getchar(); ASX_System_Delete(hSystem); return 0; } void PrintControlName(ASX_HANDLE hControl) { char *pszName; int nLen; enum asxCONTROL eControl; ASX_Control_GetType(hControl, &eControl); ASXSTRING_EnumToString(eControl,0,0,&nLen); pszName=(char *)malloc(nLen); ASXSTRING_EnumToString(eControl,pszName,nLen,&nLen); printf("Control : %s\n",pszName); free(pszName); } int CheckError(ASX_HANDLE hObj, int nLine) { int nError; int asxSubSystemErrorCode=0; char *pszAsxErrorString; char *pszAsxSubSystemErrorString; int nLen1,nLen2; ASX_Error_GetLast( hObj, &nError, &asxSubSystemErrorCode); if(!nError) return 0; ASX_Error_GetLastString( hObj, 0,0,&nLen1,0,0,&nLen2); pszAsxErrorString = (char *)malloc(nLen1); pszAsxSubSystemErrorString = (char *)malloc(nLen2); ASX_Error_GetLastString( hObj, pszAsxErrorString,nLen1,&nLen1,pszAsxSubSystemErrorString,nLen2,&nLen2); printf("Error: #%d, %s - Subsystem Error: #%ld, %s \n", nError, pszAsxErrorString, asxSubSystemErrorCode, pszAsxSubSystemErrorString ); printf("When called from source %s line %d\n",__FILE__,nLine); printf("Press ENTER to exit\n"); getchar(); free(pszAsxErrorString); free(pszAsxSubSystemErrorString); ASX_System_Delete(hSystem); exit(1); return 1; }
1.7.3