mirror of
https://github.com/tuxbox-neutrino/libstb-hal.git
synced 2025-08-26 15:02:58 +02:00
libtriple: implement cAudio class
This commit is contained in:
249
libtriple/audio_td.cpp
Normal file
249
libtriple/audio_td.cpp
Normal file
@@ -0,0 +1,249 @@
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
#include <hardware/tddevices.h>
|
||||
#define AUDIO_DEVICE "/dev/" DEVICE_NAME_AUDIO
|
||||
#include "audio_td.h"
|
||||
|
||||
cAudio * audioDecoder = NULL;
|
||||
|
||||
cAudio::cAudio(void *, void *, void *)
|
||||
{
|
||||
fd = -1;
|
||||
openDevice();
|
||||
Muted = false;
|
||||
}
|
||||
|
||||
cAudio::~cAudio(void)
|
||||
{
|
||||
closeDevice();
|
||||
}
|
||||
|
||||
void cAudio::openDevice(void)
|
||||
{
|
||||
if (fd < 0)
|
||||
{
|
||||
if ((fd = open(AUDIO_DEVICE, O_RDWR)) < 0)
|
||||
fprintf(stderr, "cAudio::openDevice: open failed (%m)\n");
|
||||
}
|
||||
else
|
||||
fprintf(stderr, "cAudio::openDevice: already open (fd = %d)\n", fd);
|
||||
}
|
||||
|
||||
void cAudio::closeDevice(void)
|
||||
{
|
||||
if (fd >= 0)
|
||||
close(fd);
|
||||
fd = -1;
|
||||
}
|
||||
|
||||
int cAudio::do_mute(bool enable, bool remember)
|
||||
{
|
||||
lt_debug("cAudio::%s(%d, %d)\n", __FUNCTION__, enable, remember);
|
||||
int ret;
|
||||
if (remember)
|
||||
Muted = enable;
|
||||
ret = ioctl(fd, MPEG_AUD_SET_MUTE, enable);
|
||||
if (ret < 0)
|
||||
fprintf(stderr, "cAudio::%s(%d) failed (%m)\n", __FUNCTION__, (int)enable);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int map_volume(const int volume)
|
||||
{
|
||||
unsigned char vol = volume;
|
||||
if (vol > 100)
|
||||
vol = 100;
|
||||
|
||||
// vol = (invlog63[volume] + 1) / 2;
|
||||
vol = 31 - vol * 31 / 100;
|
||||
return vol;
|
||||
}
|
||||
|
||||
int cAudio::setVolume(unsigned int left, unsigned int right)
|
||||
{
|
||||
// int avsfd;
|
||||
int ret;
|
||||
int vl = map_volume(left);
|
||||
int vr = map_volume(right);
|
||||
int v = map_volume((left + right) / 2);
|
||||
// if (settings.volume_type == CControld::TYPE_OST || forcetype == (int)CControld::TYPE_OST)
|
||||
{
|
||||
AUDVOL vol;
|
||||
vol.frontleft = vl;
|
||||
vol.frontright = vr;
|
||||
vol.rearleft = vl;
|
||||
vol.rearright = vr;
|
||||
vol.center = v;
|
||||
vol.lfe = v;
|
||||
ret = ioctl(fd, MPEG_AUD_SET_VOL, &vol);
|
||||
if (ret < 0)
|
||||
fprintf(stderr, "cAudio::setVolume MPEG_AUD_SET_VOL failed (%m)\n");
|
||||
return ret;
|
||||
}
|
||||
#if 0
|
||||
else if (settings.volume_type == CControld::TYPE_AVS || forcetype == (int)CControld::TYPE_AVS)
|
||||
{
|
||||
if ((avsfd = open(AVS_DEVICE, O_RDWR)) < 0)
|
||||
perror("[controld] " AVS_DEVICE);
|
||||
else {
|
||||
if (ioctl(avsfd, IOC_AVS_SET_VOLUME, v))
|
||||
perror("[controld] IOC_AVS_SET_VOLUME");
|
||||
close(avsfd);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
fprintf(stderr, "CAudio::setVolume: invalid settings.volume_type = %d\n", settings.volume_type);
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
int cAudio::Start(void)
|
||||
{
|
||||
int ret;
|
||||
ret = ioctl(fd, MPEG_AUD_PLAY);
|
||||
/* this seems to be not strictly necessary since neutrino
|
||||
re-mutes all the time, but is certainly more correct */
|
||||
ioctl(fd, MPEG_AUD_SET_MUTE, Muted);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int cAudio::Stop(void)
|
||||
{
|
||||
return ioctl(fd, MPEG_AUD_STOP);
|
||||
}
|
||||
|
||||
bool cAudio::Pause(bool /*Pcm*/)
|
||||
{
|
||||
return true;
|
||||
};
|
||||
|
||||
void cAudio::SetSyncMode(AVSYNC_TYPE /*Mode*/)
|
||||
{
|
||||
fprintf(stderr, "cAudio::%s\n", __FUNCTION__);
|
||||
};
|
||||
|
||||
void cAudio::SetStreamType(AUDIO_FORMAT type)
|
||||
{
|
||||
int bypass_disable;
|
||||
fprintf(stderr, "cAudio::%s\n", __FUNCTION__);
|
||||
StreamType = type;
|
||||
|
||||
if (StreamType != AUDIO_FMT_DOLBY_DIGITAL && StreamType != AUDIO_FMT_MPEG && StreamType != AUDIO_FMT_MPG1)
|
||||
fprintf(stderr, "cAudio::%s unhandled AUDIO_FORMAT %d\n", __FUNCTION__, StreamType);
|
||||
|
||||
bypass_disable = (StreamType != AUDIO_FMT_DOLBY_DIGITAL);
|
||||
setBypassMode(bypass_disable);
|
||||
|
||||
if (StreamType == AUDIO_FMT_MPEG)
|
||||
ioctl(fd, MPEG_AUD_SET_STREAM_TYPE, AUD_STREAM_TYPE_PES);
|
||||
if (StreamType == AUDIO_FMT_MPG1)
|
||||
ioctl(fd, MPEG_AUD_SET_STREAM_TYPE, AUD_STREAM_TYPE_MPEG1);
|
||||
};
|
||||
|
||||
int cAudio::setChannel(int /*channel*/)
|
||||
{
|
||||
fprintf(stderr, "cAudio::%s\n", __FUNCTION__);
|
||||
return 0;
|
||||
};
|
||||
|
||||
int cAudio::PrepareClipPlay(int /*uNoOfChannels*/, int /*uSampleRate*/, int /*uBitsPerSample*/, int /*bLittleEndian*/)
|
||||
{
|
||||
fprintf(stderr, "cAudio::%s\n", __FUNCTION__);
|
||||
return 0;
|
||||
};
|
||||
|
||||
int cAudio::WriteClip(unsigned char * /*buffer*/, int /*size*/)
|
||||
{
|
||||
fprintf(stderr, "cAudio::%s\n", __FUNCTION__);
|
||||
return 0;
|
||||
};
|
||||
|
||||
int cAudio::StopClip()
|
||||
{
|
||||
fprintf(stderr, "cAudio::%s\n", __FUNCTION__);
|
||||
return 0;
|
||||
};
|
||||
|
||||
void cAudio::getAudioInfo(int &type, int &layer, int &freq, int &bitrate, int &mode)
|
||||
{
|
||||
fprintf(stderr, "cAudio::%s\n", __FUNCTION__);
|
||||
unsigned int atype;
|
||||
static const int freq_mpg[] = {44100, 48000, 32000, 0};
|
||||
static const int freq_ac3[] = {48000, 44100, 32000, 0};
|
||||
scratchl2 i;
|
||||
if (ioctl(fd, MPEG_AUD_GET_DECTYP, &atype) < 0)
|
||||
perror("cAudio::getAudioInfo MPEG_AUD_GET_DECTYP");
|
||||
if (ioctl(fd, MPEG_AUD_GET_STATUS, &i) < 0)
|
||||
perror("cAudio::getAudioInfo MPEG_AUD_GET_STATUS");
|
||||
|
||||
type = atype;
|
||||
#if 0
|
||||
/* this does not work, some of the values are negative?? */
|
||||
AMPEGStatus A;
|
||||
memcpy(&A, &i.word00, sizeof(i.word00));
|
||||
layer = A.audio_mpeg_layer;
|
||||
mode = A.audio_mpeg_mode;
|
||||
bitrate = A.audio_mpeg_bitrate;
|
||||
switch(A.audio_mpeg_frequency)
|
||||
#endif
|
||||
/* layer and bitrate are not used anyway... */
|
||||
layer = 0; //(i.word00 >> 17) & 3;
|
||||
bitrate = 0; //(i.word00 >> 12) & 3;
|
||||
switch (type)
|
||||
{
|
||||
case 0: /* MPEG */
|
||||
mode = (i.word00 >> 6) & 3;
|
||||
freq = freq_mpg[(i.word00 >> 10) & 3];
|
||||
break;
|
||||
case 1: /* AC3 */
|
||||
mode = (i.word00 >> 28) & 7;
|
||||
freq = freq_ac3[(i.word00 >> 16) & 3];
|
||||
break;
|
||||
default:
|
||||
mode = 0;
|
||||
freq = 0;
|
||||
}
|
||||
//fprintf(stderr, "type: %d layer: %d freq: %d bitrate: %d mode: %d\n", type, layer, freq, bitrate, mode);
|
||||
};
|
||||
|
||||
void cAudio::SetSRS(int /*iq_enable*/, int /*nmgr_enable*/, int /*iq_mode*/, int /*iq_level*/)
|
||||
{
|
||||
fprintf(stderr, "cAudio::%s\n", __FUNCTION__);
|
||||
};
|
||||
|
||||
void cAudio::SetSpdifDD(bool /*enable*/)
|
||||
{
|
||||
fprintf(stderr, "cAudio::%s\n", __FUNCTION__);
|
||||
};
|
||||
|
||||
void cAudio::ScheduleMute(bool /*On*/)
|
||||
{
|
||||
fprintf(stderr, "cAudio::%s\n", __FUNCTION__);
|
||||
};
|
||||
|
||||
void cAudio::EnableAnalogOut(bool /*enable*/)
|
||||
{
|
||||
fprintf(stderr, "cAudio::%s\n", __FUNCTION__);
|
||||
};
|
||||
|
||||
void cAudio::setBypassMode(bool disable)
|
||||
{
|
||||
/* disable = true: audio is MPEG, disable = false: audio is AC3 */
|
||||
if (disable)
|
||||
{
|
||||
ioctl(fd, MPEG_AUD_SET_MODE, AUD_MODE_MPEG);
|
||||
return;
|
||||
}
|
||||
/* 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);
|
||||
return;
|
||||
/* all those ioctl aways return "invalid argument", but they seem to
|
||||
work anyway, so there's no use in checking the return value */
|
||||
}
|
88
libtriple/audio_td.h
Normal file
88
libtriple/audio_td.h
Normal file
@@ -0,0 +1,88 @@
|
||||
/* public header file */
|
||||
|
||||
#ifndef _AUDIO_TD_H_
|
||||
#define _AUDIO_TD_H_
|
||||
|
||||
#include <hardware/aud/aud_inf.h>
|
||||
|
||||
typedef enum
|
||||
{
|
||||
AUDIO_SYNC_WITH_PTS,
|
||||
AUDIO_NO_SYNC,
|
||||
AUDIO_SYNC_AUDIO_MASTER
|
||||
} AUDIO_SYNC_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
|
||||
{
|
||||
private:
|
||||
int fd;
|
||||
bool Muted;
|
||||
|
||||
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);
|
||||
#define AVSYNC_TYPE int
|
||||
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
|
||||
|
Reference in New Issue
Block a user