Exemplo n.º 1
0
static void MciError(ULONG ulError)
{
	unsigned char buffer[128];
	ULONG rc;
	
	rc = mciGetErrorString(ulError, buffer, sizeof(buffer));
	
	if (rc == MCIERR_SUCCESS)
		sprintf(mmerror,"MCI Error %d: %s",ULONG_LOWD(ulError),buffer);
	else
		sprintf(mmerror,"MCI Error %d: Cannot query error message.",ULONG_LOWD(rc));
	
	error1("%s",mmerror);
}
Exemplo n.º 2
0
static int write_os2(audio_output_t *ao,unsigned char *buf,int len)
{
	if(len > audiobufsize || !playingbuffer) return -1;
	
	if(mmp.ulBitsPerSample == 16)
		ao->format = MPG123_ENC_SIGNED_16;
	else if(mmp.ulBitsPerSample == 8)
		ao->format = MPG123_ENC_UNSIGNED_8;
	else return -1;
	
	ao->rate = mmp.ulSamplesPerSec;
	ao->channels = mmp.ulChannels;
	
	if(buf && len)
	{
		ULONG rc;
		int upto;
		
		mstatp.ulItem = MCI_STATUS_POSITION;
		
		rc = mciSendCommand( maop.usDeviceID,
				MCI_STATUS,
				MCI_STATUS_ITEM | MCI_WAIT,
				&mstatp,
				0 );
		
		if ( ULONG_LOWD(rc) != MCIERR_SUCCESS )
		{
			MciError(rc);
			maop.usDeviceID = 0;
			return(-1);
		}
		
		/* this is hypocrite...
		DART returns the value in ulReturn instead of ulValue,
		also it returns in milliseconds and not MMTIME... arg */
		
		upto = (mstatp.ulReturn-playedbuffer.ulTime) * mmp.ulSamplesPerSec / 1000;
		upto *= mmp.ulChannels * (mmp.ulBitsPerSample>>3);
		
		/* if a timing problem occurs, let's at least not crash */
		if(upto > playingbuffer->ulBufferLength)
			upto = playingbuffer->ulBufferLength;
		
		if(len < upto) {
			memcpy(buf,(char *) (playingbuffer->pBuffer)+upto-len, len);
		} else {
			memcpy(buf,(char *) playedbuffer.pBuffer+playedbuffer.ulBufferLength-(len-upto),len-upto);
			memcpy(buf+(len-upto),playingbuffer->pBuffer,upto);
		}
	}
Exemplo n.º 3
0
int open_os2(audio_output_t *ao)
{
	ULONG rc,i;
	char *temp;
	ULONG openflags;
	PPIB ppib;
	USHORT bits;
	
	if(maop.usDeviceID) return (maop.usDeviceID);
	
	if(!ai) return -1;
	
	if(!ao->device) ao->device = "0";
	
	if(ao->rate < 0) ao->rate = 44100;
	if(ao->channels < 0) ao->channels = 2;
	if(ao->format < 0) ao->format = MPG123_ENC_SIGNED_16;
	
	if(ao->format == MPG123_ENC_SIGNED_16)
		bits = 16;
	else if(ao->format == MPG123_ENC_UNSIGNED_8)
		bits = 8;
	else return -1;
	
	/* open the mixer device */
	memset (&maop, 0, sizeof(maop));
	maop.usDeviceID = 0;
	maop.pszDeviceType = (PSZ) MAKEULONG(MCI_DEVTYPE_AUDIO_AMPMIX, atoi(ao->device));
	
	openflags = MCI_WAIT | MCI_OPEN_TYPE_ID;
	if(!lockdevice) openflags |= MCI_OPEN_SHAREABLE;
	
	rc = mciSendCommand(0, MCI_OPEN, openflags, &maop, 0);
	
	if (ULONG_LOWD(rc) != MCIERR_SUCCESS)
	{
		MciError(rc);
		maop.usDeviceID = 0;
		return(-1);
	}
	
	/* volume in ao->gain ?? */
	
	/* Set the MCI_MIXSETUP_PARMS data structure to match the audio stream. */
	
	memset(&mmp, 0, sizeof(mmp));
	
	mmp.ulBitsPerSample = bits;
	mmp.ulFormatTag = MCI_WAVE_FORMAT_PCM;
	mmp.ulSamplesPerSec = ao->rate;
	mmp.ulChannels = ao->channels;
	
	/* Setup the mixer for playback of wave data */
	mmp.ulFormatMode = MCI_PLAY;
	mmp.ulDeviceType = MCI_DEVTYPE_WAVEFORM_AUDIO;
	mmp.pmixEvent    = DARTEvent;
	
	rc = mciSendCommand( maop.usDeviceID,
		MCI_MIXSETUP,
		MCI_WAIT | MCI_MIXSETUP_INIT,
		&mmp,
		0 );
	
	if ( ULONG_LOWD(rc) != MCIERR_SUCCESS )
	{
		MciError(rc);
		maop.usDeviceID = 0;
		return(-1);
	}
	
	volume = audio_set_volume(ai,volume);
	
	/* Set up the BufferParms data structure and allocate
	* device buffers from the Amp-Mixer  */
	
	memset(&mbp, 0, sizeof(mbp));
	free(MixBuffers);
	free(bufferinfo);
	if(numbuffers < 5) numbuffers = 5;
	if(numbuffers > 200) numbuffers = 200;
	MixBuffers = calloc(numbuffers, sizeof(*MixBuffers));
	bufferinfo = calloc(numbuffers, sizeof(*bufferinfo));
	
	ulMCIBuffers = numbuffers;
	mbp.ulNumBuffers = ulMCIBuffers;
	/*   mbp.ulBufferSize = mmp.ulBufferSize; */
	/* I don't like this... they must be smaller than 64KB or else the
	engine needs major rewrite */
	mbp.ulBufferSize = audiobufsize;
	mbp.pBufList = MixBuffers;
	
	rc = mciSendCommand( maop.usDeviceID,
	MCI_BUFFER,
	MCI_WAIT | MCI_ALLOCATE_MEMORY,
	(PVOID) &mbp,
	0 );
	
	if ( ULONG_LOWD(rc) != MCIERR_SUCCESS )
	{
		MciError(rc);
		maop.usDeviceID = 0;
		return(-1);
	}
	
	pBufferplayed = playedbuffer.pBuffer = calloc(1,audiobufsize);
	
	ulMCIBuffers = mbp.ulNumBuffers; /* never know! */
	
	/* Fill all device buffers with zeros and set linked list */
	
	for(i = 0; i < ulMCIBuffers; i++)
	{
		MixBuffers[i].ulFlags = 0;
		MixBuffers[i].ulBufferLength = mbp.ulBufferSize;
		memset(MixBuffers[i].pBuffer, 0, MixBuffers[i].ulBufferLength);
		
		MixBuffers[i].ulUserParm = (ULONG) &bufferinfo[i];
		bufferinfo[i].NextBuffer = &MixBuffers[i+1];
	}
	
	bufferinfo[i-1].NextBuffer = &MixBuffers[0];
	
	/* Create a semaphore to know when data has been played by the DART thread */
	DosCreateEventSem(NULL,&dataplayed,0,FALSE);
	
	playingbuffer = &MixBuffers[0];
	tobefilled = &MixBuffers[1];
	playingframe = 0;
	nomoredata = TRUE;
	nobuffermode = FALSE;
	justflushed = FALSE;
	
	if(boostprio)
	{
		temp = alloca(strlen(boostprio)+1);
		strcpy(temp,boostprio);
		
		boostdelta = atoi(temp+1);
		*(temp+1) = 0;
		boostclass = atoi(temp);
	}
	if(boostclass > 4) boostdelta = 3;
	if(boostdelta > 31) boostdelta = 31;
	if(boostdelta < -31) boostdelta = -31;
	
	
	if(normalprio)
	{
		temp = alloca(strlen(normalprio)+1);
		strcpy(temp,normalprio);
		
		normaldelta = atoi(temp+1);
		*(temp+1) = 0;
		normalclass = atoi(temp);
	}
	if(normalclass > 4) normaldelta = 3;
	if(normaldelta > 31) normaldelta = 31;
	if(normaldelta < -31) normaldelta = -31;
	
	
	DosGetInfoBlocks(&mainthread,&ppib); /* ppib not needed, but makes some DOSCALLS.DLL crash */
	DosSetPriority(PRTYS_THREAD,boostclass,boostdelta,mainthread->tib_ptib2->tib2_ultid);
	
	/* Write buffers to kick off the amp mixer. see DARTEvent() */
	rc = mmp.pmixWrite( mmp.ulMixHandle,
		MixBuffers,
		ulMCIBuffers );
	
	return maop.usDeviceID;
}
Exemplo n.º 4
0
int OpenDevice()
{
 CHAR  achBuffer[CCHMAXPATH] = "";
 APIRET rc;
 MCI_AMP_OPEN_PARMS   AmpOpenParms;
 MCI_CONNECTOR_PARMS  ConnectorParms;
 MCI_AMP_SET_PARMS    AmpSetParms ;
 MCI_GENERIC_PARMS    GenericParms;
 int i;
 ULONG Action;
 ULONG Wrote;

   // Setup the open structure, pass the playlist and tell MCI_OPEN to use it
   memset(&AmpOpenParms,0,sizeof(AmpOpenParms));

   AmpOpenParms.usDeviceID = ( USHORT ) 0;
//   AmpOpenParms.pszDeviceType = ( PSZ ) MCI_DEVTYPE_AUDIO_AMPMIX;
   AmpOpenParms.pszDeviceType = (PSZ) MAKEULONG(MCI_DEVTYPE_AUDIO_AMPMIX, device);

   rc = mciSendCommand(0,
                       MCI_OPEN,
                       MCI_WAIT | MCI_OPEN_TYPE_ID | MCI_OPEN_SHAREABLE,
                       ( PVOID ) &AmpOpenParms,
                       0 );

   if (ULONG_LOWD(rc) != MCIERR_SUCCESS) {
        mciGetErrorString( rc, (PSZ)achBuffer,   sizeof( achBuffer));

   cout << "Error #" << ULONG_LOWD(rc) << ": " << achBuffer << endl;
	goto Init_Err;
   }
   DeviceId = AmpOpenParms.usDeviceID;

   //Grab exclusive rights to device instance (NOT entire device)
   GenericParms.hwndCallback = 0;	//Not needed, so set to 0
   rc = mciSendCommand(DeviceId, MCI_ACQUIREDEVICE, MCI_EXCLUSIVE_INSTANCE,
		       (PVOID)&GenericParms, 0);
   if (ULONG_LOWD(rc) != MCIERR_SUCCESS) {
        mciGetErrorString( rc, (PSZ)achBuffer,   sizeof( achBuffer));

   cout << "Error #" << ULONG_LOWD(rc) << ": " << achBuffer << endl;
   goto Init_Err;
   }

   /* Set the MixSetupParms data structure to match the loaded file.
    * This is a global that is used to setup the mixer.
    */
   memset( &MixSetupParms, 0, sizeof( MCI_MIXSETUP_PARMS ) );

   MixSetupParms.ulBitsPerSample = RecSettings.bits;
   MixSetupParms.ulSamplesPerSec = RecSettings.rate;
   MixSetupParms.ulFormatTag = RecSettings.format;
   MixSetupParms.ulChannels = RecSettings.numchan;

   /* Setup the mixer for playback of wave data
    */
   MixSetupParms.ulFormatMode = MCI_RECORD;
   MixSetupParms.ulDeviceType = MCI_DEVTYPE_WAVEFORM_AUDIO;
   MixSetupParms.pmixEvent    = MixHandler;

   rc = mciSendCommand( DeviceId,
                        MCI_MIXSETUP,
                        MCI_WAIT | MCI_MIXSETUP_INIT,
                        ( PVOID ) &MixSetupParms,
                        0 );

   if ( rc != MCIERR_SUCCESS ) {
        mciGetErrorString( rc, (PSZ)achBuffer,   sizeof( achBuffer));

   cout << "Error #" << hex << rc << ": " << achBuffer << endl;
   goto Init_Err;
   }

   /* Use the suggested buffer size provide by the mixer device
    * and the size of the audio file to calculate the required
    * number of Amp-Mixer buffers.
    */
   ulNumBuffers = NUM_BUFFERS;

   /*
    * Set up the BufferParms data structure and allocate
    * device buffers from the Amp-Mixer
    */
   MixSetupParms.ulBufferSize = ulBuffersize;
	
   BufferParms.ulNumBuffers = ulNumBuffers;
   BufferParms.ulBufferSize = MixSetupParms.ulBufferSize;
   BufferParms.pBufList = MixBuffers;


   for(i=0;i<NUM_BUFFERS;i++) {
	MixBuffers[i].ulUserParm = i;	//nr of buffer (used in mixer.c)
   }

   rc = mciSendCommand( DeviceId,
                        MCI_BUFFER,
                        MCI_WAIT | MCI_ALLOCATE_MEMORY,
                        ( PVOID ) &BufferParms,
                        0 );

   if ( ULONG_LOWD( rc) != MCIERR_SUCCESS ) {
	goto Init_Err;
   }

   rc = wavfile.openWAV(filename, CREATE, RecSettings.rate,
              RecSettings.numchan, RecSettings.bits, RecSettings.format);
   if(rc)     goto Init_Err;

#if 0
   rc = DosOpen(filename,       	/* file name from Open dialog */
  	      &modin,	      		/* file handle returned */
	      &Action,
	      0L,
	      FILE_NORMAL,
              OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_REPLACE_IF_EXISTS,
              OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYWRITE,
	      (PEAOP2)NULL);
   if(rc)     goto Init_Err;
   //save settings to file
   DosWrite(modin, (char *)&RecSettings, sizeof(RecSettings), &Wrote);
#endif
   
   /* Set the connector to 'line in'
    */
   memset( &ConnectorParms, '\0', sizeof( MCI_CONNECTOR_PARMS ) );
   ConnectorParms.ulConnectorType = MCI_LINE_IN_CONNECTOR;

   rc = mciSendCommand( DeviceId,
                       MCI_CONNECTOR,
                       MCI_WAIT |
                       MCI_ENABLE_CONNECTOR |
                       MCI_CONNECTOR_TYPE,
                       ( PVOID ) &ConnectorParms,
                       0 );

   /* Allow the user to hear what is being recorded
    * by turning the monitor on
    */
   memset( &AmpSetParms, '\0', sizeof( MCI_AMP_SET_PARMS ) );
   AmpSetParms.ulItem = MCI_AMP_SET_MONITOR;
   rc = mciSendCommand( DeviceId,
                       MCI_SET,
                       MCI_WAIT | MCI_SET_ON | MCI_SET_ITEM,
                       ( PVOID ) &AmpSetParms,
                       0 );

   return(TRUE);
Init_Err:
   return(FALSE);
}
ULONG ConnectToAmp( INSTANCE           *ulpInstance,
                    MMDRV_OPEN_PARMS   *pDrvOpenParams,
                    ULONG              ulOpenFlags )

{

  ULONG                ulDeviceTypeID;         // device id of connected device
  ULONG                ulrc;                   // return code variable
//  ULONG                ulHoldError;
  USHORT               usConnLength;           // length of conn struct

  MCI_AMP_OPEN_PARMS   MCIAmpOpenParms;          // MCI AmpMixer Open Parameters
  DEFAULTCONNECTIONS2  DefCon;                   // MCI Connections Block
//  SPCB                 tempspcb;
  MMAUDIOHEADER        mmaudioheader;
  VSD_AUDIOOPEN_PARMS  vsdOpen;
  CONCB                concb;

  /* Inform the amp how we wish to initialize the device */

  memmove( &mmaudioheader, &ulpInstance->mmAudioHeader, sizeof( MMAUDIOHEADER ));
  vsdOpen.pHeader = ( PVOID) &mmaudioheader;
  vsdOpen.ulFlags = VSD_AUDIO_OPEN;
  vsdOpen.ulReserved2 = (ULONG) &concb;


  /*****************************
  * Obtain WaveAudio Device ID
  *****************************/
  ulpInstance->usWaveDeviceID = pDrvOpenParams->usDeviceID;

  ulDeviceTypeID = MAKEULONG ( MCI_DEVTYPE_WAVEFORM_AUDIO,
                               pDrvOpenParams->usDeviceOrd);

  /******************************************************
  * Ensure that the INI file contains the right device id
  ******************************************************/

  if ( pDrvOpenParams->usDeviceType != MCI_DEVTYPE_WAVEFORM_AUDIO )
     {
     return ( MCIERR_INI_FILE );
     }

  usConnLength = sizeof(DEFAULTCONNECTIONS2);

  ulrc =  mciQueryDefaultConnections ( ulDeviceTypeID,
                                       &DefCon,
                                       &usConnLength);

  /******************************************************
  * Ensure that the INI file says that we are connected
  * to an amp mixer.  If it says that we are connected
  * to ourselves, return an error.
  ******************************************************/

  if ( ULONG_LOWD( DefCon.dwDeviceTypeID2 ) == MCI_DEVTYPE_WAVEFORM_AUDIO )
     {
     return ( MCIERR_INI_FILE );
     }

  /******************************
  * Open an AMP/MIXER Instance
  ******************************/

  MCIAmpOpenParms.pszDeviceType = (PSZ) DefCon.dwDeviceTypeID2;

  MCIAmpOpenParms.hwndCallback = (ULONG) NULL;

// 6421 --no need to retrive this information any more
// we are truly device independent

//  GetPDDName (DefCon.dwDeviceTypeID2, szPDDName);

//  strcpy ( ulpInstance->szAudioDevName, szPDDName);

  /* Copy the name of the pdd + vsd dll to amp structure */

//  strcpy ((PSZ) AMPMIX.szDeviceName,
//          ulpInstance->szAudioDevName);

//  strcpy ((PSZ) ulpInstance->StreamInfo.AudioDCB.szDevName,
//          ulpInstance->szAudioDevName);

  /*******************************************
  * The current amp/mixer uses an undocumented
  * structure.  Pass this structure in on the
  * open also.
  ********************************************/

  MCIAmpOpenParms.pDevDataPtr = (PVOID) &vsdOpen;


  /* Open what we are connected to--usually the amp */

  ulrc = mciSendCommand (0,
                         MCI_OPEN,
                         MCI_OPEN_TYPE_ID| MCI_WAIT| ulOpenFlags,
                         (PVOID) &MCIAmpOpenParms,
                         0);

// CODEC change
   /*--------------------------------------------
   * It is possible that the VSD may require a
   * best fit.  Try with the best fit parameters.
   *-------------------------------------------*/
     if (ulrc)

        {
#ifndef CONNECTION
        if ( ulrc == MCIERR_UNSUPP_FORMAT_TAG )
           {
           /* Open what we are connected to--usually the amp */

           ulrc = mciSendCommand (0,
                                  MCI_OPEN,
                                  MCI_OPEN_TYPE_ID| MCI_WAIT| ulOpenFlags,
                                  (PVOID) &MCIAmpOpenParms,
                                  0);
           }
       if ( ulrc )
#endif
          {
          return ( ulrc );
          }
        ulpInstance->ulRealTimeTranslation = MMIO_REALTIME;
        memmove( &ulpInstance->mmAudioHeader, &mmaudioheader, sizeof( MMAUDIOHEADER ) );
        } /* If the amp-mixer could not deal with the data type */
     else
        {
        ulpInstance->ulRealTimeTranslation = MMIO_NONREALTIME;
        }
// CODEC feature--removed functionality


  /* Remember the amp device id so that we can close it */

  ulpInstance->usAmpDeviceID = MCIAmpOpenParms.usDeviceID;

#ifndef CONNECTION
  ulrc = GetMixerInfo( ulpInstance, &concb );

  if ( ulrc )
     {
     /*-----------------------------------------
     * Ensure that the amp-mixer is CLOSED!!!!!!
     * Else an error will lock the device.
     *------------------------------------------*/

     mciSendCommand ((WORD)ulpInstance->usAmpDeviceID,
                     MCI_CLOSE,
                     MCI_WAIT,
                     0,
                     0);
     }
#endif

  return ( ulrc );


} /* ConnectToAmp */