Remove 44.1 kHz workaround from AudioDevice on PulseAudio.

We currently inform VoE that 44.1 kHz audio is 44 kHz. We now have arbitrary
resampling in VoE, allowing us to pass in the native 44.1 kHz.

Our ALSA interface always requires 48 kHz, allowing ALSA to handle resampling.

This also removes WEBRTC_PA_GTALK which was not defined anywhere.

BUG=webrtc:1395
TESTED=Using 44.1 for capture and render in loopback, ran through all codec channel/rate combinations. Quality is good. Testing AEC was difficult as I can't find a way to change the sample rate of an individual device in PulseAudio. Using a webcam at 32 kHz, other problems were the overriding contribution to quality degradation (delay issues, possible clock drift from the camera). At least I verified that the quality got no worse with this patch.
R=xians@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/1384004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@3955 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
andrew@webrtc.org 2013-05-03 19:01:46 +00:00
parent 7cb766b016
commit a31c428307
2 changed files with 14 additions and 104 deletions

View File

@ -79,7 +79,7 @@ AudioDeviceLinuxPulse::AudioDeviceLinuxPulse(const int32_t id) :
_outputDeviceIndex(0), _outputDeviceIndex(0),
_inputDeviceIsSpecified(false), _inputDeviceIsSpecified(false),
_outputDeviceIsSpecified(false), _outputDeviceIsSpecified(false),
_samplingFreq(0), sample_rate_hz_(0),
_recChannels(1), _recChannels(1),
_playChannels(1), _playChannels(1),
_playBufType(AudioDeviceModule::kFixedBufferSize), _playBufType(AudioDeviceModule::kFixedBufferSize),
@ -804,13 +804,11 @@ int32_t AudioDeviceLinuxPulse::StereoRecordingIsAvailable(bool& available)
return 0; return 0;
} }
#ifndef WEBRTC_PA_GTALK
// Check if the selected microphone can record stereo. // Check if the selected microphone can record stereo.
bool isAvailable(false); bool isAvailable(false);
error = _mixerManager.StereoRecordingIsAvailable(isAvailable); error = _mixerManager.StereoRecordingIsAvailable(isAvailable);
if (!error) if (!error)
available = isAvailable; available = isAvailable;
#endif
// Close the initialized input mixer // Close the initialized input mixer
if (!wasInitialized) if (!wasInitialized)
@ -824,12 +822,10 @@ int32_t AudioDeviceLinuxPulse::StereoRecordingIsAvailable(bool& available)
int32_t AudioDeviceLinuxPulse::SetStereoRecording(bool enable) int32_t AudioDeviceLinuxPulse::SetStereoRecording(bool enable)
{ {
#ifndef WEBRTC_PA_GTALK
if (enable) if (enable)
_recChannels = 2; _recChannels = 2;
else else
_recChannels = 1; _recChannels = 1;
#endif
return 0; return 0;
} }
@ -863,13 +859,11 @@ int32_t AudioDeviceLinuxPulse::StereoPlayoutIsAvailable(bool& available)
return -1; return -1;
} }
#ifndef WEBRTC_PA_GTALK
// Check if the selected speaker can play stereo. // Check if the selected speaker can play stereo.
bool isAvailable(false); bool isAvailable(false);
error = _mixerManager.StereoPlayoutIsAvailable(isAvailable); error = _mixerManager.StereoPlayoutIsAvailable(isAvailable);
if (!error) if (!error)
available = isAvailable; available = isAvailable;
#endif
// Close the initialized input mixer // Close the initialized input mixer
if (!wasInitialized) if (!wasInitialized)
@ -883,12 +877,10 @@ int32_t AudioDeviceLinuxPulse::StereoPlayoutIsAvailable(bool& available)
int32_t AudioDeviceLinuxPulse::SetStereoPlayout(bool enable) int32_t AudioDeviceLinuxPulse::SetStereoPlayout(bool enable)
{ {
#ifndef WEBRTC_PA_GTALK
if (enable) if (enable)
_playChannels = 2; _playChannels = 2;
else else
_playChannels = 1; _playChannels = 1;
#endif
return 0; return 0;
} }
@ -1276,18 +1268,11 @@ int32_t AudioDeviceLinuxPulse::InitPlayout()
" InitSpeaker() failed"); " InitSpeaker() failed");
} }
// Set sampling rate to use
uint32_t samplingRate = _samplingFreq * 1000;
if (samplingRate == 44000)
{
samplingRate = 44100;
}
// Set the play sample specification // Set the play sample specification
pa_sample_spec playSampleSpec; pa_sample_spec playSampleSpec;
playSampleSpec.channels = _playChannels; playSampleSpec.channels = _playChannels;
playSampleSpec.format = PA_SAMPLE_S16LE; playSampleSpec.format = PA_SAMPLE_S16LE;
playSampleSpec.rate = samplingRate; playSampleSpec.rate = sample_rate_hz_;
// Create a new play stream // Create a new play stream
_playStream = LATE(pa_stream_new)(_paContext, "playStream", _playStream = LATE(pa_stream_new)(_paContext, "playStream",
@ -1307,7 +1292,7 @@ int32_t AudioDeviceLinuxPulse::InitPlayout()
if (_ptrAudioBuffer) if (_ptrAudioBuffer)
{ {
// Update audio buffer with the selected parameters // Update audio buffer with the selected parameters
_ptrAudioBuffer->SetPlayoutSampleRate(_samplingFreq * 1000); _ptrAudioBuffer->SetPlayoutSampleRate(sample_rate_hz_);
_ptrAudioBuffer->SetPlayoutChannels((uint8_t) _playChannels); _ptrAudioBuffer->SetPlayoutChannels((uint8_t) _playChannels);
} }
@ -1356,7 +1341,7 @@ int32_t AudioDeviceLinuxPulse::InitPlayout()
} }
// num samples in bytes * num channels // num samples in bytes * num channels
_playbackBufferSize = _samplingFreq * 10 * 2 * _playChannels; _playbackBufferSize = sample_rate_hz_ / 100 * 2 * _playChannels;
_playbackBufferUnused = _playbackBufferSize; _playbackBufferUnused = _playbackBufferSize;
_playBuffer = new int8_t[_playbackBufferSize]; _playBuffer = new int8_t[_playbackBufferSize];
@ -1402,18 +1387,11 @@ int32_t AudioDeviceLinuxPulse::InitRecording()
" InitMicrophone() failed"); " InitMicrophone() failed");
} }
// Set sampling rate to use
uint32_t samplingRate = _samplingFreq * 1000;
if (samplingRate == 44000)
{
samplingRate = 44100;
}
// Set the rec sample specification // Set the rec sample specification
pa_sample_spec recSampleSpec; pa_sample_spec recSampleSpec;
recSampleSpec.channels = _recChannels; recSampleSpec.channels = _recChannels;
recSampleSpec.format = PA_SAMPLE_S16LE; recSampleSpec.format = PA_SAMPLE_S16LE;
recSampleSpec.rate = samplingRate; recSampleSpec.rate = sample_rate_hz_;
// Create a new rec stream // Create a new rec stream
_recStream = LATE(pa_stream_new)(_paContext, "recStream", &recSampleSpec, _recStream = LATE(pa_stream_new)(_paContext, "recStream", &recSampleSpec,
@ -1432,7 +1410,7 @@ int32_t AudioDeviceLinuxPulse::InitRecording()
if (_ptrAudioBuffer) if (_ptrAudioBuffer)
{ {
// Update audio buffer with the selected parameters // Update audio buffer with the selected parameters
_ptrAudioBuffer->SetRecordingSampleRate(_samplingFreq * 1000); _ptrAudioBuffer->SetRecordingSampleRate(sample_rate_hz_);
_ptrAudioBuffer->SetRecordingChannels((uint8_t) _recChannels); _ptrAudioBuffer->SetRecordingChannels((uint8_t) _recChannels);
} }
@ -1475,7 +1453,7 @@ int32_t AudioDeviceLinuxPulse::InitRecording()
_configuredLatencyRec = latency; _configuredLatencyRec = latency;
} }
_recordBufferSize = _samplingFreq * 10 * 2 * _recChannels; _recordBufferSize = sample_rate_hz_ / 100 * 2 * _recChannels;
_recordBufferUsed = 0; _recordBufferUsed = 0;
_recBuffer = new int8_t[_recordBufferSize]; _recBuffer = new int8_t[_recordBufferSize];
@ -1985,17 +1963,7 @@ void AudioDeviceLinuxPulse::PaSourceInfoCallbackHandler(
void AudioDeviceLinuxPulse::PaServerInfoCallbackHandler(const pa_server_info *i) void AudioDeviceLinuxPulse::PaServerInfoCallbackHandler(const pa_server_info *i)
{ {
// Use PA native sampling rate // Use PA native sampling rate
uint32_t paSampleRate = i->sample_spec.rate; sample_rate_hz_ = i->sample_spec.rate;
if (paSampleRate == 44100)
{
#ifdef WEBRTC_PA_GTALK
paSampleRate = 48000;
#else
paSampleRate = 44000;
#endif
}
_samplingFreq = paSampleRate / 1000;
// Copy the PA server version // Copy the PA server version
strncpy(_paServerVersion, i->server_version, 31); strncpy(_paServerVersion, i->server_version, 31);
@ -2052,13 +2020,6 @@ void AudioDeviceLinuxPulse::PaStreamStateCallbackHandler(pa_stream *p)
int32_t AudioDeviceLinuxPulse::CheckPulseAudioVersion() int32_t AudioDeviceLinuxPulse::CheckPulseAudioVersion()
{ {
/*int32_t index = 0;
int32_t partIndex = 0;
int32_t partNum = 1;
int32_t minVersion[3] = {0, 9, 15};
bool versionOk = false;
char str[8] = {0};*/
PaLock(); PaLock();
pa_operation* paOperation = NULL; pa_operation* paOperation = NULL;
@ -2074,54 +2035,6 @@ int32_t AudioDeviceLinuxPulse::CheckPulseAudioVersion()
WEBRTC_TRACE(kTraceStateInfo, kTraceAudioDevice, -1, WEBRTC_TRACE(kTraceStateInfo, kTraceAudioDevice, -1,
" checking PulseAudio version: %s", _paServerVersion); " checking PulseAudio version: %s", _paServerVersion);
/* Saved because it may turn out that we need to check the version in the future
while (true)
{
if (_paServerVersion[index] == '.')
{
index++;
str[partIndex] = '\0';
partIndex = 0;
if(partNum == 2)
{
if (atoi(str) < minVersion[1])
{
break;
}
partNum = 3;
}
else
{
if (atoi(str) > minVersion[0])
{
versionOk = true;
break;
}
partNum = 2;
}
}
else if (_paServerVersion[index] == '\0' || _paServerVersion[index] == '-')
{
str[partIndex] = '\0';
if (atoi(str) >= minVersion[2])
{
versionOk = true;
}
break;
}
str[partIndex] = _paServerVersion[index];
index++;
partIndex++;
}
if (!versionOk)
{
return -1;
}
*/
return 0; return 0;
} }
@ -2131,7 +2044,7 @@ int32_t AudioDeviceLinuxPulse::InitSamplingFrequency()
pa_operation* paOperation = NULL; pa_operation* paOperation = NULL;
// Get the server info and update _samplingFreq // Get the server info and update sample_rate_hz_
paOperation = LATE(pa_context_get_server_info)(_paContext, paOperation = LATE(pa_context_get_server_info)(_paContext,
PaServerInfoCallback, this); PaServerInfoCallback, this);
@ -2354,11 +2267,11 @@ int32_t AudioDeviceLinuxPulse::InitPulseAudio()
} }
// Initialize sampling frequency // Initialize sampling frequency
if (InitSamplingFrequency() < 0 || _samplingFreq == 0) if (InitSamplingFrequency() < 0 || sample_rate_hz_ == 0)
{ {
WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
" failed to initialize sampling frequency, set to %d", " failed to initialize sampling frequency, set to %d Hz",
_samplingFreq); sample_rate_hz_);
return -1; return -1;
} }

View File

@ -17,9 +17,6 @@
#include <pulse/pulseaudio.h> #include <pulse/pulseaudio.h>
// Set this define to make the code behave like in GTalk/libjingle
//#define WEBRTC_PA_GTALK
// We define this flag if it's missing from our headers, because we want to be // We define this flag if it's missing from our headers, because we want to be
// able to compile against old headers but still use PA_STREAM_ADJUST_LATENCY // able to compile against old headers but still use PA_STREAM_ADJUST_LATENCY
// if run against a recent version of the library. // if run against a recent version of the library.
@ -311,7 +308,7 @@ private:
bool _inputDeviceIsSpecified; bool _inputDeviceIsSpecified;
bool _outputDeviceIsSpecified; bool _outputDeviceIsSpecified;
uint32_t _samplingFreq; int sample_rate_hz_;
uint8_t _recChannels; uint8_t _recChannels;
uint8_t _playChannels; uint8_t _playChannels;