Beispiel #1
0
const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceID id )
{
    internalPortAudioDevice *pad;
    if( (id < 0) || ( id >= Pa_CountDevices()) ) return NULL;
    pad = Pa_GetInternalDevice( id );
    return  &pad->pad_Info ;
}
Beispiel #2
0
/*----------------------------------------------------------------------*/
const PaDeviceInfo* Pa_GetDeviceInfo(PaDeviceID id)
{
    PaDeviceInfo*             res = (PaDeviceInfo*)NULL;
	internalPortAudioDevice*  pad = Pa_GetInternalDevice(id);  /* Call. */
    if (pad)
	    res = &pad->pad_Info;   /* Not finding the specified ID is not  */
    if (!res)                   /* the same as &pad->pad_Info == NULL.  */
        ERR_RPT(("Pa_GetDeviceInfo() could not find it (ID=%d).\n", id));
    return res;                 /* So (maybe) a second/third ERR_RPT(). */
}
Beispiel #3
0
PaError PaHost_OpenStream( internalPortAudioStream   *past )
{
    PaError          result = paNoError;
    PaHostSoundControl *pahsc;
    unsigned int     minNumBuffers;
    internalPortAudioDevice *pad;
    DBUG(("PaHost_OpenStream() called.\n" ));

    /* Allocate and initialize host data. */
    pahsc = (PaHostSoundControl *) malloc(sizeof(PaHostSoundControl));
    if( pahsc == NULL )
    {
        result = paInsufficientMemory;
        goto error;
    }
    memset( pahsc, 0, sizeof(PaHostSoundControl) );
    past->past_DeviceData = (void *) pahsc;

    pahsc->pahsc_OutputHandle = BAD_DEVICE_ID; /* No device currently opened. */
    pahsc->pahsc_InputHandle = BAD_DEVICE_ID;
    pahsc->pahsc_IsAudioThreadValid = 0;
    pahsc->pahsc_IsWatchDogThreadValid = 0;

    /* Allocate native buffers. */
    pahsc->pahsc_BytesPerInputBuffer = past->past_FramesPerUserBuffer *
                                       past->past_NumInputChannels * sizeof(short);
    if( past->past_NumInputChannels > 0)
    {
        pahsc->pahsc_NativeInputBuffer = (short *) malloc(pahsc->pahsc_BytesPerInputBuffer);
        if( pahsc->pahsc_NativeInputBuffer == NULL )
        {
            result = paInsufficientMemory;
            goto error;
        }
    }
    pahsc->pahsc_BytesPerOutputBuffer = past->past_FramesPerUserBuffer *
                                        past->past_NumOutputChannels * sizeof(short);
    if( past->past_NumOutputChannels > 0)
    {
        pahsc->pahsc_NativeOutputBuffer = (short *) malloc(pahsc->pahsc_BytesPerOutputBuffer);
        if( pahsc->pahsc_NativeOutputBuffer == NULL )
        {
            result = paInsufficientMemory;
            goto error;
        }
    }

    /* DBUG(("PaHost_OpenStream: pahsc_MinFramesPerHostBuffer = %d\n", pahsc->pahsc_MinFramesPerHostBuffer )); */
    minNumBuffers = Pa_GetMinNumBuffers( past->past_FramesPerUserBuffer, past->past_SampleRate );
    past->past_NumUserBuffers = ( minNumBuffers > past->past_NumUserBuffers ) ? minNumBuffers : past->past_NumUserBuffers;

    pahsc->pahsc_InverseMicrosPerBuffer = past->past_SampleRate / (1000000.0 * past->past_FramesPerUserBuffer);
    DBUG(("past_SampleRate = %g\n", past->past_SampleRate ));
    DBUG(("past_FramesPerUserBuffer = %d\n", past->past_FramesPerUserBuffer ));
    DBUG(("pahsc_InverseMicrosPerBuffer = %g\n", pahsc->pahsc_InverseMicrosPerBuffer ));

    /* ------------------------- OPEN DEVICE -----------------------*/

    /* just output */
    if (past->past_OutputDeviceID == past->past_InputDeviceID)
    {

        if ((past->past_NumOutputChannels > 0) && (past->past_NumInputChannels > 0) )
        {
            pad = Pa_GetInternalDevice( past->past_OutputDeviceID );
            DBUG(("PaHost_OpenStream: attempt to open %s for O_RDWR\n", pad->pad_DeviceName ));

            /* dmazzoni: test it first in nonblocking mode to
               make sure the device is not busy */
            pahsc->pahsc_InputHandle = open(pad->pad_DeviceName,O_RDWR|O_NONBLOCK);
            if(pahsc->pahsc_InputHandle==-1)
            {
                ERR_RPT(("PaHost_OpenStream: could not open %s for O_RDWR\n", pad->pad_DeviceName ));
                result = paHostError;
                goto error;
            }
            close(pahsc->pahsc_InputHandle);

            pahsc->pahsc_OutputHandle = pahsc->pahsc_InputHandle =
                                            open(pad->pad_DeviceName,O_RDWR);
            if(pahsc->pahsc_InputHandle==-1)
            {
                ERR_RPT(("PaHost_OpenStream: could not open %s for O_RDWR\n", pad->pad_DeviceName ));
                result = paHostError;
                goto error;
            }
            Pa_SetLatency( pahsc->pahsc_OutputHandle,
                           past->past_NumUserBuffers, past->past_FramesPerUserBuffer,
                           past->past_NumOutputChannels );
            result = Pa_SetupDeviceFormat( pahsc->pahsc_OutputHandle,
                                           past->past_NumOutputChannels, (int)past->past_SampleRate );
        }
    }
    else
    {
        if (past->past_NumOutputChannels > 0)
        {
            pad = Pa_GetInternalDevice( past->past_OutputDeviceID );
            DBUG(("PaHost_OpenStream: attempt to open %s for O_WRONLY\n", pad->pad_DeviceName ));
            /* dmazzoni: test it first in nonblocking mode to
               make sure the device is not busy */
            pahsc->pahsc_OutputHandle = open(pad->pad_DeviceName,O_WRONLY|O_NONBLOCK);
            if(pahsc->pahsc_OutputHandle==-1)
            {
                ERR_RPT(("PaHost_OpenStream: could not open %s for O_WRONLY\n", pad->pad_DeviceName ));
                result = paHostError;
                goto error;
            }
            close(pahsc->pahsc_OutputHandle);

            pahsc->pahsc_OutputHandle = open(pad->pad_DeviceName,O_WRONLY);
            if(pahsc->pahsc_OutputHandle==-1)
            {
                ERR_RPT(("PaHost_OpenStream: could not open %s for O_WRONLY\n", pad->pad_DeviceName ));
                result = paHostError;
                goto error;
            }
            Pa_SetLatency( pahsc->pahsc_OutputHandle,
                           past->past_NumUserBuffers, past->past_FramesPerUserBuffer,
                           past->past_NumOutputChannels );
            result = Pa_SetupOutputDeviceFormat( pahsc->pahsc_OutputHandle,
                                           past->past_NumOutputChannels, (int)past->past_SampleRate );
        }

        if (past->past_NumInputChannels > 0)
        {
            pad = Pa_GetInternalDevice( past->past_InputDeviceID );
            DBUG(("PaHost_OpenStream: attempt to open %s for O_RDONLY\n", pad->pad_DeviceName ));
            /* dmazzoni: test it first in nonblocking mode to
               make sure the device is not busy */
            pahsc->pahsc_InputHandle = open(pad->pad_DeviceName,O_RDONLY|O_NONBLOCK);
            if(pahsc->pahsc_InputHandle==-1)
            {
                ERR_RPT(("PaHost_OpenStream: could not open %s for O_RDONLY\n", pad->pad_DeviceName ));
                result = paHostError;
                goto error;
            }
            close(pahsc->pahsc_InputHandle);

            pahsc->pahsc_InputHandle = open(pad->pad_DeviceName,O_RDONLY);
            if(pahsc->pahsc_InputHandle==-1)
            {
                ERR_RPT(("PaHost_OpenStream: could not open %s for O_RDONLY\n", pad->pad_DeviceName ));
                result = paHostError;
                goto error;
            }
            Pa_SetLatency( pahsc->pahsc_InputHandle, /* DH20010115 - was OutputHandle! */
                           past->past_NumUserBuffers, past->past_FramesPerUserBuffer,
                           past->past_NumInputChannels );
            result = Pa_SetupInputDeviceFormat( pahsc->pahsc_InputHandle,
                                           past->past_NumInputChannels, (int)past->past_SampleRate );
        }
    }


    DBUG(("PaHost_OpenStream: SUCCESS - result = %d\n", result ));
    return result;

error:
    ERR_RPT(("PaHost_OpenStream: ERROR - result = %d\n", result ));
    PaHost_CloseStream( past );
    return result;
}
Beispiel #4
0
PaError PaHost_OpenStream( internalPortAudioStream   *past )
{
	HRESULT          hr;
	PaError          result = paNoError;
	PaHostSoundControl *pahsc;
	int              numBytes, maxChannels;
	unsigned int     minNumBuffers;
	internalPortAudioDevice *pad;
	DSoundWrapper   *dsw;
/* Allocate and initialize host data. */
	pahsc = (PaHostSoundControl *) PaHost_AllocateFastMemory(sizeof(PaHostSoundControl)); /* MEM */
	if( pahsc == NULL )
	{
		result = paInsufficientMemory;
		goto error;
	}
	memset( pahsc, 0, sizeof(PaHostSoundControl) );
	past->past_DeviceData = (void *) pahsc;
	pahsc->pahsc_TimerID = 0;
	dsw = &pahsc->pahsc_DSoundWrapper;
	DSW_Init( dsw );
/* Allocate native buffer. */
	maxChannels = ( past->past_NumOutputChannels > past->past_NumInputChannels ) ?
		past->past_NumOutputChannels : past->past_NumInputChannels;
	pahsc->pahsc_BytesPerBuffer = past->past_FramesPerUserBuffer * maxChannels * sizeof(short);
	if( maxChannels > 0 )
	{
		pahsc->pahsc_NativeBuffer = (short *) PaHost_AllocateFastMemory(pahsc->pahsc_BytesPerBuffer); /* MEM */
		if( pahsc->pahsc_NativeBuffer == NULL )
		{
			result = paInsufficientMemory;
			goto error;
		}
	}
	else
	{
		result = paInvalidChannelCount;
		goto error;
	}
	
	DBUG(("PaHost_OpenStream: pahsc_MinFramesPerHostBuffer = %d\n", pahsc->pahsc_MinFramesPerHostBuffer ));
	minNumBuffers = Pa_GetMinNumBuffers( past->past_FramesPerUserBuffer, past->past_SampleRate );
	past->past_NumUserBuffers = ( minNumBuffers > past->past_NumUserBuffers ) ? minNumBuffers : past->past_NumUserBuffers;
	numBytes = pahsc->pahsc_BytesPerBuffer * past->past_NumUserBuffers;
	if( numBytes < DSBSIZE_MIN )
	{
		result = paBufferTooSmall;
		goto error;
	}
	if( numBytes > DSBSIZE_MAX )
	{
		result = paBufferTooBig;
		goto error;
	}
	pahsc->pahsc_FramesPerDSBuffer = past->past_FramesPerUserBuffer * past->past_NumUserBuffers;
	{
		int msecLatency = (int) ((pahsc->pahsc_FramesPerDSBuffer * 1000) / past->past_SampleRate);
		PRINT(("PortAudio on DirectSound - Latency = %d frames, %d msec\n", pahsc->pahsc_FramesPerDSBuffer, msecLatency ));
	}
/* ------------------ OUTPUT */
	if( (past->past_OutputDeviceID >= 0) && (past->past_NumOutputChannels > 0) )
	{
		DBUG(("PaHost_OpenStream: deviceID = 0x%x\n", past->past_OutputDeviceID));
		pad = Pa_GetInternalDevice( past->past_OutputDeviceID );
		hr = DirectSoundCreate( pad->pad_lpGUID, &dsw->dsw_pDirectSound,   NULL );
/* If this fails, then try each output device until we find one that works. */
		if( hr != DS_OK )
		{
			int i;
			ERR_RPT(("Creation of requested Audio Output device '%s' failed.\n",
				((pad->pad_lpGUID == NULL) ? "Default" : pad->pad_Info.name) ));
			for( i=0; i<Pa_CountDevices(); i++ )
			{
				pad = Pa_GetInternalDevice( i );
				if( pad->pad_Info.maxOutputChannels >= past->past_NumOutputChannels )
				{
					DBUG(("Try device '%s' instead.\n", pad->pad_Info.name ));
					hr = DirectSoundCreate( pad->pad_lpGUID, &dsw->dsw_pDirectSound,   NULL );
					if( hr == DS_OK )
					{
						ERR_RPT(("Using device '%s' instead.\n", pad->pad_Info.name ));
						break;
					}
				}
			}
		}
		if( hr != DS_OK )
		{
			ERR_RPT(("PortAudio: DirectSoundCreate() failed!\n"));
			result = paHostError;
			sPaHostError = hr;
			goto error;
		}
		hr = DSW_InitOutputBuffer( dsw,
			(unsigned long) (past->past_SampleRate + 0.5),
			past->past_NumOutputChannels, numBytes );
		DBUG(("DSW_InitOutputBuffer() returns %x\n", hr));
		if( hr != DS_OK )
		{
			result = paHostError;
			sPaHostError = hr;
			goto error;
		}
		past->past_FrameCount = pahsc->pahsc_DSoundWrapper.dsw_FramesWritten;
	}
#if SUPPORT_AUDIO_CAPTURE
/* ------------------ INPUT */
	if( (past->past_InputDeviceID >= 0) && (past->past_NumInputChannels > 0) )
	{
		pad = Pa_GetInternalDevice( past->past_InputDeviceID );
		hr = DirectSoundCaptureCreate( pad->pad_lpGUID, &dsw->dsw_pDirectSoundCapture,   NULL );
/* If this fails, then try each input device until we find one that works. */
		if( hr != DS_OK )
		{
			int i;
			ERR_RPT(("Creation of requested Audio Capture device '%s' failed.\n",
				((pad->pad_lpGUID == NULL) ? "Default" : pad->pad_Info.name) ));
			for( i=0; i<Pa_CountDevices(); i++ )
			{
				pad = Pa_GetInternalDevice( i );
				if( pad->pad_Info.maxInputChannels >= past->past_NumInputChannels )
				{
					PRINT(("Try device '%s' instead.\n", pad->pad_Info.name ));
					hr = DirectSoundCaptureCreate( pad->pad_lpGUID, &dsw->dsw_pDirectSoundCapture,   NULL );
					if( hr == DS_OK ) break;
				}
			}
		}
		if( hr != DS_OK )
		{
			ERR_RPT(("PortAudio: DirectSoundCaptureCreate() failed!\n"));
			result = paHostError;
			sPaHostError = hr;
			goto error;
		}
		hr = DSW_InitInputBuffer( dsw,
			(unsigned long) (past->past_SampleRate + 0.5),
			past->past_NumInputChannels, numBytes );
		DBUG(("DSW_InitInputBuffer() returns %x\n", hr));
		if( hr != DS_OK )
		{
			ERR_RPT(("PortAudio: DSW_InitInputBuffer() returns %x\n", hr));
			result = paHostError;
			sPaHostError = hr;
			goto error;
		}
	}
#endif /* SUPPORT_AUDIO_CAPTURE */
	/* Calculate scalar used in CPULoad calculation. */ 
	{
		LARGE_INTEGER frequency;
		if( QueryPerformanceFrequency( &frequency ) == 0 )
		{
			pahsc->pahsc_InverseTicksPerUserBuffer = 0.0;
		}
		else
		{
			pahsc->pahsc_InverseTicksPerUserBuffer = past->past_SampleRate /
				( (double)frequency.QuadPart * past->past_FramesPerUserBuffer );
			DBUG(("pahsc_InverseTicksPerUserBuffer = %g\n", pahsc->pahsc_InverseTicksPerUserBuffer ));
		}
	}
	return result;
error:
	PaHost_CloseStream( past );
	return result;
}
Beispiel #5
0
/*--------------------------------------------------------------------------------------*/
PaError PaHost_OpenStream(internalPortAudioStream *past)
{
	PaError                 result = paNoError;
	PaHostSoundControl      *pahsc;
	unsigned int            minNumBuffers;
	internalPortAudioDevice *padIN, *padOUT;        /* For looking up native AL-numbers. */
    ALconfig                sgiALconfig = NULL;     /* IRIX-datatype.   */
    long                    pvbuf[8];               /* To get/set hardware configs.      */
    long                    sr, ALqsize;
    DBUG(("PaHost_OpenStream() called.\n"));        /* Alloc FASTMEM and init host data. */
    if (!past)
        {
        ERR_RPT(("Streampointer NULL!\n"));
        result = paBadStreamPtr;        goto done;
        }
	pahsc = (PaHostSoundControl*)PaHost_AllocateFastMemory(sizeof(PaHostSoundControl));
	if (pahsc == NULL)
	    {
        ERR_RPT(("FAST Memory allocation failed.\n"));  /* Pass trough some ERR_RPT-exit-  */
        result = paInsufficientMemory;  goto done;      /* code (nothing will be freed).   */
	    }
	memset(pahsc, 0, sizeof(PaHostSoundControl));
/*  pahsc->pahsc_threadPID = -1;                       Should pahsc_threadPID be inited to */
	past->past_DeviceData = (void*)pahsc;           /* -1 instead of 0 ??                  */
    /*--------------------------------------------------- Allocate native buffers: --------*/
    pahsc->pahsc_SamplesPerInputBuffer = past->past_FramesPerUserBuffer * /* Needed by the */
                                         past->past_NumInputChannels;     /* audio-thread. */
	pahsc->pahsc_BytesPerInputBuffer   = pahsc->pahsc_SamplesPerInputBuffer * sizeof(short);
	if (past->past_NumInputChannels > 0)                       /* Assumes short = 16 bits! */
	    {
		pahsc->pahsc_NativeInputBuffer = (short*)PaHost_AllocateFastMemory(pahsc->pahsc_BytesPerInputBuffer);        
		if( pahsc->pahsc_NativeInputBuffer == NULL )
		    {
            ERR_RPT(("Fast memory allocation for input-buffer failed.\n"));
			result = paInsufficientMemory;  goto done;
		    }
	    }
    pahsc->pahsc_SamplesPerOutputBuffer = past->past_FramesPerUserBuffer * /* Needed by the */
                                          past->past_NumOutputChannels;    /* audio-thread. */
	pahsc->pahsc_BytesPerOutputBuffer   = pahsc->pahsc_SamplesPerOutputBuffer * sizeof(short);
	if (past->past_NumOutputChannels > 0)                       /* Assumes short = 16 bits! */
	    {
		pahsc->pahsc_NativeOutputBuffer = (short*)PaHost_AllocateFastMemory(pahsc->pahsc_BytesPerOutputBuffer);
		if (pahsc->pahsc_NativeOutputBuffer == NULL)
		    {
            ERR_RPT(("Fast memory allocation for output-buffer failed.\n"));
			result = paInsufficientMemory;  goto done;
		    }
	    }
    /*------------------------------------------ Manipulate hardware if necessary and allowed: --*/
    ALseterrorhandler(0);                           /* 0 = turn off the default error handler.   */
    pvbuf[0] = AL_INPUT_RATE;
    pvbuf[2] = AL_INPUT_COUNT;
    pvbuf[4] = AL_OUTPUT_RATE;              /* TO FIX: rates may be logically, not always in Hz! */
    pvbuf[6] = AL_OUTPUT_COUNT;
    sr = (long)(past->past_SampleRate + 0.5);   /* Common for input and output :-)               */
    if (past->past_NumInputChannels > 0)                        /* We need to lookup the corre-  */
        {                                                       /* sponding native AL-number(s). */
        padIN = Pa_GetInternalDevice(past->past_InputDeviceID);
        if (!padIN)
            {
            ERR_RPT(("Pa_GetInternalDevice() for input failed.\n"));
	        result = paHostError;  goto done;
            }
        if (ALgetparams(padIN->pad_ALdevice, &pvbuf[0], 4)) /* Although input and output will both be on */
            goto sgiError;                                  /* the same AL-device, the AL-library might  */
        if (pvbuf[1] != sr)                                 /* contain more than AL_DEFAULT_DEVICE in    */
            {  /* Rate different from current harware-rate?    the future. Therefore 2 seperate queries. */
            if (pvbuf[3] > 0)     /* Means, there's other clients using AL-input-ports */
                {
                ERR_RPT(("Sorry, not allowed to switch input-hardware to %ld Hz because \
another process is currently using input at %ld kHz.\n", sr, pvbuf[1]));
                result = paHostError;   goto done;
                }
            pvbuf[1] = sr;                  /* Then set input-rate. */
            if (ALsetparams(padIN->pad_ALdevice, &pvbuf[0], 2))
                goto sgiError;      /* WHETHER THIS SAMPLERATE WAS REALLY PRESENT IN OUR ARRAY OF RATES, */
            }                       /* IS NOT CHECKED, AT LEAST NOT BY ME, WITHIN THIS FILE! Does PA do? */