]> git.vomp.tv Git - vompclient-marten.git/blob - vaudioselector.cc
*** empty log message ***
[vompclient-marten.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     // FIXME memory leak - nobody is deleting audio channel name? // try:
253     delete[] acl[i]->name;
254     Log::getInstance()->log("VAudioSelector", Log::DEBUG, "Deleted char[] on close");
255     delete acl[i];
256   }
257   acl.clear();
258
259   sl.clear();
260
261   Message* m = new Message();
262   m->from = this;
263   m->to = parent;
264   m->message = Message::CHILD_CLOSE;
265   Command::getInstance()->postMessageNoLock(m);
266 }
267
268 void VAudioSelector::draw()
269 {
270   TBBoxx::draw();
271   
272   // FIXME bad drawing
273   
274   rectangle(0, 0, area.w, 30, Colour::TITLEBARBACKGROUND);
275   drawText(tr("Audio"), 45, 5, Colour::LIGHTTEXT);
276
277   sl.setBackgroundColour(backgroundColour);
278   sl.draw();
279 }
280
281 int VAudioSelector::handleCommand(int command)
282 {
283   switch (command)
284   {
285     case Remote::BACK:
286     case Remote::OK:
287     case Remote::GREEN:
288     {
289       return 4;
290     }
291     case Remote::DF_UP:
292     case Remote::UP:
293     {
294       sl.up();
295       sl.draw();
296
297       BoxStack::getInstance()->update(this);
298
299       Message* m = new Message();
300       m->from = this;
301       m->to = parent;
302       m->message = Message::AUDIO_CHANGE_CHANNEL;
303       m->parameter = (((AudioChannel*)sl.getCurrentOptionData())->pestype &0xFFFF)|(((AudioChannel*)sl.getCurrentOptionData())->type &0xFF)<<16 ;
304       Command::getInstance()->postMessageNoLock(m);
305
306       return 2;
307     }
308     case Remote::DF_DOWN:
309     case Remote::DOWN:
310     {
311       sl.down();
312       sl.draw();
313
314       BoxStack::getInstance()->update(this);
315
316       Message* m = new Message();
317       m->from = this;
318       m->to = parent;
319       m->message = Message::AUDIO_CHANGE_CHANNEL;
320       m->parameter = (((AudioChannel*)sl.getCurrentOptionData())->pestype &0xFFFF)|(((AudioChannel*)sl.getCurrentOptionData())->type &0xFF)<<16 ;
321       Command::getInstance()->postMessageNoLock(m);
322
323       return 2;
324     }
325   }
326
327   return 1;
328 }
329
330 void VAudioSelector::processMessage(Message* m)
331 {
332   if (m->message == Message::MOUSE_MOVE)
333   {
334     UINT lastsel=sl.getCurrentOption();
335     if (sl.mouseMove((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY()))
336     {
337       sl.draw();
338       BoxStack::getInstance()->update(this);
339       if ((int)lastsel!=sl.getCurrentOption()) 
340       { 
341         Message* m2 = new Message();
342         m2->from = this;
343         m2->to = parent;
344         m2->message = Message::AUDIO_CHANGE_CHANNEL;
345         m2->parameter = (((AudioChannel*)sl.getCurrentOptionData())->pestype &0xFFFF)|(((AudioChannel*)sl.getCurrentOptionData())->type &0xFF)<<16 ;
346         Command::getInstance()->postMessageNoLock(m2);
347       }
348     }
349   }
350   else if (m->message == Message::MOUSE_LBDOWN)
351   {
352     if (sl.mouseLBDOWN((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY()))
353     {
354       BoxStack::getInstance()->handleCommand(Remote::OK); //simulate OK press
355     }
356     else
357     { //check if press is outside this view! then simulate cancel
358       int x=(m->parameter>>16)-getScreenX();
359       int y=(m->parameter&0xFFFF)-getScreenY();
360       if (x<0 || y <0 || x>(int)getWidth() || y>(int)getHeight())
361       {
362         BoxStack::getInstance()->handleCommand(Remote::BACK); //simulate cancel press
363       }
364     }
365   }
366 }
367