root/branches/ppalmers-streaming/src/libstreaming/amdtp/AmdtpTransmitStreamProcessor.cpp

Revision 719, 31.5 kB (checked in by ppalmers, 16 years ago)

backup commit

Line 
1 /*
2  * Copyright (C) 2005-2007 by Pieter Palmers
3  *
4  * This file is part of FFADO
5  * FFADO = Free Firewire (pro-)audio drivers for linux
6  *
7  * FFADO is based upon FreeBoB.
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License version 2.1, as published by the Free Software Foundation;
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
21  * MA 02110-1301 USA
22  */
23
24 #include "AmdtpTransmitStreamProcessor.h"
25 #include "AmdtpPort.h"
26 #include "../StreamProcessorManager.h"
27
28 #include "../util/cycletimer.h"
29
30 #include <netinet/in.h>
31 #include <assert.h>
32
33 // in ticks
34 // as per AMDTP2.1:
35 // 354.17us + 125us @ 24.576ticks/usec = 11776.08192 ticks
36 #define DEFAULT_TRANSFER_DELAY (11776U)
37
38 #define TRANSMIT_TRANSFER_DELAY DEFAULT_TRANSFER_DELAY
39
40 namespace Streaming {
41
42 /* transmit */
43 AmdtpTransmitStreamProcessor::AmdtpTransmitStreamProcessor(int port, int dimension)
44         : StreamProcessor(ePT_Transmit, port)
45         , m_dimension(dimension)
46         , m_last_timestamp(0)
47         , m_dbc(0)
48         , m_ringbuffer_size_frames(0)
49 {}
50
51 enum raw1394_iso_disposition
52 AmdtpTransmitStreamProcessor::getPacket(unsigned char *data, unsigned int *length,
53                   unsigned char *tag, unsigned char *sy,
54                   int cycle, unsigned int dropped, unsigned int max_length) {
55     struct iec61883_packet *packet = (struct iec61883_packet *) data;
56
57     if (cycle<0) {
58         debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE,"Xmit handler for cycle %d, (running=%d)\n",
59             cycle, isRunning());
60         *tag = 0;
61         *sy = 0;
62         *length=0;
63         return RAW1394_ISO_OK;
64     }
65
66     debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE,"Xmit handler for cycle %d, (running=%d)\n",
67         cycle, isRunning());
68
69     if (addCycles(m_last_cycle, 1) != cycle) {
70         debugWarning("(%p) Dropped %d packets on cycle %d\n", diffCycles(cycle,m_last_cycle)-1, cycle);
71     }
72
73     m_last_cycle=cycle;
74
75 #ifdef DEBUG
76     if(dropped>0) {
77         debugWarning("Dropped %d packets on cycle %d\n",dropped, cycle);
78     }
79 #endif
80
81     // calculate & preset common values
82
83     /* Our node ID can change after a bus reset, so it is best to fetch
84      * our node ID for each packet. */
85     packet->sid = m_handler->getLocalNodeId() & 0x3f;
86
87     packet->dbs = m_dimension;
88     packet->fn = 0;
89     packet->qpc = 0;
90     packet->sph = 0;
91     packet->reserved = 0;
92     packet->dbc = m_dbc;
93     packet->eoh1 = 2;
94     packet->fmt = IEC61883_FMT_AMDTP;
95
96     *tag = IEC61883_TAG_WITH_CIP;
97     *sy = 0;
98
99     // determine if we want to send a packet or not
100     // note that we can't use getCycleTimer directly here,
101     // because packets are queued in advance. This means that
102     // we the packet we are constructing will be sent out
103     // on 'cycle', not 'now'.
104     unsigned int ctr=m_handler->getCycleTimer();
105     int now_cycles = (int)CYCLE_TIMER_GET_CYCLES(ctr);
106
107     // the difference between the cycle this
108     // packet is intended for and 'now'
109     int cycle_diff = diffCycles(cycle, now_cycles);
110
111 #ifdef DEBUG
112     if(isRunning() && (cycle_diff < 0)) {
113         debugWarning("Requesting packet for cycle %04d which is in the past (now=%04dcy)\n",
114             cycle, now_cycles);
115     }
116
117     // keep track of the lag
118     m_PacketStat.mark(cycle_diff);
119 #endif
120
121     // as long as the cycle parameter is not in sync with
122     // the current time, the stream is considered not
123     // to be 'running'
124     // NOTE: this works only at startup
125     if (!isRunning() && cycle_diff >= 0 && cycle >= 0) {
126             debugOutput(DEBUG_LEVEL_VERBOSE, "Xmit StreamProcessor %p started running at cycle %d\n",this, cycle);
127     }
128
129     signed int fc;
130     uint64_t presentation_time;
131     unsigned int presentation_cycle;
132     int cycles_until_presentation;
133
134     uint64_t transmit_at_time;
135     unsigned int transmit_at_cycle;
136     int cycles_until_transmit;
137
138     // FIXME: should become a define
139     // the absolute minimum number of cycles we want to transmit
140     // a packet ahead of the presentation time. The nominal time
141     // the packet is transmitted ahead of the presentation time is
142     // given by TRANSMIT_TRANSFER_DELAY (in ticks), but in case we
143     // are too late for that, this constant defines how late we can
144     // be.
145     const int min_cycles_before_presentation = 1;
146     // FIXME: should become a define
147     // the absolute maximum number of cycles we want to transmit
148     // a packet ahead of the ideal transmit time. The nominal time
149     // the packet is transmitted ahead of the presentation time is
150     // given by TRANSMIT_TRANSFER_DELAY (in ticks), but we can send
151     // packets early if we want to. (not completely according to spec)
152     const int max_cycles_to_transmit_early = 5;
153
154     if( !isRunning() || !m_data_buffer->isEnabled() ) {
155         debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE,
156                     "Not running (%d) or buffer not enabled (enabled=%d)\n",
157                     isRunning(), m_data_buffer->isEnabled());
158
159         // not running or not enabled
160         goto send_empty_packet;
161     }
162
163 try_block_of_frames:
164     debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, "Try for cycle %d\n", cycle);
165     // check whether the packet buffer has packets for us to send.
166     // the base timestamp is the one of the next sample in the buffer
167     ffado_timestamp_t ts_head_tmp;
168     m_data_buffer->getBufferHeadTimestamp(&ts_head_tmp, &fc); // thread safe
169
170     // the timestamp gives us the time at which we want the sample block
171     // to be output by the device
172     presentation_time=(uint64_t)ts_head_tmp;
173
174     // now we calculate the time when we have to transmit the sample block
175     transmit_at_time = substractTicks(presentation_time, TRANSMIT_TRANSFER_DELAY);
176
177     // calculate the cycle this block should be presented in
178     // (this is just a virtual calculation since at that time it should
179     //  already be in the device's buffer)
180     presentation_cycle = (unsigned int)(TICKS_TO_CYCLES( presentation_time ));
181
182     // calculate the cycle this block should be transmitted in
183     transmit_at_cycle = (unsigned int)(TICKS_TO_CYCLES( transmit_at_time ));
184
185     // we can check whether this cycle is within the 'window' we have
186     // to send this packet.
187     // first calculate the number of cycles left before presentation time
188     cycles_until_presentation = diffCycles( presentation_cycle, cycle );
189
190     // we can check whether this cycle is within the 'window' we have
191     // to send this packet.
192     // first calculate the number of cycles left before presentation time
193     cycles_until_transmit = diffCycles( transmit_at_cycle, cycle );
194
195     // two different options:
196     // 1) there are not enough frames for one packet
197     //      => determine wether this is a problem, since we might still
198     //         have some time to send it
199     // 2) there are enough packets
200     //      => determine whether we have to send them in this packet
201     if (fc < (signed int)m_syt_interval) {
202         m_PacketStat.signal(0);
203         // not enough frames in the buffer,
204         debugOutput(DEBUG_LEVEL_VERBOSE,
205                     "Insufficient frames: N=%02d, CY=%04u, TC=%04u, CUT=%04d\n",
206                     fc, cycle, transmit_at_cycle, cycles_until_transmit);
207         // we can still postpone the queueing of the packets
208         // if we are far enough ahead of the presentation time
209         if( cycles_until_presentation <= min_cycles_before_presentation ) {
210             m_PacketStat.signal(1);
211             // we are too late
212             // meaning that we in some sort of xrun state
213             // signal xrun situation ??HERE??
214             m_xruns++;
215             // we send an empty packet on this cycle
216             goto send_empty_packet; // UGLY but effective
217         } else {
218             m_PacketStat.signal(2);
219             // there is still time left to send the packet
220             // we want the system to give this packet another go
221 //             goto try_packet_again; // UGLY but effective
222             // unfortunatly the try_again doesn't work very well,
223             // so we'll have to either usleep(one cycle) and goto try_block_of_frames
224            
225             // or just fill this with an empty packet
226             // if we have to do this too often, the presentation time will
227             // get too close and we're in trouble
228             goto send_empty_packet; // UGLY but effective
229         }
230     } else {
231         m_PacketStat.signal(3);
232         // there are enough frames, so check the time they are intended for
233         // all frames have a certain 'time window' in which they can be sent
234         // this corresponds to the range of the timestamp mechanism:
235         // we can send a packet 15 cycles in advance of the 'presentation time'
236         // in theory we can send the packet up till one cycle before the presentation time,
237         // however this is not very smart.
238        
239         // There are 3 options:
240         // 1) the frame block is too early
241         //      => send an empty packet
242         // 2) the frame block is within the window
243         //      => send it
244         // 3) the frame block is too late
245         //      => discard (and raise xrun?)
246         //         get next block of frames and repeat
247        
248         if (cycles_until_transmit <= max_cycles_to_transmit_early) {
249             m_PacketStat.signal(4);
250             // it's time send the packet
251             goto send_packet; // UGLY but effective
252         } else if (cycles_until_transmit < 0) {
253             // we are too late
254             debugOutput(DEBUG_LEVEL_VERBOSE,
255                         "Too late: CY=%04u, TC=%04u, CUT=%04d, TSP=%011llu (%04u)\n",
256                         cycle,
257                         transmit_at_cycle, cycles_until_transmit,
258                         presentation_time, (unsigned int)TICKS_TO_CYCLES(presentation_time));
259
260             // however, if we can send this sufficiently before the presentation
261             // time, it could be harmless.
262             // NOTE: dangerous since the device has no way of reporting that it didn't get
263             //       this packet on time.
264             if ( cycles_until_presentation <= min_cycles_before_presentation ) {
265                 m_PacketStat.signal(5);
266                 // we are not that late and can still try to transmit the packet
267                 goto send_packet; // UGLY but effective
268             } else { // definitely too late
269                 m_PacketStat.signal(6);
270                 // remove the samples
271                 m_data_buffer->dropFrames(m_syt_interval);
272                 // signal some xrun situation ??HERE??
273                 m_xruns++;
274                 // try a new block of frames
275                 goto try_block_of_frames; // UGLY but effective
276             }
277         } else {
278             m_PacketStat.signal(7);
279             debugOutput(DEBUG_LEVEL_VERY_VERBOSE,
280                         "Too early: CY=%04u, TC=%04u, CUT=%04d, TST=%011llu (%04u), TSP=%011llu (%04u)\n",
281                         cycle,
282                         transmit_at_cycle, cycles_until_transmit,
283                         transmit_at_time, (unsigned int)TICKS_TO_CYCLES(transmit_at_time),
284                         presentation_time, (unsigned int)TICKS_TO_CYCLES(presentation_time));
285             #ifdef DEBUG
286             if (cycles_until_transmit > max_cycles_to_transmit_early + 1) {
287                 debugOutput(DEBUG_LEVEL_VERBOSE,
288                             "Way too early: CY=%04u, TC=%04u, CUT=%04d, TST=%011llu (%04u), TSP=%011llu (%04u)\n",
289                             cycle,
290                             transmit_at_cycle, cycles_until_transmit,
291                             transmit_at_time, (unsigned int)TICKS_TO_CYCLES(transmit_at_time),
292                             presentation_time, (unsigned int)TICKS_TO_CYCLES(presentation_time));
293             }
294             #endif
295             // we are too early, send only an empty packet
296             goto send_empty_packet; // UGLY but effective
297         }
298     }
299
300     debugFatal("Should never reach this code!\n");
301     return RAW1394_ISO_ERROR;
302
303 send_empty_packet:
304     debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "XMIT NONE: CY=%04u, TSP=%011llu (%04u)\n",
305             cycle,
306             presentation_time, (unsigned int)TICKS_TO_CYCLES(presentation_time));
307
308     m_dbc += fillNoDataPacketHeader(packet, length);
309     return RAW1394_ISO_DEFER;
310
311 send_packet:
312     if (m_data_buffer->readFrames(m_syt_interval, (char *)(data + 8))) {
313         m_dbc += fillDataPacketHeader(packet, length, presentation_time);
314
315         // process all ports that should be handled on a per-packet base
316         // this is MIDI for AMDTP (due to the need of DBC)
317         if (!encodePacketPorts((quadlet_t *)(data+8), m_syt_interval, packet->dbc)) {
318             debugWarning("Problem encoding Packet Ports\n");
319         }
320
321         debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "XMIT DATA: CY=%04u, TST=%011llu (%04u), TSP=%011llu (%04u)\n",
322             cycle,
323             transmit_at_time, (unsigned int)TICKS_TO_CYCLES(transmit_at_time),
324             presentation_time, (unsigned int)TICKS_TO_CYCLES(presentation_time));
325
326         return RAW1394_ISO_OK;
327     }
328
329 // the ISO AGAIN does not work very well...
330 // try_packet_again:
331 //
332 //     debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "XMIT RETRY: CY=%04u, TSP=%011llu (%04u)\n",
333 //             cycle,
334 //             presentation_time, (unsigned int)TICKS_TO_CYCLES(presentation_time));
335 //     return RAW1394_ISO_AGAIN;
336
337     // else:
338     debugFatal("This is impossible, since we checked the buffer size before!\n");
339     return RAW1394_ISO_ERROR;
340 }
341
342 unsigned int
343 AmdtpTransmitStreamProcessor::getEventsPerFrame()
344 {
345     return m_dimension;
346 }
347
348 unsigned int
349 AmdtpTransmitStreamProcessor::getUpdatePeriod()
350 {
351     return m_syt_interval;
352 }
353
354
355 unsigned int AmdtpTransmitStreamProcessor::fillDataPacketHeader(
356         struct iec61883_packet *packet, unsigned int* length,
357         uint32_t ts) {
358
359     packet->fdf = m_fdf;
360
361     // convert the timestamp to SYT format
362     uint16_t timestamp_SYT = TICKS_TO_SYT(ts);
363     packet->syt = ntohs(timestamp_SYT);
364
365     *length = m_syt_interval*sizeof(quadlet_t)*m_dimension + 8;
366
367     return m_syt_interval;
368 }
369
370 unsigned int AmdtpTransmitStreamProcessor::fillNoDataPacketHeader(
371         struct iec61883_packet *packet, unsigned int* length) {
372
373     // no-data packets have syt=0xFFFF
374     // and have the usual amount of events as dummy data (?)
375     packet->fdf = IEC61883_FDF_NODATA;
376     packet->syt = 0xffff;
377
378     // FIXME: either make this a setting or choose
379     bool send_payload=true;
380     if(send_payload) {
381         // this means no-data packets with payload (DICE doesn't like that)
382         *length = 2*sizeof(quadlet_t) + m_syt_interval * m_dimension * sizeof(quadlet_t);
383         return m_syt_interval;
384     } else {
385         // dbc is not incremented
386         // this means no-data packets without payload
387         *length = 2*sizeof(quadlet_t);
388         return 0;
389     }
390 }
391
392 bool AmdtpTransmitStreamProcessor::prefill() {
393
394     debugOutput( DEBUG_LEVEL_VERBOSE, "Prefill transmit buffers...\n");
395
396     if(!transferSilence(m_ringbuffer_size_frames)) {
397         debugFatal("Could not prefill transmit stream\n");
398         return false;
399     }
400
401     return true;
402 }
403
404 bool AmdtpTransmitStreamProcessor::reset() {
405
406     debugOutput( DEBUG_LEVEL_VERBOSE, "Resetting...\n");
407
408     // reset the statistics
409     m_PeriodStat.reset();
410     m_PacketStat.reset();
411     m_WakeupStat.reset();
412
413     m_data_buffer->setTickOffset(0);
414
415 //     // reset all non-device specific stuff
416 //     // i.e. the iso stream and the associated ports
417 //     if(!StreamProcessor::reset()) {
418 //         debugFatal("Could not do base class reset\n");
419 //         return false;
420 //     }
421
422     // we should prefill the event buffer
423     if (!prefill()) {
424         debugFatal("Could not prefill buffers\n");
425         return false;
426     }
427
428     return true;
429 }
430
431 bool AmdtpTransmitStreamProcessor::prepareChild() {
432     m_PeriodStat.setName("XMT PERIOD");
433     m_PacketStat.setName("XMT PACKET");
434     m_WakeupStat.setName("XMT WAKEUP");
435
436     debugOutput( DEBUG_LEVEL_VERBOSE, "Preparing (%p)...\n", this);
437
438     // prepare all non-device specific stuff
439     // i.e. the iso stream and the associated ports
440     if(!StreamProcessor::prepare()) {
441         debugFatal("Could not prepare base class\n");
442         return false;
443     }
444
445     switch (m_manager->getNominalRate()) {
446     case 32000:
447         m_syt_interval = 8;
448         m_fdf = IEC61883_FDF_SFC_32KHZ;
449         break;
450     case 44100:
451         m_syt_interval = 8;
452         m_fdf = IEC61883_FDF_SFC_44K1HZ;
453         break;
454     default:
455     case 48000:
456         m_syt_interval = 8;
457         m_fdf = IEC61883_FDF_SFC_48KHZ;
458         break;
459     case 88200:
460         m_syt_interval = 16;
461         m_fdf = IEC61883_FDF_SFC_88K2HZ;
462         break;
463     case 96000:
464         m_syt_interval = 16;
465         m_fdf = IEC61883_FDF_SFC_96KHZ;
466         break;
467     case 176400:
468         m_syt_interval = 32;
469         m_fdf = IEC61883_FDF_SFC_176K4HZ;
470         break;
471     case 192000:
472         m_syt_interval = 32;
473         m_fdf = IEC61883_FDF_SFC_192KHZ;
474         break;
475     }
476
477     iec61883_cip_init (
478         &m_cip_status,
479         IEC61883_FMT_AMDTP,
480         m_fdf,
481         m_manager->getNominalRate(),
482         m_dimension,
483         m_syt_interval);
484
485     // prepare the framerate estimate
486     float ticks_per_frame = (TICKS_PER_SECOND*1.0) / ((float)m_manager->getNominalRate());
487     m_ticks_per_frame=ticks_per_frame;
488
489     // initialize internal buffer
490     m_ringbuffer_size_frames=m_manager->getNbBuffers() * m_manager->getPeriodSize();
491
492     assert(m_data_buffer);
493     m_data_buffer->setBufferSize(m_ringbuffer_size_frames * 2);
494     m_data_buffer->setEventSize(sizeof(quadlet_t));
495     m_data_buffer->setEventsPerFrame(m_dimension);
496
497     m_data_buffer->setUpdatePeriod(m_manager->getPeriodSize());
498     m_data_buffer->setNominalRate(ticks_per_frame);
499
500     m_data_buffer->setWrapValue(128L*TICKS_PER_SECOND);
501
502     m_data_buffer->prepare();
503
504     // set the parameters of ports we can:
505     // we want the audio ports to be period buffered,
506     // and the midi ports to be packet buffered
507     for ( PortVectorIterator it = m_Ports.begin();
508           it != m_Ports.end();
509           ++it )
510     {
511         debugOutput(DEBUG_LEVEL_VERBOSE, "Setting up port %s\n",(*it)->getName().c_str());
512         if(!(*it)->setBufferSize(m_manager->getPeriodSize())) {
513             debugFatal("Could not set buffer size to %d\n",m_manager->getPeriodSize());
514             return false;
515         }
516
517
518         switch ((*it)->getPortType()) {
519             case Port::E_Audio:
520                 if(!(*it)->setSignalType(Port::E_PeriodSignalled)) {
521                     debugFatal("Could not set signal type to PeriodSignalling");
522                     return false;
523                 }
524                 debugWarning("---------------- ! Doing hardcoded test setup ! --------------\n");
525                 // buffertype and datatype are dependant on the API
526                 if(!(*it)->setBufferType(Port::E_PointerBuffer)) {
527                     debugFatal("Could not set buffer type");
528                     return false;
529                 }
530                 if(!(*it)->useExternalBuffer(true)) {
531                     debugFatal("Could not set external buffer usage");
532                     return false;
533                 }
534
535                 if(!(*it)->setDataType(Port::E_Float)) {
536                     debugFatal("Could not set data type");
537                     return false;
538                 }
539
540
541                 break;
542             case Port::E_Midi:
543                 if(!(*it)->setSignalType(Port::E_PacketSignalled)) {
544                     debugFatal("Could not set signal type to PeriodSignalling");
545                     return false;
546                 }
547
548                 // we use a timing unit of 10ns
549                 // this makes sure that for the max syt interval
550                 // we don't have rounding, and keeps the numbers low
551                 // we have 1 slot every 8 events
552                 // we have syt_interval events per packet
553                 // => syt_interval/8 slots per packet
554                 // packet rate is 8000pkt/sec => interval=125us
555                 // so the slot interval is (1/8000)/(syt_interval/8)
556                 // or: 1/(1000 * syt_interval) sec
557                 // which is 1e9/(1000*syt_interval) nsec
558                 // or 100000/syt_interval 'units'
559                 // the event interval is fixed to 320us = 32000 'units'
560                 if(!(*it)->useRateControl(true,(100000/m_syt_interval),32000, false)) {
561                     debugFatal("Could not set signal type to PeriodSignalling");
562                     return false;
563                 }
564
565                 // buffertype and datatype are dependant on the API
566                 debugWarning("---------------- ! Doing hardcoded test setup ! --------------\n");
567                 // buffertype and datatype are dependant on the API
568                 if(!(*it)->setBufferType(Port::E_RingBuffer)) {
569                     debugFatal("Could not set buffer type");
570                     return false;
571                 }
572                 if(!(*it)->setDataType(Port::E_MidiEvent)) {
573                     debugFatal("Could not set data type");
574                     return false;
575                 }
576                 break;
577             default:
578                 debugWarning("Unsupported port type specified\n");
579                 break;
580         }
581     }
582
583     // the API specific settings of the ports should already be set,
584     // as this is called from the processorManager->prepare()
585     // so we can init the ports
586     if(!initPorts()) {
587         debugFatal("Could not initialize ports!\n");
588         return false;
589     }
590
591     if(!preparePorts()) {
592         debugFatal("Could not initialize ports!\n");
593         return false;
594     }
595
596     debugOutput( DEBUG_LEVEL_VERBOSE, "Prepared for:\n");
597     debugOutput( DEBUG_LEVEL_VERBOSE, " Samplerate: %d, FDF: %d, DBS: %d, SYT: %d\n",
598              m_manager->getNominalRate(),m_fdf,m_dimension,m_syt_interval);
599     debugOutput( DEBUG_LEVEL_VERBOSE, " PeriodSize: %d, NbBuffers: %d\n",
600              m_manager->getPeriodSize(), m_manager->getNbBuffers());
601     debugOutput( DEBUG_LEVEL_VERBOSE, " Port: %d, Channel: %d\n",
602              m_port,m_channel);
603
604     return true;
605
606 }
607
608 bool AmdtpTransmitStreamProcessor::prepareForStart() {
609     return true;
610 }
611
612 bool AmdtpTransmitStreamProcessor::prepareForStop() {
613     return true;
614 }
615
616 bool AmdtpTransmitStreamProcessor::prepareForEnable(uint64_t time_to_enable_at) {
617
618 //     if (!StreamProcessor::prepareForEnable(time_to_enable_at)) {
619 //         debugError("StreamProcessor::prepareForEnable failed\n");
620 //         return false;
621 //     }
622
623     return true;
624 }
625
626 unsigned int
627 AmdtpTransmitStreamProcessor::getPacketsPerPeriod()
628 {
629     return (m_manager->getPeriodSize())/m_syt_interval;
630 }
631
632 bool AmdtpTransmitStreamProcessor::transferSilence(unsigned int nframes) {
633     bool retval;
634     signed int fc;
635     ffado_timestamp_t ts_tail_tmp;
636     uint64_t ts_tail;
637    
638     // prepare a buffer of silence
639     char *dummybuffer=(char *)calloc(sizeof(quadlet_t),nframes*m_dimension);
640     transmitSilenceBlock(dummybuffer, nframes, 0);
641
642    
643     m_data_buffer->getBufferTailTimestamp(&ts_tail_tmp, &fc);
644     if (fc != 0) {
645         debugWarning("Prefilling a buffer that already contains %d frames\n", fc);
646     }
647
648     ts_tail = (uint64_t)ts_tail_tmp;
649     // modify the timestamp such that it makes sense
650     ts_tail = addTicks(ts_tail, (uint64_t)(nframes * getTicksPerFrame()));
651     // add the silence data to the ringbuffer
652     if(m_data_buffer->writeFrames(nframes, dummybuffer, ts_tail)) {
653         retval=true;
654     } else {
655         debugWarning("Could not write to event buffer\n");
656         retval=false;
657     }
658
659     free(dummybuffer);
660
661     return retval;
662 }
663
664 bool AmdtpTransmitStreamProcessor::putFrames(unsigned int nbframes, int64_t ts) {
665     m_PeriodStat.mark(m_data_buffer->getBufferFill());
666     debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, "AmdtpTransmitStreamProcessor::putFrames(%d, %llu)\n", nbframes, ts);
667
668     // transfer the data
669     m_data_buffer->blockProcessWriteFrames(nbframes, ts);
670
671     debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, " New timestamp: %llu\n", ts);
672
673     return true; // FIXME: what about failure?
674 }
675
676 bool AmdtpTransmitStreamProcessor::putFramesDry(unsigned int nbframes, int64_t ts) {
677     m_PeriodStat.mark(m_data_buffer->getBufferFill());
678     debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, "AmdtpTransmitStreamProcessor::putFramesDry(%d, %llu)\n", nbframes, ts);
679
680     bool retval;
681     char dummybuffer[sizeof(quadlet_t)*nbframes*m_dimension];
682
683     transmitSilenceBlock(dummybuffer, nbframes, 0);
684     // add the silence data to the ringbuffer
685     if(m_data_buffer->writeFrames(nbframes, dummybuffer, ts)) {
686         retval=true;
687     } else {
688         debugWarning("Could not write %u events to event buffer\n", nbframes);
689         retval=false;
690     }
691
692     debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, " New timestamp: %llu\n", ts);
693     return retval;
694 }
695
696 /*
697  * write received events to the stream ringbuffers.
698  */
699
700 bool AmdtpTransmitStreamProcessor::processWriteBlock(char *data,
701                        unsigned int nevents, unsigned int offset)
702 {
703     bool no_problem=true;
704
705     for ( PortVectorIterator it = m_PeriodPorts.begin();
706           it != m_PeriodPorts.end();
707           ++it )
708     {
709
710         if((*it)->isDisabled()) {continue;};
711
712         //FIXME: make this into a static_cast when not DEBUG?
713
714         AmdtpPortInfo *pinfo=dynamic_cast<AmdtpPortInfo *>(*it);
715         assert(pinfo); // this should not fail!!
716
717         switch(pinfo->getFormat()) {
718         case AmdtpPortInfo::E_MBLA:
719             if(encodePortToMBLAEvents(static_cast<AmdtpAudioPort *>(*it), (quadlet_t *)data, offset, nevents)) {
720                 debugWarning("Could not encode port %s to MBLA events",(*it)->getName().c_str());
721                 no_problem=false;
722             }
723             break;
724         case AmdtpPortInfo::E_SPDIF: // still unimplemented
725             break;
726         default: // ignore
727             break;
728         }
729     }
730     return no_problem;
731
732 }
733
734 int AmdtpTransmitStreamProcessor::transmitSilenceBlock(char *data,
735                        unsigned int nevents, unsigned int offset)
736 {
737     int problem=0;
738
739     for ( PortVectorIterator it = m_PeriodPorts.begin();
740           it != m_PeriodPorts.end();
741           ++it )
742     {
743
744         //FIXME: make this into a static_cast when not DEBUG?
745
746         AmdtpPortInfo *pinfo=dynamic_cast<AmdtpPortInfo *>(*it);
747         assert(pinfo); // this should not fail!!
748
749         switch(pinfo->getFormat()) {
750         case AmdtpPortInfo::E_MBLA:
751             if(encodeSilencePortToMBLAEvents(static_cast<AmdtpAudioPort *>(*it), (quadlet_t *)data, offset, nevents)) {
752                 debugWarning("Could not encode port %s to MBLA events",(*it)->getName().c_str());
753                 problem=1;
754             }
755             break;
756         case AmdtpPortInfo::E_SPDIF: // still unimplemented
757             break;
758         default: // ignore
759             break;
760         }
761     }
762     return problem;
763
764 }
765
766 /**
767  * @brief decode a packet for the packet-based ports
768  *
769  * @param data Packet data
770  * @param nevents number of events in data (including events of other ports & port types)
771  * @param dbc DataBlockCount value for this packet
772  * @return true if all successfull
773  */
774 bool AmdtpTransmitStreamProcessor::encodePacketPorts(quadlet_t *data, unsigned int nevents, unsigned int dbc)
775 {
776     bool ok=true;
777     quadlet_t byte;
778
779     quadlet_t *target_event=NULL;
780     unsigned int j;
781
782     for ( PortVectorIterator it = m_PacketPorts.begin();
783           it != m_PacketPorts.end();
784           ++it )
785     {
786
787 #ifdef DEBUG
788         AmdtpPortInfo *pinfo=dynamic_cast<AmdtpPortInfo *>(*it);
789         assert(pinfo); // this should not fail!!
790
791         // the only packet type of events for AMDTP is MIDI in mbla
792         assert(pinfo->getFormat()==AmdtpPortInfo::E_Midi);
793 #endif
794
795         AmdtpMidiPort *mp=static_cast<AmdtpMidiPort *>(*it);
796
797         // we encode this directly (no function call) due to the high frequency
798         /* idea:
799         spec says: current_midi_port=(dbc+j)%8;
800         => if we start at (dbc+stream->location-1)%8,
801         we'll start at the right event for the midi port.
802         => if we increment j with 8, we stay at the right event.
803         */
804         // FIXME: as we know in advance how big a packet is (syt_interval) we can
805         //        predict how much loops will be present here
806         // first prefill the buffer with NO_DATA's on all time muxed channels
807
808         for(j = (dbc & 0x07)+mp->getLocation(); j < nevents; j += 8) {
809            
810             quadlet_t tmpval;
811            
812             target_event=(quadlet_t *)(data + ((j * m_dimension) + mp->getPosition()));
813            
814             if(mp->canRead()) { // we can send a byte
815                 mp->readEvent(&byte);
816                 byte &= 0xFF;
817                 tmpval=htonl(
818                     IEC61883_AM824_SET_LABEL((byte)<<16,
819                                              IEC61883_AM824_LABEL_MIDI_1X));
820
821                 debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, "MIDI port %s, pos=%d, loc=%d, dbc=%d, nevents=%d, dim=%d\n",
822                     mp->getName().c_str(), mp->getPosition(), mp->getLocation(), dbc, nevents, m_dimension);
823                 debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, "base=%p, target=%p, value=%08X\n",
824                     data, target_event, tmpval);
825                    
826             } else {
827                 // can't send a byte, either because there is no byte,
828                 // or because this would exceed the maximum rate
829                 tmpval=htonl(
830                     IEC61883_AM824_SET_LABEL(0,IEC61883_AM824_LABEL_MIDI_NO_DATA));
831             }
832            
833             *target_event=tmpval;
834         }
835
836     }
837
838     return ok;
839 }
840
841
842 int AmdtpTransmitStreamProcessor::encodePortToMBLAEvents(AmdtpAudioPort *p, quadlet_t *data,
843                        unsigned int offset, unsigned int nevents)
844 {
845     unsigned int j=0;
846
847     quadlet_t *target_event;
848
849     target_event=(quadlet_t *)(data + p->getPosition());
850
851     switch(p->getDataType()) {
852         default:
853         case Port::E_Int24:
854             {
855                 quadlet_t *buffer=(quadlet_t *)(p->getBufferAddress());
856
857                 assert(nevents + offset <= p->getBufferSize());
858
859                 buffer+=offset;
860
861                 for(j = 0; j < nevents; j += 1) { // decode max nsamples
862                     *target_event = htonl((*(buffer) & 0x00FFFFFF) | 0x40000000);
863                     buffer++;
864                     target_event += m_dimension;
865                 }
866             }
867             break;
868         case Port::E_Float:
869             {
870                 const float multiplier = (float)(0x7FFFFF00);
871                 float *buffer=(float *)(p->getBufferAddress());
872
873                 assert(nevents + offset <= p->getBufferSize());
874
875                 buffer+=offset;
876
877                 for(j = 0; j < nevents; j += 1) { // decode max nsamples
878
879                     // don't care for overflow
880                     float v = *buffer * multiplier;  // v: -231 .. 231
881                     unsigned int tmp = ((int)v);
882                     *target_event = htonl((tmp >> 8) | 0x40000000);
883
884                     buffer++;
885                     target_event += m_dimension;
886                 }
887             }
888             break;
889     }
890
891     return 0;
892 }
893 int AmdtpTransmitStreamProcessor::encodeSilencePortToMBLAEvents(AmdtpAudioPort *p, quadlet_t *data,
894                        unsigned int offset, unsigned int nevents)
895 {
896     unsigned int j=0;
897
898     quadlet_t *target_event;
899
900     target_event=(quadlet_t *)(data + p->getPosition());
901
902     switch(p->getDataType()) {
903         default:
904         case Port::E_Int24:
905         case Port::E_Float:
906             {
907                 for(j = 0; j < nevents; j += 1) { // decode max nsamples
908                     *target_event = htonl(0x40000000);
909                     target_event += m_dimension;
910                 }
911             }
912             break;
913     }
914
915     return 0;
916 }
917
918 } // end of namespace Streaming
Note: See TracBrowser for help on using the browser.