zapit/src/zapit.cpp: add support for adjusting volume per channel/pid

This commit is contained in:
[CST] Focus
2012-08-16 15:51:32 +04:00
parent 7d723aa44f
commit b7a9d81a50
2 changed files with 158 additions and 18 deletions

View File

@@ -21,11 +21,21 @@
#define PAL 0
#define NTSC 1
#define AUDIO_CONFIG_FILE "/var/tuxbox/config/zapit/audio.conf"
#define VOLUME_CONFIG_FILE "/var/tuxbox/config/zapit/volume.conf"
typedef std::map<t_channel_id, audio_map_set_t> audio_map_t;
typedef audio_map_t::iterator audio_map_iterator_t;
typedef std::map<transponder_id_t, time_t> sdt_tp_map_t;
typedef std::pair<int, int> pid_pair_t;
typedef std::pair<t_channel_id, pid_pair_t> volume_pair_t;
typedef std::multimap<t_channel_id, pid_pair_t> volume_map_t;
typedef volume_map_t::iterator volume_map_iterator_t;
typedef std::pair<volume_map_iterator_t,volume_map_iterator_t> volume_map_range_t;
#define VOLUME_PERCENT_AC3 100
#define VOLUME_PERCENT_PCM 75
/* complete zapit start thread-parameters in a struct */
typedef struct ZAPIT_start_arg
{
@@ -33,6 +43,7 @@ typedef struct ZAPIT_start_arg
t_channel_id startchannelradio_id;
int uselastchannel;
int video_mode;
int volume;
int ci_clock;
} Z_start_arg;
@@ -89,6 +100,7 @@ class CZapit : public OpenThreads::Thread
RECORD_MODE = 0x04
};
OpenThreads::Mutex mutex;
bool started;
bool event_mode;
bool firstzap;
@@ -99,10 +111,12 @@ class CZapit : public OpenThreads::Thread
int def_audio_mode;
int aspectratio;
int mode43;
#if 0
unsigned int volume_left;
unsigned int volume_right;
unsigned int def_volume_left;
unsigned int def_volume_right;
#endif
int current_volume;
int volume_percent;
int currentMode;
bool playbackStopForced;
@@ -121,6 +135,7 @@ class CZapit : public OpenThreads::Thread
CFrontend * live_fe;
audio_map_t audio_map;
volume_map_t vol_map;
//bool current_is_nvod;
//bool standby;
t_channel_id lastChannelRadio;
@@ -130,6 +145,7 @@ class CZapit : public OpenThreads::Thread
//void LoadAudioMap();
void SaveAudioMap();
void SaveVolumeMap();
void SaveSettings(bool write_conf);
//void SaveChannelPids(CZapitChannel* channel);
void RestoreChannelPids(CZapitChannel* channel);
@@ -171,6 +187,7 @@ class CZapit : public OpenThreads::Thread
Zapit_config config;
CZapitSdtMonitor SdtMonitor;
void LoadAudioMap();
void LoadVolumeMap();
void SaveChannelPids(CZapitChannel* channel);
virtual void ConfigFrontend();
bool StopPlayBack(bool send_pmt);
@@ -224,5 +241,11 @@ class CZapit : public OpenThreads::Thread
void SetCurrentChannelID(const t_channel_id channel_id) { live_channel_id = channel_id; };
void SetLiveFrontend(CFrontend * fe) { if(fe) live_fe = fe; }
CFrontend * GetLiveFrontend() { return live_fe; };
int GetPidVolume(t_channel_id channel_id, int pid, bool ac3 = false);
void SetPidVolume(t_channel_id channel_id, int pid, int percent);
void SetVolume(int vol);
int GetVolume() { return current_volume; };
int SetVolumePercent(int percent);
};
#endif /* __zapit_h__ */

View File

