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

Revision 242, 32.8 kB (checked in by pieterpalmers, 18 years ago)

- made the bounce device actually work

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