⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pa_unix_oss.c

📁 一个开源的sip源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    {        int stereo = 1;        if( ioctl( devHandle, SNDCTL_DSP_STEREO, &stereo ) < 0 )        {            maxNumChannels = 1;        }        else        {            maxNumChannels = (stereo) ? 2 : 1;        }        PA_DEBUG(( "%s: use SNDCTL_DSP_STEREO, maxNumChannels = %d\n", __FUNCTION__, maxNumChannels ))    }    /* During channel negotiation, the last ioctl() may have failed. This can     * also cause sample rate negotiation to fail. Hence the following, to return     * to a supported number of channels. SG20011005 */    {        /* use most reasonable default value */        int temp = PA_MIN( maxNumChannels, 2 );        ENSURE_( ioctl( devHandle, SNDCTL_DSP_CHANNELS, &temp ), paUnanticipatedHostError );    }    /* Get supported sample rate closest to 44100 Hz */    if( *defaultSampleRate < 0 )    {        sr = 44100;        if( ioctl( devHandle, SNDCTL_DSP_SPEED, &sr ) < 0 )        {            result = paUnanticipatedHostError;            goto error;        }        *defaultSampleRate = sr;    }    *maxChannelCount = maxNumChannels;    /* TODO */    *defaultLowLatency = 512. / *defaultSampleRate;    *defaultHighLatency = 2048. / *defaultSampleRate;error:    if( devHandle >= 0 )        close( devHandle );    return result;}/** Query OSS device. * * This is where PaDeviceInfo objects are constructed and filled in with relevant information. * * Aspect DeviceCapabilities: The inferred device capabilities are recorded in a PaDeviceInfo object that is constructed * in place. */static PaError QueryDevice( char *deviceName, PaOSSHostApiRepresentation *ossApi, PaDeviceInfo **deviceInfo ){    PaError result = paNoError;    double sampleRate = -1.;    int maxInputChannels, maxOutputChannels;    PaTime defaultLowInputLatency, defaultLowOutputLatency, defaultHighInputLatency, defaultHighOutputLatency;    PaError tmpRes = paNoError;    int busy = 0;    *deviceInfo = NULL;    /* douglas:       we have to do this querying in a slightly different order. apparently       some sound cards will give you different info based on their settins.        e.g. a card might give you stereo at 22kHz but only mono at 44kHz.       the correct order for OSS is: format, channels, sample rate    */    /* Aspect StreamChannels: The number of channels supported for a device may depend on the mode it is     * opened in, it may have more channels available for capture than playback and vice versa. Therefore     * we will open the device in both read- and write-only mode to determine the supported number.     */    if( (tmpRes = QueryDirection( deviceName, StreamMode_In, &sampleRate, &maxInputChannels, &defaultLowInputLatency,                &defaultHighInputLatency )) != paNoError )    {        if( tmpRes != paDeviceUnavailable )        {            PA_DEBUG(( "%s: Querying device %s for capture failed!\n", __FUNCTION__, deviceName ));            /* PA_ENSURE( tmpRes ); */        }        ++busy;    }    if( (tmpRes = QueryDirection( deviceName, StreamMode_Out, &sampleRate, &maxOutputChannels, &defaultLowOutputLatency,                &defaultHighOutputLatency )) != paNoError )    {        if( tmpRes != paDeviceUnavailable )        {            PA_DEBUG(( "%s: Querying device %s for playback failed!\n", __FUNCTION__, deviceName ));            /* PA_ENSURE( tmpRes ); */        }        ++busy;    }    assert( 0 <= busy && busy <= 2 );    if( 2 == busy )     /* Both directions are unavailable to us */    {        result = paDeviceUnavailable;        goto error;    }    PA_UNLESS( *deviceInfo = PaUtil_GroupAllocateMemory( ossApi->allocations, sizeof (PaDeviceInfo) ), paInsufficientMemory );    PA_ENSURE( PaUtil_InitializeDeviceInfo( *deviceInfo, deviceName, ossApi->hostApiIndex, maxInputChannels, maxOutputChannels,                defaultLowInputLatency, defaultLowOutputLatency, defaultHighInputLatency, defaultHighOutputLatency, sampleRate,                ossApi->allocations ) );error:    return result;}/** Query host devices. * * Loop over host devices and query their capabilitiesu * * Aspect DeviceCapabilities: This function calls QueryDevice on each device entry and receives a filled in PaDeviceInfo object * per device, these are placed in the host api representation's deviceInfos array. */static PaError BuildDeviceList( PaOSSHostApiRepresentation *ossApi ){    PaError result = paNoError;    PaUtilHostApiRepresentation *commonApi = &ossApi->inheritedHostApiRep;    int i;    int numDevices = 0, maxDeviceInfos = 1;    PaDeviceInfo **deviceInfos = NULL;    /* These two will be set to the first working input and output device, respectively */    commonApi->info.defaultInputDevice = paNoDevice;    commonApi->info.defaultOutputDevice = paNoDevice;    /* Find devices by calling QueryDevice on each     * potential device names.  When we find a valid one,     * add it to a linked list.     * A: Can there only be 10 devices? */    for( i = 0; i < 10; i++ )    {       char deviceName[32];       PaDeviceInfo *deviceInfo;       int testResult;       struct stat stbuf;       if( i == 0 )          snprintf(deviceName, sizeof (deviceName), "%s", DEVICE_NAME_BASE);       else          snprintf(deviceName, sizeof (deviceName), "%s%d", DEVICE_NAME_BASE, i);       /* PA_DEBUG(("PaOSS BuildDeviceList: trying device %s\n", deviceName )); */       if( stat( deviceName, &stbuf ) < 0 )       {           if( ENOENT != errno )               PA_DEBUG(( "%s: Error stat'ing %s: %s\n", __FUNCTION__, deviceName, strerror( errno ) ));           continue;       }       if( (testResult = QueryDevice( deviceName, ossApi, &deviceInfo )) != paNoError )       {           if( testResult != paDeviceUnavailable )               PA_ENSURE( testResult );           continue;       }       ++numDevices;       if( !deviceInfos || numDevices > maxDeviceInfos )       {           maxDeviceInfos *= 2;           PA_UNLESS( deviceInfos = (PaDeviceInfo **) realloc( deviceInfos, maxDeviceInfos * sizeof (PaDeviceInfo *) ),                   paInsufficientMemory );       }       {           int devIdx = numDevices - 1;           deviceInfos[devIdx] = deviceInfo;           if( commonApi->info.defaultInputDevice == paNoDevice && deviceInfo->maxInputChannels > 0 )               commonApi->info.defaultInputDevice = devIdx;           if( commonApi->info.defaultOutputDevice == paNoDevice && deviceInfo->maxOutputChannels > 0 )               commonApi->info.defaultOutputDevice = devIdx;       }    }    /* Make an array of PaDeviceInfo pointers out of the linked list */    PA_DEBUG(("PaOSS %s: Total number of devices found: %d\n", __FUNCTION__, numDevices));    commonApi->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory(        ossApi->allocations, sizeof(PaDeviceInfo*) * numDevices );    memcpy( commonApi->deviceInfos, deviceInfos, numDevices * sizeof (PaDeviceInfo *) );    commonApi->info.deviceCount = numDevices;error:    free( deviceInfos );    return result;}static void Terminate( struct PaUtilHostApiRepresentation *hostApi ){    PaOSSHostApiRepresentation *ossHostApi = (PaOSSHostApiRepresentation*)hostApi;    if( ossHostApi->allocations )    {        PaUtil_FreeAllAllocations( ossHostApi->allocations );        PaUtil_DestroyAllocationGroup( ossHostApi->allocations );    }    PaUtil_FreeMemory( ossHostApi );}static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,                                  const PaStreamParameters *inputParameters,                                  const PaStreamParameters *outputParameters,                                  double sampleRate ){    PaError result = paNoError;    PaDeviceIndex device;    PaDeviceInfo *deviceInfo;    char *deviceName;    int inputChannelCount, outputChannelCount;    int tempDevHandle = -1;    int flags;    PaSampleFormat inputSampleFormat, outputSampleFormat;        if( inputParameters )    {        inputChannelCount = inputParameters->channelCount;        inputSampleFormat = inputParameters->sampleFormat;        /* unless alternate device specification is supported, reject the use of            paUseHostApiSpecificDeviceSpecification */        if( inputParameters->device == paUseHostApiSpecificDeviceSpecification )            return paInvalidDevice;        /* check that input device can support inputChannelCount */        if( inputChannelCount > hostApi->deviceInfos[ inputParameters->device ]->maxInputChannels )            return paInvalidChannelCount;        /* validate inputStreamInfo */        if( inputParameters->hostApiSpecificStreamInfo )            return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */    }    else    {        inputChannelCount = 0;    }    if( outputParameters )    {        outputChannelCount = outputParameters->channelCount;        outputSampleFormat = outputParameters->sampleFormat;                /* unless alternate device specification is supported, reject the use of            paUseHostApiSpecificDeviceSpecification */        if( outputParameters->device == paUseHostApiSpecificDeviceSpecification )            return paInvalidDevice;        /* check that output device can support inputChannelCount */        if( outputChannelCount > hostApi->deviceInfos[ outputParameters->device ]->maxOutputChannels )            return paInvalidChannelCount;        /* validate outputStreamInfo */        if( outputParameters->hostApiSpecificStreamInfo )            return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */    }    else    {        outputChannelCount = 0;    }    if (inputChannelCount == 0 && outputChannelCount == 0)        return paInvalidChannelCount;    /* if full duplex, make sure that they're the same device */    if (inputChannelCount > 0 && outputChannelCount > 0 &&        inputParameters->device != outputParameters->device)        return paInvalidDevice;    /* if full duplex, also make sure that they're the same number of channels */    if (inputChannelCount > 0 && outputChannelCount > 0 &&        inputChannelCount != outputChannelCount)       return paInvalidChannelCount;    /* open the device so we can do more tests */        if( inputChannelCount > 0 )    {        result = PaUtil_DeviceIndexToHostApiDeviceIndex(&device, inputParameters->device, hostApi);        if (result != paNoError)            return result;    }    else    {        result = PaUtil_DeviceIndexToHostApiDeviceIndex(&device, outputParameters->device, hostApi);        if (result != paNoError)            return result;    }    deviceInfo = hostApi->deviceInfos[device];    deviceName = (char *)deviceInfo->name;        flags = O_NONBLOCK;    if (inputChannelCount > 0 && outputChannelCount > 0)       flags |= O_RDWR;    else if (inputChannelCount > 0)       flags |= O_RDONLY;    else       flags |= O_WRONLY;    ENSURE_( tempDevHandle = open( deviceInfo->name, flags ), paDeviceUnavailable );    /* PaOssStream_Configure will do the rest of the checking for us */    /* PA_ENSURE( PaOssStream_Configure( tempDevHandle, deviceName, outputChannelCount, &sampleRate ) ); */    /* everything succeeded! */ error:    if( tempDevHandle >= 0 )        close( tempDevHandle );             return result;}/** Validate stream parameters. * * Aspect StreamChannels: We verify that the number of channels is within the allowed range for the device */static PaError ValidateParameters( const PaStreamParameters *parameters, const PaDeviceInfo *deviceInfo, StreamMode mode ){    int maxChans;    assert( parameters );    if( parameters->device == paUseHostApiSpecificDeviceSpecification )    {        return paInvalidDevice;    }    maxChans = (mode == StreamMode_In ? deviceInfo->maxInputChannels :        deviceInfo->maxOutputChannels);    if( parameters->channelCount > maxChans )    {        return paInvalidChannelCount;    }    return paNoError;}static PaError PaOssStreamComponent_Initialize( PaOssStreamComponent *component, const PaStreamParameters *parameters,        int callbackMode, int fd, const char *deviceName ){    PaError result = paNoError;    assert( component );    memset( component, 0, sizeof (PaOssStreamComponent) );    component->fd = fd;    component->devName = deviceName;    component->userChannelCount = parameters->channelCount;    component->userFormat = parameters->sampleFormat;    component->latency = parameters->suggestedLatency;    component->userInterleaved = !(parameters->sampleFormat & paNonInterleaved);    if( !callbackMode && !component->userInterleaved )    {        /* Pre-allocate non-interleaved user provided buffers */        PA_UNLESS( component->userBuffers = PaUtil_AllocateMemory( sizeof (void *) * component->userChannelCount ),                paInsufficientMemory );    }error:    return result;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -