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': {
'libraries': [
'-ldl',
'-ldl','-lX11',
],
},
'conditions': [

View File

@@ -19,7 +19,6 @@
#include "trace.h"
#include "thread_wrapper.h"
webrtc_adm_linux_alsa::AlsaSymbolTable AlsaSymbolTable;
// Accesses ALSA functions through our late-binding symbol table instead of
@@ -110,6 +109,7 @@ AudioDeviceLinuxALSA::AudioDeviceLinuxALSA(const int32_t id) :
_playBufDelay(80),
_playBufDelayFixed(80)
{
memset(_oldKeyState, 0, sizeof(_oldKeyState));
WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, id,
"%s created", __FUNCTION__);
}
@@ -182,6 +182,14 @@ int32_t AudioDeviceLinuxALSA::Init()
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;
_playError = 0;
_recWarning = 0;
@@ -248,6 +256,12 @@ int32_t AudioDeviceLinuxALSA::Terminate()
_critSect.Enter();
}
if (_XDisplay)
{
XCloseDisplay(_XDisplay);
_XDisplay = NULL;
}
_initialized = false;
_outputDeviceIsSpecified = false;
_inputDeviceIsSpecified = false;
@@ -2290,6 +2304,8 @@ bool AudioDeviceLinuxALSA::RecThreadProcess()
_playoutDelay * 1000 / _playoutFreq,
_recordingDelay * 1000 / _recordingFreq, 0);
_ptrAudioBuffer->SetTypingStatus(KeyPressed());
// Deliver recorded samples at specified sample rate, mic level etc.
// to the observer using callback.
UnLock();
@@ -2317,4 +2333,25 @@ bool AudioDeviceLinuxALSA::RecThreadProcess()
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

View File

@@ -12,13 +12,15 @@
#define WEBRTC_AUDIO_DEVICE_AUDIO_DEVICE_ALSA_LINUX_H
#include "audio_device_generic.h"
#include "critical_section_wrapper.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 <sys/soundcard.h>
#include <sys/ioctl.h>
#include <X11/Xlib.h>
namespace webrtc
{
@@ -167,6 +169,9 @@ private:
const int32_t ednLen = 0) const;
int32_t ErrorRecovery(int32_t error, snd_pcm_t* deviceHandle);
private:
bool KeyPressed() const;
private:
void Lock() { _critSect.Enter(); };
void UnLock() { _critSect.Leave(); };
@@ -242,6 +247,9 @@ private:
uint16_t _playBufDelay; // 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(&_playBufferAttr, 0, sizeof(_playBufferAttr));
memset(&_recBufferAttr, 0, sizeof(_recBufferAttr));
memset(_oldKeyState, 0, sizeof(_oldKeyState));
}
AudioDeviceLinuxPulse::~AudioDeviceLinuxPulse()
@@ -230,6 +231,14 @@ int32_t AudioDeviceLinuxPulse::Init()
_recWarning = 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
const char* threadName = "webrtc_audio_module_rec_thread";
_ptrThreadRec = ThreadWrapper::CreateThread(RecThreadFunc, this,
@@ -343,6 +352,12 @@ int32_t AudioDeviceLinuxPulse::Terminate()
return -1;
}
if (_XDisplay)
{
XCloseDisplay(_XDisplay);
_XDisplay = NULL;
}
_initialized = false;
_outputDeviceIsSpecified = false;
_inputDeviceIsSpecified = false;
@@ -2655,7 +2670,7 @@ int32_t AudioDeviceLinuxPulse::ProcessRecordedData(
else
recDelay = 0;
_ptrAudioBuffer->SetVQEData(_sndCardPlayDelay, recDelay, clockDrift);
_ptrAudioBuffer->SetTypingStatus(KeyPressed());
// Deliver recorded samples at specified sample rate,
// mic level etc. to the observer using callback
UnLock();
@@ -3094,4 +3109,24 @@ bool AudioDeviceLinuxPulse::RecThreadProcess()
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 <pulse/pulseaudio.h>
#include <X11/Xlib.h>
// 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
@@ -237,6 +238,9 @@ private:
void WaitForOperationCompletion(pa_operation* paOperation) const;
void WaitForSuccess(pa_operation* paOperation) const;
private:
bool KeyPressed() const;
private:
static void PaContextStateCallback(pa_context *c, void *pThis);
static void PaSinkInfoCallback(pa_context *c, const pa_sink_info *i,
@@ -374,6 +378,9 @@ private:
uint32_t _playStreamFlags;
pa_buffer_attr _playBufferAttr;
pa_buffer_attr _recBufferAttr;
char _oldKeyState[32];
Display* _XDisplay;
};
}