示例#1
0
static PaError Pa_TimeSlice( internalPortAudioStream   *past )
{
	PaError           result = 0;
	long              bytesEmpty = 0;
	long              bytesFilled = 0;
	long              bytesToXfer = 0;
	long              numChunks;
	HRESULT           hresult;
	PaHostSoundControl  *pahsc;
	short            *nativeBufPtr;
	past->past_NumCallbacks += 1;
	pahsc = (PaHostSoundControl *) past->past_DeviceData;
	if( pahsc == NULL ) return paInternalError;
/* How much input data is available? */
#if SUPPORT_AUDIO_CAPTURE
	if( past->past_NumInputChannels > 0 )
	{
		DSW_QueryInputFilled( &pahsc->pahsc_DSoundWrapper, &bytesFilled );
		bytesToXfer = bytesFilled;
	}
#endif /* SUPPORT_AUDIO_CAPTURE */
/* How much output room is available? */
	if( past->past_NumOutputChannels > 0 )
	{
		DSW_QueryOutputSpace( &pahsc->pahsc_DSoundWrapper, &bytesEmpty );
		bytesToXfer = bytesEmpty;
	}
	AddTraceMessage( "bytesEmpty ", bytesEmpty );
/* Choose smallest value if both are active. */
	if( (past->past_NumInputChannels > 0) && (past->past_NumOutputChannels > 0) )
	{
		bytesToXfer = ( bytesFilled < bytesEmpty ) ? bytesFilled : bytesEmpty;
	}
/*	printf("bytesFilled = %d, bytesEmpty = %d, bytesToXfer = %d\n",
		bytesFilled, bytesEmpty, bytesToXfer);
*/
/* Quantize to multiples of a buffer. */
	numChunks = bytesToXfer / pahsc->pahsc_BytesPerBuffer;
	if( numChunks > (long)(past->past_NumUserBuffers/2) )
	{
		numChunks = (long)past->past_NumUserBuffers/2;
	}
	else if( numChunks < 0 )
	{
		numChunks = 0;
	}
	AddTraceMessage( "numChunks ", numChunks );
	nativeBufPtr = pahsc->pahsc_NativeBuffer;
	if( numChunks > 0 )
	{
		while( numChunks-- > 0 )
		{
		/* Measure usage based on time to process one user buffer. */
			Pa_StartUsageCalculation( past );
	#if SUPPORT_AUDIO_CAPTURE
	/* Get native data from DirectSound. */
			if( past->past_NumInputChannels > 0 )
			{
				hresult = DSW_ReadBlock( &pahsc->pahsc_DSoundWrapper, (char *) nativeBufPtr, pahsc->pahsc_BytesPerBuffer );
				if( hresult < 0 )
				{
					ERR_RPT(("DirectSound ReadBlock failed, hresult = 0x%x\n",hresult));
					sPaHostError = hresult;
					break;
				}
			}
	#endif /* SUPPORT_AUDIO_CAPTURE */
	/* Convert 16 bit native data to user data and call user routine. */
			result = Pa_CallConvertInt16( past, nativeBufPtr, nativeBufPtr );
			if( result != 0) break;
	/* Pass native data to DirectSound. */
			if( past->past_NumOutputChannels > 0 )
			{
			/*	static short DEBUGHACK = 0;
				DEBUGHACK += 0x0049;
				nativeBufPtr[0] = DEBUGHACK; /* Make buzz to see if DirectSound still running. */
				hresult = DSW_WriteBlock( &pahsc->pahsc_DSoundWrapper, (char *) nativeBufPtr, pahsc->pahsc_BytesPerBuffer );
				if( hresult < 0 )
				{
					ERR_RPT(("DirectSound WriteBlock failed, result = 0x%x\n",hresult));
					sPaHostError = hresult;
					break;
				}
			}
			Pa_EndUsageCalculation( past );
		}
	}
	return result;
}
示例#2
0
static PaError Pa_AudioThreadProc( internalPortAudioStream   *past )
{
    PaError      result;
    PaHostSoundControl             *pahsc;
    ssize_t      bytes_read, bytes_written;

    pahsc = (PaHostSoundControl *) past->past_DeviceData;
    if( pahsc == NULL ) return paInternalError;

#ifdef GNUSTEP
    GSRegisterCurrentThread(); /* SB20010904 */
#endif

    result = PaHost_BoostPriority( past );
    if( result < 0 ) goto error;

    past->past_IsActive = 1;
    DBUG(("entering thread.\n"));

    while( (past->past_StopNow == 0) && (past->past_StopSoon == 0) )
    {
        /* Read data from device */
        if(pahsc->pahsc_NativeInputBuffer)
        {
            unsigned int totalread = 0;
            DBUG(("Pa_AudioThreadProc: attempt to read %d bytes\n", pahsc->pahsc_BytesPerInputBuffer));
            do
            {
                bytes_read = read(pahsc->pahsc_InputHandle,
                    (char *)pahsc->pahsc_NativeInputBuffer + totalread,
                    pahsc->pahsc_BytesPerInputBuffer - totalread);

                if (bytes_read < 0)
                {
                    ERR_RPT(("PortAudio: read interrupted!\n"));
                    break;
                }

                totalread += bytes_read;
            } while( totalread < pahsc->pahsc_BytesPerInputBuffer);
        }

        /* Convert 16 bit native data to user data and call user routine. */
        DBUG(("converting...\n"));
        Pa_StartUsageCalculation( past );
        result = Pa_CallConvertInt16( past,
                                      pahsc->pahsc_NativeInputBuffer,
                                      pahsc->pahsc_NativeOutputBuffer );
        Pa_EndUsageCalculation( past );
        if( result != 0)
        {
            DBUG(("hmm, Pa_CallConvertInt16() says: %d. i'm bailing.\n",
                  result));
            break;
        }

        /* Write data to device. */
        if( pahsc->pahsc_NativeOutputBuffer )
        {
            unsigned int totalwritten = 0;
            do
            {
                bytes_written = write(pahsc->pahsc_OutputHandle,
                    (void *)pahsc->pahsc_NativeOutputBuffer,
                    pahsc->pahsc_BytesPerOutputBuffer);
                if( bytes_written < 0 )
                {
                    ERR_RPT(("PortAudio: write interrupted!"));
                    break;
                }

                totalwritten += bytes_written;
            } while( totalwritten < pahsc->pahsc_BytesPerOutputBuffer);
        }

        Pa_UpdateStreamTime(pahsc);
    }
    DBUG(("Pa_AudioThreadProc: left audio loop.\n"));

    past->past_IsActive = 0;
    PaHost_StopWatchDog( pahsc );

error:
    DBUG(("leaving audio thread.\n"));
#ifdef GNUSTEP
    GSUnregisterCurrentThread();  /* SB20010904 */
#endif
    return result;
}
示例#3
0
/*---------------------------------------------------------------------------------------------------*/
static PaError Pa_SgiAudioProcess(internalPortAudioStream *past) /* Spawned by PaHost_StartEngine(). */
{
    PaError                 result = paNoError;
    PaHostSoundControl      *pahsc;
    
    if (!past)
        return paBadStreamPtr;
    pahsc = (PaHostSoundControl*)past->past_DeviceData;
	if (!pahsc)
        return paInternalError;
	past->past_IsActive = 1;            /* Wasn't this already done by the calling parent?!   */
    DBUG(("entering thread.\n"));

    while (!past->past_StopSoon)        /* OR-ing StopSoon and StopNow here gives problems! */
        {
        /*---------------------------------------- INPUT: ------------------------------------*/
        if (pahsc->pahsc_NativeInputBuffer)     /* Then pahsc_ALportIN should also be there!  */
            {
            while (ALgetfilled(pahsc->pahsc_ALportIN) < pahsc->pahsc_SamplesPerInputBuffer)
                {
                /* Trying sginap(1); and usleep(); here... things get blocked under IRIX6.2. */
                if (past->past_StopNow)    /* Don't let ALreadsamps() block */
                    goto done;
                }
            if (ALreadsamps(pahsc->pahsc_ALportIN, (void*)pahsc->pahsc_NativeInputBuffer,
                            pahsc->pahsc_SamplesPerInputBuffer))    /* Number of samples instead  */
                {                                                   /* of number of frames.       */
                ERR_RPT(("ALreadsamps() failed.\n"));
                result =  paInternalError;
                goto done;
                }
            }
        /*---------------------------------------------------- USER CALLBACK ROUTINE: ----------*/
        /* DBUG(("Calling Pa_CallConvertInt16()...\n")); */
        Pa_StartUsageCalculation(past);                     /* Convert 16 bit native data to    */
	    result = Pa_CallConvertInt16(past,                  /* user data and call user routine. */
				                 pahsc->pahsc_NativeInputBuffer, pahsc->pahsc_NativeOutputBuffer);
	    Pa_EndUsageCalculation(past);
	    if (result) 
		    {
			DBUG(("Pa_CallConvertInt16() returned %d, stopping...\n", result));
            goto done;                      /* This is apparently NOT an error!       */
		    }                               /* Just letting the userCallBack stop us. */
        /*---------------------------------------- OUTPUT: ------------------------------------*/
        if (pahsc->pahsc_NativeOutputBuffer)    /* Then pahsc_ALportOUT should also be there!  */
            {
            while (ALgetfillable(pahsc->pahsc_ALportOUT) < pahsc->pahsc_SamplesPerOutputBuffer)
                {
                /* Trying sginap(1); and usleep(); here... things get blocked under IRIX6.2. */
                if (past->past_StopNow)    /* Don't let ALwritesamps() block */
                    goto done;
                }
            if (ALwritesamps(pahsc->pahsc_ALportOUT, (void*)pahsc->pahsc_NativeOutputBuffer,
                             pahsc->pahsc_SamplesPerOutputBuffer))
                {
                ERR_RPT(("ALwritesamps() failed.\n"));
                result = paInternalError;
                goto done;
                }
            }
        /*-------------------------------------------------------------------------------------*/
        }
done:
    /* pahsc->pahsc_ThreadPID = -1;   Hu? doesn't help!! (added by Pieter) */
    past->past_IsActive = 0;
    DBUG(("leaving thread.\n"));
    return result;
}