summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGerald Begumisa <ben_g@users.sourceforge.net>2008-12-18 08:07:04 +0000
committerGerald Begumisa <ben_g@users.sourceforge.net>2008-12-18 08:07:04 +0000
commit3f5c1d9c9358eb6d7a1f2c75b49446303157fcd4 (patch)
tree8bce4fff04918d60ed8bed2669f9c21220556d80
parent960e134a00df44a2cb3eda87f2d7dcde9fb5156e (diff)
Added AudioGain filter that allows gain to be increased or reduced on all channels or a per-channel basis. Therefore 3 configuration parameters have been added, which are AudioGain, AudioGainChannel1 and AudioGainChannel2. These parameters take values in Db. Setting the AudioGain applies the gain to both channels. While setting AudioGainChannel1 and AudioGainChannel2 applies gain to channel 1 and channel 2 respectively.
git-svn-id: https://oreka.svn.sourceforge.net/svnroot/oreka/trunk@587 09dcff7a-b715-0410-9601-b79a96267cd0
-rw-r--r--orkaudio/Makefile.am2
-rw-r--r--orkaudio/OrkAudio.cpp8
-rw-r--r--orkbasecxx/BatchProcessing.cpp20
-rw-r--r--orkbasecxx/Config.cpp6
-rw-r--r--orkbasecxx/Config.h10
-rw-r--r--orkbasecxx/Makefile.am4
-rw-r--r--orkbasecxx/configure.in2
-rw-r--r--orkbasecxx/filters/Makefile.am2
-rw-r--r--orkbasecxx/filters/audiogain/AudioGain.cpp170
-rw-r--r--orkbasecxx/filters/audiogain/AudioGain.h38
-rw-r--r--orkbasecxx/filters/audiogain/Makefile.am6
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