Linux support for typing detection

R=henrika@webrtc.org

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

git-svn-id: http://webrtc.googlecode.com/svn/trunk@4031 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
niklas.enbom@webrtc.org
2013-05-14 21:33:11 +00:00
parent 4ce838934c
commit e2a800644c
5 changed files with 93 additions and 6 deletions

View File

@@ -138,7 +138,7 @@
], ],
'link_settings': { 'link_settings': {
'libraries': [ 'libraries': [
'-ldl', '-ldl','-lX11',
], ],
}, },
'conditions': [ 'conditions': [

View File

@@ -19,7 +19,6 @@
#include "trace.h" #include "trace.h"
#include "thread_wrapper.h" #include "thread_wrapper.h"
webrtc_adm_linux_alsa::AlsaSymbolTable AlsaSymbolTable; webrtc_adm_linux_alsa::AlsaSymbolTable AlsaSymbolTable;
// Accesses ALSA functions through our late-binding symbol table instead of // Accesses ALSA functions through our late-binding symbol table instead of
@@ -110,6 +109,7 @@ AudioDeviceLinuxALSA::AudioDeviceLinuxALSA(const int32_t id) :
_playBufDelay(80), _playBufDelay(80),
_playBufDelayFixed(80) _playBufDelayFixed(80)
{ {
memset(_oldKeyState, 0, sizeof(_oldKeyState));
WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, id, WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, id,
"%s created", __FUNCTION__); "%s created", __FUNCTION__);
} }
@@ -182,6 +182,14 @@ int32_t AudioDeviceLinuxALSA::Init()
return 0; return 0;
} }
//Get X display handle for typing detection
_XDisplay = XOpenDisplay(NULL);
if (!_XDisplay)
{
WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
" failed to open X display, typing detection will not work");
}
_playWarning = 0; _playWarning = 0;
_playError = 0; _playError = 0;
_recWarning = 0; _recWarning = 0;
@@ -248,6 +256,12 @@ int32_t AudioDeviceLinuxALSA::Terminate()
_critSect.Enter(); _critSect.Enter();
} }
if (_XDisplay)
{
XCloseDisplay(_XDisplay);
_XDisplay = NULL;
}
_initialized = false; _initialized = false;
_outputDeviceIsSpecified = false; _outputDeviceIsSpecified = false;
_inputDeviceIsSpecified = false; _inputDeviceIsSpecified = false;
@@ -2290,6 +2304,8 @@ bool AudioDeviceLinuxALSA::RecThreadProcess()
_playoutDelay * 1000 / _playoutFreq, _playoutDelay * 1000 / _playoutFreq,
_recordingDelay * 1000 / _recordingFreq, 0); _recordingDelay * 1000 / _recordingFreq, 0);
_ptrAudioBuffer->SetTypingStatus(KeyPressed());
// Deliver recorded samples at specified sample rate, mic level etc. // Deliver recorded samples at specified sample rate, mic level etc.
// to the observer using callback. // to the observer using callback.
UnLock(); UnLock();
@@ -2317,4 +2333,25 @@ bool AudioDeviceLinuxALSA::RecThreadProcess()
return true; return true;
} }
bool AudioDeviceLinuxALSA::KeyPressed() const{
char szKey[32];
unsigned int i = 0;
char state = 0;
if (!_XDisplay)
return false;
// Check key map status
XQueryKeymap(_XDisplay, szKey);
// A bit change in keymap means a key is pressed
for (i = 0; i < sizeof(szKey); i++)
state |= (szKey[i] ^ _oldKeyState[i]) & szKey[i];
// Save old state
memcpy((char*)_oldKeyState, (char*)szKey, sizeof(_oldKeyState));
return (state != 0);
}
} // namespace webrtc } // namespace webrtc

View File

@@ -12,13 +12,15 @@
#define WEBRTC_AUDIO_DEVICE_AUDIO_DEVICE_ALSA_LINUX_H #define WEBRTC_AUDIO_DEVICE_AUDIO_DEVICE_ALSA_LINUX_H
#include "audio_device_generic.h" #include "audio_device_generic.h"
#include "critical_section_wrapper.h"
#include "audio_mixer_manager_alsa_linux.h" #include "audio_mixer_manager_alsa_linux.h"
#include "critical_section_wrapper.h"
#include <sys/soundcard.h>
#include <sys/ioctl.h>
#include <alsa/asoundlib.h> #include <alsa/asoundlib.h>
#include <sys/soundcard.h>
#include <sys/ioctl.h>
#include <X11/Xlib.h>
namespace webrtc namespace webrtc
{ {
@@ -167,6 +169,9 @@ private:
const int32_t ednLen = 0) const; const int32_t ednLen = 0) const;
int32_t ErrorRecovery(int32_t error, snd_pcm_t* deviceHandle); int32_t ErrorRecovery(int32_t error, snd_pcm_t* deviceHandle);
private:
bool KeyPressed() const;
private: private:
void Lock() { _critSect.Enter(); }; void Lock() { _critSect.Enter(); };
void UnLock() { _critSect.Leave(); }; void UnLock() { _critSect.Leave(); };
@@ -242,6 +247,9 @@ private:
uint16_t _playBufDelay; // playback delay uint16_t _playBufDelay; // playback delay
uint16_t _playBufDelayFixed; // fixed playback delay uint16_t _playBufDelayFixed; // fixed playback delay
char _oldKeyState[32];
Display* _XDisplay;
}; };
} }

