]> git.vomp.tv Git - vompclient.git/blob - vaudioselector.cc
Windows AC3, live tv banner icon w/s
[vompclient.git] / vaudioselector.cc
1 /*
2     Copyright 2006 Chris Tallon, Marten Richter
3
4     This file is part of VOMP.
5
6     VOMP is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     VOMP is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with VOMP; if not, write to the Free Software
18     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19 */
20
21 #include "vaudioselector.h"
22
23 #include "remote.h"
24 #include "colour.h"
25 #include "video.h"
26 #include "audio.h"
27 #include "boxstack.h"
28 #include "i18n.h"
29 #include "message.h"
30 #include "command.h"
31 #include "recinfo.h"
32 #include "log.h"
33 #include "channel.h"
34
35 VAudioSelector::VAudioSelector(void* tparent, bool* availableMpegAudioChannels,
36         bool* availableAc3AudioChannels, int currentAudioChannel, RecInfo* recInfo)
37 {
38   Log::getInstance()->log("VAS", Log::DEBUG, "%i", currentAudioChannel);
39
40   parent = tparent;
41
42   liveMode = false;
43
44   setSize(200, 120);
45   createBuffer();
46
47   sl.setPosition(40, 30);
48   sl.setSize(area.w - 45, area.h - 30);
49   add(&sl);
50
51   // Load data from availableAudioChannels, currentAudioChannel and recInfo
52
53   int i;
54
55   for (i = 0; i < PES_AUDIO_MAXCHANNELS; i++)
56   {
57     if (availableMpegAudioChannels[i])
58     {
59       AudioChannel* ac = new AudioChannel();
60       ac->type = 0;
61       ac->name = NULL;
62       ac->pestype = PES_AUDIO_START + i;
63       acl.push_back(ac);
64     }
65   }
66   if (availableAc3AudioChannels != NULL)
67   {
68     for (i = 0; i < PES_AUDIO_AC3_MAXCHANNELS; i++)
69     {
70       if (availableAc3AudioChannels[i])
71       {
72         AudioChannel* ac = new AudioChannel();
73         ac->type = 1;//ac3
74         ac->name = NULL;
75         ac->pestype = PES_AUDIO_AC3_START + i;
76         acl.push_back(ac);
77       }
78     }
79   }
80
81   unsigned char numchan_recinfo = recInfo->numComponents;
82   unsigned char numchan_siz = acl.size();
83   int mp_audcounter = 0;
84   int ac3_counter = 0;
85   int ac3_offset = 0;
86
87   for (i = 0; i < numchan_siz; i++)
88   {
89     AudioChannel* ac = acl[i];
90     if (ac)
91     {
92       if (ac->type==0)
93       {
94         ac3_offset++;
95       }
96     }
97   }
98
99   unsigned char type;
100   char* lang;
101   char* description;
102   int type_int;
103
104   for (i = 0; i < numchan_recinfo; i++)
105   {
106     if (recInfo->streams[i] != 2) continue; //not an audio component
107     type = recInfo->types[i];
108     lang = recInfo->languages[i];
109     description = recInfo->descriptions[i];
110     AudioChannel* ac = NULL;
111     type_int = 0;
112
113     switch (type)
114     {
115       case 1: //mpaudio mono
116       case 3: //mpaudio stereo
117         if (mp_audcounter < numchan_siz) ac = acl[mp_audcounter];
118         type_int = 0;
119         break;
120       case 5: //ac3
121         if (ac3_counter + ac3_offset < numchan_siz) ac = acl[ac3_counter + ac3_offset];
122         type_int = 1;
123         break;
124     }
125
126     if (ac)
127     {
128       if (ac->type == type_int)
129       {
130         if (description && (strlen(description) > 0))
131         {
132           ac->name = new char[strlen(description)+1];
133           strcpy(ac->name, description);
134         }
135         else if (lang && (strlen(lang) > 0))
136         {
137           ac->name = new char[strlen(lang)+1];
138           strcpy(ac->name, lang);
139         }
140       }
141     }
142
143     switch (type_int)
144     {
145       case 0: //mpaudio
146         mp_audcounter++;
147         break;
148       case 1: //ac3
149         ac3_counter++;
150         break;
151     }
152   }
153
154   // Now do display
155
156   char tempString[300];
157   int audioChannelListSize = acl.size();
158
159   if (audioChannelListSize)
160   {
161     for(i = 0; i < audioChannelListSize; i++)
162     {
163       AudioChannel* ac = acl[i];
164
165       if (ac->name)
166       {
167         sl.addOption(ac->name, (ULONG)ac, (ac->pestype == currentAudioChannel));
168       }
169       else
170       {
171         if (ac->type==0)
172         {
173           SNPRINTF(tempString, 299, "%lu", (ULONG)(ac->pestype - PES_AUDIO_START));
174         }
175         else if (ac->type==1)
176         {
177           SNPRINTF(tempString, 299, "ac3 %lu", (ULONG)(ac->pestype - PES_AUDIO_AC3_START));
178         }
179         else
180         {
181           SNPRINTF(tempString, 299, "unknown");
182         }
183         sl.addOption(tempString, (ULONG)ac, (ac->pestype == currentAudioChannel));
184       }
185     }
186   }
187   else
188   {
189     sl.addOption(tr("No audio channel data available"), 0, 1);
190   }
191 }
192
193 VAudioSelector::VAudioSelector(void* tparent, Channel* channel, int currentAudioChannel)
194 {
195   parent = tparent;
196
197   liveMode = true;
198
199   setSize(200, 120);
200   createBuffer();
201
202   sl.setPosition(40, 30);
203   sl.setSize(area.w - 45, area.h - 30);
204   add(&sl);
205
206   // Load data from availableAudioChannels, currentAudioChannel and recInfo
207
208   for (UINT i = 0; i < channel->numAPids; i++)
209   {
210     AudioChannel* ac = new AudioChannel();
211     ac->type = 0;
212     ac->name = new char[strlen(channel->apids[i].name) + 1];
213     strcpy(ac->name, channel->apids[i].name);
214     ac->pestype = channel->apids[i].pid;
215     acl.push_back(ac);
216   }
217   if (Audio::getInstance()->supportsAc3()) {
218       for (UINT i = 0; i < channel->numDPids; i++)
219       {
220           AudioChannel* ac = new AudioChannel();
221           ac->type = 1;
222           ac->name = new char[strlen(channel->dpids[i].name) + 1];
223           strcpy(ac->name, channel->dpids[i].name);
224           ac->pestype = channel->dpids[i].pid;
225           acl.push_back(ac);
226       }
227   }
228     
229   int audioChannelListSize = acl.size();
230
231   if (audioChannelListSize)
232   {
233     for(int i = 0; i < audioChannelListSize; i++)
234     {
235       AudioChannel* ac = acl[i];
236       sl.addOption(ac->name, (ULONG)ac, (ac->pestype == currentAudioChannel));
237     }
238   }
239   else
240   {
241     sl.addOption(tr("No audio channel data available"), 0, 1);
242   }
243 }
244
245 VAudioSelector::~VAudioSelector()
246 {
247   int audioChannelListSize = acl.size();
248   for(int i = 0; i < audioChannelListSize; i++)
249   {
250     delete acl[i]; // FIXME memory leak - nobody is deleting audio channel name?
251   }
252   acl.clear();
253
254   sl.clear();
255
256   Message* m = new Message();
257   m->from = this;
258   m->to = parent;
259   m->message = Message::CHILD_CLOSE;
260   Command::getInstance()->postMessageNoLock(m);
261 }
262
263 void VAudioSelector::draw()
264 {
265   TBBoxx::draw();
266   
267   // FIXME bad drawing
268   
269   rectangle(0, 0, area.w, 30, Colour::TITLEBARBACKGROUND);
270   drawText(tr("Audio"), 45, 5, Colour::LIGHTTEXT);
271
272   sl.setBackgroundColour(backgroundColour);
273   sl.draw();
274 }
275
276 int VAudioSelector::handleCommand(int command)
277 {
278   switch (command)
279   {
280     case Remote::BACK:
281     case Remote::OK:
282     case Remote::GREEN:
283     {
284       return 4;
285     }
286     case Remote::DF_UP:
287     case Remote::UP:
288     {
289       sl.up();
290       sl.draw();
291
292       BoxStack::getInstance()->update(this);
293
294       Message* m = new Message();
295       m->from = this;
296       m->to = parent;
297       m->message = Message::AUDIO_CHANGE_CHANNEL;
298       m->parameter = (((AudioChannel*)sl.getCurrentOptionData())->pestype &0xFFFF)|(((AudioChannel*)sl.getCurrentOptionData())->type &0xFF)<<16 ;
299       Command::getInstance()->postMessageNoLock(m);
300
301       return 2;
302     }
303     case Remote::DF_DOWN:
304     case Remote::DOWN:
305     {
306       sl.down();
307       sl.draw();
308
309       BoxStack::getInstance()->update(this);
310
311       Message* m = new Message();
312       m->from = this;
313       m->to = parent;
314       m->message = Message::AUDIO_CHANGE_CHANNEL;
315       m->parameter = (((AudioChannel*)sl.getCurrentOptionData())->pestype &0xFFFF)|(((AudioChannel*)sl.getCurrentOptionData())->type &0xFF)<<16 ;
316       Command::getInstance()->postMessageNoLock(m);
317
318       return 2;
319     }
320   }
321
322   return 1;
323 }
324
325 void VAudioSelector::processMessage(Message* m)
326 {
327   if (m->message == Message::MOUSE_MOVE)
328   {
329     UINT lastsel=sl.getCurrentOption();
330     if (sl.mouseMove((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY()))
331     {
332       sl.draw();
333       BoxStack::getInstance()->update(this);
334       if ((int)lastsel!=sl.getCurrentOption()) 
335       { 
336         Message* m2 = new Message();
337         m2->from = this;
338         m2->to = parent;
339         m2->message = Message::AUDIO_CHANGE_CHANNEL;
340         m2->parameter = (((AudioChannel*)sl.getCurrentOptionData())->pestype &0xFFFF)|(((AudioChannel*)sl.getCurrentOptionData())->type &0xFF)<<16 ;
341         Command::getInstance()->postMessageNoLock(m2);
342       }
343     }
344   }
345   else if (m->message == Message::MOUSE_LBDOWN)
346   {
347     if (sl.mouseLBDOWN((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY()))
348     {
349       BoxStack::getInstance()->handleCommand(Remote::OK); //simulate OK press
350     }
351     else
352     { //check if press is outside this view! then simulate cancel
353       int x=(m->parameter>>16)-getScreenX();
354       int y=(m->parameter&0xFFFF)-getScreenY();
355       if (x<0 || y <0 || x>(int)getWidth() || y>(int)getHeight())
356       {
357         BoxStack::getInstance()->handleCommand(Remote::BACK); //simulate cancel press
358       }
359     }
360   }
361 }
362