vdr/audio.c

129 lines
2.8 KiB
C

/*
* audio.c: The basic audio interface
*
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: audio.c 2.2 2010/05/16 11:00:52 kls Exp $
*/
#include "audio.h"
#include <stdlib.h>
#include "dvbdevice.h"
// --- cAudio ----------------------------------------------------------------
cAudio::cAudio(void)
{
Audios.Add(this);
}
cAudio::~cAudio()
{
}
// --- cAudios ---------------------------------------------------------------
cAudios Audios;
void cAudios::PlayAudio(const uchar *Data, int Length, uchar Id)
{
for (cAudio *audio = First(); audio; audio = Next(audio))
audio->Play(Data, Length, Id);
}
void cAudios::PlayTsAudio(const uchar *Data, int Length)
{
for (cAudio *audio = First(); audio; audio = Next(audio))
audio->PlayTs(Data, Length);
}
void cAudios::MuteAudio(bool On)
{
for (cAudio *audio = First(); audio; audio = Next(audio))
audio->Mute(On);
}
void cAudios::ClearAudio(void)
{
for (cAudio *audio = First(); audio; audio = Next(audio))
audio->Clear();
}
// --- cExternalAudio --------------------------------------------------------
cExternalAudio::cExternalAudio(const char *Command)
{
command = strdup(Command);
mute = false;
cDvbDevice::SetTransferModeForDolbyDigital(2);
}
cExternalAudio::~cExternalAudio()
{
free(command);
}
void cExternalAudio::Play(const uchar *Data, int Length, uchar Id)
{
if (command && !mute) {
if (pipe || pipe.Open(command, "w")) {
if (0x80 <= Id && Id <= 0x87 || Id == 0xBD) { // AC3
int written = Data[8] + 9; // skips the PES header
if (Id != 0xBD)
written += 4; // skips AC3 bytes
Length -= written;
while (Length > 0) {
int w = fwrite(Data + written, 1, Length, pipe);
if (w < 0) {
LOG_ERROR;
break;
}
Length -= w;
written += w;
}
}
}
else {
esyslog("ERROR: can't open pipe to audio command '%s'", command);
free(command);
command = NULL;
}
}
}
void cExternalAudio::PlayTs(const uchar *Data, int Length)
{
if (command && !mute) {
if (pipe || pipe.Open(command, "w")) {
int written = 0;
while (Length > 0) {
int w = fwrite(Data + written, 1, Length, pipe);
if (w < 0) {
LOG_ERROR;
break;
}
Length -= w;
written += w;
}
}
else {
esyslog("ERROR: can't open pipe to audio command '%s'", command);
free(command);
command = NULL;
}
}
}
void cExternalAudio::Mute(bool On)
{
mute = On;
if (mute)
Clear();
}
void cExternalAudio::Clear(void)
{
pipe.Close();
}