all: clean up cAudio header, separate private stuff

This commit is contained in:
Stefan Seyfried
2013-11-02 20:06:29 +01:00
parent 69527185a9
commit 1166d49486
15 changed files with 366 additions and 594 deletions

View File

@@ -9,7 +9,7 @@
#include <proc_tools.h> #include <proc_tools.h>
#include "audio_lib.h" #include "audio_hal.h"
#include "lt_debug.h" #include "lt_debug.h"
#define AUDIO_DEVICE "/dev/dvb/adapter0/audio0" #define AUDIO_DEVICE "/dev/dvb/adapter0/audio0"
@@ -20,54 +20,55 @@
cAudio * audioDecoder = NULL; cAudio * audioDecoder = NULL;
typedef struct audio_pdata
{
int fd;
int clipfd;
int mixer_fd;
int mixer_num;
} audio_pdata;
#define P ((audio_pdata *)pdata)
cAudio::cAudio(void *, void *, void *) cAudio::cAudio(void *, void *, void *)
{ {
fd = -1; pdata = calloc(1, sizeof(audio_pdata));
clipfd = -1; P->clipfd = -1;
mixer_fd = -1; P->mixer_fd = -1;
openDevice(); P->fd = open(AUDIO_DEVICE, O_RDONLY|O_CLOEXEC);
Muted = false; if (P->fd < 0)
lt_info("%s: open failed (%m)\n", __func__);
muted = false;
} }
cAudio::~cAudio(void) cAudio::~cAudio(void)
{ {
closeDevice(); if (P->fd >= 0) {
} ioctl(P->fd, AUDIO_CONTINUE); /* enigma2 also does CONTINUE before close... */
close(P->fd);
void cAudio::openDevice(void) P->fd = -1;
{
lt_debug("%s\n", __func__);
if (fd < 0)
{
if ((fd = open(AUDIO_DEVICE, O_RDONLY|O_CLOEXEC)) < 0)
lt_info("openDevice: open failed (%m)\n");
do_mute(true, false);
} }
else if (P->clipfd >= 0)
lt_info("openDevice: already open (fd = %d)\n", fd); close(P->clipfd);
if (P->mixer_fd >= 0)
close(P->mixer_fd);
free(pdata);
} }
void cAudio::closeDevice(void) int cAudio::mute(void)
{ {
lt_debug("%s\n", __func__); return SetMute(true);
ioctl(fd, AUDIO_CONTINUE); /* enigma2 also does CONTINUE before close... */
if (fd >= 0)
close(fd);
fd = -1;
if (clipfd >= 0)
close(clipfd);
clipfd = -1;
if (mixer_fd >= 0)
close(mixer_fd);
mixer_fd = -1;
} }
int cAudio::do_mute(bool enable, bool remember) int cAudio::unmute(void)
{ {
lt_debug("%s(%d, %d)\n", __func__, enable, remember); return SetMute(false);
}
if (remember) int cAudio::SetMute(bool enable)
Muted = enable; {
lt_debug("%s(%d)\n", __func__, enable);
muted = enable;
#if 0 #if 0
/* does not work? */ /* does not work? */
if (ioctl(fd, AUDIO_SET_MUTE, enable) < 0 ) if (ioctl(fd, AUDIO_SET_MUTE, enable) < 0 )
@@ -96,14 +97,14 @@ int cAudio::setVolume(unsigned int left, unsigned int right)
lt_debug("%s(%d, %d)\n", __func__, left, right); lt_debug("%s(%d, %d)\n", __func__, left, right);
volume = (left + right) / 2; volume = (left + right) / 2;
if (clipfd != -1 && mixer_fd != -1) { if (P->clipfd != -1 && P->mixer_fd != -1) {
int tmp = 0; int tmp = 0;
/* not sure if left / right is correct here, but it is always the same anyways ;-) */ /* not sure if left / right is correct here, but it is always the same anyways ;-) */
if (! Muted) if (! muted)
tmp = left << 8 | right; tmp = left << 8 | right;
int ret = ioctl(mixer_fd, MIXER_WRITE(mixer_num), &tmp); int ret = ioctl(P->mixer_fd, MIXER_WRITE(P->mixer_num), &tmp);
if (ret == -1) if (ret == -1)
lt_info("%s: MIXER_WRITE(%d),%04x: %m\n", __func__, mixer_num, tmp); lt_info("%s: MIXER_WRITE(%d),%04x: %m\n", __func__, P->mixer_num, tmp);
return ret; return ret;
} }
@@ -111,7 +112,7 @@ int cAudio::setVolume(unsigned int left, unsigned int right)
mixer.volume_left = map_volume(left); mixer.volume_left = map_volume(left);
mixer.volume_right = map_volume(right); mixer.volume_right = map_volume(right);
if (ioctl(fd, AUDIO_SET_MIXER, &mixer) < 0) if (ioctl(P->fd, AUDIO_SET_MIXER, &mixer) < 0)
lt_info("%s: AUDIO_SET_MIXER failed (%m)\n", __func__); lt_info("%s: AUDIO_SET_MIXER failed (%m)\n", __func__);
return 0; return 0;
@@ -121,16 +122,16 @@ int cAudio::Start(void)
{ {
lt_debug("%s\n", __func__); lt_debug("%s\n", __func__);
int ret; int ret;
ioctl(fd, AUDIO_CONTINUE); ioctl(P->fd, AUDIO_CONTINUE);
ret = ioctl(fd, AUDIO_PLAY); ret = ioctl(P->fd, AUDIO_PLAY);
return ret; return ret;
} }
int cAudio::Stop(void) int cAudio::Stop(void)
{ {
lt_debug("%s\n", __func__); lt_debug("%s\n", __func__);
ioctl(fd, AUDIO_STOP); ioctl(P->fd, AUDIO_STOP);
ioctl(fd, AUDIO_CONTINUE); /* no idea why we have to stop and then continue => enigma2 does it, too */ ioctl(P->fd, AUDIO_CONTINUE); /* no idea why we have to stop and then continue => enigma2 does it, too */
return 0; return 0;
} }
@@ -142,7 +143,7 @@ bool cAudio::Pause(bool /*Pcm*/)
void cAudio::SetSyncMode(AVSYNC_TYPE Mode) void cAudio::SetSyncMode(AVSYNC_TYPE Mode)
{ {
lt_debug("%s %d\n", __func__, Mode); lt_debug("%s %d\n", __func__, Mode);
ioctl(fd, AUDIO_SET_AV_SYNC, Mode); ioctl(P->fd, AUDIO_SET_AV_SYNC, Mode);
}; };
//AUDIO_ENCODING_AC3 //AUDIO_ENCODING_AC3
@@ -158,7 +159,6 @@ void cAudio::SetStreamType(AUDIO_FORMAT type)
{ {
int bypass = AUDIO_STREAMTYPE_MPEG; int bypass = AUDIO_STREAMTYPE_MPEG;
lt_debug("%s %d\n", __func__, type); lt_debug("%s %d\n", __func__, type);
StreamType = type;
switch (type) switch (type)
{ {
@@ -175,7 +175,7 @@ void cAudio::SetStreamType(AUDIO_FORMAT type)
// Normaly the encoding should be set using AUDIO_SET_ENCODING // Normaly the encoding should be set using AUDIO_SET_ENCODING
// But as we implemented the behavior to bypass (cause of e2) this is correct here // But as we implemented the behavior to bypass (cause of e2) this is correct here
if (ioctl(fd, AUDIO_SET_BYPASS_MODE, bypass) < 0) if (ioctl(P->fd, AUDIO_SET_BYPASS_MODE, bypass) < 0)
lt_info("%s: AUDIO_SET_BYPASS_MODE failed (%m)\n", __func__); lt_info("%s: AUDIO_SET_BYPASS_MODE failed (%m)\n", __func__);
}; };
@@ -191,12 +191,12 @@ int cAudio::PrepareClipPlay(int ch, int srate, int bits, int little_endian)
const char *dsp_dev = getenv("DSP_DEVICE"); const char *dsp_dev = getenv("DSP_DEVICE");
const char *mix_dev = getenv("MIX_DEVICE"); const char *mix_dev = getenv("MIX_DEVICE");
lt_debug("%s ch %d srate %d bits %d le %d\n", __FUNCTION__, ch, srate, bits, little_endian); lt_debug("%s ch %d srate %d bits %d le %d\n", __FUNCTION__, ch, srate, bits, little_endian);
if (clipfd >= 0) { if (P->clipfd >= 0) {
lt_info("%s: clipfd already opened (%d)\n", __FUNCTION__, clipfd); lt_info("%s: clipfd already opened (%d)\n", __func__, P->clipfd);
return -1; return -1;
} }
mixer_num = -1; P->mixer_num = -1;
mixer_fd = -1; P->mixer_fd = -1;
/* a different DSP device can be given with DSP_DEVICE and MIX_DEVICE /* a different DSP device can be given with DSP_DEVICE and MIX_DEVICE
* if this device cannot be opened, we fall back to the internal OSS device * if this device cannot be opened, we fall back to the internal OSS device
* Example: * Example:
@@ -213,8 +213,8 @@ int cAudio::PrepareClipPlay(int ch, int srate, int bits, int little_endian)
} }
lt_info("%s: dsp_dev %s mix_dev %s\n", __func__, dsp_dev, mix_dev); /* NULL mix_dev is ok */ lt_info("%s: dsp_dev %s mix_dev %s\n", __func__, dsp_dev, mix_dev); /* NULL mix_dev is ok */
/* the tdoss dsp driver seems to work only on the second open(). really. */ /* the tdoss dsp driver seems to work only on the second open(). really. */
clipfd = open(dsp_dev, O_WRONLY|O_CLOEXEC); P->clipfd = open(dsp_dev, O_WRONLY|O_CLOEXEC);
if (clipfd < 0) { if (P->clipfd < 0) {
lt_info("%s open %s: %m\n", dsp_dev, __FUNCTION__); lt_info("%s open %s: %m\n", dsp_dev, __FUNCTION__);
return -1; return -1;
} }
@@ -223,29 +223,29 @@ int cAudio::PrepareClipPlay(int ch, int srate, int bits, int little_endian)
fmt = AFMT_S16_BE; fmt = AFMT_S16_BE;
else else
fmt = AFMT_S16_LE; fmt = AFMT_S16_LE;
if (ioctl(clipfd, SNDCTL_DSP_SETFMT, &fmt)) if (ioctl(P->clipfd, SNDCTL_DSP_SETFMT, &fmt))
perror("SNDCTL_DSP_SETFMT"); perror("SNDCTL_DSP_SETFMT");
if (ioctl(clipfd, SNDCTL_DSP_CHANNELS, &ch)) if (ioctl(P->clipfd, SNDCTL_DSP_CHANNELS, &ch))
perror("SNDCTL_DSP_CHANNELS"); perror("SNDCTL_DSP_CHANNELS");
if (ioctl(clipfd, SNDCTL_DSP_SPEED, &srate)) if (ioctl(P->clipfd, SNDCTL_DSP_SPEED, &srate))
perror("SNDCTL_DSP_SPEED"); perror("SNDCTL_DSP_SPEED");
if (ioctl(clipfd, SNDCTL_DSP_RESET)) if (ioctl(P->clipfd, SNDCTL_DSP_RESET))
perror("SNDCTL_DSP_RESET"); perror("SNDCTL_DSP_RESET");
if (!mix_dev) if (!mix_dev)
return 0; return 0;
mixer_fd = open(mix_dev, O_RDWR|O_CLOEXEC); P->mixer_fd = open(mix_dev, O_RDWR|O_CLOEXEC);
if (mixer_fd < 0) { if (P->mixer_fd < 0) {
lt_info("%s: open mixer %s failed (%m)\n", __func__, mix_dev); lt_info("%s: open mixer %s failed (%m)\n", __func__, mix_dev);
/* not a real error */ /* not a real error */
return 0; return 0;
} }
if (ioctl(mixer_fd, SOUND_MIXER_READ_DEVMASK, &devmask) == -1) { if (ioctl(P->mixer_fd, SOUND_MIXER_READ_DEVMASK, &devmask) == -1) {
lt_info("%s: SOUND_MIXER_READ_DEVMASK %m\n", __func__); lt_info("%s: SOUND_MIXER_READ_DEVMASK %m\n", __func__);
devmask = 0; devmask = 0;
} }
if (ioctl(mixer_fd, SOUND_MIXER_READ_STEREODEVS, &stereo) == -1) { if (ioctl(P->mixer_fd, SOUND_MIXER_READ_STEREODEVS, &stereo) == -1) {
lt_info("%s: SOUND_MIXER_READ_STEREODEVS %m\n", __func__); lt_info("%s: SOUND_MIXER_READ_STEREODEVS %m\n", __func__);
stereo = 0; stereo = 0;
} }
@@ -253,8 +253,8 @@ int cAudio::PrepareClipPlay(int ch, int srate, int bits, int little_endian)
if (usable == 0) { if (usable == 0) {
lt_info("%s: devmask: %08x stereo: %08x, no usable dev :-(\n", lt_info("%s: devmask: %08x stereo: %08x, no usable dev :-(\n",
__func__, devmask, stereo); __func__, devmask, stereo);
close(mixer_fd); close(P->mixer_fd);
mixer_fd = -1; P->mixer_fd = -1;
return 0; /* TODO: should we treat this as error? */ return 0; /* TODO: should we treat this as error? */
} }
/* __builtin_popcount needs GCC, it counts the set bits... */ /* __builtin_popcount needs GCC, it counts the set bits... */
@@ -265,14 +265,14 @@ int cAudio::PrepareClipPlay(int ch, int srate, int bits, int little_endian)
__func__, devmask, stereo, __func__); __func__, devmask, stereo, __func__);
const char *tmp = getenv("MIX_NUMBER"); const char *tmp = getenv("MIX_NUMBER");
if (tmp) if (tmp)
mixer_num = atoi(tmp); P->mixer_num = atoi(tmp);
lt_info("%s: mixer_num is %d -> device %08x\n", lt_info("%s: mixer_num is %d -> device %08x\n",
__func__, mixer_num, (mixer_num >= 0) ? (1 << mixer_num) : 0); __func__, P->mixer_num, (P->mixer_num >= 0) ? (1 << P->mixer_num) : 0);
/* no error checking, you'd better know what you are doing... */ /* no error checking, you'd better know what you are doing... */
} else { } else {
mixer_num = 0; P->mixer_num = 0;
while (!(usable & 0x01)) { while (!(usable & 0x01)) {
mixer_num++; P->mixer_num++;
usable >>= 1; usable >>= 1;
} }
} }
@@ -285,11 +285,11 @@ int cAudio::WriteClip(unsigned char *buffer, int size)
{ {
int ret; int ret;
// lt_debug("cAudio::%s\n", __FUNCTION__); // lt_debug("cAudio::%s\n", __FUNCTION__);
if (clipfd <= 0) { if (P->clipfd <= 0) {
lt_info("%s: clipfd not yet opened\n", __FUNCTION__); lt_info("%s: clipfd not yet opened\n", __FUNCTION__);
return -1; return -1;
} }
ret = write(clipfd, buffer, size); ret = write(P->clipfd, buffer, size);
if (ret < 0) if (ret < 0)
lt_info("%s: write error (%m)\n", __FUNCTION__); lt_info("%s: write error (%m)\n", __FUNCTION__);
return ret; return ret;
@@ -298,15 +298,15 @@ int cAudio::WriteClip(unsigned char *buffer, int size)
int cAudio::StopClip() int cAudio::StopClip()
{ {
lt_debug("%s\n", __FUNCTION__); lt_debug("%s\n", __FUNCTION__);
if (clipfd <= 0) { if (P->clipfd <= 0) {
lt_info("%s: clipfd not yet opened\n", __FUNCTION__); lt_info("%s: clipfd not yet opened\n", __FUNCTION__);
return -1; return -1;
} }
close(clipfd); close(P->clipfd);
clipfd = -1; P->clipfd = -1;
if (mixer_fd >= 0) if (P->mixer_fd >= 0)
close(mixer_fd); close(P->mixer_fd);
mixer_fd = -1; P->mixer_fd = -1;
setVolume(volume, volume); setVolume(volume, volume);
return 0; return 0;
}; };
@@ -370,10 +370,15 @@ void cAudio::SetHdmiDD(bool enable)
lt_debug("%s %d\n", __func__, enable); lt_debug("%s %d\n", __func__, enable);
}; };
#define AUDIO_BYPASS_ON 0
#define AUDIO_BYPASS_OFF 1
void cAudio::SetSpdifDD(bool enable) void cAudio::SetSpdifDD(bool enable)
{ {
lt_debug("%s %d\n", __func__, enable); lt_debug("%s %d\n", __func__, enable);
setBypassMode(!enable); //setBypassMode(!enable);
int mode = enable ? AUDIO_BYPASS_ON : AUDIO_BYPASS_OFF;
if (ioctl(P->fd, AUDIO_SET_BYPASS_MODE, mode) < 0)
lt_info("%s AUDIO_SET_BYPASS_MODE %d: %m\n", __func__, mode);
}; };
void cAudio::ScheduleMute(bool On) void cAudio::ScheduleMute(bool On)
@@ -386,8 +391,7 @@ void cAudio::EnableAnalogOut(bool enable)
lt_debug("%s %d\n", __FUNCTION__, enable); lt_debug("%s %d\n", __FUNCTION__, enable);
}; };
#define AUDIO_BYPASS_ON 0 #if 0
#define AUDIO_BYPASS_OFF 1
void cAudio::setBypassMode(bool disable) void cAudio::setBypassMode(bool disable)
{ {
lt_debug("%s %d\n", __func__, disable); lt_debug("%s %d\n", __func__, disable);
@@ -396,3 +400,4 @@ void cAudio::setBypassMode(bool disable)
lt_info("%s AUDIO_SET_BYPASS_MODE %d: %m\n", __func__, mode); lt_info("%s AUDIO_SET_BYPASS_MODE %d: %m\n", __func__, mode);
return; return;
} }
#endif

