📄 alsasounddevice.cxx
字号:
// exit(-1); } /* Disable the XRUN detection */ if (snd_pcm_sw_params_set_stop_threshold(writeHandle, swparams, 0x7FFFFFFF)){ cerr << "Could not set ALSA stop threshold (playback)" << endl; exit(-1); } if (snd_pcm_sw_params_set_avail_min(writeHandle, swparams, minAvailable)){ #ifdef DEBUG_OUTPUT cerr << "Could not set ALSA avail_min (playback)" << endl; #endif// exit(-1); } if (snd_pcm_sw_params(writeHandle, swparams) < 0) { cerr << "Could not apply sw parameters to ALSA sound card (playback)" << endl; exit(-1); } // snd_pcm_prepare( writeHandle );#ifdef DEBUG_OUTPUT cerr << "ALSA OPENED playback!!" << endl << flush;#endif openedPlayback = true; lockOpen.unlock(); return 1;} int AlsaSoundDevice::openRecord( int samplingRate, int nChannels, int format ){ snd_pcm_hw_params_t *hwparams2; snd_pcm_sw_params_t *swparams2; lockOpen.lock(); snd_pcm_hw_params_alloca(&hwparams2); snd_pcm_sw_params_alloca(&swparams2); if (snd_pcm_open(&readHandle, dev.c_str(), SND_PCM_STREAM_CAPTURE, 0)<0){ cerr << "Could not open ALSA sound card for recording" << endl; exit(-1); } if (snd_pcm_hw_params_any(readHandle, hwparams2) < 0) { cerr << "Could not get ALSA sound card parameters (record) " << endl; exit(-1); } if (snd_pcm_hw_params_set_access(readHandle, hwparams2, SND_PCM_ACCESS_RW_INTERLEAVED) < 0) { cerr << "Could not set ALSA mode (record) " << endl; exit(-1); } if (snd_pcm_hw_params_set_channels(readHandle, hwparams2, nChannels)<0){ //if desired num of channels fails, try setting to 1 channel cerr << "Cound not configure ALSA for recording on "<< nChannels<< "channels." << endl; if( nChannels != 1 ){ if (snd_pcm_hw_params_set_channels( readHandle, hwparams2, 1)<0){ // try to fall back on 1 channel, which should work // in most cases cerr << "Cound not configure ALSA for " "recording on 1 channel." << endl; cerr << "Minisip will now exit." << endl; exit(-1); } else{ this->nChannelsRecord = 1; } } else{ cerr << "Cound not configure ALSA " "for recording on 1 channel." << endl; cerr << "Minisip will now exit." << endl; exit(-1); } } else{ this->nChannelsRecord = nChannels; } setFormat( format ); _snd_pcm_format alsaFormat; switch( format ){ case SOUND_S16LE: alsaFormat = SND_PCM_FORMAT_S16_LE; break; case SOUND_S16BE: alsaFormat = SND_PCM_FORMAT_S16_BE; break; case SOUND_U16LE: alsaFormat = SND_PCM_FORMAT_U16_LE; break; case SOUND_U16BE: alsaFormat = SND_PCM_FORMAT_U16_BE; break; default: cerr << "ALSA: Unhandled sound format (record) " << endl; exit( -1 ); } if (snd_pcm_hw_params_set_format(readHandle, hwparams2, alsaFormat) < 0) { cerr << "Could not set ALSA format (record) " << endl; exit(-1); }/* if (snd_pcm_hw_params_set_buffer_time(readHandle, hwparams2, 40000, 0) < 0) { cerr << "Could not set ALSA buffer time" << endl; exit(-1); } */ unsigned int wantedSamplingRate = (unsigned int)samplingRate; if( snd_pcm_hw_params_set_rate_near(readHandle, hwparams2, (unsigned int *)&samplingRate, NULL) < 0){ cerr << "Could not set ALSA rate (record) " << endl; exit(-1); } if( (unsigned int)samplingRate != wantedSamplingRate ){ #ifdef DEBUG_OUTPUT cerr << "Could not set chosen (record) rate of " << wantedSamplingRate << ", set to "<< samplingRate <<endl; #endif } this->samplingRate = samplingRate; unsigned long periodSizeMin = 960; //desired size of one period ... in number of frames unsigned long periodSizeMax; //size of one period ... in number of frames uint32_t numPeriodsMin; //desired buffer length in number of periods uint32_t numPeriodsMax; //desired buffer length in number of periods unsigned long max_buffer_size; //max buffer size allowd // uint32_t startThreshold = 16; //number of frames in the buffer so the hw will start processing// uint32_t minAvailable = 32; //number of available frames so we can read/write int32_t dir; //fetch the params ... exit if not able ... if( snd_pcm_hw_params_get_period_size_min (hwparams2, &periodSizeMin, &dir) < 0 ) { cerr << "Record: Could not get ALSA period min size" << endl; exit( -1 ); } if( snd_pcm_hw_params_get_period_size_max (hwparams2, &periodSizeMax, &dir) < 0 ) { cerr << "Record: Could not get ALSA period max size" << endl; exit( -1 ); } if( snd_pcm_hw_params_get_periods_min (hwparams2, &numPeriodsMin, &dir) < 0 ) { cerr << "Record: Could not get ALSA periods min " << endl; exit( -1 ); } if( snd_pcm_hw_params_get_periods_max (hwparams2, &numPeriodsMax, &dir) < 0 ) { cerr << "Record: Could not get ALSA periods max " << endl; exit( -1 ); } if( snd_pcm_hw_params_get_buffer_size_max (hwparams2, &max_buffer_size) < 0 ) { cerr << "Record: Could not get ALSA max buffer size " << endl; exit( -1 ); } if( calculateAlsaParams( periodSizeMin, periodSizeMax, numPeriodsMin, numPeriodsMax, max_buffer_size) < 0 ) { cerr << "Record: Could Not calculate Alsa Params" << endl; exit( -1 ); }#ifdef DEBUG_OUTPUT printf( "ALSA Record: setting values %d, %d\n", (int)this->numPeriods, (int)this->periodSize );#endif //Set the calculated params ... they should not give an eror ... still, check ... if( snd_pcm_hw_params_set_periods (readHandle, hwparams2, this->numPeriods, 0) < 0 ) { cerr << "Record Could not set ALSA periods" << endl; exit( -1 ); } if( snd_pcm_hw_params_set_period_size_near (readHandle, hwparams2, &this->periodSize, 0) < 0 ) { cerr << "Record Could not set ALSA period size" << endl; exit( -1 ); } #ifdef DEBUG_OUTPUT else { cerr << "Record: alsa period size set to " << this->periodSize << endl; }#endif if (snd_pcm_hw_params(readHandle, hwparams2) < 0) { cerr << "Record Could not apply parameters to ALSA sound card for playout" << endl; exit(-1); } if (snd_pcm_sw_params_current(readHandle, swparams2) < 0) { cerr << "Record Could not get ALSA software parameters" << endl; exit(-1); } /* Disable the XRUN detection */ if (snd_pcm_sw_params_set_stop_threshold(readHandle, swparams2, 0x7FFFFFFF)){ cerr << "Record Could not set ALSA stop threshold" << endl; exit(-1); } if (snd_pcm_sw_params(readHandle, swparams2) < 0) { cerr << "Record Could not apply sw parameters to ALSA sound card" << endl; exit(-1); } //snd_pcm_prepare(writeHandle); snd_pcm_prepare(readHandle); //snd_pcm_start(readHandle); #ifdef DEBUG_OUTPUT cerr << "ALSA OPENED record!!" << endl << flush;#endif openedRecord = true; lockOpen.unlock(); return 0;}//Note: in alsa jargon, nSamples would be named nFrames. An AlsaFrame is made of // N samples per each channel, and each sample is X bytes long.int AlsaSoundDevice::readFromDevice( byte_t * buffer, uint32_t nSamples ){ int nSamplesRead = 0; if( readHandle == NULL ){ return -EBADF; } //it reads nSamples and returns the number of samples read ... // or directly the negative error code if an error nSamplesRead = snd_pcm_readi( readHandle, buffer, nSamples ); return nSamplesRead;}int AlsaSoundDevice::readError( int errcode, byte_t * buffer, uint32_t nSamples ) { string msg = ""; bool mustReturn = true; switch( errcode ){ case -EAGAIN: case -EINTR: msg = "REAGAIN"; mustReturn = false; break; case -EPIPE: msg = "REPIPE"; if( snd_pcm_prepare( readHandle ) == -1 ) { mustReturn = true;} else { mustReturn = false; } break; default: msg = "RERROR"; break; }#ifdef DEBUG_OUTPUT fprintf( stderr, msg.c_str() );#endif if( mustReturn ) { return -1; } else { return 0; }}int AlsaSoundDevice::writeToDevice( byte_t * buffer, uint32_t nSamples ){ int nSamplesWritten = 0; if( writeHandle == NULL ){ return -EBADF; } nSamplesWritten = snd_pcm_writei( writeHandle, buffer, nSamples ); return nSamplesWritten; //the return is already the samples written or a negative value}int AlsaSoundDevice::writeError( int errcode, byte_t * buffer, uint32_t nSamples ) { string msg = ""; bool mustReturn = true; switch( errcode ){ case -EAGAIN: case -EINTR: msg = "WEAGAIN"; mustReturn = false; break; case -EPIPE: msg = "WEPIPE"; if( snd_pcm_prepare( writeHandle ) == -1 ) { mustReturn = true;} else { mustReturn = false; } break; default: msg = "WERROR"; break; }#ifdef DEBUG_OUTPUT fprintf( stderr, msg.c_str() );#endif if( mustReturn ) { return -1; } else { return 0; }}void AlsaSoundDevice::sync(){ if( snd_pcm_drain( writeHandle ) < 0 ){#ifdef DEBUG_OUTPUT cerr << "ALSA: Error on pcm_drain" << endl;#endif //exit(-1); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -