dual_mono_record/main.c

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.

00001 /* $Header: /Repository/apps/asx/examples/dual_mono_record/main.c,v 1.5 2004/10/13 18:16:08 as-tfe Exp $ */
00002 #include "stdio.h"
00003 #include "stdlib.h"
00004 #include "asx.h"
00005 #include "asxstring.h"
00006 
00007 ASX_HANDLE hSystem=0;
00008 
00009 int CheckError(ASX_HANDLE hObj, int nLine);
00010 void PrintControlName(ASX_HANDLE hControl);
00011 
00012 int main(int argc, char* argv[])
00013 {
00014     char *pszName;
00015     ASX_HANDLE hAdapter;
00016     ASX_HANDLE hMixer;
00017     ASX_HANDLE hRecorder[4];
00018     ASX_HANDLE hChannelMode[4];
00019     ASX_HANDLE hMux[4];
00020     int nAdapterToUse=0;
00021     int i,nLen;
00022     char szFilenames[][16]={ "test1.wav","test2.wav","test3.wav","test4.wav"};
00023 
00024     // create the system
00025     ASX_System_Create(ASX_SYSTEM_TYPE_HPI,&hSystem);
00026     CheckError(hSystem, __LINE__);
00027 
00028     // get the adapter
00029     ASX_System_GetAdapter(hSystem,nAdapterToUse,&hAdapter);
00030     CheckError(hAdapter, __LINE__);
00031 
00032     ASX_Adapter_GetName(hAdapter,0,0,&nLen);
00033     CheckError(hAdapter, __LINE__);
00034     pszName = (char *)malloc(nLen);
00035     ASX_Adapter_GetName(hAdapter,pszName,nLen,&nLen);
00036     CheckError(hAdapter, __LINE__);
00037     printf("Adapter [%d] is %s \n", nAdapterToUse,pszName);
00038 
00039     // get the mixer handle
00040     ASX_Adapter_GetMixer( hAdapter, &hMixer );
00041     CheckError(hAdapter, __LINE__);
00042 
00043     // Grab a recorder, channel mode and mux control for each recorder.
00044     for(i=0; i<4; i++)
00045     {
00046         // get a record object
00047         ASX_Mixer_GetControlByNodeTypeAndIndex(
00048             hMixer,
00049             0,0,
00050             asxNODE_RECORDER,i,
00051             asxCONTROL_RECORDER,
00052             &hRecorder[i]);
00053         CheckError(hMixer, __LINE__);
00054 
00055         // print out some control details
00056         PrintControlName(hRecorder[i]);
00057 
00058         // get multiplexer object
00059         ASX_Mixer_GetControlByNodeTypeAndIndex(
00060             hMixer,
00061             0,0,
00062             asxNODE_RECORDER,i,
00063             asxCONTROL_MULTIPLEXER,
00064             &hMux[i]);
00065         CheckError(hMixer, __LINE__);
00066 
00067         // set the multiplexer to the correct line in
00068         switch(i)
00069         {
00070             case 0:
00071             case 1:
00072                 ASX_Multiplexer_Set( hMux[i], asxNODE_LINE_IN, 0);
00073                 CheckError(hMux[i], __LINE__);
00074                 break;
00075             case 2:
00076             case 3:
00077                 ASX_Multiplexer_Set( hMux[i], asxNODE_LINE_IN, 1);
00078                 CheckError(hMux[i], __LINE__);
00079                 break;
00080         }
00081 
00082         // get channel mode object
00083         ASX_Mixer_GetControlByNodeTypeAndIndex(
00084             hMixer,
00085             0,0,
00086             asxNODE_RECORDER,i,
00087             asxCONTROL_CHANNEL_MODE,
00088             &hChannelMode[i]);
00089         CheckError(hMixer, __LINE__);
00090 
00091         // set the channel mode
00092         switch(i)
00093         {
00094             case 0:
00095             case 2:
00096                 ASX_ChannelMode_Set( hChannelMode[i], asxCHANNELMODE_NORMAL);
00097                 CheckError(hChannelMode[i], __LINE__);
00098                 break;
00099             case 1:
00100             case 3:
00101                 ASX_ChannelMode_Set( hChannelMode[i], asxCHANNELMODE_SWAP);
00102                 CheckError(hChannelMode[i], __LINE__);
00103                 break;
00104         }
00105     }
00106 
00107     // open the player and pass in the file to be played
00108     for(i=0; i<4; i++)
00109     {
00110         printf("Open recorder %d\n",i);
00111         ASX_Recorder_Open(
00112             hRecorder[i], 
00113             szFilenames[i],
00114             asxFILE_FORMAT_WAV,     // file format
00115             asxFILE_MODE_CREATE,    // file mode (create vs append)
00116             1,                      // channels = 1 or 2 at present
00117             asxAUDIO_FORMAT_PCM16,  // sample format
00118             44100,                  // sample rate = 8000 to 192000 Hz
00119             0,                      // 8000 to 384000 bps (MPEG only)
00120             asxRECORD_MODE_DONT_CARE    // MPEG mode
00121             );
00122         CheckError(hRecorder[i], __LINE__);
00123     }
00124 
00125     // start recording all files
00126     for(i=0; i<4; i++)
00127     {
00128         ASX_Recorder_Start( hRecorder[i] );
00129         CheckError(hRecorder[i], __LINE__);
00130     }
00131 
00132     // wait for recording completion
00133     printf("Hit enter to end recording\n");
00134     getchar();
00135 
00136     for(i=0; i<4; i++)
00137     {
00138         ASX_Recorder_Stop( hRecorder[i] );
00139         CheckError(hRecorder[i], __LINE__);
00140     }
00141 
00142     printf("Recording complete.\n");
00143 
00144     // close the file being recorded
00145     for(i=0; i<4; i++)
00146     {
00147         ASX_Recorder_Close(hRecorder[i]);
00148         CheckError(hRecorder[i], __LINE__);
00149     }
00150 
00151     printf("Press ENTER to exit\n");
00152     getchar();
00153     ASX_System_Delete(hSystem);
00154     return 0;
00155 }
00156 
00157 void PrintControlName(ASX_HANDLE hControl)
00158 {
00159     char *pszName;
00160     int nLen;
00161     enum asxCONTROL eControl;
00162 
00163     ASX_Control_GetType(hControl, &eControl);
00164     ASXSTRING_EnumToString(eControl,0,0,&nLen);
00165     pszName=(char *)malloc(nLen);
00166     ASXSTRING_EnumToString(eControl,pszName,nLen,&nLen);
00167     printf("Control : %s\n",pszName);
00168 
00169     free(pszName);
00170 }
00171 
00172 int CheckError(ASX_HANDLE hObj, int nLine)
00173 {
00174     int nError;
00175     int asxSubSystemErrorCode=0;
00176     char *pszAsxErrorString;
00177     char *pszAsxSubSystemErrorString;
00178     int nLen1,nLen2;
00179 
00180     ASX_Error_GetLast( hObj, &nError, &asxSubSystemErrorCode);
00181     if(!nError)
00182         return 0;
00183     ASX_Error_GetLastString( hObj, 0,0,&nLen1,0,0,&nLen2);
00184     pszAsxErrorString = (char *)malloc(nLen1);
00185     pszAsxSubSystemErrorString = (char *)malloc(nLen2);
00186     ASX_Error_GetLastString( hObj, pszAsxErrorString,nLen1,&nLen1,pszAsxSubSystemErrorString,nLen2,&nLen2);
00187     printf("Error: #%d, %s - Subsystem Error: #%ld, %s \n",
00188         nError,
00189         pszAsxErrorString,
00190         asxSubSystemErrorCode,
00191         pszAsxSubSystemErrorString );
00192     printf("When called from source %s line %d\n",__FILE__,nLine);
00193 
00194     printf("Press ENTER to exit\n");
00195     getchar();
00196     free(pszAsxErrorString);
00197     free(pszAsxSubSystemErrorString);
00198     ASX_System_Delete(hSystem);
00199     exit(1);
00200     return 1;
00201 }
00202 

Generated on Tue Nov 18 13:03:39 2008 for ASX by  doxygen 1.4.6-NO