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

Revision 227, 30.7 kB (checked in by pieterpalmers, 17 years ago)

- another day of good progress comes to and end...
- compiles and runs, only the midi stuff and the xrun handling remain.

I'll also have to rework the C API somewhat.

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) 2005,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 "AmdtpStreamProcessor.h"
30 #include "Port.h"
31 #include "AmdtpPort.h"
32
33 #include <netinet/in.h>
34 #include <assert.h>
35
36
37 namespace FreebobStreaming {
38
39 IMPL_DEBUG_MODULE( AmdtpTransmitStreamProcessor, AmdtpTransmitStreamProcessor, DEBUG_LEVEL_NORMAL );
40 IMPL_DEBUG_MODULE( AmdtpReceiveStreamProcessor, AmdtpReceiveStreamProcessor, DEBUG_LEVEL_NORMAL );
41
42
43 /* transmit */
44 AmdtpTransmitStreamProcessor::AmdtpTransmitStreamProcessor(int port, int framerate, int dimension)
45         : TransmitStreamProcessor(port, framerate), m_dimension(dimension) {
46
47
48 }
49
50 AmdtpTransmitStreamProcessor::~AmdtpTransmitStreamProcessor() {
51         freebob_ringbuffer_free(m_event_buffer);
52         free(m_cluster_buffer);
53 }
54
55 bool AmdtpTransmitStreamProcessor::init() {
56
57         debugOutput( DEBUG_LEVEL_VERBOSE, "Initializing (%p)...\n");
58         // call the parent init
59         // this has to be done before allocating the buffers,
60         // because this sets the buffersizes from the processormanager
61         if(!TransmitStreamProcessor::init()) {
62                 debugFatal("Could not do base class init (%p)\n",this);
63                 return false;
64         }
65        
66
67         return true;
68 }
69
70 void AmdtpTransmitStreamProcessor::setVerboseLevel(int l) {
71         setDebugLevel(l);
72         TransmitStreamProcessor::setVerboseLevel(l);
73 }
74
75
76 int AmdtpTransmitStreamProcessor::getPacket(unsigned char *data, unsigned int *length,
77                       unsigned char *tag, unsigned char *sy,
78                       int cycle, unsigned int dropped, unsigned int max_length) {
79
80         struct iec61883_packet *packet = (struct iec61883_packet *) data;
81        
82         // signal that we are running (a transmit stream is always 'runnable')
83         m_running=true;
84        
85         // don't process the stream when it is not enabled.
86         // however, we do have to generate (semi) valid packets
87         // that means that we'll send NODATA packets FIXME: check!!
88         if(m_disabled) {
89                 iec61883_cip_fill_header_nodata(getNodeId(), &m_cip_status, packet);
90                 *length = 0; // this is to disable sending
91                 *tag = IEC61883_TAG_WITH_CIP;
92                 *sy = 0;
93                 return (int)RAW1394_ISO_OK;
94         }
95                
96         // construct the packet cip
97         int nevents = iec61883_cip_fill_header (getNodeId(), &m_cip_status, packet);
98
99         enum raw1394_iso_disposition retval = RAW1394_ISO_OK;
100
101         if (!(nevents > 0)) {
102                
103                 if (m_cip_status.mode == IEC61883_MODE_BLOCKING_EMPTY) {
104                         *length = 8;
105                         return (int)RAW1394_ISO_OK ;
106                 }
107                 else {
108                         nevents = m_cip_status.syt_interval;
109                 }
110         }
111        
112         int read_size=nevents*sizeof(quadlet_t)*m_dimension;
113
114         if ((freebob_ringbuffer_read(m_event_buffer,(char *)(data+8),read_size)) <
115                                 read_size)
116         {
117                 debugWarning("Transmit buffer underrun (cycle %d, FC=%d, PC=%d)\n",
118                              cycle, m_framecounter, m_handler->getPacketCount());
119                
120                 // signal underrun
121                 // FIXME: underrun signaling turned off!!
122                 m_xruns++;
123
124                 retval=RAW1394_ISO_DEFER;
125                 *length=0;
126
127         } else {
128                 retval=RAW1394_ISO_OK;
129                 *length = read_size + 8;
130                
131                 // process all ports that should be handled on a per-packet base
132                 // this is MIDI for AMDTP (due to the need of DBC)
133                 if (!encodePacketPorts((quadlet_t *)(data+8), nevents, packet->dbc)) {
134                         debugWarning("Problem encoding Packet Ports\n");
135                 }
136         }
137        
138         *tag = IEC61883_TAG_WITH_CIP;
139         *sy = 0;
140        
141         // update the frame counter
142         m_framecounter+=nevents;
143
144         return (int)retval;
145
146 }
147
148 bool AmdtpTransmitStreamProcessor::reset() {
149
150         debugOutput( DEBUG_LEVEL_VERBOSE, "Resetting...\n");
151
152         // reset the event buffer, discard all content
153         freebob_ringbuffer_reset(m_event_buffer);
154        
155         // reset all non-device specific stuff
156         // i.e. the iso stream and the associated ports
157         return TransmitStreamProcessor::reset();
158 }
159
160 bool AmdtpTransmitStreamProcessor::prepare() {
161
162         debugOutput( DEBUG_LEVEL_VERBOSE, "Preparing...\n");
163        
164         // prepare all non-device specific stuff
165         // i.e. the iso stream and the associated ports
166         if(!TransmitStreamProcessor::prepare()) {
167                 debugFatal("Could not prepare base class\n");
168                 return false;
169         }
170        
171         switch (m_framerate) {
172         case 32000:
173                 m_syt_interval = 8;
174                 m_fdf = IEC61883_FDF_SFC_32KHZ;
175                 break;
176         case 44100:
177                 m_syt_interval = 8;
178                 m_fdf = IEC61883_FDF_SFC_44K1HZ;
179                 break;
180         default:
181         case 48000:
182                 m_syt_interval = 8;
183                 m_fdf = IEC61883_FDF_SFC_48KHZ;
184                 break;
185         case 88200:
186                 m_syt_interval = 16;
187                 m_fdf = IEC61883_FDF_SFC_88K2HZ;
188                 break;
189         case 96000:
190                 m_syt_interval = 16;
191                 m_fdf = IEC61883_FDF_SFC_96KHZ;
192                 break;
193         case 176400:
194                 m_syt_interval = 32;
195                 m_fdf = IEC61883_FDF_SFC_176K4HZ;
196                 break;
197         case 192000:
198                 m_syt_interval = 32;
199                 m_fdf = IEC61883_FDF_SFC_192KHZ;
200                 break;
201         }
202        
203         iec61883_cip_init (
204                 &m_cip_status,
205                 IEC61883_FMT_AMDTP,
206                 m_fdf,
207                 m_framerate,
208                 m_dimension,
209                 m_syt_interval);
210
211         // allocate the event buffer
212         if( !(m_event_buffer=freebob_ringbuffer_create(
213                         (m_dimension * m_nb_buffers * m_period) * sizeof(quadlet_t)))) {
214                 debugFatal("Could not allocate memory event ringbuffer");
215 //              return -ENOMEM;
216                 return false;
217         }
218
219         // allocate the temporary cluster buffer
220         if( !(m_cluster_buffer=(char *)calloc(m_dimension,sizeof(quadlet_t)))) {
221                 debugFatal("Could not allocate temporary cluster buffer");
222                 freebob_ringbuffer_free(m_event_buffer);
223                 return false;
224 //              return -ENOMEM;
225         }
226
227         // set the parameters of ports we can:
228         // we want the audio ports to be period buffered,
229         // and the midi ports to be packet buffered
230         for ( PortVectorIterator it = m_Ports.begin();
231                   it != m_Ports.end();
232                   ++it )
233         {
234                 debugOutput(DEBUG_LEVEL_VERBOSE, "Setting up port %s\n",(*it)->getName().c_str());
235                 if(!(*it)->setBufferSize(m_period)) {
236                         debugFatal("Could not set buffer size to %d\n",m_period);
237                         return false;
238                 }
239                
240                
241                 switch ((*it)->getPortType()) {
242                         case Port::E_Audio:
243                                 if(!(*it)->setSignalType(Port::E_PeriodSignalled)) {
244                                         debugFatal("Could not set signal type to PeriodSignalling");
245                                         return false;
246                                 }
247                                 debugWarning("---------------- ! Doing hardcoded test setup ! --------------\n");
248                                 // buffertype and datatype are dependant on the API
249                                 if(!(*it)->setBufferType(Port::E_PointerBuffer)) {
250                                         debugFatal("Could not set buffer type");
251                                         return false;
252                                 }
253                                 if(!(*it)->useExternalBuffer(true)) {
254                                         debugFatal("Could not set external buffer usage");
255                                         return false;
256                                 }
257                                
258                                 if(!(*it)->setDataType(Port::E_Float)) {
259                                         debugFatal("Could not set data type");
260                                         return false;
261                                 }
262                                
263                                
264                                 break;
265                         case Port::E_Midi:
266                                 if(!(*it)->setSignalType(Port::E_PacketSignalled)) {
267                                         debugFatal("Could not set signal type to PeriodSignalling");
268                                         return false;
269                                 }
270                                 // buffertype and datatype are dependant on the API
271                                 debugWarning("---------------- ! Doing hardcoded test setup ! --------------\n");
272                                 // buffertype and datatype are dependant on the API
273                                 if(!(*it)->setBufferType(Port::E_RingBuffer)) {
274                                         debugFatal("Could not set buffer type");
275                                         return false;
276                                 }
277                                 if(!(*it)->setDataType(Port::E_MidiEvent)) {
278                                         debugFatal("Could not set data type");
279                                         return false;
280                                 }
281                                 break;
282                         default:
283                                 debugWarning("Unsupported port type specified\n");
284                                 break;
285                 }
286         }
287
288         // the API specific settings of the ports should already be set,
289         // as this is called from the processorManager->prepare()
290         // so we can init the ports
291         if(!initPorts()) {
292                 debugFatal("Could not initialize ports!\n");
293                 return false;
294         }
295
296         if(!preparePorts()) {
297                 debugFatal("Could not initialize ports!\n");
298                 return false;
299         }
300
301         // we should prefill the event buffer
302         // FIXME: i have to solve this otherwise because the ports aren't ready yet
303         // especially if there are no internal buffers=> segfault
304         int i=m_nb_buffers;
305         while(i--) {
306                 if(!transferSilence()) {
307                         debugFatal("Could not prefill transmit stream\n");
308                         return false;
309                 }
310         }
311        
312         debugOutput( DEBUG_LEVEL_VERBOSE, "Prepared for:\n");
313         debugOutput( DEBUG_LEVEL_VERBOSE, " Samplerate: %d, FDF: %d, DBS: %d, SYT: %d\n",
314                      m_framerate,m_fdf,m_dimension,m_syt_interval);
315         debugOutput( DEBUG_LEVEL_VERBOSE, " PeriodSize: %d, NbBuffers: %d\n",
316                      m_period,m_nb_buffers);
317         debugOutput( DEBUG_LEVEL_VERBOSE, " Port: %d, Channel: %d\n",
318                      m_port,m_channel);
319
320         return true;
321
322 }
323
324 bool AmdtpTransmitStreamProcessor::transferSilence() {
325         /* a naive implementation would look like this: */
326        
327         unsigned int write_size=m_period*sizeof(quadlet_t)*m_dimension;
328         char *dummybuffer=(char *)calloc(sizeof(quadlet_t),m_period*m_dimension);
329         transmitSilenceBlock(dummybuffer, m_period, 0);
330
331         if (freebob_ringbuffer_write(m_event_buffer,(char *)(dummybuffer),write_size) < write_size) {
332                 debugWarning("Could not write to event buffer\n");
333         }
334         return true;
335 }
336
337 bool AmdtpTransmitStreamProcessor::transfer() {
338
339         debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "Transferring period...\n");
340         // TODO: improve
341 /* a naive implementation would look like this:
342
343         unsigned int write_size=m_period*sizeof(quadlet_t)*m_dimension;
344         char *dummybuffer=(char *)calloc(sizeof(quadlet_t),m_period*m_dimension);
345         transmitBlock(dummybuffer, m_period, 0, 0);
346
347         if (freebob_ringbuffer_write(m_event_buffer,(char *)(dummybuffer),write_size) < write_size) {
348                 debugWarning("Could not write to event buffer\n");
349         }
350
351
352         free(dummybuffer);
353 */
354 /* but we're not that naive anymore... */
355         int xrun;
356         unsigned int offset=0;
357        
358         freebob_ringbuffer_data_t vec[2];
359         // we received one period of frames
360         // this is period_size*dimension of events
361         int events2write=m_period*m_dimension;
362         int bytes2write=events2write*sizeof(quadlet_t);
363
364         /* write events2write bytes to the ringbuffer
365         *  first see if it can be done in one read.
366         *  if so, ok.
367         *  otherwise write up to a multiple of clusters directly to the buffer
368         *  then do the buffer wrap around using ringbuffer_write
369         *  then write the remaining data directly to the buffer in a third pass
370         *  Make sure that we cannot end up on a non-cluster aligned position!
371         */
372         int cluster_size=m_dimension*sizeof(quadlet_t);
373
374         while(bytes2write>0) {
375                 int byteswritten=0;
376                
377                 unsigned int frameswritten=(m_period*cluster_size-bytes2write)/cluster_size;
378                 offset=frameswritten;
379                
380                 freebob_ringbuffer_get_write_vector(m_event_buffer, vec);
381                        
382                 if(vec[0].len==0) { // this indicates a full event buffer
383                         debugError("Event buffer overrun in processor %d\n",this);
384                         break;
385                 }
386                        
387                 /* if we don't take care we will get stuck in an infinite loop
388                 * because we align to a cluster boundary later
389                 * the remaining nb of bytes in one write operation can be
390                 * smaller than one cluster
391                 * this can happen because the ringbuffer size is always a power of 2
392                 */
393                 if(vec[0].len<cluster_size) {
394                        
395                         // encode to the temporary buffer
396                         xrun = transmitBlock(m_cluster_buffer, 1, offset);
397                        
398                         if(xrun<0) {
399                                 // xrun detected
400                                 debugError("Frame buffer underrun in processor %d\n",this);
401                                 break;
402                         }
403                                
404                         // use the ringbuffer function to write one cluster
405                         // the write function handles the wrap around.
406                         freebob_ringbuffer_write(m_event_buffer,
407                                                  m_cluster_buffer,
408                                                  cluster_size);
409                                
410                         // we advanced one cluster_size
411                         bytes2write-=cluster_size;
412                                
413                 } else { //
414                        
415                         if(bytes2write>vec[0].len) {
416                                 // align to a cluster boundary
417                                 byteswritten=vec[0].len-(vec[0].len%cluster_size);
418                         } else {
419                                 byteswritten=bytes2write;
420                         }
421                                
422                         xrun = transmitBlock(vec[0].buf,
423                                              byteswritten/cluster_size,
424                                              offset);
425                        
426                         if(xrun<0) {
427                                         // xrun detected
428                                 debugError("Frame buffer underrun in processor %d\n",this);
429                                 break;
430                         }
431
432                         freebob_ringbuffer_write_advance(m_event_buffer, byteswritten);
433                         bytes2write -= byteswritten;
434                 }
435                        
436                 // the bytes2write should always be cluster aligned
437                 assert(bytes2write%cluster_size==0);
438                        
439         }
440
441         return true;
442 }
443 /*
444  * write received events to the stream ringbuffers.
445  */
446
447 int AmdtpTransmitStreamProcessor::transmitBlock(char *data,
448                                            unsigned int nevents, unsigned int offset)
449 {
450         int problem=0;
451
452         for ( PortVectorIterator it = m_PeriodPorts.begin();
453           it != m_PeriodPorts.end();
454           ++it )
455     {
456
457                 //FIXME: make this into a static_cast when not DEBUG?
458
459                 AmdtpPortInfo *pinfo=dynamic_cast<AmdtpPortInfo *>(*it);
460                 assert(pinfo); // this should not fail!!
461
462                 switch(pinfo->getFormat()) {
463                 case AmdtpPortInfo::E_MBLA:
464                         if(encodePortToMBLAEvents(static_cast<AmdtpAudioPort *>(*it), (quadlet_t *)data, offset, nevents)) {
465                                 debugWarning("Could not encode port %s to MBLA events",(*it)->getName().c_str());
466                                 problem=1;
467                         }
468                         break;
469                 case AmdtpPortInfo::E_SPDIF: // still unimplemented
470                         break;
471                 default: // ignore
472                         break;
473                 }
474     }
475         return problem;
476
477 }
478
479 int AmdtpTransmitStreamProcessor::transmitSilenceBlock(char *data,
480                                            unsigned int nevents, unsigned int offset)
481 {
482         int problem=0;
483
484         for ( PortVectorIterator it = m_PeriodPorts.begin();
485           it != m_PeriodPorts.end();
486           ++it )
487     {
488
489                 //FIXME: make this into a static_cast when not DEBUG?
490
491                 AmdtpPortInfo *pinfo=dynamic_cast<AmdtpPortInfo *>(*it);
492                 assert(pinfo); // this should not fail!!
493
494                 switch(pinfo->getFormat()) {
495                 case AmdtpPortInfo::E_MBLA:
496                         if(encodeSilencePortToMBLAEvents(static_cast<AmdtpAudioPort *>(*it), (quadlet_t *)data, offset, nevents)) {
497                                 debugWarning("Could not encode port %s to MBLA events",(*it)->getName().c_str());
498                                 problem=1;
499                         }
500                         break;
501                 case AmdtpPortInfo::E_SPDIF: // still unimplemented
502                         break;
503                 default: // ignore
504                         break;
505                 }
506     }
507         return problem;
508
509 }
510
511 /**
512  * @brief decode a packet for the packet-based ports
513  *
514  * @param data Packet data
515  * @param nevents number of events in data (including events of other ports & port types)
516  * @param dbc DataBlockCount value for this packet
517  * @return true if all successfull
518  */
519 bool AmdtpTransmitStreamProcessor::encodePacketPorts(quadlet_t *data, unsigned int nevents, unsigned int dbc)
520 {
521         bool ok=true;
522         char byte;
523        
524         quadlet_t *target_event=NULL;
525         int j;
526        
527         for ( PortVectorIterator it = m_PacketPorts.begin();
528           it != m_PacketPorts.end();
529           ++it )
530         {
531
532 #ifdef DEBUG
533                 AmdtpPortInfo *pinfo=dynamic_cast<AmdtpPortInfo *>(*it);
534                 assert(pinfo); // this should not fail!!
535
536                 // the only packet type of events for AMDTP is MIDI in mbla
537                 assert(pinfo->getFormat()==AmdtpPortInfo::E_Midi);
538 #endif
539                
540                 AmdtpMidiPort *mp=static_cast<AmdtpMidiPort *>(*it);
541                
542                 // we encode this directly (no function call) due to the high frequency
543                 /* idea:
544                 spec says: current_midi_port=(dbc+j)%8;
545                 => if we start at (dbc+stream->location-1)%8 [due to location_min=1],
546                 we'll start at the right event for the midi port.
547                 => if we increment j with 8, we stay at the right event.
548                 */
549                 // FIXME: as we know in advance how big a packet is (syt_interval) we can
550                 //        predict how much loops will be present here
551                 // first prefill the buffer with NO_DATA's on all time muxed channels
552                
553                 for(j = (dbc & 0x07)+mp->getLocation()-1; j < nevents; j += 8) {
554                
555                         target_event=(quadlet_t *)(data + ((j * m_dimension) + mp->getPosition()));
556                        
557                         if(mp->canSend()) { // we can send a byte
558                                 mp->readEvent(&byte);
559                                 *target_event=htonl(
560                                         IEC61883_AM824_SET_LABEL((byte)<<16,
561                                                                  IEC61883_AM824_LABEL_MIDI_1X));
562                         } else {
563                                 // can't send a byte, either because there is no byte,
564                                 // or because this would exceed the maximum rate
565                                 *target_event=htonl(
566                                         IEC61883_AM824_SET_LABEL(0,IEC61883_AM824_LABEL_MIDI_NO_DATA));
567                         }
568                         mp->trigger();
569                 }
570
571         }
572        
573         return ok;
574 }
575
576
577 int AmdtpTransmitStreamProcessor::encodePortToMBLAEvents(AmdtpAudioPort *p, quadlet_t *data,
578                                            unsigned int offset, unsigned int nevents)
579 {
580         unsigned int j=0;
581
582         quadlet_t *target_event;
583
584         target_event=(quadlet_t *)(data + p->getPosition());
585
586         switch(p->getDataType()) {
587                 default:
588                 case Port::E_Int24:
589                         {
590                                 quadlet_t *buffer=(quadlet_t *)(p->getBufferAddress());
591
592                                 assert(nevents + offset <= p->getBufferSize());
593
594                                 buffer+=offset;
595
596                                 for(j = 0; j < nevents; j += 1) { // decode max nsamples
597                                         *target_event = htonl((*(buffer) & 0x00FFFFFF) | 0x40000000);
598                                         buffer++;
599                                         target_event += m_dimension;
600                                 }
601                         }
602                         break;
603                 case Port::E_Float:
604                         {
605                                 const float multiplier = (float)(0x7FFFFF00);
606                                 float *buffer=(float *)(p->getBufferAddress());
607
608                                 assert(nevents + offset <= p->getBufferSize());
609
610                                 buffer+=offset;
611
612                                 for(j = 0; j < nevents; j += 1) { // decode max nsamples               
613        
614                                         // don't care for overflow
615                                         float v = *buffer * multiplier;  // v: -231 .. 231
616                                         unsigned int tmp = ((int)v);
617                                         *target_event = htonl((tmp >> 8) | 0x40000000);
618                                        
619                                         buffer++;
620                                         target_event += m_dimension;
621                                 }
622                         }
623                         break;
624         }
625
626         return 0;
627 }
628 int AmdtpTransmitStreamProcessor::encodeSilencePortToMBLAEvents(AmdtpAudioPort *p, quadlet_t *data,
629                                            unsigned int offset, unsigned int nevents)
630 {
631         unsigned int j=0;
632
633         quadlet_t *target_event;
634
635         target_event=(quadlet_t *)(data + p->getPosition());
636
637         switch(p->getDataType()) {
638                 default:
639                 case Port::E_Int24:
640                 case Port::E_Float:
641                         {
642                                 for(j = 0; j < nevents; j += 1) { // decode max nsamples
643                                         *target_event = htonl(0x40000000);
644                                         target_event += m_dimension;
645                                 }
646                         }
647                         break;
648         }
649
650         return 0;
651 }
652
653 /* --------------------- RECEIVE ----------------------- */
654
655 AmdtpReceiveStreamProcessor::AmdtpReceiveStreamProcessor(int port, int framerate, int dimension)
656         : ReceiveStreamProcessor(port, framerate), m_dimension(dimension) {
657
658
659 }
660
661 AmdtpReceiveStreamProcessor::~AmdtpReceiveStreamProcessor() {
662         freebob_ringbuffer_free(m_event_buffer);
663         free(m_cluster_buffer);
664
665 }
666
667 bool AmdtpReceiveStreamProcessor::init() {
668         // call the parent init
669         // this has to be done before allocating the buffers,
670         // because this sets the buffersizes from the processormanager
671         if(!ReceiveStreamProcessor::init()) {
672                 debugFatal("Could not do base class init (%d)\n",this);
673                 return false;
674         }
675
676         return true;
677 }
678
679 int AmdtpReceiveStreamProcessor::putPacket(unsigned char *data, unsigned int length,
680                       unsigned char channel, unsigned char tag, unsigned char sy,
681                           unsigned int cycle, unsigned int dropped) {
682
683         enum raw1394_iso_disposition retval=RAW1394_ISO_OK;
684        
685         struct iec61883_packet *packet = (struct iec61883_packet *) data;
686         assert(packet);
687        
688         if((packet->fmt == 0x10) && (packet->fdf != 0xFF) && (packet->dbs>0) && (length>=2*sizeof(quadlet_t))) {
689                 unsigned int nevents=((length / sizeof (quadlet_t)) - 2)/packet->dbs;
690                
691                 // signal that we're running
692                 if(nevents) m_running=true;
693                
694                 // don't process the stream when it is not enabled.
695                 if(m_disabled) {
696                         return (int)RAW1394_ISO_OK;
697                 }
698                
699                
700                 unsigned int write_size=nevents*sizeof(quadlet_t)*m_dimension;
701                 // add the data payload to the ringbuffer
702                
703                 if (freebob_ringbuffer_write(m_event_buffer,(char *)(data+8),write_size) < write_size)
704                 {
705                         debugWarning("Buffer overrun!\n");
706                         m_xruns++;
707
708                         retval=RAW1394_ISO_DEFER;
709                 } else {
710                         retval=RAW1394_ISO_OK;
711                         // process all ports that should be handled on a per-packet base
712                         // this is MIDI for AMDTP (due to the need of DBC)
713                         if (!decodePacketPorts((quadlet_t *)(data+8), nevents, packet->dbc)) {
714                                 debugWarning("Problem decoding Packet Ports\n");
715                         }
716                 }
717
718                 debugOutput(DEBUG_LEVEL_VERY_VERBOSE,
719                         "RCV: CH = %d, FDF = %X. SYT = %6d, DBS = %3d, DBC = %3d, FMT = %3d, LEN = %4d (%2d)\n",
720                         channel, packet->fdf,
721                         packet->syt,
722                         packet->dbs,
723                         packet->dbc,
724                         packet->fmt,
725                         length,
726                         ((length / sizeof (quadlet_t)) - 2)/packet->dbs);
727                
728                 // update the frame counter
729                 m_framecounter+=nevents;
730                
731         } else {
732                 // discard packet
733                 // can be important for sync though
734         }
735
736         return (int)retval;
737 }
738
739 void AmdtpReceiveStreamProcessor::setVerboseLevel(int l) {
740         setDebugLevel(l);
741         ReceiveStreamProcessor::setVerboseLevel(l);
742
743 }
744
745
746 bool AmdtpReceiveStreamProcessor::reset() {
747
748         debugOutput( DEBUG_LEVEL_VERBOSE, "Resetting...\n");
749
750         // reset the event buffer, discard all content
751         freebob_ringbuffer_reset(m_event_buffer);
752        
753         // reset all non-device specific stuff
754         // i.e. the iso stream and the associated ports
755         return ReceiveStreamProcessor::reset();
756 }
757
758 bool AmdtpReceiveStreamProcessor::prepare() {
759
760         // prepare all non-device specific stuff
761         // i.e. the iso stream and the associated ports
762         if(!ReceiveStreamProcessor::prepare()) {
763                 debugFatal("Could not prepare base class\n");
764                 return false;
765         }
766        
767         debugOutput( DEBUG_LEVEL_VERBOSE, "Preparing...\n");
768         switch (m_framerate) {
769         case 32000:
770                 m_syt_interval = 8;
771                 break;
772         case 44100:
773                 m_syt_interval = 8;
774                 break;
775         default:
776         case 48000:
777                 m_syt_interval = 8;
778                 break;
779         case 88200:
780                 m_syt_interval = 16;
781                 break;
782         case 96000:
783                 m_syt_interval = 16;
784                 break;
785         case 176400:
786                 m_syt_interval = 32;
787                 break;
788         case 192000:
789                 m_syt_interval = 32;
790                 break;
791         }
792
793         if( !(m_event_buffer=freebob_ringbuffer_create(
794                         (m_dimension * m_nb_buffers * m_period) * sizeof(quadlet_t)))) {
795                 debugFatal("Could not allocate memory event ringbuffer");
796 //              return -ENOMEM;
797                 return false;
798         }
799
800         // allocate the temporary cluster buffer
801         if( !(m_cluster_buffer=(char *)calloc(m_dimension,sizeof(quadlet_t)))) {
802                 debugFatal("Could not allocate temporary cluster buffer");
803                 freebob_ringbuffer_free(m_event_buffer);
804 //              return -ENOMEM;
805                 return false;
806         }
807
808         // set the parameters of ports we can:
809         // we want the audio ports to be period buffered,
810         // and the midi ports to be packet buffered
811         for ( PortVectorIterator it = m_Ports.begin();
812                   it != m_Ports.end();
813                   ++it )
814         {
815                 debugOutput(DEBUG_LEVEL_VERBOSE, "Setting up port %s\n",(*it)->getName().c_str());
816                 if(!(*it)->setBufferSize(m_period)) {
817                         debugFatal("Could not set buffer size to %d\n",m_period);
818                         return false;
819                 }
820
821                 switch ((*it)->getPortType()) {
822                         case Port::E_Audio:
823                                 if(!(*it)->setSignalType(Port::E_PeriodSignalled)) {
824                                         debugFatal("Could not set signal type to PeriodSignalling");
825                                         return false;
826                                 }
827                                 // buffertype and datatype are dependant on the API
828                                 debugWarning("---------------- ! Doing hardcoded dummy setup ! --------------\n");
829                                 // buffertype and datatype are dependant on the API
830                                 if(!(*it)->setBufferType(Port::E_PointerBuffer)) {
831                                         debugFatal("Could not set buffer type");
832                                         return false;
833                                 }
834                                 if(!(*it)->useExternalBuffer(true)) {
835                                         debugFatal("Could not set external buffer usage");
836                                         return false;
837                                 }
838                                 if(!(*it)->setDataType(Port::E_Float)) {
839                                         debugFatal("Could not set data type");
840                                         return false;
841                                 }
842                                 break;
843                         case Port::E_Midi:
844                                 if(!(*it)->setSignalType(Port::E_PacketSignalled)) {
845                                         debugFatal("Could not set signal type to PacketSignalling");
846                                         return false;
847                                 }
848                                 // buffertype and datatype are dependant on the API
849                                 // buffertype and datatype are dependant on the API
850                                 debugWarning("---------------- ! Doing hardcoded test setup ! --------------\n");
851                                 // buffertype and datatype are dependant on the API
852                                 if(!(*it)->setBufferType(Port::E_RingBuffer)) {
853                                         debugFatal("Could not set buffer type");
854                                         return false;
855                                 }
856                                 if(!(*it)->setDataType(Port::E_MidiEvent)) {
857                                         debugFatal("Could not set data type");
858                                         return false;
859                                 }
860                                 break;
861                         default:
862                                 debugWarning("Unsupported port type specified\n");
863                                 break;
864                 }
865
866         }
867
868         // the API specific settings of the ports should already be set,
869         // as this is called from the processorManager->prepare()
870         // so we can init the ports
871         if(!initPorts()) {
872                 debugFatal("Could not initialize ports!\n");
873                 return false;
874         }
875
876         if(!preparePorts()) {
877                 debugFatal("Could not initialize ports!\n");
878                 return false;
879         }
880
881
882         debugOutput( DEBUG_LEVEL_VERBOSE, "Prepared for:\n");
883         debugOutput( DEBUG_LEVEL_VERBOSE, " Samplerate: %d, DBS: %d, SYT: %d\n",
884                      m_framerate,m_dimension,m_syt_interval);
885         debugOutput( DEBUG_LEVEL_VERBOSE, " PeriodSize: %d, NbBuffers: %d\n",
886                      m_period,m_nb_buffers);
887         debugOutput( DEBUG_LEVEL_VERBOSE, " Port: %d, Channel: %d\n",
888                      m_port,m_channel);
889         return true;
890
891 }
892
893 bool AmdtpReceiveStreamProcessor::transfer() {
894
895         debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "Transferring period...\n");
896        
897 /* another naive section:       
898         unsigned int read_size=m_period*sizeof(quadlet_t)*m_dimension;
899         char *dummybuffer=(char *)calloc(sizeof(quadlet_t),m_period*m_dimension);
900         if (freebob_ringbuffer_read(m_event_buffer,(char *)(dummybuffer),read_size) < read_size) {
901                 debugWarning("Could not read from event buffer\n");
902         }
903
904         receiveBlock(dummybuffer, m_period, 0);
905
906         free(dummybuffer);
907 */
908         int xrun;
909         unsigned int offset=0;
910        
911         freebob_ringbuffer_data_t vec[2];
912         // we received one period of frames on each connection
913         // this is period_size*dimension of events
914
915         int events2read=m_period*m_dimension;
916         int bytes2read=events2read*sizeof(quadlet_t);
917         /* read events2read bytes from the ringbuffer
918         *  first see if it can be done in one read.
919         *  if so, ok.
920         *  otherwise read up to a multiple of clusters directly from the buffer
921         *  then do the buffer wrap around using ringbuffer_read
922         *  then read the remaining data directly from the buffer in a third pass
923         *  Make sure that we cannot end up on a non-cluster aligned position!
924         */
925         int cluster_size=m_dimension*sizeof(quadlet_t);
926        
927         while(bytes2read>0) {
928                 unsigned int framesread=(m_period*cluster_size-bytes2read)/cluster_size;
929                 offset=framesread;
930                
931                 int bytesread=0;
932
933                 freebob_ringbuffer_get_read_vector(m_event_buffer, vec);
934                        
935                 if(vec[0].len==0) { // this indicates an empty event buffer
936                         debugError("Frame buffer underrun in processor %d\n",this);
937                         break;
938                 }
939                        
940                 /* if we don't take care we will get stuck in an infinite loop
941                 * because we align to a cluster boundary later
942                 * the remaining nb of bytes in one read operation can be smaller than one cluster
943                 * this can happen because the ringbuffer size is always a power of 2
944                         */
945                 if(vec[0].len<cluster_size) {
946                         // use the ringbuffer function to read one cluster
947                         // the read function handles wrap around
948                         freebob_ringbuffer_read(m_event_buffer,m_cluster_buffer,cluster_size);
949
950                         xrun = receiveBlock(m_cluster_buffer, 1, offset);
951                                
952                         if(xrun<0) {
953                                 // xrun detected
954                                 debugError("Frame buffer underrun in processor %d\n",this);
955                                 break;
956                         }
957                                
958                                 // we advanced one cluster_size
959                         bytes2read-=cluster_size;
960                                
961                 } else { //
962                        
963                         if(bytes2read>vec[0].len) {
964                                         // align to a cluster boundary
965                                 bytesread=vec[0].len-(vec[0].len%cluster_size);
966                         } else {
967                                 bytesread=bytes2read;
968                         }
969                                
970                         xrun = receiveBlock(vec[0].buf, bytesread/cluster_size, offset);
971                                
972                         if(xrun<0) {
973                                         // xrun detected
974                                 debugError("Frame buffer underrun in processor %d\n",this);
975                                 break;
976                         }
977
978                         freebob_ringbuffer_read_advance(m_event_buffer, bytesread);
979                         bytes2read -= bytesread;
980                 }
981                        
982                 // the bytes2read should always be cluster aligned
983                 assert(bytes2read%cluster_size==0);
984         }
985
986         return true;
987 }
988
989 /**
990  * \brief write received events to the stream ringbuffers.
991  */
992 int AmdtpReceiveStreamProcessor::receiveBlock(char *data,
993                                            unsigned int nevents, unsigned int offset)
994 {
995         int problem=0;
996
997         for ( PortVectorIterator it = m_PeriodPorts.begin();
998           it != m_PeriodPorts.end();
999           ++it )
1000     {
1001
1002                 //FIXME: make this into a static_cast when not DEBUG?
1003
1004                 AmdtpPortInfo *pinfo=dynamic_cast<AmdtpPortInfo *>(*it);
1005                 assert(pinfo); // this should not fail!!
1006
1007                 switch(pinfo->getFormat()) {
1008                 case AmdtpPortInfo::E_MBLA:
1009                         if(decodeMBLAEventsToPort(static_cast<AmdtpAudioPort *>(*it), (quadlet_t *)data, offset, nevents)) {
1010                                 debugWarning("Could not decode packet MBLA to port %s",(*it)->getName().c_str());
1011                                 problem=1;
1012                         }
1013                         break;
1014                 case AmdtpPortInfo::E_SPDIF: // still unimplemented
1015                         break;
1016         /* for this processor, midi is a packet based port
1017                 case AmdtpPortInfo::E_Midi:
1018                         break;*/
1019                 default: // ignore
1020                         break;
1021                 }
1022     }
1023         return problem;
1024
1025 }
1026
1027 /**
1028  * @brief decode a packet for the packet-based ports
1029  *
1030  * @param data Packet data
1031  * @param nevents number of events in data (including events of other ports & port types)
1032  * @param dbc DataBlockCount value for this packet
1033  * @return true if all successfull
1034  */
1035 bool AmdtpReceiveStreamProcessor::decodePacketPorts(quadlet_t *data, unsigned int nevents, unsigned int dbc)
1036 {
1037         bool ok=true;
1038        
1039         quadlet_t *target_event=NULL;
1040         int j;
1041        
1042         for ( PortVectorIterator it = m_PacketPorts.begin();
1043           it != m_PacketPorts.end();
1044           ++it )
1045         {
1046
1047 #ifdef DEBUG
1048                 AmdtpPortInfo *pinfo=dynamic_cast<AmdtpPortInfo *>(*it);
1049                 assert(pinfo); // this should not fail!!
1050
1051                 // the only packet type of events for AMDTP is MIDI in mbla
1052                 assert(pinfo->getFormat()==AmdtpPortInfo::E_Midi);
1053 #endif
1054                 AmdtpMidiPort *mp=static_cast<AmdtpMidiPort *>(*it);
1055                
1056                 // we decode this directly (no function call) due to the high frequency
1057                 /* idea:
1058                 spec says: current_midi_port=(dbc+j)%8;
1059                 => if we start at (dbc+stream->location-1)%8 [due to location_min=1],
1060                 we'll start at the right event for the midi port.
1061                 => if we increment j with 8, we stay at the right event.
1062                 */
1063                 // FIXME: as we know in advance how big a packet is (syt_interval) we can
1064                 //        predict how much loops will be present here
1065                 for(j = (dbc & 0x07)+mp->getLocation()-1; j < nevents; j += 8) {
1066                         target_event=(quadlet_t *)(data + ((j * m_dimension) + mp->getPosition()));
1067                         quadlet_t sample_int=ntohl(*target_event);
1068                         if(IEC61883_AM824_GET_LABEL(sample_int) != IEC61883_AM824_LABEL_MIDI_NO_DATA) {
1069                                 sample_int=(sample_int >> 16) & 0xFF;
1070                                 if(!mp->writeEvent(&sample_int)) {
1071                                         debugWarning("Packet port events lost\n");
1072                                         ok=false;
1073                                 }
1074                         }
1075                 }
1076
1077         }
1078        
1079         return ok;
1080 }
1081
1082 int AmdtpReceiveStreamProcessor::decodeMBLAEventsToPort(AmdtpAudioPort *p, quadlet_t *data,
1083                                            unsigned int offset, unsigned int nevents)
1084 {
1085         unsigned int j=0;
1086
1087 //      printf("****************\n");
1088 //      hexDumpQuadlets(data,m_dimension*4);
1089 //      printf("****************\n");
1090
1091         quadlet_t *target_event;
1092
1093         target_event=(quadlet_t *)(data + p->getPosition());
1094
1095         switch(p->getDataType()) {
1096                 default:
1097                 case Port::E_Int24:
1098                         {
1099                                 quadlet_t *buffer=(quadlet_t *)(p->getBufferAddress());
1100
1101                                 assert(nevents + offset <= p->getBufferSize());
1102
1103                                 buffer+=offset;
1104
1105                                 for(j = 0; j < nevents; j += 1) { // decode max nsamples
1106                                         *(buffer)=(ntohl((*target_event) ) & 0x00FFFFFF);
1107                                         buffer++;
1108                                         target_event+=m_dimension;
1109                                 }
1110                         }
1111                         break;
1112                 case Port::E_Float:
1113                         {
1114                                 const float multiplier = 1.0f / (float)(0x7FFFFF);
1115                                 float *buffer=(float *)(p->getBufferAddress());
1116
1117                                 assert(nevents + offset <= p->getBufferSize());
1118
1119                                 buffer+=offset;
1120
1121                                 for(j = 0; j < nevents; j += 1) { // decode max nsamples               
1122        
1123                                         unsigned int v = ntohl(*target_event) & 0x00FFFFFF;
1124                                         // sign-extend highest bit of 24-bit int
1125                                         int tmp = (int)(v << 8) / 256;
1126                
1127                                         *buffer = tmp * multiplier;
1128                                
1129                                         buffer++;
1130                                         target_event+=m_dimension;
1131                                 }
1132                         }
1133                         break;
1134         }
1135
1136         return 0;
1137 }
1138
1139 } // end of namespace FreebobStreaming
Note: See TracBrowser for help on using the browser.