root/trunk/libffado/src/libavc/musicsubunit/avc_musicsubunit.cpp

Revision 1110, 10.8 kB (checked in by wagi, 14 years ago)

Lot's of small and big bug fixes allong the caching path.
There were several parts not correctly deserialized.

This should fix ticket #65

Line 
1 /*
2  * Copyright (C) 2005-2008 by Pieter Palmers
3  * Copyright (C) 2005-2008 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 program is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation, either version 2 of the License, or
13  * (at your option) version 3 of the License.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
22  *
23  */
24
25 #include "libieee1394/configrom.h"
26
27 #include "../general/avc_subunit.h"
28 #include "../general/avc_unit.h"
29
30 #include "../general/avc_plug_info.h"
31 #include "../streamformat/avc_extended_stream_format.h"
32 #include "libutil/cmd_serialize.h"
33
34 #include "avc_musicsubunit.h"
35 #include "avc_descriptor_music.h"
36
37 #include <sstream>
38
39 namespace AVC {
40
41 ////////////////////////////////////////////
42
43 SubunitMusic::SubunitMusic( Unit& unit, subunit_t id )
44     : Subunit( unit, eST_Music, id )
45     , m_status_descriptor ( new AVCMusicStatusDescriptor( &unit, this ) )
46 {
47
48 }
49
50 SubunitMusic::SubunitMusic()
51     : Subunit()
52     , m_status_descriptor ( NULL )
53 {
54 }
55
56 SubunitMusic::~SubunitMusic()
57 {
58     if (m_status_descriptor) delete m_status_descriptor;
59 }
60
61 bool
62 SubunitMusic::discover()
63 {
64     debugOutput(DEBUG_LEVEL_NORMAL, "Discovering %s...\n", getName());
65
66     // discover the AV/C generic part
67     if ( !Subunit::discover() ) {
68         return false;
69     }
70
71     // now we have the subunit plugs
72
73     return true;
74 }
75
76 bool
77 SubunitMusic::initPlugFromDescriptor( Plug& plug )
78 {
79     debugOutput(DEBUG_LEVEL_VERBOSE, "Loading info from descriptor for plug: \n");
80     bool result=true;
81
82     // load the descriptor (if not already loaded)
83     if (m_status_descriptor != NULL) {
84         result &= m_status_descriptor->load();
85     }
86
87     AVCMusicSubunitPlugInfoBlock *info;
88     info = m_status_descriptor->getSubunitPlugInfoBlock(plug.getDirection(), plug.getPlugId());
89
90     if (info == NULL) {
91         debugError("Could not find plug info block\n");
92         return false;
93     }
94
95     debugOutput(DEBUG_LEVEL_VERBOSE, "Found plug: %s\n",info->getName().c_str());
96
97     // plug name
98     result &= plug.setName(info->getName());
99
100     // plug type
101     switch (info->m_plug_type) {
102         case AVCMusicSubunitPlugInfoBlock::ePT_IsoStream:
103             result &= plug.setPlugType(Plug::eAPT_IsoStream);
104             break;
105         case AVCMusicSubunitPlugInfoBlock::ePT_AsyncStream:
106             result &= plug.setPlugType(Plug::eAPT_AsyncStream);
107             break;
108         case AVCMusicSubunitPlugInfoBlock::ePT_Midi:
109             result &= plug.setPlugType(Plug::eAPT_Midi);
110             break;
111         case AVCMusicSubunitPlugInfoBlock::ePT_Sync:
112             result &= plug.setPlugType(Plug::eAPT_Sync);
113             break;
114         case AVCMusicSubunitPlugInfoBlock::ePT_Analog:
115             result &= plug.setPlugType(Plug::eAPT_Analog);
116             break;
117         case AVCMusicSubunitPlugInfoBlock::ePT_Digital:
118             result &= plug.setPlugType(Plug::eAPT_Digital);
119             break;
120     }
121
122     // number of channels
123     result &= plug.setNrOfChannels(info->m_nb_channels);
124
125     int idx=1;
126     for ( AVCMusicClusterInfoBlockVectorIterator it = info->m_Clusters.begin();
127           it != info->m_Clusters.end();
128           ++it )
129     {
130         struct Plug::ClusterInfo cinfo;
131
132         AVCMusicClusterInfoBlock *c=(*it);
133
134         cinfo.m_index=idx; //FIXME: is this correct?
135         cinfo.m_portType=c->m_port_type;
136         cinfo.m_nrOfChannels=c->m_nb_signals;
137         cinfo.m_streamFormat=c->m_stream_format;
138         cinfo.m_name=c->getName();
139
140         debugOutput(DEBUG_LEVEL_VERBOSE, "Adding cluster idx=%2d type=%02X nbch=%2d fmt=%02X name=%s\n",
141             cinfo.m_index, cinfo.m_portType, cinfo.m_nrOfChannels, cinfo.m_streamFormat, cinfo.m_name.c_str());
142
143         for ( AVCMusicClusterInfoBlock::SignalInfoVectorIterator sig_it
144                   = c->m_SignalInfos.begin();
145               sig_it != c->m_SignalInfos.end();
146               ++sig_it )
147         {
148             struct AVCMusicClusterInfoBlock::sSignalInfo s=(*sig_it);
149             struct Plug::ChannelInfo sinfo;
150
151             sinfo.m_streamPosition = s.stream_position;
152             sinfo.m_location = s.stream_location;
153
154             AVCMusicPlugInfoBlock *mplug = m_status_descriptor->getMusicPlugInfoBlock(s.music_plug_id);
155
156             if (mplug==NULL) {
157                 debugWarning("No music plug found for this signal\n");
158                 sinfo.m_name = "unknown";
159             } else {
160                 sinfo.m_name = mplug->getName();
161
162                 #if AVC_STREAMCONFIG_USE_MUSICPLUG
163                 if (plug.getDirection() == Plug::eAPD_Input) {
164                     // it's an input plug to the subunit
165                     // so we have to check the source field of the music plug
166                     if(s.stream_position != mplug->m_source_stream_position) {
167                         debugWarning("s.stream_position (= 0x%02X) != mplug->m_source_stream_position (= 0x%02X)\n",
168                             s.stream_position, mplug->m_source_stream_position);
169                         // use the one from the music plug
170                         sinfo.m_streamPosition= mplug->m_source_stream_position;
171                     }
172                     if(s.stream_location != mplug->m_source_stream_location) {
173                         debugWarning("s.stream_location (= 0x%02X) != mplug->m_source_stream_location (= 0x%02X)\n",
174                             s.stream_location, mplug->m_source_stream_location);
175                         // use the one from the music plug
176                         sinfo.m_location=mplug->m_source_stream_location;
177                     }
178                 } else if (plug.getDirection() == Plug::eAPD_Output) {
179                     // it's an output plug from the subunit
180                     // so we have to check the destination field of the music plug
181                     if(s.stream_position != mplug->m_dest_stream_position) {
182                         debugWarning("s.stream_position (= 0x%02X) != mplug->m_dest_stream_position (= 0x%02X)\n",
183                             s.stream_position, mplug->m_dest_stream_position);
184    
185                         // use the one from the music plug
186                         sinfo.m_streamPosition=mplug->m_dest_stream_position;
187                     }
188                     if(s.stream_location != mplug->m_dest_stream_location) {
189                         debugWarning("s.stream_location (= 0x%02X) != mplug->m_dest_stream_location (= 0x%02X)\n",
190                             s.stream_location, mplug->m_dest_stream_location);
191                         // use the one from the music plug
192                         //sinfo.m_location=mplug->m_dest_stream_location;
193                         // HACK: recent ECHO firmware only fills the AVCMusicClusterInfoBlock correctly
194                         sinfo.m_location=s.stream_location;
195                     }
196                 } else {
197                     debugWarning("Invalid plug direction.\n");
198                 }
199                 #endif
200             }
201
202             debugOutput(DEBUG_LEVEL_VERBOSE, "Adding signal pos=%2d loc=%2d name=%s\n",
203                 sinfo.m_streamPosition, sinfo.m_location, sinfo.m_name.c_str());
204
205             cinfo.m_channelInfos.push_back(sinfo);
206         }
207
208         idx++;
209         plug.getClusterInfos().push_back(cinfo);
210     }
211
212
213     return result;
214
215 }
216
217 bool
218 SubunitMusic::loadDescriptors()
219 {
220     bool result=true;
221     if (m_status_descriptor != NULL) {
222         result &= m_status_descriptor->load();
223     } else {
224         debugError("BUG: m_status_descriptor == NULL\n");
225         return false;
226     }
227     return result;
228 }
229
230 void
231 SubunitMusic::showMusicPlugs()
232 {
233     if(m_status_descriptor) {
234         unsigned int nbplugs = m_status_descriptor->getNbMusicPlugs();
235         printf( "digraph musicplugconnections {\n" );
236
237         for(unsigned int i=0;i<nbplugs;i++) {
238             AVCMusicPlugInfoBlock *mplug = m_status_descriptor->getMusicPlugInfoBlock(i);
239             if(mplug==NULL) {
240                 debugError("NULL plug!\n");
241                 return;
242             }
243             char plugstr[32];
244             snprintf(plugstr, 32, "MusicPlug %d", mplug->m_music_plug_id);
245
246             // the plug itself
247             printf( "\t\"%s\" [color=red,style=filled];\n",
248                     plugstr );
249
250             Plug * plug;
251             // the source connection (where it's signal originates)
252             plug = m_unit->getPlugManager().getPlug( eST_Music, 0,
253                                                      0xFF, 0xFF,
254                                                      Plug::eAPA_SubunitPlug,
255                                                      Plug::eAPD_Input,
256                                                      mplug->m_source_plug_id);
257             if(plug) {
258                 printf( "\t\"(%d) %s\" -> \"%s\"\n",
259                         plug->getGlobalId(),
260                         plug->getName(),
261                         plugstr );
262             } else {
263                 debugWarning("Destination plug not found\n");
264             }
265
266             // the destination connection (where it's signal goes)
267             plug = m_unit->getPlugManager().getPlug( eST_Music, 0,
268                                                      0xFF, 0xFF,
269                                                      Plug::eAPA_SubunitPlug,
270                                                      Plug::eAPD_Output,
271                                                      mplug->m_dest_plug_id);
272             if(plug) {
273                
274                 printf( "\t\"%s\" -> \"(%d) %s\"\n",
275                         plugstr,
276                         plug->getGlobalId(),
277                         plug->getName() );
278             } else {
279                 debugWarning("Source plug not found\n");
280             }
281    
282         }
283        
284         printf("}\n" );
285         printf( "Use \"dot -Tps FILENAME.dot -o FILENAME.ps\" "
286                 "to generate graph\n");
287     }
288 }
289
290 void
291 SubunitMusic::setVerboseLevel(int l)
292 {
293     Subunit::setVerboseLevel(l);
294     if (m_status_descriptor != NULL) {
295         m_status_descriptor->setVerboseLevel(l);
296     }
297 }
298
299 const char*
300 SubunitMusic::getName()
301 {
302     return "MusicSubunit";
303 }
304
305 bool
306 SubunitMusic::serializeChild( Glib::ustring basePath,
307                               Util::IOSerialize& ser ) const
308 {
309     return true;
310 }
311
312 bool
313 SubunitMusic::deserializeChild( Glib::ustring basePath,
314                                 Util::IODeserialize& deser,
315                                 Unit& unit )
316 {
317     return true;
318 }
319
320 bool
321 SubunitMusic::deserializeUpdateChild( Glib::ustring basePath,
322                                       Util::IODeserialize& deser )
323 {
324     return true;
325 }
326
327 }
Note: See TracBrowser for help on using the browser.