Refactoring for typing detection
R=henrika@webrtc.org Review URL: https://webrtc-codereview.appspot.com/1370004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@3976 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
ef14488d03
commit
3be565b502
@ -46,6 +46,7 @@ AudioDeviceBuffer::AudioDeviceBuffer() :
|
||||
_playFile(*FileWrapper::Create()),
|
||||
_currentMicLevel(0),
|
||||
_newMicLevel(0),
|
||||
_typingStatus(false),
|
||||
_playDelayMS(0),
|
||||
_recDelayMS(0),
|
||||
_clockDrift(0) {
|
||||
@ -266,6 +267,12 @@ int32_t AudioDeviceBuffer::SetCurrentMicLevel(uint32_t level)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t AudioDeviceBuffer::SetTypingStatus(bool typingStatus)
|
||||
{
|
||||
_typingStatus = typingStatus;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// NewMicLevel
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -469,6 +476,7 @@ int32_t AudioDeviceBuffer::DeliverRecordedData()
|
||||
totalDelayMS,
|
||||
_clockDrift,
|
||||
_currentMicLevel,
|
||||
_typingStatus,
|
||||
newMicLevel);
|
||||
if (res != -1)
|
||||
{
|
||||
|
@ -67,6 +67,8 @@ public:
|
||||
const char fileName[kAdmMaxFileNameSize]);
|
||||
int32_t StopOutputFileRecording();
|
||||
|
||||
int32_t SetTypingStatus(bool typingStatus);
|
||||
|
||||
AudioDeviceBuffer();
|
||||
~AudioDeviceBuffer();
|
||||
|
||||
@ -110,6 +112,8 @@ private:
|
||||
uint32_t _currentMicLevel;
|
||||
uint32_t _newMicLevel;
|
||||
|
||||
bool _typingStatus;
|
||||
|
||||
uint32_t _playDelayMS;
|
||||
uint32_t _recDelayMS;
|
||||
|
||||
|
@ -62,6 +62,7 @@ public:
|
||||
const uint32_t totalDelayMS,
|
||||
const int32_t clockDrift,
|
||||
const uint32_t currentMicLevel,
|
||||
const bool keyPressed,
|
||||
uint32_t& newMicLevel) = 0;
|
||||
|
||||
virtual int32_t NeedMorePlayData(const uint32_t nSamples,
|
||||
|
@ -13,15 +13,17 @@
|
||||
#include "audio_device_config.h"
|
||||
|
||||
#include "event_wrapper.h"
|
||||
#include "portaudio/pa_ringbuffer.h"
|
||||
#include "trace.h"
|
||||
#include "thread_wrapper.h"
|
||||
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
#include <cassert>
|
||||
|
||||
#include <sys/sysctl.h> // sysctlbyname()
|
||||
#include <mach/mach.h> // mach_task_self()
|
||||
#include <libkern/OSAtomic.h> // OSAtomicCompareAndSwap()
|
||||
#include "portaudio/pa_ringbuffer.h"
|
||||
#include <mach/mach.h> // mach_task_self()
|
||||
#include <sys/sysctl.h> // sysctlbyname()
|
||||
|
||||
|
||||
|
||||
namespace webrtc
|
||||
{
|
||||
@ -3207,6 +3209,8 @@ bool AudioDeviceMac::CaptureWorkerThread()
|
||||
|
||||
_ptrAudioBuffer->SetVQEData(msecOnPlaySide, msecOnRecordSide, 0);
|
||||
|
||||
_ptrAudioBuffer->SetTypingStatus(KeyPressed());
|
||||
|
||||
// deliver recorded samples at specified sample rate, mic level etc.
|
||||
// to the observer using callback
|
||||
_ptrAudioBuffer->DeliverRecordedData();
|
||||
@ -3236,4 +3240,14 @@ bool AudioDeviceMac::CaptureWorkerThread()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AudioDeviceMac::KeyPressed() const{
|
||||
|
||||
bool key_down = false;
|
||||
// loop through all Mac virtual key constant values
|
||||
for (int key_index = 0; key_index <= 0x5C; key_index++) {
|
||||
key_down |= CGEventSourceKeyState(kCGEventSourceStateHIDSystemState,
|
||||
key_index);
|
||||
}
|
||||
return(key_down);
|
||||
}
|
||||
} // namespace webrtc
|
||||
|
@ -293,6 +293,9 @@ private:
|
||||
bool CaptureWorkerThread();
|
||||
bool RenderWorkerThread();
|
||||
|
||||
private:
|
||||
bool KeyPressed() const;
|
||||
|
||||
private:
|
||||
AudioDeviceBuffer* _ptrAudioBuffer;
|
||||
|
||||
|
@ -92,6 +92,7 @@ class AudioTransportAPI: public AudioTransport {
|
||||
const uint32_t totalDelay,
|
||||
const int32_t clockSkew,
|
||||
const uint32_t currentMicLevel,
|
||||
const bool keyPressed,
|
||||
uint32_t& newMicLevel) {
|
||||
rec_count_++;
|
||||
if (rec_count_ % 100 == 0) {
|
||||
|
@ -176,6 +176,7 @@ int32_t AudioTransportImpl::RecordedDataIsAvailable(
|
||||
const uint32_t totalDelayMS,
|
||||
const int32_t clockDrift,
|
||||
const uint32_t currentMicLevel,
|
||||
const bool keyPressed,
|
||||
uint32_t& newMicLevel)
|
||||
{
|
||||
if (_fullDuplex && _audioList.GetSize() < 15)
|
||||
|
@ -101,6 +101,7 @@ public:
|
||||
const uint32_t totalDelayMS,
|
||||
const int32_t clockDrift,
|
||||
const uint32_t currentMicLevel,
|
||||
const bool keyPressed,
|
||||
uint32_t& newMicLevel);
|
||||
|
||||
virtual int32_t NeedMorePlayData(const uint32_t nSamples,
|
||||
|
@ -4092,6 +4092,8 @@ DWORD AudioDeviceWindowsCore::DoCaptureThread()
|
||||
sndCardRecDelay,
|
||||
0);
|
||||
|
||||
_ptrAudioBuffer->SetTypingStatus(KeyPressed());
|
||||
|
||||
QueryPerformanceCounter(&t1); // measure time: START
|
||||
|
||||
_UnLock(); // release lock while making the callback
|
||||
@ -5145,6 +5147,16 @@ char* AudioDeviceWindowsCore::WideToUTF8(const TCHAR* src) const {
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
bool AudioDeviceWindowsCore::KeyPressed() const{
|
||||
|
||||
int key_down = 0;
|
||||
for (int key = VK_SPACE; key < VK_NUMLOCK; key++) {
|
||||
short res = GetAsyncKeyState(key);
|
||||
key_down |= res & 0x1; // Get the LSB
|
||||
}
|
||||
return (key_down > 0);
|
||||
}
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // WEBRTC_WINDOWS_CORE_AUDIO_BUILD
|
||||
|
@ -210,6 +210,9 @@ public:
|
||||
public:
|
||||
virtual void AttachAudioBuffer(AudioDeviceBuffer* audioBuffer);
|
||||
|
||||
private:
|
||||
bool KeyPressed() const;
|
||||
|
||||
private: // avrt function pointers
|
||||
PAvRevertMmThreadCharacteristics _PAvRevertMmThreadCharacteristics;
|
||||
PAvSetMmThreadCharacteristicsA _PAvSetMmThreadCharacteristicsA;
|
||||
|
@ -3359,6 +3359,8 @@ int32_t AudioDeviceWindowsWave::RecProc(LONGLONG& consumedTime)
|
||||
|
||||
_ptrAudioBuffer->SetVQEData(msecOnPlaySide, msecOnRecordSide, drift);
|
||||
|
||||
_ptrAudioBuffer->SetTypingStatus(KeyPressed());
|
||||
|
||||
// Store the play and rec delay values for video synchronization
|
||||
_sndCardPlayDelay = msecOnPlaySide;
|
||||
_sndCardRecDelay = msecOnRecordSide;
|
||||
@ -3820,5 +3822,15 @@ int32_t AudioDeviceWindowsWave::RestartTimerIfNeeded(const uint32_t time)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bool AudioDeviceWindowsWave::KeyPressed() const{
|
||||
|
||||
int key_down = 0;
|
||||
for (int key = VK_SPACE; key < VK_NUMLOCK; key++) {
|
||||
short res = GetAsyncKeyState(key);
|
||||
key_down |= res & 0x1; // Get the LSB
|
||||
}
|
||||
return (key_down > 0);
|
||||
}
|
||||
} // namespace webrtc
|
||||
|
||||
|
@ -177,6 +177,9 @@ private:
|
||||
inline int32_t InputSanityCheckAfterUnlockedPeriod() const;
|
||||
inline int32_t OutputSanityCheckAfterUnlockedPeriod() const;
|
||||
|
||||
private:
|
||||
bool KeyPressed() const;
|
||||
|
||||
private:
|
||||
int32_t EnumeratePlayoutDevices();
|
||||
int32_t EnumerateRecordingDevices();
|
||||
|
@ -54,12 +54,6 @@ class EventWrapper {
|
||||
|
||||
virtual bool StopTimer() = 0;
|
||||
|
||||
// Only implemented on Windows
|
||||
// Returns 1 if a key has been pressed since last call to this function.
|
||||
// -1 indicates failure
|
||||
// 0 indicates no key has been pressed since last call
|
||||
// TODO(hellner) this function does not seem to belong here
|
||||
static int KeyPressed();
|
||||
};
|
||||
} // namespace webrtc
|
||||
|
||||
|
@ -30,33 +30,4 @@ EventWrapper* EventWrapper::Create() {
|
||||
return EventPosix::Create();
|
||||
#endif
|
||||
}
|
||||
|
||||
int EventWrapper::KeyPressed() {
|
||||
#if defined(_WIN32)
|
||||
int key_down = 0;
|
||||
for (int key = 0x20; key < 0x90; key++) {
|
||||
short res = GetAsyncKeyState(key);
|
||||
key_down |= res % 2; // Get the LSB
|
||||
}
|
||||
if (key_down) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
#elif defined(WEBRTC_MAC) && !defined(WEBRTC_IOS)
|
||||
bool key_down = false;
|
||||
// loop through all Mac virtual key constant values
|
||||
for (int key_index = 0; key_index <= 0x5C; key_index++) {
|
||||
key_down |= CGEventSourceKeyState(kCGEventSourceStateHIDSystemState,
|
||||
key_index);
|
||||
}
|
||||
if (key_down) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
} // namespace webrtc
|
||||
|
@ -332,7 +332,8 @@ TransmitMixer::PrepareDemux(const void* audioSamples,
|
||||
const uint32_t samplesPerSec,
|
||||
const uint16_t totalDelayMS,
|
||||
const int32_t clockDrift,
|
||||
const uint16_t currentMicLevel)
|
||||
const uint16_t currentMicLevel,
|
||||
const bool keyPressed)
|
||||
{
|
||||
WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, -1),
|
||||
"TransmitMixer::PrepareDemux(nSamples=%u, nChannels=%u,"
|
||||
@ -369,7 +370,7 @@ TransmitMixer::PrepareDemux(const void* audioSamples,
|
||||
|
||||
// --- Annoying typing detection (utilizes the APM/VAD decision)
|
||||
#ifdef WEBRTC_VOICE_ENGINE_TYPING_DETECTION
|
||||
TypingDetection();
|
||||
TypingDetection(keyPressed);
|
||||
#endif
|
||||
|
||||
// --- Mute during DTMF tone if direct feedback is enabled
|
||||
@ -1327,7 +1328,7 @@ void TransmitMixer::ProcessAudio(int delay_ms, int clock_drift,
|
||||
}
|
||||
|
||||
#ifdef WEBRTC_VOICE_ENGINE_TYPING_DETECTION
|
||||
int TransmitMixer::TypingDetection()
|
||||
int TransmitMixer::TypingDetection(const bool keyPressed)
|
||||
{
|
||||
|
||||
// We let the VAD determine if we're using this feature or not.
|
||||
@ -1336,13 +1337,6 @@ int TransmitMixer::TypingDetection()
|
||||
return (0);
|
||||
}
|
||||
|
||||
int keyPressed = EventWrapper::KeyPressed();
|
||||
|
||||
if (keyPressed < 0)
|
||||
{
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (_audioFrame.vad_activity_ == AudioFrame::kVadActive)
|
||||
_timeActive++;
|
||||
else
|
||||
|
@ -56,7 +56,8 @@ public:
|
||||
const uint32_t samplesPerSec,
|
||||
const uint16_t totalDelayMS,
|
||||
const int32_t clockDrift,
|
||||
const uint16_t currentMicLevel);
|
||||
const uint16_t currentMicLevel,
|
||||
const bool keyPressed);
|
||||
|
||||
|
||||
int32_t DemuxAndMix();
|
||||
@ -178,7 +179,7 @@ private:
|
||||
void ProcessAudio(int delay_ms, int clock_drift, int current_mic_level);
|
||||
|
||||
#ifdef WEBRTC_VOICE_ENGINE_TYPING_DETECTION
|
||||
int TypingDetection();
|
||||
int TypingDetection(const bool keyPressed);
|
||||
#endif
|
||||
|
||||
// uses
|
||||
|
@ -133,6 +133,7 @@ int32_t VoEBaseImpl::RecordedDataIsAvailable(
|
||||
const uint32_t totalDelayMS,
|
||||
const int32_t clockDrift,
|
||||
const uint32_t currentMicLevel,
|
||||
const bool keyPressed,
|
||||
uint32_t& newMicLevel)
|
||||
{
|
||||
WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_shared->instance_id(), -1),
|
||||
@ -195,7 +196,7 @@ int32_t VoEBaseImpl::RecordedDataIsAvailable(
|
||||
// (APM, mix with file, record to file, mute, etc.)
|
||||
_shared->transmit_mixer()->PrepareDemux(audioSamples, nSamples, nChannels,
|
||||
samplesPerSec, static_cast<uint16_t>(totalDelayMS), clockDrift,
|
||||
currentVoEMicLevel);
|
||||
currentVoEMicLevel, keyPressed);
|
||||
|
||||
// Copy the audio frame to each sending channel and perform
|
||||
// channel-dependent operations (file mixing, mute, etc.) to prepare
|
||||
|
@ -80,6 +80,7 @@ public:
|
||||
const uint32_t totalDelayMS,
|
||||
const int32_t clockDrift,
|
||||
const uint32_t currentMicLevel,
|
||||
const bool keyPressed,
|
||||
uint32_t& newMicLevel);
|
||||
|
||||
virtual int32_t NeedMorePlayData(const uint32_t nSamples,
|
||||
|
@ -244,7 +244,8 @@ int VoEExternalMediaImpl::ExternalRecordingInsertData(
|
||||
samplingFreqHz,
|
||||
totalDelayMS,
|
||||
0,
|
||||
0);
|
||||
0,
|
||||
false); // Typing detection not supported
|
||||
|
||||
shared_->transmit_mixer()->DemuxAndMix();
|
||||
shared_->transmit_mixer()->EncodeAndSend();
|
||||
|
Loading…
Reference in New Issue
Block a user