root/trunk/libfreebob/src/bebob/bebob_avdevice_subunit.cpp

Revision 187, 13.6 kB (checked in by wagi, 18 years ago)

2006-05-04 Daniel Wagner <wagi@monom.org>

  • configure.ac: Version bumped to 0.7.2
  • src/bebob: Some cleanup on naming and
    namespaces.
Line 
1 /* bebob_avdevice_subunit.cpp
2  * Copyright (C) 2005,06 by Daniel Wagner
3  *
4  * This file is part of FreeBob.
5  *
6  * FreeBob 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  * FreeBob is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with FreeBob; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
18  * MA 02111-1307 USA.
19  */
20
21 #include "bebob/bebob_functionblock.h"
22 #include "bebob/bebob_avdevice_subunit.h"
23 #include "bebob/bebob_avdevice.h"
24 #include "bebob/bebob_avplug.h"
25 #include "configrom.h"
26
27 #include "libfreebobavc/avc_plug_info.h"
28 #include "libfreebobavc/avc_extended_stream_format.h"
29 #include "libfreebobavc/serialize.h"
30
31 namespace BeBoB {
32
33 IMPL_DEBUG_MODULE( AvDeviceSubunit, AvDeviceSubunit, DEBUG_LEVEL_VERBOSE );
34
35 ////////////////////////////////////////////
36
37 AvDeviceSubunit::AvDeviceSubunit( AvDevice& avDevice,
38                                   AVCCommand::ESubunitType type,
39                                   subunit_t id,
40                                   int verboseLevel )
41     : m_avDevice( &avDevice )
42     , m_sbType( type )
43     , m_sbId( id )
44     , m_verboseLevel( verboseLevel )
45 {
46     if ( m_verboseLevel ) {
47         setDebugLevel( DEBUG_LEVEL_VERBOSE );
48     }
49 }
50
51 AvDeviceSubunit::~AvDeviceSubunit()
52 {
53     for ( AvPlugVector::iterator it = m_plugs.begin();
54           it != m_plugs.end();
55           ++it )
56     {
57         delete *it;
58     }
59 }
60
61 bool
62 AvDeviceSubunit::discover()
63 {
64     if ( !discoverPlugs() ) {
65         debugError( "plug discovering failed\n" );
66         return false;
67     }
68
69     return true;
70 }
71
72 bool
73 AvDeviceSubunit::discoverPlugs()
74 {
75     PlugInfoCmd plugInfoCmd( m_avDevice->get1394Service(),
76                              PlugInfoCmd::eSF_SerialBusIsochronousAndExternalPlug );
77     plugInfoCmd.setNodeId( m_avDevice->getConfigRom().getNodeId() );
78     plugInfoCmd.setCommandType( AVCCommand::eCT_Status );
79     plugInfoCmd.setSubunitType( m_sbType );
80     plugInfoCmd.setSubunitId( m_sbId );
81     plugInfoCmd.setVerbose( m_verboseLevel );
82
83     if ( !plugInfoCmd.fire() ) {
84         debugError( "plug info command failed\n" );
85         return false;
86     }
87
88     debugOutput( DEBUG_LEVEL_NORMAL, "number of source plugs = %d\n",
89                  plugInfoCmd.m_sourcePlugs );
90     debugOutput( DEBUG_LEVEL_NORMAL, "number of destination output "
91                  "plugs = %d\n", plugInfoCmd.m_destinationPlugs );
92
93     if ( !discoverPlugs( AvPlug::eAPD_Input,
94                          plugInfoCmd.m_destinationPlugs ) )
95     {
96         debugError( "destination plug discovering failed\n" );
97         return false;
98     }
99
100     if ( !discoverPlugs(  AvPlug::eAPD_Output,
101                           plugInfoCmd.m_sourcePlugs ) )
102     {
103         debugError( "source plug discovering failed\n" );
104         return false;
105     }
106
107     return true;
108 }
109
110 bool
111 AvDeviceSubunit::discoverConnections()
112 {
113     for ( AvPlugVector::iterator it = m_plugs.begin();
114           it != m_plugs.end();
115           ++it )
116     {
117         AvPlug* plug = *it;
118         if ( !plug->discoverConnections() ) {
119             debugError( "plug connection discovering failed ('%s')\n",
120                         plug->getName() );
121             return false;
122         }
123     }
124
125     return true;
126 }
127
128 bool
129 AvDeviceSubunit::discoverPlugs(AvPlug::EAvPlugDirection plugDirection,
130                                plug_id_t plugMaxId )
131 {
132     for ( int plugIdx = 0;
133           plugIdx < plugMaxId;
134           ++plugIdx )
135     {
136         AVCCommand::ESubunitType subunitType =
137             static_cast<AVCCommand::ESubunitType>( getSubunitType() );
138         AvPlug* plug = new AvPlug( *m_avDevice->get1394Service(),
139                                    m_avDevice->getConfigRom().getNodeId(),
140                                    m_avDevice->getPlugManager(),
141                                    subunitType,
142                                    getSubunitId(),
143                                    0xff,
144                                    0xff,
145                                    AvPlug::eAPA_SubunitPlug,
146                                    plugDirection,
147                                    plugIdx,
148                                    m_verboseLevel );
149         if ( !plug || !plug->discover() ) {
150             debugError( "plug discover failed\n" );
151             return false;
152         }
153
154         debugOutput( DEBUG_LEVEL_NORMAL, "plug '%s' found\n",
155                      plug->getName() );
156         m_plugs.push_back( plug );
157     }
158     return true;
159 }
160
161 bool
162 AvDeviceSubunit::addPlug( AvPlug& plug )
163 {
164     m_plugs.push_back( &plug );
165     return true;
166 }
167
168
169 AvPlug*
170 AvDeviceSubunit::getPlug(AvPlug::EAvPlugDirection direction, plug_id_t plugId)
171 {
172     for ( AvPlugVector::iterator it = m_plugs.begin();
173           it != m_plugs.end();
174           ++it )
175     {
176         AvPlug* plug = *it;
177         if ( ( plug->getPlugId() == plugId )
178             && ( plug->getDirection() == direction ) )
179         {
180             return plug;
181         }
182     }
183     return 0;
184 }
185
186 ////////////////////////////////////////////
187
188 AvDeviceSubunitAudio::AvDeviceSubunitAudio( AvDevice& avDevice,
189                                             subunit_t id,
190                                             int verboseLevel )
191     : AvDeviceSubunit( avDevice, AVCCommand::eST_Audio, id, verboseLevel )
192 {
193 }
194
195 AvDeviceSubunitAudio::~AvDeviceSubunitAudio()
196 {
197     for ( FunctionBlockVector::iterator it = m_functions.begin();
198           it != m_functions.end();
199           ++it )
200     {
201         delete *it;
202     }
203 }
204
205 bool
206 AvDeviceSubunitAudio::discover()
207 {
208     if ( !AvDeviceSubunit::discover() ) {
209         return false;
210     }
211
212     if ( !discoverFunctionBlocks() ) {
213         debugError( "function block discovering failed\n" );
214         return false;
215     }
216
217     return true;
218 }
219
220 bool
221 AvDeviceSubunitAudio::discoverConnections()
222 {
223     if ( !AvDeviceSubunit::discoverConnections() ) {
224         return false;
225     }
226
227     for ( FunctionBlockVector::iterator it = m_functions.begin();
228           it != m_functions.end();
229           ++it )
230     {
231         FunctionBlock* function = *it;
232         if ( !function->discoverConnections() ) {
233             debugError( "functionblock connection discovering failed ('%s')\n",
234                         function->getName() );
235             return false;
236         }
237     }
238
239     return true;
240 }
241
242 const char*
243 AvDeviceSubunitAudio::getName()
244 {
245     return "AudioSubunit";
246 }
247
248 bool
249 AvDeviceSubunitAudio::discoverFunctionBlocks()
250 {
251     if ( !discoverFunctionBlocksDo(
252              ExtendedSubunitInfoCmd::eFBT_AudioSubunitSelector) )
253     {
254         debugError( "Could not discover function block selector\n" );
255         return false;
256     }
257     if ( !discoverFunctionBlocksDo(
258              ExtendedSubunitInfoCmd::eFBT_AudioSubunitFeature) )
259     {
260         debugError( "Could not discover function block feature\n" );
261         return false;
262     }
263     if ( !discoverFunctionBlocksDo(
264              ExtendedSubunitInfoCmd::eFBT_AudioSubunitProcessing) )
265     {
266         debugError( "Could not discover function block processing\n" );
267         return false;
268     }
269     if ( !discoverFunctionBlocksDo(
270              ExtendedSubunitInfoCmd::eFBT_AudioSubunitCodec) )
271     {
272         debugError( "Could not discover function block codec\n" );
273         return false;
274     }
275
276     return true;
277 }
278
279 bool
280 AvDeviceSubunitAudio::discoverFunctionBlocksDo(
281     ExtendedSubunitInfoCmd::EFunctionBlockType fbType )
282 {
283     int page = 0;
284     bool cmdSuccess = false;
285     bool finished = false;
286
287     do {
288         ExtendedSubunitInfoCmd
289             extSubunitInfoCmd( m_avDevice->get1394Service() );
290         extSubunitInfoCmd.setNodeId( m_avDevice->getConfigRom().getNodeId() );
291         extSubunitInfoCmd.setCommandType( AVCCommand::eCT_Status );
292         extSubunitInfoCmd.setSubunitId( getSubunitId() );
293         extSubunitInfoCmd.setSubunitType( getSubunitType() );
294         extSubunitInfoCmd.setVerbose( m_verboseLevel );
295
296         extSubunitInfoCmd.m_fbType = fbType;
297         extSubunitInfoCmd.m_page = page;
298
299         cmdSuccess = extSubunitInfoCmd.fire();
300         if ( cmdSuccess
301              && ( extSubunitInfoCmd.getResponse()
302                   == AVCCommand::eR_Implemented ) )
303         {
304             for ( ExtendedSubunitInfoPageDataVector::iterator it =
305                       extSubunitInfoCmd.m_infoPageDatas.begin();
306                   cmdSuccess
307                       && ( it != extSubunitInfoCmd.m_infoPageDatas.end() );
308                   ++it )
309             {
310                 cmdSuccess = createFunctionBlock( fbType, **it );
311             }
312             if ( ( extSubunitInfoCmd.m_infoPageDatas.size() != 0 )
313                  && ( extSubunitInfoCmd.m_infoPageDatas.size() == 5 ) )
314             {
315                 page++;
316             } else {
317                 finished = true;
318             }
319         } else {
320             finished = true;
321         }
322     } while ( cmdSuccess && !finished );
323
324     return cmdSuccess;
325 }
326
327 bool
328 AvDeviceSubunitAudio::createFunctionBlock(
329     ExtendedSubunitInfoCmd::EFunctionBlockType fbType,
330     ExtendedSubunitInfoPageData& data )
331 {
332     FunctionBlock::ESpecialPurpose purpose
333         = convertSpecialPurpose(  data.m_functionBlockSpecialPupose );
334
335     FunctionBlock* fb = 0;
336
337     switch ( fbType ) {
338     case ExtendedSubunitInfoCmd::eFBT_AudioSubunitSelector:
339     {
340         fb = new FunctionBlockSelector( *this,
341                                         data.m_functionBlockId,
342                                         purpose,
343                                         data.m_noOfInputPlugs,
344                                         data.m_noOfOutputPlugs,
345                                         m_verboseLevel );
346     }
347     break;
348     case ExtendedSubunitInfoCmd::eFBT_AudioSubunitFeature:
349     {
350         fb = new FunctionBlockFeature( *this,
351                                        data.m_functionBlockId,
352                                        purpose,
353                                        data.m_noOfInputPlugs,
354                                        data.m_noOfOutputPlugs,
355                                        m_verboseLevel );
356     }
357     break;
358     case ExtendedSubunitInfoCmd::eFBT_AudioSubunitProcessing:
359     {
360         switch ( data.m_functionBlockType ) {
361         case ExtendedSubunitInfoCmd::ePT_EnhancedMixer:
362         {
363             fb = new FunctionBlockEnhancedMixer( *this,
364                                                  data.m_functionBlockId,
365                                                  purpose,
366                                                  data.m_noOfInputPlugs,
367                                                  data.m_noOfOutputPlugs,
368                                                  m_verboseLevel );
369         }
370         break;
371         case ExtendedSubunitInfoCmd::ePT_Mixer:
372         case ExtendedSubunitInfoCmd::ePT_Generic:
373         case ExtendedSubunitInfoCmd::ePT_UpDown:
374         case ExtendedSubunitInfoCmd::ePT_DolbyProLogic:
375         case ExtendedSubunitInfoCmd::ePT_3DStereoExtender:
376         case ExtendedSubunitInfoCmd::ePT_Reverberation:
377         case ExtendedSubunitInfoCmd::ePT_Chorus:
378         case ExtendedSubunitInfoCmd::ePT_DynamicRangeCompression:
379         default:
380             fb = new FunctionBlockProcessing( *this,
381                                               data.m_functionBlockId,
382                                               purpose,
383                                               data.m_noOfInputPlugs,
384                                               data.m_noOfOutputPlugs,
385                                               m_verboseLevel );
386             debugWarning( "Dummy function block processing created. "
387                           "Implementation is missing\n" );
388         }
389     }
390     break;
391     case ExtendedSubunitInfoCmd::eFBT_AudioSubunitCodec:
392     {
393         fb = new FunctionBlockCodec( *this,
394                                      data.m_functionBlockId,
395                                      purpose,
396                                      data.m_noOfInputPlugs,
397                                      data.m_noOfOutputPlugs,
398                                      m_verboseLevel );
399         debugWarning( "Dummy function block codec created. "
400                       "Implementation is missing\n" );
401     }
402     break;
403     default:
404         debugError( "Unhandled function block type found\n" );
405         return false;
406     }
407
408     if ( !fb ) {
409         debugError( "Could create function block\n" );
410         return false;
411     }
412     if ( !fb->discover() ) {
413         debugError( "Could not discover function block %s\n",
414                     fb->getName() );
415         delete fb;
416         return false;
417     }
418     m_functions.push_back( fb );
419
420     return true;
421 }
422
423 FunctionBlock::ESpecialPurpose
424 AvDeviceSubunitAudio::convertSpecialPurpose(
425     function_block_special_purpose_t specialPurpose )
426 {
427     FunctionBlock::ESpecialPurpose p;
428     switch ( specialPurpose ) {
429     case ExtendedSubunitInfoPageData::eSP_InputGain:
430         p  = FunctionBlock::eSP_InputGain;
431         break;
432     case ExtendedSubunitInfoPageData::eSP_OutputVolume:
433         p = FunctionBlock::eSP_OutputVolume;
434     break;
435     default:
436         p = FunctionBlock::eSP_NoSpecialPurpose;
437     }
438     return p;
439 }
440
441
442 ////////////////////////////////////////////
443
444 AvDeviceSubunitMusic::AvDeviceSubunitMusic( AvDevice& avDevice,
445                                             subunit_t id,
446                                             int verboseLevel )
447     : AvDeviceSubunit( avDevice, AVCCommand::eST_Music, id, verboseLevel )
448 {
449 }
450
451 AvDeviceSubunitMusic::~AvDeviceSubunitMusic()
452 {
453 }
454
455 const char*
456 AvDeviceSubunitMusic::getName()
457 {
458     return "MusicSubunit";
459 }
460
461 }
Note: See TracBrowser for help on using the browser.