@@ -109,8 +109,7 @@ CZapit::CZapit()
{
started = false;
pmt_update_fd = -1;
volume_left = 0, volume_right = 0;
def_volume_left = 0, def_volume_right = 0;
//volume_left = 0, volume_right = 0;
audio_mode = 0;
aspectratio=0;
mode43=0;
@@ -122,6 +121,8 @@ CZapit::CZapit()
playing = false;
list_changed = false; // flag to indicate, allchans was changed
currentMode = 0;
current_volume = 100;
volume_percent = 0;
}
CZapit::~CZapit()
@@ -240,6 +241,38 @@ void CZapit::SaveAudioMap()
fclose(audio_config_file);
}
void CZapit::LoadVolumeMap()
{
vol_map.clear();
FILE *volume_config_file = fopen(VOLUME_CONFIG_FILE, "r");
if (!volume_config_file) {
perror(VOLUME_CONFIG_FILE);
return;
}
t_channel_id chan;
int apid = 0;
int volume = 0;
char s[1000];
while (fgets(s, 1000, volume_config_file)) {
if (sscanf(s, "%llx %d %d", &chan, &apid, &volume) == 3)
vol_map.insert(volume_pair_t(chan, pid_pair_t(apid, volume)));
}
fclose(volume_config_file);
}
void CZapit::SaveVolumeMap()
{
FILE *volume_config_file = fopen(VOLUME_CONFIG_FILE, "w");
if (!volume_config_file) {
perror(VOLUME_CONFIG_FILE);
return;
}
for (volume_map_iterator_t it = vol_map.begin(); it != vol_map.end(); ++it)
fprintf(volume_config_file, "%llx %d %d\n", (uint64_t) it->first, it->second.first, it->second.second);
fdatasync(fileno(volume_config_file));
fclose(volume_config_file);
}
void CZapit::LoadSettings()
{
@@ -285,6 +318,7 @@ void CZapit::LoadSettings()
/**/
LoadAudioMap();
LoadVolumeMap();
}
void CZapit::ConfigFrontend()
@@ -324,10 +358,10 @@ void CZapit::SaveChannelPids(CZapitChannel* channel)
if(channel == NULL)
return;
printf("[zapit] saving channel, apid %x sub pid %x mode %d volume %d\n", channel->getAudioPid(), dvbsub_getpid(), audio_mode, volume_right);
printf("[zapit] saving channel, apid %x sub pid %x mode %d volume %d\n", channel->getAudioPid(), dvbsub_getpid(), audio_mode, current_volume);
audio_map[channel->getChannelID()].apid = channel->getAudioPid();
audio_map[channel->getChannelID()].mode = audio_mode;
audio_map[channel->getChannelID()].volume = audioDecoder->getVolume();
audio_map[channel->getChannelID()].volume = current_volume;
audio_map[channel->getChannelID()].subpid = dvbsub_getpid();
tuxtx_subtitle_running(&audio_map[channel->getChannelID()].ttxpid, &audio_map[channel->getChannelID()].ttxpage, NULL);
}
@@ -344,19 +378,9 @@ void CZapit::RestoreChannelPids(CZapitChannel * channel)
if (channel->getAudioChannel(i)->pid == pidmap->apid ) {
DBG("***** Setting audio!\n");
channel->setAudioChannel(i);
#if 0
if(we_playing && (channel->getAudioChannel(i)->audioChannelType != CZapitAudioChannel::MPEG))
ChangeAudioPid(i);
#endif
}
}
}
#if 0 // to restore saved volume per channel if needed. after first zap its done by neutrino
if(firstzap) {
audioDecoder->setVolume(audio_map_it->second.volume, audio_map_it->second.volume);
}
#endif
volume_left = volume_right = pidmap->volume;
audio_mode = pidmap->mode;
dvbsub_setpid(pidmap->subpid);
@@ -374,12 +398,10 @@ void CZapit::RestoreChannelPids(CZapitChannel * channel)
else
tuxtx_set_pid(pidmap->ttxpid, pidmap->ttxpage, (char *) tmplang.c_str());
} else {
volume_left = volume_right = def_volume_left;
audio_mode = def_audio_mode;
tuxtx_set_pid(0, 0, (char *) channel->getTeletextLang());
}
/* restore saved stereo / left / right channel mode */
//audioDecoder->setVolume(volume_left, volume_right);
audioDecoder->setChannel(audio_mode);
}
@@ -552,6 +574,85 @@ bool CZapit::ZapForRecord(const t_channel_id channel_id)
return true;
}
/* set channel/pid volume percent, using current channel_id and pid, if those params is 0 */
void CZapit::SetPidVolume(t_channel_id channel_id, int pid, int percent)
{
if (!channel_id)
channel_id = live_channel_id;
if (!pid && (channel_id == live_channel_id) && current_channel)
pid = current_channel->getAudioPid();
INFO("############################### channel %llx pid %x map size %d percent %d", channel_id, pid, vol_map.size(), percent);
volume_map_range_t pids = vol_map.equal_range(channel_id);
for (volume_map_iterator_t it = pids.first; it != pids.second; ++it) {
if (it->second.first == pid) {
it->second.second = percent;
return;
}
}
vol_map.insert(volume_pair_t(channel_id, pid_pair_t(pid, percent)));
}
/* return channel/pid volume percent, using current channel_id and pid, if those params is 0 */
int CZapit::GetPidVolume(t_channel_id channel_id, int pid, bool ac3)
{
int percent = -1;
if (!channel_id)
channel_id = live_channel_id;
if (!pid && (channel_id == live_channel_id) && current_channel)
pid = current_channel->getAudioPid();
volume_map_range_t pids = vol_map.equal_range(channel_id);
for (volume_map_iterator_t it = pids.first; it != pids.second; ++it) {
if (it->second.first == pid) {
percent = it->second.second;
break;
}
}
if (percent < 0) {
percent = ac3 ? VOLUME_PERCENT_AC3 : VOLUME_PERCENT_PCM;
if ((channel_id == live_channel_id) && current_channel) {
for (int i = 0; i < current_channel->getAudioChannelCount(); i++) {
if (pid == current_channel->getAudioPid(i)) {
percent = current_channel->getAudioChannel(i)->audioChannelType == CZapitAudioChannel::AC3 ?
VOLUME_PERCENT_AC3 : VOLUME_PERCENT_PCM;
break;
}
}
}
}
INFO("############################### channel %llx pid %x map size %d percent %d", channel_id, pid, vol_map.size(), percent);
return percent;
}
void CZapit::SetVolume(int vol)
{
current_volume = vol;
if (current_volume < 0)
current_volume = 0;
if (current_volume > 100)
current_volume = 100;
int value = (current_volume * volume_percent) / 100;
INFO("############ volume %d percent %d -> %d ############", current_volume, volume_percent, value);
audioDecoder->setVolume(value, value);
//volume_left = volume_right = current_volume;
}
int CZapit::SetVolumePercent(int percent)
{
int ret = volume_percent;
if (volume_percent != percent) {
volume_percent = percent;
SetVolume(current_volume);
}
return ret;
}
void CZapit::SetAudioStreamType(CZapitAudioChannel::ZapitAudioChannelType audioChannelType)
{
const char *audioStr = "UNKNOWN";
@@ -581,6 +682,10 @@ void CZapit::SetAudioStreamType(CZapitAudioChannel::ZapitAudioChannelType audioC
break;
}
/* FIXME: bigger percent for AC3 only, what about AAC etc ? */
int newpercent = GetPidVolume(0, 0, audioChannelType == CZapitAudioChannel::AC3);
SetVolumePercent(newpercent);
printf("[zapit] starting %s audio\n", audioStr);
}
@@ -1471,15 +1576,21 @@ bool CZapit::ParseCommand(CBasicMessage::Header &rmsg, int connfd)
case CZapitMessages::CMD_SET_VOLUME: {
CZapitMessages::commandVolume msgVolume;
CBasicServer::receive_data(connfd, &msgVolume, sizeof(msgVolume));
#if 0
audioDecoder->setVolume(msgVolume.left, msgVolume.right);
volume_left = msgVolume.left;
volume_right = msgVolume.right;
#endif
SetVolume(msgVolume.left);
break;
}
case CZapitMessages::CMD_GET_VOLUME: {
CZapitMessages::commandVolume msgVolume;
#if 0
msgVolume.left = volume_left;
msgVolume.right = volume_right;
#endif
msgVolume.left = msgVolume.right = current_volume;
CBasicServer::send_data(connfd, &msgVolume, sizeof(msgVolume));
break;
}
@@ -1808,6 +1919,9 @@ bool CZapit::StopPlayBack(bool send_pmt)
else
dvbsub_stop();
/* reset volume percent to 100% i.e. for media playback, should be safe
* because StartPlayBack will use defaults or saved value */
SetVolumePercent(100);
return true;
}
@@ -1821,6 +1935,7 @@ void CZapit::enterStandby(void)
SaveSettings(true);
SaveAudioMap();
SaveVolumeMap();
StopPlayBack(true);
if(!(currentMode & RECORD_MODE)) {
@@ -1912,6 +2027,7 @@ bool CZapit::Start(Z_start_arg *ZapStart_arg)
live_fe = CFEManager::getInstance()->getFE(0);
/* load configuration or set defaults if no configuration file exists */
video_mode = ZapStart_arg->video_mode;
current_volume = ZapStart_arg->volume;
videoDemux = new cDemux();
videoDemux->Open(DMX_VIDEO_CHANNEL);
@@ -2088,6 +2204,7 @@ void CZapit::run()
SaveChannelPids(current_channel);
SaveSettings(true);
SaveAudioMap();
SaveVolumeMap();
StopPlayBack(true);
CFEManager::getInstance()->saveSettings(true);