View File

@@ -1,98 +0,0 @@
/* public header file */
#ifndef _AUDIO_LIB_H_
#define _AUDIO_LIB_H_
#include <cs_types.h>
typedef enum
{
AUDIO_SYNC_WITH_PTS,
AUDIO_NO_SYNC,
AUDIO_SYNC_AUDIO_MASTER
} AUDIO_SYNC_MODE;
typedef enum {
HDMI_ENCODED_OFF,
HDMI_ENCODED_AUTO,
HDMI_ENCODED_FORCED
} HDMI_ENCODED_MODE;
typedef enum
{
AUDIO_FMT_AUTO = 0,
AUDIO_FMT_MPEG,
AUDIO_FMT_MP3,
AUDIO_FMT_DOLBY_DIGITAL,
AUDIO_FMT_BASIC = AUDIO_FMT_DOLBY_DIGITAL,
AUDIO_FMT_AAC,
AUDIO_FMT_AAC_PLUS,
AUDIO_FMT_DD_PLUS,
AUDIO_FMT_DTS,
AUDIO_FMT_AVS,
AUDIO_FMT_MLP,
AUDIO_FMT_WMA,
AUDIO_FMT_MPG1, // TD only. For Movieplayer / cPlayback
AUDIO_FMT_ADVANCED = AUDIO_FMT_MLP
} AUDIO_FORMAT;
class cAudio
{
friend class cPlayback;
private:
int fd;
bool Muted;
int clipfd; /* for pcm playback */
int mixer_fd; /* if we are using the OSS mixer */
int mixer_num; /* oss mixer to use, if any */
AUDIO_FORMAT StreamType;
AUDIO_SYNC_MODE SyncMode;
bool started;
int volume;
void openDevice(void);
void closeDevice(void);
int do_mute(bool enable, bool remember);
void setBypassMode(bool disable);
public:
/* construct & destruct */
cAudio(void *, void *, void *);
~cAudio(void);
void *GetHandle() { return NULL; };
/* shut up */
int mute(bool remember = true) { return do_mute(true, remember); };
int unmute(bool remember = true) { return do_mute(false, remember); };
/* volume, min = 0, max = 255 */
int setVolume(unsigned int left, unsigned int right);
int getVolume(void) { return volume;}
bool getMuteStatus(void) { return Muted; };
/* start and stop audio */
int Start(void);
int Stop(void);
bool Pause(bool Pcm = true);
void SetStreamType(AUDIO_FORMAT type);
void SetSyncMode(AVSYNC_TYPE Mode);
/* select channels */
int setChannel(int channel);
int PrepareClipPlay(int uNoOfChannels, int uSampleRate, int uBitsPerSample, int bLittleEndian);
int WriteClip(unsigned char * buffer, int size);
int StopClip();
void getAudioInfo(int &type, int &layer, int& freq, int &bitrate, int &mode);
void SetSRS(int iq_enable, int nmgr_enable, int iq_mode, int iq_level);
bool IsHdmiDDSupported();
void SetHdmiDD(bool enable);
void SetSpdifDD(bool enable);
void ScheduleMute(bool On);
void EnableAnalogOut(bool enable);
};
#endif

