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

📄 pa_unix.c

📁 Audacity是一款用於錄音和編輯聲音的、免費的開放源碼軟體。它可以執行於Mac OS X、Microsoft Windows、GNU/Linux和其它作業系統
💻 C
📖 第 1 页 / 共 3 页
字号:
    /* 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;}/*************************************************************************/PaError PaHost_StartOutput( internalPortAudioStream *past ){    return paNoError;}/*************************************************************************/PaError PaHost_StartInput( internalPortAudioStream *past ){    return paNoError;}/*************************************************************************/PaError PaHost_StartEngine( internalPortAudioStream *past ){    PaHostSoundControl *pahsc;    PaError             result = paNoError;    int                 hres;    pahsc = (PaHostSoundControl *) past->past_DeviceData;    past->past_StopSoon = 0;    past->past_StopNow = 0;    past->past_IsActive = 1;    /* Use pthread_create() instead of __clone() because:     *   - pthread_create also works for other UNIX systems like Solaris,     *   - the Java HotSpot VM crashes in pthread_setcanceltype() when using __clone()     */    hres = pthread_create(&(pahsc->pahsc_AudioThread),                          NULL /*pthread_attr_t * attr*/,                          (pthread_function_t)Pa_AudioThreadProc, past);    if( hres != 0 )    {        result = paHostError;        sPaHostError = hres;        pahsc->pahsc_IsAudioThreadValid = 0;        goto error;    }    pahsc->pahsc_IsAudioThreadValid = 1;error:    return result;}/*************************************************************************/PaError PaHost_StopEngine( internalPortAudioStream *past, int abort ){    int                 hres;    PaError             result = paNoError;    PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;    if( pahsc == NULL ) return paNoError;    /* Tell background thread to stop generating more data and to let current data play out. */    past->past_StopSoon = 1;    /* If aborting, tell background thread to stop NOW! */    if( abort ) past->past_StopNow = 1;    /* Join thread to recover memory resources. */    if( pahsc->pahsc_IsAudioThreadValid )    {        /* This check is needed for GNUSTEP - SB20010904 */        if ( !pthread_equal( pahsc->pahsc_AudioThread, pthread_self() ) )        {            hres = pthread_join( pahsc->pahsc_AudioThread, NULL );        }        else        {            DBUG(("Play thread was stopped from itself - can't do pthread_join()\n"));            hres = 0;        }        if( hres != 0 )        {            result = paHostError;            sPaHostError = hres;        }        pahsc->pahsc_IsAudioThreadValid = 0;    }    past->past_IsActive = 0;    return result;}/*************************************************************************/PaError PaHost_StopInput( internalPortAudioStream *past, int abort ){    return paNoError;}/*************************************************************************/PaError PaHost_StopOutput( internalPortAudioStream *past, int abort ){    return paNoError;}/*******************************************************************/PaError PaHost_CloseStream( internalPortAudioStream   *past ){    PaHostSoundControl *pahsc;    if( past == NULL ) return paBadStreamPtr;    pahsc = (PaHostSoundControl *) past->past_DeviceData;    if( pahsc == NULL ) return paNoError;    if( pahsc->pahsc_OutputHandle != BAD_DEVICE_ID )    {        int err = 0;        DBUG(("PaHost_CloseStream: attempt to close output device handle = %d\n",              pahsc->pahsc_OutputHandle ));        Pa_FlushStream(pahsc->pahsc_OutputHandle);        err = close(pahsc->pahsc_OutputHandle);        if( err < 0 )        {            ERR_RPT(("PaHost_CloseStream: warning, closing output device failed.\n"));        }    }    if( (pahsc->pahsc_InputHandle != BAD_DEVICE_ID) &&            (pahsc->pahsc_InputHandle != pahsc->pahsc_OutputHandle) )    {        int err = 0;        DBUG(("PaHost_CloseStream: attempt to close input device handle = %d\n",              pahsc->pahsc_InputHandle ));        Pa_FlushStream(pahsc->pahsc_InputHandle);        err = close(pahsc->pahsc_InputHandle);        if( err < 0 )        {            ERR_RPT(("PaHost_CloseStream: warning, closing input device failed.\n"));        }    }    pahsc->pahsc_OutputHandle = BAD_DEVICE_ID;    pahsc->pahsc_InputHandle = BAD_DEVICE_ID;    if( pahsc->pahsc_NativeInputBuffer )    {        free( pahsc->pahsc_NativeInputBuffer );        pahsc->pahsc_NativeInputBuffer = NULL;    }    if( pahsc->pahsc_NativeOutputBuffer )    {        free( pahsc->pahsc_NativeOutputBuffer );        pahsc->pahsc_NativeOutputBuffer = NULL;    }    free( pahsc );    past->past_DeviceData = NULL;    return paNoError;}/*************************************************************************/PaError PaHost_Term( void ){    /* Free all of the linked devices. */    internalPortAudioDevice *pad, *nextPad;    pad = sDeviceList;    while( pad != NULL )    {        nextPad = pad->pad_Next;        DBUG(("PaHost_Term: freeing %s\n", pad->pad_DeviceName ));        PaHost_FreeFastMemory( pad, sizeof(internalPortAudioDevice) );        pad = nextPad;    }    sDeviceList = NULL;    return 0;}/************************************************************************* * Sleep for the requested number of milliseconds. */void Pa_Sleep( long msec ){#if 0    struct timeval timeout;    timeout.tv_sec = msec / 1000;    timeout.tv_usec = (msec % 1000) * 1000;    select( 0, NULL, NULL, NULL, &timeout );#else    long usecs = msec * 1000;    usleep( usecs );#endif}/************************************************************************* * Allocate memory that can be accessed in real-time. * This may need to be held in physical memory so that it is not * paged to virtual memory. * This call MUST be balanced with a call to PaHost_FreeFastMemory(). */void *PaHost_AllocateFastMemory( long numBytes ){    void *addr = malloc( numBytes ); /* FIXME - do we need physical, wired, non-virtual memory? */    if( addr != NULL ) memset( addr, 0, numBytes );    return addr;}/************************************************************************* * Free memory that could be accessed in real-time. * This call MUST be balanced with a call to PaHost_AllocateFastMemory(). */void PaHost_FreeFastMemory( void *addr, long numBytes ){    if( addr != NULL ) free( addr );}/***********************************************************************/PaError PaHost_StreamActive( internalPortAudioStream   *past ){    PaHostSoundControl *pahsc;    if( past == NULL ) return paBadStreamPtr;    pahsc = (PaHostSoundControl *) past->past_DeviceData;    if( pahsc == NULL ) return paInternalError;    return (PaError) (past->past_IsActive != 0);}/***********************************************************************/long Pa_GetHostError( void ){    return (long) sPaHostError;}

⌨️ 快捷键说明

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