diff options
author | Christian Gmeiner <christian.gmeiner@gmail.com> | 2009-02-21 17:59:40 +0100 |
---|---|---|
committer | Christian Gmeiner <christian.gmeiner@gmail.com> | 2009-02-21 17:59:40 +0100 |
commit | 2d405ad8011283e20c50d63eb47741cd5dbcc5c7 (patch) | |
tree | 49c8559b39f48d8368d31784442ac4b2b6263dcf | |
parent | f686d1cc06b0f6251f882087820d685cff0c90be (diff) | |
download | vdr-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-- | Makefile | 2 | ||||
-rw-r--r-- | dxr3audio.c | 66 | ||||
-rw-r--r-- | dxr3audio.h | 41 | ||||
-rw-r--r-- | dxr3demuxdevice.c | 8 | ||||
-rw-r--r-- | dxr3demuxdevice.h | 10 | ||||
-rw-r--r-- | dxr3device.c | 25 | ||||
-rw-r--r-- | dxr3device.h | 5 | ||||
-rw-r--r-- | dxr3output-audio.c | 13 | ||||
-rw-r--r-- | dxr3output.h | 9 |
9 files changed, 162 insertions, 17 deletions
@@ -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); }; // ================================== |