View File

@@ -22,7 +22,7 @@
#include <cstdio> #include <cstdio>
#include <cstdlib> #include <cstdlib>
#include "audio_lib.h" #include "audio_hal.h"
#include "audio_priv.h" #include "audio_priv.h"
#include "dmx_hal.h" #include "dmx_hal.h"
#include "lt_debug.h" #include "lt_debug.h"

View File

@@ -1,7 +1,22 @@
/* public header file */ /*
* (C) 2010-2013 Stefan Seyfried
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 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 General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _AUDIO_LIB_H_ #ifndef __audio_hal__
#define _AUDIO_LIB_H_ #define __audio_hal__
#include <stdint.h> #include <stdint.h>
#include <cs_types.h> #include <cs_types.h>

View File

@@ -1,16 +1 @@
#include <config.h> #include "audio_hal.h"
#if HAVE_TRIPLEDRAGON
#include "../libtriple/audio_td.h"
#elif HAVE_SPARK_HARDWARE
#include "../libspark/audio_lib.h"
#elif HAVE_AZBOX_HARDWARE
#include "../azbox/audio_lib.h"
#elif HAVE_GENERIC_HARDWARE
#if BOXMODEL_RASPI
#include "../raspi/audio_lib.h"
#else
#include "../generic-pc/audio_lib.h"
#endif
#else
#error neither HAVE_TRIPLEDRAGON nor HAVE_SPARK_HARDWARE defined
#endif

View File

@@ -6,7 +6,8 @@
#include <unistd.h> #include <unistd.h>
#include <linux/dvb/audio.h> #include <linux/dvb/audio.h>
#include "audio_lib.h" #include "audio_hal.h"
#include "audio_priv.h"
#include "lt_debug.h" #include "lt_debug.h"
#define AUDIO_DEVICE "/dev/dvb/adapter0/audio0" #define AUDIO_DEVICE "/dev/dvb/adapter0/audio0"
@@ -16,6 +17,7 @@
#include <linux/soundcard.h> #include <linux/soundcard.h>
cAudio * audioDecoder = NULL; cAudio * audioDecoder = NULL;
ADec *adec = NULL;
static int proc_put(const char *path, const char *value, const int len) static int proc_put(const char *path, const char *value, const int len)
{ {
@@ -32,32 +34,41 @@ static int proc_put(const char *path, const char *value, const int len)
cAudio::cAudio(void *, void *, void *) cAudio::cAudio(void *, void *, void *)
{ {
fd = -1; adec = new ADec();
clipfd = -1;
mixer_fd = -1;
openDevice();
Muted = false;
} }
cAudio::~cAudio(void) cAudio::~cAudio(void)
{
delete adec;
}
ADec::ADec(void)
{
fd = -1;
clipfd = -1;
mixer_fd = -1;
openDevice();
muted = false;
}
ADec::~ADec(void)
{ {
closeDevice(); closeDevice();
} }
void cAudio::openDevice(void) void ADec::openDevice(void)
{ {
if (fd < 0) if (fd < 0)
{ {
if ((fd = open(AUDIO_DEVICE, O_RDWR)) < 0) if ((fd = open(AUDIO_DEVICE, O_RDWR|O_CLOEXEC)) < 0)
lt_info("openDevice: open failed (%m)\n"); lt_info("openDevice: open failed (%m)\n");
fcntl(fd, F_SETFD, FD_CLOEXEC); //SetMute(true);
do_mute(true, false);
} }
else else
lt_info("openDevice: already open (fd = %d)\n", fd); lt_info("openDevice: already open (fd = %d)\n", fd);
} }
void cAudio::closeDevice(void) void ADec::closeDevice(void)
{ {
if (fd >= 0) if (fd >= 0)
close(fd); close(fd);
@@ -70,15 +81,30 @@ void cAudio::closeDevice(void)
mixer_fd = -1; mixer_fd = -1;
} }
int cAudio::do_mute(bool enable, bool remember) int cAudio::mute(void)
{ {
lt_debug("%s(%d, %d)\n", __FUNCTION__, enable, remember); return SetMute(true);
}
int cAudio::unmute(void)
{
return SetMute(false);
}
int cAudio::SetMute(bool enable)
{
return adec->SetMute(enable);
}
int ADec::SetMute(bool enable, bool remember)
{
lt_debug("%s(%d)\n", __func__, enable);
char str[4]; char str[4];
if (remember) if (remember)
Muted = enable; muted = enable;
sprintf(str, "%d", Muted); sprintf(str, "%d", muted);
proc_put("/proc/stb/audio/j1_mute", str, strlen(str)); proc_put("/proc/stb/audio/j1_mute", str, strlen(str));
if (!enable) if (!enable)
@@ -102,8 +128,12 @@ int map_volume(const int volume)
return vol; return vol;
} }
int cAudio::setVolume(unsigned int left, unsigned int right) int cAudio::setVolume(unsigned int left, unsigned int right)
{
return adec->setVolume(left, right);
}
int ADec::setVolume(unsigned int left, unsigned int right)
{ {
lt_debug("%s(%d, %d)\n", __func__, left, right); lt_debug("%s(%d, %d)\n", __func__, left, right);
@@ -112,7 +142,7 @@ int cAudio::setVolume(unsigned int left, unsigned int right)
if (clipfd != -1 && mixer_fd != -1) { if (clipfd != -1 && mixer_fd != -1) {
int tmp = 0; int tmp = 0;
/* not sure if left / right is correct here, but it is always the same anyways ;-) */ /* not sure if left / right is correct here, but it is always the same anyways ;-) */
if (! Muted) if (! muted)
tmp = left << 8 | right; tmp = left << 8 | right;
int ret = ioctl(mixer_fd, MIXER_WRITE(mixer_num), &tmp); int ret = ioctl(mixer_fd, MIXER_WRITE(mixer_num), &tmp);
if (ret == -1) if (ret == -1)
@@ -134,14 +164,12 @@ int cAudio::setVolume(unsigned int left, unsigned int right)
int cAudio::Start(void) int cAudio::Start(void)
{ {
int ret; return adec->Start();
ret = ioctl(fd, AUDIO_PLAY);
return ret;
} }
int cAudio::Stop(void) int cAudio::Stop(void)
{ {
return ioctl(fd, AUDIO_STOP); return adec->Stop();
} }
bool cAudio::Pause(bool /*Pcm*/) bool cAudio::Pause(bool /*Pcm*/)
@@ -150,6 +178,21 @@ bool cAudio::Pause(bool /*Pcm*/)
}; };
void cAudio::SetSyncMode(AVSYNC_TYPE Mode) void cAudio::SetSyncMode(AVSYNC_TYPE Mode)
{
adec->SetSyncMode(Mode);
}
int ADec::Start(void)
{
return ioctl(fd, AUDIO_PLAY);
}
int ADec::Stop(void)
{
return ioctl(fd, AUDIO_STOP);
}
void ADec::SetSyncMode(AVSYNC_TYPE Mode)
{ {
lt_debug("%s %d\n", __func__, Mode); lt_debug("%s %d\n", __func__, Mode);
ioctl(fd, AUDIO_SET_AV_SYNC, Mode); ioctl(fd, AUDIO_SET_AV_SYNC, Mode);
@@ -165,6 +208,11 @@ void cAudio::SetSyncMode(AVSYNC_TYPE Mode)
#define AUDIO_ENCODING_LPCM 2 #define AUDIO_ENCODING_LPCM 2
#define AUDIO_ENCODING_LPCMA 11 #define AUDIO_ENCODING_LPCMA 11
void cAudio::SetStreamType(AUDIO_FORMAT type) void cAudio::SetStreamType(AUDIO_FORMAT type)
{
adec->SetStreamType(type);
}
void ADec::SetStreamType(AUDIO_FORMAT type)
{ {
int bypass = AUDIO_STREAMTYPE_MPEG; int bypass = AUDIO_STREAMTYPE_MPEG;
bool update_volume = (StreamType != type); bool update_volume = (StreamType != type);
@@ -199,6 +247,11 @@ int cAudio::setChannel(int channel)
}; };
int cAudio::PrepareClipPlay(int ch, int srate, int bits, int little_endian) int cAudio::PrepareClipPlay(int ch, int srate, int bits, int little_endian)
{
return adec->PrepareClipPlay(ch, srate, bits, little_endian);
}
int ADec::PrepareClipPlay(int ch, int srate, int bits, int little_endian)
{ {
int fmt; int fmt;
unsigned int devmask, stereo, usable; unsigned int devmask, stereo, usable;
@@ -297,6 +350,11 @@ int cAudio::PrepareClipPlay(int ch, int srate, int bits, int little_endian)
}; };
int cAudio::WriteClip(unsigned char *buffer, int size) int cAudio::WriteClip(unsigned char *buffer, int size)
{
return adec->WriteClip(buffer, size);
}
int ADec::WriteClip(unsigned char *buffer, int size)
{ {
int ret; int ret;
// lt_debug("cAudio::%s\n", __FUNCTION__); // lt_debug("cAudio::%s\n", __FUNCTION__);
@@ -311,6 +369,11 @@ int cAudio::WriteClip(unsigned char *buffer, int size)
}; };
int cAudio::StopClip() int cAudio::StopClip()
{
return adec->StopClip();
}
int ADec::StopClip()
{ {
lt_debug("%s\n", __FUNCTION__); lt_debug("%s\n", __FUNCTION__);
if (clipfd <= 0) { if (clipfd <= 0) {
@@ -390,7 +453,7 @@ void cAudio::SetHdmiDD(bool enable)
void cAudio::SetSpdifDD(bool enable) void cAudio::SetSpdifDD(bool enable)
{ {
lt_debug("%s %d\n", __func__, enable); lt_debug("%s %d\n", __func__, enable);
setBypassMode(!enable); adec->setBypassMode(!enable);
}; };
void cAudio::ScheduleMute(bool On) void cAudio::ScheduleMute(bool On)
@@ -405,7 +468,7 @@ void cAudio::EnableAnalogOut(bool enable)
#define AUDIO_BYPASS_ON 0 #define AUDIO_BYPASS_ON 0
#define AUDIO_BYPASS_OFF 1 #define AUDIO_BYPASS_OFF 1
void cAudio::setBypassMode(bool disable) void ADec::setBypassMode(bool disable)
{ {
const char *opt[] = { "passthrough", "downmix" }; const char *opt[] = { "passthrough", "downmix" };
lt_debug("%s %d\n", __func__, disable); lt_debug("%s %d\n", __func__, disable);

View File

@@ -1,97 +0,0 @@
/* public header file */
#ifndef _AUDIO_TD_H_
#define _AUDIO_TD_H_
#include <cs_types.h>
typedef enum
{
AUDIO_SYNC_WITH_PTS,
AUDIO_NO_SYNC,
AUDIO_SYNC_AUDIO_MASTER
} AUDIO_SYNC_MODE;
typedef enum {
HDMI_ENCODED_OFF,
HDMI_ENCODED_AUTO,
HDMI_ENCODED_FORCED
} HDMI_ENCODED_MODE;
typedef enum
{
AUDIO_FMT_AUTO = 0,
AUDIO_FMT_MPEG,
AUDIO_FMT_MP3,
AUDIO_FMT_DOLBY_DIGITAL,
AUDIO_FMT_BASIC = AUDIO_FMT_DOLBY_DIGITAL,
AUDIO_FMT_AAC,
AUDIO_FMT_AAC_PLUS,
AUDIO_FMT_DD_PLUS,
AUDIO_FMT_DTS,
AUDIO_FMT_AVS,
AUDIO_FMT_MLP,
AUDIO_FMT_WMA,
AUDIO_FMT_MPG1, // TD only. For Movieplayer / cPlayback
AUDIO_FMT_ADVANCED = AUDIO_FMT_MLP
} AUDIO_FORMAT;
class cAudio
{
friend class cPlayback;
private:
int fd;
bool Muted;
int clipfd; /* for pcm playback */
int mixer_fd; /* if we are using the OSS mixer */
int mixer_num; /* oss mixer to use, if any */
AUDIO_FORMAT StreamType;
AUDIO_SYNC_MODE SyncMode;
bool started;
int volume;
void openDevice(void);
void closeDevice(void);
int do_mute(bool enable, bool remember);
void setBypassMode(bool disable);
public:
/* construct & destruct */
cAudio(void *, void *, void *);
~cAudio(void);
void *GetHandle() { return NULL; };
/* shut up */
int mute(bool remember = true) { return do_mute(true, remember); };
int unmute(bool remember = true) { return do_mute(false, remember); };
/* volume, min = 0, max = 255 */
int setVolume(unsigned int left, unsigned int right);
int getVolume(void) { return volume;}
bool getMuteStatus(void) { return Muted; };
/* start and stop audio */
int Start(void);
int Stop(void);
bool Pause(bool Pcm = true);
void SetStreamType(AUDIO_FORMAT type);
void SetSyncMode(AVSYNC_TYPE Mode);
/* select channels */
int setChannel(int channel);
int PrepareClipPlay(int uNoOfChannels, int uSampleRate, int uBitsPerSample, int bLittleEndian);
int WriteClip(unsigned char * buffer, int size);
int StopClip();
void getAudioInfo(int &type, int &layer, int& freq, int &bitrate, int &mode);
void SetSRS(int iq_enable, int nmgr_enable, int iq_mode, int iq_level);
bool IsHdmiDDSupported() { return true; };
void SetHdmiDD(bool enable);
void SetSpdifDD(bool enable);
void ScheduleMute(bool On);
void EnableAnalogOut(bool enable);
};
#endif

62
libspark/audio_priv.h Normal file
View File

@@ -0,0 +1,62 @@
/*
* (C) 2010-2013 Stefan Seyfried
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 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 General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* private audio stuff, to be used inside libstb-hal only
*/
#ifndef __audio_priv__
#define __audio_priv__
#include <audio_hal.h>
class ADec
{
public:
/* construct & destruct */
ADec(void);
~ADec(void);
int SetMute(bool enable, bool remember = true);
/* volume, min = 0, max = 255 */
int setVolume(unsigned int left, unsigned int right);
/* start and stop audio */
int Start(void);
int Stop(void);
void SetStreamType(AUDIO_FORMAT type);
void SetSyncMode(AVSYNC_TYPE Mode);
/* select channels */
int PrepareClipPlay(int uNoOfChannels, int uSampleRate, int uBitsPerSample, int bLittleEndian);
int WriteClip(unsigned char * buffer, int size);
int StopClip();
void setBypassMode(bool disable);
void openDevice();
void closeDevice();
/* variables */
int fd;
int clipfd; /* for pcm playback */
int mixer_fd; /* if we are using the OSS mixer */
int mixer_num; /* oss mixer to use, if any */
AUDIO_FORMAT StreamType;
bool started;
int volume;
bool muted;
};
#endif

View File

@@ -10,7 +10,7 @@
#include <cstring> #include <cstring>
#include "playback_lib.h" #include "playback_lib.h"
#include "dmx_hal.h" #include "dmx_hal.h"
#include "audio_lib.h" #include "audio_hal.h"
#include "video_lib.h" #include "video_lib.h"
#include "lt_debug.h" #include "lt_debug.h"
#define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_PLAYBACK, this, args) #define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_PLAYBACK, this, args)

View File

@@ -3,7 +3,7 @@
#include <string.h> #include <string.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <audio_lib.h> #include <audio_priv.h>
#include <video_priv.h> #include <video_priv.h>
#include <common.h> #include <common.h>
@@ -16,7 +16,7 @@ extern ManagerHandler_t ManagerHandler;
static Context_t *player; static Context_t *player;
extern cAudio *audioDecoder; extern ADec *adec;
extern cVideo *videoDecoder; extern cVideo *videoDecoder;
static bool decoders_closed = false; static bool decoders_closed = false;
@@ -37,7 +37,7 @@ bool cPlayback::Open(playmode_t PlayMode)
if (PlayMode != PLAYMODE_TS) if (PlayMode != PLAYMODE_TS)
{ {
audioDecoder->closeDevice(); adec->closeDevice();
videoDecoder->vdec->closeDevice(); videoDecoder->vdec->closeDevice();
decoders_closed = true; decoders_closed = true;
} }
@@ -80,7 +80,7 @@ void cPlayback::Close(void)
Stop(); Stop();
if (decoders_closed) if (decoders_closed)
{ {
audioDecoder->openDevice(); adec->openDevice();
videoDecoder->vdec->openDevice(); videoDecoder->vdec->openDevice();
decoders_closed = false; decoders_closed = false;
} }
@@ -201,7 +201,7 @@ bool cPlayback::Start(char *filename, unsigned short vpid, int vtype, unsigned s
{ {
ret = true; ret = true;
videoDecoder->vdec->Stop(false); videoDecoder->vdec->Stop(false);
audioDecoder->Stop(); adec->Stop();
} }
} }
return ret; return ret;
@@ -253,7 +253,7 @@ bool cPlayback::SetSpeed(int speed)
if (! decoders_closed) if (! decoders_closed)
{ {
audioDecoder->closeDevice(); adec->closeDevice();
videoDecoder->vdec->closeDevice(); videoDecoder->vdec->closeDevice();
decoders_closed = true; decoders_closed = true;
usleep(500000); usleep(500000);

View File

@@ -4,7 +4,7 @@
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <unistd.h> #include <unistd.h>
#include <hardware/aud/aud_inf.h>
#include <hardware/tddevices.h> #include <hardware/tddevices.h>
#include <avs/avs_inf.h> #include <avs/avs_inf.h>
#define AUDIO_DEVICE "/dev/" DEVICE_NAME_AUDIO #define AUDIO_DEVICE "/dev/" DEVICE_NAME_AUDIO
@@ -17,60 +17,63 @@
cAudio * audioDecoder = NULL; cAudio * audioDecoder = NULL;
typedef struct audio_pdata
{
int fd;
int clipfd;
int mixer_fd;
int mixer_num;
} audio_pdata;
#define P ((audio_pdata *)pdata)
cAudio::cAudio(void *, void *, void *) cAudio::cAudio(void *, void *, void *)
{ {
fd = -1; pdata = calloc(1, sizeof(audio_pdata));
clipfd = -1; P->clipfd = -1;
mixer_fd = -1; P->mixer_fd = -1;
openDevice(); int fd = open(AUDIO_DEVICE, O_RDWR);
Muted = false; if (fd < 0)
lt_info("%s: open failed (%m)\n", __func__);
fcntl(fd, F_SETFD, FD_CLOEXEC);
P->fd = fd;
SetMute(true);
muted = false;
} }
cAudio::~cAudio(void) cAudio::~cAudio(void)
{ {
closeDevice(); if (P->fd >= 0)
close(P->fd);
if (P->clipfd >= 0)
close(P->clipfd);
if (P->mixer_fd >= 0)
close(P->mixer_fd);
free(pdata);
} }
void cAudio::openDevice(void) int cAudio::mute(void)
{ {
if (fd < 0) return SetMute(true);
{
if ((fd = open(AUDIO_DEVICE, O_RDWR)) < 0)
lt_info("openDevice: open failed (%m)\n");
fcntl(fd, F_SETFD, FD_CLOEXEC);
do_mute(true, false);
}
else
lt_info("openDevice: already open (fd = %d)\n", fd);
} }
void cAudio::closeDevice(void) int cAudio::unmute(void)
{ {
if (fd >= 0) return SetMute(false);
close(fd);
fd = -1;
if (clipfd >= 0)
close(clipfd);
clipfd = -1;
if (mixer_fd >= 0)
close(mixer_fd);
mixer_fd = -1;
} }
int cAudio::do_mute(bool enable, bool remember) int cAudio::SetMute(bool enable)
{ {
lt_debug("%s(%d, %d)\n", __FUNCTION__, enable, remember); lt_debug("%s(%d)\n", __func__, enable);
int avsfd; int avsfd;
int ret; int ret;
if (remember) muted = enable;
Muted = enable; ret = ioctl(P->fd, MPEG_AUD_SET_MUTE, enable);
ret = ioctl(fd, MPEG_AUD_SET_MUTE, enable);
if (ret < 0) if (ret < 0)
lt_info("%s(%d) failed (%m)\n", __FUNCTION__, (int)enable); lt_info("%s(%d) failed (%m)\n", __FUNCTION__, (int)enable);
/* are we using alternative DSP / mixer? */ /* are we using alternative DSP / mixer? */
if (clipfd != -1 || mixer_fd != -1) if (P->clipfd != -1 || P->mixer_fd != -1)
setVolume(volume,volume); /* considers "Muted" variable, "remember" setVolume(volume,volume); /* considers "muted" variable, "remember"
is basically always true in this context */ is basically always true in this context */
avsfd = open("/dev/stb/tdsystem", O_RDONLY); avsfd = open("/dev/stb/tdsystem", O_RDONLY);
if (avsfd >= 0) if (avsfd >= 0)
@@ -103,14 +106,14 @@ int cAudio::setVolume(unsigned int left, unsigned int right)
int vr = map_volume(right); int vr = map_volume(right);
volume = (left + right) / 2; volume = (left + right) / 2;
int v = map_volume(volume); int v = map_volume(volume);
if (clipfd != -1 && mixer_fd != -1) { if (P->clipfd != -1 && P->mixer_fd != -1) {
int tmp = 0; int tmp = 0;
/* not sure if left / right is correct here, but it is always the same anyways ;-) */ /* not sure if left / right is correct here, but it is always the same anyways ;-) */
if (! Muted) if (! muted)
tmp = left << 8 | right; tmp = left << 8 | right;
ret = ioctl(mixer_fd, MIXER_WRITE(mixer_num), &tmp); ret = ioctl(P->mixer_fd, MIXER_WRITE(P->mixer_num), &tmp);
if (ret == -1) if (ret == -1)
lt_info("%s: MIXER_WRITE(%d),%04x: %m\n", __func__, mixer_num, tmp); lt_info("%s: MIXER_WRITE(%d),%04x: %m\n", __func__, P->mixer_num, tmp);
return ret; return ret;
} }
// if (settings.volume_type == CControld::TYPE_OST || forcetype == (int)CControld::TYPE_OST) // if (settings.volume_type == CControld::TYPE_OST || forcetype == (int)CControld::TYPE_OST)
@@ -122,7 +125,7 @@ int cAudio::setVolume(unsigned int left, unsigned int right)
vol.rearright = vr; vol.rearright = vr;
vol.center = v; vol.center = v;
vol.lfe = v; vol.lfe = v;
ret = ioctl(fd, MPEG_AUD_SET_VOL, &vol); ret = ioctl(P->fd, MPEG_AUD_SET_VOL, &vol);
if (ret < 0) if (ret < 0)
lt_info("setVolume MPEG_AUD_SET_VOL failed (%m)\n"); lt_info("setVolume MPEG_AUD_SET_VOL failed (%m)\n");
return ret; return ret;
@@ -146,17 +149,17 @@ int cAudio::setVolume(unsigned int left, unsigned int right)
int cAudio::Start(void) int cAudio::Start(void)
{ {
int ret; int fd = P->fd;
ret = ioctl(fd, MPEG_AUD_PLAY); int ret = ioctl(fd, MPEG_AUD_PLAY);
/* this seems to be not strictly necessary since neutrino /* this seems to be not strictly necessary since neutrino
re-mutes all the time, but is certainly more correct */ re-mutes all the time, but is certainly more correct */
ioctl(fd, MPEG_AUD_SET_MUTE, Muted); ioctl(fd, MPEG_AUD_SET_MUTE, muted);
return ret; return ret;
} }
int cAudio::Stop(void) int cAudio::Stop(void)
{ {
return ioctl(fd, MPEG_AUD_STOP); return ioctl(P->fd, MPEG_AUD_STOP);
} }
bool cAudio::Pause(bool /*Pcm*/) bool cAudio::Pause(bool /*Pcm*/)
@@ -167,6 +170,7 @@ bool cAudio::Pause(bool /*Pcm*/)
void cAudio::SetSyncMode(AVSYNC_TYPE Mode) void cAudio::SetSyncMode(AVSYNC_TYPE Mode)
{ {
lt_debug("%s %d\n", __FUNCTION__, Mode); lt_debug("%s %d\n", __FUNCTION__, Mode);
int fd = P->fd;
switch (Mode) switch (Mode)
{ {
case 0: case 0:
@@ -180,19 +184,25 @@ void cAudio::SetSyncMode(AVSYNC_TYPE Mode)
void cAudio::SetStreamType(AUDIO_FORMAT type) void cAudio::SetStreamType(AUDIO_FORMAT type)
{ {
int bypass_disable;
lt_debug("%s %d\n", __FUNCTION__, type); lt_debug("%s %d\n", __FUNCTION__, type);
StreamType = type; int fd = P->fd;
if (type != AUDIO_FMT_DOLBY_DIGITAL && type != AUDIO_FMT_MPEG && type != AUDIO_FMT_MPG1)
lt_info("%s unhandled AUDIO_FORMAT %d\n", __func__, type);
if (StreamType != AUDIO_FMT_DOLBY_DIGITAL && StreamType != AUDIO_FMT_MPEG && StreamType != AUDIO_FMT_MPG1) bool bypass_disable = (type != AUDIO_FMT_DOLBY_DIGITAL);
lt_info("%s unhandled AUDIO_FORMAT %d\n", __FUNCTION__, StreamType); if (bypass_disable)
ioctl(fd, MPEG_AUD_SET_MODE, AUD_MODE_MPEG);
else {
/* dvb2001 does always set AUD_MODE_DTS before setting AUD_MODE_AC3,
this might be some workaround, so we do the same... */
ioctl(fd, MPEG_AUD_SET_MODE, AUD_MODE_DTS);
ioctl(fd, MPEG_AUD_SET_MODE, AUD_MODE_AC3);
}
//setBypassMode(bypass_disable);
bypass_disable = (StreamType != AUDIO_FMT_DOLBY_DIGITAL); if (type == AUDIO_FMT_MPEG)
setBypassMode(bypass_disable);
if (StreamType == AUDIO_FMT_MPEG)
ioctl(fd, MPEG_AUD_SET_STREAM_TYPE, AUD_STREAM_TYPE_PES); ioctl(fd, MPEG_AUD_SET_STREAM_TYPE, AUD_STREAM_TYPE_PES);
if (StreamType == AUDIO_FMT_MPG1) if (type == AUDIO_FMT_MPG1)
ioctl(fd, MPEG_AUD_SET_STREAM_TYPE, AUD_STREAM_TYPE_MPEG1); ioctl(fd, MPEG_AUD_SET_STREAM_TYPE, AUD_STREAM_TYPE_MPEG1);
}; };
@@ -209,12 +219,12 @@ int cAudio::PrepareClipPlay(int ch, int srate, int bits, int little_endian)
const char *dsp_dev = getenv("DSP_DEVICE"); const char *dsp_dev = getenv("DSP_DEVICE");
const char *mix_dev = getenv("MIX_DEVICE"); const char *mix_dev = getenv("MIX_DEVICE");
lt_debug("%s ch %d srate %d bits %d le %d\n", __FUNCTION__, ch, srate, bits, little_endian); lt_debug("%s ch %d srate %d bits %d le %d\n", __FUNCTION__, ch, srate, bits, little_endian);
if (clipfd >= 0) { if (P->clipfd >= 0) {
lt_info("%s: clipfd already opened (%d)\n", __FUNCTION__, clipfd); lt_info("%s: clipfd already opened (%d)\n", __func__, P->clipfd);
return -1; return -1;
} }
mixer_num = -1; P->mixer_num = -1;
mixer_fd = -1; P->mixer_fd = -1;
/* a different DSP device can be given with DSP_DEVICE and MIX_DEVICE /* a different DSP device can be given with DSP_DEVICE and MIX_DEVICE
* if this device cannot be opened, we fall back to the internal TD OSS device * if this device cannot be opened, we fall back to the internal TD OSS device
* Example: * Example:
@@ -232,42 +242,42 @@ int cAudio::PrepareClipPlay(int ch, int srate, int bits, int little_endian)
} }
lt_info("%s: dsp_dev %s mix_dev %s\n", __func__, dsp_dev, mix_dev); /* NULL mix_dev is ok */ lt_info("%s: dsp_dev %s mix_dev %s\n", __func__, dsp_dev, mix_dev); /* NULL mix_dev is ok */
/* the tdoss dsp driver seems to work only on the second open(). really. */ /* the tdoss dsp driver seems to work only on the second open(). really. */
clipfd = open(dsp_dev, O_WRONLY); P->clipfd = open(dsp_dev, O_WRONLY);
close(clipfd); close(P->clipfd);
clipfd = open(dsp_dev, O_WRONLY); P->clipfd = open(dsp_dev, O_WRONLY);
if (clipfd < 0) { if (P->clipfd < 0) {
lt_info("%s open %s: %m\n", dsp_dev, __FUNCTION__); lt_info("%s open %s: %m\n", dsp_dev, __FUNCTION__);
return -1; return -1;
} }
fcntl(clipfd, F_SETFD, FD_CLOEXEC); fcntl(P->clipfd, F_SETFD, FD_CLOEXEC);
/* no idea if we ever get little_endian == 0 */ /* no idea if we ever get little_endian == 0 */
if (little_endian) if (little_endian)
fmt = AFMT_S16_BE; fmt = AFMT_S16_BE;
else else
fmt = AFMT_S16_LE; fmt = AFMT_S16_LE;
if (ioctl(clipfd, SNDCTL_DSP_SETFMT, &fmt)) if (ioctl(P->clipfd, SNDCTL_DSP_SETFMT, &fmt))
perror("SNDCTL_DSP_SETFMT"); perror("SNDCTL_DSP_SETFMT");
if (ioctl(clipfd, SNDCTL_DSP_CHANNELS, &ch)) if (ioctl(P->clipfd, SNDCTL_DSP_CHANNELS, &ch))
perror("SNDCTL_DSP_CHANNELS"); perror("SNDCTL_DSP_CHANNELS");
if (ioctl(clipfd, SNDCTL_DSP_SPEED, &srate)) if (ioctl(P->clipfd, SNDCTL_DSP_SPEED, &srate))
perror("SNDCTL_DSP_SPEED"); perror("SNDCTL_DSP_SPEED");
if (ioctl(clipfd, SNDCTL_DSP_RESET)) if (ioctl(P->clipfd, SNDCTL_DSP_RESET))
perror("SNDCTL_DSP_RESET"); perror("SNDCTL_DSP_RESET");
if (!mix_dev) if (!mix_dev)
return 0; return 0;
mixer_fd = open(mix_dev, O_RDWR); P->mixer_fd = open(mix_dev, O_RDWR);
if (mixer_fd < 0) { if (P->mixer_fd < 0) {
lt_info("%s: open mixer %s failed (%m)\n", __func__, mix_dev); lt_info("%s: open mixer %s failed (%m)\n", __func__, mix_dev);
/* not a real error */ /* not a real error */
return 0; return 0;
} }
if (ioctl(mixer_fd, SOUND_MIXER_READ_DEVMASK, &devmask) == -1) { if (ioctl(P->mixer_fd, SOUND_MIXER_READ_DEVMASK, &devmask) == -1) {
lt_info("%s: SOUND_MIXER_READ_DEVMASK %m\n", __func__); lt_info("%s: SOUND_MIXER_READ_DEVMASK %m\n", __func__);
devmask = 0; devmask = 0;
} }
if (ioctl(mixer_fd, SOUND_MIXER_READ_STEREODEVS, &stereo) == -1) { if (ioctl(P->mixer_fd, SOUND_MIXER_READ_STEREODEVS, &stereo) == -1) {
lt_info("%s: SOUND_MIXER_READ_STEREODEVS %m\n", __func__); lt_info("%s: SOUND_MIXER_READ_STEREODEVS %m\n", __func__);
stereo = 0; stereo = 0;
} }
@@ -275,8 +285,8 @@ int cAudio::PrepareClipPlay(int ch, int srate, int bits, int little_endian)
if (usable == 0) { if (usable == 0) {
lt_info("%s: devmask: %08x stereo: %08x, no usable dev :-(\n", lt_info("%s: devmask: %08x stereo: %08x, no usable dev :-(\n",
__func__, devmask, stereo); __func__, devmask, stereo);
close(mixer_fd); close(P->mixer_fd);
mixer_fd = -1; P->mixer_fd = -1;
return 0; /* TODO: should we treat this as error? */ return 0; /* TODO: should we treat this as error? */
} }
/* __builtin_popcount needs GCC, it counts the set bits... */ /* __builtin_popcount needs GCC, it counts the set bits... */
@@ -287,14 +297,14 @@ int cAudio::PrepareClipPlay(int ch, int srate, int bits, int little_endian)
__func__, devmask, stereo, __func__); __func__, devmask, stereo, __func__);
const char *tmp = getenv("MIX_NUMBER"); const char *tmp = getenv("MIX_NUMBER");
if (tmp) if (tmp)
mixer_num = atoi(tmp); P->mixer_num = atoi(tmp);
lt_info("%s: mixer_num is %d -> device %08x\n", lt_info("%s: mixer_num is %d -> device %08x\n",
__func__, (mixer_num >= 0) ? (1 << mixer_num) : 0); __func__, P->mixer_num, (P->mixer_num >= 0) ? (1 << P->mixer_num) : 0);
/* no error checking, you'd better know what you are doing... */ /* no error checking, you'd better know what you are doing... */
} else { } else {
mixer_num = 0; P->mixer_num = 0;
while (!(usable & 0x01)) { while (!(usable & 0x01)) {
mixer_num++; P->mixer_num++;
usable >>= 1; usable >>= 1;
} }
} }
@@ -307,11 +317,11 @@ int cAudio::WriteClip(unsigned char *buffer, int size)
{ {
int ret; int ret;
// lt_debug("cAudio::%s\n", __FUNCTION__); // lt_debug("cAudio::%s\n", __FUNCTION__);
if (clipfd <= 0) { if (P->clipfd <= 0) {
lt_info("%s: clipfd not yet opened\n", __FUNCTION__); lt_info("%s: clipfd not yet opened\n", __FUNCTION__);
return -1; return -1;
} }
ret = write(clipfd, buffer, size); ret = write(P->clipfd, buffer, size);
if (ret < 0) if (ret < 0)
lt_info("%s: write error (%m)\n", __FUNCTION__); lt_info("%s: write error (%m)\n", __FUNCTION__);
return ret; return ret;
@@ -320,15 +330,15 @@ int cAudio::WriteClip(unsigned char *buffer, int size)
int cAudio::StopClip() int cAudio::StopClip()
{ {
lt_debug("%s\n", __FUNCTION__); lt_debug("%s\n", __FUNCTION__);
if (clipfd <= 0) { if (P->clipfd <= 0) {
lt_info("%s: clipfd not yet opened\n", __FUNCTION__); lt_info("%s: clipfd not yet opened\n", __FUNCTION__);
return -1; return -1;
} }
close(clipfd); close(P->clipfd);
clipfd = -1; P->clipfd = -1;
if (mixer_fd >= 0) if (P->mixer_fd >= 0)
close(mixer_fd); close(P->mixer_fd);
mixer_fd = -1; P->mixer_fd = -1;
setVolume(volume, volume); setVolume(volume, volume);
return 0; return 0;
}; };
@@ -340,6 +350,7 @@ void cAudio::getAudioInfo(int &type, int &layer, int &freq, int &bitrate, int &m
static const int freq_mpg[] = {44100, 48000, 32000, 0}; static const int freq_mpg[] = {44100, 48000, 32000, 0};
static const int freq_ac3[] = {48000, 44100, 32000, 0}; static const int freq_ac3[] = {48000, 44100, 32000, 0};
scratchl2 i; scratchl2 i;
int fd = P->fd;
if (ioctl(fd, MPEG_AUD_GET_DECTYP, &atype) < 0) if (ioctl(fd, MPEG_AUD_GET_DECTYP, &atype) < 0)
perror("cAudio::getAudioInfo MPEG_AUD_GET_DECTYP"); perror("cAudio::getAudioInfo MPEG_AUD_GET_DECTYP");
if (ioctl(fd, MPEG_AUD_GET_STATUS, &i) < 0) if (ioctl(fd, MPEG_AUD_GET_STATUS, &i) < 0)
@@ -385,6 +396,11 @@ void cAudio::SetSpdifDD(bool enable)
lt_debug("%s %d\n", __FUNCTION__, enable); lt_debug("%s %d\n", __FUNCTION__, enable);
}; };
void cAudio::SetHdmiDD(bool enable)
{
lt_debug("%s %d\n", __func__, enable);
};
void cAudio::ScheduleMute(bool On) void cAudio::ScheduleMute(bool On)
{ {
lt_debug("%s %d\n", __FUNCTION__, On); lt_debug("%s %d\n", __FUNCTION__, On);
@@ -395,6 +411,7 @@ void cAudio::EnableAnalogOut(bool enable)
lt_debug("%s %d\n", __FUNCTION__, enable); lt_debug("%s %d\n", __FUNCTION__, enable);
}; };
#if 0
void cAudio::setBypassMode(bool disable) void cAudio::setBypassMode(bool disable)
{ {
lt_debug("%s %d\n", __FUNCTION__, disable); lt_debug("%s %d\n", __FUNCTION__, disable);
@@ -412,3 +429,4 @@ void cAudio::setBypassMode(bool disable)
/* all those ioctl aways return "invalid argument", but they seem to /* all those ioctl aways return "invalid argument", but they seem to
work anyway, so there's no use in checking the return value */ work anyway, so there's no use in checking the return value */
} }
#endif

View File

@@ -1,99 +0,0 @@
/* public header file */
#ifndef _AUDIO_TD_H_
#define _AUDIO_TD_H_
#include <hardware/aud/aud_inf.h>
#include <cs_types.h>
typedef enum
{
AUDIO_SYNC_WITH_PTS,
AUDIO_NO_SYNC,
AUDIO_SYNC_AUDIO_MASTER
} AUDIO_SYNC_MODE;
typedef enum {
HDMI_ENCODED_OFF,
HDMI_ENCODED_AUTO,
HDMI_ENCODED_FORCED
} HDMI_ENCODED_MODE;
typedef enum
{
AUDIO_FMT_AUTO = 0,
AUDIO_FMT_MPEG,
AUDIO_FMT_MP3,
AUDIO_FMT_DOLBY_DIGITAL,
AUDIO_FMT_BASIC = AUDIO_FMT_DOLBY_DIGITAL,
AUDIO_FMT_AAC,
AUDIO_FMT_AAC_PLUS,
AUDIO_FMT_DD_PLUS,
AUDIO_FMT_DTS,
AUDIO_FMT_AVS,
AUDIO_FMT_MLP,
AUDIO_FMT_WMA,
AUDIO_FMT_MPG1, // TD only. For Movieplayer / cPlayback
AUDIO_FMT_ADVANCED = AUDIO_FMT_MLP
} AUDIO_FORMAT;
class cAudio
{
friend class cPlayback;
private:
int fd;
bool Muted;
int clipfd; /* for pcm playback */
int mixer_fd; /* if we are using the OSS mixer */
int mixer_num; /* oss mixer to use, if any */
AUDIO_FORMAT StreamType;
AUDIO_SYNC_MODE SyncMode;
bool started;
int volume;
void openDevice(void);
void closeDevice(void);
int do_mute(bool enable, bool remember);
void setBypassMode(bool disable);
public:
/* construct & destruct */
cAudio(void *, void *, void *);
~cAudio(void);
void *GetHandle() { return NULL; };
/* shut up */
int mute(bool remember = true) { return do_mute(true, remember); };
int unmute(bool remember = true) { return do_mute(false, remember); };
/* volume, min = 0, max = 255 */
int setVolume(unsigned int left, unsigned int right);
int getVolume(void) { return volume;}
bool getMuteStatus(void) { return Muted; };
/* start and stop audio */
int Start(void);
int Stop(void);
bool Pause(bool Pcm = true);
void SetStreamType(AUDIO_FORMAT type);
void SetSyncMode(AVSYNC_TYPE Mode);
/* select channels */
int setChannel(int channel);
int PrepareClipPlay(int uNoOfChannels, int uSampleRate, int uBitsPerSample, int bLittleEndian);
int WriteClip(unsigned char * buffer, int size);
int StopClip();
void getAudioInfo(int &type, int &layer, int& freq, int &bitrate, int &mode);
void SetSRS(int iq_enable, int nmgr_enable, int iq_mode, int iq_level);
bool IsHdmiDDSupported() { return false; };
void SetHdmiDD(bool) { return; };
void SetSpdifDD(bool enable);
void ScheduleMute(bool On);
void EnableAnalogOut(bool enable);
};
#endif

View File

@@ -37,6 +37,8 @@ static pthread_mutex_t inbufpos_mutex = PTHREAD_MUTEX_INITIALIZER;
static int dvrfd = -1; static int dvrfd = -1;
static int streamtype; static int streamtype;
static bool was_muted = false;
extern cDemux *videoDemux; extern cDemux *videoDemux;
extern cDemux *audioDemux; extern cDemux *audioDemux;
extern cVideo *videoDecoder; extern cVideo *videoDecoder;
@@ -111,7 +113,7 @@ void cPlayback::Close(void)
/* don't crash */ /* don't crash */
if (audioDecoder) if (audioDecoder)
audioDecoder->do_mute(audioDecoder->Muted, false); audioDecoder->SetMute(was_muted);
} }
bool cPlayback::Start(char *filename, unsigned short vp, int vtype, unsigned short ap, int _ac3, unsigned int) bool cPlayback::Start(char *filename, unsigned short vp, int vtype, unsigned short ap, int _ac3, unsigned int)
@@ -427,12 +429,12 @@ bool cPlayback::SetSpeed(int speed)
audioDecoder->Start(); audioDecoder->Start();
videoDecoder->Start(); videoDecoder->Start();
playstate = STATE_PLAY; playstate = STATE_PLAY;
/* cPlayback is a friend of cAudio and can use private methods */ audioDecoder->SetMute(was_muted);
audioDecoder->do_mute(audioDecoder->Muted, false);
} }
if (playback_speed == 1 && speed > 1) if (playback_speed == 1 && speed > 1)
{ {
audioDecoder->mute(false); was_muted = audioDecoder->getMuteStatus();
audioDecoder->mute();
videoDecoder->vdec->FastForwardMode(); videoDecoder->vdec->FastForwardMode();
} }
playback_speed = speed; playback_speed = speed;

View File

@@ -20,7 +20,7 @@
#include <cstdio> #include <cstdio>
#include <cstdlib> #include <cstdlib>
#include "audio_lib.h" #include "audio_hal.h"
#include "dmx_hal.h" #include "dmx_hal.h"
#include "avdec.h" #include "avdec.h"
#include "lt_debug.h" #include "lt_debug.h"

View File

@@ -1,84 +0,0 @@
/* public header file */
#ifndef _AUDIO_LIB_H_
#define _AUDIO_LIB_H_
#include <stdint.h>
#include <cs_types.h>
typedef enum
{
AUDIO_SYNC_WITH_PTS,
AUDIO_NO_SYNC,
AUDIO_SYNC_AUDIO_MASTER
} AUDIO_SYNC_MODE;
typedef enum {
HDMI_ENCODED_OFF,
HDMI_ENCODED_AUTO,
HDMI_ENCODED_FORCED
} HDMI_ENCODED_MODE;
typedef enum
{
AUDIO_FMT_AUTO = 0,
AUDIO_FMT_MPEG,
AUDIO_FMT_MP3,
AUDIO_FMT_DOLBY_DIGITAL,
AUDIO_FMT_BASIC = AUDIO_FMT_DOLBY_DIGITAL,
AUDIO_FMT_AAC,
AUDIO_FMT_AAC_PLUS,
AUDIO_FMT_DD_PLUS,
AUDIO_FMT_DTS,
AUDIO_FMT_AVS,
AUDIO_FMT_MLP,
AUDIO_FMT_WMA,
AUDIO_FMT_MPG1, // TD only. For Movieplayer / cPlayback
AUDIO_FMT_ADVANCED = AUDIO_FMT_MLP
} AUDIO_FORMAT;
class cAudio
{
public:
/* construct & destruct */
cAudio(void *, void *, void *);
~cAudio(void);
void *GetHandle() { return NULL; };
/* shut up */
int mute(void);
int unmute(void);
int SetMute(bool enable);
/* volume, min = 0, max = 255 */
int setVolume(unsigned int left, unsigned int right);
int getVolume(void) { return volume;}
bool getMuteStatus(void) { return muted; };
/* start and stop audio */
int Start(void);
int Stop(void);
bool Pause(bool Pcm = true);
void SetStreamType(AUDIO_FORMAT type);
void SetSyncMode(AVSYNC_TYPE Mode);
/* select channels */
int setChannel(int channel);
int PrepareClipPlay(int uNoOfChannels, int uSampleRate, int uBitsPerSample, int bLittleEndian);
int WriteClip(unsigned char * buffer, int size);
int StopClip();
void getAudioInfo(int &type, int &layer, int& freq, int &bitrate, int &mode);
void SetSRS(int iq_enable, int nmgr_enable, int iq_mode, int iq_level);
bool IsHdmiDDSupported();
void SetHdmiDD(bool enable);
void SetSpdifDD(bool enable);
void ScheduleMute(bool On);
void EnableAnalogOut(bool enable);
private:
bool muted;
int volume;
void *pdata;
};
#endif