diff options
author | Henri Herscher <henri@oreka.org> | 2005-10-20 13:40:58 +0000 |
---|---|---|
committer | Henri Herscher <henri@oreka.org> | 2005-10-20 13:40:58 +0000 |
commit | 7e1d63dd9fd149e4934bf77095c8610fac786b04 (patch) | |
tree | 5fe486a1b0300c3b84fb559107a868e5cc2c95da /orkaudio/CapturePort.cpp | |
parent | 467768fc956fc3e5a253373f26c71c681b31b6b8 (diff) |
First checkin
git-svn-id: https://oreka.svn.sourceforge.net/svnroot/oreka/trunk@2 09dcff7a-b715-0410-9601-b79a96267cd0
Diffstat (limited to 'orkaudio/CapturePort.cpp')
-rw-r--r-- | orkaudio/CapturePort.cpp | 248 |
1 files changed, 248 insertions, 0 deletions
diff --git a/orkaudio/CapturePort.cpp b/orkaudio/CapturePort.cpp new file mode 100644 index 0000000..52ca35c --- /dev/null +++ b/orkaudio/CapturePort.cpp @@ -0,0 +1,248 @@ +/* + * Oreka -- A media capture and retrieval platform + * + * Copyright (C) 2005, orecx LLC + * + * http://www.orecx.com + * + * This program is free software, distributed under the terms of + * the GNU General Public License. + * Please refer to http://www.gnu.org/copyleft/gpl.html + * + */ + +#define _WINSOCKAPI_ // prevents the inclusion of winsock.h + +#include "CapturePort.h" +#include "Utils.h" +#include "ImmediateProcessing.h" +#include "LogManager.h" +#include "Reporting.h" +#include "ConfigManager.h" + +CapturePort::CapturePort(CStdString& Id) +{ + m_Id = Id; + m_vadBelowThresholdSec = 0.0; + m_vadUp = false; + m_capturing = false; +} + +CStdString CapturePort::ToString() +{ + CStdString ret; + return ret; +} + +void CapturePort::AddAudioChunk(AudioChunkRef chunkRef, bool remote) +{ + time_t now = time(NULL); + + if(CONFIG.m_audioSegmentation) + { + if (m_audioTapeRef.get()) + { + if ((now - m_audioTapeRef->m_beginDate) >= CONFIG.m_audioSegmentDuration) + { + // signal current tape stop event + CaptureEventRef eventRef(new CaptureEvent); + eventRef->m_type = CaptureEvent::EtStop; + eventRef->m_timestamp = now; + AddCaptureEvent(eventRef); + + // create new tape + m_audioTapeRef.reset(new AudioTape(m_Id)); + + // signal new tape start event + eventRef.reset(new CaptureEvent); + eventRef->m_type = CaptureEvent::EtStart; + eventRef->m_timestamp = now; + AddCaptureEvent(eventRef); + } + } + else + { + // create new tape + m_audioTapeRef.reset(new AudioTape(m_Id)); + + // signal new tape start event + CaptureEventRef eventRef(new CaptureEvent); + eventRef->m_type = CaptureEvent::EtStart; + eventRef->m_timestamp = now; + AddCaptureEvent(eventRef); + } + } + else if (CONFIG.m_vad) + { + if(chunkRef->m_encoding == AudioChunk::PcmAudio) + { + if(m_vadUp) + { + // There is an ongoing capture + if (chunkRef->ComputeRmsDb() < CONFIG.m_vadLowThresholdDb) + { + // Level has gone below low threshold, increase holdon counter + m_vadBelowThresholdSec += chunkRef->GetDurationSec(); + } + else + { + // Level has gone above low threshold, reset holdon counter + m_vadBelowThresholdSec = 0.0; + } + + if (m_vadBelowThresholdSec > CONFIG.m_vadHoldOnSec) + { + // no activity detected for more than hold on time + m_vadUp = false; + + // signal current tape stop event + CaptureEventRef eventRef(new CaptureEvent); + eventRef->m_type = CaptureEvent::EtStop; + eventRef->m_timestamp = now; + AddCaptureEvent(eventRef); + } + } + else + { + // No capture is taking place yet + if (chunkRef->ComputeRmsDb() > CONFIG.m_vadHighThresholdDb) + { + // Voice detected, start a new capture + m_vadBelowThresholdSec = 0.0; + m_vadUp = true; + + // create new tape + m_audioTapeRef.reset(new AudioTape(m_Id)); + + // signal new tape start event + CaptureEventRef eventRef(new CaptureEvent); + eventRef->m_type = CaptureEvent::EtStart; + eventRef->m_timestamp = now; + AddCaptureEvent(eventRef); + } + } + } + else + { + LOG4CXX_ERROR(LOG.portLog, CStdString("Voice activity detection cannot be used on non PCM audio")); + } + } + + // ############ + //if (!m_audioTapeRef.get()) + //{ + // m_audioTapeRef.reset(new AudioTape(m_Id)); + // LOG4CXX_WARN(LOG.portLog, CStdString("Got impromptu audio")); + //} + + if (m_audioTapeRef.get() && m_capturing) + { + m_audioTapeRef->AddAudioChunk(chunkRef, remote); + + // Signal to immediate processing thread that tape has new stuff + ImmediateProcessing::GetInstance()->AddAudioTape(m_audioTapeRef); + } +} + +void CapturePort::AddCaptureEvent(CaptureEventRef eventRef) +{ + AudioTapeRef audioTapeRef = m_audioTapeRef; + + // First of all, handle tape start + if (eventRef->m_type == CaptureEvent::EtStart) + { + m_capturing = true; + if (audioTapeRef.get()) + { + audioTapeRef->SetShouldStop(); // force stop of previous tape + } + audioTapeRef.reset(new AudioTape(m_Id)); // Create a new tape + audioTapeRef->AddCaptureEvent(eventRef, true); + Reporting::GetInstance()->AddAudioTape(audioTapeRef); + m_audioTapeRef = audioTapeRef; + LOG4CXX_INFO(LOG.portLog, "#" + m_Id + ": start"); + } + + if (!audioTapeRef.get()) + { + LOG4CXX_WARN(LOG.portLog, "#" + m_Id + ": received unexpected capture event:" + + CaptureEvent::EventTypeToString(eventRef->m_type)); + } + else + { + // Ok, at this point, we know we have a valid audio tape + switch(eventRef->m_type) + { + case CaptureEvent::EtStop: + + m_capturing = false; + LOG4CXX_INFO(LOG.portLog, "#" + m_Id + ": stop"); + audioTapeRef->AddCaptureEvent(eventRef, true); + + if (m_audioTapeRef->GetAudioFileRef().get()) + { + // Notify immediate processing that tape has stopped + ImmediateProcessing::GetInstance()->AddAudioTape(m_audioTapeRef); + // Reporting needs to send a stop message + Reporting::GetInstance()->AddAudioTape(audioTapeRef); + } + else + { + // Received a stop but there is no valid audio file associated with the tape + LOG4CXX_WARN(LOG.portLog, "#" + m_Id + ": no audio reported between last start and stop"); + } + break; + case CaptureEvent::EtDirection: + case CaptureEvent::EtRemoteParty: + case CaptureEvent::EtLocalParty: + case CaptureEvent::EtLocalEntryPoint: + default: + audioTapeRef->AddCaptureEvent(eventRef, false); + } + } +} + + +//======================================= + +void CapturePorts::Initialize() +{ + m_ports.clear(); +} + +CapturePortRef CapturePorts::GetPort(CStdString & portId) +{ + std::map<CStdString, CapturePortRef>::iterator pair; + + pair = m_ports.find(portId); + + if (pair == m_ports.end()) + { + CapturePortRef nullPortRef; + return nullPortRef; + } + else + { + return pair->second; + } +} + +CapturePortRef CapturePorts::AddAndReturnPort(CStdString & portId) +{ + //MutexGuard mutexGuard(m_mutex); // To make sure a channel cannot be created twice + + CapturePortRef portRef = GetPort(portId); + if (portRef.get() == NULL) + { + // The port does not already exist, create it. + CapturePortRef newPortRef(new CapturePort(portId)); + m_ports.insert(std::make_pair(portId, newPortRef)); + return newPortRef; + } + else + { + return portRef; + } +} + + |