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

Revision 228, 31.6 kB (checked in by pieterpalmers, 16 years ago)

- generic rate control added for ringbuffer based ports.

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