summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Gmeiner <christian.gmeiner@gmail.com>2009-02-21 17:59:40 +0100
committerChristian Gmeiner <christian.gmeiner@gmail.com>2009-02-21 17:59:40 +0100
commit2d405ad8011283e20c50d63eb47741cd5dbcc5c7 (patch)
tree49c8559b39f48d8368d31784442ac4b2b6263dcf
parentf686d1cc06b0f6251f882087820d685cff0c90be (diff)
downloadvdr-plugin-dxr3-2d405ad8011283e20c50d63eb47741cd5dbcc5c7.tar.gz
vdr-plugin-dxr3-2d405ad8011283e20c50d63eb47741cd5dbcc5c7.tar.bz2
first work to get alsa audio output
Introduce a iAudio class - will be later base class for oss and alas output -, which handles volume and channel handling.
-rw-r--r--Makefile2
-rw-r--r--dxr3audio.c66
-rw-r--r--dxr3audio.h41
-rw-r--r--dxr3demuxdevice.c8
-rw-r--r--dxr3demuxdevice.h10
-rw-r--r--dxr3device.c25
-rw-r--r--dxr3device.h5
-rw-r--r--dxr3output-audio.c13
-rw-r--r--dxr3output.h9
9 files changed, 162 insertions, 17 deletions
diff --git a/Makefile b/Makefile
index 2b6ad3d..9d39760 100644
--- a/Makefile
+++ b/Makefile
@@ -68,7 +68,7 @@ DEFINES += -DUSE_XINE_SCALER
### The object files (add further files here):
OBJS = $(PLUGIN).o dxr3multichannelaudio.o dxr3sysclock.o dxr3colormanager.o \
- dxr3syncbuffer.o dxr3audiodecoder.o dxr3blackframe.o \
+ dxr3syncbuffer.o dxr3audiodecoder.o dxr3blackframe.o dxr3audio.o \
dxr3pesframe.o dxr3demuxdevice.o dxr3configdata.o dxr3ffmpeg.o \
dxr3interface_spu_encoder.o dxr3interface.o dxr3device.o \
dxr3output.o dxr3output-video.o dxr3output-audio.o dxr3osd.o dxr3spudecoder.o
diff --git a/dxr3audio.c b/dxr3audio.c
new file mode 100644
index 0000000..e2daa71
--- /dev/null
+++ b/dxr3audio.c
@@ -0,0 +1,66 @@
+/*
+ * dxr3audio.c
+ *
+ * Copyright (C) 2009 Christian Gmeiner
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include <string.h> // for memeset
+#include <math.h> // for pow
+#include <vdr/device.h> // for MAXVOLUME
+
+#include "dxr3audio.h"
+
+const static int AUDIO_STEREO = 0;
+const static int AUDIO_MONO_LEFT = 1;
+const static int AUDIO_MONO_RIGHT = 2;
+
+void iAudio::changeVolume(int16_t* pcmbuf, size_t size) {
+
+ if (vol == 0) {
+ memset(pcmbuf, 0, size);
+ } else if (vol < MAXVOLUME) {
+
+ int factor = (int)(pow(10.0, -2.5 + 2.5*vol/256.0)*0x7FFF);
+ size = size / 2;
+
+ while (size > 0) {
+ register int32_t tmp = (int32_t)(*pcmbuf) * factor;
+ *pcmbuf = (int16_t) (tmp>>15);
+ pcmbuf++;
+ size--;
+ }
+
+ // respect audio channel setting
+ if (audioChannel == AUDIO_STEREO)
+ return;
+
+ if (audioChannel == AUDIO_MONO_RIGHT) {
+
+ for (unsigned int i = 0; i < size / sizeof(short); i++) {
+ if (!(i & 0x1))
+ pcmbuf[i] = pcmbuf[i+1];
+ }
+ } else if (audioChannel == AUDIO_MONO_LEFT) {
+
+ for (unsigned int i = 0; i < size / sizeof(short); i++) {
+ if ((i & 0x1))
+ pcmbuf[i] = pcmbuf[i-1];
+ }
+ }
+ }
+}
diff --git a/dxr3audio.h b/dxr3audio.h
new file mode 100644
index 0000000..8ac071f
--- /dev/null
+++ b/dxr3audio.h
@@ -0,0 +1,41 @@
+/*
+ *
+ * Copyright (C) 2009 Christian Gmeiner
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef _AUDIO_H_
+#define _AUDIO_H_
+
+class iAudio {
+public:
+ iAudio() : vol(0), audioChannel(0) {}
+ virtual ~iAudio() {}
+
+ void setVolume(int v) { vol = v; }
+ void mute() { setVolume(0); }
+
+ void changeVolume(short* pcmbuf, size_t size);
+ void setAudioChannel(int channel) { audioChannel = channel; }
+ int getAudioChannel() { return audioChannel; }
+
+protected:
+ int vol;
+ int audioChannel;
+};
+
+#endif /*_AUDIO_H_*/
diff --git a/dxr3demuxdevice.c b/dxr3demuxdevice.c
index 16ea5af..b145827 100644
--- a/dxr3demuxdevice.c
+++ b/dxr3demuxdevice.c
@@ -43,7 +43,6 @@ cDxr3DemuxDevice::cDxr3DemuxDevice(cDxr3Interface& dxr3Device) :
esyslog("dxr3: fatal: unable to allocate memory for audio thread");
exit(1);
}
- m_pAudioThread->Start();
m_pVideoThread = new cDxr3VideoOutThread(dxr3Device, m_vBuf);
if (!m_pVideoThread)
@@ -55,6 +54,13 @@ cDxr3DemuxDevice::cDxr3DemuxDevice(cDxr3Interface& dxr3Device) :
m_aDecoder.Init();
}
+void cDxr3DemuxDevice::setAudio(iAudio *a)
+{
+ audioOut = a;
+ m_pAudioThread->setAudio(audioOut);
+ m_pAudioThread->Start();
+}
+
// ==================================
cDxr3DemuxDevice::cDxr3DemuxDevice() : // dummy constructor
m_dxr3Device(cDxr3Interface::Instance()),
diff --git a/dxr3demuxdevice.h b/dxr3demuxdevice.h
index 42c6b53..f1e874b 100644
--- a/dxr3demuxdevice.h
+++ b/dxr3demuxdevice.h
@@ -34,16 +34,18 @@ const int AUIDO_MAX_FRAME_SIZE = 5000;
const int VIDEO_MAX_FRAME_SIZE = 3000;
const uint32_t PRE_BUFFER_LENGTH = 0;
+class iAudio;
+
// ==================================
// extract video and audio
-class cDxr3DemuxDevice
-{
+class cDxr3DemuxDevice : private Uncopyable {
public:
cDxr3DemuxDevice();
cDxr3DemuxDevice(cDxr3Interface& dxr3Device);
~cDxr3DemuxDevice();
-public:
+ void setAudio(iAudio *a);
+
void Stop(void);
void Resync(void);
void Clear(void);
@@ -89,7 +91,7 @@ protected:
int m_ReUseFrame; // how often a frame should be used
private:
- cDxr3DemuxDevice(cDxr3DemuxDevice&); // no copy constructor
+ iAudio *audioOut;
};
#endif // __DXR3_DEMUX_DEVICE_H
diff --git a/dxr3device.c b/dxr3device.c
index 368ea15..edfbc9d 100644
--- a/dxr3device.c
+++ b/dxr3device.c
@@ -27,6 +27,7 @@
#include "dxr3interface.h"
#include "dxr3tools.h"
#include "dxr3osd.h"
+#include "dxr3audio.h"
// ==================================
//! constructor
@@ -36,15 +37,22 @@ cDxr3Device::cDxr3Device() : m_DemuxDevice(cDxr3Interface::Instance())
m_strBuf.erase(m_strBuf.begin(), m_strBuf.end());
m_spuDecoder = NULL;
m_CalledBySet = false;
+
+ // TODO: this will be later the place,
+ // where we will decide what kind of
+ // audio output system we will use.
+ audioOut = new iAudio();
+
+ m_DemuxDevice.setAudio(audioOut);
}
// ==================================
cDxr3Device::~cDxr3Device()
{
+ delete audioOut;
+
if (m_spuDecoder)
- {
- delete m_spuDecoder;
- }
+ delete m_spuDecoder;
}
// ==================================
@@ -264,7 +272,7 @@ int cDxr3Device::PlayAudio(const uchar *Data, int Length, uchar Id)
int origLength = Length;
bool isAc3 = ((Id & 0xF0) == 0x80) || Id == 0xbd;
-
+
if (isAc3 && !cDxr3Interface::Instance().IsAudioModeAC3())
cDxr3Interface::Instance().SetAudioDigitalAC3();
@@ -321,18 +329,19 @@ void cDxr3Device::SetVideoFormat(bool VideoFormat16_9)
//! sets volume for audio output
void cDxr3Device::SetVolumeDevice(int Volume)
{
- cDxr3Interface::Instance().SetVolume(Volume);
+ audioOut->setVolume(Volume);
}
// ==================================
//! sets audio channel for audio output (stereo, mono left, mono right)
void cDxr3Device::SetAudioChannelDevice(int AudioChannel)
{
- cDxr3Interface::Instance().SetAudioChannel(AudioChannel);
+ audioOut->setAudioChannel(AudioChannel);
}
-int cDxr3Device::GetAudioChannelDevice(void)
+
+int cDxr3Device::GetAudioChannelDevice()
{
- return cDxr3Interface::Instance().GetAudioChannel();
+ return audioOut->getAudioChannel();
}
// ==================================
diff --git a/dxr3device.h b/dxr3device.h
index 9b43161..4ea31d7 100644
--- a/dxr3device.h
+++ b/dxr3device.h
@@ -29,6 +29,8 @@
#include <string>
#include <vdr/device.h>
+class iAudio;
+
// ==================================
// our device :)
/*!
@@ -86,6 +88,9 @@ protected:
//uint8_t m_pBuffer[MAX_VIDEO_BUFFER_SIZE];
//cDxr3StartStopThread* m_pStartStopThread;
cDxr3SpuDecoder* m_spuDecoder;
+
+private:
+ iAudio *audioOut;
};
#endif /*_DXR3_DEVICE_H_*/
diff --git a/dxr3output-audio.c b/dxr3output-audio.c
index ca01ea3..f267003 100644
--- a/dxr3output-audio.c
+++ b/dxr3output-audio.c
@@ -22,6 +22,7 @@
#include <stdio.h>
#include <time.h>
#include "dxr3output.h"
+#include "dxr3audio.h"
// ==================================
const int AUDIO_OFFSET = 4500;
@@ -73,7 +74,7 @@ void cDxr3AudioOutThread::Action()
if (pts && (pts < SCR) && ((SCR - pts) > 5000))
{
m_dxr3Device.SetSysClock(pts + 1 * AUDIO_OFFSET);
- m_dxr3Device.PlayAudioFrame(pNext);
+ PlayFrame(pNext);
if (m_buffer.IsPolled())
{
m_buffer.Clear();
@@ -82,7 +83,7 @@ void cDxr3AudioOutThread::Action()
}
else
{
- m_dxr3Device.PlayAudioFrame(pNext);
+ PlayFrame(pNext);
m_buffer.Pop();
}
}
@@ -90,7 +91,7 @@ void cDxr3AudioOutThread::Action()
{
if (abs((int)pts - (int)SCR) < (AUDIO_OFFSET ))
{
- m_dxr3Device.PlayAudioFrame(pNext);
+ PlayFrame(pNext);
m_buffer.Pop();
}
}
@@ -103,6 +104,12 @@ void cDxr3AudioOutThread::Action()
}
}
+void cDxr3AudioOutThread::PlayFrame(cFixedLengthFrame *frame)
+{
+ audioOutput->changeVolume((short *)frame->GetData(), (size_t)frame->GetCount());
+ m_dxr3Device.PlayAudioFrame(frame);
+}
+
#undef SCR
// Local variables:
diff --git a/dxr3output.h b/dxr3output.h
index 9b8d408..6720bf1 100644
--- a/dxr3output.h
+++ b/dxr3output.h
@@ -26,6 +26,8 @@
#include "dxr3audiodecoder.h"
#include "Uncopyable.h"
+class iAudio;
+
// ==================================
class cDxr3OutputThread : public cThread, private Uncopyable {
public:
@@ -51,8 +53,15 @@ class cDxr3AudioOutThread : public cDxr3OutputThread {
public:
cDxr3AudioOutThread(cDxr3Interface& dxr3Device, cDxr3SyncBuffer& buffer);
+ void setAudio(iAudio *a) { audioOutput = a; }
+
protected:
void Action();
+
+private:
+ iAudio *audioOutput;
+
+ void PlayFrame(cFixedLengthFrame *frame);
};
// ==================================