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; }
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; }
/*---------------------------------------------------------------------------------------------------*/ 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; }