diff options
-rw-r--r-- | orkaudio/Makefile.am | 2 | ||||
-rw-r--r-- | orkaudio/OrkAudio.cpp | 8 | ||||
-rw-r--r-- | orkbasecxx/BatchProcessing.cpp | 20 | ||||
-rw-r--r-- | orkbasecxx/Config.cpp | 6 | ||||
-rw-r--r-- | orkbasecxx/Config.h | 10 | ||||
-rw-r--r-- | orkbasecxx/Makefile.am | 4 | ||||
-rw-r--r-- | orkbasecxx/configure.in | 2 | ||||
-rw-r--r-- | orkbasecxx/filters/Makefile.am | 2 | ||||
-rw-r--r-- | orkbasecxx/filters/audiogain/AudioGain.cpp | 170 | ||||
-rw-r--r-- | orkbasecxx/filters/audiogain/AudioGain.h | 38 | ||||
-rw-r--r-- | orkbasecxx/filters/audiogain/Makefile.am | 6 |
11 files changed, 263 insertions, 5 deletions
diff --git a/orkaudio/Makefile.am b/orkaudio/Makefile.am index 86745cb..cd3ad52 100644 --- a/orkaudio/Makefile.am +++ b/orkaudio/Makefile.am @@ -8,7 +8,7 @@ orkaudio_LDADD = orkaudio_LDFLAGS = -lACE -lxerces-c -llog4cxx -lorkbase -lsndfile orkaudio_SOURCES = OrkAudio.cpp AM_CPPFLAGS = -D_REENTRANT -INCLUDES = -I@top_srcdir@ -I../orkbasecxx -I../orkbasecxx/filters/gsm -I../orkbasecxx/filters/gsm/gsm610 -I../orkbasecxx/filters/ilbc -I../orkbasecxx/filters/ilbc/ilbc +INCLUDES = -I@top_srcdir@ -I../orkbasecxx -I../orkbasecxx/filters/gsm -I../orkbasecxx/filters/gsm/gsm610 -I../orkbasecxx/filters/ilbc -I../orkbasecxx/filters/ilbc/ilbc -I../orkbasecxx/filters/audiogain SUBDIRS = audiocaptureplugins filters #orkaudio_LDADD = $(top_builddir)/messages/libmessages.la diff --git a/orkaudio/OrkAudio.cpp b/orkaudio/OrkAudio.cpp index bb02ea9..d12bd6d 100644 --- a/orkaudio/OrkAudio.cpp +++ b/orkaudio/OrkAudio.cpp @@ -41,6 +41,7 @@ #include "Filter.h" #include "GsmFilters.h" #include "IlbcFilters.h" +#include "AudioGain.h" #include "TapeProcessor.h" #include <list> @@ -101,6 +102,9 @@ void LoadPlugins(std::list<ACE_DLL>& pluginDlls) if(error) { LOG4CXX_ERROR(LOG.rootLog, CStdString("Failed to load plugin: ") + pluginPath); + CStdString logMsg; + logMsg.Format("DLL Error: %s", dlerror()); + LOG4CXX_ERROR(LOG.rootLog, logMsg); } else { @@ -145,6 +149,8 @@ void Transcode(CStdString &file) FilterRegistry::instance()->RegisterFilter(filter); filter.reset(new IlbcToPcmFilter()); FilterRegistry::instance()->RegisterFilter(filter); + filter.reset(new AudioGainFilter()); + FilterRegistry::instance()->RegisterFilter(filter); // Register in-built tape processors and build the processing chain BatchProcessing::Initialize(); @@ -226,6 +232,8 @@ void MainThread() FilterRegistry::instance()->RegisterFilter(filter); filter.reset(new IlbcToPcmFilter()); FilterRegistry::instance()->RegisterFilter(filter); + filter.reset(new AudioGainFilter()); + FilterRegistry::instance()->RegisterFilter(filter); // Register in-built tape processors and build the processing chain BatchProcessing::Initialize(); diff --git a/orkbasecxx/BatchProcessing.cpp b/orkbasecxx/BatchProcessing.cpp index 02c73df..e82a248 100644 --- a/orkbasecxx/BatchProcessing.cpp +++ b/orkbasecxx/BatchProcessing.cpp @@ -162,6 +162,7 @@ void BatchProcessing::ThreadHandler(void *args) FilterRef decoder1; FilterRef decoder2; FilterRef decoder; + FilterRef audiogain; std::bitset<RTP_PAYLOAD_TYPE_MAX> seenRtpPayloadTypes; std::vector<FilterRef> decoders1; @@ -181,6 +182,15 @@ void BatchProcessing::ThreadHandler(void *args) size_t numSamplesS2 = 0; size_t numSamplesOut = 0; + CStdString filterName("AudioGain"); + + audiogain = FilterRegistry::instance()->GetNewFilter(filterName); + if(audiogain.get() == NULL) + { + debug = "Could not instanciate AudioGain filter"; + throw(debug); + } + while(fileRef->ReadChunkMono(chunkRef)) { // ############ HACK @@ -190,6 +200,7 @@ void BatchProcessing::ThreadHandler(void *args) // ############ HACK AudioChunkDetails details = *chunkRef->GetDetails(); + decoder.reset(); if(details.m_rtpPayloadType < -1 || details.m_rtpPayloadType >= RTP_PAYLOAD_TYPE_MAX) @@ -280,6 +291,10 @@ void BatchProcessing::ThreadHandler(void *args) filter->AudioChunkIn(tmpChunkRef); filter->AudioChunkOut(tmpChunkRef); } + + audiogain->AudioChunkIn(tmpChunkRef); + audiogain->AudioChunkOut(tmpChunkRef); + outFileRef->WriteChunk(tmpChunkRef); if(tmpChunkRef.get()) { @@ -325,11 +340,16 @@ void BatchProcessing::ThreadHandler(void *args) filter->AudioChunkIn(stopChunk); filter->AudioChunkOut(tmpChunkRef); + audiogain->AudioChunkIn(tmpChunkRef); + audiogain->AudioChunkOut(tmpChunkRef); + while(tmpChunkRef.get()) { outFileRef->WriteChunk(tmpChunkRef); numSamplesOut += tmpChunkRef->GetNumSamples(); filter->AudioChunkOut(tmpChunkRef); + audiogain->AudioChunkIn(tmpChunkRef); + audiogain->AudioChunkOut(tmpChunkRef); } } diff --git a/orkbasecxx/Config.cpp b/orkbasecxx/Config.cpp index 08038f7..f3f5cb8 100644 --- a/orkbasecxx/Config.cpp +++ b/orkbasecxx/Config.cpp @@ -73,6 +73,9 @@ Config::Config() m_tapeDurationMinimumSec = TAPE_DURATION_MINIMUM_SEC_DEFAULT; m_transcodingSleepEveryNumFrames = TRANSCODING_SLEEP_EVERY_NUM_FRAMES_DEFAULT; m_transcodingSleepUs = TRANSCODING_SLEEP_US_DEFAULT; + m_audioGain = AUDIO_GAIN_DEFAULT; + m_audioGainChannel1 = AUDIO_GAIN_CHANNEL_1_DEFAULT; + m_audioGainChannel2 = AUDIO_GAIN_CHANNEL_2_DEFAULT; } void Config::Define(Serializer* s) @@ -150,6 +153,9 @@ void Config::Define(Serializer* s) s->IntValue(TAPE_DURATION_MINIMUM_SEC_PARAM, m_tapeDurationMinimumSec); s->IntValue(TRANSCODING_SLEEP_EVERY_NUM_FRAMES_PARAM, m_transcodingSleepEveryNumFrames); s->IntValue(TRANSCODING_SLEEP_US_PARAM, m_transcodingSleepUs); + s->DoubleValue(AUDIO_GAIN_PARAM, m_audioGain); + s->DoubleValue(AUDIO_GAIN_CHANNEL_1_PARAM, m_audioGainChannel1); + s->DoubleValue(AUDIO_GAIN_CHANNEL_2_PARAM, m_audioGainChannel2); } void Config::Validate() diff --git a/orkbasecxx/Config.h b/orkbasecxx/Config.h index 02fe025..8e7634c 100644 --- a/orkbasecxx/Config.h +++ b/orkbasecxx/Config.h @@ -114,7 +114,12 @@ #define TRANSCODING_SLEEP_EVERY_NUM_FRAMES_DEFAULT 0 #define TRANSCODING_SLEEP_US_PARAM "TranscodingSleepUs" #define TRANSCODING_SLEEP_US_DEFAULT 0 - +#define AUDIO_GAIN_PARAM "AudioGain" +#define AUDIO_GAIN_DEFAULT 0 +#define AUDIO_GAIN_CHANNEL_1_PARAM "AudioGainChannel1" +#define AUDIO_GAIN_CHANNEL_1_DEFAULT 0 +#define AUDIO_GAIN_CHANNEL_2_PARAM "AudioGainChannel2" +#define AUDIO_GAIN_CHANNEL_2_DEFAULT 0 class DLL_IMPORT_EXPORT_ORKBASE Config : public Object { @@ -179,6 +184,9 @@ public: int m_tapeDurationMinimumSec; int m_transcodingSleepEveryNumFrames; int m_transcodingSleepUs; + double m_audioGain; + double m_audioGainChannel1; + double m_audioGainChannel2; private: log4cxx::LoggerPtr m_log; diff --git a/orkbasecxx/Makefile.am b/orkbasecxx/Makefile.am index 3bcd0ad..3f30d49 100644 --- a/orkbasecxx/Makefile.am +++ b/orkbasecxx/Makefile.am @@ -24,6 +24,8 @@ liborkbase_la_LIBADD = $(top_builddir)/serializers/libserializers.la \ $(top_builddir)/filters/gsm/libgsm.la \ $(top_builddir)/filters/gsm/gsm610/libgsm610.la \ $(top_builddir)/filters/ilbc/libilbc.la \ - $(top_builddir)/filters/ilbc/ilbc/libilbcrfc.la + $(top_builddir)/filters/ilbc/ilbc/libilbcrfc.la \ + $(top_builddir)/filters/audiogain/libaudiogain.la \ + -lm AM_CXXFLAGS = -D_REENTRANT diff --git a/orkbasecxx/configure.in b/orkbasecxx/configure.in index 3628876..0289276 100644 --- a/orkbasecxx/configure.in +++ b/orkbasecxx/configure.in @@ -9,4 +9,4 @@ AC_LANG_CPLUSPLUS AC_PROG_CXX AM_PROG_LIBTOOL -AC_OUTPUT(Makefile messages/Makefile serializers/Makefile audiofile/Makefile filters/Makefile filters/gsm/Makefile filters/gsm/gsm610/Makefile filters/ilbc/Makefile filters/ilbc/ilbc/Makefile) +AC_OUTPUT(Makefile messages/Makefile serializers/Makefile audiofile/Makefile filters/Makefile filters/gsm/Makefile filters/gsm/gsm610/Makefile filters/ilbc/Makefile filters/ilbc/ilbc/Makefile filters/audiogain/Makefile) diff --git a/orkbasecxx/filters/Makefile.am b/orkbasecxx/filters/Makefile.am index 9de5d81..5bf40fd 100644 --- a/orkbasecxx/filters/Makefile.am +++ b/orkbasecxx/filters/Makefile.am @@ -1 +1 @@ -SUBDIRS = gsm ilbc +SUBDIRS = gsm ilbc audiogain diff --git a/orkbasecxx/filters/audiogain/AudioGain.cpp b/orkbasecxx/filters/audiogain/AudioGain.cpp new file mode 100644 index 0000000..59fec5d --- /dev/null +++ b/orkbasecxx/filters/audiogain/AudioGain.cpp @@ -0,0 +1,170 @@ +/*
+ * 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
+ *
+ */
+#pragma warning( disable: 4786 ) // disables truncated symbols in browse-info warning
+
+#define _WINSOCKAPI_ // prevents the inclusion of winsock.h
+
+#include "AudioGain.h"
+#include "ConfigManager.h"
+
+AudioGainFilter::AudioGainFilter()
+{
+ m_log = Logger::getLogger("audiogain");
+ m_numEncodingErrors = 0;
+ LOG4CXX_INFO(this->m_log, "Initialized AudioGain filter");
+}
+
+AudioGainFilter::~AudioGainFilter()
+{
+ if(m_numEncodingErrors > 0)
+ {
+ CStdString logMsg;
+ logMsg.Format("Encoding error happened %d time(s)", m_numEncodingErrors);
+ LOG4CXX_WARN(m_log, logMsg);
+ }
+ LOG4CXX_INFO(this->m_log, "Decommissioned AudioGain filter");
+}
+
+FilterRef AudioGainFilter::Instanciate()
+{
+ FilterRef Filter(new AudioGainFilter());
+ return Filter;
+}
+
+void AudioGainFilter::AudioChunkIn(AudioChunkRef& inputAudioChunk)
+{
+ int r_samples = 0;
+ int i = 0;
+ AudioChunkDetails outputDetails;
+
+ m_outputAudioChunk.reset();
+ if(inputAudioChunk.get() == NULL) {
+ return;
+ }
+
+ if(inputAudioChunk->GetNumSamples() == 0) {
+ return;
+ }
+
+ outputDetails = *inputAudioChunk->GetDetails();
+ r_samples = inputAudioChunk->GetNumSamples();
+ m_outputAudioChunk.reset(new AudioChunk());
+
+ if(inputAudioChunk->GetEncoding() != PcmAudio)
+ {
+ if(m_numEncodingErrors == 0)
+ {
+ CStdString logMsg;
+
+ logMsg.Format("Unexpected encoding:%d expected:%d (PcmAudio), gain not applied", inputAudioChunk->GetEncoding(), PcmAudio);
+ LOG4CXX_WARN(m_log, logMsg);
+ }
+ m_numEncodingErrors++;
+ m_outputAudioChunk->SetBuffer(inputAudioChunk->m_pBuffer, outputDetails);
+ return;
+ }
+
+ short* outputBuffer = (short*)m_outputAudioChunk->CreateBuffer(outputDetails);
+ short* inputBuffer = (short*)inputAudioChunk->m_pBuffer;
+ int sample = 0;
+
+ for(i = 0; i < r_samples; i++) {
+ sample = inputBuffer[i];
+ if(CONFIG.m_audioGain != 0)
+ {
+ if(CONFIG.m_audioGain < 0)
+ {
+ sample = (int)((double)sample / sqrt(fabs(CONFIG.m_audioGain)));
+ }
+ else
+ {
+ sample = (int)((double)sample * sqrt(fabs(CONFIG.m_audioGain)));
+ }
+ }
+ if(CONFIG.m_audioGainChannel1 != 0)
+ {
+ if(outputDetails.m_channel == 1)
+ {
+ if(CONFIG.m_audioGainChannel1 < 0)
+ {
+ sample = (int)((double)sample / sqrt(fabs(CONFIG.m_audioGainChannel1)));
+ }
+ else
+ {
+ sample = (int)((double)sample * sqrt(fabs(CONFIG.m_audioGainChannel1)));
+ }
+ }
+ }
+ if(CONFIG.m_audioGainChannel2 != 0)
+ {
+ if(outputDetails.m_channel == 2)
+ {
+ if(CONFIG.m_audioGainChannel2 < 0)
+ {
+ sample = (int)((double)sample / sqrt(fabs(CONFIG.m_audioGainChannel2)));
+ }
+ else
+ {
+ sample = (int)((double)sample / sqrt(fabs(CONFIG.m_audioGainChannel2)));
+ }
+ }
+ }
+
+ if(sample < -32768)
+ {
+ sample = -32768;
+ }
+ if(sample > 32768)
+ {
+ sample = 32768;
+ }
+
+ outputBuffer[i] = sample;
+ }
+}
+
+void AudioGainFilter::AudioChunkOut(AudioChunkRef& chunk)
+{
+ chunk = m_outputAudioChunk;
+}
+
+AudioEncodingEnum AudioGainFilter::GetInputAudioEncoding()
+{
+ return PcmAudio;
+}
+
+AudioEncodingEnum AudioGainFilter::GetOutputAudioEncoding()
+{
+ return PcmAudio;
+}
+
+CStdString AudioGainFilter::GetName()
+{
+ return "AudioGain";
+}
+
+int AudioGainFilter::GetInputRtpPayloadType()
+{
+ return -1;
+}
+
+void AudioGainFilter::CaptureEventIn(CaptureEventRef& event)
+{
+ ;
+}
+
+void AudioGainFilter::CaptureEventOut(CaptureEventRef& event)
+{
+ ;
+}
+
diff --git a/orkbasecxx/filters/audiogain/AudioGain.h b/orkbasecxx/filters/audiogain/AudioGain.h new file mode 100644 index 0000000..2ba39c7 --- /dev/null +++ b/orkbasecxx/filters/audiogain/AudioGain.h @@ -0,0 +1,38 @@ +/*
+ * 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
+ *
+ */
+#include "LogManager.h"
+#include "Filter.h"
+#include <math.h>
+
+class DLL_IMPORT_EXPORT_ORKBASE AudioGainFilter : public Filter
+{
+public:
+ AudioGainFilter();
+ ~AudioGainFilter();
+
+ FilterRef __CDECL__ Instanciate();
+ void __CDECL__ AudioChunkIn(AudioChunkRef& chunk);
+ void __CDECL__ AudioChunkOut(AudioChunkRef& chunk);
+ AudioEncodingEnum __CDECL__ GetInputAudioEncoding();
+ AudioEncodingEnum __CDECL__ GetOutputAudioEncoding();
+ CStdString __CDECL__ GetName();
+ int __CDECL__ GetInputRtpPayloadType();
+ inline void __CDECL__ CaptureEventIn(CaptureEventRef& event);
+ inline void __CDECL__ CaptureEventOut(CaptureEventRef& event);
+
+private:
+ AudioChunkRef m_outputAudioChunk;
+ LoggerPtr m_log;
+ int m_numEncodingErrors;
+};
+
diff --git a/orkbasecxx/filters/audiogain/Makefile.am b/orkbasecxx/filters/audiogain/Makefile.am new file mode 100644 index 0000000..2c377b5 --- /dev/null +++ b/orkbasecxx/filters/audiogain/Makefile.am @@ -0,0 +1,6 @@ +METASOURCES = AUTO +noinst_LTLIBRARIES = libaudiogain.la +libaudiogain_la_SOURCES = AudioGain.cpp + +INCLUDES = -I@top_srcdir@ +AM_CXXFLAGS = -D_REENTRANT |