vdr  1.7.27
audio.c
Go to the documentation of this file.
00001 /*
00002  * audio.c: The basic audio interface
00003  *
00004  * See the main source file 'vdr.c' for copyright information and
00005  * how to reach the author.
00006  *
00007  * $Id: audio.c 2.2 2010/05/16 13:30:11 kls Exp $
00008  */
00009 
00010 #include "audio.h"
00011 #include <stdlib.h>
00012 #include "dvbdevice.h"
00013 
00014 // --- cAudio ----------------------------------------------------------------
00015 
00016 cAudio::cAudio(void)
00017 {
00018   Audios.Add(this);
00019 }
00020 
00021 cAudio::~cAudio()
00022 {
00023 }
00024 
00025 // --- cAudios ---------------------------------------------------------------
00026 
00027 cAudios Audios;
00028 
00029 void cAudios::PlayAudio(const uchar *Data, int Length, uchar Id)
00030 {
00031   for (cAudio *audio = First(); audio; audio = Next(audio))
00032       audio->Play(Data, Length, Id);
00033 }
00034 
00035 void cAudios::PlayTsAudio(const uchar *Data, int Length)
00036 {
00037   for (cAudio *audio = First(); audio; audio = Next(audio))
00038       audio->PlayTs(Data, Length);
00039 }
00040 
00041 void cAudios::MuteAudio(bool On)
00042 {
00043   for (cAudio *audio = First(); audio; audio = Next(audio))
00044       audio->Mute(On);
00045 }
00046 
00047 void cAudios::ClearAudio(void)
00048 {
00049   for (cAudio *audio = First(); audio; audio = Next(audio))
00050       audio->Clear();
00051 }
00052 
00053 // --- cExternalAudio --------------------------------------------------------
00054 
00055 cExternalAudio::cExternalAudio(const char *Command)
00056 {
00057   command = strdup(Command);
00058   mute = false;
00059   cDvbDevice::SetTransferModeForDolbyDigital(2);
00060 }
00061 
00062 cExternalAudio::~cExternalAudio()
00063 {
00064   free(command);
00065 }
00066 
00067 void cExternalAudio::Play(const uchar *Data, int Length, uchar Id)
00068 {
00069   if (command && !mute) {
00070      if (pipe || pipe.Open(command, "w")) {
00071         if (0x80 <= Id && Id <= 0x87 || Id == 0xBD) { // AC3
00072            int written = Data[8] + 9; // skips the PES header
00073            if (Id != 0xBD)
00074               written += 4; // skips AC3 bytes
00075            Length -= written;
00076            while (Length > 0) {
00077                  int w = fwrite(Data + written, 1, Length, pipe);
00078                  if (w < 0) {
00079                     LOG_ERROR;
00080                     break;
00081                     }
00082                  Length -= w;
00083                  written += w;
00084                  }
00085            }
00086         }
00087      else {
00088         esyslog("ERROR: can't open pipe to audio command '%s'", command);
00089         free(command);
00090         command = NULL;
00091         }
00092      }
00093 }
00094 
00095 void cExternalAudio::PlayTs(const uchar *Data, int Length)
00096 {
00097   if (command && !mute) {
00098      if (pipe || pipe.Open(command, "w")) {
00099         int written = 0;
00100         while (Length > 0) {
00101               int w = fwrite(Data + written, 1, Length, pipe);
00102               if (w < 0) {
00103                  LOG_ERROR;
00104                  break;
00105                  }
00106               Length -= w;
00107               written += w;
00108               }
00109         }
00110      else {
00111         esyslog("ERROR: can't open pipe to audio command '%s'", command);
00112         free(command);
00113         command = NULL;
00114         }
00115      }
00116 }
00117 
00118 void cExternalAudio::Mute(bool On)
00119 {
00120   mute = On;
00121   if (mute)
00122      Clear();
00123 }
00124 
00125 void cExternalAudio::Clear(void)
00126 {
00127   pipe.Close();
00128 }