root/branches/streaming-rework/src/bounce/bounce_avdevice.cpp

Revision 405, 11.1 kB (checked in by pieterpalmers, 16 years ago)

- fix some small bugs in ieee1394service and configrom
- modify bounce device's discovery routine

Line 
1 /* bounce_avdevice.cpp
2  * Copyright (C) 2006 by Pieter Palmers
3  * Copyright (C) 2006 by Daniel Wagner
4  *
5  * This file is part of FreeBoB.
6  *
7  * FreeBoB is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  * FreeBoB 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 FreeBoB; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
19  * MA 02111-1307 USA.
20  */
21
22 #ifdef ENABLE_BOUNCE
23
24 #include "bounce/bounce_avdevice.h"
25 #include "configrom.h"
26
27 #include "libfreebobavc/avc_plug_info.h"
28 #include "libfreebobavc/avc_extended_plug_info.h"
29 #include "libfreebobavc/avc_subunit_info.h"
30 #include "libfreebobavc/avc_extended_stream_format.h"
31 #include "libfreebobavc/avc_serialize.h"
32 #include "libfreebobavc/ieee1394service.h"
33 #include "libfreebobavc/avc_definitions.h"
34
35 #include "debugmodule/debugmodule.h"
36
37 #include <iostream>
38 #include <sstream>
39 #include <stdint.h>
40
41 #include <string>
42 #include <netinet/in.h>
43
44 namespace Bounce {
45
46 // to define the supported devices
47 static VendorModelEntry supportedDeviceList[] =
48 {
49     {0x0B0001, 0x0B0001, 0x0B0001, "FreeBoB", "Bounce"},
50 };
51
52 IMPL_DEBUG_MODULE( BounceDevice, BounceDevice, DEBUG_LEVEL_VERBOSE );
53
54
55 BounceDevice::BounceDevice( std::auto_ptr< ConfigRom >( configRom ),
56                             Ieee1394Service& ieee1394service,
57                             int nodeId,
58                             int verboseLevel )
59     : m_configRom( configRom )
60     , m_1394Service( &ieee1394service )
61     , m_nodeId( nodeId )
62     , m_verboseLevel( verboseLevel )
63     , m_samplerate (44100)
64     , m_model( NULL )
65     , m_id(0)
66     , m_receiveProcessor ( 0 )
67     , m_receiveProcessorBandwidth ( -1 )
68     , m_transmitProcessor ( 0 )
69     , m_transmitProcessorBandwidth ( -1 )
70 {
71     setDebugLevel( verboseLevel );
72
73     debugOutput( DEBUG_LEVEL_VERBOSE, "Created Bounce::BounceDevice (NodeID %d)\n",
74                  nodeId );
75 }
76
77 BounceDevice::~BounceDevice()
78 {
79
80 }
81
82 ConfigRom&
83 BounceDevice::getConfigRom() const
84 {
85     return *m_configRom;
86 }
87
88 bool
89 BounceDevice::probe( ConfigRom& configRom )
90 {
91 //     unsigned int vendorId = configRom.getNodeVendorId();
92     unsigned int modelId = configRom.getModelId();
93     unsigned int unitSpecifierId = configRom.getUnitSpecifierId();
94
95     for ( unsigned int i = 0;
96           i < ( sizeof( supportedDeviceList )/sizeof( VendorModelEntry ) );
97           ++i )
98     {
99         if (
100 //             ( supportedDeviceList[i].vendor_id == vendorId )
101              ( supportedDeviceList[i].model_id == modelId )
102              && ( supportedDeviceList[i].unit_specifier_id == unitSpecifierId )
103            )
104         {
105             return true;
106         }
107     }
108
109     return false;
110 }
111
112 bool
113 BounceDevice::discover()
114 {
115 //      unsigned int resp_len=0;
116 //      quadlet_t request[6];
117 //      quadlet_t *resp;
118
119 //     unsigned int vendorId = m_configRom->getNodeVendorId();
120     unsigned int modelId = m_configRom->getModelId();
121     unsigned int unitSpecifierId = m_configRom->getUnitSpecifierId();
122
123     for ( unsigned int i = 0;
124           i < ( sizeof( supportedDeviceList )/sizeof( VendorModelEntry ) );
125           ++i )
126     {
127         if ( //( supportedDeviceList[i].vendor_id == vendorId )
128              ( supportedDeviceList[i].model_id == modelId )
129              && ( supportedDeviceList[i].unit_specifier_id == unitSpecifierId )
130            )
131         {
132             m_model = &(supportedDeviceList[i]);
133         }
134     }
135
136     if (m_model != NULL) {
137         debugOutput( DEBUG_LEVEL_VERBOSE, "found %s %s\n",
138                 m_model->vendor_name, m_model->model_name);
139         return true;
140     }
141    
142     debugOutput( DEBUG_LEVEL_VERBOSE, "Discovering...\n" );
143
144         std::string vendor=std::string(FREEBOB_BOUNCE_SERVER_VENDORNAME);
145         std::string model=std::string(FREEBOB_BOUNCE_SERVER_MODELNAME);
146
147         if (!(m_configRom->getVendorName().compare(0,vendor.length(),vendor,0,vendor.length())==0)
148             || !(m_configRom->getModelName().compare(0,model.length(),model,0,model.length())==0)) {
149                 return false;
150         }
151 /*
152 // AVC1394_COMMAND_INPUT_PLUG_SIGNAL_FORMAT
153         request[0] = htonl( AVC1394_CTYPE_STATUS | (AVC1394_SUBUNIT_TYPE_FREEBOB_BOUNCE_SERVER << 19) | (0 << 16)
154                         | AVC1394_COMMAND_INPUT_PLUG_SIGNAL_FORMAT | 0x00);
155
156         request[1] =  0xFFFFFFFF;
157         resp = m_1394Service->transactionBlock( m_nodeId,
158                                                        request,
159                                                        2,
160                                                                &resp_len );
161 //      hexDump((unsigned char *)request,6*4);
162         if(resp) {
163                 char *buffer=(char *)&resp[1];
164                 resp[resp_len-1]=0;
165                 xmlDescription=buffer;
166 //              hexDump((unsigned char *)resp,6*4);
167         }
168 */
169         return true;
170 }
171
172 int BounceDevice::getSamplingFrequency( ) {
173     return m_samplerate;
174 }
175
176 bool BounceDevice::setSamplingFrequency( ESamplingFrequency samplingFrequency ) {
177     int retval=convertESamplingFrequency( samplingFrequency );
178     if (retval) {
179         m_samplerate=retval;
180         return true;
181     } else return false;
182 }
183
184 bool BounceDevice::setId( unsigned int id) {
185     debugOutput( DEBUG_LEVEL_VERBOSE, "Set id to %d...\n", id);
186     m_id=id;
187     return true;
188 }
189
190 void
191 BounceDevice::showDevice() const
192 {
193     debugOutput(DEBUG_LEVEL_NORMAL, "\nI am the bouncedevice, the bouncedevice I am...\n" );
194     debugOutput(DEBUG_LEVEL_NORMAL, "Vendor            :  %s\n", m_configRom->getVendorName().c_str());
195     debugOutput(DEBUG_LEVEL_NORMAL, "Model             :  %s\n", m_configRom->getModelName().c_str());
196     debugOutput(DEBUG_LEVEL_NORMAL, "Vendor Name       :  %s\n", m_model->vendor_name);
197     debugOutput(DEBUG_LEVEL_NORMAL, "Model Name        :  %s\n", m_model->model_name);
198     debugOutput(DEBUG_LEVEL_NORMAL, "Node              :  %d\n", m_nodeId);
199     debugOutput(DEBUG_LEVEL_NORMAL, "GUID              :  0x%016llX\n", m_configRom->getGuid());
200     debugOutput(DEBUG_LEVEL_NORMAL, "AVC test response :  %s\n", xmlDescription.c_str());
201     debugOutput(DEBUG_LEVEL_NORMAL, "\n" );
202 }
203
204 bool
205 BounceDevice::addXmlDescription( xmlNodePtr deviceNode )
206 {
207
208     return false;
209
210 }
211
212 #define BOUNCE_NR_OF_CHANNELS 2
213
214 bool
215 BounceDevice::addPortsToProcessor(
216         FreebobStreaming::StreamProcessor *processor,
217         FreebobStreaming::AmdtpAudioPort::E_Direction direction) {
218
219     debugOutput(DEBUG_LEVEL_VERBOSE,"Adding ports to processor\n");
220
221     int i=0;
222     for (i=0;i<BOUNCE_NR_OF_CHANNELS;i++) {
223         char *buff;
224         asprintf(&buff,"dev%d%s_Port%d",m_id,direction==FreebobStreaming::AmdtpAudioPort::E_Playback?"p":"c",i);
225
226         FreebobStreaming::Port *p=NULL;
227         p=new FreebobStreaming::AmdtpAudioPort(
228                 buff,
229                 direction,
230                 // \todo: streaming backend expects indexing starting from 0
231                 // but bebob reports it starting from 1. Decide where
232                 // and how to handle this (pp: here)
233                 i,
234                 0,
235                 FreebobStreaming::AmdtpPortInfo::E_MBLA,
236                 0
237         );
238
239         if (!p) {
240             debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n",buff);
241         } else {
242
243             if (!processor->addPort(p)) {
244                 debugWarning("Could not register port with stream processor\n");
245                 free(buff);
246                 return false;
247             } else {
248                 debugOutput(DEBUG_LEVEL_VERBOSE, "Added port %s\n",buff);
249
250             }
251         }
252
253         free(buff);
254
255      }
256
257         return true;
258 }
259
260 bool
261 BounceDevice::prepare() {
262
263     debugOutput(DEBUG_LEVEL_NORMAL, "Preparing BounceDevice...\n" );
264
265         m_receiveProcessor=new FreebobStreaming::AmdtpReceiveStreamProcessor(
266                                  m_1394Service->getPort(),
267                                  m_samplerate,
268                                  BOUNCE_NR_OF_CHANNELS);
269
270         if(!m_receiveProcessor->init()) {
271                 debugFatal("Could not initialize receive processor!\n");
272                 return false;
273
274         }
275
276         if (!addPortsToProcessor(m_receiveProcessor,
277                 FreebobStreaming::AmdtpAudioPort::E_Capture)) {
278                 debugFatal("Could not add ports to processor!\n");
279                 return false;
280         }
281
282         // do the transmit processor
283         m_transmitProcessor=new FreebobStreaming::AmdtpTransmitStreamProcessor(
284                                  m_1394Service->getPort(),
285                                  m_samplerate,
286                                  BOUNCE_NR_OF_CHANNELS);
287
288         m_transmitProcessor->setVerboseLevel(getDebugLevel());
289
290         if(!m_transmitProcessor->init()) {
291                 debugFatal("Could not initialize transmit processor!\n");
292                 return false;
293
294         }
295
296         if (!addPortsToProcessor(m_transmitProcessor,
297                 FreebobStreaming::AmdtpAudioPort::E_Playback)) {
298                 debugFatal("Could not add ports to processor!\n");
299                 return false;
300         }
301
302         return true;
303 }
304
305 int
306 BounceDevice::getStreamCount() {
307         return 2; // one receive, one transmit
308 }
309
310 FreebobStreaming::StreamProcessor *
311 BounceDevice::getStreamProcessorByIndex(int i) {
312         switch (i) {
313         case 0:
314                 return m_receiveProcessor;
315         case 1:
316                 return m_transmitProcessor;
317         default:
318                 return NULL;
319         }
320         return 0;
321 }
322
323 int
324 BounceDevice::startStreamByIndex(int i) {
325 //      int iso_channel=0;
326 //      int plug=0;
327 //      int hostplug=-1;
328 //
329         switch (i) {
330         case 0:
331 //              // do connection management: make connection
332 //              iso_channel = iec61883_cmp_connect(
333 //                      m_1394Service->getHandle(),
334 //                      m_nodeId | 0xffc0,
335 //                      &plug,
336 //                      raw1394_get_local_id (m_1394Service->getHandle()),
337 //                      &hostplug,
338 //                      &m_receiveProcessorBandwidth);
339 //
340 //              // set the channel obtained by the connection management
341                 m_receiveProcessor->setChannel(1);
342                 break;
343         case 1:
344 //              // do connection management: make connection
345 //              iso_channel = iec61883_cmp_connect(
346 //                      m_1394Service->getHandle(),
347 //                      raw1394_get_local_id (m_1394Service->getHandle()),
348 //                      &hostplug,
349 //                      m_nodeId | 0xffc0,
350 //                      &plug,
351 //                      &m_transmitProcessorBandwidth);
352 //
353 //              // set the channel obtained by the connection management
354 // //           m_receiveProcessor2->setChannel(iso_channel);
355                 m_transmitProcessor->setChannel(0);
356                 break;
357         default:
358                 return -1;
359         }
360
361         return 0;
362
363 }
364
365 int
366 BounceDevice::stopStreamByIndex(int i) {
367         // do connection management: break connection
368
369 //      int plug=0;
370 //      int hostplug=-1;
371 //
372 //      switch (i) {
373 //      case 0:
374 //              // do connection management: break connection
375 //              iec61883_cmp_disconnect(
376 //                      m_1394Service->getHandle(),
377 //                      m_nodeId | 0xffc0,
378 //                      plug,
379 //                      raw1394_get_local_id (m_1394Service->getHandle()),
380 //                      hostplug,
381 //                      m_receiveProcessor->getChannel(),
382 //                      m_receiveProcessorBandwidth);
383 //
384 //              break;
385 //      case 1:
386 //              // do connection management: break connection
387 //              iec61883_cmp_disconnect(
388 //                      m_1394Service->getHandle(),
389 //                      raw1394_get_local_id (m_1394Service->getHandle()),
390 //                      hostplug,
391 //                      m_nodeId | 0xffc0,
392 //                      plug,
393 //                      m_transmitProcessor->getChannel(),
394 //                      m_transmitProcessorBandwidth);
395 //
396 //              // set the channel obtained by the connection management
397 // //           m_receiveProcessor2->setChannel(iso_channel);
398 //              break;
399 //      default:
400 //              return 0;
401 //      }
402
403         return 0;
404 }
405
406 } // namespace
407
408 #endif // #ifdef ENABLE_BOUNCE
Note: See TracBrowser for help on using the browser.