]> git.vomp.tv Git - vompclient.git/blob - vaudioselector.cc
Buffering progress bar
[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   
218   if (Audio::getInstance()->supportsAc3())
219   {
220     for (UINT i = 0; i < channel->numDPids; i++)
221     {
222       AudioChannel* ac = new AudioChannel();
223       ac->type = 1;
224       ac->name = new char[strlen(channel->dpids[i].name) + 1];
225       strcpy(ac->name, channel->dpids[i].name);
226       ac->pestype = channel->dpids[i].pid;
227       acl.push_back(ac);
228     }
229   }
230     
231   int audioChannelListSize = acl.size();
232
233   if (audioChannelListSize)
234   {
235     for(int i = 0; i < audioChannelListSize; i++)
236     {
237       AudioChannel* ac = acl[i];
238       sl.addOption(ac->name, (ULONG)ac, (ac->pestype == currentAudioChannel));
239     }
240   }
241   else
242   {
243     sl.addOption(tr("No audio channel data available"), 0, 1);
244   }
245 }
246
247 VAudioSelector::~VAudioSelector()
248 {
249   int audioChannelListSize = acl.size();
250   for(int i = 0; i < audioChannelListSize; i++)
251   {
252     delete acl[i]; // FIXME memory leak - nobody is deleting audio channel name?
253   }
254   acl.clear();
255
256   sl.clear();
257
258   Message* m = new Message();
259   m->from = this;
260   m->to = parent;
261   m->message = Message::CHILD_CLOSE;
262   Command::getInstance()->postMessageNoLock(m);
263 }
264
265 void VAudioSelector::draw()
266 {
267   TBBoxx::draw();
268   
269   // FIXME bad drawing
270   
271   rectangle(0, 0, area.w, 30, Colour::TITLEBARBACKGROUND);
272   drawText(tr("Audio"), 45, 5, Colour::LIGHTTEXT);
273
274   sl.setBackgroundColour(backgroundColour);
275   sl.draw();
276 }
277
278 int VAudioSelector::handleCommand(int command)
279 {
280   switch (command)
281   {
282     case Remote::BACK:
283     case Remote::OK:
284     case Remote::GREEN:
285     {
286       return 4;
287     }
288     case Remote::DF_UP:
289     case Remote::UP:
290     {
291       sl.up();
292       sl.draw();
293
294       BoxStack::getInstance()->update(this);
295
296       Message* m = new Message();
297       m->from = this;
298       m->to = parent;
299       m->message = Message::AUDIO_CHANGE_CHANNEL;
300       m->parameter = (((AudioChannel*)sl.getCurrentOptionData())->pestype &0xFFFF)|(((AudioChannel*)sl.getCurrentOptionData())->type &0xFF)<<16 ;
301       Command::getInstance()->postMessageNoLock(m);
302
303       return 2;
304     }
305     case Remote::DF_DOWN:
306     case Remote::DOWN:
307     {
308       sl.down();
309       sl.draw();
310
311       BoxStack::getInstance()->update(this);
312
313       Message* m = new Message();
314       m->from = this;
315       m->to = parent;
316       m->message = Message::AUDIO_CHANGE_CHANNEL;
317       m->parameter = (((AudioChannel*)sl.getCurrentOptionData())->pestype &0xFFFF)|(((AudioChannel*)sl.getCurrentOptionData())->type &0xFF)<<16 ;
318       Command::getInstance()->postMessageNoLock(m);
319
320       return 2;
321     }
322   }
323
324   return 1;
325 }
326
327 void VAudioSelector::processMessage(Message* m)
328 {
329   if (m->message == Message::MOUSE_MOVE)
330   {
331     UINT lastsel=sl.getCurrentOption();
332     if (sl.mouseMove((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY()))
333     {
334       sl.draw();
335       BoxStack::getInstance()->update(this);
336       if ((int)lastsel!=sl.getCurrentOption()) 
337       { 
338         Message* m2 = new Message();
339         m2->from = this;
340         m2->to = parent;
341         m2->message = Message::AUDIO_CHANGE_CHANNEL;
342         m2->parameter = (((AudioChannel*)sl.getCurrentOptionData())->pestype &0xFFFF)|(((AudioChannel*)sl.getCurrentOptionData())->type &0xFF)<<16 ;
343         Command::getInstance()->postMessageNoLock(m2);
344       }
345     }
346   }
347   else if (m->message == Message::MOUSE_LBDOWN)
348   {
349     if (sl.mouseLBDOWN((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY()))
350     {
351       BoxStack::getInstance()->handleCommand(Remote::OK); //simulate OK press
352     }
353     else
354     { //check if press is outside this view! then simulate cancel
355       int x=(m->parameter>>16)-getScreenX();
356       int y=(m->parameter&0xFFFF)-getScreenY();
357       if (x<0 || y <0 || x>(int)getWidth() || y>(int)getHeight())
358       {
359         BoxStack::getInstance()->handleCommand(Remote::BACK); //simulate cancel press
360       }
361     }
362   }
363 }
364