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

Revision 714, 31.4 kB (checked in by ppalmers, 15 years ago)

- cleanup of streaming interfaces
- doesn't work yet

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