root/branches/libfreebob-2.0/src/libstreaming/IsoHandler.cpp

Revision 201, 10.9 kB (checked in by pieterpalmers, 18 years ago)

backup commit

Line 
1 /* $Id$ */
2
3 /*
4  *   FreeBob Streaming API
5  *   FreeBob = Firewire (pro-)audio for linux
6  *
7  *   http://freebob.sf.net
8  *
9  *   Copyright (C) 2006 Pieter Palmers <pieterpalmers@users.sourceforge.net>
10  *
11  *   This program is free software {} you can redistribute it and/or modify
12  *   it under the terms of the GNU General Public License as published by
13  *   the Free Software Foundation {} either version 2 of the License, or
14  *   (at your option) any later version.
15  *
16  *   This program is distributed in the hope that it will be useful,
17  *   but WITHOUT ANY WARRANTY {} without even the implied warranty of
18  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  *   GNU General Public License for more details.
20  *
21  *   You should have received a copy of the GNU General Public License
22  *   along with this program {} if not, write to the Free Software
23  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24  *
25  *
26  *
27  */
28
29 #include "IsoHandler.h"
30 #include "IsoStream.h"
31 #include <errno.h>
32 #include <netinet/in.h>
33
34 #include <iostream>
35 using namespace std;
36
37
38 namespace FreebobStreaming
39 {
40
41 IMPL_DEBUG_MODULE( IsoHandler, IsoHandler, DEBUG_LEVEL_NORMAL );
42
43 /* the C callbacks */
44 enum raw1394_iso_disposition
45 IsoXmitHandler::iso_transmit_handler(raw1394handle_t handle,
46                 unsigned char *data, unsigned int *length,
47                 unsigned char *tag, unsigned char *sy,
48                 int cycle, unsigned int dropped) {
49
50         IsoXmitHandler *xmitHandler=static_cast<IsoXmitHandler *>(raw1394_get_userdata(handle));
51         assert(xmitHandler);
52
53         return xmitHandler->getPacket(data, length, tag, sy, cycle, dropped);
54 }
55
56 enum raw1394_iso_disposition
57 IsoRecvHandler::iso_receive_handler(raw1394handle_t handle, unsigned char *data,
58                                                 unsigned int length, unsigned char channel,
59                                                 unsigned char tag, unsigned char sy, unsigned int cycle,
60                                                 unsigned int dropped) {
61
62         IsoRecvHandler *recvHandler=static_cast<IsoRecvHandler *>(raw1394_get_userdata(handle));
63         assert(recvHandler);
64
65         return recvHandler->putPacket(data, length, channel, tag, sy, cycle, dropped);
66 }
67
68 /* Base class implementation */
69 bool
70 IsoHandler::initialize()
71 {
72         debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
73
74     m_handle = raw1394_new_handle_on_port( m_port );
75     if ( !m_handle ) {
76         if ( !errno ) {
77             cerr << "libraw1394 not compatible" << endl;
78         } else {
79             perror( "IsoHandler::Initialize: Could not get 1394 handle" );
80             cerr << "Is ieee1394 and raw1394 driver loaded?" << endl;
81         }
82         return false;
83     }
84
85         raw1394_set_userdata(m_handle, static_cast<void *>(this));
86
87     return true;
88 }
89
90 void IsoHandler::stop()
91 {
92         debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
93         raw1394_iso_stop(m_handle);
94 };
95
96 /* Child class implementations */
97
98 IsoRecvHandler::IsoRecvHandler(int port)
99                 : IsoHandler(port), m_Client(0)
100 {
101         debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
102 }
103 IsoRecvHandler::IsoRecvHandler(int port, unsigned int buf_packets,
104                                unsigned int max_packet_size, int irq)
105                 : IsoHandler(port, buf_packets,max_packet_size,irq), m_Client(0)
106 {
107         debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
108
109 }
110 IsoRecvHandler::~IsoRecvHandler()
111 {
112         raw1394_iso_shutdown(m_handle);
113
114 }
115
116 bool
117 IsoRecvHandler::initialize() {
118         debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
119
120         IsoHandler *base=static_cast<IsoHandler *>(this);
121
122         if(!(base->initialize())) {
123                 return false;
124         }
125
126         raw1394_set_userdata(m_handle, static_cast<void *>(this));
127
128         return true;
129
130 }
131
132 enum raw1394_iso_disposition IsoRecvHandler::putPacket(unsigned char *data, unsigned int length,
133                               unsigned char channel, unsigned char tag, unsigned char sy,
134                                   unsigned int cycle, unsigned int dropped) {
135
136         debugOutput( DEBUG_LEVEL_VERY_VERBOSE,
137                      "received packet: length=%d, channel=%d, cycle=%d\n",
138                      length, channel, cycle );
139         m_packetcount++;
140
141         if(m_Client) {
142                 if(m_Client->putPacket(data, length, channel, tag, sy, cycle, dropped)) {
143 //                      return RAW1394_ISO_AGAIN;
144                 }
145         }
146        
147         return RAW1394_ISO_OK;
148 }
149
150 int IsoRecvHandler::registerStream(IsoStream *stream)
151 {
152         assert(stream);
153         debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
154
155         if (m_Client) return -1;
156
157         m_Client=stream;
158
159         raw1394_iso_shutdown(m_handle);
160
161         if(raw1394_iso_recv_init(m_handle,   iso_receive_handler,
162                                          m_buf_packets,
163                                          m_max_packet_size,
164                                              m_Client->getChannel(),
165                                              RAW1394_DMA_BUFFERFILL,
166                                          m_irq_interval)) {
167                 debugFatal("Could not do receive initialisation!\n" );
168
169                 return -1;
170         }
171
172         return 0;
173
174 }
175
176 int IsoRecvHandler::unregisterStream(IsoStream *stream)
177 {
178         assert(stream);
179         debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
180
181         if(stream != m_Client) return -1; //not registered
182
183         m_Client=0;
184         return 0;
185
186 }
187
188 int IsoRecvHandler::start(int cycle)
189 {
190         debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
191         return raw1394_iso_recv_start(m_handle, cycle, -1, 0);
192 }
193
194 /* ----------------- XMIT --------------- */
195
196 IsoXmitHandler::IsoXmitHandler(int port)
197                 : IsoHandler(port), m_Client(0), m_prebuffers(0)
198 {
199         debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
200
201 }
202 IsoXmitHandler::IsoXmitHandler(int port, unsigned int buf_packets,
203                                unsigned int max_packet_size, int irq)
204                 : IsoHandler(port, buf_packets, max_packet_size,irq),
205                   m_Client(0), m_speed(RAW1394_ISO_SPEED_400), m_prebuffers(0)
206 {
207         debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
208
209 }
210 IsoXmitHandler::IsoXmitHandler(int port, unsigned int buf_packets,
211                                unsigned int max_packet_size, int irq,
212                                enum raw1394_iso_speed speed)
213                 : IsoHandler(port, buf_packets,max_packet_size,irq),
214                   m_Client(0), m_speed(speed), m_prebuffers(0)
215 {
216         debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
217
218 }
219
220 IsoXmitHandler::~IsoXmitHandler()
221 {
222         debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
223         raw1394_iso_shutdown(m_handle);
224
225 }
226
227 bool
228 IsoXmitHandler::initialize() {
229
230         debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
231         IsoHandler *base=static_cast<IsoHandler *>(this);
232
233         if(!(base->initialize())) {
234                 return false;
235         }
236
237         raw1394_set_userdata(m_handle, static_cast<void *>(this));
238
239         // this is a dummy init, to see if everything works
240         // the real init is done when a stream is registered
241         if(raw1394_iso_xmit_init(m_handle,
242                              iso_transmit_handler,
243                              m_buf_packets,
244                              m_max_packet_size,
245                                  0,
246                                  m_speed,
247                              m_irq_interval)) {
248                 debugFatal("Could not do xmit initialisation!\n" );
249
250                 return false;
251         }
252
253         return true;
254
255 }
256
257 enum raw1394_iso_disposition IsoXmitHandler::getPacket(unsigned char *data, unsigned int *length,
258                               unsigned char *tag, unsigned char *sy,
259                               int cycle, unsigned int dropped) {
260
261         debugOutput( DEBUG_LEVEL_VERY_VERBOSE,
262                      "sending packet: length=%d, cycle=%d\n",
263                      *length, cycle );
264         m_packetcount++;
265
266         if(m_Client) {
267         if(m_Client->getPacket(data, length, tag, sy, cycle, dropped, m_max_packet_size)) {
268 //                      return RAW1394_ISO_AGAIN;
269                 }
270         }
271
272         return RAW1394_ISO_OK;
273 }
274
275 // an xmit handler can have only one source IsoStream
276 int IsoXmitHandler::registerStream(IsoStream *stream)
277 {
278         assert(stream);
279         debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
280
281         if (m_Client) return -1;
282
283         m_Client=stream;
284
285         raw1394_iso_shutdown(m_handle);
286
287         if(raw1394_iso_xmit_init(m_handle,
288                              iso_transmit_handler,
289                              m_buf_packets,
290                              m_max_packet_size,
291                                  m_Client->getChannel(),
292                                  m_speed,
293                              m_irq_interval)) {
294                 debugFatal("Could not do xmit initialisation!\n" );
295
296                 return -1;
297         }
298
299         return 0;
300
301 }
302
303 int IsoXmitHandler::unregisterStream(IsoStream *stream)
304 {
305         assert(stream);
306         debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
307
308         if(stream != m_Client) return -1; //not registered
309
310         m_Client=0;
311         return 0;
312
313 }
314
315 int IsoXmitHandler::start(int cycle)
316 {
317         debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
318         return raw1394_iso_xmit_start(m_handle, cycle, m_prebuffers);
319 }
320
321 }
322
323 /* multichannel receive  */
324 #if 0
325 IsoRecvHandler::IsoRecvHandler(int port)
326                 : IsoHandler(port)
327 {
328         debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
329 }
330 IsoRecvHandler::IsoRecvHandler(int port, unsigned int buf_packets,
331                                unsigned int max_packet_size, int irq)
332                 : IsoHandler(port, buf_packets,max_packet_size,irq)
333 {
334         debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
335
336 }
337 IsoRecvHandler::~IsoRecvHandler()
338 {
339         raw1394_iso_shutdown(m_handle);
340
341 }
342
343 bool
344 IsoRecvHandler::initialize() {
345         debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
346
347         IsoHandler *base=static_cast<IsoHandler *>(this);
348
349         if(!(base->initialize())) {
350                 return false;
351         }
352
353         raw1394_set_userdata(m_handle, static_cast<void *>(this));
354
355         if(raw1394_iso_multichannel_recv_init(m_handle,
356                                          iso_receive_handler,
357                                          m_buf_packets,
358                                          m_max_packet_size,
359                                          m_irq_interval)) {
360                 debugFatal("Could not do multichannel receive initialisation!\n" );
361
362                 return false;
363         }
364
365         return true;
366
367 }
368
369 enum raw1394_iso_disposition IsoRecvHandler::putPacket(unsigned char *data, unsigned int length,
370                               unsigned char channel, unsigned char tag, unsigned char sy,
371                                   unsigned int cycle, unsigned int dropped) {
372
373         debugOutput( DEBUG_LEVEL_VERY_VERBOSE,
374                      "received packet: length=%d, channel=%d, cycle=%d\n",
375                      length, channel, cycle );
376        
377         return RAW1394_ISO_OK;
378 }
379
380 // an recv handler can have multiple destination IsoStreams
381 // NOTE: this implementation even allows for already registered
382 // streams to be registered again.
383 int IsoRecvHandler::registerStream(IsoRecvStream *stream)
384 {
385         assert(stream);
386         debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
387
388         m_Clients.push_back(stream);
389
390         listen(stream->getChannel());
391         return 0;
392
393 }
394
395 int IsoRecvHandler::unregisterStream(IsoRecvStream *stream)
396 {
397         assert(stream);
398         debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
399
400     for ( IsoRecvStreamVectorIterator it = m_Clients.begin();
401           it != m_Clients.end();
402           ++it )
403     {
404         IsoRecvStream* s = *it;
405         if ( s == stream ) {
406                         unListen(s->getChannel());
407             m_Clients.erase(it);
408                         return 0;
409         }
410     }
411
412         return -1; //not found
413
414 }
415
416 void IsoRecvHandler::listen(int channel) {
417         int retval;
418         debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
419
420         retval=raw1394_iso_recv_listen_channel(m_handle, channel);
421
422 }
423
424 void IsoRecvHandler::unListen(int channel) {
425         int retval;
426         debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
427
428         retval=raw1394_iso_recv_unlisten_channel(m_handle, channel);
429
430 }
431
432 int IsoRecvHandler::start(int cycle)
433 {
434         debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
435         return raw1394_iso_recv_start(m_handle, cycle, -1, 0);
436 }
437 #endif
Note: See TracBrowser for help on using the browser.