mirror of
https://github.com/tuxbox-neutrino/neutrino.git
synced 2025-08-29 08:21:12 +02:00
zapit/src/zapit.cpp: add support for adjusting volume per channel/pid
This commit is contained in:
@@ -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__ */
|
||||
|
@@ -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);
|
||||
|
||||
|
Reference in New Issue
Block a user