root/branches/echoaudio/src/libavc/general/avc_subunit.cpp

Revision 524, 7.2 kB (checked in by ppalmers, 14 years ago)

echo discovery works, audio I/O works, still some issues with midi and channel naming

Line 
1 /*
2  * Copyright (C)      2007 by Pieter Palmers
3  * Copyright (C) 2005-2007 by Daniel Wagner
4  *
5  * This file is part of FFADO
6  * FFADO = Free Firewire (pro-)audio drivers for linux
7  *
8  * FFADO is based upon FreeBoB
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License version 2.1, as published by the Free Software Foundation;
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
22  * MA 02110-1301 USA
23  */
24
25
26 #include "avc_subunit.h"
27 #include "../general/avc_unit.h"
28 #include "../general/avc_plug.h"
29
30 #include "libieee1394/configrom.h"
31
32 #include "../general/avc_plug_info.h"
33 #include "../streamformat/avc_extended_stream_format.h"
34 #include "../util/avc_serialize.h"
35
36 #include <sstream>
37
38 namespace AVC {
39
40 IMPL_DEBUG_MODULE( Subunit, Subunit, DEBUG_LEVEL_VERBOSE );
41
42 ////////////////////////////////////////////
43
44 Subunit::Subunit( Unit& unit,
45                   ESubunitType type,
46                   subunit_t id )
47     : m_unit( &unit )
48     , m_sbType( type )
49     , m_sbId( id )
50 {
51
52 }
53
54 Subunit::Subunit()
55 {
56 }
57
58 Subunit::~Subunit()
59 {
60     for ( PlugVector::iterator it = m_plugs.begin();
61           it != m_plugs.end();
62           ++it )
63     {
64         delete *it;
65     }
66 }
67
68 Plug *
69 Subunit::createPlug( AVC::Unit* unit,
70                      AVC::Subunit* subunit,
71                      AVC::function_block_type_t functionBlockType,
72                      AVC::function_block_type_t functionBlockId,
73                      AVC::Plug::EPlugAddressType plugAddressType,
74                      AVC::Plug::EPlugDirection plugDirection,
75                      AVC::plug_id_t plugId )
76 {
77
78     return new Plug( unit,
79                      subunit,
80                      functionBlockType,
81                      functionBlockId,
82                      plugAddressType,
83                      plugDirection,
84                      plugId );
85 }
86
87 bool
88 Subunit::discover()
89 {
90     if ( !discoverPlugs() ) {
91         debugError( "plug discovery failed\n" );
92         return false;
93     }
94
95     return true;
96 }
97
98 bool
99 Subunit::discoverPlugs()
100 {
101     PlugInfoCmd plugInfoCmd( getUnit().get1394Service(),
102                              PlugInfoCmd::eSF_SerialBusIsochronousAndExternalPlug );
103     plugInfoCmd.setNodeId( getUnit().getConfigRom().getNodeId() );
104     plugInfoCmd.setCommandType( AVCCommand::eCT_Status );
105     plugInfoCmd.setSubunitType( getSubunitType() );
106     plugInfoCmd.setSubunitId( getSubunitId() );
107     plugInfoCmd.setVerbose( getDebugLevel() );
108
109     if ( !plugInfoCmd.fire() ) {
110         debugError( "plug info command failed\n" );
111         return false;
112     }
113
114     debugOutput( DEBUG_LEVEL_NORMAL, "number of source plugs = %d\n",
115                  plugInfoCmd.m_sourcePlugs );
116     debugOutput( DEBUG_LEVEL_NORMAL, "number of destination output "
117                  "plugs = %d\n", plugInfoCmd.m_destinationPlugs );
118
119     if ( !discoverPlugs( Plug::eAPD_Input,
120                          plugInfoCmd.m_destinationPlugs ) )
121     {
122         debugError( "destination plug discovering failed\n" );
123         return false;
124     }
125
126     if ( !discoverPlugs(  Plug::eAPD_Output,
127                           plugInfoCmd.m_sourcePlugs ) )
128     {
129         debugError( "source plug discovering failed\n" );
130         return false;
131     }
132
133     return true;
134 }
135
136 bool
137 Subunit::discoverConnections()
138 {
139     debugOutput(DEBUG_LEVEL_NORMAL, "Discovering connections...\n");
140    
141     for ( PlugVector::iterator it = getPlugs().begin();
142           it != getPlugs().end();
143           ++it )
144     {
145         Plug* plug = *it;
146         if ( !plug->discoverConnections() ) {
147             debugError( "plug connection discovering failed ('%s')\n",
148                         plug->getName() );
149             return false;
150         }
151     }
152
153     return true;
154 }
155
156 bool
157 Subunit::discoverPlugs(Plug::EPlugDirection plugDirection,
158                                       plug_id_t plugMaxId )
159 {
160     debugOutput(DEBUG_LEVEL_NORMAL, "Discovering plugs...\n");
161     for ( int plugIdx = 0;
162           plugIdx < plugMaxId;
163           ++plugIdx )
164     {
165         Plug* plug = createPlug(  &getUnit(),
166                                 &getSubunit(),
167                                 0xff,
168                                 0xff,
169                                 Plug::eAPA_SubunitPlug,
170                                 plugDirection,
171                                 plugIdx );
172         if ( !plug ) {
173             debugError( "plug creation failed\n" );
174             return false;
175         }
176        
177         plug->setVerboseLevel(getDebugLevel());
178        
179         if ( !plug->discover() ) {
180             debugError( "plug discover failed\n" );
181             return false;
182         }
183
184         debugOutput( DEBUG_LEVEL_NORMAL, "plug '%s' found\n",
185                      plug->getName() );
186         getPlugs().push_back( plug );
187     }
188     return true;
189 }
190
191 bool
192 Subunit::addPlug( Plug& plug )
193 {
194     m_plugs.push_back( &plug );
195     return true;
196 }
197
198
199 Plug*
200 Subunit::getPlug(Plug::EPlugDirection direction, plug_id_t plugId)
201 {
202     for ( PlugVector::iterator it = m_plugs.begin();
203           it != m_plugs.end();
204           ++it )
205     {
206         Plug* plug = *it;
207         if ( ( plug->getPlugId() == plugId )
208             && ( plug->getDirection() == direction ) )
209         {
210             return plug;
211         }
212     }
213     return 0;
214 }
215
216 bool
217 Subunit::initPlugFromDescriptor( Plug& plug )
218 {
219     debugError("plug loading from descriptor not implemented\n");
220     return false;
221 }
222
223 bool
224 Subunit::serialize( Glib::ustring basePath,
225                                    Util::IOSerialize& ser ) const
226 {
227     bool result;
228
229     result  = ser.write( basePath + "m_sbType", m_sbType );
230     result &= ser.write( basePath + "m_sbId", m_sbId );
231     result &= ser.write( basePath + "m_verboseLevel", getDebugLevel() );
232     result &= serializeChild( basePath, ser );
233
234     return result;
235 }
236
237 Subunit*
238 Subunit::deserialize( Glib::ustring basePath,
239                       Util::IODeserialize& deser,
240                       Unit& unit )
241 {
242     bool result;
243     ESubunitType sbType;
244     result  = deser.read( basePath + "m_sbType", sbType );
245
246     Subunit* pSubunit = 0;
247    
248     #warning FIXME: The derived class should be creating these
249     // FIXME: The derived class should be creating these, such that discover() can become pure virtual
250     switch( sbType ) {
251     case eST_Audio:
252         pSubunit = new SubunitAudio;
253         break;
254     case eST_Music:
255         pSubunit = new SubunitMusic;
256         break;
257     default:
258         pSubunit = 0;
259     }
260
261     if ( !pSubunit ) {
262         return 0;
263     }
264
265     pSubunit->m_unit = &unit;
266     pSubunit->m_sbType = sbType;
267     result &= deser.read( basePath + "m_sbId", pSubunit->m_sbId );
268     int verboseLevel;
269     result &= deser.read( basePath + "m_verboseLevel", verboseLevel );
270     setDebugLevel(verboseLevel);
271     result &= pSubunit->deserializeChild( basePath, deser, unit );
272
273     if ( !result ) {
274         delete pSubunit;
275         return 0;
276     }
277
278     return pSubunit;
279 }
280
281 }
Note: See TracBrowser for help on using the browser.