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

📄 newsoundcard.cxx

📁 Vovida 社区开源的 SIP 协议源码
💻 CXX
字号:
#include <iostream>#include <fstream>#include <cstdio>#include <unistd.h>#include <sys/ioctl.h>#include <csignal>/* sockets */#include <sys/types.h>#include <sys/socket.h>#include <fcntl.h>#include <netinet/in.h>#include <arpa/inet.h>#include <netdb.h>#ifndef WIN32#include <sys/soundcard.h>#endif#include "NewSoundCard.hxx"#include "cpLog.h"#include <cassert>#include "Lock.hxx"using Vocal::Threads::Lock;extern "C"{    unsigned char linear2ulaw( int pcm_val );    int ulaw2linear( unsigned char u_val );}NewSoundCard::NewSoundCard( const char* deviceName )    : myFD(-1),      myDeviceName(deviceName),      myFormat(NewSoundCardInvalid),      myReadBuffer(2048),      myWriteBuffer(2048){    assert(deviceName);}int NewSoundCard::reopen(){    int retval;    retval = close();    retval = retval | open();    return retval;}int NewSoundCard::open(){    deviceMutex.lock();    cpLog(LOG_DEBUG, "Opening audio hardware" );    // open audio device    LocalScopeAllocator lo;#ifndef WIN32    if( ( myFD = ::open( myDeviceName.getData(lo), O_RDWR, 0 ) ) == -1 )    {        perror("Open failed:");	deviceMutex.unlock();	myFD = -1;	return -1;    }#else    if (waveInGetNumDevs() <= 0)     {        cpLog(LOG_DEBUG, "could not get any devices");        deviceMutex.unlock();	myFD = -1;	return -1;    }    if (!m_aSoundCardWinOut.Open(SoundOut))     {        perror("Open openAudioHardware failed (not found input sound card device) : ");        deviceMutex.unlock();	myFD = -1;	return -1;    }    if (!m_aSoundCardWinIn.Open(SoundIn))     {#ifndef _DEBUG        //AND:Need for run 2 exemplars program on one computer (debug version)        m_aSoundCardWinOut.Close();        perror("Open openAudioHardware failed (not found output sound card device) : ");        deviceMutex.unlock();	myFD = -1;	return -1;#endif    }    myFD = 1;#endif#ifndef WIN32    // query audio formats    int ioctlParam = -1;    if( ioctl( myFD, SNDCTL_DSP_GETFMTS, &ioctlParam ) == -1 )    {        perror("SNDCTL_DSP_GETFMTS");        deviceMutex.unlock();	myFD = -1;        return -1;    }    // choose codec    if( ioctlParam & AFMT_MU_LAW )    {        //cpLog(LOG_DEBUG,"Setting sound card to ulaw");        ioctlParam = AFMT_MU_LAW;	myFormat = NewSoundCardUlaw;    }    else if( ioctlParam & AFMT_S16_LE )    {        //cpLog(LOG_DEBUG,"Setting sound card to linear16");        ioctlParam = AFMT_S16_LE;	myFormat = NewSoundCardSigned16LE;    }    else    {        cpLog(LOG_ERR,"Sound card doesn't support any known encodings");        printf("Sound card supports the following (Mask:%d:)\n", ioctlParam);        if( ioctlParam & AFMT_MU_LAW )     printf("  AFMT_MU_LAW\n");        if( ioctlParam & AFMT_A_LAW )      printf("  AFMT_A_LAW\n");        if( ioctlParam & AFMT_IMA_ADPCM )  printf("  AFMT_IMA_ADPCM\n");        if( ioctlParam & AFMT_U8 )         printf("  AFMT_U8\n");        if( ioctlParam & AFMT_S16_LE )     printf("  AFMT_S16_LE\n");        if( ioctlParam & AFMT_S16_BE )     printf("  AFMT_S16_BE\n");        if( ioctlParam & AFMT_S8 )         printf("  AFMT_S8\n");        if( ioctlParam & AFMT_U16_LE )     printf("  AFMT_U16_LE\n");        if( ioctlParam & AFMT_U16_BE )     printf("  AFMT_U16_BE\n");        if( ioctlParam & AFMT_MPEG )       printf("  AFMT_MPEG\n");        deviceMutex.unlock();	myFD = -1;        return -1;    }    // setting audio device parameters    //ioctlParam = AFMT_MU_LAW;  //test setting to ulaw    int ioctlParamSave = ioctlParam;    if( ioctl( myFD, SNDCTL_DSP_SETFMT, &ioctlParam ) == -1 )    {           perror("SNDCTL_DSP_SETFMT");        deviceMutex.unlock();	myFD = -1;        return -1;    }    if( ioctlParam != ioctlParamSave )    {           perror("Failed to set DSP Format, sound card returned format");        deviceMutex.unlock();	myFD = -1;        return -1;    }    ioctlParam = 1;    // set the number of channels to 1.  if this is an error, it    // should probably not be a major failure.    if( ioctl( myFD, SNDCTL_DSP_CHANNELS, &ioctlParam ) == -1 )    {        perror("SNDCTL_DSP_CHANNELS");        deviceMutex.unlock();	myFD = -1;        return -1;    }    if( ioctlParam != 1)    {        cout << "warning:  unable to set audio output to mono,"             << " may cause problems later\n";    }    ioctlParam = 8000;    if( ioctl( myFD, SNDCTL_DSP_SPEED, &ioctlParam ) == -1 )    {        perror("SNDCTL_DSP_SPEED");        deviceMutex.unlock();	myFD = -1;        return -1;    }    if( ioctlParam != 8000 )    {        perror("Failed to set sample rate");        deviceMutex.unlock();	myFD = -1;        return -1;    }#else    myFormat = NewSoundCardSigned16LE;#endif    deviceMutex.unlock();    return 0;}void NewSoundCard::write ( const unsigned char* data,			   int samples ){    signed short longdataBuffer[480];    unsigned char dataBuffer[480];    int cc = 0;    int p = 0;     // check codec encodings    switch( myFormat )    {    case NewSoundCardUlaw:        // no conversion needed	myWriteBuffer.put(data, samples);        break;            case NewSoundCardSigned16LE:        // convert sound sample from ULAW to Linear16        for(p = 0; p < samples; p++ )            longdataBuffer[p]  = ulaw2linear( data[p] );        samples *= 2;        myWriteBuffer.put((unsigned char*)longdataBuffer, samples);        break;    default:        cpLog(LOG_ERR,"Failed to provide correct codec encoding");        return;    }    deviceMutex.lock();    cc = myWriteBuffer.get(dataBuffer, samples);#ifndef WIN32    audio_buf_info info;    ::ioctl(myFD, SNDCTL_DSP_GETOSPACE, &info);    {        int bytecount = info.fragments * info.fragsize;                if (cc > bytecount)        {//            cout << "write will block" << endl;        }    }    {        if (myWriteBuffer.bytesUsed() > 100)        {//            cout << "bytesUsed: " << myWriteBuffer.bytesUsed() << endl;        }    }    {        int bufbytes = 0;        ::ioctl(myFD, SNDCTL_DSP_GETODELAY, &bufbytes);        if(bufbytes > 256)        {//            cout << "bufbytes: " << bufbytes << endl;        }    }    ::write( myFD, dataBuffer, cc );    #else    m_aSoundCardWinOut.Write(reinterpret_cast<char*>(dataBuffer), cc);#endif
    deviceMutex.unlock();    return;}int NewSoundCard::read( unsigned char* data,			const int samples ){    signed short longdataBuffer[480];#ifndef WIN32
    unsigned char dataBuffer[480];
#endif        int cc = -1;    int p = 0;    //check codec encodings    switch( myFormat )    {#ifndef WIN32    case NewSoundCardUlaw:        // no conversion needed        cc = 0;	deviceMutex.lock();        audio_buf_info info;        ::ioctl(myFD, SNDCTL_DSP_GETISPACE, &info);        {            int bytecount = info.fragments * info.fragsize;            if (samples > bytecount)            {//                cout << "read: " << bytecount << endl;            }        }        cc = ::read( myFD, dataBuffer, samples );	myReadBuffer.put(dataBuffer, cc);	deviceMutex.unlock();	cc = myReadBuffer.get(data, samples);        break;#endif    case NewSoundCardSigned16LE:        // convert sound sample from Liner16 to ULAW	deviceMutex.lock();#ifndef WIN32        cc = ::read( myFD, (char*)longdataBuffer, samples * 2 );#else        cc = m_aSoundCardWinIn.Read( (char*)longdataBuffer, samples * 2 );#endif	deviceMutex.unlock();        for(; p < cc; p++ )        {            data[p]  = linear2ulaw( longdataBuffer[p] );        }        cc /= 2;        break;    default:        cpLog(LOG_DEBUG,"Failed to provide correct encoding");        break;    }#ifndef WIN32    if( samples != cc )    {        cpLog(LOG_DEBUG,"Incomplete read from Sound Card (%d)", cc);    }#else    // AND:prevent - many garbage on screen (when run 2 programs and    // input from sound card already use one from him) :-/    if( m_aSoundCardWinIn.IsOpen() && samples != cc )    {        cpLog(LOG_ERR,"Incomplete read from Sound Card (%d)", cc);    }#endif    return cc;}int NewSoundCard::close(){    int retval = 0;    deviceMutex.lock();    cpLog(LOG_DEBUG, "Closing audio hardware" );#ifndef WIN32    if( ioctl( myFD, SNDCTL_DSP_RESET, 0 ) == -1 )     {        perror("SNDCTL_DSP_RESET");    }    retval = ::close( myFD );#else    m_aSoundCardWinOut.Close();    m_aSoundCardWinIn.Close();#endif    deviceMutex.unlock();    myFD = -1;    return retval;}NewSoundCardFormatNewSoundCard::getFormat() const{    Lock mylock_(deviceMutex);    return myFormat;}int NewSoundCard::getFd() const{    Lock mylock_(deviceMutex);    return myFD;}/* Local Variables: *//* c-file-style: "stroustrup" *//* indent-tabs-mode: nil *//* c-file-offsets: ((access-label . -) (inclass . ++)) *//* c-basic-offset: 4 *//* End: */

⌨️ 快捷键说明

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