vdr
1.7.27
|
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 }