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

📄 pa_mac_core.c

📁 IAX client库, 一个VOIP的库. 支持H.323和SIP, PBX就是采用的它
💻 C
📖 第 1 页 / 共 5 页
字号:
                        if (err) {                            DBUG(("Could not set stream %d to linear PCM: %s (%d)\n",                                  i, FourCharCode2Str(err), err));                        }                        else {                            DBUG(("Successfully set stream %d to linear PCM\n", i));                        }                        if (formatDesc.mSampleRate != desiredRate) {                            /* Let's also try to get the sample rate to match */                            double origRate = formatDesc.mSampleRate;                            formatDesc.mSampleRate = desiredRate;                            err = AudioDeviceGetProperty(devID, 0, isInput,                                                         kAudioStreamPropertyPhysicalFormatMatch,                                                         &outSize, &formatDesc);                            if (!err && formatDesc.mFormatID == kAudioFormatLinearPCM &&                                formatDesc.mSampleRate != origRate) {                                err = AudioDeviceSetProperty( devID, 0, 0,                                                              isInput, kAudioStreamPropertyPhysicalFormat,                                                              sizeof(formatDesc), &formatDesc);                                if (!err) {                                    DBUG(("We were able to set the sample rate to %.1f, too!\n",                                          formatDesc.mSampleRate));                                }                            }                        }                    }                }            }            free(streams);            // Find the closest match to the stream format that we want.            memset(&formatDesc, 0, sizeof(AudioStreamBasicDescription));                    formatDesc.mFormatID = kAudioFormatLinearPCM;            /*              formatDesc.mSampleRate = desiredRate;              Since we already set the physical format, we'll definitely get the sample rate              we wanted if possible.  And if not, then our converter will do the sample rate              conversion anyway.  Either way, it doesn't help to ask for the rate we want, and              it could hurt (because some devices will switch into a non-linear-PCM mode to              give you the rate you want).            */            /*              Should this be in here?  I'm not sure...	      (Yes, if not many devices will default to mono instead of stereo...)	    */	    formatDesc.mChannelsPerFrame = desiredNumChannels;            /*              These probably don't matter...              formatDesc.mBytesPerFrame = formatDesc.mChannelsPerFrame * sizeof(float);              formatDesc.mBytesPerPacket = formatDesc.mBytesPerFrame * formatDesc.mFramesPerPacket;            */            outSize = sizeof(AudioStreamBasicDescription);            err = AudioDeviceGetProperty(devID, 0, isInput, kAudioDevicePropertyStreamFormatMatch,                                         &outSize, &formatDesc);            DBUG(("Asked for stream format match, got err=%d, rate=%1f, formatID=%s, flags=%d channels=%d\n",                  err,                   formatDesc.mSampleRate, FourCharCode2Str(formatDesc.mFormatID),                  formatDesc.mFormatFlags, formatDesc.mChannelsPerFrame));            // It's absolutely necessary that we get linear PCM.  If not,            // we must fail.            if (formatDesc.mFormatID != kAudioFormatLinearPCM) {                DBUG(("Couldn't even get any linear PCM format!!!\n"));                result = paSampleFormatNotSupported;            }            else {                if( formatDesc.mSampleRate == origDesc.mSampleRate &&                    formatDesc.mChannelsPerFrame == origDesc.mChannelsPerFrame &&                    formatDesc.mFormatID == origDesc.mFormatID &&                    formatDesc.mFormatFlags == origDesc.mFormatFlags) {                    DBUG(("No need to change the device, it's already in an acceptable format\n"));                    result = 0;                }                else {                    DBUG(("Changing device format\n"));                    DBUG(("Orig: rate=%1f, formatID=%s, flags=%d channels=%d\n",                          origDesc.mSampleRate, FourCharCode2Str(origDesc.mFormatID),                          origDesc.mFormatFlags, origDesc.mChannelsPerFrame));                                    DBUG((" New: rate=%1f, formatID=%s, flags=%d channels=%d\n",                          formatDesc.mSampleRate, FourCharCode2Str(formatDesc.mFormatID),                          formatDesc.mFormatFlags, formatDesc.mChannelsPerFrame));                    err = AudioDeviceSetProperty( devID, 0, 0,                                                  isInput, kAudioDevicePropertyStreamFormat,                                                  sizeof(formatDesc), &formatDesc);                    if (err) {                        DBUG(("Error trying to change device format: %d\n", err));                        if (did_set_hog_mode)                            result = paSampleFormatNotSupported;                        else                            result = paDeviceUnavailable;                    }                    else {                        DBUG(("Success!\n"));                        result = 1;                    }                }            }            // Try to turn on mixing if possible (lets other programs play            // sounds, too)                    if (result == 1) {                supportsMixing = 1;                err = AudioDeviceSetProperty( devID, 0, 0, isInput,                                              kAudioDevicePropertySupportsMixing, sizeof(UInt32), &supportsMixing);                if (err) {                    DBUG(("Unable to turn on mixing\n"));                }                else {                    DBUG(("Turned on mixing!\n"));                }            }            // Release hog mode if necessary            if (did_set_hog_mode) {                DBUG(("Releasing hog mode.\n"));                hog_pid = -1;                err = AudioDeviceSetProperty( devID, 0, 0, isInput, kAudioDevicePropertyHogMode,                                              sizeof(hog_pid), &hog_pid);                if (!err)                    DBUG(("Hog release successful.\n"));            }        }        return result;}/******************************************************************* * Check volume level of device. If below threshold, then set to newLevel. * Using volume instead of decibels because decibel range varies by device. */static void PaOSX_FixVolumeScalars( AudioDeviceID devID, Boolean isInput,    int numChannels, double threshold, double newLevel ){    OSStatus err = noErr;    UInt32    dataSize;    int       iChannel;    /* The master channel is 0. Left and right are channels 1 and 2. */    /* Fix volume. */    for( iChannel = 0; iChannel<=numChannels; iChannel++ )    {        Float32   fdata32;        dataSize = sizeof( fdata32 );        err = AudioDeviceGetProperty( devID, iChannel, isInput,             kAudioDevicePropertyVolumeScalar, &dataSize, &fdata32 );        printf("devID=%d\n", devID);        printf("Channel=%d input=%d volume=%f\n",               iChannel, (int)isInput, fdata32);        if( err == noErr )        {            DBUG(("kAudioDevicePropertyVolumeScalar for channel %d = %f\n", iChannel, fdata32));            if( fdata32 <= (Float32) threshold )            {                dataSize = sizeof( fdata32 );                fdata32 = (Float32) newLevel;                printf("Channel=%d input=%d new volume=%f\n",                       iChannel, (int)isInput, fdata32);                err = AudioDeviceSetProperty( devID, 0, iChannel, isInput,                     kAudioDevicePropertyVolumeScalar, dataSize, &fdata32 );                if( err != noErr )                {                    PRINT(("Warning: audio volume is very low and could not be turned up.\n"));                }                else                {                    PRINT(("Volume for audio channel %d was <= %4.2f so set to %4.2f by PortAudio!\n",                        iChannel, threshold, newLevel ));                }            }        }    }/* Unmute if muted. */    for( iChannel = 0; iChannel<=numChannels; iChannel++ )    {        UInt32    uidata32;        dataSize = sizeof( uidata32 );        err = AudioDeviceGetProperty( devID, iChannel, isInput,             kAudioDevicePropertyMute, &dataSize, &uidata32 );        if( err == noErr )        {            DBUG(("uidata32 for channel %d = %ld\n", iChannel, uidata32));            if( uidata32 == 1 ) // muted?            {                dataSize = sizeof( uidata32 );                uidata32 = 0; // unmute                err = AudioDeviceSetProperty( devID, 0, iChannel, isInput,                     kAudioDevicePropertyMute, dataSize, &uidata32 );                if( err != noErr )                {                    PRINT(("Warning: audio is muted and could not be unmuted!\n"));                }                else                {                    PRINT(("Audio channel %d was unmuted by PortAudio!\n", iChannel ));                }            }        }    }}#if 0static void PaOSX_DumpDeviceInfo( AudioDeviceID devID, Boolean isInput ){    OSStatus err = noErr;    UInt32    dataSize;    UInt32    uidata32;    Float32   fdata32;    AudioValueRange audioRange;        dataSize = sizeof( uidata32 );    err = AudioDeviceGetProperty( devID, 0, isInput,         kAudioDevicePropertyLatency, &dataSize, &uidata32 );    if( err != noErr )    {        PRINT_ERR("Error reading kAudioDevicePropertyLatency", err);        return;    }    PRINT(("kAudioDevicePropertyLatency = %d\n", (int)uidata32 ));        dataSize = sizeof( fdata32 );    err = AudioDeviceGetProperty( devID, 1, isInput,         kAudioDevicePropertyVolumeScalar, &dataSize, &fdata32 );    if( err != noErr )    {        PRINT_ERR("Error reading kAudioDevicePropertyVolumeScalar", err);        return;    }    PRINT(("kAudioDevicePropertyVolumeScalar = %f\n", fdata32 ));        dataSize = sizeof( uidata32 );    err = AudioDeviceGetProperty( devID, 0, isInput,         kAudioDevicePropertyBufferSize, &dataSize, &uidata32 );    if( err != noErr )    {        PRINT_ERR("Error reading buffer size", err);        return;    }    PRINT(("kAudioDevicePropertyBufferSize = %d bytes\n", (int)uidata32 ));    dataSize = sizeof( audioRange );    err = AudioDeviceGetProperty( devID, 0, isInput,         kAudioDevicePropertyBufferSizeRange, &dataSize, &audioRange );    if( err != noErr )    {        PRINT_ERR("Error reading buffer size range", err);        return;    }    PRINT(("kAudioDevicePropertyBufferSizeRange = %g to %g bytes\n", audioRange.mMinimum, audioRange.mMaximum ));        dataSize = sizeof( uidata32 );    err = AudioDeviceGetProperty( devID, 0, isInput,         kAudioDevicePropertyBufferFrameSize, &dataSize, &uidata32 );    if( err != noErr )    {        PRINT_ERR("Error reading buffer size", err);        return;    }    PRINT(("kAudioDevicePropertyBufferFrameSize = %d frames\n", (int)uidata32 ));        dataSize = sizeof( audioRange );    err = AudioDeviceGetProperty( devID, 0, isInput,         kAudioDevicePropertyBufferFrameSizeRange, &dataSize, &audioRange );    if( err != noErr )    {        PRINT_ERR("Error reading buffer size range", err);        return;    }    PRINT(("kAudioDevicePropertyBufferFrameSizeRange = %g to %g frames\n", audioRange.mMinimum, audioRange.mMaximum ));    return;}#endif/*******************************************************************/static OSStatus PAOSX_DevicePropertyListener (AudioDeviceID					inDevice,								UInt32							inChannel,								Boolean							isInput,								AudioDevicePropertyID			inPropertyID,								void*							inClientData){    PaHostSoundControl       *pahsc;    internalPortAudioStream  *past;    UInt32                    dataSize;    OSStatus                  err = noErr;    AudioStreamBasicDescription userStreamFormat, hardwareStreamFormat;    Boolean                   updateInverseMicros;    Boolean                   updateConverter;    past = (internalPortAudioStream *) inClientData;    pahsc = (PaHostSoundControl *) past->past_DeviceData;    DBUG(("PAOSX_DevicePropertyListener: called with propertyID = 0x%0X\n", (unsigned int) inPropertyID ));	updateInverseMicros = (inDevice == pahsc->primaryDeviceID) &&        ((inPropertyID == kAudioDevicePropertyStreamFormat) ||         (inPropertyID == kAudioDevicePropertyBufferFrameSize));             updateConverter = (inPropertyID == kAudioDevicePropertyStreamFormat);    // Sample rate needed for both.    if( updateConverter || updateInverseMicros )    {                        /* Get target device format */        dataSize = sizeof(hardwareStreamFormat);        err = AudioDeviceGetProperty(inDevice, 0, isInput,            kAudioDevicePropertyStreamFormat, &dataSize, &hardwareStreamFormat);        if( err != noErr )        {            PRINT_ERR("PAOSX_DevicePropertyListener: Could not get device format", err);

⌨️ 快捷键说明

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