View File

@@ -136,6 +136,7 @@ AudioDeviceLinuxPulse::AudioDeviceLinuxPulse(const int32_t id) :
memset(_paServerVersion, 0, sizeof(_paServerVersion)); memset(_paServerVersion, 0, sizeof(_paServerVersion));
memset(&_playBufferAttr, 0, sizeof(_playBufferAttr)); memset(&_playBufferAttr, 0, sizeof(_playBufferAttr));
memset(&_recBufferAttr, 0, sizeof(_recBufferAttr)); memset(&_recBufferAttr, 0, sizeof(_recBufferAttr));
memset(_oldKeyState, 0, sizeof(_oldKeyState));
} }
AudioDeviceLinuxPulse::~AudioDeviceLinuxPulse() AudioDeviceLinuxPulse::~AudioDeviceLinuxPulse()
@@ -230,6 +231,14 @@ int32_t AudioDeviceLinuxPulse::Init()
_recWarning = 0; _recWarning = 0;
_recError = 0; _recError = 0;
//Get X display handle for typing detection
_XDisplay = XOpenDisplay(NULL);
if (!_XDisplay)
{
WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
" failed to open X display, typing detection will not work");
}
// RECORDING // RECORDING
const char* threadName = "webrtc_audio_module_rec_thread"; const char* threadName = "webrtc_audio_module_rec_thread";
_ptrThreadRec = ThreadWrapper::CreateThread(RecThreadFunc, this, _ptrThreadRec = ThreadWrapper::CreateThread(RecThreadFunc, this,
@@ -343,6 +352,12 @@ int32_t AudioDeviceLinuxPulse::Terminate()
return -1; return -1;
} }
if (_XDisplay)
{
XCloseDisplay(_XDisplay);
_XDisplay = NULL;
}
_initialized = false; _initialized = false;
_outputDeviceIsSpecified = false; _outputDeviceIsSpecified = false;
_inputDeviceIsSpecified = false; _inputDeviceIsSpecified = false;
@@ -2655,7 +2670,7 @@ int32_t AudioDeviceLinuxPulse::ProcessRecordedData(
else else
recDelay = 0; recDelay = 0;
_ptrAudioBuffer->SetVQEData(_sndCardPlayDelay, recDelay, clockDrift); _ptrAudioBuffer->SetVQEData(_sndCardPlayDelay, recDelay, clockDrift);
_ptrAudioBuffer->SetTypingStatus(KeyPressed());
// Deliver recorded samples at specified sample rate, // Deliver recorded samples at specified sample rate,
// mic level etc. to the observer using callback // mic level etc. to the observer using callback
UnLock(); UnLock();
@@ -3094,4 +3109,24 @@ bool AudioDeviceLinuxPulse::RecThreadProcess()
return true; return true;
} }
bool AudioDeviceLinuxPulse::KeyPressed() const{
char szKey[32];
unsigned int i = 0;
char state = 0;
if (!_XDisplay)
return false;
// Check key map status
XQueryKeymap(_XDisplay, szKey);
// A bit change in keymap means a key is pressed
for (i = 0; i < sizeof(szKey); i++)
state |= (szKey[i] ^ _oldKeyState[i]) & szKey[i];
// Save old state
memcpy((char*)_oldKeyState, (char*)szKey, sizeof(_oldKeyState));
return (state != 0);
}
} }

View File

@@ -16,6 +16,7 @@
#include "critical_section_wrapper.h" #include "critical_section_wrapper.h"
#include <pulse/pulseaudio.h> #include <pulse/pulseaudio.h>
#include <X11/Xlib.h>
// 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
@@ -237,6 +238,9 @@ private:
void WaitForOperationCompletion(pa_operation* paOperation) const; void WaitForOperationCompletion(pa_operation* paOperation) const;
void WaitForSuccess(pa_operation* paOperation) const; void WaitForSuccess(pa_operation* paOperation) const;
private:
bool KeyPressed() const;
private: private:
static void PaContextStateCallback(pa_context *c, void *pThis); static void PaContextStateCallback(pa_context *c, void *pThis);
static void PaSinkInfoCallback(pa_context *c, const pa_sink_info *i, static void PaSinkInfoCallback(pa_context *c, const pa_sink_info *i,
@@ -374,6 +378,9 @@ private:
uint32_t _playStreamFlags; uint32_t _playStreamFlags;
pa_buffer_attr _playBufferAttr; pa_buffer_attr _playBufferAttr;
pa_buffer_attr _recBufferAttr; pa_buffer_attr _recBufferAttr;
char _oldKeyState[32];
Display* _XDisplay;
}; };
} }